Merged with mainline at revision 128810.
[official-gcc.git] / gcc / config / arm / fpa.md
blobfcd92b002d7b19f31b5e98f1b7d5c1703a8840a2
1 ;;- Machine description for FPA co-processor for ARM cpus.
2 ;;  Copyright 1991, 1993, 1994, 1995, 1996, 1996, 1997, 1998, 1999, 2000,
3 ;;  2001, 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
4 ;;  Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
5 ;;  and Martin Simmons (@harleqn.co.uk).
6 ;;  More major hacks by Richard Earnshaw (rearnsha@arm.com).
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify it
11 ;; under the terms of the GNU General Public License as published
12 ;; by the Free Software Foundation; either version 3, or (at your
13 ;; option) any later version.
15 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
16 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 ;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
18 ;; License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3.  If not see
22 ;; <http://www.gnu.org/licenses/>.
24 ;; Some FPA mnemonics are ambiguous between conditional infixes and
25 ;; conditional suffixes.  All instructions use a conditional infix,
26 ;; even in unified assembly mode.
28 ;; FPA automaton.
29 (define_automaton "armfp")
31 ;; Floating point unit (FPA)
32 (define_cpu_unit "fpa" "armfp")
34 ; The fpa10 doesn't really have a memory read unit, but it can start
35 ; to speculatively execute the instruction in the pipeline, provided
36 ; the data is already loaded, so pretend reads have a delay of 2 (and
37 ; that the pipeline is infinite).
38 (define_cpu_unit "fpa_mem" "arm")
40 (define_insn_reservation "fdivx" 71
41   (and (eq_attr "fpu" "fpa")
42        (eq_attr "type" "fdivx"))
43   "core+fpa*69")
45 (define_insn_reservation "fdivd" 59
46   (and (eq_attr "fpu" "fpa")
47        (eq_attr "type" "fdivd"))
48   "core+fpa*57")
50 (define_insn_reservation "fdivs" 31
51   (and (eq_attr "fpu" "fpa")
52        (eq_attr "type" "fdivs"))
53   "core+fpa*29")
55 (define_insn_reservation "fmul" 9
56   (and (eq_attr "fpu" "fpa")
57        (eq_attr "type" "fmul"))
58   "core+fpa*7")
60 (define_insn_reservation "ffmul" 6
61   (and (eq_attr "fpu" "fpa")
62        (eq_attr "type" "ffmul"))
63   "core+fpa*4")
65 (define_insn_reservation "farith" 4
66   (and (eq_attr "fpu" "fpa")
67        (eq_attr "type" "farith"))
68   "core+fpa*2")
70 (define_insn_reservation "ffarith" 2
71   (and (eq_attr "fpu" "fpa")
72        (eq_attr "type" "ffarith"))
73   "core+fpa*2")
75 (define_insn_reservation "r_2_f" 5
76   (and (eq_attr "fpu" "fpa")
77        (eq_attr "type" "r_2_f"))
78   "core+fpa*3")
80 (define_insn_reservation "f_2_r" 1
81   (and (eq_attr "fpu" "fpa")
82        (eq_attr "type" "f_2_r"))
83   "core+fpa*2")
85 (define_insn_reservation "f_load" 3
86   (and (eq_attr "fpu" "fpa") (eq_attr "type" "f_load"))
87   "fpa_mem+core*3")
89 (define_insn_reservation "f_store" 4
90   (and (eq_attr "fpu" "fpa") (eq_attr "type" "f_store"))
91   "core*4")
93 (define_insn_reservation "r_mem_f" 6
94   (and (eq_attr "model_wbuf" "no")
95     (and (eq_attr "fpu" "fpa") (eq_attr "type" "r_mem_f")))
96   "core*6")
98 (define_insn_reservation "f_mem_r" 7
99   (and (eq_attr "fpu" "fpa") (eq_attr "type" "f_mem_r"))
100   "core*7")
103 (define_insn "*addsf3_fpa"
104   [(set (match_operand:SF          0 "s_register_operand" "=f,f")
105         (plus:SF (match_operand:SF 1 "s_register_operand" "%f,f")
106                  (match_operand:SF 2 "arm_float_add_operand"    "fG,H")))]
107   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
108   "@
109    adf%?s\\t%0, %1, %2
110    suf%?s\\t%0, %1, #%N2"
111   [(set_attr "type" "farith")
112    (set_attr "predicable" "yes")]
115 (define_insn "*adddf3_fpa"
116   [(set (match_operand:DF          0 "s_register_operand" "=f,f")
117         (plus:DF (match_operand:DF 1 "s_register_operand" "%f,f")
118                  (match_operand:DF 2 "arm_float_add_operand"    "fG,H")))]
119   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
120   "@
121    adf%?d\\t%0, %1, %2
122    suf%?d\\t%0, %1, #%N2"
123   [(set_attr "type" "farith")
124    (set_attr "predicable" "yes")]
127 (define_insn "*adddf_esfdf_df_fpa"
128   [(set (match_operand:DF           0 "s_register_operand" "=f,f")
129         (plus:DF (float_extend:DF
130                   (match_operand:SF 1 "s_register_operand"  "f,f"))
131                  (match_operand:DF  2 "arm_float_add_operand"    "fG,H")))]
132   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
133   "@
134    adf%?d\\t%0, %1, %2
135    suf%?d\\t%0, %1, #%N2"
136   [(set_attr "type" "farith")
137    (set_attr "predicable" "yes")]
140 (define_insn "*adddf_df_esfdf_fpa"
141   [(set (match_operand:DF           0 "s_register_operand" "=f")
142         (plus:DF (match_operand:DF  1 "s_register_operand"  "f")
143                  (float_extend:DF
144                   (match_operand:SF 2 "s_register_operand"  "f"))))]
145   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
146   "adf%?d\\t%0, %1, %2"
147   [(set_attr "type" "farith")
148    (set_attr "predicable" "yes")]
151 (define_insn "*adddf_esfdf_esfdf_fpa"
152   [(set (match_operand:DF           0 "s_register_operand" "=f")
153         (plus:DF (float_extend:DF 
154                   (match_operand:SF 1 "s_register_operand" "f"))
155                  (float_extend:DF
156                   (match_operand:SF 2 "s_register_operand" "f"))))]
157   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
158   "adf%?d\\t%0, %1, %2"
159   [(set_attr "type" "farith")
160    (set_attr "predicable" "yes")]
163 (define_insn "*subsf3_fpa"
164   [(set (match_operand:SF 0 "s_register_operand" "=f,f")
165         (minus:SF (match_operand:SF 1 "arm_float_rhs_operand" "f,G")
166                   (match_operand:SF 2 "arm_float_rhs_operand" "fG,f")))]
167   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
168   "@
169    suf%?s\\t%0, %1, %2
170    rsf%?s\\t%0, %2, %1"
171   [(set_attr "type" "farith")]
174 (define_insn "*subdf3_fpa"
175   [(set (match_operand:DF           0 "s_register_operand" "=f,f")
176         (minus:DF (match_operand:DF 1 "arm_float_rhs_operand"     "f,G")
177                   (match_operand:DF 2 "arm_float_rhs_operand"    "fG,f")))]
178   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
179   "@
180    suf%?d\\t%0, %1, %2
181    rsf%?d\\t%0, %2, %1"
182   [(set_attr "type" "farith")
183    (set_attr "predicable" "yes")]
186 (define_insn "*subdf_esfdf_df_fpa"
187   [(set (match_operand:DF            0 "s_register_operand" "=f")
188         (minus:DF (float_extend:DF
189                    (match_operand:SF 1 "s_register_operand"  "f"))
190                   (match_operand:DF  2 "arm_float_rhs_operand"    "fG")))]
191   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
192   "suf%?d\\t%0, %1, %2"
193   [(set_attr "type" "farith")
194    (set_attr "predicable" "yes")]
197 (define_insn "*subdf_df_esfdf_fpa"
198   [(set (match_operand:DF 0 "s_register_operand" "=f,f")
199         (minus:DF (match_operand:DF 1 "arm_float_rhs_operand" "f,G")
200                   (float_extend:DF
201                    (match_operand:SF 2 "s_register_operand" "f,f"))))]
202   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
203   "@
204    suf%?d\\t%0, %1, %2
205    rsf%?d\\t%0, %2, %1"
206   [(set_attr "type" "farith")
207    (set_attr "predicable" "yes")]
210 (define_insn "*subdf_esfdf_esfdf_fpa"
211   [(set (match_operand:DF 0 "s_register_operand" "=f")
212         (minus:DF (float_extend:DF
213                    (match_operand:SF 1 "s_register_operand" "f"))
214                   (float_extend:DF
215                    (match_operand:SF 2 "s_register_operand" "f"))))]
216   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
217   "suf%?d\\t%0, %1, %2"
218   [(set_attr "type" "farith")
219    (set_attr "predicable" "yes")]
222 (define_insn "*mulsf3_fpa"
223   [(set (match_operand:SF 0 "s_register_operand" "=f")
224         (mult:SF (match_operand:SF 1 "s_register_operand" "f")
225                  (match_operand:SF 2 "arm_float_rhs_operand" "fG")))]
226   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
227   "fml%?s\\t%0, %1, %2"
228   [(set_attr "type" "ffmul")
229    (set_attr "predicable" "yes")]
232 (define_insn "*muldf3_fpa"
233   [(set (match_operand:DF 0 "s_register_operand" "=f")
234         (mult:DF (match_operand:DF 1 "s_register_operand" "f")
235                  (match_operand:DF 2 "arm_float_rhs_operand" "fG")))]
236   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
237   "muf%?d\\t%0, %1, %2"
238   [(set_attr "type" "fmul")
239    (set_attr "predicable" "yes")]
242 (define_insn "*muldf_esfdf_df_fpa"
243   [(set (match_operand:DF 0 "s_register_operand" "=f")
244         (mult:DF (float_extend:DF
245                   (match_operand:SF 1 "s_register_operand" "f"))
246                  (match_operand:DF 2 "arm_float_rhs_operand" "fG")))]
247   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
248   "muf%?d\\t%0, %1, %2"
249   [(set_attr "type" "fmul")
250    (set_attr "predicable" "yes")]
253 (define_insn "*muldf_df_esfdf_fpa"
254   [(set (match_operand:DF 0 "s_register_operand" "=f")
255         (mult:DF (match_operand:DF 1 "s_register_operand" "f")
256                  (float_extend:DF
257                   (match_operand:SF 2 "s_register_operand" "f"))))]
258   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
259   "muf%?d\\t%0, %1, %2"
260   [(set_attr "type" "fmul")
261    (set_attr "predicable" "yes")]
264 (define_insn "*muldf_esfdf_esfdf_fpa"
265   [(set (match_operand:DF 0 "s_register_operand" "=f")
266         (mult:DF
267          (float_extend:DF (match_operand:SF 1 "s_register_operand" "f"))
268          (float_extend:DF (match_operand:SF 2 "s_register_operand" "f"))))]
269   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
270   "muf%?d\\t%0, %1, %2"
271   [(set_attr "type" "fmul")
272    (set_attr "predicable" "yes")]
275 ;; Division insns
277 (define_insn "*divsf3_fpa"
278   [(set (match_operand:SF 0 "s_register_operand" "=f,f")
279         (div:SF (match_operand:SF 1 "arm_float_rhs_operand" "f,G")
280                 (match_operand:SF 2 "arm_float_rhs_operand" "fG,f")))]
281   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
282   "@
283    fdv%?s\\t%0, %1, %2
284    frd%?s\\t%0, %2, %1"
285   [(set_attr "type" "fdivs")
286    (set_attr "predicable" "yes")]
289 (define_insn "*divdf3_fpa"
290   [(set (match_operand:DF 0 "s_register_operand" "=f,f")
291         (div:DF (match_operand:DF 1 "arm_float_rhs_operand" "f,G")
292                 (match_operand:DF 2 "arm_float_rhs_operand" "fG,f")))]
293   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
294   "@
295    dvf%?d\\t%0, %1, %2
296    rdf%?d\\t%0, %2, %1"
297   [(set_attr "type" "fdivd")
298    (set_attr "predicable" "yes")]
301 (define_insn "*divdf_esfdf_df_fpa"
302   [(set (match_operand:DF 0 "s_register_operand" "=f")
303         (div:DF (float_extend:DF
304                  (match_operand:SF 1 "s_register_operand" "f"))
305                 (match_operand:DF 2 "arm_float_rhs_operand" "fG")))]
306   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
307   "dvf%?d\\t%0, %1, %2"
308   [(set_attr "type" "fdivd")
309    (set_attr "predicable" "yes")]
312 (define_insn "*divdf_df_esfdf_fpa"
313   [(set (match_operand:DF 0 "s_register_operand" "=f")
314         (div:DF (match_operand:DF 1 "arm_float_rhs_operand" "fG")
315                 (float_extend:DF
316                  (match_operand:SF 2 "s_register_operand" "f"))))]
317   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
318   "rdf%?d\\t%0, %2, %1"
319   [(set_attr "type" "fdivd")
320    (set_attr "predicable" "yes")]
323 (define_insn "*divdf_esfdf_esfdf_fpa"
324   [(set (match_operand:DF 0 "s_register_operand" "=f")
325         (div:DF (float_extend:DF
326                  (match_operand:SF 1 "s_register_operand" "f"))
327                 (float_extend:DF
328                  (match_operand:SF 2 "s_register_operand" "f"))))]
329   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
330   "dvf%?d\\t%0, %1, %2"
331   [(set_attr "type" "fdivd")
332    (set_attr "predicable" "yes")]
335 (define_insn "*modsf3_fpa"
336   [(set (match_operand:SF 0 "s_register_operand" "=f")
337         (mod:SF (match_operand:SF 1 "s_register_operand" "f")
338                 (match_operand:SF 2 "arm_float_rhs_operand" "fG")))]
339   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
340   "rmf%?s\\t%0, %1, %2"
341   [(set_attr "type" "fdivs")
342    (set_attr "predicable" "yes")]
345 (define_insn "*moddf3_fpa"
346   [(set (match_operand:DF 0 "s_register_operand" "=f")
347         (mod:DF (match_operand:DF 1 "s_register_operand" "f")
348                 (match_operand:DF 2 "arm_float_rhs_operand" "fG")))]
349   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
350   "rmf%?d\\t%0, %1, %2"
351   [(set_attr "type" "fdivd")
352    (set_attr "predicable" "yes")]
355 (define_insn "*moddf_esfdf_df_fpa"
356   [(set (match_operand:DF 0 "s_register_operand" "=f")
357         (mod:DF (float_extend:DF
358                  (match_operand:SF 1 "s_register_operand" "f"))
359                 (match_operand:DF 2 "arm_float_rhs_operand" "fG")))]
360   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
361   "rmf%?d\\t%0, %1, %2"
362   [(set_attr "type" "fdivd")
363    (set_attr "predicable" "yes")]
366 (define_insn "*moddf_df_esfdf_fpa"
367   [(set (match_operand:DF 0 "s_register_operand" "=f")
368         (mod:DF (match_operand:DF 1 "s_register_operand" "f")
369                 (float_extend:DF
370                  (match_operand:SF 2 "s_register_operand" "f"))))]
371   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
372   "rmf%?d\\t%0, %1, %2"
373   [(set_attr "type" "fdivd")
374    (set_attr "predicable" "yes")]
377 (define_insn "*moddf_esfdf_esfdf_fpa"
378   [(set (match_operand:DF 0 "s_register_operand" "=f")
379         (mod:DF (float_extend:DF
380                  (match_operand:SF 1 "s_register_operand" "f"))
381                 (float_extend:DF
382                  (match_operand:SF 2 "s_register_operand" "f"))))]
383   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
384   "rmf%?d\\t%0, %1, %2"
385   [(set_attr "type" "fdivd")
386    (set_attr "predicable" "yes")]
389 (define_insn "*negsf2_fpa"
390   [(set (match_operand:SF         0 "s_register_operand" "=f")
391         (neg:SF (match_operand:SF 1 "s_register_operand" "f")))]
392   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
393   "mnf%?s\\t%0, %1"
394   [(set_attr "type" "ffarith")
395    (set_attr "predicable" "yes")]
398 (define_insn "*negdf2_fpa"
399   [(set (match_operand:DF         0 "s_register_operand" "=f")
400         (neg:DF (match_operand:DF 1 "s_register_operand" "f")))]
401   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
402   "mnf%?d\\t%0, %1"
403   [(set_attr "type" "ffarith")
404    (set_attr "predicable" "yes")]
407 (define_insn "*negdf_esfdf_fpa"
408   [(set (match_operand:DF 0 "s_register_operand" "=f")
409         (neg:DF (float_extend:DF
410                  (match_operand:SF 1 "s_register_operand" "f"))))]
411   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
412   "mnf%?d\\t%0, %1"
413   [(set_attr "type" "ffarith")
414    (set_attr "predicable" "yes")]
417 (define_insn "*abssf2_fpa"
418   [(set (match_operand:SF          0 "s_register_operand" "=f")
419          (abs:SF (match_operand:SF 1 "s_register_operand" "f")))]
420   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
421   "abs%?s\\t%0, %1"
422   [(set_attr "type" "ffarith")
423    (set_attr "predicable" "yes")]
426 (define_insn "*absdf2_fpa"
427   [(set (match_operand:DF         0 "s_register_operand" "=f")
428         (abs:DF (match_operand:DF 1 "s_register_operand" "f")))]
429   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
430   "abs%?d\\t%0, %1"
431   [(set_attr "type" "ffarith")
432    (set_attr "predicable" "yes")]
435 (define_insn "*absdf_esfdf_fpa"
436   [(set (match_operand:DF 0 "s_register_operand" "=f")
437         (abs:DF (float_extend:DF
438                  (match_operand:SF 1 "s_register_operand" "f"))))]
439   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
440   "abs%?d\\t%0, %1"
441   [(set_attr "type" "ffarith")
442    (set_attr "predicable" "yes")]
445 (define_insn "*sqrtsf2_fpa"
446   [(set (match_operand:SF 0 "s_register_operand" "=f")
447         (sqrt:SF (match_operand:SF 1 "s_register_operand" "f")))]
448   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
449   "sqt%?s\\t%0, %1"
450   [(set_attr "type" "float_em")
451    (set_attr "predicable" "yes")]
454 (define_insn "*sqrtdf2_fpa"
455   [(set (match_operand:DF 0 "s_register_operand" "=f")
456         (sqrt:DF (match_operand:DF 1 "s_register_operand" "f")))]
457   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
458   "sqt%?d\\t%0, %1"
459   [(set_attr "type" "float_em")
460    (set_attr "predicable" "yes")]
463 (define_insn "*sqrtdf_esfdf_fpa"
464   [(set (match_operand:DF 0 "s_register_operand" "=f")
465         (sqrt:DF (float_extend:DF
466                   (match_operand:SF 1 "s_register_operand" "f"))))]
467   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
468   "sqt%?d\\t%0, %1"
469   [(set_attr "type" "float_em")
470    (set_attr "predicable" "yes")]
473 (define_insn "*floatsisf2_fpa"
474   [(set (match_operand:SF           0 "s_register_operand" "=f")
475         (float:SF (match_operand:SI 1 "s_register_operand" "r")))]
476   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
477   "flt%?s\\t%0, %1"
478   [(set_attr "type" "r_2_f")
479    (set_attr "predicable" "yes")]
482 (define_insn "*floatsidf2_fpa"
483   [(set (match_operand:DF           0 "s_register_operand" "=f")
484         (float:DF (match_operand:SI 1 "s_register_operand" "r")))]
485   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
486   "flt%?d\\t%0, %1"
487   [(set_attr "type" "r_2_f")
488    (set_attr "predicable" "yes")]
491 (define_insn "*fix_truncsfsi2_fpa"
492   [(set (match_operand:SI         0 "s_register_operand" "=r")
493         (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" "f"))))]
494   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
495   "fix%?z\\t%0, %1"
496   [(set_attr "type" "f_2_r")
497    (set_attr "predicable" "yes")]
500 (define_insn "*fix_truncdfsi2_fpa"
501   [(set (match_operand:SI         0 "s_register_operand" "=r")
502         (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" "f"))))]
503   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
504   "fix%?z\\t%0, %1"
505   [(set_attr "type" "f_2_r")
506    (set_attr "predicable" "yes")]
509 (define_insn "*truncdfsf2_fpa"
510   [(set (match_operand:SF 0 "s_register_operand" "=f")
511         (float_truncate:SF
512          (match_operand:DF 1 "s_register_operand" "f")))]
513   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
514   "mvf%?s\\t%0, %1"
515   [(set_attr "type" "ffarith")
516    (set_attr "predicable" "yes")]
519 (define_insn "*extendsfdf2_fpa"
520   [(set (match_operand:DF                  0 "s_register_operand" "=f")
521         (float_extend:DF (match_operand:SF 1 "s_register_operand"  "f")))]
522   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
523   "mvf%?d\\t%0, %1"
524   [(set_attr "type" "ffarith")
525    (set_attr "predicable" "yes")]
528 (define_insn "*movsf_fpa"
529   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f, m,f,r,r,r, m")
530         (match_operand:SF 1 "general_operand"      "fG,H,mE,f,r,f,r,mE,r"))]
531   "TARGET_ARM
532    && TARGET_HARD_FLOAT && TARGET_FPA
533    && (GET_CODE (operands[0]) != MEM
534        || register_operand (operands[1], SFmode))"
535   "@
536    mvf%?s\\t%0, %1
537    mnf%?s\\t%0, #%N1
538    ldf%?s\\t%0, %1
539    stf%?s\\t%1, %0
540    str%?\\t%1, [%|sp, #-4]!\;ldf%?s\\t%0, [%|sp], #4
541    stf%?s\\t%1, [%|sp, #-4]!\;ldr%?\\t%0, [%|sp], #4
542    mov%?\\t%0, %1
543    ldr%?\\t%0, %1\\t%@ float
544    str%?\\t%1, %0\\t%@ float"
545   [(set_attr "length" "4,4,4,4,8,8,4,4,4")
546    (set_attr "predicable" "yes")
547    (set_attr "type"
548          "ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r,*,load1,store1")
549    (set_attr "pool_range" "*,*,1024,*,*,*,*,4096,*")
550    (set_attr "neg_pool_range" "*,*,1012,*,*,*,*,4084,*")]
553 (define_insn "*movdf_fpa"
554   [(set (match_operand:DF 0 "nonimmediate_operand"
555                                                 "=r,Q,r,m,r, f, f,f, m,!f,!r")
556         (match_operand:DF 1 "general_operand"
557                                                 "Q, r,r,r,mF,fG,H,mF,f,r, f"))]
558   "TARGET_ARM
559    && TARGET_HARD_FLOAT && TARGET_FPA
560    && (GET_CODE (operands[0]) != MEM
561        || register_operand (operands[1], DFmode))"
562   "*
563   {
564   switch (which_alternative)
565     {
566     default:
567     case 0: return \"ldm%(ia%)\\t%m1, %M0\\t%@ double\";
568     case 1: return \"stm%(ia%)\\t%m0, %M1\\t%@ double\";
569     case 2: return \"#\";
570     case 3: case 4: return output_move_double (operands);
571     case 5: return \"mvf%?d\\t%0, %1\";
572     case 6: return \"mnf%?d\\t%0, #%N1\";
573     case 7: return \"ldf%?d\\t%0, %1\";
574     case 8: return \"stf%?d\\t%1, %0\";
575     case 9: return output_mov_double_fpa_from_arm (operands);
576     case 10: return output_mov_double_arm_from_fpa (operands);
577     }
578   }
579   "
580   [(set_attr "length" "4,4,8,8,8,4,4,4,4,8,8")
581    (set_attr "predicable" "yes")
582    (set_attr "type"
583     "load1,store2,*,store2,load1,ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r")
584    (set_attr "pool_range" "*,*,*,*,1020,*,*,1024,*,*,*")
585    (set_attr "neg_pool_range" "*,*,*,*,1008,*,*,1008,*,*,*")]
588 ;; We treat XFmode as meaning 'internal format'.  It's the right size and we
589 ;; don't use it for anything else.  We only support moving between FPA
590 ;; registers and moving an FPA register to/from memory.
591 (define_insn "*movxf_fpa"
592   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,f,m")
593         (match_operand:XF 1 "general_operand" "f,m,f"))]
594   "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA
595    && (register_operand (operands[0], XFmode)
596        || register_operand (operands[1], XFmode))"
597   "*
598   switch (which_alternative)
599     {
600     default:
601     case 0: return \"mvf%?e\\t%0, %1\";
602     case 1: if (arm_fpu_arch == FPUTYPE_FPA_EMU2)
603               return \"ldf%?e\\t%0, %1\";
604             return \"lfm%?\\t%0, 1, %1\";
605     case 2: if (arm_fpu_arch == FPUTYPE_FPA_EMU2)
606               return \"stf%?e\\t%1, %0\";
607             return \"sfm%?\\t%1, 1, %0\";
608     }
609   "
610   [(set_attr "length" "4,4,4")
611    (set_attr "predicable" "yes")
612    (set_attr "type" "ffarith,f_load,f_store")]
615 ;; stfs/ldfs always use a conditional infix.  This works around the
616 ;; ambiguity between "stf pl s" and "sftp ls".
617 (define_insn "*thumb2_movsf_fpa"
618   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f, m,f,r,r,r, m")
619         (match_operand:SF 1 "general_operand"      "fG,H,mE,f,r,f,r,mE,r"))]
620   "TARGET_THUMB2
621    && TARGET_HARD_FLOAT && TARGET_FPA
622    && (GET_CODE (operands[0]) != MEM
623        || register_operand (operands[1], SFmode))"
624   "@
625    mvf%?s\\t%0, %1
626    mnf%?s\\t%0, #%N1
627    ldf%?s\\t%0, %1
628    stf%?s\\t%1, %0
629    str%?\\t%1, [%|sp, #-4]!\;ldf%?s\\t%0, [%|sp], #4
630    stf%?s\\t%1, [%|sp, #-4]!\;ldr%?\\t%0, [%|sp], #4
631    mov%?\\t%0, %1 @bar
632    ldr%?\\t%0, %1\\t%@ float
633    str%?\\t%1, %0\\t%@ float"
634   [(set_attr "length" "4,4,4,4,8,8,4,4,4")
635    (set_attr "ce_count" "1,1,1,1,2,2,1,1,1")
636    (set_attr "predicable" "yes")
637    (set_attr "type"
638          "ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r,*,load1,store1")
639    (set_attr "pool_range" "*,*,1024,*,*,*,*,4096,*")
640    (set_attr "neg_pool_range" "*,*,1012,*,*,*,*,0,*")]
643 ;; Not predicable because we don't know the number of instructions.
644 (define_insn "*thumb2_movdf_fpa"
645   [(set (match_operand:DF 0 "nonimmediate_operand"
646                                                 "=r,Q,r,m,r, f, f,f, m,!f,!r")
647         (match_operand:DF 1 "general_operand"
648                                                 "Q, r,r,r,mF,fG,H,mF,f,r, f"))]
649   "TARGET_THUMB2
650    && TARGET_HARD_FLOAT && TARGET_FPA
651    && (GET_CODE (operands[0]) != MEM
652        || register_operand (operands[1], DFmode))"
653   "*
654   {
655   switch (which_alternative)
656     {
657     default:
658     case 0: return \"ldm%(ia%)\\t%m1, %M0\\t%@ double\";
659     case 1: return \"stm%(ia%)\\t%m0, %M1\\t%@ double\";
660     case 2: case 3: case 4: return output_move_double (operands);
661     case 5: return \"mvf%?d\\t%0, %1\";
662     case 6: return \"mnf%?d\\t%0, #%N1\";
663     case 7: return \"ldf%?d\\t%0, %1\";
664     case 8: return \"stf%?d\\t%1, %0\";
665     case 9: return output_mov_double_fpa_from_arm (operands);
666     case 10: return output_mov_double_arm_from_fpa (operands);
667     }
668   }
669   "
670   [(set_attr "length" "4,4,8,8,8,4,4,4,4,8,8")
671    (set_attr "type"
672     "load1,store2,*,store2,load1,ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r")
673    (set_attr "pool_range" "*,*,*,*,4092,*,*,1024,*,*,*")
674    (set_attr "neg_pool_range" "*,*,*,*,0,*,*,1020,*,*,*")]
677 ;; Saving and restoring the floating point registers in the prologue should
678 ;; be done in XFmode, even though we don't support that for anything else
679 ;; (Well, strictly it's 'internal representation', but that's effectively
680 ;; XFmode).
681 ;; Not predicable because we don't know the number of instructions.
683 (define_insn "*thumb2_movxf_fpa"
684   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,f,f,m,f,r,r")
685         (match_operand:XF 1 "general_operand" "fG,H,m,f,r,f,r"))]
686   "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_FPA && reload_completed"
687   "*
688   switch (which_alternative)
689     {
690     default:
691     case 0: return \"mvf%?e\\t%0, %1\";
692     case 1: return \"mnf%?e\\t%0, #%N1\";
693     case 2: return \"ldf%?e\\t%0, %1\";
694     case 3: return \"stf%?e\\t%1, %0\";
695     case 4: return output_mov_long_double_fpa_from_arm (operands);
696     case 5: return output_mov_long_double_arm_from_fpa (operands);
697     case 6: return output_mov_long_double_arm_from_arm (operands);
698     }
699   "
700   [(set_attr "length" "4,4,4,4,8,8,12")
701    (set_attr "type" "ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r,*")
702    (set_attr "pool_range" "*,*,1024,*,*,*,*")
703    (set_attr "neg_pool_range" "*,*,1004,*,*,*,*")]
706 (define_insn "*cmpsf_fpa"
707   [(set (reg:CCFP CC_REGNUM)
708         (compare:CCFP (match_operand:SF 0 "s_register_operand" "f,f")
709                       (match_operand:SF 1 "arm_float_add_operand" "fG,H")))]
710   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
711   "@
712    cmf%?\\t%0, %1
713    cnf%?\\t%0, #%N1"
714   [(set_attr "conds" "set")
715    (set_attr "type" "f_2_r")]
718 (define_insn "*cmpdf_fpa"
719   [(set (reg:CCFP CC_REGNUM)
720         (compare:CCFP (match_operand:DF 0 "s_register_operand" "f,f")
721                       (match_operand:DF 1 "arm_float_add_operand" "fG,H")))]
722   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
723   "@
724    cmf%?\\t%0, %1
725    cnf%?\\t%0, #%N1"
726   [(set_attr "conds" "set")
727    (set_attr "type" "f_2_r")]
730 (define_insn "*cmpesfdf_df_fpa"
731   [(set (reg:CCFP CC_REGNUM)
732         (compare:CCFP (float_extend:DF
733                        (match_operand:SF 0 "s_register_operand" "f,f"))
734                       (match_operand:DF 1 "arm_float_add_operand" "fG,H")))]
735   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
736   "@
737    cmf%?\\t%0, %1
738    cnf%?\\t%0, #%N1"
739   [(set_attr "conds" "set")
740    (set_attr "type" "f_2_r")]
743 (define_insn "*cmpdf_esfdf_fpa"
744   [(set (reg:CCFP CC_REGNUM)
745         (compare:CCFP (match_operand:DF 0 "s_register_operand" "f")
746                       (float_extend:DF
747                        (match_operand:SF 1 "s_register_operand" "f"))))]
748   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
749   "cmf%?\\t%0, %1"
750   [(set_attr "conds" "set")
751    (set_attr "type" "f_2_r")]
754 (define_insn "*cmpsf_trap_fpa"
755   [(set (reg:CCFPE CC_REGNUM)
756         (compare:CCFPE (match_operand:SF 0 "s_register_operand" "f,f")
757                        (match_operand:SF 1 "arm_float_add_operand" "fG,H")))]
758   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
759   "@
760    cmf%?e\\t%0, %1
761    cnf%?e\\t%0, #%N1"
762   [(set_attr "conds" "set")
763    (set_attr "type" "f_2_r")]
766 (define_insn "*cmpdf_trap_fpa"
767   [(set (reg:CCFPE CC_REGNUM)
768         (compare:CCFPE (match_operand:DF 0 "s_register_operand" "f,f")
769                        (match_operand:DF 1 "arm_float_add_operand" "fG,H")))]
770   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
771   "@
772    cmf%?e\\t%0, %1
773    cnf%?e\\t%0, #%N1"
774   [(set_attr "conds" "set")
775    (set_attr "type" "f_2_r")]
778 (define_insn "*cmp_esfdf_df_trap_fpa"
779   [(set (reg:CCFPE CC_REGNUM)
780         (compare:CCFPE (float_extend:DF
781                         (match_operand:SF 0 "s_register_operand" "f,f"))
782                        (match_operand:DF 1 "arm_float_add_operand" "fG,H")))]
783   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
784   "@
785    cmf%?e\\t%0, %1
786    cnf%?e\\t%0, #%N1"
787   [(set_attr "conds" "set")
788    (set_attr "type" "f_2_r")]
791 (define_insn "*cmp_df_esfdf_trap_fpa"
792   [(set (reg:CCFPE CC_REGNUM)
793         (compare:CCFPE (match_operand:DF 0 "s_register_operand" "f")
794                        (float_extend:DF
795                         (match_operand:SF 1 "s_register_operand" "f"))))]
796   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
797   "cmf%?e\\t%0, %1"
798   [(set_attr "conds" "set")
799    (set_attr "type" "f_2_r")]
802 (define_insn "*movsfcc_fpa"
803   [(set (match_operand:SF 0 "s_register_operand" "=f,f,f,f,f,f,f,f")
804         (if_then_else:SF
805          (match_operator 3 "arm_comparison_operator" 
806           [(match_operand 4 "cc_register" "") (const_int 0)])
807          (match_operand:SF 1 "arm_float_add_operand" "0,0,fG,H,fG,fG,H,H")
808          (match_operand:SF 2 "arm_float_add_operand" "fG,H,0,0,fG,H,fG,H")))]
809   "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
810   "@
811    mvf%D3s\\t%0, %2
812    mnf%D3s\\t%0, #%N2
813    mvf%d3s\\t%0, %1
814    mnf%d3s\\t%0, #%N1
815    mvf%d3s\\t%0, %1\;mvf%D3s\\t%0, %2
816    mvf%d3s\\t%0, %1\;mnf%D3s\\t%0, #%N2
817    mnf%d3s\\t%0, #%N1\;mvf%D3s\\t%0, %2
818    mnf%d3s\\t%0, #%N1\;mnf%D3s\\t%0, #%N2"
819   [(set_attr "length" "4,4,4,4,8,8,8,8")
820    (set_attr "type" "ffarith")
821    (set_attr "conds" "use")]
824 (define_insn "*movdfcc_fpa"
825   [(set (match_operand:DF 0 "s_register_operand" "=f,f,f,f,f,f,f,f")
826         (if_then_else:DF
827          (match_operator 3 "arm_comparison_operator"
828           [(match_operand 4 "cc_register" "") (const_int 0)])
829          (match_operand:DF 1 "arm_float_add_operand" "0,0,fG,H,fG,fG,H,H")
830          (match_operand:DF 2 "arm_float_add_operand" "fG,H,0,0,fG,H,fG,H")))]
831   "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
832   "@
833    mvf%D3d\\t%0, %2
834    mnf%D3d\\t%0, #%N2
835    mvf%d3d\\t%0, %1
836    mnf%d3d\\t%0, #%N1
837    mvf%d3d\\t%0, %1\;mvf%D3d\\t%0, %2
838    mvf%d3d\\t%0, %1\;mnf%D3d\\t%0, #%N2
839    mnf%d3d\\t%0, #%N1\;mvf%D3d\\t%0, %2
840    mnf%d3d\\t%0, #%N1\;mnf%D3d\\t%0, #%N2"
841   [(set_attr "length" "4,4,4,4,8,8,8,8")
842    (set_attr "type" "ffarith")
843    (set_attr "conds" "use")]
846 (define_insn "*thumb2_movsfcc_fpa"
847   [(set (match_operand:SF 0 "s_register_operand" "=f,f,f,f,f,f,f,f")
848         (if_then_else:SF
849          (match_operator 3 "arm_comparison_operator" 
850           [(match_operand 4 "cc_register" "") (const_int 0)])
851          (match_operand:SF 1 "arm_float_add_operand" "0,0,fG,H,fG,fG,H,H")
852          (match_operand:SF 2 "arm_float_add_operand" "fG,H,0,0,fG,H,fG,H")))]
853   "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_FPA"
854   "@
855    it\\t%D3\;mvf%D3s\\t%0, %2
856    it\\t%D3\;mnf%D3s\\t%0, #%N2
857    it\\t%d3\;mvf%d3s\\t%0, %1
858    it\\t%d3\;mnf%d3s\\t%0, #%N1
859    ite\\t%d3\;mvf%d3s\\t%0, %1\;mvf%D3s\\t%0, %2
860    ite\\t%d3\;mvf%d3s\\t%0, %1\;mnf%D3s\\t%0, #%N2
861    ite\\t%d3\;mnf%d3s\\t%0, #%N1\;mvf%D3s\\t%0, %2
862    ite\\t%d3\;mnf%d3s\\t%0, #%N1\;mnf%D3s\\t%0, #%N2"
863   [(set_attr "length" "6,6,6,6,10,10,10,10")
864    (set_attr "type" "ffarith")
865    (set_attr "conds" "use")]
868 (define_insn "*thumb2_movdfcc_fpa"
869   [(set (match_operand:DF 0 "s_register_operand" "=f,f,f,f,f,f,f,f")
870         (if_then_else:DF
871          (match_operator 3 "arm_comparison_operator"
872           [(match_operand 4 "cc_register" "") (const_int 0)])
873          (match_operand:DF 1 "arm_float_add_operand" "0,0,fG,H,fG,fG,H,H")
874          (match_operand:DF 2 "arm_float_add_operand" "fG,H,0,0,fG,H,fG,H")))]
875   "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_FPA"
876   "@
877    it\\t%D3\;mvf%D3d\\t%0, %2
878    it\\t%D3\;mnf%D3d\\t%0, #%N2
879    it\\t%d3\;mvf%d3d\\t%0, %1
880    it\\t%d3\;mnf%d3d\\t%0, #%N1
881    ite\\t%d3\;mvf%d3d\\t%0, %1\;mvf%D3d\\t%0, %2
882    ite\\t%d3\;mvf%d3d\\t%0, %1\;mnf%D3d\\t%0, #%N2
883    ite\\t%d3\;mnf%d3d\\t%0, #%N1\;mvf%D3d\\t%0, %2
884    ite\\t%d3\;mnf%d3d\\t%0, #%N1\;mnf%D3d\\t%0, #%N2"
885   [(set_attr "length" "6,6,6,6,10,10,10,10")
886    (set_attr "type" "ffarith")
887    (set_attr "conds" "use")]