Merged with mainline at revision 128810.
[official-gcc.git] / gcc / config / sparc / sparc.md
blob329dd1a7ab10b162d7b090cef7e21495dc039a9f
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 Free Software Foundation, Inc.
4 ;;  Contributed by Michael Tiemann (tiemann@cygnus.com)
5 ;;  64-bit SPARC-V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
6 ;;  at Cygnus Support.
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
13 ;; any later version.
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3.  If not see
22 ;; <http://www.gnu.org/licenses/>.
24 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
26 (define_constants
27   [(UNSPEC_MOVE_PIC             0)
28    (UNSPEC_UPDATE_RETURN        1)
29    (UNSPEC_LOAD_PCREL_SYM       2)
30    (UNSPEC_MOVE_PIC_LABEL       5)
31    (UNSPEC_SETH44               6)
32    (UNSPEC_SETM44               7)
33    (UNSPEC_SETHH                9)
34    (UNSPEC_SETLM                10)
35    (UNSPEC_EMB_HISUM            11)
36    (UNSPEC_EMB_TEXTUHI          13)
37    (UNSPEC_EMB_TEXTHI           14)
38    (UNSPEC_EMB_TEXTULO          15)
39    (UNSPEC_EMB_SETHM            18)
41    (UNSPEC_TLSGD                30)
42    (UNSPEC_TLSLDM               31)
43    (UNSPEC_TLSLDO               32)
44    (UNSPEC_TLSIE                33)
45    (UNSPEC_TLSLE                34)
46    (UNSPEC_TLSLD_BASE           35)
48    (UNSPEC_FPACK16              40)
49    (UNSPEC_FPACK32              41)
50    (UNSPEC_FPACKFIX             42)
51    (UNSPEC_FEXPAND              43)
52    (UNSPEC_FPMERGE              44)
53    (UNSPEC_MUL16AL              45)
54    (UNSPEC_MUL8UL               46)
55    (UNSPEC_MULDUL               47)
56    (UNSPEC_ALIGNDATA            48)
57    (UNSPEC_ALIGNADDR            49)
58    (UNSPEC_PDIST                50)
60    (UNSPEC_SP_SET               60)
61    (UNSPEC_SP_TEST              61)
62   ])
64 (define_constants
65   [(UNSPECV_BLOCKAGE            0)
66    (UNSPECV_FLUSHW              1)
67    (UNSPECV_GOTO                2)
68    (UNSPECV_FLUSH               4)
69    (UNSPECV_SETJMP              5)
70    (UNSPECV_SAVEW               6)
71    (UNSPECV_MEMBAR              7)
72    (UNSPECV_CAS                 8)
73    (UNSPECV_SWAP                9)
74    (UNSPECV_LDSTUB              10)
75   ])
77 ;; The upper 32 fp regs on the v9 can't hold SFmode values.  To deal with this
78 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip.  The name
79 ;; is a bit of a misnomer as it covers all 64 fp regs.  The corresponding
80 ;; constraint letter is 'e'.  To avoid any confusion, 'e' is used instead of
81 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
84 ;; Attribute for cpu type.
85 ;; These must match the values for enum processor_type in sparc.h.
86 (define_attr "cpu"
87   "v7,
88    cypress,
89    v8,
90    supersparc,
91    sparclite,f930,f934,
92    hypersparc,sparclite86x,
93    sparclet,tsc701,
94    v9,
95    ultrasparc,
96    ultrasparc3,
97    niagara"
98   (const (symbol_ref "sparc_cpu_attr")))
100 ;; Attribute for the instruction set.
101 ;; At present we only need to distinguish v9/!v9, but for clarity we
102 ;; test TARGET_V8 too.
103 (define_attr "isa" "v7,v8,v9,sparclet"
104  (const
105   (cond [(symbol_ref "TARGET_V9") (const_string "v9")
106          (symbol_ref "TARGET_V8") (const_string "v8")
107          (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
108         (const_string "v7"))))
110 ;; Insn type.
111 (define_attr "type"
112   "ialu,compare,shift,
113    load,sload,store,
114    uncond_branch,branch,call,sibcall,call_no_delay_slot,return,
115    imul,idiv,
116    fpload,fpstore,
117    fp,fpmove,
118    fpcmove,fpcrmove,
119    fpcmp,
120    fpmul,fpdivs,fpdivd,
121    fpsqrts,fpsqrtd,
122    fga,fgm_pack,fgm_mul,fgm_pdist,fgm_cmp,
123    cmove,
124    ialuX,
125    multi,savew,flushw,iflush,trap"
126   (const_string "ialu"))
128 ;; True if branch/call has empty delay slot and will emit a nop in it
129 (define_attr "empty_delay_slot" "false,true"
130   (symbol_ref "empty_delay_slot (insn)"))
132 (define_attr "branch_type" "none,icc,fcc,reg"
133   (const_string "none"))
135 (define_attr "pic" "false,true"
136   (symbol_ref "flag_pic != 0"))
138 (define_attr "calls_alloca" "false,true"
139   (symbol_ref "current_function_calls_alloca != 0"))
141 (define_attr "calls_eh_return" "false,true"
142    (symbol_ref "current_function_calls_eh_return !=0 "))
143    
144 (define_attr "leaf_function" "false,true"
145   (symbol_ref "current_function_uses_only_leaf_regs != 0"))
147 (define_attr "delayed_branch" "false,true"
148   (symbol_ref "flag_delayed_branch != 0"))
150 ;; Length (in # of insns).
151 ;; Beware that setting a length greater or equal to 3 for conditional branches
152 ;; has a side-effect (see output_cbranch and output_v9branch).
153 (define_attr "length" ""
154   (cond [(eq_attr "type" "uncond_branch,call")
155            (if_then_else (eq_attr "empty_delay_slot" "true")
156              (const_int 2)
157              (const_int 1))
158          (eq_attr "type" "sibcall")
159            (if_then_else (eq_attr "leaf_function" "true")
160              (if_then_else (eq_attr "empty_delay_slot" "true")
161                (const_int 3)
162                (const_int 2))
163              (if_then_else (eq_attr "empty_delay_slot" "true")
164                (const_int 2)
165                (const_int 1)))
166          (eq_attr "branch_type" "icc")
167            (if_then_else (match_operand 0 "noov_compare64_operator" "")
168              (if_then_else (lt (pc) (match_dup 1))
169                (if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000))
170                  (if_then_else (eq_attr "empty_delay_slot" "true")
171                    (const_int 2)
172                    (const_int 1))
173                  (if_then_else (eq_attr "empty_delay_slot" "true")
174                    (const_int 4)
175                    (const_int 3)))
176                (if_then_else (lt (minus (pc) (match_dup 1)) (const_int 260000))
177                  (if_then_else (eq_attr "empty_delay_slot" "true")
178                    (const_int 2)
179                    (const_int 1))
180                  (if_then_else (eq_attr "empty_delay_slot" "true")
181                    (const_int 4)
182                    (const_int 3))))
183              (if_then_else (eq_attr "empty_delay_slot" "true")
184                (const_int 2)
185                (const_int 1)))
186          (eq_attr "branch_type" "fcc")
187            (if_then_else (match_operand 0 "fcc0_register_operand" "")
188              (if_then_else (eq_attr "empty_delay_slot" "true")
189                (if_then_else (eq (symbol_ref "TARGET_V9") (const_int 0))
190                  (const_int 3)
191                  (const_int 2))
192                (if_then_else (eq (symbol_ref "TARGET_V9") (const_int 0))
193                  (const_int 2)
194                  (const_int 1)))
195              (if_then_else (lt (pc) (match_dup 2))
196                (if_then_else (lt (minus (match_dup 2) (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 2)) (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          (eq_attr "branch_type" "reg")
211            (if_then_else (lt (pc) (match_dup 2))
212              (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000))
213                (if_then_else (eq_attr "empty_delay_slot" "true")
214                  (const_int 2)
215                  (const_int 1))
216                (if_then_else (eq_attr "empty_delay_slot" "true")
217                  (const_int 4)
218                  (const_int 3)))
219              (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000))
220                (if_then_else (eq_attr "empty_delay_slot" "true")
221                  (const_int 2)
222                  (const_int 1))
223                (if_then_else (eq_attr "empty_delay_slot" "true")
224                  (const_int 4)
225                  (const_int 3))))
226          ] (const_int 1)))
228 ;; FP precision.
229 (define_attr "fptype" "single,double"
230   (const_string "single"))
232 ;; UltraSPARC-III integer load type.
233 (define_attr "us3load_type" "2cycle,3cycle"
234   (const_string "2cycle"))
236 (define_asm_attributes
237   [(set_attr "length" "2")
238    (set_attr "type" "multi")])
240 ;; Attributes for instruction and branch scheduling
241 (define_attr "tls_call_delay" "false,true"
242   (symbol_ref "tls_call_delay (insn)"))
244 (define_attr "in_call_delay" "false,true"
245   (cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
246                 (const_string "false")
247          (eq_attr "type" "load,fpload,store,fpstore")
248                 (if_then_else (eq_attr "length" "1")
249                               (const_string "true")
250                               (const_string "false"))]
251         (if_then_else (and (eq_attr "length" "1")
252                            (eq_attr "tls_call_delay" "true"))
253                       (const_string "true")
254                       (const_string "false"))))
256 (define_attr "eligible_for_sibcall_delay" "false,true"
257   (symbol_ref "eligible_for_sibcall_delay (insn)"))
259 (define_attr "eligible_for_return_delay" "false,true"
260   (symbol_ref "eligible_for_return_delay (insn)"))
262 ;; ??? !v9: Should implement the notion of predelay slots for floating-point
263 ;; branches.  This would allow us to remove the nop always inserted before
264 ;; a floating point branch.
266 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
267 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
268 ;; This is because doing so will add several pipeline stalls to the path
269 ;; that the load/store did not come from.  Unfortunately, there is no way
270 ;; to prevent fill_eager_delay_slots from using load/store without completely
271 ;; disabling them.  For the SPEC benchmark set, this is a serious lose,
272 ;; because it prevents us from moving back the final store of inner loops.
274 (define_attr "in_branch_delay" "false,true"
275   (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
276                      (eq_attr "length" "1"))
277                 (const_string "true")
278                 (const_string "false")))
280 (define_attr "in_uncond_branch_delay" "false,true"
281   (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
282                      (eq_attr "length" "1"))
283                 (const_string "true")
284                 (const_string "false")))
286 (define_attr "in_annul_branch_delay" "false,true"
287   (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
288                      (eq_attr "length" "1"))
289                 (const_string "true")
290                 (const_string "false")))
292 (define_delay (eq_attr "type" "call")
293   [(eq_attr "in_call_delay" "true") (nil) (nil)])
295 (define_delay (eq_attr "type" "sibcall")
296   [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
298 (define_delay (eq_attr "type" "branch")
299   [(eq_attr "in_branch_delay" "true")
300    (nil) (eq_attr "in_annul_branch_delay" "true")])
302 (define_delay (eq_attr "type" "uncond_branch")
303   [(eq_attr "in_uncond_branch_delay" "true")
304    (nil) (nil)])
306 (define_delay (eq_attr "type" "return")
307   [(eq_attr "eligible_for_return_delay" "true") (nil) (nil)])
310 ;; Include SPARC DFA schedulers
312 (include "cypress.md")
313 (include "supersparc.md")
314 (include "hypersparc.md")
315 (include "sparclet.md")
316 (include "ultra1_2.md")
317 (include "ultra3.md")
318 (include "niagara.md")
321 ;; Operand and operator predicates.
323 (include "predicates.md")
326 ;; Compare instructions.
328 ;; We generate RTL for comparisons and branches by having the cmpxx 
329 ;; patterns store away the operands.  Then, the scc and bcc patterns
330 ;; emit RTL for both the compare and the branch.
332 ;; We do this because we want to generate different code for an sne and
333 ;; seq insn.  In those cases, if the second operand of the compare is not
334 ;; const0_rtx, we want to compute the xor of the two operands and test
335 ;; it against zero.
337 ;; We start with the DEFINE_EXPANDs, then the DEFINE_INSNs to match
338 ;; the patterns.  Finally, we have the DEFINE_SPLITs for some of the scc
339 ;; insns that actually require more than one machine instruction.
341 (define_expand "cmpsi"
342   [(set (reg:CC 100)
343         (compare:CC (match_operand:SI 0 "compare_operand" "")
344                     (match_operand:SI 1 "arith_operand" "")))]
345   ""
347   if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx)
348     operands[0] = force_reg (SImode, operands[0]);
350   sparc_compare_op0 = operands[0];
351   sparc_compare_op1 = operands[1];
352   DONE;
355 (define_expand "cmpdi"
356   [(set (reg:CCX 100)
357         (compare:CCX (match_operand:DI 0 "compare_operand" "")
358                      (match_operand:DI 1 "arith_operand" "")))]
359   "TARGET_ARCH64"
361   if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx)
362     operands[0] = force_reg (DImode, operands[0]);
364   sparc_compare_op0 = operands[0];
365   sparc_compare_op1 = operands[1];
366   DONE;
369 (define_expand "cmpsf"
370   ;; The 96 here isn't ever used by anyone.
371   [(set (reg:CCFP 96)
372         (compare:CCFP (match_operand:SF 0 "register_operand" "")
373                       (match_operand:SF 1 "register_operand" "")))]
374   "TARGET_FPU"
376   sparc_compare_op0 = operands[0];
377   sparc_compare_op1 = operands[1];
378   DONE;
381 (define_expand "cmpdf"
382   ;; The 96 here isn't ever used by anyone.
383   [(set (reg:CCFP 96)
384         (compare:CCFP (match_operand:DF 0 "register_operand" "")
385                       (match_operand:DF 1 "register_operand" "")))]
386   "TARGET_FPU"
388   sparc_compare_op0 = operands[0];
389   sparc_compare_op1 = operands[1];
390   DONE;
393 (define_expand "cmptf"
394   ;; The 96 here isn't ever used by anyone.
395   [(set (reg:CCFP 96)
396         (compare:CCFP (match_operand:TF 0 "register_operand" "")
397                       (match_operand:TF 1 "register_operand" "")))]
398   "TARGET_FPU"
400   sparc_compare_op0 = operands[0];
401   sparc_compare_op1 = operands[1];
402   DONE;
405 ;; Now the compare DEFINE_INSNs.
407 (define_insn "*cmpsi_insn"
408   [(set (reg:CC 100)
409         (compare:CC (match_operand:SI 0 "register_operand" "r")
410                     (match_operand:SI 1 "arith_operand" "rI")))]
411   ""
412   "cmp\t%0, %1"
413   [(set_attr "type" "compare")])
415 (define_insn "*cmpdi_sp64"
416   [(set (reg:CCX 100)
417         (compare:CCX (match_operand:DI 0 "register_operand" "r")
418                      (match_operand:DI 1 "arith_operand" "rI")))]
419   "TARGET_ARCH64"
420   "cmp\t%0, %1"
421   [(set_attr "type" "compare")])
423 (define_insn "*cmpsf_fpe"
424   [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
425         (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
426                        (match_operand:SF 2 "register_operand" "f")))]
427   "TARGET_FPU"
429   if (TARGET_V9)
430     return "fcmpes\t%0, %1, %2";
431   return "fcmpes\t%1, %2";
433   [(set_attr "type" "fpcmp")])
435 (define_insn "*cmpdf_fpe"
436   [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
437         (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
438                        (match_operand:DF 2 "register_operand" "e")))]
439   "TARGET_FPU"
441   if (TARGET_V9)
442     return "fcmped\t%0, %1, %2";
443   return "fcmped\t%1, %2";
445   [(set_attr "type" "fpcmp")
446    (set_attr "fptype" "double")])
448 (define_insn "*cmptf_fpe"
449   [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
450         (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
451                        (match_operand:TF 2 "register_operand" "e")))]
452   "TARGET_FPU && TARGET_HARD_QUAD"
454   if (TARGET_V9)
455     return "fcmpeq\t%0, %1, %2";
456   return "fcmpeq\t%1, %2";
458   [(set_attr "type" "fpcmp")])
460 (define_insn "*cmpsf_fp"
461   [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
462         (compare:CCFP (match_operand:SF 1 "register_operand" "f")
463                       (match_operand:SF 2 "register_operand" "f")))]
464   "TARGET_FPU"
466   if (TARGET_V9)
467     return "fcmps\t%0, %1, %2";
468   return "fcmps\t%1, %2";
470   [(set_attr "type" "fpcmp")])
472 (define_insn "*cmpdf_fp"
473   [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
474         (compare:CCFP (match_operand:DF 1 "register_operand" "e")
475                       (match_operand:DF 2 "register_operand" "e")))]
476   "TARGET_FPU"
478   if (TARGET_V9)
479     return "fcmpd\t%0, %1, %2";
480   return "fcmpd\t%1, %2";
482   [(set_attr "type" "fpcmp")
483    (set_attr "fptype" "double")])
485 (define_insn "*cmptf_fp"
486   [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
487         (compare:CCFP (match_operand:TF 1 "register_operand" "e")
488                       (match_operand:TF 2 "register_operand" "e")))]
489   "TARGET_FPU && TARGET_HARD_QUAD"
491   if (TARGET_V9)
492     return "fcmpq\t%0, %1, %2";
493   return "fcmpq\t%1, %2";
495   [(set_attr "type" "fpcmp")])
497 ;; Next come the scc insns.  For seq, sne, sgeu, and sltu, we can do this
498 ;; without jumps using the addx/subx instructions.  For seq/sne on v9 we use
499 ;; the same code as v8 (the addx/subx method has more applications).  The
500 ;; exception to this is "reg != 0" which can be done in one instruction on v9
501 ;; (so we do it).  For the rest, on v9 we use conditional moves; on v8, we do
502 ;; branches.
504 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
505 ;; generate addcc/subcc instructions.
507 (define_expand "seqsi_special"
508   [(set (match_dup 3)
509         (xor:SI (match_operand:SI 1 "register_operand" "")
510                 (match_operand:SI 2 "register_operand" "")))
511    (parallel [(set (match_operand:SI 0 "register_operand" "")
512                    (eq:SI (match_dup 3) (const_int 0)))
513               (clobber (reg:CC 100))])]
514   ""
515   { operands[3] = gen_reg_rtx (SImode); })
517 (define_expand "seqdi_special"
518   [(set (match_dup 3)
519         (xor:DI (match_operand:DI 1 "register_operand" "")
520                 (match_operand:DI 2 "register_operand" "")))
521    (set (match_operand:DI 0 "register_operand" "")
522         (eq:DI (match_dup 3) (const_int 0)))]
523   "TARGET_ARCH64"
524   { operands[3] = gen_reg_rtx (DImode); })
526 (define_expand "snesi_special"
527   [(set (match_dup 3)
528         (xor:SI (match_operand:SI 1 "register_operand" "")
529                 (match_operand:SI 2 "register_operand" "")))
530    (parallel [(set (match_operand:SI 0 "register_operand" "")
531                    (ne:SI (match_dup 3) (const_int 0)))
532               (clobber (reg:CC 100))])]
533   ""
534   { operands[3] = gen_reg_rtx (SImode); })
536 (define_expand "snedi_special"
537   [(set (match_dup 3)
538         (xor:DI (match_operand:DI 1 "register_operand" "")
539                 (match_operand:DI 2 "register_operand" "")))
540    (set (match_operand:DI 0 "register_operand" "")
541         (ne:DI (match_dup 3) (const_int 0)))]
542   "TARGET_ARCH64"
543   { operands[3] = gen_reg_rtx (DImode); })
545 (define_expand "seqdi_special_trunc"
546   [(set (match_dup 3)
547         (xor:DI (match_operand:DI 1 "register_operand" "")
548                 (match_operand:DI 2 "register_operand" "")))
549    (set (match_operand:SI 0 "register_operand" "")
550         (eq:SI (match_dup 3) (const_int 0)))]
551   "TARGET_ARCH64"
552   { operands[3] = gen_reg_rtx (DImode); })
554 (define_expand "snedi_special_trunc"
555   [(set (match_dup 3)
556         (xor:DI (match_operand:DI 1 "register_operand" "")
557                 (match_operand:DI 2 "register_operand" "")))
558    (set (match_operand:SI 0 "register_operand" "")
559         (ne:SI (match_dup 3) (const_int 0)))]
560   "TARGET_ARCH64"
561   { operands[3] = gen_reg_rtx (DImode); })
563 (define_expand "seqsi_special_extend"
564   [(set (match_dup 3)
565         (xor:SI (match_operand:SI 1 "register_operand" "")
566                 (match_operand:SI 2 "register_operand" "")))
567    (parallel [(set (match_operand:DI 0 "register_operand" "")
568                    (eq:DI (match_dup 3) (const_int 0)))
569               (clobber (reg:CC 100))])]
570   "TARGET_ARCH64"
571   { operands[3] = gen_reg_rtx (SImode); })
573 (define_expand "snesi_special_extend"
574   [(set (match_dup 3)
575         (xor:SI (match_operand:SI 1 "register_operand" "")
576                 (match_operand:SI 2 "register_operand" "")))
577    (parallel [(set (match_operand:DI 0 "register_operand" "")
578                    (ne:DI (match_dup 3) (const_int 0)))
579               (clobber (reg:CC 100))])]
580   "TARGET_ARCH64"
581   { operands[3] = gen_reg_rtx (SImode); })
583 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
584 ;; However, the code handles both SImode and DImode.
585 (define_expand "seq"
586   [(set (match_operand:SI 0 "int_register_operand" "")
587         (eq:SI (match_dup 1) (const_int 0)))]
588   ""
590   if (GET_MODE (sparc_compare_op0) == SImode)
591     {
592       rtx pat;
594       if (GET_MODE (operands[0]) == SImode)
595         pat = gen_seqsi_special (operands[0], sparc_compare_op0,
596                                  sparc_compare_op1);
597       else if (! TARGET_ARCH64)
598         FAIL;
599       else
600         pat = gen_seqsi_special_extend (operands[0], sparc_compare_op0,
601                                         sparc_compare_op1);
602       emit_insn (pat);
603       DONE;
604     }
605   else if (GET_MODE (sparc_compare_op0) == DImode)
606     {
607       rtx pat;
609       if (! TARGET_ARCH64)
610         FAIL;
611       else if (GET_MODE (operands[0]) == SImode)
612         pat = gen_seqdi_special_trunc (operands[0], sparc_compare_op0,
613                                        sparc_compare_op1);
614       else
615         pat = gen_seqdi_special (operands[0], sparc_compare_op0,
616                                  sparc_compare_op1);
617       emit_insn (pat);
618       DONE;
619     }
620   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
621     {
622       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
623       emit_jump_insn (gen_sne (operands[0]));
624       DONE;
625     }
626   else if (TARGET_V9)
627     {
628       if (gen_v9_scc (EQ, operands))
629         DONE;
630       /* fall through */
631     }
632   FAIL;
635 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
636 ;; However, the code handles both SImode and DImode.
637 (define_expand "sne"
638   [(set (match_operand:SI 0 "int_register_operand" "")
639         (ne:SI (match_dup 1) (const_int 0)))]
640   ""
642   if (GET_MODE (sparc_compare_op0) == SImode)
643     {
644       rtx pat;
646       if (GET_MODE (operands[0]) == SImode)
647         pat = gen_snesi_special (operands[0], sparc_compare_op0,
648                                  sparc_compare_op1);
649       else if (! TARGET_ARCH64)
650         FAIL;
651       else
652         pat = gen_snesi_special_extend (operands[0], sparc_compare_op0,
653                                         sparc_compare_op1);
654       emit_insn (pat);
655       DONE;
656     }
657   else if (GET_MODE (sparc_compare_op0) == DImode)
658     {
659       rtx pat;
661       if (! TARGET_ARCH64)
662         FAIL;
663       else if (GET_MODE (operands[0]) == SImode)
664         pat = gen_snedi_special_trunc (operands[0], sparc_compare_op0,
665                                        sparc_compare_op1);
666       else
667         pat = gen_snedi_special (operands[0], sparc_compare_op0,
668                                  sparc_compare_op1);
669       emit_insn (pat);
670       DONE;
671     }
672   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
673     {
674       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
675       emit_jump_insn (gen_sne (operands[0]));
676       DONE;
677     }
678   else if (TARGET_V9)
679     {
680       if (gen_v9_scc (NE, operands))
681         DONE;
682       /* fall through */
683     }
684   FAIL;
687 (define_expand "sgt"
688   [(set (match_operand:SI 0 "int_register_operand" "")
689         (gt:SI (match_dup 1) (const_int 0)))]
690   ""
692   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
693     {
694       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
695       emit_jump_insn (gen_sne (operands[0]));
696       DONE;
697     }
698   else if (TARGET_V9)
699     {
700       if (gen_v9_scc (GT, operands))
701         DONE;
702       /* fall through */
703     }
704   FAIL;
707 (define_expand "slt"
708   [(set (match_operand:SI 0 "int_register_operand" "")
709         (lt:SI (match_dup 1) (const_int 0)))]
710   ""
712   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
713     {
714       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
715       emit_jump_insn (gen_sne (operands[0]));
716       DONE;
717     }
718   else if (TARGET_V9)
719     {
720       if (gen_v9_scc (LT, operands))
721         DONE;
722       /* fall through */
723     }
724   FAIL;
727 (define_expand "sge"
728   [(set (match_operand:SI 0 "int_register_operand" "")
729         (ge:SI (match_dup 1) (const_int 0)))]
730   ""
732   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
733     {
734       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
735       emit_jump_insn (gen_sne (operands[0]));
736       DONE;
737     }
738   else if (TARGET_V9)
739     {
740       if (gen_v9_scc (GE, operands))
741         DONE;
742       /* fall through */
743     }
744   FAIL;
747 (define_expand "sle"
748   [(set (match_operand:SI 0 "int_register_operand" "")
749         (le:SI (match_dup 1) (const_int 0)))]
750   ""
752   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
753     {
754       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
755       emit_jump_insn (gen_sne (operands[0]));
756       DONE;
757     }
758   else if (TARGET_V9)
759     {
760       if (gen_v9_scc (LE, operands))
761         DONE;
762       /* fall through */
763     }
764   FAIL;
767 (define_expand "sgtu"
768   [(set (match_operand:SI 0 "int_register_operand" "")
769         (gtu:SI (match_dup 1) (const_int 0)))]
770   ""
772   if (! TARGET_V9)
773     {
774       rtx tem, pat;
776       /* We can do ltu easily, so if both operands are registers, swap them and
777          do a LTU.  */
778       if ((GET_CODE (sparc_compare_op0) == REG
779            || GET_CODE (sparc_compare_op0) == SUBREG)
780           && (GET_CODE (sparc_compare_op1) == REG
781               || GET_CODE (sparc_compare_op1) == SUBREG))
782         {
783           tem = sparc_compare_op0;
784           sparc_compare_op0 = sparc_compare_op1;
785           sparc_compare_op1 = tem;
786           pat = gen_sltu (operands[0]);
787           if (pat == NULL_RTX)
788             FAIL;
789           emit_insn (pat);
790           DONE;
791         }
792     }
793   else
794     {
795       if (gen_v9_scc (GTU, operands))
796         DONE;
797     }
798   FAIL;
801 (define_expand "sltu"
802   [(set (match_operand:SI 0 "int_register_operand" "")
803         (ltu:SI (match_dup 1) (const_int 0)))]
804   ""
806   if (TARGET_V9)
807     {
808       if (gen_v9_scc (LTU, operands))
809         DONE;
810     }
811   operands[1] = gen_compare_reg (LTU);
814 (define_expand "sgeu"
815   [(set (match_operand:SI 0 "int_register_operand" "")
816         (geu:SI (match_dup 1) (const_int 0)))]
817   ""
819   if (TARGET_V9)
820     {
821       if (gen_v9_scc (GEU, operands))
822         DONE;
823     }
824   operands[1] = gen_compare_reg (GEU);
827 (define_expand "sleu"
828   [(set (match_operand:SI 0 "int_register_operand" "")
829         (leu:SI (match_dup 1) (const_int 0)))]
830   ""
832   if (! TARGET_V9)
833     {
834       rtx tem, pat;
836       /* We can do geu easily, so if both operands are registers, swap them and
837          do a GEU.  */
838       if ((GET_CODE (sparc_compare_op0) == REG
839            || GET_CODE (sparc_compare_op0) == SUBREG)
840           && (GET_CODE (sparc_compare_op1) == REG
841               || GET_CODE (sparc_compare_op1) == SUBREG))
842         {
843           tem = sparc_compare_op0;
844           sparc_compare_op0 = sparc_compare_op1;
845           sparc_compare_op1 = tem;
846           pat = gen_sgeu (operands[0]);
847           if (pat == NULL_RTX)
848             FAIL;
849           emit_insn (pat);
850           DONE;
851         }
852     }
853   else
854     {
855       if (gen_v9_scc (LEU, operands))
856         DONE;
857     }
858   FAIL;
861 ;; Now the DEFINE_INSNs for the scc cases.
863 ;; The SEQ and SNE patterns are special because they can be done
864 ;; without any branching and do not involve a COMPARE.  We want
865 ;; them to always use the splits below so the results can be
866 ;; scheduled.
868 (define_insn_and_split "*snesi_zero"
869   [(set (match_operand:SI 0 "register_operand" "=r")
870         (ne:SI (match_operand:SI 1 "register_operand" "r")
871                (const_int 0)))
872    (clobber (reg:CC 100))]
873   ""
874   "#"
875   ""
876   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
877                                            (const_int 0)))
878    (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))]
879   ""
880   [(set_attr "length" "2")])
882 (define_insn_and_split "*neg_snesi_zero"
883   [(set (match_operand:SI 0 "register_operand" "=r")
884         (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
885                        (const_int 0))))
886    (clobber (reg:CC 100))]
887   ""
888   "#"
889   ""
890   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
891                                            (const_int 0)))
892    (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
893   ""
894   [(set_attr "length" "2")])
896 (define_insn_and_split "*snesi_zero_extend"
897   [(set (match_operand:DI 0 "register_operand" "=r")
898         (ne:DI (match_operand:SI 1 "register_operand" "r")
899                (const_int 0)))
900    (clobber (reg:CC 100))]
901   "TARGET_ARCH64"
902   "#"
903   "&& 1"
904   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
905                                                      (match_dup 1))
906                                            (const_int 0)))
907    (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
908                                                         (const_int 0))
909                                                (ltu:SI (reg:CC_NOOV 100)
910                                                        (const_int 0)))))]
911   ""
912   [(set_attr "length" "2")])
914 (define_insn_and_split "*snedi_zero"
915   [(set (match_operand:DI 0 "register_operand" "=&r")
916         (ne:DI (match_operand:DI 1 "register_operand" "r")
917                (const_int 0)))]
918   "TARGET_ARCH64"
919   "#"
920   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
921   [(set (match_dup 0) (const_int 0))
922    (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
923                                               (const_int 0))
924                                        (const_int 1)
925                                        (match_dup 0)))]
926   ""
927   [(set_attr "length" "2")])
929 (define_insn_and_split "*neg_snedi_zero"
930   [(set (match_operand:DI 0 "register_operand" "=&r")
931         (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
932                        (const_int 0))))]
933   "TARGET_ARCH64"
934   "#"
935   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
936   [(set (match_dup 0) (const_int 0))
937    (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
938                                               (const_int 0))
939                                        (const_int -1)
940                                        (match_dup 0)))]
941   ""
942   [(set_attr "length" "2")])
944 (define_insn_and_split "*snedi_zero_trunc"
945   [(set (match_operand:SI 0 "register_operand" "=&r")
946         (ne:SI (match_operand:DI 1 "register_operand" "r")
947                (const_int 0)))]
948   "TARGET_ARCH64"
949   "#"
950   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
951   [(set (match_dup 0) (const_int 0))
952    (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
953                                               (const_int 0))
954                                        (const_int 1)
955                                        (match_dup 0)))]
956   ""
957   [(set_attr "length" "2")])
959 (define_insn_and_split "*seqsi_zero"
960   [(set (match_operand:SI 0 "register_operand" "=r")
961         (eq:SI (match_operand:SI 1 "register_operand" "r")
962                (const_int 0)))
963    (clobber (reg:CC 100))]
964   ""
965   "#"
966   ""
967   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
968                                            (const_int 0)))
969    (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))]
970   ""
971   [(set_attr "length" "2")])
973 (define_insn_and_split "*neg_seqsi_zero"
974   [(set (match_operand:SI 0 "register_operand" "=r")
975         (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
976                        (const_int 0))))
977    (clobber (reg:CC 100))]
978   ""
979   "#"
980   ""
981   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
982                                            (const_int 0)))
983    (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
984   ""
985   [(set_attr "length" "2")])
987 (define_insn_and_split "*seqsi_zero_extend"
988   [(set (match_operand:DI 0 "register_operand" "=r")
989         (eq:DI (match_operand:SI 1 "register_operand" "r")
990                (const_int 0)))
991    (clobber (reg:CC 100))]
992   "TARGET_ARCH64"
993   "#"
994   "&& 1"
995   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
996                                                      (match_dup 1))
997                                            (const_int 0)))
998    (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
999                                                           (const_int -1))
1000                                                 (ltu:SI (reg:CC_NOOV 100)
1001                                                         (const_int 0)))))]
1002   ""
1003   [(set_attr "length" "2")])
1005 (define_insn_and_split "*seqdi_zero"
1006   [(set (match_operand:DI 0 "register_operand" "=&r")
1007         (eq:DI (match_operand:DI 1 "register_operand" "r")
1008                (const_int 0)))]
1009   "TARGET_ARCH64"
1010   "#"
1011   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1012   [(set (match_dup 0) (const_int 0))
1013    (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1014                                               (const_int 0))
1015                                        (const_int 1)
1016                                        (match_dup 0)))]
1017   ""
1018   [(set_attr "length" "2")])
1020 (define_insn_and_split "*neg_seqdi_zero"
1021   [(set (match_operand:DI 0 "register_operand" "=&r")
1022         (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
1023                        (const_int 0))))]
1024   "TARGET_ARCH64"
1025   "#"
1026   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1027   [(set (match_dup 0) (const_int 0))
1028    (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1029                                               (const_int 0))
1030                                        (const_int -1)
1031                                        (match_dup 0)))]
1032   ""
1033   [(set_attr "length" "2")]) 
1035 (define_insn_and_split "*seqdi_zero_trunc"
1036   [(set (match_operand:SI 0 "register_operand" "=&r")
1037         (eq:SI (match_operand:DI 1 "register_operand" "r")
1038                (const_int 0)))]
1039   "TARGET_ARCH64"
1040   "#"
1041   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1042   [(set (match_dup 0) (const_int 0))
1043    (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
1044                                               (const_int 0))
1045                                        (const_int 1)
1046                                        (match_dup 0)))]
1047   ""
1048   [(set_attr "length" "2")])
1050 ;; We can also do (x + (i == 0)) and related, so put them in.
1051 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1052 ;; versions for v9.
1054 (define_insn_and_split "*x_plus_i_ne_0"
1055   [(set (match_operand:SI 0 "register_operand" "=r")
1056         (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
1057                         (const_int 0))
1058                  (match_operand:SI 2 "register_operand" "r")))
1059    (clobber (reg:CC 100))]
1060   ""
1061   "#"
1062   ""
1063   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1064                                            (const_int 0)))
1065    (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1066                                (match_dup 2)))]
1067   ""
1068   [(set_attr "length" "2")])
1070 (define_insn_and_split "*x_minus_i_ne_0"
1071   [(set (match_operand:SI 0 "register_operand" "=r")
1072         (minus:SI (match_operand:SI 2 "register_operand" "r")
1073                   (ne:SI (match_operand:SI 1 "register_operand" "r")
1074                          (const_int 0))))
1075    (clobber (reg:CC 100))]
1076   ""
1077   "#"
1078   ""
1079   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1080                                            (const_int 0)))
1081    (set (match_dup 0) (minus:SI (match_dup 2)
1082                                 (ltu:SI (reg:CC 100) (const_int 0))))]
1083   ""
1084   [(set_attr "length" "2")])
1086 (define_insn_and_split "*x_plus_i_eq_0"
1087   [(set (match_operand:SI 0 "register_operand" "=r")
1088         (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1089                         (const_int 0))
1090                  (match_operand:SI 2 "register_operand" "r")))
1091    (clobber (reg:CC 100))]
1092   ""
1093   "#"
1094   ""
1095   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1096                                            (const_int 0)))
1097    (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1098                                (match_dup 2)))]
1099   ""
1100   [(set_attr "length" "2")])
1102 (define_insn_and_split "*x_minus_i_eq_0"
1103   [(set (match_operand:SI 0 "register_operand" "=r")
1104         (minus:SI (match_operand:SI 2 "register_operand" "r")
1105                   (eq:SI (match_operand:SI 1 "register_operand" "r")
1106                          (const_int 0))))
1107    (clobber (reg:CC 100))]
1108   ""
1109   "#"
1110   ""
1111   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1112                                            (const_int 0)))
1113    (set (match_dup 0) (minus:SI (match_dup 2)
1114                                 (geu:SI (reg:CC 100) (const_int 0))))]
1115   ""
1116   [(set_attr "length" "2")])
1118 ;; We can also do GEU and LTU directly, but these operate after a compare.
1119 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1120 ;; versions for v9.
1122 (define_insn "*sltu_insn"
1123   [(set (match_operand:SI 0 "register_operand" "=r")
1124         (ltu:SI (reg:CC 100) (const_int 0)))]
1125   ""
1126   "addx\t%%g0, 0, %0"
1127   [(set_attr "type" "ialuX")])
1129 (define_insn "*neg_sltu_insn"
1130   [(set (match_operand:SI 0 "register_operand" "=r")
1131         (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1132   ""
1133   "subx\t%%g0, 0, %0"
1134   [(set_attr "type" "ialuX")])
1136 ;; ??? Combine should canonicalize these next two to the same pattern.
1137 (define_insn "*neg_sltu_minus_x"
1138   [(set (match_operand:SI 0 "register_operand" "=r")
1139         (minus:SI (neg:SI (ltu:SI (reg:CC 100) (const_int 0)))
1140                   (match_operand:SI 1 "arith_operand" "rI")))]
1141   ""
1142   "subx\t%%g0, %1, %0"
1143   [(set_attr "type" "ialuX")])
1145 (define_insn "*neg_sltu_plus_x"
1146   [(set (match_operand:SI 0 "register_operand" "=r")
1147         (neg:SI (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1148                          (match_operand:SI 1 "arith_operand" "rI"))))]
1149   ""
1150   "subx\t%%g0, %1, %0"
1151   [(set_attr "type" "ialuX")])
1153 (define_insn "*sgeu_insn"
1154   [(set (match_operand:SI 0 "register_operand" "=r")
1155         (geu:SI (reg:CC 100) (const_int 0)))]
1156   ""
1157   "subx\t%%g0, -1, %0"
1158   [(set_attr "type" "ialuX")])
1160 (define_insn "*neg_sgeu_insn"
1161   [(set (match_operand:SI 0 "register_operand" "=r")
1162         (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1163   ""
1164   "addx\t%%g0, -1, %0"
1165   [(set_attr "type" "ialuX")])
1167 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
1168 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1169 ;; versions for v9.
1171 (define_insn "*sltu_plus_x"
1172   [(set (match_operand:SI 0 "register_operand" "=r")
1173         (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1174                  (match_operand:SI 1 "arith_operand" "rI")))]
1175   ""
1176   "addx\t%%g0, %1, %0"
1177   [(set_attr "type" "ialuX")])
1179 (define_insn "*sltu_plus_x_plus_y"
1180   [(set (match_operand:SI 0 "register_operand" "=r")
1181         (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1182                  (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1183                           (match_operand:SI 2 "arith_operand" "rI"))))]
1184   ""
1185   "addx\t%1, %2, %0"
1186   [(set_attr "type" "ialuX")])
1188 (define_insn "*x_minus_sltu"
1189   [(set (match_operand:SI 0 "register_operand" "=r")
1190         (minus:SI (match_operand:SI 1 "register_operand" "r")
1191                   (ltu:SI (reg:CC 100) (const_int 0))))]
1192   ""
1193   "subx\t%1, 0, %0"
1194   [(set_attr "type" "ialuX")])
1196 ;; ??? Combine should canonicalize these next two to the same pattern.
1197 (define_insn "*x_minus_y_minus_sltu"
1198   [(set (match_operand:SI 0 "register_operand" "=r")
1199         (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
1200                             (match_operand:SI 2 "arith_operand" "rI"))
1201                   (ltu:SI (reg:CC 100) (const_int 0))))]
1202   ""
1203   "subx\t%r1, %2, %0"
1204   [(set_attr "type" "ialuX")])
1206 (define_insn "*x_minus_sltu_plus_y"
1207   [(set (match_operand:SI 0 "register_operand" "=r")
1208         (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
1209                   (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1210                            (match_operand:SI 2 "arith_operand" "rI"))))]
1211   ""
1212   "subx\t%r1, %2, %0"
1213   [(set_attr "type" "ialuX")])
1215 (define_insn "*sgeu_plus_x"
1216   [(set (match_operand:SI 0 "register_operand" "=r")
1217         (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1218                  (match_operand:SI 1 "register_operand" "r")))]
1219   ""
1220   "subx\t%1, -1, %0"
1221   [(set_attr "type" "ialuX")])
1223 (define_insn "*x_minus_sgeu"
1224   [(set (match_operand:SI 0 "register_operand" "=r")
1225         (minus:SI (match_operand:SI 1 "register_operand" "r")
1226                   (geu:SI (reg:CC 100) (const_int 0))))]
1227   ""
1228   "addx\t%1, -1, %0"
1229   [(set_attr "type" "ialuX")])
1231 (define_split
1232   [(set (match_operand:SI 0 "register_operand" "")
1233         (match_operator:SI 2 "noov_compare_operator"
1234                            [(match_operand 1 "icc_or_fcc_register_operand" "")
1235                             (const_int 0)]))]
1236   "TARGET_V9
1237    && REGNO (operands[1]) == SPARC_ICC_REG
1238    && (GET_MODE (operands[1]) == CCXmode
1239        /* 32-bit LTU/GEU are better implemented using addx/subx.  */
1240        || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1241   [(set (match_dup 0) (const_int 0))
1242    (set (match_dup 0)
1243         (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1244                          (const_int 1)
1245                          (match_dup 0)))]
1246   "")
1249 ;; These control RTL generation for conditional jump insns
1251 ;; The quad-word fp compare library routines all return nonzero to indicate
1252 ;; true, which is different from the equivalent libgcc routines, so we must
1253 ;; handle them specially here.
1255 (define_expand "beq"
1256   [(set (pc)
1257         (if_then_else (eq (match_dup 1) (const_int 0))
1258                       (label_ref (match_operand 0 "" ""))
1259                       (pc)))]
1260   ""
1262   if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1263       && GET_CODE (sparc_compare_op0) == REG
1264       && GET_MODE (sparc_compare_op0) == DImode)
1265     {
1266       emit_v9_brxx_insn (EQ, sparc_compare_op0, operands[0]);
1267       DONE;
1268     }
1269   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1270     {
1271       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
1272       emit_jump_insn (gen_bne (operands[0]));
1273       DONE;
1274     }
1275   operands[1] = gen_compare_reg (EQ);
1278 (define_expand "bne"
1279   [(set (pc)
1280         (if_then_else (ne (match_dup 1) (const_int 0))
1281                       (label_ref (match_operand 0 "" ""))
1282                       (pc)))]
1283   ""
1285   if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1286       && GET_CODE (sparc_compare_op0) == REG
1287       && GET_MODE (sparc_compare_op0) == DImode)
1288     {
1289       emit_v9_brxx_insn (NE, sparc_compare_op0, operands[0]);
1290       DONE;
1291     }
1292   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1293     {
1294       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
1295       emit_jump_insn (gen_bne (operands[0]));
1296       DONE;
1297     }
1298   operands[1] = gen_compare_reg (NE);
1301 (define_expand "bgt"
1302   [(set (pc)
1303         (if_then_else (gt (match_dup 1) (const_int 0))
1304                       (label_ref (match_operand 0 "" ""))
1305                       (pc)))]
1306   ""
1308   if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1309       && GET_CODE (sparc_compare_op0) == REG
1310       && GET_MODE (sparc_compare_op0) == DImode)
1311     {
1312       emit_v9_brxx_insn (GT, sparc_compare_op0, operands[0]);
1313       DONE;
1314     }
1315   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1316     {
1317       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
1318       emit_jump_insn (gen_bne (operands[0]));
1319       DONE;
1320     }
1321   operands[1] = gen_compare_reg (GT);
1324 (define_expand "bgtu"
1325   [(set (pc)
1326         (if_then_else (gtu (match_dup 1) (const_int 0))
1327                       (label_ref (match_operand 0 "" ""))
1328                       (pc)))]
1329   ""
1331   operands[1] = gen_compare_reg (GTU);
1334 (define_expand "blt"
1335   [(set (pc)
1336         (if_then_else (lt (match_dup 1) (const_int 0))
1337                       (label_ref (match_operand 0 "" ""))
1338                       (pc)))]
1339   ""
1341   if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1342       && GET_CODE (sparc_compare_op0) == REG
1343       && GET_MODE (sparc_compare_op0) == DImode)
1344     {
1345       emit_v9_brxx_insn (LT, sparc_compare_op0, operands[0]);
1346       DONE;
1347     }
1348   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1349     {
1350       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
1351       emit_jump_insn (gen_bne (operands[0]));
1352       DONE;
1353     }
1354   operands[1] = gen_compare_reg (LT);
1357 (define_expand "bltu"
1358   [(set (pc)
1359         (if_then_else (ltu (match_dup 1) (const_int 0))
1360                       (label_ref (match_operand 0 "" ""))
1361                       (pc)))]
1362   ""
1364   operands[1] = gen_compare_reg (LTU);
1367 (define_expand "bge"
1368   [(set (pc)
1369         (if_then_else (ge (match_dup 1) (const_int 0))
1370                       (label_ref (match_operand 0 "" ""))
1371                       (pc)))]
1372   ""
1374   if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1375       && GET_CODE (sparc_compare_op0) == REG
1376       && GET_MODE (sparc_compare_op0) == DImode)
1377     {
1378       emit_v9_brxx_insn (GE, sparc_compare_op0, operands[0]);
1379       DONE;
1380     }
1381   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1382     {
1383       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
1384       emit_jump_insn (gen_bne (operands[0]));
1385       DONE;
1386     }
1387   operands[1] = gen_compare_reg (GE);
1390 (define_expand "bgeu"
1391   [(set (pc)
1392         (if_then_else (geu (match_dup 1) (const_int 0))
1393                       (label_ref (match_operand 0 "" ""))
1394                       (pc)))]
1395   ""
1397   operands[1] = gen_compare_reg (GEU);
1400 (define_expand "ble"
1401   [(set (pc)
1402         (if_then_else (le (match_dup 1) (const_int 0))
1403                       (label_ref (match_operand 0 "" ""))
1404                       (pc)))]
1405   ""
1407   if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1408       && GET_CODE (sparc_compare_op0) == REG
1409       && GET_MODE (sparc_compare_op0) == DImode)
1410     {
1411       emit_v9_brxx_insn (LE, sparc_compare_op0, operands[0]);
1412       DONE;
1413     }
1414   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1415     {
1416       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
1417       emit_jump_insn (gen_bne (operands[0]));
1418       DONE;
1419     }
1420   operands[1] = gen_compare_reg (LE);
1423 (define_expand "bleu"
1424   [(set (pc)
1425         (if_then_else (leu (match_dup 1) (const_int 0))
1426                       (label_ref (match_operand 0 "" ""))
1427                       (pc)))]
1428   ""
1430   operands[1] = gen_compare_reg (LEU);
1433 (define_expand "bunordered"
1434   [(set (pc)
1435         (if_then_else (unordered (match_dup 1) (const_int 0))
1436                       (label_ref (match_operand 0 "" ""))
1437                       (pc)))]
1438   ""
1440   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1441     {
1442       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1,
1443                                 UNORDERED);
1444       emit_jump_insn (gen_beq (operands[0]));
1445       DONE;
1446     }
1447   operands[1] = gen_compare_reg (UNORDERED);
1450 (define_expand "bordered"
1451   [(set (pc)
1452         (if_then_else (ordered (match_dup 1) (const_int 0))
1453                       (label_ref (match_operand 0 "" ""))
1454                       (pc)))]
1455   ""
1457   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1458     {
1459       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, ORDERED);
1460       emit_jump_insn (gen_bne (operands[0]));
1461       DONE;
1462     }
1463   operands[1] = gen_compare_reg (ORDERED);
1466 (define_expand "bungt"
1467   [(set (pc)
1468         (if_then_else (ungt (match_dup 1) (const_int 0))
1469                       (label_ref (match_operand 0 "" ""))
1470                       (pc)))]
1471   ""
1473   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1474     {
1475       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGT);
1476       emit_jump_insn (gen_bgt (operands[0]));
1477       DONE;
1478     }
1479   operands[1] = gen_compare_reg (UNGT);
1482 (define_expand "bunlt"
1483   [(set (pc)
1484         (if_then_else (unlt (match_dup 1) (const_int 0))
1485                       (label_ref (match_operand 0 "" ""))
1486                       (pc)))]
1487   ""
1489   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1490     {
1491       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLT);
1492       emit_jump_insn (gen_bne (operands[0]));
1493       DONE;
1494     }
1495   operands[1] = gen_compare_reg (UNLT);
1498 (define_expand "buneq"
1499   [(set (pc)
1500         (if_then_else (uneq (match_dup 1) (const_int 0))
1501                       (label_ref (match_operand 0 "" ""))
1502                       (pc)))]
1503   ""
1505   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1506     {
1507       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNEQ);
1508       emit_jump_insn (gen_beq (operands[0]));
1509       DONE;
1510     }
1511   operands[1] = gen_compare_reg (UNEQ);
1514 (define_expand "bunge"
1515   [(set (pc)
1516         (if_then_else (unge (match_dup 1) (const_int 0))
1517                       (label_ref (match_operand 0 "" ""))
1518                       (pc)))]
1519   ""
1521   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1522     {
1523       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGE);
1524       emit_jump_insn (gen_bne (operands[0]));
1525       DONE;
1526     }
1527   operands[1] = gen_compare_reg (UNGE);
1530 (define_expand "bunle"
1531   [(set (pc)
1532         (if_then_else (unle (match_dup 1) (const_int 0))
1533                       (label_ref (match_operand 0 "" ""))
1534                       (pc)))]
1535   ""
1537   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1538     {
1539       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLE);
1540       emit_jump_insn (gen_bne (operands[0]));
1541       DONE;
1542     }
1543   operands[1] = gen_compare_reg (UNLE);
1546 (define_expand "bltgt"
1547   [(set (pc)
1548         (if_then_else (ltgt (match_dup 1) (const_int 0))
1549                       (label_ref (match_operand 0 "" ""))
1550                       (pc)))]
1551   ""
1553   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1554     {
1555       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LTGT);
1556       emit_jump_insn (gen_bne (operands[0]));
1557       DONE;
1558     }
1559   operands[1] = gen_compare_reg (LTGT);
1562 ;; Now match both normal and inverted jump.
1564 ;; XXX fpcmp nop braindamage
1565 (define_insn "*normal_branch"
1566   [(set (pc)
1567         (if_then_else (match_operator 0 "noov_compare_operator"
1568                                       [(reg 100) (const_int 0)])
1569                       (label_ref (match_operand 1 "" ""))
1570                       (pc)))]
1571   ""
1573   return output_cbranch (operands[0], operands[1], 1, 0,
1574                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1575                          insn);
1577   [(set_attr "type" "branch")
1578    (set_attr "branch_type" "icc")])
1580 ;; XXX fpcmp nop braindamage
1581 (define_insn "*inverted_branch"
1582   [(set (pc)
1583         (if_then_else (match_operator 0 "noov_compare_operator"
1584                                       [(reg 100) (const_int 0)])
1585                       (pc)
1586                       (label_ref (match_operand 1 "" ""))))]
1587   ""
1589   return output_cbranch (operands[0], operands[1], 1, 1,
1590                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1591                          insn);
1593   [(set_attr "type" "branch")
1594    (set_attr "branch_type" "icc")])
1596 ;; XXX fpcmp nop braindamage
1597 (define_insn "*normal_fp_branch"
1598   [(set (pc)
1599         (if_then_else (match_operator 1 "comparison_operator"
1600                                       [(match_operand:CCFP 0 "fcc_register_operand" "c")
1601                                        (const_int 0)])
1602                       (label_ref (match_operand 2 "" ""))
1603                       (pc)))]
1604   ""
1606   return output_cbranch (operands[1], operands[2], 2, 0,
1607                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1608                          insn);
1610   [(set_attr "type" "branch")
1611    (set_attr "branch_type" "fcc")])
1613 ;; XXX fpcmp nop braindamage
1614 (define_insn "*inverted_fp_branch"
1615   [(set (pc)
1616         (if_then_else (match_operator 1 "comparison_operator"
1617                                       [(match_operand:CCFP 0 "fcc_register_operand" "c")
1618                                        (const_int 0)])
1619                       (pc)
1620                       (label_ref (match_operand 2 "" ""))))]
1621   ""
1623   return output_cbranch (operands[1], operands[2], 2, 1,
1624                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1625                          insn);
1627   [(set_attr "type" "branch")
1628    (set_attr "branch_type" "fcc")])
1630 ;; XXX fpcmp nop braindamage
1631 (define_insn "*normal_fpe_branch"
1632   [(set (pc)
1633         (if_then_else (match_operator 1 "comparison_operator"
1634                                       [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1635                                        (const_int 0)])
1636                       (label_ref (match_operand 2 "" ""))
1637                       (pc)))]
1638   ""
1640   return output_cbranch (operands[1], operands[2], 2, 0,
1641                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1642                          insn);
1644   [(set_attr "type" "branch")
1645    (set_attr "branch_type" "fcc")])
1647 ;; XXX fpcmp nop braindamage
1648 (define_insn "*inverted_fpe_branch"
1649   [(set (pc)
1650         (if_then_else (match_operator 1 "comparison_operator"
1651                                       [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1652                                        (const_int 0)])
1653                       (pc)
1654                       (label_ref (match_operand 2 "" ""))))]
1655   ""
1657   return output_cbranch (operands[1], operands[2], 2, 1,
1658                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1659                          insn);
1661   [(set_attr "type" "branch")
1662    (set_attr "branch_type" "fcc")])
1664 ;; SPARC V9-specific jump insns.  None of these are guaranteed to be
1665 ;; in the architecture.
1667 ;; There are no 32 bit brreg insns.
1669 ;; XXX
1670 (define_insn "*normal_int_branch_sp64"
1671   [(set (pc)
1672         (if_then_else (match_operator 0 "v9_register_compare_operator"
1673                                       [(match_operand:DI 1 "register_operand" "r")
1674                                        (const_int 0)])
1675                       (label_ref (match_operand 2 "" ""))
1676                       (pc)))]
1677   "TARGET_ARCH64"
1679   return output_v9branch (operands[0], operands[2], 1, 2, 0,
1680                           final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1681                           insn);
1683   [(set_attr "type" "branch")
1684    (set_attr "branch_type" "reg")])
1686 ;; XXX
1687 (define_insn "*inverted_int_branch_sp64"
1688   [(set (pc)
1689         (if_then_else (match_operator 0 "v9_register_compare_operator"
1690                                       [(match_operand:DI 1 "register_operand" "r")
1691                                        (const_int 0)])
1692                       (pc)
1693                       (label_ref (match_operand 2 "" ""))))]
1694   "TARGET_ARCH64"
1696   return output_v9branch (operands[0], operands[2], 1, 2, 1,
1697                           final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1698                           insn);
1700   [(set_attr "type" "branch")
1701    (set_attr "branch_type" "reg")])
1704 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1706 ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic
1707 ;; value subject to a PC-relative relocation.  Operand 2 is a helper function
1708 ;; that adds the PC value at the call point to operand 0.
1710 (define_insn "load_pcrel_sym<P:mode>"
1711   [(set (match_operand:P 0 "register_operand" "=r")
1712         (unspec:P [(match_operand:P 1 "symbolic_operand" "")
1713                    (match_operand:P 2 "call_address_operand" "")] UNSPEC_LOAD_PCREL_SYM))
1714    (clobber (reg:P 15))]
1715   ""
1717   if (flag_delayed_branch)
1718     return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0";
1719   else
1720     return "sethi\t%%hi(%a1-8), %0\n\tadd\t%0, %%lo(%a1-4), %0\n\tcall\t%a2\n\t nop";
1722   [(set (attr "type") (const_string "multi"))
1723    (set (attr "length")
1724         (if_then_else (eq_attr "delayed_branch" "true")
1725                       (const_int 3)
1726                       (const_int 4)))])
1729 ;; Integer move instructions
1731 (define_expand "movqi"
1732   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1733         (match_operand:QI 1 "general_operand" ""))]
1734   ""
1736   if (sparc_expand_move (QImode, operands))
1737     DONE;
1740 (define_insn "*movqi_insn"
1741   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1742         (match_operand:QI 1 "input_operand"   "rI,m,rJ"))]
1743   "(register_operand (operands[0], QImode)
1744     || register_or_zero_operand (operands[1], QImode))"
1745   "@
1746    mov\t%1, %0
1747    ldub\t%1, %0
1748    stb\t%r1, %0"
1749   [(set_attr "type" "*,load,store")
1750    (set_attr "us3load_type" "*,3cycle,*")])
1752 (define_expand "movhi"
1753   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1754         (match_operand:HI 1 "general_operand" ""))]
1755   ""
1757   if (sparc_expand_move (HImode, operands))
1758     DONE;
1761 (define_insn "*movhi_insn"
1762   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1763         (match_operand:HI 1 "input_operand"   "rI,K,m,rJ"))]
1764   "(register_operand (operands[0], HImode)
1765     || register_or_zero_operand (operands[1], HImode))"
1766   "@
1767    mov\t%1, %0
1768    sethi\t%%hi(%a1), %0
1769    lduh\t%1, %0
1770    sth\t%r1, %0"
1771   [(set_attr "type" "*,*,load,store")
1772    (set_attr "us3load_type" "*,*,3cycle,*")])
1774 ;; We always work with constants here.
1775 (define_insn "*movhi_lo_sum"
1776   [(set (match_operand:HI 0 "register_operand" "=r")
1777         (ior:HI (match_operand:HI 1 "register_operand" "%r")
1778                 (match_operand:HI 2 "small_int_operand" "I")))]
1779   ""
1780   "or\t%1, %2, %0")
1782 (define_expand "movsi"
1783   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1784         (match_operand:SI 1 "general_operand" ""))]
1785   ""
1787   if (sparc_expand_move (SImode, operands))
1788     DONE;
1791 (define_insn "*movsi_insn"
1792   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m,!f,!f,!m,d")
1793         (match_operand:SI 1 "input_operand"   "rI,K,m,rJ,f,m,f,J"))]
1794   "(register_operand (operands[0], SImode)
1795     || register_or_zero_operand (operands[1], SImode))"
1796   "@
1797    mov\t%1, %0
1798    sethi\t%%hi(%a1), %0
1799    ld\t%1, %0
1800    st\t%r1, %0
1801    fmovs\t%1, %0
1802    ld\t%1, %0
1803    st\t%1, %0
1804    fzeros\t%0"
1805   [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga")])
1807 (define_insn "*movsi_lo_sum"
1808   [(set (match_operand:SI 0 "register_operand" "=r")
1809         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1810                    (match_operand:SI 2 "immediate_operand" "in")))]
1811   ""
1812   "or\t%1, %%lo(%a2), %0")
1814 (define_insn "*movsi_high"
1815   [(set (match_operand:SI 0 "register_operand" "=r")
1816         (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1817   ""
1818   "sethi\t%%hi(%a1), %0")
1820 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1821 ;; so that CSE won't optimize the address computation away.
1822 (define_insn "movsi_lo_sum_pic"
1823   [(set (match_operand:SI 0 "register_operand" "=r")
1824         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1825                    (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1826   "flag_pic"
1827   "or\t%1, %%lo(%a2), %0")
1829 (define_insn "movsi_high_pic"
1830   [(set (match_operand:SI 0 "register_operand" "=r")
1831         (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1832   "flag_pic && check_pic (1)"
1833   "sethi\t%%hi(%a1), %0")
1835 (define_expand "movsi_pic_label_ref"
1836   [(set (match_dup 3) (high:SI
1837      (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1838                  (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1839    (set (match_dup 4) (lo_sum:SI (match_dup 3)
1840      (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1841    (set (match_operand:SI 0 "register_operand" "=r")
1842         (minus:SI (match_dup 5) (match_dup 4)))]
1843   "flag_pic"
1845   current_function_uses_pic_offset_table = 1;
1846   operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1847   if (!can_create_pseudo_p ())
1848     {
1849       operands[3] = operands[0];
1850       operands[4] = operands[0];
1851     }
1852   else
1853     {
1854       operands[3] = gen_reg_rtx (SImode);
1855       operands[4] = gen_reg_rtx (SImode);
1856     }
1857   operands[5] = pic_offset_table_rtx;
1860 (define_insn "*movsi_high_pic_label_ref"
1861   [(set (match_operand:SI 0 "register_operand" "=r")
1862       (high:SI
1863         (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1864                     (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1865   "flag_pic"
1866   "sethi\t%%hi(%a2-(%a1-.)), %0")
1868 (define_insn "*movsi_lo_sum_pic_label_ref"
1869   [(set (match_operand:SI 0 "register_operand" "=r")
1870       (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1871         (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
1872                     (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1873   "flag_pic"
1874   "or\t%1, %%lo(%a3-(%a2-.)), %0")
1876 ;; Set up the PIC register for VxWorks.
1878 (define_expand "vxworks_load_got"
1879   [(set (match_dup 0)
1880         (high:SI (match_dup 1)))
1881    (set (match_dup 0)
1882         (mem:SI (lo_sum:SI (match_dup 0) (match_dup 1))))
1883    (set (match_dup 0)
1884         (mem:SI (lo_sum:SI (match_dup 0) (match_dup 2))))]
1885   "TARGET_VXWORKS_RTP"
1887   operands[0] = pic_offset_table_rtx;
1888   operands[1] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_BASE);
1889   operands[2] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_INDEX);
1892 (define_expand "movdi"
1893   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1894         (match_operand:DI 1 "general_operand" ""))]
1895   ""
1897   if (sparc_expand_move (DImode, operands))
1898     DONE;
1901 ;; Be careful, fmovd does not exist when !v9.
1902 ;; We match MEM moves directly when we have correct even
1903 ;; numbered registers, but fall into splits otherwise.
1904 ;; The constraint ordering here is really important to
1905 ;; avoid insane problems in reload, especially for patterns
1906 ;; of the form:
1908 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
1909 ;;                       (const_int -5016)))
1910 ;;      (reg:DI 2 %g2))
1913 (define_insn "*movdi_insn_sp32"
1914   [(set (match_operand:DI 0 "nonimmediate_operand"
1915                                 "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
1916         (match_operand:DI 1 "input_operand"
1917                                 " J,U,T,r,o,i,r, f, T, o, f, f"))]
1918   "! TARGET_V9
1919    && (register_operand (operands[0], DImode)
1920        || register_or_zero_operand (operands[1], DImode))"
1921   "@
1922    #
1923    std\t%1, %0
1924    ldd\t%1, %0
1925    #
1926    #
1927    #
1928    #
1929    std\t%1, %0
1930    ldd\t%1, %0
1931    #
1932    #
1933    #"
1934   [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
1935    (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
1937 (define_insn "*movdi_insn_sp32_v9"
1938   [(set (match_operand:DI 0 "nonimmediate_operand"
1939                                         "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?e,?e,?W")
1940         (match_operand:DI 1 "input_operand"
1941                                         " J,J,U,T,r,o,i,r, f, T, o, f, e, W, e"))]
1942   "! TARGET_ARCH64
1943    && TARGET_V9
1944    && (register_operand (operands[0], DImode)
1945        || register_or_zero_operand (operands[1], DImode))"
1946   "@
1947    stx\t%%g0, %0
1948    #
1949    std\t%1, %0
1950    ldd\t%1, %0
1951    #
1952    #
1953    #
1954    #
1955    std\t%1, %0
1956    ldd\t%1, %0
1957    #
1958    #
1959    fmovd\\t%1, %0
1960    ldd\\t%1, %0
1961    std\\t%1, %0"
1962   [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,fpload,fpstore")
1963    (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,*,*")
1964    (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])
1966 (define_insn "*movdi_insn_sp64"
1967   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,m,?e,?e,?W,b")
1968         (match_operand:DI 1 "input_operand"   "rI,N,m,rJ,e,W,e,J"))]
1969   "TARGET_ARCH64
1970    && (register_operand (operands[0], DImode)
1971        || register_or_zero_operand (operands[1], DImode))"
1972   "@
1973    mov\t%1, %0
1974    sethi\t%%hi(%a1), %0
1975    ldx\t%1, %0
1976    stx\t%r1, %0
1977    fmovd\t%1, %0
1978    ldd\t%1, %0
1979    std\t%1, %0
1980    fzero\t%0"
1981   [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga")
1982    (set_attr "fptype" "*,*,*,*,double,*,*,double")])
1984 (define_expand "movdi_pic_label_ref"
1985   [(set (match_dup 3) (high:DI
1986      (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1987                  (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1988    (set (match_dup 4) (lo_sum:DI (match_dup 3)
1989      (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1990    (set (match_operand:DI 0 "register_operand" "=r")
1991         (minus:DI (match_dup 5) (match_dup 4)))]
1992   "TARGET_ARCH64 && flag_pic"
1994   current_function_uses_pic_offset_table = 1;
1995   operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1996   if (!can_create_pseudo_p ())
1997     {
1998       operands[3] = operands[0];
1999       operands[4] = operands[0];
2000     }
2001   else
2002     {
2003       operands[3] = gen_reg_rtx (DImode);
2004       operands[4] = gen_reg_rtx (DImode);
2005     }
2006   operands[5] = pic_offset_table_rtx;
2009 (define_insn "*movdi_high_pic_label_ref"
2010   [(set (match_operand:DI 0 "register_operand" "=r")
2011         (high:DI
2012           (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2013                       (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2014   "TARGET_ARCH64 && flag_pic"
2015   "sethi\t%%hi(%a2-(%a1-.)), %0")
2017 (define_insn "*movdi_lo_sum_pic_label_ref"
2018   [(set (match_operand:DI 0 "register_operand" "=r")
2019       (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2020         (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
2021                     (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2022   "TARGET_ARCH64 && flag_pic"
2023   "or\t%1, %%lo(%a3-(%a2-.)), %0")
2025 ;; SPARC-v9 code model support insns.  See sparc_emit_set_symbolic_const64
2026 ;; in sparc.c to see what is going on here... PIC stuff comes first.
2028 (define_insn "movdi_lo_sum_pic"
2029   [(set (match_operand:DI 0 "register_operand" "=r")
2030         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2031                    (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
2032   "TARGET_ARCH64 && flag_pic"
2033   "or\t%1, %%lo(%a2), %0")
2035 (define_insn "movdi_high_pic"
2036   [(set (match_operand:DI 0 "register_operand" "=r")
2037         (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
2038   "TARGET_ARCH64 && flag_pic && check_pic (1)"
2039   "sethi\t%%hi(%a1), %0")
2041 (define_insn "*sethi_di_medlow_embmedany_pic"
2042   [(set (match_operand:DI 0 "register_operand" "=r")
2043         (high:DI (match_operand:DI 1 "medium_pic_operand" "")))]
2044   "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
2045   "sethi\t%%hi(%a1), %0")
2047 (define_insn "*sethi_di_medlow"
2048   [(set (match_operand:DI 0 "register_operand" "=r")
2049         (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
2050   "TARGET_CM_MEDLOW && check_pic (1)"
2051   "sethi\t%%hi(%a1), %0")
2053 (define_insn "*losum_di_medlow"
2054   [(set (match_operand:DI 0 "register_operand" "=r")
2055         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2056                    (match_operand:DI 2 "symbolic_operand" "")))]
2057   "TARGET_CM_MEDLOW"
2058   "or\t%1, %%lo(%a2), %0")
2060 (define_insn "seth44"
2061   [(set (match_operand:DI 0 "register_operand" "=r")
2062         (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
2063   "TARGET_CM_MEDMID"
2064   "sethi\t%%h44(%a1), %0")
2066 (define_insn "setm44"
2067   [(set (match_operand:DI 0 "register_operand" "=r")
2068         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2069                    (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
2070   "TARGET_CM_MEDMID"
2071   "or\t%1, %%m44(%a2), %0")
2073 (define_insn "setl44"
2074   [(set (match_operand:DI 0 "register_operand" "=r")
2075         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2076                    (match_operand:DI 2 "symbolic_operand" "")))]
2077   "TARGET_CM_MEDMID"
2078   "or\t%1, %%l44(%a2), %0")
2080 (define_insn "sethh"
2081   [(set (match_operand:DI 0 "register_operand" "=r")
2082         (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
2083   "TARGET_CM_MEDANY"
2084   "sethi\t%%hh(%a1), %0")
2086 (define_insn "setlm"
2087   [(set (match_operand:DI 0 "register_operand" "=r")
2088         (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
2089   "TARGET_CM_MEDANY"
2090   "sethi\t%%lm(%a1), %0")
2092 (define_insn "sethm"
2093   [(set (match_operand:DI 0 "register_operand" "=r")
2094         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2095                    (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
2096   "TARGET_CM_MEDANY"
2097   "or\t%1, %%hm(%a2), %0")
2099 (define_insn "setlo"
2100   [(set (match_operand:DI 0 "register_operand" "=r")
2101         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2102                    (match_operand:DI 2 "symbolic_operand" "")))]
2103   "TARGET_CM_MEDANY"
2104   "or\t%1, %%lo(%a2), %0")
2106 (define_insn "embmedany_sethi"
2107   [(set (match_operand:DI 0 "register_operand" "=r")
2108         (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
2109   "TARGET_CM_EMBMEDANY && check_pic (1)"
2110   "sethi\t%%hi(%a1), %0")
2112 (define_insn "embmedany_losum"
2113   [(set (match_operand:DI 0 "register_operand" "=r")
2114         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2115                    (match_operand:DI 2 "data_segment_operand" "")))]
2116   "TARGET_CM_EMBMEDANY"
2117   "add\t%1, %%lo(%a2), %0")
2119 (define_insn "embmedany_brsum"
2120   [(set (match_operand:DI 0 "register_operand" "=r")
2121         (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
2122   "TARGET_CM_EMBMEDANY"
2123   "add\t%1, %_, %0")
2125 (define_insn "embmedany_textuhi"
2126   [(set (match_operand:DI 0 "register_operand" "=r")
2127         (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
2128   "TARGET_CM_EMBMEDANY && check_pic (1)"
2129   "sethi\t%%uhi(%a1), %0")
2131 (define_insn "embmedany_texthi"
2132   [(set (match_operand:DI 0 "register_operand" "=r")
2133         (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
2134   "TARGET_CM_EMBMEDANY && check_pic (1)"
2135   "sethi\t%%hi(%a1), %0")
2137 (define_insn "embmedany_textulo"
2138   [(set (match_operand:DI 0 "register_operand" "=r")
2139         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2140                    (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
2141   "TARGET_CM_EMBMEDANY"
2142   "or\t%1, %%ulo(%a2), %0")
2144 (define_insn "embmedany_textlo"
2145   [(set (match_operand:DI 0 "register_operand" "=r")
2146         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2147                    (match_operand:DI 2 "text_segment_operand" "")))]
2148   "TARGET_CM_EMBMEDANY"
2149   "or\t%1, %%lo(%a2), %0")
2151 ;; Now some patterns to help reload out a bit.
2152 (define_expand "reload_indi"
2153   [(parallel [(match_operand:DI 0 "register_operand" "=r")
2154               (match_operand:DI 1 "immediate_operand" "")
2155               (match_operand:TI 2 "register_operand" "=&r")])]
2156   "(TARGET_CM_MEDANY
2157     || TARGET_CM_EMBMEDANY)
2158    && ! flag_pic"
2160   sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2161   DONE;
2164 (define_expand "reload_outdi"
2165   [(parallel [(match_operand:DI 0 "register_operand" "=r")
2166               (match_operand:DI 1 "immediate_operand" "")
2167               (match_operand:TI 2 "register_operand" "=&r")])]
2168   "(TARGET_CM_MEDANY
2169     || TARGET_CM_EMBMEDANY)
2170    && ! flag_pic"
2172   sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2173   DONE;
2176 ;; Split up putting CONSTs and REGs into DI regs when !arch64
2177 (define_split
2178   [(set (match_operand:DI 0 "register_operand" "")
2179         (match_operand:DI 1 "const_int_operand" ""))]
2180   "! TARGET_ARCH64 && reload_completed"
2181   [(clobber (const_int 0))]
2183 #if HOST_BITS_PER_WIDE_INT == 32
2184   emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2185                         (INTVAL (operands[1]) < 0) ?
2186                         constm1_rtx :
2187                         const0_rtx));
2188   emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2189                         operands[1]));
2190 #else
2191   unsigned int low, high;
2193   low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
2194   high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
2195   emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
2197   /* Slick... but this trick loses if this subreg constant part
2198      can be done in one insn.  */
2199   if (low == high
2200       && ! SPARC_SETHI32_P (high)
2201       && ! SPARC_SIMM13_P (high))
2202     emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2203                           gen_highpart (SImode, operands[0])));
2204   else
2205     emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
2206 #endif
2207   DONE;
2210 (define_split
2211   [(set (match_operand:DI 0 "register_operand" "")
2212         (match_operand:DI 1 "const_double_operand" ""))]
2213   "reload_completed
2214    && (! TARGET_V9
2215        || (! TARGET_ARCH64
2216            && ((GET_CODE (operands[0]) == REG
2217                 && REGNO (operands[0]) < 32)
2218                || (GET_CODE (operands[0]) == SUBREG
2219                    && GET_CODE (SUBREG_REG (operands[0])) == REG
2220                    && REGNO (SUBREG_REG (operands[0])) < 32))))"
2221   [(clobber (const_int 0))]
2223   emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2224                         GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
2226   /* Slick... but this trick loses if this subreg constant part
2227      can be done in one insn.  */
2228   if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
2229       && ! SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
2230       && ! SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1])))
2231     {
2232       emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2233                             gen_highpart (SImode, operands[0])));
2234     }
2235   else
2236     {
2237       emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2238                             GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
2239     }
2240   DONE;
2243 (define_split
2244   [(set (match_operand:DI 0 "register_operand" "")
2245         (match_operand:DI 1 "register_operand" ""))]
2246   "reload_completed
2247    && (! TARGET_V9
2248        || (! TARGET_ARCH64
2249            && ((GET_CODE (operands[0]) == REG
2250                 && REGNO (operands[0]) < 32)
2251                || (GET_CODE (operands[0]) == SUBREG
2252                    && GET_CODE (SUBREG_REG (operands[0])) == REG
2253                    && REGNO (SUBREG_REG (operands[0])) < 32))))"
2254   [(clobber (const_int 0))]
2256   rtx set_dest = operands[0];
2257   rtx set_src = operands[1];
2258   rtx dest1, dest2;
2259   rtx src1, src2;
2261   dest1 = gen_highpart (SImode, set_dest);
2262   dest2 = gen_lowpart (SImode, set_dest);
2263   src1 = gen_highpart (SImode, set_src);
2264   src2 = gen_lowpart (SImode, set_src);
2266   /* Now emit using the real source and destination we found, swapping
2267      the order if we detect overlap.  */
2268   if (reg_overlap_mentioned_p (dest1, src2))
2269     {
2270       emit_insn (gen_movsi (dest2, src2));
2271       emit_insn (gen_movsi (dest1, src1));
2272     }
2273   else
2274     {
2275       emit_insn (gen_movsi (dest1, src1));
2276       emit_insn (gen_movsi (dest2, src2));
2277     }
2278   DONE;
2281 ;; Now handle the cases of memory moves from/to non-even
2282 ;; DI mode register pairs.
2283 (define_split
2284   [(set (match_operand:DI 0 "register_operand" "")
2285         (match_operand:DI 1 "memory_operand" ""))]
2286   "(! TARGET_ARCH64
2287     && reload_completed
2288     && sparc_splitdi_legitimate (operands[0], operands[1]))"
2289   [(clobber (const_int 0))]
2291   rtx word0 = adjust_address (operands[1], SImode, 0);
2292   rtx word1 = adjust_address (operands[1], SImode, 4);
2293   rtx high_part = gen_highpart (SImode, operands[0]);
2294   rtx low_part = gen_lowpart (SImode, operands[0]);
2296   if (reg_overlap_mentioned_p (high_part, word1))
2297     {
2298       emit_insn (gen_movsi (low_part, word1));
2299       emit_insn (gen_movsi (high_part, word0));
2300     }
2301   else
2302     {
2303       emit_insn (gen_movsi (high_part, word0));
2304       emit_insn (gen_movsi (low_part, word1));
2305     }
2306   DONE;
2309 (define_split
2310   [(set (match_operand:DI 0 "memory_operand" "")
2311         (match_operand:DI 1 "register_operand" ""))]
2312   "(! TARGET_ARCH64
2313     && reload_completed
2314     && sparc_splitdi_legitimate (operands[1], operands[0]))"
2315   [(clobber (const_int 0))]
2317   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
2318                         gen_highpart (SImode, operands[1])));
2319   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
2320                         gen_lowpart (SImode, operands[1])));
2321   DONE;
2324 (define_split
2325   [(set (match_operand:DI 0 "memory_operand" "")
2326         (match_operand:DI 1 "const_zero_operand" ""))]
2327   "reload_completed
2328    && (! TARGET_V9
2329        || (! TARGET_ARCH64
2330            && ! mem_min_alignment (operands[0], 8)))
2331    && offsettable_memref_p (operands[0])"
2332   [(clobber (const_int 0))]
2334   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
2335   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
2336   DONE;
2340 ;; Floating point and vector move instructions
2342 ;; We don't define V1SI because SI should work just fine.
2343 (define_mode_iterator V32 [SF V2HI V4QI])
2345 ;; Yes, you guessed it right, the former movsf expander.
2346 (define_expand "mov<V32:mode>"
2347   [(set (match_operand:V32 0 "nonimmediate_operand" "")
2348         (match_operand:V32 1 "general_operand" ""))]
2349   "<V32:MODE>mode == SFmode || TARGET_VIS"
2351   if (sparc_expand_move (<V32:MODE>mode, operands))
2352     DONE;
2355 (define_insn "*movsf_insn"
2356   [(set (match_operand:V32 0 "nonimmediate_operand" "=d,f,*r,*r,*r,f,*r,m,m")
2357         (match_operand:V32 1 "input_operand"        "GY,f,*rRY,Q,S,m,m,f,*rGY"))]
2358   "TARGET_FPU
2359    && (register_operand (operands[0], <V32:MODE>mode)
2360        || register_or_zero_operand (operands[1], <V32:MODE>mode))"
2362   if (GET_CODE (operands[1]) == CONST_DOUBLE
2363       && (which_alternative == 2
2364           || which_alternative == 3
2365           || which_alternative == 4))
2366     {
2367       REAL_VALUE_TYPE r;
2368       long i;
2370       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2371       REAL_VALUE_TO_TARGET_SINGLE (r, i);
2372       operands[1] = GEN_INT (i);
2373     }
2375   switch (which_alternative)
2376     {
2377     case 0:
2378       return "fzeros\t%0";
2379     case 1:
2380       return "fmovs\t%1, %0";
2381     case 2:
2382       return "mov\t%1, %0";
2383     case 3:
2384       return "sethi\t%%hi(%a1), %0";
2385     case 4:
2386       return "#";
2387     case 5:
2388     case 6:
2389       return "ld\t%1, %0";
2390     case 7:
2391     case 8:
2392       return "st\t%r1, %0";
2393     default:
2394       gcc_unreachable ();
2395     }
2397   [(set_attr "type" "fga,fpmove,*,*,*,fpload,load,fpstore,store")])
2399 ;; Exactly the same as above, except that all `f' cases are deleted.
2400 ;; This is necessary to prevent reload from ever trying to use a `f' reg
2401 ;; when -mno-fpu.
2403 (define_insn "*movsf_insn_no_fpu"
2404   [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,m")
2405         (match_operand:SF 1 "input_operand"    "rR,Q,S,m,rG"))]
2406   "! TARGET_FPU
2407    && (register_operand (operands[0], SFmode)
2408        || register_or_zero_operand (operands[1], SFmode))"
2410   if (GET_CODE (operands[1]) == CONST_DOUBLE
2411       && (which_alternative == 0
2412           || which_alternative == 1
2413           || which_alternative == 2))
2414     {
2415       REAL_VALUE_TYPE r;
2416       long i;
2418       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2419       REAL_VALUE_TO_TARGET_SINGLE (r, i);
2420       operands[1] = GEN_INT (i);
2421     }
2423   switch (which_alternative)
2424     {
2425     case 0:
2426       return "mov\t%1, %0";
2427     case 1:
2428       return "sethi\t%%hi(%a1), %0";
2429     case 2:
2430       return "#";
2431     case 3:
2432       return "ld\t%1, %0";
2433     case 4:
2434       return "st\t%r1, %0";
2435     default:
2436       gcc_unreachable ();
2437     }
2439   [(set_attr "type" "*,*,*,load,store")])
2441 ;; The following 3 patterns build SFmode constants in integer registers.
2443 (define_insn "*movsf_lo_sum"
2444   [(set (match_operand:SF 0 "register_operand" "=r")
2445         (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
2446                    (match_operand:SF 2 "fp_const_high_losum_operand" "S")))]
2447   ""
2449   REAL_VALUE_TYPE r;
2450   long i;
2452   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
2453   REAL_VALUE_TO_TARGET_SINGLE (r, i);
2454   operands[2] = GEN_INT (i);
2455   return "or\t%1, %%lo(%a2), %0";
2458 (define_insn "*movsf_high"
2459   [(set (match_operand:SF 0 "register_operand" "=r")
2460         (high:SF (match_operand:SF 1 "fp_const_high_losum_operand" "S")))]
2461   ""
2463   REAL_VALUE_TYPE r;
2464   long i;
2466   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2467   REAL_VALUE_TO_TARGET_SINGLE (r, i);
2468   operands[1] = GEN_INT (i);
2469   return "sethi\t%%hi(%1), %0";
2472 (define_split
2473   [(set (match_operand:SF 0 "register_operand" "")
2474         (match_operand:SF 1 "fp_const_high_losum_operand" ""))]
2475   "REG_P (operands[0]) && REGNO (operands[0]) < 32"
2476   [(set (match_dup 0) (high:SF (match_dup 1)))
2477    (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
2479 (define_mode_iterator V64 [DF V2SI V4HI V8QI])
2481 ;; Yes, you again guessed it right, the former movdf expander.
2482 (define_expand "mov<V64:mode>"
2483   [(set (match_operand:V64 0 "nonimmediate_operand" "")
2484         (match_operand:V64 1 "general_operand" ""))]
2485   "<V64:MODE>mode == DFmode || TARGET_VIS"
2487   if (sparc_expand_move (<V64:MODE>mode, operands))
2488     DONE;
2491 ;; Be careful, fmovd does not exist when !v9.
2492 (define_insn "*movdf_insn_sp32"
2493   [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o")
2494         (match_operand:DF 1 "input_operand"    "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
2495   "TARGET_FPU
2496    && ! TARGET_V9
2497    && (register_operand (operands[0], DFmode)
2498        || register_or_zero_operand (operands[1], DFmode))"
2499   "@
2500   ldd\t%1, %0
2501   std\t%1, %0
2502   ldd\t%1, %0
2503   std\t%1, %0
2504   #
2505   #
2506   #
2507   #
2508   #
2509   #"
2510  [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
2511   (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
2513 (define_insn "*movdf_insn_sp32_no_fpu"
2514   [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
2515         (match_operand:DF 1 "input_operand"    "T,U,G,ro,r"))]
2516   "! TARGET_FPU
2517    && ! TARGET_V9
2518    && (register_operand (operands[0], DFmode)
2519        || register_or_zero_operand (operands[1], DFmode))"
2520   "@
2521   ldd\t%1, %0
2522   std\t%1, %0
2523   #
2524   #
2525   #"
2526   [(set_attr "type" "load,store,*,*,*")
2527    (set_attr "length" "*,*,2,2,2")])
2529 ;; We have available v9 double floats but not 64-bit integer registers.
2530 (define_insn "*movdf_insn_sp32_v9"
2531   [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,T,W,U,T,f,*r,o")
2532         (match_operand:V64 1 "input_operand" "GY,e,W#F,GY,e,T,U,o#F,*roGYF,*rGYf"))]
2533   "TARGET_FPU
2534    && TARGET_V9
2535    && ! TARGET_ARCH64
2536    && (register_operand (operands[0], <V64:MODE>mode)
2537        || register_or_zero_operand (operands[1], <V64:MODE>mode))"
2538   "@
2539   fzero\t%0
2540   fmovd\t%1, %0
2541   ldd\t%1, %0
2542   stx\t%r1, %0
2543   std\t%1, %0
2544   ldd\t%1, %0
2545   std\t%1, %0
2546   #
2547   #
2548   #"
2549   [(set_attr "type" "fga,fpmove,load,store,store,load,store,*,*,*")
2550    (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
2551    (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
2553 (define_insn "*movdf_insn_sp32_v9_no_fpu"
2554   [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
2555         (match_operand:DF 1 "input_operand"    "T,U,G,ro,rG"))]
2556   "! TARGET_FPU
2557    && TARGET_V9
2558    && ! TARGET_ARCH64
2559    && (register_operand (operands[0], DFmode)
2560        || register_or_zero_operand (operands[1], DFmode))"
2561   "@
2562   ldd\t%1, %0
2563   std\t%1, %0
2564   stx\t%r1, %0
2565   #
2566   #"
2567   [(set_attr "type" "load,store,store,*,*")
2568    (set_attr "length" "*,*,*,2,2")])
2570 ;; We have available both v9 double floats and 64-bit integer registers.
2571 (define_insn "*movdf_insn_sp64"
2572   [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,W,*r,*r,m,*r")
2573         (match_operand:V64 1 "input_operand"    "GY,e,W#F,e,*rGY,m,*rGY,F"))]
2574   "TARGET_FPU
2575    && TARGET_ARCH64
2576    && (register_operand (operands[0], <V64:MODE>mode)
2577        || register_or_zero_operand (operands[1], <V64:MODE>mode))"
2578   "@
2579   fzero\t%0
2580   fmovd\t%1, %0
2581   ldd\t%1, %0
2582   std\t%1, %0
2583   mov\t%r1, %0
2584   ldx\t%1, %0
2585   stx\t%r1, %0
2586   #"
2587   [(set_attr "type" "fga,fpmove,load,store,*,load,store,*")
2588    (set_attr "length" "*,*,*,*,*,*,*,2")
2589    (set_attr "fptype" "double,double,*,*,*,*,*,*")])
2591 (define_insn "*movdf_insn_sp64_no_fpu"
2592   [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
2593         (match_operand:DF 1 "input_operand"    "r,m,rG"))]
2594   "! TARGET_FPU
2595    && TARGET_ARCH64
2596    && (register_operand (operands[0], DFmode)
2597        || register_or_zero_operand (operands[1], DFmode))"
2598   "@
2599   mov\t%1, %0
2600   ldx\t%1, %0
2601   stx\t%r1, %0"
2602   [(set_attr "type" "*,load,store")])
2604 ;; This pattern build DFmode constants in integer registers.
2605 (define_split
2606   [(set (match_operand:DF 0 "register_operand" "")
2607         (match_operand:DF 1 "const_double_operand" ""))]
2608   "TARGET_FPU
2609    && (GET_CODE (operands[0]) == REG
2610        && REGNO (operands[0]) < 32)
2611    && ! const_zero_operand(operands[1], DFmode)
2612    && reload_completed"
2613   [(clobber (const_int 0))]
2615   REAL_VALUE_TYPE r;
2616   long l[2];
2618   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2619   REAL_VALUE_TO_TARGET_DOUBLE (r, l);
2620   operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
2622   if (TARGET_ARCH64)
2623     {
2624 #if HOST_BITS_PER_WIDE_INT == 32
2625       gcc_unreachable ();
2626 #else
2627       HOST_WIDE_INT val;
2629       val = ((HOST_WIDE_INT)(unsigned long)l[1] |
2630              ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
2631       emit_insn (gen_movdi (operands[0], gen_int_mode (val, DImode)));
2632 #endif
2633     }
2634   else
2635     {
2636       emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2637                             gen_int_mode (l[0], SImode)));
2639       /* Slick... but this trick loses if this subreg constant part
2640          can be done in one insn.  */
2641       if (l[1] == l[0]
2642           && ! SPARC_SETHI32_P (l[0])
2643           && ! SPARC_SIMM13_P (l[0]))
2644         {
2645           emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2646                                 gen_highpart (SImode, operands[0])));
2647         }
2648       else
2649         {
2650           emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2651                                 gen_int_mode (l[1], SImode)));
2652         }
2653     }
2654   DONE;
2657 ;; Ok, now the splits to handle all the multi insn and
2658 ;; mis-aligned memory address cases.
2659 ;; In these splits please take note that we must be
2660 ;; careful when V9 but not ARCH64 because the integer
2661 ;; register DFmode cases must be handled.
2662 (define_split
2663   [(set (match_operand:V64 0 "register_operand" "")
2664         (match_operand:V64 1 "register_operand" ""))]
2665   "(! TARGET_V9
2666     || (! TARGET_ARCH64
2667         && ((GET_CODE (operands[0]) == REG
2668              && REGNO (operands[0]) < 32)
2669             || (GET_CODE (operands[0]) == SUBREG
2670                 && GET_CODE (SUBREG_REG (operands[0])) == REG
2671                 && REGNO (SUBREG_REG (operands[0])) < 32))))
2672    && reload_completed"
2673   [(clobber (const_int 0))]
2675   rtx set_dest = operands[0];
2676   rtx set_src = operands[1];
2677   rtx dest1, dest2;
2678   rtx src1, src2;
2679   enum machine_mode half_mode;
2681   /* We can be expanded for DFmode or integral vector modes.  */
2682   if (<V64:MODE>mode == DFmode)
2683     half_mode = SFmode;
2684   else
2685     half_mode = SImode;
2686   
2687   dest1 = gen_highpart (half_mode, set_dest);
2688   dest2 = gen_lowpart (half_mode, set_dest);
2689   src1 = gen_highpart (half_mode, set_src);
2690   src2 = gen_lowpart (half_mode, set_src);
2692   /* Now emit using the real source and destination we found, swapping
2693      the order if we detect overlap.  */
2694   if (reg_overlap_mentioned_p (dest1, src2))
2695     {
2696       emit_move_insn_1 (dest2, src2);
2697       emit_move_insn_1 (dest1, src1);
2698     }
2699   else
2700     {
2701       emit_move_insn_1 (dest1, src1);
2702       emit_move_insn_1 (dest2, src2);
2703     }
2704   DONE;
2707 (define_split
2708   [(set (match_operand:V64 0 "register_operand" "")
2709         (match_operand:V64 1 "memory_operand" ""))]
2710   "reload_completed
2711    && ! TARGET_ARCH64
2712    && (((REGNO (operands[0]) % 2) != 0)
2713        || ! mem_min_alignment (operands[1], 8))
2714    && offsettable_memref_p (operands[1])"
2715   [(clobber (const_int 0))]
2717   enum machine_mode half_mode;
2718   rtx word0, word1;
2720   /* We can be expanded for DFmode or integral vector modes.  */
2721   if (<V64:MODE>mode == DFmode)
2722     half_mode = SFmode;
2723   else
2724     half_mode = SImode;
2726   word0 = adjust_address (operands[1], half_mode, 0);
2727   word1 = adjust_address (operands[1], half_mode, 4);
2729   if (reg_overlap_mentioned_p (gen_highpart (half_mode, operands[0]), word1))
2730     {
2731       emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2732       emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2733     }
2734   else
2735     {
2736       emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2737       emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2738     }
2739   DONE;
2742 (define_split
2743   [(set (match_operand:V64 0 "memory_operand" "")
2744         (match_operand:V64 1 "register_operand" ""))]
2745   "reload_completed
2746    && ! TARGET_ARCH64
2747    && (((REGNO (operands[1]) % 2) != 0)
2748        || ! mem_min_alignment (operands[0], 8))
2749    && offsettable_memref_p (operands[0])"
2750   [(clobber (const_int 0))]
2752   enum machine_mode half_mode;
2753   rtx word0, word1;
2755   /* We can be expanded for DFmode or integral vector modes.  */
2756   if (<V64:MODE>mode == DFmode)
2757     half_mode = SFmode;
2758   else
2759     half_mode = SImode;
2761   word0 = adjust_address (operands[0], half_mode, 0);
2762   word1 = adjust_address (operands[0], half_mode, 4);
2764   emit_move_insn_1 (word0, gen_highpart (half_mode, operands[1]));
2765   emit_move_insn_1 (word1, gen_lowpart (half_mode, operands[1]));
2766   DONE;
2769 (define_split
2770   [(set (match_operand:V64 0 "memory_operand" "")
2771         (match_operand:V64 1 "const_zero_operand" ""))]
2772   "reload_completed
2773    && (! TARGET_V9
2774        || (! TARGET_ARCH64
2775            && ! mem_min_alignment (operands[0], 8)))
2776    && offsettable_memref_p (operands[0])"
2777   [(clobber (const_int 0))]
2779   enum machine_mode half_mode;
2780   rtx dest1, dest2;
2782   /* We can be expanded for DFmode or integral vector modes.  */
2783   if (<V64:MODE>mode == DFmode)
2784     half_mode = SFmode;
2785   else
2786     half_mode = SImode;
2788   dest1 = adjust_address (operands[0], half_mode, 0);
2789   dest2 = adjust_address (operands[0], half_mode, 4);
2791   emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2792   emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2793   DONE;
2796 (define_split
2797   [(set (match_operand:V64 0 "register_operand" "")
2798         (match_operand:V64 1 "const_zero_operand" ""))]
2799   "reload_completed
2800    && ! TARGET_ARCH64
2801    && ((GET_CODE (operands[0]) == REG
2802         && REGNO (operands[0]) < 32)
2803        || (GET_CODE (operands[0]) == SUBREG
2804            && GET_CODE (SUBREG_REG (operands[0])) == REG
2805            && REGNO (SUBREG_REG (operands[0])) < 32))"
2806   [(clobber (const_int 0))]
2808   enum machine_mode half_mode;
2809   rtx set_dest = operands[0];
2810   rtx dest1, dest2;
2812   /* We can be expanded for DFmode or integral vector modes.  */
2813   if (<V64:MODE>mode == DFmode)
2814     half_mode = SFmode;
2815   else
2816     half_mode = SImode;
2818   dest1 = gen_highpart (half_mode, set_dest);
2819   dest2 = gen_lowpart (half_mode, set_dest);
2820   emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2821   emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2822   DONE;
2825 (define_expand "movtf"
2826   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2827         (match_operand:TF 1 "general_operand" ""))]
2828   ""
2830   if (sparc_expand_move (TFmode, operands))
2831     DONE;
2834 (define_insn "*movtf_insn_sp32"
2835   [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,U,r")
2836         (match_operand:TF 1 "input_operand"    "G,oe,GeUr,o,roG"))]
2837   "TARGET_FPU
2838    && ! TARGET_ARCH64
2839    && (register_operand (operands[0], TFmode)
2840        || register_or_zero_operand (operands[1], TFmode))"
2841   "#"
2842   [(set_attr "length" "4")])
2844 ;; Exactly the same as above, except that all `e' cases are deleted.
2845 ;; This is necessary to prevent reload from ever trying to use a `e' reg
2846 ;; when -mno-fpu.
2848 (define_insn "*movtf_insn_sp32_no_fpu"
2849   [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
2850         (match_operand:TF 1 "input_operand"    "G,o,U,roG,r"))]
2851   "! TARGET_FPU
2852    && ! TARGET_ARCH64
2853    && (register_operand (operands[0], TFmode)
2854        || register_or_zero_operand (operands[1], TFmode))"
2855   "#"
2856   [(set_attr "length" "4")])
2858 (define_insn "*movtf_insn_sp64"
2859   [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,r")
2860         (match_operand:TF 1 "input_operand"    "G,oe,Ger,roG"))]
2861   "TARGET_FPU
2862    && TARGET_ARCH64
2863    && ! TARGET_HARD_QUAD
2864    && (register_operand (operands[0], TFmode)
2865        || register_or_zero_operand (operands[1], TFmode))"
2866   "#"
2867   [(set_attr "length" "2")])
2869 (define_insn "*movtf_insn_sp64_hq"
2870   [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,e,m,o,r")
2871         (match_operand:TF 1 "input_operand"    "G,e,m,e,rG,roG"))]
2872   "TARGET_FPU
2873    && TARGET_ARCH64
2874    && TARGET_HARD_QUAD
2875    && (register_operand (operands[0], TFmode)
2876        || register_or_zero_operand (operands[1], TFmode))"
2877   "@
2878   #
2879   fmovq\t%1, %0
2880   ldq\t%1, %0
2881   stq\t%1, %0
2882   #
2883   #"
2884   [(set_attr "type" "*,fpmove,fpload,fpstore,*,*")
2885    (set_attr "length" "2,*,*,*,2,2")])
2887 (define_insn "*movtf_insn_sp64_no_fpu"
2888   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
2889         (match_operand:TF 1 "input_operand"    "orG,rG"))]
2890   "! TARGET_FPU
2891    && TARGET_ARCH64
2892    && (register_operand (operands[0], TFmode)
2893        || register_or_zero_operand (operands[1], TFmode))"
2894   "#"
2895   [(set_attr "length" "2")])
2897 ;; Now all the splits to handle multi-insn TF mode moves.
2898 (define_split
2899   [(set (match_operand:TF 0 "register_operand" "")
2900         (match_operand:TF 1 "register_operand" ""))]
2901   "reload_completed
2902    && (! TARGET_ARCH64
2903        || (TARGET_FPU
2904            && ! TARGET_HARD_QUAD)
2905        || ! fp_register_operand (operands[0], TFmode))"
2906   [(clobber (const_int 0))]
2908   rtx set_dest = operands[0];
2909   rtx set_src = operands[1];
2910   rtx dest1, dest2;
2911   rtx src1, src2;
2913   dest1 = gen_df_reg (set_dest, 0);
2914   dest2 = gen_df_reg (set_dest, 1);
2915   src1 = gen_df_reg (set_src, 0);
2916   src2 = gen_df_reg (set_src, 1);
2918   /* Now emit using the real source and destination we found, swapping
2919      the order if we detect overlap.  */
2920   if (reg_overlap_mentioned_p (dest1, src2))
2921     {
2922       emit_insn (gen_movdf (dest2, src2));
2923       emit_insn (gen_movdf (dest1, src1));
2924     }
2925   else
2926     {
2927       emit_insn (gen_movdf (dest1, src1));
2928       emit_insn (gen_movdf (dest2, src2));
2929     }
2930   DONE;
2933 (define_split
2934   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2935         (match_operand:TF 1 "const_zero_operand" ""))]
2936   "reload_completed"
2937   [(clobber (const_int 0))]
2939   rtx set_dest = operands[0];
2940   rtx dest1, dest2;
2942   switch (GET_CODE (set_dest))
2943     {
2944     case REG:
2945       dest1 = gen_df_reg (set_dest, 0);
2946       dest2 = gen_df_reg (set_dest, 1);
2947       break;
2948     case MEM:
2949       dest1 = adjust_address (set_dest, DFmode, 0);
2950       dest2 = adjust_address (set_dest, DFmode, 8);
2951       break;
2952     default:
2953       gcc_unreachable ();      
2954     }
2956   emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
2957   emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
2958   DONE;
2961 (define_split
2962   [(set (match_operand:TF 0 "register_operand" "")
2963         (match_operand:TF 1 "memory_operand" ""))]
2964   "(reload_completed
2965     && offsettable_memref_p (operands[1])
2966     && (! TARGET_ARCH64
2967         || ! TARGET_HARD_QUAD
2968         || ! fp_register_operand (operands[0], TFmode)))"
2969   [(clobber (const_int 0))]
2971   rtx word0 = adjust_address (operands[1], DFmode, 0);
2972   rtx word1 = adjust_address (operands[1], DFmode, 8);
2973   rtx set_dest, dest1, dest2;
2975   set_dest = operands[0];
2977   dest1 = gen_df_reg (set_dest, 0);
2978   dest2 = gen_df_reg (set_dest, 1);
2980   /* Now output, ordering such that we don't clobber any registers
2981      mentioned in the address.  */
2982   if (reg_overlap_mentioned_p (dest1, word1))
2984     {
2985       emit_insn (gen_movdf (dest2, word1));
2986       emit_insn (gen_movdf (dest1, word0));
2987     }
2988   else
2989    {
2990       emit_insn (gen_movdf (dest1, word0));
2991       emit_insn (gen_movdf (dest2, word1));
2992    }
2993   DONE;
2996 (define_split
2997   [(set (match_operand:TF 0 "memory_operand" "")
2998         (match_operand:TF 1 "register_operand" ""))]
2999   "(reload_completed
3000     && offsettable_memref_p (operands[0])
3001     && (! TARGET_ARCH64
3002         || ! TARGET_HARD_QUAD
3003         || ! fp_register_operand (operands[1], TFmode)))"
3004   [(clobber (const_int 0))]
3006   rtx set_src = operands[1];
3008   emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
3009                         gen_df_reg (set_src, 0)));
3010   emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
3011                         gen_df_reg (set_src, 1)));
3012   DONE;
3016 ;; SPARC-V9 conditional move instructions.
3018 ;; We can handle larger constants here for some flavors, but for now we keep
3019 ;; it simple and only allow those constants supported by all flavors.
3020 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3021 ;; 3 contains the constant if one is present, but we handle either for
3022 ;; generality (sparc.c puts a constant in operand 2).
3024 (define_expand "movqicc"
3025   [(set (match_operand:QI 0 "register_operand" "")
3026         (if_then_else:QI (match_operand 1 "comparison_operator" "")
3027                          (match_operand:QI 2 "arith10_operand" "")
3028                          (match_operand:QI 3 "arith10_operand" "")))]
3029   "TARGET_V9"
3031   enum rtx_code code = GET_CODE (operands[1]);
3033   if (GET_MODE (sparc_compare_op0) == DImode
3034       && ! TARGET_ARCH64)
3035     FAIL;
3037   if (sparc_compare_op1 == const0_rtx
3038       && GET_CODE (sparc_compare_op0) == REG
3039       && GET_MODE (sparc_compare_op0) == DImode
3040       && v9_regcmp_p (code))
3041     {
3042       operands[1] = gen_rtx_fmt_ee (code, DImode,
3043                              sparc_compare_op0, sparc_compare_op1);
3044     }
3045   else
3046     {
3047       rtx cc_reg = gen_compare_reg (code);
3048       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3049     }
3052 (define_expand "movhicc"
3053   [(set (match_operand:HI 0 "register_operand" "")
3054         (if_then_else:HI (match_operand 1 "comparison_operator" "")
3055                          (match_operand:HI 2 "arith10_operand" "")
3056                          (match_operand:HI 3 "arith10_operand" "")))]
3057   "TARGET_V9"
3059   enum rtx_code code = GET_CODE (operands[1]);
3061   if (GET_MODE (sparc_compare_op0) == DImode
3062       && ! TARGET_ARCH64)
3063     FAIL;
3065   if (sparc_compare_op1 == const0_rtx
3066       && GET_CODE (sparc_compare_op0) == REG
3067       && GET_MODE (sparc_compare_op0) == DImode
3068       && v9_regcmp_p (code))
3069     {
3070       operands[1] = gen_rtx_fmt_ee (code, DImode,
3071                              sparc_compare_op0, sparc_compare_op1);
3072     }
3073   else
3074     {
3075       rtx cc_reg = gen_compare_reg (code);
3076       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3077     }
3080 (define_expand "movsicc"
3081   [(set (match_operand:SI 0 "register_operand" "")
3082         (if_then_else:SI (match_operand 1 "comparison_operator" "")
3083                          (match_operand:SI 2 "arith10_operand" "")
3084                          (match_operand:SI 3 "arith10_operand" "")))]
3085   "TARGET_V9"
3087   enum rtx_code code = GET_CODE (operands[1]);
3088   enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
3090   if (sparc_compare_op1 == const0_rtx
3091       && GET_CODE (sparc_compare_op0) == REG
3092       && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
3093     {
3094       operands[1] = gen_rtx_fmt_ee (code, op0_mode,
3095                              sparc_compare_op0, sparc_compare_op1);
3096     }
3097   else
3098     {
3099       rtx cc_reg = gen_compare_reg (code);
3100       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3101                                     cc_reg, const0_rtx);
3102     }
3105 (define_expand "movdicc"
3106   [(set (match_operand:DI 0 "register_operand" "")
3107         (if_then_else:DI (match_operand 1 "comparison_operator" "")
3108                          (match_operand:DI 2 "arith10_operand" "")
3109                          (match_operand:DI 3 "arith10_operand" "")))]
3110   "TARGET_ARCH64"
3112   enum rtx_code code = GET_CODE (operands[1]);
3114   if (sparc_compare_op1 == const0_rtx
3115       && GET_CODE (sparc_compare_op0) == REG
3116       && GET_MODE (sparc_compare_op0) == DImode
3117       && v9_regcmp_p (code))
3118     {
3119       operands[1] = gen_rtx_fmt_ee (code, DImode,
3120                              sparc_compare_op0, sparc_compare_op1);
3121     }
3122   else
3123     {
3124       rtx cc_reg = gen_compare_reg (code);
3125       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3126                                     cc_reg, const0_rtx);
3127     }
3130 (define_expand "movsfcc"
3131   [(set (match_operand:SF 0 "register_operand" "")
3132         (if_then_else:SF (match_operand 1 "comparison_operator" "")
3133                          (match_operand:SF 2 "register_operand" "")
3134                          (match_operand:SF 3 "register_operand" "")))]
3135   "TARGET_V9 && TARGET_FPU"
3137   enum rtx_code code = GET_CODE (operands[1]);
3139   if (GET_MODE (sparc_compare_op0) == DImode
3140       && ! TARGET_ARCH64)
3141     FAIL;
3143   if (sparc_compare_op1 == const0_rtx
3144       && GET_CODE (sparc_compare_op0) == REG
3145       && GET_MODE (sparc_compare_op0) == DImode
3146       && v9_regcmp_p (code))
3147     {
3148       operands[1] = gen_rtx_fmt_ee (code, DImode,
3149                              sparc_compare_op0, sparc_compare_op1);
3150     }
3151   else
3152     {
3153       rtx cc_reg = gen_compare_reg (code);
3154       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3155     }
3158 (define_expand "movdfcc"
3159   [(set (match_operand:DF 0 "register_operand" "")
3160         (if_then_else:DF (match_operand 1 "comparison_operator" "")
3161                          (match_operand:DF 2 "register_operand" "")
3162                          (match_operand:DF 3 "register_operand" "")))]
3163   "TARGET_V9 && TARGET_FPU"
3165   enum rtx_code code = GET_CODE (operands[1]);
3167   if (GET_MODE (sparc_compare_op0) == DImode
3168       && ! TARGET_ARCH64)
3169     FAIL;
3171   if (sparc_compare_op1 == const0_rtx
3172       && GET_CODE (sparc_compare_op0) == REG
3173       && GET_MODE (sparc_compare_op0) == DImode
3174       && v9_regcmp_p (code))
3175     {
3176       operands[1] = gen_rtx_fmt_ee (code, DImode,
3177                              sparc_compare_op0, sparc_compare_op1);
3178     }
3179   else
3180     {
3181       rtx cc_reg = gen_compare_reg (code);
3182       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3183     }
3186 (define_expand "movtfcc"
3187   [(set (match_operand:TF 0 "register_operand" "")
3188         (if_then_else:TF (match_operand 1 "comparison_operator" "")
3189                          (match_operand:TF 2 "register_operand" "")
3190                          (match_operand:TF 3 "register_operand" "")))]
3191   "TARGET_V9 && TARGET_FPU"
3193   enum rtx_code code = GET_CODE (operands[1]);
3195   if (GET_MODE (sparc_compare_op0) == DImode
3196       && ! TARGET_ARCH64)
3197     FAIL;
3199   if (sparc_compare_op1 == const0_rtx
3200       && GET_CODE (sparc_compare_op0) == REG
3201       && GET_MODE (sparc_compare_op0) == DImode
3202       && v9_regcmp_p (code))
3203     {
3204       operands[1] = gen_rtx_fmt_ee (code, DImode,
3205                              sparc_compare_op0, sparc_compare_op1);
3206     }
3207   else
3208     {
3209       rtx cc_reg = gen_compare_reg (code);
3210       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3211     }
3214 ;; Conditional move define_insns.
3216 (define_insn "*movqi_cc_sp64"
3217   [(set (match_operand:QI 0 "register_operand" "=r,r")
3218         (if_then_else:QI (match_operator 1 "comparison_operator"
3219                                 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3220                                  (const_int 0)])
3221                          (match_operand:QI 3 "arith11_operand" "rL,0")
3222                          (match_operand:QI 4 "arith11_operand" "0,rL")))]
3223   "TARGET_V9"
3224   "@
3225    mov%C1\t%x2, %3, %0
3226    mov%c1\t%x2, %4, %0"
3227   [(set_attr "type" "cmove")])
3229 (define_insn "*movhi_cc_sp64"
3230   [(set (match_operand:HI 0 "register_operand" "=r,r")
3231         (if_then_else:HI (match_operator 1 "comparison_operator"
3232                                 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3233                                  (const_int 0)])
3234                          (match_operand:HI 3 "arith11_operand" "rL,0")
3235                          (match_operand:HI 4 "arith11_operand" "0,rL")))]
3236   "TARGET_V9"
3237   "@
3238    mov%C1\t%x2, %3, %0
3239    mov%c1\t%x2, %4, %0"
3240   [(set_attr "type" "cmove")])
3242 (define_insn "*movsi_cc_sp64"
3243   [(set (match_operand:SI 0 "register_operand" "=r,r")
3244         (if_then_else:SI (match_operator 1 "comparison_operator"
3245                                 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3246                                  (const_int 0)])
3247                          (match_operand:SI 3 "arith11_operand" "rL,0")
3248                          (match_operand:SI 4 "arith11_operand" "0,rL")))]
3249   "TARGET_V9"
3250   "@
3251    mov%C1\t%x2, %3, %0
3252    mov%c1\t%x2, %4, %0"
3253   [(set_attr "type" "cmove")])
3255 (define_insn "*movdi_cc_sp64"
3256   [(set (match_operand:DI 0 "register_operand" "=r,r")
3257         (if_then_else:DI (match_operator 1 "comparison_operator"
3258                                 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3259                                  (const_int 0)])
3260                          (match_operand:DI 3 "arith11_operand" "rL,0")
3261                          (match_operand:DI 4 "arith11_operand" "0,rL")))]
3262   "TARGET_ARCH64"
3263   "@
3264    mov%C1\t%x2, %3, %0
3265    mov%c1\t%x2, %4, %0"
3266   [(set_attr "type" "cmove")])
3268 (define_insn "*movdi_cc_sp64_trunc"
3269   [(set (match_operand:SI 0 "register_operand" "=r,r")
3270         (if_then_else:SI (match_operator 1 "comparison_operator"
3271                                 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3272                                  (const_int 0)])
3273                          (match_operand:SI 3 "arith11_operand" "rL,0")
3274                          (match_operand:SI 4 "arith11_operand" "0,rL")))]
3275   "TARGET_ARCH64"
3276   "@
3277    mov%C1\t%x2, %3, %0
3278    mov%c1\t%x2, %4, %0"
3279   [(set_attr "type" "cmove")])
3281 (define_insn "*movsf_cc_sp64"
3282   [(set (match_operand:SF 0 "register_operand" "=f,f")
3283         (if_then_else:SF (match_operator 1 "comparison_operator"
3284                                 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3285                                  (const_int 0)])
3286                          (match_operand:SF 3 "register_operand" "f,0")
3287                          (match_operand:SF 4 "register_operand" "0,f")))]
3288   "TARGET_V9 && TARGET_FPU"
3289   "@
3290    fmovs%C1\t%x2, %3, %0
3291    fmovs%c1\t%x2, %4, %0"
3292   [(set_attr "type" "fpcmove")])
3294 (define_insn "movdf_cc_sp64"
3295   [(set (match_operand:DF 0 "register_operand" "=e,e")
3296         (if_then_else:DF (match_operator 1 "comparison_operator"
3297                                 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3298                                  (const_int 0)])
3299                          (match_operand:DF 3 "register_operand" "e,0")
3300                          (match_operand:DF 4 "register_operand" "0,e")))]
3301   "TARGET_V9 && TARGET_FPU"
3302   "@
3303    fmovd%C1\t%x2, %3, %0
3304    fmovd%c1\t%x2, %4, %0"
3305   [(set_attr "type" "fpcmove")
3306    (set_attr "fptype" "double")])
3308 (define_insn "*movtf_cc_hq_sp64"
3309   [(set (match_operand:TF 0 "register_operand" "=e,e")
3310         (if_then_else:TF (match_operator 1 "comparison_operator"
3311                                 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3312                                  (const_int 0)])
3313                          (match_operand:TF 3 "register_operand" "e,0")
3314                          (match_operand:TF 4 "register_operand" "0,e")))]
3315   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3316   "@
3317    fmovq%C1\t%x2, %3, %0
3318    fmovq%c1\t%x2, %4, %0"
3319   [(set_attr "type" "fpcmove")])
3321 (define_insn_and_split "*movtf_cc_sp64"
3322   [(set (match_operand:TF 0 "register_operand" "=e,e")
3323         (if_then_else:TF (match_operator 1 "comparison_operator"
3324                             [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3325                              (const_int 0)])
3326                          (match_operand:TF 3 "register_operand" "e,0")
3327                          (match_operand:TF 4 "register_operand" "0,e")))]
3328   "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
3329   "#"
3330   "&& reload_completed"
3331   [(clobber (const_int 0))]
3333   rtx set_dest = operands[0];
3334   rtx set_srca = operands[3];
3335   rtx set_srcb = operands[4];
3336   int third = rtx_equal_p (set_dest, set_srca);
3337   rtx dest1, dest2;
3338   rtx srca1, srca2, srcb1, srcb2;
3340   dest1 = gen_df_reg (set_dest, 0);
3341   dest2 = gen_df_reg (set_dest, 1);
3342   srca1 = gen_df_reg (set_srca, 0);
3343   srca2 = gen_df_reg (set_srca, 1);
3344   srcb1 = gen_df_reg (set_srcb, 0);
3345   srcb2 = gen_df_reg (set_srcb, 1);
3347   /* Now emit using the real source and destination we found, swapping
3348      the order if we detect overlap.  */
3349   if ((third && reg_overlap_mentioned_p (dest1, srcb2))
3350       || (!third && reg_overlap_mentioned_p (dest1, srca2)))
3351     {
3352       emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3353       emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3354     }
3355   else
3356     {
3357       emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3358       emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3359     }
3360   DONE;
3362   [(set_attr "length" "2")])
3364 (define_insn "*movqi_cc_reg_sp64"
3365   [(set (match_operand:QI 0 "register_operand" "=r,r")
3366         (if_then_else:QI (match_operator 1 "v9_register_compare_operator"
3367                                 [(match_operand:DI 2 "register_operand" "r,r")
3368                                  (const_int 0)])
3369                          (match_operand:QI 3 "arith10_operand" "rM,0")
3370                          (match_operand:QI 4 "arith10_operand" "0,rM")))]
3371   "TARGET_ARCH64"
3372   "@
3373    movr%D1\t%2, %r3, %0
3374    movr%d1\t%2, %r4, %0"
3375   [(set_attr "type" "cmove")])
3377 (define_insn "*movhi_cc_reg_sp64"
3378   [(set (match_operand:HI 0 "register_operand" "=r,r")
3379         (if_then_else:HI (match_operator 1 "v9_register_compare_operator"
3380                                 [(match_operand:DI 2 "register_operand" "r,r")
3381                                  (const_int 0)])
3382                          (match_operand:HI 3 "arith10_operand" "rM,0")
3383                          (match_operand:HI 4 "arith10_operand" "0,rM")))]
3384   "TARGET_ARCH64"
3385   "@
3386    movr%D1\t%2, %r3, %0
3387    movr%d1\t%2, %r4, %0"
3388   [(set_attr "type" "cmove")])
3390 (define_insn "*movsi_cc_reg_sp64"
3391   [(set (match_operand:SI 0 "register_operand" "=r,r")
3392         (if_then_else:SI (match_operator 1 "v9_register_compare_operator"
3393                                 [(match_operand:DI 2 "register_operand" "r,r")
3394                                  (const_int 0)])
3395                          (match_operand:SI 3 "arith10_operand" "rM,0")
3396                          (match_operand:SI 4 "arith10_operand" "0,rM")))]
3397   "TARGET_ARCH64"
3398   "@
3399    movr%D1\t%2, %r3, %0
3400    movr%d1\t%2, %r4, %0"
3401   [(set_attr "type" "cmove")])
3403 (define_insn "*movdi_cc_reg_sp64"
3404   [(set (match_operand:DI 0 "register_operand" "=r,r")
3405         (if_then_else:DI (match_operator 1 "v9_register_compare_operator"
3406                                 [(match_operand:DI 2 "register_operand" "r,r")
3407                                  (const_int 0)])
3408                          (match_operand:DI 3 "arith10_operand" "rM,0")
3409                          (match_operand:DI 4 "arith10_operand" "0,rM")))]
3410   "TARGET_ARCH64"
3411   "@
3412    movr%D1\t%2, %r3, %0
3413    movr%d1\t%2, %r4, %0"
3414   [(set_attr "type" "cmove")])
3416 (define_insn "*movsf_cc_reg_sp64"
3417   [(set (match_operand:SF 0 "register_operand" "=f,f")
3418         (if_then_else:SF (match_operator 1 "v9_register_compare_operator"
3419                                 [(match_operand:DI 2 "register_operand" "r,r")
3420                                  (const_int 0)])
3421                          (match_operand:SF 3 "register_operand" "f,0")
3422                          (match_operand:SF 4 "register_operand" "0,f")))]
3423   "TARGET_ARCH64 && TARGET_FPU"
3424   "@
3425    fmovrs%D1\t%2, %3, %0
3426    fmovrs%d1\t%2, %4, %0"
3427   [(set_attr "type" "fpcrmove")])
3429 (define_insn "movdf_cc_reg_sp64"
3430   [(set (match_operand:DF 0 "register_operand" "=e,e")
3431         (if_then_else:DF (match_operator 1 "v9_register_compare_operator"
3432                                 [(match_operand:DI 2 "register_operand" "r,r")
3433                                  (const_int 0)])
3434                          (match_operand:DF 3 "register_operand" "e,0")
3435                          (match_operand:DF 4 "register_operand" "0,e")))]
3436   "TARGET_ARCH64 && TARGET_FPU"
3437   "@
3438    fmovrd%D1\t%2, %3, %0
3439    fmovrd%d1\t%2, %4, %0"
3440   [(set_attr "type" "fpcrmove")
3441    (set_attr "fptype" "double")])
3443 (define_insn "*movtf_cc_reg_hq_sp64"
3444   [(set (match_operand:TF 0 "register_operand" "=e,e")
3445         (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
3446                                 [(match_operand:DI 2 "register_operand" "r,r")
3447                                  (const_int 0)])
3448                          (match_operand:TF 3 "register_operand" "e,0")
3449                          (match_operand:TF 4 "register_operand" "0,e")))]
3450   "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
3451   "@
3452    fmovrq%D1\t%2, %3, %0
3453    fmovrq%d1\t%2, %4, %0"
3454   [(set_attr "type" "fpcrmove")])
3456 (define_insn_and_split "*movtf_cc_reg_sp64"
3457   [(set (match_operand:TF 0 "register_operand" "=e,e")
3458         (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
3459                                 [(match_operand:DI 2 "register_operand" "r,r")
3460                                  (const_int 0)])
3461                          (match_operand:TF 3 "register_operand" "e,0")
3462                          (match_operand:TF 4 "register_operand" "0,e")))]
3463   "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
3464   "#"
3465   "&& reload_completed"
3466   [(clobber (const_int 0))]
3468   rtx set_dest = operands[0];
3469   rtx set_srca = operands[3];
3470   rtx set_srcb = operands[4];
3471   int third = rtx_equal_p (set_dest, set_srca);
3472   rtx dest1, dest2;
3473   rtx srca1, srca2, srcb1, srcb2;
3475   dest1 = gen_df_reg (set_dest, 0);
3476   dest2 = gen_df_reg (set_dest, 1);
3477   srca1 = gen_df_reg (set_srca, 0);
3478   srca2 = gen_df_reg (set_srca, 1);
3479   srcb1 = gen_df_reg (set_srcb, 0);
3480   srcb2 = gen_df_reg (set_srcb, 1);
3482   /* Now emit using the real source and destination we found, swapping
3483      the order if we detect overlap.  */
3484   if ((third && reg_overlap_mentioned_p (dest1, srcb2))
3485       || (!third && reg_overlap_mentioned_p (dest1, srca2)))
3486     {
3487       emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3488       emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3489     }
3490   else
3491     {
3492       emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3493       emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3494     }
3495   DONE;
3497   [(set_attr "length" "2")])
3500 ;; Zero-extension instructions
3502 ;; These patterns originally accepted general_operands, however, slightly
3503 ;; better code is generated by only accepting register_operands, and then
3504 ;; letting combine generate the ldu[hb] insns.
3506 (define_expand "zero_extendhisi2"
3507   [(set (match_operand:SI 0 "register_operand" "")
3508         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
3509   ""
3511   rtx temp = gen_reg_rtx (SImode);
3512   rtx shift_16 = GEN_INT (16);
3513   int op1_subbyte = 0;
3515   if (GET_CODE (operand1) == SUBREG)
3516     {
3517       op1_subbyte = SUBREG_BYTE (operand1);
3518       op1_subbyte /= GET_MODE_SIZE (SImode);
3519       op1_subbyte *= GET_MODE_SIZE (SImode);
3520       operand1 = XEXP (operand1, 0);
3521     }
3523   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3524                           shift_16));
3525   emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
3526   DONE;
3529 (define_insn "*zero_extendhisi2_insn"
3530   [(set (match_operand:SI 0 "register_operand" "=r")
3531         (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3532   ""
3533   "lduh\t%1, %0"
3534   [(set_attr "type" "load")
3535    (set_attr "us3load_type" "3cycle")])
3537 (define_expand "zero_extendqihi2"
3538   [(set (match_operand:HI 0 "register_operand" "")
3539         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
3540   ""
3541   "")
3543 (define_insn "*zero_extendqihi2_insn"
3544   [(set (match_operand:HI 0 "register_operand" "=r,r")
3545         (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
3546   "GET_CODE (operands[1]) != CONST_INT"
3547   "@
3548    and\t%1, 0xff, %0
3549    ldub\t%1, %0"
3550   [(set_attr "type" "*,load")
3551    (set_attr "us3load_type" "*,3cycle")])
3553 (define_expand "zero_extendqisi2"
3554   [(set (match_operand:SI 0 "register_operand" "")
3555         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
3556   ""
3557   "")
3559 (define_insn "*zero_extendqisi2_insn"
3560   [(set (match_operand:SI 0 "register_operand" "=r,r")
3561         (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
3562   "GET_CODE (operands[1]) != CONST_INT"
3563   "@
3564    and\t%1, 0xff, %0
3565    ldub\t%1, %0"
3566   [(set_attr "type" "*,load")
3567    (set_attr "us3load_type" "*,3cycle")])
3569 (define_expand "zero_extendqidi2"
3570   [(set (match_operand:DI 0 "register_operand" "")
3571         (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
3572   "TARGET_ARCH64"
3573   "")
3575 (define_insn "*zero_extendqidi2_insn"
3576   [(set (match_operand:DI 0 "register_operand" "=r,r")
3577         (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
3578   "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
3579   "@
3580    and\t%1, 0xff, %0
3581    ldub\t%1, %0"
3582   [(set_attr "type" "*,load")
3583    (set_attr "us3load_type" "*,3cycle")])
3585 (define_expand "zero_extendhidi2"
3586   [(set (match_operand:DI 0 "register_operand" "")
3587         (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
3588   "TARGET_ARCH64"
3590   rtx temp = gen_reg_rtx (DImode);
3591   rtx shift_48 = GEN_INT (48);
3592   int op1_subbyte = 0;
3594   if (GET_CODE (operand1) == SUBREG)
3595     {
3596       op1_subbyte = SUBREG_BYTE (operand1);
3597       op1_subbyte /= GET_MODE_SIZE (DImode);
3598       op1_subbyte *= GET_MODE_SIZE (DImode);
3599       operand1 = XEXP (operand1, 0);
3600     }
3602   emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3603                           shift_48));
3604   emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
3605   DONE;
3608 (define_insn "*zero_extendhidi2_insn"
3609   [(set (match_operand:DI 0 "register_operand" "=r")
3610         (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3611   "TARGET_ARCH64"
3612   "lduh\t%1, %0"
3613   [(set_attr "type" "load")
3614    (set_attr "us3load_type" "3cycle")])
3616 ;; ??? Write truncdisi pattern using sra?
3618 (define_expand "zero_extendsidi2"
3619   [(set (match_operand:DI 0 "register_operand" "")
3620         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
3621   ""
3622   "")
3624 (define_insn "*zero_extendsidi2_insn_sp64"
3625   [(set (match_operand:DI 0 "register_operand" "=r,r")
3626         (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
3627   "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
3628   "@
3629    srl\t%1, 0, %0
3630    lduw\t%1, %0"
3631   [(set_attr "type" "shift,load")])
3633 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
3634   [(set (match_operand:DI 0 "register_operand" "=r")
3635         (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
3636   "! TARGET_ARCH64"
3637   "#"
3638   "&& reload_completed"
3639   [(set (match_dup 2) (match_dup 3))
3640    (set (match_dup 4) (match_dup 5))]
3642   rtx dest1, dest2;
3644   dest1 = gen_highpart (SImode, operands[0]);
3645   dest2 = gen_lowpart (SImode, operands[0]);
3647   /* Swap the order in case of overlap.  */
3648   if (REGNO (dest1) == REGNO (operands[1]))
3649     {
3650       operands[2] = dest2;
3651       operands[3] = operands[1];
3652       operands[4] = dest1;
3653       operands[5] = const0_rtx;
3654     }
3655   else
3656     {
3657       operands[2] = dest1;
3658       operands[3] = const0_rtx;
3659       operands[4] = dest2;
3660       operands[5] = operands[1];
3661     }
3663   [(set_attr "length" "2")])
3665 ;; Simplify comparisons of extended values.
3667 (define_insn "*cmp_zero_extendqisi2"
3668   [(set (reg:CC 100)
3669         (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
3670                     (const_int 0)))]
3671   ""
3672   "andcc\t%0, 0xff, %%g0"
3673   [(set_attr "type" "compare")])
3675 (define_insn "*cmp_zero_qi"
3676   [(set (reg:CC 100)
3677         (compare:CC (match_operand:QI 0 "register_operand" "r")
3678                     (const_int 0)))]
3679   ""
3680   "andcc\t%0, 0xff, %%g0"
3681   [(set_attr "type" "compare")])
3683 (define_insn "*cmp_zero_extendqisi2_set"
3684   [(set (reg:CC 100)
3685         (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
3686                     (const_int 0)))
3687    (set (match_operand:SI 0 "register_operand" "=r")
3688         (zero_extend:SI (match_dup 1)))]
3689   ""
3690   "andcc\t%1, 0xff, %0"
3691   [(set_attr "type" "compare")])
3693 (define_insn "*cmp_zero_extendqisi2_andcc_set"
3694   [(set (reg:CC 100)
3695         (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
3696                             (const_int 255))
3697                     (const_int 0)))
3698    (set (match_operand:SI 0 "register_operand" "=r")
3699         (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
3700   ""
3701   "andcc\t%1, 0xff, %0"
3702   [(set_attr "type" "compare")])
3704 (define_insn "*cmp_zero_extendqidi2"
3705   [(set (reg:CCX 100)
3706         (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
3707                      (const_int 0)))]
3708   "TARGET_ARCH64"
3709   "andcc\t%0, 0xff, %%g0"
3710   [(set_attr "type" "compare")])
3712 (define_insn "*cmp_zero_qi_sp64"
3713   [(set (reg:CCX 100)
3714         (compare:CCX (match_operand:QI 0 "register_operand" "r")
3715                      (const_int 0)))]
3716   "TARGET_ARCH64"
3717   "andcc\t%0, 0xff, %%g0"
3718   [(set_attr "type" "compare")])
3720 (define_insn "*cmp_zero_extendqidi2_set"
3721   [(set (reg:CCX 100)
3722         (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
3723                      (const_int 0)))
3724    (set (match_operand:DI 0 "register_operand" "=r")
3725         (zero_extend:DI (match_dup 1)))]
3726   "TARGET_ARCH64"
3727   "andcc\t%1, 0xff, %0"
3728   [(set_attr "type" "compare")])
3730 (define_insn "*cmp_zero_extendqidi2_andcc_set"
3731   [(set (reg:CCX 100)
3732         (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
3733                              (const_int 255))
3734                      (const_int 0)))
3735    (set (match_operand:DI 0 "register_operand" "=r")
3736         (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
3737   "TARGET_ARCH64"
3738   "andcc\t%1, 0xff, %0"
3739   [(set_attr "type" "compare")])
3741 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
3743 (define_insn "*cmp_siqi_trunc"
3744   [(set (reg:CC 100)
3745         (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
3746                     (const_int 0)))]
3747   ""
3748   "andcc\t%0, 0xff, %%g0"
3749   [(set_attr "type" "compare")])
3751 (define_insn "*cmp_siqi_trunc_set"
3752   [(set (reg:CC 100)
3753         (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
3754                     (const_int 0)))
3755    (set (match_operand:QI 0 "register_operand" "=r")
3756         (subreg:QI (match_dup 1) 3))]
3757   ""
3758   "andcc\t%1, 0xff, %0"
3759   [(set_attr "type" "compare")])
3761 (define_insn "*cmp_diqi_trunc"
3762   [(set (reg:CC 100)
3763         (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
3764                     (const_int 0)))]
3765   "TARGET_ARCH64"
3766   "andcc\t%0, 0xff, %%g0"
3767   [(set_attr "type" "compare")])
3769 (define_insn "*cmp_diqi_trunc_set"
3770   [(set (reg:CC 100)
3771         (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
3772                     (const_int 0)))
3773    (set (match_operand:QI 0 "register_operand" "=r")
3774         (subreg:QI (match_dup 1) 7))]
3775   "TARGET_ARCH64"
3776   "andcc\t%1, 0xff, %0"
3777   [(set_attr "type" "compare")])
3780 ;; Sign-extension instructions
3782 ;; These patterns originally accepted general_operands, however, slightly
3783 ;; better code is generated by only accepting register_operands, and then
3784 ;; letting combine generate the lds[hb] insns.
3786 (define_expand "extendhisi2"
3787   [(set (match_operand:SI 0 "register_operand" "")
3788         (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
3789   ""
3791   rtx temp = gen_reg_rtx (SImode);
3792   rtx shift_16 = GEN_INT (16);
3793   int op1_subbyte = 0;
3795   if (GET_CODE (operand1) == SUBREG)
3796     {
3797       op1_subbyte = SUBREG_BYTE (operand1);
3798       op1_subbyte /= GET_MODE_SIZE (SImode);
3799       op1_subbyte *= GET_MODE_SIZE (SImode);
3800       operand1 = XEXP (operand1, 0);
3801     }
3803   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3804                           shift_16));
3805   emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
3806   DONE;
3809 (define_insn "*sign_extendhisi2_insn"
3810   [(set (match_operand:SI 0 "register_operand" "=r")
3811         (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3812   ""
3813   "ldsh\t%1, %0"
3814   [(set_attr "type" "sload")
3815    (set_attr "us3load_type" "3cycle")])
3817 (define_expand "extendqihi2"
3818   [(set (match_operand:HI 0 "register_operand" "")
3819         (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
3820   ""
3822   rtx temp = gen_reg_rtx (SImode);
3823   rtx shift_24 = GEN_INT (24);
3824   int op1_subbyte = 0;
3825   int op0_subbyte = 0;
3827   if (GET_CODE (operand1) == SUBREG)
3828     {
3829       op1_subbyte = SUBREG_BYTE (operand1);
3830       op1_subbyte /= GET_MODE_SIZE (SImode);
3831       op1_subbyte *= GET_MODE_SIZE (SImode);
3832       operand1 = XEXP (operand1, 0);
3833     }
3834   if (GET_CODE (operand0) == SUBREG)
3835     {
3836       op0_subbyte = SUBREG_BYTE (operand0);
3837       op0_subbyte /= GET_MODE_SIZE (SImode);
3838       op0_subbyte *= GET_MODE_SIZE (SImode);
3839       operand0 = XEXP (operand0, 0);
3840     }
3841   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3842                           shift_24));
3843   if (GET_MODE (operand0) != SImode)
3844     operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
3845   emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3846   DONE;
3849 (define_insn "*sign_extendqihi2_insn"
3850   [(set (match_operand:HI 0 "register_operand" "=r")
3851         (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3852   ""
3853   "ldsb\t%1, %0"
3854   [(set_attr "type" "sload")
3855    (set_attr "us3load_type" "3cycle")])
3857 (define_expand "extendqisi2"
3858   [(set (match_operand:SI 0 "register_operand" "")
3859         (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
3860   ""
3862   rtx temp = gen_reg_rtx (SImode);
3863   rtx shift_24 = GEN_INT (24);
3864   int op1_subbyte = 0;
3866   if (GET_CODE (operand1) == SUBREG)
3867     {
3868       op1_subbyte = SUBREG_BYTE (operand1);
3869       op1_subbyte /= GET_MODE_SIZE (SImode);
3870       op1_subbyte *= GET_MODE_SIZE (SImode);
3871       operand1 = XEXP (operand1, 0);
3872     }
3874   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3875                           shift_24));
3876   emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3877   DONE;
3880 (define_insn "*sign_extendqisi2_insn"
3881   [(set (match_operand:SI 0 "register_operand" "=r")
3882         (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3883   ""
3884   "ldsb\t%1, %0"
3885   [(set_attr "type" "sload")
3886    (set_attr "us3load_type" "3cycle")])
3888 (define_expand "extendqidi2"
3889   [(set (match_operand:DI 0 "register_operand" "")
3890         (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
3891   "TARGET_ARCH64"
3893   rtx temp = gen_reg_rtx (DImode);
3894   rtx shift_56 = GEN_INT (56);
3895   int op1_subbyte = 0;
3897   if (GET_CODE (operand1) == SUBREG)
3898     {
3899       op1_subbyte = SUBREG_BYTE (operand1);
3900       op1_subbyte /= GET_MODE_SIZE (DImode);
3901       op1_subbyte *= GET_MODE_SIZE (DImode);
3902       operand1 = XEXP (operand1, 0);
3903     }
3905   emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3906                           shift_56));
3907   emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
3908   DONE;
3911 (define_insn "*sign_extendqidi2_insn"
3912   [(set (match_operand:DI 0 "register_operand" "=r")
3913         (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3914   "TARGET_ARCH64"
3915   "ldsb\t%1, %0"
3916   [(set_attr "type" "sload")
3917    (set_attr "us3load_type" "3cycle")])
3919 (define_expand "extendhidi2"
3920   [(set (match_operand:DI 0 "register_operand" "")
3921         (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
3922   "TARGET_ARCH64"
3924   rtx temp = gen_reg_rtx (DImode);
3925   rtx shift_48 = GEN_INT (48);
3926   int op1_subbyte = 0;
3928   if (GET_CODE (operand1) == SUBREG)
3929     {
3930       op1_subbyte = SUBREG_BYTE (operand1);
3931       op1_subbyte /= GET_MODE_SIZE (DImode);
3932       op1_subbyte *= GET_MODE_SIZE (DImode);
3933       operand1 = XEXP (operand1, 0);
3934     }
3936   emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3937                           shift_48));
3938   emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
3939   DONE;
3942 (define_insn "*sign_extendhidi2_insn"
3943   [(set (match_operand:DI 0 "register_operand" "=r")
3944         (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3945   "TARGET_ARCH64"
3946   "ldsh\t%1, %0"
3947   [(set_attr "type" "sload")
3948    (set_attr "us3load_type" "3cycle")])
3950 (define_expand "extendsidi2"
3951   [(set (match_operand:DI 0 "register_operand" "")
3952         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3953   "TARGET_ARCH64"
3954   "")
3956 (define_insn "*sign_extendsidi2_insn"
3957   [(set (match_operand:DI 0 "register_operand" "=r,r")
3958         (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
3959   "TARGET_ARCH64"
3960   "@
3961   sra\t%1, 0, %0
3962   ldsw\t%1, %0"
3963   [(set_attr "type" "shift,sload")
3964    (set_attr "us3load_type" "*,3cycle")])
3967 ;; Special pattern for optimizing bit-field compares.  This is needed
3968 ;; because combine uses this as a canonical form.
3970 (define_insn "*cmp_zero_extract"
3971   [(set (reg:CC 100)
3972         (compare:CC
3973          (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
3974                           (match_operand:SI 1 "small_int_operand" "I")
3975                           (match_operand:SI 2 "small_int_operand" "I"))
3976          (const_int 0)))]
3977   "INTVAL (operands[2]) > 19"
3979   int len = INTVAL (operands[1]);
3980   int pos = 32 - INTVAL (operands[2]) - len;
3981   HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
3982   operands[1] = GEN_INT (mask);
3983   return "andcc\t%0, %1, %%g0";
3985   [(set_attr "type" "compare")])
3987 (define_insn "*cmp_zero_extract_sp64"
3988   [(set (reg:CCX 100)
3989         (compare:CCX
3990          (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
3991                           (match_operand:SI 1 "small_int_operand" "I")
3992                           (match_operand:SI 2 "small_int_operand" "I"))
3993          (const_int 0)))]
3994   "TARGET_ARCH64 && INTVAL (operands[2]) > 51"
3996   int len = INTVAL (operands[1]);
3997   int pos = 64 - INTVAL (operands[2]) - len;
3998   HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
3999   operands[1] = GEN_INT (mask);
4000   return "andcc\t%0, %1, %%g0";
4002   [(set_attr "type" "compare")])
4005 ;; Conversions between float, double and long double.
4007 (define_insn "extendsfdf2"
4008   [(set (match_operand:DF 0 "register_operand" "=e")
4009         (float_extend:DF
4010          (match_operand:SF 1 "register_operand" "f")))]
4011   "TARGET_FPU"
4012   "fstod\t%1, %0"
4013   [(set_attr "type" "fp")
4014    (set_attr "fptype" "double")])
4016 (define_expand "extendsftf2"
4017   [(set (match_operand:TF 0 "nonimmediate_operand" "")
4018         (float_extend:TF
4019          (match_operand:SF 1 "register_operand" "")))]
4020   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4021   "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4023 (define_insn "*extendsftf2_hq"
4024   [(set (match_operand:TF 0 "register_operand" "=e")
4025         (float_extend:TF
4026          (match_operand:SF 1 "register_operand" "f")))]
4027   "TARGET_FPU && TARGET_HARD_QUAD"
4028   "fstoq\t%1, %0"
4029   [(set_attr "type" "fp")])
4031 (define_expand "extenddftf2"
4032   [(set (match_operand:TF 0 "nonimmediate_operand" "")
4033         (float_extend:TF
4034          (match_operand:DF 1 "register_operand" "")))]
4035   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4036   "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4038 (define_insn "*extenddftf2_hq"
4039   [(set (match_operand:TF 0 "register_operand" "=e")
4040         (float_extend:TF
4041          (match_operand:DF 1 "register_operand" "e")))]
4042   "TARGET_FPU && TARGET_HARD_QUAD"
4043   "fdtoq\t%1, %0"
4044   [(set_attr "type" "fp")])
4046 (define_insn "truncdfsf2"
4047   [(set (match_operand:SF 0 "register_operand" "=f")
4048         (float_truncate:SF
4049          (match_operand:DF 1 "register_operand" "e")))]
4050   "TARGET_FPU"
4051   "fdtos\t%1, %0"
4052   [(set_attr "type" "fp")
4053    (set_attr "fptype" "double")])
4055 (define_expand "trunctfsf2"
4056   [(set (match_operand:SF 0 "register_operand" "")
4057         (float_truncate:SF
4058          (match_operand:TF 1 "general_operand" "")))]
4059   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4060   "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4062 (define_insn "*trunctfsf2_hq"
4063   [(set (match_operand:SF 0 "register_operand" "=f")
4064         (float_truncate:SF
4065          (match_operand:TF 1 "register_operand" "e")))]
4066   "TARGET_FPU && TARGET_HARD_QUAD"
4067   "fqtos\t%1, %0"
4068   [(set_attr "type" "fp")])
4070 (define_expand "trunctfdf2"
4071   [(set (match_operand:DF 0 "register_operand" "")
4072         (float_truncate:DF
4073          (match_operand:TF 1 "general_operand" "")))]
4074   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4075   "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4077 (define_insn "*trunctfdf2_hq"
4078   [(set (match_operand:DF 0 "register_operand" "=e")
4079         (float_truncate:DF
4080          (match_operand:TF 1 "register_operand" "e")))]
4081   "TARGET_FPU && TARGET_HARD_QUAD"
4082   "fqtod\t%1, %0"
4083   [(set_attr "type" "fp")])
4086 ;; Conversion between fixed point and floating point.
4088 (define_insn "floatsisf2"
4089   [(set (match_operand:SF 0 "register_operand" "=f")
4090         (float:SF (match_operand:SI 1 "register_operand" "f")))]
4091   "TARGET_FPU"
4092   "fitos\t%1, %0"
4093   [(set_attr "type" "fp")
4094    (set_attr "fptype" "double")])
4096 (define_insn "floatsidf2"
4097   [(set (match_operand:DF 0 "register_operand" "=e")
4098         (float:DF (match_operand:SI 1 "register_operand" "f")))]
4099   "TARGET_FPU"
4100   "fitod\t%1, %0"
4101   [(set_attr "type" "fp")
4102    (set_attr "fptype" "double")])
4104 (define_expand "floatsitf2"
4105   [(set (match_operand:TF 0 "nonimmediate_operand" "")
4106         (float:TF (match_operand:SI 1 "register_operand" "")))]
4107   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4108   "emit_tfmode_cvt (FLOAT, operands); DONE;")
4110 (define_insn "*floatsitf2_hq"
4111   [(set (match_operand:TF 0 "register_operand" "=e")
4112         (float:TF (match_operand:SI 1 "register_operand" "f")))]
4113   "TARGET_FPU && TARGET_HARD_QUAD"
4114   "fitoq\t%1, %0"
4115   [(set_attr "type" "fp")])
4117 (define_expand "floatunssitf2"
4118   [(set (match_operand:TF 0 "nonimmediate_operand" "")
4119         (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
4120   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4121   "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4123 ;; Now the same for 64 bit sources.
4125 (define_insn "floatdisf2"
4126   [(set (match_operand:SF 0 "register_operand" "=f")
4127         (float:SF (match_operand:DI 1 "register_operand" "e")))]
4128   "TARGET_V9 && TARGET_FPU"
4129   "fxtos\t%1, %0"
4130   [(set_attr "type" "fp")
4131    (set_attr "fptype" "double")])
4133 (define_expand "floatunsdisf2"
4134   [(use (match_operand:SF 0 "register_operand" ""))
4135    (use (match_operand:DI 1 "general_operand" ""))]
4136   "TARGET_ARCH64 && TARGET_FPU"
4137   "sparc_emit_floatunsdi (operands, SFmode); DONE;")
4139 (define_insn "floatdidf2"
4140   [(set (match_operand:DF 0 "register_operand" "=e")
4141         (float:DF (match_operand:DI 1 "register_operand" "e")))]
4142   "TARGET_V9 && TARGET_FPU"
4143   "fxtod\t%1, %0"
4144   [(set_attr "type" "fp")
4145    (set_attr "fptype" "double")])
4147 (define_expand "floatunsdidf2"
4148   [(use (match_operand:DF 0 "register_operand" ""))
4149    (use (match_operand:DI 1 "general_operand" ""))]
4150   "TARGET_ARCH64 && TARGET_FPU"
4151   "sparc_emit_floatunsdi (operands, DFmode); DONE;")
4153 (define_expand "floatditf2"
4154   [(set (match_operand:TF 0 "nonimmediate_operand" "")
4155         (float:TF (match_operand:DI 1 "register_operand" "")))]
4156   "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4157   "emit_tfmode_cvt (FLOAT, operands); DONE;")
4159 (define_insn "*floatditf2_hq"
4160   [(set (match_operand:TF 0 "register_operand" "=e")
4161         (float:TF (match_operand:DI 1 "register_operand" "e")))]
4162   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4163   "fxtoq\t%1, %0"
4164   [(set_attr "type" "fp")])
4166 (define_expand "floatunsditf2"
4167   [(set (match_operand:TF 0 "nonimmediate_operand" "")
4168         (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
4169   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4170   "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4172 ;; Convert a float to an actual integer.
4173 ;; Truncation is performed as part of the conversion.
4175 (define_insn "fix_truncsfsi2"
4176   [(set (match_operand:SI 0 "register_operand" "=f")
4177         (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4178   "TARGET_FPU"
4179   "fstoi\t%1, %0"
4180   [(set_attr "type" "fp")
4181    (set_attr "fptype" "double")])
4183 (define_insn "fix_truncdfsi2"
4184   [(set (match_operand:SI 0 "register_operand" "=f")
4185         (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4186   "TARGET_FPU"
4187   "fdtoi\t%1, %0"
4188   [(set_attr "type" "fp")
4189    (set_attr "fptype" "double")])
4191 (define_expand "fix_trunctfsi2"
4192   [(set (match_operand:SI 0 "register_operand" "")
4193         (fix:SI (match_operand:TF 1 "general_operand" "")))]
4194   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4195   "emit_tfmode_cvt (FIX, operands); DONE;")
4197 (define_insn "*fix_trunctfsi2_hq"
4198   [(set (match_operand:SI 0 "register_operand" "=f")
4199         (fix:SI (match_operand:TF 1 "register_operand" "e")))]
4200   "TARGET_FPU && TARGET_HARD_QUAD"
4201   "fqtoi\t%1, %0"
4202   [(set_attr "type" "fp")])
4204 (define_expand "fixuns_trunctfsi2"
4205   [(set (match_operand:SI 0 "register_operand" "")
4206         (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
4207   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4208   "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4210 ;; Now the same, for V9 targets
4212 (define_insn "fix_truncsfdi2"
4213   [(set (match_operand:DI 0 "register_operand" "=e")
4214         (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4215   "TARGET_V9 && TARGET_FPU"
4216   "fstox\t%1, %0"
4217   [(set_attr "type" "fp")
4218    (set_attr "fptype" "double")])
4220 (define_expand "fixuns_truncsfdi2"
4221   [(use (match_operand:DI 0 "register_operand" ""))
4222    (use (match_operand:SF 1 "general_operand" ""))]
4223   "TARGET_ARCH64 && TARGET_FPU"
4224   "sparc_emit_fixunsdi (operands, SFmode); DONE;")
4226 (define_insn "fix_truncdfdi2"
4227   [(set (match_operand:DI 0 "register_operand" "=e")
4228         (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4229   "TARGET_V9 && TARGET_FPU"
4230   "fdtox\t%1, %0"
4231   [(set_attr "type" "fp")
4232    (set_attr "fptype" "double")])
4234 (define_expand "fixuns_truncdfdi2"
4235   [(use (match_operand:DI 0 "register_operand" ""))
4236    (use (match_operand:DF 1 "general_operand" ""))]
4237   "TARGET_ARCH64 && TARGET_FPU"
4238   "sparc_emit_fixunsdi (operands, DFmode); DONE;")
4240 (define_expand "fix_trunctfdi2"
4241   [(set (match_operand:DI 0 "register_operand" "")
4242         (fix:DI (match_operand:TF 1 "general_operand" "")))]
4243   "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4244   "emit_tfmode_cvt (FIX, operands); DONE;")
4246 (define_insn "*fix_trunctfdi2_hq"
4247   [(set (match_operand:DI 0 "register_operand" "=e")
4248         (fix:DI (match_operand:TF 1 "register_operand" "e")))]
4249   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4250   "fqtox\t%1, %0"
4251   [(set_attr "type" "fp")])
4253 (define_expand "fixuns_trunctfdi2"
4254   [(set (match_operand:DI 0 "register_operand" "")
4255         (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
4256   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4257   "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4260 ;; Integer addition/subtraction instructions.
4262 (define_expand "adddi3"
4263   [(set (match_operand:DI 0 "register_operand" "")
4264         (plus:DI (match_operand:DI 1 "register_operand" "")
4265                  (match_operand:DI 2 "arith_double_add_operand" "")))]
4266   ""
4268   if (! TARGET_ARCH64)
4269     {
4270       emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4271                           gen_rtx_SET (VOIDmode, operands[0],
4272                                    gen_rtx_PLUS (DImode, operands[1],
4273                                                  operands[2])),
4274                           gen_rtx_CLOBBER (VOIDmode,
4275                                    gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4276       DONE;
4277     }
4280 (define_insn_and_split "adddi3_insn_sp32"
4281   [(set (match_operand:DI 0 "register_operand" "=r")
4282         (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4283                  (match_operand:DI 2 "arith_double_operand" "rHI")))
4284    (clobber (reg:CC 100))]
4285   "! TARGET_ARCH64"
4286   "#"
4287   "&& reload_completed"
4288   [(parallel [(set (reg:CC_NOOV 100)
4289                    (compare:CC_NOOV (plus:SI (match_dup 4)
4290                                              (match_dup 5))
4291                                     (const_int 0)))
4292               (set (match_dup 3)
4293                    (plus:SI (match_dup 4) (match_dup 5)))])
4294    (set (match_dup 6)
4295         (plus:SI (plus:SI (match_dup 7)
4296                           (match_dup 8))
4297                  (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4299   operands[3] = gen_lowpart (SImode, operands[0]);
4300   operands[4] = gen_lowpart (SImode, operands[1]);
4301   operands[5] = gen_lowpart (SImode, operands[2]);
4302   operands[6] = gen_highpart (SImode, operands[0]);
4303   operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
4304 #if HOST_BITS_PER_WIDE_INT == 32
4305   if (GET_CODE (operands[2]) == CONST_INT)
4306     {
4307       if (INTVAL (operands[2]) < 0)
4308         operands[8] = constm1_rtx;
4309       else
4310         operands[8] = const0_rtx;
4311     }
4312   else
4313 #endif
4314     operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4316   [(set_attr "length" "2")])
4318 ;; LTU here means "carry set"
4319 (define_insn "addx"
4320   [(set (match_operand:SI 0 "register_operand" "=r")
4321         (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4322                           (match_operand:SI 2 "arith_operand" "rI"))
4323                  (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4324   ""
4325   "addx\t%1, %2, %0"
4326   [(set_attr "type" "ialuX")])
4328 (define_insn_and_split "*addx_extend_sp32"
4329   [(set (match_operand:DI 0 "register_operand" "=r")
4330         (zero_extend:DI (plus:SI (plus:SI
4331                                   (match_operand:SI 1 "register_or_zero_operand" "%rJ")
4332                                   (match_operand:SI 2 "arith_operand" "rI"))
4333                                  (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4334   "! TARGET_ARCH64"
4335   "#"
4336   "&& reload_completed"
4337   [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
4338                                (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4339    (set (match_dup 4) (const_int 0))]
4340   "operands[3] = gen_lowpart (SImode, operands[0]);
4341    operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
4342   [(set_attr "length" "2")])
4344 (define_insn "*addx_extend_sp64"
4345   [(set (match_operand:DI 0 "register_operand" "=r")
4346         (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
4347                                           (match_operand:SI 2 "arith_operand" "rI"))
4348                                  (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4349   "TARGET_ARCH64"
4350   "addx\t%r1, %2, %0"
4351   [(set_attr "type" "ialuX")])
4353 (define_insn_and_split ""
4354   [(set (match_operand:DI 0 "register_operand" "=r")
4355         (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4356                  (match_operand:DI 2 "register_operand" "r")))
4357    (clobber (reg:CC 100))]
4358   "! TARGET_ARCH64"
4359   "#"
4360   "&& reload_completed"
4361   [(parallel [(set (reg:CC_NOOV 100)
4362                    (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
4363                                     (const_int 0)))
4364               (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
4365    (set (match_dup 6)
4366         (plus:SI (plus:SI (match_dup 4) (const_int 0))
4367                  (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4368   "operands[3] = gen_lowpart (SImode, operands[2]);
4369    operands[4] = gen_highpart (SImode, operands[2]);
4370    operands[5] = gen_lowpart (SImode, operands[0]);
4371    operands[6] = gen_highpart (SImode, operands[0]);"
4372   [(set_attr "length" "2")])
4374 (define_insn "*adddi3_sp64"
4375   [(set (match_operand:DI 0 "register_operand" "=r,r")
4376         (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
4377                  (match_operand:DI 2 "arith_add_operand" "rI,O")))]
4378   "TARGET_ARCH64"
4379   "@
4380    add\t%1, %2, %0
4381    sub\t%1, -%2, %0")
4383 (define_insn "addsi3"
4384   [(set (match_operand:SI 0 "register_operand" "=r,r,d")
4385         (plus:SI (match_operand:SI 1 "register_operand" "%r,r,d")
4386                  (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
4387   ""
4388   "@
4389    add\t%1, %2, %0
4390    sub\t%1, -%2, %0
4391    fpadd32s\t%1, %2, %0"
4392   [(set_attr "type" "*,*,fga")
4393    (set_attr "fptype" "*,*,single")])
4395 (define_insn "*cmp_cc_plus"
4396   [(set (reg:CC_NOOV 100)
4397         (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
4398                                   (match_operand:SI 1 "arith_operand" "rI"))
4399                          (const_int 0)))]
4400   ""
4401   "addcc\t%0, %1, %%g0"
4402   [(set_attr "type" "compare")])
4404 (define_insn "*cmp_ccx_plus"
4405   [(set (reg:CCX_NOOV 100)
4406         (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_operand" "%r")
4407                                    (match_operand:DI 1 "arith_operand" "rI"))
4408                           (const_int 0)))]
4409   "TARGET_ARCH64"
4410   "addcc\t%0, %1, %%g0"
4411   [(set_attr "type" "compare")])
4413 (define_insn "*cmp_cc_plus_set"
4414   [(set (reg:CC_NOOV 100)
4415         (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4416                                   (match_operand:SI 2 "arith_operand" "rI"))
4417                          (const_int 0)))
4418    (set (match_operand:SI 0 "register_operand" "=r")
4419         (plus:SI (match_dup 1) (match_dup 2)))]
4420   ""
4421   "addcc\t%1, %2, %0"
4422   [(set_attr "type" "compare")])
4424 (define_insn "*cmp_ccx_plus_set"
4425   [(set (reg:CCX_NOOV 100)
4426         (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_operand" "%r")
4427                                    (match_operand:DI 2 "arith_operand" "rI"))
4428                           (const_int 0)))
4429    (set (match_operand:DI 0 "register_operand" "=r")
4430         (plus:DI (match_dup 1) (match_dup 2)))]
4431   "TARGET_ARCH64"
4432   "addcc\t%1, %2, %0"
4433   [(set_attr "type" "compare")])
4435 (define_expand "subdi3"
4436   [(set (match_operand:DI 0 "register_operand" "")
4437         (minus:DI (match_operand:DI 1 "register_operand" "")
4438                   (match_operand:DI 2 "arith_double_add_operand" "")))]
4439   ""
4441   if (! TARGET_ARCH64)
4442     {
4443       emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4444                           gen_rtx_SET (VOIDmode, operands[0],
4445                                    gen_rtx_MINUS (DImode, operands[1],
4446                                                   operands[2])),
4447                           gen_rtx_CLOBBER (VOIDmode,
4448                                    gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4449       DONE;
4450     }
4453 (define_insn_and_split "subdi3_insn_sp32"
4454   [(set (match_operand:DI 0 "register_operand" "=r")
4455         (minus:DI (match_operand:DI 1 "register_operand" "r")
4456                   (match_operand:DI 2 "arith_double_operand" "rHI")))
4457    (clobber (reg:CC 100))]
4458   "! TARGET_ARCH64"
4459   "#"
4460   "&& reload_completed"
4461   [(parallel [(set (reg:CC_NOOV 100)
4462                    (compare:CC_NOOV (minus:SI (match_dup 4)
4463                                               (match_dup 5))
4464                                     (const_int 0)))
4465               (set (match_dup 3)
4466                    (minus:SI (match_dup 4) (match_dup 5)))])
4467    (set (match_dup 6)
4468         (minus:SI (minus:SI (match_dup 7)
4469                             (match_dup 8))
4470                   (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4472   operands[3] = gen_lowpart (SImode, operands[0]);
4473   operands[4] = gen_lowpart (SImode, operands[1]);
4474   operands[5] = gen_lowpart (SImode, operands[2]);
4475   operands[6] = gen_highpart (SImode, operands[0]);
4476   operands[7] = gen_highpart (SImode, operands[1]);
4477 #if HOST_BITS_PER_WIDE_INT == 32
4478   if (GET_CODE (operands[2]) == CONST_INT)
4479     {
4480       if (INTVAL (operands[2]) < 0)
4481         operands[8] = constm1_rtx;
4482       else
4483         operands[8] = const0_rtx;
4484     }
4485   else
4486 #endif
4487     operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4489   [(set_attr "length" "2")])
4491 ;; LTU here means "carry set"
4492 (define_insn "subx"
4493   [(set (match_operand:SI 0 "register_operand" "=r")
4494         (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4495                             (match_operand:SI 2 "arith_operand" "rI"))
4496                   (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4497   ""
4498   "subx\t%r1, %2, %0"
4499   [(set_attr "type" "ialuX")])
4501 (define_insn "*subx_extend_sp64"
4502   [(set (match_operand:DI 0 "register_operand" "=r")
4503         (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4504                                             (match_operand:SI 2 "arith_operand" "rI"))
4505                                   (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4506   "TARGET_ARCH64"
4507   "subx\t%r1, %2, %0"
4508   [(set_attr "type" "ialuX")])
4510 (define_insn_and_split "*subx_extend"
4511   [(set (match_operand:DI 0 "register_operand" "=r")
4512         (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4513                                             (match_operand:SI 2 "arith_operand" "rI"))
4514                                   (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4515   "! TARGET_ARCH64"
4516   "#"
4517   "&& reload_completed"
4518   [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
4519                                 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4520    (set (match_dup 4) (const_int 0))]
4521   "operands[3] = gen_lowpart (SImode, operands[0]);
4522    operands[4] = gen_highpart (SImode, operands[0]);"
4523   [(set_attr "length" "2")])
4525 (define_insn_and_split ""
4526   [(set (match_operand:DI 0 "register_operand" "=r")
4527       (minus:DI (match_operand:DI 1 "register_operand" "r")
4528                 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
4529    (clobber (reg:CC 100))]
4530   "! TARGET_ARCH64"
4531   "#"
4532   "&& reload_completed"
4533   [(parallel [(set (reg:CC_NOOV 100)
4534                    (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
4535                                     (const_int 0)))
4536               (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
4537    (set (match_dup 6)
4538         (minus:SI (minus:SI (match_dup 4) (const_int 0))
4539                   (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4540   "operands[3] = gen_lowpart (SImode, operands[1]);
4541    operands[4] = gen_highpart (SImode, operands[1]);
4542    operands[5] = gen_lowpart (SImode, operands[0]);
4543    operands[6] = gen_highpart (SImode, operands[0]);"
4544   [(set_attr "length" "2")])
4546 (define_insn "*subdi3_sp64"
4547   [(set (match_operand:DI 0 "register_operand" "=r,r")
4548         (minus:DI (match_operand:DI 1 "register_operand" "r,r")
4549                   (match_operand:DI 2 "arith_add_operand" "rI,O")))]
4550   "TARGET_ARCH64"
4551   "@
4552    sub\t%1, %2, %0
4553    add\t%1, -%2, %0")
4555 (define_insn "subsi3"
4556   [(set (match_operand:SI 0 "register_operand" "=r,r,d")
4557         (minus:SI (match_operand:SI 1 "register_operand" "r,r,d")
4558                   (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
4559   ""
4560   "@
4561    sub\t%1, %2, %0
4562    add\t%1, -%2, %0
4563    fpsub32s\t%1, %2, %0"
4564   [(set_attr "type" "*,*,fga")
4565    (set_attr "fptype" "*,*,single")])
4567 (define_insn "*cmp_minus_cc"
4568   [(set (reg:CC_NOOV 100)
4569         (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
4570                                    (match_operand:SI 1 "arith_operand" "rI"))
4571                          (const_int 0)))]
4572   ""
4573   "subcc\t%r0, %1, %%g0"
4574   [(set_attr "type" "compare")])
4576 (define_insn "*cmp_minus_ccx"
4577   [(set (reg:CCX_NOOV 100)
4578         (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
4579                                     (match_operand:DI 1 "arith_operand" "rI"))
4580                           (const_int 0)))]
4581   "TARGET_ARCH64"
4582   "subcc\t%0, %1, %%g0"
4583   [(set_attr "type" "compare")])
4585 (define_insn "cmp_minus_cc_set"
4586   [(set (reg:CC_NOOV 100)
4587         (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4588                                    (match_operand:SI 2 "arith_operand" "rI"))
4589                          (const_int 0)))
4590    (set (match_operand:SI 0 "register_operand" "=r")
4591         (minus:SI (match_dup 1) (match_dup 2)))]
4592   ""
4593   "subcc\t%r1, %2, %0"
4594   [(set_attr "type" "compare")])
4596 (define_insn "*cmp_minus_ccx_set"
4597   [(set (reg:CCX_NOOV 100)
4598         (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
4599                                     (match_operand:DI 2 "arith_operand" "rI"))
4600                           (const_int 0)))
4601    (set (match_operand:DI 0 "register_operand" "=r")
4602         (minus:DI (match_dup 1) (match_dup 2)))]
4603   "TARGET_ARCH64"
4604   "subcc\t%1, %2, %0"
4605   [(set_attr "type" "compare")])
4608 ;; Integer multiply/divide instructions.
4610 ;; The 32-bit multiply/divide instructions are deprecated on v9, but at
4611 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
4613 (define_insn "mulsi3"
4614   [(set (match_operand:SI 0 "register_operand" "=r")
4615         (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4616                  (match_operand:SI 2 "arith_operand" "rI")))]
4617   "TARGET_HARD_MUL"
4618   "smul\t%1, %2, %0"
4619   [(set_attr "type" "imul")])
4621 (define_expand "muldi3"
4622   [(set (match_operand:DI 0 "register_operand" "")
4623         (mult:DI (match_operand:DI 1 "arith_operand" "")
4624                  (match_operand:DI 2 "arith_operand" "")))]
4625   "TARGET_ARCH64 || TARGET_V8PLUS"
4627   if (TARGET_V8PLUS)
4628     {
4629       emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
4630       DONE;
4631     }
4634 (define_insn "*muldi3_sp64"
4635   [(set (match_operand:DI 0 "register_operand" "=r")
4636         (mult:DI (match_operand:DI 1 "arith_operand" "%r")
4637                  (match_operand:DI 2 "arith_operand" "rI")))]
4638   "TARGET_ARCH64"
4639   "mulx\t%1, %2, %0"
4640   [(set_attr "type" "imul")])
4642 ;; V8plus wide multiply.
4643 ;; XXX
4644 (define_insn "muldi3_v8plus"
4645   [(set (match_operand:DI 0 "register_operand" "=r,h")
4646         (mult:DI (match_operand:DI 1 "arith_operand" "%r,0")
4647                  (match_operand:DI 2 "arith_operand" "rI,rI")))
4648    (clobber (match_scratch:SI 3 "=&h,X"))
4649    (clobber (match_scratch:SI 4 "=&h,X"))]
4650   "TARGET_V8PLUS"
4652   if (sparc_check_64 (operands[1], insn) <= 0)
4653     output_asm_insn ("srl\t%L1, 0, %L1", operands);
4654   if (which_alternative == 1)
4655     output_asm_insn ("sllx\t%H1, 32, %H1", operands);
4656   if (GET_CODE (operands[2]) == CONST_INT)
4657     {
4658       if (which_alternative == 1)
4659         return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %2, %L0\;srlx\t%L0, 32, %H0";
4660       else
4661         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";
4662     }
4663   else if (rtx_equal_p (operands[1], operands[2]))
4664     {
4665       if (which_alternative == 1)
4666         return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %H1, %L0\;srlx\t%L0, 32, %H0";
4667       else
4668         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";
4669     }
4670   if (sparc_check_64 (operands[2], insn) <= 0)
4671     output_asm_insn ("srl\t%L2, 0, %L2", operands);
4672   if (which_alternative == 1)
4673     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";
4674   else
4675     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";
4677   [(set_attr "type" "multi")
4678    (set_attr "length" "9,8")])
4680 (define_insn "*cmp_mul_set"
4681   [(set (reg:CC 100)
4682         (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4683                     (match_operand:SI 2 "arith_operand" "rI"))
4684                     (const_int 0)))
4685    (set (match_operand:SI 0 "register_operand" "=r")
4686         (mult:SI (match_dup 1) (match_dup 2)))]
4687   "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
4688   "smulcc\t%1, %2, %0"
4689   [(set_attr "type" "imul")])
4691 (define_expand "mulsidi3"
4692   [(set (match_operand:DI 0 "register_operand" "")
4693         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4694                  (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
4695   "TARGET_HARD_MUL"
4697   if (CONSTANT_P (operands[2]))
4698     {
4699       if (TARGET_V8PLUS)
4700         emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
4701                                               operands[2]));
4702       else if (TARGET_ARCH32)
4703         emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
4704                                             operands[2]));
4705       else 
4706         emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
4707                                             operands[2]));
4708       DONE;
4709     }
4710   if (TARGET_V8PLUS)
4711     {
4712       emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
4713       DONE;
4714     }
4717 ;; V9 puts the 64-bit product in a 64-bit register.  Only out or global
4718 ;; registers can hold 64-bit values in the V8plus environment.
4719 ;; XXX
4720 (define_insn "mulsidi3_v8plus"
4721   [(set (match_operand:DI 0 "register_operand" "=h,r")
4722         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4723                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4724    (clobber (match_scratch:SI 3 "=X,&h"))]
4725   "TARGET_V8PLUS"
4726   "@
4727    smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4728    smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4729   [(set_attr "type" "multi")
4730    (set_attr "length" "2,3")])
4732 ;; XXX
4733 (define_insn "const_mulsidi3_v8plus"
4734   [(set (match_operand:DI 0 "register_operand" "=h,r")
4735         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4736                  (match_operand:DI 2 "small_int_operand" "I,I")))
4737    (clobber (match_scratch:SI 3 "=X,&h"))]
4738   "TARGET_V8PLUS"
4739   "@
4740    smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4741    smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4742   [(set_attr "type" "multi")
4743    (set_attr "length" "2,3")])
4745 ;; XXX
4746 (define_insn "*mulsidi3_sp32"
4747   [(set (match_operand:DI 0 "register_operand" "=r")
4748         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4749                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4750   "TARGET_HARD_MUL32"
4752   return TARGET_SPARCLET
4753          ? "smuld\t%1, %2, %L0"
4754          : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4756   [(set (attr "type")
4757         (if_then_else (eq_attr "isa" "sparclet")
4758                       (const_string "imul") (const_string "multi")))
4759    (set (attr "length")
4760         (if_then_else (eq_attr "isa" "sparclet")
4761                       (const_int 1) (const_int 2)))])
4763 (define_insn "*mulsidi3_sp64"
4764   [(set (match_operand:DI 0 "register_operand" "=r")
4765         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4766                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4767   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4768   "smul\t%1, %2, %0"
4769   [(set_attr "type" "imul")])
4771 ;; Extra pattern, because sign_extend of a constant isn't valid.
4773 ;; XXX
4774 (define_insn "const_mulsidi3_sp32"
4775   [(set (match_operand:DI 0 "register_operand" "=r")
4776         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4777                  (match_operand:DI 2 "small_int_operand" "I")))]
4778   "TARGET_HARD_MUL32"
4780   return TARGET_SPARCLET
4781          ? "smuld\t%1, %2, %L0"
4782          : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4784   [(set (attr "type")
4785         (if_then_else (eq_attr "isa" "sparclet")
4786                       (const_string "imul") (const_string "multi")))
4787    (set (attr "length")
4788         (if_then_else (eq_attr "isa" "sparclet")
4789                       (const_int 1) (const_int 2)))])
4791 (define_insn "const_mulsidi3_sp64"
4792   [(set (match_operand:DI 0 "register_operand" "=r")
4793         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4794                  (match_operand:DI 2 "small_int_operand" "I")))]
4795   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4796   "smul\t%1, %2, %0"
4797   [(set_attr "type" "imul")])
4799 (define_expand "smulsi3_highpart"
4800   [(set (match_operand:SI 0 "register_operand" "")
4801         (truncate:SI
4802          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4803                                (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
4804                       (const_int 32))))]
4805   "TARGET_HARD_MUL && TARGET_ARCH32"
4807   if (CONSTANT_P (operands[2]))
4808     {
4809       if (TARGET_V8PLUS)
4810         {
4811           emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
4812                                                         operands[1],
4813                                                         operands[2],
4814                                                         GEN_INT (32)));
4815           DONE;
4816         }
4817       emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
4818       DONE;
4819     }
4820   if (TARGET_V8PLUS)
4821     {
4822       emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
4823                                               operands[2], GEN_INT (32)));
4824       DONE;
4825     }
4828 ;; XXX
4829 (define_insn "smulsi3_highpart_v8plus"
4830   [(set (match_operand:SI 0 "register_operand" "=h,r")
4831         (truncate:SI
4832          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4833                                (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4834                       (match_operand:SI 3 "small_int_operand" "I,I"))))
4835    (clobber (match_scratch:SI 4 "=X,&h"))]
4836   "TARGET_V8PLUS"
4837   "@
4838    smul\t%1, %2, %0\;srlx\t%0, %3, %0
4839    smul\t%1, %2, %4\;srlx\t%4, %3, %0"
4840   [(set_attr "type" "multi")
4841    (set_attr "length" "2")])
4843 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
4844 ;; XXX
4845 (define_insn ""
4846   [(set (match_operand:SI 0 "register_operand" "=h,r")
4847         (subreg:SI
4848          (lshiftrt:DI
4849           (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4850                    (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4851           (match_operand:SI 3 "small_int_operand" "I,I"))
4852          4))
4853    (clobber (match_scratch:SI 4 "=X,&h"))]
4854   "TARGET_V8PLUS"
4855   "@
4856    smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4857    smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4858   [(set_attr "type" "multi")
4859    (set_attr "length" "2")])
4861 ;; XXX
4862 (define_insn "const_smulsi3_highpart_v8plus"
4863   [(set (match_operand:SI 0 "register_operand" "=h,r")
4864         (truncate:SI
4865          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4866                                (match_operand:DI 2 "small_int_operand" "I,I"))
4867                       (match_operand:SI 3 "small_int_operand" "I,I"))))
4868    (clobber (match_scratch:SI 4 "=X,&h"))]
4869   "TARGET_V8PLUS"
4870   "@
4871    smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4872    smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4873   [(set_attr "type" "multi")
4874    (set_attr "length" "2")])
4876 ;; XXX
4877 (define_insn "*smulsi3_highpart_sp32"
4878   [(set (match_operand:SI 0 "register_operand" "=r")
4879         (truncate:SI
4880          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4881                                (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
4882                       (const_int 32))))]
4883   "TARGET_HARD_MUL32"
4884   "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4885   [(set_attr "type" "multi")
4886    (set_attr "length" "2")])
4888 ;; XXX
4889 (define_insn "const_smulsi3_highpart"
4890   [(set (match_operand:SI 0 "register_operand" "=r")
4891         (truncate:SI
4892          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4893                                (match_operand:DI 2 "small_int_operand" "i"))
4894                       (const_int 32))))]
4895   "TARGET_HARD_MUL32"
4896   "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4897   [(set_attr "type" "multi")
4898    (set_attr "length" "2")])
4900 (define_expand "umulsidi3"
4901   [(set (match_operand:DI 0 "register_operand" "")
4902         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4903                  (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
4904   "TARGET_HARD_MUL"
4906   if (CONSTANT_P (operands[2]))
4907     {
4908       if (TARGET_V8PLUS)
4909         emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
4910                                                operands[2]));
4911       else if (TARGET_ARCH32)
4912         emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
4913                                              operands[2]));
4914       else 
4915         emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
4916                                              operands[2]));
4917       DONE;
4918     }
4919   if (TARGET_V8PLUS)
4920     {
4921       emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
4922       DONE;
4923     }
4926 ;; XXX
4927 (define_insn "umulsidi3_v8plus"
4928   [(set (match_operand:DI 0 "register_operand" "=h,r")
4929         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4930                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4931    (clobber (match_scratch:SI 3 "=X,&h"))]
4932   "TARGET_V8PLUS"
4933   "@
4934    umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4935    umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4936   [(set_attr "type" "multi")
4937    (set_attr "length" "2,3")])
4939 ;; XXX
4940 (define_insn "*umulsidi3_sp32"
4941   [(set (match_operand:DI 0 "register_operand" "=r")
4942         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4943                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4944   "TARGET_HARD_MUL32"
4946   return TARGET_SPARCLET
4947          ? "umuld\t%1, %2, %L0"
4948          : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
4950   [(set (attr "type")
4951         (if_then_else (eq_attr "isa" "sparclet")
4952                       (const_string "imul") (const_string "multi")))
4953    (set (attr "length")
4954         (if_then_else (eq_attr "isa" "sparclet")
4955                       (const_int 1) (const_int 2)))])
4957 (define_insn "*umulsidi3_sp64"
4958   [(set (match_operand:DI 0 "register_operand" "=r")
4959         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4960                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4961   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4962   "umul\t%1, %2, %0"
4963   [(set_attr "type" "imul")])
4965 ;; Extra pattern, because sign_extend of a constant isn't valid.
4967 ;; XXX
4968 (define_insn "const_umulsidi3_sp32"
4969   [(set (match_operand:DI 0 "register_operand" "=r")
4970         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4971                  (match_operand:DI 2 "uns_small_int_operand" "")))]
4972   "TARGET_HARD_MUL32"
4974   return TARGET_SPARCLET
4975          ? "umuld\t%1, %s2, %L0"
4976          : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
4978   [(set (attr "type")
4979         (if_then_else (eq_attr "isa" "sparclet")
4980                       (const_string "imul") (const_string "multi")))
4981    (set (attr "length")
4982         (if_then_else (eq_attr "isa" "sparclet")
4983                       (const_int 1) (const_int 2)))])
4985 (define_insn "const_umulsidi3_sp64"
4986   [(set (match_operand:DI 0 "register_operand" "=r")
4987         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4988                  (match_operand:DI 2 "uns_small_int_operand" "")))]
4989   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4990   "umul\t%1, %s2, %0"
4991   [(set_attr "type" "imul")])
4993 ;; XXX
4994 (define_insn "const_umulsidi3_v8plus"
4995   [(set (match_operand:DI 0 "register_operand" "=h,r")
4996         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4997                  (match_operand:DI 2 "uns_small_int_operand" "")))
4998    (clobber (match_scratch:SI 3 "=X,h"))]
4999   "TARGET_V8PLUS"
5000   "@
5001    umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
5002    umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5003   [(set_attr "type" "multi")
5004    (set_attr "length" "2,3")])
5006 (define_expand "umulsi3_highpart"
5007   [(set (match_operand:SI 0 "register_operand" "")
5008         (truncate:SI
5009          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5010                                (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
5011                       (const_int 32))))]
5012   "TARGET_HARD_MUL && TARGET_ARCH32"
5014   if (CONSTANT_P (operands[2]))
5015     {
5016       if (TARGET_V8PLUS)
5017         {
5018           emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
5019                                                         operands[1],
5020                                                         operands[2],
5021                                                         GEN_INT (32)));
5022           DONE;
5023         }
5024       emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
5025       DONE;
5026     }
5027   if (TARGET_V8PLUS)
5028     {
5029       emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
5030                                               operands[2], GEN_INT (32)));
5031       DONE;
5032     }
5035 ;; XXX
5036 (define_insn "umulsi3_highpart_v8plus"
5037   [(set (match_operand:SI 0 "register_operand" "=h,r")
5038         (truncate:SI
5039          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5040                                (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5041                       (match_operand:SI 3 "small_int_operand" "I,I"))))
5042    (clobber (match_scratch:SI 4 "=X,h"))]
5043   "TARGET_V8PLUS"
5044   "@
5045    umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5046    umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5047   [(set_attr "type" "multi")
5048    (set_attr "length" "2")])
5050 ;; XXX
5051 (define_insn "const_umulsi3_highpart_v8plus"
5052   [(set (match_operand:SI 0 "register_operand" "=h,r")
5053         (truncate:SI
5054          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5055                                (match_operand:DI 2 "uns_small_int_operand" ""))
5056                       (match_operand:SI 3 "small_int_operand" "I,I"))))
5057    (clobber (match_scratch:SI 4 "=X,h"))]
5058   "TARGET_V8PLUS"
5059   "@
5060    umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
5061    umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
5062   [(set_attr "type" "multi")
5063    (set_attr "length" "2")])
5065 ;; XXX
5066 (define_insn "*umulsi3_highpart_sp32"
5067   [(set (match_operand:SI 0 "register_operand" "=r")
5068         (truncate:SI
5069          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5070                                (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
5071                       (const_int 32))))]
5072   "TARGET_HARD_MUL32"
5073   "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
5074   [(set_attr "type" "multi")
5075    (set_attr "length" "2")])
5077 ;; XXX
5078 (define_insn "const_umulsi3_highpart"
5079   [(set (match_operand:SI 0 "register_operand" "=r")
5080         (truncate:SI
5081          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5082                                (match_operand:DI 2 "uns_small_int_operand" ""))
5083                       (const_int 32))))]
5084   "TARGET_HARD_MUL32"
5085   "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
5086   [(set_attr "type" "multi")
5087    (set_attr "length" "2")])
5089 ;; The V8 architecture specifies that there must be 3 instructions between
5090 ;; a Y register write and a use of it for correct results.
5092 (define_expand "divsi3"
5093   [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
5094                    (div:SI (match_operand:SI 1 "register_operand" "r,r")
5095                            (match_operand:SI 2 "input_operand" "rI,m")))
5096               (clobber (match_scratch:SI 3 "=&r,&r"))])]
5097   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5099   if (TARGET_ARCH64)
5100     {
5101       operands[3] = gen_reg_rtx(SImode);
5102       emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
5103       emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
5104                                   operands[3]));
5105       DONE;
5106     }
5109 (define_insn "divsi3_sp32"
5110   [(set (match_operand:SI 0 "register_operand" "=r,r")
5111         (div:SI (match_operand:SI 1 "register_operand" "r,r")
5112                 (match_operand:SI 2 "input_operand" "rI,m")))
5113    (clobber (match_scratch:SI 3 "=&r,&r"))]
5114   "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
5115    && TARGET_ARCH32"
5117   if (which_alternative == 0)
5118     if (TARGET_V9)
5119       return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdiv\t%1, %2, %0";
5120     else
5121       return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
5122   else
5123     if (TARGET_V9)
5124       return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tld\t%2, %3\n\tsdiv\t%1, %3, %0";
5125     else
5126       return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tld\t%2, %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
5128   [(set_attr "type" "multi")
5129    (set (attr "length")
5130         (if_then_else (eq_attr "isa" "v9")
5131                       (const_int 4) (const_int 6)))])
5133 (define_insn "divsi3_sp64"
5134   [(set (match_operand:SI 0 "register_operand" "=r")
5135         (div:SI (match_operand:SI 1 "register_operand" "r")
5136                 (match_operand:SI 2 "input_operand" "rI")))
5137    (use (match_operand:SI 3 "register_operand" "r"))]
5138   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5139   "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
5140   [(set_attr "type" "multi")
5141    (set_attr "length" "2")])
5143 (define_insn "divdi3"
5144   [(set (match_operand:DI 0 "register_operand" "=r")
5145         (div:DI (match_operand:DI 1 "register_operand" "r")
5146                 (match_operand:DI 2 "arith_operand" "rI")))]
5147   "TARGET_ARCH64"
5148   "sdivx\t%1, %2, %0"
5149   [(set_attr "type" "idiv")])
5151 (define_insn "*cmp_sdiv_cc_set"
5152   [(set (reg:CC 100)
5153         (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
5154                             (match_operand:SI 2 "arith_operand" "rI"))
5155                     (const_int 0)))
5156    (set (match_operand:SI 0 "register_operand" "=r")
5157         (div:SI (match_dup 1) (match_dup 2)))
5158    (clobber (match_scratch:SI 3 "=&r"))]
5159   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5161   if (TARGET_V9)
5162     return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdivcc\t%1, %2, %0";
5163   else
5164     return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
5166   [(set_attr "type" "multi")
5167    (set (attr "length")
5168         (if_then_else (eq_attr "isa" "v9")
5169                       (const_int 3) (const_int 6)))])
5171 ;; XXX
5172 (define_expand "udivsi3"
5173   [(set (match_operand:SI 0 "register_operand" "")
5174         (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "")
5175                  (match_operand:SI 2 "input_operand" "")))]
5176   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5177   "")
5179 ;; The V8 architecture specifies that there must be 3 instructions between
5180 ;; a Y register write and a use of it for correct results.
5182 (define_insn "udivsi3_sp32"
5183   [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
5184         (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r,r,m")
5185                  (match_operand:SI 2 "input_operand" "rI,m,r")))]
5186   "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
5187    && TARGET_ARCH32"
5189   output_asm_insn ("wr\t%%g0, %%g0, %%y", operands);
5190   switch (which_alternative)
5191     {
5192     default:
5193       return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
5194     case 1:
5195       return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
5196     case 2:
5197       return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
5198     }
5200   [(set_attr "type" "multi")
5201    (set_attr "length" "5")])
5203 (define_insn "udivsi3_sp64"
5204   [(set (match_operand:SI 0 "register_operand" "=r")
5205         (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r")
5206                  (match_operand:SI 2 "input_operand" "rI")))]
5207   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5208   "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
5209   [(set_attr "type" "multi")
5210    (set_attr "length" "2")])
5212 (define_insn "udivdi3"
5213   [(set (match_operand:DI 0 "register_operand" "=r")
5214         (udiv:DI (match_operand:DI 1 "register_operand" "r")
5215                  (match_operand:DI 2 "arith_operand" "rI")))]
5216   "TARGET_ARCH64"
5217   "udivx\t%1, %2, %0"
5218   [(set_attr "type" "idiv")])
5220 (define_insn "*cmp_udiv_cc_set"
5221   [(set (reg:CC 100)
5222         (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
5223                              (match_operand:SI 2 "arith_operand" "rI"))
5224                     (const_int 0)))
5225    (set (match_operand:SI 0 "register_operand" "=r")
5226         (udiv:SI (match_dup 1) (match_dup 2)))]
5227   "TARGET_V8
5228    || TARGET_DEPRECATED_V8_INSNS"
5230   if (TARGET_V9)
5231     return "wr\t%%g0, %%g0, %%y\n\tudivcc\t%1, %2, %0";
5232   else
5233     return "wr\t%%g0, %%g0, %%y\n\tnop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
5235   [(set_attr "type" "multi")
5236    (set (attr "length")
5237         (if_then_else (eq_attr "isa" "v9")
5238                       (const_int 2) (const_int 5)))])
5240 ; sparclet multiply/accumulate insns
5242 (define_insn "*smacsi"
5243   [(set (match_operand:SI 0 "register_operand" "=r")
5244         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
5245                           (match_operand:SI 2 "arith_operand" "rI"))
5246                  (match_operand:SI 3 "register_operand" "0")))]
5247   "TARGET_SPARCLET"
5248   "smac\t%1, %2, %0"
5249   [(set_attr "type" "imul")])
5251 (define_insn "*smacdi"
5252   [(set (match_operand:DI 0 "register_operand" "=r")
5253         (plus:DI (mult:DI (sign_extend:DI
5254                            (match_operand:SI 1 "register_operand" "%r"))
5255                           (sign_extend:DI
5256                            (match_operand:SI 2 "register_operand" "r")))
5257                  (match_operand:DI 3 "register_operand" "0")))]
5258   "TARGET_SPARCLET"
5259   "smacd\t%1, %2, %L0"
5260   [(set_attr "type" "imul")])
5262 (define_insn "*umacdi"
5263   [(set (match_operand:DI 0 "register_operand" "=r")
5264         (plus:DI (mult:DI (zero_extend:DI
5265                            (match_operand:SI 1 "register_operand" "%r"))
5266                           (zero_extend:DI
5267                            (match_operand:SI 2 "register_operand" "r")))
5268                  (match_operand:DI 3 "register_operand" "0")))]
5269   "TARGET_SPARCLET"
5270   "umacd\t%1, %2, %L0"
5271   [(set_attr "type" "imul")])
5274 ;; Boolean instructions.
5276 ;; We define DImode `and' so with DImode `not' we can get
5277 ;; DImode `andn'.  Other combinations are possible.
5279 (define_mode_iterator V64I [DI V2SI V4HI V8QI])
5280 (define_mode_iterator V32I [SI V2HI V4QI])
5282 (define_expand "and<V64I:mode>3"
5283   [(set (match_operand:V64I 0 "register_operand" "")
5284         (and:V64I (match_operand:V64I 1 "arith_double_operand" "")
5285                   (match_operand:V64I 2 "arith_double_operand" "")))]
5286   ""
5287   "")
5289 (define_insn "*and<V64I:mode>3_sp32"
5290   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5291         (and:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5292                   (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5293   "! TARGET_ARCH64"
5294   "@
5295   #
5296   fand\t%1, %2, %0"
5297   [(set_attr "type" "*,fga")
5298    (set_attr "length" "2,*")
5299    (set_attr "fptype" "*,double")])
5301 (define_insn "*and<V64I:mode>3_sp64"
5302   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5303         (and:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
5304                   (match_operand:V64I 2 "arith_operand" "rI,b")))]
5305   "TARGET_ARCH64"
5306   "@
5307    and\t%1, %2, %0
5308    fand\t%1, %2, %0"
5309   [(set_attr "type" "*,fga")
5310    (set_attr "fptype" "*,double")])
5312 (define_insn "and<V32I:mode>3"
5313   [(set (match_operand:V32I 0 "register_operand" "=r,d")
5314         (and:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
5315                   (match_operand:V32I 2 "arith_operand" "rI,d")))]
5316   ""
5317   "@
5318    and\t%1, %2, %0
5319    fands\t%1, %2, %0"
5320   [(set_attr "type" "*,fga")
5321    (set_attr "fptype" "*,single")])
5323 (define_split
5324   [(set (match_operand:SI 0 "register_operand" "")
5325         (and:SI (match_operand:SI 1 "register_operand" "")
5326                 (match_operand:SI 2 "const_compl_high_operand" "")))
5327    (clobber (match_operand:SI 3 "register_operand" ""))]
5328   ""
5329   [(set (match_dup 3) (match_dup 4))
5330    (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
5332   operands[4] = GEN_INT (~INTVAL (operands[2]));
5335 (define_insn_and_split "*and_not_<V64I:mode>_sp32"
5336   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5337         (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
5338                   (match_operand:V64I 2 "register_operand" "r,b")))]
5339   "! TARGET_ARCH64"
5340   "@
5341    #
5342    fandnot1\t%1, %2, %0"
5343   "&& reload_completed
5344    && ((GET_CODE (operands[0]) == REG
5345         && REGNO (operands[0]) < 32)
5346        || (GET_CODE (operands[0]) == SUBREG
5347            && GET_CODE (SUBREG_REG (operands[0])) == REG
5348            && REGNO (SUBREG_REG (operands[0])) < 32))"
5349   [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
5350    (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
5351   "operands[3] = gen_highpart (SImode, operands[0]);
5352    operands[4] = gen_highpart (SImode, operands[1]);
5353    operands[5] = gen_highpart (SImode, operands[2]);
5354    operands[6] = gen_lowpart (SImode, operands[0]);
5355    operands[7] = gen_lowpart (SImode, operands[1]);
5356    operands[8] = gen_lowpart (SImode, operands[2]);"
5357   [(set_attr "type" "*,fga")
5358    (set_attr "length" "2,*")
5359    (set_attr "fptype" "*,double")])
5361 (define_insn "*and_not_<V64I:mode>_sp64"
5362   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5363         (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
5364                   (match_operand:V64I 2 "register_operand" "r,b")))]
5365   "TARGET_ARCH64"
5366   "@
5367    andn\t%2, %1, %0
5368    fandnot1\t%1, %2, %0"
5369   [(set_attr "type" "*,fga")
5370    (set_attr "fptype" "*,double")])
5372 (define_insn "*and_not_<V32I:mode>"
5373   [(set (match_operand:V32I 0 "register_operand" "=r,d")
5374         (and:V32I (not:V32I (match_operand:V32I 1 "register_operand" "%r,d"))
5375                   (match_operand:V32I 2 "register_operand" "r,d")))]
5376   ""
5377   "@
5378    andn\t%2, %1, %0
5379    fandnot1s\t%1, %2, %0"
5380   [(set_attr "type" "*,fga")
5381    (set_attr "fptype" "*,single")])
5383 (define_expand "ior<V64I:mode>3"
5384   [(set (match_operand:V64I 0 "register_operand" "")
5385         (ior:V64I (match_operand:V64I 1 "arith_double_operand" "")
5386                   (match_operand:V64I 2 "arith_double_operand" "")))]
5387   ""
5388   "")
5390 (define_insn "*ior<V64I:mode>3_sp32"
5391   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5392         (ior:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5393                   (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5394   "! TARGET_ARCH64"
5395   "@
5396   #
5397   for\t%1, %2, %0"
5398   [(set_attr "type" "*,fga")
5399    (set_attr "length" "2,*")
5400    (set_attr "fptype" "*,double")])
5402 (define_insn "*ior<V64I:mode>3_sp64"
5403   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5404         (ior:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
5405                   (match_operand:V64I 2 "arith_operand" "rI,b")))]
5406   "TARGET_ARCH64"
5407   "@
5408   or\t%1, %2, %0
5409   for\t%1, %2, %0"
5410   [(set_attr "type" "*,fga")
5411    (set_attr "fptype" "*,double")])
5413 (define_insn "ior<V32I:mode>3"
5414   [(set (match_operand:V32I 0 "register_operand" "=r,d")
5415         (ior:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
5416                   (match_operand:V32I 2 "arith_operand" "rI,d")))]
5417   ""
5418   "@
5419    or\t%1, %2, %0
5420    fors\t%1, %2, %0"
5421   [(set_attr "type" "*,fga")
5422    (set_attr "fptype" "*,single")])
5424 (define_split
5425   [(set (match_operand:SI 0 "register_operand" "")
5426         (ior:SI (match_operand:SI 1 "register_operand" "")
5427                 (match_operand:SI 2 "const_compl_high_operand" "")))
5428    (clobber (match_operand:SI 3 "register_operand" ""))]
5429   ""
5430   [(set (match_dup 3) (match_dup 4))
5431    (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
5433   operands[4] = GEN_INT (~INTVAL (operands[2]));
5436 (define_insn_and_split "*or_not_<V64I:mode>_sp32"
5437   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5438         (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
5439                   (match_operand:V64I 2 "register_operand" "r,b")))]
5440   "! TARGET_ARCH64"
5441   "@
5442    #
5443    fornot1\t%1, %2, %0"
5444   "&& reload_completed
5445    && ((GET_CODE (operands[0]) == REG
5446         && REGNO (operands[0]) < 32)
5447        || (GET_CODE (operands[0]) == SUBREG
5448            && GET_CODE (SUBREG_REG (operands[0])) == REG
5449            && REGNO (SUBREG_REG (operands[0])) < 32))"
5450   [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
5451    (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
5452   "operands[3] = gen_highpart (SImode, operands[0]);
5453    operands[4] = gen_highpart (SImode, operands[1]);
5454    operands[5] = gen_highpart (SImode, operands[2]);
5455    operands[6] = gen_lowpart (SImode, operands[0]);
5456    operands[7] = gen_lowpart (SImode, operands[1]);
5457    operands[8] = gen_lowpart (SImode, operands[2]);"
5458   [(set_attr "type" "*,fga")
5459    (set_attr "length" "2,*")
5460    (set_attr "fptype" "*,double")])
5462 (define_insn "*or_not_<V64I:mode>_sp64"
5463   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5464         (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
5465                   (match_operand:V64I 2 "register_operand" "r,b")))]
5466   "TARGET_ARCH64"
5467   "@
5468   orn\t%2, %1, %0
5469   fornot1\t%1, %2, %0"
5470   [(set_attr "type" "*,fga")
5471    (set_attr "fptype" "*,double")])
5473 (define_insn "*or_not_<V32I:mode>"
5474   [(set (match_operand:V32I 0 "register_operand" "=r,d")
5475         (ior:V32I (not:V32I (match_operand:V32I 1 "register_operand" "r,d"))
5476                   (match_operand:V32I 2 "register_operand" "r,d")))]
5477   ""
5478   "@
5479    orn\t%2, %1, %0
5480    fornot1s\t%1, %2, %0"
5481   [(set_attr "type" "*,fga")
5482    (set_attr "fptype" "*,single")])
5484 (define_expand "xor<V64I:mode>3"
5485   [(set (match_operand:V64I 0 "register_operand" "")
5486         (xor:V64I (match_operand:V64I 1 "arith_double_operand" "")
5487                   (match_operand:V64I 2 "arith_double_operand" "")))]
5488   ""
5489   "")
5491 (define_insn "*xor<V64I:mode>3_sp32"
5492   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5493         (xor:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5494                   (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5495   "! TARGET_ARCH64"
5496   "@
5497   #
5498   fxor\t%1, %2, %0"
5499   [(set_attr "type" "*,fga")
5500    (set_attr "length" "2,*")
5501    (set_attr "fptype" "*,double")])
5503 (define_insn "*xor<V64I:mode>3_sp64"
5504   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5505         (xor:V64I (match_operand:V64I 1 "arith_operand" "%rJ,b")
5506                   (match_operand:V64I 2 "arith_operand" "rI,b")))]
5507   "TARGET_ARCH64"
5508   "@
5509   xor\t%r1, %2, %0
5510   fxor\t%1, %2, %0"
5511   [(set_attr "type" "*,fga")
5512    (set_attr "fptype" "*,double")])
5514 (define_insn "xor<V32I:mode>3"
5515   [(set (match_operand:V32I 0 "register_operand" "=r,d")
5516         (xor:V32I (match_operand:V32I 1 "arith_operand" "%rJ,d")
5517                   (match_operand:V32I 2 "arith_operand" "rI,d")))]
5518   ""
5519   "@
5520    xor\t%r1, %2, %0
5521    fxors\t%1, %2, %0"
5522   [(set_attr "type" "*,fga")
5523    (set_attr "fptype" "*,single")])
5525 (define_split
5526   [(set (match_operand:SI 0 "register_operand" "")
5527         (xor:SI (match_operand:SI 1 "register_operand" "")
5528                 (match_operand:SI 2 "const_compl_high_operand" "")))
5529    (clobber (match_operand:SI 3 "register_operand" ""))]
5530    ""
5531   [(set (match_dup 3) (match_dup 4))
5532    (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
5534   operands[4] = GEN_INT (~INTVAL (operands[2]));
5537 (define_split
5538   [(set (match_operand:SI 0 "register_operand" "")
5539         (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
5540                         (match_operand:SI 2 "const_compl_high_operand" ""))))
5541    (clobber (match_operand:SI 3 "register_operand" ""))]
5542   ""
5543   [(set (match_dup 3) (match_dup 4))
5544    (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
5546   operands[4] = GEN_INT (~INTVAL (operands[2]));
5549 ;; Split DImode logical operations requiring two instructions.
5550 (define_split
5551   [(set (match_operand:V64I 0 "register_operand" "")
5552         (match_operator:V64I 1 "cc_arith_operator"      ; AND, IOR, XOR
5553                            [(match_operand:V64I 2 "register_operand" "")
5554                             (match_operand:V64I 3 "arith_double_operand" "")]))]
5555   "! TARGET_ARCH64
5556    && reload_completed
5557    && ((GET_CODE (operands[0]) == REG
5558         && REGNO (operands[0]) < 32)
5559        || (GET_CODE (operands[0]) == SUBREG
5560            && GET_CODE (SUBREG_REG (operands[0])) == REG
5561            && REGNO (SUBREG_REG (operands[0])) < 32))"
5562   [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
5563    (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
5565   operands[4] = gen_highpart (SImode, operands[0]);
5566   operands[5] = gen_lowpart (SImode, operands[0]);
5567   operands[6] = gen_highpart (SImode, operands[2]);
5568   operands[7] = gen_lowpart (SImode, operands[2]);
5569 #if HOST_BITS_PER_WIDE_INT == 32
5570   if (GET_CODE (operands[3]) == CONST_INT && <V64I:MODE>mode == DImode)
5571     {
5572       if (INTVAL (operands[3]) < 0)
5573         operands[8] = constm1_rtx;
5574       else
5575         operands[8] = const0_rtx;
5576     }
5577   else
5578 #endif
5579     operands[8] = gen_highpart_mode (SImode, <V64I:MODE>mode, operands[3]);
5580   operands[9] = gen_lowpart (SImode, operands[3]);
5583 ;; xnor patterns.  Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
5584 ;; Combine now canonicalizes to the rightmost expression.
5585 (define_insn_and_split "*xor_not_<V64I:mode>_sp32"
5586   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5587         (not:V64I (xor:V64I (match_operand:V64I 1 "register_operand" "r,b")
5588                             (match_operand:V64I 2 "register_operand" "r,b"))))]
5589   "! TARGET_ARCH64"
5590   "@
5591    #
5592    fxnor\t%1, %2, %0"
5593   "&& reload_completed
5594    && ((GET_CODE (operands[0]) == REG
5595         && REGNO (operands[0]) < 32)
5596        || (GET_CODE (operands[0]) == SUBREG
5597            && GET_CODE (SUBREG_REG (operands[0])) == REG
5598            && REGNO (SUBREG_REG (operands[0])) < 32))"
5599   [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
5600    (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
5601   "operands[3] = gen_highpart (SImode, operands[0]);
5602    operands[4] = gen_highpart (SImode, operands[1]);
5603    operands[5] = gen_highpart (SImode, operands[2]);
5604    operands[6] = gen_lowpart (SImode, operands[0]);
5605    operands[7] = gen_lowpart (SImode, operands[1]);
5606    operands[8] = gen_lowpart (SImode, operands[2]);"
5607   [(set_attr "type" "*,fga")
5608    (set_attr "length" "2,*")
5609    (set_attr "fptype" "*,double")])
5611 (define_insn "*xor_not_<V64I:mode>_sp64"
5612   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5613         (not:V64I (xor:V64I (match_operand:V64I 1 "register_or_zero_operand" "rJ,b")
5614                             (match_operand:V64I 2 "arith_operand" "rI,b"))))]
5615   "TARGET_ARCH64"
5616   "@
5617   xnor\t%r1, %2, %0
5618   fxnor\t%1, %2, %0"
5619   [(set_attr "type" "*,fga")
5620    (set_attr "fptype" "*,double")])
5622 (define_insn "*xor_not_<V32I:mode>"
5623   [(set (match_operand:V32I 0 "register_operand" "=r,d")
5624         (not:V32I (xor:V32I (match_operand:V32I 1 "register_or_zero_operand" "rJ,d")
5625                             (match_operand:V32I 2 "arith_operand" "rI,d"))))]
5626   ""
5627   "@
5628    xnor\t%r1, %2, %0
5629    fxnors\t%1, %2, %0"
5630   [(set_attr "type" "*,fga")
5631    (set_attr "fptype" "*,single")])
5633 ;; These correspond to the above in the case where we also (or only)
5634 ;; want to set the condition code.  
5636 (define_insn "*cmp_cc_arith_op"
5637   [(set (reg:CC 100)
5638         (compare:CC
5639          (match_operator:SI 2 "cc_arith_operator"
5640                             [(match_operand:SI 0 "arith_operand" "%r")
5641                              (match_operand:SI 1 "arith_operand" "rI")])
5642          (const_int 0)))]
5643   ""
5644   "%A2cc\t%0, %1, %%g0"
5645   [(set_attr "type" "compare")])
5647 (define_insn "*cmp_ccx_arith_op"
5648   [(set (reg:CCX 100)
5649         (compare:CCX
5650          (match_operator:DI 2 "cc_arith_operator"
5651                             [(match_operand:DI 0 "arith_operand" "%r")
5652                              (match_operand:DI 1 "arith_operand" "rI")])
5653          (const_int 0)))]
5654   "TARGET_ARCH64"
5655   "%A2cc\t%0, %1, %%g0"
5656   [(set_attr "type" "compare")])
5658 (define_insn "*cmp_cc_arith_op_set"
5659   [(set (reg:CC 100)
5660         (compare:CC
5661          (match_operator:SI 3 "cc_arith_operator"
5662                             [(match_operand:SI 1 "arith_operand" "%r")
5663                              (match_operand:SI 2 "arith_operand" "rI")])
5664          (const_int 0)))
5665    (set (match_operand:SI 0 "register_operand" "=r")
5666         (match_operator:SI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5667   "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5668   "%A3cc\t%1, %2, %0"
5669   [(set_attr "type" "compare")])
5671 (define_insn "*cmp_ccx_arith_op_set"
5672   [(set (reg:CCX 100)
5673         (compare:CCX
5674          (match_operator:DI 3 "cc_arith_operator"
5675                             [(match_operand:DI 1 "arith_operand" "%r")
5676                              (match_operand:DI 2 "arith_operand" "rI")])
5677          (const_int 0)))
5678    (set (match_operand:DI 0 "register_operand" "=r")
5679         (match_operator:DI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5680   "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5681   "%A3cc\t%1, %2, %0"
5682   [(set_attr "type" "compare")])
5684 (define_insn "*cmp_cc_xor_not"
5685   [(set (reg:CC 100)
5686         (compare:CC
5687          (not:SI (xor:SI (match_operand:SI 0 "register_or_zero_operand" "%rJ")
5688                          (match_operand:SI 1 "arith_operand" "rI")))
5689          (const_int 0)))]
5690   ""
5691   "xnorcc\t%r0, %1, %%g0"
5692   [(set_attr "type" "compare")])
5694 (define_insn "*cmp_ccx_xor_not"
5695   [(set (reg:CCX 100)
5696         (compare:CCX
5697          (not:DI (xor:DI (match_operand:DI 0 "register_or_zero_operand" "%rJ")
5698                          (match_operand:DI 1 "arith_operand" "rI")))
5699          (const_int 0)))]
5700   "TARGET_ARCH64"
5701   "xnorcc\t%r0, %1, %%g0"
5702   [(set_attr "type" "compare")])
5704 (define_insn "*cmp_cc_xor_not_set"
5705   [(set (reg:CC 100)
5706         (compare:CC
5707          (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
5708                          (match_operand:SI 2 "arith_operand" "rI")))
5709          (const_int 0)))
5710    (set (match_operand:SI 0 "register_operand" "=r")
5711         (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
5712   ""
5713   "xnorcc\t%r1, %2, %0"
5714   [(set_attr "type" "compare")])
5716 (define_insn "*cmp_ccx_xor_not_set"
5717   [(set (reg:CCX 100)
5718         (compare:CCX
5719          (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
5720                          (match_operand:DI 2 "arith_operand" "rI")))
5721          (const_int 0)))
5722    (set (match_operand:DI 0 "register_operand" "=r")
5723         (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
5724   "TARGET_ARCH64"
5725   "xnorcc\t%r1, %2, %0"
5726   [(set_attr "type" "compare")])
5728 (define_insn "*cmp_cc_arith_op_not"
5729   [(set (reg:CC 100)
5730         (compare:CC
5731          (match_operator:SI 2 "cc_arith_not_operator"
5732                             [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
5733                              (match_operand:SI 1 "register_or_zero_operand" "rJ")])
5734          (const_int 0)))]
5735   ""
5736   "%B2cc\t%r1, %0, %%g0"
5737   [(set_attr "type" "compare")])
5739 (define_insn "*cmp_ccx_arith_op_not"
5740   [(set (reg:CCX 100)
5741         (compare:CCX
5742          (match_operator:DI 2 "cc_arith_not_operator"
5743                             [(not:DI (match_operand:DI 0 "arith_operand" "rI"))
5744                              (match_operand:DI 1 "register_or_zero_operand" "rJ")])
5745          (const_int 0)))]
5746   "TARGET_ARCH64"
5747   "%B2cc\t%r1, %0, %%g0"
5748   [(set_attr "type" "compare")])
5750 (define_insn "*cmp_cc_arith_op_not_set"
5751   [(set (reg:CC 100)
5752         (compare:CC
5753          (match_operator:SI 3 "cc_arith_not_operator"
5754                             [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
5755                              (match_operand:SI 2 "register_or_zero_operand" "rJ")])
5756          (const_int 0)))
5757    (set (match_operand:SI 0 "register_operand" "=r")
5758         (match_operator:SI 4 "cc_arith_not_operator"
5759                             [(not:SI (match_dup 1)) (match_dup 2)]))]
5760   "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5761   "%B3cc\t%r2, %1, %0"
5762   [(set_attr "type" "compare")])
5764 (define_insn "*cmp_ccx_arith_op_not_set"
5765   [(set (reg:CCX 100)
5766         (compare:CCX
5767          (match_operator:DI 3 "cc_arith_not_operator"
5768                             [(not:DI (match_operand:DI 1 "arith_operand" "rI"))
5769                              (match_operand:DI 2 "register_or_zero_operand" "rJ")])
5770          (const_int 0)))
5771    (set (match_operand:DI 0 "register_operand" "=r")
5772         (match_operator:DI 4 "cc_arith_not_operator"
5773                             [(not:DI (match_dup 1)) (match_dup 2)]))]
5774   "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5775   "%B3cc\t%r2, %1, %0"
5776   [(set_attr "type" "compare")])
5778 ;; We cannot use the "neg" pseudo insn because the Sun assembler
5779 ;; does not know how to make it work for constants.
5781 (define_expand "negdi2"
5782   [(set (match_operand:DI 0 "register_operand" "=r")
5783         (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5784   ""
5786   if (! TARGET_ARCH64)
5787     {
5788       emit_insn (gen_rtx_PARALLEL
5789                  (VOIDmode,
5790                   gen_rtvec (2,
5791                              gen_rtx_SET (VOIDmode, operand0,
5792                                           gen_rtx_NEG (DImode, operand1)),
5793                              gen_rtx_CLOBBER (VOIDmode,
5794                                               gen_rtx_REG (CCmode,
5795                                                            SPARC_ICC_REG)))));
5796       DONE;
5797     }
5800 (define_insn_and_split "*negdi2_sp32"
5801   [(set (match_operand:DI 0 "register_operand" "=r")
5802         (neg:DI (match_operand:DI 1 "register_operand" "r")))
5803    (clobber (reg:CC 100))]
5804   "TARGET_ARCH32"
5805   "#"
5806   "&& reload_completed"
5807   [(parallel [(set (reg:CC_NOOV 100)
5808                    (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
5809                                     (const_int 0)))
5810               (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
5811    (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
5812                                 (ltu:SI (reg:CC 100) (const_int 0))))]
5813   "operands[2] = gen_highpart (SImode, operands[0]);
5814    operands[3] = gen_highpart (SImode, operands[1]);
5815    operands[4] = gen_lowpart (SImode, operands[0]);
5816    operands[5] = gen_lowpart (SImode, operands[1]);"
5817   [(set_attr "length" "2")])
5819 (define_insn "*negdi2_sp64"
5820   [(set (match_operand:DI 0 "register_operand" "=r")
5821         (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5822   "TARGET_ARCH64"
5823   "sub\t%%g0, %1, %0")
5825 (define_insn "negsi2"
5826   [(set (match_operand:SI 0 "register_operand" "=r")
5827         (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
5828   ""
5829   "sub\t%%g0, %1, %0")
5831 (define_insn "*cmp_cc_neg"
5832   [(set (reg:CC_NOOV 100)
5833         (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
5834                          (const_int 0)))]
5835   ""
5836   "subcc\t%%g0, %0, %%g0"
5837   [(set_attr "type" "compare")])
5839 (define_insn "*cmp_ccx_neg"
5840   [(set (reg:CCX_NOOV 100)
5841         (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_operand" "rI"))
5842                           (const_int 0)))]
5843   "TARGET_ARCH64"
5844   "subcc\t%%g0, %0, %%g0"
5845   [(set_attr "type" "compare")])
5847 (define_insn "*cmp_cc_set_neg"
5848   [(set (reg:CC_NOOV 100)
5849         (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
5850                          (const_int 0)))
5851    (set (match_operand:SI 0 "register_operand" "=r")
5852         (neg:SI (match_dup 1)))]
5853   ""
5854   "subcc\t%%g0, %1, %0"
5855   [(set_attr "type" "compare")])
5857 (define_insn "*cmp_ccx_set_neg"
5858   [(set (reg:CCX_NOOV 100)
5859         (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_operand" "rI"))
5860                           (const_int 0)))
5861    (set (match_operand:DI 0 "register_operand" "=r")
5862         (neg:DI (match_dup 1)))]
5863   "TARGET_ARCH64"
5864   "subcc\t%%g0, %1, %0"
5865   [(set_attr "type" "compare")])
5867 ;; We cannot use the "not" pseudo insn because the Sun assembler
5868 ;; does not know how to make it work for constants.
5869 (define_expand "one_cmpl<V64I:mode>2"
5870   [(set (match_operand:V64I 0 "register_operand" "")
5871         (not:V64I (match_operand:V64I 1 "register_operand" "")))]
5872   ""
5873   "")
5875 (define_insn_and_split "*one_cmpl<V64I:mode>2_sp32"
5876   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5877         (not:V64I (match_operand:V64I 1 "register_operand" "r,b")))]
5878   "! TARGET_ARCH64"
5879   "@
5880    #
5881    fnot1\t%1, %0"
5882   "&& reload_completed
5883    && ((GET_CODE (operands[0]) == REG
5884         && REGNO (operands[0]) < 32)
5885        || (GET_CODE (operands[0]) == SUBREG
5886            && GET_CODE (SUBREG_REG (operands[0])) == REG
5887            && REGNO (SUBREG_REG (operands[0])) < 32))"
5888   [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
5889    (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
5890   "operands[2] = gen_highpart (SImode, operands[0]);
5891    operands[3] = gen_highpart (SImode, operands[1]);
5892    operands[4] = gen_lowpart (SImode, operands[0]);
5893    operands[5] = gen_lowpart (SImode, operands[1]);"
5894   [(set_attr "type" "*,fga")
5895    (set_attr "length" "2,*")
5896    (set_attr "fptype" "*,double")])
5898 (define_insn "*one_cmpl<V64I:mode>2_sp64"
5899   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5900         (not:V64I (match_operand:V64I 1 "arith_operand" "rI,b")))]
5901   "TARGET_ARCH64"
5902   "@
5903    xnor\t%%g0, %1, %0
5904    fnot1\t%1, %0"
5905   [(set_attr "type" "*,fga")
5906    (set_attr "fptype" "*,double")])
5908 (define_insn "one_cmpl<V32I:mode>2"
5909   [(set (match_operand:V32I 0 "register_operand" "=r,d")
5910         (not:V32I (match_operand:V32I 1 "arith_operand" "rI,d")))]
5911   ""
5912   "@
5913   xnor\t%%g0, %1, %0
5914   fnot1s\t%1, %0"
5915   [(set_attr "type" "*,fga")
5916    (set_attr "fptype" "*,single")])
5918 (define_insn "*cmp_cc_not"
5919   [(set (reg:CC 100)
5920         (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
5921                     (const_int 0)))]
5922   ""
5923   "xnorcc\t%%g0, %0, %%g0"
5924   [(set_attr "type" "compare")])
5926 (define_insn "*cmp_ccx_not"
5927   [(set (reg:CCX 100)
5928         (compare:CCX (not:DI (match_operand:DI 0 "arith_operand" "rI"))
5929                      (const_int 0)))]
5930   "TARGET_ARCH64"
5931   "xnorcc\t%%g0, %0, %%g0"
5932   [(set_attr "type" "compare")])
5934 (define_insn "*cmp_cc_set_not"
5935   [(set (reg:CC 100)
5936         (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
5937                     (const_int 0)))
5938    (set (match_operand:SI 0 "register_operand" "=r")
5939         (not:SI (match_dup 1)))]
5940   ""
5941   "xnorcc\t%%g0, %1, %0"
5942   [(set_attr "type" "compare")])
5944 (define_insn "*cmp_ccx_set_not"
5945   [(set (reg:CCX 100)
5946         (compare:CCX (not:DI (match_operand:DI 1 "arith_operand" "rI"))
5947                     (const_int 0)))
5948    (set (match_operand:DI 0 "register_operand" "=r")
5949         (not:DI (match_dup 1)))]
5950   "TARGET_ARCH64"
5951   "xnorcc\t%%g0, %1, %0"
5952   [(set_attr "type" "compare")])
5954 (define_insn "*cmp_cc_set"
5955   [(set (match_operand:SI 0 "register_operand" "=r")
5956         (match_operand:SI 1 "register_operand" "r"))
5957    (set (reg:CC 100)
5958         (compare:CC (match_dup 1)
5959                     (const_int 0)))]
5960   ""
5961   "orcc\t%1, 0, %0"
5962   [(set_attr "type" "compare")])
5964 (define_insn "*cmp_ccx_set64"
5965   [(set (match_operand:DI 0 "register_operand" "=r")
5966         (match_operand:DI 1 "register_operand" "r"))
5967    (set (reg:CCX 100)
5968         (compare:CCX (match_dup 1)
5969                      (const_int 0)))]
5970   "TARGET_ARCH64"
5971   "orcc\t%1, 0, %0"
5972    [(set_attr "type" "compare")])
5975 ;; Floating point arithmetic instructions.
5977 (define_expand "addtf3"
5978   [(set (match_operand:TF 0 "nonimmediate_operand" "")
5979         (plus:TF (match_operand:TF 1 "general_operand" "")
5980                  (match_operand:TF 2 "general_operand" "")))]
5981   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5982   "emit_tfmode_binop (PLUS, operands); DONE;")
5984 (define_insn "*addtf3_hq"
5985   [(set (match_operand:TF 0 "register_operand" "=e")
5986         (plus:TF (match_operand:TF 1 "register_operand" "e")
5987                  (match_operand:TF 2 "register_operand" "e")))]
5988   "TARGET_FPU && TARGET_HARD_QUAD"
5989   "faddq\t%1, %2, %0"
5990   [(set_attr "type" "fp")])
5992 (define_insn "adddf3"
5993   [(set (match_operand:DF 0 "register_operand" "=e")
5994         (plus:DF (match_operand:DF 1 "register_operand" "e")
5995                  (match_operand:DF 2 "register_operand" "e")))]
5996   "TARGET_FPU"
5997   "faddd\t%1, %2, %0"
5998   [(set_attr "type" "fp")
5999    (set_attr "fptype" "double")])
6001 (define_insn "addsf3"
6002   [(set (match_operand:SF 0 "register_operand" "=f")
6003         (plus:SF (match_operand:SF 1 "register_operand" "f")
6004                  (match_operand:SF 2 "register_operand" "f")))]
6005   "TARGET_FPU"
6006   "fadds\t%1, %2, %0"
6007   [(set_attr "type" "fp")])
6009 (define_expand "subtf3"
6010   [(set (match_operand:TF 0 "nonimmediate_operand" "")
6011         (minus:TF (match_operand:TF 1 "general_operand" "")
6012                   (match_operand:TF 2 "general_operand" "")))]
6013   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6014   "emit_tfmode_binop (MINUS, operands); DONE;")
6016 (define_insn "*subtf3_hq"
6017   [(set (match_operand:TF 0 "register_operand" "=e")
6018         (minus:TF (match_operand:TF 1 "register_operand" "e")
6019                   (match_operand:TF 2 "register_operand" "e")))]
6020   "TARGET_FPU && TARGET_HARD_QUAD"
6021   "fsubq\t%1, %2, %0"
6022   [(set_attr "type" "fp")])
6024 (define_insn "subdf3"
6025   [(set (match_operand:DF 0 "register_operand" "=e")
6026         (minus:DF (match_operand:DF 1 "register_operand" "e")
6027                   (match_operand:DF 2 "register_operand" "e")))]
6028   "TARGET_FPU"
6029   "fsubd\t%1, %2, %0"
6030   [(set_attr "type" "fp")
6031    (set_attr "fptype" "double")])
6033 (define_insn "subsf3"
6034   [(set (match_operand:SF 0 "register_operand" "=f")
6035         (minus:SF (match_operand:SF 1 "register_operand" "f")
6036                   (match_operand:SF 2 "register_operand" "f")))]
6037   "TARGET_FPU"
6038   "fsubs\t%1, %2, %0"
6039   [(set_attr "type" "fp")])
6041 (define_expand "multf3"
6042   [(set (match_operand:TF 0 "nonimmediate_operand" "")
6043         (mult:TF (match_operand:TF 1 "general_operand" "")
6044                  (match_operand:TF 2 "general_operand" "")))]
6045   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6046   "emit_tfmode_binop (MULT, operands); DONE;")
6048 (define_insn "*multf3_hq"
6049   [(set (match_operand:TF 0 "register_operand" "=e")
6050         (mult:TF (match_operand:TF 1 "register_operand" "e")
6051                  (match_operand:TF 2 "register_operand" "e")))]
6052   "TARGET_FPU && TARGET_HARD_QUAD"
6053   "fmulq\t%1, %2, %0"
6054   [(set_attr "type" "fpmul")])
6056 (define_insn "muldf3"
6057   [(set (match_operand:DF 0 "register_operand" "=e")
6058         (mult:DF (match_operand:DF 1 "register_operand" "e")
6059                  (match_operand:DF 2 "register_operand" "e")))]
6060   "TARGET_FPU"
6061   "fmuld\t%1, %2, %0"
6062   [(set_attr "type" "fpmul")
6063    (set_attr "fptype" "double")])
6065 (define_insn "mulsf3"
6066   [(set (match_operand:SF 0 "register_operand" "=f")
6067         (mult:SF (match_operand:SF 1 "register_operand" "f")
6068                  (match_operand:SF 2 "register_operand" "f")))]
6069   "TARGET_FPU"
6070   "fmuls\t%1, %2, %0"
6071   [(set_attr "type" "fpmul")])
6073 (define_insn "*muldf3_extend"
6074   [(set (match_operand:DF 0 "register_operand" "=e")
6075         (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
6076                  (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
6077   "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
6078   "fsmuld\t%1, %2, %0"
6079   [(set_attr "type" "fpmul")
6080    (set_attr "fptype" "double")])
6082 (define_insn "*multf3_extend"
6083   [(set (match_operand:TF 0 "register_operand" "=e")
6084         (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
6085                  (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
6086   "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
6087   "fdmulq\t%1, %2, %0"
6088   [(set_attr "type" "fpmul")])
6090 (define_expand "divtf3"
6091   [(set (match_operand:TF 0 "nonimmediate_operand" "")
6092         (div:TF (match_operand:TF 1 "general_operand" "")
6093                 (match_operand:TF 2 "general_operand" "")))]
6094   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6095   "emit_tfmode_binop (DIV, operands); DONE;")
6097 ;; don't have timing for quad-prec. divide.
6098 (define_insn "*divtf3_hq"
6099   [(set (match_operand:TF 0 "register_operand" "=e")
6100         (div:TF (match_operand:TF 1 "register_operand" "e")
6101                 (match_operand:TF 2 "register_operand" "e")))]
6102   "TARGET_FPU && TARGET_HARD_QUAD"
6103   "fdivq\t%1, %2, %0"
6104   [(set_attr "type" "fpdivd")])
6106 (define_insn "divdf3"
6107   [(set (match_operand:DF 0 "register_operand" "=e")
6108         (div:DF (match_operand:DF 1 "register_operand" "e")
6109                 (match_operand:DF 2 "register_operand" "e")))]
6110   "TARGET_FPU"
6111   "fdivd\t%1, %2, %0"
6112   [(set_attr "type" "fpdivd")
6113    (set_attr "fptype" "double")])
6115 (define_insn "divsf3"
6116   [(set (match_operand:SF 0 "register_operand" "=f")
6117         (div:SF (match_operand:SF 1 "register_operand" "f")
6118                 (match_operand:SF 2 "register_operand" "f")))]
6119   "TARGET_FPU"
6120   "fdivs\t%1, %2, %0"
6121   [(set_attr "type" "fpdivs")])
6123 (define_expand "negtf2"
6124   [(set (match_operand:TF 0 "register_operand" "=e,e")
6125         (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6126   "TARGET_FPU"
6127   "")
6129 (define_insn_and_split "*negtf2_notv9"
6130   [(set (match_operand:TF 0 "register_operand" "=e,e")
6131         (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6132   ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6133   "TARGET_FPU
6134    && ! TARGET_V9"
6135   "@
6136   fnegs\t%0, %0
6137   #"
6138   "&& reload_completed
6139    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6140   [(set (match_dup 2) (neg:SF (match_dup 3)))
6141    (set (match_dup 4) (match_dup 5))
6142    (set (match_dup 6) (match_dup 7))]
6143   "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6144    operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6145    operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6146    operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6147    operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6148    operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6149   [(set_attr "type" "fpmove,*")
6150    (set_attr "length" "*,2")])
6152 (define_insn_and_split "*negtf2_v9"
6153   [(set (match_operand:TF 0 "register_operand" "=e,e")
6154         (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6155   ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6156   "TARGET_FPU && TARGET_V9"
6157   "@
6158   fnegd\t%0, %0
6159   #"
6160   "&& reload_completed
6161    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6162   [(set (match_dup 2) (neg:DF (match_dup 3)))
6163    (set (match_dup 4) (match_dup 5))]
6164   "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6165    operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6166    operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6167    operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6168   [(set_attr "type" "fpmove,*")
6169    (set_attr "length" "*,2")
6170    (set_attr "fptype" "double")])
6172 (define_expand "negdf2"
6173   [(set (match_operand:DF 0 "register_operand" "")
6174         (neg:DF (match_operand:DF 1 "register_operand" "")))]
6175   "TARGET_FPU"
6176   "")
6178 (define_insn_and_split "*negdf2_notv9"
6179   [(set (match_operand:DF 0 "register_operand" "=e,e")
6180         (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
6181   "TARGET_FPU && ! TARGET_V9"
6182   "@
6183   fnegs\t%0, %0
6184   #"
6185   "&& reload_completed
6186    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6187   [(set (match_dup 2) (neg:SF (match_dup 3)))
6188    (set (match_dup 4) (match_dup 5))]
6189   "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6190    operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6191    operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6192    operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6193   [(set_attr "type" "fpmove,*")
6194    (set_attr "length" "*,2")])
6196 (define_insn "*negdf2_v9"
6197   [(set (match_operand:DF 0 "register_operand" "=e")
6198         (neg:DF (match_operand:DF 1 "register_operand" "e")))]
6199   "TARGET_FPU && TARGET_V9"
6200   "fnegd\t%1, %0"
6201   [(set_attr "type" "fpmove")
6202    (set_attr "fptype" "double")])
6204 (define_insn "negsf2"
6205   [(set (match_operand:SF 0 "register_operand" "=f")
6206         (neg:SF (match_operand:SF 1 "register_operand" "f")))]
6207   "TARGET_FPU"
6208   "fnegs\t%1, %0"
6209   [(set_attr "type" "fpmove")])
6211 (define_expand "abstf2"
6212   [(set (match_operand:TF 0 "register_operand" "")
6213         (abs:TF (match_operand:TF 1 "register_operand" "")))]
6214   "TARGET_FPU"
6215   "")
6217 (define_insn_and_split "*abstf2_notv9"
6218   [(set (match_operand:TF 0 "register_operand" "=e,e")
6219         (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6220   ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6221   "TARGET_FPU && ! TARGET_V9"
6222   "@
6223   fabss\t%0, %0
6224   #"
6225   "&& reload_completed
6226    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6227   [(set (match_dup 2) (abs:SF (match_dup 3)))
6228    (set (match_dup 4) (match_dup 5))
6229    (set (match_dup 6) (match_dup 7))]
6230   "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6231    operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6232    operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6233    operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6234    operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6235    operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6236   [(set_attr "type" "fpmove,*")
6237    (set_attr "length" "*,2")])
6239 (define_insn "*abstf2_hq_v9"
6240   [(set (match_operand:TF 0 "register_operand" "=e,e")
6241         (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6242   "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
6243   "@
6244   fabsd\t%0, %0
6245   fabsq\t%1, %0"
6246   [(set_attr "type" "fpmove")
6247    (set_attr "fptype" "double,*")])
6249 (define_insn_and_split "*abstf2_v9"
6250   [(set (match_operand:TF 0 "register_operand" "=e,e")
6251         (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6252   "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
6253   "@
6254   fabsd\t%0, %0
6255   #"
6256   "&& reload_completed
6257    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6258   [(set (match_dup 2) (abs:DF (match_dup 3)))
6259    (set (match_dup 4) (match_dup 5))]
6260   "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6261    operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6262    operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6263    operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6264   [(set_attr "type" "fpmove,*")
6265    (set_attr "length" "*,2")
6266    (set_attr "fptype" "double,*")])
6268 (define_expand "absdf2"
6269   [(set (match_operand:DF 0 "register_operand" "")
6270         (abs:DF (match_operand:DF 1 "register_operand" "")))]
6271   "TARGET_FPU"
6272   "")
6274 (define_insn_and_split "*absdf2_notv9"
6275   [(set (match_operand:DF 0 "register_operand" "=e,e")
6276         (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
6277   "TARGET_FPU && ! TARGET_V9"
6278   "@
6279   fabss\t%0, %0
6280   #"
6281   "&& reload_completed
6282    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6283   [(set (match_dup 2) (abs:SF (match_dup 3)))
6284    (set (match_dup 4) (match_dup 5))]
6285   "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6286    operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6287    operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6288    operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6289   [(set_attr "type" "fpmove,*")
6290    (set_attr "length" "*,2")])
6292 (define_insn "*absdf2_v9"
6293   [(set (match_operand:DF 0 "register_operand" "=e")
6294         (abs:DF (match_operand:DF 1 "register_operand" "e")))]
6295   "TARGET_FPU && TARGET_V9"
6296   "fabsd\t%1, %0"
6297   [(set_attr "type" "fpmove")
6298    (set_attr "fptype" "double")])
6300 (define_insn "abssf2"
6301   [(set (match_operand:SF 0 "register_operand" "=f")
6302         (abs:SF (match_operand:SF 1 "register_operand" "f")))]
6303   "TARGET_FPU"
6304   "fabss\t%1, %0"
6305   [(set_attr "type" "fpmove")])
6307 (define_expand "sqrttf2"
6308   [(set (match_operand:TF 0 "nonimmediate_operand" "")
6309         (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
6310   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6311   "emit_tfmode_unop (SQRT, operands); DONE;")
6313 (define_insn "*sqrttf2_hq"
6314   [(set (match_operand:TF 0 "register_operand" "=e")
6315         (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
6316   "TARGET_FPU && TARGET_HARD_QUAD"
6317   "fsqrtq\t%1, %0"
6318   [(set_attr "type" "fpsqrtd")])
6320 (define_insn "sqrtdf2"
6321   [(set (match_operand:DF 0 "register_operand" "=e")
6322         (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
6323   "TARGET_FPU"
6324   "fsqrtd\t%1, %0"
6325   [(set_attr "type" "fpsqrtd")
6326    (set_attr "fptype" "double")])
6328 (define_insn "sqrtsf2"
6329   [(set (match_operand:SF 0 "register_operand" "=f")
6330         (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
6331   "TARGET_FPU"
6332   "fsqrts\t%1, %0"
6333   [(set_attr "type" "fpsqrts")])
6336 ;; Arithmetic shift instructions.
6338 (define_insn "ashlsi3"
6339   [(set (match_operand:SI 0 "register_operand" "=r")
6340         (ashift:SI (match_operand:SI 1 "register_operand" "r")
6341                    (match_operand:SI 2 "arith_operand" "rI")))]
6342   ""
6344   if (GET_CODE (operands[2]) == CONST_INT)
6345     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6346   return "sll\t%1, %2, %0";
6348   [(set (attr "type")
6349         (if_then_else (match_operand 2 "const_one_operand" "")
6350                       (const_string "ialu") (const_string "shift")))])
6352 (define_expand "ashldi3"
6353   [(set (match_operand:DI 0 "register_operand" "=r")
6354         (ashift:DI (match_operand:DI 1 "register_operand" "r")
6355                    (match_operand:SI 2 "arith_operand" "rI")))]
6356   "TARGET_ARCH64 || TARGET_V8PLUS"
6358   if (! TARGET_ARCH64)
6359     {
6360       if (GET_CODE (operands[2]) == CONST_INT)
6361         FAIL;
6362       emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
6363       DONE;
6364     }
6367 (define_insn "*ashldi3_sp64"
6368   [(set (match_operand:DI 0 "register_operand" "=r")
6369         (ashift:DI (match_operand:DI 1 "register_operand" "r")
6370                    (match_operand:SI 2 "arith_operand" "rI")))]
6371   "TARGET_ARCH64"
6373   if (GET_CODE (operands[2]) == CONST_INT)
6374     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6375   return "sllx\t%1, %2, %0";
6377   [(set (attr "type")
6378         (if_then_else (match_operand 2 "const_one_operand" "")
6379                       (const_string "ialu") (const_string "shift")))])
6381 ;; XXX UGH!
6382 (define_insn "ashldi3_v8plus"
6383   [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6384         (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6385                    (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6386    (clobber (match_scratch:SI 3 "=X,X,&h"))]
6387   "TARGET_V8PLUS"
6388   "* return output_v8plus_shift (operands, insn, \"sllx\");"
6389   [(set_attr "type" "multi")
6390    (set_attr "length" "5,5,6")])
6392 ;; Optimize (1LL<<x)-1
6393 ;; XXX this also needs to be fixed to handle equal subregs
6394 ;; XXX first before we could re-enable it.
6395 ;(define_insn ""
6396 ;  [(set (match_operand:DI 0 "register_operand" "=h")
6397 ;       (plus:DI (ashift:DI (const_int 1)
6398 ;                           (match_operand:SI 1 "arith_operand" "rI"))
6399 ;                (const_int -1)))]
6400 ;  "0 && TARGET_V8PLUS"
6402 ;  if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
6403 ;    return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
6404 ;  return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
6406 ;  [(set_attr "type" "multi")
6407 ;   (set_attr "length" "4")])
6409 (define_insn "*cmp_cc_ashift_1"
6410   [(set (reg:CC_NOOV 100)
6411         (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
6412                                     (const_int 1))
6413                          (const_int 0)))]
6414   ""
6415   "addcc\t%0, %0, %%g0"
6416   [(set_attr "type" "compare")])
6418 (define_insn "*cmp_cc_set_ashift_1"
6419   [(set (reg:CC_NOOV 100)
6420         (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
6421                                     (const_int 1))
6422                          (const_int 0)))
6423    (set (match_operand:SI 0 "register_operand" "=r")
6424         (ashift:SI (match_dup 1) (const_int 1)))]
6425   ""
6426   "addcc\t%1, %1, %0"
6427   [(set_attr "type" "compare")])
6429 (define_insn "ashrsi3"
6430   [(set (match_operand:SI 0 "register_operand" "=r")
6431         (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
6432                      (match_operand:SI 2 "arith_operand" "rI")))]
6433   ""
6434   {
6435      if (GET_CODE (operands[2]) == CONST_INT)
6436        operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6437      return "sra\t%1, %2, %0";
6438   }
6439   [(set_attr "type" "shift")])
6441 (define_insn "*ashrsi3_extend"
6442   [(set (match_operand:DI 0 "register_operand" "=r")
6443         (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
6444                                      (match_operand:SI 2 "arith_operand" "r"))))]
6445   "TARGET_ARCH64"
6446   "sra\t%1, %2, %0"
6447   [(set_attr "type" "shift")])
6449 ;; This handles the case as above, but with constant shift instead of
6450 ;; register. Combiner "simplifies" it for us a little bit though.
6451 (define_insn "*ashrsi3_extend2"
6452   [(set (match_operand:DI 0 "register_operand" "=r")
6453         (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
6454                                 (const_int 32))
6455                      (match_operand:SI 2 "small_int_operand" "I")))]
6456   "TARGET_ARCH64 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64"
6458   operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
6459   return "sra\t%1, %2, %0";
6461   [(set_attr "type" "shift")])
6463 (define_expand "ashrdi3"
6464   [(set (match_operand:DI 0 "register_operand" "=r")
6465         (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6466                      (match_operand:SI 2 "arith_operand" "rI")))]
6467   "TARGET_ARCH64 || TARGET_V8PLUS"
6469   if (! TARGET_ARCH64)
6470     {
6471       if (GET_CODE (operands[2]) == CONST_INT)
6472         FAIL;   /* prefer generic code in this case */
6473       emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
6474       DONE;
6475     }
6478 (define_insn "*ashrdi3_sp64"
6479   [(set (match_operand:DI 0 "register_operand" "=r")
6480         (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6481                      (match_operand:SI 2 "arith_operand" "rI")))]
6482   "TARGET_ARCH64"
6483   
6484   {
6485     if (GET_CODE (operands[2]) == CONST_INT)
6486       operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6487     return "srax\t%1, %2, %0";
6488   }
6489   [(set_attr "type" "shift")])
6491 ;; XXX
6492 (define_insn "ashrdi3_v8plus"
6493   [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6494         (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6495                      (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6496    (clobber (match_scratch:SI 3 "=X,X,&h"))]
6497   "TARGET_V8PLUS"
6498   "* return output_v8plus_shift (operands, insn, \"srax\");"
6499   [(set_attr "type" "multi")
6500    (set_attr "length" "5,5,6")])
6502 (define_insn "lshrsi3"
6503   [(set (match_operand:SI 0 "register_operand" "=r")
6504         (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
6505                      (match_operand:SI 2 "arith_operand" "rI")))]
6506   ""
6507   {
6508     if (GET_CODE (operands[2]) == CONST_INT)
6509       operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6510     return "srl\t%1, %2, %0";
6511   }
6512   [(set_attr "type" "shift")])
6514 ;; This handles the case where
6515 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
6516 ;; but combiner "simplifies" it for us.
6517 (define_insn "*lshrsi3_extend"
6518   [(set (match_operand:DI 0 "register_operand" "=r")
6519         (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
6520                            (match_operand:SI 2 "arith_operand" "r")) 0)
6521                 (match_operand 3 "const_int_operand" "")))]
6522   "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff"
6523   "srl\t%1, %2, %0"
6524   [(set_attr "type" "shift")])
6526 ;; This handles the case where
6527 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
6528 ;; but combiner "simplifies" it for us.
6529 (define_insn "*lshrsi3_extend2"
6530   [(set (match_operand:DI 0 "register_operand" "=r")
6531         (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
6532                          (match_operand 2 "small_int_operand" "I")
6533                          (const_int 32)))]
6534   "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6536   operands[2] = GEN_INT (32 - INTVAL (operands[2]));
6537   return "srl\t%1, %2, %0";
6539   [(set_attr "type" "shift")])
6541 (define_expand "lshrdi3"
6542   [(set (match_operand:DI 0 "register_operand" "=r")
6543         (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6544                      (match_operand:SI 2 "arith_operand" "rI")))]
6545   "TARGET_ARCH64 || TARGET_V8PLUS"
6547   if (! TARGET_ARCH64)
6548     {
6549       if (GET_CODE (operands[2]) == CONST_INT)
6550         FAIL;
6551       emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
6552       DONE;
6553     }
6556 (define_insn "*lshrdi3_sp64"
6557   [(set (match_operand:DI 0 "register_operand" "=r")
6558         (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6559                      (match_operand:SI 2 "arith_operand" "rI")))]
6560   "TARGET_ARCH64"
6561   {
6562     if (GET_CODE (operands[2]) == CONST_INT)
6563       operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6564     return "srlx\t%1, %2, %0";
6565   }
6566   [(set_attr "type" "shift")])
6568 ;; XXX
6569 (define_insn "lshrdi3_v8plus"
6570   [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6571         (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6572                      (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6573    (clobber (match_scratch:SI 3 "=X,X,&h"))]
6574   "TARGET_V8PLUS"
6575   "* return output_v8plus_shift (operands, insn, \"srlx\");"
6576   [(set_attr "type" "multi")
6577    (set_attr "length" "5,5,6")])
6579 (define_insn ""
6580   [(set (match_operand:SI 0 "register_operand" "=r")
6581         (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6582                                              (const_int 32)) 4)
6583                      (match_operand:SI 2 "small_int_operand" "I")))]
6584   "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6586   operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6587   return "srax\t%1, %2, %0";
6589   [(set_attr "type" "shift")])
6591 (define_insn ""
6592   [(set (match_operand:SI 0 "register_operand" "=r")
6593         (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6594                                              (const_int 32)) 4)
6595                      (match_operand:SI 2 "small_int_operand" "I")))]
6596   "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6598   operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6599   return "srlx\t%1, %2, %0";
6601   [(set_attr "type" "shift")])
6603 (define_insn ""
6604   [(set (match_operand:SI 0 "register_operand" "=r")
6605         (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6606                                              (match_operand:SI 2 "small_int_operand" "I")) 4)
6607                      (match_operand:SI 3 "small_int_operand" "I")))]
6608   "TARGET_ARCH64
6609    && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6610    && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6611    && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6613   operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6615   return "srax\t%1, %2, %0";
6617   [(set_attr "type" "shift")])
6619 (define_insn ""
6620   [(set (match_operand:SI 0 "register_operand" "=r")
6621         (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6622                                              (match_operand:SI 2 "small_int_operand" "I")) 4)
6623                      (match_operand:SI 3 "small_int_operand" "I")))]
6624   "TARGET_ARCH64
6625    && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6626    && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6627    && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6629   operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6631   return "srlx\t%1, %2, %0";
6633   [(set_attr "type" "shift")])
6636 ;; Unconditional and other jump instructions.
6638 (define_insn "jump"
6639   [(set (pc) (label_ref (match_operand 0 "" "")))]
6640   ""
6641   "* return output_ubranch (operands[0], 0, insn);"
6642   [(set_attr "type" "uncond_branch")])
6644 (define_expand "tablejump"
6645   [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
6646               (use (label_ref (match_operand 1 "" "")))])]
6647   ""
6649   gcc_assert (GET_MODE (operands[0]) == CASE_VECTOR_MODE);
6651   /* In pic mode, our address differences are against the base of the
6652      table.  Add that base value back in; CSE ought to be able to combine
6653      the two address loads.  */
6654   if (flag_pic)
6655     {
6656       rtx tmp, tmp2;
6657       tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
6658       tmp2 = operands[0];
6659       if (CASE_VECTOR_MODE != Pmode)
6660         tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
6661       tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
6662       operands[0] = memory_address (Pmode, tmp);
6663     }
6666 (define_insn "*tablejump_sp32"
6667   [(set (pc) (match_operand:SI 0 "address_operand" "p"))
6668    (use (label_ref (match_operand 1 "" "")))]
6669   "! TARGET_ARCH64"
6670   "jmp\t%a0%#"
6671   [(set_attr "type" "uncond_branch")])
6673 (define_insn "*tablejump_sp64"
6674   [(set (pc) (match_operand:DI 0 "address_operand" "p"))
6675    (use (label_ref (match_operand 1 "" "")))]
6676   "TARGET_ARCH64"
6677   "jmp\t%a0%#"
6678   [(set_attr "type" "uncond_branch")])
6681 ;; Jump to subroutine instructions.
6683 (define_expand "call"
6684   ;; Note that this expression is not used for generating RTL.
6685   ;; All the RTL is generated explicitly below.
6686   [(call (match_operand 0 "call_operand" "")
6687          (match_operand 3 "" "i"))]
6688   ;; operands[2] is next_arg_register
6689   ;; operands[3] is struct_value_size_rtx.
6690   ""
6692   rtx fn_rtx;
6694   gcc_assert (MEM_P (operands[0]) && GET_MODE (operands[0]) == FUNCTION_MODE);
6696   gcc_assert (GET_CODE (operands[3]) == CONST_INT);
6698   if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
6699     {
6700       /* This is really a PIC sequence.  We want to represent
6701          it as a funny jump so its delay slots can be filled. 
6703          ??? But if this really *is* a CALL, will not it clobber the
6704          call-clobbered registers?  We lose this if it is a JUMP_INSN.
6705          Why cannot we have delay slots filled if it were a CALL?  */
6707       /* We accept negative sizes for untyped calls.  */
6708       if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6709         emit_jump_insn
6710           (gen_rtx_PARALLEL
6711            (VOIDmode,
6712             gen_rtvec (3,
6713                        gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6714                        operands[3],
6715                        gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6716       else
6717         emit_jump_insn
6718           (gen_rtx_PARALLEL
6719            (VOIDmode,
6720             gen_rtvec (2,
6721                        gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6722                        gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6723       goto finish_call;
6724     }
6726   fn_rtx = operands[0];
6728   /* We accept negative sizes for untyped calls.  */
6729   if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6730     sparc_emit_call_insn
6731       (gen_rtx_PARALLEL
6732        (VOIDmode,
6733         gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6734                    operands[3],
6735                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6736        XEXP (fn_rtx, 0));
6737   else
6738     sparc_emit_call_insn
6739       (gen_rtx_PARALLEL
6740        (VOIDmode,
6741         gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6742                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6743        XEXP (fn_rtx, 0));
6745  finish_call:
6747   DONE;
6750 ;; We can't use the same pattern for these two insns, because then registers
6751 ;; in the address may not be properly reloaded.
6753 (define_insn "*call_address_sp32"
6754   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6755          (match_operand 1 "" ""))
6756    (clobber (reg:SI 15))]
6757   ;;- Do not use operand 1 for most machines.
6758   "! TARGET_ARCH64"
6759   "call\t%a0, %1%#"
6760   [(set_attr "type" "call")])
6762 (define_insn "*call_symbolic_sp32"
6763   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6764          (match_operand 1 "" ""))
6765    (clobber (reg:SI 15))]
6766   ;;- Do not use operand 1 for most machines.
6767   "! TARGET_ARCH64"
6768   "call\t%a0, %1%#"
6769   [(set_attr "type" "call")])
6771 (define_insn "*call_address_sp64"
6772   [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
6773          (match_operand 1 "" ""))
6774    (clobber (reg:DI 15))]
6775   ;;- Do not use operand 1 for most machines.
6776   "TARGET_ARCH64"
6777   "call\t%a0, %1%#"
6778   [(set_attr "type" "call")])
6780 (define_insn "*call_symbolic_sp64"
6781   [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6782          (match_operand 1 "" ""))
6783    (clobber (reg:DI 15))]
6784   ;;- Do not use operand 1 for most machines.
6785   "TARGET_ARCH64"
6786   "call\t%a0, %1%#"
6787   [(set_attr "type" "call")])
6789 ;; This is a call that wants a structure value.
6790 ;; There is no such critter for v9 (??? we may need one anyway).
6791 (define_insn "*call_address_struct_value_sp32"
6792   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6793          (match_operand 1 "" ""))
6794    (match_operand 2 "immediate_operand" "")
6795    (clobber (reg:SI 15))]
6796   ;;- Do not use operand 1 for most machines.
6797   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6799   operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6800   return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6802   [(set_attr "type" "call_no_delay_slot")
6803    (set_attr "length" "3")])
6805 ;; This is a call that wants a structure value.
6806 ;; There is no such critter for v9 (??? we may need one anyway).
6807 (define_insn "*call_symbolic_struct_value_sp32"
6808   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6809          (match_operand 1 "" ""))
6810    (match_operand 2 "immediate_operand" "")
6811    (clobber (reg:SI 15))]
6812   ;;- Do not use operand 1 for most machines.
6813   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6815   operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6816   return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6818   [(set_attr "type" "call_no_delay_slot")
6819    (set_attr "length" "3")])
6821 ;; This is a call that may want a structure value.  This is used for
6822 ;; untyped_calls.
6823 (define_insn "*call_address_untyped_struct_value_sp32"
6824   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6825          (match_operand 1 "" ""))
6826    (match_operand 2 "immediate_operand" "")
6827    (clobber (reg:SI 15))]
6828   ;;- Do not use operand 1 for most machines.
6829   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6830   "call\t%a0, %1\n\t nop\n\tnop"
6831   [(set_attr "type" "call_no_delay_slot")
6832    (set_attr "length" "3")])
6834 ;; This is a call that may want a structure value.  This is used for
6835 ;; untyped_calls.
6836 (define_insn "*call_symbolic_untyped_struct_value_sp32"
6837   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6838          (match_operand 1 "" ""))
6839    (match_operand 2 "immediate_operand" "")
6840    (clobber (reg:SI 15))]
6841   ;;- Do not use operand 1 for most machines.
6842   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6843   "call\t%a0, %1\n\t nop\n\tnop"
6844   [(set_attr "type" "call_no_delay_slot")
6845    (set_attr "length" "3")])
6847 (define_expand "call_value"
6848   ;; Note that this expression is not used for generating RTL.
6849   ;; All the RTL is generated explicitly below.
6850   [(set (match_operand 0 "register_operand" "=rf")
6851         (call (match_operand 1 "" "")
6852               (match_operand 4 "" "")))]
6853   ;; operand 2 is stack_size_rtx
6854   ;; operand 3 is next_arg_register
6855   ""
6857   rtx fn_rtx;
6858   rtvec vec;
6860   gcc_assert (MEM_P (operands[1]) && GET_MODE (operands[1]) == FUNCTION_MODE);
6862   fn_rtx = operands[1];
6864   vec = gen_rtvec (2,
6865                    gen_rtx_SET (VOIDmode, operands[0],
6866                                 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
6867                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
6869   sparc_emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec), XEXP (fn_rtx, 0));
6871   DONE;
6874 (define_insn "*call_value_address_sp32"
6875   [(set (match_operand 0 "" "=rf")
6876         (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
6877               (match_operand 2 "" "")))
6878    (clobber (reg:SI 15))]
6879   ;;- Do not use operand 2 for most machines.
6880   "! TARGET_ARCH64"
6881   "call\t%a1, %2%#"
6882   [(set_attr "type" "call")])
6884 (define_insn "*call_value_symbolic_sp32"
6885   [(set (match_operand 0 "" "=rf")
6886         (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6887               (match_operand 2 "" "")))
6888    (clobber (reg:SI 15))]
6889   ;;- Do not use operand 2 for most machines.
6890   "! TARGET_ARCH64"
6891   "call\t%a1, %2%#"
6892   [(set_attr "type" "call")])
6894 (define_insn "*call_value_address_sp64"
6895   [(set (match_operand 0 "" "")
6896         (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
6897               (match_operand 2 "" "")))
6898    (clobber (reg:DI 15))]
6899   ;;- Do not use operand 2 for most machines.
6900   "TARGET_ARCH64"
6901   "call\t%a1, %2%#"
6902   [(set_attr "type" "call")])
6904 (define_insn "*call_value_symbolic_sp64"
6905   [(set (match_operand 0 "" "")
6906         (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6907               (match_operand 2 "" "")))
6908    (clobber (reg:DI 15))]
6909   ;;- Do not use operand 2 for most machines.
6910   "TARGET_ARCH64"
6911   "call\t%a1, %2%#"
6912   [(set_attr "type" "call")])
6914 (define_expand "untyped_call"
6915   [(parallel [(call (match_operand 0 "" "")
6916                     (const_int 0))
6917               (match_operand:BLK 1 "memory_operand" "")
6918               (match_operand 2 "" "")])]
6919   ""
6921   rtx valreg1 = gen_rtx_REG (DImode, 8);
6922   rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6923   rtx result = operands[1];
6925   /* Pass constm1 to indicate that it may expect a structure value, but
6926      we don't know what size it is.  */
6927   emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
6929   /* Save the function value registers.  */
6930   emit_move_insn (adjust_address (result, DImode, 0), valreg1);
6931   emit_move_insn (adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8),
6932                                   valreg2);
6934   /* The optimizer does not know that the call sets the function value
6935      registers we stored in the result block.  We avoid problems by
6936      claiming that all hard registers are used and clobbered at this
6937      point.  */
6938   emit_insn (gen_blockage ());
6940   DONE;
6943 ;;  Tail call instructions.
6945 (define_expand "sibcall"
6946   [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
6947               (return)])]
6948   ""
6949   "")
6951 (define_insn "*sibcall_symbolic_sp32"
6952   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6953          (match_operand 1 "" ""))
6954    (return)]
6955   "! TARGET_ARCH64"
6956   "* return output_sibcall(insn, operands[0]);"
6957   [(set_attr "type" "sibcall")])
6959 (define_insn "*sibcall_symbolic_sp64"
6960   [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6961          (match_operand 1 "" ""))
6962    (return)]
6963   "TARGET_ARCH64"
6964   "* return output_sibcall(insn, operands[0]);"
6965   [(set_attr "type" "sibcall")])
6967 (define_expand "sibcall_value"
6968   [(parallel [(set (match_operand 0 "register_operand" "=rf")
6969                 (call (match_operand 1 "" "") (const_int 0)))
6970               (return)])]
6971   ""
6972   "")
6974 (define_insn "*sibcall_value_symbolic_sp32"
6975   [(set (match_operand 0 "" "=rf")
6976         (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6977               (match_operand 2 "" "")))
6978    (return)]
6979   "! TARGET_ARCH64"
6980   "* return output_sibcall(insn, operands[1]);"
6981   [(set_attr "type" "sibcall")])
6983 (define_insn "*sibcall_value_symbolic_sp64"
6984   [(set (match_operand 0 "" "")
6985         (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6986               (match_operand 2 "" "")))
6987    (return)]
6988   "TARGET_ARCH64"
6989   "* return output_sibcall(insn, operands[1]);"
6990   [(set_attr "type" "sibcall")])
6993 ;; Special instructions.
6995 (define_expand "prologue"
6996   [(const_int 0)]
6997   ""
6999   sparc_expand_prologue ();
7000   DONE;
7003 ;; The "save register window" insn is modelled as follows so that the DWARF-2
7004 ;; backend automatically emits the required call frame debugging information
7005 ;; while it is parsing it.  Therefore, the pattern should not be modified
7006 ;; without first studying the impact of the changes on the debug info.
7007 ;; [(set (%fp) (%sp))
7008 ;;  (set (%sp) (unspec_volatile [(%sp) (-frame_size)] UNSPECV_SAVEW))
7009 ;;  (set (%i7) (%o7))]
7011 (define_insn "save_register_window<P:mode>"
7012   [(set (reg:P 30) (reg:P 14))
7013    (set (reg:P 14) (unspec_volatile:P [(reg:P 14)
7014                                        (match_operand:P 0 "arith_operand" "rI")] UNSPECV_SAVEW))
7015    (set (reg:P 31) (reg:P 15))]
7016   ""
7017   "save\t%%sp, %0, %%sp"
7018   [(set_attr "type" "savew")])
7020 (define_expand "epilogue"
7021   [(return)]
7022   ""
7024   sparc_expand_epilogue ();
7027 (define_expand "sibcall_epilogue"
7028   [(return)]
7029   ""
7031   sparc_expand_epilogue ();
7032   DONE;
7035 (define_expand "return"
7036   [(return)]
7037   "sparc_can_use_return_insn_p ()"
7038   "")
7040 (define_insn "*return_internal"
7041   [(return)]
7042   ""
7043   "* return output_return (insn);"
7044   [(set_attr "type" "return")
7045    (set (attr "length")
7046         (cond [(eq_attr "leaf_function" "true")
7047                  (if_then_else (eq_attr "empty_delay_slot" "true")
7048                                (const_int 2)
7049                                (const_int 1))
7050                (eq_attr "calls_eh_return" "true")
7051                  (if_then_else (eq_attr "delayed_branch" "true")
7052                                (if_then_else (eq_attr "isa" "v9")
7053                                              (const_int 2)
7054                                              (const_int 3))
7055                                (if_then_else (eq_attr "isa" "v9")
7056                                              (const_int 3)
7057                                              (const_int 4)))
7058                (eq_attr "empty_delay_slot" "true")
7059                  (if_then_else (eq_attr "delayed_branch" "true")
7060                                (const_int 2)
7061                                (const_int 3))
7062               ] (const_int 1)))])
7064 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
7065 ;; all of memory.  This blocks insns from being moved across this point.
7067 (define_insn "blockage"
7068   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7069   ""
7070   ""
7071   [(set_attr "length" "0")])
7073 ;; Prepare to return any type including a structure value.
7075 (define_expand "untyped_return"
7076   [(match_operand:BLK 0 "memory_operand" "")
7077    (match_operand 1 "" "")]
7078   ""
7080   rtx valreg1 = gen_rtx_REG (DImode, 24);
7081   rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
7082   rtx result = operands[0];
7084   if (! TARGET_ARCH64)
7085     {
7086       rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
7087                                          ? 15 : 31));
7088       rtx value = gen_reg_rtx (SImode);
7090       /* Fetch the instruction where we will return to and see if it's an unimp
7091          instruction (the most significant 10 bits will be zero).  If so,
7092          update the return address to skip the unimp instruction.  */
7093       emit_move_insn (value,
7094                       gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
7095       emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
7096       emit_insn (gen_update_return (rtnreg, value));
7097     }
7099   /* Reload the function value registers.  */
7100   emit_move_insn (valreg1, adjust_address (result, DImode, 0));
7101   emit_move_insn (valreg2,
7102                   adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
7104   /* Put USE insns before the return.  */
7105   emit_insn (gen_rtx_USE (VOIDmode, valreg1));
7106   emit_insn (gen_rtx_USE (VOIDmode, valreg2));
7108   /* Construct the return.  */
7109   expand_naked_return ();
7111   DONE;
7114 ;; Adjust the return address conditionally. If the value of op1 is equal
7115 ;; to all zero then adjust the return address i.e. op0 = op0 + 4.
7116 ;; This is technically *half* the check required by the 32-bit SPARC
7117 ;; psABI. This check only ensures that an "unimp" insn was written by
7118 ;; the caller, but doesn't check to see if the expected size matches
7119 ;; (this is encoded in the 12 lower bits). This check is obsolete and
7120 ;; only used by the above code "untyped_return".
7122 (define_insn "update_return"
7123   [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
7124                (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
7125   "! TARGET_ARCH64"
7127   if (flag_delayed_branch)
7128     return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
7129   else
7130     return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
7132   [(set (attr "type") (const_string "multi"))
7133    (set (attr "length")
7134         (if_then_else (eq_attr "delayed_branch" "true")
7135                       (const_int 3)
7136                       (const_int 4)))])
7138 (define_insn "nop"
7139   [(const_int 0)]
7140   ""
7141   "nop")
7143 (define_expand "indirect_jump"
7144   [(set (pc) (match_operand 0 "address_operand" "p"))]
7145   ""
7146   "")
7148 (define_insn "*branch_sp32"
7149   [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
7150   "! TARGET_ARCH64"
7151  "jmp\t%a0%#"
7152  [(set_attr "type" "uncond_branch")])
7154 (define_insn "*branch_sp64"
7155   [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
7156   "TARGET_ARCH64"
7157   "jmp\t%a0%#"
7158   [(set_attr "type" "uncond_branch")])
7160 (define_expand "nonlocal_goto"
7161   [(match_operand:SI 0 "general_operand" "")
7162    (match_operand:SI 1 "general_operand" "")
7163    (match_operand:SI 2 "general_operand" "")
7164    (match_operand:SI 3 "" "")]
7165   ""
7167   rtx lab = operands[1];
7168   rtx stack = operands[2];
7169   rtx fp = operands[3];
7170   rtx labreg;
7172   /* Trap instruction to flush all the register windows.  */
7173   emit_insn (gen_flush_register_windows ());
7175   /* Load the fp value for the containing fn into %fp.  This is needed
7176      because STACK refers to %fp.  Note that virtual register instantiation
7177      fails if the virtual %fp isn't set from a register.  */
7178   if (GET_CODE (fp) != REG)
7179     fp = force_reg (Pmode, fp);
7180   emit_move_insn (virtual_stack_vars_rtx, fp);
7182   /* Find the containing function's current nonlocal goto handler,
7183      which will do any cleanups and then jump to the label.  */
7184   labreg = gen_rtx_REG (Pmode, 8);
7185   emit_move_insn (labreg, lab);
7187   /* Restore %fp from stack pointer value for containing function.
7188      The restore insn that follows will move this to %sp,
7189      and reload the appropriate value into %fp.  */
7190   emit_move_insn (hard_frame_pointer_rtx, stack);
7192   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
7193   emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
7195   /* ??? The V9-specific version was disabled in rev 1.65.  */
7196   emit_jump_insn (gen_goto_handler_and_restore (labreg));
7197   emit_barrier ();
7198   DONE;
7201 ;; Special trap insn to flush register windows.
7202 (define_insn "flush_register_windows"
7203   [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
7204   ""
7205   { return TARGET_V9 ? "flushw" : "ta\t3"; }
7206   [(set_attr "type" "flushw")])
7208 (define_insn "goto_handler_and_restore"
7209   [(unspec_volatile [(match_operand 0 "register_operand" "=r")] UNSPECV_GOTO)]
7210   "GET_MODE (operands[0]) == Pmode"
7212   if (flag_delayed_branch)
7213     return "jmp\t%0\n\t restore";
7214   else
7215     return "mov\t%0,%%g1\n\trestore\n\tjmp\t%%g1\n\t nop";
7217   [(set (attr "type") (const_string "multi"))
7218    (set (attr "length")
7219         (if_then_else (eq_attr "delayed_branch" "true")
7220                       (const_int 2)
7221                       (const_int 4)))])
7223 ;; For __builtin_setjmp we need to flush register windows iff the function
7224 ;; calls alloca as well, because otherwise the register window might be
7225 ;; saved after %sp adjustment and thus setjmp would crash
7226 (define_expand "builtin_setjmp_setup"
7227   [(match_operand 0 "register_operand" "r")]
7228   ""
7230   emit_insn (gen_do_builtin_setjmp_setup ());
7231   DONE;
7234 (define_insn "do_builtin_setjmp_setup"
7235   [(unspec_volatile [(const_int 0)] UNSPECV_SETJMP)]
7236   ""
7238   if (! current_function_calls_alloca)
7239     return "";
7240   if (! TARGET_V9)
7241     return "\tta\t3\n";
7242   fputs ("\tflushw\n", asm_out_file);
7243   if (flag_pic)
7244     fprintf (asm_out_file, "\tst%c\t%%l7, [%%sp+%d]\n",
7245              TARGET_ARCH64 ? 'x' : 'w',
7246              SPARC_STACK_BIAS + 7 * UNITS_PER_WORD);
7247   fprintf (asm_out_file, "\tst%c\t%%fp, [%%sp+%d]\n",
7248            TARGET_ARCH64 ? 'x' : 'w',
7249            SPARC_STACK_BIAS + 14 * UNITS_PER_WORD);
7250   fprintf (asm_out_file, "\tst%c\t%%i7, [%%sp+%d]\n",
7251            TARGET_ARCH64 ? 'x' : 'w',
7252            SPARC_STACK_BIAS + 15 * UNITS_PER_WORD);
7253   return "";
7255   [(set_attr "type" "multi")
7256    (set (attr "length")
7257         (cond [(eq_attr "calls_alloca" "false")
7258                  (const_int 0)
7259                (eq_attr "isa" "!v9")
7260                  (const_int 1)
7261                (eq_attr "pic" "true")
7262                  (const_int 4)] (const_int 3)))])
7264 ;; Pattern for use after a setjmp to store FP and the return register
7265 ;; into the stack area.
7267 (define_expand "setjmp"
7268   [(const_int 0)]
7269   ""
7271   rtx mem;
7272   
7273   mem = gen_rtx_MEM (Pmode,
7274                      plus_constant (stack_pointer_rtx,
7275                                     SPARC_STACK_BIAS + 14 * UNITS_PER_WORD));
7276   emit_insn (gen_rtx_SET (VOIDmode, mem, frame_pointer_rtx));
7278   mem = gen_rtx_MEM (Pmode,
7279                      plus_constant (stack_pointer_rtx,
7280                                     SPARC_STACK_BIAS + 15 * UNITS_PER_WORD));
7281   emit_insn (gen_rtx_SET (VOIDmode, mem, gen_rtx_REG (Pmode, 31)));
7282   DONE;
7285 ;; Special pattern for the FLUSH instruction.
7287 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
7288 ; of the define_insn otherwise missing a mode.  We make "flush", aka
7289 ; gen_flush, the default one since sparc_initialize_trampoline uses
7290 ; it on SImode mem values.
7292 (define_insn "flush"
7293   [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7294   ""
7295   { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7296   [(set_attr "type" "iflush")])
7298 (define_insn "flushdi"
7299   [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7300   ""
7301   { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7302   [(set_attr "type" "iflush")])
7305 ;; Find first set instructions.
7307 ;; The scan instruction searches from the most significant bit while ffs
7308 ;; searches from the least significant bit.  The bit index and treatment of
7309 ;; zero also differ.  It takes at least 7 instructions to get the proper
7310 ;; result.  Here is an obvious 8 instruction sequence.
7312 ;; XXX
7313 (define_insn "ffssi2"
7314   [(set (match_operand:SI 0 "register_operand" "=&r")
7315         (ffs:SI (match_operand:SI 1 "register_operand" "r")))
7316    (clobber (match_scratch:SI 2 "=&r"))]
7317   "TARGET_SPARCLITE || TARGET_SPARCLET"
7319   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";
7321   [(set_attr "type" "multi")
7322    (set_attr "length" "8")])
7324 ;; ??? This should be a define expand, so that the extra instruction have
7325 ;; a chance of being optimized away.
7327 ;; Disabled because none of the UltraSPARCs implement popc.  The HAL R1
7328 ;; does, but no one uses that and we don't have a switch for it.
7330 ;(define_insn "ffsdi2"
7331 ;  [(set (match_operand:DI 0 "register_operand" "=&r")
7332 ;       (ffs:DI (match_operand:DI 1 "register_operand" "r")))
7333 ;   (clobber (match_scratch:DI 2 "=&r"))]
7334 ;  "TARGET_ARCH64"
7335 ;  "neg\t%1, %2\;xnor\t%1, %2, %2\;popc\t%2, %0\;movzr\t%1, 0, %0"
7336 ;  [(set_attr "type" "multi")
7337 ;   (set_attr "length" "4")])
7341 ;; Peepholes go at the end.
7343 ;; Optimize consecutive loads or stores into ldd and std when possible.
7344 ;; The conditions in which we do this are very restricted and are 
7345 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
7347 (define_peephole2
7348   [(set (match_operand:SI 0 "memory_operand" "")
7349       (const_int 0))
7350    (set (match_operand:SI 1 "memory_operand" "")
7351       (const_int 0))]
7352   "TARGET_V9
7353    && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
7354   [(set (match_dup 0)
7355        (const_int 0))]
7356   "operands[0] = widen_memory_access (operands[0], DImode, 0);")
7358 (define_peephole2
7359   [(set (match_operand:SI 0 "memory_operand" "")
7360       (const_int 0))
7361    (set (match_operand:SI 1 "memory_operand" "")
7362       (const_int 0))]
7363   "TARGET_V9
7364    && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
7365   [(set (match_dup 1)
7366        (const_int 0))]
7367   "operands[1] = widen_memory_access (operands[1], DImode, 0);")
7369 (define_peephole2
7370   [(set (match_operand:SI 0 "register_operand" "")
7371         (match_operand:SI 1 "memory_operand" ""))
7372    (set (match_operand:SI 2 "register_operand" "")
7373         (match_operand:SI 3 "memory_operand" ""))]
7374   "registers_ok_for_ldd_peep (operands[0], operands[2]) 
7375    && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])" 
7376   [(set (match_dup 0)
7377         (match_dup 1))]
7378   "operands[1] = widen_memory_access (operands[1], DImode, 0);
7379    operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
7381 (define_peephole2
7382   [(set (match_operand:SI 0 "memory_operand" "")
7383         (match_operand:SI 1 "register_operand" ""))
7384    (set (match_operand:SI 2 "memory_operand" "")
7385         (match_operand:SI 3 "register_operand" ""))]
7386   "registers_ok_for_ldd_peep (operands[1], operands[3]) 
7387    && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7388   [(set (match_dup 0)
7389         (match_dup 1))]
7390   "operands[0] = widen_memory_access (operands[0], DImode, 0);
7391    operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
7393 (define_peephole2
7394   [(set (match_operand:SF 0 "register_operand" "")
7395         (match_operand:SF 1 "memory_operand" ""))
7396    (set (match_operand:SF 2 "register_operand" "")
7397         (match_operand:SF 3 "memory_operand" ""))]
7398   "registers_ok_for_ldd_peep (operands[0], operands[2]) 
7399    && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
7400   [(set (match_dup 0)
7401         (match_dup 1))]
7402   "operands[1] = widen_memory_access (operands[1], DFmode, 0);
7403    operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
7405 (define_peephole2
7406   [(set (match_operand:SF 0 "memory_operand" "")
7407         (match_operand:SF 1 "register_operand" ""))
7408    (set (match_operand:SF 2 "memory_operand" "")
7409         (match_operand:SF 3 "register_operand" ""))]
7410   "registers_ok_for_ldd_peep (operands[1], operands[3]) 
7411   && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7412   [(set (match_dup 0)
7413         (match_dup 1))]
7414   "operands[0] = widen_memory_access (operands[0], DFmode, 0);
7415    operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
7417 (define_peephole2
7418   [(set (match_operand:SI 0 "register_operand" "")
7419         (match_operand:SI 1 "memory_operand" ""))
7420    (set (match_operand:SI 2 "register_operand" "")
7421         (match_operand:SI 3 "memory_operand" ""))]
7422   "registers_ok_for_ldd_peep (operands[2], operands[0]) 
7423   && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
7424   [(set (match_dup 2)
7425         (match_dup 3))]
7426    "operands[3] = widen_memory_access (operands[3], DImode, 0);
7427     operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
7429 (define_peephole2
7430   [(set (match_operand:SI 0 "memory_operand" "")
7431         (match_operand:SI 1 "register_operand" ""))
7432    (set (match_operand:SI 2 "memory_operand" "")
7433         (match_operand:SI 3 "register_operand" ""))]
7434   "registers_ok_for_ldd_peep (operands[3], operands[1]) 
7435   && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)" 
7436   [(set (match_dup 2)
7437         (match_dup 3))]
7438   "operands[2] = widen_memory_access (operands[2], DImode, 0);
7439    operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
7440    ")
7442 (define_peephole2
7443   [(set (match_operand:SF 0 "register_operand" "")
7444         (match_operand:SF 1 "memory_operand" ""))
7445    (set (match_operand:SF 2 "register_operand" "")
7446         (match_operand:SF 3 "memory_operand" ""))]
7447   "registers_ok_for_ldd_peep (operands[2], operands[0]) 
7448   && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
7449   [(set (match_dup 2)
7450         (match_dup 3))]
7451   "operands[3] = widen_memory_access (operands[3], DFmode, 0);
7452    operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
7454 (define_peephole2
7455   [(set (match_operand:SF 0 "memory_operand" "")
7456         (match_operand:SF 1 "register_operand" ""))
7457    (set (match_operand:SF 2 "memory_operand" "")
7458         (match_operand:SF 3 "register_operand" ""))]
7459   "registers_ok_for_ldd_peep (operands[3], operands[1]) 
7460   && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
7461   [(set (match_dup 2)
7462         (match_dup 3))]
7463   "operands[2] = widen_memory_access (operands[2], DFmode, 0);
7464    operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
7466 ;; Optimize the case of following a reg-reg move with a test
7467 ;; of reg just moved.  Don't allow floating point regs for operand 0 or 1.
7468 ;; This can result from a float to fix conversion.
7470 (define_peephole2
7471   [(set (match_operand:SI 0 "register_operand" "")
7472         (match_operand:SI 1 "register_operand" ""))
7473    (set (reg:CC 100)
7474         (compare:CC (match_operand:SI 2 "register_operand" "")
7475                     (const_int 0)))]
7476   "(rtx_equal_p (operands[2], operands[0])
7477     || rtx_equal_p (operands[2], operands[1]))
7478     && ! SPARC_FP_REG_P (REGNO (operands[0]))
7479     && ! SPARC_FP_REG_P (REGNO (operands[1]))"
7480   [(parallel [(set (match_dup 0) (match_dup 1))
7481               (set (reg:CC 100)
7482                    (compare:CC (match_dup 1) (const_int 0)))])]
7483   "")
7485 (define_peephole2
7486   [(set (match_operand:DI 0 "register_operand" "")
7487         (match_operand:DI 1 "register_operand" ""))
7488    (set (reg:CCX 100)
7489         (compare:CCX (match_operand:DI 2 "register_operand" "")
7490                     (const_int 0)))]
7491   "TARGET_ARCH64
7492    && (rtx_equal_p (operands[2], operands[0])
7493        || rtx_equal_p (operands[2], operands[1]))
7494    && ! SPARC_FP_REG_P (REGNO (operands[0]))
7495    && ! SPARC_FP_REG_P (REGNO (operands[1]))"
7496   [(parallel [(set (match_dup 0) (match_dup 1))
7497               (set (reg:CCX 100)
7498                    (compare:CCX (match_dup 1) (const_int 0)))])]
7499   "")
7502 ;; Prefetch instructions.
7504 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
7505 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
7506 ;; ??? operations.  With DFA we might be able to model this, but it requires a lot of
7507 ;; ??? state.
7508 (define_expand "prefetch"
7509   [(match_operand 0 "address_operand" "")
7510    (match_operand 1 "const_int_operand" "")
7511    (match_operand 2 "const_int_operand" "")]
7512   "TARGET_V9"
7514   if (TARGET_ARCH64)
7515     emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
7516   else
7517     emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
7518   DONE;
7521 (define_insn "prefetch_64"
7522   [(prefetch (match_operand:DI 0 "address_operand" "p")
7523              (match_operand:DI 1 "const_int_operand" "n")
7524              (match_operand:DI 2 "const_int_operand" "n"))]
7525   ""
7527   static const char * const prefetch_instr[2][2] = {
7528     {
7529       "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7530       "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7531     },
7532     {
7533       "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7534       "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7535     }
7536   };
7537   int read_or_write = INTVAL (operands[1]);
7538   int locality = INTVAL (operands[2]);
7540   gcc_assert (read_or_write == 0 || read_or_write == 1);
7541   gcc_assert (locality >= 0 && locality < 4);
7542   return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7544   [(set_attr "type" "load")])
7546 (define_insn "prefetch_32"
7547   [(prefetch (match_operand:SI 0 "address_operand" "p")
7548              (match_operand:SI 1 "const_int_operand" "n")
7549              (match_operand:SI 2 "const_int_operand" "n"))]
7550   ""
7552   static const char * const prefetch_instr[2][2] = {
7553     {
7554       "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7555       "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7556     },
7557     {
7558       "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7559       "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7560     }
7561   };
7562   int read_or_write = INTVAL (operands[1]);
7563   int locality = INTVAL (operands[2]);
7565   gcc_assert (read_or_write == 0 || read_or_write == 1);
7566   gcc_assert (locality >= 0 && locality < 4);
7567   return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7569   [(set_attr "type" "load")])
7572 ;; Trap instructions.
7574 (define_insn "trap"
7575   [(trap_if (const_int 1) (const_int 5))]
7576   ""
7577   "ta\t5"
7578   [(set_attr "type" "trap")])
7580 (define_expand "conditional_trap"
7581   [(trap_if (match_operator 0 "noov_compare_operator" [(match_dup 2) (match_dup 3)])
7582             (match_operand:SI 1 "arith_operand" ""))]
7583   ""
7584   "operands[2] = gen_compare_reg (GET_CODE (operands[0]));
7585    if (GET_MODE (operands[2]) != CCmode && GET_MODE (operands[2]) != CCXmode)
7586      FAIL;
7587    operands[3] = const0_rtx;")
7589 (define_insn ""
7590   [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CC 100) (const_int 0)])
7591             (match_operand:SI 1 "arith_operand" "rM"))]
7592   ""
7594   if (TARGET_V9)
7595     return "t%C0\t%%icc, %1";
7596   else
7597     return "t%C0\t%1";
7599   [(set_attr "type" "trap")])
7601 (define_insn ""
7602   [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CCX 100) (const_int 0)])
7603             (match_operand:SI 1 "arith_operand" "rM"))]
7604   "TARGET_V9"
7605   "t%C0\t%%xcc, %1"
7606   [(set_attr "type" "trap")])
7609 ;; TLS support instructions.
7611 (define_insn "tgd_hi22"
7612   [(set (match_operand:SI 0 "register_operand" "=r")
7613         (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
7614                             UNSPEC_TLSGD)))]
7615   "TARGET_TLS"
7616   "sethi\\t%%tgd_hi22(%a1), %0")
7618 (define_insn "tgd_lo10"
7619   [(set (match_operand:SI 0 "register_operand" "=r")
7620         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7621                    (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
7622                               UNSPEC_TLSGD)))]
7623   "TARGET_TLS"
7624   "add\\t%1, %%tgd_lo10(%a2), %0")
7626 (define_insn "tgd_add32"
7627   [(set (match_operand:SI 0 "register_operand" "=r")
7628         (plus:SI (match_operand:SI 1 "register_operand" "r")
7629                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7630                              (match_operand 3 "tgd_symbolic_operand" "")]
7631                             UNSPEC_TLSGD)))]
7632   "TARGET_TLS && TARGET_ARCH32"
7633   "add\\t%1, %2, %0, %%tgd_add(%a3)")
7635 (define_insn "tgd_add64"
7636   [(set (match_operand:DI 0 "register_operand" "=r")
7637         (plus:DI (match_operand:DI 1 "register_operand" "r")
7638                  (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7639                              (match_operand 3 "tgd_symbolic_operand" "")]
7640                             UNSPEC_TLSGD)))]
7641   "TARGET_TLS && TARGET_ARCH64"
7642   "add\\t%1, %2, %0, %%tgd_add(%a3)")
7644 (define_insn "tgd_call32"
7645   [(set (match_operand 0 "register_operand" "=r")
7646         (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
7647                                   (match_operand 2 "tgd_symbolic_operand" "")]
7648                                  UNSPEC_TLSGD))
7649               (match_operand 3 "" "")))
7650    (clobber (reg:SI 15))]
7651   "TARGET_TLS && TARGET_ARCH32"
7652   "call\t%a1, %%tgd_call(%a2)%#"
7653   [(set_attr "type" "call")])
7655 (define_insn "tgd_call64"
7656   [(set (match_operand 0 "register_operand" "=r")
7657         (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
7658                                   (match_operand 2 "tgd_symbolic_operand" "")]
7659                                  UNSPEC_TLSGD))
7660               (match_operand 3 "" "")))
7661    (clobber (reg:DI 15))]
7662   "TARGET_TLS && TARGET_ARCH64"
7663   "call\t%a1, %%tgd_call(%a2)%#"
7664   [(set_attr "type" "call")])
7666 (define_insn "tldm_hi22"
7667   [(set (match_operand:SI 0 "register_operand" "=r")
7668         (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7669   "TARGET_TLS"
7670   "sethi\\t%%tldm_hi22(%&), %0")
7672 (define_insn "tldm_lo10"
7673   [(set (match_operand:SI 0 "register_operand" "=r")
7674         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7675                     (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7676   "TARGET_TLS"
7677   "add\\t%1, %%tldm_lo10(%&), %0")
7679 (define_insn "tldm_add32"
7680   [(set (match_operand:SI 0 "register_operand" "=r")
7681         (plus:SI (match_operand:SI 1 "register_operand" "r")
7682                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
7683                             UNSPEC_TLSLDM)))]
7684   "TARGET_TLS && TARGET_ARCH32"
7685   "add\\t%1, %2, %0, %%tldm_add(%&)")
7687 (define_insn "tldm_add64"
7688   [(set (match_operand:DI 0 "register_operand" "=r")
7689         (plus:DI (match_operand:DI 1 "register_operand" "r")
7690                  (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
7691                             UNSPEC_TLSLDM)))]
7692   "TARGET_TLS && TARGET_ARCH64"
7693   "add\\t%1, %2, %0, %%tldm_add(%&)")
7695 (define_insn "tldm_call32"
7696   [(set (match_operand 0 "register_operand" "=r")
7697         (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
7698                                  UNSPEC_TLSLDM))
7699               (match_operand 2 "" "")))
7700    (clobber (reg:SI 15))]
7701   "TARGET_TLS && TARGET_ARCH32"
7702   "call\t%a1, %%tldm_call(%&)%#"
7703   [(set_attr "type" "call")])
7705 (define_insn "tldm_call64"
7706   [(set (match_operand 0 "register_operand" "=r")
7707         (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
7708                                  UNSPEC_TLSLDM))
7709               (match_operand 2 "" "")))
7710    (clobber (reg:DI 15))]
7711   "TARGET_TLS && TARGET_ARCH64"
7712   "call\t%a1, %%tldm_call(%&)%#"
7713   [(set_attr "type" "call")])
7715 (define_insn "tldo_hix22"
7716   [(set (match_operand:SI 0 "register_operand" "=r")
7717         (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
7718                             UNSPEC_TLSLDO)))]
7719   "TARGET_TLS"
7720   "sethi\\t%%tldo_hix22(%a1), %0")
7722 (define_insn "tldo_lox10"
7723   [(set (match_operand:SI 0 "register_operand" "=r")
7724         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7725                    (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
7726                               UNSPEC_TLSLDO)))]
7727   "TARGET_TLS"
7728   "xor\\t%1, %%tldo_lox10(%a2), %0")
7730 (define_insn "tldo_add32"
7731   [(set (match_operand:SI 0 "register_operand" "=r")
7732         (plus:SI (match_operand:SI 1 "register_operand" "r")
7733                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7734                              (match_operand 3 "tld_symbolic_operand" "")]
7735                             UNSPEC_TLSLDO)))]
7736   "TARGET_TLS && TARGET_ARCH32"
7737   "add\\t%1, %2, %0, %%tldo_add(%a3)")
7739 (define_insn "tldo_add64"
7740   [(set (match_operand:DI 0 "register_operand" "=r")
7741         (plus:DI (match_operand:DI 1 "register_operand" "r")
7742                  (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7743                              (match_operand 3 "tld_symbolic_operand" "")]
7744                             UNSPEC_TLSLDO)))]
7745   "TARGET_TLS && TARGET_ARCH64"
7746   "add\\t%1, %2, %0, %%tldo_add(%a3)")
7748 (define_insn "tie_hi22"
7749   [(set (match_operand:SI 0 "register_operand" "=r")
7750         (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
7751                             UNSPEC_TLSIE)))]
7752   "TARGET_TLS"
7753   "sethi\\t%%tie_hi22(%a1), %0")
7755 (define_insn "tie_lo10"
7756   [(set (match_operand:SI 0 "register_operand" "=r")
7757         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7758                    (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
7759                               UNSPEC_TLSIE)))]
7760   "TARGET_TLS"
7761   "add\\t%1, %%tie_lo10(%a2), %0")
7763 (define_insn "tie_ld32"
7764   [(set (match_operand:SI 0 "register_operand" "=r")
7765         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
7766                     (match_operand:SI 2 "register_operand" "r")
7767                     (match_operand 3 "tie_symbolic_operand" "")]
7768                    UNSPEC_TLSIE))]
7769   "TARGET_TLS && TARGET_ARCH32"
7770   "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
7771   [(set_attr "type" "load")])
7773 (define_insn "tie_ld64"
7774   [(set (match_operand:DI 0 "register_operand" "=r")
7775         (unspec:DI [(match_operand:DI 1 "register_operand" "r")
7776                     (match_operand:SI 2 "register_operand" "r")
7777                     (match_operand 3 "tie_symbolic_operand" "")]
7778                    UNSPEC_TLSIE))]
7779   "TARGET_TLS && TARGET_ARCH64"
7780   "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
7781   [(set_attr "type" "load")])
7783 (define_insn "tie_add32"
7784   [(set (match_operand:SI 0 "register_operand" "=r")
7785         (plus:SI (match_operand:SI 1 "register_operand" "r")
7786                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7787                              (match_operand 3 "tie_symbolic_operand" "")]
7788                             UNSPEC_TLSIE)))]
7789   "TARGET_SUN_TLS && TARGET_ARCH32"
7790   "add\\t%1, %2, %0, %%tie_add(%a3)")
7792 (define_insn "tie_add64"
7793   [(set (match_operand:DI 0 "register_operand" "=r")
7794         (plus:DI (match_operand:DI 1 "register_operand" "r")
7795                  (unspec:DI [(match_operand:DI 2 "register_operand" "r")
7796                              (match_operand 3 "tie_symbolic_operand" "")]
7797                             UNSPEC_TLSIE)))]
7798   "TARGET_SUN_TLS && TARGET_ARCH64"
7799   "add\\t%1, %2, %0, %%tie_add(%a3)")
7801 (define_insn "tle_hix22_sp32"
7802   [(set (match_operand:SI 0 "register_operand" "=r")
7803         (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
7804                             UNSPEC_TLSLE)))]
7805   "TARGET_TLS && TARGET_ARCH32"
7806   "sethi\\t%%tle_hix22(%a1), %0")
7808 (define_insn "tle_lox10_sp32"
7809   [(set (match_operand:SI 0 "register_operand" "=r")
7810         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7811                    (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
7812                               UNSPEC_TLSLE)))]
7813   "TARGET_TLS && TARGET_ARCH32"
7814   "xor\\t%1, %%tle_lox10(%a2), %0")
7816 (define_insn "tle_hix22_sp64"
7817   [(set (match_operand:DI 0 "register_operand" "=r")
7818         (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
7819                             UNSPEC_TLSLE)))]
7820   "TARGET_TLS && TARGET_ARCH64"
7821   "sethi\\t%%tle_hix22(%a1), %0")
7823 (define_insn "tle_lox10_sp64"
7824   [(set (match_operand:DI 0 "register_operand" "=r")
7825         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
7826                    (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
7827                               UNSPEC_TLSLE)))]
7828   "TARGET_TLS && TARGET_ARCH64"
7829   "xor\\t%1, %%tle_lox10(%a2), %0")
7831 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
7832 (define_insn "*tldo_ldub_sp32"
7833   [(set (match_operand:QI 0 "register_operand" "=r")
7834         (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7835                                      (match_operand 3 "tld_symbolic_operand" "")]
7836                                     UNSPEC_TLSLDO)
7837                          (match_operand:SI 1 "register_operand" "r"))))]
7838   "TARGET_TLS && TARGET_ARCH32"
7839   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7840   [(set_attr "type" "load")
7841    (set_attr "us3load_type" "3cycle")])
7843 (define_insn "*tldo_ldub1_sp32"
7844   [(set (match_operand:HI 0 "register_operand" "=r")
7845         (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7846                                                      (match_operand 3 "tld_symbolic_operand" "")]
7847                                                     UNSPEC_TLSLDO)
7848                                          (match_operand:SI 1 "register_operand" "r")))))]
7849   "TARGET_TLS && TARGET_ARCH32"
7850   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7851   [(set_attr "type" "load")
7852    (set_attr "us3load_type" "3cycle")])
7854 (define_insn "*tldo_ldub2_sp32"
7855   [(set (match_operand:SI 0 "register_operand" "=r")
7856         (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7857                                                      (match_operand 3 "tld_symbolic_operand" "")]
7858                                                     UNSPEC_TLSLDO)
7859                                          (match_operand:SI 1 "register_operand" "r")))))]
7860   "TARGET_TLS && TARGET_ARCH32"
7861   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7862   [(set_attr "type" "load")
7863    (set_attr "us3load_type" "3cycle")])
7865 (define_insn "*tldo_ldsb1_sp32"
7866   [(set (match_operand:HI 0 "register_operand" "=r")
7867         (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7868                                                      (match_operand 3 "tld_symbolic_operand" "")]
7869                                                     UNSPEC_TLSLDO)
7870                                          (match_operand:SI 1 "register_operand" "r")))))]
7871   "TARGET_TLS && TARGET_ARCH32"
7872   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7873   [(set_attr "type" "sload")
7874    (set_attr "us3load_type" "3cycle")])
7876 (define_insn "*tldo_ldsb2_sp32"
7877   [(set (match_operand:SI 0 "register_operand" "=r")
7878         (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7879                                                      (match_operand 3 "tld_symbolic_operand" "")]
7880                                                     UNSPEC_TLSLDO)
7881                                          (match_operand:SI 1 "register_operand" "r")))))]
7882   "TARGET_TLS && TARGET_ARCH32"
7883   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7884   [(set_attr "type" "sload")
7885    (set_attr "us3load_type" "3cycle")])
7887 (define_insn "*tldo_ldub_sp64"
7888   [(set (match_operand:QI 0 "register_operand" "=r")
7889         (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7890                                      (match_operand 3 "tld_symbolic_operand" "")]
7891                                     UNSPEC_TLSLDO)
7892                          (match_operand:DI 1 "register_operand" "r"))))]
7893   "TARGET_TLS && TARGET_ARCH64"
7894   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7895   [(set_attr "type" "load")
7896    (set_attr "us3load_type" "3cycle")])
7898 (define_insn "*tldo_ldub1_sp64"
7899   [(set (match_operand:HI 0 "register_operand" "=r")
7900         (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7901                                                      (match_operand 3 "tld_symbolic_operand" "")]
7902                                                     UNSPEC_TLSLDO)
7903                                          (match_operand:DI 1 "register_operand" "r")))))]
7904   "TARGET_TLS && TARGET_ARCH64"
7905   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7906   [(set_attr "type" "load")
7907    (set_attr "us3load_type" "3cycle")])
7909 (define_insn "*tldo_ldub2_sp64"
7910   [(set (match_operand:SI 0 "register_operand" "=r")
7911         (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7912                                                      (match_operand 3 "tld_symbolic_operand" "")]
7913                                                     UNSPEC_TLSLDO)
7914                                          (match_operand:DI 1 "register_operand" "r")))))]
7915   "TARGET_TLS && TARGET_ARCH64"
7916   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7917   [(set_attr "type" "load")
7918    (set_attr "us3load_type" "3cycle")])
7920 (define_insn "*tldo_ldub3_sp64"
7921   [(set (match_operand:DI 0 "register_operand" "=r")
7922         (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7923                                                      (match_operand 3 "tld_symbolic_operand" "")]
7924                                                     UNSPEC_TLSLDO)
7925                                          (match_operand:DI 1 "register_operand" "r")))))]
7926   "TARGET_TLS && TARGET_ARCH64"
7927   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7928   [(set_attr "type" "load")
7929    (set_attr "us3load_type" "3cycle")])
7931 (define_insn "*tldo_ldsb1_sp64"
7932   [(set (match_operand:HI 0 "register_operand" "=r")
7933         (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7934                                                      (match_operand 3 "tld_symbolic_operand" "")]
7935                                                     UNSPEC_TLSLDO)
7936                                          (match_operand:DI 1 "register_operand" "r")))))]
7937   "TARGET_TLS && TARGET_ARCH64"
7938   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7939   [(set_attr "type" "sload")
7940    (set_attr "us3load_type" "3cycle")])
7942 (define_insn "*tldo_ldsb2_sp64"
7943   [(set (match_operand:SI 0 "register_operand" "=r")
7944         (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7945                                                      (match_operand 3 "tld_symbolic_operand" "")]
7946                                                     UNSPEC_TLSLDO)
7947                                          (match_operand:DI 1 "register_operand" "r")))))]
7948   "TARGET_TLS && TARGET_ARCH64"
7949   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7950   [(set_attr "type" "sload")
7951    (set_attr "us3load_type" "3cycle")])
7953 (define_insn "*tldo_ldsb3_sp64"
7954   [(set (match_operand:DI 0 "register_operand" "=r")
7955         (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7956                                                      (match_operand 3 "tld_symbolic_operand" "")]
7957                                                     UNSPEC_TLSLDO)
7958                                          (match_operand:DI 1 "register_operand" "r")))))]
7959   "TARGET_TLS && TARGET_ARCH64"
7960   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7961   [(set_attr "type" "sload")
7962    (set_attr "us3load_type" "3cycle")])
7964 (define_insn "*tldo_lduh_sp32"
7965   [(set (match_operand:HI 0 "register_operand" "=r")
7966         (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7967                                      (match_operand 3 "tld_symbolic_operand" "")]
7968                                     UNSPEC_TLSLDO)
7969                          (match_operand:SI 1 "register_operand" "r"))))]
7970   "TARGET_TLS && TARGET_ARCH32"
7971   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7972   [(set_attr "type" "load")
7973    (set_attr "us3load_type" "3cycle")])
7975 (define_insn "*tldo_lduh1_sp32"
7976   [(set (match_operand:SI 0 "register_operand" "=r")
7977         (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7978                                                      (match_operand 3 "tld_symbolic_operand" "")]
7979                                                     UNSPEC_TLSLDO)
7980                                          (match_operand:SI 1 "register_operand" "r")))))]
7981   "TARGET_TLS && TARGET_ARCH32"
7982   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7983   [(set_attr "type" "load")
7984    (set_attr "us3load_type" "3cycle")])
7986 (define_insn "*tldo_ldsh1_sp32"
7987   [(set (match_operand:SI 0 "register_operand" "=r")
7988         (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7989                                                      (match_operand 3 "tld_symbolic_operand" "")]
7990                                                     UNSPEC_TLSLDO)
7991                                          (match_operand:SI 1 "register_operand" "r")))))]
7992   "TARGET_TLS && TARGET_ARCH32"
7993   "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7994   [(set_attr "type" "sload")
7995    (set_attr "us3load_type" "3cycle")])
7997 (define_insn "*tldo_lduh_sp64"
7998   [(set (match_operand:HI 0 "register_operand" "=r")
7999         (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8000                                      (match_operand 3 "tld_symbolic_operand" "")]
8001                                     UNSPEC_TLSLDO)
8002                          (match_operand:DI 1 "register_operand" "r"))))]
8003   "TARGET_TLS && TARGET_ARCH64"
8004   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8005   [(set_attr "type" "load")
8006    (set_attr "us3load_type" "3cycle")])
8008 (define_insn "*tldo_lduh1_sp64"
8009   [(set (match_operand:SI 0 "register_operand" "=r")
8010         (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8011                                                      (match_operand 3 "tld_symbolic_operand" "")]
8012                                                     UNSPEC_TLSLDO)
8013                                          (match_operand:DI 1 "register_operand" "r")))))]
8014   "TARGET_TLS && TARGET_ARCH64"
8015   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8016   [(set_attr "type" "load")
8017    (set_attr "us3load_type" "3cycle")])
8019 (define_insn "*tldo_lduh2_sp64"
8020   [(set (match_operand:DI 0 "register_operand" "=r")
8021         (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8022                                                      (match_operand 3 "tld_symbolic_operand" "")]
8023                                                     UNSPEC_TLSLDO)
8024                                          (match_operand:DI 1 "register_operand" "r")))))]
8025   "TARGET_TLS && TARGET_ARCH64"
8026   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8027   [(set_attr "type" "load")
8028    (set_attr "us3load_type" "3cycle")])
8030 (define_insn "*tldo_ldsh1_sp64"
8031   [(set (match_operand:SI 0 "register_operand" "=r")
8032         (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8033                                                      (match_operand 3 "tld_symbolic_operand" "")]
8034                                                     UNSPEC_TLSLDO)
8035                                          (match_operand:DI 1 "register_operand" "r")))))]
8036   "TARGET_TLS && TARGET_ARCH64"
8037   "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8038   [(set_attr "type" "sload")
8039    (set_attr "us3load_type" "3cycle")])
8041 (define_insn "*tldo_ldsh2_sp64"
8042   [(set (match_operand:DI 0 "register_operand" "=r")
8043         (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8044                                                      (match_operand 3 "tld_symbolic_operand" "")]
8045                                                     UNSPEC_TLSLDO)
8046                                          (match_operand:DI 1 "register_operand" "r")))))]
8047   "TARGET_TLS && TARGET_ARCH64"
8048   "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8049   [(set_attr "type" "sload")
8050    (set_attr "us3load_type" "3cycle")])
8052 (define_insn "*tldo_lduw_sp32"
8053   [(set (match_operand:SI 0 "register_operand" "=r")
8054         (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8055                                      (match_operand 3 "tld_symbolic_operand" "")]
8056                                     UNSPEC_TLSLDO)
8057                          (match_operand:SI 1 "register_operand" "r"))))]
8058   "TARGET_TLS && TARGET_ARCH32"
8059   "ld\t[%1 + %2], %0, %%tldo_add(%3)"
8060   [(set_attr "type" "load")])
8062 (define_insn "*tldo_lduw_sp64"
8063   [(set (match_operand:SI 0 "register_operand" "=r")
8064         (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8065                                      (match_operand 3 "tld_symbolic_operand" "")]
8066                                     UNSPEC_TLSLDO)
8067                          (match_operand:DI 1 "register_operand" "r"))))]
8068   "TARGET_TLS && TARGET_ARCH64"
8069   "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8070   [(set_attr "type" "load")])
8072 (define_insn "*tldo_lduw1_sp64"
8073   [(set (match_operand:DI 0 "register_operand" "=r")
8074         (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8075                                                      (match_operand 3 "tld_symbolic_operand" "")]
8076                                                     UNSPEC_TLSLDO)
8077                                          (match_operand:DI 1 "register_operand" "r")))))]
8078   "TARGET_TLS && TARGET_ARCH64"
8079   "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8080   [(set_attr "type" "load")])
8082 (define_insn "*tldo_ldsw1_sp64"
8083   [(set (match_operand:DI 0 "register_operand" "=r")
8084         (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8085                                                      (match_operand 3 "tld_symbolic_operand" "")]
8086                                                     UNSPEC_TLSLDO)
8087                                          (match_operand:DI 1 "register_operand" "r")))))]
8088   "TARGET_TLS && TARGET_ARCH64"
8089   "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
8090   [(set_attr "type" "sload")
8091    (set_attr "us3load_type" "3cycle")])
8093 (define_insn "*tldo_ldx_sp64"
8094   [(set (match_operand:DI 0 "register_operand" "=r")
8095         (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8096                                      (match_operand 3 "tld_symbolic_operand" "")]
8097                                     UNSPEC_TLSLDO)
8098                          (match_operand:DI 1 "register_operand" "r"))))]
8099   "TARGET_TLS && TARGET_ARCH64"
8100   "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
8101   [(set_attr "type" "load")])
8103 (define_insn "*tldo_stb_sp32"
8104   [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8105                                      (match_operand 3 "tld_symbolic_operand" "")]
8106                                     UNSPEC_TLSLDO)
8107                          (match_operand:SI 1 "register_operand" "r")))
8108         (match_operand:QI 0 "register_operand" "=r"))]
8109   "TARGET_TLS && TARGET_ARCH32"
8110   "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8111   [(set_attr "type" "store")])
8113 (define_insn "*tldo_stb_sp64"
8114   [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8115                                      (match_operand 3 "tld_symbolic_operand" "")]
8116                                     UNSPEC_TLSLDO)
8117                          (match_operand:DI 1 "register_operand" "r")))
8118         (match_operand:QI 0 "register_operand" "=r"))]
8119   "TARGET_TLS && TARGET_ARCH64"
8120   "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8121   [(set_attr "type" "store")])
8123 (define_insn "*tldo_sth_sp32"
8124   [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8125                                      (match_operand 3 "tld_symbolic_operand" "")]
8126                                     UNSPEC_TLSLDO)
8127                          (match_operand:SI 1 "register_operand" "r")))
8128         (match_operand:HI 0 "register_operand" "=r"))]
8129   "TARGET_TLS && TARGET_ARCH32"
8130   "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8131   [(set_attr "type" "store")])
8133 (define_insn "*tldo_sth_sp64"
8134   [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8135                                      (match_operand 3 "tld_symbolic_operand" "")]
8136                                     UNSPEC_TLSLDO)
8137                          (match_operand:DI 1 "register_operand" "r")))
8138         (match_operand:HI 0 "register_operand" "=r"))]
8139   "TARGET_TLS && TARGET_ARCH64"
8140   "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8141   [(set_attr "type" "store")])
8143 (define_insn "*tldo_stw_sp32"
8144   [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8145                                      (match_operand 3 "tld_symbolic_operand" "")]
8146                                     UNSPEC_TLSLDO)
8147                          (match_operand:SI 1 "register_operand" "r")))
8148         (match_operand:SI 0 "register_operand" "=r"))]
8149   "TARGET_TLS && TARGET_ARCH32"
8150   "st\t%0, [%1 + %2], %%tldo_add(%3)"
8151   [(set_attr "type" "store")])
8153 (define_insn "*tldo_stw_sp64"
8154   [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8155                                      (match_operand 3 "tld_symbolic_operand" "")]
8156                                     UNSPEC_TLSLDO)
8157                          (match_operand:DI 1 "register_operand" "r")))
8158         (match_operand:SI 0 "register_operand" "=r"))]
8159   "TARGET_TLS && TARGET_ARCH64"
8160   "stw\t%0, [%1 + %2], %%tldo_add(%3)"
8161   [(set_attr "type" "store")])
8163 (define_insn "*tldo_stx_sp64"
8164   [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8165                                      (match_operand 3 "tld_symbolic_operand" "")]
8166                                     UNSPEC_TLSLDO)
8167                          (match_operand:DI 1 "register_operand" "r")))
8168         (match_operand:DI 0 "register_operand" "=r"))]
8169   "TARGET_TLS && TARGET_ARCH64"
8170   "stx\t%0, [%1 + %2], %%tldo_add(%3)"
8171   [(set_attr "type" "store")])
8174 ;; Stack protector instructions.
8176 (define_expand "stack_protect_set"
8177   [(match_operand 0 "memory_operand" "")
8178    (match_operand 1 "memory_operand" "")]
8179   ""
8181 #ifdef TARGET_THREAD_SSP_OFFSET
8182   rtx tlsreg = gen_rtx_REG (Pmode, 7);
8183   rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
8184   operands[1] = gen_rtx_MEM (Pmode, addr);
8185 #endif
8186   if (TARGET_ARCH64)
8187     emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
8188   else
8189     emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
8190   DONE;
8193 (define_insn "stack_protect_setsi"
8194   [(set (match_operand:SI 0 "memory_operand" "=m")
8195         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
8196    (set (match_scratch:SI 2 "=&r") (const_int 0))]
8197   "TARGET_ARCH32"
8198   "ld\t%1, %2\;st\t%2, %0\;mov\t0, %2"
8199   [(set_attr "type" "multi")
8200    (set_attr "length" "3")])
8202 (define_insn "stack_protect_setdi"
8203   [(set (match_operand:DI 0 "memory_operand" "=m")
8204         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
8205    (set (match_scratch:DI 2 "=&r") (const_int 0))]
8206   "TARGET_ARCH64"
8207   "ldx\t%1, %2\;stx\t%2, %0\;mov\t0, %2"
8208   [(set_attr "type" "multi")
8209    (set_attr "length" "3")])
8211 (define_expand "stack_protect_test"
8212   [(match_operand 0 "memory_operand" "")
8213    (match_operand 1 "memory_operand" "")
8214    (match_operand 2 "" "")]
8215   ""
8217 #ifdef TARGET_THREAD_SSP_OFFSET
8218   rtx tlsreg = gen_rtx_REG (Pmode, 7);
8219   rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
8220   operands[1] = gen_rtx_MEM (Pmode, addr);
8221 #endif
8222   if (TARGET_ARCH64)
8223     {
8224       rtx temp = gen_reg_rtx (Pmode);
8225       emit_insn (gen_stack_protect_testdi (temp, operands[0], operands[1]));
8226       sparc_compare_op0 = temp;
8227       sparc_compare_op1 = const0_rtx;
8228     }
8229   else
8230     {
8231       emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
8232       sparc_compare_op0 = operands[0];
8233       sparc_compare_op1 = operands[1];
8234       sparc_compare_emitted = gen_rtx_REG (CCmode, SPARC_ICC_REG);
8235     }
8236   emit_jump_insn (gen_beq (operands[2]));
8237   DONE;
8240 (define_insn "stack_protect_testsi"
8241   [(set (reg:CC 100)
8242         (unspec:CC [(match_operand:SI 0 "memory_operand" "m")
8243                     (match_operand:SI 1 "memory_operand" "m")]
8244                    UNSPEC_SP_TEST))
8245    (set (match_scratch:SI 3 "=r") (const_int 0))
8246    (clobber (match_scratch:SI 2 "=&r"))]
8247   "TARGET_ARCH32"
8248   "ld\t%0, %2\;ld\t%1, %3\;xorcc\t%2, %3, %2\;mov\t0, %3"
8249   [(set_attr "type" "multi")
8250    (set_attr "length" "4")])
8252 (define_insn "stack_protect_testdi"
8253   [(set (match_operand:DI 0 "register_operand" "=&r")
8254         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
8255                     (match_operand:DI 2 "memory_operand" "m")]
8256                    UNSPEC_SP_TEST))
8257    (set (match_scratch:DI 3 "=r") (const_int 0))]
8258   "TARGET_ARCH64"
8259   "ldx\t%1, %0\;ldx\t%2, %3\;xor\t%0, %3, %0\;mov\t0, %3"
8260   [(set_attr "type" "multi")
8261    (set_attr "length" "4")])
8264 ;; Vector instructions.
8266 (define_insn "addv2si3"
8267   [(set (match_operand:V2SI 0 "register_operand" "=e")
8268         (plus:V2SI (match_operand:V2SI 1 "register_operand" "e")
8269                    (match_operand:V2SI 2 "register_operand" "e")))]
8270   "TARGET_VIS"
8271   "fpadd32\t%1, %2, %0"
8272   [(set_attr "type" "fga")
8273    (set_attr "fptype" "double")])
8275 (define_insn "addv4hi3"
8276   [(set (match_operand:V4HI 0 "register_operand" "=e")
8277          (plus:V4HI (match_operand:V4HI 1 "register_operand" "e")
8278                     (match_operand:V4HI 2 "register_operand" "e")))]
8279   "TARGET_VIS"
8280   "fpadd16\t%1, %2, %0"
8281   [(set_attr "type" "fga")
8282    (set_attr "fptype" "double")])
8284 ;; fpadd32s is emitted by the addsi3 pattern.
8286 (define_insn "addv2hi3"
8287   [(set (match_operand:V2HI 0 "register_operand" "=f")
8288         (plus:V2HI (match_operand:V2HI 1 "register_operand" "f")
8289                    (match_operand:V2HI 2 "register_operand" "f")))]
8290   "TARGET_VIS"
8291   "fpadd16s\t%1, %2, %0"
8292   [(set_attr "type" "fga")
8293    (set_attr "fptype" "single")])
8295 (define_insn "subv2si3"
8296   [(set (match_operand:V2SI 0 "register_operand" "=e")
8297         (minus:V2SI (match_operand:V2SI 1 "register_operand" "e")
8298                     (match_operand:V2SI 2 "register_operand" "e")))]
8299   "TARGET_VIS"
8300   "fpsub32\t%1, %2, %0"
8301   [(set_attr "type" "fga")
8302    (set_attr "fptype" "double")])
8304 (define_insn "subv4hi3"
8305   [(set (match_operand:V4HI 0 "register_operand" "=e")
8306         (minus:V4HI (match_operand:V4HI 1 "register_operand" "e")
8307                     (match_operand:V4HI 2 "register_operand" "e")))]
8308   "TARGET_VIS"
8309   "fpsub16\t%1, %2, %0"
8310   [(set_attr "type" "fga")
8311    (set_attr "fptype" "double")])
8313 ;; fpsub32s is emitted by the subsi3 pattern.
8315 (define_insn "subv2hi3"
8316   [(set (match_operand:V2HI 0 "register_operand" "=f")
8317         (minus:V2HI (match_operand:V2HI 1 "register_operand" "f")
8318                     (match_operand:V2HI 2 "register_operand" "f")))]
8319   "TARGET_VIS"
8320   "fpsub16s\t%1, %2, %0"
8321   [(set_attr "type" "fga")
8322    (set_attr "fptype" "single")])
8324 ;; All other logical instructions have integer equivalents so they
8325 ;; are defined together.
8327 ;; (ior (not (op1)) (not (op2))) is the canonical form of NAND.
8329 (define_insn "*nand<V64mode>_vis"
8330   [(set (match_operand:V64 0 "register_operand" "=e")
8331         (ior:V64 (not:V64 (match_operand:V64 1 "register_operand" "e"))
8332                  (not:V64 (match_operand:V64 2 "register_operand" "e"))))]
8333   "TARGET_VIS"
8334   "fnand\t%1, %2, %0"
8335   [(set_attr "type" "fga")
8336    (set_attr "fptype" "double")])
8338 (define_insn "*nand<V32mode>_vis"
8339   [(set (match_operand:V32 0 "register_operand" "=f")
8340          (ior:V32 (not:V32 (match_operand:V32 1 "register_operand" "f"))
8341                   (not:V32 (match_operand:V32 2 "register_operand" "f"))))]
8342   "TARGET_VIS"
8343   "fnands\t%1, %2, %0"
8344   [(set_attr "type" "fga")
8345    (set_attr "fptype" "single")])
8347 ;; Hard to generate VIS instructions.  We have builtins for these.
8349 (define_insn "fpack16_vis"
8350   [(set (match_operand:V4QI 0 "register_operand" "=f")
8351         (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e")]
8352                       UNSPEC_FPACK16))]
8353   "TARGET_VIS"
8354   "fpack16\t%1, %0"
8355   [(set_attr "type" "fga")
8356    (set_attr "fptype" "double")])
8358 (define_insn "fpackfix_vis"
8359   [(set (match_operand:V2HI 0 "register_operand" "=f")
8360         (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e")]
8361                       UNSPEC_FPACKFIX))]
8362   "TARGET_VIS"
8363   "fpackfix\t%1, %0"
8364   [(set_attr "type" "fga")
8365    (set_attr "fptype" "double")])
8367 (define_insn "fpack32_vis"
8368   [(set (match_operand:V8QI 0 "register_operand" "=e")
8369         (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e")
8370                       (match_operand:V8QI 2 "register_operand" "e")]
8371                      UNSPEC_FPACK32))]
8372   "TARGET_VIS"
8373   "fpack32\t%1, %2, %0"
8374   [(set_attr "type" "fga")
8375    (set_attr "fptype" "double")])
8377 (define_insn "fexpand_vis"
8378   [(set (match_operand:V4HI 0 "register_operand" "=e")
8379         (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")]
8380          UNSPEC_FEXPAND))]
8381  "TARGET_VIS"
8382  "fexpand\t%1, %0"
8383  [(set_attr "type" "fga")
8384   (set_attr "fptype" "double")])
8386 ;; It may be possible to describe this operation as (1 indexed):
8387 ;; (vec_select (vec_duplicate (vec_duplicate (vec_concat 1 2)))
8388 ;;  1,5,10,14,19,23,28,32)
8389 ;; Note that (vec_merge:V8QI [(V4QI) (V4QI)] (10101010 = 170) doesn't work
8390 ;; because vec_merge expects all the operands to be of the same type.
8391 (define_insn "fpmerge_vis"
8392   [(set (match_operand:V8QI 0 "register_operand" "=e")
8393         (unspec:V8QI [(match_operand:V4QI 1 "register_operand" "f")
8394                       (match_operand:V4QI 2 "register_operand" "f")]
8395          UNSPEC_FPMERGE))]
8396  "TARGET_VIS"
8397  "fpmerge\t%1, %2, %0"
8398  [(set_attr "type" "fga")
8399   (set_attr "fptype" "double")])
8401 ;; Partitioned multiply instructions
8402 (define_insn "fmul8x16_vis"
8403   [(set (match_operand:V4HI 0 "register_operand" "=e")
8404         (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
8405                    (match_operand:V4HI 2 "register_operand" "e")))]
8406   "TARGET_VIS"
8407   "fmul8x16\t%1, %2, %0"
8408   [(set_attr "type" "fpmul")
8409    (set_attr "fptype" "double")])
8411 ;; Only one of the following two insns can be a multiply.
8412 (define_insn "fmul8x16au_vis"
8413   [(set (match_operand:V4HI 0 "register_operand" "=e")
8414         (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
8415                    (match_operand:V2HI 2 "register_operand" "f")))]
8416   "TARGET_VIS"
8417   "fmul8x16au\t%1, %2, %0"
8418   [(set_attr "type" "fpmul")
8419    (set_attr "fptype" "double")])
8421 (define_insn "fmul8x16al_vis"
8422   [(set (match_operand:V4HI 0 "register_operand" "=e")
8423         (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8424                       (match_operand:V2HI 2 "register_operand" "f")]
8425          UNSPEC_MUL16AL))]
8426   "TARGET_VIS"
8427   "fmul8x16al\t%1, %2, %0"
8428   [(set_attr "type" "fpmul")
8429    (set_attr "fptype" "double")])
8431 ;; Only one of the following two insns can be a multiply.
8432 (define_insn "fmul8sux16_vis"
8433   [(set (match_operand:V4HI 0 "register_operand" "=e")
8434         (mult:V4HI (match_operand:V8QI 1 "register_operand" "e")
8435                    (match_operand:V4HI 2 "register_operand" "e")))]
8436   "TARGET_VIS"
8437   "fmul8sux16\t%1, %2, %0"
8438   [(set_attr "type" "fpmul")
8439    (set_attr "fptype" "double")])
8441 (define_insn "fmul8ulx16_vis"
8442   [(set (match_operand:V4HI 0 "register_operand" "=e")
8443         (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
8444                       (match_operand:V4HI 2 "register_operand" "e")]
8445          UNSPEC_MUL8UL))]
8446   "TARGET_VIS"
8447   "fmul8ulx16\t%1, %2, %0"
8448   [(set_attr "type" "fpmul")
8449    (set_attr "fptype" "double")])
8451 ;; Only one of the following two insns can be a multiply.
8452 (define_insn "fmuld8sux16_vis"
8453   [(set (match_operand:V2SI 0 "register_operand" "=e")
8454         (mult:V2SI (match_operand:V4QI 1 "register_operand" "f")
8455                    (match_operand:V2HI 2 "register_operand" "f")))]
8456   "TARGET_VIS"
8457   "fmuld8sux16\t%1, %2, %0"
8458   [(set_attr "type" "fpmul")
8459    (set_attr "fptype" "double")])
8461 (define_insn "fmuld8ulx16_vis"
8462   [(set (match_operand:V2SI 0 "register_operand" "=e")
8463         (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
8464                       (match_operand:V2HI 2 "register_operand" "f")]
8465          UNSPEC_MULDUL))]
8466   "TARGET_VIS"
8467   "fmuld8ulx16\t%1, %2, %0"
8468   [(set_attr "type" "fpmul")
8469    (set_attr "fptype" "double")])
8471 ;; Using faligndata only makes sense after an alignaddr since the choice of
8472 ;; bytes to take out of each operand is dependent on the results of the last
8473 ;; alignaddr.
8474 (define_insn "faligndata<V64I:mode>_vis"
8475   [(set (match_operand:V64I 0 "register_operand" "=e")
8476         (unspec:V64I [(match_operand:V64I 1 "register_operand" "e")
8477                       (match_operand:V64I 2 "register_operand" "e")]
8478          UNSPEC_ALIGNDATA))]
8479   "TARGET_VIS"
8480   "faligndata\t%1, %2, %0"
8481   [(set_attr "type" "fga")
8482    (set_attr "fptype" "double")])
8484 (define_insn "alignaddr<P:mode>_vis"
8485   [(set (match_operand:P 0 "register_operand" "=r")
8486         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8487                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
8488          UNSPEC_ALIGNADDR))]
8489   "TARGET_VIS"
8490   "alignaddr\t%r1, %r2, %0")
8492 (define_insn "pdist_vis"
8493   [(set (match_operand:DI 0 "register_operand" "=e")
8494         (unspec:DI [(match_operand:V8QI 1 "register_operand" "e")
8495                     (match_operand:V8QI 2 "register_operand" "e")
8496                     (match_operand:DI 3 "register_operand" "0")]
8497          UNSPEC_PDIST))]
8498   "TARGET_VIS"
8499   "pdist\t%1, %2, %0"
8500   [(set_attr "type" "fga")
8501    (set_attr "fptype" "double")])
8503 (include "sync.md")