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