OSDN Git Service

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