OSDN Git Service

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