4 cgen(Node *n, Node *nn)
10 cgenrel(Node *n, Node *nn, int inrel)
14 Node nod, nod1, nod2, nod3, nod4;
19 prtree(nn, "cgen lhs");
22 if(n == Z || n->type == T)
24 if(typesuv[n->type->etype]) {
25 sugen(n, nn, n->type->width);
31 if(n->addable >= INDEXED) {
50 if(r != Z && r->complex >= FNX)
57 gopcode(OAS, &nod, Z, &nod1);
76 diag(n, "unknown op in cgen: %O", o);
82 if(l->addable >= INDEXED && l->complex < FNX) {
83 if(nn != Z || r->addable < INDEXED) {
84 if(r->complex >= FNX && nn == Z)
87 regalloc(&nod, r, nn);
97 if(l->complex >= r->complex) {
98 reglcgen(&nod1, l, Z);
99 if(r->addable >= INDEXED) {
106 regalloc(&nod, r, nn);
109 regalloc(&nod, r, nn);
111 reglcgen(&nod1, l, Z);
120 regalloc(&nod, r, nn);
121 if(l->complex >= r->complex) {
122 reglcgen(&nod1, n, Z);
126 reglcgen(&nod1, n, Z);
128 regalloc(&nod2, n, Z);
129 gopcode(OAS, &nod1, Z, &nod2);
130 bitstore(l, &nod, &nod1, &nod2, nn);
138 bitload(n, &nod, Z, Z, nn);
139 gopcode(OAS, &nod, Z, nn);
146 if((t = vlog(r)) >= 0) {
147 /* signed div/mod by constant power of 2 */
149 gopcode(OGE, nodconst(0), nn, Z);
152 gopcode(OADD, nodconst((1<<t)-1), Z, nn);
154 gopcode(OASHR, nodconst(t), Z, nn);
156 gopcode(OSUB, nn, nodconst(0), nn);
157 gopcode(OAND, nodconst((1<<t)-1), Z, nn);
158 gopcode(OSUB, nn, nodconst(0), nn);
162 gopcode(OAND, nodconst((1<<t)-1), Z, nn);
172 if(!typefd[n->type->etype]) {
174 gopcode(o, Z, l, nn);
189 if(!typefd[n->type->etype]) {
195 gopcode(o, r, Z, nn);
208 if(o == OMUL || o == OLMUL) {
212 if(l->complex >= r->complex) {
213 regalloc(&nod, l, nn);
215 regalloc(&nod1, r, Z);
217 gopcode(o, &nod1, Z, &nod);
219 regalloc(&nod, r, nn);
221 regalloc(&nod1, l, Z);
223 gopcode(o, &nod, &nod1, &nod);
225 gopcode(OAS, &nod, Z, nn);
241 if(!typefd[r->type->etype])
242 if(!typefd[n->type->etype]) {
243 if(l->addable < INDEXED)
244 reglcgen(&nod2, l, Z);
247 regalloc(&nod, r, nn);
248 gopcode(OAS, &nod2, Z, &nod);
249 gopcode(o, r, Z, &nod);
250 gopcode(OAS, &nod, Z, &nod2);
253 if(l->addable < INDEXED)
266 if(l->complex >= r->complex) {
267 if(l->addable < INDEXED)
268 reglcgen(&nod2, l, Z);
271 regalloc(&nod1, r, Z);
274 regalloc(&nod1, r, Z);
276 if(l->addable < INDEXED)
277 reglcgen(&nod2, l, Z);
282 regalloc(&nod, n, nn);
284 gopcode(o, &nod1, Z, &nod);
287 gopcode(OAS, &nod, Z, nn);
290 if(l->addable < INDEXED)
295 regalloc(&nod4, n, nn);
296 if(l->complex >= r->complex) {
297 bitload(l, &nod, &nod1, &nod2, &nod4);
298 regalloc(&nod3, r, Z);
301 regalloc(&nod3, r, Z);
303 bitload(l, &nod, &nod1, &nod2, &nod4);
306 gopcode(o, &nod3, Z, &nod4);
310 bitstore(l, &nod, &nod1, &nod2, nn);
322 if(l->complex >= FNX) {
324 diag(n, "bad function call");
326 regret(&nod, l->left);
328 regsalloc(&nod1, l->left);
329 gopcode(OAS, &nod, Z, &nod1);
343 gargs(r, &nod, &nod1);
344 if(l->addable < INDEXED) {
345 reglcgen(&nod, l, Z);
346 gopcode(OFUNC, Z, Z, &nod);
349 gopcode(OFUNC, Z, Z, l);
355 gopcode(OAS, &nod, Z, nn);
365 regialloc(&nod, n, nn);
369 if(sconst(r) && (v = r->vconst+nod.xoffset) > -4096 && v < 4096) {
378 gopcode(OAS, &nod, Z, nn);
425 * convert from types l->n->nn
427 if(nocast(l->type, n->type)) {
428 if(nocast(n->type, nn->type)) {
433 regalloc(&nod, l, nn);
435 regalloc(&nod1, n, &nod);
439 gopcode(OAS, &nod, Z, &nod1);
440 gopcode(OAS, &nod1, Z, nn);
446 sugen(l, nodrat, l->type->width);
448 warn(n, "non-interruptable temporary");
450 if(!r || r->op != OCONST) {
451 diag(n, "DOT and no offset");
454 nod.xoffset += (long)r->vconst;
474 if(l->type->etype == TIND)
475 v = l->type->link->width;
483 if(l->addable < INDEXED)
484 reglcgen(&nod2, l, Z);
488 regalloc(&nod, l, nn);
489 gopcode(OAS, &nod2, Z, &nod);
490 regalloc(&nod1, l, Z);
491 if(typefd[l->type->etype]) {
492 regalloc(&nod3, l, Z);
494 gopcode(OAS, nodfconst(-v), Z, &nod3);
495 gopcode(OSUB, &nod3, &nod, &nod1);
497 gopcode(OAS, nodfconst(v), Z, &nod3);
498 gopcode(OADD, &nod3, &nod, &nod1);
502 gopcode(OADD, nodconst(v), &nod, &nod1);
503 gopcode(OAS, &nod1, Z, &nod2);
507 if(l->addable < INDEXED)
514 if(l->type->etype == TIND)
515 v = l->type->link->width;
522 if(l->addable < INDEXED)
523 reglcgen(&nod2, l, Z);
527 regalloc(&nod, l, nn);
528 gopcode(OAS, &nod2, Z, &nod);
529 if(typefd[l->type->etype]) {
530 regalloc(&nod3, l, Z);
532 gopcode(OAS, nodfconst(-v), Z, &nod3);
533 gopcode(OSUB, &nod3, Z, &nod);
535 gopcode(OAS, nodfconst(v), Z, &nod3);
536 gopcode(OADD, &nod3, Z, &nod);
540 gopcode(OADD, nodconst(v), Z, &nod);
541 gopcode(OAS, &nod, Z, &nod2);
542 if(nn && l->op == ONAME) /* in x=++i, emit USED(i) */
546 if(l->addable < INDEXED)
551 if(nn != Z && (o == OPOSTINC || o == OPOSTDEC)) {
552 bitload(l, &nod, &nod1, &nod2, Z);
553 gopcode(OAS, &nod, Z, nn);
554 gopcode(OADD, nodconst(v), Z, &nod);
555 bitstore(l, &nod, &nod1, &nod2, Z);
558 bitload(l, &nod, &nod1, &nod2, nn);
559 gopcode(OADD, nodconst(v), Z, &nod);
560 bitstore(l, &nod, &nod1, &nod2, nn);
568 reglcgen(Node *t, Node *n, Node *nn)
578 if(sconst(r) && (v = r->vconst+t->xoffset) > -4096 && v < 4096) {
587 } else if(n->op == OINDREG) {
588 if((v = n->xoffset) > -4096 && v < 4096) {
602 reglpcgen(Node *n, Node *nn, int f)
607 nn->type = types[TLONG];
619 lcgen(Node *n, Node *nn)
625 prtree(nn, "lcgen lhs");
628 if(n == Z || n->type == T)
632 regalloc(&nod, n, Z);
636 if(n->addable < INDEXED) {
637 diag(n, "unknown op in lcgen: %O", n->op);
644 nod.type = types[TIND];
645 gopcode(OAS, &nod, Z, nn);
649 cgen(n->left, n->left);
660 lcgen(n->right->left, nn);
664 lcgen(n->right->right, nn);
671 bcgen(Node *n, int true)
681 boolgen(Node *n, int true, Node *nn)
685 Node *l, *r, nod, nod1;
689 prtree(nn, "boolgen lhs");
690 prtree(n, "boolgen");
698 regalloc(&nod, n, nn);
702 o = comrel[relindex(o)];
703 if(typefd[n->type->etype]) {
704 gopcode(o, nodfconst(0), &nod, Z);
706 gopcode(o, nodconst(0), &nod, Z);
724 boolgen(r, true, nn);
728 boolgen(l, !true, nn);
734 bcgen(r->left, true);
739 bcgen(r->right, !true);
787 o = comrel[relindex(o)];
788 if(l->complex >= FNX && r->complex >= FNX) {
792 gopcode(OAS, &nod, Z, &nod1);
796 boolgen(&nod, true, nn);
800 regalloc(&nod, r, nn);
802 o = invrel[relindex(o)];
803 gopcode(o, l, &nod, Z);
808 regalloc(&nod, l, nn);
810 gopcode(o, r, &nod, Z);
814 if(l->complex >= r->complex) {
815 regalloc(&nod1, l, nn);
816 cgenrel(l, &nod1, 1);
817 regalloc(&nod, r, Z);
820 regalloc(&nod, r, nn);
822 regalloc(&nod1, l, Z);
823 cgenrel(l, &nod1, 1);
825 gopcode(o, &nod, &nod1, Z);
832 gopcode(OAS, nodconst(1), Z, nn);
836 gopcode(OAS, nodconst(0), Z, nn);
845 sugen(Node *n, Node *nn, long w)
848 Node nod0, nod1, nod2, nod3, nod4, *l, *r;
853 if(n == Z || n->type == T)
856 prtree(nn, "sugen lhs");
865 nullwarn(n->left, Z);
873 if(n->type && typev[n->type->etype]) {
875 nullwarn(n->left, Z);
880 nn->type = types[TLONG];
881 reglcgen(&nod1, nn, Z);
884 if(align(0, types[TCHAR], Aarg1)) /* isbigendian */
885 gopcode(OAS, nod32const(n->vconst>>32), Z, &nod1);
887 gopcode(OAS, nod32const(n->vconst), Z, &nod1);
888 nod1.xoffset += SZ_LONG;
889 if(align(0, types[TCHAR], Aarg1)) /* isbigendian */
890 gopcode(OAS, nod32const(n->vconst), Z, &nod1);
892 gopcode(OAS, nod32const(n->vconst>>32), Z, &nod1);
901 sugen(l, nodrat, l->type->width);
903 warn(n, "non-interruptable temporary");
906 if(!r || r->op != OCONST) {
907 diag(n, "DOT and no offset");
910 nod1.xoffset += (long)r->vconst;
918 * rewrite so lhs has no fn call
920 if(nn != Z && nn->complex >= FNX) {
922 nod1.type = typ(TIND, n->type);
923 regret(&nod2, &nod1);
925 regsalloc(&nod0, &nod1);
926 gopcode(OAS, &nod2, Z, &nod0);
940 for(t = n->type->link; t != T; t = t->down) {
951 * hand craft *(&nn + o) = l
966 nod2.type = typ(TIND, t);
972 nod3.type = nod2.type;
977 nod4.type = nod2.type;
978 nod4.vconst = t->offset;
991 if(n->addable < INDEXED)
992 sugen(n->right, n->left, w);
995 sugen(n->right, nodrat, w);
996 warn(n, "non-interruptable temporary");
997 sugen(nodrat, n->left, w);
998 sugen(nodrat, nn, w);
1003 sugen(n, nodrat, w);
1006 if(nn->op != OIND) {
1007 nn = new1(OADDR, nn, Z);
1008 nn->type = types[TIND];
1012 n = new(OFUNC, n->left, new(OLIST, nn, n->right));
1013 n->type = types[TVOID];
1014 n->left->type = types[TVOID];
1021 sugen(n->right->left, nn, w);
1025 sugen(n->right->right, nn, w);
1031 sugen(n->right, nn, w);
1039 if(n->complex >= FNX && nn->complex >= FNX) {
1041 nn->type = types[TLONG];
1042 regialloc(&nod1, nn, Z);
1044 regsalloc(&nod2, nn);
1047 gopcode(OAS, &nod1, Z, &nod2);
1050 nod2.type = typ(TIND, t);
1065 if(n->complex > nn->complex) {
1066 reglpcgen(&nod1, n, 1);
1067 reglpcgen(&nod2, nn, 1);
1069 reglpcgen(&nod2, nn, 1);
1070 reglpcgen(&nod1, n, 1);
1072 regalloc(&nod3, ®node, Z);
1073 regalloc(&nod4, ®node, Z);
1074 if(nod3.reg > nod4.reg){
1075 /* code below assumes nod3 loaded first */
1076 Node t = nod3; nod3 = nod4; nod4 = t;
1078 nod0 = *nodconst((1<<nod3.reg)|(1<<nod4.reg));
1079 if(w == 2 && nod1.xoffset == 0)
1080 gmovm(&nod1, &nod0, 0);
1082 gmove(&nod1, &nod3);
1084 nod1.xoffset += SZ_LONG;
1085 gmove(&nod1, &nod4);
1088 if(w == 2 && nod2.xoffset == 0)
1089 gmovm(&nod0, &nod2, 0);
1091 gmove(&nod3, &nod2);
1093 nod2.xoffset += SZ_LONG;
1094 gmove(&nod4, &nod2);
1104 if(n->complex > nn->complex) {
1105 reglpcgen(&nod1, n, 0);
1106 reglpcgen(&nod2, nn, 0);
1108 reglpcgen(&nod2, nn, 0);
1109 reglpcgen(&nod1, n, 0);
1113 for(c = 0; c < w && c < 4; c++) {
1120 nod4 = *(nodconst(m));
1123 gmovm(&nod1, &nod4, 1);
1124 gmovm(&nod4, &nod2, 1);
1129 regalloc(&nod3, ®node, Z);
1130 gopcode(OAS, nodconst(w/c), Z, &nod3);
1134 gmovm(&nod1, &nod4, 1);
1135 gmovm(&nod4, &nod2, 1);
1137 gopcode(OSUB, nodconst(1), Z, &nod3);
1138 gopcode(OEQ, nodconst(0), &nod3, Z);
1147 while ((m&(1<<i)) == 0)
1155 gmovm(&nod1, &nod4, 0);
1156 gmovm(&nod4, &nod2, 0);
1160 while ((m&(1<<i)) == 0)