OSDN Git Service

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