mirror of
https://github.com/golang/go
synced 2024-11-14 15:20:43 -07:00
e464d7d797
When generating code for unsigned equals (==) and not equals (!=) comparisons we currently, on s390x, always use signed comparisons. This mostly works well, however signed comparisons on s390x sign extend their immediates and unsigned comparisons zero extend them. For compare-and-branch instructions which can only have 8-bit immediates this significantly changes the range of immediate values we can represent: [-128, 127] for signed comparisons and [0, 255] for unsigned comparisons. When generating equals and not equals checks we don't neet to worry about whether the comparison is signed or unsigned. This CL therefore adds rules to allow us to switch signedness for such comparisons if it means that it brings a constant into range for an 8-bit immediate. For example, a signed equals with an integer in the range [128, 255] will now be implemented using an unsigned compare-and-branch instruction rather than separate compare and branch instructions. As part of this change I've also added support for adding a name to block control values using the same `x:(...)` syntax we use for value rules. Triggers 792 times when compiling cmd and std. Change-Id: I77fa80a128f0a8ce51a2888d1e384bd5e9b61a77 Reviewed-on: https://go-review.googlesource.com/c/go/+/228642 Run-TryBot: Michael Munday <mike.munday@ibm.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
207 lines
4.1 KiB
Go
207 lines
4.1 KiB
Go
// asmcheck
|
|
|
|
// Copyright 2019 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.
|
|
|
|
package codegen
|
|
|
|
//go:noinline
|
|
func dummy() {}
|
|
|
|
// Signed 64-bit compare-and-branch.
|
|
func si64(x, y chan int64) {
|
|
// s390x:"CGRJ\t[$](2|4), R[0-9]+, R[0-9]+, "
|
|
for <-x < <-y {
|
|
dummy()
|
|
}
|
|
|
|
// s390x:"CL?GRJ\t[$]8, R[0-9]+, R[0-9]+, "
|
|
for <-x == <-y {
|
|
dummy()
|
|
}
|
|
}
|
|
|
|
// Signed 64-bit compare-and-branch with 8-bit immediate.
|
|
func si64x8() {
|
|
// s390x:"CGIJ\t[$]12, R[0-9]+, [$]127, "
|
|
for i := int64(0); i < 128; i++ {
|
|
dummy()
|
|
}
|
|
|
|
// s390x:"CGIJ\t[$]10, R[0-9]+, [$]-128, "
|
|
for i := int64(0); i > -129; i-- {
|
|
dummy()
|
|
}
|
|
|
|
// s390x:"CGIJ\t[$]2, R[0-9]+, [$]127, "
|
|
for i := int64(0); i >= 128; i++ {
|
|
dummy()
|
|
}
|
|
|
|
// s390x:"CGIJ\t[$]4, R[0-9]+, [$]-128, "
|
|
for i := int64(0); i <= -129; i-- {
|
|
dummy()
|
|
}
|
|
}
|
|
|
|
// Unsigned 64-bit compare-and-branch.
|
|
func ui64(x, y chan uint64) {
|
|
// s390x:"CLGRJ\t[$](2|4), R[0-9]+, R[0-9]+, "
|
|
for <-x > <-y {
|
|
dummy()
|
|
}
|
|
|
|
// s390x:"CL?GRJ\t[$]6, R[0-9]+, R[0-9]+, "
|
|
for <-x != <-y {
|
|
dummy()
|
|
}
|
|
}
|
|
|
|
// Unsigned 64-bit comparison with 8-bit immediate.
|
|
func ui64x8() {
|
|
// s390x:"CLGIJ\t[$]4, R[0-9]+, [$]128, "
|
|
for i := uint64(0); i < 128; i++ {
|
|
dummy()
|
|
}
|
|
|
|
// s390x:"CLGIJ\t[$]12, R[0-9]+, [$]255, "
|
|
for i := uint64(0); i < 256; i++ {
|
|
dummy()
|
|
}
|
|
|
|
// s390x:"CLGIJ\t[$]2, R[0-9]+, [$]255, "
|
|
for i := uint64(0); i >= 256; i-- {
|
|
dummy()
|
|
}
|
|
|
|
// s390x:"CLGIJ\t[$]2, R[0-9]+, [$]0, "
|
|
for i := uint64(1024); i > 0; i-- {
|
|
dummy()
|
|
}
|
|
}
|
|
|
|
// Signed 32-bit compare-and-branch.
|
|
func si32(x, y chan int32) {
|
|
// s390x:"CRJ\t[$](2|4), R[0-9]+, R[0-9]+, "
|
|
for <-x < <-y {
|
|
dummy()
|
|
}
|
|
|
|
// s390x:"CL?RJ\t[$]8, R[0-9]+, R[0-9]+, "
|
|
for <-x == <-y {
|
|
dummy()
|
|
}
|
|
}
|
|
|
|
// Signed 32-bit compare-and-branch with 8-bit immediate.
|
|
func si32x8() {
|
|
// s390x:"CIJ\t[$]12, R[0-9]+, [$]127, "
|
|
for i := int32(0); i < 128; i++ {
|
|
dummy()
|
|
}
|
|
|
|
// s390x:"CIJ\t[$]10, R[0-9]+, [$]-128, "
|
|
for i := int32(0); i > -129; i-- {
|
|
dummy()
|
|
}
|
|
|
|
// s390x:"CIJ\t[$]2, R[0-9]+, [$]127, "
|
|
for i := int32(0); i >= 128; i++ {
|
|
dummy()
|
|
}
|
|
|
|
// s390x:"CIJ\t[$]4, R[0-9]+, [$]-128, "
|
|
for i := int32(0); i <= -129; i-- {
|
|
dummy()
|
|
}
|
|
}
|
|
|
|
// Unsigned 32-bit compare-and-branch.
|
|
func ui32(x, y chan uint32) {
|
|
// s390x:"CLRJ\t[$](2|4), R[0-9]+, R[0-9]+, "
|
|
for <-x > <-y {
|
|
dummy()
|
|
}
|
|
|
|
// s390x:"CL?RJ\t[$]6, R[0-9]+, R[0-9]+, "
|
|
for <-x != <-y {
|
|
dummy()
|
|
}
|
|
}
|
|
|
|
// Unsigned 32-bit comparison with 8-bit immediate.
|
|
func ui32x8() {
|
|
// s390x:"CLIJ\t[$]4, R[0-9]+, [$]128, "
|
|
for i := uint32(0); i < 128; i++ {
|
|
dummy()
|
|
}
|
|
|
|
// s390x:"CLIJ\t[$]12, R[0-9]+, [$]255, "
|
|
for i := uint32(0); i < 256; i++ {
|
|
dummy()
|
|
}
|
|
|
|
// s390x:"CLIJ\t[$]2, R[0-9]+, [$]255, "
|
|
for i := uint32(0); i >= 256; i-- {
|
|
dummy()
|
|
}
|
|
|
|
// s390x:"CLIJ\t[$]2, R[0-9]+, [$]0, "
|
|
for i := uint32(1024); i > 0; i-- {
|
|
dummy()
|
|
}
|
|
}
|
|
|
|
// Signed 64-bit comparison with unsigned 8-bit immediate.
|
|
func si64xu8(x chan int64) {
|
|
// s390x:"CLGIJ\t[$]8, R[0-9]+, [$]128, "
|
|
for <-x == 128 {
|
|
dummy()
|
|
}
|
|
|
|
// s390x:"CLGIJ\t[$]6, R[0-9]+, [$]255, "
|
|
for <-x != 255 {
|
|
dummy()
|
|
}
|
|
}
|
|
|
|
// Signed 32-bit comparison with unsigned 8-bit immediate.
|
|
func si32xu8(x chan int32) {
|
|
// s390x:"CLIJ\t[$]8, R[0-9]+, [$]255, "
|
|
for <-x == 255 {
|
|
dummy()
|
|
}
|
|
|
|
// s390x:"CLIJ\t[$]6, R[0-9]+, [$]128, "
|
|
for <-x != 128 {
|
|
dummy()
|
|
}
|
|
}
|
|
|
|
// Unsigned 64-bit comparison with signed 8-bit immediate.
|
|
func ui64xu8(x chan uint64) {
|
|
// s390x:"CGIJ\t[$]8, R[0-9]+, [$]-1, "
|
|
for <-x == ^uint64(0) {
|
|
dummy()
|
|
}
|
|
|
|
// s390x:"CGIJ\t[$]6, R[0-9]+, [$]-128, "
|
|
for <-x != ^uint64(127) {
|
|
dummy()
|
|
}
|
|
}
|
|
|
|
// Unsigned 32-bit comparison with signed 8-bit immediate.
|
|
func ui32xu8(x chan uint32) {
|
|
// s390x:"CIJ\t[$]8, R[0-9]+, [$]-128, "
|
|
for <-x == ^uint32(127) {
|
|
dummy()
|
|
}
|
|
|
|
// s390x:"CIJ\t[$]6, R[0-9]+, [$]-1, "
|
|
for <-x != ^uint32(0) {
|
|
dummy()
|
|
}
|
|
}
|