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/compile: mips64 instruction UNPREDICTABLE error #30459

Closed
hengwu0 opened this issue Feb 28, 2019 · 5 comments
Closed

cmd/compile: mips64 instruction UNPREDICTABLE error #30459

hengwu0 opened this issue Feb 28, 2019 · 5 comments
Labels
FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone

Comments

@hengwu0
Copy link
Contributor

hengwu0 commented Feb 28, 2019

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

$ go version
go version go1.10.3 linux/amd64

Does this issue reproduce with the latest release?

yes

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

go env Output
$ go env
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/wuheng/.cache/go-build"
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/wuheng/go"
GORACE=""
GOROOT="/home/wuheng/CrossTools/golang"
GOTMPDIR=""
GOTOOLDIR="/home/wuheng/CrossTools/golang/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build622509133=/tmp/go-build -gno-record-gcc-switches"

What did you do?

[wuheng@localhost]$ GOCACHE=off GOARCH=mips64 go build -o A main.go

Copy file A to mips64 system level qemu...

[wuheng@mips64]$ qemu-system-mips64 -version
QEMU emulator version 2.10.1

What did you expect to see?

In qemu-system-mips64:

[wuheng@mips64]$ ./A
0

What did you see instead?

In qemu-system-mips64:

[wuheng@mips64]$ ./A
46

My source code main.go

package main

import "fmt"
import "os"

func main() {
	var x byte=os.Args[0][0]
	mask := rune(x) << 31 >> 31
	fmt.Println(mask)
}
@hengwu0
Copy link
Contributor Author

hengwu0 commented Feb 28, 2019

I looked the asm of file A, it showed below:

[wuheng@localhost]$ mips64--gnu-objdump -S A | less
...
       mask := rune(x) << 31 >> 31
   a9558:       00010ff8        dsll    at,at,0x1f
   a955c:       00200821        move    at,at
   a9560:       00010ffb        dsra    at,at,0x1f
...

It seemd golang use AADDU instruction to sign-extended to high 32 bits( 00200821 indicate AADDU ), but there is an UNPREDICTABLE in addu explained in MIPS64 ISA. Which showed below:

Restrictions:

If either GPR rt or GPR rs does not contain sign-extended 32-bit values (bits 63..31 equal), then the result of the operation is UNPREDICTABLE.

Operation:
if NotWordValue(GPR[rs]) or NotWordValue(GPR[rt]) then
    UNPREDICTABLE
endif
temp ← GPR[rs] + GPR[rt]
GPR[rd] ← sign_extend(temp31..0)

I debuged the program A, and I found the high 32 bits are not equal in at register!

@hengwu0
Copy link
Contributor Author

hengwu0 commented Feb 28, 2019

You can replace addu with a sll instruction with a definite behavior (sll will discard the upper 32 bits of the 64 bits, then do sign extensions, with certain behavior). It won't have any UNPREDICTABLE expectation. #30461

@ALTree ALTree added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Feb 28, 2019
@ALTree ALTree added this to the Go1.13 milestone Feb 28, 2019
@gopherbot
Copy link

Change https://golang.org/cl/164758 mentions this issue: cmd/compile: Fix mips64 instruction UNPREDICTABLE bug

@cherrymui
Copy link
Member

Thanks for the investigation. The MIPS64 port was written according to MIPS III ISA, which, as far as I know, doesn't have such restriction. That said, if the fix works on both old and new MIPS64 machines, I'm ok with it.

@hengwu0
Copy link
Contributor Author

hengwu0 commented Mar 4, 2019

Thanks for the investigation. The MIPS64 port was written according to MIPS III ISA, which, as far as I know, doesn't have such restriction. That said, if the fix works on both old and new MIPS64 machines, I'm ok with it.

I looked the MIPS III ISA, there is a line of addu in the manual: In 64-bit mode, the operands must be valid sign-extended, 32-bit values. So it also has the restriction too!!! Reference here. I debuged the program A, and I found the high 32 bits are not equal in at register!
Thanks for merging.

@golang golang locked and limited conversation to collaborators Mar 4, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Projects
None yet
Development

No branches or pull requests

4 participants