1 ;; Machine description for RISC-V Bit Manipulation operations.
2 ;; Copyright (C) 2021-2022 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 (define_insn "*shNadduw"
43 [(set (match_operand:DI 0 "register_operand" "=r")
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")])
55 ;; During combine, we may encounter an attempt to combine
56 ;; slli rtmp, rs, #imm
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
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)
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;
82 /* If the bias + scale don't add up to operand[2], reject. */
83 if ((scale + bias) != UINTVAL (operands[2]))
86 /* If the shift-amount is out-of-range for sh[123]add.uw, reject. */
87 if ((scale < 1) || (scale > 3))
90 /* If there's no bias, the '*shNadduw' pattern should have matched. */
94 operands[6] = GEN_INT (bias);
95 operands[7] = GEN_INT (scale);
96 operands[8] = GEN_INT (0xffffffffULL << scale);
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"
106 [(set_attr "type" "bitmanip")
107 (set_attr "mode" "DI")])
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"
117 [(set_attr "type" "bitmanip")
118 (set_attr "mode" "DI")])
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")))]
128 [(set_attr "type" "bitmanip")
129 (set_attr "mode" "<X:MODE>")])
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"))))]
137 [(set_attr "type" "bitmanip")
138 (set_attr "mode" "<X:MODE>")])
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")))]
144 "<bitmanip_insn>%~\t%0,%1"
145 [(set_attr "type" "bitmanip")
146 (set_attr "mode" "SI")])
148 (define_insn "*<bitmanip_optab>disi2"
149 [(set (match_operand:DI 0 "register_operand" "=r")
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")])
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")])
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")))]
172 [(set_attr "type" "bitmanip,load")
173 (set_attr "mode" "<GPR:MODE>")])
175 (define_insn "*extend<SHORT:mode><SUPERQI:mode>2_zbb"
176 [(set (match_operand:SUPERQI 0 "register_operand" "=r,r")
178 (match_operand:SHORT 1 "nonimmediate_operand" " r,m")))]
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>")])
186 (define_insn "*zero_extendhi<GPR:mode>2_zbb"
187 [(set (match_operand:GPR 0 "register_operand" "=r,r")
189 (match_operand:HI 1 "nonimmediate_operand" " r,m")))]
194 [(set_attr "type" "bitmanip,load")
195 (set_attr "mode" "HI")])
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")))]
203 [(set_attr "type" "bitmanip")])
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"
211 [(set_attr "type" "bitmanip")])
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"
219 [(set_attr "type" "bitmanip")])
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")))]
227 [(set_attr "type" "bitmanip")])
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"
235 [(set_attr "type" "bitmanip")])
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"
243 [(set_attr "type" "bitmanip")])
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")))]
250 [(set_attr "type" "bitmanip")])
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
256 (define_expand "bswaphi2"
257 [(set (match_operand:HI 0 "register_operand" "=r")
258 (bswap:HI (match_operand:HI 1 "register_operand" "r")))]
261 rtx tmp = gen_reg_rtx (word_mode);
262 rtx newop1 = gen_lowpart (word_mode, operands[1]);
264 emit_insn (gen_bswapdi2 (tmp, newop1));
266 emit_insn (gen_bswapsi2 (tmp, newop1));
267 rtx tmp1 = gen_reg_rtx (word_mode);
269 emit_insn (gen_lshrdi3 (tmp1, tmp, GEN_INT (64 - 16)));
271 emit_insn (gen_lshrsi3 (tmp1, tmp, GEN_INT (32 - 16)));
272 emit_move_insn (operands[0], gen_lowpart (HImode, tmp1));
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")))]
281 "<bitmanip_insn>\t%0,%1,%2"
282 [(set_attr "type" "bitmanip")])
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")))]
293 [(set_attr "type" "bitmanip")])
295 (define_insn "*bset<mode>_mask"
296 [(set (match_operand:X 0 "register_operand" "=r")
297 (ior:X (ashift:X (const_int 1)
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")))]
304 [(set_attr "type" "bitmanip")])
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")))]
312 [(set_attr "type" "bitmanip")])
314 (define_insn "*bset<mode>_1_mask"
315 [(set (match_operand:X 0 "register_operand" "=r")
316 (ashift:X (const_int 1)
318 (and:X (match_operand:X 1 "register_operand" "r")
319 (match_operand 2 "<X:shiftm1>" "<X:shiftm1p>")) 0)))]
322 [(set_attr "type" "bitmanip")])
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")))]
330 [(set_attr "type" "bitmanip")])
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")))]
339 [(set_attr "type" "bitmanip")])
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")))]
347 [(set_attr "type" "bitmanip")])
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")))]
356 [(set_attr "type" "bitmanip")])
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")))]
364 [(set_attr "type" "bitmanip")])
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")
371 (match_operand:QI 2 "register_operand" "r"))))]
374 [(set_attr "type" "bitmanip")])
376 (define_insn "*bexti"
377 [(set (match_operand:X 0 "register_operand" "=r")
378 (zero_extract:X (match_operand:X 1 "register_operand" "r")
380 (match_operand 2 "immediate_operand" "n")))]
381 "TARGET_ZBS && UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)"
383 [(set_attr "type" "bitmanip")])