OSDN Git Service

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