OSDN Git Service

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