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>
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,
}
// 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;
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 */