]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: allow -shared/-dynlink on ppc64
authorMichael Hudson-Doyle <michael.hudson@canonical.com>
Wed, 23 Sep 2015 09:02:50 +0000 (21:02 +1200)
committerMichael Hudson-Doyle <michael.hudson@canonical.com>
Mon, 19 Oct 2015 20:27:55 +0000 (20:27 +0000)
Only effect is register related: do not allocate R2 or R12, put function
entrypoint in R12 before indirect call.

Change-Id: I9cdd553bab022601c9cb5bb43c9dc0c368c6fb0a
Reviewed-on: https://go-review.googlesource.com/15961
Reviewed-by: Ian Lance Taylor <iant@golang.org>
src/cmd/compile/internal/gc/lex.go
src/cmd/compile/internal/ppc64/galign.go
src/cmd/compile/internal/ppc64/gsubr.go
src/cmd/compile/internal/ppc64/reg.go

index 340e37fc6b1fa58d264fdaffe1355f9a4fa16c42..81198f37bf2fb6aa7f3d5046a6bf9bad686f207a 100644 (file)
@@ -217,11 +217,13 @@ func Main() {
        obj.Flagcount("y", "debug declarations in canned imports (with -d)", &Debug['y'])
        var flag_shared int
        var flag_dynlink bool
-       if Thearch.Thechar == '6' || Thearch.Thechar == '5' {
+       if Thearch.Thechar == '5' || Thearch.Thechar == '6' || Thearch.Thechar == '9' {
                obj.Flagcount("shared", "generate code that can be linked into a shared library", &flag_shared)
        }
        if Thearch.Thechar == '6' {
                obj.Flagcount("largemodel", "generate code that assumes a large memory model", &flag_largemodel)
+       }
+       if Thearch.Thechar == '6' || Thearch.Thechar == '9' {
                flag.BoolVar(&flag_dynlink, "dynlink", false, "support references to Go symbols defined in other shared libraries")
        }
        obj.Flagstr("cpuprofile", "write cpu profile to `file`", &cpuprofile)
index 16509da8fe1c9ee4439147ecd83faac0a487143c..2bd49fd3753e45c9b66aa0cbad86cac2ebe329bd 100644 (file)
@@ -43,6 +43,11 @@ func betypeinit() {
        gc.Widthptr = 8
        gc.Widthint = 8
        gc.Widthreg = 8
+
+       if gc.Ctxt.Flag_shared != 0 {
+               gc.Thearch.ReservedRegs = append(gc.Thearch.ReservedRegs, ppc64.REG_R2)
+               gc.Thearch.ReservedRegs = append(gc.Thearch.ReservedRegs, ppc64.REG_R12)
+       }
 }
 
 func Main() {
index dde05c4a512dfa6fd6d403f4a72c6c4d9610473f..9e99a31220d1e51cd214e326e23d60626f9ee08d 100644 (file)
@@ -580,6 +580,18 @@ func rawgins(as int, f *gc.Node, t *gc.Node) *obj.Prog {
        case obj.ACALL:
                if p.To.Type == obj.TYPE_REG && p.To.Reg != ppc64.REG_CTR {
                        // Allow front end to emit CALL REG, and rewrite into MOV REG, CTR; CALL CTR.
+                       if gc.Ctxt.Flag_dynlink {
+                               // Make sure function pointer is in R12 as well when
+                               // dynamically linking Go.
+                               // TODO(mwhudson): it would obviously be better to
+                               // change the register allocation to put the value in
+                               // R12 already, but I don't know how to do that.
+                               q := gc.Prog(as)
+                               q.As = ppc64.AMOVD
+                               q.From = p.To
+                               q.To.Type = obj.TYPE_REG
+                               q.To.Reg = ppc64.REG_R12
+                       }
                        pp := gc.Prog(as)
                        pp.From = p.From
                        pp.To.Type = obj.TYPE_REG
index a3018362f64019790ae3a92d0e1620b5b8b14ba1..e231079347eb514e4984c556bde78cc4f76c85d0 100644 (file)
@@ -113,6 +113,12 @@ func excludedregs() uint64 {
        // Exclude registers with fixed functions
        regbits := uint64(1<<0 | RtoB(ppc64.REGSP) | RtoB(ppc64.REGG) | RtoB(ppc64.REGTLS) | RtoB(ppc64.REGTMP))
 
+       if gc.Ctxt.Flag_dynlink {
+               // When dynamically linking Go, R2 is reserved to be the TOC pointer
+               // and R12 so that calls via function pointer can stomp on it.
+               regbits |= RtoB(ppc64.REG_R2)
+               regbits |= RtoB(ppc64.REG_R12)
+       }
        // Also exclude floating point registers with fixed constants
        regbits |= RtoB(ppc64.REG_F27) | RtoB(ppc64.REG_F28) | RtoB(ppc64.REG_F29) | RtoB(ppc64.REG_F30) | RtoB(ppc64.REG_F31)