mirror of
https://github.com/golang/go.git
synced 2024-09-22 02:48:50 +00:00
cmd/compile: fix magic multiply smashing AX
Fixes #12411. Change-Id: I2202a754c7750e3b2119e3744362c98ca0d2433e Reviewed-on: https://go-review.googlesource.com/17818 Reviewed-by: Keith Randall <khr@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
parent
63a6f305ef
commit
03c8164849
@ -365,24 +365,25 @@ func cgen_hmul(nl *gc.Node, nr *gc.Node, res *gc.Node) {
|
||||
gc.Cgenr(nl, &n1, res)
|
||||
var n2 gc.Node
|
||||
gc.Cgenr(nr, &n2, nil)
|
||||
var ax gc.Node
|
||||
gc.Nodreg(&ax, t, x86.REG_AX)
|
||||
var ax, oldax, dx, olddx gc.Node
|
||||
savex(x86.REG_AX, &ax, &oldax, res, gc.Types[gc.TUINT64])
|
||||
savex(x86.REG_DX, &dx, &olddx, res, gc.Types[gc.TUINT64])
|
||||
gmove(&n1, &ax)
|
||||
gins(a, &n2, nil)
|
||||
gc.Regfree(&n2)
|
||||
gc.Regfree(&n1)
|
||||
|
||||
var dx gc.Node
|
||||
if t.Width == 1 {
|
||||
// byte multiply behaves differently.
|
||||
gc.Nodreg(&ax, t, x86.REG_AH)
|
||||
|
||||
gc.Nodreg(&dx, t, x86.REG_DX)
|
||||
gmove(&ax, &dx)
|
||||
var byteAH, byteDX gc.Node
|
||||
gc.Nodreg(&byteAH, t, x86.REG_AH)
|
||||
gc.Nodreg(&byteDX, t, x86.REG_DX)
|
||||
gmove(&byteAH, &byteDX)
|
||||
}
|
||||
|
||||
gc.Nodreg(&dx, t, x86.REG_DX)
|
||||
gmove(&dx, res)
|
||||
|
||||
restx(&ax, &oldax)
|
||||
restx(&dx, &olddx)
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -531,24 +531,21 @@ func cgen_bmul(op gc.Op, nl *gc.Node, nr *gc.Node, res *gc.Node) bool {
|
||||
func cgen_hmul(nl *gc.Node, nr *gc.Node, res *gc.Node) {
|
||||
var n1 gc.Node
|
||||
var n2 gc.Node
|
||||
var ax gc.Node
|
||||
var dx gc.Node
|
||||
|
||||
t := nl.Type
|
||||
a := optoas(gc.OHMUL, t)
|
||||
|
||||
// gen nl in n1.
|
||||
gc.Tempname(&n1, t)
|
||||
|
||||
gc.Cgen(nl, &n1)
|
||||
|
||||
// gen nr in n2.
|
||||
gc.Regalloc(&n2, t, res)
|
||||
|
||||
gc.Cgen(nr, &n2)
|
||||
|
||||
// multiply.
|
||||
gc.Nodreg(&ax, t, x86.REG_AX)
|
||||
var ax, oldax, dx, olddx gc.Node
|
||||
savex(x86.REG_AX, &ax, &oldax, res, gc.Types[gc.TUINT32])
|
||||
savex(x86.REG_DX, &dx, &olddx, res, gc.Types[gc.TUINT32])
|
||||
|
||||
gmove(&n2, &ax)
|
||||
gins(a, &n1, nil)
|
||||
@ -556,14 +553,16 @@ func cgen_hmul(nl *gc.Node, nr *gc.Node, res *gc.Node) {
|
||||
|
||||
if t.Width == 1 {
|
||||
// byte multiply behaves differently.
|
||||
gc.Nodreg(&ax, t, x86.REG_AH)
|
||||
|
||||
gc.Nodreg(&dx, t, x86.REG_DX)
|
||||
gmove(&ax, &dx)
|
||||
var byteAH, byteDX gc.Node
|
||||
gc.Nodreg(&byteAH, t, x86.REG_AH)
|
||||
gc.Nodreg(&byteDX, t, x86.REG_DX)
|
||||
gmove(&byteAH, &byteDX)
|
||||
}
|
||||
|
||||
gc.Nodreg(&dx, t, x86.REG_DX)
|
||||
gmove(&dx, res)
|
||||
|
||||
restx(&ax, &oldax)
|
||||
restx(&dx, &olddx)
|
||||
}
|
||||
|
||||
/*
|
||||
|
24
test/fixedbugs/issue12411.go
Normal file
24
test/fixedbugs/issue12411.go
Normal file
@ -0,0 +1,24 @@
|
||||
// +build !386
|
||||
// run
|
||||
|
||||
// Copyright 2015 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Issue 12411. Loss of AX during %.
|
||||
|
||||
package main
|
||||
|
||||
func main() {
|
||||
x := f(4)
|
||||
if x != 0 {
|
||||
println("BUG: x=", x)
|
||||
}
|
||||
}
|
||||
|
||||
//go:noinline
|
||||
func f(x int) int {
|
||||
// AX was live on entry to one of the % code generations,
|
||||
// and the % code generation smashed it.
|
||||
return ((2 * x) % 3) % (2 % ((x << 2) ^ (x % 3)))
|
||||
}
|
Loading…
Reference in New Issue
Block a user