From 1f85d3ad09152e09d5f4e9b6d9dcec72dbb4ad9b Mon Sep 17 00:00:00 2001 From: Michael Hudson-Doyle Date: Thu, 27 Apr 2017 11:56:42 +1200 Subject: [PATCH] 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 TryBot-Result: Gobot Gobot Reviewed-by: Keith Randall --- src/cmd/internal/obj/x86/obj6.go | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/cmd/internal/obj/x86/obj6.go b/src/cmd/internal/obj/x86/obj6.go index 4289dbcf82..d34f0aeaa6 100644 --- a/src/cmd/internal/obj/x86/obj6.go +++ b/src/cmd/internal/obj/x86/obj6.go @@ -296,15 +296,13 @@ func progedit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) { // Rewrite p, if necessary, to access global data via the global offset table. func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) { - var add, lea, mov obj.As + var lea, mov obj.As var reg int16 if ctxt.Arch.Family == sys.AMD64 { - add = AADDQ lea = ALEAQ mov = AMOVQ reg = REG_R15 } else { - add = AADDL lea = ALEAL mov = AMOVL reg = REG_CX @@ -321,8 +319,10 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) { // 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 = ctxt.Lookup("runtime.duffzero") @@ -339,9 +339,10 @@ func rewriteToUseGot(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) { p.To.Offset = 0 p.To.Sym = nil p1 := obj.Appendp(p, newprog) - 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(p1, newprog) -- 2.50.0