OSDN Git Service

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