aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Randall <khr@golang.org>2016-08-09 13:58:06 -0700
committerKeith Randall <khr@golang.org>2016-08-10 17:09:38 +0000
commit77ef597f38e11e03522d1ccac34cfd39a1ca8d8e (patch)
tree6b0bf662f015a58861460c0c3dc2d2df36667c96
parentff37d0e681a8b35c0ebff34bc1e73105f8845928 (diff)
downloadgo-77ef597f38e11e03522d1ccac34cfd39a1ca8d8e.tar.gz
go-77ef597f38e11e03522d1ccac34cfd39a1ca8d8e.zip
[dev.ssa] cmd/compile: more fixes for 386 shared libraries
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>
-rw-r--r--src/cmd/compile/internal/ssa/gen/386.rules3
-rw-r--r--src/cmd/compile/internal/ssa/gen/386Ops.go3
-rw-r--r--src/cmd/compile/internal/ssa/opGen.go2
-rw-r--r--src/cmd/internal/obj/x86/obj6.go21
4 files changed, 19 insertions, 10 deletions
diff --git a/src/cmd/compile/internal/ssa/gen/386.rules b/src/cmd/compile/internal/ssa/gen/386.rules
index 921eb06265..b360189e43 100644
--- a/src/cmd/compile/internal/ssa/gen/386.rules
+++ b/src/cmd/compile/internal/ssa/gen/386.rules
@@ -669,7 +669,8 @@
// 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.
diff --git a/src/cmd/compile/internal/ssa/gen/386Ops.go b/src/cmd/compile/internal/ssa/gen/386Ops.go
index 83db157d4f..88948e0033 100644
--- a/src/cmd/compile/internal/ssa/gen/386Ops.go
+++ b/src/cmd/compile/internal/ssa/gen/386Ops.go
@@ -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.
},
},
diff --git a/src/cmd/compile/internal/ssa/opGen.go b/src/cmd/compile/internal/ssa/opGen.go
index 17e5c28004..b8d3b7eac5 100644
--- a/src/cmd/compile/internal/ssa/opGen.go
+++ b/src/cmd/compile/internal/ssa/opGen.go
@@ -3511,7 +3511,7 @@ var opcodeTable = [...]opInfo{
{0, 128}, // DI
{1, 1}, // AX
},
- clobbers: 128, // DI
+ clobbers: 130, // CX DI
},
},
{
diff --git a/src/cmd/internal/obj/x86/obj6.go b/src/cmd/internal/obj/x86/obj6.go
index 9a47ae16ed..7b868bafdb 100644
--- a/src/cmd/internal/obj/x86/obj6.go
+++ b/src/cmd/internal/obj/x86/obj6.go
@@ -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)