OSDN Git Service

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