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(&nod1, r, Z);
293 regalloc(&nod1, r, Z);
295 if(l->addable < INDEXED)
296 reglcgen(&nod2, l, Z);
300 if(nod1.type->etype == nod2.type->etype || !typefd[nod1.type->etype])
301 regalloc(&nod, &nod2, nn);
303 regalloc(&nod, &nod1, Z);
304 gopcode(OAS, &nod2, Z, &nod);
305 if(nod1.type->etype != nod.type->etype){
306 regalloc(&nod3, &nod, Z);
311 gopcode(o, &nod1, &nod, &nod);
317 if(l->addable < INDEXED)
322 regalloc(&nod4, n, nn);
323 regalloc(&nod3, r, Z);
324 if(l->complex >= r->complex) {
325 bitload(l, &nod, &nod1, &nod2, &nod4);
329 bitload(l, &nod, &nod1, &nod2, &nod4);
332 gopcode(o, &nod3, Z, &nod4);
336 bitstore(l, &nod, &nod1, &nod2, nn);
349 if(l->complex >= FNX) {
351 diag(n, "bad function call");
353 regret(&nod, l->left);
355 regsalloc(&nod1, l->left);
356 gopcode(OAS, &nod, Z, &nod1);
370 gargs(r, &nod, &nod1);
371 if(l->addable < INDEXED) {
372 reglcgen(&nod, l, Z);
373 gopcode(OFUNC, Z, Z, &nod);
376 gopcode(OFUNC, Z, Z, l);
382 gopcode(OAS, &nod, Z, nn);
392 regialloc(&nod, n, nn);
396 if(usableoffset(n, nod.xoffset, r)){
405 gopcode(OAS, &nod, Z, nn);
452 * convert from types l->n->nn
454 if(nocast(l->type, n->type) && nocast(n->type, nn->type)) {
455 /* both null, gen l->nn */
459 if(ewidth[n->type->etype] < ewidth[l->type->etype]){
460 if(l->type->etype == TIND && typechlp[n->type->etype])
461 warn(n, "conversion of pointer to shorter integer");
463 if(nocast(n->type, nn->type) || castup(n->type, nn->type)){
464 if(typefd[l->type->etype] != typefd[nn->type->etype])
465 regalloc(&nod, l, nn);
467 regalloc(&nod, nn, nn);
474 regalloc(&nod, l, nn);
476 regalloc(&nod1, n, &nod);
480 gopcode(OAS, &nod, Z, &nod1);
481 gopcode(OAS, &nod1, Z, nn);
487 sugen(l, nodrat, l->type->width);
489 warn(n, "non-interruptable temporary");
491 if(!r || r->op != OCONST) {
492 diag(n, "DOT and no offset");
495 nod.xoffset += (long)r->vconst;
515 if(l->type->etype == TIND)
516 v = l->type->link->width;
524 if(l->addable < INDEXED)
525 reglcgen(&nod2, l, Z);
529 regalloc(&nod, l, nn);
530 gopcode(OAS, &nod2, Z, &nod);
531 regalloc(&nod1, l, Z);
532 if(typefd[l->type->etype]) {
533 regalloc(&nod3, l, Z);
535 gopcode(OAS, nodfconst(-v), Z, &nod3);
536 gopcode(OSUB, &nod3, &nod, &nod1);
538 gopcode(OAS, nodfconst(v), Z, &nod3);
539 gopcode(OADD, &nod3, &nod, &nod1);
543 gopcode(OADD, nodconst(v), &nod, &nod1);
544 gopcode(OAS, &nod1, Z, &nod2);
548 if(l->addable < INDEXED)
555 if(l->type->etype == TIND)
556 v = l->type->link->width;
563 if(l->addable < INDEXED)
564 reglcgen(&nod2, l, Z);
568 regalloc(&nod, l, nn);
569 gopcode(OAS, &nod2, Z, &nod);
570 if(typefd[l->type->etype]) {
571 regalloc(&nod3, l, Z);
573 gopcode(OAS, nodfconst(-v), Z, &nod3);
574 gopcode(OSUB, &nod3, Z, &nod);
576 gopcode(OAS, nodfconst(v), Z, &nod3);
577 gopcode(OADD, &nod3, Z, &nod);
581 gopcode(OADD, nodconst(v), Z, &nod);
582 gopcode(OAS, &nod, Z, &nod2);
583 if(nn && l->op == ONAME) /* in x=++i, emit USED(i) */
587 if(l->addable < INDEXED)
592 if(nn != Z && (o == OPOSTINC || o == OPOSTDEC)) {
593 bitload(l, &nod, &nod1, &nod2, Z);
594 gopcode(OAS, &nod, Z, nn);
595 gopcode(OADD, nodconst(v), Z, &nod);
596 bitstore(l, &nod, &nod1, &nod2, Z);
599 bitload(l, &nod, &nod1, &nod2, nn);
600 gopcode(OADD, nodconst(v), Z, &nod);
601 bitstore(l, &nod, &nod1, &nod2, nn);
609 reglcgen(Node *t, Node *n, Node *nn)
619 if(usableoffset(n, t->xoffset, r)) {
628 } else if(n->op == OINDREG) {
629 if(usableoffset(n, t->xoffset+n->xoffset, nil)) {
631 n->type = types[TIND];
649 lcgen(Node *n, Node *nn)
655 prtree(nn, "lcgen lhs");
658 if(n == Z || n->type == T)
662 regalloc(&nod, n, Z);
666 if(n->addable < INDEXED) {
667 diag(n, "unknown op in lcgen: %O", n->op);
674 nod.type = types[TIND];
675 gopcode(OAS, &nod, Z, nn);
679 cgen(n->left, n->left);
690 lcgen(n->right->left, nn);
694 lcgen(n->right->right, nn);
701 bcgen(Node *n, int true)
711 boolgen(Node *n, int true, Node *nn)
715 Node *l, *r, nod, nod1;
719 prtree(nn, "boolgen lhs");
720 prtree(n, "boolgen");
728 regalloc(&nod, n, nn);
733 if(typefd[n->type->etype]) {
734 gopcode(true ? o | BTRUE : o, nodfconst(0), &nod, Z);
736 gopcode(o, nodconst(0), &nod, Z);
754 boolgen(r, true, nn);
758 boolgen(l, !true, nn);
764 bcgen(r->left, true);
769 bcgen(r->right, !true);
817 o = comrel[relindex(o)];
818 if(l->complex >= FNX && r->complex >= FNX) {
822 gopcode(OAS, &nod, Z, &nod1);
826 boolgen(&nod, true, nn);
830 regalloc(&nod, r, nn);
832 o = invrel[relindex(o)];
833 gopcode(true ? o | BTRUE : o, l, &nod, Z);
838 regalloc(&nod, l, nn);
840 gopcode(true ? o | BTRUE : o, r, &nod, Z);
844 if(l->complex >= r->complex) {
845 regalloc(&nod1, l, nn);
846 cgenrel(l, &nod1, 1);
847 regalloc(&nod, r, Z);
850 regalloc(&nod, r, nn);
852 regalloc(&nod1, l, Z);
853 cgenrel(l, &nod1, 1);
855 gopcode(true ? o | BTRUE : o, &nod, &nod1, Z);
862 gopcode(OAS, nodconst(1), Z, nn);
866 gopcode(OAS, nodconst(0), Z, nn);
875 sugen(Node *n, Node *nn, long w)
878 Node nod0, nod1, nod2, nod3, nod4, *l, *r;
883 if(n == Z || n->type == T)
886 prtree(nn, "sugen lhs");
895 nullwarn(n->left, Z);
903 if(n->type && typev[n->type->etype]) {
905 nullwarn(n->left, Z);
910 nn->type = types[TLONG];
911 reglcgen(&nod1, nn, Z);
914 if(align(0, types[TCHAR], Aarg1)) /* isbigendian */
915 gopcode(OAS, nod32const(n->vconst>>32), Z, &nod1);
917 gopcode(OAS, nod32const(n->vconst), Z, &nod1);
918 nod1.xoffset += SZ_LONG;
919 if(align(0, types[TCHAR], Aarg1)) /* isbigendian */
920 gopcode(OAS, nod32const(n->vconst), Z, &nod1);
922 gopcode(OAS, nod32const(n->vconst>>32), Z, &nod1);
931 sugen(l, nodrat, l->type->width);
933 warn(n, "non-interruptable temporary");
936 if(!r || r->op != OCONST) {
937 diag(n, "DOT and no offset");
940 nod1.xoffset += (long)r->vconst;
948 * rewrite so lhs has no side effects
950 if(nn != Z && side(nn)) {
952 nod1.type = typ(TIND, n->type);
953 regret(&nod2, &nod1);
955 regsalloc(&nod0, &nod1);
956 gopcode(OAS, &nod2, Z, &nod0);
970 for(t = n->type->link; t != T; t = t->down) {
981 * hand craft *(&nn + o) = l
996 nod2.type = typ(TIND, t);
1002 nod3.type = nod2.type;
1007 nod4.type = nod2.type;
1008 nod4.vconst = t->offset;
1021 if(n->addable < INDEXED)
1022 sugen(n->right, n->left, w);
1025 sugen(n->right, nodrat, w);
1026 warn(n, "non-interruptable temporary");
1027 sugen(nodrat, n->left, w);
1028 sugen(nodrat, nn, w);
1033 sugen(n, nodrat, w);
1036 if(nn->op != OIND) {
1037 nn = new1(OADDR, nn, Z);
1038 nn->type = types[TIND];
1042 n = new(OFUNC, n->left, new(OLIST, nn, n->right));
1043 n->type = types[TVOID];
1044 n->left->type = types[TVOID];
1051 sugen(n->right->left, nn, w);
1055 sugen(n->right->right, nn, w);
1061 sugen(n->right, nn, w);
1069 if(n->complex >= FNX && nn->complex >= FNX) {
1071 nn->type = types[TLONG];
1072 regialloc(&nod1, nn, Z);
1074 regsalloc(&nod2, &nod1);
1077 gopcode(OAS, &nod1, Z, &nod2);
1080 nod2.type = typ(TIND, t);
1093 /* TO DO: use AMOV/VLONG when possible */
1094 if(n->complex > nn->complex) {
1096 n->type = types[TLONG];
1097 reglcgen(&nod1, n, Z);
1101 nn->type = types[TLONG];
1102 reglcgen(&nod2, nn, Z);
1106 nn->type = types[TLONG];
1107 reglcgen(&nod2, nn, Z);
1111 n->type = types[TLONG];
1112 reglcgen(&nod1, n, Z);
1118 layout(&nod1, &nod2, w, 0, Z);
1123 * minimize space for unrolling loop
1124 * 3,4,5 times. (6 or more is never minimum)
1125 * if small structure, try 2 also.
1138 regalloc(&nod3, ®node, Z);
1139 layout(&nod1, &nod2, w%c, w/c, &nod3);
1142 layout(&nod1, &nod2, c, 0, Z);
1144 gopcode(OSUB, nodconst(1L), Z, &nod3);
1145 nod1.op = OREGISTER;
1147 nod1.type = types[TIND];
1148 gopcode(OADD, nodconst(c*SZ_LONG), Z, &nod1);
1150 nod2.op = OREGISTER;
1152 nod2.type = types[TIND];
1153 gopcode(OADD, nodconst(c*SZ_LONG), Z, &nod2);
1156 gopcode(OGT, nodconst(0), &nod3, Z);
1166 layout(Node *f, Node *t, int c, int cv, Node *cn)
1171 layout(f, t, 2, 0, Z);
1175 regalloc(&t1, ®node, Z);
1176 regalloc(&t2, ®node, Z);
1178 gopcode(OAS, f, Z, &t1);
1179 f->xoffset += SZ_LONG;
1182 gopcode(OAS, nodconst(cv), Z, cn);
1184 gopcode(OAS, f, Z, &t2);
1185 f->xoffset += SZ_LONG;
1188 gopcode(OAS, &t1, Z, t);
1189 t->xoffset += SZ_LONG;
1192 gopcode(OAS, f, Z, &t1);
1193 f->xoffset += SZ_LONG;
1196 gopcode(OAS, &t2, Z, t);
1197 t->xoffset += SZ_LONG;
1200 gopcode(OAS, &t1, Z, t);
1201 t->xoffset += SZ_LONG;
1208 * if a constant and vlong, doesn't fit as 32-bit signed immediate
1213 return n->op == OCONST && !sconst(n);
1217 * casting up to t2 covers an intermediate cast to t1
1220 castup(Type *t1, Type *t2)
1224 if(!nilcast(t1, t2))
1226 /* known to be small to large */
1231 return ft == TLONG || ft == TINT || ft == TSHORT || ft == TCHAR;
1234 return ft == TULONG || ft == TUINT || ft == TUSHORT || ft == TUCHAR;
1236 return ft == TLONG || ft == TINT || ft == TSHORT;
1238 return ft == TULONG || ft == TUINT || ft == TUSHORT;