Commit 0b36211c authored by Dave Cheney's avatar Dave Cheney

liblink: generate MRC replacement in liblink, not tls_arm

Fixes #8690.

This CL moves the save of LR around BL runtime.read_tls_fallback to liblink as it is not needed when MRC is not replaced.

LGTM=rsc, minux
R=rsc, khr, minux
CC=golang-codereviews
https://golang.org/cl/147310043
parent 5368e63b
...@@ -119,14 +119,30 @@ progedit(Link *ctxt, Prog *p) ...@@ -119,14 +119,30 @@ progedit(Link *ctxt, Prog *p)
ctxt->diag("%L: TLS MRC instruction must write to R0 as it might get translated into a BL instruction", p->lineno); ctxt->diag("%L: TLS MRC instruction must write to R0 as it might get translated into a BL instruction", p->lineno);
if(ctxt->goarm < 7) { if(ctxt->goarm < 7) {
// Replace it with BL runtime.read_tls_fallback(SB). // Replace it with BL runtime.read_tls_fallback(SB) for ARM CPUs that lack the tls extension.
if(tlsfallback == nil) if(tlsfallback == nil)
tlsfallback = linklookup(ctxt, "runtime.read_tls_fallback", 0); tlsfallback = linklookup(ctxt, "runtime.read_tls_fallback", 0);
// MOVW LR, R11
p->as = AMOVW;
p->from.type = D_REG;
p->from.reg = REGLINK;
p->to.type = D_REG;
p->to.reg = REGTMP;
// BL runtime.read_tls_fallback(SB) // BL runtime.read_tls_fallback(SB)
p = appendp(ctxt, p);
p->as = ABL; p->as = ABL;
p->to.type = D_BRANCH; p->to.type = D_BRANCH;
p->to.sym = tlsfallback; p->to.sym = tlsfallback;
p->to.offset = 0; p->to.offset = 0;
// MOVW R11, LR
p = appendp(ctxt, p);
p->as = AMOVW;
p->from.type = D_REG;
p->from.reg = REGTMP;
p->to.type = D_REG;
p->to.reg = REGLINK;
break; break;
} }
} }
......
...@@ -31,11 +31,8 @@ TEXT runtime·save_g(SB),NOSPLIT,$-4 ...@@ -31,11 +31,8 @@ TEXT runtime·save_g(SB),NOSPLIT,$-4
#endif #endif
// If the host does not support MRC the linker will replace it with // If the host does not support MRC the linker will replace it with
// a call to runtime.read_tls_fallback which jumps to __kuser_get_tls. // a call to runtime.read_tls_fallback which jumps to __kuser_get_tls.
// Both functions are written to only disturb R0 so it should be safe to // The replacement function saves LR in R11 over the call to read_tls_fallback.
// use R11 here to temporarily store LR.
MOVW LR, R11
MRC 15, 0, R0, C13, C0, 3 // fetch TLS base pointer MRC 15, 0, R0, C13, C0, 3 // fetch TLS base pointer
MOVW R11, LR
// $runtime.tlsg(SB) is a special linker symbol. // $runtime.tlsg(SB) is a special linker symbol.
// It is the offset from the TLS base pointer to our // It is the offset from the TLS base pointer to our
// thread-local storage for g. // thread-local storage for g.
...@@ -57,10 +54,8 @@ TEXT runtime·load_g(SB),NOSPLIT,$0 ...@@ -57,10 +54,8 @@ TEXT runtime·load_g(SB),NOSPLIT,$0
// nothing to do as nacl/arm does not use TLS at all. // nothing to do as nacl/arm does not use TLS at all.
RET RET
#endif #endif
// See comment in save_g. // See save_g
MOVW LR, R11
MRC 15, 0, R0, C13, C0, 3 // fetch TLS base pointer MRC 15, 0, R0, C13, C0, 3 // fetch TLS base pointer
MOVW R11, LR
// $runtime.tlsg(SB) is a special linker symbol. // $runtime.tlsg(SB) is a special linker symbol.
// It is the offset from the TLS base pointer to our // It is the offset from the TLS base pointer to our
// thread-local storage for g. // thread-local storage for 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