OSDN Git Service

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