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);
365 * convert from types l->n->nn
367 if(nocast(l->type, n->type) && nocast(n->type, nn->type)) {
368 /* both null, gen l->nn */
372 regalloc(&nod, l, nn);
374 regalloc(&nod1, n, &nod);
375 gopcode(OAS, &nod, Z, &nod1);
376 gopcode(OAS, &nod1, Z, nn);
382 sugen(l, nodrat, l->type->width);
384 warn(n, "non-interruptable temporary");
386 if(!r || r->op != OCONST) {
387 diag(n, "DOT and no offset");
390 nod.xoffset += (long)r->vconst;
410 if(l->type->etype == TIND)
411 v = l->type->link->width;
419 if(l->addable < INDEXED)
420 reglcgen(&nod2, l, Z);
424 regalloc(&nod, l, nn);
425 gopcode(OAS, &nod2, Z, &nod);
426 regalloc(&nod1, l, Z);
427 if(typefd[l->type->etype]) {
428 regalloc(&nod3, l, Z);
430 gopcode(OAS, nodfconst(-v), Z, &nod3);
431 gopcode(OSUB, &nod3, &nod, &nod1);
433 gopcode(OAS, nodfconst(v), Z, &nod3);
434 gopcode(OADD, &nod3, &nod, &nod1);
438 gopcode(OADD, nodconst(v), &nod, &nod1);
439 gopcode(OAS, &nod1, Z, &nod2);
443 if(l->addable < INDEXED)
450 if(l->type->etype == TIND)
451 v = l->type->link->width;
458 if(l->addable < INDEXED)
459 reglcgen(&nod2, l, Z);
463 regalloc(&nod, l, nn);
464 gopcode(OAS, &nod2, Z, &nod);
465 if(typefd[l->type->etype]) {
466 regalloc(&nod3, l, Z);
468 gopcode(OAS, nodfconst(-v), Z, &nod3);
469 gopcode(OSUB, &nod3, Z, &nod);
471 gopcode(OAS, nodfconst(v), Z, &nod3);
472 gopcode(OADD, &nod3, Z, &nod);
476 gopcode(OADD, nodconst(v), Z, &nod);
477 gopcode(OAS, &nod, Z, &nod2);
478 if(nn && l->op == ONAME) /* in x=++i, emit USED(i) */
482 if(l->addable < INDEXED)
487 if(nn != Z && (o == OPOSTINC || o == OPOSTDEC)) {
488 bitload(l, &nod, &nod1, &nod2, Z);
489 gopcode(OAS, &nod, Z, nn);
490 gopcode(OADD, nodconst(v), Z, &nod);
491 bitstore(l, &nod, &nod1, &nod2, Z);
494 bitload(l, &nod, &nod1, &nod2, nn);
495 gopcode(OADD, nodconst(v), Z, &nod);
496 bitstore(l, &nod, &nod1, &nod2, nn);
503 genasop(int o, Node *l, Node *r, Node *nn)
505 Node nod, nod1, nod2;
508 hardleft = l->addable < INDEXED || l->complex >= FNX;
509 if(l->complex >= r->complex) {
511 reglcgen(&nod2, l, Z);
514 regalloc(&nod1, r, Z);
517 regalloc(&nod1, r, Z);
520 reglcgen(&nod2, l, Z);
524 if(nod1.type == nod2.type || !typefd[nod1.type->etype])
525 regalloc(&nod, &nod2, nn);
527 regalloc(&nod, &nod1, Z);
529 gopcode(o, &nod1, Z, &nod);
540 reglcgen(Node *t, Node *n, Node *nn)
565 lcgen(Node *n, Node *nn)
571 prtree(nn, "lcgen lhs");
574 if(n == Z || n->type == T)
578 regalloc(&nod, n, Z);
582 if(n->addable < INDEXED) {
583 diag(n, "unknown op in lcgen: %O", n->op);
590 nod.type = types[TIND];
591 gopcode(OAS, &nod, Z, nn);
595 cgen(n->left, n->left);
606 lcgen(n->right->left, nn);
610 lcgen(n->right->right, nn);
617 bcgen(Node *n, int true)
627 boolgen(Node *n, int true, Node *nn)
631 Node *l, *r, nod, nod1;
635 prtree(nn, "boolgen lhs");
636 prtree(n, "boolgen");
644 if(n->op == OCONST) {
656 regalloc(&nod, n, nn);
660 o = comrel[relindex(o)];
661 if(typefd[n->type->etype]) {
662 nodreg(&nod1, n, NREG+FREGZERO);
663 gopcode(o, &nod, Z, &nod1);
665 gopcode(o, &nod, Z, nodconst(0));
671 boolgen(r, true, nn);
675 boolgen(l, !true, nn);
681 bcgen(r->left, true);
686 bcgen(r->right, !true);
734 o = comrel[relindex(o)];
735 if(l->complex >= FNX && r->complex >= FNX) {
739 gopcode(OAS, &nod, Z, &nod1);
743 boolgen(&nod, true, nn);
747 regalloc(&nod, l, nn);
749 gopcode(o, &nod, Z, r);
753 if(l->complex >= r->complex) {
754 regalloc(&nod1, l, nn);
756 regalloc(&nod, r, Z);
759 regalloc(&nod, r, nn);
761 regalloc(&nod1, l, Z);
764 gopcode(o, &nod1, Z, &nod);
771 gopcode(OAS, nodconst(1L), Z, nn);
775 gopcode(OAS, nodconst(0L), Z, nn);
784 sugen(Node *n, Node *nn, long w)
787 Node nod0, nod1, nod2, nod3, nod4, *l, *r;
792 if(n == Z || n->type == T)
795 prtree(nn, "sugen lhs");
804 nullwarn(n->left, Z);
812 if(n->type && typev[n->type->etype]) {
814 nullwarn(n->left, Z);
819 nn->type = types[TLONG];
820 reglcgen(&nod1, nn, Z);
823 if(align(0, types[TCHAR], Aarg1)) /* isbigendian */
824 gopcode(OAS, nod32const(n->vconst>>32), Z, &nod1);
826 gopcode(OAS, nod32const(n->vconst), Z, &nod1);
827 nod1.xoffset += SZ_LONG;
828 if(align(0, types[TCHAR], Aarg1)) /* isbigendian */
829 gopcode(OAS, nod32const(n->vconst), Z, &nod1);
831 gopcode(OAS, nod32const(n->vconst>>32), Z, &nod1);
840 sugen(l, nodrat, l->type->width);
842 warn(n, "non-interruptable temporary");
845 if(!r || r->op != OCONST) {
846 diag(n, "DOT and no offset");
849 nod1.xoffset += (long)r->vconst;
857 * rewrite so lhs has no side effects
859 if(nn != Z && side(nn)) {
861 nod1.type = typ(TIND, n->type);
862 regalloc(&nod2, &nod1, Z);
864 regsalloc(&nod0, &nod1);
865 gopcode(OAS, &nod2, Z, &nod0);
879 for(t = n->type->link; t != T; t = t->down) {
890 * hand craft *(&nn + o) = l
905 nod2.type = typ(TIND, t);
911 nod3.type = nod2.type;
916 nod4.type = nod2.type;
917 nod4.vconst = t->offset;
930 if(n->addable < INDEXED)
931 sugen(n->right, n->left, w);
934 /* BOTCH -- functions can clobber rathole */
935 sugen(n->right, nodrat, w);
936 warn(n, "non-interruptable temporary");
937 sugen(nodrat, n->left, w);
938 sugen(nodrat, nn, w);
947 nn = new1(OADDR, nn, Z);
948 nn->type = types[TIND];
952 n = new(OFUNC, n->left, new(OLIST, nn, n->right));
953 n->type = types[TVOID];
954 n->left->type = types[TVOID];
961 sugen(n->right->left, nn, w);
965 sugen(n->right->right, nn, w);
971 sugen(n->right, nn, w);
979 if(n->complex >= FNX && nn->complex >= FNX) {
981 nn->type = types[TLONG];
982 regialloc(&nod1, nn, Z);
984 regsalloc(&nod2, nn);
987 gopcode(OAS, &nod1, Z, &nod2);
990 nod2.type = typ(TIND, t);
1003 if(n->complex > nn->complex) {
1005 n->type = types[TLONG];
1006 reglcgen(&nod1, n, Z);
1010 nn->type = types[TLONG];
1011 reglcgen(&nod2, nn, Z);
1015 nn->type = types[TLONG];
1016 reglcgen(&nod2, nn, Z);
1020 n->type = types[TLONG];
1021 reglcgen(&nod1, n, Z);
1027 layout(&nod1, &nod2, w, 0, Z);
1032 * minimize space for unrolling loop
1033 * 3,4,5 times. (6 or more is never minimum)
1034 * if small structure, try 2 also.
1047 regalloc(&nod3, ®node, Z);
1048 layout(&nod1, &nod2, w%c, w/c, &nod3);
1051 layout(&nod1, &nod2, c, 0, Z);
1053 gopcode(OSUB, nodconst(1L), Z, &nod3);
1054 nod1.op = OREGISTER;
1055 gopcode(OADD, nodconst(c*SZ_LONG), Z, &nod1);
1056 nod2.op = OREGISTER;
1057 gopcode(OADD, nodconst(c*SZ_LONG), Z, &nod2);
1059 gopcode(OGT, &nod3, Z, nodconst(0));
1069 layout(Node *f, Node *t, int c, int cv, Node *cn)
1074 layout(f, t, 2, 0, Z);
1078 regalloc(&t1, ®node, Z);
1079 regalloc(&t2, ®node, Z);
1081 gopcode(OAS, f, Z, &t1);
1082 f->xoffset += SZ_LONG;
1085 gopcode(OAS, nodconst(cv), Z, cn);
1087 gopcode(OAS, f, Z, &t2);
1088 f->xoffset += SZ_LONG;
1091 gopcode(OAS, &t1, Z, t);
1092 t->xoffset += SZ_LONG;
1095 gopcode(OAS, f, Z, &t1);
1096 f->xoffset += SZ_LONG;
1099 gopcode(OAS, &t2, Z, t);
1100 t->xoffset += SZ_LONG;
1103 gopcode(OAS, &t1, Z, t);
1104 t->xoffset += SZ_LONG;