summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Hudson-Doyle <michael.hudson@canonical.com>2017-04-27 11:56:42 +1200
committerRuss Cox <rsc@golang.org>2017-10-25 18:57:16 +0000
commitb838f943ab3e3cb46e386e4541f0f1d2226c7958 (patch)
treea6e0efa5d845d17ad9b376a5c3e93d68c6897572
parent3be9637d5658535714baeed1994af39342c5066c (diff)
downloadgo-git-b838f943ab3e3cb46e386e4541f0f1d2226c7958.tar.gz
[release-branch.go1.8] cmd/internal/obj/x86: use LEAx rather than ADDx when calling DUFFxxxx via GOT
DUFFZERO on 386 is not marked as clobbering flags, but rewriteToUseGot rewrote "ADUFFZERO $offset" to "MOVL runtime.duffxxx@GOT, CX; ADDL $offset, CX; CALL CX" which does. Luckily the fix is easier than figuring out what the problem was: replace the ADDL $offset, CX with LEAL $offset(CX), CX. On amd64 DUFFZERO clobbers flags, on arm, arm64 and ppc64 ADD does not clobber flags and s390x does not use the duff functions, so I'm fairly confident this is the only fix required. I don't know how to write a test though. Change-Id: I69b0958f5f45771d61db5f5ecb4ded94e8960d4d Reviewed-on: https://go-review.googlesource.com/41821 Run-TryBot: Michael Hudson-Doyle <michael.hudson@canonical.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org> Reviewed-on: https://go-review.googlesource.com/70871 Run-TryBot: Russ Cox <rsc@golang.org>
-rw-r--r--src/cmd/internal/obj/x86/obj6.go13
1 files changed, 7 insertions, 6 deletions
diff --git a/src/cmd/internal/obj/x86/obj6.go b/src/cmd/internal/obj/x86/obj6.go
index eb6f867ca7..f3dfd32979 100644
--- a/src/cmd/internal/obj/x86/obj6.go
+++ b/src/cmd/internal/obj/x86/obj6.go
@@ -322,15 +322,13 @@ func progedit(ctxt *obj.Link, p *obj.Prog) {
// Rewrite p, if necessary, to access global data via the global offset table.
func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) {
- var add, lea, mov obj.As
+ var lea, mov obj.As
var reg int16
if p.Mode == 64 {
- add = AADDQ
lea = ALEAQ
mov = AMOVQ
reg = REG_R15
} else {
- add = AADDL
lea = ALEAL
mov = AMOVL
reg = REG_CX
@@ -347,8 +345,10 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) {
// ADUFFxxx $offset
// becomes
// $MOV runtime.duffxxx@GOT, $reg
- // $ADD $offset, $reg
+ // $LEA $offset($reg), $reg
// CALL $reg
+ // (we use LEAx rather than ADDx because ADDx clobbers
+ // flags and duffzero on 386 does not otherwise do so)
var sym *obj.LSym
if p.As == obj.ADUFFZERO {
sym = obj.Linklookup(ctxt, "runtime.duffzero", 0)
@@ -365,9 +365,10 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog) {
p.To.Offset = 0
p.To.Sym = nil
p1 := obj.Appendp(ctxt, p)
- p1.As = add
- p1.From.Type = obj.TYPE_CONST
+ p1.As = lea
+ p1.From.Type = obj.TYPE_MEM
p1.From.Offset = offset
+ p1.From.Reg = reg
p1.To.Type = obj.TYPE_REG
p1.To.Reg = reg
p2 := obj.Appendp(ctxt, p1)