comparison gcc/config/arm/vfp.md @ 0:a06113de4d67

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