1 ;; Machine Description for shared bits common to IWMMXT and Neon.
2 ;; Copyright (C) 2006-2021 Free Software Foundation, Inc.
3 ;; Written by CodeSourcery.
5 ;; This file is part of GCC.
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 by
9 ;; the Free Software Foundation; either version 3, or (at your option)
12 ;; GCC is distributed in the hope that it will be useful, but
13 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 ;; General Public License for more details.
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/>.
23 (define_expand "mov<mode>"
24 [(set (match_operand:VNIM1 0 "nonimmediate_operand")
25 (match_operand:VNIM1 1 "general_operand"))]
27 || (TARGET_REALLY_IWMMXT && VALID_IWMMXT_REG_MODE (<MODE>mode))
28 || (TARGET_HAVE_MVE && VALID_MVE_SI_MODE (<MODE>mode))
29 || (TARGET_HAVE_MVE_FLOAT && VALID_MVE_SF_MODE (<MODE>mode))"
31 gcc_checking_assert (aligned_operand (operands[0], <MODE>mode));
32 gcc_checking_assert (aligned_operand (operands[1], <MODE>mode));
33 if (can_create_pseudo_p ())
35 if (!REG_P (operands[0]))
36 operands[1] = force_reg (<MODE>mode, operands[1]);
37 else if ((TARGET_NEON || TARGET_HAVE_MVE || TARGET_HAVE_MVE_FLOAT)
38 && (CONSTANT_P (operands[1])))
40 operands[1] = neon_make_constant (operands[1]);
41 gcc_assert (operands[1] != NULL_RTX);
46 (define_expand "mov<mode>"
47 [(set (match_operand:VNINOTM1 0 "nonimmediate_operand")
48 (match_operand:VNINOTM1 1 "general_operand"))]
50 || (TARGET_REALLY_IWMMXT && VALID_IWMMXT_REG_MODE (<MODE>mode))"
52 gcc_checking_assert (aligned_operand (operands[0], <MODE>mode));
53 gcc_checking_assert (aligned_operand (operands[1], <MODE>mode));
54 if (can_create_pseudo_p ())
56 if (!REG_P (operands[0]))
57 operands[1] = force_reg (<MODE>mode, operands[1]);
58 else if (TARGET_NEON && CONSTANT_P (operands[1]))
60 operands[1] = neon_make_constant (operands[1]);
61 gcc_assert (operands[1] != NULL_RTX);
66 (define_expand "movv8hf"
67 [(set (match_operand:V8HF 0 "s_register_operand")
68 (match_operand:V8HF 1 "s_register_operand"))]
69 "TARGET_NEON || TARGET_HAVE_MVE_FLOAT"
71 gcc_checking_assert (aligned_operand (operands[0], E_V8HFmode));
72 gcc_checking_assert (aligned_operand (operands[1], E_V8HFmode));
73 if (can_create_pseudo_p ())
75 if (!REG_P (operands[0]))
76 operands[1] = force_reg (E_V8HFmode, operands[1]);
80 ;; Vector arithmetic. Expanders are blank, then unnamed insns implement
81 ;; patterns separately for Neon, IWMMXT and MVE.
83 (define_expand "add<mode>3"
84 [(set (match_operand:VDQ 0 "s_register_operand")
85 (plus:VDQ (match_operand:VDQ 1 "s_register_operand")
86 (match_operand:VDQ 2 "s_register_operand")))]
87 "ARM_HAVE_<MODE>_ARITH"
90 (define_expand "sub<mode>3"
91 [(set (match_operand:VDQ 0 "s_register_operand")
92 (minus:VDQ (match_operand:VDQ 1 "s_register_operand")
93 (match_operand:VDQ 2 "s_register_operand")))]
94 "ARM_HAVE_<MODE>_ARITH"
97 (define_expand "mul<mode>3"
98 [(set (match_operand:VDQWH 0 "s_register_operand")
99 (mult:VDQWH (match_operand:VDQWH 1 "s_register_operand")
100 (match_operand:VDQWH 2 "s_register_operand")))]
101 "ARM_HAVE_<MODE>_ARITH"
104 (define_expand "smin<mode>3"
105 [(set (match_operand:VALLW 0 "s_register_operand")
106 (smin:VALLW (match_operand:VALLW 1 "s_register_operand")
107 (match_operand:VALLW 2 "s_register_operand")))]
108 "ARM_HAVE_<MODE>_ARITH"
111 (define_expand "umin<mode>3"
112 [(set (match_operand:VINTW 0 "s_register_operand")
113 (umin:VINTW (match_operand:VINTW 1 "s_register_operand")
114 (match_operand:VINTW 2 "s_register_operand")))]
115 "ARM_HAVE_<MODE>_ARITH"
118 (define_expand "smax<mode>3"
119 [(set (match_operand:VALLW 0 "s_register_operand")
120 (smax:VALLW (match_operand:VALLW 1 "s_register_operand")
121 (match_operand:VALLW 2 "s_register_operand")))]
122 "ARM_HAVE_<MODE>_ARITH"
125 (define_expand "umax<mode>3"
126 [(set (match_operand:VINTW 0 "s_register_operand")
127 (umax:VINTW (match_operand:VINTW 1 "s_register_operand")
128 (match_operand:VINTW 2 "s_register_operand")))]
129 "ARM_HAVE_<MODE>_ARITH"
132 (define_expand "vec_perm<mode>"
133 [(match_operand:VE 0 "s_register_operand")
134 (match_operand:VE 1 "s_register_operand")
135 (match_operand:VE 2 "s_register_operand")
136 (match_operand:VE 3 "s_register_operand")]
137 "TARGET_NEON && !BYTES_BIG_ENDIAN"
139 arm_expand_vec_perm (operands[0], operands[1], operands[2], operands[3]);
143 (define_expand "vec_extract<mode><V_elem_l>"
144 [(match_operand:<V_elem> 0 "nonimmediate_operand")
145 (match_operand:VQX_NOBF 1 "s_register_operand")
146 (match_operand:SI 2 "immediate_operand")]
147 "TARGET_NEON || TARGET_HAVE_MVE"
150 emit_insn (gen_neon_vec_extract<mode><V_elem_l> (operands[0], operands[1],
152 else if (TARGET_HAVE_MVE)
153 emit_insn (gen_mve_vec_extract<mode><V_elem_l> (operands[0], operands[1],
160 (define_expand "vec_set<mode>"
161 [(match_operand:VQX_NOBF 0 "s_register_operand" "")
162 (match_operand:<V_elem> 1 "s_register_operand" "")
163 (match_operand:SI 2 "immediate_operand" "")]
164 "TARGET_NEON || TARGET_HAVE_MVE"
166 HOST_WIDE_INT elem = HOST_WIDE_INT_1 << INTVAL (operands[2]);
168 emit_insn (gen_vec_set<mode>_internal (operands[0], operands[1],
169 GEN_INT (elem), operands[0]));
171 emit_insn (gen_mve_vec_set<mode>_internal (operands[0], operands[1],
172 GEN_INT (elem), operands[0]));
176 (define_expand "and<mode>3"
177 [(set (match_operand:VDQ 0 "s_register_operand" "")
178 (and:VDQ (match_operand:VDQ 1 "s_register_operand" "")
179 (match_operand:VDQ 2 "neon_inv_logic_op2" "")))]
180 "ARM_HAVE_<MODE>_ARITH"
183 (define_expand "ior<mode>3"
184 [(set (match_operand:VDQ 0 "s_register_operand" "")
185 (ior:VDQ (match_operand:VDQ 1 "s_register_operand" "")
186 (match_operand:VDQ 2 "neon_logic_op2" "")))]
187 "ARM_HAVE_<MODE>_ARITH"
190 (define_expand "xor<mode>3"
191 [(set (match_operand:VDQ 0 "s_register_operand" "")
192 (xor:VDQ (match_operand:VDQ 1 "s_register_operand" "")
193 (match_operand:VDQ 2 "s_register_operand" "")))]
194 "ARM_HAVE_<MODE>_ARITH"
197 (define_expand "one_cmpl<mode>2"
198 [(set (match_operand:VDQ 0 "s_register_operand")
199 (not:VDQ (match_operand:VDQ 1 "s_register_operand")))]
200 "ARM_HAVE_<MODE>_ARITH"
203 (define_expand "neg<mode>2"
204 [(set (match_operand:VDQWH 0 "s_register_operand" "")
205 (neg:VDQWH (match_operand:VDQWH 1 "s_register_operand" "")))]
206 "ARM_HAVE_<MODE>_ARITH"
209 (define_expand "cadd<rot><mode>3"
210 [(set (match_operand:VF 0 "register_operand")
211 (unspec:VF [(match_operand:VF 1 "register_operand")
212 (match_operand:VF 2 "register_operand")]
214 "(TARGET_COMPLEX || (TARGET_HAVE_MVE && TARGET_HAVE_MVE_FLOAT
215 && ARM_HAVE_<MODE>_ARITH)) && !BYTES_BIG_ENDIAN"