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>
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)
}
/*
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)
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)
}
/*
--- /dev/null
+// +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)))
+}