1 ;; Machine description for RISC-V Scalar Cryptography extensions.
2 ;; Copyright (C) 2023-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)
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 (define_c_enum "unspec" [
74 (define_insn "riscv_brev8_<mode>"
75 [(set (match_operand:GPR 0 "register_operand" "=r")
76 (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")]
80 [(set_attr "type" "crypto")])
82 (define_insn "riscv_zip"
83 [(set (match_operand:SI 0 "register_operand" "=r")
84 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
86 "TARGET_ZBKB && !TARGET_64BIT"
88 [(set_attr "type" "crypto")])
90 (define_insn "riscv_unzip"
91 [(set (match_operand:SI 0 "register_operand" "=r")
92 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
94 "TARGET_ZBKB && !TARGET_64BIT"
96 [(set_attr "type" "crypto")])
98 (define_insn "riscv_pack_<X:mode><HISI:mode>"
99 [(set (match_operand:X 0 "register_operand" "=r")
100 (unspec:X [(match_operand:HISI 1 "register_operand" "r")
101 (match_operand:HISI 2 "register_operand" "r")]
105 [(set_attr "type" "crypto")])
107 ;; This is slightly more complex than the other pack patterns
108 ;; that fully expose the RTL as it needs to self-adjust to
109 ;; rv32 and rv64. But it's not that hard.
110 (define_insn "riscv_xpack_<X:mode>_<HX:mode>_2"
111 [(set (match_operand:X 0 "register_operand" "=r")
112 (ior:X (ashift:X (match_operand:X 1 "register_operand" "r")
113 (match_operand 2 "immediate_operand" "n"))
115 (match_operand:HX 3 "register_operand" "r"))))]
116 "TARGET_ZBKB && INTVAL (operands[2]) == BITS_PER_WORD / 2"
118 [(set_attr "type" "crypto")])
120 (define_insn "riscv_packh_<mode>"
121 [(set (match_operand:X 0 "register_operand" "=r")
122 (unspec:X [(match_operand:QI 1 "register_operand" "r")
123 (match_operand:QI 2 "register_operand" "r")]
127 [(set_attr "type" "crypto")])
129 ;; So this is both a useful pattern unto itself and a bridge to the
130 ;; general packh pattern below.
131 (define_insn "*riscv_packh_<mode>_2"
132 [(set (match_operand:X 0 "register_operand" "=r")
133 (and:X (ashift:X (match_operand:X 1 "register_operand" "r")
138 [(set_attr "type" "crypto")])
140 ;; While the two operands of the IOR could be swapped, this appears
141 ;; to be the canonical form. The other form doesn't seem to trigger.
142 (define_insn "*riscv_packh_<mode>_3"
143 [(set (match_operand:X 0 "register_operand" "=r")
144 (ior:X (and:X (ashift:X (match_operand:X 1 "register_operand" "r")
147 (zero_extend:X (match_operand:QI 2 "register_operand" "r"))))]
150 [(set_attr "type" "crypto")])
152 (define_insn "riscv_packw"
153 [(set (match_operand:DI 0 "register_operand" "=r")
154 (unspec:DI [(match_operand:HI 1 "register_operand" "r")
155 (match_operand:HI 2 "register_operand" "r")]
157 "TARGET_ZBKB && TARGET_64BIT"
159 [(set_attr "type" "crypto")])
161 ;; Implemented as a splitter for initial recognition. It generates
162 ;; new RTL with the extension moved to the outer position. This
163 ;; allows later code to eliminate subsequent explicit sign extensions.
165 [(set (match_operand:DI 0 "register_operand")
167 (sign_extend:DI (match_operand:HI 1 "register_operand"))
169 (zero_extend:DI (match_operand:HI 2 "register_operand"))))]
170 "TARGET_ZBKB && TARGET_64BIT"
172 (sign_extend:DI (ior:SI (ashift:SI (match_dup 1) (const_int 16))
173 (zero_extend:SI (match_dup 2)))))]
174 "operands[1] = gen_lowpart (SImode, operands[1]);")
176 ;; And this patches the result of the splitter above.
177 (define_insn "*riscv_packw_2"
178 [(set (match_operand:DI 0 "register_operand" "=r")
181 (ashift:SI (match_operand:SI 1 "register_operand" "r")
183 (zero_extend:SI (match_operand:HI 2 "register_operand" "r")))))]
184 "TARGET_ZBKB && TARGET_64BIT"
186 [(set_attr "type" "crypto")])
190 (define_insn "riscv_xperm4_<mode>"
191 [(set (match_operand:X 0 "register_operand" "=r")
192 (unspec:X [(match_operand:X 1 "register_operand" "r")
193 (match_operand:X 2 "register_operand" "r")]
197 [(set_attr "type" "crypto")])
199 (define_insn "riscv_xperm8_<mode>"
200 [(set (match_operand:X 0 "register_operand" "=r")
201 (unspec:X [(match_operand:X 1 "register_operand" "r")
202 (match_operand:X 2 "register_operand" "r")]
206 [(set_attr "type" "crypto")])
210 (define_insn "riscv_aes32dsi"
211 [(set (match_operand:SI 0 "register_operand" "=r")
212 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
213 (match_operand:SI 2 "register_operand" "r")
214 (match_operand:SI 3 "const_0_3_operand" "")]
216 "TARGET_ZKND && !TARGET_64BIT"
217 "aes32dsi\t%0,%1,%2,%3"
218 [(set_attr "type" "crypto")])
220 (define_insn "riscv_aes32dsmi"
221 [(set (match_operand:SI 0 "register_operand" "=r")
222 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
223 (match_operand:SI 2 "register_operand" "r")
224 (match_operand:SI 3 "const_0_3_operand" "")]
226 "TARGET_ZKND && !TARGET_64BIT"
227 "aes32dsmi\t%0,%1,%2,%3"
228 [(set_attr "type" "crypto")])
230 (define_insn "riscv_aes64ds"
231 [(set (match_operand:DI 0 "register_operand" "=r")
232 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
233 (match_operand:DI 2 "register_operand" "r")]
235 "TARGET_ZKND && TARGET_64BIT"
237 [(set_attr "type" "crypto")])
239 (define_insn "riscv_aes64dsm"
240 [(set (match_operand:DI 0 "register_operand" "=r")
241 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
242 (match_operand:DI 2 "register_operand" "r")]
244 "TARGET_ZKND && TARGET_64BIT"
246 [(set_attr "type" "crypto")])
248 (define_insn "riscv_aes64im"
249 [(set (match_operand:DI 0 "register_operand" "=r")
250 (unspec:DI [(match_operand:DI 1 "register_operand" "r")]
252 "TARGET_ZKND && TARGET_64BIT"
254 [(set_attr "type" "crypto")])
256 (define_insn "riscv_aes64ks1i"
257 [(set (match_operand:DI 0 "register_operand" "=r")
258 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
259 (match_operand:SI 2 "const_0_10_operand" "")]
261 "(TARGET_ZKND || TARGET_ZKNE) && TARGET_64BIT"
262 "aes64ks1i\t%0,%1,%2"
263 [(set_attr "type" "crypto")])
265 (define_insn "riscv_aes64ks2"
266 [(set (match_operand:DI 0 "register_operand" "=r")
267 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
268 (match_operand:DI 2 "register_operand" "r")]
270 "(TARGET_ZKND || TARGET_ZKNE) && TARGET_64BIT"
272 [(set_attr "type" "crypto")])
276 (define_insn "riscv_aes32esi"
277 [(set (match_operand:SI 0 "register_operand" "=r")
278 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
279 (match_operand:SI 2 "register_operand" "r")
280 (match_operand:SI 3 "const_0_3_operand" "")]
282 "TARGET_ZKNE && !TARGET_64BIT"
283 "aes32esi\t%0,%1,%2,%3"
284 [(set_attr "type" "crypto")])
286 (define_insn "riscv_aes32esmi"
287 [(set (match_operand:SI 0 "register_operand" "=r")
288 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
289 (match_operand:SI 2 "register_operand" "r")
290 (match_operand:SI 3 "const_0_3_operand" "")]
292 "TARGET_ZKNE && !TARGET_64BIT"
293 "aes32esmi\t%0,%1,%2,%3"
294 [(set_attr "type" "crypto")])
296 (define_insn "riscv_aes64es"
297 [(set (match_operand:DI 0 "register_operand" "=r")
298 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
299 (match_operand:DI 2 "register_operand" "r")]
301 "TARGET_ZKNE && TARGET_64BIT"
303 [(set_attr "type" "crypto")])
305 (define_insn "riscv_aes64esm"
306 [(set (match_operand:DI 0 "register_operand" "=r")
307 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
308 (match_operand:DI 2 "register_operand" "r")]
310 "TARGET_ZKNE && TARGET_64BIT"
312 [(set_attr "type" "crypto")])
316 (define_int_iterator SHA256_OP [
317 UNSPEC_SHA_256_SIG0 UNSPEC_SHA_256_SIG1
318 UNSPEC_SHA_256_SUM0 UNSPEC_SHA_256_SUM1])
319 (define_int_attr sha256_op [
320 (UNSPEC_SHA_256_SIG0 "sha256sig0") (UNSPEC_SHA_256_SIG1 "sha256sig1")
321 (UNSPEC_SHA_256_SUM0 "sha256sum0") (UNSPEC_SHA_256_SUM1 "sha256sum1")])
323 (define_insn "*riscv_<sha256_op>_si"
324 [(set (match_operand:SI 0 "register_operand" "=r")
325 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
327 "TARGET_ZKNH && !TARGET_64BIT"
329 [(set_attr "type" "crypto")])
331 (define_insn "riscv_<sha256_op>_di_extended"
332 [(set (match_operand:DI 0 "register_operand" "=r")
334 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
336 "TARGET_ZKNH && TARGET_64BIT"
338 [(set_attr "type" "crypto")])
340 (define_expand "riscv_<sha256_op>_si"
341 [(set (match_operand:SI 0 "register_operand" "=r")
342 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
348 rtx t = gen_reg_rtx (DImode);
349 emit_insn (gen_riscv_<sha256_op>_di_extended (t, operands[1]));
350 t = gen_lowpart (SImode, t);
351 SUBREG_PROMOTED_VAR_P (t) = 1;
352 SUBREG_PROMOTED_SET (t, SRP_SIGNED);
353 emit_move_insn (operands[0], t);
357 [(set_attr "type" "crypto")])
361 (define_insn "riscv_sha512sig0h"
362 [(set (match_operand:SI 0 "register_operand" "=r")
363 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
364 (match_operand:SI 2 "register_operand" "r")]
365 UNSPEC_SHA_512_SIG0H))]
366 "TARGET_ZKNH && !TARGET_64BIT"
367 "sha512sig0h\t%0,%1,%2"
368 [(set_attr "type" "crypto")])
370 (define_insn "riscv_sha512sig0l"
371 [(set (match_operand:SI 0 "register_operand" "=r")
372 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
373 (match_operand:SI 2 "register_operand" "r")]
374 UNSPEC_SHA_512_SIG0L))]
375 "TARGET_ZKNH && !TARGET_64BIT"
376 "sha512sig0l\t%0,%1,%2"
377 [(set_attr "type" "crypto")])
379 (define_insn "riscv_sha512sig1h"
380 [(set (match_operand:SI 0 "register_operand" "=r")
381 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
382 (match_operand:SI 2 "register_operand" "r")]
383 UNSPEC_SHA_512_SIG1H))]
384 "TARGET_ZKNH && !TARGET_64BIT"
385 "sha512sig1h\t%0,%1,%2"
386 [(set_attr "type" "crypto")])
388 (define_insn "riscv_sha512sig1l"
389 [(set (match_operand:SI 0 "register_operand" "=r")
390 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
391 (match_operand:SI 2 "register_operand" "r")]
392 UNSPEC_SHA_512_SIG1L))]
393 "TARGET_ZKNH && !TARGET_64BIT"
394 "sha512sig1l\t%0,%1,%2"
395 [(set_attr "type" "crypto")])
397 (define_insn "riscv_sha512sum0r"
398 [(set (match_operand:SI 0 "register_operand" "=r")
399 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
400 (match_operand:SI 2 "register_operand" "r")]
401 UNSPEC_SHA_512_SUM0R))]
402 "TARGET_ZKNH && !TARGET_64BIT"
403 "sha512sum0r\t%0,%1,%2"
404 [(set_attr "type" "crypto")])
406 (define_insn "riscv_sha512sum1r"
407 [(set (match_operand:SI 0 "register_operand" "=r")
408 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
409 (match_operand:SI 2 "register_operand" "r")]
410 UNSPEC_SHA_512_SUM1R))]
411 "TARGET_ZKNH && !TARGET_64BIT"
412 "sha512sum1r\t%0,%1,%2"
413 [(set_attr "type" "crypto")])
415 (define_insn "riscv_sha512sig0"
416 [(set (match_operand:DI 0 "register_operand" "=r")
417 (unspec:DI [(match_operand:DI 1 "register_operand" "r")]
418 UNSPEC_SHA_512_SIG0))]
419 "TARGET_ZKNH && TARGET_64BIT"
421 [(set_attr "type" "crypto")])
423 (define_insn "riscv_sha512sig1"
424 [(set (match_operand:DI 0 "register_operand" "=r")
425 (unspec:DI [(match_operand:DI 1 "register_operand" "r")]
426 UNSPEC_SHA_512_SIG1))]
427 "TARGET_ZKNH && TARGET_64BIT"
429 [(set_attr "type" "crypto")])
431 (define_insn "riscv_sha512sum0"
432 [(set (match_operand:DI 0 "register_operand" "=r")
433 (unspec:DI [(match_operand:DI 1 "register_operand" "r")]
434 UNSPEC_SHA_512_SUM0))]
435 "TARGET_ZKNH && TARGET_64BIT"
437 [(set_attr "type" "crypto")])
439 (define_insn "riscv_sha512sum1"
440 [(set (match_operand:DI 0 "register_operand" "=r")
441 (unspec:DI [(match_operand:DI 1 "register_operand" "r")]
442 UNSPEC_SHA_512_SUM1))]
443 "TARGET_ZKNH && TARGET_64BIT"
445 [(set_attr "type" "crypto")])
449 (define_int_iterator SM3_OP [UNSPEC_SM3_P0 UNSPEC_SM3_P1])
450 (define_int_attr sm3_op [(UNSPEC_SM3_P0 "sm3p0") (UNSPEC_SM3_P1 "sm3p1")])
452 (define_insn "*riscv_<sm3_op>_si"
453 [(set (match_operand:SI 0 "register_operand" "=r")
454 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
456 "TARGET_ZKSH && !TARGET_64BIT"
458 [(set_attr "type" "crypto")])
460 (define_insn "riscv_<sm3_op>_di_extended"
461 [(set (match_operand:DI 0 "register_operand" "=r")
463 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
465 "TARGET_ZKSH && TARGET_64BIT"
467 [(set_attr "type" "crypto")])
469 (define_expand "riscv_<sm3_op>_si"
470 [(set (match_operand:SI 0 "register_operand" "=r")
471 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
477 rtx t = gen_reg_rtx (DImode);
478 emit_insn (gen_riscv_<sm3_op>_di_extended (t, operands[1]));
479 t = gen_lowpart (SImode, t);
480 SUBREG_PROMOTED_VAR_P (t) = 1;
481 SUBREG_PROMOTED_SET (t, SRP_SIGNED);
482 emit_move_insn (operands[0], t);
486 [(set_attr "type" "crypto")])
490 (define_int_iterator SM4_OP [UNSPEC_SM4_ED UNSPEC_SM4_KS])
491 (define_int_attr sm4_op [(UNSPEC_SM4_ED "sm4ed") (UNSPEC_SM4_KS "sm4ks")])
493 (define_insn "*riscv_<sm4_op>_si"
494 [(set (match_operand:SI 0 "register_operand" "=r")
495 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
496 (match_operand:SI 2 "register_operand" "r")
497 (match_operand:SI 3 "const_0_3_operand" "")]
499 "TARGET_ZKSED && !TARGET_64BIT"
500 "<sm4_op>\t%0,%1,%2,%3"
501 [(set_attr "type" "crypto")])
503 (define_insn "riscv_<sm4_op>_di_extended"
504 [(set (match_operand:DI 0 "register_operand" "=r")
506 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
507 (match_operand:SI 2 "register_operand" "r")
508 (match_operand:SI 3 "const_0_3_operand" "")]
510 "TARGET_ZKSED && TARGET_64BIT"
511 "<sm4_op>\t%0,%1,%2,%3"
512 [(set_attr "type" "crypto")])
514 (define_expand "riscv_<sm4_op>_si"
515 [(set (match_operand:SI 0 "register_operand" "=r")
516 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
517 (match_operand:SI 2 "register_operand" "r")
518 (match_operand:SI 3 "const_0_3_operand" "")]
524 rtx t = gen_reg_rtx (DImode);
525 emit_insn (gen_riscv_<sm4_op>_di_extended (t, operands[1], operands[2], operands[3]));
526 t = gen_lowpart (SImode, t);
527 SUBREG_PROMOTED_VAR_P (t) = 1;
528 SUBREG_PROMOTED_SET (t, SRP_SIGNED);
529 emit_move_insn (operands[0], t);
533 [(set_attr "type" "crypto")])