OSDN Git Service

* doc/invoke.texi (SPARC options): Remove -mflat and
[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 "register_operand" ""))]
4666   "TARGET_ARCH64 && TARGET_FPU"
4667   "sparc_emit_floatunsdi (operands); 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 "register_operand" ""))]
4680   "TARGET_ARCH64 && TARGET_FPU"
4681   "sparc_emit_floatunsdi (operands); 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_insn "fix_truncdfdi2"
4751   [(set (match_operand:DI 0 "register_operand" "=e")
4752         (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4753   "TARGET_V9 && TARGET_FPU"
4754   "fdtox\t%1, %0"
4755   [(set_attr "type" "fp")
4756    (set_attr "fptype" "double")])
4757
4758 (define_expand "fix_trunctfdi2"
4759   [(set (match_operand:DI 0 "register_operand" "")
4760         (fix:DI (match_operand:TF 1 "general_operand" "")))]
4761   "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4762   "emit_tfmode_cvt (FIX, operands); DONE;")
4763
4764 (define_insn "*fix_trunctfdi2_hq"
4765   [(set (match_operand:DI 0 "register_operand" "=e")
4766         (fix:DI (match_operand:TF 1 "register_operand" "e")))]
4767   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4768   "fqtox\t%1, %0"
4769   [(set_attr "type" "fp")])
4770
4771 (define_expand "fixuns_trunctfdi2"
4772   [(set (match_operand:DI 0 "register_operand" "")
4773         (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
4774   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4775   "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4776 \f
4777 ;;- arithmetic instructions
4778
4779 (define_expand "adddi3"
4780   [(set (match_operand:DI 0 "register_operand" "")
4781         (plus:DI (match_operand:DI 1 "register_operand" "")
4782                  (match_operand:DI 2 "arith_double_add_operand" "")))]
4783   ""
4784 {
4785   if (! TARGET_ARCH64)
4786     {
4787       emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4788                           gen_rtx_SET (VOIDmode, operands[0],
4789                                    gen_rtx_PLUS (DImode, operands[1],
4790                                                  operands[2])),
4791                           gen_rtx_CLOBBER (VOIDmode,
4792                                    gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4793       DONE;
4794     }
4795 })
4796
4797 (define_insn_and_split "adddi3_insn_sp32"
4798   [(set (match_operand:DI 0 "register_operand" "=r")
4799         (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4800                  (match_operand:DI 2 "arith_double_operand" "rHI")))
4801    (clobber (reg:CC 100))]
4802   "! TARGET_ARCH64"
4803   "#"
4804   "&& reload_completed"
4805   [(parallel [(set (reg:CC_NOOV 100)
4806                    (compare:CC_NOOV (plus:SI (match_dup 4)
4807                                              (match_dup 5))
4808                                     (const_int 0)))
4809               (set (match_dup 3)
4810                    (plus:SI (match_dup 4) (match_dup 5)))])
4811    (set (match_dup 6)
4812         (plus:SI (plus:SI (match_dup 7)
4813                           (match_dup 8))
4814                  (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4815 {
4816   operands[3] = gen_lowpart (SImode, operands[0]);
4817   operands[4] = gen_lowpart (SImode, operands[1]);
4818   operands[5] = gen_lowpart (SImode, operands[2]);
4819   operands[6] = gen_highpart (SImode, operands[0]);
4820   operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
4821 #if HOST_BITS_PER_WIDE_INT == 32
4822   if (GET_CODE (operands[2]) == CONST_INT)
4823     {
4824       if (INTVAL (operands[2]) < 0)
4825         operands[8] = constm1_rtx;
4826       else
4827         operands[8] = const0_rtx;
4828     }
4829   else
4830 #endif
4831     operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4832 }
4833   [(set_attr "length" "2")])
4834
4835 (define_split
4836   [(set (match_operand:DI 0 "register_operand" "")
4837         (minus:DI (match_operand:DI 1 "arith_double_operand" "")
4838                   (match_operand:DI 2 "arith_double_operand" "")))
4839    (clobber (reg:CC 100))]
4840   "! TARGET_ARCH64 && reload_completed"
4841   [(parallel [(set (reg:CC_NOOV 100)
4842                    (compare:CC_NOOV (minus:SI (match_dup 4)
4843                                               (match_dup 5))
4844                                     (const_int 0)))
4845               (set (match_dup 3)
4846                    (minus:SI (match_dup 4) (match_dup 5)))])
4847    (set (match_dup 6)
4848         (minus:SI (minus:SI (match_dup 7)
4849                             (match_dup 8))
4850                   (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4851 {
4852   operands[3] = gen_lowpart (SImode, operands[0]);
4853   operands[4] = gen_lowpart (SImode, operands[1]);
4854   operands[5] = gen_lowpart (SImode, operands[2]);
4855   operands[6] = gen_highpart (SImode, operands[0]);
4856   operands[7] = gen_highpart (SImode, operands[1]);
4857 #if HOST_BITS_PER_WIDE_INT == 32
4858   if (GET_CODE (operands[2]) == CONST_INT)
4859     {
4860       if (INTVAL (operands[2]) < 0)
4861         operands[8] = constm1_rtx;
4862       else
4863         operands[8] = const0_rtx;
4864     }
4865   else
4866 #endif
4867     operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4868 })
4869
4870 ;; LTU here means "carry set"
4871 (define_insn "addx"
4872   [(set (match_operand:SI 0 "register_operand" "=r")
4873         (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4874                           (match_operand:SI 2 "arith_operand" "rI"))
4875                  (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4876   ""
4877   "addx\t%1, %2, %0"
4878   [(set_attr "type" "ialuX")])
4879
4880 (define_insn_and_split "*addx_extend_sp32"
4881   [(set (match_operand:DI 0 "register_operand" "=r")
4882         (zero_extend:DI (plus:SI (plus:SI
4883                                   (match_operand:SI 1 "reg_or_0_operand" "%rJ")
4884                                   (match_operand:SI 2 "arith_operand" "rI"))
4885                                  (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4886   "! TARGET_ARCH64"
4887   "#"
4888   "&& reload_completed"
4889   [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
4890                                (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4891    (set (match_dup 4) (const_int 0))]
4892   "operands[3] = gen_lowpart (SImode, operands[0]);
4893    operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
4894   [(set_attr "length" "2")])
4895
4896 (define_insn "*addx_extend_sp64"
4897   [(set (match_operand:DI 0 "register_operand" "=r")
4898         (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
4899                                           (match_operand:SI 2 "arith_operand" "rI"))
4900                                  (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4901   "TARGET_ARCH64"
4902   "addx\t%r1, %2, %0"
4903   [(set_attr "type" "ialuX")])
4904
4905 (define_insn "subx"
4906   [(set (match_operand:SI 0 "register_operand" "=r")
4907         (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4908                             (match_operand:SI 2 "arith_operand" "rI"))
4909                   (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4910   ""
4911   "subx\t%r1, %2, %0"
4912   [(set_attr "type" "ialuX")])
4913
4914 (define_insn "*subx_extend_sp64"
4915   [(set (match_operand:DI 0 "register_operand" "=r")
4916         (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4917                                             (match_operand:SI 2 "arith_operand" "rI"))
4918                                   (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4919   "TARGET_ARCH64"
4920   "subx\t%r1, %2, %0"
4921   [(set_attr "type" "ialuX")])
4922
4923 (define_insn_and_split "*subx_extend"
4924   [(set (match_operand:DI 0 "register_operand" "=r")
4925         (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4926                                             (match_operand:SI 2 "arith_operand" "rI"))
4927                                   (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4928   "! TARGET_ARCH64"
4929   "#"
4930   "&& reload_completed"
4931   [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
4932                                 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4933    (set (match_dup 4) (const_int 0))]
4934   "operands[3] = gen_lowpart (SImode, operands[0]);
4935    operands[4] = gen_highpart (SImode, operands[0]);"
4936   [(set_attr "length" "2")])
4937
4938 (define_insn_and_split ""
4939   [(set (match_operand:DI 0 "register_operand" "=r")
4940         (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4941                  (match_operand:DI 2 "register_operand" "r")))
4942    (clobber (reg:CC 100))]
4943   "! TARGET_ARCH64"
4944   "#"
4945   "&& reload_completed"
4946   [(parallel [(set (reg:CC_NOOV 100)
4947                    (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
4948                                     (const_int 0)))
4949               (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
4950    (set (match_dup 6)
4951         (plus:SI (plus:SI (match_dup 4) (const_int 0))
4952                  (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4953   "operands[3] = gen_lowpart (SImode, operands[2]);
4954    operands[4] = gen_highpart (SImode, operands[2]);
4955    operands[5] = gen_lowpart (SImode, operands[0]);
4956    operands[6] = gen_highpart (SImode, operands[0]);"
4957   [(set_attr "length" "2")])
4958
4959 (define_insn "*adddi3_sp64"
4960   [(set (match_operand:DI 0 "register_operand" "=r,r")
4961         (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
4962                  (match_operand:DI 2 "arith_double_add_operand" "rHI,O")))]
4963   "TARGET_ARCH64"
4964   "@
4965    add\t%1, %2, %0
4966    sub\t%1, -%2, %0")
4967
4968 (define_insn "addsi3"
4969   [(set (match_operand:SI 0 "register_operand" "=r,r,d")
4970         (plus:SI (match_operand:SI 1 "register_operand" "%r,r,d")
4971                  (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
4972   ""
4973   "@
4974    add\t%1, %2, %0
4975    sub\t%1, -%2, %0
4976    fpadd32s\t%1, %2, %0"
4977   [(set_attr "type" "*,*,fga")])
4978
4979 (define_insn "*cmp_cc_plus"
4980   [(set (reg:CC_NOOV 100)
4981         (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
4982                                   (match_operand:SI 1 "arith_operand" "rI"))
4983                          (const_int 0)))]
4984   ""
4985   "addcc\t%0, %1, %%g0"
4986   [(set_attr "type" "compare")])
4987
4988 (define_insn "*cmp_ccx_plus"
4989   [(set (reg:CCX_NOOV 100)
4990         (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_double_operand" "%r")
4991                                    (match_operand:DI 1 "arith_double_operand" "rHI"))
4992                           (const_int 0)))]
4993   "TARGET_ARCH64"
4994   "addcc\t%0, %1, %%g0"
4995   [(set_attr "type" "compare")])
4996
4997 (define_insn "*cmp_cc_plus_set"
4998   [(set (reg:CC_NOOV 100)
4999         (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5000                                   (match_operand:SI 2 "arith_operand" "rI"))
5001                          (const_int 0)))
5002    (set (match_operand:SI 0 "register_operand" "=r")
5003         (plus:SI (match_dup 1) (match_dup 2)))]
5004   ""
5005   "addcc\t%1, %2, %0"
5006   [(set_attr "type" "compare")])
5007
5008 (define_insn "*cmp_ccx_plus_set"
5009   [(set (reg:CCX_NOOV 100)
5010         (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5011                                    (match_operand:DI 2 "arith_double_operand" "rHI"))
5012                           (const_int 0)))
5013    (set (match_operand:DI 0 "register_operand" "=r")
5014         (plus:DI (match_dup 1) (match_dup 2)))]
5015   "TARGET_ARCH64"
5016   "addcc\t%1, %2, %0"
5017   [(set_attr "type" "compare")])
5018
5019 (define_expand "subdi3"
5020   [(set (match_operand:DI 0 "register_operand" "")
5021         (minus:DI (match_operand:DI 1 "register_operand" "")
5022                   (match_operand:DI 2 "arith_double_add_operand" "")))]
5023   ""
5024 {
5025   if (! TARGET_ARCH64)
5026     {
5027       emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5028                           gen_rtx_SET (VOIDmode, operands[0],
5029                                    gen_rtx_MINUS (DImode, operands[1],
5030                                                   operands[2])),
5031                           gen_rtx_CLOBBER (VOIDmode,
5032                                    gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5033       DONE;
5034     }
5035 })
5036
5037 (define_insn_and_split "*subdi3_sp32"
5038   [(set (match_operand:DI 0 "register_operand" "=r")
5039         (minus:DI (match_operand:DI 1 "register_operand" "r")
5040                   (match_operand:DI 2 "arith_double_operand" "rHI")))
5041    (clobber (reg:CC 100))]
5042   "! TARGET_ARCH64"
5043   "#"
5044   "&& reload_completed
5045    && (GET_CODE (operands[2]) == CONST_INT
5046        || GET_CODE (operands[2]) == CONST_DOUBLE)"
5047   [(clobber (const_int 0))]
5048 {
5049   rtx highp, lowp;
5050
5051   highp = gen_highpart_mode (SImode, DImode, operands[2]);
5052   lowp = gen_lowpart (SImode, operands[2]);
5053   if ((lowp == const0_rtx)
5054       && (operands[0] == operands[1]))
5055     {
5056       emit_insn (gen_rtx_SET (VOIDmode,
5057                               gen_highpart (SImode, operands[0]),
5058                               gen_rtx_MINUS (SImode,
5059                                              gen_highpart_mode (SImode, DImode,
5060                                                                 operands[1]),
5061                                              highp)));
5062     }
5063   else
5064     {
5065       emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5066                                        gen_lowpart (SImode, operands[1]),
5067                                        lowp));
5068       emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5069                            gen_highpart_mode (SImode, DImode, operands[1]),
5070                            highp));
5071     }
5072   DONE;
5073 }
5074   [(set_attr "length" "2")])
5075
5076 (define_split
5077   [(set (match_operand:DI 0 "register_operand" "")
5078         (minus:DI (match_operand:DI 1 "register_operand" "")
5079                   (match_operand:DI 2 "register_operand" "")))
5080    (clobber (reg:CC 100))]
5081   "! TARGET_ARCH64
5082    && reload_completed"
5083   [(clobber (const_int 0))]
5084 {
5085   emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5086                                    gen_lowpart (SImode, operands[1]),
5087                                    gen_lowpart (SImode, operands[2])));
5088   emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5089                        gen_highpart (SImode, operands[1]),
5090                        gen_highpart (SImode, operands[2])));
5091   DONE;
5092 })
5093
5094 (define_insn_and_split ""
5095   [(set (match_operand:DI 0 "register_operand" "=r")
5096       (minus:DI (match_operand:DI 1 "register_operand" "r")
5097                 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
5098    (clobber (reg:CC 100))]
5099   "! TARGET_ARCH64"
5100   "#"
5101   "&& reload_completed"
5102   [(parallel [(set (reg:CC_NOOV 100)
5103                    (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
5104                                     (const_int 0)))
5105               (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
5106    (set (match_dup 6)
5107         (minus:SI (minus:SI (match_dup 4) (const_int 0))
5108                   (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5109   "operands[3] = gen_lowpart (SImode, operands[1]);
5110    operands[4] = gen_highpart (SImode, operands[1]);
5111    operands[5] = gen_lowpart (SImode, operands[0]);
5112    operands[6] = gen_highpart (SImode, operands[0]);"
5113   [(set_attr "length" "2")])
5114
5115 (define_insn "*subdi3_sp64"
5116   [(set (match_operand:DI 0 "register_operand" "=r,r")
5117         (minus:DI (match_operand:DI 1 "register_operand" "r,r")
5118                   (match_operand:DI 2 "arith_double_add_operand" "rHI,O")))]
5119   "TARGET_ARCH64"
5120   "@
5121    sub\t%1, %2, %0
5122    add\t%1, -%2, %0")
5123
5124 (define_insn "subsi3"
5125   [(set (match_operand:SI 0 "register_operand" "=r,r,d")
5126         (minus:SI (match_operand:SI 1 "register_operand" "r,r,d")
5127                   (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
5128   ""
5129   "@
5130    sub\t%1, %2, %0
5131    add\t%1, -%2, %0
5132    fpsub32s\t%1, %2, %0"
5133   [(set_attr "type" "*,*,fga")])
5134
5135 (define_insn "*cmp_minus_cc"
5136   [(set (reg:CC_NOOV 100)
5137         (compare:CC_NOOV (minus:SI (match_operand:SI 0 "reg_or_0_operand" "rJ")
5138                                    (match_operand:SI 1 "arith_operand" "rI"))
5139                          (const_int 0)))]
5140   ""
5141   "subcc\t%r0, %1, %%g0"
5142   [(set_attr "type" "compare")])
5143
5144 (define_insn "*cmp_minus_ccx"
5145   [(set (reg:CCX_NOOV 100)
5146         (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
5147                                     (match_operand:DI 1 "arith_double_operand" "rHI"))
5148                           (const_int 0)))]
5149   "TARGET_ARCH64"
5150   "subcc\t%0, %1, %%g0"
5151   [(set_attr "type" "compare")])
5152
5153 (define_insn "cmp_minus_cc_set"
5154   [(set (reg:CC_NOOV 100)
5155         (compare:CC_NOOV (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5156                                    (match_operand:SI 2 "arith_operand" "rI"))
5157                          (const_int 0)))
5158    (set (match_operand:SI 0 "register_operand" "=r")
5159         (minus:SI (match_dup 1) (match_dup 2)))]
5160   ""
5161   "subcc\t%r1, %2, %0"
5162   [(set_attr "type" "compare")])
5163
5164 (define_insn "*cmp_minus_ccx_set"
5165   [(set (reg:CCX_NOOV 100)
5166         (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
5167                                     (match_operand:DI 2 "arith_double_operand" "rHI"))
5168                           (const_int 0)))
5169    (set (match_operand:DI 0 "register_operand" "=r")
5170         (minus:DI (match_dup 1) (match_dup 2)))]
5171   "TARGET_ARCH64"
5172   "subcc\t%1, %2, %0"
5173   [(set_attr "type" "compare")])
5174 \f
5175 ;; Integer Multiply/Divide.
5176
5177 ;; The 32 bit multiply/divide instructions are deprecated on v9, but at
5178 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
5179
5180 (define_insn "mulsi3"
5181   [(set (match_operand:SI 0 "register_operand" "=r")
5182         (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5183                  (match_operand:SI 2 "arith_operand" "rI")))]
5184   "TARGET_HARD_MUL"
5185   "smul\t%1, %2, %0"
5186   [(set_attr "type" "imul")])
5187
5188 (define_expand "muldi3"
5189   [(set (match_operand:DI 0 "register_operand" "=r")
5190         (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5191                  (match_operand:DI 2 "arith_double_operand" "rHI")))]
5192   "TARGET_ARCH64 || TARGET_V8PLUS"
5193 {
5194   if (TARGET_V8PLUS)
5195     {
5196       emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
5197       DONE;
5198     }
5199 })
5200
5201 (define_insn "*muldi3_sp64"
5202   [(set (match_operand:DI 0 "register_operand" "=r")
5203         (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5204                  (match_operand:DI 2 "arith_double_operand" "rHI")))]
5205   "TARGET_ARCH64"
5206   "mulx\t%1, %2, %0"
5207   [(set_attr "type" "imul")])
5208
5209 ;; V8plus wide multiply.
5210 ;; XXX
5211 (define_insn "muldi3_v8plus"
5212   [(set (match_operand:DI 0 "register_operand" "=r,h")
5213         (mult:DI (match_operand:DI 1 "arith_double_operand" "%r,0")
5214                  (match_operand:DI 2 "arith_double_operand" "rI,rI")))
5215    (clobber (match_scratch:SI 3 "=&h,X"))
5216    (clobber (match_scratch:SI 4 "=&h,X"))]
5217   "TARGET_V8PLUS"
5218 {
5219   if (sparc_check_64 (operands[1], insn) <= 0)
5220     output_asm_insn ("srl\t%L1, 0, %L1", operands);
5221   if (which_alternative == 1)
5222     output_asm_insn ("sllx\t%H1, 32, %H1", operands);
5223   if (GET_CODE (operands[2]) == CONST_INT)
5224     {
5225       if (which_alternative == 1)
5226         return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %2, %L0\;srlx\t%L0, 32, %H0";
5227       else
5228         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";
5229     }
5230   else if (rtx_equal_p (operands[1], operands[2]))
5231     {
5232       if (which_alternative == 1)
5233         return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %H1, %L0\;srlx\t%L0, 32, %H0";
5234       else
5235         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";
5236     }
5237   if (sparc_check_64 (operands[2], insn) <= 0)
5238     output_asm_insn ("srl\t%L2, 0, %L2", operands);
5239   if (which_alternative == 1)
5240     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";
5241   else
5242     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";
5243 }
5244   [(set_attr "type" "multi")
5245    (set_attr "length" "9,8")])
5246
5247 (define_insn "*cmp_mul_set"
5248   [(set (reg:CC 100)
5249         (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5250                     (match_operand:SI 2 "arith_operand" "rI"))
5251                     (const_int 0)))
5252    (set (match_operand:SI 0 "register_operand" "=r")
5253         (mult:SI (match_dup 1) (match_dup 2)))]
5254   "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
5255   "smulcc\t%1, %2, %0"
5256   [(set_attr "type" "imul")])
5257
5258 (define_expand "mulsidi3"
5259   [(set (match_operand:DI 0 "register_operand" "")
5260         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5261                  (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
5262   "TARGET_HARD_MUL"
5263 {
5264   if (CONSTANT_P (operands[2]))
5265     {
5266       if (TARGET_V8PLUS)
5267         emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
5268                                               operands[2]));
5269       else if (TARGET_ARCH32)
5270         emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
5271                                             operands[2]));
5272       else 
5273         emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
5274                                             operands[2]));
5275       DONE;
5276     }
5277   if (TARGET_V8PLUS)
5278     {
5279       emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
5280       DONE;
5281     }
5282 })
5283
5284 ;; V9 puts the 64 bit product in a 64 bit register.  Only out or global
5285 ;; registers can hold 64 bit values in the V8plus environment.
5286 ;; XXX
5287 (define_insn "mulsidi3_v8plus"
5288   [(set (match_operand:DI 0 "register_operand" "=h,r")
5289         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5290                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5291    (clobber (match_scratch:SI 3 "=X,&h"))]
5292   "TARGET_V8PLUS"
5293   "@
5294    smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5295    smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5296   [(set_attr "type" "multi")
5297    (set_attr "length" "2,3")])
5298
5299 ;; XXX
5300 (define_insn "const_mulsidi3_v8plus"
5301   [(set (match_operand:DI 0 "register_operand" "=h,r")
5302         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5303                  (match_operand:DI 2 "small_int" "I,I")))
5304    (clobber (match_scratch:SI 3 "=X,&h"))]
5305   "TARGET_V8PLUS"
5306   "@
5307    smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5308    smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5309   [(set_attr "type" "multi")
5310    (set_attr "length" "2,3")])
5311
5312 ;; XXX
5313 (define_insn "*mulsidi3_sp32"
5314   [(set (match_operand:DI 0 "register_operand" "=r")
5315         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5316                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5317   "TARGET_HARD_MUL32"
5318 {
5319   return TARGET_SPARCLET
5320          ? "smuld\t%1, %2, %L0"
5321          : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
5322 }
5323   [(set (attr "type")
5324         (if_then_else (eq_attr "isa" "sparclet")
5325                       (const_string "imul") (const_string "multi")))
5326    (set (attr "length")
5327         (if_then_else (eq_attr "isa" "sparclet")
5328                       (const_int 1) (const_int 2)))])
5329
5330 (define_insn "*mulsidi3_sp64"
5331   [(set (match_operand:DI 0 "register_operand" "=r")
5332         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5333                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5334   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5335   "smul\t%1, %2, %0"
5336   [(set_attr "type" "imul")])
5337
5338 ;; Extra pattern, because sign_extend of a constant isn't valid.
5339
5340 ;; XXX
5341 (define_insn "const_mulsidi3_sp32"
5342   [(set (match_operand:DI 0 "register_operand" "=r")
5343         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5344                  (match_operand:DI 2 "small_int" "I")))]
5345   "TARGET_HARD_MUL32"
5346 {
5347   return TARGET_SPARCLET
5348          ? "smuld\t%1, %2, %L0"
5349          : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
5350 }
5351   [(set (attr "type")
5352         (if_then_else (eq_attr "isa" "sparclet")
5353                       (const_string "imul") (const_string "multi")))
5354    (set (attr "length")
5355         (if_then_else (eq_attr "isa" "sparclet")
5356                       (const_int 1) (const_int 2)))])
5357
5358 (define_insn "const_mulsidi3_sp64"
5359   [(set (match_operand:DI 0 "register_operand" "=r")
5360         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5361                  (match_operand:DI 2 "small_int" "I")))]
5362   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5363   "smul\t%1, %2, %0"
5364   [(set_attr "type" "imul")])
5365
5366 (define_expand "smulsi3_highpart"
5367   [(set (match_operand:SI 0 "register_operand" "")
5368         (truncate:SI
5369          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5370                                (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
5371                       (const_int 32))))]
5372   "TARGET_HARD_MUL && TARGET_ARCH32"
5373 {
5374   if (CONSTANT_P (operands[2]))
5375     {
5376       if (TARGET_V8PLUS)
5377         {
5378           emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
5379                                                         operands[1],
5380                                                         operands[2],
5381                                                         GEN_INT (32)));
5382           DONE;
5383         }
5384       emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
5385       DONE;
5386     }
5387   if (TARGET_V8PLUS)
5388     {
5389       emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
5390                                               operands[2], GEN_INT (32)));
5391       DONE;
5392     }
5393 })
5394
5395 ;; XXX
5396 (define_insn "smulsi3_highpart_v8plus"
5397   [(set (match_operand:SI 0 "register_operand" "=h,r")
5398         (truncate:SI
5399          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5400                                (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5401                       (match_operand:SI 3 "const_int_operand" "i,i"))))
5402    (clobber (match_scratch:SI 4 "=X,&h"))]
5403   "TARGET_V8PLUS"
5404   "@
5405    smul\t%1, %2, %0\;srlx\t%0, %3, %0
5406    smul\t%1, %2, %4\;srlx\t%4, %3, %0"
5407   [(set_attr "type" "multi")
5408    (set_attr "length" "2")])
5409
5410 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
5411 ;; XXX
5412 (define_insn ""
5413   [(set (match_operand:SI 0 "register_operand" "=h,r")
5414         (subreg:SI
5415          (lshiftrt:DI
5416           (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5417                    (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5418           (match_operand:SI 3 "const_int_operand" "i,i"))
5419          4))
5420    (clobber (match_scratch:SI 4 "=X,&h"))]
5421   "TARGET_V8PLUS"
5422   "@
5423    smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5424    smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5425   [(set_attr "type" "multi")
5426    (set_attr "length" "2")])
5427
5428 ;; XXX
5429 (define_insn "const_smulsi3_highpart_v8plus"
5430   [(set (match_operand:SI 0 "register_operand" "=h,r")
5431         (truncate:SI
5432          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5433                                (match_operand:DI 2 "small_int" "i,i"))
5434                       (match_operand:SI 3 "const_int_operand" "i,i"))))
5435    (clobber (match_scratch:SI 4 "=X,&h"))]
5436   "TARGET_V8PLUS"
5437   "@
5438    smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5439    smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5440   [(set_attr "type" "multi")
5441    (set_attr "length" "2")])
5442
5443 ;; XXX
5444 (define_insn "*smulsi3_highpart_sp32"
5445   [(set (match_operand:SI 0 "register_operand" "=r")
5446         (truncate:SI
5447          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5448                                (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
5449                       (const_int 32))))]
5450   "TARGET_HARD_MUL32"
5451   "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
5452   [(set_attr "type" "multi")
5453    (set_attr "length" "2")])
5454
5455 ;; XXX
5456 (define_insn "const_smulsi3_highpart"
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                                (match_operand:DI 2 "small_int" "i"))
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 (define_expand "umulsidi3"
5468   [(set (match_operand:DI 0 "register_operand" "")
5469         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5470                  (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
5471   "TARGET_HARD_MUL"
5472 {
5473   if (CONSTANT_P (operands[2]))
5474     {
5475       if (TARGET_V8PLUS)
5476         emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
5477                                                operands[2]));
5478       else if (TARGET_ARCH32)
5479         emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
5480                                              operands[2]));
5481       else 
5482         emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
5483                                              operands[2]));
5484       DONE;
5485     }
5486   if (TARGET_V8PLUS)
5487     {
5488       emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
5489       DONE;
5490     }
5491 })
5492
5493 ;; XXX
5494 (define_insn "umulsidi3_v8plus"
5495   [(set (match_operand:DI 0 "register_operand" "=h,r")
5496         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5497                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5498    (clobber (match_scratch:SI 3 "=X,&h"))]
5499   "TARGET_V8PLUS"
5500   "@
5501    umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5502    umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5503   [(set_attr "type" "multi")
5504    (set_attr "length" "2,3")])
5505
5506 ;; XXX
5507 (define_insn "*umulsidi3_sp32"
5508   [(set (match_operand:DI 0 "register_operand" "=r")
5509         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5510                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5511   "TARGET_HARD_MUL32"
5512 {
5513   return TARGET_SPARCLET
5514          ? "umuld\t%1, %2, %L0"
5515          : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
5516 }
5517   [(set (attr "type")
5518         (if_then_else (eq_attr "isa" "sparclet")
5519                       (const_string "imul") (const_string "multi")))
5520    (set (attr "length")
5521         (if_then_else (eq_attr "isa" "sparclet")
5522                       (const_int 1) (const_int 2)))])
5523
5524 (define_insn "*umulsidi3_sp64"
5525   [(set (match_operand:DI 0 "register_operand" "=r")
5526         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5527                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5528   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5529   "umul\t%1, %2, %0"
5530   [(set_attr "type" "imul")])
5531
5532 ;; Extra pattern, because sign_extend of a constant isn't valid.
5533
5534 ;; XXX
5535 (define_insn "const_umulsidi3_sp32"
5536   [(set (match_operand:DI 0 "register_operand" "=r")
5537         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5538                  (match_operand:DI 2 "uns_small_int" "")))]
5539   "TARGET_HARD_MUL32"
5540 {
5541   return TARGET_SPARCLET
5542          ? "umuld\t%1, %s2, %L0"
5543          : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
5544 }
5545   [(set (attr "type")
5546         (if_then_else (eq_attr "isa" "sparclet")
5547                       (const_string "imul") (const_string "multi")))
5548    (set (attr "length")
5549         (if_then_else (eq_attr "isa" "sparclet")
5550                       (const_int 1) (const_int 2)))])
5551
5552 (define_insn "const_umulsidi3_sp64"
5553   [(set (match_operand:DI 0 "register_operand" "=r")
5554         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5555                  (match_operand:DI 2 "uns_small_int" "")))]
5556   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5557   "umul\t%1, %s2, %0"
5558   [(set_attr "type" "imul")])
5559
5560 ;; XXX
5561 (define_insn "const_umulsidi3_v8plus"
5562   [(set (match_operand:DI 0 "register_operand" "=h,r")
5563         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5564                  (match_operand:DI 2 "uns_small_int" "")))
5565    (clobber (match_scratch:SI 3 "=X,h"))]
5566   "TARGET_V8PLUS"
5567   "@
5568    umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
5569    umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5570   [(set_attr "type" "multi")
5571    (set_attr "length" "2,3")])
5572
5573 (define_expand "umulsi3_highpart"
5574   [(set (match_operand:SI 0 "register_operand" "")
5575         (truncate:SI
5576          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5577                                (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
5578                       (const_int 32))))]
5579   "TARGET_HARD_MUL && TARGET_ARCH32"
5580 {
5581   if (CONSTANT_P (operands[2]))
5582     {
5583       if (TARGET_V8PLUS)
5584         {
5585           emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
5586                                                         operands[1],
5587                                                         operands[2],
5588                                                         GEN_INT (32)));
5589           DONE;
5590         }
5591       emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
5592       DONE;
5593     }
5594   if (TARGET_V8PLUS)
5595     {
5596       emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
5597                                               operands[2], GEN_INT (32)));
5598       DONE;
5599     }
5600 })
5601
5602 ;; XXX
5603 (define_insn "umulsi3_highpart_v8plus"
5604   [(set (match_operand:SI 0 "register_operand" "=h,r")
5605         (truncate:SI
5606          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5607                                (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5608                       (match_operand:SI 3 "const_int_operand" "i,i"))))
5609    (clobber (match_scratch:SI 4 "=X,h"))]
5610   "TARGET_V8PLUS"
5611   "@
5612    umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5613    umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5614   [(set_attr "type" "multi")
5615    (set_attr "length" "2")])
5616
5617 ;; XXX
5618 (define_insn "const_umulsi3_highpart_v8plus"
5619   [(set (match_operand:SI 0 "register_operand" "=h,r")
5620         (truncate:SI
5621          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5622                                (match_operand:DI 2 "uns_small_int" ""))
5623                       (match_operand:SI 3 "const_int_operand" "i,i"))))
5624    (clobber (match_scratch:SI 4 "=X,h"))]
5625   "TARGET_V8PLUS"
5626   "@
5627    umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
5628    umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
5629   [(set_attr "type" "multi")
5630    (set_attr "length" "2")])
5631
5632 ;; XXX
5633 (define_insn "*umulsi3_highpart_sp32"
5634   [(set (match_operand:SI 0 "register_operand" "=r")
5635         (truncate:SI
5636          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5637                                (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
5638                       (const_int 32))))]
5639   "TARGET_HARD_MUL32"
5640   "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
5641   [(set_attr "type" "multi")
5642    (set_attr "length" "2")])
5643
5644 ;; XXX
5645 (define_insn "const_umulsi3_highpart"
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                                (match_operand:DI 2 "uns_small_int" ""))
5650                       (const_int 32))))]
5651   "TARGET_HARD_MUL32"
5652   "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
5653   [(set_attr "type" "multi")
5654    (set_attr "length" "2")])
5655
5656 ;; The v8 architecture specifies that there must be 3 instructions between
5657 ;; a y register write and a use of it for correct results.
5658
5659 (define_expand "divsi3"
5660   [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
5661                    (div:SI (match_operand:SI 1 "register_operand" "r,r")
5662                            (match_operand:SI 2 "input_operand" "rI,m")))
5663               (clobber (match_scratch:SI 3 "=&r,&r"))])]
5664   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5665 {
5666   if (TARGET_ARCH64)
5667     {
5668       operands[3] = gen_reg_rtx(SImode);
5669       emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
5670       emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
5671                                   operands[3]));
5672       DONE;
5673     }
5674 })
5675
5676 (define_insn "divsi3_sp32"
5677   [(set (match_operand:SI 0 "register_operand" "=r,r")
5678         (div:SI (match_operand:SI 1 "register_operand" "r,r")
5679                 (match_operand:SI 2 "input_operand" "rI,m")))
5680    (clobber (match_scratch:SI 3 "=&r,&r"))]
5681   "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
5682    && TARGET_ARCH32"
5683 {
5684   if (which_alternative == 0)
5685     if (TARGET_V9)
5686       return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdiv\t%1, %2, %0";
5687     else
5688       return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
5689   else
5690     if (TARGET_V9)
5691       return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tld\t%2, %3\n\tsdiv\t%1, %3, %0";
5692     else
5693       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";
5694 }
5695   [(set_attr "type" "multi")
5696    (set (attr "length")
5697         (if_then_else (eq_attr "isa" "v9")
5698                       (const_int 4) (const_int 6)))])
5699
5700 (define_insn "divsi3_sp64"
5701   [(set (match_operand:SI 0 "register_operand" "=r")
5702         (div:SI (match_operand:SI 1 "register_operand" "r")
5703                 (match_operand:SI 2 "input_operand" "rI")))
5704    (use (match_operand:SI 3 "register_operand" "r"))]
5705   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5706   "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
5707   [(set_attr "type" "multi")
5708    (set_attr "length" "2")])
5709
5710 (define_insn "divdi3"
5711   [(set (match_operand:DI 0 "register_operand" "=r")
5712         (div:DI (match_operand:DI 1 "register_operand" "r")
5713                 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5714   "TARGET_ARCH64"
5715   "sdivx\t%1, %2, %0"
5716   [(set_attr "type" "idiv")])
5717
5718 (define_insn "*cmp_sdiv_cc_set"
5719   [(set (reg:CC 100)
5720         (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
5721                             (match_operand:SI 2 "arith_operand" "rI"))
5722                     (const_int 0)))
5723    (set (match_operand:SI 0 "register_operand" "=r")
5724         (div:SI (match_dup 1) (match_dup 2)))
5725    (clobber (match_scratch:SI 3 "=&r"))]
5726   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5727 {
5728   if (TARGET_V9)
5729     return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdivcc\t%1, %2, %0";
5730   else
5731     return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
5732 }
5733   [(set_attr "type" "multi")
5734    (set (attr "length")
5735         (if_then_else (eq_attr "isa" "v9")
5736                       (const_int 3) (const_int 6)))])
5737
5738 ;; XXX
5739 (define_expand "udivsi3"
5740   [(set (match_operand:SI 0 "register_operand" "")
5741         (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "")
5742                  (match_operand:SI 2 "input_operand" "")))]
5743   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5744   "")
5745
5746 (define_insn "udivsi3_sp32"
5747   [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
5748         (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r,r,m")
5749                  (match_operand:SI 2 "input_operand" "rI,m,r")))]
5750   "(TARGET_V8
5751     || TARGET_DEPRECATED_V8_INSNS)
5752    && TARGET_ARCH32"
5753 {
5754   output_asm_insn ("wr\t%%g0, %%g0, %%y", operands);
5755   switch (which_alternative)
5756     {
5757     default:
5758       return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
5759     case 1:
5760       return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
5761     case 2:
5762       return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
5763     }
5764 }
5765   [(set_attr "type" "multi")
5766    (set_attr "length" "5")])
5767
5768 (define_insn "udivsi3_sp64"
5769   [(set (match_operand:SI 0 "register_operand" "=r")
5770         (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r")
5771                  (match_operand:SI 2 "input_operand" "rI")))]
5772   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5773   "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
5774   [(set_attr "type" "multi")
5775    (set_attr "length" "2")])
5776
5777 (define_insn "udivdi3"
5778   [(set (match_operand:DI 0 "register_operand" "=r")
5779         (udiv:DI (match_operand:DI 1 "register_operand" "r")
5780                  (match_operand:DI 2 "arith_double_operand" "rHI")))]
5781   "TARGET_ARCH64"
5782   "udivx\t%1, %2, %0"
5783   [(set_attr "type" "idiv")])
5784
5785 (define_insn "*cmp_udiv_cc_set"
5786   [(set (reg:CC 100)
5787         (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
5788                              (match_operand:SI 2 "arith_operand" "rI"))
5789                     (const_int 0)))
5790    (set (match_operand:SI 0 "register_operand" "=r")
5791         (udiv:SI (match_dup 1) (match_dup 2)))]
5792   "TARGET_V8
5793    || TARGET_DEPRECATED_V8_INSNS"
5794 {
5795   if (TARGET_V9)
5796     return "wr\t%%g0, %%g0, %%y\n\tudivcc\t%1, %2, %0";
5797   else
5798     return "wr\t%%g0, %%g0, %%y\n\tnop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
5799 }
5800   [(set_attr "type" "multi")
5801    (set (attr "length")
5802         (if_then_else (eq_attr "isa" "v9")
5803                       (const_int 2) (const_int 5)))])
5804
5805 ; sparclet multiply/accumulate insns
5806
5807 (define_insn "*smacsi"
5808   [(set (match_operand:SI 0 "register_operand" "=r")
5809         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
5810                           (match_operand:SI 2 "arith_operand" "rI"))
5811                  (match_operand:SI 3 "register_operand" "0")))]
5812   "TARGET_SPARCLET"
5813   "smac\t%1, %2, %0"
5814   [(set_attr "type" "imul")])
5815
5816 (define_insn "*smacdi"
5817   [(set (match_operand:DI 0 "register_operand" "=r")
5818         (plus:DI (mult:DI (sign_extend:DI
5819                            (match_operand:SI 1 "register_operand" "%r"))
5820                           (sign_extend:DI
5821                            (match_operand:SI 2 "register_operand" "r")))
5822                  (match_operand:DI 3 "register_operand" "0")))]
5823   "TARGET_SPARCLET"
5824   "smacd\t%1, %2, %L0"
5825   [(set_attr "type" "imul")])
5826
5827 (define_insn "*umacdi"
5828   [(set (match_operand:DI 0 "register_operand" "=r")
5829         (plus:DI (mult:DI (zero_extend:DI
5830                            (match_operand:SI 1 "register_operand" "%r"))
5831                           (zero_extend:DI
5832                            (match_operand:SI 2 "register_operand" "r")))
5833                  (match_operand:DI 3 "register_operand" "0")))]
5834   "TARGET_SPARCLET"
5835   "umacd\t%1, %2, %L0"
5836   [(set_attr "type" "imul")])
5837 \f
5838 ;;- Boolean instructions
5839 ;; We define DImode `and' so with DImode `not' we can get
5840 ;; DImode `andn'.  Other combinations are possible.
5841
5842 (define_expand "anddi3"
5843   [(set (match_operand:DI 0 "register_operand" "")
5844         (and:DI (match_operand:DI 1 "arith_double_operand" "")
5845                 (match_operand:DI 2 "arith_double_operand" "")))]
5846   ""
5847   "")
5848
5849 (define_insn "*anddi3_sp32"
5850   [(set (match_operand:DI 0 "register_operand" "=r,b")
5851         (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
5852                 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
5853   "! TARGET_ARCH64"
5854   "@
5855   #
5856   fand\t%1, %2, %0"
5857   [(set_attr "type" "*,fga")
5858    (set_attr "length" "2,*")
5859    (set_attr "fptype" "double")])
5860
5861 (define_insn "*anddi3_sp64"
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    and\t%1, %2, %0
5868    fand\t%1, %2, %0"
5869   [(set_attr "type" "*,fga")
5870    (set_attr "fptype" "double")])
5871
5872 (define_insn "andsi3"
5873   [(set (match_operand:SI 0 "register_operand" "=r,d")
5874         (and:SI (match_operand:SI 1 "arith_operand" "%r,d")
5875                 (match_operand:SI 2 "arith_operand" "rI,d")))]
5876   ""
5877   "@
5878    and\t%1, %2, %0
5879    fands\t%1, %2, %0"
5880   [(set_attr "type" "*,fga")])
5881
5882 (define_split
5883   [(set (match_operand:SI 0 "register_operand" "")
5884         (and:SI (match_operand:SI 1 "register_operand" "")
5885                 (match_operand:SI 2 "" "")))
5886    (clobber (match_operand:SI 3 "register_operand" ""))]
5887   "GET_CODE (operands[2]) == CONST_INT
5888    && !SMALL_INT32 (operands[2])
5889    && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
5890   [(set (match_dup 3) (match_dup 4))
5891    (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
5892 {
5893   operands[4] = GEN_INT (~INTVAL (operands[2]));
5894 })
5895
5896 ;; Split DImode logical operations requiring two instructions.
5897 (define_split
5898   [(set (match_operand:DI 0 "register_operand" "")
5899         (match_operator:DI 1 "cc_arithop"       ; AND, IOR, XOR
5900                            [(match_operand:DI 2 "register_operand" "")
5901                             (match_operand:DI 3 "arith_double_operand" "")]))]
5902   "! TARGET_ARCH64
5903    && reload_completed
5904    && ((GET_CODE (operands[0]) == REG
5905         && REGNO (operands[0]) < 32)
5906        || (GET_CODE (operands[0]) == SUBREG
5907            && GET_CODE (SUBREG_REG (operands[0])) == REG
5908            && REGNO (SUBREG_REG (operands[0])) < 32))"
5909   [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
5910    (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
5911 {
5912   operands[4] = gen_highpart (SImode, operands[0]);
5913   operands[5] = gen_lowpart (SImode, operands[0]);
5914   operands[6] = gen_highpart (SImode, operands[2]);
5915   operands[7] = gen_lowpart (SImode, operands[2]);
5916 #if HOST_BITS_PER_WIDE_INT == 32
5917   if (GET_CODE (operands[3]) == CONST_INT)
5918     {
5919       if (INTVAL (operands[3]) < 0)
5920         operands[8] = constm1_rtx;
5921       else
5922         operands[8] = const0_rtx;
5923     }
5924   else
5925 #endif
5926     operands[8] = gen_highpart_mode (SImode, DImode, operands[3]);
5927   operands[9] = gen_lowpart (SImode, operands[3]);
5928 })
5929
5930 (define_insn_and_split "*and_not_di_sp32"
5931   [(set (match_operand:DI 0 "register_operand" "=r,b")
5932         (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
5933                 (match_operand:DI 2 "register_operand" "r,b")))]
5934   "! TARGET_ARCH64"
5935   "@
5936    #
5937    fandnot1\t%1, %2, %0"
5938   "&& reload_completed
5939    && ((GET_CODE (operands[0]) == REG
5940         && REGNO (operands[0]) < 32)
5941        || (GET_CODE (operands[0]) == SUBREG
5942            && GET_CODE (SUBREG_REG (operands[0])) == REG
5943            && REGNO (SUBREG_REG (operands[0])) < 32))"
5944   [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
5945    (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
5946   "operands[3] = gen_highpart (SImode, operands[0]);
5947    operands[4] = gen_highpart (SImode, operands[1]);
5948    operands[5] = gen_highpart (SImode, operands[2]);
5949    operands[6] = gen_lowpart (SImode, operands[0]);
5950    operands[7] = gen_lowpart (SImode, operands[1]);
5951    operands[8] = gen_lowpart (SImode, operands[2]);"
5952   [(set_attr "type" "*,fga")
5953    (set_attr "length" "2,*")
5954    (set_attr "fptype" "double")])
5955
5956 (define_insn "*and_not_di_sp64"
5957   [(set (match_operand:DI 0 "register_operand" "=r,b")
5958         (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
5959                 (match_operand:DI 2 "register_operand" "r,b")))]
5960   "TARGET_ARCH64"
5961   "@
5962    andn\t%2, %1, %0
5963    fandnot1\t%1, %2, %0"
5964   [(set_attr "type" "*,fga")
5965    (set_attr "fptype" "double")])
5966
5967 (define_insn "*and_not_si"
5968   [(set (match_operand:SI 0 "register_operand" "=r,d")
5969         (and:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
5970                 (match_operand:SI 2 "register_operand" "r,d")))]
5971   ""
5972   "@
5973    andn\t%2, %1, %0
5974    fandnot1s\t%1, %2, %0"
5975   [(set_attr "type" "*,fga")])
5976
5977 (define_expand "iordi3"
5978   [(set (match_operand:DI 0 "register_operand" "")
5979         (ior:DI (match_operand:DI 1 "arith_double_operand" "")
5980                 (match_operand:DI 2 "arith_double_operand" "")))]
5981   ""
5982   "")
5983
5984 (define_insn "*iordi3_sp32"
5985   [(set (match_operand:DI 0 "register_operand" "=r,b")
5986         (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
5987                 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
5988   "! TARGET_ARCH64"
5989   "@
5990   #
5991   for\t%1, %2, %0"
5992   [(set_attr "type" "*,fga")
5993    (set_attr "length" "2,*")
5994    (set_attr "fptype" "double")])
5995
5996 (define_insn "*iordi3_sp64"
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   or\t%1, %2, %0
6003   for\t%1, %2, %0"
6004   [(set_attr "type" "*,fga")
6005    (set_attr "fptype" "double")])
6006
6007 (define_insn "iorsi3"
6008   [(set (match_operand:SI 0 "register_operand" "=r,d")
6009         (ior:SI (match_operand:SI 1 "arith_operand" "%r,d")
6010                 (match_operand:SI 2 "arith_operand" "rI,d")))]
6011   ""
6012   "@
6013    or\t%1, %2, %0
6014    fors\t%1, %2, %0"
6015   [(set_attr "type" "*,fga")])
6016
6017 (define_split
6018   [(set (match_operand:SI 0 "register_operand" "")
6019         (ior:SI (match_operand:SI 1 "register_operand" "")
6020                 (match_operand:SI 2 "" "")))
6021    (clobber (match_operand:SI 3 "register_operand" ""))]
6022   "GET_CODE (operands[2]) == CONST_INT
6023    && !SMALL_INT32 (operands[2])
6024    && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6025   [(set (match_dup 3) (match_dup 4))
6026    (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
6027 {
6028   operands[4] = GEN_INT (~INTVAL (operands[2]));
6029 })
6030
6031 (define_insn_and_split "*or_not_di_sp32"
6032   [(set (match_operand:DI 0 "register_operand" "=r,b")
6033         (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6034                 (match_operand:DI 2 "register_operand" "r,b")))]
6035   "! TARGET_ARCH64"
6036   "@
6037    #
6038    fornot1\t%1, %2, %0"
6039   "&& reload_completed
6040    && ((GET_CODE (operands[0]) == REG
6041         && REGNO (operands[0]) < 32)
6042        || (GET_CODE (operands[0]) == SUBREG
6043            && GET_CODE (SUBREG_REG (operands[0])) == REG
6044            && REGNO (SUBREG_REG (operands[0])) < 32))"
6045   [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
6046    (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
6047   "operands[3] = gen_highpart (SImode, operands[0]);
6048    operands[4] = gen_highpart (SImode, operands[1]);
6049    operands[5] = gen_highpart (SImode, operands[2]);
6050    operands[6] = gen_lowpart (SImode, operands[0]);
6051    operands[7] = gen_lowpart (SImode, operands[1]);
6052    operands[8] = gen_lowpart (SImode, operands[2]);"
6053   [(set_attr "type" "*,fga")
6054    (set_attr "length" "2,*")
6055    (set_attr "fptype" "double")])
6056
6057 (define_insn "*or_not_di_sp64"
6058   [(set (match_operand:DI 0 "register_operand" "=r,b")
6059         (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6060                 (match_operand:DI 2 "register_operand" "r,b")))]
6061   "TARGET_ARCH64"
6062   "@
6063   orn\t%2, %1, %0
6064   fornot1\t%1, %2, %0"
6065   [(set_attr "type" "*,fga")
6066    (set_attr "fptype" "double")])
6067
6068 (define_insn "*or_not_si"
6069   [(set (match_operand:SI 0 "register_operand" "=r,d")
6070         (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6071                 (match_operand:SI 2 "register_operand" "r,d")))]
6072   ""
6073   "@
6074    orn\t%2, %1, %0
6075    fornot1s\t%1, %2, %0"
6076   [(set_attr "type" "*,fga")])
6077
6078 (define_expand "xordi3"
6079   [(set (match_operand:DI 0 "register_operand" "")
6080         (xor:DI (match_operand:DI 1 "arith_double_operand" "")
6081                 (match_operand:DI 2 "arith_double_operand" "")))]
6082   ""
6083   "")
6084
6085 (define_insn "*xordi3_sp32"
6086   [(set (match_operand:DI 0 "register_operand" "=r,b")
6087         (xor:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6088                 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6089   "! TARGET_ARCH64"
6090   "@
6091   #
6092   fxor\t%1, %2, %0"
6093   [(set_attr "type" "*,fga")
6094    (set_attr "length" "2,*")
6095    (set_attr "fptype" "double")])
6096
6097 (define_insn "*xordi3_sp64"
6098   [(set (match_operand:DI 0 "register_operand" "=r,b")
6099         (xor:DI (match_operand:DI 1 "arith_double_operand" "%rJ,b")
6100                 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6101   "TARGET_ARCH64"
6102   "@
6103   xor\t%r1, %2, %0
6104   fxor\t%1, %2, %0"
6105   [(set_attr "type" "*,fga")
6106    (set_attr "fptype" "double")])
6107
6108 (define_insn "*xordi3_sp64_dbl"
6109   [(set (match_operand:DI 0 "register_operand" "=r")
6110         (xor:DI (match_operand:DI 1 "register_operand" "r")
6111                 (match_operand:DI 2 "const64_operand" "")))]
6112   "(TARGET_ARCH64
6113     && HOST_BITS_PER_WIDE_INT != 64)"
6114   "xor\t%1, %2, %0")
6115
6116 (define_insn "xorsi3"
6117   [(set (match_operand:SI 0 "register_operand" "=r,d")
6118         (xor:SI (match_operand:SI 1 "arith_operand" "%rJ,d")
6119                 (match_operand:SI 2 "arith_operand" "rI,d")))]
6120   ""
6121   "@
6122    xor\t%r1, %2, %0
6123    fxors\t%1, %2, %0"
6124   [(set_attr "type" "*,fga")])
6125
6126 (define_split
6127   [(set (match_operand:SI 0 "register_operand" "")
6128         (xor:SI (match_operand:SI 1 "register_operand" "")
6129                 (match_operand:SI 2 "" "")))
6130    (clobber (match_operand:SI 3 "register_operand" ""))]
6131   "GET_CODE (operands[2]) == CONST_INT
6132    && !SMALL_INT32 (operands[2])
6133    && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6134   [(set (match_dup 3) (match_dup 4))
6135    (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
6136 {
6137   operands[4] = GEN_INT (~INTVAL (operands[2]));
6138 })
6139
6140 (define_split
6141   [(set (match_operand:SI 0 "register_operand" "")
6142         (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
6143                         (match_operand:SI 2 "" ""))))
6144    (clobber (match_operand:SI 3 "register_operand" ""))]
6145   "GET_CODE (operands[2]) == CONST_INT
6146    && !SMALL_INT32 (operands[2])
6147    && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6148   [(set (match_dup 3) (match_dup 4))
6149    (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
6150 {
6151   operands[4] = GEN_INT (~INTVAL (operands[2]));
6152 })
6153
6154 ;; xnor patterns.  Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
6155 ;; Combine now canonicalizes to the rightmost expression.
6156 (define_insn_and_split "*xor_not_di_sp32"
6157   [(set (match_operand:DI 0 "register_operand" "=r,b")
6158         (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r,b")
6159                         (match_operand:DI 2 "register_operand" "r,b"))))]
6160   "! TARGET_ARCH64"
6161   "@
6162    #
6163    fxnor\t%1, %2, %0"
6164   "&& reload_completed
6165    && ((GET_CODE (operands[0]) == REG
6166         && REGNO (operands[0]) < 32)
6167        || (GET_CODE (operands[0]) == SUBREG
6168            && GET_CODE (SUBREG_REG (operands[0])) == REG
6169            && REGNO (SUBREG_REG (operands[0])) < 32))"
6170   [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
6171    (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
6172   "operands[3] = gen_highpart (SImode, operands[0]);
6173    operands[4] = gen_highpart (SImode, operands[1]);
6174    operands[5] = gen_highpart (SImode, operands[2]);
6175    operands[6] = gen_lowpart (SImode, operands[0]);
6176    operands[7] = gen_lowpart (SImode, operands[1]);
6177    operands[8] = gen_lowpart (SImode, operands[2]);"
6178   [(set_attr "type" "*,fga")
6179    (set_attr "length" "2,*")
6180    (set_attr "fptype" "double")])
6181
6182 (define_insn "*xor_not_di_sp64"
6183   [(set (match_operand:DI 0 "register_operand" "=r,b")
6184         (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,b")
6185                         (match_operand:DI 2 "arith_double_operand" "rHI,b"))))]
6186   "TARGET_ARCH64"
6187   "@
6188   xnor\t%r1, %2, %0
6189   fxnor\t%1, %2, %0"
6190   [(set_attr "type" "*,fga")
6191    (set_attr "fptype" "double")])
6192
6193 (define_insn "*xor_not_si"
6194   [(set (match_operand:SI 0 "register_operand" "=r,d")
6195         (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,d")
6196                         (match_operand:SI 2 "arith_operand" "rI,d"))))]
6197   ""
6198   "@
6199    xnor\t%r1, %2, %0
6200    fxnors\t%1, %2, %0"
6201   [(set_attr "type" "*,fga")])
6202
6203 ;; These correspond to the above in the case where we also (or only)
6204 ;; want to set the condition code.  
6205
6206 (define_insn "*cmp_cc_arith_op"
6207   [(set (reg:CC 100)
6208         (compare:CC
6209          (match_operator:SI 2 "cc_arithop"
6210                             [(match_operand:SI 0 "arith_operand" "%r")
6211                              (match_operand:SI 1 "arith_operand" "rI")])
6212          (const_int 0)))]
6213   ""
6214   "%A2cc\t%0, %1, %%g0"
6215   [(set_attr "type" "compare")])
6216
6217 (define_insn "*cmp_ccx_arith_op"
6218   [(set (reg:CCX 100)
6219         (compare:CCX
6220          (match_operator:DI 2 "cc_arithop"
6221                             [(match_operand:DI 0 "arith_double_operand" "%r")
6222                              (match_operand:DI 1 "arith_double_operand" "rHI")])
6223          (const_int 0)))]
6224   "TARGET_ARCH64"
6225   "%A2cc\t%0, %1, %%g0"
6226   [(set_attr "type" "compare")])
6227
6228 (define_insn "*cmp_cc_arith_op_set"
6229   [(set (reg:CC 100)
6230         (compare:CC
6231          (match_operator:SI 3 "cc_arithop"
6232                             [(match_operand:SI 1 "arith_operand" "%r")
6233                              (match_operand:SI 2 "arith_operand" "rI")])
6234          (const_int 0)))
6235    (set (match_operand:SI 0 "register_operand" "=r")
6236         (match_operator:SI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6237   "GET_CODE (operands[3]) == GET_CODE (operands[4])"
6238   "%A3cc\t%1, %2, %0"
6239   [(set_attr "type" "compare")])
6240
6241 (define_insn "*cmp_ccx_arith_op_set"
6242   [(set (reg:CCX 100)
6243         (compare:CCX
6244          (match_operator:DI 3 "cc_arithop"
6245                             [(match_operand:DI 1 "arith_double_operand" "%r")
6246                              (match_operand:DI 2 "arith_double_operand" "rHI")])
6247          (const_int 0)))
6248    (set (match_operand:DI 0 "register_operand" "=r")
6249         (match_operator:DI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6250   "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
6251   "%A3cc\t%1, %2, %0"
6252   [(set_attr "type" "compare")])
6253
6254 (define_insn "*cmp_cc_xor_not"
6255   [(set (reg:CC 100)
6256         (compare:CC
6257          (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
6258                          (match_operand:SI 1 "arith_operand" "rI")))
6259          (const_int 0)))]
6260   ""
6261   "xnorcc\t%r0, %1, %%g0"
6262   [(set_attr "type" "compare")])
6263
6264 (define_insn "*cmp_ccx_xor_not"
6265   [(set (reg:CCX 100)
6266         (compare:CCX
6267          (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ")
6268                          (match_operand:DI 1 "arith_double_operand" "rHI")))
6269          (const_int 0)))]
6270   "TARGET_ARCH64"
6271   "xnorcc\t%r0, %1, %%g0"
6272   [(set_attr "type" "compare")])
6273
6274 (define_insn "*cmp_cc_xor_not_set"
6275   [(set (reg:CC 100)
6276         (compare:CC
6277          (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
6278                          (match_operand:SI 2 "arith_operand" "rI")))
6279          (const_int 0)))
6280    (set (match_operand:SI 0 "register_operand" "=r")
6281         (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
6282   ""
6283   "xnorcc\t%r1, %2, %0"
6284   [(set_attr "type" "compare")])
6285
6286 (define_insn "*cmp_ccx_xor_not_set"
6287   [(set (reg:CCX 100)
6288         (compare:CCX
6289          (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
6290                          (match_operand:DI 2 "arith_double_operand" "rHI")))
6291          (const_int 0)))
6292    (set (match_operand:DI 0 "register_operand" "=r")
6293         (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
6294   "TARGET_ARCH64"
6295   "xnorcc\t%r1, %2, %0"
6296   [(set_attr "type" "compare")])
6297
6298 (define_insn "*cmp_cc_arith_op_not"
6299   [(set (reg:CC 100)
6300         (compare:CC
6301          (match_operator:SI 2 "cc_arithopn"
6302                             [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
6303                              (match_operand:SI 1 "reg_or_0_operand" "rJ")])
6304          (const_int 0)))]
6305   ""
6306   "%B2cc\t%r1, %0, %%g0"
6307   [(set_attr "type" "compare")])
6308
6309 (define_insn "*cmp_ccx_arith_op_not"
6310   [(set (reg:CCX 100)
6311         (compare:CCX
6312          (match_operator:DI 2 "cc_arithopn"
6313                             [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6314                              (match_operand:DI 1 "reg_or_0_operand" "rJ")])
6315          (const_int 0)))]
6316   "TARGET_ARCH64"
6317   "%B2cc\t%r1, %0, %%g0"
6318   [(set_attr "type" "compare")])
6319
6320 (define_insn "*cmp_cc_arith_op_not_set"
6321   [(set (reg:CC 100)
6322         (compare:CC
6323          (match_operator:SI 3 "cc_arithopn"
6324                             [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
6325                              (match_operand:SI 2 "reg_or_0_operand" "rJ")])
6326          (const_int 0)))
6327    (set (match_operand:SI 0 "register_operand" "=r")
6328         (match_operator:SI 4 "cc_arithopn"
6329                             [(not:SI (match_dup 1)) (match_dup 2)]))]
6330   "GET_CODE (operands[3]) == GET_CODE (operands[4])"
6331   "%B3cc\t%r2, %1, %0"
6332   [(set_attr "type" "compare")])
6333
6334 (define_insn "*cmp_ccx_arith_op_not_set"
6335   [(set (reg:CCX 100)
6336         (compare:CCX
6337          (match_operator:DI 3 "cc_arithopn"
6338                             [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6339                              (match_operand:DI 2 "reg_or_0_operand" "rJ")])
6340          (const_int 0)))
6341    (set (match_operand:DI 0 "register_operand" "=r")
6342         (match_operator:DI 4 "cc_arithopn"
6343                             [(not:DI (match_dup 1)) (match_dup 2)]))]
6344   "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
6345   "%B3cc\t%r2, %1, %0"
6346   [(set_attr "type" "compare")])
6347
6348 ;; We cannot use the "neg" pseudo insn because the Sun assembler
6349 ;; does not know how to make it work for constants.
6350
6351 (define_expand "negdi2"
6352   [(set (match_operand:DI 0 "register_operand" "=r")
6353         (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6354   ""
6355 {
6356   if (! TARGET_ARCH64)
6357     {
6358       emit_insn (gen_rtx_PARALLEL
6359                  (VOIDmode,
6360                   gen_rtvec (2,
6361                              gen_rtx_SET (VOIDmode, operand0,
6362                                           gen_rtx_NEG (DImode, operand1)),
6363                              gen_rtx_CLOBBER (VOIDmode,
6364                                               gen_rtx_REG (CCmode,
6365                                                            SPARC_ICC_REG)))));
6366       DONE;
6367     }
6368 })
6369
6370 (define_insn_and_split "*negdi2_sp32"
6371   [(set (match_operand:DI 0 "register_operand" "=r")
6372         (neg:DI (match_operand:DI 1 "register_operand" "r")))
6373    (clobber (reg:CC 100))]
6374   "TARGET_ARCH32"
6375   "#"
6376   "&& reload_completed"
6377   [(parallel [(set (reg:CC_NOOV 100)
6378                    (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
6379                                     (const_int 0)))
6380               (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
6381    (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
6382                                 (ltu:SI (reg:CC 100) (const_int 0))))]
6383   "operands[2] = gen_highpart (SImode, operands[0]);
6384    operands[3] = gen_highpart (SImode, operands[1]);
6385    operands[4] = gen_lowpart (SImode, operands[0]);
6386    operands[5] = gen_lowpart (SImode, operands[1]);"
6387   [(set_attr "length" "2")])
6388
6389 (define_insn "*negdi2_sp64"
6390   [(set (match_operand:DI 0 "register_operand" "=r")
6391         (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6392   "TARGET_ARCH64"
6393   "sub\t%%g0, %1, %0")
6394
6395 (define_insn "negsi2"
6396   [(set (match_operand:SI 0 "register_operand" "=r")
6397         (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
6398   ""
6399   "sub\t%%g0, %1, %0")
6400
6401 (define_insn "*cmp_cc_neg"
6402   [(set (reg:CC_NOOV 100)
6403         (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
6404                          (const_int 0)))]
6405   ""
6406   "subcc\t%%g0, %0, %%g0"
6407   [(set_attr "type" "compare")])
6408
6409 (define_insn "*cmp_ccx_neg"
6410   [(set (reg:CCX_NOOV 100)
6411         (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6412                           (const_int 0)))]
6413   "TARGET_ARCH64"
6414   "subcc\t%%g0, %0, %%g0"
6415   [(set_attr "type" "compare")])
6416
6417 (define_insn "*cmp_cc_set_neg"
6418   [(set (reg:CC_NOOV 100)
6419         (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
6420                          (const_int 0)))
6421    (set (match_operand:SI 0 "register_operand" "=r")
6422         (neg:SI (match_dup 1)))]
6423   ""
6424   "subcc\t%%g0, %1, %0"
6425   [(set_attr "type" "compare")])
6426
6427 (define_insn "*cmp_ccx_set_neg"
6428   [(set (reg:CCX_NOOV 100)
6429         (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6430                           (const_int 0)))
6431    (set (match_operand:DI 0 "register_operand" "=r")
6432         (neg:DI (match_dup 1)))]
6433   "TARGET_ARCH64"
6434   "subcc\t%%g0, %1, %0"
6435   [(set_attr "type" "compare")])
6436
6437 ;; We cannot use the "not" pseudo insn because the Sun assembler
6438 ;; does not know how to make it work for constants.
6439 (define_expand "one_cmpldi2"
6440   [(set (match_operand:DI 0 "register_operand" "")
6441         (not:DI (match_operand:DI 1 "register_operand" "")))]
6442   ""
6443   "")
6444
6445 (define_insn_and_split "*one_cmpldi2_sp32"
6446   [(set (match_operand:DI 0 "register_operand" "=r,b")
6447         (not:DI (match_operand:DI 1 "register_operand" "r,b")))]
6448   "! TARGET_ARCH64"
6449   "@
6450    #
6451    fnot1\t%1, %0"
6452   "&& reload_completed
6453    && ((GET_CODE (operands[0]) == REG
6454         && REGNO (operands[0]) < 32)
6455        || (GET_CODE (operands[0]) == SUBREG
6456            && GET_CODE (SUBREG_REG (operands[0])) == REG
6457            && REGNO (SUBREG_REG (operands[0])) < 32))"
6458   [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
6459    (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
6460   "operands[2] = gen_highpart (SImode, operands[0]);
6461    operands[3] = gen_highpart (SImode, operands[1]);
6462    operands[4] = gen_lowpart (SImode, operands[0]);
6463    operands[5] = gen_lowpart (SImode, operands[1]);"
6464   [(set_attr "type" "*,fga")
6465    (set_attr "length" "2,*")
6466    (set_attr "fptype" "double")])
6467
6468 (define_insn "*one_cmpldi2_sp64"
6469   [(set (match_operand:DI 0 "register_operand" "=r,b")
6470         (not:DI (match_operand:DI 1 "arith_double_operand" "rHI,b")))]
6471   "TARGET_ARCH64"
6472   "@
6473    xnor\t%%g0, %1, %0
6474    fnot1\t%1, %0"
6475   [(set_attr "type" "*,fga")
6476    (set_attr "fptype" "double")])
6477
6478 (define_insn "one_cmplsi2"
6479   [(set (match_operand:SI 0 "register_operand" "=r,d")
6480         (not:SI (match_operand:SI 1 "arith_operand" "rI,d")))]
6481   ""
6482   "@
6483   xnor\t%%g0, %1, %0
6484   fnot1s\t%1, %0"
6485   [(set_attr "type" "*,fga")])
6486
6487 (define_insn "*cmp_cc_not"
6488   [(set (reg:CC 100)
6489         (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
6490                     (const_int 0)))]
6491   ""
6492   "xnorcc\t%%g0, %0, %%g0"
6493   [(set_attr "type" "compare")])
6494
6495 (define_insn "*cmp_ccx_not"
6496   [(set (reg:CCX 100)
6497         (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6498                      (const_int 0)))]
6499   "TARGET_ARCH64"
6500   "xnorcc\t%%g0, %0, %%g0"
6501   [(set_attr "type" "compare")])
6502
6503 (define_insn "*cmp_cc_set_not"
6504   [(set (reg:CC 100)
6505         (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
6506                     (const_int 0)))
6507    (set (match_operand:SI 0 "register_operand" "=r")
6508         (not:SI (match_dup 1)))]
6509   ""
6510   "xnorcc\t%%g0, %1, %0"
6511   [(set_attr "type" "compare")])
6512
6513 (define_insn "*cmp_ccx_set_not"
6514   [(set (reg:CCX 100)
6515         (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6516                     (const_int 0)))
6517    (set (match_operand:DI 0 "register_operand" "=r")
6518         (not:DI (match_dup 1)))]
6519   "TARGET_ARCH64"
6520   "xnorcc\t%%g0, %1, %0"
6521   [(set_attr "type" "compare")])
6522
6523 (define_insn "*cmp_cc_set"
6524   [(set (match_operand:SI 0 "register_operand" "=r")
6525         (match_operand:SI 1 "register_operand" "r"))
6526    (set (reg:CC 100)
6527         (compare:CC (match_dup 1)
6528                     (const_int 0)))]
6529   ""
6530   "orcc\t%1, 0, %0"
6531   [(set_attr "type" "compare")])
6532
6533 (define_insn "*cmp_ccx_set64"
6534   [(set (match_operand:DI 0 "register_operand" "=r")
6535         (match_operand:DI 1 "register_operand" "r"))
6536    (set (reg:CCX 100)
6537         (compare:CCX (match_dup 1)
6538                      (const_int 0)))]
6539   "TARGET_ARCH64"
6540   "orcc\t%1, 0, %0"
6541    [(set_attr "type" "compare")])
6542 \f
6543 ;; Floating point arithmetic instructions.
6544
6545 (define_expand "addtf3"
6546   [(set (match_operand:TF 0 "nonimmediate_operand" "")
6547         (plus:TF (match_operand:TF 1 "general_operand" "")
6548                  (match_operand:TF 2 "general_operand" "")))]
6549   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6550   "emit_tfmode_binop (PLUS, operands); DONE;")
6551
6552 (define_insn "*addtf3_hq"
6553   [(set (match_operand:TF 0 "register_operand" "=e")
6554         (plus:TF (match_operand:TF 1 "register_operand" "e")
6555                  (match_operand:TF 2 "register_operand" "e")))]
6556   "TARGET_FPU && TARGET_HARD_QUAD"
6557   "faddq\t%1, %2, %0"
6558   [(set_attr "type" "fp")])
6559
6560 (define_insn "adddf3"
6561   [(set (match_operand:DF 0 "register_operand" "=e")
6562         (plus:DF (match_operand:DF 1 "register_operand" "e")
6563                  (match_operand:DF 2 "register_operand" "e")))]
6564   "TARGET_FPU"
6565   "faddd\t%1, %2, %0"
6566   [(set_attr "type" "fp")
6567    (set_attr "fptype" "double")])
6568
6569 (define_insn "addsf3"
6570   [(set (match_operand:SF 0 "register_operand" "=f")
6571         (plus:SF (match_operand:SF 1 "register_operand" "f")
6572                  (match_operand:SF 2 "register_operand" "f")))]
6573   "TARGET_FPU"
6574   "fadds\t%1, %2, %0"
6575   [(set_attr "type" "fp")])
6576
6577 (define_expand "subtf3"
6578   [(set (match_operand:TF 0 "nonimmediate_operand" "")
6579         (minus:TF (match_operand:TF 1 "general_operand" "")
6580                   (match_operand:TF 2 "general_operand" "")))]
6581   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6582   "emit_tfmode_binop (MINUS, operands); DONE;")
6583
6584 (define_insn "*subtf3_hq"
6585   [(set (match_operand:TF 0 "register_operand" "=e")
6586         (minus:TF (match_operand:TF 1 "register_operand" "e")
6587                   (match_operand:TF 2 "register_operand" "e")))]
6588   "TARGET_FPU && TARGET_HARD_QUAD"
6589   "fsubq\t%1, %2, %0"
6590   [(set_attr "type" "fp")])
6591
6592 (define_insn "subdf3"
6593   [(set (match_operand:DF 0 "register_operand" "=e")
6594         (minus:DF (match_operand:DF 1 "register_operand" "e")
6595                   (match_operand:DF 2 "register_operand" "e")))]
6596   "TARGET_FPU"
6597   "fsubd\t%1, %2, %0"
6598   [(set_attr "type" "fp")
6599    (set_attr "fptype" "double")])
6600
6601 (define_insn "subsf3"
6602   [(set (match_operand:SF 0 "register_operand" "=f")
6603         (minus:SF (match_operand:SF 1 "register_operand" "f")
6604                   (match_operand:SF 2 "register_operand" "f")))]
6605   "TARGET_FPU"
6606   "fsubs\t%1, %2, %0"
6607   [(set_attr "type" "fp")])
6608
6609 (define_expand "multf3"
6610   [(set (match_operand:TF 0 "nonimmediate_operand" "")
6611         (mult:TF (match_operand:TF 1 "general_operand" "")
6612                  (match_operand:TF 2 "general_operand" "")))]
6613   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6614   "emit_tfmode_binop (MULT, operands); DONE;")
6615
6616 (define_insn "*multf3_hq"
6617   [(set (match_operand:TF 0 "register_operand" "=e")
6618         (mult:TF (match_operand:TF 1 "register_operand" "e")
6619                  (match_operand:TF 2 "register_operand" "e")))]
6620   "TARGET_FPU && TARGET_HARD_QUAD"
6621   "fmulq\t%1, %2, %0"
6622   [(set_attr "type" "fpmul")])
6623
6624 (define_insn "muldf3"
6625   [(set (match_operand:DF 0 "register_operand" "=e")
6626         (mult:DF (match_operand:DF 1 "register_operand" "e")
6627                  (match_operand:DF 2 "register_operand" "e")))]
6628   "TARGET_FPU"
6629   "fmuld\t%1, %2, %0"
6630   [(set_attr "type" "fpmul")
6631    (set_attr "fptype" "double")])
6632
6633 (define_insn "mulsf3"
6634   [(set (match_operand:SF 0 "register_operand" "=f")
6635         (mult:SF (match_operand:SF 1 "register_operand" "f")
6636                  (match_operand:SF 2 "register_operand" "f")))]
6637   "TARGET_FPU"
6638   "fmuls\t%1, %2, %0"
6639   [(set_attr "type" "fpmul")])
6640
6641 (define_insn "*muldf3_extend"
6642   [(set (match_operand:DF 0 "register_operand" "=e")
6643         (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
6644                  (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
6645   "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
6646   "fsmuld\t%1, %2, %0"
6647   [(set_attr "type" "fpmul")
6648    (set_attr "fptype" "double")])
6649
6650 (define_insn "*multf3_extend"
6651   [(set (match_operand:TF 0 "register_operand" "=e")
6652         (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
6653                  (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
6654   "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
6655   "fdmulq\t%1, %2, %0"
6656   [(set_attr "type" "fpmul")])
6657
6658 (define_expand "divtf3"
6659   [(set (match_operand:TF 0 "nonimmediate_operand" "")
6660         (div:TF (match_operand:TF 1 "general_operand" "")
6661                 (match_operand:TF 2 "general_operand" "")))]
6662   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6663   "emit_tfmode_binop (DIV, operands); DONE;")
6664
6665 ;; don't have timing for quad-prec. divide.
6666 (define_insn "*divtf3_hq"
6667   [(set (match_operand:TF 0 "register_operand" "=e")
6668         (div:TF (match_operand:TF 1 "register_operand" "e")
6669                 (match_operand:TF 2 "register_operand" "e")))]
6670   "TARGET_FPU && TARGET_HARD_QUAD"
6671   "fdivq\t%1, %2, %0"
6672   [(set_attr "type" "fpdivd")])
6673
6674 (define_insn "divdf3"
6675   [(set (match_operand:DF 0 "register_operand" "=e")
6676         (div:DF (match_operand:DF 1 "register_operand" "e")
6677                 (match_operand:DF 2 "register_operand" "e")))]
6678   "TARGET_FPU"
6679   "fdivd\t%1, %2, %0"
6680   [(set_attr "type" "fpdivd")
6681    (set_attr "fptype" "double")])
6682
6683 (define_insn "divsf3"
6684   [(set (match_operand:SF 0 "register_operand" "=f")
6685         (div:SF (match_operand:SF 1 "register_operand" "f")
6686                 (match_operand:SF 2 "register_operand" "f")))]
6687   "TARGET_FPU"
6688   "fdivs\t%1, %2, %0"
6689   [(set_attr "type" "fpdivs")])
6690
6691 (define_expand "negtf2"
6692   [(set (match_operand:TF 0 "register_operand" "=e,e")
6693         (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6694   "TARGET_FPU"
6695   "")
6696
6697 (define_insn_and_split "*negtf2_notv9"
6698   [(set (match_operand:TF 0 "register_operand" "=e,e")
6699         (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6700   ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6701   "TARGET_FPU
6702    && ! TARGET_V9"
6703   "@
6704   fnegs\t%0, %0
6705   #"
6706   "&& reload_completed
6707    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6708   [(set (match_dup 2) (neg:SF (match_dup 3)))
6709    (set (match_dup 4) (match_dup 5))
6710    (set (match_dup 6) (match_dup 7))]
6711   "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6712    operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6713    operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6714    operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6715    operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6716    operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6717   [(set_attr "type" "fpmove,*")
6718    (set_attr "length" "*,2")])
6719
6720 (define_insn_and_split "*negtf2_v9"
6721   [(set (match_operand:TF 0 "register_operand" "=e,e")
6722         (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6723   ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6724   "TARGET_FPU && TARGET_V9"
6725   "@
6726   fnegd\t%0, %0
6727   #"
6728   "&& reload_completed
6729    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6730   [(set (match_dup 2) (neg:DF (match_dup 3)))
6731    (set (match_dup 4) (match_dup 5))]
6732   "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6733    operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6734    operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6735    operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6736   [(set_attr "type" "fpmove,*")
6737    (set_attr "length" "*,2")
6738    (set_attr "fptype" "double")])
6739
6740 (define_expand "negdf2"
6741   [(set (match_operand:DF 0 "register_operand" "")
6742         (neg:DF (match_operand:DF 1 "register_operand" "")))]
6743   "TARGET_FPU"
6744   "")
6745
6746 (define_insn_and_split "*negdf2_notv9"
6747   [(set (match_operand:DF 0 "register_operand" "=e,e")
6748         (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
6749   "TARGET_FPU && ! TARGET_V9"
6750   "@
6751   fnegs\t%0, %0
6752   #"
6753   "&& reload_completed
6754    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6755   [(set (match_dup 2) (neg:SF (match_dup 3)))
6756    (set (match_dup 4) (match_dup 5))]
6757   "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6758    operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6759    operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6760    operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6761   [(set_attr "type" "fpmove,*")
6762    (set_attr "length" "*,2")])
6763
6764 (define_insn "*negdf2_v9"
6765   [(set (match_operand:DF 0 "register_operand" "=e")
6766         (neg:DF (match_operand:DF 1 "register_operand" "e")))]
6767   "TARGET_FPU && TARGET_V9"
6768   "fnegd\t%1, %0"
6769   [(set_attr "type" "fpmove")
6770    (set_attr "fptype" "double")])
6771
6772 (define_insn "negsf2"
6773   [(set (match_operand:SF 0 "register_operand" "=f")
6774         (neg:SF (match_operand:SF 1 "register_operand" "f")))]
6775   "TARGET_FPU"
6776   "fnegs\t%1, %0"
6777   [(set_attr "type" "fpmove")])
6778
6779 (define_expand "abstf2"
6780   [(set (match_operand:TF 0 "register_operand" "")
6781         (abs:TF (match_operand:TF 1 "register_operand" "")))]
6782   "TARGET_FPU"
6783   "")
6784
6785 (define_insn_and_split "*abstf2_notv9"
6786   [(set (match_operand:TF 0 "register_operand" "=e,e")
6787         (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6788   ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6789   "TARGET_FPU && ! TARGET_V9"
6790   "@
6791   fabss\t%0, %0
6792   #"
6793   "&& reload_completed
6794    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6795   [(set (match_dup 2) (abs:SF (match_dup 3)))
6796    (set (match_dup 4) (match_dup 5))
6797    (set (match_dup 6) (match_dup 7))]
6798   "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6799    operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6800    operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6801    operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6802    operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6803    operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6804   [(set_attr "type" "fpmove,*")
6805    (set_attr "length" "*,2")])
6806
6807 (define_insn "*abstf2_hq_v9"
6808   [(set (match_operand:TF 0 "register_operand" "=e,e")
6809         (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6810   "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
6811   "@
6812   fabsd\t%0, %0
6813   fabsq\t%1, %0"
6814   [(set_attr "type" "fpmove")
6815    (set_attr "fptype" "double,*")])
6816
6817 (define_insn_and_split "*abstf2_v9"
6818   [(set (match_operand:TF 0 "register_operand" "=e,e")
6819         (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6820   "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
6821   "@
6822   fabsd\t%0, %0
6823   #"
6824   "&& reload_completed
6825    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6826   [(set (match_dup 2) (abs:DF (match_dup 3)))
6827    (set (match_dup 4) (match_dup 5))]
6828   "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6829    operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6830    operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6831    operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6832   [(set_attr "type" "fpmove,*")
6833    (set_attr "length" "*,2")
6834    (set_attr "fptype" "double,*")])
6835
6836 (define_expand "absdf2"
6837   [(set (match_operand:DF 0 "register_operand" "")
6838         (abs:DF (match_operand:DF 1 "register_operand" "")))]
6839   "TARGET_FPU"
6840   "")
6841
6842 (define_insn_and_split "*absdf2_notv9"
6843   [(set (match_operand:DF 0 "register_operand" "=e,e")
6844         (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
6845   "TARGET_FPU && ! TARGET_V9"
6846   "@
6847   fabss\t%0, %0
6848   #"
6849   "&& reload_completed
6850    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6851   [(set (match_dup 2) (abs:SF (match_dup 3)))
6852    (set (match_dup 4) (match_dup 5))]
6853   "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6854    operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6855    operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6856    operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6857   [(set_attr "type" "fpmove,*")
6858    (set_attr "length" "*,2")])
6859
6860 (define_insn "*absdf2_v9"
6861   [(set (match_operand:DF 0 "register_operand" "=e")
6862         (abs:DF (match_operand:DF 1 "register_operand" "e")))]
6863   "TARGET_FPU && TARGET_V9"
6864   "fabsd\t%1, %0"
6865   [(set_attr "type" "fpmove")
6866    (set_attr "fptype" "double")])
6867
6868 (define_insn "abssf2"
6869   [(set (match_operand:SF 0 "register_operand" "=f")
6870         (abs:SF (match_operand:SF 1 "register_operand" "f")))]
6871   "TARGET_FPU"
6872   "fabss\t%1, %0"
6873   [(set_attr "type" "fpmove")])
6874
6875 (define_expand "sqrttf2"
6876   [(set (match_operand:TF 0 "nonimmediate_operand" "")
6877         (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
6878   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6879   "emit_tfmode_unop (SQRT, operands); DONE;")
6880
6881 (define_insn "*sqrttf2_hq"
6882   [(set (match_operand:TF 0 "register_operand" "=e")
6883         (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
6884   "TARGET_FPU && TARGET_HARD_QUAD"
6885   "fsqrtq\t%1, %0"
6886   [(set_attr "type" "fpsqrtd")])
6887
6888 (define_insn "sqrtdf2"
6889   [(set (match_operand:DF 0 "register_operand" "=e")
6890         (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
6891   "TARGET_FPU"
6892   "fsqrtd\t%1, %0"
6893   [(set_attr "type" "fpsqrtd")
6894    (set_attr "fptype" "double")])
6895
6896 (define_insn "sqrtsf2"
6897   [(set (match_operand:SF 0 "register_operand" "=f")
6898         (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
6899   "TARGET_FPU"
6900   "fsqrts\t%1, %0"
6901   [(set_attr "type" "fpsqrts")])
6902 \f
6903 ;;- arithmetic shift instructions
6904
6905 (define_insn "ashlsi3"
6906   [(set (match_operand:SI 0 "register_operand" "=r")
6907         (ashift:SI (match_operand:SI 1 "register_operand" "r")
6908                    (match_operand:SI 2 "arith_operand" "rI")))]
6909   ""
6910 {
6911   if (operands[2] == const1_rtx)
6912     return "add\t%1, %1, %0";
6913   if (GET_CODE (operands[2]) == CONST_INT)
6914     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6915   return "sll\t%1, %2, %0";
6916 }
6917   [(set (attr "type")
6918         (if_then_else (match_operand 2 "const1_operand" "")
6919                       (const_string "ialu") (const_string "shift")))])
6920
6921 (define_expand "ashldi3"
6922   [(set (match_operand:DI 0 "register_operand" "=r")
6923         (ashift:DI (match_operand:DI 1 "register_operand" "r")
6924                    (match_operand:SI 2 "arith_operand" "rI")))]
6925   "TARGET_ARCH64 || TARGET_V8PLUS"
6926 {
6927   if (! TARGET_ARCH64)
6928     {
6929       if (GET_CODE (operands[2]) == CONST_INT)
6930         FAIL;
6931       emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
6932       DONE;
6933     }
6934 })
6935
6936 (define_insn "*ashldi3_sp64"
6937   [(set (match_operand:DI 0 "register_operand" "=r")
6938         (ashift:DI (match_operand:DI 1 "register_operand" "r")
6939                    (match_operand:SI 2 "arith_operand" "rI")))]
6940   "TARGET_ARCH64"
6941 {
6942   if (operands[2] == const1_rtx)
6943     return "add\t%1, %1, %0";
6944   if (GET_CODE (operands[2]) == CONST_INT)
6945     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6946   return "sllx\t%1, %2, %0";
6947 }
6948   [(set (attr "type")
6949         (if_then_else (match_operand 2 "const1_operand" "")
6950                       (const_string "ialu") (const_string "shift")))])
6951
6952 ;; XXX UGH!
6953 (define_insn "ashldi3_v8plus"
6954   [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6955         (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6956                    (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6957    (clobber (match_scratch:SI 3 "=X,X,&h"))]
6958   "TARGET_V8PLUS"
6959   { return sparc_v8plus_shift (operands, insn, "sllx"); }
6960   [(set_attr "type" "multi")
6961    (set_attr "length" "5,5,6")])
6962
6963 ;; Optimize (1LL<<x)-1
6964 ;; XXX this also needs to be fixed to handle equal subregs
6965 ;; XXX first before we could re-enable it.
6966 ;(define_insn ""
6967 ;  [(set (match_operand:DI 0 "register_operand" "=h")
6968 ;       (plus:DI (ashift:DI (const_int 1)
6969 ;                           (match_operand:SI 1 "arith_operand" "rI"))
6970 ;                (const_int -1)))]
6971 ;  "0 && TARGET_V8PLUS"
6972 ;{
6973 ;  if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
6974 ;    return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
6975 ;  return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
6976 ;}
6977 ;  [(set_attr "type" "multi")
6978 ;   (set_attr "length" "4")])
6979
6980 (define_insn "*cmp_cc_ashift_1"
6981   [(set (reg:CC_NOOV 100)
6982         (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
6983                                     (const_int 1))
6984                          (const_int 0)))]
6985   ""
6986   "addcc\t%0, %0, %%g0"
6987   [(set_attr "type" "compare")])
6988
6989 (define_insn "*cmp_cc_set_ashift_1"
6990   [(set (reg:CC_NOOV 100)
6991         (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
6992                                     (const_int 1))
6993                          (const_int 0)))
6994    (set (match_operand:SI 0 "register_operand" "=r")
6995         (ashift:SI (match_dup 1) (const_int 1)))]
6996   ""
6997   "addcc\t%1, %1, %0"
6998   [(set_attr "type" "compare")])
6999
7000 (define_insn "ashrsi3"
7001   [(set (match_operand:SI 0 "register_operand" "=r")
7002         (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7003                      (match_operand:SI 2 "arith_operand" "rI")))]
7004   ""
7005   {
7006      if (GET_CODE (operands[2]) == CONST_INT)
7007        operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7008      return "sra\t%1, %2, %0";
7009   }
7010   [(set_attr "type" "shift")])
7011
7012 (define_insn "*ashrsi3_extend"
7013   [(set (match_operand:DI 0 "register_operand" "=r")
7014         (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7015                                      (match_operand:SI 2 "arith_operand" "r"))))]
7016   "TARGET_ARCH64"
7017   "sra\t%1, %2, %0"
7018   [(set_attr "type" "shift")])
7019
7020 ;; This handles the case as above, but with constant shift instead of
7021 ;; register. Combiner "simplifies" it for us a little bit though.
7022 (define_insn "*ashrsi3_extend2"
7023   [(set (match_operand:DI 0 "register_operand" "=r")
7024         (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7025                                 (const_int 32))
7026                      (match_operand:SI 2 "small_int_or_double" "n")))]
7027   "TARGET_ARCH64
7028    && ((GET_CODE (operands[2]) == CONST_INT
7029         && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64)
7030        || (GET_CODE (operands[2]) == CONST_DOUBLE
7031            && !CONST_DOUBLE_HIGH (operands[2])
7032            && CONST_DOUBLE_LOW (operands[2]) >= 32
7033            && CONST_DOUBLE_LOW (operands[2]) < 64))"
7034 {
7035   operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
7036
7037   return "sra\t%1, %2, %0";
7038 }
7039   [(set_attr "type" "shift")])
7040
7041 (define_expand "ashrdi3"
7042   [(set (match_operand:DI 0 "register_operand" "=r")
7043         (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7044                      (match_operand:SI 2 "arith_operand" "rI")))]
7045   "TARGET_ARCH64 || TARGET_V8PLUS"
7046 {
7047   if (! TARGET_ARCH64)
7048     {
7049       if (GET_CODE (operands[2]) == CONST_INT)
7050         FAIL;   /* prefer generic code in this case */
7051       emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
7052       DONE;
7053     }
7054 })
7055
7056 (define_insn "*ashrdi3_sp64"
7057   [(set (match_operand:DI 0 "register_operand" "=r")
7058         (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7059                      (match_operand:SI 2 "arith_operand" "rI")))]
7060   "TARGET_ARCH64"
7061   
7062   {
7063     if (GET_CODE (operands[2]) == CONST_INT)
7064       operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7065     return "srax\t%1, %2, %0";
7066   }
7067   [(set_attr "type" "shift")])
7068
7069 ;; XXX
7070 (define_insn "ashrdi3_v8plus"
7071   [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7072         (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7073                      (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7074    (clobber (match_scratch:SI 3 "=X,X,&h"))]
7075   "TARGET_V8PLUS"
7076   { return sparc_v8plus_shift (operands, insn, "srax"); }
7077   [(set_attr "type" "multi")
7078    (set_attr "length" "5,5,6")])
7079
7080 (define_insn "lshrsi3"
7081   [(set (match_operand:SI 0 "register_operand" "=r")
7082         (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
7083                      (match_operand:SI 2 "arith_operand" "rI")))]
7084   ""
7085   {
7086     if (GET_CODE (operands[2]) == CONST_INT)
7087       operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7088     return "srl\t%1, %2, %0";
7089   }
7090   [(set_attr "type" "shift")])
7091
7092 ;; This handles the case where
7093 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
7094 ;; but combiner "simplifies" it for us.
7095 (define_insn "*lshrsi3_extend"
7096   [(set (match_operand:DI 0 "register_operand" "=r")
7097         (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
7098                            (match_operand:SI 2 "arith_operand" "r")) 0)
7099                 (match_operand 3 "" "")))]
7100   "TARGET_ARCH64
7101    && ((GET_CODE (operands[3]) == CONST_DOUBLE
7102            && CONST_DOUBLE_HIGH (operands[3]) == 0
7103            && CONST_DOUBLE_LOW (operands[3]) == 0xffffffff)
7104        || (HOST_BITS_PER_WIDE_INT >= 64
7105            && GET_CODE (operands[3]) == CONST_INT
7106            && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff))"
7107   "srl\t%1, %2, %0"
7108   [(set_attr "type" "shift")])
7109
7110 ;; This handles the case where
7111 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
7112 ;; but combiner "simplifies" it for us.
7113 (define_insn "*lshrsi3_extend2"
7114   [(set (match_operand:DI 0 "register_operand" "=r")
7115         (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7116                          (match_operand 2 "small_int_or_double" "n")
7117                          (const_int 32)))]
7118   "TARGET_ARCH64
7119    && ((GET_CODE (operands[2]) == CONST_INT
7120         && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7121        || (GET_CODE (operands[2]) == CONST_DOUBLE
7122            && CONST_DOUBLE_HIGH (operands[2]) == 0
7123            && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7124 {
7125   operands[2] = GEN_INT (32 - INTVAL (operands[2]));
7126
7127   return "srl\t%1, %2, %0";
7128 }
7129   [(set_attr "type" "shift")])
7130
7131 (define_expand "lshrdi3"
7132   [(set (match_operand:DI 0 "register_operand" "=r")
7133         (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7134                      (match_operand:SI 2 "arith_operand" "rI")))]
7135   "TARGET_ARCH64 || TARGET_V8PLUS"
7136 {
7137   if (! TARGET_ARCH64)
7138     {
7139       if (GET_CODE (operands[2]) == CONST_INT)
7140         FAIL;
7141       emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
7142       DONE;
7143     }
7144 })
7145
7146 (define_insn "*lshrdi3_sp64"
7147   [(set (match_operand:DI 0 "register_operand" "=r")
7148         (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7149                      (match_operand:SI 2 "arith_operand" "rI")))]
7150   "TARGET_ARCH64"
7151   {
7152     if (GET_CODE (operands[2]) == CONST_INT)
7153       operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7154     return "srlx\t%1, %2, %0";
7155   }
7156   [(set_attr "type" "shift")])
7157
7158 ;; XXX
7159 (define_insn "lshrdi3_v8plus"
7160   [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7161         (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7162                      (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7163    (clobber (match_scratch:SI 3 "=X,X,&h"))]
7164   "TARGET_V8PLUS"
7165   { return sparc_v8plus_shift (operands, insn, "srlx"); }
7166   [(set_attr "type" "multi")
7167    (set_attr "length" "5,5,6")])
7168
7169 (define_insn ""
7170   [(set (match_operand:SI 0 "register_operand" "=r")
7171         (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7172                                              (const_int 32)) 4)
7173                      (match_operand:SI 2 "small_int_or_double" "n")))]
7174   "TARGET_ARCH64
7175    && ((GET_CODE (operands[2]) == CONST_INT
7176         && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7177        || (GET_CODE (operands[2]) == CONST_DOUBLE
7178            && !CONST_DOUBLE_HIGH (operands[2])
7179            && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7180 {
7181   operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
7182
7183   return "srax\t%1, %2, %0";
7184 }
7185   [(set_attr "type" "shift")])
7186
7187 (define_insn ""
7188   [(set (match_operand:SI 0 "register_operand" "=r")
7189         (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7190                                              (const_int 32)) 4)
7191                      (match_operand:SI 2 "small_int_or_double" "n")))]
7192   "TARGET_ARCH64
7193    && ((GET_CODE (operands[2]) == CONST_INT
7194         && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7195        || (GET_CODE (operands[2]) == CONST_DOUBLE
7196            && !CONST_DOUBLE_HIGH (operands[2])
7197            && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7198 {
7199   operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
7200
7201   return "srlx\t%1, %2, %0";
7202 }
7203   [(set_attr "type" "shift")])
7204
7205 (define_insn ""
7206   [(set (match_operand:SI 0 "register_operand" "=r")
7207         (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7208                                              (match_operand:SI 2 "small_int_or_double" "n")) 4)
7209                      (match_operand:SI 3 "small_int_or_double" "n")))]
7210   "TARGET_ARCH64
7211    && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
7212    && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
7213    && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
7214    && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
7215 {
7216   operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
7217
7218   return "srax\t%1, %2, %0";
7219 }
7220   [(set_attr "type" "shift")])
7221
7222 (define_insn ""
7223   [(set (match_operand:SI 0 "register_operand" "=r")
7224         (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7225                                              (match_operand:SI 2 "small_int_or_double" "n")) 4)
7226                      (match_operand:SI 3 "small_int_or_double" "n")))]
7227   "TARGET_ARCH64
7228    && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
7229    && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
7230    && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
7231    && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
7232 {
7233   operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
7234
7235   return "srlx\t%1, %2, %0";
7236 }
7237   [(set_attr "type" "shift")])
7238 \f
7239 ;; Unconditional and other jump instructions
7240 ;; On the SPARC, by setting the annul bit on an unconditional branch, the
7241 ;; following insn is never executed.  This saves us a nop.  Dbx does not
7242 ;; handle such branches though, so we only use them when optimizing.
7243 (define_insn "jump"
7244   [(set (pc) (label_ref (match_operand 0 "" "")))]
7245   ""
7246 {
7247   /* TurboSPARC is reported to have problems with
7248      with
7249         foo: b,a foo
7250      i.e. an empty loop with the annul bit set.  The workaround is to use 
7251         foo: b foo; nop
7252      instead.  */
7253
7254   if (! TARGET_V9 && flag_delayed_branch
7255       && (INSN_ADDRESSES (INSN_UID (operands[0]))
7256           == INSN_ADDRESSES (INSN_UID (insn))))
7257     return "b\t%l0%#";
7258   else
7259     return TARGET_V9 ? "ba%*,pt\t%%xcc, %l0%(" : "b%*\t%l0%(";
7260 }
7261   [(set_attr "type" "uncond_branch")])
7262
7263 (define_expand "tablejump"
7264   [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
7265               (use (label_ref (match_operand 1 "" "")))])]
7266   ""
7267 {
7268   if (GET_MODE (operands[0]) != CASE_VECTOR_MODE)
7269     abort ();
7270
7271   /* In pic mode, our address differences are against the base of the
7272      table.  Add that base value back in; CSE ought to be able to combine
7273      the two address loads.  */
7274   if (flag_pic)
7275     {
7276       rtx tmp, tmp2;
7277       tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
7278       tmp2 = operands[0];
7279       if (CASE_VECTOR_MODE != Pmode)
7280         tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
7281       tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
7282       operands[0] = memory_address (Pmode, tmp);
7283     }
7284 })
7285
7286 (define_insn "*tablejump_sp32"
7287   [(set (pc) (match_operand:SI 0 "address_operand" "p"))
7288    (use (label_ref (match_operand 1 "" "")))]
7289   "! TARGET_ARCH64"
7290   "jmp\t%a0%#"
7291   [(set_attr "type" "uncond_branch")])
7292
7293 (define_insn "*tablejump_sp64"
7294   [(set (pc) (match_operand:DI 0 "address_operand" "p"))
7295    (use (label_ref (match_operand 1 "" "")))]
7296   "TARGET_ARCH64"
7297   "jmp\t%a0%#"
7298   [(set_attr "type" "uncond_branch")])
7299
7300 ;; This pattern recognizes the "instruction" that appears in 
7301 ;; a function call that wants a structure value, 
7302 ;; to inform the called function if compiled with Sun CC.
7303 ;(define_insn "*unimp_insn"
7304 ;  [(match_operand:SI 0 "immediate_operand" "")]
7305 ;  "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0"
7306 ;  "unimp\t%0"
7307 ;  [(set_attr "type" "marker")])
7308
7309 ;;- jump to subroutine
7310 (define_expand "call"
7311   ;; Note that this expression is not used for generating RTL.
7312   ;; All the RTL is generated explicitly below.
7313   [(call (match_operand 0 "call_operand" "")
7314          (match_operand 3 "" "i"))]
7315   ;; operands[2] is next_arg_register
7316   ;; operands[3] is struct_value_size_rtx.
7317   ""
7318 {
7319   rtx fn_rtx, nregs_rtx;
7320
7321    if (GET_MODE (operands[0]) != FUNCTION_MODE)
7322     abort ();
7323
7324   if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
7325     {
7326       /* This is really a PIC sequence.  We want to represent
7327          it as a funny jump so its delay slots can be filled. 
7328
7329          ??? But if this really *is* a CALL, will not it clobber the
7330          call-clobbered registers?  We lose this if it is a JUMP_INSN.
7331          Why cannot we have delay slots filled if it were a CALL?  */
7332
7333       if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7334         emit_jump_insn
7335           (gen_rtx_PARALLEL
7336            (VOIDmode,
7337             gen_rtvec (3,
7338                        gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
7339                        operands[3],
7340                        gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7341       else
7342         emit_jump_insn
7343           (gen_rtx_PARALLEL
7344            (VOIDmode,
7345             gen_rtvec (2,
7346                        gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
7347                        gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7348       goto finish_call;
7349     }
7350
7351   fn_rtx = operands[0];
7352
7353   /* Count the number of parameter registers being used by this call.
7354      if that argument is NULL, it means we are using them all, which
7355      means 6 on the sparc.  */
7356 #if 0
7357   if (operands[2])
7358     nregs_rtx = GEN_INT (REGNO (operands[2]) - 8);
7359   else
7360     nregs_rtx = GEN_INT (6);
7361 #else
7362   nregs_rtx = const0_rtx;
7363 #endif
7364
7365   if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7366     emit_call_insn
7367       (gen_rtx_PARALLEL
7368        (VOIDmode,
7369         gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
7370                    operands[3],
7371                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7372   else
7373     emit_call_insn
7374       (gen_rtx_PARALLEL
7375        (VOIDmode,
7376         gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx),
7377                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7378
7379  finish_call:
7380 #if 0
7381   /* If this call wants a structure value,
7382      emit an unimp insn to let the called function know about this.  */
7383   if (! TARGET_ARCH64 && INTVAL (operands[3]) > 0)
7384     {
7385       rtx insn = emit_insn (operands[3]);
7386       SCHED_GROUP_P (insn) = 1;
7387     }
7388 #endif
7389
7390   DONE;
7391 })
7392
7393 ;; We can't use the same pattern for these two insns, because then registers
7394 ;; in the address may not be properly reloaded.
7395
7396 (define_insn "*call_address_sp32"
7397   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7398          (match_operand 1 "" ""))
7399    (clobber (reg:SI 15))]
7400   ;;- Do not use operand 1 for most machines.
7401   "! TARGET_ARCH64"
7402   "call\t%a0, %1%#"
7403   [(set_attr "type" "call")])
7404
7405 (define_insn "*call_symbolic_sp32"
7406   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7407          (match_operand 1 "" ""))
7408    (clobber (reg:SI 15))]
7409   ;;- Do not use operand 1 for most machines.
7410   "! TARGET_ARCH64"
7411   "call\t%a0, %1%#"
7412   [(set_attr "type" "call")])
7413
7414 (define_insn "*call_address_sp64"
7415   [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
7416          (match_operand 1 "" ""))
7417    (clobber (reg:DI 15))]
7418   ;;- Do not use operand 1 for most machines.
7419   "TARGET_ARCH64"
7420   "call\t%a0, %1%#"
7421   [(set_attr "type" "call")])
7422
7423 (define_insn "*call_symbolic_sp64"
7424   [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
7425          (match_operand 1 "" ""))
7426    (clobber (reg:DI 15))]
7427   ;;- Do not use operand 1 for most machines.
7428   "TARGET_ARCH64"
7429   "call\t%a0, %1%#"
7430   [(set_attr "type" "call")])
7431
7432 ;; This is a call that wants a structure value.
7433 ;; There is no such critter for v9 (??? we may need one anyway).
7434 (define_insn "*call_address_struct_value_sp32"
7435   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7436          (match_operand 1 "" ""))
7437    (match_operand 2 "immediate_operand" "")
7438    (clobber (reg:SI 15))]
7439   ;;- Do not use operand 1 for most machines.
7440   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
7441   "call\t%a0, %1\n\tnop\n\tunimp\t%2"
7442   [(set_attr "type" "call_no_delay_slot")
7443    (set_attr "length" "3")])
7444
7445 ;; This is a call that wants a structure value.
7446 ;; There is no such critter for v9 (??? we may need one anyway).
7447 (define_insn "*call_symbolic_struct_value_sp32"
7448   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7449          (match_operand 1 "" ""))
7450    (match_operand 2 "immediate_operand" "")
7451    (clobber (reg:SI 15))]
7452   ;;- Do not use operand 1 for most machines.
7453   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0"
7454   "call\t%a0, %1\n\tnop\n\tunimp\t%2"
7455   [(set_attr "type" "call_no_delay_slot")
7456    (set_attr "length" "3")])
7457
7458 ;; This is a call that may want a structure value.  This is used for
7459 ;; untyped_calls.
7460 (define_insn "*call_address_untyped_struct_value_sp32"
7461   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7462          (match_operand 1 "" ""))
7463    (match_operand 2 "immediate_operand" "")
7464    (clobber (reg:SI 15))]
7465   ;;- Do not use operand 1 for most machines.
7466   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7467   "call\t%a0, %1\n\tnop\n\tnop"
7468   [(set_attr "type" "call_no_delay_slot")
7469    (set_attr "length" "3")])
7470
7471 ;; This is a call that wants a structure value.
7472 (define_insn "*call_symbolic_untyped_struct_value_sp32"
7473   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
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 (define_expand "call_value"
7484   ;; Note that this expression is not used for generating RTL.
7485   ;; All the RTL is generated explicitly below.
7486   [(set (match_operand 0 "register_operand" "=rf")
7487         (call (match_operand 1 "" "")
7488               (match_operand 4 "" "")))]
7489   ;; operand 2 is stack_size_rtx
7490   ;; operand 3 is next_arg_register
7491   ""
7492 {
7493   rtx fn_rtx, nregs_rtx;
7494   rtvec vec;
7495
7496   if (GET_MODE (operands[1]) != FUNCTION_MODE)
7497     abort ();
7498
7499   fn_rtx = operands[1];
7500
7501 #if 0
7502   if (operands[3])
7503     nregs_rtx = GEN_INT (REGNO (operands[3]) - 8);
7504   else
7505     nregs_rtx = GEN_INT (6);
7506 #else
7507   nregs_rtx = const0_rtx;
7508 #endif
7509
7510   vec = gen_rtvec (2,
7511                    gen_rtx_SET (VOIDmode, operands[0],
7512                                 gen_rtx_CALL (VOIDmode, fn_rtx, nregs_rtx)),
7513                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
7514
7515   emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
7516
7517   DONE;
7518 })
7519
7520 (define_insn "*call_value_address_sp32"
7521   [(set (match_operand 0 "" "=rf")
7522         (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
7523               (match_operand 2 "" "")))
7524    (clobber (reg:SI 15))]
7525   ;;- Do not use operand 2 for most machines.
7526   "! TARGET_ARCH64"
7527   "call\t%a1, %2%#"
7528   [(set_attr "type" "call")])
7529
7530 (define_insn "*call_value_symbolic_sp32"
7531   [(set (match_operand 0 "" "=rf")
7532         (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7533               (match_operand 2 "" "")))
7534    (clobber (reg:SI 15))]
7535   ;;- Do not use operand 2 for most machines.
7536   "! TARGET_ARCH64"
7537   "call\t%a1, %2%#"
7538   [(set_attr "type" "call")])
7539
7540 (define_insn "*call_value_address_sp64"
7541   [(set (match_operand 0 "" "")
7542         (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
7543               (match_operand 2 "" "")))
7544    (clobber (reg:DI 15))]
7545   ;;- Do not use operand 2 for most machines.
7546   "TARGET_ARCH64"
7547   "call\t%a1, %2%#"
7548   [(set_attr "type" "call")])
7549
7550 (define_insn "*call_value_symbolic_sp64"
7551   [(set (match_operand 0 "" "")
7552         (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
7553               (match_operand 2 "" "")))
7554    (clobber (reg:DI 15))]
7555   ;;- Do not use operand 2 for most machines.
7556   "TARGET_ARCH64"
7557   "call\t%a1, %2%#"
7558   [(set_attr "type" "call")])
7559
7560 (define_expand "untyped_call"
7561   [(parallel [(call (match_operand 0 "" "")
7562                     (const_int 0))
7563               (match_operand 1 "" "")
7564               (match_operand 2 "" "")])]
7565   ""
7566 {
7567   int i;
7568
7569   /* Pass constm1 to indicate that it may expect a structure value, but
7570      we don't know what size it is.  */
7571   emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
7572
7573   for (i = 0; i < XVECLEN (operands[2], 0); i++)
7574     {
7575       rtx set = XVECEXP (operands[2], 0, i);
7576       emit_move_insn (SET_DEST (set), SET_SRC (set));
7577     }
7578
7579   /* The optimizer does not know that the call sets the function value
7580      registers we stored in the result block.  We avoid problems by
7581      claiming that all hard registers are used and clobbered at this
7582      point.  */
7583   emit_insn (gen_blockage ());
7584
7585   DONE;
7586 })
7587
7588 ;;- tail calls
7589 (define_expand "sibcall"
7590   [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
7591               (return)])]
7592   ""
7593   "")
7594
7595 (define_insn "*sibcall_symbolic_sp32"
7596   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7597          (match_operand 1 "" ""))
7598    (return)]
7599   "! TARGET_ARCH64"
7600   "* return output_sibcall(insn, operands[0]);"
7601   [(set_attr "type" "sibcall")])
7602
7603 (define_insn "*sibcall_symbolic_sp64"
7604   [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
7605          (match_operand 1 "" ""))
7606    (return)]
7607   "TARGET_ARCH64"
7608   "* return output_sibcall(insn, operands[0]);"
7609   [(set_attr "type" "sibcall")])
7610
7611 (define_expand "sibcall_value"
7612   [(parallel [(set (match_operand 0 "register_operand" "=rf")
7613                 (call (match_operand 1 "" "") (const_int 0)))
7614               (return)])]
7615   ""
7616   "")
7617
7618 (define_insn "*sibcall_value_symbolic_sp32"
7619   [(set (match_operand 0 "" "=rf")
7620         (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7621               (match_operand 2 "" "")))
7622    (return)]
7623   "! TARGET_ARCH64"
7624   "* return output_sibcall(insn, operands[1]);"
7625   [(set_attr "type" "sibcall")])
7626
7627 (define_insn "*sibcall_value_symbolic_sp64"
7628   [(set (match_operand 0 "" "")
7629         (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
7630               (match_operand 2 "" "")))
7631    (return)]
7632   "TARGET_ARCH64"
7633   "* return output_sibcall(insn, operands[1]);"
7634   [(set_attr "type" "sibcall")])
7635
7636 (define_expand "sibcall_epilogue"
7637   [(const_int 0)]
7638   ""
7639   "DONE;")
7640
7641 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
7642 ;; all of memory.  This blocks insns from being moved across this point.
7643
7644 (define_insn "blockage"
7645   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7646   ""
7647   ""
7648   [(set_attr "length" "0")])
7649
7650 ;; Prepare to return any type including a structure value.
7651
7652 (define_expand "untyped_return"
7653   [(match_operand:BLK 0 "memory_operand" "")
7654    (match_operand 1 "" "")]
7655   ""
7656 {
7657   rtx valreg1 = gen_rtx_REG (DImode, 24);
7658   rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
7659   rtx result = operands[0];
7660
7661   if (! TARGET_ARCH64)
7662     {
7663       rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
7664                                          ? 15 : 31));
7665       rtx value = gen_reg_rtx (SImode);
7666
7667       /* Fetch the instruction where we will return to and see if it's an unimp
7668          instruction (the most significant 10 bits will be zero).  If so,
7669          update the return address to skip the unimp instruction.  */
7670       emit_move_insn (value,
7671                       gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
7672       emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
7673       emit_insn (gen_update_return (rtnreg, value));
7674     }
7675
7676   /* Reload the function value registers.  */
7677   emit_move_insn (valreg1, adjust_address (result, DImode, 0));
7678   emit_move_insn (valreg2,
7679                   adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
7680
7681   /* Put USE insns before the return.  */
7682   emit_insn (gen_rtx_USE (VOIDmode, valreg1));
7683   emit_insn (gen_rtx_USE (VOIDmode, valreg2));
7684
7685   /* Construct the return.  */
7686   expand_naked_return ();
7687
7688   DONE;
7689 })
7690
7691 ;; This is a bit of a hack.  We're incrementing a fixed register (%i7),
7692 ;; and parts of the compiler don't want to believe that the add is needed.
7693
7694 (define_insn "update_return"
7695   [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
7696                (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
7697   "! TARGET_ARCH64"
7698   "cmp\t%1, 0\;be,a\t.+8\;add\t%0, 4, %0"
7699   [(set_attr "type" "multi")
7700    (set_attr "length" "3")])
7701 \f
7702 (define_insn "nop"
7703   [(const_int 0)]
7704   ""
7705   "nop")
7706
7707 (define_expand "indirect_jump"
7708   [(set (pc) (match_operand 0 "address_operand" "p"))]
7709   ""
7710   "")
7711
7712 (define_insn "*branch_sp32"
7713   [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
7714   "! TARGET_ARCH64"
7715  "jmp\t%a0%#"
7716  [(set_attr "type" "uncond_branch")])
7717  
7718 (define_insn "*branch_sp64"
7719   [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
7720   "TARGET_ARCH64"
7721   "jmp\t%a0%#"
7722   [(set_attr "type" "uncond_branch")])
7723
7724 (define_expand "nonlocal_goto"
7725   [(match_operand:SI 0 "general_operand" "")
7726    (match_operand:SI 1 "general_operand" "")
7727    (match_operand:SI 2 "general_operand" "")
7728    (match_operand:SI 3 "" "")]
7729   ""
7730 {
7731 #if 0
7732   rtx chain = operands[0];
7733 #endif
7734   rtx lab = operands[1];
7735   rtx stack = operands[2];
7736   rtx fp = operands[3];
7737   rtx labreg;
7738
7739   /* Trap instruction to flush all the register windows.  */
7740   emit_insn (gen_flush_register_windows ());
7741
7742   /* Load the fp value for the containing fn into %fp.  This is needed
7743      because STACK refers to %fp.  Note that virtual register instantiation
7744      fails if the virtual %fp isn't set from a register.  */
7745   if (GET_CODE (fp) != REG)
7746     fp = force_reg (Pmode, fp);
7747   emit_move_insn (virtual_stack_vars_rtx, fp);
7748
7749   /* Find the containing function's current nonlocal goto handler,
7750      which will do any cleanups and then jump to the label.  */
7751   labreg = gen_rtx_REG (Pmode, 8);
7752   emit_move_insn (labreg, lab);
7753
7754   /* Restore %fp from stack pointer value for containing function.
7755      The restore insn that follows will move this to %sp,
7756      and reload the appropriate value into %fp.  */
7757   emit_move_insn (hard_frame_pointer_rtx, stack);
7758
7759   /* USE of frame_pointer_rtx added for consistency; not clear if
7760      really needed.  */
7761   /*emit_insn (gen_rtx_USE (VOIDmode, frame_pointer_rtx));*/
7762   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
7763
7764 #if 0
7765   /* Return, restoring reg window and jumping to goto handler.  */
7766   if (TARGET_V9 && GET_CODE (chain) == CONST_INT
7767       && ! (INTVAL (chain) & ~(HOST_WIDE_INT)0xffffffff))
7768     {
7769       emit_jump_insn (gen_goto_handler_and_restore_v9 (labreg,
7770                                                        static_chain_rtx,
7771                                                        chain));
7772       emit_barrier ();
7773       DONE;
7774     }
7775   /* Put in the static chain register the nonlocal label address.  */
7776   emit_move_insn (static_chain_rtx, chain);
7777 #endif
7778
7779   emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
7780   emit_jump_insn (gen_goto_handler_and_restore (labreg));
7781   emit_barrier ();
7782   DONE;
7783 })
7784
7785 ;; Special trap insn to flush register windows.
7786 (define_insn "flush_register_windows"
7787   [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
7788   ""
7789   { return TARGET_V9 ? "flushw" : "ta\t3"; }
7790   [(set_attr "type" "flushw")])
7791
7792 (define_insn "goto_handler_and_restore"
7793   [(unspec_volatile [(match_operand 0 "register_operand" "=r")] UNSPECV_GOTO)]
7794   "GET_MODE (operands[0]) == Pmode"
7795   "jmp\t%0+0\n\trestore"
7796   [(set_attr "type" "multi")
7797    (set_attr "length" "2")])
7798
7799 ;;(define_insn "goto_handler_and_restore_v9"
7800 ;;  [(unspec_volatile [(match_operand:SI 0 "register_operand" "=r,r")
7801 ;;                   (match_operand:SI 1 "register_operand" "=r,r")
7802 ;;                   (match_operand:SI 2 "const_int_operand" "I,n")] UNSPECV_GOTO_V9)]
7803 ;;  "TARGET_V9 && ! TARGET_ARCH64"
7804 ;;  "@
7805 ;;   return\t%0+0\n\tmov\t%2, %Y1
7806 ;;   sethi\t%%hi(%2), %1\n\treturn\t%0+0\n\tor\t%Y1, %%lo(%2), %Y1"
7807 ;;  [(set_attr "type" "multi")
7808 ;;   (set_attr "length" "2,3")])
7809 ;;
7810 ;;(define_insn "*goto_handler_and_restore_v9_sp64"
7811 ;;  [(unspec_volatile [(match_operand:DI 0 "register_operand" "=r,r")
7812 ;;                   (match_operand:DI 1 "register_operand" "=r,r")
7813 ;;                   (match_operand:SI 2 "const_int_operand" "I,n")] UNSPECV_GOTO_V9)]
7814 ;;  "TARGET_V9 && TARGET_ARCH64"
7815 ;;  "@
7816 ;;   return\t%0+0\n\tmov\t%2, %Y1
7817 ;;   sethi\t%%hi(%2), %1\n\treturn\t%0+0\n\tor\t%Y1, %%lo(%2), %Y1"
7818 ;;  [(set_attr "type" "multi")
7819 ;;   (set_attr "length" "2,3")])
7820
7821 ;; For __builtin_setjmp we need to flush register windows iff the function
7822 ;; calls alloca as well, because otherwise the register window might be
7823 ;; saved after %sp adjustment and thus setjmp would crash
7824 (define_expand "builtin_setjmp_setup"
7825   [(match_operand 0 "register_operand" "r")]
7826   ""
7827 {
7828   emit_insn (gen_do_builtin_setjmp_setup ());
7829   DONE;
7830 })
7831
7832 (define_insn "do_builtin_setjmp_setup"
7833   [(unspec_volatile [(const_int 0)] UNSPECV_SETJMP)]
7834   ""
7835 {
7836   if (! current_function_calls_alloca)
7837     return "";
7838   if (! TARGET_V9)
7839     return "\tta\t3\n";
7840   fputs ("\tflushw\n", asm_out_file);
7841   if (flag_pic)
7842     fprintf (asm_out_file, "\tst%c\t%%l7, [%%sp+%d]\n",
7843              TARGET_ARCH64 ? 'x' : 'w',
7844              SPARC_STACK_BIAS + 7 * UNITS_PER_WORD);
7845   fprintf (asm_out_file, "\tst%c\t%%fp, [%%sp+%d]\n",
7846            TARGET_ARCH64 ? 'x' : 'w',
7847            SPARC_STACK_BIAS + 14 * UNITS_PER_WORD);
7848   fprintf (asm_out_file, "\tst%c\t%%i7, [%%sp+%d]\n",
7849            TARGET_ARCH64 ? 'x' : 'w',
7850            SPARC_STACK_BIAS + 15 * UNITS_PER_WORD);
7851   return "";
7852 }
7853   [(set_attr "type" "multi")
7854    (set (attr "length")
7855         (cond [(eq_attr "current_function_calls_alloca" "false")
7856                  (const_int 0)
7857                (eq_attr "isa" "!v9")
7858                  (const_int 1)
7859                (eq_attr "pic" "true")
7860                  (const_int 4)] (const_int 3)))])
7861
7862 ;; Pattern for use after a setjmp to store FP and the return register
7863 ;; into the stack area.
7864
7865 (define_expand "setjmp"
7866   [(const_int 0)]
7867   ""
7868 {
7869   if (TARGET_ARCH64)
7870     emit_insn (gen_setjmp_64 ());
7871   else
7872     emit_insn (gen_setjmp_32 ());
7873   DONE;
7874 })
7875
7876 (define_expand "setjmp_32"
7877   [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
7878    (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
7879   ""
7880   { operands[0] = frame_pointer_rtx; })
7881
7882 (define_expand "setjmp_64"
7883   [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
7884    (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
7885   ""
7886   { operands[0] = frame_pointer_rtx; })
7887
7888 ;; Special pattern for the FLUSH instruction.
7889
7890 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
7891 ; of the define_insn otherwise missing a mode.  We make "flush", aka
7892 ; gen_flush, the default one since sparc_initialize_trampoline uses
7893 ; it on SImode mem values.
7894
7895 (define_insn "flush"
7896   [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7897   ""
7898   { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7899   [(set_attr "type" "iflush")])
7900
7901 (define_insn "flushdi"
7902   [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7903   ""
7904   { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7905   [(set_attr "type" "iflush")])
7906
7907 \f
7908 ;; find first set.
7909
7910 ;; The scan instruction searches from the most significant bit while ffs
7911 ;; searches from the least significant bit.  The bit index and treatment of
7912 ;; zero also differ.  It takes at least 7 instructions to get the proper
7913 ;; result.  Here is an obvious 8 instruction sequence.
7914
7915 ;; XXX
7916 (define_insn "ffssi2"
7917   [(set (match_operand:SI 0 "register_operand" "=&r")
7918         (ffs:SI (match_operand:SI 1 "register_operand" "r")))
7919    (clobber (match_scratch:SI 2 "=&r"))]
7920   "TARGET_SPARCLITE || TARGET_SPARCLET"
7921 {
7922   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";
7923 }
7924   [(set_attr "type" "multi")
7925    (set_attr "length" "8")])
7926
7927 ;; ??? This should be a define expand, so that the extra instruction have
7928 ;; a chance of being optimized away.
7929
7930 ;; Disabled because none of the UltraSPARCs implement popc.  The HAL R1
7931 ;; does, but no one uses that and we don't have a switch for it.
7932 ;
7933 ;(define_insn "ffsdi2"
7934 ;  [(set (match_operand:DI 0 "register_operand" "=&r")
7935 ;       (ffs:DI (match_operand:DI 1 "register_operand" "r")))
7936 ;   (clobber (match_scratch:DI 2 "=&r"))]
7937 ;  "TARGET_ARCH64"
7938 ;  "neg\t%1, %2\;xnor\t%1, %2, %2\;popc\t%2, %0\;movzr\t%1, 0, %0"
7939 ;  [(set_attr "type" "multi")
7940 ;   (set_attr "length" "4")])
7941
7942
7943 \f
7944 ;; Peepholes go at the end.
7945
7946 ;; Optimize consecutive loads or stores into ldd and std when possible.
7947 ;; The conditions in which we do this are very restricted and are 
7948 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
7949
7950 (define_peephole2
7951   [(set (match_operand:SI 0 "memory_operand" "")
7952       (const_int 0))
7953    (set (match_operand:SI 1 "memory_operand" "")
7954       (const_int 0))]
7955   "TARGET_V9
7956    && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
7957   [(set (match_dup 0)
7958        (const_int 0))]
7959   "operands[0] = widen_memory_access (operands[0], DImode, 0);")
7960
7961 (define_peephole2
7962   [(set (match_operand:SI 0 "memory_operand" "")
7963       (const_int 0))
7964    (set (match_operand:SI 1 "memory_operand" "")
7965       (const_int 0))]
7966   "TARGET_V9
7967    && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
7968   [(set (match_dup 1)
7969        (const_int 0))]
7970   "operands[1] = widen_memory_access (operands[1], DImode, 0);")
7971
7972 (define_peephole2
7973   [(set (match_operand:SI 0 "register_operand" "")
7974         (match_operand:SI 1 "memory_operand" ""))
7975    (set (match_operand:SI 2 "register_operand" "")
7976         (match_operand:SI 3 "memory_operand" ""))]
7977   "registers_ok_for_ldd_peep (operands[0], operands[2]) 
7978    && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])" 
7979   [(set (match_dup 0)
7980         (match_dup 1))]
7981   "operands[1] = widen_memory_access (operands[1], DImode, 0);
7982    operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
7983
7984 (define_peephole2
7985   [(set (match_operand:SI 0 "memory_operand" "")
7986         (match_operand:SI 1 "register_operand" ""))
7987    (set (match_operand:SI 2 "memory_operand" "")
7988         (match_operand:SI 3 "register_operand" ""))]
7989   "registers_ok_for_ldd_peep (operands[1], operands[3]) 
7990    && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7991   [(set (match_dup 0)
7992         (match_dup 1))]
7993   "operands[0] = widen_memory_access (operands[0], DImode, 0);
7994    operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
7995
7996 (define_peephole2
7997   [(set (match_operand:SF 0 "register_operand" "")
7998         (match_operand:SF 1 "memory_operand" ""))
7999    (set (match_operand:SF 2 "register_operand" "")
8000         (match_operand:SF 3 "memory_operand" ""))]
8001   "registers_ok_for_ldd_peep (operands[0], operands[2]) 
8002    && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
8003   [(set (match_dup 0)
8004         (match_dup 1))]
8005   "operands[1] = widen_memory_access (operands[1], DFmode, 0);
8006    operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
8007
8008 (define_peephole2
8009   [(set (match_operand:SF 0 "memory_operand" "")
8010         (match_operand:SF 1 "register_operand" ""))
8011    (set (match_operand:SF 2 "memory_operand" "")
8012         (match_operand:SF 3 "register_operand" ""))]
8013   "registers_ok_for_ldd_peep (operands[1], operands[3]) 
8014   && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
8015   [(set (match_dup 0)
8016         (match_dup 1))]
8017   "operands[0] = widen_memory_access (operands[0], DFmode, 0);
8018    operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
8019
8020 (define_peephole2
8021   [(set (match_operand:SI 0 "register_operand" "")
8022         (match_operand:SI 1 "memory_operand" ""))
8023    (set (match_operand:SI 2 "register_operand" "")
8024         (match_operand:SI 3 "memory_operand" ""))]
8025   "registers_ok_for_ldd_peep (operands[2], operands[0]) 
8026   && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
8027   [(set (match_dup 2)
8028         (match_dup 3))]
8029    "operands[3] = widen_memory_access (operands[3], DImode, 0);
8030     operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
8031
8032 (define_peephole2
8033   [(set (match_operand:SI 0 "memory_operand" "")
8034         (match_operand:SI 1 "register_operand" ""))
8035    (set (match_operand:SI 2 "memory_operand" "")
8036         (match_operand:SI 3 "register_operand" ""))]
8037   "registers_ok_for_ldd_peep (operands[3], operands[1]) 
8038   && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)" 
8039   [(set (match_dup 2)
8040         (match_dup 3))]
8041   "operands[2] = widen_memory_access (operands[2], DImode, 0);
8042    operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
8043    ")
8044  
8045 (define_peephole2
8046   [(set (match_operand:SF 0 "register_operand" "")
8047         (match_operand:SF 1 "memory_operand" ""))
8048    (set (match_operand:SF 2 "register_operand" "")
8049         (match_operand:SF 3 "memory_operand" ""))]
8050   "registers_ok_for_ldd_peep (operands[2], operands[0]) 
8051   && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
8052   [(set (match_dup 2)
8053         (match_dup 3))]
8054   "operands[3] = widen_memory_access (operands[3], DFmode, 0);
8055    operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
8056
8057 (define_peephole2
8058   [(set (match_operand:SF 0 "memory_operand" "")
8059         (match_operand:SF 1 "register_operand" ""))
8060    (set (match_operand:SF 2 "memory_operand" "")
8061         (match_operand:SF 3 "register_operand" ""))]
8062   "registers_ok_for_ldd_peep (operands[3], operands[1]) 
8063   && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
8064   [(set (match_dup 2)
8065         (match_dup 3))]
8066   "operands[2] = widen_memory_access (operands[2], DFmode, 0);
8067    operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
8068  
8069 ;; Optimize the case of following a reg-reg move with a test
8070 ;; of reg just moved.  Don't allow floating point regs for operand 0 or 1.
8071 ;; This can result from a float to fix conversion.
8072
8073 (define_peephole2
8074   [(set (match_operand:SI 0 "register_operand" "")
8075         (match_operand:SI 1 "register_operand" ""))
8076    (set (reg:CC 100)
8077         (compare:CC (match_operand:SI 2 "register_operand" "")
8078                     (const_int 0)))]
8079   "(rtx_equal_p (operands[2], operands[0])
8080     || rtx_equal_p (operands[2], operands[1]))
8081     && ! SPARC_FP_REG_P (REGNO (operands[0]))
8082     && ! SPARC_FP_REG_P (REGNO (operands[1]))"
8083   [(parallel [(set (match_dup 0) (match_dup 1))
8084               (set (reg:CC 100)
8085                    (compare:CC (match_dup 1) (const_int 0)))])]
8086   "")
8087
8088 (define_peephole2
8089   [(set (match_operand:DI 0 "register_operand" "")
8090         (match_operand:DI 1 "register_operand" ""))
8091    (set (reg:CCX 100)
8092         (compare:CCX (match_operand:DI 2 "register_operand" "")
8093                     (const_int 0)))]
8094   "TARGET_ARCH64
8095    && (rtx_equal_p (operands[2], operands[0])
8096        || rtx_equal_p (operands[2], operands[1]))
8097    && ! SPARC_FP_REG_P (REGNO (operands[0]))
8098    && ! SPARC_FP_REG_P (REGNO (operands[1]))"
8099   [(parallel [(set (match_dup 0) (match_dup 1))
8100               (set (reg:CCX 100)
8101                    (compare:CCX (match_dup 1) (const_int 0)))])]
8102   "")
8103
8104 ;; Return peepholes.  These are generated by sparc_function_epilogue
8105 ;; who then immediately calls final_scan_insn.
8106
8107 (define_insn "*return_qi"
8108   [(set (match_operand:QI 0 "restore_operand" "")
8109         (match_operand:QI 1 "arith_operand" "rI"))
8110    (return)]
8111   "sparc_emitting_epilogue"
8112 {
8113   if (! TARGET_ARCH64 && current_function_returns_struct)
8114     return "jmp\t%%i7+12\n\trestore %%g0, %1, %Y0";
8115   else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
8116                          || IN_OR_GLOBAL_P (operands[1])))
8117     return "return\t%%i7+8\n\tmov\t%Y1, %Y0";
8118   else
8119     return "ret\n\trestore %%g0, %1, %Y0";
8120 }
8121   [(set_attr "type" "multi")
8122    (set_attr "length" "2")])
8123
8124 (define_insn "*return_hi"
8125   [(set (match_operand:HI 0 "restore_operand" "")
8126         (match_operand:HI 1 "arith_operand" "rI"))
8127    (return)]
8128   "sparc_emitting_epilogue"
8129 {
8130   if (! TARGET_ARCH64 && current_function_returns_struct)
8131     return "jmp\t%%i7+12\n\trestore %%g0, %1, %Y0";
8132   else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
8133                          || IN_OR_GLOBAL_P (operands[1])))
8134     return "return\t%%i7+8\n\tmov\t%Y1, %Y0";
8135   else
8136     return "ret\;restore %%g0, %1, %Y0";
8137 }
8138   [(set_attr "type" "multi")
8139    (set_attr "length" "2")])
8140
8141 (define_insn "*return_si"
8142   [(set (match_operand:SI 0 "restore_operand" "")
8143         (match_operand:SI 1 "arith_operand" "rI"))
8144    (return)]
8145   "sparc_emitting_epilogue"
8146 {
8147   if (! TARGET_ARCH64 && current_function_returns_struct)
8148     return "jmp\t%%i7+12\n\trestore %%g0, %1, %Y0";
8149   else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT
8150                          || IN_OR_GLOBAL_P (operands[1])))
8151     return "return\t%%i7+8\n\tmov\t%Y1, %Y0";
8152   else
8153     return "ret\;restore %%g0, %1, %Y0";
8154 }
8155   [(set_attr "type" "multi")
8156    (set_attr "length" "2")])
8157
8158 (define_insn "*return_sf_no_fpu"
8159   [(set (match_operand:SF 0 "restore_operand" "=r")
8160         (match_operand:SF 1 "register_operand" "r"))
8161    (return)]
8162   "sparc_emitting_epilogue"
8163 {
8164   if (! TARGET_ARCH64 && current_function_returns_struct)
8165     return "jmp\t%%i7+12\n\trestore %%g0, %1, %Y0";
8166   else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
8167     return "return\t%%i7+8\n\tmov\t%Y1, %Y0";
8168   else
8169     return "ret\;restore %%g0, %1, %Y0";
8170 }
8171   [(set_attr "type" "multi")
8172    (set_attr "length" "2")])
8173
8174 (define_insn "*return_df_no_fpu"
8175   [(set (match_operand:DF 0 "restore_operand" "=r")
8176         (match_operand:DF 1 "register_operand" "r"))
8177    (return)]
8178   "sparc_emitting_epilogue && TARGET_ARCH64"
8179 {
8180   if (IN_OR_GLOBAL_P (operands[1]))
8181     return "return\t%%i7+8\n\tmov\t%Y1, %Y0";
8182   else
8183     return "ret\;restore %%g0, %1, %Y0";
8184 }
8185   [(set_attr "type" "multi")
8186    (set_attr "length" "2")])
8187
8188 (define_insn "*return_addsi"
8189   [(set (match_operand:SI 0 "restore_operand" "")
8190         (plus:SI (match_operand:SI 1 "register_operand" "r")
8191                  (match_operand:SI 2 "arith_operand" "rI")))
8192    (return)]
8193   "sparc_emitting_epilogue"
8194 {
8195   if (! TARGET_ARCH64 && current_function_returns_struct)
8196     return "jmp\t%%i7+12\n\trestore %r1, %2, %Y0";
8197   /* If operands are global or in registers, can use return */
8198   else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1])
8199            && (GET_CODE (operands[2]) == CONST_INT
8200                || IN_OR_GLOBAL_P (operands[2])))
8201     return "return\t%%i7+8\n\tadd\t%Y1, %Y2, %Y0";
8202   else
8203     return "ret\;restore %r1, %2, %Y0";
8204 }
8205   [(set_attr "type" "multi")
8206    (set_attr "length" "2")])
8207
8208 (define_insn "*return_losum_si"
8209   [(set (match_operand:SI 0 "restore_operand" "")
8210         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8211                    (match_operand:SI 2 "immediate_operand" "in")))
8212    (return)]
8213   "sparc_emitting_epilogue && ! TARGET_CM_MEDMID"
8214 {
8215   if (! TARGET_ARCH64 && current_function_returns_struct)
8216     return "jmp\t%%i7+12\n\trestore %r1, %%lo(%a2), %Y0";
8217   /* If operands are global or in registers, can use return */
8218   else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]))
8219     return "return\t%%i7+8\n\tor\t%Y1, %%lo(%a2), %Y0";
8220   else
8221     return "ret\;restore %r1, %%lo(%a2), %Y0";
8222 }
8223   [(set_attr "type" "multi")
8224    (set_attr "length" "2")])
8225
8226 (define_insn "*return_di"
8227   [(set (match_operand:DI 0 "restore_operand" "")
8228         (match_operand:DI 1 "arith_double_operand" "rHI"))
8229    (return)]
8230   "sparc_emitting_epilogue && TARGET_ARCH64"
8231   "ret\;restore %%g0, %1, %Y0"
8232   [(set_attr "type" "multi")
8233    (set_attr "length" "2")])
8234
8235 (define_insn "*return_adddi"
8236   [(set (match_operand:DI 0 "restore_operand" "")
8237         (plus:DI (match_operand:DI 1 "arith_operand" "%r")
8238                  (match_operand:DI 2 "arith_double_operand" "rHI")))
8239    (return)]
8240   "sparc_emitting_epilogue && TARGET_ARCH64"
8241   "ret\;restore %r1, %2, %Y0"
8242   [(set_attr "type" "multi")
8243    (set_attr "length" "2")])
8244
8245 (define_insn "*return_losum_di"
8246   [(set (match_operand:DI 0 "restore_operand" "")
8247         (lo_sum:DI (match_operand:DI 1 "arith_operand" "%r")
8248                    (match_operand:DI 2 "immediate_operand" "in")))
8249    (return)]
8250   "sparc_emitting_epilogue && TARGET_ARCH64 && ! TARGET_CM_MEDMID"
8251   "ret\;restore %r1, %%lo(%a2), %Y0"
8252   [(set_attr "type" "multi")
8253    (set_attr "length" "2")])
8254
8255 (define_insn "*return_sf"
8256   [(set (reg:SF 32)
8257         (match_operand:SF 0 "register_operand" "f"))
8258    (return)]
8259   "sparc_emitting_epilogue"
8260   "ret\;fmovs\t%0, %%f0"
8261   [(set_attr "type" "multi")
8262    (set_attr "length" "2")])
8263
8264 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
8265 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
8266 ;; ??? operations.  With DFA we might be able to model this, but it requires a lot of
8267 ;; ??? state.
8268 (define_expand "prefetch"
8269   [(match_operand 0 "address_operand" "")
8270    (match_operand 1 "const_int_operand" "")
8271    (match_operand 2 "const_int_operand" "")]
8272   "TARGET_V9"
8273 {
8274   if (TARGET_ARCH64)
8275     emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
8276   else
8277     emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
8278   DONE;
8279 })
8280
8281 (define_insn "prefetch_64"
8282   [(prefetch (match_operand:DI 0 "address_operand" "p")
8283              (match_operand:DI 1 "const_int_operand" "n")
8284              (match_operand:DI 2 "const_int_operand" "n"))]
8285   ""
8286 {
8287   static const char * const prefetch_instr[2][2] = {
8288     {
8289       "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
8290       "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
8291     },
8292     {
8293       "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
8294       "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
8295     }
8296   };
8297   int read_or_write = INTVAL (operands[1]);
8298   int locality = INTVAL (operands[2]);
8299
8300   if (read_or_write != 0 && read_or_write != 1)
8301     abort ();
8302   if (locality < 0 || locality > 3)
8303     abort ();
8304   return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
8305 }
8306   [(set_attr "type" "load")])
8307
8308 (define_insn "prefetch_32"
8309   [(prefetch (match_operand:SI 0 "address_operand" "p")
8310              (match_operand:SI 1 "const_int_operand" "n")
8311              (match_operand:SI 2 "const_int_operand" "n"))]
8312   ""
8313 {
8314   static const char * const prefetch_instr[2][2] = {
8315     {
8316       "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
8317       "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
8318     },
8319     {
8320       "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
8321       "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
8322     }
8323   };
8324   int read_or_write = INTVAL (operands[1]);
8325   int locality = INTVAL (operands[2]);
8326
8327   if (read_or_write != 0 && read_or_write != 1)
8328     abort ();
8329   if (locality < 0 || locality > 3)
8330     abort ();
8331   return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
8332 }
8333   [(set_attr "type" "load")])
8334 \f
8335 (define_expand "prologue"
8336   [(const_int 1)]
8337   "flag_pic && current_function_uses_pic_offset_table"
8338 {
8339   load_pic_register ();
8340   DONE;
8341 })
8342 \f
8343 (define_insn "trap"
8344   [(trap_if (const_int 1) (const_int 5))]
8345   ""
8346   "ta\t5"
8347   [(set_attr "type" "trap")])
8348
8349 (define_expand "conditional_trap"
8350   [(trap_if (match_operator 0 "noov_compare_op"
8351                             [(match_dup 2) (match_dup 3)])
8352             (match_operand:SI 1 "arith_operand" ""))]
8353   ""
8354   "operands[2] = gen_compare_reg (GET_CODE (operands[0]),
8355                                   sparc_compare_op0, sparc_compare_op1);
8356    operands[3] = const0_rtx;")
8357
8358 (define_insn ""
8359   [(trap_if (match_operator 0 "noov_compare_op" [(reg:CC 100) (const_int 0)])
8360             (match_operand:SI 1 "arith_operand" "rM"))]
8361   ""
8362   "t%C0\t%1"
8363   [(set_attr "type" "trap")])
8364
8365 (define_insn ""
8366   [(trap_if (match_operator 0 "noov_compare_op" [(reg:CCX 100) (const_int 0)])
8367             (match_operand:SI 1 "arith_operand" "rM"))]
8368   "TARGET_V9"
8369   "t%C0\t%%xcc, %1"
8370   [(set_attr "type" "trap")])
8371
8372 ;; TLS support
8373 (define_insn "tgd_hi22"
8374   [(set (match_operand:SI 0 "register_operand" "=r")
8375         (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
8376                             UNSPEC_TLSGD)))]
8377   "TARGET_TLS"
8378   "sethi\\t%%tgd_hi22(%a1), %0")
8379
8380 (define_insn "tgd_lo10"
8381   [(set (match_operand:SI 0 "register_operand" "=r")
8382         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8383                    (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
8384                               UNSPEC_TLSGD)))]
8385   "TARGET_TLS"
8386   "add\\t%1, %%tgd_lo10(%a2), %0")
8387
8388 (define_insn "tgd_add32"
8389   [(set (match_operand:SI 0 "register_operand" "=r")
8390         (plus:SI (match_operand:SI 1 "register_operand" "r")
8391                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8392                              (match_operand 3 "tgd_symbolic_operand" "")]
8393                             UNSPEC_TLSGD)))]
8394   "TARGET_TLS && TARGET_ARCH32"
8395   "add\\t%1, %2, %0, %%tgd_add(%a3)")
8396
8397 (define_insn "tgd_add64"
8398   [(set (match_operand:DI 0 "register_operand" "=r")
8399         (plus:DI (match_operand:DI 1 "register_operand" "r")
8400                  (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8401                              (match_operand 3 "tgd_symbolic_operand" "")]
8402                             UNSPEC_TLSGD)))]
8403   "TARGET_TLS && TARGET_ARCH64"
8404   "add\\t%1, %2, %0, %%tgd_add(%a3)")
8405
8406 (define_insn "tgd_call32"
8407   [(set (match_operand 0 "register_operand" "=r")
8408         (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
8409                                   (match_operand 2 "tgd_symbolic_operand" "")]
8410                                  UNSPEC_TLSGD))
8411               (match_operand 3 "" "")))
8412    (clobber (reg:SI 15))]
8413   "TARGET_TLS && TARGET_ARCH32"
8414   "call\t%a1, %%tgd_call(%a2)%#"
8415   [(set_attr "type" "call")])
8416
8417 (define_insn "tgd_call64"
8418   [(set (match_operand 0 "register_operand" "=r")
8419         (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
8420                                   (match_operand 2 "tgd_symbolic_operand" "")]
8421                                  UNSPEC_TLSGD))
8422               (match_operand 3 "" "")))
8423    (clobber (reg:DI 15))]
8424   "TARGET_TLS && TARGET_ARCH64"
8425   "call\t%a1, %%tgd_call(%a2)%#"
8426   [(set_attr "type" "call")])
8427
8428 (define_insn "tldm_hi22"
8429   [(set (match_operand:SI 0 "register_operand" "=r")
8430         (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
8431   "TARGET_TLS"
8432   "sethi\\t%%tldm_hi22(%&), %0")
8433
8434 (define_insn "tldm_lo10"
8435   [(set (match_operand:SI 0 "register_operand" "=r")
8436         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8437                     (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
8438   "TARGET_TLS"
8439   "add\\t%1, %%tldm_lo10(%&), %0")
8440
8441 (define_insn "tldm_add32"
8442   [(set (match_operand:SI 0 "register_operand" "=r")
8443         (plus:SI (match_operand:SI 1 "register_operand" "r")
8444                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
8445                             UNSPEC_TLSLDM)))]
8446   "TARGET_TLS && TARGET_ARCH32"
8447   "add\\t%1, %2, %0, %%tldm_add(%&)")
8448
8449 (define_insn "tldm_add64"
8450   [(set (match_operand:DI 0 "register_operand" "=r")
8451         (plus:DI (match_operand:DI 1 "register_operand" "r")
8452                  (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
8453                             UNSPEC_TLSLDM)))]
8454   "TARGET_TLS && TARGET_ARCH64"
8455   "add\\t%1, %2, %0, %%tldm_add(%&)")
8456
8457 (define_insn "tldm_call32"
8458   [(set (match_operand 0 "register_operand" "=r")
8459         (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
8460                                  UNSPEC_TLSLDM))
8461               (match_operand 2 "" "")))
8462    (clobber (reg:SI 15))]
8463   "TARGET_TLS && TARGET_ARCH32"
8464   "call\t%a1, %%tldm_call(%&)%#"
8465   [(set_attr "type" "call")])
8466
8467 (define_insn "tldm_call64"
8468   [(set (match_operand 0 "register_operand" "=r")
8469         (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
8470                                  UNSPEC_TLSLDM))
8471               (match_operand 2 "" "")))
8472    (clobber (reg:DI 15))]
8473   "TARGET_TLS && TARGET_ARCH64"
8474   "call\t%a1, %%tldm_call(%&)%#"
8475   [(set_attr "type" "call")])
8476
8477 (define_insn "tldo_hix22"
8478   [(set (match_operand:SI 0 "register_operand" "=r")
8479         (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
8480                             UNSPEC_TLSLDO)))]
8481   "TARGET_TLS"
8482   "sethi\\t%%tldo_hix22(%a1), %0")
8483
8484 (define_insn "tldo_lox10"
8485   [(set (match_operand:SI 0 "register_operand" "=r")
8486         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8487                    (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
8488                               UNSPEC_TLSLDO)))]
8489   "TARGET_TLS"
8490   "xor\\t%1, %%tldo_lox10(%a2), %0")
8491
8492 (define_insn "tldo_add32"
8493   [(set (match_operand:SI 0 "register_operand" "=r")
8494         (plus:SI (match_operand:SI 1 "register_operand" "r")
8495                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8496                              (match_operand 3 "tld_symbolic_operand" "")]
8497                             UNSPEC_TLSLDO)))]
8498   "TARGET_TLS && TARGET_ARCH32"
8499   "add\\t%1, %2, %0, %%tldo_add(%a3)")
8500
8501 (define_insn "tldo_add64"
8502   [(set (match_operand:DI 0 "register_operand" "=r")
8503         (plus:DI (match_operand:DI 1 "register_operand" "r")
8504                  (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8505                              (match_operand 3 "tld_symbolic_operand" "")]
8506                             UNSPEC_TLSLDO)))]
8507   "TARGET_TLS && TARGET_ARCH64"
8508   "add\\t%1, %2, %0, %%tldo_add(%a3)")
8509
8510 (define_insn "tie_hi22"
8511   [(set (match_operand:SI 0 "register_operand" "=r")
8512         (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
8513                             UNSPEC_TLSIE)))]
8514   "TARGET_TLS"
8515   "sethi\\t%%tie_hi22(%a1), %0")
8516
8517 (define_insn "tie_lo10"
8518   [(set (match_operand:SI 0 "register_operand" "=r")
8519         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8520                    (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
8521                               UNSPEC_TLSIE)))]
8522   "TARGET_TLS"
8523   "add\\t%1, %%tie_lo10(%a2), %0")
8524
8525 (define_insn "tie_ld32"
8526   [(set (match_operand:SI 0 "register_operand" "=r")
8527         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
8528                     (match_operand:SI 2 "register_operand" "r")
8529                     (match_operand 3 "tie_symbolic_operand" "")]
8530                    UNSPEC_TLSIE))]
8531   "TARGET_TLS && TARGET_ARCH32"
8532   "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
8533   [(set_attr "type" "load")])
8534
8535 (define_insn "tie_ld64"
8536   [(set (match_operand:DI 0 "register_operand" "=r")
8537         (unspec:DI [(match_operand:DI 1 "register_operand" "r")
8538                     (match_operand:SI 2 "register_operand" "r")
8539                     (match_operand 3 "tie_symbolic_operand" "")]
8540                    UNSPEC_TLSIE))]
8541   "TARGET_TLS && TARGET_ARCH64"
8542   "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
8543   [(set_attr "type" "load")])
8544
8545 (define_insn "tie_add32"
8546   [(set (match_operand:SI 0 "register_operand" "=r")
8547         (plus:SI (match_operand:SI 1 "register_operand" "r")
8548                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8549                              (match_operand 3 "tie_symbolic_operand" "")]
8550                             UNSPEC_TLSIE)))]
8551   "TARGET_SUN_TLS && TARGET_ARCH32"
8552   "add\\t%1, %2, %0, %%tie_add(%a3)")
8553
8554 (define_insn "tie_add64"
8555   [(set (match_operand:DI 0 "register_operand" "=r")
8556         (plus:DI (match_operand:DI 1 "register_operand" "r")
8557                  (unspec:DI [(match_operand:DI 2 "register_operand" "r")
8558                              (match_operand 3 "tie_symbolic_operand" "")]
8559                             UNSPEC_TLSIE)))]
8560   "TARGET_SUN_TLS && TARGET_ARCH64"
8561   "add\\t%1, %2, %0, %%tie_add(%a3)")
8562
8563 (define_insn "tle_hix22_sp32"
8564   [(set (match_operand:SI 0 "register_operand" "=r")
8565         (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
8566                             UNSPEC_TLSLE)))]
8567   "TARGET_TLS && TARGET_ARCH32"
8568   "sethi\\t%%tle_hix22(%a1), %0")
8569
8570 (define_insn "tle_lox10_sp32"
8571   [(set (match_operand:SI 0 "register_operand" "=r")
8572         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8573                    (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
8574                               UNSPEC_TLSLE)))]
8575   "TARGET_TLS && TARGET_ARCH32"
8576   "xor\\t%1, %%tle_lox10(%a2), %0")
8577
8578 (define_insn "tle_hix22_sp64"
8579   [(set (match_operand:DI 0 "register_operand" "=r")
8580         (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
8581                             UNSPEC_TLSLE)))]
8582   "TARGET_TLS && TARGET_ARCH64"
8583   "sethi\\t%%tle_hix22(%a1), %0")
8584
8585 (define_insn "tle_lox10_sp64"
8586   [(set (match_operand:DI 0 "register_operand" "=r")
8587         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
8588                    (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
8589                               UNSPEC_TLSLE)))]
8590   "TARGET_TLS && TARGET_ARCH64"
8591   "xor\\t%1, %%tle_lox10(%a2), %0")
8592
8593 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
8594 (define_insn "*tldo_ldub_sp32"
8595   [(set (match_operand:QI 0 "register_operand" "=r")
8596         (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8597                                      (match_operand 3 "tld_symbolic_operand" "")]
8598                                     UNSPEC_TLSLDO)
8599                          (match_operand:SI 1 "register_operand" "r"))))]
8600   "TARGET_TLS && TARGET_ARCH32"
8601   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8602   [(set_attr "type" "load")
8603    (set_attr "us3load_type" "3cycle")])
8604
8605 (define_insn "*tldo_ldub1_sp32"
8606   [(set (match_operand:HI 0 "register_operand" "=r")
8607         (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8608                                                      (match_operand 3 "tld_symbolic_operand" "")]
8609                                                     UNSPEC_TLSLDO)
8610                                          (match_operand:SI 1 "register_operand" "r")))))]
8611   "TARGET_TLS && TARGET_ARCH32"
8612   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8613   [(set_attr "type" "load")
8614    (set_attr "us3load_type" "3cycle")])
8615
8616 (define_insn "*tldo_ldub2_sp32"
8617   [(set (match_operand:SI 0 "register_operand" "=r")
8618         (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8619                                                      (match_operand 3 "tld_symbolic_operand" "")]
8620                                                     UNSPEC_TLSLDO)
8621                                          (match_operand:SI 1 "register_operand" "r")))))]
8622   "TARGET_TLS && TARGET_ARCH32"
8623   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8624   [(set_attr "type" "load")
8625    (set_attr "us3load_type" "3cycle")])
8626
8627 (define_insn "*tldo_ldsb1_sp32"
8628   [(set (match_operand:HI 0 "register_operand" "=r")
8629         (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8630                                                      (match_operand 3 "tld_symbolic_operand" "")]
8631                                                     UNSPEC_TLSLDO)
8632                                          (match_operand:SI 1 "register_operand" "r")))))]
8633   "TARGET_TLS && TARGET_ARCH32"
8634   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8635   [(set_attr "type" "sload")
8636    (set_attr "us3load_type" "3cycle")])
8637
8638 (define_insn "*tldo_ldsb2_sp32"
8639   [(set (match_operand:SI 0 "register_operand" "=r")
8640         (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8641                                                      (match_operand 3 "tld_symbolic_operand" "")]
8642                                                     UNSPEC_TLSLDO)
8643                                          (match_operand:SI 1 "register_operand" "r")))))]
8644   "TARGET_TLS && TARGET_ARCH32"
8645   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8646   [(set_attr "type" "sload")
8647    (set_attr "us3load_type" "3cycle")])
8648
8649 (define_insn "*tldo_ldub_sp64"
8650   [(set (match_operand:QI 0 "register_operand" "=r")
8651         (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8652                                      (match_operand 3 "tld_symbolic_operand" "")]
8653                                     UNSPEC_TLSLDO)
8654                          (match_operand:DI 1 "register_operand" "r"))))]
8655   "TARGET_TLS && TARGET_ARCH64"
8656   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8657   [(set_attr "type" "load")
8658    (set_attr "us3load_type" "3cycle")])
8659
8660 (define_insn "*tldo_ldub1_sp64"
8661   [(set (match_operand:HI 0 "register_operand" "=r")
8662         (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8663                                                      (match_operand 3 "tld_symbolic_operand" "")]
8664                                                     UNSPEC_TLSLDO)
8665                                          (match_operand:DI 1 "register_operand" "r")))))]
8666   "TARGET_TLS && TARGET_ARCH64"
8667   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8668   [(set_attr "type" "load")
8669    (set_attr "us3load_type" "3cycle")])
8670
8671 (define_insn "*tldo_ldub2_sp64"
8672   [(set (match_operand:SI 0 "register_operand" "=r")
8673         (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8674                                                      (match_operand 3 "tld_symbolic_operand" "")]
8675                                                     UNSPEC_TLSLDO)
8676                                          (match_operand:DI 1 "register_operand" "r")))))]
8677   "TARGET_TLS && TARGET_ARCH64"
8678   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8679   [(set_attr "type" "load")
8680    (set_attr "us3load_type" "3cycle")])
8681
8682 (define_insn "*tldo_ldub3_sp64"
8683   [(set (match_operand:DI 0 "register_operand" "=r")
8684         (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8685                                                      (match_operand 3 "tld_symbolic_operand" "")]
8686                                                     UNSPEC_TLSLDO)
8687                                          (match_operand:DI 1 "register_operand" "r")))))]
8688   "TARGET_TLS && TARGET_ARCH64"
8689   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8690   [(set_attr "type" "load")
8691    (set_attr "us3load_type" "3cycle")])
8692
8693 (define_insn "*tldo_ldsb1_sp64"
8694   [(set (match_operand:HI 0 "register_operand" "=r")
8695         (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8696                                                      (match_operand 3 "tld_symbolic_operand" "")]
8697                                                     UNSPEC_TLSLDO)
8698                                          (match_operand:DI 1 "register_operand" "r")))))]
8699   "TARGET_TLS && TARGET_ARCH64"
8700   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8701   [(set_attr "type" "sload")
8702    (set_attr "us3load_type" "3cycle")])
8703
8704 (define_insn "*tldo_ldsb2_sp64"
8705   [(set (match_operand:SI 0 "register_operand" "=r")
8706         (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8707                                                      (match_operand 3 "tld_symbolic_operand" "")]
8708                                                     UNSPEC_TLSLDO)
8709                                          (match_operand:DI 1 "register_operand" "r")))))]
8710   "TARGET_TLS && TARGET_ARCH64"
8711   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8712   [(set_attr "type" "sload")
8713    (set_attr "us3load_type" "3cycle")])
8714
8715 (define_insn "*tldo_ldsb3_sp64"
8716   [(set (match_operand:DI 0 "register_operand" "=r")
8717         (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8718                                                      (match_operand 3 "tld_symbolic_operand" "")]
8719                                                     UNSPEC_TLSLDO)
8720                                          (match_operand:DI 1 "register_operand" "r")))))]
8721   "TARGET_TLS && TARGET_ARCH64"
8722   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8723   [(set_attr "type" "sload")
8724    (set_attr "us3load_type" "3cycle")])
8725
8726 (define_insn "*tldo_lduh_sp32"
8727   [(set (match_operand:HI 0 "register_operand" "=r")
8728         (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8729                                      (match_operand 3 "tld_symbolic_operand" "")]
8730                                     UNSPEC_TLSLDO)
8731                          (match_operand:SI 1 "register_operand" "r"))))]
8732   "TARGET_TLS && TARGET_ARCH32"
8733   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8734   [(set_attr "type" "load")
8735    (set_attr "us3load_type" "3cycle")])
8736
8737 (define_insn "*tldo_lduh1_sp32"
8738   [(set (match_operand:SI 0 "register_operand" "=r")
8739         (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8740                                                      (match_operand 3 "tld_symbolic_operand" "")]
8741                                                     UNSPEC_TLSLDO)
8742                                          (match_operand:SI 1 "register_operand" "r")))))]
8743   "TARGET_TLS && TARGET_ARCH32"
8744   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8745   [(set_attr "type" "load")
8746    (set_attr "us3load_type" "3cycle")])
8747
8748 (define_insn "*tldo_ldsh1_sp32"
8749   [(set (match_operand:SI 0 "register_operand" "=r")
8750         (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8751                                                      (match_operand 3 "tld_symbolic_operand" "")]
8752                                                     UNSPEC_TLSLDO)
8753                                          (match_operand:SI 1 "register_operand" "r")))))]
8754   "TARGET_TLS && TARGET_ARCH32"
8755   "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8756   [(set_attr "type" "sload")
8757    (set_attr "us3load_type" "3cycle")])
8758
8759 (define_insn "*tldo_lduh_sp64"
8760   [(set (match_operand:HI 0 "register_operand" "=r")
8761         (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8762                                      (match_operand 3 "tld_symbolic_operand" "")]
8763                                     UNSPEC_TLSLDO)
8764                          (match_operand:DI 1 "register_operand" "r"))))]
8765   "TARGET_TLS && TARGET_ARCH64"
8766   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8767   [(set_attr "type" "load")
8768    (set_attr "us3load_type" "3cycle")])
8769
8770 (define_insn "*tldo_lduh1_sp64"
8771   [(set (match_operand:SI 0 "register_operand" "=r")
8772         (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8773                                                      (match_operand 3 "tld_symbolic_operand" "")]
8774                                                     UNSPEC_TLSLDO)
8775                                          (match_operand:DI 1 "register_operand" "r")))))]
8776   "TARGET_TLS && TARGET_ARCH64"
8777   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8778   [(set_attr "type" "load")
8779    (set_attr "us3load_type" "3cycle")])
8780
8781 (define_insn "*tldo_lduh2_sp64"
8782   [(set (match_operand:DI 0 "register_operand" "=r")
8783         (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8784                                                      (match_operand 3 "tld_symbolic_operand" "")]
8785                                                     UNSPEC_TLSLDO)
8786                                          (match_operand:DI 1 "register_operand" "r")))))]
8787   "TARGET_TLS && TARGET_ARCH64"
8788   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8789   [(set_attr "type" "load")
8790    (set_attr "us3load_type" "3cycle")])
8791
8792 (define_insn "*tldo_ldsh1_sp64"
8793   [(set (match_operand:SI 0 "register_operand" "=r")
8794         (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8795                                                      (match_operand 3 "tld_symbolic_operand" "")]
8796                                                     UNSPEC_TLSLDO)
8797                                          (match_operand:DI 1 "register_operand" "r")))))]
8798   "TARGET_TLS && TARGET_ARCH64"
8799   "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8800   [(set_attr "type" "sload")
8801    (set_attr "us3load_type" "3cycle")])
8802
8803 (define_insn "*tldo_ldsh2_sp64"
8804   [(set (match_operand:DI 0 "register_operand" "=r")
8805         (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8806                                                      (match_operand 3 "tld_symbolic_operand" "")]
8807                                                     UNSPEC_TLSLDO)
8808                                          (match_operand:DI 1 "register_operand" "r")))))]
8809   "TARGET_TLS && TARGET_ARCH64"
8810   "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8811   [(set_attr "type" "sload")
8812    (set_attr "us3load_type" "3cycle")])
8813
8814 (define_insn "*tldo_lduw_sp32"
8815   [(set (match_operand:SI 0 "register_operand" "=r")
8816         (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8817                                      (match_operand 3 "tld_symbolic_operand" "")]
8818                                     UNSPEC_TLSLDO)
8819                          (match_operand:SI 1 "register_operand" "r"))))]
8820   "TARGET_TLS && TARGET_ARCH32"
8821   "ld\t[%1 + %2], %0, %%tldo_add(%3)"
8822   [(set_attr "type" "load")])
8823
8824 (define_insn "*tldo_lduw_sp64"
8825   [(set (match_operand:SI 0 "register_operand" "=r")
8826         (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8827                                      (match_operand 3 "tld_symbolic_operand" "")]
8828                                     UNSPEC_TLSLDO)
8829                          (match_operand:DI 1 "register_operand" "r"))))]
8830   "TARGET_TLS && TARGET_ARCH64"
8831   "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8832   [(set_attr "type" "load")])
8833
8834 (define_insn "*tldo_lduw1_sp64"
8835   [(set (match_operand:DI 0 "register_operand" "=r")
8836         (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8837                                                      (match_operand 3 "tld_symbolic_operand" "")]
8838                                                     UNSPEC_TLSLDO)
8839                                          (match_operand:DI 1 "register_operand" "r")))))]
8840   "TARGET_TLS && TARGET_ARCH64"
8841   "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8842   [(set_attr "type" "load")])
8843
8844 (define_insn "*tldo_ldsw1_sp64"
8845   [(set (match_operand:DI 0 "register_operand" "=r")
8846         (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8847                                                      (match_operand 3 "tld_symbolic_operand" "")]
8848                                                     UNSPEC_TLSLDO)
8849                                          (match_operand:DI 1 "register_operand" "r")))))]
8850   "TARGET_TLS && TARGET_ARCH64"
8851   "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
8852   [(set_attr "type" "sload")
8853    (set_attr "us3load_type" "3cycle")])
8854
8855 (define_insn "*tldo_ldx_sp64"
8856   [(set (match_operand:DI 0 "register_operand" "=r")
8857         (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8858                                      (match_operand 3 "tld_symbolic_operand" "")]
8859                                     UNSPEC_TLSLDO)
8860                          (match_operand:DI 1 "register_operand" "r"))))]
8861   "TARGET_TLS && TARGET_ARCH64"
8862   "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
8863   [(set_attr "type" "load")])
8864
8865 (define_insn "*tldo_stb_sp32"
8866   [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8867                                      (match_operand 3 "tld_symbolic_operand" "")]
8868                                     UNSPEC_TLSLDO)
8869                          (match_operand:SI 1 "register_operand" "r")))
8870         (match_operand:QI 0 "register_operand" "=r"))]
8871   "TARGET_TLS && TARGET_ARCH32"
8872   "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8873   [(set_attr "type" "store")])
8874
8875 (define_insn "*tldo_stb_sp64"
8876   [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8877                                      (match_operand 3 "tld_symbolic_operand" "")]
8878                                     UNSPEC_TLSLDO)
8879                          (match_operand:DI 1 "register_operand" "r")))
8880         (match_operand:QI 0 "register_operand" "=r"))]
8881   "TARGET_TLS && TARGET_ARCH64"
8882   "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8883   [(set_attr "type" "store")])
8884
8885 (define_insn "*tldo_sth_sp32"
8886   [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8887                                      (match_operand 3 "tld_symbolic_operand" "")]
8888                                     UNSPEC_TLSLDO)
8889                          (match_operand:SI 1 "register_operand" "r")))
8890         (match_operand:HI 0 "register_operand" "=r"))]
8891   "TARGET_TLS && TARGET_ARCH32"
8892   "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8893   [(set_attr "type" "store")])
8894
8895 (define_insn "*tldo_sth_sp64"
8896   [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8897                                      (match_operand 3 "tld_symbolic_operand" "")]
8898                                     UNSPEC_TLSLDO)
8899                          (match_operand:DI 1 "register_operand" "r")))
8900         (match_operand:HI 0 "register_operand" "=r"))]
8901   "TARGET_TLS && TARGET_ARCH64"
8902   "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8903   [(set_attr "type" "store")])
8904
8905 (define_insn "*tldo_stw_sp32"
8906   [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8907                                      (match_operand 3 "tld_symbolic_operand" "")]
8908                                     UNSPEC_TLSLDO)
8909                          (match_operand:SI 1 "register_operand" "r")))
8910         (match_operand:SI 0 "register_operand" "=r"))]
8911   "TARGET_TLS && TARGET_ARCH32"
8912   "st\t%0, [%1 + %2], %%tldo_add(%3)"
8913   [(set_attr "type" "store")])
8914
8915 (define_insn "*tldo_stw_sp64"
8916   [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8917                                      (match_operand 3 "tld_symbolic_operand" "")]
8918                                     UNSPEC_TLSLDO)
8919                          (match_operand:DI 1 "register_operand" "r")))
8920         (match_operand:SI 0 "register_operand" "=r"))]
8921   "TARGET_TLS && TARGET_ARCH64"
8922   "stw\t%0, [%1 + %2], %%tldo_add(%3)"
8923   [(set_attr "type" "store")])
8924
8925 (define_insn "*tldo_stx_sp64"
8926   [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8927                                      (match_operand 3 "tld_symbolic_operand" "")]
8928                                     UNSPEC_TLSLDO)
8929                          (match_operand:DI 1 "register_operand" "r")))
8930         (match_operand:DI 0 "register_operand" "=r"))]
8931   "TARGET_TLS && TARGET_ARCH64"
8932   "stx\t%0, [%1 + %2], %%tldo_add(%3)"
8933   [(set_attr "type" "store")])