arm.md (fixuns_truncsfsi2, [...]): New patterns.
[gcc.git] / gcc / config / arm / vfp.md
1 ;; ARM VFP coprocessor Machine Description
2 ;; Copyright (C) 2003 Free Software Foundation, Inc.
3 ;; Written by CodeSourcery, LLC.
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 2, 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 COPYING. If not, write to the Free
19 ;; Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 ;; 02111-1307, USA. */
21
22 ;; Additional register numbers
23 (define_constants
24 [(VFPCC_REGNUM 95)]
25 )
26
27 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
28 ;; Pipeline description
29 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
30
31 (define_automaton "vfp11")
32
33 ;; There are 3 pipelines in the VFP11 unit.
34 ;;
35 ;; - A 8-stage FMAC pipeline (7 execute + writeback) with forward from
36 ;; fourth stage for simple operations.
37 ;;
38 ;; - A 5-stage DS pipeline (4 execute + writeback) for divide/sqrt insns.
39 ;; These insns also uses first execute stage of FMAC pipeline.
40 ;;
41 ;; - A 4-stage LS pipeline (execute + 2 memory + writeback) with forward from
42 ;; second memory stage for loads.
43
44 ;; We do not model Write-After-Read hazards.
45 ;; We do not do write scheduling with the arm core, so it is only necessary
46 ;; to model the first stage of each pipeline
47 ;; ??? Need to model LS pipeline properly for load/store multiple?
48 ;; We do not model fmstat properly. This could be done by modeling pipelines
49 ;; properly and defining an absence set between a dummy fmstat unit and all
50 ;; other vfp units.
51
52 (define_cpu_unit "fmac" "vfp11")
53
54 (define_cpu_unit "ds" "vfp11")
55
56 (define_cpu_unit "vfp_ls" "vfp11")
57
58 ;; The VFP "type" attributes differ from those used in the FPA model.
59 ;; ffarith Fast floating point insns, eg. abs, neg, cpy, cmp.
60 ;; farith Most arithmetic insns.
61 ;; fmul Double precision multiply.
62 ;; fdivs Single precision sqrt or division.
63 ;; fdivd Double precision sqrt or division.
64 ;; f_load Floating point load from memory.
65 ;; f_store Floating point store to memory.
66 ;; f_2_r Transfer vfp to arm reg.
67 ;; r_2_f Transfer arm to vfp reg.
68
69 (define_insn_reservation "vfp_ffarith" 4
70 (and (eq_attr "fpu" "vfp")
71 (eq_attr "type" "ffarith"))
72 "fmac")
73
74 (define_insn_reservation "vfp_farith" 8
75 (and (eq_attr "fpu" "vfp")
76 (eq_attr "type" "farith"))
77 "fmac")
78
79 (define_insn_reservation "vfp_fmul" 9
80 (and (eq_attr "fpu" "vfp")
81 (eq_attr "type" "fmul"))
82 "fmac*2")
83
84 (define_insn_reservation "vfp_fdivs" 19
85 (and (eq_attr "fpu" "vfp")
86 (eq_attr "type" "fdivs"))
87 "ds*15")
88
89 (define_insn_reservation "vfp_fdivd" 33
90 (and (eq_attr "fpu" "vfp")
91 (eq_attr "type" "fdivd"))
92 "fmac+ds*29")
93
94 ;; Moves to/from arm regs also use the load/store pipeline.
95 (define_insn_reservation "vfp_fload" 4
96 (and (eq_attr "fpu" "vfp")
97 (eq_attr "type" "f_load,r_2_f"))
98 "vfp_ls")
99
100 (define_insn_reservation "vfp_fstore" 4
101 (and (eq_attr "fpu" "vfp")
102 (eq_attr "type" "f_load,f_2_r"))
103 "vfp_ls")
104
105
106 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
107 ;; Insn pattern
108 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
109
110 ;; SImode moves
111 ;; ??? For now do not allow loading constants into vfp regs. This causes
112 ;; problems because small constants get converted into adds.
113 (define_insn "*arm_movsi_vfp"
114 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r ,m,!w,r,!w,!w, Uv")
115 (match_operand:SI 1 "general_operand" "rI,K,mi,r,r,!w,!w,Uvi,!w"))]
116 "TARGET_ARM && TARGET_VFP && TARGET_HARD_FLOAT
117 && ( s_register_operand (operands[0], SImode)
118 || s_register_operand (operands[1], SImode))"
119 "@
120 mov%?\\t%0, %1
121 mvn%?\\t%0, #%B1
122 ldr%?\\t%0, %1
123 str%?\\t%1, %0
124 fmsr%?\\t%0, %1\\t%@ int
125 fmrs%?\\t%0, %1\\t%@ int
126 fcpys%?\\t%0, %1\\t%@ int
127 flds%?\\t%0, %1\\t%@ int
128 fsts%?\\t%1, %0\\t%@ int"
129 [(set_attr "predicable" "yes")
130 (set_attr "type" "*,*,load1,store1,r_2_f,f_2_r,ffarith,f_load,f_store")
131 (set_attr "pool_range" "*,*,4096,*,*,*,*,1020,*")
132 (set_attr "neg_pool_range" "*,*,4084,*,*,*,*,1008,*")]
133 )
134
135
136 ;; DImode moves
137
138 (define_insn "*arm_movdi_vfp"
139 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r,o<>,w,r,w,w ,Uv")
140 (match_operand:DI 1 "di_operand" "rIK,mi,r ,r,w,w,Uvi,w"))]
141 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
142 "*
143 switch (which_alternative)
144 {
145 case 0: case 1: case 2:
146 return (output_move_double (operands));
147 case 3:
148 return \"fmdrr%?\\t%P0, %1\\t%@ int\";
149 case 4:
150 return \"fmrrd%?\\t%0, %1\\t%@ int\";
151 case 5:
152 return \"fcpyd%?\\t%P0, %P1\\t%@ int\";
153 case 6:
154 return \"fldd%?\\t%P0, %1\\t%@ int\";
155 case 7:
156 return \"fstd%?\\t%P1, %0\\t%@ int\";
157 default:
158 abort ();
159 }
160 "
161 [(set_attr "type" "*,load2,store2,r_2_f,f_2_r,ffarith,f_load,f_store")
162 (set_attr "length" "8,8,8,4,4,4,4,4")
163 (set_attr "pool_range" "*,1020,*,*,*,*,1020,*")
164 (set_attr "neg_pool_range" "*,1008,*,*,*,*,1008,*")]
165 )
166
167
168 ;; SFmode moves
169
170 (define_insn "*movsf_vfp"
171 [(set (match_operand:SF 0 "nonimmediate_operand" "=w,r,w ,Uv,r ,m,w,r")
172 (match_operand:SF 1 "general_operand" " r,w,UvE,w, mE,r,w,r"))]
173 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP
174 && ( s_register_operand (operands[0], SFmode)
175 || s_register_operand (operands[1], SFmode))"
176 "@
177 fmsr%?\\t%0, %1
178 fmrs%?\\t%0, %1
179 flds%?\\t%0, %1
180 fsts%?\\t%1, %0
181 ldr%?\\t%0, %1\\t%@ float
182 str%?\\t%1, %0\\t%@ float
183 fcpys%?\\t%0, %1
184 mov%?\\t%0, %1\\t%@ float"
185 [(set_attr "predicable" "yes")
186 (set_attr "type" "r_2_f,f_2_r,ffarith,*,f_load,f_store,load1,store1")
187 (set_attr "pool_range" "*,*,1020,*,4096,*,*,*")
188 (set_attr "neg_pool_range" "*,*,1008,*,4080,*,*,*")]
189 )
190
191
192 ;; DFmode moves
193
194 (define_insn "*movdf_vfp"
195 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=w,r,r, m,w ,Uv,w,r")
196 (match_operand:DF 1 "soft_df_operand" " r,w,mF,r,UvF,w, w,r"))]
197 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
198 "*
199 {
200 switch (which_alternative)
201 {
202 case 0:
203 return \"fmdrr%?\\t%P0, %Q1, %R1\";
204 case 1:
205 return \"fmrrd%?\\t%Q0, %R0, %P1\";
206 case 2: case 3: case 7:
207 return output_move_double (operands);
208 case 4:
209 return \"fldd%?\\t%P0, %1\";
210 case 5:
211 return \"fstd%?\\t%P1, %0\";
212 case 6:
213 return \"fcpyd%?\\t%P0, %P1\";
214 default:
215 abort ();
216 }
217 }
218 "
219 [(set_attr "type" "r_2_f,f_2_r,ffarith,*,load2,store2,f_load,f_store")
220 (set_attr "length" "4,4,8,8,4,4,4,8")
221 (set_attr "pool_range" "*,*,1020,*,1020,*,*,*")
222 (set_attr "neg_pool_range" "*,*,1008,*,1008,*,*,*")]
223 )
224
225
226 ;; Conditional move patterns
227
228 (define_insn "*movsfcc_vfp"
229 [(set (match_operand:SF 0 "s_register_operand" "=w,w,w,w,w,w,?r,?r,?r")
230 (if_then_else:SF
231 (match_operator 3 "arm_comparison_operator"
232 [(match_operand 4 "cc_register" "") (const_int 0)])
233 (match_operand:SF 1 "s_register_operand" "0,w,w,0,?r,?r,0,w,w")
234 (match_operand:SF 2 "s_register_operand" "w,0,w,?r,0,?r,w,0,w")))]
235 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
236 "@
237 fcpys%D3\\t%0, %2
238 fcpys%d3\\t%0, %1
239 fcpys%D3\\t%0, %2\;fcpys%d3\\t%0, %1
240 fmsr%D3\\t%0, %2
241 fmsr%d3\\t%0, %1
242 fmsr%D3\\t%0, %2\;fmsr%d3\\t%0, %1
243 fmrs%D3\\t%0, %2
244 fmrs%d3\\t%0, %1
245 fmrs%D3\\t%0, %2\;fmrs%d3\\t%0, %1"
246 [(set_attr "conds" "use")
247 (set_attr "length" "4,4,8,4,4,8,4,4,8")
248 (set_attr "type" "ffarith,ffarith,ffarith,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r")]
249 )
250
251 (define_insn "*movdfcc_vfp"
252 [(set (match_operand:DF 0 "s_register_operand" "=w,w,w,w,w,w,?r,?r,?r")
253 (if_then_else:DF
254 (match_operator 3 "arm_comparison_operator"
255 [(match_operand 4 "cc_register" "") (const_int 0)])
256 (match_operand:DF 1 "s_register_operand" "0,w,w,0,?r,?r,0,w,w")
257 (match_operand:DF 2 "s_register_operand" "w,0,w,?r,0,?r,w,0,w")))]
258 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
259 "@
260 fcpyd%D3\\t%P0, %P2
261 fcpyd%d3\\t%P0, %P1
262 fcpyd%D3\\t%P0, %P2\;fcpyd%d3\\t%P0, %P1
263 fmdrr%D3\\t%P0, %Q2, %R2
264 fmdrr%d3\\t%P0, %Q1, %R1
265 fmdrr%D3\\t%P0, %Q2, %R2\;fmdrr%d3\\t%P0, %Q1, %R1
266 fmrrd%D3\\t%Q0, %R0, %P2
267 fmrrd%d3\\t%Q0, %R0, %P1
268 fmrrd%D3\\t%Q0, %R0, %P2\;fmrrd%d3\\t%Q0, %R0, %P1"
269 [(set_attr "conds" "use")
270 (set_attr "length" "4,4,8,4,4,8,4,4,8")
271 (set_attr "type" "ffarith,ffarith,ffarith,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r")]
272 )
273
274
275 ;; Sign manipulation functions
276
277 (define_insn "*abssf2_vfp"
278 [(set (match_operand:SF 0 "s_register_operand" "=w")
279 (abs:SF (match_operand:SF 1 "s_register_operand" "w")))]
280 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
281 "fabss%?\\t%0, %1"
282 [(set_attr "predicable" "yes")
283 (set_attr "type" "ffarith")]
284 )
285
286 (define_insn "*absdf2_vfp"
287 [(set (match_operand:DF 0 "s_register_operand" "=w")
288 (abs:DF (match_operand:DF 1 "s_register_operand" "w")))]
289 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
290 "fabsd%?\\t%P0, %P1"
291 [(set_attr "predicable" "yes")
292 (set_attr "type" "ffarith")]
293 )
294
295 (define_insn "*negsf2_vfp"
296 [(set (match_operand:SF 0 "s_register_operand" "+w")
297 (neg:SF (match_operand:SF 1 "s_register_operand" "w")))]
298 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
299 "fnegs%?\\t%0, %1"
300 [(set_attr "predicable" "yes")
301 (set_attr "type" "ffarith")]
302 )
303
304 (define_insn "*negdf2_vfp"
305 [(set (match_operand:DF 0 "s_register_operand" "+w")
306 (neg:DF (match_operand:DF 1 "s_register_operand" "w")))]
307 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
308 "fnegd%?\\t%P0, %P1"
309 [(set_attr "predicable" "yes")
310 (set_attr "type" "ffarith")]
311 )
312
313
314 ;; Arithmetic insns
315
316 (define_insn "*addsf3_vfp"
317 [(set (match_operand:SF 0 "s_register_operand" "=w")
318 (plus:SF (match_operand:SF 1 "s_register_operand" "w")
319 (match_operand:SF 2 "s_register_operand" "w")))]
320 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
321 "fadds%?\\t%0, %1, %2"
322 [(set_attr "predicable" "yes")
323 (set_attr "type" "farith")]
324 )
325
326 (define_insn "*adddf3_vfp"
327 [(set (match_operand:DF 0 "s_register_operand" "=w")
328 (plus:DF (match_operand:DF 1 "s_register_operand" "w")
329 (match_operand:DF 2 "s_register_operand" "w")))]
330 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
331 "faddd%?\\t%P0, %P1, %P2"
332 [(set_attr "predicable" "yes")
333 (set_attr "type" "farith")]
334 )
335
336
337 (define_insn "*subsf3_vfp"
338 [(set (match_operand:SF 0 "s_register_operand" "=w")
339 (minus:SF (match_operand:SF 1 "s_register_operand" "w")
340 (match_operand:SF 2 "s_register_operand" "w")))]
341 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
342 "fsubs%?\\t%0, %1, %2"
343 [(set_attr "predicable" "yes")
344 (set_attr "type" "farith")]
345 )
346
347 (define_insn "*subdf3_vfp"
348 [(set (match_operand:DF 0 "s_register_operand" "=w")
349 (minus:DF (match_operand:DF 1 "s_register_operand" "w")
350 (match_operand:DF 2 "s_register_operand" "w")))]
351 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
352 "fsubd%?\\t%P0, %P1, %P2"
353 [(set_attr "predicable" "yes")
354 (set_attr "type" "farith")]
355 )
356
357
358 ;; Division insns
359
360 (define_insn "*divsf3_vfp"
361 [(set (match_operand:SF 0 "s_register_operand" "+w")
362 (div:SF (match_operand:SF 1 "s_register_operand" "w")
363 (match_operand:SF 2 "s_register_operand" "w")))]
364 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
365 "fdivs%?\\t%0, %1, %2"
366 [(set_attr "predicable" "yes")
367 (set_attr "type" "fdivs")]
368 )
369
370 (define_insn "*divdf3_vfp"
371 [(set (match_operand:DF 0 "s_register_operand" "+w")
372 (div:DF (match_operand:DF 1 "s_register_operand" "w")
373 (match_operand:DF 2 "s_register_operand" "w")))]
374 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
375 "fdivd%?\\t%P0, %P1, %P2"
376 [(set_attr "predicable" "yes")
377 (set_attr "type" "fdivd")]
378 )
379
380
381 ;; Multiplication insns
382
383 (define_insn "*mulsf3_vfp"
384 [(set (match_operand:SF 0 "s_register_operand" "+w")
385 (mult:SF (match_operand:SF 1 "s_register_operand" "w")
386 (match_operand:SF 2 "s_register_operand" "w")))]
387 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
388 "fmuls%?\\t%0, %1, %2"
389 [(set_attr "predicable" "yes")
390 (set_attr "type" "farith")]
391 )
392
393 (define_insn "*muldf3_vfp"
394 [(set (match_operand:DF 0 "s_register_operand" "+w")
395 (mult:DF (match_operand:DF 1 "s_register_operand" "w")
396 (match_operand:DF 2 "s_register_operand" "w")))]
397 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
398 "fmuld%?\\t%P0, %P1, %P2"
399 [(set_attr "predicable" "yes")
400 (set_attr "type" "fmul")]
401 )
402
403
404 (define_insn "*mulsf3negsf_vfp"
405 [(set (match_operand:SF 0 "s_register_operand" "+w")
406 (mult:SF (neg:SF (match_operand:SF 1 "s_register_operand" "w"))
407 (match_operand:SF 2 "s_register_operand" "w")))]
408 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
409 "fnmuls%?\\t%0, %1, %2"
410 [(set_attr "predicable" "yes")
411 (set_attr "type" "farith")]
412 )
413
414 (define_insn "*muldf3negdf_vfp"
415 [(set (match_operand:DF 0 "s_register_operand" "+w")
416 (mult:DF (neg:DF (match_operand:DF 1 "s_register_operand" "w"))
417 (match_operand:DF 2 "s_register_operand" "w")))]
418 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
419 "fnmuld%?\\t%P0, %P1, %P2"
420 [(set_attr "predicable" "yes")
421 (set_attr "type" "fmul")]
422 )
423
424
425 ;; Multiply-accumulate insns
426
427 ;; 0 = 1 * 2 + 0
428 (define_insn "*mulsf3addsf_vfp"
429 [(set (match_operand:SF 0 "s_register_operand" "=w")
430 (plus:SF (mult:SF (match_operand:SF 2 "s_register_operand" "w")
431 (match_operand:SF 3 "s_register_operand" "w"))
432 (match_operand:SF 1 "s_register_operand" "0")))]
433 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
434 "fmacs%?\\t%0, %2, %3"
435 [(set_attr "predicable" "yes")
436 (set_attr "type" "farith")]
437 )
438
439 (define_insn "*muldf3adddf_vfp"
440 [(set (match_operand:DF 0 "s_register_operand" "=w")
441 (plus:DF (mult:DF (match_operand:DF 2 "s_register_operand" "w")
442 (match_operand:DF 3 "s_register_operand" "w"))
443 (match_operand:DF 1 "s_register_operand" "0")))]
444 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
445 "fmacd%?\\t%P0, %P2, %P3"
446 [(set_attr "predicable" "yes")
447 (set_attr "type" "fmul")]
448 )
449
450 ;; 0 = 1 * 2 - 0
451 (define_insn "*mulsf3subsf_vfp"
452 [(set (match_operand:SF 0 "s_register_operand" "=w")
453 (minus:SF (mult:SF (match_operand:SF 2 "s_register_operand" "w")
454 (match_operand:SF 3 "s_register_operand" "w"))
455 (match_operand:SF 1 "s_register_operand" "0")))]
456 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
457 "fmscs%?\\t%0, %2, %3"
458 [(set_attr "predicable" "yes")
459 (set_attr "type" "farith")]
460 )
461
462 (define_insn "*muldf3subdf_vfp"
463 [(set (match_operand:DF 0 "s_register_operand" "=w")
464 (minus:DF (mult:DF (match_operand:DF 2 "s_register_operand" "w")
465 (match_operand:DF 3 "s_register_operand" "w"))
466 (match_operand:DF 1 "s_register_operand" "0")))]
467 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
468 "fmscd%?\\t%P0, %P2, %P3"
469 [(set_attr "predicable" "yes")
470 (set_attr "type" "fmul")]
471 )
472
473 ;; 0 = -(1 * 2) + 0
474 (define_insn "*mulsf3negsfaddsf_vfp"
475 [(set (match_operand:SF 0 "s_register_operand" "=w")
476 (minus:SF (match_operand:SF 1 "s_register_operand" "0")
477 (mult:SF (match_operand:SF 2 "s_register_operand" "w")
478 (match_operand:SF 3 "s_register_operand" "w"))))]
479 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
480 "fnmacs%?\\t%0, %2, %3"
481 [(set_attr "predicable" "yes")
482 (set_attr "type" "farith")]
483 )
484
485 (define_insn "*fmuldf3negdfadddf_vfp"
486 [(set (match_operand:DF 0 "s_register_operand" "=w")
487 (minus:DF (match_operand:DF 1 "s_register_operand" "0")
488 (mult:DF (match_operand:DF 2 "s_register_operand" "w")
489 (match_operand:DF 3 "s_register_operand" "w"))))]
490 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
491 "fnmacd%?\\t%P0, %P2, %P3"
492 [(set_attr "predicable" "yes")
493 (set_attr "type" "fmul")]
494 )
495
496
497 ;; 0 = -(1 * 2) - 0
498 (define_insn "*mulsf3negsfsubsf_vfp"
499 [(set (match_operand:SF 0 "s_register_operand" "=w")
500 (minus:SF (mult:SF
501 (neg:SF (match_operand:SF 2 "s_register_operand" "w"))
502 (match_operand:SF 3 "s_register_operand" "w"))
503 (match_operand:SF 1 "s_register_operand" "0")))]
504 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
505 "fnmscs%?\\t%0, %2, %3"
506 [(set_attr "predicable" "yes")
507 (set_attr "type" "farith")]
508 )
509
510 (define_insn "*muldf3negdfsubdf_vfp"
511 [(set (match_operand:DF 0 "s_register_operand" "=w")
512 (minus:DF (mult:DF
513 (neg:DF (match_operand:DF 2 "s_register_operand" "w"))
514 (match_operand:DF 3 "s_register_operand" "w"))
515 (match_operand:DF 1 "s_register_operand" "0")))]
516 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
517 "fnmscd%?\\t%P0, %P2, %P3"
518 [(set_attr "predicable" "yes")
519 (set_attr "type" "fmul")]
520 )
521
522
523 ;; Conversion routines
524
525 (define_insn "*extendsfdf2_vfp"
526 [(set (match_operand:DF 0 "s_register_operand" "=w")
527 (float_extend:DF (match_operand:SF 1 "s_register_operand" "w")))]
528 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
529 "fcvtds%?\\t%P0, %1"
530 [(set_attr "predicable" "yes")
531 (set_attr "type" "farith")]
532 )
533
534 (define_insn "*truncdfsf2_vfp"
535 [(set (match_operand:SF 0 "s_register_operand" "=w")
536 (float_truncate:SF (match_operand:DF 1 "s_register_operand" "w")))]
537 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
538 "fcvtsd%?\\t%0, %P1"
539 [(set_attr "predicable" "yes")
540 (set_attr "type" "farith")]
541 )
542
543 (define_insn "*truncsisf2_vfp"
544 [(set (match_operand:SI 0 "s_register_operand" "=w")
545 (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" "w"))))]
546 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
547 "ftosizs%?\\t%0, %1"
548 [(set_attr "predicable" "yes")
549 (set_attr "type" "farith")]
550 )
551
552 (define_insn "*truncsidf2_vfp"
553 [(set (match_operand:SI 0 "s_register_operand" "=w")
554 (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" "w"))))]
555 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
556 "ftosizd%?\\t%0, %P1"
557 [(set_attr "predicable" "yes")
558 (set_attr "type" "farith")]
559 )
560
561
562 (define_insn "fixuns_truncsfsi2"
563 [(set (match_operand:SI 0 "s_register_operand" "=w")
564 (unsigned_fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" "w"))))]
565 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
566 "ftouizs%?\\t%0, %1"
567 [(set_attr "predicable" "yes")
568 (set_attr "type" "farith")]
569 )
570
571 (define_insn "fixuns_truncdfsi2"
572 [(set (match_operand:SI 0 "s_register_operand" "=w")
573 (unsigned_fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" "w"))))]
574 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
575 "ftouizd%?\\t%0, %P1"
576 [(set_attr "predicable" "yes")
577 (set_attr "type" "farith")]
578 )
579
580
581 (define_insn "*floatsisf2_vfp"
582 [(set (match_operand:SF 0 "s_register_operand" "=w")
583 (float:SF (match_operand:SI 1 "s_register_operand" "w")))]
584 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
585 "fsitos%?\\t%0, %1"
586 [(set_attr "predicable" "yes")
587 (set_attr "type" "farith")]
588 )
589
590 (define_insn "*floatsidf2_vfp"
591 [(set (match_operand:DF 0 "s_register_operand" "=w")
592 (float:DF (match_operand:SI 1 "s_register_operand" "w")))]
593 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
594 "fsitod%?\\t%P0, %1"
595 [(set_attr "predicable" "yes")
596 (set_attr "type" "farith")]
597 )
598
599
600 (define_insn "floatunssisf2"
601 [(set (match_operand:SF 0 "s_register_operand" "=w")
602 (unsigned_float:SF (match_operand:SI 1 "s_register_operand" "w")))]
603 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
604 "fuitos%?\\t%0, %1"
605 [(set_attr "predicable" "yes")
606 (set_attr "type" "farith")]
607 )
608
609 (define_insn "floatunssidf2"
610 [(set (match_operand:DF 0 "s_register_operand" "=w")
611 (unsigned_float:DF (match_operand:SI 1 "s_register_operand" "w")))]
612 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
613 "fuitod%?\\t%P0, %1"
614 [(set_attr "predicable" "yes")
615 (set_attr "type" "farith")]
616 )
617
618
619 ;; Sqrt insns.
620
621 (define_insn "*sqrtsf2_vfp"
622 [(set (match_operand:SF 0 "s_register_operand" "=w")
623 (sqrt:SF (match_operand:SF 1 "s_register_operand" "w")))]
624 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
625 "fsqrts%?\\t%0, %1"
626 [(set_attr "predicable" "yes")
627 (set_attr "type" "fdivs")]
628 )
629
630 (define_insn "*sqrtdf2_vfp"
631 [(set (match_operand:DF 0 "s_register_operand" "=w")
632 (sqrt:DF (match_operand:DF 1 "s_register_operand" "w")))]
633 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
634 "fsqrtd%?\\t%P0, %P1"
635 [(set_attr "predicable" "yes")
636 (set_attr "type" "fdivd")]
637 )
638
639
640 ;; Patterns to split/copy vfp condition flags.
641
642 (define_insn "*movcc_vfp"
643 [(set (reg CC_REGNUM)
644 (reg VFPCC_REGNUM))]
645 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
646 "fmstat%?"
647 [(set_attr "conds" "set")
648 (set_attr "type" "ffarith")]
649 )
650
651 (define_insn_and_split "*cmpsf_split_vfp"
652 [(set (reg:CCFP CC_REGNUM)
653 (compare:CCFP (match_operand:SF 0 "s_register_operand" "w")
654 (match_operand:SF 1 "vfp_compare_operand" "wG")))]
655 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
656 "#"
657 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
658 [(set (reg:CCFP VFPCC_REGNUM)
659 (compare:CCFP (match_dup 0)
660 (match_dup 1)))
661 (set (reg:CCFP CC_REGNUM)
662 (reg:CCFP VFPCC_REGNUM))]
663 ""
664 )
665
666 (define_insn_and_split "*cmpsf_trap_split_vfp"
667 [(set (reg:CCFPE CC_REGNUM)
668 (compare:CCFPE (match_operand:SF 0 "s_register_operand" "w")
669 (match_operand:SF 1 "vfp_compare_operand" "wG")))]
670 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
671 "#"
672 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
673 [(set (reg:CCFPE VFPCC_REGNUM)
674 (compare:CCFPE (match_dup 0)
675 (match_dup 1)))
676 (set (reg:CCFPE CC_REGNUM)
677 (reg:CCFPE VFPCC_REGNUM))]
678 ""
679 )
680
681 (define_insn_and_split "*cmpdf_split_vfp"
682 [(set (reg:CCFP CC_REGNUM)
683 (compare:CCFP (match_operand:DF 0 "s_register_operand" "w")
684 (match_operand:DF 1 "vfp_compare_operand" "wG")))]
685 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
686 "#"
687 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
688 [(set (reg:CCFP VFPCC_REGNUM)
689 (compare:CCFP (match_dup 0)
690 (match_dup 1)))
691 (set (reg:CCFP CC_REGNUM)
692 (reg:CCFPE VFPCC_REGNUM))]
693 ""
694 )
695
696 (define_insn_and_split "*cmpdf_trap_split_vfp"
697 [(set (reg:CCFPE CC_REGNUM)
698 (compare:CCFPE (match_operand:DF 0 "s_register_operand" "w")
699 (match_operand:DF 1 "vfp_compare_operand" "wG")))]
700 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
701 "#"
702 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
703 [(set (reg:CCFPE VFPCC_REGNUM)
704 (compare:CCFPE (match_dup 0)
705 (match_dup 1)))
706 (set (reg:CCFPE CC_REGNUM)
707 (reg:CCFPE VFPCC_REGNUM))]
708 ""
709 )
710
711
712 ;; Comparison patterns
713
714 (define_insn "*cmpsf_vfp"
715 [(set (reg:CCFP VFPCC_REGNUM)
716 (compare:CCFP (match_operand:SF 0 "s_register_operand" "w,w")
717 (match_operand:SF 1 "vfp_compare_operand" "w,G")))]
718 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
719 "@
720 fcmps%?\\t%0, %1
721 fcmpzs%?\\t%0"
722 [(set_attr "predicable" "yes")
723 (set_attr "type" "ffarith")]
724 )
725
726 (define_insn "*cmpsf_trap_vfp"
727 [(set (reg:CCFPE VFPCC_REGNUM)
728 (compare:CCFPE (match_operand:SF 0 "s_register_operand" "w,w")
729 (match_operand:SF 1 "vfp_compare_operand" "w,G")))]
730 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
731 "@
732 fcmpes%?\\t%0, %1
733 fcmpezs%?\\t%0"
734 [(set_attr "predicable" "yes")
735 (set_attr "type" "ffarith")]
736 )
737
738 (define_insn "*cmpdf_vfp"
739 [(set (reg:CCFP VFPCC_REGNUM)
740 (compare:CCFP (match_operand:DF 0 "s_register_operand" "w,w")
741 (match_operand:DF 1 "vfp_compare_operand" "w,G")))]
742 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
743 "@
744 fcmpd%?\\t%P0, %P1
745 fcmpzd%?\\t%P0"
746 [(set_attr "predicable" "yes")
747 (set_attr "type" "ffarith")]
748 )
749
750 (define_insn "*cmpdf_trap_vfp"
751 [(set (reg:CCFPE VFPCC_REGNUM)
752 (compare:CCFPE (match_operand:DF 0 "s_register_operand" "w,w")
753 (match_operand:DF 1 "vfp_compare_operand" "w,G")))]
754 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
755 "@
756 fcmped%?\\t%P0, %P1
757 fcmpezd%?\\t%P0"
758 [(set_attr "predicable" "yes")
759 (set_attr "type" "ffarith")]
760 )
761
762
763 ;; Store multiple insn used in function prologue.
764
765 (define_insn "*push_multi_vfp"
766 [(match_parallel 2 "multi_register_push"
767 [(set (match_operand:BLK 0 "memory_operand" "=m")
768 (unspec:BLK [(match_operand:DF 1 "s_register_operand" "w")]
769 UNSPEC_PUSH_MULT))])]
770 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
771 "* return vfp_output_fstmx (operands);"
772 [(set_attr "type" "f_store")]
773 )
774
775
776 ;; Unimplemented insns:
777 ;; fldm*
778 ;; fstm*
779 ;; fmdhr et al (VFPv1)
780 ;; Support for xD (single precision only) variants.
781 ;; fmrrs, fmsrr