OSDN Git Service

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