OSDN Git Service

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