]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/riscv/bitmanip.md
RISC-V: Replace not + bitwise_imm with li + bitwise_not
[thirdparty/gcc.git] / gcc / config / riscv / bitmanip.md
1 ;; Machine description for RISC-V Bit Manipulation operations.
2 ;; Copyright (C) 2021-2023 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 (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))))])
58
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).
64 ;
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)))])
75
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)))])
86
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)))]
104 {
105 operands[3] = GEN_INT (INTVAL (operands[3]) >> INTVAL (operands[2]));
106 }
107 [(set_attr "type" "bitmanip")])
108
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")])
121
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)))]
142 {
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;
148
149 /* If the bias + scale don't add up to operand[2], reject. */
150 if ((scale + bias) != UINTVAL (operands[2]))
151 FAIL;
152
153 /* If the shift-amount is out-of-range for sh[123]add.uw, reject. */
154 if ((scale < 1) || (scale > 3))
155 FAIL;
156
157 /* If there's no bias, the '*shNadduw' pattern should have matched. */
158 if (bias == 0)
159 FAIL;
160
161 operands[6] = GEN_INT (bias);
162 operands[7] = GEN_INT (scale);
163 operands[8] = GEN_INT (0xffffffffULL << scale);
164 })
165
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")])
175
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")])
186
187 ;; ZBB extension.
188
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)")
193
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)")
198
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")
203
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")
208
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>")])
217
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 ;; '(a >= 0) ? b : 0' is emitted branchless (from if-conversion). Without a
231 ;; bit of extra help for combine (i.e., the below split), we end up emitting
232 ;; not/srai/and instead of combining the not into an andn.
233 (define_split
234 [(set (match_operand:DI 0 "register_operand")
235 (and:DI (neg:DI (ge:DI (match_operand:DI 1 "register_operand")
236 (const_int 0)))
237 (match_operand:DI 2 "register_operand")))
238 (clobber (match_operand:DI 3 "register_operand"))]
239 "TARGET_ZBB || TARGET_ZBKB"
240 [(set (match_dup 3) (ashiftrt:DI (match_dup 1) (const_int 63)))
241 (set (match_dup 0) (and:DI (not:DI (match_dup 3)) (match_dup 2)))])
242
243 (define_insn "*xor_not<mode>"
244 [(set (match_operand:X 0 "register_operand" "=r")
245 (not:X (xor:X (match_operand:X 1 "register_operand" "r")
246 (match_operand:X 2 "register_operand" "r"))))]
247 "TARGET_ZBB || TARGET_ZBKB"
248 "xnor\t%0,%1,%2"
249 [(set_attr "type" "bitmanip")
250 (set_attr "mode" "<X:MODE>")])
251
252 (define_insn "*<bitmanip_optab>si2"
253 [(set (match_operand:SI 0 "register_operand" "=r")
254 (clz_ctz_pcnt:SI (match_operand:SI 1 "register_operand" "r")))]
255 "TARGET_ZBB"
256 "<bitmanip_insn>%~\t%0,%1"
257 [(set_attr "type" "<bitmanip_insn>")
258 (set_attr "mode" "SI")])
259
260 (define_insn "*<bitmanip_optab>disi2"
261 [(set (match_operand:DI 0 "register_operand" "=r")
262 (any_extend:DI
263 (clz_ctz_pcnt:SI (match_operand:SI 1 "register_operand" "r"))))]
264 "TARGET_64BIT && TARGET_ZBB"
265 "<bitmanip_insn>w\t%0,%1"
266 [(set_attr "type" "<bitmanip_insn>")
267 (set_attr "mode" "SI")])
268
269 ;; A SImode clz_ctz_pcnt may be extended to DImode via subreg.
270 (define_insn "*<bitmanip_optab>disi2_sext"
271 [(set (match_operand:DI 0 "register_operand" "=r")
272 (and:DI (subreg:DI
273 (clz_ctz_pcnt:SI (match_operand:SI 1 "register_operand" "r")) 0)
274 (match_operand:DI 2 "const_int_operand")))]
275 "TARGET_64BIT && TARGET_ZBB && ((INTVAL (operands[2]) & 0x3f) == 0x3f)"
276 "<bitmanip_insn>w\t%0,%1"
277 [(set_attr "type" "<bitmanip_insn>")
278 (set_attr "mode" "SI")])
279
280 (define_insn "*<bitmanip_optab>di2"
281 [(set (match_operand:DI 0 "register_operand" "=r")
282 (clz_ctz_pcnt:DI (match_operand:DI 1 "register_operand" "r")))]
283 "TARGET_64BIT && TARGET_ZBB"
284 "<bitmanip_insn>\t%0,%1"
285 [(set_attr "type" "<bitmanip_insn>")
286 (set_attr "mode" "DI")])
287
288 (define_insn "*zero_extendhi<GPR:mode>2_bitmanip"
289 [(set (match_operand:GPR 0 "register_operand" "=r,r")
290 (zero_extend:GPR (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
291 "TARGET_ZBB"
292 "@
293 zext.h\t%0,%1
294 lhu\t%0,%1"
295 [(set_attr "type" "bitmanip,load")
296 (set_attr "mode" "<GPR:MODE>")])
297
298 (define_insn "*extend<SHORT:mode><SUPERQI:mode>2_bitmanip"
299 [(set (match_operand:SUPERQI 0 "register_operand" "=r,r")
300 (sign_extend:SUPERQI
301 (match_operand:SHORT 1 "nonimmediate_operand" " r,m")))]
302 "TARGET_ZBB"
303 "@
304 sext.<SHORT:size>\t%0,%1
305 l<SHORT:size>\t%0,%1"
306 [(set_attr "type" "bitmanip,load")
307 (set_attr "mode" "<SUPERQI:MODE>")])
308
309 (define_expand "rotrdi3"
310 [(set (match_operand:DI 0 "register_operand")
311 (rotatert:DI (match_operand:DI 1 "register_operand")
312 (match_operand:QI 2 "arith_operand")))]
313 "TARGET_64BIT && (TARGET_ZBB || TARGET_XTHEADBB || TARGET_ZBKB)"
314 {
315 if (TARGET_XTHEADBB && !immediate_operand (operands[2], VOIDmode))
316 FAIL;
317 })
318
319 (define_insn "*rotrsi3"
320 [(set (match_operand:SI 0 "register_operand" "=r")
321 (rotatert:SI (match_operand:SI 1 "register_operand" "r")
322 (match_operand:QI 2 "arith_operand" "rI")))]
323 "TARGET_ZBB || TARGET_ZBKB"
324 "ror%i2%~\t%0,%1,%2"
325 [(set_attr "type" "bitmanip")])
326
327 (define_expand "rotrsi3"
328 [(set (match_operand:SI 0 "register_operand" "=r")
329 (rotatert:SI (match_operand:SI 1 "register_operand" "r")
330 (match_operand:QI 2 "arith_operand" "rI")))]
331 "TARGET_ZBB || TARGET_ZBKB || TARGET_XTHEADBB"
332 {
333 if (TARGET_XTHEADBB && !immediate_operand (operands[2], VOIDmode))
334 FAIL;
335 if (TARGET_64BIT && register_operand (operands[2], QImode))
336 {
337 rtx t = gen_reg_rtx (DImode);
338 emit_insn (gen_rotrsi3_sext (t, operands[1], operands[2]));
339 t = gen_lowpart (SImode, t);
340 SUBREG_PROMOTED_VAR_P (t) = 1;
341 SUBREG_PROMOTED_SET (t, SRP_SIGNED);
342 emit_move_insn (operands[0], t);
343 DONE;
344 }
345 })
346
347 (define_insn "*rotrdi3"
348 [(set (match_operand:DI 0 "register_operand" "=r")
349 (rotatert:DI (match_operand:DI 1 "register_operand" "r")
350 (match_operand:QI 2 "arith_operand" "rI")))]
351 "TARGET_64BIT && (TARGET_ZBB || TARGET_ZBKB)"
352 "ror%i2\t%0,%1,%2"
353 [(set_attr "type" "bitmanip")])
354
355 (define_insn "rotrsi3_sext"
356 [(set (match_operand:DI 0 "register_operand" "=r")
357 (sign_extend:DI (rotatert:SI (match_operand:SI 1 "register_operand" "r")
358 (match_operand:QI 2 "arith_operand" "rI"))))]
359 "TARGET_64BIT && (TARGET_ZBB || TARGET_ZBKB)"
360 "ror%i2%~\t%0,%1,%2"
361 [(set_attr "type" "bitmanip")])
362
363 (define_insn "*rotlsi3"
364 [(set (match_operand:SI 0 "register_operand" "=r")
365 (rotate:SI (match_operand:SI 1 "register_operand" "r")
366 (match_operand:QI 2 "register_operand" "r")))]
367 "TARGET_ZBB || TARGET_ZBKB"
368 "rol%~\t%0,%1,%2"
369 [(set_attr "type" "bitmanip")])
370
371 (define_expand "rotlsi3"
372 [(set (match_operand:SI 0 "register_operand" "=r")
373 (rotate:SI (match_operand:SI 1 "register_operand" "r")
374 (match_operand:QI 2 "register_operand" "r")))]
375 "TARGET_ZBB || TARGET_ZBKB"
376 {
377 if (TARGET_64BIT)
378 {
379 rtx t = gen_reg_rtx (DImode);
380 emit_insn (gen_rotlsi3_sext (t, operands[1], operands[2]));
381 t = gen_lowpart (SImode, t);
382 SUBREG_PROMOTED_VAR_P (t) = 1;
383 SUBREG_PROMOTED_SET (t, SRP_SIGNED);
384 emit_move_insn (operands[0], t);
385 DONE;
386 }
387 })
388
389 (define_insn "rotldi3"
390 [(set (match_operand:DI 0 "register_operand" "=r")
391 (rotate:DI (match_operand:DI 1 "register_operand" "r")
392 (match_operand:QI 2 "register_operand" "r")))]
393 "TARGET_64BIT && (TARGET_ZBB || TARGET_ZBKB)"
394 "rol\t%0,%1,%2"
395 [(set_attr "type" "bitmanip")])
396
397 (define_insn "rotlsi3_sext"
398 [(set (match_operand:DI 0 "register_operand" "=r")
399 (sign_extend:DI (rotate:SI (match_operand:SI 1 "register_operand" "r")
400 (match_operand:QI 2 "register_operand" "r"))))]
401 "TARGET_64BIT && (TARGET_ZBB || TARGET_ZBKB)"
402 "rolw\t%0,%1,%2"
403 [(set_attr "type" "bitmanip")])
404
405 (define_insn_and_split "*<bitmanip_optab><GPR:mode>3_mask"
406 [(set (match_operand:GPR 0 "register_operand" "= r")
407 (bitmanip_rotate:GPR
408 (match_operand:GPR 1 "register_operand" " r")
409 (match_operator 4 "subreg_lowpart_operator"
410 [(and:GPR2
411 (match_operand:GPR2 2 "register_operand" "r")
412 (match_operand 3 "<GPR:shiftm1>" "<GPR:shiftm1p>"))])))]
413 "TARGET_ZBB || TARGET_ZBKB"
414 "#"
415 "&& 1"
416 [(set (match_dup 0)
417 (bitmanip_rotate:GPR (match_dup 1)
418 (match_dup 2)))]
419 "operands[2] = gen_lowpart (QImode, operands[2]);"
420 [(set_attr "type" "bitmanip")
421 (set_attr "mode" "<GPR:MODE>")])
422
423 (define_insn_and_split "*<bitmanip_optab>si3_sext_mask"
424 [(set (match_operand:DI 0 "register_operand" "= r")
425 (sign_extend:DI (bitmanip_rotate:SI
426 (match_operand:SI 1 "register_operand" " r")
427 (match_operator 4 "subreg_lowpart_operator"
428 [(and:GPR
429 (match_operand:GPR 2 "register_operand" "r")
430 (match_operand 3 "const_si_mask_operand"))]))))]
431 "TARGET_64BIT && (TARGET_ZBB || TARGET_ZBKB)"
432 "#"
433 "&& 1"
434 [(set (match_dup 0)
435 (sign_extend:DI (bitmanip_rotate:SI (match_dup 1)
436 (match_dup 2))))]
437 "operands[2] = gen_lowpart (QImode, operands[2]);"
438 [(set_attr "type" "bitmanip")
439 (set_attr "mode" "DI")])
440
441 ;; orc.b (or-combine) is added as an unspec for the benefit of the support
442 ;; for optimized string functions (such as strcmp).
443 (define_insn "orcb<mode>2"
444 [(set (match_operand:X 0 "register_operand" "=r")
445 (unspec:X [(match_operand:X 1 "register_operand" "r")] UNSPEC_ORC_B))]
446 "TARGET_ZBB"
447 "orc.b\t%0,%1"
448 [(set_attr "type" "bitmanip")])
449
450 (define_expand "bswapdi2"
451 [(set (match_operand:DI 0 "register_operand")
452 (bswap:DI (match_operand:DI 1 "register_operand")))]
453 "TARGET_64BIT && (TARGET_ZBB || TARGET_XTHEADBB || TARGET_ZBKB)")
454
455 (define_expand "bswapsi2"
456 [(set (match_operand:SI 0 "register_operand")
457 (bswap:SI (match_operand:SI 1 "register_operand")))]
458 "TARGET_ZBB || TARGET_ZBKB || TARGET_XTHEADBB"
459 {
460 /* Expose bswapsi2 on TARGET_64BIT so that the gimple store
461 merging pass will create suitable bswap insns. We can actually
462 just FAIL that case when generating RTL and let the generic code
463 handle it. */
464 if (TARGET_64BIT && !TARGET_XTHEADBB)
465 FAIL;
466 })
467
468
469 (define_insn "*bswap<mode>2"
470 [(set (match_operand:X 0 "register_operand" "=r")
471 (bswap:X (match_operand:X 1 "register_operand" "r")))]
472 "TARGET_ZBB || TARGET_ZBKB"
473 "rev8\t%0,%1"
474 [(set_attr "type" "bitmanip")])
475
476 ;; HI bswap can be emulated using SI/DI bswap followed
477 ;; by a logical shift right
478 ;; SI bswap for TARGET_64BIT is already similarly in
479 ;; the common code.
480 (define_expand "bswaphi2"
481 [(set (match_operand:HI 0 "register_operand" "=r")
482 (bswap:HI (match_operand:HI 1 "register_operand" "r")))]
483 "TARGET_ZBB"
484 {
485 rtx tmp = gen_reg_rtx (word_mode);
486 rtx newop1 = gen_lowpart (word_mode, operands[1]);
487 if (TARGET_64BIT)
488 emit_insn (gen_bswapdi2 (tmp, newop1));
489 else
490 emit_insn (gen_bswapsi2 (tmp, newop1));
491 rtx tmp1 = gen_reg_rtx (word_mode);
492 if (TARGET_64BIT)
493 emit_insn (gen_lshrdi3 (tmp1, tmp, GEN_INT (64 - 16)));
494 else
495 emit_insn (gen_lshrsi3 (tmp1, tmp, GEN_INT (32 - 16)));
496 emit_move_insn (operands[0], gen_lowpart (HImode, tmp1));
497 DONE;
498 })
499
500 (define_expand "<bitmanip_optab>di3"
501 [(set (match_operand:DI 0 "register_operand" "=r")
502 (bitmanip_minmax:DI (match_operand:DI 1 "register_operand" "r")
503 (match_operand:DI 2 "register_operand" "r")))]
504 "TARGET_64BIT && TARGET_ZBB")
505
506 (define_expand "<bitmanip_optab>si3"
507 [(set (match_operand:SI 0 "register_operand" "=r")
508 (bitmanip_minmax:SI (match_operand:SI 1 "register_operand" "r")
509 (match_operand:SI 2 "register_operand" "r")))]
510 "TARGET_ZBB"
511 {
512 if (TARGET_64BIT)
513 {
514 rtx t = gen_reg_rtx (DImode);
515 operands[1] = force_reg (DImode, gen_rtx_SIGN_EXTEND (DImode, operands[1]));
516 operands[2] = force_reg (DImode, gen_rtx_SIGN_EXTEND (DImode, operands[2]));
517 emit_insn (gen_<bitmanip_optab>di3 (t, operands[1], operands[2]));
518 emit_move_insn (operands[0], gen_lowpart (SImode, t));
519 DONE;
520 }
521 })
522
523 (define_insn "*<bitmanip_optab><mode>3"
524 [(set (match_operand:X 0 "register_operand" "=r")
525 (bitmanip_minmax:X (match_operand:X 1 "register_operand" "r")
526 (match_operand:X 2 "reg_or_0_operand" "rJ")))]
527 "TARGET_ZBB"
528 "<bitmanip_insn>\t%0,%1,%z2"
529 [(set_attr "type" "<bitmanip_insn>")])
530
531 ;; Optimize the common case of a SImode min/max against a constant
532 ;; that is safe both for sign- and zero-extension.
533 (define_insn_and_split "*minmax"
534 [(set (match_operand:DI 0 "register_operand" "=r")
535 (sign_extend:DI
536 (subreg:SI
537 (bitmanip_minmax:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
538 (match_operand:DI 2 "immediate_operand" "i"))
539 0)))
540 (clobber (match_scratch:DI 3 "=&r"))
541 (clobber (match_scratch:DI 4 "=&r"))]
542 "TARGET_64BIT && TARGET_ZBB && sext_hwi (INTVAL (operands[2]), 32) >= 0"
543 "#"
544 "&& reload_completed"
545 [(set (match_dup 3) (sign_extend:DI (match_dup 1)))
546 (set (match_dup 4) (match_dup 2))
547 (set (match_dup 0) (<minmax_optab>:DI (match_dup 3) (match_dup 4)))]
548 ""
549 [(set_attr "type" "bitmanip")])
550
551 ;; ZBS extension.
552
553 (define_insn "*bset<mode>"
554 [(set (match_operand:X 0 "register_operand" "=r")
555 (ior:X (ashift:X (const_int 1)
556 (match_operand:QI 2 "register_operand" "r"))
557 (match_operand:X 1 "register_operand" "r")))]
558 "TARGET_ZBS"
559 "bset\t%0,%1,%2"
560 [(set_attr "type" "bitmanip")])
561
562 (define_insn "*bset<mode>_mask"
563 [(set (match_operand:X 0 "register_operand" "=r")
564 (ior:X (ashift:X (const_int 1)
565 (subreg:QI
566 (and:X (match_operand:X 2 "register_operand" "r")
567 (match_operand 3 "<X:shiftm1>" "<X:shiftm1p>")) 0))
568 (match_operand:X 1 "register_operand" "r")))]
569 "TARGET_ZBS"
570 "bset\t%0,%1,%2"
571 [(set_attr "type" "bitmanip")])
572
573 (define_insn "*bset<mode>_1"
574 [(set (match_operand:X 0 "register_operand" "=r")
575 (ashift:X (const_int 1)
576 (match_operand:QI 1 "register_operand" "r")))]
577 "TARGET_ZBS"
578 "bset\t%0,x0,%1"
579 [(set_attr "type" "bitmanip")])
580
581 (define_insn "*bset<mode>_1_mask"
582 [(set (match_operand:X 0 "register_operand" "=r")
583 (ashift:X (const_int 1)
584 (subreg:QI
585 (and:X (match_operand:X 1 "register_operand" "r")
586 (match_operand 2 "<X:shiftm1>" "<X:shiftm1p>")) 0)))]
587 "TARGET_ZBS"
588 "bset\t%0,x0,%1"
589 [(set_attr "type" "bitmanip")])
590
591 (define_insn "*bseti<mode>"
592 [(set (match_operand:X 0 "register_operand" "=r")
593 (ior:X (match_operand:X 1 "register_operand" "r")
594 (match_operand:X 2 "single_bit_mask_operand" "DbS")))]
595 "TARGET_ZBS"
596 "bseti\t%0,%1,%S2"
597 [(set_attr "type" "bitmanip")])
598
599 ;; As long as the SImode operand is not a partial subreg, we can use a
600 ;; bseti without postprocessing, as the middle end is smart enough to
601 ;; stay away from the signbit.
602 (define_insn "*bsetidisi"
603 [(set (match_operand:DI 0 "register_operand" "=r")
604 (ior:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
605 (match_operand 2 "single_bit_mask_operand" "i")))]
606 "TARGET_ZBS && TARGET_64BIT
607 && !partial_subreg_p (operands[1])"
608 "bseti\t%0,%1,%S2"
609 [(set_attr "type" "bitmanip")])
610
611 (define_insn "*bclr<mode>"
612 [(set (match_operand:X 0 "register_operand" "=r")
613 (and:X (rotate:X (const_int -2)
614 (match_operand:QI 2 "register_operand" "r"))
615 (match_operand:X 1 "register_operand" "r")))]
616 "TARGET_ZBS"
617 "bclr\t%0,%1,%2"
618 [(set_attr "type" "bitmanip")])
619
620 (define_insn "*bclri<mode>"
621 [(set (match_operand:X 0 "register_operand" "=r")
622 (and:X (match_operand:X 1 "register_operand" "r")
623 (match_operand:X 2 "not_single_bit_mask_operand" "DnS")))]
624 "TARGET_ZBS"
625 "bclri\t%0,%1,%T2"
626 [(set_attr "type" "bitmanip")])
627
628 ;; In case we have "val & ~IMM" where ~IMM has 2 bits set.
629 (define_insn_and_split "*bclri<mode>_nottwobits"
630 [(set (match_operand:X 0 "register_operand" "=r")
631 (and:X (match_operand:X 1 "register_operand" "r")
632 (match_operand:X 2 "const_nottwobits_not_arith_operand" "i")))]
633 "TARGET_ZBS && !paradoxical_subreg_p (operands[1])"
634 "#"
635 "&& reload_completed"
636 [(set (match_dup 0) (and:X (match_dup 1) (match_dup 3)))
637 (set (match_dup 0) (and:X (match_dup 0) (match_dup 4)))]
638 {
639 unsigned HOST_WIDE_INT bits = ~UINTVAL (operands[2]);
640 unsigned HOST_WIDE_INT topbit = HOST_WIDE_INT_1U << floor_log2 (bits);
641
642 operands[3] = GEN_INT (~bits | topbit);
643 operands[4] = GEN_INT (~topbit);
644 }
645 [(set_attr "type" "bitmanip")])
646
647 ;; In case of a paradoxical subreg, the sign bit and the high bits are
648 ;; not allowed to be changed
649 (define_insn_and_split "*bclridisi_nottwobits"
650 [(set (match_operand:DI 0 "register_operand" "=r")
651 (and:DI (match_operand:DI 1 "register_operand" "r")
652 (match_operand:DI 2 "const_nottwobits_not_arith_operand" "i")))]
653 "TARGET_64BIT && TARGET_ZBS
654 && clz_hwi (~UINTVAL (operands[2])) > 33"
655 "#"
656 "&& reload_completed"
657 [(set (match_dup 0) (and:DI (match_dup 1) (match_dup 3)))
658 (set (match_dup 0) (and:DI (match_dup 0) (match_dup 4)))]
659 {
660 unsigned HOST_WIDE_INT bits = ~UINTVAL (operands[2]);
661 unsigned HOST_WIDE_INT topbit = HOST_WIDE_INT_1U << floor_log2 (bits);
662
663 operands[3] = GEN_INT (~bits | topbit);
664 operands[4] = GEN_INT (~topbit);
665 }
666 [(set_attr "type" "bitmanip")])
667
668 (define_insn "*binv<mode>"
669 [(set (match_operand:X 0 "register_operand" "=r")
670 (xor:X (ashift:X (const_int 1)
671 (match_operand:QI 2 "register_operand" "r"))
672 (match_operand:X 1 "register_operand" "r")))]
673 "TARGET_ZBS"
674 "binv\t%0,%1,%2"
675 [(set_attr "type" "bitmanip")])
676
677 (define_insn "*binvi<mode>"
678 [(set (match_operand:X 0 "register_operand" "=r")
679 (xor:X (match_operand:X 1 "register_operand" "r")
680 (match_operand:X 2 "single_bit_mask_operand" "DbS")))]
681 "TARGET_ZBS"
682 "binvi\t%0,%1,%S2"
683 [(set_attr "type" "bitmanip")])
684
685 (define_insn "*bext<mode>"
686 [(set (match_operand:X 0 "register_operand" "=r")
687 (zero_extract:X (match_operand:X 1 "register_operand" "r")
688 (const_int 1)
689 (zero_extend:X
690 (match_operand:QI 2 "register_operand" "r"))))]
691 "TARGET_ZBS"
692 "bext\t%0,%1,%2"
693 [(set_attr "type" "bitmanip")])
694
695 ;; When performing `(a & (1UL << bitno)) ? 0 : -1` the combiner
696 ;; usually has the `bitno` typed as X-mode (i.e. no further
697 ;; zero-extension is performed around the bitno).
698 (define_insn "*bext<mode>"
699 [(set (match_operand:X 0 "register_operand" "=r")
700 (zero_extract:X (match_operand:X 1 "register_operand" "r")
701 (const_int 1)
702 (match_operand:X 2 "register_operand" "r")))]
703 "TARGET_ZBS"
704 "bext\t%0,%1,%2"
705 [(set_attr "type" "bitmanip")])
706
707 (define_insn "*bexti"
708 [(set (match_operand:X 0 "register_operand" "=r")
709 (zero_extract:X (match_operand:X 1 "register_operand" "r")
710 (const_int 1)
711 (match_operand 2 "immediate_operand" "n")))]
712 "TARGET_ZBS && UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
713 "bexti\t%0,%1,%2"
714 [(set_attr "type" "bitmanip")])
715
716 ;; Split for "(a & (1 << BIT_NO)) ? 0 : 1":
717 ;; We avoid reassociating "(~(a >> BIT_NO)) & 1" into "((~a) >> BIT_NO) & 1",
718 ;; so we don't have to use a temporary. Instead we extract the bit and then
719 ;; invert bit 0 ("a ^ 1") only.
720 (define_split
721 [(set (match_operand:X 0 "register_operand")
722 (and:X (not:X (lshiftrt:X (match_operand:X 1 "register_operand")
723 (subreg:QI (match_operand:X 2 "register_operand") 0)))
724 (const_int 1)))]
725 "TARGET_ZBS"
726 [(set (match_dup 0) (zero_extract:X (match_dup 1)
727 (const_int 1)
728 (match_dup 2)))
729 (set (match_dup 0) (xor:X (match_dup 0) (const_int 1)))])
730
731 ;; We can create a polarity-reversed mask (i.e. bit N -> { set = 0, clear = -1 })
732 ;; using a bext(i) followed by an addi instruction.
733 ;; This splits the canonical representation of "(a & (1 << BIT_NO)) ? 0 : -1".
734 (define_split
735 [(set (match_operand:GPR 0 "register_operand")
736 (neg:GPR (eq:GPR (zero_extract:GPR (match_operand:GPR 1 "register_operand")
737 (const_int 1)
738 (match_operand 2))
739 (const_int 0))))]
740 "TARGET_ZBS"
741 [(set (match_dup 0) (zero_extract:GPR (match_dup 1) (const_int 1) (match_dup 2)))
742 (set (match_dup 0) (plus:GPR (match_dup 0) (const_int -1)))])
743
744 ;; Catch those cases where we can use a bseti/binvi + ori/xori or
745 ;; bseti/binvi + bseti/binvi instead of a lui + addi + or/xor sequence.
746 (define_insn_and_split "*<or_optab>i<mode>_extrabit"
747 [(set (match_operand:X 0 "register_operand" "=r")
748 (any_or:X (match_operand:X 1 "register_operand" "r")
749 (match_operand:X 2 "uimm_extra_bit_or_twobits" "i")))]
750 "TARGET_ZBS"
751 "#"
752 "&& reload_completed"
753 [(set (match_dup 0) (<or_optab>:X (match_dup 1) (match_dup 3)))
754 (set (match_dup 0) (<or_optab>:X (match_dup 0) (match_dup 4)))]
755 {
756 unsigned HOST_WIDE_INT bits = UINTVAL (operands[2]);
757 unsigned HOST_WIDE_INT topbit = HOST_WIDE_INT_1U << floor_log2 (bits);
758
759 operands[3] = GEN_INT (bits &~ topbit);
760 operands[4] = GEN_INT (topbit);
761 }
762 [(set_attr "type" "bitmanip")])
763
764 ;; Same to use blcri + andi and blcri + bclri
765 (define_insn_and_split "*andi<mode>_extrabit"
766 [(set (match_operand:X 0 "register_operand" "=r")
767 (and:X (match_operand:X 1 "register_operand" "r")
768 (match_operand:X 2 "not_uimm_extra_bit_or_nottwobits" "i")))]
769 "TARGET_ZBS"
770 "#"
771 "&& reload_completed"
772 [(set (match_dup 0) (and:X (match_dup 1) (match_dup 3)))
773 (set (match_dup 0) (and:X (match_dup 0) (match_dup 4)))]
774 {
775 unsigned HOST_WIDE_INT bits = UINTVAL (operands[2]);
776 unsigned HOST_WIDE_INT topbit = HOST_WIDE_INT_1U << floor_log2 (~bits);
777
778 operands[3] = GEN_INT (bits | topbit);
779 operands[4] = GEN_INT (~topbit);
780 }
781 [(set_attr "type" "bitmanip")])
782
783 ;; IF_THEN_ELSE: test for 2 bits of opposite polarity
784 (define_insn_and_split "*branch<X:mode>_mask_twobits_equals_singlebit"
785 [(set (pc)
786 (if_then_else
787 (match_operator 1 "equality_operator"
788 [(and:X (match_operand:X 2 "register_operand" "r")
789 (match_operand:X 3 "const_twobits_not_arith_operand" "i"))
790 (match_operand:X 4 "single_bit_mask_operand" "i")])
791 (label_ref (match_operand 0 "" ""))
792 (pc)))
793 (clobber (match_scratch:X 5 "=&r"))
794 (clobber (match_scratch:X 6 "=&r"))]
795 "TARGET_ZBS && TARGET_ZBB"
796 "#"
797 "&& reload_completed"
798 [(set (match_dup 5) (zero_extract:X (match_dup 2)
799 (const_int 1)
800 (match_dup 8)))
801 (set (match_dup 6) (zero_extract:X (match_dup 2)
802 (const_int 1)
803 (match_dup 9)))
804 (set (match_dup 6) (and:X (not:X (match_dup 6)) (match_dup 5)))
805 (set (pc) (if_then_else (match_op_dup 1 [(match_dup 6) (const_int 0)])
806 (label_ref (match_dup 0))
807 (pc)))]
808 {
809 unsigned HOST_WIDE_INT twobits_mask = UINTVAL (operands[3]);
810 unsigned HOST_WIDE_INT singlebit_mask = UINTVAL (operands[4]);
811
812 /* We should never see an unsatisfiable condition. */
813 gcc_assert (twobits_mask & singlebit_mask);
814
815 int setbit = ctz_hwi (singlebit_mask);
816 int clearbit = ctz_hwi (twobits_mask & ~singlebit_mask);
817
818 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == NE ? EQ : NE,
819 <X:MODE>mode, operands[6], GEN_INT(0));
820
821 operands[8] = GEN_INT (setbit);
822 operands[9] = GEN_INT (clearbit);
823 }
824 [(set_attr "type" "bitmanip")])
825
826 ;; IF_THEN_ELSE: test for (a & (1 << BIT_NO))
827 (define_insn_and_split "*branch<X:mode>_bext"
828 [(set (pc)
829 (if_then_else
830 (match_operator 1 "equality_operator"
831 [(zero_extract:X (match_operand:X 2 "register_operand" "r")
832 (const_int 1)
833 (zero_extend:X
834 (match_operand:QI 3 "register_operand" "r")))
835 (const_int 0)])
836 (label_ref (match_operand 0 "" ""))
837 (pc)))
838 (clobber (match_scratch:X 4 "=&r"))]
839 "TARGET_ZBS"
840 "#"
841 "&& reload_completed"
842 [(set (match_dup 4) (zero_extract:X (match_dup 2)
843 (const_int 1)
844 (zero_extend:X (match_dup 3))))
845 (set (pc) (if_then_else (match_op_dup 1 [(match_dup 4) (const_int 0)])
846 (label_ref (match_dup 0))
847 (pc)))]
848 ""
849 [(set_attr "type" "bitmanip")])
850
851 ;; ZBKC or ZBC extension
852 (define_insn "riscv_clmul_<mode>"
853 [(set (match_operand:X 0 "register_operand" "=r")
854 (unspec:X [(match_operand:X 1 "register_operand" "r")
855 (match_operand:X 2 "register_operand" "r")]
856 UNSPEC_CLMUL))]
857 "TARGET_ZBKC || TARGET_ZBC"
858 "clmul\t%0,%1,%2"
859 [(set_attr "type" "clmul")])
860
861 (define_insn "riscv_clmulh_<mode>"
862 [(set (match_operand:X 0 "register_operand" "=r")
863 (unspec:X [(match_operand:X 1 "register_operand" "r")
864 (match_operand:X 2 "register_operand" "r")]
865 UNSPEC_CLMULH))]
866 "TARGET_ZBKC || TARGET_ZBC"
867 "clmulh\t%0,%1,%2"
868 [(set_attr "type" "clmul")])
869
870 ;; ZBC extension
871 (define_insn "riscv_clmulr_<mode>"
872 [(set (match_operand:X 0 "register_operand" "=r")
873 (unspec:X [(match_operand:X 1 "register_operand" "r")
874 (match_operand:X 2 "register_operand" "r")]
875 UNSPEC_CLMULR))]
876 "TARGET_ZBC"
877 "clmulr\t%0,%1,%2"
878 [(set_attr "type" "clmul")])