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 && l->complex < FNX) {
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 if(l->complex >= r->complex) {
177 regalloc(&nod, l, nn);
179 regalloc(&nod1, r, Z);
181 gopcode(o, &nod1, Z, &nod);
183 regalloc(&nod, r, nn);
185 regalloc(&nod1, l, Z);
187 gopcode(o, &nod, &nod1, &nod);
189 gopcode(OAS, &nod, Z, nn);
205 if(!typefd[r->type->etype])
206 if(!typefd[n->type->etype]) {
207 if(l->addable < INDEXED)
208 reglcgen(&nod2, l, Z);
211 regalloc(&nod, l, nn);
212 gopcode(OAS, &nod2, Z, &nod);
213 gopcode(o, r, Z, &nod);
214 gopcode(OAS, &nod, Z, &nod2);
217 if(l->addable < INDEXED)
221 genasop(o, l, r, nn);
232 genasop(o, l, r, nn);
236 regalloc(&nod4, n, nn);
237 if(l->complex >= r->complex) {
238 bitload(l, &nod, &nod1, &nod2, &nod4);
239 regalloc(&nod3, r, Z);
242 regalloc(&nod3, r, Z);
244 bitload(l, &nod, &nod1, &nod2, &nod4);
247 gopcode(o, &nod3, Z, &nod4);
251 bitstore(l, &nod, &nod1, &nod2, nn);
264 if(l->complex >= FNX) {
266 diag(n, "bad function call");
268 regret(&nod, l->left);
270 regsalloc(&nod1, l->left);
271 gopcode(OAS, &nod, Z, &nod1);
284 gargs(r, &nod, &nod1);
285 if(l->addable < INDEXED) {
286 reglcgen(&nod, l, Z);
287 gopcode(OFUNC, Z, Z, &nod);
290 gopcode(OFUNC, Z, Z, l);
296 gopcode(OAS, &nod, Z, nn);
306 regialloc(&nod, n, nn);
319 gopcode(OAS, &nod, Z, nn);
366 * convert from types l->n->nn
368 if(nocast(l->type, n->type)) {
369 if(nocast(n->type, nn->type)) {
374 regalloc(&nod, l, nn);
376 regalloc(&nod1, n, &nod);
377 gopcode(OAS, &nod, Z, &nod1);
378 gopcode(OAS, &nod1, Z, nn);
384 sugen(l, nodrat, l->type->width);
386 warn(n, "non-interruptable temporary");
388 if(!r || r->op != OCONST) {
389 diag(n, "DOT and no offset");
392 nod.xoffset += (long)r->vconst;
412 if(l->type->etype == TIND)
413 v = l->type->link->width;
421 if(l->addable < INDEXED)
422 reglcgen(&nod2, l, Z);
426 regalloc(&nod, l, nn);
427 gopcode(OAS, &nod2, Z, &nod);
428 regalloc(&nod1, l, Z);
429 if(typefd[l->type->etype]) {
430 regalloc(&nod3, l, Z);
432 gopcode(OAS, nodfconst(-v), Z, &nod3);
433 gopcode(OSUB, &nod3, &nod, &nod1);
435 gopcode(OAS, nodfconst(v), Z, &nod3);
436 gopcode(OADD, &nod3, &nod, &nod1);
440 gopcode(OADD, nodconst(v), &nod, &nod1);
441 gopcode(OAS, &nod1, Z, &nod2);
445 if(l->addable < INDEXED)
452 if(l->type->etype == TIND)
453 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 if(typefd[l->type->etype]) {
468 regalloc(&nod3, l, Z);
470 gopcode(OAS, nodfconst(-v), Z, &nod3);
471 gopcode(OSUB, &nod3, Z, &nod);
473 gopcode(OAS, nodfconst(v), Z, &nod3);
474 gopcode(OADD, &nod3, Z, &nod);
478 gopcode(OADD, nodconst(v), Z, &nod);
479 gopcode(OAS, &nod, Z, &nod2);
480 if(nn && l->op == ONAME) /* in x=++i, emit USED(i) */
484 if(l->addable < INDEXED)
489 if(nn != Z && (o == OPOSTINC || o == OPOSTDEC)) {
490 bitload(l, &nod, &nod1, &nod2, Z);
491 gopcode(OAS, &nod, Z, nn);
492 gopcode(OADD, nodconst(v), Z, &nod);
493 bitstore(l, &nod, &nod1, &nod2, Z);
496 bitload(l, &nod, &nod1, &nod2, nn);
497 gopcode(OADD, nodconst(v), Z, &nod);
498 bitstore(l, &nod, &nod1, &nod2, nn);
505 genasop(int o, Node *l, Node *r, Node *nn)
507 Node nod, nod1, nod2;
510 hardleft = l->addable < INDEXED || l->complex >= FNX;
511 if(l->complex >= r->complex) {
513 reglcgen(&nod2, l, Z);
516 regalloc(&nod1, r, Z);
519 regalloc(&nod1, r, Z);
522 reglcgen(&nod2, l, Z);
526 if(nod1.type == nod2.type || !typefd[nod1.type->etype])
527 regalloc(&nod, &nod2, nn);
529 regalloc(&nod, &nod1, Z);
531 gopcode(o, &nod1, Z, &nod);
542 reglcgen(Node *t, Node *n, Node *nn)
567 lcgen(Node *n, Node *nn)
573 prtree(nn, "lcgen lhs");
576 if(n == Z || n->type == T)
580 regalloc(&nod, n, Z);
584 if(n->addable < INDEXED) {
585 diag(n, "unknown op in lcgen: %O", n->op);
592 nod.type = types[TIND];
593 gopcode(OAS, &nod, Z, nn);
597 cgen(n->left, n->left);
608 lcgen(n->right->left, nn);
612 lcgen(n->right->right, nn);
619 bcgen(Node *n, int true)
629 boolgen(Node *n, int true, Node *nn)
633 Node *l, *r, nod, nod1;
637 prtree(nn, "boolgen lhs");
638 prtree(n, "boolgen");
646 regalloc(&nod, n, nn);
648 if(nn == Z || typefd[n->type->etype]) {
651 o = comrel[relindex(o)];
652 if(typefd[n->type->etype]) {
653 nodreg(&nod1, n, NREG+FREGZERO);
654 gopcode(o, &nod, &nod1, Z);
656 gopcode(o, &nod, Z, Z);
661 gopcode(OCOND, &nod, nodconst(0), &nod);
663 gopcode(OCOND, nodconst(1), &nod, &nod);
664 gopcode(OAS, &nod, Z, nn);
682 boolgen(r, true, nn);
686 boolgen(l, !true, nn);
692 bcgen(r->left, true);
697 bcgen(r->right, !true);
745 o = comrel[relindex(o)];
746 if(l->complex >= FNX && r->complex >= FNX) {
750 gopcode(OAS, &nod, Z, &nod1);
754 boolgen(&nod, true, nn);
757 if(nn != Z && !typefd[l->type->etype]) {
758 if(l->complex >= r->complex) {
759 regalloc(&nod1, l, nn);
761 regalloc(&nod, r, Z);
764 regalloc(&nod, r, nn);
766 regalloc(&nod1, l, Z);
771 gopcode(OSUB, &nod1, &nod, &nod);
772 gopcode(OCOND, &nod, nodconst(0), &nod);
775 gopcode(OSUB, &nod1, &nod, &nod);
776 gopcode(OCOND, nodconst(1), &nod, &nod);
779 gopcode(OCOMMA, &nod1, &nod, &nod);
782 gopcode(OCOMMA, &nod1, &nod, &nod);
783 gopcode(OXOR, nodconst(1), &nod, &nod);
786 gopcode(OCOMMA, &nod, &nod1, &nod);
787 gopcode(OXOR, nodconst(1), &nod, &nod);
790 gopcode(OCOMMA, &nod, &nod1, &nod);
793 gopcode(OCOND, &nod1, &nod, &nod);
796 gopcode(OCOND, &nod1, &nod, &nod);
797 gopcode(OXOR, nodconst(1), &nod, &nod);
800 gopcode(OCOND, &nod, &nod1, &nod);
801 gopcode(OXOR, nodconst(1), &nod, &nod);
804 gopcode(OCOND, &nod, &nod1, &nod);
807 gopcode(OAS, &nod, Z, nn);
822 regalloc(&nod, r, nn);
824 gopcode(o, l, &nod, Z);
839 regalloc(&nod, l, nn);
841 gopcode(o, &nod, r, Z);
846 if(l->complex >= r->complex) {
847 regalloc(&nod1, l, nn);
849 regalloc(&nod, r, Z);
852 regalloc(&nod, r, nn);
854 regalloc(&nod1, l, Z);
857 gopcode(o, &nod1, &nod, Z);
864 gopcode(OAS, nodconst(1), Z, nn);
868 gopcode(OAS, nodconst(0), Z, nn);
877 sugen(Node *n, Node *nn, long w)
880 Node nod0, nod1, nod2, nod3, nod4, *l, *r;
885 if(n == Z || n->type == T)
888 prtree(nn, "sugen lhs");
897 nullwarn(n->left, Z);
905 if(n->type && typev[n->type->etype]) {
907 nullwarn(n->left, Z);
912 nn->type = types[TLONG];
913 reglcgen(&nod1, nn, Z);
916 if(align(0, types[TCHAR], Aarg1)) /* isbigendian */
917 gopcode(OAS, nod32const(n->vconst>>32), Z, &nod1);
919 gopcode(OAS, nod32const(n->vconst), Z, &nod1);
920 nod1.xoffset += SZ_LONG;
921 if(align(0, types[TCHAR], Aarg1)) /* isbigendian */
922 gopcode(OAS, nod32const(n->vconst), Z, &nod1);
924 gopcode(OAS, nod32const(n->vconst>>32), Z, &nod1);
933 sugen(l, nodrat, l->type->width);
935 warn(n, "non-interruptable temporary");
938 if(!r || r->op != OCONST) {
939 diag(n, "DOT and no offset");
942 nod1.xoffset += (long)r->vconst;
950 * rewrite so lhs has no side effects
952 if(nn != Z && side(nn)) {
954 nod1.type = typ(TIND, n->type);
955 regalloc(&nod2, &nod1, Z);
957 regsalloc(&nod0, &nod1);
958 gopcode(OAS, &nod2, Z, &nod0);
972 for(t = n->type->link; t != T; t = t->down) {
983 * hand craft *(&nn + o) = l
998 nod2.type = typ(TIND, t);
1004 nod3.type = nod2.type;
1009 nod4.type = nod2.type;
1010 nod4.vconst = t->offset;
1023 if(n->addable < INDEXED)
1024 sugen(n->right, n->left, w);
1027 sugen(n->right, nodrat, w);
1028 warn(n, "non-interruptable temporary");
1029 sugen(nodrat, n->left, w);
1030 sugen(nodrat, nn, w);
1035 sugen(n, nodrat, w);
1038 if(nn->op != OIND) {
1039 nn = new1(OADDR, nn, Z);
1040 nn->type = types[TIND];
1044 n = new(OFUNC, n->left, new(OLIST, nn, n->right));
1046 n->type = types[TVOID];
1047 n->left->type = types[TVOID];
1054 sugen(n->right->left, nn, w);
1058 sugen(n->right->right, nn, w);
1064 sugen(n->right, nn, w);
1072 if(n->complex >= FNX && nn->complex >= FNX) {
1074 nn->type = types[TLONG];
1075 regialloc(&nod1, nn, Z);
1077 regsalloc(&nod2, &nod1);
1080 gopcode(OAS, &nod1, Z, &nod2);
1083 nod2.type = typ(TIND, t);
1096 if(n->complex > nn->complex) {
1098 n->type = types[TLONG];
1099 reglcgen(&nod1, n, Z);
1103 nn->type = types[TLONG];
1104 reglcgen(&nod2, nn, Z);
1108 nn->type = types[TLONG];
1109 reglcgen(&nod2, nn, Z);
1113 n->type = types[TLONG];
1114 reglcgen(&nod1, n, Z);
1120 layout(&nod1, &nod2, w, 0, Z);
1125 * minimize space for unrolling loop
1126 * 3,4,5 times. (6 or more is never minimum)
1127 * if small structure, try 2 also.
1140 regalloc(&nod3, ®node, Z);
1141 layout(&nod1, &nod2, w%c, w/c, &nod3);
1144 layout(&nod1, &nod2, c, 0, Z);
1146 gopcode(OSUB, nodconst(1), Z, &nod3);
1147 nod1.op = OREGISTER;
1148 gopcode(OADD, nodconst(c*SZ_LONG), Z, &nod1);
1149 nod2.op = OREGISTER;
1150 gopcode(OADD, nodconst(c*SZ_LONG), Z, &nod2);
1152 gopcode(OEQ, &nod3, Z, Z);
1163 layout(Node *f, Node *t, int c, int cv, Node *cn)
1168 layout(f, t, 2, 0, Z);
1172 regalloc(&t1, ®node, Z);
1173 regalloc(&t2, ®node, Z);
1174 t1.type = types[TLONG];
1175 t2.type = types[TLONG];
1177 gopcode(OAS, f, Z, &t1);
1178 f->xoffset += SZ_LONG;
1181 gopcode(OAS, nodconst(cv), Z, cn);
1183 gopcode(OAS, f, Z, &t2);
1184 f->xoffset += SZ_LONG;
1187 gopcode(OAS, &t1, Z, t);
1188 t->xoffset += SZ_LONG;
1191 gopcode(OAS, f, Z, &t1);
1192 f->xoffset += SZ_LONG;
1195 gopcode(OAS, &t2, Z, t);
1196 t->xoffset += SZ_LONG;
1199 gopcode(OAS, &t1, Z, t);
1200 t->xoffset += SZ_LONG;