OSDN Git Service

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