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  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).
7
8;; This file is part of GCC.
9
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 2, or (at your
13;; option) any later version.
14
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.
19
20;; You should have received a copy of the GNU General Public License
21;; along with GCC; see the file COPYING.  If not, write to
22;; the Free Software Foundation, 59 Temple Place - Suite 330,
23;; Boston, MA 02111-1307, USA.
24
25;; FPA automaton.
26(define_automaton "armfp")
27
28;; Floating point unit (FPA)
29(define_cpu_unit "fpa" "armfp")
30
31; The fpa10 doesn't really have a memory read unit, but it can start
32; to speculatively execute the instruction in the pipeline, provided
33; the data is already loaded, so pretend reads have a delay of 2 (and
34; that the pipeline is infinite).
35(define_cpu_unit "fpa_mem" "arm")
36
37(define_insn_reservation "fdivx" 71
38  (and (eq_attr "fpu" "fpa")
39       (eq_attr "type" "fdivx"))
40  "core+fpa*69")
41
42(define_insn_reservation "fdivd" 59
43  (and (eq_attr "fpu" "fpa")
44       (eq_attr "type" "fdivd"))
45  "core+fpa*57")
46
47(define_insn_reservation "fdivs" 31
48  (and (eq_attr "fpu" "fpa")
49       (eq_attr "type" "fdivs"))
50  "core+fpa*29")
51
52(define_insn_reservation "fmul" 9
53  (and (eq_attr "fpu" "fpa")
54       (eq_attr "type" "fmul"))
55  "core+fpa*7")
56
57(define_insn_reservation "ffmul" 6
58  (and (eq_attr "fpu" "fpa")
59       (eq_attr "type" "ffmul"))
60  "core+fpa*4")
61
62(define_insn_reservation "farith" 4
63  (and (eq_attr "fpu" "fpa")
64       (eq_attr "type" "farith"))
65  "core+fpa*2")
66
67(define_insn_reservation "ffarith" 2
68  (and (eq_attr "fpu" "fpa")
69       (eq_attr "type" "ffarith"))
70  "core+fpa*2")
71
72(define_insn_reservation "r_2_f" 5
73  (and (eq_attr "fpu" "fpa")
74       (eq_attr "type" "r_2_f"))
75  "core+fpa*3")
76
77(define_insn_reservation "f_2_r" 1
78  (and (eq_attr "fpu" "fpa")
79       (eq_attr "type" "f_2_r"))
80  "core+fpa*2")
81
82(define_insn_reservation "f_load" 3
83  (and (eq_attr "fpu" "fpa") (eq_attr "type" "f_load"))
84  "fpa_mem+core*3")
85
86(define_insn_reservation "f_store" 4
87  (and (eq_attr "fpu" "fpa") (eq_attr "type" "f_store"))
88  "core*4")
89
90(define_insn_reservation "r_mem_f" 6
91  (and (eq_attr "model_wbuf" "no")
92    (and (eq_attr "fpu" "fpa") (eq_attr "type" "r_mem_f")))
93  "core*6")
94
95(define_insn_reservation "f_mem_r" 7
96  (and (eq_attr "fpu" "fpa") (eq_attr "type" "f_mem_r"))
97  "core*7")
98
99
100(define_insn "*addsf3_fpa"
101  [(set (match_operand:SF          0 "s_register_operand" "=f,f")
102	(plus:SF (match_operand:SF 1 "s_register_operand" "%f,f")
103		 (match_operand:SF 2 "fpa_add_operand"    "fG,H")))]
104  "TARGET_ARM && TARGET_HARD_FLOAT"
105  "@
106   adf%?s\\t%0, %1, %2
107   suf%?s\\t%0, %1, #%N2"
108  [(set_attr "type" "farith")
109   (set_attr "predicable" "yes")]
110)
111
112(define_insn "*adddf3_fpa"
113  [(set (match_operand:DF          0 "s_register_operand" "=f,f")
114	(plus:DF (match_operand:DF 1 "s_register_operand" "%f,f")
115		 (match_operand:DF 2 "fpa_add_operand"    "fG,H")))]
116  "TARGET_ARM && TARGET_HARD_FLOAT"
117  "@
118   adf%?d\\t%0, %1, %2
119   suf%?d\\t%0, %1, #%N2"
120  [(set_attr "type" "farith")
121   (set_attr "predicable" "yes")]
122)
123
124(define_insn "*adddf_esfdf_df_fpa"
125  [(set (match_operand:DF           0 "s_register_operand" "=f,f")
126	(plus:DF (float_extend:DF
127		  (match_operand:SF 1 "s_register_operand"  "f,f"))
128		 (match_operand:DF  2 "fpa_add_operand"    "fG,H")))]
129  "TARGET_ARM && TARGET_HARD_FLOAT"
130  "@
131   adf%?d\\t%0, %1, %2
132   suf%?d\\t%0, %1, #%N2"
133  [(set_attr "type" "farith")
134   (set_attr "predicable" "yes")]
135)
136
137(define_insn "*adddf_df_esfdf_fpa"
138  [(set (match_operand:DF           0 "s_register_operand" "=f")
139	(plus:DF (match_operand:DF  1 "s_register_operand"  "f")
140		 (float_extend:DF
141		  (match_operand:SF 2 "s_register_operand"  "f"))))]
142  "TARGET_ARM && TARGET_HARD_FLOAT"
143  "adf%?d\\t%0, %1, %2"
144  [(set_attr "type" "farith")
145   (set_attr "predicable" "yes")]
146)
147
148(define_insn "*adddf_esfdf_esfdf_fpa"
149  [(set (match_operand:DF           0 "s_register_operand" "=f")
150	(plus:DF (float_extend:DF
151		  (match_operand:SF 1 "s_register_operand" "f"))
152		 (float_extend:DF
153		  (match_operand:SF 2 "s_register_operand" "f"))))]
154  "TARGET_ARM && TARGET_HARD_FLOAT"
155  "adf%?d\\t%0, %1, %2"
156  [(set_attr "type" "farith")
157   (set_attr "predicable" "yes")]
158)
159
160(define_insn "*subsf3_fpa"
161  [(set (match_operand:SF 0 "s_register_operand" "=f,f")
162	(minus:SF (match_operand:SF 1 "fpa_rhs_operand" "f,G")
163		  (match_operand:SF 2 "fpa_rhs_operand" "fG,f")))]
164  "TARGET_ARM && TARGET_HARD_FLOAT"
165  "@
166   suf%?s\\t%0, %1, %2
167   rsf%?s\\t%0, %2, %1"
168  [(set_attr "type" "farith")]
169)
170
171(define_insn "*subdf3_fpa"
172  [(set (match_operand:DF           0 "s_register_operand" "=f,f")
173	(minus:DF (match_operand:DF 1 "fpa_rhs_operand"     "f,G")
174		  (match_operand:DF 2 "fpa_rhs_operand"    "fG,f")))]
175  "TARGET_ARM && TARGET_HARD_FLOAT"
176  "@
177   suf%?d\\t%0, %1, %2
178   rsf%?d\\t%0, %2, %1"
179  [(set_attr "type" "farith")
180   (set_attr "predicable" "yes")]
181)
182
183(define_insn "*subdf_esfdf_df_fpa"
184  [(set (match_operand:DF            0 "s_register_operand" "=f")
185	(minus:DF (float_extend:DF
186		   (match_operand:SF 1 "s_register_operand"  "f"))
187		  (match_operand:DF  2 "fpa_rhs_operand"    "fG")))]
188  "TARGET_ARM && TARGET_HARD_FLOAT"
189  "suf%?d\\t%0, %1, %2"
190  [(set_attr "type" "farith")
191   (set_attr "predicable" "yes")]
192)
193
194(define_insn "*subdf_df_esfdf_fpa"
195  [(set (match_operand:DF 0 "s_register_operand" "=f,f")
196	(minus:DF (match_operand:DF 1 "fpa_rhs_operand" "f,G")
197		  (float_extend:DF
198		   (match_operand:SF 2 "s_register_operand" "f,f"))))]
199  "TARGET_ARM && TARGET_HARD_FLOAT"
200  "@
201   suf%?d\\t%0, %1, %2
202   rsf%?d\\t%0, %2, %1"
203  [(set_attr "type" "farith")
204   (set_attr "predicable" "yes")]
205)
206
207(define_insn "*subdf_esfdf_esfdf_fpa"
208  [(set (match_operand:DF 0 "s_register_operand" "=f")
209	(minus:DF (float_extend:DF
210		   (match_operand:SF 1 "s_register_operand" "f"))
211		  (float_extend:DF
212		   (match_operand:SF 2 "s_register_operand" "f"))))]
213  "TARGET_ARM && TARGET_HARD_FLOAT"
214  "suf%?d\\t%0, %1, %2"
215  [(set_attr "type" "farith")
216   (set_attr "predicable" "yes")]
217)
218
219(define_insn "*mulsf3_fpa"
220  [(set (match_operand:SF 0 "s_register_operand" "=f")
221	(mult:SF (match_operand:SF 1 "s_register_operand" "f")
222		 (match_operand:SF 2 "fpa_rhs_operand" "fG")))]
223  "TARGET_ARM && TARGET_HARD_FLOAT"
224  "fml%?s\\t%0, %1, %2"
225  [(set_attr "type" "ffmul")
226   (set_attr "predicable" "yes")]
227)
228
229(define_insn "*muldf3_fpa"
230  [(set (match_operand:DF 0 "s_register_operand" "=f")
231	(mult:DF (match_operand:DF 1 "s_register_operand" "f")
232		 (match_operand:DF 2 "fpa_rhs_operand" "fG")))]
233  "TARGET_ARM && TARGET_HARD_FLOAT"
234  "muf%?d\\t%0, %1, %2"
235  [(set_attr "type" "fmul")
236   (set_attr "predicable" "yes")]
237)
238
239(define_insn "*muldf_esfdf_df_fpa"
240  [(set (match_operand:DF 0 "s_register_operand" "=f")
241	(mult:DF (float_extend:DF
242		  (match_operand:SF 1 "s_register_operand" "f"))
243		 (match_operand:DF 2 "fpa_rhs_operand" "fG")))]
244  "TARGET_ARM && TARGET_HARD_FLOAT"
245  "muf%?d\\t%0, %1, %2"
246  [(set_attr "type" "fmul")
247   (set_attr "predicable" "yes")]
248)
249
250(define_insn "*muldf_df_esfdf_fpa"
251  [(set (match_operand:DF 0 "s_register_operand" "=f")
252	(mult:DF (match_operand:DF 1 "s_register_operand" "f")
253		 (float_extend:DF
254		  (match_operand:SF 2 "s_register_operand" "f"))))]
255  "TARGET_ARM && TARGET_HARD_FLOAT"
256  "muf%?d\\t%0, %1, %2"
257  [(set_attr "type" "fmul")
258   (set_attr "predicable" "yes")]
259)
260
261(define_insn "*muldf_esfdf_esfdf_fpa"
262  [(set (match_operand:DF 0 "s_register_operand" "=f")
263	(mult:DF
264	 (float_extend:DF (match_operand:SF 1 "s_register_operand" "f"))
265	 (float_extend:DF (match_operand:SF 2 "s_register_operand" "f"))))]
266  "TARGET_ARM && TARGET_HARD_FLOAT"
267  "muf%?d\\t%0, %1, %2"
268  [(set_attr "type" "fmul")
269   (set_attr "predicable" "yes")]
270)
271
272;; Division insns
273
274(define_insn "*divsf3_fpa"
275  [(set (match_operand:SF 0 "s_register_operand" "=f,f")
276	(div:SF (match_operand:SF 1 "fpa_rhs_operand" "f,G")
277		(match_operand:SF 2 "fpa_rhs_operand" "fG,f")))]
278  "TARGET_ARM && TARGET_HARD_FLOAT"
279  "@
280   fdv%?s\\t%0, %1, %2
281   frd%?s\\t%0, %2, %1"
282  [(set_attr "type" "fdivs")
283   (set_attr "predicable" "yes")]
284)
285
286(define_insn "*divdf3_fpa"
287  [(set (match_operand:DF 0 "s_register_operand" "=f,f")
288	(div:DF (match_operand:DF 1 "fpa_rhs_operand" "f,G")
289		(match_operand:DF 2 "fpa_rhs_operand" "fG,f")))]
290  "TARGET_ARM && TARGET_HARD_FLOAT"
291  "@
292   dvf%?d\\t%0, %1, %2
293   rdf%?d\\t%0, %2, %1"
294  [(set_attr "type" "fdivd")
295   (set_attr "predicable" "yes")]
296)
297
298(define_insn "*divdf_esfdf_df_fpa"
299  [(set (match_operand:DF 0 "s_register_operand" "=f")
300	(div:DF (float_extend:DF
301		 (match_operand:SF 1 "s_register_operand" "f"))
302		(match_operand:DF 2 "fpa_rhs_operand" "fG")))]
303  "TARGET_ARM && TARGET_HARD_FLOAT"
304  "dvf%?d\\t%0, %1, %2"
305  [(set_attr "type" "fdivd")
306   (set_attr "predicable" "yes")]
307)
308
309(define_insn "*divdf_df_esfdf_fpa"
310  [(set (match_operand:DF 0 "s_register_operand" "=f")
311	(div:DF (match_operand:DF 1 "fpa_rhs_operand" "fG")
312		(float_extend:DF
313		 (match_operand:SF 2 "s_register_operand" "f"))))]
314  "TARGET_ARM && TARGET_HARD_FLOAT"
315  "rdf%?d\\t%0, %2, %1"
316  [(set_attr "type" "fdivd")
317   (set_attr "predicable" "yes")]
318)
319
320(define_insn "*divdf_esfdf_esfdf_fpa"
321  [(set (match_operand:DF 0 "s_register_operand" "=f")
322	(div:DF (float_extend:DF
323		 (match_operand:SF 1 "s_register_operand" "f"))
324		(float_extend:DF
325		 (match_operand:SF 2 "s_register_operand" "f"))))]
326  "TARGET_ARM && TARGET_HARD_FLOAT"
327  "dvf%?d\\t%0, %1, %2"
328  [(set_attr "type" "fdivd")
329   (set_attr "predicable" "yes")]
330)
331
332(define_insn "*modsf3_fpa"
333  [(set (match_operand:SF 0 "s_register_operand" "=f")
334	(mod:SF (match_operand:SF 1 "s_register_operand" "f")
335		(match_operand:SF 2 "fpa_rhs_operand" "fG")))]
336  "TARGET_ARM && TARGET_HARD_FLOAT"
337  "rmf%?s\\t%0, %1, %2"
338  [(set_attr "type" "fdivs")
339   (set_attr "predicable" "yes")]
340)
341
342(define_insn "*moddf3_fpa"
343  [(set (match_operand:DF 0 "s_register_operand" "=f")
344	(mod:DF (match_operand:DF 1 "s_register_operand" "f")
345		(match_operand:DF 2 "fpa_rhs_operand" "fG")))]
346  "TARGET_ARM && TARGET_HARD_FLOAT"
347  "rmf%?d\\t%0, %1, %2"
348  [(set_attr "type" "fdivd")
349   (set_attr "predicable" "yes")]
350)
351
352(define_insn "*moddf_esfdf_df_fpa"
353  [(set (match_operand:DF 0 "s_register_operand" "=f")
354	(mod:DF (float_extend:DF
355		 (match_operand:SF 1 "s_register_operand" "f"))
356		(match_operand:DF 2 "fpa_rhs_operand" "fG")))]
357  "TARGET_ARM && TARGET_HARD_FLOAT"
358  "rmf%?d\\t%0, %1, %2"
359  [(set_attr "type" "fdivd")
360   (set_attr "predicable" "yes")]
361)
362
363(define_insn "*moddf_df_esfdf_fpa"
364  [(set (match_operand:DF 0 "s_register_operand" "=f")
365	(mod:DF (match_operand:DF 1 "s_register_operand" "f")
366		(float_extend:DF
367		 (match_operand:SF 2 "s_register_operand" "f"))))]
368  "TARGET_ARM && TARGET_HARD_FLOAT"
369  "rmf%?d\\t%0, %1, %2"
370  [(set_attr "type" "fdivd")
371   (set_attr "predicable" "yes")]
372)
373
374(define_insn "*moddf_esfdf_esfdf_fpa"
375  [(set (match_operand:DF 0 "s_register_operand" "=f")
376	(mod:DF (float_extend:DF
377		 (match_operand:SF 1 "s_register_operand" "f"))
378		(float_extend:DF
379		 (match_operand:SF 2 "s_register_operand" "f"))))]
380  "TARGET_ARM && TARGET_HARD_FLOAT"
381  "rmf%?d\\t%0, %1, %2"
382  [(set_attr "type" "fdivd")
383   (set_attr "predicable" "yes")]
384)
385
386(define_insn "*negsf2_fpa"
387  [(set (match_operand:SF         0 "s_register_operand" "=f")
388	(neg:SF (match_operand:SF 1 "s_register_operand" "f")))]
389  "TARGET_ARM && TARGET_HARD_FLOAT"
390  "mnf%?s\\t%0, %1"
391  [(set_attr "type" "ffarith")
392   (set_attr "predicable" "yes")]
393)
394
395(define_insn "*negdf2_fpa"
396  [(set (match_operand:DF         0 "s_register_operand" "=f")
397	(neg:DF (match_operand:DF 1 "s_register_operand" "f")))]
398  "TARGET_ARM && TARGET_HARD_FLOAT"
399  "mnf%?d\\t%0, %1"
400  [(set_attr "type" "ffarith")
401   (set_attr "predicable" "yes")]
402)
403
404(define_insn "*negdf_esfdf_fpa"
405  [(set (match_operand:DF 0 "s_register_operand" "=f")
406	(neg:DF (float_extend:DF
407		 (match_operand:SF 1 "s_register_operand" "f"))))]
408  "TARGET_ARM && TARGET_HARD_FLOAT"
409  "mnf%?d\\t%0, %1"
410  [(set_attr "type" "ffarith")
411   (set_attr "predicable" "yes")]
412)
413
414(define_insn "*abssf2_fpa"
415  [(set (match_operand:SF          0 "s_register_operand" "=f")
416	 (abs:SF (match_operand:SF 1 "s_register_operand" "f")))]
417  "TARGET_ARM && TARGET_HARD_FLOAT"
418  "abs%?s\\t%0, %1"
419  [(set_attr "type" "ffarith")
420   (set_attr "predicable" "yes")]
421)
422
423(define_insn "*absdf2_fpa"
424  [(set (match_operand:DF         0 "s_register_operand" "=f")
425	(abs:DF (match_operand:DF 1 "s_register_operand" "f")))]
426  "TARGET_ARM && TARGET_HARD_FLOAT"
427  "abs%?d\\t%0, %1"
428  [(set_attr "type" "ffarith")
429   (set_attr "predicable" "yes")]
430)
431
432(define_insn "*absdf_esfdf_fpa"
433  [(set (match_operand:DF 0 "s_register_operand" "=f")
434	(abs:DF (float_extend:DF
435		 (match_operand:SF 1 "s_register_operand" "f"))))]
436  "TARGET_ARM && TARGET_HARD_FLOAT"
437  "abs%?d\\t%0, %1"
438  [(set_attr "type" "ffarith")
439   (set_attr "predicable" "yes")]
440)
441
442(define_insn "*sqrtsf2_fpa"
443  [(set (match_operand:SF 0 "s_register_operand" "=f")
444	(sqrt:SF (match_operand:SF 1 "s_register_operand" "f")))]
445  "TARGET_ARM && TARGET_HARD_FLOAT"
446  "sqt%?s\\t%0, %1"
447  [(set_attr "type" "float_em")
448   (set_attr "predicable" "yes")]
449)
450
451(define_insn "*sqrtdf2_fpa"
452  [(set (match_operand:DF 0 "s_register_operand" "=f")
453	(sqrt:DF (match_operand:DF 1 "s_register_operand" "f")))]
454  "TARGET_ARM && TARGET_HARD_FLOAT"
455  "sqt%?d\\t%0, %1"
456  [(set_attr "type" "float_em")
457   (set_attr "predicable" "yes")]
458)
459
460(define_insn "*sqrtdf_esfdf_fpa"
461  [(set (match_operand:DF 0 "s_register_operand" "=f")
462	(sqrt:DF (float_extend:DF
463		  (match_operand:SF 1 "s_register_operand" "f"))))]
464  "TARGET_ARM && TARGET_HARD_FLOAT"
465  "sqt%?d\\t%0, %1"
466  [(set_attr "type" "float_em")
467   (set_attr "predicable" "yes")]
468)
469
470(define_insn "*floatsisf2_fpa"
471  [(set (match_operand:SF           0 "s_register_operand" "=f")
472	(float:SF (match_operand:SI 1 "s_register_operand" "r")))]
473  "TARGET_ARM && TARGET_HARD_FLOAT"
474  "flt%?s\\t%0, %1"
475  [(set_attr "type" "r_2_f")
476   (set_attr "predicable" "yes")]
477)
478
479(define_insn "*floatsidf2_fpa"
480  [(set (match_operand:DF           0 "s_register_operand" "=f")
481	(float:DF (match_operand:SI 1 "s_register_operand" "r")))]
482  "TARGET_ARM && TARGET_HARD_FLOAT"
483  "flt%?d\\t%0, %1"
484  [(set_attr "type" "r_2_f")
485   (set_attr "predicable" "yes")]
486)
487
488(define_insn "*fix_truncsfsi2_fpa"
489  [(set (match_operand:SI         0 "s_register_operand" "=r")
490	(fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" "f"))))]
491  "TARGET_ARM && TARGET_HARD_FLOAT"
492  "fix%?z\\t%0, %1"
493  [(set_attr "type" "f_2_r")
494   (set_attr "predicable" "yes")]
495)
496
497(define_insn "*fix_truncdfsi2_fpa"
498  [(set (match_operand:SI         0 "s_register_operand" "=r")
499	(fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" "f"))))]
500  "TARGET_ARM && TARGET_HARD_FLOAT"
501  "fix%?z\\t%0, %1"
502  [(set_attr "type" "f_2_r")
503   (set_attr "predicable" "yes")]
504)
505
506(define_insn "*truncdfsf2_fpa"
507  [(set (match_operand:SF 0 "s_register_operand" "=f")
508	(float_truncate:SF
509	 (match_operand:DF 1 "s_register_operand" "f")))]
510  "TARGET_ARM && TARGET_HARD_FLOAT"
511  "mvf%?s\\t%0, %1"
512  [(set_attr "type" "ffarith")
513   (set_attr "predicable" "yes")]
514)
515
516(define_insn "*extendsfdf2_fpa"
517  [(set (match_operand:DF                  0 "s_register_operand" "=f")
518	(float_extend:DF (match_operand:SF 1 "s_register_operand"  "f")))]
519  "TARGET_ARM && TARGET_HARD_FLOAT"
520  "mvf%?d\\t%0, %1"
521  [(set_attr "type" "ffarith")
522   (set_attr "predicable" "yes")]
523)
524
525(define_insn "*movsf_fpa"
526  [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f, m,f,r,r,r, m")
527	(match_operand:SF 1 "general_operand"      "fG,H,mE,f,r,f,r,mE,r"))]
528  "TARGET_ARM
529   && TARGET_HARD_FLOAT
530   && (GET_CODE (operands[0]) != MEM
531       || register_operand (operands[1], SFmode))"
532  "@
533   mvf%?s\\t%0, %1
534   mnf%?s\\t%0, #%N1
535   ldf%?s\\t%0, %1
536   stf%?s\\t%1, %0
537   str%?\\t%1, [%|sp, #-4]!\;ldf%?s\\t%0, [%|sp], #4
538   stf%?s\\t%1, [%|sp, #-4]!\;ldr%?\\t%0, [%|sp], #4
539   mov%?\\t%0, %1
540   ldr%?\\t%0, %1\\t%@ float
541   str%?\\t%1, %0\\t%@ float"
542  [(set_attr "length" "4,4,4,4,8,8,4,4,4")
543   (set_attr "predicable" "yes")
544   (set_attr "type"
545	 "ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r,*,load,store1")
546   (set_attr "pool_range" "*,*,1024,*,*,*,*,4096,*")
547   (set_attr "neg_pool_range" "*,*,1012,*,*,*,*,4084,*")]
548)
549
550(define_insn "*movdf_fpa"
551  [(set (match_operand:DF 0 "nonimmediate_operand"
552						"=r,Q,r,m,r, f, f,f, m,!f,!r")
553	(match_operand:DF 1 "general_operand"
554						"Q, r,r,r,mF,fG,H,mF,f,r, f"))]
555  "TARGET_ARM
556   && TARGET_HARD_FLOAT
557   && (GET_CODE (operands[0]) != MEM
558       || register_operand (operands[1], DFmode))"
559  "*
560  {
561  switch (which_alternative)
562    {
563    default:
564    case 0: return \"ldm%?ia\\t%m1, %M0\\t%@ double\";
565    case 1: return \"stm%?ia\\t%m0, %M1\\t%@ double\";
566    case 2: case 3: case 4: return output_move_double (operands);
567    case 5: return \"mvf%?d\\t%0, %1\";
568    case 6: return \"mnf%?d\\t%0, #%N1\";
569    case 7: return \"ldf%?d\\t%0, %1\";
570    case 8: return \"stf%?d\\t%1, %0\";
571    case 9: return output_mov_double_fpa_from_arm (operands);
572    case 10: return output_mov_double_arm_from_fpa (operands);
573    }
574  }
575  "
576  [(set_attr "length" "4,4,8,8,8,4,4,4,4,8,8")
577   (set_attr "predicable" "yes")
578   (set_attr "type"
579    "load,store2,*,store2,load,ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r")
580   (set_attr "pool_range" "*,*,*,*,1020,*,*,1024,*,*,*")
581   (set_attr "neg_pool_range" "*,*,*,*,1008,*,*,1008,*,*,*")]
582)
583
584;; Saving and restoring the floating point registers in the prologue should
585;; be done in XFmode, even though we don't support that for anything else
586;; (Well, strictly it's 'internal representation', but that's effectively
587;; XFmode).
588
589(define_insn "*movxf_fpa"
590  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,f,f,m,f,r,r")
591	(match_operand:XF 1 "general_operand" "fG,H,m,f,r,f,r"))]
592  "TARGET_ARM && TARGET_HARD_FLOAT && reload_completed"
593  "*
594  switch (which_alternative)
595    {
596    default:
597    case 0: return \"mvf%?e\\t%0, %1\";
598    case 1: return \"mnf%?e\\t%0, #%N1\";
599    case 2: return \"ldf%?e\\t%0, %1\";
600    case 3: return \"stf%?e\\t%1, %0\";
601    case 4: return output_mov_long_double_fpa_from_arm (operands);
602    case 5: return output_mov_long_double_arm_from_fpa (operands);
603    case 6: return output_mov_long_double_arm_from_arm (operands);
604    }
605  "
606  [(set_attr "length" "4,4,4,4,8,8,12")
607   (set_attr "predicable" "yes")
608   (set_attr "type" "ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r,*")
609   (set_attr "pool_range" "*,*,1024,*,*,*,*")
610   (set_attr "neg_pool_range" "*,*,1004,*,*,*,*")]
611)
612
613(define_insn "*cmpsf_fpa"
614  [(set (reg:CCFP CC_REGNUM)
615	(compare:CCFP (match_operand:SF 0 "s_register_operand" "f,f")
616		      (match_operand:SF 1 "fpa_add_operand" "fG,H")))]
617  "TARGET_ARM && TARGET_HARD_FLOAT"
618  "@
619   cmf%?\\t%0, %1
620   cnf%?\\t%0, #%N1"
621  [(set_attr "conds" "set")
622   (set_attr "type" "f_2_r")]
623)
624
625(define_insn "*cmpdf_fpa"
626  [(set (reg:CCFP CC_REGNUM)
627	(compare:CCFP (match_operand:DF 0 "s_register_operand" "f,f")
628		      (match_operand:DF 1 "fpa_add_operand" "fG,H")))]
629  "TARGET_ARM && TARGET_HARD_FLOAT"
630  "@
631   cmf%?\\t%0, %1
632   cnf%?\\t%0, #%N1"
633  [(set_attr "conds" "set")
634   (set_attr "type" "f_2_r")]
635)
636
637(define_insn "*cmpesfdf_df_fpa"
638  [(set (reg:CCFP CC_REGNUM)
639	(compare:CCFP (float_extend:DF
640		       (match_operand:SF 0 "s_register_operand" "f,f"))
641		      (match_operand:DF 1 "fpa_add_operand" "fG,H")))]
642  "TARGET_ARM && TARGET_HARD_FLOAT"
643  "@
644   cmf%?\\t%0, %1
645   cnf%?\\t%0, #%N1"
646  [(set_attr "conds" "set")
647   (set_attr "type" "f_2_r")]
648)
649
650(define_insn "*cmpdf_esfdf_fpa"
651  [(set (reg:CCFP CC_REGNUM)
652	(compare:CCFP (match_operand:DF 0 "s_register_operand" "f")
653		      (float_extend:DF
654		       (match_operand:SF 1 "s_register_operand" "f"))))]
655  "TARGET_ARM && TARGET_HARD_FLOAT"
656  "cmf%?\\t%0, %1"
657  [(set_attr "conds" "set")
658   (set_attr "type" "f_2_r")]
659)
660
661(define_insn "*cmpsf_trap_fpa"
662  [(set (reg:CCFPE CC_REGNUM)
663	(compare:CCFPE (match_operand:SF 0 "s_register_operand" "f,f")
664		       (match_operand:SF 1 "fpa_add_operand" "fG,H")))]
665  "TARGET_ARM && TARGET_HARD_FLOAT"
666  "@
667   cmf%?e\\t%0, %1
668   cnf%?e\\t%0, #%N1"
669  [(set_attr "conds" "set")
670   (set_attr "type" "f_2_r")]
671)
672
673(define_insn "*cmpdf_trap_fpa"
674  [(set (reg:CCFPE CC_REGNUM)
675	(compare:CCFPE (match_operand:DF 0 "s_register_operand" "f,f")
676		       (match_operand:DF 1 "fpa_add_operand" "fG,H")))]
677  "TARGET_ARM && TARGET_HARD_FLOAT"
678  "@
679   cmf%?e\\t%0, %1
680   cnf%?e\\t%0, #%N1"
681  [(set_attr "conds" "set")
682   (set_attr "type" "f_2_r")]
683)
684
685(define_insn "*cmp_esfdf_df_trap_fpa"
686  [(set (reg:CCFPE CC_REGNUM)
687	(compare:CCFPE (float_extend:DF
688			(match_operand:SF 0 "s_register_operand" "f,f"))
689		       (match_operand:DF 1 "fpa_add_operand" "fG,H")))]
690  "TARGET_ARM && TARGET_HARD_FLOAT"
691  "@
692   cmf%?e\\t%0, %1
693   cnf%?e\\t%0, #%N1"
694  [(set_attr "conds" "set")
695   (set_attr "type" "f_2_r")]
696)
697
698(define_insn "*cmp_df_esfdf_trap_fpa"
699  [(set (reg:CCFPE CC_REGNUM)
700	(compare:CCFPE (match_operand:DF 0 "s_register_operand" "f")
701		       (float_extend:DF
702			(match_operand:SF 1 "s_register_operand" "f"))))]
703  "TARGET_ARM && TARGET_HARD_FLOAT"
704  "cmf%?e\\t%0, %1"
705  [(set_attr "conds" "set")
706   (set_attr "type" "f_2_r")]
707)
708
709(define_insn "*movsfcc_fpa"
710  [(set (match_operand:SF 0 "s_register_operand" "=f,f,f,f,f,f,f,f")
711	(if_then_else:SF
712	 (match_operator 3 "arm_comparison_operator"
713	  [(match_operand 4 "cc_register" "") (const_int 0)])
714	 (match_operand:SF 1 "fpa_add_operand" "0,0,fG,H,fG,fG,H,H")
715	 (match_operand:SF 2 "fpa_add_operand" "fG,H,0,0,fG,H,fG,H")))]
716  "TARGET_ARM && TARGET_HARD_FLOAT"
717  "@
718   mvf%D3s\\t%0, %2
719   mnf%D3s\\t%0, #%N2
720   mvf%d3s\\t%0, %1
721   mnf%d3s\\t%0, #%N1
722   mvf%d3s\\t%0, %1\;mvf%D3s\\t%0, %2
723   mvf%d3s\\t%0, %1\;mnf%D3s\\t%0, #%N2
724   mnf%d3s\\t%0, #%N1\;mvf%D3s\\t%0, %2
725   mnf%d3s\\t%0, #%N1\;mnf%D3s\\t%0, #%N2"
726  [(set_attr "length" "4,4,4,4,8,8,8,8")
727   (set_attr "type" "ffarith")
728   (set_attr "conds" "use")]
729)
730
731(define_insn "*movdfcc_fpa"
732  [(set (match_operand:DF 0 "s_register_operand" "=f,f,f,f,f,f,f,f")
733	(if_then_else:DF
734	 (match_operator 3 "arm_comparison_operator"
735	  [(match_operand 4 "cc_register" "") (const_int 0)])
736	 (match_operand:DF 1 "fpa_add_operand" "0,0,fG,H,fG,fG,H,H")
737	 (match_operand:DF 2 "fpa_add_operand" "fG,H,0,0,fG,H,fG,H")))]
738  "TARGET_ARM && TARGET_HARD_FLOAT"
739  "@
740   mvf%D3d\\t%0, %2
741   mnf%D3d\\t%0, #%N2
742   mvf%d3d\\t%0, %1
743   mnf%d3d\\t%0, #%N1
744   mvf%d3d\\t%0, %1\;mvf%D3d\\t%0, %2
745   mvf%d3d\\t%0, %1\;mnf%D3d\\t%0, #%N2
746   mnf%d3d\\t%0, #%N1\;mvf%D3d\\t%0, %2
747   mnf%d3d\\t%0, #%N1\;mnf%D3d\\t%0, #%N2"
748  [(set_attr "length" "4,4,4,4,8,8,8,8")
749   (set_attr "type" "ffarith")
750   (set_attr "conds" "use")]
751)
752
753