4 cgen(Node *n, Node *nn)
8 Node nod, nod1, nod2, nod3, nod4;
13 prtree(nn, "cgen lhs");
16 if(n == Z || n->type == T)
18 if(typesuv[n->type->etype]) {
19 sugen(n, nn, n->type->width);
25 if(n->addable >= INDEXED) {
44 if(r != Z && r->complex >= FNX)
51 gopcode(OAS, &nod, Z, &nod1);
70 diag(n, "unknown op in cgen: %O", o);
76 if(l->addable >= INDEXED) {
77 if(nn != Z || r->addable < INDEXED) {
78 if(r->complex >= FNX && nn == Z)
81 regalloc(&nod, r, nn);
91 if(l->complex >= r->complex) {
92 reglcgen(&nod1, l, Z);
93 if(r->addable >= INDEXED) {
100 regalloc(&nod, r, nn);
103 regalloc(&nod, r, nn);
105 reglcgen(&nod1, l, Z);
114 regalloc(&nod, r, nn);
115 if(l->complex >= r->complex) {
116 reglcgen(&nod1, n, Z);
120 reglcgen(&nod1, n, Z);
122 regalloc(&nod2, n, Z);
123 gopcode(OAS, &nod1, Z, &nod2);
124 bitstore(l, &nod, &nod1, &nod2, nn);
132 bitload(n, &nod, Z, Z, nn);
133 gopcode(OAS, &nod, Z, nn);
150 if(!typefd[n->type->etype]) {
156 gopcode(o, r, Z, nn);
170 if(o == OMUL || o == OLMUL) {
174 print("%L multiply\n", n->lineno);
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[n->type->etype]) {
206 if(l->addable < INDEXED)
207 reglcgen(&nod2, l, Z);
210 regalloc(&nod, r, nn);
211 gopcode(OAS, &nod2, Z, &nod);
212 gopcode(o, r, Z, &nod);
213 gopcode(OAS, &nod, Z, &nod2);
216 if(l->addable < INDEXED)
229 if(l->complex >= r->complex) {
230 if(l->addable < INDEXED)
231 reglcgen(&nod2, l, Z);
234 regalloc(&nod, n, nn);
237 regalloc(&nod, n, nn);
239 if(l->addable < INDEXED)
240 reglcgen(&nod2, l, Z);
244 regalloc(&nod1, n, Z);
245 gopcode(OAS, &nod2, Z, &nod1);
246 gopcode(o, &nod, &nod1, &nod);
247 gopcode(OAS, &nod, Z, &nod2);
250 if(l->addable < INDEXED)
255 regalloc(&nod4, n, nn);
256 regalloc(&nod3, r, Z);
257 if(l->complex >= r->complex) {
258 bitload(l, &nod, &nod1, &nod2, &nod4);
262 bitload(l, &nod, &nod1, &nod2, &nod4);
265 gopcode(n->op, &nod3, Z, &nod4);
269 bitstore(l, &nod, &nod1, &nod2, nn);
281 if(l->complex >= FNX) {
283 diag(n, "bad function call");
285 regret(&nod, l->left);
287 regsalloc(&nod1, l->left);
288 gopcode(OAS, &nod, Z, &nod1);
301 gargs(r, &nod, &nod1);
302 if(l->addable < INDEXED) {
303 reglcgen(&nod, l, Z);
304 gopcode(OFUNC, Z, Z, &nod);
307 gopcode(OFUNC, Z, Z, l);
313 gopcode(OAS, &nod, Z, nn);
323 regialloc(&nod, n, nn);
336 gopcode(OAS, &nod, Z, nn);
383 * convert from types l->n->nn
385 if(nocast(l->type, n->type) && nocast(n->type, nn->type)) {
386 /* both null, gen l->nn */
390 regalloc(&nod, l, nn);
392 regalloc(&nod1, n, &nod);
393 gopcode(OAS, &nod, Z, &nod1);
394 gopcode(OAS, &nod1, Z, nn);
400 sugen(l, nodrat, l->type->width);
402 warn(n, "non-interruptable temporary");
404 if(!r || r->op != OCONST) {
405 diag(n, "DOT and no offset");
408 nod.xoffset += (long)r->vconst;
428 if(l->type->etype == TIND)
429 v = l->type->link->width;
437 if(l->addable < INDEXED)
438 reglcgen(&nod2, l, Z);
442 regalloc(&nod, l, nn);
443 gopcode(OAS, &nod2, Z, &nod);
444 regalloc(&nod1, l, Z);
445 if(typefd[l->type->etype]) {
446 regalloc(&nod3, l, Z);
448 gopcode(OAS, nodfconst(-v), Z, &nod3);
449 gopcode(OSUB, &nod3, &nod, &nod1);
451 gopcode(OAS, nodfconst(v), Z, &nod3);
452 gopcode(OADD, &nod3, &nod, &nod1);
456 gopcode(OADD, nodconst(v), &nod, &nod1);
457 gopcode(OAS, &nod1, Z, &nod2);
461 if(l->addable < INDEXED)
468 if(l->type->etype == TIND)
469 v = l->type->link->width;
476 if(l->addable < INDEXED)
477 reglcgen(&nod2, l, Z);
481 regalloc(&nod, l, nn);
482 gopcode(OAS, &nod2, Z, &nod);
483 if(typefd[l->type->etype]) {
484 regalloc(&nod3, l, Z);
486 gopcode(OAS, nodfconst(-v), Z, &nod3);
487 gopcode(OSUB, &nod3, Z, &nod);
489 gopcode(OAS, nodfconst(v), Z, &nod3);
490 gopcode(OADD, &nod3, Z, &nod);
494 gopcode(OADD, nodconst(v), Z, &nod);
495 gopcode(OAS, &nod, Z, &nod2);
496 if(nn && l->op == ONAME) /* in x=++i, emit USED(i) */
500 if(l->addable < INDEXED)
505 if(nn != Z && (o == OPOSTINC || o == OPOSTDEC)) {
506 bitload(l, &nod, &nod1, &nod2, Z);
507 gopcode(OAS, &nod, Z, nn);
508 gopcode(OADD, nodconst(v), Z, &nod);
509 bitstore(l, &nod, &nod1, &nod2, Z);
512 bitload(l, &nod, &nod1, &nod2, nn);
513 gopcode(OADD, nodconst(v), Z, &nod);
514 bitstore(l, &nod, &nod1, &nod2, nn);
521 reglcgen(Node *t, Node *n, Node *nn)
546 lcgen(Node *n, Node *nn)
552 prtree(nn, "lcgen lhs");
555 if(n == Z || n->type == T)
559 regalloc(&nod, n, Z);
563 if(n->addable < INDEXED) {
564 diag(n, "unknown op in lcgen: %O", n->op);
571 nod.type = types[TIND];
572 gopcode(OAS, &nod, Z, nn);
576 cgen(n->left, n->left);
587 lcgen(n->right->left, nn);
591 lcgen(n->right->right, nn);
598 bcgen(Node *n, int true)
608 boolgen(Node *n, int true, Node *nn)
612 Node *l, *r, nod, nod1;
616 prtree(nn, "boolgen lhs");
617 prtree(n, "boolgen");
625 if(n->op == OCONST) {
637 regalloc(&nod, n, nn);
641 o = comrel[relindex(o)];
642 if(typefd[n->type->etype]) {
643 nodreg(&nod1, n, NREG+FREGZERO);
644 gopcode(o, &nod, Z, &nod1);
646 gopcode(o, &nod, Z, nodconst(0));
652 boolgen(r, true, nn);
656 boolgen(l, !true, nn);
662 bcgen(r->left, true);
667 bcgen(r->right, !true);
715 o = comrel[relindex(o)];
716 if(l->complex >= FNX && r->complex >= FNX) {
720 gopcode(OAS, &nod, Z, &nod1);
724 boolgen(&nod, true, nn);
728 regalloc(&nod, l, nn);
730 gopcode(o, &nod, Z, r);
734 if(l->complex >= r->complex) {
735 regalloc(&nod1, l, nn);
737 regalloc(&nod, r, Z);
740 regalloc(&nod, r, nn);
742 regalloc(&nod1, l, Z);
745 gopcode(o, &nod1, Z, &nod);
752 gopcode(OAS, nodconst(1L), Z, nn);
756 gopcode(OAS, nodconst(0L), Z, nn);
765 sugen(Node *n, Node *nn, long w)
768 Node nod0, nod1, nod2, nod3, nod4, *l, *r;
773 if(n == Z || n->type == T)
776 prtree(nn, "sugen lhs");
785 nullwarn(n->left, Z);
793 if(n->type && typev[n->type->etype]) {
795 nullwarn(n->left, Z);
800 nn->type = types[TLONG];
801 reglcgen(&nod1, nn, Z);
804 if(align(0, types[TCHAR], Aarg1)) /* isbigendian */
805 gopcode(OAS, nod32const(n->vconst>>32), Z, &nod1);
807 gopcode(OAS, nod32const(n->vconst), Z, &nod1);
808 nod1.xoffset += SZ_LONG;
809 if(align(0, types[TCHAR], Aarg1)) /* isbigendian */
810 gopcode(OAS, nod32const(n->vconst), Z, &nod1);
812 gopcode(OAS, nod32const(n->vconst>>32), Z, &nod1);
821 sugen(l, nodrat, l->type->width);
823 warn(n, "non-interruptable temporary");
826 if(!r || r->op != OCONST) {
827 diag(n, "DOT and no offset");
830 nod1.xoffset += (long)r->vconst;
838 * rewrite so lhs has no fn call
840 if(nn != Z && nn->complex >= FNX) {
842 nod1.type = typ(TIND, n->type);
843 regret(&nod2, &nod1);
845 regsalloc(&nod0, &nod1);
846 gopcode(OAS, &nod2, Z, &nod0);
860 for(t = n->type->link; t != T; t = t->down) {
871 * hand craft *(&nn + o) = l
886 nod2.type = typ(TIND, t);
892 nod3.type = nod2.type;
897 nod4.type = nod2.type;
898 nod4.vconst = t->offset;
911 if(n->addable < INDEXED)
912 sugen(n->right, n->left, w);
915 /* BOTCH -- functions can clobber rathole */
916 sugen(n->right, nodrat, w);
917 warn(n, "non-interruptable temporary");
918 sugen(nodrat, n->left, w);
919 sugen(nodrat, nn, w);
928 nn = new1(OADDR, nn, Z);
929 nn->type = types[TIND];
933 n = new(OFUNC, n->left, new(OLIST, nn, n->right));
934 n->type = types[TVOID];
935 n->left->type = types[TVOID];
942 sugen(n->right->left, nn, w);
946 sugen(n->right->right, nn, w);
952 sugen(n->right, nn, w);
960 if(n->complex >= FNX && nn->complex >= FNX) {
962 nn->type = types[TLONG];
963 regialloc(&nod1, nn, Z);
965 regsalloc(&nod2, nn);
968 gopcode(OAS, &nod1, Z, &nod2);
971 nod2.type = typ(TIND, t);
984 if(n->complex > nn->complex) {
986 n->type = types[TLONG];
987 reglcgen(&nod1, n, Z);
991 nn->type = types[TLONG];
992 reglcgen(&nod2, nn, Z);
996 nn->type = types[TLONG];
997 reglcgen(&nod2, nn, Z);
1001 n->type = types[TLONG];
1002 reglcgen(&nod1, n, Z);
1008 layout(&nod1, &nod2, w, 0, Z);
1013 * minimize space for unrolling loop
1014 * 3,4,5 times. (6 or more is never minimum)
1015 * if small structure, try 2 also.
1028 regalloc(&nod3, ®node, Z);
1029 layout(&nod1, &nod2, w%c, w/c, &nod3);
1032 layout(&nod1, &nod2, c, 0, Z);
1034 gopcode(OSUB, nodconst(1L), Z, &nod3);
1035 nod1.op = OREGISTER;
1036 gopcode(OADD, nodconst(c*SZ_LONG), Z, &nod1);
1037 nod2.op = OREGISTER;
1038 gopcode(OADD, nodconst(c*SZ_LONG), Z, &nod2);
1040 gopcode(OGT, &nod3, Z, nodconst(0));
1050 layout(Node *f, Node *t, int c, int cv, Node *cn)
1055 layout(f, t, 2, 0, Z);
1059 regalloc(&t1, ®node, Z);
1060 regalloc(&t2, ®node, Z);
1062 gopcode(OAS, f, Z, &t1);
1063 f->xoffset += SZ_LONG;
1066 gopcode(OAS, nodconst(cv), Z, cn);
1068 gopcode(OAS, f, Z, &t2);
1069 f->xoffset += SZ_LONG;
1072 gopcode(OAS, &t1, Z, t);
1073 t->xoffset += SZ_LONG;
1076 gopcode(OAS, f, Z, &t1);
1077 f->xoffset += SZ_LONG;
1080 gopcode(OAS, &t2, Z, t);
1081 t->xoffset += SZ_LONG;
1084 gopcode(OAS, &t1, Z, t);
1085 t->xoffset += SZ_LONG;