summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKen Thompson <ken@golang.org>2010-05-20 17:31:28 -0700
committerKen Thompson <ken@golang.org>2010-05-20 17:31:28 -0700
commitf1148d9f2f84143a602e9c41ed78c361a3a2bc7c (patch)
tree161077a8865af84f52a276b24c5917fb84e0965e
parentee26a1fd015319168f77b69f58bfe666b4048339 (diff)
downloadgolang-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.c6
-rw-r--r--src/cmd/6g/gg.h1
-rw-r--r--src/cmd/6g/gsubr.c18
-rw-r--r--src/cmd/6g/reg.c2
-rw-r--r--src/cmd/8g/gg.h1
-rw-r--r--src/cmd/8g/gsubr.c18
-rw-r--r--src/cmd/8g/reg.c2
-rw-r--r--src/cmd/gc/gen.c1
-rw-r--r--src/cmd/gc/go.h2
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();