OSDN Git Service

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