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