OSDN Git Service

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