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

Comments

Projects
None yet
4 participants
@hengwu0
Copy link
Contributor

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

This comment has been minimized.

Copy link
Contributor Author

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

This comment has been minimized.

Copy link
Contributor Author

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 this to the Go1.13 milestone Feb 28, 2019

@gopherbot

This comment has been minimized.

Copy link

commented Mar 1, 2019

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

@cherrymui

This comment has been minimized.

Copy link
Contributor

commented Mar 1, 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.

@hengwu0

This comment has been minimized.

Copy link
Contributor Author

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.

@gopherbot gopherbot closed this in 95d4e61 Mar 5, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.