Left: | ||
Right: |
OLD | NEW |
---|---|
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 #include <u.h> | 5 #include <u.h> |
6 #include <libc.h> | 6 #include <libc.h> |
7 #include "gg.h" | 7 #include "gg.h" |
8 | 8 |
9 /* | 9 /* |
10 * generate: | 10 * generate: |
(...skipping 587 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
598 w = n->type->width; | 598 w = n->type->width; |
599 // Generate the non-addressable child first. | 599 // Generate the non-addressable child first. |
600 if(nr->addable) | 600 if(nr->addable) |
601 goto irad; | 601 goto irad; |
602 if(nl->addable) { | 602 if(nl->addable) { |
603 if(!isconst(nr, CTINT)) { | 603 if(!isconst(nr, CTINT)) { |
604 regalloc(&n1, nr->type, N); | 604 regalloc(&n1, nr->type, N); |
605 cgen(nr, &n1); | 605 cgen(nr, &n1); |
606 } | 606 } |
607 if(!isconst(nl, CTSTR)) { | 607 if(!isconst(nl, CTSTR)) { |
608 » » » » regalloc(&n3, types[tptr], res); | 608 » » » » if(isfixedarray(nl->type)) { |
609 » » » » if(isfixedarray(nl->type)) | 609 » » » » » regalloc(&n3, types[tptr], res); |
610 agen(nl, &n3); | 610 agen(nl, &n3); |
611 » » » » else { | 611 » » » » } else { |
612 igen(nl, &nlen, res); | 612 igen(nl, &nlen, res); |
613 nlen.type = types[tptr]; | 613 nlen.type = types[tptr]; |
614 nlen.xoffset += Array_array; | 614 nlen.xoffset += Array_array; |
615 regalloc(&n3, types[tptr], res); | |
615 gmove(&nlen, &n3); | 616 gmove(&nlen, &n3); |
616 nlen.type = types[simtype[TUINT]]; | 617 nlen.type = types[simtype[TUINT]]; |
617 nlen.xoffset += Array_nel-Array_array; | 618 nlen.xoffset += Array_nel-Array_array; |
618 } | 619 } |
619 } | 620 } |
620 goto index; | 621 goto index; |
621 } | 622 } |
622 tempname(&tmp, nr->type); | 623 tempname(&tmp, nr->type); |
623 cgen(nr, &tmp); | 624 cgen(nr, &tmp); |
624 nr = &tmp; | 625 nr = &tmp; |
625 irad: | 626 irad: |
626 if(!isconst(nl, CTSTR)) { | 627 if(!isconst(nl, CTSTR)) { |
627 » » » regalloc(&n3, types[tptr], res); | 628 » » » if(isfixedarray(nl->type)) { |
628 » » » if(isfixedarray(nl->type)) | 629 » » » » regalloc(&n3, types[tptr], res); |
629 agen(nl, &n3); | 630 agen(nl, &n3); |
630 » » » else { | 631 » » » } else { |
631 if(!nl->addable) { | 632 if(!nl->addable) { |
632 // igen will need an addressable node. | 633 // igen will need an addressable node. |
633 tempname(&tmp2, nl->type); | 634 tempname(&tmp2, nl->type); |
634 cgen(nl, &tmp2); | 635 cgen(nl, &tmp2); |
635 nl = &tmp2; | 636 nl = &tmp2; |
636 } | 637 } |
637 igen(nl, &nlen, res); | 638 igen(nl, &nlen, res); |
638 nlen.type = types[tptr]; | 639 nlen.type = types[tptr]; |
639 nlen.xoffset += Array_array; | 640 nlen.xoffset += Array_array; |
641 regalloc(&n3, types[tptr], res); | |
640 gmove(&nlen, &n3); | 642 gmove(&nlen, &n3); |
641 nlen.type = types[simtype[TUINT]]; | 643 nlen.type = types[simtype[TUINT]]; |
642 nlen.xoffset += Array_nel-Array_array; | 644 nlen.xoffset += Array_nel-Array_array; |
643 } | 645 } |
644 } | 646 } |
645 if(!isconst(nr, CTINT)) { | 647 if(!isconst(nr, CTINT)) { |
646 regalloc(&n1, nr->type, N); | 648 regalloc(&n1, nr->type, N); |
647 cgen(nr, &n1); | 649 cgen(nr, &n1); |
648 } | 650 } |
649 goto index; | 651 goto index; |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
807 * res = newreg | 809 * res = newreg |
808 * | 810 * |
809 * on exit, a has been changed to be *newreg. | 811 * on exit, a has been changed to be *newreg. |
810 * caller must regfree(a). | 812 * caller must regfree(a). |
811 */ | 813 */ |
812 void | 814 void |
813 igen(Node *n, Node *a, Node *res) | 815 igen(Node *n, Node *a, Node *res) |
814 { | 816 { |
815 Type *fp; | 817 Type *fp; |
816 Iter flist; | 818 Iter flist; |
817 » Node n1, n2; | 819 » Node n1; |
818 | 820 |
821 if(debug['g']) { | |
822 dump("\nigen-n", n); | |
823 } | |
819 switch(n->op) { | 824 switch(n->op) { |
820 case ONAME: | 825 case ONAME: |
821 if((n->class&PHEAP) || n->class == PPARAMREF) | 826 if((n->class&PHEAP) || n->class == PPARAMREF) |
822 break; | 827 break; |
823 *a = *n; | 828 *a = *n; |
824 return; | 829 return; |
825 | 830 |
826 case OINDREG: | 831 case OINDREG: |
827 // Increase the refcount of the register so that igen's caller | 832 // Increase the refcount of the register so that igen's caller |
828 // has to call regfree. | 833 // has to call regfree. |
829 if(n->val.u.reg != D_SP) | 834 if(n->val.u.reg != D_SP) |
830 reg[n->val.u.reg]++; | 835 reg[n->val.u.reg]++; |
831 *a = *n; | 836 *a = *n; |
832 return; | 837 return; |
833 | 838 |
834 case ODOT: | 839 case ODOT: |
835 igen(n->left, a, res); | 840 igen(n->left, a, res); |
836 a->xoffset += n->xoffset; | 841 a->xoffset += n->xoffset; |
837 a->type = n->type; | 842 a->type = n->type; |
838 return; | 843 return; |
839 | 844 |
840 case ODOTPTR: | 845 case ODOTPTR: |
841 » » regalloc(a, types[tptr], res); | 846 » » if(n->left->addable |
842 » » cgen(n->left, a); | 847 » » » || n->left->op == OCALLFUNC |
848 » » » || n->left->op == OCALLMETH | |
849 » » » || n->left->op == OCALLINTER) { | |
850 » » » // igen-able nodes. | |
851 » » » igen(n->left, &n1, res); | |
852 » » » regalloc(a, types[tptr], &n1); | |
853 » » » gmove(&n1, a); | |
854 » » » regfree(&n1); | |
855 » » } else { | |
856 » » » regalloc(a, types[tptr], &n1); | |
nigeltao
2012/10/12 07:07:36
Was the final argument supposed to change from res
remyoudompheng
2012/10/12 21:26:07
Done.
| |
857 » » » cgen(n->left, a); | |
858 » » } | |
843 if(n->xoffset != 0) { | 859 if(n->xoffset != 0) { |
844 // explicit check for nil if struct is large enough | 860 // explicit check for nil if struct is large enough |
845 // that we might derive too big a pointer. | 861 // that we might derive too big a pointer. |
846 if(n->left->type->type->width >= unmappedzero) { | 862 if(n->left->type->type->width >= unmappedzero) { |
847 n1 = *a; | 863 n1 = *a; |
848 n1.op = OINDREG; | 864 n1.op = OINDREG; |
849 n1.type = types[TUINT8]; | 865 n1.type = types[TUINT8]; |
850 n1.xoffset = 0; | 866 n1.xoffset = 0; |
851 gins(ATESTB, nodintconst(0), &n1); | 867 gins(ATESTB, nodintconst(0), &n1); |
852 } | 868 } |
(...skipping 18 matching lines...) Expand all Loading... | |
871 break; | 887 break; |
872 } | 888 } |
873 fp = structfirst(&flist, getoutarg(n->left->type)); | 889 fp = structfirst(&flist, getoutarg(n->left->type)); |
874 memset(a, 0, sizeof *a); | 890 memset(a, 0, sizeof *a); |
875 a->op = OINDREG; | 891 a->op = OINDREG; |
876 a->val.u.reg = D_SP; | 892 a->val.u.reg = D_SP; |
877 a->addable = 1; | 893 a->addable = 1; |
878 a->xoffset = fp->width; | 894 a->xoffset = fp->width; |
879 a->type = n->type; | 895 a->type = n->type; |
880 return; | 896 return; |
881 » | 897 |
882 case OINDEX: | 898 case OINDEX: |
883 // Index of fixed-size array by constant can | 899 // Index of fixed-size array by constant can |
884 // put the offset in the addressing. | 900 // put the offset in the addressing. |
885 // Could do the same for slice except that we need | 901 // Could do the same for slice except that we need |
886 // to use the real index for the bounds checking. | 902 // to use the real index for the bounds checking. |
887 if(isfixedarray(n->left->type) || | 903 if(isfixedarray(n->left->type) || |
888 (isptr[n->left->type->etype] && isfixedarray(n->left->left->t ype))) | 904 (isptr[n->left->type->etype] && isfixedarray(n->left->left->t ype))) |
889 if(isconst(n->right, CTINT)) { | 905 if(isconst(n->right, CTINT)) { |
890 » » » nodconst(&n1, types[TINT64], 0); | 906 » » » // Compute &a. |
891 » » » n2 = *n; | 907 » » » if(!isptr[n->left->type->etype]) |
892 » » » n2.right = &n1; | 908 » » » » igen(n->left, a, res); |
909 » » » else { | |
910 » » » » igen(n->left, &n1, res); | |
911 » » » » regalloc(a, types[tptr], res); | |
912 » » » » gmove(&n1, a); | |
913 » » » » regfree(&n1); | |
914 » » » » a->op = OINDREG; | |
915 » » » } | |
893 | 916 |
894 » » » regalloc(a, types[tptr], res); | 917 » » » // Compute &a[i] as &a + i*width. |
895 » » » agen(&n2, a); | |
896 » » » a->op = OINDREG; | |
897 » » » a->xoffset = mpgetfix(n->right->val.u.xval)*n->type->wid th; | |
898 a->type = n->type; | 918 a->type = n->type; |
919 a->xoffset += mpgetfix(n->right->val.u.xval)*n->type->wi dth; | |
899 return; | 920 return; |
900 } | 921 } |
901 ························ | |
902 } | 922 } |
903 | 923 |
904 regalloc(a, types[tptr], res); | 924 regalloc(a, types[tptr], res); |
905 agen(n, a); | 925 agen(n, a); |
906 a->op = OINDREG; | 926 a->op = OINDREG; |
907 a->type = n->type; | 927 a->type = n->type; |
908 } | 928 } |
909 | 929 |
910 /* | 930 /* |
911 * generate: | 931 * generate: |
(...skipping 575 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1487 regfree(&nodl); | 1507 regfree(&nodl); |
1488 return 0; | 1508 return 0; |
1489 | 1509 |
1490 yes: | 1510 yes: |
1491 if(freer) | 1511 if(freer) |
1492 regfree(&nodr); | 1512 regfree(&nodr); |
1493 if(freel) | 1513 if(freel) |
1494 regfree(&nodl); | 1514 regfree(&nodl); |
1495 return 1; | 1515 return 1; |
1496 } | 1516 } |
OLD | NEW |