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);
169 if(r->op == OCONST) {
174 regalloc(&nod, l, nn);
176 if(o == OASHL && r->vconst == 1)
177 gopcode(OADD, n->type, &nod, &nod);
179 gopcode(o, n->type, r, &nod);
188 if(nodreg(&nod, nn, D_CX)) {
191 cgen(n, &nod); /* probably a bug */
197 if(nn->op == OREGISTER && nn->reg == D_CX)
198 regalloc(&nod1, l, Z);
200 regalloc(&nod1, l, nn);
201 if(r->complex >= l->complex) {
208 gopcode(o, n->type, &nod, &nod1);
223 if(typefd[n->type->etype])
225 if(r->op == OCONST) {
226 if(r->vconst == 0 && o != OAND) {
231 if(n->op == OADD && l->op == OASHL && l->right->op == OCONST
232 && (r->op != OCONST || r->vconst < -128 || r->vconst > 127)) {
233 c = l->right->vconst;
234 if(c > 0 && c <= 3) {
235 if(l->left->complex >= r->complex) {
236 regalloc(&nod, l->left, nn);
238 if(r->addable < INDEXED) {
239 regalloc(&nod1, r, Z);
241 genmuladd(&nod, &nod, 1 << c, &nod1);
245 genmuladd(&nod, &nod, 1 << c, r);
248 regalloc(&nod, r, nn);
250 regalloc(&nod1, l->left, Z);
251 cgen(l->left, &nod1);
252 genmuladd(&nod, &nod1, 1 << c, &nod);
260 if(r->addable >= INDEXED && !hardconst(r)) {
261 regalloc(&nod, l, nn);
263 gopcode(o, n->type, r, &nod);
268 if(l->complex >= r->complex) {
269 regalloc(&nod, l, nn);
271 regalloc(&nod1, r, Z);
273 gopcode(o, n->type, &nod1, &nod);
275 regalloc(&nod1, r, nn);
277 regalloc(&nod, l, Z);
279 gopcode(o, n->type, &nod1, &nod);
296 if(typefd[n->type->etype])
298 if(r->op == OCONST && typechl[n->type->etype]) { /* TO DO */
312 regalloc(&nod, l, nn);
317 mulgen(n->type, r, &nod);
320 sdiv2(r->vconst, v, l, &nod);
323 smod2(r->vconst, v, l, &nod);
331 if((c & 0x80000000) == 0)
333 regalloc(&nod1, l, Z);
335 regalloc(&nod, l, nn);
337 gins(ACMPL, &nod1, nodconst(c));
338 gins(ASBBL, nodconst(-1), &nod);
347 if(l->addable >= INDEXED) {
352 /* should favour AX */
353 regalloc(&nod, l, nn);
355 if(r->addable < INDEXED || hardconst(r)) {
356 regalloc(&nod1, r, Z);
358 gopcode(OMUL, n->type, &nod1, &nod);
361 gopcode(OMUL, n->type, r, &nod); /* addressible */
369 * get nod1 to be D_DX
371 if(nodreg(&nod, nn, D_AX)) {
393 if(nodreg(&nod1, nn, D_DX)) {
417 if(r->op == OCONST && (o == ODIV || o == OLDIV) && immconst(r) && typechl[r->type->etype]) {
419 if(l->addable < INDEXED) {
420 regalloc(&nod2, l, Z);
425 sdivgen(l, r, &nod, &nod1);
427 udivgen(l, r, &nod, &nod1);
434 if(l->complex >= r->complex) {
437 if(o == ODIV || o == OMOD)
438 gins(typechl[l->type->etype]? ACDQ: ACQO, Z, Z);
439 if(o == OLDIV || o == OLMOD)
441 if(r->addable < INDEXED || r->op == OCONST) {
442 regalloc(&nod3, r, Z);
444 gopcode(o, n->type, &nod3, Z);
447 gopcode(o, n->type, r, Z);
453 if(o == ODIV || o == OMOD)
454 gins(typechl[l->type->etype]? ACDQ: ACQO, Z, Z);
455 if(o == OLDIV || o == OLMOD)
457 gopcode(o, n->type, &nod3, Z);
459 if(o == OMOD || o == OLMOD)
475 if(typefd[n->type->etype])
476 goto asand; /* can this happen? */
481 if(nodreg(&nod, nn, D_CX)) {
492 if(r->complex >= l->complex) {
495 reglcgen(&nod1, l, Z);
500 reglcgen(&nod1, l, Z);
506 gopcode(o, l->type, &nod, &nod1);
522 if(typefd[l->type->etype] || typefd[r->type->etype])
524 if(l->complex >= r->complex) {
526 reglcgen(&nod, l, Z);
530 regalloc(&nod1, r, nn);
532 gopcode(o, l->type, &nod1, &nod);
535 gopcode(o, l->type, r, &nod);
537 regalloc(&nod1, r, nn);
540 reglcgen(&nod, l, Z);
543 gopcode(o, l->type, &nod1, &nod);
553 if(l->complex >= r->complex) {
555 reglcgen(&nod, l, Z);
558 if(r->addable < INDEXED){
559 regalloc(&nod1, r, nn);
563 regalloc(&nod2, r, Z);
565 gopcode(o, r->type, &nod1, &nod2);
568 if(r->addable < INDEXED)
571 regalloc(&nod1, r, nn);
574 reglcgen(&nod, l, Z);
577 if(o != OASMUL && o != OASADD || !typefd[l->type->etype]) {
578 regalloc(&nod2, r, Z);
580 gopcode(o, r->type, &nod1, &nod2);
585 gopcode(o, r->type, &nod, &nod1);
604 if(typefd[n->type->etype] || typefd[r->type->etype])
606 if(r->op == OCONST && typechl[n->type->etype]) {
621 reglcgen(&nod2, l, Z);
624 regalloc(&nod, l, nn);
629 mulgen(n->type, r, &nod);
632 sdiv2(r->vconst, v, l, &nod);
635 smod2(r->vconst, v, l, &nod);
648 if((c & 0x80000000) == 0)
651 reglcgen(&nod2, l, Z);
654 regalloc(&nod1, l, nn);
656 regalloc(&nod, l, nn);
658 gins(ACMPL, &nod1, nodconst(c));
659 gins(ASBBL, nodconst(-1), &nod);
666 /* should favour AX */
667 regalloc(&nod, l, nn);
668 if(r->complex >= FNX) {
669 regalloc(&nod1, r, Z);
674 reglcgen(&nod2, l, Z);
678 if(r->addable < INDEXED || hardconst(r)) {
679 if(r->complex < FNX) {
680 regalloc(&nod1, r, Z);
683 gopcode(OASMUL, n->type, &nod1, &nod);
687 gopcode(OASMUL, n->type, r, &nod);
701 * get nod1 to be D_DX
703 if(nodreg(&nod, nn, D_AX)) {
725 if(nodreg(&nod1, nn, D_DX)) {
750 if(l->complex >= r->complex) {
752 reglcgen(&nod2, l, Z);
756 if(r->op == OCONST && typechl[r->type->etype]) {
759 sdivgen(&nod2, r, &nod, &nod1);
762 udivgen(&nod2, r, &nod, &nod1);
770 if(o == OASDIV || o == OASMOD)
771 gins(typechl[l->type->etype]? ACDQ: ACQO, Z, Z);
772 if(o == OASLDIV || o == OASLMOD)
774 if(r->addable < INDEXED || r->op == OCONST ||
775 !typeil[r->type->etype]) {
776 regalloc(&nod3, r, Z);
778 gopcode(o, l->type, &nod3, Z);
781 gopcode(o, n->type, r, Z);
783 regalloc(&nod3, r, Z);
786 reglcgen(&nod2, l, Z);
790 if(o == OASDIV || o == OASMOD)
791 gins(typechl[l->type->etype]? ACDQ: ACQO, Z, Z);
792 if(o == OASLDIV || o == OASLMOD)
794 gopcode(o, l->type, &nod3, Z);
797 if(o == OASMOD || o == OASLMOD) {
814 if(l->complex >= r->complex) {
815 regalloc(&nod, l, nn);
817 if(r->addable < INDEXED) {
818 regalloc(&nod1, r, Z);
820 gopcode(o, n->type, &nod1, &nod);
823 gopcode(o, n->type, r, &nod);
825 /* TO DO: could do better with r->addable >= INDEXED */
826 regalloc(&nod1, r, Z);
828 regalloc(&nod, l, nn);
830 gopcode(o, n->type, &nod1, &nod);
838 regalloc(&nod4, n, nn);
839 if(l->complex >= r->complex) {
840 bitload(l, &nod, &nod1, &nod2, &nod4);
841 regalloc(&nod3, r, Z);
844 regalloc(&nod3, r, Z);
846 bitload(l, &nod, &nod1, &nod2, &nod4);
850 { /* TO DO: check floating point source */
853 /* incredible grot ... */
866 bitstore(l, &nod, &nod1, &nod2, nn);
878 if(l->complex >= FNX) {
880 diag(n, "bad function call");
882 regret(&nod, l->left);
884 regsalloc(&nod1, l->left);
898 gargs(r, &nod, &nod1);
899 if(l->addable < INDEXED) {
900 reglcgen(&nod, l, nn);
902 gopcode(OFUNC, n->type, Z, &nod);
905 gopcode(OFUNC, n->type, Z, l);
921 regialloc(&nod, n, nn);
981 * convert from types l->n->nn
983 if(nocast(l->type, n->type) && nocast(n->type, nn->type)) {
984 /* both null, gen l->nn */
988 if(ewidth[n->type->etype] < ewidth[l->type->etype]){
989 if(l->type->etype == TIND && typechlp[n->type->etype])
990 warn(n, "conversion of pointer to shorter integer");
992 if(nocast(n->type, nn->type) || castup(n->type, nn->type)){
993 if(typefd[l->type->etype] != typefd[nn->type->etype])
994 regalloc(&nod, l, nn);
996 regalloc(&nod, nn, nn);
1003 regalloc(&nod, l, nn);
1005 regalloc(&nod1, n, &nod);
1013 sugen(l, nodrat, l->type->width);
1016 warn(n, "non-interruptable temporary");
1018 if(!r || r->op != OCONST) {
1019 diag(n, "DOT and no offset");
1022 nod.xoffset += (long)r->vconst;
1041 if(l->type->etype == TIND)
1042 v = l->type->link->width;
1051 reglcgen(&nod, l, Z);
1056 if(typefd[n->type->etype]) {
1057 regalloc(&nod1, l, Z);
1060 gopcode(OSUB, n->type, nodfconst(-v), &nod1);
1062 gopcode(OADD, n->type, nodfconst(v), &nod1);
1066 gopcode(OADD, n->type, nodconst(v), &nod);
1074 if(l->type->etype == TIND)
1075 v = l->type->link->width;
1083 reglcgen(&nod, l, Z);
1086 if(typefd[n->type->etype]) {
1087 regalloc(&nod1, l, Z);
1090 gopcode(OSUB, n->type, nodfconst(-v), &nod1);
1092 gopcode(OADD, n->type, nodfconst(v), &nod1);
1096 gopcode(OADD, n->type, nodconst(v), &nod);
1104 if(nn != Z && (o == OPOSTINC || o == OPOSTDEC)) {
1105 bitload(l, &nod, &nod1, &nod2, Z);
1107 gopcode(OADD, tfield, nodconst(v), &nod);
1108 bitstore(l, &nod, &nod1, &nod2, Z);
1111 bitload(l, &nod, &nod1, &nod2, nn);
1112 gopcode(OADD, tfield, nodconst(v), &nod);
1113 bitstore(l, &nod, &nod1, &nod2, nn);
1121 reglcgen(Node *t, Node *n, Node *nn)
1126 regialloc(t, n, nn);
1129 while(r->op == OADD)
1146 lcgen(Node *n, Node *nn)
1152 prtree(nn, "lcgen lhs");
1155 if(n == Z || n->type == T)
1159 regalloc(&nod, n, Z);
1163 if(n->addable < INDEXED) {
1164 diag(n, "unknown op in lcgen: %O", n->op);
1167 gopcode(OADDR, n->type, n, nn);
1171 cgen(n->left, n->left);
1172 lcgen(n->right, nn);
1182 lcgen(n->right->left, nn);
1186 lcgen(n->right->right, nn);
1193 bcgen(Node *n, int true)
1199 boolgen(n, true, Z);
1203 boolgen(Node *n, int true, Node *nn)
1207 Node *l, *r, nod, nod1;
1211 prtree(nn, "boolgen lhs");
1212 prtree(n, "boolgen");
1223 /* bad, 13 is address of external that becomes constant */
1224 if(n->addable >= INDEXED && n->addable != 13) {
1225 if(typefd[n->type->etype]) {
1226 regalloc(&nod1, n, Z);
1227 gmove(nodfconst(0.0), &nod1); /* TO DO: FREGZERO */
1228 gopcode(o, n->type, n, &nod1);
1231 gopcode(o, n->type, n, nodconst(0));
1234 regalloc(&nod, n, nn);
1236 if(typefd[n->type->etype]) {
1237 regalloc(&nod1, n, Z);
1238 gmove(nodfconst(0.0), &nod1); /* TO DO: FREGZERO */
1239 gopcode(o, n->type, &nod, &nod1);
1242 gopcode(o, n->type, &nod, nodconst(0));
1260 boolgen(r, true, nn);
1264 boolgen(l, !true, nn);
1270 bcgen(r->left, true);
1275 bcgen(r->right, !true);
1323 o = comrel[relindex(o)];
1324 if(l->complex >= FNX && r->complex >= FNX) {
1327 regsalloc(&nod1, r);
1332 boolgen(&nod, true, nn);
1336 o = invrel[relindex(o)];
1337 /* bad, 13 is address of external that becomes constant */
1338 if(r->addable < INDEXED || r->addable == 13) {
1339 regalloc(&nod, r, nn);
1341 gopcode(o, l->type, &nod, l);
1344 gopcode(o, l->type, r, l);
1347 if(typefd[l->type->etype])
1348 o = invrel[relindex(logrel[relindex(o)])];
1349 if(l->complex >= r->complex) {
1350 regalloc(&nod, l, nn);
1352 if(r->addable < INDEXED || hardconst(r) || typefd[l->type->etype]) {
1353 regalloc(&nod1, r, Z);
1355 gopcode(o, l->type, &nod, &nod1);
1358 gopcode(o, l->type, &nod, r);
1362 regalloc(&nod, r, nn);
1364 if(l->addable < INDEXED || l->addable == 13 || hardconst(l)) {
1365 regalloc(&nod1, l, Z);
1367 if(typechl[l->type->etype] && ewidth[l->type->etype] <= ewidth[TINT])
1368 gopcode(o, types[TINT], &nod1, &nod);
1370 gopcode(o, l->type, &nod1, &nod);
1373 gopcode(o, l->type, l, &nod);
1379 gmove(nodconst(1L), nn);
1383 gmove(nodconst(0L), nn);
1392 sugen(Node *n, Node *nn, long w)
1395 Node nod0, nod1, nod2, nod3, nod4, *l, *r;
1400 if(n == Z || n->type == T)
1403 prtree(nn, "sugen lhs");
1412 nullwarn(n->left, Z);
1424 sugen(l, nodrat, l->type->width);
1427 warn(n, "non-interruptable temporary");
1430 if(!r || r->op != OCONST) {
1431 diag(n, "DOT and no offset");
1434 nod1.xoffset += (long)r->vconst;
1435 nod1.type = n->type;
1436 sugen(&nod1, nn, w);
1441 * rewrite so lhs has no fn call
1443 if(nn != Z && side(nn)) {
1445 nod1.type = typ(TIND, n->type);
1446 regret(&nod2, &nod1);
1448 regsalloc(&nod0, &nod1);
1463 for(t = n->type->link; t != T; t = t->down) {
1465 if(r->op == OLIST) {
1474 * hand craft *(&nn + o) = l
1489 nod2.type = typ(TIND, t);
1495 nod3.type = nod2.type;
1500 nod4.type = nod2.type;
1501 nod4.vconst = t->offset;
1509 /* prtree(&nod0, "hand craft"); /* */
1516 if(n->addable < INDEXED)
1517 sugen(n->right, n->left, w);
1521 sugen(n->right, nodrat, w);
1522 warn(n, "non-interruptable temporary");
1523 sugen(nodrat, n->left, w);
1524 sugen(nodrat, nn, w);
1529 sugen(n, nodrat, w);
1532 if(nn->op != OIND) {
1533 nn = new1(OADDR, nn, Z);
1534 nn->type = types[TIND];
1538 n = new(OFUNC, n->left, new(OLIST, nn, n->right));
1539 n->type = types[TVOID];
1540 n->left->type = types[TVOID];
1547 sugen(n->right->left, nn, w);
1551 sugen(n->right->right, nn, w);
1557 sugen(n->right, nn, w);
1591 if(n->complex >= FNX && nn != nil && nn->complex >= FNX) {
1593 nn->type = types[TLONG];
1594 regialloc(&nod1, nn, Z);
1596 regsalloc(&nod2, nn);
1599 gins(AMOVQ, &nod1, &nod2);
1602 nod2.type = typ(TIND, t);
1617 if(n->left != Z && n->left->complex >= FNX
1618 && n->right != Z && n->right->complex >= FNX) {
1619 regsalloc(&nod1, n->right);
1620 cgen(n->right, &nod1);
1634 if(n->complex > nn->complex) {
1636 n->type = types[mt];
1637 regalloc(&nod0, n, Z);
1639 reglcgen(&nod1, n, Z);
1647 nn->type = types[mt];
1649 reglcgen(&nod2, nn, Z);
1657 nn->type = types[mt];
1658 regalloc(&nod0, nn, Z);
1660 reglcgen(&nod2, nn, Z);
1668 n->type = types[mt];
1670 reglcgen(&nod1, n, Z);
1682 gins(mo, &nod0, nn);
1683 n->xoffset += ewidth[mt];
1684 nn->xoffset += ewidth[mt];
1696 /* botch, need to save in .safe */
1698 if(n->complex > nn->complex) {
1700 n->type = types[TIND];
1701 nodreg(&nod1, n, D_SI);
1703 gins(APUSHQ, &nod1, Z);
1711 nn->type = types[TIND];
1712 nodreg(&nod2, nn, D_DI);
1714 warn(Z, "DI botch");
1715 gins(APUSHQ, &nod2, Z);
1723 nn->type = types[TIND];
1724 nodreg(&nod2, nn, D_DI);
1726 warn(Z, "DI botch");
1727 gins(APUSHQ, &nod2, Z);
1735 n->type = types[TIND];
1736 nodreg(&nod1, n, D_SI);
1738 gins(APUSHQ, &nod1, Z);
1745 nodreg(&nod3, n, D_CX);
1747 gins(APUSHQ, &nod3, Z);
1751 gins(AMOVL, nodconst(w/SZ_INT), &nod3);
1756 gins(APOPQ, Z, &nod3);
1760 gins(APOPQ, Z, &nod2);
1764 gins(APOPQ, Z, &nod1);
1773 layout(Node *f, Node *t, int c, int cv, Node *cn)
1778 layout(f, t, 2, 0, Z);
1782 regalloc(&t1, &lregnode, Z);
1783 regalloc(&t2, &lregnode, Z);
1786 f->xoffset += SZ_INT;
1789 gmove(nodconst(cv), cn);
1792 f->xoffset += SZ_INT;
1796 t->xoffset += SZ_INT;
1800 f->xoffset += SZ_INT;
1804 t->xoffset += SZ_INT;
1808 t->xoffset += SZ_INT;
1815 * constant is not vlong or fits as 32-bit signed immediate
1822 if(n->op != OCONST || !typechlpv[n->type->etype])
1824 if(typechl[n->type->etype])
1827 return n->vconst == (vlong)v;
1831 * if a constant and vlong, doesn't fit as 32-bit signed immediate
1836 return n->op == OCONST && !immconst(n);
1840 * casting up to t2 covers an intermediate cast to t1
1843 castup(Type *t1, Type *t2)
1847 if(!nilcast(t1, t2))
1849 /* known to be small to large */
1854 return ft == TLONG || ft == TINT || ft == TSHORT || ft == TCHAR;
1857 return ft == TULONG || ft == TUINT || ft == TUSHORT || ft == TUCHAR;
1859 return ft == TLONG || ft == TINT || ft == TSHORT;
1861 return ft == TULONG || ft == TUINT || ft == TUSHORT;
1869 gins(AMOVL, nodconst(0), n);
1872 /* do we need to load the address of a vlong? */
1874 vaddr(Node *n, int a)
1880 return !(n->class == CEXTERN || n->class == CGLOBL || n->class == CSTATIC);
1893 if(align(0, types[TCHAR], Aarg1)) /* isbigendian */
1894 return (long)(n->vconst) & ~0L;
1896 return (long)((uvlong)n->vconst>>32) & ~0L;
1902 if(align(0, types[TCHAR], Aarg1)) /* isbigendian */
1903 return (long)((uvlong)n->vconst>>32) & ~0L;
1905 return (long)(n->vconst) & ~0L;
1911 return nodconst(hi64v(n));
1917 return nodconst(lo64v(n));