OSDN Git Service

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