summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Cheney <dave@cheney.net>2014-09-30 10:03:10 +1000
committerDave Cheney <dave@cheney.net>2014-09-30 10:03:10 +1000
commitd8538bea6194db2a6aa5b87fda2887dfeb9a4402 (patch)
tree37f8b86ee64f33de795a802f68d3688e94273bc9
parentb4dff4847461a0f8ae373ac9fad4d270b84c5772 (diff)
downloadgo-d8538bea6194db2a6aa5b87fda2887dfeb9a4402.tar.gz
liblink: generate MRC replacement in liblink, not tls_arm
Fixes issue 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://codereview.appspot.com/147310043
-rw-r--r--src/liblink/obj5.c20
-rw-r--r--src/runtime/tls_arm.s11
2 files changed, 21 insertions, 10 deletions
diff --git a/src/liblink/obj5.c b/src/liblink/obj5.c
index e192b082b..d7f2714ed 100644
--- a/src/liblink/obj5.c
+++ b/src/liblink/obj5.c
@@ -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);
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)
tlsfallback = linklookup(ctxt, "runtime.read_tls_fallback", 0);
- // BL runtime.read_tls_fallback(SB)
+ // 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)
+ p = appendp(ctxt, p);
p->as = ABL;
p->to.type = D_BRANCH;
p->to.sym = tlsfallback;
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;
}
}
diff --git a/src/runtime/tls_arm.s b/src/runtime/tls_arm.s
index 039b01383..85c3940bf 100644
--- a/src/runtime/tls_arm.s
+++ b/src/runtime/tls_arm.s
@@ -31,11 +31,8 @@ TEXT runtimeĀ·save_g(SB),NOSPLIT,$-4
#endif
// 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.
- // Both functions are written to only disturb R0 so it should be safe to
- // use R11 here to temporarily store LR.
- MOVW LR, R11
+ // The replacement function saves LR in R11 over the call to read_tls_fallback.
MRC 15, 0, R0, C13, C0, 3 // fetch TLS base pointer
- MOVW R11, LR
// $runtime.tlsg(SB) is a special linker symbol.
// It is the offset from the TLS base pointer to our
// thread-local storage for g.
@@ -57,10 +54,8 @@ TEXT runtimeĀ·load_g(SB),NOSPLIT,$0
// nothing to do as nacl/arm does not use TLS at all.
RET
#endif
- // See comment in save_g.
- MOVW LR, R11
- MRC 15, 0, R0, C13, C0, 3 // fetch TLS base pointer
- MOVW R11, LR
+ // See save_g
+ MRC 15, 0, R0, C13, C0, 3 // fetch TLS base pointer
// $runtime.tlsg(SB) is a special linker symbol.
// It is the offset from the TLS base pointer to our
// thread-local storage for g.