LEFT | RIGHT |
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 550 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
561 * allocate a register in res and generate | 561 * allocate a register in res and generate |
562 * res = &n | 562 * res = &n |
563 */ | 563 */ |
564 void | 564 void |
565 agenr(Node *n, Node *a, Node *res) | 565 agenr(Node *n, Node *a, Node *res) |
566 { | 566 { |
567 Node *nl, *nr; | 567 Node *nl, *nr; |
568 Node n1, n2, n3, n4, n5, tmp, tmp2, nlen; | 568 Node n1, n2, n3, n4, n5, tmp, tmp2, nlen; |
569 Prog *p1; | 569 Prog *p1; |
570 Type *t; | 570 Type *t; |
571 » uint32 w; | 571 » uint64 w; |
572 uint64 v; | 572 uint64 v; |
573 int freelen; | 573 int freelen; |
574 | 574 |
575 if(debug['g']) { | 575 if(debug['g']) { |
576 dump("\nagenr-n", n); | 576 dump("\nagenr-n", n); |
577 } | 577 } |
578 | 578 |
579 nl = n->left; | 579 nl = n->left; |
580 nr = n->right; | 580 nr = n->right; |
581 | 581 |
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
875 if(n->xoffset != 0) | 875 if(n->xoffset != 0) |
876 ginscon(optoas(OADD, types[tptr]), n->xoffset, res); | 876 ginscon(optoas(OADD, types[tptr]), n->xoffset, res); |
877 break; | 877 break; |
878 | 878 |
879 case OIND: | 879 case OIND: |
880 cgen(nl, res); | 880 cgen(nl, res); |
881 break; | 881 break; |
882 | 882 |
883 case ODOT: | 883 case ODOT: |
884 agen(nl, res); | 884 agen(nl, res); |
| 885 // explicit check for nil if struct is large enough |
| 886 // that we might derive too big a pointer. If the left node |
| 887 // was ODOT we have already done the nil check. |
| 888 if(nl->op != ODOT) |
| 889 if(nl->type->width >= unmappedzero) { |
| 890 regalloc(&n1, types[tptr], res); |
| 891 gmove(res, &n1); |
| 892 n1.op = OINDREG; |
| 893 n1.type = types[TUINT8]; |
| 894 n1.xoffset = 0; |
| 895 gins(ATESTB, nodintconst(0), &n1); |
| 896 regfree(&n1); |
| 897 } |
885 if(n->xoffset != 0) | 898 if(n->xoffset != 0) |
886 ginscon(optoas(OADD, types[tptr]), n->xoffset, res); | 899 ginscon(optoas(OADD, types[tptr]), n->xoffset, res); |
887 break; | 900 break; |
888 | 901 |
889 case ODOTPTR: | 902 case ODOTPTR: |
890 cgen(nl, res); | 903 cgen(nl, res); |
| 904 // explicit check for nil if struct is large enough |
| 905 // that we might derive too big a pointer. |
| 906 if(nl->type->type->width >= unmappedzero) { |
| 907 regalloc(&n1, types[tptr], res); |
| 908 gmove(res, &n1); |
| 909 n1.op = OINDREG; |
| 910 n1.type = types[TUINT8]; |
| 911 n1.xoffset = 0; |
| 912 gins(ATESTB, nodintconst(0), &n1); |
| 913 regfree(&n1); |
| 914 } |
891 if(n->xoffset != 0) { | 915 if(n->xoffset != 0) { |
892 // explicit check for nil if struct is large enough | |
893 // that we might derive too big a pointer. | |
894 if(nl->type->type->width >= unmappedzero) { | |
895 regalloc(&n1, types[tptr], res); | |
896 gmove(res, &n1); | |
897 n1.op = OINDREG; | |
898 n1.type = types[TUINT8]; | |
899 n1.xoffset = 0; | |
900 gins(ATESTB, nodintconst(0), &n1); | |
901 regfree(&n1); | |
902 } | |
903 ginscon(optoas(OADD, types[tptr]), n->xoffset, res); | 916 ginscon(optoas(OADD, types[tptr]), n->xoffset, res); |
904 } | 917 } |
905 break; | 918 break; |
906 } | 919 } |
907 | 920 |
908 ret: | 921 ret: |
909 ; | 922 ; |
910 } | 923 } |
911 | 924 |
912 /* | 925 /* |
(...skipping 30 matching lines...) Expand all Loading... |
943 return; | 956 return; |
944 | 957 |
945 case ODOT: | 958 case ODOT: |
946 igen(n->left, a, res); | 959 igen(n->left, a, res); |
947 a->xoffset += n->xoffset; | 960 a->xoffset += n->xoffset; |
948 a->type = n->type; | 961 a->type = n->type; |
949 return; | 962 return; |
950 | 963 |
951 case ODOTPTR: | 964 case ODOTPTR: |
952 cgenr(n->left, a, res); | 965 cgenr(n->left, a, res); |
953 » » if(n->xoffset != 0) { | 966 » » // explicit check for nil if struct is large enough |
954 » » » // explicit check for nil if struct is large enough | 967 » » // that we might derive too big a pointer. |
955 » » » // that we might derive too big a pointer. | 968 » » if(n->left->type->type->width >= unmappedzero) { |
956 » » » if(n->left->type->type->width >= unmappedzero) { | 969 » » » n1 = *a; |
957 » » » » n1 = *a; | 970 » » » n1.op = OINDREG; |
958 » » » » n1.op = OINDREG; | 971 » » » n1.type = types[TUINT8]; |
959 » » » » n1.type = types[TUINT8]; | 972 » » » n1.xoffset = 0; |
960 » » » » n1.xoffset = 0; | 973 » » » gins(ATESTB, nodintconst(0), &n1); |
961 » » » » gins(ATESTB, nodintconst(0), &n1); | |
962 » » » } | |
963 } | 974 } |
964 a->op = OINDREG; | 975 a->op = OINDREG; |
965 a->xoffset += n->xoffset; | 976 a->xoffset += n->xoffset; |
966 a->type = n->type; | 977 a->type = n->type; |
967 return; | 978 return; |
968 | 979 |
969 case OCALLFUNC: | 980 case OCALLFUNC: |
970 case OCALLMETH: | 981 case OCALLMETH: |
971 case OCALLINTER: | 982 case OCALLINTER: |
972 switch(n->op) { | 983 switch(n->op) { |
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1269 | 1280 |
1270 ret: | 1281 ret: |
1271 ; | 1282 ; |
1272 } | 1283 } |
1273 | 1284 |
1274 /* | 1285 /* |
1275 * n is on stack, either local variable | 1286 * n is on stack, either local variable |
1276 * or return value from function call. | 1287 * or return value from function call. |
1277 * return n's offset from SP. | 1288 * return n's offset from SP. |
1278 */ | 1289 */ |
1279 int32 | 1290 int64 |
1280 stkof(Node *n) | 1291 stkof(Node *n) |
1281 { | 1292 { |
1282 Type *t; | 1293 Type *t; |
1283 Iter flist; | 1294 Iter flist; |
1284 » int32 off; | 1295 » int64 off; |
1285 | 1296 |
1286 switch(n->op) { | 1297 switch(n->op) { |
1287 case OINDREG: | 1298 case OINDREG: |
1288 return n->xoffset; | 1299 return n->xoffset; |
1289 | 1300 |
1290 case ODOT: | 1301 case ODOT: |
1291 t = n->left->type; | 1302 t = n->left->type; |
1292 if(isptr[t->etype]) | 1303 if(isptr[t->etype]) |
1293 break; | 1304 break; |
1294 off = stkof(n->left); | 1305 off = stkof(n->left); |
(...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1664 regfree(&nodl); | 1675 regfree(&nodl); |
1665 return 0; | 1676 return 0; |
1666 | 1677 |
1667 yes: | 1678 yes: |
1668 if(freer) | 1679 if(freer) |
1669 regfree(&nodr); | 1680 regfree(&nodr); |
1670 if(freel) | 1681 if(freel) |
1671 regfree(&nodl); | 1682 regfree(&nodl); |
1672 return 1; | 1683 return 1; |
1673 } | 1684 } |
LEFT | RIGHT |