OSDN Git Service

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