OSDN Git Service

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