3 static void genasop(int, Node*, Node*, Node*);
6 cgen(Node *n, Node *nn)
10 Node nod, nod1, nod2, nod3, nod4;
15 prtree(nn, "cgen lhs");
18 if(n == Z || n->type == T)
20 if(typesuv[n->type->etype]) {
21 sugen(n, nn, n->type->width);
27 if(n->addable >= INDEXED) {
46 if(r != Z && r->complex >= FNX)
53 gopcode(OAS, &nod, Z, &nod1);
72 diag(n, "unknown op in cgen: %O", o);
78 if(l->addable >= INDEXED) {
79 if(nn != Z || r->addable < INDEXED) {
80 if(r->complex >= FNX && nn == Z)
83 regalloc(&nod, r, nn);
93 if(l->complex >= r->complex) {
94 reglcgen(&nod1, l, Z);
95 if(r->addable >= INDEXED) {
102 regalloc(&nod, r, nn);
105 regalloc(&nod, r, nn);
107 reglcgen(&nod1, l, Z);
116 regalloc(&nod, r, nn);
117 if(l->complex >= r->complex) {
118 reglcgen(&nod1, n, Z);
122 reglcgen(&nod1, n, Z);
124 regalloc(&nod2, n, Z);
125 gopcode(OAS, &nod1, Z, &nod2);
126 bitstore(l, &nod, &nod1, &nod2, nn);
134 bitload(n, &nod, Z, Z, nn);
135 gopcode(OAS, &nod, Z, nn);
152 if(!typefd[n->type->etype]) {
158 gopcode(o, r, Z, nn);
172 if(o == OMUL || o == OLMUL) {
176 print("%L multiply\n", n->lineno);
178 if(l->complex >= r->complex) {
179 regalloc(&nod, l, nn);
181 regalloc(&nod1, r, Z);
183 gopcode(o, &nod1, Z, &nod);
185 regalloc(&nod, r, nn);
187 regalloc(&nod1, l, Z);
189 gopcode(o, &nod, &nod1, &nod);
191 gopcode(OAS, &nod, Z, nn);
207 if(!typefd[n->type->etype]) {
208 if(l->addable < INDEXED)
209 reglcgen(&nod2, l, Z);
212 regalloc(&nod, r, nn);
213 gopcode(OAS, &nod2, Z, &nod);
214 gopcode(o, r, Z, &nod);
215 gopcode(OAS, &nod, Z, &nod2);
218 if(l->addable < INDEXED)
222 genasop(o, l, r, nn);
233 genasop(o, l, r, nn);
237 regalloc(&nod4, n, nn);
238 regalloc(&nod3, r, Z);
239 if(l->complex >= r->complex) {
240 bitload(l, &nod, &nod1, &nod2, &nod4);
244 bitload(l, &nod, &nod1, &nod2, &nod4);
247 gopcode(n->op, &nod3, Z, &nod4);
251 bitstore(l, &nod, &nod1, &nod2, nn);
263 if(l->complex >= FNX) {
265 diag(n, "bad function call");
267 regret(&nod, l->left);
269 regsalloc(&nod1, l->left);
270 gopcode(OAS, &nod, Z, &nod1);
283 gargs(r, &nod, &nod1);
284 if(l->addable < INDEXED) {
285 reglcgen(&nod, l, Z);
286 gopcode(OFUNC, Z, Z, &nod);
289 gopcode(OFUNC, Z, Z, l);
295 gopcode(OAS, &nod, Z, nn);
305 regialloc(&nod, n, nn);
318 gopcode(OAS, &nod, Z, nn);
361 if(n->type != types[TVOID])
368 * convert from types l->n->nn
370 if(nocast(l->type, n->type) && nocast(n->type, nn->type)) {
371 /* both null, gen l->nn */
375 regalloc(&nod, l, nn);
377 regalloc(&nod1, n, &nod);
378 gopcode(OAS, &nod, Z, &nod1);
379 gopcode(OAS, &nod1, Z, nn);
385 sugen(l, nodrat, l->type->width);
387 warn(n, "non-interruptable temporary");
389 if(!r || r->op != OCONST) {
390 diag(n, "DOT and no offset");
393 nod.xoffset += (long)r->vconst;
413 if(l->type->etype == TIND)
414 v = l->type->link->width;
422 if(l->addable < INDEXED)
423 reglcgen(&nod2, l, Z);
427 regalloc(&nod, l, nn);
428 gopcode(OAS, &nod2, Z, &nod);
429 regalloc(&nod1, l, Z);
430 if(typefd[l->type->etype]) {
431 regalloc(&nod3, l, Z);
433 gopcode(OAS, nodfconst(-v), Z, &nod3);
434 gopcode(OSUB, &nod3, &nod, &nod1);
436 gopcode(OAS, nodfconst(v), Z, &nod3);
437 gopcode(OADD, &nod3, &nod, &nod1);
441 gopcode(OADD, nodconst(v), &nod, &nod1);
442 gopcode(OAS, &nod1, Z, &nod2);
446 if(l->addable < INDEXED)
453 if(l->type->etype == TIND)
454 v = l->type->link->width;
461 if(l->addable < INDEXED)
462 reglcgen(&nod2, l, Z);
466 regalloc(&nod, l, nn);
467 gopcode(OAS, &nod2, Z, &nod);
468 if(typefd[l->type->etype]) {
469 regalloc(&nod3, l, Z);
471 gopcode(OAS, nodfconst(-v), Z, &nod3);
472 gopcode(OSUB, &nod3, Z, &nod);
474 gopcode(OAS, nodfconst(v), Z, &nod3);
475 gopcode(OADD, &nod3, Z, &nod);
479 gopcode(OADD, nodconst(v), Z, &nod);
480 gopcode(OAS, &nod, Z, &nod2);
481 if(nn && l->op == ONAME) /* in x=++i, emit USED(i) */
485 if(l->addable < INDEXED)
490 if(nn != Z && (o == OPOSTINC || o == OPOSTDEC)) {
491 bitload(l, &nod, &nod1, &nod2, Z);
492 gopcode(OAS, &nod, Z, nn);
493 gopcode(OADD, nodconst(v), Z, &nod);
494 bitstore(l, &nod, &nod1, &nod2, Z);
497 bitload(l, &nod, &nod1, &nod2, nn);
498 gopcode(OADD, nodconst(v), Z, &nod);
499 bitstore(l, &nod, &nod1, &nod2, nn);
506 genasop(int o, Node *l, Node *r, Node *nn)
508 Node nod, nod1, nod2;
511 hardleft = l->addable < INDEXED || l->complex >= FNX;
512 if(l->complex >= r->complex) {
514 reglcgen(&nod2, l, Z);
517 regalloc(&nod1, r, Z);
520 regalloc(&nod1, r, Z);
523 reglcgen(&nod2, l, Z);
527 if(nod1.type == nod2.type || !typefd[nod1.type->etype])
528 regalloc(&nod, &nod2, nn);
530 regalloc(&nod, &nod1, Z);
532 gopcode(o, &nod1, Z, &nod);
543 reglcgen(Node *t, Node *n, Node *nn)
568 lcgen(Node *n, Node *nn)
574 prtree(nn, "lcgen lhs");
577 if(n == Z || n->type == T)
581 regalloc(&nod, n, Z);
585 if(n->addable < INDEXED) {
586 diag(n, "unknown op in lcgen: %O", n->op);
593 nod.type = types[TIND];
594 gopcode(OAS, &nod, Z, nn);
598 cgen(n->left, n->left);
609 lcgen(n->right->left, nn);
613 lcgen(n->right->right, nn);
620 bcgen(Node *n, int true)
630 boolgen(Node *n, int true, Node *nn)
634 Node *l, *r, nod, nod1;
638 prtree(nn, "boolgen lhs");
639 prtree(n, "boolgen");
647 if(n->op == OCONST) {
659 regalloc(&nod, n, nn);
663 o = comrel[relindex(o)];
664 if(typefd[n->type->etype]) {
665 nodreg(&nod1, n, NREG+FREGZERO);
666 gopcode(o, &nod, Z, &nod1);
668 gopcode(o, &nod, Z, nodconst(0));
674 boolgen(r, true, nn);
678 boolgen(l, !true, nn);
684 bcgen(r->left, true);
689 bcgen(r->right, !true);
737 o = comrel[relindex(o)];
738 if(l->complex >= FNX && r->complex >= FNX) {
742 gopcode(OAS, &nod, Z, &nod1);
746 boolgen(&nod, true, nn);
750 regalloc(&nod, l, nn);
752 gopcode(o, &nod, Z, r);
756 if(l->complex >= r->complex) {
757 regalloc(&nod1, l, nn);
759 regalloc(&nod, r, Z);
762 regalloc(&nod, r, nn);
764 regalloc(&nod1, l, Z);
767 gopcode(o, &nod1, Z, &nod);
774 gopcode(OAS, nodconst(1L), Z, nn);
778 gopcode(OAS, nodconst(0L), Z, nn);
787 sugen(Node *n, Node *nn, long w)
790 Node nod0, nod1, nod2, nod3, nod4, *l, *r;
795 if(n == Z || n->type == T)
798 prtree(nn, "sugen lhs");
807 nullwarn(n->left, Z);
815 if(n->type && typev[n->type->etype]) {
817 nullwarn(n->left, Z);
822 nn->type = types[TLONG];
823 reglcgen(&nod1, nn, Z);
826 if(align(0, types[TCHAR], Aarg1)) /* isbigendian */
827 gopcode(OAS, nod32const(n->vconst>>32), Z, &nod1);
829 gopcode(OAS, nod32const(n->vconst), Z, &nod1);
830 nod1.xoffset += SZ_LONG;
831 if(align(0, types[TCHAR], Aarg1)) /* isbigendian */
832 gopcode(OAS, nod32const(n->vconst), Z, &nod1);
834 gopcode(OAS, nod32const(n->vconst>>32), Z, &nod1);
843 sugen(l, nodrat, l->type->width);
845 warn(n, "non-interruptable temporary");
848 if(!r || r->op != OCONST) {
849 diag(n, "DOT and no offset");
852 nod1.xoffset += (long)r->vconst;
860 * rewrite so lhs has no side effects
862 if(nn != Z && side(nn)) {
864 nod1.type = typ(TIND, n->type);
865 regalloc(&nod2, &nod1, Z);
867 regsalloc(&nod0, &nod1);
868 gopcode(OAS, &nod2, Z, &nod0);
882 for(t = n->type->link; t != T; t = t->down) {
893 * hand craft *(&nn + o) = l
908 nod2.type = typ(TIND, t);
914 nod3.type = nod2.type;
919 nod4.type = nod2.type;
920 nod4.vconst = t->offset;
933 if(n->addable < INDEXED)
934 sugen(n->right, n->left, w);
937 /* BOTCH -- functions can clobber rathole */
938 sugen(n->right, nodrat, w);
939 warn(n, "non-interruptable temporary");
940 sugen(nodrat, n->left, w);
941 sugen(nodrat, nn, w);
950 nn = new1(OADDR, nn, Z);
951 nn->type = types[TIND];
955 n = new(OFUNC, n->left, new(OLIST, nn, n->right));
956 n->type = types[TVOID];
957 n->left->type = types[TVOID];
964 sugen(n->right->left, nn, w);
968 sugen(n->right->right, nn, w);
974 sugen(n->right, nn, w);
982 if(n->complex >= FNX && nn->complex >= FNX) {
984 nn->type = types[TLONG];
985 regialloc(&nod1, nn, Z);
987 regsalloc(&nod2, nn);
990 gopcode(OAS, &nod1, Z, &nod2);
993 nod2.type = typ(TIND, t);
1006 if(n->complex > nn->complex) {
1008 n->type = types[TLONG];
1009 reglcgen(&nod1, n, Z);
1013 nn->type = types[TLONG];
1014 reglcgen(&nod2, nn, Z);
1018 nn->type = types[TLONG];
1019 reglcgen(&nod2, nn, Z);
1023 n->type = types[TLONG];
1024 reglcgen(&nod1, n, Z);
1030 layout(&nod1, &nod2, w, 0, Z);
1035 * minimize space for unrolling loop
1036 * 3,4,5 times. (6 or more is never minimum)
1037 * if small structure, try 2 also.
1050 regalloc(&nod3, ®node, Z);
1051 layout(&nod1, &nod2, w%c, w/c, &nod3);
1054 layout(&nod1, &nod2, c, 0, Z);
1056 gopcode(OSUB, nodconst(1L), Z, &nod3);
1057 nod1.op = OREGISTER;
1058 gopcode(OADD, nodconst(c*SZ_LONG), Z, &nod1);
1059 nod2.op = OREGISTER;
1060 gopcode(OADD, nodconst(c*SZ_LONG), Z, &nod2);
1062 gopcode(OGT, &nod3, Z, nodconst(0));
1072 layout(Node *f, Node *t, int c, int cv, Node *cn)
1077 layout(f, t, 2, 0, Z);
1081 regalloc(&t1, ®node, Z);
1082 regalloc(&t2, ®node, Z);
1084 gopcode(OAS, f, Z, &t1);
1085 f->xoffset += SZ_LONG;
1088 gopcode(OAS, nodconst(cv), Z, cn);
1090 gopcode(OAS, f, Z, &t2);
1091 f->xoffset += SZ_LONG;
1094 gopcode(OAS, &t1, Z, t);
1095 t->xoffset += SZ_LONG;
1098 gopcode(OAS, f, Z, &t1);
1099 f->xoffset += SZ_LONG;
1102 gopcode(OAS, &t2, Z, t);
1103 t->xoffset += SZ_LONG;
1106 gopcode(OAS, &t1, Z, t);
1107 t->xoffset += SZ_LONG;