1 ;; Machine description for RISC-V Bit Manipulation operations.
2 ;; Copyright (C) 2021-2023 Free Software Foundation, Inc.
4 ;; This file is part of GCC.
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)
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.
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/>.
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"
29 [(set_attr "type" "bitmanip,load")
30 (set_attr "mode" "DI")])
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")))]
39 [(set_attr "type" "bitmanip")
40 (set_attr "mode" "<X:MODE>")])
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.
49 [(set (match_operand:DI 0 "register_operand")
50 (sign_extend:DI (div:SI (plus:SI (ashift:SI (subreg:SI (match_operand:DI 1 "register_operand") 0)
51 (match_operand:QI 2 "imm123_operand"))
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))))])
59 ; Zba does not provide W-forms of sh[123]add(.uw)?, which leads to an
60 ; interesting irregularity: we can generate a signed 32-bit result
61 ; using slli(.uw)?+ addw, but a unsigned 32-bit result can be more
62 ; efficiently be generated as sh[123]add+zext.w (the .uw can be
63 ; dropped, if we zero-extend the output anyway).
65 ; To enable this optimization, we split [ slli(.uw)?, addw, zext.w ]
66 ; into [ sh[123]add, zext.w ] for use during combine.
68 [(set (match_operand:DI 0 "register_operand")
69 (zero_extend:DI (plus:SI (ashift:SI (subreg:SI (match_operand:DI 1 "register_operand") 0)
70 (match_operand:QI 2 "imm123_operand"))
71 (subreg:SI (match_operand:DI 3 "register_operand") 0))))]
72 "TARGET_64BIT && TARGET_ZBA"
73 [(set (match_dup 0) (plus:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))
74 (set (match_dup 0) (zero_extend:DI (subreg:SI (match_dup 0) 0)))])
77 [(set (match_operand:DI 0 "register_operand")
78 (zero_extend:DI (plus:SI (subreg:SI (and:DI (ashift:DI (match_operand:DI 1 "register_operand")
79 (match_operand:QI 2 "imm123_operand"))
80 (match_operand:DI 3 "consecutive_bits_operand")) 0)
81 (subreg:SI (match_operand:DI 4 "register_operand") 0))))]
82 "TARGET_64BIT && TARGET_ZBA
83 && riscv_shamt_matches_mask_p (INTVAL (operands[2]), INTVAL (operands[3]))"
84 [(set (match_dup 0) (plus:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 4)))
85 (set (match_dup 0) (zero_extend:DI (subreg:SI (match_dup 0) 0)))])
87 ; Make sure that an andi followed by a sh[123]add remains a two instruction
88 ; sequence--and is not torn apart into slli, slri, add.
89 (define_insn_and_split "*andi_add.uw"
90 [(set (match_operand:DI 0 "register_operand" "=r")
91 (plus:DI (and:DI (ashift:DI (match_operand:DI 1 "register_operand" "r")
92 (match_operand:QI 2 "imm123_operand" "Ds3"))
93 (match_operand:DI 3 "consecutive_bits_operand" ""))
94 (match_operand:DI 4 "register_operand" "r")))
95 (clobber (match_scratch:DI 5 "=&r"))]
96 "TARGET_64BIT && TARGET_ZBA
97 && riscv_shamt_matches_mask_p (INTVAL (operands[2]), INTVAL (operands[3]))
98 && SMALL_OPERAND (INTVAL (operands[3]) >> INTVAL (operands[2]))"
100 "&& reload_completed"
101 [(set (match_dup 5) (and:DI (match_dup 1) (match_dup 3)))
102 (set (match_dup 0) (plus:DI (ashift:DI (match_dup 5) (match_dup 2))
105 operands[3] = GEN_INT (INTVAL (operands[3]) >> INTVAL (operands[2]));
108 (define_insn "*shNadduw"
109 [(set (match_operand:DI 0 "register_operand" "=r")
111 (and:DI (ashift:DI (match_operand:DI 1 "register_operand" "r")
112 (match_operand:QI 2 "imm123_operand" "Ds3"))
113 (match_operand 3 "immediate_operand" "n"))
114 (match_operand:DI 4 "register_operand" "r")))]
115 "TARGET_64BIT && TARGET_ZBA
116 && (INTVAL (operands[3]) >> INTVAL (operands[2])) == 0xffffffff"
117 "sh%2add.uw\t%0,%1,%4"
118 [(set_attr "type" "bitmanip")
119 (set_attr "mode" "DI")])
121 ;; During combine, we may encounter an attempt to combine
122 ;; slli rtmp, rs, #imm
124 ;; sh[123]add rd, rtmp, rs2
125 ;; which will lead to the immediate not satisfying the above constraints.
126 ;; By splitting the compound expression, we can simplify to a slli and a
129 [(set (match_operand:DI 0 "register_operand")
130 (plus:DI (and:DI (ashift:DI (match_operand:DI 1 "register_operand")
131 (match_operand:QI 2 "immediate_operand"))
132 (match_operand:DI 3 "consecutive_bits_operand"))
133 (match_operand:DI 4 "register_operand")))
134 (clobber (match_operand:DI 5 "register_operand"))]
135 "TARGET_64BIT && TARGET_ZBA"
136 [(set (match_dup 5) (ashift:DI (match_dup 1) (match_dup 6)))
137 (set (match_dup 0) (plus:DI (and:DI (ashift:DI (match_dup 5)
142 unsigned HOST_WIDE_INT mask = UINTVAL (operands[3]);
143 /* scale: shift within the sh[123]add.uw */
144 unsigned HOST_WIDE_INT scale = 32 - clz_hwi (mask);
145 /* bias: pre-scale amount (i.e. the prior shift amount) */
146 int bias = ctz_hwi (mask) - scale;
148 /* If the bias + scale don't add up to operand[2], reject. */
149 if ((scale + bias) != UINTVAL (operands[2]))
152 /* If the shift-amount is out-of-range for sh[123]add.uw, reject. */
153 if ((scale < 1) || (scale > 3))
156 /* If there's no bias, the '*shNadduw' pattern should have matched. */
160 operands[6] = GEN_INT (bias);
161 operands[7] = GEN_INT (scale);
162 operands[8] = GEN_INT (0xffffffffULL << scale);
165 (define_insn "*add.uw"
166 [(set (match_operand:DI 0 "register_operand" "=r")
167 (plus:DI (zero_extend:DI
168 (match_operand:SI 1 "register_operand" "r"))
169 (match_operand:DI 2 "register_operand" "r")))]
170 "TARGET_64BIT && TARGET_ZBA"
172 [(set_attr "type" "bitmanip")
173 (set_attr "mode" "DI")])
175 (define_insn "*slliuw"
176 [(set (match_operand:DI 0 "register_operand" "=r")
177 (and:DI (ashift:DI (match_operand:DI 1 "register_operand" "r")
178 (match_operand:QI 2 "immediate_operand" "I"))
179 (match_operand 3 "immediate_operand" "n")))]
180 "TARGET_64BIT && TARGET_ZBA
181 && (INTVAL (operands[3]) >> INTVAL (operands[2])) == 0xffffffff"
183 [(set_attr "type" "bitmanip")
184 (set_attr "mode" "DI")])
188 (define_expand "clzdi2"
189 [(set (match_operand:DI 0 "register_operand")
190 (clz:DI (match_operand:DI 1 "register_operand")))]
191 "TARGET_64BIT && (TARGET_ZBB || TARGET_XTHEADBB)")
193 (define_expand "clzsi2"
194 [(set (match_operand:SI 0 "register_operand")
195 (clz:SI (match_operand:SI 1 "register_operand")))]
196 "TARGET_ZBB || (!TARGET_64BIT && TARGET_XTHEADBB)")
198 (define_expand "ctz<mode>2"
199 [(set (match_operand:GPR 0 "register_operand")
200 (ctz:GPR (match_operand:GPR 1 "register_operand")))]
203 (define_expand "popcount<mode>2"
204 [(set (match_operand:GPR 0 "register_operand")
205 (popcount:GPR (match_operand:GPR 1 "register_operand")))]
208 (define_insn "*<optab>_not<mode>"
209 [(set (match_operand:X 0 "register_operand" "=r")
210 (bitmanip_bitwise:X (not:X (match_operand:X 1 "register_operand" "r"))
211 (match_operand:X 2 "register_operand" "r")))]
212 "TARGET_ZBB || TARGET_ZBKB"
214 [(set_attr "type" "bitmanip")
215 (set_attr "mode" "<X:MODE>")])
217 ;; '(a >= 0) ? b : 0' is emitted branchless (from if-conversion). Without a
218 ;; bit of extra help for combine (i.e., the below split), we end up emitting
219 ;; not/srai/and instead of combining the not into an andn.
221 [(set (match_operand:DI 0 "register_operand")
222 (and:DI (neg:DI (ge:DI (match_operand:DI 1 "register_operand")
224 (match_operand:DI 2 "register_operand")))
225 (clobber (match_operand:DI 3 "register_operand"))]
226 "TARGET_ZBB || TARGET_ZBKB"
227 [(set (match_dup 3) (ashiftrt:DI (match_dup 1) (const_int 63)))
228 (set (match_dup 0) (and:DI (not:DI (match_dup 3)) (match_dup 2)))])
230 (define_insn "*xor_not<mode>"
231 [(set (match_operand:X 0 "register_operand" "=r")
232 (not:X (xor:X (match_operand:X 1 "register_operand" "r")
233 (match_operand:X 2 "register_operand" "r"))))]
234 "TARGET_ZBB || TARGET_ZBKB"
236 [(set_attr "type" "bitmanip")
237 (set_attr "mode" "<X:MODE>")])
239 (define_insn "*<bitmanip_optab>si2"
240 [(set (match_operand:SI 0 "register_operand" "=r")
241 (clz_ctz_pcnt:SI (match_operand:SI 1 "register_operand" "r")))]
243 "<bitmanip_insn>%~\t%0,%1"
244 [(set_attr "type" "<bitmanip_insn>")
245 (set_attr "mode" "SI")])
247 (define_insn "*<bitmanip_optab>disi2"
248 [(set (match_operand:DI 0 "register_operand" "=r")
250 (clz_ctz_pcnt:SI (match_operand:SI 1 "register_operand" "r"))))]
251 "TARGET_64BIT && TARGET_ZBB"
252 "<bitmanip_insn>w\t%0,%1"
253 [(set_attr "type" "<bitmanip_insn>")
254 (set_attr "mode" "SI")])
256 ;; A SImode clz_ctz_pcnt may be extended to DImode via subreg.
257 (define_insn "*<bitmanip_optab>disi2_sext"
258 [(set (match_operand:DI 0 "register_operand" "=r")
260 (clz_ctz_pcnt:SI (match_operand:SI 1 "register_operand" "r")) 0)
261 (match_operand:DI 2 "const_int_operand")))]
262 "TARGET_64BIT && TARGET_ZBB && ((INTVAL (operands[2]) & 0x3f) == 0x3f)"
263 "<bitmanip_insn>w\t%0,%1"
264 [(set_attr "type" "bitmanip")
265 (set_attr "mode" "SI")])
267 (define_insn "*<bitmanip_optab>di2"
268 [(set (match_operand:DI 0 "register_operand" "=r")
269 (clz_ctz_pcnt:DI (match_operand:DI 1 "register_operand" "r")))]
270 "TARGET_64BIT && TARGET_ZBB"
271 "<bitmanip_insn>\t%0,%1"
272 [(set_attr "type" "<bitmanip_insn>")
273 (set_attr "mode" "DI")])
275 (define_insn "*zero_extendhi<GPR:mode>2_bitmanip"
276 [(set (match_operand:GPR 0 "register_operand" "=r,r")
277 (zero_extend:GPR (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
282 [(set_attr "type" "bitmanip,load")
283 (set_attr "mode" "<GPR:MODE>")])
285 (define_insn "*extend<SHORT:mode><SUPERQI:mode>2_zbb"
286 [(set (match_operand:SUPERQI 0 "register_operand" "=r,r")
288 (match_operand:SHORT 1 "nonimmediate_operand" " r,m")))]
291 sext.<SHORT:size>\t%0,%1
292 l<SHORT:size>\t%0,%1"
293 [(set_attr "type" "bitmanip,load")
294 (set_attr "mode" "<SUPERQI:MODE>")])
296 (define_insn "*zero_extendhi<GPR:mode>2_zbb"
297 [(set (match_operand:GPR 0 "register_operand" "=r,r")
299 (match_operand:HI 1 "nonimmediate_operand" " r,m")))]
304 [(set_attr "type" "bitmanip,load")
305 (set_attr "mode" "HI")])
307 (define_expand "rotrdi3"
308 [(set (match_operand:DI 0 "register_operand")
309 (rotatert:DI (match_operand:DI 1 "register_operand")
310 (match_operand:QI 2 "arith_operand")))]
311 "TARGET_64BIT && (TARGET_ZBB || TARGET_XTHEADBB || TARGET_ZBKB)"
313 if (TARGET_XTHEADBB && !immediate_operand (operands[2], VOIDmode))
317 (define_insn "*rotrsi3"
318 [(set (match_operand:SI 0 "register_operand" "=r")
319 (rotatert:SI (match_operand:SI 1 "register_operand" "r")
320 (match_operand:QI 2 "arith_operand" "rI")))]
321 "TARGET_ZBB || TARGET_ZBKB"
323 [(set_attr "type" "bitmanip")])
325 (define_expand "rotrsi3"
326 [(set (match_operand:SI 0 "register_operand" "=r")
327 (rotatert:SI (match_operand:SI 1 "register_operand" "r")
328 (match_operand:QI 2 "arith_operand" "rI")))]
329 "TARGET_ZBB || TARGET_ZBKB || TARGET_XTHEADBB"
331 if (TARGET_XTHEADBB && !immediate_operand (operands[2], VOIDmode))
333 if (TARGET_64BIT && register_operand (operands[2], QImode))
335 rtx t = gen_reg_rtx (DImode);
336 emit_insn (gen_rotrsi3_sext (t, operands[1], operands[2]));
337 t = gen_lowpart (SImode, t);
338 SUBREG_PROMOTED_VAR_P (t) = 1;
339 SUBREG_PROMOTED_SET (t, SRP_SIGNED);
340 emit_move_insn (operands[0], t);
345 (define_insn "*rotrdi3"
346 [(set (match_operand:DI 0 "register_operand" "=r")
347 (rotatert:DI (match_operand:DI 1 "register_operand" "r")
348 (match_operand:QI 2 "arith_operand" "rI")))]
349 "TARGET_64BIT && (TARGET_ZBB || TARGET_ZBKB)"
351 [(set_attr "type" "bitmanip")])
353 (define_insn "rotrsi3_sext"
354 [(set (match_operand:DI 0 "register_operand" "=r")
355 (sign_extend:DI (rotatert:SI (match_operand:SI 1 "register_operand" "r")
356 (match_operand:QI 2 "arith_operand" "rI"))))]
357 "TARGET_64BIT && (TARGET_ZBB || TARGET_ZBKB)"
359 [(set_attr "type" "bitmanip")])
361 (define_insn "*rotlsi3"
362 [(set (match_operand:SI 0 "register_operand" "=r")
363 (rotate:SI (match_operand:SI 1 "register_operand" "r")
364 (match_operand:QI 2 "register_operand" "r")))]
365 "TARGET_ZBB || TARGET_ZBKB"
367 [(set_attr "type" "bitmanip")])
369 (define_expand "rotlsi3"
370 [(set (match_operand:SI 0 "register_operand" "=r")
371 (rotate:SI (match_operand:SI 1 "register_operand" "r")
372 (match_operand:QI 2 "register_operand" "r")))]
373 "TARGET_ZBB || TARGET_ZBKB"
377 rtx t = gen_reg_rtx (DImode);
378 emit_insn (gen_rotlsi3_sext (t, operands[1], operands[2]));
379 t = gen_lowpart (SImode, t);
380 SUBREG_PROMOTED_VAR_P (t) = 1;
381 SUBREG_PROMOTED_SET (t, SRP_SIGNED);
382 emit_move_insn (operands[0], t);
387 (define_insn "rotldi3"
388 [(set (match_operand:DI 0 "register_operand" "=r")
389 (rotate:DI (match_operand:DI 1 "register_operand" "r")
390 (match_operand:QI 2 "register_operand" "r")))]
391 "TARGET_64BIT && (TARGET_ZBB || TARGET_ZBKB)"
393 [(set_attr "type" "bitmanip")])
395 (define_insn "rotlsi3_sext"
396 [(set (match_operand:DI 0 "register_operand" "=r")
397 (sign_extend:DI (rotate:SI (match_operand:SI 1 "register_operand" "r")
398 (match_operand:QI 2 "register_operand" "r"))))]
399 "TARGET_64BIT && (TARGET_ZBB || TARGET_ZBKB)"
401 [(set_attr "type" "bitmanip")])
403 (define_insn_and_split "*<bitmanip_optab><GPR:mode>3_mask"
404 [(set (match_operand:GPR 0 "register_operand" "= r")
406 (match_operand:GPR 1 "register_operand" " r")
407 (match_operator 4 "subreg_lowpart_operator"
409 (match_operand:GPR2 2 "register_operand" "r")
410 (match_operand 3 "<GPR:shiftm1>" "<GPR:shiftm1p>"))])))]
411 "TARGET_ZBB || TARGET_ZBKB"
415 (bitmanip_rotate:GPR (match_dup 1)
417 "operands[2] = gen_lowpart (QImode, operands[2]);"
418 [(set_attr "type" "bitmanip")
419 (set_attr "mode" "<GPR:MODE>")])
421 (define_insn_and_split "*<bitmanip_optab>si3_sext_mask"
422 [(set (match_operand:DI 0 "register_operand" "= r")
423 (sign_extend:DI (bitmanip_rotate:SI
424 (match_operand:SI 1 "register_operand" " r")
425 (match_operator 4 "subreg_lowpart_operator"
427 (match_operand:GPR 2 "register_operand" "r")
428 (match_operand 3 "const_si_mask_operand"))]))))]
429 "TARGET_64BIT && (TARGET_ZBB || TARGET_ZBKB)"
433 (sign_extend:DI (bitmanip_rotate:SI (match_dup 1)
435 "operands[2] = gen_lowpart (QImode, operands[2]);"
436 [(set_attr "type" "bitmanip")
437 (set_attr "mode" "DI")])
439 ;; orc.b (or-combine) is added as an unspec for the benefit of the support
440 ;; for optimized string functions (such as strcmp).
441 (define_insn "orcb<mode>2"
442 [(set (match_operand:X 0 "register_operand" "=r")
443 (unspec:X [(match_operand:X 1 "register_operand" "r")] UNSPEC_ORC_B))]
446 [(set_attr "type" "bitmanip")])
448 (define_expand "bswapdi2"
449 [(set (match_operand:DI 0 "register_operand")
450 (bswap:DI (match_operand:DI 1 "register_operand")))]
451 "TARGET_64BIT && (TARGET_ZBB || TARGET_XTHEADBB || TARGET_ZBKB)")
453 (define_expand "bswapsi2"
454 [(set (match_operand:SI 0 "register_operand")
455 (bswap:SI (match_operand:SI 1 "register_operand")))]
456 "(!TARGET_64BIT && (TARGET_ZBB || TARGET_ZBKB)) || TARGET_XTHEADBB")
458 (define_insn "*bswap<mode>2"
459 [(set (match_operand:X 0 "register_operand" "=r")
460 (bswap:X (match_operand:X 1 "register_operand" "r")))]
461 "TARGET_ZBB || TARGET_ZBKB"
463 [(set_attr "type" "bitmanip")])
465 ;; HI bswap can be emulated using SI/DI bswap followed
466 ;; by a logical shift right
467 ;; SI bswap for TARGET_64BIT is already similarly in
469 (define_expand "bswaphi2"
470 [(set (match_operand:HI 0 "register_operand" "=r")
471 (bswap:HI (match_operand:HI 1 "register_operand" "r")))]
474 rtx tmp = gen_reg_rtx (word_mode);
475 rtx newop1 = gen_lowpart (word_mode, operands[1]);
477 emit_insn (gen_bswapdi2 (tmp, newop1));
479 emit_insn (gen_bswapsi2 (tmp, newop1));
480 rtx tmp1 = gen_reg_rtx (word_mode);
482 emit_insn (gen_lshrdi3 (tmp1, tmp, GEN_INT (64 - 16)));
484 emit_insn (gen_lshrsi3 (tmp1, tmp, GEN_INT (32 - 16)));
485 emit_move_insn (operands[0], gen_lowpart (HImode, tmp1));
489 (define_expand "<bitmanip_optab>di3"
490 [(set (match_operand:DI 0 "register_operand" "=r")
491 (bitmanip_minmax:DI (match_operand:DI 1 "register_operand" "r")
492 (match_operand:DI 2 "register_operand" "r")))]
493 "TARGET_64BIT && TARGET_ZBB")
495 (define_expand "<bitmanip_optab>si3"
496 [(set (match_operand:SI 0 "register_operand" "=r")
497 (bitmanip_minmax:SI (match_operand:SI 1 "register_operand" "r")
498 (match_operand:SI 2 "register_operand" "r")))]
503 rtx t = gen_reg_rtx (DImode);
504 operands[1] = force_reg (DImode, gen_rtx_SIGN_EXTEND (DImode, operands[1]));
505 operands[2] = force_reg (DImode, gen_rtx_SIGN_EXTEND (DImode, operands[2]));
506 emit_insn (gen_<bitmanip_optab>di3 (t, operands[1], operands[2]));
507 emit_move_insn (operands[0], gen_lowpart (SImode, t));
512 (define_insn "*<bitmanip_optab><mode>3"
513 [(set (match_operand:X 0 "register_operand" "=r")
514 (bitmanip_minmax:X (match_operand:X 1 "register_operand" "r")
515 (match_operand:X 2 "reg_or_0_operand" "rJ")))]
517 "<bitmanip_insn>\t%0,%1,%z2"
518 [(set_attr "type" "<bitmanip_insn>")])
520 ;; Optimize the common case of a SImode min/max against a constant
521 ;; that is safe both for sign- and zero-extension.
522 (define_insn_and_split "*minmax"
523 [(set (match_operand:DI 0 "register_operand" "=r")
526 (bitmanip_minmax:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
527 (match_operand:DI 2 "immediate_operand" "i"))
529 (clobber (match_scratch:DI 3 "=&r"))
530 (clobber (match_scratch:DI 4 "=&r"))]
531 "TARGET_64BIT && TARGET_ZBB && sext_hwi (INTVAL (operands[2]), 32) >= 0"
533 "&& reload_completed"
534 [(set (match_dup 3) (sign_extend:DI (match_dup 1)))
535 (set (match_dup 4) (match_dup 2))
536 (set (match_dup 0) (<minmax_optab>:DI (match_dup 3) (match_dup 4)))])
540 (define_insn "*bset<mode>"
541 [(set (match_operand:X 0 "register_operand" "=r")
542 (ior:X (ashift:X (const_int 1)
543 (match_operand:QI 2 "register_operand" "r"))
544 (match_operand:X 1 "register_operand" "r")))]
547 [(set_attr "type" "bitmanip")])
549 (define_insn "*bset<mode>_mask"
550 [(set (match_operand:X 0 "register_operand" "=r")
551 (ior:X (ashift:X (const_int 1)
553 (and:X (match_operand:X 2 "register_operand" "r")
554 (match_operand 3 "<X:shiftm1>" "<X:shiftm1p>")) 0))
555 (match_operand:X 1 "register_operand" "r")))]
558 [(set_attr "type" "bitmanip")])
560 (define_insn "*bset<mode>_1"
561 [(set (match_operand:X 0 "register_operand" "=r")
562 (ashift:X (const_int 1)
563 (match_operand:QI 1 "register_operand" "r")))]
566 [(set_attr "type" "bitmanip")])
568 (define_insn "*bset<mode>_1_mask"
569 [(set (match_operand:X 0 "register_operand" "=r")
570 (ashift:X (const_int 1)
572 (and:X (match_operand:X 1 "register_operand" "r")
573 (match_operand 2 "<X:shiftm1>" "<X:shiftm1p>")) 0)))]
576 [(set_attr "type" "bitmanip")])
578 (define_insn "*bseti<mode>"
579 [(set (match_operand:X 0 "register_operand" "=r")
580 (ior:X (match_operand:X 1 "register_operand" "r")
581 (match_operand:X 2 "single_bit_mask_operand" "DbS")))]
584 [(set_attr "type" "bitmanip")])
586 ;; As long as the SImode operand is not a partial subreg, we can use a
587 ;; bseti without postprocessing, as the middle end is smart enough to
588 ;; stay away from the signbit.
589 (define_insn "*bsetidisi"
590 [(set (match_operand:DI 0 "register_operand" "=r")
591 (ior:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
592 (match_operand 2 "single_bit_mask_operand" "i")))]
593 "TARGET_ZBS && TARGET_64BIT
594 && !partial_subreg_p (operands[1])"
596 [(set_attr "type" "bitmanip")])
598 (define_insn "*bclr<mode>"
599 [(set (match_operand:X 0 "register_operand" "=r")
600 (and:X (rotate:X (const_int -2)
601 (match_operand:QI 2 "register_operand" "r"))
602 (match_operand:X 1 "register_operand" "r")))]
605 [(set_attr "type" "bitmanip")])
607 (define_insn "*bclri<mode>"
608 [(set (match_operand:X 0 "register_operand" "=r")
609 (and:X (match_operand:X 1 "register_operand" "r")
610 (match_operand:X 2 "not_single_bit_mask_operand" "DnS")))]
613 [(set_attr "type" "bitmanip")])
615 ;; In case we have "val & ~IMM" where ~IMM has 2 bits set.
616 (define_insn_and_split "*bclri<mode>_nottwobits"
617 [(set (match_operand:X 0 "register_operand" "=r")
618 (and:X (match_operand:X 1 "register_operand" "r")
619 (match_operand:X 2 "const_nottwobits_not_arith_operand" "i")))]
620 "TARGET_ZBS && !paradoxical_subreg_p (operands[1])"
622 "&& reload_completed"
623 [(set (match_dup 0) (and:X (match_dup 1) (match_dup 3)))
624 (set (match_dup 0) (and:X (match_dup 0) (match_dup 4)))]
626 unsigned HOST_WIDE_INT bits = ~UINTVAL (operands[2]);
627 unsigned HOST_WIDE_INT topbit = HOST_WIDE_INT_1U << floor_log2 (bits);
629 operands[3] = GEN_INT (~bits | topbit);
630 operands[4] = GEN_INT (~topbit);
633 ;; In case of a paradoxical subreg, the sign bit and the high bits are
634 ;; not allowed to be changed
635 (define_insn_and_split "*bclridisi_nottwobits"
636 [(set (match_operand:DI 0 "register_operand" "=r")
637 (and:DI (match_operand:DI 1 "register_operand" "r")
638 (match_operand:DI 2 "const_nottwobits_not_arith_operand" "i")))]
639 "TARGET_64BIT && TARGET_ZBS
640 && clz_hwi (~UINTVAL (operands[2])) > 33"
642 "&& reload_completed"
643 [(set (match_dup 0) (and:DI (match_dup 1) (match_dup 3)))
644 (set (match_dup 0) (and:DI (match_dup 0) (match_dup 4)))]
646 unsigned HOST_WIDE_INT bits = ~UINTVAL (operands[2]);
647 unsigned HOST_WIDE_INT topbit = HOST_WIDE_INT_1U << floor_log2 (bits);
649 operands[3] = GEN_INT (~bits | topbit);
650 operands[4] = GEN_INT (~topbit);
653 (define_insn "*binv<mode>"
654 [(set (match_operand:X 0 "register_operand" "=r")
655 (xor:X (ashift:X (const_int 1)
656 (match_operand:QI 2 "register_operand" "r"))
657 (match_operand:X 1 "register_operand" "r")))]
660 [(set_attr "type" "bitmanip")])
662 (define_insn "*binvi<mode>"
663 [(set (match_operand:X 0 "register_operand" "=r")
664 (xor:X (match_operand:X 1 "register_operand" "r")
665 (match_operand:X 2 "single_bit_mask_operand" "DbS")))]
668 [(set_attr "type" "bitmanip")])
670 (define_insn "*bext<mode>"
671 [(set (match_operand:X 0 "register_operand" "=r")
672 (zero_extract:X (match_operand:X 1 "register_operand" "r")
675 (match_operand:QI 2 "register_operand" "r"))))]
678 [(set_attr "type" "bitmanip")])
680 ;; When performing `(a & (1UL << bitno)) ? 0 : -1` the combiner
681 ;; usually has the `bitno` typed as X-mode (i.e. no further
682 ;; zero-extension is performed around the bitno).
683 (define_insn "*bext<mode>"
684 [(set (match_operand:X 0 "register_operand" "=r")
685 (zero_extract:X (match_operand:X 1 "register_operand" "r")
687 (match_operand:X 2 "register_operand" "r")))]
690 [(set_attr "type" "bitmanip")])
692 (define_insn "*bexti"
693 [(set (match_operand:X 0 "register_operand" "=r")
694 (zero_extract:X (match_operand:X 1 "register_operand" "r")
696 (match_operand 2 "immediate_operand" "n")))]
697 "TARGET_ZBS && UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
699 [(set_attr "type" "bitmanip")])
701 ;; Split for "(a & (1 << BIT_NO)) ? 0 : 1":
702 ;; We avoid reassociating "(~(a >> BIT_NO)) & 1" into "((~a) >> BIT_NO) & 1",
703 ;; so we don't have to use a temporary. Instead we extract the bit and then
704 ;; invert bit 0 ("a ^ 1") only.
706 [(set (match_operand:X 0 "register_operand")
707 (and:X (not:X (lshiftrt:X (match_operand:X 1 "register_operand")
708 (subreg:QI (match_operand:X 2 "register_operand") 0)))
711 [(set (match_dup 0) (zero_extract:X (match_dup 1)
714 (set (match_dup 0) (xor:X (match_dup 0) (const_int 1)))])
716 ;; We can create a polarity-reversed mask (i.e. bit N -> { set = 0, clear = -1 })
717 ;; using a bext(i) followed by an addi instruction.
718 ;; This splits the canonical representation of "(a & (1 << BIT_NO)) ? 0 : -1".
720 [(set (match_operand:GPR 0 "register_operand")
721 (neg:GPR (eq:GPR (zero_extract:GPR (match_operand:GPR 1 "register_operand")
726 [(set (match_dup 0) (zero_extract:GPR (match_dup 1) (const_int 1) (match_dup 2)))
727 (set (match_dup 0) (plus:GPR (match_dup 0) (const_int -1)))])
729 ;; Catch those cases where we can use a bseti/binvi + ori/xori or
730 ;; bseti/binvi + bseti/binvi instead of a lui + addi + or/xor sequence.
731 (define_insn_and_split "*<or_optab>i<mode>_extrabit"
732 [(set (match_operand:X 0 "register_operand" "=r")
733 (any_or:X (match_operand:X 1 "register_operand" "r")
734 (match_operand:X 2 "uimm_extra_bit_or_twobits" "i")))]
737 "&& reload_completed"
738 [(set (match_dup 0) (<or_optab>:X (match_dup 1) (match_dup 3)))
739 (set (match_dup 0) (<or_optab>:X (match_dup 0) (match_dup 4)))]
741 unsigned HOST_WIDE_INT bits = UINTVAL (operands[2]);
742 unsigned HOST_WIDE_INT topbit = HOST_WIDE_INT_1U << floor_log2 (bits);
744 operands[3] = GEN_INT (bits &~ topbit);
745 operands[4] = GEN_INT (topbit);
748 ;; Same to use blcri + andi and blcri + bclri
749 (define_insn_and_split "*andi<mode>_extrabit"
750 [(set (match_operand:X 0 "register_operand" "=r")
751 (and:X (match_operand:X 1 "register_operand" "r")
752 (match_operand:X 2 "not_uimm_extra_bit_or_nottwobits" "i")))]
755 "&& reload_completed"
756 [(set (match_dup 0) (and:X (match_dup 1) (match_dup 3)))
757 (set (match_dup 0) (and:X (match_dup 0) (match_dup 4)))]
759 unsigned HOST_WIDE_INT bits = UINTVAL (operands[2]);
760 unsigned HOST_WIDE_INT topbit = HOST_WIDE_INT_1U << floor_log2 (~bits);
762 operands[3] = GEN_INT (bits | topbit);
763 operands[4] = GEN_INT (~topbit);
766 ;; IF_THEN_ELSE: test for 2 bits of opposite polarity
767 (define_insn_and_split "*branch<X:mode>_mask_twobits_equals_singlebit"
770 (match_operator 1 "equality_operator"
771 [(and:X (match_operand:X 2 "register_operand" "r")
772 (match_operand:X 3 "const_twobits_not_arith_operand" "i"))
773 (match_operand:X 4 "single_bit_mask_operand" "i")])
774 (label_ref (match_operand 0 "" ""))
776 (clobber (match_scratch:X 5 "=&r"))
777 (clobber (match_scratch:X 6 "=&r"))]
778 "TARGET_ZBS && TARGET_ZBB"
780 "&& reload_completed"
781 [(set (match_dup 5) (zero_extract:X (match_dup 2)
784 (set (match_dup 6) (zero_extract:X (match_dup 2)
787 (set (match_dup 6) (and:X (not:X (match_dup 6)) (match_dup 5)))
788 (set (pc) (if_then_else (match_op_dup 1 [(match_dup 6) (const_int 0)])
789 (label_ref (match_dup 0))
792 unsigned HOST_WIDE_INT twobits_mask = UINTVAL (operands[3]);
793 unsigned HOST_WIDE_INT singlebit_mask = UINTVAL (operands[4]);
795 /* We should never see an unsatisfiable condition. */
796 gcc_assert (twobits_mask & singlebit_mask);
798 int setbit = ctz_hwi (singlebit_mask);
799 int clearbit = ctz_hwi (twobits_mask & ~singlebit_mask);
801 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == NE ? EQ : NE,
802 <X:MODE>mode, operands[6], GEN_INT(0));
804 operands[8] = GEN_INT (setbit);
805 operands[9] = GEN_INT (clearbit);
808 ;; IF_THEN_ELSE: test for (a & (1 << BIT_NO))
809 (define_insn_and_split "*branch<X:mode>_bext"
812 (match_operator 1 "equality_operator"
813 [(zero_extract:X (match_operand:X 2 "register_operand" "r")
816 (match_operand:QI 3 "register_operand" "r")))
818 (label_ref (match_operand 0 "" ""))
820 (clobber (match_scratch:X 4 "=&r"))]
823 "&& reload_completed"
824 [(set (match_dup 4) (zero_extract:X (match_dup 2)
826 (zero_extend:X (match_dup 3))))
827 (set (pc) (if_then_else (match_op_dup 1 [(match_dup 4) (const_int 0)])
828 (label_ref (match_dup 0))
831 ;; ZBKC or ZBC extension
832 (define_insn "riscv_clmul_<mode>"
833 [(set (match_operand:X 0 "register_operand" "=r")
834 (unspec:X [(match_operand:X 1 "register_operand" "r")
835 (match_operand:X 2 "register_operand" "r")]
837 "TARGET_ZBKC || TARGET_ZBC"
839 [(set_attr "type" "clmul")])
841 (define_insn "riscv_clmulh_<mode>"
842 [(set (match_operand:X 0 "register_operand" "=r")
843 (unspec:X [(match_operand:X 1 "register_operand" "r")
844 (match_operand:X 2 "register_operand" "r")]
846 "TARGET_ZBKC || TARGET_ZBC"
848 [(set_attr "type" "clmul")])
851 (define_insn "riscv_clmulr_<mode>"
852 [(set (match_operand:X 0 "register_operand" "=r")
853 (unspec:X [(match_operand:X 1 "register_operand" "r")
854 (match_operand:X 2 "register_operand" "r")]
858 [(set_attr "type" "clmul")])