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 == nod2.type || !typefd[nod1.type->etype])
301 regalloc(&nod, &nod2, nn);
303 regalloc(&nod, &nod1, Z);
305 gopcode(o, &nod1, &nod, &nod);
311 if(l->addable < INDEXED)
316 regalloc(&nod4, n, nn);
317 regalloc(&nod3, r, Z);
318 if(l->complex >= r->complex) {
319 bitload(l, &nod, &nod1, &nod2, &nod4);
323 bitload(l, &nod, &nod1, &nod2, &nod4);
326 gopcode(o, &nod3, Z, &nod4);
330 bitstore(l, &nod, &nod1, &nod2, nn);
343 if(l->complex >= FNX) {
345 diag(n, "bad function call");
347 regret(&nod, l->left);
349 regsalloc(&nod1, l->left);
350 gopcode(OAS, &nod, Z, &nod1);
364 gargs(r, &nod, &nod1);
365 if(l->addable < INDEXED) {
366 reglcgen(&nod, l, Z);
367 gopcode(OFUNC, Z, Z, &nod);
370 gopcode(OFUNC, Z, Z, l);
376 gopcode(OAS, &nod, Z, nn);
386 regialloc(&nod, n, nn);
390 if(usableoffset(n, nod.xoffset, r)){
399 gopcode(OAS, &nod, Z, nn);
446 * convert from types l->n->nn
448 if(nocast(l->type, n->type) && nocast(n->type, nn->type)) {
449 /* both null, gen l->nn */
453 if(ewidth[n->type->etype] < ewidth[l->type->etype]){
454 if(l->type->etype == TIND && typechlp[n->type->etype])
455 warn(n, "conversion of pointer to shorter integer");
457 if(nocast(n->type, nn->type) || castup(n->type, nn->type)){
458 if(typefd[l->type->etype] != typefd[nn->type->etype])
459 regalloc(&nod, l, nn);
461 regalloc(&nod, nn, nn);
468 regalloc(&nod, l, nn);
470 regalloc(&nod1, n, &nod);
474 gopcode(OAS, &nod, Z, &nod1);
475 gopcode(OAS, &nod1, Z, nn);
481 sugen(l, nodrat, l->type->width);
483 warn(n, "non-interruptable temporary");
485 if(!r || r->op != OCONST) {
486 diag(n, "DOT and no offset");
489 nod.xoffset += (long)r->vconst;
509 if(l->type->etype == TIND)
510 v = l->type->link->width;
518 if(l->addable < INDEXED)
519 reglcgen(&nod2, l, Z);
523 regalloc(&nod, l, nn);
524 gopcode(OAS, &nod2, Z, &nod);
525 regalloc(&nod1, l, Z);
526 if(typefd[l->type->etype]) {
527 regalloc(&nod3, l, Z);
529 gopcode(OAS, nodfconst(-v), Z, &nod3);
530 gopcode(OSUB, &nod3, &nod, &nod1);
532 gopcode(OAS, nodfconst(v), Z, &nod3);
533 gopcode(OADD, &nod3, &nod, &nod1);
537 gopcode(OADD, nodconst(v), &nod, &nod1);
538 gopcode(OAS, &nod1, Z, &nod2);
542 if(l->addable < INDEXED)
549 if(l->type->etype == TIND)
550 v = l->type->link->width;
557 if(l->addable < INDEXED)
558 reglcgen(&nod2, l, Z);
562 regalloc(&nod, l, nn);
563 gopcode(OAS, &nod2, Z, &nod);
564 if(typefd[l->type->etype]) {
565 regalloc(&nod3, l, Z);
567 gopcode(OAS, nodfconst(-v), Z, &nod3);
568 gopcode(OSUB, &nod3, Z, &nod);
570 gopcode(OAS, nodfconst(v), Z, &nod3);
571 gopcode(OADD, &nod3, Z, &nod);
575 gopcode(OADD, nodconst(v), Z, &nod);
576 gopcode(OAS, &nod, Z, &nod2);
577 if(nn && l->op == ONAME) /* in x=++i, emit USED(i) */
581 if(l->addable < INDEXED)
586 if(nn != Z && (o == OPOSTINC || o == OPOSTDEC)) {
587 bitload(l, &nod, &nod1, &nod2, Z);
588 gopcode(OAS, &nod, Z, nn);
589 gopcode(OADD, nodconst(v), Z, &nod);
590 bitstore(l, &nod, &nod1, &nod2, Z);
593 bitload(l, &nod, &nod1, &nod2, nn);
594 gopcode(OADD, nodconst(v), Z, &nod);
595 bitstore(l, &nod, &nod1, &nod2, nn);
603 reglcgen(Node *t, Node *n, Node *nn)
613 if(usableoffset(n, t->xoffset, r)) {
622 } else if(n->op == OINDREG) {
623 if(usableoffset(n, t->xoffset+n->xoffset, nil)) {
625 n->type = types[TIND];
643 lcgen(Node *n, Node *nn)
649 prtree(nn, "lcgen lhs");
652 if(n == Z || n->type == T)
656 regalloc(&nod, n, Z);
660 if(n->addable < INDEXED) {
661 diag(n, "unknown op in lcgen: %O", n->op);
668 nod.type = types[TIND];
669 gopcode(OAS, &nod, Z, nn);
673 cgen(n->left, n->left);
684 lcgen(n->right->left, nn);
688 lcgen(n->right->right, nn);
695 bcgen(Node *n, int true)
705 boolgen(Node *n, int true, Node *nn)
709 Node *l, *r, nod, nod1;
713 prtree(nn, "boolgen lhs");
714 prtree(n, "boolgen");
722 regalloc(&nod, n, nn);
727 if(typefd[n->type->etype]) {
728 gopcode(true ? o | BTRUE : o, nodfconst(0), &nod, Z);
730 gopcode(o, nodconst(0), &nod, Z);
748 boolgen(r, true, nn);
752 boolgen(l, !true, nn);
758 bcgen(r->left, true);
763 bcgen(r->right, !true);
811 o = comrel[relindex(o)];
812 if(l->complex >= FNX && r->complex >= FNX) {
816 gopcode(OAS, &nod, Z, &nod1);
820 boolgen(&nod, true, nn);
824 regalloc(&nod, r, nn);
826 o = invrel[relindex(o)];
827 gopcode(true ? o | BTRUE : o, l, &nod, Z);
832 regalloc(&nod, l, nn);
834 gopcode(true ? o | BTRUE : o, r, &nod, Z);
838 if(l->complex >= r->complex) {
839 regalloc(&nod1, l, nn);
840 cgenrel(l, &nod1, 1);
841 regalloc(&nod, r, Z);
844 regalloc(&nod, r, nn);
846 regalloc(&nod1, l, Z);
847 cgenrel(l, &nod1, 1);
849 gopcode(true ? o | BTRUE : o, &nod, &nod1, Z);
856 gopcode(OAS, nodconst(1), Z, nn);
860 gopcode(OAS, nodconst(0), Z, nn);
869 sugen(Node *n, Node *nn, long w)
872 Node nod0, nod1, nod2, nod3, nod4, *l, *r;
877 if(n == Z || n->type == T)
880 prtree(nn, "sugen lhs");
889 nullwarn(n->left, Z);
897 if(n->type && typev[n->type->etype]) {
899 nullwarn(n->left, Z);
904 nn->type = types[TLONG];
905 reglcgen(&nod1, nn, Z);
908 if(align(0, types[TCHAR], Aarg1)) /* isbigendian */
909 gopcode(OAS, nod32const(n->vconst>>32), Z, &nod1);
911 gopcode(OAS, nod32const(n->vconst), Z, &nod1);
912 nod1.xoffset += SZ_LONG;
913 if(align(0, types[TCHAR], Aarg1)) /* isbigendian */
914 gopcode(OAS, nod32const(n->vconst), Z, &nod1);
916 gopcode(OAS, nod32const(n->vconst>>32), Z, &nod1);
925 sugen(l, nodrat, l->type->width);
927 warn(n, "non-interruptable temporary");
930 if(!r || r->op != OCONST) {
931 diag(n, "DOT and no offset");
934 nod1.xoffset += (long)r->vconst;
942 * rewrite so lhs has no side effects
944 if(nn != Z && side(nn)) {
946 nod1.type = typ(TIND, n->type);
947 regret(&nod2, &nod1);
949 regsalloc(&nod0, &nod1);
950 gopcode(OAS, &nod2, Z, &nod0);
964 for(t = n->type->link; t != T; t = t->down) {
975 * hand craft *(&nn + o) = l
990 nod2.type = typ(TIND, t);
996 nod3.type = nod2.type;
1001 nod4.type = nod2.type;
1002 nod4.vconst = t->offset;
1015 if(n->addable < INDEXED)
1016 sugen(n->right, n->left, w);
1019 sugen(n->right, nodrat, w);
1020 warn(n, "non-interruptable temporary");
1021 sugen(nodrat, n->left, w);
1022 sugen(nodrat, nn, w);
1027 sugen(n, nodrat, w);
1030 if(nn->op != OIND) {
1031 nn = new1(OADDR, nn, Z);
1032 nn->type = types[TIND];
1036 n = new(OFUNC, n->left, new(OLIST, nn, n->right));
1037 n->type = types[TVOID];
1038 n->left->type = types[TVOID];
1045 sugen(n->right->left, nn, w);
1049 sugen(n->right->right, nn, w);
1055 sugen(n->right, nn, w);
1063 if(n->complex >= FNX && nn->complex >= FNX) {
1065 nn->type = types[TLONG];
1066 regialloc(&nod1, nn, Z);
1068 regsalloc(&nod2, &nod1);
1071 gopcode(OAS, &nod1, Z, &nod2);
1074 nod2.type = typ(TIND, t);
1087 /* TO DO: use AMOV/VLONG when possible */
1088 if(n->complex > nn->complex) {
1090 n->type = types[TLONG];
1091 reglcgen(&nod1, n, Z);
1095 nn->type = types[TLONG];
1096 reglcgen(&nod2, nn, Z);
1100 nn->type = types[TLONG];
1101 reglcgen(&nod2, nn, Z);
1105 n->type = types[TLONG];
1106 reglcgen(&nod1, n, Z);
1112 layout(&nod1, &nod2, w, 0, Z);
1117 * minimize space for unrolling loop
1118 * 3,4,5 times. (6 or more is never minimum)
1119 * if small structure, try 2 also.
1132 regalloc(&nod3, ®node, Z);
1133 layout(&nod1, &nod2, w%c, w/c, &nod3);
1136 layout(&nod1, &nod2, c, 0, Z);
1138 gopcode(OSUB, nodconst(1L), Z, &nod3);
1139 nod1.op = OREGISTER;
1141 nod1.type = types[TIND];
1142 gopcode(OADD, nodconst(c*SZ_LONG), Z, &nod1);
1144 nod2.op = OREGISTER;
1146 nod2.type = types[TIND];
1147 gopcode(OADD, nodconst(c*SZ_LONG), Z, &nod2);
1150 gopcode(OGT, nodconst(0), &nod3, Z);
1160 layout(Node *f, Node *t, int c, int cv, Node *cn)
1165 layout(f, t, 2, 0, Z);
1169 regalloc(&t1, ®node, Z);
1170 regalloc(&t2, ®node, Z);
1172 gopcode(OAS, f, Z, &t1);
1173 f->xoffset += SZ_LONG;
1176 gopcode(OAS, nodconst(cv), Z, cn);
1178 gopcode(OAS, f, Z, &t2);
1179 f->xoffset += SZ_LONG;
1182 gopcode(OAS, &t1, Z, t);
1183 t->xoffset += SZ_LONG;
1186 gopcode(OAS, f, Z, &t1);
1187 f->xoffset += SZ_LONG;
1190 gopcode(OAS, &t2, Z, t);
1191 t->xoffset += SZ_LONG;
1194 gopcode(OAS, &t1, Z, t);
1195 t->xoffset += SZ_LONG;
1202 * if a constant and vlong, doesn't fit as 32-bit signed immediate
1207 return n->op == OCONST && !sconst(n);
1211 * casting up to t2 covers an intermediate cast to t1
1214 castup(Type *t1, Type *t2)
1218 if(!nilcast(t1, t2))
1220 /* known to be small to large */
1225 return ft == TLONG || ft == TINT || ft == TSHORT || ft == TCHAR;
1228 return ft == TULONG || ft == TUINT || ft == TUSHORT || ft == TUCHAR;
1230 return ft == TLONG || ft == TINT || ft == TSHORT;
1232 return ft == TULONG || ft == TUINT || ft == TUSHORT;