* config/i386/i386.c (output_fp_compare): Add generation
[official-gcc.git] / gcc / config / sparc / sparc.md
blob886d190d16ade6bf8305864d2fe1b8c65f3cba05
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.
8 ;; This file is part of GCC.
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.
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.
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.
25 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
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)
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   ])
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   ])
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.
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")))
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"))))
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"))
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)"))
112 (define_attr "branch_type" "none,icc,fcc,reg"
113   (const_string "none"))
115 (define_attr "pic" "false,true"
116   (symbol_ref "flag_pic != 0"))
118 (define_attr "calls_alloca" "false,true"
119   (symbol_ref "current_function_calls_alloca != 0"))
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"))
127 (define_attr "delayed_branch" "false,true"
128   (symbol_ref "flag_delayed_branch != 0"))
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)))
208 ;; FP precision.
209 (define_attr "fptype" "single,double"
210   (const_string "single"))
212 ;; UltraSPARC-III integer load type.
213 (define_attr "us3load_type" "2cycle,3cycle"
214   (const_string "2cycle"))
216 (define_asm_attributes
217   [(set_attr "length" "2")
218    (set_attr "type" "multi")])
220 ;; Attributes for instruction and branch scheduling
221 (define_attr "tls_call_delay" "false,true"
222   (symbol_ref "tls_call_delay (insn)"))
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"))))
236 (define_attr "eligible_for_sibcall_delay" "false,true"
237   (symbol_ref "eligible_for_sibcall_delay (insn)"))
239 (define_attr "eligible_for_return_delay" "false,true"
240   (symbol_ref "eligible_for_return_delay (insn)"))
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.
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.
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")))
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")))
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")))
272 (define_delay (eq_attr "type" "call")
273   [(eq_attr "in_call_delay" "true") (nil) (nil)])
275 (define_delay (eq_attr "type" "sibcall")
276   [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
278 (define_delay (eq_attr "type" "branch")
279   [(eq_attr "in_branch_delay" "true")
280    (nil) (eq_attr "in_annul_branch_delay" "true")])
282 (define_delay (eq_attr "type" "uncond_branch")
283   [(eq_attr "in_uncond_branch_delay" "true")
284    (nil) (nil)])
286 (define_delay (eq_attr "type" "return")
287   [(eq_attr "eligible_for_return_delay" "true") (nil) (nil)])
289 ;; Include SPARC DFA schedulers
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")
299 ;; Compare instructions.
300 ;; This controls RTL generation and register allocation.
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.
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.
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.
315 ;; Put cmpsi first among compare insns so it matches two CONST_INT operands.
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   ""
323   if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx)
324     operands[0] = force_reg (SImode, operands[0]);
326   sparc_compare_op0 = operands[0];
327   sparc_compare_op1 = operands[1];
328   DONE;
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"
337   if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx)
338     operands[0] = force_reg (DImode, operands[0]);
340   sparc_compare_op0 = operands[0];
341   sparc_compare_op1 = operands[1];
342   DONE;
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"
352   sparc_compare_op0 = operands[0];
353   sparc_compare_op1 = operands[1];
354   DONE;
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"
364   sparc_compare_op0 = operands[0];
365   sparc_compare_op1 = operands[1];
366   DONE;
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"
376   sparc_compare_op0 = operands[0];
377   sparc_compare_op1 = operands[1];
378   DONE;
381 ;; Now the compare DEFINE_INSNs.
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")])
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")])
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"
405   if (TARGET_V9)
406     return "fcmpes\t%0, %1, %2";
407   return "fcmpes\t%1, %2";
409   [(set_attr "type" "fpcmp")])
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"
417   if (TARGET_V9)
418     return "fcmped\t%0, %1, %2";
419   return "fcmped\t%1, %2";
421   [(set_attr "type" "fpcmp")
422    (set_attr "fptype" "double")])
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"
430   if (TARGET_V9)
431     return "fcmpeq\t%0, %1, %2";
432   return "fcmpeq\t%1, %2";
434   [(set_attr "type" "fpcmp")])
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"
442   if (TARGET_V9)
443     return "fcmps\t%0, %1, %2";
444   return "fcmps\t%1, %2";
446   [(set_attr "type" "fpcmp")])
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"
454   if (TARGET_V9)
455     return "fcmpd\t%0, %1, %2";
456   return "fcmpd\t%1, %2";
458   [(set_attr "type" "fpcmp")
459    (set_attr "fptype" "double")])
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"
467   if (TARGET_V9)
468     return "fcmpq\t%0, %1, %2";
469   return "fcmpq\t%1, %2";
471   [(set_attr "type" "fpcmp")])
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.
480 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
481 ;; generate addcc/subcc instructions.
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); })
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); })
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); })
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); })
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); })
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); })
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); })
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); })
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   ""
566   if (GET_MODE (sparc_compare_op0) == SImode)
567     {
568       rtx pat;
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;
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;
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   ""
618   if (GET_MODE (sparc_compare_op0) == SImode)
619     {
620       rtx pat;
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;
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;
663 (define_expand "sgt"
664   [(set (match_operand:SI 0 "intreg_operand" "")
665         (gt:SI (match_dup 1) (const_int 0)))]
666   ""
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;
683 (define_expand "slt"
684   [(set (match_operand:SI 0 "intreg_operand" "")
685         (lt:SI (match_dup 1) (const_int 0)))]
686   ""
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;
703 (define_expand "sge"
704   [(set (match_operand:SI 0 "intreg_operand" "")
705         (ge:SI (match_dup 1) (const_int 0)))]
706   ""
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;
723 (define_expand "sle"
724   [(set (match_operand:SI 0 "intreg_operand" "")
725         (le:SI (match_dup 1) (const_int 0)))]
726   ""
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;
743 (define_expand "sgtu"
744   [(set (match_operand:SI 0 "intreg_operand" "")
745         (gtu:SI (match_dup 1) (const_int 0)))]
746   ""
748   if (! TARGET_V9)
749     {
750       rtx tem, pat;
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;
777 (define_expand "sltu"
778   [(set (match_operand:SI 0 "intreg_operand" "")
779         (ltu:SI (match_dup 1) (const_int 0)))]
780   ""
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);
790 (define_expand "sgeu"
791   [(set (match_operand:SI 0 "intreg_operand" "")
792         (geu:SI (match_dup 1) (const_int 0)))]
793   ""
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);
803 (define_expand "sleu"
804   [(set (match_operand:SI 0 "intreg_operand" "")
805         (leu:SI (match_dup 1) (const_int 0)))]
806   ""
808   if (! TARGET_V9)
809     {
810       rtx tem, pat;
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;
837 ;; Now the DEFINE_INSNs for the scc cases.
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.
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")]) 
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")])
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.
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")])
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")])
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")])
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")])
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.
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")])
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")])
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")])
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")])
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")])
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")])
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.
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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   ;; 32 bit LTU/GEU are better implemented using addx/subx
1213   "TARGET_V9 && REGNO (operands[1]) == SPARC_ICC_REG
1214    && (GET_MODE (operands[1]) == CCXmode
1215        || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1216   [(set (match_dup 0) (const_int 0))
1217    (set (match_dup 0)
1218         (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1219                          (const_int 1)
1220                          (match_dup 0)))]
1221   "")
1224 ;; These control RTL generation for conditional jump insns
1226 ;; The quad-word fp compare library routines all return nonzero to indicate
1227 ;; true, which is different from the equivalent libgcc routines, so we must
1228 ;; handle them specially here.
1230 (define_expand "beq"
1231   [(set (pc)
1232         (if_then_else (eq (match_dup 1) (const_int 0))
1233                       (label_ref (match_operand 0 "" ""))
1234                       (pc)))]
1235   ""
1237   if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1238       && GET_CODE (sparc_compare_op0) == REG
1239       && GET_MODE (sparc_compare_op0) == DImode)
1240     {
1241       emit_v9_brxx_insn (EQ, sparc_compare_op0, operands[0]);
1242       DONE;
1243     }
1244   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1245     {
1246       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
1247       emit_jump_insn (gen_bne (operands[0]));
1248       DONE;
1249     }
1250   operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1);
1253 (define_expand "bne"
1254   [(set (pc)
1255         (if_then_else (ne (match_dup 1) (const_int 0))
1256                       (label_ref (match_operand 0 "" ""))
1257                       (pc)))]
1258   ""
1260   if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1261       && GET_CODE (sparc_compare_op0) == REG
1262       && GET_MODE (sparc_compare_op0) == DImode)
1263     {
1264       emit_v9_brxx_insn (NE, sparc_compare_op0, operands[0]);
1265       DONE;
1266     }
1267   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1268     {
1269       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
1270       emit_jump_insn (gen_bne (operands[0]));
1271       DONE;
1272     }
1273   operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1);
1276 (define_expand "bgt"
1277   [(set (pc)
1278         (if_then_else (gt (match_dup 1) (const_int 0))
1279                       (label_ref (match_operand 0 "" ""))
1280                       (pc)))]
1281   ""
1283   if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1284       && GET_CODE (sparc_compare_op0) == REG
1285       && GET_MODE (sparc_compare_op0) == DImode)
1286     {
1287       emit_v9_brxx_insn (GT, sparc_compare_op0, operands[0]);
1288       DONE;
1289     }
1290   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1291     {
1292       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
1293       emit_jump_insn (gen_bne (operands[0]));
1294       DONE;
1295     }
1296   operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1);
1299 (define_expand "bgtu"
1300   [(set (pc)
1301         (if_then_else (gtu (match_dup 1) (const_int 0))
1302                       (label_ref (match_operand 0 "" ""))
1303                       (pc)))]
1304   ""
1306   operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1);
1309 (define_expand "blt"
1310   [(set (pc)
1311         (if_then_else (lt (match_dup 1) (const_int 0))
1312                       (label_ref (match_operand 0 "" ""))
1313                       (pc)))]
1314   ""
1316   if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1317       && GET_CODE (sparc_compare_op0) == REG
1318       && GET_MODE (sparc_compare_op0) == DImode)
1319     {
1320       emit_v9_brxx_insn (LT, sparc_compare_op0, operands[0]);
1321       DONE;
1322     }
1323   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1324     {
1325       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
1326       emit_jump_insn (gen_bne (operands[0]));
1327       DONE;
1328     }
1329   operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1);
1332 (define_expand "bltu"
1333   [(set (pc)
1334         (if_then_else (ltu (match_dup 1) (const_int 0))
1335                       (label_ref (match_operand 0 "" ""))
1336                       (pc)))]
1337   ""
1339   operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
1342 (define_expand "bge"
1343   [(set (pc)
1344         (if_then_else (ge (match_dup 1) (const_int 0))
1345                       (label_ref (match_operand 0 "" ""))
1346                       (pc)))]
1347   ""
1349   if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1350       && GET_CODE (sparc_compare_op0) == REG
1351       && GET_MODE (sparc_compare_op0) == DImode)
1352     {
1353       emit_v9_brxx_insn (GE, sparc_compare_op0, operands[0]);
1354       DONE;
1355     }
1356   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1357     {
1358       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
1359       emit_jump_insn (gen_bne (operands[0]));
1360       DONE;
1361     }
1362   operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1);
1365 (define_expand "bgeu"
1366   [(set (pc)
1367         (if_then_else (geu (match_dup 1) (const_int 0))
1368                       (label_ref (match_operand 0 "" ""))
1369                       (pc)))]
1370   ""
1372   operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
1375 (define_expand "ble"
1376   [(set (pc)
1377         (if_then_else (le (match_dup 1) (const_int 0))
1378                       (label_ref (match_operand 0 "" ""))
1379                       (pc)))]
1380   ""
1382   if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1383       && GET_CODE (sparc_compare_op0) == REG
1384       && GET_MODE (sparc_compare_op0) == DImode)
1385     {
1386       emit_v9_brxx_insn (LE, sparc_compare_op0, operands[0]);
1387       DONE;
1388     }
1389   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1390     {
1391       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
1392       emit_jump_insn (gen_bne (operands[0]));
1393       DONE;
1394     }
1395   operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1);
1398 (define_expand "bleu"
1399   [(set (pc)
1400         (if_then_else (leu (match_dup 1) (const_int 0))
1401                       (label_ref (match_operand 0 "" ""))
1402                       (pc)))]
1403   ""
1405   operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
1408 (define_expand "bunordered"
1409   [(set (pc)
1410         (if_then_else (unordered (match_dup 1) (const_int 0))
1411                       (label_ref (match_operand 0 "" ""))
1412                       (pc)))]
1413   ""
1415   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1416     {
1417       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1,
1418                                 UNORDERED);
1419       emit_jump_insn (gen_beq (operands[0]));
1420       DONE;
1421     }
1422   operands[1] = gen_compare_reg (UNORDERED, sparc_compare_op0,
1423                                  sparc_compare_op1);
1426 (define_expand "bordered"
1427   [(set (pc)
1428         (if_then_else (ordered (match_dup 1) (const_int 0))
1429                       (label_ref (match_operand 0 "" ""))
1430                       (pc)))]
1431   ""
1433   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1434     {
1435       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, ORDERED);
1436       emit_jump_insn (gen_bne (operands[0]));
1437       DONE;
1438     }
1439   operands[1] = gen_compare_reg (ORDERED, sparc_compare_op0,
1440                                  sparc_compare_op1);
1443 (define_expand "bungt"
1444   [(set (pc)
1445         (if_then_else (ungt (match_dup 1) (const_int 0))
1446                       (label_ref (match_operand 0 "" ""))
1447                       (pc)))]
1448   ""
1450   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1451     {
1452       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGT);
1453       emit_jump_insn (gen_bgt (operands[0]));
1454       DONE;
1455     }
1456   operands[1] = gen_compare_reg (UNGT, sparc_compare_op0, sparc_compare_op1);
1459 (define_expand "bunlt"
1460   [(set (pc)
1461         (if_then_else (unlt (match_dup 1) (const_int 0))
1462                       (label_ref (match_operand 0 "" ""))
1463                       (pc)))]
1464   ""
1466   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1467     {
1468       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLT);
1469       emit_jump_insn (gen_bne (operands[0]));
1470       DONE;
1471     }
1472   operands[1] = gen_compare_reg (UNLT, sparc_compare_op0, sparc_compare_op1);
1475 (define_expand "buneq"
1476   [(set (pc)
1477         (if_then_else (uneq (match_dup 1) (const_int 0))
1478                       (label_ref (match_operand 0 "" ""))
1479                       (pc)))]
1480   ""
1482   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1483     {
1484       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNEQ);
1485       emit_jump_insn (gen_beq (operands[0]));
1486       DONE;
1487     }
1488   operands[1] = gen_compare_reg (UNEQ, sparc_compare_op0, sparc_compare_op1);
1491 (define_expand "bunge"
1492   [(set (pc)
1493         (if_then_else (unge (match_dup 1) (const_int 0))
1494                       (label_ref (match_operand 0 "" ""))
1495                       (pc)))]
1496   ""
1498   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1499     {
1500       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGE);
1501       emit_jump_insn (gen_bne (operands[0]));
1502       DONE;
1503     }
1504   operands[1] = gen_compare_reg (UNGE, sparc_compare_op0, sparc_compare_op1);
1507 (define_expand "bunle"
1508   [(set (pc)
1509         (if_then_else (unle (match_dup 1) (const_int 0))
1510                       (label_ref (match_operand 0 "" ""))
1511                       (pc)))]
1512   ""
1514   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1515     {
1516       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLE);
1517       emit_jump_insn (gen_bne (operands[0]));
1518       DONE;
1519     }
1520   operands[1] = gen_compare_reg (UNLE, sparc_compare_op0, sparc_compare_op1);
1523 (define_expand "bltgt"
1524   [(set (pc)
1525         (if_then_else (ltgt (match_dup 1) (const_int 0))
1526                       (label_ref (match_operand 0 "" ""))
1527                       (pc)))]
1528   ""
1530   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1531     {
1532       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LTGT);
1533       emit_jump_insn (gen_bne (operands[0]));
1534       DONE;
1535     }
1536   operands[1] = gen_compare_reg (LTGT, sparc_compare_op0, sparc_compare_op1);
1539 ;; Now match both normal and inverted jump.
1541 ;; XXX fpcmp nop braindamage
1542 (define_insn "*normal_branch"
1543   [(set (pc)
1544         (if_then_else (match_operator 0 "noov_compare_op"
1545                                       [(reg 100) (const_int 0)])
1546                       (label_ref (match_operand 1 "" ""))
1547                       (pc)))]
1548   ""
1550   return output_cbranch (operands[0], operands[1], 1, 0,
1551                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1552                          insn);
1554   [(set_attr "type" "branch")
1555    (set_attr "branch_type" "icc")])
1557 ;; XXX fpcmp nop braindamage
1558 (define_insn "*inverted_branch"
1559   [(set (pc)
1560         (if_then_else (match_operator 0 "noov_compare_op"
1561                                       [(reg 100) (const_int 0)])
1562                       (pc)
1563                       (label_ref (match_operand 1 "" ""))))]
1564   ""
1566   return output_cbranch (operands[0], operands[1], 1, 1,
1567                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1568                          insn);
1570   [(set_attr "type" "branch")
1571    (set_attr "branch_type" "icc")])
1573 ;; XXX fpcmp nop braindamage
1574 (define_insn "*normal_fp_branch"
1575   [(set (pc)
1576         (if_then_else (match_operator 1 "comparison_operator"
1577                                       [(match_operand:CCFP 0 "fcc_reg_operand" "c")
1578                                        (const_int 0)])
1579                       (label_ref (match_operand 2 "" ""))
1580                       (pc)))]
1581   ""
1583   return output_cbranch (operands[1], operands[2], 2, 0,
1584                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1585                          insn);
1587   [(set_attr "type" "branch")
1588    (set_attr "branch_type" "fcc")])
1590 ;; XXX fpcmp nop braindamage
1591 (define_insn "*inverted_fp_branch"
1592   [(set (pc)
1593         (if_then_else (match_operator 1 "comparison_operator"
1594                                       [(match_operand:CCFP 0 "fcc_reg_operand" "c")
1595                                        (const_int 0)])
1596                       (pc)
1597                       (label_ref (match_operand 2 "" ""))))]
1598   ""
1600   return output_cbranch (operands[1], operands[2], 2, 1,
1601                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1602                          insn);
1604   [(set_attr "type" "branch")
1605    (set_attr "branch_type" "fcc")])
1607 ;; XXX fpcmp nop braindamage
1608 (define_insn "*normal_fpe_branch"
1609   [(set (pc)
1610         (if_then_else (match_operator 1 "comparison_operator"
1611                                       [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
1612                                        (const_int 0)])
1613                       (label_ref (match_operand 2 "" ""))
1614                       (pc)))]
1615   ""
1617   return output_cbranch (operands[1], operands[2], 2, 0,
1618                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1619                          insn);
1621   [(set_attr "type" "branch")
1622    (set_attr "branch_type" "fcc")])
1624 ;; XXX fpcmp nop braindamage
1625 (define_insn "*inverted_fpe_branch"
1626   [(set (pc)
1627         (if_then_else (match_operator 1 "comparison_operator"
1628                                       [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
1629                                        (const_int 0)])
1630                       (pc)
1631                       (label_ref (match_operand 2 "" ""))))]
1632   ""
1634   return output_cbranch (operands[1], operands[2], 2, 1,
1635                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1636                          insn);
1638   [(set_attr "type" "branch")
1639    (set_attr "branch_type" "fcc")])
1641 ;; SPARC V9-specific jump insns.  None of these are guaranteed to be
1642 ;; in the architecture.
1644 ;; There are no 32 bit brreg insns.
1646 ;; XXX
1647 (define_insn "*normal_int_branch_sp64"
1648   [(set (pc)
1649         (if_then_else (match_operator 0 "v9_regcmp_op"
1650                                       [(match_operand:DI 1 "register_operand" "r")
1651                                        (const_int 0)])
1652                       (label_ref (match_operand 2 "" ""))
1653                       (pc)))]
1654   "TARGET_ARCH64"
1656   return output_v9branch (operands[0], operands[2], 1, 2, 0,
1657                           final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1658                           insn);
1660   [(set_attr "type" "branch")
1661    (set_attr "branch_type" "reg")])
1663 ;; XXX
1664 (define_insn "*inverted_int_branch_sp64"
1665   [(set (pc)
1666         (if_then_else (match_operator 0 "v9_regcmp_op"
1667                                       [(match_operand:DI 1 "register_operand" "r")
1668                                        (const_int 0)])
1669                       (pc)
1670                       (label_ref (match_operand 2 "" ""))))]
1671   "TARGET_ARCH64"
1673   return output_v9branch (operands[0], operands[2], 1, 2, 1,
1674                           final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1675                           insn);
1677   [(set_attr "type" "branch")
1678    (set_attr "branch_type" "reg")])
1680 ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic
1681 ;; value subject to a PC-relative relocation.  Operand 2 is a helper function
1682 ;; that adds the PC value at the call point to operand 0.
1684 (define_insn "load_pcrel_sym"
1685   [(set (match_operand 0 "register_operand" "=r")
1686         (unspec [(match_operand 1 "symbolic_operand" "")
1687                  (match_operand 2 "call_operand_address" "")] UNSPEC_LOAD_PCREL_SYM))
1688    (clobber (reg:SI 15))]
1689   ""
1691   if (flag_delayed_branch)
1692     return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0";
1693   else
1694     return "sethi\t%%hi(%a1-8), %0\n\tadd\t%0, %%lo(%a1-4), %0\n\tcall\t%a2\n\t nop";
1696   [(set (attr "type") (const_string "multi"))
1697    (set (attr "length")
1698         (if_then_else (eq_attr "delayed_branch" "true")
1699                       (const_int 3)
1700                       (const_int 4)))])
1702 ;; Move instructions
1704 (define_expand "movqi"
1705   [(set (match_operand:QI 0 "general_operand" "")
1706         (match_operand:QI 1 "general_operand" ""))]
1707   ""
1709   /* Working with CONST_INTs is easier, so convert
1710      a double if needed.  */
1711   if (GET_CODE (operands[1]) == CONST_DOUBLE)
1712     {
1713       operands[1] = GEN_INT (trunc_int_for_mode
1714                              (CONST_DOUBLE_LOW (operands[1]), QImode));
1715     }
1717   /* Handle sets of MEM first.  */
1718   if (GET_CODE (operands[0]) == MEM)
1719     {
1720       if (reg_or_0_operand (operands[1], QImode))
1721         goto movqi_is_ok;
1723       if (! reload_in_progress)
1724         {
1725           operands[0] = validize_mem (operands[0]);
1726           operands[1] = force_reg (QImode, operands[1]);
1727         }
1728     }
1730   /* Fixup TLS cases.  */
1731   if (tls_symbolic_operand (operands [1]))
1732     operands[1] = legitimize_tls_address (operands[1]);
1734   /* Fixup PIC cases.  */
1735   if (flag_pic)
1736     {
1737       if (CONSTANT_P (operands[1])
1738           && pic_address_needs_scratch (operands[1]))
1739         operands[1] = legitimize_pic_address (operands[1], QImode, 0);
1741       if (symbolic_operand (operands[1], QImode))
1742         {
1743           operands[1] = legitimize_pic_address (operands[1],
1744                                                 QImode,
1745                                                 (reload_in_progress ?
1746                                                  operands[0] :
1747                                                  NULL_RTX));
1748           goto movqi_is_ok;
1749         }
1750     }
1752   /* All QI constants require only one insn, so proceed.  */
1754  movqi_is_ok:
1755   ;
1758 (define_insn "*movqi_insn"
1759   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1760         (match_operand:QI 1 "input_operand"   "rI,m,rJ"))]
1761   "(register_operand (operands[0], QImode)
1762     || reg_or_0_operand (operands[1], QImode))"
1763   "@
1764    mov\t%1, %0
1765    ldub\t%1, %0
1766    stb\t%r1, %0"
1767   [(set_attr "type" "*,load,store")
1768    (set_attr "us3load_type" "*,3cycle,*")])
1770 (define_expand "movhi"
1771   [(set (match_operand:HI 0 "general_operand" "")
1772         (match_operand:HI 1 "general_operand" ""))]
1773   ""
1775   /* Working with CONST_INTs is easier, so convert
1776      a double if needed.  */
1777   if (GET_CODE (operands[1]) == CONST_DOUBLE)
1778     operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
1780   /* Handle sets of MEM first.  */
1781   if (GET_CODE (operands[0]) == MEM)
1782     {
1783       if (reg_or_0_operand (operands[1], HImode))
1784         goto movhi_is_ok;
1786       if (! reload_in_progress)
1787         {
1788           operands[0] = validize_mem (operands[0]);
1789           operands[1] = force_reg (HImode, operands[1]);
1790         }
1791     }
1793   /* Fixup TLS cases.  */
1794   if (tls_symbolic_operand (operands [1]))
1795     operands[1] = legitimize_tls_address (operands[1]);
1797   /* Fixup PIC cases.  */
1798   if (flag_pic)
1799     {
1800       if (CONSTANT_P (operands[1])
1801           && pic_address_needs_scratch (operands[1]))
1802         operands[1] = legitimize_pic_address (operands[1], HImode, 0);
1804       if (symbolic_operand (operands[1], HImode))
1805         {
1806           operands[1] = legitimize_pic_address (operands[1],
1807                                                 HImode,
1808                                                 (reload_in_progress ?
1809                                                  operands[0] :
1810                                                  NULL_RTX));
1811           goto movhi_is_ok;
1812         }
1813     }
1815   /* This makes sure we will not get rematched due to splittage.  */
1816   if (! CONSTANT_P (operands[1]) || input_operand (operands[1], HImode))
1817     ;
1818   else if (CONSTANT_P (operands[1])
1819            && GET_CODE (operands[1]) != HIGH
1820            && GET_CODE (operands[1]) != LO_SUM)
1821     {
1822       sparc_emit_set_const32 (operands[0], operands[1]);
1823       DONE;
1824     }
1825  movhi_is_ok:
1826   ;
1829 (define_insn "*movhi_const64_special"
1830   [(set (match_operand:HI 0 "register_operand" "=r")
1831         (match_operand:HI 1 "const64_high_operand" ""))]
1832   "TARGET_ARCH64"
1833   "sethi\t%%hi(%a1), %0")
1835 (define_insn "*movhi_insn"
1836   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1837         (match_operand:HI 1 "input_operand"   "rI,K,m,rJ"))]
1838   "(register_operand (operands[0], HImode)
1839     || reg_or_0_operand (operands[1], HImode))"
1840   "@
1841    mov\t%1, %0
1842    sethi\t%%hi(%a1), %0
1843    lduh\t%1, %0
1844    sth\t%r1, %0"
1845   [(set_attr "type" "*,*,load,store")
1846    (set_attr "us3load_type" "*,*,3cycle,*")])
1848 ;; We always work with constants here.
1849 (define_insn "*movhi_lo_sum"
1850   [(set (match_operand:HI 0 "register_operand" "=r")
1851         (ior:HI (match_operand:HI 1 "register_operand" "%r")
1852                 (match_operand:HI 2 "small_int" "I")))]
1853   ""
1854   "or\t%1, %2, %0")
1856 (define_expand "movsi"
1857   [(set (match_operand:SI 0 "general_operand" "")
1858         (match_operand:SI 1 "general_operand" ""))]
1859   ""
1861   /* Working with CONST_INTs is easier, so convert
1862      a double if needed.  */
1863   if (GET_CODE (operands[1]) == CONST_DOUBLE)
1864     operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
1866   /* Handle sets of MEM first.  */
1867   if (GET_CODE (operands[0]) == MEM)
1868     {
1869       if (reg_or_0_operand (operands[1], SImode))
1870         goto movsi_is_ok;
1872       if (! reload_in_progress)
1873         {
1874           operands[0] = validize_mem (operands[0]);
1875           operands[1] = force_reg (SImode, operands[1]);
1876         }
1877     }
1879   /* Fixup TLS cases.  */
1880   if (tls_symbolic_operand (operands [1]))
1881     operands[1] = legitimize_tls_address (operands[1]);
1883   /* Fixup PIC cases.  */
1884   if (flag_pic)
1885     {
1886       if (CONSTANT_P (operands[1])
1887           && pic_address_needs_scratch (operands[1]))
1888         operands[1] = legitimize_pic_address (operands[1], SImode, 0);
1890       if (GET_CODE (operands[1]) == LABEL_REF)
1891         {
1892           /* shit */
1893           emit_insn (gen_movsi_pic_label_ref (operands[0], operands[1]));
1894           DONE;
1895         }
1897       if (symbolic_operand (operands[1], SImode))
1898         {
1899           operands[1] = legitimize_pic_address (operands[1],
1900                                                 SImode,
1901                                                 (reload_in_progress ?
1902                                                  operands[0] :
1903                                                  NULL_RTX));
1904           goto movsi_is_ok;
1905         }
1906     }
1908   /* If we are trying to toss an integer constant into the
1909      FPU registers, force it into memory.  */
1910   if (GET_CODE (operands[0]) == REG
1911       && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
1912       && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
1913       && CONSTANT_P (operands[1]))
1914     operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
1915                                                  operands[1]));
1917   /* This makes sure we will not get rematched due to splittage.  */
1918   if (! CONSTANT_P (operands[1]) || input_operand (operands[1], SImode))
1919     ;
1920   else if (CONSTANT_P (operands[1])
1921            && GET_CODE (operands[1]) != HIGH
1922            && GET_CODE (operands[1]) != LO_SUM)
1923     {
1924       sparc_emit_set_const32 (operands[0], operands[1]);
1925       DONE;
1926     }
1927  movsi_is_ok:
1928   ;
1931 ;; This is needed to show CSE exactly which bits are set
1932 ;; in a 64-bit register by sethi instructions.
1933 (define_insn "*movsi_const64_special"
1934   [(set (match_operand:SI 0 "register_operand" "=r")
1935         (match_operand:SI 1 "const64_high_operand" ""))]
1936   "TARGET_ARCH64"
1937   "sethi\t%%hi(%a1), %0")
1939 (define_insn "*movsi_insn"
1940   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,f,r,r,r,f,m,m,d")
1941         (match_operand:SI 1 "input_operand"   "rI,!f,K,J,m,!m,rJ,!f,J"))]
1942   "(register_operand (operands[0], SImode)
1943     || reg_or_0_operand (operands[1], SImode))"
1944   "@
1945    mov\t%1, %0
1946    fmovs\t%1, %0
1947    sethi\t%%hi(%a1), %0
1948    clr\t%0
1949    ld\t%1, %0
1950    ld\t%1, %0
1951    st\t%r1, %0
1952    st\t%1, %0
1953    fzeros\t%0"
1954   [(set_attr "type" "*,fpmove,*,*,load,fpload,store,fpstore,fga")])
1956 (define_insn "*movsi_lo_sum"
1957   [(set (match_operand:SI 0 "register_operand" "=r")
1958         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1959                    (match_operand:SI 2 "immediate_operand" "in")))]
1960   ""
1961   "or\t%1, %%lo(%a2), %0")
1963 (define_insn "*movsi_high"
1964   [(set (match_operand:SI 0 "register_operand" "=r")
1965         (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1966   ""
1967   "sethi\t%%hi(%a1), %0")
1969 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1970 ;; so that CSE won't optimize the address computation away.
1971 (define_insn "movsi_lo_sum_pic"
1972   [(set (match_operand:SI 0 "register_operand" "=r")
1973         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1974                    (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1975   "flag_pic"
1976   "or\t%1, %%lo(%a2), %0")
1978 (define_insn "movsi_high_pic"
1979   [(set (match_operand:SI 0 "register_operand" "=r")
1980         (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1981   "flag_pic && check_pic (1)"
1982   "sethi\t%%hi(%a1), %0")
1984 (define_expand "movsi_pic_label_ref"
1985   [(set (match_dup 3) (high:SI
1986      (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1987                  (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1988    (set (match_dup 4) (lo_sum:SI (match_dup 3)
1989      (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1990    (set (match_operand:SI 0 "register_operand" "=r")
1991         (minus:SI (match_dup 5) (match_dup 4)))]
1992   "flag_pic"
1994   current_function_uses_pic_offset_table = 1;
1995   operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1996   if (no_new_pseudos)
1997     {
1998       operands[3] = operands[0];
1999       operands[4] = operands[0];
2000     }
2001   else
2002     {
2003       operands[3] = gen_reg_rtx (SImode);
2004       operands[4] = gen_reg_rtx (SImode);
2005     }
2006   operands[5] = pic_offset_table_rtx;
2009 (define_insn "*movsi_high_pic_label_ref"
2010   [(set (match_operand:SI 0 "register_operand" "=r")
2011       (high:SI
2012         (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
2013                     (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2014   "flag_pic"
2015   "sethi\t%%hi(%a2-(%a1-.)), %0")
2017 (define_insn "*movsi_lo_sum_pic_label_ref"
2018   [(set (match_operand:SI 0 "register_operand" "=r")
2019       (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2020         (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
2021                     (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2022   "flag_pic"
2023   "or\t%1, %%lo(%a3-(%a2-.)), %0")
2025 (define_expand "movdi"
2026   [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
2027         (match_operand:DI 1 "general_operand" ""))]
2028   ""
2030   /* Where possible, convert CONST_DOUBLE into a CONST_INT.  */
2031   if (GET_CODE (operands[1]) == CONST_DOUBLE
2032 #if HOST_BITS_PER_WIDE_INT == 32
2033       && ((CONST_DOUBLE_HIGH (operands[1]) == 0
2034            && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) == 0)
2035           || (CONST_DOUBLE_HIGH (operands[1]) == (HOST_WIDE_INT) 0xffffffff
2036               && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) != 0))
2037 #endif
2038       )
2039     operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2041   /* Handle MEM cases first.  */
2042   if (GET_CODE (operands[0]) == MEM)
2043     {
2044       /* If it's a REG, we can always do it.
2045          The const zero case is more complex, on v9
2046          we can always perform it.  */
2047       if (register_operand (operands[1], DImode)
2048           || (TARGET_V9
2049               && (operands[1] == const0_rtx)))
2050         goto movdi_is_ok;
2052       if (! reload_in_progress)
2053         {
2054           operands[0] = validize_mem (operands[0]);
2055           operands[1] = force_reg (DImode, operands[1]);
2056         }
2057     }
2059   /* Fixup TLS cases.  */
2060   if (tls_symbolic_operand (operands [1]))
2061     operands[1] = legitimize_tls_address (operands[1]);
2063   if (flag_pic)
2064     {
2065       if (CONSTANT_P (operands[1])
2066           && pic_address_needs_scratch (operands[1]))
2067         operands[1] = legitimize_pic_address (operands[1], DImode, 0);
2069       if (GET_CODE (operands[1]) == LABEL_REF)
2070         {
2071           if (! TARGET_ARCH64)
2072             abort ();
2073           emit_insn (gen_movdi_pic_label_ref (operands[0], operands[1]));
2074           DONE;
2075         }
2077       if (symbolic_operand (operands[1], DImode))
2078         {
2079           operands[1] = legitimize_pic_address (operands[1],
2080                                                 DImode,
2081                                                 (reload_in_progress ?
2082                                                  operands[0] :
2083                                                  NULL_RTX));
2084           goto movdi_is_ok;
2085         }
2086     }
2088   /* If we are trying to toss an integer constant into the
2089      FPU registers, force it into memory.  */
2090   if (GET_CODE (operands[0]) == REG
2091       && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
2092       && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
2093       && CONSTANT_P (operands[1]))
2094     operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2095                                                  operands[1]));
2097   /* This makes sure we will not get rematched due to splittage.  */
2098   if (! CONSTANT_P (operands[1]) || input_operand (operands[1], DImode))
2099     ;
2100   else if (TARGET_ARCH64
2101            && CONSTANT_P (operands[1])
2102            && GET_CODE (operands[1]) != HIGH
2103            && GET_CODE (operands[1]) != LO_SUM)
2104     {
2105       sparc_emit_set_const64 (operands[0], operands[1]);
2106       DONE;
2107     }
2109  movdi_is_ok:
2110   ;
2113 ;; Be careful, fmovd does not exist when !v9.
2114 ;; We match MEM moves directly when we have correct even
2115 ;; numbered registers, but fall into splits otherwise.
2116 ;; The constraint ordering here is really important to
2117 ;; avoid insane problems in reload, especially for patterns
2118 ;; of the form:
2120 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
2121 ;;                       (const_int -5016)))
2122 ;;      (reg:DI 2 %g2))
2125 (define_insn "*movdi_insn_sp32_v9"
2126   [(set (match_operand:DI 0 "nonimmediate_operand"
2127                                         "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?e,?e,?W")
2128         (match_operand:DI 1 "input_operand"
2129                                         " J,J,U,T,r,o,i,r, f, T, o, f, e, W, e"))]
2130   "! TARGET_ARCH64 && TARGET_V9
2131    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2132   "@
2133    stx\t%%g0, %0
2134    #
2135    std\t%1, %0
2136    ldd\t%1, %0
2137    #
2138    #
2139    #
2140    #
2141    std\t%1, %0
2142    ldd\t%1, %0
2143    #
2144    #
2145    fmovd\\t%1, %0
2146    ldd\\t%1, %0
2147    std\\t%1, %0"
2148   [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,fpload,fpstore")
2149    (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,*,*")
2150    (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])
2152 (define_insn "*movdi_insn_sp32"
2153   [(set (match_operand:DI 0 "nonimmediate_operand"
2154                                 "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
2155         (match_operand:DI 1 "input_operand"
2156                                 " J,U,T,r,o,i,r, f, T, o, f, f"))]
2157   "! TARGET_ARCH64
2158    && (register_operand (operands[0], DImode)
2159        || register_operand (operands[1], DImode))"
2160   "@
2161    #
2162    std\t%1, %0
2163    ldd\t%1, %0
2164    #
2165    #
2166    #
2167    #
2168    std\t%1, %0
2169    ldd\t%1, %0
2170    #
2171    #
2172    #"
2173   [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
2174    (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
2176 ;; The following are generated by sparc_emit_set_const64
2177 (define_insn "*movdi_sp64_dbl"
2178   [(set (match_operand:DI 0 "register_operand" "=r")
2179         (match_operand:DI 1 "const64_operand" ""))]
2180   "(TARGET_ARCH64
2181     && HOST_BITS_PER_WIDE_INT != 64)"
2182   "mov\t%1, %0")
2184 ;; This is needed to show CSE exactly which bits are set
2185 ;; in a 64-bit register by sethi instructions.
2186 (define_insn "*movdi_const64_special"
2187   [(set (match_operand:DI 0 "register_operand" "=r")
2188         (match_operand:DI 1 "const64_high_operand" ""))]
2189   "TARGET_ARCH64"
2190   "sethi\t%%hi(%a1), %0")
2192 (define_insn "*movdi_insn_sp64_novis"
2193   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?W")
2194         (match_operand:DI 1 "input_operand"   "rI,N,J,m,rJ,e,W,e"))]
2195   "TARGET_ARCH64 && ! TARGET_VIS
2196    && (register_operand (operands[0], DImode)
2197        || reg_or_0_operand (operands[1], DImode))"
2198   "@
2199    mov\t%1, %0
2200    sethi\t%%hi(%a1), %0
2201    clr\t%0
2202    ldx\t%1, %0
2203    stx\t%r1, %0
2204    fmovd\t%1, %0
2205    ldd\t%1, %0
2206    std\t%1, %0"
2207   [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore")
2208    (set_attr "fptype" "*,*,*,*,*,double,*,*")])
2210 (define_insn "*movdi_insn_sp64_vis"
2211   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?W,b")
2212         (match_operand:DI 1 "input_operand"   "rI,N,J,m,rJ,e,W,e,J"))]
2213   "TARGET_ARCH64 && TARGET_VIS &&
2214    (register_operand (operands[0], DImode)
2215     || reg_or_0_operand (operands[1], DImode))"
2216   "@
2217    mov\t%1, %0
2218    sethi\t%%hi(%a1), %0
2219    clr\t%0
2220    ldx\t%1, %0
2221    stx\t%r1, %0
2222    fmovd\t%1, %0
2223    ldd\t%1, %0
2224    std\t%1, %0
2225    fzero\t%0"
2226   [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore,fga")
2227    (set_attr "fptype" "*,*,*,*,*,double,*,*,double")])
2229 (define_expand "movdi_pic_label_ref"
2230   [(set (match_dup 3) (high:DI
2231      (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2232                  (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2233    (set (match_dup 4) (lo_sum:DI (match_dup 3)
2234      (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2235    (set (match_operand:DI 0 "register_operand" "=r")
2236         (minus:DI (match_dup 5) (match_dup 4)))]
2237   "TARGET_ARCH64 && flag_pic"
2239   current_function_uses_pic_offset_table = 1;
2240   operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
2241   if (no_new_pseudos)
2242     {
2243       operands[3] = operands[0];
2244       operands[4] = operands[0];
2245     }
2246   else
2247     {
2248       operands[3] = gen_reg_rtx (DImode);
2249       operands[4] = gen_reg_rtx (DImode);
2250     }
2251   operands[5] = pic_offset_table_rtx;
2254 (define_insn "*movdi_high_pic_label_ref"
2255   [(set (match_operand:DI 0 "register_operand" "=r")
2256         (high:DI
2257           (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2258                       (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2259   "TARGET_ARCH64 && flag_pic"
2260   "sethi\t%%hi(%a2-(%a1-.)), %0")
2262 (define_insn "*movdi_lo_sum_pic_label_ref"
2263   [(set (match_operand:DI 0 "register_operand" "=r")
2264       (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2265         (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
2266                     (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2267   "TARGET_ARCH64 && flag_pic"
2268   "or\t%1, %%lo(%a3-(%a2-.)), %0")
2270 ;; SPARC-v9 code model support insns.  See sparc_emit_set_symbolic_const64
2271 ;; in sparc.c to see what is going on here... PIC stuff comes first.
2273 (define_insn "movdi_lo_sum_pic"
2274   [(set (match_operand:DI 0 "register_operand" "=r")
2275         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2276                    (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
2277   "TARGET_ARCH64 && flag_pic"
2278   "or\t%1, %%lo(%a2), %0")
2280 (define_insn "movdi_high_pic"
2281   [(set (match_operand:DI 0 "register_operand" "=r")
2282         (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
2283   "TARGET_ARCH64 && flag_pic && check_pic (1)"
2284   "sethi\t%%hi(%a1), %0")
2286 (define_insn "*sethi_di_medlow_embmedany_pic"
2287   [(set (match_operand:DI 0 "register_operand" "=r")
2288         (high:DI (match_operand:DI 1 "sp64_medium_pic_operand" "")))]
2289   "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
2290   "sethi\t%%hi(%a1), %0")
2292 (define_insn "*sethi_di_medlow"
2293   [(set (match_operand:DI 0 "register_operand" "=r")
2294         (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
2295   "TARGET_CM_MEDLOW && check_pic (1)"
2296   "sethi\t%%hi(%a1), %0")
2298 (define_insn "*losum_di_medlow"
2299   [(set (match_operand:DI 0 "register_operand" "=r")
2300         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2301                    (match_operand:DI 2 "symbolic_operand" "")))]
2302   "TARGET_CM_MEDLOW"
2303   "or\t%1, %%lo(%a2), %0")
2305 (define_insn "seth44"
2306   [(set (match_operand:DI 0 "register_operand" "=r")
2307         (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
2308   "TARGET_CM_MEDMID"
2309   "sethi\t%%h44(%a1), %0")
2311 (define_insn "setm44"
2312   [(set (match_operand:DI 0 "register_operand" "=r")
2313         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2314                    (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
2315   "TARGET_CM_MEDMID"
2316   "or\t%1, %%m44(%a2), %0")
2318 (define_insn "setl44"
2319   [(set (match_operand:DI 0 "register_operand" "=r")
2320         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2321                    (match_operand:DI 2 "symbolic_operand" "")))]
2322   "TARGET_CM_MEDMID"
2323   "or\t%1, %%l44(%a2), %0")
2325 (define_insn "sethh"
2326   [(set (match_operand:DI 0 "register_operand" "=r")
2327         (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
2328   "TARGET_CM_MEDANY"
2329   "sethi\t%%hh(%a1), %0")
2331 (define_insn "setlm"
2332   [(set (match_operand:DI 0 "register_operand" "=r")
2333         (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
2334   "TARGET_CM_MEDANY"
2335   "sethi\t%%lm(%a1), %0")
2337 (define_insn "sethm"
2338   [(set (match_operand:DI 0 "register_operand" "=r")
2339         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2340                    (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
2341   "TARGET_CM_MEDANY"
2342   "or\t%1, %%hm(%a2), %0")
2344 (define_insn "setlo"
2345   [(set (match_operand:DI 0 "register_operand" "=r")
2346         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2347                    (match_operand:DI 2 "symbolic_operand" "")))]
2348   "TARGET_CM_MEDANY"
2349   "or\t%1, %%lo(%a2), %0")
2351 (define_insn "embmedany_sethi"
2352   [(set (match_operand:DI 0 "register_operand" "=r")
2353         (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
2354   "TARGET_CM_EMBMEDANY && check_pic (1)"
2355   "sethi\t%%hi(%a1), %0")
2357 (define_insn "embmedany_losum"
2358   [(set (match_operand:DI 0 "register_operand" "=r")
2359         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2360                    (match_operand:DI 2 "data_segment_operand" "")))]
2361   "TARGET_CM_EMBMEDANY"
2362   "add\t%1, %%lo(%a2), %0")
2364 (define_insn "embmedany_brsum"
2365   [(set (match_operand:DI 0 "register_operand" "=r")
2366         (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
2367   "TARGET_CM_EMBMEDANY"
2368   "add\t%1, %_, %0")
2370 (define_insn "embmedany_textuhi"
2371   [(set (match_operand:DI 0 "register_operand" "=r")
2372         (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
2373   "TARGET_CM_EMBMEDANY && check_pic (1)"
2374   "sethi\t%%uhi(%a1), %0")
2376 (define_insn "embmedany_texthi"
2377   [(set (match_operand:DI 0 "register_operand" "=r")
2378         (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
2379   "TARGET_CM_EMBMEDANY && check_pic (1)"
2380   "sethi\t%%hi(%a1), %0")
2382 (define_insn "embmedany_textulo"
2383   [(set (match_operand:DI 0 "register_operand" "=r")
2384         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2385                    (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
2386   "TARGET_CM_EMBMEDANY"
2387   "or\t%1, %%ulo(%a2), %0")
2389 (define_insn "embmedany_textlo"
2390   [(set (match_operand:DI 0 "register_operand" "=r")
2391         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2392                    (match_operand:DI 2 "text_segment_operand" "")))]
2393   "TARGET_CM_EMBMEDANY"
2394   "or\t%1, %%lo(%a2), %0")
2396 ;; Now some patterns to help reload out a bit.
2397 (define_expand "reload_indi"
2398   [(parallel [(match_operand:DI 0 "register_operand" "=r")
2399               (match_operand:DI 1 "immediate_operand" "")
2400               (match_operand:TI 2 "register_operand" "=&r")])]
2401   "(TARGET_CM_MEDANY
2402     || TARGET_CM_EMBMEDANY)
2403    && ! flag_pic"
2405   sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2406   DONE;
2409 (define_expand "reload_outdi"
2410   [(parallel [(match_operand:DI 0 "register_operand" "=r")
2411               (match_operand:DI 1 "immediate_operand" "")
2412               (match_operand:TI 2 "register_operand" "=&r")])]
2413   "(TARGET_CM_MEDANY
2414     || TARGET_CM_EMBMEDANY)
2415    && ! flag_pic"
2417   sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2418   DONE;
2421 ;; Split up putting CONSTs and REGs into DI regs when !arch64
2422 (define_split
2423   [(set (match_operand:DI 0 "register_operand" "")
2424         (match_operand:DI 1 "const_int_operand" ""))]
2425   "! TARGET_ARCH64 && reload_completed"
2426   [(clobber (const_int 0))]
2428 #if HOST_BITS_PER_WIDE_INT == 32
2429   emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2430                         (INTVAL (operands[1]) < 0) ?
2431                         constm1_rtx :
2432                         const0_rtx));
2433   emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2434                         operands[1]));
2435 #else
2436   unsigned int low, high;
2438   low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
2439   high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
2440   emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
2442   /* Slick... but this trick loses if this subreg constant part
2443      can be done in one insn.  */
2444   if (low == high && (low & 0x3ff) != 0 && low + 0x1000 >= 0x2000)
2445     emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2446                           gen_highpart (SImode, operands[0])));
2447   else
2448     emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
2449 #endif
2450   DONE;
2453 (define_split
2454   [(set (match_operand:DI 0 "register_operand" "")
2455         (match_operand:DI 1 "const_double_operand" ""))]
2456   "reload_completed
2457    && (! TARGET_V9
2458        || (! TARGET_ARCH64
2459            && ((GET_CODE (operands[0]) == REG
2460                 && REGNO (operands[0]) < 32)
2461                || (GET_CODE (operands[0]) == SUBREG
2462                    && GET_CODE (SUBREG_REG (operands[0])) == REG
2463                    && REGNO (SUBREG_REG (operands[0])) < 32))))"
2464   [(clobber (const_int 0))]
2466   emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2467                         GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
2469   /* Slick... but this trick loses if this subreg constant part
2470      can be done in one insn.  */
2471   if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
2472       && !(SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
2473            || SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1]))))
2474     {
2475       emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2476                             gen_highpart (SImode, operands[0])));
2477     }
2478   else
2479     {
2480       emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2481                             GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
2482     }
2483   DONE;
2486 (define_split
2487   [(set (match_operand:DI 0 "register_operand" "")
2488         (match_operand:DI 1 "register_operand" ""))]
2489   "reload_completed
2490    && (! TARGET_V9
2491        || (! TARGET_ARCH64
2492            && ((GET_CODE (operands[0]) == REG
2493                 && REGNO (operands[0]) < 32)
2494                || (GET_CODE (operands[0]) == SUBREG
2495                    && GET_CODE (SUBREG_REG (operands[0])) == REG
2496                    && REGNO (SUBREG_REG (operands[0])) < 32))))"
2497   [(clobber (const_int 0))]
2499   rtx set_dest = operands[0];
2500   rtx set_src = operands[1];
2501   rtx dest1, dest2;
2502   rtx src1, src2;
2504   dest1 = gen_highpart (SImode, set_dest);
2505   dest2 = gen_lowpart (SImode, set_dest);
2506   src1 = gen_highpart (SImode, set_src);
2507   src2 = gen_lowpart (SImode, set_src);
2509   /* Now emit using the real source and destination we found, swapping
2510      the order if we detect overlap.  */
2511   if (reg_overlap_mentioned_p (dest1, src2))
2512     {
2513       emit_insn (gen_movsi (dest2, src2));
2514       emit_insn (gen_movsi (dest1, src1));
2515     }
2516   else
2517     {
2518       emit_insn (gen_movsi (dest1, src1));
2519       emit_insn (gen_movsi (dest2, src2));
2520     }
2521   DONE;
2524 ;; Now handle the cases of memory moves from/to non-even
2525 ;; DI mode register pairs.
2526 (define_split
2527   [(set (match_operand:DI 0 "register_operand" "")
2528         (match_operand:DI 1 "memory_operand" ""))]
2529   "(! TARGET_ARCH64
2530     && reload_completed
2531     && sparc_splitdi_legitimate (operands[0], operands[1]))"
2532   [(clobber (const_int 0))]
2534   rtx word0 = adjust_address (operands[1], SImode, 0);
2535   rtx word1 = adjust_address (operands[1], SImode, 4);
2536   rtx high_part = gen_highpart (SImode, operands[0]);
2537   rtx low_part = gen_lowpart (SImode, operands[0]);
2539   if (reg_overlap_mentioned_p (high_part, word1))
2540     {
2541       emit_insn (gen_movsi (low_part, word1));
2542       emit_insn (gen_movsi (high_part, word0));
2543     }
2544   else
2545     {
2546       emit_insn (gen_movsi (high_part, word0));
2547       emit_insn (gen_movsi (low_part, word1));
2548     }
2549   DONE;
2552 (define_split
2553   [(set (match_operand:DI 0 "memory_operand" "")
2554         (match_operand:DI 1 "register_operand" ""))]
2555   "(! TARGET_ARCH64
2556     && reload_completed
2557     && sparc_splitdi_legitimate (operands[1], operands[0]))"
2558   [(clobber (const_int 0))]
2560   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
2561                         gen_highpart (SImode, operands[1])));
2562   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
2563                         gen_lowpart (SImode, operands[1])));
2564   DONE;
2567 (define_split
2568   [(set (match_operand:DI 0 "memory_operand" "")
2569         (const_int 0))]
2570   "reload_completed
2571    && (! TARGET_V9
2572        || (! TARGET_ARCH64
2573            && ! mem_min_alignment (operands[0], 8)))
2574    && offsettable_memref_p (operands[0])"
2575   [(clobber (const_int 0))]
2577   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
2578   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
2579   DONE;
2582 ;; Floating point move insns
2584 (define_insn "*movsf_insn_novis"
2585   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,*r,*r,*r,*r,*r,f,m,m")
2586         (match_operand:SF 1 "input_operand"         "f,G,Q,*rR,S,m,m,f,*rG"))]
2587   "(TARGET_FPU && ! TARGET_VIS)
2588    && (register_operand (operands[0], SFmode)
2589        || register_operand (operands[1], SFmode)
2590        || fp_zero_operand (operands[1], SFmode))"
2592   if (GET_CODE (operands[1]) == CONST_DOUBLE
2593       && (which_alternative == 2
2594           || which_alternative == 3
2595           || which_alternative == 4))
2596     {
2597       REAL_VALUE_TYPE r;
2598       long i;
2600       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2601       REAL_VALUE_TO_TARGET_SINGLE (r, i);
2602       operands[1] = GEN_INT (i);
2603     }
2605   switch (which_alternative)
2606     {
2607     case 0:
2608       return "fmovs\t%1, %0";
2609     case 1:
2610       return "clr\t%0";
2611     case 2:
2612       return "sethi\t%%hi(%a1), %0";
2613     case 3:
2614       return "mov\t%1, %0";
2615     case 4:
2616       return "#";
2617     case 5:
2618     case 6:
2619       return "ld\t%1, %0";
2620     case 7:
2621     case 8:
2622       return "st\t%r1, %0";
2623     default:
2624       abort();
2625     }
2627   [(set_attr "type" "fpmove,*,*,*,*,load,fpload,fpstore,store")])
2629 (define_insn "*movsf_insn_vis"
2630   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,*r,*r,*r,*r,*r,f,m,m")
2631         (match_operand:SF 1 "input_operand"         "f,G,G,Q,*rR,S,m,m,f,*rG"))]
2632   "(TARGET_FPU && TARGET_VIS)
2633    && (register_operand (operands[0], SFmode)
2634        || register_operand (operands[1], SFmode)
2635        || fp_zero_operand (operands[1], SFmode))"
2637   if (GET_CODE (operands[1]) == CONST_DOUBLE
2638       && (which_alternative == 3
2639           || which_alternative == 4
2640           || which_alternative == 5))
2641     {
2642       REAL_VALUE_TYPE r;
2643       long i;
2645       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2646       REAL_VALUE_TO_TARGET_SINGLE (r, i);
2647       operands[1] = GEN_INT (i);
2648     }
2650   switch (which_alternative)
2651     {
2652     case 0:
2653       return "fmovs\t%1, %0";
2654     case 1:
2655       return "fzeros\t%0";
2656     case 2:
2657       return "clr\t%0";
2658     case 3:
2659       return "sethi\t%%hi(%a1), %0";
2660     case 4:
2661       return "mov\t%1, %0";
2662     case 5:
2663       return "#";
2664     case 6:
2665     case 7:
2666       return "ld\t%1, %0";
2667     case 8:
2668     case 9:
2669       return "st\t%r1, %0";
2670     default:
2671       abort();
2672     }
2674   [(set_attr "type" "fpmove,fga,*,*,*,*,load,fpload,fpstore,store")])
2676 ;; Exactly the same as above, except that all `f' cases are deleted.
2677 ;; This is necessary to prevent reload from ever trying to use a `f' reg
2678 ;; when -mno-fpu.
2680 (define_insn "*movsf_no_f_insn"
2681   [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,r,m")
2682         (match_operand:SF 1 "input_operand"    "G,Q,rR,S,m,rG"))]
2683   "! TARGET_FPU
2684    && (register_operand (operands[0], SFmode)
2685        || register_operand (operands[1], SFmode)
2686        || fp_zero_operand (operands[1], SFmode))"
2688   if (GET_CODE (operands[1]) == CONST_DOUBLE
2689       && (which_alternative == 1
2690           || which_alternative == 2
2691           || which_alternative == 3))
2692     {
2693       REAL_VALUE_TYPE r;
2694       long i;
2696       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2697       REAL_VALUE_TO_TARGET_SINGLE (r, i);
2698       operands[1] = GEN_INT (i);
2699     }
2701   switch (which_alternative)
2702     {
2703     case 0:
2704       return "clr\t%0";
2705     case 1:
2706       return "sethi\t%%hi(%a1), %0";
2707     case 2:
2708       return "mov\t%1, %0";
2709     case 3:
2710       return "#";
2711     case 4:
2712       return "ld\t%1, %0";
2713     case 5:
2714       return "st\t%r1, %0";
2715     default:
2716       abort();
2717     }
2719   [(set_attr "type" "*,*,*,*,load,store")])
2721 (define_insn "*movsf_lo_sum"
2722   [(set (match_operand:SF 0 "register_operand" "=r")
2723         (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
2724                    (match_operand:SF 2 "const_double_operand" "S")))]
2725   "fp_high_losum_p (operands[2])"
2727   REAL_VALUE_TYPE r;
2728   long i;
2730   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
2731   REAL_VALUE_TO_TARGET_SINGLE (r, i);
2732   operands[2] = GEN_INT (i);
2733   return "or\t%1, %%lo(%a2), %0";
2736 (define_insn "*movsf_high"
2737   [(set (match_operand:SF 0 "register_operand" "=r")
2738         (high:SF (match_operand:SF 1 "const_double_operand" "S")))]
2739   "fp_high_losum_p (operands[1])"
2741   REAL_VALUE_TYPE r;
2742   long i;
2744   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2745   REAL_VALUE_TO_TARGET_SINGLE (r, i);
2746   operands[1] = GEN_INT (i);
2747   return "sethi\t%%hi(%1), %0";
2750 (define_split
2751   [(set (match_operand:SF 0 "register_operand" "")
2752         (match_operand:SF 1 "const_double_operand" ""))]
2753   "fp_high_losum_p (operands[1])
2754    && (GET_CODE (operands[0]) == REG
2755        && REGNO (operands[0]) < 32)"
2756   [(set (match_dup 0) (high:SF (match_dup 1)))
2757    (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
2759 (define_expand "movsf"
2760   [(set (match_operand:SF 0 "general_operand" "")
2761         (match_operand:SF 1 "general_operand" ""))]
2762   ""
2764   /* Force SFmode constants into memory.  */
2765   if (GET_CODE (operands[0]) == REG
2766       && CONSTANT_P (operands[1]))
2767     {
2768       /* emit_group_store will send such bogosity to us when it is
2769          not storing directly into memory.  So fix this up to avoid
2770          crashes in output_constant_pool.  */
2771       if (operands [1] == const0_rtx)
2772         operands[1] = CONST0_RTX (SFmode);
2774       if (TARGET_VIS && fp_zero_operand (operands[1], SFmode))
2775         goto movsf_is_ok;
2777       /* We are able to build any SF constant in integer registers
2778          with at most 2 instructions.  */
2779       if (REGNO (operands[0]) < 32)
2780         goto movsf_is_ok;
2782       operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2783                                                    operands[1]));
2784     }
2786   /* Handle sets of MEM first.  */
2787   if (GET_CODE (operands[0]) == MEM)
2788     {
2789       if (register_operand (operands[1], SFmode)
2790           || fp_zero_operand (operands[1], SFmode))
2791         goto movsf_is_ok;
2793       if (! reload_in_progress)
2794         {
2795           operands[0] = validize_mem (operands[0]);
2796           operands[1] = force_reg (SFmode, operands[1]);
2797         }
2798     }
2800   /* Fixup PIC cases.  */
2801   if (flag_pic)
2802     {
2803       if (CONSTANT_P (operands[1])
2804           && pic_address_needs_scratch (operands[1]))
2805         operands[1] = legitimize_pic_address (operands[1], SFmode, 0);
2807       if (symbolic_operand (operands[1], SFmode))
2808         {
2809           operands[1] = legitimize_pic_address (operands[1],
2810                                                 SFmode,
2811                                                 (reload_in_progress ?
2812                                                  operands[0] :
2813                                                  NULL_RTX));
2814         }
2815     }
2817  movsf_is_ok:
2818   ;
2821 (define_expand "movdf"
2822   [(set (match_operand:DF 0 "general_operand" "")
2823         (match_operand:DF 1 "general_operand" ""))]
2824   ""
2826   /* Force DFmode constants into memory.  */
2827   if (GET_CODE (operands[0]) == REG
2828       && CONSTANT_P (operands[1]))
2829     {
2830       /* emit_group_store will send such bogosity to us when it is
2831          not storing directly into memory.  So fix this up to avoid
2832          crashes in output_constant_pool.  */
2833       if (operands [1] == const0_rtx)
2834         operands[1] = CONST0_RTX (DFmode);
2836       if ((TARGET_VIS || REGNO (operands[0]) < 32)
2837           && fp_zero_operand (operands[1], DFmode))
2838         goto movdf_is_ok;
2840       /* We are able to build any DF constant in integer registers.  */
2841       if (REGNO (operands[0]) < 32
2842           && (reload_completed || reload_in_progress))
2843         goto movdf_is_ok;
2845       operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2846                                                    operands[1]));
2847     }
2849   /* Handle MEM cases first.  */
2850   if (GET_CODE (operands[0]) == MEM)
2851     {
2852       if (register_operand (operands[1], DFmode)
2853           || fp_zero_operand (operands[1], DFmode))
2854         goto movdf_is_ok;
2856       if (! reload_in_progress)
2857         {
2858           operands[0] = validize_mem (operands[0]);
2859           operands[1] = force_reg (DFmode, operands[1]);
2860         }
2861     }
2863   /* Fixup PIC cases.  */
2864   if (flag_pic)
2865     {
2866       if (CONSTANT_P (operands[1])
2867           && pic_address_needs_scratch (operands[1]))
2868         operands[1] = legitimize_pic_address (operands[1], DFmode, 0);
2870       if (symbolic_operand (operands[1], DFmode))
2871         {
2872           operands[1] = legitimize_pic_address (operands[1],
2873                                                 DFmode,
2874                                                 (reload_in_progress ?
2875                                                  operands[0] :
2876                                                  NULL_RTX));
2877         }
2878     }
2880  movdf_is_ok:
2881   ;
2884 ;; Be careful, fmovd does not exist when !v9.
2885 (define_insn "*movdf_insn_sp32"
2886   [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o")
2887         (match_operand:DF 1 "input_operand"    "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
2888   "TARGET_FPU
2889    && ! TARGET_V9
2890    && (register_operand (operands[0], DFmode)
2891        || register_operand (operands[1], DFmode)
2892        || fp_zero_operand (operands[1], DFmode))"
2893   "@
2894   ldd\t%1, %0
2895   std\t%1, %0
2896   ldd\t%1, %0
2897   std\t%1, %0
2898   #
2899   #
2900   #
2901   #
2902   #
2903   #"
2904  [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
2905   (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
2907 (define_insn "*movdf_no_e_insn_sp32"
2908   [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
2909         (match_operand:DF 1 "input_operand"    "T,U,G,ro,r"))]
2910   "! TARGET_FPU
2911    && ! TARGET_V9
2912    && ! TARGET_ARCH64
2913    && (register_operand (operands[0], DFmode)
2914        || register_operand (operands[1], DFmode)
2915        || fp_zero_operand (operands[1], DFmode))"
2916   "@
2917   ldd\t%1, %0
2918   std\t%1, %0
2919   #
2920   #
2921   #"
2922   [(set_attr "type" "load,store,*,*,*")
2923    (set_attr "length" "*,*,2,2,2")])
2925 (define_insn "*movdf_no_e_insn_v9_sp32"
2926   [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
2927         (match_operand:DF 1 "input_operand"    "T,U,G,ro,rG"))]
2928   "! TARGET_FPU
2929    && TARGET_V9
2930    && ! TARGET_ARCH64
2931    && (register_operand (operands[0], DFmode)
2932        || register_operand (operands[1], DFmode)
2933        || fp_zero_operand (operands[1], DFmode))"
2934   "@
2935   ldd\t%1, %0
2936   std\t%1, %0
2937   stx\t%r1, %0
2938   #
2939   #"
2940   [(set_attr "type" "load,store,store,*,*")
2941    (set_attr "length" "*,*,*,2,2")])
2943 ;; We have available v9 double floats but not 64-bit
2944 ;; integer registers and no VIS.
2945 (define_insn "*movdf_insn_v9only_novis"
2946   [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,T,W,U,T,f,*r,o")
2947         (match_operand:DF 1 "input_operand"    "e,W#F,G,e,T,U,o#F,*roF,*rGf"))]
2948   "TARGET_FPU
2949    && TARGET_V9
2950    && ! TARGET_VIS
2951    && ! TARGET_ARCH64
2952    && (register_operand (operands[0], DFmode)
2953        || register_operand (operands[1], DFmode)
2954        || fp_zero_operand (operands[1], DFmode))"
2955   "@
2956   fmovd\t%1, %0
2957   ldd\t%1, %0
2958   stx\t%r1, %0
2959   std\t%1, %0
2960   ldd\t%1, %0
2961   std\t%1, %0
2962   #
2963   #
2964   #"
2965   [(set_attr "type" "fpmove,load,store,store,load,store,*,*,*")
2966    (set_attr "length" "*,*,*,*,*,*,2,2,2")
2967    (set_attr "fptype" "double,*,*,*,*,*,*,*,*")])
2969 ;; We have available v9 double floats but not 64-bit
2970 ;; integer registers but we have VIS.
2971 (define_insn "*movdf_insn_v9only_vis"
2972   [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,T,W,U,T,f,*r,o")
2973         (match_operand:DF 1 "input_operand" "G,e,W#F,G,e,T,U,o#F,*roGF,*rGf"))]
2974   "TARGET_FPU
2975    && TARGET_VIS
2976    && ! TARGET_ARCH64
2977    && (register_operand (operands[0], DFmode)
2978        || register_operand (operands[1], DFmode)
2979        || fp_zero_operand (operands[1], DFmode))"
2980   "@
2981   fzero\t%0
2982   fmovd\t%1, %0
2983   ldd\t%1, %0
2984   stx\t%r1, %0
2985   std\t%1, %0
2986   ldd\t%1, %0
2987   std\t%1, %0
2988   #
2989   #
2990   #"
2991   [(set_attr "type" "fga,fpmove,load,store,store,load,store,*,*,*")
2992    (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
2993    (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
2995 ;; We have available both v9 double floats and 64-bit
2996 ;; integer registers. No VIS though.
2997 (define_insn "*movdf_insn_sp64_novis"
2998   [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,W,*r,*r,m,*r")
2999         (match_operand:DF 1 "input_operand"    "e,W#F,e,*rG,m,*rG,F"))]
3000   "TARGET_FPU
3001    && ! TARGET_VIS
3002    && TARGET_ARCH64
3003    && (register_operand (operands[0], DFmode)
3004        || register_operand (operands[1], DFmode)
3005        || fp_zero_operand (operands[1], DFmode))"
3006   "@
3007   fmovd\t%1, %0
3008   ldd\t%1, %0
3009   std\t%1, %0
3010   mov\t%r1, %0
3011   ldx\t%1, %0
3012   stx\t%r1, %0
3013   #"
3014   [(set_attr "type" "fpmove,load,store,*,load,store,*")
3015    (set_attr "length" "*,*,*,*,*,*,2")
3016    (set_attr "fptype" "double,*,*,*,*,*,*")])
3018 ;; We have available both v9 double floats and 64-bit
3019 ;; integer registers. And we have VIS.
3020 (define_insn "*movdf_insn_sp64_vis"
3021   [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,W,*r,*r,m,*r")
3022         (match_operand:DF 1 "input_operand"    "G,e,W#F,e,*rG,m,*rG,F"))]
3023   "TARGET_FPU
3024    && TARGET_VIS
3025    && TARGET_ARCH64
3026    && (register_operand (operands[0], DFmode)
3027        || register_operand (operands[1], DFmode)
3028        || fp_zero_operand (operands[1], DFmode))"
3029   "@
3030   fzero\t%0
3031   fmovd\t%1, %0
3032   ldd\t%1, %0
3033   std\t%1, %0
3034   mov\t%r1, %0
3035   ldx\t%1, %0
3036   stx\t%r1, %0
3037   #"
3038   [(set_attr "type" "fga,fpmove,load,store,*,load,store,*")
3039    (set_attr "length" "*,*,*,*,*,*,*,2")
3040    (set_attr "fptype" "double,double,*,*,*,*,*,*")])
3042 (define_insn "*movdf_no_e_insn_sp64"
3043   [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
3044         (match_operand:DF 1 "input_operand"    "r,m,rG"))]
3045   "! TARGET_FPU
3046    && TARGET_ARCH64
3047    && (register_operand (operands[0], DFmode)
3048        || register_operand (operands[1], DFmode)
3049        || fp_zero_operand (operands[1], DFmode))"
3050   "@
3051   mov\t%1, %0
3052   ldx\t%1, %0
3053   stx\t%r1, %0"
3054   [(set_attr "type" "*,load,store")])
3056 (define_split
3057   [(set (match_operand:DF 0 "register_operand" "")
3058         (match_operand:DF 1 "const_double_operand" ""))]
3059   "TARGET_FPU
3060    && (GET_CODE (operands[0]) == REG
3061        && REGNO (operands[0]) < 32)
3062    && ! fp_zero_operand(operands[1], DFmode)
3063    && reload_completed"
3064   [(clobber (const_int 0))]
3066   REAL_VALUE_TYPE r;
3067   long l[2];
3069   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3070   REAL_VALUE_TO_TARGET_DOUBLE (r, l);
3071   operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
3073   if (TARGET_ARCH64)
3074     {
3075 #if HOST_BITS_PER_WIDE_INT == 64
3076       HOST_WIDE_INT val;
3078       val = ((HOST_WIDE_INT)(unsigned long)l[1] |
3079              ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
3080       emit_insn (gen_movdi (operands[0], GEN_INT (val)));
3081 #else
3082       emit_insn (gen_movdi (operands[0],
3083                             immed_double_const (l[1], l[0], DImode)));
3084 #endif
3085     }
3086   else
3087     {
3088       emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
3089                             GEN_INT (l[0])));
3091       /* Slick... but this trick loses if this subreg constant part
3092          can be done in one insn.  */
3093       if (l[1] == l[0]
3094           && !(SPARC_SETHI32_P (l[0])
3095                || SPARC_SIMM13_P (l[0])))
3096         {
3097           emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3098                                 gen_highpart (SImode, operands[0])));
3099         }
3100       else
3101         {
3102           emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3103                                 GEN_INT (l[1])));
3104         }
3105     }
3106   DONE;
3109 ;; Ok, now the splits to handle all the multi insn and
3110 ;; mis-aligned memory address cases.
3111 ;; In these splits please take note that we must be
3112 ;; careful when V9 but not ARCH64 because the integer
3113 ;; register DFmode cases must be handled.
3114 (define_split
3115   [(set (match_operand:DF 0 "register_operand" "")
3116         (match_operand:DF 1 "register_operand" ""))]
3117   "(! TARGET_V9
3118     || (! TARGET_ARCH64
3119         && ((GET_CODE (operands[0]) == REG
3120              && REGNO (operands[0]) < 32)
3121             || (GET_CODE (operands[0]) == SUBREG
3122                 && GET_CODE (SUBREG_REG (operands[0])) == REG
3123                 && REGNO (SUBREG_REG (operands[0])) < 32))))
3124    && reload_completed"
3125   [(clobber (const_int 0))]
3127   rtx set_dest = operands[0];
3128   rtx set_src = operands[1];
3129   rtx dest1, dest2;
3130   rtx src1, src2;
3132   dest1 = gen_highpart (SFmode, set_dest);
3133   dest2 = gen_lowpart (SFmode, set_dest);
3134   src1 = gen_highpart (SFmode, set_src);
3135   src2 = gen_lowpart (SFmode, set_src);
3137   /* Now emit using the real source and destination we found, swapping
3138      the order if we detect overlap.  */
3139   if (reg_overlap_mentioned_p (dest1, src2))
3140     {
3141       emit_insn (gen_movsf (dest2, src2));
3142       emit_insn (gen_movsf (dest1, src1));
3143     }
3144   else
3145     {
3146       emit_insn (gen_movsf (dest1, src1));
3147       emit_insn (gen_movsf (dest2, src2));
3148     }
3149   DONE;
3152 (define_split
3153   [(set (match_operand:DF 0 "register_operand" "")
3154         (match_operand:DF 1 "memory_operand" ""))]
3155   "reload_completed
3156    && ! TARGET_ARCH64
3157    && (((REGNO (operands[0]) % 2) != 0)
3158        || ! mem_min_alignment (operands[1], 8))
3159    && offsettable_memref_p (operands[1])"
3160   [(clobber (const_int 0))]
3162   rtx word0 = adjust_address (operands[1], SFmode, 0);
3163   rtx word1 = adjust_address (operands[1], SFmode, 4);
3165   if (reg_overlap_mentioned_p (gen_highpart (SFmode, operands[0]), word1))
3166     {
3167       emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3168                             word1));
3169       emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3170                             word0));
3171     }
3172   else
3173     {
3174       emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3175                             word0));
3176       emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3177                             word1));
3178     }
3179   DONE;
3182 (define_split
3183   [(set (match_operand:DF 0 "memory_operand" "")
3184         (match_operand:DF 1 "register_operand" ""))]
3185   "reload_completed
3186    && ! TARGET_ARCH64
3187    && (((REGNO (operands[1]) % 2) != 0)
3188        || ! mem_min_alignment (operands[0], 8))
3189    && offsettable_memref_p (operands[0])"
3190   [(clobber (const_int 0))]
3192   rtx word0 = adjust_address (operands[0], SFmode, 0);
3193   rtx word1 = adjust_address (operands[0], SFmode, 4);
3195   emit_insn (gen_movsf (word0,
3196                         gen_highpart (SFmode, operands[1])));
3197   emit_insn (gen_movsf (word1,
3198                         gen_lowpart (SFmode, operands[1])));
3199   DONE;
3202 (define_split
3203   [(set (match_operand:DF 0 "memory_operand" "")
3204         (match_operand:DF 1 "fp_zero_operand" ""))]
3205   "reload_completed
3206    && (! TARGET_V9
3207        || (! TARGET_ARCH64
3208            && ! mem_min_alignment (operands[0], 8)))
3209    && offsettable_memref_p (operands[0])"
3210   [(clobber (const_int 0))]
3212   rtx dest1, dest2;
3214   dest1 = adjust_address (operands[0], SFmode, 0);
3215   dest2 = adjust_address (operands[0], SFmode, 4);
3217   emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3218   emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3219   DONE;
3222 (define_split
3223   [(set (match_operand:DF 0 "register_operand" "")
3224         (match_operand:DF 1 "fp_zero_operand" ""))]
3225   "reload_completed
3226    && ! TARGET_ARCH64
3227    && ((GET_CODE (operands[0]) == REG
3228         && REGNO (operands[0]) < 32)
3229        || (GET_CODE (operands[0]) == SUBREG
3230            && GET_CODE (SUBREG_REG (operands[0])) == REG
3231            && REGNO (SUBREG_REG (operands[0])) < 32))"
3232   [(clobber (const_int 0))]
3234   rtx set_dest = operands[0];
3235   rtx dest1, dest2;
3237   dest1 = gen_highpart (SFmode, set_dest);
3238   dest2 = gen_lowpart (SFmode, set_dest);
3239   emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3240   emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3241   DONE;
3244 (define_expand "movtf"
3245   [(set (match_operand:TF 0 "general_operand" "")
3246         (match_operand:TF 1 "general_operand" ""))]
3247   ""
3249   /* Force TFmode constants into memory.  */
3250   if (GET_CODE (operands[0]) == REG
3251       && CONSTANT_P (operands[1]))
3252     {
3253       /* emit_group_store will send such bogosity to us when it is
3254          not storing directly into memory.  So fix this up to avoid
3255          crashes in output_constant_pool.  */
3256       if (operands [1] == const0_rtx)
3257         operands[1] = CONST0_RTX (TFmode);
3259       if (TARGET_VIS && fp_zero_operand (operands[1], TFmode))
3260         goto movtf_is_ok;
3262       operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3263                                                    operands[1]));
3264     }
3266   /* Handle MEM cases first, note that only v9 guarantees
3267      full 16-byte alignment for quads.  */
3268   if (GET_CODE (operands[0]) == MEM)
3269     {
3270       if (register_operand (operands[1], TFmode)
3271           || fp_zero_operand (operands[1], TFmode))
3272         goto movtf_is_ok;
3274       if (! reload_in_progress)
3275         {
3276           operands[0] = validize_mem (operands[0]);
3277           operands[1] = force_reg (TFmode, operands[1]);
3278         }
3279     }
3281   /* Fixup PIC cases.  */
3282   if (flag_pic)
3283     {
3284       if (CONSTANT_P (operands[1])
3285           && pic_address_needs_scratch (operands[1]))
3286         operands[1] = legitimize_pic_address (operands[1], TFmode, 0);
3288       if (symbolic_operand (operands[1], TFmode))
3289         {
3290           operands[1] = legitimize_pic_address (operands[1],
3291                                                 TFmode,
3292                                                 (reload_in_progress ?
3293                                                  operands[0] :
3294                                                  NULL_RTX));
3295         }
3296     }
3298  movtf_is_ok:
3299   ;
3302 ;; Be careful, fmovq and {st,ld}{x,q} do not exist when !arch64 so
3303 ;; we must split them all.  :-(
3304 (define_insn "*movtf_insn_sp32"
3305   [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3306         (match_operand:TF 1 "input_operand"    "oe,GeUr,o,roG"))]
3307   "TARGET_FPU
3308    && ! TARGET_VIS
3309    && ! TARGET_ARCH64
3310    && (register_operand (operands[0], TFmode)
3311        || register_operand (operands[1], TFmode)
3312        || fp_zero_operand (operands[1], TFmode))"
3313   "#"
3314   [(set_attr "length" "4")])
3316 (define_insn "*movtf_insn_vis_sp32"
3317   [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3318         (match_operand:TF 1 "input_operand"    "Goe,GeUr,o,roG"))]
3319   "TARGET_FPU
3320    && TARGET_VIS
3321    && ! TARGET_ARCH64
3322    && (register_operand (operands[0], TFmode)
3323        || register_operand (operands[1], TFmode)
3324        || fp_zero_operand (operands[1], TFmode))"
3325   "#"
3326   [(set_attr "length" "4")])
3328 ;; Exactly the same as above, except that all `e' cases are deleted.
3329 ;; This is necessary to prevent reload from ever trying to use a `e' reg
3330 ;; when -mno-fpu.
3332 (define_insn "*movtf_no_e_insn_sp32"
3333   [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
3334         (match_operand:TF 1 "input_operand"    "G,o,U,roG,r"))]
3335   "! TARGET_FPU
3336    && ! TARGET_ARCH64
3337    && (register_operand (operands[0], TFmode)
3338        || register_operand (operands[1], TFmode)
3339        || fp_zero_operand (operands[1], TFmode))"
3340   "#"
3341   [(set_attr "length" "4")])
3343 ;; Now handle the float reg cases directly when arch64,
3344 ;; hard_quad, and proper reg number alignment are all true.
3345 (define_insn "*movtf_insn_hq_sp64"
3346   [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,o,r")
3347         (match_operand:TF 1 "input_operand"    "e,m,e,Gr,roG"))]
3348   "TARGET_FPU
3349    && ! TARGET_VIS
3350    && TARGET_ARCH64
3351    && TARGET_HARD_QUAD
3352    && (register_operand (operands[0], TFmode)
3353        || register_operand (operands[1], TFmode)
3354        || fp_zero_operand (operands[1], TFmode))"
3355   "@
3356   fmovq\t%1, %0
3357   ldq\t%1, %0
3358   stq\t%1, %0
3359   #
3360   #"
3361   [(set_attr "type" "fpmove,fpload,fpstore,*,*")
3362    (set_attr "length" "*,*,*,2,2")])
3364 (define_insn "*movtf_insn_hq_vis_sp64"
3365   [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,eo,r,o")
3366         (match_operand:TF 1 "input_operand"    "e,m,e,G,roG,r"))]
3367   "TARGET_FPU
3368    && TARGET_VIS
3369    && TARGET_ARCH64
3370    && TARGET_HARD_QUAD
3371    && (register_operand (operands[0], TFmode)
3372        || register_operand (operands[1], TFmode)
3373        || fp_zero_operand (operands[1], TFmode))"
3374   "@
3375   fmovq\t%1, %0
3376   ldq\t%1, %0
3377   stq\t%1, %0
3378   #
3379   #
3380   #"
3381   [(set_attr "type" "fpmove,fpload,fpstore,*,*,*")
3382    (set_attr "length" "*,*,*,2,2,2")])
3384 ;; Now we allow the integer register cases even when
3385 ;; only arch64 is true.
3386 (define_insn "*movtf_insn_sp64"
3387   [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3388         (match_operand:TF 1 "input_operand"    "oe,Ger,orG"))]
3389   "TARGET_FPU
3390    && ! TARGET_VIS
3391    && TARGET_ARCH64
3392    && ! TARGET_HARD_QUAD
3393    && (register_operand (operands[0], TFmode)
3394        || register_operand (operands[1], TFmode)
3395        || fp_zero_operand (operands[1], TFmode))"
3396   "#"
3397   [(set_attr "length" "2")])
3399 (define_insn "*movtf_insn_vis_sp64"
3400   [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3401         (match_operand:TF 1 "input_operand"    "Goe,Ger,orG"))]
3402   "TARGET_FPU
3403    && TARGET_VIS
3404    && TARGET_ARCH64
3405    && ! TARGET_HARD_QUAD
3406    && (register_operand (operands[0], TFmode)
3407        || register_operand (operands[1], TFmode)
3408        || fp_zero_operand (operands[1], TFmode))"
3409   "#"
3410   [(set_attr "length" "2")])
3412 (define_insn "*movtf_no_e_insn_sp64"
3413   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
3414         (match_operand:TF 1 "input_operand"    "orG,rG"))]
3415   "! TARGET_FPU
3416    && TARGET_ARCH64
3417    && (register_operand (operands[0], TFmode)
3418        || register_operand (operands[1], TFmode)
3419        || fp_zero_operand (operands[1], TFmode))"
3420   "#"
3421   [(set_attr "length" "2")])
3423 ;; Now all the splits to handle multi-insn TF mode moves.
3424 (define_split
3425   [(set (match_operand:TF 0 "register_operand" "")
3426         (match_operand:TF 1 "register_operand" ""))]
3427   "reload_completed
3428    && (! TARGET_ARCH64
3429        || (TARGET_FPU
3430            && ! TARGET_HARD_QUAD)
3431        || ! fp_register_operand (operands[0], TFmode))"
3432   [(clobber (const_int 0))]
3434   rtx set_dest = operands[0];
3435   rtx set_src = operands[1];
3436   rtx dest1, dest2;
3437   rtx src1, src2;
3439   dest1 = gen_df_reg (set_dest, 0);
3440   dest2 = gen_df_reg (set_dest, 1);
3441   src1 = gen_df_reg (set_src, 0);
3442   src2 = gen_df_reg (set_src, 1);
3444   /* Now emit using the real source and destination we found, swapping
3445      the order if we detect overlap.  */
3446   if (reg_overlap_mentioned_p (dest1, src2))
3447     {
3448       emit_insn (gen_movdf (dest2, src2));
3449       emit_insn (gen_movdf (dest1, src1));
3450     }
3451   else
3452     {
3453       emit_insn (gen_movdf (dest1, src1));
3454       emit_insn (gen_movdf (dest2, src2));
3455     }
3456   DONE;
3459 (define_split
3460   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3461         (match_operand:TF 1 "fp_zero_operand" ""))]
3462   "reload_completed"
3463   [(clobber (const_int 0))]
3465   rtx set_dest = operands[0];
3466   rtx dest1, dest2;
3468   switch (GET_CODE (set_dest))
3469     {
3470     case REG:
3471       dest1 = gen_df_reg (set_dest, 0);
3472       dest2 = gen_df_reg (set_dest, 1);
3473       break;
3474     case MEM:
3475       dest1 = adjust_address (set_dest, DFmode, 0);
3476       dest2 = adjust_address (set_dest, DFmode, 8);
3477       break;
3478     default:
3479       abort ();      
3480     }
3482   emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
3483   emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
3484   DONE;
3487 (define_split
3488   [(set (match_operand:TF 0 "register_operand" "")
3489         (match_operand:TF 1 "memory_operand" ""))]
3490   "(reload_completed
3491     && offsettable_memref_p (operands[1])
3492     && (! TARGET_ARCH64
3493         || ! TARGET_HARD_QUAD
3494         || ! fp_register_operand (operands[0], TFmode)))"
3495   [(clobber (const_int 0))]
3497   rtx word0 = adjust_address (operands[1], DFmode, 0);
3498   rtx word1 = adjust_address (operands[1], DFmode, 8);
3499   rtx set_dest, dest1, dest2;
3501   set_dest = operands[0];
3503   dest1 = gen_df_reg (set_dest, 0);
3504   dest2 = gen_df_reg (set_dest, 1);
3506   /* Now output, ordering such that we don't clobber any registers
3507      mentioned in the address.  */
3508   if (reg_overlap_mentioned_p (dest1, word1))
3510     {
3511       emit_insn (gen_movdf (dest2, word1));
3512       emit_insn (gen_movdf (dest1, word0));
3513     }
3514   else
3515    {
3516       emit_insn (gen_movdf (dest1, word0));
3517       emit_insn (gen_movdf (dest2, word1));
3518    }
3519   DONE;
3522 (define_split
3523   [(set (match_operand:TF 0 "memory_operand" "")
3524         (match_operand:TF 1 "register_operand" ""))]
3525   "(reload_completed
3526     && offsettable_memref_p (operands[0])
3527     && (! TARGET_ARCH64
3528         || ! TARGET_HARD_QUAD
3529         || ! fp_register_operand (operands[1], TFmode)))"
3530   [(clobber (const_int 0))]
3532   rtx set_src = operands[1];
3534   emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
3535                         gen_df_reg (set_src, 0)));
3536   emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
3537                         gen_df_reg (set_src, 1)));
3538   DONE;
3541 ;; SPARC V9 conditional move instructions.
3543 ;; We can handle larger constants here for some flavors, but for now we keep
3544 ;; it simple and only allow those constants supported by all flavors.
3545 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3546 ;; 3 contains the constant if one is present, but we handle either for
3547 ;; generality (sparc.c puts a constant in operand 2).
3549 (define_expand "movqicc"
3550   [(set (match_operand:QI 0 "register_operand" "")
3551         (if_then_else:QI (match_operand 1 "comparison_operator" "")
3552                          (match_operand:QI 2 "arith10_operand" "")
3553                          (match_operand:QI 3 "arith10_operand" "")))]
3554   "TARGET_V9"
3556   enum rtx_code code = GET_CODE (operands[1]);
3558   if (GET_MODE (sparc_compare_op0) == DImode
3559       && ! TARGET_ARCH64)
3560     FAIL;
3562   if (sparc_compare_op1 == const0_rtx
3563       && GET_CODE (sparc_compare_op0) == REG
3564       && GET_MODE (sparc_compare_op0) == DImode
3565       && v9_regcmp_p (code))
3566     {
3567       operands[1] = gen_rtx_fmt_ee (code, DImode,
3568                              sparc_compare_op0, sparc_compare_op1);
3569     }
3570   else
3571     {
3572       rtx cc_reg = gen_compare_reg (code,
3573                                     sparc_compare_op0, sparc_compare_op1);
3574       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3575     }
3578 (define_expand "movhicc"
3579   [(set (match_operand:HI 0 "register_operand" "")
3580         (if_then_else:HI (match_operand 1 "comparison_operator" "")
3581                          (match_operand:HI 2 "arith10_operand" "")
3582                          (match_operand:HI 3 "arith10_operand" "")))]
3583   "TARGET_V9"
3585   enum rtx_code code = GET_CODE (operands[1]);
3587   if (GET_MODE (sparc_compare_op0) == DImode
3588       && ! TARGET_ARCH64)
3589     FAIL;
3591   if (sparc_compare_op1 == const0_rtx
3592       && GET_CODE (sparc_compare_op0) == REG
3593       && GET_MODE (sparc_compare_op0) == DImode
3594       && v9_regcmp_p (code))
3595     {
3596       operands[1] = gen_rtx_fmt_ee (code, DImode,
3597                              sparc_compare_op0, sparc_compare_op1);
3598     }
3599   else
3600     {
3601       rtx cc_reg = gen_compare_reg (code,
3602                                     sparc_compare_op0, sparc_compare_op1);
3603       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3604     }
3607 (define_expand "movsicc"
3608   [(set (match_operand:SI 0 "register_operand" "")
3609         (if_then_else:SI (match_operand 1 "comparison_operator" "")
3610                          (match_operand:SI 2 "arith10_operand" "")
3611                          (match_operand:SI 3 "arith10_operand" "")))]
3612   "TARGET_V9"
3614   enum rtx_code code = GET_CODE (operands[1]);
3615   enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
3617   if (sparc_compare_op1 == const0_rtx
3618       && GET_CODE (sparc_compare_op0) == REG
3619       && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
3620     {
3621       operands[1] = gen_rtx_fmt_ee (code, op0_mode,
3622                              sparc_compare_op0, sparc_compare_op1);
3623     }
3624   else
3625     {
3626       rtx cc_reg = gen_compare_reg (code,
3627                                     sparc_compare_op0, sparc_compare_op1);
3628       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3629                                     cc_reg, const0_rtx);
3630     }
3633 (define_expand "movdicc"
3634   [(set (match_operand:DI 0 "register_operand" "")
3635         (if_then_else:DI (match_operand 1 "comparison_operator" "")
3636                          (match_operand:DI 2 "arith10_double_operand" "")
3637                          (match_operand:DI 3 "arith10_double_operand" "")))]
3638   "TARGET_ARCH64"
3640   enum rtx_code code = GET_CODE (operands[1]);
3642   if (sparc_compare_op1 == const0_rtx
3643       && GET_CODE (sparc_compare_op0) == REG
3644       && GET_MODE (sparc_compare_op0) == DImode
3645       && v9_regcmp_p (code))
3646     {
3647       operands[1] = gen_rtx_fmt_ee (code, DImode,
3648                              sparc_compare_op0, sparc_compare_op1);
3649     }
3650   else
3651     {
3652       rtx cc_reg = gen_compare_reg (code,
3653                                     sparc_compare_op0, sparc_compare_op1);
3654       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3655                                     cc_reg, const0_rtx);
3656     }
3659 (define_expand "movsfcc"
3660   [(set (match_operand:SF 0 "register_operand" "")
3661         (if_then_else:SF (match_operand 1 "comparison_operator" "")
3662                          (match_operand:SF 2 "register_operand" "")
3663                          (match_operand:SF 3 "register_operand" "")))]
3664   "TARGET_V9 && TARGET_FPU"
3666   enum rtx_code code = GET_CODE (operands[1]);
3668   if (GET_MODE (sparc_compare_op0) == DImode
3669       && ! TARGET_ARCH64)
3670     FAIL;
3672   if (sparc_compare_op1 == const0_rtx
3673       && GET_CODE (sparc_compare_op0) == REG
3674       && GET_MODE (sparc_compare_op0) == DImode
3675       && v9_regcmp_p (code))
3676     {
3677       operands[1] = gen_rtx_fmt_ee (code, DImode,
3678                              sparc_compare_op0, sparc_compare_op1);
3679     }
3680   else
3681     {
3682       rtx cc_reg = gen_compare_reg (code,
3683                                     sparc_compare_op0, sparc_compare_op1);
3684       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3685     }
3688 (define_expand "movdfcc"
3689   [(set (match_operand:DF 0 "register_operand" "")
3690         (if_then_else:DF (match_operand 1 "comparison_operator" "")
3691                          (match_operand:DF 2 "register_operand" "")
3692                          (match_operand:DF 3 "register_operand" "")))]
3693   "TARGET_V9 && TARGET_FPU"
3695   enum rtx_code code = GET_CODE (operands[1]);
3697   if (GET_MODE (sparc_compare_op0) == DImode
3698       && ! TARGET_ARCH64)
3699     FAIL;
3701   if (sparc_compare_op1 == const0_rtx
3702       && GET_CODE (sparc_compare_op0) == REG
3703       && GET_MODE (sparc_compare_op0) == DImode
3704       && v9_regcmp_p (code))
3705     {
3706       operands[1] = gen_rtx_fmt_ee (code, DImode,
3707                              sparc_compare_op0, sparc_compare_op1);
3708     }
3709   else
3710     {
3711       rtx cc_reg = gen_compare_reg (code,
3712                                     sparc_compare_op0, sparc_compare_op1);
3713       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3714     }
3717 (define_expand "movtfcc"
3718   [(set (match_operand:TF 0 "register_operand" "")
3719         (if_then_else:TF (match_operand 1 "comparison_operator" "")
3720                          (match_operand:TF 2 "register_operand" "")
3721                          (match_operand:TF 3 "register_operand" "")))]
3722   "TARGET_V9 && TARGET_FPU"
3724   enum rtx_code code = GET_CODE (operands[1]);
3726   if (GET_MODE (sparc_compare_op0) == DImode
3727       && ! TARGET_ARCH64)
3728     FAIL;
3730   if (sparc_compare_op1 == const0_rtx
3731       && GET_CODE (sparc_compare_op0) == REG
3732       && GET_MODE (sparc_compare_op0) == DImode
3733       && v9_regcmp_p (code))
3734     {
3735       operands[1] = gen_rtx_fmt_ee (code, DImode,
3736                              sparc_compare_op0, sparc_compare_op1);
3737     }
3738   else
3739     {
3740       rtx cc_reg = gen_compare_reg (code,
3741                                     sparc_compare_op0, sparc_compare_op1);
3742       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3743     }
3746 ;; Conditional move define_insns.
3748 (define_insn "*movqi_cc_sp64"
3749   [(set (match_operand:QI 0 "register_operand" "=r,r")
3750         (if_then_else:QI (match_operator 1 "comparison_operator"
3751                                 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3752                                  (const_int 0)])
3753                          (match_operand:QI 3 "arith11_operand" "rL,0")
3754                          (match_operand:QI 4 "arith11_operand" "0,rL")))]
3755   "TARGET_V9"
3756   "@
3757    mov%C1\t%x2, %3, %0
3758    mov%c1\t%x2, %4, %0"
3759   [(set_attr "type" "cmove")])
3761 (define_insn "*movhi_cc_sp64"
3762   [(set (match_operand:HI 0 "register_operand" "=r,r")
3763         (if_then_else:HI (match_operator 1 "comparison_operator"
3764                                 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3765                                  (const_int 0)])
3766                          (match_operand:HI 3 "arith11_operand" "rL,0")
3767                          (match_operand:HI 4 "arith11_operand" "0,rL")))]
3768   "TARGET_V9"
3769   "@
3770    mov%C1\t%x2, %3, %0
3771    mov%c1\t%x2, %4, %0"
3772   [(set_attr "type" "cmove")])
3774 (define_insn "*movsi_cc_sp64"
3775   [(set (match_operand:SI 0 "register_operand" "=r,r")
3776         (if_then_else:SI (match_operator 1 "comparison_operator"
3777                                 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3778                                  (const_int 0)])
3779                          (match_operand:SI 3 "arith11_operand" "rL,0")
3780                          (match_operand:SI 4 "arith11_operand" "0,rL")))]
3781   "TARGET_V9"
3782   "@
3783    mov%C1\t%x2, %3, %0
3784    mov%c1\t%x2, %4, %0"
3785   [(set_attr "type" "cmove")])
3787 ;; ??? The constraints of operands 3,4 need work.
3788 (define_insn "*movdi_cc_sp64"
3789   [(set (match_operand:DI 0 "register_operand" "=r,r")
3790         (if_then_else:DI (match_operator 1 "comparison_operator"
3791                                 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3792                                  (const_int 0)])
3793                          (match_operand:DI 3 "arith11_double_operand" "rLH,0")
3794                          (match_operand:DI 4 "arith11_double_operand" "0,rLH")))]
3795   "TARGET_ARCH64"
3796   "@
3797    mov%C1\t%x2, %3, %0
3798    mov%c1\t%x2, %4, %0"
3799   [(set_attr "type" "cmove")])
3801 (define_insn "*movdi_cc_sp64_trunc"
3802   [(set (match_operand:SI 0 "register_operand" "=r,r")
3803         (if_then_else:SI (match_operator 1 "comparison_operator"
3804                                 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3805                                  (const_int 0)])
3806                          (match_operand:SI 3 "arith11_double_operand" "rLH,0")
3807                          (match_operand:SI 4 "arith11_double_operand" "0,rLH")))]
3808   "TARGET_ARCH64"
3809   "@
3810    mov%C1\t%x2, %3, %0
3811    mov%c1\t%x2, %4, %0"
3812   [(set_attr "type" "cmove")])
3814 (define_insn "*movsf_cc_sp64"
3815   [(set (match_operand:SF 0 "register_operand" "=f,f")
3816         (if_then_else:SF (match_operator 1 "comparison_operator"
3817                                 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3818                                  (const_int 0)])
3819                          (match_operand:SF 3 "register_operand" "f,0")
3820                          (match_operand:SF 4 "register_operand" "0,f")))]
3821   "TARGET_V9 && TARGET_FPU"
3822   "@
3823    fmovs%C1\t%x2, %3, %0
3824    fmovs%c1\t%x2, %4, %0"
3825   [(set_attr "type" "fpcmove")])
3827 (define_insn "movdf_cc_sp64"
3828   [(set (match_operand:DF 0 "register_operand" "=e,e")
3829         (if_then_else:DF (match_operator 1 "comparison_operator"
3830                                 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3831                                  (const_int 0)])
3832                          (match_operand:DF 3 "register_operand" "e,0")
3833                          (match_operand:DF 4 "register_operand" "0,e")))]
3834   "TARGET_V9 && TARGET_FPU"
3835   "@
3836    fmovd%C1\t%x2, %3, %0
3837    fmovd%c1\t%x2, %4, %0"
3838   [(set_attr "type" "fpcmove")
3839    (set_attr "fptype" "double")])
3841 (define_insn "*movtf_cc_hq_sp64"
3842   [(set (match_operand:TF 0 "register_operand" "=e,e")
3843         (if_then_else:TF (match_operator 1 "comparison_operator"
3844                                 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3845                                  (const_int 0)])
3846                          (match_operand:TF 3 "register_operand" "e,0")
3847                          (match_operand:TF 4 "register_operand" "0,e")))]
3848   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3849   "@
3850    fmovq%C1\t%x2, %3, %0
3851    fmovq%c1\t%x2, %4, %0"
3852   [(set_attr "type" "fpcmove")])
3854 (define_insn_and_split "*movtf_cc_sp64"
3855   [(set (match_operand:TF 0 "register_operand" "=e,e")
3856         (if_then_else:TF (match_operator 1 "comparison_operator"
3857                             [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3858                              (const_int 0)])
3859                          (match_operand:TF 3 "register_operand" "e,0")
3860                          (match_operand:TF 4 "register_operand" "0,e")))]
3861   "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
3862   "#"
3863   "&& reload_completed"
3864   [(clobber (const_int 0))]
3866   rtx set_dest = operands[0];
3867   rtx set_srca = operands[3];
3868   rtx set_srcb = operands[4];
3869   int third = rtx_equal_p (set_dest, set_srca);
3870   rtx dest1, dest2;
3871   rtx srca1, srca2, srcb1, srcb2;
3873   dest1 = gen_df_reg (set_dest, 0);
3874   dest2 = gen_df_reg (set_dest, 1);
3875   srca1 = gen_df_reg (set_srca, 0);
3876   srca2 = gen_df_reg (set_srca, 1);
3877   srcb1 = gen_df_reg (set_srcb, 0);
3878   srcb2 = gen_df_reg (set_srcb, 1);
3880   /* Now emit using the real source and destination we found, swapping
3881      the order if we detect overlap.  */
3882   if ((third && reg_overlap_mentioned_p (dest1, srcb2))
3883       || (!third && reg_overlap_mentioned_p (dest1, srca2)))
3884     {
3885       emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3886       emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3887     }
3888   else
3889     {
3890       emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3891       emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3892     }
3893   DONE;
3895   [(set_attr "length" "2")])
3897 (define_insn "*movqi_cc_reg_sp64"
3898   [(set (match_operand:QI 0 "register_operand" "=r,r")
3899         (if_then_else:QI (match_operator 1 "v9_regcmp_op"
3900                                 [(match_operand:DI 2 "register_operand" "r,r")
3901                                  (const_int 0)])
3902                          (match_operand:QI 3 "arith10_operand" "rM,0")
3903                          (match_operand:QI 4 "arith10_operand" "0,rM")))]
3904   "TARGET_ARCH64"
3905   "@
3906    movr%D1\t%2, %r3, %0
3907    movr%d1\t%2, %r4, %0"
3908   [(set_attr "type" "cmove")])
3910 (define_insn "*movhi_cc_reg_sp64"
3911   [(set (match_operand:HI 0 "register_operand" "=r,r")
3912         (if_then_else:HI (match_operator 1 "v9_regcmp_op"
3913                                 [(match_operand:DI 2 "register_operand" "r,r")
3914                                  (const_int 0)])
3915                          (match_operand:HI 3 "arith10_operand" "rM,0")
3916                          (match_operand:HI 4 "arith10_operand" "0,rM")))]
3917   "TARGET_ARCH64"
3918   "@
3919    movr%D1\t%2, %r3, %0
3920    movr%d1\t%2, %r4, %0"
3921   [(set_attr "type" "cmove")])
3923 (define_insn "*movsi_cc_reg_sp64"
3924   [(set (match_operand:SI 0 "register_operand" "=r,r")
3925         (if_then_else:SI (match_operator 1 "v9_regcmp_op"
3926                                 [(match_operand:DI 2 "register_operand" "r,r")
3927                                  (const_int 0)])
3928                          (match_operand:SI 3 "arith10_operand" "rM,0")
3929                          (match_operand:SI 4 "arith10_operand" "0,rM")))]
3930   "TARGET_ARCH64"
3931   "@
3932    movr%D1\t%2, %r3, %0
3933    movr%d1\t%2, %r4, %0"
3934   [(set_attr "type" "cmove")])
3936 ;; ??? The constraints of operands 3,4 need work.
3937 (define_insn "*movdi_cc_reg_sp64"
3938   [(set (match_operand:DI 0 "register_operand" "=r,r")
3939         (if_then_else:DI (match_operator 1 "v9_regcmp_op"
3940                                 [(match_operand:DI 2 "register_operand" "r,r")
3941                                  (const_int 0)])
3942                          (match_operand:DI 3 "arith10_double_operand" "rMH,0")
3943                          (match_operand:DI 4 "arith10_double_operand" "0,rMH")))]
3944   "TARGET_ARCH64"
3945   "@
3946    movr%D1\t%2, %r3, %0
3947    movr%d1\t%2, %r4, %0"
3948   [(set_attr "type" "cmove")])
3950 (define_insn "*movdi_cc_reg_sp64_trunc"
3951   [(set (match_operand:SI 0 "register_operand" "=r,r")
3952         (if_then_else:SI (match_operator 1 "v9_regcmp_op"
3953                                 [(match_operand:DI 2 "register_operand" "r,r")
3954                                  (const_int 0)])
3955                          (match_operand:SI 3 "arith10_double_operand" "rMH,0")
3956                          (match_operand:SI 4 "arith10_double_operand" "0,rMH")))]
3957   "TARGET_ARCH64"
3958   "@
3959    movr%D1\t%2, %r3, %0
3960    movr%d1\t%2, %r4, %0"
3961   [(set_attr "type" "cmove")])
3963 (define_insn "*movsf_cc_reg_sp64"
3964   [(set (match_operand:SF 0 "register_operand" "=f,f")
3965         (if_then_else:SF (match_operator 1 "v9_regcmp_op"
3966                                 [(match_operand:DI 2 "register_operand" "r,r")
3967                                  (const_int 0)])
3968                          (match_operand:SF 3 "register_operand" "f,0")
3969                          (match_operand:SF 4 "register_operand" "0,f")))]
3970   "TARGET_ARCH64 && TARGET_FPU"
3971   "@
3972    fmovrs%D1\t%2, %3, %0
3973    fmovrs%d1\t%2, %4, %0"
3974   [(set_attr "type" "fpcrmove")])
3976 (define_insn "movdf_cc_reg_sp64"
3977   [(set (match_operand:DF 0 "register_operand" "=e,e")
3978         (if_then_else:DF (match_operator 1 "v9_regcmp_op"
3979                                 [(match_operand:DI 2 "register_operand" "r,r")
3980                                  (const_int 0)])
3981                          (match_operand:DF 3 "register_operand" "e,0")
3982                          (match_operand:DF 4 "register_operand" "0,e")))]
3983   "TARGET_ARCH64 && TARGET_FPU"
3984   "@
3985    fmovrd%D1\t%2, %3, %0
3986    fmovrd%d1\t%2, %4, %0"
3987   [(set_attr "type" "fpcrmove")
3988    (set_attr "fptype" "double")])
3990 (define_insn "*movtf_cc_reg_hq_sp64"
3991   [(set (match_operand:TF 0 "register_operand" "=e,e")
3992         (if_then_else:TF (match_operator 1 "v9_regcmp_op"
3993                                 [(match_operand:DI 2 "register_operand" "r,r")
3994                                  (const_int 0)])
3995                          (match_operand:TF 3 "register_operand" "e,0")
3996                          (match_operand:TF 4 "register_operand" "0,e")))]
3997   "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
3998   "@
3999    fmovrq%D1\t%2, %3, %0
4000    fmovrq%d1\t%2, %4, %0"
4001   [(set_attr "type" "fpcrmove")])
4003 (define_insn_and_split "*movtf_cc_reg_sp64"
4004   [(set (match_operand:TF 0 "register_operand" "=e,e")
4005         (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4006                                 [(match_operand:DI 2 "register_operand" "r,r")
4007                                  (const_int 0)])
4008                          (match_operand:TF 3 "register_operand" "e,0")
4009                          (match_operand:TF 4 "register_operand" "0,e")))]
4010   "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
4011   "#"
4012   "&& reload_completed"
4013   [(clobber (const_int 0))]
4015   rtx set_dest = operands[0];
4016   rtx set_srca = operands[3];
4017   rtx set_srcb = operands[4];
4018   int third = rtx_equal_p (set_dest, set_srca);
4019   rtx dest1, dest2;
4020   rtx srca1, srca2, srcb1, srcb2;
4022   dest1 = gen_df_reg (set_dest, 0);
4023   dest2 = gen_df_reg (set_dest, 1);
4024   srca1 = gen_df_reg (set_srca, 0);
4025   srca2 = gen_df_reg (set_srca, 1);
4026   srcb1 = gen_df_reg (set_srcb, 0);
4027   srcb2 = gen_df_reg (set_srcb, 1);
4029   /* Now emit using the real source and destination we found, swapping
4030      the order if we detect overlap.  */
4031   if ((third && reg_overlap_mentioned_p (dest1, srcb2))
4032       || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4033     {
4034       emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4035       emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4036     }
4037   else
4038     {
4039       emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4040       emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4041     }
4042   DONE;
4044   [(set_attr "length" "2")])
4047 ;;- zero extension instructions
4049 ;; These patterns originally accepted general_operands, however, slightly
4050 ;; better code is generated by only accepting register_operands, and then
4051 ;; letting combine generate the ldu[hb] insns.
4053 (define_expand "zero_extendhisi2"
4054   [(set (match_operand:SI 0 "register_operand" "")
4055         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
4056   ""
4058   rtx temp = gen_reg_rtx (SImode);
4059   rtx shift_16 = GEN_INT (16);
4060   int op1_subbyte = 0;
4062   if (GET_CODE (operand1) == SUBREG)
4063     {
4064       op1_subbyte = SUBREG_BYTE (operand1);
4065       op1_subbyte /= GET_MODE_SIZE (SImode);
4066       op1_subbyte *= GET_MODE_SIZE (SImode);
4067       operand1 = XEXP (operand1, 0);
4068     }
4070   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4071                           shift_16));
4072   emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
4073   DONE;
4076 (define_insn "*zero_extendhisi2_insn"
4077   [(set (match_operand:SI 0 "register_operand" "=r")
4078         (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4079   ""
4080   "lduh\t%1, %0"
4081   [(set_attr "type" "load")
4082    (set_attr "us3load_type" "3cycle")])
4084 (define_expand "zero_extendqihi2"
4085   [(set (match_operand:HI 0 "register_operand" "")
4086         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
4087   ""
4088   "")
4090 (define_insn "*zero_extendqihi2_insn"
4091   [(set (match_operand:HI 0 "register_operand" "=r,r")
4092         (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
4093   "GET_CODE (operands[1]) != CONST_INT"
4094   "@
4095    and\t%1, 0xff, %0
4096    ldub\t%1, %0"
4097   [(set_attr "type" "*,load")
4098    (set_attr "us3load_type" "*,3cycle")])
4100 (define_expand "zero_extendqisi2"
4101   [(set (match_operand:SI 0 "register_operand" "")
4102         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
4103   ""
4104   "")
4106 (define_insn "*zero_extendqisi2_insn"
4107   [(set (match_operand:SI 0 "register_operand" "=r,r")
4108         (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
4109   "GET_CODE (operands[1]) != CONST_INT"
4110   "@
4111    and\t%1, 0xff, %0
4112    ldub\t%1, %0"
4113   [(set_attr "type" "*,load")
4114    (set_attr "us3load_type" "*,3cycle")])
4116 (define_expand "zero_extendqidi2"
4117   [(set (match_operand:DI 0 "register_operand" "")
4118         (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
4119   "TARGET_ARCH64"
4120   "")
4122 (define_insn "*zero_extendqidi2_insn"
4123   [(set (match_operand:DI 0 "register_operand" "=r,r")
4124         (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
4125   "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4126   "@
4127    and\t%1, 0xff, %0
4128    ldub\t%1, %0"
4129   [(set_attr "type" "*,load")
4130    (set_attr "us3load_type" "*,3cycle")])
4132 (define_expand "zero_extendhidi2"
4133   [(set (match_operand:DI 0 "register_operand" "")
4134         (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
4135   "TARGET_ARCH64"
4137   rtx temp = gen_reg_rtx (DImode);
4138   rtx shift_48 = GEN_INT (48);
4139   int op1_subbyte = 0;
4141   if (GET_CODE (operand1) == SUBREG)
4142     {
4143       op1_subbyte = SUBREG_BYTE (operand1);
4144       op1_subbyte /= GET_MODE_SIZE (DImode);
4145       op1_subbyte *= GET_MODE_SIZE (DImode);
4146       operand1 = XEXP (operand1, 0);
4147     }
4149   emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4150                           shift_48));
4151   emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
4152   DONE;
4155 (define_insn "*zero_extendhidi2_insn"
4156   [(set (match_operand:DI 0 "register_operand" "=r")
4157         (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4158   "TARGET_ARCH64"
4159   "lduh\t%1, %0"
4160   [(set_attr "type" "load")
4161    (set_attr "us3load_type" "3cycle")])
4164 ;; ??? Write truncdisi pattern using sra?
4166 (define_expand "zero_extendsidi2"
4167   [(set (match_operand:DI 0 "register_operand" "")
4168         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4169   ""
4170   "")
4172 (define_insn "*zero_extendsidi2_insn_sp64"
4173   [(set (match_operand:DI 0 "register_operand" "=r,r")
4174         (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4175   "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4176   "@
4177    srl\t%1, 0, %0
4178    lduw\t%1, %0"
4179   [(set_attr "type" "shift,load")])
4181 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
4182   [(set (match_operand:DI 0 "register_operand" "=r")
4183         (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4184   "! TARGET_ARCH64"
4185   "#"
4186   "&& reload_completed"
4187   [(set (match_dup 2) (match_dup 3))
4188    (set (match_dup 4) (match_dup 5))]
4190   rtx dest1, dest2;
4192   dest1 = gen_highpart (SImode, operands[0]);
4193   dest2 = gen_lowpart (SImode, operands[0]);
4195   /* Swap the order in case of overlap.  */
4196   if (REGNO (dest1) == REGNO (operands[1]))
4197     {
4198       operands[2] = dest2;
4199       operands[3] = operands[1];
4200       operands[4] = dest1;
4201       operands[5] = const0_rtx;
4202     }
4203   else
4204     {
4205       operands[2] = dest1;
4206       operands[3] = const0_rtx;
4207       operands[4] = dest2;
4208       operands[5] = operands[1];
4209     }
4211   [(set_attr "length" "2")])
4213 ;; Simplify comparisons of extended values.
4215 (define_insn "*cmp_zero_extendqisi2"
4216   [(set (reg:CC 100)
4217         (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
4218                     (const_int 0)))]
4219   ""
4220   "andcc\t%0, 0xff, %%g0"
4221   [(set_attr "type" "compare")])
4223 (define_insn "*cmp_zero_qi"
4224   [(set (reg:CC 100)
4225         (compare:CC (match_operand:QI 0 "register_operand" "r")
4226                     (const_int 0)))]
4227   ""
4228   "andcc\t%0, 0xff, %%g0"
4229   [(set_attr "type" "compare")])
4231 (define_insn "*cmp_zero_extendqisi2_set"
4232   [(set (reg:CC 100)
4233         (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
4234                     (const_int 0)))
4235    (set (match_operand:SI 0 "register_operand" "=r")
4236         (zero_extend:SI (match_dup 1)))]
4237   ""
4238   "andcc\t%1, 0xff, %0"
4239   [(set_attr "type" "compare")])
4241 (define_insn "*cmp_zero_extendqisi2_andcc_set"
4242   [(set (reg:CC 100)
4243         (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
4244                             (const_int 255))
4245                     (const_int 0)))
4246    (set (match_operand:SI 0 "register_operand" "=r")
4247         (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
4248   ""
4249   "andcc\t%1, 0xff, %0"
4250   [(set_attr "type" "compare")])
4252 (define_insn "*cmp_zero_extendqidi2"
4253   [(set (reg:CCX 100)
4254         (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
4255                      (const_int 0)))]
4256   "TARGET_ARCH64"
4257   "andcc\t%0, 0xff, %%g0"
4258   [(set_attr "type" "compare")])
4260 (define_insn "*cmp_zero_qi_sp64"
4261   [(set (reg:CCX 100)
4262         (compare:CCX (match_operand:QI 0 "register_operand" "r")
4263                      (const_int 0)))]
4264   "TARGET_ARCH64"
4265   "andcc\t%0, 0xff, %%g0"
4266   [(set_attr "type" "compare")])
4268 (define_insn "*cmp_zero_extendqidi2_set"
4269   [(set (reg:CCX 100)
4270         (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
4271                      (const_int 0)))
4272    (set (match_operand:DI 0 "register_operand" "=r")
4273         (zero_extend:DI (match_dup 1)))]
4274   "TARGET_ARCH64"
4275   "andcc\t%1, 0xff, %0"
4276   [(set_attr "type" "compare")])
4278 (define_insn "*cmp_zero_extendqidi2_andcc_set"
4279   [(set (reg:CCX 100)
4280         (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
4281                              (const_int 255))
4282                      (const_int 0)))
4283    (set (match_operand:DI 0 "register_operand" "=r")
4284         (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
4285   "TARGET_ARCH64"
4286   "andcc\t%1, 0xff, %0"
4287   [(set_attr "type" "compare")])
4289 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
4291 (define_insn "*cmp_siqi_trunc"
4292   [(set (reg:CC 100)
4293         (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
4294                     (const_int 0)))]
4295   ""
4296   "andcc\t%0, 0xff, %%g0"
4297   [(set_attr "type" "compare")])
4299 (define_insn "*cmp_siqi_trunc_set"
4300   [(set (reg:CC 100)
4301         (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
4302                     (const_int 0)))
4303    (set (match_operand:QI 0 "register_operand" "=r")
4304         (subreg:QI (match_dup 1) 3))]
4305   ""
4306   "andcc\t%1, 0xff, %0"
4307   [(set_attr "type" "compare")])
4309 (define_insn "*cmp_diqi_trunc"
4310   [(set (reg:CC 100)
4311         (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
4312                     (const_int 0)))]
4313   "TARGET_ARCH64"
4314   "andcc\t%0, 0xff, %%g0"
4315   [(set_attr "type" "compare")])
4317 (define_insn "*cmp_diqi_trunc_set"
4318   [(set (reg:CC 100)
4319         (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
4320                     (const_int 0)))
4321    (set (match_operand:QI 0 "register_operand" "=r")
4322         (subreg:QI (match_dup 1) 7))]
4323   "TARGET_ARCH64"
4324   "andcc\t%1, 0xff, %0"
4325   [(set_attr "type" "compare")])
4327 ;;- sign extension instructions
4329 ;; These patterns originally accepted general_operands, however, slightly
4330 ;; better code is generated by only accepting register_operands, and then
4331 ;; letting combine generate the lds[hb] insns.
4333 (define_expand "extendhisi2"
4334   [(set (match_operand:SI 0 "register_operand" "")
4335         (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
4336   ""
4338   rtx temp = gen_reg_rtx (SImode);
4339   rtx shift_16 = GEN_INT (16);
4340   int op1_subbyte = 0;
4342   if (GET_CODE (operand1) == SUBREG)
4343     {
4344       op1_subbyte = SUBREG_BYTE (operand1);
4345       op1_subbyte /= GET_MODE_SIZE (SImode);
4346       op1_subbyte *= GET_MODE_SIZE (SImode);
4347       operand1 = XEXP (operand1, 0);
4348     }
4350   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4351                           shift_16));
4352   emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
4353   DONE;
4356 (define_insn "*sign_extendhisi2_insn"
4357   [(set (match_operand:SI 0 "register_operand" "=r")
4358         (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4359   ""
4360   "ldsh\t%1, %0"
4361   [(set_attr "type" "sload")
4362    (set_attr "us3load_type" "3cycle")])
4364 (define_expand "extendqihi2"
4365   [(set (match_operand:HI 0 "register_operand" "")
4366         (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
4367   ""
4369   rtx temp = gen_reg_rtx (SImode);
4370   rtx shift_24 = GEN_INT (24);
4371   int op1_subbyte = 0;
4372   int op0_subbyte = 0;
4374   if (GET_CODE (operand1) == SUBREG)
4375     {
4376       op1_subbyte = SUBREG_BYTE (operand1);
4377       op1_subbyte /= GET_MODE_SIZE (SImode);
4378       op1_subbyte *= GET_MODE_SIZE (SImode);
4379       operand1 = XEXP (operand1, 0);
4380     }
4381   if (GET_CODE (operand0) == SUBREG)
4382     {
4383       op0_subbyte = SUBREG_BYTE (operand0);
4384       op0_subbyte /= GET_MODE_SIZE (SImode);
4385       op0_subbyte *= GET_MODE_SIZE (SImode);
4386       operand0 = XEXP (operand0, 0);
4387     }
4388   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4389                           shift_24));
4390   if (GET_MODE (operand0) != SImode)
4391     operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
4392   emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4393   DONE;
4396 (define_insn "*sign_extendqihi2_insn"
4397   [(set (match_operand:HI 0 "register_operand" "=r")
4398         (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
4399   ""
4400   "ldsb\t%1, %0"
4401   [(set_attr "type" "sload")
4402    (set_attr "us3load_type" "3cycle")])
4404 (define_expand "extendqisi2"
4405   [(set (match_operand:SI 0 "register_operand" "")
4406         (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
4407   ""
4409   rtx temp = gen_reg_rtx (SImode);
4410   rtx shift_24 = GEN_INT (24);
4411   int op1_subbyte = 0;
4413   if (GET_CODE (operand1) == SUBREG)
4414     {
4415       op1_subbyte = SUBREG_BYTE (operand1);
4416       op1_subbyte /= GET_MODE_SIZE (SImode);
4417       op1_subbyte *= GET_MODE_SIZE (SImode);
4418       operand1 = XEXP (operand1, 0);
4419     }
4421   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4422                           shift_24));
4423   emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4424   DONE;
4427 (define_insn "*sign_extendqisi2_insn"
4428   [(set (match_operand:SI 0 "register_operand" "=r")
4429         (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
4430   ""
4431   "ldsb\t%1, %0"
4432   [(set_attr "type" "sload")
4433    (set_attr "us3load_type" "3cycle")])
4435 (define_expand "extendqidi2"
4436   [(set (match_operand:DI 0 "register_operand" "")
4437         (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
4438   "TARGET_ARCH64"
4440   rtx temp = gen_reg_rtx (DImode);
4441   rtx shift_56 = GEN_INT (56);
4442   int op1_subbyte = 0;
4444   if (GET_CODE (operand1) == SUBREG)
4445     {
4446       op1_subbyte = SUBREG_BYTE (operand1);
4447       op1_subbyte /= GET_MODE_SIZE (DImode);
4448       op1_subbyte *= GET_MODE_SIZE (DImode);
4449       operand1 = XEXP (operand1, 0);
4450     }
4452   emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4453                           shift_56));
4454   emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
4455   DONE;
4458 (define_insn "*sign_extendqidi2_insn"
4459   [(set (match_operand:DI 0 "register_operand" "=r")
4460         (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
4461   "TARGET_ARCH64"
4462   "ldsb\t%1, %0"
4463   [(set_attr "type" "sload")
4464    (set_attr "us3load_type" "3cycle")])
4466 (define_expand "extendhidi2"
4467   [(set (match_operand:DI 0 "register_operand" "")
4468         (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
4469   "TARGET_ARCH64"
4471   rtx temp = gen_reg_rtx (DImode);
4472   rtx shift_48 = GEN_INT (48);
4473   int op1_subbyte = 0;
4475   if (GET_CODE (operand1) == SUBREG)
4476     {
4477       op1_subbyte = SUBREG_BYTE (operand1);
4478       op1_subbyte /= GET_MODE_SIZE (DImode);
4479       op1_subbyte *= GET_MODE_SIZE (DImode);
4480       operand1 = XEXP (operand1, 0);
4481     }
4483   emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4484                           shift_48));
4485   emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
4486   DONE;
4489 (define_insn "*sign_extendhidi2_insn"
4490   [(set (match_operand:DI 0 "register_operand" "=r")
4491         (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4492   "TARGET_ARCH64"
4493   "ldsh\t%1, %0"
4494   [(set_attr "type" "sload")
4495    (set_attr "us3load_type" "3cycle")])
4497 (define_expand "extendsidi2"
4498   [(set (match_operand:DI 0 "register_operand" "")
4499         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
4500   "TARGET_ARCH64"
4501   "")
4503 (define_insn "*sign_extendsidi2_insn"
4504   [(set (match_operand:DI 0 "register_operand" "=r,r")
4505         (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4506   "TARGET_ARCH64"
4507   "@
4508   sra\t%1, 0, %0
4509   ldsw\t%1, %0"
4510   [(set_attr "type" "shift,sload")
4511    (set_attr "us3load_type" "*,3cycle")])
4513 ;; Special pattern for optimizing bit-field compares.  This is needed
4514 ;; because combine uses this as a canonical form.
4516 (define_insn "*cmp_zero_extract"
4517   [(set (reg:CC 100)
4518         (compare:CC
4519          (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
4520                           (match_operand:SI 1 "small_int_or_double" "n")
4521                           (match_operand:SI 2 "small_int_or_double" "n"))
4522          (const_int 0)))]
4523   "(GET_CODE (operands[2]) == CONST_INT
4524     && INTVAL (operands[2]) > 19)
4525    || (GET_CODE (operands[2]) == CONST_DOUBLE
4526        && CONST_DOUBLE_LOW (operands[2]) > 19)"
4528   int len = (GET_CODE (operands[1]) == CONST_INT
4529              ? INTVAL (operands[1])
4530              : CONST_DOUBLE_LOW (operands[1]));
4531   int pos = 32 -
4532             (GET_CODE (operands[2]) == CONST_INT
4533              ? INTVAL (operands[2])
4534              : CONST_DOUBLE_LOW (operands[2])) - len;
4535   HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
4537   operands[1] = GEN_INT (mask);
4538   return "andcc\t%0, %1, %%g0";
4540   [(set_attr "type" "compare")])
4542 (define_insn "*cmp_zero_extract_sp64"
4543   [(set (reg:CCX 100)
4544         (compare:CCX
4545          (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
4546                           (match_operand:SI 1 "small_int_or_double" "n")
4547                           (match_operand:SI 2 "small_int_or_double" "n"))
4548          (const_int 0)))]
4549   "TARGET_ARCH64
4550    && ((GET_CODE (operands[2]) == CONST_INT
4551         && INTVAL (operands[2]) > 51)
4552        || (GET_CODE (operands[2]) == CONST_DOUBLE
4553            && CONST_DOUBLE_LOW (operands[2]) > 51))"
4555   int len = (GET_CODE (operands[1]) == CONST_INT
4556              ? INTVAL (operands[1])
4557              : CONST_DOUBLE_LOW (operands[1]));
4558   int pos = 64 -
4559             (GET_CODE (operands[2]) == CONST_INT
4560              ? INTVAL (operands[2])
4561              : CONST_DOUBLE_LOW (operands[2])) - len;
4562   HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
4564   operands[1] = GEN_INT (mask);
4565   return "andcc\t%0, %1, %%g0";
4567   [(set_attr "type" "compare")])
4569 ;; Conversions between float, double and long double.
4571 (define_insn "extendsfdf2"
4572   [(set (match_operand:DF 0 "register_operand" "=e")
4573         (float_extend:DF
4574          (match_operand:SF 1 "register_operand" "f")))]
4575   "TARGET_FPU"
4576   "fstod\t%1, %0"
4577   [(set_attr "type" "fp")
4578    (set_attr "fptype" "double")])
4580 (define_expand "extendsftf2"
4581   [(set (match_operand:TF 0 "nonimmediate_operand" "")
4582         (float_extend:TF
4583          (match_operand:SF 1 "register_operand" "")))]
4584   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4585   "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4587 (define_insn "*extendsftf2_hq"
4588   [(set (match_operand:TF 0 "register_operand" "=e")
4589         (float_extend:TF
4590          (match_operand:SF 1 "register_operand" "f")))]
4591   "TARGET_FPU && TARGET_HARD_QUAD"
4592   "fstoq\t%1, %0"
4593   [(set_attr "type" "fp")])
4595 (define_expand "extenddftf2"
4596   [(set (match_operand:TF 0 "nonimmediate_operand" "")
4597         (float_extend:TF
4598          (match_operand:DF 1 "register_operand" "")))]
4599   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4600   "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4602 (define_insn "*extenddftf2_hq"
4603   [(set (match_operand:TF 0 "register_operand" "=e")
4604         (float_extend:TF
4605          (match_operand:DF 1 "register_operand" "e")))]
4606   "TARGET_FPU && TARGET_HARD_QUAD"
4607   "fdtoq\t%1, %0"
4608   [(set_attr "type" "fp")])
4610 (define_insn "truncdfsf2"
4611   [(set (match_operand:SF 0 "register_operand" "=f")
4612         (float_truncate:SF
4613          (match_operand:DF 1 "register_operand" "e")))]
4614   "TARGET_FPU"
4615   "fdtos\t%1, %0"
4616   [(set_attr "type" "fp")
4617    (set_attr "fptype" "double")])
4619 (define_expand "trunctfsf2"
4620   [(set (match_operand:SF 0 "register_operand" "")
4621         (float_truncate:SF
4622          (match_operand:TF 1 "general_operand" "")))]
4623   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4624   "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4626 (define_insn "*trunctfsf2_hq"
4627   [(set (match_operand:SF 0 "register_operand" "=f")
4628         (float_truncate:SF
4629          (match_operand:TF 1 "register_operand" "e")))]
4630   "TARGET_FPU && TARGET_HARD_QUAD"
4631   "fqtos\t%1, %0"
4632   [(set_attr "type" "fp")])
4634 (define_expand "trunctfdf2"
4635   [(set (match_operand:DF 0 "register_operand" "")
4636         (float_truncate:DF
4637          (match_operand:TF 1 "general_operand" "")))]
4638   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4639   "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4641 (define_insn "*trunctfdf2_hq"
4642   [(set (match_operand:DF 0 "register_operand" "=e")
4643         (float_truncate:DF
4644          (match_operand:TF 1 "register_operand" "e")))]
4645   "TARGET_FPU && TARGET_HARD_QUAD"
4646   "fqtod\t%1, %0"
4647   [(set_attr "type" "fp")])
4649 ;; Conversion between fixed point and floating point.
4651 (define_insn "floatsisf2"
4652   [(set (match_operand:SF 0 "register_operand" "=f")
4653         (float:SF (match_operand:SI 1 "register_operand" "f")))]
4654   "TARGET_FPU"
4655   "fitos\t%1, %0"
4656   [(set_attr "type" "fp")
4657    (set_attr "fptype" "double")])
4659 (define_insn "floatsidf2"
4660   [(set (match_operand:DF 0 "register_operand" "=e")
4661         (float:DF (match_operand:SI 1 "register_operand" "f")))]
4662   "TARGET_FPU"
4663   "fitod\t%1, %0"
4664   [(set_attr "type" "fp")
4665    (set_attr "fptype" "double")])
4667 (define_expand "floatsitf2"
4668   [(set (match_operand:TF 0 "nonimmediate_operand" "")
4669         (float:TF (match_operand:SI 1 "register_operand" "")))]
4670   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4671   "emit_tfmode_cvt (FLOAT, operands); DONE;")
4673 (define_insn "*floatsitf2_hq"
4674   [(set (match_operand:TF 0 "register_operand" "=e")
4675         (float:TF (match_operand:SI 1 "register_operand" "f")))]
4676   "TARGET_FPU && TARGET_HARD_QUAD"
4677   "fitoq\t%1, %0"
4678   [(set_attr "type" "fp")])
4680 (define_expand "floatunssitf2"
4681   [(set (match_operand:TF 0 "nonimmediate_operand" "")
4682         (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
4683   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4684   "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4686 ;; Now the same for 64 bit sources.
4688 (define_insn "floatdisf2"
4689   [(set (match_operand:SF 0 "register_operand" "=f")
4690         (float:SF (match_operand:DI 1 "register_operand" "e")))]
4691   "TARGET_V9 && TARGET_FPU"
4692   "fxtos\t%1, %0"
4693   [(set_attr "type" "fp")
4694    (set_attr "fptype" "double")])
4696 (define_expand "floatunsdisf2"
4697   [(use (match_operand:SF 0 "register_operand" ""))
4698    (use (match_operand:DI 1 "general_operand" ""))]
4699   "TARGET_ARCH64 && TARGET_FPU"
4700   "sparc_emit_floatunsdi (operands, SFmode); DONE;")
4702 (define_insn "floatdidf2"
4703   [(set (match_operand:DF 0 "register_operand" "=e")
4704         (float:DF (match_operand:DI 1 "register_operand" "e")))]
4705   "TARGET_V9 && TARGET_FPU"
4706   "fxtod\t%1, %0"
4707   [(set_attr "type" "fp")
4708    (set_attr "fptype" "double")])
4710 (define_expand "floatunsdidf2"
4711   [(use (match_operand:DF 0 "register_operand" ""))
4712    (use (match_operand:DI 1 "general_operand" ""))]
4713   "TARGET_ARCH64 && TARGET_FPU"
4714   "sparc_emit_floatunsdi (operands, DFmode); DONE;")
4716 (define_expand "floatditf2"
4717   [(set (match_operand:TF 0 "nonimmediate_operand" "")
4718         (float:TF (match_operand:DI 1 "register_operand" "")))]
4719   "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4720   "emit_tfmode_cvt (FLOAT, operands); DONE;")
4722 (define_insn "*floatditf2_hq"
4723   [(set (match_operand:TF 0 "register_operand" "=e")
4724         (float:TF (match_operand:DI 1 "register_operand" "e")))]
4725   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4726   "fxtoq\t%1, %0"
4727   [(set_attr "type" "fp")])
4729 (define_expand "floatunsditf2"
4730   [(set (match_operand:TF 0 "nonimmediate_operand" "")
4731         (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
4732   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4733   "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4735 ;; Convert a float to an actual integer.
4736 ;; Truncation is performed as part of the conversion.
4738 (define_insn "fix_truncsfsi2"
4739   [(set (match_operand:SI 0 "register_operand" "=f")
4740         (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4741   "TARGET_FPU"
4742   "fstoi\t%1, %0"
4743   [(set_attr "type" "fp")
4744    (set_attr "fptype" "double")])
4746 (define_insn "fix_truncdfsi2"
4747   [(set (match_operand:SI 0 "register_operand" "=f")
4748         (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4749   "TARGET_FPU"
4750   "fdtoi\t%1, %0"
4751   [(set_attr "type" "fp")
4752    (set_attr "fptype" "double")])
4754 (define_expand "fix_trunctfsi2"
4755   [(set (match_operand:SI 0 "register_operand" "")
4756         (fix:SI (match_operand:TF 1 "general_operand" "")))]
4757   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4758   "emit_tfmode_cvt (FIX, operands); DONE;")
4760 (define_insn "*fix_trunctfsi2_hq"
4761   [(set (match_operand:SI 0 "register_operand" "=f")
4762         (fix:SI (match_operand:TF 1 "register_operand" "e")))]
4763   "TARGET_FPU && TARGET_HARD_QUAD"
4764   "fqtoi\t%1, %0"
4765   [(set_attr "type" "fp")])
4767 (define_expand "fixuns_trunctfsi2"
4768   [(set (match_operand:SI 0 "register_operand" "")
4769         (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
4770   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4771   "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4773 ;; Now the same, for V9 targets
4775 (define_insn "fix_truncsfdi2"
4776   [(set (match_operand:DI 0 "register_operand" "=e")
4777         (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4778   "TARGET_V9 && TARGET_FPU"
4779   "fstox\t%1, %0"
4780   [(set_attr "type" "fp")
4781    (set_attr "fptype" "double")])
4783 (define_expand "fixuns_truncsfdi2"
4784   [(use (match_operand:DI 0 "register_operand" ""))
4785    (use (match_operand:SF 1 "general_operand" ""))]
4786   "TARGET_ARCH64 && TARGET_FPU"
4787   "sparc_emit_fixunsdi (operands, SFmode); DONE;")
4789 (define_insn "fix_truncdfdi2"
4790   [(set (match_operand:DI 0 "register_operand" "=e")
4791         (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4792   "TARGET_V9 && TARGET_FPU"
4793   "fdtox\t%1, %0"
4794   [(set_attr "type" "fp")
4795    (set_attr "fptype" "double")])
4797 (define_expand "fixuns_truncdfdi2"
4798   [(use (match_operand:DI 0 "register_operand" ""))
4799    (use (match_operand:DF 1 "general_operand" ""))]
4800   "TARGET_ARCH64 && TARGET_FPU"
4801   "sparc_emit_fixunsdi (operands, DFmode); DONE;")
4803 (define_expand "fix_trunctfdi2"
4804   [(set (match_operand:DI 0 "register_operand" "")
4805         (fix:DI (match_operand:TF 1 "general_operand" "")))]
4806   "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4807   "emit_tfmode_cvt (FIX, operands); DONE;")
4809 (define_insn "*fix_trunctfdi2_hq"
4810   [(set (match_operand:DI 0 "register_operand" "=e")
4811         (fix:DI (match_operand:TF 1 "register_operand" "e")))]
4812   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4813   "fqtox\t%1, %0"
4814   [(set_attr "type" "fp")])
4816 (define_expand "fixuns_trunctfdi2"
4817   [(set (match_operand:DI 0 "register_operand" "")
4818         (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
4819   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4820   "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4822 ;;- arithmetic instructions
4824 (define_expand "adddi3"
4825   [(set (match_operand:DI 0 "register_operand" "")
4826         (plus:DI (match_operand:DI 1 "register_operand" "")
4827                  (match_operand:DI 2 "arith_double_add_operand" "")))]
4828   ""
4830   if (! TARGET_ARCH64)
4831     {
4832       emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4833                           gen_rtx_SET (VOIDmode, operands[0],
4834                                    gen_rtx_PLUS (DImode, operands[1],
4835                                                  operands[2])),
4836                           gen_rtx_CLOBBER (VOIDmode,
4837                                    gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4838       DONE;
4839     }
4842 (define_insn_and_split "adddi3_insn_sp32"
4843   [(set (match_operand:DI 0 "register_operand" "=r")
4844         (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4845                  (match_operand:DI 2 "arith_double_operand" "rHI")))
4846    (clobber (reg:CC 100))]
4847   "! TARGET_ARCH64"
4848   "#"
4849   "&& reload_completed"
4850   [(parallel [(set (reg:CC_NOOV 100)
4851                    (compare:CC_NOOV (plus:SI (match_dup 4)
4852                                              (match_dup 5))
4853                                     (const_int 0)))
4854               (set (match_dup 3)
4855                    (plus:SI (match_dup 4) (match_dup 5)))])
4856    (set (match_dup 6)
4857         (plus:SI (plus:SI (match_dup 7)
4858                           (match_dup 8))
4859                  (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4861   operands[3] = gen_lowpart (SImode, operands[0]);
4862   operands[4] = gen_lowpart (SImode, operands[1]);
4863   operands[5] = gen_lowpart (SImode, operands[2]);
4864   operands[6] = gen_highpart (SImode, operands[0]);
4865   operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
4866 #if HOST_BITS_PER_WIDE_INT == 32
4867   if (GET_CODE (operands[2]) == CONST_INT)
4868     {
4869       if (INTVAL (operands[2]) < 0)
4870         operands[8] = constm1_rtx;
4871       else
4872         operands[8] = const0_rtx;
4873     }
4874   else
4875 #endif
4876     operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4878   [(set_attr "length" "2")])
4880 (define_split
4881   [(set (match_operand:DI 0 "register_operand" "")
4882         (minus:DI (match_operand:DI 1 "arith_double_operand" "")
4883                   (match_operand:DI 2 "arith_double_operand" "")))
4884    (clobber (reg:CC 100))]
4885   "! TARGET_ARCH64 && reload_completed"
4886   [(parallel [(set (reg:CC_NOOV 100)
4887                    (compare:CC_NOOV (minus:SI (match_dup 4)
4888                                               (match_dup 5))
4889                                     (const_int 0)))
4890               (set (match_dup 3)
4891                    (minus:SI (match_dup 4) (match_dup 5)))])
4892    (set (match_dup 6)
4893         (minus:SI (minus:SI (match_dup 7)
4894                             (match_dup 8))
4895                   (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4897   operands[3] = gen_lowpart (SImode, operands[0]);
4898   operands[4] = gen_lowpart (SImode, operands[1]);
4899   operands[5] = gen_lowpart (SImode, operands[2]);
4900   operands[6] = gen_highpart (SImode, operands[0]);
4901   operands[7] = gen_highpart (SImode, operands[1]);
4902 #if HOST_BITS_PER_WIDE_INT == 32
4903   if (GET_CODE (operands[2]) == CONST_INT)
4904     {
4905       if (INTVAL (operands[2]) < 0)
4906         operands[8] = constm1_rtx;
4907       else
4908         operands[8] = const0_rtx;
4909     }
4910   else
4911 #endif
4912     operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4915 ;; LTU here means "carry set"
4916 (define_insn "addx"
4917   [(set (match_operand:SI 0 "register_operand" "=r")
4918         (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4919                           (match_operand:SI 2 "arith_operand" "rI"))
4920                  (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4921   ""
4922   "addx\t%1, %2, %0"
4923   [(set_attr "type" "ialuX")])
4925 (define_insn_and_split "*addx_extend_sp32"
4926   [(set (match_operand:DI 0 "register_operand" "=r")
4927         (zero_extend:DI (plus:SI (plus:SI
4928                                   (match_operand:SI 1 "reg_or_0_operand" "%rJ")
4929                                   (match_operand:SI 2 "arith_operand" "rI"))
4930                                  (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4931   "! TARGET_ARCH64"
4932   "#"
4933   "&& reload_completed"
4934   [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
4935                                (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4936    (set (match_dup 4) (const_int 0))]
4937   "operands[3] = gen_lowpart (SImode, operands[0]);
4938    operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
4939   [(set_attr "length" "2")])
4941 (define_insn "*addx_extend_sp64"
4942   [(set (match_operand:DI 0 "register_operand" "=r")
4943         (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
4944                                           (match_operand:SI 2 "arith_operand" "rI"))
4945                                  (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4946   "TARGET_ARCH64"
4947   "addx\t%r1, %2, %0"
4948   [(set_attr "type" "ialuX")])
4950 (define_insn "subx"
4951   [(set (match_operand:SI 0 "register_operand" "=r")
4952         (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4953                             (match_operand:SI 2 "arith_operand" "rI"))
4954                   (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4955   ""
4956   "subx\t%r1, %2, %0"
4957   [(set_attr "type" "ialuX")])
4959 (define_insn "*subx_extend_sp64"
4960   [(set (match_operand:DI 0 "register_operand" "=r")
4961         (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4962                                             (match_operand:SI 2 "arith_operand" "rI"))
4963                                   (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4964   "TARGET_ARCH64"
4965   "subx\t%r1, %2, %0"
4966   [(set_attr "type" "ialuX")])
4968 (define_insn_and_split "*subx_extend"
4969   [(set (match_operand:DI 0 "register_operand" "=r")
4970         (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4971                                             (match_operand:SI 2 "arith_operand" "rI"))
4972                                   (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4973   "! TARGET_ARCH64"
4974   "#"
4975   "&& reload_completed"
4976   [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
4977                                 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4978    (set (match_dup 4) (const_int 0))]
4979   "operands[3] = gen_lowpart (SImode, operands[0]);
4980    operands[4] = gen_highpart (SImode, operands[0]);"
4981   [(set_attr "length" "2")])
4983 (define_insn_and_split ""
4984   [(set (match_operand:DI 0 "register_operand" "=r")
4985         (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4986                  (match_operand:DI 2 "register_operand" "r")))
4987    (clobber (reg:CC 100))]
4988   "! TARGET_ARCH64"
4989   "#"
4990   "&& reload_completed"
4991   [(parallel [(set (reg:CC_NOOV 100)
4992                    (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
4993                                     (const_int 0)))
4994               (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
4995    (set (match_dup 6)
4996         (plus:SI (plus:SI (match_dup 4) (const_int 0))
4997                  (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4998   "operands[3] = gen_lowpart (SImode, operands[2]);
4999    operands[4] = gen_highpart (SImode, operands[2]);
5000    operands[5] = gen_lowpart (SImode, operands[0]);
5001    operands[6] = gen_highpart (SImode, operands[0]);"
5002   [(set_attr "length" "2")])
5004 (define_insn "*adddi3_sp64"
5005   [(set (match_operand:DI 0 "register_operand" "=r,r")
5006         (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
5007                  (match_operand:DI 2 "arith_double_add_operand" "rHI,O")))]
5008   "TARGET_ARCH64"
5009   "@
5010    add\t%1, %2, %0
5011    sub\t%1, -%2, %0")
5013 (define_insn "addsi3"
5014   [(set (match_operand:SI 0 "register_operand" "=r,r,d")
5015         (plus:SI (match_operand:SI 1 "register_operand" "%r,r,d")
5016                  (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
5017   ""
5018   "@
5019    add\t%1, %2, %0
5020    sub\t%1, -%2, %0
5021    fpadd32s\t%1, %2, %0"
5022   [(set_attr "type" "*,*,fga")])
5024 (define_insn "*cmp_cc_plus"
5025   [(set (reg:CC_NOOV 100)
5026         (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
5027                                   (match_operand:SI 1 "arith_operand" "rI"))
5028                          (const_int 0)))]
5029   ""
5030   "addcc\t%0, %1, %%g0"
5031   [(set_attr "type" "compare")])
5033 (define_insn "*cmp_ccx_plus"
5034   [(set (reg:CCX_NOOV 100)
5035         (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_double_operand" "%r")
5036                                    (match_operand:DI 1 "arith_double_operand" "rHI"))
5037                           (const_int 0)))]
5038   "TARGET_ARCH64"
5039   "addcc\t%0, %1, %%g0"
5040   [(set_attr "type" "compare")])
5042 (define_insn "*cmp_cc_plus_set"
5043   [(set (reg:CC_NOOV 100)
5044         (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5045                                   (match_operand:SI 2 "arith_operand" "rI"))
5046                          (const_int 0)))
5047    (set (match_operand:SI 0 "register_operand" "=r")
5048         (plus:SI (match_dup 1) (match_dup 2)))]
5049   ""
5050   "addcc\t%1, %2, %0"
5051   [(set_attr "type" "compare")])
5053 (define_insn "*cmp_ccx_plus_set"
5054   [(set (reg:CCX_NOOV 100)
5055         (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5056                                    (match_operand:DI 2 "arith_double_operand" "rHI"))
5057                           (const_int 0)))
5058    (set (match_operand:DI 0 "register_operand" "=r")
5059         (plus:DI (match_dup 1) (match_dup 2)))]
5060   "TARGET_ARCH64"
5061   "addcc\t%1, %2, %0"
5062   [(set_attr "type" "compare")])
5064 (define_expand "subdi3"
5065   [(set (match_operand:DI 0 "register_operand" "")
5066         (minus:DI (match_operand:DI 1 "register_operand" "")
5067                   (match_operand:DI 2 "arith_double_add_operand" "")))]
5068   ""
5070   if (! TARGET_ARCH64)
5071     {
5072       emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5073                           gen_rtx_SET (VOIDmode, operands[0],
5074                                    gen_rtx_MINUS (DImode, operands[1],
5075                                                   operands[2])),
5076                           gen_rtx_CLOBBER (VOIDmode,
5077                                    gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5078       DONE;
5079     }
5082 (define_insn_and_split "*subdi3_sp32"
5083   [(set (match_operand:DI 0 "register_operand" "=r")
5084         (minus:DI (match_operand:DI 1 "register_operand" "r")
5085                   (match_operand:DI 2 "arith_double_operand" "rHI")))
5086    (clobber (reg:CC 100))]
5087   "! TARGET_ARCH64"
5088   "#"
5089   "&& reload_completed
5090    && (GET_CODE (operands[2]) == CONST_INT
5091        || GET_CODE (operands[2]) == CONST_DOUBLE)"
5092   [(clobber (const_int 0))]
5094   rtx highp, lowp;
5096   highp = gen_highpart_mode (SImode, DImode, operands[2]);
5097   lowp = gen_lowpart (SImode, operands[2]);
5098   if ((lowp == const0_rtx)
5099       && (operands[0] == operands[1]))
5100     {
5101       emit_insn (gen_rtx_SET (VOIDmode,
5102                               gen_highpart (SImode, operands[0]),
5103                               gen_rtx_MINUS (SImode,
5104                                              gen_highpart_mode (SImode, DImode,
5105                                                                 operands[1]),
5106                                              highp)));
5107     }
5108   else
5109     {
5110       emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5111                                        gen_lowpart (SImode, operands[1]),
5112                                        lowp));
5113       emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5114                            gen_highpart_mode (SImode, DImode, operands[1]),
5115                            highp));
5116     }
5117   DONE;
5119   [(set_attr "length" "2")])
5121 (define_split
5122   [(set (match_operand:DI 0 "register_operand" "")
5123         (minus:DI (match_operand:DI 1 "register_operand" "")
5124                   (match_operand:DI 2 "register_operand" "")))
5125    (clobber (reg:CC 100))]
5126   "! TARGET_ARCH64
5127    && reload_completed"
5128   [(clobber (const_int 0))]
5130   emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5131                                    gen_lowpart (SImode, operands[1]),
5132                                    gen_lowpart (SImode, operands[2])));
5133   emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5134                        gen_highpart (SImode, operands[1]),
5135                        gen_highpart (SImode, operands[2])));
5136   DONE;
5139 (define_insn_and_split ""
5140   [(set (match_operand:DI 0 "register_operand" "=r")
5141       (minus:DI (match_operand:DI 1 "register_operand" "r")
5142                 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
5143    (clobber (reg:CC 100))]
5144   "! TARGET_ARCH64"
5145   "#"
5146   "&& reload_completed"
5147   [(parallel [(set (reg:CC_NOOV 100)
5148                    (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
5149                                     (const_int 0)))
5150               (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
5151    (set (match_dup 6)
5152         (minus:SI (minus:SI (match_dup 4) (const_int 0))
5153                   (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5154   "operands[3] = gen_lowpart (SImode, operands[1]);
5155    operands[4] = gen_highpart (SImode, operands[1]);
5156    operands[5] = gen_lowpart (SImode, operands[0]);
5157    operands[6] = gen_highpart (SImode, operands[0]);"
5158   [(set_attr "length" "2")])
5160 (define_insn "*subdi3_sp64"
5161   [(set (match_operand:DI 0 "register_operand" "=r,r")
5162         (minus:DI (match_operand:DI 1 "register_operand" "r,r")
5163                   (match_operand:DI 2 "arith_double_add_operand" "rHI,O")))]
5164   "TARGET_ARCH64"
5165   "@
5166    sub\t%1, %2, %0
5167    add\t%1, -%2, %0")
5169 (define_insn "subsi3"
5170   [(set (match_operand:SI 0 "register_operand" "=r,r,d")
5171         (minus:SI (match_operand:SI 1 "register_operand" "r,r,d")
5172                   (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
5173   ""
5174   "@
5175    sub\t%1, %2, %0
5176    add\t%1, -%2, %0
5177    fpsub32s\t%1, %2, %0"
5178   [(set_attr "type" "*,*,fga")])
5180 (define_insn "*cmp_minus_cc"
5181   [(set (reg:CC_NOOV 100)
5182         (compare:CC_NOOV (minus:SI (match_operand:SI 0 "reg_or_0_operand" "rJ")
5183                                    (match_operand:SI 1 "arith_operand" "rI"))
5184                          (const_int 0)))]
5185   ""
5186   "subcc\t%r0, %1, %%g0"
5187   [(set_attr "type" "compare")])
5189 (define_insn "*cmp_minus_ccx"
5190   [(set (reg:CCX_NOOV 100)
5191         (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
5192                                     (match_operand:DI 1 "arith_double_operand" "rHI"))
5193                           (const_int 0)))]
5194   "TARGET_ARCH64"
5195   "subcc\t%0, %1, %%g0"
5196   [(set_attr "type" "compare")])
5198 (define_insn "cmp_minus_cc_set"
5199   [(set (reg:CC_NOOV 100)
5200         (compare:CC_NOOV (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5201                                    (match_operand:SI 2 "arith_operand" "rI"))
5202                          (const_int 0)))
5203    (set (match_operand:SI 0 "register_operand" "=r")
5204         (minus:SI (match_dup 1) (match_dup 2)))]
5205   ""
5206   "subcc\t%r1, %2, %0"
5207   [(set_attr "type" "compare")])
5209 (define_insn "*cmp_minus_ccx_set"
5210   [(set (reg:CCX_NOOV 100)
5211         (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
5212                                     (match_operand:DI 2 "arith_double_operand" "rHI"))
5213                           (const_int 0)))
5214    (set (match_operand:DI 0 "register_operand" "=r")
5215         (minus:DI (match_dup 1) (match_dup 2)))]
5216   "TARGET_ARCH64"
5217   "subcc\t%1, %2, %0"
5218   [(set_attr "type" "compare")])
5220 ;; Integer Multiply/Divide.
5222 ;; The 32 bit multiply/divide instructions are deprecated on v9, but at
5223 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
5225 (define_insn "mulsi3"
5226   [(set (match_operand:SI 0 "register_operand" "=r")
5227         (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5228                  (match_operand:SI 2 "arith_operand" "rI")))]
5229   "TARGET_HARD_MUL"
5230   "smul\t%1, %2, %0"
5231   [(set_attr "type" "imul")])
5233 (define_expand "muldi3"
5234   [(set (match_operand:DI 0 "register_operand" "=r")
5235         (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5236                  (match_operand:DI 2 "arith_double_operand" "rHI")))]
5237   "TARGET_ARCH64 || TARGET_V8PLUS"
5239   if (TARGET_V8PLUS)
5240     {
5241       emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
5242       DONE;
5243     }
5246 (define_insn "*muldi3_sp64"
5247   [(set (match_operand:DI 0 "register_operand" "=r")
5248         (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5249                  (match_operand:DI 2 "arith_double_operand" "rHI")))]
5250   "TARGET_ARCH64"
5251   "mulx\t%1, %2, %0"
5252   [(set_attr "type" "imul")])
5254 ;; V8plus wide multiply.
5255 ;; XXX
5256 (define_insn "muldi3_v8plus"
5257   [(set (match_operand:DI 0 "register_operand" "=r,h")
5258         (mult:DI (match_operand:DI 1 "arith_double_operand" "%r,0")
5259                  (match_operand:DI 2 "arith_double_operand" "rI,rI")))
5260    (clobber (match_scratch:SI 3 "=&h,X"))
5261    (clobber (match_scratch:SI 4 "=&h,X"))]
5262   "TARGET_V8PLUS"
5264   if (sparc_check_64 (operands[1], insn) <= 0)
5265     output_asm_insn ("srl\t%L1, 0, %L1", operands);
5266   if (which_alternative == 1)
5267     output_asm_insn ("sllx\t%H1, 32, %H1", operands);
5268   if (GET_CODE (operands[2]) == CONST_INT)
5269     {
5270       if (which_alternative == 1)
5271         return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %2, %L0\;srlx\t%L0, 32, %H0";
5272       else
5273         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";
5274     }
5275   else if (rtx_equal_p (operands[1], operands[2]))
5276     {
5277       if (which_alternative == 1)
5278         return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %H1, %L0\;srlx\t%L0, 32, %H0";
5279       else
5280         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";
5281     }
5282   if (sparc_check_64 (operands[2], insn) <= 0)
5283     output_asm_insn ("srl\t%L2, 0, %L2", operands);
5284   if (which_alternative == 1)
5285     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";
5286   else
5287     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   [(set_attr "type" "multi")
5290    (set_attr "length" "9,8")])
5292 (define_insn "*cmp_mul_set"
5293   [(set (reg:CC 100)
5294         (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5295                     (match_operand:SI 2 "arith_operand" "rI"))
5296                     (const_int 0)))
5297    (set (match_operand:SI 0 "register_operand" "=r")
5298         (mult:SI (match_dup 1) (match_dup 2)))]
5299   "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
5300   "smulcc\t%1, %2, %0"
5301   [(set_attr "type" "imul")])
5303 (define_expand "mulsidi3"
5304   [(set (match_operand:DI 0 "register_operand" "")
5305         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5306                  (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
5307   "TARGET_HARD_MUL"
5309   if (CONSTANT_P (operands[2]))
5310     {
5311       if (TARGET_V8PLUS)
5312         emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
5313                                               operands[2]));
5314       else if (TARGET_ARCH32)
5315         emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
5316                                             operands[2]));
5317       else 
5318         emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
5319                                             operands[2]));
5320       DONE;
5321     }
5322   if (TARGET_V8PLUS)
5323     {
5324       emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
5325       DONE;
5326     }
5329 ;; V9 puts the 64 bit product in a 64 bit register.  Only out or global
5330 ;; registers can hold 64 bit values in the V8plus environment.
5331 ;; XXX
5332 (define_insn "mulsidi3_v8plus"
5333   [(set (match_operand:DI 0 "register_operand" "=h,r")
5334         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5335                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5336    (clobber (match_scratch:SI 3 "=X,&h"))]
5337   "TARGET_V8PLUS"
5338   "@
5339    smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5340    smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5341   [(set_attr "type" "multi")
5342    (set_attr "length" "2,3")])
5344 ;; XXX
5345 (define_insn "const_mulsidi3_v8plus"
5346   [(set (match_operand:DI 0 "register_operand" "=h,r")
5347         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5348                  (match_operand:DI 2 "small_int" "I,I")))
5349    (clobber (match_scratch:SI 3 "=X,&h"))]
5350   "TARGET_V8PLUS"
5351   "@
5352    smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5353    smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5354   [(set_attr "type" "multi")
5355    (set_attr "length" "2,3")])
5357 ;; XXX
5358 (define_insn "*mulsidi3_sp32"
5359   [(set (match_operand:DI 0 "register_operand" "=r")
5360         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5361                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5362   "TARGET_HARD_MUL32"
5364   return TARGET_SPARCLET
5365          ? "smuld\t%1, %2, %L0"
5366          : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
5368   [(set (attr "type")
5369         (if_then_else (eq_attr "isa" "sparclet")
5370                       (const_string "imul") (const_string "multi")))
5371    (set (attr "length")
5372         (if_then_else (eq_attr "isa" "sparclet")
5373                       (const_int 1) (const_int 2)))])
5375 (define_insn "*mulsidi3_sp64"
5376   [(set (match_operand:DI 0 "register_operand" "=r")
5377         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5378                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5379   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5380   "smul\t%1, %2, %0"
5381   [(set_attr "type" "imul")])
5383 ;; Extra pattern, because sign_extend of a constant isn't valid.
5385 ;; XXX
5386 (define_insn "const_mulsidi3_sp32"
5387   [(set (match_operand:DI 0 "register_operand" "=r")
5388         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5389                  (match_operand:DI 2 "small_int" "I")))]
5390   "TARGET_HARD_MUL32"
5392   return TARGET_SPARCLET
5393          ? "smuld\t%1, %2, %L0"
5394          : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
5396   [(set (attr "type")
5397         (if_then_else (eq_attr "isa" "sparclet")
5398                       (const_string "imul") (const_string "multi")))
5399    (set (attr "length")
5400         (if_then_else (eq_attr "isa" "sparclet")
5401                       (const_int 1) (const_int 2)))])
5403 (define_insn "const_mulsidi3_sp64"
5404   [(set (match_operand:DI 0 "register_operand" "=r")
5405         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5406                  (match_operand:DI 2 "small_int" "I")))]
5407   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5408   "smul\t%1, %2, %0"
5409   [(set_attr "type" "imul")])
5411 (define_expand "smulsi3_highpart"
5412   [(set (match_operand:SI 0 "register_operand" "")
5413         (truncate:SI
5414          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5415                                (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
5416                       (const_int 32))))]
5417   "TARGET_HARD_MUL && TARGET_ARCH32"
5419   if (CONSTANT_P (operands[2]))
5420     {
5421       if (TARGET_V8PLUS)
5422         {
5423           emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
5424                                                         operands[1],
5425                                                         operands[2],
5426                                                         GEN_INT (32)));
5427           DONE;
5428         }
5429       emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
5430       DONE;
5431     }
5432   if (TARGET_V8PLUS)
5433     {
5434       emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
5435                                               operands[2], GEN_INT (32)));
5436       DONE;
5437     }
5440 ;; XXX
5441 (define_insn "smulsi3_highpart_v8plus"
5442   [(set (match_operand:SI 0 "register_operand" "=h,r")
5443         (truncate:SI
5444          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5445                                (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5446                       (match_operand:SI 3 "const_int_operand" "i,i"))))
5447    (clobber (match_scratch:SI 4 "=X,&h"))]
5448   "TARGET_V8PLUS"
5449   "@
5450    smul\t%1, %2, %0\;srlx\t%0, %3, %0
5451    smul\t%1, %2, %4\;srlx\t%4, %3, %0"
5452   [(set_attr "type" "multi")
5453    (set_attr "length" "2")])
5455 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
5456 ;; XXX
5457 (define_insn ""
5458   [(set (match_operand:SI 0 "register_operand" "=h,r")
5459         (subreg:SI
5460          (lshiftrt:DI
5461           (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5462                    (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5463           (match_operand:SI 3 "const_int_operand" "i,i"))
5464          4))
5465    (clobber (match_scratch:SI 4 "=X,&h"))]
5466   "TARGET_V8PLUS"
5467   "@
5468    smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5469    smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5470   [(set_attr "type" "multi")
5471    (set_attr "length" "2")])
5473 ;; XXX
5474 (define_insn "const_smulsi3_highpart_v8plus"
5475   [(set (match_operand:SI 0 "register_operand" "=h,r")
5476         (truncate:SI
5477          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5478                                (match_operand:DI 2 "small_int" "i,i"))
5479                       (match_operand:SI 3 "const_int_operand" "i,i"))))
5480    (clobber (match_scratch:SI 4 "=X,&h"))]
5481   "TARGET_V8PLUS"
5482   "@
5483    smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5484    smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5485   [(set_attr "type" "multi")
5486    (set_attr "length" "2")])
5488 ;; XXX
5489 (define_insn "*smulsi3_highpart_sp32"
5490   [(set (match_operand:SI 0 "register_operand" "=r")
5491         (truncate:SI
5492          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5493                                (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
5494                       (const_int 32))))]
5495   "TARGET_HARD_MUL32"
5496   "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
5497   [(set_attr "type" "multi")
5498    (set_attr "length" "2")])
5500 ;; XXX
5501 (define_insn "const_smulsi3_highpart"
5502   [(set (match_operand:SI 0 "register_operand" "=r")
5503         (truncate:SI
5504          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5505                                (match_operand:DI 2 "small_int" "i"))
5506                       (const_int 32))))]
5507   "TARGET_HARD_MUL32"
5508   "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
5509   [(set_attr "type" "multi")
5510    (set_attr "length" "2")])
5512 (define_expand "umulsidi3"
5513   [(set (match_operand:DI 0 "register_operand" "")
5514         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5515                  (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
5516   "TARGET_HARD_MUL"
5518   if (CONSTANT_P (operands[2]))
5519     {
5520       if (TARGET_V8PLUS)
5521         emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
5522                                                operands[2]));
5523       else if (TARGET_ARCH32)
5524         emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
5525                                              operands[2]));
5526       else 
5527         emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
5528                                              operands[2]));
5529       DONE;
5530     }
5531   if (TARGET_V8PLUS)
5532     {
5533       emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
5534       DONE;
5535     }
5538 ;; XXX
5539 (define_insn "umulsidi3_v8plus"
5540   [(set (match_operand:DI 0 "register_operand" "=h,r")
5541         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5542                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5543    (clobber (match_scratch:SI 3 "=X,&h"))]
5544   "TARGET_V8PLUS"
5545   "@
5546    umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5547    umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5548   [(set_attr "type" "multi")
5549    (set_attr "length" "2,3")])
5551 ;; XXX
5552 (define_insn "*umulsidi3_sp32"
5553   [(set (match_operand:DI 0 "register_operand" "=r")
5554         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5555                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5556   "TARGET_HARD_MUL32"
5558   return TARGET_SPARCLET
5559          ? "umuld\t%1, %2, %L0"
5560          : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
5562   [(set (attr "type")
5563         (if_then_else (eq_attr "isa" "sparclet")
5564                       (const_string "imul") (const_string "multi")))
5565    (set (attr "length")
5566         (if_then_else (eq_attr "isa" "sparclet")
5567                       (const_int 1) (const_int 2)))])
5569 (define_insn "*umulsidi3_sp64"
5570   [(set (match_operand:DI 0 "register_operand" "=r")
5571         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5572                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5573   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5574   "umul\t%1, %2, %0"
5575   [(set_attr "type" "imul")])
5577 ;; Extra pattern, because sign_extend of a constant isn't valid.
5579 ;; XXX
5580 (define_insn "const_umulsidi3_sp32"
5581   [(set (match_operand:DI 0 "register_operand" "=r")
5582         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5583                  (match_operand:DI 2 "uns_small_int" "")))]
5584   "TARGET_HARD_MUL32"
5586   return TARGET_SPARCLET
5587          ? "umuld\t%1, %s2, %L0"
5588          : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
5590   [(set (attr "type")
5591         (if_then_else (eq_attr "isa" "sparclet")
5592                       (const_string "imul") (const_string "multi")))
5593    (set (attr "length")
5594         (if_then_else (eq_attr "isa" "sparclet")
5595                       (const_int 1) (const_int 2)))])
5597 (define_insn "const_umulsidi3_sp64"
5598   [(set (match_operand:DI 0 "register_operand" "=r")
5599         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5600                  (match_operand:DI 2 "uns_small_int" "")))]
5601   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5602   "umul\t%1, %s2, %0"
5603   [(set_attr "type" "imul")])
5605 ;; XXX
5606 (define_insn "const_umulsidi3_v8plus"
5607   [(set (match_operand:DI 0 "register_operand" "=h,r")
5608         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5609                  (match_operand:DI 2 "uns_small_int" "")))
5610    (clobber (match_scratch:SI 3 "=X,h"))]
5611   "TARGET_V8PLUS"
5612   "@
5613    umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
5614    umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5615   [(set_attr "type" "multi")
5616    (set_attr "length" "2,3")])
5618 (define_expand "umulsi3_highpart"
5619   [(set (match_operand:SI 0 "register_operand" "")
5620         (truncate:SI
5621          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5622                                (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
5623                       (const_int 32))))]
5624   "TARGET_HARD_MUL && TARGET_ARCH32"
5626   if (CONSTANT_P (operands[2]))
5627     {
5628       if (TARGET_V8PLUS)
5629         {
5630           emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
5631                                                         operands[1],
5632                                                         operands[2],
5633                                                         GEN_INT (32)));
5634           DONE;
5635         }
5636       emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
5637       DONE;
5638     }
5639   if (TARGET_V8PLUS)
5640     {
5641       emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
5642                                               operands[2], GEN_INT (32)));
5643       DONE;
5644     }
5647 ;; XXX
5648 (define_insn "umulsi3_highpart_v8plus"
5649   [(set (match_operand:SI 0 "register_operand" "=h,r")
5650         (truncate:SI
5651          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5652                                (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5653                       (match_operand:SI 3 "const_int_operand" "i,i"))))
5654    (clobber (match_scratch:SI 4 "=X,h"))]
5655   "TARGET_V8PLUS"
5656   "@
5657    umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5658    umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5659   [(set_attr "type" "multi")
5660    (set_attr "length" "2")])
5662 ;; XXX
5663 (define_insn "const_umulsi3_highpart_v8plus"
5664   [(set (match_operand:SI 0 "register_operand" "=h,r")
5665         (truncate:SI
5666          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5667                                (match_operand:DI 2 "uns_small_int" ""))
5668                       (match_operand:SI 3 "const_int_operand" "i,i"))))
5669    (clobber (match_scratch:SI 4 "=X,h"))]
5670   "TARGET_V8PLUS"
5671   "@
5672    umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
5673    umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
5674   [(set_attr "type" "multi")
5675    (set_attr "length" "2")])
5677 ;; XXX
5678 (define_insn "*umulsi3_highpart_sp32"
5679   [(set (match_operand:SI 0 "register_operand" "=r")
5680         (truncate:SI
5681          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5682                                (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
5683                       (const_int 32))))]
5684   "TARGET_HARD_MUL32"
5685   "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
5686   [(set_attr "type" "multi")
5687    (set_attr "length" "2")])
5689 ;; XXX
5690 (define_insn "const_umulsi3_highpart"
5691   [(set (match_operand:SI 0 "register_operand" "=r")
5692         (truncate:SI
5693          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5694                                (match_operand:DI 2 "uns_small_int" ""))
5695                       (const_int 32))))]
5696   "TARGET_HARD_MUL32"
5697   "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
5698   [(set_attr "type" "multi")
5699    (set_attr "length" "2")])
5701 ;; The v8 architecture specifies that there must be 3 instructions between
5702 ;; a y register write and a use of it for correct results.
5704 (define_expand "divsi3"
5705   [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
5706                    (div:SI (match_operand:SI 1 "register_operand" "r,r")
5707                            (match_operand:SI 2 "input_operand" "rI,m")))
5708               (clobber (match_scratch:SI 3 "=&r,&r"))])]
5709   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5711   if (TARGET_ARCH64)
5712     {
5713       operands[3] = gen_reg_rtx(SImode);
5714       emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
5715       emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
5716                                   operands[3]));
5717       DONE;
5718     }
5721 (define_insn "divsi3_sp32"
5722   [(set (match_operand:SI 0 "register_operand" "=r,r")
5723         (div:SI (match_operand:SI 1 "register_operand" "r,r")
5724                 (match_operand:SI 2 "input_operand" "rI,m")))
5725    (clobber (match_scratch:SI 3 "=&r,&r"))]
5726   "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
5727    && TARGET_ARCH32"
5729   if (which_alternative == 0)
5730     if (TARGET_V9)
5731       return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdiv\t%1, %2, %0";
5732     else
5733       return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
5734   else
5735     if (TARGET_V9)
5736       return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tld\t%2, %3\n\tsdiv\t%1, %3, %0";
5737     else
5738       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   [(set_attr "type" "multi")
5741    (set (attr "length")
5742         (if_then_else (eq_attr "isa" "v9")
5743                       (const_int 4) (const_int 6)))])
5745 (define_insn "divsi3_sp64"
5746   [(set (match_operand:SI 0 "register_operand" "=r")
5747         (div:SI (match_operand:SI 1 "register_operand" "r")
5748                 (match_operand:SI 2 "input_operand" "rI")))
5749    (use (match_operand:SI 3 "register_operand" "r"))]
5750   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5751   "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
5752   [(set_attr "type" "multi")
5753    (set_attr "length" "2")])
5755 (define_insn "divdi3"
5756   [(set (match_operand:DI 0 "register_operand" "=r")
5757         (div:DI (match_operand:DI 1 "register_operand" "r")
5758                 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5759   "TARGET_ARCH64"
5760   "sdivx\t%1, %2, %0"
5761   [(set_attr "type" "idiv")])
5763 (define_insn "*cmp_sdiv_cc_set"
5764   [(set (reg:CC 100)
5765         (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
5766                             (match_operand:SI 2 "arith_operand" "rI"))
5767                     (const_int 0)))
5768    (set (match_operand:SI 0 "register_operand" "=r")
5769         (div:SI (match_dup 1) (match_dup 2)))
5770    (clobber (match_scratch:SI 3 "=&r"))]
5771   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5773   if (TARGET_V9)
5774     return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdivcc\t%1, %2, %0";
5775   else
5776     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   [(set_attr "type" "multi")
5779    (set (attr "length")
5780         (if_then_else (eq_attr "isa" "v9")
5781                       (const_int 3) (const_int 6)))])
5783 ;; XXX
5784 (define_expand "udivsi3"
5785   [(set (match_operand:SI 0 "register_operand" "")
5786         (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "")
5787                  (match_operand:SI 2 "input_operand" "")))]
5788   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5789   "")
5791 (define_insn "udivsi3_sp32"
5792   [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
5793         (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r,r,m")
5794                  (match_operand:SI 2 "input_operand" "rI,m,r")))]
5795   "(TARGET_V8
5796     || TARGET_DEPRECATED_V8_INSNS)
5797    && TARGET_ARCH32"
5799   output_asm_insn ("wr\t%%g0, %%g0, %%y", operands);
5800   switch (which_alternative)
5801     {
5802     default:
5803       return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
5804     case 1:
5805       return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
5806     case 2:
5807       return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
5808     }
5810   [(set_attr "type" "multi")
5811    (set_attr "length" "5")])
5813 (define_insn "udivsi3_sp64"
5814   [(set (match_operand:SI 0 "register_operand" "=r")
5815         (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r")
5816                  (match_operand:SI 2 "input_operand" "rI")))]
5817   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5818   "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
5819   [(set_attr "type" "multi")
5820    (set_attr "length" "2")])
5822 (define_insn "udivdi3"
5823   [(set (match_operand:DI 0 "register_operand" "=r")
5824         (udiv:DI (match_operand:DI 1 "register_operand" "r")
5825                  (match_operand:DI 2 "arith_double_operand" "rHI")))]
5826   "TARGET_ARCH64"
5827   "udivx\t%1, %2, %0"
5828   [(set_attr "type" "idiv")])
5830 (define_insn "*cmp_udiv_cc_set"
5831   [(set (reg:CC 100)
5832         (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
5833                              (match_operand:SI 2 "arith_operand" "rI"))
5834                     (const_int 0)))
5835    (set (match_operand:SI 0 "register_operand" "=r")
5836         (udiv:SI (match_dup 1) (match_dup 2)))]
5837   "TARGET_V8
5838    || TARGET_DEPRECATED_V8_INSNS"
5840   if (TARGET_V9)
5841     return "wr\t%%g0, %%g0, %%y\n\tudivcc\t%1, %2, %0";
5842   else
5843     return "wr\t%%g0, %%g0, %%y\n\tnop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
5845   [(set_attr "type" "multi")
5846    (set (attr "length")
5847         (if_then_else (eq_attr "isa" "v9")
5848                       (const_int 2) (const_int 5)))])
5850 ; sparclet multiply/accumulate insns
5852 (define_insn "*smacsi"
5853   [(set (match_operand:SI 0 "register_operand" "=r")
5854         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
5855                           (match_operand:SI 2 "arith_operand" "rI"))
5856                  (match_operand:SI 3 "register_operand" "0")))]
5857   "TARGET_SPARCLET"
5858   "smac\t%1, %2, %0"
5859   [(set_attr "type" "imul")])
5861 (define_insn "*smacdi"
5862   [(set (match_operand:DI 0 "register_operand" "=r")
5863         (plus:DI (mult:DI (sign_extend:DI
5864                            (match_operand:SI 1 "register_operand" "%r"))
5865                           (sign_extend:DI
5866                            (match_operand:SI 2 "register_operand" "r")))
5867                  (match_operand:DI 3 "register_operand" "0")))]
5868   "TARGET_SPARCLET"
5869   "smacd\t%1, %2, %L0"
5870   [(set_attr "type" "imul")])
5872 (define_insn "*umacdi"
5873   [(set (match_operand:DI 0 "register_operand" "=r")
5874         (plus:DI (mult:DI (zero_extend:DI
5875                            (match_operand:SI 1 "register_operand" "%r"))
5876                           (zero_extend:DI
5877                            (match_operand:SI 2 "register_operand" "r")))
5878                  (match_operand:DI 3 "register_operand" "0")))]
5879   "TARGET_SPARCLET"
5880   "umacd\t%1, %2, %L0"
5881   [(set_attr "type" "imul")])
5883 ;;- Boolean instructions
5884 ;; We define DImode `and' so with DImode `not' we can get
5885 ;; DImode `andn'.  Other combinations are possible.
5887 (define_expand "anddi3"
5888   [(set (match_operand:DI 0 "register_operand" "")
5889         (and:DI (match_operand:DI 1 "arith_double_operand" "")
5890                 (match_operand:DI 2 "arith_double_operand" "")))]
5891   ""
5892   "")
5894 (define_insn "*anddi3_sp32"
5895   [(set (match_operand:DI 0 "register_operand" "=r,b")
5896         (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
5897                 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
5898   "! TARGET_ARCH64"
5899   "@
5900   #
5901   fand\t%1, %2, %0"
5902   [(set_attr "type" "*,fga")
5903    (set_attr "length" "2,*")
5904    (set_attr "fptype" "double")])
5906 (define_insn "*anddi3_sp64"
5907   [(set (match_operand:DI 0 "register_operand" "=r,b")
5908         (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
5909                 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
5910   "TARGET_ARCH64"
5911   "@
5912    and\t%1, %2, %0
5913    fand\t%1, %2, %0"
5914   [(set_attr "type" "*,fga")
5915    (set_attr "fptype" "double")])
5917 (define_insn "andsi3"
5918   [(set (match_operand:SI 0 "register_operand" "=r,d")
5919         (and:SI (match_operand:SI 1 "arith_operand" "%r,d")
5920                 (match_operand:SI 2 "arith_operand" "rI,d")))]
5921   ""
5922   "@
5923    and\t%1, %2, %0
5924    fands\t%1, %2, %0"
5925   [(set_attr "type" "*,fga")])
5927 (define_split
5928   [(set (match_operand:SI 0 "register_operand" "")
5929         (and:SI (match_operand:SI 1 "register_operand" "")
5930                 (match_operand:SI 2 "" "")))
5931    (clobber (match_operand:SI 3 "register_operand" ""))]
5932   "GET_CODE (operands[2]) == CONST_INT
5933    && !SMALL_INT32 (operands[2])
5934    && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
5935   [(set (match_dup 3) (match_dup 4))
5936    (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
5938   operands[4] = GEN_INT (~INTVAL (operands[2]));
5941 ;; Split DImode logical operations requiring two instructions.
5942 (define_split
5943   [(set (match_operand:DI 0 "register_operand" "")
5944         (match_operator:DI 1 "cc_arithop"       ; AND, IOR, XOR
5945                            [(match_operand:DI 2 "register_operand" "")
5946                             (match_operand:DI 3 "arith_double_operand" "")]))]
5947   "! TARGET_ARCH64
5948    && reload_completed
5949    && ((GET_CODE (operands[0]) == REG
5950         && REGNO (operands[0]) < 32)
5951        || (GET_CODE (operands[0]) == SUBREG
5952            && GET_CODE (SUBREG_REG (operands[0])) == REG
5953            && REGNO (SUBREG_REG (operands[0])) < 32))"
5954   [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
5955    (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
5957   operands[4] = gen_highpart (SImode, operands[0]);
5958   operands[5] = gen_lowpart (SImode, operands[0]);
5959   operands[6] = gen_highpart (SImode, operands[2]);
5960   operands[7] = gen_lowpart (SImode, operands[2]);
5961 #if HOST_BITS_PER_WIDE_INT == 32
5962   if (GET_CODE (operands[3]) == CONST_INT)
5963     {
5964       if (INTVAL (operands[3]) < 0)
5965         operands[8] = constm1_rtx;
5966       else
5967         operands[8] = const0_rtx;
5968     }
5969   else
5970 #endif
5971     operands[8] = gen_highpart_mode (SImode, DImode, operands[3]);
5972   operands[9] = gen_lowpart (SImode, operands[3]);
5975 (define_insn_and_split "*and_not_di_sp32"
5976   [(set (match_operand:DI 0 "register_operand" "=r,b")
5977         (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
5978                 (match_operand:DI 2 "register_operand" "r,b")))]
5979   "! TARGET_ARCH64"
5980   "@
5981    #
5982    fandnot1\t%1, %2, %0"
5983   "&& reload_completed
5984    && ((GET_CODE (operands[0]) == REG
5985         && REGNO (operands[0]) < 32)
5986        || (GET_CODE (operands[0]) == SUBREG
5987            && GET_CODE (SUBREG_REG (operands[0])) == REG
5988            && REGNO (SUBREG_REG (operands[0])) < 32))"
5989   [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
5990    (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
5991   "operands[3] = gen_highpart (SImode, operands[0]);
5992    operands[4] = gen_highpart (SImode, operands[1]);
5993    operands[5] = gen_highpart (SImode, operands[2]);
5994    operands[6] = gen_lowpart (SImode, operands[0]);
5995    operands[7] = gen_lowpart (SImode, operands[1]);
5996    operands[8] = gen_lowpart (SImode, operands[2]);"
5997   [(set_attr "type" "*,fga")
5998    (set_attr "length" "2,*")
5999    (set_attr "fptype" "double")])
6001 (define_insn "*and_not_di_sp64"
6002   [(set (match_operand:DI 0 "register_operand" "=r,b")
6003         (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6004                 (match_operand:DI 2 "register_operand" "r,b")))]
6005   "TARGET_ARCH64"
6006   "@
6007    andn\t%2, %1, %0
6008    fandnot1\t%1, %2, %0"
6009   [(set_attr "type" "*,fga")
6010    (set_attr "fptype" "double")])
6012 (define_insn "*and_not_si"
6013   [(set (match_operand:SI 0 "register_operand" "=r,d")
6014         (and:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6015                 (match_operand:SI 2 "register_operand" "r,d")))]
6016   ""
6017   "@
6018    andn\t%2, %1, %0
6019    fandnot1s\t%1, %2, %0"
6020   [(set_attr "type" "*,fga")])
6022 (define_expand "iordi3"
6023   [(set (match_operand:DI 0 "register_operand" "")
6024         (ior:DI (match_operand:DI 1 "arith_double_operand" "")
6025                 (match_operand:DI 2 "arith_double_operand" "")))]
6026   ""
6027   "")
6029 (define_insn "*iordi3_sp32"
6030   [(set (match_operand:DI 0 "register_operand" "=r,b")
6031         (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6032                 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6033   "! TARGET_ARCH64"
6034   "@
6035   #
6036   for\t%1, %2, %0"
6037   [(set_attr "type" "*,fga")
6038    (set_attr "length" "2,*")
6039    (set_attr "fptype" "double")])
6041 (define_insn "*iordi3_sp64"
6042   [(set (match_operand:DI 0 "register_operand" "=r,b")
6043         (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6044                 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6045   "TARGET_ARCH64"
6046   "@
6047   or\t%1, %2, %0
6048   for\t%1, %2, %0"
6049   [(set_attr "type" "*,fga")
6050    (set_attr "fptype" "double")])
6052 (define_insn "iorsi3"
6053   [(set (match_operand:SI 0 "register_operand" "=r,d")
6054         (ior:SI (match_operand:SI 1 "arith_operand" "%r,d")
6055                 (match_operand:SI 2 "arith_operand" "rI,d")))]
6056   ""
6057   "@
6058    or\t%1, %2, %0
6059    fors\t%1, %2, %0"
6060   [(set_attr "type" "*,fga")])
6062 (define_split
6063   [(set (match_operand:SI 0 "register_operand" "")
6064         (ior:SI (match_operand:SI 1 "register_operand" "")
6065                 (match_operand:SI 2 "" "")))
6066    (clobber (match_operand:SI 3 "register_operand" ""))]
6067   "GET_CODE (operands[2]) == CONST_INT
6068    && !SMALL_INT32 (operands[2])
6069    && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6070   [(set (match_dup 3) (match_dup 4))
6071    (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
6073   operands[4] = GEN_INT (~INTVAL (operands[2]));
6076 (define_insn_and_split "*or_not_di_sp32"
6077   [(set (match_operand:DI 0 "register_operand" "=r,b")
6078         (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6079                 (match_operand:DI 2 "register_operand" "r,b")))]
6080   "! TARGET_ARCH64"
6081   "@
6082    #
6083    fornot1\t%1, %2, %0"
6084   "&& reload_completed
6085    && ((GET_CODE (operands[0]) == REG
6086         && REGNO (operands[0]) < 32)
6087        || (GET_CODE (operands[0]) == SUBREG
6088            && GET_CODE (SUBREG_REG (operands[0])) == REG
6089            && REGNO (SUBREG_REG (operands[0])) < 32))"
6090   [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
6091    (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
6092   "operands[3] = gen_highpart (SImode, operands[0]);
6093    operands[4] = gen_highpart (SImode, operands[1]);
6094    operands[5] = gen_highpart (SImode, operands[2]);
6095    operands[6] = gen_lowpart (SImode, operands[0]);
6096    operands[7] = gen_lowpart (SImode, operands[1]);
6097    operands[8] = gen_lowpart (SImode, operands[2]);"
6098   [(set_attr "type" "*,fga")
6099    (set_attr "length" "2,*")
6100    (set_attr "fptype" "double")])
6102 (define_insn "*or_not_di_sp64"
6103   [(set (match_operand:DI 0 "register_operand" "=r,b")
6104         (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6105                 (match_operand:DI 2 "register_operand" "r,b")))]
6106   "TARGET_ARCH64"
6107   "@
6108   orn\t%2, %1, %0
6109   fornot1\t%1, %2, %0"
6110   [(set_attr "type" "*,fga")
6111    (set_attr "fptype" "double")])
6113 (define_insn "*or_not_si"
6114   [(set (match_operand:SI 0 "register_operand" "=r,d")
6115         (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6116                 (match_operand:SI 2 "register_operand" "r,d")))]
6117   ""
6118   "@
6119    orn\t%2, %1, %0
6120    fornot1s\t%1, %2, %0"
6121   [(set_attr "type" "*,fga")])
6123 (define_expand "xordi3"
6124   [(set (match_operand:DI 0 "register_operand" "")
6125         (xor:DI (match_operand:DI 1 "arith_double_operand" "")
6126                 (match_operand:DI 2 "arith_double_operand" "")))]
6127   ""
6128   "")
6130 (define_insn "*xordi3_sp32"
6131   [(set (match_operand:DI 0 "register_operand" "=r,b")
6132         (xor:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6133                 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6134   "! TARGET_ARCH64"
6135   "@
6136   #
6137   fxor\t%1, %2, %0"
6138   [(set_attr "type" "*,fga")
6139    (set_attr "length" "2,*")
6140    (set_attr "fptype" "double")])
6142 (define_insn "*xordi3_sp64"
6143   [(set (match_operand:DI 0 "register_operand" "=r,b")
6144         (xor:DI (match_operand:DI 1 "arith_double_operand" "%rJ,b")
6145                 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6146   "TARGET_ARCH64"
6147   "@
6148   xor\t%r1, %2, %0
6149   fxor\t%1, %2, %0"
6150   [(set_attr "type" "*,fga")
6151    (set_attr "fptype" "double")])
6153 (define_insn "*xordi3_sp64_dbl"
6154   [(set (match_operand:DI 0 "register_operand" "=r")
6155         (xor:DI (match_operand:DI 1 "register_operand" "r")
6156                 (match_operand:DI 2 "const64_operand" "")))]
6157   "(TARGET_ARCH64
6158     && HOST_BITS_PER_WIDE_INT != 64)"
6159   "xor\t%1, %2, %0")
6161 (define_insn "xorsi3"
6162   [(set (match_operand:SI 0 "register_operand" "=r,d")
6163         (xor:SI (match_operand:SI 1 "arith_operand" "%rJ,d")
6164                 (match_operand:SI 2 "arith_operand" "rI,d")))]
6165   ""
6166   "@
6167    xor\t%r1, %2, %0
6168    fxors\t%1, %2, %0"
6169   [(set_attr "type" "*,fga")])
6171 (define_split
6172   [(set (match_operand:SI 0 "register_operand" "")
6173         (xor:SI (match_operand:SI 1 "register_operand" "")
6174                 (match_operand:SI 2 "" "")))
6175    (clobber (match_operand:SI 3 "register_operand" ""))]
6176   "GET_CODE (operands[2]) == CONST_INT
6177    && !SMALL_INT32 (operands[2])
6178    && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6179   [(set (match_dup 3) (match_dup 4))
6180    (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
6182   operands[4] = GEN_INT (~INTVAL (operands[2]));
6185 (define_split
6186   [(set (match_operand:SI 0 "register_operand" "")
6187         (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
6188                         (match_operand:SI 2 "" ""))))
6189    (clobber (match_operand:SI 3 "register_operand" ""))]
6190   "GET_CODE (operands[2]) == CONST_INT
6191    && !SMALL_INT32 (operands[2])
6192    && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6193   [(set (match_dup 3) (match_dup 4))
6194    (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
6196   operands[4] = GEN_INT (~INTVAL (operands[2]));
6199 ;; xnor patterns.  Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
6200 ;; Combine now canonicalizes to the rightmost expression.
6201 (define_insn_and_split "*xor_not_di_sp32"
6202   [(set (match_operand:DI 0 "register_operand" "=r,b")
6203         (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r,b")
6204                         (match_operand:DI 2 "register_operand" "r,b"))))]
6205   "! TARGET_ARCH64"
6206   "@
6207    #
6208    fxnor\t%1, %2, %0"
6209   "&& reload_completed
6210    && ((GET_CODE (operands[0]) == REG
6211         && REGNO (operands[0]) < 32)
6212        || (GET_CODE (operands[0]) == SUBREG
6213            && GET_CODE (SUBREG_REG (operands[0])) == REG
6214            && REGNO (SUBREG_REG (operands[0])) < 32))"
6215   [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
6216    (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
6217   "operands[3] = gen_highpart (SImode, operands[0]);
6218    operands[4] = gen_highpart (SImode, operands[1]);
6219    operands[5] = gen_highpart (SImode, operands[2]);
6220    operands[6] = gen_lowpart (SImode, operands[0]);
6221    operands[7] = gen_lowpart (SImode, operands[1]);
6222    operands[8] = gen_lowpart (SImode, operands[2]);"
6223   [(set_attr "type" "*,fga")
6224    (set_attr "length" "2,*")
6225    (set_attr "fptype" "double")])
6227 (define_insn "*xor_not_di_sp64"
6228   [(set (match_operand:DI 0 "register_operand" "=r,b")
6229         (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,b")
6230                         (match_operand:DI 2 "arith_double_operand" "rHI,b"))))]
6231   "TARGET_ARCH64"
6232   "@
6233   xnor\t%r1, %2, %0
6234   fxnor\t%1, %2, %0"
6235   [(set_attr "type" "*,fga")
6236    (set_attr "fptype" "double")])
6238 (define_insn "*xor_not_si"
6239   [(set (match_operand:SI 0 "register_operand" "=r,d")
6240         (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,d")
6241                         (match_operand:SI 2 "arith_operand" "rI,d"))))]
6242   ""
6243   "@
6244    xnor\t%r1, %2, %0
6245    fxnors\t%1, %2, %0"
6246   [(set_attr "type" "*,fga")])
6248 ;; These correspond to the above in the case where we also (or only)
6249 ;; want to set the condition code.  
6251 (define_insn "*cmp_cc_arith_op"
6252   [(set (reg:CC 100)
6253         (compare:CC
6254          (match_operator:SI 2 "cc_arithop"
6255                             [(match_operand:SI 0 "arith_operand" "%r")
6256                              (match_operand:SI 1 "arith_operand" "rI")])
6257          (const_int 0)))]
6258   ""
6259   "%A2cc\t%0, %1, %%g0"
6260   [(set_attr "type" "compare")])
6262 (define_insn "*cmp_ccx_arith_op"
6263   [(set (reg:CCX 100)
6264         (compare:CCX
6265          (match_operator:DI 2 "cc_arithop"
6266                             [(match_operand:DI 0 "arith_double_operand" "%r")
6267                              (match_operand:DI 1 "arith_double_operand" "rHI")])
6268          (const_int 0)))]
6269   "TARGET_ARCH64"
6270   "%A2cc\t%0, %1, %%g0"
6271   [(set_attr "type" "compare")])
6273 (define_insn "*cmp_cc_arith_op_set"
6274   [(set (reg:CC 100)
6275         (compare:CC
6276          (match_operator:SI 3 "cc_arithop"
6277                             [(match_operand:SI 1 "arith_operand" "%r")
6278                              (match_operand:SI 2 "arith_operand" "rI")])
6279          (const_int 0)))
6280    (set (match_operand:SI 0 "register_operand" "=r")
6281         (match_operator:SI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6282   "GET_CODE (operands[3]) == GET_CODE (operands[4])"
6283   "%A3cc\t%1, %2, %0"
6284   [(set_attr "type" "compare")])
6286 (define_insn "*cmp_ccx_arith_op_set"
6287   [(set (reg:CCX 100)
6288         (compare:CCX
6289          (match_operator:DI 3 "cc_arithop"
6290                             [(match_operand:DI 1 "arith_double_operand" "%r")
6291                              (match_operand:DI 2 "arith_double_operand" "rHI")])
6292          (const_int 0)))
6293    (set (match_operand:DI 0 "register_operand" "=r")
6294         (match_operator:DI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6295   "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
6296   "%A3cc\t%1, %2, %0"
6297   [(set_attr "type" "compare")])
6299 (define_insn "*cmp_cc_xor_not"
6300   [(set (reg:CC 100)
6301         (compare:CC
6302          (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
6303                          (match_operand:SI 1 "arith_operand" "rI")))
6304          (const_int 0)))]
6305   ""
6306   "xnorcc\t%r0, %1, %%g0"
6307   [(set_attr "type" "compare")])
6309 (define_insn "*cmp_ccx_xor_not"
6310   [(set (reg:CCX 100)
6311         (compare:CCX
6312          (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ")
6313                          (match_operand:DI 1 "arith_double_operand" "rHI")))
6314          (const_int 0)))]
6315   "TARGET_ARCH64"
6316   "xnorcc\t%r0, %1, %%g0"
6317   [(set_attr "type" "compare")])
6319 (define_insn "*cmp_cc_xor_not_set"
6320   [(set (reg:CC 100)
6321         (compare:CC
6322          (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
6323                          (match_operand:SI 2 "arith_operand" "rI")))
6324          (const_int 0)))
6325    (set (match_operand:SI 0 "register_operand" "=r")
6326         (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
6327   ""
6328   "xnorcc\t%r1, %2, %0"
6329   [(set_attr "type" "compare")])
6331 (define_insn "*cmp_ccx_xor_not_set"
6332   [(set (reg:CCX 100)
6333         (compare:CCX
6334          (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
6335                          (match_operand:DI 2 "arith_double_operand" "rHI")))
6336          (const_int 0)))
6337    (set (match_operand:DI 0 "register_operand" "=r")
6338         (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
6339   "TARGET_ARCH64"
6340   "xnorcc\t%r1, %2, %0"
6341   [(set_attr "type" "compare")])
6343 (define_insn "*cmp_cc_arith_op_not"
6344   [(set (reg:CC 100)
6345         (compare:CC
6346          (match_operator:SI 2 "cc_arithopn"
6347                             [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
6348                              (match_operand:SI 1 "reg_or_0_operand" "rJ")])
6349          (const_int 0)))]
6350   ""
6351   "%B2cc\t%r1, %0, %%g0"
6352   [(set_attr "type" "compare")])
6354 (define_insn "*cmp_ccx_arith_op_not"
6355   [(set (reg:CCX 100)
6356         (compare:CCX
6357          (match_operator:DI 2 "cc_arithopn"
6358                             [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6359                              (match_operand:DI 1 "reg_or_0_operand" "rJ")])
6360          (const_int 0)))]
6361   "TARGET_ARCH64"
6362   "%B2cc\t%r1, %0, %%g0"
6363   [(set_attr "type" "compare")])
6365 (define_insn "*cmp_cc_arith_op_not_set"
6366   [(set (reg:CC 100)
6367         (compare:CC
6368          (match_operator:SI 3 "cc_arithopn"
6369                             [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
6370                              (match_operand:SI 2 "reg_or_0_operand" "rJ")])
6371          (const_int 0)))
6372    (set (match_operand:SI 0 "register_operand" "=r")
6373         (match_operator:SI 4 "cc_arithopn"
6374                             [(not:SI (match_dup 1)) (match_dup 2)]))]
6375   "GET_CODE (operands[3]) == GET_CODE (operands[4])"
6376   "%B3cc\t%r2, %1, %0"
6377   [(set_attr "type" "compare")])
6379 (define_insn "*cmp_ccx_arith_op_not_set"
6380   [(set (reg:CCX 100)
6381         (compare:CCX
6382          (match_operator:DI 3 "cc_arithopn"
6383                             [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6384                              (match_operand:DI 2 "reg_or_0_operand" "rJ")])
6385          (const_int 0)))
6386    (set (match_operand:DI 0 "register_operand" "=r")
6387         (match_operator:DI 4 "cc_arithopn"
6388                             [(not:DI (match_dup 1)) (match_dup 2)]))]
6389   "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
6390   "%B3cc\t%r2, %1, %0"
6391   [(set_attr "type" "compare")])
6393 ;; We cannot use the "neg" pseudo insn because the Sun assembler
6394 ;; does not know how to make it work for constants.
6396 (define_expand "negdi2"
6397   [(set (match_operand:DI 0 "register_operand" "=r")
6398         (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6399   ""
6401   if (! TARGET_ARCH64)
6402     {
6403       emit_insn (gen_rtx_PARALLEL
6404                  (VOIDmode,
6405                   gen_rtvec (2,
6406                              gen_rtx_SET (VOIDmode, operand0,
6407                                           gen_rtx_NEG (DImode, operand1)),
6408                              gen_rtx_CLOBBER (VOIDmode,
6409                                               gen_rtx_REG (CCmode,
6410                                                            SPARC_ICC_REG)))));
6411       DONE;
6412     }
6415 (define_insn_and_split "*negdi2_sp32"
6416   [(set (match_operand:DI 0 "register_operand" "=r")
6417         (neg:DI (match_operand:DI 1 "register_operand" "r")))
6418    (clobber (reg:CC 100))]
6419   "TARGET_ARCH32"
6420   "#"
6421   "&& reload_completed"
6422   [(parallel [(set (reg:CC_NOOV 100)
6423                    (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
6424                                     (const_int 0)))
6425               (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
6426    (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
6427                                 (ltu:SI (reg:CC 100) (const_int 0))))]
6428   "operands[2] = gen_highpart (SImode, operands[0]);
6429    operands[3] = gen_highpart (SImode, operands[1]);
6430    operands[4] = gen_lowpart (SImode, operands[0]);
6431    operands[5] = gen_lowpart (SImode, operands[1]);"
6432   [(set_attr "length" "2")])
6434 (define_insn "*negdi2_sp64"
6435   [(set (match_operand:DI 0 "register_operand" "=r")
6436         (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6437   "TARGET_ARCH64"
6438   "sub\t%%g0, %1, %0")
6440 (define_insn "negsi2"
6441   [(set (match_operand:SI 0 "register_operand" "=r")
6442         (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
6443   ""
6444   "sub\t%%g0, %1, %0")
6446 (define_insn "*cmp_cc_neg"
6447   [(set (reg:CC_NOOV 100)
6448         (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
6449                          (const_int 0)))]
6450   ""
6451   "subcc\t%%g0, %0, %%g0"
6452   [(set_attr "type" "compare")])
6454 (define_insn "*cmp_ccx_neg"
6455   [(set (reg:CCX_NOOV 100)
6456         (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6457                           (const_int 0)))]
6458   "TARGET_ARCH64"
6459   "subcc\t%%g0, %0, %%g0"
6460   [(set_attr "type" "compare")])
6462 (define_insn "*cmp_cc_set_neg"
6463   [(set (reg:CC_NOOV 100)
6464         (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
6465                          (const_int 0)))
6466    (set (match_operand:SI 0 "register_operand" "=r")
6467         (neg:SI (match_dup 1)))]
6468   ""
6469   "subcc\t%%g0, %1, %0"
6470   [(set_attr "type" "compare")])
6472 (define_insn "*cmp_ccx_set_neg"
6473   [(set (reg:CCX_NOOV 100)
6474         (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6475                           (const_int 0)))
6476    (set (match_operand:DI 0 "register_operand" "=r")
6477         (neg:DI (match_dup 1)))]
6478   "TARGET_ARCH64"
6479   "subcc\t%%g0, %1, %0"
6480   [(set_attr "type" "compare")])
6482 ;; We cannot use the "not" pseudo insn because the Sun assembler
6483 ;; does not know how to make it work for constants.
6484 (define_expand "one_cmpldi2"
6485   [(set (match_operand:DI 0 "register_operand" "")
6486         (not:DI (match_operand:DI 1 "register_operand" "")))]
6487   ""
6488   "")
6490 (define_insn_and_split "*one_cmpldi2_sp32"
6491   [(set (match_operand:DI 0 "register_operand" "=r,b")
6492         (not:DI (match_operand:DI 1 "register_operand" "r,b")))]
6493   "! TARGET_ARCH64"
6494   "@
6495    #
6496    fnot1\t%1, %0"
6497   "&& reload_completed
6498    && ((GET_CODE (operands[0]) == REG
6499         && REGNO (operands[0]) < 32)
6500        || (GET_CODE (operands[0]) == SUBREG
6501            && GET_CODE (SUBREG_REG (operands[0])) == REG
6502            && REGNO (SUBREG_REG (operands[0])) < 32))"
6503   [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
6504    (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
6505   "operands[2] = gen_highpart (SImode, operands[0]);
6506    operands[3] = gen_highpart (SImode, operands[1]);
6507    operands[4] = gen_lowpart (SImode, operands[0]);
6508    operands[5] = gen_lowpart (SImode, operands[1]);"
6509   [(set_attr "type" "*,fga")
6510    (set_attr "length" "2,*")
6511    (set_attr "fptype" "double")])
6513 (define_insn "*one_cmpldi2_sp64"
6514   [(set (match_operand:DI 0 "register_operand" "=r,b")
6515         (not:DI (match_operand:DI 1 "arith_double_operand" "rHI,b")))]
6516   "TARGET_ARCH64"
6517   "@
6518    xnor\t%%g0, %1, %0
6519    fnot1\t%1, %0"
6520   [(set_attr "type" "*,fga")
6521    (set_attr "fptype" "double")])
6523 (define_insn "one_cmplsi2"
6524   [(set (match_operand:SI 0 "register_operand" "=r,d")
6525         (not:SI (match_operand:SI 1 "arith_operand" "rI,d")))]
6526   ""
6527   "@
6528   xnor\t%%g0, %1, %0
6529   fnot1s\t%1, %0"
6530   [(set_attr "type" "*,fga")])
6532 (define_insn "*cmp_cc_not"
6533   [(set (reg:CC 100)
6534         (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
6535                     (const_int 0)))]
6536   ""
6537   "xnorcc\t%%g0, %0, %%g0"
6538   [(set_attr "type" "compare")])
6540 (define_insn "*cmp_ccx_not"
6541   [(set (reg:CCX 100)
6542         (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6543                      (const_int 0)))]
6544   "TARGET_ARCH64"
6545   "xnorcc\t%%g0, %0, %%g0"
6546   [(set_attr "type" "compare")])
6548 (define_insn "*cmp_cc_set_not"
6549   [(set (reg:CC 100)
6550         (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
6551                     (const_int 0)))
6552    (set (match_operand:SI 0 "register_operand" "=r")
6553         (not:SI (match_dup 1)))]
6554   ""
6555   "xnorcc\t%%g0, %1, %0"
6556   [(set_attr "type" "compare")])
6558 (define_insn "*cmp_ccx_set_not"
6559   [(set (reg:CCX 100)
6560         (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6561                     (const_int 0)))
6562    (set (match_operand:DI 0 "register_operand" "=r")
6563         (not:DI (match_dup 1)))]
6564   "TARGET_ARCH64"
6565   "xnorcc\t%%g0, %1, %0"
6566   [(set_attr "type" "compare")])
6568 (define_insn "*cmp_cc_set"
6569   [(set (match_operand:SI 0 "register_operand" "=r")
6570         (match_operand:SI 1 "register_operand" "r"))
6571    (set (reg:CC 100)
6572         (compare:CC (match_dup 1)
6573                     (const_int 0)))]
6574   ""
6575   "orcc\t%1, 0, %0"
6576   [(set_attr "type" "compare")])
6578 (define_insn "*cmp_ccx_set64"
6579   [(set (match_operand:DI 0 "register_operand" "=r")
6580         (match_operand:DI 1 "register_operand" "r"))
6581    (set (reg:CCX 100)
6582         (compare:CCX (match_dup 1)
6583                      (const_int 0)))]
6584   "TARGET_ARCH64"
6585   "orcc\t%1, 0, %0"
6586    [(set_attr "type" "compare")])
6588 ;; Floating point arithmetic instructions.
6590 (define_expand "addtf3"
6591   [(set (match_operand:TF 0 "nonimmediate_operand" "")
6592         (plus:TF (match_operand:TF 1 "general_operand" "")
6593                  (match_operand:TF 2 "general_operand" "")))]
6594   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6595   "emit_tfmode_binop (PLUS, operands); DONE;")
6597 (define_insn "*addtf3_hq"
6598   [(set (match_operand:TF 0 "register_operand" "=e")
6599         (plus:TF (match_operand:TF 1 "register_operand" "e")
6600                  (match_operand:TF 2 "register_operand" "e")))]
6601   "TARGET_FPU && TARGET_HARD_QUAD"
6602   "faddq\t%1, %2, %0"
6603   [(set_attr "type" "fp")])
6605 (define_insn "adddf3"
6606   [(set (match_operand:DF 0 "register_operand" "=e")
6607         (plus:DF (match_operand:DF 1 "register_operand" "e")
6608                  (match_operand:DF 2 "register_operand" "e")))]
6609   "TARGET_FPU"
6610   "faddd\t%1, %2, %0"
6611   [(set_attr "type" "fp")
6612    (set_attr "fptype" "double")])
6614 (define_insn "addsf3"
6615   [(set (match_operand:SF 0 "register_operand" "=f")
6616         (plus:SF (match_operand:SF 1 "register_operand" "f")
6617                  (match_operand:SF 2 "register_operand" "f")))]
6618   "TARGET_FPU"
6619   "fadds\t%1, %2, %0"
6620   [(set_attr "type" "fp")])
6622 (define_expand "subtf3"
6623   [(set (match_operand:TF 0 "nonimmediate_operand" "")
6624         (minus:TF (match_operand:TF 1 "general_operand" "")
6625                   (match_operand:TF 2 "general_operand" "")))]
6626   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6627   "emit_tfmode_binop (MINUS, operands); DONE;")
6629 (define_insn "*subtf3_hq"
6630   [(set (match_operand:TF 0 "register_operand" "=e")
6631         (minus:TF (match_operand:TF 1 "register_operand" "e")
6632                   (match_operand:TF 2 "register_operand" "e")))]
6633   "TARGET_FPU && TARGET_HARD_QUAD"
6634   "fsubq\t%1, %2, %0"
6635   [(set_attr "type" "fp")])
6637 (define_insn "subdf3"
6638   [(set (match_operand:DF 0 "register_operand" "=e")
6639         (minus:DF (match_operand:DF 1 "register_operand" "e")
6640                   (match_operand:DF 2 "register_operand" "e")))]
6641   "TARGET_FPU"
6642   "fsubd\t%1, %2, %0"
6643   [(set_attr "type" "fp")
6644    (set_attr "fptype" "double")])
6646 (define_insn "subsf3"
6647   [(set (match_operand:SF 0 "register_operand" "=f")
6648         (minus:SF (match_operand:SF 1 "register_operand" "f")
6649                   (match_operand:SF 2 "register_operand" "f")))]
6650   "TARGET_FPU"
6651   "fsubs\t%1, %2, %0"
6652   [(set_attr "type" "fp")])
6654 (define_expand "multf3"
6655   [(set (match_operand:TF 0 "nonimmediate_operand" "")
6656         (mult:TF (match_operand:TF 1 "general_operand" "")
6657                  (match_operand:TF 2 "general_operand" "")))]
6658   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6659   "emit_tfmode_binop (MULT, operands); DONE;")
6661 (define_insn "*multf3_hq"
6662   [(set (match_operand:TF 0 "register_operand" "=e")
6663         (mult:TF (match_operand:TF 1 "register_operand" "e")
6664                  (match_operand:TF 2 "register_operand" "e")))]
6665   "TARGET_FPU && TARGET_HARD_QUAD"
6666   "fmulq\t%1, %2, %0"
6667   [(set_attr "type" "fpmul")])
6669 (define_insn "muldf3"
6670   [(set (match_operand:DF 0 "register_operand" "=e")
6671         (mult:DF (match_operand:DF 1 "register_operand" "e")
6672                  (match_operand:DF 2 "register_operand" "e")))]
6673   "TARGET_FPU"
6674   "fmuld\t%1, %2, %0"
6675   [(set_attr "type" "fpmul")
6676    (set_attr "fptype" "double")])
6678 (define_insn "mulsf3"
6679   [(set (match_operand:SF 0 "register_operand" "=f")
6680         (mult:SF (match_operand:SF 1 "register_operand" "f")
6681                  (match_operand:SF 2 "register_operand" "f")))]
6682   "TARGET_FPU"
6683   "fmuls\t%1, %2, %0"
6684   [(set_attr "type" "fpmul")])
6686 (define_insn "*muldf3_extend"
6687   [(set (match_operand:DF 0 "register_operand" "=e")
6688         (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
6689                  (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
6690   "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
6691   "fsmuld\t%1, %2, %0"
6692   [(set_attr "type" "fpmul")
6693    (set_attr "fptype" "double")])
6695 (define_insn "*multf3_extend"
6696   [(set (match_operand:TF 0 "register_operand" "=e")
6697         (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
6698                  (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
6699   "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
6700   "fdmulq\t%1, %2, %0"
6701   [(set_attr "type" "fpmul")])
6703 (define_expand "divtf3"
6704   [(set (match_operand:TF 0 "nonimmediate_operand" "")
6705         (div:TF (match_operand:TF 1 "general_operand" "")
6706                 (match_operand:TF 2 "general_operand" "")))]
6707   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6708   "emit_tfmode_binop (DIV, operands); DONE;")
6710 ;; don't have timing for quad-prec. divide.
6711 (define_insn "*divtf3_hq"
6712   [(set (match_operand:TF 0 "register_operand" "=e")
6713         (div:TF (match_operand:TF 1 "register_operand" "e")
6714                 (match_operand:TF 2 "register_operand" "e")))]
6715   "TARGET_FPU && TARGET_HARD_QUAD"
6716   "fdivq\t%1, %2, %0"
6717   [(set_attr "type" "fpdivd")])
6719 (define_insn "divdf3"
6720   [(set (match_operand:DF 0 "register_operand" "=e")
6721         (div:DF (match_operand:DF 1 "register_operand" "e")
6722                 (match_operand:DF 2 "register_operand" "e")))]
6723   "TARGET_FPU"
6724   "fdivd\t%1, %2, %0"
6725   [(set_attr "type" "fpdivd")
6726    (set_attr "fptype" "double")])
6728 (define_insn "divsf3"
6729   [(set (match_operand:SF 0 "register_operand" "=f")
6730         (div:SF (match_operand:SF 1 "register_operand" "f")
6731                 (match_operand:SF 2 "register_operand" "f")))]
6732   "TARGET_FPU"
6733   "fdivs\t%1, %2, %0"
6734   [(set_attr "type" "fpdivs")])
6736 (define_expand "negtf2"
6737   [(set (match_operand:TF 0 "register_operand" "=e,e")
6738         (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6739   "TARGET_FPU"
6740   "")
6742 (define_insn_and_split "*negtf2_notv9"
6743   [(set (match_operand:TF 0 "register_operand" "=e,e")
6744         (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6745   ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6746   "TARGET_FPU
6747    && ! TARGET_V9"
6748   "@
6749   fnegs\t%0, %0
6750   #"
6751   "&& reload_completed
6752    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6753   [(set (match_dup 2) (neg:SF (match_dup 3)))
6754    (set (match_dup 4) (match_dup 5))
6755    (set (match_dup 6) (match_dup 7))]
6756   "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6757    operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6758    operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6759    operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6760    operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6761    operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6762   [(set_attr "type" "fpmove,*")
6763    (set_attr "length" "*,2")])
6765 (define_insn_and_split "*negtf2_v9"
6766   [(set (match_operand:TF 0 "register_operand" "=e,e")
6767         (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6768   ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6769   "TARGET_FPU && TARGET_V9"
6770   "@
6771   fnegd\t%0, %0
6772   #"
6773   "&& reload_completed
6774    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6775   [(set (match_dup 2) (neg:DF (match_dup 3)))
6776    (set (match_dup 4) (match_dup 5))]
6777   "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6778    operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6779    operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6780    operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6781   [(set_attr "type" "fpmove,*")
6782    (set_attr "length" "*,2")
6783    (set_attr "fptype" "double")])
6785 (define_expand "negdf2"
6786   [(set (match_operand:DF 0 "register_operand" "")
6787         (neg:DF (match_operand:DF 1 "register_operand" "")))]
6788   "TARGET_FPU"
6789   "")
6791 (define_insn_and_split "*negdf2_notv9"
6792   [(set (match_operand:DF 0 "register_operand" "=e,e")
6793         (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
6794   "TARGET_FPU && ! TARGET_V9"
6795   "@
6796   fnegs\t%0, %0
6797   #"
6798   "&& reload_completed
6799    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6800   [(set (match_dup 2) (neg:SF (match_dup 3)))
6801    (set (match_dup 4) (match_dup 5))]
6802   "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6803    operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6804    operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6805    operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6806   [(set_attr "type" "fpmove,*")
6807    (set_attr "length" "*,2")])
6809 (define_insn "*negdf2_v9"
6810   [(set (match_operand:DF 0 "register_operand" "=e")
6811         (neg:DF (match_operand:DF 1 "register_operand" "e")))]
6812   "TARGET_FPU && TARGET_V9"
6813   "fnegd\t%1, %0"
6814   [(set_attr "type" "fpmove")
6815    (set_attr "fptype" "double")])
6817 (define_insn "negsf2"
6818   [(set (match_operand:SF 0 "register_operand" "=f")
6819         (neg:SF (match_operand:SF 1 "register_operand" "f")))]
6820   "TARGET_FPU"
6821   "fnegs\t%1, %0"
6822   [(set_attr "type" "fpmove")])
6824 (define_expand "abstf2"
6825   [(set (match_operand:TF 0 "register_operand" "")
6826         (abs:TF (match_operand:TF 1 "register_operand" "")))]
6827   "TARGET_FPU"
6828   "")
6830 (define_insn_and_split "*abstf2_notv9"
6831   [(set (match_operand:TF 0 "register_operand" "=e,e")
6832         (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6833   ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6834   "TARGET_FPU && ! TARGET_V9"
6835   "@
6836   fabss\t%0, %0
6837   #"
6838   "&& reload_completed
6839    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6840   [(set (match_dup 2) (abs:SF (match_dup 3)))
6841    (set (match_dup 4) (match_dup 5))
6842    (set (match_dup 6) (match_dup 7))]
6843   "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6844    operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6845    operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6846    operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6847    operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6848    operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6849   [(set_attr "type" "fpmove,*")
6850    (set_attr "length" "*,2")])
6852 (define_insn "*abstf2_hq_v9"
6853   [(set (match_operand:TF 0 "register_operand" "=e,e")
6854         (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6855   "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
6856   "@
6857   fabsd\t%0, %0
6858   fabsq\t%1, %0"
6859   [(set_attr "type" "fpmove")
6860    (set_attr "fptype" "double,*")])
6862 (define_insn_and_split "*abstf2_v9"
6863   [(set (match_operand:TF 0 "register_operand" "=e,e")
6864         (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6865   "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
6866   "@
6867   fabsd\t%0, %0
6868   #"
6869   "&& reload_completed
6870    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6871   [(set (match_dup 2) (abs:DF (match_dup 3)))
6872    (set (match_dup 4) (match_dup 5))]
6873   "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6874    operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6875    operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6876    operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6877   [(set_attr "type" "fpmove,*")
6878    (set_attr "length" "*,2")
6879    (set_attr "fptype" "double,*")])
6881 (define_expand "absdf2"
6882   [(set (match_operand:DF 0 "register_operand" "")
6883         (abs:DF (match_operand:DF 1 "register_operand" "")))]
6884   "TARGET_FPU"
6885   "")
6887 (define_insn_and_split "*absdf2_notv9"
6888   [(set (match_operand:DF 0 "register_operand" "=e,e")
6889         (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
6890   "TARGET_FPU && ! TARGET_V9"
6891   "@
6892   fabss\t%0, %0
6893   #"
6894   "&& reload_completed
6895    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6896   [(set (match_dup 2) (abs:SF (match_dup 3)))
6897    (set (match_dup 4) (match_dup 5))]
6898   "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6899    operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6900    operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6901    operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6902   [(set_attr "type" "fpmove,*")
6903    (set_attr "length" "*,2")])
6905 (define_insn "*absdf2_v9"
6906   [(set (match_operand:DF 0 "register_operand" "=e")
6907         (abs:DF (match_operand:DF 1 "register_operand" "e")))]
6908   "TARGET_FPU && TARGET_V9"
6909   "fabsd\t%1, %0"
6910   [(set_attr "type" "fpmove")
6911    (set_attr "fptype" "double")])
6913 (define_insn "abssf2"
6914   [(set (match_operand:SF 0 "register_operand" "=f")
6915         (abs:SF (match_operand:SF 1 "register_operand" "f")))]
6916   "TARGET_FPU"
6917   "fabss\t%1, %0"
6918   [(set_attr "type" "fpmove")])
6920 (define_expand "sqrttf2"
6921   [(set (match_operand:TF 0 "nonimmediate_operand" "")
6922         (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
6923   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6924   "emit_tfmode_unop (SQRT, operands); DONE;")
6926 (define_insn "*sqrttf2_hq"
6927   [(set (match_operand:TF 0 "register_operand" "=e")
6928         (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
6929   "TARGET_FPU && TARGET_HARD_QUAD"
6930   "fsqrtq\t%1, %0"
6931   [(set_attr "type" "fpsqrtd")])
6933 (define_insn "sqrtdf2"
6934   [(set (match_operand:DF 0 "register_operand" "=e")
6935         (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
6936   "TARGET_FPU"
6937   "fsqrtd\t%1, %0"
6938   [(set_attr "type" "fpsqrtd")
6939    (set_attr "fptype" "double")])
6941 (define_insn "sqrtsf2"
6942   [(set (match_operand:SF 0 "register_operand" "=f")
6943         (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
6944   "TARGET_FPU"
6945   "fsqrts\t%1, %0"
6946   [(set_attr "type" "fpsqrts")])
6948 ;;- arithmetic shift instructions
6950 (define_insn "ashlsi3"
6951   [(set (match_operand:SI 0 "register_operand" "=r")
6952         (ashift:SI (match_operand:SI 1 "register_operand" "r")
6953                    (match_operand:SI 2 "arith_operand" "rI")))]
6954   ""
6956   if (GET_CODE (operands[2]) == CONST_INT)
6957     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6958   return "sll\t%1, %2, %0";
6960   [(set (attr "type")
6961         (if_then_else (match_operand 2 "const1_operand" "")
6962                       (const_string "ialu") (const_string "shift")))])
6964 (define_expand "ashldi3"
6965   [(set (match_operand:DI 0 "register_operand" "=r")
6966         (ashift:DI (match_operand:DI 1 "register_operand" "r")
6967                    (match_operand:SI 2 "arith_operand" "rI")))]
6968   "TARGET_ARCH64 || TARGET_V8PLUS"
6970   if (! TARGET_ARCH64)
6971     {
6972       if (GET_CODE (operands[2]) == CONST_INT)
6973         FAIL;
6974       emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
6975       DONE;
6976     }
6979 (define_insn "*ashldi3_sp64"
6980   [(set (match_operand:DI 0 "register_operand" "=r")
6981         (ashift:DI (match_operand:DI 1 "register_operand" "r")
6982                    (match_operand:SI 2 "arith_operand" "rI")))]
6983   "TARGET_ARCH64"
6985   if (GET_CODE (operands[2]) == CONST_INT)
6986     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6987   return "sllx\t%1, %2, %0";
6989   [(set (attr "type")
6990         (if_then_else (match_operand 2 "const1_operand" "")
6991                       (const_string "ialu") (const_string "shift")))])
6993 ;; XXX UGH!
6994 (define_insn "ashldi3_v8plus"
6995   [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6996         (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6997                    (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6998    (clobber (match_scratch:SI 3 "=X,X,&h"))]
6999   "TARGET_V8PLUS"
7000   "* return output_v8plus_shift (operands, insn, \"sllx\");"
7001   [(set_attr "type" "multi")
7002    (set_attr "length" "5,5,6")])
7004 ;; Optimize (1LL<<x)-1
7005 ;; XXX this also needs to be fixed to handle equal subregs
7006 ;; XXX first before we could re-enable it.
7007 ;(define_insn ""
7008 ;  [(set (match_operand:DI 0 "register_operand" "=h")
7009 ;       (plus:DI (ashift:DI (const_int 1)
7010 ;                           (match_operand:SI 1 "arith_operand" "rI"))
7011 ;                (const_int -1)))]
7012 ;  "0 && TARGET_V8PLUS"
7014 ;  if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
7015 ;    return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
7016 ;  return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
7018 ;  [(set_attr "type" "multi")
7019 ;   (set_attr "length" "4")])
7021 (define_insn "*cmp_cc_ashift_1"
7022   [(set (reg:CC_NOOV 100)
7023         (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
7024                                     (const_int 1))
7025                          (const_int 0)))]
7026   ""
7027   "addcc\t%0, %0, %%g0"
7028   [(set_attr "type" "compare")])
7030 (define_insn "*cmp_cc_set_ashift_1"
7031   [(set (reg:CC_NOOV 100)
7032         (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
7033                                     (const_int 1))
7034                          (const_int 0)))
7035    (set (match_operand:SI 0 "register_operand" "=r")
7036         (ashift:SI (match_dup 1) (const_int 1)))]
7037   ""
7038   "addcc\t%1, %1, %0"
7039   [(set_attr "type" "compare")])
7041 (define_insn "ashrsi3"
7042   [(set (match_operand:SI 0 "register_operand" "=r")
7043         (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7044                      (match_operand:SI 2 "arith_operand" "rI")))]
7045   ""
7046   {
7047      if (GET_CODE (operands[2]) == CONST_INT)
7048        operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7049      return "sra\t%1, %2, %0";
7050   }
7051   [(set_attr "type" "shift")])
7053 (define_insn "*ashrsi3_extend"
7054   [(set (match_operand:DI 0 "register_operand" "=r")
7055         (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7056                                      (match_operand:SI 2 "arith_operand" "r"))))]
7057   "TARGET_ARCH64"
7058   "sra\t%1, %2, %0"
7059   [(set_attr "type" "shift")])
7061 ;; This handles the case as above, but with constant shift instead of
7062 ;; register. Combiner "simplifies" it for us a little bit though.
7063 (define_insn "*ashrsi3_extend2"
7064   [(set (match_operand:DI 0 "register_operand" "=r")
7065         (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7066                                 (const_int 32))
7067                      (match_operand:SI 2 "small_int_or_double" "n")))]
7068   "TARGET_ARCH64
7069    && ((GET_CODE (operands[2]) == CONST_INT
7070         && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64)
7071        || (GET_CODE (operands[2]) == CONST_DOUBLE
7072            && !CONST_DOUBLE_HIGH (operands[2])
7073            && CONST_DOUBLE_LOW (operands[2]) >= 32
7074            && CONST_DOUBLE_LOW (operands[2]) < 64))"
7076   operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
7078   return "sra\t%1, %2, %0";
7080   [(set_attr "type" "shift")])
7082 (define_expand "ashrdi3"
7083   [(set (match_operand:DI 0 "register_operand" "=r")
7084         (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7085                      (match_operand:SI 2 "arith_operand" "rI")))]
7086   "TARGET_ARCH64 || TARGET_V8PLUS"
7088   if (! TARGET_ARCH64)
7089     {
7090       if (GET_CODE (operands[2]) == CONST_INT)
7091         FAIL;   /* prefer generic code in this case */
7092       emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
7093       DONE;
7094     }
7097 (define_insn "*ashrdi3_sp64"
7098   [(set (match_operand:DI 0 "register_operand" "=r")
7099         (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7100                      (match_operand:SI 2 "arith_operand" "rI")))]
7101   "TARGET_ARCH64"
7102   
7103   {
7104     if (GET_CODE (operands[2]) == CONST_INT)
7105       operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7106     return "srax\t%1, %2, %0";
7107   }
7108   [(set_attr "type" "shift")])
7110 ;; XXX
7111 (define_insn "ashrdi3_v8plus"
7112   [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7113         (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7114                      (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7115    (clobber (match_scratch:SI 3 "=X,X,&h"))]
7116   "TARGET_V8PLUS"
7117   "* return output_v8plus_shift (operands, insn, \"srax\");"
7118   [(set_attr "type" "multi")
7119    (set_attr "length" "5,5,6")])
7121 (define_insn "lshrsi3"
7122   [(set (match_operand:SI 0 "register_operand" "=r")
7123         (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
7124                      (match_operand:SI 2 "arith_operand" "rI")))]
7125   ""
7126   {
7127     if (GET_CODE (operands[2]) == CONST_INT)
7128       operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7129     return "srl\t%1, %2, %0";
7130   }
7131   [(set_attr "type" "shift")])
7133 ;; This handles the case where
7134 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
7135 ;; but combiner "simplifies" it for us.
7136 (define_insn "*lshrsi3_extend"
7137   [(set (match_operand:DI 0 "register_operand" "=r")
7138         (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
7139                            (match_operand:SI 2 "arith_operand" "r")) 0)
7140                 (match_operand 3 "" "")))]
7141   "TARGET_ARCH64
7142    && ((GET_CODE (operands[3]) == CONST_DOUBLE
7143            && CONST_DOUBLE_HIGH (operands[3]) == 0
7144            && CONST_DOUBLE_LOW (operands[3]) == 0xffffffff)
7145        || (HOST_BITS_PER_WIDE_INT >= 64
7146            && GET_CODE (operands[3]) == CONST_INT
7147            && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff))"
7148   "srl\t%1, %2, %0"
7149   [(set_attr "type" "shift")])
7151 ;; This handles the case where
7152 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
7153 ;; but combiner "simplifies" it for us.
7154 (define_insn "*lshrsi3_extend2"
7155   [(set (match_operand:DI 0 "register_operand" "=r")
7156         (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7157                          (match_operand 2 "small_int_or_double" "n")
7158                          (const_int 32)))]
7159   "TARGET_ARCH64
7160    && ((GET_CODE (operands[2]) == CONST_INT
7161         && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7162        || (GET_CODE (operands[2]) == CONST_DOUBLE
7163            && CONST_DOUBLE_HIGH (operands[2]) == 0
7164            && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7166   operands[2] = GEN_INT (32 - INTVAL (operands[2]));
7168   return "srl\t%1, %2, %0";
7170   [(set_attr "type" "shift")])
7172 (define_expand "lshrdi3"
7173   [(set (match_operand:DI 0 "register_operand" "=r")
7174         (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7175                      (match_operand:SI 2 "arith_operand" "rI")))]
7176   "TARGET_ARCH64 || TARGET_V8PLUS"
7178   if (! TARGET_ARCH64)
7179     {
7180       if (GET_CODE (operands[2]) == CONST_INT)
7181         FAIL;
7182       emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
7183       DONE;
7184     }
7187 (define_insn "*lshrdi3_sp64"
7188   [(set (match_operand:DI 0 "register_operand" "=r")
7189         (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7190                      (match_operand:SI 2 "arith_operand" "rI")))]
7191   "TARGET_ARCH64"
7192   {
7193     if (GET_CODE (operands[2]) == CONST_INT)
7194       operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7195     return "srlx\t%1, %2, %0";
7196   }
7197   [(set_attr "type" "shift")])
7199 ;; XXX
7200 (define_insn "lshrdi3_v8plus"
7201   [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7202         (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7203                      (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7204    (clobber (match_scratch:SI 3 "=X,X,&h"))]
7205   "TARGET_V8PLUS"
7206   "* return output_v8plus_shift (operands, insn, \"srlx\");"
7207   [(set_attr "type" "multi")
7208    (set_attr "length" "5,5,6")])
7210 (define_insn ""
7211   [(set (match_operand:SI 0 "register_operand" "=r")
7212         (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7213                                              (const_int 32)) 4)
7214                      (match_operand:SI 2 "small_int_or_double" "n")))]
7215   "TARGET_ARCH64
7216    && ((GET_CODE (operands[2]) == CONST_INT
7217         && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7218        || (GET_CODE (operands[2]) == CONST_DOUBLE
7219            && !CONST_DOUBLE_HIGH (operands[2])
7220            && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7222   operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
7224   return "srax\t%1, %2, %0";
7226   [(set_attr "type" "shift")])
7228 (define_insn ""
7229   [(set (match_operand:SI 0 "register_operand" "=r")
7230         (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7231                                              (const_int 32)) 4)
7232                      (match_operand:SI 2 "small_int_or_double" "n")))]
7233   "TARGET_ARCH64
7234    && ((GET_CODE (operands[2]) == CONST_INT
7235         && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7236        || (GET_CODE (operands[2]) == CONST_DOUBLE
7237            && !CONST_DOUBLE_HIGH (operands[2])
7238            && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7240   operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
7242   return "srlx\t%1, %2, %0";
7244   [(set_attr "type" "shift")])
7246 (define_insn ""
7247   [(set (match_operand:SI 0 "register_operand" "=r")
7248         (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7249                                              (match_operand:SI 2 "small_int_or_double" "n")) 4)
7250                      (match_operand:SI 3 "small_int_or_double" "n")))]
7251   "TARGET_ARCH64
7252    && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
7253    && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
7254    && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
7255    && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
7257   operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
7259   return "srax\t%1, %2, %0";
7261   [(set_attr "type" "shift")])
7263 (define_insn ""
7264   [(set (match_operand:SI 0 "register_operand" "=r")
7265         (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7266                                              (match_operand:SI 2 "small_int_or_double" "n")) 4)
7267                      (match_operand:SI 3 "small_int_or_double" "n")))]
7268   "TARGET_ARCH64
7269    && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
7270    && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
7271    && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
7272    && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
7274   operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
7276   return "srlx\t%1, %2, %0";
7278   [(set_attr "type" "shift")])
7280 ;; Unconditional and other jump instructions
7281 (define_insn "jump"
7282   [(set (pc) (label_ref (match_operand 0 "" "")))]
7283   ""
7284   "* return output_ubranch (operands[0], 0, insn);"
7285   [(set_attr "type" "uncond_branch")])
7287 (define_expand "tablejump"
7288   [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
7289               (use (label_ref (match_operand 1 "" "")))])]
7290   ""
7292   if (GET_MODE (operands[0]) != CASE_VECTOR_MODE)
7293     abort ();
7295   /* In pic mode, our address differences are against the base of the
7296      table.  Add that base value back in; CSE ought to be able to combine
7297      the two address loads.  */
7298   if (flag_pic)
7299     {
7300       rtx tmp, tmp2;
7301       tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
7302       tmp2 = operands[0];
7303       if (CASE_VECTOR_MODE != Pmode)
7304         tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
7305       tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
7306       operands[0] = memory_address (Pmode, tmp);
7307     }
7310 (define_insn "*tablejump_sp32"
7311   [(set (pc) (match_operand:SI 0 "address_operand" "p"))
7312    (use (label_ref (match_operand 1 "" "")))]
7313   "! TARGET_ARCH64"
7314   "jmp\t%a0%#"
7315   [(set_attr "type" "uncond_branch")])
7317 (define_insn "*tablejump_sp64"
7318   [(set (pc) (match_operand:DI 0 "address_operand" "p"))
7319    (use (label_ref (match_operand 1 "" "")))]
7320   "TARGET_ARCH64"
7321   "jmp\t%a0%#"
7322   [(set_attr "type" "uncond_branch")])
7324 ;;- jump to subroutine
7325 (define_expand "call"
7326   ;; Note that this expression is not used for generating RTL.
7327   ;; All the RTL is generated explicitly below.
7328   [(call (match_operand 0 "call_operand" "")
7329          (match_operand 3 "" "i"))]
7330   ;; operands[2] is next_arg_register
7331   ;; operands[3] is struct_value_size_rtx.
7332   ""
7334   rtx fn_rtx;
7336   if (GET_MODE (operands[0]) != FUNCTION_MODE)
7337     abort ();
7339   if (GET_CODE (operands[3]) != CONST_INT)
7340     abort();
7342   if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
7343     {
7344       /* This is really a PIC sequence.  We want to represent
7345          it as a funny jump so its delay slots can be filled. 
7347          ??? But if this really *is* a CALL, will not it clobber the
7348          call-clobbered registers?  We lose this if it is a JUMP_INSN.
7349          Why cannot we have delay slots filled if it were a CALL?  */
7351       /* We accept negative sizes for untyped calls.  */
7352       if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7353         emit_jump_insn
7354           (gen_rtx_PARALLEL
7355            (VOIDmode,
7356             gen_rtvec (3,
7357                        gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
7358                        operands[3],
7359                        gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7360       else
7361         emit_jump_insn
7362           (gen_rtx_PARALLEL
7363            (VOIDmode,
7364             gen_rtvec (2,
7365                        gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
7366                        gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7367       goto finish_call;
7368     }
7370   fn_rtx = operands[0];
7372   /* We accept negative sizes for untyped calls.  */
7373   if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7374     emit_call_insn
7375       (gen_rtx_PARALLEL
7376        (VOIDmode,
7377         gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
7378                    operands[3],
7379                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7380   else
7381     emit_call_insn
7382       (gen_rtx_PARALLEL
7383        (VOIDmode,
7384         gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
7385                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7387  finish_call:
7389   DONE;
7392 ;; We can't use the same pattern for these two insns, because then registers
7393 ;; in the address may not be properly reloaded.
7395 (define_insn "*call_address_sp32"
7396   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7397          (match_operand 1 "" ""))
7398    (clobber (reg:SI 15))]
7399   ;;- Do not use operand 1 for most machines.
7400   "! TARGET_ARCH64"
7401   "call\t%a0, %1%#"
7402   [(set_attr "type" "call")])
7404 (define_insn "*call_symbolic_sp32"
7405   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7406          (match_operand 1 "" ""))
7407    (clobber (reg:SI 15))]
7408   ;;- Do not use operand 1 for most machines.
7409   "! TARGET_ARCH64"
7410   "call\t%a0, %1%#"
7411   [(set_attr "type" "call")])
7413 (define_insn "*call_address_sp64"
7414   [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
7415          (match_operand 1 "" ""))
7416    (clobber (reg:DI 15))]
7417   ;;- Do not use operand 1 for most machines.
7418   "TARGET_ARCH64"
7419   "call\t%a0, %1%#"
7420   [(set_attr "type" "call")])
7422 (define_insn "*call_symbolic_sp64"
7423   [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
7424          (match_operand 1 "" ""))
7425    (clobber (reg:DI 15))]
7426   ;;- Do not use operand 1 for most machines.
7427   "TARGET_ARCH64"
7428   "call\t%a0, %1%#"
7429   [(set_attr "type" "call")])
7431 ;; This is a call that wants a structure value.
7432 ;; There is no such critter for v9 (??? we may need one anyway).
7433 (define_insn "*call_address_struct_value_sp32"
7434   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7435          (match_operand 1 "" ""))
7436    (match_operand 2 "immediate_operand" "")
7437    (clobber (reg:SI 15))]
7438   ;;- Do not use operand 1 for most machines.
7439   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
7440   "call\t%a0, %1\n\t nop\n\tunimp\t%2"
7441   [(set_attr "type" "call_no_delay_slot")
7442    (set_attr "length" "3")])
7444 ;; This is a call that wants a structure value.
7445 ;; There is no such critter for v9 (??? we may need one anyway).
7446 (define_insn "*call_symbolic_struct_value_sp32"
7447   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7448          (match_operand 1 "" ""))
7449    (match_operand 2 "immediate_operand" "")
7450    (clobber (reg:SI 15))]
7451   ;;- Do not use operand 1 for most machines.
7452   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
7453   "call\t%a0, %1\n\t nop\n\tunimp\t%2"
7454   [(set_attr "type" "call_no_delay_slot")
7455    (set_attr "length" "3")])
7457 ;; This is a call that may want a structure value.  This is used for
7458 ;; untyped_calls.
7459 (define_insn "*call_address_untyped_struct_value_sp32"
7460   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7461          (match_operand 1 "" ""))
7462    (match_operand 2 "immediate_operand" "")
7463    (clobber (reg:SI 15))]
7464   ;;- Do not use operand 1 for most machines.
7465   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7466   "call\t%a0, %1\n\t nop\n\tnop"
7467   [(set_attr "type" "call_no_delay_slot")
7468    (set_attr "length" "3")])
7470 ;; This is a call that may want a structure value.  This is used for
7471 ;; untyped_calls.
7472 (define_insn "*call_symbolic_untyped_struct_value_sp32"
7473   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7474          (match_operand 1 "" ""))
7475    (match_operand 2 "immediate_operand" "")
7476    (clobber (reg:SI 15))]
7477   ;;- Do not use operand 1 for most machines.
7478   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7479   "call\t%a0, %1\n\t nop\n\tnop"
7480   [(set_attr "type" "call_no_delay_slot")
7481    (set_attr "length" "3")])
7483 (define_expand "call_value"
7484   ;; Note that this expression is not used for generating RTL.
7485   ;; All the RTL is generated explicitly below.
7486   [(set (match_operand 0 "register_operand" "=rf")
7487         (call (match_operand 1 "" "")
7488               (match_operand 4 "" "")))]
7489   ;; operand 2 is stack_size_rtx
7490   ;; operand 3 is next_arg_register
7491   ""
7493   rtx fn_rtx;
7494   rtvec vec;
7496   if (GET_MODE (operands[1]) != FUNCTION_MODE)
7497     abort ();
7499   fn_rtx = operands[1];
7501   vec = gen_rtvec (2,
7502                    gen_rtx_SET (VOIDmode, operands[0],
7503                                 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
7504                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
7506   emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
7508   DONE;
7511 (define_insn "*call_value_address_sp32"
7512   [(set (match_operand 0 "" "=rf")
7513         (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
7514               (match_operand 2 "" "")))
7515    (clobber (reg:SI 15))]
7516   ;;- Do not use operand 2 for most machines.
7517   "! TARGET_ARCH64"
7518   "call\t%a1, %2%#"
7519   [(set_attr "type" "call")])
7521 (define_insn "*call_value_symbolic_sp32"
7522   [(set (match_operand 0 "" "=rf")
7523         (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7524               (match_operand 2 "" "")))
7525    (clobber (reg:SI 15))]
7526   ;;- Do not use operand 2 for most machines.
7527   "! TARGET_ARCH64"
7528   "call\t%a1, %2%#"
7529   [(set_attr "type" "call")])
7531 (define_insn "*call_value_address_sp64"
7532   [(set (match_operand 0 "" "")
7533         (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
7534               (match_operand 2 "" "")))
7535    (clobber (reg:DI 15))]
7536   ;;- Do not use operand 2 for most machines.
7537   "TARGET_ARCH64"
7538   "call\t%a1, %2%#"
7539   [(set_attr "type" "call")])
7541 (define_insn "*call_value_symbolic_sp64"
7542   [(set (match_operand 0 "" "")
7543         (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
7544               (match_operand 2 "" "")))
7545    (clobber (reg:DI 15))]
7546   ;;- Do not use operand 2 for most machines.
7547   "TARGET_ARCH64"
7548   "call\t%a1, %2%#"
7549   [(set_attr "type" "call")])
7551 (define_expand "untyped_call"
7552   [(parallel [(call (match_operand 0 "" "")
7553                     (const_int 0))
7554               (match_operand 1 "" "")
7555               (match_operand 2 "" "")])]
7556   ""
7558   int i;
7560   /* Pass constm1 to indicate that it may expect a structure value, but
7561      we don't know what size it is.  */
7562   emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
7564   for (i = 0; i < XVECLEN (operands[2], 0); i++)
7565     {
7566       rtx set = XVECEXP (operands[2], 0, i);
7567       emit_move_insn (SET_DEST (set), SET_SRC (set));
7568     }
7570   /* The optimizer does not know that the call sets the function value
7571      registers we stored in the result block.  We avoid problems by
7572      claiming that all hard registers are used and clobbered at this
7573      point.  */
7574   emit_insn (gen_blockage ());
7576   DONE;
7579 ;;- tail calls
7580 (define_expand "sibcall"
7581   [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
7582               (return)])]
7583   ""
7584   "")
7586 (define_insn "*sibcall_symbolic_sp32"
7587   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7588          (match_operand 1 "" ""))
7589    (return)]
7590   "! TARGET_ARCH64"
7591   "* return output_sibcall(insn, operands[0]);"
7592   [(set_attr "type" "sibcall")])
7594 (define_insn "*sibcall_symbolic_sp64"
7595   [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
7596          (match_operand 1 "" ""))
7597    (return)]
7598   "TARGET_ARCH64"
7599   "* return output_sibcall(insn, operands[0]);"
7600   [(set_attr "type" "sibcall")])
7602 (define_expand "sibcall_value"
7603   [(parallel [(set (match_operand 0 "register_operand" "=rf")
7604                 (call (match_operand 1 "" "") (const_int 0)))
7605               (return)])]
7606   ""
7607   "")
7609 (define_insn "*sibcall_value_symbolic_sp32"
7610   [(set (match_operand 0 "" "=rf")
7611         (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7612               (match_operand 2 "" "")))
7613    (return)]
7614   "! TARGET_ARCH64"
7615   "* return output_sibcall(insn, operands[1]);"
7616   [(set_attr "type" "sibcall")])
7618 (define_insn "*sibcall_value_symbolic_sp64"
7619   [(set (match_operand 0 "" "")
7620         (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
7621               (match_operand 2 "" "")))
7622    (return)]
7623   "TARGET_ARCH64"
7624   "* return output_sibcall(insn, operands[1]);"
7625   [(set_attr "type" "sibcall")])
7627 (define_expand "sibcall_epilogue"
7628   [(return)]
7629   ""
7631   sparc_expand_epilogue ();
7632   DONE;
7635 (define_expand "prologue"
7636   [(const_int 0)]
7637   ""
7639   sparc_expand_prologue ();
7640   DONE;
7643 (define_expand "save_register_window"
7644   [(use (match_operand 0 "arith_operand" ""))]
7645   ""
7647   rtvec vec;
7649   vec = gen_rtvec (2,
7650                    gen_rtx_SET (VOIDmode,
7651                                 stack_pointer_rtx,
7652                                 gen_rtx_PLUS (Pmode,
7653                                               hard_frame_pointer_rtx,
7654                                               operands[0])),
7655                    gen_rtx_UNSPEC_VOLATILE (VOIDmode,
7656                                             gen_rtvec (1, const0_rtx),
7657                                             UNSPECV_SAVEW));
7659   emit_insn (gen_rtx_PARALLEL (VOIDmode, vec));
7660   DONE;
7663 (define_insn "*save_register_windowsi"
7664   [(set (reg:SI 14) (plus:SI (reg:SI 30)
7665                              (match_operand:SI 0 "arith_operand" "rI")))
7666    (unspec_volatile [(const_int 0)] UNSPECV_SAVEW)]
7667   "! TARGET_ARCH64"
7668   "save\t%%sp, %0, %%sp"
7669   [(set_attr "type" "savew")])
7671 (define_insn "*save_register_windowdi"
7672   [(set (reg:DI 14) (plus:DI (reg:DI 30)
7673                              (match_operand:DI 0 "arith_operand" "rI")))
7674    (unspec_volatile [(const_int 0)] UNSPECV_SAVEW)]
7675   "TARGET_ARCH64"
7676   "save\t%%sp, %0, %%sp"
7677   [(set_attr "type" "savew")])
7679 (define_expand "epilogue"
7680   [(return)]
7681   ""
7683   sparc_expand_epilogue ();
7686 (define_insn "*return_internal"
7687   [(return)]
7688   ""
7689   "* return output_return (insn);"
7690   [(set_attr "type" "return")
7691    (set (attr "length")
7692         (cond [(eq_attr "leaf_function" "true")
7693                  (if_then_else (eq_attr "empty_delay_slot" "true")
7694                                (const_int 2)
7695                                (const_int 1))
7696                (eq_attr "calls_eh_return" "true")
7697                  (if_then_else (eq_attr "delayed_branch" "true")
7698                                (if_then_else (eq_attr "isa" "v9")
7699                                              (const_int 2)
7700                                              (const_int 3))
7701                                (if_then_else (eq_attr "isa" "v9")
7702                                              (const_int 3)
7703                                              (const_int 4)))
7704                (eq_attr "empty_delay_slot" "true")
7705                  (if_then_else (eq_attr "delayed_branch" "true")
7706                                (const_int 2)
7707                                (const_int 3))
7708               ] (const_int 1)))])
7710 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
7711 ;; all of memory.  This blocks insns from being moved across this point.
7713 (define_insn "blockage"
7714   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7715   ""
7716   ""
7717   [(set_attr "length" "0")])
7719 ;; Prepare to return any type including a structure value.
7721 (define_expand "untyped_return"
7722   [(match_operand:BLK 0 "memory_operand" "")
7723    (match_operand 1 "" "")]
7724   ""
7726   rtx valreg1 = gen_rtx_REG (DImode, 24);
7727   rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
7728   rtx result = operands[0];
7730   if (! TARGET_ARCH64)
7731     {
7732       rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
7733                                          ? 15 : 31));
7734       rtx value = gen_reg_rtx (SImode);
7736       /* Fetch the instruction where we will return to and see if it's an unimp
7737          instruction (the most significant 10 bits will be zero).  If so,
7738          update the return address to skip the unimp instruction.  */
7739       emit_move_insn (value,
7740                       gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
7741       emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
7742       emit_insn (gen_update_return (rtnreg, value));
7743     }
7745   /* Reload the function value registers.  */
7746   emit_move_insn (valreg1, adjust_address (result, DImode, 0));
7747   emit_move_insn (valreg2,
7748                   adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
7750   /* Put USE insns before the return.  */
7751   emit_insn (gen_rtx_USE (VOIDmode, valreg1));
7752   emit_insn (gen_rtx_USE (VOIDmode, valreg2));
7754   /* Construct the return.  */
7755   expand_naked_return ();
7757   DONE;
7760 ;; This is a bit of a hack.  We're incrementing a fixed register (%i7),
7761 ;; and parts of the compiler don't want to believe that the add is needed.
7763 (define_insn "update_return"
7764   [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
7765                (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
7766   "! TARGET_ARCH64"
7768   if (flag_delayed_branch)
7769     return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
7770   else
7771     return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
7773   [(set (attr "type") (const_string "multi"))
7774    (set (attr "length")
7775         (if_then_else (eq_attr "delayed_branch" "true")
7776                       (const_int 3)
7777                       (const_int 4)))])
7779 (define_insn "nop"
7780   [(const_int 0)]
7781   ""
7782   "nop")
7784 (define_expand "indirect_jump"
7785   [(set (pc) (match_operand 0 "address_operand" "p"))]
7786   ""
7787   "")
7789 (define_insn "*branch_sp32"
7790   [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
7791   "! TARGET_ARCH64"
7792  "jmp\t%a0%#"
7793  [(set_attr "type" "uncond_branch")])
7795 (define_insn "*branch_sp64"
7796   [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
7797   "TARGET_ARCH64"
7798   "jmp\t%a0%#"
7799   [(set_attr "type" "uncond_branch")])
7801 (define_expand "nonlocal_goto"
7802   [(match_operand:SI 0 "general_operand" "")
7803    (match_operand:SI 1 "general_operand" "")
7804    (match_operand:SI 2 "general_operand" "")
7805    (match_operand:SI 3 "" "")]
7806   ""
7808   rtx lab = operands[1];
7809   rtx stack = operands[2];
7810   rtx fp = operands[3];
7811   rtx labreg;
7813   /* Trap instruction to flush all the register windows.  */
7814   emit_insn (gen_flush_register_windows ());
7816   /* Load the fp value for the containing fn into %fp.  This is needed
7817      because STACK refers to %fp.  Note that virtual register instantiation
7818      fails if the virtual %fp isn't set from a register.  */
7819   if (GET_CODE (fp) != REG)
7820     fp = force_reg (Pmode, fp);
7821   emit_move_insn (virtual_stack_vars_rtx, fp);
7823   /* Find the containing function's current nonlocal goto handler,
7824      which will do any cleanups and then jump to the label.  */
7825   labreg = gen_rtx_REG (Pmode, 8);
7826   emit_move_insn (labreg, lab);
7828   /* Restore %fp from stack pointer value for containing function.
7829      The restore insn that follows will move this to %sp,
7830      and reload the appropriate value into %fp.  */
7831   emit_move_insn (hard_frame_pointer_rtx, stack);
7833   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
7834   emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
7836   /* ??? The V9-specific version was disabled in rev 1.65.  */
7837   emit_jump_insn (gen_goto_handler_and_restore (labreg));
7838   emit_barrier ();
7839   DONE;
7842 ;; Special trap insn to flush register windows.
7843 (define_insn "flush_register_windows"
7844   [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
7845   ""
7846   { return TARGET_V9 ? "flushw" : "ta\t3"; }
7847   [(set_attr "type" "flushw")])
7849 (define_insn "goto_handler_and_restore"
7850   [(unspec_volatile [(match_operand 0 "register_operand" "=r")] UNSPECV_GOTO)]
7851   "GET_MODE (operands[0]) == Pmode"
7853   if (flag_delayed_branch)
7854     return "jmp\t%0\n\t restore";
7855   else
7856     return "mov\t%0,%%g1\n\trestore\n\tjmp\t%%g1\n\t nop";
7858   [(set (attr "type") (const_string "multi"))
7859    (set (attr "length")
7860         (if_then_else (eq_attr "delayed_branch" "true")
7861                       (const_int 2)
7862                       (const_int 4)))])
7864 ;; For __builtin_setjmp we need to flush register windows iff the function
7865 ;; calls alloca as well, because otherwise the register window might be
7866 ;; saved after %sp adjustment and thus setjmp would crash
7867 (define_expand "builtin_setjmp_setup"
7868   [(match_operand 0 "register_operand" "r")]
7869   ""
7871   emit_insn (gen_do_builtin_setjmp_setup ());
7872   DONE;
7875 (define_insn "do_builtin_setjmp_setup"
7876   [(unspec_volatile [(const_int 0)] UNSPECV_SETJMP)]
7877   ""
7879   if (! current_function_calls_alloca)
7880     return "";
7881   if (! TARGET_V9)
7882     return "\tta\t3\n";
7883   fputs ("\tflushw\n", asm_out_file);
7884   if (flag_pic)
7885     fprintf (asm_out_file, "\tst%c\t%%l7, [%%sp+%d]\n",
7886              TARGET_ARCH64 ? 'x' : 'w',
7887              SPARC_STACK_BIAS + 7 * UNITS_PER_WORD);
7888   fprintf (asm_out_file, "\tst%c\t%%fp, [%%sp+%d]\n",
7889            TARGET_ARCH64 ? 'x' : 'w',
7890            SPARC_STACK_BIAS + 14 * UNITS_PER_WORD);
7891   fprintf (asm_out_file, "\tst%c\t%%i7, [%%sp+%d]\n",
7892            TARGET_ARCH64 ? 'x' : 'w',
7893            SPARC_STACK_BIAS + 15 * UNITS_PER_WORD);
7894   return "";
7896   [(set_attr "type" "multi")
7897    (set (attr "length")
7898         (cond [(eq_attr "calls_alloca" "false")
7899                  (const_int 0)
7900                (eq_attr "isa" "!v9")
7901                  (const_int 1)
7902                (eq_attr "pic" "true")
7903                  (const_int 4)] (const_int 3)))])
7905 ;; Pattern for use after a setjmp to store FP and the return register
7906 ;; into the stack area.
7908 (define_expand "setjmp"
7909   [(const_int 0)]
7910   ""
7912   if (TARGET_ARCH64)
7913     emit_insn (gen_setjmp_64 ());
7914   else
7915     emit_insn (gen_setjmp_32 ());
7916   DONE;
7919 (define_expand "setjmp_32"
7920   [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
7921    (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
7922   ""
7923   { operands[0] = frame_pointer_rtx; })
7925 (define_expand "setjmp_64"
7926   [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
7927    (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
7928   ""
7929   { operands[0] = frame_pointer_rtx; })
7931 ;; Special pattern for the FLUSH instruction.
7933 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
7934 ; of the define_insn otherwise missing a mode.  We make "flush", aka
7935 ; gen_flush, the default one since sparc_initialize_trampoline uses
7936 ; it on SImode mem values.
7938 (define_insn "flush"
7939   [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7940   ""
7941   { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7942   [(set_attr "type" "iflush")])
7944 (define_insn "flushdi"
7945   [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7946   ""
7947   { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7948   [(set_attr "type" "iflush")])
7951 ;; find first set.
7953 ;; The scan instruction searches from the most significant bit while ffs
7954 ;; searches from the least significant bit.  The bit index and treatment of
7955 ;; zero also differ.  It takes at least 7 instructions to get the proper
7956 ;; result.  Here is an obvious 8 instruction sequence.
7958 ;; XXX
7959 (define_insn "ffssi2"
7960   [(set (match_operand:SI 0 "register_operand" "=&r")
7961         (ffs:SI (match_operand:SI 1 "register_operand" "r")))
7962    (clobber (match_scratch:SI 2 "=&r"))]
7963   "TARGET_SPARCLITE || TARGET_SPARCLET"
7965   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";
7967   [(set_attr "type" "multi")
7968    (set_attr "length" "8")])
7970 ;; ??? This should be a define expand, so that the extra instruction have
7971 ;; a chance of being optimized away.
7973 ;; Disabled because none of the UltraSPARCs implement popc.  The HAL R1
7974 ;; does, but no one uses that and we don't have a switch for it.
7976 ;(define_insn "ffsdi2"
7977 ;  [(set (match_operand:DI 0 "register_operand" "=&r")
7978 ;       (ffs:DI (match_operand:DI 1 "register_operand" "r")))
7979 ;   (clobber (match_scratch:DI 2 "=&r"))]
7980 ;  "TARGET_ARCH64"
7981 ;  "neg\t%1, %2\;xnor\t%1, %2, %2\;popc\t%2, %0\;movzr\t%1, 0, %0"
7982 ;  [(set_attr "type" "multi")
7983 ;   (set_attr "length" "4")])
7987 ;; Peepholes go at the end.
7989 ;; Optimize consecutive loads or stores into ldd and std when possible.
7990 ;; The conditions in which we do this are very restricted and are 
7991 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
7993 (define_peephole2
7994   [(set (match_operand:SI 0 "memory_operand" "")
7995       (const_int 0))
7996    (set (match_operand:SI 1 "memory_operand" "")
7997       (const_int 0))]
7998   "TARGET_V9
7999    && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
8000   [(set (match_dup 0)
8001        (const_int 0))]
8002   "operands[0] = widen_memory_access (operands[0], DImode, 0);")
8004 (define_peephole2
8005   [(set (match_operand:SI 0 "memory_operand" "")
8006       (const_int 0))
8007    (set (match_operand:SI 1 "memory_operand" "")
8008       (const_int 0))]
8009   "TARGET_V9
8010    && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
8011   [(set (match_dup 1)
8012        (const_int 0))]
8013   "operands[1] = widen_memory_access (operands[1], DImode, 0);")
8015 (define_peephole2
8016   [(set (match_operand:SI 0 "register_operand" "")
8017         (match_operand:SI 1 "memory_operand" ""))
8018    (set (match_operand:SI 2 "register_operand" "")
8019         (match_operand:SI 3 "memory_operand" ""))]
8020   "registers_ok_for_ldd_peep (operands[0], operands[2]) 
8021    && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])" 
8022   [(set (match_dup 0)
8023         (match_dup 1))]
8024   "operands[1] = widen_memory_access (operands[1], DImode, 0);
8025    operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
8027 (define_peephole2
8028   [(set (match_operand:SI 0 "memory_operand" "")
8029         (match_operand:SI 1 "register_operand" ""))
8030    (set (match_operand:SI 2 "memory_operand" "")
8031         (match_operand:SI 3 "register_operand" ""))]
8032   "registers_ok_for_ldd_peep (operands[1], operands[3]) 
8033    && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
8034   [(set (match_dup 0)
8035         (match_dup 1))]
8036   "operands[0] = widen_memory_access (operands[0], DImode, 0);
8037    operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
8039 (define_peephole2
8040   [(set (match_operand:SF 0 "register_operand" "")
8041         (match_operand:SF 1 "memory_operand" ""))
8042    (set (match_operand:SF 2 "register_operand" "")
8043         (match_operand:SF 3 "memory_operand" ""))]
8044   "registers_ok_for_ldd_peep (operands[0], operands[2]) 
8045    && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
8046   [(set (match_dup 0)
8047         (match_dup 1))]
8048   "operands[1] = widen_memory_access (operands[1], DFmode, 0);
8049    operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
8051 (define_peephole2
8052   [(set (match_operand:SF 0 "memory_operand" "")
8053         (match_operand:SF 1 "register_operand" ""))
8054    (set (match_operand:SF 2 "memory_operand" "")
8055         (match_operand:SF 3 "register_operand" ""))]
8056   "registers_ok_for_ldd_peep (operands[1], operands[3]) 
8057   && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
8058   [(set (match_dup 0)
8059         (match_dup 1))]
8060   "operands[0] = widen_memory_access (operands[0], DFmode, 0);
8061    operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
8063 (define_peephole2
8064   [(set (match_operand:SI 0 "register_operand" "")
8065         (match_operand:SI 1 "memory_operand" ""))
8066    (set (match_operand:SI 2 "register_operand" "")
8067         (match_operand:SI 3 "memory_operand" ""))]
8068   "registers_ok_for_ldd_peep (operands[2], operands[0]) 
8069   && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
8070   [(set (match_dup 2)
8071         (match_dup 3))]
8072    "operands[3] = widen_memory_access (operands[3], DImode, 0);
8073     operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
8075 (define_peephole2
8076   [(set (match_operand:SI 0 "memory_operand" "")
8077         (match_operand:SI 1 "register_operand" ""))
8078    (set (match_operand:SI 2 "memory_operand" "")
8079         (match_operand:SI 3 "register_operand" ""))]
8080   "registers_ok_for_ldd_peep (operands[3], operands[1]) 
8081   && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)" 
8082   [(set (match_dup 2)
8083         (match_dup 3))]
8084   "operands[2] = widen_memory_access (operands[2], DImode, 0);
8085    operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
8086    ")
8088 (define_peephole2
8089   [(set (match_operand:SF 0 "register_operand" "")
8090         (match_operand:SF 1 "memory_operand" ""))
8091    (set (match_operand:SF 2 "register_operand" "")
8092         (match_operand:SF 3 "memory_operand" ""))]
8093   "registers_ok_for_ldd_peep (operands[2], operands[0]) 
8094   && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
8095   [(set (match_dup 2)
8096         (match_dup 3))]
8097   "operands[3] = widen_memory_access (operands[3], DFmode, 0);
8098    operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
8100 (define_peephole2
8101   [(set (match_operand:SF 0 "memory_operand" "")
8102         (match_operand:SF 1 "register_operand" ""))
8103    (set (match_operand:SF 2 "memory_operand" "")
8104         (match_operand:SF 3 "register_operand" ""))]
8105   "registers_ok_for_ldd_peep (operands[3], operands[1]) 
8106   && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
8107   [(set (match_dup 2)
8108         (match_dup 3))]
8109   "operands[2] = widen_memory_access (operands[2], DFmode, 0);
8110    operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
8112 ;; Optimize the case of following a reg-reg move with a test
8113 ;; of reg just moved.  Don't allow floating point regs for operand 0 or 1.
8114 ;; This can result from a float to fix conversion.
8116 (define_peephole2
8117   [(set (match_operand:SI 0 "register_operand" "")
8118         (match_operand:SI 1 "register_operand" ""))
8119    (set (reg:CC 100)
8120         (compare:CC (match_operand:SI 2 "register_operand" "")
8121                     (const_int 0)))]
8122   "(rtx_equal_p (operands[2], operands[0])
8123     || rtx_equal_p (operands[2], operands[1]))
8124     && ! SPARC_FP_REG_P (REGNO (operands[0]))
8125     && ! SPARC_FP_REG_P (REGNO (operands[1]))"
8126   [(parallel [(set (match_dup 0) (match_dup 1))
8127               (set (reg:CC 100)
8128                    (compare:CC (match_dup 1) (const_int 0)))])]
8129   "")
8131 (define_peephole2
8132   [(set (match_operand:DI 0 "register_operand" "")
8133         (match_operand:DI 1 "register_operand" ""))
8134    (set (reg:CCX 100)
8135         (compare:CCX (match_operand:DI 2 "register_operand" "")
8136                     (const_int 0)))]
8137   "TARGET_ARCH64
8138    && (rtx_equal_p (operands[2], operands[0])
8139        || rtx_equal_p (operands[2], operands[1]))
8140    && ! SPARC_FP_REG_P (REGNO (operands[0]))
8141    && ! SPARC_FP_REG_P (REGNO (operands[1]))"
8142   [(parallel [(set (match_dup 0) (match_dup 1))
8143               (set (reg:CCX 100)
8144                    (compare:CCX (match_dup 1) (const_int 0)))])]
8145   "")
8147 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
8148 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
8149 ;; ??? operations.  With DFA we might be able to model this, but it requires a lot of
8150 ;; ??? state.
8151 (define_expand "prefetch"
8152   [(match_operand 0 "address_operand" "")
8153    (match_operand 1 "const_int_operand" "")
8154    (match_operand 2 "const_int_operand" "")]
8155   "TARGET_V9"
8157   if (TARGET_ARCH64)
8158     emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
8159   else
8160     emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
8161   DONE;
8164 (define_insn "prefetch_64"
8165   [(prefetch (match_operand:DI 0 "address_operand" "p")
8166              (match_operand:DI 1 "const_int_operand" "n")
8167              (match_operand:DI 2 "const_int_operand" "n"))]
8168   ""
8170   static const char * const prefetch_instr[2][2] = {
8171     {
8172       "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
8173       "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
8174     },
8175     {
8176       "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
8177       "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
8178     }
8179   };
8180   int read_or_write = INTVAL (operands[1]);
8181   int locality = INTVAL (operands[2]);
8183   if (read_or_write != 0 && read_or_write != 1)
8184     abort ();
8185   if (locality < 0 || locality > 3)
8186     abort ();
8187   return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
8189   [(set_attr "type" "load")])
8191 (define_insn "prefetch_32"
8192   [(prefetch (match_operand:SI 0 "address_operand" "p")
8193              (match_operand:SI 1 "const_int_operand" "n")
8194              (match_operand:SI 2 "const_int_operand" "n"))]
8195   ""
8197   static const char * const prefetch_instr[2][2] = {
8198     {
8199       "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
8200       "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
8201     },
8202     {
8203       "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
8204       "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
8205     }
8206   };
8207   int read_or_write = INTVAL (operands[1]);
8208   int locality = INTVAL (operands[2]);
8210   if (read_or_write != 0 && read_or_write != 1)
8211     abort ();
8212   if (locality < 0 || locality > 3)
8213     abort ();
8214   return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
8216   [(set_attr "type" "load")])
8218 (define_insn "trap"
8219   [(trap_if (const_int 1) (const_int 5))]
8220   ""
8221   "ta\t5"
8222   [(set_attr "type" "trap")])
8224 (define_expand "conditional_trap"
8225   [(trap_if (match_operator 0 "noov_compare_op"
8226                             [(match_dup 2) (match_dup 3)])
8227             (match_operand:SI 1 "arith_operand" ""))]
8228   ""
8229   "operands[2] = gen_compare_reg (GET_CODE (operands[0]),
8230                                   sparc_compare_op0, sparc_compare_op1);
8231    operands[3] = const0_rtx;")
8233 (define_insn ""
8234   [(trap_if (match_operator 0 "noov_compare_op" [(reg:CC 100) (const_int 0)])
8235             (match_operand:SI 1 "arith_operand" "rM"))]
8236   ""
8237   "t%C0\t%1"
8238   [(set_attr "type" "trap")])
8240 (define_insn ""
8241   [(trap_if (match_operator 0 "noov_compare_op" [(reg:CCX 100) (const_int 0)])
8242             (match_operand:SI 1 "arith_operand" "rM"))]
8243   "TARGET_V9"
8244   "t%C0\t%%xcc, %1"
8245   [(set_attr "type" "trap")])
8247 ;; TLS support
8248 (define_insn "tgd_hi22"
8249   [(set (match_operand:SI 0 "register_operand" "=r")
8250         (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
8251                             UNSPEC_TLSGD)))]
8252   "TARGET_TLS"
8253   "sethi\\t%%tgd_hi22(%a1), %0")
8255 (define_insn "tgd_lo10"
8256   [(set (match_operand:SI 0 "register_operand" "=r")
8257         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8258                    (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
8259                               UNSPEC_TLSGD)))]
8260   "TARGET_TLS"
8261   "add\\t%1, %%tgd_lo10(%a2), %0")
8263 (define_insn "tgd_add32"
8264   [(set (match_operand:SI 0 "register_operand" "=r")
8265         (plus:SI (match_operand:SI 1 "register_operand" "r")
8266                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8267                              (match_operand 3 "tgd_symbolic_operand" "")]
8268                             UNSPEC_TLSGD)))]
8269   "TARGET_TLS && TARGET_ARCH32"
8270   "add\\t%1, %2, %0, %%tgd_add(%a3)")
8272 (define_insn "tgd_add64"
8273   [(set (match_operand:DI 0 "register_operand" "=r")
8274         (plus:DI (match_operand:DI 1 "register_operand" "r")
8275                  (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8276                              (match_operand 3 "tgd_symbolic_operand" "")]
8277                             UNSPEC_TLSGD)))]
8278   "TARGET_TLS && TARGET_ARCH64"
8279   "add\\t%1, %2, %0, %%tgd_add(%a3)")
8281 (define_insn "tgd_call32"
8282   [(set (match_operand 0 "register_operand" "=r")
8283         (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
8284                                   (match_operand 2 "tgd_symbolic_operand" "")]
8285                                  UNSPEC_TLSGD))
8286               (match_operand 3 "" "")))
8287    (clobber (reg:SI 15))]
8288   "TARGET_TLS && TARGET_ARCH32"
8289   "call\t%a1, %%tgd_call(%a2)%#"
8290   [(set_attr "type" "call")])
8292 (define_insn "tgd_call64"
8293   [(set (match_operand 0 "register_operand" "=r")
8294         (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
8295                                   (match_operand 2 "tgd_symbolic_operand" "")]
8296                                  UNSPEC_TLSGD))
8297               (match_operand 3 "" "")))
8298    (clobber (reg:DI 15))]
8299   "TARGET_TLS && TARGET_ARCH64"
8300   "call\t%a1, %%tgd_call(%a2)%#"
8301   [(set_attr "type" "call")])
8303 (define_insn "tldm_hi22"
8304   [(set (match_operand:SI 0 "register_operand" "=r")
8305         (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
8306   "TARGET_TLS"
8307   "sethi\\t%%tldm_hi22(%&), %0")
8309 (define_insn "tldm_lo10"
8310   [(set (match_operand:SI 0 "register_operand" "=r")
8311         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8312                     (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
8313   "TARGET_TLS"
8314   "add\\t%1, %%tldm_lo10(%&), %0")
8316 (define_insn "tldm_add32"
8317   [(set (match_operand:SI 0 "register_operand" "=r")
8318         (plus:SI (match_operand:SI 1 "register_operand" "r")
8319                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
8320                             UNSPEC_TLSLDM)))]
8321   "TARGET_TLS && TARGET_ARCH32"
8322   "add\\t%1, %2, %0, %%tldm_add(%&)")
8324 (define_insn "tldm_add64"
8325   [(set (match_operand:DI 0 "register_operand" "=r")
8326         (plus:DI (match_operand:DI 1 "register_operand" "r")
8327                  (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
8328                             UNSPEC_TLSLDM)))]
8329   "TARGET_TLS && TARGET_ARCH64"
8330   "add\\t%1, %2, %0, %%tldm_add(%&)")
8332 (define_insn "tldm_call32"
8333   [(set (match_operand 0 "register_operand" "=r")
8334         (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
8335                                  UNSPEC_TLSLDM))
8336               (match_operand 2 "" "")))
8337    (clobber (reg:SI 15))]
8338   "TARGET_TLS && TARGET_ARCH32"
8339   "call\t%a1, %%tldm_call(%&)%#"
8340   [(set_attr "type" "call")])
8342 (define_insn "tldm_call64"
8343   [(set (match_operand 0 "register_operand" "=r")
8344         (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
8345                                  UNSPEC_TLSLDM))
8346               (match_operand 2 "" "")))
8347    (clobber (reg:DI 15))]
8348   "TARGET_TLS && TARGET_ARCH64"
8349   "call\t%a1, %%tldm_call(%&)%#"
8350   [(set_attr "type" "call")])
8352 (define_insn "tldo_hix22"
8353   [(set (match_operand:SI 0 "register_operand" "=r")
8354         (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
8355                             UNSPEC_TLSLDO)))]
8356   "TARGET_TLS"
8357   "sethi\\t%%tldo_hix22(%a1), %0")
8359 (define_insn "tldo_lox10"
8360   [(set (match_operand:SI 0 "register_operand" "=r")
8361         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8362                    (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
8363                               UNSPEC_TLSLDO)))]
8364   "TARGET_TLS"
8365   "xor\\t%1, %%tldo_lox10(%a2), %0")
8367 (define_insn "tldo_add32"
8368   [(set (match_operand:SI 0 "register_operand" "=r")
8369         (plus:SI (match_operand:SI 1 "register_operand" "r")
8370                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8371                              (match_operand 3 "tld_symbolic_operand" "")]
8372                             UNSPEC_TLSLDO)))]
8373   "TARGET_TLS && TARGET_ARCH32"
8374   "add\\t%1, %2, %0, %%tldo_add(%a3)")
8376 (define_insn "tldo_add64"
8377   [(set (match_operand:DI 0 "register_operand" "=r")
8378         (plus:DI (match_operand:DI 1 "register_operand" "r")
8379                  (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8380                              (match_operand 3 "tld_symbolic_operand" "")]
8381                             UNSPEC_TLSLDO)))]
8382   "TARGET_TLS && TARGET_ARCH64"
8383   "add\\t%1, %2, %0, %%tldo_add(%a3)")
8385 (define_insn "tie_hi22"
8386   [(set (match_operand:SI 0 "register_operand" "=r")
8387         (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
8388                             UNSPEC_TLSIE)))]
8389   "TARGET_TLS"
8390   "sethi\\t%%tie_hi22(%a1), %0")
8392 (define_insn "tie_lo10"
8393   [(set (match_operand:SI 0 "register_operand" "=r")
8394         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8395                    (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
8396                               UNSPEC_TLSIE)))]
8397   "TARGET_TLS"
8398   "add\\t%1, %%tie_lo10(%a2), %0")
8400 (define_insn "tie_ld32"
8401   [(set (match_operand:SI 0 "register_operand" "=r")
8402         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
8403                     (match_operand:SI 2 "register_operand" "r")
8404                     (match_operand 3 "tie_symbolic_operand" "")]
8405                    UNSPEC_TLSIE))]
8406   "TARGET_TLS && TARGET_ARCH32"
8407   "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
8408   [(set_attr "type" "load")])
8410 (define_insn "tie_ld64"
8411   [(set (match_operand:DI 0 "register_operand" "=r")
8412         (unspec:DI [(match_operand:DI 1 "register_operand" "r")
8413                     (match_operand:SI 2 "register_operand" "r")
8414                     (match_operand 3 "tie_symbolic_operand" "")]
8415                    UNSPEC_TLSIE))]
8416   "TARGET_TLS && TARGET_ARCH64"
8417   "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
8418   [(set_attr "type" "load")])
8420 (define_insn "tie_add32"
8421   [(set (match_operand:SI 0 "register_operand" "=r")
8422         (plus:SI (match_operand:SI 1 "register_operand" "r")
8423                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8424                              (match_operand 3 "tie_symbolic_operand" "")]
8425                             UNSPEC_TLSIE)))]
8426   "TARGET_SUN_TLS && TARGET_ARCH32"
8427   "add\\t%1, %2, %0, %%tie_add(%a3)")
8429 (define_insn "tie_add64"
8430   [(set (match_operand:DI 0 "register_operand" "=r")
8431         (plus:DI (match_operand:DI 1 "register_operand" "r")
8432                  (unspec:DI [(match_operand:DI 2 "register_operand" "r")
8433                              (match_operand 3 "tie_symbolic_operand" "")]
8434                             UNSPEC_TLSIE)))]
8435   "TARGET_SUN_TLS && TARGET_ARCH64"
8436   "add\\t%1, %2, %0, %%tie_add(%a3)")
8438 (define_insn "tle_hix22_sp32"
8439   [(set (match_operand:SI 0 "register_operand" "=r")
8440         (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
8441                             UNSPEC_TLSLE)))]
8442   "TARGET_TLS && TARGET_ARCH32"
8443   "sethi\\t%%tle_hix22(%a1), %0")
8445 (define_insn "tle_lox10_sp32"
8446   [(set (match_operand:SI 0 "register_operand" "=r")
8447         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8448                    (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
8449                               UNSPEC_TLSLE)))]
8450   "TARGET_TLS && TARGET_ARCH32"
8451   "xor\\t%1, %%tle_lox10(%a2), %0")
8453 (define_insn "tle_hix22_sp64"
8454   [(set (match_operand:DI 0 "register_operand" "=r")
8455         (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
8456                             UNSPEC_TLSLE)))]
8457   "TARGET_TLS && TARGET_ARCH64"
8458   "sethi\\t%%tle_hix22(%a1), %0")
8460 (define_insn "tle_lox10_sp64"
8461   [(set (match_operand:DI 0 "register_operand" "=r")
8462         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
8463                    (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
8464                               UNSPEC_TLSLE)))]
8465   "TARGET_TLS && TARGET_ARCH64"
8466   "xor\\t%1, %%tle_lox10(%a2), %0")
8468 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
8469 (define_insn "*tldo_ldub_sp32"
8470   [(set (match_operand:QI 0 "register_operand" "=r")
8471         (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8472                                      (match_operand 3 "tld_symbolic_operand" "")]
8473                                     UNSPEC_TLSLDO)
8474                          (match_operand:SI 1 "register_operand" "r"))))]
8475   "TARGET_TLS && TARGET_ARCH32"
8476   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8477   [(set_attr "type" "load")
8478    (set_attr "us3load_type" "3cycle")])
8480 (define_insn "*tldo_ldub1_sp32"
8481   [(set (match_operand:HI 0 "register_operand" "=r")
8482         (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8483                                                      (match_operand 3 "tld_symbolic_operand" "")]
8484                                                     UNSPEC_TLSLDO)
8485                                          (match_operand:SI 1 "register_operand" "r")))))]
8486   "TARGET_TLS && TARGET_ARCH32"
8487   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8488   [(set_attr "type" "load")
8489    (set_attr "us3load_type" "3cycle")])
8491 (define_insn "*tldo_ldub2_sp32"
8492   [(set (match_operand:SI 0 "register_operand" "=r")
8493         (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8494                                                      (match_operand 3 "tld_symbolic_operand" "")]
8495                                                     UNSPEC_TLSLDO)
8496                                          (match_operand:SI 1 "register_operand" "r")))))]
8497   "TARGET_TLS && TARGET_ARCH32"
8498   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8499   [(set_attr "type" "load")
8500    (set_attr "us3load_type" "3cycle")])
8502 (define_insn "*tldo_ldsb1_sp32"
8503   [(set (match_operand:HI 0 "register_operand" "=r")
8504         (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8505                                                      (match_operand 3 "tld_symbolic_operand" "")]
8506                                                     UNSPEC_TLSLDO)
8507                                          (match_operand:SI 1 "register_operand" "r")))))]
8508   "TARGET_TLS && TARGET_ARCH32"
8509   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8510   [(set_attr "type" "sload")
8511    (set_attr "us3load_type" "3cycle")])
8513 (define_insn "*tldo_ldsb2_sp32"
8514   [(set (match_operand:SI 0 "register_operand" "=r")
8515         (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8516                                                      (match_operand 3 "tld_symbolic_operand" "")]
8517                                                     UNSPEC_TLSLDO)
8518                                          (match_operand:SI 1 "register_operand" "r")))))]
8519   "TARGET_TLS && TARGET_ARCH32"
8520   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8521   [(set_attr "type" "sload")
8522    (set_attr "us3load_type" "3cycle")])
8524 (define_insn "*tldo_ldub_sp64"
8525   [(set (match_operand:QI 0 "register_operand" "=r")
8526         (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8527                                      (match_operand 3 "tld_symbolic_operand" "")]
8528                                     UNSPEC_TLSLDO)
8529                          (match_operand:DI 1 "register_operand" "r"))))]
8530   "TARGET_TLS && TARGET_ARCH64"
8531   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8532   [(set_attr "type" "load")
8533    (set_attr "us3load_type" "3cycle")])
8535 (define_insn "*tldo_ldub1_sp64"
8536   [(set (match_operand:HI 0 "register_operand" "=r")
8537         (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8538                                                      (match_operand 3 "tld_symbolic_operand" "")]
8539                                                     UNSPEC_TLSLDO)
8540                                          (match_operand:DI 1 "register_operand" "r")))))]
8541   "TARGET_TLS && TARGET_ARCH64"
8542   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8543   [(set_attr "type" "load")
8544    (set_attr "us3load_type" "3cycle")])
8546 (define_insn "*tldo_ldub2_sp64"
8547   [(set (match_operand:SI 0 "register_operand" "=r")
8548         (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8549                                                      (match_operand 3 "tld_symbolic_operand" "")]
8550                                                     UNSPEC_TLSLDO)
8551                                          (match_operand:DI 1 "register_operand" "r")))))]
8552   "TARGET_TLS && TARGET_ARCH64"
8553   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8554   [(set_attr "type" "load")
8555    (set_attr "us3load_type" "3cycle")])
8557 (define_insn "*tldo_ldub3_sp64"
8558   [(set (match_operand:DI 0 "register_operand" "=r")
8559         (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8560                                                      (match_operand 3 "tld_symbolic_operand" "")]
8561                                                     UNSPEC_TLSLDO)
8562                                          (match_operand:DI 1 "register_operand" "r")))))]
8563   "TARGET_TLS && TARGET_ARCH64"
8564   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8565   [(set_attr "type" "load")
8566    (set_attr "us3load_type" "3cycle")])
8568 (define_insn "*tldo_ldsb1_sp64"
8569   [(set (match_operand:HI 0 "register_operand" "=r")
8570         (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8571                                                      (match_operand 3 "tld_symbolic_operand" "")]
8572                                                     UNSPEC_TLSLDO)
8573                                          (match_operand:DI 1 "register_operand" "r")))))]
8574   "TARGET_TLS && TARGET_ARCH64"
8575   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8576   [(set_attr "type" "sload")
8577    (set_attr "us3load_type" "3cycle")])
8579 (define_insn "*tldo_ldsb2_sp64"
8580   [(set (match_operand:SI 0 "register_operand" "=r")
8581         (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8582                                                      (match_operand 3 "tld_symbolic_operand" "")]
8583                                                     UNSPEC_TLSLDO)
8584                                          (match_operand:DI 1 "register_operand" "r")))))]
8585   "TARGET_TLS && TARGET_ARCH64"
8586   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8587   [(set_attr "type" "sload")
8588    (set_attr "us3load_type" "3cycle")])
8590 (define_insn "*tldo_ldsb3_sp64"
8591   [(set (match_operand:DI 0 "register_operand" "=r")
8592         (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8593                                                      (match_operand 3 "tld_symbolic_operand" "")]
8594                                                     UNSPEC_TLSLDO)
8595                                          (match_operand:DI 1 "register_operand" "r")))))]
8596   "TARGET_TLS && TARGET_ARCH64"
8597   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8598   [(set_attr "type" "sload")
8599    (set_attr "us3load_type" "3cycle")])
8601 (define_insn "*tldo_lduh_sp32"
8602   [(set (match_operand:HI 0 "register_operand" "=r")
8603         (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8604                                      (match_operand 3 "tld_symbolic_operand" "")]
8605                                     UNSPEC_TLSLDO)
8606                          (match_operand:SI 1 "register_operand" "r"))))]
8607   "TARGET_TLS && TARGET_ARCH32"
8608   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8609   [(set_attr "type" "load")
8610    (set_attr "us3load_type" "3cycle")])
8612 (define_insn "*tldo_lduh1_sp32"
8613   [(set (match_operand:SI 0 "register_operand" "=r")
8614         (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8615                                                      (match_operand 3 "tld_symbolic_operand" "")]
8616                                                     UNSPEC_TLSLDO)
8617                                          (match_operand:SI 1 "register_operand" "r")))))]
8618   "TARGET_TLS && TARGET_ARCH32"
8619   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8620   [(set_attr "type" "load")
8621    (set_attr "us3load_type" "3cycle")])
8623 (define_insn "*tldo_ldsh1_sp32"
8624   [(set (match_operand:SI 0 "register_operand" "=r")
8625         (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8626                                                      (match_operand 3 "tld_symbolic_operand" "")]
8627                                                     UNSPEC_TLSLDO)
8628                                          (match_operand:SI 1 "register_operand" "r")))))]
8629   "TARGET_TLS && TARGET_ARCH32"
8630   "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8631   [(set_attr "type" "sload")
8632    (set_attr "us3load_type" "3cycle")])
8634 (define_insn "*tldo_lduh_sp64"
8635   [(set (match_operand:HI 0 "register_operand" "=r")
8636         (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8637                                      (match_operand 3 "tld_symbolic_operand" "")]
8638                                     UNSPEC_TLSLDO)
8639                          (match_operand:DI 1 "register_operand" "r"))))]
8640   "TARGET_TLS && TARGET_ARCH64"
8641   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8642   [(set_attr "type" "load")
8643    (set_attr "us3load_type" "3cycle")])
8645 (define_insn "*tldo_lduh1_sp64"
8646   [(set (match_operand:SI 0 "register_operand" "=r")
8647         (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8648                                                      (match_operand 3 "tld_symbolic_operand" "")]
8649                                                     UNSPEC_TLSLDO)
8650                                          (match_operand:DI 1 "register_operand" "r")))))]
8651   "TARGET_TLS && TARGET_ARCH64"
8652   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8653   [(set_attr "type" "load")
8654    (set_attr "us3load_type" "3cycle")])
8656 (define_insn "*tldo_lduh2_sp64"
8657   [(set (match_operand:DI 0 "register_operand" "=r")
8658         (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8659                                                      (match_operand 3 "tld_symbolic_operand" "")]
8660                                                     UNSPEC_TLSLDO)
8661                                          (match_operand:DI 1 "register_operand" "r")))))]
8662   "TARGET_TLS && TARGET_ARCH64"
8663   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8664   [(set_attr "type" "load")
8665    (set_attr "us3load_type" "3cycle")])
8667 (define_insn "*tldo_ldsh1_sp64"
8668   [(set (match_operand:SI 0 "register_operand" "=r")
8669         (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8670                                                      (match_operand 3 "tld_symbolic_operand" "")]
8671                                                     UNSPEC_TLSLDO)
8672                                          (match_operand:DI 1 "register_operand" "r")))))]
8673   "TARGET_TLS && TARGET_ARCH64"
8674   "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8675   [(set_attr "type" "sload")
8676    (set_attr "us3load_type" "3cycle")])
8678 (define_insn "*tldo_ldsh2_sp64"
8679   [(set (match_operand:DI 0 "register_operand" "=r")
8680         (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8681                                                      (match_operand 3 "tld_symbolic_operand" "")]
8682                                                     UNSPEC_TLSLDO)
8683                                          (match_operand:DI 1 "register_operand" "r")))))]
8684   "TARGET_TLS && TARGET_ARCH64"
8685   "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8686   [(set_attr "type" "sload")
8687    (set_attr "us3load_type" "3cycle")])
8689 (define_insn "*tldo_lduw_sp32"
8690   [(set (match_operand:SI 0 "register_operand" "=r")
8691         (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8692                                      (match_operand 3 "tld_symbolic_operand" "")]
8693                                     UNSPEC_TLSLDO)
8694                          (match_operand:SI 1 "register_operand" "r"))))]
8695   "TARGET_TLS && TARGET_ARCH32"
8696   "ld\t[%1 + %2], %0, %%tldo_add(%3)"
8697   [(set_attr "type" "load")])
8699 (define_insn "*tldo_lduw_sp64"
8700   [(set (match_operand:SI 0 "register_operand" "=r")
8701         (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8702                                      (match_operand 3 "tld_symbolic_operand" "")]
8703                                     UNSPEC_TLSLDO)
8704                          (match_operand:DI 1 "register_operand" "r"))))]
8705   "TARGET_TLS && TARGET_ARCH64"
8706   "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8707   [(set_attr "type" "load")])
8709 (define_insn "*tldo_lduw1_sp64"
8710   [(set (match_operand:DI 0 "register_operand" "=r")
8711         (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8712                                                      (match_operand 3 "tld_symbolic_operand" "")]
8713                                                     UNSPEC_TLSLDO)
8714                                          (match_operand:DI 1 "register_operand" "r")))))]
8715   "TARGET_TLS && TARGET_ARCH64"
8716   "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8717   [(set_attr "type" "load")])
8719 (define_insn "*tldo_ldsw1_sp64"
8720   [(set (match_operand:DI 0 "register_operand" "=r")
8721         (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8722                                                      (match_operand 3 "tld_symbolic_operand" "")]
8723                                                     UNSPEC_TLSLDO)
8724                                          (match_operand:DI 1 "register_operand" "r")))))]
8725   "TARGET_TLS && TARGET_ARCH64"
8726   "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
8727   [(set_attr "type" "sload")
8728    (set_attr "us3load_type" "3cycle")])
8730 (define_insn "*tldo_ldx_sp64"
8731   [(set (match_operand:DI 0 "register_operand" "=r")
8732         (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8733                                      (match_operand 3 "tld_symbolic_operand" "")]
8734                                     UNSPEC_TLSLDO)
8735                          (match_operand:DI 1 "register_operand" "r"))))]
8736   "TARGET_TLS && TARGET_ARCH64"
8737   "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
8738   [(set_attr "type" "load")])
8740 (define_insn "*tldo_stb_sp32"
8741   [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8742                                      (match_operand 3 "tld_symbolic_operand" "")]
8743                                     UNSPEC_TLSLDO)
8744                          (match_operand:SI 1 "register_operand" "r")))
8745         (match_operand:QI 0 "register_operand" "=r"))]
8746   "TARGET_TLS && TARGET_ARCH32"
8747   "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8748   [(set_attr "type" "store")])
8750 (define_insn "*tldo_stb_sp64"
8751   [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8752                                      (match_operand 3 "tld_symbolic_operand" "")]
8753                                     UNSPEC_TLSLDO)
8754                          (match_operand:DI 1 "register_operand" "r")))
8755         (match_operand:QI 0 "register_operand" "=r"))]
8756   "TARGET_TLS && TARGET_ARCH64"
8757   "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8758   [(set_attr "type" "store")])
8760 (define_insn "*tldo_sth_sp32"
8761   [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8762                                      (match_operand 3 "tld_symbolic_operand" "")]
8763                                     UNSPEC_TLSLDO)
8764                          (match_operand:SI 1 "register_operand" "r")))
8765         (match_operand:HI 0 "register_operand" "=r"))]
8766   "TARGET_TLS && TARGET_ARCH32"
8767   "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8768   [(set_attr "type" "store")])
8770 (define_insn "*tldo_sth_sp64"
8771   [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8772                                      (match_operand 3 "tld_symbolic_operand" "")]
8773                                     UNSPEC_TLSLDO)
8774                          (match_operand:DI 1 "register_operand" "r")))
8775         (match_operand:HI 0 "register_operand" "=r"))]
8776   "TARGET_TLS && TARGET_ARCH64"
8777   "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8778   [(set_attr "type" "store")])
8780 (define_insn "*tldo_stw_sp32"
8781   [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8782                                      (match_operand 3 "tld_symbolic_operand" "")]
8783                                     UNSPEC_TLSLDO)
8784                          (match_operand:SI 1 "register_operand" "r")))
8785         (match_operand:SI 0 "register_operand" "=r"))]
8786   "TARGET_TLS && TARGET_ARCH32"
8787   "st\t%0, [%1 + %2], %%tldo_add(%3)"
8788   [(set_attr "type" "store")])
8790 (define_insn "*tldo_stw_sp64"
8791   [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8792                                      (match_operand 3 "tld_symbolic_operand" "")]
8793                                     UNSPEC_TLSLDO)
8794                          (match_operand:DI 1 "register_operand" "r")))
8795         (match_operand:SI 0 "register_operand" "=r"))]
8796   "TARGET_TLS && TARGET_ARCH64"
8797   "stw\t%0, [%1 + %2], %%tldo_add(%3)"
8798   [(set_attr "type" "store")])
8800 (define_insn "*tldo_stx_sp64"
8801   [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8802                                      (match_operand 3 "tld_symbolic_operand" "")]
8803                                     UNSPEC_TLSLDO)
8804                          (match_operand:DI 1 "register_operand" "r")))
8805         (match_operand:DI 0 "register_operand" "=r"))]
8806   "TARGET_TLS && TARGET_ARCH64"
8807   "stx\t%0, [%1 + %2], %%tldo_add(%3)"
8808   [(set_attr "type" "store")])