Merge from mainline (167278:168000).
[official-gcc/graphite-test-results.git] / gcc / config / sparc / sparc.md
blobf8939dd77d18bfe22f3e098bef697e1567bbe5b4
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 operand 0.
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" "")] UNSPEC_LOAD_PCREL_SYM))
1122    (clobber (reg:P 15))]
1123   ""
1125   if (flag_delayed_branch)
1126     return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0";
1127   else
1128     return "sethi\t%%hi(%a1-8), %0\n\tadd\t%0, %%lo(%a1-4), %0\n\tcall\t%a2\n\t nop";
1130   [(set (attr "type") (const_string "multi"))
1131    (set (attr "length")
1132         (if_then_else (eq_attr "delayed_branch" "true")
1133                       (const_int 3)
1134                       (const_int 4)))])
1137 ;; Integer move instructions
1139 (define_expand "movqi"
1140   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1141         (match_operand:QI 1 "general_operand" ""))]
1142   ""
1144   if (sparc_expand_move (QImode, operands))
1145     DONE;
1148 (define_insn "*movqi_insn"
1149   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1150         (match_operand:QI 1 "input_operand"   "rI,m,rJ"))]
1151   "(register_operand (operands[0], QImode)
1152     || register_or_zero_operand (operands[1], QImode))"
1153   "@
1154    mov\t%1, %0
1155    ldub\t%1, %0
1156    stb\t%r1, %0"
1157   [(set_attr "type" "*,load,store")
1158    (set_attr "us3load_type" "*,3cycle,*")])
1160 (define_expand "movhi"
1161   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1162         (match_operand:HI 1 "general_operand" ""))]
1163   ""
1165   if (sparc_expand_move (HImode, operands))
1166     DONE;
1169 (define_insn "*movhi_insn"
1170   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1171         (match_operand:HI 1 "input_operand"   "rI,K,m,rJ"))]
1172   "(register_operand (operands[0], HImode)
1173     || register_or_zero_operand (operands[1], HImode))"
1174   "@
1175    mov\t%1, %0
1176    sethi\t%%hi(%a1), %0
1177    lduh\t%1, %0
1178    sth\t%r1, %0"
1179   [(set_attr "type" "*,*,load,store")
1180    (set_attr "us3load_type" "*,*,3cycle,*")])
1182 ;; We always work with constants here.
1183 (define_insn "*movhi_lo_sum"
1184   [(set (match_operand:HI 0 "register_operand" "=r")
1185         (ior:HI (match_operand:HI 1 "register_operand" "%r")
1186                 (match_operand:HI 2 "small_int_operand" "I")))]
1187   ""
1188   "or\t%1, %2, %0")
1190 (define_expand "movsi"
1191   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1192         (match_operand:SI 1 "general_operand" ""))]
1193   ""
1195   if (sparc_expand_move (SImode, operands))
1196     DONE;
1199 (define_insn "*movsi_insn"
1200   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m,!f,!f,!m,d")
1201         (match_operand:SI 1 "input_operand"   "rI,K,m,rJ,f,m,f,J"))]
1202   "(register_operand (operands[0], SImode)
1203     || register_or_zero_operand (operands[1], SImode))"
1204   "@
1205    mov\t%1, %0
1206    sethi\t%%hi(%a1), %0
1207    ld\t%1, %0
1208    st\t%r1, %0
1209    fmovs\t%1, %0
1210    ld\t%1, %0
1211    st\t%1, %0
1212    fzeros\t%0"
1213   [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga")])
1215 (define_insn "*movsi_lo_sum"
1216   [(set (match_operand:SI 0 "register_operand" "=r")
1217         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1218                    (match_operand:SI 2 "immediate_operand" "in")))]
1219   ""
1220   "or\t%1, %%lo(%a2), %0")
1222 (define_insn "*movsi_high"
1223   [(set (match_operand:SI 0 "register_operand" "=r")
1224         (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1225   ""
1226   "sethi\t%%hi(%a1), %0")
1228 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1229 ;; so that CSE won't optimize the address computation away.
1230 (define_insn "movsi_lo_sum_pic"
1231   [(set (match_operand:SI 0 "register_operand" "=r")
1232         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1233                    (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1234   "flag_pic"
1236 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1237   return "xor\t%1, %%gdop_lox10(%a2), %0";
1238 #else
1239   return "or\t%1, %%lo(%a2), %0";
1240 #endif
1243 (define_insn "movsi_high_pic"
1244   [(set (match_operand:SI 0 "register_operand" "=r")
1245         (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1246   "flag_pic && check_pic (1)"
1248 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1249   return "sethi\t%%gdop_hix22(%a1), %0";
1250 #else
1251   return "sethi\t%%hi(%a1), %0";
1252 #endif
1255 (define_insn "movsi_pic_gotdata_op"
1256   [(set (match_operand:SI 0 "register_operand" "=r")
1257         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
1258                     (match_operand:SI 2 "register_operand" "r")
1259                     (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
1260   "flag_pic && check_pic (1)"
1262 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1263   return "ld\t[%1 + %2], %0, %%gdop(%a3)";
1264 #else
1265   return "ld\t[%1 + %2], %0";
1266 #endif
1268   [(set_attr "type" "load")])
1270 (define_expand "movsi_pic_label_ref"
1271   [(set (match_dup 3) (high:SI
1272      (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1273                  (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1274    (set (match_dup 4) (lo_sum:SI (match_dup 3)
1275      (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1276    (set (match_operand:SI 0 "register_operand" "=r")
1277         (minus:SI (match_dup 5) (match_dup 4)))]
1278   "flag_pic"
1280   crtl->uses_pic_offset_table = 1;
1281   operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1282   if (!can_create_pseudo_p ())
1283     {
1284       operands[3] = operands[0];
1285       operands[4] = operands[0];
1286     }
1287   else
1288     {
1289       operands[3] = gen_reg_rtx (SImode);
1290       operands[4] = gen_reg_rtx (SImode);
1291     }
1292   operands[5] = pic_offset_table_rtx;
1295 (define_insn "*movsi_high_pic_label_ref"
1296   [(set (match_operand:SI 0 "register_operand" "=r")
1297       (high:SI
1298         (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1299                     (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1300   "flag_pic"
1301   "sethi\t%%hi(%a2-(%a1-.)), %0")
1303 (define_insn "*movsi_lo_sum_pic_label_ref"
1304   [(set (match_operand:SI 0 "register_operand" "=r")
1305       (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1306         (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
1307                     (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1308   "flag_pic"
1309   "or\t%1, %%lo(%a3-(%a2-.)), %0")
1311 ;; Set up the PIC register for VxWorks.
1313 (define_expand "vxworks_load_got"
1314   [(set (match_dup 0)
1315         (high:SI (match_dup 1)))
1316    (set (match_dup 0)
1317         (mem:SI (lo_sum:SI (match_dup 0) (match_dup 1))))
1318    (set (match_dup 0)
1319         (mem:SI (lo_sum:SI (match_dup 0) (match_dup 2))))]
1320   "TARGET_VXWORKS_RTP"
1322   operands[0] = pic_offset_table_rtx;
1323   operands[1] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_BASE);
1324   operands[2] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_INDEX);
1327 (define_expand "movdi"
1328   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1329         (match_operand:DI 1 "general_operand" ""))]
1330   ""
1332   if (sparc_expand_move (DImode, operands))
1333     DONE;
1336 ;; Be careful, fmovd does not exist when !v9.
1337 ;; We match MEM moves directly when we have correct even
1338 ;; numbered registers, but fall into splits otherwise.
1339 ;; The constraint ordering here is really important to
1340 ;; avoid insane problems in reload, especially for patterns
1341 ;; of the form:
1343 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
1344 ;;                       (const_int -5016)))
1345 ;;      (reg:DI 2 %g2))
1348 (define_insn "*movdi_insn_sp32"
1349   [(set (match_operand:DI 0 "nonimmediate_operand"
1350                                 "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
1351         (match_operand:DI 1 "input_operand"
1352                                 " J,U,T,r,o,i,r, f, T, o, f, f"))]
1353   "! TARGET_V9
1354    && (register_operand (operands[0], DImode)
1355        || register_or_zero_operand (operands[1], DImode))"
1356   "@
1357    #
1358    std\t%1, %0
1359    ldd\t%1, %0
1360    #
1361    #
1362    #
1363    #
1364    std\t%1, %0
1365    ldd\t%1, %0
1366    #
1367    #
1368    #"
1369   [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
1370    (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
1372 (define_insn "*movdi_insn_sp32_v9"
1373   [(set (match_operand:DI 0 "nonimmediate_operand"
1374                                         "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?e,?e,?W")
1375         (match_operand:DI 1 "input_operand"
1376                                         " J,J,U,T,r,o,i,r, f, T, o, f, e, W, e"))]
1377   "! TARGET_ARCH64
1378    && TARGET_V9
1379    && (register_operand (operands[0], DImode)
1380        || register_or_zero_operand (operands[1], DImode))"
1381   "@
1382    stx\t%%g0, %0
1383    #
1384    std\t%1, %0
1385    ldd\t%1, %0
1386    #
1387    #
1388    #
1389    #
1390    std\t%1, %0
1391    ldd\t%1, %0
1392    #
1393    #
1394    fmovd\\t%1, %0
1395    ldd\\t%1, %0
1396    std\\t%1, %0"
1397   [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,fpload,fpstore")
1398    (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,*,*")
1399    (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])
1401 (define_insn "*movdi_insn_sp64"
1402   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,m,?e,?e,?W,b")
1403         (match_operand:DI 1 "input_operand"   "rI,N,m,rJ,e,W,e,J"))]
1404   "TARGET_ARCH64
1405    && (register_operand (operands[0], DImode)
1406        || register_or_zero_operand (operands[1], DImode))"
1407   "@
1408    mov\t%1, %0
1409    sethi\t%%hi(%a1), %0
1410    ldx\t%1, %0
1411    stx\t%r1, %0
1412    fmovd\t%1, %0
1413    ldd\t%1, %0
1414    std\t%1, %0
1415    fzero\t%0"
1416   [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga")
1417    (set_attr "fptype" "*,*,*,*,double,*,*,double")])
1419 (define_expand "movdi_pic_label_ref"
1420   [(set (match_dup 3) (high:DI
1421      (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1422                  (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1423    (set (match_dup 4) (lo_sum:DI (match_dup 3)
1424      (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1425    (set (match_operand:DI 0 "register_operand" "=r")
1426         (minus:DI (match_dup 5) (match_dup 4)))]
1427   "TARGET_ARCH64 && flag_pic"
1429   crtl->uses_pic_offset_table = 1;
1430   operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1431   if (!can_create_pseudo_p ())
1432     {
1433       operands[3] = operands[0];
1434       operands[4] = operands[0];
1435     }
1436   else
1437     {
1438       operands[3] = gen_reg_rtx (DImode);
1439       operands[4] = gen_reg_rtx (DImode);
1440     }
1441   operands[5] = pic_offset_table_rtx;
1444 (define_insn "*movdi_high_pic_label_ref"
1445   [(set (match_operand:DI 0 "register_operand" "=r")
1446         (high:DI
1447           (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1448                       (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1449   "TARGET_ARCH64 && flag_pic"
1450   "sethi\t%%hi(%a2-(%a1-.)), %0")
1452 (define_insn "*movdi_lo_sum_pic_label_ref"
1453   [(set (match_operand:DI 0 "register_operand" "=r")
1454       (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1455         (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
1456                     (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1457   "TARGET_ARCH64 && flag_pic"
1458   "or\t%1, %%lo(%a3-(%a2-.)), %0")
1460 ;; SPARC-v9 code model support insns.  See sparc_emit_set_symbolic_const64
1461 ;; in sparc.c to see what is going on here... PIC stuff comes first.
1463 (define_insn "movdi_lo_sum_pic"
1464   [(set (match_operand:DI 0 "register_operand" "=r")
1465         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1466                    (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1467   "TARGET_ARCH64 && flag_pic"
1469 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1470   return "xor\t%1, %%gdop_lox10(%a2), %0";
1471 #else
1472   return "or\t%1, %%lo(%a2), %0";
1473 #endif
1476 (define_insn "movdi_high_pic"
1477   [(set (match_operand:DI 0 "register_operand" "=r")
1478         (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1479   "TARGET_ARCH64 && flag_pic && check_pic (1)"
1481 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1482   return "sethi\t%%gdop_hix22(%a1), %0";
1483 #else
1484   return "sethi\t%%hi(%a1), %0";
1485 #endif
1488 (define_insn "movdi_pic_gotdata_op"
1489   [(set (match_operand:DI 0 "register_operand" "=r")
1490         (unspec:DI [(match_operand:DI 1 "register_operand" "r")
1491                     (match_operand:DI 2 "register_operand" "r")
1492                     (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
1493   "TARGET_ARCH64 && flag_pic && check_pic (1)"
1495 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1496   return "ldx\t[%1 + %2], %0, %%gdop(%a3)";
1497 #else
1498   return "ldx\t[%1 + %2], %0";
1499 #endif
1501   [(set_attr "type" "load")])
1503 (define_insn "*sethi_di_medlow_embmedany_pic"
1504   [(set (match_operand:DI 0 "register_operand" "=r")
1505         (high:DI (match_operand:DI 1 "medium_pic_operand" "")))]
1506   "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
1507   "sethi\t%%hi(%a1), %0")
1509 (define_insn "*sethi_di_medlow"
1510   [(set (match_operand:DI 0 "register_operand" "=r")
1511         (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
1512   "TARGET_CM_MEDLOW && check_pic (1)"
1513   "sethi\t%%hi(%a1), %0")
1515 (define_insn "*losum_di_medlow"
1516   [(set (match_operand:DI 0 "register_operand" "=r")
1517         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1518                    (match_operand:DI 2 "symbolic_operand" "")))]
1519   "TARGET_CM_MEDLOW"
1520   "or\t%1, %%lo(%a2), %0")
1522 (define_insn "seth44"
1523   [(set (match_operand:DI 0 "register_operand" "=r")
1524         (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
1525   "TARGET_CM_MEDMID"
1526   "sethi\t%%h44(%a1), %0")
1528 (define_insn "setm44"
1529   [(set (match_operand:DI 0 "register_operand" "=r")
1530         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1531                    (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
1532   "TARGET_CM_MEDMID"
1533   "or\t%1, %%m44(%a2), %0")
1535 (define_insn "setl44"
1536   [(set (match_operand:DI 0 "register_operand" "=r")
1537         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1538                    (match_operand:DI 2 "symbolic_operand" "")))]
1539   "TARGET_CM_MEDMID"
1540   "or\t%1, %%l44(%a2), %0")
1542 (define_insn "sethh"
1543   [(set (match_operand:DI 0 "register_operand" "=r")
1544         (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
1545   "TARGET_CM_MEDANY"
1546   "sethi\t%%hh(%a1), %0")
1548 (define_insn "setlm"
1549   [(set (match_operand:DI 0 "register_operand" "=r")
1550         (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
1551   "TARGET_CM_MEDANY"
1552   "sethi\t%%lm(%a1), %0")
1554 (define_insn "sethm"
1555   [(set (match_operand:DI 0 "register_operand" "=r")
1556         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1557                    (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
1558   "TARGET_CM_MEDANY"
1559   "or\t%1, %%hm(%a2), %0")
1561 (define_insn "setlo"
1562   [(set (match_operand:DI 0 "register_operand" "=r")
1563         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1564                    (match_operand:DI 2 "symbolic_operand" "")))]
1565   "TARGET_CM_MEDANY"
1566   "or\t%1, %%lo(%a2), %0")
1568 (define_insn "embmedany_sethi"
1569   [(set (match_operand:DI 0 "register_operand" "=r")
1570         (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
1571   "TARGET_CM_EMBMEDANY && check_pic (1)"
1572   "sethi\t%%hi(%a1), %0")
1574 (define_insn "embmedany_losum"
1575   [(set (match_operand:DI 0 "register_operand" "=r")
1576         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1577                    (match_operand:DI 2 "data_segment_operand" "")))]
1578   "TARGET_CM_EMBMEDANY"
1579   "add\t%1, %%lo(%a2), %0")
1581 (define_insn "embmedany_brsum"
1582   [(set (match_operand:DI 0 "register_operand" "=r")
1583         (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
1584   "TARGET_CM_EMBMEDANY"
1585   "add\t%1, %_, %0")
1587 (define_insn "embmedany_textuhi"
1588   [(set (match_operand:DI 0 "register_operand" "=r")
1589         (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
1590   "TARGET_CM_EMBMEDANY && check_pic (1)"
1591   "sethi\t%%uhi(%a1), %0")
1593 (define_insn "embmedany_texthi"
1594   [(set (match_operand:DI 0 "register_operand" "=r")
1595         (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
1596   "TARGET_CM_EMBMEDANY && check_pic (1)"
1597   "sethi\t%%hi(%a1), %0")
1599 (define_insn "embmedany_textulo"
1600   [(set (match_operand:DI 0 "register_operand" "=r")
1601         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1602                    (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
1603   "TARGET_CM_EMBMEDANY"
1604   "or\t%1, %%ulo(%a2), %0")
1606 (define_insn "embmedany_textlo"
1607   [(set (match_operand:DI 0 "register_operand" "=r")
1608         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1609                    (match_operand:DI 2 "text_segment_operand" "")))]
1610   "TARGET_CM_EMBMEDANY"
1611   "or\t%1, %%lo(%a2), %0")
1613 ;; Now some patterns to help reload out a bit.
1614 (define_expand "reload_indi"
1615   [(parallel [(match_operand:DI 0 "register_operand" "=r")
1616               (match_operand:DI 1 "immediate_operand" "")
1617               (match_operand:TI 2 "register_operand" "=&r")])]
1618   "(TARGET_CM_MEDANY
1619     || TARGET_CM_EMBMEDANY)
1620    && ! flag_pic"
1622   sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1623   DONE;
1626 (define_expand "reload_outdi"
1627   [(parallel [(match_operand:DI 0 "register_operand" "=r")
1628               (match_operand:DI 1 "immediate_operand" "")
1629               (match_operand:TI 2 "register_operand" "=&r")])]
1630   "(TARGET_CM_MEDANY
1631     || TARGET_CM_EMBMEDANY)
1632    && ! flag_pic"
1634   sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1635   DONE;
1638 ;; Split up putting CONSTs and REGs into DI regs when !arch64
1639 (define_split
1640   [(set (match_operand:DI 0 "register_operand" "")
1641         (match_operand:DI 1 "const_int_operand" ""))]
1642   "! TARGET_ARCH64 && reload_completed"
1643   [(clobber (const_int 0))]
1645 #if HOST_BITS_PER_WIDE_INT == 32
1646   emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1647                         (INTVAL (operands[1]) < 0) ?
1648                         constm1_rtx :
1649                         const0_rtx));
1650   emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1651                         operands[1]));
1652 #else
1653   unsigned int low, high;
1655   low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
1656   high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
1657   emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
1659   /* Slick... but this trick loses if this subreg constant part
1660      can be done in one insn.  */
1661   if (low == high
1662       && ! SPARC_SETHI32_P (high)
1663       && ! SPARC_SIMM13_P (high))
1664     emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1665                           gen_highpart (SImode, operands[0])));
1666   else
1667     emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
1668 #endif
1669   DONE;
1672 (define_split
1673   [(set (match_operand:DI 0 "register_operand" "")
1674         (match_operand:DI 1 "const_double_operand" ""))]
1675   "reload_completed
1676    && (! TARGET_V9
1677        || (! TARGET_ARCH64
1678            && ((GET_CODE (operands[0]) == REG
1679                 && REGNO (operands[0]) < 32)
1680                || (GET_CODE (operands[0]) == SUBREG
1681                    && GET_CODE (SUBREG_REG (operands[0])) == REG
1682                    && REGNO (SUBREG_REG (operands[0])) < 32))))"
1683   [(clobber (const_int 0))]
1685   emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1686                         GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
1688   /* Slick... but this trick loses if this subreg constant part
1689      can be done in one insn.  */
1690   if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
1691       && ! SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
1692       && ! SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1])))
1693     {
1694       emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1695                             gen_highpart (SImode, operands[0])));
1696     }
1697   else
1698     {
1699       emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1700                             GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
1701     }
1702   DONE;
1705 (define_split
1706   [(set (match_operand:DI 0 "register_operand" "")
1707         (match_operand:DI 1 "register_operand" ""))]
1708   "reload_completed
1709    && (! TARGET_V9
1710        || (! TARGET_ARCH64
1711            && ((GET_CODE (operands[0]) == REG
1712                 && REGNO (operands[0]) < 32)
1713                || (GET_CODE (operands[0]) == SUBREG
1714                    && GET_CODE (SUBREG_REG (operands[0])) == REG
1715                    && REGNO (SUBREG_REG (operands[0])) < 32))))"
1716   [(clobber (const_int 0))]
1718   rtx set_dest = operands[0];
1719   rtx set_src = operands[1];
1720   rtx dest1, dest2;
1721   rtx src1, src2;
1723   dest1 = gen_highpart (SImode, set_dest);
1724   dest2 = gen_lowpart (SImode, set_dest);
1725   src1 = gen_highpart (SImode, set_src);
1726   src2 = gen_lowpart (SImode, set_src);
1728   /* Now emit using the real source and destination we found, swapping
1729      the order if we detect overlap.  */
1730   if (reg_overlap_mentioned_p (dest1, src2))
1731     {
1732       emit_insn (gen_movsi (dest2, src2));
1733       emit_insn (gen_movsi (dest1, src1));
1734     }
1735   else
1736     {
1737       emit_insn (gen_movsi (dest1, src1));
1738       emit_insn (gen_movsi (dest2, src2));
1739     }
1740   DONE;
1743 ;; Now handle the cases of memory moves from/to non-even
1744 ;; DI mode register pairs.
1745 (define_split
1746   [(set (match_operand:DI 0 "register_operand" "")
1747         (match_operand:DI 1 "memory_operand" ""))]
1748   "(! TARGET_ARCH64
1749     && reload_completed
1750     && sparc_splitdi_legitimate (operands[0], operands[1]))"
1751   [(clobber (const_int 0))]
1753   rtx word0 = adjust_address (operands[1], SImode, 0);
1754   rtx word1 = adjust_address (operands[1], SImode, 4);
1755   rtx high_part = gen_highpart (SImode, operands[0]);
1756   rtx low_part = gen_lowpart (SImode, operands[0]);
1758   if (reg_overlap_mentioned_p (high_part, word1))
1759     {
1760       emit_insn (gen_movsi (low_part, word1));
1761       emit_insn (gen_movsi (high_part, word0));
1762     }
1763   else
1764     {
1765       emit_insn (gen_movsi (high_part, word0));
1766       emit_insn (gen_movsi (low_part, word1));
1767     }
1768   DONE;
1771 (define_split
1772   [(set (match_operand:DI 0 "memory_operand" "")
1773         (match_operand:DI 1 "register_operand" ""))]
1774   "(! TARGET_ARCH64
1775     && reload_completed
1776     && sparc_splitdi_legitimate (operands[1], operands[0]))"
1777   [(clobber (const_int 0))]
1779   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
1780                         gen_highpart (SImode, operands[1])));
1781   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
1782                         gen_lowpart (SImode, operands[1])));
1783   DONE;
1786 (define_split
1787   [(set (match_operand:DI 0 "memory_operand" "")
1788         (match_operand:DI 1 "const_zero_operand" ""))]
1789   "reload_completed
1790    && (! TARGET_V9
1791        || (! TARGET_ARCH64
1792            && ! mem_min_alignment (operands[0], 8)))
1793    && offsettable_memref_p (operands[0])"
1794   [(clobber (const_int 0))]
1796   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
1797   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
1798   DONE;
1802 ;; Floating point and vector move instructions
1804 ;; Yes, you guessed it right, the former movsf expander.
1805 (define_expand "mov<V32:mode>"
1806   [(set (match_operand:V32 0 "nonimmediate_operand" "")
1807         (match_operand:V32 1 "general_operand" ""))]
1808   "<V32:MODE>mode == SFmode || TARGET_VIS"
1810   if (sparc_expand_move (<V32:MODE>mode, operands))
1811     DONE;
1814 (define_insn "*movsf_insn"
1815   [(set (match_operand:V32 0 "nonimmediate_operand" "=d,f,*r,*r,*r,f,*r,m,m")
1816         (match_operand:V32 1 "input_operand"        "GY,f,*rRY,Q,S,m,m,f,*rGY"))]
1817   "TARGET_FPU
1818    && (register_operand (operands[0], <V32:MODE>mode)
1819        || register_or_zero_operand (operands[1], <V32:MODE>mode))"
1821   if (GET_CODE (operands[1]) == CONST_DOUBLE
1822       && (which_alternative == 2
1823           || which_alternative == 3
1824           || which_alternative == 4))
1825     {
1826       REAL_VALUE_TYPE r;
1827       long i;
1829       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
1830       REAL_VALUE_TO_TARGET_SINGLE (r, i);
1831       operands[1] = GEN_INT (i);
1832     }
1834   switch (which_alternative)
1835     {
1836     case 0:
1837       return "fzeros\t%0";
1838     case 1:
1839       return "fmovs\t%1, %0";
1840     case 2:
1841       return "mov\t%1, %0";
1842     case 3:
1843       return "sethi\t%%hi(%a1), %0";
1844     case 4:
1845       return "#";
1846     case 5:
1847     case 6:
1848       return "ld\t%1, %0";
1849     case 7:
1850     case 8:
1851       return "st\t%r1, %0";
1852     default:
1853       gcc_unreachable ();
1854     }
1856   [(set_attr "type" "fga,fpmove,*,*,*,fpload,load,fpstore,store")])
1858 ;; Exactly the same as above, except that all `f' cases are deleted.
1859 ;; This is necessary to prevent reload from ever trying to use a `f' reg
1860 ;; when -mno-fpu.
1862 (define_insn "*movsf_insn_no_fpu"
1863   [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,m")
1864         (match_operand:SF 1 "input_operand"    "rR,Q,S,m,rG"))]
1865   "! TARGET_FPU
1866    && (register_operand (operands[0], SFmode)
1867        || register_or_zero_operand (operands[1], SFmode))"
1869   if (GET_CODE (operands[1]) == CONST_DOUBLE
1870       && (which_alternative == 0
1871           || which_alternative == 1
1872           || which_alternative == 2))
1873     {
1874       REAL_VALUE_TYPE r;
1875       long i;
1877       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
1878       REAL_VALUE_TO_TARGET_SINGLE (r, i);
1879       operands[1] = GEN_INT (i);
1880     }
1882   switch (which_alternative)
1883     {
1884     case 0:
1885       return "mov\t%1, %0";
1886     case 1:
1887       return "sethi\t%%hi(%a1), %0";
1888     case 2:
1889       return "#";
1890     case 3:
1891       return "ld\t%1, %0";
1892     case 4:
1893       return "st\t%r1, %0";
1894     default:
1895       gcc_unreachable ();
1896     }
1898   [(set_attr "type" "*,*,*,load,store")])
1900 ;; The following 3 patterns build SFmode constants in integer registers.
1902 (define_insn "*movsf_lo_sum"
1903   [(set (match_operand:SF 0 "register_operand" "=r")
1904         (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
1905                    (match_operand:SF 2 "fp_const_high_losum_operand" "S")))]
1906   ""
1908   REAL_VALUE_TYPE r;
1909   long i;
1911   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
1912   REAL_VALUE_TO_TARGET_SINGLE (r, i);
1913   operands[2] = GEN_INT (i);
1914   return "or\t%1, %%lo(%a2), %0";
1917 (define_insn "*movsf_high"
1918   [(set (match_operand:SF 0 "register_operand" "=r")
1919         (high:SF (match_operand:SF 1 "fp_const_high_losum_operand" "S")))]
1920   ""
1922   REAL_VALUE_TYPE r;
1923   long i;
1925   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
1926   REAL_VALUE_TO_TARGET_SINGLE (r, i);
1927   operands[1] = GEN_INT (i);
1928   return "sethi\t%%hi(%1), %0";
1931 (define_split
1932   [(set (match_operand:SF 0 "register_operand" "")
1933         (match_operand:SF 1 "fp_const_high_losum_operand" ""))]
1934   "REG_P (operands[0]) && REGNO (operands[0]) < 32"
1935   [(set (match_dup 0) (high:SF (match_dup 1)))
1936    (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
1938 ;; Yes, you again guessed it right, the former movdf expander.
1939 (define_expand "mov<V64:mode>"
1940   [(set (match_operand:V64 0 "nonimmediate_operand" "")
1941         (match_operand:V64 1 "general_operand" ""))]
1942   "<V64:MODE>mode == DFmode || TARGET_VIS"
1944   if (sparc_expand_move (<V64:MODE>mode, operands))
1945     DONE;
1948 ;; Be careful, fmovd does not exist when !v9.
1949 (define_insn "*movdf_insn_sp32"
1950   [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o")
1951         (match_operand:DF 1 "input_operand"    "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
1952   "TARGET_FPU
1953    && ! TARGET_V9
1954    && (register_operand (operands[0], DFmode)
1955        || register_or_zero_operand (operands[1], DFmode))"
1956   "@
1957   ldd\t%1, %0
1958   std\t%1, %0
1959   ldd\t%1, %0
1960   std\t%1, %0
1961   #
1962   #
1963   #
1964   #
1965   #
1966   #"
1967  [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
1968   (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
1970 (define_insn "*movdf_insn_sp32_no_fpu"
1971   [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
1972         (match_operand:DF 1 "input_operand"    "T,U,G,ro,r"))]
1973   "! TARGET_FPU
1974    && ! TARGET_V9
1975    && (register_operand (operands[0], DFmode)
1976        || register_or_zero_operand (operands[1], DFmode))"
1977   "@
1978   ldd\t%1, %0
1979   std\t%1, %0
1980   #
1981   #
1982   #"
1983   [(set_attr "type" "load,store,*,*,*")
1984    (set_attr "length" "*,*,2,2,2")])
1986 ;; We have available v9 double floats but not 64-bit integer registers.
1987 (define_insn "*movdf_insn_sp32_v9"
1988   [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,T,W,U,T,f,*r,o")
1989         (match_operand:V64 1 "input_operand" "GY,e,W#F,GY,e,T,U,o#F,*roGYDF,*rGYf"))]
1990   "TARGET_FPU
1991    && TARGET_V9
1992    && ! TARGET_ARCH64
1993    && (register_operand (operands[0], <V64:MODE>mode)
1994        || register_or_zero_operand (operands[1], <V64:MODE>mode))"
1995   "@
1996   fzero\t%0
1997   fmovd\t%1, %0
1998   ldd\t%1, %0
1999   stx\t%r1, %0
2000   std\t%1, %0
2001   ldd\t%1, %0
2002   std\t%1, %0
2003   #
2004   #
2005   #"
2006   [(set_attr "type" "fga,fpmove,load,store,store,load,store,*,*,*")
2007    (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
2008    (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
2010 (define_insn "*movdf_insn_sp32_v9_no_fpu"
2011   [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
2012         (match_operand:DF 1 "input_operand"    "T,U,G,ro,rG"))]
2013   "! TARGET_FPU
2014    && TARGET_V9
2015    && ! TARGET_ARCH64
2016    && (register_operand (operands[0], DFmode)
2017        || register_or_zero_operand (operands[1], DFmode))"
2018   "@
2019   ldd\t%1, %0
2020   std\t%1, %0
2021   stx\t%r1, %0
2022   #
2023   #"
2024   [(set_attr "type" "load,store,store,*,*")
2025    (set_attr "length" "*,*,*,2,2")])
2027 ;; We have available both v9 double floats and 64-bit integer registers.
2028 (define_insn "*movdf_insn_sp64"
2029   [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,W,*r,*r,m,*r")
2030         (match_operand:V64 1 "input_operand"    "GY,e,W#F,e,*rGY,m,*rGY,DF"))]
2031   "TARGET_FPU
2032    && TARGET_ARCH64
2033    && (register_operand (operands[0], <V64:MODE>mode)
2034        || register_or_zero_operand (operands[1], <V64:MODE>mode))"
2035   "@
2036   fzero\t%0
2037   fmovd\t%1, %0
2038   ldd\t%1, %0
2039   std\t%1, %0
2040   mov\t%r1, %0
2041   ldx\t%1, %0
2042   stx\t%r1, %0
2043   #"
2044   [(set_attr "type" "fga,fpmove,load,store,*,load,store,*")
2045    (set_attr "length" "*,*,*,*,*,*,*,2")
2046    (set_attr "fptype" "double,double,*,*,*,*,*,*")])
2048 (define_insn "*movdf_insn_sp64_no_fpu"
2049   [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
2050         (match_operand:DF 1 "input_operand"    "r,m,rG"))]
2051   "! TARGET_FPU
2052    && TARGET_ARCH64
2053    && (register_operand (operands[0], DFmode)
2054        || register_or_zero_operand (operands[1], DFmode))"
2055   "@
2056   mov\t%1, %0
2057   ldx\t%1, %0
2058   stx\t%r1, %0"
2059   [(set_attr "type" "*,load,store")])
2061 ;; This pattern builds V64mode constants in integer registers.
2062 (define_split
2063   [(set (match_operand:V64 0 "register_operand" "")
2064         (match_operand:V64 1 "const_double_or_vector_operand" ""))]
2065   "TARGET_FPU
2066    && (GET_CODE (operands[0]) == REG
2067        && REGNO (operands[0]) < 32)
2068    && ! const_zero_operand (operands[1], GET_MODE (operands[0]))
2069    && reload_completed"
2070   [(clobber (const_int 0))]
2072   operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
2074   if (TARGET_ARCH64)
2075     {
2076 #if HOST_BITS_PER_WIDE_INT == 32
2077       gcc_unreachable ();
2078 #else
2079       enum machine_mode mode = GET_MODE (operands[1]);
2080       rtx tem = simplify_subreg (DImode, operands[1], mode, 0);
2081       emit_insn (gen_movdi (operands[0], tem));
2082 #endif
2083     }
2084   else
2085     {
2086       enum machine_mode mode = GET_MODE (operands[1]);
2087       rtx hi = simplify_subreg (SImode, operands[1], mode, 0);
2088       rtx lo = simplify_subreg (SImode, operands[1], mode, 4);
2090       gcc_assert (GET_CODE (hi) == CONST_INT);
2091       gcc_assert (GET_CODE (lo) == CONST_INT);
2093       emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), hi));
2095       /* Slick... but this trick loses if this subreg constant part
2096          can be done in one insn.  */
2097       if (lo == hi
2098           && ! SPARC_SETHI32_P (INTVAL (hi))
2099           && ! SPARC_SIMM13_P (INTVAL (hi)))
2100         {
2101           emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2102                                 gen_highpart (SImode, operands[0])));
2103         }
2104       else
2105         {
2106           emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), lo));
2107         }
2108     }
2109   DONE;
2112 ;; Ok, now the splits to handle all the multi insn and
2113 ;; mis-aligned memory address cases.
2114 ;; In these splits please take note that we must be
2115 ;; careful when V9 but not ARCH64 because the integer
2116 ;; register DFmode cases must be handled.
2117 (define_split
2118   [(set (match_operand:V64 0 "register_operand" "")
2119         (match_operand:V64 1 "register_operand" ""))]
2120   "(! TARGET_V9
2121     || (! TARGET_ARCH64
2122         && ((GET_CODE (operands[0]) == REG
2123              && REGNO (operands[0]) < 32)
2124             || (GET_CODE (operands[0]) == SUBREG
2125                 && GET_CODE (SUBREG_REG (operands[0])) == REG
2126                 && REGNO (SUBREG_REG (operands[0])) < 32))))
2127    && reload_completed"
2128   [(clobber (const_int 0))]
2130   rtx set_dest = operands[0];
2131   rtx set_src = operands[1];
2132   rtx dest1, dest2;
2133   rtx src1, src2;
2134   enum machine_mode half_mode;
2136   /* We can be expanded for DFmode or integral vector modes.  */
2137   if (<V64:MODE>mode == DFmode)
2138     half_mode = SFmode;
2139   else
2140     half_mode = SImode;
2141   
2142   dest1 = gen_highpart (half_mode, set_dest);
2143   dest2 = gen_lowpart (half_mode, set_dest);
2144   src1 = gen_highpart (half_mode, set_src);
2145   src2 = gen_lowpart (half_mode, set_src);
2147   /* Now emit using the real source and destination we found, swapping
2148      the order if we detect overlap.  */
2149   if (reg_overlap_mentioned_p (dest1, src2))
2150     {
2151       emit_move_insn_1 (dest2, src2);
2152       emit_move_insn_1 (dest1, src1);
2153     }
2154   else
2155     {
2156       emit_move_insn_1 (dest1, src1);
2157       emit_move_insn_1 (dest2, src2);
2158     }
2159   DONE;
2162 (define_split
2163   [(set (match_operand:V64 0 "register_operand" "")
2164         (match_operand:V64 1 "memory_operand" ""))]
2165   "reload_completed
2166    && ! TARGET_ARCH64
2167    && (((REGNO (operands[0]) % 2) != 0)
2168        || ! mem_min_alignment (operands[1], 8))
2169    && offsettable_memref_p (operands[1])"
2170   [(clobber (const_int 0))]
2172   enum machine_mode half_mode;
2173   rtx word0, word1;
2175   /* We can be expanded for DFmode or integral vector modes.  */
2176   if (<V64:MODE>mode == DFmode)
2177     half_mode = SFmode;
2178   else
2179     half_mode = SImode;
2181   word0 = adjust_address (operands[1], half_mode, 0);
2182   word1 = adjust_address (operands[1], half_mode, 4);
2184   if (reg_overlap_mentioned_p (gen_highpart (half_mode, operands[0]), word1))
2185     {
2186       emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2187       emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2188     }
2189   else
2190     {
2191       emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2192       emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2193     }
2194   DONE;
2197 (define_split
2198   [(set (match_operand:V64 0 "memory_operand" "")
2199         (match_operand:V64 1 "register_operand" ""))]
2200   "reload_completed
2201    && ! TARGET_ARCH64
2202    && (((REGNO (operands[1]) % 2) != 0)
2203        || ! mem_min_alignment (operands[0], 8))
2204    && offsettable_memref_p (operands[0])"
2205   [(clobber (const_int 0))]
2207   enum machine_mode half_mode;
2208   rtx word0, word1;
2210   /* We can be expanded for DFmode or integral vector modes.  */
2211   if (<V64:MODE>mode == DFmode)
2212     half_mode = SFmode;
2213   else
2214     half_mode = SImode;
2216   word0 = adjust_address (operands[0], half_mode, 0);
2217   word1 = adjust_address (operands[0], half_mode, 4);
2219   emit_move_insn_1 (word0, gen_highpart (half_mode, operands[1]));
2220   emit_move_insn_1 (word1, gen_lowpart (half_mode, operands[1]));
2221   DONE;
2224 (define_split
2225   [(set (match_operand:V64 0 "memory_operand" "")
2226         (match_operand:V64 1 "const_zero_operand" ""))]
2227   "reload_completed
2228    && (! TARGET_V9
2229        || (! TARGET_ARCH64
2230            && ! mem_min_alignment (operands[0], 8)))
2231    && offsettable_memref_p (operands[0])"
2232   [(clobber (const_int 0))]
2234   enum machine_mode half_mode;
2235   rtx dest1, dest2;
2237   /* We can be expanded for DFmode or integral vector modes.  */
2238   if (<V64:MODE>mode == DFmode)
2239     half_mode = SFmode;
2240   else
2241     half_mode = SImode;
2243   dest1 = adjust_address (operands[0], half_mode, 0);
2244   dest2 = adjust_address (operands[0], half_mode, 4);
2246   emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2247   emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2248   DONE;
2251 (define_split
2252   [(set (match_operand:V64 0 "register_operand" "")
2253         (match_operand:V64 1 "const_zero_operand" ""))]
2254   "reload_completed
2255    && ! TARGET_ARCH64
2256    && ((GET_CODE (operands[0]) == REG
2257         && REGNO (operands[0]) < 32)
2258        || (GET_CODE (operands[0]) == SUBREG
2259            && GET_CODE (SUBREG_REG (operands[0])) == REG
2260            && REGNO (SUBREG_REG (operands[0])) < 32))"
2261   [(clobber (const_int 0))]
2263   enum machine_mode half_mode;
2264   rtx set_dest = operands[0];
2265   rtx dest1, dest2;
2267   /* We can be expanded for DFmode or integral vector modes.  */
2268   if (<V64:MODE>mode == DFmode)
2269     half_mode = SFmode;
2270   else
2271     half_mode = SImode;
2273   dest1 = gen_highpart (half_mode, set_dest);
2274   dest2 = gen_lowpart (half_mode, set_dest);
2275   emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2276   emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2277   DONE;
2280 (define_expand "movtf"
2281   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2282         (match_operand:TF 1 "general_operand" ""))]
2283   ""
2285   if (sparc_expand_move (TFmode, operands))
2286     DONE;
2289 (define_insn "*movtf_insn_sp32"
2290   [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,U,r")
2291         (match_operand:TF 1 "input_operand"    "G,oe,GeUr,o,roG"))]
2292   "TARGET_FPU
2293    && ! TARGET_ARCH64
2294    && (register_operand (operands[0], TFmode)
2295        || register_or_zero_operand (operands[1], TFmode))"
2296   "#"
2297   [(set_attr "length" "4")])
2299 ;; Exactly the same as above, except that all `e' cases are deleted.
2300 ;; This is necessary to prevent reload from ever trying to use a `e' reg
2301 ;; when -mno-fpu.
2303 (define_insn "*movtf_insn_sp32_no_fpu"
2304   [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
2305         (match_operand:TF 1 "input_operand"    "G,o,U,roG,r"))]
2306   "! TARGET_FPU
2307    && ! TARGET_ARCH64
2308    && (register_operand (operands[0], TFmode)
2309        || register_or_zero_operand (operands[1], TFmode))"
2310   "#"
2311   [(set_attr "length" "4")])
2313 (define_insn "*movtf_insn_sp64"
2314   [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,r")
2315         (match_operand:TF 1 "input_operand"    "G,oe,Ger,roG"))]
2316   "TARGET_FPU
2317    && TARGET_ARCH64
2318    && ! TARGET_HARD_QUAD
2319    && (register_operand (operands[0], TFmode)
2320        || register_or_zero_operand (operands[1], TFmode))"
2321   "#"
2322   [(set_attr "length" "2")])
2324 (define_insn "*movtf_insn_sp64_hq"
2325   [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,e,m,o,r")
2326         (match_operand:TF 1 "input_operand"    "G,e,m,e,rG,roG"))]
2327   "TARGET_FPU
2328    && TARGET_ARCH64
2329    && TARGET_HARD_QUAD
2330    && (register_operand (operands[0], TFmode)
2331        || register_or_zero_operand (operands[1], TFmode))"
2332   "@
2333   #
2334   fmovq\t%1, %0
2335   ldq\t%1, %0
2336   stq\t%1, %0
2337   #
2338   #"
2339   [(set_attr "type" "*,fpmove,fpload,fpstore,*,*")
2340    (set_attr "length" "2,*,*,*,2,2")])
2342 (define_insn "*movtf_insn_sp64_no_fpu"
2343   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
2344         (match_operand:TF 1 "input_operand"    "orG,rG"))]
2345   "! TARGET_FPU
2346    && TARGET_ARCH64
2347    && (register_operand (operands[0], TFmode)
2348        || register_or_zero_operand (operands[1], TFmode))"
2349   "#"
2350   [(set_attr "length" "2")])
2352 ;; Now all the splits to handle multi-insn TF mode moves.
2353 (define_split
2354   [(set (match_operand:TF 0 "register_operand" "")
2355         (match_operand:TF 1 "register_operand" ""))]
2356   "reload_completed
2357    && (! TARGET_ARCH64
2358        || (TARGET_FPU
2359            && ! TARGET_HARD_QUAD)
2360        || ! fp_register_operand (operands[0], TFmode))"
2361   [(clobber (const_int 0))]
2363   rtx set_dest = operands[0];
2364   rtx set_src = operands[1];
2365   rtx dest1, dest2;
2366   rtx src1, src2;
2368   dest1 = gen_df_reg (set_dest, 0);
2369   dest2 = gen_df_reg (set_dest, 1);
2370   src1 = gen_df_reg (set_src, 0);
2371   src2 = gen_df_reg (set_src, 1);
2373   /* Now emit using the real source and destination we found, swapping
2374      the order if we detect overlap.  */
2375   if (reg_overlap_mentioned_p (dest1, src2))
2376     {
2377       emit_insn (gen_movdf (dest2, src2));
2378       emit_insn (gen_movdf (dest1, src1));
2379     }
2380   else
2381     {
2382       emit_insn (gen_movdf (dest1, src1));
2383       emit_insn (gen_movdf (dest2, src2));
2384     }
2385   DONE;
2388 (define_split
2389   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2390         (match_operand:TF 1 "const_zero_operand" ""))]
2391   "reload_completed"
2392   [(clobber (const_int 0))]
2394   rtx set_dest = operands[0];
2395   rtx dest1, dest2;
2397   switch (GET_CODE (set_dest))
2398     {
2399     case REG:
2400       dest1 = gen_df_reg (set_dest, 0);
2401       dest2 = gen_df_reg (set_dest, 1);
2402       break;
2403     case MEM:
2404       dest1 = adjust_address (set_dest, DFmode, 0);
2405       dest2 = adjust_address (set_dest, DFmode, 8);
2406       break;
2407     default:
2408       gcc_unreachable ();      
2409     }
2411   emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
2412   emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
2413   DONE;
2416 (define_split
2417   [(set (match_operand:TF 0 "register_operand" "")
2418         (match_operand:TF 1 "memory_operand" ""))]
2419   "(reload_completed
2420     && offsettable_memref_p (operands[1])
2421     && (! TARGET_ARCH64
2422         || ! TARGET_HARD_QUAD
2423         || ! fp_register_operand (operands[0], TFmode)))"
2424   [(clobber (const_int 0))]
2426   rtx word0 = adjust_address (operands[1], DFmode, 0);
2427   rtx word1 = adjust_address (operands[1], DFmode, 8);
2428   rtx set_dest, dest1, dest2;
2430   set_dest = operands[0];
2432   dest1 = gen_df_reg (set_dest, 0);
2433   dest2 = gen_df_reg (set_dest, 1);
2435   /* Now output, ordering such that we don't clobber any registers
2436      mentioned in the address.  */
2437   if (reg_overlap_mentioned_p (dest1, word1))
2439     {
2440       emit_insn (gen_movdf (dest2, word1));
2441       emit_insn (gen_movdf (dest1, word0));
2442     }
2443   else
2444    {
2445       emit_insn (gen_movdf (dest1, word0));
2446       emit_insn (gen_movdf (dest2, word1));
2447    }
2448   DONE;
2451 (define_split
2452   [(set (match_operand:TF 0 "memory_operand" "")
2453         (match_operand:TF 1 "register_operand" ""))]
2454   "(reload_completed
2455     && offsettable_memref_p (operands[0])
2456     && (! TARGET_ARCH64
2457         || ! TARGET_HARD_QUAD
2458         || ! fp_register_operand (operands[1], TFmode)))"
2459   [(clobber (const_int 0))]
2461   rtx set_src = operands[1];
2463   emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
2464                         gen_df_reg (set_src, 0)));
2465   emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
2466                         gen_df_reg (set_src, 1)));
2467   DONE;
2471 ;; SPARC-V9 conditional move instructions
2473 ;; We can handle larger constants here for some flavors, but for now we keep
2474 ;; it simple and only allow those constants supported by all flavors.
2475 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
2476 ;; 3 contains the constant if one is present, but we handle either for
2477 ;; generality (sparc.c puts a constant in operand 2).
2479 (define_expand "mov<I:mode>cc"
2480   [(set (match_operand:I 0 "register_operand" "")
2481         (if_then_else:I (match_operand 1 "comparison_operator" "")
2482                         (match_operand:I 2 "arith10_operand" "")
2483                         (match_operand:I 3 "arith10_operand" "")))]
2484   "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2486   enum rtx_code code = GET_CODE (operands[1]);
2487   rtx cc_reg;
2489   if (GET_MODE (XEXP (operands[1], 0)) == DImode
2490       && ! TARGET_ARCH64)
2491     FAIL;
2493   if (GET_MODE (XEXP (operands[1], 0)) == TFmode && !TARGET_HARD_QUAD)
2494     operands[1]
2495       = sparc_emit_float_lib_cmp (XEXP (operands[1], 0), XEXP (operands[1], 1),
2496                                   GET_CODE (operands[1]));
2498   if (XEXP (operands[1], 1) == const0_rtx
2499       && GET_CODE (XEXP (operands[1], 0)) == REG
2500       && GET_MODE (XEXP (operands[1], 0)) == DImode
2501       && v9_regcmp_p (code))
2502     cc_reg = XEXP (operands[1], 0);
2503   else
2504     cc_reg = gen_compare_reg (operands[1]);
2506   operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
2509 (define_expand "mov<F:mode>cc"
2510   [(set (match_operand:F 0 "register_operand" "")
2511         (if_then_else:F (match_operand 1 "comparison_operator" "")
2512                         (match_operand:F 2 "register_operand" "")
2513                         (match_operand:F 3 "register_operand" "")))]
2514   "TARGET_V9 && TARGET_FPU"
2516   enum rtx_code code = GET_CODE (operands[1]);
2517   rtx cc_reg;
2519   if (GET_MODE (XEXP (operands[1], 0)) == DImode
2520       && ! TARGET_ARCH64)
2521     FAIL;
2523   if (GET_MODE (XEXP (operands[1], 0)) == TFmode && !TARGET_HARD_QUAD)
2524     operands[1]
2525       = sparc_emit_float_lib_cmp (XEXP (operands[1], 0), XEXP (operands[1], 1),
2526                                   GET_CODE (operands[1]));
2528   if (XEXP (operands[1], 1) == const0_rtx
2529       && GET_CODE (XEXP (operands[1], 0)) == REG
2530       && GET_MODE (XEXP (operands[1], 0)) == DImode
2531       && v9_regcmp_p (code))
2532     cc_reg = XEXP (operands[1], 0);
2533   else
2534     cc_reg = gen_compare_reg (operands[1]);
2536   operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
2539 ;; Conditional move define_insns
2541 (define_insn "*mov<I:mode>_cc_v9"
2542   [(set (match_operand:I 0 "register_operand" "=r,r")
2543         (if_then_else:I (match_operator 1 "comparison_operator"
2544                                [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2545                                 (const_int 0)])
2546                         (match_operand:I 3 "arith11_operand" "rL,0")
2547                         (match_operand:I 4 "arith11_operand" "0,rL")))]
2548   "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2549   "@
2550    mov%C1\t%x2, %3, %0
2551    mov%c1\t%x2, %4, %0"
2552   [(set_attr "type" "cmove")])
2554 (define_insn "*mov<I:mode>_cc_reg_sp64"
2555   [(set (match_operand:I 0 "register_operand" "=r,r")
2556         (if_then_else:I (match_operator 1 "v9_register_compare_operator"
2557                                 [(match_operand:DI 2 "register_operand" "r,r")
2558                                  (const_int 0)])
2559                         (match_operand:I 3 "arith10_operand" "rM,0")
2560                         (match_operand:I 4 "arith10_operand" "0,rM")))]
2561   "TARGET_ARCH64"
2562   "@
2563    movr%D1\t%2, %r3, %0
2564    movr%d1\t%2, %r4, %0"
2565   [(set_attr "type" "cmove")])
2567 (define_insn "*movsf_cc_v9"
2568   [(set (match_operand:SF 0 "register_operand" "=f,f")
2569         (if_then_else:SF (match_operator 1 "comparison_operator"
2570                                 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2571                                  (const_int 0)])
2572                          (match_operand:SF 3 "register_operand" "f,0")
2573                          (match_operand:SF 4 "register_operand" "0,f")))]
2574   "TARGET_V9 && TARGET_FPU"
2575   "@
2576    fmovs%C1\t%x2, %3, %0
2577    fmovs%c1\t%x2, %4, %0"
2578   [(set_attr "type" "fpcmove")])
2580 (define_insn "*movsf_cc_reg_sp64"
2581   [(set (match_operand:SF 0 "register_operand" "=f,f")
2582         (if_then_else:SF (match_operator 1 "v9_register_compare_operator"
2583                                 [(match_operand:DI 2 "register_operand" "r,r")
2584                                  (const_int 0)])
2585                          (match_operand:SF 3 "register_operand" "f,0")
2586                          (match_operand:SF 4 "register_operand" "0,f")))]
2587   "TARGET_ARCH64 && TARGET_FPU"
2588   "@
2589    fmovrs%D1\t%2, %3, %0
2590    fmovrs%d1\t%2, %4, %0"
2591   [(set_attr "type" "fpcrmove")])
2593 ;; Named because invoked by movtf_cc_v9
2594 (define_insn "movdf_cc_v9"
2595   [(set (match_operand:DF 0 "register_operand" "=e,e")
2596         (if_then_else:DF (match_operator 1 "comparison_operator"
2597                                 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2598                                  (const_int 0)])
2599                          (match_operand:DF 3 "register_operand" "e,0")
2600                          (match_operand:DF 4 "register_operand" "0,e")))]
2601   "TARGET_V9 && TARGET_FPU"
2602   "@
2603    fmovd%C1\t%x2, %3, %0
2604    fmovd%c1\t%x2, %4, %0"
2605   [(set_attr "type" "fpcmove")
2606    (set_attr "fptype" "double")])
2608 ;; Named because invoked by movtf_cc_reg_sp64
2609 (define_insn "movdf_cc_reg_sp64"
2610   [(set (match_operand:DF 0 "register_operand" "=e,e")
2611         (if_then_else:DF (match_operator 1 "v9_register_compare_operator"
2612                                 [(match_operand:DI 2 "register_operand" "r,r")
2613                                  (const_int 0)])
2614                          (match_operand:DF 3 "register_operand" "e,0")
2615                          (match_operand:DF 4 "register_operand" "0,e")))]
2616   "TARGET_ARCH64 && TARGET_FPU"
2617   "@
2618    fmovrd%D1\t%2, %3, %0
2619    fmovrd%d1\t%2, %4, %0"
2620   [(set_attr "type" "fpcrmove")
2621    (set_attr "fptype" "double")])
2623 (define_insn "*movtf_cc_hq_v9"
2624   [(set (match_operand:TF 0 "register_operand" "=e,e")
2625         (if_then_else:TF (match_operator 1 "comparison_operator"
2626                                 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2627                                  (const_int 0)])
2628                          (match_operand:TF 3 "register_operand" "e,0")
2629                          (match_operand:TF 4 "register_operand" "0,e")))]
2630   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
2631   "@
2632    fmovq%C1\t%x2, %3, %0
2633    fmovq%c1\t%x2, %4, %0"
2634   [(set_attr "type" "fpcmove")])
2636 (define_insn "*movtf_cc_reg_hq_sp64"
2637   [(set (match_operand:TF 0 "register_operand" "=e,e")
2638         (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2639                                 [(match_operand:DI 2 "register_operand" "r,r")
2640                                  (const_int 0)])
2641                          (match_operand:TF 3 "register_operand" "e,0")
2642                          (match_operand:TF 4 "register_operand" "0,e")))]
2643   "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
2644   "@
2645    fmovrq%D1\t%2, %3, %0
2646    fmovrq%d1\t%2, %4, %0"
2647   [(set_attr "type" "fpcrmove")])
2649 (define_insn_and_split "*movtf_cc_v9"
2650   [(set (match_operand:TF 0 "register_operand" "=e,e")
2651         (if_then_else:TF (match_operator 1 "comparison_operator"
2652                             [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
2653                              (const_int 0)])
2654                          (match_operand:TF 3 "register_operand" "e,0")
2655                          (match_operand:TF 4 "register_operand" "0,e")))]
2656   "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
2657   "#"
2658   "&& reload_completed"
2659   [(clobber (const_int 0))]
2661   rtx set_dest = operands[0];
2662   rtx set_srca = operands[3];
2663   rtx set_srcb = operands[4];
2664   int third = rtx_equal_p (set_dest, set_srca);
2665   rtx dest1, dest2;
2666   rtx srca1, srca2, srcb1, srcb2;
2668   dest1 = gen_df_reg (set_dest, 0);
2669   dest2 = gen_df_reg (set_dest, 1);
2670   srca1 = gen_df_reg (set_srca, 0);
2671   srca2 = gen_df_reg (set_srca, 1);
2672   srcb1 = gen_df_reg (set_srcb, 0);
2673   srcb2 = gen_df_reg (set_srcb, 1);
2675   /* Now emit using the real source and destination we found, swapping
2676      the order if we detect overlap.  */
2677   if ((third && reg_overlap_mentioned_p (dest1, srcb2))
2678       || (!third && reg_overlap_mentioned_p (dest1, srca2)))
2679     {
2680       emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, srcb2));
2681       emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, srcb1));
2682     }
2683   else
2684     {
2685       emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, srcb1));
2686       emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, srcb2));
2687     }
2688   DONE;
2690   [(set_attr "length" "2")])
2692 (define_insn_and_split "*movtf_cc_reg_sp64"
2693   [(set (match_operand:TF 0 "register_operand" "=e,e")
2694         (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2695                                 [(match_operand:DI 2 "register_operand" "r,r")
2696                                  (const_int 0)])
2697                          (match_operand:TF 3 "register_operand" "e,0")
2698                          (match_operand:TF 4 "register_operand" "0,e")))]
2699   "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
2700   "#"
2701   "&& reload_completed"
2702   [(clobber (const_int 0))]
2704   rtx set_dest = operands[0];
2705   rtx set_srca = operands[3];
2706   rtx set_srcb = operands[4];
2707   int third = rtx_equal_p (set_dest, set_srca);
2708   rtx dest1, dest2;
2709   rtx srca1, srca2, srcb1, srcb2;
2711   dest1 = gen_df_reg (set_dest, 0);
2712   dest2 = gen_df_reg (set_dest, 1);
2713   srca1 = gen_df_reg (set_srca, 0);
2714   srca2 = gen_df_reg (set_srca, 1);
2715   srcb1 = gen_df_reg (set_srcb, 0);
2716   srcb2 = gen_df_reg (set_srcb, 1);
2718   /* Now emit using the real source and destination we found, swapping
2719      the order if we detect overlap.  */
2720   if ((third && reg_overlap_mentioned_p (dest1, srcb2))
2721       || (!third && reg_overlap_mentioned_p (dest1, srca2)))
2722     {
2723       emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
2724       emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
2725     }
2726   else
2727     {
2728       emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
2729       emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
2730     }
2731   DONE;
2733   [(set_attr "length" "2")])
2736 ;; Zero-extension instructions
2738 ;; These patterns originally accepted general_operands, however, slightly
2739 ;; better code is generated by only accepting register_operands, and then
2740 ;; letting combine generate the ldu[hb] insns.
2742 (define_expand "zero_extendhisi2"
2743   [(set (match_operand:SI 0 "register_operand" "")
2744         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
2745   ""
2747   rtx temp = gen_reg_rtx (SImode);
2748   rtx shift_16 = GEN_INT (16);
2749   int op1_subbyte = 0;
2751   if (GET_CODE (operand1) == SUBREG)
2752     {
2753       op1_subbyte = SUBREG_BYTE (operand1);
2754       op1_subbyte /= GET_MODE_SIZE (SImode);
2755       op1_subbyte *= GET_MODE_SIZE (SImode);
2756       operand1 = XEXP (operand1, 0);
2757     }
2759   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
2760                           shift_16));
2761   emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
2762   DONE;
2765 (define_insn "*zero_extendhisi2_insn"
2766   [(set (match_operand:SI 0 "register_operand" "=r")
2767         (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2768   ""
2769   "lduh\t%1, %0"
2770   [(set_attr "type" "load")
2771    (set_attr "us3load_type" "3cycle")])
2773 (define_expand "zero_extendqihi2"
2774   [(set (match_operand:HI 0 "register_operand" "")
2775         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
2776   ""
2777   "")
2779 (define_insn "*zero_extendqihi2_insn"
2780   [(set (match_operand:HI 0 "register_operand" "=r,r")
2781         (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
2782   "GET_CODE (operands[1]) != CONST_INT"
2783   "@
2784    and\t%1, 0xff, %0
2785    ldub\t%1, %0"
2786   [(set_attr "type" "*,load")
2787    (set_attr "us3load_type" "*,3cycle")])
2789 (define_expand "zero_extendqisi2"
2790   [(set (match_operand:SI 0 "register_operand" "")
2791         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
2792   ""
2793   "")
2795 (define_insn "*zero_extendqisi2_insn"
2796   [(set (match_operand:SI 0 "register_operand" "=r,r")
2797         (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
2798   "GET_CODE (operands[1]) != CONST_INT"
2799   "@
2800    and\t%1, 0xff, %0
2801    ldub\t%1, %0"
2802   [(set_attr "type" "*,load")
2803    (set_attr "us3load_type" "*,3cycle")])
2805 (define_expand "zero_extendqidi2"
2806   [(set (match_operand:DI 0 "register_operand" "")
2807         (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
2808   "TARGET_ARCH64"
2809   "")
2811 (define_insn "*zero_extendqidi2_insn"
2812   [(set (match_operand:DI 0 "register_operand" "=r,r")
2813         (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
2814   "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
2815   "@
2816    and\t%1, 0xff, %0
2817    ldub\t%1, %0"
2818   [(set_attr "type" "*,load")
2819    (set_attr "us3load_type" "*,3cycle")])
2821 (define_expand "zero_extendhidi2"
2822   [(set (match_operand:DI 0 "register_operand" "")
2823         (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
2824   "TARGET_ARCH64"
2826   rtx temp = gen_reg_rtx (DImode);
2827   rtx shift_48 = GEN_INT (48);
2828   int op1_subbyte = 0;
2830   if (GET_CODE (operand1) == SUBREG)
2831     {
2832       op1_subbyte = SUBREG_BYTE (operand1);
2833       op1_subbyte /= GET_MODE_SIZE (DImode);
2834       op1_subbyte *= GET_MODE_SIZE (DImode);
2835       operand1 = XEXP (operand1, 0);
2836     }
2838   emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
2839                           shift_48));
2840   emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
2841   DONE;
2844 (define_insn "*zero_extendhidi2_insn"
2845   [(set (match_operand:DI 0 "register_operand" "=r")
2846         (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
2847   "TARGET_ARCH64"
2848   "lduh\t%1, %0"
2849   [(set_attr "type" "load")
2850    (set_attr "us3load_type" "3cycle")])
2852 ;; ??? Write truncdisi pattern using sra?
2854 (define_expand "zero_extendsidi2"
2855   [(set (match_operand:DI 0 "register_operand" "")
2856         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
2857   ""
2858   "")
2860 (define_insn "*zero_extendsidi2_insn_sp64"
2861   [(set (match_operand:DI 0 "register_operand" "=r,r")
2862         (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
2863   "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
2864   "@
2865    srl\t%1, 0, %0
2866    lduw\t%1, %0"
2867   [(set_attr "type" "shift,load")])
2869 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
2870   [(set (match_operand:DI 0 "register_operand" "=r")
2871         (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
2872   "! TARGET_ARCH64"
2873   "#"
2874   "&& reload_completed"
2875   [(set (match_dup 2) (match_dup 3))
2876    (set (match_dup 4) (match_dup 5))]
2878   rtx dest1, dest2;
2880   dest1 = gen_highpart (SImode, operands[0]);
2881   dest2 = gen_lowpart (SImode, operands[0]);
2883   /* Swap the order in case of overlap.  */
2884   if (REGNO (dest1) == REGNO (operands[1]))
2885     {
2886       operands[2] = dest2;
2887       operands[3] = operands[1];
2888       operands[4] = dest1;
2889       operands[5] = const0_rtx;
2890     }
2891   else
2892     {
2893       operands[2] = dest1;
2894       operands[3] = const0_rtx;
2895       operands[4] = dest2;
2896       operands[5] = operands[1];
2897     }
2899   [(set_attr "length" "2")])
2901 ;; Simplify comparisons of extended values.
2903 (define_insn "*cmp_zero_extendqisi2"
2904   [(set (reg:CC 100)
2905         (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
2906                     (const_int 0)))]
2907   ""
2908   "andcc\t%0, 0xff, %%g0"
2909   [(set_attr "type" "compare")])
2911 (define_insn "*cmp_zero_qi"
2912   [(set (reg:CC 100)
2913         (compare:CC (match_operand:QI 0 "register_operand" "r")
2914                     (const_int 0)))]
2915   ""
2916   "andcc\t%0, 0xff, %%g0"
2917   [(set_attr "type" "compare")])
2919 (define_insn "*cmp_zero_extendqisi2_set"
2920   [(set (reg:CC 100)
2921         (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
2922                     (const_int 0)))
2923    (set (match_operand:SI 0 "register_operand" "=r")
2924         (zero_extend:SI (match_dup 1)))]
2925   ""
2926   "andcc\t%1, 0xff, %0"
2927   [(set_attr "type" "compare")])
2929 (define_insn "*cmp_zero_extendqisi2_andcc_set"
2930   [(set (reg:CC 100)
2931         (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
2932                             (const_int 255))
2933                     (const_int 0)))
2934    (set (match_operand:SI 0 "register_operand" "=r")
2935         (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
2936   ""
2937   "andcc\t%1, 0xff, %0"
2938   [(set_attr "type" "compare")])
2940 (define_insn "*cmp_zero_extendqidi2"
2941   [(set (reg:CCX 100)
2942         (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
2943                      (const_int 0)))]
2944   "TARGET_ARCH64"
2945   "andcc\t%0, 0xff, %%g0"
2946   [(set_attr "type" "compare")])
2948 (define_insn "*cmp_zero_qi_sp64"
2949   [(set (reg:CCX 100)
2950         (compare:CCX (match_operand:QI 0 "register_operand" "r")
2951                      (const_int 0)))]
2952   "TARGET_ARCH64"
2953   "andcc\t%0, 0xff, %%g0"
2954   [(set_attr "type" "compare")])
2956 (define_insn "*cmp_zero_extendqidi2_set"
2957   [(set (reg:CCX 100)
2958         (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
2959                      (const_int 0)))
2960    (set (match_operand:DI 0 "register_operand" "=r")
2961         (zero_extend:DI (match_dup 1)))]
2962   "TARGET_ARCH64"
2963   "andcc\t%1, 0xff, %0"
2964   [(set_attr "type" "compare")])
2966 (define_insn "*cmp_zero_extendqidi2_andcc_set"
2967   [(set (reg:CCX 100)
2968         (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
2969                              (const_int 255))
2970                      (const_int 0)))
2971    (set (match_operand:DI 0 "register_operand" "=r")
2972         (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
2973   "TARGET_ARCH64"
2974   "andcc\t%1, 0xff, %0"
2975   [(set_attr "type" "compare")])
2977 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
2979 (define_insn "*cmp_siqi_trunc"
2980   [(set (reg:CC 100)
2981         (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
2982                     (const_int 0)))]
2983   ""
2984   "andcc\t%0, 0xff, %%g0"
2985   [(set_attr "type" "compare")])
2987 (define_insn "*cmp_siqi_trunc_set"
2988   [(set (reg:CC 100)
2989         (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
2990                     (const_int 0)))
2991    (set (match_operand:QI 0 "register_operand" "=r")
2992         (subreg:QI (match_dup 1) 3))]
2993   ""
2994   "andcc\t%1, 0xff, %0"
2995   [(set_attr "type" "compare")])
2997 (define_insn "*cmp_diqi_trunc"
2998   [(set (reg:CC 100)
2999         (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
3000                     (const_int 0)))]
3001   "TARGET_ARCH64"
3002   "andcc\t%0, 0xff, %%g0"
3003   [(set_attr "type" "compare")])
3005 (define_insn "*cmp_diqi_trunc_set"
3006   [(set (reg:CC 100)
3007         (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
3008                     (const_int 0)))
3009    (set (match_operand:QI 0 "register_operand" "=r")
3010         (subreg:QI (match_dup 1) 7))]
3011   "TARGET_ARCH64"
3012   "andcc\t%1, 0xff, %0"
3013   [(set_attr "type" "compare")])
3016 ;; Sign-extension instructions
3018 ;; These patterns originally accepted general_operands, however, slightly
3019 ;; better code is generated by only accepting register_operands, and then
3020 ;; letting combine generate the lds[hb] insns.
3022 (define_expand "extendhisi2"
3023   [(set (match_operand:SI 0 "register_operand" "")
3024         (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
3025   ""
3027   rtx temp = gen_reg_rtx (SImode);
3028   rtx shift_16 = GEN_INT (16);
3029   int op1_subbyte = 0;
3031   if (GET_CODE (operand1) == SUBREG)
3032     {
3033       op1_subbyte = SUBREG_BYTE (operand1);
3034       op1_subbyte /= GET_MODE_SIZE (SImode);
3035       op1_subbyte *= GET_MODE_SIZE (SImode);
3036       operand1 = XEXP (operand1, 0);
3037     }
3039   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3040                           shift_16));
3041   emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
3042   DONE;
3045 (define_insn "*sign_extendhisi2_insn"
3046   [(set (match_operand:SI 0 "register_operand" "=r")
3047         (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3048   ""
3049   "ldsh\t%1, %0"
3050   [(set_attr "type" "sload")
3051    (set_attr "us3load_type" "3cycle")])
3053 (define_expand "extendqihi2"
3054   [(set (match_operand:HI 0 "register_operand" "")
3055         (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
3056   ""
3058   rtx temp = gen_reg_rtx (SImode);
3059   rtx shift_24 = GEN_INT (24);
3060   int op1_subbyte = 0;
3061   int op0_subbyte = 0;
3063   if (GET_CODE (operand1) == SUBREG)
3064     {
3065       op1_subbyte = SUBREG_BYTE (operand1);
3066       op1_subbyte /= GET_MODE_SIZE (SImode);
3067       op1_subbyte *= GET_MODE_SIZE (SImode);
3068       operand1 = XEXP (operand1, 0);
3069     }
3070   if (GET_CODE (operand0) == SUBREG)
3071     {
3072       op0_subbyte = SUBREG_BYTE (operand0);
3073       op0_subbyte /= GET_MODE_SIZE (SImode);
3074       op0_subbyte *= GET_MODE_SIZE (SImode);
3075       operand0 = XEXP (operand0, 0);
3076     }
3077   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3078                           shift_24));
3079   if (GET_MODE (operand0) != SImode)
3080     operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
3081   emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3082   DONE;
3085 (define_insn "*sign_extendqihi2_insn"
3086   [(set (match_operand:HI 0 "register_operand" "=r")
3087         (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3088   ""
3089   "ldsb\t%1, %0"
3090   [(set_attr "type" "sload")
3091    (set_attr "us3load_type" "3cycle")])
3093 (define_expand "extendqisi2"
3094   [(set (match_operand:SI 0 "register_operand" "")
3095         (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
3096   ""
3098   rtx temp = gen_reg_rtx (SImode);
3099   rtx shift_24 = GEN_INT (24);
3100   int op1_subbyte = 0;
3102   if (GET_CODE (operand1) == SUBREG)
3103     {
3104       op1_subbyte = SUBREG_BYTE (operand1);
3105       op1_subbyte /= GET_MODE_SIZE (SImode);
3106       op1_subbyte *= GET_MODE_SIZE (SImode);
3107       operand1 = XEXP (operand1, 0);
3108     }
3110   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3111                           shift_24));
3112   emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3113   DONE;
3116 (define_insn "*sign_extendqisi2_insn"
3117   [(set (match_operand:SI 0 "register_operand" "=r")
3118         (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3119   ""
3120   "ldsb\t%1, %0"
3121   [(set_attr "type" "sload")
3122    (set_attr "us3load_type" "3cycle")])
3124 (define_expand "extendqidi2"
3125   [(set (match_operand:DI 0 "register_operand" "")
3126         (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
3127   "TARGET_ARCH64"
3129   rtx temp = gen_reg_rtx (DImode);
3130   rtx shift_56 = GEN_INT (56);
3131   int op1_subbyte = 0;
3133   if (GET_CODE (operand1) == SUBREG)
3134     {
3135       op1_subbyte = SUBREG_BYTE (operand1);
3136       op1_subbyte /= GET_MODE_SIZE (DImode);
3137       op1_subbyte *= GET_MODE_SIZE (DImode);
3138       operand1 = XEXP (operand1, 0);
3139     }
3141   emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3142                           shift_56));
3143   emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
3144   DONE;
3147 (define_insn "*sign_extendqidi2_insn"
3148   [(set (match_operand:DI 0 "register_operand" "=r")
3149         (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3150   "TARGET_ARCH64"
3151   "ldsb\t%1, %0"
3152   [(set_attr "type" "sload")
3153    (set_attr "us3load_type" "3cycle")])
3155 (define_expand "extendhidi2"
3156   [(set (match_operand:DI 0 "register_operand" "")
3157         (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
3158   "TARGET_ARCH64"
3160   rtx temp = gen_reg_rtx (DImode);
3161   rtx shift_48 = GEN_INT (48);
3162   int op1_subbyte = 0;
3164   if (GET_CODE (operand1) == SUBREG)
3165     {
3166       op1_subbyte = SUBREG_BYTE (operand1);
3167       op1_subbyte /= GET_MODE_SIZE (DImode);
3168       op1_subbyte *= GET_MODE_SIZE (DImode);
3169       operand1 = XEXP (operand1, 0);
3170     }
3172   emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3173                           shift_48));
3174   emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
3175   DONE;
3178 (define_insn "*sign_extendhidi2_insn"
3179   [(set (match_operand:DI 0 "register_operand" "=r")
3180         (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3181   "TARGET_ARCH64"
3182   "ldsh\t%1, %0"
3183   [(set_attr "type" "sload")
3184    (set_attr "us3load_type" "3cycle")])
3186 (define_expand "extendsidi2"
3187   [(set (match_operand:DI 0 "register_operand" "")
3188         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3189   "TARGET_ARCH64"
3190   "")
3192 (define_insn "*sign_extendsidi2_insn"
3193   [(set (match_operand:DI 0 "register_operand" "=r,r")
3194         (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
3195   "TARGET_ARCH64"
3196   "@
3197   sra\t%1, 0, %0
3198   ldsw\t%1, %0"
3199   [(set_attr "type" "shift,sload")
3200    (set_attr "us3load_type" "*,3cycle")])
3203 ;; Special pattern for optimizing bit-field compares.  This is needed
3204 ;; because combine uses this as a canonical form.
3206 (define_insn "*cmp_zero_extract"
3207   [(set (reg:CC 100)
3208         (compare:CC
3209          (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
3210                           (match_operand:SI 1 "small_int_operand" "I")
3211                           (match_operand:SI 2 "small_int_operand" "I"))
3212          (const_int 0)))]
3213   "INTVAL (operands[2]) > 19"
3215   int len = INTVAL (operands[1]);
3216   int pos = 32 - INTVAL (operands[2]) - len;
3217   HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
3218   operands[1] = GEN_INT (mask);
3219   return "andcc\t%0, %1, %%g0";
3221   [(set_attr "type" "compare")])
3223 (define_insn "*cmp_zero_extract_sp64"
3224   [(set (reg:CCX 100)
3225         (compare:CCX
3226          (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
3227                           (match_operand:SI 1 "small_int_operand" "I")
3228                           (match_operand:SI 2 "small_int_operand" "I"))
3229          (const_int 0)))]
3230   "TARGET_ARCH64 && INTVAL (operands[2]) > 51"
3232   int len = INTVAL (operands[1]);
3233   int pos = 64 - INTVAL (operands[2]) - len;
3234   HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
3235   operands[1] = GEN_INT (mask);
3236   return "andcc\t%0, %1, %%g0";
3238   [(set_attr "type" "compare")])
3241 ;; Conversions between float, double and long double.
3243 (define_insn "extendsfdf2"
3244   [(set (match_operand:DF 0 "register_operand" "=e")
3245         (float_extend:DF
3246          (match_operand:SF 1 "register_operand" "f")))]
3247   "TARGET_FPU"
3248   "fstod\t%1, %0"
3249   [(set_attr "type" "fp")
3250    (set_attr "fptype" "double")])
3252 (define_expand "extendsftf2"
3253   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3254         (float_extend:TF
3255          (match_operand:SF 1 "register_operand" "")))]
3256   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3257   "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3259 (define_insn "*extendsftf2_hq"
3260   [(set (match_operand:TF 0 "register_operand" "=e")
3261         (float_extend:TF
3262          (match_operand:SF 1 "register_operand" "f")))]
3263   "TARGET_FPU && TARGET_HARD_QUAD"
3264   "fstoq\t%1, %0"
3265   [(set_attr "type" "fp")])
3267 (define_expand "extenddftf2"
3268   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3269         (float_extend:TF
3270          (match_operand:DF 1 "register_operand" "")))]
3271   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3272   "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3274 (define_insn "*extenddftf2_hq"
3275   [(set (match_operand:TF 0 "register_operand" "=e")
3276         (float_extend:TF
3277          (match_operand:DF 1 "register_operand" "e")))]
3278   "TARGET_FPU && TARGET_HARD_QUAD"
3279   "fdtoq\t%1, %0"
3280   [(set_attr "type" "fp")])
3282 (define_insn "truncdfsf2"
3283   [(set (match_operand:SF 0 "register_operand" "=f")
3284         (float_truncate:SF
3285          (match_operand:DF 1 "register_operand" "e")))]
3286   "TARGET_FPU"
3287   "fdtos\t%1, %0"
3288   [(set_attr "type" "fp")
3289    (set_attr "fptype" "double")])
3291 (define_expand "trunctfsf2"
3292   [(set (match_operand:SF 0 "register_operand" "")
3293         (float_truncate:SF
3294          (match_operand:TF 1 "general_operand" "")))]
3295   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3296   "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3298 (define_insn "*trunctfsf2_hq"
3299   [(set (match_operand:SF 0 "register_operand" "=f")
3300         (float_truncate:SF
3301          (match_operand:TF 1 "register_operand" "e")))]
3302   "TARGET_FPU && TARGET_HARD_QUAD"
3303   "fqtos\t%1, %0"
3304   [(set_attr "type" "fp")])
3306 (define_expand "trunctfdf2"
3307   [(set (match_operand:DF 0 "register_operand" "")
3308         (float_truncate:DF
3309          (match_operand:TF 1 "general_operand" "")))]
3310   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3311   "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3313 (define_insn "*trunctfdf2_hq"
3314   [(set (match_operand:DF 0 "register_operand" "=e")
3315         (float_truncate:DF
3316          (match_operand:TF 1 "register_operand" "e")))]
3317   "TARGET_FPU && TARGET_HARD_QUAD"
3318   "fqtod\t%1, %0"
3319   [(set_attr "type" "fp")])
3322 ;; Conversion between fixed point and floating point.
3324 (define_insn "floatsisf2"
3325   [(set (match_operand:SF 0 "register_operand" "=f")
3326         (float:SF (match_operand:SI 1 "register_operand" "f")))]
3327   "TARGET_FPU"
3328   "fitos\t%1, %0"
3329   [(set_attr "type" "fp")
3330    (set_attr "fptype" "double")])
3332 (define_insn "floatsidf2"
3333   [(set (match_operand:DF 0 "register_operand" "=e")
3334         (float:DF (match_operand:SI 1 "register_operand" "f")))]
3335   "TARGET_FPU"
3336   "fitod\t%1, %0"
3337   [(set_attr "type" "fp")
3338    (set_attr "fptype" "double")])
3340 (define_expand "floatsitf2"
3341   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3342         (float:TF (match_operand:SI 1 "register_operand" "")))]
3343   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3344   "emit_tfmode_cvt (FLOAT, operands); DONE;")
3346 (define_insn "*floatsitf2_hq"
3347   [(set (match_operand:TF 0 "register_operand" "=e")
3348         (float:TF (match_operand:SI 1 "register_operand" "f")))]
3349   "TARGET_FPU && TARGET_HARD_QUAD"
3350   "fitoq\t%1, %0"
3351   [(set_attr "type" "fp")])
3353 (define_expand "floatunssitf2"
3354   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3355         (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
3356   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3357   "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3359 ;; Now the same for 64 bit sources.
3361 (define_insn "floatdisf2"
3362   [(set (match_operand:SF 0 "register_operand" "=f")
3363         (float:SF (match_operand:DI 1 "register_operand" "e")))]
3364   "TARGET_V9 && TARGET_FPU"
3365   "fxtos\t%1, %0"
3366   [(set_attr "type" "fp")
3367    (set_attr "fptype" "double")])
3369 (define_expand "floatunsdisf2"
3370   [(use (match_operand:SF 0 "register_operand" ""))
3371    (use (match_operand:DI 1 "general_operand" ""))]
3372   "TARGET_ARCH64 && TARGET_FPU"
3373   "sparc_emit_floatunsdi (operands, SFmode); DONE;")
3375 (define_insn "floatdidf2"
3376   [(set (match_operand:DF 0 "register_operand" "=e")
3377         (float:DF (match_operand:DI 1 "register_operand" "e")))]
3378   "TARGET_V9 && TARGET_FPU"
3379   "fxtod\t%1, %0"
3380   [(set_attr "type" "fp")
3381    (set_attr "fptype" "double")])
3383 (define_expand "floatunsdidf2"
3384   [(use (match_operand:DF 0 "register_operand" ""))
3385    (use (match_operand:DI 1 "general_operand" ""))]
3386   "TARGET_ARCH64 && TARGET_FPU"
3387   "sparc_emit_floatunsdi (operands, DFmode); DONE;")
3389 (define_expand "floatditf2"
3390   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3391         (float:TF (match_operand:DI 1 "register_operand" "")))]
3392   "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3393   "emit_tfmode_cvt (FLOAT, operands); DONE;")
3395 (define_insn "*floatditf2_hq"
3396   [(set (match_operand:TF 0 "register_operand" "=e")
3397         (float:TF (match_operand:DI 1 "register_operand" "e")))]
3398   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3399   "fxtoq\t%1, %0"
3400   [(set_attr "type" "fp")])
3402 (define_expand "floatunsditf2"
3403   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3404         (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
3405   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3406   "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3408 ;; Convert a float to an actual integer.
3409 ;; Truncation is performed as part of the conversion.
3411 (define_insn "fix_truncsfsi2"
3412   [(set (match_operand:SI 0 "register_operand" "=f")
3413         (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3414   "TARGET_FPU"
3415   "fstoi\t%1, %0"
3416   [(set_attr "type" "fp")
3417    (set_attr "fptype" "double")])
3419 (define_insn "fix_truncdfsi2"
3420   [(set (match_operand:SI 0 "register_operand" "=f")
3421         (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3422   "TARGET_FPU"
3423   "fdtoi\t%1, %0"
3424   [(set_attr "type" "fp")
3425    (set_attr "fptype" "double")])
3427 (define_expand "fix_trunctfsi2"
3428   [(set (match_operand:SI 0 "register_operand" "")
3429         (fix:SI (match_operand:TF 1 "general_operand" "")))]
3430   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3431   "emit_tfmode_cvt (FIX, operands); DONE;")
3433 (define_insn "*fix_trunctfsi2_hq"
3434   [(set (match_operand:SI 0 "register_operand" "=f")
3435         (fix:SI (match_operand:TF 1 "register_operand" "e")))]
3436   "TARGET_FPU && TARGET_HARD_QUAD"
3437   "fqtoi\t%1, %0"
3438   [(set_attr "type" "fp")])
3440 (define_expand "fixuns_trunctfsi2"
3441   [(set (match_operand:SI 0 "register_operand" "")
3442         (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
3443   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3444   "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3446 ;; Now the same, for V9 targets
3448 (define_insn "fix_truncsfdi2"
3449   [(set (match_operand:DI 0 "register_operand" "=e")
3450         (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3451   "TARGET_V9 && TARGET_FPU"
3452   "fstox\t%1, %0"
3453   [(set_attr "type" "fp")
3454    (set_attr "fptype" "double")])
3456 (define_expand "fixuns_truncsfdi2"
3457   [(use (match_operand:DI 0 "register_operand" ""))
3458    (use (match_operand:SF 1 "general_operand" ""))]
3459   "TARGET_ARCH64 && TARGET_FPU"
3460   "sparc_emit_fixunsdi (operands, SFmode); DONE;")
3462 (define_insn "fix_truncdfdi2"
3463   [(set (match_operand:DI 0 "register_operand" "=e")
3464         (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3465   "TARGET_V9 && TARGET_FPU"
3466   "fdtox\t%1, %0"
3467   [(set_attr "type" "fp")
3468    (set_attr "fptype" "double")])
3470 (define_expand "fixuns_truncdfdi2"
3471   [(use (match_operand:DI 0 "register_operand" ""))
3472    (use (match_operand:DF 1 "general_operand" ""))]
3473   "TARGET_ARCH64 && TARGET_FPU"
3474   "sparc_emit_fixunsdi (operands, DFmode); DONE;")
3476 (define_expand "fix_trunctfdi2"
3477   [(set (match_operand:DI 0 "register_operand" "")
3478         (fix:DI (match_operand:TF 1 "general_operand" "")))]
3479   "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3480   "emit_tfmode_cvt (FIX, operands); DONE;")
3482 (define_insn "*fix_trunctfdi2_hq"
3483   [(set (match_operand:DI 0 "register_operand" "=e")
3484         (fix:DI (match_operand:TF 1 "register_operand" "e")))]
3485   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3486   "fqtox\t%1, %0"
3487   [(set_attr "type" "fp")])
3489 (define_expand "fixuns_trunctfdi2"
3490   [(set (match_operand:DI 0 "register_operand" "")
3491         (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
3492   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3493   "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3496 ;; Integer addition/subtraction instructions.
3498 (define_expand "adddi3"
3499   [(set (match_operand:DI 0 "register_operand" "")
3500         (plus:DI (match_operand:DI 1 "register_operand" "")
3501                  (match_operand:DI 2 "arith_double_add_operand" "")))]
3502   ""
3504   if (! TARGET_ARCH64)
3505     {
3506       emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3507                           gen_rtx_SET (VOIDmode, operands[0],
3508                                    gen_rtx_PLUS (DImode, operands[1],
3509                                                  operands[2])),
3510                           gen_rtx_CLOBBER (VOIDmode,
3511                                    gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3512       DONE;
3513     }
3516 (define_insn_and_split "*adddi3_insn_sp32"
3517   [(set (match_operand:DI 0 "register_operand" "=r")
3518         (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
3519                  (match_operand:DI 2 "arith_double_operand" "rHI")))
3520    (clobber (reg:CC 100))]
3521   "! TARGET_ARCH64"
3522   "#"
3523   "&& reload_completed"
3524   [(parallel [(set (reg:CC_NOOV 100)
3525                    (compare:CC_NOOV (plus:SI (match_dup 4)
3526                                              (match_dup 5))
3527                                     (const_int 0)))
3528               (set (match_dup 3)
3529                    (plus:SI (match_dup 4) (match_dup 5)))])
3530    (set (match_dup 6)
3531         (plus:SI (plus:SI (match_dup 7)
3532                           (match_dup 8))
3533                  (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3535   operands[3] = gen_lowpart (SImode, operands[0]);
3536   operands[4] = gen_lowpart (SImode, operands[1]);
3537   operands[5] = gen_lowpart (SImode, operands[2]);
3538   operands[6] = gen_highpart (SImode, operands[0]);
3539   operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
3540 #if HOST_BITS_PER_WIDE_INT == 32
3541   if (GET_CODE (operands[2]) == CONST_INT)
3542     {
3543       if (INTVAL (operands[2]) < 0)
3544         operands[8] = constm1_rtx;
3545       else
3546         operands[8] = const0_rtx;
3547     }
3548   else
3549 #endif
3550     operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3552   [(set_attr "length" "2")])
3554 ;; LTU here means "carry set"
3555 (define_insn "addx"
3556   [(set (match_operand:SI 0 "register_operand" "=r")
3557         (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3558                           (match_operand:SI 2 "arith_operand" "rI"))
3559                  (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3560   ""
3561   "addx\t%1, %2, %0"
3562   [(set_attr "type" "ialuX")])
3564 (define_insn_and_split "*addx_extend_sp32"
3565   [(set (match_operand:DI 0 "register_operand" "=r")
3566         (zero_extend:DI (plus:SI (plus:SI
3567                                   (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3568                                   (match_operand:SI 2 "arith_operand" "rI"))
3569                                  (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
3570   "! TARGET_ARCH64"
3571   "#"
3572   "&& reload_completed"
3573   [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
3574                                (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
3575    (set (match_dup 4) (const_int 0))]
3576   "operands[3] = gen_lowpart (SImode, operands[0]);
3577    operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
3578   [(set_attr "length" "2")])
3580 (define_insn "*addx_extend_sp64"
3581   [(set (match_operand:DI 0 "register_operand" "=r")
3582         (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3583                                           (match_operand:SI 2 "arith_operand" "rI"))
3584                                  (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
3585   "TARGET_ARCH64"
3586   "addx\t%r1, %2, %0"
3587   [(set_attr "type" "ialuX")])
3589 (define_insn_and_split "*adddi3_extend_sp32"
3590   [(set (match_operand:DI 0 "register_operand" "=r")
3591         (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
3592                  (match_operand:DI 2 "register_operand" "r")))
3593    (clobber (reg:CC 100))]
3594   "! TARGET_ARCH64"
3595   "#"
3596   "&& reload_completed"
3597   [(parallel [(set (reg:CC_NOOV 100)
3598                    (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
3599                                     (const_int 0)))
3600               (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
3601    (set (match_dup 6)
3602         (plus:SI (plus:SI (match_dup 4) (const_int 0))
3603                  (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3604   "operands[3] = gen_lowpart (SImode, operands[2]);
3605    operands[4] = gen_highpart (SImode, operands[2]);
3606    operands[5] = gen_lowpart (SImode, operands[0]);
3607    operands[6] = gen_highpart (SImode, operands[0]);"
3608   [(set_attr "length" "2")])
3610 (define_insn "*adddi3_sp64"
3611   [(set (match_operand:DI 0 "register_operand" "=r,r")
3612         (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
3613                  (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3614   "TARGET_ARCH64"
3615   "@
3616    add\t%1, %2, %0
3617    sub\t%1, -%2, %0")
3619 (define_insn "addsi3"
3620   [(set (match_operand:SI 0 "register_operand" "=r,r,d")
3621         (plus:SI (match_operand:SI 1 "register_operand" "%r,r,d")
3622                  (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
3623   ""
3624   "@
3625    add\t%1, %2, %0
3626    sub\t%1, -%2, %0
3627    fpadd32s\t%1, %2, %0"
3628   [(set_attr "type" "*,*,fga")
3629    (set_attr "fptype" "*,*,single")])
3631 (define_insn "*cmp_cc_plus"
3632   [(set (reg:CC_NOOV 100)
3633         (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
3634                                   (match_operand:SI 1 "arith_operand" "rI"))
3635                          (const_int 0)))]
3636   ""
3637   "addcc\t%0, %1, %%g0"
3638   [(set_attr "type" "compare")])
3640 (define_insn "*cmp_ccx_plus"
3641   [(set (reg:CCX_NOOV 100)
3642         (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_operand" "%r")
3643                                    (match_operand:DI 1 "arith_operand" "rI"))
3644                           (const_int 0)))]
3645   "TARGET_ARCH64"
3646   "addcc\t%0, %1, %%g0"
3647   [(set_attr "type" "compare")])
3649 (define_insn "*cmp_cc_plus_set"
3650   [(set (reg:CC_NOOV 100)
3651         (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3652                                   (match_operand:SI 2 "arith_operand" "rI"))
3653                          (const_int 0)))
3654    (set (match_operand:SI 0 "register_operand" "=r")
3655         (plus:SI (match_dup 1) (match_dup 2)))]
3656   ""
3657   "addcc\t%1, %2, %0"
3658   [(set_attr "type" "compare")])
3660 (define_insn "*cmp_ccx_plus_set"
3661   [(set (reg:CCX_NOOV 100)
3662         (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_operand" "%r")
3663                                    (match_operand:DI 2 "arith_operand" "rI"))
3664                           (const_int 0)))
3665    (set (match_operand:DI 0 "register_operand" "=r")
3666         (plus:DI (match_dup 1) (match_dup 2)))]
3667   "TARGET_ARCH64"
3668   "addcc\t%1, %2, %0"
3669   [(set_attr "type" "compare")])
3671 (define_expand "subdi3"
3672   [(set (match_operand:DI 0 "register_operand" "")
3673         (minus:DI (match_operand:DI 1 "register_operand" "")
3674                   (match_operand:DI 2 "arith_double_add_operand" "")))]
3675   ""
3677   if (! TARGET_ARCH64)
3678     {
3679       emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3680                           gen_rtx_SET (VOIDmode, operands[0],
3681                                    gen_rtx_MINUS (DImode, operands[1],
3682                                                   operands[2])),
3683                           gen_rtx_CLOBBER (VOIDmode,
3684                                    gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3685       DONE;
3686     }
3689 (define_insn_and_split "*subdi3_insn_sp32"
3690   [(set (match_operand:DI 0 "register_operand" "=r")
3691         (minus:DI (match_operand:DI 1 "register_operand" "r")
3692                   (match_operand:DI 2 "arith_double_operand" "rHI")))
3693    (clobber (reg:CC 100))]
3694   "! TARGET_ARCH64"
3695   "#"
3696   "&& reload_completed"
3697   [(parallel [(set (reg:CC_NOOV 100)
3698                    (compare:CC_NOOV (minus:SI (match_dup 4)
3699                                               (match_dup 5))
3700                                     (const_int 0)))
3701               (set (match_dup 3)
3702                    (minus:SI (match_dup 4) (match_dup 5)))])
3703    (set (match_dup 6)
3704         (minus:SI (minus:SI (match_dup 7)
3705                             (match_dup 8))
3706                   (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3708   operands[3] = gen_lowpart (SImode, operands[0]);
3709   operands[4] = gen_lowpart (SImode, operands[1]);
3710   operands[5] = gen_lowpart (SImode, operands[2]);
3711   operands[6] = gen_highpart (SImode, operands[0]);
3712   operands[7] = gen_highpart (SImode, operands[1]);
3713 #if HOST_BITS_PER_WIDE_INT == 32
3714   if (GET_CODE (operands[2]) == CONST_INT)
3715     {
3716       if (INTVAL (operands[2]) < 0)
3717         operands[8] = constm1_rtx;
3718       else
3719         operands[8] = const0_rtx;
3720     }
3721   else
3722 #endif
3723     operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3725   [(set_attr "length" "2")])
3727 ;; LTU here means "carry set"
3728 (define_insn "subx"
3729   [(set (match_operand:SI 0 "register_operand" "=r")
3730         (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3731                             (match_operand:SI 2 "arith_operand" "rI"))
3732                   (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3733   ""
3734   "subx\t%r1, %2, %0"
3735   [(set_attr "type" "ialuX")])
3737 (define_insn "*subx_extend_sp64"
3738   [(set (match_operand:DI 0 "register_operand" "=r")
3739         (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3740                                             (match_operand:SI 2 "arith_operand" "rI"))
3741                                   (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
3742   "TARGET_ARCH64"
3743   "subx\t%r1, %2, %0"
3744   [(set_attr "type" "ialuX")])
3746 (define_insn_and_split "*subx_extend"
3747   [(set (match_operand:DI 0 "register_operand" "=r")
3748         (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3749                                             (match_operand:SI 2 "arith_operand" "rI"))
3750                                   (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
3751   "! TARGET_ARCH64"
3752   "#"
3753   "&& reload_completed"
3754   [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
3755                                 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
3756    (set (match_dup 4) (const_int 0))]
3757   "operands[3] = gen_lowpart (SImode, operands[0]);
3758    operands[4] = gen_highpart (SImode, operands[0]);"
3759   [(set_attr "length" "2")])
3761 (define_insn_and_split "*subdi3_extend_sp32"
3762   [(set (match_operand:DI 0 "register_operand" "=r")
3763       (minus:DI (match_operand:DI 1 "register_operand" "r")
3764                 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
3765    (clobber (reg:CC 100))]
3766   "! TARGET_ARCH64"
3767   "#"
3768   "&& reload_completed"
3769   [(parallel [(set (reg:CC_NOOV 100)
3770                    (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
3771                                     (const_int 0)))
3772               (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
3773    (set (match_dup 6)
3774         (minus:SI (minus:SI (match_dup 4) (const_int 0))
3775                   (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
3776   "operands[3] = gen_lowpart (SImode, operands[1]);
3777    operands[4] = gen_highpart (SImode, operands[1]);
3778    operands[5] = gen_lowpart (SImode, operands[0]);
3779    operands[6] = gen_highpart (SImode, operands[0]);"
3780   [(set_attr "length" "2")])
3782 (define_insn "*subdi3_sp64"
3783   [(set (match_operand:DI 0 "register_operand" "=r,r")
3784         (minus:DI (match_operand:DI 1 "register_operand" "r,r")
3785                   (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3786   "TARGET_ARCH64"
3787   "@
3788    sub\t%1, %2, %0
3789    add\t%1, -%2, %0")
3791 (define_insn "subsi3"
3792   [(set (match_operand:SI 0 "register_operand" "=r,r,d")
3793         (minus:SI (match_operand:SI 1 "register_operand" "r,r,d")
3794                   (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
3795   ""
3796   "@
3797    sub\t%1, %2, %0
3798    add\t%1, -%2, %0
3799    fpsub32s\t%1, %2, %0"
3800   [(set_attr "type" "*,*,fga")
3801    (set_attr "fptype" "*,*,single")])
3803 (define_insn "*cmp_minus_cc"
3804   [(set (reg:CC_NOOV 100)
3805         (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
3806                                    (match_operand:SI 1 "arith_operand" "rI"))
3807                          (const_int 0)))]
3808   ""
3809   "subcc\t%r0, %1, %%g0"
3810   [(set_attr "type" "compare")])
3812 (define_insn "*cmp_minus_ccx"
3813   [(set (reg:CCX_NOOV 100)
3814         (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
3815                                     (match_operand:DI 1 "arith_operand" "rI"))
3816                           (const_int 0)))]
3817   "TARGET_ARCH64"
3818   "subcc\t%0, %1, %%g0"
3819   [(set_attr "type" "compare")])
3821 (define_insn "cmp_minus_cc_set"
3822   [(set (reg:CC_NOOV 100)
3823         (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3824                                    (match_operand:SI 2 "arith_operand" "rI"))
3825                          (const_int 0)))
3826    (set (match_operand:SI 0 "register_operand" "=r")
3827         (minus:SI (match_dup 1) (match_dup 2)))]
3828   ""
3829   "subcc\t%r1, %2, %0"
3830   [(set_attr "type" "compare")])
3832 (define_insn "*cmp_minus_ccx_set"
3833   [(set (reg:CCX_NOOV 100)
3834         (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
3835                                     (match_operand:DI 2 "arith_operand" "rI"))
3836                           (const_int 0)))
3837    (set (match_operand:DI 0 "register_operand" "=r")
3838         (minus:DI (match_dup 1) (match_dup 2)))]
3839   "TARGET_ARCH64"
3840   "subcc\t%1, %2, %0"
3841   [(set_attr "type" "compare")])
3844 ;; Integer multiply/divide instructions.
3846 ;; The 32-bit multiply/divide instructions are deprecated on v9, but at
3847 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
3849 (define_insn "mulsi3"
3850   [(set (match_operand:SI 0 "register_operand" "=r")
3851         (mult:SI (match_operand:SI 1 "arith_operand" "%r")
3852                  (match_operand:SI 2 "arith_operand" "rI")))]
3853   "TARGET_HARD_MUL"
3854   "smul\t%1, %2, %0"
3855   [(set_attr "type" "imul")])
3857 (define_expand "muldi3"
3858   [(set (match_operand:DI 0 "register_operand" "")
3859         (mult:DI (match_operand:DI 1 "arith_operand" "")
3860                  (match_operand:DI 2 "arith_operand" "")))]
3861   "TARGET_ARCH64 || TARGET_V8PLUS"
3863   if (TARGET_V8PLUS)
3864     {
3865       emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
3866       DONE;
3867     }
3870 (define_insn "*muldi3_sp64"
3871   [(set (match_operand:DI 0 "register_operand" "=r")
3872         (mult:DI (match_operand:DI 1 "arith_operand" "%r")
3873                  (match_operand:DI 2 "arith_operand" "rI")))]
3874   "TARGET_ARCH64"
3875   "mulx\t%1, %2, %0"
3876   [(set_attr "type" "imul")])
3878 ;; V8plus wide multiply.
3879 ;; XXX
3880 (define_insn "muldi3_v8plus"
3881   [(set (match_operand:DI 0 "register_operand" "=r,h")
3882         (mult:DI (match_operand:DI 1 "arith_operand" "%r,0")
3883                  (match_operand:DI 2 "arith_operand" "rI,rI")))
3884    (clobber (match_scratch:SI 3 "=&h,X"))
3885    (clobber (match_scratch:SI 4 "=&h,X"))]
3886   "TARGET_V8PLUS"
3888   if (sparc_check_64 (operands[1], insn) <= 0)
3889     output_asm_insn ("srl\t%L1, 0, %L1", operands);
3890   if (which_alternative == 1)
3891     output_asm_insn ("sllx\t%H1, 32, %H1", operands);
3892   if (GET_CODE (operands[2]) == CONST_INT)
3893     {
3894       if (which_alternative == 1)
3895         return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %2, %L0\;srlx\t%L0, 32, %H0";
3896       else
3897         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";
3898     }
3899   else if (rtx_equal_p (operands[1], operands[2]))
3900     {
3901       if (which_alternative == 1)
3902         return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %H1, %L0\;srlx\t%L0, 32, %H0";
3903       else
3904         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";
3905     }
3906   if (sparc_check_64 (operands[2], insn) <= 0)
3907     output_asm_insn ("srl\t%L2, 0, %L2", operands);
3908   if (which_alternative == 1)
3909     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";
3910   else
3911     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";
3913   [(set_attr "type" "multi")
3914    (set_attr "length" "9,8")])
3916 (define_insn "*cmp_mul_set"
3917   [(set (reg:CC 100)
3918         (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
3919                     (match_operand:SI 2 "arith_operand" "rI"))
3920                     (const_int 0)))
3921    (set (match_operand:SI 0 "register_operand" "=r")
3922         (mult:SI (match_dup 1) (match_dup 2)))]
3923   "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
3924   "smulcc\t%1, %2, %0"
3925   [(set_attr "type" "imul")])
3927 (define_expand "mulsidi3"
3928   [(set (match_operand:DI 0 "register_operand" "")
3929         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
3930                  (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
3931   "TARGET_HARD_MUL"
3933   if (CONSTANT_P (operands[2]))
3934     {
3935       if (TARGET_V8PLUS)
3936         emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
3937                                               operands[2]));
3938       else if (TARGET_ARCH32)
3939         emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
3940                                             operands[2]));
3941       else 
3942         emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
3943                                             operands[2]));
3944       DONE;
3945     }
3946   if (TARGET_V8PLUS)
3947     {
3948       emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
3949       DONE;
3950     }
3953 ;; V9 puts the 64-bit product in a 64-bit register.  Only out or global
3954 ;; registers can hold 64-bit values in the V8plus environment.
3955 ;; XXX
3956 (define_insn "mulsidi3_v8plus"
3957   [(set (match_operand:DI 0 "register_operand" "=h,r")
3958         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
3959                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
3960    (clobber (match_scratch:SI 3 "=X,&h"))]
3961   "TARGET_V8PLUS"
3962   "@
3963    smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
3964    smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
3965   [(set_attr "type" "multi")
3966    (set_attr "length" "2,3")])
3968 ;; XXX
3969 (define_insn "const_mulsidi3_v8plus"
3970   [(set (match_operand:DI 0 "register_operand" "=h,r")
3971         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
3972                  (match_operand:DI 2 "small_int_operand" "I,I")))
3973    (clobber (match_scratch:SI 3 "=X,&h"))]
3974   "TARGET_V8PLUS"
3975   "@
3976    smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
3977    smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
3978   [(set_attr "type" "multi")
3979    (set_attr "length" "2,3")])
3981 ;; XXX
3982 (define_insn "*mulsidi3_sp32"
3983   [(set (match_operand:DI 0 "register_operand" "=r")
3984         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
3985                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
3986   "TARGET_HARD_MUL32"
3988   return TARGET_SPARCLET
3989          ? "smuld\t%1, %2, %L0"
3990          : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
3992   [(set (attr "type")
3993         (if_then_else (eq_attr "isa" "sparclet")
3994                       (const_string "imul") (const_string "multi")))
3995    (set (attr "length")
3996         (if_then_else (eq_attr "isa" "sparclet")
3997                       (const_int 1) (const_int 2)))])
3999 (define_insn "*mulsidi3_sp64"
4000   [(set (match_operand:DI 0 "register_operand" "=r")
4001         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4002                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4003   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4004   "smul\t%1, %2, %0"
4005   [(set_attr "type" "imul")])
4007 ;; Extra pattern, because sign_extend of a constant isn't valid.
4009 ;; XXX
4010 (define_insn "const_mulsidi3_sp32"
4011   [(set (match_operand:DI 0 "register_operand" "=r")
4012         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4013                  (match_operand:DI 2 "small_int_operand" "I")))]
4014   "TARGET_HARD_MUL32"
4016   return TARGET_SPARCLET
4017          ? "smuld\t%1, %2, %L0"
4018          : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4020   [(set (attr "type")
4021         (if_then_else (eq_attr "isa" "sparclet")
4022                       (const_string "imul") (const_string "multi")))
4023    (set (attr "length")
4024         (if_then_else (eq_attr "isa" "sparclet")
4025                       (const_int 1) (const_int 2)))])
4027 (define_insn "const_mulsidi3_sp64"
4028   [(set (match_operand:DI 0 "register_operand" "=r")
4029         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4030                  (match_operand:DI 2 "small_int_operand" "I")))]
4031   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4032   "smul\t%1, %2, %0"
4033   [(set_attr "type" "imul")])
4035 (define_expand "smulsi3_highpart"
4036   [(set (match_operand:SI 0 "register_operand" "")
4037         (truncate:SI
4038          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4039                                (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
4040                       (const_int 32))))]
4041   "TARGET_HARD_MUL && TARGET_ARCH32"
4043   if (CONSTANT_P (operands[2]))
4044     {
4045       if (TARGET_V8PLUS)
4046         {
4047           emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
4048                                                         operands[1],
4049                                                         operands[2],
4050                                                         GEN_INT (32)));
4051           DONE;
4052         }
4053       emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
4054       DONE;
4055     }
4056   if (TARGET_V8PLUS)
4057     {
4058       emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
4059                                               operands[2], GEN_INT (32)));
4060       DONE;
4061     }
4064 ;; XXX
4065 (define_insn "smulsi3_highpart_v8plus"
4066   [(set (match_operand:SI 0 "register_operand" "=h,r")
4067         (truncate:SI
4068          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4069                                (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4070                       (match_operand:SI 3 "small_int_operand" "I,I"))))
4071    (clobber (match_scratch:SI 4 "=X,&h"))]
4072   "TARGET_V8PLUS"
4073   "@
4074    smul\t%1, %2, %0\;srlx\t%0, %3, %0
4075    smul\t%1, %2, %4\;srlx\t%4, %3, %0"
4076   [(set_attr "type" "multi")
4077    (set_attr "length" "2")])
4079 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
4080 ;; XXX
4081 (define_insn ""
4082   [(set (match_operand:SI 0 "register_operand" "=h,r")
4083         (subreg:SI
4084          (lshiftrt:DI
4085           (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4086                    (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4087           (match_operand:SI 3 "small_int_operand" "I,I"))
4088          4))
4089    (clobber (match_scratch:SI 4 "=X,&h"))]
4090   "TARGET_V8PLUS"
4091   "@
4092    smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4093    smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4094   [(set_attr "type" "multi")
4095    (set_attr "length" "2")])
4097 ;; XXX
4098 (define_insn "const_smulsi3_highpart_v8plus"
4099   [(set (match_operand:SI 0 "register_operand" "=h,r")
4100         (truncate:SI
4101          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4102                                (match_operand:DI 2 "small_int_operand" "I,I"))
4103                       (match_operand:SI 3 "small_int_operand" "I,I"))))
4104    (clobber (match_scratch:SI 4 "=X,&h"))]
4105   "TARGET_V8PLUS"
4106   "@
4107    smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4108    smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4109   [(set_attr "type" "multi")
4110    (set_attr "length" "2")])
4112 ;; XXX
4113 (define_insn "*smulsi3_highpart_sp32"
4114   [(set (match_operand:SI 0 "register_operand" "=r")
4115         (truncate:SI
4116          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4117                                (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
4118                       (const_int 32))))]
4119   "TARGET_HARD_MUL32"
4120   "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4121   [(set_attr "type" "multi")
4122    (set_attr "length" "2")])
4124 ;; XXX
4125 (define_insn "const_smulsi3_highpart"
4126   [(set (match_operand:SI 0 "register_operand" "=r")
4127         (truncate:SI
4128          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4129                                (match_operand:DI 2 "small_int_operand" "i"))
4130                       (const_int 32))))]
4131   "TARGET_HARD_MUL32"
4132   "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4133   [(set_attr "type" "multi")
4134    (set_attr "length" "2")])
4136 (define_expand "umulsidi3"
4137   [(set (match_operand:DI 0 "register_operand" "")
4138         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4139                  (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
4140   "TARGET_HARD_MUL"
4142   if (CONSTANT_P (operands[2]))
4143     {
4144       if (TARGET_V8PLUS)
4145         emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
4146                                                operands[2]));
4147       else if (TARGET_ARCH32)
4148         emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
4149                                              operands[2]));
4150       else 
4151         emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
4152                                              operands[2]));
4153       DONE;
4154     }
4155   if (TARGET_V8PLUS)
4156     {
4157       emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
4158       DONE;
4159     }
4162 ;; XXX
4163 (define_insn "umulsidi3_v8plus"
4164   [(set (match_operand:DI 0 "register_operand" "=h,r")
4165         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4166                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4167    (clobber (match_scratch:SI 3 "=X,&h"))]
4168   "TARGET_V8PLUS"
4169   "@
4170    umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4171    umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4172   [(set_attr "type" "multi")
4173    (set_attr "length" "2,3")])
4175 ;; XXX
4176 (define_insn "*umulsidi3_sp32"
4177   [(set (match_operand:DI 0 "register_operand" "=r")
4178         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4179                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4180   "TARGET_HARD_MUL32"
4182   return TARGET_SPARCLET
4183          ? "umuld\t%1, %2, %L0"
4184          : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
4186   [(set (attr "type")
4187         (if_then_else (eq_attr "isa" "sparclet")
4188                       (const_string "imul") (const_string "multi")))
4189    (set (attr "length")
4190         (if_then_else (eq_attr "isa" "sparclet")
4191                       (const_int 1) (const_int 2)))])
4193 (define_insn "*umulsidi3_sp64"
4194   [(set (match_operand:DI 0 "register_operand" "=r")
4195         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4196                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4197   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4198   "umul\t%1, %2, %0"
4199   [(set_attr "type" "imul")])
4201 ;; Extra pattern, because sign_extend of a constant isn't valid.
4203 ;; XXX
4204 (define_insn "const_umulsidi3_sp32"
4205   [(set (match_operand:DI 0 "register_operand" "=r")
4206         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4207                  (match_operand:DI 2 "uns_small_int_operand" "")))]
4208   "TARGET_HARD_MUL32"
4210   return TARGET_SPARCLET
4211          ? "umuld\t%1, %s2, %L0"
4212          : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
4214   [(set (attr "type")
4215         (if_then_else (eq_attr "isa" "sparclet")
4216                       (const_string "imul") (const_string "multi")))
4217    (set (attr "length")
4218         (if_then_else (eq_attr "isa" "sparclet")
4219                       (const_int 1) (const_int 2)))])
4221 (define_insn "const_umulsidi3_sp64"
4222   [(set (match_operand:DI 0 "register_operand" "=r")
4223         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4224                  (match_operand:DI 2 "uns_small_int_operand" "")))]
4225   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4226   "umul\t%1, %s2, %0"
4227   [(set_attr "type" "imul")])
4229 ;; XXX
4230 (define_insn "const_umulsidi3_v8plus"
4231   [(set (match_operand:DI 0 "register_operand" "=h,r")
4232         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4233                  (match_operand:DI 2 "uns_small_int_operand" "")))
4234    (clobber (match_scratch:SI 3 "=X,h"))]
4235   "TARGET_V8PLUS"
4236   "@
4237    umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
4238    umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4239   [(set_attr "type" "multi")
4240    (set_attr "length" "2,3")])
4242 (define_expand "umulsi3_highpart"
4243   [(set (match_operand:SI 0 "register_operand" "")
4244         (truncate:SI
4245          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4246                                (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
4247                       (const_int 32))))]
4248   "TARGET_HARD_MUL && TARGET_ARCH32"
4250   if (CONSTANT_P (operands[2]))
4251     {
4252       if (TARGET_V8PLUS)
4253         {
4254           emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
4255                                                         operands[1],
4256                                                         operands[2],
4257                                                         GEN_INT (32)));
4258           DONE;
4259         }
4260       emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
4261       DONE;
4262     }
4263   if (TARGET_V8PLUS)
4264     {
4265       emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
4266                                               operands[2], GEN_INT (32)));
4267       DONE;
4268     }
4271 ;; XXX
4272 (define_insn "umulsi3_highpart_v8plus"
4273   [(set (match_operand:SI 0 "register_operand" "=h,r")
4274         (truncate:SI
4275          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4276                                (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4277                       (match_operand:SI 3 "small_int_operand" "I,I"))))
4278    (clobber (match_scratch:SI 4 "=X,h"))]
4279   "TARGET_V8PLUS"
4280   "@
4281    umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4282    umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4283   [(set_attr "type" "multi")
4284    (set_attr "length" "2")])
4286 ;; XXX
4287 (define_insn "const_umulsi3_highpart_v8plus"
4288   [(set (match_operand:SI 0 "register_operand" "=h,r")
4289         (truncate:SI
4290          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4291                                (match_operand:DI 2 "uns_small_int_operand" ""))
4292                       (match_operand:SI 3 "small_int_operand" "I,I"))))
4293    (clobber (match_scratch:SI 4 "=X,h"))]
4294   "TARGET_V8PLUS"
4295   "@
4296    umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
4297    umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
4298   [(set_attr "type" "multi")
4299    (set_attr "length" "2")])
4301 ;; XXX
4302 (define_insn "*umulsi3_highpart_sp32"
4303   [(set (match_operand:SI 0 "register_operand" "=r")
4304         (truncate:SI
4305          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4306                                (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
4307                       (const_int 32))))]
4308   "TARGET_HARD_MUL32"
4309   "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
4310   [(set_attr "type" "multi")
4311    (set_attr "length" "2")])
4313 ;; XXX
4314 (define_insn "const_umulsi3_highpart"
4315   [(set (match_operand:SI 0 "register_operand" "=r")
4316         (truncate:SI
4317          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4318                                (match_operand:DI 2 "uns_small_int_operand" ""))
4319                       (const_int 32))))]
4320   "TARGET_HARD_MUL32"
4321   "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
4322   [(set_attr "type" "multi")
4323    (set_attr "length" "2")])
4325 (define_expand "divsi3"
4326   [(parallel [(set (match_operand:SI 0 "register_operand" "")
4327                    (div:SI (match_operand:SI 1 "register_operand" "")
4328                            (match_operand:SI 2 "input_operand" "")))
4329               (clobber (match_scratch:SI 3 ""))])]
4330   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4332   if (TARGET_ARCH64)
4333     {
4334       operands[3] = gen_reg_rtx(SImode);
4335       emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
4336       emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
4337                                   operands[3]));
4338       DONE;
4339     }
4342 ;; The V8 architecture specifies that there must be at least 3 instructions
4343 ;; between a write to the Y register and a use of it for correct results.
4344 ;; We try to fill one of them with a simple constant or a memory load.
4346 (define_insn "divsi3_sp32"
4347   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
4348         (div:SI (match_operand:SI 1 "register_operand" "r,r,r")
4349                 (match_operand:SI 2 "input_operand" "rI,K,m")))
4350    (clobber (match_scratch:SI 3 "=&r,&r,&r"))]
4351   "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4353   output_asm_insn ("sra\t%1, 31, %3", operands);
4354   output_asm_insn ("wr\t%3, 0, %%y", operands);
4356   switch (which_alternative)
4357     {
4358     case 0:
4359       if (TARGET_V9)
4360         return "sdiv\t%1, %2, %0";
4361       else
4362         return "nop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
4363     case 1:
4364       if (TARGET_V9)
4365         return "sethi\t%%hi(%a2), %3\n\tsdiv\t%1, %3, %0";
4366       else
4367         return "sethi\t%%hi(%a2), %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4368     case 2:
4369       if (TARGET_V9)
4370         return "ld\t%2, %3\n\tsdiv\t%1, %3, %0";
4371       else
4372         return "ld\t%2, %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4373     default:
4374       gcc_unreachable ();
4375     }
4377   [(set_attr "type" "multi")
4378    (set (attr "length")
4379         (if_then_else (eq_attr "isa" "v9")
4380                       (const_int 4) (const_int 6)))])
4382 (define_insn "divsi3_sp64"
4383   [(set (match_operand:SI 0 "register_operand" "=r")
4384         (div:SI (match_operand:SI 1 "register_operand" "r")
4385                 (match_operand:SI 2 "input_operand" "rI")))
4386    (use (match_operand:SI 3 "register_operand" "r"))]
4387   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4388   "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
4389   [(set_attr "type" "multi")
4390    (set_attr "length" "2")])
4392 (define_insn "divdi3"
4393   [(set (match_operand:DI 0 "register_operand" "=r")
4394         (div:DI (match_operand:DI 1 "register_operand" "r")
4395                 (match_operand:DI 2 "arith_operand" "rI")))]
4396   "TARGET_ARCH64"
4397   "sdivx\t%1, %2, %0"
4398   [(set_attr "type" "idiv")])
4400 (define_insn "*cmp_sdiv_cc_set"
4401   [(set (reg:CC 100)
4402         (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
4403                             (match_operand:SI 2 "arith_operand" "rI"))
4404                     (const_int 0)))
4405    (set (match_operand:SI 0 "register_operand" "=r")
4406         (div:SI (match_dup 1) (match_dup 2)))
4407    (clobber (match_scratch:SI 3 "=&r"))]
4408   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4410   output_asm_insn ("sra\t%1, 31, %3", operands);
4411   output_asm_insn ("wr\t%3, 0, %%y", operands);
4413   if (TARGET_V9)
4414     return "sdivcc\t%1, %2, %0";
4415   else
4416     return "nop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
4418   [(set_attr "type" "multi")
4419    (set (attr "length")
4420         (if_then_else (eq_attr "isa" "v9")
4421                       (const_int 3) (const_int 6)))])
4423 ;; XXX
4424 (define_expand "udivsi3"
4425   [(set (match_operand:SI 0 "register_operand" "")
4426         (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "")
4427                  (match_operand:SI 2 "input_operand" "")))]
4428   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4429   "")
4431 ;; The V8 architecture specifies that there must be at least 3 instructions
4432 ;; between a write to the Y register and a use of it for correct results.
4433 ;; We try to fill one of them with a simple constant or a memory load.
4435 (define_insn "udivsi3_sp32"
4436   [(set (match_operand:SI 0 "register_operand" "=r,&r,&r,&r")
4437         (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r,r,r,m")
4438                  (match_operand:SI 2 "input_operand" "rI,K,m,r")))]
4439   "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4441   output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4443   switch (which_alternative)
4444     {
4445     case 0:
4446       if (TARGET_V9)
4447         return "udiv\t%1, %2, %0";
4448       else
4449         return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
4450     case 1:
4451       if (TARGET_V9)
4452         return "sethi\t%%hi(%a2), %0\n\tudiv\t%1, %0, %0";
4453       else
4454         return "sethi\t%%hi(%a2), %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4455     case 2:
4456       if (TARGET_V9)
4457         return "ld\t%2, %0\n\tudiv\t%1, %0, %0";
4458       else
4459         return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4460     case 3:
4461       if (TARGET_V9)
4462         return "ld\t%1, %0\n\tudiv\t%0, %2, %0";
4463       else
4464         return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
4465     default:
4466       gcc_unreachable ();
4467     }
4469   [(set_attr "type" "multi")
4470    (set (attr "length")
4471         (if_then_else (eq_attr "isa" "v9")
4472                       (const_int 3) (const_int 5)))])
4474 (define_insn "udivsi3_sp64"
4475   [(set (match_operand:SI 0 "register_operand" "=r")
4476         (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r")
4477                  (match_operand:SI 2 "input_operand" "rI")))]
4478   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4479   "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
4480   [(set_attr "type" "multi")
4481    (set_attr "length" "2")])
4483 (define_insn "udivdi3"
4484   [(set (match_operand:DI 0 "register_operand" "=r")
4485         (udiv:DI (match_operand:DI 1 "register_operand" "r")
4486                  (match_operand:DI 2 "arith_operand" "rI")))]
4487   "TARGET_ARCH64"
4488   "udivx\t%1, %2, %0"
4489   [(set_attr "type" "idiv")])
4491 (define_insn "*cmp_udiv_cc_set"
4492   [(set (reg:CC 100)
4493         (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
4494                              (match_operand:SI 2 "arith_operand" "rI"))
4495                     (const_int 0)))
4496    (set (match_operand:SI 0 "register_operand" "=r")
4497         (udiv:SI (match_dup 1) (match_dup 2)))]
4498   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4500   output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4502   if (TARGET_V9)
4503     return "udivcc\t%1, %2, %0";
4504   else
4505     return "nop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
4507   [(set_attr "type" "multi")
4508    (set (attr "length")
4509         (if_then_else (eq_attr "isa" "v9")
4510                       (const_int 2) (const_int 5)))])
4512 ; sparclet multiply/accumulate insns
4514 (define_insn "*smacsi"
4515   [(set (match_operand:SI 0 "register_operand" "=r")
4516         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
4517                           (match_operand:SI 2 "arith_operand" "rI"))
4518                  (match_operand:SI 3 "register_operand" "0")))]
4519   "TARGET_SPARCLET"
4520   "smac\t%1, %2, %0"
4521   [(set_attr "type" "imul")])
4523 (define_insn "*smacdi"
4524   [(set (match_operand:DI 0 "register_operand" "=r")
4525         (plus:DI (mult:DI (sign_extend:DI
4526                            (match_operand:SI 1 "register_operand" "%r"))
4527                           (sign_extend:DI
4528                            (match_operand:SI 2 "register_operand" "r")))
4529                  (match_operand:DI 3 "register_operand" "0")))]
4530   "TARGET_SPARCLET"
4531   "smacd\t%1, %2, %L0"
4532   [(set_attr "type" "imul")])
4534 (define_insn "*umacdi"
4535   [(set (match_operand:DI 0 "register_operand" "=r")
4536         (plus:DI (mult:DI (zero_extend:DI
4537                            (match_operand:SI 1 "register_operand" "%r"))
4538                           (zero_extend:DI
4539                            (match_operand:SI 2 "register_operand" "r")))
4540                  (match_operand:DI 3 "register_operand" "0")))]
4541   "TARGET_SPARCLET"
4542   "umacd\t%1, %2, %L0"
4543   [(set_attr "type" "imul")])
4546 ;; Boolean instructions.
4548 ;; We define DImode `and' so with DImode `not' we can get
4549 ;; DImode `andn'.  Other combinations are possible.
4551 (define_expand "and<V64I:mode>3"
4552   [(set (match_operand:V64I 0 "register_operand" "")
4553         (and:V64I (match_operand:V64I 1 "arith_double_operand" "")
4554                   (match_operand:V64I 2 "arith_double_operand" "")))]
4555   ""
4556   "")
4558 (define_insn "*and<V64I:mode>3_sp32"
4559   [(set (match_operand:V64I 0 "register_operand" "=r,b")
4560         (and:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
4561                   (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
4562   "! TARGET_ARCH64"
4563   "@
4564   #
4565   fand\t%1, %2, %0"
4566   [(set_attr "type" "*,fga")
4567    (set_attr "length" "2,*")
4568    (set_attr "fptype" "*,double")])
4570 (define_insn "*and<V64I:mode>3_sp64"
4571   [(set (match_operand:V64I 0 "register_operand" "=r,b")
4572         (and:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
4573                   (match_operand:V64I 2 "arith_operand" "rI,b")))]
4574   "TARGET_ARCH64"
4575   "@
4576    and\t%1, %2, %0
4577    fand\t%1, %2, %0"
4578   [(set_attr "type" "*,fga")
4579    (set_attr "fptype" "*,double")])
4581 (define_insn "and<V32I:mode>3"
4582   [(set (match_operand:V32I 0 "register_operand" "=r,d")
4583         (and:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
4584                   (match_operand:V32I 2 "arith_operand" "rI,d")))]
4585   ""
4586   "@
4587    and\t%1, %2, %0
4588    fands\t%1, %2, %0"
4589   [(set_attr "type" "*,fga")
4590    (set_attr "fptype" "*,single")])
4592 (define_split
4593   [(set (match_operand:SI 0 "register_operand" "")
4594         (and:SI (match_operand:SI 1 "register_operand" "")
4595                 (match_operand:SI 2 "const_compl_high_operand" "")))
4596    (clobber (match_operand:SI 3 "register_operand" ""))]
4597   ""
4598   [(set (match_dup 3) (match_dup 4))
4599    (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
4601   operands[4] = GEN_INT (~INTVAL (operands[2]));
4604 (define_insn_and_split "*and_not_<V64I:mode>_sp32"
4605   [(set (match_operand:V64I 0 "register_operand" "=r,b")
4606         (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
4607                   (match_operand:V64I 2 "register_operand" "r,b")))]
4608   "! TARGET_ARCH64"
4609   "@
4610    #
4611    fandnot1\t%1, %2, %0"
4612   "&& reload_completed
4613    && ((GET_CODE (operands[0]) == REG
4614         && REGNO (operands[0]) < 32)
4615        || (GET_CODE (operands[0]) == SUBREG
4616            && GET_CODE (SUBREG_REG (operands[0])) == REG
4617            && REGNO (SUBREG_REG (operands[0])) < 32))"
4618   [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
4619    (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
4620   "operands[3] = gen_highpart (SImode, operands[0]);
4621    operands[4] = gen_highpart (SImode, operands[1]);
4622    operands[5] = gen_highpart (SImode, operands[2]);
4623    operands[6] = gen_lowpart (SImode, operands[0]);
4624    operands[7] = gen_lowpart (SImode, operands[1]);
4625    operands[8] = gen_lowpart (SImode, operands[2]);"
4626   [(set_attr "type" "*,fga")
4627    (set_attr "length" "2,*")
4628    (set_attr "fptype" "*,double")])
4630 (define_insn "*and_not_<V64I:mode>_sp64"
4631   [(set (match_operand:V64I 0 "register_operand" "=r,b")
4632         (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
4633                   (match_operand:V64I 2 "register_operand" "r,b")))]
4634   "TARGET_ARCH64"
4635   "@
4636    andn\t%2, %1, %0
4637    fandnot1\t%1, %2, %0"
4638   [(set_attr "type" "*,fga")
4639    (set_attr "fptype" "*,double")])
4641 (define_insn "*and_not_<V32I:mode>"
4642   [(set (match_operand:V32I 0 "register_operand" "=r,d")
4643         (and:V32I (not:V32I (match_operand:V32I 1 "register_operand" "%r,d"))
4644                   (match_operand:V32I 2 "register_operand" "r,d")))]
4645   ""
4646   "@
4647    andn\t%2, %1, %0
4648    fandnot1s\t%1, %2, %0"
4649   [(set_attr "type" "*,fga")
4650    (set_attr "fptype" "*,single")])
4652 (define_expand "ior<V64I:mode>3"
4653   [(set (match_operand:V64I 0 "register_operand" "")
4654         (ior:V64I (match_operand:V64I 1 "arith_double_operand" "")
4655                   (match_operand:V64I 2 "arith_double_operand" "")))]
4656   ""
4657   "")
4659 (define_insn "*ior<V64I:mode>3_sp32"
4660   [(set (match_operand:V64I 0 "register_operand" "=r,b")
4661         (ior:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
4662                   (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
4663   "! TARGET_ARCH64"
4664   "@
4665   #
4666   for\t%1, %2, %0"
4667   [(set_attr "type" "*,fga")
4668    (set_attr "length" "2,*")
4669    (set_attr "fptype" "*,double")])
4671 (define_insn "*ior<V64I:mode>3_sp64"
4672   [(set (match_operand:V64I 0 "register_operand" "=r,b")
4673         (ior:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
4674                   (match_operand:V64I 2 "arith_operand" "rI,b")))]
4675   "TARGET_ARCH64"
4676   "@
4677   or\t%1, %2, %0
4678   for\t%1, %2, %0"
4679   [(set_attr "type" "*,fga")
4680    (set_attr "fptype" "*,double")])
4682 (define_insn "ior<V32I:mode>3"
4683   [(set (match_operand:V32I 0 "register_operand" "=r,d")
4684         (ior:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
4685                   (match_operand:V32I 2 "arith_operand" "rI,d")))]
4686   ""
4687   "@
4688    or\t%1, %2, %0
4689    fors\t%1, %2, %0"
4690   [(set_attr "type" "*,fga")
4691    (set_attr "fptype" "*,single")])
4693 (define_split
4694   [(set (match_operand:SI 0 "register_operand" "")
4695         (ior:SI (match_operand:SI 1 "register_operand" "")
4696                 (match_operand:SI 2 "const_compl_high_operand" "")))
4697    (clobber (match_operand:SI 3 "register_operand" ""))]
4698   ""
4699   [(set (match_dup 3) (match_dup 4))
4700    (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
4702   operands[4] = GEN_INT (~INTVAL (operands[2]));
4705 (define_insn_and_split "*or_not_<V64I:mode>_sp32"
4706   [(set (match_operand:V64I 0 "register_operand" "=r,b")
4707         (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
4708                   (match_operand:V64I 2 "register_operand" "r,b")))]
4709   "! TARGET_ARCH64"
4710   "@
4711    #
4712    fornot1\t%1, %2, %0"
4713   "&& reload_completed
4714    && ((GET_CODE (operands[0]) == REG
4715         && REGNO (operands[0]) < 32)
4716        || (GET_CODE (operands[0]) == SUBREG
4717            && GET_CODE (SUBREG_REG (operands[0])) == REG
4718            && REGNO (SUBREG_REG (operands[0])) < 32))"
4719   [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
4720    (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
4721   "operands[3] = gen_highpart (SImode, operands[0]);
4722    operands[4] = gen_highpart (SImode, operands[1]);
4723    operands[5] = gen_highpart (SImode, operands[2]);
4724    operands[6] = gen_lowpart (SImode, operands[0]);
4725    operands[7] = gen_lowpart (SImode, operands[1]);
4726    operands[8] = gen_lowpart (SImode, operands[2]);"
4727   [(set_attr "type" "*,fga")
4728    (set_attr "length" "2,*")
4729    (set_attr "fptype" "*,double")])
4731 (define_insn "*or_not_<V64I:mode>_sp64"
4732   [(set (match_operand:V64I 0 "register_operand" "=r,b")
4733         (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
4734                   (match_operand:V64I 2 "register_operand" "r,b")))]
4735   "TARGET_ARCH64"
4736   "@
4737   orn\t%2, %1, %0
4738   fornot1\t%1, %2, %0"
4739   [(set_attr "type" "*,fga")
4740    (set_attr "fptype" "*,double")])
4742 (define_insn "*or_not_<V32I:mode>"
4743   [(set (match_operand:V32I 0 "register_operand" "=r,d")
4744         (ior:V32I (not:V32I (match_operand:V32I 1 "register_operand" "r,d"))
4745                   (match_operand:V32I 2 "register_operand" "r,d")))]
4746   ""
4747   "@
4748    orn\t%2, %1, %0
4749    fornot1s\t%1, %2, %0"
4750   [(set_attr "type" "*,fga")
4751    (set_attr "fptype" "*,single")])
4753 (define_expand "xor<V64I:mode>3"
4754   [(set (match_operand:V64I 0 "register_operand" "")
4755         (xor:V64I (match_operand:V64I 1 "arith_double_operand" "")
4756                   (match_operand:V64I 2 "arith_double_operand" "")))]
4757   ""
4758   "")
4760 (define_insn "*xor<V64I:mode>3_sp32"
4761   [(set (match_operand:V64I 0 "register_operand" "=r,b")
4762         (xor:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
4763                   (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
4764   "! TARGET_ARCH64"
4765   "@
4766   #
4767   fxor\t%1, %2, %0"
4768   [(set_attr "type" "*,fga")
4769    (set_attr "length" "2,*")
4770    (set_attr "fptype" "*,double")])
4772 (define_insn "*xor<V64I:mode>3_sp64"
4773   [(set (match_operand:V64I 0 "register_operand" "=r,b")
4774         (xor:V64I (match_operand:V64I 1 "arith_operand" "%rJ,b")
4775                   (match_operand:V64I 2 "arith_operand" "rI,b")))]
4776   "TARGET_ARCH64"
4777   "@
4778   xor\t%r1, %2, %0
4779   fxor\t%1, %2, %0"
4780   [(set_attr "type" "*,fga")
4781    (set_attr "fptype" "*,double")])
4783 (define_insn "xor<V32I:mode>3"
4784   [(set (match_operand:V32I 0 "register_operand" "=r,d")
4785         (xor:V32I (match_operand:V32I 1 "arith_operand" "%rJ,d")
4786                   (match_operand:V32I 2 "arith_operand" "rI,d")))]
4787   ""
4788   "@
4789    xor\t%r1, %2, %0
4790    fxors\t%1, %2, %0"
4791   [(set_attr "type" "*,fga")
4792    (set_attr "fptype" "*,single")])
4794 (define_split
4795   [(set (match_operand:SI 0 "register_operand" "")
4796         (xor:SI (match_operand:SI 1 "register_operand" "")
4797                 (match_operand:SI 2 "const_compl_high_operand" "")))
4798    (clobber (match_operand:SI 3 "register_operand" ""))]
4799    ""
4800   [(set (match_dup 3) (match_dup 4))
4801    (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
4803   operands[4] = GEN_INT (~INTVAL (operands[2]));
4806 (define_split
4807   [(set (match_operand:SI 0 "register_operand" "")
4808         (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
4809                         (match_operand:SI 2 "const_compl_high_operand" ""))))
4810    (clobber (match_operand:SI 3 "register_operand" ""))]
4811   ""
4812   [(set (match_dup 3) (match_dup 4))
4813    (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
4815   operands[4] = GEN_INT (~INTVAL (operands[2]));
4818 ;; Split DImode logical operations requiring two instructions.
4819 (define_split
4820   [(set (match_operand:V64I 0 "register_operand" "")
4821         (match_operator:V64I 1 "cc_arith_operator"      ; AND, IOR, XOR
4822                            [(match_operand:V64I 2 "register_operand" "")
4823                             (match_operand:V64I 3 "arith_double_operand" "")]))]
4824   "! TARGET_ARCH64
4825    && reload_completed
4826    && ((GET_CODE (operands[0]) == REG
4827         && REGNO (operands[0]) < 32)
4828        || (GET_CODE (operands[0]) == SUBREG
4829            && GET_CODE (SUBREG_REG (operands[0])) == REG
4830            && REGNO (SUBREG_REG (operands[0])) < 32))"
4831   [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
4832    (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
4834   operands[4] = gen_highpart (SImode, operands[0]);
4835   operands[5] = gen_lowpart (SImode, operands[0]);
4836   operands[6] = gen_highpart (SImode, operands[2]);
4837   operands[7] = gen_lowpart (SImode, operands[2]);
4838 #if HOST_BITS_PER_WIDE_INT == 32
4839   if (GET_CODE (operands[3]) == CONST_INT && <V64I:MODE>mode == DImode)
4840     {
4841       if (INTVAL (operands[3]) < 0)
4842         operands[8] = constm1_rtx;
4843       else
4844         operands[8] = const0_rtx;
4845     }
4846   else
4847 #endif
4848     operands[8] = gen_highpart_mode (SImode, <V64I:MODE>mode, operands[3]);
4849   operands[9] = gen_lowpart (SImode, operands[3]);
4852 ;; xnor patterns.  Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
4853 ;; Combine now canonicalizes to the rightmost expression.
4854 (define_insn_and_split "*xor_not_<V64I:mode>_sp32"
4855   [(set (match_operand:V64I 0 "register_operand" "=r,b")
4856         (not:V64I (xor:V64I (match_operand:V64I 1 "register_operand" "r,b")
4857                             (match_operand:V64I 2 "register_operand" "r,b"))))]
4858   "! TARGET_ARCH64"
4859   "@
4860    #
4861    fxnor\t%1, %2, %0"
4862   "&& reload_completed
4863    && ((GET_CODE (operands[0]) == REG
4864         && REGNO (operands[0]) < 32)
4865        || (GET_CODE (operands[0]) == SUBREG
4866            && GET_CODE (SUBREG_REG (operands[0])) == REG
4867            && REGNO (SUBREG_REG (operands[0])) < 32))"
4868   [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
4869    (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
4870   "operands[3] = gen_highpart (SImode, operands[0]);
4871    operands[4] = gen_highpart (SImode, operands[1]);
4872    operands[5] = gen_highpart (SImode, operands[2]);
4873    operands[6] = gen_lowpart (SImode, operands[0]);
4874    operands[7] = gen_lowpart (SImode, operands[1]);
4875    operands[8] = gen_lowpart (SImode, operands[2]);"
4876   [(set_attr "type" "*,fga")
4877    (set_attr "length" "2,*")
4878    (set_attr "fptype" "*,double")])
4880 (define_insn "*xor_not_<V64I:mode>_sp64"
4881   [(set (match_operand:V64I 0 "register_operand" "=r,b")
4882         (not:V64I (xor:V64I (match_operand:V64I 1 "register_or_zero_operand" "rJ,b")
4883                             (match_operand:V64I 2 "arith_operand" "rI,b"))))]
4884   "TARGET_ARCH64"
4885   "@
4886   xnor\t%r1, %2, %0
4887   fxnor\t%1, %2, %0"
4888   [(set_attr "type" "*,fga")
4889    (set_attr "fptype" "*,double")])
4891 (define_insn "*xor_not_<V32I:mode>"
4892   [(set (match_operand:V32I 0 "register_operand" "=r,d")
4893         (not:V32I (xor:V32I (match_operand:V32I 1 "register_or_zero_operand" "rJ,d")
4894                             (match_operand:V32I 2 "arith_operand" "rI,d"))))]
4895   ""
4896   "@
4897    xnor\t%r1, %2, %0
4898    fxnors\t%1, %2, %0"
4899   [(set_attr "type" "*,fga")
4900    (set_attr "fptype" "*,single")])
4902 ;; These correspond to the above in the case where we also (or only)
4903 ;; want to set the condition code.  
4905 (define_insn "*cmp_cc_arith_op"
4906   [(set (reg:CC 100)
4907         (compare:CC
4908          (match_operator:SI 2 "cc_arith_operator"
4909                             [(match_operand:SI 0 "arith_operand" "%r")
4910                              (match_operand:SI 1 "arith_operand" "rI")])
4911          (const_int 0)))]
4912   ""
4913   "%A2cc\t%0, %1, %%g0"
4914   [(set_attr "type" "compare")])
4916 (define_insn "*cmp_ccx_arith_op"
4917   [(set (reg:CCX 100)
4918         (compare:CCX
4919          (match_operator:DI 2 "cc_arith_operator"
4920                             [(match_operand:DI 0 "arith_operand" "%r")
4921                              (match_operand:DI 1 "arith_operand" "rI")])
4922          (const_int 0)))]
4923   "TARGET_ARCH64"
4924   "%A2cc\t%0, %1, %%g0"
4925   [(set_attr "type" "compare")])
4927 (define_insn "*cmp_cc_arith_op_set"
4928   [(set (reg:CC 100)
4929         (compare:CC
4930          (match_operator:SI 3 "cc_arith_operator"
4931                             [(match_operand:SI 1 "arith_operand" "%r")
4932                              (match_operand:SI 2 "arith_operand" "rI")])
4933          (const_int 0)))
4934    (set (match_operand:SI 0 "register_operand" "=r")
4935         (match_operator:SI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
4936   "GET_CODE (operands[3]) == GET_CODE (operands[4])"
4937   "%A3cc\t%1, %2, %0"
4938   [(set_attr "type" "compare")])
4940 (define_insn "*cmp_ccx_arith_op_set"
4941   [(set (reg:CCX 100)
4942         (compare:CCX
4943          (match_operator:DI 3 "cc_arith_operator"
4944                             [(match_operand:DI 1 "arith_operand" "%r")
4945                              (match_operand:DI 2 "arith_operand" "rI")])
4946          (const_int 0)))
4947    (set (match_operand:DI 0 "register_operand" "=r")
4948         (match_operator:DI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
4949   "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
4950   "%A3cc\t%1, %2, %0"
4951   [(set_attr "type" "compare")])
4953 (define_insn "*cmp_cc_xor_not"
4954   [(set (reg:CC 100)
4955         (compare:CC
4956          (not:SI (xor:SI (match_operand:SI 0 "register_or_zero_operand" "%rJ")
4957                          (match_operand:SI 1 "arith_operand" "rI")))
4958          (const_int 0)))]
4959   ""
4960   "xnorcc\t%r0, %1, %%g0"
4961   [(set_attr "type" "compare")])
4963 (define_insn "*cmp_ccx_xor_not"
4964   [(set (reg:CCX 100)
4965         (compare:CCX
4966          (not:DI (xor:DI (match_operand:DI 0 "register_or_zero_operand" "%rJ")
4967                          (match_operand:DI 1 "arith_operand" "rI")))
4968          (const_int 0)))]
4969   "TARGET_ARCH64"
4970   "xnorcc\t%r0, %1, %%g0"
4971   [(set_attr "type" "compare")])
4973 (define_insn "*cmp_cc_xor_not_set"
4974   [(set (reg:CC 100)
4975         (compare:CC
4976          (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
4977                          (match_operand:SI 2 "arith_operand" "rI")))
4978          (const_int 0)))
4979    (set (match_operand:SI 0 "register_operand" "=r")
4980         (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
4981   ""
4982   "xnorcc\t%r1, %2, %0"
4983   [(set_attr "type" "compare")])
4985 (define_insn "*cmp_ccx_xor_not_set"
4986   [(set (reg:CCX 100)
4987         (compare:CCX
4988          (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
4989                          (match_operand:DI 2 "arith_operand" "rI")))
4990          (const_int 0)))
4991    (set (match_operand:DI 0 "register_operand" "=r")
4992         (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
4993   "TARGET_ARCH64"
4994   "xnorcc\t%r1, %2, %0"
4995   [(set_attr "type" "compare")])
4997 (define_insn "*cmp_cc_arith_op_not"
4998   [(set (reg:CC 100)
4999         (compare:CC
5000          (match_operator:SI 2 "cc_arith_not_operator"
5001                             [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
5002                              (match_operand:SI 1 "register_or_zero_operand" "rJ")])
5003          (const_int 0)))]
5004   ""
5005   "%B2cc\t%r1, %0, %%g0"
5006   [(set_attr "type" "compare")])
5008 (define_insn "*cmp_ccx_arith_op_not"
5009   [(set (reg:CCX 100)
5010         (compare:CCX
5011          (match_operator:DI 2 "cc_arith_not_operator"
5012                             [(not:DI (match_operand:DI 0 "arith_operand" "rI"))
5013                              (match_operand:DI 1 "register_or_zero_operand" "rJ")])
5014          (const_int 0)))]
5015   "TARGET_ARCH64"
5016   "%B2cc\t%r1, %0, %%g0"
5017   [(set_attr "type" "compare")])
5019 (define_insn "*cmp_cc_arith_op_not_set"
5020   [(set (reg:CC 100)
5021         (compare:CC
5022          (match_operator:SI 3 "cc_arith_not_operator"
5023                             [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
5024                              (match_operand:SI 2 "register_or_zero_operand" "rJ")])
5025          (const_int 0)))
5026    (set (match_operand:SI 0 "register_operand" "=r")
5027         (match_operator:SI 4 "cc_arith_not_operator"
5028                             [(not:SI (match_dup 1)) (match_dup 2)]))]
5029   "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5030   "%B3cc\t%r2, %1, %0"
5031   [(set_attr "type" "compare")])
5033 (define_insn "*cmp_ccx_arith_op_not_set"
5034   [(set (reg:CCX 100)
5035         (compare:CCX
5036          (match_operator:DI 3 "cc_arith_not_operator"
5037                             [(not:DI (match_operand:DI 1 "arith_operand" "rI"))
5038                              (match_operand:DI 2 "register_or_zero_operand" "rJ")])
5039          (const_int 0)))
5040    (set (match_operand:DI 0 "register_operand" "=r")
5041         (match_operator:DI 4 "cc_arith_not_operator"
5042                             [(not:DI (match_dup 1)) (match_dup 2)]))]
5043   "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5044   "%B3cc\t%r2, %1, %0"
5045   [(set_attr "type" "compare")])
5047 ;; We cannot use the "neg" pseudo insn because the Sun assembler
5048 ;; does not know how to make it work for constants.
5050 (define_expand "negdi2"
5051   [(set (match_operand:DI 0 "register_operand" "=r")
5052         (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5053   ""
5055   if (! TARGET_ARCH64)
5056     {
5057       emit_insn (gen_rtx_PARALLEL
5058                  (VOIDmode,
5059                   gen_rtvec (2,
5060                              gen_rtx_SET (VOIDmode, operand0,
5061                                           gen_rtx_NEG (DImode, operand1)),
5062                              gen_rtx_CLOBBER (VOIDmode,
5063                                               gen_rtx_REG (CCmode,
5064                                                            SPARC_ICC_REG)))));
5065       DONE;
5066     }
5069 (define_insn_and_split "*negdi2_sp32"
5070   [(set (match_operand:DI 0 "register_operand" "=r")
5071         (neg:DI (match_operand:DI 1 "register_operand" "r")))
5072    (clobber (reg:CC 100))]
5073   "! TARGET_ARCH64"
5074   "#"
5075   "&& reload_completed"
5076   [(parallel [(set (reg:CC_NOOV 100)
5077                    (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
5078                                     (const_int 0)))
5079               (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
5080    (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
5081                                 (ltu:SI (reg:CC 100) (const_int 0))))]
5082   "operands[2] = gen_highpart (SImode, operands[0]);
5083    operands[3] = gen_highpart (SImode, operands[1]);
5084    operands[4] = gen_lowpart (SImode, operands[0]);
5085    operands[5] = gen_lowpart (SImode, operands[1]);"
5086   [(set_attr "length" "2")])
5088 (define_insn "*negdi2_sp64"
5089   [(set (match_operand:DI 0 "register_operand" "=r")
5090         (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5091   "TARGET_ARCH64"
5092   "sub\t%%g0, %1, %0")
5094 (define_insn "negsi2"
5095   [(set (match_operand:SI 0 "register_operand" "=r")
5096         (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
5097   ""
5098   "sub\t%%g0, %1, %0")
5100 (define_insn "*cmp_cc_neg"
5101   [(set (reg:CC_NOOV 100)
5102         (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
5103                          (const_int 0)))]
5104   ""
5105   "subcc\t%%g0, %0, %%g0"
5106   [(set_attr "type" "compare")])
5108 (define_insn "*cmp_ccx_neg"
5109   [(set (reg:CCX_NOOV 100)
5110         (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_operand" "rI"))
5111                           (const_int 0)))]
5112   "TARGET_ARCH64"
5113   "subcc\t%%g0, %0, %%g0"
5114   [(set_attr "type" "compare")])
5116 (define_insn "*cmp_cc_set_neg"
5117   [(set (reg:CC_NOOV 100)
5118         (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
5119                          (const_int 0)))
5120    (set (match_operand:SI 0 "register_operand" "=r")
5121         (neg:SI (match_dup 1)))]
5122   ""
5123   "subcc\t%%g0, %1, %0"
5124   [(set_attr "type" "compare")])
5126 (define_insn "*cmp_ccx_set_neg"
5127   [(set (reg:CCX_NOOV 100)
5128         (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_operand" "rI"))
5129                           (const_int 0)))
5130    (set (match_operand:DI 0 "register_operand" "=r")
5131         (neg:DI (match_dup 1)))]
5132   "TARGET_ARCH64"
5133   "subcc\t%%g0, %1, %0"
5134   [(set_attr "type" "compare")])
5136 ;; We cannot use the "not" pseudo insn because the Sun assembler
5137 ;; does not know how to make it work for constants.
5138 (define_expand "one_cmpl<V64I:mode>2"
5139   [(set (match_operand:V64I 0 "register_operand" "")
5140         (not:V64I (match_operand:V64I 1 "register_operand" "")))]
5141   ""
5142   "")
5144 (define_insn_and_split "*one_cmpl<V64I:mode>2_sp32"
5145   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5146         (not:V64I (match_operand:V64I 1 "register_operand" "r,b")))]
5147   "! TARGET_ARCH64"
5148   "@
5149    #
5150    fnot1\t%1, %0"
5151   "&& reload_completed
5152    && ((GET_CODE (operands[0]) == REG
5153         && REGNO (operands[0]) < 32)
5154        || (GET_CODE (operands[0]) == SUBREG
5155            && GET_CODE (SUBREG_REG (operands[0])) == REG
5156            && REGNO (SUBREG_REG (operands[0])) < 32))"
5157   [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
5158    (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
5159   "operands[2] = gen_highpart (SImode, operands[0]);
5160    operands[3] = gen_highpart (SImode, operands[1]);
5161    operands[4] = gen_lowpart (SImode, operands[0]);
5162    operands[5] = gen_lowpart (SImode, operands[1]);"
5163   [(set_attr "type" "*,fga")
5164    (set_attr "length" "2,*")
5165    (set_attr "fptype" "*,double")])
5167 (define_insn "*one_cmpl<V64I:mode>2_sp64"
5168   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5169         (not:V64I (match_operand:V64I 1 "arith_operand" "rI,b")))]
5170   "TARGET_ARCH64"
5171   "@
5172    xnor\t%%g0, %1, %0
5173    fnot1\t%1, %0"
5174   [(set_attr "type" "*,fga")
5175    (set_attr "fptype" "*,double")])
5177 (define_insn "one_cmpl<V32I:mode>2"
5178   [(set (match_operand:V32I 0 "register_operand" "=r,d")
5179         (not:V32I (match_operand:V32I 1 "arith_operand" "rI,d")))]
5180   ""
5181   "@
5182   xnor\t%%g0, %1, %0
5183   fnot1s\t%1, %0"
5184   [(set_attr "type" "*,fga")
5185    (set_attr "fptype" "*,single")])
5187 (define_insn "*cmp_cc_not"
5188   [(set (reg:CC 100)
5189         (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
5190                     (const_int 0)))]
5191   ""
5192   "xnorcc\t%%g0, %0, %%g0"
5193   [(set_attr "type" "compare")])
5195 (define_insn "*cmp_ccx_not"
5196   [(set (reg:CCX 100)
5197         (compare:CCX (not:DI (match_operand:DI 0 "arith_operand" "rI"))
5198                      (const_int 0)))]
5199   "TARGET_ARCH64"
5200   "xnorcc\t%%g0, %0, %%g0"
5201   [(set_attr "type" "compare")])
5203 (define_insn "*cmp_cc_set_not"
5204   [(set (reg:CC 100)
5205         (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
5206                     (const_int 0)))
5207    (set (match_operand:SI 0 "register_operand" "=r")
5208         (not:SI (match_dup 1)))]
5209   ""
5210   "xnorcc\t%%g0, %1, %0"
5211   [(set_attr "type" "compare")])
5213 (define_insn "*cmp_ccx_set_not"
5214   [(set (reg:CCX 100)
5215         (compare:CCX (not:DI (match_operand:DI 1 "arith_operand" "rI"))
5216                     (const_int 0)))
5217    (set (match_operand:DI 0 "register_operand" "=r")
5218         (not:DI (match_dup 1)))]
5219   "TARGET_ARCH64"
5220   "xnorcc\t%%g0, %1, %0"
5221   [(set_attr "type" "compare")])
5223 (define_insn "*cmp_cc_set"
5224   [(set (match_operand:SI 0 "register_operand" "=r")
5225         (match_operand:SI 1 "register_operand" "r"))
5226    (set (reg:CC 100)
5227         (compare:CC (match_dup 1)
5228                     (const_int 0)))]
5229   ""
5230   "orcc\t%1, 0, %0"
5231   [(set_attr "type" "compare")])
5233 (define_insn "*cmp_ccx_set64"
5234   [(set (match_operand:DI 0 "register_operand" "=r")
5235         (match_operand:DI 1 "register_operand" "r"))
5236    (set (reg:CCX 100)
5237         (compare:CCX (match_dup 1)
5238                      (const_int 0)))]
5239   "TARGET_ARCH64"
5240   "orcc\t%1, 0, %0"
5241    [(set_attr "type" "compare")])
5244 ;; Floating point arithmetic instructions.
5246 (define_expand "addtf3"
5247   [(set (match_operand:TF 0 "nonimmediate_operand" "")
5248         (plus:TF (match_operand:TF 1 "general_operand" "")
5249                  (match_operand:TF 2 "general_operand" "")))]
5250   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5251   "emit_tfmode_binop (PLUS, operands); DONE;")
5253 (define_insn "*addtf3_hq"
5254   [(set (match_operand:TF 0 "register_operand" "=e")
5255         (plus:TF (match_operand:TF 1 "register_operand" "e")
5256                  (match_operand:TF 2 "register_operand" "e")))]
5257   "TARGET_FPU && TARGET_HARD_QUAD"
5258   "faddq\t%1, %2, %0"
5259   [(set_attr "type" "fp")])
5261 (define_insn "adddf3"
5262   [(set (match_operand:DF 0 "register_operand" "=e")
5263         (plus:DF (match_operand:DF 1 "register_operand" "e")
5264                  (match_operand:DF 2 "register_operand" "e")))]
5265   "TARGET_FPU"
5266   "faddd\t%1, %2, %0"
5267   [(set_attr "type" "fp")
5268    (set_attr "fptype" "double")])
5270 (define_insn "addsf3"
5271   [(set (match_operand:SF 0 "register_operand" "=f")
5272         (plus:SF (match_operand:SF 1 "register_operand" "f")
5273                  (match_operand:SF 2 "register_operand" "f")))]
5274   "TARGET_FPU"
5275   "fadds\t%1, %2, %0"
5276   [(set_attr "type" "fp")])
5278 (define_expand "subtf3"
5279   [(set (match_operand:TF 0 "nonimmediate_operand" "")
5280         (minus:TF (match_operand:TF 1 "general_operand" "")
5281                   (match_operand:TF 2 "general_operand" "")))]
5282   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5283   "emit_tfmode_binop (MINUS, operands); DONE;")
5285 (define_insn "*subtf3_hq"
5286   [(set (match_operand:TF 0 "register_operand" "=e")
5287         (minus:TF (match_operand:TF 1 "register_operand" "e")
5288                   (match_operand:TF 2 "register_operand" "e")))]
5289   "TARGET_FPU && TARGET_HARD_QUAD"
5290   "fsubq\t%1, %2, %0"
5291   [(set_attr "type" "fp")])
5293 (define_insn "subdf3"
5294   [(set (match_operand:DF 0 "register_operand" "=e")
5295         (minus:DF (match_operand:DF 1 "register_operand" "e")
5296                   (match_operand:DF 2 "register_operand" "e")))]
5297   "TARGET_FPU"
5298   "fsubd\t%1, %2, %0"
5299   [(set_attr "type" "fp")
5300    (set_attr "fptype" "double")])
5302 (define_insn "subsf3"
5303   [(set (match_operand:SF 0 "register_operand" "=f")
5304         (minus:SF (match_operand:SF 1 "register_operand" "f")
5305                   (match_operand:SF 2 "register_operand" "f")))]
5306   "TARGET_FPU"
5307   "fsubs\t%1, %2, %0"
5308   [(set_attr "type" "fp")])
5310 (define_expand "multf3"
5311   [(set (match_operand:TF 0 "nonimmediate_operand" "")
5312         (mult:TF (match_operand:TF 1 "general_operand" "")
5313                  (match_operand:TF 2 "general_operand" "")))]
5314   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5315   "emit_tfmode_binop (MULT, operands); DONE;")
5317 (define_insn "*multf3_hq"
5318   [(set (match_operand:TF 0 "register_operand" "=e")
5319         (mult:TF (match_operand:TF 1 "register_operand" "e")
5320                  (match_operand:TF 2 "register_operand" "e")))]
5321   "TARGET_FPU && TARGET_HARD_QUAD"
5322   "fmulq\t%1, %2, %0"
5323   [(set_attr "type" "fpmul")])
5325 (define_insn "muldf3"
5326   [(set (match_operand:DF 0 "register_operand" "=e")
5327         (mult:DF (match_operand:DF 1 "register_operand" "e")
5328                  (match_operand:DF 2 "register_operand" "e")))]
5329   "TARGET_FPU"
5330   "fmuld\t%1, %2, %0"
5331   [(set_attr "type" "fpmul")
5332    (set_attr "fptype" "double")])
5334 (define_insn "mulsf3"
5335   [(set (match_operand:SF 0 "register_operand" "=f")
5336         (mult:SF (match_operand:SF 1 "register_operand" "f")
5337                  (match_operand:SF 2 "register_operand" "f")))]
5338   "TARGET_FPU"
5339   "fmuls\t%1, %2, %0"
5340   [(set_attr "type" "fpmul")])
5342 (define_insn "*muldf3_extend"
5343   [(set (match_operand:DF 0 "register_operand" "=e")
5344         (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
5345                  (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
5346   "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
5347   "fsmuld\t%1, %2, %0"
5348   [(set_attr "type" "fpmul")
5349    (set_attr "fptype" "double")])
5351 (define_insn "*multf3_extend"
5352   [(set (match_operand:TF 0 "register_operand" "=e")
5353         (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
5354                  (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
5355   "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
5356   "fdmulq\t%1, %2, %0"
5357   [(set_attr "type" "fpmul")])
5359 (define_expand "divtf3"
5360   [(set (match_operand:TF 0 "nonimmediate_operand" "")
5361         (div:TF (match_operand:TF 1 "general_operand" "")
5362                 (match_operand:TF 2 "general_operand" "")))]
5363   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5364   "emit_tfmode_binop (DIV, operands); DONE;")
5366 ;; don't have timing for quad-prec. divide.
5367 (define_insn "*divtf3_hq"
5368   [(set (match_operand:TF 0 "register_operand" "=e")
5369         (div:TF (match_operand:TF 1 "register_operand" "e")
5370                 (match_operand:TF 2 "register_operand" "e")))]
5371   "TARGET_FPU && TARGET_HARD_QUAD"
5372   "fdivq\t%1, %2, %0"
5373   [(set_attr "type" "fpdivd")])
5375 (define_insn "divdf3"
5376   [(set (match_operand:DF 0 "register_operand" "=e")
5377         (div:DF (match_operand:DF 1 "register_operand" "e")
5378                 (match_operand:DF 2 "register_operand" "e")))]
5379   "TARGET_FPU"
5380   "fdivd\t%1, %2, %0"
5381   [(set_attr "type" "fpdivd")
5382    (set_attr "fptype" "double")])
5384 (define_insn "divsf3"
5385   [(set (match_operand:SF 0 "register_operand" "=f")
5386         (div:SF (match_operand:SF 1 "register_operand" "f")
5387                 (match_operand:SF 2 "register_operand" "f")))]
5388   "TARGET_FPU"
5389   "fdivs\t%1, %2, %0"
5390   [(set_attr "type" "fpdivs")])
5392 (define_expand "negtf2"
5393   [(set (match_operand:TF 0 "register_operand" "=e,e")
5394         (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5395   "TARGET_FPU"
5396   "")
5398 (define_insn_and_split "*negtf2_notv9"
5399   [(set (match_operand:TF 0 "register_operand" "=e,e")
5400         (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5401   ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5402   "TARGET_FPU
5403    && ! TARGET_V9"
5404   "@
5405   fnegs\t%0, %0
5406   #"
5407   "&& reload_completed
5408    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5409   [(set (match_dup 2) (neg:SF (match_dup 3)))
5410    (set (match_dup 4) (match_dup 5))
5411    (set (match_dup 6) (match_dup 7))]
5412   "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5413    operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5414    operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5415    operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
5416    operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5417    operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5418   [(set_attr "type" "fpmove,*")
5419    (set_attr "length" "*,2")])
5421 (define_insn_and_split "*negtf2_v9"
5422   [(set (match_operand:TF 0 "register_operand" "=e,e")
5423         (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5424   ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5425   "TARGET_FPU && TARGET_V9"
5426   "@
5427   fnegd\t%0, %0
5428   #"
5429   "&& reload_completed
5430    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5431   [(set (match_dup 2) (neg:DF (match_dup 3)))
5432    (set (match_dup 4) (match_dup 5))]
5433   "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
5434    operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
5435    operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5436    operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5437   [(set_attr "type" "fpmove,*")
5438    (set_attr "length" "*,2")
5439    (set_attr "fptype" "double")])
5441 (define_expand "negdf2"
5442   [(set (match_operand:DF 0 "register_operand" "")
5443         (neg:DF (match_operand:DF 1 "register_operand" "")))]
5444   "TARGET_FPU"
5445   "")
5447 (define_insn_and_split "*negdf2_notv9"
5448   [(set (match_operand:DF 0 "register_operand" "=e,e")
5449         (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
5450   "TARGET_FPU && ! TARGET_V9"
5451   "@
5452   fnegs\t%0, %0
5453   #"
5454   "&& reload_completed
5455    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5456   [(set (match_dup 2) (neg:SF (match_dup 3)))
5457    (set (match_dup 4) (match_dup 5))]
5458   "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5459    operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5460    operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5461    operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
5462   [(set_attr "type" "fpmove,*")
5463    (set_attr "length" "*,2")])
5465 (define_insn "*negdf2_v9"
5466   [(set (match_operand:DF 0 "register_operand" "=e")
5467         (neg:DF (match_operand:DF 1 "register_operand" "e")))]
5468   "TARGET_FPU && TARGET_V9"
5469   "fnegd\t%1, %0"
5470   [(set_attr "type" "fpmove")
5471    (set_attr "fptype" "double")])
5473 (define_insn "negsf2"
5474   [(set (match_operand:SF 0 "register_operand" "=f")
5475         (neg:SF (match_operand:SF 1 "register_operand" "f")))]
5476   "TARGET_FPU"
5477   "fnegs\t%1, %0"
5478   [(set_attr "type" "fpmove")])
5480 (define_expand "abstf2"
5481   [(set (match_operand:TF 0 "register_operand" "")
5482         (abs:TF (match_operand:TF 1 "register_operand" "")))]
5483   "TARGET_FPU"
5484   "")
5486 (define_insn_and_split "*abstf2_notv9"
5487   [(set (match_operand:TF 0 "register_operand" "=e,e")
5488         (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5489   ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5490   "TARGET_FPU && ! TARGET_V9"
5491   "@
5492   fabss\t%0, %0
5493   #"
5494   "&& reload_completed
5495    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5496   [(set (match_dup 2) (abs:SF (match_dup 3)))
5497    (set (match_dup 4) (match_dup 5))
5498    (set (match_dup 6) (match_dup 7))]
5499   "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5500    operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5501    operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5502    operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
5503    operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5504    operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5505   [(set_attr "type" "fpmove,*")
5506    (set_attr "length" "*,2")])
5508 (define_insn "*abstf2_hq_v9"
5509   [(set (match_operand:TF 0 "register_operand" "=e,e")
5510         (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5511   "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
5512   "@
5513   fabsd\t%0, %0
5514   fabsq\t%1, %0"
5515   [(set_attr "type" "fpmove")
5516    (set_attr "fptype" "double,*")])
5518 (define_insn_and_split "*abstf2_v9"
5519   [(set (match_operand:TF 0 "register_operand" "=e,e")
5520         (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5521   "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
5522   "@
5523   fabsd\t%0, %0
5524   #"
5525   "&& reload_completed
5526    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5527   [(set (match_dup 2) (abs:DF (match_dup 3)))
5528    (set (match_dup 4) (match_dup 5))]
5529   "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
5530    operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
5531    operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5532    operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5533   [(set_attr "type" "fpmove,*")
5534    (set_attr "length" "*,2")
5535    (set_attr "fptype" "double,*")])
5537 (define_expand "absdf2"
5538   [(set (match_operand:DF 0 "register_operand" "")
5539         (abs:DF (match_operand:DF 1 "register_operand" "")))]
5540   "TARGET_FPU"
5541   "")
5543 (define_insn_and_split "*absdf2_notv9"
5544   [(set (match_operand:DF 0 "register_operand" "=e,e")
5545         (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
5546   "TARGET_FPU && ! TARGET_V9"
5547   "@
5548   fabss\t%0, %0
5549   #"
5550   "&& reload_completed
5551    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5552   [(set (match_dup 2) (abs:SF (match_dup 3)))
5553    (set (match_dup 4) (match_dup 5))]
5554   "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5555    operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5556    operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5557    operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
5558   [(set_attr "type" "fpmove,*")
5559    (set_attr "length" "*,2")])
5561 (define_insn "*absdf2_v9"
5562   [(set (match_operand:DF 0 "register_operand" "=e")
5563         (abs:DF (match_operand:DF 1 "register_operand" "e")))]
5564   "TARGET_FPU && TARGET_V9"
5565   "fabsd\t%1, %0"
5566   [(set_attr "type" "fpmove")
5567    (set_attr "fptype" "double")])
5569 (define_insn "abssf2"
5570   [(set (match_operand:SF 0 "register_operand" "=f")
5571         (abs:SF (match_operand:SF 1 "register_operand" "f")))]
5572   "TARGET_FPU"
5573   "fabss\t%1, %0"
5574   [(set_attr "type" "fpmove")])
5576 (define_expand "sqrttf2"
5577   [(set (match_operand:TF 0 "nonimmediate_operand" "")
5578         (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
5579   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5580   "emit_tfmode_unop (SQRT, operands); DONE;")
5582 (define_insn "*sqrttf2_hq"
5583   [(set (match_operand:TF 0 "register_operand" "=e")
5584         (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
5585   "TARGET_FPU && TARGET_HARD_QUAD"
5586   "fsqrtq\t%1, %0"
5587   [(set_attr "type" "fpsqrtd")])
5589 (define_insn "sqrtdf2"
5590   [(set (match_operand:DF 0 "register_operand" "=e")
5591         (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
5592   "TARGET_FPU"
5593   "fsqrtd\t%1, %0"
5594   [(set_attr "type" "fpsqrtd")
5595    (set_attr "fptype" "double")])
5597 (define_insn "sqrtsf2"
5598   [(set (match_operand:SF 0 "register_operand" "=f")
5599         (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
5600   "TARGET_FPU"
5601   "fsqrts\t%1, %0"
5602   [(set_attr "type" "fpsqrts")])
5605 ;; Arithmetic shift instructions.
5607 (define_insn "ashlsi3"
5608   [(set (match_operand:SI 0 "register_operand" "=r")
5609         (ashift:SI (match_operand:SI 1 "register_operand" "r")
5610                    (match_operand:SI 2 "arith_operand" "rI")))]
5611   ""
5613   if (GET_CODE (operands[2]) == CONST_INT)
5614     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5615   return "sll\t%1, %2, %0";
5617   [(set (attr "type")
5618         (if_then_else (match_operand 2 "const_one_operand" "")
5619                       (const_string "ialu") (const_string "shift")))])
5621 (define_expand "ashldi3"
5622   [(set (match_operand:DI 0 "register_operand" "=r")
5623         (ashift:DI (match_operand:DI 1 "register_operand" "r")
5624                    (match_operand:SI 2 "arith_operand" "rI")))]
5625   "TARGET_ARCH64 || TARGET_V8PLUS"
5627   if (! TARGET_ARCH64)
5628     {
5629       if (GET_CODE (operands[2]) == CONST_INT)
5630         FAIL;
5631       emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
5632       DONE;
5633     }
5636 (define_insn "*ashldi3_sp64"
5637   [(set (match_operand:DI 0 "register_operand" "=r")
5638         (ashift:DI (match_operand:DI 1 "register_operand" "r")
5639                    (match_operand:SI 2 "arith_operand" "rI")))]
5640   "TARGET_ARCH64"
5642   if (GET_CODE (operands[2]) == CONST_INT)
5643     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5644   return "sllx\t%1, %2, %0";
5646   [(set (attr "type")
5647         (if_then_else (match_operand 2 "const_one_operand" "")
5648                       (const_string "ialu") (const_string "shift")))])
5650 ;; XXX UGH!
5651 (define_insn "ashldi3_v8plus"
5652   [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5653         (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5654                    (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5655    (clobber (match_scratch:SI 3 "=X,X,&h"))]
5656   "TARGET_V8PLUS"
5657   "* return output_v8plus_shift (operands, insn, \"sllx\");"
5658   [(set_attr "type" "multi")
5659    (set_attr "length" "5,5,6")])
5661 ;; Optimize (1LL<<x)-1
5662 ;; XXX this also needs to be fixed to handle equal subregs
5663 ;; XXX first before we could re-enable it.
5664 ;(define_insn ""
5665 ;  [(set (match_operand:DI 0 "register_operand" "=h")
5666 ;       (plus:DI (ashift:DI (const_int 1)
5667 ;                           (match_operand:SI 1 "arith_operand" "rI"))
5668 ;                (const_int -1)))]
5669 ;  "0 && TARGET_V8PLUS"
5671 ;  if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
5672 ;    return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5673 ;  return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5675 ;  [(set_attr "type" "multi")
5676 ;   (set_attr "length" "4")])
5678 (define_insn "*cmp_cc_ashift_1"
5679   [(set (reg:CC_NOOV 100)
5680         (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
5681                                     (const_int 1))
5682                          (const_int 0)))]
5683   ""
5684   "addcc\t%0, %0, %%g0"
5685   [(set_attr "type" "compare")])
5687 (define_insn "*cmp_cc_set_ashift_1"
5688   [(set (reg:CC_NOOV 100)
5689         (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
5690                                     (const_int 1))
5691                          (const_int 0)))
5692    (set (match_operand:SI 0 "register_operand" "=r")
5693         (ashift:SI (match_dup 1) (const_int 1)))]
5694   ""
5695   "addcc\t%1, %1, %0"
5696   [(set_attr "type" "compare")])
5698 (define_insn "ashrsi3"
5699   [(set (match_operand:SI 0 "register_operand" "=r")
5700         (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5701                      (match_operand:SI 2 "arith_operand" "rI")))]
5702   ""
5703   {
5704      if (GET_CODE (operands[2]) == CONST_INT)
5705        operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5706      return "sra\t%1, %2, %0";
5707   }
5708   [(set_attr "type" "shift")])
5710 (define_insn "*ashrsi3_extend"
5711   [(set (match_operand:DI 0 "register_operand" "=r")
5712         (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5713                                      (match_operand:SI 2 "arith_operand" "r"))))]
5714   "TARGET_ARCH64"
5715   "sra\t%1, %2, %0"
5716   [(set_attr "type" "shift")])
5718 ;; This handles the case as above, but with constant shift instead of
5719 ;; register. Combiner "simplifies" it for us a little bit though.
5720 (define_insn "*ashrsi3_extend2"
5721   [(set (match_operand:DI 0 "register_operand" "=r")
5722         (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
5723                                 (const_int 32))
5724                      (match_operand:SI 2 "small_int_operand" "I")))]
5725   "TARGET_ARCH64 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64"
5727   operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
5728   return "sra\t%1, %2, %0";
5730   [(set_attr "type" "shift")])
5732 (define_expand "ashrdi3"
5733   [(set (match_operand:DI 0 "register_operand" "=r")
5734         (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5735                      (match_operand:SI 2 "arith_operand" "rI")))]
5736   "TARGET_ARCH64 || TARGET_V8PLUS"
5738   if (! TARGET_ARCH64)
5739     {
5740       if (GET_CODE (operands[2]) == CONST_INT)
5741         FAIL;   /* prefer generic code in this case */
5742       emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
5743       DONE;
5744     }
5747 (define_insn "*ashrdi3_sp64"
5748   [(set (match_operand:DI 0 "register_operand" "=r")
5749         (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5750                      (match_operand:SI 2 "arith_operand" "rI")))]
5751   "TARGET_ARCH64"
5752   
5753   {
5754     if (GET_CODE (operands[2]) == CONST_INT)
5755       operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5756     return "srax\t%1, %2, %0";
5757   }
5758   [(set_attr "type" "shift")])
5760 ;; XXX
5761 (define_insn "ashrdi3_v8plus"
5762   [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5763         (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5764                      (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5765    (clobber (match_scratch:SI 3 "=X,X,&h"))]
5766   "TARGET_V8PLUS"
5767   "* return output_v8plus_shift (operands, insn, \"srax\");"
5768   [(set_attr "type" "multi")
5769    (set_attr "length" "5,5,6")])
5771 (define_insn "lshrsi3"
5772   [(set (match_operand:SI 0 "register_operand" "=r")
5773         (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5774                      (match_operand:SI 2 "arith_operand" "rI")))]
5775   ""
5776   {
5777     if (GET_CODE (operands[2]) == CONST_INT)
5778       operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5779     return "srl\t%1, %2, %0";
5780   }
5781   [(set_attr "type" "shift")])
5783 ;; This handles the case where
5784 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
5785 ;; but combiner "simplifies" it for us.
5786 (define_insn "*lshrsi3_extend"
5787   [(set (match_operand:DI 0 "register_operand" "=r")
5788         (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5789                            (match_operand:SI 2 "arith_operand" "r")) 0)
5790                 (match_operand 3 "const_int_operand" "")))]
5791   "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff"
5792   "srl\t%1, %2, %0"
5793   [(set_attr "type" "shift")])
5795 ;; This handles the case where
5796 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
5797 ;; but combiner "simplifies" it for us.
5798 (define_insn "*lshrsi3_extend2"
5799   [(set (match_operand:DI 0 "register_operand" "=r")
5800         (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
5801                          (match_operand 2 "small_int_operand" "I")
5802                          (const_int 32)))]
5803   "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
5805   operands[2] = GEN_INT (32 - INTVAL (operands[2]));
5806   return "srl\t%1, %2, %0";
5808   [(set_attr "type" "shift")])
5810 (define_expand "lshrdi3"
5811   [(set (match_operand:DI 0 "register_operand" "=r")
5812         (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5813                      (match_operand:SI 2 "arith_operand" "rI")))]
5814   "TARGET_ARCH64 || TARGET_V8PLUS"
5816   if (! TARGET_ARCH64)
5817     {
5818       if (GET_CODE (operands[2]) == CONST_INT)
5819         FAIL;
5820       emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
5821       DONE;
5822     }
5825 (define_insn "*lshrdi3_sp64"
5826   [(set (match_operand:DI 0 "register_operand" "=r")
5827         (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5828                      (match_operand:SI 2 "arith_operand" "rI")))]
5829   "TARGET_ARCH64"
5830   {
5831     if (GET_CODE (operands[2]) == CONST_INT)
5832       operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5833     return "srlx\t%1, %2, %0";
5834   }
5835   [(set_attr "type" "shift")])
5837 ;; XXX
5838 (define_insn "lshrdi3_v8plus"
5839   [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5840         (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5841                      (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5842    (clobber (match_scratch:SI 3 "=X,X,&h"))]
5843   "TARGET_V8PLUS"
5844   "* return output_v8plus_shift (operands, insn, \"srlx\");"
5845   [(set_attr "type" "multi")
5846    (set_attr "length" "5,5,6")])
5848 (define_insn ""
5849   [(set (match_operand:SI 0 "register_operand" "=r")
5850         (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5851                                              (const_int 32)) 4)
5852                      (match_operand:SI 2 "small_int_operand" "I")))]
5853   "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
5855   operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
5856   return "srax\t%1, %2, %0";
5858   [(set_attr "type" "shift")])
5860 (define_insn ""
5861   [(set (match_operand:SI 0 "register_operand" "=r")
5862         (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5863                                              (const_int 32)) 4)
5864                      (match_operand:SI 2 "small_int_operand" "I")))]
5865   "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
5867   operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
5868   return "srlx\t%1, %2, %0";
5870   [(set_attr "type" "shift")])
5872 (define_insn ""
5873   [(set (match_operand:SI 0 "register_operand" "=r")
5874         (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5875                                              (match_operand:SI 2 "small_int_operand" "I")) 4)
5876                      (match_operand:SI 3 "small_int_operand" "I")))]
5877   "TARGET_ARCH64
5878    && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
5879    && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
5880    && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
5882   operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
5884   return "srax\t%1, %2, %0";
5886   [(set_attr "type" "shift")])
5888 (define_insn ""
5889   [(set (match_operand:SI 0 "register_operand" "=r")
5890         (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5891                                              (match_operand:SI 2 "small_int_operand" "I")) 4)
5892                      (match_operand:SI 3 "small_int_operand" "I")))]
5893   "TARGET_ARCH64
5894    && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
5895    && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
5896    && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
5898   operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
5900   return "srlx\t%1, %2, %0";
5902   [(set_attr "type" "shift")])
5905 ;; Unconditional and other jump instructions.
5907 (define_insn "jump"
5908   [(set (pc) (label_ref (match_operand 0 "" "")))]
5909   ""
5910   "* return output_ubranch (operands[0], 0, insn);"
5911   [(set_attr "type" "uncond_branch")])
5913 (define_expand "tablejump"
5914   [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
5915               (use (label_ref (match_operand 1 "" "")))])]
5916   ""
5918   gcc_assert (GET_MODE (operands[0]) == CASE_VECTOR_MODE);
5920   /* In pic mode, our address differences are against the base of the
5921      table.  Add that base value back in; CSE ought to be able to combine
5922      the two address loads.  */
5923   if (flag_pic)
5924     {
5925       rtx tmp, tmp2;
5926       tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
5927       tmp2 = operands[0];
5928       if (CASE_VECTOR_MODE != Pmode)
5929         tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
5930       tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
5931       operands[0] = memory_address (Pmode, tmp);
5932     }
5935 (define_insn "*tablejump_sp32"
5936   [(set (pc) (match_operand:SI 0 "address_operand" "p"))
5937    (use (label_ref (match_operand 1 "" "")))]
5938   "! TARGET_ARCH64"
5939   "jmp\t%a0%#"
5940   [(set_attr "type" "uncond_branch")])
5942 (define_insn "*tablejump_sp64"
5943   [(set (pc) (match_operand:DI 0 "address_operand" "p"))
5944    (use (label_ref (match_operand 1 "" "")))]
5945   "TARGET_ARCH64"
5946   "jmp\t%a0%#"
5947   [(set_attr "type" "uncond_branch")])
5950 ;; Jump to subroutine instructions.
5952 (define_expand "call"
5953   ;; Note that this expression is not used for generating RTL.
5954   ;; All the RTL is generated explicitly below.
5955   [(call (match_operand 0 "call_operand" "")
5956          (match_operand 3 "" "i"))]
5957   ;; operands[2] is next_arg_register
5958   ;; operands[3] is struct_value_size_rtx.
5959   ""
5961   rtx fn_rtx;
5963   gcc_assert (MEM_P (operands[0]) && GET_MODE (operands[0]) == FUNCTION_MODE);
5965   gcc_assert (GET_CODE (operands[3]) == CONST_INT);
5967   if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
5968     {
5969       /* This is really a PIC sequence.  We want to represent
5970          it as a funny jump so its delay slots can be filled. 
5972          ??? But if this really *is* a CALL, will not it clobber the
5973          call-clobbered registers?  We lose this if it is a JUMP_INSN.
5974          Why cannot we have delay slots filled if it were a CALL?  */
5976       /* We accept negative sizes for untyped calls.  */
5977       if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
5978         emit_jump_insn
5979           (gen_rtx_PARALLEL
5980            (VOIDmode,
5981             gen_rtvec (3,
5982                        gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
5983                        operands[3],
5984                        gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
5985       else
5986         emit_jump_insn
5987           (gen_rtx_PARALLEL
5988            (VOIDmode,
5989             gen_rtvec (2,
5990                        gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
5991                        gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
5992       goto finish_call;
5993     }
5995   fn_rtx = operands[0];
5997   /* We accept negative sizes for untyped calls.  */
5998   if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
5999     sparc_emit_call_insn
6000       (gen_rtx_PARALLEL
6001        (VOIDmode,
6002         gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6003                    operands[3],
6004                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6005        XEXP (fn_rtx, 0));
6006   else
6007     sparc_emit_call_insn
6008       (gen_rtx_PARALLEL
6009        (VOIDmode,
6010         gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6011                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6012        XEXP (fn_rtx, 0));
6014  finish_call:
6016   DONE;
6019 ;; We can't use the same pattern for these two insns, because then registers
6020 ;; in the address may not be properly reloaded.
6022 (define_insn "*call_address_sp32"
6023   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6024          (match_operand 1 "" ""))
6025    (clobber (reg:SI 15))]
6026   ;;- Do not use operand 1 for most machines.
6027   "! TARGET_ARCH64"
6028   "call\t%a0, %1%#"
6029   [(set_attr "type" "call")])
6031 (define_insn "*call_symbolic_sp32"
6032   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6033          (match_operand 1 "" ""))
6034    (clobber (reg:SI 15))]
6035   ;;- Do not use operand 1 for most machines.
6036   "! TARGET_ARCH64"
6037   "call\t%a0, %1%#"
6038   [(set_attr "type" "call")])
6040 (define_insn "*call_address_sp64"
6041   [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
6042          (match_operand 1 "" ""))
6043    (clobber (reg:DI 15))]
6044   ;;- Do not use operand 1 for most machines.
6045   "TARGET_ARCH64"
6046   "call\t%a0, %1%#"
6047   [(set_attr "type" "call")])
6049 (define_insn "*call_symbolic_sp64"
6050   [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6051          (match_operand 1 "" ""))
6052    (clobber (reg:DI 15))]
6053   ;;- Do not use operand 1 for most machines.
6054   "TARGET_ARCH64"
6055   "call\t%a0, %1%#"
6056   [(set_attr "type" "call")])
6058 ;; This is a call that wants a structure value.
6059 ;; There is no such critter for v9 (??? we may need one anyway).
6060 (define_insn "*call_address_struct_value_sp32"
6061   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6062          (match_operand 1 "" ""))
6063    (match_operand 2 "immediate_operand" "")
6064    (clobber (reg:SI 15))]
6065   ;;- Do not use operand 1 for most machines.
6066   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6068   operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6069   return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6071   [(set_attr "type" "call_no_delay_slot")
6072    (set_attr "length" "3")])
6074 ;; This is a call that wants a structure value.
6075 ;; There is no such critter for v9 (??? we may need one anyway).
6076 (define_insn "*call_symbolic_struct_value_sp32"
6077   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6078          (match_operand 1 "" ""))
6079    (match_operand 2 "immediate_operand" "")
6080    (clobber (reg:SI 15))]
6081   ;;- Do not use operand 1 for most machines.
6082   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6084   operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6085   return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6087   [(set_attr "type" "call_no_delay_slot")
6088    (set_attr "length" "3")])
6090 ;; This is a call that may want a structure value.  This is used for
6091 ;; untyped_calls.
6092 (define_insn "*call_address_untyped_struct_value_sp32"
6093   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6094          (match_operand 1 "" ""))
6095    (match_operand 2 "immediate_operand" "")
6096    (clobber (reg:SI 15))]
6097   ;;- Do not use operand 1 for most machines.
6098   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6099   "call\t%a0, %1\n\t nop\n\tnop"
6100   [(set_attr "type" "call_no_delay_slot")
6101    (set_attr "length" "3")])
6103 ;; This is a call that may want a structure value.  This is used for
6104 ;; untyped_calls.
6105 (define_insn "*call_symbolic_untyped_struct_value_sp32"
6106   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6107          (match_operand 1 "" ""))
6108    (match_operand 2 "immediate_operand" "")
6109    (clobber (reg:SI 15))]
6110   ;;- Do not use operand 1 for most machines.
6111   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6112   "call\t%a0, %1\n\t nop\n\tnop"
6113   [(set_attr "type" "call_no_delay_slot")
6114    (set_attr "length" "3")])
6116 (define_expand "call_value"
6117   ;; Note that this expression is not used for generating RTL.
6118   ;; All the RTL is generated explicitly below.
6119   [(set (match_operand 0 "register_operand" "=rf")
6120         (call (match_operand 1 "" "")
6121               (match_operand 4 "" "")))]
6122   ;; operand 2 is stack_size_rtx
6123   ;; operand 3 is next_arg_register
6124   ""
6126   rtx fn_rtx;
6127   rtvec vec;
6129   gcc_assert (MEM_P (operands[1]) && GET_MODE (operands[1]) == FUNCTION_MODE);
6131   fn_rtx = operands[1];
6133   vec = gen_rtvec (2,
6134                    gen_rtx_SET (VOIDmode, operands[0],
6135                                 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
6136                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
6138   sparc_emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec), XEXP (fn_rtx, 0));
6140   DONE;
6143 (define_insn "*call_value_address_sp32"
6144   [(set (match_operand 0 "" "=rf")
6145         (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
6146               (match_operand 2 "" "")))
6147    (clobber (reg:SI 15))]
6148   ;;- Do not use operand 2 for most machines.
6149   "! TARGET_ARCH64"
6150   "call\t%a1, %2%#"
6151   [(set_attr "type" "call")])
6153 (define_insn "*call_value_symbolic_sp32"
6154   [(set (match_operand 0 "" "=rf")
6155         (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6156               (match_operand 2 "" "")))
6157    (clobber (reg:SI 15))]
6158   ;;- Do not use operand 2 for most machines.
6159   "! TARGET_ARCH64"
6160   "call\t%a1, %2%#"
6161   [(set_attr "type" "call")])
6163 (define_insn "*call_value_address_sp64"
6164   [(set (match_operand 0 "" "")
6165         (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
6166               (match_operand 2 "" "")))
6167    (clobber (reg:DI 15))]
6168   ;;- Do not use operand 2 for most machines.
6169   "TARGET_ARCH64"
6170   "call\t%a1, %2%#"
6171   [(set_attr "type" "call")])
6173 (define_insn "*call_value_symbolic_sp64"
6174   [(set (match_operand 0 "" "")
6175         (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6176               (match_operand 2 "" "")))
6177    (clobber (reg:DI 15))]
6178   ;;- Do not use operand 2 for most machines.
6179   "TARGET_ARCH64"
6180   "call\t%a1, %2%#"
6181   [(set_attr "type" "call")])
6183 (define_expand "untyped_call"
6184   [(parallel [(call (match_operand 0 "" "")
6185                     (const_int 0))
6186               (match_operand:BLK 1 "memory_operand" "")
6187               (match_operand 2 "" "")])]
6188   ""
6190   rtx valreg1 = gen_rtx_REG (DImode, 8);
6191   rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6192   rtx result = operands[1];
6194   /* Pass constm1 to indicate that it may expect a structure value, but
6195      we don't know what size it is.  */
6196   emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
6198   /* Save the function value registers.  */
6199   emit_move_insn (adjust_address (result, DImode, 0), valreg1);
6200   emit_move_insn (adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8),
6201                                   valreg2);
6203   /* The optimizer does not know that the call sets the function value
6204      registers we stored in the result block.  We avoid problems by
6205      claiming that all hard registers are used and clobbered at this
6206      point.  */
6207   emit_insn (gen_blockage ());
6209   DONE;
6212 ;;  Tail call instructions.
6214 (define_expand "sibcall"
6215   [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
6216               (return)])]
6217   ""
6218   "")
6220 (define_insn "*sibcall_symbolic_sp32"
6221   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6222          (match_operand 1 "" ""))
6223    (return)]
6224   "! TARGET_ARCH64"
6225   "* return output_sibcall(insn, operands[0]);"
6226   [(set_attr "type" "sibcall")])
6228 (define_insn "*sibcall_symbolic_sp64"
6229   [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6230          (match_operand 1 "" ""))
6231    (return)]
6232   "TARGET_ARCH64"
6233   "* return output_sibcall(insn, operands[0]);"
6234   [(set_attr "type" "sibcall")])
6236 (define_expand "sibcall_value"
6237   [(parallel [(set (match_operand 0 "register_operand" "=rf")
6238                 (call (match_operand 1 "" "") (const_int 0)))
6239               (return)])]
6240   ""
6241   "")
6243 (define_insn "*sibcall_value_symbolic_sp32"
6244   [(set (match_operand 0 "" "=rf")
6245         (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6246               (match_operand 2 "" "")))
6247    (return)]
6248   "! TARGET_ARCH64"
6249   "* return output_sibcall(insn, operands[1]);"
6250   [(set_attr "type" "sibcall")])
6252 (define_insn "*sibcall_value_symbolic_sp64"
6253   [(set (match_operand 0 "" "")
6254         (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6255               (match_operand 2 "" "")))
6256    (return)]
6257   "TARGET_ARCH64"
6258   "* return output_sibcall(insn, operands[1]);"
6259   [(set_attr "type" "sibcall")])
6262 ;; Special instructions.
6264 (define_expand "prologue"
6265   [(const_int 0)]
6266   ""
6268   sparc_expand_prologue ();
6269   DONE;
6272 ;; The "save register window" insn is modelled as follows so that the DWARF-2
6273 ;; backend automatically emits the required call frame debugging information
6274 ;; while it is parsing it.  Therefore, the pattern should not be modified
6275 ;; without first studying the impact of the changes on the debug info.
6276 ;; [(set (%fp) (%sp))
6277 ;;  (set (%sp) (unspec_volatile [(%sp) (-frame_size)] UNSPECV_SAVEW))
6278 ;;  (set (%i7) (%o7))]
6280 (define_insn "save_register_window<P:mode>"
6281   [(set (reg:P 30) (reg:P 14))
6282    (set (reg:P 14) (unspec_volatile:P [(reg:P 14)
6283                                        (match_operand:P 0 "arith_operand" "rI")] UNSPECV_SAVEW))
6284    (set (reg:P 31) (reg:P 15))]
6285   ""
6286   "save\t%%sp, %0, %%sp"
6287   [(set_attr "type" "savew")])
6289 (define_expand "epilogue"
6290   [(return)]
6291   ""
6293   sparc_expand_epilogue ();
6296 (define_expand "sibcall_epilogue"
6297   [(return)]
6298   ""
6300   sparc_expand_epilogue ();
6301   DONE;
6304 (define_expand "return"
6305   [(return)]
6306   "sparc_can_use_return_insn_p ()"
6307   "")
6309 (define_insn "*return_internal"
6310   [(return)]
6311   ""
6312   "* return output_return (insn);"
6313   [(set_attr "type" "return")
6314    (set (attr "length")
6315         (cond [(eq_attr "leaf_function" "true")
6316                  (if_then_else (eq_attr "empty_delay_slot" "true")
6317                                (const_int 2)
6318                                (const_int 1))
6319                (eq_attr "calls_eh_return" "true")
6320                  (if_then_else (eq_attr "delayed_branch" "true")
6321                                (if_then_else (eq_attr "isa" "v9")
6322                                              (const_int 2)
6323                                              (const_int 3))
6324                                (if_then_else (eq_attr "isa" "v9")
6325                                              (const_int 3)
6326                                              (const_int 4)))
6327                (eq_attr "empty_delay_slot" "true")
6328                  (if_then_else (eq_attr "delayed_branch" "true")
6329                                (const_int 2)
6330                                (const_int 3))
6331               ] (const_int 1)))])
6333 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
6334 ;; all of memory.  This blocks insns from being moved across this point.
6336 (define_insn "blockage"
6337   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
6338   ""
6339   ""
6340   [(set_attr "length" "0")])
6342 (define_expand "probe_stack"
6343   [(set (match_operand 0 "memory_operand" "") (const_int 0))]
6344   ""
6346   operands[0]
6347     = adjust_address (operands[0], GET_MODE (operands[0]), SPARC_STACK_BIAS);
6350 (define_insn "probe_stack_range<P:mode>"
6351   [(set (match_operand:P 0 "register_operand" "=r")
6352         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
6353                             (match_operand:P 2 "register_operand" "r")]
6354                             UNSPECV_PROBE_STACK_RANGE))]
6355   ""
6356   "* return output_probe_stack_range (operands[0], operands[2]);"
6357   [(set_attr "type" "multi")])
6359 ;; Prepare to return any type including a structure value.
6361 (define_expand "untyped_return"
6362   [(match_operand:BLK 0 "memory_operand" "")
6363    (match_operand 1 "" "")]
6364   ""
6366   rtx valreg1 = gen_rtx_REG (DImode, 24);
6367   rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6368   rtx result = operands[0];
6370   if (! TARGET_ARCH64)
6371     {
6372       rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
6373                                          ? 15 : 31));
6374       rtx value = gen_reg_rtx (SImode);
6376       /* Fetch the instruction where we will return to and see if it's an unimp
6377          instruction (the most significant 10 bits will be zero).  If so,
6378          update the return address to skip the unimp instruction.  */
6379       emit_move_insn (value,
6380                       gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
6381       emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
6382       emit_insn (gen_update_return (rtnreg, value));
6383     }
6385   /* Reload the function value registers.  */
6386   emit_move_insn (valreg1, adjust_address (result, DImode, 0));
6387   emit_move_insn (valreg2,
6388                   adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
6390   /* Put USE insns before the return.  */
6391   emit_use (valreg1);
6392   emit_use (valreg2);
6394   /* Construct the return.  */
6395   expand_naked_return ();
6397   DONE;
6400 ;; Adjust the return address conditionally. If the value of op1 is equal
6401 ;; to all zero then adjust the return address i.e. op0 = op0 + 4.
6402 ;; This is technically *half* the check required by the 32-bit SPARC
6403 ;; psABI. This check only ensures that an "unimp" insn was written by
6404 ;; the caller, but doesn't check to see if the expected size matches
6405 ;; (this is encoded in the 12 lower bits). This check is obsolete and
6406 ;; only used by the above code "untyped_return".
6408 (define_insn "update_return"
6409   [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
6410                (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
6411   "! TARGET_ARCH64"
6413   if (flag_delayed_branch)
6414     return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
6415   else
6416     return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
6418   [(set (attr "type") (const_string "multi"))
6419    (set (attr "length")
6420         (if_then_else (eq_attr "delayed_branch" "true")
6421                       (const_int 3)
6422                       (const_int 4)))])
6424 (define_insn "nop"
6425   [(const_int 0)]
6426   ""
6427   "nop")
6429 (define_expand "indirect_jump"
6430   [(set (pc) (match_operand 0 "address_operand" "p"))]
6431   ""
6432   "")
6434 (define_insn "*branch_sp32"
6435   [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
6436   "! TARGET_ARCH64"
6437  "jmp\t%a0%#"
6438  [(set_attr "type" "uncond_branch")])
6440 (define_insn "*branch_sp64"
6441   [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
6442   "TARGET_ARCH64"
6443   "jmp\t%a0%#"
6444   [(set_attr "type" "uncond_branch")])
6446 (define_expand "nonlocal_goto"
6447   [(match_operand:SI 0 "general_operand" "")
6448    (match_operand:SI 1 "general_operand" "")
6449    (match_operand:SI 2 "general_operand" "")
6450    (match_operand:SI 3 "" "")]
6451   ""
6453   rtx lab = operands[1];
6454   rtx stack = operands[2];
6455   rtx fp = operands[3];
6456   rtx labreg;
6458   /* Trap instruction to flush all the register windows.  */
6459   emit_insn (gen_flush_register_windows ());
6461   /* Load the fp value for the containing fn into %fp.  This is needed
6462      because STACK refers to %fp.  Note that virtual register instantiation
6463      fails if the virtual %fp isn't set from a register.  */
6464   if (GET_CODE (fp) != REG)
6465     fp = force_reg (Pmode, fp);
6466   emit_move_insn (virtual_stack_vars_rtx, fp);
6468   /* Find the containing function's current nonlocal goto handler,
6469      which will do any cleanups and then jump to the label.  */
6470   labreg = gen_rtx_REG (Pmode, 8);
6471   emit_move_insn (labreg, lab);
6473   /* Restore %fp from stack pointer value for containing function.
6474      The restore insn that follows will move this to %sp,
6475      and reload the appropriate value into %fp.  */
6476   emit_move_insn (hard_frame_pointer_rtx, stack);
6478   emit_use (stack_pointer_rtx);
6480   /* ??? The V9-specific version was disabled in rev 1.65.  */
6481   emit_jump_insn (gen_goto_handler_and_restore (labreg));
6482   emit_barrier ();
6483   DONE;
6486 ;; Special trap insn to flush register windows.
6487 (define_insn "flush_register_windows"
6488   [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
6489   ""
6490   { return TARGET_V9 ? "flushw" : "ta\t3"; }
6491   [(set_attr "type" "flushw")])
6493 (define_insn "goto_handler_and_restore"
6494   [(unspec_volatile [(match_operand 0 "register_operand" "=r")] UNSPECV_GOTO)]
6495   "GET_MODE (operands[0]) == Pmode"
6497   if (flag_delayed_branch)
6498     return "jmp\t%0\n\t restore";
6499   else
6500     return "mov\t%0,%%g1\n\trestore\n\tjmp\t%%g1\n\t nop";
6502   [(set (attr "type") (const_string "multi"))
6503    (set (attr "length")
6504         (if_then_else (eq_attr "delayed_branch" "true")
6505                       (const_int 2)
6506                       (const_int 4)))])
6508 ;; For __builtin_setjmp we need to flush register windows iff the function
6509 ;; calls alloca as well, because otherwise the register window might be
6510 ;; saved after %sp adjustment and thus setjmp would crash
6511 (define_expand "builtin_setjmp_setup"
6512   [(match_operand 0 "register_operand" "r")]
6513   ""
6515   emit_insn (gen_do_builtin_setjmp_setup ());
6516   DONE;
6519 (define_insn "do_builtin_setjmp_setup"
6520   [(unspec_volatile [(const_int 0)] UNSPECV_SETJMP)]
6521   ""
6523   if (!cfun->calls_alloca)
6524     return "";
6525   if (!TARGET_V9)
6526     return "ta\t3";
6527   fputs ("\tflushw\n", asm_out_file);
6528   if (flag_pic)
6529     fprintf (asm_out_file, "\tst%c\t%%l7, [%%sp+%d]\n",
6530              TARGET_ARCH64 ? 'x' : 'w',
6531              SPARC_STACK_BIAS + 7 * UNITS_PER_WORD);
6532   fprintf (asm_out_file, "\tst%c\t%%fp, [%%sp+%d]\n",
6533            TARGET_ARCH64 ? 'x' : 'w',
6534            SPARC_STACK_BIAS + 14 * UNITS_PER_WORD);
6535   fprintf (asm_out_file, "\tst%c\t%%i7, [%%sp+%d]\n",
6536            TARGET_ARCH64 ? 'x' : 'w',
6537            SPARC_STACK_BIAS + 15 * UNITS_PER_WORD);
6538   return "";
6540   [(set_attr "type" "multi")
6541    (set (attr "length")
6542         (cond [(eq_attr "calls_alloca" "false")
6543                  (const_int 0)
6544                (eq_attr "isa" "!v9")
6545                  (const_int 1)
6546                (eq_attr "pic" "true")
6547                  (const_int 4)] (const_int 3)))])
6549 ;; Pattern for use after a setjmp to store FP and the return register
6550 ;; into the stack area.
6552 (define_expand "setjmp"
6553   [(const_int 0)]
6554   ""
6556   rtx mem;
6557   
6558   mem = gen_rtx_MEM (Pmode,
6559                      plus_constant (stack_pointer_rtx,
6560                                     SPARC_STACK_BIAS + 14 * UNITS_PER_WORD));
6561   emit_insn (gen_rtx_SET (VOIDmode, mem, frame_pointer_rtx));
6563   mem = gen_rtx_MEM (Pmode,
6564                      plus_constant (stack_pointer_rtx,
6565                                     SPARC_STACK_BIAS + 15 * UNITS_PER_WORD));
6566   emit_insn (gen_rtx_SET (VOIDmode, mem, gen_rtx_REG (Pmode, 31)));
6567   DONE;
6570 ;; Special pattern for the FLUSH instruction.
6572 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
6573 ; of the define_insn otherwise missing a mode.  We make "flush", aka
6574 ; gen_flush, the default one since sparc_initialize_trampoline uses
6575 ; it on SImode mem values.
6577 (define_insn "flush"
6578   [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
6579   ""
6580   { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
6581   [(set_attr "type" "iflush")])
6583 (define_insn "flushdi"
6584   [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
6585   ""
6586   { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
6587   [(set_attr "type" "iflush")])
6590 ;; Find first set instructions.
6592 ;; The scan instruction searches from the most significant bit while ffs
6593 ;; searches from the least significant bit.  The bit index and treatment of
6594 ;; zero also differ.  It takes at least 7 instructions to get the proper
6595 ;; result.  Here is an obvious 8 instruction sequence.
6597 ;; XXX
6598 (define_insn "ffssi2"
6599   [(set (match_operand:SI 0 "register_operand" "=&r")
6600         (ffs:SI (match_operand:SI 1 "register_operand" "r")))
6601    (clobber (match_scratch:SI 2 "=&r"))]
6602   "TARGET_SPARCLITE || TARGET_SPARCLET"
6604   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";
6606   [(set_attr "type" "multi")
6607    (set_attr "length" "8")])
6609 ;; ??? This should be a define expand, so that the extra instruction have
6610 ;; a chance of being optimized away.
6612 ;; Disabled because none of the UltraSPARCs implement popc.  The HAL R1
6613 ;; does, but no one uses that and we don't have a switch for it.
6615 ;(define_insn "ffsdi2"
6616 ;  [(set (match_operand:DI 0 "register_operand" "=&r")
6617 ;       (ffs:DI (match_operand:DI 1 "register_operand" "r")))
6618 ;   (clobber (match_scratch:DI 2 "=&r"))]
6619 ;  "TARGET_ARCH64"
6620 ;  "neg\t%1, %2\;xnor\t%1, %2, %2\;popc\t%2, %0\;movzr\t%1, 0, %0"
6621 ;  [(set_attr "type" "multi")
6622 ;   (set_attr "length" "4")])
6626 ;; Peepholes go at the end.
6628 ;; Optimize consecutive loads or stores into ldd and std when possible.
6629 ;; The conditions in which we do this are very restricted and are 
6630 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
6632 (define_peephole2
6633   [(set (match_operand:SI 0 "memory_operand" "")
6634       (const_int 0))
6635    (set (match_operand:SI 1 "memory_operand" "")
6636       (const_int 0))]
6637   "TARGET_V9
6638    && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
6639   [(set (match_dup 0)
6640        (const_int 0))]
6641   "operands[0] = widen_memory_access (operands[0], DImode, 0);")
6643 (define_peephole2
6644   [(set (match_operand:SI 0 "memory_operand" "")
6645       (const_int 0))
6646    (set (match_operand:SI 1 "memory_operand" "")
6647       (const_int 0))]
6648   "TARGET_V9
6649    && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
6650   [(set (match_dup 1)
6651        (const_int 0))]
6652   "operands[1] = widen_memory_access (operands[1], DImode, 0);")
6654 (define_peephole2
6655   [(set (match_operand:SI 0 "register_operand" "")
6656         (match_operand:SI 1 "memory_operand" ""))
6657    (set (match_operand:SI 2 "register_operand" "")
6658         (match_operand:SI 3 "memory_operand" ""))]
6659   "registers_ok_for_ldd_peep (operands[0], operands[2]) 
6660    && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])" 
6661   [(set (match_dup 0)
6662         (match_dup 1))]
6663   "operands[1] = widen_memory_access (operands[1], DImode, 0);
6664    operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
6666 (define_peephole2
6667   [(set (match_operand:SI 0 "memory_operand" "")
6668         (match_operand:SI 1 "register_operand" ""))
6669    (set (match_operand:SI 2 "memory_operand" "")
6670         (match_operand:SI 3 "register_operand" ""))]
6671   "registers_ok_for_ldd_peep (operands[1], operands[3]) 
6672    && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
6673   [(set (match_dup 0)
6674         (match_dup 1))]
6675   "operands[0] = widen_memory_access (operands[0], DImode, 0);
6676    operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
6678 (define_peephole2
6679   [(set (match_operand:SF 0 "register_operand" "")
6680         (match_operand:SF 1 "memory_operand" ""))
6681    (set (match_operand:SF 2 "register_operand" "")
6682         (match_operand:SF 3 "memory_operand" ""))]
6683   "registers_ok_for_ldd_peep (operands[0], operands[2]) 
6684    && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
6685   [(set (match_dup 0)
6686         (match_dup 1))]
6687   "operands[1] = widen_memory_access (operands[1], DFmode, 0);
6688    operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
6690 (define_peephole2
6691   [(set (match_operand:SF 0 "memory_operand" "")
6692         (match_operand:SF 1 "register_operand" ""))
6693    (set (match_operand:SF 2 "memory_operand" "")
6694         (match_operand:SF 3 "register_operand" ""))]
6695   "registers_ok_for_ldd_peep (operands[1], operands[3]) 
6696   && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
6697   [(set (match_dup 0)
6698         (match_dup 1))]
6699   "operands[0] = widen_memory_access (operands[0], DFmode, 0);
6700    operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
6702 (define_peephole2
6703   [(set (match_operand:SI 0 "register_operand" "")
6704         (match_operand:SI 1 "memory_operand" ""))
6705    (set (match_operand:SI 2 "register_operand" "")
6706         (match_operand:SI 3 "memory_operand" ""))]
6707   "registers_ok_for_ldd_peep (operands[2], operands[0]) 
6708   && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
6709   [(set (match_dup 2)
6710         (match_dup 3))]
6711    "operands[3] = widen_memory_access (operands[3], DImode, 0);
6712     operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
6714 (define_peephole2
6715   [(set (match_operand:SI 0 "memory_operand" "")
6716         (match_operand:SI 1 "register_operand" ""))
6717    (set (match_operand:SI 2 "memory_operand" "")
6718         (match_operand:SI 3 "register_operand" ""))]
6719   "registers_ok_for_ldd_peep (operands[3], operands[1]) 
6720   && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)" 
6721   [(set (match_dup 2)
6722         (match_dup 3))]
6723   "operands[2] = widen_memory_access (operands[2], DImode, 0);
6724    operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
6725    ")
6727 (define_peephole2
6728   [(set (match_operand:SF 0 "register_operand" "")
6729         (match_operand:SF 1 "memory_operand" ""))
6730    (set (match_operand:SF 2 "register_operand" "")
6731         (match_operand:SF 3 "memory_operand" ""))]
6732   "registers_ok_for_ldd_peep (operands[2], operands[0]) 
6733   && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
6734   [(set (match_dup 2)
6735         (match_dup 3))]
6736   "operands[3] = widen_memory_access (operands[3], DFmode, 0);
6737    operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
6739 (define_peephole2
6740   [(set (match_operand:SF 0 "memory_operand" "")
6741         (match_operand:SF 1 "register_operand" ""))
6742    (set (match_operand:SF 2 "memory_operand" "")
6743         (match_operand:SF 3 "register_operand" ""))]
6744   "registers_ok_for_ldd_peep (operands[3], operands[1]) 
6745   && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
6746   [(set (match_dup 2)
6747         (match_dup 3))]
6748   "operands[2] = widen_memory_access (operands[2], DFmode, 0);
6749    operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
6751 ;; Optimize the case of following a reg-reg move with a test
6752 ;; of reg just moved.  Don't allow floating point regs for operand 0 or 1.
6753 ;; This can result from a float to fix conversion.
6755 (define_peephole2
6756   [(set (match_operand:SI 0 "register_operand" "")
6757         (match_operand:SI 1 "register_operand" ""))
6758    (set (reg:CC 100)
6759         (compare:CC (match_operand:SI 2 "register_operand" "")
6760                     (const_int 0)))]
6761   "(rtx_equal_p (operands[2], operands[0])
6762     || rtx_equal_p (operands[2], operands[1]))
6763     && ! SPARC_FP_REG_P (REGNO (operands[0]))
6764     && ! SPARC_FP_REG_P (REGNO (operands[1]))"
6765   [(parallel [(set (match_dup 0) (match_dup 1))
6766               (set (reg:CC 100)
6767                    (compare:CC (match_dup 1) (const_int 0)))])]
6768   "")
6770 (define_peephole2
6771   [(set (match_operand:DI 0 "register_operand" "")
6772         (match_operand:DI 1 "register_operand" ""))
6773    (set (reg:CCX 100)
6774         (compare:CCX (match_operand:DI 2 "register_operand" "")
6775                     (const_int 0)))]
6776   "TARGET_ARCH64
6777    && (rtx_equal_p (operands[2], operands[0])
6778        || rtx_equal_p (operands[2], operands[1]))
6779    && ! SPARC_FP_REG_P (REGNO (operands[0]))
6780    && ! SPARC_FP_REG_P (REGNO (operands[1]))"
6781   [(parallel [(set (match_dup 0) (match_dup 1))
6782               (set (reg:CCX 100)
6783                    (compare:CCX (match_dup 1) (const_int 0)))])]
6784   "")
6787 ;; Prefetch instructions.
6789 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
6790 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
6791 ;; ??? operations.  With DFA we might be able to model this, but it requires a lot of
6792 ;; ??? state.
6793 (define_expand "prefetch"
6794   [(match_operand 0 "address_operand" "")
6795    (match_operand 1 "const_int_operand" "")
6796    (match_operand 2 "const_int_operand" "")]
6797   "TARGET_V9"
6799   if (TARGET_ARCH64)
6800     emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
6801   else
6802     emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
6803   DONE;
6806 (define_insn "prefetch_64"
6807   [(prefetch (match_operand:DI 0 "address_operand" "p")
6808              (match_operand:DI 1 "const_int_operand" "n")
6809              (match_operand:DI 2 "const_int_operand" "n"))]
6810   ""
6812   static const char * const prefetch_instr[2][2] = {
6813     {
6814       "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
6815       "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
6816     },
6817     {
6818       "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
6819       "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
6820     }
6821   };
6822   int read_or_write = INTVAL (operands[1]);
6823   int locality = INTVAL (operands[2]);
6825   gcc_assert (read_or_write == 0 || read_or_write == 1);
6826   gcc_assert (locality >= 0 && locality < 4);
6827   return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
6829   [(set_attr "type" "load")])
6831 (define_insn "prefetch_32"
6832   [(prefetch (match_operand:SI 0 "address_operand" "p")
6833              (match_operand:SI 1 "const_int_operand" "n")
6834              (match_operand:SI 2 "const_int_operand" "n"))]
6835   ""
6837   static const char * const prefetch_instr[2][2] = {
6838     {
6839       "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
6840       "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
6841     },
6842     {
6843       "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
6844       "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
6845     }
6846   };
6847   int read_or_write = INTVAL (operands[1]);
6848   int locality = INTVAL (operands[2]);
6850   gcc_assert (read_or_write == 0 || read_or_write == 1);
6851   gcc_assert (locality >= 0 && locality < 4);
6852   return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
6854   [(set_attr "type" "load")])
6857 ;; Trap instructions.
6859 (define_insn "trap"
6860   [(trap_if (const_int 1) (const_int 5))]
6861   ""
6862   "ta\t5"
6863   [(set_attr "type" "trap")])
6865 (define_expand "ctrapsi4"
6866   [(trap_if (match_operator 0 "noov_compare_operator"
6867              [(match_operand:SI 1 "compare_operand" "")
6868               (match_operand:SI 2 "arith_operand" "")])
6869            (match_operand 3 ""))]
6870   ""
6871   "operands[1] = gen_compare_reg (operands[0]);
6872    if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
6873      FAIL;
6874    operands[2] = const0_rtx;")
6876 (define_expand "ctrapdi4"
6877   [(trap_if (match_operator 0 "noov_compare_operator"
6878              [(match_operand:DI 1 "compare_operand" "")
6879               (match_operand:DI 2 "arith_operand" "")])
6880            (match_operand 3 ""))]
6881   "TARGET_ARCH64"
6882   "operands[1] = gen_compare_reg (operands[0]);
6883    if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
6884      FAIL;
6885    operands[2] = const0_rtx;")
6888 (define_insn ""
6889   [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CC 100) (const_int 0)])
6890             (match_operand:SI 1 "arith_operand" "rM"))]
6891   ""
6893   if (TARGET_V9)
6894     return "t%C0\t%%icc, %1";
6895   else
6896     return "t%C0\t%1";
6898   [(set_attr "type" "trap")])
6900 (define_insn ""
6901   [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CCX 100) (const_int 0)])
6902             (match_operand:SI 1 "arith_operand" "rM"))]
6903   "TARGET_V9"
6904   "t%C0\t%%xcc, %1"
6905   [(set_attr "type" "trap")])
6908 ;; TLS support instructions.
6910 (define_insn "tgd_hi22"
6911   [(set (match_operand:SI 0 "register_operand" "=r")
6912         (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
6913                             UNSPEC_TLSGD)))]
6914   "TARGET_TLS"
6915   "sethi\\t%%tgd_hi22(%a1), %0")
6917 (define_insn "tgd_lo10"
6918   [(set (match_operand:SI 0 "register_operand" "=r")
6919         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
6920                    (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
6921                               UNSPEC_TLSGD)))]
6922   "TARGET_TLS"
6923   "add\\t%1, %%tgd_lo10(%a2), %0")
6925 (define_insn "tgd_add32"
6926   [(set (match_operand:SI 0 "register_operand" "=r")
6927         (plus:SI (match_operand:SI 1 "register_operand" "r")
6928                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")
6929                              (match_operand 3 "tgd_symbolic_operand" "")]
6930                             UNSPEC_TLSGD)))]
6931   "TARGET_TLS && TARGET_ARCH32"
6932   "add\\t%1, %2, %0, %%tgd_add(%a3)")
6934 (define_insn "tgd_add64"
6935   [(set (match_operand:DI 0 "register_operand" "=r")
6936         (plus:DI (match_operand:DI 1 "register_operand" "r")
6937                  (unspec:DI [(match_operand:SI 2 "register_operand" "r")
6938                              (match_operand 3 "tgd_symbolic_operand" "")]
6939                             UNSPEC_TLSGD)))]
6940   "TARGET_TLS && TARGET_ARCH64"
6941   "add\\t%1, %2, %0, %%tgd_add(%a3)")
6943 (define_insn "tgd_call32"
6944   [(set (match_operand 0 "register_operand" "=r")
6945         (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
6946                                   (match_operand 2 "tgd_symbolic_operand" "")]
6947                                  UNSPEC_TLSGD))
6948               (match_operand 3 "" "")))
6949    (clobber (reg:SI 15))]
6950   "TARGET_TLS && TARGET_ARCH32"
6951   "call\t%a1, %%tgd_call(%a2)%#"
6952   [(set_attr "type" "call")])
6954 (define_insn "tgd_call64"
6955   [(set (match_operand 0 "register_operand" "=r")
6956         (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
6957                                   (match_operand 2 "tgd_symbolic_operand" "")]
6958                                  UNSPEC_TLSGD))
6959               (match_operand 3 "" "")))
6960    (clobber (reg:DI 15))]
6961   "TARGET_TLS && TARGET_ARCH64"
6962   "call\t%a1, %%tgd_call(%a2)%#"
6963   [(set_attr "type" "call")])
6965 (define_insn "tldm_hi22"
6966   [(set (match_operand:SI 0 "register_operand" "=r")
6967         (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
6968   "TARGET_TLS"
6969   "sethi\\t%%tldm_hi22(%&), %0")
6971 (define_insn "tldm_lo10"
6972   [(set (match_operand:SI 0 "register_operand" "=r")
6973         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
6974                     (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
6975   "TARGET_TLS"
6976   "add\\t%1, %%tldm_lo10(%&), %0")
6978 (define_insn "tldm_add32"
6979   [(set (match_operand:SI 0 "register_operand" "=r")
6980         (plus:SI (match_operand:SI 1 "register_operand" "r")
6981                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
6982                             UNSPEC_TLSLDM)))]
6983   "TARGET_TLS && TARGET_ARCH32"
6984   "add\\t%1, %2, %0, %%tldm_add(%&)")
6986 (define_insn "tldm_add64"
6987   [(set (match_operand:DI 0 "register_operand" "=r")
6988         (plus:DI (match_operand:DI 1 "register_operand" "r")
6989                  (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
6990                             UNSPEC_TLSLDM)))]
6991   "TARGET_TLS && TARGET_ARCH64"
6992   "add\\t%1, %2, %0, %%tldm_add(%&)")
6994 (define_insn "tldm_call32"
6995   [(set (match_operand 0 "register_operand" "=r")
6996         (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
6997                                  UNSPEC_TLSLDM))
6998               (match_operand 2 "" "")))
6999    (clobber (reg:SI 15))]
7000   "TARGET_TLS && TARGET_ARCH32"
7001   "call\t%a1, %%tldm_call(%&)%#"
7002   [(set_attr "type" "call")])
7004 (define_insn "tldm_call64"
7005   [(set (match_operand 0 "register_operand" "=r")
7006         (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
7007                                  UNSPEC_TLSLDM))
7008               (match_operand 2 "" "")))
7009    (clobber (reg:DI 15))]
7010   "TARGET_TLS && TARGET_ARCH64"
7011   "call\t%a1, %%tldm_call(%&)%#"
7012   [(set_attr "type" "call")])
7014 (define_insn "tldo_hix22"
7015   [(set (match_operand:SI 0 "register_operand" "=r")
7016         (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
7017                             UNSPEC_TLSLDO)))]
7018   "TARGET_TLS"
7019   "sethi\\t%%tldo_hix22(%a1), %0")
7021 (define_insn "tldo_lox10"
7022   [(set (match_operand:SI 0 "register_operand" "=r")
7023         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7024                    (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
7025                               UNSPEC_TLSLDO)))]
7026   "TARGET_TLS"
7027   "xor\\t%1, %%tldo_lox10(%a2), %0")
7029 (define_insn "tldo_add32"
7030   [(set (match_operand:SI 0 "register_operand" "=r")
7031         (plus:SI (match_operand:SI 1 "register_operand" "r")
7032                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7033                              (match_operand 3 "tld_symbolic_operand" "")]
7034                             UNSPEC_TLSLDO)))]
7035   "TARGET_TLS && TARGET_ARCH32"
7036   "add\\t%1, %2, %0, %%tldo_add(%a3)")
7038 (define_insn "tldo_add64"
7039   [(set (match_operand:DI 0 "register_operand" "=r")
7040         (plus:DI (match_operand:DI 1 "register_operand" "r")
7041                  (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7042                              (match_operand 3 "tld_symbolic_operand" "")]
7043                             UNSPEC_TLSLDO)))]
7044   "TARGET_TLS && TARGET_ARCH64"
7045   "add\\t%1, %2, %0, %%tldo_add(%a3)")
7047 (define_insn "tie_hi22"
7048   [(set (match_operand:SI 0 "register_operand" "=r")
7049         (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
7050                             UNSPEC_TLSIE)))]
7051   "TARGET_TLS"
7052   "sethi\\t%%tie_hi22(%a1), %0")
7054 (define_insn "tie_lo10"
7055   [(set (match_operand:SI 0 "register_operand" "=r")
7056         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7057                    (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
7058                               UNSPEC_TLSIE)))]
7059   "TARGET_TLS"
7060   "add\\t%1, %%tie_lo10(%a2), %0")
7062 (define_insn "tie_ld32"
7063   [(set (match_operand:SI 0 "register_operand" "=r")
7064         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
7065                     (match_operand:SI 2 "register_operand" "r")
7066                     (match_operand 3 "tie_symbolic_operand" "")]
7067                    UNSPEC_TLSIE))]
7068   "TARGET_TLS && TARGET_ARCH32"
7069   "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
7070   [(set_attr "type" "load")])
7072 (define_insn "tie_ld64"
7073   [(set (match_operand:DI 0 "register_operand" "=r")
7074         (unspec:DI [(match_operand:DI 1 "register_operand" "r")
7075                     (match_operand:SI 2 "register_operand" "r")
7076                     (match_operand 3 "tie_symbolic_operand" "")]
7077                    UNSPEC_TLSIE))]
7078   "TARGET_TLS && TARGET_ARCH64"
7079   "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
7080   [(set_attr "type" "load")])
7082 (define_insn "tie_add32"
7083   [(set (match_operand:SI 0 "register_operand" "=r")
7084         (plus:SI (match_operand:SI 1 "register_operand" "r")
7085                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7086                              (match_operand 3 "tie_symbolic_operand" "")]
7087                             UNSPEC_TLSIE)))]
7088   "TARGET_SUN_TLS && TARGET_ARCH32"
7089   "add\\t%1, %2, %0, %%tie_add(%a3)")
7091 (define_insn "tie_add64"
7092   [(set (match_operand:DI 0 "register_operand" "=r")
7093         (plus:DI (match_operand:DI 1 "register_operand" "r")
7094                  (unspec:DI [(match_operand:DI 2 "register_operand" "r")
7095                              (match_operand 3 "tie_symbolic_operand" "")]
7096                             UNSPEC_TLSIE)))]
7097   "TARGET_SUN_TLS && TARGET_ARCH64"
7098   "add\\t%1, %2, %0, %%tie_add(%a3)")
7100 (define_insn "tle_hix22_sp32"
7101   [(set (match_operand:SI 0 "register_operand" "=r")
7102         (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
7103                             UNSPEC_TLSLE)))]
7104   "TARGET_TLS && TARGET_ARCH32"
7105   "sethi\\t%%tle_hix22(%a1), %0")
7107 (define_insn "tle_lox10_sp32"
7108   [(set (match_operand:SI 0 "register_operand" "=r")
7109         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7110                    (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
7111                               UNSPEC_TLSLE)))]
7112   "TARGET_TLS && TARGET_ARCH32"
7113   "xor\\t%1, %%tle_lox10(%a2), %0")
7115 (define_insn "tle_hix22_sp64"
7116   [(set (match_operand:DI 0 "register_operand" "=r")
7117         (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
7118                             UNSPEC_TLSLE)))]
7119   "TARGET_TLS && TARGET_ARCH64"
7120   "sethi\\t%%tle_hix22(%a1), %0")
7122 (define_insn "tle_lox10_sp64"
7123   [(set (match_operand:DI 0 "register_operand" "=r")
7124         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
7125                    (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
7126                               UNSPEC_TLSLE)))]
7127   "TARGET_TLS && TARGET_ARCH64"
7128   "xor\\t%1, %%tle_lox10(%a2), %0")
7130 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
7131 (define_insn "*tldo_ldub_sp32"
7132   [(set (match_operand:QI 0 "register_operand" "=r")
7133         (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7134                                      (match_operand 3 "tld_symbolic_operand" "")]
7135                                     UNSPEC_TLSLDO)
7136                          (match_operand:SI 1 "register_operand" "r"))))]
7137   "TARGET_TLS && TARGET_ARCH32"
7138   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7139   [(set_attr "type" "load")
7140    (set_attr "us3load_type" "3cycle")])
7142 (define_insn "*tldo_ldub1_sp32"
7143   [(set (match_operand:HI 0 "register_operand" "=r")
7144         (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7145                                                      (match_operand 3 "tld_symbolic_operand" "")]
7146                                                     UNSPEC_TLSLDO)
7147                                          (match_operand:SI 1 "register_operand" "r")))))]
7148   "TARGET_TLS && TARGET_ARCH32"
7149   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7150   [(set_attr "type" "load")
7151    (set_attr "us3load_type" "3cycle")])
7153 (define_insn "*tldo_ldub2_sp32"
7154   [(set (match_operand:SI 0 "register_operand" "=r")
7155         (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7156                                                      (match_operand 3 "tld_symbolic_operand" "")]
7157                                                     UNSPEC_TLSLDO)
7158                                          (match_operand:SI 1 "register_operand" "r")))))]
7159   "TARGET_TLS && TARGET_ARCH32"
7160   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7161   [(set_attr "type" "load")
7162    (set_attr "us3load_type" "3cycle")])
7164 (define_insn "*tldo_ldsb1_sp32"
7165   [(set (match_operand:HI 0 "register_operand" "=r")
7166         (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7167                                                      (match_operand 3 "tld_symbolic_operand" "")]
7168                                                     UNSPEC_TLSLDO)
7169                                          (match_operand:SI 1 "register_operand" "r")))))]
7170   "TARGET_TLS && TARGET_ARCH32"
7171   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7172   [(set_attr "type" "sload")
7173    (set_attr "us3load_type" "3cycle")])
7175 (define_insn "*tldo_ldsb2_sp32"
7176   [(set (match_operand:SI 0 "register_operand" "=r")
7177         (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7178                                                      (match_operand 3 "tld_symbolic_operand" "")]
7179                                                     UNSPEC_TLSLDO)
7180                                          (match_operand:SI 1 "register_operand" "r")))))]
7181   "TARGET_TLS && TARGET_ARCH32"
7182   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7183   [(set_attr "type" "sload")
7184    (set_attr "us3load_type" "3cycle")])
7186 (define_insn "*tldo_ldub_sp64"
7187   [(set (match_operand:QI 0 "register_operand" "=r")
7188         (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7189                                      (match_operand 3 "tld_symbolic_operand" "")]
7190                                     UNSPEC_TLSLDO)
7191                          (match_operand:DI 1 "register_operand" "r"))))]
7192   "TARGET_TLS && TARGET_ARCH64"
7193   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7194   [(set_attr "type" "load")
7195    (set_attr "us3load_type" "3cycle")])
7197 (define_insn "*tldo_ldub1_sp64"
7198   [(set (match_operand:HI 0 "register_operand" "=r")
7199         (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7200                                                      (match_operand 3 "tld_symbolic_operand" "")]
7201                                                     UNSPEC_TLSLDO)
7202                                          (match_operand:DI 1 "register_operand" "r")))))]
7203   "TARGET_TLS && TARGET_ARCH64"
7204   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7205   [(set_attr "type" "load")
7206    (set_attr "us3load_type" "3cycle")])
7208 (define_insn "*tldo_ldub2_sp64"
7209   [(set (match_operand:SI 0 "register_operand" "=r")
7210         (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7211                                                      (match_operand 3 "tld_symbolic_operand" "")]
7212                                                     UNSPEC_TLSLDO)
7213                                          (match_operand:DI 1 "register_operand" "r")))))]
7214   "TARGET_TLS && TARGET_ARCH64"
7215   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7216   [(set_attr "type" "load")
7217    (set_attr "us3load_type" "3cycle")])
7219 (define_insn "*tldo_ldub3_sp64"
7220   [(set (match_operand:DI 0 "register_operand" "=r")
7221         (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7222                                                      (match_operand 3 "tld_symbolic_operand" "")]
7223                                                     UNSPEC_TLSLDO)
7224                                          (match_operand:DI 1 "register_operand" "r")))))]
7225   "TARGET_TLS && TARGET_ARCH64"
7226   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7227   [(set_attr "type" "load")
7228    (set_attr "us3load_type" "3cycle")])
7230 (define_insn "*tldo_ldsb1_sp64"
7231   [(set (match_operand:HI 0 "register_operand" "=r")
7232         (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7233                                                      (match_operand 3 "tld_symbolic_operand" "")]
7234                                                     UNSPEC_TLSLDO)
7235                                          (match_operand:DI 1 "register_operand" "r")))))]
7236   "TARGET_TLS && TARGET_ARCH64"
7237   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7238   [(set_attr "type" "sload")
7239    (set_attr "us3load_type" "3cycle")])
7241 (define_insn "*tldo_ldsb2_sp64"
7242   [(set (match_operand:SI 0 "register_operand" "=r")
7243         (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7244                                                      (match_operand 3 "tld_symbolic_operand" "")]
7245                                                     UNSPEC_TLSLDO)
7246                                          (match_operand:DI 1 "register_operand" "r")))))]
7247   "TARGET_TLS && TARGET_ARCH64"
7248   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7249   [(set_attr "type" "sload")
7250    (set_attr "us3load_type" "3cycle")])
7252 (define_insn "*tldo_ldsb3_sp64"
7253   [(set (match_operand:DI 0 "register_operand" "=r")
7254         (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7255                                                      (match_operand 3 "tld_symbolic_operand" "")]
7256                                                     UNSPEC_TLSLDO)
7257                                          (match_operand:DI 1 "register_operand" "r")))))]
7258   "TARGET_TLS && TARGET_ARCH64"
7259   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7260   [(set_attr "type" "sload")
7261    (set_attr "us3load_type" "3cycle")])
7263 (define_insn "*tldo_lduh_sp32"
7264   [(set (match_operand:HI 0 "register_operand" "=r")
7265         (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7266                                      (match_operand 3 "tld_symbolic_operand" "")]
7267                                     UNSPEC_TLSLDO)
7268                          (match_operand:SI 1 "register_operand" "r"))))]
7269   "TARGET_TLS && TARGET_ARCH32"
7270   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7271   [(set_attr "type" "load")
7272    (set_attr "us3load_type" "3cycle")])
7274 (define_insn "*tldo_lduh1_sp32"
7275   [(set (match_operand:SI 0 "register_operand" "=r")
7276         (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7277                                                      (match_operand 3 "tld_symbolic_operand" "")]
7278                                                     UNSPEC_TLSLDO)
7279                                          (match_operand:SI 1 "register_operand" "r")))))]
7280   "TARGET_TLS && TARGET_ARCH32"
7281   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7282   [(set_attr "type" "load")
7283    (set_attr "us3load_type" "3cycle")])
7285 (define_insn "*tldo_ldsh1_sp32"
7286   [(set (match_operand:SI 0 "register_operand" "=r")
7287         (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7288                                                      (match_operand 3 "tld_symbolic_operand" "")]
7289                                                     UNSPEC_TLSLDO)
7290                                          (match_operand:SI 1 "register_operand" "r")))))]
7291   "TARGET_TLS && TARGET_ARCH32"
7292   "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7293   [(set_attr "type" "sload")
7294    (set_attr "us3load_type" "3cycle")])
7296 (define_insn "*tldo_lduh_sp64"
7297   [(set (match_operand:HI 0 "register_operand" "=r")
7298         (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7299                                      (match_operand 3 "tld_symbolic_operand" "")]
7300                                     UNSPEC_TLSLDO)
7301                          (match_operand:DI 1 "register_operand" "r"))))]
7302   "TARGET_TLS && TARGET_ARCH64"
7303   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7304   [(set_attr "type" "load")
7305    (set_attr "us3load_type" "3cycle")])
7307 (define_insn "*tldo_lduh1_sp64"
7308   [(set (match_operand:SI 0 "register_operand" "=r")
7309         (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7310                                                      (match_operand 3 "tld_symbolic_operand" "")]
7311                                                     UNSPEC_TLSLDO)
7312                                          (match_operand:DI 1 "register_operand" "r")))))]
7313   "TARGET_TLS && TARGET_ARCH64"
7314   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7315   [(set_attr "type" "load")
7316    (set_attr "us3load_type" "3cycle")])
7318 (define_insn "*tldo_lduh2_sp64"
7319   [(set (match_operand:DI 0 "register_operand" "=r")
7320         (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7321                                                      (match_operand 3 "tld_symbolic_operand" "")]
7322                                                     UNSPEC_TLSLDO)
7323                                          (match_operand:DI 1 "register_operand" "r")))))]
7324   "TARGET_TLS && TARGET_ARCH64"
7325   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7326   [(set_attr "type" "load")
7327    (set_attr "us3load_type" "3cycle")])
7329 (define_insn "*tldo_ldsh1_sp64"
7330   [(set (match_operand:SI 0 "register_operand" "=r")
7331         (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7332                                                      (match_operand 3 "tld_symbolic_operand" "")]
7333                                                     UNSPEC_TLSLDO)
7334                                          (match_operand:DI 1 "register_operand" "r")))))]
7335   "TARGET_TLS && TARGET_ARCH64"
7336   "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7337   [(set_attr "type" "sload")
7338    (set_attr "us3load_type" "3cycle")])
7340 (define_insn "*tldo_ldsh2_sp64"
7341   [(set (match_operand:DI 0 "register_operand" "=r")
7342         (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7343                                                      (match_operand 3 "tld_symbolic_operand" "")]
7344                                                     UNSPEC_TLSLDO)
7345                                          (match_operand:DI 1 "register_operand" "r")))))]
7346   "TARGET_TLS && TARGET_ARCH64"
7347   "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7348   [(set_attr "type" "sload")
7349    (set_attr "us3load_type" "3cycle")])
7351 (define_insn "*tldo_lduw_sp32"
7352   [(set (match_operand:SI 0 "register_operand" "=r")
7353         (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7354                                      (match_operand 3 "tld_symbolic_operand" "")]
7355                                     UNSPEC_TLSLDO)
7356                          (match_operand:SI 1 "register_operand" "r"))))]
7357   "TARGET_TLS && TARGET_ARCH32"
7358   "ld\t[%1 + %2], %0, %%tldo_add(%3)"
7359   [(set_attr "type" "load")])
7361 (define_insn "*tldo_lduw_sp64"
7362   [(set (match_operand:SI 0 "register_operand" "=r")
7363         (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7364                                      (match_operand 3 "tld_symbolic_operand" "")]
7365                                     UNSPEC_TLSLDO)
7366                          (match_operand:DI 1 "register_operand" "r"))))]
7367   "TARGET_TLS && TARGET_ARCH64"
7368   "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7369   [(set_attr "type" "load")])
7371 (define_insn "*tldo_lduw1_sp64"
7372   [(set (match_operand:DI 0 "register_operand" "=r")
7373         (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7374                                                      (match_operand 3 "tld_symbolic_operand" "")]
7375                                                     UNSPEC_TLSLDO)
7376                                          (match_operand:DI 1 "register_operand" "r")))))]
7377   "TARGET_TLS && TARGET_ARCH64"
7378   "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7379   [(set_attr "type" "load")])
7381 (define_insn "*tldo_ldsw1_sp64"
7382   [(set (match_operand:DI 0 "register_operand" "=r")
7383         (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7384                                                      (match_operand 3 "tld_symbolic_operand" "")]
7385                                                     UNSPEC_TLSLDO)
7386                                          (match_operand:DI 1 "register_operand" "r")))))]
7387   "TARGET_TLS && TARGET_ARCH64"
7388   "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
7389   [(set_attr "type" "sload")
7390    (set_attr "us3load_type" "3cycle")])
7392 (define_insn "*tldo_ldx_sp64"
7393   [(set (match_operand:DI 0 "register_operand" "=r")
7394         (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7395                                      (match_operand 3 "tld_symbolic_operand" "")]
7396                                     UNSPEC_TLSLDO)
7397                          (match_operand:DI 1 "register_operand" "r"))))]
7398   "TARGET_TLS && TARGET_ARCH64"
7399   "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
7400   [(set_attr "type" "load")])
7402 (define_insn "*tldo_stb_sp32"
7403   [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7404                                      (match_operand 3 "tld_symbolic_operand" "")]
7405                                     UNSPEC_TLSLDO)
7406                          (match_operand:SI 1 "register_operand" "r")))
7407         (match_operand:QI 0 "register_operand" "=r"))]
7408   "TARGET_TLS && TARGET_ARCH32"
7409   "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7410   [(set_attr "type" "store")])
7412 (define_insn "*tldo_stb_sp64"
7413   [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7414                                      (match_operand 3 "tld_symbolic_operand" "")]
7415                                     UNSPEC_TLSLDO)
7416                          (match_operand:DI 1 "register_operand" "r")))
7417         (match_operand:QI 0 "register_operand" "=r"))]
7418   "TARGET_TLS && TARGET_ARCH64"
7419   "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7420   [(set_attr "type" "store")])
7422 (define_insn "*tldo_sth_sp32"
7423   [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7424                                      (match_operand 3 "tld_symbolic_operand" "")]
7425                                     UNSPEC_TLSLDO)
7426                          (match_operand:SI 1 "register_operand" "r")))
7427         (match_operand:HI 0 "register_operand" "=r"))]
7428   "TARGET_TLS && TARGET_ARCH32"
7429   "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7430   [(set_attr "type" "store")])
7432 (define_insn "*tldo_sth_sp64"
7433   [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7434                                      (match_operand 3 "tld_symbolic_operand" "")]
7435                                     UNSPEC_TLSLDO)
7436                          (match_operand:DI 1 "register_operand" "r")))
7437         (match_operand:HI 0 "register_operand" "=r"))]
7438   "TARGET_TLS && TARGET_ARCH64"
7439   "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7440   [(set_attr "type" "store")])
7442 (define_insn "*tldo_stw_sp32"
7443   [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7444                                      (match_operand 3 "tld_symbolic_operand" "")]
7445                                     UNSPEC_TLSLDO)
7446                          (match_operand:SI 1 "register_operand" "r")))
7447         (match_operand:SI 0 "register_operand" "=r"))]
7448   "TARGET_TLS && TARGET_ARCH32"
7449   "st\t%0, [%1 + %2], %%tldo_add(%3)"
7450   [(set_attr "type" "store")])
7452 (define_insn "*tldo_stw_sp64"
7453   [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7454                                      (match_operand 3 "tld_symbolic_operand" "")]
7455                                     UNSPEC_TLSLDO)
7456                          (match_operand:DI 1 "register_operand" "r")))
7457         (match_operand:SI 0 "register_operand" "=r"))]
7458   "TARGET_TLS && TARGET_ARCH64"
7459   "stw\t%0, [%1 + %2], %%tldo_add(%3)"
7460   [(set_attr "type" "store")])
7462 (define_insn "*tldo_stx_sp64"
7463   [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7464                                      (match_operand 3 "tld_symbolic_operand" "")]
7465                                     UNSPEC_TLSLDO)
7466                          (match_operand:DI 1 "register_operand" "r")))
7467         (match_operand:DI 0 "register_operand" "=r"))]
7468   "TARGET_TLS && TARGET_ARCH64"
7469   "stx\t%0, [%1 + %2], %%tldo_add(%3)"
7470   [(set_attr "type" "store")])
7473 ;; Stack protector instructions.
7475 (define_expand "stack_protect_set"
7476   [(match_operand 0 "memory_operand" "")
7477    (match_operand 1 "memory_operand" "")]
7478   ""
7480 #ifdef TARGET_THREAD_SSP_OFFSET
7481   rtx tlsreg = gen_rtx_REG (Pmode, 7);
7482   rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7483   operands[1] = gen_rtx_MEM (Pmode, addr);
7484 #endif
7485   if (TARGET_ARCH64)
7486     emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
7487   else
7488     emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
7489   DONE;
7492 (define_insn "stack_protect_setsi"
7493   [(set (match_operand:SI 0 "memory_operand" "=m")
7494         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7495    (set (match_scratch:SI 2 "=&r") (const_int 0))]
7496   "TARGET_ARCH32"
7497   "ld\t%1, %2\;st\t%2, %0\;mov\t0, %2"
7498   [(set_attr "type" "multi")
7499    (set_attr "length" "3")])
7501 (define_insn "stack_protect_setdi"
7502   [(set (match_operand:DI 0 "memory_operand" "=m")
7503         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7504    (set (match_scratch:DI 2 "=&r") (const_int 0))]
7505   "TARGET_ARCH64"
7506   "ldx\t%1, %2\;stx\t%2, %0\;mov\t0, %2"
7507   [(set_attr "type" "multi")
7508    (set_attr "length" "3")])
7510 (define_expand "stack_protect_test"
7511   [(match_operand 0 "memory_operand" "")
7512    (match_operand 1 "memory_operand" "")
7513    (match_operand 2 "" "")]
7514   ""
7516   rtx result, test;
7517 #ifdef TARGET_THREAD_SSP_OFFSET
7518   rtx tlsreg = gen_rtx_REG (Pmode, 7);
7519   rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7520   operands[1] = gen_rtx_MEM (Pmode, addr);
7521 #endif
7522   if (TARGET_ARCH64)
7523     {
7524       result = gen_reg_rtx (Pmode);
7525       emit_insn (gen_stack_protect_testdi (result, operands[0], operands[1]));
7526       test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7527       emit_jump_insn (gen_cbranchdi4 (test, result, const0_rtx, operands[2]));
7528     }
7529   else
7530     {
7531       emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
7532       result = gen_rtx_REG (CCmode, SPARC_ICC_REG);
7533       test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7534       emit_jump_insn (gen_cbranchcc4 (test, result, const0_rtx, operands[2]));
7535     }
7536   DONE;
7539 (define_insn "stack_protect_testsi"
7540   [(set (reg:CC 100)
7541         (unspec:CC [(match_operand:SI 0 "memory_operand" "m")
7542                     (match_operand:SI 1 "memory_operand" "m")]
7543                    UNSPEC_SP_TEST))
7544    (set (match_scratch:SI 3 "=r") (const_int 0))
7545    (clobber (match_scratch:SI 2 "=&r"))]
7546   "TARGET_ARCH32"
7547   "ld\t%0, %2\;ld\t%1, %3\;xorcc\t%2, %3, %2\;mov\t0, %3"
7548   [(set_attr "type" "multi")
7549    (set_attr "length" "4")])
7551 (define_insn "stack_protect_testdi"
7552   [(set (match_operand:DI 0 "register_operand" "=&r")
7553         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
7554                     (match_operand:DI 2 "memory_operand" "m")]
7555                    UNSPEC_SP_TEST))
7556    (set (match_scratch:DI 3 "=r") (const_int 0))]
7557   "TARGET_ARCH64"
7558   "ldx\t%1, %0\;ldx\t%2, %3\;xor\t%0, %3, %0\;mov\t0, %3"
7559   [(set_attr "type" "multi")
7560    (set_attr "length" "4")])
7563 ;; Vector instructions.
7565 (define_insn "addv2si3"
7566   [(set (match_operand:V2SI 0 "register_operand" "=e")
7567         (plus:V2SI (match_operand:V2SI 1 "register_operand" "e")
7568                    (match_operand:V2SI 2 "register_operand" "e")))]
7569   "TARGET_VIS"
7570   "fpadd32\t%1, %2, %0"
7571   [(set_attr "type" "fga")
7572    (set_attr "fptype" "double")])
7574 (define_insn "addv4hi3"
7575   [(set (match_operand:V4HI 0 "register_operand" "=e")
7576          (plus:V4HI (match_operand:V4HI 1 "register_operand" "e")
7577                     (match_operand:V4HI 2 "register_operand" "e")))]
7578   "TARGET_VIS"
7579   "fpadd16\t%1, %2, %0"
7580   [(set_attr "type" "fga")
7581    (set_attr "fptype" "double")])
7583 ;; fpadd32s is emitted by the addsi3 pattern.
7585 (define_insn "addv2hi3"
7586   [(set (match_operand:V2HI 0 "register_operand" "=f")
7587         (plus:V2HI (match_operand:V2HI 1 "register_operand" "f")
7588                    (match_operand:V2HI 2 "register_operand" "f")))]
7589   "TARGET_VIS"
7590   "fpadd16s\t%1, %2, %0"
7591   [(set_attr "type" "fga")
7592    (set_attr "fptype" "single")])
7594 (define_insn "subv2si3"
7595   [(set (match_operand:V2SI 0 "register_operand" "=e")
7596         (minus:V2SI (match_operand:V2SI 1 "register_operand" "e")
7597                     (match_operand:V2SI 2 "register_operand" "e")))]
7598   "TARGET_VIS"
7599   "fpsub32\t%1, %2, %0"
7600   [(set_attr "type" "fga")
7601    (set_attr "fptype" "double")])
7603 (define_insn "subv4hi3"
7604   [(set (match_operand:V4HI 0 "register_operand" "=e")
7605         (minus:V4HI (match_operand:V4HI 1 "register_operand" "e")
7606                     (match_operand:V4HI 2 "register_operand" "e")))]
7607   "TARGET_VIS"
7608   "fpsub16\t%1, %2, %0"
7609   [(set_attr "type" "fga")
7610    (set_attr "fptype" "double")])
7612 ;; fpsub32s is emitted by the subsi3 pattern.
7614 (define_insn "subv2hi3"
7615   [(set (match_operand:V2HI 0 "register_operand" "=f")
7616         (minus:V2HI (match_operand:V2HI 1 "register_operand" "f")
7617                     (match_operand:V2HI 2 "register_operand" "f")))]
7618   "TARGET_VIS"
7619   "fpsub16s\t%1, %2, %0"
7620   [(set_attr "type" "fga")
7621    (set_attr "fptype" "single")])
7623 ;; All other logical instructions have integer equivalents so they
7624 ;; are defined together.
7626 ;; (ior (not (op1)) (not (op2))) is the canonical form of NAND.
7628 (define_insn "*nand<V64:mode>_vis"
7629   [(set (match_operand:V64 0 "register_operand" "=e")
7630         (ior:V64 (not:V64 (match_operand:V64 1 "register_operand" "e"))
7631                  (not:V64 (match_operand:V64 2 "register_operand" "e"))))]
7632   "TARGET_VIS"
7633   "fnand\t%1, %2, %0"
7634   [(set_attr "type" "fga")
7635    (set_attr "fptype" "double")])
7637 (define_insn "*nand<V32:mode>_vis"
7638   [(set (match_operand:V32 0 "register_operand" "=f")
7639          (ior:V32 (not:V32 (match_operand:V32 1 "register_operand" "f"))
7640                   (not:V32 (match_operand:V32 2 "register_operand" "f"))))]
7641   "TARGET_VIS"
7642   "fnands\t%1, %2, %0"
7643   [(set_attr "type" "fga")
7644    (set_attr "fptype" "single")])
7646 ;; Hard to generate VIS instructions.  We have builtins for these.
7648 (define_insn "fpack16_vis"
7649   [(set (match_operand:V4QI 0 "register_operand" "=f")
7650         (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e")]
7651                       UNSPEC_FPACK16))]
7652   "TARGET_VIS"
7653   "fpack16\t%1, %0"
7654   [(set_attr "type" "fga")
7655    (set_attr "fptype" "double")])
7657 (define_insn "fpackfix_vis"
7658   [(set (match_operand:V2HI 0 "register_operand" "=f")
7659         (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e")]
7660                       UNSPEC_FPACKFIX))]
7661   "TARGET_VIS"
7662   "fpackfix\t%1, %0"
7663   [(set_attr "type" "fga")
7664    (set_attr "fptype" "double")])
7666 (define_insn "fpack32_vis"
7667   [(set (match_operand:V8QI 0 "register_operand" "=e")
7668         (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e")
7669                       (match_operand:V8QI 2 "register_operand" "e")]
7670                      UNSPEC_FPACK32))]
7671   "TARGET_VIS"
7672   "fpack32\t%1, %2, %0"
7673   [(set_attr "type" "fga")
7674    (set_attr "fptype" "double")])
7676 (define_insn "fexpand_vis"
7677   [(set (match_operand:V4HI 0 "register_operand" "=e")
7678         (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")]
7679          UNSPEC_FEXPAND))]
7680  "TARGET_VIS"
7681  "fexpand\t%1, %0"
7682  [(set_attr "type" "fga")
7683   (set_attr "fptype" "double")])
7685 ;; It may be possible to describe this operation as (1 indexed):
7686 ;; (vec_select (vec_duplicate (vec_duplicate (vec_concat 1 2)))
7687 ;;  1,5,10,14,19,23,28,32)
7688 ;; Note that (vec_merge:V8QI [(V4QI) (V4QI)] (10101010 = 170) doesn't work
7689 ;; because vec_merge expects all the operands to be of the same type.
7690 (define_insn "fpmerge_vis"
7691   [(set (match_operand:V8QI 0 "register_operand" "=e")
7692         (unspec:V8QI [(match_operand:V4QI 1 "register_operand" "f")
7693                       (match_operand:V4QI 2 "register_operand" "f")]
7694          UNSPEC_FPMERGE))]
7695  "TARGET_VIS"
7696  "fpmerge\t%1, %2, %0"
7697  [(set_attr "type" "fga")
7698   (set_attr "fptype" "double")])
7700 ;; Partitioned multiply instructions
7701 (define_insn "fmul8x16_vis"
7702   [(set (match_operand:V4HI 0 "register_operand" "=e")
7703         (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
7704                    (match_operand:V4HI 2 "register_operand" "e")))]
7705   "TARGET_VIS"
7706   "fmul8x16\t%1, %2, %0"
7707   [(set_attr "type" "fpmul")
7708    (set_attr "fptype" "double")])
7710 ;; Only one of the following two insns can be a multiply.
7711 (define_insn "fmul8x16au_vis"
7712   [(set (match_operand:V4HI 0 "register_operand" "=e")
7713         (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
7714                    (match_operand:V2HI 2 "register_operand" "f")))]
7715   "TARGET_VIS"
7716   "fmul8x16au\t%1, %2, %0"
7717   [(set_attr "type" "fpmul")
7718    (set_attr "fptype" "double")])
7720 (define_insn "fmul8x16al_vis"
7721   [(set (match_operand:V4HI 0 "register_operand" "=e")
7722         (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
7723                       (match_operand:V2HI 2 "register_operand" "f")]
7724          UNSPEC_MUL16AL))]
7725   "TARGET_VIS"
7726   "fmul8x16al\t%1, %2, %0"
7727   [(set_attr "type" "fpmul")
7728    (set_attr "fptype" "double")])
7730 ;; Only one of the following two insns can be a multiply.
7731 (define_insn "fmul8sux16_vis"
7732   [(set (match_operand:V4HI 0 "register_operand" "=e")
7733         (mult:V4HI (match_operand:V8QI 1 "register_operand" "e")
7734                    (match_operand:V4HI 2 "register_operand" "e")))]
7735   "TARGET_VIS"
7736   "fmul8sux16\t%1, %2, %0"
7737   [(set_attr "type" "fpmul")
7738    (set_attr "fptype" "double")])
7740 (define_insn "fmul8ulx16_vis"
7741   [(set (match_operand:V4HI 0 "register_operand" "=e")
7742         (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
7743                       (match_operand:V4HI 2 "register_operand" "e")]
7744          UNSPEC_MUL8UL))]
7745   "TARGET_VIS"
7746   "fmul8ulx16\t%1, %2, %0"
7747   [(set_attr "type" "fpmul")
7748    (set_attr "fptype" "double")])
7750 ;; Only one of the following two insns can be a multiply.
7751 (define_insn "fmuld8sux16_vis"
7752   [(set (match_operand:V2SI 0 "register_operand" "=e")
7753         (mult:V2SI (match_operand:V4QI 1 "register_operand" "f")
7754                    (match_operand:V2HI 2 "register_operand" "f")))]
7755   "TARGET_VIS"
7756   "fmuld8sux16\t%1, %2, %0"
7757   [(set_attr "type" "fpmul")
7758    (set_attr "fptype" "double")])
7760 (define_insn "fmuld8ulx16_vis"
7761   [(set (match_operand:V2SI 0 "register_operand" "=e")
7762         (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
7763                       (match_operand:V2HI 2 "register_operand" "f")]
7764          UNSPEC_MULDUL))]
7765   "TARGET_VIS"
7766   "fmuld8ulx16\t%1, %2, %0"
7767   [(set_attr "type" "fpmul")
7768    (set_attr "fptype" "double")])
7770 ;; Using faligndata only makes sense after an alignaddr since the choice of
7771 ;; bytes to take out of each operand is dependent on the results of the last
7772 ;; alignaddr.
7773 (define_insn "faligndata<V64I:mode>_vis"
7774   [(set (match_operand:V64I 0 "register_operand" "=e")
7775         (unspec:V64I [(match_operand:V64I 1 "register_operand" "e")
7776                       (match_operand:V64I 2 "register_operand" "e")]
7777          UNSPEC_ALIGNDATA))]
7778   "TARGET_VIS"
7779   "faligndata\t%1, %2, %0"
7780   [(set_attr "type" "fga")
7781    (set_attr "fptype" "double")])
7783 (define_insn "alignaddr<P:mode>_vis"
7784   [(set (match_operand:P 0 "register_operand" "=r")
7785         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
7786                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
7787          UNSPEC_ALIGNADDR))]
7788   "TARGET_VIS"
7789   "alignaddr\t%r1, %r2, %0")
7791 (define_insn "pdist_vis"
7792   [(set (match_operand:DI 0 "register_operand" "=e")
7793         (unspec:DI [(match_operand:V8QI 1 "register_operand" "e")
7794                     (match_operand:V8QI 2 "register_operand" "e")
7795                     (match_operand:DI 3 "register_operand" "0")]
7796          UNSPEC_PDIST))]
7797   "TARGET_VIS"
7798   "pdist\t%1, %2, %0"
7799   [(set_attr "type" "fga")
7800    (set_attr "fptype" "double")])
7802 (include "sync.md")