OSDN Git Service

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