Dead
[official-gcc.git] / gomp-20050608-branch / gcc / config / sparc / sparc.md
blob10727cb3416cc1e7dc84859a29867c32e044182a
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 Free Software Foundation, Inc.
4 ;;  Contributed by Michael Tiemann (tiemann@cygnus.com)
5 ;;  64-bit SPARC-V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
6 ;;  at Cygnus Support.
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING.  If not, write to
22 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, USA.
25 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
27 (define_constants
28   [(UNSPEC_MOVE_PIC             0)
29    (UNSPEC_UPDATE_RETURN        1)
30    (UNSPEC_LOAD_PCREL_SYM       2)
31    (UNSPEC_MOVE_PIC_LABEL       5)
32    (UNSPEC_SETH44               6)
33    (UNSPEC_SETM44               7)
34    (UNSPEC_SETHH                9)
35    (UNSPEC_SETLM                10)
36    (UNSPEC_EMB_HISUM            11)
37    (UNSPEC_EMB_TEXTUHI          13)
38    (UNSPEC_EMB_TEXTHI           14)
39    (UNSPEC_EMB_TEXTULO          15)
40    (UNSPEC_EMB_SETHM            18)
42    (UNSPEC_TLSGD                30)
43    (UNSPEC_TLSLDM               31)
44    (UNSPEC_TLSLDO               32)
45    (UNSPEC_TLSIE                33)
46    (UNSPEC_TLSLE                34)
47    (UNSPEC_TLSLD_BASE           35)
49    (UNSPEC_FPACK16              40)
50    (UNSPEC_FPACK32              41)
51    (UNSPEC_FPACKFIX             42)
52    (UNSPEC_FEXPAND              43)
53    (UNSPEC_FPMERGE              44)
54    (UNSPEC_MUL16AL              45)
55    (UNSPEC_MUL8UL               46)
56    (UNSPEC_MULDUL               47)
57    (UNSPEC_ALIGNDATA            48)
58    (UNSPEC_ALIGNADDR            49)
59    (UNSPEC_PDIST                50)
61    (UNSPEC_SP_SET               60)
62    (UNSPEC_SP_TEST              61)
63   ])
65 (define_constants
66   [(UNSPECV_BLOCKAGE            0)
67    (UNSPECV_FLUSHW              1)
68    (UNSPECV_GOTO                2)
69    (UNSPECV_FLUSH               4)
70    (UNSPECV_SETJMP              5)
71    (UNSPECV_SAVEW               6)
72    (UNSPECV_MEMBAR              7)
73    (UNSPECV_CAS                 8)
74    (UNSPECV_SWAP                9)
75    (UNSPECV_LDSTUB              10)
76   ])
78 ;; The upper 32 fp regs on the v9 can't hold SFmode values.  To deal with this
79 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip.  The name
80 ;; is a bit of a misnomer as it covers all 64 fp regs.  The corresponding
81 ;; constraint letter is 'e'.  To avoid any confusion, 'e' is used instead of
82 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
85 ;; Attribute for cpu type.
86 ;; These must match the values for enum processor_type in sparc.h.
87 (define_attr "cpu"
88   "v7,
89    cypress,
90    v8,
91    supersparc,
92    sparclite,f930,f934,
93    hypersparc,sparclite86x,
94    sparclet,tsc701,
95    v9,
96    ultrasparc,
97    ultrasparc3"
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")
320 ;; Operand and operator predicates.
322 (include "predicates.md")
325 ;; Compare instructions.
327 ;; We generate RTL for comparisons and branches by having the cmpxx 
328 ;; patterns store away the operands.  Then, the scc and bcc patterns
329 ;; emit RTL for both the compare and the branch.
331 ;; We do this because we want to generate different code for an sne and
332 ;; seq insn.  In those cases, if the second operand of the compare is not
333 ;; const0_rtx, we want to compute the xor of the two operands and test
334 ;; it against zero.
336 ;; We start with the DEFINE_EXPANDs, then the DEFINE_INSNs to match
337 ;; the patterns.  Finally, we have the DEFINE_SPLITs for some of the scc
338 ;; insns that actually require more than one machine instruction.
340 (define_expand "cmpsi"
341   [(set (reg:CC 100)
342         (compare:CC (match_operand:SI 0 "compare_operand" "")
343                     (match_operand:SI 1 "arith_operand" "")))]
344   ""
346   if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx)
347     operands[0] = force_reg (SImode, operands[0]);
349   sparc_compare_op0 = operands[0];
350   sparc_compare_op1 = operands[1];
351   DONE;
354 (define_expand "cmpdi"
355   [(set (reg:CCX 100)
356         (compare:CCX (match_operand:DI 0 "compare_operand" "")
357                      (match_operand:DI 1 "arith_operand" "")))]
358   "TARGET_ARCH64"
360   if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx)
361     operands[0] = force_reg (DImode, operands[0]);
363   sparc_compare_op0 = operands[0];
364   sparc_compare_op1 = operands[1];
365   DONE;
368 (define_expand "cmpsf"
369   ;; The 96 here isn't ever used by anyone.
370   [(set (reg:CCFP 96)
371         (compare:CCFP (match_operand:SF 0 "register_operand" "")
372                       (match_operand:SF 1 "register_operand" "")))]
373   "TARGET_FPU"
375   sparc_compare_op0 = operands[0];
376   sparc_compare_op1 = operands[1];
377   DONE;
380 (define_expand "cmpdf"
381   ;; The 96 here isn't ever used by anyone.
382   [(set (reg:CCFP 96)
383         (compare:CCFP (match_operand:DF 0 "register_operand" "")
384                       (match_operand:DF 1 "register_operand" "")))]
385   "TARGET_FPU"
387   sparc_compare_op0 = operands[0];
388   sparc_compare_op1 = operands[1];
389   DONE;
392 (define_expand "cmptf"
393   ;; The 96 here isn't ever used by anyone.
394   [(set (reg:CCFP 96)
395         (compare:CCFP (match_operand:TF 0 "register_operand" "")
396                       (match_operand:TF 1 "register_operand" "")))]
397   "TARGET_FPU"
399   sparc_compare_op0 = operands[0];
400   sparc_compare_op1 = operands[1];
401   DONE;
404 ;; Now the compare DEFINE_INSNs.
406 (define_insn "*cmpsi_insn"
407   [(set (reg:CC 100)
408         (compare:CC (match_operand:SI 0 "register_operand" "r")
409                     (match_operand:SI 1 "arith_operand" "rI")))]
410   ""
411   "cmp\t%0, %1"
412   [(set_attr "type" "compare")])
414 (define_insn "*cmpdi_sp64"
415   [(set (reg:CCX 100)
416         (compare:CCX (match_operand:DI 0 "register_operand" "r")
417                      (match_operand:DI 1 "arith_operand" "rI")))]
418   "TARGET_ARCH64"
419   "cmp\t%0, %1"
420   [(set_attr "type" "compare")])
422 (define_insn "*cmpsf_fpe"
423   [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
424         (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
425                        (match_operand:SF 2 "register_operand" "f")))]
426   "TARGET_FPU"
428   if (TARGET_V9)
429     return "fcmpes\t%0, %1, %2";
430   return "fcmpes\t%1, %2";
432   [(set_attr "type" "fpcmp")])
434 (define_insn "*cmpdf_fpe"
435   [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
436         (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
437                        (match_operand:DF 2 "register_operand" "e")))]
438   "TARGET_FPU"
440   if (TARGET_V9)
441     return "fcmped\t%0, %1, %2";
442   return "fcmped\t%1, %2";
444   [(set_attr "type" "fpcmp")
445    (set_attr "fptype" "double")])
447 (define_insn "*cmptf_fpe"
448   [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
449         (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
450                        (match_operand:TF 2 "register_operand" "e")))]
451   "TARGET_FPU && TARGET_HARD_QUAD"
453   if (TARGET_V9)
454     return "fcmpeq\t%0, %1, %2";
455   return "fcmpeq\t%1, %2";
457   [(set_attr "type" "fpcmp")])
459 (define_insn "*cmpsf_fp"
460   [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
461         (compare:CCFP (match_operand:SF 1 "register_operand" "f")
462                       (match_operand:SF 2 "register_operand" "f")))]
463   "TARGET_FPU"
465   if (TARGET_V9)
466     return "fcmps\t%0, %1, %2";
467   return "fcmps\t%1, %2";
469   [(set_attr "type" "fpcmp")])
471 (define_insn "*cmpdf_fp"
472   [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
473         (compare:CCFP (match_operand:DF 1 "register_operand" "e")
474                       (match_operand:DF 2 "register_operand" "e")))]
475   "TARGET_FPU"
477   if (TARGET_V9)
478     return "fcmpd\t%0, %1, %2";
479   return "fcmpd\t%1, %2";
481   [(set_attr "type" "fpcmp")
482    (set_attr "fptype" "double")])
484 (define_insn "*cmptf_fp"
485   [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
486         (compare:CCFP (match_operand:TF 1 "register_operand" "e")
487                       (match_operand:TF 2 "register_operand" "e")))]
488   "TARGET_FPU && TARGET_HARD_QUAD"
490   if (TARGET_V9)
491     return "fcmpq\t%0, %1, %2";
492   return "fcmpq\t%1, %2";
494   [(set_attr "type" "fpcmp")])
496 ;; Next come the scc insns.  For seq, sne, sgeu, and sltu, we can do this
497 ;; without jumps using the addx/subx instructions.  For seq/sne on v9 we use
498 ;; the same code as v8 (the addx/subx method has more applications).  The
499 ;; exception to this is "reg != 0" which can be done in one instruction on v9
500 ;; (so we do it).  For the rest, on v9 we use conditional moves; on v8, we do
501 ;; branches.
503 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
504 ;; generate addcc/subcc instructions.
506 (define_expand "seqsi_special"
507   [(set (match_dup 3)
508         (xor:SI (match_operand:SI 1 "register_operand" "")
509                 (match_operand:SI 2 "register_operand" "")))
510    (parallel [(set (match_operand:SI 0 "register_operand" "")
511                    (eq:SI (match_dup 3) (const_int 0)))
512               (clobber (reg:CC 100))])]
513   ""
514   { operands[3] = gen_reg_rtx (SImode); })
516 (define_expand "seqdi_special"
517   [(set (match_dup 3)
518         (xor:DI (match_operand:DI 1 "register_operand" "")
519                 (match_operand:DI 2 "register_operand" "")))
520    (set (match_operand:DI 0 "register_operand" "")
521         (eq:DI (match_dup 3) (const_int 0)))]
522   "TARGET_ARCH64"
523   { operands[3] = gen_reg_rtx (DImode); })
525 (define_expand "snesi_special"
526   [(set (match_dup 3)
527         (xor:SI (match_operand:SI 1 "register_operand" "")
528                 (match_operand:SI 2 "register_operand" "")))
529    (parallel [(set (match_operand:SI 0 "register_operand" "")
530                    (ne:SI (match_dup 3) (const_int 0)))
531               (clobber (reg:CC 100))])]
532   ""
533   { operands[3] = gen_reg_rtx (SImode); })
535 (define_expand "snedi_special"
536   [(set (match_dup 3)
537         (xor:DI (match_operand:DI 1 "register_operand" "")
538                 (match_operand:DI 2 "register_operand" "")))
539    (set (match_operand:DI 0 "register_operand" "")
540         (ne:DI (match_dup 3) (const_int 0)))]
541   "TARGET_ARCH64"
542   { operands[3] = gen_reg_rtx (DImode); })
544 (define_expand "seqdi_special_trunc"
545   [(set (match_dup 3)
546         (xor:DI (match_operand:DI 1 "register_operand" "")
547                 (match_operand:DI 2 "register_operand" "")))
548    (set (match_operand:SI 0 "register_operand" "")
549         (eq:SI (match_dup 3) (const_int 0)))]
550   "TARGET_ARCH64"
551   { operands[3] = gen_reg_rtx (DImode); })
553 (define_expand "snedi_special_trunc"
554   [(set (match_dup 3)
555         (xor:DI (match_operand:DI 1 "register_operand" "")
556                 (match_operand:DI 2 "register_operand" "")))
557    (set (match_operand:SI 0 "register_operand" "")
558         (ne:SI (match_dup 3) (const_int 0)))]
559   "TARGET_ARCH64"
560   { operands[3] = gen_reg_rtx (DImode); })
562 (define_expand "seqsi_special_extend"
563   [(set (match_dup 3)
564         (xor:SI (match_operand:SI 1 "register_operand" "")
565                 (match_operand:SI 2 "register_operand" "")))
566    (parallel [(set (match_operand:DI 0 "register_operand" "")
567                    (eq:DI (match_dup 3) (const_int 0)))
568               (clobber (reg:CC 100))])]
569   "TARGET_ARCH64"
570   { operands[3] = gen_reg_rtx (SImode); })
572 (define_expand "snesi_special_extend"
573   [(set (match_dup 3)
574         (xor:SI (match_operand:SI 1 "register_operand" "")
575                 (match_operand:SI 2 "register_operand" "")))
576    (parallel [(set (match_operand:DI 0 "register_operand" "")
577                    (ne:DI (match_dup 3) (const_int 0)))
578               (clobber (reg:CC 100))])]
579   "TARGET_ARCH64"
580   { operands[3] = gen_reg_rtx (SImode); })
582 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
583 ;; However, the code handles both SImode and DImode.
584 (define_expand "seq"
585   [(set (match_operand:SI 0 "int_register_operand" "")
586         (eq:SI (match_dup 1) (const_int 0)))]
587   ""
589   if (GET_MODE (sparc_compare_op0) == SImode)
590     {
591       rtx pat;
593       if (GET_MODE (operands[0]) == SImode)
594         pat = gen_seqsi_special (operands[0], sparc_compare_op0,
595                                  sparc_compare_op1);
596       else if (! TARGET_ARCH64)
597         FAIL;
598       else
599         pat = gen_seqsi_special_extend (operands[0], sparc_compare_op0,
600                                         sparc_compare_op1);
601       emit_insn (pat);
602       DONE;
603     }
604   else if (GET_MODE (sparc_compare_op0) == DImode)
605     {
606       rtx pat;
608       if (! TARGET_ARCH64)
609         FAIL;
610       else if (GET_MODE (operands[0]) == SImode)
611         pat = gen_seqdi_special_trunc (operands[0], sparc_compare_op0,
612                                        sparc_compare_op1);
613       else
614         pat = gen_seqdi_special (operands[0], sparc_compare_op0,
615                                  sparc_compare_op1);
616       emit_insn (pat);
617       DONE;
618     }
619   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
620     {
621       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
622       emit_jump_insn (gen_sne (operands[0]));
623       DONE;
624     }
625   else if (TARGET_V9)
626     {
627       if (gen_v9_scc (EQ, operands))
628         DONE;
629       /* fall through */
630     }
631   FAIL;
634 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
635 ;; However, the code handles both SImode and DImode.
636 (define_expand "sne"
637   [(set (match_operand:SI 0 "int_register_operand" "")
638         (ne:SI (match_dup 1) (const_int 0)))]
639   ""
641   if (GET_MODE (sparc_compare_op0) == SImode)
642     {
643       rtx pat;
645       if (GET_MODE (operands[0]) == SImode)
646         pat = gen_snesi_special (operands[0], sparc_compare_op0,
647                                  sparc_compare_op1);
648       else if (! TARGET_ARCH64)
649         FAIL;
650       else
651         pat = gen_snesi_special_extend (operands[0], sparc_compare_op0,
652                                         sparc_compare_op1);
653       emit_insn (pat);
654       DONE;
655     }
656   else if (GET_MODE (sparc_compare_op0) == DImode)
657     {
658       rtx pat;
660       if (! TARGET_ARCH64)
661         FAIL;
662       else if (GET_MODE (operands[0]) == SImode)
663         pat = gen_snedi_special_trunc (operands[0], sparc_compare_op0,
664                                        sparc_compare_op1);
665       else
666         pat = gen_snedi_special (operands[0], sparc_compare_op0,
667                                  sparc_compare_op1);
668       emit_insn (pat);
669       DONE;
670     }
671   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
672     {
673       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
674       emit_jump_insn (gen_sne (operands[0]));
675       DONE;
676     }
677   else if (TARGET_V9)
678     {
679       if (gen_v9_scc (NE, operands))
680         DONE;
681       /* fall through */
682     }
683   FAIL;
686 (define_expand "sgt"
687   [(set (match_operand:SI 0 "int_register_operand" "")
688         (gt:SI (match_dup 1) (const_int 0)))]
689   ""
691   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
692     {
693       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
694       emit_jump_insn (gen_sne (operands[0]));
695       DONE;
696     }
697   else if (TARGET_V9)
698     {
699       if (gen_v9_scc (GT, operands))
700         DONE;
701       /* fall through */
702     }
703   FAIL;
706 (define_expand "slt"
707   [(set (match_operand:SI 0 "int_register_operand" "")
708         (lt:SI (match_dup 1) (const_int 0)))]
709   ""
711   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
712     {
713       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
714       emit_jump_insn (gen_sne (operands[0]));
715       DONE;
716     }
717   else if (TARGET_V9)
718     {
719       if (gen_v9_scc (LT, operands))
720         DONE;
721       /* fall through */
722     }
723   FAIL;
726 (define_expand "sge"
727   [(set (match_operand:SI 0 "int_register_operand" "")
728         (ge:SI (match_dup 1) (const_int 0)))]
729   ""
731   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
732     {
733       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
734       emit_jump_insn (gen_sne (operands[0]));
735       DONE;
736     }
737   else if (TARGET_V9)
738     {
739       if (gen_v9_scc (GE, operands))
740         DONE;
741       /* fall through */
742     }
743   FAIL;
746 (define_expand "sle"
747   [(set (match_operand:SI 0 "int_register_operand" "")
748         (le:SI (match_dup 1) (const_int 0)))]
749   ""
751   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
752     {
753       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
754       emit_jump_insn (gen_sne (operands[0]));
755       DONE;
756     }
757   else if (TARGET_V9)
758     {
759       if (gen_v9_scc (LE, operands))
760         DONE;
761       /* fall through */
762     }
763   FAIL;
766 (define_expand "sgtu"
767   [(set (match_operand:SI 0 "int_register_operand" "")
768         (gtu:SI (match_dup 1) (const_int 0)))]
769   ""
771   if (! TARGET_V9)
772     {
773       rtx tem, pat;
775       /* We can do ltu easily, so if both operands are registers, swap them and
776          do a LTU.  */
777       if ((GET_CODE (sparc_compare_op0) == REG
778            || GET_CODE (sparc_compare_op0) == SUBREG)
779           && (GET_CODE (sparc_compare_op1) == REG
780               || GET_CODE (sparc_compare_op1) == SUBREG))
781         {
782           tem = sparc_compare_op0;
783           sparc_compare_op0 = sparc_compare_op1;
784           sparc_compare_op1 = tem;
785           pat = gen_sltu (operands[0]);
786           if (pat == NULL_RTX)
787             FAIL;
788           emit_insn (pat);
789           DONE;
790         }
791     }
792   else
793     {
794       if (gen_v9_scc (GTU, operands))
795         DONE;
796     }
797   FAIL;
800 (define_expand "sltu"
801   [(set (match_operand:SI 0 "int_register_operand" "")
802         (ltu:SI (match_dup 1) (const_int 0)))]
803   ""
805   if (TARGET_V9)
806     {
807       if (gen_v9_scc (LTU, operands))
808         DONE;
809     }
810   operands[1] = gen_compare_reg (LTU);
813 (define_expand "sgeu"
814   [(set (match_operand:SI 0 "int_register_operand" "")
815         (geu:SI (match_dup 1) (const_int 0)))]
816   ""
818   if (TARGET_V9)
819     {
820       if (gen_v9_scc (GEU, operands))
821         DONE;
822     }
823   operands[1] = gen_compare_reg (GEU);
826 (define_expand "sleu"
827   [(set (match_operand:SI 0 "int_register_operand" "")
828         (leu:SI (match_dup 1) (const_int 0)))]
829   ""
831   if (! TARGET_V9)
832     {
833       rtx tem, pat;
835       /* We can do geu easily, so if both operands are registers, swap them and
836          do a GEU.  */
837       if ((GET_CODE (sparc_compare_op0) == REG
838            || GET_CODE (sparc_compare_op0) == SUBREG)
839           && (GET_CODE (sparc_compare_op1) == REG
840               || GET_CODE (sparc_compare_op1) == SUBREG))
841         {
842           tem = sparc_compare_op0;
843           sparc_compare_op0 = sparc_compare_op1;
844           sparc_compare_op1 = tem;
845           pat = gen_sgeu (operands[0]);
846           if (pat == NULL_RTX)
847             FAIL;
848           emit_insn (pat);
849           DONE;
850         }
851     }
852   else
853     {
854       if (gen_v9_scc (LEU, operands))
855         DONE;
856     }
857   FAIL;
860 ;; Now the DEFINE_INSNs for the scc cases.
862 ;; The SEQ and SNE patterns are special because they can be done
863 ;; without any branching and do not involve a COMPARE.  We want
864 ;; them to always use the splits below so the results can be
865 ;; scheduled.
867 (define_insn_and_split "*snesi_zero"
868   [(set (match_operand:SI 0 "register_operand" "=r")
869         (ne:SI (match_operand:SI 1 "register_operand" "r")
870                (const_int 0)))
871    (clobber (reg:CC 100))]
872   ""
873   "#"
874   ""
875   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
876                                            (const_int 0)))
877    (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))]
878   ""
879   [(set_attr "length" "2")])
881 (define_insn_and_split "*neg_snesi_zero"
882   [(set (match_operand:SI 0 "register_operand" "=r")
883         (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
884                        (const_int 0))))
885    (clobber (reg:CC 100))]
886   ""
887   "#"
888   ""
889   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
890                                            (const_int 0)))
891    (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
892   ""
893   [(set_attr "length" "2")])
895 (define_insn_and_split "*snesi_zero_extend"
896   [(set (match_operand:DI 0 "register_operand" "=r")
897         (ne:DI (match_operand:SI 1 "register_operand" "r")
898                (const_int 0)))
899    (clobber (reg:CC 100))]
900   "TARGET_ARCH64"
901   "#"
902   "&& 1"
903   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
904                                                      (match_dup 1))
905                                            (const_int 0)))
906    (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
907                                                         (const_int 0))
908                                                (ltu:SI (reg:CC_NOOV 100)
909                                                        (const_int 0)))))]
910   ""
911   [(set_attr "length" "2")])
913 (define_insn_and_split "*snedi_zero"
914   [(set (match_operand:DI 0 "register_operand" "=&r")
915         (ne:DI (match_operand:DI 1 "register_operand" "r")
916                (const_int 0)))]
917   "TARGET_ARCH64"
918   "#"
919   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
920   [(set (match_dup 0) (const_int 0))
921    (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
922                                               (const_int 0))
923                                        (const_int 1)
924                                        (match_dup 0)))]
925   ""
926   [(set_attr "length" "2")])
928 (define_insn_and_split "*neg_snedi_zero"
929   [(set (match_operand:DI 0 "register_operand" "=&r")
930         (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
931                        (const_int 0))))]
932   "TARGET_ARCH64"
933   "#"
934   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
935   [(set (match_dup 0) (const_int 0))
936    (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
937                                               (const_int 0))
938                                        (const_int -1)
939                                        (match_dup 0)))]
940   ""
941   [(set_attr "length" "2")])
943 (define_insn_and_split "*snedi_zero_trunc"
944   [(set (match_operand:SI 0 "register_operand" "=&r")
945         (ne:SI (match_operand:DI 1 "register_operand" "r")
946                (const_int 0)))]
947   "TARGET_ARCH64"
948   "#"
949   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
950   [(set (match_dup 0) (const_int 0))
951    (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
952                                               (const_int 0))
953                                        (const_int 1)
954                                        (match_dup 0)))]
955   ""
956   [(set_attr "length" "2")])
958 (define_insn_and_split "*seqsi_zero"
959   [(set (match_operand:SI 0 "register_operand" "=r")
960         (eq:SI (match_operand:SI 1 "register_operand" "r")
961                (const_int 0)))
962    (clobber (reg:CC 100))]
963   ""
964   "#"
965   ""
966   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
967                                            (const_int 0)))
968    (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))]
969   ""
970   [(set_attr "length" "2")])
972 (define_insn_and_split "*neg_seqsi_zero"
973   [(set (match_operand:SI 0 "register_operand" "=r")
974         (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
975                        (const_int 0))))
976    (clobber (reg:CC 100))]
977   ""
978   "#"
979   ""
980   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
981                                            (const_int 0)))
982    (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
983   ""
984   [(set_attr "length" "2")])
986 (define_insn_and_split "*seqsi_zero_extend"
987   [(set (match_operand:DI 0 "register_operand" "=r")
988         (eq:DI (match_operand:SI 1 "register_operand" "r")
989                (const_int 0)))
990    (clobber (reg:CC 100))]
991   "TARGET_ARCH64"
992   "#"
993   "&& 1"
994   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
995                                                      (match_dup 1))
996                                            (const_int 0)))
997    (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
998                                                           (const_int -1))
999                                                 (ltu:SI (reg:CC_NOOV 100)
1000                                                         (const_int 0)))))]
1001   ""
1002   [(set_attr "length" "2")])
1004 (define_insn_and_split "*seqdi_zero"
1005   [(set (match_operand:DI 0 "register_operand" "=&r")
1006         (eq:DI (match_operand:DI 1 "register_operand" "r")
1007                (const_int 0)))]
1008   "TARGET_ARCH64"
1009   "#"
1010   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1011   [(set (match_dup 0) (const_int 0))
1012    (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1013                                               (const_int 0))
1014                                        (const_int 1)
1015                                        (match_dup 0)))]
1016   ""
1017   [(set_attr "length" "2")])
1019 (define_insn_and_split "*neg_seqdi_zero"
1020   [(set (match_operand:DI 0 "register_operand" "=&r")
1021         (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
1022                        (const_int 0))))]
1023   "TARGET_ARCH64"
1024   "#"
1025   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1026   [(set (match_dup 0) (const_int 0))
1027    (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1028                                               (const_int 0))
1029                                        (const_int -1)
1030                                        (match_dup 0)))]
1031   ""
1032   [(set_attr "length" "2")]) 
1034 (define_insn_and_split "*seqdi_zero_trunc"
1035   [(set (match_operand:SI 0 "register_operand" "=&r")
1036         (eq:SI (match_operand:DI 1 "register_operand" "r")
1037                (const_int 0)))]
1038   "TARGET_ARCH64"
1039   "#"
1040   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1041   [(set (match_dup 0) (const_int 0))
1042    (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
1043                                               (const_int 0))
1044                                        (const_int 1)
1045                                        (match_dup 0)))]
1046   ""
1047   [(set_attr "length" "2")])
1049 ;; We can also do (x + (i == 0)) and related, so put them in.
1050 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1051 ;; versions for v9.
1053 (define_insn_and_split "*x_plus_i_ne_0"
1054   [(set (match_operand:SI 0 "register_operand" "=r")
1055         (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
1056                         (const_int 0))
1057                  (match_operand:SI 2 "register_operand" "r")))
1058    (clobber (reg:CC 100))]
1059   ""
1060   "#"
1061   ""
1062   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1063                                            (const_int 0)))
1064    (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1065                                (match_dup 2)))]
1066   ""
1067   [(set_attr "length" "2")])
1069 (define_insn_and_split "*x_minus_i_ne_0"
1070   [(set (match_operand:SI 0 "register_operand" "=r")
1071         (minus:SI (match_operand:SI 2 "register_operand" "r")
1072                   (ne:SI (match_operand:SI 1 "register_operand" "r")
1073                          (const_int 0))))
1074    (clobber (reg:CC 100))]
1075   ""
1076   "#"
1077   ""
1078   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1079                                            (const_int 0)))
1080    (set (match_dup 0) (minus:SI (match_dup 2)
1081                                 (ltu:SI (reg:CC 100) (const_int 0))))]
1082   ""
1083   [(set_attr "length" "2")])
1085 (define_insn_and_split "*x_plus_i_eq_0"
1086   [(set (match_operand:SI 0 "register_operand" "=r")
1087         (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1088                         (const_int 0))
1089                  (match_operand:SI 2 "register_operand" "r")))
1090    (clobber (reg:CC 100))]
1091   ""
1092   "#"
1093   ""
1094   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1095                                            (const_int 0)))
1096    (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1097                                (match_dup 2)))]
1098   ""
1099   [(set_attr "length" "2")])
1101 (define_insn_and_split "*x_minus_i_eq_0"
1102   [(set (match_operand:SI 0 "register_operand" "=r")
1103         (minus:SI (match_operand:SI 2 "register_operand" "r")
1104                   (eq:SI (match_operand:SI 1 "register_operand" "r")
1105                          (const_int 0))))
1106    (clobber (reg:CC 100))]
1107   ""
1108   "#"
1109   ""
1110   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1111                                            (const_int 0)))
1112    (set (match_dup 0) (minus:SI (match_dup 2)
1113                                 (geu:SI (reg:CC 100) (const_int 0))))]
1114   ""
1115   [(set_attr "length" "2")])
1117 ;; We can also do GEU and LTU directly, but these operate after a compare.
1118 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1119 ;; versions for v9.
1121 (define_insn "*sltu_insn"
1122   [(set (match_operand:SI 0 "register_operand" "=r")
1123         (ltu:SI (reg:CC 100) (const_int 0)))]
1124   ""
1125   "addx\t%%g0, 0, %0"
1126   [(set_attr "type" "ialuX")])
1128 (define_insn "*neg_sltu_insn"
1129   [(set (match_operand:SI 0 "register_operand" "=r")
1130         (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1131   ""
1132   "subx\t%%g0, 0, %0"
1133   [(set_attr "type" "ialuX")])
1135 ;; ??? Combine should canonicalize these next two to the same pattern.
1136 (define_insn "*neg_sltu_minus_x"
1137   [(set (match_operand:SI 0 "register_operand" "=r")
1138         (minus:SI (neg:SI (ltu:SI (reg:CC 100) (const_int 0)))
1139                   (match_operand:SI 1 "arith_operand" "rI")))]
1140   ""
1141   "subx\t%%g0, %1, %0"
1142   [(set_attr "type" "ialuX")])
1144 (define_insn "*neg_sltu_plus_x"
1145   [(set (match_operand:SI 0 "register_operand" "=r")
1146         (neg:SI (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1147                          (match_operand:SI 1 "arith_operand" "rI"))))]
1148   ""
1149   "subx\t%%g0, %1, %0"
1150   [(set_attr "type" "ialuX")])
1152 (define_insn "*sgeu_insn"
1153   [(set (match_operand:SI 0 "register_operand" "=r")
1154         (geu:SI (reg:CC 100) (const_int 0)))]
1155   ""
1156   "subx\t%%g0, -1, %0"
1157   [(set_attr "type" "ialuX")])
1159 (define_insn "*neg_sgeu_insn"
1160   [(set (match_operand:SI 0 "register_operand" "=r")
1161         (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1162   ""
1163   "addx\t%%g0, -1, %0"
1164   [(set_attr "type" "ialuX")])
1166 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
1167 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1168 ;; versions for v9.
1170 (define_insn "*sltu_plus_x"
1171   [(set (match_operand:SI 0 "register_operand" "=r")
1172         (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1173                  (match_operand:SI 1 "arith_operand" "rI")))]
1174   ""
1175   "addx\t%%g0, %1, %0"
1176   [(set_attr "type" "ialuX")])
1178 (define_insn "*sltu_plus_x_plus_y"
1179   [(set (match_operand:SI 0 "register_operand" "=r")
1180         (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1181                  (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1182                           (match_operand:SI 2 "arith_operand" "rI"))))]
1183   ""
1184   "addx\t%1, %2, %0"
1185   [(set_attr "type" "ialuX")])
1187 (define_insn "*x_minus_sltu"
1188   [(set (match_operand:SI 0 "register_operand" "=r")
1189         (minus:SI (match_operand:SI 1 "register_operand" "r")
1190                   (ltu:SI (reg:CC 100) (const_int 0))))]
1191   ""
1192   "subx\t%1, 0, %0"
1193   [(set_attr "type" "ialuX")])
1195 ;; ??? Combine should canonicalize these next two to the same pattern.
1196 (define_insn "*x_minus_y_minus_sltu"
1197   [(set (match_operand:SI 0 "register_operand" "=r")
1198         (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
1199                             (match_operand:SI 2 "arith_operand" "rI"))
1200                   (ltu:SI (reg:CC 100) (const_int 0))))]
1201   ""
1202   "subx\t%r1, %2, %0"
1203   [(set_attr "type" "ialuX")])
1205 (define_insn "*x_minus_sltu_plus_y"
1206   [(set (match_operand:SI 0 "register_operand" "=r")
1207         (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
1208                   (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1209                            (match_operand:SI 2 "arith_operand" "rI"))))]
1210   ""
1211   "subx\t%r1, %2, %0"
1212   [(set_attr "type" "ialuX")])
1214 (define_insn "*sgeu_plus_x"
1215   [(set (match_operand:SI 0 "register_operand" "=r")
1216         (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1217                  (match_operand:SI 1 "register_operand" "r")))]
1218   ""
1219   "subx\t%1, -1, %0"
1220   [(set_attr "type" "ialuX")])
1222 (define_insn "*x_minus_sgeu"
1223   [(set (match_operand:SI 0 "register_operand" "=r")
1224         (minus:SI (match_operand:SI 1 "register_operand" "r")
1225                   (geu:SI (reg:CC 100) (const_int 0))))]
1226   ""
1227   "addx\t%1, -1, %0"
1228   [(set_attr "type" "ialuX")])
1230 (define_split
1231   [(set (match_operand:SI 0 "register_operand" "")
1232         (match_operator:SI 2 "noov_compare_operator"
1233                            [(match_operand 1 "icc_or_fcc_register_operand" "")
1234                             (const_int 0)]))]
1235   "TARGET_V9
1236    && REGNO (operands[1]) == SPARC_ICC_REG
1237    && (GET_MODE (operands[1]) == CCXmode
1238        /* 32 bit LTU/GEU are better implemented using addx/subx.  */
1239        || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1240   [(set (match_dup 0) (const_int 0))
1241    (set (match_dup 0)
1242         (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1243                          (const_int 1)
1244                          (match_dup 0)))]
1245   "")
1248 ;; These control RTL generation for conditional jump insns
1250 ;; The quad-word fp compare library routines all return nonzero to indicate
1251 ;; true, which is different from the equivalent libgcc routines, so we must
1252 ;; handle them specially here.
1254 (define_expand "beq"
1255   [(set (pc)
1256         (if_then_else (eq (match_dup 1) (const_int 0))
1257                       (label_ref (match_operand 0 "" ""))
1258                       (pc)))]
1259   ""
1261   if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1262       && GET_CODE (sparc_compare_op0) == REG
1263       && GET_MODE (sparc_compare_op0) == DImode)
1264     {
1265       emit_v9_brxx_insn (EQ, sparc_compare_op0, operands[0]);
1266       DONE;
1267     }
1268   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1269     {
1270       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
1271       emit_jump_insn (gen_bne (operands[0]));
1272       DONE;
1273     }
1274   operands[1] = gen_compare_reg (EQ);
1277 (define_expand "bne"
1278   [(set (pc)
1279         (if_then_else (ne (match_dup 1) (const_int 0))
1280                       (label_ref (match_operand 0 "" ""))
1281                       (pc)))]
1282   ""
1284   if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1285       && GET_CODE (sparc_compare_op0) == REG
1286       && GET_MODE (sparc_compare_op0) == DImode)
1287     {
1288       emit_v9_brxx_insn (NE, sparc_compare_op0, operands[0]);
1289       DONE;
1290     }
1291   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1292     {
1293       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
1294       emit_jump_insn (gen_bne (operands[0]));
1295       DONE;
1296     }
1297   operands[1] = gen_compare_reg (NE);
1300 (define_expand "bgt"
1301   [(set (pc)
1302         (if_then_else (gt (match_dup 1) (const_int 0))
1303                       (label_ref (match_operand 0 "" ""))
1304                       (pc)))]
1305   ""
1307   if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1308       && GET_CODE (sparc_compare_op0) == REG
1309       && GET_MODE (sparc_compare_op0) == DImode)
1310     {
1311       emit_v9_brxx_insn (GT, sparc_compare_op0, operands[0]);
1312       DONE;
1313     }
1314   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1315     {
1316       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
1317       emit_jump_insn (gen_bne (operands[0]));
1318       DONE;
1319     }
1320   operands[1] = gen_compare_reg (GT);
1323 (define_expand "bgtu"
1324   [(set (pc)
1325         (if_then_else (gtu (match_dup 1) (const_int 0))
1326                       (label_ref (match_operand 0 "" ""))
1327                       (pc)))]
1328   ""
1330   operands[1] = gen_compare_reg (GTU);
1333 (define_expand "blt"
1334   [(set (pc)
1335         (if_then_else (lt (match_dup 1) (const_int 0))
1336                       (label_ref (match_operand 0 "" ""))
1337                       (pc)))]
1338   ""
1340   if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1341       && GET_CODE (sparc_compare_op0) == REG
1342       && GET_MODE (sparc_compare_op0) == DImode)
1343     {
1344       emit_v9_brxx_insn (LT, sparc_compare_op0, operands[0]);
1345       DONE;
1346     }
1347   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1348     {
1349       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
1350       emit_jump_insn (gen_bne (operands[0]));
1351       DONE;
1352     }
1353   operands[1] = gen_compare_reg (LT);
1356 (define_expand "bltu"
1357   [(set (pc)
1358         (if_then_else (ltu (match_dup 1) (const_int 0))
1359                       (label_ref (match_operand 0 "" ""))
1360                       (pc)))]
1361   ""
1363   operands[1] = gen_compare_reg (LTU);
1366 (define_expand "bge"
1367   [(set (pc)
1368         (if_then_else (ge (match_dup 1) (const_int 0))
1369                       (label_ref (match_operand 0 "" ""))
1370                       (pc)))]
1371   ""
1373   if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1374       && GET_CODE (sparc_compare_op0) == REG
1375       && GET_MODE (sparc_compare_op0) == DImode)
1376     {
1377       emit_v9_brxx_insn (GE, sparc_compare_op0, operands[0]);
1378       DONE;
1379     }
1380   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1381     {
1382       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
1383       emit_jump_insn (gen_bne (operands[0]));
1384       DONE;
1385     }
1386   operands[1] = gen_compare_reg (GE);
1389 (define_expand "bgeu"
1390   [(set (pc)
1391         (if_then_else (geu (match_dup 1) (const_int 0))
1392                       (label_ref (match_operand 0 "" ""))
1393                       (pc)))]
1394   ""
1396   operands[1] = gen_compare_reg (GEU);
1399 (define_expand "ble"
1400   [(set (pc)
1401         (if_then_else (le (match_dup 1) (const_int 0))
1402                       (label_ref (match_operand 0 "" ""))
1403                       (pc)))]
1404   ""
1406   if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1407       && GET_CODE (sparc_compare_op0) == REG
1408       && GET_MODE (sparc_compare_op0) == DImode)
1409     {
1410       emit_v9_brxx_insn (LE, sparc_compare_op0, operands[0]);
1411       DONE;
1412     }
1413   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1414     {
1415       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
1416       emit_jump_insn (gen_bne (operands[0]));
1417       DONE;
1418     }
1419   operands[1] = gen_compare_reg (LE);
1422 (define_expand "bleu"
1423   [(set (pc)
1424         (if_then_else (leu (match_dup 1) (const_int 0))
1425                       (label_ref (match_operand 0 "" ""))
1426                       (pc)))]
1427   ""
1429   operands[1] = gen_compare_reg (LEU);
1432 (define_expand "bunordered"
1433   [(set (pc)
1434         (if_then_else (unordered (match_dup 1) (const_int 0))
1435                       (label_ref (match_operand 0 "" ""))
1436                       (pc)))]
1437   ""
1439   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1440     {
1441       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1,
1442                                 UNORDERED);
1443       emit_jump_insn (gen_beq (operands[0]));
1444       DONE;
1445     }
1446   operands[1] = gen_compare_reg (UNORDERED);
1449 (define_expand "bordered"
1450   [(set (pc)
1451         (if_then_else (ordered (match_dup 1) (const_int 0))
1452                       (label_ref (match_operand 0 "" ""))
1453                       (pc)))]
1454   ""
1456   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1457     {
1458       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, ORDERED);
1459       emit_jump_insn (gen_bne (operands[0]));
1460       DONE;
1461     }
1462   operands[1] = gen_compare_reg (ORDERED);
1465 (define_expand "bungt"
1466   [(set (pc)
1467         (if_then_else (ungt (match_dup 1) (const_int 0))
1468                       (label_ref (match_operand 0 "" ""))
1469                       (pc)))]
1470   ""
1472   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1473     {
1474       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGT);
1475       emit_jump_insn (gen_bgt (operands[0]));
1476       DONE;
1477     }
1478   operands[1] = gen_compare_reg (UNGT);
1481 (define_expand "bunlt"
1482   [(set (pc)
1483         (if_then_else (unlt (match_dup 1) (const_int 0))
1484                       (label_ref (match_operand 0 "" ""))
1485                       (pc)))]
1486   ""
1488   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1489     {
1490       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLT);
1491       emit_jump_insn (gen_bne (operands[0]));
1492       DONE;
1493     }
1494   operands[1] = gen_compare_reg (UNLT);
1497 (define_expand "buneq"
1498   [(set (pc)
1499         (if_then_else (uneq (match_dup 1) (const_int 0))
1500                       (label_ref (match_operand 0 "" ""))
1501                       (pc)))]
1502   ""
1504   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1505     {
1506       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNEQ);
1507       emit_jump_insn (gen_beq (operands[0]));
1508       DONE;
1509     }
1510   operands[1] = gen_compare_reg (UNEQ);
1513 (define_expand "bunge"
1514   [(set (pc)
1515         (if_then_else (unge (match_dup 1) (const_int 0))
1516                       (label_ref (match_operand 0 "" ""))
1517                       (pc)))]
1518   ""
1520   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1521     {
1522       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGE);
1523       emit_jump_insn (gen_bne (operands[0]));
1524       DONE;
1525     }
1526   operands[1] = gen_compare_reg (UNGE);
1529 (define_expand "bunle"
1530   [(set (pc)
1531         (if_then_else (unle (match_dup 1) (const_int 0))
1532                       (label_ref (match_operand 0 "" ""))
1533                       (pc)))]
1534   ""
1536   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1537     {
1538       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLE);
1539       emit_jump_insn (gen_bne (operands[0]));
1540       DONE;
1541     }
1542   operands[1] = gen_compare_reg (UNLE);
1545 (define_expand "bltgt"
1546   [(set (pc)
1547         (if_then_else (ltgt (match_dup 1) (const_int 0))
1548                       (label_ref (match_operand 0 "" ""))
1549                       (pc)))]
1550   ""
1552   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1553     {
1554       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LTGT);
1555       emit_jump_insn (gen_bne (operands[0]));
1556       DONE;
1557     }
1558   operands[1] = gen_compare_reg (LTGT);
1561 ;; Now match both normal and inverted jump.
1563 ;; XXX fpcmp nop braindamage
1564 (define_insn "*normal_branch"
1565   [(set (pc)
1566         (if_then_else (match_operator 0 "noov_compare_operator"
1567                                       [(reg 100) (const_int 0)])
1568                       (label_ref (match_operand 1 "" ""))
1569                       (pc)))]
1570   ""
1572   return output_cbranch (operands[0], operands[1], 1, 0,
1573                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1574                          insn);
1576   [(set_attr "type" "branch")
1577    (set_attr "branch_type" "icc")])
1579 ;; XXX fpcmp nop braindamage
1580 (define_insn "*inverted_branch"
1581   [(set (pc)
1582         (if_then_else (match_operator 0 "noov_compare_operator"
1583                                       [(reg 100) (const_int 0)])
1584                       (pc)
1585                       (label_ref (match_operand 1 "" ""))))]
1586   ""
1588   return output_cbranch (operands[0], operands[1], 1, 1,
1589                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1590                          insn);
1592   [(set_attr "type" "branch")
1593    (set_attr "branch_type" "icc")])
1595 ;; XXX fpcmp nop braindamage
1596 (define_insn "*normal_fp_branch"
1597   [(set (pc)
1598         (if_then_else (match_operator 1 "comparison_operator"
1599                                       [(match_operand:CCFP 0 "fcc_register_operand" "c")
1600                                        (const_int 0)])
1601                       (label_ref (match_operand 2 "" ""))
1602                       (pc)))]
1603   ""
1605   return output_cbranch (operands[1], operands[2], 2, 0,
1606                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1607                          insn);
1609   [(set_attr "type" "branch")
1610    (set_attr "branch_type" "fcc")])
1612 ;; XXX fpcmp nop braindamage
1613 (define_insn "*inverted_fp_branch"
1614   [(set (pc)
1615         (if_then_else (match_operator 1 "comparison_operator"
1616                                       [(match_operand:CCFP 0 "fcc_register_operand" "c")
1617                                        (const_int 0)])
1618                       (pc)
1619                       (label_ref (match_operand 2 "" ""))))]
1620   ""
1622   return output_cbranch (operands[1], operands[2], 2, 1,
1623                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1624                          insn);
1626   [(set_attr "type" "branch")
1627    (set_attr "branch_type" "fcc")])
1629 ;; XXX fpcmp nop braindamage
1630 (define_insn "*normal_fpe_branch"
1631   [(set (pc)
1632         (if_then_else (match_operator 1 "comparison_operator"
1633                                       [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1634                                        (const_int 0)])
1635                       (label_ref (match_operand 2 "" ""))
1636                       (pc)))]
1637   ""
1639   return output_cbranch (operands[1], operands[2], 2, 0,
1640                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1641                          insn);
1643   [(set_attr "type" "branch")
1644    (set_attr "branch_type" "fcc")])
1646 ;; XXX fpcmp nop braindamage
1647 (define_insn "*inverted_fpe_branch"
1648   [(set (pc)
1649         (if_then_else (match_operator 1 "comparison_operator"
1650                                       [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1651                                        (const_int 0)])
1652                       (pc)
1653                       (label_ref (match_operand 2 "" ""))))]
1654   ""
1656   return output_cbranch (operands[1], operands[2], 2, 1,
1657                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1658                          insn);
1660   [(set_attr "type" "branch")
1661    (set_attr "branch_type" "fcc")])
1663 ;; SPARC V9-specific jump insns.  None of these are guaranteed to be
1664 ;; in the architecture.
1666 ;; There are no 32 bit brreg insns.
1668 ;; XXX
1669 (define_insn "*normal_int_branch_sp64"
1670   [(set (pc)
1671         (if_then_else (match_operator 0 "v9_register_compare_operator"
1672                                       [(match_operand:DI 1 "register_operand" "r")
1673                                        (const_int 0)])
1674                       (label_ref (match_operand 2 "" ""))
1675                       (pc)))]
1676   "TARGET_ARCH64"
1678   return output_v9branch (operands[0], operands[2], 1, 2, 0,
1679                           final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1680                           insn);
1682   [(set_attr "type" "branch")
1683    (set_attr "branch_type" "reg")])
1685 ;; XXX
1686 (define_insn "*inverted_int_branch_sp64"
1687   [(set (pc)
1688         (if_then_else (match_operator 0 "v9_register_compare_operator"
1689                                       [(match_operand:DI 1 "register_operand" "r")
1690                                        (const_int 0)])
1691                       (pc)
1692                       (label_ref (match_operand 2 "" ""))))]
1693   "TARGET_ARCH64"
1695   return output_v9branch (operands[0], operands[2], 1, 2, 1,
1696                           final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1697                           insn);
1699   [(set_attr "type" "branch")
1700    (set_attr "branch_type" "reg")])
1703 (define_mode_macro P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1705 ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic
1706 ;; value subject to a PC-relative relocation.  Operand 2 is a helper function
1707 ;; that adds the PC value at the call point to operand 0.
1709 (define_insn "load_pcrel_sym<P:mode>"
1710   [(set (match_operand:P 0 "register_operand" "=r")
1711         (unspec:P [(match_operand:P 1 "symbolic_operand" "")
1712                    (match_operand:P 2 "call_address_operand" "")] UNSPEC_LOAD_PCREL_SYM))
1713    (clobber (reg:P 15))]
1714   ""
1716   if (flag_delayed_branch)
1717     return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0";
1718   else
1719     return "sethi\t%%hi(%a1-8), %0\n\tadd\t%0, %%lo(%a1-4), %0\n\tcall\t%a2\n\t nop";
1721   [(set (attr "type") (const_string "multi"))
1722    (set (attr "length")
1723         (if_then_else (eq_attr "delayed_branch" "true")
1724                       (const_int 3)
1725                       (const_int 4)))])
1728 ;; Integer move instructions
1730 (define_expand "movqi"
1731   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1732         (match_operand:QI 1 "general_operand" ""))]
1733   ""
1735   if (sparc_expand_move (QImode, operands))
1736     DONE;
1739 (define_insn "*movqi_insn"
1740   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1741         (match_operand:QI 1 "input_operand"   "rI,m,rJ"))]
1742   "(register_operand (operands[0], QImode)
1743     || register_or_zero_operand (operands[1], QImode))"
1744   "@
1745    mov\t%1, %0
1746    ldub\t%1, %0
1747    stb\t%r1, %0"
1748   [(set_attr "type" "*,load,store")
1749    (set_attr "us3load_type" "*,3cycle,*")])
1751 (define_expand "movhi"
1752   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1753         (match_operand:HI 1 "general_operand" ""))]
1754   ""
1756   if (sparc_expand_move (HImode, operands))
1757     DONE;
1760 (define_insn "*movhi_insn"
1761   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1762         (match_operand:HI 1 "input_operand"   "rI,K,m,rJ"))]
1763   "(register_operand (operands[0], HImode)
1764     || register_or_zero_operand (operands[1], HImode))"
1765   "@
1766    mov\t%1, %0
1767    sethi\t%%hi(%a1), %0
1768    lduh\t%1, %0
1769    sth\t%r1, %0"
1770   [(set_attr "type" "*,*,load,store")
1771    (set_attr "us3load_type" "*,*,3cycle,*")])
1773 ;; We always work with constants here.
1774 (define_insn "*movhi_lo_sum"
1775   [(set (match_operand:HI 0 "register_operand" "=r")
1776         (ior:HI (match_operand:HI 1 "register_operand" "%r")
1777                 (match_operand:HI 2 "small_int_operand" "I")))]
1778   ""
1779   "or\t%1, %2, %0")
1781 (define_expand "movsi"
1782   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1783         (match_operand:SI 1 "general_operand" ""))]
1784   ""
1786   if (sparc_expand_move (SImode, operands))
1787     DONE;
1790 (define_insn "*movsi_insn"
1791   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m,!f,!f,!m,d")
1792         (match_operand:SI 1 "input_operand"   "rI,K,m,rJ,f,m,f,J"))]
1793   "(register_operand (operands[0], SImode)
1794     || register_or_zero_operand (operands[1], SImode))"
1795   "@
1796    mov\t%1, %0
1797    sethi\t%%hi(%a1), %0
1798    ld\t%1, %0
1799    st\t%r1, %0
1800    fmovs\t%1, %0
1801    ld\t%1, %0
1802    st\t%1, %0
1803    fzeros\t%0"
1804   [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga")])
1806 (define_insn "*movsi_lo_sum"
1807   [(set (match_operand:SI 0 "register_operand" "=r")
1808         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1809                    (match_operand:SI 2 "immediate_operand" "in")))]
1810   ""
1811   "or\t%1, %%lo(%a2), %0")
1813 (define_insn "*movsi_high"
1814   [(set (match_operand:SI 0 "register_operand" "=r")
1815         (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1816   ""
1817   "sethi\t%%hi(%a1), %0")
1819 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1820 ;; so that CSE won't optimize the address computation away.
1821 (define_insn "movsi_lo_sum_pic"
1822   [(set (match_operand:SI 0 "register_operand" "=r")
1823         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1824                    (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1825   "flag_pic"
1826   "or\t%1, %%lo(%a2), %0")
1828 (define_insn "movsi_high_pic"
1829   [(set (match_operand:SI 0 "register_operand" "=r")
1830         (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1831   "flag_pic && check_pic (1)"
1832   "sethi\t%%hi(%a1), %0")
1834 (define_expand "movsi_pic_label_ref"
1835   [(set (match_dup 3) (high:SI
1836      (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1837                  (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1838    (set (match_dup 4) (lo_sum:SI (match_dup 3)
1839      (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1840    (set (match_operand:SI 0 "register_operand" "=r")
1841         (minus:SI (match_dup 5) (match_dup 4)))]
1842   "flag_pic"
1844   current_function_uses_pic_offset_table = 1;
1845   operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1846   if (no_new_pseudos)
1847     {
1848       operands[3] = operands[0];
1849       operands[4] = operands[0];
1850     }
1851   else
1852     {
1853       operands[3] = gen_reg_rtx (SImode);
1854       operands[4] = gen_reg_rtx (SImode);
1855     }
1856   operands[5] = pic_offset_table_rtx;
1859 (define_insn "*movsi_high_pic_label_ref"
1860   [(set (match_operand:SI 0 "register_operand" "=r")
1861       (high:SI
1862         (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1863                     (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1864   "flag_pic"
1865   "sethi\t%%hi(%a2-(%a1-.)), %0")
1867 (define_insn "*movsi_lo_sum_pic_label_ref"
1868   [(set (match_operand:SI 0 "register_operand" "=r")
1869       (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1870         (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
1871                     (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1872   "flag_pic"
1873   "or\t%1, %%lo(%a3-(%a2-.)), %0")
1875 (define_expand "movdi"
1876   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1877         (match_operand:DI 1 "general_operand" ""))]
1878   ""
1880   if (sparc_expand_move (DImode, operands))
1881     DONE;
1884 ;; Be careful, fmovd does not exist when !v9.
1885 ;; We match MEM moves directly when we have correct even
1886 ;; numbered registers, but fall into splits otherwise.
1887 ;; The constraint ordering here is really important to
1888 ;; avoid insane problems in reload, especially for patterns
1889 ;; of the form:
1891 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
1892 ;;                       (const_int -5016)))
1893 ;;      (reg:DI 2 %g2))
1896 (define_insn "*movdi_insn_sp32"
1897   [(set (match_operand:DI 0 "nonimmediate_operand"
1898                                 "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
1899         (match_operand:DI 1 "input_operand"
1900                                 " J,U,T,r,o,i,r, f, T, o, f, f"))]
1901   "! TARGET_V9
1902    && (register_operand (operands[0], DImode)
1903        || register_or_zero_operand (operands[1], DImode))"
1904   "@
1905    #
1906    std\t%1, %0
1907    ldd\t%1, %0
1908    #
1909    #
1910    #
1911    #
1912    std\t%1, %0
1913    ldd\t%1, %0
1914    #
1915    #
1916    #"
1917   [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
1918    (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
1920 (define_insn "*movdi_insn_sp32_v9"
1921   [(set (match_operand:DI 0 "nonimmediate_operand"
1922                                         "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?e,?e,?W")
1923         (match_operand:DI 1 "input_operand"
1924                                         " J,J,U,T,r,o,i,r, f, T, o, f, e, W, e"))]
1925   "! TARGET_ARCH64
1926    && TARGET_V9
1927    && (register_operand (operands[0], DImode)
1928        || register_or_zero_operand (operands[1], DImode))"
1929   "@
1930    stx\t%%g0, %0
1931    #
1932    std\t%1, %0
1933    ldd\t%1, %0
1934    #
1935    #
1936    #
1937    #
1938    std\t%1, %0
1939    ldd\t%1, %0
1940    #
1941    #
1942    fmovd\\t%1, %0
1943    ldd\\t%1, %0
1944    std\\t%1, %0"
1945   [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,fpload,fpstore")
1946    (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,*,*")
1947    (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])
1949 (define_insn "*movdi_insn_sp64"
1950   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,m,?e,?e,?W,b")
1951         (match_operand:DI 1 "input_operand"   "rI,N,m,rJ,e,W,e,J"))]
1952   "TARGET_ARCH64
1953    && (register_operand (operands[0], DImode)
1954        || register_or_zero_operand (operands[1], DImode))"
1955   "@
1956    mov\t%1, %0
1957    sethi\t%%hi(%a1), %0
1958    ldx\t%1, %0
1959    stx\t%r1, %0
1960    fmovd\t%1, %0
1961    ldd\t%1, %0
1962    std\t%1, %0
1963    fzero\t%0"
1964   [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga")
1965    (set_attr "fptype" "*,*,*,*,double,*,*,double")])
1967 (define_expand "movdi_pic_label_ref"
1968   [(set (match_dup 3) (high:DI
1969      (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1970                  (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1971    (set (match_dup 4) (lo_sum:DI (match_dup 3)
1972      (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1973    (set (match_operand:DI 0 "register_operand" "=r")
1974         (minus:DI (match_dup 5) (match_dup 4)))]
1975   "TARGET_ARCH64 && flag_pic"
1977   current_function_uses_pic_offset_table = 1;
1978   operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1979   if (no_new_pseudos)
1980     {
1981       operands[3] = operands[0];
1982       operands[4] = operands[0];
1983     }
1984   else
1985     {
1986       operands[3] = gen_reg_rtx (DImode);
1987       operands[4] = gen_reg_rtx (DImode);
1988     }
1989   operands[5] = pic_offset_table_rtx;
1992 (define_insn "*movdi_high_pic_label_ref"
1993   [(set (match_operand:DI 0 "register_operand" "=r")
1994         (high:DI
1995           (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1996                       (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1997   "TARGET_ARCH64 && flag_pic"
1998   "sethi\t%%hi(%a2-(%a1-.)), %0")
2000 (define_insn "*movdi_lo_sum_pic_label_ref"
2001   [(set (match_operand:DI 0 "register_operand" "=r")
2002       (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2003         (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
2004                     (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2005   "TARGET_ARCH64 && flag_pic"
2006   "or\t%1, %%lo(%a3-(%a2-.)), %0")
2008 ;; SPARC-v9 code model support insns.  See sparc_emit_set_symbolic_const64
2009 ;; in sparc.c to see what is going on here... PIC stuff comes first.
2011 (define_insn "movdi_lo_sum_pic"
2012   [(set (match_operand:DI 0 "register_operand" "=r")
2013         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2014                    (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
2015   "TARGET_ARCH64 && flag_pic"
2016   "or\t%1, %%lo(%a2), %0")
2018 (define_insn "movdi_high_pic"
2019   [(set (match_operand:DI 0 "register_operand" "=r")
2020         (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
2021   "TARGET_ARCH64 && flag_pic && check_pic (1)"
2022   "sethi\t%%hi(%a1), %0")
2024 (define_insn "*sethi_di_medlow_embmedany_pic"
2025   [(set (match_operand:DI 0 "register_operand" "=r")
2026         (high:DI (match_operand:DI 1 "medium_pic_operand" "")))]
2027   "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
2028   "sethi\t%%hi(%a1), %0")
2030 (define_insn "*sethi_di_medlow"
2031   [(set (match_operand:DI 0 "register_operand" "=r")
2032         (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
2033   "TARGET_CM_MEDLOW && check_pic (1)"
2034   "sethi\t%%hi(%a1), %0")
2036 (define_insn "*losum_di_medlow"
2037   [(set (match_operand:DI 0 "register_operand" "=r")
2038         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2039                    (match_operand:DI 2 "symbolic_operand" "")))]
2040   "TARGET_CM_MEDLOW"
2041   "or\t%1, %%lo(%a2), %0")
2043 (define_insn "seth44"
2044   [(set (match_operand:DI 0 "register_operand" "=r")
2045         (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
2046   "TARGET_CM_MEDMID"
2047   "sethi\t%%h44(%a1), %0")
2049 (define_insn "setm44"
2050   [(set (match_operand:DI 0 "register_operand" "=r")
2051         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2052                    (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
2053   "TARGET_CM_MEDMID"
2054   "or\t%1, %%m44(%a2), %0")
2056 (define_insn "setl44"
2057   [(set (match_operand:DI 0 "register_operand" "=r")
2058         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2059                    (match_operand:DI 2 "symbolic_operand" "")))]
2060   "TARGET_CM_MEDMID"
2061   "or\t%1, %%l44(%a2), %0")
2063 (define_insn "sethh"
2064   [(set (match_operand:DI 0 "register_operand" "=r")
2065         (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
2066   "TARGET_CM_MEDANY"
2067   "sethi\t%%hh(%a1), %0")
2069 (define_insn "setlm"
2070   [(set (match_operand:DI 0 "register_operand" "=r")
2071         (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
2072   "TARGET_CM_MEDANY"
2073   "sethi\t%%lm(%a1), %0")
2075 (define_insn "sethm"
2076   [(set (match_operand:DI 0 "register_operand" "=r")
2077         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2078                    (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
2079   "TARGET_CM_MEDANY"
2080   "or\t%1, %%hm(%a2), %0")
2082 (define_insn "setlo"
2083   [(set (match_operand:DI 0 "register_operand" "=r")
2084         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2085                    (match_operand:DI 2 "symbolic_operand" "")))]
2086   "TARGET_CM_MEDANY"
2087   "or\t%1, %%lo(%a2), %0")
2089 (define_insn "embmedany_sethi"
2090   [(set (match_operand:DI 0 "register_operand" "=r")
2091         (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
2092   "TARGET_CM_EMBMEDANY && check_pic (1)"
2093   "sethi\t%%hi(%a1), %0")
2095 (define_insn "embmedany_losum"
2096   [(set (match_operand:DI 0 "register_operand" "=r")
2097         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2098                    (match_operand:DI 2 "data_segment_operand" "")))]
2099   "TARGET_CM_EMBMEDANY"
2100   "add\t%1, %%lo(%a2), %0")
2102 (define_insn "embmedany_brsum"
2103   [(set (match_operand:DI 0 "register_operand" "=r")
2104         (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
2105   "TARGET_CM_EMBMEDANY"
2106   "add\t%1, %_, %0")
2108 (define_insn "embmedany_textuhi"
2109   [(set (match_operand:DI 0 "register_operand" "=r")
2110         (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
2111   "TARGET_CM_EMBMEDANY && check_pic (1)"
2112   "sethi\t%%uhi(%a1), %0")
2114 (define_insn "embmedany_texthi"
2115   [(set (match_operand:DI 0 "register_operand" "=r")
2116         (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
2117   "TARGET_CM_EMBMEDANY && check_pic (1)"
2118   "sethi\t%%hi(%a1), %0")
2120 (define_insn "embmedany_textulo"
2121   [(set (match_operand:DI 0 "register_operand" "=r")
2122         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2123                    (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
2124   "TARGET_CM_EMBMEDANY"
2125   "or\t%1, %%ulo(%a2), %0")
2127 (define_insn "embmedany_textlo"
2128   [(set (match_operand:DI 0 "register_operand" "=r")
2129         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2130                    (match_operand:DI 2 "text_segment_operand" "")))]
2131   "TARGET_CM_EMBMEDANY"
2132   "or\t%1, %%lo(%a2), %0")
2134 ;; Now some patterns to help reload out a bit.
2135 (define_expand "reload_indi"
2136   [(parallel [(match_operand:DI 0 "register_operand" "=r")
2137               (match_operand:DI 1 "immediate_operand" "")
2138               (match_operand:TI 2 "register_operand" "=&r")])]
2139   "(TARGET_CM_MEDANY
2140     || TARGET_CM_EMBMEDANY)
2141    && ! flag_pic"
2143   sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2144   DONE;
2147 (define_expand "reload_outdi"
2148   [(parallel [(match_operand:DI 0 "register_operand" "=r")
2149               (match_operand:DI 1 "immediate_operand" "")
2150               (match_operand:TI 2 "register_operand" "=&r")])]
2151   "(TARGET_CM_MEDANY
2152     || TARGET_CM_EMBMEDANY)
2153    && ! flag_pic"
2155   sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2156   DONE;
2159 ;; Split up putting CONSTs and REGs into DI regs when !arch64
2160 (define_split
2161   [(set (match_operand:DI 0 "register_operand" "")
2162         (match_operand:DI 1 "const_int_operand" ""))]
2163   "! TARGET_ARCH64 && reload_completed"
2164   [(clobber (const_int 0))]
2166 #if HOST_BITS_PER_WIDE_INT == 32
2167   emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2168                         (INTVAL (operands[1]) < 0) ?
2169                         constm1_rtx :
2170                         const0_rtx));
2171   emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2172                         operands[1]));
2173 #else
2174   unsigned int low, high;
2176   low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
2177   high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
2178   emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
2180   /* Slick... but this trick loses if this subreg constant part
2181      can be done in one insn.  */
2182   if (low == high
2183       && ! SPARC_SETHI32_P (high)
2184       && ! SPARC_SIMM13_P (high))
2185     emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2186                           gen_highpart (SImode, operands[0])));
2187   else
2188     emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
2189 #endif
2190   DONE;
2193 (define_split
2194   [(set (match_operand:DI 0 "register_operand" "")
2195         (match_operand:DI 1 "const_double_operand" ""))]
2196   "reload_completed
2197    && (! TARGET_V9
2198        || (! TARGET_ARCH64
2199            && ((GET_CODE (operands[0]) == REG
2200                 && REGNO (operands[0]) < 32)
2201                || (GET_CODE (operands[0]) == SUBREG
2202                    && GET_CODE (SUBREG_REG (operands[0])) == REG
2203                    && REGNO (SUBREG_REG (operands[0])) < 32))))"
2204   [(clobber (const_int 0))]
2206   emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2207                         GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
2209   /* Slick... but this trick loses if this subreg constant part
2210      can be done in one insn.  */
2211   if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
2212       && ! SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
2213       && ! SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1])))
2214     {
2215       emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2216                             gen_highpart (SImode, operands[0])));
2217     }
2218   else
2219     {
2220       emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2221                             GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
2222     }
2223   DONE;
2226 (define_split
2227   [(set (match_operand:DI 0 "register_operand" "")
2228         (match_operand:DI 1 "register_operand" ""))]
2229   "reload_completed
2230    && (! TARGET_V9
2231        || (! TARGET_ARCH64
2232            && ((GET_CODE (operands[0]) == REG
2233                 && REGNO (operands[0]) < 32)
2234                || (GET_CODE (operands[0]) == SUBREG
2235                    && GET_CODE (SUBREG_REG (operands[0])) == REG
2236                    && REGNO (SUBREG_REG (operands[0])) < 32))))"
2237   [(clobber (const_int 0))]
2239   rtx set_dest = operands[0];
2240   rtx set_src = operands[1];
2241   rtx dest1, dest2;
2242   rtx src1, src2;
2244   dest1 = gen_highpart (SImode, set_dest);
2245   dest2 = gen_lowpart (SImode, set_dest);
2246   src1 = gen_highpart (SImode, set_src);
2247   src2 = gen_lowpart (SImode, set_src);
2249   /* Now emit using the real source and destination we found, swapping
2250      the order if we detect overlap.  */
2251   if (reg_overlap_mentioned_p (dest1, src2))
2252     {
2253       emit_insn (gen_movsi (dest2, src2));
2254       emit_insn (gen_movsi (dest1, src1));
2255     }
2256   else
2257     {
2258       emit_insn (gen_movsi (dest1, src1));
2259       emit_insn (gen_movsi (dest2, src2));
2260     }
2261   DONE;
2264 ;; Now handle the cases of memory moves from/to non-even
2265 ;; DI mode register pairs.
2266 (define_split
2267   [(set (match_operand:DI 0 "register_operand" "")
2268         (match_operand:DI 1 "memory_operand" ""))]
2269   "(! TARGET_ARCH64
2270     && reload_completed
2271     && sparc_splitdi_legitimate (operands[0], operands[1]))"
2272   [(clobber (const_int 0))]
2274   rtx word0 = adjust_address (operands[1], SImode, 0);
2275   rtx word1 = adjust_address (operands[1], SImode, 4);
2276   rtx high_part = gen_highpart (SImode, operands[0]);
2277   rtx low_part = gen_lowpart (SImode, operands[0]);
2279   if (reg_overlap_mentioned_p (high_part, word1))
2280     {
2281       emit_insn (gen_movsi (low_part, word1));
2282       emit_insn (gen_movsi (high_part, word0));
2283     }
2284   else
2285     {
2286       emit_insn (gen_movsi (high_part, word0));
2287       emit_insn (gen_movsi (low_part, word1));
2288     }
2289   DONE;
2292 (define_split
2293   [(set (match_operand:DI 0 "memory_operand" "")
2294         (match_operand:DI 1 "register_operand" ""))]
2295   "(! TARGET_ARCH64
2296     && reload_completed
2297     && sparc_splitdi_legitimate (operands[1], operands[0]))"
2298   [(clobber (const_int 0))]
2300   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
2301                         gen_highpart (SImode, operands[1])));
2302   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
2303                         gen_lowpart (SImode, operands[1])));
2304   DONE;
2307 (define_split
2308   [(set (match_operand:DI 0 "memory_operand" "")
2309         (match_operand:DI 1 "const_zero_operand" ""))]
2310   "reload_completed
2311    && (! TARGET_V9
2312        || (! TARGET_ARCH64
2313            && ! mem_min_alignment (operands[0], 8)))
2314    && offsettable_memref_p (operands[0])"
2315   [(clobber (const_int 0))]
2317   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
2318   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
2319   DONE;
2323 ;; Floating point and vector move instructions
2325 ;; We don't define V1SI because SI should work just fine.
2326 (define_mode_macro V32 [SF V2HI V4QI])
2328 ;; Yes, you guessed it right, the former movsf expander.
2329 (define_expand "mov<V32:mode>"
2330   [(set (match_operand:V32 0 "nonimmediate_operand" "")
2331         (match_operand:V32 1 "general_operand" ""))]
2332   "<V32:MODE>mode == SFmode || TARGET_VIS"
2334   if (sparc_expand_move (<V32:MODE>mode, operands))
2335     DONE;
2338 (define_insn "*movsf_insn"
2339   [(set (match_operand:V32 0 "nonimmediate_operand" "=d,f,*r,*r,*r,f,*r,m,m")
2340         (match_operand:V32 1 "input_operand"        "GY,f,*rRY,Q,S,m,m,f,*rGY"))]
2341   "TARGET_FPU
2342    && (register_operand (operands[0], <V32:MODE>mode)
2343        || register_or_zero_operand (operands[1], <V32:MODE>mode))"
2345   if (GET_CODE (operands[1]) == CONST_DOUBLE
2346       && (which_alternative == 2
2347           || which_alternative == 3
2348           || which_alternative == 4))
2349     {
2350       REAL_VALUE_TYPE r;
2351       long i;
2353       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2354       REAL_VALUE_TO_TARGET_SINGLE (r, i);
2355       operands[1] = GEN_INT (i);
2356     }
2358   switch (which_alternative)
2359     {
2360     case 0:
2361       return "fzeros\t%0";
2362     case 1:
2363       return "fmovs\t%1, %0";
2364     case 2:
2365       return "mov\t%1, %0";
2366     case 3:
2367       return "sethi\t%%hi(%a1), %0";
2368     case 4:
2369       return "#";
2370     case 5:
2371     case 6:
2372       return "ld\t%1, %0";
2373     case 7:
2374     case 8:
2375       return "st\t%r1, %0";
2376     default:
2377       gcc_unreachable ();
2378     }
2380   [(set_attr "type" "fga,fpmove,*,*,*,fpload,load,fpstore,store")])
2382 ;; Exactly the same as above, except that all `f' cases are deleted.
2383 ;; This is necessary to prevent reload from ever trying to use a `f' reg
2384 ;; when -mno-fpu.
2386 (define_insn "*movsf_insn_no_fpu"
2387   [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,m")
2388         (match_operand:SF 1 "input_operand"    "rR,Q,S,m,rG"))]
2389   "! TARGET_FPU
2390    && (register_operand (operands[0], SFmode)
2391        || register_or_zero_operand (operands[1], SFmode))"
2393   if (GET_CODE (operands[1]) == CONST_DOUBLE
2394       && (which_alternative == 0
2395           || which_alternative == 1
2396           || which_alternative == 2))
2397     {
2398       REAL_VALUE_TYPE r;
2399       long i;
2401       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2402       REAL_VALUE_TO_TARGET_SINGLE (r, i);
2403       operands[1] = GEN_INT (i);
2404     }
2406   switch (which_alternative)
2407     {
2408     case 0:
2409       return "mov\t%1, %0";
2410     case 1:
2411       return "sethi\t%%hi(%a1), %0";
2412     case 2:
2413       return "#";
2414     case 3:
2415       return "ld\t%1, %0";
2416     case 4:
2417       return "st\t%r1, %0";
2418     default:
2419       gcc_unreachable ();
2420     }
2422   [(set_attr "type" "*,*,*,load,store")])
2424 ;; The following 3 patterns build SFmode constants in integer registers.
2426 (define_insn "*movsf_lo_sum"
2427   [(set (match_operand:SF 0 "register_operand" "=r")
2428         (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
2429                    (match_operand:SF 2 "fp_const_high_losum_operand" "S")))]
2430   ""
2432   REAL_VALUE_TYPE r;
2433   long i;
2435   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
2436   REAL_VALUE_TO_TARGET_SINGLE (r, i);
2437   operands[2] = GEN_INT (i);
2438   return "or\t%1, %%lo(%a2), %0";
2441 (define_insn "*movsf_high"
2442   [(set (match_operand:SF 0 "register_operand" "=r")
2443         (high:SF (match_operand:SF 1 "fp_const_high_losum_operand" "S")))]
2444   ""
2446   REAL_VALUE_TYPE r;
2447   long i;
2449   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2450   REAL_VALUE_TO_TARGET_SINGLE (r, i);
2451   operands[1] = GEN_INT (i);
2452   return "sethi\t%%hi(%1), %0";
2455 (define_split
2456   [(set (match_operand:SF 0 "register_operand" "")
2457         (match_operand:SF 1 "fp_const_high_losum_operand" ""))]
2458   "REG_P (operands[0]) && REGNO (operands[0]) < 32"
2459   [(set (match_dup 0) (high:SF (match_dup 1)))
2460    (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
2462 (define_mode_macro V64 [DF V2SI V4HI V8QI])
2464 ;; Yes, you again guessed it right, the former movdf expander.
2465 (define_expand "mov<V64:mode>"
2466   [(set (match_operand:V64 0 "nonimmediate_operand" "")
2467         (match_operand:V64 1 "general_operand" ""))]
2468   "<V64:MODE>mode == DFmode || TARGET_VIS"
2470   if (sparc_expand_move (<V64:MODE>mode, operands))
2471     DONE;
2474 ;; Be careful, fmovd does not exist when !v9.
2475 (define_insn "*movdf_insn_sp32"
2476   [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o")
2477         (match_operand:DF 1 "input_operand"    "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
2478   "TARGET_FPU
2479    && ! TARGET_V9
2480    && (register_operand (operands[0], DFmode)
2481        || register_or_zero_operand (operands[1], DFmode))"
2482   "@
2483   ldd\t%1, %0
2484   std\t%1, %0
2485   ldd\t%1, %0
2486   std\t%1, %0
2487   #
2488   #
2489   #
2490   #
2491   #
2492   #"
2493  [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
2494   (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
2496 (define_insn "*movdf_insn_sp32_no_fpu"
2497   [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
2498         (match_operand:DF 1 "input_operand"    "T,U,G,ro,r"))]
2499   "! TARGET_FPU
2500    && ! TARGET_V9
2501    && (register_operand (operands[0], DFmode)
2502        || register_or_zero_operand (operands[1], DFmode))"
2503   "@
2504   ldd\t%1, %0
2505   std\t%1, %0
2506   #
2507   #
2508   #"
2509   [(set_attr "type" "load,store,*,*,*")
2510    (set_attr "length" "*,*,2,2,2")])
2512 ;; We have available v9 double floats but not 64-bit integer registers.
2513 (define_insn "*movdf_insn_sp32_v9"
2514   [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,T,W,U,T,f,*r,o")
2515         (match_operand:V64 1 "input_operand" "GY,e,W#F,GY,e,T,U,o#F,*roGYF,*rGYf"))]
2516   "TARGET_FPU
2517    && TARGET_V9
2518    && ! TARGET_ARCH64
2519    && (register_operand (operands[0], <V64:MODE>mode)
2520        || register_or_zero_operand (operands[1], <V64:MODE>mode))"
2521   "@
2522   fzero\t%0
2523   fmovd\t%1, %0
2524   ldd\t%1, %0
2525   stx\t%r1, %0
2526   std\t%1, %0
2527   ldd\t%1, %0
2528   std\t%1, %0
2529   #
2530   #
2531   #"
2532   [(set_attr "type" "fga,fpmove,load,store,store,load,store,*,*,*")
2533    (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
2534    (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
2536 (define_insn "*movdf_insn_sp32_v9_no_fpu"
2537   [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
2538         (match_operand:DF 1 "input_operand"    "T,U,G,ro,rG"))]
2539   "! TARGET_FPU
2540    && TARGET_V9
2541    && ! TARGET_ARCH64
2542    && (register_operand (operands[0], DFmode)
2543        || register_or_zero_operand (operands[1], DFmode))"
2544   "@
2545   ldd\t%1, %0
2546   std\t%1, %0
2547   stx\t%r1, %0
2548   #
2549   #"
2550   [(set_attr "type" "load,store,store,*,*")
2551    (set_attr "length" "*,*,*,2,2")])
2553 ;; We have available both v9 double floats and 64-bit integer registers.
2554 (define_insn "*movdf_insn_sp64"
2555   [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,W,*r,*r,m,*r")
2556         (match_operand:V64 1 "input_operand"    "GY,e,W#F,e,*rGY,m,*rGY,F"))]
2557   "TARGET_FPU
2558    && TARGET_ARCH64
2559    && (register_operand (operands[0], <V64:MODE>mode)
2560        || register_or_zero_operand (operands[1], <V64:MODE>mode))"
2561   "@
2562   fzero\t%0
2563   fmovd\t%1, %0
2564   ldd\t%1, %0
2565   std\t%1, %0
2566   mov\t%r1, %0
2567   ldx\t%1, %0
2568   stx\t%r1, %0
2569   #"
2570   [(set_attr "type" "fga,fpmove,load,store,*,load,store,*")
2571    (set_attr "length" "*,*,*,*,*,*,*,2")
2572    (set_attr "fptype" "double,double,*,*,*,*,*,*")])
2574 (define_insn "*movdf_insn_sp64_no_fpu"
2575   [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
2576         (match_operand:DF 1 "input_operand"    "r,m,rG"))]
2577   "! TARGET_FPU
2578    && TARGET_ARCH64
2579    && (register_operand (operands[0], DFmode)
2580        || register_or_zero_operand (operands[1], DFmode))"
2581   "@
2582   mov\t%1, %0
2583   ldx\t%1, %0
2584   stx\t%r1, %0"
2585   [(set_attr "type" "*,load,store")])
2587 ;; This pattern build DFmode constants in integer registers.
2588 (define_split
2589   [(set (match_operand:DF 0 "register_operand" "")
2590         (match_operand:DF 1 "const_double_operand" ""))]
2591   "TARGET_FPU
2592    && (GET_CODE (operands[0]) == REG
2593        && REGNO (operands[0]) < 32)
2594    && ! const_zero_operand(operands[1], DFmode)
2595    && reload_completed"
2596   [(clobber (const_int 0))]
2598   REAL_VALUE_TYPE r;
2599   long l[2];
2601   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2602   REAL_VALUE_TO_TARGET_DOUBLE (r, l);
2603   operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
2605   if (TARGET_ARCH64)
2606     {
2607 #if HOST_BITS_PER_WIDE_INT == 32
2608       gcc_unreachable ();
2609 #else
2610       HOST_WIDE_INT val;
2612       val = ((HOST_WIDE_INT)(unsigned long)l[1] |
2613              ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
2614       emit_insn (gen_movdi (operands[0], gen_int_mode (val, DImode)));
2615 #endif
2616     }
2617   else
2618     {
2619       emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2620                             gen_int_mode (l[0], SImode)));
2622       /* Slick... but this trick loses if this subreg constant part
2623          can be done in one insn.  */
2624       if (l[1] == l[0]
2625           && ! SPARC_SETHI32_P (l[0])
2626           && ! SPARC_SIMM13_P (l[0]))
2627         {
2628           emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2629                                 gen_highpart (SImode, operands[0])));
2630         }
2631       else
2632         {
2633           emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2634                                 gen_int_mode (l[1], SImode)));
2635         }
2636     }
2637   DONE;
2640 ;; Ok, now the splits to handle all the multi insn and
2641 ;; mis-aligned memory address cases.
2642 ;; In these splits please take note that we must be
2643 ;; careful when V9 but not ARCH64 because the integer
2644 ;; register DFmode cases must be handled.
2645 (define_split
2646   [(set (match_operand:V64 0 "register_operand" "")
2647         (match_operand:V64 1 "register_operand" ""))]
2648   "(! TARGET_V9
2649     || (! TARGET_ARCH64
2650         && ((GET_CODE (operands[0]) == REG
2651              && REGNO (operands[0]) < 32)
2652             || (GET_CODE (operands[0]) == SUBREG
2653                 && GET_CODE (SUBREG_REG (operands[0])) == REG
2654                 && REGNO (SUBREG_REG (operands[0])) < 32))))
2655    && reload_completed"
2656   [(clobber (const_int 0))]
2658   rtx set_dest = operands[0];
2659   rtx set_src = operands[1];
2660   rtx dest1, dest2;
2661   rtx src1, src2;
2662   enum machine_mode half_mode;
2664   /* We can be expanded for DFmode or integral vector modes.  */
2665   if (<V64:MODE>mode == DFmode)
2666     half_mode = SFmode;
2667   else
2668     half_mode = SImode;
2669   
2670   dest1 = gen_highpart (half_mode, set_dest);
2671   dest2 = gen_lowpart (half_mode, set_dest);
2672   src1 = gen_highpart (half_mode, set_src);
2673   src2 = gen_lowpart (half_mode, set_src);
2675   /* Now emit using the real source and destination we found, swapping
2676      the order if we detect overlap.  */
2677   if (reg_overlap_mentioned_p (dest1, src2))
2678     {
2679       emit_move_insn_1 (dest2, src2);
2680       emit_move_insn_1 (dest1, src1);
2681     }
2682   else
2683     {
2684       emit_move_insn_1 (dest1, src1);
2685       emit_move_insn_1 (dest2, src2);
2686     }
2687   DONE;
2690 (define_split
2691   [(set (match_operand:V64 0 "register_operand" "")
2692         (match_operand:V64 1 "memory_operand" ""))]
2693   "reload_completed
2694    && ! TARGET_ARCH64
2695    && (((REGNO (operands[0]) % 2) != 0)
2696        || ! mem_min_alignment (operands[1], 8))
2697    && offsettable_memref_p (operands[1])"
2698   [(clobber (const_int 0))]
2700   enum machine_mode half_mode;
2701   rtx word0, word1;
2703   /* We can be expanded for DFmode or integral vector modes.  */
2704   if (<V64:MODE>mode == DFmode)
2705     half_mode = SFmode;
2706   else
2707     half_mode = SImode;
2709   word0 = adjust_address (operands[1], half_mode, 0);
2710   word1 = adjust_address (operands[1], half_mode, 4);
2712   if (reg_overlap_mentioned_p (gen_highpart (half_mode, operands[0]), word1))
2713     {
2714       emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2715       emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2716     }
2717   else
2718     {
2719       emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2720       emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2721     }
2722   DONE;
2725 (define_split
2726   [(set (match_operand:V64 0 "memory_operand" "")
2727         (match_operand:V64 1 "register_operand" ""))]
2728   "reload_completed
2729    && ! TARGET_ARCH64
2730    && (((REGNO (operands[1]) % 2) != 0)
2731        || ! mem_min_alignment (operands[0], 8))
2732    && offsettable_memref_p (operands[0])"
2733   [(clobber (const_int 0))]
2735   enum machine_mode half_mode;
2736   rtx word0, word1;
2738   /* We can be expanded for DFmode or integral vector modes.  */
2739   if (<V64:MODE>mode == DFmode)
2740     half_mode = SFmode;
2741   else
2742     half_mode = SImode;
2744   word0 = adjust_address (operands[0], half_mode, 0);
2745   word1 = adjust_address (operands[0], half_mode, 4);
2747   emit_move_insn_1 (word0, gen_highpart (half_mode, operands[1]));
2748   emit_move_insn_1 (word1, gen_lowpart (half_mode, operands[1]));
2749   DONE;
2752 (define_split
2753   [(set (match_operand:V64 0 "memory_operand" "")
2754         (match_operand:V64 1 "const_zero_operand" ""))]
2755   "reload_completed
2756    && (! TARGET_V9
2757        || (! TARGET_ARCH64
2758            && ! mem_min_alignment (operands[0], 8)))
2759    && offsettable_memref_p (operands[0])"
2760   [(clobber (const_int 0))]
2762   enum machine_mode half_mode;
2763   rtx dest1, dest2;
2765   /* We can be expanded for DFmode or integral vector modes.  */
2766   if (<V64:MODE>mode == DFmode)
2767     half_mode = SFmode;
2768   else
2769     half_mode = SImode;
2771   dest1 = adjust_address (operands[0], half_mode, 0);
2772   dest2 = adjust_address (operands[0], half_mode, 4);
2774   emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2775   emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2776   DONE;
2779 (define_split
2780   [(set (match_operand:V64 0 "register_operand" "")
2781         (match_operand:V64 1 "const_zero_operand" ""))]
2782   "reload_completed
2783    && ! TARGET_ARCH64
2784    && ((GET_CODE (operands[0]) == REG
2785         && REGNO (operands[0]) < 32)
2786        || (GET_CODE (operands[0]) == SUBREG
2787            && GET_CODE (SUBREG_REG (operands[0])) == REG
2788            && REGNO (SUBREG_REG (operands[0])) < 32))"
2789   [(clobber (const_int 0))]
2791   enum machine_mode half_mode;
2792   rtx set_dest = operands[0];
2793   rtx dest1, dest2;
2795   /* We can be expanded for DFmode or integral vector modes.  */
2796   if (<V64:MODE>mode == DFmode)
2797     half_mode = SFmode;
2798   else
2799     half_mode = SImode;
2801   dest1 = gen_highpart (half_mode, set_dest);
2802   dest2 = gen_lowpart (half_mode, set_dest);
2803   emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2804   emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2805   DONE;
2808 (define_expand "movtf"
2809   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2810         (match_operand:TF 1 "general_operand" ""))]
2811   ""
2813   if (sparc_expand_move (TFmode, operands))
2814     DONE;
2817 (define_insn "*movtf_insn_sp32"
2818   [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,U,r")
2819         (match_operand:TF 1 "input_operand"    "G,oe,GeUr,o,roG"))]
2820   "TARGET_FPU
2821    && ! TARGET_ARCH64
2822    && (register_operand (operands[0], TFmode)
2823        || register_or_zero_operand (operands[1], TFmode))"
2824   "#"
2825   [(set_attr "length" "4")])
2827 ;; Exactly the same as above, except that all `e' cases are deleted.
2828 ;; This is necessary to prevent reload from ever trying to use a `e' reg
2829 ;; when -mno-fpu.
2831 (define_insn "*movtf_insn_sp32_no_fpu"
2832   [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
2833         (match_operand:TF 1 "input_operand"    "G,o,U,roG,r"))]
2834   "! TARGET_FPU
2835    && ! TARGET_ARCH64
2836    && (register_operand (operands[0], TFmode)
2837        || register_or_zero_operand (operands[1], TFmode))"
2838   "#"
2839   [(set_attr "length" "4")])
2841 (define_insn "*movtf_insn_sp64"
2842   [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,r")
2843         (match_operand:TF 1 "input_operand"    "G,oe,Ger,roG"))]
2844   "TARGET_FPU
2845    && TARGET_ARCH64
2846    && ! TARGET_HARD_QUAD
2847    && (register_operand (operands[0], TFmode)
2848        || register_or_zero_operand (operands[1], TFmode))"
2849   "#"
2850   [(set_attr "length" "2")])
2852 (define_insn "*movtf_insn_sp64_hq"
2853   [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,e,m,o,r")
2854         (match_operand:TF 1 "input_operand"    "G,e,m,e,rG,roG"))]
2855   "TARGET_FPU
2856    && TARGET_ARCH64
2857    && TARGET_HARD_QUAD
2858    && (register_operand (operands[0], TFmode)
2859        || register_or_zero_operand (operands[1], TFmode))"
2860   "@
2861   #
2862   fmovq\t%1, %0
2863   ldq\t%1, %0
2864   stq\t%1, %0
2865   #
2866   #"
2867   [(set_attr "type" "*,fpmove,fpload,fpstore,*,*")
2868    (set_attr "length" "2,*,*,*,2,2")])
2870 (define_insn "*movtf_insn_sp64_no_fpu"
2871   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
2872         (match_operand:TF 1 "input_operand"    "orG,rG"))]
2873   "! TARGET_FPU
2874    && TARGET_ARCH64
2875    && (register_operand (operands[0], TFmode)
2876        || register_or_zero_operand (operands[1], TFmode))"
2877   "#"
2878   [(set_attr "length" "2")])
2880 ;; Now all the splits to handle multi-insn TF mode moves.
2881 (define_split
2882   [(set (match_operand:TF 0 "register_operand" "")
2883         (match_operand:TF 1 "register_operand" ""))]
2884   "reload_completed
2885    && (! TARGET_ARCH64
2886        || (TARGET_FPU
2887            && ! TARGET_HARD_QUAD)
2888        || ! fp_register_operand (operands[0], TFmode))"
2889   [(clobber (const_int 0))]
2891   rtx set_dest = operands[0];
2892   rtx set_src = operands[1];
2893   rtx dest1, dest2;
2894   rtx src1, src2;
2896   dest1 = gen_df_reg (set_dest, 0);
2897   dest2 = gen_df_reg (set_dest, 1);
2898   src1 = gen_df_reg (set_src, 0);
2899   src2 = gen_df_reg (set_src, 1);
2901   /* Now emit using the real source and destination we found, swapping
2902      the order if we detect overlap.  */
2903   if (reg_overlap_mentioned_p (dest1, src2))
2904     {
2905       emit_insn (gen_movdf (dest2, src2));
2906       emit_insn (gen_movdf (dest1, src1));
2907     }
2908   else
2909     {
2910       emit_insn (gen_movdf (dest1, src1));
2911       emit_insn (gen_movdf (dest2, src2));
2912     }
2913   DONE;
2916 (define_split
2917   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2918         (match_operand:TF 1 "const_zero_operand" ""))]
2919   "reload_completed"
2920   [(clobber (const_int 0))]
2922   rtx set_dest = operands[0];
2923   rtx dest1, dest2;
2925   switch (GET_CODE (set_dest))
2926     {
2927     case REG:
2928       dest1 = gen_df_reg (set_dest, 0);
2929       dest2 = gen_df_reg (set_dest, 1);
2930       break;
2931     case MEM:
2932       dest1 = adjust_address (set_dest, DFmode, 0);
2933       dest2 = adjust_address (set_dest, DFmode, 8);
2934       break;
2935     default:
2936       gcc_unreachable ();      
2937     }
2939   emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
2940   emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
2941   DONE;
2944 (define_split
2945   [(set (match_operand:TF 0 "register_operand" "")
2946         (match_operand:TF 1 "memory_operand" ""))]
2947   "(reload_completed
2948     && offsettable_memref_p (operands[1])
2949     && (! TARGET_ARCH64
2950         || ! TARGET_HARD_QUAD
2951         || ! fp_register_operand (operands[0], TFmode)))"
2952   [(clobber (const_int 0))]
2954   rtx word0 = adjust_address (operands[1], DFmode, 0);
2955   rtx word1 = adjust_address (operands[1], DFmode, 8);
2956   rtx set_dest, dest1, dest2;
2958   set_dest = operands[0];
2960   dest1 = gen_df_reg (set_dest, 0);
2961   dest2 = gen_df_reg (set_dest, 1);
2963   /* Now output, ordering such that we don't clobber any registers
2964      mentioned in the address.  */
2965   if (reg_overlap_mentioned_p (dest1, word1))
2967     {
2968       emit_insn (gen_movdf (dest2, word1));
2969       emit_insn (gen_movdf (dest1, word0));
2970     }
2971   else
2972    {
2973       emit_insn (gen_movdf (dest1, word0));
2974       emit_insn (gen_movdf (dest2, word1));
2975    }
2976   DONE;
2979 (define_split
2980   [(set (match_operand:TF 0 "memory_operand" "")
2981         (match_operand:TF 1 "register_operand" ""))]
2982   "(reload_completed
2983     && offsettable_memref_p (operands[0])
2984     && (! TARGET_ARCH64
2985         || ! TARGET_HARD_QUAD
2986         || ! fp_register_operand (operands[1], TFmode)))"
2987   [(clobber (const_int 0))]
2989   rtx set_src = operands[1];
2991   emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
2992                         gen_df_reg (set_src, 0)));
2993   emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
2994                         gen_df_reg (set_src, 1)));
2995   DONE;
2999 ;; SPARC-V9 conditional move instructions.
3001 ;; We can handle larger constants here for some flavors, but for now we keep
3002 ;; it simple and only allow those constants supported by all flavors.
3003 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3004 ;; 3 contains the constant if one is present, but we handle either for
3005 ;; generality (sparc.c puts a constant in operand 2).
3007 (define_expand "movqicc"
3008   [(set (match_operand:QI 0 "register_operand" "")
3009         (if_then_else:QI (match_operand 1 "comparison_operator" "")
3010                          (match_operand:QI 2 "arith10_operand" "")
3011                          (match_operand:QI 3 "arith10_operand" "")))]
3012   "TARGET_V9"
3014   enum rtx_code code = GET_CODE (operands[1]);
3016   if (GET_MODE (sparc_compare_op0) == DImode
3017       && ! TARGET_ARCH64)
3018     FAIL;
3020   if (sparc_compare_op1 == const0_rtx
3021       && GET_CODE (sparc_compare_op0) == REG
3022       && GET_MODE (sparc_compare_op0) == DImode
3023       && v9_regcmp_p (code))
3024     {
3025       operands[1] = gen_rtx_fmt_ee (code, DImode,
3026                              sparc_compare_op0, sparc_compare_op1);
3027     }
3028   else
3029     {
3030       rtx cc_reg = gen_compare_reg (code);
3031       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3032     }
3035 (define_expand "movhicc"
3036   [(set (match_operand:HI 0 "register_operand" "")
3037         (if_then_else:HI (match_operand 1 "comparison_operator" "")
3038                          (match_operand:HI 2 "arith10_operand" "")
3039                          (match_operand:HI 3 "arith10_operand" "")))]
3040   "TARGET_V9"
3042   enum rtx_code code = GET_CODE (operands[1]);
3044   if (GET_MODE (sparc_compare_op0) == DImode
3045       && ! TARGET_ARCH64)
3046     FAIL;
3048   if (sparc_compare_op1 == const0_rtx
3049       && GET_CODE (sparc_compare_op0) == REG
3050       && GET_MODE (sparc_compare_op0) == DImode
3051       && v9_regcmp_p (code))
3052     {
3053       operands[1] = gen_rtx_fmt_ee (code, DImode,
3054                              sparc_compare_op0, sparc_compare_op1);
3055     }
3056   else
3057     {
3058       rtx cc_reg = gen_compare_reg (code);
3059       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3060     }
3063 (define_expand "movsicc"
3064   [(set (match_operand:SI 0 "register_operand" "")
3065         (if_then_else:SI (match_operand 1 "comparison_operator" "")
3066                          (match_operand:SI 2 "arith10_operand" "")
3067                          (match_operand:SI 3 "arith10_operand" "")))]
3068   "TARGET_V9"
3070   enum rtx_code code = GET_CODE (operands[1]);
3071   enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
3073   if (sparc_compare_op1 == const0_rtx
3074       && GET_CODE (sparc_compare_op0) == REG
3075       && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
3076     {
3077       operands[1] = gen_rtx_fmt_ee (code, op0_mode,
3078                              sparc_compare_op0, sparc_compare_op1);
3079     }
3080   else
3081     {
3082       rtx cc_reg = gen_compare_reg (code);
3083       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3084                                     cc_reg, const0_rtx);
3085     }
3088 (define_expand "movdicc"
3089   [(set (match_operand:DI 0 "register_operand" "")
3090         (if_then_else:DI (match_operand 1 "comparison_operator" "")
3091                          (match_operand:DI 2 "arith10_operand" "")
3092                          (match_operand:DI 3 "arith10_operand" "")))]
3093   "TARGET_ARCH64"
3095   enum rtx_code code = GET_CODE (operands[1]);
3097   if (sparc_compare_op1 == const0_rtx
3098       && GET_CODE (sparc_compare_op0) == REG
3099       && GET_MODE (sparc_compare_op0) == DImode
3100       && v9_regcmp_p (code))
3101     {
3102       operands[1] = gen_rtx_fmt_ee (code, DImode,
3103                              sparc_compare_op0, sparc_compare_op1);
3104     }
3105   else
3106     {
3107       rtx cc_reg = gen_compare_reg (code);
3108       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3109                                     cc_reg, const0_rtx);
3110     }
3113 (define_expand "movsfcc"
3114   [(set (match_operand:SF 0 "register_operand" "")
3115         (if_then_else:SF (match_operand 1 "comparison_operator" "")
3116                          (match_operand:SF 2 "register_operand" "")
3117                          (match_operand:SF 3 "register_operand" "")))]
3118   "TARGET_V9 && TARGET_FPU"
3120   enum rtx_code code = GET_CODE (operands[1]);
3122   if (GET_MODE (sparc_compare_op0) == DImode
3123       && ! TARGET_ARCH64)
3124     FAIL;
3126   if (sparc_compare_op1 == const0_rtx
3127       && GET_CODE (sparc_compare_op0) == REG
3128       && GET_MODE (sparc_compare_op0) == DImode
3129       && v9_regcmp_p (code))
3130     {
3131       operands[1] = gen_rtx_fmt_ee (code, DImode,
3132                              sparc_compare_op0, sparc_compare_op1);
3133     }
3134   else
3135     {
3136       rtx cc_reg = gen_compare_reg (code);
3137       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3138     }
3141 (define_expand "movdfcc"
3142   [(set (match_operand:DF 0 "register_operand" "")
3143         (if_then_else:DF (match_operand 1 "comparison_operator" "")
3144                          (match_operand:DF 2 "register_operand" "")
3145                          (match_operand:DF 3 "register_operand" "")))]
3146   "TARGET_V9 && TARGET_FPU"
3148   enum rtx_code code = GET_CODE (operands[1]);
3150   if (GET_MODE (sparc_compare_op0) == DImode
3151       && ! TARGET_ARCH64)
3152     FAIL;
3154   if (sparc_compare_op1 == const0_rtx
3155       && GET_CODE (sparc_compare_op0) == REG
3156       && GET_MODE (sparc_compare_op0) == DImode
3157       && v9_regcmp_p (code))
3158     {
3159       operands[1] = gen_rtx_fmt_ee (code, DImode,
3160                              sparc_compare_op0, sparc_compare_op1);
3161     }
3162   else
3163     {
3164       rtx cc_reg = gen_compare_reg (code);
3165       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3166     }
3169 (define_expand "movtfcc"
3170   [(set (match_operand:TF 0 "register_operand" "")
3171         (if_then_else:TF (match_operand 1 "comparison_operator" "")
3172                          (match_operand:TF 2 "register_operand" "")
3173                          (match_operand:TF 3 "register_operand" "")))]
3174   "TARGET_V9 && TARGET_FPU"
3176   enum rtx_code code = GET_CODE (operands[1]);
3178   if (GET_MODE (sparc_compare_op0) == DImode
3179       && ! TARGET_ARCH64)
3180     FAIL;
3182   if (sparc_compare_op1 == const0_rtx
3183       && GET_CODE (sparc_compare_op0) == REG
3184       && GET_MODE (sparc_compare_op0) == DImode
3185       && v9_regcmp_p (code))
3186     {
3187       operands[1] = gen_rtx_fmt_ee (code, DImode,
3188                              sparc_compare_op0, sparc_compare_op1);
3189     }
3190   else
3191     {
3192       rtx cc_reg = gen_compare_reg (code);
3193       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3194     }
3197 ;; Conditional move define_insns.
3199 (define_insn "*movqi_cc_sp64"
3200   [(set (match_operand:QI 0 "register_operand" "=r,r")
3201         (if_then_else:QI (match_operator 1 "comparison_operator"
3202                                 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3203                                  (const_int 0)])
3204                          (match_operand:QI 3 "arith11_operand" "rL,0")
3205                          (match_operand:QI 4 "arith11_operand" "0,rL")))]
3206   "TARGET_V9"
3207   "@
3208    mov%C1\t%x2, %3, %0
3209    mov%c1\t%x2, %4, %0"
3210   [(set_attr "type" "cmove")])
3212 (define_insn "*movhi_cc_sp64"
3213   [(set (match_operand:HI 0 "register_operand" "=r,r")
3214         (if_then_else:HI (match_operator 1 "comparison_operator"
3215                                 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3216                                  (const_int 0)])
3217                          (match_operand:HI 3 "arith11_operand" "rL,0")
3218                          (match_operand:HI 4 "arith11_operand" "0,rL")))]
3219   "TARGET_V9"
3220   "@
3221    mov%C1\t%x2, %3, %0
3222    mov%c1\t%x2, %4, %0"
3223   [(set_attr "type" "cmove")])
3225 (define_insn "*movsi_cc_sp64"
3226   [(set (match_operand:SI 0 "register_operand" "=r,r")
3227         (if_then_else:SI (match_operator 1 "comparison_operator"
3228                                 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3229                                  (const_int 0)])
3230                          (match_operand:SI 3 "arith11_operand" "rL,0")
3231                          (match_operand:SI 4 "arith11_operand" "0,rL")))]
3232   "TARGET_V9"
3233   "@
3234    mov%C1\t%x2, %3, %0
3235    mov%c1\t%x2, %4, %0"
3236   [(set_attr "type" "cmove")])
3238 (define_insn "*movdi_cc_sp64"
3239   [(set (match_operand:DI 0 "register_operand" "=r,r")
3240         (if_then_else:DI (match_operator 1 "comparison_operator"
3241                                 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3242                                  (const_int 0)])
3243                          (match_operand:DI 3 "arith11_operand" "rL,0")
3244                          (match_operand:DI 4 "arith11_operand" "0,rL")))]
3245   "TARGET_ARCH64"
3246   "@
3247    mov%C1\t%x2, %3, %0
3248    mov%c1\t%x2, %4, %0"
3249   [(set_attr "type" "cmove")])
3251 (define_insn "*movdi_cc_sp64_trunc"
3252   [(set (match_operand:SI 0 "register_operand" "=r,r")
3253         (if_then_else:SI (match_operator 1 "comparison_operator"
3254                                 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3255                                  (const_int 0)])
3256                          (match_operand:SI 3 "arith11_operand" "rL,0")
3257                          (match_operand:SI 4 "arith11_operand" "0,rL")))]
3258   "TARGET_ARCH64"
3259   "@
3260    mov%C1\t%x2, %3, %0
3261    mov%c1\t%x2, %4, %0"
3262   [(set_attr "type" "cmove")])
3264 (define_insn "*movsf_cc_sp64"
3265   [(set (match_operand:SF 0 "register_operand" "=f,f")
3266         (if_then_else:SF (match_operator 1 "comparison_operator"
3267                                 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3268                                  (const_int 0)])
3269                          (match_operand:SF 3 "register_operand" "f,0")
3270                          (match_operand:SF 4 "register_operand" "0,f")))]
3271   "TARGET_V9 && TARGET_FPU"
3272   "@
3273    fmovs%C1\t%x2, %3, %0
3274    fmovs%c1\t%x2, %4, %0"
3275   [(set_attr "type" "fpcmove")])
3277 (define_insn "movdf_cc_sp64"
3278   [(set (match_operand:DF 0 "register_operand" "=e,e")
3279         (if_then_else:DF (match_operator 1 "comparison_operator"
3280                                 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3281                                  (const_int 0)])
3282                          (match_operand:DF 3 "register_operand" "e,0")
3283                          (match_operand:DF 4 "register_operand" "0,e")))]
3284   "TARGET_V9 && TARGET_FPU"
3285   "@
3286    fmovd%C1\t%x2, %3, %0
3287    fmovd%c1\t%x2, %4, %0"
3288   [(set_attr "type" "fpcmove")
3289    (set_attr "fptype" "double")])
3291 (define_insn "*movtf_cc_hq_sp64"
3292   [(set (match_operand:TF 0 "register_operand" "=e,e")
3293         (if_then_else:TF (match_operator 1 "comparison_operator"
3294                                 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3295                                  (const_int 0)])
3296                          (match_operand:TF 3 "register_operand" "e,0")
3297                          (match_operand:TF 4 "register_operand" "0,e")))]
3298   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3299   "@
3300    fmovq%C1\t%x2, %3, %0
3301    fmovq%c1\t%x2, %4, %0"
3302   [(set_attr "type" "fpcmove")])
3304 (define_insn_and_split "*movtf_cc_sp64"
3305   [(set (match_operand:TF 0 "register_operand" "=e,e")
3306         (if_then_else:TF (match_operator 1 "comparison_operator"
3307                             [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3308                              (const_int 0)])
3309                          (match_operand:TF 3 "register_operand" "e,0")
3310                          (match_operand:TF 4 "register_operand" "0,e")))]
3311   "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
3312   "#"
3313   "&& reload_completed"
3314   [(clobber (const_int 0))]
3316   rtx set_dest = operands[0];
3317   rtx set_srca = operands[3];
3318   rtx set_srcb = operands[4];
3319   int third = rtx_equal_p (set_dest, set_srca);
3320   rtx dest1, dest2;
3321   rtx srca1, srca2, srcb1, srcb2;
3323   dest1 = gen_df_reg (set_dest, 0);
3324   dest2 = gen_df_reg (set_dest, 1);
3325   srca1 = gen_df_reg (set_srca, 0);
3326   srca2 = gen_df_reg (set_srca, 1);
3327   srcb1 = gen_df_reg (set_srcb, 0);
3328   srcb2 = gen_df_reg (set_srcb, 1);
3330   /* Now emit using the real source and destination we found, swapping
3331      the order if we detect overlap.  */
3332   if ((third && reg_overlap_mentioned_p (dest1, srcb2))
3333       || (!third && reg_overlap_mentioned_p (dest1, srca2)))
3334     {
3335       emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3336       emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3337     }
3338   else
3339     {
3340       emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3341       emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3342     }
3343   DONE;
3345   [(set_attr "length" "2")])
3347 (define_insn "*movqi_cc_reg_sp64"
3348   [(set (match_operand:QI 0 "register_operand" "=r,r")
3349         (if_then_else:QI (match_operator 1 "v9_register_compare_operator"
3350                                 [(match_operand:DI 2 "register_operand" "r,r")
3351                                  (const_int 0)])
3352                          (match_operand:QI 3 "arith10_operand" "rM,0")
3353                          (match_operand:QI 4 "arith10_operand" "0,rM")))]
3354   "TARGET_ARCH64"
3355   "@
3356    movr%D1\t%2, %r3, %0
3357    movr%d1\t%2, %r4, %0"
3358   [(set_attr "type" "cmove")])
3360 (define_insn "*movhi_cc_reg_sp64"
3361   [(set (match_operand:HI 0 "register_operand" "=r,r")
3362         (if_then_else:HI (match_operator 1 "v9_register_compare_operator"
3363                                 [(match_operand:DI 2 "register_operand" "r,r")
3364                                  (const_int 0)])
3365                          (match_operand:HI 3 "arith10_operand" "rM,0")
3366                          (match_operand:HI 4 "arith10_operand" "0,rM")))]
3367   "TARGET_ARCH64"
3368   "@
3369    movr%D1\t%2, %r3, %0
3370    movr%d1\t%2, %r4, %0"
3371   [(set_attr "type" "cmove")])
3373 (define_insn "*movsi_cc_reg_sp64"
3374   [(set (match_operand:SI 0 "register_operand" "=r,r")
3375         (if_then_else:SI (match_operator 1 "v9_register_compare_operator"
3376                                 [(match_operand:DI 2 "register_operand" "r,r")
3377                                  (const_int 0)])
3378                          (match_operand:SI 3 "arith10_operand" "rM,0")
3379                          (match_operand:SI 4 "arith10_operand" "0,rM")))]
3380   "TARGET_ARCH64"
3381   "@
3382    movr%D1\t%2, %r3, %0
3383    movr%d1\t%2, %r4, %0"
3384   [(set_attr "type" "cmove")])
3386 (define_insn "*movdi_cc_reg_sp64"
3387   [(set (match_operand:DI 0 "register_operand" "=r,r")
3388         (if_then_else:DI (match_operator 1 "v9_register_compare_operator"
3389                                 [(match_operand:DI 2 "register_operand" "r,r")
3390                                  (const_int 0)])
3391                          (match_operand:DI 3 "arith10_operand" "rM,0")
3392                          (match_operand:DI 4 "arith10_operand" "0,rM")))]
3393   "TARGET_ARCH64"
3394   "@
3395    movr%D1\t%2, %r3, %0
3396    movr%d1\t%2, %r4, %0"
3397   [(set_attr "type" "cmove")])
3399 (define_insn "*movsf_cc_reg_sp64"
3400   [(set (match_operand:SF 0 "register_operand" "=f,f")
3401         (if_then_else:SF (match_operator 1 "v9_register_compare_operator"
3402                                 [(match_operand:DI 2 "register_operand" "r,r")
3403                                  (const_int 0)])
3404                          (match_operand:SF 3 "register_operand" "f,0")
3405                          (match_operand:SF 4 "register_operand" "0,f")))]
3406   "TARGET_ARCH64 && TARGET_FPU"
3407   "@
3408    fmovrs%D1\t%2, %3, %0
3409    fmovrs%d1\t%2, %4, %0"
3410   [(set_attr "type" "fpcrmove")])
3412 (define_insn "movdf_cc_reg_sp64"
3413   [(set (match_operand:DF 0 "register_operand" "=e,e")
3414         (if_then_else:DF (match_operator 1 "v9_register_compare_operator"
3415                                 [(match_operand:DI 2 "register_operand" "r,r")
3416                                  (const_int 0)])
3417                          (match_operand:DF 3 "register_operand" "e,0")
3418                          (match_operand:DF 4 "register_operand" "0,e")))]
3419   "TARGET_ARCH64 && TARGET_FPU"
3420   "@
3421    fmovrd%D1\t%2, %3, %0
3422    fmovrd%d1\t%2, %4, %0"
3423   [(set_attr "type" "fpcrmove")
3424    (set_attr "fptype" "double")])
3426 (define_insn "*movtf_cc_reg_hq_sp64"
3427   [(set (match_operand:TF 0 "register_operand" "=e,e")
3428         (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
3429                                 [(match_operand:DI 2 "register_operand" "r,r")
3430                                  (const_int 0)])
3431                          (match_operand:TF 3 "register_operand" "e,0")
3432                          (match_operand:TF 4 "register_operand" "0,e")))]
3433   "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
3434   "@
3435    fmovrq%D1\t%2, %3, %0
3436    fmovrq%d1\t%2, %4, %0"
3437   [(set_attr "type" "fpcrmove")])
3439 (define_insn_and_split "*movtf_cc_reg_sp64"
3440   [(set (match_operand:TF 0 "register_operand" "=e,e")
3441         (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
3442                                 [(match_operand:DI 2 "register_operand" "r,r")
3443                                  (const_int 0)])
3444                          (match_operand:TF 3 "register_operand" "e,0")
3445                          (match_operand:TF 4 "register_operand" "0,e")))]
3446   "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
3447   "#"
3448   "&& reload_completed"
3449   [(clobber (const_int 0))]
3451   rtx set_dest = operands[0];
3452   rtx set_srca = operands[3];
3453   rtx set_srcb = operands[4];
3454   int third = rtx_equal_p (set_dest, set_srca);
3455   rtx dest1, dest2;
3456   rtx srca1, srca2, srcb1, srcb2;
3458   dest1 = gen_df_reg (set_dest, 0);
3459   dest2 = gen_df_reg (set_dest, 1);
3460   srca1 = gen_df_reg (set_srca, 0);
3461   srca2 = gen_df_reg (set_srca, 1);
3462   srcb1 = gen_df_reg (set_srcb, 0);
3463   srcb2 = gen_df_reg (set_srcb, 1);
3465   /* Now emit using the real source and destination we found, swapping
3466      the order if we detect overlap.  */
3467   if ((third && reg_overlap_mentioned_p (dest1, srcb2))
3468       || (!third && reg_overlap_mentioned_p (dest1, srca2)))
3469     {
3470       emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3471       emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3472     }
3473   else
3474     {
3475       emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3476       emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3477     }
3478   DONE;
3480   [(set_attr "length" "2")])
3483 ;; Zero-extension instructions
3485 ;; These patterns originally accepted general_operands, however, slightly
3486 ;; better code is generated by only accepting register_operands, and then
3487 ;; letting combine generate the ldu[hb] insns.
3489 (define_expand "zero_extendhisi2"
3490   [(set (match_operand:SI 0 "register_operand" "")
3491         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
3492   ""
3494   rtx temp = gen_reg_rtx (SImode);
3495   rtx shift_16 = GEN_INT (16);
3496   int op1_subbyte = 0;
3498   if (GET_CODE (operand1) == SUBREG)
3499     {
3500       op1_subbyte = SUBREG_BYTE (operand1);
3501       op1_subbyte /= GET_MODE_SIZE (SImode);
3502       op1_subbyte *= GET_MODE_SIZE (SImode);
3503       operand1 = XEXP (operand1, 0);
3504     }
3506   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3507                           shift_16));
3508   emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
3509   DONE;
3512 (define_insn "*zero_extendhisi2_insn"
3513   [(set (match_operand:SI 0 "register_operand" "=r")
3514         (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3515   ""
3516   "lduh\t%1, %0"
3517   [(set_attr "type" "load")
3518    (set_attr "us3load_type" "3cycle")])
3520 (define_expand "zero_extendqihi2"
3521   [(set (match_operand:HI 0 "register_operand" "")
3522         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
3523   ""
3524   "")
3526 (define_insn "*zero_extendqihi2_insn"
3527   [(set (match_operand:HI 0 "register_operand" "=r,r")
3528         (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
3529   "GET_CODE (operands[1]) != CONST_INT"
3530   "@
3531    and\t%1, 0xff, %0
3532    ldub\t%1, %0"
3533   [(set_attr "type" "*,load")
3534    (set_attr "us3load_type" "*,3cycle")])
3536 (define_expand "zero_extendqisi2"
3537   [(set (match_operand:SI 0 "register_operand" "")
3538         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
3539   ""
3540   "")
3542 (define_insn "*zero_extendqisi2_insn"
3543   [(set (match_operand:SI 0 "register_operand" "=r,r")
3544         (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
3545   "GET_CODE (operands[1]) != CONST_INT"
3546   "@
3547    and\t%1, 0xff, %0
3548    ldub\t%1, %0"
3549   [(set_attr "type" "*,load")
3550    (set_attr "us3load_type" "*,3cycle")])
3552 (define_expand "zero_extendqidi2"
3553   [(set (match_operand:DI 0 "register_operand" "")
3554         (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
3555   "TARGET_ARCH64"
3556   "")
3558 (define_insn "*zero_extendqidi2_insn"
3559   [(set (match_operand:DI 0 "register_operand" "=r,r")
3560         (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
3561   "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
3562   "@
3563    and\t%1, 0xff, %0
3564    ldub\t%1, %0"
3565   [(set_attr "type" "*,load")
3566    (set_attr "us3load_type" "*,3cycle")])
3568 (define_expand "zero_extendhidi2"
3569   [(set (match_operand:DI 0 "register_operand" "")
3570         (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
3571   "TARGET_ARCH64"
3573   rtx temp = gen_reg_rtx (DImode);
3574   rtx shift_48 = GEN_INT (48);
3575   int op1_subbyte = 0;
3577   if (GET_CODE (operand1) == SUBREG)
3578     {
3579       op1_subbyte = SUBREG_BYTE (operand1);
3580       op1_subbyte /= GET_MODE_SIZE (DImode);
3581       op1_subbyte *= GET_MODE_SIZE (DImode);
3582       operand1 = XEXP (operand1, 0);
3583     }
3585   emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3586                           shift_48));
3587   emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
3588   DONE;
3591 (define_insn "*zero_extendhidi2_insn"
3592   [(set (match_operand:DI 0 "register_operand" "=r")
3593         (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3594   "TARGET_ARCH64"
3595   "lduh\t%1, %0"
3596   [(set_attr "type" "load")
3597    (set_attr "us3load_type" "3cycle")])
3599 ;; ??? Write truncdisi pattern using sra?
3601 (define_expand "zero_extendsidi2"
3602   [(set (match_operand:DI 0 "register_operand" "")
3603         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
3604   ""
3605   "")
3607 (define_insn "*zero_extendsidi2_insn_sp64"
3608   [(set (match_operand:DI 0 "register_operand" "=r,r")
3609         (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
3610   "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
3611   "@
3612    srl\t%1, 0, %0
3613    lduw\t%1, %0"
3614   [(set_attr "type" "shift,load")])
3616 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
3617   [(set (match_operand:DI 0 "register_operand" "=r")
3618         (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
3619   "! TARGET_ARCH64"
3620   "#"
3621   "&& reload_completed"
3622   [(set (match_dup 2) (match_dup 3))
3623    (set (match_dup 4) (match_dup 5))]
3625   rtx dest1, dest2;
3627   dest1 = gen_highpart (SImode, operands[0]);
3628   dest2 = gen_lowpart (SImode, operands[0]);
3630   /* Swap the order in case of overlap.  */
3631   if (REGNO (dest1) == REGNO (operands[1]))
3632     {
3633       operands[2] = dest2;
3634       operands[3] = operands[1];
3635       operands[4] = dest1;
3636       operands[5] = const0_rtx;
3637     }
3638   else
3639     {
3640       operands[2] = dest1;
3641       operands[3] = const0_rtx;
3642       operands[4] = dest2;
3643       operands[5] = operands[1];
3644     }
3646   [(set_attr "length" "2")])
3648 ;; Simplify comparisons of extended values.
3650 (define_insn "*cmp_zero_extendqisi2"
3651   [(set (reg:CC 100)
3652         (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
3653                     (const_int 0)))]
3654   ""
3655   "andcc\t%0, 0xff, %%g0"
3656   [(set_attr "type" "compare")])
3658 (define_insn "*cmp_zero_qi"
3659   [(set (reg:CC 100)
3660         (compare:CC (match_operand:QI 0 "register_operand" "r")
3661                     (const_int 0)))]
3662   ""
3663   "andcc\t%0, 0xff, %%g0"
3664   [(set_attr "type" "compare")])
3666 (define_insn "*cmp_zero_extendqisi2_set"
3667   [(set (reg:CC 100)
3668         (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
3669                     (const_int 0)))
3670    (set (match_operand:SI 0 "register_operand" "=r")
3671         (zero_extend:SI (match_dup 1)))]
3672   ""
3673   "andcc\t%1, 0xff, %0"
3674   [(set_attr "type" "compare")])
3676 (define_insn "*cmp_zero_extendqisi2_andcc_set"
3677   [(set (reg:CC 100)
3678         (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
3679                             (const_int 255))
3680                     (const_int 0)))
3681    (set (match_operand:SI 0 "register_operand" "=r")
3682         (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
3683   ""
3684   "andcc\t%1, 0xff, %0"
3685   [(set_attr "type" "compare")])
3687 (define_insn "*cmp_zero_extendqidi2"
3688   [(set (reg:CCX 100)
3689         (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
3690                      (const_int 0)))]
3691   "TARGET_ARCH64"
3692   "andcc\t%0, 0xff, %%g0"
3693   [(set_attr "type" "compare")])
3695 (define_insn "*cmp_zero_qi_sp64"
3696   [(set (reg:CCX 100)
3697         (compare:CCX (match_operand:QI 0 "register_operand" "r")
3698                      (const_int 0)))]
3699   "TARGET_ARCH64"
3700   "andcc\t%0, 0xff, %%g0"
3701   [(set_attr "type" "compare")])
3703 (define_insn "*cmp_zero_extendqidi2_set"
3704   [(set (reg:CCX 100)
3705         (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
3706                      (const_int 0)))
3707    (set (match_operand:DI 0 "register_operand" "=r")
3708         (zero_extend:DI (match_dup 1)))]
3709   "TARGET_ARCH64"
3710   "andcc\t%1, 0xff, %0"
3711   [(set_attr "type" "compare")])
3713 (define_insn "*cmp_zero_extendqidi2_andcc_set"
3714   [(set (reg:CCX 100)
3715         (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
3716                              (const_int 255))
3717                      (const_int 0)))
3718    (set (match_operand:DI 0 "register_operand" "=r")
3719         (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
3720   "TARGET_ARCH64"
3721   "andcc\t%1, 0xff, %0"
3722   [(set_attr "type" "compare")])
3724 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
3726 (define_insn "*cmp_siqi_trunc"
3727   [(set (reg:CC 100)
3728         (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
3729                     (const_int 0)))]
3730   ""
3731   "andcc\t%0, 0xff, %%g0"
3732   [(set_attr "type" "compare")])
3734 (define_insn "*cmp_siqi_trunc_set"
3735   [(set (reg:CC 100)
3736         (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
3737                     (const_int 0)))
3738    (set (match_operand:QI 0 "register_operand" "=r")
3739         (subreg:QI (match_dup 1) 3))]
3740   ""
3741   "andcc\t%1, 0xff, %0"
3742   [(set_attr "type" "compare")])
3744 (define_insn "*cmp_diqi_trunc"
3745   [(set (reg:CC 100)
3746         (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
3747                     (const_int 0)))]
3748   "TARGET_ARCH64"
3749   "andcc\t%0, 0xff, %%g0"
3750   [(set_attr "type" "compare")])
3752 (define_insn "*cmp_diqi_trunc_set"
3753   [(set (reg:CC 100)
3754         (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
3755                     (const_int 0)))
3756    (set (match_operand:QI 0 "register_operand" "=r")
3757         (subreg:QI (match_dup 1) 7))]
3758   "TARGET_ARCH64"
3759   "andcc\t%1, 0xff, %0"
3760   [(set_attr "type" "compare")])
3763 ;; Sign-extension instructions
3765 ;; These patterns originally accepted general_operands, however, slightly
3766 ;; better code is generated by only accepting register_operands, and then
3767 ;; letting combine generate the lds[hb] insns.
3769 (define_expand "extendhisi2"
3770   [(set (match_operand:SI 0 "register_operand" "")
3771         (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
3772   ""
3774   rtx temp = gen_reg_rtx (SImode);
3775   rtx shift_16 = GEN_INT (16);
3776   int op1_subbyte = 0;
3778   if (GET_CODE (operand1) == SUBREG)
3779     {
3780       op1_subbyte = SUBREG_BYTE (operand1);
3781       op1_subbyte /= GET_MODE_SIZE (SImode);
3782       op1_subbyte *= GET_MODE_SIZE (SImode);
3783       operand1 = XEXP (operand1, 0);
3784     }
3786   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3787                           shift_16));
3788   emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
3789   DONE;
3792 (define_insn "*sign_extendhisi2_insn"
3793   [(set (match_operand:SI 0 "register_operand" "=r")
3794         (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3795   ""
3796   "ldsh\t%1, %0"
3797   [(set_attr "type" "sload")
3798    (set_attr "us3load_type" "3cycle")])
3800 (define_expand "extendqihi2"
3801   [(set (match_operand:HI 0 "register_operand" "")
3802         (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
3803   ""
3805   rtx temp = gen_reg_rtx (SImode);
3806   rtx shift_24 = GEN_INT (24);
3807   int op1_subbyte = 0;
3808   int op0_subbyte = 0;
3810   if (GET_CODE (operand1) == SUBREG)
3811     {
3812       op1_subbyte = SUBREG_BYTE (operand1);
3813       op1_subbyte /= GET_MODE_SIZE (SImode);
3814       op1_subbyte *= GET_MODE_SIZE (SImode);
3815       operand1 = XEXP (operand1, 0);
3816     }
3817   if (GET_CODE (operand0) == SUBREG)
3818     {
3819       op0_subbyte = SUBREG_BYTE (operand0);
3820       op0_subbyte /= GET_MODE_SIZE (SImode);
3821       op0_subbyte *= GET_MODE_SIZE (SImode);
3822       operand0 = XEXP (operand0, 0);
3823     }
3824   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3825                           shift_24));
3826   if (GET_MODE (operand0) != SImode)
3827     operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
3828   emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3829   DONE;
3832 (define_insn "*sign_extendqihi2_insn"
3833   [(set (match_operand:HI 0 "register_operand" "=r")
3834         (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3835   ""
3836   "ldsb\t%1, %0"
3837   [(set_attr "type" "sload")
3838    (set_attr "us3load_type" "3cycle")])
3840 (define_expand "extendqisi2"
3841   [(set (match_operand:SI 0 "register_operand" "")
3842         (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
3843   ""
3845   rtx temp = gen_reg_rtx (SImode);
3846   rtx shift_24 = GEN_INT (24);
3847   int op1_subbyte = 0;
3849   if (GET_CODE (operand1) == SUBREG)
3850     {
3851       op1_subbyte = SUBREG_BYTE (operand1);
3852       op1_subbyte /= GET_MODE_SIZE (SImode);
3853       op1_subbyte *= GET_MODE_SIZE (SImode);
3854       operand1 = XEXP (operand1, 0);
3855     }
3857   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3858                           shift_24));
3859   emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3860   DONE;
3863 (define_insn "*sign_extendqisi2_insn"
3864   [(set (match_operand:SI 0 "register_operand" "=r")
3865         (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3866   ""
3867   "ldsb\t%1, %0"
3868   [(set_attr "type" "sload")
3869    (set_attr "us3load_type" "3cycle")])
3871 (define_expand "extendqidi2"
3872   [(set (match_operand:DI 0 "register_operand" "")
3873         (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
3874   "TARGET_ARCH64"
3876   rtx temp = gen_reg_rtx (DImode);
3877   rtx shift_56 = GEN_INT (56);
3878   int op1_subbyte = 0;
3880   if (GET_CODE (operand1) == SUBREG)
3881     {
3882       op1_subbyte = SUBREG_BYTE (operand1);
3883       op1_subbyte /= GET_MODE_SIZE (DImode);
3884       op1_subbyte *= GET_MODE_SIZE (DImode);
3885       operand1 = XEXP (operand1, 0);
3886     }
3888   emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3889                           shift_56));
3890   emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
3891   DONE;
3894 (define_insn "*sign_extendqidi2_insn"
3895   [(set (match_operand:DI 0 "register_operand" "=r")
3896         (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3897   "TARGET_ARCH64"
3898   "ldsb\t%1, %0"
3899   [(set_attr "type" "sload")
3900    (set_attr "us3load_type" "3cycle")])
3902 (define_expand "extendhidi2"
3903   [(set (match_operand:DI 0 "register_operand" "")
3904         (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
3905   "TARGET_ARCH64"
3907   rtx temp = gen_reg_rtx (DImode);
3908   rtx shift_48 = GEN_INT (48);
3909   int op1_subbyte = 0;
3911   if (GET_CODE (operand1) == SUBREG)
3912     {
3913       op1_subbyte = SUBREG_BYTE (operand1);
3914       op1_subbyte /= GET_MODE_SIZE (DImode);
3915       op1_subbyte *= GET_MODE_SIZE (DImode);
3916       operand1 = XEXP (operand1, 0);
3917     }
3919   emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3920                           shift_48));
3921   emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
3922   DONE;
3925 (define_insn "*sign_extendhidi2_insn"
3926   [(set (match_operand:DI 0 "register_operand" "=r")
3927         (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3928   "TARGET_ARCH64"
3929   "ldsh\t%1, %0"
3930   [(set_attr "type" "sload")
3931    (set_attr "us3load_type" "3cycle")])
3933 (define_expand "extendsidi2"
3934   [(set (match_operand:DI 0 "register_operand" "")
3935         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3936   "TARGET_ARCH64"
3937   "")
3939 (define_insn "*sign_extendsidi2_insn"
3940   [(set (match_operand:DI 0 "register_operand" "=r,r")
3941         (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
3942   "TARGET_ARCH64"
3943   "@
3944   sra\t%1, 0, %0
3945   ldsw\t%1, %0"
3946   [(set_attr "type" "shift,sload")
3947    (set_attr "us3load_type" "*,3cycle")])
3950 ;; Special pattern for optimizing bit-field compares.  This is needed
3951 ;; because combine uses this as a canonical form.
3953 (define_insn "*cmp_zero_extract"
3954   [(set (reg:CC 100)
3955         (compare:CC
3956          (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
3957                           (match_operand:SI 1 "small_int_operand" "I")
3958                           (match_operand:SI 2 "small_int_operand" "I"))
3959          (const_int 0)))]
3960   "INTVAL (operands[2]) > 19"
3962   int len = INTVAL (operands[1]);
3963   int pos = 32 - INTVAL (operands[2]) - len;
3964   HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
3965   operands[1] = GEN_INT (mask);
3966   return "andcc\t%0, %1, %%g0";
3968   [(set_attr "type" "compare")])
3970 (define_insn "*cmp_zero_extract_sp64"
3971   [(set (reg:CCX 100)
3972         (compare:CCX
3973          (zero_extract:DI (match_operand:DI 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   "TARGET_ARCH64 && INTVAL (operands[2]) > 51"
3979   int len = INTVAL (operands[1]);
3980   int pos = 64 - INTVAL (operands[2]) - len;
3981   HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
3982   operands[1] = GEN_INT (mask);
3983   return "andcc\t%0, %1, %%g0";
3985   [(set_attr "type" "compare")])
3988 ;; Conversions between float, double and long double.
3990 (define_insn "extendsfdf2"
3991   [(set (match_operand:DF 0 "register_operand" "=e")
3992         (float_extend:DF
3993          (match_operand:SF 1 "register_operand" "f")))]
3994   "TARGET_FPU"
3995   "fstod\t%1, %0"
3996   [(set_attr "type" "fp")
3997    (set_attr "fptype" "double")])
3999 (define_expand "extendsftf2"
4000   [(set (match_operand:TF 0 "nonimmediate_operand" "")
4001         (float_extend:TF
4002          (match_operand:SF 1 "register_operand" "")))]
4003   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4004   "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4006 (define_insn "*extendsftf2_hq"
4007   [(set (match_operand:TF 0 "register_operand" "=e")
4008         (float_extend:TF
4009          (match_operand:SF 1 "register_operand" "f")))]
4010   "TARGET_FPU && TARGET_HARD_QUAD"
4011   "fstoq\t%1, %0"
4012   [(set_attr "type" "fp")])
4014 (define_expand "extenddftf2"
4015   [(set (match_operand:TF 0 "nonimmediate_operand" "")
4016         (float_extend:TF
4017          (match_operand:DF 1 "register_operand" "")))]
4018   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4019   "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4021 (define_insn "*extenddftf2_hq"
4022   [(set (match_operand:TF 0 "register_operand" "=e")
4023         (float_extend:TF
4024          (match_operand:DF 1 "register_operand" "e")))]
4025   "TARGET_FPU && TARGET_HARD_QUAD"
4026   "fdtoq\t%1, %0"
4027   [(set_attr "type" "fp")])
4029 (define_insn "truncdfsf2"
4030   [(set (match_operand:SF 0 "register_operand" "=f")
4031         (float_truncate:SF
4032          (match_operand:DF 1 "register_operand" "e")))]
4033   "TARGET_FPU"
4034   "fdtos\t%1, %0"
4035   [(set_attr "type" "fp")
4036    (set_attr "fptype" "double")])
4038 (define_expand "trunctfsf2"
4039   [(set (match_operand:SF 0 "register_operand" "")
4040         (float_truncate:SF
4041          (match_operand:TF 1 "general_operand" "")))]
4042   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4043   "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4045 (define_insn "*trunctfsf2_hq"
4046   [(set (match_operand:SF 0 "register_operand" "=f")
4047         (float_truncate:SF
4048          (match_operand:TF 1 "register_operand" "e")))]
4049   "TARGET_FPU && TARGET_HARD_QUAD"
4050   "fqtos\t%1, %0"
4051   [(set_attr "type" "fp")])
4053 (define_expand "trunctfdf2"
4054   [(set (match_operand:DF 0 "register_operand" "")
4055         (float_truncate:DF
4056          (match_operand:TF 1 "general_operand" "")))]
4057   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4058   "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4060 (define_insn "*trunctfdf2_hq"
4061   [(set (match_operand:DF 0 "register_operand" "=e")
4062         (float_truncate:DF
4063          (match_operand:TF 1 "register_operand" "e")))]
4064   "TARGET_FPU && TARGET_HARD_QUAD"
4065   "fqtod\t%1, %0"
4066   [(set_attr "type" "fp")])
4069 ;; Conversion between fixed point and floating point.
4071 (define_insn "floatsisf2"
4072   [(set (match_operand:SF 0 "register_operand" "=f")
4073         (float:SF (match_operand:SI 1 "register_operand" "f")))]
4074   "TARGET_FPU"
4075   "fitos\t%1, %0"
4076   [(set_attr "type" "fp")
4077    (set_attr "fptype" "double")])
4079 (define_insn "floatsidf2"
4080   [(set (match_operand:DF 0 "register_operand" "=e")
4081         (float:DF (match_operand:SI 1 "register_operand" "f")))]
4082   "TARGET_FPU"
4083   "fitod\t%1, %0"
4084   [(set_attr "type" "fp")
4085    (set_attr "fptype" "double")])
4087 (define_expand "floatsitf2"
4088   [(set (match_operand:TF 0 "nonimmediate_operand" "")
4089         (float:TF (match_operand:SI 1 "register_operand" "")))]
4090   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4091   "emit_tfmode_cvt (FLOAT, operands); DONE;")
4093 (define_insn "*floatsitf2_hq"
4094   [(set (match_operand:TF 0 "register_operand" "=e")
4095         (float:TF (match_operand:SI 1 "register_operand" "f")))]
4096   "TARGET_FPU && TARGET_HARD_QUAD"
4097   "fitoq\t%1, %0"
4098   [(set_attr "type" "fp")])
4100 (define_expand "floatunssitf2"
4101   [(set (match_operand:TF 0 "nonimmediate_operand" "")
4102         (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
4103   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4104   "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4106 ;; Now the same for 64 bit sources.
4108 (define_insn "floatdisf2"
4109   [(set (match_operand:SF 0 "register_operand" "=f")
4110         (float:SF (match_operand:DI 1 "register_operand" "e")))]
4111   "TARGET_V9 && TARGET_FPU"
4112   "fxtos\t%1, %0"
4113   [(set_attr "type" "fp")
4114    (set_attr "fptype" "double")])
4116 (define_expand "floatunsdisf2"
4117   [(use (match_operand:SF 0 "register_operand" ""))
4118    (use (match_operand:DI 1 "general_operand" ""))]
4119   "TARGET_ARCH64 && TARGET_FPU"
4120   "sparc_emit_floatunsdi (operands, SFmode); DONE;")
4122 (define_insn "floatdidf2"
4123   [(set (match_operand:DF 0 "register_operand" "=e")
4124         (float:DF (match_operand:DI 1 "register_operand" "e")))]
4125   "TARGET_V9 && TARGET_FPU"
4126   "fxtod\t%1, %0"
4127   [(set_attr "type" "fp")
4128    (set_attr "fptype" "double")])
4130 (define_expand "floatunsdidf2"
4131   [(use (match_operand:DF 0 "register_operand" ""))
4132    (use (match_operand:DI 1 "general_operand" ""))]
4133   "TARGET_ARCH64 && TARGET_FPU"
4134   "sparc_emit_floatunsdi (operands, DFmode); DONE;")
4136 (define_expand "floatditf2"
4137   [(set (match_operand:TF 0 "nonimmediate_operand" "")
4138         (float:TF (match_operand:DI 1 "register_operand" "")))]
4139   "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4140   "emit_tfmode_cvt (FLOAT, operands); DONE;")
4142 (define_insn "*floatditf2_hq"
4143   [(set (match_operand:TF 0 "register_operand" "=e")
4144         (float:TF (match_operand:DI 1 "register_operand" "e")))]
4145   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4146   "fxtoq\t%1, %0"
4147   [(set_attr "type" "fp")])
4149 (define_expand "floatunsditf2"
4150   [(set (match_operand:TF 0 "nonimmediate_operand" "")
4151         (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
4152   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4153   "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4155 ;; Convert a float to an actual integer.
4156 ;; Truncation is performed as part of the conversion.
4158 (define_insn "fix_truncsfsi2"
4159   [(set (match_operand:SI 0 "register_operand" "=f")
4160         (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4161   "TARGET_FPU"
4162   "fstoi\t%1, %0"
4163   [(set_attr "type" "fp")
4164    (set_attr "fptype" "double")])
4166 (define_insn "fix_truncdfsi2"
4167   [(set (match_operand:SI 0 "register_operand" "=f")
4168         (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4169   "TARGET_FPU"
4170   "fdtoi\t%1, %0"
4171   [(set_attr "type" "fp")
4172    (set_attr "fptype" "double")])
4174 (define_expand "fix_trunctfsi2"
4175   [(set (match_operand:SI 0 "register_operand" "")
4176         (fix:SI (match_operand:TF 1 "general_operand" "")))]
4177   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4178   "emit_tfmode_cvt (FIX, operands); DONE;")
4180 (define_insn "*fix_trunctfsi2_hq"
4181   [(set (match_operand:SI 0 "register_operand" "=f")
4182         (fix:SI (match_operand:TF 1 "register_operand" "e")))]
4183   "TARGET_FPU && TARGET_HARD_QUAD"
4184   "fqtoi\t%1, %0"
4185   [(set_attr "type" "fp")])
4187 (define_expand "fixuns_trunctfsi2"
4188   [(set (match_operand:SI 0 "register_operand" "")
4189         (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
4190   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4191   "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4193 ;; Now the same, for V9 targets
4195 (define_insn "fix_truncsfdi2"
4196   [(set (match_operand:DI 0 "register_operand" "=e")
4197         (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4198   "TARGET_V9 && TARGET_FPU"
4199   "fstox\t%1, %0"
4200   [(set_attr "type" "fp")
4201    (set_attr "fptype" "double")])
4203 (define_expand "fixuns_truncsfdi2"
4204   [(use (match_operand:DI 0 "register_operand" ""))
4205    (use (match_operand:SF 1 "general_operand" ""))]
4206   "TARGET_ARCH64 && TARGET_FPU"
4207   "sparc_emit_fixunsdi (operands, SFmode); DONE;")
4209 (define_insn "fix_truncdfdi2"
4210   [(set (match_operand:DI 0 "register_operand" "=e")
4211         (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4212   "TARGET_V9 && TARGET_FPU"
4213   "fdtox\t%1, %0"
4214   [(set_attr "type" "fp")
4215    (set_attr "fptype" "double")])
4217 (define_expand "fixuns_truncdfdi2"
4218   [(use (match_operand:DI 0 "register_operand" ""))
4219    (use (match_operand:DF 1 "general_operand" ""))]
4220   "TARGET_ARCH64 && TARGET_FPU"
4221   "sparc_emit_fixunsdi (operands, DFmode); DONE;")
4223 (define_expand "fix_trunctfdi2"
4224   [(set (match_operand:DI 0 "register_operand" "")
4225         (fix:DI (match_operand:TF 1 "general_operand" "")))]
4226   "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4227   "emit_tfmode_cvt (FIX, operands); DONE;")
4229 (define_insn "*fix_trunctfdi2_hq"
4230   [(set (match_operand:DI 0 "register_operand" "=e")
4231         (fix:DI (match_operand:TF 1 "register_operand" "e")))]
4232   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4233   "fqtox\t%1, %0"
4234   [(set_attr "type" "fp")])
4236 (define_expand "fixuns_trunctfdi2"
4237   [(set (match_operand:DI 0 "register_operand" "")
4238         (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
4239   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4240   "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4243 ;; Integer addition/subtraction instructions.
4245 (define_expand "adddi3"
4246   [(set (match_operand:DI 0 "register_operand" "")
4247         (plus:DI (match_operand:DI 1 "register_operand" "")
4248                  (match_operand:DI 2 "arith_double_add_operand" "")))]
4249   ""
4251   if (! TARGET_ARCH64)
4252     {
4253       emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4254                           gen_rtx_SET (VOIDmode, operands[0],
4255                                    gen_rtx_PLUS (DImode, operands[1],
4256                                                  operands[2])),
4257                           gen_rtx_CLOBBER (VOIDmode,
4258                                    gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4259       DONE;
4260     }
4263 (define_insn_and_split "adddi3_insn_sp32"
4264   [(set (match_operand:DI 0 "register_operand" "=r")
4265         (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4266                  (match_operand:DI 2 "arith_double_operand" "rHI")))
4267    (clobber (reg:CC 100))]
4268   "! TARGET_ARCH64"
4269   "#"
4270   "&& reload_completed"
4271   [(parallel [(set (reg:CC_NOOV 100)
4272                    (compare:CC_NOOV (plus:SI (match_dup 4)
4273                                              (match_dup 5))
4274                                     (const_int 0)))
4275               (set (match_dup 3)
4276                    (plus:SI (match_dup 4) (match_dup 5)))])
4277    (set (match_dup 6)
4278         (plus:SI (plus:SI (match_dup 7)
4279                           (match_dup 8))
4280                  (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4282   operands[3] = gen_lowpart (SImode, operands[0]);
4283   operands[4] = gen_lowpart (SImode, operands[1]);
4284   operands[5] = gen_lowpart (SImode, operands[2]);
4285   operands[6] = gen_highpart (SImode, operands[0]);
4286   operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
4287 #if HOST_BITS_PER_WIDE_INT == 32
4288   if (GET_CODE (operands[2]) == CONST_INT)
4289     {
4290       if (INTVAL (operands[2]) < 0)
4291         operands[8] = constm1_rtx;
4292       else
4293         operands[8] = const0_rtx;
4294     }
4295   else
4296 #endif
4297     operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4299   [(set_attr "length" "2")])
4301 ;; LTU here means "carry set"
4302 (define_insn "addx"
4303   [(set (match_operand:SI 0 "register_operand" "=r")
4304         (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4305                           (match_operand:SI 2 "arith_operand" "rI"))
4306                  (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4307   ""
4308   "addx\t%1, %2, %0"
4309   [(set_attr "type" "ialuX")])
4311 (define_insn_and_split "*addx_extend_sp32"
4312   [(set (match_operand:DI 0 "register_operand" "=r")
4313         (zero_extend:DI (plus:SI (plus:SI
4314                                   (match_operand:SI 1 "register_or_zero_operand" "%rJ")
4315                                   (match_operand:SI 2 "arith_operand" "rI"))
4316                                  (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4317   "! TARGET_ARCH64"
4318   "#"
4319   "&& reload_completed"
4320   [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
4321                                (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4322    (set (match_dup 4) (const_int 0))]
4323   "operands[3] = gen_lowpart (SImode, operands[0]);
4324    operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
4325   [(set_attr "length" "2")])
4327 (define_insn "*addx_extend_sp64"
4328   [(set (match_operand:DI 0 "register_operand" "=r")
4329         (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
4330                                           (match_operand:SI 2 "arith_operand" "rI"))
4331                                  (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4332   "TARGET_ARCH64"
4333   "addx\t%r1, %2, %0"
4334   [(set_attr "type" "ialuX")])
4336 (define_insn_and_split ""
4337   [(set (match_operand:DI 0 "register_operand" "=r")
4338         (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4339                  (match_operand:DI 2 "register_operand" "r")))
4340    (clobber (reg:CC 100))]
4341   "! TARGET_ARCH64"
4342   "#"
4343   "&& reload_completed"
4344   [(parallel [(set (reg:CC_NOOV 100)
4345                    (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
4346                                     (const_int 0)))
4347               (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
4348    (set (match_dup 6)
4349         (plus:SI (plus:SI (match_dup 4) (const_int 0))
4350                  (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4351   "operands[3] = gen_lowpart (SImode, operands[2]);
4352    operands[4] = gen_highpart (SImode, operands[2]);
4353    operands[5] = gen_lowpart (SImode, operands[0]);
4354    operands[6] = gen_highpart (SImode, operands[0]);"
4355   [(set_attr "length" "2")])
4357 (define_insn "*adddi3_sp64"
4358   [(set (match_operand:DI 0 "register_operand" "=r,r")
4359         (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
4360                  (match_operand:DI 2 "arith_add_operand" "rI,O")))]
4361   "TARGET_ARCH64"
4362   "@
4363    add\t%1, %2, %0
4364    sub\t%1, -%2, %0")
4366 (define_insn "addsi3"
4367   [(set (match_operand:SI 0 "register_operand" "=r,r,d")
4368         (plus:SI (match_operand:SI 1 "register_operand" "%r,r,d")
4369                  (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
4370   ""
4371   "@
4372    add\t%1, %2, %0
4373    sub\t%1, -%2, %0
4374    fpadd32s\t%1, %2, %0"
4375   [(set_attr "type" "*,*,fga")
4376    (set_attr "fptype" "*,*,single")])
4378 (define_insn "*cmp_cc_plus"
4379   [(set (reg:CC_NOOV 100)
4380         (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
4381                                   (match_operand:SI 1 "arith_operand" "rI"))
4382                          (const_int 0)))]
4383   ""
4384   "addcc\t%0, %1, %%g0"
4385   [(set_attr "type" "compare")])
4387 (define_insn "*cmp_ccx_plus"
4388   [(set (reg:CCX_NOOV 100)
4389         (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_operand" "%r")
4390                                    (match_operand:DI 1 "arith_operand" "rI"))
4391                           (const_int 0)))]
4392   "TARGET_ARCH64"
4393   "addcc\t%0, %1, %%g0"
4394   [(set_attr "type" "compare")])
4396 (define_insn "*cmp_cc_plus_set"
4397   [(set (reg:CC_NOOV 100)
4398         (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4399                                   (match_operand:SI 2 "arith_operand" "rI"))
4400                          (const_int 0)))
4401    (set (match_operand:SI 0 "register_operand" "=r")
4402         (plus:SI (match_dup 1) (match_dup 2)))]
4403   ""
4404   "addcc\t%1, %2, %0"
4405   [(set_attr "type" "compare")])
4407 (define_insn "*cmp_ccx_plus_set"
4408   [(set (reg:CCX_NOOV 100)
4409         (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_operand" "%r")
4410                                    (match_operand:DI 2 "arith_operand" "rI"))
4411                           (const_int 0)))
4412    (set (match_operand:DI 0 "register_operand" "=r")
4413         (plus:DI (match_dup 1) (match_dup 2)))]
4414   "TARGET_ARCH64"
4415   "addcc\t%1, %2, %0"
4416   [(set_attr "type" "compare")])
4418 (define_expand "subdi3"
4419   [(set (match_operand:DI 0 "register_operand" "")
4420         (minus:DI (match_operand:DI 1 "register_operand" "")
4421                   (match_operand:DI 2 "arith_double_add_operand" "")))]
4422   ""
4424   if (! TARGET_ARCH64)
4425     {
4426       emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4427                           gen_rtx_SET (VOIDmode, operands[0],
4428                                    gen_rtx_MINUS (DImode, operands[1],
4429                                                   operands[2])),
4430                           gen_rtx_CLOBBER (VOIDmode,
4431                                    gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4432       DONE;
4433     }
4436 (define_insn_and_split "subdi3_insn_sp32"
4437   [(set (match_operand:DI 0 "register_operand" "=r")
4438         (minus:DI (match_operand:DI 1 "register_operand" "r")
4439                   (match_operand:DI 2 "arith_double_operand" "rHI")))
4440    (clobber (reg:CC 100))]
4441   "! TARGET_ARCH64"
4442   "#"
4443   "&& reload_completed"
4444   [(parallel [(set (reg:CC_NOOV 100)
4445                    (compare:CC_NOOV (minus:SI (match_dup 4)
4446                                               (match_dup 5))
4447                                     (const_int 0)))
4448               (set (match_dup 3)
4449                    (minus:SI (match_dup 4) (match_dup 5)))])
4450    (set (match_dup 6)
4451         (minus:SI (minus:SI (match_dup 7)
4452                             (match_dup 8))
4453                   (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4455   operands[3] = gen_lowpart (SImode, operands[0]);
4456   operands[4] = gen_lowpart (SImode, operands[1]);
4457   operands[5] = gen_lowpart (SImode, operands[2]);
4458   operands[6] = gen_highpart (SImode, operands[0]);
4459   operands[7] = gen_highpart (SImode, operands[1]);
4460 #if HOST_BITS_PER_WIDE_INT == 32
4461   if (GET_CODE (operands[2]) == CONST_INT)
4462     {
4463       if (INTVAL (operands[2]) < 0)
4464         operands[8] = constm1_rtx;
4465       else
4466         operands[8] = const0_rtx;
4467     }
4468   else
4469 #endif
4470     operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4472   [(set_attr "length" "2")])
4474 ;; LTU here means "carry set"
4475 (define_insn "subx"
4476   [(set (match_operand:SI 0 "register_operand" "=r")
4477         (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4478                             (match_operand:SI 2 "arith_operand" "rI"))
4479                   (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4480   ""
4481   "subx\t%r1, %2, %0"
4482   [(set_attr "type" "ialuX")])
4484 (define_insn "*subx_extend_sp64"
4485   [(set (match_operand:DI 0 "register_operand" "=r")
4486         (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4487                                             (match_operand:SI 2 "arith_operand" "rI"))
4488                                   (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4489   "TARGET_ARCH64"
4490   "subx\t%r1, %2, %0"
4491   [(set_attr "type" "ialuX")])
4493 (define_insn_and_split "*subx_extend"
4494   [(set (match_operand:DI 0 "register_operand" "=r")
4495         (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4496                                             (match_operand:SI 2 "arith_operand" "rI"))
4497                                   (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4498   "! TARGET_ARCH64"
4499   "#"
4500   "&& reload_completed"
4501   [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
4502                                 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4503    (set (match_dup 4) (const_int 0))]
4504   "operands[3] = gen_lowpart (SImode, operands[0]);
4505    operands[4] = gen_highpart (SImode, operands[0]);"
4506   [(set_attr "length" "2")])
4508 (define_insn_and_split ""
4509   [(set (match_operand:DI 0 "register_operand" "=r")
4510       (minus:DI (match_operand:DI 1 "register_operand" "r")
4511                 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
4512    (clobber (reg:CC 100))]
4513   "! TARGET_ARCH64"
4514   "#"
4515   "&& reload_completed"
4516   [(parallel [(set (reg:CC_NOOV 100)
4517                    (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
4518                                     (const_int 0)))
4519               (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
4520    (set (match_dup 6)
4521         (minus:SI (minus:SI (match_dup 4) (const_int 0))
4522                   (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4523   "operands[3] = gen_lowpart (SImode, operands[1]);
4524    operands[4] = gen_highpart (SImode, operands[1]);
4525    operands[5] = gen_lowpart (SImode, operands[0]);
4526    operands[6] = gen_highpart (SImode, operands[0]);"
4527   [(set_attr "length" "2")])
4529 (define_insn "*subdi3_sp64"
4530   [(set (match_operand:DI 0 "register_operand" "=r,r")
4531         (minus:DI (match_operand:DI 1 "register_operand" "r,r")
4532                   (match_operand:DI 2 "arith_add_operand" "rI,O")))]
4533   "TARGET_ARCH64"
4534   "@
4535    sub\t%1, %2, %0
4536    add\t%1, -%2, %0")
4538 (define_insn "subsi3"
4539   [(set (match_operand:SI 0 "register_operand" "=r,r,d")
4540         (minus:SI (match_operand:SI 1 "register_operand" "r,r,d")
4541                   (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
4542   ""
4543   "@
4544    sub\t%1, %2, %0
4545    add\t%1, -%2, %0
4546    fpsub32s\t%1, %2, %0"
4547   [(set_attr "type" "*,*,fga")
4548    (set_attr "fptype" "*,*,single")])
4550 (define_insn "*cmp_minus_cc"
4551   [(set (reg:CC_NOOV 100)
4552         (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
4553                                    (match_operand:SI 1 "arith_operand" "rI"))
4554                          (const_int 0)))]
4555   ""
4556   "subcc\t%r0, %1, %%g0"
4557   [(set_attr "type" "compare")])
4559 (define_insn "*cmp_minus_ccx"
4560   [(set (reg:CCX_NOOV 100)
4561         (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
4562                                     (match_operand:DI 1 "arith_operand" "rI"))
4563                           (const_int 0)))]
4564   "TARGET_ARCH64"
4565   "subcc\t%0, %1, %%g0"
4566   [(set_attr "type" "compare")])
4568 (define_insn "cmp_minus_cc_set"
4569   [(set (reg:CC_NOOV 100)
4570         (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4571                                    (match_operand:SI 2 "arith_operand" "rI"))
4572                          (const_int 0)))
4573    (set (match_operand:SI 0 "register_operand" "=r")
4574         (minus:SI (match_dup 1) (match_dup 2)))]
4575   ""
4576   "subcc\t%r1, %2, %0"
4577   [(set_attr "type" "compare")])
4579 (define_insn "*cmp_minus_ccx_set"
4580   [(set (reg:CCX_NOOV 100)
4581         (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
4582                                     (match_operand:DI 2 "arith_operand" "rI"))
4583                           (const_int 0)))
4584    (set (match_operand:DI 0 "register_operand" "=r")
4585         (minus:DI (match_dup 1) (match_dup 2)))]
4586   "TARGET_ARCH64"
4587   "subcc\t%1, %2, %0"
4588   [(set_attr "type" "compare")])
4591 ;; Integer multiply/divide instructions.
4593 ;; The 32 bit multiply/divide instructions are deprecated on v9, but at
4594 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
4596 (define_insn "mulsi3"
4597   [(set (match_operand:SI 0 "register_operand" "=r")
4598         (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4599                  (match_operand:SI 2 "arith_operand" "rI")))]
4600   "TARGET_HARD_MUL"
4601   "smul\t%1, %2, %0"
4602   [(set_attr "type" "imul")])
4604 (define_expand "muldi3"
4605   [(set (match_operand:DI 0 "register_operand" "")
4606         (mult:DI (match_operand:DI 1 "arith_operand" "")
4607                  (match_operand:DI 2 "arith_operand" "")))]
4608   "TARGET_ARCH64 || TARGET_V8PLUS"
4610   if (TARGET_V8PLUS)
4611     {
4612       emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
4613       DONE;
4614     }
4617 (define_insn "*muldi3_sp64"
4618   [(set (match_operand:DI 0 "register_operand" "=r")
4619         (mult:DI (match_operand:DI 1 "arith_operand" "%r")
4620                  (match_operand:DI 2 "arith_operand" "rI")))]
4621   "TARGET_ARCH64"
4622   "mulx\t%1, %2, %0"
4623   [(set_attr "type" "imul")])
4625 ;; V8plus wide multiply.
4626 ;; XXX
4627 (define_insn "muldi3_v8plus"
4628   [(set (match_operand:DI 0 "register_operand" "=r,h")
4629         (mult:DI (match_operand:DI 1 "arith_operand" "%r,0")
4630                  (match_operand:DI 2 "arith_operand" "rI,rI")))
4631    (clobber (match_scratch:SI 3 "=&h,X"))
4632    (clobber (match_scratch:SI 4 "=&h,X"))]
4633   "TARGET_V8PLUS"
4635   if (sparc_check_64 (operands[1], insn) <= 0)
4636     output_asm_insn ("srl\t%L1, 0, %L1", operands);
4637   if (which_alternative == 1)
4638     output_asm_insn ("sllx\t%H1, 32, %H1", operands);
4639   if (GET_CODE (operands[2]) == CONST_INT)
4640     {
4641       if (which_alternative == 1)
4642         return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %2, %L0\;srlx\t%L0, 32, %H0";
4643       else
4644         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";
4645     }
4646   else if (rtx_equal_p (operands[1], operands[2]))
4647     {
4648       if (which_alternative == 1)
4649         return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %H1, %L0\;srlx\t%L0, 32, %H0";
4650       else
4651         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";
4652     }
4653   if (sparc_check_64 (operands[2], insn) <= 0)
4654     output_asm_insn ("srl\t%L2, 0, %L2", operands);
4655   if (which_alternative == 1)
4656     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";
4657   else
4658     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";
4660   [(set_attr "type" "multi")
4661    (set_attr "length" "9,8")])
4663 (define_insn "*cmp_mul_set"
4664   [(set (reg:CC 100)
4665         (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4666                     (match_operand:SI 2 "arith_operand" "rI"))
4667                     (const_int 0)))
4668    (set (match_operand:SI 0 "register_operand" "=r")
4669         (mult:SI (match_dup 1) (match_dup 2)))]
4670   "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
4671   "smulcc\t%1, %2, %0"
4672   [(set_attr "type" "imul")])
4674 (define_expand "mulsidi3"
4675   [(set (match_operand:DI 0 "register_operand" "")
4676         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4677                  (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
4678   "TARGET_HARD_MUL"
4680   if (CONSTANT_P (operands[2]))
4681     {
4682       if (TARGET_V8PLUS)
4683         emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
4684                                               operands[2]));
4685       else if (TARGET_ARCH32)
4686         emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
4687                                             operands[2]));
4688       else 
4689         emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
4690                                             operands[2]));
4691       DONE;
4692     }
4693   if (TARGET_V8PLUS)
4694     {
4695       emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
4696       DONE;
4697     }
4700 ;; V9 puts the 64 bit product in a 64 bit register.  Only out or global
4701 ;; registers can hold 64 bit values in the V8plus environment.
4702 ;; XXX
4703 (define_insn "mulsidi3_v8plus"
4704   [(set (match_operand:DI 0 "register_operand" "=h,r")
4705         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4706                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4707    (clobber (match_scratch:SI 3 "=X,&h"))]
4708   "TARGET_V8PLUS"
4709   "@
4710    smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4711    smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4712   [(set_attr "type" "multi")
4713    (set_attr "length" "2,3")])
4715 ;; XXX
4716 (define_insn "const_mulsidi3_v8plus"
4717   [(set (match_operand:DI 0 "register_operand" "=h,r")
4718         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4719                  (match_operand:DI 2 "small_int_operand" "I,I")))
4720    (clobber (match_scratch:SI 3 "=X,&h"))]
4721   "TARGET_V8PLUS"
4722   "@
4723    smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4724    smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4725   [(set_attr "type" "multi")
4726    (set_attr "length" "2,3")])
4728 ;; XXX
4729 (define_insn "*mulsidi3_sp32"
4730   [(set (match_operand:DI 0 "register_operand" "=r")
4731         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4732                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4733   "TARGET_HARD_MUL32"
4735   return TARGET_SPARCLET
4736          ? "smuld\t%1, %2, %L0"
4737          : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4739   [(set (attr "type")
4740         (if_then_else (eq_attr "isa" "sparclet")
4741                       (const_string "imul") (const_string "multi")))
4742    (set (attr "length")
4743         (if_then_else (eq_attr "isa" "sparclet")
4744                       (const_int 1) (const_int 2)))])
4746 (define_insn "*mulsidi3_sp64"
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_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4751   "smul\t%1, %2, %0"
4752   [(set_attr "type" "imul")])
4754 ;; Extra pattern, because sign_extend of a constant isn't valid.
4756 ;; XXX
4757 (define_insn "const_mulsidi3_sp32"
4758   [(set (match_operand:DI 0 "register_operand" "=r")
4759         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4760                  (match_operand:DI 2 "small_int_operand" "I")))]
4761   "TARGET_HARD_MUL32"
4763   return TARGET_SPARCLET
4764          ? "smuld\t%1, %2, %L0"
4765          : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4767   [(set (attr "type")
4768         (if_then_else (eq_attr "isa" "sparclet")
4769                       (const_string "imul") (const_string "multi")))
4770    (set (attr "length")
4771         (if_then_else (eq_attr "isa" "sparclet")
4772                       (const_int 1) (const_int 2)))])
4774 (define_insn "const_mulsidi3_sp64"
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_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4779   "smul\t%1, %2, %0"
4780   [(set_attr "type" "imul")])
4782 (define_expand "smulsi3_highpart"
4783   [(set (match_operand:SI 0 "register_operand" "")
4784         (truncate:SI
4785          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4786                                (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
4787                       (const_int 32))))]
4788   "TARGET_HARD_MUL && TARGET_ARCH32"
4790   if (CONSTANT_P (operands[2]))
4791     {
4792       if (TARGET_V8PLUS)
4793         {
4794           emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
4795                                                         operands[1],
4796                                                         operands[2],
4797                                                         GEN_INT (32)));
4798           DONE;
4799         }
4800       emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
4801       DONE;
4802     }
4803   if (TARGET_V8PLUS)
4804     {
4805       emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
4806                                               operands[2], GEN_INT (32)));
4807       DONE;
4808     }
4811 ;; XXX
4812 (define_insn "smulsi3_highpart_v8plus"
4813   [(set (match_operand:SI 0 "register_operand" "=h,r")
4814         (truncate:SI
4815          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4816                                (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4817                       (match_operand:SI 3 "small_int_operand" "I,I"))))
4818    (clobber (match_scratch:SI 4 "=X,&h"))]
4819   "TARGET_V8PLUS"
4820   "@
4821    smul\t%1, %2, %0\;srlx\t%0, %3, %0
4822    smul\t%1, %2, %4\;srlx\t%4, %3, %0"
4823   [(set_attr "type" "multi")
4824    (set_attr "length" "2")])
4826 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
4827 ;; XXX
4828 (define_insn ""
4829   [(set (match_operand:SI 0 "register_operand" "=h,r")
4830         (subreg:SI
4831          (lshiftrt:DI
4832           (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          4))
4836    (clobber (match_scratch:SI 4 "=X,&h"))]
4837   "TARGET_V8PLUS"
4838   "@
4839    smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4840    smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4841   [(set_attr "type" "multi")
4842    (set_attr "length" "2")])
4844 ;; XXX
4845 (define_insn "const_smulsi3_highpart_v8plus"
4846   [(set (match_operand:SI 0 "register_operand" "=h,r")
4847         (truncate:SI
4848          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4849                                (match_operand:DI 2 "small_int_operand" "I,I"))
4850                       (match_operand:SI 3 "small_int_operand" "I,I"))))
4851    (clobber (match_scratch:SI 4 "=X,&h"))]
4852   "TARGET_V8PLUS"
4853   "@
4854    smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4855    smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4856   [(set_attr "type" "multi")
4857    (set_attr "length" "2")])
4859 ;; XXX
4860 (define_insn "*smulsi3_highpart_sp32"
4861   [(set (match_operand:SI 0 "register_operand" "=r")
4862         (truncate:SI
4863          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4864                                (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
4865                       (const_int 32))))]
4866   "TARGET_HARD_MUL32"
4867   "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4868   [(set_attr "type" "multi")
4869    (set_attr "length" "2")])
4871 ;; XXX
4872 (define_insn "const_smulsi3_highpart"
4873   [(set (match_operand:SI 0 "register_operand" "=r")
4874         (truncate:SI
4875          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4876                                (match_operand:DI 2 "small_int_operand" "i"))
4877                       (const_int 32))))]
4878   "TARGET_HARD_MUL32"
4879   "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4880   [(set_attr "type" "multi")
4881    (set_attr "length" "2")])
4883 (define_expand "umulsidi3"
4884   [(set (match_operand:DI 0 "register_operand" "")
4885         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4886                  (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
4887   "TARGET_HARD_MUL"
4889   if (CONSTANT_P (operands[2]))
4890     {
4891       if (TARGET_V8PLUS)
4892         emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
4893                                                operands[2]));
4894       else if (TARGET_ARCH32)
4895         emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
4896                                              operands[2]));
4897       else 
4898         emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
4899                                              operands[2]));
4900       DONE;
4901     }
4902   if (TARGET_V8PLUS)
4903     {
4904       emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
4905       DONE;
4906     }
4909 ;; XXX
4910 (define_insn "umulsidi3_v8plus"
4911   [(set (match_operand:DI 0 "register_operand" "=h,r")
4912         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4913                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4914    (clobber (match_scratch:SI 3 "=X,&h"))]
4915   "TARGET_V8PLUS"
4916   "@
4917    umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4918    umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4919   [(set_attr "type" "multi")
4920    (set_attr "length" "2,3")])
4922 ;; XXX
4923 (define_insn "*umulsidi3_sp32"
4924   [(set (match_operand:DI 0 "register_operand" "=r")
4925         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4926                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4927   "TARGET_HARD_MUL32"
4929   return TARGET_SPARCLET
4930          ? "umuld\t%1, %2, %L0"
4931          : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
4933   [(set (attr "type")
4934         (if_then_else (eq_attr "isa" "sparclet")
4935                       (const_string "imul") (const_string "multi")))
4936    (set (attr "length")
4937         (if_then_else (eq_attr "isa" "sparclet")
4938                       (const_int 1) (const_int 2)))])
4940 (define_insn "*umulsidi3_sp64"
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_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4945   "umul\t%1, %2, %0"
4946   [(set_attr "type" "imul")])
4948 ;; Extra pattern, because sign_extend of a constant isn't valid.
4950 ;; XXX
4951 (define_insn "const_umulsidi3_sp32"
4952   [(set (match_operand:DI 0 "register_operand" "=r")
4953         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4954                  (match_operand:DI 2 "uns_small_int_operand" "")))]
4955   "TARGET_HARD_MUL32"
4957   return TARGET_SPARCLET
4958          ? "umuld\t%1, %s2, %L0"
4959          : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
4961   [(set (attr "type")
4962         (if_then_else (eq_attr "isa" "sparclet")
4963                       (const_string "imul") (const_string "multi")))
4964    (set (attr "length")
4965         (if_then_else (eq_attr "isa" "sparclet")
4966                       (const_int 1) (const_int 2)))])
4968 (define_insn "const_umulsidi3_sp64"
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_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4973   "umul\t%1, %s2, %0"
4974   [(set_attr "type" "imul")])
4976 ;; XXX
4977 (define_insn "const_umulsidi3_v8plus"
4978   [(set (match_operand:DI 0 "register_operand" "=h,r")
4979         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4980                  (match_operand:DI 2 "uns_small_int_operand" "")))
4981    (clobber (match_scratch:SI 3 "=X,h"))]
4982   "TARGET_V8PLUS"
4983   "@
4984    umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
4985    umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4986   [(set_attr "type" "multi")
4987    (set_attr "length" "2,3")])
4989 (define_expand "umulsi3_highpart"
4990   [(set (match_operand:SI 0 "register_operand" "")
4991         (truncate:SI
4992          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4993                                (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
4994                       (const_int 32))))]
4995   "TARGET_HARD_MUL && TARGET_ARCH32"
4997   if (CONSTANT_P (operands[2]))
4998     {
4999       if (TARGET_V8PLUS)
5000         {
5001           emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
5002                                                         operands[1],
5003                                                         operands[2],
5004                                                         GEN_INT (32)));
5005           DONE;
5006         }
5007       emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
5008       DONE;
5009     }
5010   if (TARGET_V8PLUS)
5011     {
5012       emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
5013                                               operands[2], GEN_INT (32)));
5014       DONE;
5015     }
5018 ;; XXX
5019 (define_insn "umulsi3_highpart_v8plus"
5020   [(set (match_operand:SI 0 "register_operand" "=h,r")
5021         (truncate:SI
5022          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5023                                (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5024                       (match_operand:SI 3 "small_int_operand" "I,I"))))
5025    (clobber (match_scratch:SI 4 "=X,h"))]
5026   "TARGET_V8PLUS"
5027   "@
5028    umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5029    umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5030   [(set_attr "type" "multi")
5031    (set_attr "length" "2")])
5033 ;; XXX
5034 (define_insn "const_umulsi3_highpart_v8plus"
5035   [(set (match_operand:SI 0 "register_operand" "=h,r")
5036         (truncate:SI
5037          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5038                                (match_operand:DI 2 "uns_small_int_operand" ""))
5039                       (match_operand:SI 3 "small_int_operand" "I,I"))))
5040    (clobber (match_scratch:SI 4 "=X,h"))]
5041   "TARGET_V8PLUS"
5042   "@
5043    umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
5044    umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
5045   [(set_attr "type" "multi")
5046    (set_attr "length" "2")])
5048 ;; XXX
5049 (define_insn "*umulsi3_highpart_sp32"
5050   [(set (match_operand:SI 0 "register_operand" "=r")
5051         (truncate:SI
5052          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5053                                (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
5054                       (const_int 32))))]
5055   "TARGET_HARD_MUL32"
5056   "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
5057   [(set_attr "type" "multi")
5058    (set_attr "length" "2")])
5060 ;; XXX
5061 (define_insn "const_umulsi3_highpart"
5062   [(set (match_operand:SI 0 "register_operand" "=r")
5063         (truncate:SI
5064          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5065                                (match_operand:DI 2 "uns_small_int_operand" ""))
5066                       (const_int 32))))]
5067   "TARGET_HARD_MUL32"
5068   "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
5069   [(set_attr "type" "multi")
5070    (set_attr "length" "2")])
5072 ;; The V8 architecture specifies that there must be 3 instructions between
5073 ;; a Y register write and a use of it for correct results.
5075 (define_expand "divsi3"
5076   [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
5077                    (div:SI (match_operand:SI 1 "register_operand" "r,r")
5078                            (match_operand:SI 2 "input_operand" "rI,m")))
5079               (clobber (match_scratch:SI 3 "=&r,&r"))])]
5080   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5082   if (TARGET_ARCH64)
5083     {
5084       operands[3] = gen_reg_rtx(SImode);
5085       emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
5086       emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
5087                                   operands[3]));
5088       DONE;
5089     }
5092 (define_insn "divsi3_sp32"
5093   [(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)
5098    && TARGET_ARCH32"
5100   if (which_alternative == 0)
5101     if (TARGET_V9)
5102       return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdiv\t%1, %2, %0";
5103     else
5104       return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
5105   else
5106     if (TARGET_V9)
5107       return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tld\t%2, %3\n\tsdiv\t%1, %3, %0";
5108     else
5109       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";
5111   [(set_attr "type" "multi")
5112    (set (attr "length")
5113         (if_then_else (eq_attr "isa" "v9")
5114                       (const_int 4) (const_int 6)))])
5116 (define_insn "divsi3_sp64"
5117   [(set (match_operand:SI 0 "register_operand" "=r")
5118         (div:SI (match_operand:SI 1 "register_operand" "r")
5119                 (match_operand:SI 2 "input_operand" "rI")))
5120    (use (match_operand:SI 3 "register_operand" "r"))]
5121   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5122   "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
5123   [(set_attr "type" "multi")
5124    (set_attr "length" "2")])
5126 (define_insn "divdi3"
5127   [(set (match_operand:DI 0 "register_operand" "=r")
5128         (div:DI (match_operand:DI 1 "register_operand" "r")
5129                 (match_operand:DI 2 "arith_operand" "rI")))]
5130   "TARGET_ARCH64"
5131   "sdivx\t%1, %2, %0"
5132   [(set_attr "type" "idiv")])
5134 (define_insn "*cmp_sdiv_cc_set"
5135   [(set (reg:CC 100)
5136         (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
5137                             (match_operand:SI 2 "arith_operand" "rI"))
5138                     (const_int 0)))
5139    (set (match_operand:SI 0 "register_operand" "=r")
5140         (div:SI (match_dup 1) (match_dup 2)))
5141    (clobber (match_scratch:SI 3 "=&r"))]
5142   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5144   if (TARGET_V9)
5145     return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdivcc\t%1, %2, %0";
5146   else
5147     return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
5149   [(set_attr "type" "multi")
5150    (set (attr "length")
5151         (if_then_else (eq_attr "isa" "v9")
5152                       (const_int 3) (const_int 6)))])
5154 ;; XXX
5155 (define_expand "udivsi3"
5156   [(set (match_operand:SI 0 "register_operand" "")
5157         (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "")
5158                  (match_operand:SI 2 "input_operand" "")))]
5159   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5160   "")
5162 ;; The V8 architecture specifies that there must be 3 instructions between
5163 ;; a Y register write and a use of it for correct results.
5165 (define_insn "udivsi3_sp32"
5166   [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
5167         (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r,r,m")
5168                  (match_operand:SI 2 "input_operand" "rI,m,r")))]
5169   "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
5170    && TARGET_ARCH32"
5172   output_asm_insn ("wr\t%%g0, %%g0, %%y", operands);
5173   switch (which_alternative)
5174     {
5175     default:
5176       return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
5177     case 1:
5178       return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
5179     case 2:
5180       return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
5181     }
5183   [(set_attr "type" "multi")
5184    (set_attr "length" "5")])
5186 (define_insn "udivsi3_sp64"
5187   [(set (match_operand:SI 0 "register_operand" "=r")
5188         (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r")
5189                  (match_operand:SI 2 "input_operand" "rI")))]
5190   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5191   "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
5192   [(set_attr "type" "multi")
5193    (set_attr "length" "2")])
5195 (define_insn "udivdi3"
5196   [(set (match_operand:DI 0 "register_operand" "=r")
5197         (udiv:DI (match_operand:DI 1 "register_operand" "r")
5198                  (match_operand:DI 2 "arith_operand" "rI")))]
5199   "TARGET_ARCH64"
5200   "udivx\t%1, %2, %0"
5201   [(set_attr "type" "idiv")])
5203 (define_insn "*cmp_udiv_cc_set"
5204   [(set (reg:CC 100)
5205         (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
5206                              (match_operand:SI 2 "arith_operand" "rI"))
5207                     (const_int 0)))
5208    (set (match_operand:SI 0 "register_operand" "=r")
5209         (udiv:SI (match_dup 1) (match_dup 2)))]
5210   "TARGET_V8
5211    || TARGET_DEPRECATED_V8_INSNS"
5213   if (TARGET_V9)
5214     return "wr\t%%g0, %%g0, %%y\n\tudivcc\t%1, %2, %0";
5215   else
5216     return "wr\t%%g0, %%g0, %%y\n\tnop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
5218   [(set_attr "type" "multi")
5219    (set (attr "length")
5220         (if_then_else (eq_attr "isa" "v9")
5221                       (const_int 2) (const_int 5)))])
5223 ; sparclet multiply/accumulate insns
5225 (define_insn "*smacsi"
5226   [(set (match_operand:SI 0 "register_operand" "=r")
5227         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
5228                           (match_operand:SI 2 "arith_operand" "rI"))
5229                  (match_operand:SI 3 "register_operand" "0")))]
5230   "TARGET_SPARCLET"
5231   "smac\t%1, %2, %0"
5232   [(set_attr "type" "imul")])
5234 (define_insn "*smacdi"
5235   [(set (match_operand:DI 0 "register_operand" "=r")
5236         (plus:DI (mult:DI (sign_extend:DI
5237                            (match_operand:SI 1 "register_operand" "%r"))
5238                           (sign_extend:DI
5239                            (match_operand:SI 2 "register_operand" "r")))
5240                  (match_operand:DI 3 "register_operand" "0")))]
5241   "TARGET_SPARCLET"
5242   "smacd\t%1, %2, %L0"
5243   [(set_attr "type" "imul")])
5245 (define_insn "*umacdi"
5246   [(set (match_operand:DI 0 "register_operand" "=r")
5247         (plus:DI (mult:DI (zero_extend:DI
5248                            (match_operand:SI 1 "register_operand" "%r"))
5249                           (zero_extend:DI
5250                            (match_operand:SI 2 "register_operand" "r")))
5251                  (match_operand:DI 3 "register_operand" "0")))]
5252   "TARGET_SPARCLET"
5253   "umacd\t%1, %2, %L0"
5254   [(set_attr "type" "imul")])
5257 ;; Boolean instructions.
5259 ;; We define DImode `and' so with DImode `not' we can get
5260 ;; DImode `andn'.  Other combinations are possible.
5262 (define_mode_macro V64I [DI V2SI V4HI V8QI])
5263 (define_mode_macro V32I [SI V2HI V4QI])
5265 (define_expand "and<V64I:mode>3"
5266   [(set (match_operand:V64I 0 "register_operand" "")
5267         (and:V64I (match_operand:V64I 1 "arith_double_operand" "")
5268                   (match_operand:V64I 2 "arith_double_operand" "")))]
5269   ""
5270   "")
5272 (define_insn "*and<V64I:mode>3_sp32"
5273   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5274         (and:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5275                   (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5276   "! TARGET_ARCH64"
5277   "@
5278   #
5279   fand\t%1, %2, %0"
5280   [(set_attr "type" "*,fga")
5281    (set_attr "length" "2,*")
5282    (set_attr "fptype" "*,double")])
5284 (define_insn "*and<V64I:mode>3_sp64"
5285   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5286         (and:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
5287                   (match_operand:V64I 2 "arith_operand" "rI,b")))]
5288   "TARGET_ARCH64"
5289   "@
5290    and\t%1, %2, %0
5291    fand\t%1, %2, %0"
5292   [(set_attr "type" "*,fga")
5293    (set_attr "fptype" "*,double")])
5295 (define_insn "and<V32I:mode>3"
5296   [(set (match_operand:V32I 0 "register_operand" "=r,d")
5297         (and:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
5298                   (match_operand:V32I 2 "arith_operand" "rI,d")))]
5299   ""
5300   "@
5301    and\t%1, %2, %0
5302    fands\t%1, %2, %0"
5303   [(set_attr "type" "*,fga")
5304    (set_attr "fptype" "*,single")])
5306 (define_split
5307   [(set (match_operand:SI 0 "register_operand" "")
5308         (and:SI (match_operand:SI 1 "register_operand" "")
5309                 (match_operand:SI 2 "const_compl_high_operand" "")))
5310    (clobber (match_operand:SI 3 "register_operand" ""))]
5311   ""
5312   [(set (match_dup 3) (match_dup 4))
5313    (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
5315   operands[4] = GEN_INT (~INTVAL (operands[2]));
5318 (define_insn_and_split "*and_not_<V64I:mode>_sp32"
5319   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5320         (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
5321                   (match_operand:V64I 2 "register_operand" "r,b")))]
5322   "! TARGET_ARCH64"
5323   "@
5324    #
5325    fandnot1\t%1, %2, %0"
5326   "&& reload_completed
5327    && ((GET_CODE (operands[0]) == REG
5328         && REGNO (operands[0]) < 32)
5329        || (GET_CODE (operands[0]) == SUBREG
5330            && GET_CODE (SUBREG_REG (operands[0])) == REG
5331            && REGNO (SUBREG_REG (operands[0])) < 32))"
5332   [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
5333    (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
5334   "operands[3] = gen_highpart (SImode, operands[0]);
5335    operands[4] = gen_highpart (SImode, operands[1]);
5336    operands[5] = gen_highpart (SImode, operands[2]);
5337    operands[6] = gen_lowpart (SImode, operands[0]);
5338    operands[7] = gen_lowpart (SImode, operands[1]);
5339    operands[8] = gen_lowpart (SImode, operands[2]);"
5340   [(set_attr "type" "*,fga")
5341    (set_attr "length" "2,*")
5342    (set_attr "fptype" "*,double")])
5344 (define_insn "*and_not_<V64I:mode>_sp64"
5345   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5346         (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
5347                   (match_operand:V64I 2 "register_operand" "r,b")))]
5348   "TARGET_ARCH64"
5349   "@
5350    andn\t%2, %1, %0
5351    fandnot1\t%1, %2, %0"
5352   [(set_attr "type" "*,fga")
5353    (set_attr "fptype" "*,double")])
5355 (define_insn "*and_not_<V32I:mode>"
5356   [(set (match_operand:V32I 0 "register_operand" "=r,d")
5357         (and:V32I (not:V32I (match_operand:V32I 1 "register_operand" "%r,d"))
5358                   (match_operand:V32I 2 "register_operand" "r,d")))]
5359   ""
5360   "@
5361    andn\t%2, %1, %0
5362    fandnot1s\t%1, %2, %0"
5363   [(set_attr "type" "*,fga")
5364    (set_attr "fptype" "*,single")])
5366 (define_expand "ior<V64I:mode>3"
5367   [(set (match_operand:V64I 0 "register_operand" "")
5368         (ior:V64I (match_operand:V64I 1 "arith_double_operand" "")
5369                   (match_operand:V64I 2 "arith_double_operand" "")))]
5370   ""
5371   "")
5373 (define_insn "*ior<V64I:mode>3_sp32"
5374   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5375         (ior:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5376                   (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5377   "! TARGET_ARCH64"
5378   "@
5379   #
5380   for\t%1, %2, %0"
5381   [(set_attr "type" "*,fga")
5382    (set_attr "length" "2,*")
5383    (set_attr "fptype" "*,double")])
5385 (define_insn "*ior<V64I:mode>3_sp64"
5386   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5387         (ior:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
5388                   (match_operand:V64I 2 "arith_operand" "rI,b")))]
5389   "TARGET_ARCH64"
5390   "@
5391   or\t%1, %2, %0
5392   for\t%1, %2, %0"
5393   [(set_attr "type" "*,fga")
5394    (set_attr "fptype" "*,double")])
5396 (define_insn "ior<V32I:mode>3"
5397   [(set (match_operand:V32I 0 "register_operand" "=r,d")
5398         (ior:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
5399                   (match_operand:V32I 2 "arith_operand" "rI,d")))]
5400   ""
5401   "@
5402    or\t%1, %2, %0
5403    fors\t%1, %2, %0"
5404   [(set_attr "type" "*,fga")
5405    (set_attr "fptype" "*,single")])
5407 (define_split
5408   [(set (match_operand:SI 0 "register_operand" "")
5409         (ior:SI (match_operand:SI 1 "register_operand" "")
5410                 (match_operand:SI 2 "const_compl_high_operand" "")))
5411    (clobber (match_operand:SI 3 "register_operand" ""))]
5412   ""
5413   [(set (match_dup 3) (match_dup 4))
5414    (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
5416   operands[4] = GEN_INT (~INTVAL (operands[2]));
5419 (define_insn_and_split "*or_not_<V64I:mode>_sp32"
5420   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5421         (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
5422                   (match_operand:V64I 2 "register_operand" "r,b")))]
5423   "! TARGET_ARCH64"
5424   "@
5425    #
5426    fornot1\t%1, %2, %0"
5427   "&& reload_completed
5428    && ((GET_CODE (operands[0]) == REG
5429         && REGNO (operands[0]) < 32)
5430        || (GET_CODE (operands[0]) == SUBREG
5431            && GET_CODE (SUBREG_REG (operands[0])) == REG
5432            && REGNO (SUBREG_REG (operands[0])) < 32))"
5433   [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
5434    (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
5435   "operands[3] = gen_highpart (SImode, operands[0]);
5436    operands[4] = gen_highpart (SImode, operands[1]);
5437    operands[5] = gen_highpart (SImode, operands[2]);
5438    operands[6] = gen_lowpart (SImode, operands[0]);
5439    operands[7] = gen_lowpart (SImode, operands[1]);
5440    operands[8] = gen_lowpart (SImode, operands[2]);"
5441   [(set_attr "type" "*,fga")
5442    (set_attr "length" "2,*")
5443    (set_attr "fptype" "*,double")])
5445 (define_insn "*or_not_<V64I:mode>_sp64"
5446   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5447         (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
5448                   (match_operand:V64I 2 "register_operand" "r,b")))]
5449   "TARGET_ARCH64"
5450   "@
5451   orn\t%2, %1, %0
5452   fornot1\t%1, %2, %0"
5453   [(set_attr "type" "*,fga")
5454    (set_attr "fptype" "*,double")])
5456 (define_insn "*or_not_<V32I:mode>"
5457   [(set (match_operand:V32I 0 "register_operand" "=r,d")
5458         (ior:V32I (not:V32I (match_operand:V32I 1 "register_operand" "r,d"))
5459                   (match_operand:V32I 2 "register_operand" "r,d")))]
5460   ""
5461   "@
5462    orn\t%2, %1, %0
5463    fornot1s\t%1, %2, %0"
5464   [(set_attr "type" "*,fga")
5465    (set_attr "fptype" "*,single")])
5467 (define_expand "xor<V64I:mode>3"
5468   [(set (match_operand:V64I 0 "register_operand" "")
5469         (xor:V64I (match_operand:V64I 1 "arith_double_operand" "")
5470                   (match_operand:V64I 2 "arith_double_operand" "")))]
5471   ""
5472   "")
5474 (define_insn "*xor<V64I:mode>3_sp32"
5475   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5476         (xor:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5477                   (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5478   "! TARGET_ARCH64"
5479   "@
5480   #
5481   fxor\t%1, %2, %0"
5482   [(set_attr "type" "*,fga")
5483    (set_attr "length" "2,*")
5484    (set_attr "fptype" "*,double")])
5486 (define_insn "*xor<V64I:mode>3_sp64"
5487   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5488         (xor:V64I (match_operand:V64I 1 "arith_operand" "%rJ,b")
5489                   (match_operand:V64I 2 "arith_operand" "rI,b")))]
5490   "TARGET_ARCH64"
5491   "@
5492   xor\t%r1, %2, %0
5493   fxor\t%1, %2, %0"
5494   [(set_attr "type" "*,fga")
5495    (set_attr "fptype" "*,double")])
5497 (define_insn "xor<V32I:mode>3"
5498   [(set (match_operand:V32I 0 "register_operand" "=r,d")
5499         (xor:V32I (match_operand:V32I 1 "arith_operand" "%rJ,d")
5500                   (match_operand:V32I 2 "arith_operand" "rI,d")))]
5501   ""
5502   "@
5503    xor\t%r1, %2, %0
5504    fxors\t%1, %2, %0"
5505   [(set_attr "type" "*,fga")
5506    (set_attr "fptype" "*,single")])
5508 (define_split
5509   [(set (match_operand:SI 0 "register_operand" "")
5510         (xor:SI (match_operand:SI 1 "register_operand" "")
5511                 (match_operand:SI 2 "const_compl_high_operand" "")))
5512    (clobber (match_operand:SI 3 "register_operand" ""))]
5513    ""
5514   [(set (match_dup 3) (match_dup 4))
5515    (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
5517   operands[4] = GEN_INT (~INTVAL (operands[2]));
5520 (define_split
5521   [(set (match_operand:SI 0 "register_operand" "")
5522         (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
5523                         (match_operand:SI 2 "const_compl_high_operand" ""))))
5524    (clobber (match_operand:SI 3 "register_operand" ""))]
5525   ""
5526   [(set (match_dup 3) (match_dup 4))
5527    (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
5529   operands[4] = GEN_INT (~INTVAL (operands[2]));
5532 ;; Split DImode logical operations requiring two instructions.
5533 (define_split
5534   [(set (match_operand:V64I 0 "register_operand" "")
5535         (match_operator:V64I 1 "cc_arith_operator"      ; AND, IOR, XOR
5536                            [(match_operand:V64I 2 "register_operand" "")
5537                             (match_operand:V64I 3 "arith_double_operand" "")]))]
5538   "! TARGET_ARCH64
5539    && reload_completed
5540    && ((GET_CODE (operands[0]) == REG
5541         && REGNO (operands[0]) < 32)
5542        || (GET_CODE (operands[0]) == SUBREG
5543            && GET_CODE (SUBREG_REG (operands[0])) == REG
5544            && REGNO (SUBREG_REG (operands[0])) < 32))"
5545   [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
5546    (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
5548   operands[4] = gen_highpart (SImode, operands[0]);
5549   operands[5] = gen_lowpart (SImode, operands[0]);
5550   operands[6] = gen_highpart (SImode, operands[2]);
5551   operands[7] = gen_lowpart (SImode, operands[2]);
5552 #if HOST_BITS_PER_WIDE_INT == 32
5553   if (GET_CODE (operands[3]) == CONST_INT && <V64I:MODE>mode == DImode)
5554     {
5555       if (INTVAL (operands[3]) < 0)
5556         operands[8] = constm1_rtx;
5557       else
5558         operands[8] = const0_rtx;
5559     }
5560   else
5561 #endif
5562     operands[8] = gen_highpart_mode (SImode, <V64I:MODE>mode, operands[3]);
5563   operands[9] = gen_lowpart (SImode, operands[3]);
5566 ;; xnor patterns.  Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
5567 ;; Combine now canonicalizes to the rightmost expression.
5568 (define_insn_and_split "*xor_not_<V64I:mode>_sp32"
5569   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5570         (not:V64I (xor:V64I (match_operand:V64I 1 "register_operand" "r,b")
5571                             (match_operand:V64I 2 "register_operand" "r,b"))))]
5572   "! TARGET_ARCH64"
5573   "@
5574    #
5575    fxnor\t%1, %2, %0"
5576   "&& reload_completed
5577    && ((GET_CODE (operands[0]) == REG
5578         && REGNO (operands[0]) < 32)
5579        || (GET_CODE (operands[0]) == SUBREG
5580            && GET_CODE (SUBREG_REG (operands[0])) == REG
5581            && REGNO (SUBREG_REG (operands[0])) < 32))"
5582   [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
5583    (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
5584   "operands[3] = gen_highpart (SImode, operands[0]);
5585    operands[4] = gen_highpart (SImode, operands[1]);
5586    operands[5] = gen_highpart (SImode, operands[2]);
5587    operands[6] = gen_lowpart (SImode, operands[0]);
5588    operands[7] = gen_lowpart (SImode, operands[1]);
5589    operands[8] = gen_lowpart (SImode, operands[2]);"
5590   [(set_attr "type" "*,fga")
5591    (set_attr "length" "2,*")
5592    (set_attr "fptype" "*,double")])
5594 (define_insn "*xor_not_<V64I:mode>_sp64"
5595   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5596         (not:V64I (xor:V64I (match_operand:V64I 1 "register_or_zero_operand" "rJ,b")
5597                             (match_operand:V64I 2 "arith_operand" "rI,b"))))]
5598   "TARGET_ARCH64"
5599   "@
5600   xnor\t%r1, %2, %0
5601   fxnor\t%1, %2, %0"
5602   [(set_attr "type" "*,fga")
5603    (set_attr "fptype" "*,double")])
5605 (define_insn "*xor_not_<V32I:mode>"
5606   [(set (match_operand:V32I 0 "register_operand" "=r,d")
5607         (not:V32I (xor:V32I (match_operand:V32I 1 "register_or_zero_operand" "rJ,d")
5608                             (match_operand:V32I 2 "arith_operand" "rI,d"))))]
5609   ""
5610   "@
5611    xnor\t%r1, %2, %0
5612    fxnors\t%1, %2, %0"
5613   [(set_attr "type" "*,fga")
5614    (set_attr "fptype" "*,single")])
5616 ;; These correspond to the above in the case where we also (or only)
5617 ;; want to set the condition code.  
5619 (define_insn "*cmp_cc_arith_op"
5620   [(set (reg:CC 100)
5621         (compare:CC
5622          (match_operator:SI 2 "cc_arith_operator"
5623                             [(match_operand:SI 0 "arith_operand" "%r")
5624                              (match_operand:SI 1 "arith_operand" "rI")])
5625          (const_int 0)))]
5626   ""
5627   "%A2cc\t%0, %1, %%g0"
5628   [(set_attr "type" "compare")])
5630 (define_insn "*cmp_ccx_arith_op"
5631   [(set (reg:CCX 100)
5632         (compare:CCX
5633          (match_operator:DI 2 "cc_arith_operator"
5634                             [(match_operand:DI 0 "arith_operand" "%r")
5635                              (match_operand:DI 1 "arith_operand" "rI")])
5636          (const_int 0)))]
5637   "TARGET_ARCH64"
5638   "%A2cc\t%0, %1, %%g0"
5639   [(set_attr "type" "compare")])
5641 (define_insn "*cmp_cc_arith_op_set"
5642   [(set (reg:CC 100)
5643         (compare:CC
5644          (match_operator:SI 3 "cc_arith_operator"
5645                             [(match_operand:SI 1 "arith_operand" "%r")
5646                              (match_operand:SI 2 "arith_operand" "rI")])
5647          (const_int 0)))
5648    (set (match_operand:SI 0 "register_operand" "=r")
5649         (match_operator:SI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5650   "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5651   "%A3cc\t%1, %2, %0"
5652   [(set_attr "type" "compare")])
5654 (define_insn "*cmp_ccx_arith_op_set"
5655   [(set (reg:CCX 100)
5656         (compare:CCX
5657          (match_operator:DI 3 "cc_arith_operator"
5658                             [(match_operand:DI 1 "arith_operand" "%r")
5659                              (match_operand:DI 2 "arith_operand" "rI")])
5660          (const_int 0)))
5661    (set (match_operand:DI 0 "register_operand" "=r")
5662         (match_operator:DI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5663   "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5664   "%A3cc\t%1, %2, %0"
5665   [(set_attr "type" "compare")])
5667 (define_insn "*cmp_cc_xor_not"
5668   [(set (reg:CC 100)
5669         (compare:CC
5670          (not:SI (xor:SI (match_operand:SI 0 "register_or_zero_operand" "%rJ")
5671                          (match_operand:SI 1 "arith_operand" "rI")))
5672          (const_int 0)))]
5673   ""
5674   "xnorcc\t%r0, %1, %%g0"
5675   [(set_attr "type" "compare")])
5677 (define_insn "*cmp_ccx_xor_not"
5678   [(set (reg:CCX 100)
5679         (compare:CCX
5680          (not:DI (xor:DI (match_operand:DI 0 "register_or_zero_operand" "%rJ")
5681                          (match_operand:DI 1 "arith_operand" "rI")))
5682          (const_int 0)))]
5683   "TARGET_ARCH64"
5684   "xnorcc\t%r0, %1, %%g0"
5685   [(set_attr "type" "compare")])
5687 (define_insn "*cmp_cc_xor_not_set"
5688   [(set (reg:CC 100)
5689         (compare:CC
5690          (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
5691                          (match_operand:SI 2 "arith_operand" "rI")))
5692          (const_int 0)))
5693    (set (match_operand:SI 0 "register_operand" "=r")
5694         (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
5695   ""
5696   "xnorcc\t%r1, %2, %0"
5697   [(set_attr "type" "compare")])
5699 (define_insn "*cmp_ccx_xor_not_set"
5700   [(set (reg:CCX 100)
5701         (compare:CCX
5702          (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
5703                          (match_operand:DI 2 "arith_operand" "rI")))
5704          (const_int 0)))
5705    (set (match_operand:DI 0 "register_operand" "=r")
5706         (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
5707   "TARGET_ARCH64"
5708   "xnorcc\t%r1, %2, %0"
5709   [(set_attr "type" "compare")])
5711 (define_insn "*cmp_cc_arith_op_not"
5712   [(set (reg:CC 100)
5713         (compare:CC
5714          (match_operator:SI 2 "cc_arith_not_operator"
5715                             [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
5716                              (match_operand:SI 1 "register_or_zero_operand" "rJ")])
5717          (const_int 0)))]
5718   ""
5719   "%B2cc\t%r1, %0, %%g0"
5720   [(set_attr "type" "compare")])
5722 (define_insn "*cmp_ccx_arith_op_not"
5723   [(set (reg:CCX 100)
5724         (compare:CCX
5725          (match_operator:DI 2 "cc_arith_not_operator"
5726                             [(not:DI (match_operand:DI 0 "arith_operand" "rI"))
5727                              (match_operand:DI 1 "register_or_zero_operand" "rJ")])
5728          (const_int 0)))]
5729   "TARGET_ARCH64"
5730   "%B2cc\t%r1, %0, %%g0"
5731   [(set_attr "type" "compare")])
5733 (define_insn "*cmp_cc_arith_op_not_set"
5734   [(set (reg:CC 100)
5735         (compare:CC
5736          (match_operator:SI 3 "cc_arith_not_operator"
5737                             [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
5738                              (match_operand:SI 2 "register_or_zero_operand" "rJ")])
5739          (const_int 0)))
5740    (set (match_operand:SI 0 "register_operand" "=r")
5741         (match_operator:SI 4 "cc_arith_not_operator"
5742                             [(not:SI (match_dup 1)) (match_dup 2)]))]
5743   "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5744   "%B3cc\t%r2, %1, %0"
5745   [(set_attr "type" "compare")])
5747 (define_insn "*cmp_ccx_arith_op_not_set"
5748   [(set (reg:CCX 100)
5749         (compare:CCX
5750          (match_operator:DI 3 "cc_arith_not_operator"
5751                             [(not:DI (match_operand:DI 1 "arith_operand" "rI"))
5752                              (match_operand:DI 2 "register_or_zero_operand" "rJ")])
5753          (const_int 0)))
5754    (set (match_operand:DI 0 "register_operand" "=r")
5755         (match_operator:DI 4 "cc_arith_not_operator"
5756                             [(not:DI (match_dup 1)) (match_dup 2)]))]
5757   "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5758   "%B3cc\t%r2, %1, %0"
5759   [(set_attr "type" "compare")])
5761 ;; We cannot use the "neg" pseudo insn because the Sun assembler
5762 ;; does not know how to make it work for constants.
5764 (define_expand "negdi2"
5765   [(set (match_operand:DI 0 "register_operand" "=r")
5766         (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5767   ""
5769   if (! TARGET_ARCH64)
5770     {
5771       emit_insn (gen_rtx_PARALLEL
5772                  (VOIDmode,
5773                   gen_rtvec (2,
5774                              gen_rtx_SET (VOIDmode, operand0,
5775                                           gen_rtx_NEG (DImode, operand1)),
5776                              gen_rtx_CLOBBER (VOIDmode,
5777                                               gen_rtx_REG (CCmode,
5778                                                            SPARC_ICC_REG)))));
5779       DONE;
5780     }
5783 (define_insn_and_split "*negdi2_sp32"
5784   [(set (match_operand:DI 0 "register_operand" "=r")
5785         (neg:DI (match_operand:DI 1 "register_operand" "r")))
5786    (clobber (reg:CC 100))]
5787   "TARGET_ARCH32"
5788   "#"
5789   "&& reload_completed"
5790   [(parallel [(set (reg:CC_NOOV 100)
5791                    (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
5792                                     (const_int 0)))
5793               (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
5794    (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
5795                                 (ltu:SI (reg:CC 100) (const_int 0))))]
5796   "operands[2] = gen_highpart (SImode, operands[0]);
5797    operands[3] = gen_highpart (SImode, operands[1]);
5798    operands[4] = gen_lowpart (SImode, operands[0]);
5799    operands[5] = gen_lowpart (SImode, operands[1]);"
5800   [(set_attr "length" "2")])
5802 (define_insn "*negdi2_sp64"
5803   [(set (match_operand:DI 0 "register_operand" "=r")
5804         (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5805   "TARGET_ARCH64"
5806   "sub\t%%g0, %1, %0")
5808 (define_insn "negsi2"
5809   [(set (match_operand:SI 0 "register_operand" "=r")
5810         (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
5811   ""
5812   "sub\t%%g0, %1, %0")
5814 (define_insn "*cmp_cc_neg"
5815   [(set (reg:CC_NOOV 100)
5816         (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
5817                          (const_int 0)))]
5818   ""
5819   "subcc\t%%g0, %0, %%g0"
5820   [(set_attr "type" "compare")])
5822 (define_insn "*cmp_ccx_neg"
5823   [(set (reg:CCX_NOOV 100)
5824         (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_operand" "rI"))
5825                           (const_int 0)))]
5826   "TARGET_ARCH64"
5827   "subcc\t%%g0, %0, %%g0"
5828   [(set_attr "type" "compare")])
5830 (define_insn "*cmp_cc_set_neg"
5831   [(set (reg:CC_NOOV 100)
5832         (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
5833                          (const_int 0)))
5834    (set (match_operand:SI 0 "register_operand" "=r")
5835         (neg:SI (match_dup 1)))]
5836   ""
5837   "subcc\t%%g0, %1, %0"
5838   [(set_attr "type" "compare")])
5840 (define_insn "*cmp_ccx_set_neg"
5841   [(set (reg:CCX_NOOV 100)
5842         (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_operand" "rI"))
5843                           (const_int 0)))
5844    (set (match_operand:DI 0 "register_operand" "=r")
5845         (neg:DI (match_dup 1)))]
5846   "TARGET_ARCH64"
5847   "subcc\t%%g0, %1, %0"
5848   [(set_attr "type" "compare")])
5850 ;; We cannot use the "not" pseudo insn because the Sun assembler
5851 ;; does not know how to make it work for constants.
5852 (define_expand "one_cmpl<V64I:mode>2"
5853   [(set (match_operand:V64I 0 "register_operand" "")
5854         (not:V64I (match_operand:V64I 1 "register_operand" "")))]
5855   ""
5856   "")
5858 (define_insn_and_split "*one_cmpl<V64I:mode>2_sp32"
5859   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5860         (not:V64I (match_operand:V64I 1 "register_operand" "r,b")))]
5861   "! TARGET_ARCH64"
5862   "@
5863    #
5864    fnot1\t%1, %0"
5865   "&& reload_completed
5866    && ((GET_CODE (operands[0]) == REG
5867         && REGNO (operands[0]) < 32)
5868        || (GET_CODE (operands[0]) == SUBREG
5869            && GET_CODE (SUBREG_REG (operands[0])) == REG
5870            && REGNO (SUBREG_REG (operands[0])) < 32))"
5871   [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
5872    (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
5873   "operands[2] = gen_highpart (SImode, operands[0]);
5874    operands[3] = gen_highpart (SImode, operands[1]);
5875    operands[4] = gen_lowpart (SImode, operands[0]);
5876    operands[5] = gen_lowpart (SImode, operands[1]);"
5877   [(set_attr "type" "*,fga")
5878    (set_attr "length" "2,*")
5879    (set_attr "fptype" "*,double")])
5881 (define_insn "*one_cmpl<V64I:mode>2_sp64"
5882   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5883         (not:V64I (match_operand:V64I 1 "arith_operand" "rI,b")))]
5884   "TARGET_ARCH64"
5885   "@
5886    xnor\t%%g0, %1, %0
5887    fnot1\t%1, %0"
5888   [(set_attr "type" "*,fga")
5889    (set_attr "fptype" "*,double")])
5891 (define_insn "one_cmpl<V32I:mode>2"
5892   [(set (match_operand:V32I 0 "register_operand" "=r,d")
5893         (not:V32I (match_operand:V32I 1 "arith_operand" "rI,d")))]
5894   ""
5895   "@
5896   xnor\t%%g0, %1, %0
5897   fnot1s\t%1, %0"
5898   [(set_attr "type" "*,fga")
5899    (set_attr "fptype" "*,single")])
5901 (define_insn "*cmp_cc_not"
5902   [(set (reg:CC 100)
5903         (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
5904                     (const_int 0)))]
5905   ""
5906   "xnorcc\t%%g0, %0, %%g0"
5907   [(set_attr "type" "compare")])
5909 (define_insn "*cmp_ccx_not"
5910   [(set (reg:CCX 100)
5911         (compare:CCX (not:DI (match_operand:DI 0 "arith_operand" "rI"))
5912                      (const_int 0)))]
5913   "TARGET_ARCH64"
5914   "xnorcc\t%%g0, %0, %%g0"
5915   [(set_attr "type" "compare")])
5917 (define_insn "*cmp_cc_set_not"
5918   [(set (reg:CC 100)
5919         (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
5920                     (const_int 0)))
5921    (set (match_operand:SI 0 "register_operand" "=r")
5922         (not:SI (match_dup 1)))]
5923   ""
5924   "xnorcc\t%%g0, %1, %0"
5925   [(set_attr "type" "compare")])
5927 (define_insn "*cmp_ccx_set_not"
5928   [(set (reg:CCX 100)
5929         (compare:CCX (not:DI (match_operand:DI 1 "arith_operand" "rI"))
5930                     (const_int 0)))
5931    (set (match_operand:DI 0 "register_operand" "=r")
5932         (not:DI (match_dup 1)))]
5933   "TARGET_ARCH64"
5934   "xnorcc\t%%g0, %1, %0"
5935   [(set_attr "type" "compare")])
5937 (define_insn "*cmp_cc_set"
5938   [(set (match_operand:SI 0 "register_operand" "=r")
5939         (match_operand:SI 1 "register_operand" "r"))
5940    (set (reg:CC 100)
5941         (compare:CC (match_dup 1)
5942                     (const_int 0)))]
5943   ""
5944   "orcc\t%1, 0, %0"
5945   [(set_attr "type" "compare")])
5947 (define_insn "*cmp_ccx_set64"
5948   [(set (match_operand:DI 0 "register_operand" "=r")
5949         (match_operand:DI 1 "register_operand" "r"))
5950    (set (reg:CCX 100)
5951         (compare:CCX (match_dup 1)
5952                      (const_int 0)))]
5953   "TARGET_ARCH64"
5954   "orcc\t%1, 0, %0"
5955    [(set_attr "type" "compare")])
5958 ;; Floating point arithmetic instructions.
5960 (define_expand "addtf3"
5961   [(set (match_operand:TF 0 "nonimmediate_operand" "")
5962         (plus:TF (match_operand:TF 1 "general_operand" "")
5963                  (match_operand:TF 2 "general_operand" "")))]
5964   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5965   "emit_tfmode_binop (PLUS, operands); DONE;")
5967 (define_insn "*addtf3_hq"
5968   [(set (match_operand:TF 0 "register_operand" "=e")
5969         (plus:TF (match_operand:TF 1 "register_operand" "e")
5970                  (match_operand:TF 2 "register_operand" "e")))]
5971   "TARGET_FPU && TARGET_HARD_QUAD"
5972   "faddq\t%1, %2, %0"
5973   [(set_attr "type" "fp")])
5975 (define_insn "adddf3"
5976   [(set (match_operand:DF 0 "register_operand" "=e")
5977         (plus:DF (match_operand:DF 1 "register_operand" "e")
5978                  (match_operand:DF 2 "register_operand" "e")))]
5979   "TARGET_FPU"
5980   "faddd\t%1, %2, %0"
5981   [(set_attr "type" "fp")
5982    (set_attr "fptype" "double")])
5984 (define_insn "addsf3"
5985   [(set (match_operand:SF 0 "register_operand" "=f")
5986         (plus:SF (match_operand:SF 1 "register_operand" "f")
5987                  (match_operand:SF 2 "register_operand" "f")))]
5988   "TARGET_FPU"
5989   "fadds\t%1, %2, %0"
5990   [(set_attr "type" "fp")])
5992 (define_expand "subtf3"
5993   [(set (match_operand:TF 0 "nonimmediate_operand" "")
5994         (minus:TF (match_operand:TF 1 "general_operand" "")
5995                   (match_operand:TF 2 "general_operand" "")))]
5996   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5997   "emit_tfmode_binop (MINUS, operands); DONE;")
5999 (define_insn "*subtf3_hq"
6000   [(set (match_operand:TF 0 "register_operand" "=e")
6001         (minus:TF (match_operand:TF 1 "register_operand" "e")
6002                   (match_operand:TF 2 "register_operand" "e")))]
6003   "TARGET_FPU && TARGET_HARD_QUAD"
6004   "fsubq\t%1, %2, %0"
6005   [(set_attr "type" "fp")])
6007 (define_insn "subdf3"
6008   [(set (match_operand:DF 0 "register_operand" "=e")
6009         (minus:DF (match_operand:DF 1 "register_operand" "e")
6010                   (match_operand:DF 2 "register_operand" "e")))]
6011   "TARGET_FPU"
6012   "fsubd\t%1, %2, %0"
6013   [(set_attr "type" "fp")
6014    (set_attr "fptype" "double")])
6016 (define_insn "subsf3"
6017   [(set (match_operand:SF 0 "register_operand" "=f")
6018         (minus:SF (match_operand:SF 1 "register_operand" "f")
6019                   (match_operand:SF 2 "register_operand" "f")))]
6020   "TARGET_FPU"
6021   "fsubs\t%1, %2, %0"
6022   [(set_attr "type" "fp")])
6024 (define_expand "multf3"
6025   [(set (match_operand:TF 0 "nonimmediate_operand" "")
6026         (mult:TF (match_operand:TF 1 "general_operand" "")
6027                  (match_operand:TF 2 "general_operand" "")))]
6028   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6029   "emit_tfmode_binop (MULT, operands); DONE;")
6031 (define_insn "*multf3_hq"
6032   [(set (match_operand:TF 0 "register_operand" "=e")
6033         (mult:TF (match_operand:TF 1 "register_operand" "e")
6034                  (match_operand:TF 2 "register_operand" "e")))]
6035   "TARGET_FPU && TARGET_HARD_QUAD"
6036   "fmulq\t%1, %2, %0"
6037   [(set_attr "type" "fpmul")])
6039 (define_insn "muldf3"
6040   [(set (match_operand:DF 0 "register_operand" "=e")
6041         (mult:DF (match_operand:DF 1 "register_operand" "e")
6042                  (match_operand:DF 2 "register_operand" "e")))]
6043   "TARGET_FPU"
6044   "fmuld\t%1, %2, %0"
6045   [(set_attr "type" "fpmul")
6046    (set_attr "fptype" "double")])
6048 (define_insn "mulsf3"
6049   [(set (match_operand:SF 0 "register_operand" "=f")
6050         (mult:SF (match_operand:SF 1 "register_operand" "f")
6051                  (match_operand:SF 2 "register_operand" "f")))]
6052   "TARGET_FPU"
6053   "fmuls\t%1, %2, %0"
6054   [(set_attr "type" "fpmul")])
6056 (define_insn "*muldf3_extend"
6057   [(set (match_operand:DF 0 "register_operand" "=e")
6058         (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
6059                  (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
6060   "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
6061   "fsmuld\t%1, %2, %0"
6062   [(set_attr "type" "fpmul")
6063    (set_attr "fptype" "double")])
6065 (define_insn "*multf3_extend"
6066   [(set (match_operand:TF 0 "register_operand" "=e")
6067         (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
6068                  (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
6069   "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
6070   "fdmulq\t%1, %2, %0"
6071   [(set_attr "type" "fpmul")])
6073 (define_expand "divtf3"
6074   [(set (match_operand:TF 0 "nonimmediate_operand" "")
6075         (div:TF (match_operand:TF 1 "general_operand" "")
6076                 (match_operand:TF 2 "general_operand" "")))]
6077   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6078   "emit_tfmode_binop (DIV, operands); DONE;")
6080 ;; don't have timing for quad-prec. divide.
6081 (define_insn "*divtf3_hq"
6082   [(set (match_operand:TF 0 "register_operand" "=e")
6083         (div:TF (match_operand:TF 1 "register_operand" "e")
6084                 (match_operand:TF 2 "register_operand" "e")))]
6085   "TARGET_FPU && TARGET_HARD_QUAD"
6086   "fdivq\t%1, %2, %0"
6087   [(set_attr "type" "fpdivd")])
6089 (define_insn "divdf3"
6090   [(set (match_operand:DF 0 "register_operand" "=e")
6091         (div:DF (match_operand:DF 1 "register_operand" "e")
6092                 (match_operand:DF 2 "register_operand" "e")))]
6093   "TARGET_FPU"
6094   "fdivd\t%1, %2, %0"
6095   [(set_attr "type" "fpdivd")
6096    (set_attr "fptype" "double")])
6098 (define_insn "divsf3"
6099   [(set (match_operand:SF 0 "register_operand" "=f")
6100         (div:SF (match_operand:SF 1 "register_operand" "f")
6101                 (match_operand:SF 2 "register_operand" "f")))]
6102   "TARGET_FPU"
6103   "fdivs\t%1, %2, %0"
6104   [(set_attr "type" "fpdivs")])
6106 (define_expand "negtf2"
6107   [(set (match_operand:TF 0 "register_operand" "=e,e")
6108         (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6109   "TARGET_FPU"
6110   "")
6112 (define_insn_and_split "*negtf2_notv9"
6113   [(set (match_operand:TF 0 "register_operand" "=e,e")
6114         (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6115   ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6116   "TARGET_FPU
6117    && ! TARGET_V9"
6118   "@
6119   fnegs\t%0, %0
6120   #"
6121   "&& reload_completed
6122    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6123   [(set (match_dup 2) (neg:SF (match_dup 3)))
6124    (set (match_dup 4) (match_dup 5))
6125    (set (match_dup 6) (match_dup 7))]
6126   "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6127    operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6128    operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6129    operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6130    operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6131    operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6132   [(set_attr "type" "fpmove,*")
6133    (set_attr "length" "*,2")])
6135 (define_insn_and_split "*negtf2_v9"
6136   [(set (match_operand:TF 0 "register_operand" "=e,e")
6137         (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6138   ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6139   "TARGET_FPU && TARGET_V9"
6140   "@
6141   fnegd\t%0, %0
6142   #"
6143   "&& reload_completed
6144    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6145   [(set (match_dup 2) (neg:DF (match_dup 3)))
6146    (set (match_dup 4) (match_dup 5))]
6147   "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6148    operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6149    operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6150    operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6151   [(set_attr "type" "fpmove,*")
6152    (set_attr "length" "*,2")
6153    (set_attr "fptype" "double")])
6155 (define_expand "negdf2"
6156   [(set (match_operand:DF 0 "register_operand" "")
6157         (neg:DF (match_operand:DF 1 "register_operand" "")))]
6158   "TARGET_FPU"
6159   "")
6161 (define_insn_and_split "*negdf2_notv9"
6162   [(set (match_operand:DF 0 "register_operand" "=e,e")
6163         (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
6164   "TARGET_FPU && ! TARGET_V9"
6165   "@
6166   fnegs\t%0, %0
6167   #"
6168   "&& reload_completed
6169    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6170   [(set (match_dup 2) (neg:SF (match_dup 3)))
6171    (set (match_dup 4) (match_dup 5))]
6172   "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6173    operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6174    operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6175    operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6176   [(set_attr "type" "fpmove,*")
6177    (set_attr "length" "*,2")])
6179 (define_insn "*negdf2_v9"
6180   [(set (match_operand:DF 0 "register_operand" "=e")
6181         (neg:DF (match_operand:DF 1 "register_operand" "e")))]
6182   "TARGET_FPU && TARGET_V9"
6183   "fnegd\t%1, %0"
6184   [(set_attr "type" "fpmove")
6185    (set_attr "fptype" "double")])
6187 (define_insn "negsf2"
6188   [(set (match_operand:SF 0 "register_operand" "=f")
6189         (neg:SF (match_operand:SF 1 "register_operand" "f")))]
6190   "TARGET_FPU"
6191   "fnegs\t%1, %0"
6192   [(set_attr "type" "fpmove")])
6194 (define_expand "abstf2"
6195   [(set (match_operand:TF 0 "register_operand" "")
6196         (abs:TF (match_operand:TF 1 "register_operand" "")))]
6197   "TARGET_FPU"
6198   "")
6200 (define_insn_and_split "*abstf2_notv9"
6201   [(set (match_operand:TF 0 "register_operand" "=e,e")
6202         (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6203   ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6204   "TARGET_FPU && ! TARGET_V9"
6205   "@
6206   fabss\t%0, %0
6207   #"
6208   "&& reload_completed
6209    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6210   [(set (match_dup 2) (abs:SF (match_dup 3)))
6211    (set (match_dup 4) (match_dup 5))
6212    (set (match_dup 6) (match_dup 7))]
6213   "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6214    operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6215    operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6216    operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6217    operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6218    operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6219   [(set_attr "type" "fpmove,*")
6220    (set_attr "length" "*,2")])
6222 (define_insn "*abstf2_hq_v9"
6223   [(set (match_operand:TF 0 "register_operand" "=e,e")
6224         (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6225   "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
6226   "@
6227   fabsd\t%0, %0
6228   fabsq\t%1, %0"
6229   [(set_attr "type" "fpmove")
6230    (set_attr "fptype" "double,*")])
6232 (define_insn_and_split "*abstf2_v9"
6233   [(set (match_operand:TF 0 "register_operand" "=e,e")
6234         (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6235   "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
6236   "@
6237   fabsd\t%0, %0
6238   #"
6239   "&& reload_completed
6240    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6241   [(set (match_dup 2) (abs:DF (match_dup 3)))
6242    (set (match_dup 4) (match_dup 5))]
6243   "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6244    operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6245    operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6246    operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6247   [(set_attr "type" "fpmove,*")
6248    (set_attr "length" "*,2")
6249    (set_attr "fptype" "double,*")])
6251 (define_expand "absdf2"
6252   [(set (match_operand:DF 0 "register_operand" "")
6253         (abs:DF (match_operand:DF 1 "register_operand" "")))]
6254   "TARGET_FPU"
6255   "")
6257 (define_insn_and_split "*absdf2_notv9"
6258   [(set (match_operand:DF 0 "register_operand" "=e,e")
6259         (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
6260   "TARGET_FPU && ! TARGET_V9"
6261   "@
6262   fabss\t%0, %0
6263   #"
6264   "&& reload_completed
6265    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6266   [(set (match_dup 2) (abs:SF (match_dup 3)))
6267    (set (match_dup 4) (match_dup 5))]
6268   "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6269    operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6270    operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6271    operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6272   [(set_attr "type" "fpmove,*")
6273    (set_attr "length" "*,2")])
6275 (define_insn "*absdf2_v9"
6276   [(set (match_operand:DF 0 "register_operand" "=e")
6277         (abs:DF (match_operand:DF 1 "register_operand" "e")))]
6278   "TARGET_FPU && TARGET_V9"
6279   "fabsd\t%1, %0"
6280   [(set_attr "type" "fpmove")
6281    (set_attr "fptype" "double")])
6283 (define_insn "abssf2"
6284   [(set (match_operand:SF 0 "register_operand" "=f")
6285         (abs:SF (match_operand:SF 1 "register_operand" "f")))]
6286   "TARGET_FPU"
6287   "fabss\t%1, %0"
6288   [(set_attr "type" "fpmove")])
6290 (define_expand "sqrttf2"
6291   [(set (match_operand:TF 0 "nonimmediate_operand" "")
6292         (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
6293   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6294   "emit_tfmode_unop (SQRT, operands); DONE;")
6296 (define_insn "*sqrttf2_hq"
6297   [(set (match_operand:TF 0 "register_operand" "=e")
6298         (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
6299   "TARGET_FPU && TARGET_HARD_QUAD"
6300   "fsqrtq\t%1, %0"
6301   [(set_attr "type" "fpsqrtd")])
6303 (define_insn "sqrtdf2"
6304   [(set (match_operand:DF 0 "register_operand" "=e")
6305         (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
6306   "TARGET_FPU"
6307   "fsqrtd\t%1, %0"
6308   [(set_attr "type" "fpsqrtd")
6309    (set_attr "fptype" "double")])
6311 (define_insn "sqrtsf2"
6312   [(set (match_operand:SF 0 "register_operand" "=f")
6313         (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
6314   "TARGET_FPU"
6315   "fsqrts\t%1, %0"
6316   [(set_attr "type" "fpsqrts")])
6319 ;; Arithmetic shift instructions.
6321 (define_insn "ashlsi3"
6322   [(set (match_operand:SI 0 "register_operand" "=r")
6323         (ashift:SI (match_operand:SI 1 "register_operand" "r")
6324                    (match_operand:SI 2 "arith_operand" "rI")))]
6325   ""
6327   if (GET_CODE (operands[2]) == CONST_INT)
6328     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6329   return "sll\t%1, %2, %0";
6331   [(set (attr "type")
6332         (if_then_else (match_operand 2 "const_one_operand" "")
6333                       (const_string "ialu") (const_string "shift")))])
6335 (define_expand "ashldi3"
6336   [(set (match_operand:DI 0 "register_operand" "=r")
6337         (ashift:DI (match_operand:DI 1 "register_operand" "r")
6338                    (match_operand:SI 2 "arith_operand" "rI")))]
6339   "TARGET_ARCH64 || TARGET_V8PLUS"
6341   if (! TARGET_ARCH64)
6342     {
6343       if (GET_CODE (operands[2]) == CONST_INT)
6344         FAIL;
6345       emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
6346       DONE;
6347     }
6350 (define_insn "*ashldi3_sp64"
6351   [(set (match_operand:DI 0 "register_operand" "=r")
6352         (ashift:DI (match_operand:DI 1 "register_operand" "r")
6353                    (match_operand:SI 2 "arith_operand" "rI")))]
6354   "TARGET_ARCH64"
6356   if (GET_CODE (operands[2]) == CONST_INT)
6357     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6358   return "sllx\t%1, %2, %0";
6360   [(set (attr "type")
6361         (if_then_else (match_operand 2 "const_one_operand" "")
6362                       (const_string "ialu") (const_string "shift")))])
6364 ;; XXX UGH!
6365 (define_insn "ashldi3_v8plus"
6366   [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6367         (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6368                    (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6369    (clobber (match_scratch:SI 3 "=X,X,&h"))]
6370   "TARGET_V8PLUS"
6371   "* return output_v8plus_shift (operands, insn, \"sllx\");"
6372   [(set_attr "type" "multi")
6373    (set_attr "length" "5,5,6")])
6375 ;; Optimize (1LL<<x)-1
6376 ;; XXX this also needs to be fixed to handle equal subregs
6377 ;; XXX first before we could re-enable it.
6378 ;(define_insn ""
6379 ;  [(set (match_operand:DI 0 "register_operand" "=h")
6380 ;       (plus:DI (ashift:DI (const_int 1)
6381 ;                           (match_operand:SI 1 "arith_operand" "rI"))
6382 ;                (const_int -1)))]
6383 ;  "0 && TARGET_V8PLUS"
6385 ;  if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
6386 ;    return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
6387 ;  return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
6389 ;  [(set_attr "type" "multi")
6390 ;   (set_attr "length" "4")])
6392 (define_insn "*cmp_cc_ashift_1"
6393   [(set (reg:CC_NOOV 100)
6394         (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
6395                                     (const_int 1))
6396                          (const_int 0)))]
6397   ""
6398   "addcc\t%0, %0, %%g0"
6399   [(set_attr "type" "compare")])
6401 (define_insn "*cmp_cc_set_ashift_1"
6402   [(set (reg:CC_NOOV 100)
6403         (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
6404                                     (const_int 1))
6405                          (const_int 0)))
6406    (set (match_operand:SI 0 "register_operand" "=r")
6407         (ashift:SI (match_dup 1) (const_int 1)))]
6408   ""
6409   "addcc\t%1, %1, %0"
6410   [(set_attr "type" "compare")])
6412 (define_insn "ashrsi3"
6413   [(set (match_operand:SI 0 "register_operand" "=r")
6414         (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
6415                      (match_operand:SI 2 "arith_operand" "rI")))]
6416   ""
6417   {
6418      if (GET_CODE (operands[2]) == CONST_INT)
6419        operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6420      return "sra\t%1, %2, %0";
6421   }
6422   [(set_attr "type" "shift")])
6424 (define_insn "*ashrsi3_extend"
6425   [(set (match_operand:DI 0 "register_operand" "=r")
6426         (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
6427                                      (match_operand:SI 2 "arith_operand" "r"))))]
6428   "TARGET_ARCH64"
6429   "sra\t%1, %2, %0"
6430   [(set_attr "type" "shift")])
6432 ;; This handles the case as above, but with constant shift instead of
6433 ;; register. Combiner "simplifies" it for us a little bit though.
6434 (define_insn "*ashrsi3_extend2"
6435   [(set (match_operand:DI 0 "register_operand" "=r")
6436         (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
6437                                 (const_int 32))
6438                      (match_operand:SI 2 "small_int_operand" "I")))]
6439   "TARGET_ARCH64 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64"
6441   operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
6442   return "sra\t%1, %2, %0";
6444   [(set_attr "type" "shift")])
6446 (define_expand "ashrdi3"
6447   [(set (match_operand:DI 0 "register_operand" "=r")
6448         (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6449                      (match_operand:SI 2 "arith_operand" "rI")))]
6450   "TARGET_ARCH64 || TARGET_V8PLUS"
6452   if (! TARGET_ARCH64)
6453     {
6454       if (GET_CODE (operands[2]) == CONST_INT)
6455         FAIL;   /* prefer generic code in this case */
6456       emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
6457       DONE;
6458     }
6461 (define_insn "*ashrdi3_sp64"
6462   [(set (match_operand:DI 0 "register_operand" "=r")
6463         (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6464                      (match_operand:SI 2 "arith_operand" "rI")))]
6465   "TARGET_ARCH64"
6466   
6467   {
6468     if (GET_CODE (operands[2]) == CONST_INT)
6469       operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6470     return "srax\t%1, %2, %0";
6471   }
6472   [(set_attr "type" "shift")])
6474 ;; XXX
6475 (define_insn "ashrdi3_v8plus"
6476   [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6477         (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6478                      (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6479    (clobber (match_scratch:SI 3 "=X,X,&h"))]
6480   "TARGET_V8PLUS"
6481   "* return output_v8plus_shift (operands, insn, \"srax\");"
6482   [(set_attr "type" "multi")
6483    (set_attr "length" "5,5,6")])
6485 (define_insn "lshrsi3"
6486   [(set (match_operand:SI 0 "register_operand" "=r")
6487         (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
6488                      (match_operand:SI 2 "arith_operand" "rI")))]
6489   ""
6490   {
6491     if (GET_CODE (operands[2]) == CONST_INT)
6492       operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6493     return "srl\t%1, %2, %0";
6494   }
6495   [(set_attr "type" "shift")])
6497 ;; This handles the case where
6498 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
6499 ;; but combiner "simplifies" it for us.
6500 (define_insn "*lshrsi3_extend"
6501   [(set (match_operand:DI 0 "register_operand" "=r")
6502         (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
6503                            (match_operand:SI 2 "arith_operand" "r")) 0)
6504                 (match_operand 3 "const_int_operand" "")))]
6505   "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff"
6506   "srl\t%1, %2, %0"
6507   [(set_attr "type" "shift")])
6509 ;; This handles the case where
6510 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
6511 ;; but combiner "simplifies" it for us.
6512 (define_insn "*lshrsi3_extend2"
6513   [(set (match_operand:DI 0 "register_operand" "=r")
6514         (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
6515                          (match_operand 2 "small_int_operand" "I")
6516                          (const_int 32)))]
6517   "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6519   operands[2] = GEN_INT (32 - INTVAL (operands[2]));
6520   return "srl\t%1, %2, %0";
6522   [(set_attr "type" "shift")])
6524 (define_expand "lshrdi3"
6525   [(set (match_operand:DI 0 "register_operand" "=r")
6526         (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6527                      (match_operand:SI 2 "arith_operand" "rI")))]
6528   "TARGET_ARCH64 || TARGET_V8PLUS"
6530   if (! TARGET_ARCH64)
6531     {
6532       if (GET_CODE (operands[2]) == CONST_INT)
6533         FAIL;
6534       emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
6535       DONE;
6536     }
6539 (define_insn "*lshrdi3_sp64"
6540   [(set (match_operand:DI 0 "register_operand" "=r")
6541         (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6542                      (match_operand:SI 2 "arith_operand" "rI")))]
6543   "TARGET_ARCH64"
6544   {
6545     if (GET_CODE (operands[2]) == CONST_INT)
6546       operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6547     return "srlx\t%1, %2, %0";
6548   }
6549   [(set_attr "type" "shift")])
6551 ;; XXX
6552 (define_insn "lshrdi3_v8plus"
6553   [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6554         (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6555                      (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6556    (clobber (match_scratch:SI 3 "=X,X,&h"))]
6557   "TARGET_V8PLUS"
6558   "* return output_v8plus_shift (operands, insn, \"srlx\");"
6559   [(set_attr "type" "multi")
6560    (set_attr "length" "5,5,6")])
6562 (define_insn ""
6563   [(set (match_operand:SI 0 "register_operand" "=r")
6564         (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6565                                              (const_int 32)) 4)
6566                      (match_operand:SI 2 "small_int_operand" "I")))]
6567   "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6569   operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6570   return "srax\t%1, %2, %0";
6572   [(set_attr "type" "shift")])
6574 (define_insn ""
6575   [(set (match_operand:SI 0 "register_operand" "=r")
6576         (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6577                                              (const_int 32)) 4)
6578                      (match_operand:SI 2 "small_int_operand" "I")))]
6579   "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6581   operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6582   return "srlx\t%1, %2, %0";
6584   [(set_attr "type" "shift")])
6586 (define_insn ""
6587   [(set (match_operand:SI 0 "register_operand" "=r")
6588         (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6589                                              (match_operand:SI 2 "small_int_operand" "I")) 4)
6590                      (match_operand:SI 3 "small_int_operand" "I")))]
6591   "TARGET_ARCH64
6592    && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6593    && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6594    && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6596   operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6598   return "srax\t%1, %2, %0";
6600   [(set_attr "type" "shift")])
6602 (define_insn ""
6603   [(set (match_operand:SI 0 "register_operand" "=r")
6604         (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6605                                              (match_operand:SI 2 "small_int_operand" "I")) 4)
6606                      (match_operand:SI 3 "small_int_operand" "I")))]
6607   "TARGET_ARCH64
6608    && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6609    && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6610    && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6612   operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6614   return "srlx\t%1, %2, %0";
6616   [(set_attr "type" "shift")])
6619 ;; Unconditional and other jump instructions.
6621 (define_insn "jump"
6622   [(set (pc) (label_ref (match_operand 0 "" "")))]
6623   ""
6624   "* return output_ubranch (operands[0], 0, insn);"
6625   [(set_attr "type" "uncond_branch")])
6627 (define_expand "tablejump"
6628   [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
6629               (use (label_ref (match_operand 1 "" "")))])]
6630   ""
6632   gcc_assert (GET_MODE (operands[0]) == CASE_VECTOR_MODE);
6634   /* In pic mode, our address differences are against the base of the
6635      table.  Add that base value back in; CSE ought to be able to combine
6636      the two address loads.  */
6637   if (flag_pic)
6638     {
6639       rtx tmp, tmp2;
6640       tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
6641       tmp2 = operands[0];
6642       if (CASE_VECTOR_MODE != Pmode)
6643         tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
6644       tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
6645       operands[0] = memory_address (Pmode, tmp);
6646     }
6649 (define_insn "*tablejump_sp32"
6650   [(set (pc) (match_operand:SI 0 "address_operand" "p"))
6651    (use (label_ref (match_operand 1 "" "")))]
6652   "! TARGET_ARCH64"
6653   "jmp\t%a0%#"
6654   [(set_attr "type" "uncond_branch")])
6656 (define_insn "*tablejump_sp64"
6657   [(set (pc) (match_operand:DI 0 "address_operand" "p"))
6658    (use (label_ref (match_operand 1 "" "")))]
6659   "TARGET_ARCH64"
6660   "jmp\t%a0%#"
6661   [(set_attr "type" "uncond_branch")])
6664 ;; Jump to subroutine instructions.
6666 (define_expand "call"
6667   ;; Note that this expression is not used for generating RTL.
6668   ;; All the RTL is generated explicitly below.
6669   [(call (match_operand 0 "call_operand" "")
6670          (match_operand 3 "" "i"))]
6671   ;; operands[2] is next_arg_register
6672   ;; operands[3] is struct_value_size_rtx.
6673   ""
6675   rtx fn_rtx;
6677   gcc_assert (GET_MODE (operands[0]) == FUNCTION_MODE);
6679   gcc_assert (GET_CODE (operands[3]) == CONST_INT);
6681   if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
6682     {
6683       /* This is really a PIC sequence.  We want to represent
6684          it as a funny jump so its delay slots can be filled. 
6686          ??? But if this really *is* a CALL, will not it clobber the
6687          call-clobbered registers?  We lose this if it is a JUMP_INSN.
6688          Why cannot we have delay slots filled if it were a CALL?  */
6690       /* We accept negative sizes for untyped calls.  */
6691       if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6692         emit_jump_insn
6693           (gen_rtx_PARALLEL
6694            (VOIDmode,
6695             gen_rtvec (3,
6696                        gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6697                        operands[3],
6698                        gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6699       else
6700         emit_jump_insn
6701           (gen_rtx_PARALLEL
6702            (VOIDmode,
6703             gen_rtvec (2,
6704                        gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6705                        gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6706       goto finish_call;
6707     }
6709   fn_rtx = operands[0];
6711   /* We accept negative sizes for untyped calls.  */
6712   if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6713     emit_call_insn
6714       (gen_rtx_PARALLEL
6715        (VOIDmode,
6716         gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6717                    operands[3],
6718                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6719   else
6720     emit_call_insn
6721       (gen_rtx_PARALLEL
6722        (VOIDmode,
6723         gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6724                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6726  finish_call:
6728   DONE;
6731 ;; We can't use the same pattern for these two insns, because then registers
6732 ;; in the address may not be properly reloaded.
6734 (define_insn "*call_address_sp32"
6735   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6736          (match_operand 1 "" ""))
6737    (clobber (reg:SI 15))]
6738   ;;- Do not use operand 1 for most machines.
6739   "! TARGET_ARCH64"
6740   "call\t%a0, %1%#"
6741   [(set_attr "type" "call")])
6743 (define_insn "*call_symbolic_sp32"
6744   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6745          (match_operand 1 "" ""))
6746    (clobber (reg:SI 15))]
6747   ;;- Do not use operand 1 for most machines.
6748   "! TARGET_ARCH64"
6749   "call\t%a0, %1%#"
6750   [(set_attr "type" "call")])
6752 (define_insn "*call_address_sp64"
6753   [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
6754          (match_operand 1 "" ""))
6755    (clobber (reg:DI 15))]
6756   ;;- Do not use operand 1 for most machines.
6757   "TARGET_ARCH64"
6758   "call\t%a0, %1%#"
6759   [(set_attr "type" "call")])
6761 (define_insn "*call_symbolic_sp64"
6762   [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6763          (match_operand 1 "" ""))
6764    (clobber (reg:DI 15))]
6765   ;;- Do not use operand 1 for most machines.
6766   "TARGET_ARCH64"
6767   "call\t%a0, %1%#"
6768   [(set_attr "type" "call")])
6770 ;; This is a call that wants a structure value.
6771 ;; There is no such critter for v9 (??? we may need one anyway).
6772 (define_insn "*call_address_struct_value_sp32"
6773   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6774          (match_operand 1 "" ""))
6775    (match_operand 2 "immediate_operand" "")
6776    (clobber (reg:SI 15))]
6777   ;;- Do not use operand 1 for most machines.
6778   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6780   operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6781   return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6783   [(set_attr "type" "call_no_delay_slot")
6784    (set_attr "length" "3")])
6786 ;; This is a call that wants a structure value.
6787 ;; There is no such critter for v9 (??? we may need one anyway).
6788 (define_insn "*call_symbolic_struct_value_sp32"
6789   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6790          (match_operand 1 "" ""))
6791    (match_operand 2 "immediate_operand" "")
6792    (clobber (reg:SI 15))]
6793   ;;- Do not use operand 1 for most machines.
6794   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6796   operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6797   return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6799   [(set_attr "type" "call_no_delay_slot")
6800    (set_attr "length" "3")])
6802 ;; This is a call that may want a structure value.  This is used for
6803 ;; untyped_calls.
6804 (define_insn "*call_address_untyped_struct_value_sp32"
6805   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6806          (match_operand 1 "" ""))
6807    (match_operand 2 "immediate_operand" "")
6808    (clobber (reg:SI 15))]
6809   ;;- Do not use operand 1 for most machines.
6810   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6811   "call\t%a0, %1\n\t nop\n\tnop"
6812   [(set_attr "type" "call_no_delay_slot")
6813    (set_attr "length" "3")])
6815 ;; This is a call that may want a structure value.  This is used for
6816 ;; untyped_calls.
6817 (define_insn "*call_symbolic_untyped_struct_value_sp32"
6818   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6819          (match_operand 1 "" ""))
6820    (match_operand 2 "immediate_operand" "")
6821    (clobber (reg:SI 15))]
6822   ;;- Do not use operand 1 for most machines.
6823   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6824   "call\t%a0, %1\n\t nop\n\tnop"
6825   [(set_attr "type" "call_no_delay_slot")
6826    (set_attr "length" "3")])
6828 (define_expand "call_value"
6829   ;; Note that this expression is not used for generating RTL.
6830   ;; All the RTL is generated explicitly below.
6831   [(set (match_operand 0 "register_operand" "=rf")
6832         (call (match_operand 1 "" "")
6833               (match_operand 4 "" "")))]
6834   ;; operand 2 is stack_size_rtx
6835   ;; operand 3 is next_arg_register
6836   ""
6838   rtx fn_rtx;
6839   rtvec vec;
6841   gcc_assert (GET_MODE (operands[1]) == FUNCTION_MODE);
6843   fn_rtx = operands[1];
6845   vec = gen_rtvec (2,
6846                    gen_rtx_SET (VOIDmode, operands[0],
6847                                 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
6848                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
6850   emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
6852   DONE;
6855 (define_insn "*call_value_address_sp32"
6856   [(set (match_operand 0 "" "=rf")
6857         (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
6858               (match_operand 2 "" "")))
6859    (clobber (reg:SI 15))]
6860   ;;- Do not use operand 2 for most machines.
6861   "! TARGET_ARCH64"
6862   "call\t%a1, %2%#"
6863   [(set_attr "type" "call")])
6865 (define_insn "*call_value_symbolic_sp32"
6866   [(set (match_operand 0 "" "=rf")
6867         (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6868               (match_operand 2 "" "")))
6869    (clobber (reg:SI 15))]
6870   ;;- Do not use operand 2 for most machines.
6871   "! TARGET_ARCH64"
6872   "call\t%a1, %2%#"
6873   [(set_attr "type" "call")])
6875 (define_insn "*call_value_address_sp64"
6876   [(set (match_operand 0 "" "")
6877         (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
6878               (match_operand 2 "" "")))
6879    (clobber (reg:DI 15))]
6880   ;;- Do not use operand 2 for most machines.
6881   "TARGET_ARCH64"
6882   "call\t%a1, %2%#"
6883   [(set_attr "type" "call")])
6885 (define_insn "*call_value_symbolic_sp64"
6886   [(set (match_operand 0 "" "")
6887         (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6888               (match_operand 2 "" "")))
6889    (clobber (reg:DI 15))]
6890   ;;- Do not use operand 2 for most machines.
6891   "TARGET_ARCH64"
6892   "call\t%a1, %2%#"
6893   [(set_attr "type" "call")])
6895 (define_expand "untyped_call"
6896   [(parallel [(call (match_operand 0 "" "")
6897                     (const_int 0))
6898               (match_operand:BLK 1 "memory_operand" "")
6899               (match_operand 2 "" "")])]
6900   ""
6902   rtx valreg1 = gen_rtx_REG (DImode, 8);
6903   rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6904   rtx result = operands[1];
6906   /* Pass constm1 to indicate that it may expect a structure value, but
6907      we don't know what size it is.  */
6908   emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
6910   /* Save the function value registers.  */
6911   emit_move_insn (adjust_address (result, DImode, 0), valreg1);
6912   emit_move_insn (adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8),
6913                                   valreg2);
6915   /* The optimizer does not know that the call sets the function value
6916      registers we stored in the result block.  We avoid problems by
6917      claiming that all hard registers are used and clobbered at this
6918      point.  */
6919   emit_insn (gen_blockage ());
6921   DONE;
6924 ;;  Tail call instructions.
6926 (define_expand "sibcall"
6927   [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
6928               (return)])]
6929   ""
6930   "")
6932 (define_insn "*sibcall_symbolic_sp32"
6933   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6934          (match_operand 1 "" ""))
6935    (return)]
6936   "! TARGET_ARCH64"
6937   "* return output_sibcall(insn, operands[0]);"
6938   [(set_attr "type" "sibcall")])
6940 (define_insn "*sibcall_symbolic_sp64"
6941   [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6942          (match_operand 1 "" ""))
6943    (return)]
6944   "TARGET_ARCH64"
6945   "* return output_sibcall(insn, operands[0]);"
6946   [(set_attr "type" "sibcall")])
6948 (define_expand "sibcall_value"
6949   [(parallel [(set (match_operand 0 "register_operand" "=rf")
6950                 (call (match_operand 1 "" "") (const_int 0)))
6951               (return)])]
6952   ""
6953   "")
6955 (define_insn "*sibcall_value_symbolic_sp32"
6956   [(set (match_operand 0 "" "=rf")
6957         (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6958               (match_operand 2 "" "")))
6959    (return)]
6960   "! TARGET_ARCH64"
6961   "* return output_sibcall(insn, operands[1]);"
6962   [(set_attr "type" "sibcall")])
6964 (define_insn "*sibcall_value_symbolic_sp64"
6965   [(set (match_operand 0 "" "")
6966         (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6967               (match_operand 2 "" "")))
6968    (return)]
6969   "TARGET_ARCH64"
6970   "* return output_sibcall(insn, operands[1]);"
6971   [(set_attr "type" "sibcall")])
6974 ;; Special instructions.
6976 (define_expand "prologue"
6977   [(const_int 0)]
6978   ""
6980   sparc_expand_prologue ();
6981   DONE;
6984 ;; The "save register window" insn is modelled as follows so that the DWARF-2
6985 ;; backend automatically emits the required call frame debugging information
6986 ;; while it is parsing it.  Therefore, the pattern should not be modified
6987 ;; without first studying the impact of the changes on the debug info.
6988 ;; [(set (%fp) (%sp))
6989 ;;  (set (%sp) (unspec_volatile [(%sp) (-frame_size)] UNSPECV_SAVEW))
6990 ;;  (set (%i7) (%o7))]
6992 (define_insn "save_register_window<P:mode>"
6993   [(set (reg:P 30) (reg:P 14))
6994    (set (reg:P 14) (unspec_volatile:P [(reg:P 14)
6995                                        (match_operand:P 0 "arith_operand" "rI")] UNSPECV_SAVEW))
6996    (set (reg:P 31) (reg:P 15))]
6997   ""
6998   "save\t%%sp, %0, %%sp"
6999   [(set_attr "type" "savew")])
7001 (define_expand "epilogue"
7002   [(return)]
7003   ""
7005   sparc_expand_epilogue ();
7008 (define_expand "sibcall_epilogue"
7009   [(return)]
7010   ""
7012   sparc_expand_epilogue ();
7013   DONE;
7016 (define_expand "return"
7017   [(return)]
7018   "sparc_can_use_return_insn_p ()"
7019   "")
7021 (define_insn "*return_internal"
7022   [(return)]
7023   ""
7024   "* return output_return (insn);"
7025   [(set_attr "type" "return")
7026    (set (attr "length")
7027         (cond [(eq_attr "leaf_function" "true")
7028                  (if_then_else (eq_attr "empty_delay_slot" "true")
7029                                (const_int 2)
7030                                (const_int 1))
7031                (eq_attr "calls_eh_return" "true")
7032                  (if_then_else (eq_attr "delayed_branch" "true")
7033                                (if_then_else (eq_attr "isa" "v9")
7034                                              (const_int 2)
7035                                              (const_int 3))
7036                                (if_then_else (eq_attr "isa" "v9")
7037                                              (const_int 3)
7038                                              (const_int 4)))
7039                (eq_attr "empty_delay_slot" "true")
7040                  (if_then_else (eq_attr "delayed_branch" "true")
7041                                (const_int 2)
7042                                (const_int 3))
7043               ] (const_int 1)))])
7045 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
7046 ;; all of memory.  This blocks insns from being moved across this point.
7048 (define_insn "blockage"
7049   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7050   ""
7051   ""
7052   [(set_attr "length" "0")])
7054 ;; Prepare to return any type including a structure value.
7056 (define_expand "untyped_return"
7057   [(match_operand:BLK 0 "memory_operand" "")
7058    (match_operand 1 "" "")]
7059   ""
7061   rtx valreg1 = gen_rtx_REG (DImode, 24);
7062   rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
7063   rtx result = operands[0];
7065   if (! TARGET_ARCH64)
7066     {
7067       rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
7068                                          ? 15 : 31));
7069       rtx value = gen_reg_rtx (SImode);
7071       /* Fetch the instruction where we will return to and see if it's an unimp
7072          instruction (the most significant 10 bits will be zero).  If so,
7073          update the return address to skip the unimp instruction.  */
7074       emit_move_insn (value,
7075                       gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
7076       emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
7077       emit_insn (gen_update_return (rtnreg, value));
7078     }
7080   /* Reload the function value registers.  */
7081   emit_move_insn (valreg1, adjust_address (result, DImode, 0));
7082   emit_move_insn (valreg2,
7083                   adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
7085   /* Put USE insns before the return.  */
7086   emit_insn (gen_rtx_USE (VOIDmode, valreg1));
7087   emit_insn (gen_rtx_USE (VOIDmode, valreg2));
7089   /* Construct the return.  */
7090   expand_naked_return ();
7092   DONE;
7095 ;; This is a bit of a hack.  We're incrementing a fixed register (%i7),
7096 ;; and parts of the compiler don't want to believe that the add is needed.
7098 (define_insn "update_return"
7099   [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
7100                (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
7101   "! TARGET_ARCH64"
7103   if (flag_delayed_branch)
7104     return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
7105   else
7106     return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
7108   [(set (attr "type") (const_string "multi"))
7109    (set (attr "length")
7110         (if_then_else (eq_attr "delayed_branch" "true")
7111                       (const_int 3)
7112                       (const_int 4)))])
7114 (define_insn "nop"
7115   [(const_int 0)]
7116   ""
7117   "nop")
7119 (define_expand "indirect_jump"
7120   [(set (pc) (match_operand 0 "address_operand" "p"))]
7121   ""
7122   "")
7124 (define_insn "*branch_sp32"
7125   [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
7126   "! TARGET_ARCH64"
7127  "jmp\t%a0%#"
7128  [(set_attr "type" "uncond_branch")])
7130 (define_insn "*branch_sp64"
7131   [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
7132   "TARGET_ARCH64"
7133   "jmp\t%a0%#"
7134   [(set_attr "type" "uncond_branch")])
7136 (define_expand "nonlocal_goto"
7137   [(match_operand:SI 0 "general_operand" "")
7138    (match_operand:SI 1 "general_operand" "")
7139    (match_operand:SI 2 "general_operand" "")
7140    (match_operand:SI 3 "" "")]
7141   ""
7143   rtx lab = operands[1];
7144   rtx stack = operands[2];
7145   rtx fp = operands[3];
7146   rtx labreg;
7148   /* Trap instruction to flush all the register windows.  */
7149   emit_insn (gen_flush_register_windows ());
7151   /* Load the fp value for the containing fn into %fp.  This is needed
7152      because STACK refers to %fp.  Note that virtual register instantiation
7153      fails if the virtual %fp isn't set from a register.  */
7154   if (GET_CODE (fp) != REG)
7155     fp = force_reg (Pmode, fp);
7156   emit_move_insn (virtual_stack_vars_rtx, fp);
7158   /* Find the containing function's current nonlocal goto handler,
7159      which will do any cleanups and then jump to the label.  */
7160   labreg = gen_rtx_REG (Pmode, 8);
7161   emit_move_insn (labreg, lab);
7163   /* Restore %fp from stack pointer value for containing function.
7164      The restore insn that follows will move this to %sp,
7165      and reload the appropriate value into %fp.  */
7166   emit_move_insn (hard_frame_pointer_rtx, stack);
7168   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
7169   emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
7171   /* ??? The V9-specific version was disabled in rev 1.65.  */
7172   emit_jump_insn (gen_goto_handler_and_restore (labreg));
7173   emit_barrier ();
7174   DONE;
7177 ;; Special trap insn to flush register windows.
7178 (define_insn "flush_register_windows"
7179   [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
7180   ""
7181   { return TARGET_V9 ? "flushw" : "ta\t3"; }
7182   [(set_attr "type" "flushw")])
7184 (define_insn "goto_handler_and_restore"
7185   [(unspec_volatile [(match_operand 0 "register_operand" "=r")] UNSPECV_GOTO)]
7186   "GET_MODE (operands[0]) == Pmode"
7188   if (flag_delayed_branch)
7189     return "jmp\t%0\n\t restore";
7190   else
7191     return "mov\t%0,%%g1\n\trestore\n\tjmp\t%%g1\n\t nop";
7193   [(set (attr "type") (const_string "multi"))
7194    (set (attr "length")
7195         (if_then_else (eq_attr "delayed_branch" "true")
7196                       (const_int 2)
7197                       (const_int 4)))])
7199 ;; For __builtin_setjmp we need to flush register windows iff the function
7200 ;; calls alloca as well, because otherwise the register window might be
7201 ;; saved after %sp adjustment and thus setjmp would crash
7202 (define_expand "builtin_setjmp_setup"
7203   [(match_operand 0 "register_operand" "r")]
7204   ""
7206   emit_insn (gen_do_builtin_setjmp_setup ());
7207   DONE;
7210 (define_insn "do_builtin_setjmp_setup"
7211   [(unspec_volatile [(const_int 0)] UNSPECV_SETJMP)]
7212   ""
7214   if (! current_function_calls_alloca)
7215     return "";
7216   if (! TARGET_V9)
7217     return "\tta\t3\n";
7218   fputs ("\tflushw\n", asm_out_file);
7219   if (flag_pic)
7220     fprintf (asm_out_file, "\tst%c\t%%l7, [%%sp+%d]\n",
7221              TARGET_ARCH64 ? 'x' : 'w',
7222              SPARC_STACK_BIAS + 7 * UNITS_PER_WORD);
7223   fprintf (asm_out_file, "\tst%c\t%%fp, [%%sp+%d]\n",
7224            TARGET_ARCH64 ? 'x' : 'w',
7225            SPARC_STACK_BIAS + 14 * UNITS_PER_WORD);
7226   fprintf (asm_out_file, "\tst%c\t%%i7, [%%sp+%d]\n",
7227            TARGET_ARCH64 ? 'x' : 'w',
7228            SPARC_STACK_BIAS + 15 * UNITS_PER_WORD);
7229   return "";
7231   [(set_attr "type" "multi")
7232    (set (attr "length")
7233         (cond [(eq_attr "calls_alloca" "false")
7234                  (const_int 0)
7235                (eq_attr "isa" "!v9")
7236                  (const_int 1)
7237                (eq_attr "pic" "true")
7238                  (const_int 4)] (const_int 3)))])
7240 ;; Pattern for use after a setjmp to store FP and the return register
7241 ;; into the stack area.
7243 (define_expand "setjmp"
7244   [(const_int 0)]
7245   ""
7247   if (TARGET_ARCH64)
7248     emit_insn (gen_setjmp_64 ());
7249   else
7250     emit_insn (gen_setjmp_32 ());
7251   DONE;
7254 (define_expand "setjmp_32"
7255   [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
7256    (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
7257   ""
7258   { operands[0] = frame_pointer_rtx; })
7260 (define_expand "setjmp_64"
7261   [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
7262    (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
7263   ""
7264   { operands[0] = frame_pointer_rtx; })
7266 ;; Special pattern for the FLUSH instruction.
7268 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
7269 ; of the define_insn otherwise missing a mode.  We make "flush", aka
7270 ; gen_flush, the default one since sparc_initialize_trampoline uses
7271 ; it on SImode mem values.
7273 (define_insn "flush"
7274   [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7275   ""
7276   { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7277   [(set_attr "type" "iflush")])
7279 (define_insn "flushdi"
7280   [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7281   ""
7282   { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7283   [(set_attr "type" "iflush")])
7286 ;; Find first set instructions.
7288 ;; The scan instruction searches from the most significant bit while ffs
7289 ;; searches from the least significant bit.  The bit index and treatment of
7290 ;; zero also differ.  It takes at least 7 instructions to get the proper
7291 ;; result.  Here is an obvious 8 instruction sequence.
7293 ;; XXX
7294 (define_insn "ffssi2"
7295   [(set (match_operand:SI 0 "register_operand" "=&r")
7296         (ffs:SI (match_operand:SI 1 "register_operand" "r")))
7297    (clobber (match_scratch:SI 2 "=&r"))]
7298   "TARGET_SPARCLITE || TARGET_SPARCLET"
7300   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";
7302   [(set_attr "type" "multi")
7303    (set_attr "length" "8")])
7305 ;; ??? This should be a define expand, so that the extra instruction have
7306 ;; a chance of being optimized away.
7308 ;; Disabled because none of the UltraSPARCs implement popc.  The HAL R1
7309 ;; does, but no one uses that and we don't have a switch for it.
7311 ;(define_insn "ffsdi2"
7312 ;  [(set (match_operand:DI 0 "register_operand" "=&r")
7313 ;       (ffs:DI (match_operand:DI 1 "register_operand" "r")))
7314 ;   (clobber (match_scratch:DI 2 "=&r"))]
7315 ;  "TARGET_ARCH64"
7316 ;  "neg\t%1, %2\;xnor\t%1, %2, %2\;popc\t%2, %0\;movzr\t%1, 0, %0"
7317 ;  [(set_attr "type" "multi")
7318 ;   (set_attr "length" "4")])
7322 ;; Peepholes go at the end.
7324 ;; Optimize consecutive loads or stores into ldd and std when possible.
7325 ;; The conditions in which we do this are very restricted and are 
7326 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
7328 (define_peephole2
7329   [(set (match_operand:SI 0 "memory_operand" "")
7330       (const_int 0))
7331    (set (match_operand:SI 1 "memory_operand" "")
7332       (const_int 0))]
7333   "TARGET_V9
7334    && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
7335   [(set (match_dup 0)
7336        (const_int 0))]
7337   "operands[0] = widen_memory_access (operands[0], DImode, 0);")
7339 (define_peephole2
7340   [(set (match_operand:SI 0 "memory_operand" "")
7341       (const_int 0))
7342    (set (match_operand:SI 1 "memory_operand" "")
7343       (const_int 0))]
7344   "TARGET_V9
7345    && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
7346   [(set (match_dup 1)
7347        (const_int 0))]
7348   "operands[1] = widen_memory_access (operands[1], DImode, 0);")
7350 (define_peephole2
7351   [(set (match_operand:SI 0 "register_operand" "")
7352         (match_operand:SI 1 "memory_operand" ""))
7353    (set (match_operand:SI 2 "register_operand" "")
7354         (match_operand:SI 3 "memory_operand" ""))]
7355   "registers_ok_for_ldd_peep (operands[0], operands[2]) 
7356    && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])" 
7357   [(set (match_dup 0)
7358         (match_dup 1))]
7359   "operands[1] = widen_memory_access (operands[1], DImode, 0);
7360    operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
7362 (define_peephole2
7363   [(set (match_operand:SI 0 "memory_operand" "")
7364         (match_operand:SI 1 "register_operand" ""))
7365    (set (match_operand:SI 2 "memory_operand" "")
7366         (match_operand:SI 3 "register_operand" ""))]
7367   "registers_ok_for_ldd_peep (operands[1], operands[3]) 
7368    && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7369   [(set (match_dup 0)
7370         (match_dup 1))]
7371   "operands[0] = widen_memory_access (operands[0], DImode, 0);
7372    operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
7374 (define_peephole2
7375   [(set (match_operand:SF 0 "register_operand" "")
7376         (match_operand:SF 1 "memory_operand" ""))
7377    (set (match_operand:SF 2 "register_operand" "")
7378         (match_operand:SF 3 "memory_operand" ""))]
7379   "registers_ok_for_ldd_peep (operands[0], operands[2]) 
7380    && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
7381   [(set (match_dup 0)
7382         (match_dup 1))]
7383   "operands[1] = widen_memory_access (operands[1], DFmode, 0);
7384    operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
7386 (define_peephole2
7387   [(set (match_operand:SF 0 "memory_operand" "")
7388         (match_operand:SF 1 "register_operand" ""))
7389    (set (match_operand:SF 2 "memory_operand" "")
7390         (match_operand:SF 3 "register_operand" ""))]
7391   "registers_ok_for_ldd_peep (operands[1], operands[3]) 
7392   && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7393   [(set (match_dup 0)
7394         (match_dup 1))]
7395   "operands[0] = widen_memory_access (operands[0], DFmode, 0);
7396    operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
7398 (define_peephole2
7399   [(set (match_operand:SI 0 "register_operand" "")
7400         (match_operand:SI 1 "memory_operand" ""))
7401    (set (match_operand:SI 2 "register_operand" "")
7402         (match_operand:SI 3 "memory_operand" ""))]
7403   "registers_ok_for_ldd_peep (operands[2], operands[0]) 
7404   && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
7405   [(set (match_dup 2)
7406         (match_dup 3))]
7407    "operands[3] = widen_memory_access (operands[3], DImode, 0);
7408     operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
7410 (define_peephole2
7411   [(set (match_operand:SI 0 "memory_operand" "")
7412         (match_operand:SI 1 "register_operand" ""))
7413    (set (match_operand:SI 2 "memory_operand" "")
7414         (match_operand:SI 3 "register_operand" ""))]
7415   "registers_ok_for_ldd_peep (operands[3], operands[1]) 
7416   && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)" 
7417   [(set (match_dup 2)
7418         (match_dup 3))]
7419   "operands[2] = widen_memory_access (operands[2], DImode, 0);
7420    operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
7421    ")
7423 (define_peephole2
7424   [(set (match_operand:SF 0 "register_operand" "")
7425         (match_operand:SF 1 "memory_operand" ""))
7426    (set (match_operand:SF 2 "register_operand" "")
7427         (match_operand:SF 3 "memory_operand" ""))]
7428   "registers_ok_for_ldd_peep (operands[2], operands[0]) 
7429   && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
7430   [(set (match_dup 2)
7431         (match_dup 3))]
7432   "operands[3] = widen_memory_access (operands[3], DFmode, 0);
7433    operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
7435 (define_peephole2
7436   [(set (match_operand:SF 0 "memory_operand" "")
7437         (match_operand:SF 1 "register_operand" ""))
7438    (set (match_operand:SF 2 "memory_operand" "")
7439         (match_operand:SF 3 "register_operand" ""))]
7440   "registers_ok_for_ldd_peep (operands[3], operands[1]) 
7441   && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
7442   [(set (match_dup 2)
7443         (match_dup 3))]
7444   "operands[2] = widen_memory_access (operands[2], DFmode, 0);
7445    operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
7447 ;; Optimize the case of following a reg-reg move with a test
7448 ;; of reg just moved.  Don't allow floating point regs for operand 0 or 1.
7449 ;; This can result from a float to fix conversion.
7451 (define_peephole2
7452   [(set (match_operand:SI 0 "register_operand" "")
7453         (match_operand:SI 1 "register_operand" ""))
7454    (set (reg:CC 100)
7455         (compare:CC (match_operand:SI 2 "register_operand" "")
7456                     (const_int 0)))]
7457   "(rtx_equal_p (operands[2], operands[0])
7458     || rtx_equal_p (operands[2], operands[1]))
7459     && ! SPARC_FP_REG_P (REGNO (operands[0]))
7460     && ! SPARC_FP_REG_P (REGNO (operands[1]))"
7461   [(parallel [(set (match_dup 0) (match_dup 1))
7462               (set (reg:CC 100)
7463                    (compare:CC (match_dup 1) (const_int 0)))])]
7464   "")
7466 (define_peephole2
7467   [(set (match_operand:DI 0 "register_operand" "")
7468         (match_operand:DI 1 "register_operand" ""))
7469    (set (reg:CCX 100)
7470         (compare:CCX (match_operand:DI 2 "register_operand" "")
7471                     (const_int 0)))]
7472   "TARGET_ARCH64
7473    && (rtx_equal_p (operands[2], operands[0])
7474        || rtx_equal_p (operands[2], operands[1]))
7475    && ! SPARC_FP_REG_P (REGNO (operands[0]))
7476    && ! SPARC_FP_REG_P (REGNO (operands[1]))"
7477   [(parallel [(set (match_dup 0) (match_dup 1))
7478               (set (reg:CCX 100)
7479                    (compare:CCX (match_dup 1) (const_int 0)))])]
7480   "")
7483 ;; Prefetch instructions.
7485 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
7486 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
7487 ;; ??? operations.  With DFA we might be able to model this, but it requires a lot of
7488 ;; ??? state.
7489 (define_expand "prefetch"
7490   [(match_operand 0 "address_operand" "")
7491    (match_operand 1 "const_int_operand" "")
7492    (match_operand 2 "const_int_operand" "")]
7493   "TARGET_V9"
7495   if (TARGET_ARCH64)
7496     emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
7497   else
7498     emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
7499   DONE;
7502 (define_insn "prefetch_64"
7503   [(prefetch (match_operand:DI 0 "address_operand" "p")
7504              (match_operand:DI 1 "const_int_operand" "n")
7505              (match_operand:DI 2 "const_int_operand" "n"))]
7506   ""
7508   static const char * const prefetch_instr[2][2] = {
7509     {
7510       "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7511       "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7512     },
7513     {
7514       "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7515       "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7516     }
7517   };
7518   int read_or_write = INTVAL (operands[1]);
7519   int locality = INTVAL (operands[2]);
7521   gcc_assert (read_or_write == 0 || read_or_write == 1);
7522   gcc_assert (locality >= 0 && locality < 4);
7523   return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7525   [(set_attr "type" "load")])
7527 (define_insn "prefetch_32"
7528   [(prefetch (match_operand:SI 0 "address_operand" "p")
7529              (match_operand:SI 1 "const_int_operand" "n")
7530              (match_operand:SI 2 "const_int_operand" "n"))]
7531   ""
7533   static const char * const prefetch_instr[2][2] = {
7534     {
7535       "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7536       "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7537     },
7538     {
7539       "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7540       "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7541     }
7542   };
7543   int read_or_write = INTVAL (operands[1]);
7544   int locality = INTVAL (operands[2]);
7546   gcc_assert (read_or_write == 0 || read_or_write == 1);
7547   gcc_assert (locality >= 0 && locality < 4);
7548   return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7550   [(set_attr "type" "load")])
7553 ;; Trap instructions.
7555 (define_insn "trap"
7556   [(trap_if (const_int 1) (const_int 5))]
7557   ""
7558   "ta\t5"
7559   [(set_attr "type" "trap")])
7561 (define_expand "conditional_trap"
7562   [(trap_if (match_operator 0 "noov_compare_operator" [(match_dup 2) (match_dup 3)])
7563             (match_operand:SI 1 "arith_operand" ""))]
7564   ""
7565   "operands[2] = gen_compare_reg (GET_CODE (operands[0]));
7566    if (GET_MODE (operands[2]) != CCmode && GET_MODE (operands[2]) != CCXmode)
7567      FAIL;
7568    operands[3] = const0_rtx;")
7570 (define_insn ""
7571   [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CC 100) (const_int 0)])
7572             (match_operand:SI 1 "arith_operand" "rM"))]
7573   ""
7575   if (TARGET_V9)
7576     return "t%C0\t%%icc, %1";
7577   else
7578     return "t%C0\t%1";
7580   [(set_attr "type" "trap")])
7582 (define_insn ""
7583   [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CCX 100) (const_int 0)])
7584             (match_operand:SI 1 "arith_operand" "rM"))]
7585   "TARGET_V9"
7586   "t%C0\t%%xcc, %1"
7587   [(set_attr "type" "trap")])
7590 ;; TLS support instructions.
7592 (define_insn "tgd_hi22"
7593   [(set (match_operand:SI 0 "register_operand" "=r")
7594         (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
7595                             UNSPEC_TLSGD)))]
7596   "TARGET_TLS"
7597   "sethi\\t%%tgd_hi22(%a1), %0")
7599 (define_insn "tgd_lo10"
7600   [(set (match_operand:SI 0 "register_operand" "=r")
7601         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7602                    (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
7603                               UNSPEC_TLSGD)))]
7604   "TARGET_TLS"
7605   "add\\t%1, %%tgd_lo10(%a2), %0")
7607 (define_insn "tgd_add32"
7608   [(set (match_operand:SI 0 "register_operand" "=r")
7609         (plus:SI (match_operand:SI 1 "register_operand" "r")
7610                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7611                              (match_operand 3 "tgd_symbolic_operand" "")]
7612                             UNSPEC_TLSGD)))]
7613   "TARGET_TLS && TARGET_ARCH32"
7614   "add\\t%1, %2, %0, %%tgd_add(%a3)")
7616 (define_insn "tgd_add64"
7617   [(set (match_operand:DI 0 "register_operand" "=r")
7618         (plus:DI (match_operand:DI 1 "register_operand" "r")
7619                  (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7620                              (match_operand 3 "tgd_symbolic_operand" "")]
7621                             UNSPEC_TLSGD)))]
7622   "TARGET_TLS && TARGET_ARCH64"
7623   "add\\t%1, %2, %0, %%tgd_add(%a3)")
7625 (define_insn "tgd_call32"
7626   [(set (match_operand 0 "register_operand" "=r")
7627         (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
7628                                   (match_operand 2 "tgd_symbolic_operand" "")]
7629                                  UNSPEC_TLSGD))
7630               (match_operand 3 "" "")))
7631    (clobber (reg:SI 15))]
7632   "TARGET_TLS && TARGET_ARCH32"
7633   "call\t%a1, %%tgd_call(%a2)%#"
7634   [(set_attr "type" "call")])
7636 (define_insn "tgd_call64"
7637   [(set (match_operand 0 "register_operand" "=r")
7638         (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
7639                                   (match_operand 2 "tgd_symbolic_operand" "")]
7640                                  UNSPEC_TLSGD))
7641               (match_operand 3 "" "")))
7642    (clobber (reg:DI 15))]
7643   "TARGET_TLS && TARGET_ARCH64"
7644   "call\t%a1, %%tgd_call(%a2)%#"
7645   [(set_attr "type" "call")])
7647 (define_insn "tldm_hi22"
7648   [(set (match_operand:SI 0 "register_operand" "=r")
7649         (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7650   "TARGET_TLS"
7651   "sethi\\t%%tldm_hi22(%&), %0")
7653 (define_insn "tldm_lo10"
7654   [(set (match_operand:SI 0 "register_operand" "=r")
7655         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7656                     (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7657   "TARGET_TLS"
7658   "add\\t%1, %%tldm_lo10(%&), %0")
7660 (define_insn "tldm_add32"
7661   [(set (match_operand:SI 0 "register_operand" "=r")
7662         (plus:SI (match_operand:SI 1 "register_operand" "r")
7663                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
7664                             UNSPEC_TLSLDM)))]
7665   "TARGET_TLS && TARGET_ARCH32"
7666   "add\\t%1, %2, %0, %%tldm_add(%&)")
7668 (define_insn "tldm_add64"
7669   [(set (match_operand:DI 0 "register_operand" "=r")
7670         (plus:DI (match_operand:DI 1 "register_operand" "r")
7671                  (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
7672                             UNSPEC_TLSLDM)))]
7673   "TARGET_TLS && TARGET_ARCH64"
7674   "add\\t%1, %2, %0, %%tldm_add(%&)")
7676 (define_insn "tldm_call32"
7677   [(set (match_operand 0 "register_operand" "=r")
7678         (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
7679                                  UNSPEC_TLSLDM))
7680               (match_operand 2 "" "")))
7681    (clobber (reg:SI 15))]
7682   "TARGET_TLS && TARGET_ARCH32"
7683   "call\t%a1, %%tldm_call(%&)%#"
7684   [(set_attr "type" "call")])
7686 (define_insn "tldm_call64"
7687   [(set (match_operand 0 "register_operand" "=r")
7688         (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
7689                                  UNSPEC_TLSLDM))
7690               (match_operand 2 "" "")))
7691    (clobber (reg:DI 15))]
7692   "TARGET_TLS && TARGET_ARCH64"
7693   "call\t%a1, %%tldm_call(%&)%#"
7694   [(set_attr "type" "call")])
7696 (define_insn "tldo_hix22"
7697   [(set (match_operand:SI 0 "register_operand" "=r")
7698         (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
7699                             UNSPEC_TLSLDO)))]
7700   "TARGET_TLS"
7701   "sethi\\t%%tldo_hix22(%a1), %0")
7703 (define_insn "tldo_lox10"
7704   [(set (match_operand:SI 0 "register_operand" "=r")
7705         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7706                    (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
7707                               UNSPEC_TLSLDO)))]
7708   "TARGET_TLS"
7709   "xor\\t%1, %%tldo_lox10(%a2), %0")
7711 (define_insn "tldo_add32"
7712   [(set (match_operand:SI 0 "register_operand" "=r")
7713         (plus:SI (match_operand:SI 1 "register_operand" "r")
7714                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7715                              (match_operand 3 "tld_symbolic_operand" "")]
7716                             UNSPEC_TLSLDO)))]
7717   "TARGET_TLS && TARGET_ARCH32"
7718   "add\\t%1, %2, %0, %%tldo_add(%a3)")
7720 (define_insn "tldo_add64"
7721   [(set (match_operand:DI 0 "register_operand" "=r")
7722         (plus:DI (match_operand:DI 1 "register_operand" "r")
7723                  (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7724                              (match_operand 3 "tld_symbolic_operand" "")]
7725                             UNSPEC_TLSLDO)))]
7726   "TARGET_TLS && TARGET_ARCH64"
7727   "add\\t%1, %2, %0, %%tldo_add(%a3)")
7729 (define_insn "tie_hi22"
7730   [(set (match_operand:SI 0 "register_operand" "=r")
7731         (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
7732                             UNSPEC_TLSIE)))]
7733   "TARGET_TLS"
7734   "sethi\\t%%tie_hi22(%a1), %0")
7736 (define_insn "tie_lo10"
7737   [(set (match_operand:SI 0 "register_operand" "=r")
7738         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7739                    (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
7740                               UNSPEC_TLSIE)))]
7741   "TARGET_TLS"
7742   "add\\t%1, %%tie_lo10(%a2), %0")
7744 (define_insn "tie_ld32"
7745   [(set (match_operand:SI 0 "register_operand" "=r")
7746         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
7747                     (match_operand:SI 2 "register_operand" "r")
7748                     (match_operand 3 "tie_symbolic_operand" "")]
7749                    UNSPEC_TLSIE))]
7750   "TARGET_TLS && TARGET_ARCH32"
7751   "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
7752   [(set_attr "type" "load")])
7754 (define_insn "tie_ld64"
7755   [(set (match_operand:DI 0 "register_operand" "=r")
7756         (unspec:DI [(match_operand:DI 1 "register_operand" "r")
7757                     (match_operand:SI 2 "register_operand" "r")
7758                     (match_operand 3 "tie_symbolic_operand" "")]
7759                    UNSPEC_TLSIE))]
7760   "TARGET_TLS && TARGET_ARCH64"
7761   "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
7762   [(set_attr "type" "load")])
7764 (define_insn "tie_add32"
7765   [(set (match_operand:SI 0 "register_operand" "=r")
7766         (plus:SI (match_operand:SI 1 "register_operand" "r")
7767                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7768                              (match_operand 3 "tie_symbolic_operand" "")]
7769                             UNSPEC_TLSIE)))]
7770   "TARGET_SUN_TLS && TARGET_ARCH32"
7771   "add\\t%1, %2, %0, %%tie_add(%a3)")
7773 (define_insn "tie_add64"
7774   [(set (match_operand:DI 0 "register_operand" "=r")
7775         (plus:DI (match_operand:DI 1 "register_operand" "r")
7776                  (unspec:DI [(match_operand:DI 2 "register_operand" "r")
7777                              (match_operand 3 "tie_symbolic_operand" "")]
7778                             UNSPEC_TLSIE)))]
7779   "TARGET_SUN_TLS && TARGET_ARCH64"
7780   "add\\t%1, %2, %0, %%tie_add(%a3)")
7782 (define_insn "tle_hix22_sp32"
7783   [(set (match_operand:SI 0 "register_operand" "=r")
7784         (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
7785                             UNSPEC_TLSLE)))]
7786   "TARGET_TLS && TARGET_ARCH32"
7787   "sethi\\t%%tle_hix22(%a1), %0")
7789 (define_insn "tle_lox10_sp32"
7790   [(set (match_operand:SI 0 "register_operand" "=r")
7791         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7792                    (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
7793                               UNSPEC_TLSLE)))]
7794   "TARGET_TLS && TARGET_ARCH32"
7795   "xor\\t%1, %%tle_lox10(%a2), %0")
7797 (define_insn "tle_hix22_sp64"
7798   [(set (match_operand:DI 0 "register_operand" "=r")
7799         (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
7800                             UNSPEC_TLSLE)))]
7801   "TARGET_TLS && TARGET_ARCH64"
7802   "sethi\\t%%tle_hix22(%a1), %0")
7804 (define_insn "tle_lox10_sp64"
7805   [(set (match_operand:DI 0 "register_operand" "=r")
7806         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
7807                    (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
7808                               UNSPEC_TLSLE)))]
7809   "TARGET_TLS && TARGET_ARCH64"
7810   "xor\\t%1, %%tle_lox10(%a2), %0")
7812 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
7813 (define_insn "*tldo_ldub_sp32"
7814   [(set (match_operand:QI 0 "register_operand" "=r")
7815         (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7816                                      (match_operand 3 "tld_symbolic_operand" "")]
7817                                     UNSPEC_TLSLDO)
7818                          (match_operand:SI 1 "register_operand" "r"))))]
7819   "TARGET_TLS && TARGET_ARCH32"
7820   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7821   [(set_attr "type" "load")
7822    (set_attr "us3load_type" "3cycle")])
7824 (define_insn "*tldo_ldub1_sp32"
7825   [(set (match_operand:HI 0 "register_operand" "=r")
7826         (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7827                                                      (match_operand 3 "tld_symbolic_operand" "")]
7828                                                     UNSPEC_TLSLDO)
7829                                          (match_operand:SI 1 "register_operand" "r")))))]
7830   "TARGET_TLS && TARGET_ARCH32"
7831   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7832   [(set_attr "type" "load")
7833    (set_attr "us3load_type" "3cycle")])
7835 (define_insn "*tldo_ldub2_sp32"
7836   [(set (match_operand:SI 0 "register_operand" "=r")
7837         (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7838                                                      (match_operand 3 "tld_symbolic_operand" "")]
7839                                                     UNSPEC_TLSLDO)
7840                                          (match_operand:SI 1 "register_operand" "r")))))]
7841   "TARGET_TLS && TARGET_ARCH32"
7842   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7843   [(set_attr "type" "load")
7844    (set_attr "us3load_type" "3cycle")])
7846 (define_insn "*tldo_ldsb1_sp32"
7847   [(set (match_operand:HI 0 "register_operand" "=r")
7848         (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7849                                                      (match_operand 3 "tld_symbolic_operand" "")]
7850                                                     UNSPEC_TLSLDO)
7851                                          (match_operand:SI 1 "register_operand" "r")))))]
7852   "TARGET_TLS && TARGET_ARCH32"
7853   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7854   [(set_attr "type" "sload")
7855    (set_attr "us3load_type" "3cycle")])
7857 (define_insn "*tldo_ldsb2_sp32"
7858   [(set (match_operand:SI 0 "register_operand" "=r")
7859         (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7860                                                      (match_operand 3 "tld_symbolic_operand" "")]
7861                                                     UNSPEC_TLSLDO)
7862                                          (match_operand:SI 1 "register_operand" "r")))))]
7863   "TARGET_TLS && TARGET_ARCH32"
7864   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7865   [(set_attr "type" "sload")
7866    (set_attr "us3load_type" "3cycle")])
7868 (define_insn "*tldo_ldub_sp64"
7869   [(set (match_operand:QI 0 "register_operand" "=r")
7870         (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7871                                      (match_operand 3 "tld_symbolic_operand" "")]
7872                                     UNSPEC_TLSLDO)
7873                          (match_operand:DI 1 "register_operand" "r"))))]
7874   "TARGET_TLS && TARGET_ARCH64"
7875   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7876   [(set_attr "type" "load")
7877    (set_attr "us3load_type" "3cycle")])
7879 (define_insn "*tldo_ldub1_sp64"
7880   [(set (match_operand:HI 0 "register_operand" "=r")
7881         (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7882                                                      (match_operand 3 "tld_symbolic_operand" "")]
7883                                                     UNSPEC_TLSLDO)
7884                                          (match_operand:DI 1 "register_operand" "r")))))]
7885   "TARGET_TLS && TARGET_ARCH64"
7886   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7887   [(set_attr "type" "load")
7888    (set_attr "us3load_type" "3cycle")])
7890 (define_insn "*tldo_ldub2_sp64"
7891   [(set (match_operand:SI 0 "register_operand" "=r")
7892         (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7893                                                      (match_operand 3 "tld_symbolic_operand" "")]
7894                                                     UNSPEC_TLSLDO)
7895                                          (match_operand:DI 1 "register_operand" "r")))))]
7896   "TARGET_TLS && TARGET_ARCH64"
7897   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7898   [(set_attr "type" "load")
7899    (set_attr "us3load_type" "3cycle")])
7901 (define_insn "*tldo_ldub3_sp64"
7902   [(set (match_operand:DI 0 "register_operand" "=r")
7903         (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7904                                                      (match_operand 3 "tld_symbolic_operand" "")]
7905                                                     UNSPEC_TLSLDO)
7906                                          (match_operand:DI 1 "register_operand" "r")))))]
7907   "TARGET_TLS && TARGET_ARCH64"
7908   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7909   [(set_attr "type" "load")
7910    (set_attr "us3load_type" "3cycle")])
7912 (define_insn "*tldo_ldsb1_sp64"
7913   [(set (match_operand:HI 0 "register_operand" "=r")
7914         (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7915                                                      (match_operand 3 "tld_symbolic_operand" "")]
7916                                                     UNSPEC_TLSLDO)
7917                                          (match_operand:DI 1 "register_operand" "r")))))]
7918   "TARGET_TLS && TARGET_ARCH64"
7919   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7920   [(set_attr "type" "sload")
7921    (set_attr "us3load_type" "3cycle")])
7923 (define_insn "*tldo_ldsb2_sp64"
7924   [(set (match_operand:SI 0 "register_operand" "=r")
7925         (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7926                                                      (match_operand 3 "tld_symbolic_operand" "")]
7927                                                     UNSPEC_TLSLDO)
7928                                          (match_operand:DI 1 "register_operand" "r")))))]
7929   "TARGET_TLS && TARGET_ARCH64"
7930   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7931   [(set_attr "type" "sload")
7932    (set_attr "us3load_type" "3cycle")])
7934 (define_insn "*tldo_ldsb3_sp64"
7935   [(set (match_operand:DI 0 "register_operand" "=r")
7936         (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7937                                                      (match_operand 3 "tld_symbolic_operand" "")]
7938                                                     UNSPEC_TLSLDO)
7939                                          (match_operand:DI 1 "register_operand" "r")))))]
7940   "TARGET_TLS && TARGET_ARCH64"
7941   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7942   [(set_attr "type" "sload")
7943    (set_attr "us3load_type" "3cycle")])
7945 (define_insn "*tldo_lduh_sp32"
7946   [(set (match_operand:HI 0 "register_operand" "=r")
7947         (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7948                                      (match_operand 3 "tld_symbolic_operand" "")]
7949                                     UNSPEC_TLSLDO)
7950                          (match_operand:SI 1 "register_operand" "r"))))]
7951   "TARGET_TLS && TARGET_ARCH32"
7952   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7953   [(set_attr "type" "load")
7954    (set_attr "us3load_type" "3cycle")])
7956 (define_insn "*tldo_lduh1_sp32"
7957   [(set (match_operand:SI 0 "register_operand" "=r")
7958         (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7959                                                      (match_operand 3 "tld_symbolic_operand" "")]
7960                                                     UNSPEC_TLSLDO)
7961                                          (match_operand:SI 1 "register_operand" "r")))))]
7962   "TARGET_TLS && TARGET_ARCH32"
7963   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7964   [(set_attr "type" "load")
7965    (set_attr "us3load_type" "3cycle")])
7967 (define_insn "*tldo_ldsh1_sp32"
7968   [(set (match_operand:SI 0 "register_operand" "=r")
7969         (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7970                                                      (match_operand 3 "tld_symbolic_operand" "")]
7971                                                     UNSPEC_TLSLDO)
7972                                          (match_operand:SI 1 "register_operand" "r")))))]
7973   "TARGET_TLS && TARGET_ARCH32"
7974   "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7975   [(set_attr "type" "sload")
7976    (set_attr "us3load_type" "3cycle")])
7978 (define_insn "*tldo_lduh_sp64"
7979   [(set (match_operand:HI 0 "register_operand" "=r")
7980         (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7981                                      (match_operand 3 "tld_symbolic_operand" "")]
7982                                     UNSPEC_TLSLDO)
7983                          (match_operand:DI 1 "register_operand" "r"))))]
7984   "TARGET_TLS && TARGET_ARCH64"
7985   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7986   [(set_attr "type" "load")
7987    (set_attr "us3load_type" "3cycle")])
7989 (define_insn "*tldo_lduh1_sp64"
7990   [(set (match_operand:SI 0 "register_operand" "=r")
7991         (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7992                                                      (match_operand 3 "tld_symbolic_operand" "")]
7993                                                     UNSPEC_TLSLDO)
7994                                          (match_operand:DI 1 "register_operand" "r")))))]
7995   "TARGET_TLS && TARGET_ARCH64"
7996   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7997   [(set_attr "type" "load")
7998    (set_attr "us3load_type" "3cycle")])
8000 (define_insn "*tldo_lduh2_sp64"
8001   [(set (match_operand:DI 0 "register_operand" "=r")
8002         (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8003                                                      (match_operand 3 "tld_symbolic_operand" "")]
8004                                                     UNSPEC_TLSLDO)
8005                                          (match_operand:DI 1 "register_operand" "r")))))]
8006   "TARGET_TLS && TARGET_ARCH64"
8007   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8008   [(set_attr "type" "load")
8009    (set_attr "us3load_type" "3cycle")])
8011 (define_insn "*tldo_ldsh1_sp64"
8012   [(set (match_operand:SI 0 "register_operand" "=r")
8013         (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8014                                                      (match_operand 3 "tld_symbolic_operand" "")]
8015                                                     UNSPEC_TLSLDO)
8016                                          (match_operand:DI 1 "register_operand" "r")))))]
8017   "TARGET_TLS && TARGET_ARCH64"
8018   "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8019   [(set_attr "type" "sload")
8020    (set_attr "us3load_type" "3cycle")])
8022 (define_insn "*tldo_ldsh2_sp64"
8023   [(set (match_operand:DI 0 "register_operand" "=r")
8024         (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8025                                                      (match_operand 3 "tld_symbolic_operand" "")]
8026                                                     UNSPEC_TLSLDO)
8027                                          (match_operand:DI 1 "register_operand" "r")))))]
8028   "TARGET_TLS && TARGET_ARCH64"
8029   "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8030   [(set_attr "type" "sload")
8031    (set_attr "us3load_type" "3cycle")])
8033 (define_insn "*tldo_lduw_sp32"
8034   [(set (match_operand:SI 0 "register_operand" "=r")
8035         (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8036                                      (match_operand 3 "tld_symbolic_operand" "")]
8037                                     UNSPEC_TLSLDO)
8038                          (match_operand:SI 1 "register_operand" "r"))))]
8039   "TARGET_TLS && TARGET_ARCH32"
8040   "ld\t[%1 + %2], %0, %%tldo_add(%3)"
8041   [(set_attr "type" "load")])
8043 (define_insn "*tldo_lduw_sp64"
8044   [(set (match_operand:SI 0 "register_operand" "=r")
8045         (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8046                                      (match_operand 3 "tld_symbolic_operand" "")]
8047                                     UNSPEC_TLSLDO)
8048                          (match_operand:DI 1 "register_operand" "r"))))]
8049   "TARGET_TLS && TARGET_ARCH64"
8050   "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8051   [(set_attr "type" "load")])
8053 (define_insn "*tldo_lduw1_sp64"
8054   [(set (match_operand:DI 0 "register_operand" "=r")
8055         (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8056                                                      (match_operand 3 "tld_symbolic_operand" "")]
8057                                                     UNSPEC_TLSLDO)
8058                                          (match_operand:DI 1 "register_operand" "r")))))]
8059   "TARGET_TLS && TARGET_ARCH64"
8060   "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8061   [(set_attr "type" "load")])
8063 (define_insn "*tldo_ldsw1_sp64"
8064   [(set (match_operand:DI 0 "register_operand" "=r")
8065         (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8066                                                      (match_operand 3 "tld_symbolic_operand" "")]
8067                                                     UNSPEC_TLSLDO)
8068                                          (match_operand:DI 1 "register_operand" "r")))))]
8069   "TARGET_TLS && TARGET_ARCH64"
8070   "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
8071   [(set_attr "type" "sload")
8072    (set_attr "us3load_type" "3cycle")])
8074 (define_insn "*tldo_ldx_sp64"
8075   [(set (match_operand:DI 0 "register_operand" "=r")
8076         (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8077                                      (match_operand 3 "tld_symbolic_operand" "")]
8078                                     UNSPEC_TLSLDO)
8079                          (match_operand:DI 1 "register_operand" "r"))))]
8080   "TARGET_TLS && TARGET_ARCH64"
8081   "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
8082   [(set_attr "type" "load")])
8084 (define_insn "*tldo_stb_sp32"
8085   [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8086                                      (match_operand 3 "tld_symbolic_operand" "")]
8087                                     UNSPEC_TLSLDO)
8088                          (match_operand:SI 1 "register_operand" "r")))
8089         (match_operand:QI 0 "register_operand" "=r"))]
8090   "TARGET_TLS && TARGET_ARCH32"
8091   "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8092   [(set_attr "type" "store")])
8094 (define_insn "*tldo_stb_sp64"
8095   [(set (mem:QI (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         (match_operand:QI 0 "register_operand" "=r"))]
8100   "TARGET_TLS && TARGET_ARCH64"
8101   "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8102   [(set_attr "type" "store")])
8104 (define_insn "*tldo_sth_sp32"
8105   [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8106                                      (match_operand 3 "tld_symbolic_operand" "")]
8107                                     UNSPEC_TLSLDO)
8108                          (match_operand:SI 1 "register_operand" "r")))
8109         (match_operand:HI 0 "register_operand" "=r"))]
8110   "TARGET_TLS && TARGET_ARCH32"
8111   "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8112   [(set_attr "type" "store")])
8114 (define_insn "*tldo_sth_sp64"
8115   [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8116                                      (match_operand 3 "tld_symbolic_operand" "")]
8117                                     UNSPEC_TLSLDO)
8118                          (match_operand:DI 1 "register_operand" "r")))
8119         (match_operand:HI 0 "register_operand" "=r"))]
8120   "TARGET_TLS && TARGET_ARCH64"
8121   "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8122   [(set_attr "type" "store")])
8124 (define_insn "*tldo_stw_sp32"
8125   [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8126                                      (match_operand 3 "tld_symbolic_operand" "")]
8127                                     UNSPEC_TLSLDO)
8128                          (match_operand:SI 1 "register_operand" "r")))
8129         (match_operand:SI 0 "register_operand" "=r"))]
8130   "TARGET_TLS && TARGET_ARCH32"
8131   "st\t%0, [%1 + %2], %%tldo_add(%3)"
8132   [(set_attr "type" "store")])
8134 (define_insn "*tldo_stw_sp64"
8135   [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8136                                      (match_operand 3 "tld_symbolic_operand" "")]
8137                                     UNSPEC_TLSLDO)
8138                          (match_operand:DI 1 "register_operand" "r")))
8139         (match_operand:SI 0 "register_operand" "=r"))]
8140   "TARGET_TLS && TARGET_ARCH64"
8141   "stw\t%0, [%1 + %2], %%tldo_add(%3)"
8142   [(set_attr "type" "store")])
8144 (define_insn "*tldo_stx_sp64"
8145   [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8146                                      (match_operand 3 "tld_symbolic_operand" "")]
8147                                     UNSPEC_TLSLDO)
8148                          (match_operand:DI 1 "register_operand" "r")))
8149         (match_operand:DI 0 "register_operand" "=r"))]
8150   "TARGET_TLS && TARGET_ARCH64"
8151   "stx\t%0, [%1 + %2], %%tldo_add(%3)"
8152   [(set_attr "type" "store")])
8155 ;; Stack protector instructions.
8157 (define_expand "stack_protect_set"
8158   [(match_operand 0 "memory_operand" "")
8159    (match_operand 1 "memory_operand" "")]
8160   ""
8162 #ifdef TARGET_THREAD_SSP_OFFSET
8163   rtx tlsreg = gen_rtx_REG (Pmode, 7);
8164   rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
8165   operands[1] = gen_rtx_MEM (Pmode, addr);
8166 #endif
8167   if (TARGET_ARCH64)
8168     emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
8169   else
8170     emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
8171   DONE;
8174 (define_insn "stack_protect_setsi"
8175   [(set (match_operand:SI 0 "memory_operand" "=m")
8176         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
8177    (set (match_scratch:SI 2 "=&r") (const_int 0))]
8178   "TARGET_ARCH32"
8179   "ld\t%1, %2\;st\t%2, %0\;mov\t0, %2"
8180   [(set_attr "type" "multi")
8181    (set_attr "length" "3")])
8183 (define_insn "stack_protect_setdi"
8184   [(set (match_operand:DI 0 "memory_operand" "=m")
8185         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
8186    (set (match_scratch:DI 2 "=&r") (const_int 0))]
8187   "TARGET_ARCH64"
8188   "ldx\t%1, %2\;stx\t%2, %0\;mov\t0, %2"
8189   [(set_attr "type" "multi")
8190    (set_attr "length" "3")])
8192 (define_expand "stack_protect_test"
8193   [(match_operand 0 "memory_operand" "")
8194    (match_operand 1 "memory_operand" "")
8195    (match_operand 2 "" "")]
8196   ""
8198 #ifdef TARGET_THREAD_SSP_OFFSET
8199   rtx tlsreg = gen_rtx_REG (Pmode, 7);
8200   rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
8201   operands[1] = gen_rtx_MEM (Pmode, addr);
8202 #endif
8203   if (TARGET_ARCH64)
8204     {
8205       rtx temp = gen_reg_rtx (Pmode);
8206       emit_insn (gen_stack_protect_testdi (temp, operands[0], operands[1]));
8207       sparc_compare_op0 = temp;
8208       sparc_compare_op1 = const0_rtx;
8209     }
8210   else
8211     {
8212       emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
8213       sparc_compare_op0 = operands[0];
8214       sparc_compare_op1 = operands[1];
8215       sparc_compare_emitted = gen_rtx_REG (CCmode, SPARC_ICC_REG);
8216     }
8217   emit_jump_insn (gen_beq (operands[2]));
8218   DONE;
8221 (define_insn "stack_protect_testsi"
8222   [(set (reg:CC 100)
8223         (unspec:CC [(match_operand:SI 0 "memory_operand" "m")
8224                     (match_operand:SI 1 "memory_operand" "m")]
8225                    UNSPEC_SP_TEST))
8226    (set (match_scratch:SI 3 "=r") (const_int 0))
8227    (clobber (match_scratch:SI 2 "=&r"))]
8228   "TARGET_ARCH32"
8229   "ld\t%0, %2\;ld\t%1, %3\;xorcc\t%2, %3, %2\;mov\t0, %3"
8230   [(set_attr "type" "multi")
8231    (set_attr "length" "4")])
8233 (define_insn "stack_protect_testdi"
8234   [(set (match_operand:DI 0 "register_operand" "=&r")
8235         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
8236                     (match_operand:DI 2 "memory_operand" "m")]
8237                    UNSPEC_SP_TEST))
8238    (set (match_scratch:DI 3 "=r") (const_int 0))]
8239   "TARGET_ARCH64"
8240   "ldx\t%1, %0\;ldx\t%2, %3\;xor\t%0, %3, %0\;mov\t0, %3"
8241   [(set_attr "type" "multi")
8242    (set_attr "length" "4")])
8245 ;; Vector instructions.
8247 (define_insn "addv2si3"
8248   [(set (match_operand:V2SI 0 "register_operand" "=e")
8249         (plus:V2SI (match_operand:V2SI 1 "register_operand" "e")
8250                    (match_operand:V2SI 2 "register_operand" "e")))]
8251   "TARGET_VIS"
8252   "fpadd32\t%1, %2, %0"
8253   [(set_attr "type" "fga")
8254    (set_attr "fptype" "double")])
8256 (define_insn "addv4hi3"
8257   [(set (match_operand:V4HI 0 "register_operand" "=e")
8258          (plus:V4HI (match_operand:V4HI 1 "register_operand" "e")
8259                     (match_operand:V4HI 2 "register_operand" "e")))]
8260   "TARGET_VIS"
8261   "fpadd16\t%1, %2, %0"
8262   [(set_attr "type" "fga")
8263    (set_attr "fptype" "double")])
8265 ;; fpadd32s is emitted by the addsi3 pattern.
8267 (define_insn "addv2hi3"
8268   [(set (match_operand:V2HI 0 "register_operand" "=f")
8269         (plus:V2HI (match_operand:V2HI 1 "register_operand" "f")
8270                    (match_operand:V2HI 2 "register_operand" "f")))]
8271   "TARGET_VIS"
8272   "fpadd16s\t%1, %2, %0"
8273   [(set_attr "type" "fga")
8274    (set_attr "fptype" "single")])
8276 (define_insn "subv2si3"
8277   [(set (match_operand:V2SI 0 "register_operand" "=e")
8278         (minus:V2SI (match_operand:V2SI 1 "register_operand" "e")
8279                     (match_operand:V2SI 2 "register_operand" "e")))]
8280   "TARGET_VIS"
8281   "fpsub32\t%1, %2, %0"
8282   [(set_attr "type" "fga")
8283    (set_attr "fptype" "double")])
8285 (define_insn "subv4hi3"
8286   [(set (match_operand:V4HI 0 "register_operand" "=e")
8287         (minus:V4HI (match_operand:V4HI 1 "register_operand" "e")
8288                     (match_operand:V4HI 2 "register_operand" "e")))]
8289   "TARGET_VIS"
8290   "fpsub16\t%1, %2, %0"
8291   [(set_attr "type" "fga")
8292    (set_attr "fptype" "double")])
8294 ;; fpsub32s is emitted by the subsi3 pattern.
8296 (define_insn "subv2hi3"
8297   [(set (match_operand:V2HI 0 "register_operand" "=f")
8298         (minus:V2HI (match_operand:V2HI 1 "register_operand" "f")
8299                     (match_operand:V2HI 2 "register_operand" "f")))]
8300   "TARGET_VIS"
8301   "fpsub16s\t%1, %2, %0"
8302   [(set_attr "type" "fga")
8303    (set_attr "fptype" "single")])
8305 ;; All other logical instructions have integer equivalents so they
8306 ;; are defined together.
8308 ;; (ior (not (op1)) (not (op2))) is the canonical form of NAND.
8310 (define_insn "*nand<V64mode>_vis"
8311   [(set (match_operand:V64 0 "register_operand" "=e")
8312         (ior:V64 (not:V64 (match_operand:V64 1 "register_operand" "e"))
8313                  (not:V64 (match_operand:V64 2 "register_operand" "e"))))]
8314   "TARGET_VIS"
8315   "fnand\t%1, %2, %0"
8316   [(set_attr "type" "fga")
8317    (set_attr "fptype" "double")])
8319 (define_insn "*nand<V32mode>_vis"
8320   [(set (match_operand:V32 0 "register_operand" "=f")
8321          (ior:V32 (not:V32 (match_operand:V32 1 "register_operand" "f"))
8322                   (not:V32 (match_operand:V32 2 "register_operand" "f"))))]
8323   "TARGET_VIS"
8324   "fnands\t%1, %2, %0"
8325   [(set_attr "type" "fga")
8326    (set_attr "fptype" "single")])
8328 ;; Hard to generate VIS instructions.  We have builtins for these.
8330 (define_insn "fpack16_vis"
8331   [(set (match_operand:V4QI 0 "register_operand" "=f")
8332         (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e")]
8333                       UNSPEC_FPACK16))]
8334   "TARGET_VIS"
8335   "fpack16\t%1, %0"
8336   [(set_attr "type" "fga")
8337    (set_attr "fptype" "double")])
8339 (define_insn "fpackfix_vis"
8340   [(set (match_operand:V2HI 0 "register_operand" "=f")
8341         (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e")]
8342                       UNSPEC_FPACKFIX))]
8343   "TARGET_VIS"
8344   "fpackfix\t%1, %0"
8345   [(set_attr "type" "fga")
8346    (set_attr "fptype" "double")])
8348 (define_insn "fpack32_vis"
8349   [(set (match_operand:V8QI 0 "register_operand" "=e")
8350         (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e")
8351                       (match_operand:V8QI 2 "register_operand" "e")]
8352                      UNSPEC_FPACK32))]
8353   "TARGET_VIS"
8354   "fpack32\t%1, %2, %0"
8355   [(set_attr "type" "fga")
8356    (set_attr "fptype" "double")])
8358 (define_insn "fexpand_vis"
8359   [(set (match_operand:V4HI 0 "register_operand" "=e")
8360         (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")]
8361          UNSPEC_FEXPAND))]
8362  "TARGET_VIS"
8363  "fexpand\t%1, %0"
8364  [(set_attr "type" "fga")
8365   (set_attr "fptype" "double")])
8367 ;; It may be possible to describe this operation as (1 indexed):
8368 ;; (vec_select (vec_duplicate (vec_duplicate (vec_concat 1 2)))
8369 ;;  1,5,10,14,19,23,28,32)
8370 ;; Note that (vec_merge:V8QI [(V4QI) (V4QI)] (10101010 = 170) doesn't work
8371 ;; because vec_merge expects all the operands to be of the same type.
8372 (define_insn "fpmerge_vis"
8373   [(set (match_operand:V8QI 0 "register_operand" "=e")
8374         (unspec:V8QI [(match_operand:V4QI 1 "register_operand" "f")
8375                       (match_operand:V4QI 2 "register_operand" "f")]
8376          UNSPEC_FPMERGE))]
8377  "TARGET_VIS"
8378  "fpmerge\t%1, %2, %0"
8379  [(set_attr "type" "fga")
8380   (set_attr "fptype" "double")])
8382 ;; Partitioned multiply instructions
8383 (define_insn "fmul8x16_vis"
8384   [(set (match_operand:V4HI 0 "register_operand" "=e")
8385         (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
8386                    (match_operand:V4HI 2 "register_operand" "e")))]
8387   "TARGET_VIS"
8388   "fmul8x16\t%1, %2, %0"
8389   [(set_attr "type" "fpmul")
8390    (set_attr "fptype" "double")])
8392 ;; Only one of the following two insns can be a multiply.
8393 (define_insn "fmul8x16au_vis"
8394   [(set (match_operand:V4HI 0 "register_operand" "=e")
8395         (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
8396                    (match_operand:V2HI 2 "register_operand" "f")))]
8397   "TARGET_VIS"
8398   "fmul8x16au\t%1, %2, %0"
8399   [(set_attr "type" "fpmul")
8400    (set_attr "fptype" "double")])
8402 (define_insn "fmul8x16al_vis"
8403   [(set (match_operand:V4HI 0 "register_operand" "=e")
8404         (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8405                       (match_operand:V2HI 2 "register_operand" "f")]
8406          UNSPEC_MUL16AL))]
8407   "TARGET_VIS"
8408   "fmul8x16al\t%1, %2, %0"
8409   [(set_attr "type" "fpmul")
8410    (set_attr "fptype" "double")])
8412 ;; Only one of the following two insns can be a multiply.
8413 (define_insn "fmul8sux16_vis"
8414   [(set (match_operand:V4HI 0 "register_operand" "=e")
8415         (mult:V4HI (match_operand:V8QI 1 "register_operand" "e")
8416                    (match_operand:V4HI 2 "register_operand" "e")))]
8417   "TARGET_VIS"
8418   "fmul8sux16\t%1, %2, %0"
8419   [(set_attr "type" "fpmul")
8420    (set_attr "fptype" "double")])
8422 (define_insn "fmul8ulx16_vis"
8423   [(set (match_operand:V4HI 0 "register_operand" "=e")
8424         (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
8425                       (match_operand:V4HI 2 "register_operand" "e")]
8426          UNSPEC_MUL8UL))]
8427   "TARGET_VIS"
8428   "fmul8ulx16\t%1, %2, %0"
8429   [(set_attr "type" "fpmul")
8430    (set_attr "fptype" "double")])
8432 ;; Only one of the following two insns can be a multiply.
8433 (define_insn "fmuld8sux16_vis"
8434   [(set (match_operand:V2SI 0 "register_operand" "=e")
8435         (mult:V2SI (match_operand:V4QI 1 "register_operand" "f")
8436                    (match_operand:V2HI 2 "register_operand" "f")))]
8437   "TARGET_VIS"
8438   "fmuld8sux16\t%1, %2, %0"
8439   [(set_attr "type" "fpmul")
8440    (set_attr "fptype" "double")])
8442 (define_insn "fmuld8ulx16_vis"
8443   [(set (match_operand:V2SI 0 "register_operand" "=e")
8444         (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
8445                       (match_operand:V2HI 2 "register_operand" "f")]
8446          UNSPEC_MULDUL))]
8447   "TARGET_VIS"
8448   "fmuld8ulx16\t%1, %2, %0"
8449   [(set_attr "type" "fpmul")
8450    (set_attr "fptype" "double")])
8452 ;; Using faligndata only makes sense after an alignaddr since the choice of
8453 ;; bytes to take out of each operand is dependent on the results of the last
8454 ;; alignaddr.
8455 (define_insn "faligndata<V64I:mode>_vis"
8456   [(set (match_operand:V64I 0 "register_operand" "=e")
8457         (unspec:V64I [(match_operand:V64I 1 "register_operand" "e")
8458                       (match_operand:V64I 2 "register_operand" "e")]
8459          UNSPEC_ALIGNDATA))]
8460   "TARGET_VIS"
8461   "faligndata\t%1, %2, %0"
8462   [(set_attr "type" "fga")
8463    (set_attr "fptype" "double")])
8465 (define_insn "alignaddr<P:mode>_vis"
8466   [(set (match_operand:P 0 "register_operand" "=r")
8467         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8468                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
8469          UNSPEC_ALIGNADDR))]
8470   "TARGET_VIS"
8471   "alignaddr\t%r1, %r2, %0")
8473 (define_insn "pdist_vis"
8474   [(set (match_operand:DI 0 "register_operand" "=e")
8475         (unspec:DI [(match_operand:V8QI 1 "register_operand" "e")
8476                     (match_operand:V8QI 2 "register_operand" "e")
8477                     (match_operand:DI 3 "register_operand" "0")]
8478          UNSPEC_PDIST))]
8479   "TARGET_VIS"
8480   "pdist\t%1, %2, %0"
8481   [(set_attr "type" "fga")
8482    (set_attr "fptype" "double")])
8484 (include "sync.md")