OSDN Git Service

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