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