* config/ia64/ia64.md: Define new attribute "empty".
[official-gcc.git] / gcc / config / sparc / sparc.md
blob7f6c3fbead0eae5f71c3da497316e9dfa4cb1088
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_GET_PC               2)
31    (UNSPEC_MOVE_PIC_LABEL       5)
32    (UNSPEC_SETH44               6)
33    (UNSPEC_SETM44               7)
34    (UNSPEC_SETHH                9)
35    (UNSPEC_SETLM                10)
36    (UNSPEC_EMB_HISUM            11)
37    (UNSPEC_EMB_TEXTUHI          13)
38    (UNSPEC_EMB_TEXTHI           14)
39    (UNSPEC_EMB_TEXTULO          15)
40    (UNSPEC_EMB_SETHM            18)
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 program counter insns.
1669 (define_insn "get_pc"
1670   [(clobber (reg:SI 15))
1671    (set (match_operand 0 "register_operand" "=r")
1672         (unspec [(match_operand 1 "" "") (match_operand 2 "" "")] UNSPEC_GET_PC))]
1673   "flag_pic && REGNO (operands[0]) == 23"
1674   "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\tadd\t%0, %%lo(%a1+4), %0"
1675   [(set_attr "type" "multi")
1676    (set_attr "length" "3")])
1679 ;; Move instructions
1681 (define_expand "movqi"
1682   [(set (match_operand:QI 0 "general_operand" "")
1683         (match_operand:QI 1 "general_operand" ""))]
1684   ""
1686   /* Working with CONST_INTs is easier, so convert
1687      a double if needed.  */
1688   if (GET_CODE (operands[1]) == CONST_DOUBLE)
1689     {
1690       operands[1] = GEN_INT (trunc_int_for_mode
1691                              (CONST_DOUBLE_LOW (operands[1]), QImode));
1692     }
1694   /* Handle sets of MEM first.  */
1695   if (GET_CODE (operands[0]) == MEM)
1696     {
1697       if (reg_or_0_operand (operands[1], QImode))
1698         goto movqi_is_ok;
1700       if (! reload_in_progress)
1701         {
1702           operands[0] = validize_mem (operands[0]);
1703           operands[1] = force_reg (QImode, operands[1]);
1704         }
1705     }
1707   /* Fixup TLS cases.  */
1708   if (tls_symbolic_operand (operands [1]))
1709     operands[1] = legitimize_tls_address (operands[1]);
1711   /* Fixup PIC cases.  */
1712   if (flag_pic)
1713     {
1714       if (CONSTANT_P (operands[1])
1715           && pic_address_needs_scratch (operands[1]))
1716         operands[1] = legitimize_pic_address (operands[1], QImode, 0);
1718       if (symbolic_operand (operands[1], QImode))
1719         {
1720           operands[1] = legitimize_pic_address (operands[1],
1721                                                 QImode,
1722                                                 (reload_in_progress ?
1723                                                  operands[0] :
1724                                                  NULL_RTX));
1725           goto movqi_is_ok;
1726         }
1727     }
1729   /* All QI constants require only one insn, so proceed.  */
1731  movqi_is_ok:
1732   ;
1735 (define_insn "*movqi_insn"
1736   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1737         (match_operand:QI 1 "input_operand"   "rI,m,rJ"))]
1738   "(register_operand (operands[0], QImode)
1739     || reg_or_0_operand (operands[1], QImode))"
1740   "@
1741    mov\t%1, %0
1742    ldub\t%1, %0
1743    stb\t%r1, %0"
1744   [(set_attr "type" "*,load,store")
1745    (set_attr "us3load_type" "*,3cycle,*")])
1747 (define_expand "movhi"
1748   [(set (match_operand:HI 0 "general_operand" "")
1749         (match_operand:HI 1 "general_operand" ""))]
1750   ""
1752   /* Working with CONST_INTs is easier, so convert
1753      a double if needed.  */
1754   if (GET_CODE (operands[1]) == CONST_DOUBLE)
1755     operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
1757   /* Handle sets of MEM first.  */
1758   if (GET_CODE (operands[0]) == MEM)
1759     {
1760       if (reg_or_0_operand (operands[1], HImode))
1761         goto movhi_is_ok;
1763       if (! reload_in_progress)
1764         {
1765           operands[0] = validize_mem (operands[0]);
1766           operands[1] = force_reg (HImode, operands[1]);
1767         }
1768     }
1770   /* Fixup TLS cases.  */
1771   if (tls_symbolic_operand (operands [1]))
1772     operands[1] = legitimize_tls_address (operands[1]);
1774   /* Fixup PIC cases.  */
1775   if (flag_pic)
1776     {
1777       if (CONSTANT_P (operands[1])
1778           && pic_address_needs_scratch (operands[1]))
1779         operands[1] = legitimize_pic_address (operands[1], HImode, 0);
1781       if (symbolic_operand (operands[1], HImode))
1782         {
1783           operands[1] = legitimize_pic_address (operands[1],
1784                                                 HImode,
1785                                                 (reload_in_progress ?
1786                                                  operands[0] :
1787                                                  NULL_RTX));
1788           goto movhi_is_ok;
1789         }
1790     }
1792   /* This makes sure we will not get rematched due to splittage.  */
1793   if (! CONSTANT_P (operands[1]) || input_operand (operands[1], HImode))
1794     ;
1795   else if (CONSTANT_P (operands[1])
1796            && GET_CODE (operands[1]) != HIGH
1797            && GET_CODE (operands[1]) != LO_SUM)
1798     {
1799       sparc_emit_set_const32 (operands[0], operands[1]);
1800       DONE;
1801     }
1802  movhi_is_ok:
1803   ;
1806 (define_insn "*movhi_const64_special"
1807   [(set (match_operand:HI 0 "register_operand" "=r")
1808         (match_operand:HI 1 "const64_high_operand" ""))]
1809   "TARGET_ARCH64"
1810   "sethi\t%%hi(%a1), %0")
1812 (define_insn "*movhi_insn"
1813   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1814         (match_operand:HI 1 "input_operand"   "rI,K,m,rJ"))]
1815   "(register_operand (operands[0], HImode)
1816     || reg_or_0_operand (operands[1], HImode))"
1817   "@
1818    mov\t%1, %0
1819    sethi\t%%hi(%a1), %0
1820    lduh\t%1, %0
1821    sth\t%r1, %0"
1822   [(set_attr "type" "*,*,load,store")
1823    (set_attr "us3load_type" "*,*,3cycle,*")])
1825 ;; We always work with constants here.
1826 (define_insn "*movhi_lo_sum"
1827   [(set (match_operand:HI 0 "register_operand" "=r")
1828         (ior:HI (match_operand:HI 1 "register_operand" "%r")
1829                 (match_operand:HI 2 "small_int" "I")))]
1830   ""
1831   "or\t%1, %2, %0")
1833 (define_expand "movsi"
1834   [(set (match_operand:SI 0 "general_operand" "")
1835         (match_operand:SI 1 "general_operand" ""))]
1836   ""
1838   /* Working with CONST_INTs is easier, so convert
1839      a double if needed.  */
1840   if (GET_CODE (operands[1]) == CONST_DOUBLE)
1841     operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
1843   /* Handle sets of MEM first.  */
1844   if (GET_CODE (operands[0]) == MEM)
1845     {
1846       if (reg_or_0_operand (operands[1], SImode))
1847         goto movsi_is_ok;
1849       if (! reload_in_progress)
1850         {
1851           operands[0] = validize_mem (operands[0]);
1852           operands[1] = force_reg (SImode, operands[1]);
1853         }
1854     }
1856   /* Fixup TLS cases.  */
1857   if (tls_symbolic_operand (operands [1]))
1858     operands[1] = legitimize_tls_address (operands[1]);
1860   /* Fixup PIC cases.  */
1861   if (flag_pic)
1862     {
1863       if (CONSTANT_P (operands[1])
1864           && pic_address_needs_scratch (operands[1]))
1865         operands[1] = legitimize_pic_address (operands[1], SImode, 0);
1867       if (GET_CODE (operands[1]) == LABEL_REF)
1868         {
1869           /* shit */
1870           emit_insn (gen_movsi_pic_label_ref (operands[0], operands[1]));
1871           DONE;
1872         }
1874       if (symbolic_operand (operands[1], SImode))
1875         {
1876           operands[1] = legitimize_pic_address (operands[1],
1877                                                 SImode,
1878                                                 (reload_in_progress ?
1879                                                  operands[0] :
1880                                                  NULL_RTX));
1881           goto movsi_is_ok;
1882         }
1883     }
1885   /* If we are trying to toss an integer constant into the
1886      FPU registers, force it into memory.  */
1887   if (GET_CODE (operands[0]) == REG
1888       && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
1889       && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
1890       && CONSTANT_P (operands[1]))
1891     operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
1892                                                  operands[1]));
1894   /* This makes sure we will not get rematched due to splittage.  */
1895   if (! CONSTANT_P (operands[1]) || input_operand (operands[1], SImode))
1896     ;
1897   else if (CONSTANT_P (operands[1])
1898            && GET_CODE (operands[1]) != HIGH
1899            && GET_CODE (operands[1]) != LO_SUM)
1900     {
1901       sparc_emit_set_const32 (operands[0], operands[1]);
1902       DONE;
1903     }
1904  movsi_is_ok:
1905   ;
1908 ;; This is needed to show CSE exactly which bits are set
1909 ;; in a 64-bit register by sethi instructions.
1910 (define_insn "*movsi_const64_special"
1911   [(set (match_operand:SI 0 "register_operand" "=r")
1912         (match_operand:SI 1 "const64_high_operand" ""))]
1913   "TARGET_ARCH64"
1914   "sethi\t%%hi(%a1), %0")
1916 (define_insn "*movsi_insn"
1917   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,f,r,r,r,f,m,m,d")
1918         (match_operand:SI 1 "input_operand"   "rI,!f,K,J,m,!m,rJ,!f,J"))]
1919   "(register_operand (operands[0], SImode)
1920     || reg_or_0_operand (operands[1], SImode))"
1921   "@
1922    mov\t%1, %0
1923    fmovs\t%1, %0
1924    sethi\t%%hi(%a1), %0
1925    clr\t%0
1926    ld\t%1, %0
1927    ld\t%1, %0
1928    st\t%r1, %0
1929    st\t%1, %0
1930    fzeros\t%0"
1931   [(set_attr "type" "*,fpmove,*,*,load,fpload,store,fpstore,fga")])
1933 (define_insn "*movsi_lo_sum"
1934   [(set (match_operand:SI 0 "register_operand" "=r")
1935         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1936                    (match_operand:SI 2 "immediate_operand" "in")))]
1937   ""
1938   "or\t%1, %%lo(%a2), %0")
1940 (define_insn "*movsi_high"
1941   [(set (match_operand:SI 0 "register_operand" "=r")
1942         (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1943   ""
1944   "sethi\t%%hi(%a1), %0")
1946 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1947 ;; so that CSE won't optimize the address computation away.
1948 (define_insn "movsi_lo_sum_pic"
1949   [(set (match_operand:SI 0 "register_operand" "=r")
1950         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1951                    (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1952   "flag_pic"
1953   "or\t%1, %%lo(%a2), %0")
1955 (define_insn "movsi_high_pic"
1956   [(set (match_operand:SI 0 "register_operand" "=r")
1957         (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1958   "flag_pic && check_pic (1)"
1959   "sethi\t%%hi(%a1), %0")
1961 (define_expand "movsi_pic_label_ref"
1962   [(set (match_dup 3) (high:SI
1963      (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1964                  (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1965    (set (match_dup 4) (lo_sum:SI (match_dup 3)
1966      (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1967    (set (match_operand:SI 0 "register_operand" "=r")
1968         (minus:SI (match_dup 5) (match_dup 4)))]
1969   "flag_pic"
1971   current_function_uses_pic_offset_table = 1;
1972   operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1973   if (no_new_pseudos)
1974     {
1975       operands[3] = operands[0];
1976       operands[4] = operands[0];
1977     }
1978   else
1979     {
1980       operands[3] = gen_reg_rtx (SImode);
1981       operands[4] = gen_reg_rtx (SImode);
1982     }
1983   operands[5] = pic_offset_table_rtx;
1986 (define_insn "*movsi_high_pic_label_ref"
1987   [(set (match_operand:SI 0 "register_operand" "=r")
1988       (high:SI
1989         (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1990                     (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1991   "flag_pic"
1992   "sethi\t%%hi(%a2-(%a1-.)), %0")
1994 (define_insn "*movsi_lo_sum_pic_label_ref"
1995   [(set (match_operand:SI 0 "register_operand" "=r")
1996       (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1997         (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
1998                     (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1999   "flag_pic"
2000   "or\t%1, %%lo(%a3-(%a2-.)), %0")
2002 (define_expand "movdi"
2003   [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
2004         (match_operand:DI 1 "general_operand" ""))]
2005   ""
2007   /* Where possible, convert CONST_DOUBLE into a CONST_INT.  */
2008   if (GET_CODE (operands[1]) == CONST_DOUBLE
2009 #if HOST_BITS_PER_WIDE_INT == 32
2010       && ((CONST_DOUBLE_HIGH (operands[1]) == 0
2011            && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) == 0)
2012           || (CONST_DOUBLE_HIGH (operands[1]) == (HOST_WIDE_INT) 0xffffffff
2013               && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) != 0))
2014 #endif
2015       )
2016     operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2018   /* Handle MEM cases first.  */
2019   if (GET_CODE (operands[0]) == MEM)
2020     {
2021       /* If it's a REG, we can always do it.
2022          The const zero case is more complex, on v9
2023          we can always perform it.  */
2024       if (register_operand (operands[1], DImode)
2025           || (TARGET_V9
2026               && (operands[1] == const0_rtx)))
2027         goto movdi_is_ok;
2029       if (! reload_in_progress)
2030         {
2031           operands[0] = validize_mem (operands[0]);
2032           operands[1] = force_reg (DImode, operands[1]);
2033         }
2034     }
2036   /* Fixup TLS cases.  */
2037   if (tls_symbolic_operand (operands [1]))
2038     operands[1] = legitimize_tls_address (operands[1]);
2040   if (flag_pic)
2041     {
2042       if (CONSTANT_P (operands[1])
2043           && pic_address_needs_scratch (operands[1]))
2044         operands[1] = legitimize_pic_address (operands[1], DImode, 0);
2046       if (GET_CODE (operands[1]) == LABEL_REF)
2047         {
2048           if (! TARGET_ARCH64)
2049             abort ();
2050           emit_insn (gen_movdi_pic_label_ref (operands[0], operands[1]));
2051           DONE;
2052         }
2054       if (symbolic_operand (operands[1], DImode))
2055         {
2056           operands[1] = legitimize_pic_address (operands[1],
2057                                                 DImode,
2058                                                 (reload_in_progress ?
2059                                                  operands[0] :
2060                                                  NULL_RTX));
2061           goto movdi_is_ok;
2062         }
2063     }
2065   /* If we are trying to toss an integer constant into the
2066      FPU registers, force it into memory.  */
2067   if (GET_CODE (operands[0]) == REG
2068       && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
2069       && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
2070       && CONSTANT_P (operands[1]))
2071     operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2072                                                  operands[1]));
2074   /* This makes sure we will not get rematched due to splittage.  */
2075   if (! CONSTANT_P (operands[1]) || input_operand (operands[1], DImode))
2076     ;
2077   else if (TARGET_ARCH64
2078            && CONSTANT_P (operands[1])
2079            && GET_CODE (operands[1]) != HIGH
2080            && GET_CODE (operands[1]) != LO_SUM)
2081     {
2082       sparc_emit_set_const64 (operands[0], operands[1]);
2083       DONE;
2084     }
2086  movdi_is_ok:
2087   ;
2090 ;; Be careful, fmovd does not exist when !v9.
2091 ;; We match MEM moves directly when we have correct even
2092 ;; numbered registers, but fall into splits otherwise.
2093 ;; The constraint ordering here is really important to
2094 ;; avoid insane problems in reload, especially for patterns
2095 ;; of the form:
2097 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
2098 ;;                       (const_int -5016)))
2099 ;;      (reg:DI 2 %g2))
2102 (define_insn "*movdi_insn_sp32_v9"
2103   [(set (match_operand:DI 0 "nonimmediate_operand"
2104                                         "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?e,?e,?W")
2105         (match_operand:DI 1 "input_operand"
2106                                         " J,J,U,T,r,o,i,r, f, T, o, f, e, W, e"))]
2107   "! TARGET_ARCH64 && TARGET_V9
2108    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2109   "@
2110    stx\t%%g0, %0
2111    #
2112    std\t%1, %0
2113    ldd\t%1, %0
2114    #
2115    #
2116    #
2117    #
2118    std\t%1, %0
2119    ldd\t%1, %0
2120    #
2121    #
2122    fmovd\\t%1, %0
2123    ldd\\t%1, %0
2124    std\\t%1, %0"
2125   [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,fpload,fpstore")
2126    (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,*,*")
2127    (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])
2129 (define_insn "*movdi_insn_sp32"
2130   [(set (match_operand:DI 0 "nonimmediate_operand"
2131                                 "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
2132         (match_operand:DI 1 "input_operand"
2133                                 " J,U,T,r,o,i,r, f, T, o, f, f"))]
2134   "! TARGET_ARCH64
2135    && (register_operand (operands[0], DImode)
2136        || register_operand (operands[1], DImode))"
2137   "@
2138    #
2139    std\t%1, %0
2140    ldd\t%1, %0
2141    #
2142    #
2143    #
2144    #
2145    std\t%1, %0
2146    ldd\t%1, %0
2147    #
2148    #
2149    #"
2150   [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
2151    (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
2153 ;; The following are generated by sparc_emit_set_const64
2154 (define_insn "*movdi_sp64_dbl"
2155   [(set (match_operand:DI 0 "register_operand" "=r")
2156         (match_operand:DI 1 "const64_operand" ""))]
2157   "(TARGET_ARCH64
2158     && HOST_BITS_PER_WIDE_INT != 64)"
2159   "mov\t%1, %0")
2161 ;; This is needed to show CSE exactly which bits are set
2162 ;; in a 64-bit register by sethi instructions.
2163 (define_insn "*movdi_const64_special"
2164   [(set (match_operand:DI 0 "register_operand" "=r")
2165         (match_operand:DI 1 "const64_high_operand" ""))]
2166   "TARGET_ARCH64"
2167   "sethi\t%%hi(%a1), %0")
2169 (define_insn "*movdi_insn_sp64_novis"
2170   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?W")
2171         (match_operand:DI 1 "input_operand"   "rI,N,J,m,rJ,e,W,e"))]
2172   "TARGET_ARCH64 && ! TARGET_VIS
2173    && (register_operand (operands[0], DImode)
2174        || reg_or_0_operand (operands[1], DImode))"
2175   "@
2176    mov\t%1, %0
2177    sethi\t%%hi(%a1), %0
2178    clr\t%0
2179    ldx\t%1, %0
2180    stx\t%r1, %0
2181    fmovd\t%1, %0
2182    ldd\t%1, %0
2183    std\t%1, %0"
2184   [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore")
2185    (set_attr "fptype" "*,*,*,*,*,double,*,*")])
2187 (define_insn "*movdi_insn_sp64_vis"
2188   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?W,b")
2189         (match_operand:DI 1 "input_operand"   "rI,N,J,m,rJ,e,W,e,J"))]
2190   "TARGET_ARCH64 && TARGET_VIS &&
2191    (register_operand (operands[0], DImode)
2192     || reg_or_0_operand (operands[1], DImode))"
2193   "@
2194    mov\t%1, %0
2195    sethi\t%%hi(%a1), %0
2196    clr\t%0
2197    ldx\t%1, %0
2198    stx\t%r1, %0
2199    fmovd\t%1, %0
2200    ldd\t%1, %0
2201    std\t%1, %0
2202    fzero\t%0"
2203   [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore,fga")
2204    (set_attr "fptype" "*,*,*,*,*,double,*,*,double")])
2206 (define_expand "movdi_pic_label_ref"
2207   [(set (match_dup 3) (high:DI
2208      (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2209                  (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2210    (set (match_dup 4) (lo_sum:DI (match_dup 3)
2211      (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2212    (set (match_operand:DI 0 "register_operand" "=r")
2213         (minus:DI (match_dup 5) (match_dup 4)))]
2214   "TARGET_ARCH64 && flag_pic"
2216   current_function_uses_pic_offset_table = 1;
2217   operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
2218   if (no_new_pseudos)
2219     {
2220       operands[3] = operands[0];
2221       operands[4] = operands[0];
2222     }
2223   else
2224     {
2225       operands[3] = gen_reg_rtx (DImode);
2226       operands[4] = gen_reg_rtx (DImode);
2227     }
2228   operands[5] = pic_offset_table_rtx;
2231 (define_insn "*movdi_high_pic_label_ref"
2232   [(set (match_operand:DI 0 "register_operand" "=r")
2233         (high:DI
2234           (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2235                       (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2236   "TARGET_ARCH64 && flag_pic"
2237   "sethi\t%%hi(%a2-(%a1-.)), %0")
2239 (define_insn "*movdi_lo_sum_pic_label_ref"
2240   [(set (match_operand:DI 0 "register_operand" "=r")
2241       (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2242         (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
2243                     (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2244   "TARGET_ARCH64 && flag_pic"
2245   "or\t%1, %%lo(%a3-(%a2-.)), %0")
2247 ;; SPARC-v9 code model support insns.  See sparc_emit_set_symbolic_const64
2248 ;; in sparc.c to see what is going on here... PIC stuff comes first.
2250 (define_insn "movdi_lo_sum_pic"
2251   [(set (match_operand:DI 0 "register_operand" "=r")
2252         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2253                    (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
2254   "TARGET_ARCH64 && flag_pic"
2255   "or\t%1, %%lo(%a2), %0")
2257 (define_insn "movdi_high_pic"
2258   [(set (match_operand:DI 0 "register_operand" "=r")
2259         (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
2260   "TARGET_ARCH64 && flag_pic && check_pic (1)"
2261   "sethi\t%%hi(%a1), %0")
2263 (define_insn "*sethi_di_medlow_embmedany_pic"
2264   [(set (match_operand:DI 0 "register_operand" "=r")
2265         (high:DI (match_operand:DI 1 "sp64_medium_pic_operand" "")))]
2266   "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
2267   "sethi\t%%hi(%a1), %0")
2269 (define_insn "*sethi_di_medlow"
2270   [(set (match_operand:DI 0 "register_operand" "=r")
2271         (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
2272   "TARGET_CM_MEDLOW && check_pic (1)"
2273   "sethi\t%%hi(%a1), %0")
2275 (define_insn "*losum_di_medlow"
2276   [(set (match_operand:DI 0 "register_operand" "=r")
2277         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2278                    (match_operand:DI 2 "symbolic_operand" "")))]
2279   "TARGET_CM_MEDLOW"
2280   "or\t%1, %%lo(%a2), %0")
2282 (define_insn "seth44"
2283   [(set (match_operand:DI 0 "register_operand" "=r")
2284         (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
2285   "TARGET_CM_MEDMID"
2286   "sethi\t%%h44(%a1), %0")
2288 (define_insn "setm44"
2289   [(set (match_operand:DI 0 "register_operand" "=r")
2290         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2291                    (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
2292   "TARGET_CM_MEDMID"
2293   "or\t%1, %%m44(%a2), %0")
2295 (define_insn "setl44"
2296   [(set (match_operand:DI 0 "register_operand" "=r")
2297         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2298                    (match_operand:DI 2 "symbolic_operand" "")))]
2299   "TARGET_CM_MEDMID"
2300   "or\t%1, %%l44(%a2), %0")
2302 (define_insn "sethh"
2303   [(set (match_operand:DI 0 "register_operand" "=r")
2304         (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
2305   "TARGET_CM_MEDANY"
2306   "sethi\t%%hh(%a1), %0")
2308 (define_insn "setlm"
2309   [(set (match_operand:DI 0 "register_operand" "=r")
2310         (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
2311   "TARGET_CM_MEDANY"
2312   "sethi\t%%lm(%a1), %0")
2314 (define_insn "sethm"
2315   [(set (match_operand:DI 0 "register_operand" "=r")
2316         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2317                    (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
2318   "TARGET_CM_MEDANY"
2319   "or\t%1, %%hm(%a2), %0")
2321 (define_insn "setlo"
2322   [(set (match_operand:DI 0 "register_operand" "=r")
2323         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2324                    (match_operand:DI 2 "symbolic_operand" "")))]
2325   "TARGET_CM_MEDANY"
2326   "or\t%1, %%lo(%a2), %0")
2328 (define_insn "embmedany_sethi"
2329   [(set (match_operand:DI 0 "register_operand" "=r")
2330         (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
2331   "TARGET_CM_EMBMEDANY && check_pic (1)"
2332   "sethi\t%%hi(%a1), %0")
2334 (define_insn "embmedany_losum"
2335   [(set (match_operand:DI 0 "register_operand" "=r")
2336         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2337                    (match_operand:DI 2 "data_segment_operand" "")))]
2338   "TARGET_CM_EMBMEDANY"
2339   "add\t%1, %%lo(%a2), %0")
2341 (define_insn "embmedany_brsum"
2342   [(set (match_operand:DI 0 "register_operand" "=r")
2343         (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
2344   "TARGET_CM_EMBMEDANY"
2345   "add\t%1, %_, %0")
2347 (define_insn "embmedany_textuhi"
2348   [(set (match_operand:DI 0 "register_operand" "=r")
2349         (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
2350   "TARGET_CM_EMBMEDANY && check_pic (1)"
2351   "sethi\t%%uhi(%a1), %0")
2353 (define_insn "embmedany_texthi"
2354   [(set (match_operand:DI 0 "register_operand" "=r")
2355         (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
2356   "TARGET_CM_EMBMEDANY && check_pic (1)"
2357   "sethi\t%%hi(%a1), %0")
2359 (define_insn "embmedany_textulo"
2360   [(set (match_operand:DI 0 "register_operand" "=r")
2361         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2362                    (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
2363   "TARGET_CM_EMBMEDANY"
2364   "or\t%1, %%ulo(%a2), %0")
2366 (define_insn "embmedany_textlo"
2367   [(set (match_operand:DI 0 "register_operand" "=r")
2368         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2369                    (match_operand:DI 2 "text_segment_operand" "")))]
2370   "TARGET_CM_EMBMEDANY"
2371   "or\t%1, %%lo(%a2), %0")
2373 ;; Now some patterns to help reload out a bit.
2374 (define_expand "reload_indi"
2375   [(parallel [(match_operand:DI 0 "register_operand" "=r")
2376               (match_operand:DI 1 "immediate_operand" "")
2377               (match_operand:TI 2 "register_operand" "=&r")])]
2378   "(TARGET_CM_MEDANY
2379     || TARGET_CM_EMBMEDANY)
2380    && ! flag_pic"
2382   sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2383   DONE;
2386 (define_expand "reload_outdi"
2387   [(parallel [(match_operand:DI 0 "register_operand" "=r")
2388               (match_operand:DI 1 "immediate_operand" "")
2389               (match_operand:TI 2 "register_operand" "=&r")])]
2390   "(TARGET_CM_MEDANY
2391     || TARGET_CM_EMBMEDANY)
2392    && ! flag_pic"
2394   sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2395   DONE;
2398 ;; Split up putting CONSTs and REGs into DI regs when !arch64
2399 (define_split
2400   [(set (match_operand:DI 0 "register_operand" "")
2401         (match_operand:DI 1 "const_int_operand" ""))]
2402   "! TARGET_ARCH64 && reload_completed"
2403   [(clobber (const_int 0))]
2405 #if HOST_BITS_PER_WIDE_INT == 32
2406   emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2407                         (INTVAL (operands[1]) < 0) ?
2408                         constm1_rtx :
2409                         const0_rtx));
2410   emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2411                         operands[1]));
2412 #else
2413   unsigned int low, high;
2415   low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
2416   high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
2417   emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
2419   /* Slick... but this trick loses if this subreg constant part
2420      can be done in one insn.  */
2421   if (low == high && (low & 0x3ff) != 0 && low + 0x1000 >= 0x2000)
2422     emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2423                           gen_highpart (SImode, operands[0])));
2424   else
2425     emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
2426 #endif
2427   DONE;
2430 (define_split
2431   [(set (match_operand:DI 0 "register_operand" "")
2432         (match_operand:DI 1 "const_double_operand" ""))]
2433   "reload_completed
2434    && (! TARGET_V9
2435        || (! TARGET_ARCH64
2436            && ((GET_CODE (operands[0]) == REG
2437                 && REGNO (operands[0]) < 32)
2438                || (GET_CODE (operands[0]) == SUBREG
2439                    && GET_CODE (SUBREG_REG (operands[0])) == REG
2440                    && REGNO (SUBREG_REG (operands[0])) < 32))))"
2441   [(clobber (const_int 0))]
2443   emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2444                         GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
2446   /* Slick... but this trick loses if this subreg constant part
2447      can be done in one insn.  */
2448   if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
2449       && !(SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
2450            || SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1]))))
2451     {
2452       emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2453                             gen_highpart (SImode, operands[0])));
2454     }
2455   else
2456     {
2457       emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2458                             GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
2459     }
2460   DONE;
2463 (define_split
2464   [(set (match_operand:DI 0 "register_operand" "")
2465         (match_operand:DI 1 "register_operand" ""))]
2466   "reload_completed
2467    && (! TARGET_V9
2468        || (! TARGET_ARCH64
2469            && ((GET_CODE (operands[0]) == REG
2470                 && REGNO (operands[0]) < 32)
2471                || (GET_CODE (operands[0]) == SUBREG
2472                    && GET_CODE (SUBREG_REG (operands[0])) == REG
2473                    && REGNO (SUBREG_REG (operands[0])) < 32))))"
2474   [(clobber (const_int 0))]
2476   rtx set_dest = operands[0];
2477   rtx set_src = operands[1];
2478   rtx dest1, dest2;
2479   rtx src1, src2;
2481   dest1 = gen_highpart (SImode, set_dest);
2482   dest2 = gen_lowpart (SImode, set_dest);
2483   src1 = gen_highpart (SImode, set_src);
2484   src2 = gen_lowpart (SImode, set_src);
2486   /* Now emit using the real source and destination we found, swapping
2487      the order if we detect overlap.  */
2488   if (reg_overlap_mentioned_p (dest1, src2))
2489     {
2490       emit_insn (gen_movsi (dest2, src2));
2491       emit_insn (gen_movsi (dest1, src1));
2492     }
2493   else
2494     {
2495       emit_insn (gen_movsi (dest1, src1));
2496       emit_insn (gen_movsi (dest2, src2));
2497     }
2498   DONE;
2501 ;; Now handle the cases of memory moves from/to non-even
2502 ;; DI mode register pairs.
2503 (define_split
2504   [(set (match_operand:DI 0 "register_operand" "")
2505         (match_operand:DI 1 "memory_operand" ""))]
2506   "(! TARGET_ARCH64
2507     && reload_completed
2508     && sparc_splitdi_legitimate (operands[0], operands[1]))"
2509   [(clobber (const_int 0))]
2511   rtx word0 = adjust_address (operands[1], SImode, 0);
2512   rtx word1 = adjust_address (operands[1], SImode, 4);
2513   rtx high_part = gen_highpart (SImode, operands[0]);
2514   rtx low_part = gen_lowpart (SImode, operands[0]);
2516   if (reg_overlap_mentioned_p (high_part, word1))
2517     {
2518       emit_insn (gen_movsi (low_part, word1));
2519       emit_insn (gen_movsi (high_part, word0));
2520     }
2521   else
2522     {
2523       emit_insn (gen_movsi (high_part, word0));
2524       emit_insn (gen_movsi (low_part, word1));
2525     }
2526   DONE;
2529 (define_split
2530   [(set (match_operand:DI 0 "memory_operand" "")
2531         (match_operand:DI 1 "register_operand" ""))]
2532   "(! TARGET_ARCH64
2533     && reload_completed
2534     && sparc_splitdi_legitimate (operands[1], operands[0]))"
2535   [(clobber (const_int 0))]
2537   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
2538                         gen_highpart (SImode, operands[1])));
2539   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
2540                         gen_lowpart (SImode, operands[1])));
2541   DONE;
2544 (define_split
2545   [(set (match_operand:DI 0 "memory_operand" "")
2546         (const_int 0))]
2547   "reload_completed
2548    && (! TARGET_V9
2549        || (! TARGET_ARCH64
2550            && ! mem_min_alignment (operands[0], 8)))
2551    && offsettable_memref_p (operands[0])"
2552   [(clobber (const_int 0))]
2554   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
2555   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
2556   DONE;
2559 ;; Floating point move insns
2561 (define_insn "*movsf_insn_novis"
2562   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,*r,*r,*r,*r,*r,f,m,m")
2563         (match_operand:SF 1 "input_operand"         "f,G,Q,*rR,S,m,m,f,*rG"))]
2564   "(TARGET_FPU && ! TARGET_VIS)
2565    && (register_operand (operands[0], SFmode)
2566        || register_operand (operands[1], SFmode)
2567        || fp_zero_operand (operands[1], SFmode))"
2569   if (GET_CODE (operands[1]) == CONST_DOUBLE
2570       && (which_alternative == 2
2571           || which_alternative == 3
2572           || which_alternative == 4))
2573     {
2574       REAL_VALUE_TYPE r;
2575       long i;
2577       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2578       REAL_VALUE_TO_TARGET_SINGLE (r, i);
2579       operands[1] = GEN_INT (i);
2580     }
2582   switch (which_alternative)
2583     {
2584     case 0:
2585       return "fmovs\t%1, %0";
2586     case 1:
2587       return "clr\t%0";
2588     case 2:
2589       return "sethi\t%%hi(%a1), %0";
2590     case 3:
2591       return "mov\t%1, %0";
2592     case 4:
2593       return "#";
2594     case 5:
2595     case 6:
2596       return "ld\t%1, %0";
2597     case 7:
2598     case 8:
2599       return "st\t%r1, %0";
2600     default:
2601       abort();
2602     }
2604   [(set_attr "type" "fpmove,*,*,*,*,load,fpload,fpstore,store")])
2606 (define_insn "*movsf_insn_vis"
2607   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,*r,*r,*r,*r,*r,f,m,m")
2608         (match_operand:SF 1 "input_operand"         "f,G,G,Q,*rR,S,m,m,f,*rG"))]
2609   "(TARGET_FPU && TARGET_VIS)
2610    && (register_operand (operands[0], SFmode)
2611        || register_operand (operands[1], SFmode)
2612        || fp_zero_operand (operands[1], SFmode))"
2614   if (GET_CODE (operands[1]) == CONST_DOUBLE
2615       && (which_alternative == 3
2616           || which_alternative == 4
2617           || which_alternative == 5))
2618     {
2619       REAL_VALUE_TYPE r;
2620       long i;
2622       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2623       REAL_VALUE_TO_TARGET_SINGLE (r, i);
2624       operands[1] = GEN_INT (i);
2625     }
2627   switch (which_alternative)
2628     {
2629     case 0:
2630       return "fmovs\t%1, %0";
2631     case 1:
2632       return "fzeros\t%0";
2633     case 2:
2634       return "clr\t%0";
2635     case 3:
2636       return "sethi\t%%hi(%a1), %0";
2637     case 4:
2638       return "mov\t%1, %0";
2639     case 5:
2640       return "#";
2641     case 6:
2642     case 7:
2643       return "ld\t%1, %0";
2644     case 8:
2645     case 9:
2646       return "st\t%r1, %0";
2647     default:
2648       abort();
2649     }
2651   [(set_attr "type" "fpmove,fga,*,*,*,*,load,fpload,fpstore,store")])
2653 ;; Exactly the same as above, except that all `f' cases are deleted.
2654 ;; This is necessary to prevent reload from ever trying to use a `f' reg
2655 ;; when -mno-fpu.
2657 (define_insn "*movsf_no_f_insn"
2658   [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,r,m")
2659         (match_operand:SF 1 "input_operand"    "G,Q,rR,S,m,rG"))]
2660   "! TARGET_FPU
2661    && (register_operand (operands[0], SFmode)
2662        || register_operand (operands[1], SFmode)
2663        || fp_zero_operand (operands[1], SFmode))"
2665   if (GET_CODE (operands[1]) == CONST_DOUBLE
2666       && (which_alternative == 1
2667           || which_alternative == 2
2668           || which_alternative == 3))
2669     {
2670       REAL_VALUE_TYPE r;
2671       long i;
2673       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2674       REAL_VALUE_TO_TARGET_SINGLE (r, i);
2675       operands[1] = GEN_INT (i);
2676     }
2678   switch (which_alternative)
2679     {
2680     case 0:
2681       return "clr\t%0";
2682     case 1:
2683       return "sethi\t%%hi(%a1), %0";
2684     case 2:
2685       return "mov\t%1, %0";
2686     case 3:
2687       return "#";
2688     case 4:
2689       return "ld\t%1, %0";
2690     case 5:
2691       return "st\t%r1, %0";
2692     default:
2693       abort();
2694     }
2696   [(set_attr "type" "*,*,*,*,load,store")])
2698 (define_insn "*movsf_lo_sum"
2699   [(set (match_operand:SF 0 "register_operand" "=r")
2700         (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
2701                    (match_operand:SF 2 "const_double_operand" "S")))]
2702   "fp_high_losum_p (operands[2])"
2704   REAL_VALUE_TYPE r;
2705   long i;
2707   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
2708   REAL_VALUE_TO_TARGET_SINGLE (r, i);
2709   operands[2] = GEN_INT (i);
2710   return "or\t%1, %%lo(%a2), %0";
2713 (define_insn "*movsf_high"
2714   [(set (match_operand:SF 0 "register_operand" "=r")
2715         (high:SF (match_operand:SF 1 "const_double_operand" "S")))]
2716   "fp_high_losum_p (operands[1])"
2718   REAL_VALUE_TYPE r;
2719   long i;
2721   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2722   REAL_VALUE_TO_TARGET_SINGLE (r, i);
2723   operands[1] = GEN_INT (i);
2724   return "sethi\t%%hi(%1), %0";
2727 (define_split
2728   [(set (match_operand:SF 0 "register_operand" "")
2729         (match_operand:SF 1 "const_double_operand" ""))]
2730   "fp_high_losum_p (operands[1])
2731    && (GET_CODE (operands[0]) == REG
2732        && REGNO (operands[0]) < 32)"
2733   [(set (match_dup 0) (high:SF (match_dup 1)))
2734    (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
2736 (define_expand "movsf"
2737   [(set (match_operand:SF 0 "general_operand" "")
2738         (match_operand:SF 1 "general_operand" ""))]
2739   ""
2741   /* Force SFmode constants into memory.  */
2742   if (GET_CODE (operands[0]) == REG
2743       && CONSTANT_P (operands[1]))
2744     {
2745       /* emit_group_store will send such bogosity to us when it is
2746          not storing directly into memory.  So fix this up to avoid
2747          crashes in output_constant_pool.  */
2748       if (operands [1] == const0_rtx)
2749         operands[1] = CONST0_RTX (SFmode);
2751       if (TARGET_VIS && fp_zero_operand (operands[1], SFmode))
2752         goto movsf_is_ok;
2754       /* We are able to build any SF constant in integer registers
2755          with at most 2 instructions.  */
2756       if (REGNO (operands[0]) < 32)
2757         goto movsf_is_ok;
2759       operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2760                                                    operands[1]));
2761     }
2763   /* Handle sets of MEM first.  */
2764   if (GET_CODE (operands[0]) == MEM)
2765     {
2766       if (register_operand (operands[1], SFmode)
2767           || fp_zero_operand (operands[1], SFmode))
2768         goto movsf_is_ok;
2770       if (! reload_in_progress)
2771         {
2772           operands[0] = validize_mem (operands[0]);
2773           operands[1] = force_reg (SFmode, operands[1]);
2774         }
2775     }
2777   /* Fixup PIC cases.  */
2778   if (flag_pic)
2779     {
2780       if (CONSTANT_P (operands[1])
2781           && pic_address_needs_scratch (operands[1]))
2782         operands[1] = legitimize_pic_address (operands[1], SFmode, 0);
2784       if (symbolic_operand (operands[1], SFmode))
2785         {
2786           operands[1] = legitimize_pic_address (operands[1],
2787                                                 SFmode,
2788                                                 (reload_in_progress ?
2789                                                  operands[0] :
2790                                                  NULL_RTX));
2791         }
2792     }
2794  movsf_is_ok:
2795   ;
2798 (define_expand "movdf"
2799   [(set (match_operand:DF 0 "general_operand" "")
2800         (match_operand:DF 1 "general_operand" ""))]
2801   ""
2803   /* Force DFmode constants into memory.  */
2804   if (GET_CODE (operands[0]) == REG
2805       && CONSTANT_P (operands[1]))
2806     {
2807       /* emit_group_store will send such bogosity to us when it is
2808          not storing directly into memory.  So fix this up to avoid
2809          crashes in output_constant_pool.  */
2810       if (operands [1] == const0_rtx)
2811         operands[1] = CONST0_RTX (DFmode);
2813       if ((TARGET_VIS || REGNO (operands[0]) < 32)
2814           && fp_zero_operand (operands[1], DFmode))
2815         goto movdf_is_ok;
2817       /* We are able to build any DF constant in integer registers.  */
2818       if (REGNO (operands[0]) < 32
2819           && (reload_completed || reload_in_progress))
2820         goto movdf_is_ok;
2822       operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2823                                                    operands[1]));
2824     }
2826   /* Handle MEM cases first.  */
2827   if (GET_CODE (operands[0]) == MEM)
2828     {
2829       if (register_operand (operands[1], DFmode)
2830           || fp_zero_operand (operands[1], DFmode))
2831         goto movdf_is_ok;
2833       if (! reload_in_progress)
2834         {
2835           operands[0] = validize_mem (operands[0]);
2836           operands[1] = force_reg (DFmode, operands[1]);
2837         }
2838     }
2840   /* Fixup PIC cases.  */
2841   if (flag_pic)
2842     {
2843       if (CONSTANT_P (operands[1])
2844           && pic_address_needs_scratch (operands[1]))
2845         operands[1] = legitimize_pic_address (operands[1], DFmode, 0);
2847       if (symbolic_operand (operands[1], DFmode))
2848         {
2849           operands[1] = legitimize_pic_address (operands[1],
2850                                                 DFmode,
2851                                                 (reload_in_progress ?
2852                                                  operands[0] :
2853                                                  NULL_RTX));
2854         }
2855     }
2857  movdf_is_ok:
2858   ;
2861 ;; Be careful, fmovd does not exist when !v9.
2862 (define_insn "*movdf_insn_sp32"
2863   [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o")
2864         (match_operand:DF 1 "input_operand"    "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
2865   "TARGET_FPU
2866    && ! TARGET_V9
2867    && (register_operand (operands[0], DFmode)
2868        || register_operand (operands[1], DFmode)
2869        || fp_zero_operand (operands[1], DFmode))"
2870   "@
2871   ldd\t%1, %0
2872   std\t%1, %0
2873   ldd\t%1, %0
2874   std\t%1, %0
2875   #
2876   #
2877   #
2878   #
2879   #
2880   #"
2881  [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
2882   (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
2884 (define_insn "*movdf_no_e_insn_sp32"
2885   [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
2886         (match_operand:DF 1 "input_operand"    "T,U,G,ro,r"))]
2887   "! TARGET_FPU
2888    && ! TARGET_V9
2889    && ! TARGET_ARCH64
2890    && (register_operand (operands[0], DFmode)
2891        || register_operand (operands[1], DFmode)
2892        || fp_zero_operand (operands[1], DFmode))"
2893   "@
2894   ldd\t%1, %0
2895   std\t%1, %0
2896   #
2897   #
2898   #"
2899   [(set_attr "type" "load,store,*,*,*")
2900    (set_attr "length" "*,*,2,2,2")])
2902 (define_insn "*movdf_no_e_insn_v9_sp32"
2903   [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
2904         (match_operand:DF 1 "input_operand"    "T,U,G,ro,rG"))]
2905   "! TARGET_FPU
2906    && TARGET_V9
2907    && ! TARGET_ARCH64
2908    && (register_operand (operands[0], DFmode)
2909        || register_operand (operands[1], DFmode)
2910        || fp_zero_operand (operands[1], DFmode))"
2911   "@
2912   ldd\t%1, %0
2913   std\t%1, %0
2914   stx\t%r1, %0
2915   #
2916   #"
2917   [(set_attr "type" "load,store,store,*,*")
2918    (set_attr "length" "*,*,*,2,2")])
2920 ;; We have available v9 double floats but not 64-bit
2921 ;; integer registers and no VIS.
2922 (define_insn "*movdf_insn_v9only_novis"
2923   [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,T,W,U,T,f,*r,o")
2924         (match_operand:DF 1 "input_operand"    "e,W#F,G,e,T,U,o#F,*roF,*rGf"))]
2925   "TARGET_FPU
2926    && TARGET_V9
2927    && ! TARGET_VIS
2928    && ! TARGET_ARCH64
2929    && (register_operand (operands[0], DFmode)
2930        || register_operand (operands[1], DFmode)
2931        || fp_zero_operand (operands[1], DFmode))"
2932   "@
2933   fmovd\t%1, %0
2934   ldd\t%1, %0
2935   stx\t%r1, %0
2936   std\t%1, %0
2937   ldd\t%1, %0
2938   std\t%1, %0
2939   #
2940   #
2941   #"
2942   [(set_attr "type" "fpmove,load,store,store,load,store,*,*,*")
2943    (set_attr "length" "*,*,*,*,*,*,2,2,2")
2944    (set_attr "fptype" "double,*,*,*,*,*,*,*,*")])
2946 ;; We have available v9 double floats but not 64-bit
2947 ;; integer registers but we have VIS.
2948 (define_insn "*movdf_insn_v9only_vis"
2949   [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,T,W,U,T,f,*r,o")
2950         (match_operand:DF 1 "input_operand" "G,e,W#F,G,e,T,U,o#F,*roGF,*rGf"))]
2951   "TARGET_FPU
2952    && TARGET_VIS
2953    && ! TARGET_ARCH64
2954    && (register_operand (operands[0], DFmode)
2955        || register_operand (operands[1], DFmode)
2956        || fp_zero_operand (operands[1], DFmode))"
2957   "@
2958   fzero\t%0
2959   fmovd\t%1, %0
2960   ldd\t%1, %0
2961   stx\t%r1, %0
2962   std\t%1, %0
2963   ldd\t%1, %0
2964   std\t%1, %0
2965   #
2966   #
2967   #"
2968   [(set_attr "type" "fga,fpmove,load,store,store,load,store,*,*,*")
2969    (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
2970    (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
2972 ;; We have available both v9 double floats and 64-bit
2973 ;; integer registers. No VIS though.
2974 (define_insn "*movdf_insn_sp64_novis"
2975   [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,W,*r,*r,m,*r")
2976         (match_operand:DF 1 "input_operand"    "e,W#F,e,*rG,m,*rG,F"))]
2977   "TARGET_FPU
2978    && ! TARGET_VIS
2979    && TARGET_ARCH64
2980    && (register_operand (operands[0], DFmode)
2981        || register_operand (operands[1], DFmode)
2982        || fp_zero_operand (operands[1], DFmode))"
2983   "@
2984   fmovd\t%1, %0
2985   ldd\t%1, %0
2986   std\t%1, %0
2987   mov\t%r1, %0
2988   ldx\t%1, %0
2989   stx\t%r1, %0
2990   #"
2991   [(set_attr "type" "fpmove,load,store,*,load,store,*")
2992    (set_attr "length" "*,*,*,*,*,*,2")
2993    (set_attr "fptype" "double,*,*,*,*,*,*")])
2995 ;; We have available both v9 double floats and 64-bit
2996 ;; integer registers. And we have VIS.
2997 (define_insn "*movdf_insn_sp64_vis"
2998   [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,W,*r,*r,m,*r")
2999         (match_operand:DF 1 "input_operand"    "G,e,W#F,e,*rG,m,*rG,F"))]
3000   "TARGET_FPU
3001    && TARGET_VIS
3002    && TARGET_ARCH64
3003    && (register_operand (operands[0], DFmode)
3004        || register_operand (operands[1], DFmode)
3005        || fp_zero_operand (operands[1], DFmode))"
3006   "@
3007   fzero\t%0
3008   fmovd\t%1, %0
3009   ldd\t%1, %0
3010   std\t%1, %0
3011   mov\t%r1, %0
3012   ldx\t%1, %0
3013   stx\t%r1, %0
3014   #"
3015   [(set_attr "type" "fga,fpmove,load,store,*,load,store,*")
3016    (set_attr "length" "*,*,*,*,*,*,*,2")
3017    (set_attr "fptype" "double,double,*,*,*,*,*,*")])
3019 (define_insn "*movdf_no_e_insn_sp64"
3020   [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
3021         (match_operand:DF 1 "input_operand"    "r,m,rG"))]
3022   "! TARGET_FPU
3023    && TARGET_ARCH64
3024    && (register_operand (operands[0], DFmode)
3025        || register_operand (operands[1], DFmode)
3026        || fp_zero_operand (operands[1], DFmode))"
3027   "@
3028   mov\t%1, %0
3029   ldx\t%1, %0
3030   stx\t%r1, %0"
3031   [(set_attr "type" "*,load,store")])
3033 (define_split
3034   [(set (match_operand:DF 0 "register_operand" "")
3035         (match_operand:DF 1 "const_double_operand" ""))]
3036   "TARGET_FPU
3037    && (GET_CODE (operands[0]) == REG
3038        && REGNO (operands[0]) < 32)
3039    && ! fp_zero_operand(operands[1], DFmode)
3040    && reload_completed"
3041   [(clobber (const_int 0))]
3043   REAL_VALUE_TYPE r;
3044   long l[2];
3046   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3047   REAL_VALUE_TO_TARGET_DOUBLE (r, l);
3048   operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
3050   if (TARGET_ARCH64)
3051     {
3052 #if HOST_BITS_PER_WIDE_INT == 64
3053       HOST_WIDE_INT val;
3055       val = ((HOST_WIDE_INT)(unsigned long)l[1] |
3056              ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
3057       emit_insn (gen_movdi (operands[0], GEN_INT (val)));
3058 #else
3059       emit_insn (gen_movdi (operands[0],
3060                             immed_double_const (l[1], l[0], DImode)));
3061 #endif
3062     }
3063   else
3064     {
3065       emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
3066                             GEN_INT (l[0])));
3068       /* Slick... but this trick loses if this subreg constant part
3069          can be done in one insn.  */
3070       if (l[1] == l[0]
3071           && !(SPARC_SETHI32_P (l[0])
3072                || SPARC_SIMM13_P (l[0])))
3073         {
3074           emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3075                                 gen_highpart (SImode, operands[0])));
3076         }
3077       else
3078         {
3079           emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3080                                 GEN_INT (l[1])));
3081         }
3082     }
3083   DONE;
3086 ;; Ok, now the splits to handle all the multi insn and
3087 ;; mis-aligned memory address cases.
3088 ;; In these splits please take note that we must be
3089 ;; careful when V9 but not ARCH64 because the integer
3090 ;; register DFmode cases must be handled.
3091 (define_split
3092   [(set (match_operand:DF 0 "register_operand" "")
3093         (match_operand:DF 1 "register_operand" ""))]
3094   "(! TARGET_V9
3095     || (! TARGET_ARCH64
3096         && ((GET_CODE (operands[0]) == REG
3097              && REGNO (operands[0]) < 32)
3098             || (GET_CODE (operands[0]) == SUBREG
3099                 && GET_CODE (SUBREG_REG (operands[0])) == REG
3100                 && REGNO (SUBREG_REG (operands[0])) < 32))))
3101    && reload_completed"
3102   [(clobber (const_int 0))]
3104   rtx set_dest = operands[0];
3105   rtx set_src = operands[1];
3106   rtx dest1, dest2;
3107   rtx src1, src2;
3109   dest1 = gen_highpart (SFmode, set_dest);
3110   dest2 = gen_lowpart (SFmode, set_dest);
3111   src1 = gen_highpart (SFmode, set_src);
3112   src2 = gen_lowpart (SFmode, set_src);
3114   /* Now emit using the real source and destination we found, swapping
3115      the order if we detect overlap.  */
3116   if (reg_overlap_mentioned_p (dest1, src2))
3117     {
3118       emit_insn (gen_movsf (dest2, src2));
3119       emit_insn (gen_movsf (dest1, src1));
3120     }
3121   else
3122     {
3123       emit_insn (gen_movsf (dest1, src1));
3124       emit_insn (gen_movsf (dest2, src2));
3125     }
3126   DONE;
3129 (define_split
3130   [(set (match_operand:DF 0 "register_operand" "")
3131         (match_operand:DF 1 "memory_operand" ""))]
3132   "reload_completed
3133    && ! TARGET_ARCH64
3134    && (((REGNO (operands[0]) % 2) != 0)
3135        || ! mem_min_alignment (operands[1], 8))
3136    && offsettable_memref_p (operands[1])"
3137   [(clobber (const_int 0))]
3139   rtx word0 = adjust_address (operands[1], SFmode, 0);
3140   rtx word1 = adjust_address (operands[1], SFmode, 4);
3142   if (reg_overlap_mentioned_p (gen_highpart (SFmode, operands[0]), word1))
3143     {
3144       emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3145                             word1));
3146       emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3147                             word0));
3148     }
3149   else
3150     {
3151       emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]),
3152                             word0));
3153       emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]),
3154                             word1));
3155     }
3156   DONE;
3159 (define_split
3160   [(set (match_operand:DF 0 "memory_operand" "")
3161         (match_operand:DF 1 "register_operand" ""))]
3162   "reload_completed
3163    && ! TARGET_ARCH64
3164    && (((REGNO (operands[1]) % 2) != 0)
3165        || ! mem_min_alignment (operands[0], 8))
3166    && offsettable_memref_p (operands[0])"
3167   [(clobber (const_int 0))]
3169   rtx word0 = adjust_address (operands[0], SFmode, 0);
3170   rtx word1 = adjust_address (operands[0], SFmode, 4);
3172   emit_insn (gen_movsf (word0,
3173                         gen_highpart (SFmode, operands[1])));
3174   emit_insn (gen_movsf (word1,
3175                         gen_lowpart (SFmode, operands[1])));
3176   DONE;
3179 (define_split
3180   [(set (match_operand:DF 0 "memory_operand" "")
3181         (match_operand:DF 1 "fp_zero_operand" ""))]
3182   "reload_completed
3183    && (! TARGET_V9
3184        || (! TARGET_ARCH64
3185            && ! mem_min_alignment (operands[0], 8)))
3186    && offsettable_memref_p (operands[0])"
3187   [(clobber (const_int 0))]
3189   rtx dest1, dest2;
3191   dest1 = adjust_address (operands[0], SFmode, 0);
3192   dest2 = adjust_address (operands[0], SFmode, 4);
3194   emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3195   emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3196   DONE;
3199 (define_split
3200   [(set (match_operand:DF 0 "register_operand" "")
3201         (match_operand:DF 1 "fp_zero_operand" ""))]
3202   "reload_completed
3203    && ! TARGET_ARCH64
3204    && ((GET_CODE (operands[0]) == REG
3205         && REGNO (operands[0]) < 32)
3206        || (GET_CODE (operands[0]) == SUBREG
3207            && GET_CODE (SUBREG_REG (operands[0])) == REG
3208            && REGNO (SUBREG_REG (operands[0])) < 32))"
3209   [(clobber (const_int 0))]
3211   rtx set_dest = operands[0];
3212   rtx dest1, dest2;
3214   dest1 = gen_highpart (SFmode, set_dest);
3215   dest2 = gen_lowpart (SFmode, set_dest);
3216   emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
3217   emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
3218   DONE;
3221 (define_expand "movtf"
3222   [(set (match_operand:TF 0 "general_operand" "")
3223         (match_operand:TF 1 "general_operand" ""))]
3224   ""
3226   /* Force TFmode constants into memory.  */
3227   if (GET_CODE (operands[0]) == REG
3228       && CONSTANT_P (operands[1]))
3229     {
3230       /* emit_group_store will send such bogosity to us when it is
3231          not storing directly into memory.  So fix this up to avoid
3232          crashes in output_constant_pool.  */
3233       if (operands [1] == const0_rtx)
3234         operands[1] = CONST0_RTX (TFmode);
3236       if (TARGET_VIS && fp_zero_operand (operands[1], TFmode))
3237         goto movtf_is_ok;
3239       operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3240                                                    operands[1]));
3241     }
3243   /* Handle MEM cases first, note that only v9 guarantees
3244      full 16-byte alignment for quads.  */
3245   if (GET_CODE (operands[0]) == MEM)
3246     {
3247       if (register_operand (operands[1], TFmode)
3248           || fp_zero_operand (operands[1], TFmode))
3249         goto movtf_is_ok;
3251       if (! reload_in_progress)
3252         {
3253           operands[0] = validize_mem (operands[0]);
3254           operands[1] = force_reg (TFmode, operands[1]);
3255         }
3256     }
3258   /* Fixup PIC cases.  */
3259   if (flag_pic)
3260     {
3261       if (CONSTANT_P (operands[1])
3262           && pic_address_needs_scratch (operands[1]))
3263         operands[1] = legitimize_pic_address (operands[1], TFmode, 0);
3265       if (symbolic_operand (operands[1], TFmode))
3266         {
3267           operands[1] = legitimize_pic_address (operands[1],
3268                                                 TFmode,
3269                                                 (reload_in_progress ?
3270                                                  operands[0] :
3271                                                  NULL_RTX));
3272         }
3273     }
3275  movtf_is_ok:
3276   ;
3279 ;; Be careful, fmovq and {st,ld}{x,q} do not exist when !arch64 so
3280 ;; we must split them all.  :-(
3281 (define_insn "*movtf_insn_sp32"
3282   [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3283         (match_operand:TF 1 "input_operand"    "oe,GeUr,o,roG"))]
3284   "TARGET_FPU
3285    && ! TARGET_VIS
3286    && ! TARGET_ARCH64
3287    && (register_operand (operands[0], TFmode)
3288        || register_operand (operands[1], TFmode)
3289        || fp_zero_operand (operands[1], TFmode))"
3290   "#"
3291   [(set_attr "length" "4")])
3293 (define_insn "*movtf_insn_vis_sp32"
3294   [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3295         (match_operand:TF 1 "input_operand"    "Goe,GeUr,o,roG"))]
3296   "TARGET_FPU
3297    && TARGET_VIS
3298    && ! TARGET_ARCH64
3299    && (register_operand (operands[0], TFmode)
3300        || register_operand (operands[1], TFmode)
3301        || fp_zero_operand (operands[1], TFmode))"
3302   "#"
3303   [(set_attr "length" "4")])
3305 ;; Exactly the same as above, except that all `e' cases are deleted.
3306 ;; This is necessary to prevent reload from ever trying to use a `e' reg
3307 ;; when -mno-fpu.
3309 (define_insn "*movtf_no_e_insn_sp32"
3310   [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
3311         (match_operand:TF 1 "input_operand"    "G,o,U,roG,r"))]
3312   "! TARGET_FPU
3313    && ! TARGET_ARCH64
3314    && (register_operand (operands[0], TFmode)
3315        || register_operand (operands[1], TFmode)
3316        || fp_zero_operand (operands[1], TFmode))"
3317   "#"
3318   [(set_attr "length" "4")])
3320 ;; Now handle the float reg cases directly when arch64,
3321 ;; hard_quad, and proper reg number alignment are all true.
3322 (define_insn "*movtf_insn_hq_sp64"
3323   [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,o,r")
3324         (match_operand:TF 1 "input_operand"    "e,m,e,Gr,roG"))]
3325   "TARGET_FPU
3326    && ! TARGET_VIS
3327    && TARGET_ARCH64
3328    && TARGET_HARD_QUAD
3329    && (register_operand (operands[0], TFmode)
3330        || register_operand (operands[1], TFmode)
3331        || fp_zero_operand (operands[1], TFmode))"
3332   "@
3333   fmovq\t%1, %0
3334   ldq\t%1, %0
3335   stq\t%1, %0
3336   #
3337   #"
3338   [(set_attr "type" "fpmove,fpload,fpstore,*,*")
3339    (set_attr "length" "*,*,*,2,2")])
3341 (define_insn "*movtf_insn_hq_vis_sp64"
3342   [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,eo,r,o")
3343         (match_operand:TF 1 "input_operand"    "e,m,e,G,roG,r"))]
3344   "TARGET_FPU
3345    && TARGET_VIS
3346    && TARGET_ARCH64
3347    && TARGET_HARD_QUAD
3348    && (register_operand (operands[0], TFmode)
3349        || register_operand (operands[1], TFmode)
3350        || fp_zero_operand (operands[1], TFmode))"
3351   "@
3352   fmovq\t%1, %0
3353   ldq\t%1, %0
3354   stq\t%1, %0
3355   #
3356   #
3357   #"
3358   [(set_attr "type" "fpmove,fpload,fpstore,*,*,*")
3359    (set_attr "length" "*,*,*,2,2,2")])
3361 ;; Now we allow the integer register cases even when
3362 ;; only arch64 is true.
3363 (define_insn "*movtf_insn_sp64"
3364   [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3365         (match_operand:TF 1 "input_operand"    "oe,Ger,orG"))]
3366   "TARGET_FPU
3367    && ! TARGET_VIS
3368    && TARGET_ARCH64
3369    && ! TARGET_HARD_QUAD
3370    && (register_operand (operands[0], TFmode)
3371        || register_operand (operands[1], TFmode)
3372        || fp_zero_operand (operands[1], TFmode))"
3373   "#"
3374   [(set_attr "length" "2")])
3376 (define_insn "*movtf_insn_vis_sp64"
3377   [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3378         (match_operand:TF 1 "input_operand"    "Goe,Ger,orG"))]
3379   "TARGET_FPU
3380    && TARGET_VIS
3381    && TARGET_ARCH64
3382    && ! TARGET_HARD_QUAD
3383    && (register_operand (operands[0], TFmode)
3384        || register_operand (operands[1], TFmode)
3385        || fp_zero_operand (operands[1], TFmode))"
3386   "#"
3387   [(set_attr "length" "2")])
3389 (define_insn "*movtf_no_e_insn_sp64"
3390   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
3391         (match_operand:TF 1 "input_operand"    "orG,rG"))]
3392   "! TARGET_FPU
3393    && TARGET_ARCH64
3394    && (register_operand (operands[0], TFmode)
3395        || register_operand (operands[1], TFmode)
3396        || fp_zero_operand (operands[1], TFmode))"
3397   "#"
3398   [(set_attr "length" "2")])
3400 ;; Now all the splits to handle multi-insn TF mode moves.
3401 (define_split
3402   [(set (match_operand:TF 0 "register_operand" "")
3403         (match_operand:TF 1 "register_operand" ""))]
3404   "reload_completed
3405    && (! TARGET_ARCH64
3406        || (TARGET_FPU
3407            && ! TARGET_HARD_QUAD)
3408        || ! fp_register_operand (operands[0], TFmode))"
3409   [(clobber (const_int 0))]
3411   rtx set_dest = operands[0];
3412   rtx set_src = operands[1];
3413   rtx dest1, dest2;
3414   rtx src1, src2;
3416   dest1 = gen_df_reg (set_dest, 0);
3417   dest2 = gen_df_reg (set_dest, 1);
3418   src1 = gen_df_reg (set_src, 0);
3419   src2 = gen_df_reg (set_src, 1);
3421   /* Now emit using the real source and destination we found, swapping
3422      the order if we detect overlap.  */
3423   if (reg_overlap_mentioned_p (dest1, src2))
3424     {
3425       emit_insn (gen_movdf (dest2, src2));
3426       emit_insn (gen_movdf (dest1, src1));
3427     }
3428   else
3429     {
3430       emit_insn (gen_movdf (dest1, src1));
3431       emit_insn (gen_movdf (dest2, src2));
3432     }
3433   DONE;
3436 (define_split
3437   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3438         (match_operand:TF 1 "fp_zero_operand" ""))]
3439   "reload_completed"
3440   [(clobber (const_int 0))]
3442   rtx set_dest = operands[0];
3443   rtx dest1, dest2;
3445   switch (GET_CODE (set_dest))
3446     {
3447     case REG:
3448       dest1 = gen_df_reg (set_dest, 0);
3449       dest2 = gen_df_reg (set_dest, 1);
3450       break;
3451     case MEM:
3452       dest1 = adjust_address (set_dest, DFmode, 0);
3453       dest2 = adjust_address (set_dest, DFmode, 8);
3454       break;
3455     default:
3456       abort ();      
3457     }
3459   emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
3460   emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
3461   DONE;
3464 (define_split
3465   [(set (match_operand:TF 0 "register_operand" "")
3466         (match_operand:TF 1 "memory_operand" ""))]
3467   "(reload_completed
3468     && offsettable_memref_p (operands[1])
3469     && (! TARGET_ARCH64
3470         || ! TARGET_HARD_QUAD
3471         || ! fp_register_operand (operands[0], TFmode)))"
3472   [(clobber (const_int 0))]
3474   rtx word0 = adjust_address (operands[1], DFmode, 0);
3475   rtx word1 = adjust_address (operands[1], DFmode, 8);
3476   rtx set_dest, dest1, dest2;
3478   set_dest = operands[0];
3480   dest1 = gen_df_reg (set_dest, 0);
3481   dest2 = gen_df_reg (set_dest, 1);
3483   /* Now output, ordering such that we don't clobber any registers
3484      mentioned in the address.  */
3485   if (reg_overlap_mentioned_p (dest1, word1))
3487     {
3488       emit_insn (gen_movdf (dest2, word1));
3489       emit_insn (gen_movdf (dest1, word0));
3490     }
3491   else
3492    {
3493       emit_insn (gen_movdf (dest1, word0));
3494       emit_insn (gen_movdf (dest2, word1));
3495    }
3496   DONE;
3499 (define_split
3500   [(set (match_operand:TF 0 "memory_operand" "")
3501         (match_operand:TF 1 "register_operand" ""))]
3502   "(reload_completed
3503     && offsettable_memref_p (operands[0])
3504     && (! TARGET_ARCH64
3505         || ! TARGET_HARD_QUAD
3506         || ! fp_register_operand (operands[1], TFmode)))"
3507   [(clobber (const_int 0))]
3509   rtx set_src = operands[1];
3511   emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
3512                         gen_df_reg (set_src, 0)));
3513   emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
3514                         gen_df_reg (set_src, 1)));
3515   DONE;
3518 ;; SPARC V9 conditional move instructions.
3520 ;; We can handle larger constants here for some flavors, but for now we keep
3521 ;; it simple and only allow those constants supported by all flavors.
3522 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3523 ;; 3 contains the constant if one is present, but we handle either for
3524 ;; generality (sparc.c puts a constant in operand 2).
3526 (define_expand "movqicc"
3527   [(set (match_operand:QI 0 "register_operand" "")
3528         (if_then_else:QI (match_operand 1 "comparison_operator" "")
3529                          (match_operand:QI 2 "arith10_operand" "")
3530                          (match_operand:QI 3 "arith10_operand" "")))]
3531   "TARGET_V9"
3533   enum rtx_code code = GET_CODE (operands[1]);
3535   if (GET_MODE (sparc_compare_op0) == DImode
3536       && ! TARGET_ARCH64)
3537     FAIL;
3539   if (sparc_compare_op1 == const0_rtx
3540       && GET_CODE (sparc_compare_op0) == REG
3541       && GET_MODE (sparc_compare_op0) == DImode
3542       && v9_regcmp_p (code))
3543     {
3544       operands[1] = gen_rtx_fmt_ee (code, DImode,
3545                              sparc_compare_op0, sparc_compare_op1);
3546     }
3547   else
3548     {
3549       rtx cc_reg = gen_compare_reg (code,
3550                                     sparc_compare_op0, sparc_compare_op1);
3551       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3552     }
3555 (define_expand "movhicc"
3556   [(set (match_operand:HI 0 "register_operand" "")
3557         (if_then_else:HI (match_operand 1 "comparison_operator" "")
3558                          (match_operand:HI 2 "arith10_operand" "")
3559                          (match_operand:HI 3 "arith10_operand" "")))]
3560   "TARGET_V9"
3562   enum rtx_code code = GET_CODE (operands[1]);
3564   if (GET_MODE (sparc_compare_op0) == DImode
3565       && ! TARGET_ARCH64)
3566     FAIL;
3568   if (sparc_compare_op1 == const0_rtx
3569       && GET_CODE (sparc_compare_op0) == REG
3570       && GET_MODE (sparc_compare_op0) == DImode
3571       && v9_regcmp_p (code))
3572     {
3573       operands[1] = gen_rtx_fmt_ee (code, DImode,
3574                              sparc_compare_op0, sparc_compare_op1);
3575     }
3576   else
3577     {
3578       rtx cc_reg = gen_compare_reg (code,
3579                                     sparc_compare_op0, sparc_compare_op1);
3580       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3581     }
3584 (define_expand "movsicc"
3585   [(set (match_operand:SI 0 "register_operand" "")
3586         (if_then_else:SI (match_operand 1 "comparison_operator" "")
3587                          (match_operand:SI 2 "arith10_operand" "")
3588                          (match_operand:SI 3 "arith10_operand" "")))]
3589   "TARGET_V9"
3591   enum rtx_code code = GET_CODE (operands[1]);
3592   enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
3594   if (sparc_compare_op1 == const0_rtx
3595       && GET_CODE (sparc_compare_op0) == REG
3596       && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
3597     {
3598       operands[1] = gen_rtx_fmt_ee (code, op0_mode,
3599                              sparc_compare_op0, sparc_compare_op1);
3600     }
3601   else
3602     {
3603       rtx cc_reg = gen_compare_reg (code,
3604                                     sparc_compare_op0, sparc_compare_op1);
3605       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3606                                     cc_reg, const0_rtx);
3607     }
3610 (define_expand "movdicc"
3611   [(set (match_operand:DI 0 "register_operand" "")
3612         (if_then_else:DI (match_operand 1 "comparison_operator" "")
3613                          (match_operand:DI 2 "arith10_double_operand" "")
3614                          (match_operand:DI 3 "arith10_double_operand" "")))]
3615   "TARGET_ARCH64"
3617   enum rtx_code code = GET_CODE (operands[1]);
3619   if (sparc_compare_op1 == const0_rtx
3620       && GET_CODE (sparc_compare_op0) == REG
3621       && GET_MODE (sparc_compare_op0) == DImode
3622       && v9_regcmp_p (code))
3623     {
3624       operands[1] = gen_rtx_fmt_ee (code, DImode,
3625                              sparc_compare_op0, sparc_compare_op1);
3626     }
3627   else
3628     {
3629       rtx cc_reg = gen_compare_reg (code,
3630                                     sparc_compare_op0, sparc_compare_op1);
3631       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3632                                     cc_reg, const0_rtx);
3633     }
3636 (define_expand "movsfcc"
3637   [(set (match_operand:SF 0 "register_operand" "")
3638         (if_then_else:SF (match_operand 1 "comparison_operator" "")
3639                          (match_operand:SF 2 "register_operand" "")
3640                          (match_operand:SF 3 "register_operand" "")))]
3641   "TARGET_V9 && TARGET_FPU"
3643   enum rtx_code code = GET_CODE (operands[1]);
3645   if (GET_MODE (sparc_compare_op0) == DImode
3646       && ! TARGET_ARCH64)
3647     FAIL;
3649   if (sparc_compare_op1 == const0_rtx
3650       && GET_CODE (sparc_compare_op0) == REG
3651       && GET_MODE (sparc_compare_op0) == DImode
3652       && v9_regcmp_p (code))
3653     {
3654       operands[1] = gen_rtx_fmt_ee (code, DImode,
3655                              sparc_compare_op0, sparc_compare_op1);
3656     }
3657   else
3658     {
3659       rtx cc_reg = gen_compare_reg (code,
3660                                     sparc_compare_op0, sparc_compare_op1);
3661       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3662     }
3665 (define_expand "movdfcc"
3666   [(set (match_operand:DF 0 "register_operand" "")
3667         (if_then_else:DF (match_operand 1 "comparison_operator" "")
3668                          (match_operand:DF 2 "register_operand" "")
3669                          (match_operand:DF 3 "register_operand" "")))]
3670   "TARGET_V9 && TARGET_FPU"
3672   enum rtx_code code = GET_CODE (operands[1]);
3674   if (GET_MODE (sparc_compare_op0) == DImode
3675       && ! TARGET_ARCH64)
3676     FAIL;
3678   if (sparc_compare_op1 == const0_rtx
3679       && GET_CODE (sparc_compare_op0) == REG
3680       && GET_MODE (sparc_compare_op0) == DImode
3681       && v9_regcmp_p (code))
3682     {
3683       operands[1] = gen_rtx_fmt_ee (code, DImode,
3684                              sparc_compare_op0, sparc_compare_op1);
3685     }
3686   else
3687     {
3688       rtx cc_reg = gen_compare_reg (code,
3689                                     sparc_compare_op0, sparc_compare_op1);
3690       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3691     }
3694 (define_expand "movtfcc"
3695   [(set (match_operand:TF 0 "register_operand" "")
3696         (if_then_else:TF (match_operand 1 "comparison_operator" "")
3697                          (match_operand:TF 2 "register_operand" "")
3698                          (match_operand:TF 3 "register_operand" "")))]
3699   "TARGET_V9 && TARGET_FPU"
3701   enum rtx_code code = GET_CODE (operands[1]);
3703   if (GET_MODE (sparc_compare_op0) == DImode
3704       && ! TARGET_ARCH64)
3705     FAIL;
3707   if (sparc_compare_op1 == const0_rtx
3708       && GET_CODE (sparc_compare_op0) == REG
3709       && GET_MODE (sparc_compare_op0) == DImode
3710       && v9_regcmp_p (code))
3711     {
3712       operands[1] = gen_rtx_fmt_ee (code, DImode,
3713                              sparc_compare_op0, sparc_compare_op1);
3714     }
3715   else
3716     {
3717       rtx cc_reg = gen_compare_reg (code,
3718                                     sparc_compare_op0, sparc_compare_op1);
3719       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3720     }
3723 ;; Conditional move define_insns.
3725 (define_insn "*movqi_cc_sp64"
3726   [(set (match_operand:QI 0 "register_operand" "=r,r")
3727         (if_then_else:QI (match_operator 1 "comparison_operator"
3728                                 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3729                                  (const_int 0)])
3730                          (match_operand:QI 3 "arith11_operand" "rL,0")
3731                          (match_operand:QI 4 "arith11_operand" "0,rL")))]
3732   "TARGET_V9"
3733   "@
3734    mov%C1\t%x2, %3, %0
3735    mov%c1\t%x2, %4, %0"
3736   [(set_attr "type" "cmove")])
3738 (define_insn "*movhi_cc_sp64"
3739   [(set (match_operand:HI 0 "register_operand" "=r,r")
3740         (if_then_else:HI (match_operator 1 "comparison_operator"
3741                                 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3742                                  (const_int 0)])
3743                          (match_operand:HI 3 "arith11_operand" "rL,0")
3744                          (match_operand:HI 4 "arith11_operand" "0,rL")))]
3745   "TARGET_V9"
3746   "@
3747    mov%C1\t%x2, %3, %0
3748    mov%c1\t%x2, %4, %0"
3749   [(set_attr "type" "cmove")])
3751 (define_insn "*movsi_cc_sp64"
3752   [(set (match_operand:SI 0 "register_operand" "=r,r")
3753         (if_then_else:SI (match_operator 1 "comparison_operator"
3754                                 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3755                                  (const_int 0)])
3756                          (match_operand:SI 3 "arith11_operand" "rL,0")
3757                          (match_operand:SI 4 "arith11_operand" "0,rL")))]
3758   "TARGET_V9"
3759   "@
3760    mov%C1\t%x2, %3, %0
3761    mov%c1\t%x2, %4, %0"
3762   [(set_attr "type" "cmove")])
3764 ;; ??? The constraints of operands 3,4 need work.
3765 (define_insn "*movdi_cc_sp64"
3766   [(set (match_operand:DI 0 "register_operand" "=r,r")
3767         (if_then_else:DI (match_operator 1 "comparison_operator"
3768                                 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3769                                  (const_int 0)])
3770                          (match_operand:DI 3 "arith11_double_operand" "rLH,0")
3771                          (match_operand:DI 4 "arith11_double_operand" "0,rLH")))]
3772   "TARGET_ARCH64"
3773   "@
3774    mov%C1\t%x2, %3, %0
3775    mov%c1\t%x2, %4, %0"
3776   [(set_attr "type" "cmove")])
3778 (define_insn "*movdi_cc_sp64_trunc"
3779   [(set (match_operand:SI 0 "register_operand" "=r,r")
3780         (if_then_else:SI (match_operator 1 "comparison_operator"
3781                                 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3782                                  (const_int 0)])
3783                          (match_operand:SI 3 "arith11_double_operand" "rLH,0")
3784                          (match_operand:SI 4 "arith11_double_operand" "0,rLH")))]
3785   "TARGET_ARCH64"
3786   "@
3787    mov%C1\t%x2, %3, %0
3788    mov%c1\t%x2, %4, %0"
3789   [(set_attr "type" "cmove")])
3791 (define_insn "*movsf_cc_sp64"
3792   [(set (match_operand:SF 0 "register_operand" "=f,f")
3793         (if_then_else:SF (match_operator 1 "comparison_operator"
3794                                 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3795                                  (const_int 0)])
3796                          (match_operand:SF 3 "register_operand" "f,0")
3797                          (match_operand:SF 4 "register_operand" "0,f")))]
3798   "TARGET_V9 && TARGET_FPU"
3799   "@
3800    fmovs%C1\t%x2, %3, %0
3801    fmovs%c1\t%x2, %4, %0"
3802   [(set_attr "type" "fpcmove")])
3804 (define_insn "movdf_cc_sp64"
3805   [(set (match_operand:DF 0 "register_operand" "=e,e")
3806         (if_then_else:DF (match_operator 1 "comparison_operator"
3807                                 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3808                                  (const_int 0)])
3809                          (match_operand:DF 3 "register_operand" "e,0")
3810                          (match_operand:DF 4 "register_operand" "0,e")))]
3811   "TARGET_V9 && TARGET_FPU"
3812   "@
3813    fmovd%C1\t%x2, %3, %0
3814    fmovd%c1\t%x2, %4, %0"
3815   [(set_attr "type" "fpcmove")
3816    (set_attr "fptype" "double")])
3818 (define_insn "*movtf_cc_hq_sp64"
3819   [(set (match_operand:TF 0 "register_operand" "=e,e")
3820         (if_then_else:TF (match_operator 1 "comparison_operator"
3821                                 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3822                                  (const_int 0)])
3823                          (match_operand:TF 3 "register_operand" "e,0")
3824                          (match_operand:TF 4 "register_operand" "0,e")))]
3825   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3826   "@
3827    fmovq%C1\t%x2, %3, %0
3828    fmovq%c1\t%x2, %4, %0"
3829   [(set_attr "type" "fpcmove")])
3831 (define_insn_and_split "*movtf_cc_sp64"
3832   [(set (match_operand:TF 0 "register_operand" "=e,e")
3833         (if_then_else:TF (match_operator 1 "comparison_operator"
3834                             [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3835                              (const_int 0)])
3836                          (match_operand:TF 3 "register_operand" "e,0")
3837                          (match_operand:TF 4 "register_operand" "0,e")))]
3838   "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
3839   "#"
3840   "&& reload_completed"
3841   [(clobber (const_int 0))]
3843   rtx set_dest = operands[0];
3844   rtx set_srca = operands[3];
3845   rtx set_srcb = operands[4];
3846   int third = rtx_equal_p (set_dest, set_srca);
3847   rtx dest1, dest2;
3848   rtx srca1, srca2, srcb1, srcb2;
3850   dest1 = gen_df_reg (set_dest, 0);
3851   dest2 = gen_df_reg (set_dest, 1);
3852   srca1 = gen_df_reg (set_srca, 0);
3853   srca2 = gen_df_reg (set_srca, 1);
3854   srcb1 = gen_df_reg (set_srcb, 0);
3855   srcb2 = gen_df_reg (set_srcb, 1);
3857   /* Now emit using the real source and destination we found, swapping
3858      the order if we detect overlap.  */
3859   if ((third && reg_overlap_mentioned_p (dest1, srcb2))
3860       || (!third && reg_overlap_mentioned_p (dest1, srca2)))
3861     {
3862       emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3863       emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3864     }
3865   else
3866     {
3867       emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3868       emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3869     }
3870   DONE;
3872   [(set_attr "length" "2")])
3874 (define_insn "*movqi_cc_reg_sp64"
3875   [(set (match_operand:QI 0 "register_operand" "=r,r")
3876         (if_then_else:QI (match_operator 1 "v9_regcmp_op"
3877                                 [(match_operand:DI 2 "register_operand" "r,r")
3878                                  (const_int 0)])
3879                          (match_operand:QI 3 "arith10_operand" "rM,0")
3880                          (match_operand:QI 4 "arith10_operand" "0,rM")))]
3881   "TARGET_ARCH64"
3882   "@
3883    movr%D1\t%2, %r3, %0
3884    movr%d1\t%2, %r4, %0"
3885   [(set_attr "type" "cmove")])
3887 (define_insn "*movhi_cc_reg_sp64"
3888   [(set (match_operand:HI 0 "register_operand" "=r,r")
3889         (if_then_else:HI (match_operator 1 "v9_regcmp_op"
3890                                 [(match_operand:DI 2 "register_operand" "r,r")
3891                                  (const_int 0)])
3892                          (match_operand:HI 3 "arith10_operand" "rM,0")
3893                          (match_operand:HI 4 "arith10_operand" "0,rM")))]
3894   "TARGET_ARCH64"
3895   "@
3896    movr%D1\t%2, %r3, %0
3897    movr%d1\t%2, %r4, %0"
3898   [(set_attr "type" "cmove")])
3900 (define_insn "*movsi_cc_reg_sp64"
3901   [(set (match_operand:SI 0 "register_operand" "=r,r")
3902         (if_then_else:SI (match_operator 1 "v9_regcmp_op"
3903                                 [(match_operand:DI 2 "register_operand" "r,r")
3904                                  (const_int 0)])
3905                          (match_operand:SI 3 "arith10_operand" "rM,0")
3906                          (match_operand:SI 4 "arith10_operand" "0,rM")))]
3907   "TARGET_ARCH64"
3908   "@
3909    movr%D1\t%2, %r3, %0
3910    movr%d1\t%2, %r4, %0"
3911   [(set_attr "type" "cmove")])
3913 ;; ??? The constraints of operands 3,4 need work.
3914 (define_insn "*movdi_cc_reg_sp64"
3915   [(set (match_operand:DI 0 "register_operand" "=r,r")
3916         (if_then_else:DI (match_operator 1 "v9_regcmp_op"
3917                                 [(match_operand:DI 2 "register_operand" "r,r")
3918                                  (const_int 0)])
3919                          (match_operand:DI 3 "arith10_double_operand" "rMH,0")
3920                          (match_operand:DI 4 "arith10_double_operand" "0,rMH")))]
3921   "TARGET_ARCH64"
3922   "@
3923    movr%D1\t%2, %r3, %0
3924    movr%d1\t%2, %r4, %0"
3925   [(set_attr "type" "cmove")])
3927 (define_insn "*movdi_cc_reg_sp64_trunc"
3928   [(set (match_operand:SI 0 "register_operand" "=r,r")
3929         (if_then_else:SI (match_operator 1 "v9_regcmp_op"
3930                                 [(match_operand:DI 2 "register_operand" "r,r")
3931                                  (const_int 0)])
3932                          (match_operand:SI 3 "arith10_double_operand" "rMH,0")
3933                          (match_operand:SI 4 "arith10_double_operand" "0,rMH")))]
3934   "TARGET_ARCH64"
3935   "@
3936    movr%D1\t%2, %r3, %0
3937    movr%d1\t%2, %r4, %0"
3938   [(set_attr "type" "cmove")])
3940 (define_insn "*movsf_cc_reg_sp64"
3941   [(set (match_operand:SF 0 "register_operand" "=f,f")
3942         (if_then_else:SF (match_operator 1 "v9_regcmp_op"
3943                                 [(match_operand:DI 2 "register_operand" "r,r")
3944                                  (const_int 0)])
3945                          (match_operand:SF 3 "register_operand" "f,0")
3946                          (match_operand:SF 4 "register_operand" "0,f")))]
3947   "TARGET_ARCH64 && TARGET_FPU"
3948   "@
3949    fmovrs%D1\t%2, %3, %0
3950    fmovrs%d1\t%2, %4, %0"
3951   [(set_attr "type" "fpcrmove")])
3953 (define_insn "movdf_cc_reg_sp64"
3954   [(set (match_operand:DF 0 "register_operand" "=e,e")
3955         (if_then_else:DF (match_operator 1 "v9_regcmp_op"
3956                                 [(match_operand:DI 2 "register_operand" "r,r")
3957                                  (const_int 0)])
3958                          (match_operand:DF 3 "register_operand" "e,0")
3959                          (match_operand:DF 4 "register_operand" "0,e")))]
3960   "TARGET_ARCH64 && TARGET_FPU"
3961   "@
3962    fmovrd%D1\t%2, %3, %0
3963    fmovrd%d1\t%2, %4, %0"
3964   [(set_attr "type" "fpcrmove")
3965    (set_attr "fptype" "double")])
3967 (define_insn "*movtf_cc_reg_hq_sp64"
3968   [(set (match_operand:TF 0 "register_operand" "=e,e")
3969         (if_then_else:TF (match_operator 1 "v9_regcmp_op"
3970                                 [(match_operand:DI 2 "register_operand" "r,r")
3971                                  (const_int 0)])
3972                          (match_operand:TF 3 "register_operand" "e,0")
3973                          (match_operand:TF 4 "register_operand" "0,e")))]
3974   "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
3975   "@
3976    fmovrq%D1\t%2, %3, %0
3977    fmovrq%d1\t%2, %4, %0"
3978   [(set_attr "type" "fpcrmove")])
3980 (define_insn_and_split "*movtf_cc_reg_sp64"
3981   [(set (match_operand:TF 0 "register_operand" "=e,e")
3982         (if_then_else:TF (match_operator 1 "v9_regcmp_op"
3983                                 [(match_operand:DI 2 "register_operand" "r,r")
3984                                  (const_int 0)])
3985                          (match_operand:TF 3 "register_operand" "e,0")
3986                          (match_operand:TF 4 "register_operand" "0,e")))]
3987   "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
3988   "#"
3989   "&& reload_completed"
3990   [(clobber (const_int 0))]
3992   rtx set_dest = operands[0];
3993   rtx set_srca = operands[3];
3994   rtx set_srcb = operands[4];
3995   int third = rtx_equal_p (set_dest, set_srca);
3996   rtx dest1, dest2;
3997   rtx srca1, srca2, srcb1, srcb2;
3999   dest1 = gen_df_reg (set_dest, 0);
4000   dest2 = gen_df_reg (set_dest, 1);
4001   srca1 = gen_df_reg (set_srca, 0);
4002   srca2 = gen_df_reg (set_srca, 1);
4003   srcb1 = gen_df_reg (set_srcb, 0);
4004   srcb2 = gen_df_reg (set_srcb, 1);
4006   /* Now emit using the real source and destination we found, swapping
4007      the order if we detect overlap.  */
4008   if ((third && reg_overlap_mentioned_p (dest1, srcb2))
4009       || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4010     {
4011       emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4012       emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4013     }
4014   else
4015     {
4016       emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4017       emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4018     }
4019   DONE;
4021   [(set_attr "length" "2")])
4024 ;;- zero extension instructions
4026 ;; These patterns originally accepted general_operands, however, slightly
4027 ;; better code is generated by only accepting register_operands, and then
4028 ;; letting combine generate the ldu[hb] insns.
4030 (define_expand "zero_extendhisi2"
4031   [(set (match_operand:SI 0 "register_operand" "")
4032         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
4033   ""
4035   rtx temp = gen_reg_rtx (SImode);
4036   rtx shift_16 = GEN_INT (16);
4037   int op1_subbyte = 0;
4039   if (GET_CODE (operand1) == SUBREG)
4040     {
4041       op1_subbyte = SUBREG_BYTE (operand1);
4042       op1_subbyte /= GET_MODE_SIZE (SImode);
4043       op1_subbyte *= GET_MODE_SIZE (SImode);
4044       operand1 = XEXP (operand1, 0);
4045     }
4047   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4048                           shift_16));
4049   emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
4050   DONE;
4053 (define_insn "*zero_extendhisi2_insn"
4054   [(set (match_operand:SI 0 "register_operand" "=r")
4055         (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4056   ""
4057   "lduh\t%1, %0"
4058   [(set_attr "type" "load")
4059    (set_attr "us3load_type" "3cycle")])
4061 (define_expand "zero_extendqihi2"
4062   [(set (match_operand:HI 0 "register_operand" "")
4063         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
4064   ""
4065   "")
4067 (define_insn "*zero_extendqihi2_insn"
4068   [(set (match_operand:HI 0 "register_operand" "=r,r")
4069         (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
4070   "GET_CODE (operands[1]) != CONST_INT"
4071   "@
4072    and\t%1, 0xff, %0
4073    ldub\t%1, %0"
4074   [(set_attr "type" "*,load")
4075    (set_attr "us3load_type" "*,3cycle")])
4077 (define_expand "zero_extendqisi2"
4078   [(set (match_operand:SI 0 "register_operand" "")
4079         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
4080   ""
4081   "")
4083 (define_insn "*zero_extendqisi2_insn"
4084   [(set (match_operand:SI 0 "register_operand" "=r,r")
4085         (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
4086   "GET_CODE (operands[1]) != CONST_INT"
4087   "@
4088    and\t%1, 0xff, %0
4089    ldub\t%1, %0"
4090   [(set_attr "type" "*,load")
4091    (set_attr "us3load_type" "*,3cycle")])
4093 (define_expand "zero_extendqidi2"
4094   [(set (match_operand:DI 0 "register_operand" "")
4095         (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
4096   "TARGET_ARCH64"
4097   "")
4099 (define_insn "*zero_extendqidi2_insn"
4100   [(set (match_operand:DI 0 "register_operand" "=r,r")
4101         (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
4102   "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4103   "@
4104    and\t%1, 0xff, %0
4105    ldub\t%1, %0"
4106   [(set_attr "type" "*,load")
4107    (set_attr "us3load_type" "*,3cycle")])
4109 (define_expand "zero_extendhidi2"
4110   [(set (match_operand:DI 0 "register_operand" "")
4111         (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
4112   "TARGET_ARCH64"
4114   rtx temp = gen_reg_rtx (DImode);
4115   rtx shift_48 = GEN_INT (48);
4116   int op1_subbyte = 0;
4118   if (GET_CODE (operand1) == SUBREG)
4119     {
4120       op1_subbyte = SUBREG_BYTE (operand1);
4121       op1_subbyte /= GET_MODE_SIZE (DImode);
4122       op1_subbyte *= GET_MODE_SIZE (DImode);
4123       operand1 = XEXP (operand1, 0);
4124     }
4126   emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4127                           shift_48));
4128   emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
4129   DONE;
4132 (define_insn "*zero_extendhidi2_insn"
4133   [(set (match_operand:DI 0 "register_operand" "=r")
4134         (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4135   "TARGET_ARCH64"
4136   "lduh\t%1, %0"
4137   [(set_attr "type" "load")
4138    (set_attr "us3load_type" "3cycle")])
4141 ;; ??? Write truncdisi pattern using sra?
4143 (define_expand "zero_extendsidi2"
4144   [(set (match_operand:DI 0 "register_operand" "")
4145         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4146   ""
4147   "")
4149 (define_insn "*zero_extendsidi2_insn_sp64"
4150   [(set (match_operand:DI 0 "register_operand" "=r,r")
4151         (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4152   "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4153   "@
4154    srl\t%1, 0, %0
4155    lduw\t%1, %0"
4156   [(set_attr "type" "shift,load")])
4158 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
4159   [(set (match_operand:DI 0 "register_operand" "=r")
4160         (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4161   "! TARGET_ARCH64"
4162   "#"
4163   "&& reload_completed"
4164   [(set (match_dup 2) (match_dup 3))
4165    (set (match_dup 4) (match_dup 5))]
4167   rtx dest1, dest2;
4169   dest1 = gen_highpart (SImode, operands[0]);
4170   dest2 = gen_lowpart (SImode, operands[0]);
4172   /* Swap the order in case of overlap.  */
4173   if (REGNO (dest1) == REGNO (operands[1]))
4174     {
4175       operands[2] = dest2;
4176       operands[3] = operands[1];
4177       operands[4] = dest1;
4178       operands[5] = const0_rtx;
4179     }
4180   else
4181     {
4182       operands[2] = dest1;
4183       operands[3] = const0_rtx;
4184       operands[4] = dest2;
4185       operands[5] = operands[1];
4186     }
4188   [(set_attr "length" "2")])
4190 ;; Simplify comparisons of extended values.
4192 (define_insn "*cmp_zero_extendqisi2"
4193   [(set (reg:CC 100)
4194         (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
4195                     (const_int 0)))]
4196   ""
4197   "andcc\t%0, 0xff, %%g0"
4198   [(set_attr "type" "compare")])
4200 (define_insn "*cmp_zero_qi"
4201   [(set (reg:CC 100)
4202         (compare:CC (match_operand:QI 0 "register_operand" "r")
4203                     (const_int 0)))]
4204   ""
4205   "andcc\t%0, 0xff, %%g0"
4206   [(set_attr "type" "compare")])
4208 (define_insn "*cmp_zero_extendqisi2_set"
4209   [(set (reg:CC 100)
4210         (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
4211                     (const_int 0)))
4212    (set (match_operand:SI 0 "register_operand" "=r")
4213         (zero_extend:SI (match_dup 1)))]
4214   ""
4215   "andcc\t%1, 0xff, %0"
4216   [(set_attr "type" "compare")])
4218 (define_insn "*cmp_zero_extendqisi2_andcc_set"
4219   [(set (reg:CC 100)
4220         (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
4221                             (const_int 255))
4222                     (const_int 0)))
4223    (set (match_operand:SI 0 "register_operand" "=r")
4224         (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
4225   ""
4226   "andcc\t%1, 0xff, %0"
4227   [(set_attr "type" "compare")])
4229 (define_insn "*cmp_zero_extendqidi2"
4230   [(set (reg:CCX 100)
4231         (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
4232                      (const_int 0)))]
4233   "TARGET_ARCH64"
4234   "andcc\t%0, 0xff, %%g0"
4235   [(set_attr "type" "compare")])
4237 (define_insn "*cmp_zero_qi_sp64"
4238   [(set (reg:CCX 100)
4239         (compare:CCX (match_operand:QI 0 "register_operand" "r")
4240                      (const_int 0)))]
4241   "TARGET_ARCH64"
4242   "andcc\t%0, 0xff, %%g0"
4243   [(set_attr "type" "compare")])
4245 (define_insn "*cmp_zero_extendqidi2_set"
4246   [(set (reg:CCX 100)
4247         (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
4248                      (const_int 0)))
4249    (set (match_operand:DI 0 "register_operand" "=r")
4250         (zero_extend:DI (match_dup 1)))]
4251   "TARGET_ARCH64"
4252   "andcc\t%1, 0xff, %0"
4253   [(set_attr "type" "compare")])
4255 (define_insn "*cmp_zero_extendqidi2_andcc_set"
4256   [(set (reg:CCX 100)
4257         (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
4258                              (const_int 255))
4259                      (const_int 0)))
4260    (set (match_operand:DI 0 "register_operand" "=r")
4261         (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
4262   "TARGET_ARCH64"
4263   "andcc\t%1, 0xff, %0"
4264   [(set_attr "type" "compare")])
4266 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
4268 (define_insn "*cmp_siqi_trunc"
4269   [(set (reg:CC 100)
4270         (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
4271                     (const_int 0)))]
4272   ""
4273   "andcc\t%0, 0xff, %%g0"
4274   [(set_attr "type" "compare")])
4276 (define_insn "*cmp_siqi_trunc_set"
4277   [(set (reg:CC 100)
4278         (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
4279                     (const_int 0)))
4280    (set (match_operand:QI 0 "register_operand" "=r")
4281         (subreg:QI (match_dup 1) 3))]
4282   ""
4283   "andcc\t%1, 0xff, %0"
4284   [(set_attr "type" "compare")])
4286 (define_insn "*cmp_diqi_trunc"
4287   [(set (reg:CC 100)
4288         (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
4289                     (const_int 0)))]
4290   "TARGET_ARCH64"
4291   "andcc\t%0, 0xff, %%g0"
4292   [(set_attr "type" "compare")])
4294 (define_insn "*cmp_diqi_trunc_set"
4295   [(set (reg:CC 100)
4296         (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
4297                     (const_int 0)))
4298    (set (match_operand:QI 0 "register_operand" "=r")
4299         (subreg:QI (match_dup 1) 7))]
4300   "TARGET_ARCH64"
4301   "andcc\t%1, 0xff, %0"
4302   [(set_attr "type" "compare")])
4304 ;;- sign extension instructions
4306 ;; These patterns originally accepted general_operands, however, slightly
4307 ;; better code is generated by only accepting register_operands, and then
4308 ;; letting combine generate the lds[hb] insns.
4310 (define_expand "extendhisi2"
4311   [(set (match_operand:SI 0 "register_operand" "")
4312         (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
4313   ""
4315   rtx temp = gen_reg_rtx (SImode);
4316   rtx shift_16 = GEN_INT (16);
4317   int op1_subbyte = 0;
4319   if (GET_CODE (operand1) == SUBREG)
4320     {
4321       op1_subbyte = SUBREG_BYTE (operand1);
4322       op1_subbyte /= GET_MODE_SIZE (SImode);
4323       op1_subbyte *= GET_MODE_SIZE (SImode);
4324       operand1 = XEXP (operand1, 0);
4325     }
4327   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4328                           shift_16));
4329   emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
4330   DONE;
4333 (define_insn "*sign_extendhisi2_insn"
4334   [(set (match_operand:SI 0 "register_operand" "=r")
4335         (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4336   ""
4337   "ldsh\t%1, %0"
4338   [(set_attr "type" "sload")
4339    (set_attr "us3load_type" "3cycle")])
4341 (define_expand "extendqihi2"
4342   [(set (match_operand:HI 0 "register_operand" "")
4343         (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
4344   ""
4346   rtx temp = gen_reg_rtx (SImode);
4347   rtx shift_24 = GEN_INT (24);
4348   int op1_subbyte = 0;
4349   int op0_subbyte = 0;
4351   if (GET_CODE (operand1) == SUBREG)
4352     {
4353       op1_subbyte = SUBREG_BYTE (operand1);
4354       op1_subbyte /= GET_MODE_SIZE (SImode);
4355       op1_subbyte *= GET_MODE_SIZE (SImode);
4356       operand1 = XEXP (operand1, 0);
4357     }
4358   if (GET_CODE (operand0) == SUBREG)
4359     {
4360       op0_subbyte = SUBREG_BYTE (operand0);
4361       op0_subbyte /= GET_MODE_SIZE (SImode);
4362       op0_subbyte *= GET_MODE_SIZE (SImode);
4363       operand0 = XEXP (operand0, 0);
4364     }
4365   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4366                           shift_24));
4367   if (GET_MODE (operand0) != SImode)
4368     operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
4369   emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4370   DONE;
4373 (define_insn "*sign_extendqihi2_insn"
4374   [(set (match_operand:HI 0 "register_operand" "=r")
4375         (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
4376   ""
4377   "ldsb\t%1, %0"
4378   [(set_attr "type" "sload")
4379    (set_attr "us3load_type" "3cycle")])
4381 (define_expand "extendqisi2"
4382   [(set (match_operand:SI 0 "register_operand" "")
4383         (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
4384   ""
4386   rtx temp = gen_reg_rtx (SImode);
4387   rtx shift_24 = GEN_INT (24);
4388   int op1_subbyte = 0;
4390   if (GET_CODE (operand1) == SUBREG)
4391     {
4392       op1_subbyte = SUBREG_BYTE (operand1);
4393       op1_subbyte /= GET_MODE_SIZE (SImode);
4394       op1_subbyte *= GET_MODE_SIZE (SImode);
4395       operand1 = XEXP (operand1, 0);
4396     }
4398   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4399                           shift_24));
4400   emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4401   DONE;
4404 (define_insn "*sign_extendqisi2_insn"
4405   [(set (match_operand:SI 0 "register_operand" "=r")
4406         (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
4407   ""
4408   "ldsb\t%1, %0"
4409   [(set_attr "type" "sload")
4410    (set_attr "us3load_type" "3cycle")])
4412 (define_expand "extendqidi2"
4413   [(set (match_operand:DI 0 "register_operand" "")
4414         (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
4415   "TARGET_ARCH64"
4417   rtx temp = gen_reg_rtx (DImode);
4418   rtx shift_56 = GEN_INT (56);
4419   int op1_subbyte = 0;
4421   if (GET_CODE (operand1) == SUBREG)
4422     {
4423       op1_subbyte = SUBREG_BYTE (operand1);
4424       op1_subbyte /= GET_MODE_SIZE (DImode);
4425       op1_subbyte *= GET_MODE_SIZE (DImode);
4426       operand1 = XEXP (operand1, 0);
4427     }
4429   emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4430                           shift_56));
4431   emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
4432   DONE;
4435 (define_insn "*sign_extendqidi2_insn"
4436   [(set (match_operand:DI 0 "register_operand" "=r")
4437         (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
4438   "TARGET_ARCH64"
4439   "ldsb\t%1, %0"
4440   [(set_attr "type" "sload")
4441    (set_attr "us3load_type" "3cycle")])
4443 (define_expand "extendhidi2"
4444   [(set (match_operand:DI 0 "register_operand" "")
4445         (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
4446   "TARGET_ARCH64"
4448   rtx temp = gen_reg_rtx (DImode);
4449   rtx shift_48 = GEN_INT (48);
4450   int op1_subbyte = 0;
4452   if (GET_CODE (operand1) == SUBREG)
4453     {
4454       op1_subbyte = SUBREG_BYTE (operand1);
4455       op1_subbyte /= GET_MODE_SIZE (DImode);
4456       op1_subbyte *= GET_MODE_SIZE (DImode);
4457       operand1 = XEXP (operand1, 0);
4458     }
4460   emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4461                           shift_48));
4462   emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
4463   DONE;
4466 (define_insn "*sign_extendhidi2_insn"
4467   [(set (match_operand:DI 0 "register_operand" "=r")
4468         (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4469   "TARGET_ARCH64"
4470   "ldsh\t%1, %0"
4471   [(set_attr "type" "sload")
4472    (set_attr "us3load_type" "3cycle")])
4474 (define_expand "extendsidi2"
4475   [(set (match_operand:DI 0 "register_operand" "")
4476         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
4477   "TARGET_ARCH64"
4478   "")
4480 (define_insn "*sign_extendsidi2_insn"
4481   [(set (match_operand:DI 0 "register_operand" "=r,r")
4482         (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4483   "TARGET_ARCH64"
4484   "@
4485   sra\t%1, 0, %0
4486   ldsw\t%1, %0"
4487   [(set_attr "type" "shift,sload")
4488    (set_attr "us3load_type" "*,3cycle")])
4490 ;; Special pattern for optimizing bit-field compares.  This is needed
4491 ;; because combine uses this as a canonical form.
4493 (define_insn "*cmp_zero_extract"
4494   [(set (reg:CC 100)
4495         (compare:CC
4496          (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
4497                           (match_operand:SI 1 "small_int_or_double" "n")
4498                           (match_operand:SI 2 "small_int_or_double" "n"))
4499          (const_int 0)))]
4500   "(GET_CODE (operands[2]) == CONST_INT
4501     && INTVAL (operands[2]) > 19)
4502    || (GET_CODE (operands[2]) == CONST_DOUBLE
4503        && CONST_DOUBLE_LOW (operands[2]) > 19)"
4505   int len = (GET_CODE (operands[1]) == CONST_INT
4506              ? INTVAL (operands[1])
4507              : CONST_DOUBLE_LOW (operands[1]));
4508   int pos = 32 -
4509             (GET_CODE (operands[2]) == CONST_INT
4510              ? INTVAL (operands[2])
4511              : CONST_DOUBLE_LOW (operands[2])) - len;
4512   HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
4514   operands[1] = GEN_INT (mask);
4515   return "andcc\t%0, %1, %%g0";
4517   [(set_attr "type" "compare")])
4519 (define_insn "*cmp_zero_extract_sp64"
4520   [(set (reg:CCX 100)
4521         (compare:CCX
4522          (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
4523                           (match_operand:SI 1 "small_int_or_double" "n")
4524                           (match_operand:SI 2 "small_int_or_double" "n"))
4525          (const_int 0)))]
4526   "TARGET_ARCH64
4527    && ((GET_CODE (operands[2]) == CONST_INT
4528         && INTVAL (operands[2]) > 51)
4529        || (GET_CODE (operands[2]) == CONST_DOUBLE
4530            && CONST_DOUBLE_LOW (operands[2]) > 51))"
4532   int len = (GET_CODE (operands[1]) == CONST_INT
4533              ? INTVAL (operands[1])
4534              : CONST_DOUBLE_LOW (operands[1]));
4535   int pos = 64 -
4536             (GET_CODE (operands[2]) == CONST_INT
4537              ? INTVAL (operands[2])
4538              : CONST_DOUBLE_LOW (operands[2])) - len;
4539   HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
4541   operands[1] = GEN_INT (mask);
4542   return "andcc\t%0, %1, %%g0";
4544   [(set_attr "type" "compare")])
4546 ;; Conversions between float, double and long double.
4548 (define_insn "extendsfdf2"
4549   [(set (match_operand:DF 0 "register_operand" "=e")
4550         (float_extend:DF
4551          (match_operand:SF 1 "register_operand" "f")))]
4552   "TARGET_FPU"
4553   "fstod\t%1, %0"
4554   [(set_attr "type" "fp")
4555    (set_attr "fptype" "double")])
4557 (define_expand "extendsftf2"
4558   [(set (match_operand:TF 0 "nonimmediate_operand" "")
4559         (float_extend:TF
4560          (match_operand:SF 1 "register_operand" "")))]
4561   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4562   "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4564 (define_insn "*extendsftf2_hq"
4565   [(set (match_operand:TF 0 "register_operand" "=e")
4566         (float_extend:TF
4567          (match_operand:SF 1 "register_operand" "f")))]
4568   "TARGET_FPU && TARGET_HARD_QUAD"
4569   "fstoq\t%1, %0"
4570   [(set_attr "type" "fp")])
4572 (define_expand "extenddftf2"
4573   [(set (match_operand:TF 0 "nonimmediate_operand" "")
4574         (float_extend:TF
4575          (match_operand:DF 1 "register_operand" "")))]
4576   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4577   "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4579 (define_insn "*extenddftf2_hq"
4580   [(set (match_operand:TF 0 "register_operand" "=e")
4581         (float_extend:TF
4582          (match_operand:DF 1 "register_operand" "e")))]
4583   "TARGET_FPU && TARGET_HARD_QUAD"
4584   "fdtoq\t%1, %0"
4585   [(set_attr "type" "fp")])
4587 (define_insn "truncdfsf2"
4588   [(set (match_operand:SF 0 "register_operand" "=f")
4589         (float_truncate:SF
4590          (match_operand:DF 1 "register_operand" "e")))]
4591   "TARGET_FPU"
4592   "fdtos\t%1, %0"
4593   [(set_attr "type" "fp")
4594    (set_attr "fptype" "double")])
4596 (define_expand "trunctfsf2"
4597   [(set (match_operand:SF 0 "register_operand" "")
4598         (float_truncate:SF
4599          (match_operand:TF 1 "general_operand" "")))]
4600   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4601   "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4603 (define_insn "*trunctfsf2_hq"
4604   [(set (match_operand:SF 0 "register_operand" "=f")
4605         (float_truncate:SF
4606          (match_operand:TF 1 "register_operand" "e")))]
4607   "TARGET_FPU && TARGET_HARD_QUAD"
4608   "fqtos\t%1, %0"
4609   [(set_attr "type" "fp")])
4611 (define_expand "trunctfdf2"
4612   [(set (match_operand:DF 0 "register_operand" "")
4613         (float_truncate:DF
4614          (match_operand:TF 1 "general_operand" "")))]
4615   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4616   "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4618 (define_insn "*trunctfdf2_hq"
4619   [(set (match_operand:DF 0 "register_operand" "=e")
4620         (float_truncate:DF
4621          (match_operand:TF 1 "register_operand" "e")))]
4622   "TARGET_FPU && TARGET_HARD_QUAD"
4623   "fqtod\t%1, %0"
4624   [(set_attr "type" "fp")])
4626 ;; Conversion between fixed point and floating point.
4628 (define_insn "floatsisf2"
4629   [(set (match_operand:SF 0 "register_operand" "=f")
4630         (float:SF (match_operand:SI 1 "register_operand" "f")))]
4631   "TARGET_FPU"
4632   "fitos\t%1, %0"
4633   [(set_attr "type" "fp")
4634    (set_attr "fptype" "double")])
4636 (define_insn "floatsidf2"
4637   [(set (match_operand:DF 0 "register_operand" "=e")
4638         (float:DF (match_operand:SI 1 "register_operand" "f")))]
4639   "TARGET_FPU"
4640   "fitod\t%1, %0"
4641   [(set_attr "type" "fp")
4642    (set_attr "fptype" "double")])
4644 (define_expand "floatsitf2"
4645   [(set (match_operand:TF 0 "nonimmediate_operand" "")
4646         (float:TF (match_operand:SI 1 "register_operand" "")))]
4647   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4648   "emit_tfmode_cvt (FLOAT, operands); DONE;")
4650 (define_insn "*floatsitf2_hq"
4651   [(set (match_operand:TF 0 "register_operand" "=e")
4652         (float:TF (match_operand:SI 1 "register_operand" "f")))]
4653   "TARGET_FPU && TARGET_HARD_QUAD"
4654   "fitoq\t%1, %0"
4655   [(set_attr "type" "fp")])
4657 (define_expand "floatunssitf2"
4658   [(set (match_operand:TF 0 "nonimmediate_operand" "")
4659         (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
4660   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4661   "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4663 ;; Now the same for 64 bit sources.
4665 (define_insn "floatdisf2"
4666   [(set (match_operand:SF 0 "register_operand" "=f")
4667         (float:SF (match_operand:DI 1 "register_operand" "e")))]
4668   "TARGET_V9 && TARGET_FPU"
4669   "fxtos\t%1, %0"
4670   [(set_attr "type" "fp")
4671    (set_attr "fptype" "double")])
4673 (define_expand "floatunsdisf2"
4674   [(use (match_operand:SF 0 "register_operand" ""))
4675    (use (match_operand:DI 1 "general_operand" ""))]
4676   "TARGET_ARCH64 && TARGET_FPU"
4677   "sparc_emit_floatunsdi (operands, SFmode); DONE;")
4679 (define_insn "floatdidf2"
4680   [(set (match_operand:DF 0 "register_operand" "=e")
4681         (float:DF (match_operand:DI 1 "register_operand" "e")))]
4682   "TARGET_V9 && TARGET_FPU"
4683   "fxtod\t%1, %0"
4684   [(set_attr "type" "fp")
4685    (set_attr "fptype" "double")])
4687 (define_expand "floatunsdidf2"
4688   [(use (match_operand:DF 0 "register_operand" ""))
4689    (use (match_operand:DI 1 "general_operand" ""))]
4690   "TARGET_ARCH64 && TARGET_FPU"
4691   "sparc_emit_floatunsdi (operands, DFmode); DONE;")
4693 (define_expand "floatditf2"
4694   [(set (match_operand:TF 0 "nonimmediate_operand" "")
4695         (float:TF (match_operand:DI 1 "register_operand" "")))]
4696   "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4697   "emit_tfmode_cvt (FLOAT, operands); DONE;")
4699 (define_insn "*floatditf2_hq"
4700   [(set (match_operand:TF 0 "register_operand" "=e")
4701         (float:TF (match_operand:DI 1 "register_operand" "e")))]
4702   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4703   "fxtoq\t%1, %0"
4704   [(set_attr "type" "fp")])
4706 (define_expand "floatunsditf2"
4707   [(set (match_operand:TF 0 "nonimmediate_operand" "")
4708         (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
4709   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4710   "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4712 ;; Convert a float to an actual integer.
4713 ;; Truncation is performed as part of the conversion.
4715 (define_insn "fix_truncsfsi2"
4716   [(set (match_operand:SI 0 "register_operand" "=f")
4717         (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4718   "TARGET_FPU"
4719   "fstoi\t%1, %0"
4720   [(set_attr "type" "fp")
4721    (set_attr "fptype" "double")])
4723 (define_insn "fix_truncdfsi2"
4724   [(set (match_operand:SI 0 "register_operand" "=f")
4725         (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4726   "TARGET_FPU"
4727   "fdtoi\t%1, %0"
4728   [(set_attr "type" "fp")
4729    (set_attr "fptype" "double")])
4731 (define_expand "fix_trunctfsi2"
4732   [(set (match_operand:SI 0 "register_operand" "")
4733         (fix:SI (match_operand:TF 1 "general_operand" "")))]
4734   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4735   "emit_tfmode_cvt (FIX, operands); DONE;")
4737 (define_insn "*fix_trunctfsi2_hq"
4738   [(set (match_operand:SI 0 "register_operand" "=f")
4739         (fix:SI (match_operand:TF 1 "register_operand" "e")))]
4740   "TARGET_FPU && TARGET_HARD_QUAD"
4741   "fqtoi\t%1, %0"
4742   [(set_attr "type" "fp")])
4744 (define_expand "fixuns_trunctfsi2"
4745   [(set (match_operand:SI 0 "register_operand" "")
4746         (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
4747   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4748   "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4750 ;; Now the same, for V9 targets
4752 (define_insn "fix_truncsfdi2"
4753   [(set (match_operand:DI 0 "register_operand" "=e")
4754         (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4755   "TARGET_V9 && TARGET_FPU"
4756   "fstox\t%1, %0"
4757   [(set_attr "type" "fp")
4758    (set_attr "fptype" "double")])
4760 (define_expand "fixuns_truncsfdi2"
4761   [(use (match_operand:DI 0 "register_operand" ""))
4762    (use (match_operand:SF 1 "general_operand" ""))]
4763   "TARGET_ARCH64 && TARGET_FPU"
4764   "sparc_emit_fixunsdi (operands, SFmode); DONE;")
4766 (define_insn "fix_truncdfdi2"
4767   [(set (match_operand:DI 0 "register_operand" "=e")
4768         (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4769   "TARGET_V9 && TARGET_FPU"
4770   "fdtox\t%1, %0"
4771   [(set_attr "type" "fp")
4772    (set_attr "fptype" "double")])
4774 (define_expand "fixuns_truncdfdi2"
4775   [(use (match_operand:DI 0 "register_operand" ""))
4776    (use (match_operand:DF 1 "general_operand" ""))]
4777   "TARGET_ARCH64 && TARGET_FPU"
4778   "sparc_emit_fixunsdi (operands, DFmode); DONE;")
4780 (define_expand "fix_trunctfdi2"
4781   [(set (match_operand:DI 0 "register_operand" "")
4782         (fix:DI (match_operand:TF 1 "general_operand" "")))]
4783   "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4784   "emit_tfmode_cvt (FIX, operands); DONE;")
4786 (define_insn "*fix_trunctfdi2_hq"
4787   [(set (match_operand:DI 0 "register_operand" "=e")
4788         (fix:DI (match_operand:TF 1 "register_operand" "e")))]
4789   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4790   "fqtox\t%1, %0"
4791   [(set_attr "type" "fp")])
4793 (define_expand "fixuns_trunctfdi2"
4794   [(set (match_operand:DI 0 "register_operand" "")
4795         (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
4796   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4797   "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4799 ;;- arithmetic instructions
4801 (define_expand "adddi3"
4802   [(set (match_operand:DI 0 "register_operand" "")
4803         (plus:DI (match_operand:DI 1 "register_operand" "")
4804                  (match_operand:DI 2 "arith_double_add_operand" "")))]
4805   ""
4807   if (! TARGET_ARCH64)
4808     {
4809       emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4810                           gen_rtx_SET (VOIDmode, operands[0],
4811                                    gen_rtx_PLUS (DImode, operands[1],
4812                                                  operands[2])),
4813                           gen_rtx_CLOBBER (VOIDmode,
4814                                    gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4815       DONE;
4816     }
4819 (define_insn_and_split "adddi3_insn_sp32"
4820   [(set (match_operand:DI 0 "register_operand" "=r")
4821         (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4822                  (match_operand:DI 2 "arith_double_operand" "rHI")))
4823    (clobber (reg:CC 100))]
4824   "! TARGET_ARCH64"
4825   "#"
4826   "&& reload_completed"
4827   [(parallel [(set (reg:CC_NOOV 100)
4828                    (compare:CC_NOOV (plus:SI (match_dup 4)
4829                                              (match_dup 5))
4830                                     (const_int 0)))
4831               (set (match_dup 3)
4832                    (plus:SI (match_dup 4) (match_dup 5)))])
4833    (set (match_dup 6)
4834         (plus:SI (plus:SI (match_dup 7)
4835                           (match_dup 8))
4836                  (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4838   operands[3] = gen_lowpart (SImode, operands[0]);
4839   operands[4] = gen_lowpart (SImode, operands[1]);
4840   operands[5] = gen_lowpart (SImode, operands[2]);
4841   operands[6] = gen_highpart (SImode, operands[0]);
4842   operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
4843 #if HOST_BITS_PER_WIDE_INT == 32
4844   if (GET_CODE (operands[2]) == CONST_INT)
4845     {
4846       if (INTVAL (operands[2]) < 0)
4847         operands[8] = constm1_rtx;
4848       else
4849         operands[8] = const0_rtx;
4850     }
4851   else
4852 #endif
4853     operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4855   [(set_attr "length" "2")])
4857 (define_split
4858   [(set (match_operand:DI 0 "register_operand" "")
4859         (minus:DI (match_operand:DI 1 "arith_double_operand" "")
4860                   (match_operand:DI 2 "arith_double_operand" "")))
4861    (clobber (reg:CC 100))]
4862   "! TARGET_ARCH64 && reload_completed"
4863   [(parallel [(set (reg:CC_NOOV 100)
4864                    (compare:CC_NOOV (minus:SI (match_dup 4)
4865                                               (match_dup 5))
4866                                     (const_int 0)))
4867               (set (match_dup 3)
4868                    (minus:SI (match_dup 4) (match_dup 5)))])
4869    (set (match_dup 6)
4870         (minus:SI (minus:SI (match_dup 7)
4871                             (match_dup 8))
4872                   (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4874   operands[3] = gen_lowpart (SImode, operands[0]);
4875   operands[4] = gen_lowpart (SImode, operands[1]);
4876   operands[5] = gen_lowpart (SImode, operands[2]);
4877   operands[6] = gen_highpart (SImode, operands[0]);
4878   operands[7] = gen_highpart (SImode, operands[1]);
4879 #if HOST_BITS_PER_WIDE_INT == 32
4880   if (GET_CODE (operands[2]) == CONST_INT)
4881     {
4882       if (INTVAL (operands[2]) < 0)
4883         operands[8] = constm1_rtx;
4884       else
4885         operands[8] = const0_rtx;
4886     }
4887   else
4888 #endif
4889     operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4892 ;; LTU here means "carry set"
4893 (define_insn "addx"
4894   [(set (match_operand:SI 0 "register_operand" "=r")
4895         (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4896                           (match_operand:SI 2 "arith_operand" "rI"))
4897                  (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4898   ""
4899   "addx\t%1, %2, %0"
4900   [(set_attr "type" "ialuX")])
4902 (define_insn_and_split "*addx_extend_sp32"
4903   [(set (match_operand:DI 0 "register_operand" "=r")
4904         (zero_extend:DI (plus:SI (plus:SI
4905                                   (match_operand:SI 1 "reg_or_0_operand" "%rJ")
4906                                   (match_operand:SI 2 "arith_operand" "rI"))
4907                                  (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4908   "! TARGET_ARCH64"
4909   "#"
4910   "&& reload_completed"
4911   [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
4912                                (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4913    (set (match_dup 4) (const_int 0))]
4914   "operands[3] = gen_lowpart (SImode, operands[0]);
4915    operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
4916   [(set_attr "length" "2")])
4918 (define_insn "*addx_extend_sp64"
4919   [(set (match_operand:DI 0 "register_operand" "=r")
4920         (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
4921                                           (match_operand:SI 2 "arith_operand" "rI"))
4922                                  (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4923   "TARGET_ARCH64"
4924   "addx\t%r1, %2, %0"
4925   [(set_attr "type" "ialuX")])
4927 (define_insn "subx"
4928   [(set (match_operand:SI 0 "register_operand" "=r")
4929         (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4930                             (match_operand:SI 2 "arith_operand" "rI"))
4931                   (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4932   ""
4933   "subx\t%r1, %2, %0"
4934   [(set_attr "type" "ialuX")])
4936 (define_insn "*subx_extend_sp64"
4937   [(set (match_operand:DI 0 "register_operand" "=r")
4938         (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4939                                             (match_operand:SI 2 "arith_operand" "rI"))
4940                                   (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4941   "TARGET_ARCH64"
4942   "subx\t%r1, %2, %0"
4943   [(set_attr "type" "ialuX")])
4945 (define_insn_and_split "*subx_extend"
4946   [(set (match_operand:DI 0 "register_operand" "=r")
4947         (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
4948                                             (match_operand:SI 2 "arith_operand" "rI"))
4949                                   (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4950   "! TARGET_ARCH64"
4951   "#"
4952   "&& reload_completed"
4953   [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
4954                                 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4955    (set (match_dup 4) (const_int 0))]
4956   "operands[3] = gen_lowpart (SImode, operands[0]);
4957    operands[4] = gen_highpart (SImode, operands[0]);"
4958   [(set_attr "length" "2")])
4960 (define_insn_and_split ""
4961   [(set (match_operand:DI 0 "register_operand" "=r")
4962         (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4963                  (match_operand:DI 2 "register_operand" "r")))
4964    (clobber (reg:CC 100))]
4965   "! TARGET_ARCH64"
4966   "#"
4967   "&& reload_completed"
4968   [(parallel [(set (reg:CC_NOOV 100)
4969                    (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
4970                                     (const_int 0)))
4971               (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
4972    (set (match_dup 6)
4973         (plus:SI (plus:SI (match_dup 4) (const_int 0))
4974                  (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4975   "operands[3] = gen_lowpart (SImode, operands[2]);
4976    operands[4] = gen_highpart (SImode, operands[2]);
4977    operands[5] = gen_lowpart (SImode, operands[0]);
4978    operands[6] = gen_highpart (SImode, operands[0]);"
4979   [(set_attr "length" "2")])
4981 (define_insn "*adddi3_sp64"
4982   [(set (match_operand:DI 0 "register_operand" "=r,r")
4983         (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
4984                  (match_operand:DI 2 "arith_double_add_operand" "rHI,O")))]
4985   "TARGET_ARCH64"
4986   "@
4987    add\t%1, %2, %0
4988    sub\t%1, -%2, %0")
4990 (define_insn "addsi3"
4991   [(set (match_operand:SI 0 "register_operand" "=r,r,d")
4992         (plus:SI (match_operand:SI 1 "register_operand" "%r,r,d")
4993                  (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
4994   ""
4995   "@
4996    add\t%1, %2, %0
4997    sub\t%1, -%2, %0
4998    fpadd32s\t%1, %2, %0"
4999   [(set_attr "type" "*,*,fga")])
5001 (define_insn "*cmp_cc_plus"
5002   [(set (reg:CC_NOOV 100)
5003         (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
5004                                   (match_operand:SI 1 "arith_operand" "rI"))
5005                          (const_int 0)))]
5006   ""
5007   "addcc\t%0, %1, %%g0"
5008   [(set_attr "type" "compare")])
5010 (define_insn "*cmp_ccx_plus"
5011   [(set (reg:CCX_NOOV 100)
5012         (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_double_operand" "%r")
5013                                    (match_operand:DI 1 "arith_double_operand" "rHI"))
5014                           (const_int 0)))]
5015   "TARGET_ARCH64"
5016   "addcc\t%0, %1, %%g0"
5017   [(set_attr "type" "compare")])
5019 (define_insn "*cmp_cc_plus_set"
5020   [(set (reg:CC_NOOV 100)
5021         (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5022                                   (match_operand:SI 2 "arith_operand" "rI"))
5023                          (const_int 0)))
5024    (set (match_operand:SI 0 "register_operand" "=r")
5025         (plus:SI (match_dup 1) (match_dup 2)))]
5026   ""
5027   "addcc\t%1, %2, %0"
5028   [(set_attr "type" "compare")])
5030 (define_insn "*cmp_ccx_plus_set"
5031   [(set (reg:CCX_NOOV 100)
5032         (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5033                                    (match_operand:DI 2 "arith_double_operand" "rHI"))
5034                           (const_int 0)))
5035    (set (match_operand:DI 0 "register_operand" "=r")
5036         (plus:DI (match_dup 1) (match_dup 2)))]
5037   "TARGET_ARCH64"
5038   "addcc\t%1, %2, %0"
5039   [(set_attr "type" "compare")])
5041 (define_expand "subdi3"
5042   [(set (match_operand:DI 0 "register_operand" "")
5043         (minus:DI (match_operand:DI 1 "register_operand" "")
5044                   (match_operand:DI 2 "arith_double_add_operand" "")))]
5045   ""
5047   if (! TARGET_ARCH64)
5048     {
5049       emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5050                           gen_rtx_SET (VOIDmode, operands[0],
5051                                    gen_rtx_MINUS (DImode, operands[1],
5052                                                   operands[2])),
5053                           gen_rtx_CLOBBER (VOIDmode,
5054                                    gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5055       DONE;
5056     }
5059 (define_insn_and_split "*subdi3_sp32"
5060   [(set (match_operand:DI 0 "register_operand" "=r")
5061         (minus:DI (match_operand:DI 1 "register_operand" "r")
5062                   (match_operand:DI 2 "arith_double_operand" "rHI")))
5063    (clobber (reg:CC 100))]
5064   "! TARGET_ARCH64"
5065   "#"
5066   "&& reload_completed
5067    && (GET_CODE (operands[2]) == CONST_INT
5068        || GET_CODE (operands[2]) == CONST_DOUBLE)"
5069   [(clobber (const_int 0))]
5071   rtx highp, lowp;
5073   highp = gen_highpart_mode (SImode, DImode, operands[2]);
5074   lowp = gen_lowpart (SImode, operands[2]);
5075   if ((lowp == const0_rtx)
5076       && (operands[0] == operands[1]))
5077     {
5078       emit_insn (gen_rtx_SET (VOIDmode,
5079                               gen_highpart (SImode, operands[0]),
5080                               gen_rtx_MINUS (SImode,
5081                                              gen_highpart_mode (SImode, DImode,
5082                                                                 operands[1]),
5083                                              highp)));
5084     }
5085   else
5086     {
5087       emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5088                                        gen_lowpart (SImode, operands[1]),
5089                                        lowp));
5090       emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5091                            gen_highpart_mode (SImode, DImode, operands[1]),
5092                            highp));
5093     }
5094   DONE;
5096   [(set_attr "length" "2")])
5098 (define_split
5099   [(set (match_operand:DI 0 "register_operand" "")
5100         (minus:DI (match_operand:DI 1 "register_operand" "")
5101                   (match_operand:DI 2 "register_operand" "")))
5102    (clobber (reg:CC 100))]
5103   "! TARGET_ARCH64
5104    && reload_completed"
5105   [(clobber (const_int 0))]
5107   emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5108                                    gen_lowpart (SImode, operands[1]),
5109                                    gen_lowpart (SImode, operands[2])));
5110   emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5111                        gen_highpart (SImode, operands[1]),
5112                        gen_highpart (SImode, operands[2])));
5113   DONE;
5116 (define_insn_and_split ""
5117   [(set (match_operand:DI 0 "register_operand" "=r")
5118       (minus:DI (match_operand:DI 1 "register_operand" "r")
5119                 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
5120    (clobber (reg:CC 100))]
5121   "! TARGET_ARCH64"
5122   "#"
5123   "&& reload_completed"
5124   [(parallel [(set (reg:CC_NOOV 100)
5125                    (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
5126                                     (const_int 0)))
5127               (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
5128    (set (match_dup 6)
5129         (minus:SI (minus:SI (match_dup 4) (const_int 0))
5130                   (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5131   "operands[3] = gen_lowpart (SImode, operands[1]);
5132    operands[4] = gen_highpart (SImode, operands[1]);
5133    operands[5] = gen_lowpart (SImode, operands[0]);
5134    operands[6] = gen_highpart (SImode, operands[0]);"
5135   [(set_attr "length" "2")])
5137 (define_insn "*subdi3_sp64"
5138   [(set (match_operand:DI 0 "register_operand" "=r,r")
5139         (minus:DI (match_operand:DI 1 "register_operand" "r,r")
5140                   (match_operand:DI 2 "arith_double_add_operand" "rHI,O")))]
5141   "TARGET_ARCH64"
5142   "@
5143    sub\t%1, %2, %0
5144    add\t%1, -%2, %0")
5146 (define_insn "subsi3"
5147   [(set (match_operand:SI 0 "register_operand" "=r,r,d")
5148         (minus:SI (match_operand:SI 1 "register_operand" "r,r,d")
5149                   (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
5150   ""
5151   "@
5152    sub\t%1, %2, %0
5153    add\t%1, -%2, %0
5154    fpsub32s\t%1, %2, %0"
5155   [(set_attr "type" "*,*,fga")])
5157 (define_insn "*cmp_minus_cc"
5158   [(set (reg:CC_NOOV 100)
5159         (compare:CC_NOOV (minus:SI (match_operand:SI 0 "reg_or_0_operand" "rJ")
5160                                    (match_operand:SI 1 "arith_operand" "rI"))
5161                          (const_int 0)))]
5162   ""
5163   "subcc\t%r0, %1, %%g0"
5164   [(set_attr "type" "compare")])
5166 (define_insn "*cmp_minus_ccx"
5167   [(set (reg:CCX_NOOV 100)
5168         (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
5169                                     (match_operand:DI 1 "arith_double_operand" "rHI"))
5170                           (const_int 0)))]
5171   "TARGET_ARCH64"
5172   "subcc\t%0, %1, %%g0"
5173   [(set_attr "type" "compare")])
5175 (define_insn "cmp_minus_cc_set"
5176   [(set (reg:CC_NOOV 100)
5177         (compare:CC_NOOV (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5178                                    (match_operand:SI 2 "arith_operand" "rI"))
5179                          (const_int 0)))
5180    (set (match_operand:SI 0 "register_operand" "=r")
5181         (minus:SI (match_dup 1) (match_dup 2)))]
5182   ""
5183   "subcc\t%r1, %2, %0"
5184   [(set_attr "type" "compare")])
5186 (define_insn "*cmp_minus_ccx_set"
5187   [(set (reg:CCX_NOOV 100)
5188         (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
5189                                     (match_operand:DI 2 "arith_double_operand" "rHI"))
5190                           (const_int 0)))
5191    (set (match_operand:DI 0 "register_operand" "=r")
5192         (minus:DI (match_dup 1) (match_dup 2)))]
5193   "TARGET_ARCH64"
5194   "subcc\t%1, %2, %0"
5195   [(set_attr "type" "compare")])
5197 ;; Integer Multiply/Divide.
5199 ;; The 32 bit multiply/divide instructions are deprecated on v9, but at
5200 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
5202 (define_insn "mulsi3"
5203   [(set (match_operand:SI 0 "register_operand" "=r")
5204         (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5205                  (match_operand:SI 2 "arith_operand" "rI")))]
5206   "TARGET_HARD_MUL"
5207   "smul\t%1, %2, %0"
5208   [(set_attr "type" "imul")])
5210 (define_expand "muldi3"
5211   [(set (match_operand:DI 0 "register_operand" "=r")
5212         (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5213                  (match_operand:DI 2 "arith_double_operand" "rHI")))]
5214   "TARGET_ARCH64 || TARGET_V8PLUS"
5216   if (TARGET_V8PLUS)
5217     {
5218       emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
5219       DONE;
5220     }
5223 (define_insn "*muldi3_sp64"
5224   [(set (match_operand:DI 0 "register_operand" "=r")
5225         (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5226                  (match_operand:DI 2 "arith_double_operand" "rHI")))]
5227   "TARGET_ARCH64"
5228   "mulx\t%1, %2, %0"
5229   [(set_attr "type" "imul")])
5231 ;; V8plus wide multiply.
5232 ;; XXX
5233 (define_insn "muldi3_v8plus"
5234   [(set (match_operand:DI 0 "register_operand" "=r,h")
5235         (mult:DI (match_operand:DI 1 "arith_double_operand" "%r,0")
5236                  (match_operand:DI 2 "arith_double_operand" "rI,rI")))
5237    (clobber (match_scratch:SI 3 "=&h,X"))
5238    (clobber (match_scratch:SI 4 "=&h,X"))]
5239   "TARGET_V8PLUS"
5241   if (sparc_check_64 (operands[1], insn) <= 0)
5242     output_asm_insn ("srl\t%L1, 0, %L1", operands);
5243   if (which_alternative == 1)
5244     output_asm_insn ("sllx\t%H1, 32, %H1", operands);
5245   if (GET_CODE (operands[2]) == CONST_INT)
5246     {
5247       if (which_alternative == 1)
5248         return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %2, %L0\;srlx\t%L0, 32, %H0";
5249       else
5250         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";
5251     }
5252   else if (rtx_equal_p (operands[1], operands[2]))
5253     {
5254       if (which_alternative == 1)
5255         return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %H1, %L0\;srlx\t%L0, 32, %H0";
5256       else
5257         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";
5258     }
5259   if (sparc_check_64 (operands[2], insn) <= 0)
5260     output_asm_insn ("srl\t%L2, 0, %L2", operands);
5261   if (which_alternative == 1)
5262     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";
5263   else
5264     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";
5266   [(set_attr "type" "multi")
5267    (set_attr "length" "9,8")])
5269 (define_insn "*cmp_mul_set"
5270   [(set (reg:CC 100)
5271         (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5272                     (match_operand:SI 2 "arith_operand" "rI"))
5273                     (const_int 0)))
5274    (set (match_operand:SI 0 "register_operand" "=r")
5275         (mult:SI (match_dup 1) (match_dup 2)))]
5276   "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
5277   "smulcc\t%1, %2, %0"
5278   [(set_attr "type" "imul")])
5280 (define_expand "mulsidi3"
5281   [(set (match_operand:DI 0 "register_operand" "")
5282         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5283                  (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
5284   "TARGET_HARD_MUL"
5286   if (CONSTANT_P (operands[2]))
5287     {
5288       if (TARGET_V8PLUS)
5289         emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
5290                                               operands[2]));
5291       else if (TARGET_ARCH32)
5292         emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
5293                                             operands[2]));
5294       else 
5295         emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
5296                                             operands[2]));
5297       DONE;
5298     }
5299   if (TARGET_V8PLUS)
5300     {
5301       emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
5302       DONE;
5303     }
5306 ;; V9 puts the 64 bit product in a 64 bit register.  Only out or global
5307 ;; registers can hold 64 bit values in the V8plus environment.
5308 ;; XXX
5309 (define_insn "mulsidi3_v8plus"
5310   [(set (match_operand:DI 0 "register_operand" "=h,r")
5311         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5312                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5313    (clobber (match_scratch:SI 3 "=X,&h"))]
5314   "TARGET_V8PLUS"
5315   "@
5316    smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5317    smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5318   [(set_attr "type" "multi")
5319    (set_attr "length" "2,3")])
5321 ;; XXX
5322 (define_insn "const_mulsidi3_v8plus"
5323   [(set (match_operand:DI 0 "register_operand" "=h,r")
5324         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5325                  (match_operand:DI 2 "small_int" "I,I")))
5326    (clobber (match_scratch:SI 3 "=X,&h"))]
5327   "TARGET_V8PLUS"
5328   "@
5329    smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5330    smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5331   [(set_attr "type" "multi")
5332    (set_attr "length" "2,3")])
5334 ;; XXX
5335 (define_insn "*mulsidi3_sp32"
5336   [(set (match_operand:DI 0 "register_operand" "=r")
5337         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5338                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5339   "TARGET_HARD_MUL32"
5341   return TARGET_SPARCLET
5342          ? "smuld\t%1, %2, %L0"
5343          : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
5345   [(set (attr "type")
5346         (if_then_else (eq_attr "isa" "sparclet")
5347                       (const_string "imul") (const_string "multi")))
5348    (set (attr "length")
5349         (if_then_else (eq_attr "isa" "sparclet")
5350                       (const_int 1) (const_int 2)))])
5352 (define_insn "*mulsidi3_sp64"
5353   [(set (match_operand:DI 0 "register_operand" "=r")
5354         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5355                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5356   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5357   "smul\t%1, %2, %0"
5358   [(set_attr "type" "imul")])
5360 ;; Extra pattern, because sign_extend of a constant isn't valid.
5362 ;; XXX
5363 (define_insn "const_mulsidi3_sp32"
5364   [(set (match_operand:DI 0 "register_operand" "=r")
5365         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5366                  (match_operand:DI 2 "small_int" "I")))]
5367   "TARGET_HARD_MUL32"
5369   return TARGET_SPARCLET
5370          ? "smuld\t%1, %2, %L0"
5371          : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
5373   [(set (attr "type")
5374         (if_then_else (eq_attr "isa" "sparclet")
5375                       (const_string "imul") (const_string "multi")))
5376    (set (attr "length")
5377         (if_then_else (eq_attr "isa" "sparclet")
5378                       (const_int 1) (const_int 2)))])
5380 (define_insn "const_mulsidi3_sp64"
5381   [(set (match_operand:DI 0 "register_operand" "=r")
5382         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5383                  (match_operand:DI 2 "small_int" "I")))]
5384   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5385   "smul\t%1, %2, %0"
5386   [(set_attr "type" "imul")])
5388 (define_expand "smulsi3_highpart"
5389   [(set (match_operand:SI 0 "register_operand" "")
5390         (truncate:SI
5391          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5392                                (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
5393                       (const_int 32))))]
5394   "TARGET_HARD_MUL && TARGET_ARCH32"
5396   if (CONSTANT_P (operands[2]))
5397     {
5398       if (TARGET_V8PLUS)
5399         {
5400           emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
5401                                                         operands[1],
5402                                                         operands[2],
5403                                                         GEN_INT (32)));
5404           DONE;
5405         }
5406       emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
5407       DONE;
5408     }
5409   if (TARGET_V8PLUS)
5410     {
5411       emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
5412                                               operands[2], GEN_INT (32)));
5413       DONE;
5414     }
5417 ;; XXX
5418 (define_insn "smulsi3_highpart_v8plus"
5419   [(set (match_operand:SI 0 "register_operand" "=h,r")
5420         (truncate:SI
5421          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5422                                (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5423                       (match_operand:SI 3 "const_int_operand" "i,i"))))
5424    (clobber (match_scratch:SI 4 "=X,&h"))]
5425   "TARGET_V8PLUS"
5426   "@
5427    smul\t%1, %2, %0\;srlx\t%0, %3, %0
5428    smul\t%1, %2, %4\;srlx\t%4, %3, %0"
5429   [(set_attr "type" "multi")
5430    (set_attr "length" "2")])
5432 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
5433 ;; XXX
5434 (define_insn ""
5435   [(set (match_operand:SI 0 "register_operand" "=h,r")
5436         (subreg:SI
5437          (lshiftrt:DI
5438           (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5439                    (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5440           (match_operand:SI 3 "const_int_operand" "i,i"))
5441          4))
5442    (clobber (match_scratch:SI 4 "=X,&h"))]
5443   "TARGET_V8PLUS"
5444   "@
5445    smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5446    smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5447   [(set_attr "type" "multi")
5448    (set_attr "length" "2")])
5450 ;; XXX
5451 (define_insn "const_smulsi3_highpart_v8plus"
5452   [(set (match_operand:SI 0 "register_operand" "=h,r")
5453         (truncate:SI
5454          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5455                                (match_operand:DI 2 "small_int" "i,i"))
5456                       (match_operand:SI 3 "const_int_operand" "i,i"))))
5457    (clobber (match_scratch:SI 4 "=X,&h"))]
5458   "TARGET_V8PLUS"
5459   "@
5460    smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5461    smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5462   [(set_attr "type" "multi")
5463    (set_attr "length" "2")])
5465 ;; XXX
5466 (define_insn "*smulsi3_highpart_sp32"
5467   [(set (match_operand:SI 0 "register_operand" "=r")
5468         (truncate:SI
5469          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5470                                (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
5471                       (const_int 32))))]
5472   "TARGET_HARD_MUL32"
5473   "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
5474   [(set_attr "type" "multi")
5475    (set_attr "length" "2")])
5477 ;; XXX
5478 (define_insn "const_smulsi3_highpart"
5479   [(set (match_operand:SI 0 "register_operand" "=r")
5480         (truncate:SI
5481          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5482                                (match_operand:DI 2 "small_int" "i"))
5483                       (const_int 32))))]
5484   "TARGET_HARD_MUL32"
5485   "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
5486   [(set_attr "type" "multi")
5487    (set_attr "length" "2")])
5489 (define_expand "umulsidi3"
5490   [(set (match_operand:DI 0 "register_operand" "")
5491         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5492                  (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
5493   "TARGET_HARD_MUL"
5495   if (CONSTANT_P (operands[2]))
5496     {
5497       if (TARGET_V8PLUS)
5498         emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
5499                                                operands[2]));
5500       else if (TARGET_ARCH32)
5501         emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
5502                                              operands[2]));
5503       else 
5504         emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
5505                                              operands[2]));
5506       DONE;
5507     }
5508   if (TARGET_V8PLUS)
5509     {
5510       emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
5511       DONE;
5512     }
5515 ;; XXX
5516 (define_insn "umulsidi3_v8plus"
5517   [(set (match_operand:DI 0 "register_operand" "=h,r")
5518         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5519                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5520    (clobber (match_scratch:SI 3 "=X,&h"))]
5521   "TARGET_V8PLUS"
5522   "@
5523    umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5524    umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5525   [(set_attr "type" "multi")
5526    (set_attr "length" "2,3")])
5528 ;; XXX
5529 (define_insn "*umulsidi3_sp32"
5530   [(set (match_operand:DI 0 "register_operand" "=r")
5531         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5532                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5533   "TARGET_HARD_MUL32"
5535   return TARGET_SPARCLET
5536          ? "umuld\t%1, %2, %L0"
5537          : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
5539   [(set (attr "type")
5540         (if_then_else (eq_attr "isa" "sparclet")
5541                       (const_string "imul") (const_string "multi")))
5542    (set (attr "length")
5543         (if_then_else (eq_attr "isa" "sparclet")
5544                       (const_int 1) (const_int 2)))])
5546 (define_insn "*umulsidi3_sp64"
5547   [(set (match_operand:DI 0 "register_operand" "=r")
5548         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5549                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5550   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5551   "umul\t%1, %2, %0"
5552   [(set_attr "type" "imul")])
5554 ;; Extra pattern, because sign_extend of a constant isn't valid.
5556 ;; XXX
5557 (define_insn "const_umulsidi3_sp32"
5558   [(set (match_operand:DI 0 "register_operand" "=r")
5559         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5560                  (match_operand:DI 2 "uns_small_int" "")))]
5561   "TARGET_HARD_MUL32"
5563   return TARGET_SPARCLET
5564          ? "umuld\t%1, %s2, %L0"
5565          : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
5567   [(set (attr "type")
5568         (if_then_else (eq_attr "isa" "sparclet")
5569                       (const_string "imul") (const_string "multi")))
5570    (set (attr "length")
5571         (if_then_else (eq_attr "isa" "sparclet")
5572                       (const_int 1) (const_int 2)))])
5574 (define_insn "const_umulsidi3_sp64"
5575   [(set (match_operand:DI 0 "register_operand" "=r")
5576         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5577                  (match_operand:DI 2 "uns_small_int" "")))]
5578   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5579   "umul\t%1, %s2, %0"
5580   [(set_attr "type" "imul")])
5582 ;; XXX
5583 (define_insn "const_umulsidi3_v8plus"
5584   [(set (match_operand:DI 0 "register_operand" "=h,r")
5585         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5586                  (match_operand:DI 2 "uns_small_int" "")))
5587    (clobber (match_scratch:SI 3 "=X,h"))]
5588   "TARGET_V8PLUS"
5589   "@
5590    umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
5591    umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5592   [(set_attr "type" "multi")
5593    (set_attr "length" "2,3")])
5595 (define_expand "umulsi3_highpart"
5596   [(set (match_operand:SI 0 "register_operand" "")
5597         (truncate:SI
5598          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5599                                (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
5600                       (const_int 32))))]
5601   "TARGET_HARD_MUL && TARGET_ARCH32"
5603   if (CONSTANT_P (operands[2]))
5604     {
5605       if (TARGET_V8PLUS)
5606         {
5607           emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
5608                                                         operands[1],
5609                                                         operands[2],
5610                                                         GEN_INT (32)));
5611           DONE;
5612         }
5613       emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
5614       DONE;
5615     }
5616   if (TARGET_V8PLUS)
5617     {
5618       emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
5619                                               operands[2], GEN_INT (32)));
5620       DONE;
5621     }
5624 ;; XXX
5625 (define_insn "umulsi3_highpart_v8plus"
5626   [(set (match_operand:SI 0 "register_operand" "=h,r")
5627         (truncate:SI
5628          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5629                                (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5630                       (match_operand:SI 3 "const_int_operand" "i,i"))))
5631    (clobber (match_scratch:SI 4 "=X,h"))]
5632   "TARGET_V8PLUS"
5633   "@
5634    umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5635    umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5636   [(set_attr "type" "multi")
5637    (set_attr "length" "2")])
5639 ;; XXX
5640 (define_insn "const_umulsi3_highpart_v8plus"
5641   [(set (match_operand:SI 0 "register_operand" "=h,r")
5642         (truncate:SI
5643          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5644                                (match_operand:DI 2 "uns_small_int" ""))
5645                       (match_operand:SI 3 "const_int_operand" "i,i"))))
5646    (clobber (match_scratch:SI 4 "=X,h"))]
5647   "TARGET_V8PLUS"
5648   "@
5649    umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
5650    umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
5651   [(set_attr "type" "multi")
5652    (set_attr "length" "2")])
5654 ;; XXX
5655 (define_insn "*umulsi3_highpart_sp32"
5656   [(set (match_operand:SI 0 "register_operand" "=r")
5657         (truncate:SI
5658          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5659                                (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
5660                       (const_int 32))))]
5661   "TARGET_HARD_MUL32"
5662   "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
5663   [(set_attr "type" "multi")
5664    (set_attr "length" "2")])
5666 ;; XXX
5667 (define_insn "const_umulsi3_highpart"
5668   [(set (match_operand:SI 0 "register_operand" "=r")
5669         (truncate:SI
5670          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5671                                (match_operand:DI 2 "uns_small_int" ""))
5672                       (const_int 32))))]
5673   "TARGET_HARD_MUL32"
5674   "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
5675   [(set_attr "type" "multi")
5676    (set_attr "length" "2")])
5678 ;; The v8 architecture specifies that there must be 3 instructions between
5679 ;; a y register write and a use of it for correct results.
5681 (define_expand "divsi3"
5682   [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
5683                    (div:SI (match_operand:SI 1 "register_operand" "r,r")
5684                            (match_operand:SI 2 "input_operand" "rI,m")))
5685               (clobber (match_scratch:SI 3 "=&r,&r"))])]
5686   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5688   if (TARGET_ARCH64)
5689     {
5690       operands[3] = gen_reg_rtx(SImode);
5691       emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
5692       emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
5693                                   operands[3]));
5694       DONE;
5695     }
5698 (define_insn "divsi3_sp32"
5699   [(set (match_operand:SI 0 "register_operand" "=r,r")
5700         (div:SI (match_operand:SI 1 "register_operand" "r,r")
5701                 (match_operand:SI 2 "input_operand" "rI,m")))
5702    (clobber (match_scratch:SI 3 "=&r,&r"))]
5703   "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
5704    && TARGET_ARCH32"
5706   if (which_alternative == 0)
5707     if (TARGET_V9)
5708       return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdiv\t%1, %2, %0";
5709     else
5710       return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
5711   else
5712     if (TARGET_V9)
5713       return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tld\t%2, %3\n\tsdiv\t%1, %3, %0";
5714     else
5715       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";
5717   [(set_attr "type" "multi")
5718    (set (attr "length")
5719         (if_then_else (eq_attr "isa" "v9")
5720                       (const_int 4) (const_int 6)))])
5722 (define_insn "divsi3_sp64"
5723   [(set (match_operand:SI 0 "register_operand" "=r")
5724         (div:SI (match_operand:SI 1 "register_operand" "r")
5725                 (match_operand:SI 2 "input_operand" "rI")))
5726    (use (match_operand:SI 3 "register_operand" "r"))]
5727   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5728   "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
5729   [(set_attr "type" "multi")
5730    (set_attr "length" "2")])
5732 (define_insn "divdi3"
5733   [(set (match_operand:DI 0 "register_operand" "=r")
5734         (div:DI (match_operand:DI 1 "register_operand" "r")
5735                 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5736   "TARGET_ARCH64"
5737   "sdivx\t%1, %2, %0"
5738   [(set_attr "type" "idiv")])
5740 (define_insn "*cmp_sdiv_cc_set"
5741   [(set (reg:CC 100)
5742         (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
5743                             (match_operand:SI 2 "arith_operand" "rI"))
5744                     (const_int 0)))
5745    (set (match_operand:SI 0 "register_operand" "=r")
5746         (div:SI (match_dup 1) (match_dup 2)))
5747    (clobber (match_scratch:SI 3 "=&r"))]
5748   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5750   if (TARGET_V9)
5751     return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdivcc\t%1, %2, %0";
5752   else
5753     return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
5755   [(set_attr "type" "multi")
5756    (set (attr "length")
5757         (if_then_else (eq_attr "isa" "v9")
5758                       (const_int 3) (const_int 6)))])
5760 ;; XXX
5761 (define_expand "udivsi3"
5762   [(set (match_operand:SI 0 "register_operand" "")
5763         (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "")
5764                  (match_operand:SI 2 "input_operand" "")))]
5765   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5766   "")
5768 (define_insn "udivsi3_sp32"
5769   [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
5770         (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r,r,m")
5771                  (match_operand:SI 2 "input_operand" "rI,m,r")))]
5772   "(TARGET_V8
5773     || TARGET_DEPRECATED_V8_INSNS)
5774    && TARGET_ARCH32"
5776   output_asm_insn ("wr\t%%g0, %%g0, %%y", operands);
5777   switch (which_alternative)
5778     {
5779     default:
5780       return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
5781     case 1:
5782       return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
5783     case 2:
5784       return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
5785     }
5787   [(set_attr "type" "multi")
5788    (set_attr "length" "5")])
5790 (define_insn "udivsi3_sp64"
5791   [(set (match_operand:SI 0 "register_operand" "=r")
5792         (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r")
5793                  (match_operand:SI 2 "input_operand" "rI")))]
5794   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5795   "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
5796   [(set_attr "type" "multi")
5797    (set_attr "length" "2")])
5799 (define_insn "udivdi3"
5800   [(set (match_operand:DI 0 "register_operand" "=r")
5801         (udiv:DI (match_operand:DI 1 "register_operand" "r")
5802                  (match_operand:DI 2 "arith_double_operand" "rHI")))]
5803   "TARGET_ARCH64"
5804   "udivx\t%1, %2, %0"
5805   [(set_attr "type" "idiv")])
5807 (define_insn "*cmp_udiv_cc_set"
5808   [(set (reg:CC 100)
5809         (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
5810                              (match_operand:SI 2 "arith_operand" "rI"))
5811                     (const_int 0)))
5812    (set (match_operand:SI 0 "register_operand" "=r")
5813         (udiv:SI (match_dup 1) (match_dup 2)))]
5814   "TARGET_V8
5815    || TARGET_DEPRECATED_V8_INSNS"
5817   if (TARGET_V9)
5818     return "wr\t%%g0, %%g0, %%y\n\tudivcc\t%1, %2, %0";
5819   else
5820     return "wr\t%%g0, %%g0, %%y\n\tnop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
5822   [(set_attr "type" "multi")
5823    (set (attr "length")
5824         (if_then_else (eq_attr "isa" "v9")
5825                       (const_int 2) (const_int 5)))])
5827 ; sparclet multiply/accumulate insns
5829 (define_insn "*smacsi"
5830   [(set (match_operand:SI 0 "register_operand" "=r")
5831         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
5832                           (match_operand:SI 2 "arith_operand" "rI"))
5833                  (match_operand:SI 3 "register_operand" "0")))]
5834   "TARGET_SPARCLET"
5835   "smac\t%1, %2, %0"
5836   [(set_attr "type" "imul")])
5838 (define_insn "*smacdi"
5839   [(set (match_operand:DI 0 "register_operand" "=r")
5840         (plus:DI (mult:DI (sign_extend:DI
5841                            (match_operand:SI 1 "register_operand" "%r"))
5842                           (sign_extend:DI
5843                            (match_operand:SI 2 "register_operand" "r")))
5844                  (match_operand:DI 3 "register_operand" "0")))]
5845   "TARGET_SPARCLET"
5846   "smacd\t%1, %2, %L0"
5847   [(set_attr "type" "imul")])
5849 (define_insn "*umacdi"
5850   [(set (match_operand:DI 0 "register_operand" "=r")
5851         (plus:DI (mult:DI (zero_extend:DI
5852                            (match_operand:SI 1 "register_operand" "%r"))
5853                           (zero_extend:DI
5854                            (match_operand:SI 2 "register_operand" "r")))
5855                  (match_operand:DI 3 "register_operand" "0")))]
5856   "TARGET_SPARCLET"
5857   "umacd\t%1, %2, %L0"
5858   [(set_attr "type" "imul")])
5860 ;;- Boolean instructions
5861 ;; We define DImode `and' so with DImode `not' we can get
5862 ;; DImode `andn'.  Other combinations are possible.
5864 (define_expand "anddi3"
5865   [(set (match_operand:DI 0 "register_operand" "")
5866         (and:DI (match_operand:DI 1 "arith_double_operand" "")
5867                 (match_operand:DI 2 "arith_double_operand" "")))]
5868   ""
5869   "")
5871 (define_insn "*anddi3_sp32"
5872   [(set (match_operand:DI 0 "register_operand" "=r,b")
5873         (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
5874                 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
5875   "! TARGET_ARCH64"
5876   "@
5877   #
5878   fand\t%1, %2, %0"
5879   [(set_attr "type" "*,fga")
5880    (set_attr "length" "2,*")
5881    (set_attr "fptype" "double")])
5883 (define_insn "*anddi3_sp64"
5884   [(set (match_operand:DI 0 "register_operand" "=r,b")
5885         (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
5886                 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
5887   "TARGET_ARCH64"
5888   "@
5889    and\t%1, %2, %0
5890    fand\t%1, %2, %0"
5891   [(set_attr "type" "*,fga")
5892    (set_attr "fptype" "double")])
5894 (define_insn "andsi3"
5895   [(set (match_operand:SI 0 "register_operand" "=r,d")
5896         (and:SI (match_operand:SI 1 "arith_operand" "%r,d")
5897                 (match_operand:SI 2 "arith_operand" "rI,d")))]
5898   ""
5899   "@
5900    and\t%1, %2, %0
5901    fands\t%1, %2, %0"
5902   [(set_attr "type" "*,fga")])
5904 (define_split
5905   [(set (match_operand:SI 0 "register_operand" "")
5906         (and:SI (match_operand:SI 1 "register_operand" "")
5907                 (match_operand:SI 2 "" "")))
5908    (clobber (match_operand:SI 3 "register_operand" ""))]
5909   "GET_CODE (operands[2]) == CONST_INT
5910    && !SMALL_INT32 (operands[2])
5911    && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
5912   [(set (match_dup 3) (match_dup 4))
5913    (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
5915   operands[4] = GEN_INT (~INTVAL (operands[2]));
5918 ;; Split DImode logical operations requiring two instructions.
5919 (define_split
5920   [(set (match_operand:DI 0 "register_operand" "")
5921         (match_operator:DI 1 "cc_arithop"       ; AND, IOR, XOR
5922                            [(match_operand:DI 2 "register_operand" "")
5923                             (match_operand:DI 3 "arith_double_operand" "")]))]
5924   "! TARGET_ARCH64
5925    && reload_completed
5926    && ((GET_CODE (operands[0]) == REG
5927         && REGNO (operands[0]) < 32)
5928        || (GET_CODE (operands[0]) == SUBREG
5929            && GET_CODE (SUBREG_REG (operands[0])) == REG
5930            && REGNO (SUBREG_REG (operands[0])) < 32))"
5931   [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
5932    (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
5934   operands[4] = gen_highpart (SImode, operands[0]);
5935   operands[5] = gen_lowpart (SImode, operands[0]);
5936   operands[6] = gen_highpart (SImode, operands[2]);
5937   operands[7] = gen_lowpart (SImode, operands[2]);
5938 #if HOST_BITS_PER_WIDE_INT == 32
5939   if (GET_CODE (operands[3]) == CONST_INT)
5940     {
5941       if (INTVAL (operands[3]) < 0)
5942         operands[8] = constm1_rtx;
5943       else
5944         operands[8] = const0_rtx;
5945     }
5946   else
5947 #endif
5948     operands[8] = gen_highpart_mode (SImode, DImode, operands[3]);
5949   operands[9] = gen_lowpart (SImode, operands[3]);
5952 (define_insn_and_split "*and_not_di_sp32"
5953   [(set (match_operand:DI 0 "register_operand" "=r,b")
5954         (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
5955                 (match_operand:DI 2 "register_operand" "r,b")))]
5956   "! TARGET_ARCH64"
5957   "@
5958    #
5959    fandnot1\t%1, %2, %0"
5960   "&& reload_completed
5961    && ((GET_CODE (operands[0]) == REG
5962         && REGNO (operands[0]) < 32)
5963        || (GET_CODE (operands[0]) == SUBREG
5964            && GET_CODE (SUBREG_REG (operands[0])) == REG
5965            && REGNO (SUBREG_REG (operands[0])) < 32))"
5966   [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
5967    (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
5968   "operands[3] = gen_highpart (SImode, operands[0]);
5969    operands[4] = gen_highpart (SImode, operands[1]);
5970    operands[5] = gen_highpart (SImode, operands[2]);
5971    operands[6] = gen_lowpart (SImode, operands[0]);
5972    operands[7] = gen_lowpart (SImode, operands[1]);
5973    operands[8] = gen_lowpart (SImode, operands[2]);"
5974   [(set_attr "type" "*,fga")
5975    (set_attr "length" "2,*")
5976    (set_attr "fptype" "double")])
5978 (define_insn "*and_not_di_sp64"
5979   [(set (match_operand:DI 0 "register_operand" "=r,b")
5980         (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
5981                 (match_operand:DI 2 "register_operand" "r,b")))]
5982   "TARGET_ARCH64"
5983   "@
5984    andn\t%2, %1, %0
5985    fandnot1\t%1, %2, %0"
5986   [(set_attr "type" "*,fga")
5987    (set_attr "fptype" "double")])
5989 (define_insn "*and_not_si"
5990   [(set (match_operand:SI 0 "register_operand" "=r,d")
5991         (and:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
5992                 (match_operand:SI 2 "register_operand" "r,d")))]
5993   ""
5994   "@
5995    andn\t%2, %1, %0
5996    fandnot1s\t%1, %2, %0"
5997   [(set_attr "type" "*,fga")])
5999 (define_expand "iordi3"
6000   [(set (match_operand:DI 0 "register_operand" "")
6001         (ior:DI (match_operand:DI 1 "arith_double_operand" "")
6002                 (match_operand:DI 2 "arith_double_operand" "")))]
6003   ""
6004   "")
6006 (define_insn "*iordi3_sp32"
6007   [(set (match_operand:DI 0 "register_operand" "=r,b")
6008         (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6009                 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6010   "! TARGET_ARCH64"
6011   "@
6012   #
6013   for\t%1, %2, %0"
6014   [(set_attr "type" "*,fga")
6015    (set_attr "length" "2,*")
6016    (set_attr "fptype" "double")])
6018 (define_insn "*iordi3_sp64"
6019   [(set (match_operand:DI 0 "register_operand" "=r,b")
6020         (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6021                 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6022   "TARGET_ARCH64"
6023   "@
6024   or\t%1, %2, %0
6025   for\t%1, %2, %0"
6026   [(set_attr "type" "*,fga")
6027    (set_attr "fptype" "double")])
6029 (define_insn "iorsi3"
6030   [(set (match_operand:SI 0 "register_operand" "=r,d")
6031         (ior:SI (match_operand:SI 1 "arith_operand" "%r,d")
6032                 (match_operand:SI 2 "arith_operand" "rI,d")))]
6033   ""
6034   "@
6035    or\t%1, %2, %0
6036    fors\t%1, %2, %0"
6037   [(set_attr "type" "*,fga")])
6039 (define_split
6040   [(set (match_operand:SI 0 "register_operand" "")
6041         (ior:SI (match_operand:SI 1 "register_operand" "")
6042                 (match_operand:SI 2 "" "")))
6043    (clobber (match_operand:SI 3 "register_operand" ""))]
6044   "GET_CODE (operands[2]) == CONST_INT
6045    && !SMALL_INT32 (operands[2])
6046    && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6047   [(set (match_dup 3) (match_dup 4))
6048    (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
6050   operands[4] = GEN_INT (~INTVAL (operands[2]));
6053 (define_insn_and_split "*or_not_di_sp32"
6054   [(set (match_operand:DI 0 "register_operand" "=r,b")
6055         (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6056                 (match_operand:DI 2 "register_operand" "r,b")))]
6057   "! TARGET_ARCH64"
6058   "@
6059    #
6060    fornot1\t%1, %2, %0"
6061   "&& reload_completed
6062    && ((GET_CODE (operands[0]) == REG
6063         && REGNO (operands[0]) < 32)
6064        || (GET_CODE (operands[0]) == SUBREG
6065            && GET_CODE (SUBREG_REG (operands[0])) == REG
6066            && REGNO (SUBREG_REG (operands[0])) < 32))"
6067   [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
6068    (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
6069   "operands[3] = gen_highpart (SImode, operands[0]);
6070    operands[4] = gen_highpart (SImode, operands[1]);
6071    operands[5] = gen_highpart (SImode, operands[2]);
6072    operands[6] = gen_lowpart (SImode, operands[0]);
6073    operands[7] = gen_lowpart (SImode, operands[1]);
6074    operands[8] = gen_lowpart (SImode, operands[2]);"
6075   [(set_attr "type" "*,fga")
6076    (set_attr "length" "2,*")
6077    (set_attr "fptype" "double")])
6079 (define_insn "*or_not_di_sp64"
6080   [(set (match_operand:DI 0 "register_operand" "=r,b")
6081         (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b"))
6082                 (match_operand:DI 2 "register_operand" "r,b")))]
6083   "TARGET_ARCH64"
6084   "@
6085   orn\t%2, %1, %0
6086   fornot1\t%1, %2, %0"
6087   [(set_attr "type" "*,fga")
6088    (set_attr "fptype" "double")])
6090 (define_insn "*or_not_si"
6091   [(set (match_operand:SI 0 "register_operand" "=r,d")
6092         (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r,d"))
6093                 (match_operand:SI 2 "register_operand" "r,d")))]
6094   ""
6095   "@
6096    orn\t%2, %1, %0
6097    fornot1s\t%1, %2, %0"
6098   [(set_attr "type" "*,fga")])
6100 (define_expand "xordi3"
6101   [(set (match_operand:DI 0 "register_operand" "")
6102         (xor:DI (match_operand:DI 1 "arith_double_operand" "")
6103                 (match_operand:DI 2 "arith_double_operand" "")))]
6104   ""
6105   "")
6107 (define_insn "*xordi3_sp32"
6108   [(set (match_operand:DI 0 "register_operand" "=r,b")
6109         (xor:DI (match_operand:DI 1 "arith_double_operand" "%r,b")
6110                 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6111   "! TARGET_ARCH64"
6112   "@
6113   #
6114   fxor\t%1, %2, %0"
6115   [(set_attr "type" "*,fga")
6116    (set_attr "length" "2,*")
6117    (set_attr "fptype" "double")])
6119 (define_insn "*xordi3_sp64"
6120   [(set (match_operand:DI 0 "register_operand" "=r,b")
6121         (xor:DI (match_operand:DI 1 "arith_double_operand" "%rJ,b")
6122                 (match_operand:DI 2 "arith_double_operand" "rHI,b")))]
6123   "TARGET_ARCH64"
6124   "@
6125   xor\t%r1, %2, %0
6126   fxor\t%1, %2, %0"
6127   [(set_attr "type" "*,fga")
6128    (set_attr "fptype" "double")])
6130 (define_insn "*xordi3_sp64_dbl"
6131   [(set (match_operand:DI 0 "register_operand" "=r")
6132         (xor:DI (match_operand:DI 1 "register_operand" "r")
6133                 (match_operand:DI 2 "const64_operand" "")))]
6134   "(TARGET_ARCH64
6135     && HOST_BITS_PER_WIDE_INT != 64)"
6136   "xor\t%1, %2, %0")
6138 (define_insn "xorsi3"
6139   [(set (match_operand:SI 0 "register_operand" "=r,d")
6140         (xor:SI (match_operand:SI 1 "arith_operand" "%rJ,d")
6141                 (match_operand:SI 2 "arith_operand" "rI,d")))]
6142   ""
6143   "@
6144    xor\t%r1, %2, %0
6145    fxors\t%1, %2, %0"
6146   [(set_attr "type" "*,fga")])
6148 (define_split
6149   [(set (match_operand:SI 0 "register_operand" "")
6150         (xor:SI (match_operand:SI 1 "register_operand" "")
6151                 (match_operand:SI 2 "" "")))
6152    (clobber (match_operand:SI 3 "register_operand" ""))]
6153   "GET_CODE (operands[2]) == CONST_INT
6154    && !SMALL_INT32 (operands[2])
6155    && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6156   [(set (match_dup 3) (match_dup 4))
6157    (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
6159   operands[4] = GEN_INT (~INTVAL (operands[2]));
6162 (define_split
6163   [(set (match_operand:SI 0 "register_operand" "")
6164         (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
6165                         (match_operand:SI 2 "" ""))))
6166    (clobber (match_operand:SI 3 "register_operand" ""))]
6167   "GET_CODE (operands[2]) == CONST_INT
6168    && !SMALL_INT32 (operands[2])
6169    && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6170   [(set (match_dup 3) (match_dup 4))
6171    (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
6173   operands[4] = GEN_INT (~INTVAL (operands[2]));
6176 ;; xnor patterns.  Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
6177 ;; Combine now canonicalizes to the rightmost expression.
6178 (define_insn_and_split "*xor_not_di_sp32"
6179   [(set (match_operand:DI 0 "register_operand" "=r,b")
6180         (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r,b")
6181                         (match_operand:DI 2 "register_operand" "r,b"))))]
6182   "! TARGET_ARCH64"
6183   "@
6184    #
6185    fxnor\t%1, %2, %0"
6186   "&& reload_completed
6187    && ((GET_CODE (operands[0]) == REG
6188         && REGNO (operands[0]) < 32)
6189        || (GET_CODE (operands[0]) == SUBREG
6190            && GET_CODE (SUBREG_REG (operands[0])) == REG
6191            && REGNO (SUBREG_REG (operands[0])) < 32))"
6192   [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
6193    (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
6194   "operands[3] = gen_highpart (SImode, operands[0]);
6195    operands[4] = gen_highpart (SImode, operands[1]);
6196    operands[5] = gen_highpart (SImode, operands[2]);
6197    operands[6] = gen_lowpart (SImode, operands[0]);
6198    operands[7] = gen_lowpart (SImode, operands[1]);
6199    operands[8] = gen_lowpart (SImode, operands[2]);"
6200   [(set_attr "type" "*,fga")
6201    (set_attr "length" "2,*")
6202    (set_attr "fptype" "double")])
6204 (define_insn "*xor_not_di_sp64"
6205   [(set (match_operand:DI 0 "register_operand" "=r,b")
6206         (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,b")
6207                         (match_operand:DI 2 "arith_double_operand" "rHI,b"))))]
6208   "TARGET_ARCH64"
6209   "@
6210   xnor\t%r1, %2, %0
6211   fxnor\t%1, %2, %0"
6212   [(set_attr "type" "*,fga")
6213    (set_attr "fptype" "double")])
6215 (define_insn "*xor_not_si"
6216   [(set (match_operand:SI 0 "register_operand" "=r,d")
6217         (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,d")
6218                         (match_operand:SI 2 "arith_operand" "rI,d"))))]
6219   ""
6220   "@
6221    xnor\t%r1, %2, %0
6222    fxnors\t%1, %2, %0"
6223   [(set_attr "type" "*,fga")])
6225 ;; These correspond to the above in the case where we also (or only)
6226 ;; want to set the condition code.  
6228 (define_insn "*cmp_cc_arith_op"
6229   [(set (reg:CC 100)
6230         (compare:CC
6231          (match_operator:SI 2 "cc_arithop"
6232                             [(match_operand:SI 0 "arith_operand" "%r")
6233                              (match_operand:SI 1 "arith_operand" "rI")])
6234          (const_int 0)))]
6235   ""
6236   "%A2cc\t%0, %1, %%g0"
6237   [(set_attr "type" "compare")])
6239 (define_insn "*cmp_ccx_arith_op"
6240   [(set (reg:CCX 100)
6241         (compare:CCX
6242          (match_operator:DI 2 "cc_arithop"
6243                             [(match_operand:DI 0 "arith_double_operand" "%r")
6244                              (match_operand:DI 1 "arith_double_operand" "rHI")])
6245          (const_int 0)))]
6246   "TARGET_ARCH64"
6247   "%A2cc\t%0, %1, %%g0"
6248   [(set_attr "type" "compare")])
6250 (define_insn "*cmp_cc_arith_op_set"
6251   [(set (reg:CC 100)
6252         (compare:CC
6253          (match_operator:SI 3 "cc_arithop"
6254                             [(match_operand:SI 1 "arith_operand" "%r")
6255                              (match_operand:SI 2 "arith_operand" "rI")])
6256          (const_int 0)))
6257    (set (match_operand:SI 0 "register_operand" "=r")
6258         (match_operator:SI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6259   "GET_CODE (operands[3]) == GET_CODE (operands[4])"
6260   "%A3cc\t%1, %2, %0"
6261   [(set_attr "type" "compare")])
6263 (define_insn "*cmp_ccx_arith_op_set"
6264   [(set (reg:CCX 100)
6265         (compare:CCX
6266          (match_operator:DI 3 "cc_arithop"
6267                             [(match_operand:DI 1 "arith_double_operand" "%r")
6268                              (match_operand:DI 2 "arith_double_operand" "rHI")])
6269          (const_int 0)))
6270    (set (match_operand:DI 0 "register_operand" "=r")
6271         (match_operator:DI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6272   "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
6273   "%A3cc\t%1, %2, %0"
6274   [(set_attr "type" "compare")])
6276 (define_insn "*cmp_cc_xor_not"
6277   [(set (reg:CC 100)
6278         (compare:CC
6279          (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
6280                          (match_operand:SI 1 "arith_operand" "rI")))
6281          (const_int 0)))]
6282   ""
6283   "xnorcc\t%r0, %1, %%g0"
6284   [(set_attr "type" "compare")])
6286 (define_insn "*cmp_ccx_xor_not"
6287   [(set (reg:CCX 100)
6288         (compare:CCX
6289          (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ")
6290                          (match_operand:DI 1 "arith_double_operand" "rHI")))
6291          (const_int 0)))]
6292   "TARGET_ARCH64"
6293   "xnorcc\t%r0, %1, %%g0"
6294   [(set_attr "type" "compare")])
6296 (define_insn "*cmp_cc_xor_not_set"
6297   [(set (reg:CC 100)
6298         (compare:CC
6299          (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
6300                          (match_operand:SI 2 "arith_operand" "rI")))
6301          (const_int 0)))
6302    (set (match_operand:SI 0 "register_operand" "=r")
6303         (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
6304   ""
6305   "xnorcc\t%r1, %2, %0"
6306   [(set_attr "type" "compare")])
6308 (define_insn "*cmp_ccx_xor_not_set"
6309   [(set (reg:CCX 100)
6310         (compare:CCX
6311          (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
6312                          (match_operand:DI 2 "arith_double_operand" "rHI")))
6313          (const_int 0)))
6314    (set (match_operand:DI 0 "register_operand" "=r")
6315         (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
6316   "TARGET_ARCH64"
6317   "xnorcc\t%r1, %2, %0"
6318   [(set_attr "type" "compare")])
6320 (define_insn "*cmp_cc_arith_op_not"
6321   [(set (reg:CC 100)
6322         (compare:CC
6323          (match_operator:SI 2 "cc_arithopn"
6324                             [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
6325                              (match_operand:SI 1 "reg_or_0_operand" "rJ")])
6326          (const_int 0)))]
6327   ""
6328   "%B2cc\t%r1, %0, %%g0"
6329   [(set_attr "type" "compare")])
6331 (define_insn "*cmp_ccx_arith_op_not"
6332   [(set (reg:CCX 100)
6333         (compare:CCX
6334          (match_operator:DI 2 "cc_arithopn"
6335                             [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6336                              (match_operand:DI 1 "reg_or_0_operand" "rJ")])
6337          (const_int 0)))]
6338   "TARGET_ARCH64"
6339   "%B2cc\t%r1, %0, %%g0"
6340   [(set_attr "type" "compare")])
6342 (define_insn "*cmp_cc_arith_op_not_set"
6343   [(set (reg:CC 100)
6344         (compare:CC
6345          (match_operator:SI 3 "cc_arithopn"
6346                             [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
6347                              (match_operand:SI 2 "reg_or_0_operand" "rJ")])
6348          (const_int 0)))
6349    (set (match_operand:SI 0 "register_operand" "=r")
6350         (match_operator:SI 4 "cc_arithopn"
6351                             [(not:SI (match_dup 1)) (match_dup 2)]))]
6352   "GET_CODE (operands[3]) == GET_CODE (operands[4])"
6353   "%B3cc\t%r2, %1, %0"
6354   [(set_attr "type" "compare")])
6356 (define_insn "*cmp_ccx_arith_op_not_set"
6357   [(set (reg:CCX 100)
6358         (compare:CCX
6359          (match_operator:DI 3 "cc_arithopn"
6360                             [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6361                              (match_operand:DI 2 "reg_or_0_operand" "rJ")])
6362          (const_int 0)))
6363    (set (match_operand:DI 0 "register_operand" "=r")
6364         (match_operator:DI 4 "cc_arithopn"
6365                             [(not:DI (match_dup 1)) (match_dup 2)]))]
6366   "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
6367   "%B3cc\t%r2, %1, %0"
6368   [(set_attr "type" "compare")])
6370 ;; We cannot use the "neg" pseudo insn because the Sun assembler
6371 ;; does not know how to make it work for constants.
6373 (define_expand "negdi2"
6374   [(set (match_operand:DI 0 "register_operand" "=r")
6375         (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6376   ""
6378   if (! TARGET_ARCH64)
6379     {
6380       emit_insn (gen_rtx_PARALLEL
6381                  (VOIDmode,
6382                   gen_rtvec (2,
6383                              gen_rtx_SET (VOIDmode, operand0,
6384                                           gen_rtx_NEG (DImode, operand1)),
6385                              gen_rtx_CLOBBER (VOIDmode,
6386                                               gen_rtx_REG (CCmode,
6387                                                            SPARC_ICC_REG)))));
6388       DONE;
6389     }
6392 (define_insn_and_split "*negdi2_sp32"
6393   [(set (match_operand:DI 0 "register_operand" "=r")
6394         (neg:DI (match_operand:DI 1 "register_operand" "r")))
6395    (clobber (reg:CC 100))]
6396   "TARGET_ARCH32"
6397   "#"
6398   "&& reload_completed"
6399   [(parallel [(set (reg:CC_NOOV 100)
6400                    (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
6401                                     (const_int 0)))
6402               (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
6403    (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
6404                                 (ltu:SI (reg:CC 100) (const_int 0))))]
6405   "operands[2] = gen_highpart (SImode, operands[0]);
6406    operands[3] = gen_highpart (SImode, operands[1]);
6407    operands[4] = gen_lowpart (SImode, operands[0]);
6408    operands[5] = gen_lowpart (SImode, operands[1]);"
6409   [(set_attr "length" "2")])
6411 (define_insn "*negdi2_sp64"
6412   [(set (match_operand:DI 0 "register_operand" "=r")
6413         (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6414   "TARGET_ARCH64"
6415   "sub\t%%g0, %1, %0")
6417 (define_insn "negsi2"
6418   [(set (match_operand:SI 0 "register_operand" "=r")
6419         (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
6420   ""
6421   "sub\t%%g0, %1, %0")
6423 (define_insn "*cmp_cc_neg"
6424   [(set (reg:CC_NOOV 100)
6425         (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
6426                          (const_int 0)))]
6427   ""
6428   "subcc\t%%g0, %0, %%g0"
6429   [(set_attr "type" "compare")])
6431 (define_insn "*cmp_ccx_neg"
6432   [(set (reg:CCX_NOOV 100)
6433         (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6434                           (const_int 0)))]
6435   "TARGET_ARCH64"
6436   "subcc\t%%g0, %0, %%g0"
6437   [(set_attr "type" "compare")])
6439 (define_insn "*cmp_cc_set_neg"
6440   [(set (reg:CC_NOOV 100)
6441         (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
6442                          (const_int 0)))
6443    (set (match_operand:SI 0 "register_operand" "=r")
6444         (neg:SI (match_dup 1)))]
6445   ""
6446   "subcc\t%%g0, %1, %0"
6447   [(set_attr "type" "compare")])
6449 (define_insn "*cmp_ccx_set_neg"
6450   [(set (reg:CCX_NOOV 100)
6451         (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6452                           (const_int 0)))
6453    (set (match_operand:DI 0 "register_operand" "=r")
6454         (neg:DI (match_dup 1)))]
6455   "TARGET_ARCH64"
6456   "subcc\t%%g0, %1, %0"
6457   [(set_attr "type" "compare")])
6459 ;; We cannot use the "not" pseudo insn because the Sun assembler
6460 ;; does not know how to make it work for constants.
6461 (define_expand "one_cmpldi2"
6462   [(set (match_operand:DI 0 "register_operand" "")
6463         (not:DI (match_operand:DI 1 "register_operand" "")))]
6464   ""
6465   "")
6467 (define_insn_and_split "*one_cmpldi2_sp32"
6468   [(set (match_operand:DI 0 "register_operand" "=r,b")
6469         (not:DI (match_operand:DI 1 "register_operand" "r,b")))]
6470   "! TARGET_ARCH64"
6471   "@
6472    #
6473    fnot1\t%1, %0"
6474   "&& reload_completed
6475    && ((GET_CODE (operands[0]) == REG
6476         && REGNO (operands[0]) < 32)
6477        || (GET_CODE (operands[0]) == SUBREG
6478            && GET_CODE (SUBREG_REG (operands[0])) == REG
6479            && REGNO (SUBREG_REG (operands[0])) < 32))"
6480   [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
6481    (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
6482   "operands[2] = gen_highpart (SImode, operands[0]);
6483    operands[3] = gen_highpart (SImode, operands[1]);
6484    operands[4] = gen_lowpart (SImode, operands[0]);
6485    operands[5] = gen_lowpart (SImode, operands[1]);"
6486   [(set_attr "type" "*,fga")
6487    (set_attr "length" "2,*")
6488    (set_attr "fptype" "double")])
6490 (define_insn "*one_cmpldi2_sp64"
6491   [(set (match_operand:DI 0 "register_operand" "=r,b")
6492         (not:DI (match_operand:DI 1 "arith_double_operand" "rHI,b")))]
6493   "TARGET_ARCH64"
6494   "@
6495    xnor\t%%g0, %1, %0
6496    fnot1\t%1, %0"
6497   [(set_attr "type" "*,fga")
6498    (set_attr "fptype" "double")])
6500 (define_insn "one_cmplsi2"
6501   [(set (match_operand:SI 0 "register_operand" "=r,d")
6502         (not:SI (match_operand:SI 1 "arith_operand" "rI,d")))]
6503   ""
6504   "@
6505   xnor\t%%g0, %1, %0
6506   fnot1s\t%1, %0"
6507   [(set_attr "type" "*,fga")])
6509 (define_insn "*cmp_cc_not"
6510   [(set (reg:CC 100)
6511         (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
6512                     (const_int 0)))]
6513   ""
6514   "xnorcc\t%%g0, %0, %%g0"
6515   [(set_attr "type" "compare")])
6517 (define_insn "*cmp_ccx_not"
6518   [(set (reg:CCX 100)
6519         (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6520                      (const_int 0)))]
6521   "TARGET_ARCH64"
6522   "xnorcc\t%%g0, %0, %%g0"
6523   [(set_attr "type" "compare")])
6525 (define_insn "*cmp_cc_set_not"
6526   [(set (reg:CC 100)
6527         (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
6528                     (const_int 0)))
6529    (set (match_operand:SI 0 "register_operand" "=r")
6530         (not:SI (match_dup 1)))]
6531   ""
6532   "xnorcc\t%%g0, %1, %0"
6533   [(set_attr "type" "compare")])
6535 (define_insn "*cmp_ccx_set_not"
6536   [(set (reg:CCX 100)
6537         (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6538                     (const_int 0)))
6539    (set (match_operand:DI 0 "register_operand" "=r")
6540         (not:DI (match_dup 1)))]
6541   "TARGET_ARCH64"
6542   "xnorcc\t%%g0, %1, %0"
6543   [(set_attr "type" "compare")])
6545 (define_insn "*cmp_cc_set"
6546   [(set (match_operand:SI 0 "register_operand" "=r")
6547         (match_operand:SI 1 "register_operand" "r"))
6548    (set (reg:CC 100)
6549         (compare:CC (match_dup 1)
6550                     (const_int 0)))]
6551   ""
6552   "orcc\t%1, 0, %0"
6553   [(set_attr "type" "compare")])
6555 (define_insn "*cmp_ccx_set64"
6556   [(set (match_operand:DI 0 "register_operand" "=r")
6557         (match_operand:DI 1 "register_operand" "r"))
6558    (set (reg:CCX 100)
6559         (compare:CCX (match_dup 1)
6560                      (const_int 0)))]
6561   "TARGET_ARCH64"
6562   "orcc\t%1, 0, %0"
6563    [(set_attr "type" "compare")])
6565 ;; Floating point arithmetic instructions.
6567 (define_expand "addtf3"
6568   [(set (match_operand:TF 0 "nonimmediate_operand" "")
6569         (plus:TF (match_operand:TF 1 "general_operand" "")
6570                  (match_operand:TF 2 "general_operand" "")))]
6571   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6572   "emit_tfmode_binop (PLUS, operands); DONE;")
6574 (define_insn "*addtf3_hq"
6575   [(set (match_operand:TF 0 "register_operand" "=e")
6576         (plus:TF (match_operand:TF 1 "register_operand" "e")
6577                  (match_operand:TF 2 "register_operand" "e")))]
6578   "TARGET_FPU && TARGET_HARD_QUAD"
6579   "faddq\t%1, %2, %0"
6580   [(set_attr "type" "fp")])
6582 (define_insn "adddf3"
6583   [(set (match_operand:DF 0 "register_operand" "=e")
6584         (plus:DF (match_operand:DF 1 "register_operand" "e")
6585                  (match_operand:DF 2 "register_operand" "e")))]
6586   "TARGET_FPU"
6587   "faddd\t%1, %2, %0"
6588   [(set_attr "type" "fp")
6589    (set_attr "fptype" "double")])
6591 (define_insn "addsf3"
6592   [(set (match_operand:SF 0 "register_operand" "=f")
6593         (plus:SF (match_operand:SF 1 "register_operand" "f")
6594                  (match_operand:SF 2 "register_operand" "f")))]
6595   "TARGET_FPU"
6596   "fadds\t%1, %2, %0"
6597   [(set_attr "type" "fp")])
6599 (define_expand "subtf3"
6600   [(set (match_operand:TF 0 "nonimmediate_operand" "")
6601         (minus:TF (match_operand:TF 1 "general_operand" "")
6602                   (match_operand:TF 2 "general_operand" "")))]
6603   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6604   "emit_tfmode_binop (MINUS, operands); DONE;")
6606 (define_insn "*subtf3_hq"
6607   [(set (match_operand:TF 0 "register_operand" "=e")
6608         (minus:TF (match_operand:TF 1 "register_operand" "e")
6609                   (match_operand:TF 2 "register_operand" "e")))]
6610   "TARGET_FPU && TARGET_HARD_QUAD"
6611   "fsubq\t%1, %2, %0"
6612   [(set_attr "type" "fp")])
6614 (define_insn "subdf3"
6615   [(set (match_operand:DF 0 "register_operand" "=e")
6616         (minus:DF (match_operand:DF 1 "register_operand" "e")
6617                   (match_operand:DF 2 "register_operand" "e")))]
6618   "TARGET_FPU"
6619   "fsubd\t%1, %2, %0"
6620   [(set_attr "type" "fp")
6621    (set_attr "fptype" "double")])
6623 (define_insn "subsf3"
6624   [(set (match_operand:SF 0 "register_operand" "=f")
6625         (minus:SF (match_operand:SF 1 "register_operand" "f")
6626                   (match_operand:SF 2 "register_operand" "f")))]
6627   "TARGET_FPU"
6628   "fsubs\t%1, %2, %0"
6629   [(set_attr "type" "fp")])
6631 (define_expand "multf3"
6632   [(set (match_operand:TF 0 "nonimmediate_operand" "")
6633         (mult:TF (match_operand:TF 1 "general_operand" "")
6634                  (match_operand:TF 2 "general_operand" "")))]
6635   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6636   "emit_tfmode_binop (MULT, operands); DONE;")
6638 (define_insn "*multf3_hq"
6639   [(set (match_operand:TF 0 "register_operand" "=e")
6640         (mult:TF (match_operand:TF 1 "register_operand" "e")
6641                  (match_operand:TF 2 "register_operand" "e")))]
6642   "TARGET_FPU && TARGET_HARD_QUAD"
6643   "fmulq\t%1, %2, %0"
6644   [(set_attr "type" "fpmul")])
6646 (define_insn "muldf3"
6647   [(set (match_operand:DF 0 "register_operand" "=e")
6648         (mult:DF (match_operand:DF 1 "register_operand" "e")
6649                  (match_operand:DF 2 "register_operand" "e")))]
6650   "TARGET_FPU"
6651   "fmuld\t%1, %2, %0"
6652   [(set_attr "type" "fpmul")
6653    (set_attr "fptype" "double")])
6655 (define_insn "mulsf3"
6656   [(set (match_operand:SF 0 "register_operand" "=f")
6657         (mult:SF (match_operand:SF 1 "register_operand" "f")
6658                  (match_operand:SF 2 "register_operand" "f")))]
6659   "TARGET_FPU"
6660   "fmuls\t%1, %2, %0"
6661   [(set_attr "type" "fpmul")])
6663 (define_insn "*muldf3_extend"
6664   [(set (match_operand:DF 0 "register_operand" "=e")
6665         (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
6666                  (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
6667   "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
6668   "fsmuld\t%1, %2, %0"
6669   [(set_attr "type" "fpmul")
6670    (set_attr "fptype" "double")])
6672 (define_insn "*multf3_extend"
6673   [(set (match_operand:TF 0 "register_operand" "=e")
6674         (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
6675                  (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
6676   "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
6677   "fdmulq\t%1, %2, %0"
6678   [(set_attr "type" "fpmul")])
6680 (define_expand "divtf3"
6681   [(set (match_operand:TF 0 "nonimmediate_operand" "")
6682         (div:TF (match_operand:TF 1 "general_operand" "")
6683                 (match_operand:TF 2 "general_operand" "")))]
6684   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6685   "emit_tfmode_binop (DIV, operands); DONE;")
6687 ;; don't have timing for quad-prec. divide.
6688 (define_insn "*divtf3_hq"
6689   [(set (match_operand:TF 0 "register_operand" "=e")
6690         (div:TF (match_operand:TF 1 "register_operand" "e")
6691                 (match_operand:TF 2 "register_operand" "e")))]
6692   "TARGET_FPU && TARGET_HARD_QUAD"
6693   "fdivq\t%1, %2, %0"
6694   [(set_attr "type" "fpdivd")])
6696 (define_insn "divdf3"
6697   [(set (match_operand:DF 0 "register_operand" "=e")
6698         (div:DF (match_operand:DF 1 "register_operand" "e")
6699                 (match_operand:DF 2 "register_operand" "e")))]
6700   "TARGET_FPU"
6701   "fdivd\t%1, %2, %0"
6702   [(set_attr "type" "fpdivd")
6703    (set_attr "fptype" "double")])
6705 (define_insn "divsf3"
6706   [(set (match_operand:SF 0 "register_operand" "=f")
6707         (div:SF (match_operand:SF 1 "register_operand" "f")
6708                 (match_operand:SF 2 "register_operand" "f")))]
6709   "TARGET_FPU"
6710   "fdivs\t%1, %2, %0"
6711   [(set_attr "type" "fpdivs")])
6713 (define_expand "negtf2"
6714   [(set (match_operand:TF 0 "register_operand" "=e,e")
6715         (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6716   "TARGET_FPU"
6717   "")
6719 (define_insn_and_split "*negtf2_notv9"
6720   [(set (match_operand:TF 0 "register_operand" "=e,e")
6721         (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6722   ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6723   "TARGET_FPU
6724    && ! TARGET_V9"
6725   "@
6726   fnegs\t%0, %0
6727   #"
6728   "&& reload_completed
6729    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6730   [(set (match_dup 2) (neg:SF (match_dup 3)))
6731    (set (match_dup 4) (match_dup 5))
6732    (set (match_dup 6) (match_dup 7))]
6733   "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6734    operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6735    operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6736    operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6737    operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6738    operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6739   [(set_attr "type" "fpmove,*")
6740    (set_attr "length" "*,2")])
6742 (define_insn_and_split "*negtf2_v9"
6743   [(set (match_operand:TF 0 "register_operand" "=e,e")
6744         (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6745   ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6746   "TARGET_FPU && TARGET_V9"
6747   "@
6748   fnegd\t%0, %0
6749   #"
6750   "&& reload_completed
6751    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6752   [(set (match_dup 2) (neg:DF (match_dup 3)))
6753    (set (match_dup 4) (match_dup 5))]
6754   "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6755    operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6756    operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6757    operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6758   [(set_attr "type" "fpmove,*")
6759    (set_attr "length" "*,2")
6760    (set_attr "fptype" "double")])
6762 (define_expand "negdf2"
6763   [(set (match_operand:DF 0 "register_operand" "")
6764         (neg:DF (match_operand:DF 1 "register_operand" "")))]
6765   "TARGET_FPU"
6766   "")
6768 (define_insn_and_split "*negdf2_notv9"
6769   [(set (match_operand:DF 0 "register_operand" "=e,e")
6770         (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
6771   "TARGET_FPU && ! TARGET_V9"
6772   "@
6773   fnegs\t%0, %0
6774   #"
6775   "&& reload_completed
6776    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6777   [(set (match_dup 2) (neg:SF (match_dup 3)))
6778    (set (match_dup 4) (match_dup 5))]
6779   "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6780    operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6781    operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6782    operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6783   [(set_attr "type" "fpmove,*")
6784    (set_attr "length" "*,2")])
6786 (define_insn "*negdf2_v9"
6787   [(set (match_operand:DF 0 "register_operand" "=e")
6788         (neg:DF (match_operand:DF 1 "register_operand" "e")))]
6789   "TARGET_FPU && TARGET_V9"
6790   "fnegd\t%1, %0"
6791   [(set_attr "type" "fpmove")
6792    (set_attr "fptype" "double")])
6794 (define_insn "negsf2"
6795   [(set (match_operand:SF 0 "register_operand" "=f")
6796         (neg:SF (match_operand:SF 1 "register_operand" "f")))]
6797   "TARGET_FPU"
6798   "fnegs\t%1, %0"
6799   [(set_attr "type" "fpmove")])
6801 (define_expand "abstf2"
6802   [(set (match_operand:TF 0 "register_operand" "")
6803         (abs:TF (match_operand:TF 1 "register_operand" "")))]
6804   "TARGET_FPU"
6805   "")
6807 (define_insn_and_split "*abstf2_notv9"
6808   [(set (match_operand:TF 0 "register_operand" "=e,e")
6809         (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6810   ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6811   "TARGET_FPU && ! TARGET_V9"
6812   "@
6813   fabss\t%0, %0
6814   #"
6815   "&& reload_completed
6816    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6817   [(set (match_dup 2) (abs:SF (match_dup 3)))
6818    (set (match_dup 4) (match_dup 5))
6819    (set (match_dup 6) (match_dup 7))]
6820   "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6821    operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6822    operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6823    operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6824    operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6825    operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6826   [(set_attr "type" "fpmove,*")
6827    (set_attr "length" "*,2")])
6829 (define_insn "*abstf2_hq_v9"
6830   [(set (match_operand:TF 0 "register_operand" "=e,e")
6831         (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6832   "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
6833   "@
6834   fabsd\t%0, %0
6835   fabsq\t%1, %0"
6836   [(set_attr "type" "fpmove")
6837    (set_attr "fptype" "double,*")])
6839 (define_insn_and_split "*abstf2_v9"
6840   [(set (match_operand:TF 0 "register_operand" "=e,e")
6841         (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6842   "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
6843   "@
6844   fabsd\t%0, %0
6845   #"
6846   "&& reload_completed
6847    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6848   [(set (match_dup 2) (abs:DF (match_dup 3)))
6849    (set (match_dup 4) (match_dup 5))]
6850   "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6851    operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6852    operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6853    operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6854   [(set_attr "type" "fpmove,*")
6855    (set_attr "length" "*,2")
6856    (set_attr "fptype" "double,*")])
6858 (define_expand "absdf2"
6859   [(set (match_operand:DF 0 "register_operand" "")
6860         (abs:DF (match_operand:DF 1 "register_operand" "")))]
6861   "TARGET_FPU"
6862   "")
6864 (define_insn_and_split "*absdf2_notv9"
6865   [(set (match_operand:DF 0 "register_operand" "=e,e")
6866         (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
6867   "TARGET_FPU && ! TARGET_V9"
6868   "@
6869   fabss\t%0, %0
6870   #"
6871   "&& reload_completed
6872    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6873   [(set (match_dup 2) (abs:SF (match_dup 3)))
6874    (set (match_dup 4) (match_dup 5))]
6875   "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6876    operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6877    operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6878    operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6879   [(set_attr "type" "fpmove,*")
6880    (set_attr "length" "*,2")])
6882 (define_insn "*absdf2_v9"
6883   [(set (match_operand:DF 0 "register_operand" "=e")
6884         (abs:DF (match_operand:DF 1 "register_operand" "e")))]
6885   "TARGET_FPU && TARGET_V9"
6886   "fabsd\t%1, %0"
6887   [(set_attr "type" "fpmove")
6888    (set_attr "fptype" "double")])
6890 (define_insn "abssf2"
6891   [(set (match_operand:SF 0 "register_operand" "=f")
6892         (abs:SF (match_operand:SF 1 "register_operand" "f")))]
6893   "TARGET_FPU"
6894   "fabss\t%1, %0"
6895   [(set_attr "type" "fpmove")])
6897 (define_expand "sqrttf2"
6898   [(set (match_operand:TF 0 "nonimmediate_operand" "")
6899         (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
6900   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6901   "emit_tfmode_unop (SQRT, operands); DONE;")
6903 (define_insn "*sqrttf2_hq"
6904   [(set (match_operand:TF 0 "register_operand" "=e")
6905         (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
6906   "TARGET_FPU && TARGET_HARD_QUAD"
6907   "fsqrtq\t%1, %0"
6908   [(set_attr "type" "fpsqrtd")])
6910 (define_insn "sqrtdf2"
6911   [(set (match_operand:DF 0 "register_operand" "=e")
6912         (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
6913   "TARGET_FPU"
6914   "fsqrtd\t%1, %0"
6915   [(set_attr "type" "fpsqrtd")
6916    (set_attr "fptype" "double")])
6918 (define_insn "sqrtsf2"
6919   [(set (match_operand:SF 0 "register_operand" "=f")
6920         (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
6921   "TARGET_FPU"
6922   "fsqrts\t%1, %0"
6923   [(set_attr "type" "fpsqrts")])
6925 ;;- arithmetic shift instructions
6927 (define_insn "ashlsi3"
6928   [(set (match_operand:SI 0 "register_operand" "=r")
6929         (ashift:SI (match_operand:SI 1 "register_operand" "r")
6930                    (match_operand:SI 2 "arith_operand" "rI")))]
6931   ""
6933   if (operands[2] == const1_rtx)
6934     return "add\t%1, %1, %0";
6935   if (GET_CODE (operands[2]) == CONST_INT)
6936     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6937   return "sll\t%1, %2, %0";
6939   [(set (attr "type")
6940         (if_then_else (match_operand 2 "const1_operand" "")
6941                       (const_string "ialu") (const_string "shift")))])
6943 (define_expand "ashldi3"
6944   [(set (match_operand:DI 0 "register_operand" "=r")
6945         (ashift:DI (match_operand:DI 1 "register_operand" "r")
6946                    (match_operand:SI 2 "arith_operand" "rI")))]
6947   "TARGET_ARCH64 || TARGET_V8PLUS"
6949   if (! TARGET_ARCH64)
6950     {
6951       if (GET_CODE (operands[2]) == CONST_INT)
6952         FAIL;
6953       emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
6954       DONE;
6955     }
6958 (define_insn "*ashldi3_sp64"
6959   [(set (match_operand:DI 0 "register_operand" "=r")
6960         (ashift:DI (match_operand:DI 1 "register_operand" "r")
6961                    (match_operand:SI 2 "arith_operand" "rI")))]
6962   "TARGET_ARCH64"
6964   if (operands[2] == const1_rtx)
6965     return "add\t%1, %1, %0";
6966   if (GET_CODE (operands[2]) == CONST_INT)
6967     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6968   return "sllx\t%1, %2, %0";
6970   [(set (attr "type")
6971         (if_then_else (match_operand 2 "const1_operand" "")
6972                       (const_string "ialu") (const_string "shift")))])
6974 ;; XXX UGH!
6975 (define_insn "ashldi3_v8plus"
6976   [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6977         (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6978                    (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6979    (clobber (match_scratch:SI 3 "=X,X,&h"))]
6980   "TARGET_V8PLUS"
6981   "* return output_v8plus_shift (operands, insn, \"sllx\");"
6982   [(set_attr "type" "multi")
6983    (set_attr "length" "5,5,6")])
6985 ;; Optimize (1LL<<x)-1
6986 ;; XXX this also needs to be fixed to handle equal subregs
6987 ;; XXX first before we could re-enable it.
6988 ;(define_insn ""
6989 ;  [(set (match_operand:DI 0 "register_operand" "=h")
6990 ;       (plus:DI (ashift:DI (const_int 1)
6991 ;                           (match_operand:SI 1 "arith_operand" "rI"))
6992 ;                (const_int -1)))]
6993 ;  "0 && TARGET_V8PLUS"
6995 ;  if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
6996 ;    return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
6997 ;  return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
6999 ;  [(set_attr "type" "multi")
7000 ;   (set_attr "length" "4")])
7002 (define_insn "*cmp_cc_ashift_1"
7003   [(set (reg:CC_NOOV 100)
7004         (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
7005                                     (const_int 1))
7006                          (const_int 0)))]
7007   ""
7008   "addcc\t%0, %0, %%g0"
7009   [(set_attr "type" "compare")])
7011 (define_insn "*cmp_cc_set_ashift_1"
7012   [(set (reg:CC_NOOV 100)
7013         (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
7014                                     (const_int 1))
7015                          (const_int 0)))
7016    (set (match_operand:SI 0 "register_operand" "=r")
7017         (ashift:SI (match_dup 1) (const_int 1)))]
7018   ""
7019   "addcc\t%1, %1, %0"
7020   [(set_attr "type" "compare")])
7022 (define_insn "ashrsi3"
7023   [(set (match_operand:SI 0 "register_operand" "=r")
7024         (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7025                      (match_operand:SI 2 "arith_operand" "rI")))]
7026   ""
7027   {
7028      if (GET_CODE (operands[2]) == CONST_INT)
7029        operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7030      return "sra\t%1, %2, %0";
7031   }
7032   [(set_attr "type" "shift")])
7034 (define_insn "*ashrsi3_extend"
7035   [(set (match_operand:DI 0 "register_operand" "=r")
7036         (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7037                                      (match_operand:SI 2 "arith_operand" "r"))))]
7038   "TARGET_ARCH64"
7039   "sra\t%1, %2, %0"
7040   [(set_attr "type" "shift")])
7042 ;; This handles the case as above, but with constant shift instead of
7043 ;; register. Combiner "simplifies" it for us a little bit though.
7044 (define_insn "*ashrsi3_extend2"
7045   [(set (match_operand:DI 0 "register_operand" "=r")
7046         (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7047                                 (const_int 32))
7048                      (match_operand:SI 2 "small_int_or_double" "n")))]
7049   "TARGET_ARCH64
7050    && ((GET_CODE (operands[2]) == CONST_INT
7051         && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64)
7052        || (GET_CODE (operands[2]) == CONST_DOUBLE
7053            && !CONST_DOUBLE_HIGH (operands[2])
7054            && CONST_DOUBLE_LOW (operands[2]) >= 32
7055            && CONST_DOUBLE_LOW (operands[2]) < 64))"
7057   operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
7059   return "sra\t%1, %2, %0";
7061   [(set_attr "type" "shift")])
7063 (define_expand "ashrdi3"
7064   [(set (match_operand:DI 0 "register_operand" "=r")
7065         (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7066                      (match_operand:SI 2 "arith_operand" "rI")))]
7067   "TARGET_ARCH64 || TARGET_V8PLUS"
7069   if (! TARGET_ARCH64)
7070     {
7071       if (GET_CODE (operands[2]) == CONST_INT)
7072         FAIL;   /* prefer generic code in this case */
7073       emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
7074       DONE;
7075     }
7078 (define_insn "*ashrdi3_sp64"
7079   [(set (match_operand:DI 0 "register_operand" "=r")
7080         (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7081                      (match_operand:SI 2 "arith_operand" "rI")))]
7082   "TARGET_ARCH64"
7083   
7084   {
7085     if (GET_CODE (operands[2]) == CONST_INT)
7086       operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7087     return "srax\t%1, %2, %0";
7088   }
7089   [(set_attr "type" "shift")])
7091 ;; XXX
7092 (define_insn "ashrdi3_v8plus"
7093   [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7094         (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7095                      (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7096    (clobber (match_scratch:SI 3 "=X,X,&h"))]
7097   "TARGET_V8PLUS"
7098   "* return output_v8plus_shift (operands, insn, \"srax\");"
7099   [(set_attr "type" "multi")
7100    (set_attr "length" "5,5,6")])
7102 (define_insn "lshrsi3"
7103   [(set (match_operand:SI 0 "register_operand" "=r")
7104         (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
7105                      (match_operand:SI 2 "arith_operand" "rI")))]
7106   ""
7107   {
7108     if (GET_CODE (operands[2]) == CONST_INT)
7109       operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7110     return "srl\t%1, %2, %0";
7111   }
7112   [(set_attr "type" "shift")])
7114 ;; This handles the case where
7115 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
7116 ;; but combiner "simplifies" it for us.
7117 (define_insn "*lshrsi3_extend"
7118   [(set (match_operand:DI 0 "register_operand" "=r")
7119         (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
7120                            (match_operand:SI 2 "arith_operand" "r")) 0)
7121                 (match_operand 3 "" "")))]
7122   "TARGET_ARCH64
7123    && ((GET_CODE (operands[3]) == CONST_DOUBLE
7124            && CONST_DOUBLE_HIGH (operands[3]) == 0
7125            && CONST_DOUBLE_LOW (operands[3]) == 0xffffffff)
7126        || (HOST_BITS_PER_WIDE_INT >= 64
7127            && GET_CODE (operands[3]) == CONST_INT
7128            && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff))"
7129   "srl\t%1, %2, %0"
7130   [(set_attr "type" "shift")])
7132 ;; This handles the case where
7133 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
7134 ;; but combiner "simplifies" it for us.
7135 (define_insn "*lshrsi3_extend2"
7136   [(set (match_operand:DI 0 "register_operand" "=r")
7137         (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7138                          (match_operand 2 "small_int_or_double" "n")
7139                          (const_int 32)))]
7140   "TARGET_ARCH64
7141    && ((GET_CODE (operands[2]) == CONST_INT
7142         && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7143        || (GET_CODE (operands[2]) == CONST_DOUBLE
7144            && CONST_DOUBLE_HIGH (operands[2]) == 0
7145            && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7147   operands[2] = GEN_INT (32 - INTVAL (operands[2]));
7149   return "srl\t%1, %2, %0";
7151   [(set_attr "type" "shift")])
7153 (define_expand "lshrdi3"
7154   [(set (match_operand:DI 0 "register_operand" "=r")
7155         (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7156                      (match_operand:SI 2 "arith_operand" "rI")))]
7157   "TARGET_ARCH64 || TARGET_V8PLUS"
7159   if (! TARGET_ARCH64)
7160     {
7161       if (GET_CODE (operands[2]) == CONST_INT)
7162         FAIL;
7163       emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
7164       DONE;
7165     }
7168 (define_insn "*lshrdi3_sp64"
7169   [(set (match_operand:DI 0 "register_operand" "=r")
7170         (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7171                      (match_operand:SI 2 "arith_operand" "rI")))]
7172   "TARGET_ARCH64"
7173   {
7174     if (GET_CODE (operands[2]) == CONST_INT)
7175       operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7176     return "srlx\t%1, %2, %0";
7177   }
7178   [(set_attr "type" "shift")])
7180 ;; XXX
7181 (define_insn "lshrdi3_v8plus"
7182   [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7183         (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7184                      (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7185    (clobber (match_scratch:SI 3 "=X,X,&h"))]
7186   "TARGET_V8PLUS"
7187   "* return output_v8plus_shift (operands, insn, \"srlx\");"
7188   [(set_attr "type" "multi")
7189    (set_attr "length" "5,5,6")])
7191 (define_insn ""
7192   [(set (match_operand:SI 0 "register_operand" "=r")
7193         (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7194                                              (const_int 32)) 4)
7195                      (match_operand:SI 2 "small_int_or_double" "n")))]
7196   "TARGET_ARCH64
7197    && ((GET_CODE (operands[2]) == CONST_INT
7198         && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7199        || (GET_CODE (operands[2]) == CONST_DOUBLE
7200            && !CONST_DOUBLE_HIGH (operands[2])
7201            && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7203   operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
7205   return "srax\t%1, %2, %0";
7207   [(set_attr "type" "shift")])
7209 (define_insn ""
7210   [(set (match_operand:SI 0 "register_operand" "=r")
7211         (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7212                                              (const_int 32)) 4)
7213                      (match_operand:SI 2 "small_int_or_double" "n")))]
7214   "TARGET_ARCH64
7215    && ((GET_CODE (operands[2]) == CONST_INT
7216         && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7217        || (GET_CODE (operands[2]) == CONST_DOUBLE
7218            && !CONST_DOUBLE_HIGH (operands[2])
7219            && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7221   operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
7223   return "srlx\t%1, %2, %0";
7225   [(set_attr "type" "shift")])
7227 (define_insn ""
7228   [(set (match_operand:SI 0 "register_operand" "=r")
7229         (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7230                                              (match_operand:SI 2 "small_int_or_double" "n")) 4)
7231                      (match_operand:SI 3 "small_int_or_double" "n")))]
7232   "TARGET_ARCH64
7233    && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
7234    && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
7235    && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
7236    && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
7238   operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
7240   return "srax\t%1, %2, %0";
7242   [(set_attr "type" "shift")])
7244 (define_insn ""
7245   [(set (match_operand:SI 0 "register_operand" "=r")
7246         (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7247                                              (match_operand:SI 2 "small_int_or_double" "n")) 4)
7248                      (match_operand:SI 3 "small_int_or_double" "n")))]
7249   "TARGET_ARCH64
7250    && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
7251    && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
7252    && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
7253    && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
7255   operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
7257   return "srlx\t%1, %2, %0";
7259   [(set_attr "type" "shift")])
7261 ;; Unconditional and other jump instructions
7262 ;; On the SPARC, by setting the annul bit on an unconditional branch, the
7263 ;; following insn is never executed.  This saves us a nop.  Dbx does not
7264 ;; handle such branches though, so we only use them when optimizing.
7265 (define_insn "jump"
7266   [(set (pc) (label_ref (match_operand 0 "" "")))]
7267   ""
7269   /* TurboSPARC is reported to have problems with
7270      with
7271         foo: b,a foo
7272      i.e. an empty loop with the annul bit set.  The workaround is to use 
7273         foo: b foo; nop
7274      instead.  */
7276   if (! TARGET_V9 && flag_delayed_branch
7277       && (INSN_ADDRESSES (INSN_UID (operands[0]))
7278           == INSN_ADDRESSES (INSN_UID (insn))))
7279     return "b\t%l0%#";
7280   else
7281     return TARGET_V9 ? "ba%*,pt\t%%xcc, %l0%(" : "b%*\t%l0%(";
7283   [(set_attr "type" "uncond_branch")])
7285 (define_expand "tablejump"
7286   [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
7287               (use (label_ref (match_operand 1 "" "")))])]
7288   ""
7290   if (GET_MODE (operands[0]) != CASE_VECTOR_MODE)
7291     abort ();
7293   /* In pic mode, our address differences are against the base of the
7294      table.  Add that base value back in; CSE ought to be able to combine
7295      the two address loads.  */
7296   if (flag_pic)
7297     {
7298       rtx tmp, tmp2;
7299       tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
7300       tmp2 = operands[0];
7301       if (CASE_VECTOR_MODE != Pmode)
7302         tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
7303       tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
7304       operands[0] = memory_address (Pmode, tmp);
7305     }
7308 (define_insn "*tablejump_sp32"
7309   [(set (pc) (match_operand:SI 0 "address_operand" "p"))
7310    (use (label_ref (match_operand 1 "" "")))]
7311   "! TARGET_ARCH64"
7312   "jmp\t%a0%#"
7313   [(set_attr "type" "uncond_branch")])
7315 (define_insn "*tablejump_sp64"
7316   [(set (pc) (match_operand:DI 0 "address_operand" "p"))
7317    (use (label_ref (match_operand 1 "" "")))]
7318   "TARGET_ARCH64"
7319   "jmp\t%a0%#"
7320   [(set_attr "type" "uncond_branch")])
7322 ;;- jump to subroutine
7323 (define_expand "call"
7324   ;; Note that this expression is not used for generating RTL.
7325   ;; All the RTL is generated explicitly below.
7326   [(call (match_operand 0 "call_operand" "")
7327          (match_operand 3 "" "i"))]
7328   ;; operands[2] is next_arg_register
7329   ;; operands[3] is struct_value_size_rtx.
7330   ""
7332   rtx fn_rtx;
7334   if (GET_MODE (operands[0]) != FUNCTION_MODE)
7335     abort ();
7337   if (GET_CODE (operands[3]) != CONST_INT)
7338     abort();
7340   if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
7341     {
7342       /* This is really a PIC sequence.  We want to represent
7343          it as a funny jump so its delay slots can be filled. 
7345          ??? But if this really *is* a CALL, will not it clobber the
7346          call-clobbered registers?  We lose this if it is a JUMP_INSN.
7347          Why cannot we have delay slots filled if it were a CALL?  */
7349       /* We accept negative sizes for untyped calls.  */
7350       if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7351         emit_jump_insn
7352           (gen_rtx_PARALLEL
7353            (VOIDmode,
7354             gen_rtvec (3,
7355                        gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
7356                        operands[3],
7357                        gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7358       else
7359         emit_jump_insn
7360           (gen_rtx_PARALLEL
7361            (VOIDmode,
7362             gen_rtvec (2,
7363                        gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
7364                        gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7365       goto finish_call;
7366     }
7368   fn_rtx = operands[0];
7370   /* We accept negative sizes for untyped calls.  */
7371   if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7372     emit_call_insn
7373       (gen_rtx_PARALLEL
7374        (VOIDmode,
7375         gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
7376                    operands[3],
7377                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7378   else
7379     emit_call_insn
7380       (gen_rtx_PARALLEL
7381        (VOIDmode,
7382         gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
7383                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7385  finish_call:
7387   DONE;
7390 ;; We can't use the same pattern for these two insns, because then registers
7391 ;; in the address may not be properly reloaded.
7393 (define_insn "*call_address_sp32"
7394   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7395          (match_operand 1 "" ""))
7396    (clobber (reg:SI 15))]
7397   ;;- Do not use operand 1 for most machines.
7398   "! TARGET_ARCH64"
7399   "call\t%a0, %1%#"
7400   [(set_attr "type" "call")])
7402 (define_insn "*call_symbolic_sp32"
7403   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7404          (match_operand 1 "" ""))
7405    (clobber (reg:SI 15))]
7406   ;;- Do not use operand 1 for most machines.
7407   "! TARGET_ARCH64"
7408   "call\t%a0, %1%#"
7409   [(set_attr "type" "call")])
7411 (define_insn "*call_address_sp64"
7412   [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
7413          (match_operand 1 "" ""))
7414    (clobber (reg:DI 15))]
7415   ;;- Do not use operand 1 for most machines.
7416   "TARGET_ARCH64"
7417   "call\t%a0, %1%#"
7418   [(set_attr "type" "call")])
7420 (define_insn "*call_symbolic_sp64"
7421   [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
7422          (match_operand 1 "" ""))
7423    (clobber (reg:DI 15))]
7424   ;;- Do not use operand 1 for most machines.
7425   "TARGET_ARCH64"
7426   "call\t%a0, %1%#"
7427   [(set_attr "type" "call")])
7429 ;; This is a call that wants a structure value.
7430 ;; There is no such critter for v9 (??? we may need one anyway).
7431 (define_insn "*call_address_struct_value_sp32"
7432   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7433          (match_operand 1 "" ""))
7434    (match_operand 2 "immediate_operand" "")
7435    (clobber (reg:SI 15))]
7436   ;;- Do not use operand 1 for most machines.
7437   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
7438   "call\t%a0, %1\n\t nop\n\tunimp\t%2"
7439   [(set_attr "type" "call_no_delay_slot")
7440    (set_attr "length" "3")])
7442 ;; This is a call that wants a structure value.
7443 ;; There is no such critter for v9 (??? we may need one anyway).
7444 (define_insn "*call_symbolic_struct_value_sp32"
7445   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7446          (match_operand 1 "" ""))
7447    (match_operand 2 "immediate_operand" "")
7448    (clobber (reg:SI 15))]
7449   ;;- Do not use operand 1 for most machines.
7450   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
7451   "call\t%a0, %1\n\t nop\n\tunimp\t%2"
7452   [(set_attr "type" "call_no_delay_slot")
7453    (set_attr "length" "3")])
7455 ;; This is a call that may want a structure value.  This is used for
7456 ;; untyped_calls.
7457 (define_insn "*call_address_untyped_struct_value_sp32"
7458   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7459          (match_operand 1 "" ""))
7460    (match_operand 2 "immediate_operand" "")
7461    (clobber (reg:SI 15))]
7462   ;;- Do not use operand 1 for most machines.
7463   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7464   "call\t%a0, %1\n\t nop\n\tnop"
7465   [(set_attr "type" "call_no_delay_slot")
7466    (set_attr "length" "3")])
7468 ;; This is a call that may want a structure value.  This is used for
7469 ;; untyped_calls.
7470 (define_insn "*call_symbolic_untyped_struct_value_sp32"
7471   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7472          (match_operand 1 "" ""))
7473    (match_operand 2 "immediate_operand" "")
7474    (clobber (reg:SI 15))]
7475   ;;- Do not use operand 1 for most machines.
7476   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7477   "call\t%a0, %1\n\t nop\n\tnop"
7478   [(set_attr "type" "call_no_delay_slot")
7479    (set_attr "length" "3")])
7481 (define_expand "call_value"
7482   ;; Note that this expression is not used for generating RTL.
7483   ;; All the RTL is generated explicitly below.
7484   [(set (match_operand 0 "register_operand" "=rf")
7485         (call (match_operand 1 "" "")
7486               (match_operand 4 "" "")))]
7487   ;; operand 2 is stack_size_rtx
7488   ;; operand 3 is next_arg_register
7489   ""
7491   rtx fn_rtx;
7492   rtvec vec;
7494   if (GET_MODE (operands[1]) != FUNCTION_MODE)
7495     abort ();
7497   fn_rtx = operands[1];
7499   vec = gen_rtvec (2,
7500                    gen_rtx_SET (VOIDmode, operands[0],
7501                                 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
7502                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
7504   emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
7506   DONE;
7509 (define_insn "*call_value_address_sp32"
7510   [(set (match_operand 0 "" "=rf")
7511         (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
7512               (match_operand 2 "" "")))
7513    (clobber (reg:SI 15))]
7514   ;;- Do not use operand 2 for most machines.
7515   "! TARGET_ARCH64"
7516   "call\t%a1, %2%#"
7517   [(set_attr "type" "call")])
7519 (define_insn "*call_value_symbolic_sp32"
7520   [(set (match_operand 0 "" "=rf")
7521         (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7522               (match_operand 2 "" "")))
7523    (clobber (reg:SI 15))]
7524   ;;- Do not use operand 2 for most machines.
7525   "! TARGET_ARCH64"
7526   "call\t%a1, %2%#"
7527   [(set_attr "type" "call")])
7529 (define_insn "*call_value_address_sp64"
7530   [(set (match_operand 0 "" "")
7531         (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
7532               (match_operand 2 "" "")))
7533    (clobber (reg:DI 15))]
7534   ;;- Do not use operand 2 for most machines.
7535   "TARGET_ARCH64"
7536   "call\t%a1, %2%#"
7537   [(set_attr "type" "call")])
7539 (define_insn "*call_value_symbolic_sp64"
7540   [(set (match_operand 0 "" "")
7541         (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
7542               (match_operand 2 "" "")))
7543    (clobber (reg:DI 15))]
7544   ;;- Do not use operand 2 for most machines.
7545   "TARGET_ARCH64"
7546   "call\t%a1, %2%#"
7547   [(set_attr "type" "call")])
7549 (define_expand "untyped_call"
7550   [(parallel [(call (match_operand 0 "" "")
7551                     (const_int 0))
7552               (match_operand 1 "" "")
7553               (match_operand 2 "" "")])]
7554   ""
7556   int i;
7558   /* Pass constm1 to indicate that it may expect a structure value, but
7559      we don't know what size it is.  */
7560   emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
7562   for (i = 0; i < XVECLEN (operands[2], 0); i++)
7563     {
7564       rtx set = XVECEXP (operands[2], 0, i);
7565       emit_move_insn (SET_DEST (set), SET_SRC (set));
7566     }
7568   /* The optimizer does not know that the call sets the function value
7569      registers we stored in the result block.  We avoid problems by
7570      claiming that all hard registers are used and clobbered at this
7571      point.  */
7572   emit_insn (gen_blockage ());
7574   DONE;
7577 ;;- tail calls
7578 (define_expand "sibcall"
7579   [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
7580               (return)])]
7581   ""
7582   "")
7584 (define_insn "*sibcall_symbolic_sp32"
7585   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7586          (match_operand 1 "" ""))
7587    (return)]
7588   "! TARGET_ARCH64"
7589   "* return output_sibcall(insn, operands[0]);"
7590   [(set_attr "type" "sibcall")])
7592 (define_insn "*sibcall_symbolic_sp64"
7593   [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
7594          (match_operand 1 "" ""))
7595    (return)]
7596   "TARGET_ARCH64"
7597   "* return output_sibcall(insn, operands[0]);"
7598   [(set_attr "type" "sibcall")])
7600 (define_expand "sibcall_value"
7601   [(parallel [(set (match_operand 0 "register_operand" "=rf")
7602                 (call (match_operand 1 "" "") (const_int 0)))
7603               (return)])]
7604   ""
7605   "")
7607 (define_insn "*sibcall_value_symbolic_sp32"
7608   [(set (match_operand 0 "" "=rf")
7609         (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7610               (match_operand 2 "" "")))
7611    (return)]
7612   "! TARGET_ARCH64"
7613   "* return output_sibcall(insn, operands[1]);"
7614   [(set_attr "type" "sibcall")])
7616 (define_insn "*sibcall_value_symbolic_sp64"
7617   [(set (match_operand 0 "" "")
7618         (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
7619               (match_operand 2 "" "")))
7620    (return)]
7621   "TARGET_ARCH64"
7622   "* return output_sibcall(insn, operands[1]);"
7623   [(set_attr "type" "sibcall")])
7625 (define_expand "sibcall_epilogue"
7626   [(return)]
7627   ""
7629   sparc_expand_epilogue ();
7630   DONE;
7633 (define_expand "prologue"
7634   [(const_int 0)]
7635   ""
7637   sparc_expand_prologue ();
7638   DONE;
7641 (define_expand "save_register_window"
7642   [(use (match_operand 0 "arith_operand" ""))]
7643   ""
7645   rtvec vec;
7647   vec = gen_rtvec (2,
7648                    gen_rtx_SET (VOIDmode,
7649                                 stack_pointer_rtx,
7650                                 gen_rtx_PLUS (Pmode,
7651                                               hard_frame_pointer_rtx,
7652                                               operands[0])),
7653                    gen_rtx_UNSPEC_VOLATILE (VOIDmode,
7654                                             gen_rtvec (1, const0_rtx),
7655                                             UNSPECV_SAVEW));
7657   emit_insn (gen_rtx_PARALLEL (VOIDmode, vec));
7658   DONE;
7661 (define_insn "*save_register_windowsi"
7662   [(set (reg:SI 14) (plus:SI (reg:SI 30)
7663                              (match_operand:SI 0 "arith_operand" "rI")))
7664    (unspec_volatile [(const_int 0)] UNSPECV_SAVEW)]
7665   "! TARGET_ARCH64"
7666   "save\t%%sp, %0, %%sp"
7667   [(set_attr "type" "savew")])
7669 (define_insn "*save_register_windowdi"
7670   [(set (reg:DI 14) (plus:DI (reg:DI 30)
7671                              (match_operand:DI 0 "arith_operand" "rI")))
7672    (unspec_volatile [(const_int 0)] UNSPECV_SAVEW)]
7673   "TARGET_ARCH64"
7674   "save\t%%sp, %0, %%sp"
7675   [(set_attr "type" "savew")])
7677 (define_expand "epilogue"
7678   [(return)]
7679   ""
7681   sparc_expand_epilogue ();
7684 (define_insn "*return_internal"
7685   [(return)]
7686   ""
7687   "* return output_return (insn);"
7688   [(set_attr "type" "return")
7689    (set_attr "length" "2")])
7691 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
7692 ;; all of memory.  This blocks insns from being moved across this point.
7694 (define_insn "blockage"
7695   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7696   ""
7697   ""
7698   [(set_attr "length" "0")])
7700 ;; Prepare to return any type including a structure value.
7702 (define_expand "untyped_return"
7703   [(match_operand:BLK 0 "memory_operand" "")
7704    (match_operand 1 "" "")]
7705   ""
7707   rtx valreg1 = gen_rtx_REG (DImode, 24);
7708   rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
7709   rtx result = operands[0];
7711   if (! TARGET_ARCH64)
7712     {
7713       rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
7714                                          ? 15 : 31));
7715       rtx value = gen_reg_rtx (SImode);
7717       /* Fetch the instruction where we will return to and see if it's an unimp
7718          instruction (the most significant 10 bits will be zero).  If so,
7719          update the return address to skip the unimp instruction.  */
7720       emit_move_insn (value,
7721                       gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
7722       emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
7723       emit_insn (gen_update_return (rtnreg, value));
7724     }
7726   /* Reload the function value registers.  */
7727   emit_move_insn (valreg1, adjust_address (result, DImode, 0));
7728   emit_move_insn (valreg2,
7729                   adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
7731   /* Put USE insns before the return.  */
7732   emit_insn (gen_rtx_USE (VOIDmode, valreg1));
7733   emit_insn (gen_rtx_USE (VOIDmode, valreg2));
7735   /* Construct the return.  */
7736   expand_naked_return ();
7738   DONE;
7741 ;; This is a bit of a hack.  We're incrementing a fixed register (%i7),
7742 ;; and parts of the compiler don't want to believe that the add is needed.
7744 (define_insn "update_return"
7745   [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
7746                (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
7747   "! TARGET_ARCH64"
7748   "cmp\t%1, 0\;be,a\t.+8\;add\t%0, 4, %0"
7749   [(set_attr "type" "multi")
7750    (set_attr "length" "3")])
7752 (define_insn "nop"
7753   [(const_int 0)]
7754   ""
7755   "nop")
7757 (define_expand "indirect_jump"
7758   [(set (pc) (match_operand 0 "address_operand" "p"))]
7759   ""
7760   "")
7762 (define_insn "*branch_sp32"
7763   [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
7764   "! TARGET_ARCH64"
7765  "jmp\t%a0%#"
7766  [(set_attr "type" "uncond_branch")])
7768 (define_insn "*branch_sp64"
7769   [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
7770   "TARGET_ARCH64"
7771   "jmp\t%a0%#"
7772   [(set_attr "type" "uncond_branch")])
7774 (define_expand "nonlocal_goto"
7775   [(match_operand:SI 0 "general_operand" "")
7776    (match_operand:SI 1 "general_operand" "")
7777    (match_operand:SI 2 "general_operand" "")
7778    (match_operand:SI 3 "" "")]
7779   ""
7781 #if 0
7782   rtx chain = operands[0];
7783 #endif
7784   rtx lab = operands[1];
7785   rtx stack = operands[2];
7786   rtx fp = operands[3];
7787   rtx labreg;
7789   /* Trap instruction to flush all the register windows.  */
7790   emit_insn (gen_flush_register_windows ());
7792   /* Load the fp value for the containing fn into %fp.  This is needed
7793      because STACK refers to %fp.  Note that virtual register instantiation
7794      fails if the virtual %fp isn't set from a register.  */
7795   if (GET_CODE (fp) != REG)
7796     fp = force_reg (Pmode, fp);
7797   emit_move_insn (virtual_stack_vars_rtx, fp);
7799   /* Find the containing function's current nonlocal goto handler,
7800      which will do any cleanups and then jump to the label.  */
7801   labreg = gen_rtx_REG (Pmode, 8);
7802   emit_move_insn (labreg, lab);
7804   /* Restore %fp from stack pointer value for containing function.
7805      The restore insn that follows will move this to %sp,
7806      and reload the appropriate value into %fp.  */
7807   emit_move_insn (hard_frame_pointer_rtx, stack);
7809   /* USE of frame_pointer_rtx added for consistency; not clear if
7810      really needed.  */
7811   /*emit_insn (gen_rtx_USE (VOIDmode, frame_pointer_rtx));*/
7812   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
7814 #if 0
7815   /* Return, restoring reg window and jumping to goto handler.  */
7816   if (TARGET_V9 && GET_CODE (chain) == CONST_INT
7817       && ! (INTVAL (chain) & ~(HOST_WIDE_INT)0xffffffff))
7818     {
7819       emit_jump_insn (gen_goto_handler_and_restore_v9 (labreg,
7820                                                        static_chain_rtx,
7821                                                        chain));
7822       emit_barrier ();
7823       DONE;
7824     }
7825   /* Put in the static chain register the nonlocal label address.  */
7826   emit_move_insn (static_chain_rtx, chain);
7827 #endif
7829   emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
7830   emit_jump_insn (gen_goto_handler_and_restore (labreg));
7831   emit_barrier ();
7832   DONE;
7835 ;; Special trap insn to flush register windows.
7836 (define_insn "flush_register_windows"
7837   [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
7838   ""
7839   { return TARGET_V9 ? "flushw" : "ta\t3"; }
7840   [(set_attr "type" "flushw")])
7842 (define_insn "goto_handler_and_restore"
7843   [(unspec_volatile [(match_operand 0 "register_operand" "=r")] UNSPECV_GOTO)]
7844   "GET_MODE (operands[0]) == Pmode"
7845   "jmp\t%0+0\n\trestore"
7846   [(set_attr "type" "multi")
7847    (set_attr "length" "2")])
7849 ;;(define_insn "goto_handler_and_restore_v9"
7850 ;;  [(unspec_volatile [(match_operand:SI 0 "register_operand" "=r,r")
7851 ;;                   (match_operand:SI 1 "register_operand" "=r,r")
7852 ;;                   (match_operand:SI 2 "const_int_operand" "I,n")] UNSPECV_GOTO_V9)]
7853 ;;  "TARGET_V9 && ! TARGET_ARCH64"
7854 ;;  "@
7855 ;;   return\t%0+0\n\tmov\t%2, %Y1
7856 ;;   sethi\t%%hi(%2), %1\n\treturn\t%0+0\n\tor\t%Y1, %%lo(%2), %Y1"
7857 ;;  [(set_attr "type" "multi")
7858 ;;   (set_attr "length" "2,3")])
7860 ;;(define_insn "*goto_handler_and_restore_v9_sp64"
7861 ;;  [(unspec_volatile [(match_operand:DI 0 "register_operand" "=r,r")
7862 ;;                   (match_operand:DI 1 "register_operand" "=r,r")
7863 ;;                   (match_operand:SI 2 "const_int_operand" "I,n")] UNSPECV_GOTO_V9)]
7864 ;;  "TARGET_V9 && TARGET_ARCH64"
7865 ;;  "@
7866 ;;   return\t%0+0\n\tmov\t%2, %Y1
7867 ;;   sethi\t%%hi(%2), %1\n\treturn\t%0+0\n\tor\t%Y1, %%lo(%2), %Y1"
7868 ;;  [(set_attr "type" "multi")
7869 ;;   (set_attr "length" "2,3")])
7871 ;; For __builtin_setjmp we need to flush register windows iff the function
7872 ;; calls alloca as well, because otherwise the register window might be
7873 ;; saved after %sp adjustment and thus setjmp would crash
7874 (define_expand "builtin_setjmp_setup"
7875   [(match_operand 0 "register_operand" "r")]
7876   ""
7878   emit_insn (gen_do_builtin_setjmp_setup ());
7879   DONE;
7882 (define_insn "do_builtin_setjmp_setup"
7883   [(unspec_volatile [(const_int 0)] UNSPECV_SETJMP)]
7884   ""
7886   if (! current_function_calls_alloca)
7887     return "";
7888   if (! TARGET_V9)
7889     return "\tta\t3\n";
7890   fputs ("\tflushw\n", asm_out_file);
7891   if (flag_pic)
7892     fprintf (asm_out_file, "\tst%c\t%%l7, [%%sp+%d]\n",
7893              TARGET_ARCH64 ? 'x' : 'w',
7894              SPARC_STACK_BIAS + 7 * UNITS_PER_WORD);
7895   fprintf (asm_out_file, "\tst%c\t%%fp, [%%sp+%d]\n",
7896            TARGET_ARCH64 ? 'x' : 'w',
7897            SPARC_STACK_BIAS + 14 * UNITS_PER_WORD);
7898   fprintf (asm_out_file, "\tst%c\t%%i7, [%%sp+%d]\n",
7899            TARGET_ARCH64 ? 'x' : 'w',
7900            SPARC_STACK_BIAS + 15 * UNITS_PER_WORD);
7901   return "";
7903   [(set_attr "type" "multi")
7904    (set (attr "length")
7905         (cond [(eq_attr "current_function_calls_alloca" "false")
7906                  (const_int 0)
7907                (eq_attr "isa" "!v9")
7908                  (const_int 1)
7909                (eq_attr "pic" "true")
7910                  (const_int 4)] (const_int 3)))])
7912 ;; Pattern for use after a setjmp to store FP and the return register
7913 ;; into the stack area.
7915 (define_expand "setjmp"
7916   [(const_int 0)]
7917   ""
7919   if (TARGET_ARCH64)
7920     emit_insn (gen_setjmp_64 ());
7921   else
7922     emit_insn (gen_setjmp_32 ());
7923   DONE;
7926 (define_expand "setjmp_32"
7927   [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
7928    (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
7929   ""
7930   { operands[0] = frame_pointer_rtx; })
7932 (define_expand "setjmp_64"
7933   [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
7934    (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
7935   ""
7936   { operands[0] = frame_pointer_rtx; })
7938 ;; Special pattern for the FLUSH instruction.
7940 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
7941 ; of the define_insn otherwise missing a mode.  We make "flush", aka
7942 ; gen_flush, the default one since sparc_initialize_trampoline uses
7943 ; it on SImode mem values.
7945 (define_insn "flush"
7946   [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7947   ""
7948   { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7949   [(set_attr "type" "iflush")])
7951 (define_insn "flushdi"
7952   [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7953   ""
7954   { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7955   [(set_attr "type" "iflush")])
7958 ;; find first set.
7960 ;; The scan instruction searches from the most significant bit while ffs
7961 ;; searches from the least significant bit.  The bit index and treatment of
7962 ;; zero also differ.  It takes at least 7 instructions to get the proper
7963 ;; result.  Here is an obvious 8 instruction sequence.
7965 ;; XXX
7966 (define_insn "ffssi2"
7967   [(set (match_operand:SI 0 "register_operand" "=&r")
7968         (ffs:SI (match_operand:SI 1 "register_operand" "r")))
7969    (clobber (match_scratch:SI 2 "=&r"))]
7970   "TARGET_SPARCLITE || TARGET_SPARCLET"
7972   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";
7974   [(set_attr "type" "multi")
7975    (set_attr "length" "8")])
7977 ;; ??? This should be a define expand, so that the extra instruction have
7978 ;; a chance of being optimized away.
7980 ;; Disabled because none of the UltraSPARCs implement popc.  The HAL R1
7981 ;; does, but no one uses that and we don't have a switch for it.
7983 ;(define_insn "ffsdi2"
7984 ;  [(set (match_operand:DI 0 "register_operand" "=&r")
7985 ;       (ffs:DI (match_operand:DI 1 "register_operand" "r")))
7986 ;   (clobber (match_scratch:DI 2 "=&r"))]
7987 ;  "TARGET_ARCH64"
7988 ;  "neg\t%1, %2\;xnor\t%1, %2, %2\;popc\t%2, %0\;movzr\t%1, 0, %0"
7989 ;  [(set_attr "type" "multi")
7990 ;   (set_attr "length" "4")])
7994 ;; Peepholes go at the end.
7996 ;; Optimize consecutive loads or stores into ldd and std when possible.
7997 ;; The conditions in which we do this are very restricted and are 
7998 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
8000 (define_peephole2
8001   [(set (match_operand:SI 0 "memory_operand" "")
8002       (const_int 0))
8003    (set (match_operand:SI 1 "memory_operand" "")
8004       (const_int 0))]
8005   "TARGET_V9
8006    && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
8007   [(set (match_dup 0)
8008        (const_int 0))]
8009   "operands[0] = widen_memory_access (operands[0], DImode, 0);")
8011 (define_peephole2
8012   [(set (match_operand:SI 0 "memory_operand" "")
8013       (const_int 0))
8014    (set (match_operand:SI 1 "memory_operand" "")
8015       (const_int 0))]
8016   "TARGET_V9
8017    && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
8018   [(set (match_dup 1)
8019        (const_int 0))]
8020   "operands[1] = widen_memory_access (operands[1], DImode, 0);")
8022 (define_peephole2
8023   [(set (match_operand:SI 0 "register_operand" "")
8024         (match_operand:SI 1 "memory_operand" ""))
8025    (set (match_operand:SI 2 "register_operand" "")
8026         (match_operand:SI 3 "memory_operand" ""))]
8027   "registers_ok_for_ldd_peep (operands[0], operands[2]) 
8028    && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])" 
8029   [(set (match_dup 0)
8030         (match_dup 1))]
8031   "operands[1] = widen_memory_access (operands[1], DImode, 0);
8032    operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
8034 (define_peephole2
8035   [(set (match_operand:SI 0 "memory_operand" "")
8036         (match_operand:SI 1 "register_operand" ""))
8037    (set (match_operand:SI 2 "memory_operand" "")
8038         (match_operand:SI 3 "register_operand" ""))]
8039   "registers_ok_for_ldd_peep (operands[1], operands[3]) 
8040    && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
8041   [(set (match_dup 0)
8042         (match_dup 1))]
8043   "operands[0] = widen_memory_access (operands[0], DImode, 0);
8044    operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
8046 (define_peephole2
8047   [(set (match_operand:SF 0 "register_operand" "")
8048         (match_operand:SF 1 "memory_operand" ""))
8049    (set (match_operand:SF 2 "register_operand" "")
8050         (match_operand:SF 3 "memory_operand" ""))]
8051   "registers_ok_for_ldd_peep (operands[0], operands[2]) 
8052    && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
8053   [(set (match_dup 0)
8054         (match_dup 1))]
8055   "operands[1] = widen_memory_access (operands[1], DFmode, 0);
8056    operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
8058 (define_peephole2
8059   [(set (match_operand:SF 0 "memory_operand" "")
8060         (match_operand:SF 1 "register_operand" ""))
8061    (set (match_operand:SF 2 "memory_operand" "")
8062         (match_operand:SF 3 "register_operand" ""))]
8063   "registers_ok_for_ldd_peep (operands[1], operands[3]) 
8064   && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
8065   [(set (match_dup 0)
8066         (match_dup 1))]
8067   "operands[0] = widen_memory_access (operands[0], DFmode, 0);
8068    operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
8070 (define_peephole2
8071   [(set (match_operand:SI 0 "register_operand" "")
8072         (match_operand:SI 1 "memory_operand" ""))
8073    (set (match_operand:SI 2 "register_operand" "")
8074         (match_operand:SI 3 "memory_operand" ""))]
8075   "registers_ok_for_ldd_peep (operands[2], operands[0]) 
8076   && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
8077   [(set (match_dup 2)
8078         (match_dup 3))]
8079    "operands[3] = widen_memory_access (operands[3], DImode, 0);
8080     operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
8082 (define_peephole2
8083   [(set (match_operand:SI 0 "memory_operand" "")
8084         (match_operand:SI 1 "register_operand" ""))
8085    (set (match_operand:SI 2 "memory_operand" "")
8086         (match_operand:SI 3 "register_operand" ""))]
8087   "registers_ok_for_ldd_peep (operands[3], operands[1]) 
8088   && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)" 
8089   [(set (match_dup 2)
8090         (match_dup 3))]
8091   "operands[2] = widen_memory_access (operands[2], DImode, 0);
8092    operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
8093    ")
8095 (define_peephole2
8096   [(set (match_operand:SF 0 "register_operand" "")
8097         (match_operand:SF 1 "memory_operand" ""))
8098    (set (match_operand:SF 2 "register_operand" "")
8099         (match_operand:SF 3 "memory_operand" ""))]
8100   "registers_ok_for_ldd_peep (operands[2], operands[0]) 
8101   && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
8102   [(set (match_dup 2)
8103         (match_dup 3))]
8104   "operands[3] = widen_memory_access (operands[3], DFmode, 0);
8105    operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
8107 (define_peephole2
8108   [(set (match_operand:SF 0 "memory_operand" "")
8109         (match_operand:SF 1 "register_operand" ""))
8110    (set (match_operand:SF 2 "memory_operand" "")
8111         (match_operand:SF 3 "register_operand" ""))]
8112   "registers_ok_for_ldd_peep (operands[3], operands[1]) 
8113   && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
8114   [(set (match_dup 2)
8115         (match_dup 3))]
8116   "operands[2] = widen_memory_access (operands[2], DFmode, 0);
8117    operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
8119 ;; Optimize the case of following a reg-reg move with a test
8120 ;; of reg just moved.  Don't allow floating point regs for operand 0 or 1.
8121 ;; This can result from a float to fix conversion.
8123 (define_peephole2
8124   [(set (match_operand:SI 0 "register_operand" "")
8125         (match_operand:SI 1 "register_operand" ""))
8126    (set (reg:CC 100)
8127         (compare:CC (match_operand:SI 2 "register_operand" "")
8128                     (const_int 0)))]
8129   "(rtx_equal_p (operands[2], operands[0])
8130     || rtx_equal_p (operands[2], operands[1]))
8131     && ! SPARC_FP_REG_P (REGNO (operands[0]))
8132     && ! SPARC_FP_REG_P (REGNO (operands[1]))"
8133   [(parallel [(set (match_dup 0) (match_dup 1))
8134               (set (reg:CC 100)
8135                    (compare:CC (match_dup 1) (const_int 0)))])]
8136   "")
8138 (define_peephole2
8139   [(set (match_operand:DI 0 "register_operand" "")
8140         (match_operand:DI 1 "register_operand" ""))
8141    (set (reg:CCX 100)
8142         (compare:CCX (match_operand:DI 2 "register_operand" "")
8143                     (const_int 0)))]
8144   "TARGET_ARCH64
8145    && (rtx_equal_p (operands[2], operands[0])
8146        || rtx_equal_p (operands[2], operands[1]))
8147    && ! SPARC_FP_REG_P (REGNO (operands[0]))
8148    && ! SPARC_FP_REG_P (REGNO (operands[1]))"
8149   [(parallel [(set (match_dup 0) (match_dup 1))
8150               (set (reg:CCX 100)
8151                    (compare:CCX (match_dup 1) (const_int 0)))])]
8152   "")
8154 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
8155 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
8156 ;; ??? operations.  With DFA we might be able to model this, but it requires a lot of
8157 ;; ??? state.
8158 (define_expand "prefetch"
8159   [(match_operand 0 "address_operand" "")
8160    (match_operand 1 "const_int_operand" "")
8161    (match_operand 2 "const_int_operand" "")]
8162   "TARGET_V9"
8164   if (TARGET_ARCH64)
8165     emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
8166   else
8167     emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
8168   DONE;
8171 (define_insn "prefetch_64"
8172   [(prefetch (match_operand:DI 0 "address_operand" "p")
8173              (match_operand:DI 1 "const_int_operand" "n")
8174              (match_operand:DI 2 "const_int_operand" "n"))]
8175   ""
8177   static const char * const prefetch_instr[2][2] = {
8178     {
8179       "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
8180       "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
8181     },
8182     {
8183       "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
8184       "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
8185     }
8186   };
8187   int read_or_write = INTVAL (operands[1]);
8188   int locality = INTVAL (operands[2]);
8190   if (read_or_write != 0 && read_or_write != 1)
8191     abort ();
8192   if (locality < 0 || locality > 3)
8193     abort ();
8194   return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
8196   [(set_attr "type" "load")])
8198 (define_insn "prefetch_32"
8199   [(prefetch (match_operand:SI 0 "address_operand" "p")
8200              (match_operand:SI 1 "const_int_operand" "n")
8201              (match_operand:SI 2 "const_int_operand" "n"))]
8202   ""
8204   static const char * const prefetch_instr[2][2] = {
8205     {
8206       "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
8207       "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
8208     },
8209     {
8210       "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
8211       "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
8212     }
8213   };
8214   int read_or_write = INTVAL (operands[1]);
8215   int locality = INTVAL (operands[2]);
8217   if (read_or_write != 0 && read_or_write != 1)
8218     abort ();
8219   if (locality < 0 || locality > 3)
8220     abort ();
8221   return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
8223   [(set_attr "type" "load")])
8225 (define_insn "trap"
8226   [(trap_if (const_int 1) (const_int 5))]
8227   ""
8228   "ta\t5"
8229   [(set_attr "type" "trap")])
8231 (define_expand "conditional_trap"
8232   [(trap_if (match_operator 0 "noov_compare_op"
8233                             [(match_dup 2) (match_dup 3)])
8234             (match_operand:SI 1 "arith_operand" ""))]
8235   ""
8236   "operands[2] = gen_compare_reg (GET_CODE (operands[0]),
8237                                   sparc_compare_op0, sparc_compare_op1);
8238    operands[3] = const0_rtx;")
8240 (define_insn ""
8241   [(trap_if (match_operator 0 "noov_compare_op" [(reg:CC 100) (const_int 0)])
8242             (match_operand:SI 1 "arith_operand" "rM"))]
8243   ""
8244   "t%C0\t%1"
8245   [(set_attr "type" "trap")])
8247 (define_insn ""
8248   [(trap_if (match_operator 0 "noov_compare_op" [(reg:CCX 100) (const_int 0)])
8249             (match_operand:SI 1 "arith_operand" "rM"))]
8250   "TARGET_V9"
8251   "t%C0\t%%xcc, %1"
8252   [(set_attr "type" "trap")])
8254 ;; TLS support
8255 (define_insn "tgd_hi22"
8256   [(set (match_operand:SI 0 "register_operand" "=r")
8257         (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
8258                             UNSPEC_TLSGD)))]
8259   "TARGET_TLS"
8260   "sethi\\t%%tgd_hi22(%a1), %0")
8262 (define_insn "tgd_lo10"
8263   [(set (match_operand:SI 0 "register_operand" "=r")
8264         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8265                    (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
8266                               UNSPEC_TLSGD)))]
8267   "TARGET_TLS"
8268   "add\\t%1, %%tgd_lo10(%a2), %0")
8270 (define_insn "tgd_add32"
8271   [(set (match_operand:SI 0 "register_operand" "=r")
8272         (plus:SI (match_operand:SI 1 "register_operand" "r")
8273                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8274                              (match_operand 3 "tgd_symbolic_operand" "")]
8275                             UNSPEC_TLSGD)))]
8276   "TARGET_TLS && TARGET_ARCH32"
8277   "add\\t%1, %2, %0, %%tgd_add(%a3)")
8279 (define_insn "tgd_add64"
8280   [(set (match_operand:DI 0 "register_operand" "=r")
8281         (plus:DI (match_operand:DI 1 "register_operand" "r")
8282                  (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8283                              (match_operand 3 "tgd_symbolic_operand" "")]
8284                             UNSPEC_TLSGD)))]
8285   "TARGET_TLS && TARGET_ARCH64"
8286   "add\\t%1, %2, %0, %%tgd_add(%a3)")
8288 (define_insn "tgd_call32"
8289   [(set (match_operand 0 "register_operand" "=r")
8290         (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
8291                                   (match_operand 2 "tgd_symbolic_operand" "")]
8292                                  UNSPEC_TLSGD))
8293               (match_operand 3 "" "")))
8294    (clobber (reg:SI 15))]
8295   "TARGET_TLS && TARGET_ARCH32"
8296   "call\t%a1, %%tgd_call(%a2)%#"
8297   [(set_attr "type" "call")])
8299 (define_insn "tgd_call64"
8300   [(set (match_operand 0 "register_operand" "=r")
8301         (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
8302                                   (match_operand 2 "tgd_symbolic_operand" "")]
8303                                  UNSPEC_TLSGD))
8304               (match_operand 3 "" "")))
8305    (clobber (reg:DI 15))]
8306   "TARGET_TLS && TARGET_ARCH64"
8307   "call\t%a1, %%tgd_call(%a2)%#"
8308   [(set_attr "type" "call")])
8310 (define_insn "tldm_hi22"
8311   [(set (match_operand:SI 0 "register_operand" "=r")
8312         (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
8313   "TARGET_TLS"
8314   "sethi\\t%%tldm_hi22(%&), %0")
8316 (define_insn "tldm_lo10"
8317   [(set (match_operand:SI 0 "register_operand" "=r")
8318         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8319                     (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
8320   "TARGET_TLS"
8321   "add\\t%1, %%tldm_lo10(%&), %0")
8323 (define_insn "tldm_add32"
8324   [(set (match_operand:SI 0 "register_operand" "=r")
8325         (plus:SI (match_operand:SI 1 "register_operand" "r")
8326                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
8327                             UNSPEC_TLSLDM)))]
8328   "TARGET_TLS && TARGET_ARCH32"
8329   "add\\t%1, %2, %0, %%tldm_add(%&)")
8331 (define_insn "tldm_add64"
8332   [(set (match_operand:DI 0 "register_operand" "=r")
8333         (plus:DI (match_operand:DI 1 "register_operand" "r")
8334                  (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
8335                             UNSPEC_TLSLDM)))]
8336   "TARGET_TLS && TARGET_ARCH64"
8337   "add\\t%1, %2, %0, %%tldm_add(%&)")
8339 (define_insn "tldm_call32"
8340   [(set (match_operand 0 "register_operand" "=r")
8341         (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
8342                                  UNSPEC_TLSLDM))
8343               (match_operand 2 "" "")))
8344    (clobber (reg:SI 15))]
8345   "TARGET_TLS && TARGET_ARCH32"
8346   "call\t%a1, %%tldm_call(%&)%#"
8347   [(set_attr "type" "call")])
8349 (define_insn "tldm_call64"
8350   [(set (match_operand 0 "register_operand" "=r")
8351         (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
8352                                  UNSPEC_TLSLDM))
8353               (match_operand 2 "" "")))
8354    (clobber (reg:DI 15))]
8355   "TARGET_TLS && TARGET_ARCH64"
8356   "call\t%a1, %%tldm_call(%&)%#"
8357   [(set_attr "type" "call")])
8359 (define_insn "tldo_hix22"
8360   [(set (match_operand:SI 0 "register_operand" "=r")
8361         (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
8362                             UNSPEC_TLSLDO)))]
8363   "TARGET_TLS"
8364   "sethi\\t%%tldo_hix22(%a1), %0")
8366 (define_insn "tldo_lox10"
8367   [(set (match_operand:SI 0 "register_operand" "=r")
8368         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8369                    (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
8370                               UNSPEC_TLSLDO)))]
8371   "TARGET_TLS"
8372   "xor\\t%1, %%tldo_lox10(%a2), %0")
8374 (define_insn "tldo_add32"
8375   [(set (match_operand:SI 0 "register_operand" "=r")
8376         (plus:SI (match_operand:SI 1 "register_operand" "r")
8377                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8378                              (match_operand 3 "tld_symbolic_operand" "")]
8379                             UNSPEC_TLSLDO)))]
8380   "TARGET_TLS && TARGET_ARCH32"
8381   "add\\t%1, %2, %0, %%tldo_add(%a3)")
8383 (define_insn "tldo_add64"
8384   [(set (match_operand:DI 0 "register_operand" "=r")
8385         (plus:DI (match_operand:DI 1 "register_operand" "r")
8386                  (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8387                              (match_operand 3 "tld_symbolic_operand" "")]
8388                             UNSPEC_TLSLDO)))]
8389   "TARGET_TLS && TARGET_ARCH64"
8390   "add\\t%1, %2, %0, %%tldo_add(%a3)")
8392 (define_insn "tie_hi22"
8393   [(set (match_operand:SI 0 "register_operand" "=r")
8394         (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
8395                             UNSPEC_TLSIE)))]
8396   "TARGET_TLS"
8397   "sethi\\t%%tie_hi22(%a1), %0")
8399 (define_insn "tie_lo10"
8400   [(set (match_operand:SI 0 "register_operand" "=r")
8401         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8402                    (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
8403                               UNSPEC_TLSIE)))]
8404   "TARGET_TLS"
8405   "add\\t%1, %%tie_lo10(%a2), %0")
8407 (define_insn "tie_ld32"
8408   [(set (match_operand:SI 0 "register_operand" "=r")
8409         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
8410                     (match_operand:SI 2 "register_operand" "r")
8411                     (match_operand 3 "tie_symbolic_operand" "")]
8412                    UNSPEC_TLSIE))]
8413   "TARGET_TLS && TARGET_ARCH32"
8414   "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
8415   [(set_attr "type" "load")])
8417 (define_insn "tie_ld64"
8418   [(set (match_operand:DI 0 "register_operand" "=r")
8419         (unspec:DI [(match_operand:DI 1 "register_operand" "r")
8420                     (match_operand:SI 2 "register_operand" "r")
8421                     (match_operand 3 "tie_symbolic_operand" "")]
8422                    UNSPEC_TLSIE))]
8423   "TARGET_TLS && TARGET_ARCH64"
8424   "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
8425   [(set_attr "type" "load")])
8427 (define_insn "tie_add32"
8428   [(set (match_operand:SI 0 "register_operand" "=r")
8429         (plus:SI (match_operand:SI 1 "register_operand" "r")
8430                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8431                              (match_operand 3 "tie_symbolic_operand" "")]
8432                             UNSPEC_TLSIE)))]
8433   "TARGET_SUN_TLS && TARGET_ARCH32"
8434   "add\\t%1, %2, %0, %%tie_add(%a3)")
8436 (define_insn "tie_add64"
8437   [(set (match_operand:DI 0 "register_operand" "=r")
8438         (plus:DI (match_operand:DI 1 "register_operand" "r")
8439                  (unspec:DI [(match_operand:DI 2 "register_operand" "r")
8440                              (match_operand 3 "tie_symbolic_operand" "")]
8441                             UNSPEC_TLSIE)))]
8442   "TARGET_SUN_TLS && TARGET_ARCH64"
8443   "add\\t%1, %2, %0, %%tie_add(%a3)")
8445 (define_insn "tle_hix22_sp32"
8446   [(set (match_operand:SI 0 "register_operand" "=r")
8447         (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
8448                             UNSPEC_TLSLE)))]
8449   "TARGET_TLS && TARGET_ARCH32"
8450   "sethi\\t%%tle_hix22(%a1), %0")
8452 (define_insn "tle_lox10_sp32"
8453   [(set (match_operand:SI 0 "register_operand" "=r")
8454         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8455                    (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
8456                               UNSPEC_TLSLE)))]
8457   "TARGET_TLS && TARGET_ARCH32"
8458   "xor\\t%1, %%tle_lox10(%a2), %0")
8460 (define_insn "tle_hix22_sp64"
8461   [(set (match_operand:DI 0 "register_operand" "=r")
8462         (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
8463                             UNSPEC_TLSLE)))]
8464   "TARGET_TLS && TARGET_ARCH64"
8465   "sethi\\t%%tle_hix22(%a1), %0")
8467 (define_insn "tle_lox10_sp64"
8468   [(set (match_operand:DI 0 "register_operand" "=r")
8469         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
8470                    (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
8471                               UNSPEC_TLSLE)))]
8472   "TARGET_TLS && TARGET_ARCH64"
8473   "xor\\t%1, %%tle_lox10(%a2), %0")
8475 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
8476 (define_insn "*tldo_ldub_sp32"
8477   [(set (match_operand:QI 0 "register_operand" "=r")
8478         (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8479                                      (match_operand 3 "tld_symbolic_operand" "")]
8480                                     UNSPEC_TLSLDO)
8481                          (match_operand:SI 1 "register_operand" "r"))))]
8482   "TARGET_TLS && TARGET_ARCH32"
8483   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8484   [(set_attr "type" "load")
8485    (set_attr "us3load_type" "3cycle")])
8487 (define_insn "*tldo_ldub1_sp32"
8488   [(set (match_operand:HI 0 "register_operand" "=r")
8489         (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8490                                                      (match_operand 3 "tld_symbolic_operand" "")]
8491                                                     UNSPEC_TLSLDO)
8492                                          (match_operand:SI 1 "register_operand" "r")))))]
8493   "TARGET_TLS && TARGET_ARCH32"
8494   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8495   [(set_attr "type" "load")
8496    (set_attr "us3load_type" "3cycle")])
8498 (define_insn "*tldo_ldub2_sp32"
8499   [(set (match_operand:SI 0 "register_operand" "=r")
8500         (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8501                                                      (match_operand 3 "tld_symbolic_operand" "")]
8502                                                     UNSPEC_TLSLDO)
8503                                          (match_operand:SI 1 "register_operand" "r")))))]
8504   "TARGET_TLS && TARGET_ARCH32"
8505   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8506   [(set_attr "type" "load")
8507    (set_attr "us3load_type" "3cycle")])
8509 (define_insn "*tldo_ldsb1_sp32"
8510   [(set (match_operand:HI 0 "register_operand" "=r")
8511         (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8512                                                      (match_operand 3 "tld_symbolic_operand" "")]
8513                                                     UNSPEC_TLSLDO)
8514                                          (match_operand:SI 1 "register_operand" "r")))))]
8515   "TARGET_TLS && TARGET_ARCH32"
8516   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8517   [(set_attr "type" "sload")
8518    (set_attr "us3load_type" "3cycle")])
8520 (define_insn "*tldo_ldsb2_sp32"
8521   [(set (match_operand:SI 0 "register_operand" "=r")
8522         (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8523                                                      (match_operand 3 "tld_symbolic_operand" "")]
8524                                                     UNSPEC_TLSLDO)
8525                                          (match_operand:SI 1 "register_operand" "r")))))]
8526   "TARGET_TLS && TARGET_ARCH32"
8527   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8528   [(set_attr "type" "sload")
8529    (set_attr "us3load_type" "3cycle")])
8531 (define_insn "*tldo_ldub_sp64"
8532   [(set (match_operand:QI 0 "register_operand" "=r")
8533         (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8534                                      (match_operand 3 "tld_symbolic_operand" "")]
8535                                     UNSPEC_TLSLDO)
8536                          (match_operand:DI 1 "register_operand" "r"))))]
8537   "TARGET_TLS && TARGET_ARCH64"
8538   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8539   [(set_attr "type" "load")
8540    (set_attr "us3load_type" "3cycle")])
8542 (define_insn "*tldo_ldub1_sp64"
8543   [(set (match_operand:HI 0 "register_operand" "=r")
8544         (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8545                                                      (match_operand 3 "tld_symbolic_operand" "")]
8546                                                     UNSPEC_TLSLDO)
8547                                          (match_operand:DI 1 "register_operand" "r")))))]
8548   "TARGET_TLS && TARGET_ARCH64"
8549   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8550   [(set_attr "type" "load")
8551    (set_attr "us3load_type" "3cycle")])
8553 (define_insn "*tldo_ldub2_sp64"
8554   [(set (match_operand:SI 0 "register_operand" "=r")
8555         (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8556                                                      (match_operand 3 "tld_symbolic_operand" "")]
8557                                                     UNSPEC_TLSLDO)
8558                                          (match_operand:DI 1 "register_operand" "r")))))]
8559   "TARGET_TLS && TARGET_ARCH64"
8560   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8561   [(set_attr "type" "load")
8562    (set_attr "us3load_type" "3cycle")])
8564 (define_insn "*tldo_ldub3_sp64"
8565   [(set (match_operand:DI 0 "register_operand" "=r")
8566         (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8567                                                      (match_operand 3 "tld_symbolic_operand" "")]
8568                                                     UNSPEC_TLSLDO)
8569                                          (match_operand:DI 1 "register_operand" "r")))))]
8570   "TARGET_TLS && TARGET_ARCH64"
8571   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8572   [(set_attr "type" "load")
8573    (set_attr "us3load_type" "3cycle")])
8575 (define_insn "*tldo_ldsb1_sp64"
8576   [(set (match_operand:HI 0 "register_operand" "=r")
8577         (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8578                                                      (match_operand 3 "tld_symbolic_operand" "")]
8579                                                     UNSPEC_TLSLDO)
8580                                          (match_operand:DI 1 "register_operand" "r")))))]
8581   "TARGET_TLS && TARGET_ARCH64"
8582   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8583   [(set_attr "type" "sload")
8584    (set_attr "us3load_type" "3cycle")])
8586 (define_insn "*tldo_ldsb2_sp64"
8587   [(set (match_operand:SI 0 "register_operand" "=r")
8588         (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8589                                                      (match_operand 3 "tld_symbolic_operand" "")]
8590                                                     UNSPEC_TLSLDO)
8591                                          (match_operand:DI 1 "register_operand" "r")))))]
8592   "TARGET_TLS && TARGET_ARCH64"
8593   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8594   [(set_attr "type" "sload")
8595    (set_attr "us3load_type" "3cycle")])
8597 (define_insn "*tldo_ldsb3_sp64"
8598   [(set (match_operand:DI 0 "register_operand" "=r")
8599         (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8600                                                      (match_operand 3 "tld_symbolic_operand" "")]
8601                                                     UNSPEC_TLSLDO)
8602                                          (match_operand:DI 1 "register_operand" "r")))))]
8603   "TARGET_TLS && TARGET_ARCH64"
8604   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8605   [(set_attr "type" "sload")
8606    (set_attr "us3load_type" "3cycle")])
8608 (define_insn "*tldo_lduh_sp32"
8609   [(set (match_operand:HI 0 "register_operand" "=r")
8610         (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8611                                      (match_operand 3 "tld_symbolic_operand" "")]
8612                                     UNSPEC_TLSLDO)
8613                          (match_operand:SI 1 "register_operand" "r"))))]
8614   "TARGET_TLS && TARGET_ARCH32"
8615   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8616   [(set_attr "type" "load")
8617    (set_attr "us3load_type" "3cycle")])
8619 (define_insn "*tldo_lduh1_sp32"
8620   [(set (match_operand:SI 0 "register_operand" "=r")
8621         (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8622                                                      (match_operand 3 "tld_symbolic_operand" "")]
8623                                                     UNSPEC_TLSLDO)
8624                                          (match_operand:SI 1 "register_operand" "r")))))]
8625   "TARGET_TLS && TARGET_ARCH32"
8626   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8627   [(set_attr "type" "load")
8628    (set_attr "us3load_type" "3cycle")])
8630 (define_insn "*tldo_ldsh1_sp32"
8631   [(set (match_operand:SI 0 "register_operand" "=r")
8632         (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8633                                                      (match_operand 3 "tld_symbolic_operand" "")]
8634                                                     UNSPEC_TLSLDO)
8635                                          (match_operand:SI 1 "register_operand" "r")))))]
8636   "TARGET_TLS && TARGET_ARCH32"
8637   "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8638   [(set_attr "type" "sload")
8639    (set_attr "us3load_type" "3cycle")])
8641 (define_insn "*tldo_lduh_sp64"
8642   [(set (match_operand:HI 0 "register_operand" "=r")
8643         (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8644                                      (match_operand 3 "tld_symbolic_operand" "")]
8645                                     UNSPEC_TLSLDO)
8646                          (match_operand:DI 1 "register_operand" "r"))))]
8647   "TARGET_TLS && TARGET_ARCH64"
8648   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8649   [(set_attr "type" "load")
8650    (set_attr "us3load_type" "3cycle")])
8652 (define_insn "*tldo_lduh1_sp64"
8653   [(set (match_operand:SI 0 "register_operand" "=r")
8654         (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8655                                                      (match_operand 3 "tld_symbolic_operand" "")]
8656                                                     UNSPEC_TLSLDO)
8657                                          (match_operand:DI 1 "register_operand" "r")))))]
8658   "TARGET_TLS && TARGET_ARCH64"
8659   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8660   [(set_attr "type" "load")
8661    (set_attr "us3load_type" "3cycle")])
8663 (define_insn "*tldo_lduh2_sp64"
8664   [(set (match_operand:DI 0 "register_operand" "=r")
8665         (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8666                                                      (match_operand 3 "tld_symbolic_operand" "")]
8667                                                     UNSPEC_TLSLDO)
8668                                          (match_operand:DI 1 "register_operand" "r")))))]
8669   "TARGET_TLS && TARGET_ARCH64"
8670   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8671   [(set_attr "type" "load")
8672    (set_attr "us3load_type" "3cycle")])
8674 (define_insn "*tldo_ldsh1_sp64"
8675   [(set (match_operand:SI 0 "register_operand" "=r")
8676         (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8677                                                      (match_operand 3 "tld_symbolic_operand" "")]
8678                                                     UNSPEC_TLSLDO)
8679                                          (match_operand:DI 1 "register_operand" "r")))))]
8680   "TARGET_TLS && TARGET_ARCH64"
8681   "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8682   [(set_attr "type" "sload")
8683    (set_attr "us3load_type" "3cycle")])
8685 (define_insn "*tldo_ldsh2_sp64"
8686   [(set (match_operand:DI 0 "register_operand" "=r")
8687         (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8688                                                      (match_operand 3 "tld_symbolic_operand" "")]
8689                                                     UNSPEC_TLSLDO)
8690                                          (match_operand:DI 1 "register_operand" "r")))))]
8691   "TARGET_TLS && TARGET_ARCH64"
8692   "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8693   [(set_attr "type" "sload")
8694    (set_attr "us3load_type" "3cycle")])
8696 (define_insn "*tldo_lduw_sp32"
8697   [(set (match_operand:SI 0 "register_operand" "=r")
8698         (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8699                                      (match_operand 3 "tld_symbolic_operand" "")]
8700                                     UNSPEC_TLSLDO)
8701                          (match_operand:SI 1 "register_operand" "r"))))]
8702   "TARGET_TLS && TARGET_ARCH32"
8703   "ld\t[%1 + %2], %0, %%tldo_add(%3)"
8704   [(set_attr "type" "load")])
8706 (define_insn "*tldo_lduw_sp64"
8707   [(set (match_operand:SI 0 "register_operand" "=r")
8708         (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8709                                      (match_operand 3 "tld_symbolic_operand" "")]
8710                                     UNSPEC_TLSLDO)
8711                          (match_operand:DI 1 "register_operand" "r"))))]
8712   "TARGET_TLS && TARGET_ARCH64"
8713   "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8714   [(set_attr "type" "load")])
8716 (define_insn "*tldo_lduw1_sp64"
8717   [(set (match_operand:DI 0 "register_operand" "=r")
8718         (zero_extend:DI (mem:SI (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   "TARGET_TLS && TARGET_ARCH64"
8723   "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8724   [(set_attr "type" "load")])
8726 (define_insn "*tldo_ldsw1_sp64"
8727   [(set (match_operand:DI 0 "register_operand" "=r")
8728         (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8729                                                      (match_operand 3 "tld_symbolic_operand" "")]
8730                                                     UNSPEC_TLSLDO)
8731                                          (match_operand:DI 1 "register_operand" "r")))))]
8732   "TARGET_TLS && TARGET_ARCH64"
8733   "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
8734   [(set_attr "type" "sload")
8735    (set_attr "us3load_type" "3cycle")])
8737 (define_insn "*tldo_ldx_sp64"
8738   [(set (match_operand:DI 0 "register_operand" "=r")
8739         (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8740                                      (match_operand 3 "tld_symbolic_operand" "")]
8741                                     UNSPEC_TLSLDO)
8742                          (match_operand:DI 1 "register_operand" "r"))))]
8743   "TARGET_TLS && TARGET_ARCH64"
8744   "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
8745   [(set_attr "type" "load")])
8747 (define_insn "*tldo_stb_sp32"
8748   [(set (mem:QI (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:QI 0 "register_operand" "=r"))]
8753   "TARGET_TLS && TARGET_ARCH32"
8754   "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8755   [(set_attr "type" "store")])
8757 (define_insn "*tldo_stb_sp64"
8758   [(set (mem:QI (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:QI 0 "register_operand" "=r"))]
8763   "TARGET_TLS && TARGET_ARCH64"
8764   "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8765   [(set_attr "type" "store")])
8767 (define_insn "*tldo_sth_sp32"
8768   [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8769                                      (match_operand 3 "tld_symbolic_operand" "")]
8770                                     UNSPEC_TLSLDO)
8771                          (match_operand:SI 1 "register_operand" "r")))
8772         (match_operand:HI 0 "register_operand" "=r"))]
8773   "TARGET_TLS && TARGET_ARCH32"
8774   "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8775   [(set_attr "type" "store")])
8777 (define_insn "*tldo_sth_sp64"
8778   [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8779                                      (match_operand 3 "tld_symbolic_operand" "")]
8780                                     UNSPEC_TLSLDO)
8781                          (match_operand:DI 1 "register_operand" "r")))
8782         (match_operand:HI 0 "register_operand" "=r"))]
8783   "TARGET_TLS && TARGET_ARCH64"
8784   "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8785   [(set_attr "type" "store")])
8787 (define_insn "*tldo_stw_sp32"
8788   [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8789                                      (match_operand 3 "tld_symbolic_operand" "")]
8790                                     UNSPEC_TLSLDO)
8791                          (match_operand:SI 1 "register_operand" "r")))
8792         (match_operand:SI 0 "register_operand" "=r"))]
8793   "TARGET_TLS && TARGET_ARCH32"
8794   "st\t%0, [%1 + %2], %%tldo_add(%3)"
8795   [(set_attr "type" "store")])
8797 (define_insn "*tldo_stw_sp64"
8798   [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8799                                      (match_operand 3 "tld_symbolic_operand" "")]
8800                                     UNSPEC_TLSLDO)
8801                          (match_operand:DI 1 "register_operand" "r")))
8802         (match_operand:SI 0 "register_operand" "=r"))]
8803   "TARGET_TLS && TARGET_ARCH64"
8804   "stw\t%0, [%1 + %2], %%tldo_add(%3)"
8805   [(set_attr "type" "store")])
8807 (define_insn "*tldo_stx_sp64"
8808   [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8809                                      (match_operand 3 "tld_symbolic_operand" "")]
8810                                     UNSPEC_TLSLDO)
8811                          (match_operand:DI 1 "register_operand" "r")))
8812         (match_operand:DI 0 "register_operand" "=r"))]
8813   "TARGET_TLS && TARGET_ARCH64"
8814   "stx\t%0, [%1 + %2], %%tldo_add(%3)"
8815   [(set_attr "type" "store")])