]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/riscv/bitmanip.md
RISC-V: split to allow formation of sh[123]add before 32bit divw
[thirdparty/gcc.git] / gcc / config / riscv / bitmanip.md
1 ;; Machine description for RISC-V Bit Manipulation operations.
2 ;; Copyright (C) 2021-2022 Free Software Foundation, Inc.
3
4 ;; This file is part of GCC.
5
6 ;; GCC is free software; you can redistribute it and/or modify
7 ;; it under the terms of the GNU General Public License as published by
8 ;; the Free Software Foundation; either version 3, or (at your option)
9 ;; any later version.
10
11 ;; GCC is distributed in the hope that it will be useful,
12 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 ;; GNU General Public License for more details.
15
16 ;; You should have received a copy of the GNU General Public License
17 ;; along with GCC; see the file COPYING3. If not see
18 ;; <http://www.gnu.org/licenses/>.
19
20 ;; ZBA extension.
21
22 (define_insn "*zero_extendsidi2_bitmanip"
23 [(set (match_operand:DI 0 "register_operand" "=r,r")
24 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
25 "TARGET_64BIT && TARGET_ZBA"
26 "@
27 zext.w\t%0,%1
28 lwu\t%0,%1"
29 [(set_attr "type" "bitmanip,load")
30 (set_attr "mode" "DI")])
31
32 (define_insn "*shNadd"
33 [(set (match_operand:X 0 "register_operand" "=r")
34 (plus:X (ashift:X (match_operand:X 1 "register_operand" "r")
35 (match_operand:QI 2 "imm123_operand" "Ds3"))
36 (match_operand:X 3 "register_operand" "r")))]
37 "TARGET_ZBA"
38 "sh%2add\t%0,%1,%3"
39 [(set_attr "type" "bitmanip")
40 (set_attr "mode" "<X:MODE>")])
41
42 ; When using strength-reduction, we will reduce a multiplication to a
43 ; sequence of shifts and adds. If this is performed with 32-bit types
44 ; and followed by a division, the lack of w-form sh[123]add will make
45 ; combination impossible and lead to a slli + addw being generated.
46 ; Split the sequence with the knowledge that a w-form div will perform
47 ; implicit sign-extensions.
48 (define_split
49 [(set (match_operand:DI 0 "register_operand")
50 (sign_extend:DI (div:SI (plus:SI (subreg:SI (ashift:DI (match_operand:DI 1 "register_operand")
51 (match_operand:QI 2 "imm123_operand")) 0)
52 (subreg:SI (match_operand:DI 3 "register_operand") 0))
53 (subreg:SI (match_operand:DI 4 "register_operand") 0))))
54 (clobber (match_operand:DI 5 "register_operand"))]
55 "TARGET_64BIT && TARGET_ZBA"
56 [(set (match_dup 5) (plus:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))
57 (set (match_dup 0) (sign_extend:DI (div:SI (subreg:SI (match_dup 5) 0) (subreg:SI (match_dup 4) 0))))])
58
59 (define_insn "*shNadduw"
60 [(set (match_operand:DI 0 "register_operand" "=r")
61 (plus:DI
62 (and:DI (ashift:DI (match_operand:DI 1 "register_operand" "r")
63 (match_operand:QI 2 "imm123_operand" "Ds3"))
64 (match_operand 3 "immediate_operand" "n"))
65 (match_operand:DI 4 "register_operand" "r")))]
66 "TARGET_64BIT && TARGET_ZBA
67 && (INTVAL (operands[3]) >> INTVAL (operands[2])) == 0xffffffff"
68 "sh%2add.uw\t%0,%1,%4"
69 [(set_attr "type" "bitmanip")
70 (set_attr "mode" "DI")])
71
72 ;; During combine, we may encounter an attempt to combine
73 ;; slli rtmp, rs, #imm
74 ;; zext.w rtmp, rtmp
75 ;; sh[123]add rd, rtmp, rs2
76 ;; which will lead to the immediate not satisfying the above constraints.
77 ;; By splitting the compound expression, we can simplify to a slli and a
78 ;; sh[123]add.uw.
79 (define_split
80 [(set (match_operand:DI 0 "register_operand")
81 (plus:DI (and:DI (ashift:DI (match_operand:DI 1 "register_operand")
82 (match_operand:QI 2 "immediate_operand"))
83 (match_operand:DI 3 "consecutive_bits_operand"))
84 (match_operand:DI 4 "register_operand")))
85 (clobber (match_operand:DI 5 "register_operand"))]
86 "TARGET_64BIT && TARGET_ZBA"
87 [(set (match_dup 5) (ashift:DI (match_dup 1) (match_dup 6)))
88 (set (match_dup 0) (plus:DI (and:DI (ashift:DI (match_dup 5)
89 (match_dup 7))
90 (match_dup 8))
91 (match_dup 4)))]
92 {
93 unsigned HOST_WIDE_INT mask = UINTVAL (operands[3]);
94 /* scale: shift within the sh[123]add.uw */
95 unsigned HOST_WIDE_INT scale = 32 - clz_hwi (mask);
96 /* bias: pre-scale amount (i.e. the prior shift amount) */
97 int bias = ctz_hwi (mask) - scale;
98
99 /* If the bias + scale don't add up to operand[2], reject. */
100 if ((scale + bias) != UINTVAL (operands[2]))
101 FAIL;
102
103 /* If the shift-amount is out-of-range for sh[123]add.uw, reject. */
104 if ((scale < 1) || (scale > 3))
105 FAIL;
106
107 /* If there's no bias, the '*shNadduw' pattern should have matched. */
108 if (bias == 0)
109 FAIL;
110
111 operands[6] = GEN_INT (bias);
112 operands[7] = GEN_INT (scale);
113 operands[8] = GEN_INT (0xffffffffULL << scale);
114 })
115
116 (define_insn "*add.uw"
117 [(set (match_operand:DI 0 "register_operand" "=r")
118 (plus:DI (zero_extend:DI
119 (match_operand:SI 1 "register_operand" "r"))
120 (match_operand:DI 2 "register_operand" "r")))]
121 "TARGET_64BIT && TARGET_ZBA"
122 "add.uw\t%0,%1,%2"
123 [(set_attr "type" "bitmanip")
124 (set_attr "mode" "DI")])
125
126 (define_insn "*slliuw"
127 [(set (match_operand:DI 0 "register_operand" "=r")
128 (and:DI (ashift:DI (match_operand:DI 1 "register_operand" "r")
129 (match_operand:QI 2 "immediate_operand" "I"))
130 (match_operand 3 "immediate_operand" "n")))]
131 "TARGET_64BIT && TARGET_ZBA
132 && (INTVAL (operands[3]) >> INTVAL (operands[2])) == 0xffffffff"
133 "slli.uw\t%0,%1,%2"
134 [(set_attr "type" "bitmanip")
135 (set_attr "mode" "DI")])
136
137 ;; ZBB extension.
138
139 (define_insn "*<optab>_not<mode>"
140 [(set (match_operand:X 0 "register_operand" "=r")
141 (bitmanip_bitwise:X (not:X (match_operand:X 1 "register_operand" "r"))
142 (match_operand:X 2 "register_operand" "r")))]
143 "TARGET_ZBB"
144 "<insn>n\t%0,%2,%1"
145 [(set_attr "type" "bitmanip")
146 (set_attr "mode" "<X:MODE>")])
147
148 ;; '(a >= 0) ? b : 0' is emitted branchless (from if-conversion). Without a
149 ;; bit of extra help for combine (i.e., the below split), we end up emitting
150 ;; not/srai/and instead of combining the not into an andn.
151 (define_split
152 [(set (match_operand:DI 0 "register_operand")
153 (and:DI (neg:DI (ge:DI (match_operand:DI 1 "register_operand")
154 (const_int 0)))
155 (match_operand:DI 2 "register_operand")))
156 (clobber (match_operand:DI 3 "register_operand"))]
157 "TARGET_ZBB"
158 [(set (match_dup 3) (ashiftrt:DI (match_dup 1) (const_int 63)))
159 (set (match_dup 0) (and:DI (not:DI (match_dup 3)) (match_dup 2)))])
160
161 (define_insn "*xor_not<mode>"
162 [(set (match_operand:X 0 "register_operand" "=r")
163 (not:X (xor:X (match_operand:X 1 "register_operand" "r")
164 (match_operand:X 2 "register_operand" "r"))))]
165 "TARGET_ZBB"
166 "xnor\t%0,%1,%2"
167 [(set_attr "type" "bitmanip")
168 (set_attr "mode" "<X:MODE>")])
169
170 (define_insn "<bitmanip_optab>si2"
171 [(set (match_operand:SI 0 "register_operand" "=r")
172 (clz_ctz_pcnt:SI (match_operand:SI 1 "register_operand" "r")))]
173 "TARGET_ZBB"
174 "<bitmanip_insn>%~\t%0,%1"
175 [(set_attr "type" "bitmanip")
176 (set_attr "mode" "SI")])
177
178 (define_insn "*<bitmanip_optab>disi2"
179 [(set (match_operand:DI 0 "register_operand" "=r")
180 (sign_extend:DI
181 (clz_ctz_pcnt:SI (match_operand:SI 1 "register_operand" "r"))))]
182 "TARGET_64BIT && TARGET_ZBB"
183 "<bitmanip_insn>w\t%0,%1"
184 [(set_attr "type" "bitmanip")
185 (set_attr "mode" "SI")])
186
187 (define_insn "<bitmanip_optab>di2"
188 [(set (match_operand:DI 0 "register_operand" "=r")
189 (clz_ctz_pcnt:DI (match_operand:DI 1 "register_operand" "r")))]
190 "TARGET_64BIT && TARGET_ZBB"
191 "<bitmanip_insn>\t%0,%1"
192 [(set_attr "type" "bitmanip")
193 (set_attr "mode" "DI")])
194
195 (define_insn "*zero_extendhi<GPR:mode>2_bitmanip"
196 [(set (match_operand:GPR 0 "register_operand" "=r,r")
197 (zero_extend:GPR (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
198 "TARGET_ZBB"
199 "@
200 zext.h\t%0,%1
201 lhu\t%0,%1"
202 [(set_attr "type" "bitmanip,load")
203 (set_attr "mode" "<GPR:MODE>")])
204
205 (define_insn "*extend<SHORT:mode><SUPERQI:mode>2_zbb"
206 [(set (match_operand:SUPERQI 0 "register_operand" "=r,r")
207 (sign_extend:SUPERQI
208 (match_operand:SHORT 1 "nonimmediate_operand" " r,m")))]
209 "TARGET_ZBB"
210 "@
211 sext.<SHORT:size>\t%0,%1
212 l<SHORT:size>\t%0,%1"
213 [(set_attr "type" "bitmanip,load")
214 (set_attr "mode" "<SUPERQI:MODE>")])
215
216 (define_insn "*zero_extendhi<GPR:mode>2_zbb"
217 [(set (match_operand:GPR 0 "register_operand" "=r,r")
218 (zero_extend:GPR
219 (match_operand:HI 1 "nonimmediate_operand" " r,m")))]
220 "TARGET_ZBB"
221 "@
222 zext.h\t%0,%1
223 lhu\t%0,%1"
224 [(set_attr "type" "bitmanip,load")
225 (set_attr "mode" "HI")])
226
227 (define_insn "rotrsi3"
228 [(set (match_operand:SI 0 "register_operand" "=r")
229 (rotatert:SI (match_operand:SI 1 "register_operand" "r")
230 (match_operand:QI 2 "arith_operand" "rI")))]
231 "TARGET_ZBB"
232 "ror%i2%~\t%0,%1,%2"
233 [(set_attr "type" "bitmanip")])
234
235 (define_insn "rotrdi3"
236 [(set (match_operand:DI 0 "register_operand" "=r")
237 (rotatert:DI (match_operand:DI 1 "register_operand" "r")
238 (match_operand:QI 2 "arith_operand" "rI")))]
239 "TARGET_64BIT && TARGET_ZBB"
240 "ror%i2\t%0,%1,%2"
241 [(set_attr "type" "bitmanip")])
242
243 (define_insn "rotrsi3_sext"
244 [(set (match_operand:DI 0 "register_operand" "=r")
245 (sign_extend:DI (rotatert:SI (match_operand:SI 1 "register_operand" "r")
246 (match_operand:QI 2 "register_operand" "r"))))]
247 "TARGET_64BIT && TARGET_ZBB"
248 "rorw\t%0,%1,%2"
249 [(set_attr "type" "bitmanip")])
250
251 (define_insn "rotlsi3"
252 [(set (match_operand:SI 0 "register_operand" "=r")
253 (rotate:SI (match_operand:SI 1 "register_operand" "r")
254 (match_operand:QI 2 "register_operand" "r")))]
255 "TARGET_ZBB"
256 "rol%~\t%0,%1,%2"
257 [(set_attr "type" "bitmanip")])
258
259 (define_insn "rotldi3"
260 [(set (match_operand:DI 0 "register_operand" "=r")
261 (rotate:DI (match_operand:DI 1 "register_operand" "r")
262 (match_operand:QI 2 "register_operand" "r")))]
263 "TARGET_64BIT && TARGET_ZBB"
264 "rol\t%0,%1,%2"
265 [(set_attr "type" "bitmanip")])
266
267 (define_insn "rotlsi3_sext"
268 [(set (match_operand:DI 0 "register_operand" "=r")
269 (sign_extend:DI (rotate:SI (match_operand:SI 1 "register_operand" "r")
270 (match_operand:QI 2 "register_operand" "r"))))]
271 "TARGET_64BIT && TARGET_ZBB"
272 "rolw\t%0,%1,%2"
273 [(set_attr "type" "bitmanip")])
274
275 ;; orc.b (or-combine) is added as an unspec for the benefit of the support
276 ;; for optimized string functions (such as strcmp).
277 (define_insn "orcb<mode>2"
278 [(set (match_operand:X 0 "register_operand" "=r")
279 (unspec:X [(match_operand:X 1 "register_operand" "r")] UNSPEC_ORC_B))]
280 "TARGET_ZBB"
281 "orc.b\t%0,%1")
282
283 (define_insn "bswap<mode>2"
284 [(set (match_operand:X 0 "register_operand" "=r")
285 (bswap:X (match_operand:X 1 "register_operand" "r")))]
286 "TARGET_ZBB"
287 "rev8\t%0,%1"
288 [(set_attr "type" "bitmanip")])
289
290 ;; HI bswap can be emulated using SI/DI bswap followed
291 ;; by a logical shift right
292 ;; SI bswap for TARGET_64BIT is already similarly in
293 ;; the common code.
294 (define_expand "bswaphi2"
295 [(set (match_operand:HI 0 "register_operand" "=r")
296 (bswap:HI (match_operand:HI 1 "register_operand" "r")))]
297 "TARGET_ZBB"
298 {
299 rtx tmp = gen_reg_rtx (word_mode);
300 rtx newop1 = gen_lowpart (word_mode, operands[1]);
301 if (TARGET_64BIT)
302 emit_insn (gen_bswapdi2 (tmp, newop1));
303 else
304 emit_insn (gen_bswapsi2 (tmp, newop1));
305 rtx tmp1 = gen_reg_rtx (word_mode);
306 if (TARGET_64BIT)
307 emit_insn (gen_lshrdi3 (tmp1, tmp, GEN_INT (64 - 16)));
308 else
309 emit_insn (gen_lshrsi3 (tmp1, tmp, GEN_INT (32 - 16)));
310 emit_move_insn (operands[0], gen_lowpart (HImode, tmp1));
311 DONE;
312 })
313
314 (define_insn "<bitmanip_optab><mode>3"
315 [(set (match_operand:X 0 "register_operand" "=r")
316 (bitmanip_minmax:X (match_operand:X 1 "register_operand" "r")
317 (match_operand:X 2 "register_operand" "r")))]
318 "TARGET_ZBB"
319 "<bitmanip_insn>\t%0,%1,%2"
320 [(set_attr "type" "bitmanip")])
321
322 ;; ZBS extension.
323
324 (define_insn "*bset<mode>"
325 [(set (match_operand:X 0 "register_operand" "=r")
326 (ior:X (ashift:X (const_int 1)
327 (match_operand:QI 2 "register_operand" "r"))
328 (match_operand:X 1 "register_operand" "r")))]
329 "TARGET_ZBS"
330 "bset\t%0,%1,%2"
331 [(set_attr "type" "bitmanip")])
332
333 (define_insn "*bset<mode>_mask"
334 [(set (match_operand:X 0 "register_operand" "=r")
335 (ior:X (ashift:X (const_int 1)
336 (subreg:QI
337 (and:X (match_operand:X 2 "register_operand" "r")
338 (match_operand 3 "<X:shiftm1>" "<X:shiftm1p>")) 0))
339 (match_operand:X 1 "register_operand" "r")))]
340 "TARGET_ZBS"
341 "bset\t%0,%1,%2"
342 [(set_attr "type" "bitmanip")])
343
344 (define_insn "*bset<mode>_1"
345 [(set (match_operand:X 0 "register_operand" "=r")
346 (ashift:X (const_int 1)
347 (match_operand:QI 1 "register_operand" "r")))]
348 "TARGET_ZBS"
349 "bset\t%0,x0,%1"
350 [(set_attr "type" "bitmanip")])
351
352 (define_insn "*bset<mode>_1_mask"
353 [(set (match_operand:X 0 "register_operand" "=r")
354 (ashift:X (const_int 1)
355 (subreg:QI
356 (and:X (match_operand:X 1 "register_operand" "r")
357 (match_operand 2 "<X:shiftm1>" "<X:shiftm1p>")) 0)))]
358 "TARGET_ZBS"
359 "bset\t%0,x0,%1"
360 [(set_attr "type" "bitmanip")])
361
362 (define_insn "*bseti<mode>"
363 [(set (match_operand:X 0 "register_operand" "=r")
364 (ior:X (match_operand:X 1 "register_operand" "r")
365 (match_operand:X 2 "single_bit_mask_operand" "DbS")))]
366 "TARGET_ZBS"
367 "bseti\t%0,%1,%S2"
368 [(set_attr "type" "bitmanip")])
369
370 ;; As long as the SImode operand is not a partial subreg, we can use a
371 ;; bseti without postprocessing, as the middle end is smart enough to
372 ;; stay away from the signbit.
373 (define_insn "*bsetidisi"
374 [(set (match_operand:DI 0 "register_operand" "=r")
375 (ior:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
376 (match_operand 2 "single_bit_mask_operand" "i")))]
377 "TARGET_ZBS && TARGET_64BIT
378 && !partial_subreg_p (operands[2])"
379 "bseti\t%0,%1,%S2"
380 [(set_attr "type" "bitmanip")])
381
382 (define_insn "*bclr<mode>"
383 [(set (match_operand:X 0 "register_operand" "=r")
384 (and:X (rotate:X (const_int -2)
385 (match_operand:QI 2 "register_operand" "r"))
386 (match_operand:X 1 "register_operand" "r")))]
387 "TARGET_ZBS"
388 "bclr\t%0,%1,%2"
389 [(set_attr "type" "bitmanip")])
390
391 (define_insn "*bclri<mode>"
392 [(set (match_operand:X 0 "register_operand" "=r")
393 (and:X (match_operand:X 1 "register_operand" "r")
394 (match_operand:X 2 "not_single_bit_mask_operand" "DnS")))]
395 "TARGET_ZBS"
396 "bclri\t%0,%1,%T2"
397 [(set_attr "type" "bitmanip")])
398
399 ;; In case we have "val & ~IMM" where ~IMM has 2 bits set.
400 (define_insn_and_split "*bclri<mode>_nottwobits"
401 [(set (match_operand:X 0 "register_operand" "=r")
402 (and:X (match_operand:X 1 "register_operand" "r")
403 (match_operand:X 2 "const_nottwobits_operand" "i")))]
404 "TARGET_ZBS && !paradoxical_subreg_p (operands[1])"
405 "#"
406 "&& reload_completed"
407 [(set (match_dup 0) (and:X (match_dup 1) (match_dup 3)))
408 (set (match_dup 0) (and:X (match_dup 0) (match_dup 4)))]
409 {
410 unsigned HOST_WIDE_INT bits = ~UINTVAL (operands[2]);
411 unsigned HOST_WIDE_INT topbit = HOST_WIDE_INT_1U << floor_log2 (bits);
412
413 operands[3] = GEN_INT (~bits | topbit);
414 operands[4] = GEN_INT (~topbit);
415 })
416
417 ;; In case of a paradoxical subreg, the sign bit and the high bits are
418 ;; not allowed to be changed
419 (define_insn_and_split "*bclridisi_nottwobits"
420 [(set (match_operand:DI 0 "register_operand" "=r")
421 (and:DI (match_operand:DI 1 "register_operand" "r")
422 (match_operand:DI 2 "const_nottwobits_operand" "i")))]
423 "TARGET_64BIT && TARGET_ZBS
424 && clz_hwi (~UINTVAL (operands[2])) > 33"
425 "#"
426 "&& reload_completed"
427 [(set (match_dup 0) (and:DI (match_dup 1) (match_dup 3)))
428 (set (match_dup 0) (and:DI (match_dup 0) (match_dup 4)))]
429 {
430 unsigned HOST_WIDE_INT bits = ~UINTVAL (operands[2]);
431 unsigned HOST_WIDE_INT topbit = HOST_WIDE_INT_1U << floor_log2 (bits);
432
433 operands[3] = GEN_INT (~bits | topbit);
434 operands[4] = GEN_INT (~topbit);
435 })
436
437 (define_insn "*binv<mode>"
438 [(set (match_operand:X 0 "register_operand" "=r")
439 (xor:X (ashift:X (const_int 1)
440 (match_operand:QI 2 "register_operand" "r"))
441 (match_operand:X 1 "register_operand" "r")))]
442 "TARGET_ZBS"
443 "binv\t%0,%1,%2"
444 [(set_attr "type" "bitmanip")])
445
446 (define_insn "*binvi<mode>"
447 [(set (match_operand:X 0 "register_operand" "=r")
448 (xor:X (match_operand:X 1 "register_operand" "r")
449 (match_operand:X 2 "single_bit_mask_operand" "DbS")))]
450 "TARGET_ZBS"
451 "binvi\t%0,%1,%S2"
452 [(set_attr "type" "bitmanip")])
453
454 (define_insn "*bext<mode>"
455 [(set (match_operand:X 0 "register_operand" "=r")
456 (zero_extract:X (match_operand:X 1 "register_operand" "r")
457 (const_int 1)
458 (zero_extend:X
459 (match_operand:QI 2 "register_operand" "r"))))]
460 "TARGET_ZBS"
461 "bext\t%0,%1,%2"
462 [(set_attr "type" "bitmanip")])
463
464 ;; When performing `(a & (1UL << bitno)) ? 0 : -1` the combiner
465 ;; usually has the `bitno` typed as X-mode (i.e. no further
466 ;; zero-extension is performed around the bitno).
467 (define_insn "*bext<mode>"
468 [(set (match_operand:X 0 "register_operand" "=r")
469 (zero_extract:X (match_operand:X 1 "register_operand" "r")
470 (const_int 1)
471 (match_operand:X 2 "register_operand" "r")))]
472 "TARGET_ZBS"
473 "bext\t%0,%1,%2"
474 [(set_attr "type" "bitmanip")])
475
476 (define_insn "*bexti"
477 [(set (match_operand:X 0 "register_operand" "=r")
478 (zero_extract:X (match_operand:X 1 "register_operand" "r")
479 (const_int 1)
480 (match_operand 2 "immediate_operand" "n")))]
481 "TARGET_ZBS && UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
482 "bexti\t%0,%1,%2"
483 [(set_attr "type" "bitmanip")])
484
485 ;; Split for "(a & (1 << BIT_NO)) ? 0 : 1":
486 ;; We avoid reassociating "(~(a >> BIT_NO)) & 1" into "((~a) >> BIT_NO) & 1",
487 ;; so we don't have to use a temporary. Instead we extract the bit and then
488 ;; invert bit 0 ("a ^ 1") only.
489 (define_split
490 [(set (match_operand:X 0 "register_operand")
491 (and:X (not:X (lshiftrt:X (match_operand:X 1 "register_operand")
492 (subreg:QI (match_operand:X 2 "register_operand") 0)))
493 (const_int 1)))]
494 "TARGET_ZBS"
495 [(set (match_dup 0) (zero_extract:X (match_dup 1)
496 (const_int 1)
497 (match_dup 2)))
498 (set (match_dup 0) (xor:X (match_dup 0) (const_int 1)))])
499
500 ;; We can create a polarity-reversed mask (i.e. bit N -> { set = 0, clear = -1 })
501 ;; using a bext(i) followed by an addi instruction.
502 ;; This splits the canonical representation of "(a & (1 << BIT_NO)) ? 0 : -1".
503 (define_split
504 [(set (match_operand:GPR 0 "register_operand")
505 (neg:GPR (eq:GPR (zero_extract:GPR (match_operand:GPR 1 "register_operand")
506 (const_int 1)
507 (match_operand 2))
508 (const_int 0))))]
509 "TARGET_ZBS"
510 [(set (match_dup 0) (zero_extract:GPR (match_dup 1) (const_int 1) (match_dup 2)))
511 (set (match_dup 0) (plus:GPR (match_dup 0) (const_int -1)))])