]> Cypherpunks repositories - gostls13.git/commitdiff
liblink: generate MRC replacement in liblink, not tls_arm
authorDave Cheney <dave@cheney.net>
Tue, 30 Sep 2014 00:03:10 +0000 (10:03 +1000)
committerDave Cheney <dave@cheney.net>
Tue, 30 Sep 2014 00:03:10 +0000 (10:03 +1000)
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

src/liblink/obj5.c
src/runtime/tls_arm.s

index e192b082b54d728bfe2e8f6e659f582f516e2878..d7f2714ed886e0e8026eabdb0acd1c17fbff6b97 100644 (file)
@@ -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;
                        }
                }
index 039b0138338cb7015780e011ae142f65b4f683b0..85c3940bf2543cfa5f63549269e85690ad8e7ee4 100644 (file)
@@ -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.