Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(2447)

Side by Side Diff: src/cmd/5g/cgen.c

Issue 6621061: code review 6621061: cmd/5g, cmd/6g, cmd/8g: fix out of registers. (Closed)
Patch Set: diff -r b595997205c8 https://go.googlecode.com/hg/ Created 12 years, 5 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | src/cmd/6g/cgen.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | src/cmd/6g/cgen.c » ('j') | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b