OSDN Git Service

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