3 static void cmpv(Node*, int, Node*);
4 static void testv(Node*, int);
5 static void cgen64(Node*, Node*);
6 static int isvconstable(int, vlong);
7 static void genasop(int, Node*, Node*, Node*);
10 cgen(Node *n, Node *nn)
14 Node nod, nod1, nod2, nod3, nod4;
19 prtree(nn, "cgen lhs");
22 if(n == Z || n->type == T)
24 if(typesu[n->type->etype]) {
25 sugen(n, nn, n->type->width);
28 if(typev[n->type->etype]) {
39 if(n->addable >= INDEXED) {
58 if(r != Z && r->complex >= FNX)
61 if(!typev[r->type->etype]) {
88 diag(n, "unknown op in cgen: %O", o);
97 regalloc(&nod, l, nn);
99 gopcode(o, &nod, Z, &nod);
107 if(l->addable >= INDEXED) {
108 if(nn != Z || r->addable < INDEXED) {
109 regalloc(&nod, r, nn);
117 if(l->complex >= r->complex) {
118 reglcgen(&nod1, l, Z);
119 if(r->addable >= INDEXED) {
126 regalloc(&nod, r, nn);
129 regalloc(&nod, r, nn);
131 reglcgen(&nod1, l, Z);
140 regalloc(&nod, r, nn);
141 if(l->complex >= r->complex) {
142 reglcgen(&nod1, n, Z);
146 reglcgen(&nod1, n, Z);
148 regalloc(&nod2, n, Z);
149 gopcode(OAS, &nod1, Z, &nod2);
150 bitstore(l, &nod, &nod1, &nod2, nn);
158 bitload(n, &nod, Z, Z, nn);
159 gopcode(OAS, &nod, Z, nn);
165 if(r->op == OCONST && r->vconst == -1){
166 regalloc(&nod, l, nn);
168 gopcode(OCOM, &nod, Z, &nod);
184 if(nn != Z && r->op == OCONST && !typefd[n->type->etype] &&
185 (!typev[n->type->etype] || isvconstable(o, r->vconst))) {
186 regalloc(&nod, l, nn);
188 if(o == OAND || r->vconst != 0)
189 gopcode(o, r, Z, &nod);
205 if((o == OMUL || o == OLMUL) && !typev[n->type->etype]) {
209 print("%L multiply\n", n->lineno);
211 if(l->complex >= r->complex) {
212 regalloc(&nod, l, nn);
214 if(o != OMUL || typev[n->type->etype] || !sconst(r)) {
215 regalloc(&nod1, r, Z);
217 gopcode(o, &nod1, Z, &nod);
220 gopcode(o, r, Z, &nod);
222 regalloc(&nod1, r, nn);
224 regalloc(&nod, l, Z);
226 gopcode(o, &nod1, Z, &nod);
229 gopcode(OAS, &nod, Z, nn);
243 if(r->op == OCONST && !typefd[r->type->etype] && !typefd[n->type->etype] &&
244 (!typev[n->type->etype] || isvconstable(o, r->vconst))) {
245 if(l->addable < INDEXED)
246 reglcgen(&nod2, l, Z);
249 regalloc(&nod, l, nn);
250 gopcode(OAS, &nod2, Z, &nod);
251 gopcode(o, r, Z, &nod);
252 gopcode(OAS, &nod, Z, &nod2);
255 if(l->addable < INDEXED)
259 genasop(o, l, r, nn);
270 genasop(o, l, r, nn);
274 regalloc(&nod4, n, nn);
275 regalloc(&nod3, r, Z);
276 if(l->complex >= r->complex) {
277 bitload(l, &nod, &nod1, &nod2, &nod4);
281 bitload(l, &nod, &nod1, &nod2, &nod4);
284 gopcode(n->op, &nod3, Z, &nod4);
288 bitstore(l, &nod, &nod1, &nod2, nn);
300 if(l->complex >= FNX) {
302 diag(n, "bad function call");
304 regret(&nod, l->left);
306 regsalloc(&nod1, l->left);
307 gopcode(OAS, &nod, Z, &nod1);
320 gargs(r, &nod, &nod1);
321 if(l->addable < INDEXED) {
322 reglcgen(&nod, l, Z);
323 gopcode(OFUNC, Z, Z, &nod);
326 gopcode(OFUNC, Z, Z, l);
332 gopcode(OAS, &nod, Z, nn);
342 regialloc(&nod, n, nn);
402 * convert from types l->n->nn
404 if(nocast(l->type, n->type) && nocast(n->type, nn->type)) {
405 /* both null, gen l->nn */
409 if(typev[l->type->etype] || typev[n->type->etype]) {
413 regalloc(&nod, l, nn);
415 regalloc(&nod1, n, &nod);
423 sugen(l, nodrat, l->type->width);
425 warn(n, "non-interruptable temporary");
427 if(!r || r->op != OCONST) {
428 diag(n, "DOT and no offset");
431 nod.xoffset += (long)r->vconst;
451 if(l->type->etype == TIND)
452 v = l->type->link->width;
460 if(l->addable < INDEXED)
461 reglcgen(&nod2, l, Z);
465 regalloc(&nod, l, nn);
466 gopcode(OAS, &nod2, Z, &nod);
467 regalloc(&nod1, l, Z);
468 if(typefd[l->type->etype]) {
469 regalloc(&nod3, l, Z);
471 gopcode(OAS, nodfconst(-v), Z, &nod3);
472 gopcode(OSUB, &nod3, &nod, &nod1);
474 gopcode(OAS, nodfconst(v), Z, &nod3);
475 gopcode(OADD, &nod3, &nod, &nod1);
479 gopcode(OADD, nodconst(v), &nod, &nod1);
480 gopcode(OAS, &nod1, Z, &nod2);
484 if(l->addable < INDEXED)
491 if(l->type->etype == TIND)
492 v = l->type->link->width;
499 if(l->addable < INDEXED)
500 reglcgen(&nod2, l, Z);
504 regalloc(&nod, l, nn);
505 gopcode(OAS, &nod2, Z, &nod);
506 if(typefd[l->type->etype]) {
507 regalloc(&nod3, l, Z);
509 gopcode(OAS, nodfconst(-v), Z, &nod3);
510 gopcode(OSUB, &nod3, Z, &nod);
512 gopcode(OAS, nodfconst(v), Z, &nod3);
513 gopcode(OADD, &nod3, Z, &nod);
517 gopcode(OADD, nodconst(v), Z, &nod);
518 gopcode(OAS, &nod, Z, &nod2);
519 if(nn && l->op == ONAME) /* in x=++i, emit USED(i) */
523 if(l->addable < INDEXED)
528 if(nn != Z && (o == OPOSTINC || o == OPOSTDEC)) {
529 bitload(l, &nod, &nod1, &nod2, Z);
530 gopcode(OAS, &nod, Z, nn);
531 gopcode(OADD, nodconst(v), Z, &nod);
532 bitstore(l, &nod, &nod1, &nod2, Z);
535 bitload(l, &nod, &nod1, &nod2, nn);
536 gopcode(OADD, nodconst(v), Z, &nod);
537 bitstore(l, &nod, &nod1, &nod2, nn);
544 genasop(int o, Node *l, Node *r, Node *nn)
546 Node nod, nod1, nod2;
549 hardleft = l->addable < INDEXED || l->complex >= FNX;
550 if(l->complex >= r->complex) {
552 reglcgen(&nod2, l, Z);
555 regalloc(&nod1, r, Z);
558 regalloc(&nod1, r, Z);
561 reglcgen(&nod2, l, Z);
565 if(nod1.type == nod2.type || !typefd[nod1.type->etype])
566 regalloc(&nod, &nod2, nn);
568 regalloc(&nod, &nod1, Z);
570 gopcode(o, &nod1, Z, &nod);
581 reglcgen(Node *t, Node *n, Node *nn)
606 lcgen(Node *n, Node *nn)
612 prtree(nn, "lcgen lhs");
615 if(n == Z || n->type == T)
619 regalloc(&nod, n, Z);
623 if(n->addable < INDEXED) {
624 diag(n, "unknown op in lcgen: %O", n->op);
631 nod.type = types[TIND];
632 gopcode(OAS, &nod, Z, nn);
636 cgen(n->left, n->left);
647 lcgen(n->right->left, nn);
651 lcgen(n->right->right, nn);
658 bcgen(Node *n, int true)
668 boolgen(Node *n, int true, Node *nn)
672 Node *l, *r, nod, nod1;
676 prtree(nn, "boolgen lhs");
677 prtree(n, "boolgen");
686 if(n->op == OCONST) {
698 if(typev[n->type->etype]) {
702 regalloc(&nod, n, nn);
706 o = comrel[relindex(o)];
707 if(typefd[n->type->etype]) {
708 nodreg(&nod1, n, NREG+FREGZERO);
709 gopcode(o, &nod, Z, &nod1);
711 gopcode(o, &nod, Z, nodconst(0));
717 boolgen(r, true, nn);
721 boolgen(l, !true, nn);
727 bcgen(r->left, true);
732 bcgen(r->right, !true);
780 if(typev[l->type->etype]){
786 o = comrel[relindex(o)];
787 if(l->complex >= FNX && r->complex >= FNX) {
791 gopcode(OAS, &nod, Z, &nod1);
795 boolgen(&nod, true, nn);
798 if(!uns && sconst(r) || (uns || o == OEQ || o == ONE) && uconst(r)) {
799 regalloc(&nod, l, nn);
801 gopcode(o, &nod, Z, r);
805 if(l->complex >= r->complex) {
806 regalloc(&nod1, l, nn);
808 regalloc(&nod, r, Z);
811 regalloc(&nod, r, nn);
813 regalloc(&nod1, l, Z);
816 gopcode(o, &nod1, Z, &nod);
823 gopcode(OAS, nodconst(1L), Z, nn);
827 gopcode(OAS, nodconst(0L), Z, nn);
836 sugen(Node *n, Node *nn, long w)
839 Node nod0, nod1, nod2, nod3, nod4, *l, *r;
844 if(n == Z || n->type == T)
850 prtree(nn, "sugen lhs");
853 if(typev[n->type->etype]) {
854 diag(n, "old vlong sugen: %O", n->op);
860 nullwarn(n->left, Z);
869 sugen(l, nodrat, l->type->width);
871 warn(n, "non-interruptable temporary");
874 if(!r || r->op != OCONST) {
875 diag(n, "DOT and no offset");
878 nod1.xoffset += (long)r->vconst;
886 * rewrite so lhs has no side effects
888 if(nn != Z && side(nn)) {
890 nod1.type = typ(TIND, n->type);
891 regalloc(&nod2, &nod1, Z);
893 regsalloc(&nod0, &nod1);
894 gopcode(OAS, &nod2, Z, &nod0);
908 for(t = n->type->link; t != T; t = t->down) {
919 * hand craft *(&nn + o) = l
934 nod2.type = typ(TIND, t);
940 nod3.type = nod2.type;
945 nod4.type = nod2.type;
946 nod4.vconst = t->offset;
953 /* prtree(&nod0, "hand craft"); /* */
960 if(n->addable < INDEXED)
961 sugen(n->right, n->left, w);
964 /* BOTCH -- functions can clobber rathole */
965 sugen(n->right, nodrat, w);
966 warn(n, "non-interruptable temporary");
967 sugen(nodrat, n->left, w);
968 sugen(nodrat, nn, w);
972 /* this transformation should probably be done earlier */
978 nn = new1(OADDR, nn, Z);
979 nn->type = types[TIND];
983 n = new(OFUNC, n->left, new(OLIST, nn, n->right));
985 n->type = types[TVOID];
986 n->left->type = types[TVOID];
993 sugen(n->right->left, nn, w);
997 sugen(n->right->right, nn, w);
1003 sugen(n->right, nn, w);
1011 if(n->complex >= FNX && nn->complex >= FNX) {
1013 nn->type = types[TLONG];
1014 regialloc(&nod1, nn, Z);
1016 regsalloc(&nod2, nn);
1019 gmove(&nod1, &nod2);
1022 nod2.type = typ(TIND, t);
1035 if(n->complex > nn->complex) {
1037 n->type = types[TLONG];
1038 reglcgen(&nod1, n, Z);
1042 nn->type = types[TLONG];
1043 reglcgen(&nod2, nn, Z);
1047 nn->type = types[TLONG];
1048 reglcgen(&nod2, nn, Z);
1052 n->type = types[TLONG];
1053 reglcgen(&nod1, n, Z);
1059 layout(&nod1, &nod2, w, 0, Z);
1064 * minimize space for unrolling loop
1065 * 3,4,5 times. (6 or more is never minimum)
1066 * if small structure, try 2 also.
1079 regalloc(&nod3, ®node, Z);
1080 layout(&nod1, &nod2, w%c, w/c, &nod3);
1083 layout(&nod1, &nod2, c, 0, Z);
1085 gopcode(OSUB, nodconst(1L), Z, &nod3);
1086 nod1.op = OREGISTER;
1087 gopcode(OADD, nodconst(c*SZ_LONG), Z, &nod1);
1088 nod2.op = OREGISTER;
1089 gopcode(OADD, nodconst(c*SZ_LONG), Z, &nod2);
1091 gopcode(OGT, &nod3, Z, nodconst(0));
1101 layout(Node *f, Node *t, int c, int cv, Node *cn)
1106 layout(f, t, 2, 0, Z);
1110 regalloc(&t1, ®node, Z);
1111 regalloc(&t2, ®node, Z);
1113 gopcode(OAS, f, Z, &t1);
1114 f->xoffset += SZ_LONG;
1117 gopcode(OAS, nodconst(cv), Z, cn);
1119 gopcode(OAS, f, Z, &t2);
1120 f->xoffset += SZ_LONG;
1123 gopcode(OAS, &t1, Z, t);
1124 t->xoffset += SZ_LONG;
1127 gopcode(OAS, f, Z, &t1);
1128 f->xoffset += SZ_LONG;
1131 gopcode(OAS, &t2, Z, t);
1132 t->xoffset += SZ_LONG;
1135 gopcode(OAS, &t1, Z, t);
1136 t->xoffset += SZ_LONG;
1143 * is the vlong's value directly addressible?
1148 return n->op == ONAME || n->op == OCONST || n->op == OINDREG;
1152 * can the constant be used with given vlong op?
1155 isvconstable(int o, vlong v)
1160 /* there isn't an immediate form for ADDE/SUBE, but there are special ADDME/ADDZE etc */
1161 return v == 0 || v == -1;
1177 * most 64-bit operations: cgen into a register pair, then operate.
1178 * 64-bit comparisons are handled a little differently because the two underlying
1179 * comparisons can be compiled separately, since the calculations don't interact.
1183 vcgen(Node *n, Node *o, int *f)
1187 if(n->complex >= FNX) {
1193 if(n->addable < INDEXED && n->op != OIND && n->op != OINDEX) {
1217 gcmpv(Node *l, Node *r, void (*mov)(Node*, Node*, int), int op)
1221 regalloc(&vl, ®node, Z);
1223 regalloc(&vr, ®node, Z);
1224 mov(r, &vr, 1+isuns(op));
1225 gopcode(op, &vl, Z, &vr);
1226 if(vl.op == OREGISTER)
1228 if(vr.op == OREGISTER)
1233 brcondv(Node *l, Node *r, int chi, int clo)
1235 Prog *p1, *p2, *p3, *p4;
1237 gcmpv(l, r, gloadhi, chi);
1241 gcmpv(l, r, gloadlo, clo);
1253 testv(Node *n, int true)
1260 nod.right = new1(0, Z, Z);
1261 *nod.right = *nodconst(0);
1262 nod.right->type = n->type;
1263 nod.type = types[TLONG];
1264 cmpv(&nod, true, Z);
1268 * comparison for vlong does high and low order parts separately,
1269 * which saves loading the latter if the high order comparison suffices
1272 cmpv(Node *n, int true, Node *nn)
1274 Node *l, *r, nod, nod1;
1281 prtree(nn, "cmpv lhs");
1287 if(l->complex >= FNX && r->complex >= FNX) {
1288 regsalloc(&nod1, r);
1292 cmpv(&nod, true, nn);
1296 if(l->complex >= r->complex) {
1297 vcgen(l, &nod1, &f1);
1298 vcgen(r, &nod, &f2);
1300 vcgen(r, &nod, &f2);
1301 vcgen(l, &nod1, &f1);
1303 nod.type = types[TLONG];
1304 nod1.type = types[TLONG];
1307 o = comrel[relindex(o)];
1310 gcmpv(&nod1, &nod, gloadhi, ONE);
1312 gcmpv(&nod1, &nod, gloadlo, ONE);
1319 gcmpv(&nod1, &nod, gloadhi, ONE);
1321 gcmpv(&nod1, &nod, gloadlo, OEQ);
1328 brcondv(&nod1, &nod, OLT, OLS);
1331 brcondv(&nod1, &nod, OGT, OHI);
1334 brcondv(&nod1, &nod, OLO, OLS);
1337 brcondv(&nod1, &nod, OHI, OHI);
1340 brcondv(&nod1, &nod, OLT, OLO);
1343 brcondv(&nod1, &nod, OGT, OHS);
1346 brcondv(&nod1, &nod, OLO, OLO);
1349 brcondv(&nod1, &nod, OHI, OHS);
1352 diag(n, "bad cmpv");
1363 cgen64(Node *n, Node *nn)
1379 nullwarn(n->left, Z);
1382 if(nn->op != OREGPAIR) {
1383 //prtree(n, "cgen64 const");
1385 nn->type = types[TLONG];
1386 reglcgen(&nod1, nn, Z);
1389 if(align(0, types[TCHAR], Aarg1)) /* isbigendian */
1390 gmove(nod32const(n->vconst>>32), &nod1);
1392 gmove(nod32const(n->vconst), &nod1);
1393 nod1.xoffset += SZ_LONG;
1394 if(align(0, types[TCHAR], Aarg1)) /* isbigendian */
1395 gmove(nod32const(n->vconst), &nod1);
1397 gmove(nod32const(n->vconst>>32), &nod1);
1406 * convert from types l->n->nn
1408 if(typev[l->type->etype]){
1409 /* vlong to non-vlong */
1411 if(l->addable < INDEXED && l->op != OIND && l->op != OINDEX) {
1412 regalloc(&nod, l, l);
1414 regalloc(&nod1, n, nn);
1415 gmove(nod.right, &nod1);
1417 reglcgen(&nod, l, Z);
1418 regalloc(&nod1, n, nn);
1419 gloadlo(&nod, &nod1, 0); /* TO DO: not correct for typefd */
1423 regalloc(&nod1, n, nn);
1424 gloadlo(l, &nod1, 0); /* TO DO: not correct for typefd */
1427 /* non-vlong to vlong */
1428 regalloc(&nod, l, Z);
1430 regalloc(&nod1, n, nn);
1431 gmove(&nod, nod1.right);
1432 if(typeu[l->type->etype])
1433 gmove(nodconst(0), nod1.left);
1435 gopcode(OASHR, nodconst(31), nod1.right, nod1.left);
1443 /* this transformation should probably be done earlier */
1445 regsalloc(&nod1, n);
1449 if(nn->op != OIND) {
1450 if(nn->op == OREGPAIR) {
1452 regsalloc(&nod1, nn);
1456 d = new1(OADDR, d, Z);
1457 d->type = types[TIND];
1461 n = new(OFUNC, l, new(OLIST, d, r));
1463 n->type = types[TVOID];
1464 n->left->type = types[TVOID];
1471 diag(n, "bad cgen64 %O", o);