OSDN Git Service

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