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(typesu[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 && l->complex < FNX) {
77 if(nn != Z || r->addable < INDEXED) {
78 regalloc(&nod, r, nn);
86 if(l->complex >= r->complex) {
87 reglcgen(&nod1, l, Z);
88 if(r->addable >= INDEXED) {
95 regalloc(&nod, r, nn);
98 regalloc(&nod, r, nn);
100 reglcgen(&nod1, l, Z);
109 regalloc(&nod, r, nn);
110 if(l->complex >= r->complex) {
111 reglcgen(&nod1, n, Z);
115 reglcgen(&nod1, n, Z);
117 regalloc(&nod2, n, Z);
118 gopcode(OAS, &nod1, Z, &nod2);
119 bitstore(l, &nod, &nod1, &nod2, nn);
127 bitload(n, &nod, Z, Z, nn);
128 gopcode(OAS, &nod, Z, nn);
151 if(!typefd[n->type->etype]) {
157 gopcode(o, r, Z, nn);
165 /* if(o == OMUL || o == OLMUL) {
169 if(l->complex >= r->complex) {
170 regalloc(&nod, l, nn);
172 regalloc(&nod1, l, Z); /* note: l used for type, so shifts work! */
174 gopcode(o, &nod1, Z, &nod);
176 regalloc(&nod, l, nn); /* note: l used for type, so shifts work! */
178 regalloc(&nod1, l, Z);
180 gopcode(o, &nod, &nod1, &nod);
182 gopcode(OAS, &nod, Z, nn);
204 if(!typefd[r->type->etype])
205 if(!typefd[n->type->etype]) {
206 if(l->addable < INDEXED)
207 reglcgen(&nod2, l, Z);
210 regalloc(&nod, l, nn); /* note: l used for type, so shifts work! */
211 gopcode(OAS, &nod2, Z, &nod);
212 gopcode(o, r, Z, &nod);
213 gopcode(OAS, &nod, Z, &nod2);
216 if(l->addable < INDEXED)
221 if(l->complex >= r->complex) {
222 if(l->addable < INDEXED)
223 reglcgen(&nod2, l, Z);
226 regalloc(&nod1, r, Z);
229 regalloc(&nod1, r, Z);
231 if(l->addable < INDEXED)
232 reglcgen(&nod2, l, Z);
237 regalloc(&nod, n, nn);
239 if(nod1.type->etype != nod.type->etype){
240 regalloc(&nod3, &nod, Z);
245 gopcode(o, &nod1, Z, &nod);
248 gopcode(OAS, &nod, Z, nn);
251 if(l->addable < INDEXED)
256 regalloc(&nod4, n, nn);
257 if(l->complex >= r->complex) {
258 bitload(l, &nod, &nod1, &nod2, &nod4);
259 regalloc(&nod3, r, Z);
262 regalloc(&nod3, r, Z);
264 bitload(l, &nod, &nod1, &nod2, &nod4);
267 gopcode(o, &nod3, Z, &nod4);
271 bitstore(l, &nod, &nod1, &nod2, nn);
283 if(l->complex >= FNX) {
285 diag(n, "bad function call");
287 regret(&nod, l->left);
289 regsalloc(&nod1, l->left);
290 gopcode(OAS, &nod, Z, &nod1);
304 gargs(r, &nod, &nod1);
305 if(l->addable < INDEXED) {
306 reglcgen(&nod, l, Z);
307 gopcode(OFUNC, Z, Z, &nod);
310 gopcode(OFUNC, Z, Z, l);
316 gopcode(OAS, &nod, Z, nn);
326 regialloc(&nod, n, nn);
339 gopcode(OAS, &nod, Z, nn);
386 * convert from types l->n->nn
388 if(nocast(l->type, n->type)) {
389 if(nocast(n->type, nn->type)) {
394 regalloc(&nod, l, nn);
396 regalloc(&nod1, n, &nod);
397 gopcode(OAS, &nod, Z, &nod1);
398 gopcode(OAS, &nod1, Z, nn);
404 sugen(l, nodrat, l->type->width);
406 warn(n, "non-interruptable temporary");
408 if(!r || r->op != OCONST) {
409 diag(n, "DOT and no offset");
412 nod.xoffset += (long)r->vconst;
432 if(l->type->etype == TIND)
433 v = l->type->link->width;
441 if(l->addable < INDEXED)
442 reglcgen(&nod2, l, Z);
446 regalloc(&nod, l, nn);
447 gopcode(OAS, &nod2, Z, &nod);
448 regalloc(&nod1, l, Z);
449 if(typefd[l->type->etype]) {
450 regalloc(&nod3, l, Z);
452 gopcode(OAS, nodfconst(-v), Z, &nod3);
453 gopcode(OSUB, &nod3, &nod, &nod1);
455 gopcode(OAS, nodfconst(v), Z, &nod3);
456 gopcode(OADD, &nod3, &nod, &nod1);
460 gopcode(OADD, nodconst(v), &nod, &nod1);
461 gopcode(OAS, &nod1, Z, &nod2);
465 if(l->addable < INDEXED)
472 if(l->type->etype == TIND)
473 v = l->type->link->width;
480 if(l->addable < INDEXED)
481 reglcgen(&nod2, l, Z);
485 regalloc(&nod, l, nn);
486 gopcode(OAS, &nod2, Z, &nod);
487 if(typefd[l->type->etype]) {
488 regalloc(&nod3, l, Z);
490 gopcode(OAS, nodfconst(-v), Z, &nod3);
491 gopcode(OSUB, &nod3, Z, &nod);
493 gopcode(OAS, nodfconst(v), Z, &nod3);
494 gopcode(OADD, &nod3, Z, &nod);
498 gopcode(OADD, nodconst(v), Z, &nod);
499 gopcode(OAS, &nod, Z, &nod2);
500 if(nn && l->op == ONAME) /* in x=++i, emit USED(i) */
504 if(l->addable < INDEXED)
509 if(nn != Z && (o == OPOSTINC || o == OPOSTDEC)) {
510 bitload(l, &nod, &nod1, &nod2, Z);
511 gopcode(OAS, &nod, Z, nn);
512 gopcode(OADD, nodconst(v), Z, &nod);
513 bitstore(l, &nod, &nod1, &nod2, Z);
516 bitload(l, &nod, &nod1, &nod2, nn);
517 gopcode(OADD, nodconst(v), Z, &nod);
518 bitstore(l, &nod, &nod1, &nod2, nn);
526 reglcgen(Node *t, Node *n, Node *nn)
551 lcgen(Node *n, Node *nn)
557 prtree(nn, "lcgen lhs");
560 if(n == Z || n->type == T)
564 regalloc(&nod, n, Z);
568 if(n->addable < INDEXED) {
569 diag(n, "unknown op in lcgen: %O", n->op);
576 nod.type = types[TIND];
577 gopcode(OAS, &nod, Z, nn);
581 cgen(n->left, n->left);
592 lcgen(n->right->left, nn);
596 lcgen(n->right->right, nn);
603 bcgen(Node *n, int true)
613 boolgen(Node *n, int true, Node *nn)
617 Node *l, *r, nod, nod1;
621 prtree(nn, "boolgen lhs");
622 prtree(n, "boolgen");
630 regalloc(&nod, n, nn);
634 o = comrel[relindex(o)];
635 if(typefd[n->type->etype]) {
636 nodreg(&nod1, n, NREG+FREGZERO);
637 gopcode(o, &nod, Z, &nod1);
639 gopcode(o, &nod, Z, nodconst(0));
657 boolgen(r, true, nn);
661 boolgen(l, !true, nn);
667 bcgen(r->left, true);
672 bcgen(r->right, !true);
720 o = comrel[relindex(o)];
721 if(l->complex >= FNX && r->complex >= FNX) {
725 gopcode(OAS, &nod, Z, &nod1);
729 boolgen(&nod, true, nn);
733 regalloc(&nod, l, nn);
735 gopcode(o, &nod, Z, r);
739 if(l->complex >= r->complex) {
740 regalloc(&nod1, l, nn);
742 regalloc(&nod, r, Z);
745 regalloc(&nod, r, nn);
747 regalloc(&nod1, l, Z);
750 gopcode(o, &nod1, Z, &nod);
757 gopcode(OAS, nodconst(1), Z, nn);
761 gopcode(OAS, nodconst(0), Z, nn);
770 sugen(Node *n, Node *nn, long w)
773 Node nod0, nod1, nod2, nod3, nod4, *l, *r;
778 if(n == Z || n->type == T)
781 prtree(nn, "sugen lhs");
790 nullwarn(n->left, Z);
799 sugen(l, nodrat, l->type->width);
801 warn(n, "non-interruptable temporary");
804 if(!r || r->op != OCONST) {
805 diag(n, "DOT and no offset");
808 nod1.xoffset += (long)r->vconst;
816 * rewrite so lhs has no fn call
818 if(nn != Z && nn->complex >= FNX) {
820 nod1.type = typ(TIND, n->type);
821 regret(&nod2, &nod1);
823 regsalloc(&nod0, &nod1);
824 gopcode(OAS, &nod2, Z, &nod0);
838 for(t = n->type->link; t != T; t = t->down) {
849 * hand craft *(&nn + o) = l
864 nod2.type = typ(TIND, t);
870 nod3.type = nod2.type;
875 nod4.type = nod2.type;
876 nod4.vconst = t->offset;
883 /* prtree(&nod0, "hand craft"); /* */
890 if(n->addable < INDEXED)
891 sugen(n->right, n->left, w);
894 sugen(n->right, nodrat, w);
895 warn(n, "non-interruptable temporary");
896 sugen(nodrat, n->left, w);
897 sugen(nodrat, nn, w);
906 nn = new1(OADDR, nn, Z);
907 nn->type = types[TIND];
911 n = new(OFUNC, n->left, new(OLIST, nn, n->right));
912 n->type = types[TVOID];
913 n->left->type = types[TVOID];
920 sugen(n->right->left, nn, w);
924 sugen(n->right->right, nn, w);
930 sugen(n->right, nn, w);
938 if(n->complex >= FNX && nn->complex >= FNX) {
940 nn->type = types[TLONG];
941 regialloc(&nod1, nn, Z);
943 regsalloc(&nod2, nn);
946 gopcode(OAS, &nod1, Z, &nod2);
949 nod2.type = typ(TIND, t);
962 if(n->complex > nn->complex) {
964 n->type = types[TLONG];
965 reglcgen(&nod1, n, Z);
969 nn->type = types[TLONG];
970 reglcgen(&nod2, nn, Z);
974 nn->type = types[TLONG];
975 reglcgen(&nod2, nn, Z);
979 n->type = types[TLONG];
980 reglcgen(&nod1, n, Z);
986 layout(&nod1, &nod2, w, 0, Z);
991 * minimize space for unrolling loop
992 * 3,4,5 times. (6 or more is never minimum)
993 * if small structure, try 2 also.
1006 regalloc(&nod3, ®node, Z);
1007 layout(&nod1, &nod2, w%c, w/c, &nod3);
1010 layout(&nod1, &nod2, c, 0, Z);
1012 gopcode(OSUB, nodconst(1), Z, &nod3);
1013 nod1.op = OREGISTER;
1014 gopcode(OADD, nodconst(c*SZ_LONG), Z, &nod1);
1015 nod2.op = OREGISTER;
1016 gopcode(OADD, nodconst(c*SZ_LONG), Z, &nod2);
1018 gopcode(OGT, &nod3, Z, nodconst(0));
1028 layout(Node *f, Node *t, int c, int cv, Node *cn)
1033 layout(f, t, 2, 0, Z);
1037 regalloc(&t1, ®node, Z);
1038 regalloc(&t2, ®node, Z);
1040 gopcode(OAS, f, Z, &t1);
1041 f->xoffset += SZ_LONG;
1044 gopcode(OAS, nodconst(cv), Z, cn);
1046 gopcode(OAS, f, Z, &t2);
1047 f->xoffset += SZ_LONG;
1050 gopcode(OAS, &t1, Z, t);
1051 t->xoffset += SZ_LONG;
1054 gopcode(OAS, f, Z, &t1);
1055 f->xoffset += SZ_LONG;
1058 gopcode(OAS, &t2, Z, t);
1059 t->xoffset += SZ_LONG;
1062 gopcode(OAS, &t1, Z, t);
1063 t->xoffset += SZ_LONG;