OSDN Git Service

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