[committed] Fix RISC-V missing stack tie
[official-gcc.git] / gcc / config / riscv / bitmanip.md
blobccda25c01c1bea374f7a5981e9b4150a69e8ec99
1 ;; Machine description for RISC-V Bit Manipulation operations.
2 ;; Copyright (C) 2021-2024 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)
9 ;; any later version.
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/>.
20 ;; ZBA extension.
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")])
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>")])
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 (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.
67 (define_split
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)))])
76 (define_split
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]))"
99   "#"
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))
103                                (match_dup 4)))]
105         operands[3] = GEN_INT (INTVAL (operands[3]) >> INTVAL (operands[2]));
107 [(set_attr "type" "bitmanip")])
109 (define_insn "*shNadduw"
110   [(set (match_operand:DI 0 "register_operand" "=r")
111         (plus:DI
112           (and:DI (ashift:DI (match_operand:DI 1 "register_operand" "r")
113                              (match_operand:QI 2 "imm123_operand" "Ds3"))
114                  (match_operand 3 "immediate_operand" "n"))
115           (match_operand:DI 4 "register_operand" "r")))]
116   "TARGET_64BIT && TARGET_ZBA
117    && (INTVAL (operands[3]) >> INTVAL (operands[2])) == 0xffffffff"
118   "sh%2add.uw\t%0,%1,%4"
119   [(set_attr "type" "bitmanip")
120    (set_attr "mode" "DI")])
122 ;; During combine, we may encounter an attempt to combine
123 ;;   slli rtmp, rs, #imm
124 ;;   zext.w rtmp, rtmp
125 ;;   sh[123]add rd, rtmp, rs2
126 ;; which will lead to the immediate not satisfying the above constraints.
127 ;; By splitting the compound expression, we can simplify to a slli and a
128 ;; sh[123]add.uw.
129 (define_split
130   [(set (match_operand:DI 0 "register_operand")
131         (plus:DI (and:DI (ashift:DI (match_operand:DI 1 "register_operand")
132                                     (match_operand:QI 2 "immediate_operand"))
133                          (match_operand:DI 3 "consecutive_bits_operand"))
134                  (match_operand:DI 4 "register_operand")))
135    (clobber (match_operand:DI 5 "register_operand"))]
136   "TARGET_64BIT && TARGET_ZBA"
137   [(set (match_dup 5) (ashift:DI (match_dup 1) (match_dup 6)))
138    (set (match_dup 0) (plus:DI (and:DI (ashift:DI (match_dup 5)
139                                                   (match_dup 7))
140                                        (match_dup 8))
141                                (match_dup 4)))]
143         unsigned HOST_WIDE_INT mask = UINTVAL (operands[3]);
144         /* scale: shift within the sh[123]add.uw */
145         unsigned HOST_WIDE_INT scale = 32 - clz_hwi (mask);
146         /* bias:  pre-scale amount (i.e. the prior shift amount) */
147         int bias = ctz_hwi (mask) - scale;
149         /* If the bias + scale don't add up to operand[2], reject. */
150         if ((scale + bias) != UINTVAL (operands[2]))
151            FAIL;
153         /* If the shift-amount is out-of-range for sh[123]add.uw, reject. */
154         if ((scale < 1) || (scale > 3))
155            FAIL;
157         /* If there's no bias, the '*shNadduw' pattern should have matched. */
158         if (bias == 0)
159            FAIL;
161         operands[6] = GEN_INT (bias);
162         operands[7] = GEN_INT (scale);
163         operands[8] = GEN_INT (0xffffffffULL << scale);
166 (define_insn "*add.uw"
167   [(set (match_operand:DI 0 "register_operand" "=r")
168         (plus:DI (zero_extend:DI
169                    (match_operand:SI 1 "register_operand" "r"))
170                  (match_operand:DI 2 "register_operand" "r")))]
171   "TARGET_64BIT && TARGET_ZBA"
172   "add.uw\t%0,%1,%2"
173   [(set_attr "type" "bitmanip")
174    (set_attr "mode" "DI")])
176 (define_insn "*slliuw"
177   [(set (match_operand:DI 0 "register_operand" "=r")
178         (and:DI (ashift:DI (match_operand:DI 1 "register_operand" "r")
179                            (match_operand:QI 2 "immediate_operand" "I"))
180                 (match_operand 3 "immediate_operand" "n")))]
181   "TARGET_64BIT && TARGET_ZBA
182    && (INTVAL (operands[3]) >> INTVAL (operands[2])) == 0xffffffff"
183   "slli.uw\t%0,%1,%2"
184   [(set_attr "type" "bitmanip")
185    (set_attr "mode" "DI")])
187 ;; ZBB extension.
189 (define_expand "clzdi2"
190   [(set (match_operand:DI 0 "register_operand")
191         (clz:DI (match_operand:DI 1 "register_operand")))]
192   "TARGET_64BIT && (TARGET_ZBB || TARGET_XTHEADBB)")
194 (define_expand "clzsi2"
195   [(set (match_operand:SI 0 "register_operand")
196         (clz:SI (match_operand:SI 1 "register_operand")))]
197   "TARGET_ZBB || (!TARGET_64BIT && TARGET_XTHEADBB)")
199 (define_expand "ctz<mode>2"
200   [(set (match_operand:GPR 0 "register_operand")
201         (ctz:GPR (match_operand:GPR 1 "register_operand")))]
202   "TARGET_ZBB")
204 (define_expand "popcount<mode>2"
205   [(set (match_operand:GPR 0 "register_operand")
206         (popcount:GPR (match_operand:GPR 1 "register_operand")))]
207   "TARGET_ZBB")
209 (define_insn "<optab>_not<mode>3"
210   [(set (match_operand:X 0 "register_operand" "=r")
211         (bitmanip_bitwise:X (not:X (match_operand:X 1 "register_operand" "r"))
212                             (match_operand:X 2 "register_operand" "r")))]
213   "TARGET_ZBB || TARGET_ZBKB"
214   "<insn>n\t%0,%2,%1"
215   [(set_attr "type" "bitmanip")
216    (set_attr "mode" "<X:MODE>")])
218 (define_insn_and_split "*<optab>_not_const<mode>"
219   [(set (match_operand:X 0 "register_operand" "=r")
220        (bitmanip_bitwise:X (not:X (match_operand:X 1 "register_operand" "r"))
221               (match_operand:X 2 "const_arith_operand" "I")))
222   (clobber (match_scratch:X 3 "=&r"))]
223   "(TARGET_ZBB || TARGET_ZBKB) && !TARGET_ZCB
224    && !optimize_function_for_size_p (cfun)"
225   "#"
226   "&& reload_completed"
227   [(set (match_dup 3) (match_dup 2))
228    (set (match_dup 0) (bitmanip_bitwise:X (not:X (match_dup 1)) (match_dup 3)))]
229   ""
230   [(set_attr "type" "bitmanip")])
232 ;; '(a >= 0) ? b : 0' is emitted branchless (from if-conversion).  Without a
233 ;; bit of extra help for combine (i.e., the below split), we end up emitting
234 ;; not/srai/and instead of combining the not into an andn.
235 (define_split
236   [(set (match_operand:DI 0 "register_operand")
237         (and:DI (neg:DI (ge:DI (match_operand:DI 1 "register_operand")
238                                (const_int 0)))
239                 (match_operand:DI 2 "register_operand")))
240    (clobber (match_operand:DI 3 "register_operand"))]
241   "TARGET_ZBB || TARGET_ZBKB"
242   [(set (match_dup 3) (ashiftrt:DI (match_dup 1) (const_int 63)))
243    (set (match_dup 0) (and:DI (not:DI (match_dup 3)) (match_dup 2)))])
245 (define_insn "*xor_not<mode>"
246   [(set (match_operand:X 0 "register_operand" "=r")
247         (not:X (xor:X (match_operand:X 1 "register_operand" "r")
248                       (match_operand:X 2 "register_operand" "r"))))]
249   "TARGET_ZBB || TARGET_ZBKB"
250   "xnor\t%0,%1,%2"
251   [(set_attr "type" "bitmanip")
252    (set_attr "mode" "<X:MODE>")])
254 (define_insn "*<bitmanip_optab>si2"
255   [(set (match_operand:SI 0 "register_operand" "=r")
256         (clz_ctz_pcnt:SI (match_operand:SI 1 "register_operand" "r")))]
257   "TARGET_ZBB"
258   "<bitmanip_insn>%~\t%0,%1"
259   [(set_attr "type" "<bitmanip_insn>")
260    (set_attr "mode" "SI")])
262 (define_insn "*<bitmanip_optab>disi2"
263   [(set (match_operand:DI 0 "register_operand" "=r")
264         (any_extend:DI
265           (clz_ctz_pcnt:SI (match_operand:SI 1 "register_operand" "r"))))]
266   "TARGET_64BIT && TARGET_ZBB"
267   "<bitmanip_insn>w\t%0,%1"
268   [(set_attr "type" "<bitmanip_insn>")
269    (set_attr "mode" "SI")])
271 ;; A SImode clz_ctz_pcnt may be extended to DImode via subreg.
272 (define_insn "*<bitmanip_optab>disi2_sext"
273   [(set (match_operand:DI 0 "register_operand" "=r")
274         (and:DI (subreg:DI
275           (clz_ctz_pcnt:SI (match_operand:SI 1 "register_operand" "r")) 0)
276           (match_operand:DI 2 "const_int_operand")))]
277   "TARGET_64BIT && TARGET_ZBB && ((INTVAL (operands[2]) & 0x3f) == 0x3f)"
278   "<bitmanip_insn>w\t%0,%1"
279   [(set_attr "type" "<bitmanip_insn>")
280    (set_attr "mode" "SI")])
282 (define_insn "*<bitmanip_optab>di2"
283   [(set (match_operand:DI 0 "register_operand" "=r")
284         (clz_ctz_pcnt:DI (match_operand:DI 1 "register_operand" "r")))]
285   "TARGET_64BIT && TARGET_ZBB"
286   "<bitmanip_insn>\t%0,%1"
287   [(set_attr "type" "<bitmanip_insn>")
288    (set_attr "mode" "DI")])
290 (define_insn "*zero_extendhi<GPR:mode>2_bitmanip"
291   [(set (match_operand:GPR 0 "register_operand" "=r,r")
292         (zero_extend:GPR (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
293   "TARGET_ZBB && !TARGET_XTHEADMEMIDX"
294   "@
295    zext.h\t%0,%1
296    lhu\t%0,%1"
297   [(set_attr "type" "bitmanip,load")
298    (set_attr "mode" "<GPR:MODE>")])
300 (define_insn "*extend<SHORT:mode><SUPERQI:mode>2_bitmanip"
301   [(set (match_operand:SUPERQI   0 "register_operand"     "=r,r")
302         (sign_extend:SUPERQI
303             (match_operand:SHORT 1 "nonimmediate_operand" " r,m")))]
304   "TARGET_ZBB && !TARGET_XTHEADMEMIDX"
305   "@
306    sext.<SHORT:size>\t%0,%1
307    l<SHORT:size>\t%0,%1"
308   [(set_attr "type" "bitmanip,load")
309    (set_attr "mode" "<SUPERQI:MODE>")])
311 (define_expand "rotrdi3"
312   [(set (match_operand:DI 0 "register_operand")
313         (rotatert:DI (match_operand:DI 1 "register_operand")
314                      (match_operand:QI 2 "arith_operand")))]
315   "TARGET_64BIT && (TARGET_ZBB || TARGET_XTHEADBB || TARGET_ZBKB)"
317   if (TARGET_XTHEADBB && !immediate_operand (operands[2], VOIDmode))
318     FAIL;
321 (define_insn "*rotrsi3"
322   [(set (match_operand:SI 0 "register_operand" "=r")
323         (rotatert:SI (match_operand:SI 1 "register_operand" "r")
324                      (match_operand:QI 2 "arith_operand" "rI")))]
325   "TARGET_ZBB || TARGET_ZBKB"
326   "ror%i2%~\t%0,%1,%2"
327   [(set_attr "type" "bitmanip")])
329 (define_expand "rotrsi3"
330   [(set (match_operand:SI 0 "register_operand" "=r")
331        (rotatert:SI (match_operand:SI 1 "register_operand" "r")
332                     (match_operand:QI 2 "arith_operand" "rI")))]
333   "TARGET_ZBB || TARGET_ZBKB || TARGET_XTHEADBB"
335   if (TARGET_XTHEADBB && !immediate_operand (operands[2], VOIDmode))
336     FAIL;
337   if (TARGET_64BIT && register_operand (operands[2], QImode))
338     {
339       rtx t = gen_reg_rtx (DImode);
340       emit_insn (gen_rotrsi3_sext (t, operands[1], operands[2]));
341       t = gen_lowpart (SImode, t);
342       SUBREG_PROMOTED_VAR_P (t) = 1;
343       SUBREG_PROMOTED_SET (t, SRP_SIGNED);
344       emit_move_insn (operands[0], t);
345       DONE;
346     }
349 (define_insn "*rotrdi3"
350   [(set (match_operand:DI 0 "register_operand" "=r")
351         (rotatert:DI (match_operand:DI 1 "register_operand" "r")
352                      (match_operand:QI 2 "arith_operand" "rI")))]
353   "TARGET_64BIT && (TARGET_ZBB || TARGET_ZBKB)"
354   "ror%i2\t%0,%1,%2"
355   [(set_attr "type" "bitmanip")])
357 (define_insn "rotrsi3_sext"
358   [(set (match_operand:DI 0 "register_operand" "=r")
359         (sign_extend:DI (rotatert:SI (match_operand:SI 1 "register_operand" "r")
360                                  (match_operand:QI 2 "arith_operand" "rI"))))]
361   "TARGET_64BIT && (TARGET_ZBB || TARGET_ZBKB)"
362   "ror%i2%~\t%0,%1,%2"
363   [(set_attr "type" "bitmanip")])
365 (define_insn "*rotlsi3"
366   [(set (match_operand:SI 0 "register_operand" "=r")
367         (rotate:SI (match_operand:SI 1 "register_operand" "r")
368                    (match_operand:QI 2 "register_operand" "r")))]
369   "TARGET_ZBB || TARGET_ZBKB"
370   "rol%~\t%0,%1,%2"
371   [(set_attr "type" "bitmanip")])
373 (define_expand "rotlsi3"
374   [(set (match_operand:SI 0 "register_operand" "=r")
375        (rotate:SI (match_operand:SI 1 "register_operand" "r")
376                   (match_operand:QI 2 "register_operand" "r")))]
377   "TARGET_ZBB || TARGET_ZBKB"
379   if (TARGET_64BIT)
380     {
381       rtx t = gen_reg_rtx (DImode);
382       emit_insn (gen_rotlsi3_sext (t, operands[1], operands[2]));
383       t = gen_lowpart (SImode, t);
384       SUBREG_PROMOTED_VAR_P (t) = 1;
385       SUBREG_PROMOTED_SET (t, SRP_SIGNED);
386       emit_move_insn (operands[0], t);
387       DONE;
388     }
391 (define_insn "rotldi3"
392   [(set (match_operand:DI 0 "register_operand" "=r")
393         (rotate:DI (match_operand:DI 1 "register_operand" "r")
394                    (match_operand:QI 2 "register_operand" "r")))]
395   "TARGET_64BIT && (TARGET_ZBB || TARGET_ZBKB)"
396   "rol\t%0,%1,%2"
397   [(set_attr "type" "bitmanip")])
399 (define_insn "rotlsi3_sext"
400   [(set (match_operand:DI 0 "register_operand" "=r")
401         (sign_extend:DI (rotate:SI (match_operand:SI 1 "register_operand" "r")
402                                    (match_operand:QI 2 "register_operand" "r"))))]
403   "TARGET_64BIT && (TARGET_ZBB || TARGET_ZBKB)"
404   "rolw\t%0,%1,%2"
405   [(set_attr "type" "bitmanip")])
407 (define_insn_and_split "*<bitmanip_optab><GPR:mode>3_mask"
408   [(set (match_operand:GPR     0 "register_operand" "= r")
409         (bitmanip_rotate:GPR
410             (match_operand:GPR 1 "register_operand" "  r")
411             (match_operator 4 "subreg_lowpart_operator"
412              [(and:GPR2
413                (match_operand:GPR2 2 "register_operand"  "r")
414                (match_operand 3 "<GPR:shiftm1>" "<GPR:shiftm1p>"))])))]
415   "TARGET_ZBB || TARGET_ZBKB"
416   "#"
417   "&& 1"
418   [(set (match_dup 0)
419         (bitmanip_rotate:GPR (match_dup 1)
420                              (match_dup 2)))]
421   "operands[2] = gen_lowpart (QImode, operands[2]);"
422   [(set_attr "type" "bitmanip")
423    (set_attr "mode" "<GPR:MODE>")])
425 (define_insn_and_split "*<bitmanip_optab>si3_sext_mask"
426   [(set (match_operand:DI     0 "register_operand" "= r")
427   (sign_extend:DI (bitmanip_rotate:SI
428             (match_operand:SI 1 "register_operand" "  r")
429             (match_operator 4 "subreg_lowpart_operator"
430              [(and:GPR
431                (match_operand:GPR 2 "register_operand"  "r")
432                (match_operand 3 "const_si_mask_operand"))]))))]
433   "TARGET_64BIT && (TARGET_ZBB || TARGET_ZBKB)"
434   "#"
435   "&& 1"
436   [(set (match_dup 0)
437   (sign_extend:DI (bitmanip_rotate:SI (match_dup 1)
438                            (match_dup 2))))]
439   "operands[2] = gen_lowpart (QImode, operands[2]);"
440   [(set_attr "type" "bitmanip")
441    (set_attr "mode" "DI")])
443 ;; orc.b (or-combine) is added as an unspec for the benefit of the support
444 ;; for optimized string functions (such as strcmp).
445 (define_insn "orcb<mode>2"
446   [(set (match_operand:GPR 0 "register_operand" "=r")
447         (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")] UNSPEC_ORC_B))]
448   "TARGET_ZBB"
449   "orc.b\t%0,%1"
450   [(set_attr "type" "bitmanip")])
452 (define_expand "bswapdi2"
453   [(set (match_operand:DI 0 "register_operand")
454         (bswap:DI (match_operand:DI 1 "register_operand")))]
455   "TARGET_64BIT && (TARGET_ZBB || TARGET_XTHEADBB || TARGET_ZBKB)")
457 (define_expand "bswapsi2"
458   [(set (match_operand:SI 0 "register_operand")
459         (bswap:SI (match_operand:SI 1 "register_operand")))]
460   "TARGET_ZBB || TARGET_ZBKB || TARGET_XTHEADBB"
462   /* Expose bswapsi2 on TARGET_64BIT so that the gimple store
463      merging pass will create suitable bswap insns.  We can actually
464      just FAIL that case when generating RTL and let the generic code
465      handle it.  */
466   if (TARGET_64BIT && !TARGET_XTHEADBB)
467     FAIL;
471 (define_insn "*bswap<mode>2"
472   [(set (match_operand:X 0 "register_operand" "=r")
473         (bswap:X (match_operand:X 1 "register_operand" "r")))]
474   "TARGET_ZBB || TARGET_ZBKB"
475   "rev8\t%0,%1"
476   [(set_attr "type" "bitmanip")])
478 ;; HI bswap can be emulated using SI/DI bswap followed
479 ;; by a logical shift right
480 ;; SI bswap for TARGET_64BIT is already similarly in
481 ;; the common code.
482 (define_expand "bswaphi2"
483   [(set (match_operand:HI 0 "register_operand" "=r")
484         (bswap:HI (match_operand:HI 1 "register_operand" "r")))]
485   "TARGET_ZBB"
487   rtx tmp = gen_reg_rtx (word_mode);
488   rtx newop1 = gen_lowpart (word_mode, operands[1]);
489   if (TARGET_64BIT)
490     emit_insn (gen_bswapdi2 (tmp, newop1));
491   else
492     emit_insn (gen_bswapsi2 (tmp, newop1));
493   rtx tmp1 = gen_reg_rtx (word_mode);
494   if (TARGET_64BIT)
495     emit_insn (gen_lshrdi3 (tmp1, tmp, GEN_INT (64 - 16)));
496   else
497     emit_insn (gen_lshrsi3 (tmp1, tmp, GEN_INT (32 - 16)));
498   emit_move_insn (operands[0], gen_lowpart (HImode, tmp1));
499   DONE;
502 (define_expand "<bitmanip_optab>di3"
503   [(set (match_operand:DI 0 "register_operand" "=r")
504         (bitmanip_minmax:DI (match_operand:DI 1 "register_operand" "r")
505                             (match_operand:DI 2 "register_operand" "r")))]
506   "TARGET_64BIT && TARGET_ZBB")
508 (define_expand "<bitmanip_optab>si3"
509   [(set (match_operand:SI 0 "register_operand" "=r")
510         (bitmanip_minmax:SI (match_operand:SI 1 "register_operand" "r")
511                             (match_operand:SI 2 "register_operand" "r")))]
512   "TARGET_ZBB"
514   if (TARGET_64BIT)
515     {
516       rtx t = gen_reg_rtx (DImode);
517       operands[1] = force_reg (DImode, gen_rtx_SIGN_EXTEND (DImode, operands[1]));
518       operands[2] = force_reg (DImode, gen_rtx_SIGN_EXTEND (DImode, operands[2]));
519       emit_insn (gen_<bitmanip_optab>di3 (t, operands[1], operands[2]));
520       emit_move_insn (operands[0], gen_lowpart (SImode, t));
521       DONE;
522     }
525 (define_insn "*<bitmanip_optab><mode>3"
526   [(set (match_operand:X 0 "register_operand" "=r")
527         (bitmanip_minmax:X (match_operand:X 1 "register_operand" "r")
528                            (match_operand:X 2 "reg_or_0_operand" "rJ")))]
529   "TARGET_ZBB"
530   "<bitmanip_insn>\t%0,%1,%z2"
531   [(set_attr "type" "<bitmanip_insn>")])
533 ;; Optimize the common case of a SImode min/max against a constant
534 ;; that is safe both for sign- and zero-extension.
535 (define_insn_and_split "*minmax"
536   [(set (match_operand:DI 0 "register_operand" "=r")
537         (sign_extend:DI
538           (subreg:SI
539             (bitmanip_minmax:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
540                                                 (match_operand:DI 2 "immediate_operand" "i"))
541            0)))
542    (clobber (match_scratch:DI 3 "=&r"))
543    (clobber (match_scratch:DI 4 "=&r"))]
544   "TARGET_64BIT && TARGET_ZBB && sext_hwi (INTVAL (operands[2]), 32) >= 0"
545   "#"
546   "&& reload_completed"
547   [(set (match_dup 3) (sign_extend:DI (match_dup 1)))
548    (set (match_dup 4) (match_dup 2))
549    (set (match_dup 0) (<minmax_optab>:DI (match_dup 3) (match_dup 4)))]
550   ""
551   [(set_attr "type" "bitmanip")])
553 ;; ZBS extension.
555 (define_insn "*bset<mode>"
556   [(set (match_operand:X 0 "register_operand" "=r")
557         (ior:X (ashift:X (const_int 1)
558                          (match_operand:QI 2 "register_operand" "r"))
559                (match_operand:X 1 "register_operand" "r")))]
560   "TARGET_ZBS"
561   "bset\t%0,%1,%2"
562   [(set_attr "type" "bitmanip")])
564 (define_insn "*bset<mode>_mask"
565   [(set (match_operand:X 0 "register_operand" "=r")
566         (ior:X (ashift:X (const_int 1)
567                          (subreg:QI
568                           (and:X (match_operand:X 2 "register_operand" "r")
569                                  (match_operand 3 "<X:shiftm1>" "<X:shiftm1p>")) 0))
570                (match_operand:X 1 "register_operand" "r")))]
571   "TARGET_ZBS"
572   "bset\t%0,%1,%2"
573   [(set_attr "type" "bitmanip")])
575 (define_insn "*bset<mode>_1"
576   [(set (match_operand:X 0 "register_operand" "=r")
577         (ashift:X (const_int 1)
578                   (match_operand:QI 1 "register_operand" "r")))]
579   "TARGET_ZBS"
580   "bset\t%0,x0,%1"
581   [(set_attr "type" "bitmanip")])
583 (define_insn "*bset<mode>_1_mask"
584   [(set (match_operand:X 0 "register_operand" "=r")
585         (ashift:X (const_int 1)
586                   (subreg:QI
587                    (and:X (match_operand:X 1 "register_operand" "r")
588                           (match_operand 2 "<X:shiftm1>" "<X:shiftm1p>")) 0)))]
589   "TARGET_ZBS"
590   "bset\t%0,x0,%1"
591   [(set_attr "type" "bitmanip")])
593 (define_insn "*bseti<mode>"
594   [(set (match_operand:X 0 "register_operand" "=r")
595         (ior:X (match_operand:X 1 "register_operand" "r")
596                (match_operand:X 2 "single_bit_mask_operand" "DbS")))]
597   "TARGET_ZBS"
598   "bseti\t%0,%1,%S2"
599   [(set_attr "type" "bitmanip")])
601 ;; As long as the SImode operand is not a partial subreg, we can use a
602 ;; bseti without postprocessing, as the middle end is smart enough to
603 ;; stay away from the signbit.
604 (define_insn "*bsetidisi"
605   [(set (match_operand:DI 0 "register_operand" "=r")
606         (ior:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
607                 (match_operand 2 "single_bit_mask_operand" "i")))]
608   "TARGET_ZBS && TARGET_64BIT
609    && !partial_subreg_p (operands[1])"
610   "bseti\t%0,%1,%S2"
611   [(set_attr "type" "bitmanip")])
613 (define_insn "*bclr<mode>"
614   [(set (match_operand:X 0 "register_operand" "=r")
615         (and:X (rotate:X (const_int -2)
616                          (match_operand:QI 2 "register_operand" "r"))
617                (match_operand:X 1 "register_operand" "r")))]
618   "TARGET_ZBS"
619   "bclr\t%0,%1,%2"
620   [(set_attr "type" "bitmanip")])
622 (define_insn "*bclri<mode>"
623   [(set (match_operand:X 0 "register_operand" "=r")
624         (and:X (match_operand:X 1 "register_operand" "r")
625                (match_operand:X 2 "not_single_bit_mask_operand" "DnS")))]
626   "TARGET_ZBS"
627   "bclri\t%0,%1,%T2"
628   [(set_attr "type" "bitmanip")])
630 ;; In case we have "val & ~IMM" where ~IMM has 2 bits set.
631 (define_insn_and_split "*bclri<mode>_nottwobits"
632   [(set (match_operand:X 0 "register_operand" "=r")
633         (and:X (match_operand:X 1 "register_operand" "r")
634                (match_operand:X 2 "const_nottwobits_not_arith_operand" "i")))]
635   "TARGET_ZBS && !paradoxical_subreg_p (operands[1])"
636   "#"
637   "&& reload_completed"
638   [(set (match_dup 0) (and:X (match_dup 1) (match_dup 3)))
639    (set (match_dup 0) (and:X (match_dup 0) (match_dup 4)))]
641         unsigned HOST_WIDE_INT bits = ~UINTVAL (operands[2]);
642         unsigned HOST_WIDE_INT topbit = HOST_WIDE_INT_1U << floor_log2 (bits);
644         operands[3] = GEN_INT (~bits | topbit);
645         operands[4] = GEN_INT (~topbit);
647 [(set_attr "type" "bitmanip")])
649 ;; In case of a paradoxical subreg, the sign bit and the high bits are
650 ;; not allowed to be changed
651 (define_insn_and_split "*bclridisi_nottwobits"
652   [(set (match_operand:DI 0 "register_operand" "=r")
653         (and:DI (match_operand:DI 1 "register_operand" "r")
654                 (match_operand:DI 2 "const_nottwobits_not_arith_operand" "i")))]
655   "TARGET_64BIT && TARGET_ZBS
656    && clz_hwi (~UINTVAL (operands[2])) > 33"
657   "#"
658   "&& reload_completed"
659   [(set (match_dup 0) (and:DI (match_dup 1) (match_dup 3)))
660    (set (match_dup 0) (and:DI (match_dup 0) (match_dup 4)))]
662         unsigned HOST_WIDE_INT bits = ~UINTVAL (operands[2]);
663         unsigned HOST_WIDE_INT topbit = HOST_WIDE_INT_1U << floor_log2 (bits);
665         operands[3] = GEN_INT (~bits | topbit);
666         operands[4] = GEN_INT (~topbit);
668 [(set_attr "type" "bitmanip")])
670 (define_insn "*binv<mode>"
671   [(set (match_operand:X 0 "register_operand" "=r")
672         (xor:X (ashift:X (const_int 1)
673                          (match_operand:QI 2 "register_operand" "r"))
674                (match_operand:X 1 "register_operand" "r")))]
675   "TARGET_ZBS"
676   "binv\t%0,%1,%2"
677   [(set_attr "type" "bitmanip")])
679 (define_insn "*binvi<mode>"
680   [(set (match_operand:X 0 "register_operand" "=r")
681         (xor:X (match_operand:X 1 "register_operand" "r")
682                (match_operand:X 2 "single_bit_mask_operand" "DbS")))]
683   "TARGET_ZBS"
684   "binvi\t%0,%1,%S2"
685   [(set_attr "type" "bitmanip")])
687 (define_insn "*bext<mode>"
688   [(set (match_operand:X 0 "register_operand" "=r")
689         (zero_extract:X (match_operand:X 1 "register_operand" "r")
690                         (const_int 1)
691                         (zero_extend:X
692                          (match_operand:QI 2 "register_operand" "r"))))]
693   "TARGET_ZBS"
694   "bext\t%0,%1,%2"
695   [(set_attr "type" "bitmanip")])
697 ;; When performing `(a & (1UL << bitno)) ? 0 : -1` the combiner
698 ;; usually has the `bitno` typed as X-mode (i.e. no further
699 ;; zero-extension is performed around the bitno).
700 (define_insn "*bext<mode>"
701   [(set (match_operand:X 0 "register_operand" "=r")
702         (zero_extract:X (match_operand:X 1 "register_operand" "r")
703                         (const_int 1)
704                         (match_operand:X 2 "register_operand" "r")))]
705   "TARGET_ZBS"
706   "bext\t%0,%1,%2"
707   [(set_attr "type" "bitmanip")])
709 (define_insn "*bexti"
710   [(set (match_operand:X 0 "register_operand" "=r")
711         (zero_extract:X (match_operand:X 1 "register_operand" "r")
712                         (const_int 1)
713                         (match_operand 2 "immediate_operand" "n")))]
714   "TARGET_ZBS && UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
715   "bexti\t%0,%1,%2"
716   [(set_attr "type" "bitmanip")])
718 ;; Split for "(a & (1 << BIT_NO)) ? 0 : 1":
719 ;; We avoid reassociating "(~(a >> BIT_NO)) & 1" into "((~a) >> BIT_NO) & 1",
720 ;; so we don't have to use a temporary.  Instead we extract the bit and then
721 ;; invert bit 0 ("a ^ 1") only.
722 (define_split
723   [(set (match_operand:X 0 "register_operand")
724         (and:X (not:X (lshiftrt:X (match_operand:X 1 "register_operand")
725                                   (subreg:QI (match_operand:X 2 "register_operand") 0)))
726                (const_int 1)))]
727   "TARGET_ZBS"
728   [(set (match_dup 0) (zero_extract:X (match_dup 1)
729                                       (const_int 1)
730                                       (match_dup 2)))
731    (set (match_dup 0) (xor:X (match_dup 0) (const_int 1)))])
733 ;; We can create a polarity-reversed mask (i.e. bit N -> { set = 0, clear = -1 })
734 ;; using a bext(i) followed by an addi instruction.
735 ;; This splits the canonical representation of "(a & (1 << BIT_NO)) ? 0 : -1".
736 (define_split
737   [(set (match_operand:GPR 0 "register_operand")
738        (neg:GPR (eq:GPR (zero_extract:GPR (match_operand:GPR 1 "register_operand")
739                                           (const_int 1)
740                                           (match_operand 2))
741                         (const_int 0))))]
742   "TARGET_ZBS"
743   [(set (match_dup 0) (zero_extract:GPR (match_dup 1) (const_int 1) (match_dup 2)))
744    (set (match_dup 0) (plus:GPR (match_dup 0) (const_int -1)))])
746 ;; Catch those cases where we can use a bseti/binvi + ori/xori or
747 ;; bseti/binvi + bseti/binvi instead of a lui + addi + or/xor sequence.
748 (define_insn_and_split "*<or_optab>i<mode>_extrabit"
749   [(set (match_operand:X 0 "register_operand" "=r")
750         (any_or:X (match_operand:X 1 "register_operand" "r")
751                   (match_operand:X 2 "uimm_extra_bit_or_twobits" "i")))]
752   "TARGET_ZBS"
753   "#"
754   "&& reload_completed"
755   [(set (match_dup 0) (<or_optab>:X (match_dup 1) (match_dup 3)))
756    (set (match_dup 0) (<or_optab>:X (match_dup 0) (match_dup 4)))]
758         unsigned HOST_WIDE_INT bits = UINTVAL (operands[2]);
759         unsigned HOST_WIDE_INT topbit = HOST_WIDE_INT_1U << floor_log2 (bits);
761         operands[3] = GEN_INT (bits &~ topbit);
762         operands[4] = GEN_INT (topbit);
764 [(set_attr "type" "bitmanip")])
766 ;; Same to use blcri + andi and blcri + bclri
767 (define_insn_and_split "*andi<mode>_extrabit"
768   [(set (match_operand:X 0 "register_operand" "=r")
769         (and:X (match_operand:X 1 "register_operand" "r")
770                (match_operand:X 2 "not_uimm_extra_bit_or_nottwobits" "i")))]
771   "TARGET_ZBS"
772   "#"
773   "&& reload_completed"
774   [(set (match_dup 0) (and:X (match_dup 1) (match_dup 3)))
775    (set (match_dup 0) (and:X (match_dup 0) (match_dup 4)))]
777         unsigned HOST_WIDE_INT bits = UINTVAL (operands[2]);
778         unsigned HOST_WIDE_INT topbit = HOST_WIDE_INT_1U << floor_log2 (~bits);
780         operands[3] = GEN_INT (bits | topbit);
781         operands[4] = GEN_INT (~topbit);
783 [(set_attr "type" "bitmanip")])
785 ;; IF_THEN_ELSE: test for 2 bits of opposite polarity
786 (define_insn_and_split "*branch<X:mode>_mask_twobits_equals_singlebit"
787   [(set (pc)
788         (if_then_else
789           (match_operator 1 "equality_operator"
790             [(and:X (match_operand:X 2 "register_operand" "r")
791                     (match_operand:X 3 "const_twobits_not_arith_operand" "i"))
792              (match_operand:X 4 "single_bit_mask_operand" "i")])
793          (label_ref (match_operand 0 "" ""))
794          (pc)))
795    (clobber (match_scratch:X 5 "=&r"))
796    (clobber (match_scratch:X 6 "=&r"))]
797   "TARGET_ZBS && TARGET_ZBB"
798   "#"
799   "&& reload_completed"
800   [(set (match_dup 5) (zero_extract:X (match_dup 2)
801                                       (const_int 1)
802                                       (match_dup 8)))
803    (set (match_dup 6) (zero_extract:X (match_dup 2)
804                                       (const_int 1)
805                                       (match_dup 9)))
806    (set (match_dup 6) (and:X (not:X (match_dup 6)) (match_dup 5)))
807    (set (pc) (if_then_else (match_op_dup 1 [(match_dup 6) (const_int 0)])
808                            (label_ref (match_dup 0))
809                            (pc)))]
811    unsigned HOST_WIDE_INT twobits_mask = UINTVAL (operands[3]);
812    unsigned HOST_WIDE_INT singlebit_mask = UINTVAL (operands[4]);
814    /* We should never see an unsatisfiable condition.  */
815    gcc_assert (twobits_mask & singlebit_mask);
817    int setbit = ctz_hwi (singlebit_mask);
818    int clearbit = ctz_hwi (twobits_mask & ~singlebit_mask);
820    operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == NE ? EQ : NE,
821                                  <X:MODE>mode, operands[6], GEN_INT(0));
823    operands[8] = GEN_INT (setbit);
824    operands[9] = GEN_INT (clearbit);
826 [(set_attr "type" "bitmanip")])
828 ;; IF_THEN_ELSE: test for (a & (1 << BIT_NO))
829 (define_insn_and_split "*branch<X:mode>_bext"
830   [(set (pc)
831         (if_then_else
832           (match_operator 1 "equality_operator"
833          [(zero_extract:X (match_operand:X 2 "register_operand" "r")
834                           (const_int 1)
835                           (zero_extend:X
836                             (match_operand:QI 3 "register_operand" "r")))
837             (const_int 0)])
838         (label_ref (match_operand 0 "" ""))
839         (pc)))
840   (clobber (match_scratch:X 4 "=&r"))]
841   "TARGET_ZBS"
842   "#"
843   "&& reload_completed"
844   [(set (match_dup 4) (zero_extract:X (match_dup 2)
845                                         (const_int 1)
846                                         (zero_extend:X (match_dup 3))))
847    (set (pc) (if_then_else (match_op_dup 1 [(match_dup 4) (const_int 0)])
848                            (label_ref (match_dup 0))
849                            (pc)))]
850    ""
851   [(set_attr "type" "bitmanip")])
853 ;; ZBKC or ZBC extension
854 (define_insn "riscv_clmul_<mode>"
855   [(set (match_operand:GPR 0 "register_operand" "=r")
856         (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
857                   (match_operand:GPR 2 "register_operand" "r")]
858                   UNSPEC_CLMUL))]
859   "TARGET_ZBKC || TARGET_ZBC"
860   "clmul\t%0,%1,%2"
861   [(set_attr "type" "clmul")])
863 (define_insn "riscv_clmulh_<mode>"
864   [(set (match_operand:X 0 "register_operand" "=r")
865         (unspec:X [(match_operand:X 1 "register_operand" "r")
866                   (match_operand:X 2 "register_operand" "r")]
867                   UNSPEC_CLMULH))]
868   "TARGET_ZBKC || TARGET_ZBC"
869   "clmulh\t%0,%1,%2"
870   [(set_attr "type" "clmul")])
872 ;; ZBC extension
873 (define_insn "riscv_clmulr_<mode>"
874   [(set (match_operand:X 0 "register_operand" "=r")
875         (unspec:X [(match_operand:X 1 "register_operand" "r")
876                   (match_operand:X 2 "register_operand" "r")]
877                   UNSPEC_CLMULR))]
878   "TARGET_ZBC"
879   "clmulr\t%0,%1,%2"
880   [(set_attr "type" "clmul")])