]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/9g: don't use R13
authorAustin Clements <austin@google.com>
Tue, 16 Dec 2014 18:52:09 +0000 (13:52 -0500)
committerAustin Clements <austin@google.com>
Wed, 7 Jan 2015 20:36:08 +0000 (20:36 +0000)
R13 is the C TLS pointer.  Once we're calling to and from C code, if
we clobber R13 in our code, sigtramp won't know whether to get the
current g from REGG or from C TLS.  The simplest solution is for Go
code to preserve the C TLS pointer.  This is equivalent to what other
platforms do, except that on other platforms the TLS pointer is in a
special register.

Change-Id: I076e9cb83fd78843eb68cb07c748c4705c9a4c82
Reviewed-on: https://go-review.googlesource.com/2007
Reviewed-by: Minux Ma <minux@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
src/cmd/9g/gsubr.c
src/cmd/9g/reg.c
src/cmd/9l/9.out.h

index e5cd5ed4bf0109be324d02e3c0179664ecc7bbea..8abbde45319bdd20766c0a12c51c24d804c5b5f9 100644 (file)
@@ -262,8 +262,15 @@ afunclit(Addr *a, Node *n)
 static int     resvd[] =
 {
        REGZERO,
-       REGSP,  // reserved for SP, XXX: not reserved in 9c.
-       30,     // for g
+       REGSP,  // reserved for SP
+       // We need to preserve the C ABI TLS pointer because sigtramp
+       // may happen during C code and needs to access the g.  C
+       // clobbers REGG, so if Go were to clobber REGTLS, sigtramp
+       // won't know which convention to use.  By preserving REGTLS,
+       // we can just retrieve g from TLS when we aren't sure.
+       REGTLS,
+       // TODO(austin): Consolidate REGTLS and REGG?
+       REGG,
        REGTMP, // REGTMP
        FREGCVI+NREG,
        FREGZERO+NREG,
index 2d8dbc4f1aa3062a60ebe4a899f2b3edfcb2e04d..6d40127ecc623b800b948a2adfd24a25ddb00c3e 100644 (file)
@@ -185,7 +185,7 @@ regopt(Prog *firstp)
        }
 
        // Exclude registers with fixed functions
-       regbits = (1<<D_R0)|RtoB(REGSP)|RtoB(REGG);
+       regbits = (1<<D_R0)|RtoB(REGSP)|RtoB(REGG)|RtoB(REGTLS);
        // Also exclude floating point registers with fixed constants
        regbits |= FtoB(D_F0+27)|FtoB(D_F0+28)|FtoB(D_F0+29)|FtoB(D_F0+30)|FtoB(D_F0+31);
        externs = zbits;
index e7601f027944b4c16918e287c16db7e6d3802805..520ee9a81a64358fc402f4b6d32891e092b0eac2 100644 (file)
@@ -48,6 +48,7 @@ enum
        REGRT2          = 4,    /* reserved for runtime, duffcopy */
        REGMIN          = 7,    /* register variables allocated from here to REGMAX */
        REGENV          = 11,   /* environment for closures */
+       REGTLS          = 13,   /* C ABI TLS base pointer */
        REGMAX          = 27,
        REGEXT          = 30,   /* external registers allocated from here down */
        REGG            = 30,   /* G */