diff options
author | Ken Thompson <ken@golang.org> | 2010-05-20 17:31:28 -0700 |
---|---|---|
committer | Ken Thompson <ken@golang.org> | 2010-05-20 17:31:28 -0700 |
commit | f1148d9f2f84143a602e9c41ed78c361a3a2bc7c (patch) | |
tree | 161077a8865af84f52a276b24c5917fb84e0965e | |
parent | ee26a1fd015319168f77b69f58bfe666b4048339 (diff) | |
download | golang-f1148d9f2f84143a602e9c41ed78c361a3a2bc7c.tar.gz |
fix issue 798
cannot allocate an audomatic temp
while real registers are allocated.
there is a chance that the automatic
will be allocated to one of the
allocated registers. the fix is to
not registerize such variables.
R=rsc
CC=golang-dev
http://codereview.appspot.com/1202042
-rw-r--r-- | src/cmd/5g/gsubr.c | 6 | ||||
-rw-r--r-- | src/cmd/6g/gg.h | 1 | ||||
-rw-r--r-- | src/cmd/6g/gsubr.c | 18 | ||||
-rw-r--r-- | src/cmd/6g/reg.c | 2 | ||||
-rw-r--r-- | src/cmd/8g/gg.h | 1 | ||||
-rw-r--r-- | src/cmd/8g/gsubr.c | 18 | ||||
-rw-r--r-- | src/cmd/8g/reg.c | 2 | ||||
-rw-r--r-- | src/cmd/gc/gen.c | 1 | ||||
-rw-r--r-- | src/cmd/gc/go.h | 2 |
9 files changed, 51 insertions, 0 deletions
diff --git a/src/cmd/5g/gsubr.c b/src/cmd/5g/gsubr.c index ef7815747..ea6ab1d70 100644 --- a/src/cmd/5g/gsubr.c +++ b/src/cmd/5g/gsubr.c @@ -197,6 +197,12 @@ afunclit(Addr *a) } } +int32 +anyregalloc(void) +{ + return 0; +} + /* * allocate register of type t, leave in n. * if o != N, o is desired fixed register. diff --git a/src/cmd/6g/gg.h b/src/cmd/6g/gg.h index 875c77358..353a86dcd 100644 --- a/src/cmd/6g/gg.h +++ b/src/cmd/6g/gg.h @@ -28,6 +28,7 @@ struct Addr uchar index; uchar etype; uchar scale; /* doubles as width in DATA op */ + uchar pun; /* dont register variable */ }; #define A ((Addr*)0) diff --git a/src/cmd/6g/gsubr.c b/src/cmd/6g/gsubr.c index e9ad6c094..1c11b14ae 100644 --- a/src/cmd/6g/gsubr.c +++ b/src/cmd/6g/gsubr.c @@ -238,6 +238,23 @@ gclean(void) yyerror("reg %R left allocated\n", i); } +int32 +anyregalloc(void) +{ + int i, j; + + for(i=D_AL; i<=D_DI; i++) { + if(reg[i] == 0) + goto ok; + for(j=0; j<nelem(resvd); j++) + if(resvd[j] == i) + goto ok; + return 1; + ok:; + } + return 0; +} + /* * allocate register of type t, leave in n. * if o != N, o is desired fixed register. @@ -982,6 +999,7 @@ naddr(Node *n, Addr *a, int canemitcode) a->width = n->type->width; a->gotype = ngotype(n); } + a->pun = n->pun; a->offset = n->xoffset; a->sym = n->sym; if(a->sym == S) diff --git a/src/cmd/6g/reg.c b/src/cmd/6g/reg.c index 10a00b38d..e92740e04 100644 --- a/src/cmd/6g/reg.c +++ b/src/cmd/6g/reg.c @@ -879,6 +879,8 @@ mkvar(Reg *r, Adr *a) } } } + if(a->pun) + flag = 1; switch(et) { case 0: diff --git a/src/cmd/8g/gg.h b/src/cmd/8g/gg.h index a00d69711..57cd1b56b 100644 --- a/src/cmd/8g/gg.h +++ b/src/cmd/8g/gg.h @@ -30,6 +30,7 @@ struct Addr uchar index; uchar etype; uchar scale; /* doubles as width in DATA op */ + uchar pun; /* dont register variable */ }; #define A ((Addr*)0) diff --git a/src/cmd/8g/gsubr.c b/src/cmd/8g/gsubr.c index 27fec96a7..3e85b7e30 100644 --- a/src/cmd/8g/gsubr.c +++ b/src/cmd/8g/gsubr.c @@ -710,6 +710,23 @@ gclean(void) yyerror("reg %R left allocated at %lux", i, regpc[i]); } +int32 +anyregalloc(void) +{ + int i, j; + + for(i=D_AL; i<=D_DI; i++) { + if(reg[i] == 0) + goto ok; + for(j=0; j<nelem(resvd); j++) + if(resvd[j] == i) + goto ok; + return 1; + ok:; + } + return 0; +} + /* * allocate register of type t, leave in n. * if o != N, o is desired fixed register. @@ -1692,6 +1709,7 @@ naddr(Node *n, Addr *a, int canemitcode) a->width = n->type->width; a->gotype = ngotype(n); } + a->pun = n->pun; a->offset = n->xoffset; a->sym = n->sym; if(a->sym == S) diff --git a/src/cmd/8g/reg.c b/src/cmd/8g/reg.c index e23205c68..3e57916c7 100644 --- a/src/cmd/8g/reg.c +++ b/src/cmd/8g/reg.c @@ -794,6 +794,8 @@ mkvar(Reg *r, Adr *a) } } } + if(a->pun) + flag = 1; switch(et) { case 0: diff --git a/src/cmd/gc/gen.c b/src/cmd/gc/gen.c index 437d41fcf..ec41d9b8e 100644 --- a/src/cmd/gc/gen.c +++ b/src/cmd/gc/gen.c @@ -663,4 +663,5 @@ tempname(Node *n, Type *t) stksize += w; stksize = rnd(stksize, w); n->xoffset = -stksize; + n->pun = anyregalloc(); } diff --git a/src/cmd/gc/go.h b/src/cmd/gc/go.h index 3051ebe2b..5aa95eee3 100644 --- a/src/cmd/gc/go.h +++ b/src/cmd/gc/go.h @@ -215,6 +215,7 @@ struct Node uchar used; uchar oldref; uchar isddd; + uchar pun; // dont registerize variable ONAME // most nodes Node* left; @@ -1241,3 +1242,4 @@ int duintptr(Sym *s, int off, uint64 v); int duintxx(Sym *s, int off, uint64 v, int wid); void genembedtramp(Type*, Type*, Sym*); int gen_as_init(Node*); +int anyregalloc(); |