0
|
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
|