OSDN Git Service

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