1 #include "gc.h"
2
3 /* ,x/^(print|prtree)\(/i/\/\/ */
4 int castup(Type*, Type*);
5 void checkmask(Node*, Node*);
6
7 void
cgen(Node * n,Node * nn)8 cgen(Node *n, Node *nn)
9 {
10 Node *l, *r, *t;
11 Prog *p1;
12 Node nod, nod1, nod2, nod3, nod4;
13 int o, hardleft;
14 long v, curs;
15 vlong c;
16
17 if(debug['g']) {
18 prtree(nn, "cgen lhs");
19 prtree(n, "cgen");
20 }
21 if(n == Z || n->type == T)
22 return;
23 if(typesu[n->type->etype]) {
24 sugen(n, nn, n->type->width);
25 return;
26 }
27 l = n->left;
28 r = n->right;
29 o = n->op;
30 if(n->addable >= INDEXED) {
31 if(nn == Z) {
32 switch(o) {
33 default:
34 nullwarn(Z, Z);
35 break;
36 case OINDEX:
37 nullwarn(l, r);
38 break;
39 }
40 return;
41 }
42 gmove(n, nn);
43 return;
44 }
45 curs = cursafe;
46
47 if(l->complex >= FNX)
48 if(r != Z && r->complex >= FNX)
49 switch(o) {
50 default:
51 if(cond(o) && typesu[l->type->etype])
52 break;
53
54 regret(&nod, r);
55 cgen(r, &nod);
56
57 regsalloc(&nod1, r);
58 gmove(&nod, &nod1);
59
60 regfree(&nod);
61 nod = *n;
62 nod.right = &nod1;
63
64 cgen(&nod, nn);
65 return;
66
67 case OFUNC:
68 case OCOMMA:
69 case OANDAND:
70 case OOROR:
71 case OCOND:
72 case ODOT:
73 break;
74 }
75
76 hardleft = l->addable < INDEXED || l->complex >= FNX;
77 switch(o) {
78 default:
79 diag(n, "unknown op in cgen: %O", o);
80 break;
81
82 case ONEG:
83 case OCOM:
84 if(nn == Z) {
85 nullwarn(l, Z);
86 break;
87 }
88 regalloc(&nod, l, nn);
89 cgen(l, &nod);
90 gopcode(o, n->type, Z, &nod);
91 gmove(&nod, nn);
92 regfree(&nod);
93 break;
94
95 case OAS:
96 if(l->op == OBIT)
97 goto bitas;
98 if(!hardleft) {
99 if(nn != Z || r->addable < INDEXED || hardconst(r)) {
100 if(r->complex >= FNX && nn == Z)
101 regret(&nod, r);
102 else
103 regalloc(&nod, r, nn);
104 cgen(r, &nod);
105 gmove(&nod, l);
106 if(nn != Z)
107 gmove(&nod, nn);
108 regfree(&nod);
109 } else
110 gmove(r, l);
111 break;
112 }
113 if(l->complex >= r->complex) {
114 if(l->op == OINDEX && immconst(r)) {
115 gmove(r, l);
116 break;
117 }
118 reglcgen(&nod1, l, Z);
119 if(r->addable >= INDEXED && !hardconst(r)) {
120 gmove(r, &nod1);
121 if(nn != Z)
122 gmove(r, nn);
123 regfree(&nod1);
124 break;
125 }
126 regalloc(&nod, r, nn);
127 cgen(r, &nod);
128 } else {
129 regalloc(&nod, r, nn);
130 cgen(r, &nod);
131 reglcgen(&nod1, l, Z);
132 }
133 gmove(&nod, &nod1);
134 regfree(&nod);
135 regfree(&nod1);
136 break;
137
138 bitas:
139 n = l->left;
140 regalloc(&nod, r, nn);
141 if(l->complex >= r->complex) {
142 reglcgen(&nod1, n, Z);
143 cgen(r, &nod);
144 } else {
145 cgen(r, &nod);
146 reglcgen(&nod1, n, Z);
147 }
148 regalloc(&nod2, n, Z);
149 gmove(&nod1, &nod2);
150 bitstore(l, &nod, &nod1, &nod2, nn);
151 break;
152
153 case OBIT:
154 if(nn == Z) {
155 nullwarn(l, Z);
156 break;
157 }
158 bitload(n, &nod, Z, Z, nn);
159 gmove(&nod, nn);
160 regfree(&nod);
161 break;
162
163 case OLSHR:
164 case OASHL:
165 case OASHR:
166 if(nn == Z) {
167 nullwarn(l, r);
168 break;
169 }
170 if(r->op == OCONST) {
171 if(r->vconst == 0) {
172 cgen(l, nn);
173 break;
174 }
175 regalloc(&nod, l, nn);
176 cgen(l, &nod);
177 if(o == OASHL && r->vconst == 1)
178 gopcode(OADD, n->type, &nod, &nod);
179 else
180 gopcode(o, n->type, r, &nod);
181 gmove(&nod, nn);
182 regfree(&nod);
183 break;
184 }
185
186 /*
187 * get nod to be D_CX
188 */
189 if(nodreg(&nod, nn, D_CX)) {
190 regsalloc(&nod1, n);
191 gmove(&nod, &nod1);
192 cgen(n, &nod); /* probably a bug */
193 gmove(&nod, nn);
194 gmove(&nod1, &nod);
195 break;
196 }
197 reg[D_CX]++;
198 if(nn->op == OREGISTER && nn->reg == D_CX)
199 regalloc(&nod1, l, Z);
200 else
201 regalloc(&nod1, l, nn);
202 if(r->complex >= l->complex) {
203 cgen(r, &nod);
204 cgen(l, &nod1);
205 } else {
206 cgen(l, &nod1);
207 cgen(r, &nod);
208 }
209 gopcode(o, n->type, &nod, &nod1);
210 gmove(&nod1, nn);
211 regfree(&nod);
212 regfree(&nod1);
213 break;
214
215 case OADD:
216 case OSUB:
217 case OOR:
218 case OXOR:
219 case OAND:
220 if(nn == Z) {
221 nullwarn(l, r);
222 break;
223 }
224 if(typefd[n->type->etype])
225 goto fop;
226 if(r->op == OCONST) {
227 if(r->vconst == 0 && o != OAND) {
228 cgen(l, nn);
229 break;
230 }
231 }
232 if(n->op == OADD && l->op == OASHL && l->right->op == OCONST
233 && (r->op != OCONST || r->vconst < -128 || r->vconst > 127)) {
234 c = l->right->vconst;
235 if(c > 0 && c <= 3) {
236 if(l->left->complex >= r->complex) {
237 regalloc(&nod, l->left, nn);
238 cgen(l->left, &nod);
239 if(r->addable < INDEXED) {
240 regalloc(&nod1, r, Z);
241 cgen(r, &nod1);
242 genmuladd(&nod, &nod, 1 << c, &nod1);
243 regfree(&nod1);
244 }
245 else
246 genmuladd(&nod, &nod, 1 << c, r);
247 }
248 else {
249 regalloc(&nod, r, nn);
250 cgen(r, &nod);
251 regalloc(&nod1, l->left, Z);
252 cgen(l->left, &nod1);
253 genmuladd(&nod, &nod1, 1 << c, &nod);
254 regfree(&nod1);
255 }
256 gmove(&nod, nn);
257 regfree(&nod);
258 break;
259 }
260 }
261 if(n->op == OAND)
262 checkmask(n, r);
263 if(r->addable >= INDEXED && !hardconst(r)) {
264 regalloc(&nod, l, nn);
265 cgen(l, &nod);
266 gopcode(o, n->type, r, &nod);
267 gmove(&nod, nn);
268 regfree(&nod);
269 break;
270 }
271 if(l->complex >= r->complex) {
272 regalloc(&nod, l, nn);
273 cgen(l, &nod);
274 regalloc(&nod1, r, Z);
275 cgen(r, &nod1);
276 gopcode(o, n->type, &nod1, &nod);
277 } else {
278 regalloc(&nod1, r, nn);
279 cgen(r, &nod1);
280 regalloc(&nod, l, Z);
281 cgen(l, &nod);
282 gopcode(o, n->type, &nod1, &nod);
283 }
284 gmove(&nod, nn);
285 regfree(&nod);
286 regfree(&nod1);
287 break;
288
289 case OLMOD:
290 case OMOD:
291 case OLMUL:
292 case OLDIV:
293 case OMUL:
294 case ODIV:
295 if(nn == Z) {
296 nullwarn(l, r);
297 break;
298 }
299 if(typefd[n->type->etype])
300 goto fop;
301 if(r->op == OCONST && typechl[n->type->etype]) { /* TO DO */
302 SET(v);
303 switch(o) {
304 case ODIV:
305 case OMOD:
306 c = r->vconst;
307 if(c < 0)
308 c = -c;
309 v = log2(c);
310 if(v < 0)
311 break;
312 /* fall thru */
313 case OMUL:
314 case OLMUL:
315 regalloc(&nod, l, nn);
316 cgen(l, &nod);
317 switch(o) {
318 case OMUL:
319 case OLMUL:
320 mulgen(n->type, r, &nod);
321 break;
322 case ODIV:
323 sdiv2(r->vconst, v, l, &nod);
324 break;
325 case OMOD:
326 smod2(r->vconst, v, l, &nod);
327 break;
328 }
329 gmove(&nod, nn);
330 regfree(&nod);
331 goto done;
332 case OLDIV:
333 c = r->vconst;
334 if((c & 0x80000000) == 0)
335 break;
336 regalloc(&nod1, l, Z);
337 cgen(l, &nod1);
338 regalloc(&nod, l, nn);
339 zeroregm(&nod);
340 gins(ACMPL, &nod1, nodconst(c));
341 gins(ASBBL, nodconst(-1), &nod);
342 regfree(&nod1);
343 gmove(&nod, nn);
344 regfree(&nod);
345 goto done;
346 }
347 }
348
349 if(o == OMUL) {
350 if(l->addable >= INDEXED) {
351 t = l;
352 l = r;
353 r = t;
354 }
355 /* should favour AX */
356 regalloc(&nod, l, nn);
357 cgen(l, &nod);
358 if(r->addable < INDEXED || hardconst(r)) {
359 regalloc(&nod1, r, Z);
360 cgen(r, &nod1);
361 gopcode(OMUL, n->type, &nod1, &nod);
362 regfree(&nod1);
363 }else
364 gopcode(OMUL, n->type, r, &nod); /* addressible */
365 gmove(&nod, nn);
366 regfree(&nod);
367 break;
368 }
369
370 /*
371 * get nod to be D_AX
372 * get nod1 to be D_DX
373 */
374 if(nodreg(&nod, nn, D_AX)) {
375 regsalloc(&nod2, n);
376 gmove(&nod, &nod2);
377 v = reg[D_AX];
378 reg[D_AX] = 0;
379
380 if(isreg(l, D_AX)) {
381 nod3 = *n;
382 nod3.left = &nod2;
383 cgen(&nod3, nn);
384 } else
385 if(isreg(r, D_AX)) {
386 nod3 = *n;
387 nod3.right = &nod2;
388 cgen(&nod3, nn);
389 } else
390 cgen(n, nn);
391
392 gmove(&nod2, &nod);
393 reg[D_AX] = v;
394 break;
395 }
396 if(nodreg(&nod1, nn, D_DX)) {
397 regsalloc(&nod2, n);
398 gmove(&nod1, &nod2);
399 v = reg[D_DX];
400 reg[D_DX] = 0;
401
402 if(isreg(l, D_DX)) {
403 nod3 = *n;
404 nod3.left = &nod2;
405 cgen(&nod3, nn);
406 } else
407 if(isreg(r, D_DX)) {
408 nod3 = *n;
409 nod3.right = &nod2;
410 cgen(&nod3, nn);
411 } else
412 cgen(n, nn);
413
414 gmove(&nod2, &nod1);
415 reg[D_DX] = v;
416 break;
417 }
418 reg[D_AX]++;
419
420 if(r->op == OCONST && (o == ODIV || o == OLDIV) && immconst(r) && typechl[r->type->etype]) {
421 reg[D_DX]++;
422 if(l->addable < INDEXED) {
423 regalloc(&nod2, l, Z);
424 cgen(l, &nod2);
425 l = &nod2;
426 }
427 if(o == ODIV)
428 sdivgen(l, r, &nod, &nod1);
429 else
430 udivgen(l, r, &nod, &nod1);
431 gmove(&nod1, nn);
432 if(l == &nod2)
433 regfree(l);
434 goto freeaxdx;
435 }
436
437 if(l->complex >= r->complex) {
438 cgen(l, &nod);
439 reg[D_DX]++;
440 if(o == ODIV || o == OMOD)
441 gins(typechl[l->type->etype]? ACDQ: ACQO, Z, Z);
442 if(o == OLDIV || o == OLMOD)
443 zeroregm(&nod1);
444 if(r->addable < INDEXED || r->op == OCONST) {
445 regalloc(&nod3, r, Z);
446 cgen(r, &nod3);
447 gopcode(o, n->type, &nod3, Z);
448 regfree(&nod3);
449 } else
450 gopcode(o, n->type, r, Z);
451 } else {
452 regsalloc(&nod3, r);
453 cgen(r, &nod3);
454 cgen(l, &nod);
455 reg[D_DX]++;
456 if(o == ODIV || o == OMOD)
457 gins(typechl[l->type->etype]? ACDQ: ACQO, Z, Z);
458 if(o == OLDIV || o == OLMOD)
459 zeroregm(&nod1);
460 gopcode(o, n->type, &nod3, Z);
461 }
462 if(o == OMOD || o == OLMOD)
463 gmove(&nod1, nn);
464 else
465 gmove(&nod, nn);
466 freeaxdx:
467 regfree(&nod);
468 regfree(&nod1);
469 break;
470
471 case OASLSHR:
472 case OASASHL:
473 case OASASHR:
474 if(r->op == OCONST)
475 goto asand;
476 if(l->op == OBIT)
477 goto asbitop;
478 if(typefd[n->type->etype])
479 goto asand; /* can this happen? */
480
481 /*
482 * get nod to be D_CX
483 */
484 if(nodreg(&nod, nn, D_CX)) {
485 regsalloc(&nod1, n);
486 gmove(&nod, &nod1);
487 cgen(n, &nod);
488 if(nn != Z)
489 gmove(&nod, nn);
490 gmove(&nod1, &nod);
491 break;
492 }
493 reg[D_CX]++;
494
495 if(r->complex >= l->complex) {
496 cgen(r, &nod);
497 if(hardleft)
498 reglcgen(&nod1, l, Z);
499 else
500 nod1 = *l;
501 } else {
502 if(hardleft)
503 reglcgen(&nod1, l, Z);
504 else
505 nod1 = *l;
506 cgen(r, &nod);
507 }
508
509 gopcode(o, l->type, &nod, &nod1);
510 regfree(&nod);
511 if(nn != Z)
512 gmove(&nod1, nn);
513 if(hardleft)
514 regfree(&nod1);
515 break;
516
517 case OASAND:
518 case OASADD:
519 case OASSUB:
520 case OASXOR:
521 case OASOR:
522 asand:
523 if(l->op == OBIT)
524 goto asbitop;
525 if(typefd[l->type->etype] || typefd[r->type->etype])
526 goto asfop;
527 if(o == OASAND)
528 checkmask(n, r);
529 if(l->complex >= r->complex) {
530 if(hardleft)
531 reglcgen(&nod, l, Z);
532 else
533 nod = *l;
534 if(!immconst(r)) {
535 regalloc(&nod1, r, nn);
536 cgen(r, &nod1);
537 gopcode(o, l->type, &nod1, &nod);
538 regfree(&nod1);
539 } else
540 gopcode(o, l->type, r, &nod);
541 } else {
542 regalloc(&nod1, r, nn);
543 cgen(r, &nod1);
544 if(hardleft)
545 reglcgen(&nod, l, Z);
546 else
547 nod = *l;
548 gopcode(o, l->type, &nod1, &nod);
549 regfree(&nod1);
550 }
551 if(nn != Z)
552 gmove(&nod, nn);
553 if(hardleft)
554 regfree(&nod);
555 break;
556
557 asfop:
558 if(l->complex >= r->complex) {
559 if(hardleft)
560 reglcgen(&nod, l, Z);
561 else
562 nod = *l;
563 if(r->addable < INDEXED){
564 regalloc(&nod1, r, nn);
565 cgen(r, &nod1);
566 }else
567 nod1 = *r;
568 regalloc(&nod2, r, Z);
569 gmove(&nod, &nod2);
570 gopcode(o, r->type, &nod1, &nod2);
571 gmove(&nod2, &nod);
572 regfree(&nod2);
573 if(r->addable < INDEXED)
574 regfree(&nod1);
575 } else {
576 regalloc(&nod1, r, nn);
577 cgen(r, &nod1);
578 if(hardleft)
579 reglcgen(&nod, l, Z);
580 else
581 nod = *l;
582 if(o != OASMUL && o != OASADD || !typefd[l->type->etype]) {
583 regalloc(&nod2, r, Z);
584 gmove(&nod, &nod2);
585 gopcode(o, r->type, &nod1, &nod2);
586 regfree(&nod1);
587 gmove(&nod2, &nod);
588 regfree(&nod2);
589 } else {
590 gopcode(o, r->type, &nod, &nod1);
591 gmove(&nod1, &nod);
592 regfree(&nod1);
593 }
594 }
595 if(nn != Z)
596 gmove(&nod, nn);
597 if(hardleft)
598 regfree(&nod);
599 break;
600
601 case OASLMUL:
602 case OASLDIV:
603 case OASLMOD:
604 case OASMUL:
605 case OASDIV:
606 case OASMOD:
607 if(l->op == OBIT)
608 goto asbitop;
609 if(typefd[n->type->etype] || typefd[r->type->etype])
610 goto asfop;
611 if(r->op == OCONST && typechl[n->type->etype]) {
612 SET(v);
613 switch(o) {
614 case OASDIV:
615 case OASMOD:
616 c = r->vconst;
617 if(c < 0)
618 c = -c;
619 v = log2(c);
620 if(v < 0)
621 break;
622 /* fall thru */
623 case OASMUL:
624 case OASLMUL:
625 if(hardleft)
626 reglcgen(&nod2, l, Z);
627 else
628 nod2 = *l;
629 regalloc(&nod, l, nn);
630 cgen(&nod2, &nod);
631 switch(o) {
632 case OASMUL:
633 case OASLMUL:
634 mulgen(n->type, r, &nod);
635 break;
636 case OASDIV:
637 sdiv2(r->vconst, v, l, &nod);
638 break;
639 case OASMOD:
640 smod2(r->vconst, v, l, &nod);
641 break;
642 }
643 havev:
644 gmove(&nod, &nod2);
645 if(nn != Z)
646 gmove(&nod, nn);
647 if(hardleft)
648 regfree(&nod2);
649 regfree(&nod);
650 goto done;
651 case OASLDIV:
652 c = r->vconst;
653 if((c & 0x80000000) == 0)
654 break;
655 if(hardleft)
656 reglcgen(&nod2, l, Z);
657 else
658 nod2 = *l;
659 regalloc(&nod1, l, nn);
660 cgen(&nod2, &nod1);
661 regalloc(&nod, l, nn);
662 zeroregm(&nod);
663 gins(ACMPL, &nod1, nodconst(c));
664 gins(ASBBL, nodconst(-1), &nod);
665 regfree(&nod1);
666 goto havev;
667 }
668 }
669
670 if(o == OASMUL) {
671 /* should favour AX */
672 regalloc(&nod, l, nn);
673 if(r->complex >= FNX) {
674 regalloc(&nod1, r, Z);
675 cgen(r, &nod1);
676 r = &nod1;
677 }
678 if(hardleft)
679 reglcgen(&nod2, l, Z);
680 else
681 nod2 = *l;
682 cgen(&nod2, &nod);
683 if(r->addable < INDEXED || hardconst(r)) {
684 if(r->complex < FNX) {
685 regalloc(&nod1, r, Z);
686 cgen(r, &nod1);
687 }
688 gopcode(OASMUL, n->type, &nod1, &nod);
689 regfree(&nod1);
690 }
691 else
692 gopcode(OASMUL, n->type, r, &nod);
693 if(r == &nod1)
694 regfree(r);
695 gmove(&nod, &nod2);
696 if(nn != Z)
697 gmove(&nod, nn);
698 regfree(&nod);
699 if(hardleft)
700 regfree(&nod2);
701 break;
702 }
703
704 /*
705 * get nod to be D_AX
706 * get nod1 to be D_DX
707 */
708 if(nodreg(&nod, nn, D_AX)) {
709 regsalloc(&nod2, n);
710 gmove(&nod, &nod2);
711 v = reg[D_AX];
712 reg[D_AX] = 0;
713
714 if(isreg(l, D_AX)) {
715 nod3 = *n;
716 nod3.left = &nod2;
717 cgen(&nod3, nn);
718 } else
719 if(isreg(r, D_AX)) {
720 nod3 = *n;
721 nod3.right = &nod2;
722 cgen(&nod3, nn);
723 } else
724 cgen(n, nn);
725
726 gmove(&nod2, &nod);
727 reg[D_AX] = v;
728 break;
729 }
730 if(nodreg(&nod1, nn, D_DX)) {
731 regsalloc(&nod2, n);
732 gmove(&nod1, &nod2);
733 v = reg[D_DX];
734 reg[D_DX] = 0;
735
736 if(isreg(l, D_DX)) {
737 nod3 = *n;
738 nod3.left = &nod2;
739 cgen(&nod3, nn);
740 } else
741 if(isreg(r, D_DX)) {
742 nod3 = *n;
743 nod3.right = &nod2;
744 cgen(&nod3, nn);
745 } else
746 cgen(n, nn);
747
748 gmove(&nod2, &nod1);
749 reg[D_DX] = v;
750 break;
751 }
752 reg[D_AX]++;
753 reg[D_DX]++;
754
755 if(l->complex >= r->complex) {
756 if(hardleft)
757 reglcgen(&nod2, l, Z);
758 else
759 nod2 = *l;
760 cgen(&nod2, &nod);
761 if(r->op == OCONST && typechl[r->type->etype]) {
762 switch(o) {
763 case OASDIV:
764 sdivgen(&nod2, r, &nod, &nod1);
765 goto divdone;
766 case OASLDIV:
767 udivgen(&nod2, r, &nod, &nod1);
768 divdone:
769 gmove(&nod1, &nod2);
770 if(nn != Z)
771 gmove(&nod1, nn);
772 goto freelxaxdx;
773 }
774 }
775 if(o == OASDIV || o == OASMOD)
776 gins(typechl[l->type->etype]? ACDQ: ACQO, Z, Z);
777 if(o == OASLDIV || o == OASLMOD)
778 zeroregm(&nod1);
779 if(r->addable < INDEXED || r->op == OCONST ||
780 !typeil[r->type->etype]) {
781 regalloc(&nod3, r, Z);
782 cgen(r, &nod3);
783 gopcode(o, l->type, &nod3, Z);
784 regfree(&nod3);
785 } else
786 gopcode(o, n->type, r, Z);
787 } else {
788 regalloc(&nod3, r, Z);
789 cgen(r, &nod3);
790 if(hardleft)
791 reglcgen(&nod2, l, Z);
792 else
793 nod2 = *l;
794 cgen(&nod2, &nod);
795 if(o == OASDIV || o == OASMOD)
796 gins(typechl[l->type->etype]? ACDQ: ACQO, Z, Z);
797 if(o == OASLDIV || o == OASLMOD)
798 zeroregm(&nod1);
799 gopcode(o, l->type, &nod3, Z);
800 regfree(&nod3);
801 }
802 if(o == OASMOD || o == OASLMOD) {
803 gmove(&nod1, &nod2);
804 if(nn != Z)
805 gmove(&nod1, nn);
806 } else {
807 gmove(&nod, &nod2);
808 if(nn != Z)
809 gmove(&nod, nn);
810 }
811 freelxaxdx:
812 if(hardleft)
813 regfree(&nod2);
814 regfree(&nod);
815 regfree(&nod1);
816 break;
817
818 fop:
819 if(l->complex >= r->complex) {
820 regalloc(&nod, l, nn);
821 cgen(l, &nod);
822 if(r->addable < INDEXED) {
823 regalloc(&nod1, r, Z);
824 cgen(r, &nod1);
825 gopcode(o, n->type, &nod1, &nod);
826 regfree(&nod1);
827 } else
828 gopcode(o, n->type, r, &nod);
829 } else {
830 /* TO DO: could do better with r->addable >= INDEXED */
831 regalloc(&nod1, r, Z);
832 cgen(r, &nod1);
833 regalloc(&nod, l, nn);
834 cgen(l, &nod);
835 gopcode(o, n->type, &nod1, &nod);
836 regfree(&nod1);
837 }
838 gmove(&nod, nn);
839 regfree(&nod);
840 break;
841
842 asbitop:
843 regalloc(&nod4, n, nn);
844 if(l->complex >= r->complex) {
845 bitload(l, &nod, &nod1, &nod2, &nod4);
846 regalloc(&nod3, r, Z);
847 cgen(r, &nod3);
848 } else {
849 regalloc(&nod3, r, Z);
850 cgen(r, &nod3);
851 bitload(l, &nod, &nod1, &nod2, &nod4);
852 }
853 gmove(&nod, &nod4);
854
855 { /* TO DO: check floating point source */
856 Node onod;
857
858 /* incredible grot ... */
859 onod = nod3;
860 onod.op = o;
861 onod.complex = 2;
862 onod.addable = 0;
863 onod.type = tfield;
864 onod.left = &nod4;
865 onod.right = &nod3;
866 cgen(&onod, Z);
867 }
868 regfree(&nod3);
869 gmove(&nod4, &nod);
870 regfree(&nod4);
871 bitstore(l, &nod, &nod1, &nod2, nn);
872 break;
873
874 case OADDR:
875 if(nn == Z) {
876 nullwarn(l, Z);
877 break;
878 }
879 lcgen(l, nn);
880 break;
881
882 case OFUNC:
883 if(l->complex >= FNX) {
884 if(l->op != OIND)
885 diag(n, "bad function call");
886
887 regret(&nod, l->left);
888 cgen(l->left, &nod);
889 regsalloc(&nod1, l->left);
890 gmove(&nod, &nod1);
891 regfree(&nod);
892
893 nod = *n;
894 nod.left = &nod2;
895 nod2 = *l;
896 nod2.left = &nod1;
897 nod2.complex = 1;
898 cgen(&nod, nn);
899
900 return;
901 }
902 o = reg[REGARG];
903 gargs(r, &nod, &nod1);
904 if(l->addable < INDEXED) {
905 reglcgen(&nod, l, nn);
906 nod.op = OREGISTER;
907 gopcode(OFUNC, n->type, Z, &nod);
908 regfree(&nod);
909 } else
910 gopcode(OFUNC, n->type, Z, l);
911 if(REGARG)
912 if(o != reg[REGARG])
913 reg[REGARG]--;
914 if(nn != Z) {
915 regret(&nod, n);
916 gmove(&nod, nn);
917 regfree(&nod);
918 }
919 break;
920
921 case OIND:
922 if(nn == Z) {
923 nullwarn(l, Z);
924 break;
925 }
926 regialloc(&nod, n, nn);
927 r = l;
928 while(r->op == OADD)
929 r = r->right;
930 if(sconst(r)) {
931 v = r->vconst;
932 r->vconst = 0;
933 cgen(l, &nod);
934 nod.xoffset += v;
935 r->vconst = v;
936 } else
937 cgen(l, &nod);
938 regind(&nod, n);
939 gmove(&nod, nn);
940 regfree(&nod);
941 break;
942
943 case OEQ:
944 case ONE:
945 case OLE:
946 case OLT:
947 case OGE:
948 case OGT:
949 case OLO:
950 case OLS:
951 case OHI:
952 case OHS:
953 if(nn == Z) {
954 nullwarn(l, r);
955 break;
956 }
957 boolgen(n, 1, nn);
958 break;
959
960 case OANDAND:
961 case OOROR:
962 boolgen(n, 1, nn);
963 if(nn == Z)
964 patch(p, pc);
965 break;
966
967 case ONOT:
968 if(nn == Z) {
969 nullwarn(l, Z);
970 break;
971 }
972 boolgen(n, 1, nn);
973 break;
974
975 case OCOMMA:
976 cgen(l, Z);
977 cgen(r, nn);
978 break;
979
980 case OCAST:
981 if(nn == Z) {
982 nullwarn(l, Z);
983 break;
984 }
985 /*
986 * convert from types l->n->nn
987 */
988 if(nocast(l->type, n->type) && nocast(n->type, nn->type)) {
989 /* both null, gen l->nn */
990 cgen(l, nn);
991 break;
992 }
993 if(ewidth[n->type->etype] < ewidth[l->type->etype]){
994 if(l->type->etype == TIND && typechlp[n->type->etype])
995 warn(n, "conversion of pointer to shorter integer");
996 }else if(0){
997 if(nocast(n->type, nn->type) || castup(n->type, nn->type)){
998 if(typefd[l->type->etype] != typefd[nn->type->etype])
999 regalloc(&nod, l, nn);
1000 else
1001 regalloc(&nod, nn, nn);
1002 cgen(l, &nod);
1003 gmove(&nod, nn);
1004 regfree(&nod);
1005 break;
1006 }
1007 }
1008 regalloc(&nod, l, nn);
1009 cgen(l, &nod);
1010 regalloc(&nod1, n, &nod);
1011 gmove(&nod, &nod1);
1012 gmove(&nod1, nn);
1013 regfree(&nod1);
1014 regfree(&nod);
1015 break;
1016
1017 case ODOT:
1018 sugen(l, nodrat, l->type->width);
1019 if(nn == Z)
1020 break;
1021 warn(n, "non-interruptable temporary");
1022 nod = *nodrat;
1023 if(!r || r->op != OCONST) {
1024 diag(n, "DOT and no offset");
1025 break;
1026 }
1027 nod.xoffset += (long)r->vconst;
1028 nod.type = n->type;
1029 cgen(&nod, nn);
1030 break;
1031
1032 case OCOND:
1033 bcgen(l, 1);
1034 p1 = p;
1035 cgen(r->left, nn);
1036 gbranch(OGOTO);
1037 patch(p1, pc);
1038 p1 = p;
1039 cgen(r->right, nn);
1040 patch(p1, pc);
1041 break;
1042
1043 case OPOSTINC:
1044 case OPOSTDEC:
1045 v = 1;
1046 if(l->type->etype == TIND)
1047 v = l->type->link->width;
1048 if(o == OPOSTDEC)
1049 v = -v;
1050 if(l->op == OBIT)
1051 goto bitinc;
1052 if(nn == Z)
1053 goto pre;
1054
1055 if(hardleft)
1056 reglcgen(&nod, l, Z);
1057 else
1058 nod = *l;
1059
1060 gmove(&nod, nn);
1061 if(typefd[n->type->etype]) {
1062 regalloc(&nod1, l, Z);
1063 gmove(&nod, &nod1);
1064 if(v < 0)
1065 gopcode(OSUB, n->type, nodfconst(-v), &nod1);
1066 else
1067 gopcode(OADD, n->type, nodfconst(v), &nod1);
1068 gmove(&nod1, &nod);
1069 regfree(&nod1);
1070 } else
1071 gopcode(OADD, n->type, nodconst(v), &nod);
1072 if(hardleft)
1073 regfree(&nod);
1074 break;
1075
1076 case OPREINC:
1077 case OPREDEC:
1078 v = 1;
1079 if(l->type->etype == TIND)
1080 v = l->type->link->width;
1081 if(o == OPREDEC)
1082 v = -v;
1083 if(l->op == OBIT)
1084 goto bitinc;
1085
1086 pre:
1087 if(hardleft)
1088 reglcgen(&nod, l, Z);
1089 else
1090 nod = *l;
1091 if(typefd[n->type->etype]) {
1092 regalloc(&nod1, l, Z);
1093 gmove(&nod, &nod1);
1094 if(v < 0)
1095 gopcode(OSUB, n->type, nodfconst(-v), &nod1);
1096 else
1097 gopcode(OADD, n->type, nodfconst(v), &nod1);
1098 gmove(&nod1, &nod);
1099 regfree(&nod1);
1100 } else
1101 gopcode(OADD, n->type, nodconst(v), &nod);
1102 if(nn != Z)
1103 gmove(&nod, nn);
1104 if(hardleft)
1105 regfree(&nod);
1106 break;
1107
1108 bitinc:
1109 if(nn != Z && (o == OPOSTINC || o == OPOSTDEC)) {
1110 bitload(l, &nod, &nod1, &nod2, Z);
1111 gmove(&nod, nn);
1112 gopcode(OADD, tfield, nodconst(v), &nod);
1113 bitstore(l, &nod, &nod1, &nod2, Z);
1114 break;
1115 }
1116 bitload(l, &nod, &nod1, &nod2, nn);
1117 gopcode(OADD, tfield, nodconst(v), &nod);
1118 bitstore(l, &nod, &nod1, &nod2, nn);
1119 break;
1120 }
1121 done:
1122 cursafe = curs;
1123 }
1124
1125 void
reglcgen(Node * t,Node * n,Node * nn)1126 reglcgen(Node *t, Node *n, Node *nn)
1127 {
1128 Node *r;
1129 long v;
1130
1131 regialloc(t, n, nn);
1132 if(n->op == OIND) {
1133 r = n->left;
1134 while(r->op == OADD)
1135 r = r->right;
1136 if(sconst(r)) {
1137 v = r->vconst;
1138 r->vconst = 0;
1139 lcgen(n, t);
1140 t->xoffset += v;
1141 r->vconst = v;
1142 regind(t, n);
1143 return;
1144 }
1145 }
1146 lcgen(n, t);
1147 regind(t, n);
1148 }
1149
1150 void
lcgen(Node * n,Node * nn)1151 lcgen(Node *n, Node *nn)
1152 {
1153 Prog *p1;
1154 Node nod;
1155
1156 if(debug['g']) {
1157 prtree(nn, "lcgen lhs");
1158 prtree(n, "lcgen");
1159 }
1160 if(n == Z || n->type == T)
1161 return;
1162 if(nn == Z) {
1163 nn = &nod;
1164 regalloc(&nod, n, Z);
1165 }
1166 switch(n->op) {
1167 default:
1168 if(n->addable < INDEXED) {
1169 diag(n, "unknown op in lcgen: %O", n->op);
1170 break;
1171 }
1172 gopcode(OADDR, n->type, n, nn);
1173 break;
1174
1175 case OCOMMA:
1176 cgen(n->left, n->left);
1177 lcgen(n->right, nn);
1178 break;
1179
1180 case OIND:
1181 cgen(n->left, nn);
1182 break;
1183
1184 case OCOND:
1185 bcgen(n->left, 1);
1186 p1 = p;
1187 lcgen(n->right->left, nn);
1188 gbranch(OGOTO);
1189 patch(p1, pc);
1190 p1 = p;
1191 lcgen(n->right->right, nn);
1192 patch(p1, pc);
1193 break;
1194 }
1195 }
1196
1197 void
bcgen(Node * n,int true)1198 bcgen(Node *n, int true)
1199 {
1200
1201 if(n->type == T)
1202 gbranch(OGOTO);
1203 else
1204 boolgen(n, true, Z);
1205 }
1206
1207 void
boolgen(Node * n,int true,Node * nn)1208 boolgen(Node *n, int true, Node *nn)
1209 {
1210 int o;
1211 Prog *p1, *p2;
1212 Node *l, *r, nod, nod1;
1213 long curs;
1214
1215 if(debug['g']) {
1216 prtree(nn, "boolgen lhs");
1217 prtree(n, "boolgen");
1218 }
1219 curs = cursafe;
1220 l = n->left;
1221 r = n->right;
1222 switch(n->op) {
1223
1224 default:
1225 o = ONE;
1226 if(true)
1227 o = OEQ;
1228 /* bad, 13 is address of external that becomes constant */
1229 if(n->addable >= INDEXED && n->addable != 13) {
1230 if(typefd[n->type->etype]) {
1231 regalloc(&nod1, n, Z);
1232 gmove(nodfconst(0.0), &nod1); /* TO DO: FREGZERO */
1233 gopcode(o, n->type, n, &nod1);
1234 regfree(&nod1);
1235 } else
1236 gopcode(o, n->type, n, nodconst(0));
1237 goto com;
1238 }
1239 regalloc(&nod, n, nn);
1240 cgen(n, &nod);
1241 if(typefd[n->type->etype]) {
1242 regalloc(&nod1, n, Z);
1243 gmove(nodfconst(0.0), &nod1); /* TO DO: FREGZERO */
1244 gopcode(o, n->type, &nod, &nod1);
1245 regfree(&nod1);
1246 } else
1247 gopcode(o, n->type, &nod, nodconst(0));
1248 regfree(&nod);
1249 goto com;
1250
1251 case OCONST:
1252 o = vconst(n);
1253 if(!true)
1254 o = !o;
1255 gbranch(OGOTO);
1256 if(o) {
1257 p1 = p;
1258 gbranch(OGOTO);
1259 patch(p1, pc);
1260 }
1261 goto com;
1262
1263 case OCOMMA:
1264 cgen(l, Z);
1265 boolgen(r, true, nn);
1266 break;
1267
1268 case ONOT:
1269 boolgen(l, !true, nn);
1270 break;
1271
1272 case OCOND:
1273 bcgen(l, 1);
1274 p1 = p;
1275 bcgen(r->left, true);
1276 p2 = p;
1277 gbranch(OGOTO);
1278 patch(p1, pc);
1279 p1 = p;
1280 bcgen(r->right, !true);
1281 patch(p2, pc);
1282 p2 = p;
1283 gbranch(OGOTO);
1284 patch(p1, pc);
1285 patch(p2, pc);
1286 goto com;
1287
1288 case OANDAND:
1289 if(!true)
1290 goto caseor;
1291
1292 caseand:
1293 bcgen(l, true);
1294 p1 = p;
1295 bcgen(r, !true);
1296 p2 = p;
1297 patch(p1, pc);
1298 gbranch(OGOTO);
1299 patch(p2, pc);
1300 goto com;
1301
1302 case OOROR:
1303 if(!true)
1304 goto caseand;
1305
1306 caseor:
1307 bcgen(l, !true);
1308 p1 = p;
1309 bcgen(r, !true);
1310 p2 = p;
1311 gbranch(OGOTO);
1312 patch(p1, pc);
1313 patch(p2, pc);
1314 goto com;
1315
1316 case OEQ:
1317 case ONE:
1318 case OLE:
1319 case OLT:
1320 case OGE:
1321 case OGT:
1322 case OHI:
1323 case OHS:
1324 case OLO:
1325 case OLS:
1326 o = n->op;
1327 if(true)
1328 o = comrel[relindex(o)];
1329 if(l->complex >= FNX && r->complex >= FNX) {
1330 regret(&nod, r);
1331 cgen(r, &nod);
1332 regsalloc(&nod1, r);
1333 gmove(&nod, &nod1);
1334 regfree(&nod);
1335 nod = *n;
1336 nod.right = &nod1;
1337 boolgen(&nod, true, nn);
1338 break;
1339 }
1340 if(immconst(l)) {
1341 o = invrel[relindex(o)];
1342 /* bad, 13 is address of external that becomes constant */
1343 if(r->addable < INDEXED || r->addable == 13) {
1344 regalloc(&nod, r, nn);
1345 cgen(r, &nod);
1346 gopcode(o, l->type, &nod, l);
1347 regfree(&nod);
1348 } else
1349 gopcode(o, l->type, r, l);
1350 goto com;
1351 }
1352 if(typefd[l->type->etype])
1353 o = invrel[relindex(logrel[relindex(o)])];
1354 if(l->complex >= r->complex) {
1355 regalloc(&nod, l, nn);
1356 cgen(l, &nod);
1357 if(r->addable < INDEXED || hardconst(r) || typefd[l->type->etype]) {
1358 regalloc(&nod1, r, Z);
1359 cgen(r, &nod1);
1360 gopcode(o, l->type, &nod, &nod1);
1361 regfree(&nod1);
1362 } else
1363 gopcode(o, l->type, &nod, r);
1364 regfree(&nod);
1365 goto com;
1366 }
1367 regalloc(&nod, r, nn);
1368 cgen(r, &nod);
1369 if(l->addable < INDEXED || l->addable == 13 || hardconst(l)) {
1370 regalloc(&nod1, l, Z);
1371 cgen(l, &nod1);
1372 if(typechl[l->type->etype] && ewidth[l->type->etype] <= ewidth[TINT])
1373 gopcode(o, types[TINT], &nod1, &nod);
1374 else
1375 gopcode(o, l->type, &nod1, &nod);
1376 regfree(&nod1);
1377 } else
1378 gopcode(o, l->type, l, &nod);
1379 regfree(&nod);
1380
1381 com:
1382 if(nn != Z) {
1383 p1 = p;
1384 gmove(nodconst(1L), nn);
1385 gbranch(OGOTO);
1386 p2 = p;
1387 patch(p1, pc);
1388 gmove(nodconst(0L), nn);
1389 patch(p2, pc);
1390 }
1391 break;
1392 }
1393 cursafe = curs;
1394 }
1395
1396 void
sugen(Node * n,Node * nn,long w)1397 sugen(Node *n, Node *nn, long w)
1398 {
1399 Prog *p1;
1400 Node nod0, nod1, nod2, nod3, nod4, *l, *r;
1401 Type *t;
1402 int c, mt, mo;
1403 vlong o0, o1;
1404
1405 if(n == Z || n->type == T)
1406 return;
1407 if(debug['g']) {
1408 prtree(nn, "sugen lhs");
1409 prtree(n, "sugen");
1410 }
1411 if(nn == nodrat)
1412 if(w > nrathole)
1413 nrathole = w;
1414 switch(n->op) {
1415 case OIND:
1416 if(nn == Z) {
1417 nullwarn(n->left, Z);
1418 break;
1419 }
1420
1421 default:
1422 goto copy;
1423
1424 case OCONST:
1425 goto copy;
1426
1427 case ODOT:
1428 l = n->left;
1429 sugen(l, nodrat, l->type->width);
1430 if(nn == Z)
1431 break;
1432 warn(n, "non-interruptable temporary");
1433 nod1 = *nodrat;
1434 r = n->right;
1435 if(!r || r->op != OCONST) {
1436 diag(n, "DOT and no offset");
1437 break;
1438 }
1439 nod1.xoffset += (long)r->vconst;
1440 nod1.type = n->type;
1441 sugen(&nod1, nn, w);
1442 break;
1443
1444 case OSTRUCT:
1445 /*
1446 * rewrite so lhs has no fn call
1447 */
1448 if(nn != Z && side(nn)) {
1449 nod1 = *n;
1450 nod1.type = typ(TIND, n->type);
1451 regret(&nod2, &nod1);
1452 lcgen(nn, &nod2);
1453 regsalloc(&nod0, &nod1);
1454 cgen(&nod2, &nod0);
1455 regfree(&nod2);
1456
1457 nod1 = *n;
1458 nod1.op = OIND;
1459 nod1.left = &nod0;
1460 nod1.right = Z;
1461 nod1.complex = 1;
1462
1463 sugen(n, &nod1, w);
1464 return;
1465 }
1466
1467 r = n->left;
1468 for(t = n->type->link; t != T; t = t->down) {
1469 l = r;
1470 if(r->op == OLIST) {
1471 l = r->left;
1472 r = r->right;
1473 }
1474 if(nn == Z) {
1475 cgen(l, nn);
1476 continue;
1477 }
1478 /*
1479 * hand craft *(&nn + o) = l
1480 */
1481 nod0 = znode;
1482 nod0.op = OAS;
1483 nod0.type = t;
1484 nod0.left = &nod1;
1485 nod0.right = nil;
1486
1487 nod1 = znode;
1488 nod1.op = OIND;
1489 nod1.type = t;
1490 nod1.left = &nod2;
1491
1492 nod2 = znode;
1493 nod2.op = OADD;
1494 nod2.type = typ(TIND, t);
1495 nod2.left = &nod3;
1496 nod2.right = &nod4;
1497
1498 nod3 = znode;
1499 nod3.op = OADDR;
1500 nod3.type = nod2.type;
1501 nod3.left = nn;
1502
1503 nod4 = znode;
1504 nod4.op = OCONST;
1505 nod4.type = nod2.type;
1506 nod4.vconst = t->offset;
1507
1508 ccom(&nod0);
1509 acom(&nod0);
1510 xcom(&nod0);
1511 nod0.addable = 0;
1512 nod0.right = l;
1513
1514 /* prtree(&nod0, "hand craft"); /* */
1515 cgen(&nod0, Z);
1516 }
1517 break;
1518
1519 case OAS:
1520 if(nn == Z) {
1521 if(n->addable < INDEXED)
1522 sugen(n->right, n->left, w);
1523 break;
1524 }
1525
1526 sugen(n->right, nodrat, w);
1527 warn(n, "non-interruptable temporary");
1528 sugen(nodrat, n->left, w);
1529 sugen(nodrat, nn, w);
1530 break;
1531
1532 case OFUNC:
1533 if(nn == Z) {
1534 sugen(n, nodrat, w);
1535 break;
1536 }
1537 if(nn->op != OIND) {
1538 nn = new1(OADDR, nn, Z);
1539 nn->type = types[TIND];
1540 nn->addable = 0;
1541 } else
1542 nn = nn->left;
1543 n = new(OFUNC, n->left, new(OLIST, nn, n->right));
1544 n->type = types[TVOID];
1545 n->left->type = types[TVOID];
1546 cgen(n, Z);
1547 break;
1548
1549 case OCOND:
1550 bcgen(n->left, 1);
1551 p1 = p;
1552 sugen(n->right->left, nn, w);
1553 gbranch(OGOTO);
1554 patch(p1, pc);
1555 p1 = p;
1556 sugen(n->right->right, nn, w);
1557 patch(p1, pc);
1558 break;
1559
1560 case OCOMMA:
1561 cgen(n->left, Z);
1562 sugen(n->right, nn, w);
1563 break;
1564 }
1565 return;
1566
1567 copy:
1568 if(nn == Z) {
1569 switch(n->op) {
1570 case OASADD:
1571 case OASSUB:
1572 case OASAND:
1573 case OASOR:
1574 case OASXOR:
1575
1576 case OASMUL:
1577 case OASLMUL:
1578
1579
1580 case OASASHL:
1581 case OASASHR:
1582 case OASLSHR:
1583 break;
1584
1585 case OPOSTINC:
1586 case OPOSTDEC:
1587 case OPREINC:
1588 case OPREDEC:
1589 break;
1590
1591 default:
1592 return;
1593 }
1594 }
1595
1596 if(n->complex >= FNX && nn != nil && nn->complex >= FNX) {
1597 t = nn->type;
1598 nn->type = types[TLONG];
1599 regialloc(&nod1, nn, Z);
1600 lcgen(nn, &nod1);
1601 regsalloc(&nod2, nn);
1602 nn->type = t;
1603
1604 gins(AMOVQ, &nod1, &nod2);
1605 regfree(&nod1);
1606
1607 nod2.type = typ(TIND, t);
1608
1609 nod1 = nod2;
1610 nod1.op = OIND;
1611 nod1.left = &nod2;
1612 nod1.right = Z;
1613 nod1.complex = 1;
1614 nod1.type = t;
1615
1616 sugen(n, &nod1, w);
1617 return;
1618 }
1619
1620 if(w <= 32) {
1621 c = cursafe;
1622 if(n->left != Z && n->left->complex >= FNX
1623 && n->right != Z && n->right->complex >= FNX) {
1624 regsalloc(&nod1, n->right);
1625 cgen(n->right, &nod1);
1626 nod2 = *n;
1627 nod2.right = &nod1;
1628 cgen(&nod2, nn);
1629 cursafe = c;
1630 return;
1631 }
1632 if(w & 7) {
1633 mt = TLONG;
1634 mo = AMOVL;
1635 } else {
1636 mt = TVLONG;
1637 mo = AMOVQ;
1638 }
1639 if(n->complex > nn->complex) {
1640 t = n->type;
1641 n->type = types[mt];
1642 regalloc(&nod0, n, Z);
1643 if(!vaddr(n, 0)) {
1644 reglcgen(&nod1, n, Z);
1645 n->type = t;
1646 n = &nod1;
1647 }
1648 else
1649 n->type = t;
1650
1651 t = nn->type;
1652 nn->type = types[mt];
1653 if(!vaddr(nn, 0)) {
1654 reglcgen(&nod2, nn, Z);
1655 nn->type = t;
1656 nn = &nod2;
1657 }
1658 else
1659 nn->type = t;
1660 } else {
1661 t = nn->type;
1662 nn->type = types[mt];
1663 regalloc(&nod0, nn, Z);
1664 if(!vaddr(nn, 0)) {
1665 reglcgen(&nod2, nn, Z);
1666 nn->type = t;
1667 nn = &nod2;
1668 }
1669 else
1670 nn->type = t;
1671
1672 t = n->type;
1673 n->type = types[mt];
1674 if(!vaddr(n, 0)) {
1675 reglcgen(&nod1, n, Z);
1676 n->type = t;
1677 n = &nod1;
1678 }
1679 else
1680 n->type = t;
1681 }
1682 o0 = n->xoffset;
1683 o1 = nn->xoffset;
1684 w /= ewidth[mt];
1685 while(--w >= 0) {
1686 gins(mo, n, &nod0);
1687 gins(mo, &nod0, nn);
1688 n->xoffset += ewidth[mt];
1689 nn->xoffset += ewidth[mt];
1690 }
1691 n->xoffset = o0;
1692 nn->xoffset = o1;
1693 if(nn == &nod2)
1694 regfree(&nod2);
1695 if(n == &nod1)
1696 regfree(&nod1);
1697 regfree(&nod0);
1698 return;
1699 }
1700
1701 /* botch, need to save in .safe */
1702 c = 0;
1703 if(n->complex > nn->complex) {
1704 t = n->type;
1705 n->type = types[TIND];
1706 nodreg(&nod1, n, D_SI);
1707 if(reg[D_SI]) {
1708 gins(APUSHQ, &nod1, Z);
1709 c |= 1;
1710 reg[D_SI]++;
1711 }
1712 lcgen(n, &nod1);
1713 n->type = t;
1714
1715 t = nn->type;
1716 nn->type = types[TIND];
1717 nodreg(&nod2, nn, D_DI);
1718 if(reg[D_DI]) {
1719 warn(Z, "DI botch");
1720 gins(APUSHQ, &nod2, Z);
1721 c |= 2;
1722 reg[D_DI]++;
1723 }
1724 lcgen(nn, &nod2);
1725 nn->type = t;
1726 } else {
1727 t = nn->type;
1728 nn->type = types[TIND];
1729 nodreg(&nod2, nn, D_DI);
1730 if(reg[D_DI]) {
1731 warn(Z, "DI botch");
1732 gins(APUSHQ, &nod2, Z);
1733 c |= 2;
1734 reg[D_DI]++;
1735 }
1736 lcgen(nn, &nod2);
1737 nn->type = t;
1738
1739 t = n->type;
1740 n->type = types[TIND];
1741 nodreg(&nod1, n, D_SI);
1742 if(reg[D_SI]) {
1743 gins(APUSHQ, &nod1, Z);
1744 c |= 1;
1745 reg[D_SI]++;
1746 }
1747 lcgen(n, &nod1);
1748 n->type = t;
1749 }
1750 nodreg(&nod3, n, D_CX);
1751 if(reg[D_CX]) {
1752 gins(APUSHQ, &nod3, Z);
1753 c |= 4;
1754 reg[D_CX]++;
1755 }
1756 gins(AMOVL, nodconst(w/SZ_INT), &nod3);
1757 gins(ACLD, Z, Z);
1758 gins(AREP, Z, Z);
1759 gins(AMOVSL, Z, Z);
1760 if(c & 4) {
1761 gins(APOPQ, Z, &nod3);
1762 reg[D_CX]--;
1763 }
1764 if(c & 2) {
1765 gins(APOPQ, Z, &nod2);
1766 reg[nod2.reg]--;
1767 }
1768 if(c & 1) {
1769 gins(APOPQ, Z, &nod1);
1770 reg[nod1.reg]--;
1771 }
1772 }
1773
1774 /*
1775 * TO DO
1776 */
1777 void
layout(Node * f,Node * t,int c,int cv,Node * cn)1778 layout(Node *f, Node *t, int c, int cv, Node *cn)
1779 {
1780 Node t1, t2;
1781
1782 while(c > 3) {
1783 layout(f, t, 2, 0, Z);
1784 c -= 2;
1785 }
1786
1787 regalloc(&t1, &lregnode, Z);
1788 regalloc(&t2, &lregnode, Z);
1789 if(c > 0) {
1790 gmove(f, &t1);
1791 f->xoffset += SZ_INT;
1792 }
1793 if(cn != Z)
1794 gmove(nodconst(cv), cn);
1795 if(c > 1) {
1796 gmove(f, &t2);
1797 f->xoffset += SZ_INT;
1798 }
1799 if(c > 0) {
1800 gmove(&t1, t);
1801 t->xoffset += SZ_INT;
1802 }
1803 if(c > 2) {
1804 gmove(f, &t1);
1805 f->xoffset += SZ_INT;
1806 }
1807 if(c > 1) {
1808 gmove(&t2, t);
1809 t->xoffset += SZ_INT;
1810 }
1811 if(c > 2) {
1812 gmove(&t1, t);
1813 t->xoffset += SZ_INT;
1814 }
1815 regfree(&t1);
1816 regfree(&t2);
1817 }
1818
1819 /*
1820 * constant is not vlong or fits as 32-bit signed immediate
1821 */
1822 int
immconst(Node * n)1823 immconst(Node *n)
1824 {
1825 long v;
1826
1827 if(n->op != OCONST || !typechlpv[n->type->etype])
1828 return 0;
1829 if(typechl[n->type->etype])
1830 return 1;
1831 v = n->vconst;
1832 return n->vconst == (vlong)v;
1833 }
1834
1835 /*
1836 * if a constant and vlong, doesn't fit as 32-bit signed immediate
1837 */
1838 int
hardconst(Node * n)1839 hardconst(Node *n)
1840 {
1841 return n->op == OCONST && !immconst(n);
1842 }
1843
1844 /*
1845 * casting up to t2 covers an intermediate cast to t1
1846 */
1847 int
castup(Type * t1,Type * t2)1848 castup(Type *t1, Type *t2)
1849 {
1850 int ft;
1851
1852 if(!nilcast(t1, t2))
1853 return 0;
1854 /* known to be small to large */
1855 ft = t1->etype;
1856 switch(t2->etype){
1857 case TINT:
1858 case TLONG:
1859 return ft == TLONG || ft == TINT || ft == TSHORT || ft == TCHAR;
1860 case TUINT:
1861 case TULONG:
1862 return ft == TULONG || ft == TUINT || ft == TUSHORT || ft == TUCHAR;
1863 case TVLONG:
1864 return ft == TLONG || ft == TINT || ft == TSHORT;
1865 case TUVLONG:
1866 return ft == TULONG || ft == TUINT || ft == TUSHORT;
1867 }
1868 return 0;
1869 }
1870
1871 /*
1872 * vl &= ~ul or vl & ~ul
1873 * create a ul mask with top bits zero, which is usually wrong
1874 */
1875 void
checkmask(Node * n,Node * r)1876 checkmask(Node *n, Node *r)
1877 {
1878 Node *rl;
1879
1880 if((n->op == OAND || n->op == OASAND) &&
1881 r->op == OCAST &&
1882 (rl = r->left)->op == OCOM &&
1883 typesuv[n->type->etype] && typeu[rl->type->etype] && typechl[rl->type->etype])
1884 warn(n, "32-bit mask zero-extended to 64 bits");
1885 }
1886
1887 void
zeroregm(Node * n)1888 zeroregm(Node *n)
1889 {
1890 gins(AMOVL, nodconst(0), n);
1891 }
1892
1893 /* do we need to load the address of a vlong? */
1894 int
vaddr(Node * n,int a)1895 vaddr(Node *n, int a)
1896 {
1897 switch(n->op) {
1898 case ONAME:
1899 if(a)
1900 return 1;
1901 return !(n->class == CEXTERN || n->class == CGLOBL || n->class == CSTATIC);
1902
1903 case OCONST:
1904 case OREGISTER:
1905 case OINDREG:
1906 return 1;
1907 }
1908 return 0;
1909 }
1910
1911 long
hi64v(Node * n)1912 hi64v(Node *n)
1913 {
1914 if(align(0, types[TCHAR], Aarg1)) /* isbigendian */
1915 return (long)(n->vconst) & ~0L;
1916 else
1917 return (long)((uvlong)n->vconst>>32) & ~0L;
1918 }
1919
1920 long
lo64v(Node * n)1921 lo64v(Node *n)
1922 {
1923 if(align(0, types[TCHAR], Aarg1)) /* isbigendian */
1924 return (long)((uvlong)n->vconst>>32) & ~0L;
1925 else
1926 return (long)(n->vconst) & ~0L;
1927 }
1928
1929 Node *
hi64(Node * n)1930 hi64(Node *n)
1931 {
1932 return nodconst(hi64v(n));
1933 }
1934
1935 Node *
lo64(Node * n)1936 lo64(Node *n)
1937 {
1938 return nodconst(lo64v(n));
1939 }
1940
1941 int
cond(int op)1942 cond(int op)
1943 {
1944 switch(op) {
1945 case OANDAND:
1946 case OOROR:
1947 case ONOT:
1948 return 1;
1949
1950 case OEQ:
1951 case ONE:
1952 case OLE:
1953 case OLT:
1954 case OGE:
1955 case OGT:
1956 case OHI:
1957 case OHS:
1958 case OLO:
1959 case OLS:
1960 return 1;
1961 }
1962 return 0;
1963 }
1964