]>
Commit | Line | Data |
---|---|---|
3f4d9b98 | 1 | ;; ARM VFP instruction patterns |
d1e082c2 | 2 | ;; Copyright (C) 2003-2013 Free Software Foundation, Inc. |
3f4d9b98 | 3 | ;; Written by CodeSourcery. |
9b66ebb1 PB |
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 | |
2f83c7d6 | 9 | ;; the Free Software Foundation; either version 3, or (at your option) |
9b66ebb1 PB |
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 | |
2f83c7d6 NC |
18 | ;; along with GCC; see the file COPYING3. If not see |
19 | ;; <http://www.gnu.org/licenses/>. */ | |
9b66ebb1 | 20 | |
9b66ebb1 PB |
21 | ;; SImode moves |
22 | ;; ??? For now do not allow loading constants into vfp regs. This causes | |
59b9a953 | 23 | ;; problems because small constants get converted into adds. |
9b66ebb1 | 24 | (define_insn "*arm_movsi_vfp" |
f5c630c3 | 25 | [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m ,*t,r,*t,*t, *Uv") |
d58bc084 | 26 | (match_operand:SI 1 "general_operand" "rk, I,K,j,mi,rk,r,*t,*t,*Uvi,*t"))] |
9b66ebb1 PB |
27 | "TARGET_ARM && TARGET_VFP && TARGET_HARD_FLOAT |
28 | && ( s_register_operand (operands[0], SImode) | |
29 | || s_register_operand (operands[1], SImode))" | |
5b3e6663 PB |
30 | "* |
31 | switch (which_alternative) | |
32 | { | |
f5c630c3 | 33 | case 0: case 1: |
5b3e6663 | 34 | return \"mov%?\\t%0, %1\"; |
5b3e6663 | 35 | case 2: |
f5c630c3 | 36 | return \"mvn%?\\t%0, #%B1\"; |
5b3e6663 | 37 | case 3: |
f5c630c3 | 38 | return \"movw%?\\t%0, %1\"; |
5b3e6663 | 39 | case 4: |
f5c630c3 | 40 | return \"ldr%?\\t%0, %1\"; |
5b3e6663 | 41 | case 5: |
f5c630c3 | 42 | return \"str%?\\t%1, %0\"; |
5b3e6663 | 43 | case 6: |
f5c630c3 | 44 | return \"fmsr%?\\t%0, %1\\t%@ int\"; |
5b3e6663 | 45 | case 7: |
f5c630c3 PB |
46 | return \"fmrs%?\\t%0, %1\\t%@ int\"; |
47 | case 8: | |
5b3e6663 | 48 | return \"fcpys%?\\t%0, %1\\t%@ int\"; |
f5c630c3 | 49 | case 9: case 10: |
5b3e6663 PB |
50 | return output_move_vfp (operands); |
51 | default: | |
52 | gcc_unreachable (); | |
53 | } | |
54 | " | |
55 | [(set_attr "predicable" "yes") | |
148413a4 | 56 | (set_attr "type" "*,*,simple_alu_imm,simple_alu_imm,load1,store1,r_2_f,f_2_r,fcpys,f_loads,f_stores") |
392e87f6 | 57 | (set_attr "neon_type" "*,*,*,*,*,*,neon_mcr,neon_mrc,neon_vmov,*,*") |
f8045c41 | 58 | (set_attr "insn" "mov,mov,mvn,mov,*,*,*,*,*,*,*") |
f5c630c3 PB |
59 | (set_attr "pool_range" "*,*,*,*,4096,*,*,*,*,1020,*") |
60 | (set_attr "neg_pool_range" "*,*,*,*,4084,*,*,*,*,1008,*")] | |
5b3e6663 PB |
61 | ) |
62 | ||
28907f9a MS |
63 | ;; See thumb2.md:thumb2_movsi_insn for an explanation of the split |
64 | ;; high/low register alternatives for loads and stores here. | |
5b3e6663 | 65 | (define_insn "*thumb2_movsi_vfp" |
28907f9a MS |
66 | [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r, l,*hk,m, *m,*t, r,*t,*t, *Uv") |
67 | (match_operand:SI 1 "general_operand" "rk, I,K,j,mi,*mi,l,*hk, r,*t,*t,*Uvi,*t"))] | |
5b3e6663 PB |
68 | "TARGET_THUMB2 && TARGET_VFP && TARGET_HARD_FLOAT |
69 | && ( s_register_operand (operands[0], SImode) | |
70 | || s_register_operand (operands[1], SImode))" | |
71 | "* | |
72 | switch (which_alternative) | |
73 | { | |
f5c630c3 | 74 | case 0: case 1: |
5b3e6663 | 75 | return \"mov%?\\t%0, %1\"; |
5b3e6663 | 76 | case 2: |
f5c630c3 | 77 | return \"mvn%?\\t%0, #%B1\"; |
5b3e6663 | 78 | case 3: |
f5c630c3 | 79 | return \"movw%?\\t%0, %1\"; |
5b3e6663 | 80 | case 4: |
5b3e6663 | 81 | case 5: |
28907f9a | 82 | return \"ldr%?\\t%0, %1\"; |
5b3e6663 | 83 | case 6: |
5b3e6663 | 84 | case 7: |
28907f9a | 85 | return \"str%?\\t%1, %0\"; |
f5c630c3 | 86 | case 8: |
28907f9a MS |
87 | return \"fmsr%?\\t%0, %1\\t%@ int\"; |
88 | case 9: | |
89 | return \"fmrs%?\\t%0, %1\\t%@ int\"; | |
90 | case 10: | |
5b3e6663 | 91 | return \"fcpys%?\\t%0, %1\\t%@ int\"; |
28907f9a | 92 | case 11: case 12: |
5b3e6663 PB |
93 | return output_move_vfp (operands); |
94 | default: | |
95 | gcc_unreachable (); | |
96 | } | |
97 | " | |
9b66ebb1 | 98 | [(set_attr "predicable" "yes") |
837b01f6 | 99 | (set_attr "type" "*,*,*,*,load1,load1,store1,store1,r_2_f,f_2_r,fcpys,f_loads,f_stores") |
392e87f6 | 100 | (set_attr "neon_type" "*,*,*,*,*,*,*,*,neon_mcr,neon_mrc,neon_vmov,*,*") |
f8045c41 | 101 | (set_attr "insn" "mov,mov,mvn,mov,*,*,*,*,*,*,*,*,*") |
88f519b2 | 102 | (set_attr "pool_range" "*,*,*,*,1018,4094,*,*,*,*,*,1018,*") |
28907f9a | 103 | (set_attr "neg_pool_range" "*,*,*,*, 0, 0,*,*,*,*,*,1008,*")] |
9b66ebb1 PB |
104 | ) |
105 | ||
106 | ||
107 | ;; DImode moves | |
108 | ||
0127c76f | 109 | (define_insn "*movdi_vfp" |
4542a38a GY |
110 | [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r,r,r,r,q,q,m,w,r,w,w, Uv") |
111 | (match_operand:DI 1 "di_operand" "r,rDa,Db,Dc,mi,mi,q,r,w,w,Uvi,w"))] | |
0127c76f | 112 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP && arm_tune != cortexa8 |
7baa7c13 | 113 | && ( register_operand (operands[0], DImode) |
00a3a76a AS |
114 | || register_operand (operands[1], DImode)) |
115 | && !(TARGET_NEON && CONST_INT_P (operands[1]) | |
116 | && neon_immediate_valid_for_move (operands[1], DImode, NULL, NULL))" | |
7baa7c13 BS |
117 | "* |
118 | switch (which_alternative) | |
119 | { | |
120 | case 0: | |
7baa7c13 BS |
121 | case 1: |
122 | case 2: | |
7baa7c13 | 123 | case 3: |
0127c76f | 124 | return \"#\"; |
7baa7c13 | 125 | case 4: |
7baa7c13 | 126 | case 5: |
0127c76f | 127 | case 6: |
3598da80 | 128 | return output_move_double (operands, true, NULL); |
0127c76f RR |
129 | case 7: |
130 | return \"fmdrr%?\\t%P0, %Q1, %R1\\t%@ int\"; | |
131 | case 8: | |
132 | return \"fmrrd%?\\t%Q0, %R0, %P1\\t%@ int\"; | |
133 | case 9: | |
7baa7c13 BS |
134 | if (TARGET_VFP_SINGLE) |
135 | return \"fcpys%?\\t%0, %1\\t%@ int\;fcpys%?\\t%p0, %p1\\t%@ int\"; | |
136 | else | |
137 | return \"fcpyd%?\\t%P0, %P1\\t%@ int\"; | |
0127c76f | 138 | case 10: case 11: |
7baa7c13 BS |
139 | return output_move_vfp (operands); |
140 | default: | |
141 | gcc_unreachable (); | |
142 | } | |
143 | " | |
0127c76f RR |
144 | [(set_attr "type" "*,*,*,*,load2,load2,store2,r_2_f,f_2_r,ffarithd,f_loadd,f_stored") |
145 | (set_attr "neon_type" "*,*,*,*,*,*,*,neon_mcr_2_mcrr,neon_mrrc,neon_vmov,*,*") | |
146 | (set (attr "length") (cond [(eq_attr "alternative" "1,4,5,6") (const_int 8) | |
147 | (eq_attr "alternative" "2") (const_int 12) | |
148 | (eq_attr "alternative" "3") (const_int 16) | |
149 | (eq_attr "alternative" "9") | |
150 | (if_then_else | |
b75b1be2 | 151 | (match_test "TARGET_VFP_SINGLE") |
0127c76f RR |
152 | (const_int 8) |
153 | (const_int 4))] | |
154 | (const_int 4))) | |
88f519b2 MGD |
155 | (set_attr "arm_pool_range" "*,*,*,*,1020,4096,*,*,*,*,1020,*") |
156 | (set_attr "thumb2_pool_range" "*,*,*,*,1018,4094,*,*,*,*,1018,*") | |
635a48fb | 157 | (set_attr "neg_pool_range" "*,*,*,*,1004,0,*,*,*,*,1004,*") |
0127c76f | 158 | (set_attr "arch" "t2,any,any,any,a,t2,any,any,any,any,any,any")] |
7baa7c13 BS |
159 | ) |
160 | ||
0127c76f RR |
161 | (define_insn "*movdi_vfp_cortexa8" |
162 | [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r,r,r,r,r,r,m,w,!r,w,w, Uv") | |
163 | (match_operand:DI 1 "di_operand" "r,rDa,Db,Dc,mi,mi,r,r,w,w,Uvi,w"))] | |
164 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP && arm_tune == cortexa8 | |
165 | && ( register_operand (operands[0], DImode) | |
00a3a76a AS |
166 | || register_operand (operands[1], DImode)) |
167 | && !(TARGET_NEON && CONST_INT_P (operands[1]) | |
168 | && neon_immediate_valid_for_move (operands[1], DImode, NULL, NULL))" | |
9b66ebb1 PB |
169 | "* |
170 | switch (which_alternative) | |
171 | { | |
9b901d50 | 172 | case 0: |
9b901d50 RE |
173 | case 1: |
174 | case 2: | |
9b66ebb1 | 175 | case 3: |
0127c76f | 176 | return \"#\"; |
9b66ebb1 | 177 | case 4: |
9b66ebb1 | 178 | case 5: |
0127c76f | 179 | case 6: |
3598da80 | 180 | return output_move_double (operands, true, NULL); |
0127c76f | 181 | case 7: |
5b3e6663 | 182 | return \"fmdrr%?\\t%P0, %Q1, %R1\\t%@ int\"; |
0127c76f | 183 | case 8: |
5b3e6663 | 184 | return \"fmrrd%?\\t%Q0, %R0, %P1\\t%@ int\"; |
0127c76f RR |
185 | case 9: |
186 | return \"fcpyd%?\\t%P0, %P1\\t%@ int\"; | |
187 | case 10: case 11: | |
5b3e6663 PB |
188 | return output_move_vfp (operands); |
189 | default: | |
0127c76f | 190 | gcc_unreachable (); |
5b3e6663 PB |
191 | } |
192 | " | |
0127c76f | 193 | [(set_attr "type" "*,*,*,*,load2,load2,store2,r_2_f,f_2_r,ffarithd,f_loadd,f_stored") |
392e87f6 | 194 | (set_attr "neon_type" "*,*,*,*,*,*,*,neon_mcr_2_mcrr,neon_mrrc,neon_vmov,*,*") |
3598da80 RR |
195 | (set (attr "length") (cond [(eq_attr "alternative" "1") (const_int 8) |
196 | (eq_attr "alternative" "2") (const_int 12) | |
197 | (eq_attr "alternative" "3") (const_int 16) | |
198 | (eq_attr "alternative" "4,5,6") | |
199 | (symbol_ref | |
200 | "arm_count_output_move_double_insns (operands) \ | |
201 | * 4")] | |
202 | (const_int 4))) | |
0127c76f | 203 | (set_attr "predicable" "yes") |
88f519b2 MGD |
204 | (set_attr "arm_pool_range" "*,*,*,*,1018,4094,*,*,*,*,1018,*") |
205 | (set_attr "thumb2_pool_range" "*,*,*,*,1018,4094,*,*,*,*,1018,*") | |
635a48fb | 206 | (set_attr "neg_pool_range" "*,*,*,*,1004,0,*,*,*,*,1004,*") |
3598da80 RR |
207 | (set (attr "ce_count") |
208 | (symbol_ref "get_attr_length (insn) / 4")) | |
0127c76f RR |
209 | (set_attr "arch" "t2,any,any,any,a,t2,any,any,any,any,any,any")] |
210 | ) | |
5b3e6663 | 211 | |
0fd8c3ad | 212 | ;; HFmode moves |
e0dc3601 | 213 | (define_insn "*movhf_vfp_neon" |
0fd8c3ad SL |
214 | [(set (match_operand:HF 0 "nonimmediate_operand" "= t,Um,r,m,t,r,t,r,r") |
215 | (match_operand:HF 1 "general_operand" " Um, t,m,r,t,r,r,t,F"))] | |
216 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_NEON_FP16 | |
217 | && ( s_register_operand (operands[0], HFmode) | |
218 | || s_register_operand (operands[1], HFmode))" | |
219 | "* | |
220 | switch (which_alternative) | |
221 | { | |
222 | case 0: /* S register from memory */ | |
223 | return \"vld1.16\\t{%z0}, %A1\"; | |
224 | case 1: /* memory from S register */ | |
225 | return \"vst1.16\\t{%z1}, %A0\"; | |
226 | case 2: /* ARM register from memory */ | |
227 | return \"ldrh\\t%0, %1\\t%@ __fp16\"; | |
228 | case 3: /* memory from ARM register */ | |
229 | return \"strh\\t%1, %0\\t%@ __fp16\"; | |
230 | case 4: /* S register from S register */ | |
231 | return \"fcpys\\t%0, %1\"; | |
232 | case 5: /* ARM register from ARM register */ | |
233 | return \"mov\\t%0, %1\\t%@ __fp16\"; | |
234 | case 6: /* S register from ARM register */ | |
235 | return \"fmsr\\t%0, %1\"; | |
236 | case 7: /* ARM register from S register */ | |
237 | return \"fmrs\\t%0, %1\"; | |
238 | case 8: /* ARM register from constant */ | |
239 | { | |
240 | REAL_VALUE_TYPE r; | |
241 | long bits; | |
242 | rtx ops[4]; | |
243 | ||
244 | REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]); | |
245 | bits = real_to_target (NULL, &r, HFmode); | |
246 | ops[0] = operands[0]; | |
247 | ops[1] = GEN_INT (bits); | |
248 | ops[2] = GEN_INT (bits & 0xff00); | |
249 | ops[3] = GEN_INT (bits & 0x00ff); | |
250 | ||
251 | if (arm_arch_thumb2) | |
252 | output_asm_insn (\"movw\\t%0, %1\", ops); | |
253 | else | |
254 | output_asm_insn (\"mov\\t%0, %2\;orr\\t%0, %0, %3\", ops); | |
255 | return \"\"; | |
256 | } | |
257 | default: | |
258 | gcc_unreachable (); | |
259 | } | |
260 | " | |
261 | [(set_attr "conds" "unconditional") | |
262 | (set_attr "type" "*,*,load1,store1,fcpys,*,r_2_f,f_2_r,*") | |
263 | (set_attr "neon_type" "neon_vld1_1_2_regs,neon_vst1_1_2_regs_vst2_2_regs,*,*,*,*,*,*,*") | |
264 | (set_attr "length" "4,4,4,4,4,4,4,4,8")] | |
265 | ) | |
266 | ||
e0dc3601 PB |
267 | ;; FP16 without element load/store instructions. |
268 | (define_insn "*movhf_vfp" | |
269 | [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,t,r,t,r,r") | |
270 | (match_operand:HF 1 "general_operand" " m,r,t,r,r,t,F"))] | |
271 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FP16 && !TARGET_NEON_FP16 | |
272 | && ( s_register_operand (operands[0], HFmode) | |
273 | || s_register_operand (operands[1], HFmode))" | |
274 | "* | |
275 | switch (which_alternative) | |
276 | { | |
277 | case 0: /* ARM register from memory */ | |
278 | return \"ldrh\\t%0, %1\\t%@ __fp16\"; | |
279 | case 1: /* memory from ARM register */ | |
280 | return \"strh\\t%1, %0\\t%@ __fp16\"; | |
281 | case 2: /* S register from S register */ | |
282 | return \"fcpys\\t%0, %1\"; | |
283 | case 3: /* ARM register from ARM register */ | |
284 | return \"mov\\t%0, %1\\t%@ __fp16\"; | |
285 | case 4: /* S register from ARM register */ | |
286 | return \"fmsr\\t%0, %1\"; | |
287 | case 5: /* ARM register from S register */ | |
288 | return \"fmrs\\t%0, %1\"; | |
289 | case 6: /* ARM register from constant */ | |
290 | { | |
291 | REAL_VALUE_TYPE r; | |
292 | long bits; | |
293 | rtx ops[4]; | |
294 | ||
295 | REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]); | |
296 | bits = real_to_target (NULL, &r, HFmode); | |
297 | ops[0] = operands[0]; | |
298 | ops[1] = GEN_INT (bits); | |
299 | ops[2] = GEN_INT (bits & 0xff00); | |
300 | ops[3] = GEN_INT (bits & 0x00ff); | |
301 | ||
302 | if (arm_arch_thumb2) | |
303 | output_asm_insn (\"movw\\t%0, %1\", ops); | |
304 | else | |
305 | output_asm_insn (\"mov\\t%0, %2\;orr\\t%0, %0, %3\", ops); | |
306 | return \"\"; | |
307 | } | |
308 | default: | |
309 | gcc_unreachable (); | |
310 | } | |
311 | " | |
312 | [(set_attr "conds" "unconditional") | |
313 | (set_attr "type" "load1,store1,fcpys,*,r_2_f,f_2_r,*") | |
314 | (set_attr "length" "4,4,4,4,4,4,8")] | |
315 | ) | |
316 | ||
9b66ebb1 PB |
317 | |
318 | ;; SFmode moves | |
221b2a64 PB |
319 | ;; Disparage the w<->r cases because reloading an invalid address is |
320 | ;; preferable to loading the value via integer registers. | |
9b66ebb1 PB |
321 | |
322 | (define_insn "*movsf_vfp" | |
f1adb0a9 JB |
323 | [(set (match_operand:SF 0 "nonimmediate_operand" "=t,?r,t ,t ,Uv,r ,m,t,r") |
324 | (match_operand:SF 1 "general_operand" " ?r,t,Dv,UvE,t, mE,r,t,r"))] | |
9b66ebb1 PB |
325 | "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP |
326 | && ( s_register_operand (operands[0], SFmode) | |
327 | || s_register_operand (operands[1], SFmode))" | |
5b3e6663 PB |
328 | "* |
329 | switch (which_alternative) | |
330 | { | |
331 | case 0: | |
332 | return \"fmsr%?\\t%0, %1\"; | |
333 | case 1: | |
334 | return \"fmrs%?\\t%0, %1\"; | |
f1adb0a9 JB |
335 | case 2: |
336 | return \"fconsts%?\\t%0, #%G1\"; | |
337 | case 3: case 4: | |
5b3e6663 | 338 | return output_move_vfp (operands); |
5b3e6663 | 339 | case 5: |
f1adb0a9 | 340 | return \"ldr%?\\t%0, %1\\t%@ float\"; |
5b3e6663 | 341 | case 6: |
f1adb0a9 | 342 | return \"str%?\\t%1, %0\\t%@ float\"; |
5b3e6663 | 343 | case 7: |
f1adb0a9 JB |
344 | return \"fcpys%?\\t%0, %1\"; |
345 | case 8: | |
5b3e6663 PB |
346 | return \"mov%?\\t%0, %1\\t%@ float\"; |
347 | default: | |
348 | gcc_unreachable (); | |
349 | } | |
350 | " | |
9b66ebb1 | 351 | [(set_attr "predicable" "yes") |
f1adb0a9 | 352 | (set_attr "type" |
51c69ddb | 353 | "r_2_f,f_2_r,fconsts,f_loads,f_stores,load1,store1,fcpys,*") |
392e87f6 | 354 | (set_attr "neon_type" "neon_mcr,neon_mrc,*,*,*,*,*,neon_vmov,*") |
f8045c41 | 355 | (set_attr "insn" "*,*,*,*,*,*,*,*,mov") |
f1adb0a9 JB |
356 | (set_attr "pool_range" "*,*,*,1020,*,4096,*,*,*") |
357 | (set_attr "neg_pool_range" "*,*,*,1008,*,4080,*,*,*")] | |
9b66ebb1 PB |
358 | ) |
359 | ||
5b3e6663 | 360 | (define_insn "*thumb2_movsf_vfp" |
f1adb0a9 JB |
361 | [(set (match_operand:SF 0 "nonimmediate_operand" "=t,?r,t, t ,Uv,r ,m,t,r") |
362 | (match_operand:SF 1 "general_operand" " ?r,t,Dv,UvE,t, mE,r,t,r"))] | |
5b3e6663 PB |
363 | "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_VFP |
364 | && ( s_register_operand (operands[0], SFmode) | |
365 | || s_register_operand (operands[1], SFmode))" | |
366 | "* | |
367 | switch (which_alternative) | |
368 | { | |
369 | case 0: | |
370 | return \"fmsr%?\\t%0, %1\"; | |
371 | case 1: | |
372 | return \"fmrs%?\\t%0, %1\"; | |
f1adb0a9 JB |
373 | case 2: |
374 | return \"fconsts%?\\t%0, #%G1\"; | |
375 | case 3: case 4: | |
5b3e6663 | 376 | return output_move_vfp (operands); |
5b3e6663 | 377 | case 5: |
f1adb0a9 | 378 | return \"ldr%?\\t%0, %1\\t%@ float\"; |
5b3e6663 | 379 | case 6: |
f1adb0a9 | 380 | return \"str%?\\t%1, %0\\t%@ float\"; |
5b3e6663 | 381 | case 7: |
f1adb0a9 JB |
382 | return \"fcpys%?\\t%0, %1\"; |
383 | case 8: | |
5b3e6663 PB |
384 | return \"mov%?\\t%0, %1\\t%@ float\"; |
385 | default: | |
386 | gcc_unreachable (); | |
387 | } | |
388 | " | |
389 | [(set_attr "predicable" "yes") | |
1572e697 | 390 | (set_attr "predicable_short_it" "no") |
f1adb0a9 | 391 | (set_attr "type" |
837b01f6 | 392 | "r_2_f,f_2_r,fconsts,f_loads,f_stores,load1,store1,fcpys,*") |
392e87f6 | 393 | (set_attr "neon_type" "neon_mcr,neon_mrc,*,*,*,*,*,neon_vmov,*") |
f8045c41 | 394 | (set_attr "insn" "*,*,*,*,*,*,*,*,mov") |
88f519b2 | 395 | (set_attr "pool_range" "*,*,*,1018,*,4090,*,*,*") |
f1adb0a9 | 396 | (set_attr "neg_pool_range" "*,*,*,1008,*,0,*,*,*")] |
5b3e6663 PB |
397 | ) |
398 | ||
9b66ebb1 PB |
399 | ;; DFmode moves |
400 | ||
401 | (define_insn "*movdf_vfp" | |
95f89bb3 RR |
402 | [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=w,?r,w ,w ,Uv,r, m,w,r") |
403 | (match_operand:DF 1 "soft_df_operand" " ?r,w,Dy,UvF,w ,mF,r,w,r"))] | |
d5b6e637 PB |
404 | "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP |
405 | && ( register_operand (operands[0], DFmode) | |
406 | || register_operand (operands[1], DFmode))" | |
9b66ebb1 PB |
407 | "* |
408 | { | |
409 | switch (which_alternative) | |
410 | { | |
411 | case 0: | |
412 | return \"fmdrr%?\\t%P0, %Q1, %R1\"; | |
413 | case 1: | |
414 | return \"fmrrd%?\\t%Q0, %R0, %P1\"; | |
f1adb0a9 | 415 | case 2: |
e0dc3601 | 416 | gcc_assert (TARGET_VFP_DOUBLE); |
f1adb0a9 JB |
417 | return \"fconstd%?\\t%P0, #%G1\"; |
418 | case 3: case 4: | |
5b3e6663 | 419 | return output_move_vfp (operands); |
95f89bb3 | 420 | case 5: case 6: |
3598da80 | 421 | return output_move_double (operands, true, NULL); |
9b901d50 | 422 | case 7: |
e0dc3601 PB |
423 | if (TARGET_VFP_SINGLE) |
424 | return \"fcpys%?\\t%0, %1\;fcpys%?\\t%p0, %p1\"; | |
425 | else | |
426 | return \"fcpyd%?\\t%P0, %P1\"; | |
f1adb0a9 | 427 | case 8: |
9b901d50 | 428 | return \"#\"; |
9b66ebb1 | 429 | default: |
e6d29d15 | 430 | gcc_unreachable (); |
9b66ebb1 PB |
431 | } |
432 | } | |
433 | " | |
f1adb0a9 | 434 | [(set_attr "type" |
51c69ddb | 435 | "r_2_f,f_2_r,fconstd,f_loadd,f_stored,load2,store2,ffarithd,*") |
392e87f6 | 436 | (set_attr "neon_type" "neon_mcr_2_mcrr,neon_mrrc,*,*,*,*,*,neon_vmov,*") |
95f89bb3 | 437 | (set (attr "length") (cond [(eq_attr "alternative" "5,6,8") (const_int 8) |
e0dc3601 PB |
438 | (eq_attr "alternative" "7") |
439 | (if_then_else | |
b75b1be2 | 440 | (match_test "TARGET_VFP_SINGLE") |
e0dc3601 PB |
441 | (const_int 8) |
442 | (const_int 4))] | |
443 | (const_int 4))) | |
54f52b81 | 444 | (set_attr "predicable" "yes") |
f1adb0a9 | 445 | (set_attr "pool_range" "*,*,*,1020,*,1020,*,*,*") |
635a48fb | 446 | (set_attr "neg_pool_range" "*,*,*,1004,*,1004,*,*,*")] |
9b66ebb1 PB |
447 | ) |
448 | ||
5b3e6663 | 449 | (define_insn "*thumb2_movdf_vfp" |
95f89bb3 RR |
450 | [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=w,?r,w ,w ,Uv,r ,m,w,r") |
451 | (match_operand:DF 1 "soft_df_operand" " ?r,w,Dy,UvF,w, mF,r, w,r"))] | |
de7c74be RB |
452 | "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_VFP |
453 | && ( register_operand (operands[0], DFmode) | |
454 | || register_operand (operands[1], DFmode))" | |
5b3e6663 PB |
455 | "* |
456 | { | |
457 | switch (which_alternative) | |
458 | { | |
459 | case 0: | |
460 | return \"fmdrr%?\\t%P0, %Q1, %R1\"; | |
461 | case 1: | |
462 | return \"fmrrd%?\\t%Q0, %R0, %P1\"; | |
f1adb0a9 | 463 | case 2: |
e0dc3601 | 464 | gcc_assert (TARGET_VFP_DOUBLE); |
f1adb0a9 | 465 | return \"fconstd%?\\t%P0, #%G1\"; |
95f89bb3 | 466 | case 3: case 4: |
5b3e6663 | 467 | return output_move_vfp (operands); |
95f89bb3 | 468 | case 5: case 6: case 8: |
3598da80 | 469 | return output_move_double (operands, true, NULL); |
f1adb0a9 | 470 | case 7: |
e0dc3601 PB |
471 | if (TARGET_VFP_SINGLE) |
472 | return \"fcpys%?\\t%0, %1\;fcpys%?\\t%p0, %p1\"; | |
473 | else | |
474 | return \"fcpyd%?\\t%P0, %P1\"; | |
5b3e6663 PB |
475 | default: |
476 | abort (); | |
477 | } | |
478 | } | |
479 | " | |
f1adb0a9 | 480 | [(set_attr "type" |
95f89bb3 | 481 | "r_2_f,f_2_r,fconstd,f_loadd,f_stored,load2,store2,ffarithd,*") |
392e87f6 | 482 | (set_attr "neon_type" "neon_mcr_2_mcrr,neon_mrrc,*,*,*,*,*,neon_vmov,*") |
95f89bb3 | 483 | (set (attr "length") (cond [(eq_attr "alternative" "5,6,8") (const_int 8) |
e0dc3601 PB |
484 | (eq_attr "alternative" "7") |
485 | (if_then_else | |
b75b1be2 | 486 | (match_test "TARGET_VFP_SINGLE") |
e0dc3601 PB |
487 | (const_int 8) |
488 | (const_int 4))] | |
489 | (const_int 4))) | |
88f519b2 | 490 | (set_attr "pool_range" "*,*,*,1018,*,4094,*,*,*") |
95f89bb3 | 491 | (set_attr "neg_pool_range" "*,*,*,1008,*,0,*,*,*")] |
5b3e6663 PB |
492 | ) |
493 | ||
9b66ebb1 PB |
494 | |
495 | ;; Conditional move patterns | |
496 | ||
497 | (define_insn "*movsfcc_vfp" | |
f1adb0a9 | 498 | [(set (match_operand:SF 0 "s_register_operand" "=t,t,t,t,t,t,?r,?r,?r") |
9b66ebb1 PB |
499 | (if_then_else:SF |
500 | (match_operator 3 "arm_comparison_operator" | |
501 | [(match_operand 4 "cc_register" "") (const_int 0)]) | |
f1adb0a9 JB |
502 | (match_operand:SF 1 "s_register_operand" "0,t,t,0,?r,?r,0,t,t") |
503 | (match_operand:SF 2 "s_register_operand" "t,0,t,?r,0,?r,t,0,t")))] | |
9b66ebb1 PB |
504 | "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP" |
505 | "@ | |
506 | fcpys%D3\\t%0, %2 | |
507 | fcpys%d3\\t%0, %1 | |
508 | fcpys%D3\\t%0, %2\;fcpys%d3\\t%0, %1 | |
509 | fmsr%D3\\t%0, %2 | |
510 | fmsr%d3\\t%0, %1 | |
511 | fmsr%D3\\t%0, %2\;fmsr%d3\\t%0, %1 | |
512 | fmrs%D3\\t%0, %2 | |
513 | fmrs%d3\\t%0, %1 | |
514 | fmrs%D3\\t%0, %2\;fmrs%d3\\t%0, %1" | |
515 | [(set_attr "conds" "use") | |
516 | (set_attr "length" "4,4,8,4,4,8,4,4,8") | |
392e87f6 AS |
517 | (set_attr "type" "fcpys,fcpys,fcpys,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r") |
518 | (set_attr "neon_type" "neon_vmov,neon_vmov,neon_vmov,neon_mcr,neon_mcr,neon_mcr,neon_mrc,neon_mrc,neon_mrc")] | |
9b66ebb1 PB |
519 | ) |
520 | ||
5b3e6663 | 521 | (define_insn "*thumb2_movsfcc_vfp" |
f1adb0a9 | 522 | [(set (match_operand:SF 0 "s_register_operand" "=t,t,t,t,t,t,?r,?r,?r") |
5b3e6663 PB |
523 | (if_then_else:SF |
524 | (match_operator 3 "arm_comparison_operator" | |
525 | [(match_operand 4 "cc_register" "") (const_int 0)]) | |
f1adb0a9 JB |
526 | (match_operand:SF 1 "s_register_operand" "0,t,t,0,?r,?r,0,t,t") |
527 | (match_operand:SF 2 "s_register_operand" "t,0,t,?r,0,?r,t,0,t")))] | |
1572e697 | 528 | "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_VFP && !arm_restrict_it" |
5b3e6663 PB |
529 | "@ |
530 | it\\t%D3\;fcpys%D3\\t%0, %2 | |
531 | it\\t%d3\;fcpys%d3\\t%0, %1 | |
532 | ite\\t%D3\;fcpys%D3\\t%0, %2\;fcpys%d3\\t%0, %1 | |
533 | it\\t%D3\;fmsr%D3\\t%0, %2 | |
534 | it\\t%d3\;fmsr%d3\\t%0, %1 | |
535 | ite\\t%D3\;fmsr%D3\\t%0, %2\;fmsr%d3\\t%0, %1 | |
536 | it\\t%D3\;fmrs%D3\\t%0, %2 | |
537 | it\\t%d3\;fmrs%d3\\t%0, %1 | |
538 | ite\\t%D3\;fmrs%D3\\t%0, %2\;fmrs%d3\\t%0, %1" | |
539 | [(set_attr "conds" "use") | |
540 | (set_attr "length" "6,6,10,6,6,10,6,6,10") | |
392e87f6 AS |
541 | (set_attr "type" "fcpys,fcpys,fcpys,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r") |
542 | (set_attr "neon_type" "neon_vmov,neon_vmov,neon_vmov,neon_mcr,neon_mcr,neon_mcr,neon_mrc,neon_mrc,neon_mrc")] | |
5b3e6663 PB |
543 | ) |
544 | ||
9b66ebb1 PB |
545 | (define_insn "*movdfcc_vfp" |
546 | [(set (match_operand:DF 0 "s_register_operand" "=w,w,w,w,w,w,?r,?r,?r") | |
547 | (if_then_else:DF | |
548 | (match_operator 3 "arm_comparison_operator" | |
549 | [(match_operand 4 "cc_register" "") (const_int 0)]) | |
550 | (match_operand:DF 1 "s_register_operand" "0,w,w,0,?r,?r,0,w,w") | |
551 | (match_operand:DF 2 "s_register_operand" "w,0,w,?r,0,?r,w,0,w")))] | |
e0dc3601 | 552 | "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
9b66ebb1 PB |
553 | "@ |
554 | fcpyd%D3\\t%P0, %P2 | |
555 | fcpyd%d3\\t%P0, %P1 | |
556 | fcpyd%D3\\t%P0, %P2\;fcpyd%d3\\t%P0, %P1 | |
557 | fmdrr%D3\\t%P0, %Q2, %R2 | |
558 | fmdrr%d3\\t%P0, %Q1, %R1 | |
559 | fmdrr%D3\\t%P0, %Q2, %R2\;fmdrr%d3\\t%P0, %Q1, %R1 | |
560 | fmrrd%D3\\t%Q0, %R0, %P2 | |
561 | fmrrd%d3\\t%Q0, %R0, %P1 | |
562 | fmrrd%D3\\t%Q0, %R0, %P2\;fmrrd%d3\\t%Q0, %R0, %P1" | |
563 | [(set_attr "conds" "use") | |
564 | (set_attr "length" "4,4,8,4,4,8,4,4,8") | |
392e87f6 AS |
565 | (set_attr "type" "ffarithd,ffarithd,ffarithd,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r") |
566 | (set_attr "neon_type" "neon_vmov,neon_vmov,neon_vmov,neon_mcr_2_mcrr,neon_mcr_2_mcrr,neon_mcr_2_mcrr,neon_mrrc,neon_mrrc,neon_mrrc")] | |
9b66ebb1 PB |
567 | ) |
568 | ||
5b3e6663 PB |
569 | (define_insn "*thumb2_movdfcc_vfp" |
570 | [(set (match_operand:DF 0 "s_register_operand" "=w,w,w,w,w,w,?r,?r,?r") | |
571 | (if_then_else:DF | |
572 | (match_operator 3 "arm_comparison_operator" | |
573 | [(match_operand 4 "cc_register" "") (const_int 0)]) | |
574 | (match_operand:DF 1 "s_register_operand" "0,w,w,0,?r,?r,0,w,w") | |
575 | (match_operand:DF 2 "s_register_operand" "w,0,w,?r,0,?r,w,0,w")))] | |
1572e697 | 576 | "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE && !arm_restrict_it" |
5b3e6663 PB |
577 | "@ |
578 | it\\t%D3\;fcpyd%D3\\t%P0, %P2 | |
579 | it\\t%d3\;fcpyd%d3\\t%P0, %P1 | |
580 | ite\\t%D3\;fcpyd%D3\\t%P0, %P2\;fcpyd%d3\\t%P0, %P1 | |
581 | it\t%D3\;fmdrr%D3\\t%P0, %Q2, %R2 | |
582 | it\t%d3\;fmdrr%d3\\t%P0, %Q1, %R1 | |
583 | ite\\t%D3\;fmdrr%D3\\t%P0, %Q2, %R2\;fmdrr%d3\\t%P0, %Q1, %R1 | |
584 | it\t%D3\;fmrrd%D3\\t%Q0, %R0, %P2 | |
585 | it\t%d3\;fmrrd%d3\\t%Q0, %R0, %P1 | |
586 | ite\\t%D3\;fmrrd%D3\\t%Q0, %R0, %P2\;fmrrd%d3\\t%Q0, %R0, %P1" | |
587 | [(set_attr "conds" "use") | |
588 | (set_attr "length" "6,6,10,6,6,10,6,6,10") | |
392e87f6 AS |
589 | (set_attr "type" "ffarithd,ffarithd,ffarithd,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r") |
590 | (set_attr "neon_type" "neon_vmov,neon_vmov,neon_vmov,neon_mcr_2_mcrr,neon_mcr_2_mcrr,neon_mcr_2_mcrr,neon_mrrc,neon_mrrc,neon_mrrc")] | |
5b3e6663 PB |
591 | ) |
592 | ||
9b66ebb1 PB |
593 | |
594 | ;; Sign manipulation functions | |
595 | ||
596 | (define_insn "*abssf2_vfp" | |
f1adb0a9 JB |
597 | [(set (match_operand:SF 0 "s_register_operand" "=t") |
598 | (abs:SF (match_operand:SF 1 "s_register_operand" "t")))] | |
5b3e6663 | 599 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" |
9b66ebb1 PB |
600 | "fabss%?\\t%0, %1" |
601 | [(set_attr "predicable" "yes") | |
1572e697 | 602 | (set_attr "predicable_short_it" "no") |
51c69ddb | 603 | (set_attr "type" "ffariths")] |
9b66ebb1 PB |
604 | ) |
605 | ||
606 | (define_insn "*absdf2_vfp" | |
607 | [(set (match_operand:DF 0 "s_register_operand" "=w") | |
608 | (abs:DF (match_operand:DF 1 "s_register_operand" "w")))] | |
e0dc3601 | 609 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
9b66ebb1 PB |
610 | "fabsd%?\\t%P0, %P1" |
611 | [(set_attr "predicable" "yes") | |
1572e697 | 612 | (set_attr "predicable_short_it" "no") |
51c69ddb | 613 | (set_attr "type" "ffarithd")] |
9b66ebb1 PB |
614 | ) |
615 | ||
616 | (define_insn "*negsf2_vfp" | |
f1adb0a9 JB |
617 | [(set (match_operand:SF 0 "s_register_operand" "=t,?r") |
618 | (neg:SF (match_operand:SF 1 "s_register_operand" "t,r")))] | |
5b3e6663 | 619 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" |
81632f11 RE |
620 | "@ |
621 | fnegs%?\\t%0, %1 | |
622 | eor%?\\t%0, %1, #-2147483648" | |
9b66ebb1 | 623 | [(set_attr "predicable" "yes") |
1572e697 | 624 | (set_attr "predicable_short_it" "no") |
51c69ddb | 625 | (set_attr "type" "ffariths")] |
9b66ebb1 PB |
626 | ) |
627 | ||
81632f11 RE |
628 | (define_insn_and_split "*negdf2_vfp" |
629 | [(set (match_operand:DF 0 "s_register_operand" "=w,?r,?r") | |
630 | (neg:DF (match_operand:DF 1 "s_register_operand" "w,0,r")))] | |
e0dc3601 | 631 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
81632f11 RE |
632 | "@ |
633 | fnegd%?\\t%P0, %P1 | |
634 | # | |
635 | #" | |
e0dc3601 | 636 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE && reload_completed |
81632f11 RE |
637 | && arm_general_register_operand (operands[0], DFmode)" |
638 | [(set (match_dup 0) (match_dup 1))] | |
639 | " | |
640 | if (REGNO (operands[0]) == REGNO (operands[1])) | |
641 | { | |
642 | operands[0] = gen_highpart (SImode, operands[0]); | |
643 | operands[1] = gen_rtx_XOR (SImode, operands[0], GEN_INT (0x80000000)); | |
644 | } | |
645 | else | |
646 | { | |
647 | rtx in_hi, in_lo, out_hi, out_lo; | |
648 | ||
649 | in_hi = gen_rtx_XOR (SImode, gen_highpart (SImode, operands[1]), | |
650 | GEN_INT (0x80000000)); | |
651 | in_lo = gen_lowpart (SImode, operands[1]); | |
652 | out_hi = gen_highpart (SImode, operands[0]); | |
653 | out_lo = gen_lowpart (SImode, operands[0]); | |
654 | ||
655 | if (REGNO (in_lo) == REGNO (out_hi)) | |
656 | { | |
657 | emit_insn (gen_rtx_SET (SImode, out_lo, in_lo)); | |
658 | operands[0] = out_hi; | |
659 | operands[1] = in_hi; | |
660 | } | |
661 | else | |
662 | { | |
663 | emit_insn (gen_rtx_SET (SImode, out_hi, in_hi)); | |
664 | operands[0] = out_lo; | |
665 | operands[1] = in_lo; | |
666 | } | |
667 | } | |
668 | " | |
9b66ebb1 | 669 | [(set_attr "predicable" "yes") |
1572e697 | 670 | (set_attr "predicable_short_it" "no") |
81632f11 | 671 | (set_attr "length" "4,4,8") |
51c69ddb | 672 | (set_attr "type" "ffarithd")] |
9b66ebb1 PB |
673 | ) |
674 | ||
675 | ||
676 | ;; Arithmetic insns | |
677 | ||
678 | (define_insn "*addsf3_vfp" | |
f1adb0a9 JB |
679 | [(set (match_operand:SF 0 "s_register_operand" "=t") |
680 | (plus:SF (match_operand:SF 1 "s_register_operand" "t") | |
681 | (match_operand:SF 2 "s_register_operand" "t")))] | |
5b3e6663 | 682 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" |
9b66ebb1 PB |
683 | "fadds%?\\t%0, %1, %2" |
684 | [(set_attr "predicable" "yes") | |
1572e697 | 685 | (set_attr "predicable_short_it" "no") |
51c69ddb | 686 | (set_attr "type" "fadds")] |
9b66ebb1 PB |
687 | ) |
688 | ||
689 | (define_insn "*adddf3_vfp" | |
690 | [(set (match_operand:DF 0 "s_register_operand" "=w") | |
691 | (plus:DF (match_operand:DF 1 "s_register_operand" "w") | |
692 | (match_operand:DF 2 "s_register_operand" "w")))] | |
e0dc3601 | 693 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
9b66ebb1 PB |
694 | "faddd%?\\t%P0, %P1, %P2" |
695 | [(set_attr "predicable" "yes") | |
1572e697 | 696 | (set_attr "predicable_short_it" "no") |
51c69ddb | 697 | (set_attr "type" "faddd")] |
9b66ebb1 PB |
698 | ) |
699 | ||
700 | ||
701 | (define_insn "*subsf3_vfp" | |
f1adb0a9 JB |
702 | [(set (match_operand:SF 0 "s_register_operand" "=t") |
703 | (minus:SF (match_operand:SF 1 "s_register_operand" "t") | |
704 | (match_operand:SF 2 "s_register_operand" "t")))] | |
5b3e6663 | 705 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" |
9b66ebb1 PB |
706 | "fsubs%?\\t%0, %1, %2" |
707 | [(set_attr "predicable" "yes") | |
1572e697 | 708 | (set_attr "predicable_short_it" "no") |
51c69ddb | 709 | (set_attr "type" "fadds")] |
9b66ebb1 PB |
710 | ) |
711 | ||
712 | (define_insn "*subdf3_vfp" | |
713 | [(set (match_operand:DF 0 "s_register_operand" "=w") | |
714 | (minus:DF (match_operand:DF 1 "s_register_operand" "w") | |
715 | (match_operand:DF 2 "s_register_operand" "w")))] | |
e0dc3601 | 716 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
9b66ebb1 PB |
717 | "fsubd%?\\t%P0, %P1, %P2" |
718 | [(set_attr "predicable" "yes") | |
1572e697 | 719 | (set_attr "predicable_short_it" "no") |
51c69ddb | 720 | (set_attr "type" "faddd")] |
9b66ebb1 PB |
721 | ) |
722 | ||
723 | ||
724 | ;; Division insns | |
725 | ||
726 | (define_insn "*divsf3_vfp" | |
0498a2be | 727 | [(set (match_operand:SF 0 "s_register_operand" "=t") |
f1adb0a9 JB |
728 | (div:SF (match_operand:SF 1 "s_register_operand" "t") |
729 | (match_operand:SF 2 "s_register_operand" "t")))] | |
5b3e6663 | 730 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" |
9b66ebb1 PB |
731 | "fdivs%?\\t%0, %1, %2" |
732 | [(set_attr "predicable" "yes") | |
1572e697 | 733 | (set_attr "predicable_short_it" "no") |
9b66ebb1 PB |
734 | (set_attr "type" "fdivs")] |
735 | ) | |
736 | ||
737 | (define_insn "*divdf3_vfp" | |
0498a2be | 738 | [(set (match_operand:DF 0 "s_register_operand" "=w") |
9b66ebb1 PB |
739 | (div:DF (match_operand:DF 1 "s_register_operand" "w") |
740 | (match_operand:DF 2 "s_register_operand" "w")))] | |
e0dc3601 | 741 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
9b66ebb1 PB |
742 | "fdivd%?\\t%P0, %P1, %P2" |
743 | [(set_attr "predicable" "yes") | |
1572e697 | 744 | (set_attr "predicable_short_it" "no") |
9b66ebb1 PB |
745 | (set_attr "type" "fdivd")] |
746 | ) | |
747 | ||
748 | ||
749 | ;; Multiplication insns | |
750 | ||
751 | (define_insn "*mulsf3_vfp" | |
0498a2be | 752 | [(set (match_operand:SF 0 "s_register_operand" "=t") |
f1adb0a9 JB |
753 | (mult:SF (match_operand:SF 1 "s_register_operand" "t") |
754 | (match_operand:SF 2 "s_register_operand" "t")))] | |
5b3e6663 | 755 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" |
9b66ebb1 PB |
756 | "fmuls%?\\t%0, %1, %2" |
757 | [(set_attr "predicable" "yes") | |
1572e697 | 758 | (set_attr "predicable_short_it" "no") |
a8e17e9e | 759 | (set_attr "type" "fmuls")] |
9b66ebb1 PB |
760 | ) |
761 | ||
762 | (define_insn "*muldf3_vfp" | |
0498a2be | 763 | [(set (match_operand:DF 0 "s_register_operand" "=w") |
9b66ebb1 PB |
764 | (mult:DF (match_operand:DF 1 "s_register_operand" "w") |
765 | (match_operand:DF 2 "s_register_operand" "w")))] | |
e0dc3601 | 766 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
9b66ebb1 PB |
767 | "fmuld%?\\t%P0, %P1, %P2" |
768 | [(set_attr "predicable" "yes") | |
1572e697 | 769 | (set_attr "predicable_short_it" "no") |
a8e17e9e | 770 | (set_attr "type" "fmuld")] |
9b66ebb1 PB |
771 | ) |
772 | ||
9b66ebb1 | 773 | (define_insn "*mulsf3negsf_vfp" |
0498a2be | 774 | [(set (match_operand:SF 0 "s_register_operand" "=t") |
f1adb0a9 JB |
775 | (mult:SF (neg:SF (match_operand:SF 1 "s_register_operand" "t")) |
776 | (match_operand:SF 2 "s_register_operand" "t")))] | |
5b3e6663 | 777 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" |
9b66ebb1 PB |
778 | "fnmuls%?\\t%0, %1, %2" |
779 | [(set_attr "predicable" "yes") | |
1572e697 | 780 | (set_attr "predicable_short_it" "no") |
a8e17e9e | 781 | (set_attr "type" "fmuls")] |
9b66ebb1 PB |
782 | ) |
783 | ||
784 | (define_insn "*muldf3negdf_vfp" | |
0498a2be | 785 | [(set (match_operand:DF 0 "s_register_operand" "=w") |
9b66ebb1 PB |
786 | (mult:DF (neg:DF (match_operand:DF 1 "s_register_operand" "w")) |
787 | (match_operand:DF 2 "s_register_operand" "w")))] | |
e0dc3601 | 788 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
9b66ebb1 PB |
789 | "fnmuld%?\\t%P0, %P1, %P2" |
790 | [(set_attr "predicable" "yes") | |
1572e697 | 791 | (set_attr "predicable_short_it" "no") |
a8e17e9e | 792 | (set_attr "type" "fmuld")] |
9b66ebb1 PB |
793 | ) |
794 | ||
795 | ||
796 | ;; Multiply-accumulate insns | |
797 | ||
798 | ;; 0 = 1 * 2 + 0 | |
799 | (define_insn "*mulsf3addsf_vfp" | |
f1adb0a9 JB |
800 | [(set (match_operand:SF 0 "s_register_operand" "=t") |
801 | (plus:SF (mult:SF (match_operand:SF 2 "s_register_operand" "t") | |
802 | (match_operand:SF 3 "s_register_operand" "t")) | |
9b66ebb1 | 803 | (match_operand:SF 1 "s_register_operand" "0")))] |
5b3e6663 | 804 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" |
9b66ebb1 PB |
805 | "fmacs%?\\t%0, %2, %3" |
806 | [(set_attr "predicable" "yes") | |
1572e697 | 807 | (set_attr "predicable_short_it" "no") |
a8e17e9e | 808 | (set_attr "type" "fmacs")] |
9b66ebb1 PB |
809 | ) |
810 | ||
811 | (define_insn "*muldf3adddf_vfp" | |
812 | [(set (match_operand:DF 0 "s_register_operand" "=w") | |
813 | (plus:DF (mult:DF (match_operand:DF 2 "s_register_operand" "w") | |
814 | (match_operand:DF 3 "s_register_operand" "w")) | |
815 | (match_operand:DF 1 "s_register_operand" "0")))] | |
e0dc3601 | 816 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
9b66ebb1 PB |
817 | "fmacd%?\\t%P0, %P2, %P3" |
818 | [(set_attr "predicable" "yes") | |
1572e697 | 819 | (set_attr "predicable_short_it" "no") |
a8e17e9e | 820 | (set_attr "type" "fmacd")] |
9b66ebb1 PB |
821 | ) |
822 | ||
823 | ;; 0 = 1 * 2 - 0 | |
824 | (define_insn "*mulsf3subsf_vfp" | |
f1adb0a9 JB |
825 | [(set (match_operand:SF 0 "s_register_operand" "=t") |
826 | (minus:SF (mult:SF (match_operand:SF 2 "s_register_operand" "t") | |
827 | (match_operand:SF 3 "s_register_operand" "t")) | |
9b66ebb1 | 828 | (match_operand:SF 1 "s_register_operand" "0")))] |
5b3e6663 | 829 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" |
9b66ebb1 PB |
830 | "fmscs%?\\t%0, %2, %3" |
831 | [(set_attr "predicable" "yes") | |
1572e697 | 832 | (set_attr "predicable_short_it" "no") |
a8e17e9e | 833 | (set_attr "type" "fmacs")] |
9b66ebb1 PB |
834 | ) |
835 | ||
836 | (define_insn "*muldf3subdf_vfp" | |
837 | [(set (match_operand:DF 0 "s_register_operand" "=w") | |
838 | (minus:DF (mult:DF (match_operand:DF 2 "s_register_operand" "w") | |
839 | (match_operand:DF 3 "s_register_operand" "w")) | |
840 | (match_operand:DF 1 "s_register_operand" "0")))] | |
e0dc3601 | 841 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
9b66ebb1 PB |
842 | "fmscd%?\\t%P0, %P2, %P3" |
843 | [(set_attr "predicable" "yes") | |
1572e697 | 844 | (set_attr "predicable_short_it" "no") |
a8e17e9e | 845 | (set_attr "type" "fmacd")] |
9b66ebb1 PB |
846 | ) |
847 | ||
848 | ;; 0 = -(1 * 2) + 0 | |
849 | (define_insn "*mulsf3negsfaddsf_vfp" | |
f1adb0a9 | 850 | [(set (match_operand:SF 0 "s_register_operand" "=t") |
9b66ebb1 | 851 | (minus:SF (match_operand:SF 1 "s_register_operand" "0") |
f1adb0a9 JB |
852 | (mult:SF (match_operand:SF 2 "s_register_operand" "t") |
853 | (match_operand:SF 3 "s_register_operand" "t"))))] | |
5b3e6663 | 854 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" |
9b66ebb1 PB |
855 | "fnmacs%?\\t%0, %2, %3" |
856 | [(set_attr "predicable" "yes") | |
1572e697 | 857 | (set_attr "predicable_short_it" "no") |
a8e17e9e | 858 | (set_attr "type" "fmacs")] |
9b66ebb1 PB |
859 | ) |
860 | ||
861 | (define_insn "*fmuldf3negdfadddf_vfp" | |
862 | [(set (match_operand:DF 0 "s_register_operand" "=w") | |
863 | (minus:DF (match_operand:DF 1 "s_register_operand" "0") | |
864 | (mult:DF (match_operand:DF 2 "s_register_operand" "w") | |
865 | (match_operand:DF 3 "s_register_operand" "w"))))] | |
e0dc3601 | 866 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
9b66ebb1 PB |
867 | "fnmacd%?\\t%P0, %P2, %P3" |
868 | [(set_attr "predicable" "yes") | |
1572e697 | 869 | (set_attr "predicable_short_it" "no") |
a8e17e9e | 870 | (set_attr "type" "fmacd")] |
9b66ebb1 PB |
871 | ) |
872 | ||
873 | ||
874 | ;; 0 = -(1 * 2) - 0 | |
875 | (define_insn "*mulsf3negsfsubsf_vfp" | |
f1adb0a9 | 876 | [(set (match_operand:SF 0 "s_register_operand" "=t") |
9b66ebb1 | 877 | (minus:SF (mult:SF |
f1adb0a9 JB |
878 | (neg:SF (match_operand:SF 2 "s_register_operand" "t")) |
879 | (match_operand:SF 3 "s_register_operand" "t")) | |
9b66ebb1 | 880 | (match_operand:SF 1 "s_register_operand" "0")))] |
5b3e6663 | 881 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" |
9b66ebb1 PB |
882 | "fnmscs%?\\t%0, %2, %3" |
883 | [(set_attr "predicable" "yes") | |
1572e697 | 884 | (set_attr "predicable_short_it" "no") |
a8e17e9e | 885 | (set_attr "type" "fmacs")] |
9b66ebb1 PB |
886 | ) |
887 | ||
888 | (define_insn "*muldf3negdfsubdf_vfp" | |
889 | [(set (match_operand:DF 0 "s_register_operand" "=w") | |
890 | (minus:DF (mult:DF | |
891 | (neg:DF (match_operand:DF 2 "s_register_operand" "w")) | |
892 | (match_operand:DF 3 "s_register_operand" "w")) | |
893 | (match_operand:DF 1 "s_register_operand" "0")))] | |
e0dc3601 | 894 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
9b66ebb1 PB |
895 | "fnmscd%?\\t%P0, %P2, %P3" |
896 | [(set_attr "predicable" "yes") | |
1572e697 | 897 | (set_attr "predicable_short_it" "no") |
a8e17e9e | 898 | (set_attr "type" "fmacd")] |
9b66ebb1 PB |
899 | ) |
900 | ||
76f722f4 MGD |
901 | ;; Fused-multiply-accumulate |
902 | ||
903 | (define_insn "fma<SDF:mode>4" | |
904 | [(set (match_operand:SDF 0 "register_operand" "=<F_constraint>") | |
905 | (fma:SDF (match_operand:SDF 1 "register_operand" "<F_constraint>") | |
906 | (match_operand:SDF 2 "register_operand" "<F_constraint>") | |
907 | (match_operand:SDF 3 "register_operand" "0")))] | |
908 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FMA" | |
909 | "vfma%?.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2" | |
910 | [(set_attr "predicable" "yes") | |
1572e697 | 911 | (set_attr "predicable_short_it" "no") |
29637783 | 912 | (set_attr "type" "ffma<vfp_type>")] |
76f722f4 MGD |
913 | ) |
914 | ||
915 | (define_insn "*fmsub<SDF:mode>4" | |
916 | [(set (match_operand:SDF 0 "register_operand" "=<F_constraint>") | |
917 | (fma:SDF (neg:SDF (match_operand:SDF 1 "register_operand" | |
918 | "<F_constraint>")) | |
919 | (match_operand:SDF 2 "register_operand" "<F_constraint>") | |
920 | (match_operand:SDF 3 "register_operand" "0")))] | |
921 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FMA" | |
922 | "vfms%?.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2" | |
923 | [(set_attr "predicable" "yes") | |
1572e697 | 924 | (set_attr "predicable_short_it" "no") |
29637783 | 925 | (set_attr "type" "ffma<vfp_type>")] |
76f722f4 MGD |
926 | ) |
927 | ||
928 | (define_insn "*fnmsub<SDF:mode>4" | |
929 | [(set (match_operand:SDF 0 "register_operand" "=<F_constraint>") | |
930 | (fma:SDF (match_operand:SDF 1 "register_operand" "<F_constraint>") | |
931 | (match_operand:SDF 2 "register_operand" "<F_constraint>") | |
932 | (neg:SDF (match_operand:SDF 3 "register_operand" "0"))))] | |
933 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FMA" | |
934 | "vfnms%?.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2" | |
935 | [(set_attr "predicable" "yes") | |
1572e697 | 936 | (set_attr "predicable_short_it" "no") |
29637783 | 937 | (set_attr "type" "ffma<vfp_type>")] |
76f722f4 MGD |
938 | ) |
939 | ||
940 | (define_insn "*fnmadd<SDF:mode>4" | |
941 | [(set (match_operand:SDF 0 "register_operand" "=<F_constraint>") | |
942 | (fma:SDF (neg:SDF (match_operand:SDF 1 "register_operand" | |
943 | "<F_constraint>")) | |
944 | (match_operand:SDF 2 "register_operand" "<F_constraint>") | |
945 | (neg:SDF (match_operand:SDF 3 "register_operand" "0"))))] | |
946 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FMA" | |
947 | "vfnma%?.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2" | |
948 | [(set_attr "predicable" "yes") | |
1572e697 | 949 | (set_attr "predicable_short_it" "no") |
29637783 | 950 | (set_attr "type" "ffma<vfp_type>")] |
76f722f4 MGD |
951 | ) |
952 | ||
9b66ebb1 PB |
953 | |
954 | ;; Conversion routines | |
955 | ||
956 | (define_insn "*extendsfdf2_vfp" | |
957 | [(set (match_operand:DF 0 "s_register_operand" "=w") | |
f1adb0a9 | 958 | (float_extend:DF (match_operand:SF 1 "s_register_operand" "t")))] |
e0dc3601 | 959 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
9b66ebb1 PB |
960 | "fcvtds%?\\t%P0, %1" |
961 | [(set_attr "predicable" "yes") | |
1572e697 | 962 | (set_attr "predicable_short_it" "no") |
75fe7b2f | 963 | (set_attr "type" "f_cvt")] |
9b66ebb1 PB |
964 | ) |
965 | ||
966 | (define_insn "*truncdfsf2_vfp" | |
f1adb0a9 | 967 | [(set (match_operand:SF 0 "s_register_operand" "=t") |
9b66ebb1 | 968 | (float_truncate:SF (match_operand:DF 1 "s_register_operand" "w")))] |
e0dc3601 | 969 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
9b66ebb1 PB |
970 | "fcvtsd%?\\t%0, %P1" |
971 | [(set_attr "predicable" "yes") | |
1572e697 | 972 | (set_attr "predicable_short_it" "no") |
75fe7b2f | 973 | (set_attr "type" "f_cvt")] |
9b66ebb1 PB |
974 | ) |
975 | ||
0fd8c3ad SL |
976 | (define_insn "extendhfsf2" |
977 | [(set (match_operand:SF 0 "s_register_operand" "=t") | |
978 | (float_extend:SF (match_operand:HF 1 "s_register_operand" "t")))] | |
e0dc3601 | 979 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FP16" |
0fd8c3ad SL |
980 | "vcvtb%?.f32.f16\\t%0, %1" |
981 | [(set_attr "predicable" "yes") | |
1572e697 | 982 | (set_attr "predicable_short_it" "no") |
0fd8c3ad SL |
983 | (set_attr "type" "f_cvt")] |
984 | ) | |
985 | ||
986 | (define_insn "truncsfhf2" | |
987 | [(set (match_operand:HF 0 "s_register_operand" "=t") | |
988 | (float_truncate:HF (match_operand:SF 1 "s_register_operand" "t")))] | |
e0dc3601 | 989 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FP16" |
0fd8c3ad SL |
990 | "vcvtb%?.f16.f32\\t%0, %1" |
991 | [(set_attr "predicable" "yes") | |
1572e697 | 992 | (set_attr "predicable_short_it" "no") |
0fd8c3ad SL |
993 | (set_attr "type" "f_cvt")] |
994 | ) | |
995 | ||
9b66ebb1 | 996 | (define_insn "*truncsisf2_vfp" |
f1adb0a9 JB |
997 | [(set (match_operand:SI 0 "s_register_operand" "=t") |
998 | (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" "t"))))] | |
5b3e6663 | 999 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" |
9b66ebb1 PB |
1000 | "ftosizs%?\\t%0, %1" |
1001 | [(set_attr "predicable" "yes") | |
1572e697 | 1002 | (set_attr "predicable_short_it" "no") |
75fe7b2f | 1003 | (set_attr "type" "f_cvt")] |
9b66ebb1 PB |
1004 | ) |
1005 | ||
1006 | (define_insn "*truncsidf2_vfp" | |
f1adb0a9 | 1007 | [(set (match_operand:SI 0 "s_register_operand" "=t") |
9b66ebb1 | 1008 | (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" "w"))))] |
e0dc3601 | 1009 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
9b66ebb1 PB |
1010 | "ftosizd%?\\t%0, %P1" |
1011 | [(set_attr "predicable" "yes") | |
1572e697 | 1012 | (set_attr "predicable_short_it" "no") |
75fe7b2f | 1013 | (set_attr "type" "f_cvt")] |
9b66ebb1 PB |
1014 | ) |
1015 | ||
6f6c1f6d PB |
1016 | |
1017 | (define_insn "fixuns_truncsfsi2" | |
f1adb0a9 JB |
1018 | [(set (match_operand:SI 0 "s_register_operand" "=t") |
1019 | (unsigned_fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" "t"))))] | |
5b3e6663 | 1020 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" |
6f6c1f6d PB |
1021 | "ftouizs%?\\t%0, %1" |
1022 | [(set_attr "predicable" "yes") | |
1572e697 | 1023 | (set_attr "predicable_short_it" "no") |
75fe7b2f | 1024 | (set_attr "type" "f_cvt")] |
6f6c1f6d PB |
1025 | ) |
1026 | ||
1027 | (define_insn "fixuns_truncdfsi2" | |
f1adb0a9 JB |
1028 | [(set (match_operand:SI 0 "s_register_operand" "=t") |
1029 | (unsigned_fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" "t"))))] | |
e0dc3601 | 1030 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
6f6c1f6d PB |
1031 | "ftouizd%?\\t%0, %P1" |
1032 | [(set_attr "predicable" "yes") | |
1572e697 | 1033 | (set_attr "predicable_short_it" "no") |
75fe7b2f | 1034 | (set_attr "type" "f_cvt")] |
6f6c1f6d PB |
1035 | ) |
1036 | ||
1037 | ||
9b66ebb1 | 1038 | (define_insn "*floatsisf2_vfp" |
f1adb0a9 JB |
1039 | [(set (match_operand:SF 0 "s_register_operand" "=t") |
1040 | (float:SF (match_operand:SI 1 "s_register_operand" "t")))] | |
5b3e6663 | 1041 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" |
9b66ebb1 PB |
1042 | "fsitos%?\\t%0, %1" |
1043 | [(set_attr "predicable" "yes") | |
1572e697 | 1044 | (set_attr "predicable_short_it" "no") |
75fe7b2f | 1045 | (set_attr "type" "f_cvt")] |
9b66ebb1 PB |
1046 | ) |
1047 | ||
1048 | (define_insn "*floatsidf2_vfp" | |
1049 | [(set (match_operand:DF 0 "s_register_operand" "=w") | |
f1adb0a9 | 1050 | (float:DF (match_operand:SI 1 "s_register_operand" "t")))] |
e0dc3601 | 1051 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
9b66ebb1 PB |
1052 | "fsitod%?\\t%P0, %1" |
1053 | [(set_attr "predicable" "yes") | |
1572e697 | 1054 | (set_attr "predicable_short_it" "no") |
75fe7b2f | 1055 | (set_attr "type" "f_cvt")] |
9b66ebb1 PB |
1056 | ) |
1057 | ||
1058 | ||
6f6c1f6d | 1059 | (define_insn "floatunssisf2" |
f1adb0a9 JB |
1060 | [(set (match_operand:SF 0 "s_register_operand" "=t") |
1061 | (unsigned_float:SF (match_operand:SI 1 "s_register_operand" "t")))] | |
5b3e6663 | 1062 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" |
6f6c1f6d PB |
1063 | "fuitos%?\\t%0, %1" |
1064 | [(set_attr "predicable" "yes") | |
1572e697 | 1065 | (set_attr "predicable_short_it" "no") |
75fe7b2f | 1066 | (set_attr "type" "f_cvt")] |
6f6c1f6d PB |
1067 | ) |
1068 | ||
1069 | (define_insn "floatunssidf2" | |
1070 | [(set (match_operand:DF 0 "s_register_operand" "=w") | |
f1adb0a9 | 1071 | (unsigned_float:DF (match_operand:SI 1 "s_register_operand" "t")))] |
e0dc3601 | 1072 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
6f6c1f6d PB |
1073 | "fuitod%?\\t%P0, %1" |
1074 | [(set_attr "predicable" "yes") | |
1572e697 | 1075 | (set_attr "predicable_short_it" "no") |
75fe7b2f | 1076 | (set_attr "type" "f_cvt")] |
6f6c1f6d PB |
1077 | ) |
1078 | ||
1079 | ||
9b66ebb1 PB |
1080 | ;; Sqrt insns. |
1081 | ||
1082 | (define_insn "*sqrtsf2_vfp" | |
f1adb0a9 JB |
1083 | [(set (match_operand:SF 0 "s_register_operand" "=t") |
1084 | (sqrt:SF (match_operand:SF 1 "s_register_operand" "t")))] | |
5b3e6663 | 1085 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" |
9b66ebb1 PB |
1086 | "fsqrts%?\\t%0, %1" |
1087 | [(set_attr "predicable" "yes") | |
1572e697 | 1088 | (set_attr "predicable_short_it" "no") |
9b66ebb1 PB |
1089 | (set_attr "type" "fdivs")] |
1090 | ) | |
1091 | ||
1092 | (define_insn "*sqrtdf2_vfp" | |
1093 | [(set (match_operand:DF 0 "s_register_operand" "=w") | |
1094 | (sqrt:DF (match_operand:DF 1 "s_register_operand" "w")))] | |
e0dc3601 | 1095 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
9b66ebb1 PB |
1096 | "fsqrtd%?\\t%P0, %P1" |
1097 | [(set_attr "predicable" "yes") | |
1572e697 | 1098 | (set_attr "predicable_short_it" "no") |
9b66ebb1 PB |
1099 | (set_attr "type" "fdivd")] |
1100 | ) | |
1101 | ||
1102 | ||
1103 | ;; Patterns to split/copy vfp condition flags. | |
1104 | ||
1105 | (define_insn "*movcc_vfp" | |
1106 | [(set (reg CC_REGNUM) | |
1107 | (reg VFPCC_REGNUM))] | |
5b3e6663 | 1108 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" |
9b66ebb1 PB |
1109 | "fmstat%?" |
1110 | [(set_attr "conds" "set") | |
75fe7b2f | 1111 | (set_attr "type" "f_flag")] |
9b66ebb1 PB |
1112 | ) |
1113 | ||
1114 | (define_insn_and_split "*cmpsf_split_vfp" | |
1115 | [(set (reg:CCFP CC_REGNUM) | |
f1adb0a9 JB |
1116 | (compare:CCFP (match_operand:SF 0 "s_register_operand" "t") |
1117 | (match_operand:SF 1 "vfp_compare_operand" "tG")))] | |
5b3e6663 | 1118 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" |
9b66ebb1 | 1119 | "#" |
5b3e6663 | 1120 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" |
9b66ebb1 PB |
1121 | [(set (reg:CCFP VFPCC_REGNUM) |
1122 | (compare:CCFP (match_dup 0) | |
1123 | (match_dup 1))) | |
1124 | (set (reg:CCFP CC_REGNUM) | |
1125 | (reg:CCFP VFPCC_REGNUM))] | |
1126 | "" | |
1127 | ) | |
1128 | ||
1129 | (define_insn_and_split "*cmpsf_trap_split_vfp" | |
1130 | [(set (reg:CCFPE CC_REGNUM) | |
f1adb0a9 JB |
1131 | (compare:CCFPE (match_operand:SF 0 "s_register_operand" "t") |
1132 | (match_operand:SF 1 "vfp_compare_operand" "tG")))] | |
5b3e6663 | 1133 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" |
9b66ebb1 | 1134 | "#" |
5b3e6663 | 1135 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" |
9b66ebb1 PB |
1136 | [(set (reg:CCFPE VFPCC_REGNUM) |
1137 | (compare:CCFPE (match_dup 0) | |
1138 | (match_dup 1))) | |
1139 | (set (reg:CCFPE CC_REGNUM) | |
1140 | (reg:CCFPE VFPCC_REGNUM))] | |
1141 | "" | |
1142 | ) | |
1143 | ||
1144 | (define_insn_and_split "*cmpdf_split_vfp" | |
1145 | [(set (reg:CCFP CC_REGNUM) | |
1146 | (compare:CCFP (match_operand:DF 0 "s_register_operand" "w") | |
1147 | (match_operand:DF 1 "vfp_compare_operand" "wG")))] | |
e0dc3601 | 1148 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
9b66ebb1 | 1149 | "#" |
e0dc3601 | 1150 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
9b66ebb1 PB |
1151 | [(set (reg:CCFP VFPCC_REGNUM) |
1152 | (compare:CCFP (match_dup 0) | |
1153 | (match_dup 1))) | |
1154 | (set (reg:CCFP CC_REGNUM) | |
510bc854 | 1155 | (reg:CCFP VFPCC_REGNUM))] |
9b66ebb1 PB |
1156 | "" |
1157 | ) | |
1158 | ||
1159 | (define_insn_and_split "*cmpdf_trap_split_vfp" | |
1160 | [(set (reg:CCFPE CC_REGNUM) | |
1161 | (compare:CCFPE (match_operand:DF 0 "s_register_operand" "w") | |
1162 | (match_operand:DF 1 "vfp_compare_operand" "wG")))] | |
e0dc3601 | 1163 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
9b66ebb1 | 1164 | "#" |
e0dc3601 | 1165 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
9b66ebb1 PB |
1166 | [(set (reg:CCFPE VFPCC_REGNUM) |
1167 | (compare:CCFPE (match_dup 0) | |
1168 | (match_dup 1))) | |
1169 | (set (reg:CCFPE CC_REGNUM) | |
1170 | (reg:CCFPE VFPCC_REGNUM))] | |
1171 | "" | |
1172 | ) | |
1173 | ||
1174 | ||
1175 | ;; Comparison patterns | |
1176 | ||
1177 | (define_insn "*cmpsf_vfp" | |
1178 | [(set (reg:CCFP VFPCC_REGNUM) | |
f1adb0a9 JB |
1179 | (compare:CCFP (match_operand:SF 0 "s_register_operand" "t,t") |
1180 | (match_operand:SF 1 "vfp_compare_operand" "t,G")))] | |
5b3e6663 | 1181 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" |
9b66ebb1 PB |
1182 | "@ |
1183 | fcmps%?\\t%0, %1 | |
1184 | fcmpzs%?\\t%0" | |
1185 | [(set_attr "predicable" "yes") | |
1572e697 | 1186 | (set_attr "predicable_short_it" "no") |
51c69ddb | 1187 | (set_attr "type" "fcmps")] |
9b66ebb1 PB |
1188 | ) |
1189 | ||
1190 | (define_insn "*cmpsf_trap_vfp" | |
1191 | [(set (reg:CCFPE VFPCC_REGNUM) | |
f1adb0a9 JB |
1192 | (compare:CCFPE (match_operand:SF 0 "s_register_operand" "t,t") |
1193 | (match_operand:SF 1 "vfp_compare_operand" "t,G")))] | |
5b3e6663 | 1194 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" |
9b66ebb1 PB |
1195 | "@ |
1196 | fcmpes%?\\t%0, %1 | |
1197 | fcmpezs%?\\t%0" | |
1198 | [(set_attr "predicable" "yes") | |
1572e697 | 1199 | (set_attr "predicable_short_it" "no") |
7dd8ecf0 | 1200 | (set_attr "type" "fcmps")] |
9b66ebb1 PB |
1201 | ) |
1202 | ||
1203 | (define_insn "*cmpdf_vfp" | |
1204 | [(set (reg:CCFP VFPCC_REGNUM) | |
1205 | (compare:CCFP (match_operand:DF 0 "s_register_operand" "w,w") | |
1206 | (match_operand:DF 1 "vfp_compare_operand" "w,G")))] | |
e0dc3601 | 1207 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
9b66ebb1 PB |
1208 | "@ |
1209 | fcmpd%?\\t%P0, %P1 | |
1210 | fcmpzd%?\\t%P0" | |
1211 | [(set_attr "predicable" "yes") | |
1572e697 | 1212 | (set_attr "predicable_short_it" "no") |
51c69ddb | 1213 | (set_attr "type" "fcmpd")] |
9b66ebb1 PB |
1214 | ) |
1215 | ||
1216 | (define_insn "*cmpdf_trap_vfp" | |
1217 | [(set (reg:CCFPE VFPCC_REGNUM) | |
1218 | (compare:CCFPE (match_operand:DF 0 "s_register_operand" "w,w") | |
1219 | (match_operand:DF 1 "vfp_compare_operand" "w,G")))] | |
e0dc3601 | 1220 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" |
9b66ebb1 PB |
1221 | "@ |
1222 | fcmped%?\\t%P0, %P1 | |
1223 | fcmpezd%?\\t%P0" | |
1224 | [(set_attr "predicable" "yes") | |
1572e697 | 1225 | (set_attr "predicable_short_it" "no") |
51c69ddb | 1226 | (set_attr "type" "fcmpd")] |
9b66ebb1 PB |
1227 | ) |
1228 | ||
7f3d8f56 RR |
1229 | ;; Fixed point to floating point conversions. |
1230 | (define_code_iterator FCVT [unsigned_float float]) | |
1231 | (define_code_attr FCVTI32typename [(unsigned_float "u32") (float "s32")]) | |
1232 | ||
1233 | (define_insn "*combine_vcvt_f32_<FCVTI32typename>" | |
1234 | [(set (match_operand:SF 0 "s_register_operand" "=t") | |
1235 | (mult:SF (FCVT:SF (match_operand:SI 1 "s_register_operand" "0")) | |
1236 | (match_operand 2 | |
1237 | "const_double_vcvt_power_of_two_reciprocal" "Dt")))] | |
1238 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP3 && !flag_rounding_math" | |
1239 | "vcvt.f32.<FCVTI32typename>\\t%0, %1, %v2" | |
1240 | [(set_attr "predicable" "no") | |
1241 | (set_attr "type" "f_cvt")] | |
1242 | ) | |
9b66ebb1 | 1243 | |
7f3d8f56 RR |
1244 | ;; Not the ideal way of implementing this. Ideally we would be able to split |
1245 | ;; this into a move to a DP register and then a vcvt.f64.i32 | |
1246 | (define_insn "*combine_vcvt_f64_<FCVTI32typename>" | |
1247 | [(set (match_operand:DF 0 "s_register_operand" "=x,x,w") | |
1248 | (mult:DF (FCVT:DF (match_operand:SI 1 "s_register_operand" "r,t,r")) | |
1249 | (match_operand 2 | |
1250 | "const_double_vcvt_power_of_two_reciprocal" "Dt,Dt,Dt")))] | |
1251 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP3 && !flag_rounding_math | |
1252 | && !TARGET_VFP_SINGLE" | |
1253 | "@ | |
1254 | vmov.f32\\t%0, %1\;vcvt.f64.<FCVTI32typename>\\t%P0, %P0, %v2 | |
1255 | vmov.f32\\t%0, %1\;vcvt.f64.<FCVTI32typename>\\t%P0, %P0, %v2 | |
6184a33d | 1256 | vmov.f64\\t%P0, %1, %1\;vcvt.f64.<FCVTI32typename>\\t%P0, %P0, %v2" |
7f3d8f56 RR |
1257 | [(set_attr "predicable" "no") |
1258 | (set_attr "type" "f_cvt") | |
1259 | (set_attr "length" "8")] | |
1260 | ) | |
9b66ebb1 | 1261 | |
7f3d8f56 | 1262 | ;; Store multiple insn used in function prologue. |
9b66ebb1 PB |
1263 | (define_insn "*push_multi_vfp" |
1264 | [(match_parallel 2 "multi_register_push" | |
1265 | [(set (match_operand:BLK 0 "memory_operand" "=m") | |
4e6f5666 | 1266 | (unspec:BLK [(match_operand:DF 1 "vfp_register_operand" "")] |
9b66ebb1 | 1267 | UNSPEC_PUSH_MULT))])] |
5b3e6663 | 1268 | "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP" |
8edfc4cc | 1269 | "* return vfp_output_fstmd (operands);" |
75fe7b2f | 1270 | [(set_attr "type" "f_stored")] |
9b66ebb1 PB |
1271 | ) |
1272 | ||
1dd4fe1f KT |
1273 | ;; VRINT round to integral instructions. |
1274 | ;; Invoked for the patterns: btruncsf2, btruncdf2, ceilsf2, ceildf2, | |
1275 | ;; roundsf2, rounddf2, floorsf2, floordf2, nearbyintsf2, nearbyintdf2, | |
1276 | ;; rintsf2, rintdf2. | |
1277 | (define_insn "<vrint_pattern><SDF:mode>2" | |
1278 | [(set (match_operand:SDF 0 "register_operand" "=<F_constraint>") | |
1279 | (unspec:SDF [(match_operand:SDF 1 | |
1280 | "register_operand" "<F_constraint>")] | |
1281 | VRINT))] | |
1282 | "TARGET_HARD_FLOAT && TARGET_FPU_ARMV8 <vfp_double_cond>" | |
1283 | "vrint<vrint_variant>%?.<V_if_elem>\\t%<V_reg>0, %<V_reg>1" | |
1284 | [(set_attr "predicable" "<vrint_predicable>") | |
1572e697 | 1285 | (set_attr "predicable_short_it" "no") |
1dd4fe1f KT |
1286 | (set_attr "type" "f_rint<vfp_type>")] |
1287 | ) | |
9b66ebb1 | 1288 | |
37202071 KT |
1289 | ;; MIN_EXPR and MAX_EXPR eventually map to 'smin' and 'smax' in RTL. |
1290 | ;; The 'smax' and 'smin' RTL standard pattern names do not specify which | |
1291 | ;; operand will be returned when both operands are zero (i.e. they may not | |
1292 | ;; honour signed zeroes), or when either operand is NaN. Therefore GCC | |
1293 | ;; only introduces MIN_EXPR/MAX_EXPR in fast math mode or when not honouring | |
1294 | ;; NaNs. | |
1295 | ||
1296 | (define_insn "smax<mode>3" | |
1297 | [(set (match_operand:SDF 0 "register_operand" "=<F_constraint>") | |
1298 | (smax:SDF (match_operand:SDF 1 "register_operand" "<F_constraint>") | |
1299 | (match_operand:SDF 2 "register_operand" "<F_constraint>")))] | |
1300 | "TARGET_HARD_FLOAT && TARGET_FPU_ARMV8 <vfp_double_cond>" | |
1301 | "vmaxnm.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2" | |
1302 | [(set_attr "type" "f_minmax<vfp_type>")] | |
1303 | ) | |
1304 | ||
1305 | (define_insn "smin<mode>3" | |
1306 | [(set (match_operand:SDF 0 "register_operand" "=<F_constraint>") | |
1307 | (smin:SDF (match_operand:SDF 1 "register_operand" "<F_constraint>") | |
1308 | (match_operand:SDF 2 "register_operand" "<F_constraint>")))] | |
1309 | "TARGET_HARD_FLOAT && TARGET_FPU_ARMV8 <vfp_double_cond>" | |
1310 | "vminnm.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2" | |
1311 | [(set_attr "type" "f_minmax<vfp_type>")] | |
1312 | ) | |
1313 | ||
9b66ebb1 PB |
1314 | ;; Unimplemented insns: |
1315 | ;; fldm* | |
1316 | ;; fstm* | |
1317 | ;; fmdhr et al (VFPv1) | |
59b9a953 | 1318 | ;; Support for xD (single precision only) variants. |
9b66ebb1 | 1319 | ;; fmrrs, fmsrr |