OSDN Git Service

More consistent access to sparc %ger register.
[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_MOVE_PIC_LABEL       5)
32    (UNSPEC_SETH44               6)
33    (UNSPEC_SETM44               7)
34    (UNSPEC_SETHH                9)
35    (UNSPEC_SETLM                10)
36    (UNSPEC_EMB_HISUM            11)
37    (UNSPEC_EMB_TEXTUHI          13)
38    (UNSPEC_EMB_TEXTHI           14)
39    (UNSPEC_EMB_TEXTULO          15)
40    (UNSPEC_EMB_SETHM            18)
41    (UNSPEC_MOVE_GOTDATA         19)
42
43    (UNSPEC_MEMBAR               20)
44
45    (UNSPEC_TLSGD                30)
46    (UNSPEC_TLSLDM               31)
47    (UNSPEC_TLSLDO               32)
48    (UNSPEC_TLSIE                33)
49    (UNSPEC_TLSLE                34)
50    (UNSPEC_TLSLD_BASE           35)
51
52    (UNSPEC_FPACK16              40)
53    (UNSPEC_FPACK32              41)
54    (UNSPEC_FPACKFIX             42)
55    (UNSPEC_FEXPAND              43)
56    (UNSPEC_FPMERGE              44)
57    (UNSPEC_MUL16AL              45)
58    (UNSPEC_MUL8UL               46)
59    (UNSPEC_MULDUL               47)
60    (UNSPEC_ALIGNDATA            48)
61    (UNSPEC_FCMP                 49)
62    (UNSPEC_PDIST                50)
63    (UNSPEC_EDGE8                51)
64    (UNSPEC_EDGE8L               52)
65    (UNSPEC_EDGE16               53)
66    (UNSPEC_EDGE16L              54)
67    (UNSPEC_EDGE32               55)
68    (UNSPEC_EDGE32L              56)
69    (UNSPEC_ARRAY8               57)
70    (UNSPEC_ARRAY16              58)
71    (UNSPEC_ARRAY32              59)
72
73    (UNSPEC_SP_SET               60)
74    (UNSPEC_SP_TEST              61)
75
76    (UNSPEC_EDGE8N               70)
77    (UNSPEC_EDGE8LN              71)
78    (UNSPEC_EDGE16N              72)
79    (UNSPEC_EDGE16LN             73)
80    (UNSPEC_EDGE32N              74)
81    (UNSPEC_EDGE32LN             75)
82    (UNSPEC_BSHUFFLE             76)
83    (UNSPEC_CMASK8               77)
84    (UNSPEC_CMASK16              78)
85    (UNSPEC_CMASK32              79)
86    (UNSPEC_FCHKSM16             80)
87    (UNSPEC_PDISTN               81)
88    (UNSPEC_FUCMP                82)
89   ])
90
91 (define_constants
92   [(UNSPECV_BLOCKAGE            0)
93    (UNSPECV_FLUSHW              1)
94    (UNSPECV_GOTO                2)
95    (UNSPECV_FLUSH               4)
96    (UNSPECV_SAVEW               6)
97    (UNSPECV_CAS                 8)
98    (UNSPECV_SWAP                9)
99    (UNSPECV_LDSTUB              10)
100    (UNSPECV_PROBE_STACK_RANGE   11)
101   ])
102
103 (define_constants
104  [(G0_REG                       0)
105   (G1_REG                       1)
106   (G2_REG                       2)
107   (G3_REG                       3)
108   (G4_REG                       4)
109   (G5_REG                       5)
110   (G6_REG                       6)
111   (G7_REG                       7)
112   (O0_REG                       8)
113   (O1_REG                       9)
114   (O2_REG                       10)
115   (O3_REG                       11)
116   (O4_REG                       12)
117   (O5_REG                       13)
118   (O6_REG                       14)
119   (O7_REG                       15)
120   (L0_REG                       16)
121   (L1_REG                       17)
122   (L2_REG                       18)
123   (L3_REG                       19)
124   (L4_REG                       20)
125   (L5_REG                       21)
126   (L6_REG                       22)
127   (L7_REG                       23)
128   (I0_REG                       24)
129   (I1_REG                       25)
130   (I2_REG                       26)
131   (I3_REG                       27)
132   (I4_REG                       28)
133   (I5_REG                       29)
134   (I6_REG                       30)
135   (I7_REG                       31)
136   (F0_REG                       32)
137   (F1_REG                       33)
138   (F2_REG                       34)
139   (F3_REG                       35)
140   (F4_REG                       36)
141   (F5_REG                       37)
142   (F6_REG                       38)
143   (F7_REG                       39)
144   (F8_REG                       40)
145   (F9_REG                       41)
146   (F10_REG                      42)
147   (F11_REG                      43)
148   (F12_REG                      44)
149   (F13_REG                      45)
150   (F14_REG                      46)
151   (F15_REG                      47)
152   (F16_REG                      48)
153   (F17_REG                      49)
154   (F18_REG                      50)
155   (F19_REG                      51)
156   (F20_REG                      52)
157   (F21_REG                      53)
158   (F22_REG                      54)
159   (F23_REG                      55)
160   (F24_REG                      56)
161   (F25_REG                      57)
162   (F26_REG                      58)
163   (F27_REG                      59)
164   (F28_REG                      60)
165   (F29_REG                      61)
166   (F30_REG                      62)
167   (F31_REG                      63)
168   (F32_REG                      64)
169   (F34_REG                      66)
170   (F36_REG                      68)
171   (F38_REG                      70)
172   (F40_REG                      72)
173   (F42_REG                      74)
174   (F44_REG                      76)
175   (F46_REG                      78)
176   (F48_REG                      80)
177   (F50_REG                      82)
178   (F52_REG                      84)
179   (F54_REG                      86)
180   (F56_REG                      88)
181   (F58_REG                      90)
182   (F60_REG                      92)
183   (F62_REG                      94)
184   (FCC0_REG                     96)
185   (FCC1_REG                     97)
186   (FCC2_REG                     98)
187   (FCC3_REG                     99)
188   (CC_REG                       100)
189   (SFP_REG                      101)
190   (GSR_REG                      102)
191  ])
192
193 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
194 (define_mode_iterator I [QI HI SI DI])
195 (define_mode_iterator F [SF DF TF])
196
197 ;; We don't define V1SI because SI should work just fine.
198 (define_mode_iterator V32 [SF V2HI V4QI])
199 (define_mode_iterator V32I [SI V2HI V4QI])
200
201 (define_mode_iterator V64 [DF V2SI V4HI V8QI])
202 (define_mode_iterator V64I [DI V2SI V4HI V8QI])
203
204 (define_mode_iterator V64N8 [V2SI V4HI])
205
206 ;; The upper 32 fp regs on the v9 can't hold SFmode values.  To deal with this
207 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip.  The name
208 ;; is a bit of a misnomer as it covers all 64 fp regs.  The corresponding
209 ;; constraint letter is 'e'.  To avoid any confusion, 'e' is used instead of
210 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
211
212 (define_mode_attr vbits [(V2SI "32") (V4HI "16") (SI "32s") (V2HI "16s")])
213 (define_mode_attr vconstr [(V2SI "e") (V4HI "e") (SI "f") (V2HI "f")])
214
215 ;; Attribute for cpu type.
216 ;; These must match the values for enum processor_type in sparc.h.
217 (define_attr "cpu"
218   "v7,
219    cypress,
220    v8,
221    supersparc,
222    hypersparc,
223    leon,
224    sparclite,
225    f930,
226    f934,
227    sparclite86x,
228    sparclet,
229    tsc701,
230    v9,
231    ultrasparc,
232    ultrasparc3,
233    niagara,
234    niagara2,
235    niagara3,
236    niagara4"
237   (const (symbol_ref "sparc_cpu_attr")))
238
239 ;; Attribute for the instruction set.
240 ;; At present we only need to distinguish v9/!v9, but for clarity we
241 ;; test TARGET_V8 too.
242 (define_attr "isa" "v7,v8,v9,sparclet"
243  (const
244   (cond [(symbol_ref "TARGET_V9") (const_string "v9")
245          (symbol_ref "TARGET_V8") (const_string "v8")
246          (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
247         (const_string "v7"))))
248
249 ;; Insn type.
250 (define_attr "type"
251   "ialu,compare,shift,
252    load,sload,store,
253    uncond_branch,branch,call,sibcall,call_no_delay_slot,return,
254    imul,idiv,
255    fpload,fpstore,
256    fp,fpmove,
257    fpcmove,fpcrmove,
258    fpcmp,
259    fpmul,fpdivs,fpdivd,
260    fpsqrts,fpsqrtd,
261    fga,fgm_pack,fgm_mul,fgm_pdist,fgm_cmp,edge,edgen,gsr,array,
262    cmove,
263    ialuX,
264    multi,savew,flushw,iflush,trap"
265   (const_string "ialu"))
266
267 ;; True if branch/call has empty delay slot and will emit a nop in it
268 (define_attr "empty_delay_slot" "false,true"
269   (symbol_ref "(empty_delay_slot (insn)
270                 ? EMPTY_DELAY_SLOT_TRUE : EMPTY_DELAY_SLOT_FALSE)"))
271
272 (define_attr "branch_type" "none,icc,fcc,reg"
273   (const_string "none"))
274
275 (define_attr "pic" "false,true"
276   (symbol_ref "(flag_pic != 0 ? PIC_TRUE : PIC_FALSE)"))
277
278 (define_attr "calls_alloca" "false,true"
279   (symbol_ref "(cfun->calls_alloca != 0
280                 ? CALLS_ALLOCA_TRUE : CALLS_ALLOCA_FALSE)"))
281
282 (define_attr "calls_eh_return" "false,true"
283    (symbol_ref "(crtl->calls_eh_return != 0
284                  ? CALLS_EH_RETURN_TRUE : CALLS_EH_RETURN_FALSE)"))
285
286 (define_attr "leaf_function" "false,true"
287   (symbol_ref "(current_function_uses_only_leaf_regs != 0
288                 ? LEAF_FUNCTION_TRUE : LEAF_FUNCTION_FALSE)"))
289
290 (define_attr "delayed_branch" "false,true"
291   (symbol_ref "(flag_delayed_branch != 0
292                 ? DELAYED_BRANCH_TRUE : DELAYED_BRANCH_FALSE)"))
293
294 (define_attr "flat" "false,true"
295   (symbol_ref "(TARGET_FLAT != 0
296                 ? FLAT_TRUE : FLAT_FALSE)"))
297
298 ;; Length (in # of insns).
299 ;; Beware that setting a length greater or equal to 3 for conditional branches
300 ;; has a side-effect (see output_cbranch and output_v9branch).
301 (define_attr "length" ""
302   (cond [(eq_attr "type" "uncond_branch,call")
303            (if_then_else (eq_attr "empty_delay_slot" "true")
304              (const_int 2)
305              (const_int 1))
306          (eq_attr "type" "sibcall")
307            (if_then_else (eq_attr "leaf_function" "true")
308              (if_then_else (eq_attr "empty_delay_slot" "true")
309                (const_int 3)
310                (const_int 2))
311              (if_then_else (eq_attr "empty_delay_slot" "true")
312                (const_int 2)
313                (const_int 1)))
314          (eq_attr "branch_type" "icc")
315            (if_then_else (match_operand 0 "noov_compare64_operator" "")
316              (if_then_else (lt (pc) (match_dup 1))
317                (if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000))
318                  (if_then_else (eq_attr "empty_delay_slot" "true")
319                    (const_int 2)
320                    (const_int 1))
321                  (if_then_else (eq_attr "empty_delay_slot" "true")
322                    (const_int 4)
323                    (const_int 3)))
324                (if_then_else (lt (minus (pc) (match_dup 1)) (const_int 260000))
325                  (if_then_else (eq_attr "empty_delay_slot" "true")
326                    (const_int 2)
327                    (const_int 1))
328                  (if_then_else (eq_attr "empty_delay_slot" "true")
329                    (const_int 4)
330                    (const_int 3))))
331              (if_then_else (eq_attr "empty_delay_slot" "true")
332                (const_int 2)
333                (const_int 1)))
334          (eq_attr "branch_type" "fcc")
335            (if_then_else (match_operand 0 "fcc0_register_operand" "")
336              (if_then_else (eq_attr "empty_delay_slot" "true")
337                (if_then_else (not (match_test "TARGET_V9"))
338                  (const_int 3)
339                  (const_int 2))
340                (if_then_else (not (match_test "TARGET_V9"))
341                  (const_int 2)
342                  (const_int 1)))
343              (if_then_else (lt (pc) (match_dup 2))
344                (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000))
345                  (if_then_else (eq_attr "empty_delay_slot" "true")
346                    (const_int 2)
347                    (const_int 1))
348                  (if_then_else (eq_attr "empty_delay_slot" "true")
349                    (const_int 4)
350                    (const_int 3)))
351                (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000))
352                  (if_then_else (eq_attr "empty_delay_slot" "true")
353                    (const_int 2)
354                    (const_int 1))
355                  (if_then_else (eq_attr "empty_delay_slot" "true")
356                    (const_int 4)
357                    (const_int 3)))))
358          (eq_attr "branch_type" "reg")
359            (if_then_else (lt (pc) (match_dup 2))
360              (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000))
361                (if_then_else (eq_attr "empty_delay_slot" "true")
362                  (const_int 2)
363                  (const_int 1))
364                (if_then_else (eq_attr "empty_delay_slot" "true")
365                  (const_int 4)
366                  (const_int 3)))
367              (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000))
368                (if_then_else (eq_attr "empty_delay_slot" "true")
369                  (const_int 2)
370                  (const_int 1))
371                (if_then_else (eq_attr "empty_delay_slot" "true")
372                  (const_int 4)
373                  (const_int 3))))
374          ] (const_int 1)))
375
376 ;; FP precision.
377 (define_attr "fptype" "single,double"
378   (const_string "single"))
379
380 ;; UltraSPARC-III integer load type.
381 (define_attr "us3load_type" "2cycle,3cycle"
382   (const_string "2cycle"))
383
384 (define_asm_attributes
385   [(set_attr "length" "2")
386    (set_attr "type" "multi")])
387
388 ;; Attributes for instruction and branch scheduling
389 (define_attr "tls_call_delay" "false,true"
390   (symbol_ref "(tls_call_delay (insn)
391                 ? TLS_CALL_DELAY_TRUE : TLS_CALL_DELAY_FALSE)"))
392
393 (define_attr "in_call_delay" "false,true"
394   (cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
395                 (const_string "false")
396          (eq_attr "type" "load,fpload,store,fpstore")
397                 (if_then_else (eq_attr "length" "1")
398                               (const_string "true")
399                               (const_string "false"))]
400         (if_then_else (and (eq_attr "length" "1")
401                            (eq_attr "tls_call_delay" "true"))
402                       (const_string "true")
403                       (const_string "false"))))
404
405 (define_attr "eligible_for_sibcall_delay" "false,true"
406   (symbol_ref "(eligible_for_sibcall_delay (insn)
407                 ? ELIGIBLE_FOR_SIBCALL_DELAY_TRUE
408                 : ELIGIBLE_FOR_SIBCALL_DELAY_FALSE)"))
409
410 (define_attr "eligible_for_return_delay" "false,true"
411   (symbol_ref "(eligible_for_return_delay (insn)
412                 ? ELIGIBLE_FOR_RETURN_DELAY_TRUE
413                 : ELIGIBLE_FOR_RETURN_DELAY_FALSE)"))
414
415 ;; ??? !v9: Should implement the notion of predelay slots for floating-point
416 ;; branches.  This would allow us to remove the nop always inserted before
417 ;; a floating point branch.
418
419 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
420 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
421 ;; This is because doing so will add several pipeline stalls to the path
422 ;; that the load/store did not come from.  Unfortunately, there is no way
423 ;; to prevent fill_eager_delay_slots from using load/store without completely
424 ;; disabling them.  For the SPEC benchmark set, this is a serious lose,
425 ;; because it prevents us from moving back the final store of inner loops.
426
427 (define_attr "in_branch_delay" "false,true"
428   (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
429                      (eq_attr "length" "1"))
430                 (const_string "true")
431                 (const_string "false")))
432
433 (define_attr "in_uncond_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_annul_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_delay (eq_attr "type" "call")
446   [(eq_attr "in_call_delay" "true") (nil) (nil)])
447
448 (define_delay (eq_attr "type" "sibcall")
449   [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
450
451 (define_delay (eq_attr "type" "branch")
452   [(eq_attr "in_branch_delay" "true")
453    (nil) (eq_attr "in_annul_branch_delay" "true")])
454
455 (define_delay (eq_attr "type" "uncond_branch")
456   [(eq_attr "in_uncond_branch_delay" "true")
457    (nil) (nil)])
458
459 (define_delay (eq_attr "type" "return")
460   [(eq_attr "eligible_for_return_delay" "true") (nil) (nil)])
461
462
463 ;; Include SPARC DFA schedulers
464
465 (include "cypress.md")
466 (include "supersparc.md")
467 (include "hypersparc.md")
468 (include "leon.md")
469 (include "sparclet.md")
470 (include "ultra1_2.md")
471 (include "ultra3.md")
472 (include "niagara.md")
473 (include "niagara2.md")
474
475
476 ;; Operand and operator predicates and constraints
477
478 (include "predicates.md")
479 (include "constraints.md")
480
481
482 ;; Compare instructions.
483
484 ;; These are just the DEFINE_INSNs to match the patterns and the
485 ;; DEFINE_SPLITs for some of the scc insns that actually require
486 ;; more than one machine instruction.  DEFINE_EXPANDs are further down.
487
488 ;; The compare DEFINE_INSNs.
489
490 (define_insn "*cmpsi_insn"
491   [(set (reg:CC CC_REG)
492         (compare:CC (match_operand:SI 0 "register_operand" "r")
493                     (match_operand:SI 1 "arith_operand" "rI")))]
494   ""
495   "cmp\t%0, %1"
496   [(set_attr "type" "compare")])
497
498 (define_insn "*cmpdi_sp64"
499   [(set (reg:CCX CC_REG)
500         (compare:CCX (match_operand:DI 0 "register_operand" "r")
501                      (match_operand:DI 1 "arith_operand" "rI")))]
502   "TARGET_ARCH64"
503   "cmp\t%0, %1"
504   [(set_attr "type" "compare")])
505
506 (define_insn "*cmpsf_fpe"
507   [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
508         (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
509                        (match_operand:SF 2 "register_operand" "f")))]
510   "TARGET_FPU"
511 {
512   if (TARGET_V9)
513     return "fcmpes\t%0, %1, %2";
514   return "fcmpes\t%1, %2";
515 }
516   [(set_attr "type" "fpcmp")])
517
518 (define_insn "*cmpdf_fpe"
519   [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
520         (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
521                        (match_operand:DF 2 "register_operand" "e")))]
522   "TARGET_FPU"
523 {
524   if (TARGET_V9)
525     return "fcmped\t%0, %1, %2";
526   return "fcmped\t%1, %2";
527 }
528   [(set_attr "type" "fpcmp")
529    (set_attr "fptype" "double")])
530
531 (define_insn "*cmptf_fpe"
532   [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
533         (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
534                        (match_operand:TF 2 "register_operand" "e")))]
535   "TARGET_FPU && TARGET_HARD_QUAD"
536 {
537   if (TARGET_V9)
538     return "fcmpeq\t%0, %1, %2";
539   return "fcmpeq\t%1, %2";
540 }
541   [(set_attr "type" "fpcmp")])
542
543 (define_insn "*cmpsf_fp"
544   [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
545         (compare:CCFP (match_operand:SF 1 "register_operand" "f")
546                       (match_operand:SF 2 "register_operand" "f")))]
547   "TARGET_FPU"
548 {
549   if (TARGET_V9)
550     return "fcmps\t%0, %1, %2";
551   return "fcmps\t%1, %2";
552 }
553   [(set_attr "type" "fpcmp")])
554
555 (define_insn "*cmpdf_fp"
556   [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
557         (compare:CCFP (match_operand:DF 1 "register_operand" "e")
558                       (match_operand:DF 2 "register_operand" "e")))]
559   "TARGET_FPU"
560 {
561   if (TARGET_V9)
562     return "fcmpd\t%0, %1, %2";
563   return "fcmpd\t%1, %2";
564 }
565   [(set_attr "type" "fpcmp")
566    (set_attr "fptype" "double")])
567
568 (define_insn "*cmptf_fp"
569   [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
570         (compare:CCFP (match_operand:TF 1 "register_operand" "e")
571                       (match_operand:TF 2 "register_operand" "e")))]
572   "TARGET_FPU && TARGET_HARD_QUAD"
573 {
574   if (TARGET_V9)
575     return "fcmpq\t%0, %1, %2";
576   return "fcmpq\t%1, %2";
577 }
578   [(set_attr "type" "fpcmp")])
579 \f
580 ;; Next come the scc insns.
581
582 (define_expand "cstoresi4"
583   [(use (match_operator 1 "comparison_operator"
584          [(match_operand:SI 2 "compare_operand" "")
585           (match_operand:SI 3 "arith_operand" "")]))
586    (clobber (match_operand:SI 0 "register_operand"))]
587   ""
588 {
589   if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
590     operands[2] = force_reg (SImode, operands[2]);
591   if (emit_scc_insn (operands)) DONE; else FAIL;
592 })
593
594 (define_expand "cstoredi4"
595   [(use (match_operator 1 "comparison_operator"
596          [(match_operand:DI 2 "compare_operand" "")
597           (match_operand:DI 3 "arith_operand" "")]))
598    (clobber (match_operand:SI 0 "register_operand"))]
599   "TARGET_ARCH64"
600 {
601   if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
602     operands[2] = force_reg (DImode, operands[2]);
603   if (emit_scc_insn (operands)) DONE; else FAIL;
604 })
605
606 (define_expand "cstore<F:mode>4"
607   [(use (match_operator 1 "comparison_operator"
608          [(match_operand:F 2 "register_operand" "")
609           (match_operand:F 3 "register_operand" "")]))
610    (clobber (match_operand:SI 0 "register_operand"))]
611   "TARGET_FPU"
612   { if (emit_scc_insn (operands)) DONE; else FAIL; })
613
614 \f
615
616 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
617 ;; generate addcc/subcc instructions.
618
619 (define_expand "seqsi_special"
620   [(set (match_dup 3)
621         (xor:SI (match_operand:SI 1 "register_operand" "")
622                 (match_operand:SI 2 "register_operand" "")))
623    (parallel [(set (match_operand:SI 0 "register_operand" "")
624                    (eq:SI (match_dup 3) (const_int 0)))
625               (clobber (reg:CC CC_REG))])]
626   ""
627   { operands[3] = gen_reg_rtx (SImode); })
628
629 (define_expand "seqdi_special"
630   [(set (match_dup 3)
631         (xor:DI (match_operand:DI 1 "register_operand" "")
632                 (match_operand:DI 2 "register_operand" "")))
633    (set (match_operand:SI 0 "register_operand" "")
634         (eq:SI (match_dup 3) (const_int 0)))]
635   "TARGET_ARCH64"
636   { operands[3] = gen_reg_rtx (DImode); })
637
638 (define_expand "snesi_special"
639   [(set (match_dup 3)
640         (xor:SI (match_operand:SI 1 "register_operand" "")
641                 (match_operand:SI 2 "register_operand" "")))
642    (parallel [(set (match_operand:SI 0 "register_operand" "")
643                    (ne:SI (match_dup 3) (const_int 0)))
644               (clobber (reg:CC CC_REG))])]
645   ""
646   { operands[3] = gen_reg_rtx (SImode); })
647
648 (define_expand "snedi_special"
649   [(set (match_dup 3)
650         (xor:DI (match_operand:DI 1 "register_operand" "")
651                 (match_operand:DI 2 "register_operand" "")))
652    (set (match_operand:SI 0 "register_operand" "")
653         (ne:SI (match_dup 3) (const_int 0)))]
654   "TARGET_ARCH64"
655   { operands[3] = gen_reg_rtx (DImode); })
656
657
658 ;; Now the DEFINE_INSNs for the scc cases.
659
660 ;; The SEQ and SNE patterns are special because they can be done
661 ;; without any branching and do not involve a COMPARE.  We want
662 ;; them to always use the splits below so the results can be
663 ;; scheduled.
664
665 (define_insn_and_split "*snesi_zero"
666   [(set (match_operand:SI 0 "register_operand" "=r")
667         (ne:SI (match_operand:SI 1 "register_operand" "r")
668                (const_int 0)))
669    (clobber (reg:CC CC_REG))]
670   ""
671   "#"
672   ""
673   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
674                                            (const_int 0)))
675    (set (match_dup 0) (ltu:SI (reg:CC CC_REG) (const_int 0)))]
676   ""
677   [(set_attr "length" "2")])
678
679 (define_insn_and_split "*neg_snesi_zero"
680   [(set (match_operand:SI 0 "register_operand" "=r")
681         (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
682                        (const_int 0))))
683    (clobber (reg:CC CC_REG))]
684   ""
685   "#"
686   ""
687   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
688                                            (const_int 0)))
689    (set (match_dup 0) (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0))))]
690   ""
691   [(set_attr "length" "2")])
692
693 (define_insn_and_split "*snesi_zero_extend"
694   [(set (match_operand:DI 0 "register_operand" "=r")
695         (ne:DI (match_operand:SI 1 "register_operand" "r")
696                (const_int 0)))
697    (clobber (reg:CC CC_REG))]
698   "TARGET_ARCH64"
699   "#"
700   "&& 1"
701   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (minus:SI (const_int 0)
702                                                      (match_dup 1))
703                                            (const_int 0)))
704    (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
705                                                         (const_int 0))
706                                                (ltu:SI (reg:CC_NOOV CC_REG)
707                                                        (const_int 0)))))]
708   ""
709   [(set_attr "length" "2")])
710
711 (define_insn_and_split "*snedi_zero"
712   [(set (match_operand:DI 0 "register_operand" "=&r")
713         (ne:DI (match_operand:DI 1 "register_operand" "r")
714                (const_int 0)))]
715   "TARGET_ARCH64"
716   "#"
717   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
718   [(set (match_dup 0) (const_int 0))
719    (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
720                                               (const_int 0))
721                                        (const_int 1)
722                                        (match_dup 0)))]
723   ""
724   [(set_attr "length" "2")])
725
726 (define_insn_and_split "*neg_snedi_zero"
727   [(set (match_operand:DI 0 "register_operand" "=&r")
728         (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
729                        (const_int 0))))]
730   "TARGET_ARCH64"
731   "#"
732   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
733   [(set (match_dup 0) (const_int 0))
734    (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
735                                               (const_int 0))
736                                        (const_int -1)
737                                        (match_dup 0)))]
738   ""
739   [(set_attr "length" "2")])
740
741 (define_insn_and_split "*snedi_zero_trunc"
742   [(set (match_operand:SI 0 "register_operand" "=&r")
743         (ne:SI (match_operand:DI 1 "register_operand" "r")
744                (const_int 0)))]
745   "TARGET_ARCH64"
746   "#"
747   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
748   [(set (match_dup 0) (const_int 0))
749    (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
750                                               (const_int 0))
751                                        (const_int 1)
752                                        (match_dup 0)))]
753   ""
754   [(set_attr "length" "2")])
755
756 (define_insn_and_split "*seqsi_zero"
757   [(set (match_operand:SI 0 "register_operand" "=r")
758         (eq:SI (match_operand:SI 1 "register_operand" "r")
759                (const_int 0)))
760    (clobber (reg:CC CC_REG))]
761   ""
762   "#"
763   ""
764   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
765                                            (const_int 0)))
766    (set (match_dup 0) (geu:SI (reg:CC CC_REG) (const_int 0)))]
767   ""
768   [(set_attr "length" "2")])
769
770 (define_insn_and_split "*neg_seqsi_zero"
771   [(set (match_operand:SI 0 "register_operand" "=r")
772         (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
773                        (const_int 0))))
774    (clobber (reg:CC CC_REG))]
775   ""
776   "#"
777   ""
778   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
779                                            (const_int 0)))
780    (set (match_dup 0) (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0))))]
781   ""
782   [(set_attr "length" "2")])
783
784 (define_insn_and_split "*seqsi_zero_extend"
785   [(set (match_operand:DI 0 "register_operand" "=r")
786         (eq:DI (match_operand:SI 1 "register_operand" "r")
787                (const_int 0)))
788    (clobber (reg:CC CC_REG))]
789   "TARGET_ARCH64"
790   "#"
791   "&& 1"
792   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (minus:SI (const_int 0)
793                                                      (match_dup 1))
794                                            (const_int 0)))
795    (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
796                                                           (const_int -1))
797                                                 (ltu:SI (reg:CC_NOOV CC_REG)
798                                                         (const_int 0)))))]
799   ""
800   [(set_attr "length" "2")])
801
802 (define_insn_and_split "*seqdi_zero"
803   [(set (match_operand:DI 0 "register_operand" "=&r")
804         (eq:DI (match_operand:DI 1 "register_operand" "r")
805                (const_int 0)))]
806   "TARGET_ARCH64"
807   "#"
808   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
809   [(set (match_dup 0) (const_int 0))
810    (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
811                                               (const_int 0))
812                                        (const_int 1)
813                                        (match_dup 0)))]
814   ""
815   [(set_attr "length" "2")])
816
817 (define_insn_and_split "*neg_seqdi_zero"
818   [(set (match_operand:DI 0 "register_operand" "=&r")
819         (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
820                        (const_int 0))))]
821   "TARGET_ARCH64"
822   "#"
823   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
824   [(set (match_dup 0) (const_int 0))
825    (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
826                                               (const_int 0))
827                                        (const_int -1)
828                                        (match_dup 0)))]
829   ""
830   [(set_attr "length" "2")]) 
831
832 (define_insn_and_split "*seqdi_zero_trunc"
833   [(set (match_operand:SI 0 "register_operand" "=&r")
834         (eq:SI (match_operand:DI 1 "register_operand" "r")
835                (const_int 0)))]
836   "TARGET_ARCH64"
837   "#"
838   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
839   [(set (match_dup 0) (const_int 0))
840    (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
841                                               (const_int 0))
842                                        (const_int 1)
843                                        (match_dup 0)))]
844   ""
845   [(set_attr "length" "2")])
846
847 ;; We can also do (x + (i == 0)) and related, so put them in.
848 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
849 ;; versions for v9.
850
851 (define_insn_and_split "*x_plus_i_ne_0"
852   [(set (match_operand:SI 0 "register_operand" "=r")
853         (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
854                         (const_int 0))
855                  (match_operand:SI 2 "register_operand" "r")))
856    (clobber (reg:CC CC_REG))]
857   ""
858   "#"
859   ""
860   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
861                                            (const_int 0)))
862    (set (match_dup 0) (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
863                                (match_dup 2)))]
864   ""
865   [(set_attr "length" "2")])
866
867 (define_insn_and_split "*x_minus_i_ne_0"
868   [(set (match_operand:SI 0 "register_operand" "=r")
869         (minus:SI (match_operand:SI 2 "register_operand" "r")
870                   (ne:SI (match_operand:SI 1 "register_operand" "r")
871                          (const_int 0))))
872    (clobber (reg:CC CC_REG))]
873   ""
874   "#"
875   ""
876   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
877                                            (const_int 0)))
878    (set (match_dup 0) (minus:SI (match_dup 2)
879                                 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
880   ""
881   [(set_attr "length" "2")])
882
883 (define_insn_and_split "*x_plus_i_eq_0"
884   [(set (match_operand:SI 0 "register_operand" "=r")
885         (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
886                         (const_int 0))
887                  (match_operand:SI 2 "register_operand" "r")))
888    (clobber (reg:CC CC_REG))]
889   ""
890   "#"
891   ""
892   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
893                                            (const_int 0)))
894    (set (match_dup 0) (plus:SI (geu:SI (reg:CC CC_REG) (const_int 0))
895                                (match_dup 2)))]
896   ""
897   [(set_attr "length" "2")])
898
899 (define_insn_and_split "*x_minus_i_eq_0"
900   [(set (match_operand:SI 0 "register_operand" "=r")
901         (minus:SI (match_operand:SI 2 "register_operand" "r")
902                   (eq:SI (match_operand:SI 1 "register_operand" "r")
903                          (const_int 0))))
904    (clobber (reg:CC CC_REG))]
905   ""
906   "#"
907   ""
908   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
909                                            (const_int 0)))
910    (set (match_dup 0) (minus:SI (match_dup 2)
911                                 (geu:SI (reg:CC CC_REG) (const_int 0))))]
912   ""
913   [(set_attr "length" "2")])
914
915 ;; We can also do GEU and LTU directly, but these operate after a compare.
916 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
917 ;; versions for v9.
918
919 (define_insn "*sltu_insn"
920   [(set (match_operand:SI 0 "register_operand" "=r")
921         (ltu:SI (reg:CC CC_REG) (const_int 0)))]
922   ""
923   "addx\t%%g0, 0, %0"
924   [(set_attr "type" "ialuX")])
925
926 (define_insn "*neg_sltu_insn"
927   [(set (match_operand:SI 0 "register_operand" "=r")
928         (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0))))]
929   ""
930   "subx\t%%g0, 0, %0"
931   [(set_attr "type" "ialuX")])
932
933 ;; ??? Combine should canonicalize these next two to the same pattern.
934 (define_insn "*neg_sltu_minus_x"
935   [(set (match_operand:SI 0 "register_operand" "=r")
936         (minus:SI (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0)))
937                   (match_operand:SI 1 "arith_operand" "rI")))]
938   ""
939   "subx\t%%g0, %1, %0"
940   [(set_attr "type" "ialuX")])
941
942 (define_insn "*neg_sltu_plus_x"
943   [(set (match_operand:SI 0 "register_operand" "=r")
944         (neg:SI (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
945                          (match_operand:SI 1 "arith_operand" "rI"))))]
946   ""
947   "subx\t%%g0, %1, %0"
948   [(set_attr "type" "ialuX")])
949
950 (define_insn "*sgeu_insn"
951   [(set (match_operand:SI 0 "register_operand" "=r")
952         (geu:SI (reg:CC CC_REG) (const_int 0)))]
953   ""
954   "subx\t%%g0, -1, %0"
955   [(set_attr "type" "ialuX")])
956
957 (define_insn "*neg_sgeu_insn"
958   [(set (match_operand:SI 0 "register_operand" "=r")
959         (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0))))]
960   ""
961   "addx\t%%g0, -1, %0"
962   [(set_attr "type" "ialuX")])
963
964 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
965 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
966 ;; versions for v9.
967
968 (define_insn "*sltu_plus_x"
969   [(set (match_operand:SI 0 "register_operand" "=r")
970         (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
971                  (match_operand:SI 1 "arith_operand" "rI")))]
972   ""
973   "addx\t%%g0, %1, %0"
974   [(set_attr "type" "ialuX")])
975
976 (define_insn "*sltu_plus_x_plus_y"
977   [(set (match_operand:SI 0 "register_operand" "=r")
978         (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
979                  (plus:SI (match_operand:SI 1 "arith_operand" "%r")
980                           (match_operand:SI 2 "arith_operand" "rI"))))]
981   ""
982   "addx\t%1, %2, %0"
983   [(set_attr "type" "ialuX")])
984
985 (define_insn "*x_minus_sltu"
986   [(set (match_operand:SI 0 "register_operand" "=r")
987         (minus:SI (match_operand:SI 1 "register_operand" "r")
988                   (ltu:SI (reg:CC CC_REG) (const_int 0))))]
989   ""
990   "subx\t%1, 0, %0"
991   [(set_attr "type" "ialuX")])
992
993 ;; ??? Combine should canonicalize these next two to the same pattern.
994 (define_insn "*x_minus_y_minus_sltu"
995   [(set (match_operand:SI 0 "register_operand" "=r")
996         (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
997                             (match_operand:SI 2 "arith_operand" "rI"))
998                   (ltu:SI (reg:CC CC_REG) (const_int 0))))]
999   ""
1000   "subx\t%r1, %2, %0"
1001   [(set_attr "type" "ialuX")])
1002
1003 (define_insn "*x_minus_sltu_plus_y"
1004   [(set (match_operand:SI 0 "register_operand" "=r")
1005         (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
1006                   (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
1007                            (match_operand:SI 2 "arith_operand" "rI"))))]
1008   ""
1009   "subx\t%r1, %2, %0"
1010   [(set_attr "type" "ialuX")])
1011
1012 (define_insn "*sgeu_plus_x"
1013   [(set (match_operand:SI 0 "register_operand" "=r")
1014         (plus:SI (geu:SI (reg:CC CC_REG) (const_int 0))
1015                  (match_operand:SI 1 "register_operand" "r")))]
1016   ""
1017   "subx\t%1, -1, %0"
1018   [(set_attr "type" "ialuX")])
1019
1020 (define_insn "*x_minus_sgeu"
1021   [(set (match_operand:SI 0 "register_operand" "=r")
1022         (minus:SI (match_operand:SI 1 "register_operand" "r")
1023                   (geu:SI (reg:CC CC_REG) (const_int 0))))]
1024   ""
1025   "addx\t%1, -1, %0"
1026   [(set_attr "type" "ialuX")])
1027
1028 (define_split
1029   [(set (match_operand:SI 0 "register_operand" "")
1030         (match_operator:SI 2 "noov_compare_operator"
1031                            [(match_operand 1 "icc_or_fcc_register_operand" "")
1032                             (const_int 0)]))]
1033   "TARGET_V9
1034    && REGNO (operands[1]) == SPARC_ICC_REG
1035    && (GET_MODE (operands[1]) == CCXmode
1036        /* 32-bit LTU/GEU are better implemented using addx/subx.  */
1037        || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1038   [(set (match_dup 0) (const_int 0))
1039    (set (match_dup 0)
1040         (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1041                          (const_int 1)
1042                          (match_dup 0)))]
1043   "")
1044
1045 \f
1046 ;; These control RTL generation for conditional jump insns
1047
1048 (define_expand "cbranchcc4"
1049   [(set (pc)
1050         (if_then_else (match_operator 0 "comparison_operator"
1051                           [(match_operand 1 "compare_operand" "")
1052                            (match_operand 2 "const_zero_operand" "")])
1053                       (label_ref (match_operand 3 "" ""))
1054                       (pc)))]
1055   ""
1056   "")
1057
1058 (define_expand "cbranchsi4"
1059   [(use (match_operator 0 "comparison_operator"
1060          [(match_operand:SI 1 "compare_operand" "")
1061           (match_operand:SI 2 "arith_operand" "")]))
1062    (use (match_operand 3 ""))]
1063   ""
1064 {
1065   if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
1066     operands[1] = force_reg (SImode, operands[1]);
1067   emit_conditional_branch_insn (operands);
1068   DONE;
1069 })
1070
1071 (define_expand "cbranchdi4"
1072   [(use (match_operator 0 "comparison_operator"
1073          [(match_operand:DI 1 "compare_operand" "")
1074           (match_operand:DI 2 "arith_operand" "")]))
1075    (use (match_operand 3 ""))]
1076   "TARGET_ARCH64"
1077 {
1078   if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
1079     operands[1] = force_reg (DImode, operands[1]);
1080   emit_conditional_branch_insn (operands);
1081   DONE;
1082 })
1083
1084 (define_expand "cbranch<F:mode>4"
1085   [(use (match_operator 0 "comparison_operator"
1086          [(match_operand:F 1 "register_operand" "")
1087           (match_operand:F 2 "register_operand" "")]))
1088    (use (match_operand 3 ""))]
1089   "TARGET_FPU"
1090   { emit_conditional_branch_insn (operands); DONE; })
1091
1092
1093 ;; Now match both normal and inverted jump.
1094
1095 ;; XXX fpcmp nop braindamage
1096 (define_insn "*normal_branch"
1097   [(set (pc)
1098         (if_then_else (match_operator 0 "noov_compare_operator"
1099                                       [(reg CC_REG) (const_int 0)])
1100                       (label_ref (match_operand 1 "" ""))
1101                       (pc)))]
1102   ""
1103 {
1104   return output_cbranch (operands[0], operands[1], 1, 0,
1105                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1106                          insn);
1107 }
1108   [(set_attr "type" "branch")
1109    (set_attr "branch_type" "icc")])
1110
1111 ;; XXX fpcmp nop braindamage
1112 (define_insn "*inverted_branch"
1113   [(set (pc)
1114         (if_then_else (match_operator 0 "noov_compare_operator"
1115                                       [(reg CC_REG) (const_int 0)])
1116                       (pc)
1117                       (label_ref (match_operand 1 "" ""))))]
1118   ""
1119 {
1120   return output_cbranch (operands[0], operands[1], 1, 1,
1121                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1122                          insn);
1123 }
1124   [(set_attr "type" "branch")
1125    (set_attr "branch_type" "icc")])
1126
1127 ;; XXX fpcmp nop braindamage
1128 (define_insn "*normal_fp_branch"
1129   [(set (pc)
1130         (if_then_else (match_operator 1 "comparison_operator"
1131                                       [(match_operand:CCFP 0 "fcc_register_operand" "c")
1132                                        (const_int 0)])
1133                       (label_ref (match_operand 2 "" ""))
1134                       (pc)))]
1135   ""
1136 {
1137   return output_cbranch (operands[1], operands[2], 2, 0,
1138                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1139                          insn);
1140 }
1141   [(set_attr "type" "branch")
1142    (set_attr "branch_type" "fcc")])
1143
1144 ;; XXX fpcmp nop braindamage
1145 (define_insn "*inverted_fp_branch"
1146   [(set (pc)
1147         (if_then_else (match_operator 1 "comparison_operator"
1148                                       [(match_operand:CCFP 0 "fcc_register_operand" "c")
1149                                        (const_int 0)])
1150                       (pc)
1151                       (label_ref (match_operand 2 "" ""))))]
1152   ""
1153 {
1154   return output_cbranch (operands[1], operands[2], 2, 1,
1155                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1156                          insn);
1157 }
1158   [(set_attr "type" "branch")
1159    (set_attr "branch_type" "fcc")])
1160
1161 ;; XXX fpcmp nop braindamage
1162 (define_insn "*normal_fpe_branch"
1163   [(set (pc)
1164         (if_then_else (match_operator 1 "comparison_operator"
1165                                       [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1166                                        (const_int 0)])
1167                       (label_ref (match_operand 2 "" ""))
1168                       (pc)))]
1169   ""
1170 {
1171   return output_cbranch (operands[1], operands[2], 2, 0,
1172                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1173                          insn);
1174 }
1175   [(set_attr "type" "branch")
1176    (set_attr "branch_type" "fcc")])
1177
1178 ;; XXX fpcmp nop braindamage
1179 (define_insn "*inverted_fpe_branch"
1180   [(set (pc)
1181         (if_then_else (match_operator 1 "comparison_operator"
1182                                       [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1183                                        (const_int 0)])
1184                       (pc)
1185                       (label_ref (match_operand 2 "" ""))))]
1186   ""
1187 {
1188   return output_cbranch (operands[1], operands[2], 2, 1,
1189                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1190                          insn);
1191 }
1192   [(set_attr "type" "branch")
1193    (set_attr "branch_type" "fcc")])
1194
1195 ;; SPARC V9-specific jump insns.  None of these are guaranteed to be
1196 ;; in the architecture.
1197
1198 ;; There are no 32 bit brreg insns.
1199
1200 ;; XXX
1201 (define_insn "*normal_int_branch_sp64"
1202   [(set (pc)
1203         (if_then_else (match_operator 0 "v9_register_compare_operator"
1204                                       [(match_operand:DI 1 "register_operand" "r")
1205                                        (const_int 0)])
1206                       (label_ref (match_operand 2 "" ""))
1207                       (pc)))]
1208   "TARGET_ARCH64"
1209 {
1210   return output_v9branch (operands[0], operands[2], 1, 2, 0,
1211                           final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1212                           insn);
1213 }
1214   [(set_attr "type" "branch")
1215    (set_attr "branch_type" "reg")])
1216
1217 ;; XXX
1218 (define_insn "*inverted_int_branch_sp64"
1219   [(set (pc)
1220         (if_then_else (match_operator 0 "v9_register_compare_operator"
1221                                       [(match_operand:DI 1 "register_operand" "r")
1222                                        (const_int 0)])
1223                       (pc)
1224                       (label_ref (match_operand 2 "" ""))))]
1225   "TARGET_ARCH64"
1226 {
1227   return output_v9branch (operands[0], operands[2], 1, 2, 1,
1228                           final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1229                           insn);
1230 }
1231   [(set_attr "type" "branch")
1232    (set_attr "branch_type" "reg")])
1233
1234
1235 ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic
1236 ;; value subject to a PC-relative relocation.  Operand 2 is a helper function
1237 ;; that adds the PC value at the call point to register #(operand 3).
1238
1239 (define_insn "load_pcrel_sym<P:mode>"
1240   [(set (match_operand:P 0 "register_operand" "=r")
1241         (unspec:P [(match_operand:P 1 "symbolic_operand" "")
1242                    (match_operand:P 2 "call_address_operand" "")
1243                    (match_operand:P 3 "const_int_operand" "")] UNSPEC_LOAD_PCREL_SYM))
1244    (clobber (reg:P O7_REG))]
1245   "REGNO (operands[0]) == INTVAL (operands[3])"
1246 {
1247   if (flag_delayed_branch)
1248     return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0";
1249   else
1250     return "sethi\t%%hi(%a1-8), %0\n\tadd\t%0, %%lo(%a1-4), %0\n\tcall\t%a2\n\t nop";
1251 }
1252   [(set (attr "type") (const_string "multi"))
1253    (set (attr "length")
1254         (if_then_else (eq_attr "delayed_branch" "true")
1255                       (const_int 3)
1256                       (const_int 4)))])
1257
1258
1259 ;; Integer move instructions
1260
1261 (define_expand "movqi"
1262   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1263         (match_operand:QI 1 "general_operand" ""))]
1264   ""
1265 {
1266   if (sparc_expand_move (QImode, operands))
1267     DONE;
1268 })
1269
1270 (define_insn "*movqi_insn"
1271   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1272         (match_operand:QI 1 "input_operand"   "rI,m,rJ"))]
1273   "(register_operand (operands[0], QImode)
1274     || register_or_zero_operand (operands[1], QImode))"
1275   "@
1276    mov\t%1, %0
1277    ldub\t%1, %0
1278    stb\t%r1, %0"
1279   [(set_attr "type" "*,load,store")
1280    (set_attr "us3load_type" "*,3cycle,*")])
1281
1282 (define_expand "movhi"
1283   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1284         (match_operand:HI 1 "general_operand" ""))]
1285   ""
1286 {
1287   if (sparc_expand_move (HImode, operands))
1288     DONE;
1289 })
1290
1291 (define_insn "*movhi_insn"
1292   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1293         (match_operand:HI 1 "input_operand"   "rI,K,m,rJ"))]
1294   "(register_operand (operands[0], HImode)
1295     || register_or_zero_operand (operands[1], HImode))"
1296   "@
1297    mov\t%1, %0
1298    sethi\t%%hi(%a1), %0
1299    lduh\t%1, %0
1300    sth\t%r1, %0"
1301   [(set_attr "type" "*,*,load,store")
1302    (set_attr "us3load_type" "*,*,3cycle,*")])
1303
1304 ;; We always work with constants here.
1305 (define_insn "*movhi_lo_sum"
1306   [(set (match_operand:HI 0 "register_operand" "=r")
1307         (ior:HI (match_operand:HI 1 "register_operand" "%r")
1308                 (match_operand:HI 2 "small_int_operand" "I")))]
1309   ""
1310   "or\t%1, %2, %0")
1311
1312 (define_expand "movsi"
1313   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1314         (match_operand:SI 1 "general_operand" ""))]
1315   ""
1316 {
1317   if (sparc_expand_move (SImode, operands))
1318     DONE;
1319 })
1320
1321 (define_insn "*movsi_insn"
1322   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m,!f,!f,!m,d,d")
1323         (match_operand:SI 1 "input_operand"   "rI,K,m,rJ,f,m,f,J,P"))]
1324   "(register_operand (operands[0], SImode)
1325     || register_or_zero_or_all_ones_operand (operands[1], SImode))"
1326   "@
1327    mov\t%1, %0
1328    sethi\t%%hi(%a1), %0
1329    ld\t%1, %0
1330    st\t%r1, %0
1331    fmovs\t%1, %0
1332    ld\t%1, %0
1333    st\t%1, %0
1334    fzeros\t%0
1335    fones\t%0"
1336   [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga,fga")])
1337
1338 (define_insn "*movsi_lo_sum"
1339   [(set (match_operand:SI 0 "register_operand" "=r")
1340         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1341                    (match_operand:SI 2 "immediate_operand" "in")))]
1342   ""
1343   "or\t%1, %%lo(%a2), %0")
1344
1345 (define_insn "*movsi_high"
1346   [(set (match_operand:SI 0 "register_operand" "=r")
1347         (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1348   ""
1349   "sethi\t%%hi(%a1), %0")
1350
1351 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1352 ;; so that CSE won't optimize the address computation away.
1353 (define_insn "movsi_lo_sum_pic"
1354   [(set (match_operand:SI 0 "register_operand" "=r")
1355         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1356                    (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1357   "flag_pic"
1358 {
1359 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1360   return "xor\t%1, %%gdop_lox10(%a2), %0";
1361 #else
1362   return "or\t%1, %%lo(%a2), %0";
1363 #endif
1364 })
1365
1366 (define_insn "movsi_high_pic"
1367   [(set (match_operand:SI 0 "register_operand" "=r")
1368         (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1369   "flag_pic && check_pic (1)"
1370 {
1371 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1372   return "sethi\t%%gdop_hix22(%a1), %0";
1373 #else
1374   return "sethi\t%%hi(%a1), %0";
1375 #endif
1376 })
1377
1378 (define_insn "movsi_pic_gotdata_op"
1379   [(set (match_operand:SI 0 "register_operand" "=r")
1380         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
1381                     (match_operand:SI 2 "register_operand" "r")
1382                     (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
1383   "flag_pic && check_pic (1)"
1384 {
1385 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1386   return "ld\t[%1 + %2], %0, %%gdop(%a3)";
1387 #else
1388   return "ld\t[%1 + %2], %0";
1389 #endif
1390 }
1391   [(set_attr "type" "load")])
1392
1393 (define_expand "movsi_pic_label_ref"
1394   [(set (match_dup 3) (high:SI
1395      (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1396                  (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1397    (set (match_dup 4) (lo_sum:SI (match_dup 3)
1398      (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1399    (set (match_operand:SI 0 "register_operand" "=r")
1400         (minus:SI (match_dup 5) (match_dup 4)))]
1401   "flag_pic"
1402 {
1403   crtl->uses_pic_offset_table = 1;
1404   operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1405   if (!can_create_pseudo_p ())
1406     {
1407       operands[3] = operands[0];
1408       operands[4] = operands[0];
1409     }
1410   else
1411     {
1412       operands[3] = gen_reg_rtx (SImode);
1413       operands[4] = gen_reg_rtx (SImode);
1414     }
1415   operands[5] = pic_offset_table_rtx;
1416 })
1417
1418 (define_insn "*movsi_high_pic_label_ref"
1419   [(set (match_operand:SI 0 "register_operand" "=r")
1420       (high:SI
1421         (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1422                     (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1423   "flag_pic"
1424   "sethi\t%%hi(%a2-(%a1-.)), %0")
1425
1426 (define_insn "*movsi_lo_sum_pic_label_ref"
1427   [(set (match_operand:SI 0 "register_operand" "=r")
1428       (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1429         (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
1430                     (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1431   "flag_pic"
1432   "or\t%1, %%lo(%a3-(%a2-.)), %0")
1433
1434 ;; Set up the PIC register for VxWorks.
1435
1436 (define_expand "vxworks_load_got"
1437   [(set (match_dup 0)
1438         (high:SI (match_dup 1)))
1439    (set (match_dup 0)
1440         (mem:SI (lo_sum:SI (match_dup 0) (match_dup 1))))
1441    (set (match_dup 0)
1442         (mem:SI (lo_sum:SI (match_dup 0) (match_dup 2))))]
1443   "TARGET_VXWORKS_RTP"
1444 {
1445   operands[0] = pic_offset_table_rtx;
1446   operands[1] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_BASE);
1447   operands[2] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_INDEX);
1448 })
1449
1450 (define_expand "movdi"
1451   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1452         (match_operand:DI 1 "general_operand" ""))]
1453   ""
1454 {
1455   if (sparc_expand_move (DImode, operands))
1456     DONE;
1457 })
1458
1459 ;; Be careful, fmovd does not exist when !v9.
1460 ;; We match MEM moves directly when we have correct even
1461 ;; numbered registers, but fall into splits otherwise.
1462 ;; The constraint ordering here is really important to
1463 ;; avoid insane problems in reload, especially for patterns
1464 ;; of the form:
1465 ;;
1466 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
1467 ;;                       (const_int -5016)))
1468 ;;      (reg:DI 2 %g2))
1469 ;;
1470
1471 (define_insn "*movdi_insn_sp32"
1472   [(set (match_operand:DI 0 "nonimmediate_operand"
1473                                 "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
1474         (match_operand:DI 1 "input_operand"
1475                                 " J,U,T,r,o,i,r, f, T, o, f, f"))]
1476   "! TARGET_V9
1477    && (register_operand (operands[0], DImode)
1478        || register_or_zero_operand (operands[1], DImode))"
1479   "@
1480    #
1481    std\t%1, %0
1482    ldd\t%1, %0
1483    #
1484    #
1485    #
1486    #
1487    std\t%1, %0
1488    ldd\t%1, %0
1489    #
1490    #
1491    #"
1492   [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
1493    (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
1494
1495 (define_insn "*movdi_insn_sp32_v9"
1496   [(set (match_operand:DI 0 "nonimmediate_operand"
1497                                         "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?e,?e,?W")
1498         (match_operand:DI 1 "input_operand"
1499                                         " J,J,U,T,r,o,i,r, f, T, o, f, e, W, e"))]
1500   "! TARGET_ARCH64
1501    && TARGET_V9
1502    && (register_operand (operands[0], DImode)
1503        || register_or_zero_operand (operands[1], DImode))"
1504   "@
1505    stx\t%%g0, %0
1506    #
1507    std\t%1, %0
1508    ldd\t%1, %0
1509    #
1510    #
1511    #
1512    #
1513    std\t%1, %0
1514    ldd\t%1, %0
1515    #
1516    #
1517    fmovd\\t%1, %0
1518    ldd\\t%1, %0
1519    std\\t%1, %0"
1520   [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,fpload,fpstore")
1521    (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,*,*")
1522    (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])
1523
1524 (define_insn "*movdi_insn_sp64"
1525   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,m,?e,?e,?W,b,b")
1526         (match_operand:DI 1 "input_operand"   "rI,N,m,rJ,e,W,e,J,P"))]
1527   "TARGET_ARCH64
1528    && (register_operand (operands[0], DImode)
1529        || register_or_zero_or_all_ones_operand (operands[1], DImode))"
1530   "@
1531    mov\t%1, %0
1532    sethi\t%%hi(%a1), %0
1533    ldx\t%1, %0
1534    stx\t%r1, %0
1535    fmovd\t%1, %0
1536    ldd\t%1, %0
1537    std\t%1, %0
1538    fzero\t%0
1539    fone\t%0"
1540   [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga,fga")
1541    (set_attr "fptype" "*,*,*,*,double,*,*,double,double")])
1542
1543 (define_expand "movdi_pic_label_ref"
1544   [(set (match_dup 3) (high:DI
1545      (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1546                  (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1547    (set (match_dup 4) (lo_sum:DI (match_dup 3)
1548      (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1549    (set (match_operand:DI 0 "register_operand" "=r")
1550         (minus:DI (match_dup 5) (match_dup 4)))]
1551   "TARGET_ARCH64 && flag_pic"
1552 {
1553   crtl->uses_pic_offset_table = 1;
1554   operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1555   if (!can_create_pseudo_p ())
1556     {
1557       operands[3] = operands[0];
1558       operands[4] = operands[0];
1559     }
1560   else
1561     {
1562       operands[3] = gen_reg_rtx (DImode);
1563       operands[4] = gen_reg_rtx (DImode);
1564     }
1565   operands[5] = pic_offset_table_rtx;
1566 })
1567
1568 (define_insn "*movdi_high_pic_label_ref"
1569   [(set (match_operand:DI 0 "register_operand" "=r")
1570         (high:DI
1571           (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1572                       (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1573   "TARGET_ARCH64 && flag_pic"
1574   "sethi\t%%hi(%a2-(%a1-.)), %0")
1575
1576 (define_insn "*movdi_lo_sum_pic_label_ref"
1577   [(set (match_operand:DI 0 "register_operand" "=r")
1578       (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1579         (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
1580                     (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1581   "TARGET_ARCH64 && flag_pic"
1582   "or\t%1, %%lo(%a3-(%a2-.)), %0")
1583
1584 ;; SPARC-v9 code model support insns.  See sparc_emit_set_symbolic_const64
1585 ;; in sparc.c to see what is going on here... PIC stuff comes first.
1586
1587 (define_insn "movdi_lo_sum_pic"
1588   [(set (match_operand:DI 0 "register_operand" "=r")
1589         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1590                    (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1591   "TARGET_ARCH64 && flag_pic"
1592 {
1593 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1594   return "xor\t%1, %%gdop_lox10(%a2), %0";
1595 #else
1596   return "or\t%1, %%lo(%a2), %0";
1597 #endif
1598 })
1599
1600 (define_insn "movdi_high_pic"
1601   [(set (match_operand:DI 0 "register_operand" "=r")
1602         (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1603   "TARGET_ARCH64 && flag_pic && check_pic (1)"
1604 {
1605 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1606   return "sethi\t%%gdop_hix22(%a1), %0";
1607 #else
1608   return "sethi\t%%hi(%a1), %0";
1609 #endif
1610 })
1611
1612 (define_insn "movdi_pic_gotdata_op"
1613   [(set (match_operand:DI 0 "register_operand" "=r")
1614         (unspec:DI [(match_operand:DI 1 "register_operand" "r")
1615                     (match_operand:DI 2 "register_operand" "r")
1616                     (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
1617   "TARGET_ARCH64 && flag_pic && check_pic (1)"
1618 {
1619 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1620   return "ldx\t[%1 + %2], %0, %%gdop(%a3)";
1621 #else
1622   return "ldx\t[%1 + %2], %0";
1623 #endif
1624 }
1625   [(set_attr "type" "load")])
1626
1627 (define_insn "*sethi_di_medlow_embmedany_pic"
1628   [(set (match_operand:DI 0 "register_operand" "=r")
1629         (high:DI (match_operand:DI 1 "medium_pic_operand" "")))]
1630   "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
1631   "sethi\t%%hi(%a1), %0")
1632
1633 (define_insn "*sethi_di_medlow"
1634   [(set (match_operand:DI 0 "register_operand" "=r")
1635         (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
1636   "TARGET_CM_MEDLOW && check_pic (1)"
1637   "sethi\t%%hi(%a1), %0")
1638
1639 (define_insn "*losum_di_medlow"
1640   [(set (match_operand:DI 0 "register_operand" "=r")
1641         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1642                    (match_operand:DI 2 "symbolic_operand" "")))]
1643   "TARGET_CM_MEDLOW"
1644   "or\t%1, %%lo(%a2), %0")
1645
1646 (define_insn "seth44"
1647   [(set (match_operand:DI 0 "register_operand" "=r")
1648         (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
1649   "TARGET_CM_MEDMID"
1650   "sethi\t%%h44(%a1), %0")
1651
1652 (define_insn "setm44"
1653   [(set (match_operand:DI 0 "register_operand" "=r")
1654         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1655                    (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
1656   "TARGET_CM_MEDMID"
1657   "or\t%1, %%m44(%a2), %0")
1658
1659 (define_insn "setl44"
1660   [(set (match_operand:DI 0 "register_operand" "=r")
1661         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1662                    (match_operand:DI 2 "symbolic_operand" "")))]
1663   "TARGET_CM_MEDMID"
1664   "or\t%1, %%l44(%a2), %0")
1665
1666 (define_insn "sethh"
1667   [(set (match_operand:DI 0 "register_operand" "=r")
1668         (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
1669   "TARGET_CM_MEDANY"
1670   "sethi\t%%hh(%a1), %0")
1671
1672 (define_insn "setlm"
1673   [(set (match_operand:DI 0 "register_operand" "=r")
1674         (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
1675   "TARGET_CM_MEDANY"
1676   "sethi\t%%lm(%a1), %0")
1677
1678 (define_insn "sethm"
1679   [(set (match_operand:DI 0 "register_operand" "=r")
1680         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1681                    (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
1682   "TARGET_CM_MEDANY"
1683   "or\t%1, %%hm(%a2), %0")
1684
1685 (define_insn "setlo"
1686   [(set (match_operand:DI 0 "register_operand" "=r")
1687         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1688                    (match_operand:DI 2 "symbolic_operand" "")))]
1689   "TARGET_CM_MEDANY"
1690   "or\t%1, %%lo(%a2), %0")
1691
1692 (define_insn "embmedany_sethi"
1693   [(set (match_operand:DI 0 "register_operand" "=r")
1694         (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
1695   "TARGET_CM_EMBMEDANY && check_pic (1)"
1696   "sethi\t%%hi(%a1), %0")
1697
1698 (define_insn "embmedany_losum"
1699   [(set (match_operand:DI 0 "register_operand" "=r")
1700         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1701                    (match_operand:DI 2 "data_segment_operand" "")))]
1702   "TARGET_CM_EMBMEDANY"
1703   "add\t%1, %%lo(%a2), %0")
1704
1705 (define_insn "embmedany_brsum"
1706   [(set (match_operand:DI 0 "register_operand" "=r")
1707         (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
1708   "TARGET_CM_EMBMEDANY"
1709   "add\t%1, %_, %0")
1710
1711 (define_insn "embmedany_textuhi"
1712   [(set (match_operand:DI 0 "register_operand" "=r")
1713         (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
1714   "TARGET_CM_EMBMEDANY && check_pic (1)"
1715   "sethi\t%%uhi(%a1), %0")
1716
1717 (define_insn "embmedany_texthi"
1718   [(set (match_operand:DI 0 "register_operand" "=r")
1719         (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
1720   "TARGET_CM_EMBMEDANY && check_pic (1)"
1721   "sethi\t%%hi(%a1), %0")
1722
1723 (define_insn "embmedany_textulo"
1724   [(set (match_operand:DI 0 "register_operand" "=r")
1725         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1726                    (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
1727   "TARGET_CM_EMBMEDANY"
1728   "or\t%1, %%ulo(%a2), %0")
1729
1730 (define_insn "embmedany_textlo"
1731   [(set (match_operand:DI 0 "register_operand" "=r")
1732         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1733                    (match_operand:DI 2 "text_segment_operand" "")))]
1734   "TARGET_CM_EMBMEDANY"
1735   "or\t%1, %%lo(%a2), %0")
1736
1737 ;; Now some patterns to help reload out a bit.
1738 (define_expand "reload_indi"
1739   [(parallel [(match_operand:DI 0 "register_operand" "=r")
1740               (match_operand:DI 1 "immediate_operand" "")
1741               (match_operand:TI 2 "register_operand" "=&r")])]
1742   "(TARGET_CM_MEDANY
1743     || TARGET_CM_EMBMEDANY)
1744    && ! flag_pic"
1745 {
1746   sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1747   DONE;
1748 })
1749
1750 (define_expand "reload_outdi"
1751   [(parallel [(match_operand:DI 0 "register_operand" "=r")
1752               (match_operand:DI 1 "immediate_operand" "")
1753               (match_operand:TI 2 "register_operand" "=&r")])]
1754   "(TARGET_CM_MEDANY
1755     || TARGET_CM_EMBMEDANY)
1756    && ! flag_pic"
1757 {
1758   sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1759   DONE;
1760 })
1761
1762 ;; Split up putting CONSTs and REGs into DI regs when !arch64
1763 (define_split
1764   [(set (match_operand:DI 0 "register_operand" "")
1765         (match_operand:DI 1 "const_int_operand" ""))]
1766   "! TARGET_ARCH64 && reload_completed"
1767   [(clobber (const_int 0))]
1768 {
1769 #if HOST_BITS_PER_WIDE_INT == 32
1770   emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1771                         (INTVAL (operands[1]) < 0) ?
1772                         constm1_rtx :
1773                         const0_rtx));
1774   emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1775                         operands[1]));
1776 #else
1777   unsigned int low, high;
1778
1779   low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
1780   high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
1781   emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
1782
1783   /* Slick... but this trick loses if this subreg constant part
1784      can be done in one insn.  */
1785   if (low == high
1786       && ! SPARC_SETHI32_P (high)
1787       && ! SPARC_SIMM13_P (high))
1788     emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1789                           gen_highpart (SImode, operands[0])));
1790   else
1791     emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
1792 #endif
1793   DONE;
1794 })
1795
1796 (define_split
1797   [(set (match_operand:DI 0 "register_operand" "")
1798         (match_operand:DI 1 "const_double_operand" ""))]
1799   "reload_completed
1800    && (! TARGET_V9
1801        || (! TARGET_ARCH64
1802            && ((GET_CODE (operands[0]) == REG
1803                 && REGNO (operands[0]) < 32)
1804                || (GET_CODE (operands[0]) == SUBREG
1805                    && GET_CODE (SUBREG_REG (operands[0])) == REG
1806                    && REGNO (SUBREG_REG (operands[0])) < 32))))"
1807   [(clobber (const_int 0))]
1808 {
1809   emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1810                         GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
1811
1812   /* Slick... but this trick loses if this subreg constant part
1813      can be done in one insn.  */
1814   if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
1815       && ! SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
1816       && ! SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1])))
1817     {
1818       emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1819                             gen_highpart (SImode, operands[0])));
1820     }
1821   else
1822     {
1823       emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1824                             GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
1825     }
1826   DONE;
1827 })
1828
1829 (define_split
1830   [(set (match_operand:DI 0 "register_operand" "")
1831         (match_operand:DI 1 "register_operand" ""))]
1832   "reload_completed
1833    && (! TARGET_V9
1834        || (! TARGET_ARCH64
1835            && ((GET_CODE (operands[0]) == REG
1836                 && REGNO (operands[0]) < 32)
1837                || (GET_CODE (operands[0]) == SUBREG
1838                    && GET_CODE (SUBREG_REG (operands[0])) == REG
1839                    && REGNO (SUBREG_REG (operands[0])) < 32))))"
1840   [(clobber (const_int 0))]
1841 {
1842   rtx set_dest = operands[0];
1843   rtx set_src = operands[1];
1844   rtx dest1, dest2;
1845   rtx src1, src2;
1846
1847   dest1 = gen_highpart (SImode, set_dest);
1848   dest2 = gen_lowpart (SImode, set_dest);
1849   src1 = gen_highpart (SImode, set_src);
1850   src2 = gen_lowpart (SImode, set_src);
1851
1852   /* Now emit using the real source and destination we found, swapping
1853      the order if we detect overlap.  */
1854   if (reg_overlap_mentioned_p (dest1, src2))
1855     {
1856       emit_insn (gen_movsi (dest2, src2));
1857       emit_insn (gen_movsi (dest1, src1));
1858     }
1859   else
1860     {
1861       emit_insn (gen_movsi (dest1, src1));
1862       emit_insn (gen_movsi (dest2, src2));
1863     }
1864   DONE;
1865 })
1866
1867 ;; Now handle the cases of memory moves from/to non-even
1868 ;; DI mode register pairs.
1869 (define_split
1870   [(set (match_operand:DI 0 "register_operand" "")
1871         (match_operand:DI 1 "memory_operand" ""))]
1872   "(! TARGET_ARCH64
1873     && reload_completed
1874     && sparc_splitdi_legitimate (operands[0], operands[1]))"
1875   [(clobber (const_int 0))]
1876 {
1877   rtx word0 = adjust_address (operands[1], SImode, 0);
1878   rtx word1 = adjust_address (operands[1], SImode, 4);
1879   rtx high_part = gen_highpart (SImode, operands[0]);
1880   rtx low_part = gen_lowpart (SImode, operands[0]);
1881
1882   if (reg_overlap_mentioned_p (high_part, word1))
1883     {
1884       emit_insn (gen_movsi (low_part, word1));
1885       emit_insn (gen_movsi (high_part, word0));
1886     }
1887   else
1888     {
1889       emit_insn (gen_movsi (high_part, word0));
1890       emit_insn (gen_movsi (low_part, word1));
1891     }
1892   DONE;
1893 })
1894
1895 (define_split
1896   [(set (match_operand:DI 0 "memory_operand" "")
1897         (match_operand:DI 1 "register_operand" ""))]
1898   "(! TARGET_ARCH64
1899     && reload_completed
1900     && sparc_splitdi_legitimate (operands[1], operands[0]))"
1901   [(clobber (const_int 0))]
1902 {
1903   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
1904                         gen_highpart (SImode, operands[1])));
1905   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
1906                         gen_lowpart (SImode, operands[1])));
1907   DONE;
1908 })
1909
1910 (define_split
1911   [(set (match_operand:DI 0 "memory_operand" "")
1912         (match_operand:DI 1 "const_zero_operand" ""))]
1913   "reload_completed
1914    && (! TARGET_V9
1915        || (! TARGET_ARCH64
1916            && ! mem_min_alignment (operands[0], 8)))
1917    && offsettable_memref_p (operands[0])"
1918   [(clobber (const_int 0))]
1919 {
1920   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
1921   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
1922   DONE;
1923 })
1924
1925
1926 ;; Floating point and vector move instructions
1927
1928 ;; Yes, you guessed it right, the former movsf expander.
1929 (define_expand "mov<V32:mode>"
1930   [(set (match_operand:V32 0 "nonimmediate_operand" "")
1931         (match_operand:V32 1 "general_operand" ""))]
1932   "<V32:MODE>mode == SFmode || TARGET_VIS"
1933 {
1934   if (sparc_expand_move (<V32:MODE>mode, operands))
1935     DONE;
1936 })
1937
1938 (define_insn "*movsf_insn"
1939   [(set (match_operand:V32 0 "nonimmediate_operand" "=d,d,f,*r,*r,*r,f,*r,m,m")
1940         (match_operand:V32 1 "input_operand"        "GY,ZC,f,*rRY,Q,S,m,m,f,*rGY"))]
1941   "TARGET_FPU
1942    && (register_operand (operands[0], <V32:MODE>mode)
1943        || register_or_zero_or_all_ones_operand (operands[1], <V32:MODE>mode))"
1944 {
1945   if (GET_CODE (operands[1]) == CONST_DOUBLE
1946       && (which_alternative == 3
1947           || which_alternative == 4
1948           || which_alternative == 5))
1949     {
1950       REAL_VALUE_TYPE r;
1951       long i;
1952
1953       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
1954       REAL_VALUE_TO_TARGET_SINGLE (r, i);
1955       operands[1] = GEN_INT (i);
1956     }
1957
1958   switch (which_alternative)
1959     {
1960     case 0:
1961       return "fzeros\t%0";
1962     case 1:
1963       return "fones\t%0";
1964     case 2:
1965       return "fmovs\t%1, %0";
1966     case 3:
1967       return "mov\t%1, %0";
1968     case 4:
1969       return "sethi\t%%hi(%a1), %0";
1970     case 5:
1971       return "#";
1972     case 6:
1973     case 7:
1974       return "ld\t%1, %0";
1975     case 8:
1976     case 9:
1977       return "st\t%r1, %0";
1978     default:
1979       gcc_unreachable ();
1980     }
1981 }
1982   [(set_attr "type" "fga,fga,fpmove,*,*,*,fpload,load,fpstore,store")])
1983
1984 ;; Exactly the same as above, except that all `f' cases are deleted.
1985 ;; This is necessary to prevent reload from ever trying to use a `f' reg
1986 ;; when -mno-fpu.
1987
1988 (define_insn "*movsf_insn_no_fpu"
1989   [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,m")
1990         (match_operand:SF 1 "input_operand"    "rR,Q,S,m,rG"))]
1991   "! TARGET_FPU
1992    && (register_operand (operands[0], SFmode)
1993        || register_or_zero_operand (operands[1], SFmode))"
1994 {
1995   if (GET_CODE (operands[1]) == CONST_DOUBLE
1996       && (which_alternative == 0
1997           || which_alternative == 1
1998           || which_alternative == 2))
1999     {
2000       REAL_VALUE_TYPE r;
2001       long i;
2002
2003       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2004       REAL_VALUE_TO_TARGET_SINGLE (r, i);
2005       operands[1] = GEN_INT (i);
2006     }
2007
2008   switch (which_alternative)
2009     {
2010     case 0:
2011       return "mov\t%1, %0";
2012     case 1:
2013       return "sethi\t%%hi(%a1), %0";
2014     case 2:
2015       return "#";
2016     case 3:
2017       return "ld\t%1, %0";
2018     case 4:
2019       return "st\t%r1, %0";
2020     default:
2021       gcc_unreachable ();
2022     }
2023 }
2024   [(set_attr "type" "*,*,*,load,store")])
2025
2026 ;; The following 3 patterns build SFmode constants in integer registers.
2027
2028 (define_insn "*movsf_lo_sum"
2029   [(set (match_operand:SF 0 "register_operand" "=r")
2030         (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
2031                    (match_operand:SF 2 "fp_const_high_losum_operand" "S")))]
2032   ""
2033 {
2034   REAL_VALUE_TYPE r;
2035   long i;
2036
2037   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
2038   REAL_VALUE_TO_TARGET_SINGLE (r, i);
2039   operands[2] = GEN_INT (i);
2040   return "or\t%1, %%lo(%a2), %0";
2041 })
2042
2043 (define_insn "*movsf_high"
2044   [(set (match_operand:SF 0 "register_operand" "=r")
2045         (high:SF (match_operand:SF 1 "fp_const_high_losum_operand" "S")))]
2046   ""
2047 {
2048   REAL_VALUE_TYPE r;
2049   long i;
2050
2051   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2052   REAL_VALUE_TO_TARGET_SINGLE (r, i);
2053   operands[1] = GEN_INT (i);
2054   return "sethi\t%%hi(%1), %0";
2055 })
2056
2057 (define_split
2058   [(set (match_operand:SF 0 "register_operand" "")
2059         (match_operand:SF 1 "fp_const_high_losum_operand" ""))]
2060   "REG_P (operands[0]) && REGNO (operands[0]) < 32"
2061   [(set (match_dup 0) (high:SF (match_dup 1)))
2062    (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
2063
2064 ;; Yes, you again guessed it right, the former movdf expander.
2065 (define_expand "mov<V64:mode>"
2066   [(set (match_operand:V64 0 "nonimmediate_operand" "")
2067         (match_operand:V64 1 "general_operand" ""))]
2068   "<V64:MODE>mode == DFmode || TARGET_VIS"
2069 {
2070   if (sparc_expand_move (<V64:MODE>mode, operands))
2071     DONE;
2072 })
2073
2074 ;; Be careful, fmovd does not exist when !v9.
2075 (define_insn "*movdf_insn_sp32"
2076   [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o")
2077         (match_operand:DF 1 "input_operand"    "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
2078   "TARGET_FPU
2079    && ! TARGET_V9
2080    && (register_operand (operands[0], DFmode)
2081        || register_or_zero_operand (operands[1], DFmode))"
2082   "@
2083   ldd\t%1, %0
2084   std\t%1, %0
2085   ldd\t%1, %0
2086   std\t%1, %0
2087   #
2088   #
2089   #
2090   #
2091   #
2092   #"
2093  [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
2094   (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
2095
2096 (define_insn "*movdf_insn_sp32_no_fpu"
2097   [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
2098         (match_operand:DF 1 "input_operand"    "T,U,G,ro,r"))]
2099   "! TARGET_FPU
2100    && ! TARGET_V9
2101    && (register_operand (operands[0], DFmode)
2102        || register_or_zero_operand (operands[1], DFmode))"
2103   "@
2104   ldd\t%1, %0
2105   std\t%1, %0
2106   #
2107   #
2108   #"
2109   [(set_attr "type" "load,store,*,*,*")
2110    (set_attr "length" "*,*,2,2,2")])
2111
2112 ;; We have available v9 double floats but not 64-bit integer registers.
2113 (define_insn "*movdf_insn_sp32_v9"
2114   [(set (match_operand:V64 0 "nonimmediate_operand" "=b,b,e,e,T,W,U,T,f,*r,o")
2115         (match_operand:V64 1 "input_operand" "GY,ZC,e,W#F,GY,e,T,U,o#F,*roGYDF,*rGYf"))]
2116   "TARGET_FPU
2117    && TARGET_V9
2118    && ! TARGET_ARCH64
2119    && (register_operand (operands[0], <V64:MODE>mode)
2120        || register_or_zero_or_all_ones_operand (operands[1], <V64:MODE>mode))"
2121   "@
2122   fzero\t%0
2123   fone\t%0
2124   fmovd\t%1, %0
2125   ldd\t%1, %0
2126   stx\t%r1, %0
2127   std\t%1, %0
2128   ldd\t%1, %0
2129   std\t%1, %0
2130   #
2131   #
2132   #"
2133   [(set_attr "type" "fga,fga,fpmove,load,store,store,load,store,*,*,*")
2134    (set_attr "length" "*,*,*,*,*,*,*,*,2,2,2")
2135    (set_attr "fptype" "double,double,double,*,*,*,*,*,*,*,*")])
2136
2137 (define_insn "*movdf_insn_sp32_v9_no_fpu"
2138   [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
2139         (match_operand:DF 1 "input_operand"    "T,U,G,ro,rG"))]
2140   "! TARGET_FPU
2141    && TARGET_V9
2142    && ! TARGET_ARCH64
2143    && (register_operand (operands[0], DFmode)
2144        || register_or_zero_operand (operands[1], DFmode))"
2145   "@
2146   ldd\t%1, %0
2147   std\t%1, %0
2148   stx\t%r1, %0
2149   #
2150   #"
2151   [(set_attr "type" "load,store,store,*,*")
2152    (set_attr "length" "*,*,*,2,2")])
2153
2154 ;; We have available both v9 double floats and 64-bit integer registers.
2155 (define_insn "*movdf_insn_sp64"
2156   [(set (match_operand:V64 0 "nonimmediate_operand" "=b,b,e,e,W,*r,*r,m,*r")
2157         (match_operand:V64 1 "input_operand"    "GY,ZC,e,W#F,e,*rGY,m,*rGY,DF"))]
2158   "TARGET_FPU
2159    && TARGET_ARCH64
2160    && (register_operand (operands[0], <V64:MODE>mode)
2161        || register_or_zero_or_all_ones_operand (operands[1], <V64:MODE>mode))"
2162   "@
2163   fzero\t%0
2164   fone\t%0
2165   fmovd\t%1, %0
2166   ldd\t%1, %0
2167   std\t%1, %0
2168   mov\t%r1, %0
2169   ldx\t%1, %0
2170   stx\t%r1, %0
2171   #"
2172   [(set_attr "type" "fga,fga,fpmove,load,store,*,load,store,*")
2173    (set_attr "length" "*,*,*,*,*,*,*,*,2")
2174    (set_attr "fptype" "double,double,double,*,*,*,*,*,*")])
2175
2176 (define_insn "*movdf_insn_sp64_no_fpu"
2177   [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
2178         (match_operand:DF 1 "input_operand"    "r,m,rG"))]
2179   "! TARGET_FPU
2180    && TARGET_ARCH64
2181    && (register_operand (operands[0], DFmode)
2182        || register_or_zero_operand (operands[1], DFmode))"
2183   "@
2184   mov\t%1, %0
2185   ldx\t%1, %0
2186   stx\t%r1, %0"
2187   [(set_attr "type" "*,load,store")])
2188
2189 ;; This pattern builds V64mode constants in integer registers.
2190 (define_split
2191   [(set (match_operand:V64 0 "register_operand" "")
2192         (match_operand:V64 1 "const_double_or_vector_operand" ""))]
2193   "TARGET_FPU
2194    && (GET_CODE (operands[0]) == REG
2195        && REGNO (operands[0]) < 32)
2196    && ! const_zero_operand (operands[1], GET_MODE (operands[0]))
2197    && reload_completed"
2198   [(clobber (const_int 0))]
2199 {
2200   operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
2201
2202   if (TARGET_ARCH64)
2203     {
2204 #if HOST_BITS_PER_WIDE_INT == 32
2205       gcc_unreachable ();
2206 #else
2207       enum machine_mode mode = GET_MODE (operands[1]);
2208       rtx tem = simplify_subreg (DImode, operands[1], mode, 0);
2209       emit_insn (gen_movdi (operands[0], tem));
2210 #endif
2211     }
2212   else
2213     {
2214       enum machine_mode mode = GET_MODE (operands[1]);
2215       rtx hi = simplify_subreg (SImode, operands[1], mode, 0);
2216       rtx lo = simplify_subreg (SImode, operands[1], mode, 4);
2217
2218       gcc_assert (GET_CODE (hi) == CONST_INT);
2219       gcc_assert (GET_CODE (lo) == CONST_INT);
2220
2221       emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), hi));
2222
2223       /* Slick... but this trick loses if this subreg constant part
2224          can be done in one insn.  */
2225       if (lo == hi
2226           && ! SPARC_SETHI32_P (INTVAL (hi))
2227           && ! SPARC_SIMM13_P (INTVAL (hi)))
2228         {
2229           emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2230                                 gen_highpart (SImode, operands[0])));
2231         }
2232       else
2233         {
2234           emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), lo));
2235         }
2236     }
2237   DONE;
2238 })
2239
2240 ;; Ok, now the splits to handle all the multi insn and
2241 ;; mis-aligned memory address cases.
2242 ;; In these splits please take note that we must be
2243 ;; careful when V9 but not ARCH64 because the integer
2244 ;; register DFmode cases must be handled.
2245 (define_split
2246   [(set (match_operand:V64 0 "register_operand" "")
2247         (match_operand:V64 1 "register_operand" ""))]
2248   "(! TARGET_V9
2249     || (! TARGET_ARCH64
2250         && ((GET_CODE (operands[0]) == REG
2251              && REGNO (operands[0]) < 32)
2252             || (GET_CODE (operands[0]) == SUBREG
2253                 && GET_CODE (SUBREG_REG (operands[0])) == REG
2254                 && REGNO (SUBREG_REG (operands[0])) < 32))))
2255    && reload_completed"
2256   [(clobber (const_int 0))]
2257 {
2258   rtx set_dest = operands[0];
2259   rtx set_src = operands[1];
2260   rtx dest1, dest2;
2261   rtx src1, src2;
2262   enum machine_mode half_mode;
2263
2264   /* We can be expanded for DFmode or integral vector modes.  */
2265   if (<V64:MODE>mode == DFmode)
2266     half_mode = SFmode;
2267   else
2268     half_mode = SImode;
2269   
2270   dest1 = gen_highpart (half_mode, set_dest);
2271   dest2 = gen_lowpart (half_mode, set_dest);
2272   src1 = gen_highpart (half_mode, set_src);
2273   src2 = gen_lowpart (half_mode, set_src);
2274
2275   /* Now emit using the real source and destination we found, swapping
2276      the order if we detect overlap.  */
2277   if (reg_overlap_mentioned_p (dest1, src2))
2278     {
2279       emit_move_insn_1 (dest2, src2);
2280       emit_move_insn_1 (dest1, src1);
2281     }
2282   else
2283     {
2284       emit_move_insn_1 (dest1, src1);
2285       emit_move_insn_1 (dest2, src2);
2286     }
2287   DONE;
2288 })
2289
2290 (define_split
2291   [(set (match_operand:V64 0 "register_operand" "")
2292         (match_operand:V64 1 "memory_operand" ""))]
2293   "reload_completed
2294    && ! TARGET_ARCH64
2295    && (((REGNO (operands[0]) % 2) != 0)
2296        || ! mem_min_alignment (operands[1], 8))
2297    && offsettable_memref_p (operands[1])"
2298   [(clobber (const_int 0))]
2299 {
2300   enum machine_mode half_mode;
2301   rtx word0, word1;
2302
2303   /* We can be expanded for DFmode or integral vector modes.  */
2304   if (<V64:MODE>mode == DFmode)
2305     half_mode = SFmode;
2306   else
2307     half_mode = SImode;
2308
2309   word0 = adjust_address (operands[1], half_mode, 0);
2310   word1 = adjust_address (operands[1], half_mode, 4);
2311
2312   if (reg_overlap_mentioned_p (gen_highpart (half_mode, operands[0]), word1))
2313     {
2314       emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2315       emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2316     }
2317   else
2318     {
2319       emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2320       emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2321     }
2322   DONE;
2323 })
2324
2325 (define_split
2326   [(set (match_operand:V64 0 "memory_operand" "")
2327         (match_operand:V64 1 "register_operand" ""))]
2328   "reload_completed
2329    && ! TARGET_ARCH64
2330    && (((REGNO (operands[1]) % 2) != 0)
2331        || ! mem_min_alignment (operands[0], 8))
2332    && offsettable_memref_p (operands[0])"
2333   [(clobber (const_int 0))]
2334 {
2335   enum machine_mode half_mode;
2336   rtx word0, word1;
2337
2338   /* We can be expanded for DFmode or integral vector modes.  */
2339   if (<V64:MODE>mode == DFmode)
2340     half_mode = SFmode;
2341   else
2342     half_mode = SImode;
2343
2344   word0 = adjust_address (operands[0], half_mode, 0);
2345   word1 = adjust_address (operands[0], half_mode, 4);
2346
2347   emit_move_insn_1 (word0, gen_highpart (half_mode, operands[1]));
2348   emit_move_insn_1 (word1, gen_lowpart (half_mode, operands[1]));
2349   DONE;
2350 })
2351
2352 (define_split
2353   [(set (match_operand:V64 0 "memory_operand" "")
2354         (match_operand:V64 1 "const_zero_operand" ""))]
2355   "reload_completed
2356    && (! TARGET_V9
2357        || (! TARGET_ARCH64
2358            && ! mem_min_alignment (operands[0], 8)))
2359    && offsettable_memref_p (operands[0])"
2360   [(clobber (const_int 0))]
2361 {
2362   enum machine_mode half_mode;
2363   rtx dest1, dest2;
2364
2365   /* We can be expanded for DFmode or integral vector modes.  */
2366   if (<V64:MODE>mode == DFmode)
2367     half_mode = SFmode;
2368   else
2369     half_mode = SImode;
2370
2371   dest1 = adjust_address (operands[0], half_mode, 0);
2372   dest2 = adjust_address (operands[0], half_mode, 4);
2373
2374   emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2375   emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2376   DONE;
2377 })
2378
2379 (define_split
2380   [(set (match_operand:V64 0 "register_operand" "")
2381         (match_operand:V64 1 "const_zero_operand" ""))]
2382   "reload_completed
2383    && ! TARGET_ARCH64
2384    && ((GET_CODE (operands[0]) == REG
2385         && REGNO (operands[0]) < 32)
2386        || (GET_CODE (operands[0]) == SUBREG
2387            && GET_CODE (SUBREG_REG (operands[0])) == REG
2388            && REGNO (SUBREG_REG (operands[0])) < 32))"
2389   [(clobber (const_int 0))]
2390 {
2391   enum machine_mode half_mode;
2392   rtx set_dest = operands[0];
2393   rtx dest1, dest2;
2394
2395   /* We can be expanded for DFmode or integral vector modes.  */
2396   if (<V64:MODE>mode == DFmode)
2397     half_mode = SFmode;
2398   else
2399     half_mode = SImode;
2400
2401   dest1 = gen_highpart (half_mode, set_dest);
2402   dest2 = gen_lowpart (half_mode, set_dest);
2403   emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2404   emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2405   DONE;
2406 })
2407
2408 (define_expand "movtf"
2409   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2410         (match_operand:TF 1 "general_operand" ""))]
2411   ""
2412 {
2413   if (sparc_expand_move (TFmode, operands))
2414     DONE;
2415 })
2416
2417 (define_insn "*movtf_insn_sp32"
2418   [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,U,r")
2419         (match_operand:TF 1 "input_operand"    "G,oe,GeUr,o,roG"))]
2420   "TARGET_FPU
2421    && ! TARGET_ARCH64
2422    && (register_operand (operands[0], TFmode)
2423        || register_or_zero_operand (operands[1], TFmode))"
2424   "#"
2425   [(set_attr "length" "4")])
2426
2427 ;; Exactly the same as above, except that all `e' cases are deleted.
2428 ;; This is necessary to prevent reload from ever trying to use a `e' reg
2429 ;; when -mno-fpu.
2430
2431 (define_insn "*movtf_insn_sp32_no_fpu"
2432   [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
2433         (match_operand:TF 1 "input_operand"    "G,o,U,roG,r"))]
2434   "! TARGET_FPU
2435    && ! TARGET_ARCH64
2436    && (register_operand (operands[0], TFmode)
2437        || register_or_zero_operand (operands[1], TFmode))"
2438   "#"
2439   [(set_attr "length" "4")])
2440
2441 (define_insn "*movtf_insn_sp64"
2442   [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,r")
2443         (match_operand:TF 1 "input_operand"    "G,oe,Ger,roG"))]
2444   "TARGET_FPU
2445    && TARGET_ARCH64
2446    && ! TARGET_HARD_QUAD
2447    && (register_operand (operands[0], TFmode)
2448        || register_or_zero_operand (operands[1], TFmode))"
2449   "#"
2450   [(set_attr "length" "2")])
2451
2452 (define_insn "*movtf_insn_sp64_hq"
2453   [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,e,m,o,r")
2454         (match_operand:TF 1 "input_operand"    "G,e,m,e,rG,roG"))]
2455   "TARGET_FPU
2456    && TARGET_ARCH64
2457    && TARGET_HARD_QUAD
2458    && (register_operand (operands[0], TFmode)
2459        || register_or_zero_operand (operands[1], TFmode))"
2460   "@
2461   #
2462   fmovq\t%1, %0
2463   ldq\t%1, %0
2464   stq\t%1, %0
2465   #
2466   #"
2467   [(set_attr "type" "*,fpmove,fpload,fpstore,*,*")
2468    (set_attr "length" "2,*,*,*,2,2")])
2469
2470 (define_insn "*movtf_insn_sp64_no_fpu"
2471   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
2472         (match_operand:TF 1 "input_operand"    "orG,rG"))]
2473   "! TARGET_FPU
2474    && TARGET_ARCH64
2475    && (register_operand (operands[0], TFmode)
2476        || register_or_zero_operand (operands[1], TFmode))"
2477   "#"
2478   [(set_attr "length" "2")])
2479
2480 ;; Now all the splits to handle multi-insn TF mode moves.
2481 (define_split
2482   [(set (match_operand:TF 0 "register_operand" "")
2483         (match_operand:TF 1 "register_operand" ""))]
2484   "reload_completed
2485    && (! TARGET_ARCH64
2486        || (TARGET_FPU
2487            && ! TARGET_HARD_QUAD)
2488        || ! fp_register_operand (operands[0], TFmode))"
2489   [(clobber (const_int 0))]
2490 {
2491   rtx set_dest = operands[0];
2492   rtx set_src = operands[1];
2493   rtx dest1, dest2;
2494   rtx src1, src2;
2495
2496   dest1 = gen_df_reg (set_dest, 0);
2497   dest2 = gen_df_reg (set_dest, 1);
2498   src1 = gen_df_reg (set_src, 0);
2499   src2 = gen_df_reg (set_src, 1);
2500
2501   /* Now emit using the real source and destination we found, swapping
2502      the order if we detect overlap.  */
2503   if (reg_overlap_mentioned_p (dest1, src2))
2504     {
2505       emit_insn (gen_movdf (dest2, src2));
2506       emit_insn (gen_movdf (dest1, src1));
2507     }
2508   else
2509     {
2510       emit_insn (gen_movdf (dest1, src1));
2511       emit_insn (gen_movdf (dest2, src2));
2512     }
2513   DONE;
2514 })
2515
2516 (define_split
2517   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2518         (match_operand:TF 1 "const_zero_operand" ""))]
2519   "reload_completed"
2520   [(clobber (const_int 0))]
2521 {
2522   rtx set_dest = operands[0];
2523   rtx dest1, dest2;
2524
2525   switch (GET_CODE (set_dest))
2526     {
2527     case REG:
2528       dest1 = gen_df_reg (set_dest, 0);
2529       dest2 = gen_df_reg (set_dest, 1);
2530       break;
2531     case MEM:
2532       dest1 = adjust_address (set_dest, DFmode, 0);
2533       dest2 = adjust_address (set_dest, DFmode, 8);
2534       break;
2535     default:
2536       gcc_unreachable ();      
2537     }
2538
2539   emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
2540   emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
2541   DONE;
2542 })
2543
2544 (define_split
2545   [(set (match_operand:TF 0 "register_operand" "")
2546         (match_operand:TF 1 "memory_operand" ""))]
2547   "(reload_completed
2548     && offsettable_memref_p (operands[1])
2549     && (! TARGET_ARCH64
2550         || ! TARGET_HARD_QUAD
2551         || ! fp_register_operand (operands[0], TFmode)))"
2552   [(clobber (const_int 0))]
2553 {
2554   rtx word0 = adjust_address (operands[1], DFmode, 0);
2555   rtx word1 = adjust_address (operands[1], DFmode, 8);
2556   rtx set_dest, dest1, dest2;
2557
2558   set_dest = operands[0];
2559
2560   dest1 = gen_df_reg (set_dest, 0);
2561   dest2 = gen_df_reg (set_dest, 1);
2562
2563   /* Now output, ordering such that we don't clobber any registers
2564      mentioned in the address.  */
2565   if (reg_overlap_mentioned_p (dest1, word1))
2566
2567     {
2568       emit_insn (gen_movdf (dest2, word1));
2569       emit_insn (gen_movdf (dest1, word0));
2570     }
2571   else
2572    {
2573       emit_insn (gen_movdf (dest1, word0));
2574       emit_insn (gen_movdf (dest2, word1));
2575    }
2576   DONE;
2577 })
2578
2579 (define_split
2580   [(set (match_operand:TF 0 "memory_operand" "")
2581         (match_operand:TF 1 "register_operand" ""))]
2582   "(reload_completed
2583     && offsettable_memref_p (operands[0])
2584     && (! TARGET_ARCH64
2585         || ! TARGET_HARD_QUAD
2586         || ! fp_register_operand (operands[1], TFmode)))"
2587   [(clobber (const_int 0))]
2588 {
2589   rtx set_src = operands[1];
2590
2591   emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
2592                         gen_df_reg (set_src, 0)));
2593   emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
2594                         gen_df_reg (set_src, 1)));
2595   DONE;
2596 })
2597
2598
2599 ;; SPARC-V9 conditional move instructions
2600
2601 ;; We can handle larger constants here for some flavors, but for now we keep
2602 ;; it simple and only allow those constants supported by all flavors.
2603 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
2604 ;; 3 contains the constant if one is present, but we handle either for
2605 ;; generality (sparc.c puts a constant in operand 2).
2606
2607 (define_expand "mov<I:mode>cc"
2608   [(set (match_operand:I 0 "register_operand" "")
2609         (if_then_else:I (match_operand 1 "comparison_operator" "")
2610                         (match_operand:I 2 "arith10_operand" "")
2611                         (match_operand:I 3 "arith10_operand" "")))]
2612   "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2613 {
2614   enum rtx_code code = GET_CODE (operands[1]);
2615   rtx cc_reg;
2616
2617   if (GET_MODE (XEXP (operands[1], 0)) == DImode
2618       && ! TARGET_ARCH64)
2619     FAIL;
2620
2621   if (GET_MODE (XEXP (operands[1], 0)) == TFmode && !TARGET_HARD_QUAD)
2622     operands[1]
2623       = sparc_emit_float_lib_cmp (XEXP (operands[1], 0), XEXP (operands[1], 1),
2624                                   GET_CODE (operands[1]));
2625
2626   if (XEXP (operands[1], 1) == const0_rtx
2627       && GET_CODE (XEXP (operands[1], 0)) == REG
2628       && GET_MODE (XEXP (operands[1], 0)) == DImode
2629       && v9_regcmp_p (code))
2630     cc_reg = XEXP (operands[1], 0);
2631   else
2632     cc_reg = gen_compare_reg (operands[1]);
2633
2634   operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
2635 })
2636
2637 (define_expand "mov<F:mode>cc"
2638   [(set (match_operand:F 0 "register_operand" "")
2639         (if_then_else:F (match_operand 1 "comparison_operator" "")
2640                         (match_operand:F 2 "register_operand" "")
2641                         (match_operand:F 3 "register_operand" "")))]
2642   "TARGET_V9 && TARGET_FPU"
2643 {
2644   enum rtx_code code = GET_CODE (operands[1]);
2645   rtx cc_reg;
2646
2647   if (GET_MODE (XEXP (operands[1], 0)) == DImode
2648       && ! TARGET_ARCH64)
2649     FAIL;
2650
2651   if (GET_MODE (XEXP (operands[1], 0)) == TFmode && !TARGET_HARD_QUAD)
2652     operands[1]
2653       = sparc_emit_float_lib_cmp (XEXP (operands[1], 0), XEXP (operands[1], 1),
2654                                   GET_CODE (operands[1]));
2655
2656   if (XEXP (operands[1], 1) == const0_rtx
2657       && GET_CODE (XEXP (operands[1], 0)) == REG
2658       && GET_MODE (XEXP (operands[1], 0)) == DImode
2659       && v9_regcmp_p (code))
2660     cc_reg = XEXP (operands[1], 0);
2661   else
2662     cc_reg = gen_compare_reg (operands[1]);
2663
2664   operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
2665 })
2666
2667 ;; Conditional move define_insns
2668
2669 (define_insn "*mov<I:mode>_cc_v9"
2670   [(set (match_operand:I 0 "register_operand" "=r,r")
2671         (if_then_else:I (match_operator 1 "comparison_operator"
2672                                [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2673                                 (const_int 0)])
2674                         (match_operand:I 3 "arith11_operand" "rL,0")
2675                         (match_operand:I 4 "arith11_operand" "0,rL")))]
2676   "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2677   "@
2678    mov%C1\t%x2, %3, %0
2679    mov%c1\t%x2, %4, %0"
2680   [(set_attr "type" "cmove")])
2681
2682 (define_insn "*mov<I:mode>_cc_reg_sp64"
2683   [(set (match_operand:I 0 "register_operand" "=r,r")
2684         (if_then_else:I (match_operator 1 "v9_register_compare_operator"
2685                                 [(match_operand:DI 2 "register_operand" "r,r")
2686                                  (const_int 0)])
2687                         (match_operand:I 3 "arith10_operand" "rM,0")
2688                         (match_operand:I 4 "arith10_operand" "0,rM")))]
2689   "TARGET_ARCH64"
2690   "@
2691    movr%D1\t%2, %r3, %0
2692    movr%d1\t%2, %r4, %0"
2693   [(set_attr "type" "cmove")])
2694
2695 (define_insn "*movsf_cc_v9"
2696   [(set (match_operand:SF 0 "register_operand" "=f,f")
2697         (if_then_else:SF (match_operator 1 "comparison_operator"
2698                                 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2699                                  (const_int 0)])
2700                          (match_operand:SF 3 "register_operand" "f,0")
2701                          (match_operand:SF 4 "register_operand" "0,f")))]
2702   "TARGET_V9 && TARGET_FPU"
2703   "@
2704    fmovs%C1\t%x2, %3, %0
2705    fmovs%c1\t%x2, %4, %0"
2706   [(set_attr "type" "fpcmove")])
2707
2708 (define_insn "*movsf_cc_reg_sp64"
2709   [(set (match_operand:SF 0 "register_operand" "=f,f")
2710         (if_then_else:SF (match_operator 1 "v9_register_compare_operator"
2711                                 [(match_operand:DI 2 "register_operand" "r,r")
2712                                  (const_int 0)])
2713                          (match_operand:SF 3 "register_operand" "f,0")
2714                          (match_operand:SF 4 "register_operand" "0,f")))]
2715   "TARGET_ARCH64 && TARGET_FPU"
2716   "@
2717    fmovrs%D1\t%2, %3, %0
2718    fmovrs%d1\t%2, %4, %0"
2719   [(set_attr "type" "fpcrmove")])
2720
2721 ;; Named because invoked by movtf_cc_v9
2722 (define_insn "movdf_cc_v9"
2723   [(set (match_operand:DF 0 "register_operand" "=e,e")
2724         (if_then_else:DF (match_operator 1 "comparison_operator"
2725                                 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2726                                  (const_int 0)])
2727                          (match_operand:DF 3 "register_operand" "e,0")
2728                          (match_operand:DF 4 "register_operand" "0,e")))]
2729   "TARGET_V9 && TARGET_FPU"
2730   "@
2731    fmovd%C1\t%x2, %3, %0
2732    fmovd%c1\t%x2, %4, %0"
2733   [(set_attr "type" "fpcmove")
2734    (set_attr "fptype" "double")])
2735
2736 ;; Named because invoked by movtf_cc_reg_sp64
2737 (define_insn "movdf_cc_reg_sp64"
2738   [(set (match_operand:DF 0 "register_operand" "=e,e")
2739         (if_then_else:DF (match_operator 1 "v9_register_compare_operator"
2740                                 [(match_operand:DI 2 "register_operand" "r,r")
2741                                  (const_int 0)])
2742                          (match_operand:DF 3 "register_operand" "e,0")
2743                          (match_operand:DF 4 "register_operand" "0,e")))]
2744   "TARGET_ARCH64 && TARGET_FPU"
2745   "@
2746    fmovrd%D1\t%2, %3, %0
2747    fmovrd%d1\t%2, %4, %0"
2748   [(set_attr "type" "fpcrmove")
2749    (set_attr "fptype" "double")])
2750
2751 (define_insn "*movtf_cc_hq_v9"
2752   [(set (match_operand:TF 0 "register_operand" "=e,e")
2753         (if_then_else:TF (match_operator 1 "comparison_operator"
2754                                 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2755                                  (const_int 0)])
2756                          (match_operand:TF 3 "register_operand" "e,0")
2757                          (match_operand:TF 4 "register_operand" "0,e")))]
2758   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
2759   "@
2760    fmovq%C1\t%x2, %3, %0
2761    fmovq%c1\t%x2, %4, %0"
2762   [(set_attr "type" "fpcmove")])
2763
2764 (define_insn "*movtf_cc_reg_hq_sp64"
2765   [(set (match_operand:TF 0 "register_operand" "=e,e")
2766         (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2767                                 [(match_operand:DI 2 "register_operand" "r,r")
2768                                  (const_int 0)])
2769                          (match_operand:TF 3 "register_operand" "e,0")
2770                          (match_operand:TF 4 "register_operand" "0,e")))]
2771   "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
2772   "@
2773    fmovrq%D1\t%2, %3, %0
2774    fmovrq%d1\t%2, %4, %0"
2775   [(set_attr "type" "fpcrmove")])
2776
2777 (define_insn_and_split "*movtf_cc_v9"
2778   [(set (match_operand:TF 0 "register_operand" "=e,e")
2779         (if_then_else:TF (match_operator 1 "comparison_operator"
2780                             [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2781                              (const_int 0)])
2782                          (match_operand:TF 3 "register_operand" "e,0")
2783                          (match_operand:TF 4 "register_operand" "0,e")))]
2784   "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
2785   "#"
2786   "&& reload_completed"
2787   [(clobber (const_int 0))]
2788 {
2789   rtx set_dest = operands[0];
2790   rtx set_srca = operands[3];
2791   rtx set_srcb = operands[4];
2792   int third = rtx_equal_p (set_dest, set_srca);
2793   rtx dest1, dest2;
2794   rtx srca1, srca2, srcb1, srcb2;
2795
2796   dest1 = gen_df_reg (set_dest, 0);
2797   dest2 = gen_df_reg (set_dest, 1);
2798   srca1 = gen_df_reg (set_srca, 0);
2799   srca2 = gen_df_reg (set_srca, 1);
2800   srcb1 = gen_df_reg (set_srcb, 0);
2801   srcb2 = gen_df_reg (set_srcb, 1);
2802
2803   /* Now emit using the real source and destination we found, swapping
2804      the order if we detect overlap.  */
2805   if ((third && reg_overlap_mentioned_p (dest1, srcb2))
2806       || (!third && reg_overlap_mentioned_p (dest1, srca2)))
2807     {
2808       emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, srcb2));
2809       emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, srcb1));
2810     }
2811   else
2812     {
2813       emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, srcb1));
2814       emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, srcb2));
2815     }
2816   DONE;
2817 }
2818   [(set_attr "length" "2")])
2819
2820 (define_insn_and_split "*movtf_cc_reg_sp64"
2821   [(set (match_operand:TF 0 "register_operand" "=e,e")
2822         (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2823                                 [(match_operand:DI 2 "register_operand" "r,r")
2824                                  (const_int 0)])
2825                          (match_operand:TF 3 "register_operand" "e,0")
2826                          (match_operand:TF 4 "register_operand" "0,e")))]
2827   "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
2828   "#"
2829   "&& reload_completed"
2830   [(clobber (const_int 0))]
2831 {
2832   rtx set_dest = operands[0];
2833   rtx set_srca = operands[3];
2834   rtx set_srcb = operands[4];
2835   int third = rtx_equal_p (set_dest, set_srca);
2836   rtx dest1, dest2;
2837   rtx srca1, srca2, srcb1, srcb2;
2838
2839   dest1 = gen_df_reg (set_dest, 0);
2840   dest2 = gen_df_reg (set_dest, 1);
2841   srca1 = gen_df_reg (set_srca, 0);
2842   srca2 = gen_df_reg (set_srca, 1);
2843   srcb1 = gen_df_reg (set_srcb, 0);
2844   srcb2 = gen_df_reg (set_srcb, 1);
2845
2846   /* Now emit using the real source and destination we found, swapping
2847      the order if we detect overlap.  */
2848   if ((third && reg_overlap_mentioned_p (dest1, srcb2))
2849       || (!third && reg_overlap_mentioned_p (dest1, srca2)))
2850     {
2851       emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
2852       emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
2853     }
2854   else
2855     {
2856       emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
2857       emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
2858     }
2859   DONE;
2860 }
2861   [(set_attr "length" "2")])
2862
2863 \f
2864 ;; Zero-extension instructions
2865
2866 ;; These patterns originally accepted general_operands, however, slightly
2867 ;; better code is generated by only accepting register_operands, and then
2868 ;; letting combine generate the ldu[hb] insns.
2869
2870 (define_expand "zero_extendhisi2"
2871   [(set (match_operand:SI 0 "register_operand" "")
2872         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
2873   ""
2874 {
2875   rtx temp = gen_reg_rtx (SImode);
2876   rtx shift_16 = GEN_INT (16);
2877   int op1_subbyte = 0;
2878
2879   if (GET_CODE (operand1) == SUBREG)
2880     {
2881       op1_subbyte = SUBREG_BYTE (operand1);
2882       op1_subbyte /= GET_MODE_SIZE (SImode);
2883       op1_subbyte *= GET_MODE_SIZE (SImode);
2884       operand1 = XEXP (operand1, 0);
2885     }
2886
2887   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
2888                           shift_16));
2889   emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
2890   DONE;
2891 })
2892
2893 (define_insn "*zero_extendhisi2_insn"
2894   [(set (match_operand:SI 0 "register_operand" "=r")
2895         (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2896   ""
2897   "lduh\t%1, %0"
2898   [(set_attr "type" "load")
2899    (set_attr "us3load_type" "3cycle")])
2900
2901 (define_expand "zero_extendqihi2"
2902   [(set (match_operand:HI 0 "register_operand" "")
2903         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
2904   ""
2905   "")
2906
2907 (define_insn "*zero_extendqihi2_insn"
2908   [(set (match_operand:HI 0 "register_operand" "=r,r")
2909         (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
2910   "GET_CODE (operands[1]) != CONST_INT"
2911   "@
2912    and\t%1, 0xff, %0
2913    ldub\t%1, %0"
2914   [(set_attr "type" "*,load")
2915    (set_attr "us3load_type" "*,3cycle")])
2916
2917 (define_expand "zero_extendqisi2"
2918   [(set (match_operand:SI 0 "register_operand" "")
2919         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
2920   ""
2921   "")
2922
2923 (define_insn "*zero_extendqisi2_insn"
2924   [(set (match_operand:SI 0 "register_operand" "=r,r")
2925         (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
2926   "GET_CODE (operands[1]) != CONST_INT"
2927   "@
2928    and\t%1, 0xff, %0
2929    ldub\t%1, %0"
2930   [(set_attr "type" "*,load")
2931    (set_attr "us3load_type" "*,3cycle")])
2932
2933 (define_expand "zero_extendqidi2"
2934   [(set (match_operand:DI 0 "register_operand" "")
2935         (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
2936   "TARGET_ARCH64"
2937   "")
2938
2939 (define_insn "*zero_extendqidi2_insn"
2940   [(set (match_operand:DI 0 "register_operand" "=r,r")
2941         (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
2942   "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
2943   "@
2944    and\t%1, 0xff, %0
2945    ldub\t%1, %0"
2946   [(set_attr "type" "*,load")
2947    (set_attr "us3load_type" "*,3cycle")])
2948
2949 (define_expand "zero_extendhidi2"
2950   [(set (match_operand:DI 0 "register_operand" "")
2951         (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
2952   "TARGET_ARCH64"
2953 {
2954   rtx temp = gen_reg_rtx (DImode);
2955   rtx shift_48 = GEN_INT (48);
2956   int op1_subbyte = 0;
2957
2958   if (GET_CODE (operand1) == SUBREG)
2959     {
2960       op1_subbyte = SUBREG_BYTE (operand1);
2961       op1_subbyte /= GET_MODE_SIZE (DImode);
2962       op1_subbyte *= GET_MODE_SIZE (DImode);
2963       operand1 = XEXP (operand1, 0);
2964     }
2965
2966   emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
2967                           shift_48));
2968   emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
2969   DONE;
2970 })
2971
2972 (define_insn "*zero_extendhidi2_insn"
2973   [(set (match_operand:DI 0 "register_operand" "=r")
2974         (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
2975   "TARGET_ARCH64"
2976   "lduh\t%1, %0"
2977   [(set_attr "type" "load")
2978    (set_attr "us3load_type" "3cycle")])
2979
2980 ;; ??? Write truncdisi pattern using sra?
2981
2982 (define_expand "zero_extendsidi2"
2983   [(set (match_operand:DI 0 "register_operand" "")
2984         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
2985   ""
2986   "")
2987
2988 (define_insn "*zero_extendsidi2_insn_sp64"
2989   [(set (match_operand:DI 0 "register_operand" "=r,r")
2990         (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
2991   "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
2992   "@
2993    srl\t%1, 0, %0
2994    lduw\t%1, %0"
2995   [(set_attr "type" "shift,load")])
2996
2997 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
2998   [(set (match_operand:DI 0 "register_operand" "=r")
2999         (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
3000   "! TARGET_ARCH64"
3001   "#"
3002   "&& reload_completed"
3003   [(set (match_dup 2) (match_dup 3))
3004    (set (match_dup 4) (match_dup 5))]
3005 {
3006   rtx dest1, dest2;
3007
3008   dest1 = gen_highpart (SImode, operands[0]);
3009   dest2 = gen_lowpart (SImode, operands[0]);
3010
3011   /* Swap the order in case of overlap.  */
3012   if (REGNO (dest1) == REGNO (operands[1]))
3013     {
3014       operands[2] = dest2;
3015       operands[3] = operands[1];
3016       operands[4] = dest1;
3017       operands[5] = const0_rtx;
3018     }
3019   else
3020     {
3021       operands[2] = dest1;
3022       operands[3] = const0_rtx;
3023       operands[4] = dest2;
3024       operands[5] = operands[1];
3025     }
3026 }
3027   [(set_attr "length" "2")])
3028
3029 ;; Simplify comparisons of extended values.
3030
3031 (define_insn "*cmp_zero_extendqisi2"
3032   [(set (reg:CC CC_REG)
3033         (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
3034                     (const_int 0)))]
3035   ""
3036   "andcc\t%0, 0xff, %%g0"
3037   [(set_attr "type" "compare")])
3038
3039 (define_insn "*cmp_zero_qi"
3040   [(set (reg:CC CC_REG)
3041         (compare:CC (match_operand:QI 0 "register_operand" "r")
3042                     (const_int 0)))]
3043   ""
3044   "andcc\t%0, 0xff, %%g0"
3045   [(set_attr "type" "compare")])
3046
3047 (define_insn "*cmp_zero_extendqisi2_set"
3048   [(set (reg:CC CC_REG)
3049         (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
3050                     (const_int 0)))
3051    (set (match_operand:SI 0 "register_operand" "=r")
3052         (zero_extend:SI (match_dup 1)))]
3053   ""
3054   "andcc\t%1, 0xff, %0"
3055   [(set_attr "type" "compare")])
3056
3057 (define_insn "*cmp_zero_extendqisi2_andcc_set"
3058   [(set (reg:CC CC_REG)
3059         (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
3060                             (const_int 255))
3061                     (const_int 0)))
3062    (set (match_operand:SI 0 "register_operand" "=r")
3063         (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
3064   ""
3065   "andcc\t%1, 0xff, %0"
3066   [(set_attr "type" "compare")])
3067
3068 (define_insn "*cmp_zero_extendqidi2"
3069   [(set (reg:CCX CC_REG)
3070         (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
3071                      (const_int 0)))]
3072   "TARGET_ARCH64"
3073   "andcc\t%0, 0xff, %%g0"
3074   [(set_attr "type" "compare")])
3075
3076 (define_insn "*cmp_zero_qi_sp64"
3077   [(set (reg:CCX CC_REG)
3078         (compare:CCX (match_operand:QI 0 "register_operand" "r")
3079                      (const_int 0)))]
3080   "TARGET_ARCH64"
3081   "andcc\t%0, 0xff, %%g0"
3082   [(set_attr "type" "compare")])
3083
3084 (define_insn "*cmp_zero_extendqidi2_set"
3085   [(set (reg:CCX CC_REG)
3086         (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
3087                      (const_int 0)))
3088    (set (match_operand:DI 0 "register_operand" "=r")
3089         (zero_extend:DI (match_dup 1)))]
3090   "TARGET_ARCH64"
3091   "andcc\t%1, 0xff, %0"
3092   [(set_attr "type" "compare")])
3093
3094 (define_insn "*cmp_zero_extendqidi2_andcc_set"
3095   [(set (reg:CCX CC_REG)
3096         (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
3097                              (const_int 255))
3098                      (const_int 0)))
3099    (set (match_operand:DI 0 "register_operand" "=r")
3100         (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
3101   "TARGET_ARCH64"
3102   "andcc\t%1, 0xff, %0"
3103   [(set_attr "type" "compare")])
3104
3105 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
3106
3107 (define_insn "*cmp_siqi_trunc"
3108   [(set (reg:CC CC_REG)
3109         (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
3110                     (const_int 0)))]
3111   ""
3112   "andcc\t%0, 0xff, %%g0"
3113   [(set_attr "type" "compare")])
3114
3115 (define_insn "*cmp_siqi_trunc_set"
3116   [(set (reg:CC CC_REG)
3117         (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
3118                     (const_int 0)))
3119    (set (match_operand:QI 0 "register_operand" "=r")
3120         (subreg:QI (match_dup 1) 3))]
3121   ""
3122   "andcc\t%1, 0xff, %0"
3123   [(set_attr "type" "compare")])
3124
3125 (define_insn "*cmp_diqi_trunc"
3126   [(set (reg:CC CC_REG)
3127         (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
3128                     (const_int 0)))]
3129   "TARGET_ARCH64"
3130   "andcc\t%0, 0xff, %%g0"
3131   [(set_attr "type" "compare")])
3132
3133 (define_insn "*cmp_diqi_trunc_set"
3134   [(set (reg:CC CC_REG)
3135         (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
3136                     (const_int 0)))
3137    (set (match_operand:QI 0 "register_operand" "=r")
3138         (subreg:QI (match_dup 1) 7))]
3139   "TARGET_ARCH64"
3140   "andcc\t%1, 0xff, %0"
3141   [(set_attr "type" "compare")])
3142 \f
3143
3144 ;; Sign-extension instructions
3145
3146 ;; These patterns originally accepted general_operands, however, slightly
3147 ;; better code is generated by only accepting register_operands, and then
3148 ;; letting combine generate the lds[hb] insns.
3149
3150 (define_expand "extendhisi2"
3151   [(set (match_operand:SI 0 "register_operand" "")
3152         (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
3153   ""
3154 {
3155   rtx temp = gen_reg_rtx (SImode);
3156   rtx shift_16 = GEN_INT (16);
3157   int op1_subbyte = 0;
3158
3159   if (GET_CODE (operand1) == SUBREG)
3160     {
3161       op1_subbyte = SUBREG_BYTE (operand1);
3162       op1_subbyte /= GET_MODE_SIZE (SImode);
3163       op1_subbyte *= GET_MODE_SIZE (SImode);
3164       operand1 = XEXP (operand1, 0);
3165     }
3166
3167   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3168                           shift_16));
3169   emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
3170   DONE;
3171 })
3172
3173 (define_insn "*sign_extendhisi2_insn"
3174   [(set (match_operand:SI 0 "register_operand" "=r")
3175         (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3176   ""
3177   "ldsh\t%1, %0"
3178   [(set_attr "type" "sload")
3179    (set_attr "us3load_type" "3cycle")])
3180
3181 (define_expand "extendqihi2"
3182   [(set (match_operand:HI 0 "register_operand" "")
3183         (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
3184   ""
3185 {
3186   rtx temp = gen_reg_rtx (SImode);
3187   rtx shift_24 = GEN_INT (24);
3188   int op1_subbyte = 0;
3189   int op0_subbyte = 0;
3190
3191   if (GET_CODE (operand1) == SUBREG)
3192     {
3193       op1_subbyte = SUBREG_BYTE (operand1);
3194       op1_subbyte /= GET_MODE_SIZE (SImode);
3195       op1_subbyte *= GET_MODE_SIZE (SImode);
3196       operand1 = XEXP (operand1, 0);
3197     }
3198   if (GET_CODE (operand0) == SUBREG)
3199     {
3200       op0_subbyte = SUBREG_BYTE (operand0);
3201       op0_subbyte /= GET_MODE_SIZE (SImode);
3202       op0_subbyte *= GET_MODE_SIZE (SImode);
3203       operand0 = XEXP (operand0, 0);
3204     }
3205   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3206                           shift_24));
3207   if (GET_MODE (operand0) != SImode)
3208     operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
3209   emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3210   DONE;
3211 })
3212
3213 (define_insn "*sign_extendqihi2_insn"
3214   [(set (match_operand:HI 0 "register_operand" "=r")
3215         (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3216   ""
3217   "ldsb\t%1, %0"
3218   [(set_attr "type" "sload")
3219    (set_attr "us3load_type" "3cycle")])
3220
3221 (define_expand "extendqisi2"
3222   [(set (match_operand:SI 0 "register_operand" "")
3223         (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
3224   ""
3225 {
3226   rtx temp = gen_reg_rtx (SImode);
3227   rtx shift_24 = GEN_INT (24);
3228   int op1_subbyte = 0;
3229
3230   if (GET_CODE (operand1) == SUBREG)
3231     {
3232       op1_subbyte = SUBREG_BYTE (operand1);
3233       op1_subbyte /= GET_MODE_SIZE (SImode);
3234       op1_subbyte *= GET_MODE_SIZE (SImode);
3235       operand1 = XEXP (operand1, 0);
3236     }
3237
3238   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3239                           shift_24));
3240   emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3241   DONE;
3242 })
3243
3244 (define_insn "*sign_extendqisi2_insn"
3245   [(set (match_operand:SI 0 "register_operand" "=r")
3246         (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3247   ""
3248   "ldsb\t%1, %0"
3249   [(set_attr "type" "sload")
3250    (set_attr "us3load_type" "3cycle")])
3251
3252 (define_expand "extendqidi2"
3253   [(set (match_operand:DI 0 "register_operand" "")
3254         (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
3255   "TARGET_ARCH64"
3256 {
3257   rtx temp = gen_reg_rtx (DImode);
3258   rtx shift_56 = GEN_INT (56);
3259   int op1_subbyte = 0;
3260
3261   if (GET_CODE (operand1) == SUBREG)
3262     {
3263       op1_subbyte = SUBREG_BYTE (operand1);
3264       op1_subbyte /= GET_MODE_SIZE (DImode);
3265       op1_subbyte *= GET_MODE_SIZE (DImode);
3266       operand1 = XEXP (operand1, 0);
3267     }
3268
3269   emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3270                           shift_56));
3271   emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
3272   DONE;
3273 })
3274
3275 (define_insn "*sign_extendqidi2_insn"
3276   [(set (match_operand:DI 0 "register_operand" "=r")
3277         (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3278   "TARGET_ARCH64"
3279   "ldsb\t%1, %0"
3280   [(set_attr "type" "sload")
3281    (set_attr "us3load_type" "3cycle")])
3282
3283 (define_expand "extendhidi2"
3284   [(set (match_operand:DI 0 "register_operand" "")
3285         (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
3286   "TARGET_ARCH64"
3287 {
3288   rtx temp = gen_reg_rtx (DImode);
3289   rtx shift_48 = GEN_INT (48);
3290   int op1_subbyte = 0;
3291
3292   if (GET_CODE (operand1) == SUBREG)
3293     {
3294       op1_subbyte = SUBREG_BYTE (operand1);
3295       op1_subbyte /= GET_MODE_SIZE (DImode);
3296       op1_subbyte *= GET_MODE_SIZE (DImode);
3297       operand1 = XEXP (operand1, 0);
3298     }
3299
3300   emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3301                           shift_48));
3302   emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
3303   DONE;
3304 })
3305
3306 (define_insn "*sign_extendhidi2_insn"
3307   [(set (match_operand:DI 0 "register_operand" "=r")
3308         (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3309   "TARGET_ARCH64"
3310   "ldsh\t%1, %0"
3311   [(set_attr "type" "sload")
3312    (set_attr "us3load_type" "3cycle")])
3313
3314 (define_expand "extendsidi2"
3315   [(set (match_operand:DI 0 "register_operand" "")
3316         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3317   "TARGET_ARCH64"
3318   "")
3319
3320 (define_insn "*sign_extendsidi2_insn"
3321   [(set (match_operand:DI 0 "register_operand" "=r,r")
3322         (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
3323   "TARGET_ARCH64"
3324   "@
3325   sra\t%1, 0, %0
3326   ldsw\t%1, %0"
3327   [(set_attr "type" "shift,sload")
3328    (set_attr "us3load_type" "*,3cycle")])
3329
3330
3331 ;; Special pattern for optimizing bit-field compares.  This is needed
3332 ;; because combine uses this as a canonical form.
3333
3334 (define_insn "*cmp_zero_extract"
3335   [(set (reg:CC CC_REG)
3336         (compare:CC
3337          (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
3338                           (match_operand:SI 1 "small_int_operand" "I")
3339                           (match_operand:SI 2 "small_int_operand" "I"))
3340          (const_int 0)))]
3341   "INTVAL (operands[2]) > 19"
3342 {
3343   int len = INTVAL (operands[1]);
3344   int pos = 32 - INTVAL (operands[2]) - len;
3345   HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
3346   operands[1] = GEN_INT (mask);
3347   return "andcc\t%0, %1, %%g0";
3348 }
3349   [(set_attr "type" "compare")])
3350
3351 (define_insn "*cmp_zero_extract_sp64"
3352   [(set (reg:CCX CC_REG)
3353         (compare:CCX
3354          (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
3355                           (match_operand:SI 1 "small_int_operand" "I")
3356                           (match_operand:SI 2 "small_int_operand" "I"))
3357          (const_int 0)))]
3358   "TARGET_ARCH64 && INTVAL (operands[2]) > 51"
3359 {
3360   int len = INTVAL (operands[1]);
3361   int pos = 64 - INTVAL (operands[2]) - len;
3362   HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
3363   operands[1] = GEN_INT (mask);
3364   return "andcc\t%0, %1, %%g0";
3365 }
3366   [(set_attr "type" "compare")])
3367
3368
3369 ;; Conversions between float, double and long double.
3370
3371 (define_insn "extendsfdf2"
3372   [(set (match_operand:DF 0 "register_operand" "=e")
3373         (float_extend:DF
3374          (match_operand:SF 1 "register_operand" "f")))]
3375   "TARGET_FPU"
3376   "fstod\t%1, %0"
3377   [(set_attr "type" "fp")
3378    (set_attr "fptype" "double")])
3379
3380 (define_expand "extendsftf2"
3381   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3382         (float_extend:TF
3383          (match_operand:SF 1 "register_operand" "")))]
3384   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3385   "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3386
3387 (define_insn "*extendsftf2_hq"
3388   [(set (match_operand:TF 0 "register_operand" "=e")
3389         (float_extend:TF
3390          (match_operand:SF 1 "register_operand" "f")))]
3391   "TARGET_FPU && TARGET_HARD_QUAD"
3392   "fstoq\t%1, %0"
3393   [(set_attr "type" "fp")])
3394
3395 (define_expand "extenddftf2"
3396   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3397         (float_extend:TF
3398          (match_operand:DF 1 "register_operand" "")))]
3399   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3400   "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3401
3402 (define_insn "*extenddftf2_hq"
3403   [(set (match_operand:TF 0 "register_operand" "=e")
3404         (float_extend:TF
3405          (match_operand:DF 1 "register_operand" "e")))]
3406   "TARGET_FPU && TARGET_HARD_QUAD"
3407   "fdtoq\t%1, %0"
3408   [(set_attr "type" "fp")])
3409
3410 (define_insn "truncdfsf2"
3411   [(set (match_operand:SF 0 "register_operand" "=f")
3412         (float_truncate:SF
3413          (match_operand:DF 1 "register_operand" "e")))]
3414   "TARGET_FPU"
3415   "fdtos\t%1, %0"
3416   [(set_attr "type" "fp")
3417    (set_attr "fptype" "double")])
3418
3419 (define_expand "trunctfsf2"
3420   [(set (match_operand:SF 0 "register_operand" "")
3421         (float_truncate:SF
3422          (match_operand:TF 1 "general_operand" "")))]
3423   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3424   "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3425
3426 (define_insn "*trunctfsf2_hq"
3427   [(set (match_operand:SF 0 "register_operand" "=f")
3428         (float_truncate:SF
3429          (match_operand:TF 1 "register_operand" "e")))]
3430   "TARGET_FPU && TARGET_HARD_QUAD"
3431   "fqtos\t%1, %0"
3432   [(set_attr "type" "fp")])
3433
3434 (define_expand "trunctfdf2"
3435   [(set (match_operand:DF 0 "register_operand" "")
3436         (float_truncate:DF
3437          (match_operand:TF 1 "general_operand" "")))]
3438   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3439   "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3440
3441 (define_insn "*trunctfdf2_hq"
3442   [(set (match_operand:DF 0 "register_operand" "=e")
3443         (float_truncate:DF
3444          (match_operand:TF 1 "register_operand" "e")))]
3445   "TARGET_FPU && TARGET_HARD_QUAD"
3446   "fqtod\t%1, %0"
3447   [(set_attr "type" "fp")])
3448
3449
3450 ;; Conversion between fixed point and floating point.
3451
3452 (define_insn "floatsisf2"
3453   [(set (match_operand:SF 0 "register_operand" "=f")
3454         (float:SF (match_operand:SI 1 "register_operand" "f")))]
3455   "TARGET_FPU"
3456   "fitos\t%1, %0"
3457   [(set_attr "type" "fp")
3458    (set_attr "fptype" "double")])
3459
3460 (define_insn "floatsidf2"
3461   [(set (match_operand:DF 0 "register_operand" "=e")
3462         (float:DF (match_operand:SI 1 "register_operand" "f")))]
3463   "TARGET_FPU"
3464   "fitod\t%1, %0"
3465   [(set_attr "type" "fp")
3466    (set_attr "fptype" "double")])
3467
3468 (define_expand "floatsitf2"
3469   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3470         (float:TF (match_operand:SI 1 "register_operand" "")))]
3471   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3472   "emit_tfmode_cvt (FLOAT, operands); DONE;")
3473
3474 (define_insn "*floatsitf2_hq"
3475   [(set (match_operand:TF 0 "register_operand" "=e")
3476         (float:TF (match_operand:SI 1 "register_operand" "f")))]
3477   "TARGET_FPU && TARGET_HARD_QUAD"
3478   "fitoq\t%1, %0"
3479   [(set_attr "type" "fp")])
3480
3481 (define_expand "floatunssitf2"
3482   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3483         (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
3484   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3485   "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3486
3487 ;; Now the same for 64 bit sources.
3488
3489 (define_insn "floatdisf2"
3490   [(set (match_operand:SF 0 "register_operand" "=f")
3491         (float:SF (match_operand:DI 1 "register_operand" "e")))]
3492   "TARGET_V9 && TARGET_FPU"
3493   "fxtos\t%1, %0"
3494   [(set_attr "type" "fp")
3495    (set_attr "fptype" "double")])
3496
3497 (define_expand "floatunsdisf2"
3498   [(use (match_operand:SF 0 "register_operand" ""))
3499    (use (match_operand:DI 1 "general_operand" ""))]
3500   "TARGET_ARCH64 && TARGET_FPU"
3501   "sparc_emit_floatunsdi (operands, SFmode); DONE;")
3502
3503 (define_insn "floatdidf2"
3504   [(set (match_operand:DF 0 "register_operand" "=e")
3505         (float:DF (match_operand:DI 1 "register_operand" "e")))]
3506   "TARGET_V9 && TARGET_FPU"
3507   "fxtod\t%1, %0"
3508   [(set_attr "type" "fp")
3509    (set_attr "fptype" "double")])
3510
3511 (define_expand "floatunsdidf2"
3512   [(use (match_operand:DF 0 "register_operand" ""))
3513    (use (match_operand:DI 1 "general_operand" ""))]
3514   "TARGET_ARCH64 && TARGET_FPU"
3515   "sparc_emit_floatunsdi (operands, DFmode); DONE;")
3516
3517 (define_expand "floatditf2"
3518   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3519         (float:TF (match_operand:DI 1 "register_operand" "")))]
3520   "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3521   "emit_tfmode_cvt (FLOAT, operands); DONE;")
3522
3523 (define_insn "*floatditf2_hq"
3524   [(set (match_operand:TF 0 "register_operand" "=e")
3525         (float:TF (match_operand:DI 1 "register_operand" "e")))]
3526   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3527   "fxtoq\t%1, %0"
3528   [(set_attr "type" "fp")])
3529
3530 (define_expand "floatunsditf2"
3531   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3532         (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
3533   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3534   "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3535
3536 ;; Convert a float to an actual integer.
3537 ;; Truncation is performed as part of the conversion.
3538
3539 (define_insn "fix_truncsfsi2"
3540   [(set (match_operand:SI 0 "register_operand" "=f")
3541         (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3542   "TARGET_FPU"
3543   "fstoi\t%1, %0"
3544   [(set_attr "type" "fp")
3545    (set_attr "fptype" "double")])
3546
3547 (define_insn "fix_truncdfsi2"
3548   [(set (match_operand:SI 0 "register_operand" "=f")
3549         (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3550   "TARGET_FPU"
3551   "fdtoi\t%1, %0"
3552   [(set_attr "type" "fp")
3553    (set_attr "fptype" "double")])
3554
3555 (define_expand "fix_trunctfsi2"
3556   [(set (match_operand:SI 0 "register_operand" "")
3557         (fix:SI (match_operand:TF 1 "general_operand" "")))]
3558   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3559   "emit_tfmode_cvt (FIX, operands); DONE;")
3560
3561 (define_insn "*fix_trunctfsi2_hq"
3562   [(set (match_operand:SI 0 "register_operand" "=f")
3563         (fix:SI (match_operand:TF 1 "register_operand" "e")))]
3564   "TARGET_FPU && TARGET_HARD_QUAD"
3565   "fqtoi\t%1, %0"
3566   [(set_attr "type" "fp")])
3567
3568 (define_expand "fixuns_trunctfsi2"
3569   [(set (match_operand:SI 0 "register_operand" "")
3570         (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
3571   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3572   "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3573
3574 ;; Now the same, for V9 targets
3575
3576 (define_insn "fix_truncsfdi2"
3577   [(set (match_operand:DI 0 "register_operand" "=e")
3578         (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3579   "TARGET_V9 && TARGET_FPU"
3580   "fstox\t%1, %0"
3581   [(set_attr "type" "fp")
3582    (set_attr "fptype" "double")])
3583
3584 (define_expand "fixuns_truncsfdi2"
3585   [(use (match_operand:DI 0 "register_operand" ""))
3586    (use (match_operand:SF 1 "general_operand" ""))]
3587   "TARGET_ARCH64 && TARGET_FPU"
3588   "sparc_emit_fixunsdi (operands, SFmode); DONE;")
3589
3590 (define_insn "fix_truncdfdi2"
3591   [(set (match_operand:DI 0 "register_operand" "=e")
3592         (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3593   "TARGET_V9 && TARGET_FPU"
3594   "fdtox\t%1, %0"
3595   [(set_attr "type" "fp")
3596    (set_attr "fptype" "double")])
3597
3598 (define_expand "fixuns_truncdfdi2"
3599   [(use (match_operand:DI 0 "register_operand" ""))
3600    (use (match_operand:DF 1 "general_operand" ""))]
3601   "TARGET_ARCH64 && TARGET_FPU"
3602   "sparc_emit_fixunsdi (operands, DFmode); DONE;")
3603
3604 (define_expand "fix_trunctfdi2"
3605   [(set (match_operand:DI 0 "register_operand" "")
3606         (fix:DI (match_operand:TF 1 "general_operand" "")))]
3607   "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3608   "emit_tfmode_cvt (FIX, operands); DONE;")
3609
3610 (define_insn "*fix_trunctfdi2_hq"
3611   [(set (match_operand:DI 0 "register_operand" "=e")
3612         (fix:DI (match_operand:TF 1 "register_operand" "e")))]
3613   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3614   "fqtox\t%1, %0"
3615   [(set_attr "type" "fp")])
3616
3617 (define_expand "fixuns_trunctfdi2"
3618   [(set (match_operand:DI 0 "register_operand" "")
3619         (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
3620   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3621   "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3622
3623
3624 ;; Integer addition/subtraction instructions.
3625
3626 (define_expand "adddi3"
3627   [(set (match_operand:DI 0 "register_operand" "")
3628         (plus:DI (match_operand:DI 1 "register_operand" "")
3629                  (match_operand:DI 2 "arith_double_add_operand" "")))]
3630   ""
3631 {
3632   if (! TARGET_ARCH64)
3633     {
3634       emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3635                           gen_rtx_SET (VOIDmode, operands[0],
3636                                    gen_rtx_PLUS (DImode, operands[1],
3637                                                  operands[2])),
3638                           gen_rtx_CLOBBER (VOIDmode,
3639                                    gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3640       DONE;
3641     }
3642 })
3643
3644 (define_insn_and_split "*adddi3_insn_sp32"
3645   [(set (match_operand:DI 0 "register_operand" "=r")
3646         (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
3647                  (match_operand:DI 2 "arith_double_operand" "rHI")))
3648    (clobber (reg:CC CC_REG))]
3649   "! TARGET_ARCH64"
3650   "#"
3651   "&& reload_completed"
3652   [(parallel [(set (reg:CC_NOOV CC_REG)
3653                    (compare:CC_NOOV (plus:SI (match_dup 4)
3654                                              (match_dup 5))
3655                                     (const_int 0)))
3656               (set (match_dup 3)
3657                    (plus:SI (match_dup 4) (match_dup 5)))])
3658    (set (match_dup 6)
3659         (plus:SI (plus:SI (match_dup 7)
3660                           (match_dup 8))
3661                  (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3662 {
3663   operands[3] = gen_lowpart (SImode, operands[0]);
3664   operands[4] = gen_lowpart (SImode, operands[1]);
3665   operands[5] = gen_lowpart (SImode, operands[2]);
3666   operands[6] = gen_highpart (SImode, operands[0]);
3667   operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
3668 #if HOST_BITS_PER_WIDE_INT == 32
3669   if (GET_CODE (operands[2]) == CONST_INT)
3670     {
3671       if (INTVAL (operands[2]) < 0)
3672         operands[8] = constm1_rtx;
3673       else
3674         operands[8] = const0_rtx;
3675     }
3676   else
3677 #endif
3678     operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3679 }
3680   [(set_attr "length" "2")])
3681
3682 ;; LTU here means "carry set"
3683 (define_insn "addx"
3684   [(set (match_operand:SI 0 "register_operand" "=r")
3685         (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3686                           (match_operand:SI 2 "arith_operand" "rI"))
3687                  (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3688   ""
3689   "addx\t%1, %2, %0"
3690   [(set_attr "type" "ialuX")])
3691
3692 (define_insn_and_split "*addx_extend_sp32"
3693   [(set (match_operand:DI 0 "register_operand" "=r")
3694         (zero_extend:DI (plus:SI (plus:SI
3695                                   (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3696                                   (match_operand:SI 2 "arith_operand" "rI"))
3697                                  (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3698   "! TARGET_ARCH64"
3699   "#"
3700   "&& reload_completed"
3701   [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
3702                                (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))
3703    (set (match_dup 4) (const_int 0))]
3704   "operands[3] = gen_lowpart (SImode, operands[0]);
3705    operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
3706   [(set_attr "length" "2")])
3707
3708 (define_insn "*addx_extend_sp64"
3709   [(set (match_operand:DI 0 "register_operand" "=r")
3710         (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3711                                           (match_operand:SI 2 "arith_operand" "rI"))
3712                                  (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3713   "TARGET_ARCH64"
3714   "addx\t%r1, %2, %0"
3715   [(set_attr "type" "ialuX")])
3716
3717 (define_insn_and_split "*adddi3_extend_sp32"
3718   [(set (match_operand:DI 0 "register_operand" "=r")
3719         (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
3720                  (match_operand:DI 2 "register_operand" "r")))
3721    (clobber (reg:CC CC_REG))]
3722   "! TARGET_ARCH64"
3723   "#"
3724   "&& reload_completed"
3725   [(parallel [(set (reg:CC_NOOV CC_REG)
3726                    (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
3727                                     (const_int 0)))
3728               (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
3729    (set (match_dup 6)
3730         (plus:SI (plus:SI (match_dup 4) (const_int 0))
3731                  (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3732   "operands[3] = gen_lowpart (SImode, operands[2]);
3733    operands[4] = gen_highpart (SImode, operands[2]);
3734    operands[5] = gen_lowpart (SImode, operands[0]);
3735    operands[6] = gen_highpart (SImode, operands[0]);"
3736   [(set_attr "length" "2")])
3737
3738 (define_insn "*adddi3_sp64"
3739   [(set (match_operand:DI 0 "register_operand" "=r,r")
3740         (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
3741                  (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3742   "TARGET_ARCH64"
3743   "@
3744    add\t%1, %2, %0
3745    sub\t%1, -%2, %0")
3746
3747 (define_insn "addsi3"
3748   [(set (match_operand:SI 0 "register_operand" "=r,r,d")
3749         (plus:SI (match_operand:SI 1 "register_operand" "%r,r,d")
3750                  (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
3751   ""
3752   "@
3753    add\t%1, %2, %0
3754    sub\t%1, -%2, %0
3755    fpadd32s\t%1, %2, %0"
3756   [(set_attr "type" "*,*,fga")
3757    (set_attr "fptype" "*,*,single")])
3758
3759 (define_insn "*cmp_cc_plus"
3760   [(set (reg:CC_NOOV CC_REG)
3761         (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
3762                                   (match_operand:SI 1 "arith_operand" "rI"))
3763                          (const_int 0)))]
3764   ""
3765   "addcc\t%0, %1, %%g0"
3766   [(set_attr "type" "compare")])
3767
3768 (define_insn "*cmp_ccx_plus"
3769   [(set (reg:CCX_NOOV CC_REG)
3770         (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_operand" "%r")
3771                                    (match_operand:DI 1 "arith_operand" "rI"))
3772                           (const_int 0)))]
3773   "TARGET_ARCH64"
3774   "addcc\t%0, %1, %%g0"
3775   [(set_attr "type" "compare")])
3776
3777 (define_insn "*cmp_cc_plus_set"
3778   [(set (reg:CC_NOOV CC_REG)
3779         (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3780                                   (match_operand:SI 2 "arith_operand" "rI"))
3781                          (const_int 0)))
3782    (set (match_operand:SI 0 "register_operand" "=r")
3783         (plus:SI (match_dup 1) (match_dup 2)))]
3784   ""
3785   "addcc\t%1, %2, %0"
3786   [(set_attr "type" "compare")])
3787
3788 (define_insn "*cmp_ccx_plus_set"
3789   [(set (reg:CCX_NOOV CC_REG)
3790         (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_operand" "%r")
3791                                    (match_operand:DI 2 "arith_operand" "rI"))
3792                           (const_int 0)))
3793    (set (match_operand:DI 0 "register_operand" "=r")
3794         (plus:DI (match_dup 1) (match_dup 2)))]
3795   "TARGET_ARCH64"
3796   "addcc\t%1, %2, %0"
3797   [(set_attr "type" "compare")])
3798
3799 (define_expand "subdi3"
3800   [(set (match_operand:DI 0 "register_operand" "")
3801         (minus:DI (match_operand:DI 1 "register_operand" "")
3802                   (match_operand:DI 2 "arith_double_add_operand" "")))]
3803   ""
3804 {
3805   if (! TARGET_ARCH64)
3806     {
3807       emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3808                           gen_rtx_SET (VOIDmode, operands[0],
3809                                    gen_rtx_MINUS (DImode, operands[1],
3810                                                   operands[2])),
3811                           gen_rtx_CLOBBER (VOIDmode,
3812                                    gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3813       DONE;
3814     }
3815 })
3816
3817 (define_insn_and_split "*subdi3_insn_sp32"
3818   [(set (match_operand:DI 0 "register_operand" "=r")
3819         (minus:DI (match_operand:DI 1 "register_operand" "r")
3820                   (match_operand:DI 2 "arith_double_operand" "rHI")))
3821    (clobber (reg:CC CC_REG))]
3822   "! TARGET_ARCH64"
3823   "#"
3824   "&& reload_completed"
3825   [(parallel [(set (reg:CC_NOOV CC_REG)
3826                    (compare:CC_NOOV (minus:SI (match_dup 4)
3827                                               (match_dup 5))
3828                                     (const_int 0)))
3829               (set (match_dup 3)
3830                    (minus:SI (match_dup 4) (match_dup 5)))])
3831    (set (match_dup 6)
3832         (minus:SI (minus:SI (match_dup 7)
3833                             (match_dup 8))
3834                   (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3835 {
3836   operands[3] = gen_lowpart (SImode, operands[0]);
3837   operands[4] = gen_lowpart (SImode, operands[1]);
3838   operands[5] = gen_lowpart (SImode, operands[2]);
3839   operands[6] = gen_highpart (SImode, operands[0]);
3840   operands[7] = gen_highpart (SImode, operands[1]);
3841 #if HOST_BITS_PER_WIDE_INT == 32
3842   if (GET_CODE (operands[2]) == CONST_INT)
3843     {
3844       if (INTVAL (operands[2]) < 0)
3845         operands[8] = constm1_rtx;
3846       else
3847         operands[8] = const0_rtx;
3848     }
3849   else
3850 #endif
3851     operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3852 }
3853   [(set_attr "length" "2")])
3854
3855 ;; LTU here means "carry set"
3856 (define_insn "subx"
3857   [(set (match_operand:SI 0 "register_operand" "=r")
3858         (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3859                             (match_operand:SI 2 "arith_operand" "rI"))
3860                   (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3861   ""
3862   "subx\t%r1, %2, %0"
3863   [(set_attr "type" "ialuX")])
3864
3865 (define_insn "*subx_extend_sp64"
3866   [(set (match_operand:DI 0 "register_operand" "=r")
3867         (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3868                                             (match_operand:SI 2 "arith_operand" "rI"))
3869                                   (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3870   "TARGET_ARCH64"
3871   "subx\t%r1, %2, %0"
3872   [(set_attr "type" "ialuX")])
3873
3874 (define_insn_and_split "*subx_extend"
3875   [(set (match_operand:DI 0 "register_operand" "=r")
3876         (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3877                                             (match_operand:SI 2 "arith_operand" "rI"))
3878                                   (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3879   "! TARGET_ARCH64"
3880   "#"
3881   "&& reload_completed"
3882   [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
3883                                 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))
3884    (set (match_dup 4) (const_int 0))]
3885   "operands[3] = gen_lowpart (SImode, operands[0]);
3886    operands[4] = gen_highpart (SImode, operands[0]);"
3887   [(set_attr "length" "2")])
3888
3889 (define_insn_and_split "*subdi3_extend_sp32"
3890   [(set (match_operand:DI 0 "register_operand" "=r")
3891       (minus:DI (match_operand:DI 1 "register_operand" "r")
3892                 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
3893    (clobber (reg:CC CC_REG))]
3894   "! TARGET_ARCH64"
3895   "#"
3896   "&& reload_completed"
3897   [(parallel [(set (reg:CC_NOOV CC_REG)
3898                    (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
3899                                     (const_int 0)))
3900               (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
3901    (set (match_dup 6)
3902         (minus:SI (minus:SI (match_dup 4) (const_int 0))
3903                   (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3904   "operands[3] = gen_lowpart (SImode, operands[1]);
3905    operands[4] = gen_highpart (SImode, operands[1]);
3906    operands[5] = gen_lowpart (SImode, operands[0]);
3907    operands[6] = gen_highpart (SImode, operands[0]);"
3908   [(set_attr "length" "2")])
3909
3910 (define_insn "*subdi3_sp64"
3911   [(set (match_operand:DI 0 "register_operand" "=r,r")
3912         (minus:DI (match_operand:DI 1 "register_operand" "r,r")
3913                   (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3914   "TARGET_ARCH64"
3915   "@
3916    sub\t%1, %2, %0
3917    add\t%1, -%2, %0")
3918
3919 (define_insn "subsi3"
3920   [(set (match_operand:SI 0 "register_operand" "=r,r,d")
3921         (minus:SI (match_operand:SI 1 "register_operand" "r,r,d")
3922                   (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
3923   ""
3924   "@
3925    sub\t%1, %2, %0
3926    add\t%1, -%2, %0
3927    fpsub32s\t%1, %2, %0"
3928   [(set_attr "type" "*,*,fga")
3929    (set_attr "fptype" "*,*,single")])
3930
3931 (define_insn "*cmp_minus_cc"
3932   [(set (reg:CC_NOOV CC_REG)
3933         (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
3934                                    (match_operand:SI 1 "arith_operand" "rI"))
3935                          (const_int 0)))]
3936   ""
3937   "subcc\t%r0, %1, %%g0"
3938   [(set_attr "type" "compare")])
3939
3940 (define_insn "*cmp_minus_ccx"
3941   [(set (reg:CCX_NOOV CC_REG)
3942         (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
3943                                     (match_operand:DI 1 "arith_operand" "rI"))
3944                           (const_int 0)))]
3945   "TARGET_ARCH64"
3946   "subcc\t%0, %1, %%g0"
3947   [(set_attr "type" "compare")])
3948
3949 (define_insn "cmp_minus_cc_set"
3950   [(set (reg:CC_NOOV CC_REG)
3951         (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3952                                    (match_operand:SI 2 "arith_operand" "rI"))
3953                          (const_int 0)))
3954    (set (match_operand:SI 0 "register_operand" "=r")
3955         (minus:SI (match_dup 1) (match_dup 2)))]
3956   ""
3957   "subcc\t%r1, %2, %0"
3958   [(set_attr "type" "compare")])
3959
3960 (define_insn "*cmp_minus_ccx_set"
3961   [(set (reg:CCX_NOOV CC_REG)
3962         (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
3963                                     (match_operand:DI 2 "arith_operand" "rI"))
3964                           (const_int 0)))
3965    (set (match_operand:DI 0 "register_operand" "=r")
3966         (minus:DI (match_dup 1) (match_dup 2)))]
3967   "TARGET_ARCH64"
3968   "subcc\t%1, %2, %0"
3969   [(set_attr "type" "compare")])
3970
3971
3972 ;; Integer multiply/divide instructions.
3973
3974 ;; The 32-bit multiply/divide instructions are deprecated on v9, but at
3975 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
3976
3977 (define_insn "mulsi3"
3978   [(set (match_operand:SI 0 "register_operand" "=r")
3979         (mult:SI (match_operand:SI 1 "arith_operand" "%r")
3980                  (match_operand:SI 2 "arith_operand" "rI")))]
3981   "TARGET_HARD_MUL"
3982   "smul\t%1, %2, %0"
3983   [(set_attr "type" "imul")])
3984
3985 (define_expand "muldi3"
3986   [(set (match_operand:DI 0 "register_operand" "")
3987         (mult:DI (match_operand:DI 1 "arith_operand" "")
3988                  (match_operand:DI 2 "arith_operand" "")))]
3989   "TARGET_ARCH64 || TARGET_V8PLUS"
3990 {
3991   if (TARGET_V8PLUS)
3992     {
3993       emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
3994       DONE;
3995     }
3996 })
3997
3998 (define_insn "*muldi3_sp64"
3999   [(set (match_operand:DI 0 "register_operand" "=r")
4000         (mult:DI (match_operand:DI 1 "arith_operand" "%r")
4001                  (match_operand:DI 2 "arith_operand" "rI")))]
4002   "TARGET_ARCH64"
4003   "mulx\t%1, %2, %0"
4004   [(set_attr "type" "imul")])
4005
4006 ;; V8plus wide multiply.
4007 ;; XXX
4008 (define_insn "muldi3_v8plus"
4009   [(set (match_operand:DI 0 "register_operand" "=r,h")
4010         (mult:DI (match_operand:DI 1 "arith_operand" "%r,0")
4011                  (match_operand:DI 2 "arith_operand" "rI,rI")))
4012    (clobber (match_scratch:SI 3 "=&h,X"))
4013    (clobber (match_scratch:SI 4 "=&h,X"))]
4014   "TARGET_V8PLUS"
4015 {
4016   if (sparc_check_64 (operands[1], insn) <= 0)
4017     output_asm_insn ("srl\t%L1, 0, %L1", operands);
4018   if (which_alternative == 1)
4019     output_asm_insn ("sllx\t%H1, 32, %H1", operands);
4020   if (GET_CODE (operands[2]) == CONST_INT)
4021     {
4022       if (which_alternative == 1)
4023         return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %2, %L0\;srlx\t%L0, 32, %H0";
4024       else
4025         return "sllx\t%H1, 32, %3\n\tor\t%L1, %3, %3\n\tmulx\t%3, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0";
4026     }
4027   else if (rtx_equal_p (operands[1], operands[2]))
4028     {
4029       if (which_alternative == 1)
4030         return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %H1, %L0\;srlx\t%L0, 32, %H0";
4031       else
4032         return "sllx\t%H1, 32, %3\n\tor\t%L1, %3, %3\n\tmulx\t%3, %3, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0";
4033     }
4034   if (sparc_check_64 (operands[2], insn) <= 0)
4035     output_asm_insn ("srl\t%L2, 0, %L2", operands);
4036   if (which_alternative == 1)
4037     return "or\t%L1, %H1, %H1\n\tsllx\t%H2, 32, %L1\n\tor\t%L2, %L1, %L1\n\tmulx\t%H1, %L1, %L0\;srlx\t%L0, 32, %H0";
4038   else
4039     return "sllx\t%H1, 32, %3\n\tsllx\t%H2, 32, %4\n\tor\t%L1, %3, %3\n\tor\t%L2, %4, %4\n\tmulx\t%3, %4, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0";
4040 }
4041   [(set_attr "type" "multi")
4042    (set_attr "length" "9,8")])
4043
4044 (define_insn "*cmp_mul_set"
4045   [(set (reg:CC CC_REG)
4046         (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4047                     (match_operand:SI 2 "arith_operand" "rI"))
4048                     (const_int 0)))
4049    (set (match_operand:SI 0 "register_operand" "=r")
4050         (mult:SI (match_dup 1) (match_dup 2)))]
4051   "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
4052   "smulcc\t%1, %2, %0"
4053   [(set_attr "type" "imul")])
4054
4055 (define_expand "mulsidi3"
4056   [(set (match_operand:DI 0 "register_operand" "")
4057         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4058                  (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
4059   "TARGET_HARD_MUL"
4060 {
4061   if (CONSTANT_P (operands[2]))
4062     {
4063       if (TARGET_V8PLUS)
4064         emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
4065                                               operands[2]));
4066       else if (TARGET_ARCH32)
4067         emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
4068                                             operands[2]));
4069       else 
4070         emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
4071                                             operands[2]));
4072       DONE;
4073     }
4074   if (TARGET_V8PLUS)
4075     {
4076       emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
4077       DONE;
4078     }
4079 })
4080
4081 ;; V9 puts the 64-bit product in a 64-bit register.  Only out or global
4082 ;; registers can hold 64-bit values in the V8plus environment.
4083 ;; XXX
4084 (define_insn "mulsidi3_v8plus"
4085   [(set (match_operand:DI 0 "register_operand" "=h,r")
4086         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4087                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4088    (clobber (match_scratch:SI 3 "=X,&h"))]
4089   "TARGET_V8PLUS"
4090   "@
4091    smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4092    smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4093   [(set_attr "type" "multi")
4094    (set_attr "length" "2,3")])
4095
4096 ;; XXX
4097 (define_insn "const_mulsidi3_v8plus"
4098   [(set (match_operand:DI 0 "register_operand" "=h,r")
4099         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4100                  (match_operand:DI 2 "small_int_operand" "I,I")))
4101    (clobber (match_scratch:SI 3 "=X,&h"))]
4102   "TARGET_V8PLUS"
4103   "@
4104    smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4105    smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4106   [(set_attr "type" "multi")
4107    (set_attr "length" "2,3")])
4108
4109 ;; XXX
4110 (define_insn "*mulsidi3_sp32"
4111   [(set (match_operand:DI 0 "register_operand" "=r")
4112         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4113                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4114   "TARGET_HARD_MUL32"
4115 {
4116   return TARGET_SPARCLET
4117          ? "smuld\t%1, %2, %L0"
4118          : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4119 }
4120   [(set (attr "type")
4121         (if_then_else (eq_attr "isa" "sparclet")
4122                       (const_string "imul") (const_string "multi")))
4123    (set (attr "length")
4124         (if_then_else (eq_attr "isa" "sparclet")
4125                       (const_int 1) (const_int 2)))])
4126
4127 (define_insn "*mulsidi3_sp64"
4128   [(set (match_operand:DI 0 "register_operand" "=r")
4129         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4130                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4131   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4132   "smul\t%1, %2, %0"
4133   [(set_attr "type" "imul")])
4134
4135 ;; Extra pattern, because sign_extend of a constant isn't valid.
4136
4137 ;; XXX
4138 (define_insn "const_mulsidi3_sp32"
4139   [(set (match_operand:DI 0 "register_operand" "=r")
4140         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4141                  (match_operand:DI 2 "small_int_operand" "I")))]
4142   "TARGET_HARD_MUL32"
4143 {
4144   return TARGET_SPARCLET
4145          ? "smuld\t%1, %2, %L0"
4146          : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4147 }
4148   [(set (attr "type")
4149         (if_then_else (eq_attr "isa" "sparclet")
4150                       (const_string "imul") (const_string "multi")))
4151    (set (attr "length")
4152         (if_then_else (eq_attr "isa" "sparclet")
4153                       (const_int 1) (const_int 2)))])
4154
4155 (define_insn "const_mulsidi3_sp64"
4156   [(set (match_operand:DI 0 "register_operand" "=r")
4157         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4158                  (match_operand:DI 2 "small_int_operand" "I")))]
4159   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4160   "smul\t%1, %2, %0"
4161   [(set_attr "type" "imul")])
4162
4163 (define_expand "smulsi3_highpart"
4164   [(set (match_operand:SI 0 "register_operand" "")
4165         (truncate:SI
4166          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4167                                (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
4168                       (const_int 32))))]
4169   "TARGET_HARD_MUL && TARGET_ARCH32"
4170 {
4171   if (CONSTANT_P (operands[2]))
4172     {
4173       if (TARGET_V8PLUS)
4174         {
4175           emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
4176                                                         operands[1],
4177                                                         operands[2],
4178                                                         GEN_INT (32)));
4179           DONE;
4180         }
4181       emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
4182       DONE;
4183     }
4184   if (TARGET_V8PLUS)
4185     {
4186       emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
4187                                               operands[2], GEN_INT (32)));
4188       DONE;
4189     }
4190 })
4191
4192 ;; XXX
4193 (define_insn "smulsi3_highpart_v8plus"
4194   [(set (match_operand:SI 0 "register_operand" "=h,r")
4195         (truncate:SI
4196          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4197                                (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4198                       (match_operand:SI 3 "small_int_operand" "I,I"))))
4199    (clobber (match_scratch:SI 4 "=X,&h"))]
4200   "TARGET_V8PLUS"
4201   "@
4202    smul\t%1, %2, %0\;srlx\t%0, %3, %0
4203    smul\t%1, %2, %4\;srlx\t%4, %3, %0"
4204   [(set_attr "type" "multi")
4205    (set_attr "length" "2")])
4206
4207 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
4208 ;; XXX
4209 (define_insn ""
4210   [(set (match_operand:SI 0 "register_operand" "=h,r")
4211         (subreg:SI
4212          (lshiftrt:DI
4213           (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4214                    (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4215           (match_operand:SI 3 "small_int_operand" "I,I"))
4216          4))
4217    (clobber (match_scratch:SI 4 "=X,&h"))]
4218   "TARGET_V8PLUS"
4219   "@
4220    smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4221    smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4222   [(set_attr "type" "multi")
4223    (set_attr "length" "2")])
4224
4225 ;; XXX
4226 (define_insn "const_smulsi3_highpart_v8plus"
4227   [(set (match_operand:SI 0 "register_operand" "=h,r")
4228         (truncate:SI
4229          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4230                                (match_operand:DI 2 "small_int_operand" "I,I"))
4231                       (match_operand:SI 3 "small_int_operand" "I,I"))))
4232    (clobber (match_scratch:SI 4 "=X,&h"))]
4233   "TARGET_V8PLUS"
4234   "@
4235    smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4236    smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4237   [(set_attr "type" "multi")
4238    (set_attr "length" "2")])
4239
4240 ;; XXX
4241 (define_insn "*smulsi3_highpart_sp32"
4242   [(set (match_operand:SI 0 "register_operand" "=r")
4243         (truncate:SI
4244          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4245                                (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
4246                       (const_int 32))))]
4247   "TARGET_HARD_MUL32"
4248   "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4249   [(set_attr "type" "multi")
4250    (set_attr "length" "2")])
4251
4252 ;; XXX
4253 (define_insn "const_smulsi3_highpart"
4254   [(set (match_operand:SI 0 "register_operand" "=r")
4255         (truncate:SI
4256          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4257                                (match_operand:DI 2 "small_int_operand" "i"))
4258                       (const_int 32))))]
4259   "TARGET_HARD_MUL32"
4260   "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4261   [(set_attr "type" "multi")
4262    (set_attr "length" "2")])
4263
4264 (define_expand "umulsidi3"
4265   [(set (match_operand:DI 0 "register_operand" "")
4266         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4267                  (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
4268   "TARGET_HARD_MUL"
4269 {
4270   if (CONSTANT_P (operands[2]))
4271     {
4272       if (TARGET_V8PLUS)
4273         emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
4274                                                operands[2]));
4275       else if (TARGET_ARCH32)
4276         emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
4277                                              operands[2]));
4278       else 
4279         emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
4280                                              operands[2]));
4281       DONE;
4282     }
4283   if (TARGET_V8PLUS)
4284     {
4285       emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
4286       DONE;
4287     }
4288 })
4289
4290 ;; XXX
4291 (define_insn "umulsidi3_v8plus"
4292   [(set (match_operand:DI 0 "register_operand" "=h,r")
4293         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4294                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4295    (clobber (match_scratch:SI 3 "=X,&h"))]
4296   "TARGET_V8PLUS"
4297   "@
4298    umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4299    umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4300   [(set_attr "type" "multi")
4301    (set_attr "length" "2,3")])
4302
4303 ;; XXX
4304 (define_insn "*umulsidi3_sp32"
4305   [(set (match_operand:DI 0 "register_operand" "=r")
4306         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4307                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4308   "TARGET_HARD_MUL32"
4309 {
4310   return TARGET_SPARCLET
4311          ? "umuld\t%1, %2, %L0"
4312          : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
4313 }
4314   [(set (attr "type")
4315         (if_then_else (eq_attr "isa" "sparclet")
4316                       (const_string "imul") (const_string "multi")))
4317    (set (attr "length")
4318         (if_then_else (eq_attr "isa" "sparclet")
4319                       (const_int 1) (const_int 2)))])
4320
4321 (define_insn "*umulsidi3_sp64"
4322   [(set (match_operand:DI 0 "register_operand" "=r")
4323         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4324                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4325   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4326   "umul\t%1, %2, %0"
4327   [(set_attr "type" "imul")])
4328
4329 ;; Extra pattern, because sign_extend of a constant isn't valid.
4330
4331 ;; XXX
4332 (define_insn "const_umulsidi3_sp32"
4333   [(set (match_operand:DI 0 "register_operand" "=r")
4334         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4335                  (match_operand:DI 2 "uns_small_int_operand" "")))]
4336   "TARGET_HARD_MUL32"
4337 {
4338   return TARGET_SPARCLET
4339          ? "umuld\t%1, %s2, %L0"
4340          : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
4341 }
4342   [(set (attr "type")
4343         (if_then_else (eq_attr "isa" "sparclet")
4344                       (const_string "imul") (const_string "multi")))
4345    (set (attr "length")
4346         (if_then_else (eq_attr "isa" "sparclet")
4347                       (const_int 1) (const_int 2)))])
4348
4349 (define_insn "const_umulsidi3_sp64"
4350   [(set (match_operand:DI 0 "register_operand" "=r")
4351         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4352                  (match_operand:DI 2 "uns_small_int_operand" "")))]
4353   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4354   "umul\t%1, %s2, %0"
4355   [(set_attr "type" "imul")])
4356
4357 ;; XXX
4358 (define_insn "const_umulsidi3_v8plus"
4359   [(set (match_operand:DI 0 "register_operand" "=h,r")
4360         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4361                  (match_operand:DI 2 "uns_small_int_operand" "")))
4362    (clobber (match_scratch:SI 3 "=X,h"))]
4363   "TARGET_V8PLUS"
4364   "@
4365    umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
4366    umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4367   [(set_attr "type" "multi")
4368    (set_attr "length" "2,3")])
4369
4370 (define_expand "umulsi3_highpart"
4371   [(set (match_operand:SI 0 "register_operand" "")
4372         (truncate:SI
4373          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4374                                (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
4375                       (const_int 32))))]
4376   "TARGET_HARD_MUL && TARGET_ARCH32"
4377 {
4378   if (CONSTANT_P (operands[2]))
4379     {
4380       if (TARGET_V8PLUS)
4381         {
4382           emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
4383                                                         operands[1],
4384                                                         operands[2],
4385                                                         GEN_INT (32)));
4386           DONE;
4387         }
4388       emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
4389       DONE;
4390     }
4391   if (TARGET_V8PLUS)
4392     {
4393       emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
4394                                               operands[2], GEN_INT (32)));
4395       DONE;
4396     }
4397 })
4398
4399 ;; XXX
4400 (define_insn "umulsi3_highpart_v8plus"
4401   [(set (match_operand:SI 0 "register_operand" "=h,r")
4402         (truncate:SI
4403          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4404                                (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4405                       (match_operand:SI 3 "small_int_operand" "I,I"))))
4406    (clobber (match_scratch:SI 4 "=X,h"))]
4407   "TARGET_V8PLUS"
4408   "@
4409    umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4410    umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4411   [(set_attr "type" "multi")
4412    (set_attr "length" "2")])
4413
4414 ;; XXX
4415 (define_insn "const_umulsi3_highpart_v8plus"
4416   [(set (match_operand:SI 0 "register_operand" "=h,r")
4417         (truncate:SI
4418          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4419                                (match_operand:DI 2 "uns_small_int_operand" ""))
4420                       (match_operand:SI 3 "small_int_operand" "I,I"))))
4421    (clobber (match_scratch:SI 4 "=X,h"))]
4422   "TARGET_V8PLUS"
4423   "@
4424    umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
4425    umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
4426   [(set_attr "type" "multi")
4427    (set_attr "length" "2")])
4428
4429 ;; XXX
4430 (define_insn "*umulsi3_highpart_sp32"
4431   [(set (match_operand:SI 0 "register_operand" "=r")
4432         (truncate:SI
4433          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4434                                (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
4435                       (const_int 32))))]
4436   "TARGET_HARD_MUL32"
4437   "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
4438   [(set_attr "type" "multi")
4439    (set_attr "length" "2")])
4440
4441 ;; XXX
4442 (define_insn "const_umulsi3_highpart"
4443   [(set (match_operand:SI 0 "register_operand" "=r")
4444         (truncate:SI
4445          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4446                                (match_operand:DI 2 "uns_small_int_operand" ""))
4447                       (const_int 32))))]
4448   "TARGET_HARD_MUL32"
4449   "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
4450   [(set_attr "type" "multi")
4451    (set_attr "length" "2")])
4452
4453 (define_expand "divsi3"
4454   [(parallel [(set (match_operand:SI 0 "register_operand" "")
4455                    (div:SI (match_operand:SI 1 "register_operand" "")
4456                            (match_operand:SI 2 "input_operand" "")))
4457               (clobber (match_scratch:SI 3 ""))])]
4458   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4459 {
4460   if (TARGET_ARCH64)
4461     {
4462       operands[3] = gen_reg_rtx(SImode);
4463       emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
4464       emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
4465                                   operands[3]));
4466       DONE;
4467     }
4468 })
4469
4470 ;; The V8 architecture specifies that there must be at least 3 instructions
4471 ;; between a write to the Y register and a use of it for correct results.
4472 ;; We try to fill one of them with a simple constant or a memory load.
4473
4474 (define_insn "divsi3_sp32"
4475   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
4476         (div:SI (match_operand:SI 1 "register_operand" "r,r,r")
4477                 (match_operand:SI 2 "input_operand" "rI,K,m")))
4478    (clobber (match_scratch:SI 3 "=&r,&r,&r"))]
4479   "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4480 {
4481   output_asm_insn ("sra\t%1, 31, %3", operands);
4482   output_asm_insn ("wr\t%3, 0, %%y", operands);
4483
4484   switch (which_alternative)
4485     {
4486     case 0:
4487       if (TARGET_V9)
4488         return "sdiv\t%1, %2, %0";
4489       else
4490         return "nop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
4491     case 1:
4492       if (TARGET_V9)
4493         return "sethi\t%%hi(%a2), %3\n\tsdiv\t%1, %3, %0";
4494       else
4495         return "sethi\t%%hi(%a2), %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4496     case 2:
4497       if (TARGET_V9)
4498         return "ld\t%2, %3\n\tsdiv\t%1, %3, %0";
4499       else
4500         return "ld\t%2, %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4501     default:
4502       gcc_unreachable ();
4503     }
4504 }
4505   [(set_attr "type" "multi")
4506    (set (attr "length")
4507         (if_then_else (eq_attr "isa" "v9")
4508                       (const_int 4) (const_int 6)))])
4509
4510 (define_insn "divsi3_sp64"
4511   [(set (match_operand:SI 0 "register_operand" "=r")
4512         (div:SI (match_operand:SI 1 "register_operand" "r")
4513                 (match_operand:SI 2 "input_operand" "rI")))
4514    (use (match_operand:SI 3 "register_operand" "r"))]
4515   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4516   "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
4517   [(set_attr "type" "multi")
4518    (set_attr "length" "2")])
4519
4520 (define_insn "divdi3"
4521   [(set (match_operand:DI 0 "register_operand" "=r")
4522         (div:DI (match_operand:DI 1 "register_operand" "r")
4523                 (match_operand:DI 2 "arith_operand" "rI")))]
4524   "TARGET_ARCH64"
4525   "sdivx\t%1, %2, %0"
4526   [(set_attr "type" "idiv")])
4527
4528 (define_insn "*cmp_sdiv_cc_set"
4529   [(set (reg:CC CC_REG)
4530         (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
4531                             (match_operand:SI 2 "arith_operand" "rI"))
4532                     (const_int 0)))
4533    (set (match_operand:SI 0 "register_operand" "=r")
4534         (div:SI (match_dup 1) (match_dup 2)))
4535    (clobber (match_scratch:SI 3 "=&r"))]
4536   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4537 {
4538   output_asm_insn ("sra\t%1, 31, %3", operands);
4539   output_asm_insn ("wr\t%3, 0, %%y", operands);
4540
4541   if (TARGET_V9)
4542     return "sdivcc\t%1, %2, %0";
4543   else
4544     return "nop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
4545 }
4546   [(set_attr "type" "multi")
4547    (set (attr "length")
4548         (if_then_else (eq_attr "isa" "v9")
4549                       (const_int 3) (const_int 6)))])
4550
4551 ;; XXX
4552 (define_expand "udivsi3"
4553   [(set (match_operand:SI 0 "register_operand" "")
4554         (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "")
4555                  (match_operand:SI 2 "input_operand" "")))]
4556   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4557   "")
4558
4559 ;; The V8 architecture specifies that there must be at least 3 instructions
4560 ;; between a write to the Y register and a use of it for correct results.
4561 ;; We try to fill one of them with a simple constant or a memory load.
4562
4563 (define_insn "udivsi3_sp32"
4564   [(set (match_operand:SI 0 "register_operand" "=r,&r,&r,&r")
4565         (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r,r,r,m")
4566                  (match_operand:SI 2 "input_operand" "rI,K,m,r")))]
4567   "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4568 {
4569   output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4570
4571   switch (which_alternative)
4572     {
4573     case 0:
4574       if (TARGET_V9)
4575         return "udiv\t%1, %2, %0";
4576       else
4577         return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
4578     case 1:
4579       if (TARGET_V9)
4580         return "sethi\t%%hi(%a2), %0\n\tudiv\t%1, %0, %0";
4581       else
4582         return "sethi\t%%hi(%a2), %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4583     case 2:
4584       if (TARGET_V9)
4585         return "ld\t%2, %0\n\tudiv\t%1, %0, %0";
4586       else
4587         return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4588     case 3:
4589       if (TARGET_V9)
4590         return "ld\t%1, %0\n\tudiv\t%0, %2, %0";
4591       else
4592         return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
4593     default:
4594       gcc_unreachable ();
4595     }
4596 }
4597   [(set_attr "type" "multi")
4598    (set (attr "length")
4599         (if_then_else (eq_attr "isa" "v9")
4600                       (const_int 3) (const_int 5)))])
4601
4602 (define_insn "udivsi3_sp64"
4603   [(set (match_operand:SI 0 "register_operand" "=r")
4604         (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r")
4605                  (match_operand:SI 2 "input_operand" "rI")))]
4606   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4607   "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
4608   [(set_attr "type" "multi")
4609    (set_attr "length" "2")])
4610
4611 (define_insn "udivdi3"
4612   [(set (match_operand:DI 0 "register_operand" "=r")
4613         (udiv:DI (match_operand:DI 1 "register_operand" "r")
4614                  (match_operand:DI 2 "arith_operand" "rI")))]
4615   "TARGET_ARCH64"
4616   "udivx\t%1, %2, %0"
4617   [(set_attr "type" "idiv")])
4618
4619 (define_insn "*cmp_udiv_cc_set"
4620   [(set (reg:CC CC_REG)
4621         (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
4622                              (match_operand:SI 2 "arith_operand" "rI"))
4623                     (const_int 0)))
4624    (set (match_operand:SI 0 "register_operand" "=r")
4625         (udiv:SI (match_dup 1) (match_dup 2)))]
4626   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4627 {
4628   output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4629
4630   if (TARGET_V9)
4631     return "udivcc\t%1, %2, %0";
4632   else
4633     return "nop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
4634 }
4635   [(set_attr "type" "multi")
4636    (set (attr "length")
4637         (if_then_else (eq_attr "isa" "v9")
4638                       (const_int 2) (const_int 5)))])
4639
4640 ; sparclet multiply/accumulate insns
4641
4642 (define_insn "*smacsi"
4643   [(set (match_operand:SI 0 "register_operand" "=r")
4644         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
4645                           (match_operand:SI 2 "arith_operand" "rI"))
4646                  (match_operand:SI 3 "register_operand" "0")))]
4647   "TARGET_SPARCLET"
4648   "smac\t%1, %2, %0"
4649   [(set_attr "type" "imul")])
4650
4651 (define_insn "*smacdi"
4652   [(set (match_operand:DI 0 "register_operand" "=r")
4653         (plus:DI (mult:DI (sign_extend:DI
4654                            (match_operand:SI 1 "register_operand" "%r"))
4655                           (sign_extend:DI
4656                            (match_operand:SI 2 "register_operand" "r")))
4657                  (match_operand:DI 3 "register_operand" "0")))]
4658   "TARGET_SPARCLET"
4659   "smacd\t%1, %2, %L0"
4660   [(set_attr "type" "imul")])
4661
4662 (define_insn "*umacdi"
4663   [(set (match_operand:DI 0 "register_operand" "=r")
4664         (plus:DI (mult:DI (zero_extend:DI
4665                            (match_operand:SI 1 "register_operand" "%r"))
4666                           (zero_extend:DI
4667                            (match_operand:SI 2 "register_operand" "r")))
4668                  (match_operand:DI 3 "register_operand" "0")))]
4669   "TARGET_SPARCLET"
4670   "umacd\t%1, %2, %L0"
4671   [(set_attr "type" "imul")])
4672
4673
4674 ;; Boolean instructions.
4675
4676 ;; We define DImode `and' so with DImode `not' we can get
4677 ;; DImode `andn'.  Other combinations are possible.
4678
4679 (define_expand "and<V64I:mode>3"
4680   [(set (match_operand:V64I 0 "register_operand" "")
4681         (and:V64I (match_operand:V64I 1 "arith_double_operand" "")
4682                   (match_operand:V64I 2 "arith_double_operand" "")))]
4683   ""
4684   "")
4685
4686 (define_insn "*and<V64I:mode>3_sp32"
4687   [(set (match_operand:V64I 0 "register_operand" "=r,b")
4688         (and:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
4689                   (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
4690   "! TARGET_ARCH64"
4691   "@
4692   #
4693   fand\t%1, %2, %0"
4694   [(set_attr "type" "*,fga")
4695    (set_attr "length" "2,*")
4696    (set_attr "fptype" "*,double")])
4697
4698 (define_insn "*and<V64I:mode>3_sp64"
4699   [(set (match_operand:V64I 0 "register_operand" "=r,b")
4700         (and:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
4701                   (match_operand:V64I 2 "arith_operand" "rI,b")))]
4702   "TARGET_ARCH64"
4703   "@
4704    and\t%1, %2, %0
4705    fand\t%1, %2, %0"
4706   [(set_attr "type" "*,fga")
4707    (set_attr "fptype" "*,double")])
4708
4709 (define_insn "and<V32I:mode>3"
4710   [(set (match_operand:V32I 0 "register_operand" "=r,d")
4711         (and:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
4712                   (match_operand:V32I 2 "arith_operand" "rI,d")))]
4713   ""
4714   "@
4715    and\t%1, %2, %0
4716    fands\t%1, %2, %0"
4717   [(set_attr "type" "*,fga")
4718    (set_attr "fptype" "*,single")])
4719
4720 (define_split
4721   [(set (match_operand:SI 0 "register_operand" "")
4722         (and:SI (match_operand:SI 1 "register_operand" "")
4723                 (match_operand:SI 2 "const_compl_high_operand" "")))
4724    (clobber (match_operand:SI 3 "register_operand" ""))]
4725   ""
4726   [(set (match_dup 3) (match_dup 4))
4727    (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
4728 {
4729   operands[4] = GEN_INT (~INTVAL (operands[2]));
4730 })
4731
4732 (define_insn_and_split "*and_not_<V64I:mode>_sp32"
4733   [(set (match_operand:V64I 0 "register_operand" "=r,b")
4734         (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
4735                   (match_operand:V64I 2 "register_operand" "r,b")))]
4736   "! TARGET_ARCH64"
4737   "@
4738    #
4739    fandnot1\t%1, %2, %0"
4740   "&& reload_completed
4741    && ((GET_CODE (operands[0]) == REG
4742         && REGNO (operands[0]) < 32)
4743        || (GET_CODE (operands[0]) == SUBREG
4744            && GET_CODE (SUBREG_REG (operands[0])) == REG
4745            && REGNO (SUBREG_REG (operands[0])) < 32))"
4746   [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
4747    (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
4748   "operands[3] = gen_highpart (SImode, operands[0]);
4749    operands[4] = gen_highpart (SImode, operands[1]);
4750    operands[5] = gen_highpart (SImode, operands[2]);
4751    operands[6] = gen_lowpart (SImode, operands[0]);
4752    operands[7] = gen_lowpart (SImode, operands[1]);
4753    operands[8] = gen_lowpart (SImode, operands[2]);"
4754   [(set_attr "type" "*,fga")
4755    (set_attr "length" "2,*")
4756    (set_attr "fptype" "*,double")])
4757
4758 (define_insn "*and_not_<V64I:mode>_sp64"
4759   [(set (match_operand:V64I 0 "register_operand" "=r,b")
4760         (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
4761                   (match_operand:V64I 2 "register_operand" "r,b")))]
4762   "TARGET_ARCH64"
4763   "@
4764    andn\t%2, %1, %0
4765    fandnot1\t%1, %2, %0"
4766   [(set_attr "type" "*,fga")
4767    (set_attr "fptype" "*,double")])
4768
4769 (define_insn "*and_not_<V32I:mode>"
4770   [(set (match_operand:V32I 0 "register_operand" "=r,d")
4771         (and:V32I (not:V32I (match_operand:V32I 1 "register_operand" "%r,d"))
4772                   (match_operand:V32I 2 "register_operand" "r,d")))]
4773   ""
4774   "@
4775    andn\t%2, %1, %0
4776    fandnot1s\t%1, %2, %0"
4777   [(set_attr "type" "*,fga")
4778    (set_attr "fptype" "*,single")])
4779
4780 (define_expand "ior<V64I:mode>3"
4781   [(set (match_operand:V64I 0 "register_operand" "")
4782         (ior:V64I (match_operand:V64I 1 "arith_double_operand" "")
4783                   (match_operand:V64I 2 "arith_double_operand" "")))]
4784   ""
4785   "")
4786
4787 (define_insn "*ior<V64I:mode>3_sp32"
4788   [(set (match_operand:V64I 0 "register_operand" "=r,b")
4789         (ior:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
4790                   (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
4791   "! TARGET_ARCH64"
4792   "@
4793   #
4794   for\t%1, %2, %0"
4795   [(set_attr "type" "*,fga")
4796    (set_attr "length" "2,*")
4797    (set_attr "fptype" "*,double")])
4798
4799 (define_insn "*ior<V64I:mode>3_sp64"
4800   [(set (match_operand:V64I 0 "register_operand" "=r,b")
4801         (ior:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
4802                   (match_operand:V64I 2 "arith_operand" "rI,b")))]
4803   "TARGET_ARCH64"
4804   "@
4805   or\t%1, %2, %0
4806   for\t%1, %2, %0"
4807   [(set_attr "type" "*,fga")
4808    (set_attr "fptype" "*,double")])
4809
4810 (define_insn "ior<V32I:mode>3"
4811   [(set (match_operand:V32I 0 "register_operand" "=r,d")
4812         (ior:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
4813                   (match_operand:V32I 2 "arith_operand" "rI,d")))]
4814   ""
4815   "@
4816    or\t%1, %2, %0
4817    fors\t%1, %2, %0"
4818   [(set_attr "type" "*,fga")
4819    (set_attr "fptype" "*,single")])
4820
4821 (define_split
4822   [(set (match_operand:SI 0 "register_operand" "")
4823         (ior:SI (match_operand:SI 1 "register_operand" "")
4824                 (match_operand:SI 2 "const_compl_high_operand" "")))
4825    (clobber (match_operand:SI 3 "register_operand" ""))]
4826   ""
4827   [(set (match_dup 3) (match_dup 4))
4828    (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
4829 {
4830   operands[4] = GEN_INT (~INTVAL (operands[2]));
4831 })
4832
4833 (define_insn_and_split "*or_not_<V64I:mode>_sp32"
4834   [(set (match_operand:V64I 0 "register_operand" "=r,b")
4835         (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
4836                   (match_operand:V64I 2 "register_operand" "r,b")))]
4837   "! TARGET_ARCH64"
4838   "@
4839    #
4840    fornot1\t%1, %2, %0"
4841   "&& reload_completed
4842    && ((GET_CODE (operands[0]) == REG
4843         && REGNO (operands[0]) < 32)
4844        || (GET_CODE (operands[0]) == SUBREG
4845            && GET_CODE (SUBREG_REG (operands[0])) == REG
4846            && REGNO (SUBREG_REG (operands[0])) < 32))"
4847   [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
4848    (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
4849   "operands[3] = gen_highpart (SImode, operands[0]);
4850    operands[4] = gen_highpart (SImode, operands[1]);
4851    operands[5] = gen_highpart (SImode, operands[2]);
4852    operands[6] = gen_lowpart (SImode, operands[0]);
4853    operands[7] = gen_lowpart (SImode, operands[1]);
4854    operands[8] = gen_lowpart (SImode, operands[2]);"
4855   [(set_attr "type" "*,fga")
4856    (set_attr "length" "2,*")
4857    (set_attr "fptype" "*,double")])
4858
4859 (define_insn "*or_not_<V64I:mode>_sp64"
4860   [(set (match_operand:V64I 0 "register_operand" "=r,b")
4861         (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
4862                   (match_operand:V64I 2 "register_operand" "r,b")))]
4863   "TARGET_ARCH64"
4864   "@
4865   orn\t%2, %1, %0
4866   fornot1\t%1, %2, %0"
4867   [(set_attr "type" "*,fga")
4868    (set_attr "fptype" "*,double")])
4869
4870 (define_insn "*or_not_<V32I:mode>"
4871   [(set (match_operand:V32I 0 "register_operand" "=r,d")
4872         (ior:V32I (not:V32I (match_operand:V32I 1 "register_operand" "r,d"))
4873                   (match_operand:V32I 2 "register_operand" "r,d")))]
4874   ""
4875   "@
4876    orn\t%2, %1, %0
4877    fornot1s\t%1, %2, %0"
4878   [(set_attr "type" "*,fga")
4879    (set_attr "fptype" "*,single")])
4880
4881 (define_expand "xor<V64I:mode>3"
4882   [(set (match_operand:V64I 0 "register_operand" "")
4883         (xor:V64I (match_operand:V64I 1 "arith_double_operand" "")
4884                   (match_operand:V64I 2 "arith_double_operand" "")))]
4885   ""
4886   "")
4887
4888 (define_insn "*xor<V64I:mode>3_sp32"
4889   [(set (match_operand:V64I 0 "register_operand" "=r,b")
4890         (xor:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
4891                   (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
4892   "! TARGET_ARCH64"
4893   "@
4894   #
4895   fxor\t%1, %2, %0"
4896   [(set_attr "type" "*,fga")
4897    (set_attr "length" "2,*")
4898    (set_attr "fptype" "*,double")])
4899
4900 (define_insn "*xor<V64I:mode>3_sp64"
4901   [(set (match_operand:V64I 0 "register_operand" "=r,b")
4902         (xor:V64I (match_operand:V64I 1 "arith_operand" "%rJ,b")
4903                   (match_operand:V64I 2 "arith_operand" "rI,b")))]
4904   "TARGET_ARCH64"
4905   "@
4906   xor\t%r1, %2, %0
4907   fxor\t%1, %2, %0"
4908   [(set_attr "type" "*,fga")
4909    (set_attr "fptype" "*,double")])
4910
4911 (define_insn "xor<V32I:mode>3"
4912   [(set (match_operand:V32I 0 "register_operand" "=r,d")
4913         (xor:V32I (match_operand:V32I 1 "arith_operand" "%rJ,d")
4914                   (match_operand:V32I 2 "arith_operand" "rI,d")))]
4915   ""
4916   "@
4917    xor\t%r1, %2, %0
4918    fxors\t%1, %2, %0"
4919   [(set_attr "type" "*,fga")
4920    (set_attr "fptype" "*,single")])
4921
4922 (define_split
4923   [(set (match_operand:SI 0 "register_operand" "")
4924         (xor:SI (match_operand:SI 1 "register_operand" "")
4925                 (match_operand:SI 2 "const_compl_high_operand" "")))
4926    (clobber (match_operand:SI 3 "register_operand" ""))]
4927    ""
4928   [(set (match_dup 3) (match_dup 4))
4929    (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
4930 {
4931   operands[4] = GEN_INT (~INTVAL (operands[2]));
4932 })
4933
4934 (define_split
4935   [(set (match_operand:SI 0 "register_operand" "")
4936         (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
4937                         (match_operand:SI 2 "const_compl_high_operand" ""))))
4938    (clobber (match_operand:SI 3 "register_operand" ""))]
4939   ""
4940   [(set (match_dup 3) (match_dup 4))
4941    (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
4942 {
4943   operands[4] = GEN_INT (~INTVAL (operands[2]));
4944 })
4945
4946 ;; Split DImode logical operations requiring two instructions.
4947 (define_split
4948   [(set (match_operand:V64I 0 "register_operand" "")
4949         (match_operator:V64I 1 "cc_arith_operator"      ; AND, IOR, XOR
4950                            [(match_operand:V64I 2 "register_operand" "")
4951                             (match_operand:V64I 3 "arith_double_operand" "")]))]
4952   "! TARGET_ARCH64
4953    && reload_completed
4954    && ((GET_CODE (operands[0]) == REG
4955         && REGNO (operands[0]) < 32)
4956        || (GET_CODE (operands[0]) == SUBREG
4957            && GET_CODE (SUBREG_REG (operands[0])) == REG
4958            && REGNO (SUBREG_REG (operands[0])) < 32))"
4959   [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
4960    (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
4961 {
4962   operands[4] = gen_highpart (SImode, operands[0]);
4963   operands[5] = gen_lowpart (SImode, operands[0]);
4964   operands[6] = gen_highpart (SImode, operands[2]);
4965   operands[7] = gen_lowpart (SImode, operands[2]);
4966 #if HOST_BITS_PER_WIDE_INT == 32
4967   if (GET_CODE (operands[3]) == CONST_INT && <V64I:MODE>mode == DImode)
4968     {
4969       if (INTVAL (operands[3]) < 0)
4970         operands[8] = constm1_rtx;
4971       else
4972         operands[8] = const0_rtx;
4973     }
4974   else
4975 #endif
4976     operands[8] = gen_highpart_mode (SImode, <V64I:MODE>mode, operands[3]);
4977   operands[9] = gen_lowpart (SImode, operands[3]);
4978 })
4979
4980 ;; xnor patterns.  Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
4981 ;; Combine now canonicalizes to the rightmost expression.
4982 (define_insn_and_split "*xor_not_<V64I:mode>_sp32"
4983   [(set (match_operand:V64I 0 "register_operand" "=r,b")
4984         (not:V64I (xor:V64I (match_operand:V64I 1 "register_operand" "r,b")
4985                             (match_operand:V64I 2 "register_operand" "r,b"))))]
4986   "! TARGET_ARCH64"
4987   "@
4988    #
4989    fxnor\t%1, %2, %0"
4990   "&& reload_completed
4991    && ((GET_CODE (operands[0]) == REG
4992         && REGNO (operands[0]) < 32)
4993        || (GET_CODE (operands[0]) == SUBREG
4994            && GET_CODE (SUBREG_REG (operands[0])) == REG
4995            && REGNO (SUBREG_REG (operands[0])) < 32))"
4996   [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
4997    (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
4998   "operands[3] = gen_highpart (SImode, operands[0]);
4999    operands[4] = gen_highpart (SImode, operands[1]);
5000    operands[5] = gen_highpart (SImode, operands[2]);
5001    operands[6] = gen_lowpart (SImode, operands[0]);
5002    operands[7] = gen_lowpart (SImode, operands[1]);
5003    operands[8] = gen_lowpart (SImode, operands[2]);"
5004   [(set_attr "type" "*,fga")
5005    (set_attr "length" "2,*")
5006    (set_attr "fptype" "*,double")])
5007
5008 (define_insn "*xor_not_<V64I:mode>_sp64"
5009   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5010         (not:V64I (xor:V64I (match_operand:V64I 1 "register_or_zero_operand" "rJ,b")
5011                             (match_operand:V64I 2 "arith_operand" "rI,b"))))]
5012   "TARGET_ARCH64"
5013   "@
5014   xnor\t%r1, %2, %0
5015   fxnor\t%1, %2, %0"
5016   [(set_attr "type" "*,fga")
5017    (set_attr "fptype" "*,double")])
5018
5019 (define_insn "*xor_not_<V32I:mode>"
5020   [(set (match_operand:V32I 0 "register_operand" "=r,d")
5021         (not:V32I (xor:V32I (match_operand:V32I 1 "register_or_zero_operand" "rJ,d")
5022                             (match_operand:V32I 2 "arith_operand" "rI,d"))))]
5023   ""
5024   "@
5025    xnor\t%r1, %2, %0
5026    fxnors\t%1, %2, %0"
5027   [(set_attr "type" "*,fga")
5028    (set_attr "fptype" "*,single")])
5029
5030 ;; These correspond to the above in the case where we also (or only)
5031 ;; want to set the condition code.  
5032
5033 (define_insn "*cmp_cc_arith_op"
5034   [(set (reg:CC CC_REG)
5035         (compare:CC
5036          (match_operator:SI 2 "cc_arith_operator"
5037                             [(match_operand:SI 0 "arith_operand" "%r")
5038                              (match_operand:SI 1 "arith_operand" "rI")])
5039          (const_int 0)))]
5040   ""
5041   "%A2cc\t%0, %1, %%g0"
5042   [(set_attr "type" "compare")])
5043
5044 (define_insn "*cmp_ccx_arith_op"
5045   [(set (reg:CCX CC_REG)
5046         (compare:CCX
5047          (match_operator:DI 2 "cc_arith_operator"
5048                             [(match_operand:DI 0 "arith_operand" "%r")
5049                              (match_operand:DI 1 "arith_operand" "rI")])
5050          (const_int 0)))]
5051   "TARGET_ARCH64"
5052   "%A2cc\t%0, %1, %%g0"
5053   [(set_attr "type" "compare")])
5054
5055 (define_insn "*cmp_cc_arith_op_set"
5056   [(set (reg:CC CC_REG)
5057         (compare:CC
5058          (match_operator:SI 3 "cc_arith_operator"
5059                             [(match_operand:SI 1 "arith_operand" "%r")
5060                              (match_operand:SI 2 "arith_operand" "rI")])
5061          (const_int 0)))
5062    (set (match_operand:SI 0 "register_operand" "=r")
5063         (match_operator:SI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5064   "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5065   "%A3cc\t%1, %2, %0"
5066   [(set_attr "type" "compare")])
5067
5068 (define_insn "*cmp_ccx_arith_op_set"
5069   [(set (reg:CCX CC_REG)
5070         (compare:CCX
5071          (match_operator:DI 3 "cc_arith_operator"
5072                             [(match_operand:DI 1 "arith_operand" "%r")
5073                              (match_operand:DI 2 "arith_operand" "rI")])
5074          (const_int 0)))
5075    (set (match_operand:DI 0 "register_operand" "=r")
5076         (match_operator:DI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5077   "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5078   "%A3cc\t%1, %2, %0"
5079   [(set_attr "type" "compare")])
5080
5081 (define_insn "*cmp_cc_xor_not"
5082   [(set (reg:CC CC_REG)
5083         (compare:CC
5084          (not:SI (xor:SI (match_operand:SI 0 "register_or_zero_operand" "%rJ")
5085                          (match_operand:SI 1 "arith_operand" "rI")))
5086          (const_int 0)))]
5087   ""
5088   "xnorcc\t%r0, %1, %%g0"
5089   [(set_attr "type" "compare")])
5090
5091 (define_insn "*cmp_ccx_xor_not"
5092   [(set (reg:CCX CC_REG)
5093         (compare:CCX
5094          (not:DI (xor:DI (match_operand:DI 0 "register_or_zero_operand" "%rJ")
5095                          (match_operand:DI 1 "arith_operand" "rI")))
5096          (const_int 0)))]
5097   "TARGET_ARCH64"
5098   "xnorcc\t%r0, %1, %%g0"
5099   [(set_attr "type" "compare")])
5100
5101 (define_insn "*cmp_cc_xor_not_set"
5102   [(set (reg:CC CC_REG)
5103         (compare:CC
5104          (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
5105                          (match_operand:SI 2 "arith_operand" "rI")))
5106          (const_int 0)))
5107    (set (match_operand:SI 0 "register_operand" "=r")
5108         (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
5109   ""
5110   "xnorcc\t%r1, %2, %0"
5111   [(set_attr "type" "compare")])
5112
5113 (define_insn "*cmp_ccx_xor_not_set"
5114   [(set (reg:CCX CC_REG)
5115         (compare:CCX
5116          (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
5117                          (match_operand:DI 2 "arith_operand" "rI")))
5118          (const_int 0)))
5119    (set (match_operand:DI 0 "register_operand" "=r")
5120         (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
5121   "TARGET_ARCH64"
5122   "xnorcc\t%r1, %2, %0"
5123   [(set_attr "type" "compare")])
5124
5125 (define_insn "*cmp_cc_arith_op_not"
5126   [(set (reg:CC CC_REG)
5127         (compare:CC
5128          (match_operator:SI 2 "cc_arith_not_operator"
5129                             [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
5130                              (match_operand:SI 1 "register_or_zero_operand" "rJ")])
5131          (const_int 0)))]
5132   ""
5133   "%B2cc\t%r1, %0, %%g0"
5134   [(set_attr "type" "compare")])
5135
5136 (define_insn "*cmp_ccx_arith_op_not"
5137   [(set (reg:CCX CC_REG)
5138         (compare:CCX
5139          (match_operator:DI 2 "cc_arith_not_operator"
5140                             [(not:DI (match_operand:DI 0 "arith_operand" "rI"))
5141                              (match_operand:DI 1 "register_or_zero_operand" "rJ")])
5142          (const_int 0)))]
5143   "TARGET_ARCH64"
5144   "%B2cc\t%r1, %0, %%g0"
5145   [(set_attr "type" "compare")])
5146
5147 (define_insn "*cmp_cc_arith_op_not_set"
5148   [(set (reg:CC CC_REG)
5149         (compare:CC
5150          (match_operator:SI 3 "cc_arith_not_operator"
5151                             [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
5152                              (match_operand:SI 2 "register_or_zero_operand" "rJ")])
5153          (const_int 0)))
5154    (set (match_operand:SI 0 "register_operand" "=r")
5155         (match_operator:SI 4 "cc_arith_not_operator"
5156                             [(not:SI (match_dup 1)) (match_dup 2)]))]
5157   "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5158   "%B3cc\t%r2, %1, %0"
5159   [(set_attr "type" "compare")])
5160
5161 (define_insn "*cmp_ccx_arith_op_not_set"
5162   [(set (reg:CCX CC_REG)
5163         (compare:CCX
5164          (match_operator:DI 3 "cc_arith_not_operator"
5165                             [(not:DI (match_operand:DI 1 "arith_operand" "rI"))
5166                              (match_operand:DI 2 "register_or_zero_operand" "rJ")])
5167          (const_int 0)))
5168    (set (match_operand:DI 0 "register_operand" "=r")
5169         (match_operator:DI 4 "cc_arith_not_operator"
5170                             [(not:DI (match_dup 1)) (match_dup 2)]))]
5171   "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5172   "%B3cc\t%r2, %1, %0"
5173   [(set_attr "type" "compare")])
5174
5175 ;; We cannot use the "neg" pseudo insn because the Sun assembler
5176 ;; does not know how to make it work for constants.
5177
5178 (define_expand "negdi2"
5179   [(set (match_operand:DI 0 "register_operand" "=r")
5180         (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5181   ""
5182 {
5183   if (! TARGET_ARCH64)
5184     {
5185       emit_insn (gen_rtx_PARALLEL
5186                  (VOIDmode,
5187                   gen_rtvec (2,
5188                              gen_rtx_SET (VOIDmode, operand0,
5189                                           gen_rtx_NEG (DImode, operand1)),
5190                              gen_rtx_CLOBBER (VOIDmode,
5191                                               gen_rtx_REG (CCmode,
5192                                                            SPARC_ICC_REG)))));
5193       DONE;
5194     }
5195 })
5196
5197 (define_insn_and_split "*negdi2_sp32"
5198   [(set (match_operand:DI 0 "register_operand" "=r")
5199         (neg:DI (match_operand:DI 1 "register_operand" "r")))
5200    (clobber (reg:CC CC_REG))]
5201   "! TARGET_ARCH64"
5202   "#"
5203   "&& reload_completed"
5204   [(parallel [(set (reg:CC_NOOV CC_REG)
5205                    (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
5206                                     (const_int 0)))
5207               (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
5208    (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
5209                                 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
5210   "operands[2] = gen_highpart (SImode, operands[0]);
5211    operands[3] = gen_highpart (SImode, operands[1]);
5212    operands[4] = gen_lowpart (SImode, operands[0]);
5213    operands[5] = gen_lowpart (SImode, operands[1]);"
5214   [(set_attr "length" "2")])
5215
5216 (define_insn "*negdi2_sp64"
5217   [(set (match_operand:DI 0 "register_operand" "=r")
5218         (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5219   "TARGET_ARCH64"
5220   "sub\t%%g0, %1, %0")
5221
5222 (define_insn "negsi2"
5223   [(set (match_operand:SI 0 "register_operand" "=r")
5224         (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
5225   ""
5226   "sub\t%%g0, %1, %0")
5227
5228 (define_insn "*cmp_cc_neg"
5229   [(set (reg:CC_NOOV CC_REG)
5230         (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
5231                          (const_int 0)))]
5232   ""
5233   "subcc\t%%g0, %0, %%g0"
5234   [(set_attr "type" "compare")])
5235
5236 (define_insn "*cmp_ccx_neg"
5237   [(set (reg:CCX_NOOV CC_REG)
5238         (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_operand" "rI"))
5239                           (const_int 0)))]
5240   "TARGET_ARCH64"
5241   "subcc\t%%g0, %0, %%g0"
5242   [(set_attr "type" "compare")])
5243
5244 (define_insn "*cmp_cc_set_neg"
5245   [(set (reg:CC_NOOV CC_REG)
5246         (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
5247                          (const_int 0)))
5248    (set (match_operand:SI 0 "register_operand" "=r")
5249         (neg:SI (match_dup 1)))]
5250   ""
5251   "subcc\t%%g0, %1, %0"
5252   [(set_attr "type" "compare")])
5253
5254 (define_insn "*cmp_ccx_set_neg"
5255   [(set (reg:CCX_NOOV CC_REG)
5256         (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_operand" "rI"))
5257                           (const_int 0)))
5258    (set (match_operand:DI 0 "register_operand" "=r")
5259         (neg:DI (match_dup 1)))]
5260   "TARGET_ARCH64"
5261   "subcc\t%%g0, %1, %0"
5262   [(set_attr "type" "compare")])
5263
5264 ;; We cannot use the "not" pseudo insn because the Sun assembler
5265 ;; does not know how to make it work for constants.
5266 (define_expand "one_cmpl<V64I:mode>2"
5267   [(set (match_operand:V64I 0 "register_operand" "")
5268         (not:V64I (match_operand:V64I 1 "register_operand" "")))]
5269   ""
5270   "")
5271
5272 (define_insn_and_split "*one_cmpl<V64I:mode>2_sp32"
5273   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5274         (not:V64I (match_operand:V64I 1 "register_operand" "r,b")))]
5275   "! TARGET_ARCH64"
5276   "@
5277    #
5278    fnot1\t%1, %0"
5279   "&& reload_completed
5280    && ((GET_CODE (operands[0]) == REG
5281         && REGNO (operands[0]) < 32)
5282        || (GET_CODE (operands[0]) == SUBREG
5283            && GET_CODE (SUBREG_REG (operands[0])) == REG
5284            && REGNO (SUBREG_REG (operands[0])) < 32))"
5285   [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
5286    (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
5287   "operands[2] = gen_highpart (SImode, operands[0]);
5288    operands[3] = gen_highpart (SImode, operands[1]);
5289    operands[4] = gen_lowpart (SImode, operands[0]);
5290    operands[5] = gen_lowpart (SImode, operands[1]);"
5291   [(set_attr "type" "*,fga")
5292    (set_attr "length" "2,*")
5293    (set_attr "fptype" "*,double")])
5294
5295 (define_insn "*one_cmpl<V64I:mode>2_sp64"
5296   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5297         (not:V64I (match_operand:V64I 1 "arith_operand" "rI,b")))]
5298   "TARGET_ARCH64"
5299   "@
5300    xnor\t%%g0, %1, %0
5301    fnot1\t%1, %0"
5302   [(set_attr "type" "*,fga")
5303    (set_attr "fptype" "*,double")])
5304
5305 (define_insn "one_cmpl<V32I:mode>2"
5306   [(set (match_operand:V32I 0 "register_operand" "=r,d")
5307         (not:V32I (match_operand:V32I 1 "arith_operand" "rI,d")))]
5308   ""
5309   "@
5310   xnor\t%%g0, %1, %0
5311   fnot1s\t%1, %0"
5312   [(set_attr "type" "*,fga")
5313    (set_attr "fptype" "*,single")])
5314
5315 (define_insn "*cmp_cc_not"
5316   [(set (reg:CC CC_REG)
5317         (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
5318                     (const_int 0)))]
5319   ""
5320   "xnorcc\t%%g0, %0, %%g0"
5321   [(set_attr "type" "compare")])
5322
5323 (define_insn "*cmp_ccx_not"
5324   [(set (reg:CCX CC_REG)
5325         (compare:CCX (not:DI (match_operand:DI 0 "arith_operand" "rI"))
5326                      (const_int 0)))]
5327   "TARGET_ARCH64"
5328   "xnorcc\t%%g0, %0, %%g0"
5329   [(set_attr "type" "compare")])
5330
5331 (define_insn "*cmp_cc_set_not"
5332   [(set (reg:CC CC_REG)
5333         (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
5334                     (const_int 0)))
5335    (set (match_operand:SI 0 "register_operand" "=r")
5336         (not:SI (match_dup 1)))]
5337   ""
5338   "xnorcc\t%%g0, %1, %0"
5339   [(set_attr "type" "compare")])
5340
5341 (define_insn "*cmp_ccx_set_not"
5342   [(set (reg:CCX CC_REG)
5343         (compare:CCX (not:DI (match_operand:DI 1 "arith_operand" "rI"))
5344                     (const_int 0)))
5345    (set (match_operand:DI 0 "register_operand" "=r")
5346         (not:DI (match_dup 1)))]
5347   "TARGET_ARCH64"
5348   "xnorcc\t%%g0, %1, %0"
5349   [(set_attr "type" "compare")])
5350
5351 (define_insn "*cmp_cc_set"
5352   [(set (match_operand:SI 0 "register_operand" "=r")
5353         (match_operand:SI 1 "register_operand" "r"))
5354    (set (reg:CC CC_REG)
5355         (compare:CC (match_dup 1)
5356                     (const_int 0)))]
5357   ""
5358   "orcc\t%1, 0, %0"
5359   [(set_attr "type" "compare")])
5360
5361 (define_insn "*cmp_ccx_set64"
5362   [(set (match_operand:DI 0 "register_operand" "=r")
5363         (match_operand:DI 1 "register_operand" "r"))
5364    (set (reg:CCX CC_REG)
5365         (compare:CCX (match_dup 1)
5366                      (const_int 0)))]
5367   "TARGET_ARCH64"
5368   "orcc\t%1, 0, %0"
5369    [(set_attr "type" "compare")])
5370
5371
5372 ;; Floating point arithmetic instructions.
5373
5374 (define_expand "addtf3"
5375   [(set (match_operand:TF 0 "nonimmediate_operand" "")
5376         (plus:TF (match_operand:TF 1 "general_operand" "")
5377                  (match_operand:TF 2 "general_operand" "")))]
5378   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5379   "emit_tfmode_binop (PLUS, operands); DONE;")
5380
5381 (define_insn "*addtf3_hq"
5382   [(set (match_operand:TF 0 "register_operand" "=e")
5383         (plus:TF (match_operand:TF 1 "register_operand" "e")
5384                  (match_operand:TF 2 "register_operand" "e")))]
5385   "TARGET_FPU && TARGET_HARD_QUAD"
5386   "faddq\t%1, %2, %0"
5387   [(set_attr "type" "fp")])
5388
5389 (define_insn "adddf3"
5390   [(set (match_operand:DF 0 "register_operand" "=e")
5391         (plus:DF (match_operand:DF 1 "register_operand" "e")
5392                  (match_operand:DF 2 "register_operand" "e")))]
5393   "TARGET_FPU"
5394   "faddd\t%1, %2, %0"
5395   [(set_attr "type" "fp")
5396    (set_attr "fptype" "double")])
5397
5398 (define_insn "addsf3"
5399   [(set (match_operand:SF 0 "register_operand" "=f")
5400         (plus:SF (match_operand:SF 1 "register_operand" "f")
5401                  (match_operand:SF 2 "register_operand" "f")))]
5402   "TARGET_FPU"
5403   "fadds\t%1, %2, %0"
5404   [(set_attr "type" "fp")])
5405
5406 (define_expand "subtf3"
5407   [(set (match_operand:TF 0 "nonimmediate_operand" "")
5408         (minus:TF (match_operand:TF 1 "general_operand" "")
5409                   (match_operand:TF 2 "general_operand" "")))]
5410   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5411   "emit_tfmode_binop (MINUS, operands); DONE;")
5412
5413 (define_insn "*subtf3_hq"
5414   [(set (match_operand:TF 0 "register_operand" "=e")
5415         (minus:TF (match_operand:TF 1 "register_operand" "e")
5416                   (match_operand:TF 2 "register_operand" "e")))]
5417   "TARGET_FPU && TARGET_HARD_QUAD"
5418   "fsubq\t%1, %2, %0"
5419   [(set_attr "type" "fp")])
5420
5421 (define_insn "subdf3"
5422   [(set (match_operand:DF 0 "register_operand" "=e")
5423         (minus:DF (match_operand:DF 1 "register_operand" "e")
5424                   (match_operand:DF 2 "register_operand" "e")))]
5425   "TARGET_FPU"
5426   "fsubd\t%1, %2, %0"
5427   [(set_attr "type" "fp")
5428    (set_attr "fptype" "double")])
5429
5430 (define_insn "subsf3"
5431   [(set (match_operand:SF 0 "register_operand" "=f")
5432         (minus:SF (match_operand:SF 1 "register_operand" "f")
5433                   (match_operand:SF 2 "register_operand" "f")))]
5434   "TARGET_FPU"
5435   "fsubs\t%1, %2, %0"
5436   [(set_attr "type" "fp")])
5437
5438 (define_expand "multf3"
5439   [(set (match_operand:TF 0 "nonimmediate_operand" "")
5440         (mult:TF (match_operand:TF 1 "general_operand" "")
5441                  (match_operand:TF 2 "general_operand" "")))]
5442   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5443   "emit_tfmode_binop (MULT, operands); DONE;")
5444
5445 (define_insn "*multf3_hq"
5446   [(set (match_operand:TF 0 "register_operand" "=e")
5447         (mult:TF (match_operand:TF 1 "register_operand" "e")
5448                  (match_operand:TF 2 "register_operand" "e")))]
5449   "TARGET_FPU && TARGET_HARD_QUAD"
5450   "fmulq\t%1, %2, %0"
5451   [(set_attr "type" "fpmul")])
5452
5453 (define_insn "muldf3"
5454   [(set (match_operand:DF 0 "register_operand" "=e")
5455         (mult:DF (match_operand:DF 1 "register_operand" "e")
5456                  (match_operand:DF 2 "register_operand" "e")))]
5457   "TARGET_FPU"
5458   "fmuld\t%1, %2, %0"
5459   [(set_attr "type" "fpmul")
5460    (set_attr "fptype" "double")])
5461
5462 (define_insn "mulsf3"
5463   [(set (match_operand:SF 0 "register_operand" "=f")
5464         (mult:SF (match_operand:SF 1 "register_operand" "f")
5465                  (match_operand:SF 2 "register_operand" "f")))]
5466   "TARGET_FPU"
5467   "fmuls\t%1, %2, %0"
5468   [(set_attr "type" "fpmul")])
5469
5470 (define_insn "fmadf4"
5471   [(set (match_operand:DF 0 "register_operand" "=e")
5472         (fma:DF (match_operand:DF 1 "register_operand" "e")
5473                 (match_operand:DF 2 "register_operand" "e")
5474                 (match_operand:DF 3 "register_operand" "e")))]
5475   "TARGET_FMAF"
5476   "fmaddd\t%1, %2, %3, %0"
5477   [(set_attr "type" "fpmul")])
5478
5479 (define_insn "fmsdf4"
5480   [(set (match_operand:DF 0 "register_operand" "=e")
5481         (fma:DF (match_operand:DF 1 "register_operand" "e")
5482                 (match_operand:DF 2 "register_operand" "e")
5483                 (neg:DF (match_operand:DF 3 "register_operand" "e"))))]
5484   "TARGET_FMAF"
5485   "fmsubd\t%1, %2, %3, %0"
5486   [(set_attr "type" "fpmul")])
5487
5488 (define_insn "*nfmadf4"
5489   [(set (match_operand:DF 0 "register_operand" "=e")
5490         (neg:DF (fma:DF (match_operand:DF 1 "register_operand" "e")
5491                         (match_operand:DF 2 "register_operand" "e")
5492                         (match_operand:DF 3 "register_operand" "e"))))]
5493   "TARGET_FMAF"
5494   "fnmaddd\t%1, %2, %3, %0"
5495   [(set_attr "type" "fpmul")])
5496
5497 (define_insn "*nfmsdf4"
5498   [(set (match_operand:DF 0 "register_operand" "=e")
5499         (neg:DF (fma:DF (match_operand:DF 1 "register_operand" "e")
5500                         (match_operand:DF 2 "register_operand" "e")
5501                         (neg:DF (match_operand:DF 3 "register_operand" "e")))))]
5502   "TARGET_FMAF"
5503   "fnmsubd\t%1, %2, %3, %0"
5504   [(set_attr "type" "fpmul")])
5505
5506 (define_insn "fmasf4"
5507   [(set (match_operand:SF 0 "register_operand" "=f")
5508         (fma:SF (match_operand:SF 1 "register_operand" "f")
5509                 (match_operand:SF 2 "register_operand" "f")
5510                 (match_operand:SF 3 "register_operand" "f")))]
5511   "TARGET_FMAF"
5512   "fmadds\t%1, %2, %3, %0"
5513   [(set_attr "type" "fpmul")])
5514
5515 (define_insn "fmssf4"
5516   [(set (match_operand:SF 0 "register_operand" "=f")
5517         (fma:SF (match_operand:SF 1 "register_operand" "f")
5518                 (match_operand:SF 2 "register_operand" "f")
5519                 (neg:SF (match_operand:SF 3 "register_operand" "f"))))]
5520   "TARGET_FMAF"
5521   "fmsubs\t%1, %2, %3, %0"
5522   [(set_attr "type" "fpmul")])
5523
5524 (define_insn "*nfmasf4"
5525   [(set (match_operand:SF 0 "register_operand" "=f")
5526         (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "f")
5527                         (match_operand:SF 2 "register_operand" "f")
5528                         (match_operand:SF 3 "register_operand" "f"))))]
5529   "TARGET_FMAF"
5530   "fnmadds\t%1, %2, %3, %0"
5531   [(set_attr "type" "fpmul")])
5532
5533 (define_insn "*nfmssf4"
5534   [(set (match_operand:SF 0 "register_operand" "=f")
5535         (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "f")
5536                         (match_operand:SF 2 "register_operand" "f")
5537                         (neg:SF (match_operand:SF 3 "register_operand" "f")))))]
5538   "TARGET_FMAF"
5539   "fnmsubs\t%1, %2, %3, %0"
5540   [(set_attr "type" "fpmul")])
5541
5542 (define_insn "*muldf3_extend"
5543   [(set (match_operand:DF 0 "register_operand" "=e")
5544         (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
5545                  (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
5546   "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
5547   "fsmuld\t%1, %2, %0"
5548   [(set_attr "type" "fpmul")
5549    (set_attr "fptype" "double")])
5550
5551 (define_insn "*multf3_extend"
5552   [(set (match_operand:TF 0 "register_operand" "=e")
5553         (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
5554                  (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
5555   "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
5556   "fdmulq\t%1, %2, %0"
5557   [(set_attr "type" "fpmul")])
5558
5559 (define_expand "divtf3"
5560   [(set (match_operand:TF 0 "nonimmediate_operand" "")
5561         (div:TF (match_operand:TF 1 "general_operand" "")
5562                 (match_operand:TF 2 "general_operand" "")))]
5563   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5564   "emit_tfmode_binop (DIV, operands); DONE;")
5565
5566 ;; don't have timing for quad-prec. divide.
5567 (define_insn "*divtf3_hq"
5568   [(set (match_operand:TF 0 "register_operand" "=e")
5569         (div:TF (match_operand:TF 1 "register_operand" "e")
5570                 (match_operand:TF 2 "register_operand" "e")))]
5571   "TARGET_FPU && TARGET_HARD_QUAD"
5572   "fdivq\t%1, %2, %0"
5573   [(set_attr "type" "fpdivd")])
5574
5575 (define_insn "divdf3"
5576   [(set (match_operand:DF 0 "register_operand" "=e")
5577         (div:DF (match_operand:DF 1 "register_operand" "e")
5578                 (match_operand:DF 2 "register_operand" "e")))]
5579   "TARGET_FPU"
5580   "fdivd\t%1, %2, %0"
5581   [(set_attr "type" "fpdivd")
5582    (set_attr "fptype" "double")])
5583
5584 (define_insn "divsf3"
5585   [(set (match_operand:SF 0 "register_operand" "=f")
5586         (div:SF (match_operand:SF 1 "register_operand" "f")
5587                 (match_operand:SF 2 "register_operand" "f")))]
5588   "TARGET_FPU"
5589   "fdivs\t%1, %2, %0"
5590   [(set_attr "type" "fpdivs")])
5591
5592 (define_expand "negtf2"
5593   [(set (match_operand:TF 0 "register_operand" "=e,e")
5594         (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5595   "TARGET_FPU"
5596   "")
5597
5598 (define_insn_and_split "*negtf2_notv9"
5599   [(set (match_operand:TF 0 "register_operand" "=e,e")
5600         (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5601   ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5602   "TARGET_FPU
5603    && ! TARGET_V9"
5604   "@
5605   fnegs\t%0, %0
5606   #"
5607   "&& reload_completed
5608    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5609   [(set (match_dup 2) (neg:SF (match_dup 3)))
5610    (set (match_dup 4) (match_dup 5))
5611    (set (match_dup 6) (match_dup 7))]
5612   "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5613    operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5614    operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5615    operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
5616    operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5617    operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5618   [(set_attr "type" "fpmove,*")
5619    (set_attr "length" "*,2")])
5620
5621 (define_insn_and_split "*negtf2_v9"
5622   [(set (match_operand:TF 0 "register_operand" "=e,e")
5623         (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5624   ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5625   "TARGET_FPU && TARGET_V9"
5626   "@
5627   fnegd\t%0, %0
5628   #"
5629   "&& reload_completed
5630    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5631   [(set (match_dup 2) (neg:DF (match_dup 3)))
5632    (set (match_dup 4) (match_dup 5))]
5633   "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
5634    operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
5635    operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5636    operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5637   [(set_attr "type" "fpmove,*")
5638    (set_attr "length" "*,2")
5639    (set_attr "fptype" "double")])
5640
5641 (define_expand "negdf2"
5642   [(set (match_operand:DF 0 "register_operand" "")
5643         (neg:DF (match_operand:DF 1 "register_operand" "")))]
5644   "TARGET_FPU"
5645   "")
5646
5647 (define_insn_and_split "*negdf2_notv9"
5648   [(set (match_operand:DF 0 "register_operand" "=e,e")
5649         (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
5650   "TARGET_FPU && ! TARGET_V9"
5651   "@
5652   fnegs\t%0, %0
5653   #"
5654   "&& reload_completed
5655    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5656   [(set (match_dup 2) (neg:SF (match_dup 3)))
5657    (set (match_dup 4) (match_dup 5))]
5658   "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5659    operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5660    operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5661    operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
5662   [(set_attr "type" "fpmove,*")
5663    (set_attr "length" "*,2")])
5664
5665 (define_insn "*negdf2_v9"
5666   [(set (match_operand:DF 0 "register_operand" "=e")
5667         (neg:DF (match_operand:DF 1 "register_operand" "e")))]
5668   "TARGET_FPU && TARGET_V9"
5669   "fnegd\t%1, %0"
5670   [(set_attr "type" "fpmove")
5671    (set_attr "fptype" "double")])
5672
5673 (define_insn "negsf2"
5674   [(set (match_operand:SF 0 "register_operand" "=f")
5675         (neg:SF (match_operand:SF 1 "register_operand" "f")))]
5676   "TARGET_FPU"
5677   "fnegs\t%1, %0"
5678   [(set_attr "type" "fpmove")])
5679
5680 (define_expand "abstf2"
5681   [(set (match_operand:TF 0 "register_operand" "")
5682         (abs:TF (match_operand:TF 1 "register_operand" "")))]
5683   "TARGET_FPU"
5684   "")
5685
5686 (define_insn_and_split "*abstf2_notv9"
5687   [(set (match_operand:TF 0 "register_operand" "=e,e")
5688         (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5689   ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5690   "TARGET_FPU && ! TARGET_V9"
5691   "@
5692   fabss\t%0, %0
5693   #"
5694   "&& reload_completed
5695    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5696   [(set (match_dup 2) (abs:SF (match_dup 3)))
5697    (set (match_dup 4) (match_dup 5))
5698    (set (match_dup 6) (match_dup 7))]
5699   "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5700    operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5701    operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5702    operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
5703    operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5704    operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5705   [(set_attr "type" "fpmove,*")
5706    (set_attr "length" "*,2")])
5707
5708 (define_insn "*abstf2_hq_v9"
5709   [(set (match_operand:TF 0 "register_operand" "=e,e")
5710         (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5711   "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
5712   "@
5713   fabsd\t%0, %0
5714   fabsq\t%1, %0"
5715   [(set_attr "type" "fpmove")
5716    (set_attr "fptype" "double,*")])
5717
5718 (define_insn_and_split "*abstf2_v9"
5719   [(set (match_operand:TF 0 "register_operand" "=e,e")
5720         (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5721   "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
5722   "@
5723   fabsd\t%0, %0
5724   #"
5725   "&& reload_completed
5726    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5727   [(set (match_dup 2) (abs:DF (match_dup 3)))
5728    (set (match_dup 4) (match_dup 5))]
5729   "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
5730    operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
5731    operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5732    operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5733   [(set_attr "type" "fpmove,*")
5734    (set_attr "length" "*,2")
5735    (set_attr "fptype" "double,*")])
5736
5737 (define_expand "absdf2"
5738   [(set (match_operand:DF 0 "register_operand" "")
5739         (abs:DF (match_operand:DF 1 "register_operand" "")))]
5740   "TARGET_FPU"
5741   "")
5742
5743 (define_insn_and_split "*absdf2_notv9"
5744   [(set (match_operand:DF 0 "register_operand" "=e,e")
5745         (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
5746   "TARGET_FPU && ! TARGET_V9"
5747   "@
5748   fabss\t%0, %0
5749   #"
5750   "&& reload_completed
5751    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5752   [(set (match_dup 2) (abs:SF (match_dup 3)))
5753    (set (match_dup 4) (match_dup 5))]
5754   "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5755    operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5756    operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5757    operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
5758   [(set_attr "type" "fpmove,*")
5759    (set_attr "length" "*,2")])
5760
5761 (define_insn "*absdf2_v9"
5762   [(set (match_operand:DF 0 "register_operand" "=e")
5763         (abs:DF (match_operand:DF 1 "register_operand" "e")))]
5764   "TARGET_FPU && TARGET_V9"
5765   "fabsd\t%1, %0"
5766   [(set_attr "type" "fpmove")
5767    (set_attr "fptype" "double")])
5768
5769 (define_insn "abssf2"
5770   [(set (match_operand:SF 0 "register_operand" "=f")
5771         (abs:SF (match_operand:SF 1 "register_operand" "f")))]
5772   "TARGET_FPU"
5773   "fabss\t%1, %0"
5774   [(set_attr "type" "fpmove")])
5775
5776 (define_expand "sqrttf2"
5777   [(set (match_operand:TF 0 "nonimmediate_operand" "")
5778         (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
5779   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5780   "emit_tfmode_unop (SQRT, operands); DONE;")
5781
5782 (define_insn "*sqrttf2_hq"
5783   [(set (match_operand:TF 0 "register_operand" "=e")
5784         (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
5785   "TARGET_FPU && TARGET_HARD_QUAD"
5786   "fsqrtq\t%1, %0"
5787   [(set_attr "type" "fpsqrtd")])
5788
5789 (define_insn "sqrtdf2"
5790   [(set (match_operand:DF 0 "register_operand" "=e")
5791         (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
5792   "TARGET_FPU"
5793   "fsqrtd\t%1, %0"
5794   [(set_attr "type" "fpsqrtd")
5795    (set_attr "fptype" "double")])
5796
5797 (define_insn "sqrtsf2"
5798   [(set (match_operand:SF 0 "register_operand" "=f")
5799         (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
5800   "TARGET_FPU"
5801   "fsqrts\t%1, %0"
5802   [(set_attr "type" "fpsqrts")])
5803
5804
5805 ;; Arithmetic shift instructions.
5806
5807 (define_insn "ashlsi3"
5808   [(set (match_operand:SI 0 "register_operand" "=r")
5809         (ashift:SI (match_operand:SI 1 "register_operand" "r")
5810                    (match_operand:SI 2 "arith_operand" "rI")))]
5811   ""
5812 {
5813   if (GET_CODE (operands[2]) == CONST_INT)
5814     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5815   return "sll\t%1, %2, %0";
5816 }
5817   [(set_attr "type" "shift")])
5818
5819 (define_insn "*ashlsi3_extend"
5820   [(set (match_operand:DI 0 "register_operand" "=r")
5821         (zero_extend:DI
5822           (ashift:SI (match_operand:SI 1 "register_operand" "r")
5823                      (match_operand:SI 2 "arith_operand" "rI"))))]
5824   "TARGET_ARCH64"
5825 {
5826   if (GET_CODE (operands[2]) == CONST_INT)
5827     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5828   return "sll\t%1, %2, %0";
5829 }
5830   [(set_attr "type" "shift")])
5831
5832 (define_expand "ashldi3"
5833   [(set (match_operand:DI 0 "register_operand" "=r")
5834         (ashift:DI (match_operand:DI 1 "register_operand" "r")
5835                    (match_operand:SI 2 "arith_operand" "rI")))]
5836   "TARGET_ARCH64 || TARGET_V8PLUS"
5837 {
5838   if (! TARGET_ARCH64)
5839     {
5840       if (GET_CODE (operands[2]) == CONST_INT)
5841         FAIL;
5842       emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
5843       DONE;
5844     }
5845 })
5846
5847 (define_insn "*ashldi3_sp64"
5848   [(set (match_operand:DI 0 "register_operand" "=r")
5849         (ashift:DI (match_operand:DI 1 "register_operand" "r")
5850                    (match_operand:SI 2 "arith_operand" "rI")))]
5851   "TARGET_ARCH64"
5852 {
5853   if (GET_CODE (operands[2]) == CONST_INT)
5854     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5855   return "sllx\t%1, %2, %0";
5856 }
5857   [(set_attr "type" "shift")])
5858
5859 ;; XXX UGH!
5860 (define_insn "ashldi3_v8plus"
5861   [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5862         (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5863                    (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5864    (clobber (match_scratch:SI 3 "=X,X,&h"))]
5865   "TARGET_V8PLUS"
5866   "* return output_v8plus_shift (operands, insn, \"sllx\");"
5867   [(set_attr "type" "multi")
5868    (set_attr "length" "5,5,6")])
5869
5870 ;; Optimize (1LL<<x)-1
5871 ;; XXX this also needs to be fixed to handle equal subregs
5872 ;; XXX first before we could re-enable it.
5873 ;(define_insn ""
5874 ;  [(set (match_operand:DI 0 "register_operand" "=h")
5875 ;       (plus:DI (ashift:DI (const_int 1)
5876 ;                           (match_operand:SI 1 "arith_operand" "rI"))
5877 ;                (const_int -1)))]
5878 ;  "0 && TARGET_V8PLUS"
5879 ;{
5880 ;  if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
5881 ;    return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5882 ;  return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5883 ;}
5884 ;  [(set_attr "type" "multi")
5885 ;   (set_attr "length" "4")])
5886
5887 (define_insn "*cmp_cc_ashift_1"
5888   [(set (reg:CC_NOOV CC_REG)
5889         (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
5890                                     (const_int 1))
5891                          (const_int 0)))]
5892   ""
5893   "addcc\t%0, %0, %%g0"
5894   [(set_attr "type" "compare")])
5895
5896 (define_insn "*cmp_cc_set_ashift_1"
5897   [(set (reg:CC_NOOV CC_REG)
5898         (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
5899                                     (const_int 1))
5900                          (const_int 0)))
5901    (set (match_operand:SI 0 "register_operand" "=r")
5902         (ashift:SI (match_dup 1) (const_int 1)))]
5903   ""
5904   "addcc\t%1, %1, %0"
5905   [(set_attr "type" "compare")])
5906
5907 (define_insn "ashrsi3"
5908   [(set (match_operand:SI 0 "register_operand" "=r")
5909         (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5910                      (match_operand:SI 2 "arith_operand" "rI")))]
5911   ""
5912   {
5913      if (GET_CODE (operands[2]) == CONST_INT)
5914        operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5915      return "sra\t%1, %2, %0";
5916   }
5917   [(set_attr "type" "shift")])
5918
5919 (define_insn "*ashrsi3_extend"
5920   [(set (match_operand:DI 0 "register_operand" "=r")
5921         (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5922                                      (match_operand:SI 2 "arith_operand" "r"))))]
5923   "TARGET_ARCH64"
5924   "sra\t%1, %2, %0"
5925   [(set_attr "type" "shift")])
5926
5927 ;; This handles the case as above, but with constant shift instead of
5928 ;; register. Combiner "simplifies" it for us a little bit though.
5929 (define_insn "*ashrsi3_extend2"
5930   [(set (match_operand:DI 0 "register_operand" "=r")
5931         (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
5932                                 (const_int 32))
5933                      (match_operand:SI 2 "small_int_operand" "I")))]
5934   "TARGET_ARCH64 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64"
5935 {
5936   operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
5937   return "sra\t%1, %2, %0";
5938 }
5939   [(set_attr "type" "shift")])
5940
5941 (define_expand "ashrdi3"
5942   [(set (match_operand:DI 0 "register_operand" "=r")
5943         (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5944                      (match_operand:SI 2 "arith_operand" "rI")))]
5945   "TARGET_ARCH64 || TARGET_V8PLUS"
5946 {
5947   if (! TARGET_ARCH64)
5948     {
5949       if (GET_CODE (operands[2]) == CONST_INT)
5950         FAIL;   /* prefer generic code in this case */
5951       emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
5952       DONE;
5953     }
5954 })
5955
5956 (define_insn "*ashrdi3_sp64"
5957   [(set (match_operand:DI 0 "register_operand" "=r")
5958         (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5959                      (match_operand:SI 2 "arith_operand" "rI")))]
5960   "TARGET_ARCH64"
5961   
5962   {
5963     if (GET_CODE (operands[2]) == CONST_INT)
5964       operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5965     return "srax\t%1, %2, %0";
5966   }
5967   [(set_attr "type" "shift")])
5968
5969 ;; XXX
5970 (define_insn "ashrdi3_v8plus"
5971   [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5972         (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5973                      (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5974    (clobber (match_scratch:SI 3 "=X,X,&h"))]
5975   "TARGET_V8PLUS"
5976   "* return output_v8plus_shift (operands, insn, \"srax\");"
5977   [(set_attr "type" "multi")
5978    (set_attr "length" "5,5,6")])
5979
5980 (define_insn "lshrsi3"
5981   [(set (match_operand:SI 0 "register_operand" "=r")
5982         (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5983                      (match_operand:SI 2 "arith_operand" "rI")))]
5984   ""
5985   {
5986     if (GET_CODE (operands[2]) == CONST_INT)
5987       operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5988     return "srl\t%1, %2, %0";
5989   }
5990   [(set_attr "type" "shift")])
5991
5992 (define_insn "*lshrsi3_extend0"
5993   [(set (match_operand:DI 0 "register_operand" "=r")
5994         (zero_extend:DI
5995           (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5996                        (match_operand:SI 2 "arith_operand" "rI"))))]
5997   "TARGET_ARCH64"
5998   {
5999     if (GET_CODE (operands[2]) == CONST_INT)
6000       operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6001     return "srl\t%1, %2, %0";
6002   }
6003   [(set_attr "type" "shift")])
6004
6005 ;; This handles the case where
6006 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
6007 ;; but combiner "simplifies" it for us.
6008 (define_insn "*lshrsi3_extend1"
6009   [(set (match_operand:DI 0 "register_operand" "=r")
6010         (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
6011                            (match_operand:SI 2 "arith_operand" "r")) 0)
6012                 (match_operand 3 "const_int_operand" "")))]
6013   "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff"
6014   "srl\t%1, %2, %0"
6015   [(set_attr "type" "shift")])
6016
6017 ;; This handles the case where
6018 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
6019 ;; but combiner "simplifies" it for us.
6020 (define_insn "*lshrsi3_extend2"
6021   [(set (match_operand:DI 0 "register_operand" "=r")
6022         (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
6023                          (match_operand 2 "small_int_operand" "I")
6024                          (const_int 32)))]
6025   "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6026 {
6027   operands[2] = GEN_INT (32 - INTVAL (operands[2]));
6028   return "srl\t%1, %2, %0";
6029 }
6030   [(set_attr "type" "shift")])
6031
6032 (define_expand "lshrdi3"
6033   [(set (match_operand:DI 0 "register_operand" "=r")
6034         (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6035                      (match_operand:SI 2 "arith_operand" "rI")))]
6036   "TARGET_ARCH64 || TARGET_V8PLUS"
6037 {
6038   if (! TARGET_ARCH64)
6039     {
6040       if (GET_CODE (operands[2]) == CONST_INT)
6041         FAIL;
6042       emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
6043       DONE;
6044     }
6045 })
6046
6047 (define_insn "*lshrdi3_sp64"
6048   [(set (match_operand:DI 0 "register_operand" "=r")
6049         (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6050                      (match_operand:SI 2 "arith_operand" "rI")))]
6051   "TARGET_ARCH64"
6052   {
6053     if (GET_CODE (operands[2]) == CONST_INT)
6054       operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6055     return "srlx\t%1, %2, %0";
6056   }
6057   [(set_attr "type" "shift")])
6058
6059 ;; XXX
6060 (define_insn "lshrdi3_v8plus"
6061   [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6062         (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6063                      (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6064    (clobber (match_scratch:SI 3 "=X,X,&h"))]
6065   "TARGET_V8PLUS"
6066   "* return output_v8plus_shift (operands, insn, \"srlx\");"
6067   [(set_attr "type" "multi")
6068    (set_attr "length" "5,5,6")])
6069
6070 (define_insn ""
6071   [(set (match_operand:SI 0 "register_operand" "=r")
6072         (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6073                                              (const_int 32)) 4)
6074                      (match_operand:SI 2 "small_int_operand" "I")))]
6075   "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6076 {
6077   operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6078   return "srax\t%1, %2, %0";
6079 }
6080   [(set_attr "type" "shift")])
6081
6082 (define_insn ""
6083   [(set (match_operand:SI 0 "register_operand" "=r")
6084         (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6085                                              (const_int 32)) 4)
6086                      (match_operand:SI 2 "small_int_operand" "I")))]
6087   "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6088 {
6089   operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6090   return "srlx\t%1, %2, %0";
6091 }
6092   [(set_attr "type" "shift")])
6093
6094 (define_insn ""
6095   [(set (match_operand:SI 0 "register_operand" "=r")
6096         (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6097                                              (match_operand:SI 2 "small_int_operand" "I")) 4)
6098                      (match_operand:SI 3 "small_int_operand" "I")))]
6099   "TARGET_ARCH64
6100    && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6101    && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6102    && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6103 {
6104   operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6105
6106   return "srax\t%1, %2, %0";
6107 }
6108   [(set_attr "type" "shift")])
6109
6110 (define_insn ""
6111   [(set (match_operand:SI 0 "register_operand" "=r")
6112         (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6113                                              (match_operand:SI 2 "small_int_operand" "I")) 4)
6114                      (match_operand:SI 3 "small_int_operand" "I")))]
6115   "TARGET_ARCH64
6116    && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6117    && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6118    && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6119 {
6120   operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6121
6122   return "srlx\t%1, %2, %0";
6123 }
6124   [(set_attr "type" "shift")])
6125
6126
6127 ;; Unconditional and other jump instructions.
6128
6129 (define_insn "jump"
6130   [(set (pc) (label_ref (match_operand 0 "" "")))]
6131   ""
6132   "* return output_ubranch (operands[0], 0, insn);"
6133   [(set_attr "type" "uncond_branch")])
6134
6135 (define_expand "tablejump"
6136   [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
6137               (use (label_ref (match_operand 1 "" "")))])]
6138   ""
6139 {
6140   gcc_assert (GET_MODE (operands[0]) == CASE_VECTOR_MODE);
6141
6142   /* In pic mode, our address differences are against the base of the
6143      table.  Add that base value back in; CSE ought to be able to combine
6144      the two address loads.  */
6145   if (flag_pic)
6146     {
6147       rtx tmp, tmp2;
6148       tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
6149       tmp2 = operands[0];
6150       if (CASE_VECTOR_MODE != Pmode)
6151         tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
6152       tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
6153       operands[0] = memory_address (Pmode, tmp);
6154     }
6155 })
6156
6157 (define_insn "*tablejump_sp32"
6158   [(set (pc) (match_operand:SI 0 "address_operand" "p"))
6159    (use (label_ref (match_operand 1 "" "")))]
6160   "! TARGET_ARCH64"
6161   "jmp\t%a0%#"
6162   [(set_attr "type" "uncond_branch")])
6163
6164 (define_insn "*tablejump_sp64"
6165   [(set (pc) (match_operand:DI 0 "address_operand" "p"))
6166    (use (label_ref (match_operand 1 "" "")))]
6167   "TARGET_ARCH64"
6168   "jmp\t%a0%#"
6169   [(set_attr "type" "uncond_branch")])
6170
6171
6172 ;; Jump to subroutine instructions.
6173
6174 (define_expand "call"
6175   ;; Note that this expression is not used for generating RTL.
6176   ;; All the RTL is generated explicitly below.
6177   [(call (match_operand 0 "call_operand" "")
6178          (match_operand 3 "" "i"))]
6179   ;; operands[2] is next_arg_register
6180   ;; operands[3] is struct_value_size_rtx.
6181   ""
6182 {
6183   rtx fn_rtx;
6184
6185   gcc_assert (MEM_P (operands[0]) && GET_MODE (operands[0]) == FUNCTION_MODE);
6186
6187   gcc_assert (GET_CODE (operands[3]) == CONST_INT);
6188
6189   if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
6190     {
6191       /* This is really a PIC sequence.  We want to represent
6192          it as a funny jump so its delay slots can be filled. 
6193
6194          ??? But if this really *is* a CALL, will not it clobber the
6195          call-clobbered registers?  We lose this if it is a JUMP_INSN.
6196          Why cannot we have delay slots filled if it were a CALL?  */
6197
6198       /* We accept negative sizes for untyped calls.  */
6199       if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6200         emit_jump_insn
6201           (gen_rtx_PARALLEL
6202            (VOIDmode,
6203             gen_rtvec (3,
6204                        gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6205                        operands[3],
6206                        gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6207       else
6208         emit_jump_insn
6209           (gen_rtx_PARALLEL
6210            (VOIDmode,
6211             gen_rtvec (2,
6212                        gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6213                        gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6214       goto finish_call;
6215     }
6216
6217   fn_rtx = operands[0];
6218
6219   /* We accept negative sizes for untyped calls.  */
6220   if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6221     sparc_emit_call_insn
6222       (gen_rtx_PARALLEL
6223        (VOIDmode,
6224         gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6225                    operands[3],
6226                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6227        XEXP (fn_rtx, 0));
6228   else
6229     sparc_emit_call_insn
6230       (gen_rtx_PARALLEL
6231        (VOIDmode,
6232         gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6233                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6234        XEXP (fn_rtx, 0));
6235
6236  finish_call:
6237
6238   DONE;
6239 })
6240
6241 ;; We can't use the same pattern for these two insns, because then registers
6242 ;; in the address may not be properly reloaded.
6243
6244 (define_insn "*call_address_sp32"
6245   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6246          (match_operand 1 "" ""))
6247    (clobber (reg:SI O7_REG))]
6248   ;;- Do not use operand 1 for most machines.
6249   "! TARGET_ARCH64"
6250   "call\t%a0, %1%#"
6251   [(set_attr "type" "call")])
6252
6253 (define_insn "*call_symbolic_sp32"
6254   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6255          (match_operand 1 "" ""))
6256    (clobber (reg:SI O7_REG))]
6257   ;;- Do not use operand 1 for most machines.
6258   "! TARGET_ARCH64"
6259   "call\t%a0, %1%#"
6260   [(set_attr "type" "call")])
6261
6262 (define_insn "*call_address_sp64"
6263   [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
6264          (match_operand 1 "" ""))
6265    (clobber (reg:DI O7_REG))]
6266   ;;- Do not use operand 1 for most machines.
6267   "TARGET_ARCH64"
6268   "call\t%a0, %1%#"
6269   [(set_attr "type" "call")])
6270
6271 (define_insn "*call_symbolic_sp64"
6272   [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6273          (match_operand 1 "" ""))
6274    (clobber (reg:DI O7_REG))]
6275   ;;- Do not use operand 1 for most machines.
6276   "TARGET_ARCH64"
6277   "call\t%a0, %1%#"
6278   [(set_attr "type" "call")])
6279
6280 ;; This is a call that wants a structure value.
6281 ;; There is no such critter for v9 (??? we may need one anyway).
6282 (define_insn "*call_address_struct_value_sp32"
6283   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6284          (match_operand 1 "" ""))
6285    (match_operand 2 "immediate_operand" "")
6286    (clobber (reg:SI O7_REG))]
6287   ;;- Do not use operand 1 for most machines.
6288   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6289 {
6290   operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6291   return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6292 }
6293   [(set_attr "type" "call_no_delay_slot")
6294    (set_attr "length" "3")])
6295
6296 ;; This is a call that wants a structure value.
6297 ;; There is no such critter for v9 (??? we may need one anyway).
6298 (define_insn "*call_symbolic_struct_value_sp32"
6299   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6300          (match_operand 1 "" ""))
6301    (match_operand 2 "immediate_operand" "")
6302    (clobber (reg:SI O7_REG))]
6303   ;;- Do not use operand 1 for most machines.
6304   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6305 {
6306   operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6307   return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6308 }
6309   [(set_attr "type" "call_no_delay_slot")
6310    (set_attr "length" "3")])
6311
6312 ;; This is a call that may want a structure value.  This is used for
6313 ;; untyped_calls.
6314 (define_insn "*call_address_untyped_struct_value_sp32"
6315   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6316          (match_operand 1 "" ""))
6317    (match_operand 2 "immediate_operand" "")
6318    (clobber (reg:SI O7_REG))]
6319   ;;- Do not use operand 1 for most machines.
6320   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6321   "call\t%a0, %1\n\t nop\n\tnop"
6322   [(set_attr "type" "call_no_delay_slot")
6323    (set_attr "length" "3")])
6324
6325 ;; This is a call that may want a structure value.  This is used for
6326 ;; untyped_calls.
6327 (define_insn "*call_symbolic_untyped_struct_value_sp32"
6328   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6329          (match_operand 1 "" ""))
6330    (match_operand 2 "immediate_operand" "")
6331    (clobber (reg:SI O7_REG))]
6332   ;;- Do not use operand 1 for most machines.
6333   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6334   "call\t%a0, %1\n\t nop\n\tnop"
6335   [(set_attr "type" "call_no_delay_slot")
6336    (set_attr "length" "3")])
6337
6338 (define_expand "call_value"
6339   ;; Note that this expression is not used for generating RTL.
6340   ;; All the RTL is generated explicitly below.
6341   [(set (match_operand 0 "register_operand" "=rf")
6342         (call (match_operand 1 "" "")
6343               (match_operand 4 "" "")))]
6344   ;; operand 2 is stack_size_rtx
6345   ;; operand 3 is next_arg_register
6346   ""
6347 {
6348   rtx fn_rtx;
6349   rtvec vec;
6350
6351   gcc_assert (MEM_P (operands[1]) && GET_MODE (operands[1]) == FUNCTION_MODE);
6352
6353   fn_rtx = operands[1];
6354
6355   vec = gen_rtvec (2,
6356                    gen_rtx_SET (VOIDmode, operands[0],
6357                                 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
6358                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
6359
6360   sparc_emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec), XEXP (fn_rtx, 0));
6361
6362   DONE;
6363 })
6364
6365 (define_insn "*call_value_address_sp32"
6366   [(set (match_operand 0 "" "=rf")
6367         (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
6368               (match_operand 2 "" "")))
6369    (clobber (reg:SI O7_REG))]
6370   ;;- Do not use operand 2 for most machines.
6371   "! TARGET_ARCH64"
6372   "call\t%a1, %2%#"
6373   [(set_attr "type" "call")])
6374
6375 (define_insn "*call_value_symbolic_sp32"
6376   [(set (match_operand 0 "" "=rf")
6377         (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6378               (match_operand 2 "" "")))
6379    (clobber (reg:SI O7_REG))]
6380   ;;- Do not use operand 2 for most machines.
6381   "! TARGET_ARCH64"
6382   "call\t%a1, %2%#"
6383   [(set_attr "type" "call")])
6384
6385 (define_insn "*call_value_address_sp64"
6386   [(set (match_operand 0 "" "")
6387         (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
6388               (match_operand 2 "" "")))
6389    (clobber (reg:DI O7_REG))]
6390   ;;- Do not use operand 2 for most machines.
6391   "TARGET_ARCH64"
6392   "call\t%a1, %2%#"
6393   [(set_attr "type" "call")])
6394
6395 (define_insn "*call_value_symbolic_sp64"
6396   [(set (match_operand 0 "" "")
6397         (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6398               (match_operand 2 "" "")))
6399    (clobber (reg:DI O7_REG))]
6400   ;;- Do not use operand 2 for most machines.
6401   "TARGET_ARCH64"
6402   "call\t%a1, %2%#"
6403   [(set_attr "type" "call")])
6404
6405 (define_expand "untyped_call"
6406   [(parallel [(call (match_operand 0 "" "")
6407                     (const_int 0))
6408               (match_operand:BLK 1 "memory_operand" "")
6409               (match_operand 2 "" "")])]
6410   ""
6411 {
6412   rtx valreg1 = gen_rtx_REG (DImode, 8);
6413   rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6414   rtx result = operands[1];
6415
6416   /* Pass constm1 to indicate that it may expect a structure value, but
6417      we don't know what size it is.  */
6418   emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
6419
6420   /* Save the function value registers.  */
6421   emit_move_insn (adjust_address (result, DImode, 0), valreg1);
6422   emit_move_insn (adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8),
6423                                   valreg2);
6424
6425   /* The optimizer does not know that the call sets the function value
6426      registers we stored in the result block.  We avoid problems by
6427      claiming that all hard registers are used and clobbered at this
6428      point.  */
6429   emit_insn (gen_blockage ());
6430
6431   DONE;
6432 })
6433
6434 ;;  Tail call instructions.
6435
6436 (define_expand "sibcall"
6437   [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
6438               (return)])]
6439   ""
6440   "")
6441
6442 (define_insn "*sibcall_symbolic_sp32"
6443   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6444          (match_operand 1 "" ""))
6445    (return)]
6446   "! TARGET_ARCH64"
6447   "* return output_sibcall(insn, operands[0]);"
6448   [(set_attr "type" "sibcall")])
6449
6450 (define_insn "*sibcall_symbolic_sp64"
6451   [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6452          (match_operand 1 "" ""))
6453    (return)]
6454   "TARGET_ARCH64"
6455   "* return output_sibcall(insn, operands[0]);"
6456   [(set_attr "type" "sibcall")])
6457
6458 (define_expand "sibcall_value"
6459   [(parallel [(set (match_operand 0 "register_operand" "=rf")
6460                 (call (match_operand 1 "" "") (const_int 0)))
6461               (return)])]
6462   ""
6463   "")
6464
6465 (define_insn "*sibcall_value_symbolic_sp32"
6466   [(set (match_operand 0 "" "=rf")
6467         (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6468               (match_operand 2 "" "")))
6469    (return)]
6470   "! TARGET_ARCH64"
6471   "* return output_sibcall(insn, operands[1]);"
6472   [(set_attr "type" "sibcall")])
6473
6474 (define_insn "*sibcall_value_symbolic_sp64"
6475   [(set (match_operand 0 "" "")
6476         (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6477               (match_operand 2 "" "")))
6478    (return)]
6479   "TARGET_ARCH64"
6480   "* return output_sibcall(insn, operands[1]);"
6481   [(set_attr "type" "sibcall")])
6482
6483
6484 ;; Special instructions.
6485
6486 (define_expand "prologue"
6487   [(const_int 0)]
6488   ""
6489 {
6490   if (TARGET_FLAT)
6491     sparc_flat_expand_prologue ();
6492   else
6493     sparc_expand_prologue ();
6494   DONE;
6495 })
6496
6497 ;; The "register window save" insn is modelled as follows.  The dwarf2
6498 ;; information is manually added in emit_window_save.
6499
6500 (define_insn "window_save"
6501   [(unspec_volatile
6502         [(match_operand 0 "arith_operand" "rI")]
6503         UNSPECV_SAVEW)]
6504   "!TARGET_FLAT"
6505   "save\t%%sp, %0, %%sp"
6506   [(set_attr "type" "savew")])
6507
6508 (define_expand "epilogue"
6509   [(return)]
6510   ""
6511 {
6512   if (TARGET_FLAT)
6513     sparc_flat_expand_epilogue (false);
6514   else
6515     sparc_expand_epilogue (false);
6516 })
6517
6518 (define_expand "sibcall_epilogue"
6519   [(return)]
6520   ""
6521 {
6522   if (TARGET_FLAT)
6523     sparc_flat_expand_epilogue (false);
6524   else
6525     sparc_expand_epilogue (false);
6526   DONE;
6527 })
6528
6529 (define_expand "eh_return"
6530   [(use (match_operand 0 "general_operand" ""))]
6531   ""
6532 {
6533   emit_move_insn (gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM), operands[0]);
6534   emit_jump_insn (gen_eh_return_internal ());
6535   emit_barrier ();
6536   DONE;
6537 })
6538
6539 (define_insn_and_split "eh_return_internal"
6540   [(eh_return)]
6541   ""
6542   "#"
6543   "epilogue_completed"
6544   [(return)]
6545 {
6546   if (TARGET_FLAT)
6547     sparc_flat_expand_epilogue (true);
6548   else
6549     sparc_expand_epilogue (true);
6550 })
6551
6552 (define_expand "return"
6553   [(return)]
6554   "sparc_can_use_return_insn_p ()"
6555   "")
6556
6557 (define_insn "*return_internal"
6558   [(return)]
6559   ""
6560   "* return output_return (insn);"
6561   [(set_attr "type" "return")
6562    (set (attr "length")
6563         (cond [(eq_attr "calls_eh_return" "true")
6564                  (if_then_else (eq_attr "delayed_branch" "true")
6565                                 (if_then_else (ior (eq_attr "isa" "v9")
6566                                                    (eq_attr "flat" "true"))
6567                                         (const_int 2)
6568                                         (const_int 3))
6569                                 (if_then_else (eq_attr "flat" "true")
6570                                         (const_int 3)
6571                                         (const_int 4)))
6572                (ior (eq_attr "leaf_function" "true") (eq_attr "flat" "true"))
6573                  (if_then_else (eq_attr "empty_delay_slot" "true")
6574                                (const_int 2)
6575                                (const_int 1))
6576                (eq_attr "empty_delay_slot" "true")
6577                  (if_then_else (eq_attr "delayed_branch" "true")
6578                                (const_int 2)
6579                                (const_int 3))
6580               ] (const_int 1)))])
6581
6582 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
6583 ;; all of memory.  This blocks insns from being moved across this point.
6584
6585 (define_insn "blockage"
6586   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
6587   ""
6588   ""
6589   [(set_attr "length" "0")])
6590
6591 (define_expand "probe_stack"
6592   [(set (match_operand 0 "memory_operand" "") (const_int 0))]
6593   ""
6594 {
6595   operands[0]
6596     = adjust_address (operands[0], GET_MODE (operands[0]), SPARC_STACK_BIAS);
6597 })
6598
6599 (define_insn "probe_stack_range<P:mode>"
6600   [(set (match_operand:P 0 "register_operand" "=r")
6601         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
6602                             (match_operand:P 2 "register_operand" "r")]
6603                             UNSPECV_PROBE_STACK_RANGE))]
6604   ""
6605   "* return output_probe_stack_range (operands[0], operands[2]);"
6606   [(set_attr "type" "multi")])
6607
6608 ;; Prepare to return any type including a structure value.
6609
6610 (define_expand "untyped_return"
6611   [(match_operand:BLK 0 "memory_operand" "")
6612    (match_operand 1 "" "")]
6613   ""
6614 {
6615   rtx valreg1 = gen_rtx_REG (DImode, 24);
6616   rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6617   rtx result = operands[0];
6618
6619   if (! TARGET_ARCH64)
6620     {
6621       rtx rtnreg = gen_rtx_REG (SImode, RETURN_ADDR_REGNUM);
6622       rtx value = gen_reg_rtx (SImode);
6623
6624       /* Fetch the instruction where we will return to and see if it's an unimp
6625          instruction (the most significant 10 bits will be zero).  If so,
6626          update the return address to skip the unimp instruction.  */
6627       emit_move_insn (value,
6628                       gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
6629       emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
6630       emit_insn (gen_update_return (rtnreg, value));
6631     }
6632
6633   /* Reload the function value registers.  */
6634   emit_move_insn (valreg1, adjust_address (result, DImode, 0));
6635   emit_move_insn (valreg2,
6636                   adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
6637
6638   /* Put USE insns before the return.  */
6639   emit_use (valreg1);
6640   emit_use (valreg2);
6641
6642   /* Construct the return.  */
6643   expand_naked_return ();
6644
6645   DONE;
6646 })
6647
6648 ;; Adjust the return address conditionally. If the value of op1 is equal
6649 ;; to all zero then adjust the return address i.e. op0 = op0 + 4.
6650 ;; This is technically *half* the check required by the 32-bit SPARC
6651 ;; psABI. This check only ensures that an "unimp" insn was written by
6652 ;; the caller, but doesn't check to see if the expected size matches
6653 ;; (this is encoded in the 12 lower bits). This check is obsolete and
6654 ;; only used by the above code "untyped_return".
6655
6656 (define_insn "update_return"
6657   [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
6658                (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
6659   "! TARGET_ARCH64"
6660 {
6661   if (flag_delayed_branch)
6662     return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
6663   else
6664     return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
6665 }
6666   [(set (attr "type") (const_string "multi"))
6667    (set (attr "length")
6668         (if_then_else (eq_attr "delayed_branch" "true")
6669                       (const_int 3)
6670                       (const_int 4)))])
6671 \f
6672 (define_insn "nop"
6673   [(const_int 0)]
6674   ""
6675   "nop")
6676
6677 (define_expand "indirect_jump"
6678   [(set (pc) (match_operand 0 "address_operand" "p"))]
6679   ""
6680   "")
6681
6682 (define_insn "*branch_sp32"
6683   [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
6684   "! TARGET_ARCH64"
6685  "jmp\t%a0%#"
6686  [(set_attr "type" "uncond_branch")])
6687  
6688 (define_insn "*branch_sp64"
6689   [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
6690   "TARGET_ARCH64"
6691   "jmp\t%a0%#"
6692   [(set_attr "type" "uncond_branch")])
6693
6694 (define_expand "save_stack_nonlocal"
6695   [(set (match_operand 0 "memory_operand" "")
6696         (match_operand 1 "register_operand" ""))
6697    (set (match_dup 2) (match_dup 3))]
6698   ""
6699 {
6700   operands[0] = adjust_address_nv (operands[0], Pmode, 0);
6701   operands[2] = adjust_address_nv (operands[0], Pmode, GET_MODE_SIZE (Pmode));
6702   operands[3] = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
6703 })
6704
6705 (define_expand "restore_stack_nonlocal"
6706   [(set (match_operand 0 "register_operand" "")
6707         (match_operand 1 "memory_operand" ""))]
6708   ""
6709 {
6710   operands[1] = adjust_address_nv (operands[1], Pmode, 0);
6711 })
6712
6713 (define_expand "nonlocal_goto"
6714   [(match_operand 0 "general_operand" "")
6715    (match_operand 1 "general_operand" "")
6716    (match_operand 2 "memory_operand" "")
6717    (match_operand 3 "memory_operand" "")]
6718   ""
6719 {
6720   rtx r_label = copy_to_reg (operands[1]);
6721   rtx r_sp = adjust_address_nv (operands[2], Pmode, 0);
6722   rtx r_fp = operands[3];
6723   rtx r_i7 = adjust_address_nv (operands[2], Pmode, GET_MODE_SIZE (Pmode));
6724
6725   /* We need to flush all the register windows so that their contents will
6726      be re-synchronized by the restore insn of the target function.  */
6727   if (!TARGET_FLAT)
6728     emit_insn (gen_flush_register_windows ());
6729
6730   emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
6731   emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
6732
6733   /* Restore frame pointer for containing function.  */
6734   emit_move_insn (hard_frame_pointer_rtx, r_fp);
6735   emit_stack_restore (SAVE_NONLOCAL, r_sp);
6736
6737   /* USE of hard_frame_pointer_rtx added for consistency;
6738      not clear if really needed.  */
6739   emit_use (hard_frame_pointer_rtx);
6740   emit_use (stack_pointer_rtx);
6741
6742   /* We need to smuggle the load of %i7 as it is a fixed register.  */
6743   emit_jump_insn (gen_nonlocal_goto_internal (r_label, r_i7));
6744   emit_barrier ();
6745   DONE;
6746 })
6747
6748 (define_insn "nonlocal_goto_internal"
6749   [(unspec_volatile [(match_operand 0 "register_operand" "r")
6750                      (match_operand 1 "memory_operand" "m")] UNSPECV_GOTO)]
6751   "GET_MODE (operands[0]) == Pmode && GET_MODE (operands[1]) == Pmode"
6752 {
6753   if (flag_delayed_branch)
6754     {
6755       if (TARGET_ARCH64)
6756         return "jmp\t%0\n\t ldx\t%1, %%i7";
6757       else
6758         return "jmp\t%0\n\t ld\t%1, %%i7";
6759     }
6760   else
6761     {
6762       if (TARGET_ARCH64)
6763         return "ldx\t%1, %%i7\n\tjmp\t%0\n\t nop";
6764       else
6765         return "ld\t%1, %%i7\n\tjmp\t%0\n\t nop";
6766     }
6767 }
6768   [(set (attr "type") (const_string "multi"))
6769    (set (attr "length")
6770         (if_then_else (eq_attr "delayed_branch" "true")
6771                       (const_int 2)
6772                       (const_int 3)))])
6773
6774 (define_expand "builtin_setjmp_receiver"
6775   [(label_ref (match_operand 0 "" ""))]
6776   "flag_pic"
6777 {
6778   load_got_register ();
6779   DONE;
6780 })
6781
6782 ;; Special insn to flush register windows.
6783
6784 (define_insn "flush_register_windows"
6785   [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
6786   ""
6787   { return TARGET_V9 ? "flushw" : "ta\t3"; }
6788   [(set_attr "type" "flushw")])
6789
6790 ;; Special pattern for the FLUSH instruction.
6791
6792 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
6793 ; of the define_insn otherwise missing a mode.  We make "flush", aka
6794 ; gen_flush, the default one since sparc_initialize_trampoline uses
6795 ; it on SImode mem values.
6796
6797 (define_insn "flush"
6798   [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
6799   ""
6800   { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
6801   [(set_attr "type" "iflush")])
6802
6803 (define_insn "flushdi"
6804   [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
6805   ""
6806   { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
6807   [(set_attr "type" "iflush")])
6808
6809
6810 ;; Find first set instructions.
6811
6812 ;; The scan instruction searches from the most significant bit while ffs
6813 ;; searches from the least significant bit.  The bit index and treatment of
6814 ;; zero also differ.  It takes at least 7 instructions to get the proper
6815 ;; result.  Here is an obvious 8 instruction sequence.
6816
6817 ;; XXX
6818 (define_insn "ffssi2"
6819   [(set (match_operand:SI 0 "register_operand" "=&r")
6820         (ffs:SI (match_operand:SI 1 "register_operand" "r")))
6821    (clobber (match_scratch:SI 2 "=&r"))]
6822   "TARGET_SPARCLITE || TARGET_SPARCLET"
6823 {
6824   return "sub\t%%g0, %1, %0\;and\t%0, %1, %0\;scan\t%0, 0, %0\;mov\t32, %2\;sub\t%2, %0, %0\;sra\t%0, 31, %2\;and\t%2, 31, %2\;add\t%2, %0, %0";
6825 }
6826   [(set_attr "type" "multi")
6827    (set_attr "length" "8")])
6828
6829 ;; ??? This should be a define expand, so that the extra instruction have
6830 ;; a chance of being optimized away.
6831
6832 ;; Disabled because none of the UltraSPARCs implement popc.  The HAL R1
6833 ;; does, but no one uses that and we don't have a switch for it.
6834 ;
6835 ;(define_insn "ffsdi2"
6836 ;  [(set (match_operand:DI 0 "register_operand" "=&r")
6837 ;       (ffs:DI (match_operand:DI 1 "register_operand" "r")))
6838 ;   (clobber (match_scratch:DI 2 "=&r"))]
6839 ;  "TARGET_ARCH64"
6840 ;  "neg\t%1, %2\;xnor\t%1, %2, %2\;popc\t%2, %0\;movzr\t%1, 0, %0"
6841 ;  [(set_attr "type" "multi")
6842 ;   (set_attr "length" "4")])
6843
6844
6845 \f
6846 ;; Peepholes go at the end.
6847
6848 ;; Optimize consecutive loads or stores into ldd and std when possible.
6849 ;; The conditions in which we do this are very restricted and are 
6850 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
6851
6852 (define_peephole2
6853   [(set (match_operand:SI 0 "memory_operand" "")
6854       (const_int 0))
6855    (set (match_operand:SI 1 "memory_operand" "")
6856       (const_int 0))]
6857   "TARGET_V9
6858    && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
6859   [(set (match_dup 0)
6860        (const_int 0))]
6861   "operands[0] = widen_memory_access (operands[0], DImode, 0);")
6862
6863 (define_peephole2
6864   [(set (match_operand:SI 0 "memory_operand" "")
6865       (const_int 0))
6866    (set (match_operand:SI 1 "memory_operand" "")
6867       (const_int 0))]
6868   "TARGET_V9
6869    && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
6870   [(set (match_dup 1)
6871        (const_int 0))]
6872   "operands[1] = widen_memory_access (operands[1], DImode, 0);")
6873
6874 (define_peephole2
6875   [(set (match_operand:SI 0 "register_operand" "")
6876         (match_operand:SI 1 "memory_operand" ""))
6877    (set (match_operand:SI 2 "register_operand" "")
6878         (match_operand:SI 3 "memory_operand" ""))]
6879   "registers_ok_for_ldd_peep (operands[0], operands[2]) 
6880    && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])" 
6881   [(set (match_dup 0)
6882         (match_dup 1))]
6883   "operands[1] = widen_memory_access (operands[1], DImode, 0);
6884    operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
6885
6886 (define_peephole2
6887   [(set (match_operand:SI 0 "memory_operand" "")
6888         (match_operand:SI 1 "register_operand" ""))
6889    (set (match_operand:SI 2 "memory_operand" "")
6890         (match_operand:SI 3 "register_operand" ""))]
6891   "registers_ok_for_ldd_peep (operands[1], operands[3]) 
6892    && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
6893   [(set (match_dup 0)
6894         (match_dup 1))]
6895   "operands[0] = widen_memory_access (operands[0], DImode, 0);
6896    operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
6897
6898 (define_peephole2
6899   [(set (match_operand:SF 0 "register_operand" "")
6900         (match_operand:SF 1 "memory_operand" ""))
6901    (set (match_operand:SF 2 "register_operand" "")
6902         (match_operand:SF 3 "memory_operand" ""))]
6903   "registers_ok_for_ldd_peep (operands[0], operands[2]) 
6904    && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
6905   [(set (match_dup 0)
6906         (match_dup 1))]
6907   "operands[1] = widen_memory_access (operands[1], DFmode, 0);
6908    operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
6909
6910 (define_peephole2
6911   [(set (match_operand:SF 0 "memory_operand" "")
6912         (match_operand:SF 1 "register_operand" ""))
6913    (set (match_operand:SF 2 "memory_operand" "")
6914         (match_operand:SF 3 "register_operand" ""))]
6915   "registers_ok_for_ldd_peep (operands[1], operands[3]) 
6916   && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
6917   [(set (match_dup 0)
6918         (match_dup 1))]
6919   "operands[0] = widen_memory_access (operands[0], DFmode, 0);
6920    operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
6921
6922 (define_peephole2
6923   [(set (match_operand:SI 0 "register_operand" "")
6924         (match_operand:SI 1 "memory_operand" ""))
6925    (set (match_operand:SI 2 "register_operand" "")
6926         (match_operand:SI 3 "memory_operand" ""))]
6927   "registers_ok_for_ldd_peep (operands[2], operands[0]) 
6928   && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
6929   [(set (match_dup 2)
6930         (match_dup 3))]
6931    "operands[3] = widen_memory_access (operands[3], DImode, 0);
6932     operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
6933
6934 (define_peephole2
6935   [(set (match_operand:SI 0 "memory_operand" "")
6936         (match_operand:SI 1 "register_operand" ""))
6937    (set (match_operand:SI 2 "memory_operand" "")
6938         (match_operand:SI 3 "register_operand" ""))]
6939   "registers_ok_for_ldd_peep (operands[3], operands[1]) 
6940   && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)" 
6941   [(set (match_dup 2)
6942         (match_dup 3))]
6943   "operands[2] = widen_memory_access (operands[2], DImode, 0);
6944    operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
6945    ")
6946  
6947 (define_peephole2
6948   [(set (match_operand:SF 0 "register_operand" "")
6949         (match_operand:SF 1 "memory_operand" ""))
6950    (set (match_operand:SF 2 "register_operand" "")
6951         (match_operand:SF 3 "memory_operand" ""))]
6952   "registers_ok_for_ldd_peep (operands[2], operands[0]) 
6953   && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
6954   [(set (match_dup 2)
6955         (match_dup 3))]
6956   "operands[3] = widen_memory_access (operands[3], DFmode, 0);
6957    operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
6958
6959 (define_peephole2
6960   [(set (match_operand:SF 0 "memory_operand" "")
6961         (match_operand:SF 1 "register_operand" ""))
6962    (set (match_operand:SF 2 "memory_operand" "")
6963         (match_operand:SF 3 "register_operand" ""))]
6964   "registers_ok_for_ldd_peep (operands[3], operands[1]) 
6965   && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
6966   [(set (match_dup 2)
6967         (match_dup 3))]
6968   "operands[2] = widen_memory_access (operands[2], DFmode, 0);
6969    operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
6970  
6971 ;; Optimize the case of following a reg-reg move with a test
6972 ;; of reg just moved.  Don't allow floating point regs for operand 0 or 1.
6973 ;; This can result from a float to fix conversion.
6974
6975 (define_peephole2
6976   [(set (match_operand:SI 0 "register_operand" "")
6977         (match_operand:SI 1 "register_operand" ""))
6978    (set (reg:CC CC_REG)
6979         (compare:CC (match_operand:SI 2 "register_operand" "")
6980                     (const_int 0)))]
6981   "(rtx_equal_p (operands[2], operands[0])
6982     || rtx_equal_p (operands[2], operands[1]))
6983     && ! SPARC_FP_REG_P (REGNO (operands[0]))
6984     && ! SPARC_FP_REG_P (REGNO (operands[1]))"
6985   [(parallel [(set (match_dup 0) (match_dup 1))
6986               (set (reg:CC CC_REG)
6987                    (compare:CC (match_dup 1) (const_int 0)))])]
6988   "")
6989
6990 (define_peephole2
6991   [(set (match_operand:DI 0 "register_operand" "")
6992         (match_operand:DI 1 "register_operand" ""))
6993    (set (reg:CCX CC_REG)
6994         (compare:CCX (match_operand:DI 2 "register_operand" "")
6995                     (const_int 0)))]
6996   "TARGET_ARCH64
6997    && (rtx_equal_p (operands[2], operands[0])
6998        || rtx_equal_p (operands[2], operands[1]))
6999    && ! SPARC_FP_REG_P (REGNO (operands[0]))
7000    && ! SPARC_FP_REG_P (REGNO (operands[1]))"
7001   [(parallel [(set (match_dup 0) (match_dup 1))
7002               (set (reg:CCX CC_REG)
7003                    (compare:CCX (match_dup 1) (const_int 0)))])]
7004   "")
7005
7006
7007 ;; Prefetch instructions.
7008
7009 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
7010 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
7011 ;; ??? operations.  With DFA we might be able to model this, but it requires a lot of
7012 ;; ??? state.
7013 (define_expand "prefetch"
7014   [(match_operand 0 "address_operand" "")
7015    (match_operand 1 "const_int_operand" "")
7016    (match_operand 2 "const_int_operand" "")]
7017   "TARGET_V9"
7018 {
7019   if (TARGET_ARCH64)
7020     emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
7021   else
7022     emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
7023   DONE;
7024 })
7025
7026 (define_insn "prefetch_64"
7027   [(prefetch (match_operand:DI 0 "address_operand" "p")
7028              (match_operand:DI 1 "const_int_operand" "n")
7029              (match_operand:DI 2 "const_int_operand" "n"))]
7030   ""
7031 {
7032   static const char * const prefetch_instr[2][2] = {
7033     {
7034       "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7035       "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7036     },
7037     {
7038       "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7039       "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7040     }
7041   };
7042   int read_or_write = INTVAL (operands[1]);
7043   int locality = INTVAL (operands[2]);
7044
7045   gcc_assert (read_or_write == 0 || read_or_write == 1);
7046   gcc_assert (locality >= 0 && locality < 4);
7047   return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7048 }
7049   [(set_attr "type" "load")])
7050
7051 (define_insn "prefetch_32"
7052   [(prefetch (match_operand:SI 0 "address_operand" "p")
7053              (match_operand:SI 1 "const_int_operand" "n")
7054              (match_operand:SI 2 "const_int_operand" "n"))]
7055   ""
7056 {
7057   static const char * const prefetch_instr[2][2] = {
7058     {
7059       "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7060       "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7061     },
7062     {
7063       "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7064       "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7065     }
7066   };
7067   int read_or_write = INTVAL (operands[1]);
7068   int locality = INTVAL (operands[2]);
7069
7070   gcc_assert (read_or_write == 0 || read_or_write == 1);
7071   gcc_assert (locality >= 0 && locality < 4);
7072   return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7073 }
7074   [(set_attr "type" "load")])
7075
7076
7077 ;; Trap instructions.
7078
7079 (define_insn "trap"
7080   [(trap_if (const_int 1) (const_int 5))]
7081   ""
7082   "ta\t5"
7083   [(set_attr "type" "trap")])
7084
7085 (define_expand "ctrapsi4"
7086   [(trap_if (match_operator 0 "noov_compare_operator"
7087              [(match_operand:SI 1 "compare_operand" "")
7088               (match_operand:SI 2 "arith_operand" "")])
7089            (match_operand 3 ""))]
7090   ""
7091   "operands[1] = gen_compare_reg (operands[0]);
7092    if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
7093      FAIL;
7094    operands[2] = const0_rtx;")
7095
7096 (define_expand "ctrapdi4"
7097   [(trap_if (match_operator 0 "noov_compare_operator"
7098              [(match_operand:DI 1 "compare_operand" "")
7099               (match_operand:DI 2 "arith_operand" "")])
7100            (match_operand 3 ""))]
7101   "TARGET_ARCH64"
7102   "operands[1] = gen_compare_reg (operands[0]);
7103    if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
7104      FAIL;
7105    operands[2] = const0_rtx;")
7106
7107
7108 (define_insn ""
7109   [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CC CC_REG) (const_int 0)])
7110             (match_operand:SI 1 "arith_operand" "rM"))]
7111   ""
7112 {
7113   if (TARGET_V9)
7114     return "t%C0\t%%icc, %1";
7115   else
7116     return "t%C0\t%1";
7117 }
7118   [(set_attr "type" "trap")])
7119
7120 (define_insn ""
7121   [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CCX CC_REG) (const_int 0)])
7122             (match_operand:SI 1 "arith_operand" "rM"))]
7123   "TARGET_V9"
7124   "t%C0\t%%xcc, %1"
7125   [(set_attr "type" "trap")])
7126
7127
7128 ;; TLS support instructions.
7129
7130 (define_insn "tgd_hi22"
7131   [(set (match_operand:SI 0 "register_operand" "=r")
7132         (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
7133                             UNSPEC_TLSGD)))]
7134   "TARGET_TLS"
7135   "sethi\\t%%tgd_hi22(%a1), %0")
7136
7137 (define_insn "tgd_lo10"
7138   [(set (match_operand:SI 0 "register_operand" "=r")
7139         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7140                    (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
7141                               UNSPEC_TLSGD)))]
7142   "TARGET_TLS"
7143   "add\\t%1, %%tgd_lo10(%a2), %0")
7144
7145 (define_insn "tgd_add32"
7146   [(set (match_operand:SI 0 "register_operand" "=r")
7147         (plus:SI (match_operand:SI 1 "register_operand" "r")
7148                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7149                              (match_operand 3 "tgd_symbolic_operand" "")]
7150                             UNSPEC_TLSGD)))]
7151   "TARGET_TLS && TARGET_ARCH32"
7152   "add\\t%1, %2, %0, %%tgd_add(%a3)")
7153
7154 (define_insn "tgd_add64"
7155   [(set (match_operand:DI 0 "register_operand" "=r")
7156         (plus:DI (match_operand:DI 1 "register_operand" "r")
7157                  (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7158                              (match_operand 3 "tgd_symbolic_operand" "")]
7159                             UNSPEC_TLSGD)))]
7160   "TARGET_TLS && TARGET_ARCH64"
7161   "add\\t%1, %2, %0, %%tgd_add(%a3)")
7162
7163 (define_insn "tgd_call32"
7164   [(set (match_operand 0 "register_operand" "=r")
7165         (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
7166                                   (match_operand 2 "tgd_symbolic_operand" "")]
7167                                  UNSPEC_TLSGD))
7168               (match_operand 3 "" "")))
7169    (clobber (reg:SI O7_REG))]
7170   "TARGET_TLS && TARGET_ARCH32"
7171   "call\t%a1, %%tgd_call(%a2)%#"
7172   [(set_attr "type" "call")])
7173
7174 (define_insn "tgd_call64"
7175   [(set (match_operand 0 "register_operand" "=r")
7176         (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
7177                                   (match_operand 2 "tgd_symbolic_operand" "")]
7178                                  UNSPEC_TLSGD))
7179               (match_operand 3 "" "")))
7180    (clobber (reg:DI O7_REG))]
7181   "TARGET_TLS && TARGET_ARCH64"
7182   "call\t%a1, %%tgd_call(%a2)%#"
7183   [(set_attr "type" "call")])
7184
7185 (define_insn "tldm_hi22"
7186   [(set (match_operand:SI 0 "register_operand" "=r")
7187         (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7188   "TARGET_TLS"
7189   "sethi\\t%%tldm_hi22(%&), %0")
7190
7191 (define_insn "tldm_lo10"
7192   [(set (match_operand:SI 0 "register_operand" "=r")
7193         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7194                     (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7195   "TARGET_TLS"
7196   "add\\t%1, %%tldm_lo10(%&), %0")
7197
7198 (define_insn "tldm_add32"
7199   [(set (match_operand:SI 0 "register_operand" "=r")
7200         (plus:SI (match_operand:SI 1 "register_operand" "r")
7201                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
7202                             UNSPEC_TLSLDM)))]
7203   "TARGET_TLS && TARGET_ARCH32"
7204   "add\\t%1, %2, %0, %%tldm_add(%&)")
7205
7206 (define_insn "tldm_add64"
7207   [(set (match_operand:DI 0 "register_operand" "=r")
7208         (plus:DI (match_operand:DI 1 "register_operand" "r")
7209                  (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
7210                             UNSPEC_TLSLDM)))]
7211   "TARGET_TLS && TARGET_ARCH64"
7212   "add\\t%1, %2, %0, %%tldm_add(%&)")
7213
7214 (define_insn "tldm_call32"
7215   [(set (match_operand 0 "register_operand" "=r")
7216         (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
7217                                  UNSPEC_TLSLDM))
7218               (match_operand 2 "" "")))
7219    (clobber (reg:SI O7_REG))]
7220   "TARGET_TLS && TARGET_ARCH32"
7221   "call\t%a1, %%tldm_call(%&)%#"
7222   [(set_attr "type" "call")])
7223
7224 (define_insn "tldm_call64"
7225   [(set (match_operand 0 "register_operand" "=r")
7226         (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
7227                                  UNSPEC_TLSLDM))
7228               (match_operand 2 "" "")))
7229    (clobber (reg:DI O7_REG))]
7230   "TARGET_TLS && TARGET_ARCH64"
7231   "call\t%a1, %%tldm_call(%&)%#"
7232   [(set_attr "type" "call")])
7233
7234 (define_insn "tldo_hix22"
7235   [(set (match_operand:SI 0 "register_operand" "=r")
7236         (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
7237                             UNSPEC_TLSLDO)))]
7238   "TARGET_TLS"
7239   "sethi\\t%%tldo_hix22(%a1), %0")
7240
7241 (define_insn "tldo_lox10"
7242   [(set (match_operand:SI 0 "register_operand" "=r")
7243         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7244                    (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
7245                               UNSPEC_TLSLDO)))]
7246   "TARGET_TLS"
7247   "xor\\t%1, %%tldo_lox10(%a2), %0")
7248
7249 (define_insn "tldo_add32"
7250   [(set (match_operand:SI 0 "register_operand" "=r")
7251         (plus:SI (match_operand:SI 1 "register_operand" "r")
7252                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7253                              (match_operand 3 "tld_symbolic_operand" "")]
7254                             UNSPEC_TLSLDO)))]
7255   "TARGET_TLS && TARGET_ARCH32"
7256   "add\\t%1, %2, %0, %%tldo_add(%a3)")
7257
7258 (define_insn "tldo_add64"
7259   [(set (match_operand:DI 0 "register_operand" "=r")
7260         (plus:DI (match_operand:DI 1 "register_operand" "r")
7261                  (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7262                              (match_operand 3 "tld_symbolic_operand" "")]
7263                             UNSPEC_TLSLDO)))]
7264   "TARGET_TLS && TARGET_ARCH64"
7265   "add\\t%1, %2, %0, %%tldo_add(%a3)")
7266
7267 (define_insn "tie_hi22"
7268   [(set (match_operand:SI 0 "register_operand" "=r")
7269         (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
7270                             UNSPEC_TLSIE)))]
7271   "TARGET_TLS"
7272   "sethi\\t%%tie_hi22(%a1), %0")
7273
7274 (define_insn "tie_lo10"
7275   [(set (match_operand:SI 0 "register_operand" "=r")
7276         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7277                    (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
7278                               UNSPEC_TLSIE)))]
7279   "TARGET_TLS"
7280   "add\\t%1, %%tie_lo10(%a2), %0")
7281
7282 (define_insn "tie_ld32"
7283   [(set (match_operand:SI 0 "register_operand" "=r")
7284         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
7285                     (match_operand:SI 2 "register_operand" "r")
7286                     (match_operand 3 "tie_symbolic_operand" "")]
7287                    UNSPEC_TLSIE))]
7288   "TARGET_TLS && TARGET_ARCH32"
7289   "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
7290   [(set_attr "type" "load")])
7291
7292 (define_insn "tie_ld64"
7293   [(set (match_operand:DI 0 "register_operand" "=r")
7294         (unspec:DI [(match_operand:DI 1 "register_operand" "r")
7295                     (match_operand:SI 2 "register_operand" "r")
7296                     (match_operand 3 "tie_symbolic_operand" "")]
7297                    UNSPEC_TLSIE))]
7298   "TARGET_TLS && TARGET_ARCH64"
7299   "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
7300   [(set_attr "type" "load")])
7301
7302 (define_insn "tie_add32"
7303   [(set (match_operand:SI 0 "register_operand" "=r")
7304         (plus:SI (match_operand:SI 1 "register_operand" "r")
7305                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7306                              (match_operand 3 "tie_symbolic_operand" "")]
7307                             UNSPEC_TLSIE)))]
7308   "TARGET_SUN_TLS && TARGET_ARCH32"
7309   "add\\t%1, %2, %0, %%tie_add(%a3)")
7310
7311 (define_insn "tie_add64"
7312   [(set (match_operand:DI 0 "register_operand" "=r")
7313         (plus:DI (match_operand:DI 1 "register_operand" "r")
7314                  (unspec:DI [(match_operand:DI 2 "register_operand" "r")
7315                              (match_operand 3 "tie_symbolic_operand" "")]
7316                             UNSPEC_TLSIE)))]
7317   "TARGET_SUN_TLS && TARGET_ARCH64"
7318   "add\\t%1, %2, %0, %%tie_add(%a3)")
7319
7320 (define_insn "tle_hix22_sp32"
7321   [(set (match_operand:SI 0 "register_operand" "=r")
7322         (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
7323                             UNSPEC_TLSLE)))]
7324   "TARGET_TLS && TARGET_ARCH32"
7325   "sethi\\t%%tle_hix22(%a1), %0")
7326
7327 (define_insn "tle_lox10_sp32"
7328   [(set (match_operand:SI 0 "register_operand" "=r")
7329         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7330                    (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
7331                               UNSPEC_TLSLE)))]
7332   "TARGET_TLS && TARGET_ARCH32"
7333   "xor\\t%1, %%tle_lox10(%a2), %0")
7334
7335 (define_insn "tle_hix22_sp64"
7336   [(set (match_operand:DI 0 "register_operand" "=r")
7337         (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
7338                             UNSPEC_TLSLE)))]
7339   "TARGET_TLS && TARGET_ARCH64"
7340   "sethi\\t%%tle_hix22(%a1), %0")
7341
7342 (define_insn "tle_lox10_sp64"
7343   [(set (match_operand:DI 0 "register_operand" "=r")
7344         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
7345                    (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
7346                               UNSPEC_TLSLE)))]
7347   "TARGET_TLS && TARGET_ARCH64"
7348   "xor\\t%1, %%tle_lox10(%a2), %0")
7349
7350 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
7351 (define_insn "*tldo_ldub_sp32"
7352   [(set (match_operand:QI 0 "register_operand" "=r")
7353         (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7354                                      (match_operand 3 "tld_symbolic_operand" "")]
7355                                     UNSPEC_TLSLDO)
7356                          (match_operand:SI 1 "register_operand" "r"))))]
7357   "TARGET_TLS && TARGET_ARCH32"
7358   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7359   [(set_attr "type" "load")
7360    (set_attr "us3load_type" "3cycle")])
7361
7362 (define_insn "*tldo_ldub1_sp32"
7363   [(set (match_operand:HI 0 "register_operand" "=r")
7364         (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7365                                                      (match_operand 3 "tld_symbolic_operand" "")]
7366                                                     UNSPEC_TLSLDO)
7367                                          (match_operand:SI 1 "register_operand" "r")))))]
7368   "TARGET_TLS && TARGET_ARCH32"
7369   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7370   [(set_attr "type" "load")
7371    (set_attr "us3load_type" "3cycle")])
7372
7373 (define_insn "*tldo_ldub2_sp32"
7374   [(set (match_operand:SI 0 "register_operand" "=r")
7375         (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7376                                                      (match_operand 3 "tld_symbolic_operand" "")]
7377                                                     UNSPEC_TLSLDO)
7378                                          (match_operand:SI 1 "register_operand" "r")))))]
7379   "TARGET_TLS && TARGET_ARCH32"
7380   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7381   [(set_attr "type" "load")
7382    (set_attr "us3load_type" "3cycle")])
7383
7384 (define_insn "*tldo_ldsb1_sp32"
7385   [(set (match_operand:HI 0 "register_operand" "=r")
7386         (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7387                                                      (match_operand 3 "tld_symbolic_operand" "")]
7388                                                     UNSPEC_TLSLDO)
7389                                          (match_operand:SI 1 "register_operand" "r")))))]
7390   "TARGET_TLS && TARGET_ARCH32"
7391   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7392   [(set_attr "type" "sload")
7393    (set_attr "us3load_type" "3cycle")])
7394
7395 (define_insn "*tldo_ldsb2_sp32"
7396   [(set (match_operand:SI 0 "register_operand" "=r")
7397         (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7398                                                      (match_operand 3 "tld_symbolic_operand" "")]
7399                                                     UNSPEC_TLSLDO)
7400                                          (match_operand:SI 1 "register_operand" "r")))))]
7401   "TARGET_TLS && TARGET_ARCH32"
7402   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7403   [(set_attr "type" "sload")
7404    (set_attr "us3load_type" "3cycle")])
7405
7406 (define_insn "*tldo_ldub_sp64"
7407   [(set (match_operand:QI 0 "register_operand" "=r")
7408         (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7409                                      (match_operand 3 "tld_symbolic_operand" "")]
7410                                     UNSPEC_TLSLDO)
7411                          (match_operand:DI 1 "register_operand" "r"))))]
7412   "TARGET_TLS && TARGET_ARCH64"
7413   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7414   [(set_attr "type" "load")
7415    (set_attr "us3load_type" "3cycle")])
7416
7417 (define_insn "*tldo_ldub1_sp64"
7418   [(set (match_operand:HI 0 "register_operand" "=r")
7419         (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7420                                                      (match_operand 3 "tld_symbolic_operand" "")]
7421                                                     UNSPEC_TLSLDO)
7422                                          (match_operand:DI 1 "register_operand" "r")))))]
7423   "TARGET_TLS && TARGET_ARCH64"
7424   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7425   [(set_attr "type" "load")
7426    (set_attr "us3load_type" "3cycle")])
7427
7428 (define_insn "*tldo_ldub2_sp64"
7429   [(set (match_operand:SI 0 "register_operand" "=r")
7430         (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7431                                                      (match_operand 3 "tld_symbolic_operand" "")]
7432                                                     UNSPEC_TLSLDO)
7433                                          (match_operand:DI 1 "register_operand" "r")))))]
7434   "TARGET_TLS && TARGET_ARCH64"
7435   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7436   [(set_attr "type" "load")
7437    (set_attr "us3load_type" "3cycle")])
7438
7439 (define_insn "*tldo_ldub3_sp64"
7440   [(set (match_operand:DI 0 "register_operand" "=r")
7441         (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7442                                                      (match_operand 3 "tld_symbolic_operand" "")]
7443                                                     UNSPEC_TLSLDO)
7444                                          (match_operand:DI 1 "register_operand" "r")))))]
7445   "TARGET_TLS && TARGET_ARCH64"
7446   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7447   [(set_attr "type" "load")
7448    (set_attr "us3load_type" "3cycle")])
7449
7450 (define_insn "*tldo_ldsb1_sp64"
7451   [(set (match_operand:HI 0 "register_operand" "=r")
7452         (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7453                                                      (match_operand 3 "tld_symbolic_operand" "")]
7454                                                     UNSPEC_TLSLDO)
7455                                          (match_operand:DI 1 "register_operand" "r")))))]
7456   "TARGET_TLS && TARGET_ARCH64"
7457   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7458   [(set_attr "type" "sload")
7459    (set_attr "us3load_type" "3cycle")])
7460
7461 (define_insn "*tldo_ldsb2_sp64"
7462   [(set (match_operand:SI 0 "register_operand" "=r")
7463         (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7464                                                      (match_operand 3 "tld_symbolic_operand" "")]
7465                                                     UNSPEC_TLSLDO)
7466                                          (match_operand:DI 1 "register_operand" "r")))))]
7467   "TARGET_TLS && TARGET_ARCH64"
7468   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7469   [(set_attr "type" "sload")
7470    (set_attr "us3load_type" "3cycle")])
7471
7472 (define_insn "*tldo_ldsb3_sp64"
7473   [(set (match_operand:DI 0 "register_operand" "=r")
7474         (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7475                                                      (match_operand 3 "tld_symbolic_operand" "")]
7476                                                     UNSPEC_TLSLDO)
7477                                          (match_operand:DI 1 "register_operand" "r")))))]
7478   "TARGET_TLS && TARGET_ARCH64"
7479   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7480   [(set_attr "type" "sload")
7481    (set_attr "us3load_type" "3cycle")])
7482
7483 (define_insn "*tldo_lduh_sp32"
7484   [(set (match_operand:HI 0 "register_operand" "=r")
7485         (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7486                                      (match_operand 3 "tld_symbolic_operand" "")]
7487                                     UNSPEC_TLSLDO)
7488                          (match_operand:SI 1 "register_operand" "r"))))]
7489   "TARGET_TLS && TARGET_ARCH32"
7490   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7491   [(set_attr "type" "load")
7492    (set_attr "us3load_type" "3cycle")])
7493
7494 (define_insn "*tldo_lduh1_sp32"
7495   [(set (match_operand:SI 0 "register_operand" "=r")
7496         (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7497                                                      (match_operand 3 "tld_symbolic_operand" "")]
7498                                                     UNSPEC_TLSLDO)
7499                                          (match_operand:SI 1 "register_operand" "r")))))]
7500   "TARGET_TLS && TARGET_ARCH32"
7501   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7502   [(set_attr "type" "load")
7503    (set_attr "us3load_type" "3cycle")])
7504
7505 (define_insn "*tldo_ldsh1_sp32"
7506   [(set (match_operand:SI 0 "register_operand" "=r")
7507         (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7508                                                      (match_operand 3 "tld_symbolic_operand" "")]
7509                                                     UNSPEC_TLSLDO)
7510                                          (match_operand:SI 1 "register_operand" "r")))))]
7511   "TARGET_TLS && TARGET_ARCH32"
7512   "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7513   [(set_attr "type" "sload")
7514    (set_attr "us3load_type" "3cycle")])
7515
7516 (define_insn "*tldo_lduh_sp64"
7517   [(set (match_operand:HI 0 "register_operand" "=r")
7518         (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7519                                      (match_operand 3 "tld_symbolic_operand" "")]
7520                                     UNSPEC_TLSLDO)
7521                          (match_operand:DI 1 "register_operand" "r"))))]
7522   "TARGET_TLS && TARGET_ARCH64"
7523   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7524   [(set_attr "type" "load")
7525    (set_attr "us3load_type" "3cycle")])
7526
7527 (define_insn "*tldo_lduh1_sp64"
7528   [(set (match_operand:SI 0 "register_operand" "=r")
7529         (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7530                                                      (match_operand 3 "tld_symbolic_operand" "")]
7531                                                     UNSPEC_TLSLDO)
7532                                          (match_operand:DI 1 "register_operand" "r")))))]
7533   "TARGET_TLS && TARGET_ARCH64"
7534   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7535   [(set_attr "type" "load")
7536    (set_attr "us3load_type" "3cycle")])
7537
7538 (define_insn "*tldo_lduh2_sp64"
7539   [(set (match_operand:DI 0 "register_operand" "=r")
7540         (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7541                                                      (match_operand 3 "tld_symbolic_operand" "")]
7542                                                     UNSPEC_TLSLDO)
7543                                          (match_operand:DI 1 "register_operand" "r")))))]
7544   "TARGET_TLS && TARGET_ARCH64"
7545   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7546   [(set_attr "type" "load")
7547    (set_attr "us3load_type" "3cycle")])
7548
7549 (define_insn "*tldo_ldsh1_sp64"
7550   [(set (match_operand:SI 0 "register_operand" "=r")
7551         (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7552                                                      (match_operand 3 "tld_symbolic_operand" "")]
7553                                                     UNSPEC_TLSLDO)
7554                                          (match_operand:DI 1 "register_operand" "r")))))]
7555   "TARGET_TLS && TARGET_ARCH64"
7556   "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7557   [(set_attr "type" "sload")
7558    (set_attr "us3load_type" "3cycle")])
7559
7560 (define_insn "*tldo_ldsh2_sp64"
7561   [(set (match_operand:DI 0 "register_operand" "=r")
7562         (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7563                                                      (match_operand 3 "tld_symbolic_operand" "")]
7564                                                     UNSPEC_TLSLDO)
7565                                          (match_operand:DI 1 "register_operand" "r")))))]
7566   "TARGET_TLS && TARGET_ARCH64"
7567   "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7568   [(set_attr "type" "sload")
7569    (set_attr "us3load_type" "3cycle")])
7570
7571 (define_insn "*tldo_lduw_sp32"
7572   [(set (match_operand:SI 0 "register_operand" "=r")
7573         (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7574                                      (match_operand 3 "tld_symbolic_operand" "")]
7575                                     UNSPEC_TLSLDO)
7576                          (match_operand:SI 1 "register_operand" "r"))))]
7577   "TARGET_TLS && TARGET_ARCH32"
7578   "ld\t[%1 + %2], %0, %%tldo_add(%3)"
7579   [(set_attr "type" "load")])
7580
7581 (define_insn "*tldo_lduw_sp64"
7582   [(set (match_operand:SI 0 "register_operand" "=r")
7583         (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7584                                      (match_operand 3 "tld_symbolic_operand" "")]
7585                                     UNSPEC_TLSLDO)
7586                          (match_operand:DI 1 "register_operand" "r"))))]
7587   "TARGET_TLS && TARGET_ARCH64"
7588   "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7589   [(set_attr "type" "load")])
7590
7591 (define_insn "*tldo_lduw1_sp64"
7592   [(set (match_operand:DI 0 "register_operand" "=r")
7593         (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7594                                                      (match_operand 3 "tld_symbolic_operand" "")]
7595                                                     UNSPEC_TLSLDO)
7596                                          (match_operand:DI 1 "register_operand" "r")))))]
7597   "TARGET_TLS && TARGET_ARCH64"
7598   "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7599   [(set_attr "type" "load")])
7600
7601 (define_insn "*tldo_ldsw1_sp64"
7602   [(set (match_operand:DI 0 "register_operand" "=r")
7603         (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7604                                                      (match_operand 3 "tld_symbolic_operand" "")]
7605                                                     UNSPEC_TLSLDO)
7606                                          (match_operand:DI 1 "register_operand" "r")))))]
7607   "TARGET_TLS && TARGET_ARCH64"
7608   "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
7609   [(set_attr "type" "sload")
7610    (set_attr "us3load_type" "3cycle")])
7611
7612 (define_insn "*tldo_ldx_sp64"
7613   [(set (match_operand:DI 0 "register_operand" "=r")
7614         (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7615                                      (match_operand 3 "tld_symbolic_operand" "")]
7616                                     UNSPEC_TLSLDO)
7617                          (match_operand:DI 1 "register_operand" "r"))))]
7618   "TARGET_TLS && TARGET_ARCH64"
7619   "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
7620   [(set_attr "type" "load")])
7621
7622 (define_insn "*tldo_stb_sp32"
7623   [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7624                                      (match_operand 3 "tld_symbolic_operand" "")]
7625                                     UNSPEC_TLSLDO)
7626                          (match_operand:SI 1 "register_operand" "r")))
7627         (match_operand:QI 0 "register_operand" "=r"))]
7628   "TARGET_TLS && TARGET_ARCH32"
7629   "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7630   [(set_attr "type" "store")])
7631
7632 (define_insn "*tldo_stb_sp64"
7633   [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7634                                      (match_operand 3 "tld_symbolic_operand" "")]
7635                                     UNSPEC_TLSLDO)
7636                          (match_operand:DI 1 "register_operand" "r")))
7637         (match_operand:QI 0 "register_operand" "=r"))]
7638   "TARGET_TLS && TARGET_ARCH64"
7639   "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7640   [(set_attr "type" "store")])
7641
7642 (define_insn "*tldo_sth_sp32"
7643   [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7644                                      (match_operand 3 "tld_symbolic_operand" "")]
7645                                     UNSPEC_TLSLDO)
7646                          (match_operand:SI 1 "register_operand" "r")))
7647         (match_operand:HI 0 "register_operand" "=r"))]
7648   "TARGET_TLS && TARGET_ARCH32"
7649   "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7650   [(set_attr "type" "store")])
7651
7652 (define_insn "*tldo_sth_sp64"
7653   [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7654                                      (match_operand 3 "tld_symbolic_operand" "")]
7655                                     UNSPEC_TLSLDO)
7656                          (match_operand:DI 1 "register_operand" "r")))
7657         (match_operand:HI 0 "register_operand" "=r"))]
7658   "TARGET_TLS && TARGET_ARCH64"
7659   "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7660   [(set_attr "type" "store")])
7661
7662 (define_insn "*tldo_stw_sp32"
7663   [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7664                                      (match_operand 3 "tld_symbolic_operand" "")]
7665                                     UNSPEC_TLSLDO)
7666                          (match_operand:SI 1 "register_operand" "r")))
7667         (match_operand:SI 0 "register_operand" "=r"))]
7668   "TARGET_TLS && TARGET_ARCH32"
7669   "st\t%0, [%1 + %2], %%tldo_add(%3)"
7670   [(set_attr "type" "store")])
7671
7672 (define_insn "*tldo_stw_sp64"
7673   [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7674                                      (match_operand 3 "tld_symbolic_operand" "")]
7675                                     UNSPEC_TLSLDO)
7676                          (match_operand:DI 1 "register_operand" "r")))
7677         (match_operand:SI 0 "register_operand" "=r"))]
7678   "TARGET_TLS && TARGET_ARCH64"
7679   "stw\t%0, [%1 + %2], %%tldo_add(%3)"
7680   [(set_attr "type" "store")])
7681
7682 (define_insn "*tldo_stx_sp64"
7683   [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7684                                      (match_operand 3 "tld_symbolic_operand" "")]
7685                                     UNSPEC_TLSLDO)
7686                          (match_operand:DI 1 "register_operand" "r")))
7687         (match_operand:DI 0 "register_operand" "=r"))]
7688   "TARGET_TLS && TARGET_ARCH64"
7689   "stx\t%0, [%1 + %2], %%tldo_add(%3)"
7690   [(set_attr "type" "store")])
7691
7692
7693 ;; Stack protector instructions.
7694
7695 (define_expand "stack_protect_set"
7696   [(match_operand 0 "memory_operand" "")
7697    (match_operand 1 "memory_operand" "")]
7698   ""
7699 {
7700 #ifdef TARGET_THREAD_SSP_OFFSET
7701   rtx tlsreg = gen_rtx_REG (Pmode, 7);
7702   rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7703   operands[1] = gen_rtx_MEM (Pmode, addr);
7704 #endif
7705   if (TARGET_ARCH64)
7706     emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
7707   else
7708     emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
7709   DONE;
7710 })
7711
7712 (define_insn "stack_protect_setsi"
7713   [(set (match_operand:SI 0 "memory_operand" "=m")
7714         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7715    (set (match_scratch:SI 2 "=&r") (const_int 0))]
7716   "TARGET_ARCH32"
7717   "ld\t%1, %2\;st\t%2, %0\;mov\t0, %2"
7718   [(set_attr "type" "multi")
7719    (set_attr "length" "3")])
7720
7721 (define_insn "stack_protect_setdi"
7722   [(set (match_operand:DI 0 "memory_operand" "=m")
7723         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7724    (set (match_scratch:DI 2 "=&r") (const_int 0))]
7725   "TARGET_ARCH64"
7726   "ldx\t%1, %2\;stx\t%2, %0\;mov\t0, %2"
7727   [(set_attr "type" "multi")
7728    (set_attr "length" "3")])
7729
7730 (define_expand "stack_protect_test"
7731   [(match_operand 0 "memory_operand" "")
7732    (match_operand 1 "memory_operand" "")
7733    (match_operand 2 "" "")]
7734   ""
7735 {
7736   rtx result, test;
7737 #ifdef TARGET_THREAD_SSP_OFFSET
7738   rtx tlsreg = gen_rtx_REG (Pmode, 7);
7739   rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7740   operands[1] = gen_rtx_MEM (Pmode, addr);
7741 #endif
7742   if (TARGET_ARCH64)
7743     {
7744       result = gen_reg_rtx (Pmode);
7745       emit_insn (gen_stack_protect_testdi (result, operands[0], operands[1]));
7746       test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7747       emit_jump_insn (gen_cbranchdi4 (test, result, const0_rtx, operands[2]));
7748     }
7749   else
7750     {
7751       emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
7752       result = gen_rtx_REG (CCmode, SPARC_ICC_REG);
7753       test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7754       emit_jump_insn (gen_cbranchcc4 (test, result, const0_rtx, operands[2]));
7755     }
7756   DONE;
7757 })
7758
7759 (define_insn "stack_protect_testsi"
7760   [(set (reg:CC CC_REG)
7761         (unspec:CC [(match_operand:SI 0 "memory_operand" "m")
7762                     (match_operand:SI 1 "memory_operand" "m")]
7763                    UNSPEC_SP_TEST))
7764    (set (match_scratch:SI 3 "=r") (const_int 0))
7765    (clobber (match_scratch:SI 2 "=&r"))]
7766   "TARGET_ARCH32"
7767   "ld\t%0, %2\;ld\t%1, %3\;xorcc\t%2, %3, %2\;mov\t0, %3"
7768   [(set_attr "type" "multi")
7769    (set_attr "length" "4")])
7770
7771 (define_insn "stack_protect_testdi"
7772   [(set (match_operand:DI 0 "register_operand" "=&r")
7773         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
7774                     (match_operand:DI 2 "memory_operand" "m")]
7775                    UNSPEC_SP_TEST))
7776    (set (match_scratch:DI 3 "=r") (const_int 0))]
7777   "TARGET_ARCH64"
7778   "ldx\t%1, %0\;ldx\t%2, %3\;xor\t%0, %3, %0\;mov\t0, %3"
7779   [(set_attr "type" "multi")
7780    (set_attr "length" "4")])
7781
7782
7783 ;; Vector instructions.
7784
7785 (define_insn "addv2si3"
7786   [(set (match_operand:V2SI 0 "register_operand" "=e")
7787         (plus:V2SI (match_operand:V2SI 1 "register_operand" "e")
7788                    (match_operand:V2SI 2 "register_operand" "e")))]
7789   "TARGET_VIS"
7790   "fpadd32\t%1, %2, %0"
7791   [(set_attr "type" "fga")
7792    (set_attr "fptype" "double")])
7793
7794 (define_insn "addv4hi3"
7795   [(set (match_operand:V4HI 0 "register_operand" "=e")
7796          (plus:V4HI (match_operand:V4HI 1 "register_operand" "e")
7797                     (match_operand:V4HI 2 "register_operand" "e")))]
7798   "TARGET_VIS"
7799   "fpadd16\t%1, %2, %0"
7800   [(set_attr "type" "fga")
7801    (set_attr "fptype" "double")])
7802
7803 ;; fpadd32s is emitted by the addsi3 pattern.
7804
7805 (define_insn "addv2hi3"
7806   [(set (match_operand:V2HI 0 "register_operand" "=f")
7807         (plus:V2HI (match_operand:V2HI 1 "register_operand" "f")
7808                    (match_operand:V2HI 2 "register_operand" "f")))]
7809   "TARGET_VIS"
7810   "fpadd16s\t%1, %2, %0"
7811   [(set_attr "type" "fga")
7812    (set_attr "fptype" "single")])
7813
7814 (define_insn "subv2si3"
7815   [(set (match_operand:V2SI 0 "register_operand" "=e")
7816         (minus:V2SI (match_operand:V2SI 1 "register_operand" "e")
7817                     (match_operand:V2SI 2 "register_operand" "e")))]
7818   "TARGET_VIS"
7819   "fpsub32\t%1, %2, %0"
7820   [(set_attr "type" "fga")
7821    (set_attr "fptype" "double")])
7822
7823 (define_insn "subv4hi3"
7824   [(set (match_operand:V4HI 0 "register_operand" "=e")
7825         (minus:V4HI (match_operand:V4HI 1 "register_operand" "e")
7826                     (match_operand:V4HI 2 "register_operand" "e")))]
7827   "TARGET_VIS"
7828   "fpsub16\t%1, %2, %0"
7829   [(set_attr "type" "fga")
7830    (set_attr "fptype" "double")])
7831
7832 ;; fpsub32s is emitted by the subsi3 pattern.
7833
7834 (define_insn "subv2hi3"
7835   [(set (match_operand:V2HI 0 "register_operand" "=f")
7836         (minus:V2HI (match_operand:V2HI 1 "register_operand" "f")
7837                     (match_operand:V2HI 2 "register_operand" "f")))]
7838   "TARGET_VIS"
7839   "fpsub16s\t%1, %2, %0"
7840   [(set_attr "type" "fga")
7841    (set_attr "fptype" "single")])
7842
7843 ;; All other logical instructions have integer equivalents so they
7844 ;; are defined together.
7845
7846 ;; (ior (not (op1)) (not (op2))) is the canonical form of NAND.
7847
7848 (define_insn "*nand<V64:mode>_vis"
7849   [(set (match_operand:V64 0 "register_operand" "=e")
7850         (ior:V64 (not:V64 (match_operand:V64 1 "register_operand" "e"))
7851                  (not:V64 (match_operand:V64 2 "register_operand" "e"))))]
7852   "TARGET_VIS"
7853   "fnand\t%1, %2, %0"
7854   [(set_attr "type" "fga")
7855    (set_attr "fptype" "double")])
7856
7857 (define_insn "*nand<V32:mode>_vis"
7858   [(set (match_operand:V32 0 "register_operand" "=f")
7859          (ior:V32 (not:V32 (match_operand:V32 1 "register_operand" "f"))
7860                   (not:V32 (match_operand:V32 2 "register_operand" "f"))))]
7861   "TARGET_VIS"
7862   "fnands\t%1, %2, %0"
7863   [(set_attr "type" "fga")
7864    (set_attr "fptype" "single")])
7865
7866 ;; Hard to generate VIS instructions.  We have builtins for these.
7867
7868 (define_insn "fpack16_vis"
7869   [(set (match_operand:V4QI 0 "register_operand" "=f")
7870         (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e")
7871                       (reg:DI GSR_REG)]
7872                       UNSPEC_FPACK16))]
7873   "TARGET_VIS"
7874   "fpack16\t%1, %0"
7875   [(set_attr "type" "fga")
7876    (set_attr "fptype" "double")])
7877
7878 (define_insn "fpackfix_vis"
7879   [(set (match_operand:V2HI 0 "register_operand" "=f")
7880         (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e")
7881                       (reg:DI GSR_REG)]
7882                       UNSPEC_FPACKFIX))]
7883   "TARGET_VIS"
7884   "fpackfix\t%1, %0"
7885   [(set_attr "type" "fga")
7886    (set_attr "fptype" "double")])
7887
7888 (define_insn "fpack32_vis"
7889   [(set (match_operand:V8QI 0 "register_operand" "=e")
7890         (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e")
7891                       (match_operand:V8QI 2 "register_operand" "e")
7892                       (reg:DI GSR_REG)]
7893                      UNSPEC_FPACK32))]
7894   "TARGET_VIS"
7895   "fpack32\t%1, %2, %0"
7896   [(set_attr "type" "fga")
7897    (set_attr "fptype" "double")])
7898
7899 (define_insn "fexpand_vis"
7900   [(set (match_operand:V4HI 0 "register_operand" "=e")
7901         (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")]
7902          UNSPEC_FEXPAND))]
7903  "TARGET_VIS"
7904  "fexpand\t%1, %0"
7905  [(set_attr "type" "fga")
7906   (set_attr "fptype" "double")])
7907
7908 ;; It may be possible to describe this operation as (1 indexed):
7909 ;; (vec_select (vec_duplicate (vec_duplicate (vec_concat 1 2)))
7910 ;;  1,5,10,14,19,23,28,32)
7911 ;; Note that (vec_merge:V8QI [(V4QI) (V4QI)] (10101010 = 170) doesn't work
7912 ;; because vec_merge expects all the operands to be of the same type.
7913 (define_insn "fpmerge_vis"
7914   [(set (match_operand:V8QI 0 "register_operand" "=e")
7915         (unspec:V8QI [(match_operand:V4QI 1 "register_operand" "f")
7916                       (match_operand:V4QI 2 "register_operand" "f")]
7917          UNSPEC_FPMERGE))]
7918  "TARGET_VIS"
7919  "fpmerge\t%1, %2, %0"
7920  [(set_attr "type" "fga")
7921   (set_attr "fptype" "double")])
7922
7923 ;; Partitioned multiply instructions
7924 (define_insn "fmul8x16_vis"
7925   [(set (match_operand:V4HI 0 "register_operand" "=e")
7926         (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
7927                    (match_operand:V4HI 2 "register_operand" "e")))]
7928   "TARGET_VIS"
7929   "fmul8x16\t%1, %2, %0"
7930   [(set_attr "type" "fpmul")
7931    (set_attr "fptype" "double")])
7932
7933 ;; Only one of the following two insns can be a multiply.
7934 (define_insn "fmul8x16au_vis"
7935   [(set (match_operand:V4HI 0 "register_operand" "=e")
7936         (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
7937                    (match_operand:V2HI 2 "register_operand" "f")))]
7938   "TARGET_VIS"
7939   "fmul8x16au\t%1, %2, %0"
7940   [(set_attr "type" "fpmul")
7941    (set_attr "fptype" "double")])
7942
7943 (define_insn "fmul8x16al_vis"
7944   [(set (match_operand:V4HI 0 "register_operand" "=e")
7945         (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
7946                       (match_operand:V2HI 2 "register_operand" "f")]
7947          UNSPEC_MUL16AL))]
7948   "TARGET_VIS"
7949   "fmul8x16al\t%1, %2, %0"
7950   [(set_attr "type" "fpmul")
7951    (set_attr "fptype" "double")])
7952
7953 ;; Only one of the following two insns can be a multiply.
7954 (define_insn "fmul8sux16_vis"
7955   [(set (match_operand:V4HI 0 "register_operand" "=e")
7956         (mult:V4HI (match_operand:V8QI 1 "register_operand" "e")
7957                    (match_operand:V4HI 2 "register_operand" "e")))]
7958   "TARGET_VIS"
7959   "fmul8sux16\t%1, %2, %0"
7960   [(set_attr "type" "fpmul")
7961    (set_attr "fptype" "double")])
7962
7963 (define_insn "fmul8ulx16_vis"
7964   [(set (match_operand:V4HI 0 "register_operand" "=e")
7965         (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
7966                       (match_operand:V4HI 2 "register_operand" "e")]
7967          UNSPEC_MUL8UL))]
7968   "TARGET_VIS"
7969   "fmul8ulx16\t%1, %2, %0"
7970   [(set_attr "type" "fpmul")
7971    (set_attr "fptype" "double")])
7972
7973 ;; Only one of the following two insns can be a multiply.
7974 (define_insn "fmuld8sux16_vis"
7975   [(set (match_operand:V2SI 0 "register_operand" "=e")
7976         (mult:V2SI (match_operand:V4QI 1 "register_operand" "f")
7977                    (match_operand:V2HI 2 "register_operand" "f")))]
7978   "TARGET_VIS"
7979   "fmuld8sux16\t%1, %2, %0"
7980   [(set_attr "type" "fpmul")
7981    (set_attr "fptype" "double")])
7982
7983 (define_insn "fmuld8ulx16_vis"
7984   [(set (match_operand:V2SI 0 "register_operand" "=e")
7985         (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
7986                       (match_operand:V2HI 2 "register_operand" "f")]
7987          UNSPEC_MULDUL))]
7988   "TARGET_VIS"
7989   "fmuld8ulx16\t%1, %2, %0"
7990   [(set_attr "type" "fpmul")
7991    (set_attr "fptype" "double")])
7992
7993 (define_expand "wrgsr_vis"
7994   [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" ""))]
7995   "TARGET_VIS"
7996 {
7997   if (! TARGET_ARCH64)
7998     {
7999       emit_insn (gen_wrgsr_v8plus (operands[0]));
8000       DONE;
8001     }
8002 })
8003
8004 (define_insn "*wrgsr_sp64"
8005   [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" "rI"))]
8006   "TARGET_VIS && TARGET_ARCH64"
8007   "wr\t%%g0, %0, %%gsr"
8008   [(set_attr "type" "gsr")])
8009
8010 (define_insn "wrgsr_v8plus"
8011   [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" "I,r"))
8012    (clobber (match_scratch:SI 1 "=X,&h"))]
8013   "TARGET_VIS && ! TARGET_ARCH64"
8014 {
8015   if (GET_CODE (operands[0]) == CONST_INT
8016       || sparc_check_64 (operands[0], insn))
8017     return "wr\t%%g0, %0, %%gsr";
8018
8019   output_asm_insn("srl\t%L0, 0, %L0", operands);
8020   return "sllx\t%H0, 32, %1\n\tor\t%L0, %1, %1\n\twr\t%%g0, %1, %%gsr";
8021 }
8022   [(set_attr "type" "multi")])
8023
8024 (define_expand "rdgsr_vis"
8025   [(set (match_operand:DI 0 "register_operand" "") (reg:DI GSR_REG))]
8026   "TARGET_VIS"
8027 {
8028   if (! TARGET_ARCH64)
8029     {
8030       emit_insn (gen_rdgsr_v8plus (operands[0]));
8031       DONE;
8032     }
8033 })
8034
8035 (define_insn "*rdgsr_sp64"
8036   [(set (match_operand:DI 0 "register_operand" "=r") (reg:DI GSR_REG))]
8037   "TARGET_VIS && TARGET_ARCH64"
8038   "rd\t%%gsr, %0"
8039   [(set_attr "type" "gsr")])
8040
8041 (define_insn "rdgsr_v8plus"
8042   [(set (match_operand:DI 0 "register_operand" "=r") (reg:DI GSR_REG))
8043    (clobber (match_scratch:SI 1 "=&h"))]
8044   "TARGET_VIS && ! TARGET_ARCH64"
8045 {
8046   return "rd\t%%gsr, %1\n\tsrlx\t%1, 32, %H0\n\tmov %1, %L0";
8047 }
8048   [(set_attr "type" "multi")])
8049
8050 ;; Using faligndata only makes sense after an alignaddr since the choice of
8051 ;; bytes to take out of each operand is dependent on the results of the last
8052 ;; alignaddr.
8053 (define_insn "faligndata<V64I:mode>_vis"
8054   [(set (match_operand:V64I 0 "register_operand" "=e")
8055         (unspec:V64I [(match_operand:V64I 1 "register_operand" "e")
8056                       (match_operand:V64I 2 "register_operand" "e")
8057                       (reg:DI GSR_REG)]
8058          UNSPEC_ALIGNDATA))]
8059   "TARGET_VIS"
8060   "faligndata\t%1, %2, %0"
8061   [(set_attr "type" "fga")
8062    (set_attr "fptype" "double")])
8063
8064 (define_insn "alignaddrsi_vis"
8065   [(set (match_operand:SI 0 "register_operand" "=r")
8066         (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
8067                  (match_operand:SI 2 "register_or_zero_operand" "rJ")))
8068    (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8069         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
8070   "TARGET_VIS"
8071   "alignaddr\t%r1, %r2, %0")
8072
8073 (define_insn "alignaddrdi_vis"
8074   [(set (match_operand:DI 0 "register_operand" "=r")
8075         (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
8076                  (match_operand:DI 2 "register_or_zero_operand" "rJ")))
8077    (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8078         (plus:DI (match_dup 1) (match_dup 2)))]
8079   "TARGET_VIS"
8080   "alignaddr\t%r1, %r2, %0")
8081
8082 (define_insn "alignaddrlsi_vis"
8083   [(set (match_operand:SI 0 "register_operand" "=r")
8084         (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
8085                  (match_operand:SI 2 "register_or_zero_operand" "rJ")))
8086    (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8087         (xor:DI (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2)))
8088                 (const_int 7)))]
8089   "TARGET_VIS"
8090   "alignaddrl\t%r1, %r2, %0")
8091
8092 (define_insn "alignaddrldi_vis"
8093   [(set (match_operand:DI 0 "register_operand" "=r")
8094         (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
8095                  (match_operand:DI 2 "register_or_zero_operand" "rJ")))
8096    (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8097         (xor:DI (plus:DI (match_dup 1) (match_dup 2))
8098                 (const_int 7)))]
8099   "TARGET_VIS"
8100   "alignaddrl\t%r1, %r2, %0")
8101
8102 (define_insn "pdist_vis"
8103   [(set (match_operand:DI 0 "register_operand" "=e")
8104         (unspec:DI [(match_operand:V8QI 1 "register_operand" "e")
8105                     (match_operand:V8QI 2 "register_operand" "e")
8106                     (match_operand:DI 3 "register_operand" "0")]
8107          UNSPEC_PDIST))]
8108   "TARGET_VIS"
8109   "pdist\t%1, %2, %0"
8110   [(set_attr "type" "fga")
8111    (set_attr "fptype" "double")])
8112
8113 ;; Edge instructions produce condition codes equivalent to a 'subcc'
8114 ;; with the same operands.
8115 (define_insn "edge8<P:mode>_vis"
8116   [(set (reg:CC_NOOV CC_REG)
8117         (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
8118                                   (match_operand:P 2 "register_operand" "rJ"))
8119                          (const_int 0)))
8120    (set (match_operand:P 0 "register_operand" "=r")
8121         (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8))]
8122   "TARGET_VIS"
8123   "edge8\t%r1, %r2, %0"
8124   [(set_attr "type" "edge")])
8125
8126 (define_insn "edge8l<P:mode>_vis"
8127   [(set (reg:CC_NOOV CC_REG)
8128         (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
8129                                   (match_operand:P 2 "register_operand" "rJ"))
8130                          (const_int 0)))
8131    (set (match_operand:P 0 "register_operand" "=r")
8132         (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8L))]
8133   "TARGET_VIS"
8134   "edge8l\t%r1, %r2, %0"
8135   [(set_attr "type" "edge")])
8136
8137 (define_insn "edge16<P:mode>_vis"
8138   [(set (reg:CC_NOOV CC_REG)
8139         (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
8140                                   (match_operand:P 2 "register_operand" "rJ"))
8141                          (const_int 0)))
8142    (set (match_operand:P 0 "register_operand" "=r")
8143         (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16))]
8144   "TARGET_VIS"
8145   "edge16\t%r1, %r2, %0"
8146   [(set_attr "type" "edge")])
8147
8148 (define_insn "edge16l<P:mode>_vis"
8149   [(set (reg:CC_NOOV CC_REG)
8150         (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
8151                                   (match_operand:P 2 "register_operand" "rJ"))
8152                          (const_int 0)))
8153    (set (match_operand:P 0 "register_operand" "=r")
8154         (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16L))]
8155   "TARGET_VIS"
8156   "edge16l\t%r1, %r2, %0"
8157   [(set_attr "type" "edge")])
8158
8159 (define_insn "edge32<P:mode>_vis"
8160   [(set (reg:CC_NOOV CC_REG)
8161         (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
8162                                   (match_operand:P 2 "register_operand" "rJ"))
8163                          (const_int 0)))
8164    (set (match_operand:P 0 "register_operand" "=r")
8165         (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32))]
8166   "TARGET_VIS"
8167   "edge32\t%r1, %r2, %0"
8168   [(set_attr "type" "edge")])
8169
8170 (define_insn "edge32l<P:mode>_vis"
8171   [(set (reg:CC_NOOV CC_REG)
8172         (compare:CC_NOOV (minus:P (match_operand:P 1 "register_operand" "rJ")
8173                                   (match_operand:P 2 "register_operand" "rJ"))
8174                          (const_int 0)))
8175    (set (match_operand:P 0 "register_operand" "=r")
8176         (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32L))]
8177   "TARGET_VIS"
8178   "edge32l\t%r1, %r2, %0"
8179   [(set_attr "type" "edge")])
8180
8181 (define_code_iterator gcond [le ne gt eq])
8182 (define_mode_iterator GCM [V4HI V2SI])
8183 (define_mode_attr gcm_name [(V4HI "16") (V2SI "32")])
8184
8185 (define_insn "fcmp<code><GCM:gcm_name><P:mode>_vis"
8186   [(set (match_operand:P 0 "register_operand" "=r")
8187         (unspec:P [(gcond:GCM (match_operand:GCM 1 "register_operand" "e")
8188                               (match_operand:GCM 2 "register_operand" "e"))]
8189          UNSPEC_FCMP))]
8190   "TARGET_VIS"
8191   "fcmp<code><GCM:gcm_name>\t%1, %2, %0"
8192   [(set_attr "type" "fpmul")
8193    (set_attr "fptype" "double")])
8194
8195 (define_insn "array8<P:mode>_vis"
8196   [(set (match_operand:P 0 "register_operand" "=r")
8197         (unspec:P [(match_operand:P 1 "register_operand" "rJ")
8198                    (match_operand:P 2 "register_operand" "rJ")]
8199                   UNSPEC_ARRAY8))]
8200   "TARGET_VIS"
8201   "array8\t%r1, %r2, %0"
8202   [(set_attr "type" "array")])
8203
8204 (define_insn "array16<P:mode>_vis"
8205   [(set (match_operand:P 0 "register_operand" "=r")
8206         (unspec:P [(match_operand:P 1 "register_operand" "rJ")
8207                    (match_operand:P 2 "register_operand" "rJ")]
8208                   UNSPEC_ARRAY16))]
8209   "TARGET_VIS"
8210   "array16\t%r1, %r2, %0"
8211   [(set_attr "type" "array")])
8212
8213 (define_insn "array32<P:mode>_vis"
8214   [(set (match_operand:P 0 "register_operand" "=r")
8215         (unspec:P [(match_operand:P 1 "register_operand" "rJ")
8216                    (match_operand:P 2 "register_operand" "rJ")]
8217                   UNSPEC_ARRAY32))]
8218   "TARGET_VIS"
8219   "array32\t%r1, %r2, %0"
8220   [(set_attr "type" "array")])
8221
8222 (define_insn "bmaskdi_vis"
8223   [(set (match_operand:DI 0 "register_operand" "=r")
8224         (plus:DI (match_operand:DI 1 "register_operand" "rJ")
8225                  (match_operand:DI 2 "register_operand" "rJ")))
8226    (set (zero_extract:DI (reg:DI GSR_REG) (const_int 32) (const_int 32))
8227         (plus:DI (match_dup 1) (match_dup 2)))]
8228   "TARGET_VIS2"
8229   "bmask\t%r1, %r2, %0"
8230   [(set_attr "type" "array")])
8231
8232 (define_insn "bmasksi_vis"
8233   [(set (match_operand:SI 0 "register_operand" "=r")
8234         (plus:SI (match_operand:SI 1 "register_operand" "rJ")
8235                  (match_operand:SI 2 "register_operand" "rJ")))
8236    (set (zero_extract:DI (reg:DI GSR_REG) (const_int 32) (const_int 32))
8237         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
8238   "TARGET_VIS2"
8239   "bmask\t%r1, %r2, %0"
8240   [(set_attr "type" "array")])
8241
8242 (define_insn "bshuffle<V64I:mode>_vis"
8243   [(set (match_operand:V64I 0 "register_operand" "=e")
8244         (unspec:V64I [(match_operand:V64I 1 "register_operand" "e")
8245                       (match_operand:V64I 2 "register_operand" "e")
8246                       (reg:DI GSR_REG)]
8247                      UNSPEC_BSHUFFLE))]
8248   "TARGET_VIS2"
8249   "bshuffle\t%1, %2, %0"
8250   [(set_attr "type" "fga")
8251    (set_attr "fptype" "double")])
8252
8253 ;; VIS 2.0 adds edge variants which do not set the condition codes
8254 (define_insn "edge8n<P:mode>_vis"
8255   [(set (match_operand:P 0 "register_operand" "=r")
8256         (unspec:P [(match_operand:P 1 "register_operand" "rJ")
8257                    (match_operand:P 2 "register_operand" "rJ")]
8258                   UNSPEC_EDGE8N))]
8259   "TARGET_VIS2"
8260   "edge8n\t%r1, %r2, %0"
8261   [(set_attr "type" "edgen")])
8262
8263 (define_insn "edge8ln<P:mode>_vis"
8264   [(set (match_operand:P 0 "register_operand" "=r")
8265         (unspec:P [(match_operand:P 1 "register_operand" "rJ")
8266                    (match_operand:P 2 "register_operand" "rJ")]
8267                   UNSPEC_EDGE8LN))]
8268   "TARGET_VIS2"
8269   "edge8ln\t%r1, %r2, %0"
8270   [(set_attr "type" "edgen")])
8271
8272 (define_insn "edge16n<P:mode>_vis"
8273   [(set (match_operand:P 0 "register_operand" "=r")
8274         (unspec:P [(match_operand:P 1 "register_operand" "rJ")
8275                    (match_operand:P 2 "register_operand" "rJ")]
8276                   UNSPEC_EDGE16N))]
8277   "TARGET_VIS2"
8278   "edge16n\t%r1, %r2, %0"
8279   [(set_attr "type" "edgen")])
8280
8281 (define_insn "edge16ln<P:mode>_vis"
8282   [(set (match_operand:P 0 "register_operand" "=r")
8283         (unspec:P [(match_operand:P 1 "register_operand" "rJ")
8284                    (match_operand:P 2 "register_operand" "rJ")]
8285                   UNSPEC_EDGE16LN))]
8286   "TARGET_VIS2"
8287   "edge16ln\t%r1, %r2, %0"
8288   [(set_attr "type" "edgen")])
8289
8290 (define_insn "edge32n<P:mode>_vis"
8291   [(set (match_operand:P 0 "register_operand" "=r")
8292         (unspec:P [(match_operand:P 1 "register_operand" "rJ")
8293                    (match_operand:P 2 "register_operand" "rJ")]
8294                   UNSPEC_EDGE32N))]
8295   "TARGET_VIS2"
8296   "edge32n\t%r1, %r2, %0"
8297   [(set_attr "type" "edgen")])
8298
8299 (define_insn "edge32ln<P:mode>_vis"
8300   [(set (match_operand:P 0 "register_operand" "=r")
8301         (unspec:P [(match_operand:P 1 "register_operand" "rJ")
8302                    (match_operand:P 2 "register_operand" "rJ")]
8303                   UNSPEC_EDGE32LN))]
8304   "TARGET_VIS2"
8305   "edge32ln\t%r1, %r2, %0"
8306   [(set_attr "type" "edge")])
8307
8308 ;; Conditional moves are possible via fcmpX --> cmaskX -> bshuffle
8309 (define_insn "cmask8<P:mode>_vis"
8310   [(set (reg:DI GSR_REG)
8311         (unspec:DI [(match_operand:P 0 "register_operand" "r")
8312                     (reg:DI GSR_REG)]
8313                    UNSPEC_CMASK8))]
8314   "TARGET_VIS3"
8315   "cmask8\t%r0")
8316
8317 (define_insn "cmask16<P:mode>_vis"
8318   [(set (reg:DI GSR_REG)
8319         (unspec:DI [(match_operand:P 0 "register_operand" "r")
8320                     (reg:DI GSR_REG)]
8321                    UNSPEC_CMASK16))]
8322   "TARGET_VIS3"
8323   "cmask16\t%r0")
8324
8325 (define_insn "cmask32<P:mode>_vis"
8326   [(set (reg:DI GSR_REG)
8327         (unspec:DI [(match_operand:P 0 "register_operand" "r")
8328                     (reg:DI GSR_REG)]
8329                    UNSPEC_CMASK32))]
8330   "TARGET_VIS3"
8331   "cmask32\t%r0")
8332
8333 (define_insn "fchksm16_vis"
8334   [(set (match_operand:V4HI 0 "register_operand" "=e")
8335         (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "e")
8336                       (match_operand:V4HI 2 "register_operand" "e")]
8337                      UNSPEC_FCHKSM16))]
8338   "TARGET_VIS3"
8339   "fchksm16\t%1, %2, %0")
8340
8341 (define_code_iterator vis3_shift [ashift ss_ashift lshiftrt ashiftrt])
8342 (define_code_attr vis3_shift_insn
8343   [(ashift "fsll") (ss_ashift "fslas") (lshiftrt "fsrl") (ashiftrt "fsra")])
8344    
8345 (define_insn "<vis3_shift_insn><vbits>_vis"
8346   [(set (match_operand:V64N8 0 "register_operand" "=<vconstr>")
8347         (vis3_shift:V64N8 (match_operand:V64N8 1 "register_operand" "<vconstr>")
8348                           (match_operand:V64N8 2 "register_operand" "<vconstr>")))]
8349   "TARGET_VIS3"
8350   "<vis3_shift_insn><vbits>\t%1, %2, %0")
8351
8352 (define_insn "pdistn<mode>_vis"
8353   [(set (match_operand:P 0 "register_operand" "=r")
8354         (unspec:P [(match_operand:V8QI 1 "register_operand" "e")
8355                    (match_operand:V8QI 2 "register_operand" "e")]
8356          UNSPEC_PDISTN))]
8357   "TARGET_VIS3"
8358   "pdistn\t%1, %2, %0")
8359
8360 (define_insn "fmean16_vis"
8361   [(set (match_operand:V4HI 0 "register_operand" "=e")
8362         (truncate:V4HI
8363           (lshiftrt:V4SI
8364             (plus:V4SI
8365               (plus:V4SI
8366                 (zero_extend:V4SI
8367                   (match_operand:V4HI 1 "register_operand" "e"))
8368                 (zero_extend:V4SI
8369                   (match_operand:V4HI 2 "register_operand" "e")))
8370               (const_vector:V4SI [(const_int 1) (const_int 1)
8371                                   (const_int 1) (const_int 1)]))
8372           (const_int 1))))]
8373   "TARGET_VIS3"
8374   "fmean16\t%1, %2, %0")
8375
8376 (define_insn "fpadd64_vis"
8377   [(set (match_operand:DI 0 "register_operand" "=e")
8378         (plus:DI (match_operand:DI 1 "register_operand" "e")
8379                  (match_operand:DI 2 "register_operand" "e")))]
8380   "TARGET_VIS3"
8381   "fpadd64\t%1, %2, %0")
8382
8383 (define_insn "fpsub64_vis"
8384   [(set (match_operand:DI 0 "register_operand" "=e")
8385         (minus:DI (match_operand:DI 1 "register_operand" "e")
8386                   (match_operand:DI 2 "register_operand" "e")))]
8387   "TARGET_VIS3"
8388   "fpsub64\t%1, %2, %0")
8389
8390 (define_mode_iterator VASS [V4HI V2SI V2HI SI])
8391 (define_code_iterator vis3_addsub_ss [ss_plus ss_minus])
8392 (define_code_attr vis3_addsub_ss_insn
8393   [(ss_plus "fpadds") (ss_minus "fpsubs")])
8394
8395 (define_insn "<vis3_addsub_ss_insn><vbits>_vis"
8396   [(set (match_operand:VASS 0 "register_operand" "=<vconstr>")
8397         (vis3_addsub_ss:VASS (match_operand:VASS 1 "register_operand" "<vconstr>")
8398                              (match_operand:VASS 2 "register_operand" "<vconstr>")))]
8399   "TARGET_VIS3"
8400   "<vis3_addsub_ss_insn><vbits>\t%1, %2, %0")
8401
8402 (define_insn "fucmp<code>8<P:mode>_vis"
8403   [(set (match_operand:P 0 "register_operand" "=r")
8404         (unspec:P [(gcond:V8QI (match_operand:V8QI 1 "register_operand" "e")
8405                                (match_operand:V8QI 2 "register_operand" "e"))]
8406          UNSPEC_FUCMP))]
8407   "TARGET_VIS3"
8408   "fucmp<code>8\t%1, %2, %0")
8409
8410 (include "sync.md")