OSDN Git Service

* config/sparc/sparc.md (UNSPEC_FRAME_BLOCKAGE): New constant.
[pf3gnuchains/gcc-fork.git] / gcc / config / sparc / sparc.md
1 ;; Machine description for SPARC chip for GCC
2 ;;  Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 ;;  1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
4 ;;  2011 Free Software Foundation, Inc.
5 ;;  Contributed by Michael Tiemann (tiemann@cygnus.com)
6 ;;  64-bit SPARC-V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
7 ;;  at Cygnus Support.
8
9 ;; This file is part of GCC.
10
11 ;; GCC is free software; you can redistribute it and/or modify
12 ;; it under the terms of the GNU General Public License as published by
13 ;; the Free Software Foundation; either version 3, or (at your option)
14 ;; any later version.
15
16 ;; GCC is distributed in the hope that it will be useful,
17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 ;; GNU General Public License for more details.
20
21 ;; You should have received a copy of the GNU General Public License
22 ;; along with GCC; see the file COPYING3.  If not see
23 ;; <http://www.gnu.org/licenses/>.
24
25 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
26
27 (define_constants
28   [(UNSPEC_MOVE_PIC             0)
29    (UNSPEC_UPDATE_RETURN        1)
30    (UNSPEC_LOAD_PCREL_SYM       2)
31    (UNSPEC_FRAME_BLOCKAGE      3)
32    (UNSPEC_MOVE_PIC_LABEL       5)
33    (UNSPEC_SETH44               6)
34    (UNSPEC_SETM44               7)
35    (UNSPEC_SETHH                9)
36    (UNSPEC_SETLM                10)
37    (UNSPEC_EMB_HISUM            11)
38    (UNSPEC_EMB_TEXTUHI          13)
39    (UNSPEC_EMB_TEXTHI           14)
40    (UNSPEC_EMB_TEXTULO          15)
41    (UNSPEC_EMB_SETHM            18)
42    (UNSPEC_MOVE_GOTDATA         19)
43
44    (UNSPEC_MEMBAR               20)
45    (UNSPEC_ATOMIC               21)
46
47    (UNSPEC_TLSGD                30)
48    (UNSPEC_TLSLDM               31)
49    (UNSPEC_TLSLDO               32)
50    (UNSPEC_TLSIE                33)
51    (UNSPEC_TLSLE                34)
52    (UNSPEC_TLSLD_BASE           35)
53
54    (UNSPEC_FPACK16              40)
55    (UNSPEC_FPACK32              41)
56    (UNSPEC_FPACKFIX             42)
57    (UNSPEC_FEXPAND              43)
58    (UNSPEC_MUL16AU              44)
59    (UNSPEC_MUL16AL              45)
60    (UNSPEC_MUL8UL               46)
61    (UNSPEC_MULDUL               47)
62    (UNSPEC_ALIGNDATA            48)
63    (UNSPEC_FCMP                 49)
64    (UNSPEC_PDIST                50)
65    (UNSPEC_EDGE8                51)
66    (UNSPEC_EDGE8L               52)
67    (UNSPEC_EDGE16               53)
68    (UNSPEC_EDGE16L              54)
69    (UNSPEC_EDGE32               55)
70    (UNSPEC_EDGE32L              56)
71    (UNSPEC_ARRAY8               57)
72    (UNSPEC_ARRAY16              58)
73    (UNSPEC_ARRAY32              59)
74
75    (UNSPEC_SP_SET               60)
76    (UNSPEC_SP_TEST              61)
77
78    (UNSPEC_EDGE8N               70)
79    (UNSPEC_EDGE8LN              71)
80    (UNSPEC_EDGE16N              72)
81    (UNSPEC_EDGE16LN             73)
82    (UNSPEC_EDGE32N              74)
83    (UNSPEC_EDGE32LN             75)
84    (UNSPEC_BSHUFFLE             76)
85    (UNSPEC_CMASK8               77)
86    (UNSPEC_CMASK16              78)
87    (UNSPEC_CMASK32              79)
88    (UNSPEC_FCHKSM16             80)
89    (UNSPEC_PDISTN               81)
90    (UNSPEC_FUCMP                82)
91    (UNSPEC_FHADD                83)
92    (UNSPEC_FHSUB                84)
93    (UNSPEC_XMUL                 85)
94    (UNSPEC_MUL8                 86)
95    (UNSPEC_MUL8SU               87)
96    (UNSPEC_MULDSU               88)
97   ])
98
99 (define_constants
100   [(UNSPECV_BLOCKAGE            0)
101    (UNSPECV_FLUSHW              1)
102    (UNSPECV_GOTO                2)
103    (UNSPECV_FLUSH               4)
104    (UNSPECV_SAVEW               6)
105    (UNSPECV_CAS                 8)
106    (UNSPECV_SWAP                9)
107    (UNSPECV_LDSTUB              10)
108    (UNSPECV_PROBE_STACK_RANGE   11)
109   ])
110
111 (define_constants
112  [(G0_REG                       0)
113   (G1_REG                       1)
114   (G2_REG                       2)
115   (G3_REG                       3)
116   (G4_REG                       4)
117   (G5_REG                       5)
118   (G6_REG                       6)
119   (G7_REG                       7)
120   (O0_REG                       8)
121   (O1_REG                       9)
122   (O2_REG                       10)
123   (O3_REG                       11)
124   (O4_REG                       12)
125   (O5_REG                       13)
126   (O6_REG                       14)
127   (O7_REG                       15)
128   (L0_REG                       16)
129   (L1_REG                       17)
130   (L2_REG                       18)
131   (L3_REG                       19)
132   (L4_REG                       20)
133   (L5_REG                       21)
134   (L6_REG                       22)
135   (L7_REG                       23)
136   (I0_REG                       24)
137   (I1_REG                       25)
138   (I2_REG                       26)
139   (I3_REG                       27)
140   (I4_REG                       28)
141   (I5_REG                       29)
142   (I6_REG                       30)
143   (I7_REG                       31)
144   (F0_REG                       32)
145   (F1_REG                       33)
146   (F2_REG                       34)
147   (F3_REG                       35)
148   (F4_REG                       36)
149   (F5_REG                       37)
150   (F6_REG                       38)
151   (F7_REG                       39)
152   (F8_REG                       40)
153   (F9_REG                       41)
154   (F10_REG                      42)
155   (F11_REG                      43)
156   (F12_REG                      44)
157   (F13_REG                      45)
158   (F14_REG                      46)
159   (F15_REG                      47)
160   (F16_REG                      48)
161   (F17_REG                      49)
162   (F18_REG                      50)
163   (F19_REG                      51)
164   (F20_REG                      52)
165   (F21_REG                      53)
166   (F22_REG                      54)
167   (F23_REG                      55)
168   (F24_REG                      56)
169   (F25_REG                      57)
170   (F26_REG                      58)
171   (F27_REG                      59)
172   (F28_REG                      60)
173   (F29_REG                      61)
174   (F30_REG                      62)
175   (F31_REG                      63)
176   (F32_REG                      64)
177   (F34_REG                      66)
178   (F36_REG                      68)
179   (F38_REG                      70)
180   (F40_REG                      72)
181   (F42_REG                      74)
182   (F44_REG                      76)
183   (F46_REG                      78)
184   (F48_REG                      80)
185   (F50_REG                      82)
186   (F52_REG                      84)
187   (F54_REG                      86)
188   (F56_REG                      88)
189   (F58_REG                      90)
190   (F60_REG                      92)
191   (F62_REG                      94)
192   (FCC0_REG                     96)
193   (FCC1_REG                     97)
194   (FCC2_REG                     98)
195   (FCC3_REG                     99)
196   (CC_REG                       100)
197   (SFP_REG                      101)
198   (GSR_REG                      102)
199  ])
200
201 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
202 (define_mode_iterator I [QI HI SI DI])
203 (define_mode_iterator F [SF DF TF])
204
205 ;; The upper 32 fp regs on the v9 can't hold SFmode values.  To deal with this
206 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip.  The name
207 ;; is a bit of a misnomer as it covers all 64 fp regs.  The corresponding
208 ;; constraint letter is 'e'.  To avoid any confusion, 'e' is used instead of
209 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
210
211 ;; Attribute for cpu type.
212 ;; These must match the values for enum processor_type in sparc.h.
213 (define_attr "cpu"
214   "v7,
215    cypress,
216    v8,
217    supersparc,
218    hypersparc,
219    leon,
220    sparclite,
221    f930,
222    f934,
223    sparclite86x,
224    sparclet,
225    tsc701,
226    v9,
227    ultrasparc,
228    ultrasparc3,
229    niagara,
230    niagara2,
231    niagara3,
232    niagara4"
233   (const (symbol_ref "sparc_cpu_attr")))
234
235 ;; Attribute for the instruction set.
236 ;; At present we only need to distinguish v9/!v9, but for clarity we
237 ;; test TARGET_V8 too.
238 (define_attr "isa" "v7,v8,v9,sparclet"
239  (const
240   (cond [(symbol_ref "TARGET_V9") (const_string "v9")
241          (symbol_ref "TARGET_V8") (const_string "v8")
242          (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
243         (const_string "v7"))))
244
245 (define_attr "cpu_feature" "none,fpu,fpunotv9,v9,vis,vis3" (const_string "none"))
246
247 (define_attr "enabled" ""
248   (cond [(eq_attr "cpu_feature" "none") (const_int 1)
249          (eq_attr "cpu_feature" "fpu") (symbol_ref "TARGET_FPU")
250          (eq_attr "cpu_feature" "fpunotv9") (symbol_ref "TARGET_FPU && ! TARGET_V9")
251          (eq_attr "cpu_feature" "v9") (symbol_ref "TARGET_V9")
252          (eq_attr "cpu_feature" "vis") (symbol_ref "TARGET_VIS")
253          (eq_attr "cpu_feature" "vis3") (symbol_ref "TARGET_VIS3")]
254         (const_int 0)))
255
256 ;; Insn type.
257 (define_attr "type"
258   "ialu,compare,shift,
259    load,sload,store,
260    uncond_branch,branch,call,sibcall,call_no_delay_slot,return,
261    imul,idiv,
262    fpload,fpstore,
263    fp,fpmove,
264    fpcmove,fpcrmove,
265    fpcmp,
266    fpmul,fpdivs,fpdivd,
267    fpsqrts,fpsqrtd,
268    fga,fgm_pack,fgm_mul,fgm_pdist,fgm_cmp,edge,edgen,gsr,array,
269    cmove,
270    ialuX,
271    multi,savew,flushw,iflush,trap"
272   (const_string "ialu"))
273
274 ;; True if branch/call has empty delay slot and will emit a nop in it
275 (define_attr "empty_delay_slot" "false,true"
276   (symbol_ref "(empty_delay_slot (insn)
277                 ? EMPTY_DELAY_SLOT_TRUE : EMPTY_DELAY_SLOT_FALSE)"))
278
279 (define_attr "branch_type" "none,icc,fcc,reg"
280   (const_string "none"))
281
282 (define_attr "pic" "false,true"
283   (symbol_ref "(flag_pic != 0 ? PIC_TRUE : PIC_FALSE)"))
284
285 (define_attr "calls_alloca" "false,true"
286   (symbol_ref "(cfun->calls_alloca != 0
287                 ? CALLS_ALLOCA_TRUE : CALLS_ALLOCA_FALSE)"))
288
289 (define_attr "calls_eh_return" "false,true"
290    (symbol_ref "(crtl->calls_eh_return != 0
291                  ? CALLS_EH_RETURN_TRUE : CALLS_EH_RETURN_FALSE)"))
292
293 (define_attr "leaf_function" "false,true"
294   (symbol_ref "(current_function_uses_only_leaf_regs != 0
295                 ? LEAF_FUNCTION_TRUE : LEAF_FUNCTION_FALSE)"))
296
297 (define_attr "delayed_branch" "false,true"
298   (symbol_ref "(flag_delayed_branch != 0
299                 ? DELAYED_BRANCH_TRUE : DELAYED_BRANCH_FALSE)"))
300
301 (define_attr "flat" "false,true"
302   (symbol_ref "(TARGET_FLAT != 0
303                 ? FLAT_TRUE : FLAT_FALSE)"))
304
305 ;; Length (in # of insns).
306 ;; Beware that setting a length greater or equal to 3 for conditional branches
307 ;; has a side-effect (see output_cbranch and output_v9branch).
308 (define_attr "length" ""
309   (cond [(eq_attr "type" "uncond_branch,call")
310            (if_then_else (eq_attr "empty_delay_slot" "true")
311              (const_int 2)
312              (const_int 1))
313          (eq_attr "type" "sibcall")
314            (if_then_else (eq_attr "leaf_function" "true")
315              (if_then_else (eq_attr "empty_delay_slot" "true")
316                (const_int 3)
317                (const_int 2))
318              (if_then_else (eq_attr "empty_delay_slot" "true")
319                (const_int 2)
320                (const_int 1)))
321          (eq_attr "branch_type" "icc")
322            (if_then_else (match_operand 0 "noov_compare64_operator" "")
323              (if_then_else (lt (pc) (match_dup 1))
324                (if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000))
325                  (if_then_else (eq_attr "empty_delay_slot" "true")
326                    (const_int 2)
327                    (const_int 1))
328                  (if_then_else (eq_attr "empty_delay_slot" "true")
329                    (const_int 4)
330                    (const_int 3)))
331                (if_then_else (lt (minus (pc) (match_dup 1)) (const_int 260000))
332                  (if_then_else (eq_attr "empty_delay_slot" "true")
333                    (const_int 2)
334                    (const_int 1))
335                  (if_then_else (eq_attr "empty_delay_slot" "true")
336                    (const_int 4)
337                    (const_int 3))))
338              (if_then_else (eq_attr "empty_delay_slot" "true")
339                (const_int 2)
340                (const_int 1)))
341          (eq_attr "branch_type" "fcc")
342            (if_then_else (match_operand 0 "fcc0_register_operand" "")
343              (if_then_else (eq_attr "empty_delay_slot" "true")
344                (if_then_else (not (match_test "TARGET_V9"))
345                  (const_int 3)
346                  (const_int 2))
347                (if_then_else (not (match_test "TARGET_V9"))
348                  (const_int 2)
349                  (const_int 1)))
350              (if_then_else (lt (pc) (match_dup 2))
351                (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000))
352                  (if_then_else (eq_attr "empty_delay_slot" "true")
353                    (const_int 2)
354                    (const_int 1))
355                  (if_then_else (eq_attr "empty_delay_slot" "true")
356                    (const_int 4)
357                    (const_int 3)))
358                (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000))
359                  (if_then_else (eq_attr "empty_delay_slot" "true")
360                    (const_int 2)
361                    (const_int 1))
362                  (if_then_else (eq_attr "empty_delay_slot" "true")
363                    (const_int 4)
364                    (const_int 3)))))
365          (eq_attr "branch_type" "reg")
366            (if_then_else (lt (pc) (match_dup 2))
367              (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000))
368                (if_then_else (eq_attr "empty_delay_slot" "true")
369                  (const_int 2)
370                  (const_int 1))
371                (if_then_else (eq_attr "empty_delay_slot" "true")
372                  (const_int 4)
373                  (const_int 3)))
374              (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000))
375                (if_then_else (eq_attr "empty_delay_slot" "true")
376                  (const_int 2)
377                  (const_int 1))
378                (if_then_else (eq_attr "empty_delay_slot" "true")
379                  (const_int 4)
380                  (const_int 3))))
381          ] (const_int 1)))
382
383 ;; FP precision.
384 (define_attr "fptype" "single,double"
385   (const_string "single"))
386
387 ;; UltraSPARC-III integer load type.
388 (define_attr "us3load_type" "2cycle,3cycle"
389   (const_string "2cycle"))
390
391 (define_asm_attributes
392   [(set_attr "length" "2")
393    (set_attr "type" "multi")])
394
395 ;; Attributes for instruction and branch scheduling
396 (define_attr "tls_call_delay" "false,true"
397   (symbol_ref "(tls_call_delay (insn)
398                 ? TLS_CALL_DELAY_TRUE : TLS_CALL_DELAY_FALSE)"))
399
400 (define_attr "in_call_delay" "false,true"
401   (cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
402                 (const_string "false")
403          (eq_attr "type" "load,fpload,store,fpstore")
404                 (if_then_else (eq_attr "length" "1")
405                               (const_string "true")
406                               (const_string "false"))]
407          (if_then_else (and (eq_attr "length" "1")
408                             (eq_attr "tls_call_delay" "true"))
409                        (const_string "true")
410                        (const_string "false"))))
411
412 (define_attr "eligible_for_sibcall_delay" "false,true"
413   (symbol_ref "(eligible_for_sibcall_delay (insn)
414                 ? ELIGIBLE_FOR_SIBCALL_DELAY_TRUE
415                 : ELIGIBLE_FOR_SIBCALL_DELAY_FALSE)"))
416
417 (define_attr "eligible_for_return_delay" "false,true"
418   (symbol_ref "(eligible_for_return_delay (insn)
419                 ? ELIGIBLE_FOR_RETURN_DELAY_TRUE
420                 : ELIGIBLE_FOR_RETURN_DELAY_FALSE)"))
421
422 ;; ??? !v9: Should implement the notion of predelay slots for floating-point
423 ;; branches.  This would allow us to remove the nop always inserted before
424 ;; a floating point branch.
425
426 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
427 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
428 ;; This is because doing so will add several pipeline stalls to the path
429 ;; that the load/store did not come from.  Unfortunately, there is no way
430 ;; to prevent fill_eager_delay_slots from using load/store without completely
431 ;; disabling them.  For the SPEC benchmark set, this is a serious lose,
432 ;; because it prevents us from moving back the final store of inner loops.
433
434 (define_attr "in_branch_delay" "false,true"
435   (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
436                      (eq_attr "length" "1"))
437                 (const_string "true")
438                 (const_string "false")))
439
440 (define_attr "in_uncond_branch_delay" "false,true"
441   (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
442                      (eq_attr "length" "1"))
443                 (const_string "true")
444                 (const_string "false")))
445
446 (define_attr "in_annul_branch_delay" "false,true"
447   (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
448                      (eq_attr "length" "1"))
449                 (const_string "true")
450                 (const_string "false")))
451
452 (define_delay (eq_attr "type" "call")
453   [(eq_attr "in_call_delay" "true") (nil) (nil)])
454
455 (define_delay (eq_attr "type" "sibcall")
456   [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
457
458 (define_delay (eq_attr "type" "branch")
459   [(eq_attr "in_branch_delay" "true")
460    (nil) (eq_attr "in_annul_branch_delay" "true")])
461
462 (define_delay (eq_attr "type" "uncond_branch")
463   [(eq_attr "in_uncond_branch_delay" "true")
464    (nil) (nil)])
465
466 (define_delay (eq_attr "type" "return")
467   [(eq_attr "eligible_for_return_delay" "true") (nil) (nil)])
468
469
470 ;; Include SPARC DFA schedulers
471
472 (include "cypress.md")
473 (include "supersparc.md")
474 (include "hypersparc.md")
475 (include "leon.md")
476 (include "sparclet.md")
477 (include "ultra1_2.md")
478 (include "ultra3.md")
479 (include "niagara.md")
480 (include "niagara2.md")
481
482
483 ;; Operand and operator predicates and constraints
484
485 (include "predicates.md")
486 (include "constraints.md")
487
488
489 ;; Compare instructions.
490
491 ;; These are just the DEFINE_INSNs to match the patterns and the
492 ;; DEFINE_SPLITs for some of the scc insns that actually require
493 ;; more than one machine instruction.  DEFINE_EXPANDs are further down.
494
495 ;; The compare DEFINE_INSNs.
496
497 (define_insn "*cmpsi_insn"
498   [(set (reg:CC CC_REG)
499         (compare:CC (match_operand:SI 0 "register_operand" "r")
500                     (match_operand:SI 1 "arith_operand" "rI")))]
501   ""
502   "cmp\t%0, %1"
503   [(set_attr "type" "compare")])
504
505 (define_insn "*cmpdi_sp64"
506   [(set (reg:CCX CC_REG)
507         (compare:CCX (match_operand:DI 0 "register_operand" "r")
508                      (match_operand:DI 1 "arith_operand" "rI")))]
509   "TARGET_ARCH64"
510   "cmp\t%0, %1"
511   [(set_attr "type" "compare")])
512
513 (define_insn "*cmpsf_fpe"
514   [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
515         (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
516                        (match_operand:SF 2 "register_operand" "f")))]
517   "TARGET_FPU"
518 {
519   if (TARGET_V9)
520     return "fcmpes\t%0, %1, %2";
521   return "fcmpes\t%1, %2";
522 }
523   [(set_attr "type" "fpcmp")])
524
525 (define_insn "*cmpdf_fpe"
526   [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
527         (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
528                        (match_operand:DF 2 "register_operand" "e")))]
529   "TARGET_FPU"
530 {
531   if (TARGET_V9)
532     return "fcmped\t%0, %1, %2";
533   return "fcmped\t%1, %2";
534 }
535   [(set_attr "type" "fpcmp")
536    (set_attr "fptype" "double")])
537
538 (define_insn "*cmptf_fpe"
539   [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
540         (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
541                        (match_operand:TF 2 "register_operand" "e")))]
542   "TARGET_FPU && TARGET_HARD_QUAD"
543 {
544   if (TARGET_V9)
545     return "fcmpeq\t%0, %1, %2";
546   return "fcmpeq\t%1, %2";
547 }
548   [(set_attr "type" "fpcmp")])
549
550 (define_insn "*cmpsf_fp"
551   [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
552         (compare:CCFP (match_operand:SF 1 "register_operand" "f")
553                       (match_operand:SF 2 "register_operand" "f")))]
554   "TARGET_FPU"
555 {
556   if (TARGET_V9)
557     return "fcmps\t%0, %1, %2";
558   return "fcmps\t%1, %2";
559 }
560   [(set_attr "type" "fpcmp")])
561
562 (define_insn "*cmpdf_fp"
563   [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
564         (compare:CCFP (match_operand:DF 1 "register_operand" "e")
565                       (match_operand:DF 2 "register_operand" "e")))]
566   "TARGET_FPU"
567 {
568   if (TARGET_V9)
569     return "fcmpd\t%0, %1, %2";
570   return "fcmpd\t%1, %2";
571 }
572   [(set_attr "type" "fpcmp")
573    (set_attr "fptype" "double")])
574
575 (define_insn "*cmptf_fp"
576   [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
577         (compare:CCFP (match_operand:TF 1 "register_operand" "e")
578                       (match_operand:TF 2 "register_operand" "e")))]
579   "TARGET_FPU && TARGET_HARD_QUAD"
580 {
581   if (TARGET_V9)
582     return "fcmpq\t%0, %1, %2";
583   return "fcmpq\t%1, %2";
584 }
585   [(set_attr "type" "fpcmp")])
586 \f
587 ;; Next come the scc insns.
588
589 (define_expand "cstoresi4"
590   [(use (match_operator 1 "comparison_operator"
591          [(match_operand:SI 2 "compare_operand" "")
592           (match_operand:SI 3 "arith_operand" "")]))
593    (clobber (match_operand:SI 0 "register_operand"))]
594   ""
595 {
596   if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
597     operands[2] = force_reg (SImode, operands[2]);
598   if (emit_scc_insn (operands)) DONE; else FAIL;
599 })
600
601 (define_expand "cstoredi4"
602   [(use (match_operator 1 "comparison_operator"
603          [(match_operand:DI 2 "compare_operand" "")
604           (match_operand:DI 3 "arith_operand" "")]))
605    (clobber (match_operand:SI 0 "register_operand"))]
606   "TARGET_ARCH64"
607 {
608   if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
609     operands[2] = force_reg (DImode, operands[2]);
610   if (emit_scc_insn (operands)) DONE; else FAIL;
611 })
612
613 (define_expand "cstore<F:mode>4"
614   [(use (match_operator 1 "comparison_operator"
615          [(match_operand:F 2 "register_operand" "")
616           (match_operand:F 3 "register_operand" "")]))
617    (clobber (match_operand:SI 0 "register_operand"))]
618   "TARGET_FPU"
619   { if (emit_scc_insn (operands)) DONE; else FAIL; })
620
621 \f
622
623 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
624 ;; generate addcc/subcc instructions.
625
626 (define_expand "seqsi_special"
627   [(set (match_dup 3)
628         (xor:SI (match_operand:SI 1 "register_operand" "")
629                 (match_operand:SI 2 "register_operand" "")))
630    (parallel [(set (match_operand:SI 0 "register_operand" "")
631                    (eq:SI (match_dup 3) (const_int 0)))
632               (clobber (reg:CC CC_REG))])]
633   ""
634   { operands[3] = gen_reg_rtx (SImode); })
635
636 (define_expand "seqdi_special"
637   [(set (match_dup 3)
638         (xor:DI (match_operand:DI 1 "register_operand" "")
639                 (match_operand:DI 2 "register_operand" "")))
640    (set (match_operand:SI 0 "register_operand" "")
641         (eq:SI (match_dup 3) (const_int 0)))]
642   "TARGET_ARCH64"
643   { operands[3] = gen_reg_rtx (DImode); })
644
645 (define_expand "snesi_special"
646   [(set (match_dup 3)
647         (xor:SI (match_operand:SI 1 "register_operand" "")
648                 (match_operand:SI 2 "register_operand" "")))
649    (parallel [(set (match_operand:SI 0 "register_operand" "")
650                    (ne:SI (match_dup 3) (const_int 0)))
651               (clobber (reg:CC CC_REG))])]
652   ""
653   { operands[3] = gen_reg_rtx (SImode); })
654
655 (define_expand "snedi_special"
656   [(set (match_dup 3)
657         (xor:DI (match_operand:DI 1 "register_operand" "")
658                 (match_operand:DI 2 "register_operand" "")))
659    (set (match_operand:SI 0 "register_operand" "")
660         (ne:SI (match_dup 3) (const_int 0)))]
661   "TARGET_ARCH64 && ! TARGET_VIS3"
662   { operands[3] = gen_reg_rtx (DImode); })
663
664 (define_expand "snedi_special_vis3"
665   [(set (match_dup 3)
666         (xor:DI (match_operand:DI 1 "register_operand" "")
667                 (match_operand:DI 2 "register_operand" "")))
668    (parallel [(set (match_operand:SI 0 "register_operand" "")
669                    (ne:SI (match_dup 3) (const_int 0)))
670               (clobber (reg:CCX CC_REG))])]
671   "TARGET_ARCH64 && TARGET_VIS3"
672   { operands[3] = gen_reg_rtx (DImode); })
673
674
675 ;; Now the DEFINE_INSNs for the scc cases.
676
677 ;; The SEQ and SNE patterns are special because they can be done
678 ;; without any branching and do not involve a COMPARE.  We want
679 ;; them to always use the splits below so the results can be
680 ;; scheduled.
681
682 (define_insn_and_split "*snesi_zero"
683   [(set (match_operand:SI 0 "register_operand" "=r")
684         (ne:SI (match_operand:SI 1 "register_operand" "r")
685                (const_int 0)))
686    (clobber (reg:CC CC_REG))]
687   ""
688   "#"
689   ""
690   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
691                                            (const_int 0)))
692    (set (match_dup 0) (ltu:SI (reg:CC CC_REG) (const_int 0)))]
693   ""
694   [(set_attr "length" "2")])
695
696 (define_insn_and_split "*neg_snesi_zero"
697   [(set (match_operand:SI 0 "register_operand" "=r")
698         (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
699                        (const_int 0))))
700    (clobber (reg:CC CC_REG))]
701   ""
702   "#"
703   ""
704   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
705                                            (const_int 0)))
706    (set (match_dup 0) (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0))))]
707   ""
708   [(set_attr "length" "2")])
709
710 (define_insn_and_split "*snesi_zero_extend"
711   [(set (match_operand:DI 0 "register_operand" "=r")
712         (ne:DI (match_operand:SI 1 "register_operand" "r")
713                (const_int 0)))
714    (clobber (reg:CC CC_REG))]
715   "TARGET_ARCH64"
716   "#"
717   "&& 1"
718   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (minus:SI (const_int 0)
719                                                      (match_dup 1))
720                                            (const_int 0)))
721    (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
722                                                         (const_int 0))
723                                                (ltu:SI (reg:CC_NOOV CC_REG)
724                                                        (const_int 0)))))]
725   ""
726   [(set_attr "length" "2")])
727
728 (define_insn_and_split "*neg_snesi_sign_extend"
729   [(set (match_operand:DI 0 "register_operand" "=r")
730         (neg:DI (ne:DI (match_operand:SI 1 "register_operand" "r")
731                       (const_int 0))))
732    (clobber (reg:CC CC_REG))]
733   "TARGET_ARCH64"
734   "#"
735   "&& 1"
736   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (minus:SI (const_int 0)
737                                                      (match_dup 1))
738                                            (const_int 0)))
739    (set (match_dup 0) (sign_extend:DI (neg:SI (ltu:SI (reg:CC CC_REG)
740                                                       (const_int 0)))))]
741   ""
742   [(set_attr "length" "2")])
743
744 (define_insn_and_split "*snedi_zero"
745   [(set (match_operand:DI 0 "register_operand" "=&r")
746         (ne:DI (match_operand:DI 1 "register_operand" "r")
747                (const_int 0)))]
748   "TARGET_ARCH64 && ! TARGET_VIS3"
749   "#"
750   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
751   [(set (match_dup 0) (const_int 0))
752    (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
753                                               (const_int 0))
754                                        (const_int 1)
755                                        (match_dup 0)))]
756   ""
757   [(set_attr "length" "2")])
758
759 (define_insn_and_split "*snedi_zero_vis3"
760   [(set (match_operand:DI 0 "register_operand" "=r")
761         (ne:DI (match_operand:DI 1 "register_operand" "r")
762                (const_int 0)))
763    (clobber (reg:CCX CC_REG))]
764   "TARGET_ARCH64 && TARGET_VIS3"
765   "#"
766   ""
767   [(set (reg:CCX_NOOV CC_REG) (compare:CCX_NOOV (neg:DI (match_dup 1))
768                                                 (const_int 0)))
769    (set (match_dup 0) (ltu:DI (reg:CCX CC_REG) (const_int 0)))]
770   ""
771   [(set_attr "length" "2")])
772
773 (define_insn_and_split "*neg_snedi_zero"
774   [(set (match_operand:DI 0 "register_operand" "=&r")
775         (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
776                        (const_int 0))))]
777   "TARGET_ARCH64"
778   "#"
779   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
780   [(set (match_dup 0) (const_int 0))
781    (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
782                                               (const_int 0))
783                                        (const_int -1)
784                                        (match_dup 0)))]
785   ""
786   [(set_attr "length" "2")])
787
788 (define_insn_and_split "*snedi_zero_trunc"
789   [(set (match_operand:SI 0 "register_operand" "=&r")
790         (ne:SI (match_operand:DI 1 "register_operand" "r")
791                (const_int 0)))]
792   "TARGET_ARCH64 && ! TARGET_VIS3"
793   "#"
794   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
795   [(set (match_dup 0) (const_int 0))
796    (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
797                                               (const_int 0))
798                                        (const_int 1)
799                                        (match_dup 0)))]
800   ""
801   [(set_attr "length" "2")])
802
803 (define_insn_and_split "*snedi_zero_trunc_vis3"
804   [(set (match_operand:SI 0 "register_operand" "=r")
805         (ne:SI (match_operand:DI 1 "register_operand" "r")
806                (const_int 0)))
807    (clobber (reg:CCX CC_REG))]
808   "TARGET_ARCH64 && TARGET_VIS3"
809   "#"
810   ""
811   [(set (reg:CCX_NOOV CC_REG) (compare:CCX_NOOV (neg:DI (match_dup 1))
812                                                 (const_int 0)))
813    (set (match_dup 0) (ltu:SI (reg:CCX CC_REG) (const_int 0)))]
814   ""
815   [(set_attr "length" "2")])
816
817 (define_insn_and_split "*seqsi_zero"
818   [(set (match_operand:SI 0 "register_operand" "=r")
819         (eq:SI (match_operand:SI 1 "register_operand" "r")
820                (const_int 0)))
821    (clobber (reg:CC CC_REG))]
822   ""
823   "#"
824   ""
825   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
826                                            (const_int 0)))
827    (set (match_dup 0) (geu:SI (reg:CC CC_REG) (const_int 0)))]
828   ""
829   [(set_attr "length" "2")])
830
831 (define_insn_and_split "*neg_seqsi_zero"
832   [(set (match_operand:SI 0 "register_operand" "=r")
833         (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
834                        (const_int 0))))
835    (clobber (reg:CC CC_REG))]
836   ""
837   "#"
838   ""
839   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
840                                            (const_int 0)))
841    (set (match_dup 0) (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0))))]
842   ""
843   [(set_attr "length" "2")])
844
845 (define_insn_and_split "*seqsi_zero_extend"
846   [(set (match_operand:DI 0 "register_operand" "=r")
847         (eq:DI (match_operand:SI 1 "register_operand" "r")
848                (const_int 0)))
849    (clobber (reg:CC CC_REG))]
850   "TARGET_ARCH64"
851   "#"
852   "&& 1"
853   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (minus:SI (const_int 0)
854                                                      (match_dup 1))
855                                            (const_int 0)))
856    (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
857                                                           (const_int -1))
858                                                 (ltu:SI (reg:CC_NOOV CC_REG)
859                                                         (const_int 0)))))]
860   ""
861   [(set_attr "length" "2")])
862
863 (define_insn_and_split "*neg_seqsi_sign_extend"
864   [(set (match_operand:DI 0 "register_operand" "=r")
865         (neg:DI (eq:DI (match_operand:SI 1 "register_operand" "r")
866                        (const_int 0))))
867    (clobber (reg:CC CC_REG))]
868   "TARGET_ARCH64"
869   "#"
870   "&& 1"
871   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
872                                            (const_int 0)))
873    (set (match_dup 0) (sign_extend:DI (neg:SI (geu:SI (reg:CC CC_REG)
874                                                       (const_int 0)))))]
875   ""
876   [(set_attr "length" "2")])
877
878 (define_insn_and_split "*seqdi_zero"
879   [(set (match_operand:DI 0 "register_operand" "=&r")
880         (eq:DI (match_operand:DI 1 "register_operand" "r")
881                (const_int 0)))]
882   "TARGET_ARCH64"
883   "#"
884   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
885   [(set (match_dup 0) (const_int 0))
886    (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
887                                               (const_int 0))
888                                        (const_int 1)
889                                        (match_dup 0)))]
890   ""
891   [(set_attr "length" "2")])
892
893 (define_insn_and_split "*neg_seqdi_zero"
894   [(set (match_operand:DI 0 "register_operand" "=&r")
895         (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
896                        (const_int 0))))]
897   "TARGET_ARCH64"
898   "#"
899   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
900   [(set (match_dup 0) (const_int 0))
901    (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
902                                               (const_int 0))
903                                        (const_int -1)
904                                        (match_dup 0)))]
905   ""
906   [(set_attr "length" "2")]) 
907
908 (define_insn_and_split "*seqdi_zero_trunc"
909   [(set (match_operand:SI 0 "register_operand" "=&r")
910         (eq:SI (match_operand:DI 1 "register_operand" "r")
911                (const_int 0)))]
912   "TARGET_ARCH64"
913   "#"
914   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
915   [(set (match_dup 0) (const_int 0))
916    (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
917                                               (const_int 0))
918                                        (const_int 1)
919                                        (match_dup 0)))]
920   ""
921   [(set_attr "length" "2")])
922
923 ;; We can also do (x + (i == 0)) and related, so put them in.
924 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
925 ;; versions for v9.
926
927 (define_insn_and_split "*x_plus_i_ne_0"
928   [(set (match_operand:SI 0 "register_operand" "=r")
929         (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
930                         (const_int 0))
931                  (match_operand:SI 2 "register_operand" "r")))
932    (clobber (reg:CC CC_REG))]
933   ""
934   "#"
935   ""
936   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
937                                            (const_int 0)))
938    (set (match_dup 0) (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
939                                (match_dup 2)))]
940   ""
941   [(set_attr "length" "2")])
942
943 (define_insn_and_split "*x_minus_i_ne_0"
944   [(set (match_operand:SI 0 "register_operand" "=r")
945         (minus:SI (match_operand:SI 2 "register_operand" "r")
946                   (ne:SI (match_operand:SI 1 "register_operand" "r")
947                          (const_int 0))))
948    (clobber (reg:CC CC_REG))]
949   ""
950   "#"
951   ""
952   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
953                                            (const_int 0)))
954    (set (match_dup 0) (minus:SI (match_dup 2)
955                                 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
956   ""
957   [(set_attr "length" "2")])
958
959 (define_insn_and_split "*x_plus_i_eq_0"
960   [(set (match_operand:SI 0 "register_operand" "=r")
961         (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
962                         (const_int 0))
963                  (match_operand:SI 2 "register_operand" "r")))
964    (clobber (reg:CC CC_REG))]
965   ""
966   "#"
967   ""
968   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
969                                            (const_int 0)))
970    (set (match_dup 0) (plus:SI (geu:SI (reg:CC CC_REG) (const_int 0))
971                                (match_dup 2)))]
972   ""
973   [(set_attr "length" "2")])
974
975 (define_insn_and_split "*x_minus_i_eq_0"
976   [(set (match_operand:SI 0 "register_operand" "=r")
977         (minus:SI (match_operand:SI 2 "register_operand" "r")
978                   (eq:SI (match_operand:SI 1 "register_operand" "r")
979                          (const_int 0))))
980    (clobber (reg:CC CC_REG))]
981   ""
982   "#"
983   ""
984   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
985                                            (const_int 0)))
986    (set (match_dup 0) (minus:SI (match_dup 2)
987                                 (geu:SI (reg:CC CC_REG) (const_int 0))))]
988   ""
989   [(set_attr "length" "2")])
990
991 ;; We can also do GEU and LTU directly, but these operate after a compare.
992 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
993 ;; versions for v9.
994
995 (define_insn "*sltu_insn"
996   [(set (match_operand:SI 0 "register_operand" "=r")
997         (ltu:SI (reg:CC CC_REG) (const_int 0)))]
998   ""
999   "addx\t%%g0, 0, %0"
1000   [(set_attr "type" "ialuX")])
1001
1002 (define_insn "*sltu_insn_vis3"
1003   [(set (match_operand:DI 0 "register_operand" "=r")
1004         (ltu:DI (reg:CCX CC_REG) (const_int 0)))]
1005   "TARGET_ARCH64 && TARGET_VIS3"
1006   "addxc\t%%g0, %%g0, %0"
1007   [(set_attr "type" "ialuX")])
1008
1009 (define_insn "*sltu_insn_vis3_trunc"
1010   [(set (match_operand:SI 0 "register_operand" "=r")
1011         (ltu:SI (reg:CCX CC_REG) (const_int 0)))]
1012   "TARGET_ARCH64 && TARGET_VIS3"
1013   "addxc\t%%g0, %%g0, %0"
1014   [(set_attr "type" "ialuX")])
1015
1016 (define_insn "*sltu_extend_sp64"
1017   [(set (match_operand:DI 0 "register_operand" "=r")
1018         (ltu:DI (reg:CC CC_REG) (const_int 0)))]
1019   "TARGET_ARCH64"
1020   "addx\t%%g0, 0, %0"
1021   [(set_attr "type" "ialuX")])
1022
1023 (define_insn "*neg_sltu_insn"
1024   [(set (match_operand:SI 0 "register_operand" "=r")
1025         (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0))))]
1026   ""
1027   "subx\t%%g0, 0, %0"
1028   [(set_attr "type" "ialuX")])
1029
1030 (define_insn "*neg_sltu_extend_sp64"
1031   [(set (match_operand:DI 0 "register_operand" "=r")
1032         (sign_extend:DI (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0)))))]
1033   "TARGET_ARCH64"
1034   "subx\t%%g0, 0, %0"
1035   [(set_attr "type" "ialuX")])
1036
1037 ;; ??? Combine should canonicalize these next two to the same pattern.
1038 (define_insn "*neg_sltu_minus_x"
1039   [(set (match_operand:SI 0 "register_operand" "=r")
1040         (minus:SI (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0)))
1041                   (match_operand:SI 1 "arith_operand" "rI")))]
1042   ""
1043   "subx\t%%g0, %1, %0"
1044   [(set_attr "type" "ialuX")])
1045
1046 (define_insn "*neg_sltu_plus_x"
1047   [(set (match_operand:SI 0 "register_operand" "=r")
1048         (neg:SI (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
1049                          (match_operand:SI 1 "arith_operand" "rI"))))]
1050   ""
1051   "subx\t%%g0, %1, %0"
1052   [(set_attr "type" "ialuX")])
1053
1054 (define_insn "*sgeu_insn"
1055   [(set (match_operand:SI 0 "register_operand" "=r")
1056         (geu:SI (reg:CC CC_REG) (const_int 0)))]
1057   ""
1058   "subx\t%%g0, -1, %0"
1059   [(set_attr "type" "ialuX")])
1060
1061 (define_insn "*sgeu_extend_sp64"
1062   [(set (match_operand:DI 0 "register_operand" "=r")
1063         (geu:DI (reg:CC CC_REG) (const_int 0)))]
1064   "TARGET_ARCH64"
1065   "subx\t%%g0, -1, %0"
1066   [(set_attr "type" "ialuX")])
1067
1068 (define_insn "*neg_sgeu_insn"
1069   [(set (match_operand:SI 0 "register_operand" "=r")
1070         (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0))))]
1071   ""
1072   "addx\t%%g0, -1, %0"
1073   [(set_attr "type" "ialuX")])
1074
1075 (define_insn "*neg_sgeu_extend_sp64"
1076   [(set (match_operand:DI 0 "register_operand" "=r")
1077         (sign_extend:DI (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0)))))]
1078   "TARGET_ARCH64"
1079   "addx\t%%g0, -1, %0"
1080   [(set_attr "type" "ialuX")])
1081
1082 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
1083 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1084 ;; versions for v9.
1085
1086 (define_insn "*sltu_plus_x"
1087   [(set (match_operand:SI 0 "register_operand" "=r")
1088         (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
1089                  (match_operand:SI 1 "arith_operand" "rI")))]
1090   ""
1091   "addx\t%%g0, %1, %0"
1092   [(set_attr "type" "ialuX")])
1093
1094 (define_insn "*sltu_plus_x_plus_y"
1095   [(set (match_operand:SI 0 "register_operand" "=r")
1096         (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
1097                  (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1098                           (match_operand:SI 2 "arith_operand" "rI"))))]
1099   ""
1100   "addx\t%1, %2, %0"
1101   [(set_attr "type" "ialuX")])
1102
1103 (define_insn "*x_minus_sltu"
1104   [(set (match_operand:SI 0 "register_operand" "=r")
1105         (minus:SI (match_operand:SI 1 "register_operand" "r")
1106                   (ltu:SI (reg:CC CC_REG) (const_int 0))))]
1107   ""
1108   "subx\t%1, 0, %0"
1109   [(set_attr "type" "ialuX")])
1110
1111 ;; ??? Combine should canonicalize these next two to the same pattern.
1112 (define_insn "*x_minus_y_minus_sltu"
1113   [(set (match_operand:SI 0 "register_operand" "=r")
1114         (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
1115                             (match_operand:SI 2 "arith_operand" "rI"))
1116                   (ltu:SI (reg:CC CC_REG) (const_int 0))))]
1117   ""
1118   "subx\t%r1, %2, %0"
1119   [(set_attr "type" "ialuX")])
1120
1121 (define_insn "*x_minus_sltu_plus_y"
1122   [(set (match_operand:SI 0 "register_operand" "=r")
1123         (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
1124                   (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
1125                            (match_operand:SI 2 "arith_operand" "rI"))))]
1126   ""
1127   "subx\t%r1, %2, %0"
1128   [(set_attr "type" "ialuX")])
1129
1130 (define_insn "*sgeu_plus_x"
1131   [(set (match_operand:SI 0 "register_operand" "=r")
1132         (plus:SI (geu:SI (reg:CC CC_REG) (const_int 0))
1133                  (match_operand:SI 1 "register_operand" "r")))]
1134   ""
1135   "subx\t%1, -1, %0"
1136   [(set_attr "type" "ialuX")])
1137
1138 (define_insn "*x_minus_sgeu"
1139   [(set (match_operand:SI 0 "register_operand" "=r")
1140         (minus:SI (match_operand:SI 1 "register_operand" "r")
1141                   (geu:SI (reg:CC CC_REG) (const_int 0))))]
1142   ""
1143   "addx\t%1, -1, %0"
1144   [(set_attr "type" "ialuX")])
1145
1146 (define_split
1147   [(set (match_operand:SI 0 "register_operand" "")
1148         (match_operator:SI 2 "noov_compare_operator"
1149                            [(match_operand 1 "icc_or_fcc_register_operand" "")
1150                             (const_int 0)]))]
1151   "TARGET_V9
1152    && REGNO (operands[1]) == SPARC_ICC_REG
1153    && (GET_MODE (operands[1]) == CCXmode
1154        /* 32-bit LTU/GEU are better implemented using addx/subx.  */
1155        || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1156   [(set (match_dup 0) (const_int 0))
1157    (set (match_dup 0)
1158         (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1159                          (const_int 1)
1160                          (match_dup 0)))]
1161   "")
1162
1163 \f
1164 ;; These control RTL generation for conditional jump insns
1165
1166 (define_expand "cbranchcc4"
1167   [(set (pc)
1168         (if_then_else (match_operator 0 "comparison_operator"
1169                           [(match_operand 1 "compare_operand" "")
1170                            (match_operand 2 "const_zero_operand" "")])
1171                       (label_ref (match_operand 3 "" ""))
1172                       (pc)))]
1173   ""
1174   "")
1175
1176 (define_expand "cbranchsi4"
1177   [(use (match_operator 0 "comparison_operator"
1178          [(match_operand:SI 1 "compare_operand" "")
1179           (match_operand:SI 2 "arith_operand" "")]))
1180    (use (match_operand 3 ""))]
1181   ""
1182 {
1183   if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
1184     operands[1] = force_reg (SImode, operands[1]);
1185   emit_conditional_branch_insn (operands);
1186   DONE;
1187 })
1188
1189 (define_expand "cbranchdi4"
1190   [(use (match_operator 0 "comparison_operator"
1191          [(match_operand:DI 1 "compare_operand" "")
1192           (match_operand:DI 2 "arith_operand" "")]))
1193    (use (match_operand 3 ""))]
1194   "TARGET_ARCH64"
1195 {
1196   if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
1197     operands[1] = force_reg (DImode, operands[1]);
1198   emit_conditional_branch_insn (operands);
1199   DONE;
1200 })
1201
1202 (define_expand "cbranch<F:mode>4"
1203   [(use (match_operator 0 "comparison_operator"
1204          [(match_operand:F 1 "register_operand" "")
1205           (match_operand:F 2 "register_operand" "")]))
1206    (use (match_operand 3 ""))]
1207   "TARGET_FPU"
1208   { emit_conditional_branch_insn (operands); DONE; })
1209
1210
1211 ;; Now match both normal and inverted jump.
1212
1213 ;; XXX fpcmp nop braindamage
1214 (define_insn "*normal_branch"
1215   [(set (pc)
1216         (if_then_else (match_operator 0 "noov_compare_operator"
1217                                       [(reg CC_REG) (const_int 0)])
1218                       (label_ref (match_operand 1 "" ""))
1219                       (pc)))]
1220   ""
1221 {
1222   return output_cbranch (operands[0], operands[1], 1, 0,
1223                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1224                          insn);
1225 }
1226   [(set_attr "type" "branch")
1227    (set_attr "branch_type" "icc")])
1228
1229 ;; XXX fpcmp nop braindamage
1230 (define_insn "*inverted_branch"
1231   [(set (pc)
1232         (if_then_else (match_operator 0 "noov_compare_operator"
1233                                       [(reg CC_REG) (const_int 0)])
1234                       (pc)
1235                       (label_ref (match_operand 1 "" ""))))]
1236   ""
1237 {
1238   return output_cbranch (operands[0], operands[1], 1, 1,
1239                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1240                          insn);
1241 }
1242   [(set_attr "type" "branch")
1243    (set_attr "branch_type" "icc")])
1244
1245 ;; XXX fpcmp nop braindamage
1246 (define_insn "*normal_fp_branch"
1247   [(set (pc)
1248         (if_then_else (match_operator 1 "comparison_operator"
1249                                       [(match_operand:CCFP 0 "fcc_register_operand" "c")
1250                                        (const_int 0)])
1251                       (label_ref (match_operand 2 "" ""))
1252                       (pc)))]
1253   ""
1254 {
1255   return output_cbranch (operands[1], operands[2], 2, 0,
1256                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1257                          insn);
1258 }
1259   [(set_attr "type" "branch")
1260    (set_attr "branch_type" "fcc")])
1261
1262 ;; XXX fpcmp nop braindamage
1263 (define_insn "*inverted_fp_branch"
1264   [(set (pc)
1265         (if_then_else (match_operator 1 "comparison_operator"
1266                                       [(match_operand:CCFP 0 "fcc_register_operand" "c")
1267                                        (const_int 0)])
1268                       (pc)
1269                       (label_ref (match_operand 2 "" ""))))]
1270   ""
1271 {
1272   return output_cbranch (operands[1], operands[2], 2, 1,
1273                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1274                          insn);
1275 }
1276   [(set_attr "type" "branch")
1277    (set_attr "branch_type" "fcc")])
1278
1279 ;; XXX fpcmp nop braindamage
1280 (define_insn "*normal_fpe_branch"
1281   [(set (pc)
1282         (if_then_else (match_operator 1 "comparison_operator"
1283                                       [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1284                                        (const_int 0)])
1285                       (label_ref (match_operand 2 "" ""))
1286                       (pc)))]
1287   ""
1288 {
1289   return output_cbranch (operands[1], operands[2], 2, 0,
1290                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1291                          insn);
1292 }
1293   [(set_attr "type" "branch")
1294    (set_attr "branch_type" "fcc")])
1295
1296 ;; XXX fpcmp nop braindamage
1297 (define_insn "*inverted_fpe_branch"
1298   [(set (pc)
1299         (if_then_else (match_operator 1 "comparison_operator"
1300                                       [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1301                                        (const_int 0)])
1302                       (pc)
1303                       (label_ref (match_operand 2 "" ""))))]
1304   ""
1305 {
1306   return output_cbranch (operands[1], operands[2], 2, 1,
1307                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1308                          insn);
1309 }
1310   [(set_attr "type" "branch")
1311    (set_attr "branch_type" "fcc")])
1312
1313 ;; SPARC V9-specific jump insns.  None of these are guaranteed to be
1314 ;; in the architecture.
1315
1316 ;; There are no 32 bit brreg insns.
1317
1318 ;; XXX
1319 (define_insn "*normal_int_branch_sp64"
1320   [(set (pc)
1321         (if_then_else (match_operator 0 "v9_register_compare_operator"
1322                                       [(match_operand:DI 1 "register_operand" "r")
1323                                        (const_int 0)])
1324                       (label_ref (match_operand 2 "" ""))
1325                       (pc)))]
1326   "TARGET_ARCH64"
1327 {
1328   return output_v9branch (operands[0], operands[2], 1, 2, 0,
1329                           final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1330                           insn);
1331 }
1332   [(set_attr "type" "branch")
1333    (set_attr "branch_type" "reg")])
1334
1335 ;; XXX
1336 (define_insn "*inverted_int_branch_sp64"
1337   [(set (pc)
1338         (if_then_else (match_operator 0 "v9_register_compare_operator"
1339                                       [(match_operand:DI 1 "register_operand" "r")
1340                                        (const_int 0)])
1341                       (pc)
1342                       (label_ref (match_operand 2 "" ""))))]
1343   "TARGET_ARCH64"
1344 {
1345   return output_v9branch (operands[0], operands[2], 1, 2, 1,
1346                           final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1347                           insn);
1348 }
1349   [(set_attr "type" "branch")
1350    (set_attr "branch_type" "reg")])
1351
1352
1353 ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic
1354 ;; value subject to a PC-relative relocation.  Operand 2 is a helper function
1355 ;; that adds the PC value at the call point to register #(operand 3).
1356
1357 (define_insn "load_pcrel_sym<P:mode>"
1358   [(set (match_operand:P 0 "register_operand" "=r")
1359         (unspec:P [(match_operand:P 1 "symbolic_operand" "")
1360                    (match_operand:P 2 "call_address_operand" "")
1361                    (match_operand:P 3 "const_int_operand" "")] UNSPEC_LOAD_PCREL_SYM))
1362    (clobber (reg:P O7_REG))]
1363   "REGNO (operands[0]) == INTVAL (operands[3])"
1364 {
1365   if (flag_delayed_branch)
1366     return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0";
1367   else
1368     return "sethi\t%%hi(%a1-8), %0\n\tadd\t%0, %%lo(%a1-4), %0\n\tcall\t%a2\n\t nop";
1369 }
1370   [(set (attr "type") (const_string "multi"))
1371    (set (attr "length")
1372         (if_then_else (eq_attr "delayed_branch" "true")
1373                       (const_int 3)
1374                       (const_int 4)))])
1375
1376
1377 ;; Integer move instructions
1378
1379 (define_expand "movqi"
1380   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1381         (match_operand:QI 1 "general_operand" ""))]
1382   ""
1383 {
1384   if (sparc_expand_move (QImode, operands))
1385     DONE;
1386 })
1387
1388 (define_insn "*movqi_insn"
1389   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1390         (match_operand:QI 1 "input_operand"   "rI,m,rJ"))]
1391   "(register_operand (operands[0], QImode)
1392     || register_or_zero_operand (operands[1], QImode))"
1393   "@
1394    mov\t%1, %0
1395    ldub\t%1, %0
1396    stb\t%r1, %0"
1397   [(set_attr "type" "*,load,store")
1398    (set_attr "us3load_type" "*,3cycle,*")])
1399
1400 (define_expand "movhi"
1401   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1402         (match_operand:HI 1 "general_operand" ""))]
1403   ""
1404 {
1405   if (sparc_expand_move (HImode, operands))
1406     DONE;
1407 })
1408
1409 (define_insn "*movhi_insn"
1410   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1411         (match_operand:HI 1 "input_operand"   "rI,K,m,rJ"))]
1412   "(register_operand (operands[0], HImode)
1413     || register_or_zero_operand (operands[1], HImode))"
1414   "@
1415    mov\t%1, %0
1416    sethi\t%%hi(%a1), %0
1417    lduh\t%1, %0
1418    sth\t%r1, %0"
1419   [(set_attr "type" "*,*,load,store")
1420    (set_attr "us3load_type" "*,*,3cycle,*")])
1421
1422 ;; We always work with constants here.
1423 (define_insn "*movhi_lo_sum"
1424   [(set (match_operand:HI 0 "register_operand" "=r")
1425         (ior:HI (match_operand:HI 1 "register_operand" "%r")
1426                 (match_operand:HI 2 "small_int_operand" "I")))]
1427   ""
1428   "or\t%1, %2, %0")
1429
1430 (define_expand "movsi"
1431   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1432         (match_operand:SI 1 "general_operand" ""))]
1433   ""
1434 {
1435   if (sparc_expand_move (SImode, operands))
1436     DONE;
1437 })
1438
1439 (define_insn "*movsi_insn"
1440   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r, m, r,*f,*f,*f, m,d,d")
1441         (match_operand:SI 1 "input_operand"        "rI,K,m,rJ,*f, r, f, m,*f,J,P"))]
1442   "register_operand (operands[0], SImode)
1443    || register_or_zero_or_all_ones_operand (operands[1], SImode)"
1444   "@
1445    mov\t%1, %0
1446    sethi\t%%hi(%a1), %0
1447    ld\t%1, %0
1448    st\t%r1, %0
1449    movstouw\t%1, %0
1450    movwtos\t%1, %0
1451    fmovs\t%1, %0
1452    ld\t%1, %0
1453    st\t%1, %0
1454    fzeros\t%0
1455    fones\t%0"
1456   [(set_attr "type" "*,*,load,store,*,*,fpmove,fpload,fpstore,fga,fga")
1457    (set_attr "cpu_feature" "*,*,*,*,vis3,vis3,*,*,*,vis,vis")])
1458
1459 (define_insn "*movsi_lo_sum"
1460   [(set (match_operand:SI 0 "register_operand" "=r")
1461         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1462                    (match_operand:SI 2 "immediate_operand" "in")))]
1463   ""
1464   "or\t%1, %%lo(%a2), %0")
1465
1466 (define_insn "*movsi_high"
1467   [(set (match_operand:SI 0 "register_operand" "=r")
1468         (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1469   ""
1470   "sethi\t%%hi(%a1), %0")
1471
1472 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1473 ;; so that CSE won't optimize the address computation away.
1474 (define_insn "movsi_lo_sum_pic"
1475   [(set (match_operand:SI 0 "register_operand" "=r")
1476         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1477                    (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1478   "flag_pic"
1479 {
1480 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1481   return "xor\t%1, %%gdop_lox10(%a2), %0";
1482 #else
1483   return "or\t%1, %%lo(%a2), %0";
1484 #endif
1485 })
1486
1487 (define_insn "movsi_high_pic"
1488   [(set (match_operand:SI 0 "register_operand" "=r")
1489         (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1490   "flag_pic && check_pic (1)"
1491 {
1492 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1493   return "sethi\t%%gdop_hix22(%a1), %0";
1494 #else
1495   return "sethi\t%%hi(%a1), %0";
1496 #endif
1497 })
1498
1499 (define_insn "movsi_pic_gotdata_op"
1500   [(set (match_operand:SI 0 "register_operand" "=r")
1501         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
1502                     (match_operand:SI 2 "register_operand" "r")
1503                     (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
1504   "flag_pic && check_pic (1)"
1505 {
1506 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1507   return "ld\t[%1 + %2], %0, %%gdop(%a3)";
1508 #else
1509   return "ld\t[%1 + %2], %0";
1510 #endif
1511 }
1512   [(set_attr "type" "load")])
1513
1514 (define_expand "movsi_pic_label_ref"
1515   [(set (match_dup 3) (high:SI
1516      (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1517                  (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1518    (set (match_dup 4) (lo_sum:SI (match_dup 3)
1519      (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1520    (set (match_operand:SI 0 "register_operand" "=r")
1521         (minus:SI (match_dup 5) (match_dup 4)))]
1522   "flag_pic"
1523 {
1524   crtl->uses_pic_offset_table = 1;
1525   operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1526   if (!can_create_pseudo_p ())
1527     {
1528       operands[3] = operands[0];
1529       operands[4] = operands[0];
1530     }
1531   else
1532     {
1533       operands[3] = gen_reg_rtx (SImode);
1534       operands[4] = gen_reg_rtx (SImode);
1535     }
1536   operands[5] = pic_offset_table_rtx;
1537 })
1538
1539 (define_insn "*movsi_high_pic_label_ref"
1540   [(set (match_operand:SI 0 "register_operand" "=r")
1541       (high:SI
1542         (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1543                     (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1544   "flag_pic"
1545   "sethi\t%%hi(%a2-(%a1-.)), %0")
1546
1547 (define_insn "*movsi_lo_sum_pic_label_ref"
1548   [(set (match_operand:SI 0 "register_operand" "=r")
1549       (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1550         (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
1551                     (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1552   "flag_pic"
1553   "or\t%1, %%lo(%a3-(%a2-.)), %0")
1554
1555 ;; Set up the PIC register for VxWorks.
1556
1557 (define_expand "vxworks_load_got"
1558   [(set (match_dup 0)
1559         (high:SI (match_dup 1)))
1560    (set (match_dup 0)
1561         (mem:SI (lo_sum:SI (match_dup 0) (match_dup 1))))
1562    (set (match_dup 0)
1563         (mem:SI (lo_sum:SI (match_dup 0) (match_dup 2))))]
1564   "TARGET_VXWORKS_RTP"
1565 {
1566   operands[0] = pic_offset_table_rtx;
1567   operands[1] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_BASE);
1568   operands[2] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_INDEX);
1569 })
1570
1571 (define_expand "movdi"
1572   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1573         (match_operand:DI 1 "general_operand" ""))]
1574   ""
1575 {
1576   if (sparc_expand_move (DImode, operands))
1577     DONE;
1578 })
1579
1580 ;; Be careful, fmovd does not exist when !v9.
1581 ;; We match MEM moves directly when we have correct even
1582 ;; numbered registers, but fall into splits otherwise.
1583 ;; The constraint ordering here is really important to
1584 ;; avoid insane problems in reload, especially for patterns
1585 ;; of the form:
1586 ;;
1587 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
1588 ;;                       (const_int -5016)))
1589 ;;      (reg:DI 2 %g2))
1590 ;;
1591
1592 (define_insn "*movdi_insn_sp32"
1593   [(set (match_operand:DI 0 "nonimmediate_operand"
1594                                         "=T,o,T,U,o,r,r,r,?T,?*f,?*f,?o,?*e,?*e,  r,?*f,?*e,?W,b,b")
1595         (match_operand:DI 1 "input_operand"
1596                                         " J,J,U,T,r,o,i,r,*f,  T,  o,*f, *e, *e,?*f,  r,  W,*e,J,P"))]
1597   "! TARGET_ARCH64
1598    && (register_operand (operands[0], DImode)
1599        || register_or_zero_operand (operands[1], DImode))"
1600   "@
1601    stx\t%%g0, %0
1602    #
1603    std\t%1, %0
1604    ldd\t%1, %0
1605    #
1606    #
1607    #
1608    #
1609    std\t%1, %0
1610    ldd\t%1, %0
1611    #
1612    #
1613    fmovd\t%1, %0
1614    #
1615    #
1616    #
1617    ldd\t%1, %0
1618    std\t%1, %0
1619    fzero\t%0
1620    fone\t%0"
1621   [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,*,*,*,fpload,fpstore,fga,fga")
1622    (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,2,2,2,*,*,*,*")
1623    (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*,*,*,*,double,double")
1624    (set_attr "cpu_feature" "v9,*,*,*,*,*,*,*,fpu,fpu,fpu,fpu,v9,fpunotv9,vis3,vis3,fpu,fpu,vis,vis")])
1625
1626 (define_insn "*movdi_insn_sp64"
1627   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r, m, r,*e,?*e,?*e,?W,b,b")
1628         (match_operand:DI 1 "input_operand"        "rI,N,m,rJ,*e, r, *e,  W,*e,J,P"))]
1629   "TARGET_ARCH64
1630    && (register_operand (operands[0], DImode)
1631        || register_or_zero_or_all_ones_operand (operands[1], DImode))"
1632   "@
1633    mov\t%1, %0
1634    sethi\t%%hi(%a1), %0
1635    ldx\t%1, %0
1636    stx\t%r1, %0
1637    movdtox\t%1, %0
1638    movxtod\t%1, %0
1639    fmovd\t%1, %0
1640    ldd\t%1, %0
1641    std\t%1, %0
1642    fzero\t%0
1643    fone\t%0"
1644   [(set_attr "type" "*,*,load,store,*,*,fpmove,fpload,fpstore,fga,fga")
1645    (set_attr "fptype" "*,*,*,*,*,*,double,*,*,double,double")
1646    (set_attr "cpu_feature" "*,*,*,*,vis3,vis3,*,*,*,vis,vis")])
1647
1648 (define_expand "movdi_pic_label_ref"
1649   [(set (match_dup 3) (high:DI
1650      (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1651                  (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1652    (set (match_dup 4) (lo_sum:DI (match_dup 3)
1653      (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1654    (set (match_operand:DI 0 "register_operand" "=r")
1655         (minus:DI (match_dup 5) (match_dup 4)))]
1656   "TARGET_ARCH64 && flag_pic"
1657 {
1658   crtl->uses_pic_offset_table = 1;
1659   operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1660   if (!can_create_pseudo_p ())
1661     {
1662       operands[3] = operands[0];
1663       operands[4] = operands[0];
1664     }
1665   else
1666     {
1667       operands[3] = gen_reg_rtx (DImode);
1668       operands[4] = gen_reg_rtx (DImode);
1669     }
1670   operands[5] = pic_offset_table_rtx;
1671 })
1672
1673 (define_insn "*movdi_high_pic_label_ref"
1674   [(set (match_operand:DI 0 "register_operand" "=r")
1675         (high:DI
1676           (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1677                       (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1678   "TARGET_ARCH64 && flag_pic"
1679   "sethi\t%%hi(%a2-(%a1-.)), %0")
1680
1681 (define_insn "*movdi_lo_sum_pic_label_ref"
1682   [(set (match_operand:DI 0 "register_operand" "=r")
1683       (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1684         (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
1685                     (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1686   "TARGET_ARCH64 && flag_pic"
1687   "or\t%1, %%lo(%a3-(%a2-.)), %0")
1688
1689 ;; SPARC-v9 code model support insns.  See sparc_emit_set_symbolic_const64
1690 ;; in sparc.c to see what is going on here... PIC stuff comes first.
1691
1692 (define_insn "movdi_lo_sum_pic"
1693   [(set (match_operand:DI 0 "register_operand" "=r")
1694         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1695                    (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1696   "TARGET_ARCH64 && flag_pic"
1697 {
1698 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1699   return "xor\t%1, %%gdop_lox10(%a2), %0";
1700 #else
1701   return "or\t%1, %%lo(%a2), %0";
1702 #endif
1703 })
1704
1705 (define_insn "movdi_high_pic"
1706   [(set (match_operand:DI 0 "register_operand" "=r")
1707         (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1708   "TARGET_ARCH64 && flag_pic && check_pic (1)"
1709 {
1710 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1711   return "sethi\t%%gdop_hix22(%a1), %0";
1712 #else
1713   return "sethi\t%%hi(%a1), %0";
1714 #endif
1715 })
1716
1717 (define_insn "movdi_pic_gotdata_op"
1718   [(set (match_operand:DI 0 "register_operand" "=r")
1719         (unspec:DI [(match_operand:DI 1 "register_operand" "r")
1720                     (match_operand:DI 2 "register_operand" "r")
1721                     (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
1722   "TARGET_ARCH64 && flag_pic && check_pic (1)"
1723 {
1724 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1725   return "ldx\t[%1 + %2], %0, %%gdop(%a3)";
1726 #else
1727   return "ldx\t[%1 + %2], %0";
1728 #endif
1729 }
1730   [(set_attr "type" "load")])
1731
1732 (define_insn "*sethi_di_medlow_embmedany_pic"
1733   [(set (match_operand:DI 0 "register_operand" "=r")
1734         (high:DI (match_operand:DI 1 "medium_pic_operand" "")))]
1735   "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
1736   "sethi\t%%hi(%a1), %0")
1737
1738 (define_insn "*sethi_di_medlow"
1739   [(set (match_operand:DI 0 "register_operand" "=r")
1740         (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
1741   "TARGET_CM_MEDLOW && check_pic (1)"
1742   "sethi\t%%hi(%a1), %0")
1743
1744 (define_insn "*losum_di_medlow"
1745   [(set (match_operand:DI 0 "register_operand" "=r")
1746         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1747                    (match_operand:DI 2 "symbolic_operand" "")))]
1748   "TARGET_CM_MEDLOW"
1749   "or\t%1, %%lo(%a2), %0")
1750
1751 (define_insn "seth44"
1752   [(set (match_operand:DI 0 "register_operand" "=r")
1753         (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
1754   "TARGET_CM_MEDMID"
1755   "sethi\t%%h44(%a1), %0")
1756
1757 (define_insn "setm44"
1758   [(set (match_operand:DI 0 "register_operand" "=r")
1759         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1760                    (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
1761   "TARGET_CM_MEDMID"
1762   "or\t%1, %%m44(%a2), %0")
1763
1764 (define_insn "setl44"
1765   [(set (match_operand:DI 0 "register_operand" "=r")
1766         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1767                    (match_operand:DI 2 "symbolic_operand" "")))]
1768   "TARGET_CM_MEDMID"
1769   "or\t%1, %%l44(%a2), %0")
1770
1771 (define_insn "sethh"
1772   [(set (match_operand:DI 0 "register_operand" "=r")
1773         (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
1774   "TARGET_CM_MEDANY"
1775   "sethi\t%%hh(%a1), %0")
1776
1777 (define_insn "setlm"
1778   [(set (match_operand:DI 0 "register_operand" "=r")
1779         (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
1780   "TARGET_CM_MEDANY"
1781   "sethi\t%%lm(%a1), %0")
1782
1783 (define_insn "sethm"
1784   [(set (match_operand:DI 0 "register_operand" "=r")
1785         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1786                    (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
1787   "TARGET_CM_MEDANY"
1788   "or\t%1, %%hm(%a2), %0")
1789
1790 (define_insn "setlo"
1791   [(set (match_operand:DI 0 "register_operand" "=r")
1792         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1793                    (match_operand:DI 2 "symbolic_operand" "")))]
1794   "TARGET_CM_MEDANY"
1795   "or\t%1, %%lo(%a2), %0")
1796
1797 (define_insn "embmedany_sethi"
1798   [(set (match_operand:DI 0 "register_operand" "=r")
1799         (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
1800   "TARGET_CM_EMBMEDANY && check_pic (1)"
1801   "sethi\t%%hi(%a1), %0")
1802
1803 (define_insn "embmedany_losum"
1804   [(set (match_operand:DI 0 "register_operand" "=r")
1805         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1806                    (match_operand:DI 2 "data_segment_operand" "")))]
1807   "TARGET_CM_EMBMEDANY"
1808   "add\t%1, %%lo(%a2), %0")
1809
1810 (define_insn "embmedany_brsum"
1811   [(set (match_operand:DI 0 "register_operand" "=r")
1812         (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
1813   "TARGET_CM_EMBMEDANY"
1814   "add\t%1, %_, %0")
1815
1816 (define_insn "embmedany_textuhi"
1817   [(set (match_operand:DI 0 "register_operand" "=r")
1818         (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
1819   "TARGET_CM_EMBMEDANY && check_pic (1)"
1820   "sethi\t%%uhi(%a1), %0")
1821
1822 (define_insn "embmedany_texthi"
1823   [(set (match_operand:DI 0 "register_operand" "=r")
1824         (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
1825   "TARGET_CM_EMBMEDANY && check_pic (1)"
1826   "sethi\t%%hi(%a1), %0")
1827
1828 (define_insn "embmedany_textulo"
1829   [(set (match_operand:DI 0 "register_operand" "=r")
1830         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1831                    (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
1832   "TARGET_CM_EMBMEDANY"
1833   "or\t%1, %%ulo(%a2), %0")
1834
1835 (define_insn "embmedany_textlo"
1836   [(set (match_operand:DI 0 "register_operand" "=r")
1837         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1838                    (match_operand:DI 2 "text_segment_operand" "")))]
1839   "TARGET_CM_EMBMEDANY"
1840   "or\t%1, %%lo(%a2), %0")
1841
1842 ;; Now some patterns to help reload out a bit.
1843 (define_expand "reload_indi"
1844   [(parallel [(match_operand:DI 0 "register_operand" "=r")
1845               (match_operand:DI 1 "immediate_operand" "")
1846               (match_operand:TI 2 "register_operand" "=&r")])]
1847   "(TARGET_CM_MEDANY
1848     || TARGET_CM_EMBMEDANY)
1849    && ! flag_pic"
1850 {
1851   sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1852   DONE;
1853 })
1854
1855 (define_expand "reload_outdi"
1856   [(parallel [(match_operand:DI 0 "register_operand" "=r")
1857               (match_operand:DI 1 "immediate_operand" "")
1858               (match_operand:TI 2 "register_operand" "=&r")])]
1859   "(TARGET_CM_MEDANY
1860     || TARGET_CM_EMBMEDANY)
1861    && ! flag_pic"
1862 {
1863   sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1864   DONE;
1865 })
1866
1867 ;; Split up putting CONSTs and REGs into DI regs when !arch64
1868 (define_split
1869   [(set (match_operand:DI 0 "register_operand" "")
1870         (match_operand:DI 1 "const_int_operand" ""))]
1871   "! TARGET_ARCH64
1872    && ((GET_CODE (operands[0]) == REG
1873         && SPARC_INT_REG_P (REGNO (operands[0])))
1874        || (GET_CODE (operands[0]) == SUBREG
1875            && GET_CODE (SUBREG_REG (operands[0])) == REG
1876            && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))
1877    && reload_completed"
1878   [(clobber (const_int 0))]
1879 {
1880 #if HOST_BITS_PER_WIDE_INT == 32
1881   emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1882                         (INTVAL (operands[1]) < 0) ?
1883                         constm1_rtx :
1884                         const0_rtx));
1885   emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1886                         operands[1]));
1887 #else
1888   unsigned int low, high;
1889
1890   low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
1891   high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
1892   emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
1893
1894   /* Slick... but this trick loses if this subreg constant part
1895      can be done in one insn.  */
1896   if (low == high
1897       && ! SPARC_SETHI32_P (high)
1898       && ! SPARC_SIMM13_P (high))
1899     emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1900                           gen_highpart (SImode, operands[0])));
1901   else
1902     emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
1903 #endif
1904   DONE;
1905 })
1906
1907 (define_split
1908   [(set (match_operand:DI 0 "register_operand" "")
1909         (match_operand:DI 1 "const_double_operand" ""))]
1910   "reload_completed
1911    && (! TARGET_V9
1912        || (! TARGET_ARCH64
1913            && ((GET_CODE (operands[0]) == REG
1914                 && SPARC_INT_REG_P (REGNO (operands[0])))
1915                || (GET_CODE (operands[0]) == SUBREG
1916                    && GET_CODE (SUBREG_REG (operands[0])) == REG
1917                    && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))))"
1918   [(clobber (const_int 0))]
1919 {
1920   emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1921                         GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
1922
1923   /* Slick... but this trick loses if this subreg constant part
1924      can be done in one insn.  */
1925   if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
1926       && ! SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
1927       && ! SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1])))
1928     {
1929       emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1930                             gen_highpart (SImode, operands[0])));
1931     }
1932   else
1933     {
1934       emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1935                             GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
1936     }
1937   DONE;
1938 })
1939
1940 (define_split
1941   [(set (match_operand:DI 0 "register_operand" "")
1942         (match_operand:DI 1 "register_operand" ""))]
1943   "reload_completed
1944    && (! TARGET_V9
1945        || (! TARGET_ARCH64
1946            && sparc_split_regreg_legitimate (operands[0],
1947                                              operands[1])))"
1948   [(clobber (const_int 0))]
1949 {
1950   rtx set_dest = operands[0];
1951   rtx set_src = operands[1];
1952   rtx dest1, dest2;
1953   rtx src1, src2;
1954
1955   dest1 = gen_highpart (SImode, set_dest);
1956   dest2 = gen_lowpart (SImode, set_dest);
1957   src1 = gen_highpart (SImode, set_src);
1958   src2 = gen_lowpart (SImode, set_src);
1959
1960   /* Now emit using the real source and destination we found, swapping
1961      the order if we detect overlap.  */
1962   if (reg_overlap_mentioned_p (dest1, src2))
1963     {
1964       emit_insn (gen_movsi (dest2, src2));
1965       emit_insn (gen_movsi (dest1, src1));
1966     }
1967   else
1968     {
1969       emit_insn (gen_movsi (dest1, src1));
1970       emit_insn (gen_movsi (dest2, src2));
1971     }
1972   DONE;
1973 })
1974
1975 ;; Now handle the cases of memory moves from/to non-even
1976 ;; DI mode register pairs.
1977 (define_split
1978   [(set (match_operand:DI 0 "register_operand" "")
1979         (match_operand:DI 1 "memory_operand" ""))]
1980   "(! TARGET_ARCH64
1981     && reload_completed
1982     && sparc_splitdi_legitimate (operands[0], operands[1]))"
1983   [(clobber (const_int 0))]
1984 {
1985   rtx word0 = adjust_address (operands[1], SImode, 0);
1986   rtx word1 = adjust_address (operands[1], SImode, 4);
1987   rtx high_part = gen_highpart (SImode, operands[0]);
1988   rtx low_part = gen_lowpart (SImode, operands[0]);
1989
1990   if (reg_overlap_mentioned_p (high_part, word1))
1991     {
1992       emit_insn (gen_movsi (low_part, word1));
1993       emit_insn (gen_movsi (high_part, word0));
1994     }
1995   else
1996     {
1997       emit_insn (gen_movsi (high_part, word0));
1998       emit_insn (gen_movsi (low_part, word1));
1999     }
2000   DONE;
2001 })
2002
2003 (define_split
2004   [(set (match_operand:DI 0 "memory_operand" "")
2005         (match_operand:DI 1 "register_operand" ""))]
2006   "(! TARGET_ARCH64
2007     && reload_completed
2008     && sparc_splitdi_legitimate (operands[1], operands[0]))"
2009   [(clobber (const_int 0))]
2010 {
2011   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
2012                         gen_highpart (SImode, operands[1])));
2013   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
2014                         gen_lowpart (SImode, operands[1])));
2015   DONE;
2016 })
2017
2018 (define_split
2019   [(set (match_operand:DI 0 "memory_operand" "")
2020         (match_operand:DI 1 "const_zero_operand" ""))]
2021   "reload_completed
2022    && (! TARGET_V9
2023        || (! TARGET_ARCH64
2024            && ! mem_min_alignment (operands[0], 8)))
2025    && offsettable_memref_p (operands[0])"
2026   [(clobber (const_int 0))]
2027 {
2028   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
2029   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
2030   DONE;
2031 })
2032
2033
2034 ;; Floating point move instructions
2035
2036 (define_expand "movsf"
2037   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2038         (match_operand:SF 1 "general_operand" ""))]
2039   ""
2040 {
2041   if (sparc_expand_move (SFmode, operands))
2042     DONE;
2043 })
2044
2045 (define_insn "*movsf_insn"
2046   [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,f, *r,*r,*r,*r, f,f,*r,m,  m")
2047         (match_operand:SF 1 "input_operand"         "G,C,f,*rR, Q, S, f,*r,m, m,f,*rG"))]
2048   "(register_operand (operands[0], SFmode)
2049     || register_or_zero_or_all_ones_operand (operands[1], SFmode))"
2050 {
2051   if (GET_CODE (operands[1]) == CONST_DOUBLE
2052       && (which_alternative == 3
2053           || which_alternative == 4
2054           || which_alternative == 5))
2055     {
2056       REAL_VALUE_TYPE r;
2057       long i;
2058
2059       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2060       REAL_VALUE_TO_TARGET_SINGLE (r, i);
2061       operands[1] = GEN_INT (i);
2062     }
2063
2064   switch (which_alternative)
2065     {
2066     case 0:
2067       return "fzeros\t%0";
2068     case 1:
2069       return "fones\t%0";
2070     case 2:
2071       return "fmovs\t%1, %0";
2072     case 3:
2073       return "mov\t%1, %0";
2074     case 4:
2075       return "sethi\t%%hi(%a1), %0";
2076     case 5:
2077       return "#";
2078     case 6:
2079       return "movstouw\t%1, %0";
2080     case 7:
2081       return "movwtos\t%1, %0";
2082     case 8:
2083     case 9:
2084       return "ld\t%1, %0";
2085     case 10:
2086     case 11:
2087       return "st\t%r1, %0";
2088     default:
2089       gcc_unreachable ();
2090     }
2091 }
2092   [(set_attr "type" "fga,fga,fpmove,*,*,*,*,*,fpload,load,fpstore,store")
2093    (set_attr "cpu_feature" "vis,vis,fpu,*,*,*,vis3,vis3,fpu,*,fpu,*")])
2094
2095 ;; The following 3 patterns build SFmode constants in integer registers.
2096
2097 (define_insn "*movsf_lo_sum"
2098   [(set (match_operand:SF 0 "register_operand" "=r")
2099         (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
2100                    (match_operand:SF 2 "fp_const_high_losum_operand" "S")))]
2101   ""
2102 {
2103   REAL_VALUE_TYPE r;
2104   long i;
2105
2106   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
2107   REAL_VALUE_TO_TARGET_SINGLE (r, i);
2108   operands[2] = GEN_INT (i);
2109   return "or\t%1, %%lo(%a2), %0";
2110 })
2111
2112 (define_insn "*movsf_high"
2113   [(set (match_operand:SF 0 "register_operand" "=r")
2114         (high:SF (match_operand:SF 1 "fp_const_high_losum_operand" "S")))]
2115   ""
2116 {
2117   REAL_VALUE_TYPE r;
2118   long i;
2119
2120   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2121   REAL_VALUE_TO_TARGET_SINGLE (r, i);
2122   operands[1] = GEN_INT (i);
2123   return "sethi\t%%hi(%1), %0";
2124 })
2125
2126 (define_split
2127   [(set (match_operand:SF 0 "register_operand" "")
2128         (match_operand:SF 1 "fp_const_high_losum_operand" ""))]
2129   "REG_P (operands[0]) && SPARC_INT_REG_P (REGNO (operands[0]))"
2130   [(set (match_dup 0) (high:SF (match_dup 1)))
2131    (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
2132
2133 (define_expand "movdf"
2134   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2135         (match_operand:DF 1 "general_operand" ""))]
2136   ""
2137 {
2138   if (sparc_expand_move (DFmode, operands))
2139     DONE;
2140 })
2141
2142 (define_insn "*movdf_insn_sp32"
2143   [(set (match_operand:DF 0 "nonimmediate_operand" "=b,b,e,e,*r, f,  e,T,W,U,T,  f,  *r,  o,o")
2144         (match_operand:DF 1 "input_operand"         "G,C,e,e, f,*r,W#F,G,e,T,U,o#F,*roF,*rG,f"))]
2145   "! TARGET_ARCH64
2146    && (register_operand (operands[0], DFmode)
2147        || register_or_zero_or_all_ones_operand (operands[1], DFmode))"
2148   "@
2149   fzero\t%0
2150   fone\t%0
2151   fmovd\t%1, %0
2152   #
2153   #
2154   #
2155   ldd\t%1, %0
2156   stx\t%r1, %0
2157   std\t%1, %0
2158   ldd\t%1, %0
2159   std\t%1, %0
2160   #
2161   #
2162   #
2163   #"
2164   [(set_attr "type" "fga,fga,fpmove,*,*,*,fpload,store,fpstore,load,store,*,*,*,*")
2165    (set_attr "length" "*,*,*,2,2,2,*,*,*,*,*,2,2,2,2")
2166    (set_attr "fptype" "double,double,double,*,*,*,*,*,*,*,*,*,*,*,*")
2167    (set_attr "cpu_feature" "vis,vis,v9,fpunotv9,vis3,vis3,fpu,v9,fpu,*,*,fpu,*,*,fpu")])
2168
2169 (define_insn "*movdf_insn_sp64"
2170   [(set (match_operand:DF 0 "nonimmediate_operand" "=b,b,e,*r, e,  e,W, *r,*r,  m,*r")
2171         (match_operand:DF 1 "input_operand"         "G,C,e, e,*r,W#F,e,*rG, m,*rG, F"))]
2172   "TARGET_ARCH64
2173    && (register_operand (operands[0], DFmode)
2174        || register_or_zero_or_all_ones_operand (operands[1], DFmode))"
2175   "@
2176   fzero\t%0
2177   fone\t%0
2178   fmovd\t%1, %0
2179   movdtox\t%1, %0
2180   movxtod\t%1, %0
2181   ldd\t%1, %0
2182   std\t%1, %0
2183   mov\t%r1, %0
2184   ldx\t%1, %0
2185   stx\t%r1, %0
2186   #"
2187   [(set_attr "type" "fga,fga,fpmove,*,*,load,store,*,load,store,*")
2188    (set_attr "length" "*,*,*,*,*,*,*,*,*,*,2")
2189    (set_attr "fptype" "double,double,double,double,double,*,*,*,*,*,*")
2190    (set_attr "cpu_feature" "vis,vis,fpu,vis3,vis3,fpu,fpu,*,*,*,*")])
2191
2192 ;; This pattern builds DFmode constants in integer registers.
2193 (define_split
2194   [(set (match_operand:DF 0 "register_operand" "")
2195         (match_operand:DF 1 "const_double_operand" ""))]
2196   "REG_P (operands[0])
2197    && SPARC_INT_REG_P (REGNO (operands[0]))
2198    && ! const_zero_operand (operands[1], GET_MODE (operands[0]))
2199    && reload_completed"
2200   [(clobber (const_int 0))]
2201 {
2202   operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
2203
2204   if (TARGET_ARCH64)
2205     {
2206 #if HOST_BITS_PER_WIDE_INT == 32
2207       gcc_unreachable ();
2208 #else
2209       enum machine_mode mode = GET_MODE (operands[1]);
2210       rtx tem = simplify_subreg (DImode, operands[1], mode, 0);
2211       emit_insn (gen_movdi (operands[0], tem));
2212 #endif
2213     }
2214   else
2215     {
2216       enum machine_mode mode = GET_MODE (operands[1]);
2217       rtx hi = simplify_subreg (SImode, operands[1], mode, 0);
2218       rtx lo = simplify_subreg (SImode, operands[1], mode, 4);
2219
2220       gcc_assert (GET_CODE (hi) == CONST_INT);
2221       gcc_assert (GET_CODE (lo) == CONST_INT);
2222
2223       emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), hi));
2224
2225       /* Slick... but this trick loses if this subreg constant part
2226          can be done in one insn.  */
2227       if (lo == hi
2228           && ! SPARC_SETHI32_P (INTVAL (hi))
2229           && ! SPARC_SIMM13_P (INTVAL (hi)))
2230         {
2231           emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2232                                 gen_highpart (SImode, operands[0])));
2233         }
2234       else
2235         {
2236           emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), lo));
2237         }
2238     }
2239   DONE;
2240 })
2241
2242 ;; Ok, now the splits to handle all the multi insn and
2243 ;; mis-aligned memory address cases.
2244 ;; In these splits please take note that we must be
2245 ;; careful when V9 but not ARCH64 because the integer
2246 ;; register DFmode cases must be handled.
2247 (define_split
2248   [(set (match_operand:DF 0 "register_operand" "")
2249         (match_operand:DF 1 "register_operand" ""))]
2250   "(! TARGET_V9
2251     || (! TARGET_ARCH64
2252         && sparc_split_regreg_legitimate (operands[0],
2253                                           operands[1])))
2254    && reload_completed"
2255   [(clobber (const_int 0))]
2256 {
2257   rtx set_dest = operands[0];
2258   rtx set_src = operands[1];
2259   rtx dest1, dest2;
2260   rtx src1, src2;
2261
2262   dest1 = gen_highpart (SFmode, set_dest);
2263   dest2 = gen_lowpart (SFmode, set_dest);
2264   src1 = gen_highpart (SFmode, set_src);
2265   src2 = gen_lowpart (SFmode, set_src);
2266
2267   /* Now emit using the real source and destination we found, swapping
2268      the order if we detect overlap.  */
2269   if (reg_overlap_mentioned_p (dest1, src2))
2270     {
2271       emit_move_insn_1 (dest2, src2);
2272       emit_move_insn_1 (dest1, src1);
2273     }
2274   else
2275     {
2276       emit_move_insn_1 (dest1, src1);
2277       emit_move_insn_1 (dest2, src2);
2278     }
2279   DONE;
2280 })
2281
2282 (define_split
2283   [(set (match_operand:DF 0 "register_operand" "")
2284         (match_operand:DF 1 "memory_operand" ""))]
2285   "reload_completed
2286    && ! TARGET_ARCH64
2287    && (((REGNO (operands[0]) % 2) != 0)
2288        || ! mem_min_alignment (operands[1], 8))
2289    && offsettable_memref_p (operands[1])"
2290   [(clobber (const_int 0))]
2291 {
2292   rtx word0, word1;
2293
2294   word0 = adjust_address (operands[1], SFmode, 0);
2295   word1 = adjust_address (operands[1], SFmode, 4);
2296
2297   if (reg_overlap_mentioned_p (gen_highpart (SFmode, operands[0]), word1))
2298     {
2299       emit_move_insn_1 (gen_lowpart (SFmode, operands[0]), word1);
2300       emit_move_insn_1 (gen_highpart (SFmode, operands[0]), word0);
2301     }
2302   else
2303     {
2304       emit_move_insn_1 (gen_highpart (SFmode, operands[0]), word0);
2305       emit_move_insn_1 (gen_lowpart (SFmode, operands[0]), word1);
2306     }
2307   DONE;
2308 })
2309
2310 (define_split
2311   [(set (match_operand:DF 0 "memory_operand" "")
2312         (match_operand:DF 1 "register_operand" ""))]
2313   "reload_completed
2314    && ! TARGET_ARCH64
2315    && (((REGNO (operands[1]) % 2) != 0)
2316        || ! mem_min_alignment (operands[0], 8))
2317    && offsettable_memref_p (operands[0])"
2318   [(clobber (const_int 0))]
2319 {
2320   rtx word0, word1;
2321
2322   word0 = adjust_address (operands[0], SFmode, 0);
2323   word1 = adjust_address (operands[0], SFmode, 4);
2324
2325   emit_move_insn_1 (word0, gen_highpart (SFmode, operands[1]));
2326   emit_move_insn_1 (word1, gen_lowpart (SFmode, operands[1]));
2327   DONE;
2328 })
2329
2330 (define_split
2331   [(set (match_operand:DF 0 "memory_operand" "")
2332         (match_operand:DF 1 "const_zero_operand" ""))]
2333   "reload_completed
2334    && (! TARGET_V9
2335        || (! TARGET_ARCH64
2336            && ! mem_min_alignment (operands[0], 8)))
2337    && offsettable_memref_p (operands[0])"
2338   [(clobber (const_int 0))]
2339 {
2340   rtx dest1, dest2;
2341
2342   dest1 = adjust_address (operands[0], SFmode, 0);
2343   dest2 = adjust_address (operands[0], SFmode, 4);
2344
2345   emit_move_insn_1 (dest1, CONST0_RTX (SFmode));
2346   emit_move_insn_1 (dest2, CONST0_RTX (SFmode));
2347   DONE;
2348 })
2349
2350 (define_split
2351   [(set (match_operand:DF 0 "register_operand" "")
2352         (match_operand:DF 1 "const_zero_operand" ""))]
2353   "reload_completed
2354    && ! TARGET_ARCH64
2355    && ((GET_CODE (operands[0]) == REG
2356         && SPARC_INT_REG_P (REGNO (operands[0])))
2357        || (GET_CODE (operands[0]) == SUBREG
2358            && GET_CODE (SUBREG_REG (operands[0])) == REG
2359            && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
2360   [(clobber (const_int 0))]
2361 {
2362   rtx set_dest = operands[0];
2363   rtx dest1, dest2;
2364
2365   dest1 = gen_highpart (SFmode, set_dest);
2366   dest2 = gen_lowpart (SFmode, set_dest);
2367   emit_move_insn_1 (dest1, CONST0_RTX (SFmode));
2368   emit_move_insn_1 (dest2, CONST0_RTX (SFmode));
2369   DONE;
2370 })
2371
2372 (define_expand "movtf"
2373   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2374         (match_operand:TF 1 "general_operand" ""))]
2375   ""
2376 {
2377   if (sparc_expand_move (TFmode, operands))
2378     DONE;
2379 })
2380
2381 (define_insn "*movtf_insn_sp32"
2382   [(set (match_operand:TF 0 "nonimmediate_operand" "=b, e,o,  o,U,  r")
2383         (match_operand:TF 1 "input_operand"        " G,oe,e,rGU,o,roG"))]
2384   "! TARGET_ARCH64
2385    && (register_operand (operands[0], TFmode)
2386        || register_or_zero_operand (operands[1], TFmode))"
2387   "#"
2388   [(set_attr "length" "4,4,4,4,4,4")
2389    (set_attr "cpu_feature" "fpu,fpu,fpu,*,*,*")])
2390
2391 (define_insn "*movtf_insn_sp64"
2392   [(set (match_operand:TF 0 "nonimmediate_operand" "=b, e,o, o,  r")
2393         (match_operand:TF 1 "input_operand"         "G,oe,e,rG,roG"))]
2394   "TARGET_ARCH64
2395    && ! TARGET_HARD_QUAD
2396    && (register_operand (operands[0], TFmode)
2397        || register_or_zero_operand (operands[1], TFmode))"
2398   "#"
2399   [(set_attr "length" "2,2,2,2,2")
2400    (set_attr "cpu_feature" "fpu,fpu,fpu,*,*")])
2401
2402 (define_insn "*movtf_insn_sp64_hq"
2403   [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,e,m, o,  r")
2404         (match_operand:TF 1 "input_operand"         "G,e,m,e,rG,roG"))]
2405   "TARGET_ARCH64
2406    && TARGET_HARD_QUAD
2407    && (register_operand (operands[0], TFmode)
2408        || register_or_zero_operand (operands[1], TFmode))"
2409   "@
2410   #
2411   fmovq\t%1, %0
2412   ldq\t%1, %0
2413   stq\t%1, %0
2414   #
2415   #"
2416   [(set_attr "type" "*,fpmove,fpload,fpstore,*,*")
2417    (set_attr "length" "2,*,*,*,2,2")])
2418
2419 ;; Now all the splits to handle multi-insn TF mode moves.
2420 (define_split
2421   [(set (match_operand:TF 0 "register_operand" "")
2422         (match_operand:TF 1 "register_operand" ""))]
2423   "reload_completed
2424    && (! TARGET_ARCH64
2425        || (TARGET_FPU
2426            && ! TARGET_HARD_QUAD)
2427        || (! fp_register_operand (operands[0], TFmode)
2428            && ! fp_register_operand (operands[1], TFmode)))"
2429   [(clobber (const_int 0))]
2430 {
2431   rtx set_dest = operands[0];
2432   rtx set_src = operands[1];
2433   rtx dest1, dest2;
2434   rtx src1, src2;
2435
2436   dest1 = gen_df_reg (set_dest, 0);
2437   dest2 = gen_df_reg (set_dest, 1);
2438   src1 = gen_df_reg (set_src, 0);
2439   src2 = gen_df_reg (set_src, 1);
2440
2441   /* Now emit using the real source and destination we found, swapping
2442      the order if we detect overlap.  */
2443   if (reg_overlap_mentioned_p (dest1, src2))
2444     {
2445       emit_insn (gen_movdf (dest2, src2));
2446       emit_insn (gen_movdf (dest1, src1));
2447     }
2448   else
2449     {
2450       emit_insn (gen_movdf (dest1, src1));
2451       emit_insn (gen_movdf (dest2, src2));
2452     }
2453   DONE;
2454 })
2455
2456 (define_split
2457   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2458         (match_operand:TF 1 "const_zero_operand" ""))]
2459   "reload_completed"
2460   [(clobber (const_int 0))]
2461 {
2462   rtx set_dest = operands[0];
2463   rtx dest1, dest2;
2464
2465   switch (GET_CODE (set_dest))
2466     {
2467     case REG:
2468       dest1 = gen_df_reg (set_dest, 0);
2469       dest2 = gen_df_reg (set_dest, 1);
2470       break;
2471     case MEM:
2472       dest1 = adjust_address (set_dest, DFmode, 0);
2473       dest2 = adjust_address (set_dest, DFmode, 8);
2474       break;
2475     default:
2476       gcc_unreachable ();      
2477     }
2478
2479   emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
2480   emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
2481   DONE;
2482 })
2483
2484 (define_split
2485   [(set (match_operand:TF 0 "register_operand" "")
2486         (match_operand:TF 1 "memory_operand" ""))]
2487   "(reload_completed
2488     && offsettable_memref_p (operands[1])
2489     && (! TARGET_ARCH64
2490         || ! TARGET_HARD_QUAD
2491         || ! fp_register_operand (operands[0], TFmode)))"
2492   [(clobber (const_int 0))]
2493 {
2494   rtx word0 = adjust_address (operands[1], DFmode, 0);
2495   rtx word1 = adjust_address (operands[1], DFmode, 8);
2496   rtx set_dest, dest1, dest2;
2497
2498   set_dest = operands[0];
2499
2500   dest1 = gen_df_reg (set_dest, 0);
2501   dest2 = gen_df_reg (set_dest, 1);
2502
2503   /* Now output, ordering such that we don't clobber any registers
2504      mentioned in the address.  */
2505   if (reg_overlap_mentioned_p (dest1, word1))
2506
2507     {
2508       emit_insn (gen_movdf (dest2, word1));
2509       emit_insn (gen_movdf (dest1, word0));
2510     }
2511   else
2512    {
2513       emit_insn (gen_movdf (dest1, word0));
2514       emit_insn (gen_movdf (dest2, word1));
2515    }
2516   DONE;
2517 })
2518
2519 (define_split
2520   [(set (match_operand:TF 0 "memory_operand" "")
2521         (match_operand:TF 1 "register_operand" ""))]
2522   "(reload_completed
2523     && offsettable_memref_p (operands[0])
2524     && (! TARGET_ARCH64
2525         || ! TARGET_HARD_QUAD
2526         || ! fp_register_operand (operands[1], TFmode)))"
2527   [(clobber (const_int 0))]
2528 {
2529   rtx set_src = operands[1];
2530
2531   emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
2532                         gen_df_reg (set_src, 0)));
2533   emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
2534                         gen_df_reg (set_src, 1)));
2535   DONE;
2536 })
2537
2538
2539 ;; SPARC-V9 conditional move instructions
2540
2541 ;; We can handle larger constants here for some flavors, but for now we keep
2542 ;; it simple and only allow those constants supported by all flavors.
2543 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
2544 ;; 3 contains the constant if one is present, but we handle either for
2545 ;; generality (sparc.c puts a constant in operand 2).
2546 ;;
2547 ;; Our instruction patterns, on the other hand, canonicalize such that
2548 ;; operand 3 must be the set destination.
2549
2550 (define_expand "mov<I:mode>cc"
2551   [(set (match_operand:I 0 "register_operand" "")
2552         (if_then_else:I (match_operand 1 "comparison_operator" "")
2553                         (match_operand:I 2 "arith10_operand" "")
2554                         (match_operand:I 3 "arith10_operand" "")))]
2555   "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2556 {
2557   if (! sparc_expand_conditional_move (<I:MODE>mode, operands))
2558     FAIL;
2559   DONE;
2560 })
2561
2562 (define_expand "mov<F:mode>cc"
2563   [(set (match_operand:F 0 "register_operand" "")
2564         (if_then_else:F (match_operand 1 "comparison_operator" "")
2565                         (match_operand:F 2 "register_operand" "")
2566                         (match_operand:F 3 "register_operand" "")))]
2567   "TARGET_V9 && TARGET_FPU"
2568 {
2569   if (! sparc_expand_conditional_move (<F:MODE>mode, operands))
2570     FAIL;
2571   DONE;
2572 })
2573
2574 ;; Conditional move define_insns
2575
2576 (define_insn "*mov<I:mode>_cc_v9"
2577   [(set (match_operand:I 0 "register_operand" "=r")
2578         (if_then_else:I (match_operator 1 "comparison_operator"
2579                                [(match_operand 2 "icc_or_fcc_register_operand" "X")
2580                                 (const_int 0)])
2581                         (match_operand:I 3 "arith11_operand" "rL")
2582                         (match_operand:I 4 "register_operand" "0")))]
2583   "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2584   "mov%C1\t%x2, %3, %0"
2585   [(set_attr "type" "cmove")])
2586
2587 (define_insn "*mov<I:mode>_cc_reg_sp64"
2588   [(set (match_operand:I 0 "register_operand" "=r")
2589         (if_then_else:I (match_operator 1 "v9_register_compare_operator"
2590                                 [(match_operand:DI 2 "register_operand" "r")
2591                                  (const_int 0)])
2592                         (match_operand:I 3 "arith10_operand" "rM")
2593                         (match_operand:I 4 "register_operand" "0")))]
2594   "TARGET_ARCH64"
2595   "movr%D1\t%2, %r3, %0"
2596   [(set_attr "type" "cmove")])
2597
2598 (define_insn "*movsf_cc_v9"
2599   [(set (match_operand:SF 0 "register_operand" "=f")
2600         (if_then_else:SF (match_operator 1 "comparison_operator"
2601                                 [(match_operand 2 "icc_or_fcc_register_operand" "X")
2602                                  (const_int 0)])
2603                          (match_operand:SF 3 "register_operand" "f")
2604                          (match_operand:SF 4 "register_operand" "0")))]
2605   "TARGET_V9 && TARGET_FPU"
2606   "fmovs%C1\t%x2, %3, %0"
2607   [(set_attr "type" "fpcmove")])
2608
2609 (define_insn "*movsf_cc_reg_sp64"
2610   [(set (match_operand:SF 0 "register_operand" "=f")
2611         (if_then_else:SF (match_operator 1 "v9_register_compare_operator"
2612                                 [(match_operand:DI 2 "register_operand" "r")
2613                                  (const_int 0)])
2614                          (match_operand:SF 3 "register_operand" "f")
2615                          (match_operand:SF 4 "register_operand" "0")))]
2616   "TARGET_ARCH64 && TARGET_FPU"
2617   "fmovrs%D1\t%2, %3, %0"
2618   [(set_attr "type" "fpcrmove")])
2619
2620 ;; Named because invoked by movtf_cc_v9
2621 (define_insn "movdf_cc_v9"
2622   [(set (match_operand:DF 0 "register_operand" "=e")
2623         (if_then_else:DF (match_operator 1 "comparison_operator"
2624                                 [(match_operand 2 "icc_or_fcc_register_operand" "X")
2625                                  (const_int 0)])
2626                          (match_operand:DF 3 "register_operand" "e")
2627                          (match_operand:DF 4 "register_operand" "0")))]
2628   "TARGET_V9 && TARGET_FPU"
2629   "fmovd%C1\t%x2, %3, %0"
2630   [(set_attr "type" "fpcmove")
2631    (set_attr "fptype" "double")])
2632
2633 ;; Named because invoked by movtf_cc_reg_sp64
2634 (define_insn "movdf_cc_reg_sp64"
2635   [(set (match_operand:DF 0 "register_operand" "=e")
2636         (if_then_else:DF (match_operator 1 "v9_register_compare_operator"
2637                                 [(match_operand:DI 2 "register_operand" "r")
2638                                  (const_int 0)])
2639                          (match_operand:DF 3 "register_operand" "e")
2640                          (match_operand:DF 4 "register_operand" "0")))]
2641   "TARGET_ARCH64 && TARGET_FPU"
2642   "fmovrd%D1\t%2, %3, %0"
2643   [(set_attr "type" "fpcrmove")
2644    (set_attr "fptype" "double")])
2645
2646 (define_insn "*movtf_cc_hq_v9"
2647   [(set (match_operand:TF 0 "register_operand" "=e")
2648         (if_then_else:TF (match_operator 1 "comparison_operator"
2649                                 [(match_operand 2 "icc_or_fcc_register_operand" "X")
2650                                  (const_int 0)])
2651                          (match_operand:TF 3 "register_operand" "e")
2652                          (match_operand:TF 4 "register_operand" "0")))]
2653   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
2654   "fmovq%C1\t%x2, %3, %0"
2655   [(set_attr "type" "fpcmove")])
2656
2657 (define_insn "*movtf_cc_reg_hq_sp64"
2658   [(set (match_operand:TF 0 "register_operand" "=e")
2659         (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2660                                 [(match_operand:DI 2 "register_operand" "r")
2661                                  (const_int 0)])
2662                          (match_operand:TF 3 "register_operand" "e")
2663                          (match_operand:TF 4 "register_operand" "0")))]
2664   "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
2665   "fmovrq%D1\t%2, %3, %0"
2666   [(set_attr "type" "fpcrmove")])
2667
2668 (define_insn_and_split "*movtf_cc_v9"
2669   [(set (match_operand:TF 0 "register_operand" "=e")
2670         (if_then_else:TF (match_operator 1 "comparison_operator"
2671                             [(match_operand 2 "icc_or_fcc_register_operand" "X")
2672                              (const_int 0)])
2673                          (match_operand:TF 3 "register_operand" "e")
2674                          (match_operand:TF 4 "register_operand" "0")))]
2675   "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
2676   "#"
2677   "&& reload_completed"
2678   [(clobber (const_int 0))]
2679 {
2680   rtx set_dest = operands[0];
2681   rtx set_srca = operands[3];
2682   rtx dest1, dest2;
2683   rtx srca1, srca2;
2684
2685   dest1 = gen_df_reg (set_dest, 0);
2686   dest2 = gen_df_reg (set_dest, 1);
2687   srca1 = gen_df_reg (set_srca, 0);
2688   srca2 = gen_df_reg (set_srca, 1);
2689
2690   if (reg_overlap_mentioned_p (dest1, srca2))
2691     {
2692       emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, dest2));
2693       emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, dest1));
2694     }
2695   else
2696     {
2697       emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, dest1));
2698       emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, dest2));
2699     }
2700   DONE;
2701 }
2702   [(set_attr "length" "2")])
2703
2704 (define_insn_and_split "*movtf_cc_reg_sp64"
2705   [(set (match_operand:TF 0 "register_operand" "=e")
2706         (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2707                                 [(match_operand:DI 2 "register_operand" "r")
2708                                  (const_int 0)])
2709                          (match_operand:TF 3 "register_operand" "e")
2710                          (match_operand:TF 4 "register_operand" "0")))]
2711   "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
2712   "#"
2713   "&& reload_completed"
2714   [(clobber (const_int 0))]
2715 {
2716   rtx set_dest = operands[0];
2717   rtx set_srca = operands[3];
2718   rtx dest1, dest2;
2719   rtx srca1, srca2;
2720
2721   dest1 = gen_df_reg (set_dest, 0);
2722   dest2 = gen_df_reg (set_dest, 1);
2723   srca1 = gen_df_reg (set_srca, 0);
2724   srca2 = gen_df_reg (set_srca, 1);
2725
2726   if (reg_overlap_mentioned_p (dest1, srca2))
2727     {
2728       emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, dest2));
2729       emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, dest1));
2730     }
2731   else
2732     {
2733       emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, dest1));
2734       emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, dest2));
2735     }
2736   DONE;
2737 }
2738   [(set_attr "length" "2")])
2739
2740 \f
2741 ;; Zero-extension instructions
2742
2743 ;; These patterns originally accepted general_operands, however, slightly
2744 ;; better code is generated by only accepting register_operands, and then
2745 ;; letting combine generate the ldu[hb] insns.
2746
2747 (define_expand "zero_extendhisi2"
2748   [(set (match_operand:SI 0 "register_operand" "")
2749         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
2750   ""
2751 {
2752   rtx temp = gen_reg_rtx (SImode);
2753   rtx shift_16 = GEN_INT (16);
2754   int op1_subbyte = 0;
2755
2756   if (GET_CODE (operand1) == SUBREG)
2757     {
2758       op1_subbyte = SUBREG_BYTE (operand1);
2759       op1_subbyte /= GET_MODE_SIZE (SImode);
2760       op1_subbyte *= GET_MODE_SIZE (SImode);
2761       operand1 = XEXP (operand1, 0);
2762     }
2763
2764   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
2765                           shift_16));
2766   emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
2767   DONE;
2768 })
2769
2770 (define_insn "*zero_extendhisi2_insn"
2771   [(set (match_operand:SI 0 "register_operand" "=r")
2772         (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2773   ""
2774   "lduh\t%1, %0"
2775   [(set_attr "type" "load")
2776    (set_attr "us3load_type" "3cycle")])
2777
2778 (define_expand "zero_extendqihi2"
2779   [(set (match_operand:HI 0 "register_operand" "")
2780         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
2781   ""
2782   "")
2783
2784 (define_insn "*zero_extendqihi2_insn"
2785   [(set (match_operand:HI 0 "register_operand" "=r,r")
2786         (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
2787   "GET_CODE (operands[1]) != CONST_INT"
2788   "@
2789    and\t%1, 0xff, %0
2790    ldub\t%1, %0"
2791   [(set_attr "type" "*,load")
2792    (set_attr "us3load_type" "*,3cycle")])
2793
2794 (define_expand "zero_extendqisi2"
2795   [(set (match_operand:SI 0 "register_operand" "")
2796         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
2797   ""
2798   "")
2799
2800 (define_insn "*zero_extendqisi2_insn"
2801   [(set (match_operand:SI 0 "register_operand" "=r,r")
2802         (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
2803   "GET_CODE (operands[1]) != CONST_INT"
2804   "@
2805    and\t%1, 0xff, %0
2806    ldub\t%1, %0"
2807   [(set_attr "type" "*,load")
2808    (set_attr "us3load_type" "*,3cycle")])
2809
2810 (define_expand "zero_extendqidi2"
2811   [(set (match_operand:DI 0 "register_operand" "")
2812         (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
2813   "TARGET_ARCH64"
2814   "")
2815
2816 (define_insn "*zero_extendqidi2_insn"
2817   [(set (match_operand:DI 0 "register_operand" "=r,r")
2818         (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
2819   "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
2820   "@
2821    and\t%1, 0xff, %0
2822    ldub\t%1, %0"
2823   [(set_attr "type" "*,load")
2824    (set_attr "us3load_type" "*,3cycle")])
2825
2826 (define_expand "zero_extendhidi2"
2827   [(set (match_operand:DI 0 "register_operand" "")
2828         (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
2829   "TARGET_ARCH64"
2830 {
2831   rtx temp = gen_reg_rtx (DImode);
2832   rtx shift_48 = GEN_INT (48);
2833   int op1_subbyte = 0;
2834
2835   if (GET_CODE (operand1) == SUBREG)
2836     {
2837       op1_subbyte = SUBREG_BYTE (operand1);
2838       op1_subbyte /= GET_MODE_SIZE (DImode);
2839       op1_subbyte *= GET_MODE_SIZE (DImode);
2840       operand1 = XEXP (operand1, 0);
2841     }
2842
2843   emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
2844                           shift_48));
2845   emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
2846   DONE;
2847 })
2848
2849 (define_insn "*zero_extendhidi2_insn"
2850   [(set (match_operand:DI 0 "register_operand" "=r")
2851         (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
2852   "TARGET_ARCH64"
2853   "lduh\t%1, %0"
2854   [(set_attr "type" "load")
2855    (set_attr "us3load_type" "3cycle")])
2856
2857 ;; ??? Write truncdisi pattern using sra?
2858
2859 (define_expand "zero_extendsidi2"
2860   [(set (match_operand:DI 0 "register_operand" "")
2861         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
2862   ""
2863   "")
2864
2865 (define_insn "*zero_extendsidi2_insn_sp64"
2866   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
2867         (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m,*f")))]
2868   "TARGET_ARCH64
2869    && GET_CODE (operands[1]) != CONST_INT"
2870   "@
2871    srl\t%1, 0, %0
2872    lduw\t%1, %0
2873    movstouw\t%1, %0"
2874   [(set_attr "type" "shift,load,*")
2875    (set_attr "cpu_feature" "*,*,vis3")])
2876
2877 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
2878   [(set (match_operand:DI 0 "register_operand" "=r")
2879         (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
2880   "! TARGET_ARCH64"
2881   "#"
2882   "&& reload_completed"
2883   [(set (match_dup 2) (match_dup 3))
2884    (set (match_dup 4) (match_dup 5))]
2885 {
2886   rtx dest1, dest2;
2887
2888   dest1 = gen_highpart (SImode, operands[0]);
2889   dest2 = gen_lowpart (SImode, operands[0]);
2890
2891   /* Swap the order in case of overlap.  */
2892   if (REGNO (dest1) == REGNO (operands[1]))
2893     {
2894       operands[2] = dest2;
2895       operands[3] = operands[1];
2896       operands[4] = dest1;
2897       operands[5] = const0_rtx;
2898     }
2899   else
2900     {
2901       operands[2] = dest1;
2902       operands[3] = const0_rtx;
2903       operands[4] = dest2;
2904       operands[5] = operands[1];
2905     }
2906 }
2907   [(set_attr "length" "2")])
2908
2909 ;; Simplify comparisons of extended values.
2910
2911 (define_insn "*cmp_zero_extendqisi2"
2912   [(set (reg:CC CC_REG)
2913         (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
2914                     (const_int 0)))]
2915   ""
2916   "andcc\t%0, 0xff, %%g0"
2917   [(set_attr "type" "compare")])
2918
2919 (define_insn "*cmp_zero_qi"
2920   [(set (reg:CC CC_REG)
2921         (compare:CC (match_operand:QI 0 "register_operand" "r")
2922                     (const_int 0)))]
2923   ""
2924   "andcc\t%0, 0xff, %%g0"
2925   [(set_attr "type" "compare")])
2926
2927 (define_insn "*cmp_zero_extendqisi2_set"
2928   [(set (reg:CC CC_REG)
2929         (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
2930                     (const_int 0)))
2931    (set (match_operand:SI 0 "register_operand" "=r")
2932         (zero_extend:SI (match_dup 1)))]
2933   ""
2934   "andcc\t%1, 0xff, %0"
2935   [(set_attr "type" "compare")])
2936
2937 (define_insn "*cmp_zero_extendqisi2_andcc_set"
2938   [(set (reg:CC CC_REG)
2939         (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
2940                             (const_int 255))
2941                     (const_int 0)))
2942    (set (match_operand:SI 0 "register_operand" "=r")
2943         (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
2944   ""
2945   "andcc\t%1, 0xff, %0"
2946   [(set_attr "type" "compare")])
2947
2948 (define_insn "*cmp_zero_extendqidi2"
2949   [(set (reg:CCX CC_REG)
2950         (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
2951                      (const_int 0)))]
2952   "TARGET_ARCH64"
2953   "andcc\t%0, 0xff, %%g0"
2954   [(set_attr "type" "compare")])
2955
2956 (define_insn "*cmp_zero_qi_sp64"
2957   [(set (reg:CCX CC_REG)
2958         (compare:CCX (match_operand:QI 0 "register_operand" "r")
2959                      (const_int 0)))]
2960   "TARGET_ARCH64"
2961   "andcc\t%0, 0xff, %%g0"
2962   [(set_attr "type" "compare")])
2963
2964 (define_insn "*cmp_zero_extendqidi2_set"
2965   [(set (reg:CCX CC_REG)
2966         (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
2967                      (const_int 0)))
2968    (set (match_operand:DI 0 "register_operand" "=r")
2969         (zero_extend:DI (match_dup 1)))]
2970   "TARGET_ARCH64"
2971   "andcc\t%1, 0xff, %0"
2972   [(set_attr "type" "compare")])
2973
2974 (define_insn "*cmp_zero_extendqidi2_andcc_set"
2975   [(set (reg:CCX CC_REG)
2976         (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
2977                              (const_int 255))
2978                      (const_int 0)))
2979    (set (match_operand:DI 0 "register_operand" "=r")
2980         (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
2981   "TARGET_ARCH64"
2982   "andcc\t%1, 0xff, %0"
2983   [(set_attr "type" "compare")])
2984
2985 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
2986
2987 (define_insn "*cmp_siqi_trunc"
2988   [(set (reg:CC CC_REG)
2989         (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
2990                     (const_int 0)))]
2991   ""
2992   "andcc\t%0, 0xff, %%g0"
2993   [(set_attr "type" "compare")])
2994
2995 (define_insn "*cmp_siqi_trunc_set"
2996   [(set (reg:CC CC_REG)
2997         (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
2998                     (const_int 0)))
2999    (set (match_operand:QI 0 "register_operand" "=r")
3000         (subreg:QI (match_dup 1) 3))]
3001   ""
3002   "andcc\t%1, 0xff, %0"
3003   [(set_attr "type" "compare")])
3004
3005 (define_insn "*cmp_diqi_trunc"
3006   [(set (reg:CC CC_REG)
3007         (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
3008                     (const_int 0)))]
3009   "TARGET_ARCH64"
3010   "andcc\t%0, 0xff, %%g0"
3011   [(set_attr "type" "compare")])
3012
3013 (define_insn "*cmp_diqi_trunc_set"
3014   [(set (reg:CC CC_REG)
3015         (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
3016                     (const_int 0)))
3017    (set (match_operand:QI 0 "register_operand" "=r")
3018         (subreg:QI (match_dup 1) 7))]
3019   "TARGET_ARCH64"
3020   "andcc\t%1, 0xff, %0"
3021   [(set_attr "type" "compare")])
3022 \f
3023
3024 ;; Sign-extension instructions
3025
3026 ;; These patterns originally accepted general_operands, however, slightly
3027 ;; better code is generated by only accepting register_operands, and then
3028 ;; letting combine generate the lds[hb] insns.
3029
3030 (define_expand "extendhisi2"
3031   [(set (match_operand:SI 0 "register_operand" "")
3032         (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
3033   ""
3034 {
3035   rtx temp = gen_reg_rtx (SImode);
3036   rtx shift_16 = GEN_INT (16);
3037   int op1_subbyte = 0;
3038
3039   if (GET_CODE (operand1) == SUBREG)
3040     {
3041       op1_subbyte = SUBREG_BYTE (operand1);
3042       op1_subbyte /= GET_MODE_SIZE (SImode);
3043       op1_subbyte *= GET_MODE_SIZE (SImode);
3044       operand1 = XEXP (operand1, 0);
3045     }
3046
3047   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3048                           shift_16));
3049   emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
3050   DONE;
3051 })
3052
3053 (define_insn "*sign_extendhisi2_insn"
3054   [(set (match_operand:SI 0 "register_operand" "=r")
3055         (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3056   ""
3057   "ldsh\t%1, %0"
3058   [(set_attr "type" "sload")
3059    (set_attr "us3load_type" "3cycle")])
3060
3061 (define_expand "extendqihi2"
3062   [(set (match_operand:HI 0 "register_operand" "")
3063         (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
3064   ""
3065 {
3066   rtx temp = gen_reg_rtx (SImode);
3067   rtx shift_24 = GEN_INT (24);
3068   int op1_subbyte = 0;
3069   int op0_subbyte = 0;
3070
3071   if (GET_CODE (operand1) == SUBREG)
3072     {
3073       op1_subbyte = SUBREG_BYTE (operand1);
3074       op1_subbyte /= GET_MODE_SIZE (SImode);
3075       op1_subbyte *= GET_MODE_SIZE (SImode);
3076       operand1 = XEXP (operand1, 0);
3077     }
3078   if (GET_CODE (operand0) == SUBREG)
3079     {
3080       op0_subbyte = SUBREG_BYTE (operand0);
3081       op0_subbyte /= GET_MODE_SIZE (SImode);
3082       op0_subbyte *= GET_MODE_SIZE (SImode);
3083       operand0 = XEXP (operand0, 0);
3084     }
3085   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3086                           shift_24));
3087   if (GET_MODE (operand0) != SImode)
3088     operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
3089   emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3090   DONE;
3091 })
3092
3093 (define_insn "*sign_extendqihi2_insn"
3094   [(set (match_operand:HI 0 "register_operand" "=r")
3095         (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3096   ""
3097   "ldsb\t%1, %0"
3098   [(set_attr "type" "sload")
3099    (set_attr "us3load_type" "3cycle")])
3100
3101 (define_expand "extendqisi2"
3102   [(set (match_operand:SI 0 "register_operand" "")
3103         (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
3104   ""
3105 {
3106   rtx temp = gen_reg_rtx (SImode);
3107   rtx shift_24 = GEN_INT (24);
3108   int op1_subbyte = 0;
3109
3110   if (GET_CODE (operand1) == SUBREG)
3111     {
3112       op1_subbyte = SUBREG_BYTE (operand1);
3113       op1_subbyte /= GET_MODE_SIZE (SImode);
3114       op1_subbyte *= GET_MODE_SIZE (SImode);
3115       operand1 = XEXP (operand1, 0);
3116     }
3117
3118   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3119                           shift_24));
3120   emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3121   DONE;
3122 })
3123
3124 (define_insn "*sign_extendqisi2_insn"
3125   [(set (match_operand:SI 0 "register_operand" "=r")
3126         (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3127   ""
3128   "ldsb\t%1, %0"
3129   [(set_attr "type" "sload")
3130    (set_attr "us3load_type" "3cycle")])
3131
3132 (define_expand "extendqidi2"
3133   [(set (match_operand:DI 0 "register_operand" "")
3134         (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
3135   "TARGET_ARCH64"
3136 {
3137   rtx temp = gen_reg_rtx (DImode);
3138   rtx shift_56 = GEN_INT (56);
3139   int op1_subbyte = 0;
3140
3141   if (GET_CODE (operand1) == SUBREG)
3142     {
3143       op1_subbyte = SUBREG_BYTE (operand1);
3144       op1_subbyte /= GET_MODE_SIZE (DImode);
3145       op1_subbyte *= GET_MODE_SIZE (DImode);
3146       operand1 = XEXP (operand1, 0);
3147     }
3148
3149   emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3150                           shift_56));
3151   emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
3152   DONE;
3153 })
3154
3155 (define_insn "*sign_extendqidi2_insn"
3156   [(set (match_operand:DI 0 "register_operand" "=r")
3157         (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3158   "TARGET_ARCH64"
3159   "ldsb\t%1, %0"
3160   [(set_attr "type" "sload")
3161    (set_attr "us3load_type" "3cycle")])
3162
3163 (define_expand "extendhidi2"
3164   [(set (match_operand:DI 0 "register_operand" "")
3165         (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
3166   "TARGET_ARCH64"
3167 {
3168   rtx temp = gen_reg_rtx (DImode);
3169   rtx shift_48 = GEN_INT (48);
3170   int op1_subbyte = 0;
3171
3172   if (GET_CODE (operand1) == SUBREG)
3173     {
3174       op1_subbyte = SUBREG_BYTE (operand1);
3175       op1_subbyte /= GET_MODE_SIZE (DImode);
3176       op1_subbyte *= GET_MODE_SIZE (DImode);
3177       operand1 = XEXP (operand1, 0);
3178     }
3179
3180   emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3181                           shift_48));
3182   emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
3183   DONE;
3184 })
3185
3186 (define_insn "*sign_extendhidi2_insn"
3187   [(set (match_operand:DI 0 "register_operand" "=r")
3188         (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3189   "TARGET_ARCH64"
3190   "ldsh\t%1, %0"
3191   [(set_attr "type" "sload")
3192    (set_attr "us3load_type" "3cycle")])
3193
3194 (define_expand "extendsidi2"
3195   [(set (match_operand:DI 0 "register_operand" "")
3196         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3197   "TARGET_ARCH64"
3198   "")
3199
3200 (define_insn "*sign_extendsidi2_insn"
3201   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
3202         (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m,*f")))]
3203   "TARGET_ARCH64"
3204   "@
3205   sra\t%1, 0, %0
3206   ldsw\t%1, %0
3207   movstosw\t%1, %0"
3208   [(set_attr "type" "shift,sload,*")
3209    (set_attr "us3load_type" "*,3cycle,*")
3210    (set_attr "cpu_feature" "*,*,vis3")])
3211
3212
3213 ;; Special pattern for optimizing bit-field compares.  This is needed
3214 ;; because combine uses this as a canonical form.
3215
3216 (define_insn "*cmp_zero_extract"
3217   [(set (reg:CC CC_REG)
3218         (compare:CC
3219          (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
3220                           (match_operand:SI 1 "small_int_operand" "I")
3221                           (match_operand:SI 2 "small_int_operand" "I"))
3222          (const_int 0)))]
3223   "INTVAL (operands[2]) > 19"
3224 {
3225   int len = INTVAL (operands[1]);
3226   int pos = 32 - INTVAL (operands[2]) - len;
3227   HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
3228   operands[1] = GEN_INT (mask);
3229   return "andcc\t%0, %1, %%g0";
3230 }
3231   [(set_attr "type" "compare")])
3232
3233 (define_insn "*cmp_zero_extract_sp64"
3234   [(set (reg:CCX CC_REG)
3235         (compare:CCX
3236          (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
3237                           (match_operand:SI 1 "small_int_operand" "I")
3238                           (match_operand:SI 2 "small_int_operand" "I"))
3239          (const_int 0)))]
3240   "TARGET_ARCH64 && INTVAL (operands[2]) > 51"
3241 {
3242   int len = INTVAL (operands[1]);
3243   int pos = 64 - INTVAL (operands[2]) - len;
3244   HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
3245   operands[1] = GEN_INT (mask);
3246   return "andcc\t%0, %1, %%g0";
3247 }
3248   [(set_attr "type" "compare")])
3249
3250
3251 ;; Conversions between float, double and long double.
3252
3253 (define_insn "extendsfdf2"
3254   [(set (match_operand:DF 0 "register_operand" "=e")
3255         (float_extend:DF
3256          (match_operand:SF 1 "register_operand" "f")))]
3257   "TARGET_FPU"
3258   "fstod\t%1, %0"
3259   [(set_attr "type" "fp")
3260    (set_attr "fptype" "double")])
3261
3262 (define_expand "extendsftf2"
3263   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3264         (float_extend:TF
3265          (match_operand:SF 1 "register_operand" "")))]
3266   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3267   "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3268
3269 (define_insn "*extendsftf2_hq"
3270   [(set (match_operand:TF 0 "register_operand" "=e")
3271         (float_extend:TF
3272          (match_operand:SF 1 "register_operand" "f")))]
3273   "TARGET_FPU && TARGET_HARD_QUAD"
3274   "fstoq\t%1, %0"
3275   [(set_attr "type" "fp")])
3276
3277 (define_expand "extenddftf2"
3278   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3279         (float_extend:TF
3280          (match_operand:DF 1 "register_operand" "")))]
3281   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3282   "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3283
3284 (define_insn "*extenddftf2_hq"
3285   [(set (match_operand:TF 0 "register_operand" "=e")
3286         (float_extend:TF
3287          (match_operand:DF 1 "register_operand" "e")))]
3288   "TARGET_FPU && TARGET_HARD_QUAD"
3289   "fdtoq\t%1, %0"
3290   [(set_attr "type" "fp")])
3291
3292 (define_insn "truncdfsf2"
3293   [(set (match_operand:SF 0 "register_operand" "=f")
3294         (float_truncate:SF
3295          (match_operand:DF 1 "register_operand" "e")))]
3296   "TARGET_FPU"
3297   "fdtos\t%1, %0"
3298   [(set_attr "type" "fp")
3299    (set_attr "fptype" "double")])
3300
3301 (define_expand "trunctfsf2"
3302   [(set (match_operand:SF 0 "register_operand" "")
3303         (float_truncate:SF
3304          (match_operand:TF 1 "general_operand" "")))]
3305   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3306   "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3307
3308 (define_insn "*trunctfsf2_hq"
3309   [(set (match_operand:SF 0 "register_operand" "=f")
3310         (float_truncate:SF
3311          (match_operand:TF 1 "register_operand" "e")))]
3312   "TARGET_FPU && TARGET_HARD_QUAD"
3313   "fqtos\t%1, %0"
3314   [(set_attr "type" "fp")])
3315
3316 (define_expand "trunctfdf2"
3317   [(set (match_operand:DF 0 "register_operand" "")
3318         (float_truncate:DF
3319          (match_operand:TF 1 "general_operand" "")))]
3320   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3321   "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3322
3323 (define_insn "*trunctfdf2_hq"
3324   [(set (match_operand:DF 0 "register_operand" "=e")
3325         (float_truncate:DF
3326          (match_operand:TF 1 "register_operand" "e")))]
3327   "TARGET_FPU && TARGET_HARD_QUAD"
3328   "fqtod\t%1, %0"
3329   [(set_attr "type" "fp")])
3330
3331
3332 ;; Conversion between fixed point and floating point.
3333
3334 (define_insn "floatsisf2"
3335   [(set (match_operand:SF 0 "register_operand" "=f")
3336         (float:SF (match_operand:SI 1 "register_operand" "f")))]
3337   "TARGET_FPU"
3338   "fitos\t%1, %0"
3339   [(set_attr "type" "fp")
3340    (set_attr "fptype" "double")])
3341
3342 (define_insn "floatsidf2"
3343   [(set (match_operand:DF 0 "register_operand" "=e")
3344         (float:DF (match_operand:SI 1 "register_operand" "f")))]
3345   "TARGET_FPU"
3346   "fitod\t%1, %0"
3347   [(set_attr "type" "fp")
3348    (set_attr "fptype" "double")])
3349
3350 (define_expand "floatsitf2"
3351   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3352         (float:TF (match_operand:SI 1 "register_operand" "")))]
3353   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3354   "emit_tfmode_cvt (FLOAT, operands); DONE;")
3355
3356 (define_insn "*floatsitf2_hq"
3357   [(set (match_operand:TF 0 "register_operand" "=e")
3358         (float:TF (match_operand:SI 1 "register_operand" "f")))]
3359   "TARGET_FPU && TARGET_HARD_QUAD"
3360   "fitoq\t%1, %0"
3361   [(set_attr "type" "fp")])
3362
3363 (define_expand "floatunssitf2"
3364   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3365         (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
3366   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3367   "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3368
3369 ;; Now the same for 64 bit sources.
3370
3371 (define_insn "floatdisf2"
3372   [(set (match_operand:SF 0 "register_operand" "=f")
3373         (float:SF (match_operand:DI 1 "register_operand" "e")))]
3374   "TARGET_V9 && TARGET_FPU"
3375   "fxtos\t%1, %0"
3376   [(set_attr "type" "fp")
3377    (set_attr "fptype" "double")])
3378