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 2, 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 COPYING. If not, write to
22 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, USA.
25 ;; Some FPA mnemonics are ambiguous between conditional infixes and
26 ;; conditional suffixes. All instructions use a conditional infix,
27 ;; even in unified assembly mode.
30 (define_automaton "armfp")
32 ;; Floating point unit (FPA)
33 (define_cpu_unit "fpa" "armfp")
35 ; The fpa10 doesn't really have a memory read unit, but it can start
36 ; to speculatively execute the instruction in the pipeline, provided
37 ; the data is already loaded, so pretend reads have a delay of 2 (and
38 ; that the pipeline is infinite).
39 (define_cpu_unit "fpa_mem" "arm")
41 (define_insn_reservation "fdivx" 71
42 (and (eq_attr "fpu" "fpa")
43 (eq_attr "type" "fdivx"))
46 (define_insn_reservation "fdivd" 59
47 (and (eq_attr "fpu" "fpa")
48 (eq_attr "type" "fdivd"))
51 (define_insn_reservation "fdivs" 31
52 (and (eq_attr "fpu" "fpa")
53 (eq_attr "type" "fdivs"))
56 (define_insn_reservation "fmul" 9
57 (and (eq_attr "fpu" "fpa")
58 (eq_attr "type" "fmul"))
61 (define_insn_reservation "ffmul" 6
62 (and (eq_attr "fpu" "fpa")
63 (eq_attr "type" "ffmul"))
66 (define_insn_reservation "farith" 4
67 (and (eq_attr "fpu" "fpa")
68 (eq_attr "type" "farith"))
71 (define_insn_reservation "ffarith" 2
72 (and (eq_attr "fpu" "fpa")
73 (eq_attr "type" "ffarith"))
76 (define_insn_reservation "r_2_f" 5
77 (and (eq_attr "fpu" "fpa")
78 (eq_attr "type" "r_2_f"))
81 (define_insn_reservation "f_2_r" 1
82 (and (eq_attr "fpu" "fpa")
83 (eq_attr "type" "f_2_r"))
86 (define_insn_reservation "f_load" 3
87 (and (eq_attr "fpu" "fpa") (eq_attr "type" "f_load"))
90 (define_insn_reservation "f_store" 4
91 (and (eq_attr "fpu" "fpa") (eq_attr "type" "f_store"))
94 (define_insn_reservation "r_mem_f" 6
95 (and (eq_attr "model_wbuf" "no")
96 (and (eq_attr "fpu" "fpa") (eq_attr "type" "r_mem_f")))
99 (define_insn_reservation "f_mem_r" 7
100 (and (eq_attr "fpu" "fpa") (eq_attr "type" "f_mem_r"))
104 (define_insn "*addsf3_fpa"
105 [(set (match_operand:SF 0 "s_register_operand" "=f,f")
106 (plus:SF (match_operand:SF 1 "s_register_operand" "%f,f")
107 (match_operand:SF 2 "arm_float_add_operand" "fG,H")))]
108 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
111 suf%?s\\t%0, %1, #%N2"
112 [(set_attr "type" "farith")
113 (set_attr "predicable" "yes")]
116 (define_insn "*adddf3_fpa"
117 [(set (match_operand:DF 0 "s_register_operand" "=f,f")
118 (plus:DF (match_operand:DF 1 "s_register_operand" "%f,f")
119 (match_operand:DF 2 "arm_float_add_operand" "fG,H")))]
120 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
123 suf%?d\\t%0, %1, #%N2"
124 [(set_attr "type" "farith")
125 (set_attr "predicable" "yes")]
128 (define_insn "*adddf_esfdf_df_fpa"
129 [(set (match_operand:DF 0 "s_register_operand" "=f,f")
130 (plus:DF (float_extend:DF
131 (match_operand:SF 1 "s_register_operand" "f,f"))
132 (match_operand:DF 2 "arm_float_add_operand" "fG,H")))]
133 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
136 suf%?d\\t%0, %1, #%N2"
137 [(set_attr "type" "farith")
138 (set_attr "predicable" "yes")]
141 (define_insn "*adddf_df_esfdf_fpa"
142 [(set (match_operand:DF 0 "s_register_operand" "=f")
143 (plus:DF (match_operand:DF 1 "s_register_operand" "f")
145 (match_operand:SF 2 "s_register_operand" "f"))))]
146 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
147 "adf%?d\\t%0, %1, %2"
148 [(set_attr "type" "farith")
149 (set_attr "predicable" "yes")]
152 (define_insn "*adddf_esfdf_esfdf_fpa"
153 [(set (match_operand:DF 0 "s_register_operand" "=f")
154 (plus:DF (float_extend:DF
155 (match_operand:SF 1 "s_register_operand" "f"))
157 (match_operand:SF 2 "s_register_operand" "f"))))]
158 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
159 "adf%?d\\t%0, %1, %2"
160 [(set_attr "type" "farith")
161 (set_attr "predicable" "yes")]
164 (define_insn "*subsf3_fpa"
165 [(set (match_operand:SF 0 "s_register_operand" "=f,f")
166 (minus:SF (match_operand:SF 1 "arm_float_rhs_operand" "f,G")
167 (match_operand:SF 2 "arm_float_rhs_operand" "fG,f")))]
168 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
172 [(set_attr "type" "farith")]
175 (define_insn "*subdf3_fpa"
176 [(set (match_operand:DF 0 "s_register_operand" "=f,f")
177 (minus:DF (match_operand:DF 1 "arm_float_rhs_operand" "f,G")
178 (match_operand:DF 2 "arm_float_rhs_operand" "fG,f")))]
179 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
183 [(set_attr "type" "farith")
184 (set_attr "predicable" "yes")]
187 (define_insn "*subdf_esfdf_df_fpa"
188 [(set (match_operand:DF 0 "s_register_operand" "=f")
189 (minus:DF (float_extend:DF
190 (match_operand:SF 1 "s_register_operand" "f"))
191 (match_operand:DF 2 "arm_float_rhs_operand" "fG")))]
192 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
193 "suf%?d\\t%0, %1, %2"
194 [(set_attr "type" "farith")
195 (set_attr "predicable" "yes")]
198 (define_insn "*subdf_df_esfdf_fpa"
199 [(set (match_operand:DF 0 "s_register_operand" "=f,f")
200 (minus:DF (match_operand:DF 1 "arm_float_rhs_operand" "f,G")
202 (match_operand:SF 2 "s_register_operand" "f,f"))))]
203 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
207 [(set_attr "type" "farith")
208 (set_attr "predicable" "yes")]
211 (define_insn "*subdf_esfdf_esfdf_fpa"
212 [(set (match_operand:DF 0 "s_register_operand" "=f")
213 (minus:DF (float_extend:DF
214 (match_operand:SF 1 "s_register_operand" "f"))
216 (match_operand:SF 2 "s_register_operand" "f"))))]
217 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
218 "suf%?d\\t%0, %1, %2"
219 [(set_attr "type" "farith")
220 (set_attr "predicable" "yes")]
223 (define_insn "*mulsf3_fpa"
224 [(set (match_operand:SF 0 "s_register_operand" "=f")
225 (mult:SF (match_operand:SF 1 "s_register_operand" "f")
226 (match_operand:SF 2 "arm_float_rhs_operand" "fG")))]
227 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
228 "fml%?s\\t%0, %1, %2"
229 [(set_attr "type" "ffmul")
230 (set_attr "predicable" "yes")]
233 (define_insn "*muldf3_fpa"
234 [(set (match_operand:DF 0 "s_register_operand" "=f")
235 (mult:DF (match_operand:DF 1 "s_register_operand" "f")
236 (match_operand:DF 2 "arm_float_rhs_operand" "fG")))]
237 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
238 "muf%?d\\t%0, %1, %2"
239 [(set_attr "type" "fmul")
240 (set_attr "predicable" "yes")]
243 (define_insn "*muldf_esfdf_df_fpa"
244 [(set (match_operand:DF 0 "s_register_operand" "=f")
245 (mult:DF (float_extend:DF
246 (match_operand:SF 1 "s_register_operand" "f"))
247 (match_operand:DF 2 "arm_float_rhs_operand" "fG")))]
248 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
249 "muf%?d\\t%0, %1, %2"
250 [(set_attr "type" "fmul")
251 (set_attr "predicable" "yes")]
254 (define_insn "*muldf_df_esfdf_fpa"
255 [(set (match_operand:DF 0 "s_register_operand" "=f")
256 (mult:DF (match_operand:DF 1 "s_register_operand" "f")
258 (match_operand:SF 2 "s_register_operand" "f"))))]
259 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
260 "muf%?d\\t%0, %1, %2"
261 [(set_attr "type" "fmul")
262 (set_attr "predicable" "yes")]
265 (define_insn "*muldf_esfdf_esfdf_fpa"
266 [(set (match_operand:DF 0 "s_register_operand" "=f")
268 (float_extend:DF (match_operand:SF 1 "s_register_operand" "f"))
269 (float_extend:DF (match_operand:SF 2 "s_register_operand" "f"))))]
270 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
271 "muf%?d\\t%0, %1, %2"
272 [(set_attr "type" "fmul")
273 (set_attr "predicable" "yes")]
278 (define_insn "*divsf3_fpa"
279 [(set (match_operand:SF 0 "s_register_operand" "=f,f")
280 (div:SF (match_operand:SF 1 "arm_float_rhs_operand" "f,G")
281 (match_operand:SF 2 "arm_float_rhs_operand" "fG,f")))]
282 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
286 [(set_attr "type" "fdivs")
287 (set_attr "predicable" "yes")]
290 (define_insn "*divdf3_fpa"
291 [(set (match_operand:DF 0 "s_register_operand" "=f,f")
292 (div:DF (match_operand:DF 1 "arm_float_rhs_operand" "f,G")
293 (match_operand:DF 2 "arm_float_rhs_operand" "fG,f")))]
294 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
298 [(set_attr "type" "fdivd")
299 (set_attr "predicable" "yes")]
302 (define_insn "*divdf_esfdf_df_fpa"
303 [(set (match_operand:DF 0 "s_register_operand" "=f")
304 (div:DF (float_extend:DF
305 (match_operand:SF 1 "s_register_operand" "f"))
306 (match_operand:DF 2 "arm_float_rhs_operand" "fG")))]
307 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
308 "dvf%?d\\t%0, %1, %2"
309 [(set_attr "type" "fdivd")
310 (set_attr "predicable" "yes")]
313 (define_insn "*divdf_df_esfdf_fpa"
314 [(set (match_operand:DF 0 "s_register_operand" "=f")
315 (div:DF (match_operand:DF 1 "arm_float_rhs_operand" "fG")
317 (match_operand:SF 2 "s_register_operand" "f"))))]
318 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
319 "rdf%?d\\t%0, %2, %1"
320 [(set_attr "type" "fdivd")
321 (set_attr "predicable" "yes")]
324 (define_insn "*divdf_esfdf_esfdf_fpa"
325 [(set (match_operand:DF 0 "s_register_operand" "=f")
326 (div:DF (float_extend:DF
327 (match_operand:SF 1 "s_register_operand" "f"))
329 (match_operand:SF 2 "s_register_operand" "f"))))]
330 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
331 "dvf%?d\\t%0, %1, %2"
332 [(set_attr "type" "fdivd")
333 (set_attr "predicable" "yes")]
336 (define_insn "*modsf3_fpa"
337 [(set (match_operand:SF 0 "s_register_operand" "=f")
338 (mod:SF (match_operand:SF 1 "s_register_operand" "f")
339 (match_operand:SF 2 "arm_float_rhs_operand" "fG")))]
340 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
341 "rmf%?s\\t%0, %1, %2"
342 [(set_attr "type" "fdivs")
343 (set_attr "predicable" "yes")]
346 (define_insn "*moddf3_fpa"
347 [(set (match_operand:DF 0 "s_register_operand" "=f")
348 (mod:DF (match_operand:DF 1 "s_register_operand" "f")
349 (match_operand:DF 2 "arm_float_rhs_operand" "fG")))]
350 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
351 "rmf%?d\\t%0, %1, %2"
352 [(set_attr "type" "fdivd")
353 (set_attr "predicable" "yes")]
356 (define_insn "*moddf_esfdf_df_fpa"
357 [(set (match_operand:DF 0 "s_register_operand" "=f")
358 (mod:DF (float_extend:DF
359 (match_operand:SF 1 "s_register_operand" "f"))
360 (match_operand:DF 2 "arm_float_rhs_operand" "fG")))]
361 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
362 "rmf%?d\\t%0, %1, %2"
363 [(set_attr "type" "fdivd")
364 (set_attr "predicable" "yes")]
367 (define_insn "*moddf_df_esfdf_fpa"
368 [(set (match_operand:DF 0 "s_register_operand" "=f")
369 (mod:DF (match_operand:DF 1 "s_register_operand" "f")
371 (match_operand:SF 2 "s_register_operand" "f"))))]
372 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
373 "rmf%?d\\t%0, %1, %2"
374 [(set_attr "type" "fdivd")
375 (set_attr "predicable" "yes")]
378 (define_insn "*moddf_esfdf_esfdf_fpa"
379 [(set (match_operand:DF 0 "s_register_operand" "=f")
380 (mod:DF (float_extend:DF
381 (match_operand:SF 1 "s_register_operand" "f"))
383 (match_operand:SF 2 "s_register_operand" "f"))))]
384 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
385 "rmf%?d\\t%0, %1, %2"
386 [(set_attr "type" "fdivd")
387 (set_attr "predicable" "yes")]
390 (define_insn "*negsf2_fpa"
391 [(set (match_operand:SF 0 "s_register_operand" "=f")
392 (neg:SF (match_operand:SF 1 "s_register_operand" "f")))]
393 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
395 [(set_attr "type" "ffarith")
396 (set_attr "predicable" "yes")]
399 (define_insn "*negdf2_fpa"
400 [(set (match_operand:DF 0 "s_register_operand" "=f")
401 (neg:DF (match_operand:DF 1 "s_register_operand" "f")))]
402 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
404 [(set_attr "type" "ffarith")
405 (set_attr "predicable" "yes")]
408 (define_insn "*negdf_esfdf_fpa"
409 [(set (match_operand:DF 0 "s_register_operand" "=f")
410 (neg:DF (float_extend:DF
411 (match_operand:SF 1 "s_register_operand" "f"))))]
412 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
414 [(set_attr "type" "ffarith")
415 (set_attr "predicable" "yes")]
418 (define_insn "*abssf2_fpa"
419 [(set (match_operand:SF 0 "s_register_operand" "=f")
420 (abs:SF (match_operand:SF 1 "s_register_operand" "f")))]
421 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
423 [(set_attr "type" "ffarith")
424 (set_attr "predicable" "yes")]
427 (define_insn "*absdf2_fpa"
428 [(set (match_operand:DF 0 "s_register_operand" "=f")
429 (abs:DF (match_operand:DF 1 "s_register_operand" "f")))]
430 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
432 [(set_attr "type" "ffarith")
433 (set_attr "predicable" "yes")]
436 (define_insn "*absdf_esfdf_fpa"
437 [(set (match_operand:DF 0 "s_register_operand" "=f")
438 (abs:DF (float_extend:DF
439 (match_operand:SF 1 "s_register_operand" "f"))))]
440 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
442 [(set_attr "type" "ffarith")
443 (set_attr "predicable" "yes")]
446 (define_insn "*sqrtsf2_fpa"
447 [(set (match_operand:SF 0 "s_register_operand" "=f")
448 (sqrt:SF (match_operand:SF 1 "s_register_operand" "f")))]
449 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
451 [(set_attr "type" "float_em")
452 (set_attr "predicable" "yes")]
455 (define_insn "*sqrtdf2_fpa"
456 [(set (match_operand:DF 0 "s_register_operand" "=f")
457 (sqrt:DF (match_operand:DF 1 "s_register_operand" "f")))]
458 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
460 [(set_attr "type" "float_em")
461 (set_attr "predicable" "yes")]
464 (define_insn "*sqrtdf_esfdf_fpa"
465 [(set (match_operand:DF 0 "s_register_operand" "=f")
466 (sqrt:DF (float_extend:DF
467 (match_operand:SF 1 "s_register_operand" "f"))))]
468 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
470 [(set_attr "type" "float_em")
471 (set_attr "predicable" "yes")]
474 (define_insn "*floatsisf2_fpa"
475 [(set (match_operand:SF 0 "s_register_operand" "=f")
476 (float:SF (match_operand:SI 1 "s_register_operand" "r")))]
477 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
479 [(set_attr "type" "r_2_f")
480 (set_attr "predicable" "yes")]
483 (define_insn "*floatsidf2_fpa"
484 [(set (match_operand:DF 0 "s_register_operand" "=f")
485 (float:DF (match_operand:SI 1 "s_register_operand" "r")))]
486 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
488 [(set_attr "type" "r_2_f")
489 (set_attr "predicable" "yes")]
492 (define_insn "*fix_truncsfsi2_fpa"
493 [(set (match_operand:SI 0 "s_register_operand" "=r")
494 (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" "f"))))]
495 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
497 [(set_attr "type" "f_2_r")
498 (set_attr "predicable" "yes")]
501 (define_insn "*fix_truncdfsi2_fpa"
502 [(set (match_operand:SI 0 "s_register_operand" "=r")
503 (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" "f"))))]
504 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
506 [(set_attr "type" "f_2_r")
507 (set_attr "predicable" "yes")]
510 (define_insn "*truncdfsf2_fpa"
511 [(set (match_operand:SF 0 "s_register_operand" "=f")
513 (match_operand:DF 1 "s_register_operand" "f")))]
514 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
516 [(set_attr "type" "ffarith")
517 (set_attr "predicable" "yes")]
520 (define_insn "*extendsfdf2_fpa"
521 [(set (match_operand:DF 0 "s_register_operand" "=f")
522 (float_extend:DF (match_operand:SF 1 "s_register_operand" "f")))]
523 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
525 [(set_attr "type" "ffarith")
526 (set_attr "predicable" "yes")]
529 (define_insn "*movsf_fpa"
530 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f, m,f,r,r,r, m")
531 (match_operand:SF 1 "general_operand" "fG,H,mE,f,r,f,r,mE,r"))]
533 && TARGET_HARD_FLOAT && TARGET_FPA
534 && (GET_CODE (operands[0]) != MEM
535 || register_operand (operands[1], SFmode))"
541 str%?\\t%1, [%|sp, #-4]!\;ldf%?s\\t%0, [%|sp], #4
542 stf%?s\\t%1, [%|sp, #-4]!\;ldr%?\\t%0, [%|sp], #4
544 ldr%?\\t%0, %1\\t%@ float
545 str%?\\t%1, %0\\t%@ float"
546 [(set_attr "length" "4,4,4,4,8,8,4,4,4")
547 (set_attr "predicable" "yes")
549 "ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r,*,load1,store1")
550 (set_attr "pool_range" "*,*,1024,*,*,*,*,4096,*")
551 (set_attr "neg_pool_range" "*,*,1012,*,*,*,*,4084,*")]
554 (define_insn "*movdf_fpa"
555 [(set (match_operand:DF 0 "nonimmediate_operand"
556 "=r,Q,r,m,r, f, f,f, m,!f,!r")
557 (match_operand:DF 1 "general_operand"
558 "Q, r,r,r,mF,fG,H,mF,f,r, f"))]
560 && TARGET_HARD_FLOAT && TARGET_FPA
561 && (GET_CODE (operands[0]) != MEM
562 || register_operand (operands[1], DFmode))"
565 switch (which_alternative)
568 case 0: return \"ldm%(ia%)\\t%m1, %M0\\t%@ double\";
569 case 1: return \"stm%(ia%)\\t%m0, %M1\\t%@ double\";
570 case 2: return \"#\";
571 case 3: case 4: return output_move_double (operands);
572 case 5: return \"mvf%?d\\t%0, %1\";
573 case 6: return \"mnf%?d\\t%0, #%N1\";
574 case 7: return \"ldf%?d\\t%0, %1\";
575 case 8: return \"stf%?d\\t%1, %0\";
576 case 9: return output_mov_double_fpa_from_arm (operands);
577 case 10: return output_mov_double_arm_from_fpa (operands);
581 [(set_attr "length" "4,4,8,8,8,4,4,4,4,8,8")
582 (set_attr "predicable" "yes")
584 "load1,store2,*,store2,load1,ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r")
585 (set_attr "pool_range" "*,*,*,*,1020,*,*,1024,*,*,*")
586 (set_attr "neg_pool_range" "*,*,*,*,1008,*,*,1008,*,*,*")]
589 ;; We treat XFmode as meaning 'internal format'. It's the right size and we
590 ;; don't use it for anything else. We only support moving between FPA
591 ;; registers and moving an FPA register to/from memory.
592 (define_insn "*movxf_fpa"
593 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,f,m")
594 (match_operand:XF 1 "general_operand" "f,m,f"))]
595 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA
596 && (register_operand (operands[0], XFmode)
597 || register_operand (operands[1], XFmode))"
599 switch (which_alternative)
602 case 0: return \"mvf%?e\\t%0, %1\";
603 case 1: if (arm_fpu_arch == FPUTYPE_FPA_EMU2)
604 return \"ldf%?e\\t%0, %1\";
605 return \"lfm%?\\t%0, 1, %1\";
606 case 2: if (arm_fpu_arch == FPUTYPE_FPA_EMU2)
607 return \"stf%?e\\t%1, %0\";
608 return \"sfm%?\\t%1, 1, %0\";
611 [(set_attr "length" "4,4,4")
612 (set_attr "predicable" "yes")
613 (set_attr "type" "ffarith,f_load,f_store")]
616 ;; stfs/ldfs always use a conditional infix. This works around the
617 ;; ambiguity between "stf pl s" and "sftp ls".
618 (define_insn "*thumb2_movsf_fpa"
619 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f, m,f,r,r,r, m")
620 (match_operand:SF 1 "general_operand" "fG,H,mE,f,r,f,r,mE,r"))]
622 && TARGET_HARD_FLOAT && TARGET_FPA
623 && (GET_CODE (operands[0]) != MEM
624 || register_operand (operands[1], SFmode))"
630 str%?\\t%1, [%|sp, #-4]!\;ldf%?s\\t%0, [%|sp], #4
631 stf%?s\\t%1, [%|sp, #-4]!\;ldr%?\\t%0, [%|sp], #4
633 ldr%?\\t%0, %1\\t%@ float
634 str%?\\t%1, %0\\t%@ float"
635 [(set_attr "length" "4,4,4,4,8,8,4,4,4")
636 (set_attr "ce_count" "1,1,1,1,2,2,1,1,1")
637 (set_attr "predicable" "yes")
639 "ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r,*,load1,store1")
640 (set_attr "pool_range" "*,*,1024,*,*,*,*,4096,*")
641 (set_attr "neg_pool_range" "*,*,1012,*,*,*,*,0,*")]
644 ;; Not predicable because we don't know the number of instructions.
645 (define_insn "*thumb2_movdf_fpa"
646 [(set (match_operand:DF 0 "nonimmediate_operand"
647 "=r,Q,r,m,r, f, f,f, m,!f,!r")
648 (match_operand:DF 1 "general_operand"
649 "Q, r,r,r,mF,fG,H,mF,f,r, f"))]
651 && TARGET_HARD_FLOAT && TARGET_FPA
652 && (GET_CODE (operands[0]) != MEM
653 || register_operand (operands[1], DFmode))"
656 switch (which_alternative)
659 case 0: return \"ldm%(ia%)\\t%m1, %M0\\t%@ double\";
660 case 1: return \"stm%(ia%)\\t%m0, %M1\\t%@ double\";
661 case 2: case 3: case 4: return output_move_double (operands);
662 case 5: return \"mvf%?d\\t%0, %1\";
663 case 6: return \"mnf%?d\\t%0, #%N1\";
664 case 7: return \"ldf%?d\\t%0, %1\";
665 case 8: return \"stf%?d\\t%1, %0\";
666 case 9: return output_mov_double_fpa_from_arm (operands);
667 case 10: return output_mov_double_arm_from_fpa (operands);
671 [(set_attr "length" "4,4,8,8,8,4,4,4,4,8,8")
673 "load1,store2,*,store2,load1,ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r")
674 (set_attr "pool_range" "*,*,*,*,4092,*,*,1024,*,*,*")
675 (set_attr "neg_pool_range" "*,*,*,*,0,*,*,1020,*,*,*")]
678 ;; Saving and restoring the floating point registers in the prologue should
679 ;; be done in XFmode, even though we don't support that for anything else
680 ;; (Well, strictly it's 'internal representation', but that's effectively
682 ;; Not predicable because we don't know the number of instructions.
684 (define_insn "*thumb2_movxf_fpa"
685 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,f,f,m,f,r,r")
686 (match_operand:XF 1 "general_operand" "fG,H,m,f,r,f,r"))]
687 "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_FPA && reload_completed"
689 switch (which_alternative)
692 case 0: return \"mvf%?e\\t%0, %1\";
693 case 1: return \"mnf%?e\\t%0, #%N1\";
694 case 2: return \"ldf%?e\\t%0, %1\";
695 case 3: return \"stf%?e\\t%1, %0\";
696 case 4: return output_mov_long_double_fpa_from_arm (operands);
697 case 5: return output_mov_long_double_arm_from_fpa (operands);
698 case 6: return output_mov_long_double_arm_from_arm (operands);
701 [(set_attr "length" "4,4,4,4,8,8,12")
702 (set_attr "type" "ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r,*")
703 (set_attr "pool_range" "*,*,1024,*,*,*,*")
704 (set_attr "neg_pool_range" "*,*,1004,*,*,*,*")]
707 (define_insn "*cmpsf_fpa"
708 [(set (reg:CCFP CC_REGNUM)
709 (compare:CCFP (match_operand:SF 0 "s_register_operand" "f,f")
710 (match_operand:SF 1 "arm_float_add_operand" "fG,H")))]
711 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
715 [(set_attr "conds" "set")
716 (set_attr "type" "f_2_r")]
719 (define_insn "*cmpdf_fpa"
720 [(set (reg:CCFP CC_REGNUM)
721 (compare:CCFP (match_operand:DF 0 "s_register_operand" "f,f")
722 (match_operand:DF 1 "arm_float_add_operand" "fG,H")))]
723 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
727 [(set_attr "conds" "set")
728 (set_attr "type" "f_2_r")]
731 (define_insn "*cmpesfdf_df_fpa"
732 [(set (reg:CCFP CC_REGNUM)
733 (compare:CCFP (float_extend:DF
734 (match_operand:SF 0 "s_register_operand" "f,f"))
735 (match_operand:DF 1 "arm_float_add_operand" "fG,H")))]
736 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
740 [(set_attr "conds" "set")
741 (set_attr "type" "f_2_r")]
744 (define_insn "*cmpdf_esfdf_fpa"
745 [(set (reg:CCFP CC_REGNUM)
746 (compare:CCFP (match_operand:DF 0 "s_register_operand" "f")
748 (match_operand:SF 1 "s_register_operand" "f"))))]
749 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
751 [(set_attr "conds" "set")
752 (set_attr "type" "f_2_r")]
755 (define_insn "*cmpsf_trap_fpa"
756 [(set (reg:CCFPE CC_REGNUM)
757 (compare:CCFPE (match_operand:SF 0 "s_register_operand" "f,f")
758 (match_operand:SF 1 "arm_float_add_operand" "fG,H")))]
759 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
763 [(set_attr "conds" "set")
764 (set_attr "type" "f_2_r")]
767 (define_insn "*cmpdf_trap_fpa"
768 [(set (reg:CCFPE CC_REGNUM)
769 (compare:CCFPE (match_operand:DF 0 "s_register_operand" "f,f")
770 (match_operand:DF 1 "arm_float_add_operand" "fG,H")))]
771 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
775 [(set_attr "conds" "set")
776 (set_attr "type" "f_2_r")]
779 (define_insn "*cmp_esfdf_df_trap_fpa"
780 [(set (reg:CCFPE CC_REGNUM)
781 (compare:CCFPE (float_extend:DF
782 (match_operand:SF 0 "s_register_operand" "f,f"))
783 (match_operand:DF 1 "arm_float_add_operand" "fG,H")))]
784 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
788 [(set_attr "conds" "set")
789 (set_attr "type" "f_2_r")]
792 (define_insn "*cmp_df_esfdf_trap_fpa"
793 [(set (reg:CCFPE CC_REGNUM)
794 (compare:CCFPE (match_operand:DF 0 "s_register_operand" "f")
796 (match_operand:SF 1 "s_register_operand" "f"))))]
797 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FPA"
799 [(set_attr "conds" "set")
800 (set_attr "type" "f_2_r")]
803 (define_insn "*movsfcc_fpa"
804 [(set (match_operand:SF 0 "s_register_operand" "=f,f,f,f,f,f,f,f")
806 (match_operator 3 "arm_comparison_operator"
807 [(match_operand 4 "cc_register" "") (const_int 0)])
808 (match_operand:SF 1 "arm_float_add_operand" "0,0,fG,H,fG,fG,H,H")
809 (match_operand:SF 2 "arm_float_add_operand" "fG,H,0,0,fG,H,fG,H")))]
810 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
816 mvf%d3s\\t%0, %1\;mvf%D3s\\t%0, %2
817 mvf%d3s\\t%0, %1\;mnf%D3s\\t%0, #%N2
818 mnf%d3s\\t%0, #%N1\;mvf%D3s\\t%0, %2
819 mnf%d3s\\t%0, #%N1\;mnf%D3s\\t%0, #%N2"
820 [(set_attr "length" "4,4,4,4,8,8,8,8")
821 (set_attr "type" "ffarith")
822 (set_attr "conds" "use")]
825 (define_insn "*movdfcc_fpa"
826 [(set (match_operand:DF 0 "s_register_operand" "=f,f,f,f,f,f,f,f")
828 (match_operator 3 "arm_comparison_operator"
829 [(match_operand 4 "cc_register" "") (const_int 0)])
830 (match_operand:DF 1 "arm_float_add_operand" "0,0,fG,H,fG,fG,H,H")
831 (match_operand:DF 2 "arm_float_add_operand" "fG,H,0,0,fG,H,fG,H")))]
832 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_FPA"
838 mvf%d3d\\t%0, %1\;mvf%D3d\\t%0, %2
839 mvf%d3d\\t%0, %1\;mnf%D3d\\t%0, #%N2
840 mnf%d3d\\t%0, #%N1\;mvf%D3d\\t%0, %2
841 mnf%d3d\\t%0, #%N1\;mnf%D3d\\t%0, #%N2"
842 [(set_attr "length" "4,4,4,4,8,8,8,8")
843 (set_attr "type" "ffarith")
844 (set_attr "conds" "use")]
847 (define_insn "*thumb2_movsfcc_fpa"
848 [(set (match_operand:SF 0 "s_register_operand" "=f,f,f,f,f,f,f,f")
850 (match_operator 3 "arm_comparison_operator"
851 [(match_operand 4 "cc_register" "") (const_int 0)])
852 (match_operand:SF 1 "arm_float_add_operand" "0,0,fG,H,fG,fG,H,H")
853 (match_operand:SF 2 "arm_float_add_operand" "fG,H,0,0,fG,H,fG,H")))]
854 "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_FPA"
856 it\\t%D3\;mvf%D3s\\t%0, %2
857 it\\t%D3\;mnf%D3s\\t%0, #%N2
858 it\\t%d3\;mvf%d3s\\t%0, %1
859 it\\t%d3\;mnf%d3s\\t%0, #%N1
860 ite\\t%d3\;mvf%d3s\\t%0, %1\;mvf%D3s\\t%0, %2
861 ite\\t%d3\;mvf%d3s\\t%0, %1\;mnf%D3s\\t%0, #%N2
862 ite\\t%d3\;mnf%d3s\\t%0, #%N1\;mvf%D3s\\t%0, %2
863 ite\\t%d3\;mnf%d3s\\t%0, #%N1\;mnf%D3s\\t%0, #%N2"
864 [(set_attr "length" "6,6,6,6,10,10,10,10")
865 (set_attr "type" "ffarith")
866 (set_attr "conds" "use")]
869 (define_insn "*thumb2_movdfcc_fpa"
870 [(set (match_operand:DF 0 "s_register_operand" "=f,f,f,f,f,f,f,f")
872 (match_operator 3 "arm_comparison_operator"
873 [(match_operand 4 "cc_register" "") (const_int 0)])
874 (match_operand:DF 1 "arm_float_add_operand" "0,0,fG,H,fG,fG,H,H")
875 (match_operand:DF 2 "arm_float_add_operand" "fG,H,0,0,fG,H,fG,H")))]
876 "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_FPA"
878 it\\t%D3\;mvf%D3d\\t%0, %2
879 it\\t%D3\;mnf%D3d\\t%0, #%N2
880 it\\t%d3\;mvf%d3d\\t%0, %1
881 it\\t%d3\;mnf%d3d\\t%0, #%N1
882 ite\\t%d3\;mvf%d3d\\t%0, %1\;mvf%D3d\\t%0, %2
883 ite\\t%d3\;mvf%d3d\\t%0, %1\;mnf%D3d\\t%0, #%N2
884 ite\\t%d3\;mnf%d3d\\t%0, #%N1\;mvf%D3d\\t%0, %2
885 ite\\t%d3\;mnf%d3d\\t%0, #%N1\;mnf%D3d\\t%0, #%N2"
886 [(set_attr "length" "6,6,6,6,10,10,10,10")
887 (set_attr "type" "ffarith")
888 (set_attr "conds" "use")]