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