3 /* ,x/^(print|prtree)\(/i/\/\/ */
4 int castup(Type*, Type*);
7 cgen(Node *n, Node *nn)
11 Node nod, nod1, nod2, nod3, nod4;
17 prtree(nn, "cgen lhs");
20 if(n == Z || n->type == T)
22 if(typesu[n->type->etype]) {
23 sugen(n, nn, n->type->width);
29 if(n->addable >= INDEXED) {
47 if(r != Z && r->complex >= FNX)
50 if(cond(o) && typesu[l->type->etype])
75 hardleft = l->addable < INDEXED || l->complex >= FNX;
78 diag(n, "unknown op in cgen: %O", o);
87 regalloc(&nod, l, nn);
89 gopcode(o, n->type, Z, &nod);
98 if(nn != Z || r->addable < INDEXED || hardconst(r)) {
99 if(r->complex >= FNX && nn == Z)
102 regalloc(&nod, r, nn);
112 if(l->complex >= r->complex) {
113 if(l->op == OINDEX && immconst(r)) {
117 reglcgen(&nod1, l, Z);
118 if(r->addable >= INDEXED && !hardconst(r)) {
125 regalloc(&nod, r, nn);
128 regalloc(&nod, r, nn);
130 reglcgen(&nod1, l, Z);
139 regalloc(&nod, r, nn);
140 if(l->complex >= r->complex) {
141 reglcgen(&nod1, n, Z);
145 reglcgen(&nod1, n, Z);
147 regalloc(&nod2, n, Z);
149 bitstore(l, &nod, &nod1, &nod2, nn);
157 bitload(n, &nod, Z, Z, nn);
170 if(r->op == OCONST) {
175 regalloc(&nod, l, nn);
177 if(o == OASHL && r->vconst == 1)
178 gopcode(OADD, n->type, &nod, &nod);
180 gopcode(o, n->type, r, &nod);
189 if(nodreg(&nod, nn, D_CX)) {
192 cgen(n, &nod); /* probably a bug */
198 if(nn->op == OREGISTER && nn->reg == D_CX)
199 regalloc(&nod1, l, Z);
201 regalloc(&nod1, l, nn);
202 if(r->complex >= l->complex) {
209 gopcode(o, n->type, &nod, &nod1);
224 if(typefd[n->type->etype])
226 if(r->op == OCONST) {
227 if(r->vconst == 0 && o != OAND) {
232 if(n->op == OADD && l->op == OASHL && l->right->op == OCONST
233 && (r->op != OCONST || r->vconst < -128 || r->vconst > 127)) {
234 c = l->right->vconst;
235 if(c > 0 && c <= 3) {
236 if(l->left->complex >= r->complex) {
237 regalloc(&nod, l->left, nn);
239 if(r->addable < INDEXED) {
240 regalloc(&nod1, r, Z);
242 genmuladd(&nod, &nod, 1 << c, &nod1);
246 genmuladd(&nod, &nod, 1 << c, r);
249 regalloc(&nod, r, nn);
251 regalloc(&nod1, l->left, Z);
252 cgen(l->left, &nod1);
253 genmuladd(&nod, &nod1, 1 << c, &nod);
261 if(r->addable >= INDEXED && !hardconst(r)) {
262 regalloc(&nod, l, nn);
264 gopcode(o, n->type, r, &nod);
269 if(l->complex >= r->complex) {
270 regalloc(&nod, l, nn);
272 regalloc(&nod1, r, Z);
274 gopcode(o, n->type, &nod1, &nod);
276 regalloc(&nod1, r, nn);
278 regalloc(&nod, l, Z);
280 gopcode(o, n->type, &nod1, &nod);
297 if(typefd[n->type->etype])
299 if(r->op == OCONST && typechl[n->type->etype]) { /* TO DO */
313 regalloc(&nod, l, nn);
318 mulgen(n->type, r, &nod);
321 sdiv2(r->vconst, v, l, &nod);
324 smod2(r->vconst, v, l, &nod);
332 if((c & 0x80000000) == 0)
334 regalloc(&nod1, l, Z);
336 regalloc(&nod, l, nn);
338 gins(ACMPL, &nod1, nodconst(c));
339 gins(ASBBL, nodconst(-1), &nod);
348 if(l->addable >= INDEXED) {
353 /* should favour AX */
354 regalloc(&nod, l, nn);
356 if(r->addable < INDEXED || hardconst(r)) {
357 regalloc(&nod1, r, Z);
359 gopcode(OMUL, n->type, &nod1, &nod);
362 gopcode(OMUL, n->type, r, &nod); /* addressible */
370 * get nod1 to be D_DX
372 if(nodreg(&nod, nn, D_AX)) {
394 if(nodreg(&nod1, nn, D_DX)) {
418 if(r->op == OCONST && (o == ODIV || o == OLDIV) && immconst(r) && typechl[r->type->etype]) {
420 if(l->addable < INDEXED) {
421 regalloc(&nod2, l, Z);
426 sdivgen(l, r, &nod, &nod1);
428 udivgen(l, r, &nod, &nod1);
435 if(l->complex >= r->complex) {
438 if(o == ODIV || o == OMOD)
439 gins(typechl[l->type->etype]? ACDQ: ACQO, Z, Z);
440 if(o == OLDIV || o == OLMOD)
442 if(r->addable < INDEXED || r->op == OCONST) {
443 regalloc(&nod3, r, Z);
445 gopcode(o, n->type, &nod3, Z);
448 gopcode(o, n->type, r, Z);
454 if(o == ODIV || o == OMOD)
455 gins(typechl[l->type->etype]? ACDQ: ACQO, Z, Z);
456 if(o == OLDIV || o == OLMOD)
458 gopcode(o, n->type, &nod3, Z);
460 if(o == OMOD || o == OLMOD)
476 if(typefd[n->type->etype])
477 goto asand; /* can this happen? */
482 if(nodreg(&nod, nn, D_CX)) {
493 if(r->complex >= l->complex) {
496 reglcgen(&nod1, l, Z);
501 reglcgen(&nod1, l, Z);
507 gopcode(o, l->type, &nod, &nod1);
523 if(typefd[l->type->etype] || typefd[r->type->etype])
525 if(l->complex >= r->complex) {
527 reglcgen(&nod, l, Z);
531 regalloc(&nod1, r, nn);
533 gopcode(o, l->type, &nod1, &nod);
536 gopcode(o, l->type, r, &nod);
538 regalloc(&nod1, r, nn);
541 reglcgen(&nod, l, Z);
544 gopcode(o, l->type, &nod1, &nod);
554 if(l->complex >= r->complex) {
556 reglcgen(&nod, l, Z);
559 if(r->addable < INDEXED){
560 regalloc(&nod1, r, nn);
564 regalloc(&nod2, r, Z);
566 gopcode(o, r->type, &nod1, &nod2);
569 if(r->addable < INDEXED)
572 regalloc(&nod1, r, nn);
575 reglcgen(&nod, l, Z);
578 if(o != OASMUL && o != OASADD || !typefd[l->type->etype]) {
579 regalloc(&nod2, r, Z);
581 gopcode(o, r->type, &nod1, &nod2);
586 gopcode(o, r->type, &nod, &nod1);
605 if(typefd[n->type->etype] || typefd[r->type->etype])
607 if(r->op == OCONST && typechl[n->type->etype]) {
622 reglcgen(&nod2, l, Z);
625 regalloc(&nod, l, nn);
630 mulgen(n->type, r, &nod);
633 sdiv2(r->vconst, v, l, &nod);
636 smod2(r->vconst, v, l, &nod);
649 if((c & 0x80000000) == 0)
652 reglcgen(&nod2, l, Z);
655 regalloc(&nod1, l, nn);
657 regalloc(&nod, l, nn);
659 gins(ACMPL, &nod1, nodconst(c));
660 gins(ASBBL, nodconst(-1), &nod);
667 /* should favour AX */
668 regalloc(&nod, l, nn);
669 if(r->complex >= FNX) {
670 regalloc(&nod1, r, Z);
675 reglcgen(&nod2, l, Z);
679 if(r->addable < INDEXED || hardconst(r)) {
680 if(r->complex < FNX) {
681 regalloc(&nod1, r, Z);
684 gopcode(OASMUL, n->type, &nod1, &nod);
688 gopcode(OASMUL, n->type, r, &nod);
702 * get nod1 to be D_DX
704 if(nodreg(&nod, nn, D_AX)) {
726 if(nodreg(&nod1, nn, D_DX)) {
751 if(l->complex >= r->complex) {
753 reglcgen(&nod2, l, Z);
757 if(r->op == OCONST && typechl[r->type->etype]) {
760 sdivgen(&nod2, r, &nod, &nod1);
763 udivgen(&nod2, r, &nod, &nod1);
771 if(o == OASDIV || o == OASMOD)
772 gins(typechl[l->type->etype]? ACDQ: ACQO, Z, Z);
773 if(o == OASLDIV || o == OASLMOD)
775 if(r->addable < INDEXED || r->op == OCONST ||
776 !typeil[r->type->etype]) {
777 regalloc(&nod3, r, Z);
779 gopcode(o, l->type, &nod3, Z);
782 gopcode(o, n->type, r, Z);
784 regalloc(&nod3, r, Z);
787 reglcgen(&nod2, l, Z);
791 if(o == OASDIV || o == OASMOD)
792 gins(typechl[l->type->etype]? ACDQ: ACQO, Z, Z);
793 if(o == OASLDIV || o == OASLMOD)
795 gopcode(o, l->type, &nod3, Z);
798 if(o == OASMOD || o == OASLMOD) {
815 if(l->complex >= r->complex) {
816 regalloc(&nod, l, nn);
818 if(r->addable < INDEXED) {
819 regalloc(&nod1, r, Z);
821 gopcode(o, n->type, &nod1, &nod);
824 gopcode(o, n->type, r, &nod);
826 /* TO DO: could do better with r->addable >= INDEXED */
827 regalloc(&nod1, r, Z);
829 regalloc(&nod, l, nn);
831 gopcode(o, n->type, &nod1, &nod);
839 regalloc(&nod4, n, nn);
840 if(l->complex >= r->complex) {
841 bitload(l, &nod, &nod1, &nod2, &nod4);
842 regalloc(&nod3, r, Z);
845 regalloc(&nod3, r, Z);
847 bitload(l, &nod, &nod1, &nod2, &nod4);
851 { /* TO DO: check floating point source */
854 /* incredible grot ... */
867 bitstore(l, &nod, &nod1, &nod2, nn);
880 if(l->complex >= FNX) {
882 diag(n, "bad function call");
884 regret(&nod, l->left);
886 regsalloc(&nod1, l->left);
900 gargs(r, &nod, &nod1);
901 if(l->addable < INDEXED) {
902 reglcgen(&nod, l, nn);
904 gopcode(OFUNC, n->type, Z, &nod);
907 gopcode(OFUNC, n->type, Z, l);
923 regialloc(&nod, n, nn);
983 * convert from types l->n->nn
985 if(nocast(l->type, n->type) && nocast(n->type, nn->type)) {
986 /* both null, gen l->nn */
990 if(ewidth[n->type->etype] < ewidth[l->type->etype]){
991 if(l->type->etype == TIND && typechlp[n->type->etype])
992 warn(n, "conversion of pointer to shorter integer");
994 if(nocast(n->type, nn->type) || castup(n->type, nn->type)){
995 if(typefd[l->type->etype] != typefd[nn->type->etype])
996 regalloc(&nod, l, nn);
998 regalloc(&nod, nn, nn);
1005 regalloc(&nod, l, nn);
1007 regalloc(&nod1, n, &nod);
1015 sugen(l, nodrat, l->type->width);
1018 warn(n, "non-interruptable temporary");
1020 if(!r || r->op != OCONST) {
1021 diag(n, "DOT and no offset");
1024 nod.xoffset += (long)r->vconst;
1043 if(l->type->etype == TIND)
1044 v = l->type->link->width;
1053 reglcgen(&nod, l, Z);
1058 if(typefd[n->type->etype]) {
1059 regalloc(&nod1, l, Z);
1062 gopcode(OSUB, n->type, nodfconst(-v), &nod1);
1064 gopcode(OADD, n->type, nodfconst(v), &nod1);
1068 gopcode(OADD, n->type, nodconst(v), &nod);
1076 if(l->type->etype == TIND)
1077 v = l->type->link->width;
1085 reglcgen(&nod, l, Z);
1088 if(typefd[n->type->etype]) {
1089 regalloc(&nod1, l, Z);
1092 gopcode(OSUB, n->type, nodfconst(-v), &nod1);
1094 gopcode(OADD, n->type, nodfconst(v), &nod1);
1098 gopcode(OADD, n->type, nodconst(v), &nod);
1106 if(nn != Z && (o == OPOSTINC || o == OPOSTDEC)) {
1107 bitload(l, &nod, &nod1, &nod2, Z);
1109 gopcode(OADD, tfield, nodconst(v), &nod);
1110 bitstore(l, &nod, &nod1, &nod2, Z);
1113 bitload(l, &nod, &nod1, &nod2, nn);
1114 gopcode(OADD, tfield, nodconst(v), &nod);
1115 bitstore(l, &nod, &nod1, &nod2, nn);
1123 reglcgen(Node *t, Node *n, Node *nn)
1128 regialloc(t, n, nn);
1131 while(r->op == OADD)
1148 lcgen(Node *n, Node *nn)
1154 prtree(nn, "lcgen lhs");
1157 if(n == Z || n->type == T)
1161 regalloc(&nod, n, Z);
1165 if(n->addable < INDEXED) {
1166 diag(n, "unknown op in lcgen: %O", n->op);
1169 gopcode(OADDR, n->type, n, nn);
1173 cgen(n->left, n->left);
1174 lcgen(n->right, nn);
1184 lcgen(n->right->left, nn);
1188 lcgen(n->right->right, nn);
1195 bcgen(Node *n, int true)
1201 boolgen(n, true, Z);
1205 boolgen(Node *n, int true, Node *nn)
1209 Node *l, *r, nod, nod1;
1213 prtree(nn, "boolgen lhs");
1214 prtree(n, "boolgen");
1225 /* bad, 13 is address of external that becomes constant */
1226 if(n->addable >= INDEXED && n->addable != 13) {
1227 if(typefd[n->type->etype]) {
1228 regalloc(&nod1, n, Z);
1229 gmove(nodfconst(0.0), &nod1); /* TO DO: FREGZERO */
1230 gopcode(o, n->type, n, &nod1);
1233 gopcode(o, n->type, n, nodconst(0));
1236 regalloc(&nod, n, nn);
1238 if(typefd[n->type->etype]) {
1239 regalloc(&nod1, n, Z);
1240 gmove(nodfconst(0.0), &nod1); /* TO DO: FREGZERO */
1241 gopcode(o, n->type, &nod, &nod1);
1244 gopcode(o, n->type, &nod, nodconst(0));
1262 boolgen(r, true, nn);
1266 boolgen(l, !true, nn);
1272 bcgen(r->left, true);
1277 bcgen(r->right, !true);
1325 o = comrel[relindex(o)];
1326 if(l->complex >= FNX && r->complex >= FNX) {
1329 regsalloc(&nod1, r);
1334 boolgen(&nod, true, nn);
1338 o = invrel[relindex(o)];
1339 /* bad, 13 is address of external that becomes constant */
1340 if(r->addable < INDEXED || r->addable == 13) {
1341 regalloc(&nod, r, nn);
1343 gopcode(o, l->type, &nod, l);
1346 gopcode(o, l->type, r, l);
1349 if(typefd[l->type->etype])
1350 o = invrel[relindex(logrel[relindex(o)])];
1351 if(l->complex >= r->complex) {
1352 regalloc(&nod, l, nn);
1354 if(r->addable < INDEXED || hardconst(r) || typefd[l->type->etype]) {
1355 regalloc(&nod1, r, Z);
1357 gopcode(o, l->type, &nod, &nod1);
1360 gopcode(o, l->type, &nod, r);
1364 regalloc(&nod, r, nn);
1366 if(l->addable < INDEXED || l->addable == 13 || hardconst(l)) {
1367 regalloc(&nod1, l, Z);
1369 if(typechl[l->type->etype] && ewidth[l->type->etype] <= ewidth[TINT])
1370 gopcode(o, types[TINT], &nod1, &nod);
1372 gopcode(o, l->type, &nod1, &nod);
1375 gopcode(o, l->type, l, &nod);
1381 gmove(nodconst(1L), nn);
1385 gmove(nodconst(0L), nn);
1394 sugen(Node *n, Node *nn, long w)
1397 Node nod0, nod1, nod2, nod3, nod4, *l, *r;
1402 if(n == Z || n->type == T)
1405 prtree(nn, "sugen lhs");
1414 nullwarn(n->left, Z);
1426 sugen(l, nodrat, l->type->width);
1429 warn(n, "non-interruptable temporary");
1432 if(!r || r->op != OCONST) {
1433 diag(n, "DOT and no offset");
1436 nod1.xoffset += (long)r->vconst;
1437 nod1.type = n->type;
1438 sugen(&nod1, nn, w);
1443 * rewrite so lhs has no fn call
1445 if(nn != Z && side(nn)) {
1447 nod1.type = typ(TIND, n->type);
1448 regret(&nod2, &nod1);
1450 regsalloc(&nod0, &nod1);
1465 for(t = n->type->link; t != T; t = t->down) {
1467 if(r->op == OLIST) {
1476 * hand craft *(&nn + o) = l
1491 nod2.type = typ(TIND, t);
1497 nod3.type = nod2.type;
1502 nod4.type = nod2.type;
1503 nod4.vconst = t->offset;
1511 /* prtree(&nod0, "hand craft"); /* */
1518 if(n->addable < INDEXED)
1519 sugen(n->right, n->left, w);
1523 sugen(n->right, nodrat, w);
1524 warn(n, "non-interruptable temporary");
1525 sugen(nodrat, n->left, w);
1526 sugen(nodrat, nn, w);
1531 sugen(n, nodrat, w);
1534 if(nn->op != OIND) {
1535 nn = new1(OADDR, nn, Z);
1536 nn->type = types[TIND];
1540 n = new(OFUNC, n->left, new(OLIST, nn, n->right));
1542 n->type = types[TVOID];
1543 n->left->type = types[TVOID];
1550 sugen(n->right->left, nn, w);
1554 sugen(n->right->right, nn, w);
1560 sugen(n->right, nn, w);
1594 if(n->complex >= FNX && nn != nil && nn->complex >= FNX) {
1596 nn->type = types[TLONG];
1597 regialloc(&nod1, nn, Z);
1599 regsalloc(&nod2, &nod1);
1602 gins(AMOVQ, &nod1, &nod2);
1605 nod2.type = typ(TIND, t);
1620 if(n->left != Z && n->left->complex >= FNX
1621 && n->right != Z && n->right->complex >= FNX) {
1622 regsalloc(&nod1, n->right);
1623 cgen(n->right, &nod1);
1637 if(n->complex > nn->complex) {
1639 n->type = types[mt];
1640 regalloc(&nod0, n, Z);
1642 reglcgen(&nod1, n, Z);
1650 nn->type = types[mt];
1652 reglcgen(&nod2, nn, Z);
1660 nn->type = types[mt];
1661 regalloc(&nod0, nn, Z);
1663 reglcgen(&nod2, nn, Z);
1671 n->type = types[mt];
1673 reglcgen(&nod1, n, Z);
1685 gins(mo, &nod0, nn);
1686 n->xoffset += ewidth[mt];
1687 nn->xoffset += ewidth[mt];
1700 if(t != types[TIND]){
1701 n->type = types[TIND];
1707 if(t != types[TIND]){
1708 nn->type = types[TIND];
1714 if(nodreg(&nod1, n, D_SI)) {
1715 regsalloc(&nod4, &nod1);
1716 gmove(&nod1, &nod4);
1721 gmove(&nod4, &nod1);
1725 if(nodreg(&nod2, nn, D_DI)) {
1726 regsalloc(&nod4, &nod2);
1727 gmove(&nod2, &nod4);
1732 gmove(&nod4, &nod2);
1736 if(nodreg(&nod3, Z, D_CX)) {
1737 regsalloc(&nod4, &nod3);
1738 gmove(&nod3, &nod4);
1743 gmove(&nod4, &nod3);
1748 if(n->complex > nn->complex){
1763 gins(AMOVL, nodconst(w/SZ_LONG), &nod3);
1767 if(w & (SZ_LONG-1)) {
1768 /* odd length of packed structure */
1769 gins(AMOVL, nodconst(w & (SZ_LONG-1)), &nod3);
1783 layout(Node *f, Node *t, int c, int cv, Node *cn)
1788 layout(f, t, 2, 0, Z);
1792 regalloc(&t1, &lregnode, Z);
1793 regalloc(&t2, &lregnode, Z);
1796 f->xoffset += SZ_INT;
1799 gmove(nodconst(cv), cn);
1802 f->xoffset += SZ_INT;
1806 t->xoffset += SZ_INT;
1810 f->xoffset += SZ_INT;
1814 t->xoffset += SZ_INT;
1818 t->xoffset += SZ_INT;
1825 * constant is not vlong or fits as 32-bit signed immediate
1832 if(n->op != OCONST || !typechlpv[n->type->etype])
1834 if(typechl[n->type->etype])
1837 return n->vconst == (vlong)v;
1841 * if a constant and vlong, doesn't fit as 32-bit signed immediate
1846 return n->op == OCONST && !immconst(n);
1850 * casting up to t2 covers an intermediate cast to t1
1853 castup(Type *t1, Type *t2)
1857 if(!nilcast(t1, t2))
1859 /* known to be small to large */
1864 return ft == TLONG || ft == TINT || ft == TSHORT || ft == TCHAR;
1867 return ft == TULONG || ft == TUINT || ft == TUSHORT || ft == TUCHAR;
1869 return ft == TLONG || ft == TINT || ft == TSHORT;
1871 return ft == TULONG || ft == TUINT || ft == TUSHORT;
1879 gins(AMOVL, nodconst(0), n);
1882 /* do we need to load the address of a vlong? */
1884 vaddr(Node *n, int a)
1890 return !(n->class == CEXTERN || n->class == CGLOBL || n->class == CSTATIC);
1903 if(align(0, types[TCHAR], Aarg1)) /* isbigendian */
1904 return (long)(n->vconst) & ~0L;
1906 return (long)((uvlong)n->vconst>>32) & ~0L;
1912 if(align(0, types[TCHAR], Aarg1)) /* isbigendian */
1913 return (long)((uvlong)n->vconst>>32) & ~0L;
1915 return (long)(n->vconst) & ~0L;
1921 return nodconst(hi64v(n));
1927 return nodconst(lo64v(n));