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(define_code_iterator bitmanip_bitwise [and ior])
21
22(define_code_iterator bitmanip_minmax [smin umin smax umax])
23
24(define_code_iterator clz_ctz_pcnt [clz ctz popcount])
25
26(define_code_attr bitmanip_optab [(smin "smin")
27				  (smax "smax")
28				  (umin "umin")
29				  (umax "umax")
30				  (clz "clz")
31				  (ctz "ctz")
32				  (popcount "popcount")])
33
34
35(define_code_attr bitmanip_insn [(smin "min")
36				 (smax "max")
37				 (umin "minu")
38				 (umax "maxu")
39				 (clz "clz")
40				 (ctz "ctz")
41				 (popcount "cpop")])
42
43(define_mode_attr shiftm1 [(SI "const31_operand") (DI "const63_operand")])
44
45;; ZBA extension.
46
47(define_insn "*zero_extendsidi2_bitmanip"
48  [(set (match_operand:DI 0 "register_operand" "=r,r")
49	(zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))]
50  "TARGET_64BIT && TARGET_ZBA"
51  "@
52   zext.w\t%0,%1
53   lwu\t%0,%1"
54  [(set_attr "type" "bitmanip,load")
55   (set_attr "mode" "DI")])
56
57(define_insn "*shNadd"
58  [(set (match_operand:X 0 "register_operand" "=r")
59	(plus:X (ashift:X (match_operand:X 1 "register_operand" "r")
60			  (match_operand:QI 2 "immediate_operand" "I"))
61		(match_operand:X 3 "register_operand" "r")))]
62  "TARGET_ZBA
63   && (INTVAL (operands[2]) >= 1) && (INTVAL (operands[2]) <= 3)"
64  "sh%2add\t%0,%1,%3"
65  [(set_attr "type" "bitmanip")
66   (set_attr "mode" "<X:MODE>")])
67
68(define_insn "*shNadduw"
69  [(set (match_operand:DI 0 "register_operand" "=r")
70	(plus:DI
71	  (and:DI (ashift:DI (match_operand:DI 1 "register_operand" "r")
72			     (match_operand:QI 2 "immediate_operand" "I"))
73		 (match_operand 3 "immediate_operand" ""))
74	  (match_operand:DI 4 "register_operand" "r")))]
75  "TARGET_64BIT && TARGET_ZBA
76   && (INTVAL (operands[2]) >= 1) && (INTVAL (operands[2]) <= 3)
77   && (INTVAL (operands[3]) >> INTVAL (operands[2])) == 0xffffffff"
78  "sh%2add.uw\t%0,%1,%4"
79  [(set_attr "type" "bitmanip")
80   (set_attr "mode" "DI")])
81
82(define_insn "*add.uw"
83  [(set (match_operand:DI 0 "register_operand" "=r")
84	(plus:DI (zero_extend:DI
85		   (match_operand:SI 1 "register_operand" "r"))
86		 (match_operand:DI 2 "register_operand" "r")))]
87  "TARGET_64BIT && TARGET_ZBA"
88  "add.uw\t%0,%1,%2"
89  [(set_attr "type" "bitmanip")
90   (set_attr "mode" "DI")])
91
92(define_insn "*slliuw"
93  [(set (match_operand:DI 0 "register_operand" "=r")
94	(and:DI (ashift:DI (match_operand:DI 1 "register_operand" "r")
95			   (match_operand:QI 2 "immediate_operand" "I"))
96		(match_operand 3 "immediate_operand" "")))]
97  "TARGET_64BIT && TARGET_ZBA
98   && (INTVAL (operands[3]) >> INTVAL (operands[2])) == 0xffffffff"
99  "slli.uw\t%0,%1,%2"
100  [(set_attr "type" "bitmanip")
101   (set_attr "mode" "DI")])
102
103;; ZBB extension.
104
105(define_insn "*<optab>_not<mode>"
106  [(set (match_operand:X 0 "register_operand" "=r")
107        (bitmanip_bitwise:X (not:X (match_operand:X 1 "register_operand" "r"))
108                            (match_operand:X 2 "register_operand" "r")))]
109  "TARGET_ZBB"
110  "<insn>n\t%0,%2,%1"
111  [(set_attr "type" "bitmanip")
112   (set_attr "mode" "<X:MODE>")])
113
114(define_insn "*xor_not<mode>"
115  [(set (match_operand:X 0 "register_operand" "=r")
116        (not:X (xor:X (match_operand:X 1 "register_operand" "r")
117                      (match_operand:X 2 "register_operand" "r"))))]
118  "TARGET_ZBB"
119  "xnor\t%0,%1,%2"
120  [(set_attr "type" "bitmanip")
121   (set_attr "mode" "<X:MODE>")])
122
123(define_insn "<bitmanip_optab>si2"
124  [(set (match_operand:SI 0 "register_operand" "=r")
125        (clz_ctz_pcnt:SI (match_operand:SI 1 "register_operand" "r")))]
126  "TARGET_ZBB"
127  { return TARGET_64BIT ? "<bitmanip_insn>w\t%0,%1" : "<bitmanip_insn>\t%0,%1"; }
128  [(set_attr "type" "bitmanip")
129   (set_attr "mode" "SI")])
130
131(define_insn "*<bitmanip_optab>disi2"
132  [(set (match_operand:DI 0 "register_operand" "=r")
133        (sign_extend:DI
134          (clz_ctz_pcnt:SI (match_operand:SI 1 "register_operand" "r"))))]
135  "TARGET_64BIT && TARGET_ZBB"
136  "<bitmanip_insn>w\t%0,%1"
137  [(set_attr "type" "bitmanip")
138   (set_attr "mode" "SI")])
139
140(define_insn "<bitmanip_optab>di2"
141  [(set (match_operand:DI 0 "register_operand" "=r")
142        (clz_ctz_pcnt:DI (match_operand:DI 1 "register_operand" "r")))]
143  "TARGET_64BIT && TARGET_ZBB"
144  "<bitmanip_insn>\t%0,%1"
145  [(set_attr "type" "bitmanip")
146   (set_attr "mode" "DI")])
147
148(define_insn "*zero_extendhi<GPR:mode>2_bitmanip"
149  [(set (match_operand:GPR 0 "register_operand" "=r,r")
150        (zero_extend:GPR (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
151  "TARGET_ZBB"
152  "@
153   zext.h\t%0,%1
154   lhu\t%0,%1"
155  [(set_attr "type" "bitmanip,load")
156   (set_attr "mode" "<GPR:MODE>")])
157
158(define_insn "*extend<SHORT:mode><SUPERQI:mode>2_zbb"
159  [(set (match_operand:SUPERQI   0 "register_operand"     "=r,r")
160	(sign_extend:SUPERQI
161	    (match_operand:SHORT 1 "nonimmediate_operand" " r,m")))]
162  "TARGET_ZBB"
163  "@
164   sext.<SHORT:size>\t%0,%1
165   l<SHORT:size>\t%0,%1"
166  [(set_attr "type" "bitmanip,load")
167   (set_attr "mode" "<SUPERQI:MODE>")])
168
169(define_insn "*zero_extendhi<GPR:mode>2_zbb"
170  [(set (match_operand:GPR    0 "register_operand"     "=r,r")
171	(zero_extend:GPR
172	    (match_operand:HI 1 "nonimmediate_operand" " r,m")))]
173  "TARGET_ZBB"
174  "@
175   zext.h\t%0,%1
176   lhu\t%0,%1"
177  [(set_attr "type" "bitmanip,load")
178   (set_attr "mode" "HI")])
179
180(define_insn "rotrsi3"
181  [(set (match_operand:SI 0 "register_operand" "=r")
182	(rotatert:SI (match_operand:SI 1 "register_operand" "r")
183		     (match_operand:QI 2 "arith_operand" "rI")))]
184  "TARGET_ZBB"
185  { return TARGET_64BIT ? "ror%i2w\t%0,%1,%2" : "ror%i2\t%0,%1,%2"; }
186  [(set_attr "type" "bitmanip")])
187
188(define_insn "rotrdi3"
189  [(set (match_operand:DI 0 "register_operand" "=r")
190	(rotatert:DI (match_operand:DI 1 "register_operand" "r")
191		     (match_operand:QI 2 "arith_operand" "rI")))]
192  "TARGET_64BIT && TARGET_ZBB"
193  "ror%i2\t%0,%1,%2"
194  [(set_attr "type" "bitmanip")])
195
196(define_insn "rotrsi3_sext"
197  [(set (match_operand:DI 0 "register_operand" "=r")
198	(sign_extend:DI (rotatert:SI (match_operand:SI 1 "register_operand" "r")
199				     (match_operand:QI 2 "register_operand" "r"))))]
200  "TARGET_64BIT && TARGET_ZBB"
201  "rorw\t%0,%1,%2"
202  [(set_attr "type" "bitmanip")])
203
204(define_insn "rotlsi3"
205  [(set (match_operand:SI 0 "register_operand" "=r")
206	(rotate:SI (match_operand:SI 1 "register_operand" "r")
207		   (match_operand:QI 2 "register_operand" "r")))]
208  "TARGET_ZBB"
209  { return TARGET_64BIT ? "rolw\t%0,%1,%2" : "rol\t%0,%1,%2"; }
210  [(set_attr "type" "bitmanip")])
211
212(define_insn "rotldi3"
213  [(set (match_operand:DI 0 "register_operand" "=r")
214	(rotate:DI (match_operand:DI 1 "register_operand" "r")
215		   (match_operand:QI 2 "register_operand" "r")))]
216  "TARGET_64BIT && TARGET_ZBB"
217  "rol\t%0,%1,%2"
218  [(set_attr "type" "bitmanip")])
219
220(define_insn "rotlsi3_sext"
221  [(set (match_operand:DI 0 "register_operand" "=r")
222	(sign_extend:DI (rotate:SI (match_operand:SI 1 "register_operand" "r")
223				   (match_operand:QI 2 "register_operand" "r"))))]
224  "TARGET_64BIT && TARGET_ZBB"
225  "rolw\t%0,%1,%2"
226  [(set_attr "type" "bitmanip")])
227
228(define_insn "bswap<mode>2"
229  [(set (match_operand:X 0 "register_operand" "=r")
230        (bswap:X (match_operand:X 1 "register_operand" "r")))]
231  "TARGET_64BIT && TARGET_ZBB"
232  "rev8\t%0,%1"
233  [(set_attr "type" "bitmanip")])
234
235(define_insn "<bitmanip_optab><mode>3"
236  [(set (match_operand:X 0 "register_operand" "=r")
237        (bitmanip_minmax:X (match_operand:X 1 "register_operand" "r")
238			   (match_operand:X 2 "register_operand" "r")))]
239  "TARGET_ZBB"
240  "<bitmanip_insn>\t%0,%1,%2"
241  [(set_attr "type" "bitmanip")])
242
243;; ZBS extension.
244
245(define_insn "*bset<mode>"
246  [(set (match_operand:X 0 "register_operand" "=r")
247	(ior:X (ashift:X (const_int 1)
248			 (match_operand:QI 2 "register_operand" "r"))
249	       (match_operand:X 1 "register_operand" "r")))]
250  "TARGET_ZBS"
251  "bset\t%0,%1,%2"
252  [(set_attr "type" "bitmanip")])
253
254(define_insn "*bset<mode>_mask"
255  [(set (match_operand:X 0 "register_operand" "=r")
256	(ior:X (ashift:X (const_int 1)
257			 (subreg:QI
258			  (and:X (match_operand:X 2 "register_operand" "r")
259				 (match_operand 3 "<X:shiftm1>" "i")) 0))
260	       (match_operand:X 1 "register_operand" "r")))]
261  "TARGET_ZBS"
262  "bset\t%0,%1,%2"
263  [(set_attr "type" "bitmanip")])
264
265(define_insn "*bset<mode>_1"
266  [(set (match_operand:X 0 "register_operand" "=r")
267	(ashift:X (const_int 1)
268		  (match_operand:QI 1 "register_operand" "r")))]
269  "TARGET_ZBS"
270  "bset\t%0,x0,%1"
271  [(set_attr "type" "bitmanip")])
272
273(define_insn "*bset<mode>_1_mask"
274  [(set (match_operand:X 0 "register_operand" "=r")
275	(ashift:X (const_int 1)
276		  (subreg:QI
277		   (and:X (match_operand:X 1 "register_operand" "r")
278			  (match_operand 2 "<X:shiftm1>" "i")) 0)))]
279  "TARGET_ZBS"
280  "bset\t%0,x0,%1"
281  [(set_attr "type" "bitmanip")])
282
283(define_insn "*bseti<mode>"
284  [(set (match_operand:X 0 "register_operand" "=r")
285	(ior:X (match_operand:X 1 "register_operand" "r")
286	       (match_operand 2 "single_bit_mask_operand" "i")))]
287  "TARGET_ZBS"
288  "bseti\t%0,%1,%S2"
289  [(set_attr "type" "bitmanip")])
290
291(define_insn "*bclr<mode>"
292  [(set (match_operand:X 0 "register_operand" "=r")
293	(and:X (rotate:X (const_int -2)
294			 (match_operand:QI 2 "register_operand" "r"))
295	       (match_operand:X 1 "register_operand" "r")))]
296  "TARGET_ZBS"
297  "bclr\t%0,%1,%2"
298  [(set_attr "type" "bitmanip")])
299
300(define_insn "*bclri<mode>"
301  [(set (match_operand:X 0 "register_operand" "=r")
302	(and:X (match_operand:X 1 "register_operand" "r")
303	       (match_operand 2 "not_single_bit_mask_operand" "i")))]
304  "TARGET_ZBS"
305  "bclri\t%0,%1,%T2"
306  [(set_attr "type" "bitmanip")])
307
308(define_insn "*binv<mode>"
309  [(set (match_operand:X 0 "register_operand" "=r")
310	(xor:X (ashift:X (const_int 1)
311			 (match_operand:QI 2 "register_operand" "r"))
312	       (match_operand:X 1 "register_operand" "r")))]
313  "TARGET_ZBS"
314  "binv\t%0,%1,%2"
315  [(set_attr "type" "bitmanip")])
316
317(define_insn "*binvi<mode>"
318  [(set (match_operand:X 0 "register_operand" "=r")
319	(xor:X (match_operand:X 1 "register_operand" "r")
320	       (match_operand 2 "single_bit_mask_operand" "i")))]
321  "TARGET_ZBS"
322  "binvi\t%0,%1,%S2"
323  [(set_attr "type" "bitmanip")])
324
325(define_insn "*bext<mode>"
326  [(set (match_operand:X 0 "register_operand" "=r")
327	(zero_extract:X (match_operand:X 1 "register_operand" "r")
328			(const_int 1)
329			(zero_extend:X
330			 (match_operand:QI 2 "register_operand" "r"))))]
331  "TARGET_ZBS"
332  "bext\t%0,%1,%2"
333  [(set_attr "type" "bitmanip")])
334
335(define_insn "*bexti"
336  [(set (match_operand:X 0 "register_operand" "=r")
337	(zero_extract:X (match_operand:X 1 "register_operand" "r")
338			(const_int 1)
339			(match_operand 2 "immediate_operand" "i")))]
340  "TARGET_ZBS"
341  "bexti\t%0,%1,%2"
342  [(set_attr "type" "bitmanip")])
343