OSDN Git Service

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