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 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
306 regfree(&n1); | 306 regfree(&n1); |
307 break; | 307 break; |
308 | 308 |
309 case OITAB: | 309 case OITAB: |
310 // itable of interface value | 310 // itable of interface value |
311 igen(nl, &n1, res); | 311 igen(nl, &n1, res); |
312 n1.op = OREGISTER; // was OINDREG | 312 n1.op = OREGISTER; // was OINDREG |
313 regalloc(&n2, n->type, &n1); | 313 regalloc(&n2, n->type, &n1); |
314 n1.op = OINDREG; | 314 n1.op = OINDREG; |
315 n1.type = n->type; | 315 n1.type = n->type; |
316 » » n1.xoffset = 0; | 316 » » n1.xoffset += 0; |
317 gmove(&n1, &n2); | 317 gmove(&n1, &n2); |
318 gmove(&n2, res); | 318 gmove(&n2, res); |
319 regfree(&n1); | 319 regfree(&n1); |
320 regfree(&n2); | 320 regfree(&n2); |
321 break; | 321 break; |
322 | 322 |
323 case OLEN: | 323 case OLEN: |
324 if(istype(nl->type, TMAP) || istype(nl->type, TCHAN)) { | 324 if(istype(nl->type, TMAP) || istype(nl->type, TCHAN)) { |
325 // map has len in the first 32-bit word. | 325 // map has len in the first 32-bit word. |
326 // a zero pointer means zero length | 326 // a zero pointer means zero length |
(...skipping 15 matching lines...) Expand all Loading... |
342 regfree(&n1); | 342 regfree(&n1); |
343 break; | 343 break; |
344 } | 344 } |
345 if(istype(nl->type, TSTRING) || isslice(nl->type)) { | 345 if(istype(nl->type, TSTRING) || isslice(nl->type)) { |
346 // both slice and string have len one pointer into the s
truct. | 346 // both slice and string have len one pointer into the s
truct. |
347 igen(nl, &n1, res); | 347 igen(nl, &n1, res); |
348 n1.op = OREGISTER; // was OINDREG | 348 n1.op = OREGISTER; // was OINDREG |
349 regalloc(&n2, types[TUINT32], &n1); | 349 regalloc(&n2, types[TUINT32], &n1); |
350 n1.op = OINDREG; | 350 n1.op = OINDREG; |
351 n1.type = types[TUINT32]; | 351 n1.type = types[TUINT32]; |
352 » » » n1.xoffset = Array_nel; | 352 » » » n1.xoffset += Array_nel; |
353 gmove(&n1, &n2); | 353 gmove(&n1, &n2); |
354 gmove(&n2, res); | 354 gmove(&n2, res); |
355 regfree(&n1); | 355 regfree(&n1); |
356 regfree(&n2); | 356 regfree(&n2); |
357 break; | 357 break; |
358 } | 358 } |
359 fatal("cgen: OLEN: unknown type %lT", nl->type); | 359 fatal("cgen: OLEN: unknown type %lT", nl->type); |
360 break; | 360 break; |
361 | 361 |
362 case OCAP: | 362 case OCAP: |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
398 case OADDR: | 398 case OADDR: |
399 agen(nl, res); | 399 agen(nl, res); |
400 break; | 400 break; |
401 | 401 |
402 case OCALLMETH: | 402 case OCALLMETH: |
403 case OCALLFUNC: | 403 case OCALLFUNC: |
404 // Release res so that it is available for cgen_call. | 404 // Release res so that it is available for cgen_call. |
405 // Pick it up again after the call. | 405 // Pick it up again after the call. |
406 rg = -1; | 406 rg = -1; |
407 if(n->ullman >= UINF) { | 407 if(n->ullman >= UINF) { |
408 » » » if(res->op == OREGISTER || res->op == OINDREG) { | 408 » » » if(res != N && (res->op == OREGISTER || res->op == OINDR
EG)) { |
409 rg = res->val.u.reg; | 409 rg = res->val.u.reg; |
410 reg[rg]--; | 410 reg[rg]--; |
411 } | 411 } |
412 } | 412 } |
413 if(n->op == OCALLMETH) | 413 if(n->op == OCALLMETH) |
414 cgen_callmeth(n, 0); | 414 cgen_callmeth(n, 0); |
415 else | 415 else |
416 cgen_call(n, 0); | 416 cgen_call(n, 0); |
417 if(rg >= 0) | 417 if(rg >= 0) |
418 reg[rg]++; | 418 reg[rg]++; |
(...skipping 464 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
883 * generate: | 883 * generate: |
884 * newreg = &n; | 884 * newreg = &n; |
885 * res = newreg | 885 * res = newreg |
886 * | 886 * |
887 * on exit, a has been changed to be *newreg. | 887 * on exit, a has been changed to be *newreg. |
888 * caller must regfree(a). | 888 * caller must regfree(a). |
889 */ | 889 */ |
890 void | 890 void |
891 igen(Node *n, Node *a, Node *res) | 891 igen(Node *n, Node *a, Node *res) |
892 { | 892 { |
| 893 Node n1; |
| 894 Prog *p1; |
| 895 int r; |
| 896 |
| 897 if(debug['g']) { |
| 898 dump("\nigen-n", n); |
| 899 } |
| 900 switch(n->op) { |
| 901 case ODOT: |
| 902 igen(n->left, a, res); |
| 903 a->xoffset += n->xoffset; |
| 904 a->type = n->type; |
| 905 return; |
| 906 |
| 907 case ODOTPTR: |
| 908 if(n->left->addable |
| 909 || n->left->op == OCALLFUNC |
| 910 || n->left->op == OCALLMETH |
| 911 || n->left->op == OCALLINTER) { |
| 912 // igen-able nodes. |
| 913 igen(n->left, &n1, res); |
| 914 regalloc(a, types[tptr], &n1); |
| 915 gmove(&n1, a); |
| 916 regfree(&n1); |
| 917 } else { |
| 918 regalloc(a, types[tptr], res); |
| 919 cgen(n->left, a); |
| 920 } |
| 921 if(n->xoffset != 0) { |
| 922 // explicit check for nil if struct is large enough |
| 923 // that we might derive too big a pointer. |
| 924 if(n->left->type->type->width >= unmappedzero) { |
| 925 regalloc(&n1, types[tptr], N); |
| 926 gmove(a, &n1); |
| 927 p1 = gins(AMOVW, &n1, &n1); |
| 928 p1->from.type = D_OREG; |
| 929 p1->from.offset = 0; |
| 930 regfree(&n1); |
| 931 } |
| 932 } |
| 933 a->op = OINDREG; |
| 934 a->xoffset = n->xoffset; |
| 935 a->type = n->type; |
| 936 return; |
| 937 |
| 938 case OCALLMETH: |
| 939 case OCALLFUNC: |
| 940 case OCALLINTER: |
| 941 // Release res so that it is available for cgen_call. |
| 942 // Pick it up again after the call. |
| 943 r = -1; |
| 944 if(n->ullman >= UINF) { |
| 945 if(res != N && (res->op == OREGISTER || res->op == OINDR
EG)) { |
| 946 r = res->val.u.reg; |
| 947 reg[r]--; |
| 948 } |
| 949 } |
| 950 switch(n->op) { |
| 951 case OCALLMETH: |
| 952 cgen_callmeth(n, 0); |
| 953 break; |
| 954 case OCALLFUNC: |
| 955 cgen_call(n, 0); |
| 956 break; |
| 957 case OCALLINTER: |
| 958 cgen_callinter(n, N, 0); |
| 959 break; |
| 960 } |
| 961 if(r >= 0) |
| 962 reg[r]++; |
| 963 regalloc(a, types[tptr], res); |
| 964 cgen_aret(n, a); |
| 965 a->op = OINDREG; |
| 966 a->type = n->type; |
| 967 return; |
| 968 } |
| 969 |
893 regalloc(a, types[tptr], res); | 970 regalloc(a, types[tptr], res); |
894 agen(n, a); | 971 agen(n, a); |
895 a->op = OINDREG; | 972 a->op = OINDREG; |
896 a->type = n->type; | 973 a->type = n->type; |
897 } | 974 } |
898 | 975 |
899 /* | 976 /* |
900 * generate: | 977 * generate: |
901 * newreg = &n; | 978 * newreg = &n; |
902 * | 979 * |
903 * caller must regfree(a). | 980 * caller must regfree(a). |
904 */ | 981 */ |
905 void | 982 void |
906 agenr(Node *n, Node *a, Node *res) | 983 agenr(Node *n, Node *a, Node *res) |
907 { | 984 { |
908 » regalloc(a, types[tptr], res); | 985 » Node n1; |
909 » agen(n, a); | 986 |
| 987 » igen(n, &n1, res); |
| 988 » regalloc(a, types[tptr], N); |
| 989 » agen(&n1, a); |
| 990 » regfree(&n1); |
910 } | 991 } |
911 | 992 |
912 void | 993 void |
913 gencmp0(Node *n, Type *t, int o, int likely, Prog *to) | 994 gencmp0(Node *n, Type *t, int o, int likely, Prog *to) |
914 { | 995 { |
915 Node n1, n2, n3; | 996 Node n1, n2, n3; |
916 int a; | 997 int a; |
917 | 998 |
918 regalloc(&n1, t, N); | 999 regalloc(&n1, t, N); |
919 cgen(n, &n1); | 1000 cgen(n, &n1); |
(...skipping 508 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1428 p->to.type = D_OREG; | 1509 p->to.type = D_OREG; |
1429 p->to.offset = dir; | 1510 p->to.offset = dir; |
1430 p->scond |= C_PBIT; | 1511 p->scond |= C_PBIT; |
1431 } | 1512 } |
1432 } | 1513 } |
1433 | 1514 |
1434 regfree(&dst); | 1515 regfree(&dst); |
1435 regfree(&src); | 1516 regfree(&src); |
1436 regfree(&tmp); | 1517 regfree(&tmp); |
1437 } | 1518 } |
OLD | NEW |