OSDN Git Service

88c474c98c77b0024da063b2ab602e02687be346
[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           gcc_assert (TARGET_ARCH64);
2087           emit_insn (gen_movdi_pic_label_ref (operands[0], operands[1]));
2088           DONE;
2089         }
2090
2091       if (symbolic_operand (operands[1], DImode))
2092         {
2093           operands[1] = legitimize_pic_address (operands[1],
2094                                                 DImode,
2095                                                 (reload_in_progress ?
2096                                                  operands[0] :
2097                                                  NULL_RTX));
2098           goto movdi_is_ok;
2099         }
2100     }
2101
2102   /* If we are trying to toss an integer constant into the
2103      FPU registers, force it into memory.  */
2104   if (GET_CODE (operands[0]) == REG
2105       && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
2106       && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
2107       && CONSTANT_P (operands[1]))
2108     operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2109                                                  operands[1]));
2110
2111   /* This makes sure we will not get rematched due to splittage.  */
2112   if (! CONSTANT_P (operands[1]) || input_operand (operands[1], DImode))
2113     ;
2114   else if (TARGET_ARCH64
2115            && GET_CODE (operands[1]) != HIGH
2116            && GET_CODE (operands[1]) != LO_SUM)
2117     {
2118       sparc_emit_set_const64 (operands[0], operands[1]);
2119       DONE;
2120     }
2121
2122  movdi_is_ok:
2123   ;
2124 })
2125
2126 ;; Be careful, fmovd does not exist when !v9.
2127 ;; We match MEM moves directly when we have correct even
2128 ;; numbered registers, but fall into splits otherwise.
2129 ;; The constraint ordering here is really important to
2130 ;; avoid insane problems in reload, especially for patterns
2131 ;; of the form:
2132 ;;
2133 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
2134 ;;                       (const_int -5016)))
2135 ;;      (reg:DI 2 %g2))
2136 ;;
2137
2138 (define_insn "*movdi_insn_sp32_v9"
2139   [(set (match_operand:DI 0 "nonimmediate_operand"
2140                                         "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?e,?e,?W")
2141         (match_operand:DI 1 "input_operand"
2142                                         " J,J,U,T,r,o,i,r, f, T, o, f, e, W, e"))]
2143   "! TARGET_ARCH64 && TARGET_V9
2144    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2145   "@
2146    stx\t%%g0, %0
2147    #
2148    std\t%1, %0
2149    ldd\t%1, %0
2150    #
2151    #
2152    #
2153    #
2154    std\t%1, %0
2155    ldd\t%1, %0
2156    #
2157    #
2158    fmovd\\t%1, %0
2159    ldd\\t%1, %0
2160    std\\t%1, %0"
2161   [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,fpload,fpstore")
2162    (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,*,*")
2163    (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])
2164
2165 (define_insn "*movdi_insn_sp32"
2166   [(set (match_operand:DI 0 "nonimmediate_operand"
2167                                 "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
2168         (match_operand:DI 1 "input_operand"
2169                                 " J,U,T,r,o,i,r, f, T, o, f, f"))]
2170   "! TARGET_ARCH64
2171    && (register_operand (operands[0], DImode)
2172        || register_operand (operands[1], DImode))"
2173   "@
2174    #
2175    std\t%1, %0
2176    ldd\t%1, %0
2177    #
2178    #
2179    #
2180    #
2181    std\t%1, %0
2182    ldd\t%1, %0
2183    #
2184    #
2185    #"
2186   [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
2187    (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
2188
2189 ;; The following are generated by sparc_emit_set_const64
2190 (define_insn "*movdi_sp64_dbl"
2191   [(set (match_operand:DI 0 "register_operand" "=r")
2192         (match_operand:DI 1 "const64_operand" ""))]
2193   "(TARGET_ARCH64
2194     && HOST_BITS_PER_WIDE_INT != 64)"
2195   "mov\t%1, %0")
2196
2197 ;; This is needed to show CSE exactly which bits are set
2198 ;; in a 64-bit register by sethi instructions.
2199 (define_insn "*movdi_const64_special"
2200   [(set (match_operand:DI 0 "register_operand" "=r")
2201         (match_operand:DI 1 "const64_high_operand" ""))]
2202   "TARGET_ARCH64"
2203   "sethi\t%%hi(%a1), %0")
2204
2205 (define_insn "*movdi_insn_sp64_novis"
2206   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?W")
2207         (match_operand:DI 1 "input_operand"   "rI,N,J,m,rJ,e,W,e"))]
2208   "TARGET_ARCH64 && ! TARGET_VIS
2209    && (register_operand (operands[0], DImode)
2210        || reg_or_0_operand (operands[1], DImode))"
2211   "@
2212    mov\t%1, %0
2213    sethi\t%%hi(%a1), %0
2214    clr\t%0
2215    ldx\t%1, %0
2216    stx\t%r1, %0
2217    fmovd\t%1, %0
2218    ldd\t%1, %0
2219    std\t%1, %0"
2220   [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore")
2221    (set_attr "fptype" "*,*,*,*,*,double,*,*")])
2222
2223 ;; We don't define V1SI because SI should work just fine.
2224 (define_mode_macro V64 [DF V2SI V4HI V8QI])
2225 (define_mode_macro V32 [SF V2HI V4QI])
2226
2227 (define_insn "*movdi_insn_sp64_vis"
2228   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?W,b")
2229         (match_operand:DI 1 "input_operand"   "rI,N,J,m,rJ,e,W,e,J"))]
2230   "TARGET_ARCH64 && TARGET_VIS &&
2231    (register_operand (operands[0], DImode)
2232     || reg_or_0_operand (operands[1], DImode))"
2233   "@
2234    mov\t%1, %0
2235    sethi\t%%hi(%a1), %0
2236    clr\t%0
2237    ldx\t%1, %0
2238    stx\t%r1, %0
2239    fmovd\t%1, %0
2240    ldd\t%1, %0
2241    std\t%1, %0
2242    fzero\t%0"
2243   [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore,fga")
2244    (set_attr "fptype" "*,*,*,*,*,double,*,*,double")])
2245
2246 (define_expand "movdi_pic_label_ref"
2247   [(set (match_dup 3) (high:DI
2248      (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2249                  (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2250    (set (match_dup 4) (lo_sum:DI (match_dup 3)
2251      (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2252    (set (match_operand:DI 0 "register_operand" "=r")
2253         (minus:DI (match_dup 5) (match_dup 4)))]
2254   "TARGET_ARCH64 && flag_pic"
2255 {
2256   current_function_uses_pic_offset_table = 1;
2257   operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
2258   if (no_new_pseudos)
2259     {
2260       operands[3] = operands[0];
2261       operands[4] = operands[0];
2262     }
2263   else
2264     {
2265       operands[3] = gen_reg_rtx (DImode);
2266       operands[4] = gen_reg_rtx (DImode);
2267     }
2268   operands[5] = pic_offset_table_rtx;
2269 })
2270
2271 (define_insn "*movdi_high_pic_label_ref"
2272   [(set (match_operand:DI 0 "register_operand" "=r")
2273         (high:DI
2274           (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2275                       (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2276   "TARGET_ARCH64 && flag_pic"
2277   "sethi\t%%hi(%a2-(%a1-.)), %0")
2278
2279 (define_insn "*movdi_lo_sum_pic_label_ref"
2280   [(set (match_operand:DI 0 "register_operand" "=r")
2281       (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2282         (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
2283                     (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2284   "TARGET_ARCH64 && flag_pic"
2285   "or\t%1, %%lo(%a3-(%a2-.)), %0")
2286
2287 ;; SPARC-v9 code model support insns.  See sparc_emit_set_symbolic_const64
2288 ;; in sparc.c to see what is going on here... PIC stuff comes first.
2289
2290 (define_insn "movdi_lo_sum_pic"
2291   [(set (match_operand:DI 0 "register_operand" "=r")
2292         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2293                    (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
2294   "TARGET_ARCH64 && flag_pic"
2295   "or\t%1, %%lo(%a2), %0")
2296
2297 (define_insn "movdi_high_pic"
2298   [(set (match_operand:DI 0 "register_operand" "=r")
2299         (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
2300   "TARGET_ARCH64 && flag_pic && check_pic (1)"
2301   "sethi\t%%hi(%a1), %0")
2302
2303 (define_insn "*sethi_di_medlow_embmedany_pic"
2304   [(set (match_operand:DI 0 "register_operand" "=r")
2305         (high:DI (match_operand:DI 1 "sp64_medium_pic_operand" "")))]
2306   "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
2307   "sethi\t%%hi(%a1), %0")
2308
2309 (define_insn "*sethi_di_medlow"
2310   [(set (match_operand:DI 0 "register_operand" "=r")
2311         (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
2312   "TARGET_CM_MEDLOW && check_pic (1)"
2313   "sethi\t%%hi(%a1), %0")
2314
2315 (define_insn "*losum_di_medlow"
2316   [(set (match_operand:DI 0 "register_operand" "=r")
2317         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2318                    (match_operand:DI 2 "symbolic_operand" "")))]
2319   "TARGET_CM_MEDLOW"
2320   "or\t%1, %%lo(%a2), %0")
2321
2322 (define_insn "seth44"
2323   [(set (match_operand:DI 0 "register_operand" "=r")
2324         (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
2325   "TARGET_CM_MEDMID"
2326   "sethi\t%%h44(%a1), %0")
2327
2328 (define_insn "setm44"
2329   [(set (match_operand:DI 0 "register_operand" "=r")
2330         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2331                    (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
2332   "TARGET_CM_MEDMID"
2333   "or\t%1, %%m44(%a2), %0")
2334
2335 (define_insn "setl44"
2336   [(set (match_operand:DI 0 "register_operand" "=r")
2337         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2338                    (match_operand:DI 2 "symbolic_operand" "")))]
2339   "TARGET_CM_MEDMID"
2340   "or\t%1, %%l44(%a2), %0")
2341
2342 (define_insn "sethh"
2343   [(set (match_operand:DI 0 "register_operand" "=r")
2344         (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
2345   "TARGET_CM_MEDANY"
2346   "sethi\t%%hh(%a1), %0")
2347
2348 (define_insn "setlm"
2349   [(set (match_operand:DI 0 "register_operand" "=r")
2350         (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
2351   "TARGET_CM_MEDANY"
2352   "sethi\t%%lm(%a1), %0")
2353
2354 (define_insn "sethm"
2355   [(set (match_operand:DI 0 "register_operand" "=r")
2356         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2357                    (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
2358   "TARGET_CM_MEDANY"
2359   "or\t%1, %%hm(%a2), %0")
2360
2361 (define_insn "setlo"
2362   [(set (match_operand:DI 0 "register_operand" "=r")
2363         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2364                    (match_operand:DI 2 "symbolic_operand" "")))]
2365   "TARGET_CM_MEDANY"
2366   "or\t%1, %%lo(%a2), %0")
2367
2368 (define_insn "embmedany_sethi"
2369   [(set (match_operand:DI 0 "register_operand" "=r")
2370         (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
2371   "TARGET_CM_EMBMEDANY && check_pic (1)"
2372   "sethi\t%%hi(%a1), %0")
2373
2374 (define_insn "embmedany_losum"
2375   [(set (match_operand:DI 0 "register_operand" "=r")
2376         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2377                    (match_operand:DI 2 "data_segment_operand" "")))]
2378   "TARGET_CM_EMBMEDANY"
2379   "add\t%1, %%lo(%a2), %0")
2380
2381 (define_insn "embmedany_brsum"
2382   [(set (match_operand:DI 0 "register_operand" "=r")
2383         (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
2384   "TARGET_CM_EMBMEDANY"
2385   "add\t%1, %_, %0")
2386
2387 (define_insn "embmedany_textuhi"
2388   [(set (match_operand:DI 0 "register_operand" "=r")
2389         (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
2390   "TARGET_CM_EMBMEDANY && check_pic (1)"
2391   "sethi\t%%uhi(%a1), %0")
2392
2393 (define_insn "embmedany_texthi"
2394   [(set (match_operand:DI 0 "register_operand" "=r")
2395         (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
2396   "TARGET_CM_EMBMEDANY && check_pic (1)"
2397   "sethi\t%%hi(%a1), %0")
2398
2399 (define_insn "embmedany_textulo"
2400   [(set (match_operand:DI 0 "register_operand" "=r")
2401         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2402                    (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
2403   "TARGET_CM_EMBMEDANY"
2404   "or\t%1, %%ulo(%a2), %0")
2405
2406 (define_insn "embmedany_textlo"
2407   [(set (match_operand:DI 0 "register_operand" "=r")
2408         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2409                    (match_operand:DI 2 "text_segment_operand" "")))]
2410   "TARGET_CM_EMBMEDANY"
2411   "or\t%1, %%lo(%a2), %0")
2412
2413 ;; Now some patterns to help reload out a bit.
2414 (define_expand "reload_indi"
2415   [(parallel [(match_operand:DI 0 "register_operand" "=r")
2416               (match_operand:DI 1 "immediate_operand" "")
2417               (match_operand:TI 2 "register_operand" "=&r")])]
2418   "(TARGET_CM_MEDANY
2419     || TARGET_CM_EMBMEDANY)
2420    && ! flag_pic"
2421 {
2422   sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2423   DONE;
2424 })
2425
2426 (define_expand "reload_outdi"
2427   [(parallel [(match_operand:DI 0 "register_operand" "=r")
2428               (match_operand:DI 1 "immediate_operand" "")
2429               (match_operand:TI 2 "register_operand" "=&r")])]
2430   "(TARGET_CM_MEDANY
2431     || TARGET_CM_EMBMEDANY)
2432    && ! flag_pic"
2433 {
2434   sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2435   DONE;
2436 })
2437
2438 ;; Split up putting CONSTs and REGs into DI regs when !arch64
2439 (define_split
2440   [(set (match_operand:DI 0 "register_operand" "")
2441         (match_operand:DI 1 "const_int_operand" ""))]
2442   "! TARGET_ARCH64 && reload_completed"
2443   [(clobber (const_int 0))]
2444 {
2445 #if HOST_BITS_PER_WIDE_INT == 32
2446   emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2447                         (INTVAL (operands[1]) < 0) ?
2448                         constm1_rtx :
2449                         const0_rtx));
2450   emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2451                         operands[1]));
2452 #else
2453   unsigned int low, high;
2454
2455   low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
2456   high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
2457   emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
2458
2459   /* Slick... but this trick loses if this subreg constant part
2460      can be done in one insn.  */
2461   if (low == high && (low & 0x3ff) != 0 && low + 0x1000 >= 0x2000)
2462     emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2463                           gen_highpart (SImode, operands[0])));
2464   else
2465     emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
2466 #endif
2467   DONE;
2468 })
2469
2470 (define_split
2471   [(set (match_operand:DI 0 "register_operand" "")
2472         (match_operand:DI 1 "const_double_operand" ""))]
2473   "reload_completed
2474    && (! TARGET_V9
2475        || (! TARGET_ARCH64
2476            && ((GET_CODE (operands[0]) == REG
2477                 && REGNO (operands[0]) < 32)
2478                || (GET_CODE (operands[0]) == SUBREG
2479                    && GET_CODE (SUBREG_REG (operands[0])) == REG
2480                    && REGNO (SUBREG_REG (operands[0])) < 32))))"
2481   [(clobber (const_int 0))]
2482 {
2483   emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2484                         GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
2485
2486   /* Slick... but this trick loses if this subreg constant part
2487      can be done in one insn.  */
2488   if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
2489       && !(SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
2490            || SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1]))))
2491     {
2492       emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2493                             gen_highpart (SImode, operands[0])));
2494     }
2495   else
2496     {
2497       emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2498                             GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
2499     }
2500   DONE;
2501 })
2502
2503 (define_split
2504   [(set (match_operand:DI 0 "register_operand" "")
2505         (match_operand:DI 1 "register_operand" ""))]
2506   "reload_completed
2507    && (! TARGET_V9
2508        || (! TARGET_ARCH64
2509            && ((GET_CODE (operands[0]) == REG
2510                 && REGNO (operands[0]) < 32)
2511                || (GET_CODE (operands[0]) == SUBREG
2512                    && GET_CODE (SUBREG_REG (operands[0])) == REG
2513                    && REGNO (SUBREG_REG (operands[0])) < 32))))"
2514   [(clobber (const_int 0))]
2515 {
2516   rtx set_dest = operands[0];
2517   rtx set_src = operands[1];
2518   rtx dest1, dest2;
2519   rtx src1, src2;
2520
2521   dest1 = gen_highpart (SImode, set_dest);
2522   dest2 = gen_lowpart (SImode, set_dest);
2523   src1 = gen_highpart (SImode, set_src);
2524   src2 = gen_lowpart (SImode, set_src);
2525
2526   /* Now emit using the real source and destination we found, swapping
2527      the order if we detect overlap.  */
2528   if (reg_overlap_mentioned_p (dest1, src2))
2529     {
2530       emit_insn (gen_movsi (dest2, src2));
2531       emit_insn (gen_movsi (dest1, src1));
2532     }
2533   else
2534     {
2535       emit_insn (gen_movsi (dest1, src1));
2536       emit_insn (gen_movsi (dest2, src2));
2537     }
2538   DONE;
2539 })
2540
2541 ;; Now handle the cases of memory moves from/to non-even
2542 ;; DI mode register pairs.
2543 (define_split
2544   [(set (match_operand:DI 0 "register_operand" "")
2545         (match_operand:DI 1 "memory_operand" ""))]
2546   "(! TARGET_ARCH64
2547     && reload_completed
2548     && sparc_splitdi_legitimate (operands[0], operands[1]))"
2549   [(clobber (const_int 0))]
2550 {
2551   rtx word0 = adjust_address (operands[1], SImode, 0);
2552   rtx word1 = adjust_address (operands[1], SImode, 4);
2553   rtx high_part = gen_highpart (SImode, operands[0]);
2554   rtx low_part = gen_lowpart (SImode, operands[0]);
2555
2556   if (reg_overlap_mentioned_p (high_part, word1))
2557     {
2558       emit_insn (gen_movsi (low_part, word1));
2559       emit_insn (gen_movsi (high_part, word0));
2560     }
2561   else
2562     {
2563       emit_insn (gen_movsi (high_part, word0));
2564       emit_insn (gen_movsi (low_part, word1));
2565     }
2566   DONE;
2567 })
2568
2569 (define_split
2570   [(set (match_operand:DI 0 "memory_operand" "")
2571         (match_operand:DI 1 "register_operand" ""))]
2572   "(! TARGET_ARCH64
2573     && reload_completed
2574     && sparc_splitdi_legitimate (operands[1], operands[0]))"
2575   [(clobber (const_int 0))]
2576 {
2577   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
2578                         gen_highpart (SImode, operands[1])));
2579   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
2580                         gen_lowpart (SImode, operands[1])));
2581   DONE;
2582 })
2583
2584 (define_split
2585   [(set (match_operand:DI 0 "memory_operand" "")
2586         (const_int 0))]
2587   "reload_completed
2588    && (! TARGET_V9
2589        || (! TARGET_ARCH64
2590            && ! mem_min_alignment (operands[0], 8)))
2591    && offsettable_memref_p (operands[0])"
2592   [(clobber (const_int 0))]
2593 {
2594   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
2595   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
2596   DONE;
2597 })
2598 \f
2599 ;; Floating point move insns
2600
2601 (define_insn "*movsf_insn_novis"
2602   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,*r,*r,*r,*r,*r,f,m,m")
2603         (match_operand:SF 1 "input_operand"         "f,G,Q,*rR,S,m,m,f,*rG"))]
2604   "(TARGET_FPU && ! TARGET_VIS)
2605    && (register_operand (operands[0], SFmode)
2606        || register_operand (operands[1], SFmode)
2607        || fp_zero_operand (operands[1], SFmode))"
2608 {
2609   if (GET_CODE (operands[1]) == CONST_DOUBLE
2610       && (which_alternative == 2
2611           || which_alternative == 3
2612           || which_alternative == 4))
2613     {
2614       REAL_VALUE_TYPE r;
2615       long i;
2616
2617       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2618       REAL_VALUE_TO_TARGET_SINGLE (r, i);
2619       operands[1] = GEN_INT (i);
2620     }
2621
2622   switch (which_alternative)
2623     {
2624     case 0:
2625       return "fmovs\t%1, %0";
2626     case 1:
2627       return "clr\t%0";
2628     case 2:
2629       return "sethi\t%%hi(%a1), %0";
2630     case 3:
2631       return "mov\t%1, %0";
2632     case 4:
2633       return "#";
2634     case 5:
2635     case 6:
2636       return "ld\t%1, %0";
2637     case 7:
2638     case 8:
2639       return "st\t%r1, %0";
2640     default:
2641       gcc_unreachable ();
2642     }
2643 }
2644   [(set_attr "type" "fpmove,*,*,*,*,load,fpload,fpstore,store")])
2645
2646 (define_insn "*movsf_insn_vis"
2647   [(set (match_operand:V32 0 "nonimmediate_operand" "=f,f,*r,*r,*r,*r,*r,f,m,m")
2648         (match_operand:V32 1 "input_operand"         "f,GY,GY,Q,*rR,S,m,m,f,*rGY"))]
2649   "(TARGET_FPU && TARGET_VIS)
2650    && (register_operand (operands[0], <V32:MODE>mode)
2651        || register_operand (operands[1], <V32:MODE>mode)
2652        || fp_zero_operand (operands[1], <V32:MODE>mode))"
2653 {
2654   if (GET_CODE (operands[1]) == CONST_DOUBLE
2655       && (which_alternative == 3
2656           || which_alternative == 4
2657           || which_alternative == 5))
2658     {
2659       REAL_VALUE_TYPE r;
2660       long i;
2661
2662       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2663       REAL_VALUE_TO_TARGET_SINGLE (r, i);
2664       operands[1] = GEN_INT (i);
2665     }
2666
2667   switch (which_alternative)
2668     {
2669     case 0:
2670       return "fmovs\t%1, %0";
2671     case 1:
2672       return "fzeros\t%0";
2673     case 2:
2674       return "clr\t%0";
2675     case 3:
2676       return "sethi\t%%hi(%a1), %0";
2677     case 4:
2678       return "mov\t%1, %0";
2679     case 5:
2680       return "#";
2681     case 6:
2682     case 7:
2683       return "ld\t%1, %0";
2684     case 8:
2685     case 9:
2686       return "st\t%r1, %0";
2687     default:
2688       gcc_unreachable ();
2689     }
2690 }
2691   [(set_attr "type" "fpmove,fga,*,*,*,*,load,fpload,fpstore,store")])
2692
2693 ;; Exactly the same as above, except that all `f' cases are deleted.
2694 ;; This is necessary to prevent reload from ever trying to use a `f' reg
2695 ;; when -mno-fpu.
2696
2697 (define_insn "*movsf_no_f_insn"
2698   [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,r,m")
2699         (match_operand:SF 1 "input_operand"    "G,Q,rR,S,m,rG"))]
2700   "! TARGET_FPU
2701    && (register_operand (operands[0], SFmode)
2702        || register_operand (operands[1], SFmode)
2703        || fp_zero_operand (operands[1], SFmode))"
2704 {
2705   if (GET_CODE (operands[1]) == CONST_DOUBLE
2706       && (which_alternative == 1
2707           || which_alternative == 2
2708           || which_alternative == 3))
2709     {
2710       REAL_VALUE_TYPE r;
2711       long i;
2712
2713       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2714       REAL_VALUE_TO_TARGET_SINGLE (r, i);
2715       operands[1] = GEN_INT (i);
2716     }
2717
2718   switch (which_alternative)
2719     {
2720     case 0:
2721       return "clr\t%0";
2722     case 1:
2723       return "sethi\t%%hi(%a1), %0";
2724     case 2:
2725       return "mov\t%1, %0";
2726     case 3:
2727       return "#";
2728     case 4:
2729       return "ld\t%1, %0";
2730     case 5:
2731       return "st\t%r1, %0";
2732     default:
2733       gcc_unreachable ();
2734     }
2735 }
2736   [(set_attr "type" "*,*,*,*,load,store")])
2737
2738 ;; The following 3 patterns build SFmode constants in integer registers.
2739
2740 (define_insn "*movsf_lo_sum"
2741   [(set (match_operand:SF 0 "register_operand" "=r")
2742         (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
2743                    (match_operand:SF 2 "const_double_operand" "S")))]
2744   "fp_high_losum_p (operands[2])"
2745 {
2746   REAL_VALUE_TYPE r;
2747   long i;
2748
2749   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
2750   REAL_VALUE_TO_TARGET_SINGLE (r, i);
2751   operands[2] = GEN_INT (i);
2752   return "or\t%1, %%lo(%a2), %0";
2753 })
2754
2755 (define_insn "*movsf_high"
2756   [(set (match_operand:SF 0 "register_operand" "=r")
2757         (high:SF (match_operand:SF 1 "const_double_operand" "S")))]
2758   "fp_high_losum_p (operands[1])"
2759 {
2760   REAL_VALUE_TYPE r;
2761   long i;
2762
2763   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2764   REAL_VALUE_TO_TARGET_SINGLE (r, i);
2765   operands[1] = GEN_INT (i);
2766   return "sethi\t%%hi(%1), %0";
2767 })
2768
2769 (define_split
2770   [(set (match_operand:SF 0 "register_operand" "")
2771         (match_operand:SF 1 "const_double_operand" ""))]
2772   "fp_high_losum_p (operands[1])
2773    && (GET_CODE (operands[0]) == REG
2774        && REGNO (operands[0]) < 32)"
2775   [(set (match_dup 0) (high:SF (match_dup 1)))
2776    (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
2777
2778 ;; Yes, you guessed it right, the former movsf expander.
2779 (define_expand "mov<V32:mode>"
2780   [(set (match_operand:V32 0 "general_operand" "")
2781         (match_operand:V32 1 "general_operand" ""))]
2782   "<V32:MODE>mode == SFmode || TARGET_VIS"
2783 {
2784   /* Force constants into memory.  */
2785   if (GET_CODE (operands[0]) == REG && CONSTANT_P (operands[1]))
2786     {
2787       /* emit_group_store will send such bogosity to us when it is
2788          not storing directly into memory.  So fix this up to avoid
2789          crashes in output_constant_pool.  */
2790       if (operands [1] == const0_rtx)
2791         operands[1] = CONST0_RTX (<V32:MODE>mode);
2792
2793       if ((TARGET_VIS || REGNO (operands[0]) < 32)
2794           && fp_zero_operand (operands[1], <V32:MODE>mode))
2795         goto movsf_is_ok;
2796
2797       /* We are able to build any SF constant in integer registers
2798          with at most 2 instructions.  */
2799       if (REGNO (operands[0]) < 32
2800           && <V32:MODE>mode == SFmode)
2801         goto movsf_is_ok;
2802
2803       operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2804                                                    operands[1]));
2805     }
2806
2807   /* Handle sets of MEM first.  */
2808   if (GET_CODE (operands[0]) == MEM)
2809     {
2810       if (register_operand (operands[1], <V32:MODE>mode)
2811           || fp_zero_operand (operands[1], <V32:MODE>mode))
2812         goto movsf_is_ok;
2813
2814       if (! reload_in_progress)
2815         {
2816           operands[0] = validize_mem (operands[0]);
2817           operands[1] = force_reg (<V32:MODE>mode, operands[1]);
2818         }
2819     }
2820
2821   /* Fixup PIC cases.  */
2822   if (flag_pic)
2823     {
2824       if (CONSTANT_P (operands[1])
2825           && pic_address_needs_scratch (operands[1]))
2826         operands[1] = legitimize_pic_address (operands[1], <V32:MODE>mode, 0);
2827
2828       if (symbolic_operand (operands[1], <V32:MODE>mode))
2829         {
2830           operands[1] = legitimize_pic_address (operands[1],
2831                                                 <V32:MODE>mode,
2832                                                 (reload_in_progress ?
2833                                                  operands[0] :
2834                                                  NULL_RTX));
2835         }
2836     }
2837
2838  movsf_is_ok:
2839   ;
2840 })
2841
2842 ;; Yes, you again guessed it right, the former movdf expander.
2843 (define_expand "mov<V64:mode>"
2844   [(set (match_operand:V64 0 "general_operand" "")
2845         (match_operand:V64 1 "general_operand" ""))]
2846   "<V64:MODE>mode == DFmode || TARGET_VIS"
2847 {
2848   /* Force constants into memory.  */
2849   if (GET_CODE (operands[0]) == REG && CONSTANT_P (operands[1]))
2850     {
2851       /* emit_group_store will send such bogosity to us when it is
2852          not storing directly into memory.  So fix this up to avoid
2853          crashes in output_constant_pool.  */
2854       if (operands [1] == const0_rtx)
2855         operands[1] = CONST0_RTX (<V64:MODE>mode);
2856
2857       if ((TARGET_VIS || REGNO (operands[0]) < 32)
2858           && fp_zero_operand (operands[1], <V64:MODE>mode))
2859         goto movdf_is_ok;
2860
2861       /* We are able to build any DF constant in integer registers.  */
2862       if (REGNO (operands[0]) < 32
2863           && <V64:MODE>mode == DFmode
2864           && (reload_completed || reload_in_progress))
2865         goto movdf_is_ok;
2866
2867       operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2868                                                    operands[1]));
2869     }
2870
2871   /* Handle MEM cases first.  */
2872   if (GET_CODE (operands[0]) == MEM)
2873     {
2874       if (register_operand (operands[1], <V64:MODE>mode)
2875           || fp_zero_operand (operands[1], <V64:MODE>mode))
2876         goto movdf_is_ok;
2877
2878       if (! reload_in_progress)
2879         {
2880           operands[0] = validize_mem (operands[0]);
2881           operands[1] = force_reg (<V64:MODE>mode, operands[1]);
2882         }
2883     }
2884
2885   /* Fixup PIC cases.  */
2886   if (flag_pic)
2887     {
2888       if (CONSTANT_P (operands[1])
2889           && pic_address_needs_scratch (operands[1]))
2890         operands[1] = legitimize_pic_address (operands[1], <V64:MODE>mode, 0);
2891
2892       if (symbolic_operand (operands[1], <V64:MODE>mode))
2893         {
2894           operands[1] = legitimize_pic_address (operands[1],
2895                                                 <V64:MODE>mode,
2896                                                 (reload_in_progress ?
2897                                                  operands[0] :
2898                                                  NULL_RTX));
2899         }
2900     }
2901
2902  movdf_is_ok:
2903   ;
2904 })
2905
2906 ;; Be careful, fmovd does not exist when !v9.
2907 (define_insn "*movdf_insn_sp32"
2908   [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o")
2909         (match_operand:DF 1 "input_operand"    "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
2910   "TARGET_FPU
2911    && ! TARGET_V9
2912    && (register_operand (operands[0], DFmode)
2913        || register_operand (operands[1], DFmode)
2914        || fp_zero_operand (operands[1], DFmode))"
2915   "@
2916   ldd\t%1, %0
2917   std\t%1, %0
2918   ldd\t%1, %0
2919   std\t%1, %0
2920   #
2921   #
2922   #
2923   #
2924   #
2925   #"
2926  [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
2927   (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
2928
2929 (define_insn "*movdf_no_e_insn_sp32"
2930   [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
2931         (match_operand:DF 1 "input_operand"    "T,U,G,ro,r"))]
2932   "! TARGET_FPU
2933    && ! TARGET_V9
2934    && ! TARGET_ARCH64
2935    && (register_operand (operands[0], DFmode)
2936        || register_operand (operands[1], DFmode)
2937        || fp_zero_operand (operands[1], DFmode))"
2938   "@
2939   ldd\t%1, %0
2940   std\t%1, %0
2941   #
2942   #
2943   #"
2944   [(set_attr "type" "load,store,*,*,*")
2945    (set_attr "length" "*,*,2,2,2")])
2946
2947 (define_insn "*movdf_no_e_insn_v9_sp32"
2948   [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
2949         (match_operand:DF 1 "input_operand"    "T,U,G,ro,rG"))]
2950   "! TARGET_FPU
2951    && TARGET_V9
2952    && ! TARGET_ARCH64
2953    && (register_operand (operands[0], DFmode)
2954        || register_operand (operands[1], DFmode)
2955        || fp_zero_operand (operands[1], DFmode))"
2956   "@
2957   ldd\t%1, %0
2958   std\t%1, %0
2959   stx\t%r1, %0
2960   #
2961   #"
2962   [(set_attr "type" "load,store,store,*,*")
2963    (set_attr "length" "*,*,*,2,2")])
2964
2965 ;; We have available v9 double floats but not 64-bit
2966 ;; integer registers and no VIS.
2967 (define_insn "*movdf_insn_v9only_novis"
2968   [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,T,W,U,T,f,*r,o")
2969         (match_operand:DF 1 "input_operand"    "e,W#F,G,e,T,U,o#F,*roF,*rGf"))]
2970   "TARGET_FPU
2971    && TARGET_V9
2972    && ! TARGET_VIS
2973    && ! TARGET_ARCH64
2974    && (register_operand (operands[0], DFmode)
2975        || register_operand (operands[1], DFmode)
2976        || fp_zero_operand (operands[1], DFmode))"
2977   "@
2978   fmovd\t%1, %0
2979   ldd\t%1, %0
2980   stx\t%r1, %0
2981   std\t%1, %0
2982   ldd\t%1, %0
2983   std\t%1, %0
2984   #
2985   #
2986   #"
2987   [(set_attr "type" "fpmove,load,store,store,load,store,*,*,*")
2988    (set_attr "length" "*,*,*,*,*,*,2,2,2")
2989    (set_attr "fptype" "double,*,*,*,*,*,*,*,*")])
2990
2991 ;; We have available v9 double floats but not 64-bit
2992 ;; integer registers but we have VIS.
2993 (define_insn "*movdf_insn_v9only_vis"
2994   [(set (match_operand:V64 0 "nonimmediate_operand" "=e,e,e,T,W,U,T,f,*r,o")
2995         (match_operand:V64 1 "input_operand" "GY,e,W#F,GY,e,T,U,o#F,*roGYF,*rGYf"))]
2996   "TARGET_FPU
2997    && TARGET_VIS
2998    && ! TARGET_ARCH64
2999    && (register_operand (operands[0], <V64:MODE>mode)
3000        || register_operand (operands[1], <V64:MODE>mode)
3001        || fp_zero_operand (operands[1], <V64:MODE>mode))"
3002   "@
3003   fzero\t%0
3004   fmovd\t%1, %0
3005   ldd\t%1, %0
3006   stx\t%r1, %0
3007   std\t%1, %0
3008   ldd\t%1, %0
3009   std\t%1, %0
3010   #
3011   #
3012   #"
3013   [(set_attr "type" "fga,fpmove,load,store,store,load,store,*,*,*")
3014    (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
3015    (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
3016
3017 ;; We have available both v9 double floats and 64-bit
3018 ;; integer registers. No VIS though.
3019 (define_insn "*movdf_insn_sp64_novis"
3020   [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,W,*r,*r,m,*r")
3021         (match_operand:DF 1 "input_operand"    "e,W#F,e,*rG,m,*rG,F"))]
3022   "TARGET_FPU
3023    && ! TARGET_VIS
3024    && TARGET_ARCH64
3025    && (register_operand (operands[0], DFmode)
3026        || register_operand (operands[1], DFmode)
3027        || fp_zero_operand (operands[1], DFmode))"
3028   "@
3029   fmovd\t%1, %0
3030   ldd\t%1, %0
3031   std\t%1, %0
3032   mov\t%r1, %0
3033   ldx\t%1, %0
3034   stx\t%r1, %0
3035   #"
3036   [(set_attr "type" "fpmove,load,store,*,load,store,*")
3037    (set_attr "length" "*,*,*,*,*,*,2")
3038    (set_attr "fptype" "double,*,*,*,*,*,*")])
3039
3040 ;; We have available both v9 double floats and 64-bit
3041 ;; integer registers. And we have VIS.
3042 (define_insn "*movdf_insn_sp64_vis"
3043   [(set (match_operand:V64 0 "nonimmediate_operand" "=e,e,e,W,*r,*r,m,*r")
3044         (match_operand:V64 1 "input_operand"    "GY,e,W#F,e,*rGY,m,*rGY,F"))]
3045   "TARGET_FPU
3046    && TARGET_VIS
3047    && TARGET_ARCH64
3048    && (register_operand (operands[0], <V64:MODE>mode)
3049        || register_operand (operands[1], <V64:MODE>mode)
3050        || fp_zero_operand (operands[1], <V64:MODE>mode))"
3051   "@
3052   fzero\t%0
3053   fmovd\t%1, %0
3054   ldd\t%1, %0
3055   std\t%1, %0
3056   mov\t%r1, %0
3057   ldx\t%1, %0
3058   stx\t%r1, %0
3059   #"
3060   [(set_attr "type" "fga,fpmove,load,store,*,load,store,*")
3061    (set_attr "length" "*,*,*,*,*,*,*,2")
3062    (set_attr "fptype" "double,double,*,*,*,*,*,*")])
3063
3064 (define_insn "*movdf_no_e_insn_sp64"
3065   [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
3066         (match_operand:DF 1 "input_operand"    "r,m,rG"))]
3067   "! TARGET_FPU
3068    && TARGET_ARCH64
3069    && (register_operand (operands[0], DFmode)
3070        || register_operand (operands[1], DFmode)
3071        || fp_zero_operand (operands[1], DFmode))"
3072   "@
3073   mov\t%1, %0
3074   ldx\t%1, %0
3075   stx\t%r1, %0"
3076   [(set_attr "type" "*,load,store")])
3077
3078 ;; This pattern build DFmode constants in integer registers.
3079 (define_split
3080   [(set (match_operand:DF 0 "register_operand" "")
3081         (match_operand:DF 1 "const_double_operand" ""))]
3082   "TARGET_FPU
3083    && (GET_CODE (operands[0]) == REG
3084        && REGNO (operands[0]) < 32)
3085    && ! fp_zero_operand(operands[1], DFmode)
3086    && reload_completed"
3087   [(clobber (const_int 0))]
3088 {
3089   REAL_VALUE_TYPE r;
3090   long l[2];
3091
3092   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3093   REAL_VALUE_TO_TARGET_DOUBLE (r, l);
3094   operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
3095
3096   if (TARGET_ARCH64)
3097     {
3098 #if HOST_BITS_PER_WIDE_INT == 64
3099       HOST_WIDE_INT val;
3100
3101       val = ((HOST_WIDE_INT)(unsigned long)l[1] |
3102              ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
3103       emit_insn (gen_movdi (operands[0], GEN_INT (val)));
3104 #else
3105       emit_insn (gen_movdi (operands[0],
3106                             immed_double_const (l[1], l[0], DImode)));
3107 #endif
3108     }
3109   else
3110     {
3111       emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
3112                             GEN_INT (l[0])));
3113
3114       /* Slick... but this trick loses if this subreg constant part
3115          can be done in one insn.  */
3116       if (l[1] == l[0]
3117           && !(SPARC_SETHI32_P (l[0])
3118                || SPARC_SIMM13_P (l[0])))
3119         {
3120           emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3121                                 gen_highpart (SImode, operands[0])));
3122         }
3123       else
3124         {
3125           emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3126                                 GEN_INT (l[1])));
3127         }
3128     }
3129   DONE;
3130 })
3131
3132 ;; Ok, now the splits to handle all the multi insn and
3133 ;; mis-aligned memory address cases.
3134 ;; In these splits please take note that we must be
3135 ;; careful when V9 but not ARCH64 because the integer
3136 ;; register DFmode cases must be handled.
3137 (define_split
3138   [(set (match_operand:V64 0 "register_operand" "")
3139         (match_operand:V64 1 "register_operand" ""))]
3140   "(! TARGET_V9
3141     || (! TARGET_ARCH64
3142         && ((GET_CODE (operands[0]) == REG
3143              && REGNO (operands[0]) < 32)
3144             || (GET_CODE (operands[0]) == SUBREG
3145                 && GET_CODE (SUBREG_REG (operands[0])) == REG
3146                 && REGNO (SUBREG_REG (operands[0])) < 32))))
3147    && reload_completed"
3148   [(clobber (const_int 0))]
3149 {
3150   rtx set_dest = operands[0];
3151   rtx set_src = operands[1];
3152   rtx dest1, dest2;
3153   rtx src1, src2;
3154   enum machine_mode half_mode;
3155
3156   /* We can be expanded for DFmode or integral vector modes.  */
3157   if (<V64:MODE>mode == DFmode)
3158     half_mode = SFmode;
3159   else
3160     half_mode = SImode;
3161   
3162   dest1 = gen_highpart (half_mode, set_dest);
3163   dest2 = gen_lowpart (half_mode, set_dest);
3164   src1 = gen_highpart (half_mode, set_src);
3165   src2 = gen_lowpart (half_mode, set_src);
3166
3167   /* Now emit using the real source and destination we found, swapping
3168      the order if we detect overlap.  */
3169   if (reg_overlap_mentioned_p (dest1, src2))
3170     {
3171       emit_move_insn_1 (dest2, src2);
3172       emit_move_insn_1 (dest1, src1);
3173     }
3174   else
3175     {
3176       emit_move_insn_1 (dest1, src1);
3177       emit_move_insn_1 (dest2, src2);
3178     }
3179   DONE;
3180 })
3181
3182 (define_split
3183   [(set (match_operand:V64 0 "register_operand" "")
3184         (match_operand:V64 1 "memory_operand" ""))]
3185   "reload_completed
3186    && ! TARGET_ARCH64
3187    && (((REGNO (operands[0]) % 2) != 0)
3188        || ! mem_min_alignment (operands[1], 8))
3189    && offsettable_memref_p (operands[1])"
3190   [(clobber (const_int 0))]
3191 {
3192   enum machine_mode half_mode;
3193   rtx word0, word1;
3194
3195   /* We can be expanded for DFmode or integral vector modes.  */
3196   if (<V64:MODE>mode == DFmode)
3197     half_mode = SFmode;
3198   else
3199     half_mode = SImode;
3200
3201   word0 = adjust_address (operands[1], half_mode, 0);
3202   word1 = adjust_address (operands[1], half_mode, 4);
3203
3204   if (reg_overlap_mentioned_p (gen_highpart (half_mode, operands[0]), word1))
3205     {
3206       emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
3207       emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
3208     }
3209   else
3210     {
3211       emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
3212       emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
3213     }
3214   DONE;
3215 })
3216
3217 (define_split
3218   [(set (match_operand:V64 0 "memory_operand" "")
3219         (match_operand:V64 1 "register_operand" ""))]
3220   "reload_completed
3221    && ! TARGET_ARCH64
3222    && (((REGNO (operands[1]) % 2) != 0)
3223        || ! mem_min_alignment (operands[0], 8))
3224    && offsettable_memref_p (operands[0])"
3225   [(clobber (const_int 0))]
3226 {
3227   enum machine_mode half_mode;
3228   rtx word0, word1;
3229
3230   /* We can be expanded for DFmode or integral vector modes.  */
3231   if (<V64:MODE>mode == DFmode)
3232     half_mode = SFmode;
3233   else
3234     half_mode = SImode;
3235
3236   word0 = adjust_address (operands[0], half_mode, 0);
3237   word1 = adjust_address (operands[0], half_mode, 4);
3238
3239   emit_move_insn_1 (word0, gen_highpart (half_mode, operands[1]));
3240   emit_move_insn_1 (word1, gen_lowpart (half_mode, operands[1]));
3241   DONE;
3242 })
3243
3244 (define_split
3245   [(set (match_operand:V64 0 "memory_operand" "")
3246         (match_operand:V64 1 "fp_zero_operand" ""))]
3247   "reload_completed
3248    && (! TARGET_V9
3249        || (! TARGET_ARCH64
3250            && ! mem_min_alignment (operands[0], 8)))
3251    && offsettable_memref_p (operands[0])"
3252   [(clobber (const_int 0))]
3253 {
3254   enum machine_mode half_mode;
3255   rtx dest1, dest2;
3256
3257   /* We can be expanded for DFmode or integral vector modes.  */
3258   if (<V64:MODE>mode == DFmode)
3259     half_mode = SFmode;
3260   else
3261     half_mode = SImode;
3262
3263   dest1 = adjust_address (operands[0], half_mode, 0);
3264   dest2 = adjust_address (operands[0], half_mode, 4);
3265
3266   emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
3267   emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
3268   DONE;
3269 })
3270
3271 (define_split
3272   [(set (match_operand:V64 0 "register_operand" "")
3273         (match_operand:V64 1 "fp_zero_operand" ""))]
3274   "reload_completed
3275    && ! TARGET_ARCH64
3276    && ((GET_CODE (operands[0]) == REG
3277         && REGNO (operands[0]) < 32)
3278        || (GET_CODE (operands[0]) == SUBREG
3279            && GET_CODE (SUBREG_REG (operands[0])) == REG
3280            && REGNO (SUBREG_REG (operands[0])) < 32))"
3281   [(clobber (const_int 0))]
3282 {
3283   enum machine_mode half_mode;
3284   rtx set_dest = operands[0];
3285   rtx dest1, dest2;
3286
3287   /* We can be expanded for DFmode or integral vector modes.  */
3288   if (<V64:MODE>mode == DFmode)
3289     half_mode = SFmode;
3290   else
3291     half_mode = SImode;
3292
3293   dest1 = gen_highpart (half_mode, set_dest);
3294   dest2 = gen_lowpart (half_mode, set_dest);
3295   emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
3296   emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
3297   DONE;
3298 })
3299
3300 (define_expand "movtf"
3301   [(set (match_operand:TF 0 "general_operand" "")
3302         (match_operand:TF 1 "general_operand" ""))]
3303   ""
3304 {
3305   /* Force TFmode constants into memory.  */
3306   if (GET_CODE (operands[0]) == REG
3307       && CONSTANT_P (operands[1]))
3308     {
3309       /* emit_group_store will send such bogosity to us when it is
3310          not storing directly into memory.  So fix this up to avoid
3311          crashes in output_constant_pool.  */
3312       if (operands [1] == const0_rtx)
3313         operands[1] = CONST0_RTX (TFmode);
3314
3315       if (TARGET_VIS && fp_zero_operand (operands[1], TFmode))
3316         goto movtf_is_ok;
3317
3318       operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3319                                                    operands[1]));
3320     }
3321
3322   /* Handle MEM cases first, note that only v9 guarantees
3323      full 16-byte alignment for quads.  */
3324   if (GET_CODE (operands[0]) == MEM)
3325     {
3326       if (register_operand (operands[1], TFmode)
3327           || fp_zero_operand (operands[1], TFmode))
3328         goto movtf_is_ok;
3329
3330       if (! reload_in_progress)
3331         {
3332           operands[0] = validize_mem (operands[0]);
3333           operands[1] = force_reg (TFmode, operands[1]);
3334         }
3335     }
3336
3337   /* Fixup PIC cases.  */
3338   if (flag_pic)
3339     {
3340       if (CONSTANT_P (operands[1])
3341           && pic_address_needs_scratch (operands[1]))
3342         operands[1] = legitimize_pic_address (operands[1], TFmode, 0);
3343
3344       if (symbolic_operand (operands[1], TFmode))
3345         {
3346           operands[1] = legitimize_pic_address (operands[1],
3347                                                 TFmode,
3348                                                 (reload_in_progress ?
3349                                                  operands[0] :
3350                                                  NULL_RTX));
3351         }
3352     }
3353
3354  movtf_is_ok:
3355   ;
3356 })
3357
3358 ;; Be careful, fmovq and {st,ld}{x,q} do not exist when !arch64 so
3359 ;; we must split them all.  :-(
3360 (define_insn "*movtf_insn_sp32"
3361   [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3362         (match_operand:TF 1 "input_operand"    "oe,GeUr,o,roG"))]
3363   "TARGET_FPU
3364    && ! TARGET_VIS
3365    && ! TARGET_ARCH64
3366    && (register_operand (operands[0], TFmode)
3367        || register_operand (operands[1], TFmode)
3368        || fp_zero_operand (operands[1], TFmode))"
3369   "#"
3370   [(set_attr "length" "4")])
3371
3372 (define_insn "*movtf_insn_vis_sp32"
3373   [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3374         (match_operand:TF 1 "input_operand"    "Goe,GeUr,o,roG"))]
3375   "TARGET_FPU
3376    && TARGET_VIS
3377    && ! TARGET_ARCH64
3378    && (register_operand (operands[0], TFmode)
3379        || register_operand (operands[1], TFmode)
3380        || fp_zero_operand (operands[1], TFmode))"
3381   "#"
3382   [(set_attr "length" "4")])
3383
3384 ;; Exactly the same as above, except that all `e' cases are deleted.
3385 ;; This is necessary to prevent reload from ever trying to use a `e' reg
3386 ;; when -mno-fpu.
3387
3388 (define_insn "*movtf_no_e_insn_sp32"
3389   [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
3390         (match_operand:TF 1 "input_operand"    "G,o,U,roG,r"))]
3391   "! TARGET_FPU
3392    && ! TARGET_ARCH64
3393    && (register_operand (operands[0], TFmode)
3394        || register_operand (operands[1], TFmode)
3395        || fp_zero_operand (operands[1], TFmode))"
3396   "#"
3397   [(set_attr "length" "4")])
3398
3399 ;; Now handle the float reg cases directly when arch64,
3400 ;; hard_quad, and proper reg number alignment are all true.
3401 (define_insn "*movtf_insn_hq_sp64"
3402   [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,o,r")
3403         (match_operand:TF 1 "input_operand"    "e,m,e,Gr,roG"))]
3404   "TARGET_FPU
3405    && ! TARGET_VIS
3406    && TARGET_ARCH64
3407    && TARGET_HARD_QUAD
3408    && (register_operand (operands[0], TFmode)
3409        || register_operand (operands[1], TFmode)
3410        || fp_zero_operand (operands[1], TFmode))"
3411   "@
3412   fmovq\t%1, %0
3413   ldq\t%1, %0
3414   stq\t%1, %0
3415   #
3416   #"
3417   [(set_attr "type" "fpmove,fpload,fpstore,*,*")
3418    (set_attr "length" "*,*,*,2,2")])
3419
3420 (define_insn "*movtf_insn_hq_vis_sp64"
3421   [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,eo,r,o")
3422         (match_operand:TF 1 "input_operand"    "e,m,e,G,roG,r"))]
3423   "TARGET_FPU
3424    && TARGET_VIS
3425    && TARGET_ARCH64
3426    && TARGET_HARD_QUAD
3427    && (register_operand (operands[0], TFmode)
3428        || register_operand (operands[1], TFmode)
3429        || fp_zero_operand (operands[1], TFmode))"
3430   "@
3431   fmovq\t%1, %0
3432   ldq\t%1, %0
3433   stq\t%1, %0
3434   #
3435   #
3436   #"
3437   [(set_attr "type" "fpmove,fpload,fpstore,*,*,*")
3438    (set_attr "length" "*,*,*,2,2,2")])
3439
3440 ;; Now we allow the integer register cases even when
3441 ;; only arch64 is true.
3442 (define_insn "*movtf_insn_sp64"
3443   [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3444         (match_operand:TF 1 "input_operand"    "oe,Ger,orG"))]
3445   "TARGET_FPU
3446    && ! TARGET_VIS
3447    && TARGET_ARCH64
3448    && ! TARGET_HARD_QUAD
3449    && (register_operand (operands[0], TFmode)
3450        || register_operand (operands[1], TFmode)
3451        || fp_zero_operand (operands[1], TFmode))"
3452   "#"
3453   [(set_attr "length" "2")])
3454
3455 (define_insn "*movtf_insn_vis_sp64"
3456   [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3457         (match_operand:TF 1 "input_operand"    "Goe,Ger,orG"))]
3458   "TARGET_FPU
3459    && TARGET_VIS
3460    && TARGET_ARCH64
3461    && ! TARGET_HARD_QUAD
3462    && (register_operand (operands[0], TFmode)
3463        || register_operand (operands[1], TFmode)
3464        || fp_zero_operand (operands[1], TFmode))"
3465   "#"
3466   [(set_attr "length" "2")])
3467
3468 (define_insn "*movtf_no_e_insn_sp64"
3469   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
3470         (match_operand:TF 1 "input_operand"    "orG,rG"))]
3471   "! TARGET_FPU
3472    && TARGET_ARCH64
3473    && (register_operand (operands[0], TFmode)
3474        || register_operand (operands[1], TFmode)
3475        || fp_zero_operand (operands[1], TFmode))"
3476   "#"
3477   [(set_attr "length" "2")])
3478
3479 ;; Now all the splits to handle multi-insn TF mode moves.
3480 (define_split
3481   [(set (match_operand:TF 0 "register_operand" "")
3482         (match_operand:TF 1 "register_operand" ""))]
3483   "reload_completed
3484    && (! TARGET_ARCH64
3485        || (TARGET_FPU
3486            && ! TARGET_HARD_QUAD)
3487        || ! fp_register_operand (operands[0], TFmode))"
3488   [(clobber (const_int 0))]
3489 {
3490   rtx set_dest = operands[0];
3491   rtx set_src = operands[1];
3492   rtx dest1, dest2;
3493   rtx src1, src2;
3494
3495   dest1 = gen_df_reg (set_dest, 0);
3496   dest2 = gen_df_reg (set_dest, 1);
3497   src1 = gen_df_reg (set_src, 0);
3498   src2 = gen_df_reg (set_src, 1);
3499
3500   /* Now emit using the real source and destination we found, swapping
3501      the order if we detect overlap.  */
3502   if (reg_overlap_mentioned_p (dest1, src2))
3503     {
3504       emit_insn (gen_movdf (dest2, src2));
3505       emit_insn (gen_movdf (dest1, src1));
3506     }
3507   else
3508     {
3509       emit_insn (gen_movdf (dest1, src1));
3510       emit_insn (gen_movdf (dest2, src2));
3511     }
3512   DONE;
3513 })
3514
3515 (define_split
3516   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3517         (match_operand:TF 1 "fp_zero_operand" ""))]
3518   "reload_completed"
3519   [(clobber (const_int 0))]
3520 {
3521   rtx set_dest = operands[0];
3522   rtx dest1, dest2;
3523
3524   switch (GET_CODE (set_dest))
3525     {
3526     case REG:
3527       dest1 = gen_df_reg (set_dest, 0);
3528       dest2 = gen_df_reg (set_dest, 1);
3529       break;
3530     case MEM:
3531       dest1 = adjust_address (set_dest, DFmode, 0);
3532       dest2 = adjust_address (set_dest, DFmode, 8);
3533       break;
3534     default:
3535       gcc_unreachable ();      
3536     }
3537
3538   emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
3539   emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
3540   DONE;
3541 })
3542
3543 (define_split
3544   [(set (match_operand:TF 0 "register_operand" "")
3545         (match_operand:TF 1 "memory_operand" ""))]
3546   "(reload_completed
3547     && offsettable_memref_p (operands[1])
3548     && (! TARGET_ARCH64
3549         || ! TARGET_HARD_QUAD
3550         || ! fp_register_operand (operands[0], TFmode)))"
3551   [(clobber (const_int 0))]
3552 {
3553   rtx word0 = adjust_address (operands[1], DFmode, 0);
3554   rtx word1 = adjust_address (operands[1], DFmode, 8);
3555   rtx set_dest, dest1, dest2;
3556
3557   set_dest = operands[0];
3558
3559   dest1 = gen_df_reg (set_dest, 0);
3560   dest2 = gen_df_reg (set_dest, 1);
3561
3562   /* Now output, ordering such that we don't clobber any registers
3563      mentioned in the address.  */
3564   if (reg_overlap_mentioned_p (dest1, word1))
3565
3566     {
3567       emit_insn (gen_movdf (dest2, word1));
3568       emit_insn (gen_movdf (dest1, word0));
3569     }
3570   else
3571    {
3572       emit_insn (gen_movdf (dest1, word0));
3573       emit_insn (gen_movdf (dest2, word1));
3574    }
3575   DONE;
3576 })
3577
3578 (define_split
3579   [(set (match_operand:TF 0 "memory_operand" "")
3580         (match_operand:TF 1 "register_operand" ""))]
3581   "(reload_completed
3582     && offsettable_memref_p (operands[0])
3583     && (! TARGET_ARCH64
3584         || ! TARGET_HARD_QUAD
3585         || ! fp_register_operand (operands[1], TFmode)))"
3586   [(clobber (const_int 0))]
3587 {
3588   rtx set_src = operands[1];
3589
3590   emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
3591                         gen_df_reg (set_src, 0)));
3592   emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
3593                         gen_df_reg (set_src, 1)));
3594   DONE;
3595 })
3596 \f
3597 ;; SPARC V9 conditional move instructions.
3598
3599 ;; We can handle larger constants here for some flavors, but for now we keep
3600 ;; it simple and only allow those constants supported by all flavors.
3601 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3602 ;; 3 contains the constant if one is present, but we handle either for
3603 ;; generality (sparc.c puts a constant in operand 2).
3604
3605 (define_expand "movqicc"
3606   [(set (match_operand:QI 0 "register_operand" "")
3607         (if_then_else:QI (match_operand 1 "comparison_operator" "")
3608                          (match_operand:QI 2 "arith10_operand" "")
3609                          (match_operand:QI 3 "arith10_operand" "")))]
3610   "TARGET_V9"
3611 {
3612   enum rtx_code code = GET_CODE (operands[1]);
3613
3614   if (GET_MODE (sparc_compare_op0) == DImode
3615       && ! TARGET_ARCH64)
3616     FAIL;
3617
3618   if (sparc_compare_op1 == const0_rtx
3619       && GET_CODE (sparc_compare_op0) == REG
3620       && GET_MODE (sparc_compare_op0) == DImode
3621       && v9_regcmp_p (code))
3622     {
3623       operands[1] = gen_rtx_fmt_ee (code, DImode,
3624                              sparc_compare_op0, sparc_compare_op1);
3625     }
3626   else
3627     {
3628       rtx cc_reg = gen_compare_reg (code,
3629                                     sparc_compare_op0, sparc_compare_op1);
3630       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3631     }
3632 })
3633
3634 (define_expand "movhicc"
3635   [(set (match_operand:HI 0 "register_operand" "")
3636         (if_then_else:HI (match_operand 1 "comparison_operator" "")
3637                          (match_operand:HI 2 "arith10_operand" "")
3638                          (match_operand:HI 3 "arith10_operand" "")))]
3639   "TARGET_V9"
3640 {
3641   enum rtx_code code = GET_CODE (operands[1]);
3642
3643   if (GET_MODE (sparc_compare_op0) == DImode
3644       && ! TARGET_ARCH64)
3645     FAIL;
3646
3647   if (sparc_compare_op1 == const0_rtx
3648       && GET_CODE (sparc_compare_op0) == REG
3649       && GET_MODE (sparc_compare_op0) == DImode
3650       && v9_regcmp_p (code))
3651     {
3652       operands[1] = gen_rtx_fmt_ee (code, DImode,
3653                              sparc_compare_op0, sparc_compare_op1);
3654     }
3655   else
3656     {
3657       rtx cc_reg = gen_compare_reg (code,
3658                                     sparc_compare_op0, sparc_compare_op1);
3659       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3660     }
3661 })
3662
3663 (define_expand "movsicc"
3664   [(set (match_operand:SI 0 "register_operand" "")
3665         (if_then_else:SI (match_operand 1 "comparison_operator" "")
3666                          (match_operand:SI 2 "arith10_operand" "")
3667                          (match_operand:SI 3 "arith10_operand" "")))]
3668   "TARGET_V9"
3669 {
3670   enum rtx_code code = GET_CODE (operands[1]);
3671   enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
3672
3673   if (sparc_compare_op1 == const0_rtx
3674       && GET_CODE (sparc_compare_op0) == REG
3675       && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
3676     {
3677       operands[1] = gen_rtx_fmt_ee (code, op0_mode,
3678                              sparc_compare_op0, sparc_compare_op1);
3679     }
3680   else
3681     {
3682       rtx cc_reg = gen_compare_reg (code,
3683                                     sparc_compare_op0, sparc_compare_op1);
3684       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3685                                     cc_reg, const0_rtx);
3686     }
3687 })
3688
3689 (define_expand "movdicc"
3690   [(set (match_operand:DI 0 "register_operand" "")
3691         (if_then_else:DI (match_operand 1 "comparison_operator" "")
3692                          (match_operand:DI 2 "arith10_double_operand" "")
3693                          (match_operand:DI 3 "arith10_double_operand" "")))]
3694   "TARGET_ARCH64"
3695 {
3696   enum rtx_code code = GET_CODE (operands[1]);
3697
3698   if (sparc_compare_op1 == const0_rtx
3699       && GET_CODE (sparc_compare_op0) == REG
3700       && GET_MODE (sparc_compare_op0) == DImode
3701       && v9_regcmp_p (code))
3702     {
3703       operands[1] = gen_rtx_fmt_ee (code, DImode,
3704                              sparc_compare_op0, sparc_compare_op1);
3705     }
3706   else
3707     {
3708       rtx cc_reg = gen_compare_reg (code,
3709                                     sparc_compare_op0, sparc_compare_op1);
3710       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3711                                     cc_reg, const0_rtx);
3712     }
3713 })
3714
3715 (define_expand "movsfcc"
3716   [(set (match_operand:SF 0 "register_operand" "")
3717         (if_then_else:SF (match_operand 1 "comparison_operator" "")
3718                          (match_operand:SF 2 "register_operand" "")
3719                          (match_operand:SF 3 "register_operand" "")))]
3720   "TARGET_V9 && TARGET_FPU"
3721 {
3722   enum rtx_code code = GET_CODE (operands[1]);
3723
3724   if (GET_MODE (sparc_compare_op0) == DImode
3725       && ! TARGET_ARCH64)
3726     FAIL;
3727
3728   if (sparc_compare_op1 == const0_rtx
3729       && GET_CODE (sparc_compare_op0) == REG
3730       && GET_MODE (sparc_compare_op0) == DImode
3731       && v9_regcmp_p (code))
3732     {
3733       operands[1] = gen_rtx_fmt_ee (code, DImode,
3734                              sparc_compare_op0, sparc_compare_op1);
3735     }
3736   else
3737     {
3738       rtx cc_reg = gen_compare_reg (code,
3739                                     sparc_compare_op0, sparc_compare_op1);
3740       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3741     }
3742 })
3743
3744 (define_expand "movdfcc"
3745   [(set (match_operand:DF 0 "register_operand" "")
3746         (if_then_else:DF (match_operand 1 "comparison_operator" "")
3747                          (match_operand:DF 2 "register_operand" "")
3748                          (match_operand:DF 3 "register_operand" "")))]
3749   "TARGET_V9 && TARGET_FPU"
3750 {
3751   enum rtx_code code = GET_CODE (operands[1]);
3752
3753   if (GET_MODE (sparc_compare_op0) == DImode
3754       && ! TARGET_ARCH64)
3755     FAIL;
3756
3757   if (sparc_compare_op1 == const0_rtx
3758       && GET_CODE (sparc_compare_op0) == REG
3759       && GET_MODE (sparc_compare_op0) == DImode
3760       && v9_regcmp_p (code))
3761     {
3762       operands[1] = gen_rtx_fmt_ee (code, DImode,
3763                              sparc_compare_op0, sparc_compare_op1);
3764     }
3765   else
3766     {
3767       rtx cc_reg = gen_compare_reg (code,
3768                                     sparc_compare_op0, sparc_compare_op1);
3769       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3770     }
3771 })
3772
3773 (define_expand "movtfcc"
3774   [(set (match_operand:TF 0 "register_operand" "")
3775         (if_then_else:TF (match_operand 1 "comparison_operator" "")
3776                          (match_operand:TF 2 "register_operand" "")
3777                          (match_operand:TF 3 "register_operand" "")))]
3778   "TARGET_V9 && TARGET_FPU"
3779 {
3780   enum rtx_code code = GET_CODE (operands[1]);
3781
3782   if (GET_MODE (sparc_compare_op0) == DImode
3783       && ! TARGET_ARCH64)
3784     FAIL;
3785
3786   if (sparc_compare_op1 == const0_rtx
3787       && GET_CODE (sparc_compare_op0) == REG
3788       && GET_MODE (sparc_compare_op0) == DImode
3789       && v9_regcmp_p (code))
3790     {
3791       operands[1] = gen_rtx_fmt_ee (code, DImode,
3792                              sparc_compare_op0, sparc_compare_op1);
3793     }
3794   else
3795     {
3796       rtx cc_reg = gen_compare_reg (code,
3797                                     sparc_compare_op0, sparc_compare_op1);
3798       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3799     }
3800 })
3801
3802 ;; Conditional move define_insns.
3803
3804 (define_insn "*movqi_cc_sp64"
3805   [(set (match_operand:QI 0 "register_operand" "=r,r")
3806         (if_then_else:QI (match_operator 1 "comparison_operator"
3807                                 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3808                                  (const_int 0)])
3809                          (match_operand:QI 3 "arith11_operand" "rL,0")
3810                          (match_operand:QI 4 "arith11_operand" "0,rL")))]
3811   "TARGET_V9"
3812   "@
3813    mov%C1\t%x2, %3, %0
3814    mov%c1\t%x2, %4, %0"
3815   [(set_attr "type" "cmove")])
3816
3817 (define_insn "*movhi_cc_sp64"
3818   [(set (match_operand:HI 0 "register_operand" "=r,r")
3819         (if_then_else:HI (match_operator 1 "comparison_operator"
3820                                 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3821                                  (const_int 0)])
3822                          (match_operand:HI 3 "arith11_operand" "rL,0")
3823                          (match_operand:HI 4 "arith11_operand" "0,rL")))]
3824   "TARGET_V9"
3825   "@
3826    mov%C1\t%x2, %3, %0
3827    mov%c1\t%x2, %4, %0"
3828   [(set_attr "type" "cmove")])
3829
3830 (define_insn "*movsi_cc_sp64"
3831   [(set (match_operand:SI 0 "register_operand" "=r,r")
3832         (if_then_else:SI (match_operator 1 "comparison_operator"
3833                                 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3834                                  (const_int 0)])
3835                          (match_operand:SI 3 "arith11_operand" "rL,0")
3836                          (match_operand:SI 4 "arith11_operand" "0,rL")))]
3837   "TARGET_V9"
3838   "@
3839    mov%C1\t%x2, %3, %0
3840    mov%c1\t%x2, %4, %0"
3841   [(set_attr "type" "cmove")])
3842
3843 ;; ??? The constraints of operands 3,4 need work.
3844 (define_insn "*movdi_cc_sp64"
3845   [(set (match_operand:DI 0 "register_operand" "=r,r")
3846         (if_then_else:DI (match_operator 1 "comparison_operator"
3847                                 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3848                                  (const_int 0)])
3849                          (match_operand:DI 3 "arith11_double_operand" "rLH,0")
3850                          (match_operand:DI 4 "arith11_double_operand" "0,rLH")))]
3851   "TARGET_ARCH64"
3852   "@
3853    mov%C1\t%x2, %3, %0
3854    mov%c1\t%x2, %4, %0"
3855   [(set_attr "type" "cmove")])
3856
3857 (define_insn "*movdi_cc_sp64_trunc"
3858   [(set (match_operand:SI 0 "register_operand" "=r,r")
3859         (if_then_else:SI (match_operator 1 "comparison_operator"
3860                                 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3861                                  (const_int 0)])
3862                          (match_operand:SI 3 "arith11_double_operand" "rLH,0")
3863                          (match_operand:SI 4 "arith11_double_operand" "0,rLH")))]
3864   "TARGET_ARCH64"
3865   "@
3866    mov%C1\t%x2, %3, %0
3867    mov%c1\t%x2, %4, %0"
3868   [(set_attr "type" "cmove")])
3869
3870 (define_insn "*movsf_cc_sp64"
3871   [(set (match_operand:SF 0 "register_operand" "=f,f")
3872         (if_then_else:SF (match_operator 1 "comparison_operator"
3873                                 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3874                                  (const_int 0)])
3875                          (match_operand:SF 3 "register_operand" "f,0")
3876                          (match_operand:SF 4 "register_operand" "0,f")))]
3877   "TARGET_V9 && TARGET_FPU"
3878   "@
3879    fmovs%C1\t%x2, %3, %0
3880    fmovs%c1\t%x2, %4, %0"
3881   [(set_attr "type" "fpcmove")])
3882
3883 (define_insn "movdf_cc_sp64"
3884   [(set (match_operand:DF 0 "register_operand" "=e,e")
3885         (if_then_else:DF (match_operator 1 "comparison_operator"
3886                                 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3887                                  (const_int 0)])
3888                          (match_operand:DF 3 "register_operand" "e,0")
3889                          (match_operand:DF 4 "register_operand" "0,e")))]
3890   "TARGET_V9 && TARGET_FPU"
3891   "@
3892    fmovd%C1\t%x2, %3, %0
3893    fmovd%c1\t%x2, %4, %0"
3894   [(set_attr "type" "fpcmove")
3895    (set_attr "fptype" "double")])
3896
3897 (define_insn "*movtf_cc_hq_sp64"
3898   [(set (match_operand:TF 0 "register_operand" "=e,e")
3899         (if_then_else:TF (match_operator 1 "comparison_operator"
3900                                 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3901                                  (const_int 0)])
3902                          (match_operand:TF 3 "register_operand" "e,0")
3903                          (match_operand:TF 4 "register_operand" "0,e")))]
3904   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3905   "@
3906    fmovq%C1\t%x2, %3, %0
3907    fmovq%c1\t%x2, %4, %0"
3908   [(set_attr "type" "fpcmove")])
3909
3910 (define_insn_and_split "*movtf_cc_sp64"
3911   [(set (match_operand:TF 0 "register_operand" "=e,e")
3912         (if_then_else:TF (match_operator 1 "comparison_operator"
3913                             [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3914                              (const_int 0)])
3915                          (match_operand:TF 3 "register_operand" "e,0")
3916                          (match_operand:TF 4 "register_operand" "0,e")))]
3917   "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
3918   "#"
3919   "&& reload_completed"
3920   [(clobber (const_int 0))]
3921 {
3922   rtx set_dest = operands[0];
3923   rtx set_srca = operands[3];
3924   rtx set_srcb = operands[4];
3925   int third = rtx_equal_p (set_dest, set_srca);
3926   rtx dest1, dest2;
3927   rtx srca1, srca2, srcb1, srcb2;
3928
3929   dest1 = gen_df_reg (set_dest, 0);
3930   dest2 = gen_df_reg (set_dest, 1);
3931   srca1 = gen_df_reg (set_srca, 0);
3932   srca2 = gen_df_reg (set_srca, 1);
3933   srcb1 = gen_df_reg (set_srcb, 0);
3934   srcb2 = gen_df_reg (set_srcb, 1);
3935
3936   /* Now emit using the real source and destination we found, swapping
3937      the order if we detect overlap.  */
3938   if ((third && reg_overlap_mentioned_p (dest1, srcb2))
3939       || (!third && reg_overlap_mentioned_p (dest1, srca2)))
3940     {
3941       emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3942       emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3943     }
3944   else
3945     {
3946       emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3947       emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3948     }
3949   DONE;
3950 }
3951   [(set_attr "length" "2")])
3952
3953 (define_insn "*movqi_cc_reg_sp64"
3954   [(set (match_operand:QI 0 "register_operand" "=r,r")
3955         (if_then_else:QI (match_operator 1 "v9_regcmp_op"
3956                                 [(match_operand:DI 2 "register_operand" "r,r")
3957                                  (const_int 0)])
3958                          (match_operand:QI 3 "arith10_operand" "rM,0")
3959                          (match_operand:QI 4 "arith10_operand" "0,rM")))]
3960   "TARGET_ARCH64"
3961   "@
3962    movr%D1\t%2, %r3, %0
3963    movr%d1\t%2, %r4, %0"
3964   [(set_attr "type" "cmove")])
3965
3966 (define_insn "*movhi_cc_reg_sp64"
3967   [(set (match_operand:HI 0 "register_operand" "=r,r")
3968         (if_then_else:HI (match_operator 1 "v9_regcmp_op"
3969                                 [(match_operand:DI 2 "register_operand" "r,r")
3970                                  (const_int 0)])
3971                          (match_operand:HI 3 "arith10_operand" "rM,0")
3972                          (match_operand:HI 4 "arith10_operand" "0,rM")))]
3973   "TARGET_ARCH64"
3974   "@
3975    movr%D1\t%2, %r3, %0
3976    movr%d1\t%2, %r4, %0"
3977   [(set_attr "type" "cmove")])
3978
3979 (define_insn "*movsi_cc_reg_sp64"
3980   [(set (match_operand:SI 0 "register_operand" "=r,r")
3981         (if_then_else:SI (match_operator 1 "v9_regcmp_op"
3982                                 [(match_operand:DI 2 "register_operand" "r,r")
3983                                  (const_int 0)])
3984                          (match_operand:SI 3 "arith10_operand" "rM,0")
3985                          (match_operand:SI 4 "arith10_operand" "0,rM")))]
3986   "TARGET_ARCH64"
3987   "@
3988    movr%D1\t%2, %r3, %0
3989    movr%d1\t%2, %r4, %0"
3990   [(set_attr "type" "cmove")])
3991
3992 ;; ??? The constraints of operands 3,4 need work.
3993 (define_insn "*movdi_cc_reg_sp64"
3994   [(set (match_operand:DI 0 "register_operand" "=r,r")
3995         (if_then_else:DI (match_operator 1 "v9_regcmp_op"
3996                                 [(match_operand:DI 2 "register_operand" "r,r")
3997                                  (const_int 0)])
3998                          (match_operand:DI 3 "arith10_double_operand" "rMH,0")
3999                          (match_operand:DI 4 "arith10_double_operand" "0,rMH")))]
4000   "TARGET_ARCH64"
4001   "@
4002    movr%D1\t%2, %r3, %0
4003    movr%d1\t%2, %r4, %0"
4004   [(set_attr "type" "cmove")])
4005
4006 (define_insn "*movdi_cc_reg_sp64_trunc"
4007   [(set (match_operand:SI 0 "register_operand" "=r,r")
4008         (if_then_else:SI (match_operator 1 "v9_regcmp_op"
4009                                 [(match_operand:DI 2 "register_operand" "r,r")
4010                                  (const_int 0)])
4011                          (match_operand:SI 3 "arith10_double_operand" "rMH,0")
4012                          (match_operand:SI 4 "arith10_double_operand" "0,rMH")))]
4013   "TARGET_ARCH64"
4014   "@
4015    movr%D1\t%2, %r3, %0
4016    movr%d1\t%2, %r4, %0"
4017   [(set_attr "type" "cmove")])
4018
4019 (define_insn "*movsf_cc_reg_sp64"
4020   [(set (match_operand:SF 0 "register_operand" "=f,f")
4021         (if_then_else:SF (match_operator 1 "v9_regcmp_op"
4022                                 [(match_operand:DI 2 "register_operand" "r,r")
4023                                  (const_int 0)])
4024                          (match_operand:SF 3 "register_operand" "f,0")
4025                          (match_operand:SF 4 "register_operand" "0,f")))]
4026   "TARGET_ARCH64 && TARGET_FPU"
4027   "@
4028    fmovrs%D1\t%2, %3, %0
4029    fmovrs%d1\t%2, %4, %0"
4030   [(set_attr "type" "fpcrmove")])
4031
4032 (define_insn "movdf_cc_reg_sp64"
4033   [(set (match_operand:DF 0 "register_operand" "=e,e")
4034         (if_then_else:DF (match_operator 1 "v9_regcmp_op"
4035                                 [(match_operand:DI 2 "register_operand" "r,r")
4036                                  (const_int 0)])
4037                          (match_operand:DF 3 "register_operand" "e,0")
4038                          (match_operand:DF 4 "register_operand" "0,e")))]
4039   "TARGET_ARCH64 && TARGET_FPU"
4040   "@
4041    fmovrd%D1\t%2, %3, %0
4042    fmovrd%d1\t%2, %4, %0"
4043   [(set_attr "type" "fpcrmove")
4044    (set_attr "fptype" "double")])
4045
4046 (define_insn "*movtf_cc_reg_hq_sp64"
4047   [(set (match_operand:TF 0 "register_operand" "=e,e")
4048         (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4049                                 [(match_operand:DI 2 "register_operand" "r,r")
4050                                  (const_int 0)])
4051                          (match_operand:TF 3 "register_operand" "e,0")
4052                          (match_operand:TF 4 "register_operand" "0,e")))]
4053   "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
4054   "@
4055    fmovrq%D1\t%2, %3, %0
4056    fmovrq%d1\t%2, %4, %0"
4057   [(set_attr "type" "fpcrmove")])
4058
4059 (define_insn_and_split "*movtf_cc_reg_sp64"
4060   [(set (match_operand:TF 0 "register_operand" "=e,e")
4061         (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4062                                 [(match_operand:DI 2 "register_operand" "r,r")
4063                                  (const_int 0)])
4064                          (match_operand:TF 3 "register_operand" "e,0")
4065                          (match_operand:TF 4 "register_operand" "0,e")))]
4066   "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
4067   "#"
4068   "&& reload_completed"
4069   [(clobber (const_int 0))]
4070 {
4071   rtx set_dest = operands[0];
4072   rtx set_srca = operands[3];
4073   rtx set_srcb = operands[4];
4074   int third = rtx_equal_p (set_dest, set_srca);
4075   rtx dest1, dest2;
4076   rtx srca1, srca2, srcb1, srcb2;
4077
4078   dest1 = gen_df_reg (set_dest, 0);
4079   dest2 = gen_df_reg (set_dest, 1);
4080   srca1 = gen_df_reg (set_srca, 0);
4081   srca2 = gen_df_reg (set_srca, 1);
4082   srcb1 = gen_df_reg (set_srcb, 0);
4083   srcb2 = gen_df_reg (set_srcb, 1);
4084
4085   /* Now emit using the real source and destination we found, swapping
4086      the order if we detect overlap.  */
4087   if ((third && reg_overlap_mentioned_p (dest1, srcb2))
4088       || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4089     {
4090       emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4091       emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4092     }
4093   else
4094     {
4095       emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4096       emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4097     }
4098   DONE;
4099 }
4100   [(set_attr "length" "2")])
4101
4102 \f
4103 ;;- zero extension instructions
4104
4105 ;; These patterns originally accepted general_operands, however, slightly
4106 ;; better code is generated by only accepting register_operands, and then
4107 ;; letting combine generate the ldu[hb] insns.
4108
4109 (define_expand "zero_extendhisi2"
4110   [(set (match_operand:SI 0 "register_operand" "")
4111         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
4112   ""
4113 {
4114   rtx temp = gen_reg_rtx (SImode);
4115   rtx shift_16 = GEN_INT (16);
4116   int op1_subbyte = 0;
4117
4118   if (GET_CODE (operand1) == SUBREG)
4119     {
4120       op1_subbyte = SUBREG_BYTE (operand1);
4121       op1_subbyte /= GET_MODE_SIZE (SImode);
4122       op1_subbyte *= GET_MODE_SIZE (SImode);
4123       operand1 = XEXP (operand1, 0);
4124     }
4125
4126   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4127                           shift_16));
4128   emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
4129   DONE;
4130 })
4131
4132 (define_insn "*zero_extendhisi2_insn"
4133   [(set (match_operand:SI 0 "register_operand" "=r")
4134         (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4135   ""
4136   "lduh\t%1, %0"
4137   [(set_attr "type" "load")
4138    (set_attr "us3load_type" "3cycle")])
4139
4140 (define_expand "zero_extendqihi2"
4141   [(set (match_operand:HI 0 "register_operand" "")
4142         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
4143   ""
4144   "")
4145
4146 (define_insn "*zero_extendqihi2_insn"
4147   [(set (match_operand:HI 0 "register_operand" "=r,r")
4148         (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
4149   "GET_CODE (operands[1]) != CONST_INT"
4150   "@
4151    and\t%1, 0xff, %0
4152    ldub\t%1, %0"
4153   [(set_attr "type" "*,load")
4154    (set_attr "us3load_type" "*,3cycle")])
4155
4156 (define_expand "zero_extendqisi2"
4157   [(set (match_operand:SI 0 "register_operand" "")
4158         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
4159   ""
4160   "")
4161
4162 (define_insn "*zero_extendqisi2_insn"
4163   [(set (match_operand:SI 0 "register_operand" "=r,r")
4164         (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
4165   "GET_CODE (operands[1]) != CONST_INT"
4166   "@
4167    and\t%1, 0xff, %0
4168    ldub\t%1, %0"
4169   [(set_attr "type" "*,load")
4170    (set_attr "us3load_type" "*,3cycle")])
4171
4172 (define_expand "zero_extendqidi2"
4173   [(set (match_operand:DI 0 "register_operand" "")
4174         (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
4175   "TARGET_ARCH64"
4176   "")
4177
4178 (define_insn "*zero_extendqidi2_insn"
4179   [(set (match_operand:DI 0 "register_operand" "=r,r")
4180         (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
4181   "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4182   "@
4183    and\t%1, 0xff, %0
4184    ldub\t%1, %0"
4185   [(set_attr "type" "*,load")
4186    (set_attr "us3load_type" "*,3cycle")])
4187
4188 (define_expand "zero_extendhidi2"
4189   [(set (match_operand:DI 0 "register_operand" "")
4190         (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
4191   "TARGET_ARCH64"
4192 {
4193   rtx temp = gen_reg_rtx (DImode);
4194   rtx shift_48 = GEN_INT (48);
4195   int op1_subbyte = 0;
4196
4197   if (GET_CODE (operand1) == SUBREG)
4198     {
4199       op1_subbyte = SUBREG_BYTE (operand1);
4200       op1_subbyte /= GET_MODE_SIZE (DImode);
4201       op1_subbyte *= GET_MODE_SIZE (DImode);
4202       operand1 = XEXP (operand1, 0);
4203     }
4204
4205   emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4206                           shift_48));
4207   emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
4208   DONE;
4209 })
4210
4211 (define_insn "*zero_extendhidi2_insn"
4212   [(set (match_operand:DI 0 "register_operand" "=r")
4213         (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4214   "TARGET_ARCH64"
4215   "lduh\t%1, %0"
4216   [(set_attr "type" "load")
4217    (set_attr "us3load_type" "3cycle")])
4218
4219
4220 ;; ??? Write truncdisi pattern using sra?
4221
4222 (define_expand "zero_extendsidi2"
4223   [(set (match_operand:DI 0 "register_operand" "")
4224         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4225   ""
4226   "")
4227
4228 (define_insn "*zero_extendsidi2_insn_sp64"
4229   [(set (match_operand:DI 0 "register_operand" "=r,r")
4230         (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4231   "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4232   "@
4233    srl\t%1, 0, %0
4234    lduw\t%1, %0"
4235   [(set_attr "type" "shift,load")])
4236
4237 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
4238   [(set (match_operand:DI 0 "register_operand" "=r")
4239         (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4240   "! TARGET_ARCH64"
4241   "#"
4242   "&& reload_completed"
4243   [(set (match_dup 2) (match_dup 3))
4244    (set (match_dup 4) (match_dup 5))]
4245 {
4246   rtx dest1, dest2;
4247
4248   dest1 = gen_highpart (SImode, operands[0]);
4249   dest2 = gen_lowpart (SImode, operands[0]);
4250
4251   /* Swap the order in case of overlap.  */
4252   if (REGNO (dest1) == REGNO (operands[1]))
4253     {
4254       operands[2] = dest2;
4255       operands[3] = operands[1];
4256       operands[4] = dest1;
4257       operands[5] = const0_rtx;
4258     }
4259   else
4260     {
4261       operands[2] = dest1;
4262       operands[3] = const0_rtx;
4263       operands[4] = dest2;
4264       operands[5] = operands[1];
4265     }
4266 }
4267   [(set_attr "length" "2")])
4268
4269 ;; Simplify comparisons of extended values.
4270
4271 (define_insn "*cmp_zero_extendqisi2"
4272   [(set (reg:CC 100)
4273         (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
4274                     (const_int 0)))]
4275   ""
4276   "andcc\t%0, 0xff, %%g0"
4277   [(set_attr "type" "compare")])
4278
4279 (define_insn "*cmp_zero_qi"
4280   [(set (reg:CC 100)
4281         (compare:CC (match_operand:QI 0 "register_operand" "r")
4282                     (const_int 0)))]
4283   ""
4284   "andcc\t%0, 0xff, %%g0"
4285   [(set_attr "type" "compare")])
4286
4287 (define_insn "*cmp_zero_extendqisi2_set"
4288   [(set (reg:CC 100)
4289         (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
4290                     (const_int 0)))
4291    (set (match_operand:SI 0 "register_operand" "=r")
4292         (zero_extend:SI (match_dup 1)))]
4293   ""
4294   "andcc\t%1, 0xff, %0"
4295   [(set_attr "type" "compare")])
4296
4297 (define_insn "*cmp_zero_extendqisi2_andcc_set"
4298   [(set (reg:CC 100)
4299         (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
4300                             (const_int 255))
4301                     (const_int 0)))
4302    (set (match_operand:SI 0 "register_operand" "=r")
4303         (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
4304   ""
4305   "andcc\t%1, 0xff, %0"
4306   [(set_attr "type" "compare")])
4307
4308 (define_insn "*cmp_zero_extendqidi2"
4309   [(set (reg:CCX 100)
4310         (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
4311                      (const_int 0)))]
4312   "TARGET_ARCH64"
4313   "andcc\t%0, 0xff, %%g0"
4314   [(set_attr "type" "compare")])
4315
4316 (define_insn "*cmp_zero_qi_sp64"
4317   [(set (reg:CCX 100)
4318         (compare:CCX (match_operand:QI 0 "register_operand" "r")
4319                      (const_int 0)))]
4320   "TARGET_ARCH64"
4321   "andcc\t%0, 0xff, %%g0"
4322   [(set_attr "type" "compare")])
4323
4324 (define_insn "*cmp_zero_extendqidi2_set"
4325   [(set (reg:CCX 100)
4326         (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
4327                      (const_int 0)))
4328    (set (match_operand:DI 0 "register_operand" "=r")
4329         (zero_extend:DI (match_dup 1)))]
4330   "TARGET_ARCH64"
4331   "andcc\t%1, 0xff, %0"
4332   [(set_attr "type" "compare")])
4333
4334 (define_insn "*cmp_zero_extendqidi2_andcc_set"
4335   [(set (reg:CCX 100)
4336         (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
4337                              (const_int 255))
4338                      (const_int 0)))
4339    (set (match_operand:DI 0 "register_operand" "=r")
4340         (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
4341   "TARGET_ARCH64"
4342   "andcc\t%1, 0xff, %0"
4343   [(set_attr "type" "compare")])
4344
4345 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
4346
4347 (define_insn "*cmp_siqi_trunc"
4348   [(set (reg:CC 100)
4349         (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
4350                     (const_int 0)))]
4351   ""
4352   "andcc\t%0, 0xff, %%g0"
4353   [(set_attr "type" "compare")])
4354
4355 (define_insn "*cmp_siqi_trunc_set"
4356   [(set (reg:CC 100)
4357         (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
4358                     (const_int 0)))
4359    (set (match_operand:QI 0 "register_operand" "=r")
4360         (subreg:QI (match_dup 1) 3))]
4361   ""
4362   "andcc\t%1, 0xff, %0"
4363   [(set_attr "type" "compare")])
4364
4365 (define_insn "*cmp_diqi_trunc"
4366   [(set (reg:CC 100)
4367         (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
4368                     (const_int 0)))]
4369   "TARGET_ARCH64"
4370   "andcc\t%0, 0xff, %%g0"
4371   [(set_attr "type" "compare")])
4372
4373 (define_insn "*cmp_diqi_trunc_set"
4374   [(set (reg:CC 100)
4375         (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
4376                     (const_int 0)))
4377    (set (match_operand:QI 0 "register_operand" "=r")
4378         (subreg:QI (match_dup 1) 7))]
4379   "TARGET_ARCH64"
4380   "andcc\t%1, 0xff, %0"
4381   [(set_attr "type" "compare")])
4382 \f
4383 ;;- sign extension instructions
4384
4385 ;; These patterns originally accepted general_operands, however, slightly
4386 ;; better code is generated by only accepting register_operands, and then
4387 ;; letting combine generate the lds[hb] insns.
4388
4389 (define_expand "extendhisi2"
4390   [(set (match_operand:SI 0 "register_operand" "")
4391         (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
4392   ""
4393 {
4394   rtx temp = gen_reg_rtx (SImode);
4395   rtx shift_16 = GEN_INT (16);
4396   int op1_subbyte = 0;
4397
4398   if (GET_CODE (operand1) == SUBREG)
4399     {
4400       op1_subbyte = SUBREG_BYTE (operand1);
4401       op1_subbyte /= GET_MODE_SIZE (SImode);
4402       op1_subbyte *= GET_MODE_SIZE (SImode);
4403       operand1 = XEXP (operand1, 0);
4404     }
4405
4406   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4407                           shift_16));
4408   emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
4409   DONE;
4410 })
4411
4412 (define_insn "*sign_extendhisi2_insn"
4413   [(set (match_operand:SI 0 "register_operand" "=r")
4414         (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4415   ""
4416   "ldsh\t%1, %0"
4417   [(set_attr "type" "sload")
4418    (set_attr "us3load_type" "3cycle")])
4419
4420 (define_expand "extendqihi2"
4421   [(set (match_operand:HI 0 "register_operand" "")
4422         (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
4423   ""
4424 {
4425   rtx temp = gen_reg_rtx (SImode);
4426   rtx shift_24 = GEN_INT (24);
4427   int op1_subbyte = 0;
4428   int op0_subbyte = 0;
4429
4430   if (GET_CODE (operand1) == SUBREG)
4431     {
4432       op1_subbyte = SUBREG_BYTE (operand1);
4433       op1_subbyte /= GET_MODE_SIZE (SImode);
4434       op1_subbyte *= GET_MODE_SIZE (SImode);
4435       operand1 = XEXP (operand1, 0);
4436     }
4437   if (GET_CODE (operand0) == SUBREG)
4438     {
4439       op0_subbyte = SUBREG_BYTE (operand0);
4440       op0_subbyte /= GET_MODE_SIZE (SImode);
4441       op0_subbyte *= GET_MODE_SIZE (SImode);
4442       operand0 = XEXP (operand0, 0);
4443     }
4444   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4445                           shift_24));
4446   if (GET_MODE (operand0) != SImode)
4447     operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
4448   emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4449   DONE;
4450 })
4451
4452 (define_insn "*sign_extendqihi2_insn"
4453   [(set (match_operand:HI 0 "register_operand" "=r")
4454         (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
4455   ""
4456   "ldsb\t%1, %0"
4457   [(set_attr "type" "sload")
4458    (set_attr "us3load_type" "3cycle")])
4459
4460 (define_expand "extendqisi2"
4461   [(set (match_operand:SI 0 "register_operand" "")
4462         (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
4463   ""
4464 {
4465   rtx temp = gen_reg_rtx (SImode);
4466   rtx shift_24 = GEN_INT (24);
4467   int op1_subbyte = 0;
4468
4469   if (GET_CODE (operand1) == SUBREG)
4470     {
4471       op1_subbyte = SUBREG_BYTE (operand1);
4472       op1_subbyte /= GET_MODE_SIZE (SImode);
4473       op1_subbyte *= GET_MODE_SIZE (SImode);
4474       operand1 = XEXP (operand1, 0);
4475     }
4476
4477   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4478                           shift_24));
4479   emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4480   DONE;
4481 })
4482
4483 (define_insn "*sign_extendqisi2_insn"
4484   [(set (match_operand:SI 0 "register_operand" "=r")
4485         (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
4486   ""
4487   "ldsb\t%1, %0"
4488   [(set_attr "type" "sload")
4489    (set_attr "us3load_type" "3cycle")])
4490
4491 (define_expand "extendqidi2"
4492   [(set (match_operand:DI 0 "register_operand" "")
4493         (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
4494   "TARGET_ARCH64"
4495 {
4496   rtx temp = gen_reg_rtx (DImode);
4497   rtx shift_56 = GEN_INT (56);
4498   int op1_subbyte = 0;
4499
4500   if (GET_CODE (operand1) == SUBREG)
4501     {
4502       op1_subbyte = SUBREG_BYTE (operand1);
4503       op1_subbyte /= GET_MODE_SIZE (DImode);
4504       op1_subbyte *= GET_MODE_SIZE (DImode);
4505       operand1 = XEXP (operand1, 0);
4506     }
4507
4508   emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4509                           shift_56));
4510   emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
4511   DONE;
4512 })
4513
4514 (define_insn "*sign_extendqidi2_insn"
4515   [(set (match_operand:DI 0 "register_operand" "=r")
4516         (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
4517   "TARGET_ARCH64"
4518   "ldsb\t%1, %0"
4519   [(set_attr "type" "sload")
4520    (set_attr "us3load_type" "3cycle")])
4521
4522 (define_expand "extendhidi2"
4523   [(set (match_operand:DI 0 "register_operand" "")
4524         (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
4525   "TARGET_ARCH64"
4526 {
4527   rtx temp = gen_reg_rtx (DImode);
4528   rtx shift_48 = GEN_INT (48);
4529   int op1_subbyte = 0;
4530
4531   if (GET_CODE (operand1) == SUBREG)
4532     {
4533       op1_subbyte = SUBREG_BYTE (operand1);
4534       op1_subbyte /= GET_MODE_SIZE (DImode);
4535       op1_subbyte *= GET_MODE_SIZE (DImode);
4536       operand1 = XEXP (operand1, 0);
4537     }
4538
4539   emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4540                           shift_48));
4541   emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
4542   DONE;
4543 })
4544
4545 (define_insn "*sign_extendhidi2_insn"
4546   [(set (match_operand:DI 0 "register_operand" "=r")
4547         (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4548   "TARGET_ARCH64"
4549   "ldsh\t%1, %0"
4550   [(set_attr "type" "sload")
4551    (set_attr "us3load_type" "3cycle")])
4552
4553 (define_expand "extendsidi2"
4554   [(set (match_operand:DI 0 "register_operand" "")
4555         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
4556   "TARGET_ARCH64"
4557   "")
4558
4559 (define_insn "*sign_extendsidi2_insn"
4560   [(set (match_operand:DI 0 "register_operand" "=r,r")
4561         (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4562   "TARGET_ARCH64"
4563   "@
4564   sra\t%1, 0, %0
4565   ldsw\t%1, %0"
4566   [(set_attr "type" "shift,sload")
4567    (set_attr "us3load_type" "*,3cycle")])
4568 \f
4569 ;; Special pattern for optimizing bit-field compares.  This is needed
4570 ;; because combine uses this as a canonical form.
4571
4572 (define_insn "*cmp_zero_extract"
4573   [(set (reg:CC 100)
4574         (compare:CC
4575          (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
4576                           (match_operand:SI 1 "small_int_or_double" "n")
4577                           (match_operand:SI 2 "small_int_or_double" "n"))
4578          (const_int 0)))]
4579   "(GET_CODE (operands[2]) == CONST_INT
4580     && INTVAL (operands[2]) > 19)
4581    || (GET_CODE (operands[2]) == CONST_DOUBLE
4582        && CONST_DOUBLE_LOW (operands[2]) > 19)"
4583 {
4584   int len = (GET_CODE (operands[1]) == CONST_INT
4585              ? INTVAL (operands[1])
4586              : CONST_DOUBLE_LOW (operands[1]));
4587   int pos = 32 -
4588             (GET_CODE (operands[2]) == CONST_INT
4589              ? INTVAL (operands[2])
4590              : CONST_DOUBLE_LOW (operands[2])) - len;
4591   HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
4592
4593   operands[1] = GEN_INT (mask);
4594   return "andcc\t%0, %1, %%g0";
4595 }
4596   [(set_attr "type" "compare")])
4597
4598 (define_insn "*cmp_zero_extract_sp64"
4599   [(set (reg:CCX 100)
4600         (compare:CCX
4601          (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
4602                           (match_operand:SI 1 "small_int_or_double" "n")
4603                           (match_operand:SI 2 "small_int_or_double" "n"))
4604          (const_int 0)))]
4605   "TARGET_ARCH64
4606    && ((GET_CODE (operands[2]) == CONST_INT
4607         && INTVAL (operands[2]) > 51)
4608        || (GET_CODE (operands[2]) == CONST_DOUBLE
4609            && CONST_DOUBLE_LOW (operands[2]) > 51))"
4610 {
4611   int len = (GET_CODE (operands[1]) == CONST_INT
4612              ? INTVAL (operands[1])
4613              : CONST_DOUBLE_LOW (operands[1]));
4614   int pos = 64 -
4615             (GET_CODE (operands[2]) == CONST_INT
4616              ? INTVAL (operands[2])
4617              : CONST_DOUBLE_LOW (operands[2])) - len;
4618   HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
4619
4620   operands[1] = GEN_INT (mask);
4621   return "andcc\t%0, %1, %%g0";
4622 }
4623   [(set_attr "type" "compare")])
4624 \f
4625 ;; Conversions between float, double and long double.
4626
4627 (define_insn "extendsfdf2"
4628   [(set (match_operand:DF 0 "register_operand" "=e")
4629         (float_extend:DF
4630          (match_operand:SF 1 "register_operand" "f")))]
4631   "TARGET_FPU"
4632   "fstod\t%1, %0"
4633   [(set_attr "type" "fp")
4634    (set_attr "fptype" "double")])
4635
4636 (define_expand "extendsftf2"
4637   [(set (match_operand:TF 0 "nonimmediate_operand" "")
4638         (float_extend:TF
4639          (match_operand:SF 1 "register_operand" "")))]
4640   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4641   "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4642
4643 (define_insn "*extendsftf2_hq"
4644   [(set (match_operand:TF 0 "register_operand" "=e")
4645         (float_extend:TF
4646          (match_operand:SF 1 "register_operand" "f")))]
4647   "TARGET_FPU && TARGET_HARD_QUAD"
4648   "fstoq\t%1, %0"
4649   [(set_attr "type" "fp")])
4650
4651 (define_expand "extenddftf2"
4652   [(set (match_operand:TF 0 "nonimmediate_operand" "")
4653         (float_extend:TF
4654          (match_operand:DF 1 "register_operand" "")))]
4655   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4656   "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4657
4658 (define_insn "*extenddftf2_hq"
4659   [(set (match_operand:TF 0 "register_operand" "=e")
4660         (float_extend:TF
4661          (match_operand:DF 1 "register_operand" "e")))]
4662   "TARGET_FPU && TARGET_HARD_QUAD"
4663   "fdtoq\t%1, %0"
4664   [(set_attr "type" "fp")])
4665
4666 (define_insn "truncdfsf2"
4667   [(set (match_operand:SF 0 "register_operand" "=f")
4668         (float_truncate:SF
4669          (match_operand:DF 1 "register_operand" "e")))]
4670   "TARGET_FPU"
4671   "fdtos\t%1, %0"
4672   [(set_attr "type" "fp")
4673    (set_attr "fptype" "double")])
4674
4675 (define_expand "trunctfsf2"
4676   [(set (match_operand:SF 0 "register_operand" "")
4677         (float_truncate:SF
4678          (match_operand:TF 1 "general_operand" "")))]
4679   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4680   "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4681
4682 (define_insn "*trunctfsf2_hq"
4683   [(set (match_operand:SF 0 "register_operand" "=f")
4684         (float_truncate:SF
4685          (match_operand:TF 1 "register_operand" "e")))]
4686   "TARGET_FPU && TARGET_HARD_QUAD"
4687   "fqtos\t%1, %0"
4688   [(set_attr "type" "fp")])
4689
4690 (define_expand "trunctfdf2"
4691   [(set (match_operand:DF 0 "register_operand" "")
4692         (float_truncate:DF
4693          (match_operand:TF 1 "general_operand" "")))]
4694   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4695   "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4696
4697 (define_insn "*trunctfdf2_hq"
4698   [(set (match_operand:DF 0 "register_operand" "=e")
4699         (float_truncate:DF
4700          (match_operand:TF 1 "register_operand" "e")))]
4701   "TARGET_FPU && TARGET_HARD_QUAD"
4702   "fqtod\t%1, %0"
4703   [(set_attr "type" "fp")])
4704 \f
4705 ;; Conversion between fixed point and floating point.
4706
4707 (define_insn "floatsisf2"
4708   [(set (match_operand:SF 0 "register_operand" "=f")
4709         (float:SF (match_operand:SI 1 "register_operand" "f")))]
4710   "TARGET_FPU"
4711   "fitos\t%1, %0"
4712   [(set_attr "type" "fp")
4713    (set_attr "fptype" "double")])
4714
4715 (define_insn "floatsidf2"
4716   [(set (match_operand:DF 0 "register_operand" "=e")
4717         (float:DF (match_operand:SI 1 "register_operand" "f")))]
4718   "TARGET_FPU"
4719   "fitod\t%1, %0"
4720   [(set_attr "type" "fp")
4721    (set_attr "fptype" "double")])
4722
4723 (define_expand "floatsitf2"
4724   [(set (match_operand:TF 0 "nonimmediate_operand" "")
4725         (float:TF (match_operand:SI 1 "register_operand" "")))]
4726   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4727   "emit_tfmode_cvt (FLOAT, operands); DONE;")
4728
4729 (define_insn "*floatsitf2_hq"
4730   [(set (match_operand:TF 0 "register_operand" "=e")
4731         (float:TF (match_operand:SI 1 "register_operand" "f")))]
4732   "TARGET_FPU && TARGET_HARD_QUAD"
4733   "fitoq\t%1, %0"
4734   [(set_attr "type" "fp")])
4735
4736 (define_expand "floatunssitf2"
4737   [(set (match_operand:TF 0 "nonimmediate_operand" "")
4738         (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
4739   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4740   "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4741
4742 ;; Now the same for 64 bit sources.
4743
4744 (define_insn "floatdisf2"
4745   [(set (match_operand:SF 0 "register_operand" "=f")
4746         (float:SF (match_operand:DI 1 "register_operand" "e")))]
4747   "TARGET_V9 && TARGET_FPU"
4748   "fxtos\t%1, %0"
4749   [(set_attr "type" "fp")
4750    (set_attr "fptype" "double")])
4751
4752 (define_expand "floatunsdisf2"
4753   [(use (match_operand:SF 0 "register_operand" ""))
4754    (use (match_operand:DI 1 "general_operand" ""))]
4755   "TARGET_ARCH64 && TARGET_FPU"
4756   "sparc_emit_floatunsdi (operands, SFmode); DONE;")
4757
4758 (define_insn "floatdidf2"
4759   [(set (match_operand:DF 0 "register_operand" "=e")
4760         (float:DF (match_operand:DI 1 "register_operand" "e")))]
4761   "TARGET_V9 && TARGET_FPU"
4762   "fxtod\t%1, %0"
4763   [(set_attr "type" "fp")
4764    (set_attr "fptype" "double")])
4765
4766 (define_expand "floatunsdidf2"
4767   [(use (match_operand:DF 0 "register_operand" ""))
4768    (use (match_operand:DI 1 "general_operand" ""))]
4769   "TARGET_ARCH64 && TARGET_FPU"
4770   "sparc_emit_floatunsdi (operands, DFmode); DONE;")
4771
4772 (define_expand "floatditf2"
4773   [(set (match_operand:TF 0 "nonimmediate_operand" "")
4774         (float:TF (match_operand:DI 1 "register_operand" "")))]
4775   "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4776   "emit_tfmode_cvt (FLOAT, operands); DONE;")
4777
4778 (define_insn "*floatditf2_hq"
4779   [(set (match_operand:TF 0 "register_operand" "=e")
4780         (float:TF (match_operand:DI 1 "register_operand" "e")))]
4781   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4782   "fxtoq\t%1, %0"
4783   [(set_attr "type" "fp")])
4784
4785 (define_expand "floatunsditf2"
4786   [(set (match_operand:TF 0 "nonimmediate_operand" "")
4787         (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
4788   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4789   "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4790
4791 ;; Convert a float to an actual integer.
4792 ;; Truncation is performed as part of the conversion.
4793
4794 (define_insn "fix_truncsfsi2"
4795   [(set (match_operand:SI 0 "register_operand" "=f")
4796         (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4797   "TARGET_FPU"
4798   "fstoi\t%1, %0"
4799   [(set_attr "type" "fp")
4800    (set_attr "fptype" "double")])
4801
4802 (define_insn "fix_truncdfsi2"
4803   [(set (match_operand:SI 0 "register_operand" "=f")
4804         (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4805   "TARGET_FPU"
4806   "fdtoi\t%1, %0"
4807   [(set_attr "type" "fp")
4808    (set_attr "fptype" "double")])
4809
4810 (define_expand "fix_trunctfsi2"
4811   [(set (match_operand:SI 0 "register_operand" "")
4812         (fix:SI (match_operand:TF 1 "general_operand" "")))]
4813   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4814   "emit_tfmode_cvt (FIX, operands); DONE;")
4815
4816 (define_insn "*fix_trunctfsi2_hq"
4817   [(set (match_operand:SI 0 "register_operand" "=f")
4818         (fix:SI (match_operand:TF 1 "register_operand" "e")))]
4819   "TARGET_FPU && TARGET_HARD_QUAD"
4820   "fqtoi\t%1, %0"
4821   [(set_attr "type" "fp")])
4822
4823 (define_expand "fixuns_trunctfsi2"
4824   [(set (match_operand:SI 0 "register_operand" "")
4825         (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
4826   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4827   "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4828
4829 ;; Now the same, for V9 targets
4830
4831 (define_insn "fix_truncsfdi2"
4832   [(set (match_operand:DI 0 "register_operand" "=e")
4833         (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4834   "TARGET_V9 && TARGET_FPU"
4835   "fstox\t%1, %0"
4836   [(set_attr "type" "fp")
4837    (set_attr "fptype" "double")])
4838
4839 (define_expand "fixuns_truncsfdi2"
4840   [(use (match_operand:DI 0 "register_operand" ""))
4841    (use (match_operand:SF 1 "general_operand" ""))]
4842   "TARGET_ARCH64 && TARGET_FPU"
4843   "sparc_emit_fixunsdi (operands, SFmode); DONE;")
4844
4845 (define_insn "fix_truncdfdi2"
4846   [(set (match_operand:DI 0 "register_operand" "=e")
4847         (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4848   "TARGET_V9 && TARGET_FPU"
4849   "fdtox\t%1, %0"
4850   [(set_attr "type" "fp")
4851    (set_attr "fptype" "double")])
4852
4853 (define_expand "fixuns_truncdfdi2"
4854   [(use (match_operand:DI 0 "register_operand" ""))
4855    (use (match_operand:DF 1 "general_operand" ""))]
4856   "TARGET_ARCH64 && TARGET_FPU"
4857   "sparc_emit_fixunsdi (operands, DFmode); DONE;")
4858
4859 (define_expand "fix_trunctfdi2"
4860   [(set (match_operand:DI 0 "register_operand" "")
4861         (fix:DI (match_operand:TF 1 "general_operand" "")))]
4862   "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4863   "emit_tfmode_cvt (FIX, operands); DONE;")
4864
4865 (define_insn "*fix_trunctfdi2_hq"
4866   [(set (match_operand:DI 0 "register_operand" "=e")
4867         (fix:DI (match_operand:TF 1 "register_operand" "e")))]
4868   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4869   "fqtox\t%1, %0"
4870   [(set_attr "type" "fp")])
4871
4872 (define_expand "fixuns_trunctfdi2"
4873   [(set (match_operand:DI 0 "register_operand" "")
4874         (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
4875   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4876   "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4877 \f
4878 ;;- arithmetic instructions
4879
4880 (define_expand "adddi3"
4881   [(set (match_operand:DI 0 "register_operand" "")
4882         (plus:DI (match_operand:DI 1 "register_operand" "")
4883                  (match_operand:DI 2 "arith_double_add_operand" "")))]
4884   ""
4885 {
4886   if (! TARGET_ARCH64)
4887     {
4888       emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4889                           gen_rtx_SET (VOIDmode, operands[0],
4890                                    gen_rtx_PLUS (DImode, operands[1],
4891                                                  operands[2])),
4892                           gen_rtx_CLOBBER (VOIDmode,
4893                                    gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4894       DONE;
4895     }
4896 })
4897
4898 (define_insn_and_split "adddi3_insn_sp32"
4899   [(set (match_operand:DI 0 "register_operand" "=r")
4900         (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4901                  (match_operand:DI 2 "arith_double_operand" "rHI")))
4902    (clobber (reg:CC 100))]
4903   "! TARGET_ARCH64"
4904   "#"
4905   "&& reload_completed"
4906   [(parallel [(set (reg:CC_NOOV 100)
4907                    (compare:CC_NOOV (plus:SI (match_dup 4)
4908                                              (match_dup 5))
4909                                     (const_int 0)))
4910               (set (match_dup 3)
4911                    (plus:SI (match_dup 4) (match_dup 5)))])
4912    (set (match_dup 6)
4913         (plus:SI (plus:SI (match_dup 7)
4914                           (match_dup 8))
4915                  (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4916 {
4917   operands[3] = gen_lowpart (SImode, operands[0]);
4918   operands[4] = gen_lowpart (SImode, operands[1]);
4919   operands[5] = gen_lowpart (SImode, operands[2]);
4920   operands[6] = gen_highpart (SImode, operands[0]);
4921   operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
4922 #if HOST_BITS_PER_WIDE_INT == 32
4923   if (GET_CODE (operands[2]) == CONST_INT)
4924     {
4925       if (INTVAL (operands[2]) < 0)
4926         operands[8] = constm1_rtx;
4927       else
4928         operands[8] = const0_rtx;
4929     }
4930   else
4931 #endif
4932     operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4933 }
4934   [(set_attr "length" "2")])
4935
4936 (define_split
4937   [(set (match_operand:DI 0 "register_operand" "")
4938         (minus:DI (match_operand:DI 1 "arith_double_operand" "")
4939                   (match_operand:DI 2 "arith_double_operand" "")))
4940    (clobber (reg:CC 100))]
4941   "! TARGET_ARCH64 && reload_completed"
4942   [(parallel [(set (reg:CC_NOOV 100)
4943                    (compare:CC_NOOV (minus:SI (match_dup 4)
4944                                               (match_dup 5))
4945                                     (const_int 0)))
4946               (set (match_dup 3)
4947                    (minus:SI (match_dup 4) (match_dup 5)))])
4948    (set (match_dup 6)
4949         (minus:SI (minus:SI (match_dup 7)
4950                             (match_dup 8))
4951                   (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4952 {
4953   operands[3] = gen_lowpart (SImode, operands[0]);
4954   operands[4] = gen_lowpart (SImode, operands[1]);
4955   operands[5] = gen_lowpart (SImode, operands[2]);
4956   operands[6] = gen_highpart (SImode, operands[0]);
4957   operands[7] = gen_highpart (SImode, operands[1]);
4958 #if HOST_BITS_PER_WIDE_INT == 32
4959   if (GET_CODE (operands[2]) == CONST_INT)
4960     {
4961       if (INTVAL (operands[2]) < 0)
4962         operands[8] = constm1_rtx;
4963       else
4964         operands[8] = const0_rtx;
4965     }
4966   else
4967 #endif
4968     operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4969 })
4970
4971 ;; LTU here means "carry set"
4972 (define_insn "addx"
4973   [(set (match_operand:SI 0 "register_operand" "=r")
4974         (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4975                           (match_operand:SI 2 "arith_operand" "rI"))
4976                  (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4977   ""
4978   "addx\t%1, %2, %0"
4979   [(set_attr "type" "ialuX")])
4980
4981 (define_insn_and_split "*addx_extend_sp32"
4982   [(set (match_operand:DI 0 "register_operand" "=r")
4983         (zero_extend:DI (plus:SI (plus:SI
4984                                   (match_operand:SI 1 "reg_or_0_operand" "%rJ")
4985                                   (match_operand:SI 2 "arith_operand" "rI"))
4986                                  (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4987   "! TARGET_ARCH64"
4988   "#"
4989   "&& reload_completed"
4990   [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
4991                                (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4992    (set (match_dup 4) (const_int 0))]
4993   "operands[3] = gen_lowpart (SImode, operands[0]);
4994    operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
4995   [(set_attr "length" "2")])
4996
4997 (define_insn "*addx_extend_sp64"
4998   [(set (match_operand:DI 0 "register_operand" "=r")
4999         (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
5000                                           (match_operand:SI 2 "arith_operand" "rI"))
5001                                  (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5002   "TARGET_ARCH64"
5003   "addx\t%r1, %2, %0"
5004   [(set_attr "type" "ialuX")])
5005
5006 (define_insn "subx"
5007   [(set (match_operand:SI 0 "register_operand" "=r")
5008         (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5009                             (match_operand:SI 2 "arith_operand" "rI"))
5010                   (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5011   ""
5012   "subx\t%r1, %2, %0"
5013   [(set_attr "type" "ialuX")])
5014
5015 (define_insn "*subx_extend_sp64"
5016   [(set (match_operand:DI 0 "register_operand" "=r")
5017         (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5018                                             (match_operand:SI 2 "arith_operand" "rI"))
5019                                   (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5020   "TARGET_ARCH64"
5021   "subx\t%r1, %2, %0"
5022   [(set_attr "type" "ialuX")])
5023
5024 (define_insn_and_split "*subx_extend"
5025   [(set (match_operand:DI 0 "register_operand" "=r")
5026         (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5027                                             (match_operand:SI 2 "arith_operand" "rI"))
5028                                   (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5029   "! TARGET_ARCH64"
5030   "#"
5031   "&& reload_completed"
5032   [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
5033                                 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
5034    (set (match_dup 4) (const_int 0))]
5035   "operands[3] = gen_lowpart (SImode, operands[0]);
5036    operands[4] = gen_highpart (SImode, operands[0]);"
5037   [(set_attr "length" "2")])
5038
5039 (define_insn_and_split ""
5040   [(set (match_operand:DI 0 "register_operand" "=r")
5041         (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5042                  (match_operand:DI 2 "register_operand" "r")))
5043    (clobber (reg:CC 100))]
5044   "! TARGET_ARCH64"
5045   "#"
5046   "&& reload_completed"
5047   [(parallel [(set (reg:CC_NOOV 100)
5048                    (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
5049                                     (const_int 0)))
5050               (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
5051    (set (match_dup 6)
5052         (plus:SI (plus:SI (match_dup 4) (const_int 0))
5053                  (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5054   "operands[3] = gen_lowpart (SImode, operands[2]);
5055    operands[4] = gen_highpart (SImode, operands[2]);
5056    operands[5] = gen_lowpart (SImode, operands[0]);
5057    operands[6] = gen_highpart (SImode, operands[0]);"
5058   [(set_attr "length" "2")])
5059
5060 (define_insn "*adddi3_sp64"
5061   [(set (match_operand:DI 0 "register_operand" "=r,r")
5062         (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
5063                  (match_operand:DI 2 "arith_double_add_operand" "rHI,O")))]
5064   "TARGET_ARCH64"
5065   "@
5066    add\t%1, %2, %0
5067    sub\t%1, -%2, %0")
5068
5069 (define_insn "addsi3"
5070   [(set (match_operand:SI 0 "register_operand" "=r,r,d")
5071         (plus:SI (match_operand:SI 1 "register_operand" "%r,r,d")
5072                  (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
5073   ""
5074   "@
5075    add\t%1, %2, %0
5076    sub\t%1, -%2, %0
5077    fpadd32s\t%1, %2, %0"
5078   [(set_attr "type" "*,*,fga")
5079    (set_attr "fptype" "*,*,single")])
5080
5081 (define_insn "*cmp_cc_plus"
5082   [(set (reg:CC_NOOV 100)
5083         (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
5084                                   (match_operand:SI 1 "arith_operand" "rI"))
5085                          (const_int 0)))]
5086   ""
5087   "addcc\t%0, %1, %%g0"
5088   [(set_attr "type" "compare")])
5089
5090 (define_insn "*cmp_ccx_plus"
5091   [(set (reg:CCX_NOOV 100)
5092         (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_double_operand" "%r")
5093                                    (match_operand:DI 1 "arith_double_operand" "rHI"))
5094                           (const_int 0)))]
5095   "TARGET_ARCH64"
5096   "addcc\t%0, %1, %%g0"
5097   [(set_attr "type" "compare")])
5098
5099 (define_insn "*cmp_cc_plus_set"
5100   [(set (reg:CC_NOOV 100)
5101         (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5102                                   (match_operand:SI 2 "arith_operand" "rI"))
5103                          (const_int 0)))
5104    (set (match_operand:SI 0 "register_operand" "=r")
5105         (plus:SI (match_dup 1) (match_dup 2)))]
5106   ""
5107   "addcc\t%1, %2, %0"
5108   [(set_attr "type" "compare")])
5109
5110 (define_insn "*cmp_ccx_plus_set"
5111   [(set (reg:CCX_NOOV 100)
5112         (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5113                                    (match_operand:DI 2 "arith_double_operand" "rHI"))
5114                           (const_int 0)))
5115    (set (match_operand:DI 0 "register_operand" "=r")
5116         (plus:DI (match_dup 1) (match_dup 2)))]
5117   "TARGET_ARCH64"
5118   "addcc\t%1, %2, %0"
5119   [(set_attr "type" "compare")])
5120
5121 (define_expand "subdi3"
5122   [(set (match_operand:DI 0 "register_operand" "")
5123         (minus:DI (match_operand:DI 1 "register_operand" "")
5124                   (match_operand:DI 2 "arith_double_add_operand" "")))]
5125   ""
5126 {
5127   if (! TARGET_ARCH64)
5128     {
5129       emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5130                           gen_rtx_SET (VOIDmode, operands[0],
5131                                    gen_rtx_MINUS (DImode, operands[1],
5132                                                   operands[2])),
5133                           gen_rtx_CLOBBER (VOIDmode,
5134                                    gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5135       DONE;
5136     }
5137 })
5138
5139 (define_insn_and_split "*subdi3_sp32"
5140   [(set (match_operand:DI 0 "register_operand" "=r")
5141         (minus:DI (match_operand:DI 1 "register_operand" "r")
5142                   (match_operand:DI 2 "arith_double_operand" "rHI")))
5143    (clobber (reg:CC 100))]
5144   "! TARGET_ARCH64"
5145   "#"
5146   "&& reload_completed
5147    && (GET_CODE (operands[2]) == CONST_INT
5148        || GET_CODE (operands[2]) == CONST_DOUBLE)"
5149   [(clobber (const_int 0))]
5150 {
5151   rtx highp, lowp;
5152
5153   highp = gen_highpart_mode (SImode, DImode, operands[2]);
5154   lowp = gen_lowpart (SImode, operands[2]);
5155   if ((lowp == const0_rtx)
5156       && (operands[0] == operands[1]))
5157     {
5158       emit_insn (gen_rtx_SET (VOIDmode,
5159                               gen_highpart (SImode, operands[0]),
5160                               gen_rtx_MINUS (SImode,
5161                                              gen_highpart_mode (SImode, DImode,
5162                                                                 operands[1]),
5163                                              highp)));
5164     }
5165   else
5166     {
5167       emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5168                                        gen_lowpart (SImode, operands[1]),
5169                                        lowp));
5170       emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5171                            gen_highpart_mode (SImode, DImode, operands[1]),
5172                            highp));
5173     }
5174   DONE;
5175 }
5176   [(set_attr "length" "2")])
5177
5178 (define_split
5179   [(set (match_operand:DI 0 "register_operand" "")
5180         (minus:DI (match_operand:DI 1 "register_operand" "")
5181                   (match_operand:DI 2 "register_operand" "")))
5182    (clobber (reg:CC 100))]
5183   "! TARGET_ARCH64
5184    && reload_completed"
5185   [(clobber (const_int 0))]
5186 {
5187   emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5188                                    gen_lowpart (SImode, operands[1]),
5189                                    gen_lowpart (SImode, operands[2])));
5190   emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5191                        gen_highpart (SImode, operands[1]),
5192                        gen_highpart (SImode, operands[2])));
5193   DONE;
5194 })
5195
5196 (define_insn_and_split ""
5197   [(set (match_operand:DI 0 "register_operand" "=r")
5198       (minus:DI (match_operand:DI 1 "register_operand" "r")
5199                 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
5200    (clobber (reg:CC 100))]
5201   "! TARGET_ARCH64"
5202   "#"
5203   "&& reload_completed"
5204   [(parallel [(set (reg:CC_NOOV 100)
5205                    (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
5206                                     (const_int 0)))
5207               (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
5208    (set (match_dup 6)
5209         (minus:SI (minus:SI (match_dup 4) (const_int 0))
5210                   (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5211   "operands[3] = gen_lowpart (SImode, operands[1]);
5212    operands[4] = gen_highpart (SImode, operands[1]);
5213    operands[5] = gen_lowpart (SImode, operands[0]);
5214    operands[6] = gen_highpart (SImode, operands[0]);"
5215   [(set_attr "length" "2")])
5216
5217 (define_insn "*subdi3_sp64"
5218   [(set (match_operand:DI 0 "register_operand" "=r,r")
5219         (minus:DI (match_operand:DI 1 "register_operand" "r,r")
5220                   (match_operand:DI 2 "arith_double_add_operand" "rHI,O")))]
5221   "TARGET_ARCH64"
5222   "@
5223    sub\t%1, %2, %0
5224    add\t%1, -%2, %0")
5225
5226 (define_insn "subsi3"
5227   [(set (match_operand:SI 0 "register_operand" "=r,r,d")
5228         (minus:SI (match_operand:SI 1 "register_operand" "r,r,d")
5229                   (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
5230   ""
5231   "@
5232    sub\t%1, %2, %0
5233    add\t%1, -%2, %0
5234    fpsub32s\t%1, %2, %0"
5235   [(set_attr "type" "*,*,fga")
5236    (set_attr "fptype" "*,*,single")])
5237
5238 (define_insn "*cmp_minus_cc"
5239   [(set (reg:CC_NOOV 100)
5240         (compare:CC_NOOV (minus:SI (match_operand:SI 0 "reg_or_0_operand" "rJ")
5241                                    (match_operand:SI 1 "arith_operand" "rI"))
5242                          (const_int 0)))]
5243   ""
5244   "subcc\t%r0, %1, %%g0"
5245   [(set_attr "type" "compare")])
5246
5247 (define_insn "*cmp_minus_ccx"
5248   [(set (reg:CCX_NOOV 100)
5249         (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
5250                                     (match_operand:DI 1 "arith_double_operand" "rHI"))
5251                           (const_int 0)))]
5252   "TARGET_ARCH64"
5253   "subcc\t%0, %1, %%g0"
5254   [(set_attr "type" "compare")])
5255
5256 (define_insn "cmp_minus_cc_set"
5257   [(set (reg:CC_NOOV 100)
5258         (compare:CC_NOOV (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5259                                    (match_operand:SI 2 "arith_operand" "rI"))
5260                          (const_int 0)))
5261    (set (match_operand:SI 0 "register_operand" "=r")
5262         (minus:SI (match_dup 1) (match_dup 2)))]
5263   ""
5264   "subcc\t%r1, %2, %0"
5265   [(set_attr "type" "compare")])
5266
5267 (define_insn "*cmp_minus_ccx_set"
5268   [(set (reg:CCX_NOOV 100)
5269         (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
5270                                     (match_operand:DI 2 "arith_double_operand" "rHI"))
5271                           (const_int 0)))
5272    (set (match_operand:DI 0 "register_operand" "=r")
5273         (minus:DI (match_dup 1) (match_dup 2)))]
5274   "TARGET_ARCH64"
5275   "subcc\t%1, %2, %0"
5276   [(set_attr "type" "compare")])
5277 \f
5278 ;; Integer Multiply/Divide.
5279
5280 ;; The 32 bit multiply/divide instructions are deprecated on v9, but at
5281 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
5282
5283 (define_insn "mulsi3"
5284   [(set (match_operand:SI 0 "register_operand" "=r")
5285         (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5286                  (match_operand:SI 2 "arith_operand" "rI")))]
5287   "TARGET_HARD_MUL"
5288   "smul\t%1, %2, %0"
5289   [(set_attr "type" "imul")])
5290
5291 (define_expand "muldi3"
5292   [(set (match_operand:DI 0 "register_operand" "=r")
5293         (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5294                  (match_operand:DI 2 "arith_double_operand" "rHI")))]
5295   "TARGET_ARCH64 || TARGET_V8PLUS"
5296 {
5297   if (TARGET_V8PLUS)
5298     {
5299       emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
5300       DONE;
5301     }
5302 })
5303
5304 (define_insn "*muldi3_sp64"
5305   [(set (match_operand:DI 0 "register_operand" "=r")
5306         (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5307                  (match_operand:DI 2 "arith_double_operand" "rHI")))]
5308   "TARGET_ARCH64"
5309   "mulx\t%1, %2, %0"
5310   [(set_attr "type" "imul")])
5311
5312 ;; V8plus wide multiply.
5313 ;; XXX
5314 (define_insn "muldi3_v8plus"
5315   [(set (match_operand:DI 0 "register_operand" "=r,h")
5316         (mult:DI (match_operand:DI 1 "arith_double_operand" "%r,0")
5317                  (match_operand:DI 2 "arith_double_operand" "rI,rI")))
5318    (clobber (match_scratch:SI 3 "=&h,X"))
5319    (clobber (match_scratch:SI 4 "=&h,X"))]
5320   "TARGET_V8PLUS"
5321 {
5322   if (sparc_check_64 (operands[1], insn) <= 0)
5323     output_asm_insn ("srl\t%L1, 0, %L1", operands);
5324   if (which_alternative == 1)
5325     output_asm_insn ("sllx\t%H1, 32, %H1", operands);
5326   if (GET_CODE (operands[2]) == CONST_INT)
5327     {
5328       if (which_alternative == 1)
5329         return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %2, %L0\;srlx\t%L0, 32, %H0";
5330       else
5331         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";
5332     }
5333   else if (rtx_equal_p (operands[1], operands[2]))
5334     {
5335       if (which_alternative == 1)
5336         return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %H1, %L0\;srlx\t%L0, 32, %H0";
5337       else
5338         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";
5339     }
5340   if (sparc_check_64 (operands[2], insn) <= 0)
5341     output_asm_insn ("srl\t%L2, 0, %L2", operands);
5342   if (which_alternative == 1)
5343     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";
5344   else
5345     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";
5346 }
5347   [(set_attr "type" "multi")
5348    (set_attr "length" "9,8")])
5349
5350 (define_insn "*cmp_mul_set"
5351   [(set (reg:CC 100)
5352         (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5353                     (match_operand:SI 2 "arith_operand" "rI"))
5354                     (const_int 0)))
5355    (set (match_operand:SI 0 "register_operand" "=r")
5356         (mult:SI (match_dup 1) (match_dup 2)))]
5357   "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
5358   "smulcc\t%1, %2, %0"
5359   [(set_attr "type" "imul")])
5360
5361 (define_expand "mulsidi3"
5362   [(set (match_operand:DI 0 "register_operand" "")
5363         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5364                  (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
5365   "TARGET_HARD_MUL"
5366 {
5367   if (CONSTANT_P (operands[2]))
5368     {
5369       if (TARGET_V8PLUS)
5370         emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
5371                                               operands[2]));
5372       else if (TARGET_ARCH32)
5373         emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
5374                                             operands[2]));
5375       else 
5376         emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
5377                                             operands[2]));
5378       DONE;
5379     }
5380   if (TARGET_V8PLUS)
5381     {
5382       emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
5383       DONE;
5384     }
5385 })
5386
5387 ;; V9 puts the 64 bit product in a 64 bit register.  Only out or global
5388 ;; registers can hold 64 bit values in the V8plus environment.
5389 ;; XXX
5390 (define_insn "mulsidi3_v8plus"
5391   [(set (match_operand:DI 0 "register_operand" "=h,r")
5392         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5393                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5394    (clobber (match_scratch:SI 3 "=X,&h"))]
5395   "TARGET_V8PLUS"
5396   "@
5397    smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5398    smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5399   [(set_attr "type" "multi")
5400    (set_attr "length" "2,3")])
5401
5402 ;; XXX
5403 (define_insn "const_mulsidi3_v8plus"
5404   [(set (match_operand:DI 0 "register_operand" "=h,r")
5405         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5406                  (match_operand:DI 2 "small_int" "I,I")))
5407    (clobber (match_scratch:SI 3 "=X,&h"))]
5408   "TARGET_V8PLUS"
5409   "@
5410    smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5411    smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5412   [(set_attr "type" "multi")
5413    (set_attr "length" "2,3")])
5414
5415 ;; XXX
5416 (define_insn "*mulsidi3_sp32"
5417   [(set (match_operand:DI 0 "register_operand" "=r")
5418         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5419                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5420   "TARGET_HARD_MUL32"
5421 {
5422   return TARGET_SPARCLET
5423          ? "smuld\t%1, %2, %L0"
5424          : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
5425 }
5426   [(set (attr "type")
5427         (if_then_else (eq_attr "isa" "sparclet")
5428                       (const_string "imul") (const_string "multi")))
5429    (set (attr "length")
5430         (if_then_else (eq_attr "isa" "sparclet")
5431                       (const_int 1) (const_int 2)))])
5432
5433 (define_insn "*mulsidi3_sp64"
5434   [(set (match_operand:DI 0 "register_operand" "=r")
5435         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5436                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5437   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5438   "smul\t%1, %2, %0"
5439   [(set_attr "type" "imul")])
5440
5441 ;; Extra pattern, because sign_extend of a constant isn't valid.
5442
5443 ;; XXX
5444 (define_insn "const_mulsidi3_sp32"
5445   [(set (match_operand:DI 0 "register_operand" "=r")
5446         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5447                  (match_operand:DI 2 "small_int" "I")))]
5448   "TARGET_HARD_MUL32"
5449 {
5450   return TARGET_SPARCLET
5451          ? "smuld\t%1, %2, %L0"
5452          : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
5453 }
5454   [(set (attr "type")
5455         (if_then_else (eq_attr "isa" "sparclet")
5456                       (const_string "imul") (const_string "multi")))
5457    (set (attr "length")
5458         (if_then_else (eq_attr "isa" "sparclet")
5459                       (const_int 1) (const_int 2)))])
5460
5461 (define_insn "const_mulsidi3_sp64"
5462   [(set (match_operand:DI 0 "register_operand" "=r")
5463         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5464                  (match_operand:DI 2 "small_int" "I")))]
5465   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5466   "smul\t%1, %2, %0"
5467   [(set_attr "type" "imul")])
5468
5469 (define_expand "smulsi3_highpart"
5470   [(set (match_operand:SI 0 "register_operand" "")
5471         (truncate:SI
5472          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5473                                (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
5474                       (const_int 32))))]
5475   "TARGET_HARD_MUL && TARGET_ARCH32"
5476 {
5477   if (CONSTANT_P (operands[2]))
5478     {
5479       if (TARGET_V8PLUS)
5480         {
5481           emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
5482                                                         operands[1],
5483                                                         operands[2],
5484                                                         GEN_INT (32)));
5485           DONE;
5486         }
5487       emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
5488       DONE;
5489     }
5490   if (TARGET_V8PLUS)
5491     {
5492       emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
5493                                               operands[2], GEN_INT (32)));
5494       DONE;
5495     }
5496 })
5497
5498 ;; XXX
5499 (define_insn "smulsi3_highpart_v8plus"
5500   [(set (match_operand:SI 0 "register_operand" "=h,r")
5501         (truncate:SI
5502          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5503                                (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5504                       (match_operand:SI 3 "const_int_operand" "i,i"))))
5505    (clobber (match_scratch:SI 4 "=X,&h"))]
5506   "TARGET_V8PLUS"
5507   "@
5508    smul\t%1, %2, %0\;srlx\t%0, %3, %0
5509    smul\t%1, %2, %4\;srlx\t%4, %3, %0"
5510   [(set_attr "type" "multi")
5511    (set_attr "length" "2")])
5512
5513 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
5514 ;; XXX
5515 (define_insn ""
5516   [(set (match_operand:SI 0 "register_operand" "=h,r")
5517         (subreg:SI
5518          (lshiftrt:DI
5519           (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5520                    (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5521           (match_operand:SI 3 "const_int_operand" "i,i"))
5522          4))
5523    (clobber (match_scratch:SI 4 "=X,&h"))]
5524   "TARGET_V8PLUS"
5525   "@
5526    smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5527    smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5528   [(set_attr "type" "multi")
5529    (set_attr "length" "2")])
5530
5531 ;; XXX
5532 (define_insn "const_smulsi3_highpart_v8plus"
5533   [(set (match_operand:SI 0 "register_operand" "=h,r")
5534         (truncate:SI
5535          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5536                                (match_operand:DI 2 "small_int" "i,i"))
5537                       (match_operand:SI 3 "const_int_operand" "i,i"))))
5538    (clobber (match_scratch:SI 4 "=X,&h"))]
5539   "TARGET_V8PLUS"
5540   "@
5541    smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5542    smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5543   [(set_attr "type" "multi")
5544    (set_attr "length" "2")])
5545
5546 ;; XXX
5547 (define_insn "*smulsi3_highpart_sp32"
5548   [(set (match_operand:SI 0 "register_operand" "=r")
5549         (truncate:SI
5550          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5551                                (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
5552                       (const_int 32))))]
5553   "TARGET_HARD_MUL32"
5554   "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
5555   [(set_attr "type" "multi")
5556    (set_attr "length" "2")])
5557
5558 ;; XXX
5559 (define_insn "const_smulsi3_highpart"
5560   [(set (match_operand:SI 0 "register_operand" "=r")
5561         (truncate:SI
5562          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5563                                (match_operand:DI 2 "small_int" "i"))
5564                       (const_int 32))))]
5565   "TARGET_HARD_MUL32"
5566   "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
5567   [(set_attr "type" "multi")
5568    (set_attr "length" "2")])
5569
5570 (define_expand "umulsidi3"
5571   [(set (match_operand:DI 0 "register_operand" "")
5572         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5573                  (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
5574   "TARGET_HARD_MUL"
5575 {
5576   if (CONSTANT_P (operands[2]))
5577     {
5578       if (TARGET_V8PLUS)
5579         emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
5580                                                operands[2]));
5581       else if (TARGET_ARCH32)
5582         emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
5583                                              operands[2]));
5584       else 
5585         emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
5586                                              operands[2]));
5587       DONE;
5588     }
5589   if (TARGET_V8PLUS)
5590     {
5591       emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
5592       DONE;
5593     }
5594 })
5595
5596 ;; XXX
5597 (define_insn "umulsidi3_v8plus"
5598   [(set (match_operand:DI 0 "register_operand" "=h,r")
5599         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5600                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5601    (clobber (match_scratch:SI 3 "=X,&h"))]
5602   "TARGET_V8PLUS"
5603   "@
5604    umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5605    umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5606   [(set_attr "type" "multi")
5607    (set_attr "length" "2,3")])
5608
5609 ;; XXX
5610 (define_insn "*umulsidi3_sp32"
5611   [(set (match_operand:DI 0 "register_operand" "=r")
5612         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5613                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5614   "TARGET_HARD_MUL32"
5615 {
5616   return TARGET_SPARCLET
5617          ? "umuld\t%1, %2, %L0"
5618          : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
5619 }
5620   [(set (attr "type")
5621         (if_then_else (eq_attr "isa" "sparclet")
5622                       (const_string "imul") (const_string "multi")))
5623    (set (attr "length")
5624         (if_then_else (eq_attr "isa" "sparclet")
5625                       (const_int 1) (const_int 2)))])
5626
5627 (define_insn "*umulsidi3_sp64"
5628   [(set (match_operand:DI 0 "register_operand" "=r")
5629         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5630                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5631   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5632   "umul\t%1, %2, %0"
5633   [(set_attr "type" "imul")])
5634
5635 ;; Extra pattern, because sign_extend of a constant isn't valid.
5636
5637 ;; XXX
5638 (define_insn "const_umulsidi3_sp32"
5639   [(set (match_operand:DI 0 "register_operand" "=r")
5640         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5641                  (match_operand:DI 2 "uns_small_int" "")))]
5642   "TARGET_HARD_MUL32"
5643 {
5644   return TARGET_SPARCLET
5645          ? "umuld\t%1, %s2, %L0"
5646          : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
5647 }
5648   [(set (attr "type")
5649         (if_then_else (eq_attr "isa" "sparclet")
5650                       (const_string "imul") (const_string "multi")))
5651    (set (attr "length")
5652         (if_then_else (eq_attr "isa" "sparclet")
5653                       (const_int 1) (const_int 2)))])
5654
5655 (define_insn "const_umulsidi3_sp64"
5656   [(set (match_operand:DI 0 "register_operand" "=r")
5657         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5658                  (match_operand:DI 2 "uns_small_int" "")))]
5659   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5660   "umul\t%1, %s2, %0"
5661   [(set_attr "type" "imul")])
5662
5663 ;; XXX
5664 (define_insn "const_umulsidi3_v8plus"
5665   [(set (match_operand:DI 0 "register_operand" "=h,r")
5666         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5667                  (match_operand:DI 2 "uns_small_int" "")))
5668    (clobber (match_scratch:SI 3 "=X,h"))]
5669   "TARGET_V8PLUS"
5670   "@
5671    umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
5672    umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5673   [(set_attr "type" "multi")
5674    (set_attr "length" "2,3")])
5675
5676 (define_expand "umulsi3_highpart"
5677   [(set (match_operand:SI 0 "register_operand" "")
5678         (truncate:SI
5679          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5680                                (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
5681                       (const_int 32))))]
5682   "TARGET_HARD_MUL && TARGET_ARCH32"
5683 {
5684   if (CONSTANT_P (operands[2]))
5685     {
5686       if (TARGET_V8PLUS)
5687         {
5688           emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
5689                                                         operands[1],
5690                                                         operands[2],
5691                                                         GEN_INT (32)));
5692           DONE;
5693         }
5694       emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
5695       DONE;
5696     }
5697   if (TARGET_V8PLUS)
5698     {
5699       emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
5700                                               operands[2], GEN_INT (32)));
5701       DONE;
5702     }
5703 })
5704
5705 ;; XXX
5706 (define_insn "umulsi3_highpart_v8plus"
5707   [(set (match_operand:SI 0 "register_operand" "=h,r")
5708         (truncate:SI
5709          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5710                                (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5711                       (match_operand:SI 3 "const_int_operand" "i,i"))))
5712    (clobber (match_scratch:SI 4 "=X,h"))]
5713   "TARGET_V8PLUS"
5714   "@
5715    umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5716    umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5717   [(set_attr "type" "multi")
5718    (set_attr "length" "2")])
5719
5720 ;; XXX
5721 (define_insn "const_umulsi3_highpart_v8plus"
5722   [(set (match_operand:SI 0 "register_operand" "=h,r")
5723         (truncate:SI
5724          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5725                                (match_operand:DI 2 "uns_small_int" ""))
5726                       (match_operand:SI 3 "const_int_operand" "i,i"))))
5727    (clobber (match_scratch:SI 4 "=X,h"))]
5728   "TARGET_V8PLUS"
5729   "@
5730    umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
5731    umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
5732   [(set_attr "type" "multi")
5733    (set_attr "length" "2")])
5734
5735 ;; XXX
5736 (define_insn "*umulsi3_highpart_sp32"
5737   [(set (match_operand:SI 0 "register_operand" "=r")
5738         (truncate:SI
5739          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5740                                (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
5741                       (const_int 32))))]
5742   "TARGET_HARD_MUL32"
5743   "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
5744   [(set_attr "type" "multi")
5745    (set_attr "length" "2")])
5746
5747 ;; XXX
5748 (define_insn "const_umulsi3_highpart"
5749   [(set (match_operand:SI 0 "register_operand" "=r")
5750         (truncate:SI
5751          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5752                                (match_operand:DI 2 "uns_small_int" ""))
5753                       (const_int 32))))]
5754   "TARGET_HARD_MUL32"
5755   "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
5756   [(set_attr "type" "multi")
5757    (set_attr "length" "2")])
5758
5759 ;; The v8 architecture specifies that there must be 3 instructions between
5760 ;; a y register write and a use of it for correct results.
5761
5762 (define_expand "divsi3"
5763   [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
5764                    (div:SI (match_operand:SI 1 "register_operand" "r,r")
5765                            (match_operand:SI 2 "input_operand" "rI,m")))
5766               (clobber (match_scratch:SI 3 "=&r,&r"))])]
5767   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5768 {
5769   if (TARGET_ARCH64)
5770     {
5771       operands[3] = gen_reg_rtx(SImode);
5772       emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
5773       emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
5774                                   operands[3]));
5775       DONE;
5776     }
5777 })
5778
5779 (define_insn "divsi3_sp32"
5780   [(set (match_operand:SI 0 "register_operand" "=r,r")
5781         (div:SI (match_operand:SI 1 "register_operand" "r,r")
5782                 (match_operand:SI 2 "input_operand" "rI,m")))
5783    (clobber (match_scratch:SI 3 "=&r,&r"))]
5784   "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
5785    && TARGET_ARCH32"
5786 {
5787   if (which_alternative == 0)
5788     if (TARGET_V9)
5789       return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdiv\t%1, %2, %0";
5790     else
5791       return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
5792   else
5793     if (TARGET_V9)
5794       return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tld\t%2, %3\n\tsdiv\t%1, %3, %0";
5795     else
5796       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";
5797 }
5798   [(set_attr "type" "multi")
5799    (set (attr "length")
5800         (if_then_else (eq_attr "isa" "v9")
5801                       (const_int 4) (const_int 6)))])
5802
5803 (define_insn "divsi3_sp64"
5804   [(set (match_operand:SI 0 "register_operand" "=r")
5805         (div:SI (match_operand:SI 1 "register_operand" "r")
5806                 (match_operand:SI 2 "input_operand" "rI")))
5807    (use (match_operand:SI 3 "register_operand" "r"))]
5808   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5809   "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
5810   [(set_attr "type" "multi")
5811    (set_attr "length" "2")])
5812
5813 (define_insn "divdi3"
5814   [(set (match_operand:DI 0 "register_operand" "=r")
5815         (div:DI (match_operand:DI 1 "register_operand" "r")
5816                 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5817   "TARGET_ARCH64"
5818   "sdivx\t%1, %2, %0"
5819   [(set_attr "type" "idiv")])
5820
5821 (define_insn "*cmp_sdiv_cc_set"
5822   [(set (reg:CC 100)
5823         (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
5824                             (match_operand:SI 2 "arith_operand" "rI"))
5825                     (const_int 0)))
5826    (set (match_operand:SI 0 "register_operand" "=r")
5827         (div:SI (match_dup 1) (match_dup 2)))
5828    (clobber (match_scratch:SI 3 "=&r"))]
5829   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5830 {
5831   if (TARGET_V9)
5832     return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdivcc\t%1, %2, %0";
5833   else
5834     return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
5835 }
5836   [(set_attr "type" "multi")
5837    (set (attr "length")
5838         (if_then_else (eq_attr "isa" "v9")
5839                       (const_int 3) (const_int 6)))])
5840
5841 ;; XXX
5842 (define_expand "udivsi3"
5843   [(set (match_operand:SI 0 "register_operand" "")
5844         (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "")
5845                  (match_operand:SI 2 "input_operand" "")))]
5846   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5847   "")
5848
5849 (define_insn "udivsi3_sp32"
5850   [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
5851         (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r,r,m")
5852                  (match_operand:SI 2 "input_operand" "rI,m,r")))]
5853   "(TARGET_V8
5854     || TARGET_DEPRECATED_V8_INSNS)
5855    && TARGET_ARCH32"
5856 {
5857   output_asm_insn ("wr\t%%g0, %%g0, %%y", operands);
5858   switch (which_alternative)
5859     {
5860     default:
5861       return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
5862     case 1:
5863       return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
5864     case 2:
5865       return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
5866     }
5867 }
5868   [(set_attr "type" "multi")
5869    (set_attr "length" "5")])
5870
5871 (define_insn "udivsi3_sp64"
5872   [(set (match_operand:SI 0 "register_operand" "=r")
5873         (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r")
5874                  (match_operand:SI 2 "input_operand" "rI")))]
5875   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5876   "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
5877   [(set_attr "type" "multi")
5878    (set_attr "length" "2")])
5879
5880 (define_insn "udivdi3"
5881   [(set (match_operand:DI 0 "register_operand" "=r")
5882         (udiv:DI (match_operand:DI 1 "register_operand" "r")
5883                  (match_operand:DI 2 "arith_double_operand" "rHI")))]
5884   "TARGET_ARCH64"
5885   "udivx\t%1, %2, %0"
5886   [(set_attr "type" "idiv")])
5887
5888 (define_insn "*cmp_udiv_cc_set"
5889   [(set (reg:CC 100)
5890         (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
5891                              (match_operand:SI 2 "arith_operand" "rI"))
5892                     (const_int 0)))
5893    (set (match_operand:SI 0 "register_operand" "=r")
5894         (udiv:SI (match_dup 1) (match_dup 2)))]
5895   "TARGET_V8
5896    || TARGET_DEPRECATED_V8_INSNS"
5897 {
5898   if (TARGET_V9)
5899     return "wr\t%%g0, %%g0, %%y\n\tudivcc\t%1, %2, %0";
5900   else
5901     return "wr\t%%g0, %%g0, %%y\n\tnop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
5902 }
5903   [(set_attr "type" "multi")
5904    (set (attr "length")
5905         (if_then_else (eq_attr "isa" "v9")
5906                       (const_int 2) (const_int 5)))])
5907
5908 ; sparclet multiply/accumulate insns
5909
5910 (define_insn "*smacsi"
5911   [(set (match_operand:SI 0 "register_operand" "=r")
5912         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
5913                           (match_operand:SI 2 "arith_operand" "rI"))
5914                  (match_operand:SI 3 "register_operand" "0")))]
5915   "TARGET_SPARCLET"
5916   "smac\t%1, %2, %0"
5917   [(set_attr "type" "imul")])
5918
5919 (define_insn "*smacdi"
5920   [(set (match_operand:DI 0 "register_operand" "=r")
5921         (plus:DI (mult:DI (sign_extend:DI
5922                            (match_operand:SI 1 "register_operand" "%r"))
5923                           (sign_extend:DI
5924                            (match_operand:SI 2 "register_operand" "r")))
5925                  (match_operand:DI 3 "register_operand" "0")))]
5926   "TARGET_SPARCLET"
5927   "smacd\t%1, %2, %L0"
5928   [(set_attr "type" "imul")])
5929
5930 (define_insn "*umacdi"
5931   [(set (match_operand:DI 0 "register_operand" "=r")
5932         (plus:DI (mult:DI (zero_extend:DI
5933                            (match_operand:SI 1 "register_operand" "%r"))
5934                           (zero_extend:DI
5935                            (match_operand:SI 2 "register_operand" "r")))
5936                  (match_operand:DI 3 "register_operand" "0")))]
5937   "TARGET_SPARCLET"
5938   "umacd\t%1, %2, %L0"
5939   [(set_attr "type" "imul")])
5940 \f
5941 ;;- Boolean instructions
5942 ;; We define DImode `and' so with DImode `not' we can get
5943 ;; DImode `andn'.  Other combinations are possible.
5944
5945 (define_mode_macro V64I [DI V2SI V4HI V8QI])
5946 (define_mode_macro V32I [SI V2HI V4QI])
5947
5948 (define_expand "and<V64I:mode>3"
5949   [(set (match_operand:V64I 0 "register_operand" "")
5950         (and:V64I (match_operand:V64I 1 "arith_double_operand" "")
5951                   (match_operand:V64I 2 "arith_double_operand" "")))]
5952   ""
5953   "")
5954
5955 (define_insn "*and<V64I:mode>3_sp32"
5956   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5957         (and:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5958                   (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5959   "! TARGET_ARCH64"
5960   "@
5961   #
5962   fand\t%1, %2, %0"
5963   [(set_attr "type" "*,fga")
5964    (set_attr "length" "2,*")
5965    (set_attr "fptype" "*,double")])
5966
5967 (define_insn "*and<V64I:mode>3_sp64"
5968   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5969         (and:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5970                   (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5971   "TARGET_ARCH64"
5972   "@
5973    and\t%1, %2, %0
5974    fand\t%1, %2, %0"
5975   [(set_attr "type" "*,fga")
5976    (set_attr "fptype" "*,double")])
5977
5978 (define_insn "and<V32I:mode>3"
5979   [(set (match_operand:V32I 0 "register_operand" "=r,d")
5980         (and:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
5981                 (match_operand:V32I 2 "arith_operand" "rI,d")))]
5982   ""
5983   "@
5984    and\t%1, %2, %0
5985    fands\t%1, %2, %0"
5986   [(set_attr "type" "*,fga")
5987    (set_attr "fptype" "*,single")])
5988
5989 (define_split
5990   [(set (match_operand:SI 0 "register_operand" "")
5991         (and:SI (match_operand:SI 1 "register_operand" "")
5992                 (match_operand:SI 2 "" "")))
5993    (clobber (match_operand:SI 3 "register_operand" ""))]
5994   "GET_CODE (operands[2]) == CONST_INT
5995    && !SMALL_INT32 (operands[2])
5996    && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
5997   [(set (match_dup 3) (match_dup 4))
5998    (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
5999 {
6000   operands[4] = GEN_INT (~INTVAL (operands[2]));
6001 })
6002
6003 (define_insn_and_split "*and_not_<V64I:mode>_sp32"
6004   [(set (match_operand:V64I 0 "register_operand" "=r,b")
6005         (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
6006                   (match_operand:V64I 2 "register_operand" "r,b")))]
6007   "! TARGET_ARCH64"
6008   "@
6009    #
6010    fandnot1\t%1, %2, %0"
6011   "&& reload_completed
6012    && ((GET_CODE (operands[0]) == REG
6013         && REGNO (operands[0]) < 32)
6014        || (GET_CODE (operands[0]) == SUBREG
6015            && GET_CODE (SUBREG_REG (operands[0])) == REG
6016            && REGNO (SUBREG_REG (operands[0])) < 32))"
6017   [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
6018    (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
6019   "operands[3] = gen_highpart (SImode, operands[0]);
6020    operands[4] = gen_highpart (SImode, operands[1]);
6021    operands[5] = gen_highpart (SImode, operands[2]);
6022    operands[6] = gen_lowpart (SImode, operands[0]);
6023    operands[7] = gen_lowpart (SImode, operands[1]);
6024    operands[8] = gen_lowpart (SImode, operands[2]);"
6025   [(set_attr "type" "*,fga")
6026    (set_attr "length" "2,*")
6027    (set_attr "fptype" "*,double")])
6028
6029 (define_insn "*and_not_<V64I:mode>_sp64"
6030   [(set (match_operand:V64I 0 "register_operand" "=r,b")
6031         (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
6032                   (match_operand:V64I 2 "register_operand" "r,b")))]
6033   "TARGET_ARCH64"
6034   "@
6035    andn\t%2, %1, %0
6036    fandnot1\t%1, %2, %0"
6037   [(set_attr "type" "*,fga")
6038    (set_attr "fptype" "*,double")])
6039
6040 (define_insn "*and_not_<V32I:mode>"
6041   [(set (match_operand:V32I 0 "register_operand" "=r,d")
6042         (and:V32I (not:V32I (match_operand:V32I 1 "register_operand" "%r,d"))
6043                   (match_operand:V32I 2 "register_operand" "r,d")))]
6044   ""
6045   "@
6046    andn\t%2, %1, %0
6047    fandnot1s\t%1, %2, %0"
6048   [(set_attr "type" "*,fga")
6049    (set_attr "fptype" "*,single")])
6050
6051 (define_expand "ior<V64I:mode>3"
6052   [(set (match_operand:V64I 0 "register_operand" "")
6053         (ior:V64I (match_operand:V64I 1 "arith_double_operand" "")
6054                   (match_operand:V64I 2 "arith_double_operand" "")))]
6055   ""
6056   "")
6057
6058 (define_insn "*ior<V64I:mode>3_sp32"
6059   [(set (match_operand:V64I 0 "register_operand" "=r,b")
6060         (ior:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
6061                   (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
6062   "! TARGET_ARCH64"
6063   "@
6064   #
6065   for\t%1, %2, %0"
6066   [(set_attr "type" "*,fga")
6067    (set_attr "length" "2,*")
6068    (set_attr "fptype" "*,double")])
6069
6070 (define_insn "*ior<V64I:mode>3_sp64"
6071   [(set (match_operand:V64I 0 "register_operand" "=r,b")
6072         (ior:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
6073                   (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
6074   "TARGET_ARCH64"
6075   "@
6076   or\t%1, %2, %0
6077   for\t%1, %2, %0"
6078   [(set_attr "type" "*,fga")
6079    (set_attr "fptype" "*,double")])
6080
6081 (define_insn "ior<V32I:mode>3"
6082   [(set (match_operand:V32I 0 "register_operand" "=r,d")
6083         (ior:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
6084                   (match_operand:V32I 2 "arith_operand" "rI,d")))]
6085   ""
6086   "@
6087    or\t%1, %2, %0
6088    fors\t%1, %2, %0"
6089   [(set_attr "type" "*,fga")
6090    (set_attr "fptype" "*,single")])
6091
6092 (define_split
6093   [(set (match_operand:SI 0 "register_operand" "")
6094         (ior:SI (match_operand:SI 1 "register_operand" "")
6095                 (match_operand:SI 2 "" "")))
6096    (clobber (match_operand:SI 3 "register_operand" ""))]
6097   "GET_CODE (operands[2]) == CONST_INT
6098    && !SMALL_INT32 (operands[2])
6099    && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6100   [(set (match_dup 3) (match_dup 4))
6101    (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
6102 {
6103   operands[4] = GEN_INT (~INTVAL (operands[2]));
6104 })
6105
6106 (define_insn_and_split "*or_not_<V64I:mode>_sp32"
6107   [(set (match_operand:V64I 0 "register_operand" "=r,b")
6108         (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
6109                   (match_operand:V64I 2 "register_operand" "r,b")))]
6110   "! TARGET_ARCH64"
6111   "@
6112    #
6113    fornot1\t%1, %2, %0"
6114   "&& reload_completed
6115    && ((GET_CODE (operands[0]) == REG
6116         && REGNO (operands[0]) < 32)
6117        || (GET_CODE (operands[0]) == SUBREG
6118            && GET_CODE (SUBREG_REG (operands[0])) == REG
6119            && REGNO (SUBREG_REG (operands[0])) < 32))"
6120   [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
6121    (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
6122   "operands[3] = gen_highpart (SImode, operands[0]);
6123    operands[4] = gen_highpart (SImode, operands[1]);
6124    operands[5] = gen_highpart (SImode, operands[2]);
6125    operands[6] = gen_lowpart (SImode, operands[0]);
6126    operands[7] = gen_lowpart (SImode, operands[1]);
6127    operands[8] = gen_lowpart (SImode, operands[2]);"
6128   [(set_attr "type" "*,fga")
6129    (set_attr "length" "2,*")
6130    (set_attr "fptype" "*,double")])
6131
6132 (define_insn "*or_not_<V64I:mode>_sp64"
6133   [(set (match_operand:V64I 0 "register_operand" "=r,b")
6134         (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
6135                   (match_operand:V64I 2 "register_operand" "r,b")))]
6136   "TARGET_ARCH64"
6137   "@
6138   orn\t%2, %1, %0
6139   fornot1\t%1, %2, %0"
6140   [(set_attr "type" "*,fga")
6141    (set_attr "fptype" "*,double")])
6142
6143 (define_insn "*or_not_<V32I:mode>"
6144   [(set (match_operand:V32I 0 "register_operand" "=r,d")
6145         (ior:V32I (not:V32I (match_operand:V32I 1 "register_operand" "r,d"))
6146                   (match_operand:V32I 2 "register_operand" "r,d")))]
6147   ""
6148   "@
6149    orn\t%2, %1, %0
6150    fornot1s\t%1, %2, %0"
6151   [(set_attr "type" "*,fga")
6152    (set_attr "fptype" "*,single")])
6153
6154 (define_expand "xor<V64I:mode>3"
6155   [(set (match_operand:V64I 0 "register_operand" "")
6156         (xor:V64I (match_operand:V64I 1 "arith_double_operand" "")
6157                   (match_operand:V64I 2 "arith_double_operand" "")))]
6158   ""
6159   "")
6160
6161 (define_insn "*xor<V64I:mode>3_sp32"
6162   [(set (match_operand:V64I 0 "register_operand" "=r,b")
6163         (xor:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
6164                   (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
6165   "! TARGET_ARCH64"
6166   "@
6167   #
6168   fxor\t%1, %2, %0"
6169   [(set_attr "type" "*,fga")
6170    (set_attr "length" "2,*")
6171    (set_attr "fptype" "*,double")])
6172
6173 (define_insn "*xor<V64I:mode>3_sp64"
6174   [(set (match_operand:V64I 0 "register_operand" "=r,b")
6175         (xor:V64I (match_operand:V64I 1 "arith_double_operand" "%rJ,b")
6176                   (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
6177   "TARGET_ARCH64"
6178   "@
6179   xor\t%r1, %2, %0
6180   fxor\t%1, %2, %0"
6181   [(set_attr "type" "*,fga")
6182    (set_attr "fptype" "*,double")])
6183
6184 (define_insn "*xordi3_sp64_dbl"
6185   [(set (match_operand:DI 0 "register_operand" "=r")
6186         (xor:DI (match_operand:DI 1 "register_operand" "r")
6187                 (match_operand:DI 2 "const64_operand" "")))]
6188   "(TARGET_ARCH64
6189     && HOST_BITS_PER_WIDE_INT != 64)"
6190   "xor\t%1, %2, %0")
6191
6192 (define_insn "xor<V32I:mode>3"
6193   [(set (match_operand:V32I 0 "register_operand" "=r,d")
6194         (xor:V32I (match_operand:V32I 1 "arith_operand" "%rJ,d")
6195                   (match_operand:V32I 2 "arith_operand" "rI,d")))]
6196   ""
6197   "@
6198    xor\t%r1, %2, %0
6199    fxors\t%1, %2, %0"
6200   [(set_attr "type" "*,fga")
6201    (set_attr "fptype" "*,single")])
6202
6203 (define_split
6204   [(set (match_operand:SI 0 "register_operand" "")
6205         (xor:SI (match_operand:SI 1 "register_operand" "")
6206                 (match_operand:SI 2 "" "")))
6207    (clobber (match_operand:SI 3 "register_operand" ""))]
6208   "GET_CODE (operands[2]) == CONST_INT
6209    && !SMALL_INT32 (operands[2])
6210    && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6211   [(set (match_dup 3) (match_dup 4))
6212    (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
6213 {
6214   operands[4] = GEN_INT (~INTVAL (operands[2]));
6215 })
6216
6217 (define_split
6218   [(set (match_operand:SI 0 "register_operand" "")
6219         (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
6220                         (match_operand:SI 2 "" ""))))
6221    (clobber (match_operand:SI 3 "register_operand" ""))]
6222   "GET_CODE (operands[2]) == CONST_INT
6223    && !SMALL_INT32 (operands[2])
6224    && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6225   [(set (match_dup 3) (match_dup 4))
6226    (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
6227 {
6228   operands[4] = GEN_INT (~INTVAL (operands[2]));
6229 })
6230
6231 ;; Split DImode logical operations requiring two instructions.
6232 (define_split
6233   [(set (match_operand:V64I 0 "register_operand" "")
6234         (match_operator:V64I 1 "cc_arithop"     ; AND, IOR, XOR
6235                            [(match_operand:V64I 2 "register_operand" "")
6236                             (match_operand:V64I 3 "arith_double_operand" "")]))]
6237   "! TARGET_ARCH64
6238    && reload_completed
6239    && ((GET_CODE (operands[0]) == REG
6240         && REGNO (operands[0]) < 32)
6241        || (GET_CODE (operands[0]) == SUBREG
6242            && GET_CODE (SUBREG_REG (operands[0])) == REG
6243            && REGNO (SUBREG_REG (operands[0])) < 32))"
6244   [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
6245    (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
6246 {
6247   operands[4] = gen_highpart (SImode, operands[0]);
6248   operands[5] = gen_lowpart (SImode, operands[0]);
6249   operands[6] = gen_highpart (SImode, operands[2]);
6250   operands[7] = gen_lowpart (SImode, operands[2]);
6251 #if HOST_BITS_PER_WIDE_INT == 32
6252   if (GET_CODE (operands[3]) == CONST_INT && <V64I:MODE>mode == DImode)
6253     {
6254       if (INTVAL (operands[3]) < 0)
6255         operands[8] = constm1_rtx;
6256       else
6257         operands[8] = const0_rtx;
6258     }
6259   else
6260 #endif
6261     operands[8] = gen_highpart_mode (SImode, <V64I:MODE>mode, operands[3]);
6262   operands[9] = gen_lowpart (SImode, operands[3]);
6263 })
6264
6265 ;; xnor patterns.  Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
6266 ;; Combine now canonicalizes to the rightmost expression.
6267 (define_insn_and_split "*xor_not_<V64I:mode>_sp32"
6268   [(set (match_operand:V64I 0 "register_operand" "=r,b")
6269         (not:V64I (xor:V64I (match_operand:V64I 1 "register_operand" "r,b")
6270                             (match_operand:V64I 2 "register_operand" "r,b"))))]
6271   "! TARGET_ARCH64"
6272   "@
6273    #
6274    fxnor\t%1, %2, %0"
6275   "&& reload_completed
6276    && ((GET_CODE (operands[0]) == REG
6277         && REGNO (operands[0]) < 32)
6278        || (GET_CODE (operands[0]) == SUBREG
6279            && GET_CODE (SUBREG_REG (operands[0])) == REG
6280            && REGNO (SUBREG_REG (operands[0])) < 32))"
6281   [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
6282    (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
6283   "operands[3] = gen_highpart (SImode, operands[0]);
6284    operands[4] = gen_highpart (SImode, operands[1]);
6285    operands[5] = gen_highpart (SImode, operands[2]);
6286    operands[6] = gen_lowpart (SImode, operands[0]);
6287    operands[7] = gen_lowpart (SImode, operands[1]);
6288    operands[8] = gen_lowpart (SImode, operands[2]);"
6289   [(set_attr "type" "*,fga")
6290    (set_attr "length" "2,*")
6291    (set_attr "fptype" "*,double")])
6292
6293 (define_insn "*xor_not_<V64I:mode>_sp64"
6294   [(set (match_operand:V64I 0 "register_operand" "=r,b")
6295         (not:V64I (xor:V64I (match_operand:V64I 1 "reg_or_0_operand" "rJ,b")
6296                             (match_operand:V64I 2 "arith_double_operand" "rHI,b"))))]
6297   "TARGET_ARCH64"
6298   "@
6299   xnor\t%r1, %2, %0
6300   fxnor\t%1, %2, %0"
6301   [(set_attr "type" "*,fga")
6302    (set_attr "fptype" "*,double")])
6303
6304 (define_insn "*xor_not_<V32I:mode>"
6305   [(set (match_operand:V32I 0 "register_operand" "=r,d")
6306         (not:V32I (xor:V32I (match_operand:V32I 1 "reg_or_0_operand" "rJ,d")
6307                             (match_operand:V32I 2 "arith_operand" "rI,d"))))]
6308   ""
6309   "@
6310    xnor\t%r1, %2, %0
6311    fxnors\t%1, %2, %0"
6312   [(set_attr "type" "*,fga")
6313    (set_attr "fptype" "*,single")])
6314
6315 ;; These correspond to the above in the case where we also (or only)
6316 ;; want to set the condition code.  
6317
6318 (define_insn "*cmp_cc_arith_op"
6319   [(set (reg:CC 100)
6320         (compare:CC
6321          (match_operator:SI 2 "cc_arithop"
6322                             [(match_operand:SI 0 "arith_operand" "%r")
6323                              (match_operand:SI 1 "arith_operand" "rI")])
6324          (const_int 0)))]
6325   ""
6326   "%A2cc\t%0, %1, %%g0"
6327   [(set_attr "type" "compare")])
6328
6329 (define_insn "*cmp_ccx_arith_op"
6330   [(set (reg:CCX 100)
6331         (compare:CCX
6332          (match_operator:DI 2 "cc_arithop"
6333                             [(match_operand:DI 0 "arith_double_operand" "%r")
6334                              (match_operand:DI 1 "arith_double_operand" "rHI")])
6335          (const_int 0)))]
6336   "TARGET_ARCH64"
6337   "%A2cc\t%0, %1, %%g0"
6338   [(set_attr "type" "compare")])
6339
6340 (define_insn "*cmp_cc_arith_op_set"
6341   [(set (reg:CC 100)
6342         (compare:CC
6343          (match_operator:SI 3 "cc_arithop"
6344                             [(match_operand:SI 1 "arith_operand" "%r")
6345                              (match_operand:SI 2 "arith_operand" "rI")])
6346          (const_int 0)))
6347    (set (match_operand:SI 0 "register_operand" "=r")
6348         (match_operator:SI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6349   "GET_CODE (operands[3]) == GET_CODE (operands[4])"
6350   "%A3cc\t%1, %2, %0"
6351   [(set_attr "type" "compare")])
6352
6353 (define_insn "*cmp_ccx_arith_op_set"
6354   [(set (reg:CCX 100)
6355         (compare:CCX
6356          (match_operator:DI 3 "cc_arithop"
6357                             [(match_operand:DI 1 "arith_double_operand" "%r")
6358                              (match_operand:DI 2 "arith_double_operand" "rHI")])
6359          (const_int 0)))
6360    (set (match_operand:DI 0 "register_operand" "=r")
6361         (match_operator:DI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6362   "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
6363   "%A3cc\t%1, %2, %0"
6364   [(set_attr "type" "compare")])
6365
6366 (define_insn "*cmp_cc_xor_not"
6367   [(set (reg:CC 100)
6368         (compare:CC
6369          (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
6370                          (match_operand:SI 1 "arith_operand" "rI")))
6371          (const_int 0)))]
6372   ""
6373   "xnorcc\t%r0, %1, %%g0"
6374   [(set_attr "type" "compare")])
6375
6376 (define_insn "*cmp_ccx_xor_not"
6377   [(set (reg:CCX 100)
6378         (compare:CCX
6379          (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ")
6380                          (match_operand:DI 1 "arith_double_operand" "rHI")))
6381          (const_int 0)))]
6382   "TARGET_ARCH64"
6383   "xnorcc\t%r0, %1, %%g0"
6384   [(set_attr "type" "compare")])
6385
6386 (define_insn "*cmp_cc_xor_not_set"
6387   [(set (reg:CC 100)
6388         (compare:CC
6389          (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
6390                          (match_operand:SI 2 "arith_operand" "rI")))
6391          (const_int 0)))
6392    (set (match_operand:SI 0 "register_operand" "=r")
6393         (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
6394   ""
6395   "xnorcc\t%r1, %2, %0"
6396   [(set_attr "type" "compare")])
6397
6398 (define_insn "*cmp_ccx_xor_not_set"
6399   [(set (reg:CCX 100)
6400         (compare:CCX
6401          (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
6402                          (match_operand:DI 2 "arith_double_operand" "rHI")))
6403          (const_int 0)))
6404    (set (match_operand:DI 0 "register_operand" "=r")
6405         (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
6406   "TARGET_ARCH64"
6407   "xnorcc\t%r1, %2, %0"
6408   [(set_attr "type" "compare")])
6409
6410 (define_insn "*cmp_cc_arith_op_not"
6411   [(set (reg:CC 100)
6412         (compare:CC
6413          (match_operator:SI 2 "cc_arithopn"
6414                             [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
6415                              (match_operand:SI 1 "reg_or_0_operand" "rJ")])
6416          (const_int 0)))]
6417   ""
6418   "%B2cc\t%r1, %0, %%g0"
6419   [(set_attr "type" "compare")])
6420
6421 (define_insn "*cmp_ccx_arith_op_not"
6422   [(set (reg:CCX 100)
6423         (compare:CCX
6424          (match_operator:DI 2 "cc_arithopn"
6425                             [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6426                              (match_operand:DI 1 "reg_or_0_operand" "rJ")])
6427          (const_int 0)))]
6428   "TARGET_ARCH64"
6429   "%B2cc\t%r1, %0, %%g0"
6430   [(set_attr "type" "compare")])
6431
6432 (define_insn "*cmp_cc_arith_op_not_set"
6433   [(set (reg:CC 100)
6434         (compare:CC
6435          (match_operator:SI 3 "cc_arithopn"
6436                             [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
6437                              (match_operand:SI 2 "reg_or_0_operand" "rJ")])
6438          (const_int 0)))
6439    (set (match_operand:SI 0 "register_operand" "=r")
6440         (match_operator:SI 4 "cc_arithopn"
6441                             [(not:SI (match_dup 1)) (match_dup 2)]))]
6442   "GET_CODE (operands[3]) == GET_CODE (operands[4])"
6443   "%B3cc\t%r2, %1, %0"
6444   [(set_attr "type" "compare")])
6445
6446 (define_insn "*cmp_ccx_arith_op_not_set"
6447   [(set (reg:CCX 100)
6448         (compare:CCX
6449          (match_operator:DI 3 "cc_arithopn"
6450                             [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6451                              (match_operand:DI 2 "reg_or_0_operand" "rJ")])
6452          (const_int 0)))
6453    (set (match_operand:DI 0 "register_operand" "=r")
6454         (match_operator:DI 4 "cc_arithopn"
6455                             [(not:DI (match_dup 1)) (match_dup 2)]))]
6456   "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
6457   "%B3cc\t%r2, %1, %0"
6458   [(set_attr "type" "compare")])
6459
6460 ;; We cannot use the "neg" pseudo insn because the Sun assembler
6461 ;; does not know how to make it work for constants.
6462
6463 (define_expand "negdi2"
6464   [(set (match_operand:DI 0 "register_operand" "=r")
6465         (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6466   ""
6467 {
6468   if (! TARGET_ARCH64)
6469     {
6470       emit_insn (gen_rtx_PARALLEL
6471                  (VOIDmode,
6472                   gen_rtvec (2,
6473                              gen_rtx_SET (VOIDmode, operand0,
6474                                           gen_rtx_NEG (DImode, operand1)),
6475                              gen_rtx_CLOBBER (VOIDmode,
6476                                               gen_rtx_REG (CCmode,
6477                                                            SPARC_ICC_REG)))));
6478       DONE;
6479     }
6480 })
6481
6482 (define_insn_and_split "*negdi2_sp32"
6483   [(set (match_operand:DI 0 "register_operand" "=r")
6484         (neg:DI (match_operand:DI 1 "register_operand" "r")))
6485    (clobber (reg:CC 100))]
6486   "TARGET_ARCH32"
6487   "#"
6488   "&& reload_completed"
6489   [(parallel [(set (reg:CC_NOOV 100)
6490                    (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
6491                                     (const_int 0)))
6492               (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
6493    (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
6494                                 (ltu:SI (reg:CC 100) (const_int 0))))]
6495   "operands[2] = gen_highpart (SImode, operands[0]);
6496    operands[3] = gen_highpart (SImode, operands[1]);
6497    operands[4] = gen_lowpart (SImode, operands[0]);
6498    operands[5] = gen_lowpart (SImode, operands[1]);"
6499   [(set_attr "length" "2")])
6500
6501 (define_insn "*negdi2_sp64"
6502   [(set (match_operand:DI 0 "register_operand" "=r")
6503         (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6504   "TARGET_ARCH64"
6505   "sub\t%%g0, %1, %0")
6506
6507 (define_insn "negsi2"
6508   [(set (match_operand:SI 0 "register_operand" "=r")
6509         (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
6510   ""
6511   "sub\t%%g0, %1, %0")
6512
6513 (define_insn "*cmp_cc_neg"
6514   [(set (reg:CC_NOOV 100)
6515         (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
6516                          (const_int 0)))]
6517   ""
6518   "subcc\t%%g0, %0, %%g0"
6519   [(set_attr "type" "compare")])
6520
6521 (define_insn "*cmp_ccx_neg"
6522   [(set (reg:CCX_NOOV 100)
6523         (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6524                           (const_int 0)))]
6525   "TARGET_ARCH64"
6526   "subcc\t%%g0, %0, %%g0"
6527   [(set_attr "type" "compare")])
6528
6529 (define_insn "*cmp_cc_set_neg"
6530   [(set (reg:CC_NOOV 100)
6531         (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
6532                          (const_int 0)))
6533    (set (match_operand:SI 0 "register_operand" "=r")
6534         (neg:SI (match_dup 1)))]
6535   ""
6536   "subcc\t%%g0, %1, %0"
6537   [(set_attr "type" "compare")])
6538
6539 (define_insn "*cmp_ccx_set_neg"
6540   [(set (reg:CCX_NOOV 100)
6541         (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6542                           (const_int 0)))
6543    (set (match_operand:DI 0 "register_operand" "=r")
6544         (neg:DI (match_dup 1)))]
6545   "TARGET_ARCH64"
6546   "subcc\t%%g0, %1, %0"
6547   [(set_attr "type" "compare")])
6548
6549 ;; We cannot use the "not" pseudo insn because the Sun assembler
6550 ;; does not know how to make it work for constants.
6551 (define_expand "one_cmpl<V64I:mode>2"
6552   [(set (match_operand:V64I 0 "register_operand" "")
6553         (not:V64I (match_operand:V64I 1 "register_operand" "")))]
6554   ""
6555   "")
6556
6557 (define_insn_and_split "*one_cmpl<V64I:mode>2_sp32"
6558   [(set (match_operand:V64I 0 "register_operand" "=r,b")
6559         (not:V64I (match_operand:V64I 1 "register_operand" "r,b")))]
6560   "! TARGET_ARCH64"
6561   "@
6562    #
6563    fnot1\t%1, %0"
6564   "&& reload_completed
6565    && ((GET_CODE (operands[0]) == REG
6566         && REGNO (operands[0]) < 32)
6567        || (GET_CODE (operands[0]) == SUBREG
6568            && GET_CODE (SUBREG_REG (operands[0])) == REG
6569            && REGNO (SUBREG_REG (operands[0])) < 32))"
6570   [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
6571    (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
6572   "operands[2] = gen_highpart (SImode, operands[0]);
6573    operands[3] = gen_highpart (SImode, operands[1]);
6574    operands[4] = gen_lowpart (SImode, operands[0]);
6575    operands[5] = gen_lowpart (SImode, operands[1]);"
6576   [(set_attr "type" "*,fga")
6577    (set_attr "length" "2,*")
6578    (set_attr "fptype" "*,double")])
6579
6580 (define_insn "*one_cmpl<V64I:mode>2_sp64"
6581   [(set (match_operand:V64I 0 "register_operand" "=r,b")
6582         (not:V64I (match_operand:V64I 1 "arith_double_operand" "rHI,b")))]
6583   "TARGET_ARCH64"
6584   "@
6585    xnor\t%%g0, %1, %0
6586    fnot1\t%1, %0"
6587   [(set_attr "type" "*,fga")
6588    (set_attr "fptype" "*,double")])
6589
6590 (define_insn "one_cmpl<V32I:mode>2"
6591   [(set (match_operand:V32I 0 "register_operand" "=r,d")
6592         (not:V32I (match_operand:V32I 1 "arith_operand" "rI,d")))]
6593   ""
6594   "@
6595   xnor\t%%g0, %1, %0
6596   fnot1s\t%1, %0"
6597   [(set_attr "type" "*,fga")
6598    (set_attr "fptype" "*,single")])
6599
6600 (define_insn "*cmp_cc_not"
6601   [(set (reg:CC 100)
6602         (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
6603                     (const_int 0)))]
6604   ""
6605   "xnorcc\t%%g0, %0, %%g0"
6606   [(set_attr "type" "compare")])
6607
6608 (define_insn "*cmp_ccx_not"
6609   [(set (reg:CCX 100)
6610         (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6611                      (const_int 0)))]
6612   "TARGET_ARCH64"
6613   "xnorcc\t%%g0, %0, %%g0"
6614   [(set_attr "type" "compare")])
6615
6616 (define_insn "*cmp_cc_set_not"
6617   [(set (reg:CC 100)
6618         (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
6619                     (const_int 0)))
6620    (set (match_operand:SI 0 "register_operand" "=r")
6621         (not:SI (match_dup 1)))]
6622   ""
6623   "xnorcc\t%%g0, %1, %0"
6624   [(set_attr "type" "compare")])
6625
6626 (define_insn "*cmp_ccx_set_not"
6627   [(set (reg:CCX 100)
6628         (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6629                     (const_int 0)))
6630    (set (match_operand:DI 0 "register_operand" "=r")
6631         (not:DI (match_dup 1)))]
6632   "TARGET_ARCH64"
6633   "xnorcc\t%%g0, %1, %0"
6634   [(set_attr "type" "compare")])
6635
6636 (define_insn "*cmp_cc_set"
6637   [(set (match_operand:SI 0 "register_operand" "=r")
6638         (match_operand:SI 1 "register_operand" "r"))
6639    (set (reg:CC 100)
6640         (compare:CC (match_dup 1)
6641                     (const_int 0)))]
6642   ""
6643   "orcc\t%1, 0, %0"
6644   [(set_attr "type" "compare")])
6645
6646 (define_insn "*cmp_ccx_set64"
6647   [(set (match_operand:DI 0 "register_operand" "=r")
6648         (match_operand:DI 1 "register_operand" "r"))
6649    (set (reg:CCX 100)
6650         (compare:CCX (match_dup 1)
6651                      (const_int 0)))]
6652   "TARGET_ARCH64"
6653   "orcc\t%1, 0, %0"
6654    [(set_attr "type" "compare")])
6655 \f
6656 ;; Floating point arithmetic instructions.
6657
6658 (define_expand "addtf3"
6659   [(set (match_operand:TF 0 "nonimmediate_operand" "")
6660         (plus:TF (match_operand:TF 1 "general_operand" "")
6661                  (match_operand:TF 2 "general_operand" "")))]
6662   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6663   "emit_tfmode_binop (PLUS, operands); DONE;")
6664
6665 (define_insn "*addtf3_hq"
6666   [(set (match_operand:TF 0 "register_operand" "=e")
6667         (plus:TF (match_operand:TF 1 "register_operand" "e")
6668                  (match_operand:TF 2 "register_operand" "e")))]
6669   "TARGET_FPU && TARGET_HARD_QUAD"
6670   "faddq\t%1, %2, %0"
6671   [(set_attr "type" "fp")])
6672
6673 (define_insn "adddf3"
6674   [(set (match_operand:DF 0 "register_operand" "=e")
6675         (plus:DF (match_operand:DF 1 "register_operand" "e")
6676                  (match_operand:DF 2 "register_operand" "e")))]
6677   "TARGET_FPU"
6678   "faddd\t%1, %2, %0"
6679   [(set_attr "type" "fp")
6680    (set_attr "fptype" "double")])
6681
6682 (define_insn "addsf3"
6683   [(set (match_operand:SF 0 "register_operand" "=f")
6684         (plus:SF (match_operand:SF 1 "register_operand" "f")
6685                  (match_operand:SF 2 "register_operand" "f")))]
6686   "TARGET_FPU"
6687   "fadds\t%1, %2, %0"
6688   [(set_attr "type" "fp")])
6689
6690 (define_expand "subtf3"
6691   [(set (match_operand:TF 0 "nonimmediate_operand" "")
6692         (minus:TF (match_operand:TF 1 "general_operand" "")
6693                   (match_operand:TF 2 "general_operand" "")))]
6694   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6695   "emit_tfmode_binop (MINUS, operands); DONE;")
6696
6697 (define_insn "*subtf3_hq"
6698   [(set (match_operand:TF 0 "register_operand" "=e")
6699         (minus:TF (match_operand:TF 1 "register_operand" "e")
6700                   (match_operand:TF 2 "register_operand" "e")))]
6701   "TARGET_FPU && TARGET_HARD_QUAD"
6702   "fsubq\t%1, %2, %0"
6703   [(set_attr "type" "fp")])
6704
6705 (define_insn "subdf3"
6706   [(set (match_operand:DF 0 "register_operand" "=e")
6707         (minus:DF (match_operand:DF 1 "register_operand" "e")
6708                   (match_operand:DF 2 "register_operand" "e")))]
6709   "TARGET_FPU"
6710   "fsubd\t%1, %2, %0"
6711   [(set_attr "type" "fp")
6712    (set_attr "fptype" "double")])
6713
6714 (define_insn "subsf3"
6715   [(set (match_operand:SF 0 "register_operand" "=f")
6716         (minus:SF (match_operand:SF 1 "register_operand" "f")
6717                   (match_operand:SF 2 "register_operand" "f")))]
6718   "TARGET_FPU"
6719   "fsubs\t%1, %2, %0"
6720   [(set_attr "type" "fp")])
6721
6722 (define_expand "multf3"
6723   [(set (match_operand:TF 0 "nonimmediate_operand" "")
6724         (mult:TF (match_operand:TF 1 "general_operand" "")
6725                  (match_operand:TF 2 "general_operand" "")))]
6726   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6727   "emit_tfmode_binop (MULT, operands); DONE;")
6728
6729 (define_insn "*multf3_hq"
6730   [(set (match_operand:TF 0 "register_operand" "=e")
6731         (mult:TF (match_operand:TF 1 "register_operand" "e")
6732                  (match_operand:TF 2 "register_operand" "e")))]
6733   "TARGET_FPU && TARGET_HARD_QUAD"
6734   "fmulq\t%1, %2, %0"
6735   [(set_attr "type" "fpmul")])
6736
6737 (define_insn "muldf3"
6738   [(set (match_operand:DF 0 "register_operand" "=e")
6739         (mult:DF (match_operand:DF 1 "register_operand" "e")
6740                  (match_operand:DF 2 "register_operand" "e")))]
6741   "TARGET_FPU"
6742   "fmuld\t%1, %2, %0"
6743   [(set_attr "type" "fpmul")
6744    (set_attr "fptype" "double")])
6745
6746 (define_insn "mulsf3"
6747   [(set (match_operand:SF 0 "register_operand" "=f")
6748         (mult:SF (match_operand:SF 1 "register_operand" "f")
6749                  (match_operand:SF 2 "register_operand" "f")))]
6750   "TARGET_FPU"
6751   "fmuls\t%1, %2, %0"
6752   [(set_attr "type" "fpmul")])
6753
6754 (define_insn "*muldf3_extend"
6755   [(set (match_operand:DF 0 "register_operand" "=e")
6756         (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
6757                  (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
6758   "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
6759   "fsmuld\t%1, %2, %0"
6760   [(set_attr "type" "fpmul")
6761    (set_attr "fptype" "double")])
6762
6763 (define_insn "*multf3_extend"
6764   [(set (match_operand:TF 0 "register_operand" "=e")
6765         (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
6766                  (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
6767   "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
6768   "fdmulq\t%1, %2, %0"
6769   [(set_attr "type" "fpmul")])
6770
6771 (define_expand "divtf3"
6772   [(set (match_operand:TF 0 "nonimmediate_operand" "")
6773         (div:TF (match_operand:TF 1 "general_operand" "")
6774                 (match_operand:TF 2 "general_operand" "")))]
6775   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6776   "emit_tfmode_binop (DIV, operands); DONE;")
6777
6778 ;; don't have timing for quad-prec. divide.
6779 (define_insn "*divtf3_hq"
6780   [(set (match_operand:TF 0 "register_operand" "=e")
6781         (div:TF (match_operand:TF 1 "register_operand" "e")
6782                 (match_operand:TF 2 "register_operand" "e")))]
6783   "TARGET_FPU && TARGET_HARD_QUAD"
6784   "fdivq\t%1, %2, %0"
6785   [(set_attr "type" "fpdivd")])
6786
6787 (define_insn "divdf3"
6788   [(set (match_operand:DF 0 "register_operand" "=e")
6789         (div:DF (match_operand:DF 1 "register_operand" "e")
6790                 (match_operand:DF 2 "register_operand" "e")))]
6791   "TARGET_FPU"
6792   "fdivd\t%1, %2, %0"
6793   [(set_attr "type" "fpdivd")
6794    (set_attr "fptype" "double")])
6795
6796 (define_insn "divsf3"
6797   [(set (match_operand:SF 0 "register_operand" "=f")
6798         (div:SF (match_operand:SF 1 "register_operand" "f")
6799                 (match_operand:SF 2 "register_operand" "f")))]
6800   "TARGET_FPU"
6801   "fdivs\t%1, %2, %0"
6802   [(set_attr "type" "fpdivs")])
6803
6804 (define_expand "negtf2"
6805   [(set (match_operand:TF 0 "register_operand" "=e,e")
6806         (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6807   "TARGET_FPU"
6808   "")
6809
6810 (define_insn_and_split "*negtf2_notv9"
6811   [(set (match_operand:TF 0 "register_operand" "=e,e")
6812         (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6813   ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6814   "TARGET_FPU
6815    && ! TARGET_V9"
6816   "@
6817   fnegs\t%0, %0
6818   #"
6819   "&& reload_completed
6820    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6821   [(set (match_dup 2) (neg:SF (match_dup 3)))
6822    (set (match_dup 4) (match_dup 5))
6823    (set (match_dup 6) (match_dup 7))]
6824   "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6825    operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6826    operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6827    operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6828    operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6829    operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6830   [(set_attr "type" "fpmove,*")
6831    (set_attr "length" "*,2")])
6832
6833 (define_insn_and_split "*negtf2_v9"
6834   [(set (match_operand:TF 0 "register_operand" "=e,e")
6835         (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6836   ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6837   "TARGET_FPU && TARGET_V9"
6838   "@
6839   fnegd\t%0, %0
6840   #"
6841   "&& reload_completed
6842    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6843   [(set (match_dup 2) (neg:DF (match_dup 3)))
6844    (set (match_dup 4) (match_dup 5))]
6845   "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6846    operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6847    operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6848    operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6849   [(set_attr "type" "fpmove,*")
6850    (set_attr "length" "*,2")
6851    (set_attr "fptype" "double")])
6852
6853 (define_expand "negdf2"
6854   [(set (match_operand:DF 0 "register_operand" "")
6855         (neg:DF (match_operand:DF 1 "register_operand" "")))]
6856   "TARGET_FPU"
6857   "")
6858
6859 (define_insn_and_split "*negdf2_notv9"
6860   [(set (match_operand:DF 0 "register_operand" "=e,e")
6861         (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
6862   "TARGET_FPU && ! TARGET_V9"
6863   "@
6864   fnegs\t%0, %0
6865   #"
6866   "&& reload_completed
6867    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6868   [(set (match_dup 2) (neg:SF (match_dup 3)))
6869    (set (match_dup 4) (match_dup 5))]
6870   "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6871    operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6872    operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6873    operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6874   [(set_attr "type" "fpmove,*")
6875    (set_attr "length" "*,2")])
6876
6877 (define_insn "*negdf2_v9"
6878   [(set (match_operand:DF 0 "register_operand" "=e")
6879         (neg:DF (match_operand:DF 1 "register_operand" "e")))]
6880   "TARGET_FPU && TARGET_V9"
6881   "fnegd\t%1, %0"
6882   [(set_attr "type" "fpmove")
6883    (set_attr "fptype" "double")])
6884
6885 (define_insn "negsf2"
6886   [(set (match_operand:SF 0 "register_operand" "=f")
6887         (neg:SF (match_operand:SF 1 "register_operand" "f")))]
6888   "TARGET_FPU"
6889   "fnegs\t%1, %0"
6890   [(set_attr "type" "fpmove")])
6891
6892 (define_expand "abstf2"
6893   [(set (match_operand:TF 0 "register_operand" "")
6894         (abs:TF (match_operand:TF 1 "register_operand" "")))]
6895   "TARGET_FPU"
6896   "")
6897
6898 (define_insn_and_split "*abstf2_notv9"
6899   [(set (match_operand:TF 0 "register_operand" "=e,e")
6900         (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6901   ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6902   "TARGET_FPU && ! TARGET_V9"
6903   "@
6904   fabss\t%0, %0
6905   #"
6906   "&& reload_completed
6907    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6908   [(set (match_dup 2) (abs:SF (match_dup 3)))
6909    (set (match_dup 4) (match_dup 5))
6910    (set (match_dup 6) (match_dup 7))]
6911   "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6912    operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6913    operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6914    operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6915    operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6916    operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6917   [(set_attr "type" "fpmove,*")
6918    (set_attr "length" "*,2")])
6919
6920 (define_insn "*abstf2_hq_v9"
6921   [(set (match_operand:TF 0 "register_operand" "=e,e")
6922         (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6923   "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
6924   "@
6925   fabsd\t%0, %0
6926   fabsq\t%1, %0"
6927   [(set_attr "type" "fpmove")
6928    (set_attr "fptype" "double,*")])
6929
6930 (define_insn_and_split "*abstf2_v9"
6931   [(set (match_operand:TF 0 "register_operand" "=e,e")
6932         (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6933   "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
6934   "@
6935   fabsd\t%0, %0
6936   #"
6937   "&& reload_completed
6938    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6939   [(set (match_dup 2) (abs:DF (match_dup 3)))
6940    (set (match_dup 4) (match_dup 5))]
6941   "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6942    operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6943    operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6944    operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6945   [(set_attr "type" "fpmove,*")
6946    (set_attr "length" "*,2")
6947    (set_attr "fptype" "double,*")])
6948
6949 (define_expand "absdf2"
6950   [(set (match_operand:DF 0 "register_operand" "")
6951         (abs:DF (match_operand:DF 1 "register_operand" "")))]
6952   "TARGET_FPU"
6953   "")
6954
6955 (define_insn_and_split "*absdf2_notv9"
6956   [(set (match_operand:DF 0 "register_operand" "=e,e")
6957         (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
6958   "TARGET_FPU && ! TARGET_V9"
6959   "@
6960   fabss\t%0, %0
6961   #"
6962   "&& reload_completed
6963    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6964   [(set (match_dup 2) (abs:SF (match_dup 3)))
6965    (set (match_dup 4) (match_dup 5))]
6966   "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6967    operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6968    operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6969    operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6970   [(set_attr "type" "fpmove,*")
6971    (set_attr "length" "*,2")])
6972
6973 (define_insn "*absdf2_v9"
6974   [(set (match_operand:DF 0 "register_operand" "=e")
6975         (abs:DF (match_operand:DF 1 "register_operand" "e")))]
6976   "TARGET_FPU && TARGET_V9"
6977   "fabsd\t%1, %0"
6978   [(set_attr "type" "fpmove")
6979    (set_attr "fptype" "double")])
6980
6981 (define_insn "abssf2"
6982   [(set (match_operand:SF 0 "register_operand" "=f")
6983         (abs:SF (match_operand:SF 1 "register_operand" "f")))]
6984   "TARGET_FPU"
6985   "fabss\t%1, %0"
6986   [(set_attr "type" "fpmove")])
6987
6988 (define_expand "sqrttf2"
6989   [(set (match_operand:TF 0 "nonimmediate_operand" "")
6990         (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
6991   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6992   "emit_tfmode_unop (SQRT, operands); DONE;")
6993
6994 (define_insn "*sqrttf2_hq"
6995   [(set (match_operand:TF 0 "register_operand" "=e")
6996         (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
6997   "TARGET_FPU && TARGET_HARD_QUAD"
6998   "fsqrtq\t%1, %0"
6999   [(set_attr "type" "fpsqrtd")])
7000
7001 (define_insn "sqrtdf2"
7002   [(set (match_operand:DF 0 "register_operand" "=e")
7003         (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
7004   "TARGET_FPU"
7005   "fsqrtd\t%1, %0"
7006   [(set_attr "type" "fpsqrtd")
7007    (set_attr "fptype" "double")])
7008
7009 (define_insn "sqrtsf2"
7010   [(set (match_operand:SF 0 "register_operand" "=f")
7011         (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
7012   "TARGET_FPU"
7013   "fsqrts\t%1, %0"
7014   [(set_attr "type" "fpsqrts")])
7015 \f
7016 ;;- arithmetic shift instructions
7017
7018 (define_insn "ashlsi3"
7019   [(set (match_operand:SI 0 "register_operand" "=r")
7020         (ashift:SI (match_operand:SI 1 "register_operand" "r")
7021                    (match_operand:SI 2 "arith_operand" "rI")))]
7022   ""
7023 {
7024   if (GET_CODE (operands[2]) == CONST_INT)
7025     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7026   return "sll\t%1, %2, %0";
7027 }
7028   [(set (attr "type")
7029         (if_then_else (match_operand 2 "const1_operand" "")
7030                       (const_string "ialu") (const_string "shift")))])
7031
7032 (define_expand "ashldi3"
7033   [(set (match_operand:DI 0 "register_operand" "=r")
7034         (ashift:DI (match_operand:DI 1 "register_operand" "r")
7035                    (match_operand:SI 2 "arith_operand" "rI")))]
7036   "TARGET_ARCH64 || TARGET_V8PLUS"
7037 {
7038   if (! TARGET_ARCH64)
7039     {
7040       if (GET_CODE (operands[2]) == CONST_INT)
7041         FAIL;
7042       emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
7043       DONE;
7044     }
7045 })
7046
7047 (define_insn "*ashldi3_sp64"
7048   [(set (match_operand:DI 0 "register_operand" "=r")
7049         (ashift:DI (match_operand:DI 1 "register_operand" "r")
7050                    (match_operand:SI 2 "arith_operand" "rI")))]
7051   "TARGET_ARCH64"
7052 {
7053   if (GET_CODE (operands[2]) == CONST_INT)
7054     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7055   return "sllx\t%1, %2, %0";
7056 }
7057   [(set (attr "type")
7058         (if_then_else (match_operand 2 "const1_operand" "")
7059                       (const_string "ialu") (const_string "shift")))])
7060
7061 ;; XXX UGH!
7062 (define_insn "ashldi3_v8plus"
7063   [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7064         (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7065                    (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7066    (clobber (match_scratch:SI 3 "=X,X,&h"))]
7067   "TARGET_V8PLUS"
7068   "* return output_v8plus_shift (operands, insn, \"sllx\");"
7069   [(set_attr "type" "multi")
7070    (set_attr "length" "5,5,6")])
7071
7072 ;; Optimize (1LL<<x)-1
7073 ;; XXX this also needs to be fixed to handle equal subregs
7074 ;; XXX first before we could re-enable it.
7075 ;(define_insn ""
7076 ;  [(set (match_operand:DI 0 "register_operand" "=h")
7077 ;       (plus:DI (ashift:DI (const_int 1)
7078 ;                           (match_operand:SI 1 "arith_operand" "rI"))
7079 ;                (const_int -1)))]
7080 ;  "0 && TARGET_V8PLUS"
7081 ;{
7082 ;  if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
7083 ;    return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
7084 ;  return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
7085 ;}
7086 ;  [(set_attr "type" "multi")
7087 ;   (set_attr "length" "4")])
7088
7089 (define_insn "*cmp_cc_ashift_1"
7090   [(set (reg:CC_NOOV 100)
7091         (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
7092                                     (const_int 1))
7093                          (const_int 0)))]
7094   ""
7095   "addcc\t%0, %0, %%g0"
7096   [(set_attr "type" "compare")])
7097
7098 (define_insn "*cmp_cc_set_ashift_1"
7099   [(set (reg:CC_NOOV 100)
7100         (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
7101                                     (const_int 1))
7102                          (const_int 0)))
7103    (set (match_operand:SI 0 "register_operand" "=r")
7104         (ashift:SI (match_dup 1) (const_int 1)))]
7105   ""
7106   "addcc\t%1, %1, %0"
7107   [(set_attr "type" "compare")])
7108
7109 (define_insn "ashrsi3"
7110   [(set (match_operand:SI 0 "register_operand" "=r")
7111         (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7112                      (match_operand:SI 2 "arith_operand" "rI")))]
7113   ""
7114   {
7115      if (GET_CODE (operands[2]) == CONST_INT)
7116        operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7117      return "sra\t%1, %2, %0";
7118   }
7119   [(set_attr "type" "shift")])
7120
7121 (define_insn "*ashrsi3_extend"
7122   [(set (match_operand:DI 0 "register_operand" "=r")
7123         (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7124                                      (match_operand:SI 2 "arith_operand" "r"))))]
7125   "TARGET_ARCH64"
7126   "sra\t%1, %2, %0"
7127   [(set_attr "type" "shift")])
7128
7129 ;; This handles the case as above, but with constant shift instead of
7130 ;; register. Combiner "simplifies" it for us a little bit though.
7131 (define_insn "*ashrsi3_extend2"
7132   [(set (match_operand:DI 0 "register_operand" "=r")
7133         (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7134                                 (const_int 32))
7135                      (match_operand:SI 2 "small_int_or_double" "n")))]
7136   "TARGET_ARCH64
7137    && ((GET_CODE (operands[2]) == CONST_INT
7138         && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64)
7139        || (GET_CODE (operands[2]) == CONST_DOUBLE
7140            && !CONST_DOUBLE_HIGH (operands[2])
7141            && CONST_DOUBLE_LOW (operands[2]) >= 32
7142            && CONST_DOUBLE_LOW (operands[2]) < 64))"
7143 {
7144   operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
7145
7146   return "sra\t%1, %2, %0";
7147 }
7148   [(set_attr "type" "shift")])
7149
7150 (define_expand "ashrdi3"
7151   [(set (match_operand:DI 0 "register_operand" "=r")
7152         (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7153                      (match_operand:SI 2 "arith_operand" "rI")))]
7154   "TARGET_ARCH64 || TARGET_V8PLUS"
7155 {
7156   if (! TARGET_ARCH64)
7157     {
7158       if (GET_CODE (operands[2]) == CONST_INT)
7159         FAIL;   /* prefer generic code in this case */
7160       emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
7161       DONE;
7162     }
7163 })
7164
7165 (define_insn "*ashrdi3_sp64"
7166   [(set (match_operand:DI 0 "register_operand" "=r")
7167         (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7168                      (match_operand:SI 2 "arith_operand" "rI")))]
7169   "TARGET_ARCH64"
7170   
7171   {
7172     if (GET_CODE (operands[2]) == CONST_INT)
7173       operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7174     return "srax\t%1, %2, %0";
7175   }
7176   [(set_attr "type" "shift")])
7177
7178 ;; XXX
7179 (define_insn "ashrdi3_v8plus"
7180   [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7181         (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7182                      (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7183    (clobber (match_scratch:SI 3 "=X,X,&h"))]
7184   "TARGET_V8PLUS"
7185   "* return output_v8plus_shift (operands, insn, \"srax\");"
7186   [(set_attr "type" "multi")
7187    (set_attr "length" "5,5,6")])
7188
7189 (define_insn "lshrsi3"
7190   [(set (match_operand:SI 0 "register_operand" "=r")
7191         (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
7192                      (match_operand:SI 2 "arith_operand" "rI")))]
7193   ""
7194   {
7195     if (GET_CODE (operands[2]) == CONST_INT)
7196       operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7197     return "srl\t%1, %2, %0";
7198   }
7199   [(set_attr "type" "shift")])
7200
7201 ;; This handles the case where
7202 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
7203 ;; but combiner "simplifies" it for us.
7204 (define_insn "*lshrsi3_extend"
7205   [(set (match_operand:DI 0 "register_operand" "=r")
7206         (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
7207                            (match_operand:SI 2 "arith_operand" "r")) 0)
7208                 (match_operand 3 "" "")))]
7209   "TARGET_ARCH64
7210    && ((GET_CODE (operands[3]) == CONST_DOUBLE
7211            && CONST_DOUBLE_HIGH (operands[3]) == 0
7212            && CONST_DOUBLE_LOW (operands[3]) == 0xffffffff)
7213        || (HOST_BITS_PER_WIDE_INT >= 64
7214            && GET_CODE (operands[3]) == CONST_INT
7215            && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff))"
7216   "srl\t%1, %2, %0"
7217   [(set_attr "type" "shift")])
7218
7219 ;; This handles the case where
7220 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
7221 ;; but combiner "simplifies" it for us.
7222 (define_insn "*lshrsi3_extend2"
7223   [(set (match_operand:DI 0 "register_operand" "=r")
7224         (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7225                          (match_operand 2 "small_int_or_double" "n")
7226                          (const_int 32)))]
7227   "TARGET_ARCH64
7228    && ((GET_CODE (operands[2]) == CONST_INT
7229         && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7230        || (GET_CODE (operands[2]) == CONST_DOUBLE
7231            && CONST_DOUBLE_HIGH (operands[2]) == 0
7232            && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7233 {
7234   operands[2] = GEN_INT (32 - INTVAL (operands[2]));
7235
7236   return "srl\t%1, %2, %0";
7237 }
7238   [(set_attr "type" "shift")])
7239
7240 (define_expand "lshrdi3"
7241   [(set (match_operand:DI 0 "register_operand" "=r")
7242         (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7243                      (match_operand:SI 2 "arith_operand" "rI")))]
7244   "TARGET_ARCH64 || TARGET_V8PLUS"
7245 {
7246   if (! TARGET_ARCH64)
7247     {
7248       if (GET_CODE (operands[2]) == CONST_INT)
7249         FAIL;
7250       emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
7251       DONE;
7252     }
7253 })
7254
7255 (define_insn "*lshrdi3_sp64"
7256   [(set (match_operand:DI 0 "register_operand" "=r")
7257         (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7258                      (match_operand:SI 2 "arith_operand" "rI")))]
7259   "TARGET_ARCH64"
7260   {
7261     if (GET_CODE (operands[2]) == CONST_INT)
7262       operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7263     return "srlx\t%1, %2, %0";
7264   }
7265   [(set_attr "type" "shift")])
7266
7267 ;; XXX
7268 (define_insn "lshrdi3_v8plus"
7269   [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7270         (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7271                      (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7272    (clobber (match_scratch:SI 3 "=X,X,&h"))]
7273   "TARGET_V8PLUS"
7274   "* return output_v8plus_shift (operands, insn, \"srlx\");"
7275   [(set_attr "type" "multi")
7276    (set_attr "length" "5,5,6")])
7277
7278 (define_insn ""
7279   [(set (match_operand:SI 0 "register_operand" "=r")
7280         (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7281                                              (const_int 32)) 4)
7282                      (match_operand:SI 2 "small_int_or_double" "n")))]
7283   "TARGET_ARCH64
7284    && ((GET_CODE (operands[2]) == CONST_INT
7285         && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7286        || (GET_CODE (operands[2]) == CONST_DOUBLE
7287            && !CONST_DOUBLE_HIGH (operands[2])
7288            && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7289 {
7290   operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
7291
7292   return "srax\t%1, %2, %0";
7293 }
7294   [(set_attr "type" "shift")])
7295
7296 (define_insn ""
7297   [(set (match_operand:SI 0 "register_operand" "=r")
7298         (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7299                                              (const_int 32)) 4)
7300                      (match_operand:SI 2 "small_int_or_double" "n")))]
7301   "TARGET_ARCH64
7302    && ((GET_CODE (operands[2]) == CONST_INT
7303         && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7304        || (GET_CODE (operands[2]) == CONST_DOUBLE
7305            && !CONST_DOUBLE_HIGH (operands[2])
7306            && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7307 {
7308   operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
7309
7310   return "srlx\t%1, %2, %0";
7311 }
7312   [(set_attr "type" "shift")])
7313
7314 (define_insn ""
7315   [(set (match_operand:SI 0 "register_operand" "=r")
7316         (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7317                                              (match_operand:SI 2 "small_int_or_double" "n")) 4)
7318                      (match_operand:SI 3 "small_int_or_double" "n")))]
7319   "TARGET_ARCH64
7320    && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
7321    && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
7322    && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
7323    && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
7324 {
7325   operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
7326
7327   return "srax\t%1, %2, %0";
7328 }
7329   [(set_attr "type" "shift")])
7330
7331 (define_insn ""
7332   [(set (match_operand:SI 0 "register_operand" "=r")
7333         (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7334                                              (match_operand:SI 2 "small_int_or_double" "n")) 4)
7335                      (match_operand:SI 3 "small_int_or_double" "n")))]
7336   "TARGET_ARCH64
7337    && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
7338    && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
7339    && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
7340    && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
7341 {
7342   operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
7343
7344   return "srlx\t%1, %2, %0";
7345 }
7346   [(set_attr "type" "shift")])
7347 \f
7348 ;; Unconditional and other jump instructions
7349 (define_insn "jump"
7350   [(set (pc) (label_ref (match_operand 0 "" "")))]
7351   ""
7352   "* return output_ubranch (operands[0], 0, insn);"
7353   [(set_attr "type" "uncond_branch")])
7354
7355 (define_expand "tablejump"
7356   [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
7357               (use (label_ref (match_operand 1 "" "")))])]
7358   ""
7359 {
7360   gcc_assert (GET_MODE (operands[0]) == CASE_VECTOR_MODE);
7361
7362   /* In pic mode, our address differences are against the base of the
7363      table.  Add that base value back in; CSE ought to be able to combine
7364      the two address loads.  */
7365   if (flag_pic)
7366     {
7367       rtx tmp, tmp2;
7368       tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
7369       tmp2 = operands[0];
7370       if (CASE_VECTOR_MODE != Pmode)
7371         tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
7372       tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
7373       operands[0] = memory_address (Pmode, tmp);
7374     }
7375 })
7376
7377 (define_insn "*tablejump_sp32"
7378   [(set (pc) (match_operand:SI 0 "address_operand" "p"))
7379    (use (label_ref (match_operand 1 "" "")))]
7380   "! TARGET_ARCH64"
7381   "jmp\t%a0%#"
7382   [(set_attr "type" "uncond_branch")])
7383
7384 (define_insn "*tablejump_sp64"
7385   [(set (pc) (match_operand:DI 0 "address_operand" "p"))
7386    (use (label_ref (match_operand 1 "" "")))]
7387   "TARGET_ARCH64"
7388   "jmp\t%a0%#"
7389   [(set_attr "type" "uncond_branch")])
7390
7391 ;;- jump to subroutine
7392 (define_expand "call"
7393   ;; Note that this expression is not used for generating RTL.
7394   ;; All the RTL is generated explicitly below.
7395   [(call (match_operand 0 "call_operand" "")
7396          (match_operand 3 "" "i"))]
7397   ;; operands[2] is next_arg_register
7398   ;; operands[3] is struct_value_size_rtx.
7399   ""
7400 {
7401   rtx fn_rtx;
7402
7403   gcc_assert (GET_MODE (operands[0]) == FUNCTION_MODE);
7404
7405   gcc_assert (GET_CODE (operands[3]) == CONST_INT);
7406
7407   if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
7408     {
7409       /* This is really a PIC sequence.  We want to represent
7410          it as a funny jump so its delay slots can be filled. 
7411
7412          ??? But if this really *is* a CALL, will not it clobber the
7413          call-clobbered registers?  We lose this if it is a JUMP_INSN.
7414          Why cannot we have delay slots filled if it were a CALL?  */
7415
7416       /* We accept negative sizes for untyped calls.  */
7417       if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7418         emit_jump_insn
7419           (gen_rtx_PARALLEL
7420            (VOIDmode,
7421             gen_rtvec (3,
7422                        gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
7423                        operands[3],
7424                        gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7425       else
7426         emit_jump_insn
7427           (gen_rtx_PARALLEL
7428            (VOIDmode,
7429             gen_rtvec (2,
7430                        gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
7431                        gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7432       goto finish_call;
7433     }
7434
7435   fn_rtx = operands[0];
7436
7437   /* We accept negative sizes for untyped calls.  */
7438   if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7439     emit_call_insn
7440       (gen_rtx_PARALLEL
7441        (VOIDmode,
7442         gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
7443                    operands[3],
7444                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7445   else
7446     emit_call_insn
7447       (gen_rtx_PARALLEL
7448        (VOIDmode,
7449         gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
7450                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7451
7452  finish_call:
7453
7454   DONE;
7455 })
7456
7457 ;; We can't use the same pattern for these two insns, because then registers
7458 ;; in the address may not be properly reloaded.
7459
7460 (define_insn "*call_address_sp32"
7461   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7462          (match_operand 1 "" ""))
7463    (clobber (reg:SI 15))]
7464   ;;- Do not use operand 1 for most machines.
7465   "! TARGET_ARCH64"
7466   "call\t%a0, %1%#"
7467   [(set_attr "type" "call")])
7468
7469 (define_insn "*call_symbolic_sp32"
7470   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7471          (match_operand 1 "" ""))
7472    (clobber (reg:SI 15))]
7473   ;;- Do not use operand 1 for most machines.
7474   "! TARGET_ARCH64"
7475   "call\t%a0, %1%#"
7476   [(set_attr "type" "call")])
7477
7478 (define_insn "*call_address_sp64"
7479   [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
7480          (match_operand 1 "" ""))
7481    (clobber (reg:DI 15))]
7482   ;;- Do not use operand 1 for most machines.
7483   "TARGET_ARCH64"
7484   "call\t%a0, %1%#"
7485   [(set_attr "type" "call")])
7486
7487 (define_insn "*call_symbolic_sp64"
7488   [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
7489          (match_operand 1 "" ""))
7490    (clobber (reg:DI 15))]
7491   ;;- Do not use operand 1 for most machines.
7492   "TARGET_ARCH64"
7493   "call\t%a0, %1%#"
7494   [(set_attr "type" "call")])
7495
7496 ;; This is a call that wants a structure value.
7497 ;; There is no such critter for v9 (??? we may need one anyway).
7498 (define_insn "*call_address_struct_value_sp32"
7499   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7500          (match_operand 1 "" ""))
7501    (match_operand 2 "immediate_operand" "")
7502    (clobber (reg:SI 15))]
7503   ;;- Do not use operand 1 for most machines.
7504   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
7505 {
7506   operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
7507   return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
7508 }
7509   [(set_attr "type" "call_no_delay_slot")
7510    (set_attr "length" "3")])
7511
7512 ;; This is a call that wants a structure value.
7513 ;; There is no such critter for v9 (??? we may need one anyway).
7514 (define_insn "*call_symbolic_struct_value_sp32"
7515   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7516          (match_operand 1 "" ""))
7517    (match_operand 2 "immediate_operand" "")
7518    (clobber (reg:SI 15))]
7519   ;;- Do not use operand 1 for most machines.
7520   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
7521 {
7522   operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
7523   return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
7524 }
7525   [(set_attr "type" "call_no_delay_slot")
7526    (set_attr "length" "3")])
7527
7528 ;; This is a call that may want a structure value.  This is used for
7529 ;; untyped_calls.
7530 (define_insn "*call_address_untyped_struct_value_sp32"
7531   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7532          (match_operand 1 "" ""))
7533    (match_operand 2 "immediate_operand" "")
7534    (clobber (reg:SI 15))]
7535   ;;- Do not use operand 1 for most machines.
7536   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7537   "call\t%a0, %1\n\t nop\n\tnop"
7538   [(set_attr "type" "call_no_delay_slot")
7539    (set_attr "length" "3")])
7540
7541 ;; This is a call that may want a structure value.  This is used for
7542 ;; untyped_calls.
7543 (define_insn "*call_symbolic_untyped_struct_value_sp32"
7544   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7545          (match_operand 1 "" ""))
7546    (match_operand 2 "immediate_operand" "")
7547    (clobber (reg:SI 15))]
7548   ;;- Do not use operand 1 for most machines.
7549   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7550   "call\t%a0, %1\n\t nop\n\tnop"
7551   [(set_attr "type" "call_no_delay_slot")
7552    (set_attr "length" "3")])
7553
7554 (define_expand "call_value"
7555   ;; Note that this expression is not used for generating RTL.
7556   ;; All the RTL is generated explicitly below.
7557   [(set (match_operand 0 "register_operand" "=rf")
7558         (call (match_operand 1 "" "")
7559               (match_operand 4 "" "")))]
7560   ;; operand 2 is stack_size_rtx
7561   ;; operand 3 is next_arg_register
7562   ""
7563 {
7564   rtx fn_rtx;
7565   rtvec vec;
7566
7567   gcc_assert (GET_MODE (operands[1]) == FUNCTION_MODE);
7568
7569   fn_rtx = operands[1];
7570
7571   vec = gen_rtvec (2,
7572                    gen_rtx_SET (VOIDmode, operands[0],
7573                                 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
7574                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
7575
7576   emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
7577
7578   DONE;
7579 })
7580
7581 (define_insn "*call_value_address_sp32"
7582   [(set (match_operand 0 "" "=rf")
7583         (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
7584               (match_operand 2 "" "")))
7585    (clobber (reg:SI 15))]
7586   ;;- Do not use operand 2 for most machines.
7587   "! TARGET_ARCH64"
7588   "call\t%a1, %2%#"
7589   [(set_attr "type" "call")])
7590
7591 (define_insn "*call_value_symbolic_sp32"
7592   [(set (match_operand 0 "" "=rf")
7593         (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7594               (match_operand 2 "" "")))
7595    (clobber (reg:SI 15))]
7596   ;;- Do not use operand 2 for most machines.
7597   "! TARGET_ARCH64"
7598   "call\t%a1, %2%#"
7599   [(set_attr "type" "call")])
7600
7601 (define_insn "*call_value_address_sp64"
7602   [(set (match_operand 0 "" "")
7603         (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
7604               (match_operand 2 "" "")))
7605    (clobber (reg:DI 15))]
7606   ;;- Do not use operand 2 for most machines.
7607   "TARGET_ARCH64"
7608   "call\t%a1, %2%#"
7609   [(set_attr "type" "call")])
7610
7611 (define_insn "*call_value_symbolic_sp64"
7612   [(set (match_operand 0 "" "")
7613         (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
7614               (match_operand 2 "" "")))
7615    (clobber (reg:DI 15))]
7616   ;;- Do not use operand 2 for most machines.
7617   "TARGET_ARCH64"
7618   "call\t%a1, %2%#"
7619   [(set_attr "type" "call")])
7620
7621 (define_expand "untyped_call"
7622   [(parallel [(call (match_operand 0 "" "")
7623                     (const_int 0))
7624               (match_operand 1 "" "")
7625               (match_operand 2 "" "")])]
7626   ""
7627 {
7628   int i;
7629
7630   /* Pass constm1 to indicate that it may expect a structure value, but
7631      we don't know what size it is.  */
7632   emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
7633
7634   for (i = 0; i < XVECLEN (operands[2], 0); i++)
7635     {
7636       rtx set = XVECEXP (operands[2], 0, i);
7637       emit_move_insn (SET_DEST (set), SET_SRC (set));
7638     }
7639
7640   /* The optimizer does not know that the call sets the function value
7641      registers we stored in the result block.  We avoid problems by
7642      claiming that all hard registers are used and clobbered at this
7643      point.  */
7644   emit_insn (gen_blockage ());
7645
7646   DONE;
7647 })
7648
7649 ;;- tail calls
7650 (define_expand "sibcall"
7651   [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
7652               (return)])]
7653   ""
7654   "")
7655
7656 (define_insn "*sibcall_symbolic_sp32"
7657   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7658          (match_operand 1 "" ""))
7659    (return)]
7660   "! TARGET_ARCH64"
7661   "* return output_sibcall(insn, operands[0]);"
7662   [(set_attr "type" "sibcall")])
7663
7664 (define_insn "*sibcall_symbolic_sp64"
7665   [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
7666          (match_operand 1 "" ""))
7667    (return)]
7668   "TARGET_ARCH64"
7669   "* return output_sibcall(insn, operands[0]);"
7670   [(set_attr "type" "sibcall")])
7671
7672 (define_expand "sibcall_value"
7673   [(parallel [(set (match_operand 0 "register_operand" "=rf")
7674                 (call (match_operand 1 "" "") (const_int 0)))
7675               (return)])]
7676   ""
7677   "")
7678
7679 (define_insn "*sibcall_value_symbolic_sp32"
7680   [(set (match_operand 0 "" "=rf")
7681         (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7682               (match_operand 2 "" "")))
7683    (return)]
7684   "! TARGET_ARCH64"
7685   "* return output_sibcall(insn, operands[1]);"
7686   [(set_attr "type" "sibcall")])
7687
7688 (define_insn "*sibcall_value_symbolic_sp64"
7689   [(set (match_operand 0 "" "")
7690         (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
7691               (match_operand 2 "" "")))
7692    (return)]
7693   "TARGET_ARCH64"
7694   "* return output_sibcall(insn, operands[1]);"
7695   [(set_attr "type" "sibcall")])
7696
7697 (define_expand "sibcall_epilogue"
7698   [(return)]
7699   ""
7700 {
7701   sparc_expand_epilogue ();
7702   DONE;
7703 })
7704
7705 (define_expand "prologue"
7706   [(const_int 0)]
7707   ""
7708 {
7709   sparc_expand_prologue ();
7710   DONE;
7711 })
7712
7713 ;; The "save register window" insn is modelled as follows so that the DWARF-2
7714 ;; backend automatically emits the required call frame debugging information
7715 ;; while it is parsing it.  Therefore, the pattern should not be modified
7716 ;; without first studying the impact of the changes on the debug info.
7717 ;; [(set (%fp) (%sp))
7718 ;;  (set (%sp) (unspec_volatile [(%sp) (-frame_size)] UNSPECV_SAVEW))
7719 ;;  (set (%i7) (%o7))]
7720
7721 (define_insn "save_register_window<P:mode>"
7722   [(set (reg:P 30) (reg:P 14))
7723    (set (reg:P 14) (unspec_volatile:P [(reg:P 14)
7724                                        (match_operand:P 0 "arith_operand" "rI")] UNSPECV_SAVEW))
7725    (set (reg:P 31) (reg:P 15))]
7726   ""
7727   "save\t%%sp, %0, %%sp"
7728   [(set_attr "type" "savew")])
7729
7730 (define_expand "epilogue"
7731   [(return)]
7732   ""
7733 {
7734   sparc_expand_epilogue ();
7735 })
7736
7737 (define_expand "return"
7738   [(return)]
7739   "sparc_can_use_return_insn_p ()"
7740   "")
7741
7742 (define_insn "*return_internal"
7743   [(return)]
7744   ""
7745   "* return output_return (insn);"
7746   [(set_attr "type" "return")
7747    (set (attr "length")
7748         (cond [(eq_attr "leaf_function" "true")
7749                  (if_then_else (eq_attr "empty_delay_slot" "true")
7750                                (const_int 2)
7751                                (const_int 1))
7752                (eq_attr "calls_eh_return" "true")
7753                  (if_then_else (eq_attr "delayed_branch" "true")
7754                                (if_then_else (eq_attr "isa" "v9")
7755                                              (const_int 2)
7756                                              (const_int 3))
7757                                (if_then_else (eq_attr "isa" "v9")
7758                                              (const_int 3)
7759                                              (const_int 4)))
7760                (eq_attr "empty_delay_slot" "true")
7761                  (if_then_else (eq_attr "delayed_branch" "true")
7762                                (const_int 2)
7763                                (const_int 3))
7764               ] (const_int 1)))])
7765
7766 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
7767 ;; all of memory.  This blocks insns from being moved across this point.
7768
7769 (define_insn "blockage"
7770   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7771   ""
7772   ""
7773   [(set_attr "length" "0")])
7774
7775 ;; Prepare to return any type including a structure value.
7776
7777 (define_expand "untyped_return"
7778   [(match_operand:BLK 0 "memory_operand" "")
7779    (match_operand 1 "" "")]
7780   ""
7781 {
7782   rtx valreg1 = gen_rtx_REG (DImode, 24);
7783   rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
7784   rtx result = operands[0];
7785
7786   if (! TARGET_ARCH64)
7787     {
7788       rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
7789                                          ? 15 : 31));
7790       rtx value = gen_reg_rtx (SImode);
7791
7792       /* Fetch the instruction where we will return to and see if it's an unimp
7793          instruction (the most significant 10 bits will be zero).  If so,
7794          update the return address to skip the unimp instruction.  */
7795       emit_move_insn (value,
7796                       gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
7797       emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
7798       emit_insn (gen_update_return (rtnreg, value));
7799     }
7800
7801   /* Reload the function value registers.  */
7802   emit_move_insn (valreg1, adjust_address (result, DImode, 0));
7803   emit_move_insn (valreg2,
7804                   adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
7805
7806   /* Put USE insns before the return.  */
7807   emit_insn (gen_rtx_USE (VOIDmode, valreg1));
7808   emit_insn (gen_rtx_USE (VOIDmode, valreg2));
7809
7810   /* Construct the return.  */
7811   expand_naked_return ();
7812
7813   DONE;
7814 })
7815
7816 ;; This is a bit of a hack.  We're incrementing a fixed register (%i7),
7817 ;; and parts of the compiler don't want to believe that the add is needed.
7818
7819 (define_insn "update_return"
7820   [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
7821                (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
7822   "! TARGET_ARCH64"
7823 {
7824   if (flag_delayed_branch)
7825     return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
7826   else
7827     return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
7828 }
7829   [(set (attr "type") (const_string "multi"))
7830    (set (attr "length")
7831         (if_then_else (eq_attr "delayed_branch" "true")
7832                       (const_int 3)
7833                       (const_int 4)))])
7834 \f
7835 (define_insn "nop"
7836   [(const_int 0)]
7837   ""
7838   "nop")
7839
7840 (define_expand "indirect_jump"
7841   [(set (pc) (match_operand 0 "address_operand" "p"))]
7842   ""
7843   "")
7844
7845 (define_insn "*branch_sp32"
7846   [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
7847   "! TARGET_ARCH64"
7848  "jmp\t%a0%#"
7849  [(set_attr "type" "uncond_branch")])
7850  
7851 (define_insn "*branch_sp64"
7852   [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
7853   "TARGET_ARCH64"
7854   "jmp\t%a0%#"
7855   [(set_attr "type" "uncond_branch")])
7856
7857 (define_expand "nonlocal_goto"
7858   [(match_operand:SI 0 "general_operand" "")
7859    (match_operand:SI 1 "general_operand" "")
7860    (match_operand:SI 2 "general_operand" "")
7861    (match_operand:SI 3 "" "")]
7862   ""
7863 {
7864   rtx lab = operands[1];
7865   rtx stack = operands[2];
7866   rtx fp = operands[3];
7867   rtx labreg;
7868
7869   /* Trap instruction to flush all the register windows.  */
7870   emit_insn (gen_flush_register_windows ());
7871
7872   /* Load the fp value for the containing fn into %fp.  This is needed
7873      because STACK refers to %fp.  Note that virtual register instantiation
7874      fails if the virtual %fp isn't set from a register.  */
7875   if (GET_CODE (fp) != REG)
7876     fp = force_reg (Pmode, fp);
7877   emit_move_insn (virtual_stack_vars_rtx, fp);
7878
7879   /* Find the containing function's current nonlocal goto handler,
7880      which will do any cleanups and then jump to the label.  */
7881   labreg = gen_rtx_REG (Pmode, 8);
7882   emit_move_insn (labreg, lab);
7883
7884   /* Restore %fp from stack pointer value for containing function.
7885      The restore insn that follows will move this to %sp,
7886      and reload the appropriate value into %fp.  */
7887   emit_move_insn (hard_frame_pointer_rtx, stack);
7888
7889   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
7890   emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
7891
7892   /* ??? The V9-specific version was disabled in rev 1.65.  */
7893   emit_jump_insn (gen_goto_handler_and_restore (labreg));
7894   emit_barrier ();
7895   DONE;
7896 })
7897
7898 ;; Special trap insn to flush register windows.
7899 (define_insn "flush_register_windows"
7900   [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
7901   ""
7902   { return TARGET_V9 ? "flushw" : "ta\t3"; }
7903   [(set_attr "type" "flushw")])
7904
7905 (define_insn "goto_handler_and_restore"
7906   [(unspec_volatile [(match_operand 0 "register_operand" "=r")] UNSPECV_GOTO)]
7907   "GET_MODE (operands[0]) == Pmode"
7908 {
7909   if (flag_delayed_branch)
7910     return "jmp\t%0\n\t restore";
7911   else
7912     return "mov\t%0,%%g1\n\trestore\n\tjmp\t%%g1\n\t nop";
7913 }
7914   [(set (attr "type") (const_string "multi"))
7915    (set (attr "length")
7916         (if_then_else (eq_attr "delayed_branch" "true")
7917                       (const_int 2)
7918                       (const_int 4)))])
7919
7920 ;; For __builtin_setjmp we need to flush register windows iff the function
7921 ;; calls alloca as well, because otherwise the register window might be
7922 ;; saved after %sp adjustment and thus setjmp would crash
7923 (define_expand "builtin_setjmp_setup"
7924   [(match_operand 0 "register_operand" "r")]
7925   ""
7926 {
7927   emit_insn (gen_do_builtin_setjmp_setup ());
7928   DONE;
7929 })
7930
7931 (define_insn "do_builtin_setjmp_setup"
7932   [(unspec_volatile [(const_int 0)] UNSPECV_SETJMP)]
7933   ""
7934 {
7935   if (! current_function_calls_alloca)
7936     return "";
7937   if (! TARGET_V9)
7938     return "\tta\t3\n";
7939   fputs ("\tflushw\n", asm_out_file);
7940   if (flag_pic)
7941     fprintf (asm_out_file, "\tst%c\t%%l7, [%%sp+%d]\n",
7942              TARGET_ARCH64 ? 'x' : 'w',
7943              SPARC_STACK_BIAS + 7 * UNITS_PER_WORD);
7944   fprintf (asm_out_file, "\tst%c\t%%fp, [%%sp+%d]\n",
7945            TARGET_ARCH64 ? 'x' : 'w',
7946            SPARC_STACK_BIAS + 14 * UNITS_PER_WORD);
7947   fprintf (asm_out_file, "\tst%c\t%%i7, [%%sp+%d]\n",
7948            TARGET_ARCH64 ? 'x' : 'w',
7949            SPARC_STACK_BIAS + 15 * UNITS_PER_WORD);
7950   return "";
7951 }
7952   [(set_attr "type" "multi")
7953    (set (attr "length")
7954         (cond [(eq_attr "calls_alloca" "false")
7955                  (const_int 0)
7956                (eq_attr "isa" "!v9")
7957                  (const_int 1)
7958                (eq_attr "pic" "true")
7959                  (const_int 4)] (const_int 3)))])
7960
7961 ;; Pattern for use after a setjmp to store FP and the return register
7962 ;; into the stack area.
7963
7964 (define_expand "setjmp"
7965   [(const_int 0)]
7966   ""
7967 {
7968   if (TARGET_ARCH64)
7969     emit_insn (gen_setjmp_64 ());
7970   else
7971     emit_insn (gen_setjmp_32 ());
7972   DONE;
7973 })
7974
7975 (define_expand "setjmp_32"
7976   [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
7977    (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
7978   ""
7979   { operands[0] = frame_pointer_rtx; })
7980
7981 (define_expand "setjmp_64"
7982   [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
7983    (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
7984   ""
7985   { operands[0] = frame_pointer_rtx; })
7986
7987 ;; Special pattern for the FLUSH instruction.
7988
7989 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
7990 ; of the define_insn otherwise missing a mode.  We make "flush", aka
7991 ; gen_flush, the default one since sparc_initialize_trampoline uses
7992 ; it on SImode mem values.
7993
7994 (define_insn "flush"
7995   [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7996   ""
7997   { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7998   [(set_attr "type" "iflush")])
7999
8000 (define_insn "flushdi"
8001   [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
8002   ""
8003   { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
8004   [(set_attr "type" "iflush")])
8005
8006 \f
8007 ;; find first set.
8008
8009 ;; The scan instruction searches from the most significant bit while ffs
8010 ;; searches from the least significant bit.  The bit index and treatment of
8011 ;; zero also differ.  It takes at least 7 instructions to get the proper
8012 ;; result.  Here is an obvious 8 instruction sequence.
8013
8014 ;; XXX
8015 (define_insn "ffssi2"
8016   [(set (match_operand:SI 0 "register_operand" "=&r")
8017         (ffs:SI (match_operand:SI 1 "register_operand" "r")))
8018    (clobber (match_scratch:SI 2 "=&r"))]
8019   "TARGET_SPARCLITE || TARGET_SPARCLET"
8020 {
8021   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";
8022 }
8023   [(set_attr "type" "multi")
8024    (set_attr "length" "8")])
8025
8026 ;; ??? This should be a define expand, so that the extra instruction have
8027 ;; a chance of being optimized away.
8028
8029 ;; Disabled because none of the UltraSPARCs implement popc.  The HAL R1
8030 ;; does, but no one uses that and we don't have a switch for it.
8031 ;
8032 ;(define_insn "ffsdi2"
8033 ;  [(set (match_operand:DI 0 "register_operand" "=&r")
8034 ;       (ffs:DI (match_operand:DI 1 "register_operand" "r")))
8035 ;   (clobber (match_scratch:DI 2 "=&r"))]
8036 ;  "TARGET_ARCH64"
8037 ;  "neg\t%1, %2\;xnor\t%1, %2, %2\;popc\t%2, %0\;movzr\t%1, 0, %0"
8038 ;  [(set_attr "type" "multi")
8039 ;   (set_attr "length" "4")])
8040
8041
8042 \f
8043 ;; Peepholes go at the end.
8044
8045 ;; Optimize consecutive loads or stores into ldd and std when possible.
8046 ;; The conditions in which we do this are very restricted and are 
8047 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
8048
8049 (define_peephole2
8050   [(set (match_operand:SI 0 "memory_operand" "")
8051       (const_int 0))
8052    (set (match_operand:SI 1 "memory_operand" "")
8053       (const_int 0))]
8054   "TARGET_V9
8055    && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
8056   [(set (match_dup 0)
8057        (const_int 0))]
8058   "operands[0] = widen_memory_access (operands[0], DImode, 0);")
8059
8060 (define_peephole2
8061   [(set (match_operand:SI 0 "memory_operand" "")
8062       (const_int 0))
8063    (set (match_operand:SI 1 "memory_operand" "")
8064       (const_int 0))]
8065   "TARGET_V9
8066    && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
8067   [(set (match_dup 1)
8068        (const_int 0))]
8069   "operands[1] = widen_memory_access (operands[1], DImode, 0);")
8070
8071 (define_peephole2
8072   [(set (match_operand:SI 0 "register_operand" "")
8073         (match_operand:SI 1 "memory_operand" ""))
8074    (set (match_operand:SI 2 "register_operand" "")
8075         (match_operand:SI 3 "memory_operand" ""))]
8076   "registers_ok_for_ldd_peep (operands[0], operands[2]) 
8077    && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])" 
8078   [(set (match_dup 0)
8079         (match_dup 1))]
8080   "operands[1] = widen_memory_access (operands[1], DImode, 0);
8081    operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
8082
8083 (define_peephole2
8084   [(set (match_operand:SI 0 "memory_operand" "")
8085         (match_operand:SI 1 "register_operand" ""))
8086    (set (match_operand:SI 2 "memory_operand" "")
8087         (match_operand:SI 3 "register_operand" ""))]
8088   "registers_ok_for_ldd_peep (operands[1], operands[3]) 
8089    && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
8090   [(set (match_dup 0)
8091         (match_dup 1))]
8092   "operands[0] = widen_memory_access (operands[0], DImode, 0);
8093    operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
8094
8095 (define_peephole2
8096   [(set (match_operand:SF 0 "register_operand" "")
8097         (match_operand:SF 1 "memory_operand" ""))
8098    (set (match_operand:SF 2 "register_operand" "")
8099         (match_operand:SF 3 "memory_operand" ""))]
8100   "registers_ok_for_ldd_peep (operands[0], operands[2]) 
8101    && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
8102   [(set (match_dup 0)
8103         (match_dup 1))]
8104   "operands[1] = widen_memory_access (operands[1], DFmode, 0);
8105    operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
8106
8107 (define_peephole2
8108   [(set (match_operand:SF 0 "memory_operand" "")
8109         (match_operand:SF 1 "register_operand" ""))
8110    (set (match_operand:SF 2 "memory_operand" "")
8111         (match_operand:SF 3 "register_operand" ""))]
8112   "registers_ok_for_ldd_peep (operands[1], operands[3]) 
8113   && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
8114   [(set (match_dup 0)
8115         (match_dup 1))]
8116   "operands[0] = widen_memory_access (operands[0], DFmode, 0);
8117    operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
8118
8119 (define_peephole2
8120   [(set (match_operand:SI 0 "register_operand" "")
8121         (match_operand:SI 1 "memory_operand" ""))
8122    (set (match_operand:SI 2 "register_operand" "")
8123         (match_operand:SI 3 "memory_operand" ""))]
8124   "registers_ok_for_ldd_peep (operands[2], operands[0]) 
8125   && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
8126   [(set (match_dup 2)
8127         (match_dup 3))]
8128    "operands[3] = widen_memory_access (operands[3], DImode, 0);
8129     operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
8130
8131 (define_peephole2
8132   [(set (match_operand:SI 0 "memory_operand" "")
8133         (match_operand:SI 1 "register_operand" ""))
8134    (set (match_operand:SI 2 "memory_operand" "")
8135         (match_operand:SI 3 "register_operand" ""))]
8136   "registers_ok_for_ldd_peep (operands[3], operands[1]) 
8137   && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)" 
8138   [(set (match_dup 2)
8139         (match_dup 3))]
8140   "operands[2] = widen_memory_access (operands[2], DImode, 0);
8141    operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
8142    ")
8143  
8144 (define_peephole2
8145   [(set (match_operand:SF 0 "register_operand" "")
8146         (match_operand:SF 1 "memory_operand" ""))
8147    (set (match_operand:SF 2 "register_operand" "")
8148         (match_operand:SF 3 "memory_operand" ""))]
8149   "registers_ok_for_ldd_peep (operands[2], operands[0]) 
8150   && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
8151   [(set (match_dup 2)
8152         (match_dup 3))]
8153   "operands[3] = widen_memory_access (operands[3], DFmode, 0);
8154    operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
8155
8156 (define_peephole2
8157   [(set (match_operand:SF 0 "memory_operand" "")
8158         (match_operand:SF 1 "register_operand" ""))
8159    (set (match_operand:SF 2 "memory_operand" "")
8160         (match_operand:SF 3 "register_operand" ""))]
8161   "registers_ok_for_ldd_peep (operands[3], operands[1]) 
8162   && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
8163   [(set (match_dup 2)
8164         (match_dup 3))]
8165   "operands[2] = widen_memory_access (operands[2], DFmode, 0);
8166    operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
8167  
8168 ;; Optimize the case of following a reg-reg move with a test
8169 ;; of reg just moved.  Don't allow floating point regs for operand 0 or 1.
8170 ;; This can result from a float to fix conversion.
8171
8172 (define_peephole2
8173   [(set (match_operand:SI 0 "register_operand" "")
8174         (match_operand:SI 1 "register_operand" ""))
8175    (set (reg:CC 100)
8176         (compare:CC (match_operand:SI 2 "register_operand" "")
8177                     (const_int 0)))]
8178   "(rtx_equal_p (operands[2], operands[0])
8179     || rtx_equal_p (operands[2], operands[1]))
8180     && ! SPARC_FP_REG_P (REGNO (operands[0]))
8181     && ! SPARC_FP_REG_P (REGNO (operands[1]))"
8182   [(parallel [(set (match_dup 0) (match_dup 1))
8183               (set (reg:CC 100)
8184                    (compare:CC (match_dup 1) (const_int 0)))])]
8185   "")
8186
8187 (define_peephole2
8188   [(set (match_operand:DI 0 "register_operand" "")
8189         (match_operand:DI 1 "register_operand" ""))
8190    (set (reg:CCX 100)
8191         (compare:CCX (match_operand:DI 2 "register_operand" "")
8192                     (const_int 0)))]
8193   "TARGET_ARCH64
8194    && (rtx_equal_p (operands[2], operands[0])
8195        || rtx_equal_p (operands[2], operands[1]))
8196    && ! SPARC_FP_REG_P (REGNO (operands[0]))
8197    && ! SPARC_FP_REG_P (REGNO (operands[1]))"
8198   [(parallel [(set (match_dup 0) (match_dup 1))
8199               (set (reg:CCX 100)
8200                    (compare:CCX (match_dup 1) (const_int 0)))])]
8201   "")
8202
8203 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
8204 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
8205 ;; ??? operations.  With DFA we might be able to model this, but it requires a lot of
8206 ;; ??? state.
8207 (define_expand "prefetch"
8208   [(match_operand 0 "address_operand" "")
8209    (match_operand 1 "const_int_operand" "")
8210    (match_operand 2 "const_int_operand" "")]
8211   "TARGET_V9"
8212 {
8213   if (TARGET_ARCH64)
8214     emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
8215   else
8216     emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
8217   DONE;
8218 })
8219
8220 (define_insn "prefetch_64"
8221   [(prefetch (match_operand:DI 0 "address_operand" "p")
8222              (match_operand:DI 1 "const_int_operand" "n")
8223              (match_operand:DI 2 "const_int_operand" "n"))]
8224   ""
8225 {
8226   static const char * const prefetch_instr[2][2] = {
8227     {
8228       "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
8229       "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
8230     },
8231     {
8232       "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
8233       "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
8234     }
8235   };
8236   int read_or_write = INTVAL (operands[1]);
8237   int locality = INTVAL (operands[2]);
8238
8239   gcc_assert (read_or_write == 0 || read_or_write == 1);
8240   gcc_assert (locality >= 0 && locality < 4);
8241   return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
8242 }
8243   [(set_attr "type" "load")])
8244
8245 (define_insn "prefetch_32"
8246   [(prefetch (match_operand:SI 0 "address_operand" "p")
8247              (match_operand:SI 1 "const_int_operand" "n")
8248              (match_operand:SI 2 "const_int_operand" "n"))]
8249   ""
8250 {
8251   static const char * const prefetch_instr[2][2] = {
8252     {
8253       "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
8254       "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
8255     },
8256     {
8257       "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
8258       "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
8259     }
8260   };
8261   int read_or_write = INTVAL (operands[1]);
8262   int locality = INTVAL (operands[2]);
8263
8264   gcc_assert (read_or_write == 0 || read_or_write == 1);
8265   gcc_assert (locality >= 0 && locality < 4);
8266   return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
8267 }
8268   [(set_attr "type" "load")])
8269 \f
8270 (define_insn "trap"
8271   [(trap_if (const_int 1) (const_int 5))]
8272   ""
8273   "ta\t5"
8274   [(set_attr "type" "trap")])
8275
8276 (define_expand "conditional_trap"
8277   [(trap_if (match_operator 0 "noov_compare_op" [(match_dup 2) (match_dup 3)])
8278             (match_operand:SI 1 "arith_operand" ""))]
8279   ""
8280   "operands[2] = gen_compare_reg (GET_CODE (operands[0]),
8281                                   sparc_compare_op0, sparc_compare_op1);
8282    if (GET_MODE (operands[2]) != CCmode && GET_MODE (operands[2]) != CCXmode)
8283      FAIL;
8284    operands[3] = const0_rtx;")
8285
8286 (define_insn ""
8287   [(trap_if (match_operator 0 "noov_compare_op" [(reg:CC 100) (const_int 0)])
8288             (match_operand:SI 1 "arith_operand" "rM"))]
8289   ""
8290 {
8291   if (TARGET_V9)
8292     return "t%C0\t%%icc, %1";
8293   else
8294     return "t%C0\t%1";
8295 }
8296   [(set_attr "type" "trap")])
8297
8298 (define_insn ""
8299   [(trap_if (match_operator 0 "noov_compare_op" [(reg:CCX 100) (const_int 0)])
8300             (match_operand:SI 1 "arith_operand" "rM"))]
8301   "TARGET_V9"
8302   "t%C0\t%%xcc, %1"
8303   [(set_attr "type" "trap")])
8304
8305 ;; TLS support
8306 (define_insn "tgd_hi22"
8307   [(set (match_operand:SI 0 "register_operand" "=r")
8308         (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
8309                             UNSPEC_TLSGD)))]
8310   "TARGET_TLS"
8311   "sethi\\t%%tgd_hi22(%a1), %0")
8312
8313 (define_insn "tgd_lo10"
8314   [(set (match_operand:SI 0 "register_operand" "=r")
8315         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8316                    (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
8317                               UNSPEC_TLSGD)))]
8318   "TARGET_TLS"
8319   "add\\t%1, %%tgd_lo10(%a2), %0")
8320
8321 (define_insn "tgd_add32"
8322   [(set (match_operand:SI 0 "register_operand" "=r")
8323         (plus:SI (match_operand:SI 1 "register_operand" "r")
8324                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8325                              (match_operand 3 "tgd_symbolic_operand" "")]
8326                             UNSPEC_TLSGD)))]
8327   "TARGET_TLS && TARGET_ARCH32"
8328   "add\\t%1, %2, %0, %%tgd_add(%a3)")
8329
8330 (define_insn "tgd_add64"
8331   [(set (match_operand:DI 0 "register_operand" "=r")
8332         (plus:DI (match_operand:DI 1 "register_operand" "r")
8333                  (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8334                              (match_operand 3 "tgd_symbolic_operand" "")]
8335                             UNSPEC_TLSGD)))]
8336   "TARGET_TLS && TARGET_ARCH64"
8337   "add\\t%1, %2, %0, %%tgd_add(%a3)")
8338
8339 (define_insn "tgd_call32"
8340   [(set (match_operand 0 "register_operand" "=r")
8341         (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
8342                                   (match_operand 2 "tgd_symbolic_operand" "")]
8343                                  UNSPEC_TLSGD))
8344               (match_operand 3 "" "")))
8345    (clobber (reg:SI 15))]
8346   "TARGET_TLS && TARGET_ARCH32"
8347   "call\t%a1, %%tgd_call(%a2)%#"
8348   [(set_attr "type" "call")])
8349
8350 (define_insn "tgd_call64"
8351   [(set (match_operand 0 "register_operand" "=r")
8352         (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
8353                                   (match_operand 2 "tgd_symbolic_operand" "")]
8354                                  UNSPEC_TLSGD))
8355               (match_operand 3 "" "")))
8356    (clobber (reg:DI 15))]
8357   "TARGET_TLS && TARGET_ARCH64"
8358   "call\t%a1, %%tgd_call(%a2)%#"
8359   [(set_attr "type" "call")])
8360
8361 (define_insn "tldm_hi22"
8362   [(set (match_operand:SI 0 "register_operand" "=r")
8363         (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
8364   "TARGET_TLS"
8365   "sethi\\t%%tldm_hi22(%&), %0")
8366
8367 (define_insn "tldm_lo10"
8368   [(set (match_operand:SI 0 "register_operand" "=r")
8369         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8370                     (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
8371   "TARGET_TLS"
8372   "add\\t%1, %%tldm_lo10(%&), %0")
8373
8374 (define_insn "tldm_add32"
8375   [(set (match_operand:SI 0 "register_operand" "=r")
8376         (plus:SI (match_operand:SI 1 "register_operand" "r")
8377                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
8378                             UNSPEC_TLSLDM)))]
8379   "TARGET_TLS && TARGET_ARCH32"
8380   "add\\t%1, %2, %0, %%tldm_add(%&)")
8381
8382 (define_insn "tldm_add64"
8383   [(set (match_operand:DI 0 "register_operand" "=r")
8384         (plus:DI (match_operand:DI 1 "register_operand" "r")
8385                  (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
8386                             UNSPEC_TLSLDM)))]
8387   "TARGET_TLS && TARGET_ARCH64"
8388   "add\\t%1, %2, %0, %%tldm_add(%&)")
8389
8390 (define_insn "tldm_call32"
8391   [(set (match_operand 0 "register_operand" "=r")
8392         (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
8393                                  UNSPEC_TLSLDM))
8394               (match_operand 2 "" "")))
8395    (clobber (reg:SI 15))]
8396   "TARGET_TLS && TARGET_ARCH32"
8397   "call\t%a1, %%tldm_call(%&)%#"
8398   [(set_attr "type" "call")])
8399
8400 (define_insn "tldm_call64"
8401   [(set (match_operand 0 "register_operand" "=r")
8402         (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
8403                                  UNSPEC_TLSLDM))
8404               (match_operand 2 "" "")))
8405    (clobber (reg:DI 15))]
8406   "TARGET_TLS && TARGET_ARCH64"
8407   "call\t%a1, %%tldm_call(%&)%#"
8408   [(set_attr "type" "call")])
8409
8410 (define_insn "tldo_hix22"
8411   [(set (match_operand:SI 0 "register_operand" "=r")
8412         (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
8413                             UNSPEC_TLSLDO)))]
8414   "TARGET_TLS"
8415   "sethi\\t%%tldo_hix22(%a1), %0")
8416
8417 (define_insn "tldo_lox10"
8418   [(set (match_operand:SI 0 "register_operand" "=r")
8419         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8420                    (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
8421                               UNSPEC_TLSLDO)))]
8422   "TARGET_TLS"
8423   "xor\\t%1, %%tldo_lox10(%a2), %0")
8424
8425 (define_insn "tldo_add32"
8426   [(set (match_operand:SI 0 "register_operand" "=r")
8427         (plus:SI (match_operand:SI 1 "register_operand" "r")
8428                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8429                              (match_operand 3 "tld_symbolic_operand" "")]
8430                             UNSPEC_TLSLDO)))]
8431   "TARGET_TLS && TARGET_ARCH32"
8432   "add\\t%1, %2, %0, %%tldo_add(%a3)")
8433
8434 (define_insn "tldo_add64"
8435   [(set (match_operand:DI 0 "register_operand" "=r")
8436         (plus:DI (match_operand:DI 1 "register_operand" "r")
8437                  (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8438                              (match_operand 3 "tld_symbolic_operand" "")]
8439                             UNSPEC_TLSLDO)))]
8440   "TARGET_TLS && TARGET_ARCH64"
8441   "add\\t%1, %2, %0, %%tldo_add(%a3)")
8442
8443 (define_insn "tie_hi22"
8444   [(set (match_operand:SI 0 "register_operand" "=r")
8445         (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
8446                             UNSPEC_TLSIE)))]
8447   "TARGET_TLS"
8448   "sethi\\t%%tie_hi22(%a1), %0")
8449
8450 (define_insn "tie_lo10"
8451   [(set (match_operand:SI 0 "register_operand" "=r")
8452         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8453                    (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
8454                               UNSPEC_TLSIE)))]
8455   "TARGET_TLS"
8456   "add\\t%1, %%tie_lo10(%a2), %0")
8457
8458 (define_insn "tie_ld32"
8459   [(set (match_operand:SI 0 "register_operand" "=r")
8460         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
8461                     (match_operand:SI 2 "register_operand" "r")
8462                     (match_operand 3 "tie_symbolic_operand" "")]
8463                    UNSPEC_TLSIE))]
8464   "TARGET_TLS && TARGET_ARCH32"
8465   "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
8466   [(set_attr "type" "load")])
8467
8468 (define_insn "tie_ld64"
8469   [(set (match_operand:DI 0 "register_operand" "=r")
8470         (unspec:DI [(match_operand:DI 1 "register_operand" "r")
8471                     (match_operand:SI 2 "register_operand" "r")
8472                     (match_operand 3 "tie_symbolic_operand" "")]
8473                    UNSPEC_TLSIE))]
8474   "TARGET_TLS && TARGET_ARCH64"
8475   "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
8476   [(set_attr "type" "load")])
8477
8478 (define_insn "tie_add32"
8479   [(set (match_operand:SI 0 "register_operand" "=r")
8480         (plus:SI (match_operand:SI 1 "register_operand" "r")
8481                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8482                              (match_operand 3 "tie_symbolic_operand" "")]
8483                             UNSPEC_TLSIE)))]
8484   "TARGET_SUN_TLS && TARGET_ARCH32"
8485   "add\\t%1, %2, %0, %%tie_add(%a3)")
8486
8487 (define_insn "tie_add64"
8488   [(set (match_operand:DI 0 "register_operand" "=r")
8489         (plus:DI (match_operand:DI 1 "register_operand" "r")
8490                  (unspec:DI [(match_operand:DI 2 "register_operand" "r")
8491                              (match_operand 3 "tie_symbolic_operand" "")]
8492                             UNSPEC_TLSIE)))]
8493   "TARGET_SUN_TLS && TARGET_ARCH64"
8494   "add\\t%1, %2, %0, %%tie_add(%a3)")
8495
8496 (define_insn "tle_hix22_sp32"
8497   [(set (match_operand:SI 0 "register_operand" "=r")
8498         (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
8499                             UNSPEC_TLSLE)))]
8500   "TARGET_TLS && TARGET_ARCH32"
8501   "sethi\\t%%tle_hix22(%a1), %0")
8502
8503 (define_insn "tle_lox10_sp32"
8504   [(set (match_operand:SI 0 "register_operand" "=r")
8505         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8506                    (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
8507                               UNSPEC_TLSLE)))]
8508   "TARGET_TLS && TARGET_ARCH32"
8509   "xor\\t%1, %%tle_lox10(%a2), %0")
8510
8511 (define_insn "tle_hix22_sp64"
8512   [(set (match_operand:DI 0 "register_operand" "=r")
8513         (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
8514                             UNSPEC_TLSLE)))]
8515   "TARGET_TLS && TARGET_ARCH64"
8516   "sethi\\t%%tle_hix22(%a1), %0")
8517
8518 (define_insn "tle_lox10_sp64"
8519   [(set (match_operand:DI 0 "register_operand" "=r")
8520         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
8521                    (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
8522                               UNSPEC_TLSLE)))]
8523   "TARGET_TLS && TARGET_ARCH64"
8524   "xor\\t%1, %%tle_lox10(%a2), %0")
8525
8526 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
8527 (define_insn "*tldo_ldub_sp32"
8528   [(set (match_operand:QI 0 "register_operand" "=r")
8529         (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8530                                      (match_operand 3 "tld_symbolic_operand" "")]
8531                                     UNSPEC_TLSLDO)
8532                          (match_operand:SI 1 "register_operand" "r"))))]
8533   "TARGET_TLS && TARGET_ARCH32"
8534   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8535   [(set_attr "type" "load")
8536    (set_attr "us3load_type" "3cycle")])
8537
8538 (define_insn "*tldo_ldub1_sp32"
8539   [(set (match_operand:HI 0 "register_operand" "=r")
8540         (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8541                                                      (match_operand 3 "tld_symbolic_operand" "")]
8542                                                     UNSPEC_TLSLDO)
8543                                          (match_operand:SI 1 "register_operand" "r")))))]
8544   "TARGET_TLS && TARGET_ARCH32"
8545   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8546   [(set_attr "type" "load")
8547    (set_attr "us3load_type" "3cycle")])
8548
8549 (define_insn "*tldo_ldub2_sp32"
8550   [(set (match_operand:SI 0 "register_operand" "=r")
8551         (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8552                                                      (match_operand 3 "tld_symbolic_operand" "")]
8553                                                     UNSPEC_TLSLDO)
8554                                          (match_operand:SI 1 "register_operand" "r")))))]
8555   "TARGET_TLS && TARGET_ARCH32"
8556   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8557   [(set_attr "type" "load")
8558    (set_attr "us3load_type" "3cycle")])
8559
8560 (define_insn "*tldo_ldsb1_sp32"
8561   [(set (match_operand:HI 0 "register_operand" "=r")
8562         (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8563                                                      (match_operand 3 "tld_symbolic_operand" "")]
8564                                                     UNSPEC_TLSLDO)
8565                                          (match_operand:SI 1 "register_operand" "r")))))]
8566   "TARGET_TLS && TARGET_ARCH32"
8567   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8568   [(set_attr "type" "sload")
8569    (set_attr "us3load_type" "3cycle")])
8570
8571 (define_insn "*tldo_ldsb2_sp32"
8572   [(set (match_operand:SI 0 "register_operand" "=r")
8573         (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8574                                                      (match_operand 3 "tld_symbolic_operand" "")]
8575                                                     UNSPEC_TLSLDO)
8576                                          (match_operand:SI 1 "register_operand" "r")))))]
8577   "TARGET_TLS && TARGET_ARCH32"
8578   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8579   [(set_attr "type" "sload")
8580    (set_attr "us3load_type" "3cycle")])
8581
8582 (define_insn "*tldo_ldub_sp64"
8583   [(set (match_operand:QI 0 "register_operand" "=r")
8584         (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8585                                      (match_operand 3 "tld_symbolic_operand" "")]
8586                                     UNSPEC_TLSLDO)
8587                          (match_operand:DI 1 "register_operand" "r"))))]
8588   "TARGET_TLS && TARGET_ARCH64"
8589   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8590   [(set_attr "type" "load")
8591    (set_attr "us3load_type" "3cycle")])
8592
8593 (define_insn "*tldo_ldub1_sp64"
8594   [(set (match_operand:HI 0 "register_operand" "=r")
8595         (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8596                                                      (match_operand 3 "tld_symbolic_operand" "")]
8597                                                     UNSPEC_TLSLDO)
8598                                          (match_operand:DI 1 "register_operand" "r")))))]
8599   "TARGET_TLS && TARGET_ARCH64"
8600   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8601   [(set_attr "type" "load")
8602    (set_attr "us3load_type" "3cycle")])
8603
8604 (define_insn "*tldo_ldub2_sp64"
8605   [(set (match_operand:SI 0 "register_operand" "=r")
8606         (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8607                                                      (match_operand 3 "tld_symbolic_operand" "")]
8608                                                     UNSPEC_TLSLDO)
8609                                          (match_operand:DI 1 "register_operand" "r")))))]
8610   "TARGET_TLS && TARGET_ARCH64"
8611   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8612   [(set_attr "type" "load")
8613    (set_attr "us3load_type" "3cycle")])
8614
8615 (define_insn "*tldo_ldub3_sp64"
8616   [(set (match_operand:DI 0 "register_operand" "=r")
8617         (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8618                                                      (match_operand 3 "tld_symbolic_operand" "")]
8619                                                     UNSPEC_TLSLDO)
8620                                          (match_operand:DI 1 "register_operand" "r")))))]
8621   "TARGET_TLS && TARGET_ARCH64"
8622   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8623   [(set_attr "type" "load")
8624    (set_attr "us3load_type" "3cycle")])
8625
8626 (define_insn "*tldo_ldsb1_sp64"
8627   [(set (match_operand:HI 0 "register_operand" "=r")
8628         (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8629                                                      (match_operand 3 "tld_symbolic_operand" "")]
8630                                                     UNSPEC_TLSLDO)
8631                                          (match_operand:DI 1 "register_operand" "r")))))]
8632   "TARGET_TLS && TARGET_ARCH64"
8633   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8634   [(set_attr "type" "sload")
8635    (set_attr "us3load_type" "3cycle")])
8636
8637 (define_insn "*tldo_ldsb2_sp64"
8638   [(set (match_operand:SI 0 "register_operand" "=r")
8639         (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8640                                                      (match_operand 3 "tld_symbolic_operand" "")]
8641                                                     UNSPEC_TLSLDO)
8642                                          (match_operand:DI 1 "register_operand" "r")))))]
8643   "TARGET_TLS && TARGET_ARCH64"
8644   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8645   [(set_attr "type" "sload")
8646    (set_attr "us3load_type" "3cycle")])
8647
8648 (define_insn "*tldo_ldsb3_sp64"
8649   [(set (match_operand:DI 0 "register_operand" "=r")
8650         (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8651                                                      (match_operand 3 "tld_symbolic_operand" "")]
8652                                                     UNSPEC_TLSLDO)
8653                                          (match_operand:DI 1 "register_operand" "r")))))]
8654   "TARGET_TLS && TARGET_ARCH64"
8655   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8656   [(set_attr "type" "sload")
8657    (set_attr "us3load_type" "3cycle")])
8658
8659 (define_insn "*tldo_lduh_sp32"
8660   [(set (match_operand:HI 0 "register_operand" "=r")
8661         (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8662                                      (match_operand 3 "tld_symbolic_operand" "")]
8663                                     UNSPEC_TLSLDO)
8664                          (match_operand:SI 1 "register_operand" "r"))))]
8665   "TARGET_TLS && TARGET_ARCH32"
8666   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8667   [(set_attr "type" "load")
8668    (set_attr "us3load_type" "3cycle")])
8669
8670 (define_insn "*tldo_lduh1_sp32"
8671   [(set (match_operand:SI 0 "register_operand" "=r")
8672         (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8673                                                      (match_operand 3 "tld_symbolic_operand" "")]
8674                                                     UNSPEC_TLSLDO)
8675                                          (match_operand:SI 1 "register_operand" "r")))))]
8676   "TARGET_TLS && TARGET_ARCH32"
8677   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8678   [(set_attr "type" "load")
8679    (set_attr "us3load_type" "3cycle")])
8680
8681 (define_insn "*tldo_ldsh1_sp32"
8682   [(set (match_operand:SI 0 "register_operand" "=r")
8683         (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8684                                                      (match_operand 3 "tld_symbolic_operand" "")]
8685                                                     UNSPEC_TLSLDO)
8686                                          (match_operand:SI 1 "register_operand" "r")))))]
8687   "TARGET_TLS && TARGET_ARCH32"
8688   "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8689   [(set_attr "type" "sload")
8690    (set_attr "us3load_type" "3cycle")])
8691
8692 (define_insn "*tldo_lduh_sp64"
8693   [(set (match_operand:HI 0 "register_operand" "=r")
8694         (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8695                                      (match_operand 3 "tld_symbolic_operand" "")]
8696                                     UNSPEC_TLSLDO)
8697                          (match_operand:DI 1 "register_operand" "r"))))]
8698   "TARGET_TLS && TARGET_ARCH64"
8699   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8700   [(set_attr "type" "load")
8701    (set_attr "us3load_type" "3cycle")])
8702
8703 (define_insn "*tldo_lduh1_sp64"
8704   [(set (match_operand:SI 0 "register_operand" "=r")
8705         (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8706                                                      (match_operand 3 "tld_symbolic_operand" "")]
8707                                                     UNSPEC_TLSLDO)
8708                                          (match_operand:DI 1 "register_operand" "r")))))]
8709   "TARGET_TLS && TARGET_ARCH64"
8710   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8711   [(set_attr "type" "load")
8712    (set_attr "us3load_type" "3cycle")])
8713
8714 (define_insn "*tldo_lduh2_sp64"
8715   [(set (match_operand:DI 0 "register_operand" "=r")
8716         (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8717                                                      (match_operand 3 "tld_symbolic_operand" "")]
8718                                                     UNSPEC_TLSLDO)
8719                                          (match_operand:DI 1 "register_operand" "r")))))]
8720   "TARGET_TLS && TARGET_ARCH64"
8721   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8722   [(set_attr "type" "load")
8723    (set_attr "us3load_type" "3cycle")])
8724
8725 (define_insn "*tldo_ldsh1_sp64"
8726   [(set (match_operand:SI 0 "register_operand" "=r")
8727         (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8728                                                      (match_operand 3 "tld_symbolic_operand" "")]
8729                                                     UNSPEC_TLSLDO)
8730                                          (match_operand:DI 1 "register_operand" "r")))))]
8731   "TARGET_TLS && TARGET_ARCH64"
8732   "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8733   [(set_attr "type" "sload")
8734    (set_attr "us3load_type" "3cycle")])
8735
8736 (define_insn "*tldo_ldsh2_sp64"
8737   [(set (match_operand:DI 0 "register_operand" "=r")
8738         (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8739                                                      (match_operand 3 "tld_symbolic_operand" "")]
8740                                                     UNSPEC_TLSLDO)
8741                                          (match_operand:DI 1 "register_operand" "r")))))]
8742   "TARGET_TLS && TARGET_ARCH64"
8743   "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8744   [(set_attr "type" "sload")
8745    (set_attr "us3load_type" "3cycle")])
8746
8747 (define_insn "*tldo_lduw_sp32"
8748   [(set (match_operand:SI 0 "register_operand" "=r")
8749         (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8750                                      (match_operand 3 "tld_symbolic_operand" "")]
8751                                     UNSPEC_TLSLDO)
8752                          (match_operand:SI 1 "register_operand" "r"))))]
8753   "TARGET_TLS && TARGET_ARCH32"
8754   "ld\t[%1 + %2], %0, %%tldo_add(%3)"
8755   [(set_attr "type" "load")])
8756
8757 (define_insn "*tldo_lduw_sp64"
8758   [(set (match_operand:SI 0 "register_operand" "=r")
8759         (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8760                                      (match_operand 3 "tld_symbolic_operand" "")]
8761                                     UNSPEC_TLSLDO)
8762                          (match_operand:DI 1 "register_operand" "r"))))]
8763   "TARGET_TLS && TARGET_ARCH64"
8764   "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8765   [(set_attr "type" "load")])
8766
8767 (define_insn "*tldo_lduw1_sp64"
8768   [(set (match_operand:DI 0 "register_operand" "=r")
8769         (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8770                                                      (match_operand 3 "tld_symbolic_operand" "")]
8771                                                     UNSPEC_TLSLDO)
8772                                          (match_operand:DI 1 "register_operand" "r")))))]
8773   "TARGET_TLS && TARGET_ARCH64"
8774   "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8775   [(set_attr "type" "load")])
8776
8777 (define_insn "*tldo_ldsw1_sp64"
8778   [(set (match_operand:DI 0 "register_operand" "=r")
8779         (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8780                                                      (match_operand 3 "tld_symbolic_operand" "")]
8781                                                     UNSPEC_TLSLDO)
8782                                          (match_operand:DI 1 "register_operand" "r")))))]
8783   "TARGET_TLS && TARGET_ARCH64"
8784   "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
8785   [(set_attr "type" "sload")
8786    (set_attr "us3load_type" "3cycle")])
8787
8788 (define_insn "*tldo_ldx_sp64"
8789   [(set (match_operand:DI 0 "register_operand" "=r")
8790         (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8791                                      (match_operand 3 "tld_symbolic_operand" "")]
8792                                     UNSPEC_TLSLDO)
8793                          (match_operand:DI 1 "register_operand" "r"))))]
8794   "TARGET_TLS && TARGET_ARCH64"
8795   "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
8796   [(set_attr "type" "load")])
8797
8798 (define_insn "*tldo_stb_sp32"
8799   [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8800                                      (match_operand 3 "tld_symbolic_operand" "")]
8801                                     UNSPEC_TLSLDO)
8802                          (match_operand:SI 1 "register_operand" "r")))
8803         (match_operand:QI 0 "register_operand" "=r"))]
8804   "TARGET_TLS && TARGET_ARCH32"
8805   "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8806   [(set_attr "type" "store")])
8807
8808 (define_insn "*tldo_stb_sp64"
8809   [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8810                                      (match_operand 3 "tld_symbolic_operand" "")]
8811                                     UNSPEC_TLSLDO)
8812                          (match_operand:DI 1 "register_operand" "r")))
8813         (match_operand:QI 0 "register_operand" "=r"))]
8814   "TARGET_TLS && TARGET_ARCH64"
8815   "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8816   [(set_attr "type" "store")])
8817
8818 (define_insn "*tldo_sth_sp32"
8819   [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8820                                      (match_operand 3 "tld_symbolic_operand" "")]
8821                                     UNSPEC_TLSLDO)
8822                          (match_operand:SI 1 "register_operand" "r")))
8823         (match_operand:HI 0 "register_operand" "=r"))]
8824   "TARGET_TLS && TARGET_ARCH32"
8825   "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8826   [(set_attr "type" "store")])
8827
8828 (define_insn "*tldo_sth_sp64"
8829   [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8830                                      (match_operand 3 "tld_symbolic_operand" "")]
8831                                     UNSPEC_TLSLDO)
8832                          (match_operand:DI 1 "register_operand" "r")))
8833         (match_operand:HI 0 "register_operand" "=r"))]
8834   "TARGET_TLS && TARGET_ARCH64"
8835   "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8836   [(set_attr "type" "store")])
8837
8838 (define_insn "*tldo_stw_sp32"
8839   [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8840                                      (match_operand 3 "tld_symbolic_operand" "")]
8841                                     UNSPEC_TLSLDO)
8842                          (match_operand:SI 1 "register_operand" "r")))
8843         (match_operand:SI 0 "register_operand" "=r"))]
8844   "TARGET_TLS && TARGET_ARCH32"
8845   "st\t%0, [%1 + %2], %%tldo_add(%3)"
8846   [(set_attr "type" "store")])
8847
8848 (define_insn "*tldo_stw_sp64"
8849   [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8850                                      (match_operand 3 "tld_symbolic_operand" "")]
8851                                     UNSPEC_TLSLDO)
8852                          (match_operand:DI 1 "register_operand" "r")))
8853         (match_operand:SI 0 "register_operand" "=r"))]
8854   "TARGET_TLS && TARGET_ARCH64"
8855   "stw\t%0, [%1 + %2], %%tldo_add(%3)"
8856   [(set_attr "type" "store")])
8857
8858 (define_insn "*tldo_stx_sp64"
8859   [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8860                                      (match_operand 3 "tld_symbolic_operand" "")]
8861                                     UNSPEC_TLSLDO)
8862                          (match_operand:DI 1 "register_operand" "r")))
8863         (match_operand:DI 0 "register_operand" "=r"))]
8864   "TARGET_TLS && TARGET_ARCH64"
8865   "stx\t%0, [%1 + %2], %%tldo_add(%3)"
8866   [(set_attr "type" "store")])
8867
8868 ;; Vector instructions.
8869
8870 (define_insn "addv2si3"
8871   [(set (match_operand:V2SI 0 "register_operand" "=e")
8872         (plus:V2SI (match_operand:V2SI 1 "register_operand" "e")
8873                    (match_operand:V2SI 2 "register_operand" "e")))]
8874   "TARGET_VIS"
8875   "fpadd32\t%1, %2, %0"
8876   [(set_attr "type" "fga")
8877    (set_attr "fptype" "double")])
8878
8879 (define_insn "addv4hi3"
8880   [(set (match_operand:V4HI 0 "register_operand" "=e")
8881          (plus:V4HI (match_operand:V4HI 1 "register_operand" "e")
8882                     (match_operand:V4HI 2 "register_operand" "e")))]
8883   "TARGET_VIS"
8884   "fpadd16\t%1, %2, %0"
8885   [(set_attr "type" "fga")
8886    (set_attr "fptype" "double")])
8887
8888 ;; fpadd32s is emitted by the addsi3 pattern.
8889
8890 (define_insn "addv2hi3"
8891   [(set (match_operand:V2HI 0 "register_operand" "=f")
8892         (plus:V2HI (match_operand:V2HI 1 "register_operand" "f")
8893                    (match_operand:V2HI 2 "register_operand" "f")))]
8894   "TARGET_VIS"
8895   "fpadd16s\t%1, %2, %0"
8896   [(set_attr "type" "fga")
8897    (set_attr "fptype" "single")])
8898
8899 (define_insn "subv2si3"
8900   [(set (match_operand:V2SI 0 "register_operand" "=e")
8901         (minus:V2SI (match_operand:V2SI 1 "register_operand" "e")
8902                     (match_operand:V2SI 2 "register_operand" "e")))]
8903   "TARGET_VIS"
8904   "fpsub32\t%1, %2, %0"
8905   [(set_attr "type" "fga")
8906    (set_attr "fptype" "double")])
8907
8908 (define_insn "subv4hi3"
8909   [(set (match_operand:V4HI 0 "register_operand" "=e")
8910         (minus:V4HI (match_operand:V4HI 1 "register_operand" "e")
8911                     (match_operand:V4HI 2 "register_operand" "e")))]
8912   "TARGET_VIS"
8913   "fpsub16\t%1, %2, %0"
8914   [(set_attr "type" "fga")
8915    (set_attr "fptype" "double")])
8916
8917 ;; fpsub32s is emitted by the subsi3 pattern.
8918
8919 (define_insn "subv2hi3"
8920   [(set (match_operand:V2HI 0 "register_operand" "=f")
8921         (minus:V2HI (match_operand:V2HI 1 "register_operand" "f")
8922                     (match_operand:V2HI 2 "register_operand" "f")))]
8923   "TARGET_VIS"
8924   "fpsub16s\t%1, %2, %0"
8925   [(set_attr "type" "fga")
8926    (set_attr "fptype" "single")])
8927
8928 ;; All other logical instructions have integer equivalents so they
8929 ;; are defined together.
8930
8931 ;; (ior (not (op1)) (not (op2))) is the canonical form of NAND.
8932
8933 (define_insn "*nand<V64mode>_vis"
8934   [(set (match_operand:V64 0 "register_operand" "=e")
8935         (ior:V64 (not:V64 (match_operand:V64 1 "register_operand" "e"))
8936                  (not:V64 (match_operand:V64 2 "register_operand" "e"))))]
8937   "TARGET_VIS"
8938   "fnand\t%1, %2, %0"
8939   [(set_attr "type" "fga")
8940    (set_attr "fptype" "double")])
8941
8942 (define_insn "*nand<V32mode>_vis"
8943   [(set (match_operand:V32 0 "register_operand" "=f")
8944          (ior:V32 (not:V32 (match_operand:V32 1 "register_operand" "f"))
8945                   (not:V32 (match_operand:V32 2 "register_operand" "f"))))]
8946   "TARGET_VIS"
8947   "fnands\t%1, %2, %0"
8948   [(set_attr "type" "fga")
8949    (set_attr "fptype" "single")])
8950
8951 ;; Hard to generate VIS instructions.  We have builtins for these.
8952
8953 (define_insn "fpack16_vis"
8954   [(set (match_operand:V4QI 0 "register_operand" "=f")
8955         (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e")]
8956                       UNSPEC_FPACK16))]
8957   "TARGET_VIS"
8958   "fpack16\t%1, %0"
8959   [(set_attr "type" "fga")
8960    (set_attr "fptype" "double")])
8961
8962 (define_insn "fpackfix_vis"
8963   [(set (match_operand:V2HI 0 "register_operand" "=f")
8964         (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e")]
8965                       UNSPEC_FPACKFIX))]
8966   "TARGET_VIS"
8967   "fpackfix\t%1, %0"
8968   [(set_attr "type" "fga")
8969    (set_attr "fptype" "double")])
8970
8971 (define_insn "fpack32_vis"
8972   [(set (match_operand:V8QI 0 "register_operand" "=e")
8973         (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e")
8974                       (match_operand:V8QI 2 "register_operand" "e")]
8975                      UNSPEC_FPACK32))]
8976   "TARGET_VIS"
8977   "fpack32\t%1, %2, %0"
8978   [(set_attr "type" "fga")
8979    (set_attr "fptype" "double")])
8980
8981 (define_insn "fexpand_vis"
8982   [(set (match_operand:V4HI 0 "register_operand" "=e")
8983         (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")]
8984          UNSPEC_FEXPAND))]
8985  "TARGET_VIS"
8986  "fexpand\t%1, %0"
8987  [(set_attr "type" "fga")
8988   (set_attr "fptype" "double")])
8989
8990 ;; It may be possible to describe this operation as (1 indexed):
8991 ;; (vec_select (vec_duplicate (vec_duplicate (vec_concat 1 2)))
8992 ;;  1,5,10,14,19,23,28,32)
8993 ;; Note that (vec_merge:V8QI [(V4QI) (V4QI)] (10101010 = 170) doesn't work
8994 ;; because vec_merge expects all the operands to be of the same type.
8995 (define_insn "fpmerge_vis"
8996   [(set (match_operand:V8QI 0 "register_operand" "=e")
8997         (unspec:V8QI [(match_operand:V4QI 1 "register_operand" "f")
8998                       (match_operand:V4QI 2 "register_operand" "f")]
8999          UNSPEC_FPMERGE))]
9000  "TARGET_VIS"
9001  "fpmerge\t%1, %2, %0"
9002  [(set_attr "type" "fga")
9003   (set_attr "fptype" "double")])
9004
9005 ;; Partitioned multiply instructions
9006 (define_insn "fmul8x16_vis"
9007   [(set (match_operand:V4HI 0 "register_operand" "=e")
9008         (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
9009                    (match_operand:V4HI 2 "register_operand" "e")))]
9010   "TARGET_VIS"
9011   "fmul8x16\t%1, %2, %0"
9012   [(set_attr "type" "fpmul")
9013    (set_attr "fptype" "double")])
9014
9015 ;; Only one of the following two insns can be a multiply.
9016 (define_insn "fmul8x16au_vis"
9017   [(set (match_operand:V4HI 0 "register_operand" "=e")
9018         (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
9019                    (match_operand:V2HI 2 "register_operand" "f")))]
9020   "TARGET_VIS"
9021   "fmul8x16au\t%1, %2, %0"
9022   [(set_attr "type" "fpmul")
9023    (set_attr "fptype" "double")])
9024
9025 (define_insn "fmul8x16al_vis"
9026   [(set (match_operand:V4HI 0 "register_operand" "=e")
9027         (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
9028                       (match_operand:V2HI 2 "register_operand" "f")]
9029          UNSPEC_MUL16AL))]
9030   "TARGET_VIS"
9031   "fmul8x16al\t%1, %2, %0"
9032   [(set_attr "type" "fpmul")
9033    (set_attr "fptype" "double")])
9034
9035 ;; Only one of the following two insns can be a multiply.
9036 (define_insn "fmul8sux16_vis"
9037   [(set (match_operand:V4HI 0 "register_operand" "=e")
9038         (mult:V4HI (match_operand:V8QI 1 "register_operand" "e")
9039                    (match_operand:V4HI 2 "register_operand" "e")))]
9040   "TARGET_VIS"
9041   "fmul8sux16\t%1, %2, %0"
9042   [(set_attr "type" "fpmul")
9043    (set_attr "fptype" "double")])
9044
9045 (define_insn "fmul8ulx16_vis"
9046   [(set (match_operand:V4HI 0 "register_operand" "=e")
9047         (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
9048                       (match_operand:V4HI 2 "register_operand" "e")]
9049          UNSPEC_MUL8UL))]
9050   "TARGET_VIS"
9051   "fmul8ulx16\t%1, %2, %0"
9052   [(set_attr "type" "fpmul")
9053    (set_attr "fptype" "double")])
9054
9055 ;; Only one of the following two insns can be a multiply.
9056 (define_insn "fmuld8sux16_vis"
9057   [(set (match_operand:V2SI 0 "register_operand" "=e")
9058         (mult:V2SI (match_operand:V4QI 1 "register_operand" "f")
9059                    (match_operand:V2HI 2 "register_operand" "f")))]
9060   "TARGET_VIS"
9061   "fmuld8sux16\t%1, %2, %0"
9062   [(set_attr "type" "fpmul")
9063    (set_attr "fptype" "double")])
9064
9065 (define_insn "fmuld8ulx16_vis"
9066   [(set (match_operand:V2SI 0 "register_operand" "=e")
9067         (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
9068                       (match_operand:V2HI 2 "register_operand" "f")]
9069          UNSPEC_MULDUL))]
9070   "TARGET_VIS"
9071   "fmuld8ulx16\t%1, %2, %0"
9072   [(set_attr "type" "fpmul")
9073    (set_attr "fptype" "double")])
9074
9075 ;; Using faligndata only makes sense after an alignaddr since the choice of
9076 ;; bytes to take out of each operand is dependant on the results of the last
9077 ;; alignaddr.
9078 (define_insn "faligndata<V64I:mode>_vis"
9079   [(set (match_operand:V64I 0 "register_operand" "=e")
9080         (unspec:V64I [(match_operand:V64I 1 "register_operand" "e")
9081                       (match_operand:V64I 2 "register_operand" "e")]
9082          UNSPEC_ALIGNDATA))]
9083   "TARGET_VIS"
9084   "faligndata\t%1, %2, %0"
9085   [(set_attr "type" "fga")
9086    (set_attr "fptype" "double")])
9087
9088 (define_insn "alignaddr<P:mode>_vis"
9089   [(set (match_operand:P 0 "register_operand" "=r")
9090         (unspec:P [(match_operand:P 1 "reg_or_0_operand" "rJ")
9091                    (match_operand:P 2 "reg_or_0_operand" "rJ")]
9092          UNSPEC_ALIGNADDR))]
9093   "TARGET_VIS"
9094   "alignaddr\t%r1, %r2, %0")
9095
9096 (define_insn "pdist_vis"
9097   [(set (match_operand:DI 0 "register_operand" "=e")
9098         (unspec:DI [(match_operand:V8QI 1 "register_operand" "e")
9099                     (match_operand:V8QI 2 "register_operand" "e")
9100                     (match_operand:DI 3 "register_operand" "0")]
9101          UNSPEC_PDIST))]
9102   "TARGET_VIS"
9103   "pdist\t%1, %2, %0"
9104   [(set_attr "type" "fga")
9105    (set_attr "fptype" "double")])