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  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, 51 Franklin Street, Fifth Floor,
23;; Boston, MA 02110-1301, 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 "arm_float_add_operand"    "fG,H")))]
104  "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
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 "arm_float_add_operand"    "fG,H")))]
116  "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
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 "arm_float_add_operand"    "fG,H")))]
129  "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
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 && TARGET_FPA"
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 && TARGET_FPA"
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 "arm_float_rhs_operand" "f,G")
163		  (match_operand:SF 2 "arm_float_rhs_operand" "fG,f")))]
164  "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
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 "arm_float_rhs_operand"     "f,G")
174		  (match_operand:DF 2 "arm_float_rhs_operand"    "fG,f")))]
175  "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
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 "arm_float_rhs_operand"    "fG")))]
188  "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
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 "arm_float_rhs_operand" "f,G")
197		  (float_extend:DF
198		   (match_operand:SF 2 "s_register_operand" "f,f"))))]
199  "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
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 && TARGET_FPA"
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 "arm_float_rhs_operand" "fG")))]
223  "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
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 "arm_float_rhs_operand" "fG")))]
233  "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
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 "arm_float_rhs_operand" "fG")))]
244  "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
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 && TARGET_FPA"
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 && TARGET_FPA"
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 "arm_float_rhs_operand" "f,G")
277		(match_operand:SF 2 "arm_float_rhs_operand" "fG,f")))]
278  "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
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 "arm_float_rhs_operand" "f,G")
289		(match_operand:DF 2 "arm_float_rhs_operand" "fG,f")))]
290  "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
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 "arm_float_rhs_operand" "fG")))]
303  "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
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 "arm_float_rhs_operand" "fG")
312		(float_extend:DF
313		 (match_operand:SF 2 "s_register_operand" "f"))))]
314  "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
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 && TARGET_FPA"
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 "arm_float_rhs_operand" "fG")))]
336  "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
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 "arm_float_rhs_operand" "fG")))]
346  "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
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 "arm_float_rhs_operand" "fG")))]
357  "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
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 && TARGET_FPA"
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 && TARGET_FPA"
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 && TARGET_FPA"
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 && TARGET_FPA"
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 && TARGET_FPA"
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 && TARGET_FPA"
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 && TARGET_FPA"
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 && TARGET_FPA"
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 && TARGET_FPA"
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 && TARGET_FPA"
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 && TARGET_FPA"
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 && TARGET_FPA"
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 && TARGET_FPA"
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 && TARGET_FPA"
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 && TARGET_FPA"
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 && TARGET_FPA"
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 && TARGET_FPA"
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 && TARGET_FPA
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,*,load1,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 && TARGET_FPA
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: return \"#\";
567    case 3: case 4: return output_move_double (operands);
568    case 5: return \"mvf%?d\\t%0, %1\";
569    case 6: return \"mnf%?d\\t%0, #%N1\";
570    case 7: return \"ldf%?d\\t%0, %1\";
571    case 8: return \"stf%?d\\t%1, %0\";
572    case 9: return output_mov_double_fpa_from_arm (operands);
573    case 10: return output_mov_double_arm_from_fpa (operands);
574    }
575  }
576  "
577  [(set_attr "length" "4,4,8,8,8,4,4,4,4,8,8")
578   (set_attr "predicable" "yes")
579   (set_attr "type"
580    "load1,store2,*,store2,load1,ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r")
581   (set_attr "pool_range" "*,*,*,*,1020,*,*,1024,*,*,*")
582   (set_attr "neg_pool_range" "*,*,*,*,1008,*,*,1008,*,*,*")]
583)
584
585;; We treat XFmode as meaning 'internal format'.  It's the right size and we
586;; don't use it for anything else.  We only support moving between FPA
587;; registers and moving an FPA register to/from memory.
588(define_insn "*movxf_fpa"
589  [(set (match_operand:XF 0 "nonimmediate_operand" "=f,f,m")
590	(match_operand:XF 1 "general_operand" "f,m,f"))]
591  "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA
592   && (register_operand (operands[0], XFmode)
593       || register_operand (operands[1], XFmode))"
594  "*
595  switch (which_alternative)
596    {
597    default:
598    case 0: return \"mvf%?e\\t%0, %1\";
599    case 1: if (arm_fpu_arch == FPUTYPE_FPA_EMU2)
600	      return \"ldf%?e\\t%0, %1\";
601	    return \"lfm%?\\t%0, 1, %1\";
602    case 2: if (arm_fpu_arch == FPUTYPE_FPA_EMU2)
603	      return \"stf%?e\\t%1, %0\";
604	    return \"sfm%?\\t%1, 1, %0\";
605    }
606  "
607  [(set_attr "length" "4,4,4")
608   (set_attr "predicable" "yes")
609   (set_attr "type" "ffarith,f_load,f_store")]
610)
611
612(define_insn "*cmpsf_fpa"
613  [(set (reg:CCFP CC_REGNUM)
614	(compare:CCFP (match_operand:SF 0 "s_register_operand" "f,f")
615		      (match_operand:SF 1 "arm_float_add_operand" "fG,H")))]
616  "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
617  "@
618   cmf%?\\t%0, %1
619   cnf%?\\t%0, #%N1"
620  [(set_attr "conds" "set")
621   (set_attr "type" "f_2_r")]
622)
623
624(define_insn "*cmpdf_fpa"
625  [(set (reg:CCFP CC_REGNUM)
626	(compare:CCFP (match_operand:DF 0 "s_register_operand" "f,f")
627		      (match_operand:DF 1 "arm_float_add_operand" "fG,H")))]
628  "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
629  "@
630   cmf%?\\t%0, %1
631   cnf%?\\t%0, #%N1"
632  [(set_attr "conds" "set")
633   (set_attr "type" "f_2_r")]
634)
635
636(define_insn "*cmpesfdf_df_fpa"
637  [(set (reg:CCFP CC_REGNUM)
638	(compare:CCFP (float_extend:DF
639		       (match_operand:SF 0 "s_register_operand" "f,f"))
640		      (match_operand:DF 1 "arm_float_add_operand" "fG,H")))]
641  "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
642  "@
643   cmf%?\\t%0, %1
644   cnf%?\\t%0, #%N1"
645  [(set_attr "conds" "set")
646   (set_attr "type" "f_2_r")]
647)
648
649(define_insn "*cmpdf_esfdf_fpa"
650  [(set (reg:CCFP CC_REGNUM)
651	(compare:CCFP (match_operand:DF 0 "s_register_operand" "f")
652		      (float_extend:DF
653		       (match_operand:SF 1 "s_register_operand" "f"))))]
654  "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
655  "cmf%?\\t%0, %1"
656  [(set_attr "conds" "set")
657   (set_attr "type" "f_2_r")]
658)
659
660(define_insn "*cmpsf_trap_fpa"
661  [(set (reg:CCFPE CC_REGNUM)
662	(compare:CCFPE (match_operand:SF 0 "s_register_operand" "f,f")
663		       (match_operand:SF 1 "arm_float_add_operand" "fG,H")))]
664  "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
665  "@
666   cmf%?e\\t%0, %1
667   cnf%?e\\t%0, #%N1"
668  [(set_attr "conds" "set")
669   (set_attr "type" "f_2_r")]
670)
671
672(define_insn "*cmpdf_trap_fpa"
673  [(set (reg:CCFPE CC_REGNUM)
674	(compare:CCFPE (match_operand:DF 0 "s_register_operand" "f,f")
675		       (match_operand:DF 1 "arm_float_add_operand" "fG,H")))]
676  "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
677  "@
678   cmf%?e\\t%0, %1
679   cnf%?e\\t%0, #%N1"
680  [(set_attr "conds" "set")
681   (set_attr "type" "f_2_r")]
682)
683
684(define_insn "*cmp_esfdf_df_trap_fpa"
685  [(set (reg:CCFPE CC_REGNUM)
686	(compare:CCFPE (float_extend:DF
687			(match_operand:SF 0 "s_register_operand" "f,f"))
688		       (match_operand:DF 1 "arm_float_add_operand" "fG,H")))]
689  "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
690  "@
691   cmf%?e\\t%0, %1
692   cnf%?e\\t%0, #%N1"
693  [(set_attr "conds" "set")
694   (set_attr "type" "f_2_r")]
695)
696
697(define_insn "*cmp_df_esfdf_trap_fpa"
698  [(set (reg:CCFPE CC_REGNUM)
699	(compare:CCFPE (match_operand:DF 0 "s_register_operand" "f")
700		       (float_extend:DF
701			(match_operand:SF 1 "s_register_operand" "f"))))]
702  "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
703  "cmf%?e\\t%0, %1"
704  [(set_attr "conds" "set")
705   (set_attr "type" "f_2_r")]
706)
707
708(define_insn "*movsfcc_fpa"
709  [(set (match_operand:SF 0 "s_register_operand" "=f,f,f,f,f,f,f,f")
710	(if_then_else:SF
711	 (match_operator 3 "arm_comparison_operator" 
712	  [(match_operand 4 "cc_register" "") (const_int 0)])
713	 (match_operand:SF 1 "arm_float_add_operand" "0,0,fG,H,fG,fG,H,H")
714	 (match_operand:SF 2 "arm_float_add_operand" "fG,H,0,0,fG,H,fG,H")))]
715  "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
716  "@
717   mvf%D3s\\t%0, %2
718   mnf%D3s\\t%0, #%N2
719   mvf%d3s\\t%0, %1
720   mnf%d3s\\t%0, #%N1
721   mvf%d3s\\t%0, %1\;mvf%D3s\\t%0, %2
722   mvf%d3s\\t%0, %1\;mnf%D3s\\t%0, #%N2
723   mnf%d3s\\t%0, #%N1\;mvf%D3s\\t%0, %2
724   mnf%d3s\\t%0, #%N1\;mnf%D3s\\t%0, #%N2"
725  [(set_attr "length" "4,4,4,4,8,8,8,8")
726   (set_attr "type" "ffarith")
727   (set_attr "conds" "use")]
728)
729
730(define_insn "*movdfcc_fpa"
731  [(set (match_operand:DF 0 "s_register_operand" "=f,f,f,f,f,f,f,f")
732	(if_then_else:DF
733	 (match_operator 3 "arm_comparison_operator"
734	  [(match_operand 4 "cc_register" "") (const_int 0)])
735	 (match_operand:DF 1 "arm_float_add_operand" "0,0,fG,H,fG,fG,H,H")
736	 (match_operand:DF 2 "arm_float_add_operand" "fG,H,0,0,fG,H,fG,H")))]
737  "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
738  "@
739   mvf%D3d\\t%0, %2
740   mnf%D3d\\t%0, #%N2
741   mvf%d3d\\t%0, %1
742   mnf%d3d\\t%0, #%N1
743   mvf%d3d\\t%0, %1\;mvf%D3d\\t%0, %2
744   mvf%d3d\\t%0, %1\;mnf%D3d\\t%0, #%N2
745   mnf%d3d\\t%0, #%N1\;mvf%D3d\\t%0, %2
746   mnf%d3d\\t%0, #%N1\;mnf%D3d\\t%0, #%N2"
747  [(set_attr "length" "4,4,4,4,8,8,8,8")
748   (set_attr "type" "ffarith")
749   (set_attr "conds" "use")]
750)
751