Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd/objdump: MULSD disassembles as REPNE MULSD #17410

Closed
jcorbin opened this issue Oct 11, 2016 · 2 comments
Closed

cmd/objdump: MULSD disassembles as REPNE MULSD #17410

jcorbin opened this issue Oct 11, 2016 · 2 comments
Labels
FrozenDueToAge NeedsFix The path to resolution is known, but the work has not been done.
Milestone

Comments

@jcorbin
Copy link

jcorbin commented Oct 11, 2016

When the go disassembler (as seen in go tool objdump or go tool pprof -disasm, SSE floating point instructions are encoded with a seemingly incorrect "REPNE" prefix.

So REPNE is F2 and MULSD with an XMM operand is F2 0F 59, but the go disassembler decodes F2 0F 59 as REPNE MULSD_XMM, in opposition to gobjdump just saying mulsd.

Originally I was confused, and thought that maybe this was something like REPZ RET, but the more I looked, the more this seemed like a bug in x86 decoding.

What version of Go are you using (go version)?

go version go1.7 darwin/amd64

What operating system and processor architecture are you using (go env)?

GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/joshua/golang"
GORACE=""
GOROOT="/usr/local/Cellar/go/1.7/libexec"
GOTOOLDIR="/usr/local/Cellar/go/1.7/libexec/pkg/tool/darwin_amd64"
CC="clang"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/25/9fgzr84d7td1bkn4_wxnvgfc0000gn/T/go-build068341104=/tmp/go-build -gno-record-gcc-switches -fno-common"
CXX="clang++"
CGO_ENABLED="1"

What did you do?

Compile this code:

func fastPow(x float64, n uint) (r float64) {
    r = x
    n--
    for ; n > 0; n >>= 1 {
        if n&1 == 1 {
            r *= x
        }
        x *= x
    }
    return
}

Compare the output of GNU binutils objdump vs go tool objdump.

What did you expect to see?

Output like GNU objdump:

0000000000074eb0 <.../main.fastPow>:
   74eb0:       48 8b 44 24 10          mov    0x10(%rsp),%rax
   74eb5:       48 ff c8                dec    %rax
   74eb8:       f2 0f 10 44 24 08       movsd  0x8(%rsp),%xmm0
   74ebe:       0f 10 c8                movups %xmm0,%xmm1
   74ec1:       48 85 c0                test   %rax,%rax
   74ec4:       76 20                   jbe    74ee6 <.../main.fastPow+0x36>
   74ec6:       48 89 c1                mov    %rax,%rcx
   74ec9:       48 83 e0 01             and    $0x1,%rax
   74ecd:       48 83 f8 01             cmp    $0x1,%rax
   74ed1:       75 04                   jne    74ed7 <.../main.fastPow+0x27>
   74ed3:       f2 0f 59 c8             mulsd  %xmm0,%xmm1
   74ed7:       48 d1 e9                shr    %rcx
   74eda:       f2 0f 59 c0             mulsd  %xmm0,%xmm0
   74ede:       48 89 c8                mov    %rcx,%rax
   74ee1:       48 85 c0                test   %rax,%rax
   74ee4:       77 e0                   ja     74ec6 <.../main.fastPow+0x16>
   74ee6:       f2 0f 11 4c 24 18       movsd  %xmm1,0x18(%rsp)
   74eec:       c3                      retq
   74eed:       cc                      int3
   74eee:       cc                      int3
   74eef:       cc                      int3

What did you see instead?

TEXT .../main.fastPow(SB) .../foo.go
    foo.go:78   0x74eb0 488b442410  MOVQ 0x10(SP), AX
    foo.go:78   0x74eb5 48ffc8      DECQ AX
    foo.go:80   0x74eb8 f20f10442408    REPNE MOVSD_XMM 0x8(SP), X0
    foo.go:80   0x74ebe 0f10c8      MOVUPS X0, X1
    foo.go:80   0x74ec1 4885c0      TESTQ AX, AX
    foo.go:80   0x74ec4 7620        JBE 0x74ee6
    foo.go:81   0x74ec6 4889c1      MOVQ AX, CX
    foo.go:81   0x74ec9 4883e001    ANDQ $0x1, AX
    foo.go:81   0x74ecd 4883f801    CMPQ $0x1, AX
    foo.go:81   0x74ed1 7504        JNE 0x74ed7
    foo.go:82   0x74ed3 f20f59c8    REPNE MULSD X0, X1
    foo.go:80   0x74ed7 48d1e9      SHRQ $0x1, CX
    foo.go:84   0x74eda f20f59c0    REPNE MULSD X0, X0
    foo.go:80   0x74ede 4889c8      MOVQ CX, AX
    foo.go:80   0x74ee1 4885c0      TESTQ AX, AX
    foo.go:80   0x74ee4 77e0        JA 0x74ec6
    foo.go:164  0x74ee6 f20f114c2418    REPNE MOVSD_XMM X1, 0x18(SP)
    foo.go:164  0x74eec c3      RET
    :-1         0x74eed cc      INT $0x3
    :-1         0x74eee cc      INT $0x3
    :-1         0x74eef cc      INT $0x3
@quentinmit quentinmit changed the title Confusing disassembler output around sse floating point instructions cmd/objdump: confusing disassembler output around sse floating point instructions Oct 11, 2016
@quentinmit quentinmit added this to the Go1.8Maybe milestone Oct 11, 2016
@quentinmit quentinmit added the NeedsFix The path to resolution is known, but the work has not been done. label Oct 11, 2016
@rsc rsc changed the title cmd/objdump: confusing disassembler output around sse floating point instructions cmd/objdump: MULSD disassembles as REPNE MULSD Oct 20, 2016
@rsc rsc modified the milestones: Go1.9, Go1.8Maybe Nov 2, 2016
@LMMilewski LMMilewski self-assigned this Feb 9, 2017
@gopherbot
Copy link

CL https://golang.org/cl/36694 mentions this issue.

@gopherbot
Copy link

CL https://golang.org/cl/36770 mentions this issue.

gopherbot pushed a commit that referenced this issue Apr 20, 2017
Copied by hand.

Update #17410
Update #19142
Fixes #19986

Change-Id: I21d16d254161c75466b31c670f3b2c8c463abd66
Reviewed-on: https://go-review.googlesource.com/41205
Run-TryBot: Keith Randall <khr@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
@golang golang locked and limited conversation to collaborators Feb 16, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge NeedsFix The path to resolution is known, but the work has not been done.
Projects
None yet
Development

No branches or pull requests

5 participants