1// asmcheck
2
3// Copyright 2020 The Go Authors. All rights reserved.
4// Use of this source code is governed by a BSD-style
5// license that can be found in the LICENSE file.
6
7package codegen
8
9import (
10	"math/bits"
11)
12
13// This file contains codegen tests related to boolean simplifications/optimizations.
14
15func convertNeq0B(x uint8, c bool) bool {
16	// amd64:"ANDL\t[$]1",-"SETNE"
17	// ppc64x:"RLDICL",-"CMPW",-"ISEL"
18	b := x&1 != 0
19	return c && b
20}
21
22func convertNeq0W(x uint16, c bool) bool {
23	// amd64:"ANDL\t[$]1",-"SETNE"
24	// ppc64x:"RLDICL",-"CMPW",-"ISEL"
25	b := x&1 != 0
26	return c && b
27}
28
29func convertNeq0L(x uint32, c bool) bool {
30	// amd64:"ANDL\t[$]1",-"SETB"
31	// ppc64x:"RLDICL",-"CMPW",-"ISEL"
32	b := x&1 != 0
33	return c && b
34}
35
36func convertNeq0Q(x uint64, c bool) bool {
37	// amd64:"ANDL\t[$]1",-"SETB"
38	// ppc64x:"RLDICL",-"CMP",-"ISEL"
39	b := x&1 != 0
40	return c && b
41}
42
43func convertNeqBool32(x uint32) bool {
44	// ppc64x:"RLDICL",-"CMPW",-"ISEL"
45	return x&1 != 0
46}
47
48func convertEqBool32(x uint32) bool {
49	// ppc64x:"RLDICL",-"CMPW","XOR",-"ISEL"
50	return x&1 == 0
51}
52
53func convertNeqBool64(x uint64) bool {
54	// ppc64x:"RLDICL",-"CMP",-"ISEL"
55	return x&1 != 0
56}
57
58func convertEqBool64(x uint64) bool {
59	// ppc64x:"RLDICL","XOR",-"CMP",-"ISEL"
60	return x&1 == 0
61}
62
63func TestSetEq64(x uint64, y uint64) bool {
64	// ppc64x/power10:"SETBC\tCR0EQ",-"ISEL"
65	// ppc64x/power9:"CMP","ISEL",-"SETBC\tCR0EQ"
66	// ppc64x/power8:"CMP","ISEL",-"SETBC\tCR0EQ"
67	b := x == y
68	return b
69}
70func TestSetNeq64(x uint64, y uint64) bool {
71	// ppc64x/power10:"SETBCR\tCR0EQ",-"ISEL"
72	// ppc64x/power9:"CMP","ISEL",-"SETBCR\tCR0EQ"
73	// ppc64x/power8:"CMP","ISEL",-"SETBCR\tCR0EQ"
74	b := x != y
75	return b
76}
77func TestSetLt64(x uint64, y uint64) bool {
78	// ppc64x/power10:"SETBC\tCR0GT",-"ISEL"
79	// ppc64x/power9:"CMP","ISEL",-"SETBC\tCR0GT"
80	// ppc64x/power8:"CMP","ISEL",-"SETBC\tCR0GT"
81	b := x < y
82	return b
83}
84func TestSetLe64(x uint64, y uint64) bool {
85	// ppc64x/power10:"SETBCR\tCR0LT",-"ISEL"
86	// ppc64x/power9:"CMP","ISEL",-"SETBCR\tCR0LT"
87	// ppc64x/power8:"CMP","ISEL",-"SETBCR\tCR0LT"
88	b := x <= y
89	return b
90}
91func TestSetGt64(x uint64, y uint64) bool {
92	// ppc64x/power10:"SETBC\tCR0LT",-"ISEL"
93	// ppc64x/power9:"CMP","ISEL",-"SETBC\tCR0LT"
94	// ppc64x/power8:"CMP","ISEL",-"SETBC\tCR0LT"
95	b := x > y
96	return b
97}
98func TestSetGe64(x uint64, y uint64) bool {
99	// ppc64x/power10:"SETBCR\tCR0GT",-"ISEL"
100	// ppc64x/power9:"CMP","ISEL",-"SETBCR\tCR0GT"
101	// ppc64x/power8:"CMP","ISEL",-"SETBCR\tCR0GT"
102	b := x >= y
103	return b
104}
105func TestSetLtFp64(x float64, y float64) bool {
106	// ppc64x/power10:"SETBC\tCR0LT",-"ISEL"
107	// ppc64x/power9:"FCMP","ISEL",-"SETBC\tCR0LT"
108	// ppc64x/power8:"FCMP","ISEL",-"SETBC\tCR0LT"
109	b := x < y
110	return b
111}
112func TestSetLeFp64(x float64, y float64) bool {
113	// ppc64x/power10:"SETBC\tCR0LT","SETBC\tCR0EQ","OR",-"ISEL",-"ISEL"
114	// ppc64x/power9:"ISEL","ISEL",-"SETBC\tCR0LT",-"SETBC\tCR0EQ","OR"
115	// ppc64x/power8:"ISEL","ISEL",-"SETBC\tCR0LT",-"SETBC\tCR0EQ","OR"
116	b := x <= y
117	return b
118}
119func TestSetGtFp64(x float64, y float64) bool {
120	// ppc64x/power10:"SETBC\tCR0LT",-"ISEL"
121	// ppc64x/power9:"FCMP","ISEL",-"SETBC\tCR0LT"
122	// ppc64x/power8:"FCMP","ISEL",-"SETBC\tCR0LT"
123	b := x > y
124	return b
125}
126func TestSetGeFp64(x float64, y float64) bool {
127	// ppc64x/power10:"SETBC\tCR0LT","SETBC\tCR0EQ","OR",-"ISEL",-"ISEL"
128	// ppc64x/power9:"ISEL","ISEL",-"SETBC\tCR0LT",-"SETBC\tCR0EQ","OR"
129	// ppc64x/power8:"ISEL","ISEL",-"SETBC\tCR0LT",-"SETBC\tCR0EQ","OR"
130	b := x >= y
131	return b
132}
133func TestSetInvEq64(x uint64, y uint64) bool {
134	// ppc64x/power10:"SETBCR\tCR0EQ",-"ISEL"
135	// ppc64x/power9:"CMP","ISEL",-"SETBCR\tCR0EQ"
136	// ppc64x/power8:"CMP","ISEL",-"SETBCR\tCR0EQ"
137	b := !(x == y)
138	return b
139}
140func TestSetInvNeq64(x uint64, y uint64) bool {
141	// ppc64x/power10:"SETBC\tCR0EQ",-"ISEL"
142	// ppc64x/power9:"CMP","ISEL",-"SETBC\tCR0EQ"
143	// ppc64x/power8:"CMP","ISEL",-"SETBC\tCR0EQ"
144	b := !(x != y)
145	return b
146}
147func TestSetInvLt64(x uint64, y uint64) bool {
148	// ppc64x/power10:"SETBCR\tCR0GT",-"ISEL"
149	// ppc64x/power9:"CMP","ISEL",-"SETBCR\tCR0GT"
150	// ppc64x/power8:"CMP","ISEL",-"SETBCR\tCR0GT"
151	b := !(x < y)
152	return b
153}
154func TestSetInvLe64(x uint64, y uint64) bool {
155	// ppc64x/power10:"SETBC\tCR0LT",-"ISEL"
156	// ppc64x/power9:"CMP","ISEL",-"SETBC\tCR0LT"
157	// ppc64x/power8:"CMP","ISEL",-"SETBC\tCR0LT"
158	b := !(x <= y)
159	return b
160}
161func TestSetInvGt64(x uint64, y uint64) bool {
162	// ppc64x/power10:"SETBCR\tCR0LT",-"ISEL"
163	// ppc64x/power9:"CMP","ISEL",-"SETBCR\tCR0LT"
164	// ppc64x/power8:"CMP","ISEL",-"SETBCR\tCR0LT"
165	b := !(x > y)
166	return b
167}
168func TestSetInvGe64(x uint64, y uint64) bool {
169	// ppc64x/power10:"SETBC\tCR0GT",-"ISEL"
170	// ppc64x/power9:"CMP","ISEL",-"SETBC\tCR0GT"
171	// ppc64x/power8:"CMP","ISEL",-"SETBC\tCR0GT"
172	b := !(x >= y)
173	return b
174}
175
176func TestSetInvEqFp64(x float64, y float64) bool {
177	// ppc64x/power10:"SETBCR\tCR0EQ",-"ISEL"
178	// ppc64x/power9:"FCMP","ISEL",-"SETBCR\tCR0EQ"
179	// ppc64x/power8:"FCMP","ISEL",-"SETBCR\tCR0EQ"
180	b := !(x == y)
181	return b
182}
183func TestSetInvNeqFp64(x float64, y float64) bool {
184	// ppc64x/power10:"SETBC\tCR0EQ",-"ISEL"
185	// ppc64x/power9:"FCMP","ISEL",-"SETBC\tCR0EQ"
186	// ppc64x/power8:"FCMP","ISEL",-"SETBC\tCR0EQ"
187	b := !(x != y)
188	return b
189}
190func TestSetInvLtFp64(x float64, y float64) bool {
191	// ppc64x/power10:"SETBCR\tCR0LT",-"ISEL"
192	// ppc64x/power9:"FCMP","ISEL",-"SETBCR\tCR0LT"
193	// ppc64x/power8:"FCMP","ISEL",-"SETBCR\tCR0LT"
194	b := !(x < y)
195	return b
196}
197func TestSetInvLeFp64(x float64, y float64) bool {
198	// ppc64x/power10:"SETBC\tCR0LT",-"ISEL"
199	// ppc64x/power9:"FCMP","ISEL",-"SETBC\tCR0LT"
200	// ppc64x/power8:"FCMP","ISEL",-"SETBC\tCR0LT"
201	b := !(x <= y)
202	return b
203}
204func TestSetInvGtFp64(x float64, y float64) bool {
205	// ppc64x/power10:"SETBCR\tCR0LT",-"ISEL"
206	// ppc64x/power9:"FCMP","ISEL",-"SETBCR\tCR0LT"
207	// ppc64x/power8:"FCMP","ISEL",-"SETBCR\tCR0LT"
208	b := !(x > y)
209	return b
210}
211func TestSetInvGeFp64(x float64, y float64) bool {
212	// ppc64x/power10:"SETBC\tCR0LT",-"ISEL"
213	// ppc64x/power9:"FCMP","ISEL",-"SETBC\tCR0LT"
214	// ppc64x/power8:"FCMP","ISEL",-"SETBC\tCR0LT"
215	b := !(x >= y)
216	return b
217}
218func TestLogicalCompareZero(x *[64]uint64) {
219	// ppc64x:"ANDCC",^"AND"
220	b := x[0]&3
221	if b!=0 {
222		x[0] = b
223	}
224	// ppc64x:"ANDCC",^"AND"
225	b = x[1]&x[2]
226	if b!=0 {
227		x[1] = b
228	}
229	// ppc64x:"ANDNCC",^"ANDN"
230	b = x[1]&^x[2]
231	if b!=0 {
232		x[1] = b
233	}
234	// ppc64x:"ORCC",^"OR"
235	b = x[3]|x[4]
236	if b!=0 {
237		x[3] = b
238	}
239	// ppc64x:"SUBCC",^"SUB"
240	b = x[5]-x[6]
241	if b!=0 {
242		x[5] = b
243	}
244	// ppc64x:"NORCC",^"NOR"
245	b = ^(x[5]|x[6])
246	if b!=0 {
247		x[5] = b
248	}
249	// ppc64x:"XORCC",^"XOR"
250	b = x[7]^x[8]
251	if b!=0 {
252		x[7] = b
253	}
254	// ppc64x:"ADDCC",^"ADD"
255	b = x[9]+x[10]
256	if b!=0 {
257		x[9] = b
258	}
259	// ppc64x:"NEGCC",^"NEG"
260	b = -x[11]
261	if b!=0 {
262		x[11] = b
263	}
264	// ppc64x:"CNTLZDCC",^"CNTLZD"
265	b = uint64(bits.LeadingZeros64(x[12]))
266	if b!=0 {
267		x[12] = b
268	}
269
270	// ppc64x:"ADDCCC\t[$]4,"
271	c := int64(x[12]) + 4
272	if c <= 0 {
273		x[12] = uint64(c)
274	}
275
276}
277