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(typesu[n->type->etype]) {
25 sugen(n, nn, n->type->width);
31 if(n->addable >= INDEXED) {
50 if(r != Z && r->complex >= FNX)
53 if(cond(o) && typesu[l->type->etype])
60 gopcode(OAS, &nod, Z, &nod1);
79 diag(n, "unknown op in cgen: %O", o);
88 regalloc(&nod, l, nn);
90 gopcode(o, &nod, Z, &nod);
98 if(l->addable >= INDEXED && l->complex < FNX) {
99 if(nn != Z || r->addable < INDEXED) { /* || hardconst(r) */
100 if(r->complex >= FNX && nn == Z)
103 regalloc(&nod, r, nn);
113 if(l->complex >= r->complex) {
114 /* TO DO: see 6c for OINDEX && immconst(r) */
115 reglcgen(&nod1, l, Z);
116 if(r->addable >= INDEXED) { /* && !hardconst(r) */
123 regalloc(&nod, r, nn);
126 regalloc(&nod, r, nn);
128 reglcgen(&nod1, l, Z);
137 regalloc(&nod, r, nn);
138 if(l->complex >= r->complex) {
139 reglcgen(&nod1, n, Z);
143 reglcgen(&nod1, n, Z);
145 regalloc(&nod2, n, Z);
146 gopcode(OAS, &nod1, Z, &nod2);
147 bitstore(l, &nod, &nod1, &nod2, nn);
155 bitload(n, &nod, Z, Z, nn);
156 gopcode(OAS, &nod, Z, nn);
163 if((t = vlog(r)) >= 0) {
164 /* signed div/mod by constant power of 2 */
166 gopcode(OGE, nodconst(0), nn, Z);
169 gopcode(OADD, nodconst((1<<t)-1), Z, nn);
171 gopcode(OASHR, nodconst(t), Z, nn);
173 gopcode(ONEG, nn, Z, nn);
174 gopcode(OAND, nodconst((1<<t)-1), Z, nn);
175 gopcode(ONEG, nn, Z, nn);
179 gopcode(OAND, nodconst((1<<t)-1), Z, nn);
189 if(r->op == OCONST && r->vconst == -1){
191 gopcode(OCOM, nn, Z, nn);
208 if(!typefd[n->type->etype]) {
214 gopcode(o, r, Z, nn);
227 if(o == OMUL || o == OLMUL) {
231 if(l->complex >= r->complex) {
232 regalloc(&nod, l, nn);
234 regalloc(&nod1, l, Z); /* note: l used for type, so shifts work! */
236 gopcode(o, &nod1, Z, &nod);
238 regalloc(&nod, l, nn); /* note: l used for type, so shifts work! */
240 regalloc(&nod1, l, Z);
242 gopcode(o, &nod, &nod1, &nod);
244 gopcode(OAS, &nod, Z, nn);
260 if(!typefd[r->type->etype])
261 if(!typefd[n->type->etype]) {
262 if(l->addable < INDEXED)
263 reglcgen(&nod2, l, Z);
266 regalloc(&nod, l, nn); /* note: l used for type, so shifts work! */
267 gopcode(OAS, &nod2, Z, &nod);
268 gopcode(o, r, Z, &nod);
269 gopcode(OAS, &nod, Z, &nod2);
272 if(l->addable < INDEXED)
285 if(l->complex >= r->complex) {
286 if(l->addable < INDEXED)
287 reglcgen(&nod2, l, Z);
290 regalloc(&nod, n, nn);
293 regalloc(&nod, n, nn);
295 if(l->addable < INDEXED)
296 reglcgen(&nod2, l, Z);
300 regalloc(&nod1, n, Z);
301 gopcode(OAS, &nod2, Z, &nod1);
302 if(nod1.type->etype != nod.type->etype){
303 regalloc(&nod3, &nod, Z);
308 gopcode(o, &nod, &nod1, &nod);
314 if(l->addable < INDEXED)
319 regalloc(&nod4, n, nn);
320 regalloc(&nod3, r, Z);
321 if(l->complex >= r->complex) {
322 bitload(l, &nod, &nod1, &nod2, &nod4);
326 bitload(l, &nod, &nod1, &nod2, &nod4);
329 gopcode(o, &nod3, Z, &nod4);
333 bitstore(l, &nod, &nod1, &nod2, nn);
346 if(l->complex >= FNX) {
348 diag(n, "bad function call");
350 regret(&nod, l->left);
352 regsalloc(&nod1, l->left);
353 gopcode(OAS, &nod, Z, &nod1);
367 gargs(r, &nod, &nod1);
368 if(l->addable < INDEXED) {
369 reglcgen(&nod, l, Z);
370 gopcode(OFUNC, Z, Z, &nod);
373 gopcode(OFUNC, Z, Z, l);
379 gopcode(OAS, &nod, Z, nn);
389 regialloc(&nod, n, nn);
393 if(usableoffset(n, nod.xoffset, r)){
402 gopcode(OAS, &nod, Z, nn);
449 * convert from types l->n->nn
451 if(nocast(l->type, n->type) && nocast(n->type, nn->type)) {
452 /* both null, gen l->nn */
456 if(ewidth[n->type->etype] < ewidth[l->type->etype]){
457 if(l->type->etype == TIND && typechlp[n->type->etype])
458 warn(n, "conversion of pointer to shorter integer");
460 if(nocast(n->type, nn->type) || castup(n->type, nn->type)){
461 if(typefd[l->type->etype] != typefd[nn->type->etype])
462 regalloc(&nod, l, nn);
464 regalloc(&nod, nn, nn);
471 regalloc(&nod, l, nn);
473 regalloc(&nod1, n, &nod);
477 gopcode(OAS, &nod, Z, &nod1);
478 gopcode(OAS, &nod1, Z, nn);
484 sugen(l, nodrat, l->type->width);
486 warn(n, "non-interruptable temporary");
488 if(!r || r->op != OCONST) {
489 diag(n, "DOT and no offset");
492 nod.xoffset += (long)r->vconst;
512 if(l->type->etype == TIND)
513 v = l->type->link->width;
521 if(l->addable < INDEXED)
522 reglcgen(&nod2, l, Z);
526 regalloc(&nod, l, nn);
527 gopcode(OAS, &nod2, Z, &nod);
528 regalloc(&nod1, l, Z);
529 if(typefd[l->type->etype]) {
530 regalloc(&nod3, l, Z);
532 gopcode(OAS, nodfconst(-v), Z, &nod3);
533 gopcode(OSUB, &nod3, &nod, &nod1);
535 gopcode(OAS, nodfconst(v), Z, &nod3);
536 gopcode(OADD, &nod3, &nod, &nod1);
540 gopcode(OADD, nodconst(v), &nod, &nod1);
541 gopcode(OAS, &nod1, Z, &nod2);
545 if(l->addable < INDEXED)
552 if(l->type->etype == TIND)
553 v = l->type->link->width;
560 if(l->addable < INDEXED)
561 reglcgen(&nod2, l, Z);
565 regalloc(&nod, l, nn);
566 gopcode(OAS, &nod2, Z, &nod);
567 if(typefd[l->type->etype]) {
568 regalloc(&nod3, l, Z);
570 gopcode(OAS, nodfconst(-v), Z, &nod3);
571 gopcode(OSUB, &nod3, Z, &nod);
573 gopcode(OAS, nodfconst(v), Z, &nod3);
574 gopcode(OADD, &nod3, Z, &nod);
578 gopcode(OADD, nodconst(v), Z, &nod);
579 gopcode(OAS, &nod, Z, &nod2);
580 if(nn && l->op == ONAME) /* in x=++i, emit USED(i) */
584 if(l->addable < INDEXED)
589 if(nn != Z && (o == OPOSTINC || o == OPOSTDEC)) {
590 bitload(l, &nod, &nod1, &nod2, Z);
591 gopcode(OAS, &nod, Z, nn);
592 gopcode(OADD, nodconst(v), Z, &nod);
593 bitstore(l, &nod, &nod1, &nod2, Z);
596 bitload(l, &nod, &nod1, &nod2, nn);
597 gopcode(OADD, nodconst(v), Z, &nod);
598 bitstore(l, &nod, &nod1, &nod2, nn);
606 reglcgen(Node *t, Node *n, Node *nn)
616 if(usableoffset(n, t->xoffset, r)) {
625 } else if(n->op == OINDREG) {
626 if(usableoffset(n, t->xoffset+n->xoffset, nil)) {
628 n->type = types[TIND];
646 lcgen(Node *n, Node *nn)
652 prtree(nn, "lcgen lhs");
655 if(n == Z || n->type == T)
659 regalloc(&nod, n, Z);
663 if(n->addable < INDEXED) {
664 diag(n, "unknown op in lcgen: %O", n->op);
671 nod.type = types[TIND];
672 gopcode(OAS, &nod, Z, nn);
676 cgen(n->left, n->left);
687 lcgen(n->right->left, nn);
691 lcgen(n->right->right, nn);
698 bcgen(Node *n, int true)
708 boolgen(Node *n, int true, Node *nn)
712 Node *l, *r, nod, nod1;
716 prtree(nn, "boolgen lhs");
717 prtree(n, "boolgen");
725 regalloc(&nod, n, nn);
730 if(typefd[n->type->etype]) {
731 gopcode(true ? o | BTRUE : o, nodfconst(0), &nod, Z);
733 gopcode(o, nodconst(0), &nod, Z);
751 boolgen(r, true, nn);
755 boolgen(l, !true, nn);
761 bcgen(r->left, true);
766 bcgen(r->right, !true);
814 o = comrel[relindex(o)];
815 if(l->complex >= FNX && r->complex >= FNX) {
819 gopcode(OAS, &nod, Z, &nod1);
823 boolgen(&nod, true, nn);
827 regalloc(&nod, r, nn);
829 o = invrel[relindex(o)];
830 gopcode(true ? o | BTRUE : o, l, &nod, Z);
835 regalloc(&nod, l, nn);
837 gopcode(true ? o | BTRUE : o, r, &nod, Z);
841 if(l->complex >= r->complex) {
842 regalloc(&nod1, l, nn);
843 cgenrel(l, &nod1, 1);
844 regalloc(&nod, r, Z);
847 regalloc(&nod, r, nn);
849 regalloc(&nod1, l, Z);
850 cgenrel(l, &nod1, 1);
852 gopcode(true ? o | BTRUE : o, &nod, &nod1, Z);
859 gopcode(OAS, nodconst(1), Z, nn);
863 gopcode(OAS, nodconst(0), Z, nn);
872 sugen(Node *n, Node *nn, long w)
875 Node nod0, nod1, nod2, nod3, nod4, *l, *r;
880 if(n == Z || n->type == T)
883 prtree(nn, "sugen lhs");
892 nullwarn(n->left, Z);
900 if(n->type && typev[n->type->etype]) {
902 nullwarn(n->left, Z);
907 nn->type = types[TLONG];
908 reglcgen(&nod1, nn, Z);
911 if(align(0, types[TCHAR], Aarg1)) /* isbigendian */
912 gopcode(OAS, nod32const(n->vconst>>32), Z, &nod1);
914 gopcode(OAS, nod32const(n->vconst), Z, &nod1);
915 nod1.xoffset += SZ_LONG;
916 if(align(0, types[TCHAR], Aarg1)) /* isbigendian */
917 gopcode(OAS, nod32const(n->vconst), Z, &nod1);
919 gopcode(OAS, nod32const(n->vconst>>32), Z, &nod1);
928 sugen(l, nodrat, l->type->width);
930 warn(n, "non-interruptable temporary");
933 if(!r || r->op != OCONST) {
934 diag(n, "DOT and no offset");
937 nod1.xoffset += (long)r->vconst;
945 * rewrite so lhs has no side effects
947 if(nn != Z && side(nn)) {
949 nod1.type = typ(TIND, n->type);
950 regret(&nod2, &nod1);
952 regsalloc(&nod0, &nod1);
953 gopcode(OAS, &nod2, Z, &nod0);
967 for(t = n->type->link; t != T; t = t->down) {
978 * hand craft *(&nn + o) = l
993 nod2.type = typ(TIND, t);
999 nod3.type = nod2.type;
1004 nod4.type = nod2.type;
1005 nod4.vconst = t->offset;
1018 if(n->addable < INDEXED)
1019 sugen(n->right, n->left, w);
1022 sugen(n->right, nodrat, w);
1023 warn(n, "non-interruptable temporary");
1024 sugen(nodrat, n->left, w);
1025 sugen(nodrat, nn, w);
1030 sugen(n, nodrat, w);
1033 if(nn->op != OIND) {
1034 nn = new1(OADDR, nn, Z);
1035 nn->type = types[TIND];
1039 n = new(OFUNC, n->left, new(OLIST, nn, n->right));
1040 n->type = types[TVOID];
1041 n->left->type = types[TVOID];
1048 sugen(n->right->left, nn, w);
1052 sugen(n->right->right, nn, w);
1058 sugen(n->right, nn, w);
1066 if(n->complex >= FNX && nn->complex >= FNX) {
1068 nn->type = types[TLONG];
1069 regialloc(&nod1, nn, Z);
1071 regsalloc(&nod2, &nod1);
1074 gopcode(OAS, &nod1, Z, &nod2);
1077 nod2.type = typ(TIND, t);
1090 /* TO DO: use AMOV/VLONG when possible */
1091 if(n->complex > nn->complex) {
1093 n->type = types[TLONG];
1094 reglcgen(&nod1, n, Z);
1098 nn->type = types[TLONG];
1099 reglcgen(&nod2, nn, Z);
1103 nn->type = types[TLONG];
1104 reglcgen(&nod2, nn, Z);
1108 n->type = types[TLONG];
1109 reglcgen(&nod1, n, Z);
1115 layout(&nod1, &nod2, w, 0, Z);
1120 * minimize space for unrolling loop
1121 * 3,4,5 times. (6 or more is never minimum)
1122 * if small structure, try 2 also.
1135 regalloc(&nod3, ®node, Z);
1136 layout(&nod1, &nod2, w%c, w/c, &nod3);
1139 layout(&nod1, &nod2, c, 0, Z);
1141 gopcode(OSUB, nodconst(1L), Z, &nod3);
1142 nod1.op = OREGISTER;
1144 nod1.type = types[TIND];
1145 gopcode(OADD, nodconst(c*SZ_LONG), Z, &nod1);
1147 nod2.op = OREGISTER;
1149 nod2.type = types[TIND];
1150 gopcode(OADD, nodconst(c*SZ_LONG), Z, &nod2);
1153 gopcode(OGT, nodconst(0), &nod3, 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);
1175 gopcode(OAS, f, Z, &t1);
1176 f->xoffset += SZ_LONG;
1179 gopcode(OAS, nodconst(cv), Z, cn);
1181 gopcode(OAS, f, Z, &t2);
1182 f->xoffset += SZ_LONG;
1185 gopcode(OAS, &t1, Z, t);
1186 t->xoffset += SZ_LONG;
1189 gopcode(OAS, f, Z, &t1);
1190 f->xoffset += SZ_LONG;
1193 gopcode(OAS, &t2, Z, t);
1194 t->xoffset += SZ_LONG;
1197 gopcode(OAS, &t1, Z, t);
1198 t->xoffset += SZ_LONG;
1205 * if a constant and vlong, doesn't fit as 32-bit signed immediate
1210 return n->op == OCONST && !sconst(n);
1214 * casting up to t2 covers an intermediate cast to t1
1217 castup(Type *t1, Type *t2)
1221 if(!nilcast(t1, t2))
1223 /* known to be small to large */
1228 return ft == TLONG || ft == TINT || ft == TSHORT || ft == TCHAR;
1231 return ft == TULONG || ft == TUINT || ft == TUSHORT || ft == TUCHAR;
1233 return ft == TLONG || ft == TINT || ft == TSHORT;
1235 return ft == TULONG || ft == TUINT || ft == TUSHORT;