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