]> Cypherpunks repositories - gostls13.git/commitdiff
fix issue 798
authorKen Thompson <ken@golang.org>
Fri, 21 May 2010 00:31:28 +0000 (17:31 -0700)
committerKen Thompson <ken@golang.org>
Fri, 21 May 2010 00:31:28 +0000 (17:31 -0700)
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
https://golang.org/cl/1202042

src/cmd/5g/gsubr.c
src/cmd/6g/gg.h
src/cmd/6g/gsubr.c
src/cmd/6g/reg.c
src/cmd/8g/gg.h
src/cmd/8g/gsubr.c
src/cmd/8g/reg.c
src/cmd/gc/gen.c
src/cmd/gc/go.h

index ef78157472672264dbbf9352bbdf2c616702610c..ea6ab1d70bccab811339920e4fa7c79d9594fcd6 100644 (file)
@@ -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.
index 875c77358888c5c9b816dbe9c165885c0adebb80..353a86dcd8b294b0666f98d932436e19500267b9 100644 (file)
@@ -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)
 
index e9ad6c09467ab204e035090e5ee632c7675374b7..1c11b14aebba0bbcc2639f1162238d6283516620 100644 (file)
@@ -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)
index 10a00b38df9b157a22b8453e50973c4024f70beb..e92740e04b3f14dfdd47a10d15ae2563aa834cc2 100644 (file)
@@ -879,6 +879,8 @@ mkvar(Reg *r, Adr *a)
                        }
                }
        }
+       if(a->pun)
+               flag = 1;
 
        switch(et) {
        case 0:
index a00d69711c223b28cef8bf28851518a9fb5be5e4..57cd1b56b5df46ceb6ef75810f239a821e12d26b 100644 (file)
@@ -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)
 
index 27fec96a73bc20ebe846b85b1b8ff70ab8c0bb1b..3e85b7e30e857bf5050cb2d6d898fdd8d2c37a22 100644 (file)
@@ -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)
index e23205c68faba4788a0a5316280a2e4098ccc952..3e57916c7390463a71716bbdfb5740ed6687a782 100644 (file)
@@ -794,6 +794,8 @@ mkvar(Reg *r, Adr *a)
                        }
                }
        }
+       if(a->pun)
+               flag = 1;
 
        switch(et) {
        case 0:
index 437d41fcf7ff0b98c7edb0a840eccb68f8b0c9fa..ec41d9b8eb4771b1ce52fbe19a89d2a2184640c7 100644 (file)
@@ -663,4 +663,5 @@ tempname(Node *n, Type *t)
        stksize += w;
        stksize = rnd(stksize, w);
        n->xoffset = -stksize;
+       n->pun = anyregalloc();
 }
index 3051ebe2ba2b81a265ea8e159cf69472b5f27b27..5aa95eee3b5e73e0aed5e653960535668bc07273 100644 (file)
@@ -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();