1;; Machine Description for shared bits common to IWMMXT and Neon. 2;; Copyright (C) 2006-2020 Free Software Foundation, Inc. 3;; Written by CodeSourcery. 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 by 9;; the Free Software Foundation; either version 3, or (at your option) 10;; any later version. 11;; 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. 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;; Vector Moves 22 23(define_expand "mov<mode>" 24 [(set (match_operand:VNIM1 0 "nonimmediate_operand") 25 (match_operand:VNIM1 1 "general_operand"))] 26 "TARGET_NEON 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))" 30 { 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 ()) 34 { 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]))) 39 { 40 operands[1] = neon_make_constant (operands[1]); 41 gcc_assert (operands[1] != NULL_RTX); 42 } 43 } 44}) 45 46(define_expand "mov<mode>" 47 [(set (match_operand:VNINOTM1 0 "nonimmediate_operand") 48 (match_operand:VNINOTM1 1 "general_operand"))] 49 "TARGET_NEON 50 || (TARGET_REALLY_IWMMXT && VALID_IWMMXT_REG_MODE (<MODE>mode))" 51{ 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 ()) 55 { 56 if (!REG_P (operands[0])) 57 operands[1] = force_reg (<MODE>mode, operands[1]); 58 else if (TARGET_NEON && CONSTANT_P (operands[1])) 59 { 60 operands[1] = neon_make_constant (operands[1]); 61 gcc_assert (operands[1] != NULL_RTX); 62 } 63 } 64}) 65 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" 70{ 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 ()) 74 { 75 if (!REG_P (operands[0])) 76 operands[1] = force_reg (E_V8HFmode, operands[1]); 77 else if (TARGET_HAVE_MVE_FLOAT && CONSTANT_P (operands[1])) 78 { 79 operands[1] = neon_make_constant (operands[1]); 80 gcc_assert (operands[1] != NULL_RTX); 81 } 82 } 83}) 84 85;; Vector arithmetic. Expanders are blank, then unnamed insns implement 86;; patterns separately for Neon, IWMMXT and MVE. 87 88(define_expand "add<mode>3" 89 [(set (match_operand:VNIM 0 "s_register_operand") 90 (plus:VNIM (match_operand:VNIM 1 "s_register_operand") 91 (match_operand:VNIM 2 "s_register_operand")))] 92 "(TARGET_NEON && ((<MODE>mode != V2SFmode && <MODE>mode != V4SFmode) 93 || flag_unsafe_math_optimizations)) 94 || (TARGET_REALLY_IWMMXT && VALID_IWMMXT_REG_MODE (<MODE>mode)) 95 || (TARGET_HAVE_MVE && VALID_MVE_SI_MODE(<MODE>mode)) 96 || (TARGET_HAVE_MVE_FLOAT && VALID_MVE_SF_MODE(<MODE>mode))" 97{ 98}) 99 100;; Vector arithmetic. Expanders are blank, then unnamed insns implement 101;; patterns separately for Neon and MVE. 102 103(define_expand "addv8hf3" 104 [(set (match_operand:V8HF 0 "s_register_operand") 105 (plus:V8HF (match_operand:V8HF 1 "s_register_operand") 106 (match_operand:V8HF 2 "s_register_operand")))] 107 "(TARGET_HAVE_MVE_FLOAT && VALID_MVE_SF_MODE(V8HFmode)) 108 || (TARGET_NEON_FP16INST && flag_unsafe_math_optimizations)" 109{ 110 if (TARGET_NEON_FP16INST && flag_unsafe_math_optimizations) 111 emit_insn (gen_addv8hf3_neon (operands[0], operands[1], operands[2])); 112}) 113 114;; Vector arithmetic. Expanders are blank, then unnamed insns implement 115;; patterns separately for Neon and IWMMXT. 116 117(define_expand "add<mode>3" 118 [(set (match_operand:VNINOTM 0 "s_register_operand") 119 (plus:VNINOTM (match_operand:VNINOTM 1 "s_register_operand") 120 (match_operand:VNINOTM 2 "s_register_operand")))] 121 "(TARGET_NEON && ((<MODE>mode != V2SFmode && <MODE>mode != V4SFmode) 122 || flag_unsafe_math_optimizations)) 123 || (TARGET_REALLY_IWMMXT && VALID_IWMMXT_REG_MODE (<MODE>mode))" 124{ 125}) 126 127;; Vector arithmetic. Expanders are blank, then unnamed insns implement 128;; patterns separately for IWMMXT and Neon. 129 130(define_expand "sub<mode>3" 131 [(set (match_operand:VALL 0 "s_register_operand") 132 (minus:VALL (match_operand:VALL 1 "s_register_operand") 133 (match_operand:VALL 2 "s_register_operand")))] 134 "(TARGET_NEON && ((<MODE>mode != V2SFmode && <MODE>mode != V4SFmode) 135 || flag_unsafe_math_optimizations)) 136 || (TARGET_REALLY_IWMMXT && VALID_IWMMXT_REG_MODE (<MODE>mode))" 137{ 138}) 139 140(define_expand "mul<mode>3" 141 [(set (match_operand:VALLW 0 "s_register_operand") 142 (mult:VALLW (match_operand:VALLW 1 "s_register_operand") 143 (match_operand:VALLW 2 "s_register_operand")))] 144 "(TARGET_NEON && ((<MODE>mode != V2SFmode && <MODE>mode != V4SFmode) 145 || flag_unsafe_math_optimizations)) 146 || (<MODE>mode == V4HImode && TARGET_REALLY_IWMMXT)" 147{ 148}) 149 150(define_expand "smin<mode>3" 151 [(set (match_operand:VALLW 0 "s_register_operand") 152 (smin:VALLW (match_operand:VALLW 1 "s_register_operand") 153 (match_operand:VALLW 2 "s_register_operand")))] 154 "(TARGET_NEON && ((<MODE>mode != V2SFmode && <MODE>mode != V4SFmode) 155 || flag_unsafe_math_optimizations)) 156 || (TARGET_REALLY_IWMMXT && VALID_IWMMXT_REG_MODE (<MODE>mode))" 157{ 158}) 159 160(define_expand "umin<mode>3" 161 [(set (match_operand:VINTW 0 "s_register_operand") 162 (umin:VINTW (match_operand:VINTW 1 "s_register_operand") 163 (match_operand:VINTW 2 "s_register_operand")))] 164 "TARGET_NEON 165 || (TARGET_REALLY_IWMMXT && VALID_IWMMXT_REG_MODE (<MODE>mode))" 166{ 167}) 168 169(define_expand "smax<mode>3" 170 [(set (match_operand:VALLW 0 "s_register_operand") 171 (smax:VALLW (match_operand:VALLW 1 "s_register_operand") 172 (match_operand:VALLW 2 "s_register_operand")))] 173 "(TARGET_NEON && ((<MODE>mode != V2SFmode && <MODE>mode != V4SFmode) 174 || flag_unsafe_math_optimizations)) 175 || (TARGET_REALLY_IWMMXT && VALID_IWMMXT_REG_MODE (<MODE>mode))" 176{ 177}) 178 179(define_expand "umax<mode>3" 180 [(set (match_operand:VINTW 0 "s_register_operand") 181 (umax:VINTW (match_operand:VINTW 1 "s_register_operand") 182 (match_operand:VINTW 2 "s_register_operand")))] 183 "TARGET_NEON 184 || (TARGET_REALLY_IWMMXT && VALID_IWMMXT_REG_MODE (<MODE>mode))" 185{ 186}) 187 188(define_expand "vec_perm<mode>" 189 [(match_operand:VE 0 "s_register_operand") 190 (match_operand:VE 1 "s_register_operand") 191 (match_operand:VE 2 "s_register_operand") 192 (match_operand:VE 3 "s_register_operand")] 193 "TARGET_NEON && !BYTES_BIG_ENDIAN" 194{ 195 arm_expand_vec_perm (operands[0], operands[1], operands[2], operands[3]); 196 DONE; 197}) 198 199(define_expand "vec_extract<mode><V_elem_l>" 200 [(match_operand:<V_elem> 0 "nonimmediate_operand") 201 (match_operand:VQX_NOBF 1 "s_register_operand") 202 (match_operand:SI 2 "immediate_operand")] 203 "TARGET_NEON || TARGET_HAVE_MVE" 204{ 205 if (TARGET_NEON) 206 emit_insn (gen_neon_vec_extract<mode><V_elem_l> (operands[0], operands[1], 207 operands[2])); 208 else if (TARGET_HAVE_MVE) 209 emit_insn (gen_mve_vec_extract<mode><V_elem_l> (operands[0], operands[1], 210 operands[2])); 211 else 212 gcc_unreachable (); 213 DONE; 214}) 215 216(define_expand "vec_set<mode>" 217 [(match_operand:VQX_NOBF 0 "s_register_operand" "") 218 (match_operand:<V_elem> 1 "s_register_operand" "") 219 (match_operand:SI 2 "immediate_operand" "")] 220 "TARGET_NEON || TARGET_HAVE_MVE" 221{ 222 HOST_WIDE_INT elem = HOST_WIDE_INT_1 << INTVAL (operands[2]); 223 if (TARGET_NEON) 224 emit_insn (gen_vec_set<mode>_internal (operands[0], operands[1], 225 GEN_INT (elem), operands[0])); 226 else 227 emit_insn (gen_mve_vec_set<mode>_internal (operands[0], operands[1], 228 GEN_INT (elem), operands[0])); 229 DONE; 230}) 231