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