1;; ARMv8-A crypto patterns. 2;; Copyright (C) 2013-2020 Free Software Foundation, Inc. 3;; Contributed by ARM Ltd. 4 5;; This file is part of GCC. 6 7;; GCC is free software; you can redistribute it and/or modify it 8;; under the terms of the GNU General Public License as published 9;; by the Free Software Foundation; either version 3, or (at your 10;; option) any later version. 11 12;; GCC is distributed in the hope that it will be useful, but WITHOUT 13;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 15;; License for more details. 16 17;; You should have received a copy of the GNU General Public License 18;; along with GCC; see the file COPYING3. If not see 19;; <http://www.gnu.org/licenses/>. 20 21 22(define_insn "crypto_<crypto_pattern>" 23 [(set (match_operand:<crypto_mode> 0 "register_operand" "=w") 24 (unspec:<crypto_mode> 25 [(match_operand:<crypto_mode> 1 "register_operand" "w")] 26 CRYPTO_AESMC))] 27 "TARGET_CRYPTO" 28 "<crypto_pattern>.<crypto_size_sfx>\\t%q0, %q1" 29 [(set_attr "type" "<crypto_type>")] 30) 31 32(define_insn "crypto_<crypto_pattern>" 33 [(set (match_operand:V16QI 0 "register_operand" "=w") 34 (unspec:V16QI 35 [(xor:V16QI 36 (match_operand:V16QI 1 "register_operand" "%0") 37 (match_operand:V16QI 2 "register_operand" "w"))] 38 CRYPTO_AES))] 39 "TARGET_CRYPTO" 40 "<crypto_pattern>.<crypto_size_sfx>\\t%q0, %q2" 41 [(set_attr "type" "<crypto_type>")] 42) 43 44;; When AESE/AESMC fusion is enabled we really want to keep the two together 45;; and enforce the register dependency without scheduling or register 46;; allocation messing up the order or introducing moves inbetween. 47;; Mash the two together during combine. 48 49(define_insn "*aarch32_crypto_aese_fused" 50 [(set (match_operand:V16QI 0 "register_operand" "=w") 51 (unspec:V16QI 52 [(unspec:V16QI 53 [(xor:V16QI 54 (match_operand:V16QI 1 "register_operand" "%0") 55 (match_operand:V16QI 2 "register_operand" "w"))] 56 UNSPEC_AESE)] 57 UNSPEC_AESMC))] 58 "TARGET_CRYPTO 59 && arm_fusion_enabled_p (tune_params::FUSE_AES_AESMC)" 60 "aese.8\\t%q0, %q2\;aesmc.8\\t%q0, %q0" 61 [(set_attr "type" "crypto_aese") 62 (set_attr "length" "8")] 63) 64 65;; When AESD/AESIMC fusion is enabled we really want to keep the two together 66;; and enforce the register dependency without scheduling or register 67;; allocation messing up the order or introducing moves inbetween. 68;; Mash the two together during combine. 69 70(define_insn "*aarch32_crypto_aesd_fused" 71 [(set (match_operand:V16QI 0 "register_operand" "=w") 72 (unspec:V16QI 73 [(unspec:V16QI 74 [(xor:V16QI 75 (match_operand:V16QI 1 "register_operand" "%0") 76 (match_operand:V16QI 2 "register_operand" "w"))] 77 UNSPEC_AESD)] 78 UNSPEC_AESIMC))] 79 "TARGET_CRYPTO 80 && arm_fusion_enabled_p (tune_params::FUSE_AES_AESMC)" 81 "aesd.8\\t%q0, %q2\;aesimc.8\\t%q0, %q0" 82 [(set_attr "type" "crypto_aese") 83 (set_attr "length" "8")] 84) 85 86(define_insn "crypto_<crypto_pattern>" 87 [(set (match_operand:<crypto_mode> 0 "register_operand" "=w") 88 (unspec:<crypto_mode> 89 [(match_operand:<crypto_mode> 1 "register_operand" "0") 90 (match_operand:<crypto_mode> 2 "register_operand" "w")] 91 CRYPTO_BINARY))] 92 "TARGET_CRYPTO" 93 "<crypto_pattern>.<crypto_size_sfx>\\t%q0, %q2" 94 [(set_attr "type" "<crypto_type>")] 95) 96 97(define_insn "crypto_<crypto_pattern>" 98 [(set (match_operand:<crypto_mode> 0 "register_operand" "=w") 99 (unspec:<crypto_mode> [(match_operand:<crypto_mode> 1 "register_operand" "0") 100 (match_operand:<crypto_mode> 2 "register_operand" "w") 101 (match_operand:<crypto_mode> 3 "register_operand" "w")] 102 CRYPTO_TERNARY))] 103 "TARGET_CRYPTO" 104 "<crypto_pattern>.<crypto_size_sfx>\\t%q0, %q2, %q3" 105 [(set_attr "type" "<crypto_type>")] 106) 107 108/* The vec_select operation always selects index 0 from the lower V2SI subreg 109 of the V4SI, adjusted for endianness. Required due to neon_vget_lane and 110 neon_set_lane that change the element ordering in memory for big-endian. */ 111 112(define_expand "crypto_sha1h" 113 [(set (match_operand:V4SI 0 "register_operand") 114 (match_operand:V4SI 1 "register_operand"))] 115 "TARGET_CRYPTO" 116{ 117 rtx op2 = GEN_INT (NEON_ENDIAN_LANE_N (V2SImode, 0)); 118 emit_insn (gen_crypto_sha1h_lb (operands[0], operands[1], op2)); 119 DONE; 120}) 121 122(define_insn "crypto_sha1h_lb" 123 [(set (match_operand:V4SI 0 "register_operand" "=w") 124 (unspec:V4SI 125 [(vec_select:SI 126 (match_operand:V4SI 1 "register_operand" "w") 127 (parallel [(match_operand:SI 2 "immediate_operand" "i")]))] 128 UNSPEC_SHA1H))] 129 "TARGET_CRYPTO && INTVAL (operands[2]) == NEON_ENDIAN_LANE_N (V2SImode, 0)" 130 "sha1h.32\\t%q0, %q1" 131 [(set_attr "type" "crypto_sha1_fast")] 132) 133 134(define_insn "crypto_vmullp64" 135 [(set (match_operand:TI 0 "register_operand" "=w") 136 (unspec:TI [(match_operand:DI 1 "register_operand" "w") 137 (match_operand:DI 2 "register_operand" "w")] 138 UNSPEC_VMULLP64))] 139 "TARGET_CRYPTO" 140 "vmull.p64\\t%q0, %P1, %P2" 141 [(set_attr "type" "crypto_pmull")] 142) 143 144/* The vec_select operation always selects index 0 from the lower V2SI subreg 145 of the V4SI, adjusted for endianness. Required due to neon_vget_lane and 146 neon_set_lane that change the element ordering in memory for big-endian. */ 147 148(define_expand "crypto_<crypto_pattern>" 149 [(set (match_operand:V4SI 0 "register_operand") 150 (unspec:<crypto_mode> 151 [(match_operand:<crypto_mode> 1 "register_operand") 152 (match_operand:<crypto_mode> 2 "register_operand") 153 (match_operand:<crypto_mode> 3 "register_operand")] 154 CRYPTO_SELECTING))] 155 "TARGET_CRYPTO" 156{ 157 rtx op4 = GEN_INT (NEON_ENDIAN_LANE_N (V2SImode, 0)); 158 emit_insn (gen_crypto_<crypto_pattern>_lb 159 (operands[0], operands[1], operands[2], operands[3], op4)); 160 DONE; 161}) 162 163(define_insn "crypto_<crypto_pattern>_lb" 164 [(set (match_operand:V4SI 0 "register_operand" "=w") 165 (unspec:<crypto_mode> 166 [(match_operand:<crypto_mode> 1 "register_operand" "0") 167 (vec_select:SI 168 (match_operand:<crypto_mode> 2 "register_operand" "w") 169 (parallel [(match_operand:SI 4 "immediate_operand" "i")])) 170 (match_operand:<crypto_mode> 3 "register_operand" "w")] 171 CRYPTO_SELECTING))] 172 "TARGET_CRYPTO && INTVAL (operands[4]) == NEON_ENDIAN_LANE_N (V2SImode, 0)" 173 "<crypto_pattern>.<crypto_size_sfx>\\t%q0, %q2, %q3" 174 [(set_attr "type" "<crypto_type>")] 175) 176