Commit bbd21279 authored by Austin Clements's avatar Austin Clements

cmd/9g: don't use R13

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/2007Reviewed-by: default avatarMinux Ma <minux@golang.org>
Reviewed-by: default avatarRuss Cox <rsc@golang.org>
parent db923390
...@@ -262,8 +262,15 @@ afunclit(Addr *a, Node *n) ...@@ -262,8 +262,15 @@ afunclit(Addr *a, Node *n)
static int resvd[] = static int resvd[] =
{ {
REGZERO, REGZERO,
REGSP, // reserved for SP, XXX: not reserved in 9c. REGSP, // reserved for SP
30, // for g // 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 REGTMP, // REGTMP
FREGCVI+NREG, FREGCVI+NREG,
FREGZERO+NREG, FREGZERO+NREG,
......
...@@ -185,7 +185,7 @@ regopt(Prog *firstp) ...@@ -185,7 +185,7 @@ regopt(Prog *firstp)
} }
// Exclude registers with fixed functions // 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 // 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); regbits |= FtoB(D_F0+27)|FtoB(D_F0+28)|FtoB(D_F0+29)|FtoB(D_F0+30)|FtoB(D_F0+31);
externs = zbits; externs = zbits;
......
...@@ -48,6 +48,7 @@ enum ...@@ -48,6 +48,7 @@ enum
REGRT2 = 4, /* reserved for runtime, duffcopy */ REGRT2 = 4, /* reserved for runtime, duffcopy */
REGMIN = 7, /* register variables allocated from here to REGMAX */ REGMIN = 7, /* register variables allocated from here to REGMAX */
REGENV = 11, /* environment for closures */ REGENV = 11, /* environment for closures */
REGTLS = 13, /* C ABI TLS base pointer */
REGMAX = 27, REGMAX = 27,
REGEXT = 30, /* external registers allocated from here down */ REGEXT = 30, /* external registers allocated from here down */
REGG = 30, /* G */ REGG = 30, /* G */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment