| // asmcheck | |
| // Copyright 2020 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 | |
| import ( | |
| "math/bits" | |
| ) | |
| // This file contains codegen tests related to boolean simplifications/optimizations. | |
| func convertNeq0B(x uint8, c bool) bool { | |
| // amd64:"ANDL [$]1" -"SETNE" | |
| // ppc64x:"RLDICL" -"CMPW" -"ISEL" | |
| b := x&1 != 0 | |
| return c && b | |
| } | |
| func convertNeq0W(x uint16, c bool) bool { | |
| // amd64:"ANDL [$]1" -"SETNE" | |
| // ppc64x:"RLDICL" -"CMPW" -"ISEL" | |
| b := x&1 != 0 | |
| return c && b | |
| } | |
| func convertNeq0L(x uint32, c bool) bool { | |
| // amd64:"ANDL [$]1" -"SETB" | |
| // ppc64x:"RLDICL" -"CMPW" -"ISEL" | |
| b := x&1 != 0 | |
| return c && b | |
| } | |
| func convertNeq0Q(x uint64, c bool) bool { | |
| // amd64:"ANDL [$]1" -"SETB" | |
| // ppc64x:"RLDICL" -"CMP" -"ISEL" | |
| b := x&1 != 0 | |
| return c && b | |
| } | |
| func convertNeqBool32(x uint32) bool { | |
| // ppc64x:"RLDICL" -"CMPW" -"ISEL" | |
| return x&1 != 0 | |
| } | |
| func convertEqBool32(x uint32) bool { | |
| // ppc64x:"RLDICL" -"CMPW" "XOR" -"ISEL" | |
| // amd64:"ANDL" "XORL" -"BTL" -"SETCC" | |
| return x&1 == 0 | |
| } | |
| func convertNeqBool64(x uint64) bool { | |
| // ppc64x:"RLDICL" -"CMP" -"ISEL" | |
| return x&1 != 0 | |
| } | |
| func convertEqBool64(x uint64) bool { | |
| // ppc64x:"RLDICL" "XOR" -"CMP" -"ISEL" | |
| // amd64:"ANDL" "XORL" -"BTL" -"SETCC" | |
| return x&1 == 0 | |
| } | |
| func phiAnd(a, b bool) bool { | |
| var x bool | |
| // amd64:-"TESTB" | |
| if a { | |
| x = b | |
| } else { | |
| x = a | |
| } | |
| // amd64:"ANDL" | |
| return x | |
| } | |
| func phiOr(a, b bool) bool { | |
| var x bool | |
| // amd64:-"TESTB" | |
| if a { | |
| x = a | |
| } else { | |
| x = b | |
| } | |
| // amd64:"ORL" | |
| return x | |
| } | |
| func TestSetEq64(x uint64, y uint64) bool { | |
| // ppc64x/power10:"SETBC CR0EQ" -"ISEL" | |
| // ppc64x/power9:"CMP" "ISEL" -"SETBC CR0EQ" | |
| // ppc64x/power8:"CMP" "ISEL" -"SETBC CR0EQ" | |
| b := x == y | |
| return b | |
| } | |
| func TestSetNeq64(x uint64, y uint64) bool { | |
| // ppc64x/power10:"SETBCR CR0EQ" -"ISEL" | |
| // ppc64x/power9:"CMP" "ISEL" -"SETBCR CR0EQ" | |
| // ppc64x/power8:"CMP" "ISEL" -"SETBCR CR0EQ" | |
| b := x != y | |
| return b | |
| } | |
| func TestSetLt64(x uint64, y uint64) bool { | |
| // ppc64x/power10:"SETBC CR0GT" -"ISEL" | |
| // ppc64x/power9:"CMP" "ISEL" -"SETBC CR0GT" | |
| // ppc64x/power8:"CMP" "ISEL" -"SETBC CR0GT" | |
| b := x < y | |
| return b | |
| } | |
| func TestSetLe64(x uint64, y uint64) bool { | |
| // ppc64x/power10:"SETBCR CR0LT" -"ISEL" | |
| // ppc64x/power9:"CMP" "ISEL" -"SETBCR CR0LT" | |
| // ppc64x/power8:"CMP" "ISEL" -"SETBCR CR0LT" | |
| b := x <= y | |
| return b | |
| } | |
| func TestSetGt64(x uint64, y uint64) bool { | |
| // ppc64x/power10:"SETBC CR0LT" -"ISEL" | |
| // ppc64x/power9:"CMP" "ISEL" -"SETBC CR0LT" | |
| // ppc64x/power8:"CMP" "ISEL" -"SETBC CR0LT" | |
| b := x > y | |
| return b | |
| } | |
| func TestSetGe64(x uint64, y uint64) bool { | |
| // ppc64x/power10:"SETBCR CR0GT" -"ISEL" | |
| // ppc64x/power9:"CMP" "ISEL" -"SETBCR CR0GT" | |
| // ppc64x/power8:"CMP" "ISEL" -"SETBCR CR0GT" | |
| b := x >= y | |
| return b | |
| } | |
| func TestSetLtFp64(x float64, y float64) bool { | |
| // ppc64x/power10:"SETBC CR0LT" -"ISEL" | |
| // ppc64x/power9:"FCMP" "ISEL" -"SETBC CR0LT" | |
| // ppc64x/power8:"FCMP" "ISEL" -"SETBC CR0LT" | |
| b := x < y | |
| return b | |
| } | |
| func TestSetLeFp64(x float64, y float64) bool { | |
| // ppc64x/power10:"SETBC CR0LT" "SETBC CR0EQ" "OR" -"ISEL" -"ISEL" | |
| // ppc64x/power9:"ISEL" "ISEL" -"SETBC CR0LT" -"SETBC CR0EQ" "OR" | |
| // ppc64x/power8:"ISEL" "ISEL" -"SETBC CR0LT" -"SETBC CR0EQ" "OR" | |
| b := x <= y | |
| return b | |
| } | |
| func TestSetGtFp64(x float64, y float64) bool { | |
| // ppc64x/power10:"SETBC CR0LT" -"ISEL" | |
| // ppc64x/power9:"FCMP" "ISEL" -"SETBC CR0LT" | |
| // ppc64x/power8:"FCMP" "ISEL" -"SETBC CR0LT" | |
| b := x > y | |
| return b | |
| } | |
| func TestSetGeFp64(x float64, y float64) bool { | |
| // ppc64x/power10:"SETBC CR0LT" "SETBC CR0EQ" "OR" -"ISEL" -"ISEL" | |
| // ppc64x/power9:"ISEL" "ISEL" -"SETBC CR0LT" -"SETBC CR0EQ" "OR" | |
| // ppc64x/power8:"ISEL" "ISEL" -"SETBC CR0LT" -"SETBC CR0EQ" "OR" | |
| b := x >= y | |
| return b | |
| } | |
| func TestSetInvEq64(x uint64, y uint64) bool { | |
| // ppc64x/power10:"SETBCR CR0EQ" -"ISEL" | |
| // ppc64x/power9:"CMP" "ISEL" -"SETBCR CR0EQ" | |
| // ppc64x/power8:"CMP" "ISEL" -"SETBCR CR0EQ" | |
| b := !(x == y) | |
| return b | |
| } | |
| func TestSetInvNeq64(x uint64, y uint64) bool { | |
| // ppc64x/power10:"SETBC CR0EQ" -"ISEL" | |
| // ppc64x/power9:"CMP" "ISEL" -"SETBC CR0EQ" | |
| // ppc64x/power8:"CMP" "ISEL" -"SETBC CR0EQ" | |
| b := !(x != y) | |
| return b | |
| } | |
| func TestSetInvLt64(x uint64, y uint64) bool { | |
| // ppc64x/power10:"SETBCR CR0GT" -"ISEL" | |
| // ppc64x/power9:"CMP" "ISEL" -"SETBCR CR0GT" | |
| // ppc64x/power8:"CMP" "ISEL" -"SETBCR CR0GT" | |
| b := !(x < y) | |
| return b | |
| } | |
| func TestSetInvLe64(x uint64, y uint64) bool { | |
| // ppc64x/power10:"SETBC CR0LT" -"ISEL" | |
| // ppc64x/power9:"CMP" "ISEL" -"SETBC CR0LT" | |
| // ppc64x/power8:"CMP" "ISEL" -"SETBC CR0LT" | |
| b := !(x <= y) | |
| return b | |
| } | |
| func TestSetInvGt64(x uint64, y uint64) bool { | |
| // ppc64x/power10:"SETBCR CR0LT" -"ISEL" | |
| // ppc64x/power9:"CMP" "ISEL" -"SETBCR CR0LT" | |
| // ppc64x/power8:"CMP" "ISEL" -"SETBCR CR0LT" | |
| b := !(x > y) | |
| return b | |
| } | |
| func TestSetInvGe64(x uint64, y uint64) bool { | |
| // ppc64x/power10:"SETBC CR0GT" -"ISEL" | |
| // ppc64x/power9:"CMP" "ISEL" -"SETBC CR0GT" | |
| // ppc64x/power8:"CMP" "ISEL" -"SETBC CR0GT" | |
| b := !(x >= y) | |
| return b | |
| } | |
| func TestSetInvEqFp64(x float64, y float64) bool { | |
| // ppc64x/power10:"SETBCR CR0EQ" -"ISEL" | |
| // ppc64x/power9:"FCMP" "ISEL" -"SETBCR CR0EQ" | |
| // ppc64x/power8:"FCMP" "ISEL" -"SETBCR CR0EQ" | |
| b := !(x == y) | |
| return b | |
| } | |
| func TestSetInvNeqFp64(x float64, y float64) bool { | |
| // ppc64x/power10:"SETBC CR0EQ" -"ISEL" | |
| // ppc64x/power9:"FCMP" "ISEL" -"SETBC CR0EQ" | |
| // ppc64x/power8:"FCMP" "ISEL" -"SETBC CR0EQ" | |
| b := !(x != y) | |
| return b | |
| } | |
| func TestSetInvLtFp64(x float64, y float64) bool { | |
| // ppc64x/power10:"SETBCR CR0LT" -"ISEL" | |
| // ppc64x/power9:"FCMP" "ISEL" -"SETBCR CR0LT" | |
| // ppc64x/power8:"FCMP" "ISEL" -"SETBCR CR0LT" | |
| b := !(x < y) | |
| return b | |
| } | |
| func TestSetInvLeFp64(x float64, y float64) bool { | |
| // ppc64x/power10:"SETBC CR0LT" -"ISEL" | |
| // ppc64x/power9:"FCMP" "ISEL" -"SETBC CR0LT" | |
| // ppc64x/power8:"FCMP" "ISEL" -"SETBC CR0LT" | |
| b := !(x <= y) | |
| return b | |
| } | |
| func TestSetInvGtFp64(x float64, y float64) bool { | |
| // ppc64x/power10:"SETBCR CR0LT" -"ISEL" | |
| // ppc64x/power9:"FCMP" "ISEL" -"SETBCR CR0LT" | |
| // ppc64x/power8:"FCMP" "ISEL" -"SETBCR CR0LT" | |
| b := !(x > y) | |
| return b | |
| } | |
| func TestSetInvGeFp64(x float64, y float64) bool { | |
| // ppc64x/power10:"SETBC CR0LT" -"ISEL" | |
| // ppc64x/power9:"FCMP" "ISEL" -"SETBC CR0LT" | |
| // ppc64x/power8:"FCMP" "ISEL" -"SETBC CR0LT" | |
| b := !(x >= y) | |
| return b | |
| } | |
| func TestLogicalCompareZero(x *[64]uint64) { | |
| // ppc64x:"ANDCC",^"AND" | |
| b := x[0] & 3 | |
| if b != 0 { | |
| x[0] = b | |
| } | |
| // ppc64x:"ANDCC",^"AND" | |
| b = x[1] & x[2] | |
| if b != 0 { | |
| x[1] = b | |
| } | |
| // ppc64x:"ANDNCC",^"ANDN" | |
| b = x[1] &^ x[2] | |
| if b != 0 { | |
| x[1] = b | |
| } | |
| // ppc64x:"ORCC",^"OR" | |
| b = x[3] | x[4] | |
| if b != 0 { | |
| x[3] = b | |
| } | |
| // ppc64x:"SUBCC",^"SUB" | |
| b = x[5] - x[6] | |
| if b != 0 { | |
| x[5] = b | |
| } | |
| // ppc64x:"NORCC",^"NOR" | |
| b = ^(x[5] | x[6]) | |
| if b != 0 { | |
| x[5] = b | |
| } | |
| // ppc64x:"XORCC",^"XOR" | |
| b = x[7] ^ x[8] | |
| if b != 0 { | |
| x[7] = b | |
| } | |
| // ppc64x:"ADDCC",^"ADD" | |
| b = x[9] + x[10] | |
| if b != 0 { | |
| x[9] = b | |
| } | |
| // ppc64x:"NEGCC",^"NEG" | |
| b = -x[11] | |
| if b != 0 { | |
| x[11] = b | |
| } | |
| // ppc64x:"CNTLZDCC",^"CNTLZD" | |
| b = uint64(bits.LeadingZeros64(x[12])) | |
| if b != 0 { | |
| x[12] = b | |
| } | |
| // ppc64x:"ADDCCC [$]4," | |
| c := int64(x[12]) + 4 | |
| if c <= 0 { | |
| x[12] = uint64(c) | |
| } | |
| // ppc64x:"MULHDUCC",^"MULHDU" | |
| hi, _ := bits.Mul64(x[13], x[14]) | |
| if hi != 0 { | |
| x[14] = hi | |
| } | |
| } | |
| func constantWrite(b bool, p *bool) { | |
| if b { | |
| // amd64:`MOVB [$]1, \(` | |
| *p = b | |
| } | |
| } | |
| func boolCompare1(p, q *bool) int { | |
| // arm64:-"EOR [$]1" | |
| if *p == *q { | |
| return 5 | |
| } | |
| return 7 | |
| } | |
| func boolCompare2(p, q *bool) int { | |
| // arm64:-"EOR [$]1" | |
| if *p != *q { | |
| return 5 | |
| } | |
| return 7 | |
| } | |