Merge from mainline (168000:168310).
[official-gcc/graphite-test-results.git] / gcc / config / sparc / sparc.md
blob853bd2fbdcc6eb0e46c1e2f0dbb9aff23dd4e7e3
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, 2005, 2006, 2007, 2008, 2009, 2010
4 ;;  Free Software Foundation, Inc.
5 ;;  Contributed by Michael Tiemann (tiemann@cygnus.com)
6 ;;  64-bit SPARC-V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
7 ;;  at Cygnus Support.
9 ;; This file is part of GCC.
11 ;; GCC is free software; you can redistribute it and/or modify
12 ;; it under the terms of the GNU General Public License as published by
13 ;; the Free Software Foundation; either version 3, or (at your option)
14 ;; any later version.
16 ;; GCC is distributed in the hope that it will be useful,
17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 ;; GNU General Public License for more details.
21 ;; You should have received a copy of the GNU General Public License
22 ;; along with GCC; see the file COPYING3.  If not see
23 ;; <http://www.gnu.org/licenses/>.
25 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
27 (define_constants
28   [(UNSPEC_MOVE_PIC             0)
29    (UNSPEC_UPDATE_RETURN        1)
30    (UNSPEC_LOAD_PCREL_SYM       2)
31    (UNSPEC_MOVE_PIC_LABEL       5)
32    (UNSPEC_SETH44               6)
33    (UNSPEC_SETM44               7)
34    (UNSPEC_SETHH                9)
35    (UNSPEC_SETLM                10)
36    (UNSPEC_EMB_HISUM            11)
37    (UNSPEC_EMB_TEXTUHI          13)
38    (UNSPEC_EMB_TEXTHI           14)
39    (UNSPEC_EMB_TEXTULO          15)
40    (UNSPEC_EMB_SETHM            18)
41    (UNSPEC_MOVE_GOTDATA         19)
43    (UNSPEC_MEMBAR               20)
45    (UNSPEC_TLSGD                30)
46    (UNSPEC_TLSLDM               31)
47    (UNSPEC_TLSLDO               32)
48    (UNSPEC_TLSIE                33)
49    (UNSPEC_TLSLE                34)
50    (UNSPEC_TLSLD_BASE           35)
52    (UNSPEC_FPACK16              40)
53    (UNSPEC_FPACK32              41)
54    (UNSPEC_FPACKFIX             42)
55    (UNSPEC_FEXPAND              43)
56    (UNSPEC_FPMERGE              44)
57    (UNSPEC_MUL16AL              45)
58    (UNSPEC_MUL8UL               46)
59    (UNSPEC_MULDUL               47)
60    (UNSPEC_ALIGNDATA            48)
61    (UNSPEC_ALIGNADDR            49)
62    (UNSPEC_PDIST                50)
64    (UNSPEC_SP_SET               60)
65    (UNSPEC_SP_TEST              61)
66   ])
68 (define_constants
69   [(UNSPECV_BLOCKAGE            0)
70    (UNSPECV_FLUSHW              1)
71    (UNSPECV_GOTO                2)
72    (UNSPECV_FLUSH               4)
73    (UNSPECV_SETJMP              5)
74    (UNSPECV_SAVEW               6)
75    (UNSPECV_CAS                 8)
76    (UNSPECV_SWAP                9)
77    (UNSPECV_LDSTUB              10)
78    (UNSPECV_PROBE_STACK_RANGE   11)
79   ])
82 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
83 (define_mode_iterator I [QI HI SI DI])
84 (define_mode_iterator F [SF DF TF])
86 ;; We don't define V1SI because SI should work just fine.
87 (define_mode_iterator V32 [SF V2HI V4QI])
88 (define_mode_iterator V32I [SI V2HI V4QI])
90 (define_mode_iterator V64 [DF V2SI V4HI V8QI])
91 (define_mode_iterator V64I [DI V2SI V4HI V8QI])
93 ;; The upper 32 fp regs on the v9 can't hold SFmode values.  To deal with this
94 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip.  The name
95 ;; is a bit of a misnomer as it covers all 64 fp regs.  The corresponding
96 ;; constraint letter is 'e'.  To avoid any confusion, 'e' is used instead of
97 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
100 ;; Attribute for cpu type.
101 ;; These must match the values for enum processor_type in sparc.h.
102 (define_attr "cpu"
103   "v7,
104    cypress,
105    v8,
106    supersparc,
107    hypersparc,
108    leon,
109    sparclite,
110    f930,
111    f934,
112    sparclite86x,
113    sparclet,
114    tsc701,
115    v9,
116    ultrasparc,
117    ultrasparc3,
118    niagara,
119    niagara2"
120   (const (symbol_ref "sparc_cpu_attr")))
122 ;; Attribute for the instruction set.
123 ;; At present we only need to distinguish v9/!v9, but for clarity we
124 ;; test TARGET_V8 too.
125 (define_attr "isa" "v7,v8,v9,sparclet"
126  (const
127   (cond [(symbol_ref "TARGET_V9") (const_string "v9")
128          (symbol_ref "TARGET_V8") (const_string "v8")
129          (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
130         (const_string "v7"))))
132 ;; Insn type.
133 (define_attr "type"
134   "ialu,compare,shift,
135    load,sload,store,
136    uncond_branch,branch,call,sibcall,call_no_delay_slot,return,
137    imul,idiv,
138    fpload,fpstore,
139    fp,fpmove,
140    fpcmove,fpcrmove,
141    fpcmp,
142    fpmul,fpdivs,fpdivd,
143    fpsqrts,fpsqrtd,
144    fga,fgm_pack,fgm_mul,fgm_pdist,fgm_cmp,
145    cmove,
146    ialuX,
147    multi,savew,flushw,iflush,trap"
148   (const_string "ialu"))
150 ;; True if branch/call has empty delay slot and will emit a nop in it
151 (define_attr "empty_delay_slot" "false,true"
152   (symbol_ref "(empty_delay_slot (insn)
153                 ? EMPTY_DELAY_SLOT_TRUE : EMPTY_DELAY_SLOT_FALSE)"))
155 (define_attr "branch_type" "none,icc,fcc,reg"
156   (const_string "none"))
158 (define_attr "pic" "false,true"
159   (symbol_ref "(flag_pic != 0 ? PIC_TRUE : PIC_FALSE)"))
161 (define_attr "calls_alloca" "false,true"
162   (symbol_ref "(cfun->calls_alloca != 0
163                 ? CALLS_ALLOCA_TRUE : CALLS_ALLOCA_FALSE)"))
165 (define_attr "calls_eh_return" "false,true"
166    (symbol_ref "(crtl->calls_eh_return != 0
167                  ? CALLS_EH_RETURN_TRUE : CALLS_EH_RETURN_FALSE)"))
168    
169 (define_attr "leaf_function" "false,true"
170   (symbol_ref "(current_function_uses_only_leaf_regs != 0
171                 ? LEAF_FUNCTION_TRUE : LEAF_FUNCTION_FALSE)"))
173 (define_attr "delayed_branch" "false,true"
174   (symbol_ref "(flag_delayed_branch != 0
175                 ? DELAYED_BRANCH_TRUE : DELAYED_BRANCH_FALSE)"))
177 ;; Length (in # of insns).
178 ;; Beware that setting a length greater or equal to 3 for conditional branches
179 ;; has a side-effect (see output_cbranch and output_v9branch).
180 (define_attr "length" ""
181   (cond [(eq_attr "type" "uncond_branch,call")
182            (if_then_else (eq_attr "empty_delay_slot" "true")
183              (const_int 2)
184              (const_int 1))
185          (eq_attr "type" "sibcall")
186            (if_then_else (eq_attr "leaf_function" "true")
187              (if_then_else (eq_attr "empty_delay_slot" "true")
188                (const_int 3)
189                (const_int 2))
190              (if_then_else (eq_attr "empty_delay_slot" "true")
191                (const_int 2)
192                (const_int 1)))
193          (eq_attr "branch_type" "icc")
194            (if_then_else (match_operand 0 "noov_compare64_operator" "")
195              (if_then_else (lt (pc) (match_dup 1))
196                (if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000))
197                  (if_then_else (eq_attr "empty_delay_slot" "true")
198                    (const_int 2)
199                    (const_int 1))
200                  (if_then_else (eq_attr "empty_delay_slot" "true")
201                    (const_int 4)
202                    (const_int 3)))
203                (if_then_else (lt (minus (pc) (match_dup 1)) (const_int 260000))
204                  (if_then_else (eq_attr "empty_delay_slot" "true")
205                    (const_int 2)
206                    (const_int 1))
207                  (if_then_else (eq_attr "empty_delay_slot" "true")
208                    (const_int 4)
209                    (const_int 3))))
210              (if_then_else (eq_attr "empty_delay_slot" "true")
211                (const_int 2)
212                (const_int 1)))
213          (eq_attr "branch_type" "fcc")
214            (if_then_else (match_operand 0 "fcc0_register_operand" "")
215              (if_then_else (eq_attr "empty_delay_slot" "true")
216                (if_then_else (eq (symbol_ref "TARGET_V9") (const_int 0))
217                  (const_int 3)
218                  (const_int 2))
219                (if_then_else (eq (symbol_ref "TARGET_V9") (const_int 0))
220                  (const_int 2)
221                  (const_int 1)))
222              (if_then_else (lt (pc) (match_dup 2))
223                (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000))
224                  (if_then_else (eq_attr "empty_delay_slot" "true")
225                    (const_int 2)
226                    (const_int 1))
227                  (if_then_else (eq_attr "empty_delay_slot" "true")
228                    (const_int 4)
229                    (const_int 3)))
230                (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000))
231                  (if_then_else (eq_attr "empty_delay_slot" "true")
232                    (const_int 2)
233                    (const_int 1))
234                  (if_then_else (eq_attr "empty_delay_slot" "true")
235                    (const_int 4)
236                    (const_int 3)))))
237          (eq_attr "branch_type" "reg")
238            (if_then_else (lt (pc) (match_dup 2))
239              (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000))
240                (if_then_else (eq_attr "empty_delay_slot" "true")
241                  (const_int 2)
242                  (const_int 1))
243                (if_then_else (eq_attr "empty_delay_slot" "true")
244                  (const_int 4)
245                  (const_int 3)))
246              (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000))
247                (if_then_else (eq_attr "empty_delay_slot" "true")
248                  (const_int 2)
249                  (const_int 1))
250                (if_then_else (eq_attr "empty_delay_slot" "true")
251                  (const_int 4)
252                  (const_int 3))))
253          ] (const_int 1)))
255 ;; FP precision.
256 (define_attr "fptype" "single,double"
257   (const_string "single"))
259 ;; UltraSPARC-III integer load type.
260 (define_attr "us3load_type" "2cycle,3cycle"
261   (const_string "2cycle"))
263 (define_asm_attributes
264   [(set_attr "length" "2")
265    (set_attr "type" "multi")])
267 ;; Attributes for instruction and branch scheduling
268 (define_attr "tls_call_delay" "false,true"
269   (symbol_ref "(tls_call_delay (insn)
270                 ? TLS_CALL_DELAY_TRUE : TLS_CALL_DELAY_FALSE)"))
272 (define_attr "in_call_delay" "false,true"
273   (cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
274                 (const_string "false")
275          (eq_attr "type" "load,fpload,store,fpstore")
276                 (if_then_else (eq_attr "length" "1")
277                               (const_string "true")
278                               (const_string "false"))]
279         (if_then_else (and (eq_attr "length" "1")
280                            (eq_attr "tls_call_delay" "true"))
281                       (const_string "true")
282                       (const_string "false"))))
284 (define_attr "eligible_for_sibcall_delay" "false,true"
285   (symbol_ref "(eligible_for_sibcall_delay (insn)
286                 ? ELIGIBLE_FOR_SIBCALL_DELAY_TRUE
287                 : ELIGIBLE_FOR_SIBCALL_DELAY_FALSE)"))
289 (define_attr "eligible_for_return_delay" "false,true"
290   (symbol_ref "(eligible_for_return_delay (insn)
291                 ? ELIGIBLE_FOR_RETURN_DELAY_TRUE
292                 : ELIGIBLE_FOR_RETURN_DELAY_FALSE)"))
294 ;; ??? !v9: Should implement the notion of predelay slots for floating-point
295 ;; branches.  This would allow us to remove the nop always inserted before
296 ;; a floating point branch.
298 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
299 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
300 ;; This is because doing so will add several pipeline stalls to the path
301 ;; that the load/store did not come from.  Unfortunately, there is no way
302 ;; to prevent fill_eager_delay_slots from using load/store without completely
303 ;; disabling them.  For the SPEC benchmark set, this is a serious lose,
304 ;; because it prevents us from moving back the final store of inner loops.
306 (define_attr "in_branch_delay" "false,true"
307   (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
308                      (eq_attr "length" "1"))
309                 (const_string "true")
310                 (const_string "false")))
312 (define_attr "in_uncond_branch_delay" "false,true"
313   (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
314                      (eq_attr "length" "1"))
315                 (const_string "true")
316                 (const_string "false")))
318 (define_attr "in_annul_branch_delay" "false,true"
319   (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
320                      (eq_attr "length" "1"))
321                 (const_string "true")
322                 (const_string "false")))
324 (define_delay (eq_attr "type" "call")
325   [(eq_attr "in_call_delay" "true") (nil) (nil)])
327 (define_delay (eq_attr "type" "sibcall")
328   [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
330 (define_delay (eq_attr "type" "branch")
331   [(eq_attr "in_branch_delay" "true")
332    (nil) (eq_attr "in_annul_branch_delay" "true")])
334 (define_delay (eq_attr "type" "uncond_branch")
335   [(eq_attr "in_uncond_branch_delay" "true")
336    (nil) (nil)])
338 (define_delay (eq_attr "type" "return")
339   [(eq_attr "eligible_for_return_delay" "true") (nil) (nil)])
342 ;; Include SPARC DFA schedulers
344 (include "cypress.md")
345 (include "supersparc.md")
346 (include "hypersparc.md")
347 (include "leon.md")
348 (include "sparclet.md")
349 (include "ultra1_2.md")
350 (include "ultra3.md")
351 (include "niagara.md")
352 (include "niagara2.md")
355 ;; Operand and operator predicates and constraints
357 (include "predicates.md")
358 (include "constraints.md")
361 ;; Compare instructions.
363 ;; These are just the DEFINE_INSNs to match the patterns and the
364 ;; DEFINE_SPLITs for some of the scc insns that actually require
365 ;; more than one machine instruction.  DEFINE_EXPANDs are further down.
367 ;; The compare DEFINE_INSNs.
369 (define_insn "*cmpsi_insn"
370   [(set (reg:CC 100)
371         (compare:CC (match_operand:SI 0 "register_operand" "r")
372                     (match_operand:SI 1 "arith_operand" "rI")))]
373   ""
374   "cmp\t%0, %1"
375   [(set_attr "type" "compare")])
377 (define_insn "*cmpdi_sp64"
378   [(set (reg:CCX 100)
379         (compare:CCX (match_operand:DI 0 "register_operand" "r")
380                      (match_operand:DI 1 "arith_operand" "rI")))]
381   "TARGET_ARCH64"
382   "cmp\t%0, %1"
383   [(set_attr "type" "compare")])
385 (define_insn "*cmpsf_fpe"
386   [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
387         (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
388                        (match_operand:SF 2 "register_operand" "f")))]
389   "TARGET_FPU"
391   if (TARGET_V9)
392     return "fcmpes\t%0, %1, %2";
393   return "fcmpes\t%1, %2";
395   [(set_attr "type" "fpcmp")])
397 (define_insn "*cmpdf_fpe"
398   [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
399         (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
400                        (match_operand:DF 2 "register_operand" "e")))]
401   "TARGET_FPU"
403   if (TARGET_V9)
404     return "fcmped\t%0, %1, %2";
405   return "fcmped\t%1, %2";
407   [(set_attr "type" "fpcmp")
408    (set_attr "fptype" "double")])
410 (define_insn "*cmptf_fpe"
411   [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
412         (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
413                        (match_operand:TF 2 "register_operand" "e")))]
414   "TARGET_FPU && TARGET_HARD_QUAD"
416   if (TARGET_V9)
417     return "fcmpeq\t%0, %1, %2";
418   return "fcmpeq\t%1, %2";
420   [(set_attr "type" "fpcmp")])
422 (define_insn "*cmpsf_fp"
423   [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
424         (compare:CCFP (match_operand:SF 1 "register_operand" "f")
425                       (match_operand:SF 2 "register_operand" "f")))]
426   "TARGET_FPU"
428   if (TARGET_V9)
429     return "fcmps\t%0, %1, %2";
430   return "fcmps\t%1, %2";
432   [(set_attr "type" "fpcmp")])
434 (define_insn "*cmpdf_fp"
435   [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
436         (compare:CCFP (match_operand:DF 1 "register_operand" "e")
437                       (match_operand:DF 2 "register_operand" "e")))]
438   "TARGET_FPU"
440   if (TARGET_V9)
441     return "fcmpd\t%0, %1, %2";
442   return "fcmpd\t%1, %2";
444   [(set_attr "type" "fpcmp")
445    (set_attr "fptype" "double")])
447 (define_insn "*cmptf_fp"
448   [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
449         (compare:CCFP (match_operand:TF 1 "register_operand" "e")
450                       (match_operand:TF 2 "register_operand" "e")))]
451   "TARGET_FPU && TARGET_HARD_QUAD"
453   if (TARGET_V9)
454     return "fcmpq\t%0, %1, %2";
455   return "fcmpq\t%1, %2";
457   [(set_attr "type" "fpcmp")])
459 ;; Next come the scc insns.
461 (define_expand "cstoresi4"
462   [(use (match_operator 1 "comparison_operator"
463          [(match_operand:SI 2 "compare_operand" "")
464           (match_operand:SI 3 "arith_operand" "")]))
465    (clobber (match_operand:SI 0 "register_operand"))]
466   ""
468   if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
469     operands[2] = force_reg (SImode, operands[2]);
470   if (emit_scc_insn (operands)) DONE; else FAIL;
473 (define_expand "cstoredi4"
474   [(use (match_operator 1 "comparison_operator"
475          [(match_operand:DI 2 "compare_operand" "")
476           (match_operand:DI 3 "arith_operand" "")]))
477    (clobber (match_operand:SI 0 "register_operand"))]
478   "TARGET_ARCH64"
480   if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
481     operands[2] = force_reg (DImode, operands[2]);
482   if (emit_scc_insn (operands)) DONE; else FAIL;
485 (define_expand "cstore<F:mode>4"
486   [(use (match_operator 1 "comparison_operator"
487          [(match_operand:F 2 "register_operand" "")
488           (match_operand:F 3 "register_operand" "")]))
489    (clobber (match_operand:SI 0 "register_operand"))]
490   "TARGET_FPU"
491   { if (emit_scc_insn (operands)) DONE; else FAIL; })
495 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
496 ;; generate addcc/subcc instructions.
498 (define_expand "seqsi_special"
499   [(set (match_dup 3)
500         (xor:SI (match_operand:SI 1 "register_operand" "")
501                 (match_operand:SI 2 "register_operand" "")))
502    (parallel [(set (match_operand:SI 0 "register_operand" "")
503                    (eq:SI (match_dup 3) (const_int 0)))
504               (clobber (reg:CC 100))])]
505   ""
506   { operands[3] = gen_reg_rtx (SImode); })
508 (define_expand "seqdi_special"
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 "snesi_special"
518   [(set (match_dup 3)
519         (xor:SI (match_operand:SI 1 "register_operand" "")
520                 (match_operand:SI 2 "register_operand" "")))
521    (parallel [(set (match_operand:SI 0 "register_operand" "")
522                    (ne:SI (match_dup 3) (const_int 0)))
523               (clobber (reg:CC 100))])]
524   ""
525   { operands[3] = gen_reg_rtx (SImode); })
527 (define_expand "snedi_special"
528   [(set (match_dup 3)
529         (xor:DI (match_operand:DI 1 "register_operand" "")
530                 (match_operand:DI 2 "register_operand" "")))
531    (set (match_operand:SI 0 "register_operand" "")
532         (ne:SI (match_dup 3) (const_int 0)))]
533   "TARGET_ARCH64"
534   { operands[3] = gen_reg_rtx (DImode); })
537 ;; Now the DEFINE_INSNs for the scc cases.
539 ;; The SEQ and SNE patterns are special because they can be done
540 ;; without any branching and do not involve a COMPARE.  We want
541 ;; them to always use the splits below so the results can be
542 ;; scheduled.
544 (define_insn_and_split "*snesi_zero"
545   [(set (match_operand:SI 0 "register_operand" "=r")
546         (ne:SI (match_operand:SI 1 "register_operand" "r")
547                (const_int 0)))
548    (clobber (reg:CC 100))]
549   ""
550   "#"
551   ""
552   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
553                                            (const_int 0)))
554    (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))]
555   ""
556   [(set_attr "length" "2")])
558 (define_insn_and_split "*neg_snesi_zero"
559   [(set (match_operand:SI 0 "register_operand" "=r")
560         (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
561                        (const_int 0))))
562    (clobber (reg:CC 100))]
563   ""
564   "#"
565   ""
566   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
567                                            (const_int 0)))
568    (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
569   ""
570   [(set_attr "length" "2")])
572 (define_insn_and_split "*snesi_zero_extend"
573   [(set (match_operand:DI 0 "register_operand" "=r")
574         (ne:DI (match_operand:SI 1 "register_operand" "r")
575                (const_int 0)))
576    (clobber (reg:CC 100))]
577   "TARGET_ARCH64"
578   "#"
579   "&& 1"
580   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
581                                                      (match_dup 1))
582                                            (const_int 0)))
583    (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
584                                                         (const_int 0))
585                                                (ltu:SI (reg:CC_NOOV 100)
586                                                        (const_int 0)))))]
587   ""
588   [(set_attr "length" "2")])
590 (define_insn_and_split "*snedi_zero"
591   [(set (match_operand:DI 0 "register_operand" "=&r")
592         (ne:DI (match_operand:DI 1 "register_operand" "r")
593                (const_int 0)))]
594   "TARGET_ARCH64"
595   "#"
596   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
597   [(set (match_dup 0) (const_int 0))
598    (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
599                                               (const_int 0))
600                                        (const_int 1)
601                                        (match_dup 0)))]
602   ""
603   [(set_attr "length" "2")])
605 (define_insn_and_split "*neg_snedi_zero"
606   [(set (match_operand:DI 0 "register_operand" "=&r")
607         (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
608                        (const_int 0))))]
609   "TARGET_ARCH64"
610   "#"
611   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
612   [(set (match_dup 0) (const_int 0))
613    (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
614                                               (const_int 0))
615                                        (const_int -1)
616                                        (match_dup 0)))]
617   ""
618   [(set_attr "length" "2")])
620 (define_insn_and_split "*snedi_zero_trunc"
621   [(set (match_operand:SI 0 "register_operand" "=&r")
622         (ne:SI (match_operand:DI 1 "register_operand" "r")
623                (const_int 0)))]
624   "TARGET_ARCH64"
625   "#"
626   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
627   [(set (match_dup 0) (const_int 0))
628    (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
629                                               (const_int 0))
630                                        (const_int 1)
631                                        (match_dup 0)))]
632   ""
633   [(set_attr "length" "2")])
635 (define_insn_and_split "*seqsi_zero"
636   [(set (match_operand:SI 0 "register_operand" "=r")
637         (eq:SI (match_operand:SI 1 "register_operand" "r")
638                (const_int 0)))
639    (clobber (reg:CC 100))]
640   ""
641   "#"
642   ""
643   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
644                                            (const_int 0)))
645    (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))]
646   ""
647   [(set_attr "length" "2")])
649 (define_insn_and_split "*neg_seqsi_zero"
650   [(set (match_operand:SI 0 "register_operand" "=r")
651         (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
652                        (const_int 0))))
653    (clobber (reg:CC 100))]
654   ""
655   "#"
656   ""
657   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
658                                            (const_int 0)))
659    (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
660   ""
661   [(set_attr "length" "2")])
663 (define_insn_and_split "*seqsi_zero_extend"
664   [(set (match_operand:DI 0 "register_operand" "=r")
665         (eq:DI (match_operand:SI 1 "register_operand" "r")
666                (const_int 0)))
667    (clobber (reg:CC 100))]
668   "TARGET_ARCH64"
669   "#"
670   "&& 1"
671   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
672                                                      (match_dup 1))
673                                            (const_int 0)))
674    (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
675                                                           (const_int -1))
676                                                 (ltu:SI (reg:CC_NOOV 100)
677                                                         (const_int 0)))))]
678   ""
679   [(set_attr "length" "2")])
681 (define_insn_and_split "*seqdi_zero"
682   [(set (match_operand:DI 0 "register_operand" "=&r")
683         (eq:DI (match_operand:DI 1 "register_operand" "r")
684                (const_int 0)))]
685   "TARGET_ARCH64"
686   "#"
687   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
688   [(set (match_dup 0) (const_int 0))
689    (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
690                                               (const_int 0))
691                                        (const_int 1)
692                                        (match_dup 0)))]
693   ""
694   [(set_attr "length" "2")])
696 (define_insn_and_split "*neg_seqdi_zero"
697   [(set (match_operand:DI 0 "register_operand" "=&r")
698         (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
699                        (const_int 0))))]
700   "TARGET_ARCH64"
701   "#"
702   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
703   [(set (match_dup 0) (const_int 0))
704    (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
705                                               (const_int 0))
706                                        (const_int -1)
707                                        (match_dup 0)))]
708   ""
709   [(set_attr "length" "2")]) 
711 (define_insn_and_split "*seqdi_zero_trunc"
712   [(set (match_operand:SI 0 "register_operand" "=&r")
713         (eq:SI (match_operand:DI 1 "register_operand" "r")
714                (const_int 0)))]
715   "TARGET_ARCH64"
716   "#"
717   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
718   [(set (match_dup 0) (const_int 0))
719    (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
720                                               (const_int 0))
721                                        (const_int 1)
722                                        (match_dup 0)))]
723   ""
724   [(set_attr "length" "2")])
726 ;; We can also do (x + (i == 0)) and related, so put them in.
727 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
728 ;; versions for v9.
730 (define_insn_and_split "*x_plus_i_ne_0"
731   [(set (match_operand:SI 0 "register_operand" "=r")
732         (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
733                         (const_int 0))
734                  (match_operand:SI 2 "register_operand" "r")))
735    (clobber (reg:CC 100))]
736   ""
737   "#"
738   ""
739   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
740                                            (const_int 0)))
741    (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
742                                (match_dup 2)))]
743   ""
744   [(set_attr "length" "2")])
746 (define_insn_and_split "*x_minus_i_ne_0"
747   [(set (match_operand:SI 0 "register_operand" "=r")
748         (minus:SI (match_operand:SI 2 "register_operand" "r")
749                   (ne:SI (match_operand:SI 1 "register_operand" "r")
750                          (const_int 0))))
751    (clobber (reg:CC 100))]
752   ""
753   "#"
754   ""
755   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
756                                            (const_int 0)))
757    (set (match_dup 0) (minus:SI (match_dup 2)
758                                 (ltu:SI (reg:CC 100) (const_int 0))))]
759   ""
760   [(set_attr "length" "2")])
762 (define_insn_and_split "*x_plus_i_eq_0"
763   [(set (match_operand:SI 0 "register_operand" "=r")
764         (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
765                         (const_int 0))
766                  (match_operand:SI 2 "register_operand" "r")))
767    (clobber (reg:CC 100))]
768   ""
769   "#"
770   ""
771   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
772                                            (const_int 0)))
773    (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0))
774                                (match_dup 2)))]
775   ""
776   [(set_attr "length" "2")])
778 (define_insn_and_split "*x_minus_i_eq_0"
779   [(set (match_operand:SI 0 "register_operand" "=r")
780         (minus:SI (match_operand:SI 2 "register_operand" "r")
781                   (eq:SI (match_operand:SI 1 "register_operand" "r")
782                          (const_int 0))))
783    (clobber (reg:CC 100))]
784   ""
785   "#"
786   ""
787   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
788                                            (const_int 0)))
789    (set (match_dup 0) (minus:SI (match_dup 2)
790                                 (geu:SI (reg:CC 100) (const_int 0))))]
791   ""
792   [(set_attr "length" "2")])
794 ;; We can also do GEU and LTU directly, but these operate after a compare.
795 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
796 ;; versions for v9.
798 (define_insn "*sltu_insn"
799   [(set (match_operand:SI 0 "register_operand" "=r")
800         (ltu:SI (reg:CC 100) (const_int 0)))]
801   ""
802   "addx\t%%g0, 0, %0"
803   [(set_attr "type" "ialuX")])
805 (define_insn "*neg_sltu_insn"
806   [(set (match_operand:SI 0 "register_operand" "=r")
807         (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
808   ""
809   "subx\t%%g0, 0, %0"
810   [(set_attr "type" "ialuX")])
812 ;; ??? Combine should canonicalize these next two to the same pattern.
813 (define_insn "*neg_sltu_minus_x"
814   [(set (match_operand:SI 0 "register_operand" "=r")
815         (minus:SI (neg:SI (ltu:SI (reg:CC 100) (const_int 0)))
816                   (match_operand:SI 1 "arith_operand" "rI")))]
817   ""
818   "subx\t%%g0, %1, %0"
819   [(set_attr "type" "ialuX")])
821 (define_insn "*neg_sltu_plus_x"
822   [(set (match_operand:SI 0 "register_operand" "=r")
823         (neg:SI (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
824                          (match_operand:SI 1 "arith_operand" "rI"))))]
825   ""
826   "subx\t%%g0, %1, %0"
827   [(set_attr "type" "ialuX")])
829 (define_insn "*sgeu_insn"
830   [(set (match_operand:SI 0 "register_operand" "=r")
831         (geu:SI (reg:CC 100) (const_int 0)))]
832   ""
833   "subx\t%%g0, -1, %0"
834   [(set_attr "type" "ialuX")])
836 (define_insn "*neg_sgeu_insn"
837   [(set (match_operand:SI 0 "register_operand" "=r")
838         (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
839   ""
840   "addx\t%%g0, -1, %0"
841   [(set_attr "type" "ialuX")])
843 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
844 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
845 ;; versions for v9.
847 (define_insn "*sltu_plus_x"
848   [(set (match_operand:SI 0 "register_operand" "=r")
849         (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
850                  (match_operand:SI 1 "arith_operand" "rI")))]
851   ""
852   "addx\t%%g0, %1, %0"
853   [(set_attr "type" "ialuX")])
855 (define_insn "*sltu_plus_x_plus_y"
856   [(set (match_operand:SI 0 "register_operand" "=r")
857         (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
858                  (plus:SI (match_operand:SI 1 "arith_operand" "%r")
859                           (match_operand:SI 2 "arith_operand" "rI"))))]
860   ""
861   "addx\t%1, %2, %0"
862   [(set_attr "type" "ialuX")])
864 (define_insn "*x_minus_sltu"
865   [(set (match_operand:SI 0 "register_operand" "=r")
866         (minus:SI (match_operand:SI 1 "register_operand" "r")
867                   (ltu:SI (reg:CC 100) (const_int 0))))]
868   ""
869   "subx\t%1, 0, %0"
870   [(set_attr "type" "ialuX")])
872 ;; ??? Combine should canonicalize these next two to the same pattern.
873 (define_insn "*x_minus_y_minus_sltu"
874   [(set (match_operand:SI 0 "register_operand" "=r")
875         (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
876                             (match_operand:SI 2 "arith_operand" "rI"))
877                   (ltu:SI (reg:CC 100) (const_int 0))))]
878   ""
879   "subx\t%r1, %2, %0"
880   [(set_attr "type" "ialuX")])
882 (define_insn "*x_minus_sltu_plus_y"
883   [(set (match_operand:SI 0 "register_operand" "=r")
884         (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
885                   (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
886                            (match_operand:SI 2 "arith_operand" "rI"))))]
887   ""
888   "subx\t%r1, %2, %0"
889   [(set_attr "type" "ialuX")])
891 (define_insn "*sgeu_plus_x"
892   [(set (match_operand:SI 0 "register_operand" "=r")
893         (plus:SI (geu:SI (reg:CC 100) (const_int 0))
894                  (match_operand:SI 1 "register_operand" "r")))]
895   ""
896   "subx\t%1, -1, %0"
897   [(set_attr "type" "ialuX")])
899 (define_insn "*x_minus_sgeu"
900   [(set (match_operand:SI 0 "register_operand" "=r")
901         (minus:SI (match_operand:SI 1 "register_operand" "r")
902                   (geu:SI (reg:CC 100) (const_int 0))))]
903   ""
904   "addx\t%1, -1, %0"
905   [(set_attr "type" "ialuX")])
907 (define_split
908   [(set (match_operand:SI 0 "register_operand" "")
909         (match_operator:SI 2 "noov_compare_operator"
910                            [(match_operand 1 "icc_or_fcc_register_operand" "")
911                             (const_int 0)]))]
912   "TARGET_V9
913    && REGNO (operands[1]) == SPARC_ICC_REG
914    && (GET_MODE (operands[1]) == CCXmode
915        /* 32-bit LTU/GEU are better implemented using addx/subx.  */
916        || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
917   [(set (match_dup 0) (const_int 0))
918    (set (match_dup 0)
919         (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
920                          (const_int 1)
921                          (match_dup 0)))]
922   "")
925 ;; These control RTL generation for conditional jump insns
927 (define_expand "cbranchcc4"
928   [(set (pc)
929         (if_then_else (match_operator 0 "comparison_operator"
930                           [(match_operand 1 "compare_operand" "")
931                            (match_operand 2 "const_zero_operand" "")])
932                       (label_ref (match_operand 3 "" ""))
933                       (pc)))]
934   ""
935   "")
937 (define_expand "cbranchsi4"
938   [(use (match_operator 0 "comparison_operator"
939          [(match_operand:SI 1 "compare_operand" "")
940           (match_operand:SI 2 "arith_operand" "")]))
941    (use (match_operand 3 ""))]
942   ""
944   if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
945     operands[1] = force_reg (SImode, operands[1]);
946   emit_conditional_branch_insn (operands);
947   DONE;
950 (define_expand "cbranchdi4"
951   [(use (match_operator 0 "comparison_operator"
952          [(match_operand:DI 1 "compare_operand" "")
953           (match_operand:DI 2 "arith_operand" "")]))
954    (use (match_operand 3 ""))]
955   "TARGET_ARCH64"
957   if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
958     operands[1] = force_reg (DImode, operands[1]);
959   emit_conditional_branch_insn (operands);
960   DONE;
963 (define_expand "cbranch<F:mode>4"
964   [(use (match_operator 0 "comparison_operator"
965          [(match_operand:F 1 "register_operand" "")
966           (match_operand:F 2 "register_operand" "")]))
967    (use (match_operand 3 ""))]
968   "TARGET_FPU"
969   { emit_conditional_branch_insn (operands); DONE; })
972 ;; Now match both normal and inverted jump.
974 ;; XXX fpcmp nop braindamage
975 (define_insn "*normal_branch"
976   [(set (pc)
977         (if_then_else (match_operator 0 "noov_compare_operator"
978                                       [(reg 100) (const_int 0)])
979                       (label_ref (match_operand 1 "" ""))
980                       (pc)))]
981   ""
983   return output_cbranch (operands[0], operands[1], 1, 0,
984                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
985                          insn);
987   [(set_attr "type" "branch")
988    (set_attr "branch_type" "icc")])
990 ;; XXX fpcmp nop braindamage
991 (define_insn "*inverted_branch"
992   [(set (pc)
993         (if_then_else (match_operator 0 "noov_compare_operator"
994                                       [(reg 100) (const_int 0)])
995                       (pc)
996                       (label_ref (match_operand 1 "" ""))))]
997   ""
999   return output_cbranch (operands[0], operands[1], 1, 1,
1000                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1001                          insn);
1003   [(set_attr "type" "branch")
1004    (set_attr "branch_type" "icc")])
1006 ;; XXX fpcmp nop braindamage
1007 (define_insn "*normal_fp_branch"
1008   [(set (pc)
1009         (if_then_else (match_operator 1 "comparison_operator"
1010                                       [(match_operand:CCFP 0 "fcc_register_operand" "c")
1011                                        (const_int 0)])
1012                       (label_ref (match_operand 2 "" ""))
1013                       (pc)))]
1014   ""
1016   return output_cbranch (operands[1], operands[2], 2, 0,
1017                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1018                          insn);
1020   [(set_attr "type" "branch")
1021    (set_attr "branch_type" "fcc")])
1023 ;; XXX fpcmp nop braindamage
1024 (define_insn "*inverted_fp_branch"
1025   [(set (pc)
1026         (if_then_else (match_operator 1 "comparison_operator"
1027                                       [(match_operand:CCFP 0 "fcc_register_operand" "c")
1028                                        (const_int 0)])
1029                       (pc)
1030                       (label_ref (match_operand 2 "" ""))))]
1031   ""
1033   return output_cbranch (operands[1], operands[2], 2, 1,
1034                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1035                          insn);
1037   [(set_attr "type" "branch")
1038    (set_attr "branch_type" "fcc")])
1040 ;; XXX fpcmp nop braindamage
1041 (define_insn "*normal_fpe_branch"
1042   [(set (pc)
1043         (if_then_else (match_operator 1 "comparison_operator"
1044                                       [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1045                                        (const_int 0)])
1046                       (label_ref (match_operand 2 "" ""))
1047                       (pc)))]
1048   ""
1050   return output_cbranch (operands[1], operands[2], 2, 0,
1051                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1052                          insn);
1054   [(set_attr "type" "branch")
1055    (set_attr "branch_type" "fcc")])
1057 ;; XXX fpcmp nop braindamage
1058 (define_insn "*inverted_fpe_branch"
1059   [(set (pc)
1060         (if_then_else (match_operator 1 "comparison_operator"
1061                                       [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1062                                        (const_int 0)])
1063                       (pc)
1064                       (label_ref (match_operand 2 "" ""))))]
1065   ""
1067   return output_cbranch (operands[1], operands[2], 2, 1,
1068                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1069                          insn);
1071   [(set_attr "type" "branch")
1072    (set_attr "branch_type" "fcc")])
1074 ;; SPARC V9-specific jump insns.  None of these are guaranteed to be
1075 ;; in the architecture.
1077 ;; There are no 32 bit brreg insns.
1079 ;; XXX
1080 (define_insn "*normal_int_branch_sp64"
1081   [(set (pc)
1082         (if_then_else (match_operator 0 "v9_register_compare_operator"
1083                                       [(match_operand:DI 1 "register_operand" "r")
1084                                        (const_int 0)])
1085                       (label_ref (match_operand 2 "" ""))
1086                       (pc)))]
1087   "TARGET_ARCH64"
1089   return output_v9branch (operands[0], operands[2], 1, 2, 0,
1090                           final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1091                           insn);
1093   [(set_attr "type" "branch")
1094    (set_attr "branch_type" "reg")])
1096 ;; XXX
1097 (define_insn "*inverted_int_branch_sp64"
1098   [(set (pc)
1099         (if_then_else (match_operator 0 "v9_register_compare_operator"
1100                                       [(match_operand:DI 1 "register_operand" "r")
1101                                        (const_int 0)])
1102                       (pc)
1103                       (label_ref (match_operand 2 "" ""))))]
1104   "TARGET_ARCH64"
1106   return output_v9branch (operands[0], operands[2], 1, 2, 1,
1107                           final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1108                           insn);
1110   [(set_attr "type" "branch")
1111    (set_attr "branch_type" "reg")])
1114 ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic
1115 ;; value subject to a PC-relative relocation.  Operand 2 is a helper function
1116 ;; that adds the PC value at the call point to register #(operand 3).
1118 (define_insn "load_pcrel_sym<P:mode>"
1119   [(set (match_operand:P 0 "register_operand" "=r")
1120         (unspec:P [(match_operand:P 1 "symbolic_operand" "")
1121                    (match_operand:P 2 "call_address_operand" "")
1122                    (match_operand:P 3 "const_int_operand" "")] UNSPEC_LOAD_PCREL_SYM))
1123    (clobber (reg:P 15))]
1124   "REGNO (operands[0]) == INTVAL (operands[3])"
1126   if (flag_delayed_branch)
1127     return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0";
1128   else
1129     return "sethi\t%%hi(%a1-8), %0\n\tadd\t%0, %%lo(%a1-4), %0\n\tcall\t%a2\n\t nop";
1131   [(set (attr "type") (const_string "multi"))
1132    (set (attr "length")
1133         (if_then_else (eq_attr "delayed_branch" "true")
1134                       (const_int 3)
1135                       (const_int 4)))])
1138 ;; Integer move instructions
1140 (define_expand "movqi"
1141   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1142         (match_operand:QI 1 "general_operand" ""))]
1143   ""
1145   if (sparc_expand_move (QImode, operands))
1146     DONE;
1149 (define_insn "*movqi_insn"
1150   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1151         (match_operand:QI 1 "input_operand"   "rI,m,rJ"))]
1152   "(register_operand (operands[0], QImode)
1153     || register_or_zero_operand (operands[1], QImode))"
1154   "@
1155    mov\t%1, %0
1156    ldub\t%1, %0
1157    stb\t%r1, %0"
1158   [(set_attr "type" "*,load,store")
1159    (set_attr "us3load_type" "*,3cycle,*")])
1161 (define_expand "movhi"
1162   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1163         (match_operand:HI 1 "general_operand" ""))]
1164   ""
1166   if (sparc_expand_move (HImode, operands))
1167     DONE;
1170 (define_insn "*movhi_insn"
1171   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1172         (match_operand:HI 1 "input_operand"   "rI,K,m,rJ"))]
1173   "(register_operand (operands[0], HImode)
1174     || register_or_zero_operand (operands[1], HImode))"
1175   "@
1176    mov\t%1, %0
1177    sethi\t%%hi(%a1), %0
1178    lduh\t%1, %0
1179    sth\t%r1, %0"
1180   [(set_attr "type" "*,*,load,store")
1181    (set_attr "us3load_type" "*,*,3cycle,*")])
1183 ;; We always work with constants here.
1184 (define_insn "*movhi_lo_sum"
1185   [(set (match_operand:HI 0 "register_operand" "=r")
1186         (ior:HI (match_operand:HI 1 "register_operand" "%r")
1187                 (match_operand:HI 2 "small_int_operand" "I")))]
1188   ""
1189   "or\t%1, %2, %0")
1191 (define_expand "movsi"
1192   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1193         (match_operand:SI 1 "general_operand" ""))]
1194   ""
1196   if (sparc_expand_move (SImode, operands))
1197     DONE;
1200 (define_insn "*movsi_insn"
1201   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m,!f,!f,!m,d")
1202         (match_operand:SI 1 "input_operand"   "rI,K,m,rJ,f,m,f,J"))]
1203   "(register_operand (operands[0], SImode)
1204     || register_or_zero_operand (operands[1], SImode))"
1205   "@
1206    mov\t%1, %0
1207    sethi\t%%hi(%a1), %0
1208    ld\t%1, %0
1209    st\t%r1, %0
1210    fmovs\t%1, %0
1211    ld\t%1, %0
1212    st\t%1, %0
1213    fzeros\t%0"
1214   [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga")])
1216 (define_insn "*movsi_lo_sum"
1217   [(set (match_operand:SI 0 "register_operand" "=r")
1218         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1219                    (match_operand:SI 2 "immediate_operand" "in")))]
1220   ""
1221   "or\t%1, %%lo(%a2), %0")
1223 (define_insn "*movsi_high"
1224   [(set (match_operand:SI 0 "register_operand" "=r")
1225         (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1226   ""
1227   "sethi\t%%hi(%a1), %0")
1229 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1230 ;; so that CSE won't optimize the address computation away.
1231 (define_insn "movsi_lo_sum_pic"
1232   [(set (match_operand:SI 0 "register_operand" "=r")
1233         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1234                    (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1235   "flag_pic"
1237 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1238   return "xor\t%1, %%gdop_lox10(%a2), %0";
1239 #else
1240   return "or\t%1, %%lo(%a2), %0";
1241 #endif
1244 (define_insn "movsi_high_pic"
1245   [(set (match_operand:SI 0 "register_operand" "=r")
1246         (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1247   "flag_pic && check_pic (1)"
1249 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1250   return "sethi\t%%gdop_hix22(%a1), %0";
1251 #else
1252   return "sethi\t%%hi(%a1), %0";
1253 #endif
1256 (define_insn "movsi_pic_gotdata_op"
1257   [(set (match_operand:SI 0 "register_operand" "=r")
1258         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
1259                     (match_operand:SI 2 "register_operand" "r")
1260                     (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
1261   "flag_pic && check_pic (1)"
1263 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1264   return "ld\t[%1 + %2], %0, %%gdop(%a3)";
1265 #else
1266   return "ld\t[%1 + %2], %0";
1267 #endif
1269   [(set_attr "type" "load")])
1271 (define_expand "movsi_pic_label_ref"
1272   [(set (match_dup 3) (high:SI
1273      (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1274                  (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1275    (set (match_dup 4) (lo_sum:SI (match_dup 3)
1276      (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1277    (set (match_operand:SI 0 "register_operand" "=r")
1278         (minus:SI (match_dup 5) (match_dup 4)))]
1279   "flag_pic"
1281   crtl->uses_pic_offset_table = 1;
1282   operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1283   if (!can_create_pseudo_p ())
1284     {
1285       operands[3] = operands[0];
1286       operands[4] = operands[0];
1287     }
1288   else
1289     {
1290       operands[3] = gen_reg_rtx (SImode);
1291       operands[4] = gen_reg_rtx (SImode);
1292     }
1293   operands[5] = pic_offset_table_rtx;
1296 (define_insn "*movsi_high_pic_label_ref"
1297   [(set (match_operand:SI 0 "register_operand" "=r")
1298       (high:SI
1299         (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1300                     (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1301   "flag_pic"
1302   "sethi\t%%hi(%a2-(%a1-.)), %0")
1304 (define_insn "*movsi_lo_sum_pic_label_ref"
1305   [(set (match_operand:SI 0 "register_operand" "=r")
1306       (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1307         (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
1308                     (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1309   "flag_pic"
1310   "or\t%1, %%lo(%a3-(%a2-.)), %0")
1312 ;; Set up the PIC register for VxWorks.
1314 (define_expand "vxworks_load_got"
1315   [(set (match_dup 0)
1316         (high:SI (match_dup 1)))
1317    (set (match_dup 0)
1318         (mem:SI (lo_sum:SI (match_dup 0) (match_dup 1))))
1319    (set (match_dup 0)
1320         (mem:SI (lo_sum:SI (match_dup 0) (match_dup 2))))]
1321   "TARGET_VXWORKS_RTP"
1323   operands[0] = pic_offset_table_rtx;
1324   operands[1] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_BASE);
1325   operands[2] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_INDEX);
1328 (define_expand "movdi"
1329   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1330         (match_operand:DI 1 "general_operand" ""))]
1331   ""
1333   if (sparc_expand_move (DImode, operands))
1334     DONE;
1337 ;; Be careful, fmovd does not exist when !v9.
1338 ;; We match MEM moves directly when we have correct even
1339 ;; numbered registers, but fall into splits otherwise.
1340 ;; The constraint ordering here is really important to
1341 ;; avoid insane problems in reload, especially for patterns
1342 ;; of the form:
1344 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
1345 ;;                       (const_int -5016)))
1346 ;;      (reg:DI 2 %g2))
1349 (define_insn "*movdi_insn_sp32"
1350   [(set (match_operand:DI 0 "nonimmediate_operand"
1351                                 "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
1352         (match_operand:DI 1 "input_operand"
1353                                 " J,U,T,r,o,i,r, f, T, o, f, f"))]
1354   "! TARGET_V9
1355    && (register_operand (operands[0], DImode)
1356        || register_or_zero_operand (operands[1], DImode))"
1357   "@
1358    #
1359    std\t%1, %0
1360    ldd\t%1, %0
1361    #
1362    #
1363    #
1364    #
1365    std\t%1, %0
1366    ldd\t%1, %0
1367    #
1368    #
1369    #"
1370   [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
1371    (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
1373 (define_insn "*movdi_insn_sp32_v9"
1374   [(set (match_operand:DI 0 "nonimmediate_operand"
1375                                         "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?e,?e,?W")
1376         (match_operand:DI 1 "input_operand"
1377                                         " J,J,U,T,r,o,i,r, f, T, o, f, e, W, e"))]
1378   "! TARGET_ARCH64
1379    && TARGET_V9
1380    && (register_operand (operands[0], DImode)
1381        || register_or_zero_operand (operands[1], DImode))"
1382   "@
1383    stx\t%%g0, %0
1384    #
1385    std\t%1, %0
1386    ldd\t%1, %0
1387    #
1388    #
1389    #
1390    #
1391    std\t%1, %0
1392    ldd\t%1, %0
1393    #
1394    #
1395    fmovd\\t%1, %0
1396    ldd\\t%1, %0
1397    std\\t%1, %0"
1398   [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,fpload,fpstore")
1399    (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,*,*")
1400    (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])
1402 (define_insn "*movdi_insn_sp64"
1403   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,m,?e,?e,?W,b")
1404         (match_operand:DI 1 "input_operand"   "rI,N,m,rJ,e,W,e,J"))]
1405   "TARGET_ARCH64
1406    && (register_operand (operands[0], DImode)
1407        || register_or_zero_operand (operands[1], DImode))"
1408   "@
1409    mov\t%1, %0
1410    sethi\t%%hi(%a1), %0
1411    ldx\t%1, %0
1412    stx\t%r1, %0
1413    fmovd\t%1, %0
1414    ldd\t%1, %0
1415    std\t%1, %0
1416    fzero\t%0"
1417   [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga")
1418    (set_attr "fptype" "*,*,*,*,double,*,*,double")])
1420 (define_expand "movdi_pic_label_ref"
1421   [(set (match_dup 3) (high:DI
1422      (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1423                  (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1424    (set (match_dup 4) (lo_sum:DI (match_dup 3)
1425      (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1426    (set (match_operand:DI 0 "register_operand" "=r")
1427         (minus:DI (match_dup 5) (match_dup 4)))]
1428   "TARGET_ARCH64 && flag_pic"
1430   crtl->uses_pic_offset_table = 1;
1431   operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1432   if (!can_create_pseudo_p ())
1433     {
1434       operands[3] = operands[0];
1435       operands[4] = operands[0];
1436     }
1437   else
1438     {
1439       operands[3] = gen_reg_rtx (DImode);
1440       operands[4] = gen_reg_rtx (DImode);
1441     }
1442   operands[5] = pic_offset_table_rtx;
1445 (define_insn "*movdi_high_pic_label_ref"
1446   [(set (match_operand:DI 0 "register_operand" "=r")
1447         (high:DI
1448           (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1449                       (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1450   "TARGET_ARCH64 && flag_pic"
1451   "sethi\t%%hi(%a2-(%a1-.)), %0")
1453 (define_insn "*movdi_lo_sum_pic_label_ref"
1454   [(set (match_operand:DI 0 "register_operand" "=r")
1455       (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1456         (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
1457                     (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1458   "TARGET_ARCH64 && flag_pic"
1459   "or\t%1, %%lo(%a3-(%a2-.)), %0")
1461 ;; SPARC-v9 code model support insns.  See sparc_emit_set_symbolic_const64
1462 ;; in sparc.c to see what is going on here... PIC stuff comes first.
1464 (define_insn "movdi_lo_sum_pic"
1465   [(set (match_operand:DI 0 "register_operand" "=r")
1466         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1467                    (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1468   "TARGET_ARCH64 && flag_pic"
1470 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1471   return "xor\t%1, %%gdop_lox10(%a2), %0";
1472 #else
1473   return "or\t%1, %%lo(%a2), %0";
1474 #endif
1477 (define_insn "movdi_high_pic"
1478   [(set (match_operand:DI 0 "register_operand" "=r")
1479         (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1480   "TARGET_ARCH64 && flag_pic && check_pic (1)"
1482 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1483   return "sethi\t%%gdop_hix22(%a1), %0";
1484 #else
1485   return "sethi\t%%hi(%a1), %0";
1486 #endif
1489 (define_insn "movdi_pic_gotdata_op"
1490   [(set (match_operand:DI 0 "register_operand" "=r")
1491         (unspec:DI [(match_operand:DI 1 "register_operand" "r")
1492                     (match_operand:DI 2 "register_operand" "r")
1493                     (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
1494   "TARGET_ARCH64 && flag_pic && check_pic (1)"
1496 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1497   return "ldx\t[%1 + %2], %0, %%gdop(%a3)";
1498 #else
1499   return "ldx\t[%1 + %2], %0";
1500 #endif
1502   [(set_attr "type" "load")])
1504 (define_insn "*sethi_di_medlow_embmedany_pic"
1505   [(set (match_operand:DI 0 "register_operand" "=r")
1506         (high:DI (match_operand:DI 1 "medium_pic_operand" "")))]
1507   "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
1508   "sethi\t%%hi(%a1), %0")
1510 (define_insn "*sethi_di_medlow"
1511   [(set (match_operand:DI 0 "register_operand" "=r")
1512         (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
1513   "TARGET_CM_MEDLOW && check_pic (1)"
1514   "sethi\t%%hi(%a1), %0")
1516 (define_insn "*losum_di_medlow"
1517   [(set (match_operand:DI 0 "register_operand" "=r")
1518         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1519                    (match_operand:DI 2 "symbolic_operand" "")))]
1520   "TARGET_CM_MEDLOW"
1521   "or\t%1, %%lo(%a2), %0")
1523 (define_insn "seth44"
1524   [(set (match_operand:DI 0 "register_operand" "=r")
1525         (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
1526   "TARGET_CM_MEDMID"
1527   "sethi\t%%h44(%a1), %0")
1529 (define_insn "setm44"
1530   [(set (match_operand:DI 0 "register_operand" "=r")
1531         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1532                    (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
1533   "TARGET_CM_MEDMID"
1534   "or\t%1, %%m44(%a2), %0")
1536 (define_insn "setl44"
1537   [(set (match_operand:DI 0 "register_operand" "=r")
1538         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1539                    (match_operand:DI 2 "symbolic_operand" "")))]
1540   "TARGET_CM_MEDMID"
1541   "or\t%1, %%l44(%a2), %0")
1543 (define_insn "sethh"
1544   [(set (match_operand:DI 0 "register_operand" "=r")
1545         (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
1546   "TARGET_CM_MEDANY"
1547   "sethi\t%%hh(%a1), %0")
1549 (define_insn "setlm"
1550   [(set (match_operand:DI 0 "register_operand" "=r")
1551         (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
1552   "TARGET_CM_MEDANY"
1553   "sethi\t%%lm(%a1), %0")
1555 (define_insn "sethm"
1556   [(set (match_operand:DI 0 "register_operand" "=r")
1557         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1558                    (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
1559   "TARGET_CM_MEDANY"
1560   "or\t%1, %%hm(%a2), %0")
1562 (define_insn "setlo"
1563   [(set (match_operand:DI 0 "register_operand" "=r")
1564         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1565                    (match_operand:DI 2 "symbolic_operand" "")))]
1566   "TARGET_CM_MEDANY"
1567   "or\t%1, %%lo(%a2), %0")
1569 (define_insn "embmedany_sethi"
1570   [(set (match_operand:DI 0 "register_operand" "=r")
1571         (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
1572   "TARGET_CM_EMBMEDANY && check_pic (1)"
1573   "sethi\t%%hi(%a1), %0")
1575 (define_insn "embmedany_losum"
1576   [(set (match_operand:DI 0 "register_operand" "=r")
1577         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1578                    (match_operand:DI 2 "data_segment_operand" "")))]
1579   "TARGET_CM_EMBMEDANY"
1580   "add\t%1, %%lo(%a2), %0")
1582 (define_insn "embmedany_brsum"
1583   [(set (match_operand:DI 0 "register_operand" "=r")
1584         (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
1585   "TARGET_CM_EMBMEDANY"
1586   "add\t%1, %_, %0")
1588 (define_insn "embmedany_textuhi"
1589   [(set (match_operand:DI 0 "register_operand" "=r")
1590         (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
1591   "TARGET_CM_EMBMEDANY && check_pic (1)"
1592   "sethi\t%%uhi(%a1), %0")
1594 (define_insn "embmedany_texthi"
1595   [(set (match_operand:DI 0 "register_operand" "=r")
1596         (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
1597   "TARGET_CM_EMBMEDANY && check_pic (1)"
1598   "sethi\t%%hi(%a1), %0")
1600 (define_insn "embmedany_textulo"
1601   [(set (match_operand:DI 0 "register_operand" "=r")
1602         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1603                    (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
1604   "TARGET_CM_EMBMEDANY"
1605   "or\t%1, %%ulo(%a2), %0")
1607 (define_insn "embmedany_textlo"
1608   [(set (match_operand:DI 0 "register_operand" "=r")
1609         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1610                    (match_operand:DI 2 "text_segment_operand" "")))]
1611   "TARGET_CM_EMBMEDANY"
1612   "or\t%1, %%lo(%a2), %0")
1614 ;; Now some patterns to help reload out a bit.
1615 (define_expand "reload_indi"
1616   [(parallel [(match_operand:DI 0 "register_operand" "=r")
1617               (match_operand:DI 1 "immediate_operand" "")
1618               (match_operand:TI 2 "register_operand" "=&r")])]
1619   "(TARGET_CM_MEDANY
1620     || TARGET_CM_EMBMEDANY)
1621    && ! flag_pic"
1623   sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1624   DONE;
1627 (define_expand "reload_outdi"
1628   [(parallel [(match_operand:DI 0 "register_operand" "=r")
1629               (match_operand:DI 1 "immediate_operand" "")
1630               (match_operand:TI 2 "register_operand" "=&r")])]
1631   "(TARGET_CM_MEDANY
1632     || TARGET_CM_EMBMEDANY)
1633    && ! flag_pic"
1635   sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1636   DONE;
1639 ;; Split up putting CONSTs and REGs into DI regs when !arch64
1640 (define_split
1641   [(set (match_operand:DI 0 "register_operand" "")
1642         (match_operand:DI 1 "const_int_operand" ""))]
1643   "! TARGET_ARCH64 && reload_completed"
1644   [(clobber (const_int 0))]
1646 #if HOST_BITS_PER_WIDE_INT == 32
1647   emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1648                         (INTVAL (operands[1]) < 0) ?
1649                         constm1_rtx :
1650                         const0_rtx));
1651   emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1652                         operands[1]));
1653 #else
1654   unsigned int low, high;
1656   low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
1657   high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
1658   emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
1660   /* Slick... but this trick loses if this subreg constant part
1661      can be done in one insn.  */
1662   if (low == high
1663       && ! SPARC_SETHI32_P (high)
1664       && ! SPARC_SIMM13_P (high))
1665     emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1666                           gen_highpart (SImode, operands[0])));
1667   else
1668     emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
1669 #endif
1670   DONE;
1673 (define_split
1674   [(set (match_operand:DI 0 "register_operand" "")
1675         (match_operand:DI 1 "const_double_operand" ""))]
1676   "reload_completed
1677    && (! TARGET_V9
1678        || (! TARGET_ARCH64
1679            && ((GET_CODE (operands[0]) == REG
1680                 && REGNO (operands[0]) < 32)
1681                || (GET_CODE (operands[0]) == SUBREG
1682                    && GET_CODE (SUBREG_REG (operands[0])) == REG
1683                    && REGNO (SUBREG_REG (operands[0])) < 32))))"
1684   [(clobber (const_int 0))]
1686   emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1687                         GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
1689   /* Slick... but this trick loses if this subreg constant part
1690      can be done in one insn.  */
1691   if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
1692       && ! SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
1693       && ! SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1])))
1694     {
1695       emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1696                             gen_highpart (SImode, operands[0])));
1697     }
1698   else
1699     {
1700       emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1701                             GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
1702     }
1703   DONE;
1706 (define_split
1707   [(set (match_operand:DI 0 "register_operand" "")
1708         (match_operand:DI 1 "register_operand" ""))]
1709   "reload_completed
1710    && (! TARGET_V9
1711        || (! TARGET_ARCH64
1712            && ((GET_CODE (operands[0]) == REG
1713                 && REGNO (operands[0]) < 32)
1714                || (GET_CODE (operands[0]) == SUBREG
1715                    && GET_CODE (SUBREG_REG (operands[0])) == REG
1716                    && REGNO (SUBREG_REG (operands[0])) < 32))))"
1717   [(clobber (const_int 0))]
1719   rtx set_dest = operands[0];
1720   rtx set_src = operands[1];
1721   rtx dest1, dest2;
1722   rtx src1, src2;
1724   dest1 = gen_highpart (SImode, set_dest);
1725   dest2 = gen_lowpart (SImode, set_dest);
1726   src1 = gen_highpart (SImode, set_src);
1727   src2 = gen_lowpart (SImode, set_src);
1729   /* Now emit using the real source and destination we found, swapping
1730      the order if we detect overlap.  */
1731   if (reg_overlap_mentioned_p (dest1, src2))
1732     {
1733       emit_insn (gen_movsi (dest2, src2));
1734       emit_insn (gen_movsi (dest1, src1));
1735     }
1736   else
1737     {
1738       emit_insn (gen_movsi (dest1, src1));
1739       emit_insn (gen_movsi (dest2, src2));
1740     }
1741   DONE;
1744 ;; Now handle the cases of memory moves from/to non-even
1745 ;; DI mode register pairs.
1746 (define_split
1747   [(set (match_operand:DI 0 "register_operand" "")
1748         (match_operand:DI 1 "memory_operand" ""))]
1749   "(! TARGET_ARCH64
1750     && reload_completed
1751     && sparc_splitdi_legitimate (operands[0], operands[1]))"
1752   [(clobber (const_int 0))]
1754   rtx word0 = adjust_address (operands[1], SImode, 0);
1755   rtx word1 = adjust_address (operands[1], SImode, 4);
1756   rtx high_part = gen_highpart (SImode, operands[0]);
1757   rtx low_part = gen_lowpart (SImode, operands[0]);
1759   if (reg_overlap_mentioned_p (high_part, word1))
1760     {
1761       emit_insn (gen_movsi (low_part, word1));
1762       emit_insn (gen_movsi (high_part, word0));
1763     }
1764   else
1765     {
1766       emit_insn (gen_movsi (high_part, word0));
1767       emit_insn (gen_movsi (low_part, word1));
1768     }
1769   DONE;
1772 (define_split
1773   [(set (match_operand:DI 0 "memory_operand" "")
1774         (match_operand:DI 1 "register_operand" ""))]
1775   "(! TARGET_ARCH64
1776     && reload_completed
1777     && sparc_splitdi_legitimate (operands[1], operands[0]))"
1778   [(clobber (const_int 0))]
1780   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
1781                         gen_highpart (SImode, operands[1])));
1782   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
1783                         gen_lowpart (SImode, operands[1])));
1784   DONE;
1787 (define_split
1788   [(set (match_operand:DI 0 "memory_operand" "")
1789         (match_operand:DI 1 "const_zero_operand" ""))]
1790   "reload_completed
1791    && (! TARGET_V9
1792        || (! TARGET_ARCH64
1793            && ! mem_min_alignment (operands[0], 8)))
1794    && offsettable_memref_p (operands[0])"
1795   [(clobber (const_int 0))]
1797   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
1798   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
1799   DONE;
1803 ;; Floating point and vector move instructions
1805 ;; Yes, you guessed it right, the former movsf expander.
1806 (define_expand "mov<V32:mode>"
1807   [(set (match_operand:V32 0 "nonimmediate_operand" "")
1808         (match_operand:V32 1 "general_operand" ""))]
1809   "<V32:MODE>mode == SFmode || TARGET_VIS"
1811   if (sparc_expand_move (<V32:MODE>mode, operands))
1812     DONE;
1815 (define_insn "*movsf_insn"
1816   [(set (match_operand:V32 0 "nonimmediate_operand" "=d,f,*r,*r,*r,f,*r,m,m")
1817         (match_operand:V32 1 "input_operand"        "GY,f,*rRY,Q,S,m,m,f,*rGY"))]
1818   "TARGET_FPU
1819    && (register_operand (operands[0], <V32:MODE>mode)
1820        || register_or_zero_operand (operands[1], <V32:MODE>mode))"
1822   if (GET_CODE (operands[1]) == CONST_DOUBLE
1823       && (which_alternative == 2
1824           || which_alternative == 3
1825           || which_alternative == 4))
1826     {
1827       REAL_VALUE_TYPE r;
1828       long i;
1830       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
1831       REAL_VALUE_TO_TARGET_SINGLE (r, i);
1832       operands[1] = GEN_INT (i);
1833     }
1835   switch (which_alternative)
1836     {
1837     case 0:
1838       return "fzeros\t%0";
1839     case 1:
1840       return "fmovs\t%1, %0";
1841     case 2:
1842       return "mov\t%1, %0";
1843     case 3:
1844       return "sethi\t%%hi(%a1), %0";
1845     case 4:
1846       return "#";
1847     case 5:
1848     case 6:
1849       return "ld\t%1, %0";
1850     case 7:
1851     case 8:
1852       return "st\t%r1, %0";
1853     default:
1854       gcc_unreachable ();
1855     }
1857   [(set_attr "type" "fga,fpmove,*,*,*,fpload,load,fpstore,store")])
1859 ;; Exactly the same as above, except that all `f' cases are deleted.
1860 ;; This is necessary to prevent reload from ever trying to use a `f' reg
1861 ;; when -mno-fpu.
1863 (define_insn "*movsf_insn_no_fpu"
1864   [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,m")
1865         (match_operand:SF 1 "input_operand"    "rR,Q,S,m,rG"))]
1866   "! TARGET_FPU
1867    && (register_operand (operands[0], SFmode)
1868        || register_or_zero_operand (operands[1], SFmode))"
1870   if (GET_CODE (operands[1]) == CONST_DOUBLE
1871       && (which_alternative == 0
1872           || which_alternative == 1
1873           || which_alternative == 2))
1874     {
1875       REAL_VALUE_TYPE r;
1876       long i;
1878       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
1879       REAL_VALUE_TO_TARGET_SINGLE (r, i);
1880       operands[1] = GEN_INT (i);
1881     }
1883   switch (which_alternative)
1884     {
1885     case 0:
1886       return "mov\t%1, %0";
1887     case 1:
1888       return "sethi\t%%hi(%a1), %0";
1889     case 2:
1890       return "#";
1891     case 3:
1892       return "ld\t%1, %0";
1893     case 4:
1894       return "st\t%r1, %0";
1895     default:
1896       gcc_unreachable ();
1897     }
1899   [(set_attr "type" "*,*,*,load,store")])
1901 ;; The following 3 patterns build SFmode constants in integer registers.
1903 (define_insn "*movsf_lo_sum"
1904   [(set (match_operand:SF 0 "register_operand" "=r")
1905         (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
1906                    (match_operand:SF 2 "fp_const_high_losum_operand" "S")))]
1907   ""
1909   REAL_VALUE_TYPE r;
1910   long i;
1912   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
1913   REAL_VALUE_TO_TARGET_SINGLE (r, i);
1914   operands[2] = GEN_INT (i);
1915   return "or\t%1, %%lo(%a2), %0";
1918 (define_insn "*movsf_high"
1919   [(set (match_operand:SF 0 "register_operand" "=r")
1920         (high:SF (match_operand:SF 1 "fp_const_high_losum_operand" "S")))]
1921   ""
1923   REAL_VALUE_TYPE r;
1924   long i;
1926   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
1927   REAL_VALUE_TO_TARGET_SINGLE (r, i);
1928   operands[1] = GEN_INT (i);
1929   return "sethi\t%%hi(%1), %0";
1932 (define_split
1933   [(set (match_operand:SF 0 "register_operand" "")
1934         (match_operand:SF 1 "fp_const_high_losum_operand" ""))]
1935   "REG_P (operands[0]) && REGNO (operands[0]) < 32"
1936   [(set (match_dup 0) (high:SF (match_dup 1)))
1937    (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
1939 ;; Yes, you again guessed it right, the former movdf expander.
1940 (define_expand "mov<V64:mode>"
1941   [(set (match_operand:V64 0 "nonimmediate_operand" "")
1942         (match_operand:V64 1 "general_operand" ""))]
1943   "<V64:MODE>mode == DFmode || TARGET_VIS"
1945   if (sparc_expand_move (<V64:MODE>mode, operands))
1946     DONE;
1949 ;; Be careful, fmovd does not exist when !v9.
1950 (define_insn "*movdf_insn_sp32"
1951   [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o")
1952         (match_operand:DF 1 "input_operand"    "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
1953   "TARGET_FPU
1954    && ! TARGET_V9
1955    && (register_operand (operands[0], DFmode)
1956        || register_or_zero_operand (operands[1], DFmode))"
1957   "@
1958   ldd\t%1, %0
1959   std\t%1, %0
1960   ldd\t%1, %0
1961   std\t%1, %0
1962   #
1963   #
1964   #
1965   #
1966   #
1967   #"
1968  [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
1969   (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
1971 (define_insn "*movdf_insn_sp32_no_fpu"
1972   [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
1973         (match_operand:DF 1 "input_operand"    "T,U,G,ro,r"))]
1974   "! TARGET_FPU
1975    && ! TARGET_V9
1976    && (register_operand (operands[0], DFmode)
1977        || register_or_zero_operand (operands[1], DFmode))"
1978   "@
1979   ldd\t%1, %0
1980   std\t%1, %0
1981   #
1982   #
1983   #"
1984   [(set_attr "type" "load,store,*,*,*")
1985    (set_attr "length" "*,*,2,2,2")])
1987 ;; We have available v9 double floats but not 64-bit integer registers.
1988 (define_insn "*movdf_insn_sp32_v9"
1989   [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,T,W,U,T,f,*r,o")
1990         (match_operand:V64 1 "input_operand" "GY,e,W#F,GY,e,T,U,o#F,*roGYDF,*rGYf"))]
1991   "TARGET_FPU
1992    && TARGET_V9
1993    && ! TARGET_ARCH64
1994    && (register_operand (operands[0], <V64:MODE>mode)
1995        || register_or_zero_operand (operands[1], <V64:MODE>mode))"
1996   "@
1997   fzero\t%0
1998   fmovd\t%1, %0
1999   ldd\t%1, %0
2000   stx\t%r1, %0
2001   std\t%1, %0
2002   ldd\t%1, %0
2003   std\t%1, %0
2004   #
2005   #
2006   #"
2007   [(set_attr "type" "fga,fpmove,load,store,store,load,store,*,*,*")
2008    (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
2009    (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
2011 (define_insn "*movdf_insn_sp32_v9_no_fpu"
2012   [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
2013         (match_operand:DF 1 "input_operand"    "T,U,G,ro,rG"))]
2014   "! TARGET_FPU
2015    && TARGET_V9
2016    && ! TARGET_ARCH64
2017    && (register_operand (operands[0], DFmode)
2018        || register_or_zero_operand (operands[1], DFmode))"
2019   "@
2020   ldd\t%1, %0
2021   std\t%1, %0
2022   stx\t%r1, %0
2023   #
2024   #"
2025   [(set_attr "type" "load,store,store,*,*")
2026    (set_attr "length" "*,*,*,2,2")])
2028 ;; We have available both v9 double floats and 64-bit integer registers.
2029 (define_insn "*movdf_insn_sp64"
2030   [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,W,*r,*r,m,*r")
2031         (match_operand:V64 1 "input_operand"    "GY,e,W#F,e,*rGY,m,*rGY,DF"))]
2032   "TARGET_FPU
2033    && TARGET_ARCH64
2034    && (register_operand (operands[0], <V64:MODE>mode)
2035        || register_or_zero_operand (operands[1], <V64:MODE>mode))"
2036   "@
2037   fzero\t%0
2038   fmovd\t%1, %0
2039   ldd\t%1, %0
2040   std\t%1, %0
2041   mov\t%r1, %0
2042   ldx\t%1, %0
2043   stx\t%r1, %0
2044   #"
2045   [(set_attr "type" "fga,fpmove,load,store,*,load,store,*")
2046    (set_attr "length" "*,*,*,*,*,*,*,2")
2047    (set_attr "fptype" "double,double,*,*,*,*,*,*")])
2049 (define_insn "*movdf_insn_sp64_no_fpu"
2050   [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
2051         (match_operand:DF 1 "input_operand"    "r,m,rG"))]
2052   "! TARGET_FPU
2053    && TARGET_ARCH64
2054    && (register_operand (operands[0], DFmode)
2055        || register_or_zero_operand (operands[1], DFmode))"
2056   "@
2057   mov\t%1, %0
2058   ldx\t%1, %0
2059   stx\t%r1, %0"
2060   [(set_attr "type" "*,load,store")])
2062 ;; This pattern builds V64mode constants in integer registers.
2063 (define_split
2064   [(set (match_operand:V64 0 "register_operand" "")
2065         (match_operand:V64 1 "const_double_or_vector_operand" ""))]
2066   "TARGET_FPU
2067    && (GET_CODE (operands[0]) == REG
2068        && REGNO (operands[0]) < 32)
2069    && ! const_zero_operand (operands[1], GET_MODE (operands[0]))
2070    && reload_completed"
2071   [(clobber (const_int 0))]
2073   operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
2075   if (TARGET_ARCH64)
2076     {
2077 #if HOST_BITS_PER_WIDE_INT == 32
2078       gcc_unreachable ();
2079 #else
2080       enum machine_mode mode = GET_MODE (operands[1]);
2081       rtx tem = simplify_subreg (DImode, operands[1], mode, 0);
2082       emit_insn (gen_movdi (operands[0], tem));
2083 #endif
2084     }
2085   else
2086     {
2087       enum machine_mode mode = GET_MODE (operands[1]);
2088       rtx hi = simplify_subreg (SImode, operands[1], mode, 0);
2089       rtx lo = simplify_subreg (SImode, operands[1], mode, 4);
2091       gcc_assert (GET_CODE (hi) == CONST_INT);
2092       gcc_assert (GET_CODE (lo) == CONST_INT);
2094       emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), hi));
2096       /* Slick... but this trick loses if this subreg constant part
2097          can be done in one insn.  */
2098       if (lo == hi
2099           && ! SPARC_SETHI32_P (INTVAL (hi))
2100           && ! SPARC_SIMM13_P (INTVAL (hi)))
2101         {
2102           emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2103                                 gen_highpart (SImode, operands[0])));
2104         }
2105       else
2106         {
2107           emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), lo));
2108         }
2109     }
2110   DONE;
2113 ;; Ok, now the splits to handle all the multi insn and
2114 ;; mis-aligned memory address cases.
2115 ;; In these splits please take note that we must be
2116 ;; careful when V9 but not ARCH64 because the integer
2117 ;; register DFmode cases must be handled.
2118 (define_split
2119   [(set (match_operand:V64 0 "register_operand" "")
2120         (match_operand:V64 1 "register_operand" ""))]
2121   "(! TARGET_V9
2122     || (! TARGET_ARCH64
2123         && ((GET_CODE (operands[0]) == REG
2124              && REGNO (operands[0]) < 32)
2125             || (GET_CODE (operands[0]) == SUBREG
2126                 && GET_CODE (SUBREG_REG (operands[0])) == REG
2127                 && REGNO (SUBREG_REG (operands[0])) < 32))))
2128    && reload_completed"
2129   [(clobber (const_int 0))]
2131   rtx set_dest = operands[0];
2132   rtx set_src = operands[1];
2133   rtx dest1, dest2;
2134   rtx src1, src2;
2135   enum machine_mode half_mode;
2137   /* We can be expanded for DFmode or integral vector modes.  */
2138   if (<V64:MODE>mode == DFmode)
2139     half_mode = SFmode;
2140   else
2141     half_mode = SImode;
2142   
2143   dest1 = gen_highpart (half_mode, set_dest);
2144   dest2 = gen_lowpart (half_mode, set_dest);
2145   src1 = gen_highpart (half_mode, set_src);
2146   src2 = gen_lowpart (half_mode, set_src);
2148   /* Now emit using the real source and destination we found, swapping
2149      the order if we detect overlap.  */
2150   if (reg_overlap_mentioned_p (dest1, src2))
2151     {
2152       emit_move_insn_1 (dest2, src2);
2153       emit_move_insn_1 (dest1, src1);
2154     }
2155   else
2156     {
2157       emit_move_insn_1 (dest1, src1);
2158       emit_move_insn_1 (dest2, src2);
2159     }
2160   DONE;
2163 (define_split
2164   [(set (match_operand:V64 0 "register_operand" "")
2165         (match_operand:V64 1 "memory_operand" ""))]
2166   "reload_completed
2167    && ! TARGET_ARCH64
2168    && (((REGNO (operands[0]) % 2) != 0)
2169        || ! mem_min_alignment (operands[1], 8))
2170    && offsettable_memref_p (operands[1])"
2171   [(clobber (const_int 0))]
2173   enum machine_mode half_mode;
2174   rtx word0, word1;
2176   /* We can be expanded for DFmode or integral vector modes.  */
2177   if (<V64:MODE>mode == DFmode)
2178     half_mode = SFmode;
2179   else
2180     half_mode = SImode;
2182   word0 = adjust_address (operands[1], half_mode, 0);
2183   word1 = adjust_address (operands[1], half_mode, 4);
2185   if (reg_overlap_mentioned_p (gen_highpart (half_mode, operands[0]), word1))
2186     {
2187       emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2188       emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2189     }
2190   else
2191     {
2192       emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2193       emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2194     }
2195   DONE;
2198 (define_split
2199   [(set (match_operand:V64 0 "memory_operand" "")
2200         (match_operand:V64 1 "register_operand" ""))]
2201   "reload_completed
2202    && ! TARGET_ARCH64
2203    && (((REGNO (operands[1]) % 2) != 0)
2204        || ! mem_min_alignment (operands[0], 8))
2205    && offsettable_memref_p (operands[0])"
2206   [(clobber (const_int 0))]
2208   enum machine_mode half_mode;
2209   rtx word0, word1;
2211   /* We can be expanded for DFmode or integral vector modes.  */
2212   if (<V64:MODE>mode == DFmode)
2213     half_mode = SFmode;
2214   else
2215     half_mode = SImode;
2217   word0 = adjust_address (operands[0], half_mode, 0);
2218   word1 = adjust_address (operands[0], half_mode, 4);
2220   emit_move_insn_1 (word0, gen_highpart (half_mode, operands[1]));
2221   emit_move_insn_1 (word1, gen_lowpart (half_mode, operands[1]));
2222   DONE;
2225 (define_split
2226   [(set (match_operand:V64 0 "memory_operand" "")
2227         (match_operand:V64 1 "const_zero_operand" ""))]
2228   "reload_completed
2229    && (! TARGET_V9
2230        || (! TARGET_ARCH64
2231            && ! mem_min_alignment (operands[0], 8)))
2232    && offsettable_memref_p (operands[0])"
2233   [(clobber (const_int 0))]
2235   enum machine_mode half_mode;
2236   rtx dest1, dest2;
2238   /* We can be expanded for DFmode or integral vector modes.  */
2239   if (<V64:MODE>mode == DFmode)
2240     half_mode = SFmode;
2241   else
2242     half_mode = SImode;
2244   dest1 = adjust_address (operands[0], half_mode, 0);
2245   dest2 = adjust_address (operands[0], half_mode, 4);
2247   emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2248   emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2249   DONE;
2252 (define_split
2253   [(set (match_operand:V64 0 "register_operand" "")
2254         (match_operand:V64 1 "const_zero_operand" ""))]
2255   "reload_completed
2256    && ! TARGET_ARCH64
2257    && ((GET_CODE (operands[0]) == REG
2258         && REGNO (operands[0]) < 32)
2259        || (GET_CODE (operands[0]) == SUBREG
2260            && GET_CODE (SUBREG_REG (operands[0])) == REG
2261            && REGNO (SUBREG_REG (operands[0])) < 32))"
2262   [(clobber (const_int 0))]
2264   enum machine_mode half_mode;
2265   rtx set_dest = operands[0];
2266   rtx dest1, dest2;
2268   /* We can be expanded for DFmode or integral vector modes.  */
2269   if (<V64:MODE>mode == DFmode)
2270     half_mode = SFmode;
2271   else
2272     half_mode = SImode;
2274   dest1 = gen_highpart (half_mode, set_dest);
2275   dest2 = gen_lowpart (half_mode, set_dest);
2276   emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2277   emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2278   DONE;
2281 (define_expand "movtf"
2282   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2283         (match_operand:TF 1 "general_operand" ""))]
2284   ""
2286   if (sparc_expand_move (TFmode, operands))
2287     DONE;
2290 (define_insn "*movtf_insn_sp32"
2291   [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,U,r")
2292         (match_operand:TF 1 "input_operand"    "G,oe,GeUr,o,roG"))]
2293   "TARGET_FPU
2294    && ! TARGET_ARCH64
2295    && (register_operand (operands[0], TFmode)
2296        || register_or_zero_operand (operands[1], TFmode))"
2297   "#"
2298   [(set_attr "length" "4")])
2300 ;; Exactly the same as above, except that all `e' cases are deleted.
2301 ;; This is necessary to prevent reload from ever trying to use a `e' reg
2302 ;; when -mno-fpu.
2304 (define_insn "*movtf_insn_sp32_no_fpu"
2305   [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
2306         (match_operand:TF 1 "input_operand"    "G,o,U,roG,r"))]
2307   "! TARGET_FPU
2308    && ! TARGET_ARCH64
2309    && (register_operand (operands[0], TFmode)
2310        || register_or_zero_operand (operands[1], TFmode))"
2311   "#"
2312   [(set_attr "length" "4")])
2314 (define_insn "*movtf_insn_sp64"
2315   [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,r")
2316         (match_operand:TF 1 "input_operand"    "G,oe,Ger,roG"))]
2317   "TARGET_FPU
2318    && TARGET_ARCH64
2319    && ! TARGET_HARD_QUAD
2320    && (register_operand (operands[0], TFmode)
2321        || register_or_zero_operand (operands[1], TFmode))"
2322   "#"
2323   [(set_attr "length" "2")])
2325 (define_insn "*movtf_insn_sp64_hq"
2326   [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,e,m,o,r")
2327         (match_operand:TF 1 "input_operand"    "G,e,m,e,rG,roG"))]
2328   "TARGET_FPU
2329    && TARGET_ARCH64
2330    && TARGET_HARD_QUAD
2331    && (register_operand (operands[0], TFmode)
2332        || register_or_zero_operand (operands[1], TFmode))"
2333   "@
2334   #
2335   fmovq\t%1, %0
2336   ldq\t%1, %0
2337   stq\t%1, %0
2338   #
2339   #"
2340   [(set_attr "type" "*,fpmove,fpload,fpstore,*,*")
2341    (set_attr "length" "2,*,*,*,2,2")])
2343 (define_insn "*movtf_insn_sp64_no_fpu"
2344   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
2345         (match_operand:TF 1 "input_operand"    "orG,rG"))]
2346   "! TARGET_FPU
2347    && TARGET_ARCH64
2348    && (register_operand (operands[0], TFmode)
2349        || register_or_zero_operand (operands[1], TFmode))"
2350   "#"
2351   [(set_attr "length" "2")])
2353 ;; Now all the splits to handle multi-insn TF mode moves.
2354 (define_split
2355   [(set (match_operand:TF 0 "register_operand" "")
2356         (match_operand:TF 1 "register_operand" ""))]
2357   "reload_completed
2358    && (! TARGET_ARCH64
2359        || (TARGET_FPU
2360            && ! TARGET_HARD_QUAD)
2361        || ! fp_register_operand (operands[0], TFmode))"
2362   [(clobber (const_int 0))]
2364   rtx set_dest = operands[0];
2365   rtx set_src = operands[1];
2366   rtx dest1, dest2;
2367   rtx src1, src2;
2369   dest1 = gen_df_reg (set_dest, 0);
2370   dest2 = gen_df_reg (set_dest, 1);
2371   src1 = gen_df_reg (set_src, 0);
2372   src2 = gen_df_reg (set_src, 1);
2374   /* Now emit using the real source and destination we found, swapping
2375      the order if we detect overlap.  */
2376   if (reg_overlap_mentioned_p (dest1, src2))
2377     {
2378       emit_insn (gen_movdf (dest2, src2));
2379       emit_insn (gen_movdf (dest1, src1));
2380     }
2381   else
2382     {
2383       emit_insn (gen_movdf (dest1, src1));
2384       emit_insn (gen_movdf (dest2, src2));
2385     }
2386   DONE;
2389 (define_split
2390   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2391         (match_operand:TF 1 "const_zero_operand" ""))]
2392   "reload_completed"
2393   [(clobber (const_int 0))]
2395   rtx set_dest = operands[0];
2396   rtx dest1, dest2;
2398   switch (GET_CODE (set_dest))
2399     {
2400     case REG:
2401       dest1 = gen_df_reg (set_dest, 0);
2402       dest2 = gen_df_reg (set_dest, 1);
2403       break;
2404     case MEM:
2405       dest1 = adjust_address (set_dest, DFmode, 0);
2406       dest2 = adjust_address (set_dest, DFmode, 8);
2407       break;
2408     default:
2409       gcc_unreachable ();      
2410     }
2412   emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
2413   emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
2414   DONE;
2417 (define_split
2418   [(set (match_operand:TF 0 "register_operand" "")
2419         (match_operand:TF 1 "memory_operand" ""))]
2420   "(reload_completed
2421     && offsettable_memref_p (operands[1])
2422     && (! TARGET_ARCH64
2423         || ! TARGET_HARD_QUAD
2424         || ! fp_register_operand (operands[0], TFmode)))"
2425   [(clobber (const_int 0))]
2427   rtx word0 = adjust_address (operands[1], DFmode, 0);
2428   rtx word1 = adjust_address (operands[1], DFmode, 8);
2429   rtx set_dest, dest1, dest2;
2431   set_dest = operands[0];
2433   dest1 = gen_df_reg (set_dest, 0);
2434   dest2 = gen_df_reg (set_dest, 1);
2436   /* Now output, ordering such that we don't clobber any registers
2437      mentioned in the address.  */
2438   if (reg_overlap_mentioned_p (dest1, word1))
2440     {
2441       emit_insn (gen_movdf (dest2, word1));
2442       emit_insn (gen_movdf (dest1, word0));
2443     }
2444   else
2445    {
2446       emit_insn (gen_movdf (dest1, word0));
2447       emit_insn (gen_movdf (dest2, word1));
2448    }
2449   DONE;
2452 (define_split
2453   [(set (match_operand:TF 0 "memory_operand" "")
2454         (match_operand:TF 1 "register_operand" ""))]
2455   "(reload_completed
2456     && offsettable_memref_p (operands[0])
2457     && (! TARGET_ARCH64
2458         || ! TARGET_HARD_QUAD
2459         || ! fp_register_operand (operands[1], TFmode)))"
2460   [(clobber (const_int 0))]
2462   rtx set_src = operands[1];
2464   emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
2465                         gen_df_reg (set_src, 0)));
2466   emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
2467                         gen_df_reg (set_src, 1)));
2468   DONE;
2472 ;; SPARC-V9 conditional move instructions
2474 ;; We can handle larger constants here for some flavors, but for now we keep
2475 ;; it simple and only allow those constants supported by all flavors.
2476 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
2477 ;; 3 contains the constant if one is present, but we handle either for
2478 ;; generality (sparc.c puts a constant in operand 2).
2480 (define_expand "mov<I:mode>cc"
2481   [(set (match_operand:I 0 "register_operand" "")
2482         (if_then_else:I (match_operand 1 "comparison_operator" "")
2483                         (match_operand:I 2 "arith10_operand" "")
2484                         (match_operand:I 3 "arith10_operand" "")))]
2485   "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2487   enum rtx_code code = GET_CODE (operands[1]);
2488   rtx cc_reg;
2490   if (GET_MODE (XEXP (operands[1], 0)) == DImode
2491       && ! TARGET_ARCH64)
2492     FAIL;
2494   if (GET_MODE (XEXP (operands[1], 0)) == TFmode && !TARGET_HARD_QUAD)
2495     operands[1]
2496       = sparc_emit_float_lib_cmp (XEXP (operands[1], 0), XEXP (operands[1], 1),
2497                                   GET_CODE (operands[1]));
2499   if (XEXP (operands[1], 1) == const0_rtx
2500       && GET_CODE (XEXP (operands[1], 0)) == REG
2501       && GET_MODE (XEXP (operands[1], 0)) == DImode
2502       && v9_regcmp_p (code))
2503     cc_reg = XEXP (operands[1], 0);
2504   else
2505     cc_reg = gen_compare_reg (operands[1]);
2507   operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
2510 (define_expand "mov<F:mode>cc"
2511   [(set (match_operand:F 0 "register_operand" "")
2512         (if_then_else:F (match_operand 1 "comparison_operator" "")
2513                         (match_operand:F 2 "register_operand" "")
2514                         (match_operand:F 3 "register_operand" "")))]
2515   "TARGET_V9 && TARGET_FPU"
2517   enum rtx_code code = GET_CODE (operands[1]);
2518   rtx cc_reg;
2520   if (GET_MODE (XEXP (operands[1], 0)) == DImode
2521       && ! TARGET_ARCH64)
2522     FAIL;
2524   if (GET_MODE (XEXP (operands[1], 0)) == TFmode && !TARGET_HARD_QUAD)
2525     operands[1]
2526       = sparc_emit_float_lib_cmp (XEXP (operands[1], 0), XEXP (operands[1], 1),
2527                                   GET_CODE (operands[1]));
2529   if (XEXP (operands[1], 1) == const0_rtx
2530       && GET_CODE (XEXP (operands[1], 0)) == REG
2531       && GET_MODE (XEXP (operands[1], 0)) == DImode
2532       && v9_regcmp_p (code))
2533     cc_reg = XEXP (operands[1], 0);
2534   else
2535     cc_reg = gen_compare_reg (operands[1]);
2537   operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
2540 ;; Conditional move define_insns
2542 (define_insn "*mov<I:mode>_cc_v9"
2543   [(set (match_operand:I 0 "register_operand" "=r,r")
2544         (if_then_else:I (match_operator 1 "comparison_operator"
2545                                [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2546                                 (const_int 0)])
2547                         (match_operand:I 3 "arith11_operand" "rL,0")
2548                         (match_operand:I 4 "arith11_operand" "0,rL")))]
2549   "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2550   "@
2551    mov%C1\t%x2, %3, %0
2552    mov%c1\t%x2, %4, %0"
2553   [(set_attr "type" "cmove")])
2555 (define_insn "*mov<I:mode>_cc_reg_sp64"
2556   [(set (match_operand:I 0 "register_operand" "=r,r")
2557         (if_then_else:I (match_operator 1 "v9_register_compare_operator"
2558                                 [(match_operand:DI 2 "register_operand" "r,r")
2559                                  (const_int 0)])
2560                         (match_operand:I 3 "arith10_operand" "rM,0")
2561                         (match_operand:I 4 "arith10_operand" "0,rM")))]
2562   "TARGET_ARCH64"
2563   "@
2564    movr%D1\t%2, %r3, %0
2565    movr%d1\t%2, %r4, %0"
2566   [(set_attr "type" "cmove")])
2568 (define_insn "*movsf_cc_v9"
2569   [(set (match_operand:SF 0 "register_operand" "=f,f")
2570         (if_then_else:SF (match_operator 1 "comparison_operator"
2571                                 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2572                                  (const_int 0)])
2573                          (match_operand:SF 3 "register_operand" "f,0")
2574                          (match_operand:SF 4 "register_operand" "0,f")))]
2575   "TARGET_V9 && TARGET_FPU"
2576   "@
2577    fmovs%C1\t%x2, %3, %0
2578    fmovs%c1\t%x2, %4, %0"
2579   [(set_attr "type" "fpcmove")])
2581 (define_insn "*movsf_cc_reg_sp64"
2582   [(set (match_operand:SF 0 "register_operand" "=f,f")
2583         (if_then_else:SF (match_operator 1 "v9_register_compare_operator"
2584                                 [(match_operand:DI 2 "register_operand" "r,r")
2585                                  (const_int 0)])
2586                          (match_operand:SF 3 "register_operand" "f,0")
2587                          (match_operand:SF 4 "register_operand" "0,f")))]
2588   "TARGET_ARCH64 && TARGET_FPU"
2589   "@
2590    fmovrs%D1\t%2, %3, %0
2591    fmovrs%d1\t%2, %4, %0"
2592   [(set_attr "type" "fpcrmove")])
2594 ;; Named because invoked by movtf_cc_v9
2595 (define_insn "movdf_cc_v9"
2596   [(set (match_operand:DF 0 "register_operand" "=e,e")
2597         (if_then_else:DF (match_operator 1 "comparison_operator"
2598                                 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2599                                  (const_int 0)])
2600                          (match_operand:DF 3 "register_operand" "e,0")
2601                          (match_operand:DF 4 "register_operand" "0,e")))]
2602   "TARGET_V9 && TARGET_FPU"
2603   "@
2604    fmovd%C1\t%x2, %3, %0
2605    fmovd%c1\t%x2, %4, %0"
2606   [(set_attr "type" "fpcmove")
2607    (set_attr "fptype" "double")])
2609 ;; Named because invoked by movtf_cc_reg_sp64
2610 (define_insn "movdf_cc_reg_sp64"
2611   [(set (match_operand:DF 0 "register_operand" "=e,e")
2612         (if_then_else:DF (match_operator 1 "v9_register_compare_operator"
2613                                 [(match_operand:DI 2 "register_operand" "r,r")
2614                                  (const_int 0)])
2615                          (match_operand:DF 3 "register_operand" "e,0")
2616                          (match_operand:DF 4 "register_operand" "0,e")))]
2617   "TARGET_ARCH64 && TARGET_FPU"
2618   "@
2619    fmovrd%D1\t%2, %3, %0
2620    fmovrd%d1\t%2, %4, %0"
2621   [(set_attr "type" "fpcrmove")
2622    (set_attr "fptype" "double")])
2624 (define_insn "*movtf_cc_hq_v9"
2625   [(set (match_operand:TF 0 "register_operand" "=e,e")
2626         (if_then_else:TF (match_operator 1 "comparison_operator"
2627                                 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2628                                  (const_int 0)])
2629                          (match_operand:TF 3 "register_operand" "e,0")
2630                          (match_operand:TF 4 "register_operand" "0,e")))]
2631   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
2632   "@
2633    fmovq%C1\t%x2, %3, %0
2634    fmovq%c1\t%x2, %4, %0"
2635   [(set_attr "type" "fpcmove")])
2637 (define_insn "*movtf_cc_reg_hq_sp64"
2638   [(set (match_operand:TF 0 "register_operand" "=e,e")
2639         (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2640                                 [(match_operand:DI 2 "register_operand" "r,r")
2641                                  (const_int 0)])
2642                          (match_operand:TF 3 "register_operand" "e,0")
2643                          (match_operand:TF 4 "register_operand" "0,e")))]
2644   "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
2645   "@
2646    fmovrq%D1\t%2, %3, %0
2647    fmovrq%d1\t%2, %4, %0"
2648   [(set_attr "type" "fpcrmove")])
2650 (define_insn_and_split "*movtf_cc_v9"
2651   [(set (match_operand:TF 0 "register_operand" "=e,e")
2652         (if_then_else:TF (match_operator 1 "comparison_operator"
2653                             [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2654                              (const_int 0)])
2655                          (match_operand:TF 3 "register_operand" "e,0")
2656                          (match_operand:TF 4 "register_operand" "0,e")))]
2657   "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
2658   "#"
2659   "&& reload_completed"
2660   [(clobber (const_int 0))]
2662   rtx set_dest = operands[0];
2663   rtx set_srca = operands[3];
2664   rtx set_srcb = operands[4];
2665   int third = rtx_equal_p (set_dest, set_srca);
2666   rtx dest1, dest2;
2667   rtx srca1, srca2, srcb1, srcb2;
2669   dest1 = gen_df_reg (set_dest, 0);
2670   dest2 = gen_df_reg (set_dest, 1);
2671   srca1 = gen_df_reg (set_srca, 0);
2672   srca2 = gen_df_reg (set_srca, 1);
2673   srcb1 = gen_df_reg (set_srcb, 0);
2674   srcb2 = gen_df_reg (set_srcb, 1);
2676   /* Now emit using the real source and destination we found, swapping
2677      the order if we detect overlap.  */
2678   if ((third && reg_overlap_mentioned_p (dest1, srcb2))
2679       || (!third && reg_overlap_mentioned_p (dest1, srca2)))
2680     {
2681       emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, srcb2));
2682       emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, srcb1));
2683     }
2684   else
2685     {
2686       emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, srcb1));
2687       emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, srcb2));
2688     }
2689   DONE;
2691   [(set_attr "length" "2")])
2693 (define_insn_and_split "*movtf_cc_reg_sp64"
2694   [(set (match_operand:TF 0 "register_operand" "=e,e")
2695         (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2696                                 [(match_operand:DI 2 "register_operand" "r,r")
2697                                  (const_int 0)])
2698                          (match_operand:TF 3 "register_operand" "e,0")
2699                          (match_operand:TF 4 "register_operand" "0,e")))]
2700   "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
2701   "#"
2702   "&& reload_completed"
2703   [(clobber (const_int 0))]
2705   rtx set_dest = operands[0];
2706   rtx set_srca = operands[3];
2707   rtx set_srcb = operands[4];
2708   int third = rtx_equal_p (set_dest, set_srca);
2709   rtx dest1, dest2;
2710   rtx srca1, srca2, srcb1, srcb2;
2712   dest1 = gen_df_reg (set_dest, 0);
2713   dest2 = gen_df_reg (set_dest, 1);
2714   srca1 = gen_df_reg (set_srca, 0);
2715   srca2 = gen_df_reg (set_srca, 1);
2716   srcb1 = gen_df_reg (set_srcb, 0);
2717   srcb2 = gen_df_reg (set_srcb, 1);
2719   /* Now emit using the real source and destination we found, swapping
2720      the order if we detect overlap.  */
2721   if ((third && reg_overlap_mentioned_p (dest1, srcb2))
2722       || (!third && reg_overlap_mentioned_p (dest1, srca2)))
2723     {
2724       emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
2725       emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
2726     }
2727   else
2728     {
2729       emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
2730       emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
2731     }
2732   DONE;
2734   [(set_attr "length" "2")])
2737 ;; Zero-extension instructions
2739 ;; These patterns originally accepted general_operands, however, slightly
2740 ;; better code is generated by only accepting register_operands, and then
2741 ;; letting combine generate the ldu[hb] insns.
2743 (define_expand "zero_extendhisi2"
2744   [(set (match_operand:SI 0 "register_operand" "")
2745         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
2746   ""
2748   rtx temp = gen_reg_rtx (SImode);
2749   rtx shift_16 = GEN_INT (16);
2750   int op1_subbyte = 0;
2752   if (GET_CODE (operand1) == SUBREG)
2753     {
2754       op1_subbyte = SUBREG_BYTE (operand1);
2755       op1_subbyte /= GET_MODE_SIZE (SImode);
2756       op1_subbyte *= GET_MODE_SIZE (SImode);
2757       operand1 = XEXP (operand1, 0);
2758     }
2760   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
2761                           shift_16));
2762   emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
2763   DONE;
2766 (define_insn "*zero_extendhisi2_insn"
2767   [(set (match_operand:SI 0 "register_operand" "=r")
2768         (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2769   ""
2770   "lduh\t%1, %0"
2771   [(set_attr "type" "load")
2772    (set_attr "us3load_type" "3cycle")])
2774 (define_expand "zero_extendqihi2"
2775   [(set (match_operand:HI 0 "register_operand" "")
2776         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
2777   ""
2778   "")
2780 (define_insn "*zero_extendqihi2_insn"
2781   [(set (match_operand:HI 0 "register_operand" "=r,r")
2782         (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
2783   "GET_CODE (operands[1]) != CONST_INT"
2784   "@
2785    and\t%1, 0xff, %0
2786    ldub\t%1, %0"
2787   [(set_attr "type" "*,load")
2788    (set_attr "us3load_type" "*,3cycle")])
2790 (define_expand "zero_extendqisi2"
2791   [(set (match_operand:SI 0 "register_operand" "")
2792         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
2793   ""
2794   "")
2796 (define_insn "*zero_extendqisi2_insn"
2797   [(set (match_operand:SI 0 "register_operand" "=r,r")
2798         (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
2799   "GET_CODE (operands[1]) != CONST_INT"
2800   "@
2801    and\t%1, 0xff, %0
2802    ldub\t%1, %0"
2803   [(set_attr "type" "*,load")
2804    (set_attr "us3load_type" "*,3cycle")])
2806 (define_expand "zero_extendqidi2"
2807   [(set (match_operand:DI 0 "register_operand" "")
2808         (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
2809   "TARGET_ARCH64"
2810   "")
2812 (define_insn "*zero_extendqidi2_insn"
2813   [(set (match_operand:DI 0 "register_operand" "=r,r")
2814         (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
2815   "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
2816   "@
2817    and\t%1, 0xff, %0
2818    ldub\t%1, %0"
2819   [(set_attr "type" "*,load")
2820    (set_attr "us3load_type" "*,3cycle")])
2822 (define_expand "zero_extendhidi2"
2823   [(set (match_operand:DI 0 "register_operand" "")
2824         (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
2825   "TARGET_ARCH64"
2827   rtx temp = gen_reg_rtx (DImode);
2828   rtx shift_48 = GEN_INT (48);
2829   int op1_subbyte = 0;
2831   if (GET_CODE (operand1) == SUBREG)
2832     {
2833       op1_subbyte = SUBREG_BYTE (operand1);
2834       op1_subbyte /= GET_MODE_SIZE (DImode);
2835       op1_subbyte *= GET_MODE_SIZE (DImode);
2836       operand1 = XEXP (operand1, 0);
2837     }
2839   emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
2840                           shift_48));
2841   emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
2842   DONE;
2845 (define_insn "*zero_extendhidi2_insn"
2846   [(set (match_operand:DI 0 "register_operand" "=r")
2847         (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
2848   "TARGET_ARCH64"
2849   "lduh\t%1, %0"
2850   [(set_attr "type" "load")
2851    (set_attr "us3load_type" "3cycle")])
2853 ;; ??? Write truncdisi pattern using sra?
2855 (define_expand "zero_extendsidi2"
2856   [(set (match_operand:DI 0 "register_operand" "")
2857         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
2858   ""
2859   "")
2861 (define_insn "*zero_extendsidi2_insn_sp64"
2862   [(set (match_operand:DI 0 "register_operand" "=r,r")
2863         (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
2864   "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
2865   "@
2866    srl\t%1, 0, %0
2867    lduw\t%1, %0"
2868   [(set_attr "type" "shift,load")])
2870 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
2871   [(set (match_operand:DI 0 "register_operand" "=r")
2872         (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
2873   "! TARGET_ARCH64"
2874   "#"
2875   "&& reload_completed"
2876   [(set (match_dup 2) (match_dup 3))
2877    (set (match_dup 4) (match_dup 5))]
2879   rtx dest1, dest2;
2881   dest1 = gen_highpart (SImode, operands[0]);
2882   dest2 = gen_lowpart (SImode, operands[0]);
2884   /* Swap the order in case of overlap.  */
2885   if (REGNO (dest1) == REGNO (operands[1]))
2886     {
2887       operands[2] = dest2;
2888       operands[3] = operands[1];
2889       operands[4] = dest1;
2890       operands[5] = const0_rtx;
2891     }
2892   else
2893     {
2894       operands[2] = dest1;
2895       operands[3] = const0_rtx;
2896       operands[4] = dest2;
2897       operands[5] = operands[1];
2898     }
2900   [(set_attr "length" "2")])
2902 ;; Simplify comparisons of extended values.
2904 (define_insn "*cmp_zero_extendqisi2"
2905   [(set (reg:CC 100)
2906         (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
2907                     (const_int 0)))]
2908   ""
2909   "andcc\t%0, 0xff, %%g0"
2910   [(set_attr "type" "compare")])
2912 (define_insn "*cmp_zero_qi"
2913   [(set (reg:CC 100)
2914         (compare:CC (match_operand:QI 0 "register_operand" "r")
2915                     (const_int 0)))]
2916   ""
2917   "andcc\t%0, 0xff, %%g0"
2918   [(set_attr "type" "compare")])
2920 (define_insn "*cmp_zero_extendqisi2_set"
2921   [(set (reg:CC 100)
2922         (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
2923                     (const_int 0)))
2924    (set (match_operand:SI 0 "register_operand" "=r")
2925         (zero_extend:SI (match_dup 1)))]
2926   ""
2927   "andcc\t%1, 0xff, %0"
2928   [(set_attr "type" "compare")])
2930 (define_insn "*cmp_zero_extendqisi2_andcc_set"
2931   [(set (reg:CC 100)
2932         (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
2933                             (const_int 255))
2934                     (const_int 0)))
2935    (set (match_operand:SI 0 "register_operand" "=r")
2936         (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
2937   ""
2938   "andcc\t%1, 0xff, %0"
2939   [(set_attr "type" "compare")])
2941 (define_insn "*cmp_zero_extendqidi2"
2942   [(set (reg:CCX 100)
2943         (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
2944                      (const_int 0)))]
2945   "TARGET_ARCH64"
2946   "andcc\t%0, 0xff, %%g0"
2947   [(set_attr "type" "compare")])
2949 (define_insn "*cmp_zero_qi_sp64"
2950   [(set (reg:CCX 100)
2951         (compare:CCX (match_operand:QI 0 "register_operand" "r")
2952                      (const_int 0)))]
2953   "TARGET_ARCH64"
2954   "andcc\t%0, 0xff, %%g0"
2955   [(set_attr "type" "compare")])
2957 (define_insn "*cmp_zero_extendqidi2_set"
2958   [(set (reg:CCX 100)
2959         (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
2960                      (const_int 0)))
2961    (set (match_operand:DI 0 "register_operand" "=r")
2962         (zero_extend:DI (match_dup 1)))]
2963   "TARGET_ARCH64"
2964   "andcc\t%1, 0xff, %0"
2965   [(set_attr "type" "compare")])
2967 (define_insn "*cmp_zero_extendqidi2_andcc_set"
2968   [(set (reg:CCX 100)
2969         (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
2970                              (const_int 255))
2971                      (const_int 0)))
2972    (set (match_operand:DI 0 "register_operand" "=r")
2973         (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
2974   "TARGET_ARCH64"
2975   "andcc\t%1, 0xff, %0"
2976   [(set_attr "type" "compare")])
2978 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
2980 (define_insn "*cmp_siqi_trunc"
2981   [(set (reg:CC 100)
2982         (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
2983                     (const_int 0)))]
2984   ""
2985   "andcc\t%0, 0xff, %%g0"
2986   [(set_attr "type" "compare")])
2988 (define_insn "*cmp_siqi_trunc_set"
2989   [(set (reg:CC 100)
2990         (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
2991                     (const_int 0)))
2992    (set (match_operand:QI 0 "register_operand" "=r")
2993         (subreg:QI (match_dup 1) 3))]
2994   ""
2995   "andcc\t%1, 0xff, %0"
2996   [(set_attr "type" "compare")])
2998 (define_insn "*cmp_diqi_trunc"
2999   [(set (reg:CC 100)
3000         (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
3001                     (const_int 0)))]
3002   "TARGET_ARCH64"
3003   "andcc\t%0, 0xff, %%g0"
3004   [(set_attr "type" "compare")])
3006 (define_insn "*cmp_diqi_trunc_set"
3007   [(set (reg:CC 100)
3008         (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
3009                     (const_int 0)))
3010    (set (match_operand:QI 0 "register_operand" "=r")
3011         (subreg:QI (match_dup 1) 7))]
3012   "TARGET_ARCH64"
3013   "andcc\t%1, 0xff, %0"
3014   [(set_attr "type" "compare")])
3017 ;; Sign-extension instructions
3019 ;; These patterns originally accepted general_operands, however, slightly
3020 ;; better code is generated by only accepting register_operands, and then
3021 ;; letting combine generate the lds[hb] insns.
3023 (define_expand "extendhisi2"
3024   [(set (match_operand:SI 0 "register_operand" "")
3025         (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
3026   ""
3028   rtx temp = gen_reg_rtx (SImode);
3029   rtx shift_16 = GEN_INT (16);
3030   int op1_subbyte = 0;
3032   if (GET_CODE (operand1) == SUBREG)
3033     {
3034       op1_subbyte = SUBREG_BYTE (operand1);
3035       op1_subbyte /= GET_MODE_SIZE (SImode);
3036       op1_subbyte *= GET_MODE_SIZE (SImode);
3037       operand1 = XEXP (operand1, 0);
3038     }
3040   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3041                           shift_16));
3042   emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
3043   DONE;
3046 (define_insn "*sign_extendhisi2_insn"
3047   [(set (match_operand:SI 0 "register_operand" "=r")
3048         (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3049   ""
3050   "ldsh\t%1, %0"
3051   [(set_attr "type" "sload")
3052    (set_attr "us3load_type" "3cycle")])
3054 (define_expand "extendqihi2"
3055   [(set (match_operand:HI 0 "register_operand" "")
3056         (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
3057   ""
3059   rtx temp = gen_reg_rtx (SImode);
3060   rtx shift_24 = GEN_INT (24);
3061   int op1_subbyte = 0;
3062   int op0_subbyte = 0;
3064   if (GET_CODE (operand1) == SUBREG)
3065     {
3066       op1_subbyte = SUBREG_BYTE (operand1);
3067       op1_subbyte /= GET_MODE_SIZE (SImode);
3068       op1_subbyte *= GET_MODE_SIZE (SImode);
3069       operand1 = XEXP (operand1, 0);
3070     }
3071   if (GET_CODE (operand0) == SUBREG)
3072     {
3073       op0_subbyte = SUBREG_BYTE (operand0);
3074       op0_subbyte /= GET_MODE_SIZE (SImode);
3075       op0_subbyte *= GET_MODE_SIZE (SImode);
3076       operand0 = XEXP (operand0, 0);
3077     }
3078   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3079                           shift_24));
3080   if (GET_MODE (operand0) != SImode)
3081     operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
3082   emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3083   DONE;
3086 (define_insn "*sign_extendqihi2_insn"
3087   [(set (match_operand:HI 0 "register_operand" "=r")
3088         (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3089   ""
3090   "ldsb\t%1, %0"
3091   [(set_attr "type" "sload")
3092    (set_attr "us3load_type" "3cycle")])
3094 (define_expand "extendqisi2"
3095   [(set (match_operand:SI 0 "register_operand" "")
3096         (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
3097   ""
3099   rtx temp = gen_reg_rtx (SImode);
3100   rtx shift_24 = GEN_INT (24);
3101   int op1_subbyte = 0;
3103   if (GET_CODE (operand1) == SUBREG)
3104     {
3105       op1_subbyte = SUBREG_BYTE (operand1);
3106       op1_subbyte /= GET_MODE_SIZE (SImode);
3107       op1_subbyte *= GET_MODE_SIZE (SImode);
3108       operand1 = XEXP (operand1, 0);
3109     }
3111   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3112                           shift_24));
3113   emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3114   DONE;
3117 (define_insn "*sign_extendqisi2_insn"
3118   [(set (match_operand:SI 0 "register_operand" "=r")
3119         (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3120   ""
3121   "ldsb\t%1, %0"
3122   [(set_attr "type" "sload")
3123    (set_attr "us3load_type" "3cycle")])
3125 (define_expand "extendqidi2"
3126   [(set (match_operand:DI 0 "register_operand" "")
3127         (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
3128   "TARGET_ARCH64"
3130   rtx temp = gen_reg_rtx (DImode);
3131   rtx shift_56 = GEN_INT (56);
3132   int op1_subbyte = 0;
3134   if (GET_CODE (operand1) == SUBREG)
3135     {
3136       op1_subbyte = SUBREG_BYTE (operand1);
3137       op1_subbyte /= GET_MODE_SIZE (DImode);
3138       op1_subbyte *= GET_MODE_SIZE (DImode);
3139       operand1 = XEXP (operand1, 0);
3140     }
3142   emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3143                           shift_56));
3144   emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
3145   DONE;
3148 (define_insn "*sign_extendqidi2_insn"
3149   [(set (match_operand:DI 0 "register_operand" "=r")
3150         (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3151   "TARGET_ARCH64"
3152   "ldsb\t%1, %0"
3153   [(set_attr "type" "sload")
3154    (set_attr "us3load_type" "3cycle")])
3156 (define_expand "extendhidi2"
3157   [(set (match_operand:DI 0 "register_operand" "")
3158         (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
3159   "TARGET_ARCH64"
3161   rtx temp = gen_reg_rtx (DImode);
3162   rtx shift_48 = GEN_INT (48);
3163   int op1_subbyte = 0;
3165   if (GET_CODE (operand1) == SUBREG)
3166     {
3167       op1_subbyte = SUBREG_BYTE (operand1);
3168       op1_subbyte /= GET_MODE_SIZE (DImode);
3169       op1_subbyte *= GET_MODE_SIZE (DImode);
3170       operand1 = XEXP (operand1, 0);
3171     }
3173   emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3174                           shift_48));
3175   emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
3176   DONE;
3179 (define_insn "*sign_extendhidi2_insn"
3180   [(set (match_operand:DI 0 "register_operand" "=r")
3181         (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3182   "TARGET_ARCH64"
3183   "ldsh\t%1, %0"
3184   [(set_attr "type" "sload")
3185    (set_attr "us3load_type" "3cycle")])
3187 (define_expand "extendsidi2"
3188   [(set (match_operand:DI 0 "register_operand" "")
3189         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3190   "TARGET_ARCH64"
3191   "")
3193 (define_insn "*sign_extendsidi2_insn"
3194   [(set (match_operand:DI 0 "register_operand" "=r,r")
3195         (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
3196   "TARGET_ARCH64"
3197   "@
3198   sra\t%1, 0, %0
3199   ldsw\t%1, %0"
3200   [(set_attr "type" "shift,sload")
3201    (set_attr "us3load_type" "*,3cycle")])
3204 ;; Special pattern for optimizing bit-field compares.  This is needed
3205 ;; because combine uses this as a canonical form.
3207 (define_insn "*cmp_zero_extract"
3208   [(set (reg:CC 100)
3209         (compare:CC
3210          (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
3211                           (match_operand:SI 1 "small_int_operand" "I")
3212                           (match_operand:SI 2 "small_int_operand" "I"))
3213          (const_int 0)))]
3214   "INTVAL (operands[2]) > 19"
3216   int len = INTVAL (operands[1]);
3217   int pos = 32 - INTVAL (operands[2]) - len;
3218   HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
3219   operands[1] = GEN_INT (mask);
3220   return "andcc\t%0, %1, %%g0";
3222   [(set_attr "type" "compare")])
3224 (define_insn "*cmp_zero_extract_sp64"
3225   [(set (reg:CCX 100)
3226         (compare:CCX
3227          (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
3228                           (match_operand:SI 1 "small_int_operand" "I")
3229                           (match_operand:SI 2 "small_int_operand" "I"))
3230          (const_int 0)))]
3231   "TARGET_ARCH64 && INTVAL (operands[2]) > 51"
3233   int len = INTVAL (operands[1]);
3234   int pos = 64 - INTVAL (operands[2]) - len;
3235   HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
3236   operands[1] = GEN_INT (mask);
3237   return "andcc\t%0, %1, %%g0";
3239   [(set_attr "type" "compare")])
3242 ;; Conversions between float, double and long double.
3244 (define_insn "extendsfdf2"
3245   [(set (match_operand:DF 0 "register_operand" "=e")
3246         (float_extend:DF
3247          (match_operand:SF 1 "register_operand" "f")))]
3248   "TARGET_FPU"
3249   "fstod\t%1, %0"
3250   [(set_attr "type" "fp")
3251    (set_attr "fptype" "double")])
3253 (define_expand "extendsftf2"
3254   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3255         (float_extend:TF
3256          (match_operand:SF 1 "register_operand" "")))]
3257   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3258   "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3260 (define_insn "*extendsftf2_hq"
3261   [(set (match_operand:TF 0 "register_operand" "=e")
3262         (float_extend:TF
3263          (match_operand:SF 1 "register_operand" "f")))]
3264   "TARGET_FPU && TARGET_HARD_QUAD"
3265   "fstoq\t%1, %0"
3266   [(set_attr "type" "fp")])
3268 (define_expand "extenddftf2"
3269   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3270         (float_extend:TF
3271          (match_operand:DF 1 "register_operand" "")))]
3272   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3273   "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3275 (define_insn "*extenddftf2_hq"
3276   [(set (match_operand:TF 0 "register_operand" "=e")
3277         (float_extend:TF
3278          (match_operand:DF 1 "register_operand" "e")))]
3279   "TARGET_FPU && TARGET_HARD_QUAD"
3280   "fdtoq\t%1, %0"
3281   [(set_attr "type" "fp")])
3283 (define_insn "truncdfsf2"
3284   [(set (match_operand:SF 0 "register_operand" "=f")
3285         (float_truncate:SF
3286          (match_operand:DF 1 "register_operand" "e")))]
3287   "TARGET_FPU"
3288   "fdtos\t%1, %0"
3289   [(set_attr "type" "fp")
3290    (set_attr "fptype" "double")])
3292 (define_expand "trunctfsf2"
3293   [(set (match_operand:SF 0 "register_operand" "")
3294         (float_truncate:SF
3295          (match_operand:TF 1 "general_operand" "")))]
3296   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3297   "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3299 (define_insn "*trunctfsf2_hq"
3300   [(set (match_operand:SF 0 "register_operand" "=f")
3301         (float_truncate:SF
3302          (match_operand:TF 1 "register_operand" "e")))]
3303   "TARGET_FPU && TARGET_HARD_QUAD"
3304   "fqtos\t%1, %0"
3305   [(set_attr "type" "fp")])
3307 (define_expand "trunctfdf2"
3308   [(set (match_operand:DF 0 "register_operand" "")
3309         (float_truncate:DF
3310          (match_operand:TF 1 "general_operand" "")))]
3311   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3312   "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3314 (define_insn "*trunctfdf2_hq"
3315   [(set (match_operand:DF 0 "register_operand" "=e")
3316         (float_truncate:DF
3317          (match_operand:TF 1 "register_operand" "e")))]
3318   "TARGET_FPU && TARGET_HARD_QUAD"
3319   "fqtod\t%1, %0"
3320   [(set_attr "type" "fp")])
3323 ;; Conversion between fixed point and floating point.
3325 (define_insn "floatsisf2"
3326   [(set (match_operand:SF 0 "register_operand" "=f")
3327         (float:SF (match_operand:SI 1 "register_operand" "f")))]
3328   "TARGET_FPU"
3329   "fitos\t%1, %0"
3330   [(set_attr "type" "fp")
3331    (set_attr "fptype" "double")])
3333 (define_insn "floatsidf2"
3334   [(set (match_operand:DF 0 "register_operand" "=e")
3335         (float:DF (match_operand:SI 1 "register_operand" "f")))]
3336   "TARGET_FPU"
3337   "fitod\t%1, %0"
3338   [(set_attr "type" "fp")
3339    (set_attr "fptype" "double")])
3341 (define_expand "floatsitf2"
3342   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3343         (float:TF (match_operand:SI 1 "register_operand" "")))]
3344   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3345   "emit_tfmode_cvt (FLOAT, operands); DONE;")
3347 (define_insn "*floatsitf2_hq"
3348   [(set (match_operand:TF 0 "register_operand" "=e")
3349         (float:TF (match_operand:SI 1 "register_operand" "f")))]
3350   "TARGET_FPU && TARGET_HARD_QUAD"
3351   "fitoq\t%1, %0"
3352   [(set_attr "type" "fp")])
3354 (define_expand "floatunssitf2"
3355   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3356         (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
3357   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3358   "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3360 ;; Now the same for 64 bit sources.
3362 (define_insn "floatdisf2"
3363   [(set (match_operand:SF 0 "register_operand" "=f")
3364         (float:SF (match_operand:DI 1 "register_operand" "e")))]
3365   "TARGET_V9 && TARGET_FPU"
3366   "fxtos\t%1, %0"
3367   [(set_attr "type" "fp")
3368    (set_attr "fptype" "double")])
3370 (define_expand "floatunsdisf2"
3371   [(use (match_operand:SF 0 "register_operand" ""))
3372    (use (match_operand:DI 1 "general_operand" ""))]
3373   "TARGET_ARCH64 && TARGET_FPU"
3374   "sparc_emit_floatunsdi (operands, SFmode); DONE;")
3376 (define_insn "floatdidf2"
3377   [(set (match_operand:DF 0 "register_operand" "=e")
3378         (float:DF (match_operand:DI 1 "register_operand" "e")))]
3379   "TARGET_V9 && TARGET_FPU"
3380   "fxtod\t%1, %0"
3381   [(set_attr "type" "fp")
3382    (set_attr "fptype" "double")])
3384 (define_expand "floatunsdidf2"
3385   [(use (match_operand:DF 0 "register_operand" ""))
3386    (use (match_operand:DI 1 "general_operand" ""))]
3387   "TARGET_ARCH64 && TARGET_FPU"
3388   "sparc_emit_floatunsdi (operands, DFmode); DONE;")
3390 (define_expand "floatditf2"
3391   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3392         (float:TF (match_operand:DI 1 "register_operand" "")))]
3393   "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3394   "emit_tfmode_cvt (FLOAT, operands); DONE;")
3396 (define_insn "*floatditf2_hq"
3397   [(set (match_operand:TF 0 "register_operand" "=e")
3398         (float:TF (match_operand:DI 1 "register_operand" "e")))]
3399   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3400   "fxtoq\t%1, %0"
3401   [(set_attr "type" "fp")])
3403 (define_expand "floatunsditf2"
3404   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3405         (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
3406   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3407   "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3409 ;; Convert a float to an actual integer.
3410 ;; Truncation is performed as part of the conversion.
3412 (define_insn "fix_truncsfsi2"
3413   [(set (match_operand:SI 0 "register_operand" "=f")
3414         (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3415   "TARGET_FPU"
3416   "fstoi\t%1, %0"
3417   [(set_attr "type" "fp")
3418    (set_attr "fptype" "double")])
3420 (define_insn "fix_truncdfsi2"
3421   [(set (match_operand:SI 0 "register_operand" "=f")
3422         (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3423   "TARGET_FPU"
3424   "fdtoi\t%1, %0"
3425   [(set_attr "type" "fp")
3426    (set_attr "fptype" "double")])
3428 (define_expand "fix_trunctfsi2"
3429   [(set (match_operand:SI 0 "register_operand" "")
3430         (fix:SI (match_operand:TF 1 "general_operand" "")))]
3431   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3432   "emit_tfmode_cvt (FIX, operands); DONE;")
3434 (define_insn "*fix_trunctfsi2_hq"
3435   [(set (match_operand:SI 0 "register_operand" "=f")
3436         (fix:SI (match_operand:TF 1 "register_operand" "e")))]
3437   "TARGET_FPU && TARGET_HARD_QUAD"
3438   "fqtoi\t%1, %0"
3439   [(set_attr "type" "fp")])
3441 (define_expand "fixuns_trunctfsi2"
3442   [(set (match_operand:SI 0 "register_operand" "")
3443         (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
3444   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3445   "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3447 ;; Now the same, for V9 targets
3449 (define_insn "fix_truncsfdi2"
3450   [(set (match_operand:DI 0 "register_operand" "=e")
3451         (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3452   "TARGET_V9 && TARGET_FPU"
3453   "fstox\t%1, %0"
3454   [(set_attr "type" "fp")
3455    (set_attr "fptype" "double")])
3457 (define_expand "fixuns_truncsfdi2"
3458   [(use (match_operand:DI 0 "register_operand" ""))
3459    (use (match_operand:SF 1 "general_operand" ""))]
3460   "TARGET_ARCH64 && TARGET_FPU"
3461   "sparc_emit_fixunsdi (operands, SFmode); DONE;")
3463 (define_insn "fix_truncdfdi2"
3464   [(set (match_operand:DI 0 "register_operand" "=e")
3465         (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3466   "TARGET_V9 && TARGET_FPU"
3467   "fdtox\t%1, %0"
3468   [(set_attr "type" "fp")
3469    (set_attr "fptype" "double")])
3471 (define_expand "fixuns_truncdfdi2"
3472   [(use (match_operand:DI 0 "register_operand" ""))
3473    (use (match_operand:DF 1 "general_operand" ""))]
3474   "TARGET_ARCH64 && TARGET_FPU"
3475   "sparc_emit_fixunsdi (operands, DFmode); DONE;")
3477 (define_expand "fix_trunctfdi2"
3478   [(set (match_operand:DI 0 "register_operand" "")
3479         (fix:DI (match_operand:TF 1 "general_operand" "")))]
3480   "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3481   "emit_tfmode_cvt (FIX, operands); DONE;")
3483 (define_insn "*fix_trunctfdi2_hq"
3484   [(set (match_operand:DI 0 "register_operand" "=e")
3485         (fix:DI (match_operand:TF 1 "register_operand" "e")))]
3486   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3487   "fqtox\t%1, %0"
3488   [(set_attr "type" "fp")])
3490 (define_expand "fixuns_trunctfdi2"
3491   [(set (match_operand:DI 0 "register_operand" "")
3492         (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
3493   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3494   "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3497 ;; Integer addition/subtraction instructions.
3499 (define_expand "adddi3"
3500   [(set (match_operand:DI 0 "register_operand" "")
3501         (plus:DI (match_operand:DI 1 "register_operand" "")
3502                  (match_operand:DI 2 "arith_double_add_operand" "")))]
3503   ""
3505   if (! TARGET_ARCH64)
3506     {
3507       emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3508                           gen_rtx_SET (VOIDmode, operands[0],
3509                                    gen_rtx_PLUS (DImode, operands[1],
3510                                                  operands[2])),
3511                           gen_rtx_CLOBBER (VOIDmode,
3512                                    gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3513       DONE;
3514     }
3517 (define_insn_and_split "*adddi3_insn_sp32"
3518   [(set (match_operand:DI 0 "register_operand" "=r")
3519         (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
3520                  (match_operand:DI 2 "arith_double_operand" "rHI")))
3521    (clobber (reg:CC 100))]
3522   "! TARGET_ARCH64"
3523   "#"
3524   "&& reload_completed"
3525   [(parallel [(set (reg:CC_NOOV 100)
3526                    (compare:CC_NOOV (plus:SI (match_dup 4)
3527                                              (match_dup 5))
3528                                     (const_int 0)))
3529               (set (match_dup 3)
3530                    (plus:SI (match_dup 4) (match_dup 5)))])
3531    (set (match_dup 6)
3532         (plus:SI (plus:SI (match_dup 7)
3533                           (match_dup 8))
3534                  (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3536   operands[3] = gen_lowpart (SImode, operands[0]);
3537   operands[4] = gen_lowpart (SImode, operands[1]);
3538   operands[5] = gen_lowpart (SImode, operands[2]);
3539   operands[6] = gen_highpart (SImode, operands[0]);
3540   operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
3541 #if HOST_BITS_PER_WIDE_INT == 32
3542   if (GET_CODE (operands[2]) == CONST_INT)
3543     {
3544       if (INTVAL (operands[2]) < 0)
3545         operands[8] = constm1_rtx;
3546       else
3547         operands[8] = const0_rtx;
3548     }
3549   else
3550 #endif
3551     operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3553   [(set_attr "length" "2")])
3555 ;; LTU here means "carry set"
3556 (define_insn "addx"
3557   [(set (match_operand:SI 0 "register_operand" "=r")
3558         (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3559                           (match_operand:SI 2 "arith_operand" "rI"))
3560                  (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3561   ""
3562   "addx\t%1, %2, %0"
3563   [(set_attr "type" "ialuX")])
3565 (define_insn_and_split "*addx_extend_sp32"
3566   [(set (match_operand:DI 0 "register_operand" "=r")
3567         (zero_extend:DI (plus:SI (plus:SI
3568                                   (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3569                                   (match_operand:SI 2 "arith_operand" "rI"))
3570                                  (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
3571   "! TARGET_ARCH64"
3572   "#"
3573   "&& reload_completed"
3574   [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
3575                                (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
3576    (set (match_dup 4) (const_int 0))]
3577   "operands[3] = gen_lowpart (SImode, operands[0]);
3578    operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
3579   [(set_attr "length" "2")])
3581 (define_insn "*addx_extend_sp64"
3582   [(set (match_operand:DI 0 "register_operand" "=r")
3583         (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3584                                           (match_operand:SI 2 "arith_operand" "rI"))
3585                                  (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
3586   "TARGET_ARCH64"
3587   "addx\t%r1, %2, %0"
3588   [(set_attr "type" "ialuX")])
3590 (define_insn_and_split "*adddi3_extend_sp32"
3591   [(set (match_operand:DI 0 "register_operand" "=r")
3592         (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
3593                  (match_operand:DI 2 "register_operand" "r")))
3594    (clobber (reg:CC 100))]
3595   "! TARGET_ARCH64"
3596   "#"
3597   "&& reload_completed"
3598   [(parallel [(set (reg:CC_NOOV 100)
3599                    (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
3600                                     (const_int 0)))
3601               (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
3602    (set (match_dup 6)
3603         (plus:SI (plus:SI (match_dup 4) (const_int 0))
3604                  (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3605   "operands[3] = gen_lowpart (SImode, operands[2]);
3606    operands[4] = gen_highpart (SImode, operands[2]);
3607    operands[5] = gen_lowpart (SImode, operands[0]);
3608    operands[6] = gen_highpart (SImode, operands[0]);"
3609   [(set_attr "length" "2")])
3611 (define_insn "*adddi3_sp64"
3612   [(set (match_operand:DI 0 "register_operand" "=r,r")
3613         (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
3614                  (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3615   "TARGET_ARCH64"
3616   "@
3617    add\t%1, %2, %0
3618    sub\t%1, -%2, %0")
3620 (define_insn "addsi3"
3621   [(set (match_operand:SI 0 "register_operand" "=r,r,d")
3622         (plus:SI (match_operand:SI 1 "register_operand" "%r,r,d")
3623                  (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
3624   ""
3625   "@
3626    add\t%1, %2, %0
3627    sub\t%1, -%2, %0
3628    fpadd32s\t%1, %2, %0"
3629   [(set_attr "type" "*,*,fga")
3630    (set_attr "fptype" "*,*,single")])
3632 (define_insn "*cmp_cc_plus"
3633   [(set (reg:CC_NOOV 100)
3634         (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
3635                                   (match_operand:SI 1 "arith_operand" "rI"))
3636                          (const_int 0)))]
3637   ""
3638   "addcc\t%0, %1, %%g0"
3639   [(set_attr "type" "compare")])
3641 (define_insn "*cmp_ccx_plus"
3642   [(set (reg:CCX_NOOV 100)
3643         (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_operand" "%r")
3644                                    (match_operand:DI 1 "arith_operand" "rI"))
3645                           (const_int 0)))]
3646   "TARGET_ARCH64"
3647   "addcc\t%0, %1, %%g0"
3648   [(set_attr "type" "compare")])
3650 (define_insn "*cmp_cc_plus_set"
3651   [(set (reg:CC_NOOV 100)
3652         (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3653                                   (match_operand:SI 2 "arith_operand" "rI"))
3654                          (const_int 0)))
3655    (set (match_operand:SI 0 "register_operand" "=r")
3656         (plus:SI (match_dup 1) (match_dup 2)))]
3657   ""
3658   "addcc\t%1, %2, %0"
3659   [(set_attr "type" "compare")])
3661 (define_insn "*cmp_ccx_plus_set"
3662   [(set (reg:CCX_NOOV 100)
3663         (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_operand" "%r")
3664                                    (match_operand:DI 2 "arith_operand" "rI"))
3665                           (const_int 0)))
3666    (set (match_operand:DI 0 "register_operand" "=r")
3667         (plus:DI (match_dup 1) (match_dup 2)))]
3668   "TARGET_ARCH64"
3669   "addcc\t%1, %2, %0"
3670   [(set_attr "type" "compare")])
3672 (define_expand "subdi3"
3673   [(set (match_operand:DI 0 "register_operand" "")
3674         (minus:DI (match_operand:DI 1 "register_operand" "")
3675                   (match_operand:DI 2 "arith_double_add_operand" "")))]
3676   ""
3678   if (! TARGET_ARCH64)
3679     {
3680       emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3681                           gen_rtx_SET (VOIDmode, operands[0],
3682                                    gen_rtx_MINUS (DImode, operands[1],
3683                                                   operands[2])),
3684                           gen_rtx_CLOBBER (VOIDmode,
3685                                    gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3686       DONE;
3687     }
3690 (define_insn_and_split "*subdi3_insn_sp32"
3691   [(set (match_operand:DI 0 "register_operand" "=r")
3692         (minus:DI (match_operand:DI 1 "register_operand" "r")
3693                   (match_operand:DI 2 "arith_double_operand" "rHI")))
3694    (clobber (reg:CC 100))]
3695   "! TARGET_ARCH64"
3696   "#"
3697   "&& reload_completed"
3698   [(parallel [(set (reg:CC_NOOV 100)
3699                    (compare:CC_NOOV (minus:SI (match_dup 4)
3700                                               (match_dup 5))
3701                                     (const_int 0)))
3702               (set (match_dup 3)
3703                    (minus:SI (match_dup 4) (match_dup 5)))])
3704    (set (match_dup 6)
3705         (minus:SI (minus:SI (match_dup 7)
3706                             (match_dup 8))
3707                   (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3709   operands[3] = gen_lowpart (SImode, operands[0]);
3710   operands[4] = gen_lowpart (SImode, operands[1]);
3711   operands[5] = gen_lowpart (SImode, operands[2]);
3712   operands[6] = gen_highpart (SImode, operands[0]);
3713   operands[7] = gen_highpart (SImode, operands[1]);
3714 #if HOST_BITS_PER_WIDE_INT == 32
3715   if (GET_CODE (operands[2]) == CONST_INT)
3716     {
3717       if (INTVAL (operands[2]) < 0)
3718         operands[8] = constm1_rtx;
3719       else
3720         operands[8] = const0_rtx;
3721     }
3722   else
3723 #endif
3724     operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3726   [(set_attr "length" "2")])
3728 ;; LTU here means "carry set"
3729 (define_insn "subx"
3730   [(set (match_operand:SI 0 "register_operand" "=r")
3731         (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3732                             (match_operand:SI 2 "arith_operand" "rI"))
3733                   (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3734   ""
3735   "subx\t%r1, %2, %0"
3736   [(set_attr "type" "ialuX")])
3738 (define_insn "*subx_extend_sp64"
3739   [(set (match_operand:DI 0 "register_operand" "=r")
3740         (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3741                                             (match_operand:SI 2 "arith_operand" "rI"))
3742                                   (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
3743   "TARGET_ARCH64"
3744   "subx\t%r1, %2, %0"
3745   [(set_attr "type" "ialuX")])
3747 (define_insn_and_split "*subx_extend"
3748   [(set (match_operand:DI 0 "register_operand" "=r")
3749         (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3750                                             (match_operand:SI 2 "arith_operand" "rI"))
3751                                   (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
3752   "! TARGET_ARCH64"
3753   "#"
3754   "&& reload_completed"
3755   [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
3756                                 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
3757    (set (match_dup 4) (const_int 0))]
3758   "operands[3] = gen_lowpart (SImode, operands[0]);
3759    operands[4] = gen_highpart (SImode, operands[0]);"
3760   [(set_attr "length" "2")])
3762 (define_insn_and_split "*subdi3_extend_sp32"
3763   [(set (match_operand:DI 0 "register_operand" "=r")
3764       (minus:DI (match_operand:DI 1 "register_operand" "r")
3765                 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
3766    (clobber (reg:CC 100))]
3767   "! TARGET_ARCH64"
3768   "#"
3769   "&& reload_completed"
3770   [(parallel [(set (reg:CC_NOOV 100)
3771                    (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
3772                                     (const_int 0)))
3773               (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
3774    (set (match_dup 6)
3775         (minus:SI (minus:SI (match_dup 4) (const_int 0))
3776                   (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3777   "operands[3] = gen_lowpart (SImode, operands[1]);
3778    operands[4] = gen_highpart (SImode, operands[1]);
3779    operands[5] = gen_lowpart (SImode, operands[0]);
3780    operands[6] = gen_highpart (SImode, operands[0]);"
3781   [(set_attr "length" "2")])
3783 (define_insn "*subdi3_sp64"
3784   [(set (match_operand:DI 0 "register_operand" "=r,r")
3785         (minus:DI (match_operand:DI 1 "register_operand" "r,r")
3786                   (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3787   "TARGET_ARCH64"
3788   "@
3789    sub\t%1, %2, %0
3790    add\t%1, -%2, %0")
3792 (define_insn "subsi3"
3793   [(set (match_operand:SI 0 "register_operand" "=r,r,d")
3794         (minus:SI (match_operand:SI 1 "register_operand" "r,r,d")
3795                   (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
3796   ""
3797   "@
3798    sub\t%1, %2, %0
3799    add\t%1, -%2, %0
3800    fpsub32s\t%1, %2, %0"
3801   [(set_attr "type" "*,*,fga")
3802    (set_attr "fptype" "*,*,single")])
3804 (define_insn "*cmp_minus_cc"
3805   [(set (reg:CC_NOOV 100)
3806         (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
3807                                    (match_operand:SI 1 "arith_operand" "rI"))
3808                          (const_int 0)))]
3809   ""
3810   "subcc\t%r0, %1, %%g0"
3811   [(set_attr "type" "compare")])
3813 (define_insn "*cmp_minus_ccx"
3814   [(set (reg:CCX_NOOV 100)
3815         (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
3816                                     (match_operand:DI 1 "arith_operand" "rI"))
3817                           (const_int 0)))]
3818   "TARGET_ARCH64"
3819   "subcc\t%0, %1, %%g0"
3820   [(set_attr "type" "compare")])
3822 (define_insn "cmp_minus_cc_set"
3823   [(set (reg:CC_NOOV 100)
3824         (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3825                                    (match_operand:SI 2 "arith_operand" "rI"))
3826                          (const_int 0)))
3827    (set (match_operand:SI 0 "register_operand" "=r")
3828         (minus:SI (match_dup 1) (match_dup 2)))]
3829   ""
3830   "subcc\t%r1, %2, %0"
3831   [(set_attr "type" "compare")])
3833 (define_insn "*cmp_minus_ccx_set"
3834   [(set (reg:CCX_NOOV 100)
3835         (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
3836                                     (match_operand:DI 2 "arith_operand" "rI"))
3837                           (const_int 0)))
3838    (set (match_operand:DI 0 "register_operand" "=r")
3839         (minus:DI (match_dup 1) (match_dup 2)))]
3840   "TARGET_ARCH64"
3841   "subcc\t%1, %2, %0"
3842   [(set_attr "type" "compare")])
3845 ;; Integer multiply/divide instructions.
3847 ;; The 32-bit multiply/divide instructions are deprecated on v9, but at
3848 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
3850 (define_insn "mulsi3"
3851   [(set (match_operand:SI 0 "register_operand" "=r")
3852         (mult:SI (match_operand:SI 1 "arith_operand" "%r")
3853                  (match_operand:SI 2 "arith_operand" "rI")))]
3854   "TARGET_HARD_MUL"
3855   "smul\t%1, %2, %0"
3856   [(set_attr "type" "imul")])
3858 (define_expand "muldi3"
3859   [(set (match_operand:DI 0 "register_operand" "")
3860         (mult:DI (match_operand:DI 1 "arith_operand" "")
3861                  (match_operand:DI 2 "arith_operand" "")))]
3862   "TARGET_ARCH64 || TARGET_V8PLUS"
3864   if (TARGET_V8PLUS)
3865     {
3866       emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
3867       DONE;
3868     }
3871 (define_insn "*muldi3_sp64"
3872   [(set (match_operand:DI 0 "register_operand" "=r")
3873         (mult:DI (match_operand:DI 1 "arith_operand" "%r")
3874                  (match_operand:DI 2 "arith_operand" "rI")))]
3875   "TARGET_ARCH64"
3876   "mulx\t%1, %2, %0"
3877   [(set_attr "type" "imul")])
3879 ;; V8plus wide multiply.
3880 ;; XXX
3881 (define_insn "muldi3_v8plus"
3882   [(set (match_operand:DI 0 "register_operand" "=r,h")
3883         (mult:DI (match_operand:DI 1 "arith_operand" "%r,0")
3884                  (match_operand:DI 2 "arith_operand" "rI,rI")))
3885    (clobber (match_scratch:SI 3 "=&h,X"))
3886    (clobber (match_scratch:SI 4 "=&h,X"))]
3887   "TARGET_V8PLUS"
3889   if (sparc_check_64 (operands[1], insn) <= 0)
3890     output_asm_insn ("srl\t%L1, 0, %L1", operands);
3891   if (which_alternative == 1)
3892     output_asm_insn ("sllx\t%H1, 32, %H1", operands);
3893   if (GET_CODE (operands[2]) == CONST_INT)
3894     {
3895       if (which_alternative == 1)
3896         return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %2, %L0\;srlx\t%L0, 32, %H0";
3897       else
3898         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";
3899     }
3900   else if (rtx_equal_p (operands[1], operands[2]))
3901     {
3902       if (which_alternative == 1)
3903         return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %H1, %L0\;srlx\t%L0, 32, %H0";
3904       else
3905         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";
3906     }
3907   if (sparc_check_64 (operands[2], insn) <= 0)
3908     output_asm_insn ("srl\t%L2, 0, %L2", operands);
3909   if (which_alternative == 1)
3910     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";
3911   else
3912     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";
3914   [(set_attr "type" "multi")
3915    (set_attr "length" "9,8")])
3917 (define_insn "*cmp_mul_set"
3918   [(set (reg:CC 100)
3919         (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
3920                     (match_operand:SI 2 "arith_operand" "rI"))
3921                     (const_int 0)))
3922    (set (match_operand:SI 0 "register_operand" "=r")
3923         (mult:SI (match_dup 1) (match_dup 2)))]
3924   "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
3925   "smulcc\t%1, %2, %0"
3926   [(set_attr "type" "imul")])
3928 (define_expand "mulsidi3"
3929   [(set (match_operand:DI 0 "register_operand" "")
3930         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
3931                  (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
3932   "TARGET_HARD_MUL"
3934   if (CONSTANT_P (operands[2]))
3935     {
3936       if (TARGET_V8PLUS)
3937         emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
3938                                               operands[2]));
3939       else if (TARGET_ARCH32)
3940         emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
3941                                             operands[2]));
3942       else 
3943         emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
3944                                             operands[2]));
3945       DONE;
3946     }
3947   if (TARGET_V8PLUS)
3948     {
3949       emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
3950       DONE;
3951     }
3954 ;; V9 puts the 64-bit product in a 64-bit register.  Only out or global
3955 ;; registers can hold 64-bit values in the V8plus environment.
3956 ;; XXX
3957 (define_insn "mulsidi3_v8plus"
3958   [(set (match_operand:DI 0 "register_operand" "=h,r")
3959         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
3960                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
3961    (clobber (match_scratch:SI 3 "=X,&h"))]
3962   "TARGET_V8PLUS"
3963   "@
3964    smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
3965    smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
3966   [(set_attr "type" "multi")
3967    (set_attr "length" "2,3")])
3969 ;; XXX
3970 (define_insn "const_mulsidi3_v8plus"
3971   [(set (match_operand:DI 0 "register_operand" "=h,r")
3972         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
3973                  (match_operand:DI 2 "small_int_operand" "I,I")))
3974    (clobber (match_scratch:SI 3 "=X,&h"))]
3975   "TARGET_V8PLUS"
3976   "@
3977    smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
3978    smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
3979   [(set_attr "type" "multi")
3980    (set_attr "length" "2,3")])
3982 ;; XXX
3983 (define_insn "*mulsidi3_sp32"
3984   [(set (match_operand:DI 0 "register_operand" "=r")
3985         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
3986                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
3987   "TARGET_HARD_MUL32"
3989   return TARGET_SPARCLET
3990          ? "smuld\t%1, %2, %L0"
3991          : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
3993   [(set (attr "type")
3994         (if_then_else (eq_attr "isa" "sparclet")
3995                       (const_string "imul") (const_string "multi")))
3996    (set (attr "length")
3997         (if_then_else (eq_attr "isa" "sparclet")
3998                       (const_int 1) (const_int 2)))])
4000 (define_insn "*mulsidi3_sp64"
4001   [(set (match_operand:DI 0 "register_operand" "=r")
4002         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4003                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4004   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4005   "smul\t%1, %2, %0"
4006   [(set_attr "type" "imul")])
4008 ;; Extra pattern, because sign_extend of a constant isn't valid.
4010 ;; XXX
4011 (define_insn "const_mulsidi3_sp32"
4012   [(set (match_operand:DI 0 "register_operand" "=r")
4013         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4014                  (match_operand:DI 2 "small_int_operand" "I")))]
4015   "TARGET_HARD_MUL32"
4017   return TARGET_SPARCLET
4018          ? "smuld\t%1, %2, %L0"
4019          : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4021   [(set (attr "type")
4022         (if_then_else (eq_attr "isa" "sparclet")
4023                       (const_string "imul") (const_string "multi")))
4024    (set (attr "length")
4025         (if_then_else (eq_attr "isa" "sparclet")
4026                       (const_int 1) (const_int 2)))])
4028 (define_insn "const_mulsidi3_sp64"
4029   [(set (match_operand:DI 0 "register_operand" "=r")
4030         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4031                  (match_operand:DI 2 "small_int_operand" "I")))]
4032   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4033   "smul\t%1, %2, %0"
4034   [(set_attr "type" "imul")])
4036 (define_expand "smulsi3_highpart"
4037   [(set (match_operand:SI 0 "register_operand" "")
4038         (truncate:SI
4039          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4040                                (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
4041                       (const_int 32))))]
4042   "TARGET_HARD_MUL && TARGET_ARCH32"
4044   if (CONSTANT_P (operands[2]))
4045     {
4046       if (TARGET_V8PLUS)
4047         {
4048           emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
4049                                                         operands[1],
4050                                                         operands[2],
4051                                                         GEN_INT (32)));
4052           DONE;
4053         }
4054       emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
4055       DONE;
4056     }
4057   if (TARGET_V8PLUS)
4058     {
4059       emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
4060                                               operands[2], GEN_INT (32)));
4061       DONE;
4062     }
4065 ;; XXX
4066 (define_insn "smulsi3_highpart_v8plus"
4067   [(set (match_operand:SI 0 "register_operand" "=h,r")
4068         (truncate:SI
4069          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4070                                (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4071                       (match_operand:SI 3 "small_int_operand" "I,I"))))
4072    (clobber (match_scratch:SI 4 "=X,&h"))]
4073   "TARGET_V8PLUS"
4074   "@
4075    smul\t%1, %2, %0\;srlx\t%0, %3, %0
4076    smul\t%1, %2, %4\;srlx\t%4, %3, %0"
4077   [(set_attr "type" "multi")
4078    (set_attr "length" "2")])
4080 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
4081 ;; XXX
4082 (define_insn ""
4083   [(set (match_operand:SI 0 "register_operand" "=h,r")
4084         (subreg:SI
4085          (lshiftrt:DI
4086           (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4087                    (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4088           (match_operand:SI 3 "small_int_operand" "I,I"))
4089          4))
4090    (clobber (match_scratch:SI 4 "=X,&h"))]
4091   "TARGET_V8PLUS"
4092   "@
4093    smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4094    smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4095   [(set_attr "type" "multi")
4096    (set_attr "length" "2")])
4098 ;; XXX
4099 (define_insn "const_smulsi3_highpart_v8plus"
4100   [(set (match_operand:SI 0 "register_operand" "=h,r")
4101         (truncate:SI
4102          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4103                                (match_operand:DI 2 "small_int_operand" "I,I"))
4104                       (match_operand:SI 3 "small_int_operand" "I,I"))))
4105    (clobber (match_scratch:SI 4 "=X,&h"))]
4106   "TARGET_V8PLUS"
4107   "@
4108    smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4109    smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4110   [(set_attr "type" "multi")
4111    (set_attr "length" "2")])
4113 ;; XXX
4114 (define_insn "*smulsi3_highpart_sp32"
4115   [(set (match_operand:SI 0 "register_operand" "=r")
4116         (truncate:SI
4117          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4118                                (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
4119                       (const_int 32))))]
4120   "TARGET_HARD_MUL32"
4121   "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4122   [(set_attr "type" "multi")
4123    (set_attr "length" "2")])
4125 ;; XXX
4126 (define_insn "const_smulsi3_highpart"
4127   [(set (match_operand:SI 0 "register_operand" "=r")
4128         (truncate:SI
4129          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4130                                (match_operand:DI 2 "small_int_operand" "i"))
4131                       (const_int 32))))]
4132   "TARGET_HARD_MUL32"
4133   "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4134   [(set_attr "type" "multi")
4135    (set_attr "length" "2")])
4137 (define_expand "umulsidi3"
4138   [(set (match_operand:DI 0 "register_operand" "")
4139         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4140                  (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
4141   "TARGET_HARD_MUL"
4143   if (CONSTANT_P (operands[2]))
4144     {
4145       if (TARGET_V8PLUS)
4146         emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
4147                                                operands[2]));
4148       else if (TARGET_ARCH32)
4149         emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
4150                                              operands[2]));
4151       else 
4152         emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
4153                                              operands[2]));
4154       DONE;
4155     }
4156   if (TARGET_V8PLUS)
4157     {
4158       emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
4159       DONE;
4160     }
4163 ;; XXX
4164 (define_insn "umulsidi3_v8plus"
4165   [(set (match_operand:DI 0 "register_operand" "=h,r")
4166         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4167                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4168    (clobber (match_scratch:SI 3 "=X,&h"))]
4169   "TARGET_V8PLUS"
4170   "@
4171    umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4172    umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4173   [(set_attr "type" "multi")
4174    (set_attr "length" "2,3")])
4176 ;; XXX
4177 (define_insn "*umulsidi3_sp32"
4178   [(set (match_operand:DI 0 "register_operand" "=r")
4179         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4180                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4181   "TARGET_HARD_MUL32"
4183   return TARGET_SPARCLET
4184          ? "umuld\t%1, %2, %L0"
4185          : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
4187   [(set (attr "type")
4188         (if_then_else (eq_attr "isa" "sparclet")
4189                       (const_string "imul") (const_string "multi")))
4190    (set (attr "length")
4191         (if_then_else (eq_attr "isa" "sparclet")
4192                       (const_int 1) (const_int 2)))])
4194 (define_insn "*umulsidi3_sp64"
4195   [(set (match_operand:DI 0 "register_operand" "=r")
4196         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4197                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4198   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4199   "umul\t%1, %2, %0"
4200   [(set_attr "type" "imul")])
4202 ;; Extra pattern, because sign_extend of a constant isn't valid.
4204 ;; XXX
4205 (define_insn "const_umulsidi3_sp32"
4206   [(set (match_operand:DI 0 "register_operand" "=r")
4207         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4208                  (match_operand:DI 2 "uns_small_int_operand" "")))]
4209   "TARGET_HARD_MUL32"
4211   return TARGET_SPARCLET
4212          ? "umuld\t%1, %s2, %L0"
4213          : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
4215   [(set (attr "type")
4216         (if_then_else (eq_attr "isa" "sparclet")
4217                       (const_string "imul") (const_string "multi")))
4218    (set (attr "length")
4219         (if_then_else (eq_attr "isa" "sparclet")
4220                       (const_int 1) (const_int 2)))])
4222 (define_insn "const_umulsidi3_sp64"
4223   [(set (match_operand:DI 0 "register_operand" "=r")
4224         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4225                  (match_operand:DI 2 "uns_small_int_operand" "")))]
4226   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4227   "umul\t%1, %s2, %0"
4228   [(set_attr "type" "imul")])
4230 ;; XXX
4231 (define_insn "const_umulsidi3_v8plus"
4232   [(set (match_operand:DI 0 "register_operand" "=h,r")
4233         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4234                  (match_operand:DI 2 "uns_small_int_operand" "")))
4235    (clobber (match_scratch:SI 3 "=X,h"))]
4236   "TARGET_V8PLUS"
4237   "@
4238    umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
4239    umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4240   [(set_attr "type" "multi")
4241    (set_attr "length" "2,3")])
4243 (define_expand "umulsi3_highpart"
4244   [(set (match_operand:SI 0 "register_operand" "")
4245         (truncate:SI
4246          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4247                                (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
4248                       (const_int 32))))]
4249   "TARGET_HARD_MUL && TARGET_ARCH32"
4251   if (CONSTANT_P (operands[2]))
4252     {
4253       if (TARGET_V8PLUS)
4254         {
4255           emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
4256                                                         operands[1],
4257                                                         operands[2],
4258                                                         GEN_INT (32)));
4259           DONE;
4260         }
4261       emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
4262       DONE;
4263     }
4264   if (TARGET_V8PLUS)
4265     {
4266       emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
4267                                               operands[2], GEN_INT (32)));
4268       DONE;
4269     }
4272 ;; XXX
4273 (define_insn "umulsi3_highpart_v8plus"
4274   [(set (match_operand:SI 0 "register_operand" "=h,r")
4275         (truncate:SI
4276          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4277                                (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4278                       (match_operand:SI 3 "small_int_operand" "I,I"))))
4279    (clobber (match_scratch:SI 4 "=X,h"))]
4280   "TARGET_V8PLUS"
4281   "@
4282    umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4283    umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4284   [(set_attr "type" "multi")
4285    (set_attr "length" "2")])
4287 ;; XXX
4288 (define_insn "const_umulsi3_highpart_v8plus"
4289   [(set (match_operand:SI 0 "register_operand" "=h,r")
4290         (truncate:SI
4291          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4292                                (match_operand:DI 2 "uns_small_int_operand" ""))
4293                       (match_operand:SI 3 "small_int_operand" "I,I"))))
4294    (clobber (match_scratch:SI 4 "=X,h"))]
4295   "TARGET_V8PLUS"
4296   "@
4297    umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
4298    umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
4299   [(set_attr "type" "multi")
4300    (set_attr "length" "2")])
4302 ;; XXX
4303 (define_insn "*umulsi3_highpart_sp32"
4304   [(set (match_operand:SI 0 "register_operand" "=r")
4305         (truncate:SI
4306          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4307                                (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
4308                       (const_int 32))))]
4309   "TARGET_HARD_MUL32"
4310   "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
4311   [(set_attr "type" "multi")
4312    (set_attr "length" "2")])
4314 ;; XXX
4315 (define_insn "const_umulsi3_highpart"
4316   [(set (match_operand:SI 0 "register_operand" "=r")
4317         (truncate:SI
4318          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4319                                (match_operand:DI 2 "uns_small_int_operand" ""))
4320                       (const_int 32))))]
4321   "TARGET_HARD_MUL32"
4322   "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
4323   [(set_attr "type" "multi")
4324    (set_attr "length" "2")])
4326 (define_expand "divsi3"
4327   [(parallel [(set (match_operand:SI 0 "register_operand" "")
4328                    (div:SI (match_operand:SI 1 "register_operand" "")
4329                            (match_operand:SI 2 "input_operand" "")))
4330               (clobber (match_scratch:SI 3 ""))])]
4331   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4333   if (TARGET_ARCH64)
4334     {
4335       operands[3] = gen_reg_rtx(SImode);
4336       emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
4337       emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
4338                                   operands[3]));
4339       DONE;
4340     }
4343 ;; The V8 architecture specifies that there must be at least 3 instructions
4344 ;; between a write to the Y register and a use of it for correct results.
4345 ;; We try to fill one of them with a simple constant or a memory load.
4347 (define_insn "divsi3_sp32"
4348   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
4349         (div:SI (match_operand:SI 1 "register_operand" "r,r,r")
4350                 (match_operand:SI 2 "input_operand" "rI,K,m")))
4351    (clobber (match_scratch:SI 3 "=&r,&r,&r"))]
4352   "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4354   output_asm_insn ("sra\t%1, 31, %3", operands);
4355   output_asm_insn ("wr\t%3, 0, %%y", operands);
4357   switch (which_alternative)
4358     {
4359     case 0:
4360       if (TARGET_V9)
4361         return "sdiv\t%1, %2, %0";
4362       else
4363         return "nop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
4364     case 1:
4365       if (TARGET_V9)
4366         return "sethi\t%%hi(%a2), %3\n\tsdiv\t%1, %3, %0";
4367       else
4368         return "sethi\t%%hi(%a2), %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4369     case 2:
4370       if (TARGET_V9)
4371         return "ld\t%2, %3\n\tsdiv\t%1, %3, %0";
4372       else
4373         return "ld\t%2, %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4374     default:
4375       gcc_unreachable ();
4376     }
4378   [(set_attr "type" "multi")
4379    (set (attr "length")
4380         (if_then_else (eq_attr "isa" "v9")
4381                       (const_int 4) (const_int 6)))])
4383 (define_insn "divsi3_sp64"
4384   [(set (match_operand:SI 0 "register_operand" "=r")
4385         (div:SI (match_operand:SI 1 "register_operand" "r")
4386                 (match_operand:SI 2 "input_operand" "rI")))
4387    (use (match_operand:SI 3 "register_operand" "r"))]
4388   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4389   "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
4390   [(set_attr "type" "multi")
4391    (set_attr "length" "2")])
4393 (define_insn "divdi3"
4394   [(set (match_operand:DI 0 "register_operand" "=r")
4395         (div:DI (match_operand:DI 1 "register_operand" "r")
4396                 (match_operand:DI 2 "arith_operand" "rI")))]
4397   "TARGET_ARCH64"
4398   "sdivx\t%1, %2, %0"
4399   [(set_attr "type" "idiv")])
4401 (define_insn "*cmp_sdiv_cc_set"
4402   [(set (reg:CC 100)
4403         (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
4404                             (match_operand:SI 2 "arith_operand" "rI"))
4405                     (const_int 0)))
4406    (set (match_operand:SI 0 "register_operand" "=r")
4407         (div:SI (match_dup 1) (match_dup 2)))
4408    (clobber (match_scratch:SI 3 "=&r"))]
4409   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4411   output_asm_insn ("sra\t%1, 31, %3", operands);
4412   output_asm_insn ("wr\t%3, 0, %%y", operands);
4414   if (TARGET_V9)
4415     return "sdivcc\t%1, %2, %0";
4416   else
4417     return "nop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
4419   [(set_attr "type" "multi")
4420    (set (attr "length")
4421         (if_then_else (eq_attr "isa" "v9")
4422                       (const_int 3) (const_int 6)))])
4424 ;; XXX
4425 (define_expand "udivsi3"
4426   [(set (match_operand:SI 0 "register_operand" "")
4427         (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "")
4428                  (match_operand:SI 2 "input_operand" "")))]
4429   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4430   "")
4432 ;; The V8 architecture specifies that there must be at least 3 instructions
4433 ;; between a write to the Y register and a use of it for correct results.
4434 ;; We try to fill one of them with a simple constant or a memory load.
4436 (define_insn "udivsi3_sp32"
4437   [(set (match_operand:SI 0 "register_operand" "=r,&r,&r,&r")
4438         (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r,r,r,m")
4439                  (match_operand:SI 2 "input_operand" "rI,K,m,r")))]
4440   "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4442   output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4444   switch (which_alternative)
4445     {
4446     case 0:
4447       if (TARGET_V9)
4448         return "udiv\t%1, %2, %0";
4449       else
4450         return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
4451     case 1:
4452       if (TARGET_V9)
4453         return "sethi\t%%hi(%a2), %0\n\tudiv\t%1, %0, %0";
4454       else
4455         return "sethi\t%%hi(%a2), %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4456     case 2:
4457       if (TARGET_V9)
4458         return "ld\t%2, %0\n\tudiv\t%1, %0, %0";
4459       else
4460         return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4461     case 3:
4462       if (TARGET_V9)
4463         return "ld\t%1, %0\n\tudiv\t%0, %2, %0";
4464       else
4465         return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
4466     default:
4467       gcc_unreachable ();
4468     }
4470   [(set_attr "type" "multi")
4471    (set (attr "length")
4472         (if_then_else (eq_attr "isa" "v9")
4473                       (const_int 3) (const_int 5)))])
4475 (define_insn "udivsi3_sp64"
4476   [(set (match_operand:SI 0 "register_operand" "=r")
4477         (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r")
4478                  (match_operand:SI 2 "input_operand" "rI")))]
4479   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4480   "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
4481   [(set_attr "type" "multi")
4482    (set_attr "length" "2")])
4484 (define_insn "udivdi3"
4485   [(set (match_operand:DI 0 "register_operand" "=r")
4486         (udiv:DI (match_operand:DI 1 "register_operand" "r")
4487                  (match_operand:DI 2 "arith_operand" "rI")))]
4488   "TARGET_ARCH64"
4489   "udivx\t%1, %2, %0"
4490   [(set_attr "type" "idiv")])
4492 (define_insn "*cmp_udiv_cc_set"
4493   [(set (reg:CC 100)
4494         (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
4495                              (match_operand:SI 2 "arith_operand" "rI"))
4496                     (const_int 0)))
4497    (set (match_operand:SI 0 "register_operand" "=r")
4498         (udiv:SI (match_dup 1) (match_dup 2)))]
4499   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4501   output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4503   if (TARGET_V9)
4504     return "udivcc\t%1, %2, %0";
4505   else
4506     return "nop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
4508   [(set_attr "type" "multi")
4509    (set (attr "length")
4510         (if_then_else (eq_attr "isa" "v9")
4511                       (const_int 2) (const_int 5)))])
4513 ; sparclet multiply/accumulate insns
4515 (define_insn "*smacsi"
4516   [(set (match_operand:SI 0 "register_operand" "=r")
4517         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
4518                           (match_operand:SI 2 "arith_operand" "rI"))
4519                  (match_operand:SI 3 "register_operand" "0")))]
4520   "TARGET_SPARCLET"
4521   "smac\t%1, %2, %0"
4522   [(set_attr "type" "imul")])
4524 (define_insn "*smacdi"
4525   [(set (match_operand:DI 0 "register_operand" "=r")
4526         (plus:DI (mult:DI (sign_extend:DI
4527                            (match_operand:SI 1 "register_operand" "%r"))
4528                           (sign_extend:DI
4529                            (match_operand:SI 2 "register_operand" "r")))
4530                  (match_operand:DI 3 "register_operand" "0")))]
4531   "TARGET_SPARCLET"
4532   "smacd\t%1, %2, %L0"
4533   [(set_attr "type" "imul")])
4535 (define_insn "*umacdi"
4536   [(set (match_operand:DI 0 "register_operand" "=r")
4537         (plus:DI (mult:DI (zero_extend:DI
4538                            (match_operand:SI 1 "register_operand" "%r"))
4539                           (zero_extend:DI
4540                            (match_operand:SI 2 "register_operand" "r")))
4541                  (match_operand:DI 3 "register_operand" "0")))]
4542   "TARGET_SPARCLET"
4543   "umacd\t%1, %2, %L0"
4544   [(set_attr "type" "imul")])
4547 ;; Boolean instructions.
4549 ;; We define DImode `and' so with DImode `not' we can get
4550 ;; DImode `andn'.  Other combinations are possible.
4552 (define_expand "and<V64I:mode>3"
4553   [(set (match_operand:V64I 0 "register_operand" "")
4554         (and:V64I (match_operand:V64I 1 "arith_double_operand" "")
4555                   (match_operand:V64I 2 "arith_double_operand" "")))]
4556   ""
4557   "")
4559 (define_insn "*and<V64I:mode>3_sp32"
4560   [(set (match_operand:V64I 0 "register_operand" "=r,b")
4561         (and:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
4562                   (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
4563   "! TARGET_ARCH64"
4564   "@
4565   #
4566   fand\t%1, %2, %0"
4567   [(set_attr "type" "*,fga")
4568    (set_attr "length" "2,*")
4569    (set_attr "fptype" "*,double")])
4571 (define_insn "*and<V64I:mode>3_sp64"
4572   [(set (match_operand:V64I 0 "register_operand" "=r,b")
4573         (and:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
4574                   (match_operand:V64I 2 "arith_operand" "rI,b")))]
4575   "TARGET_ARCH64"
4576   "@
4577    and\t%1, %2, %0
4578    fand\t%1, %2, %0"
4579   [(set_attr "type" "*,fga")
4580    (set_attr "fptype" "*,double")])
4582 (define_insn "and<V32I:mode>3"
4583   [(set (match_operand:V32I 0 "register_operand" "=r,d")
4584         (and:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
4585                   (match_operand:V32I 2 "arith_operand" "rI,d")))]
4586   ""
4587   "@
4588    and\t%1, %2, %0
4589    fands\t%1, %2, %0"
4590   [(set_attr "type" "*,fga")
4591    (set_attr "fptype" "*,single")])
4593 (define_split
4594   [(set (match_operand:SI 0 "register_operand" "")
4595         (and:SI (match_operand:SI 1 "register_operand" "")
4596                 (match_operand:SI 2 "const_compl_high_operand" "")))
4597    (clobber (match_operand:SI 3 "register_operand" ""))]
4598   ""
4599   [(set (match_dup 3) (match_dup 4))
4600    (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
4602   operands[4] = GEN_INT (~INTVAL (operands[2]));
4605 (define_insn_and_split "*and_not_<V64I:mode>_sp32"
4606   [(set (match_operand:V64I 0 "register_operand" "=r,b")
4607         (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
4608                   (match_operand:V64I 2 "register_operand" "r,b")))]
4609   "! TARGET_ARCH64"
4610   "@
4611    #
4612    fandnot1\t%1, %2, %0"
4613   "&& reload_completed
4614    && ((GET_CODE (operands[0]) == REG
4615         && REGNO (operands[0]) < 32)
4616        || (GET_CODE (operands[0]) == SUBREG
4617            && GET_CODE (SUBREG_REG (operands[0])) == REG
4618            && REGNO (SUBREG_REG (operands[0])) < 32))"
4619   [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
4620    (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
4621   "operands[3] = gen_highpart (SImode, operands[0]);
4622    operands[4] = gen_highpart (SImode, operands[1]);
4623    operands[5] = gen_highpart (SImode, operands[2]);
4624    operands[6] = gen_lowpart (SImode, operands[0]);
4625    operands[7] = gen_lowpart (SImode, operands[1]);
4626    operands[8] = gen_lowpart (SImode, operands[2]);"
4627   [(set_attr "type" "*,fga")
4628    (set_attr "length" "2,*")
4629    (set_attr "fptype" "*,double")])
4631 (define_insn "*and_not_<V64I:mode>_sp64"
4632   [(set (match_operand:V64I 0 "register_operand" "=r,b")
4633         (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
4634                   (match_operand:V64I 2 "register_operand" "r,b")))]
4635   "TARGET_ARCH64"
4636   "@
4637    andn\t%2, %1, %0
4638    fandnot1\t%1, %2, %0"
4639   [(set_attr "type" "*,fga")
4640    (set_attr "fptype" "*,double")])
4642 (define_insn "*and_not_<V32I:mode>"
4643   [(set (match_operand:V32I 0 "register_operand" "=r,d")
4644         (and:V32I (not:V32I (match_operand:V32I 1 "register_operand" "%r,d"))
4645                   (match_operand:V32I 2 "register_operand" "r,d")))]
4646   ""
4647   "@
4648    andn\t%2, %1, %0
4649    fandnot1s\t%1, %2, %0"
4650   [(set_attr "type" "*,fga")
4651    (set_attr "fptype" "*,single")])
4653 (define_expand "ior<V64I:mode>3"
4654   [(set (match_operand:V64I 0 "register_operand" "")
4655         (ior:V64I (match_operand:V64I 1 "arith_double_operand" "")
4656                   (match_operand:V64I 2 "arith_double_operand" "")))]
4657   ""
4658   "")
4660 (define_insn "*ior<V64I:mode>3_sp32"
4661   [(set (match_operand:V64I 0 "register_operand" "=r,b")
4662         (ior:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
4663                   (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
4664   "! TARGET_ARCH64"
4665   "@
4666   #
4667   for\t%1, %2, %0"
4668   [(set_attr "type" "*,fga")
4669    (set_attr "length" "2,*")
4670    (set_attr "fptype" "*,double")])
4672 (define_insn "*ior<V64I:mode>3_sp64"
4673   [(set (match_operand:V64I 0 "register_operand" "=r,b")
4674         (ior:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
4675                   (match_operand:V64I 2 "arith_operand" "rI,b")))]
4676   "TARGET_ARCH64"
4677   "@
4678   or\t%1, %2, %0
4679   for\t%1, %2, %0"
4680   [(set_attr "type" "*,fga")
4681    (set_attr "fptype" "*,double")])
4683 (define_insn "ior<V32I:mode>3"
4684   [(set (match_operand:V32I 0 "register_operand" "=r,d")
4685         (ior:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
4686                   (match_operand:V32I 2 "arith_operand" "rI,d")))]
4687   ""
4688   "@
4689    or\t%1, %2, %0
4690    fors\t%1, %2, %0"
4691   [(set_attr "type" "*,fga")
4692    (set_attr "fptype" "*,single")])
4694 (define_split
4695   [(set (match_operand:SI 0 "register_operand" "")
4696         (ior:SI (match_operand:SI 1 "register_operand" "")
4697                 (match_operand:SI 2 "const_compl_high_operand" "")))
4698    (clobber (match_operand:SI 3 "register_operand" ""))]
4699   ""
4700   [(set (match_dup 3) (match_dup 4))
4701    (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
4703   operands[4] = GEN_INT (~INTVAL (operands[2]));
4706 (define_insn_and_split "*or_not_<V64I:mode>_sp32"
4707   [(set (match_operand:V64I 0 "register_operand" "=r,b")
4708         (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
4709                   (match_operand:V64I 2 "register_operand" "r,b")))]
4710   "! TARGET_ARCH64"
4711   "@
4712    #
4713    fornot1\t%1, %2, %0"
4714   "&& reload_completed
4715    && ((GET_CODE (operands[0]) == REG
4716         && REGNO (operands[0]) < 32)
4717        || (GET_CODE (operands[0]) == SUBREG
4718            && GET_CODE (SUBREG_REG (operands[0])) == REG
4719            && REGNO (SUBREG_REG (operands[0])) < 32))"
4720   [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
4721    (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
4722   "operands[3] = gen_highpart (SImode, operands[0]);
4723    operands[4] = gen_highpart (SImode, operands[1]);
4724    operands[5] = gen_highpart (SImode, operands[2]);
4725    operands[6] = gen_lowpart (SImode, operands[0]);
4726    operands[7] = gen_lowpart (SImode, operands[1]);
4727    operands[8] = gen_lowpart (SImode, operands[2]);"
4728   [(set_attr "type" "*,fga")
4729    (set_attr "length" "2,*")
4730    (set_attr "fptype" "*,double")])
4732 (define_insn "*or_not_<V64I:mode>_sp64"
4733   [(set (match_operand:V64I 0 "register_operand" "=r,b")
4734         (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
4735                   (match_operand:V64I 2 "register_operand" "r,b")))]
4736   "TARGET_ARCH64"
4737   "@
4738   orn\t%2, %1, %0
4739   fornot1\t%1, %2, %0"
4740   [(set_attr "type" "*,fga")
4741    (set_attr "fptype" "*,double")])
4743 (define_insn "*or_not_<V32I:mode>"
4744   [(set (match_operand:V32I 0 "register_operand" "=r,d")
4745         (ior:V32I (not:V32I (match_operand:V32I 1 "register_operand" "r,d"))
4746                   (match_operand:V32I 2 "register_operand" "r,d")))]
4747   ""
4748   "@
4749    orn\t%2, %1, %0
4750    fornot1s\t%1, %2, %0"
4751   [(set_attr "type" "*,fga")
4752    (set_attr "fptype" "*,single")])
4754 (define_expand "xor<V64I:mode>3"
4755   [(set (match_operand:V64I 0 "register_operand" "")
4756         (xor:V64I (match_operand:V64I 1 "arith_double_operand" "")
4757                   (match_operand:V64I 2 "arith_double_operand" "")))]
4758   ""
4759   "")
4761 (define_insn "*xor<V64I:mode>3_sp32"
4762   [(set (match_operand:V64I 0 "register_operand" "=r,b")
4763         (xor:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
4764                   (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
4765   "! TARGET_ARCH64"
4766   "@
4767   #
4768   fxor\t%1, %2, %0"
4769   [(set_attr "type" "*,fga")
4770    (set_attr "length" "2,*")
4771    (set_attr "fptype" "*,double")])
4773 (define_insn "*xor<V64I:mode>3_sp64"
4774   [(set (match_operand:V64I 0 "register_operand" "=r,b")
4775         (xor:V64I (match_operand:V64I 1 "arith_operand" "%rJ,b")
4776                   (match_operand:V64I 2 "arith_operand" "rI,b")))]
4777   "TARGET_ARCH64"
4778   "@
4779   xor\t%r1, %2, %0
4780   fxor\t%1, %2, %0"
4781   [(set_attr "type" "*,fga")
4782    (set_attr "fptype" "*,double")])
4784 (define_insn "xor<V32I:mode>3"
4785   [(set (match_operand:V32I 0 "register_operand" "=r,d")
4786         (xor:V32I (match_operand:V32I 1 "arith_operand" "%rJ,d")
4787                   (match_operand:V32I 2 "arith_operand" "rI,d")))]
4788   ""
4789   "@
4790    xor\t%r1, %2, %0
4791    fxors\t%1, %2, %0"
4792   [(set_attr "type" "*,fga")
4793    (set_attr "fptype" "*,single")])
4795 (define_split
4796   [(set (match_operand:SI 0 "register_operand" "")
4797         (xor:SI (match_operand:SI 1 "register_operand" "")
4798                 (match_operand:SI 2 "const_compl_high_operand" "")))
4799    (clobber (match_operand:SI 3 "register_operand" ""))]
4800    ""
4801   [(set (match_dup 3) (match_dup 4))
4802    (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
4804   operands[4] = GEN_INT (~INTVAL (operands[2]));
4807 (define_split
4808   [(set (match_operand:SI 0 "register_operand" "")
4809         (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
4810                         (match_operand:SI 2 "const_compl_high_operand" ""))))
4811    (clobber (match_operand:SI 3 "register_operand" ""))]
4812   ""
4813   [(set (match_dup 3) (match_dup 4))
4814    (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
4816   operands[4] = GEN_INT (~INTVAL (operands[2]));
4819 ;; Split DImode logical operations requiring two instructions.
4820 (define_split
4821   [(set (match_operand:V64I 0 "register_operand" "")
4822         (match_operator:V64I 1 "cc_arith_operator"      ; AND, IOR, XOR
4823                            [(match_operand:V64I 2 "register_operand" "")
4824                             (match_operand:V64I 3 "arith_double_operand" "")]))]
4825   "! TARGET_ARCH64
4826    && reload_completed
4827    && ((GET_CODE (operands[0]) == REG
4828         && REGNO (operands[0]) < 32)
4829        || (GET_CODE (operands[0]) == SUBREG
4830            && GET_CODE (SUBREG_REG (operands[0])) == REG
4831            && REGNO (SUBREG_REG (operands[0])) < 32))"
4832   [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
4833    (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
4835   operands[4] = gen_highpart (SImode, operands[0]);
4836   operands[5] = gen_lowpart (SImode, operands[0]);
4837   operands[6] = gen_highpart (SImode, operands[2]);
4838   operands[7] = gen_lowpart (SImode, operands[2]);
4839 #if HOST_BITS_PER_WIDE_INT == 32
4840   if (GET_CODE (operands[3]) == CONST_INT && <V64I:MODE>mode == DImode)
4841     {
4842       if (INTVAL (operands[3]) < 0)
4843         operands[8] = constm1_rtx;
4844       else
4845         operands[8] = const0_rtx;
4846     }
4847   else
4848 #endif
4849     operands[8] = gen_highpart_mode (SImode, <V64I:MODE>mode, operands[3]);
4850   operands[9] = gen_lowpart (SImode, operands[3]);
4853 ;; xnor patterns.  Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
4854 ;; Combine now canonicalizes to the rightmost expression.
4855 (define_insn_and_split "*xor_not_<V64I:mode>_sp32"
4856   [(set (match_operand:V64I 0 "register_operand" "=r,b")
4857         (not:V64I (xor:V64I (match_operand:V64I 1 "register_operand" "r,b")
4858                             (match_operand:V64I 2 "register_operand" "r,b"))))]
4859   "! TARGET_ARCH64"
4860   "@
4861    #
4862    fxnor\t%1, %2, %0"
4863   "&& reload_completed
4864    && ((GET_CODE (operands[0]) == REG
4865         && REGNO (operands[0]) < 32)
4866        || (GET_CODE (operands[0]) == SUBREG
4867            && GET_CODE (SUBREG_REG (operands[0])) == REG
4868            && REGNO (SUBREG_REG (operands[0])) < 32))"
4869   [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
4870    (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
4871   "operands[3] = gen_highpart (SImode, operands[0]);
4872    operands[4] = gen_highpart (SImode, operands[1]);
4873    operands[5] = gen_highpart (SImode, operands[2]);
4874    operands[6] = gen_lowpart (SImode, operands[0]);
4875    operands[7] = gen_lowpart (SImode, operands[1]);
4876    operands[8] = gen_lowpart (SImode, operands[2]);"
4877   [(set_attr "type" "*,fga")
4878    (set_attr "length" "2,*")
4879    (set_attr "fptype" "*,double")])
4881 (define_insn "*xor_not_<V64I:mode>_sp64"
4882   [(set (match_operand:V64I 0 "register_operand" "=r,b")
4883         (not:V64I (xor:V64I (match_operand:V64I 1 "register_or_zero_operand" "rJ,b")
4884                             (match_operand:V64I 2 "arith_operand" "rI,b"))))]
4885   "TARGET_ARCH64"
4886   "@
4887   xnor\t%r1, %2, %0
4888   fxnor\t%1, %2, %0"
4889   [(set_attr "type" "*,fga")
4890    (set_attr "fptype" "*,double")])
4892 (define_insn "*xor_not_<V32I:mode>"
4893   [(set (match_operand:V32I 0 "register_operand" "=r,d")
4894         (not:V32I (xor:V32I (match_operand:V32I 1 "register_or_zero_operand" "rJ,d")
4895                             (match_operand:V32I 2 "arith_operand" "rI,d"))))]
4896   ""
4897   "@
4898    xnor\t%r1, %2, %0
4899    fxnors\t%1, %2, %0"
4900   [(set_attr "type" "*,fga")
4901    (set_attr "fptype" "*,single")])
4903 ;; These correspond to the above in the case where we also (or only)
4904 ;; want to set the condition code.  
4906 (define_insn "*cmp_cc_arith_op"
4907   [(set (reg:CC 100)
4908         (compare:CC
4909          (match_operator:SI 2 "cc_arith_operator"
4910                             [(match_operand:SI 0 "arith_operand" "%r")
4911                              (match_operand:SI 1 "arith_operand" "rI")])
4912          (const_int 0)))]
4913   ""
4914   "%A2cc\t%0, %1, %%g0"
4915   [(set_attr "type" "compare")])
4917 (define_insn "*cmp_ccx_arith_op"
4918   [(set (reg:CCX 100)
4919         (compare:CCX
4920          (match_operator:DI 2 "cc_arith_operator"
4921                             [(match_operand:DI 0 "arith_operand" "%r")
4922                              (match_operand:DI 1 "arith_operand" "rI")])
4923          (const_int 0)))]
4924   "TARGET_ARCH64"
4925   "%A2cc\t%0, %1, %%g0"
4926   [(set_attr "type" "compare")])
4928 (define_insn "*cmp_cc_arith_op_set"
4929   [(set (reg:CC 100)
4930         (compare:CC
4931          (match_operator:SI 3 "cc_arith_operator"
4932                             [(match_operand:SI 1 "arith_operand" "%r")
4933                              (match_operand:SI 2 "arith_operand" "rI")])
4934          (const_int 0)))
4935    (set (match_operand:SI 0 "register_operand" "=r")
4936         (match_operator:SI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
4937   "GET_CODE (operands[3]) == GET_CODE (operands[4])"
4938   "%A3cc\t%1, %2, %0"
4939   [(set_attr "type" "compare")])
4941 (define_insn "*cmp_ccx_arith_op_set"
4942   [(set (reg:CCX 100)
4943         (compare:CCX
4944          (match_operator:DI 3 "cc_arith_operator"
4945                             [(match_operand:DI 1 "arith_operand" "%r")
4946                              (match_operand:DI 2 "arith_operand" "rI")])
4947          (const_int 0)))
4948    (set (match_operand:DI 0 "register_operand" "=r")
4949         (match_operator:DI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
4950   "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
4951   "%A3cc\t%1, %2, %0"
4952   [(set_attr "type" "compare")])
4954 (define_insn "*cmp_cc_xor_not"
4955   [(set (reg:CC 100)
4956         (compare:CC
4957          (not:SI (xor:SI (match_operand:SI 0 "register_or_zero_operand" "%rJ")
4958                          (match_operand:SI 1 "arith_operand" "rI")))
4959          (const_int 0)))]
4960   ""
4961   "xnorcc\t%r0, %1, %%g0"
4962   [(set_attr "type" "compare")])
4964 (define_insn "*cmp_ccx_xor_not"
4965   [(set (reg:CCX 100)
4966         (compare:CCX
4967          (not:DI (xor:DI (match_operand:DI 0 "register_or_zero_operand" "%rJ")
4968                          (match_operand:DI 1 "arith_operand" "rI")))
4969          (const_int 0)))]
4970   "TARGET_ARCH64"
4971   "xnorcc\t%r0, %1, %%g0"
4972   [(set_attr "type" "compare")])
4974 (define_insn "*cmp_cc_xor_not_set"
4975   [(set (reg:CC 100)
4976         (compare:CC
4977          (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
4978                          (match_operand:SI 2 "arith_operand" "rI")))
4979          (const_int 0)))
4980    (set (match_operand:SI 0 "register_operand" "=r")
4981         (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
4982   ""
4983   "xnorcc\t%r1, %2, %0"
4984   [(set_attr "type" "compare")])
4986 (define_insn "*cmp_ccx_xor_not_set"
4987   [(set (reg:CCX 100)
4988         (compare:CCX
4989          (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
4990                          (match_operand:DI 2 "arith_operand" "rI")))
4991          (const_int 0)))
4992    (set (match_operand:DI 0 "register_operand" "=r")
4993         (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
4994   "TARGET_ARCH64"
4995   "xnorcc\t%r1, %2, %0"
4996   [(set_attr "type" "compare")])
4998 (define_insn "*cmp_cc_arith_op_not"
4999   [(set (reg:CC 100)
5000         (compare:CC
5001          (match_operator:SI 2 "cc_arith_not_operator"
5002                             [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
5003                              (match_operand:SI 1 "register_or_zero_operand" "rJ")])
5004          (const_int 0)))]
5005   ""
5006   "%B2cc\t%r1, %0, %%g0"
5007   [(set_attr "type" "compare")])
5009 (define_insn "*cmp_ccx_arith_op_not"
5010   [(set (reg:CCX 100)
5011         (compare:CCX
5012          (match_operator:DI 2 "cc_arith_not_operator"
5013                             [(not:DI (match_operand:DI 0 "arith_operand" "rI"))
5014                              (match_operand:DI 1 "register_or_zero_operand" "rJ")])
5015          (const_int 0)))]
5016   "TARGET_ARCH64"
5017   "%B2cc\t%r1, %0, %%g0"
5018   [(set_attr "type" "compare")])
5020 (define_insn "*cmp_cc_arith_op_not_set"
5021   [(set (reg:CC 100)
5022         (compare:CC
5023          (match_operator:SI 3 "cc_arith_not_operator"
5024                             [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
5025                              (match_operand:SI 2 "register_or_zero_operand" "rJ")])
5026          (const_int 0)))
5027    (set (match_operand:SI 0 "register_operand" "=r")
5028         (match_operator:SI 4 "cc_arith_not_operator"
5029                             [(not:SI (match_dup 1)) (match_dup 2)]))]
5030   "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5031   "%B3cc\t%r2, %1, %0"
5032   [(set_attr "type" "compare")])
5034 (define_insn "*cmp_ccx_arith_op_not_set"
5035   [(set (reg:CCX 100)
5036         (compare:CCX
5037          (match_operator:DI 3 "cc_arith_not_operator"
5038                             [(not:DI (match_operand:DI 1 "arith_operand" "rI"))
5039                              (match_operand:DI 2 "register_or_zero_operand" "rJ")])
5040          (const_int 0)))
5041    (set (match_operand:DI 0 "register_operand" "=r")
5042         (match_operator:DI 4 "cc_arith_not_operator"
5043                             [(not:DI (match_dup 1)) (match_dup 2)]))]
5044   "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5045   "%B3cc\t%r2, %1, %0"
5046   [(set_attr "type" "compare")])
5048 ;; We cannot use the "neg" pseudo insn because the Sun assembler
5049 ;; does not know how to make it work for constants.
5051 (define_expand "negdi2"
5052   [(set (match_operand:DI 0 "register_operand" "=r")
5053         (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5054   ""
5056   if (! TARGET_ARCH64)
5057     {
5058       emit_insn (gen_rtx_PARALLEL
5059                  (VOIDmode,
5060                   gen_rtvec (2,
5061                              gen_rtx_SET (VOIDmode, operand0,
5062                                           gen_rtx_NEG (DImode, operand1)),
5063                              gen_rtx_CLOBBER (VOIDmode,
5064                                               gen_rtx_REG (CCmode,
5065                                                            SPARC_ICC_REG)))));
5066       DONE;
5067     }
5070 (define_insn_and_split "*negdi2_sp32"
5071   [(set (match_operand:DI 0 "register_operand" "=r")
5072         (neg:DI (match_operand:DI 1 "register_operand" "r")))
5073    (clobber (reg:CC 100))]
5074   "! TARGET_ARCH64"
5075   "#"
5076   "&& reload_completed"
5077   [(parallel [(set (reg:CC_NOOV 100)
5078                    (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
5079                                     (const_int 0)))
5080               (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
5081    (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
5082                                 (ltu:SI (reg:CC 100) (const_int 0))))]
5083   "operands[2] = gen_highpart (SImode, operands[0]);
5084    operands[3] = gen_highpart (SImode, operands[1]);
5085    operands[4] = gen_lowpart (SImode, operands[0]);
5086    operands[5] = gen_lowpart (SImode, operands[1]);"
5087   [(set_attr "length" "2")])
5089 (define_insn "*negdi2_sp64"
5090   [(set (match_operand:DI 0 "register_operand" "=r")
5091         (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5092   "TARGET_ARCH64"
5093   "sub\t%%g0, %1, %0")
5095 (define_insn "negsi2"
5096   [(set (match_operand:SI 0 "register_operand" "=r")
5097         (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
5098   ""
5099   "sub\t%%g0, %1, %0")
5101 (define_insn "*cmp_cc_neg"
5102   [(set (reg:CC_NOOV 100)
5103         (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
5104                          (const_int 0)))]
5105   ""
5106   "subcc\t%%g0, %0, %%g0"
5107   [(set_attr "type" "compare")])
5109 (define_insn "*cmp_ccx_neg"
5110   [(set (reg:CCX_NOOV 100)
5111         (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_operand" "rI"))
5112                           (const_int 0)))]
5113   "TARGET_ARCH64"
5114   "subcc\t%%g0, %0, %%g0"
5115   [(set_attr "type" "compare")])
5117 (define_insn "*cmp_cc_set_neg"
5118   [(set (reg:CC_NOOV 100)
5119         (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
5120                          (const_int 0)))
5121    (set (match_operand:SI 0 "register_operand" "=r")
5122         (neg:SI (match_dup 1)))]
5123   ""
5124   "subcc\t%%g0, %1, %0"
5125   [(set_attr "type" "compare")])
5127 (define_insn "*cmp_ccx_set_neg"
5128   [(set (reg:CCX_NOOV 100)
5129         (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_operand" "rI"))
5130                           (const_int 0)))
5131    (set (match_operand:DI 0 "register_operand" "=r")
5132         (neg:DI (match_dup 1)))]
5133   "TARGET_ARCH64"
5134   "subcc\t%%g0, %1, %0"
5135   [(set_attr "type" "compare")])
5137 ;; We cannot use the "not" pseudo insn because the Sun assembler
5138 ;; does not know how to make it work for constants.
5139 (define_expand "one_cmpl<V64I:mode>2"
5140   [(set (match_operand:V64I 0 "register_operand" "")
5141         (not:V64I (match_operand:V64I 1 "register_operand" "")))]
5142   ""
5143   "")
5145 (define_insn_and_split "*one_cmpl<V64I:mode>2_sp32"
5146   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5147         (not:V64I (match_operand:V64I 1 "register_operand" "r,b")))]
5148   "! TARGET_ARCH64"
5149   "@
5150    #
5151    fnot1\t%1, %0"
5152   "&& reload_completed
5153    && ((GET_CODE (operands[0]) == REG
5154         && REGNO (operands[0]) < 32)
5155        || (GET_CODE (operands[0]) == SUBREG
5156            && GET_CODE (SUBREG_REG (operands[0])) == REG
5157            && REGNO (SUBREG_REG (operands[0])) < 32))"
5158   [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
5159    (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
5160   "operands[2] = gen_highpart (SImode, operands[0]);
5161    operands[3] = gen_highpart (SImode, operands[1]);
5162    operands[4] = gen_lowpart (SImode, operands[0]);
5163    operands[5] = gen_lowpart (SImode, operands[1]);"
5164   [(set_attr "type" "*,fga")
5165    (set_attr "length" "2,*")
5166    (set_attr "fptype" "*,double")])
5168 (define_insn "*one_cmpl<V64I:mode>2_sp64"
5169   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5170         (not:V64I (match_operand:V64I 1 "arith_operand" "rI,b")))]
5171   "TARGET_ARCH64"
5172   "@
5173    xnor\t%%g0, %1, %0
5174    fnot1\t%1, %0"
5175   [(set_attr "type" "*,fga")
5176    (set_attr "fptype" "*,double")])
5178 (define_insn "one_cmpl<V32I:mode>2"
5179   [(set (match_operand:V32I 0 "register_operand" "=r,d")
5180         (not:V32I (match_operand:V32I 1 "arith_operand" "rI,d")))]
5181   ""
5182   "@
5183   xnor\t%%g0, %1, %0
5184   fnot1s\t%1, %0"
5185   [(set_attr "type" "*,fga")
5186    (set_attr "fptype" "*,single")])
5188 (define_insn "*cmp_cc_not"
5189   [(set (reg:CC 100)
5190         (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
5191                     (const_int 0)))]
5192   ""
5193   "xnorcc\t%%g0, %0, %%g0"
5194   [(set_attr "type" "compare")])
5196 (define_insn "*cmp_ccx_not"
5197   [(set (reg:CCX 100)
5198         (compare:CCX (not:DI (match_operand:DI 0 "arith_operand" "rI"))
5199                      (const_int 0)))]
5200   "TARGET_ARCH64"
5201   "xnorcc\t%%g0, %0, %%g0"
5202   [(set_attr "type" "compare")])
5204 (define_insn "*cmp_cc_set_not"
5205   [(set (reg:CC 100)
5206         (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
5207                     (const_int 0)))
5208    (set (match_operand:SI 0 "register_operand" "=r")
5209         (not:SI (match_dup 1)))]
5210   ""
5211   "xnorcc\t%%g0, %1, %0"
5212   [(set_attr "type" "compare")])
5214 (define_insn "*cmp_ccx_set_not"
5215   [(set (reg:CCX 100)
5216         (compare:CCX (not:DI (match_operand:DI 1 "arith_operand" "rI"))
5217                     (const_int 0)))
5218    (set (match_operand:DI 0 "register_operand" "=r")
5219         (not:DI (match_dup 1)))]
5220   "TARGET_ARCH64"
5221   "xnorcc\t%%g0, %1, %0"
5222   [(set_attr "type" "compare")])
5224 (define_insn "*cmp_cc_set"
5225   [(set (match_operand:SI 0 "register_operand" "=r")
5226         (match_operand:SI 1 "register_operand" "r"))
5227    (set (reg:CC 100)
5228         (compare:CC (match_dup 1)
5229                     (const_int 0)))]
5230   ""
5231   "orcc\t%1, 0, %0"
5232   [(set_attr "type" "compare")])
5234 (define_insn "*cmp_ccx_set64"
5235   [(set (match_operand:DI 0 "register_operand" "=r")
5236         (match_operand:DI 1 "register_operand" "r"))
5237    (set (reg:CCX 100)
5238         (compare:CCX (match_dup 1)
5239                      (const_int 0)))]
5240   "TARGET_ARCH64"
5241   "orcc\t%1, 0, %0"
5242    [(set_attr "type" "compare")])
5245 ;; Floating point arithmetic instructions.
5247 (define_expand "addtf3"
5248   [(set (match_operand:TF 0 "nonimmediate_operand" "")
5249         (plus:TF (match_operand:TF 1 "general_operand" "")
5250                  (match_operand:TF 2 "general_operand" "")))]
5251   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5252   "emit_tfmode_binop (PLUS, operands); DONE;")
5254 (define_insn "*addtf3_hq"
5255   [(set (match_operand:TF 0 "register_operand" "=e")
5256         (plus:TF (match_operand:TF 1 "register_operand" "e")
5257                  (match_operand:TF 2 "register_operand" "e")))]
5258   "TARGET_FPU && TARGET_HARD_QUAD"
5259   "faddq\t%1, %2, %0"
5260   [(set_attr "type" "fp")])
5262 (define_insn "adddf3"
5263   [(set (match_operand:DF 0 "register_operand" "=e")
5264         (plus:DF (match_operand:DF 1 "register_operand" "e")
5265                  (match_operand:DF 2 "register_operand" "e")))]
5266   "TARGET_FPU"
5267   "faddd\t%1, %2, %0"
5268   [(set_attr "type" "fp")
5269    (set_attr "fptype" "double")])
5271 (define_insn "addsf3"
5272   [(set (match_operand:SF 0 "register_operand" "=f")
5273         (plus:SF (match_operand:SF 1 "register_operand" "f")
5274                  (match_operand:SF 2 "register_operand" "f")))]
5275   "TARGET_FPU"
5276   "fadds\t%1, %2, %0"
5277   [(set_attr "type" "fp")])
5279 (define_expand "subtf3"
5280   [(set (match_operand:TF 0 "nonimmediate_operand" "")
5281         (minus:TF (match_operand:TF 1 "general_operand" "")
5282                   (match_operand:TF 2 "general_operand" "")))]
5283   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5284   "emit_tfmode_binop (MINUS, operands); DONE;")
5286 (define_insn "*subtf3_hq"
5287   [(set (match_operand:TF 0 "register_operand" "=e")
5288         (minus:TF (match_operand:TF 1 "register_operand" "e")
5289                   (match_operand:TF 2 "register_operand" "e")))]
5290   "TARGET_FPU && TARGET_HARD_QUAD"
5291   "fsubq\t%1, %2, %0"
5292   [(set_attr "type" "fp")])
5294 (define_insn "subdf3"
5295   [(set (match_operand:DF 0 "register_operand" "=e")
5296         (minus:DF (match_operand:DF 1 "register_operand" "e")
5297                   (match_operand:DF 2 "register_operand" "e")))]
5298   "TARGET_FPU"
5299   "fsubd\t%1, %2, %0"
5300   [(set_attr "type" "fp")
5301    (set_attr "fptype" "double")])
5303 (define_insn "subsf3"
5304   [(set (match_operand:SF 0 "register_operand" "=f")
5305         (minus:SF (match_operand:SF 1 "register_operand" "f")
5306                   (match_operand:SF 2 "register_operand" "f")))]
5307   "TARGET_FPU"
5308   "fsubs\t%1, %2, %0"
5309   [(set_attr "type" "fp")])
5311 (define_expand "multf3"
5312   [(set (match_operand:TF 0 "nonimmediate_operand" "")
5313         (mult:TF (match_operand:TF 1 "general_operand" "")
5314                  (match_operand:TF 2 "general_operand" "")))]
5315   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5316   "emit_tfmode_binop (MULT, operands); DONE;")
5318 (define_insn "*multf3_hq"
5319   [(set (match_operand:TF 0 "register_operand" "=e")
5320         (mult:TF (match_operand:TF 1 "register_operand" "e")
5321                  (match_operand:TF 2 "register_operand" "e")))]
5322   "TARGET_FPU && TARGET_HARD_QUAD"
5323   "fmulq\t%1, %2, %0"
5324   [(set_attr "type" "fpmul")])
5326 (define_insn "muldf3"
5327   [(set (match_operand:DF 0 "register_operand" "=e")
5328         (mult:DF (match_operand:DF 1 "register_operand" "e")
5329                  (match_operand:DF 2 "register_operand" "e")))]
5330   "TARGET_FPU"
5331   "fmuld\t%1, %2, %0"
5332   [(set_attr "type" "fpmul")
5333    (set_attr "fptype" "double")])
5335 (define_insn "mulsf3"
5336   [(set (match_operand:SF 0 "register_operand" "=f")
5337         (mult:SF (match_operand:SF 1 "register_operand" "f")
5338                  (match_operand:SF 2 "register_operand" "f")))]
5339   "TARGET_FPU"
5340   "fmuls\t%1, %2, %0"
5341   [(set_attr "type" "fpmul")])
5343 (define_insn "*muldf3_extend"
5344   [(set (match_operand:DF 0 "register_operand" "=e")
5345         (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
5346                  (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
5347   "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
5348   "fsmuld\t%1, %2, %0"
5349   [(set_attr "type" "fpmul")
5350    (set_attr "fptype" "double")])
5352 (define_insn "*multf3_extend"
5353   [(set (match_operand:TF 0 "register_operand" "=e")
5354         (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
5355                  (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
5356   "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
5357   "fdmulq\t%1, %2, %0"
5358   [(set_attr "type" "fpmul")])
5360 (define_expand "divtf3"
5361   [(set (match_operand:TF 0 "nonimmediate_operand" "")
5362         (div:TF (match_operand:TF 1 "general_operand" "")
5363                 (match_operand:TF 2 "general_operand" "")))]
5364   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5365   "emit_tfmode_binop (DIV, operands); DONE;")
5367 ;; don't have timing for quad-prec. divide.
5368 (define_insn "*divtf3_hq"
5369   [(set (match_operand:TF 0 "register_operand" "=e")
5370         (div:TF (match_operand:TF 1 "register_operand" "e")
5371                 (match_operand:TF 2 "register_operand" "e")))]
5372   "TARGET_FPU && TARGET_HARD_QUAD"
5373   "fdivq\t%1, %2, %0"
5374   [(set_attr "type" "fpdivd")])
5376 (define_insn "divdf3"
5377   [(set (match_operand:DF 0 "register_operand" "=e")
5378         (div:DF (match_operand:DF 1 "register_operand" "e")
5379                 (match_operand:DF 2 "register_operand" "e")))]
5380   "TARGET_FPU"
5381   "fdivd\t%1, %2, %0"
5382   [(set_attr "type" "fpdivd")
5383    (set_attr "fptype" "double")])
5385 (define_insn "divsf3"
5386   [(set (match_operand:SF 0 "register_operand" "=f")
5387         (div:SF (match_operand:SF 1 "register_operand" "f")
5388                 (match_operand:SF 2 "register_operand" "f")))]
5389   "TARGET_FPU"
5390   "fdivs\t%1, %2, %0"
5391   [(set_attr "type" "fpdivs")])
5393 (define_expand "negtf2"
5394   [(set (match_operand:TF 0 "register_operand" "=e,e")
5395         (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5396   "TARGET_FPU"
5397   "")
5399 (define_insn_and_split "*negtf2_notv9"
5400   [(set (match_operand:TF 0 "register_operand" "=e,e")
5401         (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5402   ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5403   "TARGET_FPU
5404    && ! TARGET_V9"
5405   "@
5406   fnegs\t%0, %0
5407   #"
5408   "&& reload_completed
5409    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5410   [(set (match_dup 2) (neg:SF (match_dup 3)))
5411    (set (match_dup 4) (match_dup 5))
5412    (set (match_dup 6) (match_dup 7))]
5413   "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5414    operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5415    operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5416    operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
5417    operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5418    operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5419   [(set_attr "type" "fpmove,*")
5420    (set_attr "length" "*,2")])
5422 (define_insn_and_split "*negtf2_v9"
5423   [(set (match_operand:TF 0 "register_operand" "=e,e")
5424         (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5425   ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5426   "TARGET_FPU && TARGET_V9"
5427   "@
5428   fnegd\t%0, %0
5429   #"
5430   "&& reload_completed
5431    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5432   [(set (match_dup 2) (neg:DF (match_dup 3)))
5433    (set (match_dup 4) (match_dup 5))]
5434   "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
5435    operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
5436    operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5437    operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5438   [(set_attr "type" "fpmove,*")
5439    (set_attr "length" "*,2")
5440    (set_attr "fptype" "double")])
5442 (define_expand "negdf2"
5443   [(set (match_operand:DF 0 "register_operand" "")
5444         (neg:DF (match_operand:DF 1 "register_operand" "")))]
5445   "TARGET_FPU"
5446   "")
5448 (define_insn_and_split "*negdf2_notv9"
5449   [(set (match_operand:DF 0 "register_operand" "=e,e")
5450         (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
5451   "TARGET_FPU && ! TARGET_V9"
5452   "@
5453   fnegs\t%0, %0
5454   #"
5455   "&& reload_completed
5456    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5457   [(set (match_dup 2) (neg:SF (match_dup 3)))
5458    (set (match_dup 4) (match_dup 5))]
5459   "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5460    operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5461    operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5462    operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
5463   [(set_attr "type" "fpmove,*")
5464    (set_attr "length" "*,2")])
5466 (define_insn "*negdf2_v9"
5467   [(set (match_operand:DF 0 "register_operand" "=e")
5468         (neg:DF (match_operand:DF 1 "register_operand" "e")))]
5469   "TARGET_FPU && TARGET_V9"
5470   "fnegd\t%1, %0"
5471   [(set_attr "type" "fpmove")
5472    (set_attr "fptype" "double")])
5474 (define_insn "negsf2"
5475   [(set (match_operand:SF 0 "register_operand" "=f")
5476         (neg:SF (match_operand:SF 1 "register_operand" "f")))]
5477   "TARGET_FPU"
5478   "fnegs\t%1, %0"
5479   [(set_attr "type" "fpmove")])
5481 (define_expand "abstf2"
5482   [(set (match_operand:TF 0 "register_operand" "")
5483         (abs:TF (match_operand:TF 1 "register_operand" "")))]
5484   "TARGET_FPU"
5485   "")
5487 (define_insn_and_split "*abstf2_notv9"
5488   [(set (match_operand:TF 0 "register_operand" "=e,e")
5489         (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5490   ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5491   "TARGET_FPU && ! TARGET_V9"
5492   "@
5493   fabss\t%0, %0
5494   #"
5495   "&& reload_completed
5496    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5497   [(set (match_dup 2) (abs:SF (match_dup 3)))
5498    (set (match_dup 4) (match_dup 5))
5499    (set (match_dup 6) (match_dup 7))]
5500   "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5501    operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5502    operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5503    operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
5504    operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5505    operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5506   [(set_attr "type" "fpmove,*")
5507    (set_attr "length" "*,2")])
5509 (define_insn "*abstf2_hq_v9"
5510   [(set (match_operand:TF 0 "register_operand" "=e,e")
5511         (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5512   "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
5513   "@
5514   fabsd\t%0, %0
5515   fabsq\t%1, %0"
5516   [(set_attr "type" "fpmove")
5517    (set_attr "fptype" "double,*")])
5519 (define_insn_and_split "*abstf2_v9"
5520   [(set (match_operand:TF 0 "register_operand" "=e,e")
5521         (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5522   "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
5523   "@
5524   fabsd\t%0, %0
5525   #"
5526   "&& reload_completed
5527    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5528   [(set (match_dup 2) (abs:DF (match_dup 3)))
5529    (set (match_dup 4) (match_dup 5))]
5530   "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
5531    operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
5532    operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5533    operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5534   [(set_attr "type" "fpmove,*")
5535    (set_attr "length" "*,2")
5536    (set_attr "fptype" "double,*")])
5538 (define_expand "absdf2"
5539   [(set (match_operand:DF 0 "register_operand" "")
5540         (abs:DF (match_operand:DF 1 "register_operand" "")))]
5541   "TARGET_FPU"
5542   "")
5544 (define_insn_and_split "*absdf2_notv9"
5545   [(set (match_operand:DF 0 "register_operand" "=e,e")
5546         (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
5547   "TARGET_FPU && ! TARGET_V9"
5548   "@
5549   fabss\t%0, %0
5550   #"
5551   "&& reload_completed
5552    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5553   [(set (match_dup 2) (abs:SF (match_dup 3)))
5554    (set (match_dup 4) (match_dup 5))]
5555   "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5556    operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5557    operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5558    operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
5559   [(set_attr "type" "fpmove,*")
5560    (set_attr "length" "*,2")])
5562 (define_insn "*absdf2_v9"
5563   [(set (match_operand:DF 0 "register_operand" "=e")
5564         (abs:DF (match_operand:DF 1 "register_operand" "e")))]
5565   "TARGET_FPU && TARGET_V9"
5566   "fabsd\t%1, %0"
5567   [(set_attr "type" "fpmove")
5568    (set_attr "fptype" "double")])
5570 (define_insn "abssf2"
5571   [(set (match_operand:SF 0 "register_operand" "=f")
5572         (abs:SF (match_operand:SF 1 "register_operand" "f")))]
5573   "TARGET_FPU"
5574   "fabss\t%1, %0"
5575   [(set_attr "type" "fpmove")])
5577 (define_expand "sqrttf2"
5578   [(set (match_operand:TF 0 "nonimmediate_operand" "")
5579         (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
5580   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5581   "emit_tfmode_unop (SQRT, operands); DONE;")
5583 (define_insn "*sqrttf2_hq"
5584   [(set (match_operand:TF 0 "register_operand" "=e")
5585         (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
5586   "TARGET_FPU && TARGET_HARD_QUAD"
5587   "fsqrtq\t%1, %0"
5588   [(set_attr "type" "fpsqrtd")])
5590 (define_insn "sqrtdf2"
5591   [(set (match_operand:DF 0 "register_operand" "=e")
5592         (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
5593   "TARGET_FPU"
5594   "fsqrtd\t%1, %0"
5595   [(set_attr "type" "fpsqrtd")
5596    (set_attr "fptype" "double")])
5598 (define_insn "sqrtsf2"
5599   [(set (match_operand:SF 0 "register_operand" "=f")
5600         (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
5601   "TARGET_FPU"
5602   "fsqrts\t%1, %0"
5603   [(set_attr "type" "fpsqrts")])
5606 ;; Arithmetic shift instructions.
5608 (define_insn "ashlsi3"
5609   [(set (match_operand:SI 0 "register_operand" "=r")
5610         (ashift:SI (match_operand:SI 1 "register_operand" "r")
5611                    (match_operand:SI 2 "arith_operand" "rI")))]
5612   ""
5614   if (GET_CODE (operands[2]) == CONST_INT)
5615     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5616   return "sll\t%1, %2, %0";
5618   [(set (attr "type")
5619         (if_then_else (match_operand 2 "const_one_operand" "")
5620                       (const_string "ialu") (const_string "shift")))])
5622 (define_expand "ashldi3"
5623   [(set (match_operand:DI 0 "register_operand" "=r")
5624         (ashift:DI (match_operand:DI 1 "register_operand" "r")
5625                    (match_operand:SI 2 "arith_operand" "rI")))]
5626   "TARGET_ARCH64 || TARGET_V8PLUS"
5628   if (! TARGET_ARCH64)
5629     {
5630       if (GET_CODE (operands[2]) == CONST_INT)
5631         FAIL;
5632       emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
5633       DONE;
5634     }
5637 (define_insn "*ashldi3_sp64"
5638   [(set (match_operand:DI 0 "register_operand" "=r")
5639         (ashift:DI (match_operand:DI 1 "register_operand" "r")
5640                    (match_operand:SI 2 "arith_operand" "rI")))]
5641   "TARGET_ARCH64"
5643   if (GET_CODE (operands[2]) == CONST_INT)
5644     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5645   return "sllx\t%1, %2, %0";
5647   [(set (attr "type")
5648         (if_then_else (match_operand 2 "const_one_operand" "")
5649                       (const_string "ialu") (const_string "shift")))])
5651 ;; XXX UGH!
5652 (define_insn "ashldi3_v8plus"
5653   [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5654         (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5655                    (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5656    (clobber (match_scratch:SI 3 "=X,X,&h"))]
5657   "TARGET_V8PLUS"
5658   "* return output_v8plus_shift (operands, insn, \"sllx\");"
5659   [(set_attr "type" "multi")
5660    (set_attr "length" "5,5,6")])
5662 ;; Optimize (1LL<<x)-1
5663 ;; XXX this also needs to be fixed to handle equal subregs
5664 ;; XXX first before we could re-enable it.
5665 ;(define_insn ""
5666 ;  [(set (match_operand:DI 0 "register_operand" "=h")
5667 ;       (plus:DI (ashift:DI (const_int 1)
5668 ;                           (match_operand:SI 1 "arith_operand" "rI"))
5669 ;                (const_int -1)))]
5670 ;  "0 && TARGET_V8PLUS"
5672 ;  if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
5673 ;    return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5674 ;  return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5676 ;  [(set_attr "type" "multi")
5677 ;   (set_attr "length" "4")])
5679 (define_insn "*cmp_cc_ashift_1"
5680   [(set (reg:CC_NOOV 100)
5681         (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
5682                                     (const_int 1))
5683                          (const_int 0)))]
5684   ""
5685   "addcc\t%0, %0, %%g0"
5686   [(set_attr "type" "compare")])
5688 (define_insn "*cmp_cc_set_ashift_1"
5689   [(set (reg:CC_NOOV 100)
5690         (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
5691                                     (const_int 1))
5692                          (const_int 0)))
5693    (set (match_operand:SI 0 "register_operand" "=r")
5694         (ashift:SI (match_dup 1) (const_int 1)))]
5695   ""
5696   "addcc\t%1, %1, %0"
5697   [(set_attr "type" "compare")])
5699 (define_insn "ashrsi3"
5700   [(set (match_operand:SI 0 "register_operand" "=r")
5701         (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5702                      (match_operand:SI 2 "arith_operand" "rI")))]
5703   ""
5704   {
5705      if (GET_CODE (operands[2]) == CONST_INT)
5706        operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5707      return "sra\t%1, %2, %0";
5708   }
5709   [(set_attr "type" "shift")])
5711 (define_insn "*ashrsi3_extend"
5712   [(set (match_operand:DI 0 "register_operand" "=r")
5713         (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5714                                      (match_operand:SI 2 "arith_operand" "r"))))]
5715   "TARGET_ARCH64"
5716   "sra\t%1, %2, %0"
5717   [(set_attr "type" "shift")])
5719 ;; This handles the case as above, but with constant shift instead of
5720 ;; register. Combiner "simplifies" it for us a little bit though.
5721 (define_insn "*ashrsi3_extend2"
5722   [(set (match_operand:DI 0 "register_operand" "=r")
5723         (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
5724                                 (const_int 32))
5725                      (match_operand:SI 2 "small_int_operand" "I")))]
5726   "TARGET_ARCH64 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64"
5728   operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
5729   return "sra\t%1, %2, %0";
5731   [(set_attr "type" "shift")])
5733 (define_expand "ashrdi3"
5734   [(set (match_operand:DI 0 "register_operand" "=r")
5735         (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5736                      (match_operand:SI 2 "arith_operand" "rI")))]
5737   "TARGET_ARCH64 || TARGET_V8PLUS"
5739   if (! TARGET_ARCH64)
5740     {
5741       if (GET_CODE (operands[2]) == CONST_INT)
5742         FAIL;   /* prefer generic code in this case */
5743       emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
5744       DONE;
5745     }
5748 (define_insn "*ashrdi3_sp64"
5749   [(set (match_operand:DI 0 "register_operand" "=r")
5750         (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5751                      (match_operand:SI 2 "arith_operand" "rI")))]
5752   "TARGET_ARCH64"
5753   
5754   {
5755     if (GET_CODE (operands[2]) == CONST_INT)
5756       operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5757     return "srax\t%1, %2, %0";
5758   }
5759   [(set_attr "type" "shift")])
5761 ;; XXX
5762 (define_insn "ashrdi3_v8plus"
5763   [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5764         (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5765                      (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5766    (clobber (match_scratch:SI 3 "=X,X,&h"))]
5767   "TARGET_V8PLUS"
5768   "* return output_v8plus_shift (operands, insn, \"srax\");"
5769   [(set_attr "type" "multi")
5770    (set_attr "length" "5,5,6")])
5772 (define_insn "lshrsi3"
5773   [(set (match_operand:SI 0 "register_operand" "=r")
5774         (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5775                      (match_operand:SI 2 "arith_operand" "rI")))]
5776   ""
5777   {
5778     if (GET_CODE (operands[2]) == CONST_INT)
5779       operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5780     return "srl\t%1, %2, %0";
5781   }
5782   [(set_attr "type" "shift")])
5784 ;; This handles the case where
5785 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
5786 ;; but combiner "simplifies" it for us.
5787 (define_insn "*lshrsi3_extend"
5788   [(set (match_operand:DI 0 "register_operand" "=r")
5789         (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5790                            (match_operand:SI 2 "arith_operand" "r")) 0)
5791                 (match_operand 3 "const_int_operand" "")))]
5792   "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff"
5793   "srl\t%1, %2, %0"
5794   [(set_attr "type" "shift")])
5796 ;; This handles the case where
5797 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
5798 ;; but combiner "simplifies" it for us.
5799 (define_insn "*lshrsi3_extend2"
5800   [(set (match_operand:DI 0 "register_operand" "=r")
5801         (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
5802                          (match_operand 2 "small_int_operand" "I")
5803                          (const_int 32)))]
5804   "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
5806   operands[2] = GEN_INT (32 - INTVAL (operands[2]));
5807   return "srl\t%1, %2, %0";
5809   [(set_attr "type" "shift")])
5811 (define_expand "lshrdi3"
5812   [(set (match_operand:DI 0 "register_operand" "=r")
5813         (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5814                      (match_operand:SI 2 "arith_operand" "rI")))]
5815   "TARGET_ARCH64 || TARGET_V8PLUS"
5817   if (! TARGET_ARCH64)
5818     {
5819       if (GET_CODE (operands[2]) == CONST_INT)
5820         FAIL;
5821       emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
5822       DONE;
5823     }
5826 (define_insn "*lshrdi3_sp64"
5827   [(set (match_operand:DI 0 "register_operand" "=r")
5828         (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5829                      (match_operand:SI 2 "arith_operand" "rI")))]
5830   "TARGET_ARCH64"
5831   {
5832     if (GET_CODE (operands[2]) == CONST_INT)
5833       operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5834     return "srlx\t%1, %2, %0";
5835   }
5836   [(set_attr "type" "shift")])
5838 ;; XXX
5839 (define_insn "lshrdi3_v8plus"
5840   [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5841         (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5842                      (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5843    (clobber (match_scratch:SI 3 "=X,X,&h"))]
5844   "TARGET_V8PLUS"
5845   "* return output_v8plus_shift (operands, insn, \"srlx\");"
5846   [(set_attr "type" "multi")
5847    (set_attr "length" "5,5,6")])
5849 (define_insn ""
5850   [(set (match_operand:SI 0 "register_operand" "=r")
5851         (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5852                                              (const_int 32)) 4)
5853                      (match_operand:SI 2 "small_int_operand" "I")))]
5854   "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
5856   operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
5857   return "srax\t%1, %2, %0";
5859   [(set_attr "type" "shift")])
5861 (define_insn ""
5862   [(set (match_operand:SI 0 "register_operand" "=r")
5863         (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5864                                              (const_int 32)) 4)
5865                      (match_operand:SI 2 "small_int_operand" "I")))]
5866   "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
5868   operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
5869   return "srlx\t%1, %2, %0";
5871   [(set_attr "type" "shift")])
5873 (define_insn ""
5874   [(set (match_operand:SI 0 "register_operand" "=r")
5875         (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5876                                              (match_operand:SI 2 "small_int_operand" "I")) 4)
5877                      (match_operand:SI 3 "small_int_operand" "I")))]
5878   "TARGET_ARCH64
5879    && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
5880    && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
5881    && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
5883   operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
5885   return "srax\t%1, %2, %0";
5887   [(set_attr "type" "shift")])
5889 (define_insn ""
5890   [(set (match_operand:SI 0 "register_operand" "=r")
5891         (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5892                                              (match_operand:SI 2 "small_int_operand" "I")) 4)
5893                      (match_operand:SI 3 "small_int_operand" "I")))]
5894   "TARGET_ARCH64
5895    && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
5896    && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
5897    && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
5899   operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
5901   return "srlx\t%1, %2, %0";
5903   [(set_attr "type" "shift")])
5906 ;; Unconditional and other jump instructions.
5908 (define_insn "jump"
5909   [(set (pc) (label_ref (match_operand 0 "" "")))]
5910   ""
5911   "* return output_ubranch (operands[0], 0, insn);"
5912   [(set_attr "type" "uncond_branch")])
5914 (define_expand "tablejump"
5915   [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
5916               (use (label_ref (match_operand 1 "" "")))])]
5917   ""
5919   gcc_assert (GET_MODE (operands[0]) == CASE_VECTOR_MODE);
5921   /* In pic mode, our address differences are against the base of the
5922      table.  Add that base value back in; CSE ought to be able to combine
5923      the two address loads.  */
5924   if (flag_pic)
5925     {
5926       rtx tmp, tmp2;
5927       tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
5928       tmp2 = operands[0];
5929       if (CASE_VECTOR_MODE != Pmode)
5930         tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
5931       tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
5932       operands[0] = memory_address (Pmode, tmp);
5933     }
5936 (define_insn "*tablejump_sp32"
5937   [(set (pc) (match_operand:SI 0 "address_operand" "p"))
5938    (use (label_ref (match_operand 1 "" "")))]
5939   "! TARGET_ARCH64"
5940   "jmp\t%a0%#"
5941   [(set_attr "type" "uncond_branch")])
5943 (define_insn "*tablejump_sp64"
5944   [(set (pc) (match_operand:DI 0 "address_operand" "p"))
5945    (use (label_ref (match_operand 1 "" "")))]
5946   "TARGET_ARCH64"
5947   "jmp\t%a0%#"
5948   [(set_attr "type" "uncond_branch")])
5951 ;; Jump to subroutine instructions.
5953 (define_expand "call"
5954   ;; Note that this expression is not used for generating RTL.
5955   ;; All the RTL is generated explicitly below.
5956   [(call (match_operand 0 "call_operand" "")
5957          (match_operand 3 "" "i"))]
5958   ;; operands[2] is next_arg_register
5959   ;; operands[3] is struct_value_size_rtx.
5960   ""
5962   rtx fn_rtx;
5964   gcc_assert (MEM_P (operands[0]) && GET_MODE (operands[0]) == FUNCTION_MODE);
5966   gcc_assert (GET_CODE (operands[3]) == CONST_INT);
5968   if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
5969     {
5970       /* This is really a PIC sequence.  We want to represent
5971          it as a funny jump so its delay slots can be filled. 
5973          ??? But if this really *is* a CALL, will not it clobber the
5974          call-clobbered registers?  We lose this if it is a JUMP_INSN.
5975          Why cannot we have delay slots filled if it were a CALL?  */
5977       /* We accept negative sizes for untyped calls.  */
5978       if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
5979         emit_jump_insn
5980           (gen_rtx_PARALLEL
5981            (VOIDmode,
5982             gen_rtvec (3,
5983                        gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
5984                        operands[3],
5985                        gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
5986       else
5987         emit_jump_insn
5988           (gen_rtx_PARALLEL
5989            (VOIDmode,
5990             gen_rtvec (2,
5991                        gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
5992                        gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
5993       goto finish_call;
5994     }
5996   fn_rtx = operands[0];
5998   /* We accept negative sizes for untyped calls.  */
5999   if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6000     sparc_emit_call_insn
6001       (gen_rtx_PARALLEL
6002        (VOIDmode,
6003         gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6004                    operands[3],
6005                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6006        XEXP (fn_rtx, 0));
6007   else
6008     sparc_emit_call_insn
6009       (gen_rtx_PARALLEL
6010        (VOIDmode,
6011         gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6012                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6013        XEXP (fn_rtx, 0));
6015  finish_call:
6017   DONE;
6020 ;; We can't use the same pattern for these two insns, because then registers
6021 ;; in the address may not be properly reloaded.
6023 (define_insn "*call_address_sp32"
6024   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6025          (match_operand 1 "" ""))
6026    (clobber (reg:SI 15))]
6027   ;;- Do not use operand 1 for most machines.
6028   "! TARGET_ARCH64"
6029   "call\t%a0, %1%#"
6030   [(set_attr "type" "call")])
6032 (define_insn "*call_symbolic_sp32"
6033   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6034          (match_operand 1 "" ""))
6035    (clobber (reg:SI 15))]
6036   ;;- Do not use operand 1 for most machines.
6037   "! TARGET_ARCH64"
6038   "call\t%a0, %1%#"
6039   [(set_attr "type" "call")])
6041 (define_insn "*call_address_sp64"
6042   [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
6043          (match_operand 1 "" ""))
6044    (clobber (reg:DI 15))]
6045   ;;- Do not use operand 1 for most machines.
6046   "TARGET_ARCH64"
6047   "call\t%a0, %1%#"
6048   [(set_attr "type" "call")])
6050 (define_insn "*call_symbolic_sp64"
6051   [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6052          (match_operand 1 "" ""))
6053    (clobber (reg:DI 15))]
6054   ;;- Do not use operand 1 for most machines.
6055   "TARGET_ARCH64"
6056   "call\t%a0, %1%#"
6057   [(set_attr "type" "call")])
6059 ;; This is a call that wants a structure value.
6060 ;; There is no such critter for v9 (??? we may need one anyway).
6061 (define_insn "*call_address_struct_value_sp32"
6062   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6063          (match_operand 1 "" ""))
6064    (match_operand 2 "immediate_operand" "")
6065    (clobber (reg:SI 15))]
6066   ;;- Do not use operand 1 for most machines.
6067   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6069   operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6070   return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6072   [(set_attr "type" "call_no_delay_slot")
6073    (set_attr "length" "3")])
6075 ;; This is a call that wants a structure value.
6076 ;; There is no such critter for v9 (??? we may need one anyway).
6077 (define_insn "*call_symbolic_struct_value_sp32"
6078   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6079          (match_operand 1 "" ""))
6080    (match_operand 2 "immediate_operand" "")
6081    (clobber (reg:SI 15))]
6082   ;;- Do not use operand 1 for most machines.
6083   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6085   operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6086   return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6088   [(set_attr "type" "call_no_delay_slot")
6089    (set_attr "length" "3")])
6091 ;; This is a call that may want a structure value.  This is used for
6092 ;; untyped_calls.
6093 (define_insn "*call_address_untyped_struct_value_sp32"
6094   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6095          (match_operand 1 "" ""))
6096    (match_operand 2 "immediate_operand" "")
6097    (clobber (reg:SI 15))]
6098   ;;- Do not use operand 1 for most machines.
6099   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6100   "call\t%a0, %1\n\t nop\n\tnop"
6101   [(set_attr "type" "call_no_delay_slot")
6102    (set_attr "length" "3")])
6104 ;; This is a call that may want a structure value.  This is used for
6105 ;; untyped_calls.
6106 (define_insn "*call_symbolic_untyped_struct_value_sp32"
6107   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6108          (match_operand 1 "" ""))
6109    (match_operand 2 "immediate_operand" "")
6110    (clobber (reg:SI 15))]
6111   ;;- Do not use operand 1 for most machines.
6112   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6113   "call\t%a0, %1\n\t nop\n\tnop"
6114   [(set_attr "type" "call_no_delay_slot")
6115    (set_attr "length" "3")])
6117 (define_expand "call_value"
6118   ;; Note that this expression is not used for generating RTL.
6119   ;; All the RTL is generated explicitly below.
6120   [(set (match_operand 0 "register_operand" "=rf")
6121         (call (match_operand 1 "" "")
6122               (match_operand 4 "" "")))]
6123   ;; operand 2 is stack_size_rtx
6124   ;; operand 3 is next_arg_register
6125   ""
6127   rtx fn_rtx;
6128   rtvec vec;
6130   gcc_assert (MEM_P (operands[1]) && GET_MODE (operands[1]) == FUNCTION_MODE);
6132   fn_rtx = operands[1];
6134   vec = gen_rtvec (2,
6135                    gen_rtx_SET (VOIDmode, operands[0],
6136                                 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
6137                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
6139   sparc_emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec), XEXP (fn_rtx, 0));
6141   DONE;
6144 (define_insn "*call_value_address_sp32"
6145   [(set (match_operand 0 "" "=rf")
6146         (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
6147               (match_operand 2 "" "")))
6148    (clobber (reg:SI 15))]
6149   ;;- Do not use operand 2 for most machines.
6150   "! TARGET_ARCH64"
6151   "call\t%a1, %2%#"
6152   [(set_attr "type" "call")])
6154 (define_insn "*call_value_symbolic_sp32"
6155   [(set (match_operand 0 "" "=rf")
6156         (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6157               (match_operand 2 "" "")))
6158    (clobber (reg:SI 15))]
6159   ;;- Do not use operand 2 for most machines.
6160   "! TARGET_ARCH64"
6161   "call\t%a1, %2%#"
6162   [(set_attr "type" "call")])
6164 (define_insn "*call_value_address_sp64"
6165   [(set (match_operand 0 "" "")
6166         (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
6167               (match_operand 2 "" "")))
6168    (clobber (reg:DI 15))]
6169   ;;- Do not use operand 2 for most machines.
6170   "TARGET_ARCH64"
6171   "call\t%a1, %2%#"
6172   [(set_attr "type" "call")])
6174 (define_insn "*call_value_symbolic_sp64"
6175   [(set (match_operand 0 "" "")
6176         (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6177               (match_operand 2 "" "")))
6178    (clobber (reg:DI 15))]
6179   ;;- Do not use operand 2 for most machines.
6180   "TARGET_ARCH64"
6181   "call\t%a1, %2%#"
6182   [(set_attr "type" "call")])
6184 (define_expand "untyped_call"
6185   [(parallel [(call (match_operand 0 "" "")
6186                     (const_int 0))
6187               (match_operand:BLK 1 "memory_operand" "")
6188               (match_operand 2 "" "")])]
6189   ""
6191   rtx valreg1 = gen_rtx_REG (DImode, 8);
6192   rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6193   rtx result = operands[1];
6195   /* Pass constm1 to indicate that it may expect a structure value, but
6196      we don't know what size it is.  */
6197   emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
6199   /* Save the function value registers.  */
6200   emit_move_insn (adjust_address (result, DImode, 0), valreg1);
6201   emit_move_insn (adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8),
6202                                   valreg2);
6204   /* The optimizer does not know that the call sets the function value
6205      registers we stored in the result block.  We avoid problems by
6206      claiming that all hard registers are used and clobbered at this
6207      point.  */
6208   emit_insn (gen_blockage ());
6210   DONE;
6213 ;;  Tail call instructions.
6215 (define_expand "sibcall"
6216   [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
6217               (return)])]
6218   ""
6219   "")
6221 (define_insn "*sibcall_symbolic_sp32"
6222   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6223          (match_operand 1 "" ""))
6224    (return)]
6225   "! TARGET_ARCH64"
6226   "* return output_sibcall(insn, operands[0]);"
6227   [(set_attr "type" "sibcall")])
6229 (define_insn "*sibcall_symbolic_sp64"
6230   [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6231          (match_operand 1 "" ""))
6232    (return)]
6233   "TARGET_ARCH64"
6234   "* return output_sibcall(insn, operands[0]);"
6235   [(set_attr "type" "sibcall")])
6237 (define_expand "sibcall_value"
6238   [(parallel [(set (match_operand 0 "register_operand" "=rf")
6239                 (call (match_operand 1 "" "") (const_int 0)))
6240               (return)])]
6241   ""
6242   "")
6244 (define_insn "*sibcall_value_symbolic_sp32"
6245   [(set (match_operand 0 "" "=rf")
6246         (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6247               (match_operand 2 "" "")))
6248    (return)]
6249   "! TARGET_ARCH64"
6250   "* return output_sibcall(insn, operands[1]);"
6251   [(set_attr "type" "sibcall")])
6253 (define_insn "*sibcall_value_symbolic_sp64"
6254   [(set (match_operand 0 "" "")
6255         (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6256               (match_operand 2 "" "")))
6257    (return)]
6258   "TARGET_ARCH64"
6259   "* return output_sibcall(insn, operands[1]);"
6260   [(set_attr "type" "sibcall")])
6263 ;; Special instructions.
6265 (define_expand "prologue"
6266   [(const_int 0)]
6267   ""
6269   sparc_expand_prologue ();
6270   DONE;
6273 ;; The "save register window" insn is modelled as follows so that the DWARF-2
6274 ;; backend automatically emits the required call frame debugging information
6275 ;; while it is parsing it.  Therefore, the pattern should not be modified
6276 ;; without first studying the impact of the changes on the debug info.
6277 ;; [(set (%fp) (%sp))
6278 ;;  (set (%sp) (unspec_volatile [(%sp) (-frame_size)] UNSPECV_SAVEW))
6279 ;;  (set (%i7) (%o7))]
6281 (define_insn "save_register_window<P:mode>"
6282   [(set (reg:P 30) (reg:P 14))
6283    (set (reg:P 14) (unspec_volatile:P [(reg:P 14)
6284                                        (match_operand:P 0 "arith_operand" "rI")] UNSPECV_SAVEW))
6285    (set (reg:P 31) (reg:P 15))]
6286   ""
6287   "save\t%%sp, %0, %%sp"
6288   [(set_attr "type" "savew")])
6290 (define_expand "epilogue"
6291   [(return)]
6292   ""
6294   sparc_expand_epilogue ();
6297 (define_expand "sibcall_epilogue"
6298   [(return)]
6299   ""
6301   sparc_expand_epilogue ();
6302   DONE;
6305 (define_expand "return"
6306   [(return)]
6307   "sparc_can_use_return_insn_p ()"
6308   "")
6310 (define_insn "*return_internal"
6311   [(return)]
6312   ""
6313   "* return output_return (insn);"
6314   [(set_attr "type" "return")
6315    (set (attr "length")
6316         (cond [(eq_attr "leaf_function" "true")
6317                  (if_then_else (eq_attr "empty_delay_slot" "true")
6318                                (const_int 2)
6319                                (const_int 1))
6320                (eq_attr "calls_eh_return" "true")
6321                  (if_then_else (eq_attr "delayed_branch" "true")
6322                                (if_then_else (eq_attr "isa" "v9")
6323                                              (const_int 2)
6324                                              (const_int 3))
6325                                (if_then_else (eq_attr "isa" "v9")
6326                                              (const_int 3)
6327                                              (const_int 4)))
6328                (eq_attr "empty_delay_slot" "true")
6329                  (if_then_else (eq_attr "delayed_branch" "true")
6330                                (const_int 2)
6331                                (const_int 3))
6332               ] (const_int 1)))])
6334 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
6335 ;; all of memory.  This blocks insns from being moved across this point.
6337 (define_insn "blockage"
6338   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
6339   ""
6340   ""
6341   [(set_attr "length" "0")])
6343 (define_expand "probe_stack"
6344   [(set (match_operand 0 "memory_operand" "") (const_int 0))]
6345   ""
6347   operands[0]
6348     = adjust_address (operands[0], GET_MODE (operands[0]), SPARC_STACK_BIAS);
6351 (define_insn "probe_stack_range<P:mode>"
6352   [(set (match_operand:P 0 "register_operand" "=r")
6353         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
6354                             (match_operand:P 2 "register_operand" "r")]
6355                             UNSPECV_PROBE_STACK_RANGE))]
6356   ""
6357   "* return output_probe_stack_range (operands[0], operands[2]);"
6358   [(set_attr "type" "multi")])
6360 ;; Prepare to return any type including a structure value.
6362 (define_expand "untyped_return"
6363   [(match_operand:BLK 0 "memory_operand" "")
6364    (match_operand 1 "" "")]
6365   ""
6367   rtx valreg1 = gen_rtx_REG (DImode, 24);
6368   rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6369   rtx result = operands[0];
6371   if (! TARGET_ARCH64)
6372     {
6373       rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
6374                                          ? 15 : 31));
6375       rtx value = gen_reg_rtx (SImode);
6377       /* Fetch the instruction where we will return to and see if it's an unimp
6378          instruction (the most significant 10 bits will be zero).  If so,
6379          update the return address to skip the unimp instruction.  */
6380       emit_move_insn (value,
6381                       gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
6382       emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
6383       emit_insn (gen_update_return (rtnreg, value));
6384     }
6386   /* Reload the function value registers.  */
6387   emit_move_insn (valreg1, adjust_address (result, DImode, 0));
6388   emit_move_insn (valreg2,
6389                   adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
6391   /* Put USE insns before the return.  */
6392   emit_use (valreg1);
6393   emit_use (valreg2);
6395   /* Construct the return.  */
6396   expand_naked_return ();
6398   DONE;
6401 ;; Adjust the return address conditionally. If the value of op1 is equal
6402 ;; to all zero then adjust the return address i.e. op0 = op0 + 4.
6403 ;; This is technically *half* the check required by the 32-bit SPARC
6404 ;; psABI. This check only ensures that an "unimp" insn was written by
6405 ;; the caller, but doesn't check to see if the expected size matches
6406 ;; (this is encoded in the 12 lower bits). This check is obsolete and
6407 ;; only used by the above code "untyped_return".
6409 (define_insn "update_return"
6410   [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
6411                (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
6412   "! TARGET_ARCH64"
6414   if (flag_delayed_branch)
6415     return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
6416   else
6417     return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
6419   [(set (attr "type") (const_string "multi"))
6420    (set (attr "length")
6421         (if_then_else (eq_attr "delayed_branch" "true")
6422                       (const_int 3)
6423                       (const_int 4)))])
6425 (define_insn "nop"
6426   [(const_int 0)]
6427   ""
6428   "nop")
6430 (define_expand "indirect_jump"
6431   [(set (pc) (match_operand 0 "address_operand" "p"))]
6432   ""
6433   "")
6435 (define_insn "*branch_sp32"
6436   [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
6437   "! TARGET_ARCH64"
6438  "jmp\t%a0%#"
6439  [(set_attr "type" "uncond_branch")])
6441 (define_insn "*branch_sp64"
6442   [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
6443   "TARGET_ARCH64"
6444   "jmp\t%a0%#"
6445   [(set_attr "type" "uncond_branch")])
6447 (define_expand "nonlocal_goto"
6448   [(match_operand:SI 0 "general_operand" "")
6449    (match_operand:SI 1 "general_operand" "")
6450    (match_operand:SI 2 "general_operand" "")
6451    (match_operand:SI 3 "" "")]
6452   ""
6454   rtx lab = operands[1];
6455   rtx stack = operands[2];
6456   rtx fp = operands[3];
6457   rtx labreg;
6459   /* Trap instruction to flush all the register windows.  */
6460   emit_insn (gen_flush_register_windows ());
6462   /* Load the fp value for the containing fn into %fp.  This is needed
6463      because STACK refers to %fp.  Note that virtual register instantiation
6464      fails if the virtual %fp isn't set from a register.  */
6465   if (GET_CODE (fp) != REG)
6466     fp = force_reg (Pmode, fp);
6467   emit_move_insn (virtual_stack_vars_rtx, fp);
6469   /* Find the containing function's current nonlocal goto handler,
6470      which will do any cleanups and then jump to the label.  */
6471   labreg = gen_rtx_REG (Pmode, 8);
6472   emit_move_insn (labreg, lab);
6474   /* Restore %fp from stack pointer value for containing function.
6475      The restore insn that follows will move this to %sp,
6476      and reload the appropriate value into %fp.  */
6477   emit_move_insn (hard_frame_pointer_rtx, stack);
6479   emit_use (stack_pointer_rtx);
6481   /* ??? The V9-specific version was disabled in rev 1.65.  */
6482   emit_jump_insn (gen_goto_handler_and_restore (labreg));
6483   emit_barrier ();
6484   DONE;
6487 ;; Special trap insn to flush register windows.
6488 (define_insn "flush_register_windows"
6489   [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
6490   ""
6491   { return TARGET_V9 ? "flushw" : "ta\t3"; }
6492   [(set_attr "type" "flushw")])
6494 (define_insn "goto_handler_and_restore"
6495   [(unspec_volatile [(match_operand 0 "register_operand" "=r")] UNSPECV_GOTO)]
6496   "GET_MODE (operands[0]) == Pmode"
6498   if (flag_delayed_branch)
6499     return "jmp\t%0\n\t restore";
6500   else
6501     return "mov\t%0,%%g1\n\trestore\n\tjmp\t%%g1\n\t nop";
6503   [(set (attr "type") (const_string "multi"))
6504    (set (attr "length")
6505         (if_then_else (eq_attr "delayed_branch" "true")
6506                       (const_int 2)
6507                       (const_int 4)))])
6509 ;; For __builtin_setjmp we need to flush register windows iff the function
6510 ;; calls alloca as well, because otherwise the register window might be
6511 ;; saved after %sp adjustment and thus setjmp would crash
6512 (define_expand "builtin_setjmp_setup"
6513   [(match_operand 0 "register_operand" "r")]
6514   ""
6516   emit_insn (gen_do_builtin_setjmp_setup ());
6517   DONE;
6520 (define_insn "do_builtin_setjmp_setup"
6521   [(unspec_volatile [(const_int 0)] UNSPECV_SETJMP)]
6522   ""
6524   if (!cfun->calls_alloca)
6525     return "";
6526   if (!TARGET_V9)
6527     return "ta\t3";
6528   fputs ("\tflushw\n", asm_out_file);
6529   if (flag_pic)
6530     fprintf (asm_out_file, "\tst%c\t%%l7, [%%sp+%d]\n",
6531              TARGET_ARCH64 ? 'x' : 'w',
6532              SPARC_STACK_BIAS + 7 * UNITS_PER_WORD);
6533   fprintf (asm_out_file, "\tst%c\t%%fp, [%%sp+%d]\n",
6534            TARGET_ARCH64 ? 'x' : 'w',
6535            SPARC_STACK_BIAS + 14 * UNITS_PER_WORD);
6536   fprintf (asm_out_file, "\tst%c\t%%i7, [%%sp+%d]\n",
6537            TARGET_ARCH64 ? 'x' : 'w',
6538            SPARC_STACK_BIAS + 15 * UNITS_PER_WORD);
6539   return "";
6541   [(set_attr "type" "multi")
6542    (set (attr "length")
6543         (cond [(eq_attr "calls_alloca" "false")
6544                  (const_int 0)
6545                (eq_attr "isa" "!v9")
6546                  (const_int 1)
6547                (eq_attr "pic" "true")
6548                  (const_int 4)] (const_int 3)))])
6550 ;; Pattern for use after a setjmp to store FP and the return register
6551 ;; into the stack area.
6553 (define_expand "setjmp"
6554   [(const_int 0)]
6555   ""
6557   rtx mem;
6558   
6559   mem = gen_rtx_MEM (Pmode,
6560                      plus_constant (stack_pointer_rtx,
6561                                     SPARC_STACK_BIAS + 14 * UNITS_PER_WORD));
6562   emit_insn (gen_rtx_SET (VOIDmode, mem, frame_pointer_rtx));
6564   mem = gen_rtx_MEM (Pmode,
6565                      plus_constant (stack_pointer_rtx,
6566                                     SPARC_STACK_BIAS + 15 * UNITS_PER_WORD));
6567   emit_insn (gen_rtx_SET (VOIDmode, mem, gen_rtx_REG (Pmode, 31)));
6568   DONE;
6571 ;; Special pattern for the FLUSH instruction.
6573 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
6574 ; of the define_insn otherwise missing a mode.  We make "flush", aka
6575 ; gen_flush, the default one since sparc_initialize_trampoline uses
6576 ; it on SImode mem values.
6578 (define_insn "flush"
6579   [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
6580   ""
6581   { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
6582   [(set_attr "type" "iflush")])
6584 (define_insn "flushdi"
6585   [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
6586   ""
6587   { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
6588   [(set_attr "type" "iflush")])
6591 ;; Find first set instructions.
6593 ;; The scan instruction searches from the most significant bit while ffs
6594 ;; searches from the least significant bit.  The bit index and treatment of
6595 ;; zero also differ.  It takes at least 7 instructions to get the proper
6596 ;; result.  Here is an obvious 8 instruction sequence.
6598 ;; XXX
6599 (define_insn "ffssi2"
6600   [(set (match_operand:SI 0 "register_operand" "=&r")
6601         (ffs:SI (match_operand:SI 1 "register_operand" "r")))
6602    (clobber (match_scratch:SI 2 "=&r"))]
6603   "TARGET_SPARCLITE || TARGET_SPARCLET"
6605   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";
6607   [(set_attr "type" "multi")
6608    (set_attr "length" "8")])
6610 ;; ??? This should be a define expand, so that the extra instruction have
6611 ;; a chance of being optimized away.
6613 ;; Disabled because none of the UltraSPARCs implement popc.  The HAL R1
6614 ;; does, but no one uses that and we don't have a switch for it.
6616 ;(define_insn "ffsdi2"
6617 ;  [(set (match_operand:DI 0 "register_operand" "=&r")
6618 ;       (ffs:DI (match_operand:DI 1 "register_operand" "r")))
6619 ;   (clobber (match_scratch:DI 2 "=&r"))]
6620 ;  "TARGET_ARCH64"
6621 ;  "neg\t%1, %2\;xnor\t%1, %2, %2\;popc\t%2, %0\;movzr\t%1, 0, %0"
6622 ;  [(set_attr "type" "multi")
6623 ;   (set_attr "length" "4")])
6627 ;; Peepholes go at the end.
6629 ;; Optimize consecutive loads or stores into ldd and std when possible.
6630 ;; The conditions in which we do this are very restricted and are 
6631 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
6633 (define_peephole2
6634   [(set (match_operand:SI 0 "memory_operand" "")
6635       (const_int 0))
6636    (set (match_operand:SI 1 "memory_operand" "")
6637       (const_int 0))]
6638   "TARGET_V9
6639    && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
6640   [(set (match_dup 0)
6641        (const_int 0))]
6642   "operands[0] = widen_memory_access (operands[0], DImode, 0);")
6644 (define_peephole2
6645   [(set (match_operand:SI 0 "memory_operand" "")
6646       (const_int 0))
6647    (set (match_operand:SI 1 "memory_operand" "")
6648       (const_int 0))]
6649   "TARGET_V9
6650    && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
6651   [(set (match_dup 1)
6652        (const_int 0))]
6653   "operands[1] = widen_memory_access (operands[1], DImode, 0);")
6655 (define_peephole2
6656   [(set (match_operand:SI 0 "register_operand" "")
6657         (match_operand:SI 1 "memory_operand" ""))
6658    (set (match_operand:SI 2 "register_operand" "")
6659         (match_operand:SI 3 "memory_operand" ""))]
6660   "registers_ok_for_ldd_peep (operands[0], operands[2]) 
6661    && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])" 
6662   [(set (match_dup 0)
6663         (match_dup 1))]
6664   "operands[1] = widen_memory_access (operands[1], DImode, 0);
6665    operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
6667 (define_peephole2
6668   [(set (match_operand:SI 0 "memory_operand" "")
6669         (match_operand:SI 1 "register_operand" ""))
6670    (set (match_operand:SI 2 "memory_operand" "")
6671         (match_operand:SI 3 "register_operand" ""))]
6672   "registers_ok_for_ldd_peep (operands[1], operands[3]) 
6673    && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
6674   [(set (match_dup 0)
6675         (match_dup 1))]
6676   "operands[0] = widen_memory_access (operands[0], DImode, 0);
6677    operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
6679 (define_peephole2
6680   [(set (match_operand:SF 0 "register_operand" "")
6681         (match_operand:SF 1 "memory_operand" ""))
6682    (set (match_operand:SF 2 "register_operand" "")
6683         (match_operand:SF 3 "memory_operand" ""))]
6684   "registers_ok_for_ldd_peep (operands[0], operands[2]) 
6685    && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
6686   [(set (match_dup 0)
6687         (match_dup 1))]
6688   "operands[1] = widen_memory_access (operands[1], DFmode, 0);
6689    operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
6691 (define_peephole2
6692   [(set (match_operand:SF 0 "memory_operand" "")
6693         (match_operand:SF 1 "register_operand" ""))
6694    (set (match_operand:SF 2 "memory_operand" "")
6695         (match_operand:SF 3 "register_operand" ""))]
6696   "registers_ok_for_ldd_peep (operands[1], operands[3]) 
6697   && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
6698   [(set (match_dup 0)
6699         (match_dup 1))]
6700   "operands[0] = widen_memory_access (operands[0], DFmode, 0);
6701    operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
6703 (define_peephole2
6704   [(set (match_operand:SI 0 "register_operand" "")
6705         (match_operand:SI 1 "memory_operand" ""))
6706    (set (match_operand:SI 2 "register_operand" "")
6707         (match_operand:SI 3 "memory_operand" ""))]
6708   "registers_ok_for_ldd_peep (operands[2], operands[0]) 
6709   && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
6710   [(set (match_dup 2)
6711         (match_dup 3))]
6712    "operands[3] = widen_memory_access (operands[3], DImode, 0);
6713     operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
6715 (define_peephole2
6716   [(set (match_operand:SI 0 "memory_operand" "")
6717         (match_operand:SI 1 "register_operand" ""))
6718    (set (match_operand:SI 2 "memory_operand" "")
6719         (match_operand:SI 3 "register_operand" ""))]
6720   "registers_ok_for_ldd_peep (operands[3], operands[1]) 
6721   && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)" 
6722   [(set (match_dup 2)
6723         (match_dup 3))]
6724   "operands[2] = widen_memory_access (operands[2], DImode, 0);
6725    operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
6726    ")
6728 (define_peephole2
6729   [(set (match_operand:SF 0 "register_operand" "")
6730         (match_operand:SF 1 "memory_operand" ""))
6731    (set (match_operand:SF 2 "register_operand" "")
6732         (match_operand:SF 3 "memory_operand" ""))]
6733   "registers_ok_for_ldd_peep (operands[2], operands[0]) 
6734   && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
6735   [(set (match_dup 2)
6736         (match_dup 3))]
6737   "operands[3] = widen_memory_access (operands[3], DFmode, 0);
6738    operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
6740 (define_peephole2
6741   [(set (match_operand:SF 0 "memory_operand" "")
6742         (match_operand:SF 1 "register_operand" ""))
6743    (set (match_operand:SF 2 "memory_operand" "")
6744         (match_operand:SF 3 "register_operand" ""))]
6745   "registers_ok_for_ldd_peep (operands[3], operands[1]) 
6746   && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
6747   [(set (match_dup 2)
6748         (match_dup 3))]
6749   "operands[2] = widen_memory_access (operands[2], DFmode, 0);
6750    operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
6752 ;; Optimize the case of following a reg-reg move with a test
6753 ;; of reg just moved.  Don't allow floating point regs for operand 0 or 1.
6754 ;; This can result from a float to fix conversion.
6756 (define_peephole2
6757   [(set (match_operand:SI 0 "register_operand" "")
6758         (match_operand:SI 1 "register_operand" ""))
6759    (set (reg:CC 100)
6760         (compare:CC (match_operand:SI 2 "register_operand" "")
6761                     (const_int 0)))]
6762   "(rtx_equal_p (operands[2], operands[0])
6763     || rtx_equal_p (operands[2], operands[1]))
6764     && ! SPARC_FP_REG_P (REGNO (operands[0]))
6765     && ! SPARC_FP_REG_P (REGNO (operands[1]))"
6766   [(parallel [(set (match_dup 0) (match_dup 1))
6767               (set (reg:CC 100)
6768                    (compare:CC (match_dup 1) (const_int 0)))])]
6769   "")
6771 (define_peephole2
6772   [(set (match_operand:DI 0 "register_operand" "")
6773         (match_operand:DI 1 "register_operand" ""))
6774    (set (reg:CCX 100)
6775         (compare:CCX (match_operand:DI 2 "register_operand" "")
6776                     (const_int 0)))]
6777   "TARGET_ARCH64
6778    && (rtx_equal_p (operands[2], operands[0])
6779        || rtx_equal_p (operands[2], operands[1]))
6780    && ! SPARC_FP_REG_P (REGNO (operands[0]))
6781    && ! SPARC_FP_REG_P (REGNO (operands[1]))"
6782   [(parallel [(set (match_dup 0) (match_dup 1))
6783               (set (reg:CCX 100)
6784                    (compare:CCX (match_dup 1) (const_int 0)))])]
6785   "")
6788 ;; Prefetch instructions.
6790 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
6791 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
6792 ;; ??? operations.  With DFA we might be able to model this, but it requires a lot of
6793 ;; ??? state.
6794 (define_expand "prefetch"
6795   [(match_operand 0 "address_operand" "")
6796    (match_operand 1 "const_int_operand" "")
6797    (match_operand 2 "const_int_operand" "")]
6798   "TARGET_V9"
6800   if (TARGET_ARCH64)
6801     emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
6802   else
6803     emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
6804   DONE;
6807 (define_insn "prefetch_64"
6808   [(prefetch (match_operand:DI 0 "address_operand" "p")
6809              (match_operand:DI 1 "const_int_operand" "n")
6810              (match_operand:DI 2 "const_int_operand" "n"))]
6811   ""
6813   static const char * const prefetch_instr[2][2] = {
6814     {
6815       "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
6816       "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
6817     },
6818     {
6819       "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
6820       "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
6821     }
6822   };
6823   int read_or_write = INTVAL (operands[1]);
6824   int locality = INTVAL (operands[2]);
6826   gcc_assert (read_or_write == 0 || read_or_write == 1);
6827   gcc_assert (locality >= 0 && locality < 4);
6828   return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
6830   [(set_attr "type" "load")])
6832 (define_insn "prefetch_32"
6833   [(prefetch (match_operand:SI 0 "address_operand" "p")
6834              (match_operand:SI 1 "const_int_operand" "n")
6835              (match_operand:SI 2 "const_int_operand" "n"))]
6836   ""
6838   static const char * const prefetch_instr[2][2] = {
6839     {
6840       "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
6841       "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
6842     },
6843     {
6844       "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
6845       "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
6846     }
6847   };
6848   int read_or_write = INTVAL (operands[1]);
6849   int locality = INTVAL (operands[2]);
6851   gcc_assert (read_or_write == 0 || read_or_write == 1);
6852   gcc_assert (locality >= 0 && locality < 4);
6853   return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
6855   [(set_attr "type" "load")])
6858 ;; Trap instructions.
6860 (define_insn "trap"
6861   [(trap_if (const_int 1) (const_int 5))]
6862   ""
6863   "ta\t5"
6864   [(set_attr "type" "trap")])
6866 (define_expand "ctrapsi4"
6867   [(trap_if (match_operator 0 "noov_compare_operator"
6868              [(match_operand:SI 1 "compare_operand" "")
6869               (match_operand:SI 2 "arith_operand" "")])
6870            (match_operand 3 ""))]
6871   ""
6872   "operands[1] = gen_compare_reg (operands[0]);
6873    if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
6874      FAIL;
6875    operands[2] = const0_rtx;")
6877 (define_expand "ctrapdi4"
6878   [(trap_if (match_operator 0 "noov_compare_operator"
6879              [(match_operand:DI 1 "compare_operand" "")
6880               (match_operand:DI 2 "arith_operand" "")])
6881            (match_operand 3 ""))]
6882   "TARGET_ARCH64"
6883   "operands[1] = gen_compare_reg (operands[0]);
6884    if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
6885      FAIL;
6886    operands[2] = const0_rtx;")
6889 (define_insn ""
6890   [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CC 100) (const_int 0)])
6891             (match_operand:SI 1 "arith_operand" "rM"))]
6892   ""
6894   if (TARGET_V9)
6895     return "t%C0\t%%icc, %1";
6896   else
6897     return "t%C0\t%1";
6899   [(set_attr "type" "trap")])
6901 (define_insn ""
6902   [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CCX 100) (const_int 0)])
6903             (match_operand:SI 1 "arith_operand" "rM"))]
6904   "TARGET_V9"
6905   "t%C0\t%%xcc, %1"
6906   [(set_attr "type" "trap")])
6909 ;; TLS support instructions.
6911 (define_insn "tgd_hi22"
6912   [(set (match_operand:SI 0 "register_operand" "=r")
6913         (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
6914                             UNSPEC_TLSGD)))]
6915   "TARGET_TLS"
6916   "sethi\\t%%tgd_hi22(%a1), %0")
6918 (define_insn "tgd_lo10"
6919   [(set (match_operand:SI 0 "register_operand" "=r")
6920         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
6921                    (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
6922                               UNSPEC_TLSGD)))]
6923   "TARGET_TLS"
6924   "add\\t%1, %%tgd_lo10(%a2), %0")
6926 (define_insn "tgd_add32"
6927   [(set (match_operand:SI 0 "register_operand" "=r")
6928         (plus:SI (match_operand:SI 1 "register_operand" "r")
6929                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")
6930                              (match_operand 3 "tgd_symbolic_operand" "")]
6931                             UNSPEC_TLSGD)))]
6932   "TARGET_TLS && TARGET_ARCH32"
6933   "add\\t%1, %2, %0, %%tgd_add(%a3)")
6935 (define_insn "tgd_add64"
6936   [(set (match_operand:DI 0 "register_operand" "=r")
6937         (plus:DI (match_operand:DI 1 "register_operand" "r")
6938                  (unspec:DI [(match_operand:SI 2 "register_operand" "r")
6939                              (match_operand 3 "tgd_symbolic_operand" "")]
6940                             UNSPEC_TLSGD)))]
6941   "TARGET_TLS && TARGET_ARCH64"
6942   "add\\t%1, %2, %0, %%tgd_add(%a3)")
6944 (define_insn "tgd_call32"
6945   [(set (match_operand 0 "register_operand" "=r")
6946         (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
6947                                   (match_operand 2 "tgd_symbolic_operand" "")]
6948                                  UNSPEC_TLSGD))
6949               (match_operand 3 "" "")))
6950    (clobber (reg:SI 15))]
6951   "TARGET_TLS && TARGET_ARCH32"
6952   "call\t%a1, %%tgd_call(%a2)%#"
6953   [(set_attr "type" "call")])
6955 (define_insn "tgd_call64"
6956   [(set (match_operand 0 "register_operand" "=r")
6957         (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
6958                                   (match_operand 2 "tgd_symbolic_operand" "")]
6959                                  UNSPEC_TLSGD))
6960               (match_operand 3 "" "")))
6961    (clobber (reg:DI 15))]
6962   "TARGET_TLS && TARGET_ARCH64"
6963   "call\t%a1, %%tgd_call(%a2)%#"
6964   [(set_attr "type" "call")])
6966 (define_insn "tldm_hi22"
6967   [(set (match_operand:SI 0 "register_operand" "=r")
6968         (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
6969   "TARGET_TLS"
6970   "sethi\\t%%tldm_hi22(%&), %0")
6972 (define_insn "tldm_lo10"
6973   [(set (match_operand:SI 0 "register_operand" "=r")
6974         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
6975                     (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
6976   "TARGET_TLS"
6977   "add\\t%1, %%tldm_lo10(%&), %0")
6979 (define_insn "tldm_add32"
6980   [(set (match_operand:SI 0 "register_operand" "=r")
6981         (plus:SI (match_operand:SI 1 "register_operand" "r")
6982                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
6983                             UNSPEC_TLSLDM)))]
6984   "TARGET_TLS && TARGET_ARCH32"
6985   "add\\t%1, %2, %0, %%tldm_add(%&)")
6987 (define_insn "tldm_add64"
6988   [(set (match_operand:DI 0 "register_operand" "=r")
6989         (plus:DI (match_operand:DI 1 "register_operand" "r")
6990                  (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
6991                             UNSPEC_TLSLDM)))]
6992   "TARGET_TLS && TARGET_ARCH64"
6993   "add\\t%1, %2, %0, %%tldm_add(%&)")
6995 (define_insn "tldm_call32"
6996   [(set (match_operand 0 "register_operand" "=r")
6997         (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
6998                                  UNSPEC_TLSLDM))
6999               (match_operand 2 "" "")))
7000    (clobber (reg:SI 15))]
7001   "TARGET_TLS && TARGET_ARCH32"
7002   "call\t%a1, %%tldm_call(%&)%#"
7003   [(set_attr "type" "call")])
7005 (define_insn "tldm_call64"
7006   [(set (match_operand 0 "register_operand" "=r")
7007         (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
7008                                  UNSPEC_TLSLDM))
7009               (match_operand 2 "" "")))
7010    (clobber (reg:DI 15))]
7011   "TARGET_TLS && TARGET_ARCH64"
7012   "call\t%a1, %%tldm_call(%&)%#"
7013   [(set_attr "type" "call")])
7015 (define_insn "tldo_hix22"
7016   [(set (match_operand:SI 0 "register_operand" "=r")
7017         (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
7018                             UNSPEC_TLSLDO)))]
7019   "TARGET_TLS"
7020   "sethi\\t%%tldo_hix22(%a1), %0")
7022 (define_insn "tldo_lox10"
7023   [(set (match_operand:SI 0 "register_operand" "=r")
7024         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7025                    (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
7026                               UNSPEC_TLSLDO)))]
7027   "TARGET_TLS"
7028   "xor\\t%1, %%tldo_lox10(%a2), %0")
7030 (define_insn "tldo_add32"
7031   [(set (match_operand:SI 0 "register_operand" "=r")
7032         (plus:SI (match_operand:SI 1 "register_operand" "r")
7033                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7034                              (match_operand 3 "tld_symbolic_operand" "")]
7035                             UNSPEC_TLSLDO)))]
7036   "TARGET_TLS && TARGET_ARCH32"
7037   "add\\t%1, %2, %0, %%tldo_add(%a3)")
7039 (define_insn "tldo_add64"
7040   [(set (match_operand:DI 0 "register_operand" "=r")
7041         (plus:DI (match_operand:DI 1 "register_operand" "r")
7042                  (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7043                              (match_operand 3 "tld_symbolic_operand" "")]
7044                             UNSPEC_TLSLDO)))]
7045   "TARGET_TLS && TARGET_ARCH64"
7046   "add\\t%1, %2, %0, %%tldo_add(%a3)")
7048 (define_insn "tie_hi22"
7049   [(set (match_operand:SI 0 "register_operand" "=r")
7050         (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
7051                             UNSPEC_TLSIE)))]
7052   "TARGET_TLS"
7053   "sethi\\t%%tie_hi22(%a1), %0")
7055 (define_insn "tie_lo10"
7056   [(set (match_operand:SI 0 "register_operand" "=r")
7057         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7058                    (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
7059                               UNSPEC_TLSIE)))]
7060   "TARGET_TLS"
7061   "add\\t%1, %%tie_lo10(%a2), %0")
7063 (define_insn "tie_ld32"
7064   [(set (match_operand:SI 0 "register_operand" "=r")
7065         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
7066                     (match_operand:SI 2 "register_operand" "r")
7067                     (match_operand 3 "tie_symbolic_operand" "")]
7068                    UNSPEC_TLSIE))]
7069   "TARGET_TLS && TARGET_ARCH32"
7070   "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
7071   [(set_attr "type" "load")])
7073 (define_insn "tie_ld64"
7074   [(set (match_operand:DI 0 "register_operand" "=r")
7075         (unspec:DI [(match_operand:DI 1 "register_operand" "r")
7076                     (match_operand:SI 2 "register_operand" "r")
7077                     (match_operand 3 "tie_symbolic_operand" "")]
7078                    UNSPEC_TLSIE))]
7079   "TARGET_TLS && TARGET_ARCH64"
7080   "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
7081   [(set_attr "type" "load")])
7083 (define_insn "tie_add32"
7084   [(set (match_operand:SI 0 "register_operand" "=r")
7085         (plus:SI (match_operand:SI 1 "register_operand" "r")
7086                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7087                              (match_operand 3 "tie_symbolic_operand" "")]
7088                             UNSPEC_TLSIE)))]
7089   "TARGET_SUN_TLS && TARGET_ARCH32"
7090   "add\\t%1, %2, %0, %%tie_add(%a3)")
7092 (define_insn "tie_add64"
7093   [(set (match_operand:DI 0 "register_operand" "=r")
7094         (plus:DI (match_operand:DI 1 "register_operand" "r")
7095                  (unspec:DI [(match_operand:DI 2 "register_operand" "r")
7096                              (match_operand 3 "tie_symbolic_operand" "")]
7097                             UNSPEC_TLSIE)))]
7098   "TARGET_SUN_TLS && TARGET_ARCH64"
7099   "add\\t%1, %2, %0, %%tie_add(%a3)")
7101 (define_insn "tle_hix22_sp32"
7102   [(set (match_operand:SI 0 "register_operand" "=r")
7103         (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
7104                             UNSPEC_TLSLE)))]
7105   "TARGET_TLS && TARGET_ARCH32"
7106   "sethi\\t%%tle_hix22(%a1), %0")
7108 (define_insn "tle_lox10_sp32"
7109   [(set (match_operand:SI 0 "register_operand" "=r")
7110         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7111                    (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
7112                               UNSPEC_TLSLE)))]
7113   "TARGET_TLS && TARGET_ARCH32"
7114   "xor\\t%1, %%tle_lox10(%a2), %0")
7116 (define_insn "tle_hix22_sp64"
7117   [(set (match_operand:DI 0 "register_operand" "=r")
7118         (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
7119                             UNSPEC_TLSLE)))]
7120   "TARGET_TLS && TARGET_ARCH64"
7121   "sethi\\t%%tle_hix22(%a1), %0")
7123 (define_insn "tle_lox10_sp64"
7124   [(set (match_operand:DI 0 "register_operand" "=r")
7125         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
7126                    (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
7127                               UNSPEC_TLSLE)))]
7128   "TARGET_TLS && TARGET_ARCH64"
7129   "xor\\t%1, %%tle_lox10(%a2), %0")
7131 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
7132 (define_insn "*tldo_ldub_sp32"
7133   [(set (match_operand:QI 0 "register_operand" "=r")
7134         (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7135                                      (match_operand 3 "tld_symbolic_operand" "")]
7136                                     UNSPEC_TLSLDO)
7137                          (match_operand:SI 1 "register_operand" "r"))))]
7138   "TARGET_TLS && TARGET_ARCH32"
7139   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7140   [(set_attr "type" "load")
7141    (set_attr "us3load_type" "3cycle")])
7143 (define_insn "*tldo_ldub1_sp32"
7144   [(set (match_operand:HI 0 "register_operand" "=r")
7145         (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7146                                                      (match_operand 3 "tld_symbolic_operand" "")]
7147                                                     UNSPEC_TLSLDO)
7148                                          (match_operand:SI 1 "register_operand" "r")))))]
7149   "TARGET_TLS && TARGET_ARCH32"
7150   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7151   [(set_attr "type" "load")
7152    (set_attr "us3load_type" "3cycle")])
7154 (define_insn "*tldo_ldub2_sp32"
7155   [(set (match_operand:SI 0 "register_operand" "=r")
7156         (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7157                                                      (match_operand 3 "tld_symbolic_operand" "")]
7158                                                     UNSPEC_TLSLDO)
7159                                          (match_operand:SI 1 "register_operand" "r")))))]
7160   "TARGET_TLS && TARGET_ARCH32"
7161   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7162   [(set_attr "type" "load")
7163    (set_attr "us3load_type" "3cycle")])
7165 (define_insn "*tldo_ldsb1_sp32"
7166   [(set (match_operand:HI 0 "register_operand" "=r")
7167         (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7168                                                      (match_operand 3 "tld_symbolic_operand" "")]
7169                                                     UNSPEC_TLSLDO)
7170                                          (match_operand:SI 1 "register_operand" "r")))))]
7171   "TARGET_TLS && TARGET_ARCH32"
7172   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7173   [(set_attr "type" "sload")
7174    (set_attr "us3load_type" "3cycle")])
7176 (define_insn "*tldo_ldsb2_sp32"
7177   [(set (match_operand:SI 0 "register_operand" "=r")
7178         (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7179                                                      (match_operand 3 "tld_symbolic_operand" "")]
7180                                                     UNSPEC_TLSLDO)
7181                                          (match_operand:SI 1 "register_operand" "r")))))]
7182   "TARGET_TLS && TARGET_ARCH32"
7183   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7184   [(set_attr "type" "sload")
7185    (set_attr "us3load_type" "3cycle")])
7187 (define_insn "*tldo_ldub_sp64"
7188   [(set (match_operand:QI 0 "register_operand" "=r")
7189         (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7190                                      (match_operand 3 "tld_symbolic_operand" "")]
7191                                     UNSPEC_TLSLDO)
7192                          (match_operand:DI 1 "register_operand" "r"))))]
7193   "TARGET_TLS && TARGET_ARCH64"
7194   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7195   [(set_attr "type" "load")
7196    (set_attr "us3load_type" "3cycle")])
7198 (define_insn "*tldo_ldub1_sp64"
7199   [(set (match_operand:HI 0 "register_operand" "=r")
7200         (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7201                                                      (match_operand 3 "tld_symbolic_operand" "")]
7202                                                     UNSPEC_TLSLDO)
7203                                          (match_operand:DI 1 "register_operand" "r")))))]
7204   "TARGET_TLS && TARGET_ARCH64"
7205   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7206   [(set_attr "type" "load")
7207    (set_attr "us3load_type" "3cycle")])
7209 (define_insn "*tldo_ldub2_sp64"
7210   [(set (match_operand:SI 0 "register_operand" "=r")
7211         (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7212                                                      (match_operand 3 "tld_symbolic_operand" "")]
7213                                                     UNSPEC_TLSLDO)
7214                                          (match_operand:DI 1 "register_operand" "r")))))]
7215   "TARGET_TLS && TARGET_ARCH64"
7216   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7217   [(set_attr "type" "load")
7218    (set_attr "us3load_type" "3cycle")])
7220 (define_insn "*tldo_ldub3_sp64"
7221   [(set (match_operand:DI 0 "register_operand" "=r")
7222         (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7223                                                      (match_operand 3 "tld_symbolic_operand" "")]
7224                                                     UNSPEC_TLSLDO)
7225                                          (match_operand:DI 1 "register_operand" "r")))))]
7226   "TARGET_TLS && TARGET_ARCH64"
7227   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7228   [(set_attr "type" "load")
7229    (set_attr "us3load_type" "3cycle")])
7231 (define_insn "*tldo_ldsb1_sp64"
7232   [(set (match_operand:HI 0 "register_operand" "=r")
7233         (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7234                                                      (match_operand 3 "tld_symbolic_operand" "")]
7235                                                     UNSPEC_TLSLDO)
7236                                          (match_operand:DI 1 "register_operand" "r")))))]
7237   "TARGET_TLS && TARGET_ARCH64"
7238   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7239   [(set_attr "type" "sload")
7240    (set_attr "us3load_type" "3cycle")])
7242 (define_insn "*tldo_ldsb2_sp64"
7243   [(set (match_operand:SI 0 "register_operand" "=r")
7244         (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7245                                                      (match_operand 3 "tld_symbolic_operand" "")]
7246                                                     UNSPEC_TLSLDO)
7247                                          (match_operand:DI 1 "register_operand" "r")))))]
7248   "TARGET_TLS && TARGET_ARCH64"
7249   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7250   [(set_attr "type" "sload")
7251    (set_attr "us3load_type" "3cycle")])
7253 (define_insn "*tldo_ldsb3_sp64"
7254   [(set (match_operand:DI 0 "register_operand" "=r")
7255         (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7256                                                      (match_operand 3 "tld_symbolic_operand" "")]
7257                                                     UNSPEC_TLSLDO)
7258                                          (match_operand:DI 1 "register_operand" "r")))))]
7259   "TARGET_TLS && TARGET_ARCH64"
7260   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7261   [(set_attr "type" "sload")
7262    (set_attr "us3load_type" "3cycle")])
7264 (define_insn "*tldo_lduh_sp32"
7265   [(set (match_operand:HI 0 "register_operand" "=r")
7266         (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7267                                      (match_operand 3 "tld_symbolic_operand" "")]
7268                                     UNSPEC_TLSLDO)
7269                          (match_operand:SI 1 "register_operand" "r"))))]
7270   "TARGET_TLS && TARGET_ARCH32"
7271   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7272   [(set_attr "type" "load")
7273    (set_attr "us3load_type" "3cycle")])
7275 (define_insn "*tldo_lduh1_sp32"
7276   [(set (match_operand:SI 0 "register_operand" "=r")
7277         (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7278                                                      (match_operand 3 "tld_symbolic_operand" "")]
7279                                                     UNSPEC_TLSLDO)
7280                                          (match_operand:SI 1 "register_operand" "r")))))]
7281   "TARGET_TLS && TARGET_ARCH32"
7282   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7283   [(set_attr "type" "load")
7284    (set_attr "us3load_type" "3cycle")])
7286 (define_insn "*tldo_ldsh1_sp32"
7287   [(set (match_operand:SI 0 "register_operand" "=r")
7288         (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7289                                                      (match_operand 3 "tld_symbolic_operand" "")]
7290                                                     UNSPEC_TLSLDO)
7291                                          (match_operand:SI 1 "register_operand" "r")))))]
7292   "TARGET_TLS && TARGET_ARCH32"
7293   "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7294   [(set_attr "type" "sload")
7295    (set_attr "us3load_type" "3cycle")])
7297 (define_insn "*tldo_lduh_sp64"
7298   [(set (match_operand:HI 0 "register_operand" "=r")
7299         (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7300                                      (match_operand 3 "tld_symbolic_operand" "")]
7301                                     UNSPEC_TLSLDO)
7302                          (match_operand:DI 1 "register_operand" "r"))))]
7303   "TARGET_TLS && TARGET_ARCH64"
7304   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7305   [(set_attr "type" "load")
7306    (set_attr "us3load_type" "3cycle")])
7308 (define_insn "*tldo_lduh1_sp64"
7309   [(set (match_operand:SI 0 "register_operand" "=r")
7310         (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7311                                                      (match_operand 3 "tld_symbolic_operand" "")]
7312                                                     UNSPEC_TLSLDO)
7313                                          (match_operand:DI 1 "register_operand" "r")))))]
7314   "TARGET_TLS && TARGET_ARCH64"
7315   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7316   [(set_attr "type" "load")
7317    (set_attr "us3load_type" "3cycle")])
7319 (define_insn "*tldo_lduh2_sp64"
7320   [(set (match_operand:DI 0 "register_operand" "=r")
7321         (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7322                                                      (match_operand 3 "tld_symbolic_operand" "")]
7323                                                     UNSPEC_TLSLDO)
7324                                          (match_operand:DI 1 "register_operand" "r")))))]
7325   "TARGET_TLS && TARGET_ARCH64"
7326   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7327   [(set_attr "type" "load")
7328    (set_attr "us3load_type" "3cycle")])
7330 (define_insn "*tldo_ldsh1_sp64"
7331   [(set (match_operand:SI 0 "register_operand" "=r")
7332         (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7333                                                      (match_operand 3 "tld_symbolic_operand" "")]
7334                                                     UNSPEC_TLSLDO)
7335                                          (match_operand:DI 1 "register_operand" "r")))))]
7336   "TARGET_TLS && TARGET_ARCH64"
7337   "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7338   [(set_attr "type" "sload")
7339    (set_attr "us3load_type" "3cycle")])
7341 (define_insn "*tldo_ldsh2_sp64"
7342   [(set (match_operand:DI 0 "register_operand" "=r")
7343         (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7344                                                      (match_operand 3 "tld_symbolic_operand" "")]
7345                                                     UNSPEC_TLSLDO)
7346                                          (match_operand:DI 1 "register_operand" "r")))))]
7347   "TARGET_TLS && TARGET_ARCH64"
7348   "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7349   [(set_attr "type" "sload")
7350    (set_attr "us3load_type" "3cycle")])
7352 (define_insn "*tldo_lduw_sp32"
7353   [(set (match_operand:SI 0 "register_operand" "=r")
7354         (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7355                                      (match_operand 3 "tld_symbolic_operand" "")]
7356                                     UNSPEC_TLSLDO)
7357                          (match_operand:SI 1 "register_operand" "r"))))]
7358   "TARGET_TLS && TARGET_ARCH32"
7359   "ld\t[%1 + %2], %0, %%tldo_add(%3)"
7360   [(set_attr "type" "load")])
7362 (define_insn "*tldo_lduw_sp64"
7363   [(set (match_operand:SI 0 "register_operand" "=r")
7364         (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7365                                      (match_operand 3 "tld_symbolic_operand" "")]
7366                                     UNSPEC_TLSLDO)
7367                          (match_operand:DI 1 "register_operand" "r"))))]
7368   "TARGET_TLS && TARGET_ARCH64"
7369   "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7370   [(set_attr "type" "load")])
7372 (define_insn "*tldo_lduw1_sp64"
7373   [(set (match_operand:DI 0 "register_operand" "=r")
7374         (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7375                                                      (match_operand 3 "tld_symbolic_operand" "")]
7376                                                     UNSPEC_TLSLDO)
7377                                          (match_operand:DI 1 "register_operand" "r")))))]
7378   "TARGET_TLS && TARGET_ARCH64"
7379   "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7380   [(set_attr "type" "load")])
7382 (define_insn "*tldo_ldsw1_sp64"
7383   [(set (match_operand:DI 0 "register_operand" "=r")
7384         (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7385                                                      (match_operand 3 "tld_symbolic_operand" "")]
7386                                                     UNSPEC_TLSLDO)
7387                                          (match_operand:DI 1 "register_operand" "r")))))]
7388   "TARGET_TLS && TARGET_ARCH64"
7389   "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
7390   [(set_attr "type" "sload")
7391    (set_attr "us3load_type" "3cycle")])
7393 (define_insn "*tldo_ldx_sp64"
7394   [(set (match_operand:DI 0 "register_operand" "=r")
7395         (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7396                                      (match_operand 3 "tld_symbolic_operand" "")]
7397                                     UNSPEC_TLSLDO)
7398                          (match_operand:DI 1 "register_operand" "r"))))]
7399   "TARGET_TLS && TARGET_ARCH64"
7400   "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
7401   [(set_attr "type" "load")])
7403 (define_insn "*tldo_stb_sp32"
7404   [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7405                                      (match_operand 3 "tld_symbolic_operand" "")]
7406                                     UNSPEC_TLSLDO)
7407                          (match_operand:SI 1 "register_operand" "r")))
7408         (match_operand:QI 0 "register_operand" "=r"))]
7409   "TARGET_TLS && TARGET_ARCH32"
7410   "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7411   [(set_attr "type" "store")])
7413 (define_insn "*tldo_stb_sp64"
7414   [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7415                                      (match_operand 3 "tld_symbolic_operand" "")]
7416                                     UNSPEC_TLSLDO)
7417                          (match_operand:DI 1 "register_operand" "r")))
7418         (match_operand:QI 0 "register_operand" "=r"))]
7419   "TARGET_TLS && TARGET_ARCH64"
7420   "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7421   [(set_attr "type" "store")])
7423 (define_insn "*tldo_sth_sp32"
7424   [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7425                                      (match_operand 3 "tld_symbolic_operand" "")]
7426                                     UNSPEC_TLSLDO)
7427                          (match_operand:SI 1 "register_operand" "r")))
7428         (match_operand:HI 0 "register_operand" "=r"))]
7429   "TARGET_TLS && TARGET_ARCH32"
7430   "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7431   [(set_attr "type" "store")])
7433 (define_insn "*tldo_sth_sp64"
7434   [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7435                                      (match_operand 3 "tld_symbolic_operand" "")]
7436                                     UNSPEC_TLSLDO)
7437                          (match_operand:DI 1 "register_operand" "r")))
7438         (match_operand:HI 0 "register_operand" "=r"))]
7439   "TARGET_TLS && TARGET_ARCH64"
7440   "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7441   [(set_attr "type" "store")])
7443 (define_insn "*tldo_stw_sp32"
7444   [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7445                                      (match_operand 3 "tld_symbolic_operand" "")]
7446                                     UNSPEC_TLSLDO)
7447                          (match_operand:SI 1 "register_operand" "r")))
7448         (match_operand:SI 0 "register_operand" "=r"))]
7449   "TARGET_TLS && TARGET_ARCH32"
7450   "st\t%0, [%1 + %2], %%tldo_add(%3)"
7451   [(set_attr "type" "store")])
7453 (define_insn "*tldo_stw_sp64"
7454   [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7455                                      (match_operand 3 "tld_symbolic_operand" "")]
7456                                     UNSPEC_TLSLDO)
7457                          (match_operand:DI 1 "register_operand" "r")))
7458         (match_operand:SI 0 "register_operand" "=r"))]
7459   "TARGET_TLS && TARGET_ARCH64"
7460   "stw\t%0, [%1 + %2], %%tldo_add(%3)"
7461   [(set_attr "type" "store")])
7463 (define_insn "*tldo_stx_sp64"
7464   [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7465                                      (match_operand 3 "tld_symbolic_operand" "")]
7466                                     UNSPEC_TLSLDO)
7467                          (match_operand:DI 1 "register_operand" "r")))
7468         (match_operand:DI 0 "register_operand" "=r"))]
7469   "TARGET_TLS && TARGET_ARCH64"
7470   "stx\t%0, [%1 + %2], %%tldo_add(%3)"
7471   [(set_attr "type" "store")])
7474 ;; Stack protector instructions.
7476 (define_expand "stack_protect_set"
7477   [(match_operand 0 "memory_operand" "")
7478    (match_operand 1 "memory_operand" "")]
7479   ""
7481 #ifdef TARGET_THREAD_SSP_OFFSET
7482   rtx tlsreg = gen_rtx_REG (Pmode, 7);
7483   rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7484   operands[1] = gen_rtx_MEM (Pmode, addr);
7485 #endif
7486   if (TARGET_ARCH64)
7487     emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
7488   else
7489     emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
7490   DONE;
7493 (define_insn "stack_protect_setsi"
7494   [(set (match_operand:SI 0 "memory_operand" "=m")
7495         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7496    (set (match_scratch:SI 2 "=&r") (const_int 0))]
7497   "TARGET_ARCH32"
7498   "ld\t%1, %2\;st\t%2, %0\;mov\t0, %2"
7499   [(set_attr "type" "multi")
7500    (set_attr "length" "3")])
7502 (define_insn "stack_protect_setdi"
7503   [(set (match_operand:DI 0 "memory_operand" "=m")
7504         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7505    (set (match_scratch:DI 2 "=&r") (const_int 0))]
7506   "TARGET_ARCH64"
7507   "ldx\t%1, %2\;stx\t%2, %0\;mov\t0, %2"
7508   [(set_attr "type" "multi")
7509    (set_attr "length" "3")])
7511 (define_expand "stack_protect_test"
7512   [(match_operand 0 "memory_operand" "")
7513    (match_operand 1 "memory_operand" "")
7514    (match_operand 2 "" "")]
7515   ""
7517   rtx result, test;
7518 #ifdef TARGET_THREAD_SSP_OFFSET
7519   rtx tlsreg = gen_rtx_REG (Pmode, 7);
7520   rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7521   operands[1] = gen_rtx_MEM (Pmode, addr);
7522 #endif
7523   if (TARGET_ARCH64)
7524     {
7525       result = gen_reg_rtx (Pmode);
7526       emit_insn (gen_stack_protect_testdi (result, operands[0], operands[1]));
7527       test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7528       emit_jump_insn (gen_cbranchdi4 (test, result, const0_rtx, operands[2]));
7529     }
7530   else
7531     {
7532       emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
7533       result = gen_rtx_REG (CCmode, SPARC_ICC_REG);
7534       test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7535       emit_jump_insn (gen_cbranchcc4 (test, result, const0_rtx, operands[2]));
7536     }
7537   DONE;
7540 (define_insn "stack_protect_testsi"
7541   [(set (reg:CC 100)
7542         (unspec:CC [(match_operand:SI 0 "memory_operand" "m")
7543                     (match_operand:SI 1 "memory_operand" "m")]
7544                    UNSPEC_SP_TEST))
7545    (set (match_scratch:SI 3 "=r") (const_int 0))
7546    (clobber (match_scratch:SI 2 "=&r"))]
7547   "TARGET_ARCH32"
7548   "ld\t%0, %2\;ld\t%1, %3\;xorcc\t%2, %3, %2\;mov\t0, %3"
7549   [(set_attr "type" "multi")
7550    (set_attr "length" "4")])
7552 (define_insn "stack_protect_testdi"
7553   [(set (match_operand:DI 0 "register_operand" "=&r")
7554         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
7555                     (match_operand:DI 2 "memory_operand" "m")]
7556                    UNSPEC_SP_TEST))
7557    (set (match_scratch:DI 3 "=r") (const_int 0))]
7558   "TARGET_ARCH64"
7559   "ldx\t%1, %0\;ldx\t%2, %3\;xor\t%0, %3, %0\;mov\t0, %3"
7560   [(set_attr "type" "multi")
7561    (set_attr "length" "4")])
7564 ;; Vector instructions.
7566 (define_insn "addv2si3"
7567   [(set (match_operand:V2SI 0 "register_operand" "=e")
7568         (plus:V2SI (match_operand:V2SI 1 "register_operand" "e")
7569                    (match_operand:V2SI 2 "register_operand" "e")))]
7570   "TARGET_VIS"
7571   "fpadd32\t%1, %2, %0"
7572   [(set_attr "type" "fga")
7573    (set_attr "fptype" "double")])
7575 (define_insn "addv4hi3"
7576   [(set (match_operand:V4HI 0 "register_operand" "=e")
7577          (plus:V4HI (match_operand:V4HI 1 "register_operand" "e")
7578                     (match_operand:V4HI 2 "register_operand" "e")))]
7579   "TARGET_VIS"
7580   "fpadd16\t%1, %2, %0"
7581   [(set_attr "type" "fga")
7582    (set_attr "fptype" "double")])
7584 ;; fpadd32s is emitted by the addsi3 pattern.
7586 (define_insn "addv2hi3"
7587   [(set (match_operand:V2HI 0 "register_operand" "=f")
7588         (plus:V2HI (match_operand:V2HI 1 "register_operand" "f")
7589                    (match_operand:V2HI 2 "register_operand" "f")))]
7590   "TARGET_VIS"
7591   "fpadd16s\t%1, %2, %0"
7592   [(set_attr "type" "fga")
7593    (set_attr "fptype" "single")])
7595 (define_insn "subv2si3"
7596   [(set (match_operand:V2SI 0 "register_operand" "=e")
7597         (minus:V2SI (match_operand:V2SI 1 "register_operand" "e")
7598                     (match_operand:V2SI 2 "register_operand" "e")))]
7599   "TARGET_VIS"
7600   "fpsub32\t%1, %2, %0"
7601   [(set_attr "type" "fga")
7602    (set_attr "fptype" "double")])
7604 (define_insn "subv4hi3"
7605   [(set (match_operand:V4HI 0 "register_operand" "=e")
7606         (minus:V4HI (match_operand:V4HI 1 "register_operand" "e")
7607                     (match_operand:V4HI 2 "register_operand" "e")))]
7608   "TARGET_VIS"
7609   "fpsub16\t%1, %2, %0"
7610   [(set_attr "type" "fga")
7611    (set_attr "fptype" "double")])
7613 ;; fpsub32s is emitted by the subsi3 pattern.
7615 (define_insn "subv2hi3"
7616   [(set (match_operand:V2HI 0 "register_operand" "=f")
7617         (minus:V2HI (match_operand:V2HI 1 "register_operand" "f")
7618                     (match_operand:V2HI 2 "register_operand" "f")))]
7619   "TARGET_VIS"
7620   "fpsub16s\t%1, %2, %0"
7621   [(set_attr "type" "fga")
7622    (set_attr "fptype" "single")])
7624 ;; All other logical instructions have integer equivalents so they
7625 ;; are defined together.
7627 ;; (ior (not (op1)) (not (op2))) is the canonical form of NAND.
7629 (define_insn "*nand<V64:mode>_vis"
7630   [(set (match_operand:V64 0 "register_operand" "=e")
7631         (ior:V64 (not:V64 (match_operand:V64 1 "register_operand" "e"))
7632                  (not:V64 (match_operand:V64 2 "register_operand" "e"))))]
7633   "TARGET_VIS"
7634   "fnand\t%1, %2, %0"
7635   [(set_attr "type" "fga")
7636    (set_attr "fptype" "double")])
7638 (define_insn "*nand<V32:mode>_vis"
7639   [(set (match_operand:V32 0 "register_operand" "=f")
7640          (ior:V32 (not:V32 (match_operand:V32 1 "register_operand" "f"))
7641                   (not:V32 (match_operand:V32 2 "register_operand" "f"))))]
7642   "TARGET_VIS"
7643   "fnands\t%1, %2, %0"
7644   [(set_attr "type" "fga")
7645    (set_attr "fptype" "single")])
7647 ;; Hard to generate VIS instructions.  We have builtins for these.
7649 (define_insn "fpack16_vis"
7650   [(set (match_operand:V4QI 0 "register_operand" "=f")
7651         (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e")]
7652                       UNSPEC_FPACK16))]
7653   "TARGET_VIS"
7654   "fpack16\t%1, %0"
7655   [(set_attr "type" "fga")
7656    (set_attr "fptype" "double")])
7658 (define_insn "fpackfix_vis"
7659   [(set (match_operand:V2HI 0 "register_operand" "=f")
7660         (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e")]
7661                       UNSPEC_FPACKFIX))]
7662   "TARGET_VIS"
7663   "fpackfix\t%1, %0"
7664   [(set_attr "type" "fga")
7665    (set_attr "fptype" "double")])
7667 (define_insn "fpack32_vis"
7668   [(set (match_operand:V8QI 0 "register_operand" "=e")
7669         (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e")
7670                       (match_operand:V8QI 2 "register_operand" "e")]
7671                      UNSPEC_FPACK32))]
7672   "TARGET_VIS"
7673   "fpack32\t%1, %2, %0"
7674   [(set_attr "type" "fga")
7675    (set_attr "fptype" "double")])
7677 (define_insn "fexpand_vis"
7678   [(set (match_operand:V4HI 0 "register_operand" "=e")
7679         (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")]
7680          UNSPEC_FEXPAND))]
7681  "TARGET_VIS"
7682  "fexpand\t%1, %0"
7683  [(set_attr "type" "fga")
7684   (set_attr "fptype" "double")])
7686 ;; It may be possible to describe this operation as (1 indexed):
7687 ;; (vec_select (vec_duplicate (vec_duplicate (vec_concat 1 2)))
7688 ;;  1,5,10,14,19,23,28,32)
7689 ;; Note that (vec_merge:V8QI [(V4QI) (V4QI)] (10101010 = 170) doesn't work
7690 ;; because vec_merge expects all the operands to be of the same type.
7691 (define_insn "fpmerge_vis"
7692   [(set (match_operand:V8QI 0 "register_operand" "=e")
7693         (unspec:V8QI [(match_operand:V4QI 1 "register_operand" "f")
7694                       (match_operand:V4QI 2 "register_operand" "f")]
7695          UNSPEC_FPMERGE))]
7696  "TARGET_VIS"
7697  "fpmerge\t%1, %2, %0"
7698  [(set_attr "type" "fga")
7699   (set_attr "fptype" "double")])
7701 ;; Partitioned multiply instructions
7702 (define_insn "fmul8x16_vis"
7703   [(set (match_operand:V4HI 0 "register_operand" "=e")
7704         (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
7705                    (match_operand:V4HI 2 "register_operand" "e")))]
7706   "TARGET_VIS"
7707   "fmul8x16\t%1, %2, %0"
7708   [(set_attr "type" "fpmul")
7709    (set_attr "fptype" "double")])
7711 ;; Only one of the following two insns can be a multiply.
7712 (define_insn "fmul8x16au_vis"
7713   [(set (match_operand:V4HI 0 "register_operand" "=e")
7714         (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
7715                    (match_operand:V2HI 2 "register_operand" "f")))]
7716   "TARGET_VIS"
7717   "fmul8x16au\t%1, %2, %0"
7718   [(set_attr "type" "fpmul")
7719    (set_attr "fptype" "double")])
7721 (define_insn "fmul8x16al_vis"
7722   [(set (match_operand:V4HI 0 "register_operand" "=e")
7723         (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
7724                       (match_operand:V2HI 2 "register_operand" "f")]
7725          UNSPEC_MUL16AL))]
7726   "TARGET_VIS"
7727   "fmul8x16al\t%1, %2, %0"
7728   [(set_attr "type" "fpmul")
7729    (set_attr "fptype" "double")])
7731 ;; Only one of the following two insns can be a multiply.
7732 (define_insn "fmul8sux16_vis"
7733   [(set (match_operand:V4HI 0 "register_operand" "=e")
7734         (mult:V4HI (match_operand:V8QI 1 "register_operand" "e")
7735                    (match_operand:V4HI 2 "register_operand" "e")))]
7736   "TARGET_VIS"
7737   "fmul8sux16\t%1, %2, %0"
7738   [(set_attr "type" "fpmul")
7739    (set_attr "fptype" "double")])
7741 (define_insn "fmul8ulx16_vis"
7742   [(set (match_operand:V4HI 0 "register_operand" "=e")
7743         (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
7744                       (match_operand:V4HI 2 "register_operand" "e")]
7745          UNSPEC_MUL8UL))]
7746   "TARGET_VIS"
7747   "fmul8ulx16\t%1, %2, %0"
7748   [(set_attr "type" "fpmul")
7749    (set_attr "fptype" "double")])
7751 ;; Only one of the following two insns can be a multiply.
7752 (define_insn "fmuld8sux16_vis"
7753   [(set (match_operand:V2SI 0 "register_operand" "=e")
7754         (mult:V2SI (match_operand:V4QI 1 "register_operand" "f")
7755                    (match_operand:V2HI 2 "register_operand" "f")))]
7756   "TARGET_VIS"
7757   "fmuld8sux16\t%1, %2, %0"
7758   [(set_attr "type" "fpmul")
7759    (set_attr "fptype" "double")])
7761 (define_insn "fmuld8ulx16_vis"
7762   [(set (match_operand:V2SI 0 "register_operand" "=e")
7763         (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
7764                       (match_operand:V2HI 2 "register_operand" "f")]
7765          UNSPEC_MULDUL))]
7766   "TARGET_VIS"
7767   "fmuld8ulx16\t%1, %2, %0"
7768   [(set_attr "type" "fpmul")
7769    (set_attr "fptype" "double")])
7771 ;; Using faligndata only makes sense after an alignaddr since the choice of
7772 ;; bytes to take out of each operand is dependent on the results of the last
7773 ;; alignaddr.
7774 (define_insn "faligndata<V64I:mode>_vis"
7775   [(set (match_operand:V64I 0 "register_operand" "=e")
7776         (unspec:V64I [(match_operand:V64I 1 "register_operand" "e")
7777                       (match_operand:V64I 2 "register_operand" "e")]
7778          UNSPEC_ALIGNDATA))]
7779   "TARGET_VIS"
7780   "faligndata\t%1, %2, %0"
7781   [(set_attr "type" "fga")
7782    (set_attr "fptype" "double")])
7784 (define_insn "alignaddr<P:mode>_vis"
7785   [(set (match_operand:P 0 "register_operand" "=r")
7786         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
7787                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
7788          UNSPEC_ALIGNADDR))]
7789   "TARGET_VIS"
7790   "alignaddr\t%r1, %r2, %0")
7792 (define_insn "pdist_vis"
7793   [(set (match_operand:DI 0 "register_operand" "=e")
7794         (unspec:DI [(match_operand:V8QI 1 "register_operand" "e")
7795                     (match_operand:V8QI 2 "register_operand" "e")
7796                     (match_operand:DI 3 "register_operand" "0")]
7797          UNSPEC_PDIST))]
7798   "TARGET_VIS"
7799   "pdist\t%1, %2, %0"
7800   [(set_attr "type" "fga")
7801    (set_attr "fptype" "double")])
7803 (include "sync.md")