]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.ssa] cmd/compile: more fixes for 386 shared libraries
authorKeith Randall <khr@golang.org>
Tue, 9 Aug 2016 20:58:06 +0000 (13:58 -0700)
committerKeith Randall <khr@golang.org>
Wed, 10 Aug 2016 17:09:38 +0000 (17:09 +0000)
Use the destination register for materializing the pc
for GOT references also. See https://go-review.googlesource.com/c/25442/
The SSA backend assumes CX does not get clobbered for these instructions.

Mark duffzero as clobbering CX. The linker needs to clobber CX
to materialize the address to call. (This affects the non-shared-library
duffzero also, but hopefully forbidding one register across duffzero
won't be a big deal.)

Hopefully this is all the cases where the linker is clobbering CX
under the hood and SSA assumes it isn't.

Change-Id: I080c938170193df57cd5ce1f2a956b68a34cc886
Reviewed-on: https://go-review.googlesource.com/26611
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Michael Hudson-Doyle <michael.hudson@canonical.com>
src/cmd/compile/internal/ssa/gen/386.rules
src/cmd/compile/internal/ssa/gen/386Ops.go
src/cmd/compile/internal/ssa/opGen.go
src/cmd/internal/obj/x86/obj6.go

index 921eb06265bf03e0c4dc97acdf924091c52a7609..b360189e43acb4f92fe703f5a01c9a1a5256c5f9 100644 (file)
 
 // We need to fold LEAQ into the MOVx ops so that the live variable analysis knows
 // what variables are being read/written by the ops.
-// Note: we turn off this merging for operations on globals when building position-independent code.
+// Note: we turn off this merging for operations on globals when building
+// position-independent code (when Flag_shared is set).
 // PIC needs a spare register to load the PC into. For loads from globals into integer registers we use
 // the target register, but for other loads and all stores, we need a free register. Having the LEAL be
 // a separate instruction gives us that register.
index 83db157d4f2e37b6084dc2f312c83a0b981a0cd7..88948e0033eda88ba4841492df29524a9c7b4551 100644 (file)
@@ -362,7 +362,8 @@ func init() {
                        argLength: 3,
                        reg: regInfo{
                                inputs:   []regMask{buildReg("DI"), buildReg("AX")},
-                               clobbers: buildReg("DI"),
+                               clobbers: buildReg("DI CX"),
+                               // Note: CX is only clobbered when dynamic linking.
                        },
                },
 
index 17e5c280041909078b4711dcf3394db2ab9580be..b8d3b7eac5df505a01de55d16f88f7e6b1533998 100644 (file)
@@ -3511,7 +3511,7 @@ var opcodeTable = [...]opInfo{
                                {0, 128}, // DI
                                {1, 1},   // AX
                        },
-                       clobbers: 128, // DI
+                       clobbers: 130, // CX DI
                },
        },
        {
index 9a47ae16ed7268bd1394489b384dcfc039b9debe..7b868bafdb3f9e9edebefdb399a28b5dde483ece 100644 (file)
@@ -334,6 +334,16 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) {
                lea = ALEAL
                mov = AMOVL
                reg = REG_CX
+               if p.To.Type == obj.TYPE_REG && p.To.Reg != p.From.Reg && p.To.Reg != p.From.Index {
+                       switch p.As {
+                       case ALEAL, AMOVL, AMOVWLZX, AMOVBLZX, AMOVWLSX, AMOVBLSX:
+                               // Special case: clobber the destination register with
+                               // the PC so we don't have to clobber CX.
+                               // The SSA backend depends on CX not being clobbered across these instructions.
+                               // See cmd/compile/internal/ssa/gen/386.rules (search for Flag_shared).
+                               reg = p.To.Reg
+                       }
+               }
        }
 
        if p.As == obj.ADUFFCOPY || p.As == obj.ADUFFZERO {
@@ -392,7 +402,7 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) {
                        dest = p.To
                        p.As = mov
                        p.To.Type = obj.TYPE_REG
-                       p.To.Reg = REG_CX
+                       p.To.Reg = reg
                        p.To.Sym = nil
                        p.To.Name = obj.NAME_NONE
                }
@@ -413,7 +423,7 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) {
                        q.As = pAs
                        q.To = dest
                        q.From.Type = obj.TYPE_REG
-                       q.From.Reg = REG_CX
+                       q.From.Reg = reg
                }
        }
        if p.From3 != nil && p.From3.Name == obj.NAME_EXTERN {
@@ -544,14 +554,11 @@ func rewriteToPcrel(ctxt *obj.Link, p *obj.Prog) {
                return
        }
        var dst int16 = REG_CX
-       if isName(&p.From) && p.To.Type == obj.TYPE_REG {
+       if p.To.Type == obj.TYPE_REG && p.To.Reg != p.From.Reg && p.To.Reg != p.From.Index {
                switch p.As {
                case ALEAL, AMOVL, AMOVWLZX, AMOVBLZX, AMOVWLSX, AMOVBLSX:
                        dst = p.To.Reg
-                       // Special case: clobber the destination register with
-                       // the PC so we don't have to clobber CX.
-                       // The SSA backend depends on CX not being clobbered across these instructions.
-                       // See cmd/compile/internal/ssa/gen/386.rules (search for Flag_shared).
+                       // Why?  See the comment near the top of rewriteToUseGot above.
                }
        }
        q := obj.Appendp(ctxt, p)