OSDN Git Service

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