vfp.md: Document fmul{s,d} and fmac{s,d} types.
[gcc.git] / gcc / config / arm / vfp.md
1 ;; ARM VFP instruction patterns
2 ;; Copyright (C) 2003, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
3 ;; Written by CodeSourcery.
4 ;;
5 ;; This file is part of GCC.
6 ;;
7 ;; GCC is free software; you can redistribute it and/or modify it
8 ;; under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 3, or (at your option)
10 ;; any later version.
11 ;;
12 ;; GCC is distributed in the hope that it will be useful, but
13 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 ;; General Public License for more details.
16 ;;
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3. If not see
19 ;; <http://www.gnu.org/licenses/>. */
20
21 ;; Additional register numbers
22 (define_constants
23 [(VFPCC_REGNUM 127)]
24 )
25
26 ;; The VFP "type" attributes differ from those used in the FPA model.
27 ;; ffarith Fast floating point insns, e.g. abs, neg, cpy, cmp.
28 ;; farith Most arithmetic insns.
29 ;; fmuls Single precision multiply.
30 ;; fmuld Double precision multiply.
31 ;; fmacs Single precision multiply-accumulate.
32 ;; fmacd Double precision multiply-accumulate.
33 ;; fdivs Single precision sqrt or division.
34 ;; fdivd Double precision sqrt or division.
35 ;; f_flag fmstat operation
36 ;; f_load[sd] Floating point load from memory.
37 ;; f_store[sd] Floating point store to memory.
38 ;; f_2_r Transfer vfp to arm reg.
39 ;; r_2_f Transfer arm to vfp reg.
40 ;; f_cvt Convert floating<->integral
41
42 ;; SImode moves
43 ;; ??? For now do not allow loading constants into vfp regs. This causes
44 ;; problems because small constants get converted into adds.
45 (define_insn "*arm_movsi_vfp"
46 [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m ,*t,r,*t,*t, *Uv")
47 (match_operand:SI 1 "general_operand" "rk, I,K,N,mi,rk,r,*t,*t,*Uvi,*t"))]
48 "TARGET_ARM && TARGET_VFP && TARGET_HARD_FLOAT
49 && ( s_register_operand (operands[0], SImode)
50 || s_register_operand (operands[1], SImode))"
51 "*
52 switch (which_alternative)
53 {
54 case 0: case 1:
55 return \"mov%?\\t%0, %1\";
56 case 2:
57 return \"mvn%?\\t%0, #%B1\";
58 case 3:
59 return \"movw%?\\t%0, %1\";
60 case 4:
61 return \"ldr%?\\t%0, %1\";
62 case 5:
63 return \"str%?\\t%1, %0\";
64 case 6:
65 return \"fmsr%?\\t%0, %1\\t%@ int\";
66 case 7:
67 return \"fmrs%?\\t%0, %1\\t%@ int\";
68 case 8:
69 return \"fcpys%?\\t%0, %1\\t%@ int\";
70 case 9: case 10:
71 return output_move_vfp (operands);
72 default:
73 gcc_unreachable ();
74 }
75 "
76 [(set_attr "predicable" "yes")
77 (set_attr "type" "*,*,*,*,load1,store1,r_2_f,f_2_r,ffarith,f_loads,f_stores")
78 (set_attr "pool_range" "*,*,*,*,4096,*,*,*,*,1020,*")
79 (set_attr "neg_pool_range" "*,*,*,*,4084,*,*,*,*,1008,*")]
80 )
81
82 (define_insn "*thumb2_movsi_vfp"
83 [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m,*t,r, *t,*t, *Uv")
84 (match_operand:SI 1 "general_operand" "rk, I,K,N,mi,rk,r,*t,*t,*Uvi,*t"))]
85 "TARGET_THUMB2 && TARGET_VFP && TARGET_HARD_FLOAT
86 && ( s_register_operand (operands[0], SImode)
87 || s_register_operand (operands[1], SImode))"
88 "*
89 switch (which_alternative)
90 {
91 case 0: case 1:
92 return \"mov%?\\t%0, %1\";
93 case 2:
94 return \"mvn%?\\t%0, #%B1\";
95 case 3:
96 return \"movw%?\\t%0, %1\";
97 case 4:
98 return \"ldr%?\\t%0, %1\";
99 case 5:
100 return \"str%?\\t%1, %0\";
101 case 6:
102 return \"fmsr%?\\t%0, %1\\t%@ int\";
103 case 7:
104 return \"fmrs%?\\t%0, %1\\t%@ int\";
105 case 8:
106 return \"fcpys%?\\t%0, %1\\t%@ int\";
107 case 9: case 10:
108 return output_move_vfp (operands);
109 default:
110 gcc_unreachable ();
111 }
112 "
113 [(set_attr "predicable" "yes")
114 (set_attr "type" "*,*,*,*,load1,store1,r_2_f,f_2_r,ffarith,f_load,f_store")
115 (set_attr "pool_range" "*,*,*,*,4096,*,*,*,*,1020,*")
116 (set_attr "neg_pool_range" "*,*,*,*, 0,*,*,*,*,1008,*")]
117 )
118
119
120 ;; DImode moves
121
122 (define_insn "*arm_movdi_vfp"
123 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r,m,w,r,w,w, Uv")
124 (match_operand:DI 1 "di_operand" "rIK,mi,r,r,w,w,Uvi,w"))]
125 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP
126 && ( register_operand (operands[0], DImode)
127 || register_operand (operands[1], DImode))"
128 "*
129 switch (which_alternative)
130 {
131 case 0:
132 return \"#\";
133 case 1:
134 case 2:
135 return output_move_double (operands);
136 case 3:
137 return \"fmdrr%?\\t%P0, %Q1, %R1\\t%@ int\";
138 case 4:
139 return \"fmrrd%?\\t%Q0, %R0, %P1\\t%@ int\";
140 case 5:
141 return \"fcpyd%?\\t%P0, %P1\\t%@ int\";
142 case 6: case 7:
143 return output_move_vfp (operands);
144 default:
145 gcc_unreachable ();
146 }
147 "
148 [(set_attr "type" "*,load2,store2,r_2_f,f_2_r,ffarith,f_loadd,f_stored")
149 (set_attr "length" "8,8,8,4,4,4,4,4")
150 (set_attr "pool_range" "*,1020,*,*,*,*,1020,*")
151 (set_attr "neg_pool_range" "*,1008,*,*,*,*,1008,*")]
152 )
153
154 (define_insn "*thumb2_movdi_vfp"
155 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r,m,w,r,w,w, Uv")
156 (match_operand:DI 1 "di_operand" "rIK,mi,r,r,w,w,Uvi,w"))]
157 "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_VFP"
158 "*
159 switch (which_alternative)
160 {
161 case 0: case 1: case 2:
162 return (output_move_double (operands));
163 case 3:
164 return \"fmdrr%?\\t%P0, %Q1, %R1\\t%@ int\";
165 case 4:
166 return \"fmrrd%?\\t%Q0, %R0, %P1\\t%@ int\";
167 case 5:
168 return \"fcpyd%?\\t%P0, %P1\\t%@ int\";
169 case 6: case 7:
170 return output_move_vfp (operands);
171 default:
172 abort ();
173 }
174 "
175 [(set_attr "type" "*,load2,store2,r_2_f,f_2_r,ffarith,f_load,f_store")
176 (set_attr "length" "8,8,8,4,4,4,4,4")
177 (set_attr "pool_range" "*,4096,*,*,*,*,1020,*")
178 (set_attr "neg_pool_range" "*, 0,*,*,*,*,1008,*")]
179 )
180
181
182 ;; SFmode moves
183 ;; Disparage the w<->r cases because reloading an invalid address is
184 ;; preferable to loading the value via integer registers.
185
186 (define_insn "*movsf_vfp"
187 [(set (match_operand:SF 0 "nonimmediate_operand" "=t,?r,t ,t ,Uv,r ,m,t,r")
188 (match_operand:SF 1 "general_operand" " ?r,t,Dv,UvE,t, mE,r,t,r"))]
189 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP
190 && ( s_register_operand (operands[0], SFmode)
191 || s_register_operand (operands[1], SFmode))"
192 "*
193 switch (which_alternative)
194 {
195 case 0:
196 return \"fmsr%?\\t%0, %1\";
197 case 1:
198 return \"fmrs%?\\t%0, %1\";
199 case 2:
200 return \"fconsts%?\\t%0, #%G1\";
201 case 3: case 4:
202 return output_move_vfp (operands);
203 case 5:
204 return \"ldr%?\\t%0, %1\\t%@ float\";
205 case 6:
206 return \"str%?\\t%1, %0\\t%@ float\";
207 case 7:
208 return \"fcpys%?\\t%0, %1\";
209 case 8:
210 return \"mov%?\\t%0, %1\\t%@ float\";
211 default:
212 gcc_unreachable ();
213 }
214 "
215 [(set_attr "predicable" "yes")
216 (set_attr "type"
217 "r_2_f,f_2_r,farith,f_loads,f_stores,load1,store1,ffarith,*")
218 (set_attr "pool_range" "*,*,*,1020,*,4096,*,*,*")
219 (set_attr "neg_pool_range" "*,*,*,1008,*,4080,*,*,*")]
220 )
221
222 (define_insn "*thumb2_movsf_vfp"
223 [(set (match_operand:SF 0 "nonimmediate_operand" "=t,?r,t, t ,Uv,r ,m,t,r")
224 (match_operand:SF 1 "general_operand" " ?r,t,Dv,UvE,t, mE,r,t,r"))]
225 "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_VFP
226 && ( s_register_operand (operands[0], SFmode)
227 || s_register_operand (operands[1], SFmode))"
228 "*
229 switch (which_alternative)
230 {
231 case 0:
232 return \"fmsr%?\\t%0, %1\";
233 case 1:
234 return \"fmrs%?\\t%0, %1\";
235 case 2:
236 return \"fconsts%?\\t%0, #%G1\";
237 case 3: case 4:
238 return output_move_vfp (operands);
239 case 5:
240 return \"ldr%?\\t%0, %1\\t%@ float\";
241 case 6:
242 return \"str%?\\t%1, %0\\t%@ float\";
243 case 7:
244 return \"fcpys%?\\t%0, %1\";
245 case 8:
246 return \"mov%?\\t%0, %1\\t%@ float\";
247 default:
248 gcc_unreachable ();
249 }
250 "
251 [(set_attr "predicable" "yes")
252 (set_attr "type"
253 "r_2_f,f_2_r,farith,f_load,f_store,load1,store1,ffarith,*")
254 (set_attr "pool_range" "*,*,*,1020,*,4092,*,*,*")
255 (set_attr "neg_pool_range" "*,*,*,1008,*,0,*,*,*")]
256 )
257
258
259 ;; DFmode moves
260
261 (define_insn "*movdf_vfp"
262 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=w,?r,w ,r, m,w ,Uv,w,r")
263 (match_operand:DF 1 "soft_df_operand" " ?r,w,Dv,mF,r,UvF,w, w,r"))]
264 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP
265 && ( register_operand (operands[0], DFmode)
266 || register_operand (operands[1], DFmode))"
267 "*
268 {
269 switch (which_alternative)
270 {
271 case 0:
272 return \"fmdrr%?\\t%P0, %Q1, %R1\";
273 case 1:
274 return \"fmrrd%?\\t%Q0, %R0, %P1\";
275 case 2:
276 return \"fconstd%?\\t%P0, #%G1\";
277 case 3: case 4:
278 return output_move_double (operands);
279 case 5: case 6:
280 return output_move_vfp (operands);
281 case 7:
282 return \"fcpyd%?\\t%P0, %P1\";
283 case 8:
284 return \"#\";
285 default:
286 gcc_unreachable ();
287 }
288 }
289 "
290 [(set_attr "type"
291 "r_2_f,f_2_r,farith,f_loadd,f_stored,load2,store2,ffarith,*")
292 (set_attr "length" "4,4,4,8,8,4,4,4,8")
293 (set_attr "pool_range" "*,*,*,1020,*,1020,*,*,*")
294 (set_attr "neg_pool_range" "*,*,*,1008,*,1008,*,*,*")]
295 )
296
297 (define_insn "*thumb2_movdf_vfp"
298 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=w,?r,w ,r, m,w ,Uv,w,r")
299 (match_operand:DF 1 "soft_df_operand" " ?r,w,Dv,mF,r,UvF,w, w,r"))]
300 "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_VFP"
301 "*
302 {
303 switch (which_alternative)
304 {
305 case 0:
306 return \"fmdrr%?\\t%P0, %Q1, %R1\";
307 case 1:
308 return \"fmrrd%?\\t%Q0, %R0, %P1\";
309 case 2:
310 return \"fconstd%?\\t%P0, #%G1\";
311 case 3: case 4: case 8:
312 return output_move_double (operands);
313 case 5: case 6:
314 return output_move_vfp (operands);
315 case 7:
316 return \"fcpyd%?\\t%P0, %P1\";
317 default:
318 abort ();
319 }
320 }
321 "
322 [(set_attr "type"
323 "r_2_f,f_2_r,farith,load2,store2,f_load,f_store,ffarith,*")
324 (set_attr "length" "4,4,4,8,8,4,4,4,8")
325 (set_attr "pool_range" "*,*,*,4096,*,1020,*,*,*")
326 (set_attr "neg_pool_range" "*,*,*,0,*,1008,*,*,*")]
327 )
328
329
330 ;; Conditional move patterns
331
332 (define_insn "*movsfcc_vfp"
333 [(set (match_operand:SF 0 "s_register_operand" "=t,t,t,t,t,t,?r,?r,?r")
334 (if_then_else:SF
335 (match_operator 3 "arm_comparison_operator"
336 [(match_operand 4 "cc_register" "") (const_int 0)])
337 (match_operand:SF 1 "s_register_operand" "0,t,t,0,?r,?r,0,t,t")
338 (match_operand:SF 2 "s_register_operand" "t,0,t,?r,0,?r,t,0,t")))]
339 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
340 "@
341 fcpys%D3\\t%0, %2
342 fcpys%d3\\t%0, %1
343 fcpys%D3\\t%0, %2\;fcpys%d3\\t%0, %1
344 fmsr%D3\\t%0, %2
345 fmsr%d3\\t%0, %1
346 fmsr%D3\\t%0, %2\;fmsr%d3\\t%0, %1
347 fmrs%D3\\t%0, %2
348 fmrs%d3\\t%0, %1
349 fmrs%D3\\t%0, %2\;fmrs%d3\\t%0, %1"
350 [(set_attr "conds" "use")
351 (set_attr "length" "4,4,8,4,4,8,4,4,8")
352 (set_attr "type" "ffarith,ffarith,ffarith,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r")]
353 )
354
355 (define_insn "*thumb2_movsfcc_vfp"
356 [(set (match_operand:SF 0 "s_register_operand" "=t,t,t,t,t,t,?r,?r,?r")
357 (if_then_else:SF
358 (match_operator 3 "arm_comparison_operator"
359 [(match_operand 4 "cc_register" "") (const_int 0)])
360 (match_operand:SF 1 "s_register_operand" "0,t,t,0,?r,?r,0,t,t")
361 (match_operand:SF 2 "s_register_operand" "t,0,t,?r,0,?r,t,0,t")))]
362 "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_VFP"
363 "@
364 it\\t%D3\;fcpys%D3\\t%0, %2
365 it\\t%d3\;fcpys%d3\\t%0, %1
366 ite\\t%D3\;fcpys%D3\\t%0, %2\;fcpys%d3\\t%0, %1
367 it\\t%D3\;fmsr%D3\\t%0, %2
368 it\\t%d3\;fmsr%d3\\t%0, %1
369 ite\\t%D3\;fmsr%D3\\t%0, %2\;fmsr%d3\\t%0, %1
370 it\\t%D3\;fmrs%D3\\t%0, %2
371 it\\t%d3\;fmrs%d3\\t%0, %1
372 ite\\t%D3\;fmrs%D3\\t%0, %2\;fmrs%d3\\t%0, %1"
373 [(set_attr "conds" "use")
374 (set_attr "length" "6,6,10,6,6,10,6,6,10")
375 (set_attr "type" "ffarith,ffarith,ffarith,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r")]
376 )
377
378 (define_insn "*movdfcc_vfp"
379 [(set (match_operand:DF 0 "s_register_operand" "=w,w,w,w,w,w,?r,?r,?r")
380 (if_then_else:DF
381 (match_operator 3 "arm_comparison_operator"
382 [(match_operand 4 "cc_register" "") (const_int 0)])
383 (match_operand:DF 1 "s_register_operand" "0,w,w,0,?r,?r,0,w,w")
384 (match_operand:DF 2 "s_register_operand" "w,0,w,?r,0,?r,w,0,w")))]
385 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
386 "@
387 fcpyd%D3\\t%P0, %P2
388 fcpyd%d3\\t%P0, %P1
389 fcpyd%D3\\t%P0, %P2\;fcpyd%d3\\t%P0, %P1
390 fmdrr%D3\\t%P0, %Q2, %R2
391 fmdrr%d3\\t%P0, %Q1, %R1
392 fmdrr%D3\\t%P0, %Q2, %R2\;fmdrr%d3\\t%P0, %Q1, %R1
393 fmrrd%D3\\t%Q0, %R0, %P2
394 fmrrd%d3\\t%Q0, %R0, %P1
395 fmrrd%D3\\t%Q0, %R0, %P2\;fmrrd%d3\\t%Q0, %R0, %P1"
396 [(set_attr "conds" "use")
397 (set_attr "length" "4,4,8,4,4,8,4,4,8")
398 (set_attr "type" "ffarith,ffarith,ffarith,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r")]
399 )
400
401 (define_insn "*thumb2_movdfcc_vfp"
402 [(set (match_operand:DF 0 "s_register_operand" "=w,w,w,w,w,w,?r,?r,?r")
403 (if_then_else:DF
404 (match_operator 3 "arm_comparison_operator"
405 [(match_operand 4 "cc_register" "") (const_int 0)])
406 (match_operand:DF 1 "s_register_operand" "0,w,w,0,?r,?r,0,w,w")
407 (match_operand:DF 2 "s_register_operand" "w,0,w,?r,0,?r,w,0,w")))]
408 "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_VFP"
409 "@
410 it\\t%D3\;fcpyd%D3\\t%P0, %P2
411 it\\t%d3\;fcpyd%d3\\t%P0, %P1
412 ite\\t%D3\;fcpyd%D3\\t%P0, %P2\;fcpyd%d3\\t%P0, %P1
413 it\t%D3\;fmdrr%D3\\t%P0, %Q2, %R2
414 it\t%d3\;fmdrr%d3\\t%P0, %Q1, %R1
415 ite\\t%D3\;fmdrr%D3\\t%P0, %Q2, %R2\;fmdrr%d3\\t%P0, %Q1, %R1
416 it\t%D3\;fmrrd%D3\\t%Q0, %R0, %P2
417 it\t%d3\;fmrrd%d3\\t%Q0, %R0, %P1
418 ite\\t%D3\;fmrrd%D3\\t%Q0, %R0, %P2\;fmrrd%d3\\t%Q0, %R0, %P1"
419 [(set_attr "conds" "use")
420 (set_attr "length" "6,6,10,6,6,10,6,6,10")
421 (set_attr "type" "ffarith,ffarith,ffarith,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r")]
422 )
423
424
425 ;; Sign manipulation functions
426
427 (define_insn "*abssf2_vfp"
428 [(set (match_operand:SF 0 "s_register_operand" "=t")
429 (abs:SF (match_operand:SF 1 "s_register_operand" "t")))]
430 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
431 "fabss%?\\t%0, %1"
432 [(set_attr "predicable" "yes")
433 (set_attr "type" "ffarith")]
434 )
435
436 (define_insn "*absdf2_vfp"
437 [(set (match_operand:DF 0 "s_register_operand" "=w")
438 (abs:DF (match_operand:DF 1 "s_register_operand" "w")))]
439 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
440 "fabsd%?\\t%P0, %P1"
441 [(set_attr "predicable" "yes")
442 (set_attr "type" "ffarith")]
443 )
444
445 (define_insn "*negsf2_vfp"
446 [(set (match_operand:SF 0 "s_register_operand" "=t,?r")
447 (neg:SF (match_operand:SF 1 "s_register_operand" "t,r")))]
448 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
449 "@
450 fnegs%?\\t%0, %1
451 eor%?\\t%0, %1, #-2147483648"
452 [(set_attr "predicable" "yes")
453 (set_attr "type" "ffarith")]
454 )
455
456 (define_insn_and_split "*negdf2_vfp"
457 [(set (match_operand:DF 0 "s_register_operand" "=w,?r,?r")
458 (neg:DF (match_operand:DF 1 "s_register_operand" "w,0,r")))]
459 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
460 "@
461 fnegd%?\\t%P0, %P1
462 #
463 #"
464 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP && reload_completed
465 && arm_general_register_operand (operands[0], DFmode)"
466 [(set (match_dup 0) (match_dup 1))]
467 "
468 if (REGNO (operands[0]) == REGNO (operands[1]))
469 {
470 operands[0] = gen_highpart (SImode, operands[0]);
471 operands[1] = gen_rtx_XOR (SImode, operands[0], GEN_INT (0x80000000));
472 }
473 else
474 {
475 rtx in_hi, in_lo, out_hi, out_lo;
476
477 in_hi = gen_rtx_XOR (SImode, gen_highpart (SImode, operands[1]),
478 GEN_INT (0x80000000));
479 in_lo = gen_lowpart (SImode, operands[1]);
480 out_hi = gen_highpart (SImode, operands[0]);
481 out_lo = gen_lowpart (SImode, operands[0]);
482
483 if (REGNO (in_lo) == REGNO (out_hi))
484 {
485 emit_insn (gen_rtx_SET (SImode, out_lo, in_lo));
486 operands[0] = out_hi;
487 operands[1] = in_hi;
488 }
489 else
490 {
491 emit_insn (gen_rtx_SET (SImode, out_hi, in_hi));
492 operands[0] = out_lo;
493 operands[1] = in_lo;
494 }
495 }
496 "
497 [(set_attr "predicable" "yes")
498 (set_attr "length" "4,4,8")
499 (set_attr "type" "ffarith")]
500 )
501
502
503 ;; Arithmetic insns
504
505 (define_insn "*addsf3_vfp"
506 [(set (match_operand:SF 0 "s_register_operand" "=t")
507 (plus:SF (match_operand:SF 1 "s_register_operand" "t")
508 (match_operand:SF 2 "s_register_operand" "t")))]
509 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
510 "fadds%?\\t%0, %1, %2"
511 [(set_attr "predicable" "yes")
512 (set_attr "type" "farith")]
513 )
514
515 (define_insn "*adddf3_vfp"
516 [(set (match_operand:DF 0 "s_register_operand" "=w")
517 (plus:DF (match_operand:DF 1 "s_register_operand" "w")
518 (match_operand:DF 2 "s_register_operand" "w")))]
519 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
520 "faddd%?\\t%P0, %P1, %P2"
521 [(set_attr "predicable" "yes")
522 (set_attr "type" "farith")]
523 )
524
525
526 (define_insn "*subsf3_vfp"
527 [(set (match_operand:SF 0 "s_register_operand" "=t")
528 (minus:SF (match_operand:SF 1 "s_register_operand" "t")
529 (match_operand:SF 2 "s_register_operand" "t")))]
530 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
531 "fsubs%?\\t%0, %1, %2"
532 [(set_attr "predicable" "yes")
533 (set_attr "type" "farith")]
534 )
535
536 (define_insn "*subdf3_vfp"
537 [(set (match_operand:DF 0 "s_register_operand" "=w")
538 (minus:DF (match_operand:DF 1 "s_register_operand" "w")
539 (match_operand:DF 2 "s_register_operand" "w")))]
540 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
541 "fsubd%?\\t%P0, %P1, %P2"
542 [(set_attr "predicable" "yes")
543 (set_attr "type" "farith")]
544 )
545
546
547 ;; Division insns
548
549 (define_insn "*divsf3_vfp"
550 [(set (match_operand:SF 0 "s_register_operand" "+t")
551 (div:SF (match_operand:SF 1 "s_register_operand" "t")
552 (match_operand:SF 2 "s_register_operand" "t")))]
553 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
554 "fdivs%?\\t%0, %1, %2"
555 [(set_attr "predicable" "yes")
556 (set_attr "type" "fdivs")]
557 )
558
559 (define_insn "*divdf3_vfp"
560 [(set (match_operand:DF 0 "s_register_operand" "+w")
561 (div:DF (match_operand:DF 1 "s_register_operand" "w")
562 (match_operand:DF 2 "s_register_operand" "w")))]
563 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
564 "fdivd%?\\t%P0, %P1, %P2"
565 [(set_attr "predicable" "yes")
566 (set_attr "type" "fdivd")]
567 )
568
569
570 ;; Multiplication insns
571
572 (define_insn "*mulsf3_vfp"
573 [(set (match_operand:SF 0 "s_register_operand" "+t")
574 (mult:SF (match_operand:SF 1 "s_register_operand" "t")
575 (match_operand:SF 2 "s_register_operand" "t")))]
576 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
577 "fmuls%?\\t%0, %1, %2"
578 [(set_attr "predicable" "yes")
579 (set_attr "type" "fmuls")]
580 )
581
582 (define_insn "*muldf3_vfp"
583 [(set (match_operand:DF 0 "s_register_operand" "+w")
584 (mult:DF (match_operand:DF 1 "s_register_operand" "w")
585 (match_operand:DF 2 "s_register_operand" "w")))]
586 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
587 "fmuld%?\\t%P0, %P1, %P2"
588 [(set_attr "predicable" "yes")
589 (set_attr "type" "fmuld")]
590 )
591
592
593 (define_insn "*mulsf3negsf_vfp"
594 [(set (match_operand:SF 0 "s_register_operand" "+t")
595 (mult:SF (neg:SF (match_operand:SF 1 "s_register_operand" "t"))
596 (match_operand:SF 2 "s_register_operand" "t")))]
597 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
598 "fnmuls%?\\t%0, %1, %2"
599 [(set_attr "predicable" "yes")
600 (set_attr "type" "fmuls")]
601 )
602
603 (define_insn "*muldf3negdf_vfp"
604 [(set (match_operand:DF 0 "s_register_operand" "+w")
605 (mult:DF (neg:DF (match_operand:DF 1 "s_register_operand" "w"))
606 (match_operand:DF 2 "s_register_operand" "w")))]
607 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
608 "fnmuld%?\\t%P0, %P1, %P2"
609 [(set_attr "predicable" "yes")
610 (set_attr "type" "fmuld")]
611 )
612
613
614 ;; Multiply-accumulate insns
615
616 ;; 0 = 1 * 2 + 0
617 (define_insn "*mulsf3addsf_vfp"
618 [(set (match_operand:SF 0 "s_register_operand" "=t")
619 (plus:SF (mult:SF (match_operand:SF 2 "s_register_operand" "t")
620 (match_operand:SF 3 "s_register_operand" "t"))
621 (match_operand:SF 1 "s_register_operand" "0")))]
622 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
623 "fmacs%?\\t%0, %2, %3"
624 [(set_attr "predicable" "yes")
625 (set_attr "type" "fmacs")]
626 )
627
628 (define_insn "*muldf3adddf_vfp"
629 [(set (match_operand:DF 0 "s_register_operand" "=w")
630 (plus:DF (mult:DF (match_operand:DF 2 "s_register_operand" "w")
631 (match_operand:DF 3 "s_register_operand" "w"))
632 (match_operand:DF 1 "s_register_operand" "0")))]
633 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
634 "fmacd%?\\t%P0, %P2, %P3"
635 [(set_attr "predicable" "yes")
636 (set_attr "type" "fmacd")]
637 )
638
639 ;; 0 = 1 * 2 - 0
640 (define_insn "*mulsf3subsf_vfp"
641 [(set (match_operand:SF 0 "s_register_operand" "=t")
642 (minus:SF (mult:SF (match_operand:SF 2 "s_register_operand" "t")
643 (match_operand:SF 3 "s_register_operand" "t"))
644 (match_operand:SF 1 "s_register_operand" "0")))]
645 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
646 "fmscs%?\\t%0, %2, %3"
647 [(set_attr "predicable" "yes")
648 (set_attr "type" "fmacs")]
649 )
650
651 (define_insn "*muldf3subdf_vfp"
652 [(set (match_operand:DF 0 "s_register_operand" "=w")
653 (minus:DF (mult:DF (match_operand:DF 2 "s_register_operand" "w")
654 (match_operand:DF 3 "s_register_operand" "w"))
655 (match_operand:DF 1 "s_register_operand" "0")))]
656 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
657 "fmscd%?\\t%P0, %P2, %P3"
658 [(set_attr "predicable" "yes")
659 (set_attr "type" "fmacd")]
660 )
661
662 ;; 0 = -(1 * 2) + 0
663 (define_insn "*mulsf3negsfaddsf_vfp"
664 [(set (match_operand:SF 0 "s_register_operand" "=t")
665 (minus:SF (match_operand:SF 1 "s_register_operand" "0")
666 (mult:SF (match_operand:SF 2 "s_register_operand" "t")
667 (match_operand:SF 3 "s_register_operand" "t"))))]
668 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
669 "fnmacs%?\\t%0, %2, %3"
670 [(set_attr "predicable" "yes")
671 (set_attr "type" "fmacs")]
672 )
673
674 (define_insn "*fmuldf3negdfadddf_vfp"
675 [(set (match_operand:DF 0 "s_register_operand" "=w")
676 (minus:DF (match_operand:DF 1 "s_register_operand" "0")
677 (mult:DF (match_operand:DF 2 "s_register_operand" "w")
678 (match_operand:DF 3 "s_register_operand" "w"))))]
679 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
680 "fnmacd%?\\t%P0, %P2, %P3"
681 [(set_attr "predicable" "yes")
682 (set_attr "type" "fmacd")]
683 )
684
685
686 ;; 0 = -(1 * 2) - 0
687 (define_insn "*mulsf3negsfsubsf_vfp"
688 [(set (match_operand:SF 0 "s_register_operand" "=t")
689 (minus:SF (mult:SF
690 (neg:SF (match_operand:SF 2 "s_register_operand" "t"))
691 (match_operand:SF 3 "s_register_operand" "t"))
692 (match_operand:SF 1 "s_register_operand" "0")))]
693 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
694 "fnmscs%?\\t%0, %2, %3"
695 [(set_attr "predicable" "yes")
696 (set_attr "type" "fmacs")]
697 )
698
699 (define_insn "*muldf3negdfsubdf_vfp"
700 [(set (match_operand:DF 0 "s_register_operand" "=w")
701 (minus:DF (mult:DF
702 (neg:DF (match_operand:DF 2 "s_register_operand" "w"))
703 (match_operand:DF 3 "s_register_operand" "w"))
704 (match_operand:DF 1 "s_register_operand" "0")))]
705 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
706 "fnmscd%?\\t%P0, %P2, %P3"
707 [(set_attr "predicable" "yes")
708 (set_attr "type" "fmacd")]
709 )
710
711
712 ;; Conversion routines
713
714 (define_insn "*extendsfdf2_vfp"
715 [(set (match_operand:DF 0 "s_register_operand" "=w")
716 (float_extend:DF (match_operand:SF 1 "s_register_operand" "t")))]
717 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
718 "fcvtds%?\\t%P0, %1"
719 [(set_attr "predicable" "yes")
720 (set_attr "type" "f_cvt")]
721 )
722
723 (define_insn "*truncdfsf2_vfp"
724 [(set (match_operand:SF 0 "s_register_operand" "=t")
725 (float_truncate:SF (match_operand:DF 1 "s_register_operand" "w")))]
726 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
727 "fcvtsd%?\\t%0, %P1"
728 [(set_attr "predicable" "yes")
729 (set_attr "type" "f_cvt")]
730 )
731
732 (define_insn "*truncsisf2_vfp"
733 [(set (match_operand:SI 0 "s_register_operand" "=t")
734 (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" "t"))))]
735 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
736 "ftosizs%?\\t%0, %1"
737 [(set_attr "predicable" "yes")
738 (set_attr "type" "f_cvt")]
739 )
740
741 (define_insn "*truncsidf2_vfp"
742 [(set (match_operand:SI 0 "s_register_operand" "=t")
743 (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" "w"))))]
744 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
745 "ftosizd%?\\t%0, %P1"
746 [(set_attr "predicable" "yes")
747 (set_attr "type" "f_cvt")]
748 )
749
750
751 (define_insn "fixuns_truncsfsi2"
752 [(set (match_operand:SI 0 "s_register_operand" "=t")
753 (unsigned_fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" "t"))))]
754 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
755 "ftouizs%?\\t%0, %1"
756 [(set_attr "predicable" "yes")
757 (set_attr "type" "f_cvt")]
758 )
759
760 (define_insn "fixuns_truncdfsi2"
761 [(set (match_operand:SI 0 "s_register_operand" "=t")
762 (unsigned_fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" "t"))))]
763 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
764 "ftouizd%?\\t%0, %P1"
765 [(set_attr "predicable" "yes")
766 (set_attr "type" "f_cvt")]
767 )
768
769
770 (define_insn "*floatsisf2_vfp"
771 [(set (match_operand:SF 0 "s_register_operand" "=t")
772 (float:SF (match_operand:SI 1 "s_register_operand" "t")))]
773 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
774 "fsitos%?\\t%0, %1"
775 [(set_attr "predicable" "yes")
776 (set_attr "type" "f_cvt")]
777 )
778
779 (define_insn "*floatsidf2_vfp"
780 [(set (match_operand:DF 0 "s_register_operand" "=w")
781 (float:DF (match_operand:SI 1 "s_register_operand" "t")))]
782 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
783 "fsitod%?\\t%P0, %1"
784 [(set_attr "predicable" "yes")
785 (set_attr "type" "f_cvt")]
786 )
787
788
789 (define_insn "floatunssisf2"
790 [(set (match_operand:SF 0 "s_register_operand" "=t")
791 (unsigned_float:SF (match_operand:SI 1 "s_register_operand" "t")))]
792 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
793 "fuitos%?\\t%0, %1"
794 [(set_attr "predicable" "yes")
795 (set_attr "type" "f_cvt")]
796 )
797
798 (define_insn "floatunssidf2"
799 [(set (match_operand:DF 0 "s_register_operand" "=w")
800 (unsigned_float:DF (match_operand:SI 1 "s_register_operand" "t")))]
801 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
802 "fuitod%?\\t%P0, %1"
803 [(set_attr "predicable" "yes")
804 (set_attr "type" "f_cvt")]
805 )
806
807
808 ;; Sqrt insns.
809
810 (define_insn "*sqrtsf2_vfp"
811 [(set (match_operand:SF 0 "s_register_operand" "=t")
812 (sqrt:SF (match_operand:SF 1 "s_register_operand" "t")))]
813 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
814 "fsqrts%?\\t%0, %1"
815 [(set_attr "predicable" "yes")
816 (set_attr "type" "fdivs")]
817 )
818
819 (define_insn "*sqrtdf2_vfp"
820 [(set (match_operand:DF 0 "s_register_operand" "=w")
821 (sqrt:DF (match_operand:DF 1 "s_register_operand" "w")))]
822 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
823 "fsqrtd%?\\t%P0, %P1"
824 [(set_attr "predicable" "yes")
825 (set_attr "type" "fdivd")]
826 )
827
828
829 ;; Patterns to split/copy vfp condition flags.
830
831 (define_insn "*movcc_vfp"
832 [(set (reg CC_REGNUM)
833 (reg VFPCC_REGNUM))]
834 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
835 "fmstat%?"
836 [(set_attr "conds" "set")
837 (set_attr "type" "f_flag")]
838 )
839
840 (define_insn_and_split "*cmpsf_split_vfp"
841 [(set (reg:CCFP CC_REGNUM)
842 (compare:CCFP (match_operand:SF 0 "s_register_operand" "t")
843 (match_operand:SF 1 "vfp_compare_operand" "tG")))]
844 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
845 "#"
846 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
847 [(set (reg:CCFP VFPCC_REGNUM)
848 (compare:CCFP (match_dup 0)
849 (match_dup 1)))
850 (set (reg:CCFP CC_REGNUM)
851 (reg:CCFP VFPCC_REGNUM))]
852 ""
853 )
854
855 (define_insn_and_split "*cmpsf_trap_split_vfp"
856 [(set (reg:CCFPE CC_REGNUM)
857 (compare:CCFPE (match_operand:SF 0 "s_register_operand" "t")
858 (match_operand:SF 1 "vfp_compare_operand" "tG")))]
859 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
860 "#"
861 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
862 [(set (reg:CCFPE VFPCC_REGNUM)
863 (compare:CCFPE (match_dup 0)
864 (match_dup 1)))
865 (set (reg:CCFPE CC_REGNUM)
866 (reg:CCFPE VFPCC_REGNUM))]
867 ""
868 )
869
870 (define_insn_and_split "*cmpdf_split_vfp"
871 [(set (reg:CCFP CC_REGNUM)
872 (compare:CCFP (match_operand:DF 0 "s_register_operand" "w")
873 (match_operand:DF 1 "vfp_compare_operand" "wG")))]
874 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
875 "#"
876 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
877 [(set (reg:CCFP VFPCC_REGNUM)
878 (compare:CCFP (match_dup 0)
879 (match_dup 1)))
880 (set (reg:CCFP CC_REGNUM)
881 (reg:CCFPE VFPCC_REGNUM))]
882 ""
883 )
884
885 (define_insn_and_split "*cmpdf_trap_split_vfp"
886 [(set (reg:CCFPE CC_REGNUM)
887 (compare:CCFPE (match_operand:DF 0 "s_register_operand" "w")
888 (match_operand:DF 1 "vfp_compare_operand" "wG")))]
889 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
890 "#"
891 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
892 [(set (reg:CCFPE VFPCC_REGNUM)
893 (compare:CCFPE (match_dup 0)
894 (match_dup 1)))
895 (set (reg:CCFPE CC_REGNUM)
896 (reg:CCFPE VFPCC_REGNUM))]
897 ""
898 )
899
900
901 ;; Comparison patterns
902
903 (define_insn "*cmpsf_vfp"
904 [(set (reg:CCFP VFPCC_REGNUM)
905 (compare:CCFP (match_operand:SF 0 "s_register_operand" "t,t")
906 (match_operand:SF 1 "vfp_compare_operand" "t,G")))]
907 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
908 "@
909 fcmps%?\\t%0, %1
910 fcmpzs%?\\t%0"
911 [(set_attr "predicable" "yes")
912 (set_attr "type" "ffarith")]
913 )
914
915 (define_insn "*cmpsf_trap_vfp"
916 [(set (reg:CCFPE VFPCC_REGNUM)
917 (compare:CCFPE (match_operand:SF 0 "s_register_operand" "t,t")
918 (match_operand:SF 1 "vfp_compare_operand" "t,G")))]
919 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
920 "@
921 fcmpes%?\\t%0, %1
922 fcmpezs%?\\t%0"
923 [(set_attr "predicable" "yes")
924 (set_attr "type" "ffarith")]
925 )
926
927 (define_insn "*cmpdf_vfp"
928 [(set (reg:CCFP VFPCC_REGNUM)
929 (compare:CCFP (match_operand:DF 0 "s_register_operand" "w,w")
930 (match_operand:DF 1 "vfp_compare_operand" "w,G")))]
931 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
932 "@
933 fcmpd%?\\t%P0, %P1
934 fcmpzd%?\\t%P0"
935 [(set_attr "predicable" "yes")
936 (set_attr "type" "ffarith")]
937 )
938
939 (define_insn "*cmpdf_trap_vfp"
940 [(set (reg:CCFPE VFPCC_REGNUM)
941 (compare:CCFPE (match_operand:DF 0 "s_register_operand" "w,w")
942 (match_operand:DF 1 "vfp_compare_operand" "w,G")))]
943 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
944 "@
945 fcmped%?\\t%P0, %P1
946 fcmpezd%?\\t%P0"
947 [(set_attr "predicable" "yes")
948 (set_attr "type" "ffarith")]
949 )
950
951
952 ;; Store multiple insn used in function prologue.
953
954 (define_insn "*push_multi_vfp"
955 [(match_parallel 2 "multi_register_push"
956 [(set (match_operand:BLK 0 "memory_operand" "=m")
957 (unspec:BLK [(match_operand:DF 1 "s_register_operand" "w")]
958 UNSPEC_PUSH_MULT))])]
959 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
960 "* return vfp_output_fstmd (operands);"
961 [(set_attr "type" "f_stored")]
962 )
963
964
965 ;; Unimplemented insns:
966 ;; fldm*
967 ;; fstm*
968 ;; fmdhr et al (VFPv1)
969 ;; Support for xD (single precision only) variants.
970 ;; fmrrs, fmsrr