]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/riscv/bitmanip.md
[RISCV] Fix PR 106632 and PR 106588 a few constraints in bitmanip.md
[thirdparty/gcc.git] / gcc / config / riscv / bitmanip.md
1 ;; Machine description for RISC-V Bit Manipulation operations.
2 ;; Copyright (C) 2021-2022 Free Software Foundation, Inc.
3
4 ;; This file is part of GCC.
5
6 ;; GCC is free software; you can redistribute it and/or modify
7 ;; it under the terms of the GNU General Public License as published by
8 ;; the Free Software Foundation; either version 3, or (at your option)
9 ;; any later version.
10
11 ;; GCC is distributed in the hope that it will be useful,
12 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 ;; GNU General Public License for more details.
15
16 ;; You should have received a copy of the GNU General Public License
17 ;; along with GCC; see the file COPYING3. If not see
18 ;; <http://www.gnu.org/licenses/>.
19
20 ;; ZBA extension.
21
22 (define_insn "*zero_extendsidi2_bitmanip"
23 [(set (match_operand:DI 0 "register_operand" "=r,r")
24 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
25 "TARGET_64BIT && TARGET_ZBA"
26 "@
27 zext.w\t%0,%1
28 lwu\t%0,%1"
29 [(set_attr "type" "bitmanip,load")
30 (set_attr "mode" "DI")])
31
32 (define_insn "*shNadd"
33 [(set (match_operand:X 0 "register_operand" "=r")
34 (plus:X (ashift:X (match_operand:X 1 "register_operand" "r")
35 (match_operand:QI 2 "imm123_operand" "Ds3"))
36 (match_operand:X 3 "register_operand" "r")))]
37 "TARGET_ZBA"
38 "sh%2add\t%0,%1,%3"
39 [(set_attr "type" "bitmanip")
40 (set_attr "mode" "<X:MODE>")])
41
42 (define_insn "*shNadduw"
43 [(set (match_operand:DI 0 "register_operand" "=r")
44 (plus:DI
45 (and:DI (ashift:DI (match_operand:DI 1 "register_operand" "r")
46 (match_operand:QI 2 "imm123_operand" "Ds3"))
47 (match_operand 3 "immediate_operand" "n"))
48 (match_operand:DI 4 "register_operand" "r")))]
49 "TARGET_64BIT && TARGET_ZBA
50 && (INTVAL (operands[3]) >> INTVAL (operands[2])) == 0xffffffff"
51 "sh%2add.uw\t%0,%1,%4"
52 [(set_attr "type" "bitmanip")
53 (set_attr "mode" "DI")])
54
55 ;; During combine, we may encounter an attempt to combine
56 ;; slli rtmp, rs, #imm
57 ;; zext.w rtmp, rtmp
58 ;; sh[123]add rd, rtmp, rs2
59 ;; which will lead to the immediate not satisfying the above constraints.
60 ;; By splitting the compound expression, we can simplify to a slli and a
61 ;; sh[123]add.uw.
62 (define_split
63 [(set (match_operand:DI 0 "register_operand")
64 (plus:DI (and:DI (ashift:DI (match_operand:DI 1 "register_operand")
65 (match_operand:QI 2 "immediate_operand"))
66 (match_operand:DI 3 "consecutive_bits_operand"))
67 (match_operand:DI 4 "register_operand")))
68 (clobber (match_operand:DI 5 "register_operand"))]
69 "TARGET_64BIT && TARGET_ZBA"
70 [(set (match_dup 5) (ashift:DI (match_dup 1) (match_dup 6)))
71 (set (match_dup 0) (plus:DI (and:DI (ashift:DI (match_dup 5)
72 (match_dup 7))
73 (match_dup 8))
74 (match_dup 4)))]
75 {
76 unsigned HOST_WIDE_INT mask = UINTVAL (operands[3]);
77 /* scale: shift within the sh[123]add.uw */
78 unsigned HOST_WIDE_INT scale = 32 - clz_hwi (mask);
79 /* bias: pre-scale amount (i.e. the prior shift amount) */
80 int bias = ctz_hwi (mask) - scale;
81
82 /* If the bias + scale don't add up to operand[2], reject. */
83 if ((scale + bias) != UINTVAL (operands[2]))
84 FAIL;
85
86 /* If the shift-amount is out-of-range for sh[123]add.uw, reject. */
87 if ((scale < 1) || (scale > 3))
88 FAIL;
89
90 /* If there's no bias, the '*shNadduw' pattern should have matched. */
91 if (bias == 0)
92 FAIL;
93
94 operands[6] = GEN_INT (bias);
95 operands[7] = GEN_INT (scale);
96 operands[8] = GEN_INT (0xffffffffULL << scale);
97 })
98
99 (define_insn "*add.uw"
100 [(set (match_operand:DI 0 "register_operand" "=r")
101 (plus:DI (zero_extend:DI
102 (match_operand:SI 1 "register_operand" "r"))
103 (match_operand:DI 2 "register_operand" "r")))]
104 "TARGET_64BIT && TARGET_ZBA"
105 "add.uw\t%0,%1,%2"
106 [(set_attr "type" "bitmanip")
107 (set_attr "mode" "DI")])
108
109 (define_insn "*slliuw"
110 [(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 "immediate_operand" "I"))
113 (match_operand 3 "immediate_operand" "n")))]
114 "TARGET_64BIT && TARGET_ZBA
115 && (INTVAL (operands[3]) >> INTVAL (operands[2])) == 0xffffffff"
116 "slli.uw\t%0,%1,%2"
117 [(set_attr "type" "bitmanip")
118 (set_attr "mode" "DI")])
119
120 ;; ZBB extension.
121
122 (define_insn "*<optab>_not<mode>"
123 [(set (match_operand:X 0 "register_operand" "=r")
124 (bitmanip_bitwise:X (not:X (match_operand:X 1 "register_operand" "r"))
125 (match_operand:X 2 "register_operand" "r")))]
126 "TARGET_ZBB"
127 "<insn>n\t%0,%2,%1"
128 [(set_attr "type" "bitmanip")
129 (set_attr "mode" "<X:MODE>")])
130
131 (define_insn "*xor_not<mode>"
132 [(set (match_operand:X 0 "register_operand" "=r")
133 (not:X (xor:X (match_operand:X 1 "register_operand" "r")
134 (match_operand:X 2 "register_operand" "r"))))]
135 "TARGET_ZBB"
136 "xnor\t%0,%1,%2"
137 [(set_attr "type" "bitmanip")
138 (set_attr "mode" "<X:MODE>")])
139
140 (define_insn "<bitmanip_optab>si2"
141 [(set (match_operand:SI 0 "register_operand" "=r")
142 (clz_ctz_pcnt:SI (match_operand:SI 1 "register_operand" "r")))]
143 "TARGET_ZBB"
144 "<bitmanip_insn>%~\t%0,%1"
145 [(set_attr "type" "bitmanip")
146 (set_attr "mode" "SI")])
147
148 (define_insn "*<bitmanip_optab>disi2"
149 [(set (match_operand:DI 0 "register_operand" "=r")
150 (sign_extend:DI
151 (clz_ctz_pcnt:SI (match_operand:SI 1 "register_operand" "r"))))]
152 "TARGET_64BIT && TARGET_ZBB"
153 "<bitmanip_insn>w\t%0,%1"
154 [(set_attr "type" "bitmanip")
155 (set_attr "mode" "SI")])
156
157 (define_insn "<bitmanip_optab>di2"
158 [(set (match_operand:DI 0 "register_operand" "=r")
159 (clz_ctz_pcnt:DI (match_operand:DI 1 "register_operand" "r")))]
160 "TARGET_64BIT && TARGET_ZBB"
161 "<bitmanip_insn>\t%0,%1"
162 [(set_attr "type" "bitmanip")
163 (set_attr "mode" "DI")])
164
165 (define_insn "*zero_extendhi<GPR:mode>2_bitmanip"
166 [(set (match_operand:GPR 0 "register_operand" "=r,r")
167 (zero_extend:GPR (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
168 "TARGET_ZBB"
169 "@
170 zext.h\t%0,%1
171 lhu\t%0,%1"
172 [(set_attr "type" "bitmanip,load")
173 (set_attr "mode" "<GPR:MODE>")])
174
175 (define_insn "*extend<SHORT:mode><SUPERQI:mode>2_zbb"
176 [(set (match_operand:SUPERQI 0 "register_operand" "=r,r")
177 (sign_extend:SUPERQI
178 (match_operand:SHORT 1 "nonimmediate_operand" " r,m")))]
179 "TARGET_ZBB"
180 "@
181 sext.<SHORT:size>\t%0,%1
182 l<SHORT:size>\t%0,%1"
183 [(set_attr "type" "bitmanip,load")
184 (set_attr "mode" "<SUPERQI:MODE>")])
185
186 (define_insn "*zero_extendhi<GPR:mode>2_zbb"
187 [(set (match_operand:GPR 0 "register_operand" "=r,r")
188 (zero_extend:GPR
189 (match_operand:HI 1 "nonimmediate_operand" " r,m")))]
190 "TARGET_ZBB"
191 "@
192 zext.h\t%0,%1
193 lhu\t%0,%1"
194 [(set_attr "type" "bitmanip,load")
195 (set_attr "mode" "HI")])
196
197 (define_insn "rotrsi3"
198 [(set (match_operand:SI 0 "register_operand" "=r")
199 (rotatert:SI (match_operand:SI 1 "register_operand" "r")
200 (match_operand:QI 2 "arith_operand" "rI")))]
201 "TARGET_ZBB"
202 "ror%i2%~\t%0,%1,%2"
203 [(set_attr "type" "bitmanip")])
204
205 (define_insn "rotrdi3"
206 [(set (match_operand:DI 0 "register_operand" "=r")
207 (rotatert:DI (match_operand:DI 1 "register_operand" "r")
208 (match_operand:QI 2 "arith_operand" "rI")))]
209 "TARGET_64BIT && TARGET_ZBB"
210 "ror%i2\t%0,%1,%2"
211 [(set_attr "type" "bitmanip")])
212
213 (define_insn "rotrsi3_sext"
214 [(set (match_operand:DI 0 "register_operand" "=r")
215 (sign_extend:DI (rotatert:SI (match_operand:SI 1 "register_operand" "r")
216 (match_operand:QI 2 "register_operand" "r"))))]
217 "TARGET_64BIT && TARGET_ZBB"
218 "rorw\t%0,%1,%2"
219 [(set_attr "type" "bitmanip")])
220
221 (define_insn "rotlsi3"
222 [(set (match_operand:SI 0 "register_operand" "=r")
223 (rotate:SI (match_operand:SI 1 "register_operand" "r")
224 (match_operand:QI 2 "register_operand" "r")))]
225 "TARGET_ZBB"
226 "rol%~\t%0,%1,%2"
227 [(set_attr "type" "bitmanip")])
228
229 (define_insn "rotldi3"
230 [(set (match_operand:DI 0 "register_operand" "=r")
231 (rotate:DI (match_operand:DI 1 "register_operand" "r")
232 (match_operand:QI 2 "register_operand" "r")))]
233 "TARGET_64BIT && TARGET_ZBB"
234 "rol\t%0,%1,%2"
235 [(set_attr "type" "bitmanip")])
236
237 (define_insn "rotlsi3_sext"
238 [(set (match_operand:DI 0 "register_operand" "=r")
239 (sign_extend:DI (rotate:SI (match_operand:SI 1 "register_operand" "r")
240 (match_operand:QI 2 "register_operand" "r"))))]
241 "TARGET_64BIT && TARGET_ZBB"
242 "rolw\t%0,%1,%2"
243 [(set_attr "type" "bitmanip")])
244
245 (define_insn "bswap<mode>2"
246 [(set (match_operand:X 0 "register_operand" "=r")
247 (bswap:X (match_operand:X 1 "register_operand" "r")))]
248 "TARGET_ZBB"
249 "rev8\t%0,%1"
250 [(set_attr "type" "bitmanip")])
251
252 ;; HI bswap can be emulated using SI/DI bswap followed
253 ;; by a logical shift right
254 ;; SI bswap for TARGET_64BIT is already similarly in
255 ;; the common code.
256 (define_expand "bswaphi2"
257 [(set (match_operand:HI 0 "register_operand" "=r")
258 (bswap:HI (match_operand:HI 1 "register_operand" "r")))]
259 "TARGET_ZBB"
260 {
261 rtx tmp = gen_reg_rtx (word_mode);
262 rtx newop1 = gen_lowpart (word_mode, operands[1]);
263 if (TARGET_64BIT)
264 emit_insn (gen_bswapdi2 (tmp, newop1));
265 else
266 emit_insn (gen_bswapsi2 (tmp, newop1));
267 rtx tmp1 = gen_reg_rtx (word_mode);
268 if (TARGET_64BIT)
269 emit_insn (gen_lshrdi3 (tmp1, tmp, GEN_INT (64 - 16)));
270 else
271 emit_insn (gen_lshrsi3 (tmp1, tmp, GEN_INT (32 - 16)));
272 emit_move_insn (operands[0], gen_lowpart (HImode, tmp1));
273 DONE;
274 })
275
276 (define_insn "<bitmanip_optab><mode>3"
277 [(set (match_operand:X 0 "register_operand" "=r")
278 (bitmanip_minmax:X (match_operand:X 1 "register_operand" "r")
279 (match_operand:X 2 "register_operand" "r")))]
280 "TARGET_ZBB"
281 "<bitmanip_insn>\t%0,%1,%2"
282 [(set_attr "type" "bitmanip")])
283
284 ;; ZBS extension.
285
286 (define_insn "*bset<mode>"
287 [(set (match_operand:X 0 "register_operand" "=r")
288 (ior:X (ashift:X (const_int 1)
289 (match_operand:QI 2 "register_operand" "r"))
290 (match_operand:X 1 "register_operand" "r")))]
291 "TARGET_ZBS"
292 "bset\t%0,%1,%2"
293 [(set_attr "type" "bitmanip")])
294
295 (define_insn "*bset<mode>_mask"
296 [(set (match_operand:X 0 "register_operand" "=r")
297 (ior:X (ashift:X (const_int 1)
298 (subreg:QI
299 (and:X (match_operand:X 2 "register_operand" "r")
300 (match_operand 3 "<X:shiftm1>" "<X:shiftm1p>")) 0))
301 (match_operand:X 1 "register_operand" "r")))]
302 "TARGET_ZBS"
303 "bset\t%0,%1,%2"
304 [(set_attr "type" "bitmanip")])
305
306 (define_insn "*bset<mode>_1"
307 [(set (match_operand:X 0 "register_operand" "=r")
308 (ashift:X (const_int 1)
309 (match_operand:QI 1 "register_operand" "r")))]
310 "TARGET_ZBS"
311 "bset\t%0,x0,%1"
312 [(set_attr "type" "bitmanip")])
313
314 (define_insn "*bset<mode>_1_mask"
315 [(set (match_operand:X 0 "register_operand" "=r")
316 (ashift:X (const_int 1)
317 (subreg:QI
318 (and:X (match_operand:X 1 "register_operand" "r")
319 (match_operand 2 "<X:shiftm1>" "<X:shiftm1p>")) 0)))]
320 "TARGET_ZBS"
321 "bset\t%0,x0,%1"
322 [(set_attr "type" "bitmanip")])
323
324 (define_insn "*bseti<mode>"
325 [(set (match_operand:X 0 "register_operand" "=r")
326 (ior:X (match_operand:X 1 "register_operand" "r")
327 (match_operand:X 2 "single_bit_mask_operand" "DbS")))]
328 "TARGET_ZBS"
329 "bseti\t%0,%1,%S2"
330 [(set_attr "type" "bitmanip")])
331
332 (define_insn "*bclr<mode>"
333 [(set (match_operand:X 0 "register_operand" "=r")
334 (and:X (rotate:X (const_int -2)
335 (match_operand:QI 2 "register_operand" "r"))
336 (match_operand:X 1 "register_operand" "r")))]
337 "TARGET_ZBS"
338 "bclr\t%0,%1,%2"
339 [(set_attr "type" "bitmanip")])
340
341 (define_insn "*bclri<mode>"
342 [(set (match_operand:X 0 "register_operand" "=r")
343 (and:X (match_operand:X 1 "register_operand" "r")
344 (match_operand:X 2 "not_single_bit_mask_operand" "DnS")))]
345 "TARGET_ZBS"
346 "bclri\t%0,%1,%T2"
347 [(set_attr "type" "bitmanip")])
348
349 (define_insn "*binv<mode>"
350 [(set (match_operand:X 0 "register_operand" "=r")
351 (xor:X (ashift:X (const_int 1)
352 (match_operand:QI 2 "register_operand" "r"))
353 (match_operand:X 1 "register_operand" "r")))]
354 "TARGET_ZBS"
355 "binv\t%0,%1,%2"
356 [(set_attr "type" "bitmanip")])
357
358 (define_insn "*binvi<mode>"
359 [(set (match_operand:X 0 "register_operand" "=r")
360 (xor:X (match_operand:X 1 "register_operand" "r")
361 (match_operand:X 2 "single_bit_mask_operand" "DbS")))]
362 "TARGET_ZBS"
363 "binvi\t%0,%1,%S2"
364 [(set_attr "type" "bitmanip")])
365
366 (define_insn "*bext<mode>"
367 [(set (match_operand:X 0 "register_operand" "=r")
368 (zero_extract:X (match_operand:X 1 "register_operand" "r")
369 (const_int 1)
370 (zero_extend:X
371 (match_operand:QI 2 "register_operand" "r"))))]
372 "TARGET_ZBS"
373 "bext\t%0,%1,%2"
374 [(set_attr "type" "bitmanip")])
375
376 (define_insn "*bexti"
377 [(set (match_operand:X 0 "register_operand" "=r")
378 (zero_extract:X (match_operand:X 1 "register_operand" "r")
379 (const_int 1)
380 (match_operand 2 "immediate_operand" "n")))]
381 "TARGET_ZBS && UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
382 "bexti\t%0,%1,%2"
383 [(set_attr "type" "bitmanip")])