Sun Niagara specific optimizations.
[official-gcc.git] / gcc / config / sparc / sparc.md
blobb6ebb8287a168e9ddf3ab243ae0006c722bf2aa7
1 ;; Machine description for SPARC chip for GCC
2 ;;  Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 ;;  1999, 2000, 2001, 2002, 2003, 2004, 2005,2006 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    niagara"
99   (const (symbol_ref "sparc_cpu_attr")))
101 ;; Attribute for the instruction set.
102 ;; At present we only need to distinguish v9/!v9, but for clarity we
103 ;; test TARGET_V8 too.
104 (define_attr "isa" "v7,v8,v9,sparclet"
105  (const
106   (cond [(symbol_ref "TARGET_V9") (const_string "v9")
107          (symbol_ref "TARGET_V8") (const_string "v8")
108          (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
109         (const_string "v7"))))
111 ;; Insn type.
112 (define_attr "type"
113   "ialu,compare,shift,
114    load,sload,store,
115    uncond_branch,branch,call,sibcall,call_no_delay_slot,return,
116    imul,idiv,
117    fpload,fpstore,
118    fp,fpmove,
119    fpcmove,fpcrmove,
120    fpcmp,
121    fpmul,fpdivs,fpdivd,
122    fpsqrts,fpsqrtd,
123    fga,fgm_pack,fgm_mul,fgm_pdist,fgm_cmp,
124    cmove,
125    ialuX,
126    multi,savew,flushw,iflush,trap"
127   (const_string "ialu"))
129 ;; True if branch/call has empty delay slot and will emit a nop in it
130 (define_attr "empty_delay_slot" "false,true"
131   (symbol_ref "empty_delay_slot (insn)"))
133 (define_attr "branch_type" "none,icc,fcc,reg"
134   (const_string "none"))
136 (define_attr "pic" "false,true"
137   (symbol_ref "flag_pic != 0"))
139 (define_attr "calls_alloca" "false,true"
140   (symbol_ref "current_function_calls_alloca != 0"))
142 (define_attr "calls_eh_return" "false,true"
143    (symbol_ref "current_function_calls_eh_return !=0 "))
144    
145 (define_attr "leaf_function" "false,true"
146   (symbol_ref "current_function_uses_only_leaf_regs != 0"))
148 (define_attr "delayed_branch" "false,true"
149   (symbol_ref "flag_delayed_branch != 0"))
151 ;; Length (in # of insns).
152 ;; Beware that setting a length greater or equal to 3 for conditional branches
153 ;; has a side-effect (see output_cbranch and output_v9branch).
154 (define_attr "length" ""
155   (cond [(eq_attr "type" "uncond_branch,call")
156            (if_then_else (eq_attr "empty_delay_slot" "true")
157              (const_int 2)
158              (const_int 1))
159          (eq_attr "type" "sibcall")
160            (if_then_else (eq_attr "leaf_function" "true")
161              (if_then_else (eq_attr "empty_delay_slot" "true")
162                (const_int 3)
163                (const_int 2))
164              (if_then_else (eq_attr "empty_delay_slot" "true")
165                (const_int 2)
166                (const_int 1)))
167          (eq_attr "branch_type" "icc")
168            (if_then_else (match_operand 0 "noov_compare64_operator" "")
169              (if_then_else (lt (pc) (match_dup 1))
170                (if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000))
171                  (if_then_else (eq_attr "empty_delay_slot" "true")
172                    (const_int 2)
173                    (const_int 1))
174                  (if_then_else (eq_attr "empty_delay_slot" "true")
175                    (const_int 4)
176                    (const_int 3)))
177                (if_then_else (lt (minus (pc) (match_dup 1)) (const_int 260000))
178                  (if_then_else (eq_attr "empty_delay_slot" "true")
179                    (const_int 2)
180                    (const_int 1))
181                  (if_then_else (eq_attr "empty_delay_slot" "true")
182                    (const_int 4)
183                    (const_int 3))))
184              (if_then_else (eq_attr "empty_delay_slot" "true")
185                (const_int 2)
186                (const_int 1)))
187          (eq_attr "branch_type" "fcc")
188            (if_then_else (match_operand 0 "fcc0_register_operand" "")
189              (if_then_else (eq_attr "empty_delay_slot" "true")
190                (if_then_else (eq (symbol_ref "TARGET_V9") (const_int 0))
191                  (const_int 3)
192                  (const_int 2))
193                (if_then_else (eq (symbol_ref "TARGET_V9") (const_int 0))
194                  (const_int 2)
195                  (const_int 1)))
196              (if_then_else (lt (pc) (match_dup 2))
197                (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000))
198                  (if_then_else (eq_attr "empty_delay_slot" "true")
199                    (const_int 2)
200                    (const_int 1))
201                  (if_then_else (eq_attr "empty_delay_slot" "true")
202                    (const_int 4)
203                    (const_int 3)))
204                (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000))
205                  (if_then_else (eq_attr "empty_delay_slot" "true")
206                    (const_int 2)
207                    (const_int 1))
208                  (if_then_else (eq_attr "empty_delay_slot" "true")
209                    (const_int 4)
210                    (const_int 3)))))
211          (eq_attr "branch_type" "reg")
212            (if_then_else (lt (pc) (match_dup 2))
213              (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000))
214                (if_then_else (eq_attr "empty_delay_slot" "true")
215                  (const_int 2)
216                  (const_int 1))
217                (if_then_else (eq_attr "empty_delay_slot" "true")
218                  (const_int 4)
219                  (const_int 3)))
220              (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000))
221                (if_then_else (eq_attr "empty_delay_slot" "true")
222                  (const_int 2)
223                  (const_int 1))
224                (if_then_else (eq_attr "empty_delay_slot" "true")
225                  (const_int 4)
226                  (const_int 3))))
227          ] (const_int 1)))
229 ;; FP precision.
230 (define_attr "fptype" "single,double"
231   (const_string "single"))
233 ;; UltraSPARC-III integer load type.
234 (define_attr "us3load_type" "2cycle,3cycle"
235   (const_string "2cycle"))
237 (define_asm_attributes
238   [(set_attr "length" "2")
239    (set_attr "type" "multi")])
241 ;; Attributes for instruction and branch scheduling
242 (define_attr "tls_call_delay" "false,true"
243   (symbol_ref "tls_call_delay (insn)"))
245 (define_attr "in_call_delay" "false,true"
246   (cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
247                 (const_string "false")
248          (eq_attr "type" "load,fpload,store,fpstore")
249                 (if_then_else (eq_attr "length" "1")
250                               (const_string "true")
251                               (const_string "false"))]
252         (if_then_else (and (eq_attr "length" "1")
253                            (eq_attr "tls_call_delay" "true"))
254                       (const_string "true")
255                       (const_string "false"))))
257 (define_attr "eligible_for_sibcall_delay" "false,true"
258   (symbol_ref "eligible_for_sibcall_delay (insn)"))
260 (define_attr "eligible_for_return_delay" "false,true"
261   (symbol_ref "eligible_for_return_delay (insn)"))
263 ;; ??? !v9: Should implement the notion of predelay slots for floating-point
264 ;; branches.  This would allow us to remove the nop always inserted before
265 ;; a floating point branch.
267 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
268 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
269 ;; This is because doing so will add several pipeline stalls to the path
270 ;; that the load/store did not come from.  Unfortunately, there is no way
271 ;; to prevent fill_eager_delay_slots from using load/store without completely
272 ;; disabling them.  For the SPEC benchmark set, this is a serious lose,
273 ;; because it prevents us from moving back the final store of inner loops.
275 (define_attr "in_branch_delay" "false,true"
276   (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
277                      (eq_attr "length" "1"))
278                 (const_string "true")
279                 (const_string "false")))
281 (define_attr "in_uncond_branch_delay" "false,true"
282   (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
283                      (eq_attr "length" "1"))
284                 (const_string "true")
285                 (const_string "false")))
287 (define_attr "in_annul_branch_delay" "false,true"
288   (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
289                      (eq_attr "length" "1"))
290                 (const_string "true")
291                 (const_string "false")))
293 (define_delay (eq_attr "type" "call")
294   [(eq_attr "in_call_delay" "true") (nil) (nil)])
296 (define_delay (eq_attr "type" "sibcall")
297   [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
299 (define_delay (eq_attr "type" "branch")
300   [(eq_attr "in_branch_delay" "true")
301    (nil) (eq_attr "in_annul_branch_delay" "true")])
303 (define_delay (eq_attr "type" "uncond_branch")
304   [(eq_attr "in_uncond_branch_delay" "true")
305    (nil) (nil)])
307 (define_delay (eq_attr "type" "return")
308   [(eq_attr "eligible_for_return_delay" "true") (nil) (nil)])
311 ;; Include SPARC DFA schedulers
313 (include "cypress.md")
314 (include "supersparc.md")
315 (include "hypersparc.md")
316 (include "sparclet.md")
317 (include "ultra1_2.md")
318 (include "ultra3.md")
319 (include "niagara.md")
322 ;; Operand and operator predicates.
324 (include "predicates.md")
327 ;; Compare instructions.
329 ;; We generate RTL for comparisons and branches by having the cmpxx 
330 ;; patterns store away the operands.  Then, the scc and bcc patterns
331 ;; emit RTL for both the compare and the branch.
333 ;; We do this because we want to generate different code for an sne and
334 ;; seq insn.  In those cases, if the second operand of the compare is not
335 ;; const0_rtx, we want to compute the xor of the two operands and test
336 ;; it against zero.
338 ;; We start with the DEFINE_EXPANDs, then the DEFINE_INSNs to match
339 ;; the patterns.  Finally, we have the DEFINE_SPLITs for some of the scc
340 ;; insns that actually require more than one machine instruction.
342 (define_expand "cmpsi"
343   [(set (reg:CC 100)
344         (compare:CC (match_operand:SI 0 "compare_operand" "")
345                     (match_operand:SI 1 "arith_operand" "")))]
346   ""
348   if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx)
349     operands[0] = force_reg (SImode, operands[0]);
351   sparc_compare_op0 = operands[0];
352   sparc_compare_op1 = operands[1];
353   DONE;
356 (define_expand "cmpdi"
357   [(set (reg:CCX 100)
358         (compare:CCX (match_operand:DI 0 "compare_operand" "")
359                      (match_operand:DI 1 "arith_operand" "")))]
360   "TARGET_ARCH64"
362   if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx)
363     operands[0] = force_reg (DImode, operands[0]);
365   sparc_compare_op0 = operands[0];
366   sparc_compare_op1 = operands[1];
367   DONE;
370 (define_expand "cmpsf"
371   ;; The 96 here isn't ever used by anyone.
372   [(set (reg:CCFP 96)
373         (compare:CCFP (match_operand:SF 0 "register_operand" "")
374                       (match_operand:SF 1 "register_operand" "")))]
375   "TARGET_FPU"
377   sparc_compare_op0 = operands[0];
378   sparc_compare_op1 = operands[1];
379   DONE;
382 (define_expand "cmpdf"
383   ;; The 96 here isn't ever used by anyone.
384   [(set (reg:CCFP 96)
385         (compare:CCFP (match_operand:DF 0 "register_operand" "")
386                       (match_operand:DF 1 "register_operand" "")))]
387   "TARGET_FPU"
389   sparc_compare_op0 = operands[0];
390   sparc_compare_op1 = operands[1];
391   DONE;
394 (define_expand "cmptf"
395   ;; The 96 here isn't ever used by anyone.
396   [(set (reg:CCFP 96)
397         (compare:CCFP (match_operand:TF 0 "register_operand" "")
398                       (match_operand:TF 1 "register_operand" "")))]
399   "TARGET_FPU"
401   sparc_compare_op0 = operands[0];
402   sparc_compare_op1 = operands[1];
403   DONE;
406 ;; Now the compare DEFINE_INSNs.
408 (define_insn "*cmpsi_insn"
409   [(set (reg:CC 100)
410         (compare:CC (match_operand:SI 0 "register_operand" "r")
411                     (match_operand:SI 1 "arith_operand" "rI")))]
412   ""
413   "cmp\t%0, %1"
414   [(set_attr "type" "compare")])
416 (define_insn "*cmpdi_sp64"
417   [(set (reg:CCX 100)
418         (compare:CCX (match_operand:DI 0 "register_operand" "r")
419                      (match_operand:DI 1 "arith_operand" "rI")))]
420   "TARGET_ARCH64"
421   "cmp\t%0, %1"
422   [(set_attr "type" "compare")])
424 (define_insn "*cmpsf_fpe"
425   [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
426         (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
427                        (match_operand:SF 2 "register_operand" "f")))]
428   "TARGET_FPU"
430   if (TARGET_V9)
431     return "fcmpes\t%0, %1, %2";
432   return "fcmpes\t%1, %2";
434   [(set_attr "type" "fpcmp")])
436 (define_insn "*cmpdf_fpe"
437   [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
438         (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
439                        (match_operand:DF 2 "register_operand" "e")))]
440   "TARGET_FPU"
442   if (TARGET_V9)
443     return "fcmped\t%0, %1, %2";
444   return "fcmped\t%1, %2";
446   [(set_attr "type" "fpcmp")
447    (set_attr "fptype" "double")])
449 (define_insn "*cmptf_fpe"
450   [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
451         (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
452                        (match_operand:TF 2 "register_operand" "e")))]
453   "TARGET_FPU && TARGET_HARD_QUAD"
455   if (TARGET_V9)
456     return "fcmpeq\t%0, %1, %2";
457   return "fcmpeq\t%1, %2";
459   [(set_attr "type" "fpcmp")])
461 (define_insn "*cmpsf_fp"
462   [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
463         (compare:CCFP (match_operand:SF 1 "register_operand" "f")
464                       (match_operand:SF 2 "register_operand" "f")))]
465   "TARGET_FPU"
467   if (TARGET_V9)
468     return "fcmps\t%0, %1, %2";
469   return "fcmps\t%1, %2";
471   [(set_attr "type" "fpcmp")])
473 (define_insn "*cmpdf_fp"
474   [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
475         (compare:CCFP (match_operand:DF 1 "register_operand" "e")
476                       (match_operand:DF 2 "register_operand" "e")))]
477   "TARGET_FPU"
479   if (TARGET_V9)
480     return "fcmpd\t%0, %1, %2";
481   return "fcmpd\t%1, %2";
483   [(set_attr "type" "fpcmp")
484    (set_attr "fptype" "double")])
486 (define_insn "*cmptf_fp"
487   [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
488         (compare:CCFP (match_operand:TF 1 "register_operand" "e")
489                       (match_operand:TF 2 "register_operand" "e")))]
490   "TARGET_FPU && TARGET_HARD_QUAD"
492   if (TARGET_V9)
493     return "fcmpq\t%0, %1, %2";
494   return "fcmpq\t%1, %2";
496   [(set_attr "type" "fpcmp")])
498 ;; Next come the scc insns.  For seq, sne, sgeu, and sltu, we can do this
499 ;; without jumps using the addx/subx instructions.  For seq/sne on v9 we use
500 ;; the same code as v8 (the addx/subx method has more applications).  The
501 ;; exception to this is "reg != 0" which can be done in one instruction on v9
502 ;; (so we do it).  For the rest, on v9 we use conditional moves; on v8, we do
503 ;; branches.
505 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
506 ;; generate addcc/subcc instructions.
508 (define_expand "seqsi_special"
509   [(set (match_dup 3)
510         (xor:SI (match_operand:SI 1 "register_operand" "")
511                 (match_operand:SI 2 "register_operand" "")))
512    (parallel [(set (match_operand:SI 0 "register_operand" "")
513                    (eq:SI (match_dup 3) (const_int 0)))
514               (clobber (reg:CC 100))])]
515   ""
516   { operands[3] = gen_reg_rtx (SImode); })
518 (define_expand "seqdi_special"
519   [(set (match_dup 3)
520         (xor:DI (match_operand:DI 1 "register_operand" "")
521                 (match_operand:DI 2 "register_operand" "")))
522    (set (match_operand:DI 0 "register_operand" "")
523         (eq:DI (match_dup 3) (const_int 0)))]
524   "TARGET_ARCH64"
525   { operands[3] = gen_reg_rtx (DImode); })
527 (define_expand "snesi_special"
528   [(set (match_dup 3)
529         (xor:SI (match_operand:SI 1 "register_operand" "")
530                 (match_operand:SI 2 "register_operand" "")))
531    (parallel [(set (match_operand:SI 0 "register_operand" "")
532                    (ne:SI (match_dup 3) (const_int 0)))
533               (clobber (reg:CC 100))])]
534   ""
535   { operands[3] = gen_reg_rtx (SImode); })
537 (define_expand "snedi_special"
538   [(set (match_dup 3)
539         (xor:DI (match_operand:DI 1 "register_operand" "")
540                 (match_operand:DI 2 "register_operand" "")))
541    (set (match_operand:DI 0 "register_operand" "")
542         (ne:DI (match_dup 3) (const_int 0)))]
543   "TARGET_ARCH64"
544   { operands[3] = gen_reg_rtx (DImode); })
546 (define_expand "seqdi_special_trunc"
547   [(set (match_dup 3)
548         (xor:DI (match_operand:DI 1 "register_operand" "")
549                 (match_operand:DI 2 "register_operand" "")))
550    (set (match_operand:SI 0 "register_operand" "")
551         (eq:SI (match_dup 3) (const_int 0)))]
552   "TARGET_ARCH64"
553   { operands[3] = gen_reg_rtx (DImode); })
555 (define_expand "snedi_special_trunc"
556   [(set (match_dup 3)
557         (xor:DI (match_operand:DI 1 "register_operand" "")
558                 (match_operand:DI 2 "register_operand" "")))
559    (set (match_operand:SI 0 "register_operand" "")
560         (ne:SI (match_dup 3) (const_int 0)))]
561   "TARGET_ARCH64"
562   { operands[3] = gen_reg_rtx (DImode); })
564 (define_expand "seqsi_special_extend"
565   [(set (match_dup 3)
566         (xor:SI (match_operand:SI 1 "register_operand" "")
567                 (match_operand:SI 2 "register_operand" "")))
568    (parallel [(set (match_operand:DI 0 "register_operand" "")
569                    (eq:DI (match_dup 3) (const_int 0)))
570               (clobber (reg:CC 100))])]
571   "TARGET_ARCH64"
572   { operands[3] = gen_reg_rtx (SImode); })
574 (define_expand "snesi_special_extend"
575   [(set (match_dup 3)
576         (xor:SI (match_operand:SI 1 "register_operand" "")
577                 (match_operand:SI 2 "register_operand" "")))
578    (parallel [(set (match_operand:DI 0 "register_operand" "")
579                    (ne:DI (match_dup 3) (const_int 0)))
580               (clobber (reg:CC 100))])]
581   "TARGET_ARCH64"
582   { operands[3] = gen_reg_rtx (SImode); })
584 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
585 ;; However, the code handles both SImode and DImode.
586 (define_expand "seq"
587   [(set (match_operand:SI 0 "int_register_operand" "")
588         (eq:SI (match_dup 1) (const_int 0)))]
589   ""
591   if (GET_MODE (sparc_compare_op0) == SImode)
592     {
593       rtx pat;
595       if (GET_MODE (operands[0]) == SImode)
596         pat = gen_seqsi_special (operands[0], sparc_compare_op0,
597                                  sparc_compare_op1);
598       else if (! TARGET_ARCH64)
599         FAIL;
600       else
601         pat = gen_seqsi_special_extend (operands[0], sparc_compare_op0,
602                                         sparc_compare_op1);
603       emit_insn (pat);
604       DONE;
605     }
606   else if (GET_MODE (sparc_compare_op0) == DImode)
607     {
608       rtx pat;
610       if (! TARGET_ARCH64)
611         FAIL;
612       else if (GET_MODE (operands[0]) == SImode)
613         pat = gen_seqdi_special_trunc (operands[0], sparc_compare_op0,
614                                        sparc_compare_op1);
615       else
616         pat = gen_seqdi_special (operands[0], sparc_compare_op0,
617                                  sparc_compare_op1);
618       emit_insn (pat);
619       DONE;
620     }
621   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
622     {
623       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
624       emit_jump_insn (gen_sne (operands[0]));
625       DONE;
626     }
627   else if (TARGET_V9)
628     {
629       if (gen_v9_scc (EQ, operands))
630         DONE;
631       /* fall through */
632     }
633   FAIL;
636 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
637 ;; However, the code handles both SImode and DImode.
638 (define_expand "sne"
639   [(set (match_operand:SI 0 "int_register_operand" "")
640         (ne:SI (match_dup 1) (const_int 0)))]
641   ""
643   if (GET_MODE (sparc_compare_op0) == SImode)
644     {
645       rtx pat;
647       if (GET_MODE (operands[0]) == SImode)
648         pat = gen_snesi_special (operands[0], sparc_compare_op0,
649                                  sparc_compare_op1);
650       else if (! TARGET_ARCH64)
651         FAIL;
652       else
653         pat = gen_snesi_special_extend (operands[0], sparc_compare_op0,
654                                         sparc_compare_op1);
655       emit_insn (pat);
656       DONE;
657     }
658   else if (GET_MODE (sparc_compare_op0) == DImode)
659     {
660       rtx pat;
662       if (! TARGET_ARCH64)
663         FAIL;
664       else if (GET_MODE (operands[0]) == SImode)
665         pat = gen_snedi_special_trunc (operands[0], sparc_compare_op0,
666                                        sparc_compare_op1);
667       else
668         pat = gen_snedi_special (operands[0], sparc_compare_op0,
669                                  sparc_compare_op1);
670       emit_insn (pat);
671       DONE;
672     }
673   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
674     {
675       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
676       emit_jump_insn (gen_sne (operands[0]));
677       DONE;
678     }
679   else if (TARGET_V9)
680     {
681       if (gen_v9_scc (NE, operands))
682         DONE;
683       /* fall through */
684     }
685   FAIL;
688 (define_expand "sgt"
689   [(set (match_operand:SI 0 "int_register_operand" "")
690         (gt:SI (match_dup 1) (const_int 0)))]
691   ""
693   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
694     {
695       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
696       emit_jump_insn (gen_sne (operands[0]));
697       DONE;
698     }
699   else if (TARGET_V9)
700     {
701       if (gen_v9_scc (GT, operands))
702         DONE;
703       /* fall through */
704     }
705   FAIL;
708 (define_expand "slt"
709   [(set (match_operand:SI 0 "int_register_operand" "")
710         (lt:SI (match_dup 1) (const_int 0)))]
711   ""
713   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
714     {
715       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
716       emit_jump_insn (gen_sne (operands[0]));
717       DONE;
718     }
719   else if (TARGET_V9)
720     {
721       if (gen_v9_scc (LT, operands))
722         DONE;
723       /* fall through */
724     }
725   FAIL;
728 (define_expand "sge"
729   [(set (match_operand:SI 0 "int_register_operand" "")
730         (ge:SI (match_dup 1) (const_int 0)))]
731   ""
733   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
734     {
735       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
736       emit_jump_insn (gen_sne (operands[0]));
737       DONE;
738     }
739   else if (TARGET_V9)
740     {
741       if (gen_v9_scc (GE, operands))
742         DONE;
743       /* fall through */
744     }
745   FAIL;
748 (define_expand "sle"
749   [(set (match_operand:SI 0 "int_register_operand" "")
750         (le:SI (match_dup 1) (const_int 0)))]
751   ""
753   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
754     {
755       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
756       emit_jump_insn (gen_sne (operands[0]));
757       DONE;
758     }
759   else if (TARGET_V9)
760     {
761       if (gen_v9_scc (LE, operands))
762         DONE;
763       /* fall through */
764     }
765   FAIL;
768 (define_expand "sgtu"
769   [(set (match_operand:SI 0 "int_register_operand" "")
770         (gtu:SI (match_dup 1) (const_int 0)))]
771   ""
773   if (! TARGET_V9)
774     {
775       rtx tem, pat;
777       /* We can do ltu easily, so if both operands are registers, swap them and
778          do a LTU.  */
779       if ((GET_CODE (sparc_compare_op0) == REG
780            || GET_CODE (sparc_compare_op0) == SUBREG)
781           && (GET_CODE (sparc_compare_op1) == REG
782               || GET_CODE (sparc_compare_op1) == SUBREG))
783         {
784           tem = sparc_compare_op0;
785           sparc_compare_op0 = sparc_compare_op1;
786           sparc_compare_op1 = tem;
787           pat = gen_sltu (operands[0]);
788           if (pat == NULL_RTX)
789             FAIL;
790           emit_insn (pat);
791           DONE;
792         }
793     }
794   else
795     {
796       if (gen_v9_scc (GTU, operands))
797         DONE;
798     }
799   FAIL;
802 (define_expand "sltu"
803   [(set (match_operand:SI 0 "int_register_operand" "")
804         (ltu:SI (match_dup 1) (const_int 0)))]
805   ""
807   if (TARGET_V9)
808     {
809       if (gen_v9_scc (LTU, operands))
810         DONE;
811     }
812   operands[1] = gen_compare_reg (LTU);
815 (define_expand "sgeu"
816   [(set (match_operand:SI 0 "int_register_operand" "")
817         (geu:SI (match_dup 1) (const_int 0)))]
818   ""
820   if (TARGET_V9)
821     {
822       if (gen_v9_scc (GEU, operands))
823         DONE;
824     }
825   operands[1] = gen_compare_reg (GEU);
828 (define_expand "sleu"
829   [(set (match_operand:SI 0 "int_register_operand" "")
830         (leu:SI (match_dup 1) (const_int 0)))]
831   ""
833   if (! TARGET_V9)
834     {
835       rtx tem, pat;
837       /* We can do geu easily, so if both operands are registers, swap them and
838          do a GEU.  */
839       if ((GET_CODE (sparc_compare_op0) == REG
840            || GET_CODE (sparc_compare_op0) == SUBREG)
841           && (GET_CODE (sparc_compare_op1) == REG
842               || GET_CODE (sparc_compare_op1) == SUBREG))
843         {
844           tem = sparc_compare_op0;
845           sparc_compare_op0 = sparc_compare_op1;
846           sparc_compare_op1 = tem;
847           pat = gen_sgeu (operands[0]);
848           if (pat == NULL_RTX)
849             FAIL;
850           emit_insn (pat);
851           DONE;
852         }
853     }
854   else
855     {
856       if (gen_v9_scc (LEU, operands))
857         DONE;
858     }
859   FAIL;
862 ;; Now the DEFINE_INSNs for the scc cases.
864 ;; The SEQ and SNE patterns are special because they can be done
865 ;; without any branching and do not involve a COMPARE.  We want
866 ;; them to always use the splits below so the results can be
867 ;; scheduled.
869 (define_insn_and_split "*snesi_zero"
870   [(set (match_operand:SI 0 "register_operand" "=r")
871         (ne:SI (match_operand:SI 1 "register_operand" "r")
872                (const_int 0)))
873    (clobber (reg:CC 100))]
874   ""
875   "#"
876   ""
877   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
878                                            (const_int 0)))
879    (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))]
880   ""
881   [(set_attr "length" "2")])
883 (define_insn_and_split "*neg_snesi_zero"
884   [(set (match_operand:SI 0 "register_operand" "=r")
885         (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
886                        (const_int 0))))
887    (clobber (reg:CC 100))]
888   ""
889   "#"
890   ""
891   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
892                                            (const_int 0)))
893    (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
894   ""
895   [(set_attr "length" "2")])
897 (define_insn_and_split "*snesi_zero_extend"
898   [(set (match_operand:DI 0 "register_operand" "=r")
899         (ne:DI (match_operand:SI 1 "register_operand" "r")
900                (const_int 0)))
901    (clobber (reg:CC 100))]
902   "TARGET_ARCH64"
903   "#"
904   "&& 1"
905   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
906                                                      (match_dup 1))
907                                            (const_int 0)))
908    (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
909                                                         (const_int 0))
910                                                (ltu:SI (reg:CC_NOOV 100)
911                                                        (const_int 0)))))]
912   ""
913   [(set_attr "length" "2")])
915 (define_insn_and_split "*snedi_zero"
916   [(set (match_operand:DI 0 "register_operand" "=&r")
917         (ne:DI (match_operand:DI 1 "register_operand" "r")
918                (const_int 0)))]
919   "TARGET_ARCH64"
920   "#"
921   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
922   [(set (match_dup 0) (const_int 0))
923    (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
924                                               (const_int 0))
925                                        (const_int 1)
926                                        (match_dup 0)))]
927   ""
928   [(set_attr "length" "2")])
930 (define_insn_and_split "*neg_snedi_zero"
931   [(set (match_operand:DI 0 "register_operand" "=&r")
932         (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
933                        (const_int 0))))]
934   "TARGET_ARCH64"
935   "#"
936   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
937   [(set (match_dup 0) (const_int 0))
938    (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
939                                               (const_int 0))
940                                        (const_int -1)
941                                        (match_dup 0)))]
942   ""
943   [(set_attr "length" "2")])
945 (define_insn_and_split "*snedi_zero_trunc"
946   [(set (match_operand:SI 0 "register_operand" "=&r")
947         (ne:SI (match_operand:DI 1 "register_operand" "r")
948                (const_int 0)))]
949   "TARGET_ARCH64"
950   "#"
951   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
952   [(set (match_dup 0) (const_int 0))
953    (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
954                                               (const_int 0))
955                                        (const_int 1)
956                                        (match_dup 0)))]
957   ""
958   [(set_attr "length" "2")])
960 (define_insn_and_split "*seqsi_zero"
961   [(set (match_operand:SI 0 "register_operand" "=r")
962         (eq:SI (match_operand:SI 1 "register_operand" "r")
963                (const_int 0)))
964    (clobber (reg:CC 100))]
965   ""
966   "#"
967   ""
968   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
969                                            (const_int 0)))
970    (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))]
971   ""
972   [(set_attr "length" "2")])
974 (define_insn_and_split "*neg_seqsi_zero"
975   [(set (match_operand:SI 0 "register_operand" "=r")
976         (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
977                        (const_int 0))))
978    (clobber (reg:CC 100))]
979   ""
980   "#"
981   ""
982   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
983                                            (const_int 0)))
984    (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
985   ""
986   [(set_attr "length" "2")])
988 (define_insn_and_split "*seqsi_zero_extend"
989   [(set (match_operand:DI 0 "register_operand" "=r")
990         (eq:DI (match_operand:SI 1 "register_operand" "r")
991                (const_int 0)))
992    (clobber (reg:CC 100))]
993   "TARGET_ARCH64"
994   "#"
995   "&& 1"
996   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
997                                                      (match_dup 1))
998                                            (const_int 0)))
999    (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
1000                                                           (const_int -1))
1001                                                 (ltu:SI (reg:CC_NOOV 100)
1002                                                         (const_int 0)))))]
1003   ""
1004   [(set_attr "length" "2")])
1006 (define_insn_and_split "*seqdi_zero"
1007   [(set (match_operand:DI 0 "register_operand" "=&r")
1008         (eq:DI (match_operand:DI 1 "register_operand" "r")
1009                (const_int 0)))]
1010   "TARGET_ARCH64"
1011   "#"
1012   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1013   [(set (match_dup 0) (const_int 0))
1014    (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1015                                               (const_int 0))
1016                                        (const_int 1)
1017                                        (match_dup 0)))]
1018   ""
1019   [(set_attr "length" "2")])
1021 (define_insn_and_split "*neg_seqdi_zero"
1022   [(set (match_operand:DI 0 "register_operand" "=&r")
1023         (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
1024                        (const_int 0))))]
1025   "TARGET_ARCH64"
1026   "#"
1027   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1028   [(set (match_dup 0) (const_int 0))
1029    (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1030                                               (const_int 0))
1031                                        (const_int -1)
1032                                        (match_dup 0)))]
1033   ""
1034   [(set_attr "length" "2")]) 
1036 (define_insn_and_split "*seqdi_zero_trunc"
1037   [(set (match_operand:SI 0 "register_operand" "=&r")
1038         (eq:SI (match_operand:DI 1 "register_operand" "r")
1039                (const_int 0)))]
1040   "TARGET_ARCH64"
1041   "#"
1042   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1043   [(set (match_dup 0) (const_int 0))
1044    (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
1045                                               (const_int 0))
1046                                        (const_int 1)
1047                                        (match_dup 0)))]
1048   ""
1049   [(set_attr "length" "2")])
1051 ;; We can also do (x + (i == 0)) and related, so put them in.
1052 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1053 ;; versions for v9.
1055 (define_insn_and_split "*x_plus_i_ne_0"
1056   [(set (match_operand:SI 0 "register_operand" "=r")
1057         (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
1058                         (const_int 0))
1059                  (match_operand:SI 2 "register_operand" "r")))
1060    (clobber (reg:CC 100))]
1061   ""
1062   "#"
1063   ""
1064   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1065                                            (const_int 0)))
1066    (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1067                                (match_dup 2)))]
1068   ""
1069   [(set_attr "length" "2")])
1071 (define_insn_and_split "*x_minus_i_ne_0"
1072   [(set (match_operand:SI 0 "register_operand" "=r")
1073         (minus:SI (match_operand:SI 2 "register_operand" "r")
1074                   (ne:SI (match_operand:SI 1 "register_operand" "r")
1075                          (const_int 0))))
1076    (clobber (reg:CC 100))]
1077   ""
1078   "#"
1079   ""
1080   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1081                                            (const_int 0)))
1082    (set (match_dup 0) (minus:SI (match_dup 2)
1083                                 (ltu:SI (reg:CC 100) (const_int 0))))]
1084   ""
1085   [(set_attr "length" "2")])
1087 (define_insn_and_split "*x_plus_i_eq_0"
1088   [(set (match_operand:SI 0 "register_operand" "=r")
1089         (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1090                         (const_int 0))
1091                  (match_operand:SI 2 "register_operand" "r")))
1092    (clobber (reg:CC 100))]
1093   ""
1094   "#"
1095   ""
1096   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1097                                            (const_int 0)))
1098    (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1099                                (match_dup 2)))]
1100   ""
1101   [(set_attr "length" "2")])
1103 (define_insn_and_split "*x_minus_i_eq_0"
1104   [(set (match_operand:SI 0 "register_operand" "=r")
1105         (minus:SI (match_operand:SI 2 "register_operand" "r")
1106                   (eq:SI (match_operand:SI 1 "register_operand" "r")
1107                          (const_int 0))))
1108    (clobber (reg:CC 100))]
1109   ""
1110   "#"
1111   ""
1112   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1113                                            (const_int 0)))
1114    (set (match_dup 0) (minus:SI (match_dup 2)
1115                                 (geu:SI (reg:CC 100) (const_int 0))))]
1116   ""
1117   [(set_attr "length" "2")])
1119 ;; We can also do GEU and LTU directly, but these operate after a compare.
1120 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1121 ;; versions for v9.
1123 (define_insn "*sltu_insn"
1124   [(set (match_operand:SI 0 "register_operand" "=r")
1125         (ltu:SI (reg:CC 100) (const_int 0)))]
1126   ""
1127   "addx\t%%g0, 0, %0"
1128   [(set_attr "type" "ialuX")])
1130 (define_insn "*neg_sltu_insn"
1131   [(set (match_operand:SI 0 "register_operand" "=r")
1132         (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1133   ""
1134   "subx\t%%g0, 0, %0"
1135   [(set_attr "type" "ialuX")])
1137 ;; ??? Combine should canonicalize these next two to the same pattern.
1138 (define_insn "*neg_sltu_minus_x"
1139   [(set (match_operand:SI 0 "register_operand" "=r")
1140         (minus:SI (neg:SI (ltu:SI (reg:CC 100) (const_int 0)))
1141                   (match_operand:SI 1 "arith_operand" "rI")))]
1142   ""
1143   "subx\t%%g0, %1, %0"
1144   [(set_attr "type" "ialuX")])
1146 (define_insn "*neg_sltu_plus_x"
1147   [(set (match_operand:SI 0 "register_operand" "=r")
1148         (neg:SI (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1149                          (match_operand:SI 1 "arith_operand" "rI"))))]
1150   ""
1151   "subx\t%%g0, %1, %0"
1152   [(set_attr "type" "ialuX")])
1154 (define_insn "*sgeu_insn"
1155   [(set (match_operand:SI 0 "register_operand" "=r")
1156         (geu:SI (reg:CC 100) (const_int 0)))]
1157   ""
1158   "subx\t%%g0, -1, %0"
1159   [(set_attr "type" "ialuX")])
1161 (define_insn "*neg_sgeu_insn"
1162   [(set (match_operand:SI 0 "register_operand" "=r")
1163         (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1164   ""
1165   "addx\t%%g0, -1, %0"
1166   [(set_attr "type" "ialuX")])
1168 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
1169 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1170 ;; versions for v9.
1172 (define_insn "*sltu_plus_x"
1173   [(set (match_operand:SI 0 "register_operand" "=r")
1174         (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1175                  (match_operand:SI 1 "arith_operand" "rI")))]
1176   ""
1177   "addx\t%%g0, %1, %0"
1178   [(set_attr "type" "ialuX")])
1180 (define_insn "*sltu_plus_x_plus_y"
1181   [(set (match_operand:SI 0 "register_operand" "=r")
1182         (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1183                  (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1184                           (match_operand:SI 2 "arith_operand" "rI"))))]
1185   ""
1186   "addx\t%1, %2, %0"
1187   [(set_attr "type" "ialuX")])
1189 (define_insn "*x_minus_sltu"
1190   [(set (match_operand:SI 0 "register_operand" "=r")
1191         (minus:SI (match_operand:SI 1 "register_operand" "r")
1192                   (ltu:SI (reg:CC 100) (const_int 0))))]
1193   ""
1194   "subx\t%1, 0, %0"
1195   [(set_attr "type" "ialuX")])
1197 ;; ??? Combine should canonicalize these next two to the same pattern.
1198 (define_insn "*x_minus_y_minus_sltu"
1199   [(set (match_operand:SI 0 "register_operand" "=r")
1200         (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
1201                             (match_operand:SI 2 "arith_operand" "rI"))
1202                   (ltu:SI (reg:CC 100) (const_int 0))))]
1203   ""
1204   "subx\t%r1, %2, %0"
1205   [(set_attr "type" "ialuX")])
1207 (define_insn "*x_minus_sltu_plus_y"
1208   [(set (match_operand:SI 0 "register_operand" "=r")
1209         (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
1210                   (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1211                            (match_operand:SI 2 "arith_operand" "rI"))))]
1212   ""
1213   "subx\t%r1, %2, %0"
1214   [(set_attr "type" "ialuX")])
1216 (define_insn "*sgeu_plus_x"
1217   [(set (match_operand:SI 0 "register_operand" "=r")
1218         (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1219                  (match_operand:SI 1 "register_operand" "r")))]
1220   ""
1221   "subx\t%1, -1, %0"
1222   [(set_attr "type" "ialuX")])
1224 (define_insn "*x_minus_sgeu"
1225   [(set (match_operand:SI 0 "register_operand" "=r")
1226         (minus:SI (match_operand:SI 1 "register_operand" "r")
1227                   (geu:SI (reg:CC 100) (const_int 0))))]
1228   ""
1229   "addx\t%1, -1, %0"
1230   [(set_attr "type" "ialuX")])
1232 (define_split
1233   [(set (match_operand:SI 0 "register_operand" "")
1234         (match_operator:SI 2 "noov_compare_operator"
1235                            [(match_operand 1 "icc_or_fcc_register_operand" "")
1236                             (const_int 0)]))]
1237   "TARGET_V9
1238    && REGNO (operands[1]) == SPARC_ICC_REG
1239    && (GET_MODE (operands[1]) == CCXmode
1240        /* 32 bit LTU/GEU are better implemented using addx/subx.  */
1241        || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1242   [(set (match_dup 0) (const_int 0))
1243    (set (match_dup 0)
1244         (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1245                          (const_int 1)
1246                          (match_dup 0)))]
1247   "")
1250 ;; These control RTL generation for conditional jump insns
1252 ;; The quad-word fp compare library routines all return nonzero to indicate
1253 ;; true, which is different from the equivalent libgcc routines, so we must
1254 ;; handle them specially here.
1256 (define_expand "beq"
1257   [(set (pc)
1258         (if_then_else (eq (match_dup 1) (const_int 0))
1259                       (label_ref (match_operand 0 "" ""))
1260                       (pc)))]
1261   ""
1263   if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1264       && GET_CODE (sparc_compare_op0) == REG
1265       && GET_MODE (sparc_compare_op0) == DImode)
1266     {
1267       emit_v9_brxx_insn (EQ, sparc_compare_op0, operands[0]);
1268       DONE;
1269     }
1270   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1271     {
1272       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
1273       emit_jump_insn (gen_bne (operands[0]));
1274       DONE;
1275     }
1276   operands[1] = gen_compare_reg (EQ);
1279 (define_expand "bne"
1280   [(set (pc)
1281         (if_then_else (ne (match_dup 1) (const_int 0))
1282                       (label_ref (match_operand 0 "" ""))
1283                       (pc)))]
1284   ""
1286   if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1287       && GET_CODE (sparc_compare_op0) == REG
1288       && GET_MODE (sparc_compare_op0) == DImode)
1289     {
1290       emit_v9_brxx_insn (NE, sparc_compare_op0, operands[0]);
1291       DONE;
1292     }
1293   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1294     {
1295       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
1296       emit_jump_insn (gen_bne (operands[0]));
1297       DONE;
1298     }
1299   operands[1] = gen_compare_reg (NE);
1302 (define_expand "bgt"
1303   [(set (pc)
1304         (if_then_else (gt (match_dup 1) (const_int 0))
1305                       (label_ref (match_operand 0 "" ""))
1306                       (pc)))]
1307   ""
1309   if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1310       && GET_CODE (sparc_compare_op0) == REG
1311       && GET_MODE (sparc_compare_op0) == DImode)
1312     {
1313       emit_v9_brxx_insn (GT, sparc_compare_op0, operands[0]);
1314       DONE;
1315     }
1316   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1317     {
1318       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
1319       emit_jump_insn (gen_bne (operands[0]));
1320       DONE;
1321     }
1322   operands[1] = gen_compare_reg (GT);
1325 (define_expand "bgtu"
1326   [(set (pc)
1327         (if_then_else (gtu (match_dup 1) (const_int 0))
1328                       (label_ref (match_operand 0 "" ""))
1329                       (pc)))]
1330   ""
1332   operands[1] = gen_compare_reg (GTU);
1335 (define_expand "blt"
1336   [(set (pc)
1337         (if_then_else (lt (match_dup 1) (const_int 0))
1338                       (label_ref (match_operand 0 "" ""))
1339                       (pc)))]
1340   ""
1342   if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1343       && GET_CODE (sparc_compare_op0) == REG
1344       && GET_MODE (sparc_compare_op0) == DImode)
1345     {
1346       emit_v9_brxx_insn (LT, sparc_compare_op0, operands[0]);
1347       DONE;
1348     }
1349   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1350     {
1351       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
1352       emit_jump_insn (gen_bne (operands[0]));
1353       DONE;
1354     }
1355   operands[1] = gen_compare_reg (LT);
1358 (define_expand "bltu"
1359   [(set (pc)
1360         (if_then_else (ltu (match_dup 1) (const_int 0))
1361                       (label_ref (match_operand 0 "" ""))
1362                       (pc)))]
1363   ""
1365   operands[1] = gen_compare_reg (LTU);
1368 (define_expand "bge"
1369   [(set (pc)
1370         (if_then_else (ge (match_dup 1) (const_int 0))
1371                       (label_ref (match_operand 0 "" ""))
1372                       (pc)))]
1373   ""
1375   if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1376       && GET_CODE (sparc_compare_op0) == REG
1377       && GET_MODE (sparc_compare_op0) == DImode)
1378     {
1379       emit_v9_brxx_insn (GE, sparc_compare_op0, operands[0]);
1380       DONE;
1381     }
1382   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1383     {
1384       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
1385       emit_jump_insn (gen_bne (operands[0]));
1386       DONE;
1387     }
1388   operands[1] = gen_compare_reg (GE);
1391 (define_expand "bgeu"
1392   [(set (pc)
1393         (if_then_else (geu (match_dup 1) (const_int 0))
1394                       (label_ref (match_operand 0 "" ""))
1395                       (pc)))]
1396   ""
1398   operands[1] = gen_compare_reg (GEU);
1401 (define_expand "ble"
1402   [(set (pc)
1403         (if_then_else (le (match_dup 1) (const_int 0))
1404                       (label_ref (match_operand 0 "" ""))
1405                       (pc)))]
1406   ""
1408   if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1409       && GET_CODE (sparc_compare_op0) == REG
1410       && GET_MODE (sparc_compare_op0) == DImode)
1411     {
1412       emit_v9_brxx_insn (LE, sparc_compare_op0, operands[0]);
1413       DONE;
1414     }
1415   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1416     {
1417       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
1418       emit_jump_insn (gen_bne (operands[0]));
1419       DONE;
1420     }
1421   operands[1] = gen_compare_reg (LE);
1424 (define_expand "bleu"
1425   [(set (pc)
1426         (if_then_else (leu (match_dup 1) (const_int 0))
1427                       (label_ref (match_operand 0 "" ""))
1428                       (pc)))]
1429   ""
1431   operands[1] = gen_compare_reg (LEU);
1434 (define_expand "bunordered"
1435   [(set (pc)
1436         (if_then_else (unordered (match_dup 1) (const_int 0))
1437                       (label_ref (match_operand 0 "" ""))
1438                       (pc)))]
1439   ""
1441   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1442     {
1443       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1,
1444                                 UNORDERED);
1445       emit_jump_insn (gen_beq (operands[0]));
1446       DONE;
1447     }
1448   operands[1] = gen_compare_reg (UNORDERED);
1451 (define_expand "bordered"
1452   [(set (pc)
1453         (if_then_else (ordered (match_dup 1) (const_int 0))
1454                       (label_ref (match_operand 0 "" ""))
1455                       (pc)))]
1456   ""
1458   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1459     {
1460       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, ORDERED);
1461       emit_jump_insn (gen_bne (operands[0]));
1462       DONE;
1463     }
1464   operands[1] = gen_compare_reg (ORDERED);
1467 (define_expand "bungt"
1468   [(set (pc)
1469         (if_then_else (ungt (match_dup 1) (const_int 0))
1470                       (label_ref (match_operand 0 "" ""))
1471                       (pc)))]
1472   ""
1474   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1475     {
1476       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGT);
1477       emit_jump_insn (gen_bgt (operands[0]));
1478       DONE;
1479     }
1480   operands[1] = gen_compare_reg (UNGT);
1483 (define_expand "bunlt"
1484   [(set (pc)
1485         (if_then_else (unlt (match_dup 1) (const_int 0))
1486                       (label_ref (match_operand 0 "" ""))
1487                       (pc)))]
1488   ""
1490   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1491     {
1492       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLT);
1493       emit_jump_insn (gen_bne (operands[0]));
1494       DONE;
1495     }
1496   operands[1] = gen_compare_reg (UNLT);
1499 (define_expand "buneq"
1500   [(set (pc)
1501         (if_then_else (uneq (match_dup 1) (const_int 0))
1502                       (label_ref (match_operand 0 "" ""))
1503                       (pc)))]
1504   ""
1506   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1507     {
1508       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNEQ);
1509       emit_jump_insn (gen_beq (operands[0]));
1510       DONE;
1511     }
1512   operands[1] = gen_compare_reg (UNEQ);
1515 (define_expand "bunge"
1516   [(set (pc)
1517         (if_then_else (unge (match_dup 1) (const_int 0))
1518                       (label_ref (match_operand 0 "" ""))
1519                       (pc)))]
1520   ""
1522   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1523     {
1524       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGE);
1525       emit_jump_insn (gen_bne (operands[0]));
1526       DONE;
1527     }
1528   operands[1] = gen_compare_reg (UNGE);
1531 (define_expand "bunle"
1532   [(set (pc)
1533         (if_then_else (unle (match_dup 1) (const_int 0))
1534                       (label_ref (match_operand 0 "" ""))
1535                       (pc)))]
1536   ""
1538   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1539     {
1540       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLE);
1541       emit_jump_insn (gen_bne (operands[0]));
1542       DONE;
1543     }
1544   operands[1] = gen_compare_reg (UNLE);
1547 (define_expand "bltgt"
1548   [(set (pc)
1549         (if_then_else (ltgt (match_dup 1) (const_int 0))
1550                       (label_ref (match_operand 0 "" ""))
1551                       (pc)))]
1552   ""
1554   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1555     {
1556       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LTGT);
1557       emit_jump_insn (gen_bne (operands[0]));
1558       DONE;
1559     }
1560   operands[1] = gen_compare_reg (LTGT);
1563 ;; Now match both normal and inverted jump.
1565 ;; XXX fpcmp nop braindamage
1566 (define_insn "*normal_branch"
1567   [(set (pc)
1568         (if_then_else (match_operator 0 "noov_compare_operator"
1569                                       [(reg 100) (const_int 0)])
1570                       (label_ref (match_operand 1 "" ""))
1571                       (pc)))]
1572   ""
1574   return output_cbranch (operands[0], operands[1], 1, 0,
1575                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1576                          insn);
1578   [(set_attr "type" "branch")
1579    (set_attr "branch_type" "icc")])
1581 ;; XXX fpcmp nop braindamage
1582 (define_insn "*inverted_branch"
1583   [(set (pc)
1584         (if_then_else (match_operator 0 "noov_compare_operator"
1585                                       [(reg 100) (const_int 0)])
1586                       (pc)
1587                       (label_ref (match_operand 1 "" ""))))]
1588   ""
1590   return output_cbranch (operands[0], operands[1], 1, 1,
1591                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1592                          insn);
1594   [(set_attr "type" "branch")
1595    (set_attr "branch_type" "icc")])
1597 ;; XXX fpcmp nop braindamage
1598 (define_insn "*normal_fp_branch"
1599   [(set (pc)
1600         (if_then_else (match_operator 1 "comparison_operator"
1601                                       [(match_operand:CCFP 0 "fcc_register_operand" "c")
1602                                        (const_int 0)])
1603                       (label_ref (match_operand 2 "" ""))
1604                       (pc)))]
1605   ""
1607   return output_cbranch (operands[1], operands[2], 2, 0,
1608                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1609                          insn);
1611   [(set_attr "type" "branch")
1612    (set_attr "branch_type" "fcc")])
1614 ;; XXX fpcmp nop braindamage
1615 (define_insn "*inverted_fp_branch"
1616   [(set (pc)
1617         (if_then_else (match_operator 1 "comparison_operator"
1618                                       [(match_operand:CCFP 0 "fcc_register_operand" "c")
1619                                        (const_int 0)])
1620                       (pc)
1621                       (label_ref (match_operand 2 "" ""))))]
1622   ""
1624   return output_cbranch (operands[1], operands[2], 2, 1,
1625                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1626                          insn);
1628   [(set_attr "type" "branch")
1629    (set_attr "branch_type" "fcc")])
1631 ;; XXX fpcmp nop braindamage
1632 (define_insn "*normal_fpe_branch"
1633   [(set (pc)
1634         (if_then_else (match_operator 1 "comparison_operator"
1635                                       [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1636                                        (const_int 0)])
1637                       (label_ref (match_operand 2 "" ""))
1638                       (pc)))]
1639   ""
1641   return output_cbranch (operands[1], operands[2], 2, 0,
1642                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1643                          insn);
1645   [(set_attr "type" "branch")
1646    (set_attr "branch_type" "fcc")])
1648 ;; XXX fpcmp nop braindamage
1649 (define_insn "*inverted_fpe_branch"
1650   [(set (pc)
1651         (if_then_else (match_operator 1 "comparison_operator"
1652                                       [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1653                                        (const_int 0)])
1654                       (pc)
1655                       (label_ref (match_operand 2 "" ""))))]
1656   ""
1658   return output_cbranch (operands[1], operands[2], 2, 1,
1659                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1660                          insn);
1662   [(set_attr "type" "branch")
1663    (set_attr "branch_type" "fcc")])
1665 ;; SPARC V9-specific jump insns.  None of these are guaranteed to be
1666 ;; in the architecture.
1668 ;; There are no 32 bit brreg insns.
1670 ;; XXX
1671 (define_insn "*normal_int_branch_sp64"
1672   [(set (pc)
1673         (if_then_else (match_operator 0 "v9_register_compare_operator"
1674                                       [(match_operand:DI 1 "register_operand" "r")
1675                                        (const_int 0)])
1676                       (label_ref (match_operand 2 "" ""))
1677                       (pc)))]
1678   "TARGET_ARCH64"
1680   return output_v9branch (operands[0], operands[2], 1, 2, 0,
1681                           final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1682                           insn);
1684   [(set_attr "type" "branch")
1685    (set_attr "branch_type" "reg")])
1687 ;; XXX
1688 (define_insn "*inverted_int_branch_sp64"
1689   [(set (pc)
1690         (if_then_else (match_operator 0 "v9_register_compare_operator"
1691                                       [(match_operand:DI 1 "register_operand" "r")
1692                                        (const_int 0)])
1693                       (pc)
1694                       (label_ref (match_operand 2 "" ""))))]
1695   "TARGET_ARCH64"
1697   return output_v9branch (operands[0], operands[2], 1, 2, 1,
1698                           final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1699                           insn);
1701   [(set_attr "type" "branch")
1702    (set_attr "branch_type" "reg")])
1705 (define_mode_macro P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1707 ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic
1708 ;; value subject to a PC-relative relocation.  Operand 2 is a helper function
1709 ;; that adds the PC value at the call point to operand 0.
1711 (define_insn "load_pcrel_sym<P:mode>"
1712   [(set (match_operand:P 0 "register_operand" "=r")
1713         (unspec:P [(match_operand:P 1 "symbolic_operand" "")
1714                    (match_operand:P 2 "call_address_operand" "")] UNSPEC_LOAD_PCREL_SYM))
1715    (clobber (reg:P 15))]
1716   ""
1718   if (flag_delayed_branch)
1719     return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0";
1720   else
1721     return "sethi\t%%hi(%a1-8), %0\n\tadd\t%0, %%lo(%a1-4), %0\n\tcall\t%a2\n\t nop";
1723   [(set (attr "type") (const_string "multi"))
1724    (set (attr "length")
1725         (if_then_else (eq_attr "delayed_branch" "true")
1726                       (const_int 3)
1727                       (const_int 4)))])
1730 ;; Integer move instructions
1732 (define_expand "movqi"
1733   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1734         (match_operand:QI 1 "general_operand" ""))]
1735   ""
1737   if (sparc_expand_move (QImode, operands))
1738     DONE;
1741 (define_insn "*movqi_insn"
1742   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1743         (match_operand:QI 1 "input_operand"   "rI,m,rJ"))]
1744   "(register_operand (operands[0], QImode)
1745     || register_or_zero_operand (operands[1], QImode))"
1746   "@
1747    mov\t%1, %0
1748    ldub\t%1, %0
1749    stb\t%r1, %0"
1750   [(set_attr "type" "*,load,store")
1751    (set_attr "us3load_type" "*,3cycle,*")])
1753 (define_expand "movhi"
1754   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1755         (match_operand:HI 1 "general_operand" ""))]
1756   ""
1758   if (sparc_expand_move (HImode, operands))
1759     DONE;
1762 (define_insn "*movhi_insn"
1763   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1764         (match_operand:HI 1 "input_operand"   "rI,K,m,rJ"))]
1765   "(register_operand (operands[0], HImode)
1766     || register_or_zero_operand (operands[1], HImode))"
1767   "@
1768    mov\t%1, %0
1769    sethi\t%%hi(%a1), %0
1770    lduh\t%1, %0
1771    sth\t%r1, %0"
1772   [(set_attr "type" "*,*,load,store")
1773    (set_attr "us3load_type" "*,*,3cycle,*")])
1775 ;; We always work with constants here.
1776 (define_insn "*movhi_lo_sum"
1777   [(set (match_operand:HI 0 "register_operand" "=r")
1778         (ior:HI (match_operand:HI 1 "register_operand" "%r")
1779                 (match_operand:HI 2 "small_int_operand" "I")))]
1780   ""
1781   "or\t%1, %2, %0")
1783 (define_expand "movsi"
1784   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1785         (match_operand:SI 1 "general_operand" ""))]
1786   ""
1788   if (sparc_expand_move (SImode, operands))
1789     DONE;
1792 (define_insn "*movsi_insn"
1793   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m,!f,!f,!m,d")
1794         (match_operand:SI 1 "input_operand"   "rI,K,m,rJ,f,m,f,J"))]
1795   "(register_operand (operands[0], SImode)
1796     || register_or_zero_operand (operands[1], SImode))"
1797   "@
1798    mov\t%1, %0
1799    sethi\t%%hi(%a1), %0
1800    ld\t%1, %0
1801    st\t%r1, %0
1802    fmovs\t%1, %0
1803    ld\t%1, %0
1804    st\t%1, %0
1805    fzeros\t%0"
1806   [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga")])
1808 (define_insn "*movsi_lo_sum"
1809   [(set (match_operand:SI 0 "register_operand" "=r")
1810         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1811                    (match_operand:SI 2 "immediate_operand" "in")))]
1812   ""
1813   "or\t%1, %%lo(%a2), %0")
1815 (define_insn "*movsi_high"
1816   [(set (match_operand:SI 0 "register_operand" "=r")
1817         (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1818   ""
1819   "sethi\t%%hi(%a1), %0")
1821 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1822 ;; so that CSE won't optimize the address computation away.
1823 (define_insn "movsi_lo_sum_pic"
1824   [(set (match_operand:SI 0 "register_operand" "=r")
1825         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1826                    (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1827   "flag_pic"
1828   "or\t%1, %%lo(%a2), %0")
1830 (define_insn "movsi_high_pic"
1831   [(set (match_operand:SI 0 "register_operand" "=r")
1832         (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1833   "flag_pic && check_pic (1)"
1834   "sethi\t%%hi(%a1), %0")
1836 (define_expand "movsi_pic_label_ref"
1837   [(set (match_dup 3) (high:SI
1838      (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1839                  (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1840    (set (match_dup 4) (lo_sum:SI (match_dup 3)
1841      (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1842    (set (match_operand:SI 0 "register_operand" "=r")
1843         (minus:SI (match_dup 5) (match_dup 4)))]
1844   "flag_pic"
1846   current_function_uses_pic_offset_table = 1;
1847   operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1848   if (no_new_pseudos)
1849     {
1850       operands[3] = operands[0];
1851       operands[4] = operands[0];
1852     }
1853   else
1854     {
1855       operands[3] = gen_reg_rtx (SImode);
1856       operands[4] = gen_reg_rtx (SImode);
1857     }
1858   operands[5] = pic_offset_table_rtx;
1861 (define_insn "*movsi_high_pic_label_ref"
1862   [(set (match_operand:SI 0 "register_operand" "=r")
1863       (high:SI
1864         (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1865                     (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1866   "flag_pic"
1867   "sethi\t%%hi(%a2-(%a1-.)), %0")
1869 (define_insn "*movsi_lo_sum_pic_label_ref"
1870   [(set (match_operand:SI 0 "register_operand" "=r")
1871       (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1872         (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
1873                     (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1874   "flag_pic"
1875   "or\t%1, %%lo(%a3-(%a2-.)), %0")
1877 (define_expand "movdi"
1878   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1879         (match_operand:DI 1 "general_operand" ""))]
1880   ""
1882   if (sparc_expand_move (DImode, operands))
1883     DONE;
1886 ;; Be careful, fmovd does not exist when !v9.
1887 ;; We match MEM moves directly when we have correct even
1888 ;; numbered registers, but fall into splits otherwise.
1889 ;; The constraint ordering here is really important to
1890 ;; avoid insane problems in reload, especially for patterns
1891 ;; of the form:
1893 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
1894 ;;                       (const_int -5016)))
1895 ;;      (reg:DI 2 %g2))
1898 (define_insn "*movdi_insn_sp32"
1899   [(set (match_operand:DI 0 "nonimmediate_operand"
1900                                 "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
1901         (match_operand:DI 1 "input_operand"
1902                                 " J,U,T,r,o,i,r, f, T, o, f, f"))]
1903   "! TARGET_V9
1904    && (register_operand (operands[0], DImode)
1905        || register_or_zero_operand (operands[1], DImode))"
1906   "@
1907    #
1908    std\t%1, %0
1909    ldd\t%1, %0
1910    #
1911    #
1912    #
1913    #
1914    std\t%1, %0
1915    ldd\t%1, %0
1916    #
1917    #
1918    #"
1919   [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
1920    (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
1922 (define_insn "*movdi_insn_sp32_v9"
1923   [(set (match_operand:DI 0 "nonimmediate_operand"
1924                                         "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?e,?e,?W")
1925         (match_operand:DI 1 "input_operand"
1926                                         " J,J,U,T,r,o,i,r, f, T, o, f, e, W, e"))]
1927   "! TARGET_ARCH64
1928    && TARGET_V9
1929    && (register_operand (operands[0], DImode)
1930        || register_or_zero_operand (operands[1], DImode))"
1931   "@
1932    stx\t%%g0, %0
1933    #
1934    std\t%1, %0
1935    ldd\t%1, %0
1936    #
1937    #
1938    #
1939    #
1940    std\t%1, %0
1941    ldd\t%1, %0
1942    #
1943    #
1944    fmovd\\t%1, %0
1945    ldd\\t%1, %0
1946    std\\t%1, %0"
1947   [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,fpload,fpstore")
1948    (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,*,*")
1949    (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])
1951 (define_insn "*movdi_insn_sp64"
1952   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,m,?e,?e,?W,b")
1953         (match_operand:DI 1 "input_operand"   "rI,N,m,rJ,e,W,e,J"))]
1954   "TARGET_ARCH64
1955    && (register_operand (operands[0], DImode)
1956        || register_or_zero_operand (operands[1], DImode))"
1957   "@
1958    mov\t%1, %0
1959    sethi\t%%hi(%a1), %0
1960    ldx\t%1, %0
1961    stx\t%r1, %0
1962    fmovd\t%1, %0
1963    ldd\t%1, %0
1964    std\t%1, %0
1965    fzero\t%0"
1966   [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga")
1967    (set_attr "fptype" "*,*,*,*,double,*,*,double")])
1969 (define_expand "movdi_pic_label_ref"
1970   [(set (match_dup 3) (high:DI
1971      (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1972                  (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1973    (set (match_dup 4) (lo_sum:DI (match_dup 3)
1974      (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1975    (set (match_operand:DI 0 "register_operand" "=r")
1976         (minus:DI (match_dup 5) (match_dup 4)))]
1977   "TARGET_ARCH64 && flag_pic"
1979   current_function_uses_pic_offset_table = 1;
1980   operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1981   if (no_new_pseudos)
1982     {
1983       operands[3] = operands[0];
1984       operands[4] = operands[0];
1985     }
1986   else
1987     {
1988       operands[3] = gen_reg_rtx (DImode);
1989       operands[4] = gen_reg_rtx (DImode);
1990     }
1991   operands[5] = pic_offset_table_rtx;
1994 (define_insn "*movdi_high_pic_label_ref"
1995   [(set (match_operand:DI 0 "register_operand" "=r")
1996         (high:DI
1997           (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1998                       (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1999   "TARGET_ARCH64 && flag_pic"
2000   "sethi\t%%hi(%a2-(%a1-.)), %0")
2002 (define_insn "*movdi_lo_sum_pic_label_ref"
2003   [(set (match_operand:DI 0 "register_operand" "=r")
2004       (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2005         (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
2006                     (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2007   "TARGET_ARCH64 && flag_pic"
2008   "or\t%1, %%lo(%a3-(%a2-.)), %0")
2010 ;; SPARC-v9 code model support insns.  See sparc_emit_set_symbolic_const64
2011 ;; in sparc.c to see what is going on here... PIC stuff comes first.
2013 (define_insn "movdi_lo_sum_pic"
2014   [(set (match_operand:DI 0 "register_operand" "=r")
2015         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2016                    (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
2017   "TARGET_ARCH64 && flag_pic"
2018   "or\t%1, %%lo(%a2), %0")
2020 (define_insn "movdi_high_pic"
2021   [(set (match_operand:DI 0 "register_operand" "=r")
2022         (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
2023   "TARGET_ARCH64 && flag_pic && check_pic (1)"
2024   "sethi\t%%hi(%a1), %0")
2026 (define_insn "*sethi_di_medlow_embmedany_pic"
2027   [(set (match_operand:DI 0 "register_operand" "=r")
2028         (high:DI (match_operand:DI 1 "medium_pic_operand" "")))]
2029   "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
2030   "sethi\t%%hi(%a1), %0")
2032 (define_insn "*sethi_di_medlow"
2033   [(set (match_operand:DI 0 "register_operand" "=r")
2034         (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
2035   "TARGET_CM_MEDLOW && check_pic (1)"
2036   "sethi\t%%hi(%a1), %0")
2038 (define_insn "*losum_di_medlow"
2039   [(set (match_operand:DI 0 "register_operand" "=r")
2040         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2041                    (match_operand:DI 2 "symbolic_operand" "")))]
2042   "TARGET_CM_MEDLOW"
2043   "or\t%1, %%lo(%a2), %0")
2045 (define_insn "seth44"
2046   [(set (match_operand:DI 0 "register_operand" "=r")
2047         (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
2048   "TARGET_CM_MEDMID"
2049   "sethi\t%%h44(%a1), %0")
2051 (define_insn "setm44"
2052   [(set (match_operand:DI 0 "register_operand" "=r")
2053         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2054                    (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
2055   "TARGET_CM_MEDMID"
2056   "or\t%1, %%m44(%a2), %0")
2058 (define_insn "setl44"
2059   [(set (match_operand:DI 0 "register_operand" "=r")
2060         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2061                    (match_operand:DI 2 "symbolic_operand" "")))]
2062   "TARGET_CM_MEDMID"
2063   "or\t%1, %%l44(%a2), %0")
2065 (define_insn "sethh"
2066   [(set (match_operand:DI 0 "register_operand" "=r")
2067         (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
2068   "TARGET_CM_MEDANY"
2069   "sethi\t%%hh(%a1), %0")
2071 (define_insn "setlm"
2072   [(set (match_operand:DI 0 "register_operand" "=r")
2073         (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
2074   "TARGET_CM_MEDANY"
2075   "sethi\t%%lm(%a1), %0")
2077 (define_insn "sethm"
2078   [(set (match_operand:DI 0 "register_operand" "=r")
2079         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2080                    (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
2081   "TARGET_CM_MEDANY"
2082   "or\t%1, %%hm(%a2), %0")
2084 (define_insn "setlo"
2085   [(set (match_operand:DI 0 "register_operand" "=r")
2086         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2087                    (match_operand:DI 2 "symbolic_operand" "")))]
2088   "TARGET_CM_MEDANY"
2089   "or\t%1, %%lo(%a2), %0")
2091 (define_insn "embmedany_sethi"
2092   [(set (match_operand:DI 0 "register_operand" "=r")
2093         (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
2094   "TARGET_CM_EMBMEDANY && check_pic (1)"
2095   "sethi\t%%hi(%a1), %0")
2097 (define_insn "embmedany_losum"
2098   [(set (match_operand:DI 0 "register_operand" "=r")
2099         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2100                    (match_operand:DI 2 "data_segment_operand" "")))]
2101   "TARGET_CM_EMBMEDANY"
2102   "add\t%1, %%lo(%a2), %0")
2104 (define_insn "embmedany_brsum"
2105   [(set (match_operand:DI 0 "register_operand" "=r")
2106         (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
2107   "TARGET_CM_EMBMEDANY"
2108   "add\t%1, %_, %0")
2110 (define_insn "embmedany_textuhi"
2111   [(set (match_operand:DI 0 "register_operand" "=r")
2112         (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
2113   "TARGET_CM_EMBMEDANY && check_pic (1)"
2114   "sethi\t%%uhi(%a1), %0")
2116 (define_insn "embmedany_texthi"
2117   [(set (match_operand:DI 0 "register_operand" "=r")
2118         (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
2119   "TARGET_CM_EMBMEDANY && check_pic (1)"
2120   "sethi\t%%hi(%a1), %0")
2122 (define_insn "embmedany_textulo"
2123   [(set (match_operand:DI 0 "register_operand" "=r")
2124         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2125                    (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
2126   "TARGET_CM_EMBMEDANY"
2127   "or\t%1, %%ulo(%a2), %0")
2129 (define_insn "embmedany_textlo"
2130   [(set (match_operand:DI 0 "register_operand" "=r")
2131         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2132                    (match_operand:DI 2 "text_segment_operand" "")))]
2133   "TARGET_CM_EMBMEDANY"
2134   "or\t%1, %%lo(%a2), %0")
2136 ;; Now some patterns to help reload out a bit.
2137 (define_expand "reload_indi"
2138   [(parallel [(match_operand:DI 0 "register_operand" "=r")
2139               (match_operand:DI 1 "immediate_operand" "")
2140               (match_operand:TI 2 "register_operand" "=&r")])]
2141   "(TARGET_CM_MEDANY
2142     || TARGET_CM_EMBMEDANY)
2143    && ! flag_pic"
2145   sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2146   DONE;
2149 (define_expand "reload_outdi"
2150   [(parallel [(match_operand:DI 0 "register_operand" "=r")
2151               (match_operand:DI 1 "immediate_operand" "")
2152               (match_operand:TI 2 "register_operand" "=&r")])]
2153   "(TARGET_CM_MEDANY
2154     || TARGET_CM_EMBMEDANY)
2155    && ! flag_pic"
2157   sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2158   DONE;
2161 ;; Split up putting CONSTs and REGs into DI regs when !arch64
2162 (define_split
2163   [(set (match_operand:DI 0 "register_operand" "")
2164         (match_operand:DI 1 "const_int_operand" ""))]
2165   "! TARGET_ARCH64 && reload_completed"
2166   [(clobber (const_int 0))]
2168 #if HOST_BITS_PER_WIDE_INT == 32
2169   emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2170                         (INTVAL (operands[1]) < 0) ?
2171                         constm1_rtx :
2172                         const0_rtx));
2173   emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2174                         operands[1]));
2175 #else
2176   unsigned int low, high;
2178   low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
2179   high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
2180   emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
2182   /* Slick... but this trick loses if this subreg constant part
2183      can be done in one insn.  */
2184   if (low == high
2185       && ! SPARC_SETHI32_P (high)
2186       && ! SPARC_SIMM13_P (high))
2187     emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2188                           gen_highpart (SImode, operands[0])));
2189   else
2190     emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
2191 #endif
2192   DONE;
2195 (define_split
2196   [(set (match_operand:DI 0 "register_operand" "")
2197         (match_operand:DI 1 "const_double_operand" ""))]
2198   "reload_completed
2199    && (! TARGET_V9
2200        || (! TARGET_ARCH64
2201            && ((GET_CODE (operands[0]) == REG
2202                 && REGNO (operands[0]) < 32)
2203                || (GET_CODE (operands[0]) == SUBREG
2204                    && GET_CODE (SUBREG_REG (operands[0])) == REG
2205                    && REGNO (SUBREG_REG (operands[0])) < 32))))"
2206   [(clobber (const_int 0))]
2208   emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2209                         GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
2211   /* Slick... but this trick loses if this subreg constant part
2212      can be done in one insn.  */
2213   if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
2214       && ! SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
2215       && ! SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1])))
2216     {
2217       emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2218                             gen_highpart (SImode, operands[0])));
2219     }
2220   else
2221     {
2222       emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2223                             GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
2224     }
2225   DONE;
2228 (define_split
2229   [(set (match_operand:DI 0 "register_operand" "")
2230         (match_operand:DI 1 "register_operand" ""))]
2231   "reload_completed
2232    && (! TARGET_V9
2233        || (! TARGET_ARCH64
2234            && ((GET_CODE (operands[0]) == REG
2235                 && REGNO (operands[0]) < 32)
2236                || (GET_CODE (operands[0]) == SUBREG
2237                    && GET_CODE (SUBREG_REG (operands[0])) == REG
2238                    && REGNO (SUBREG_REG (operands[0])) < 32))))"
2239   [(clobber (const_int 0))]
2241   rtx set_dest = operands[0];
2242   rtx set_src = operands[1];
2243   rtx dest1, dest2;
2244   rtx src1, src2;
2246   dest1 = gen_highpart (SImode, set_dest);
2247   dest2 = gen_lowpart (SImode, set_dest);
2248   src1 = gen_highpart (SImode, set_src);
2249   src2 = gen_lowpart (SImode, set_src);
2251   /* Now emit using the real source and destination we found, swapping
2252      the order if we detect overlap.  */
2253   if (reg_overlap_mentioned_p (dest1, src2))
2254     {
2255       emit_insn (gen_movsi (dest2, src2));
2256       emit_insn (gen_movsi (dest1, src1));
2257     }
2258   else
2259     {
2260       emit_insn (gen_movsi (dest1, src1));
2261       emit_insn (gen_movsi (dest2, src2));
2262     }
2263   DONE;
2266 ;; Now handle the cases of memory moves from/to non-even
2267 ;; DI mode register pairs.
2268 (define_split
2269   [(set (match_operand:DI 0 "register_operand" "")
2270         (match_operand:DI 1 "memory_operand" ""))]
2271   "(! TARGET_ARCH64
2272     && reload_completed
2273     && sparc_splitdi_legitimate (operands[0], operands[1]))"
2274   [(clobber (const_int 0))]
2276   rtx word0 = adjust_address (operands[1], SImode, 0);
2277   rtx word1 = adjust_address (operands[1], SImode, 4);
2278   rtx high_part = gen_highpart (SImode, operands[0]);
2279   rtx low_part = gen_lowpart (SImode, operands[0]);
2281   if (reg_overlap_mentioned_p (high_part, word1))
2282     {
2283       emit_insn (gen_movsi (low_part, word1));
2284       emit_insn (gen_movsi (high_part, word0));
2285     }
2286   else
2287     {
2288       emit_insn (gen_movsi (high_part, word0));
2289       emit_insn (gen_movsi (low_part, word1));
2290     }
2291   DONE;
2294 (define_split
2295   [(set (match_operand:DI 0 "memory_operand" "")
2296         (match_operand:DI 1 "register_operand" ""))]
2297   "(! TARGET_ARCH64
2298     && reload_completed
2299     && sparc_splitdi_legitimate (operands[1], operands[0]))"
2300   [(clobber (const_int 0))]
2302   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
2303                         gen_highpart (SImode, operands[1])));
2304   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
2305                         gen_lowpart (SImode, operands[1])));
2306   DONE;
2309 (define_split
2310   [(set (match_operand:DI 0 "memory_operand" "")
2311         (match_operand:DI 1 "const_zero_operand" ""))]
2312   "reload_completed
2313    && (! TARGET_V9
2314        || (! TARGET_ARCH64
2315            && ! mem_min_alignment (operands[0], 8)))
2316    && offsettable_memref_p (operands[0])"
2317   [(clobber (const_int 0))]
2319   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
2320   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
2321   DONE;
2325 ;; Floating point and vector move instructions
2327 ;; We don't define V1SI because SI should work just fine.
2328 (define_mode_macro V32 [SF V2HI V4QI])
2330 ;; Yes, you guessed it right, the former movsf expander.
2331 (define_expand "mov<V32:mode>"
2332   [(set (match_operand:V32 0 "nonimmediate_operand" "")
2333         (match_operand:V32 1 "general_operand" ""))]
2334   "<V32:MODE>mode == SFmode || TARGET_VIS"
2336   if (sparc_expand_move (<V32:MODE>mode, operands))
2337     DONE;
2340 (define_insn "*movsf_insn"
2341   [(set (match_operand:V32 0 "nonimmediate_operand" "=d,f,*r,*r,*r,f,*r,m,m")
2342         (match_operand:V32 1 "input_operand"        "GY,f,*rRY,Q,S,m,m,f,*rGY"))]
2343   "TARGET_FPU
2344    && (register_operand (operands[0], <V32:MODE>mode)
2345        || register_or_zero_operand (operands[1], <V32:MODE>mode))"
2347   if (GET_CODE (operands[1]) == CONST_DOUBLE
2348       && (which_alternative == 2
2349           || which_alternative == 3
2350           || which_alternative == 4))
2351     {
2352       REAL_VALUE_TYPE r;
2353       long i;
2355       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2356       REAL_VALUE_TO_TARGET_SINGLE (r, i);
2357       operands[1] = GEN_INT (i);
2358     }
2360   switch (which_alternative)
2361     {
2362     case 0:
2363       return "fzeros\t%0";
2364     case 1:
2365       return "fmovs\t%1, %0";
2366     case 2:
2367       return "mov\t%1, %0";
2368     case 3:
2369       return "sethi\t%%hi(%a1), %0";
2370     case 4:
2371       return "#";
2372     case 5:
2373     case 6:
2374       return "ld\t%1, %0";
2375     case 7:
2376     case 8:
2377       return "st\t%r1, %0";
2378     default:
2379       gcc_unreachable ();
2380     }
2382   [(set_attr "type" "fga,fpmove,*,*,*,fpload,load,fpstore,store")])
2384 ;; Exactly the same as above, except that all `f' cases are deleted.
2385 ;; This is necessary to prevent reload from ever trying to use a `f' reg
2386 ;; when -mno-fpu.
2388 (define_insn "*movsf_insn_no_fpu"
2389   [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,m")
2390         (match_operand:SF 1 "input_operand"    "rR,Q,S,m,rG"))]
2391   "! TARGET_FPU
2392    && (register_operand (operands[0], SFmode)
2393        || register_or_zero_operand (operands[1], SFmode))"
2395   if (GET_CODE (operands[1]) == CONST_DOUBLE
2396       && (which_alternative == 0
2397           || which_alternative == 1
2398           || which_alternative == 2))
2399     {
2400       REAL_VALUE_TYPE r;
2401       long i;
2403       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2404       REAL_VALUE_TO_TARGET_SINGLE (r, i);
2405       operands[1] = GEN_INT (i);
2406     }
2408   switch (which_alternative)
2409     {
2410     case 0:
2411       return "mov\t%1, %0";
2412     case 1:
2413       return "sethi\t%%hi(%a1), %0";
2414     case 2:
2415       return "#";
2416     case 3:
2417       return "ld\t%1, %0";
2418     case 4:
2419       return "st\t%r1, %0";
2420     default:
2421       gcc_unreachable ();
2422     }
2424   [(set_attr "type" "*,*,*,load,store")])
2426 ;; The following 3 patterns build SFmode constants in integer registers.
2428 (define_insn "*movsf_lo_sum"
2429   [(set (match_operand:SF 0 "register_operand" "=r")
2430         (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
2431                    (match_operand:SF 2 "fp_const_high_losum_operand" "S")))]
2432   ""
2434   REAL_VALUE_TYPE r;
2435   long i;
2437   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
2438   REAL_VALUE_TO_TARGET_SINGLE (r, i);
2439   operands[2] = GEN_INT (i);
2440   return "or\t%1, %%lo(%a2), %0";
2443 (define_insn "*movsf_high"
2444   [(set (match_operand:SF 0 "register_operand" "=r")
2445         (high:SF (match_operand:SF 1 "fp_const_high_losum_operand" "S")))]
2446   ""
2448   REAL_VALUE_TYPE r;
2449   long i;
2451   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2452   REAL_VALUE_TO_TARGET_SINGLE (r, i);
2453   operands[1] = GEN_INT (i);
2454   return "sethi\t%%hi(%1), %0";
2457 (define_split
2458   [(set (match_operand:SF 0 "register_operand" "")
2459         (match_operand:SF 1 "fp_const_high_losum_operand" ""))]
2460   "REG_P (operands[0]) && REGNO (operands[0]) < 32"
2461   [(set (match_dup 0) (high:SF (match_dup 1)))
2462    (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
2464 (define_mode_macro V64 [DF V2SI V4HI V8QI])
2466 ;; Yes, you again guessed it right, the former movdf expander.
2467 (define_expand "mov<V64:mode>"
2468   [(set (match_operand:V64 0 "nonimmediate_operand" "")
2469         (match_operand:V64 1 "general_operand" ""))]
2470   "<V64:MODE>mode == DFmode || TARGET_VIS"
2472   if (sparc_expand_move (<V64:MODE>mode, operands))
2473     DONE;
2476 ;; Be careful, fmovd does not exist when !v9.
2477 (define_insn "*movdf_insn_sp32"
2478   [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o")
2479         (match_operand:DF 1 "input_operand"    "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
2480   "TARGET_FPU
2481    && ! TARGET_V9
2482    && (register_operand (operands[0], DFmode)
2483        || register_or_zero_operand (operands[1], DFmode))"
2484   "@
2485   ldd\t%1, %0
2486   std\t%1, %0
2487   ldd\t%1, %0
2488   std\t%1, %0
2489   #
2490   #
2491   #
2492   #
2493   #
2494   #"
2495  [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
2496   (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
2498 (define_insn "*movdf_insn_sp32_no_fpu"
2499   [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
2500         (match_operand:DF 1 "input_operand"    "T,U,G,ro,r"))]
2501   "! TARGET_FPU
2502    && ! TARGET_V9
2503    && (register_operand (operands[0], DFmode)
2504        || register_or_zero_operand (operands[1], DFmode))"
2505   "@
2506   ldd\t%1, %0
2507   std\t%1, %0
2508   #
2509   #
2510   #"
2511   [(set_attr "type" "load,store,*,*,*")
2512    (set_attr "length" "*,*,2,2,2")])
2514 ;; We have available v9 double floats but not 64-bit integer registers.
2515 (define_insn "*movdf_insn_sp32_v9"
2516   [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,T,W,U,T,f,*r,o")
2517         (match_operand:V64 1 "input_operand" "GY,e,W#F,GY,e,T,U,o#F,*roGYF,*rGYf"))]
2518   "TARGET_FPU
2519    && TARGET_V9
2520    && ! TARGET_ARCH64
2521    && (register_operand (operands[0], <V64:MODE>mode)
2522        || register_or_zero_operand (operands[1], <V64:MODE>mode))"
2523   "@
2524   fzero\t%0
2525   fmovd\t%1, %0
2526   ldd\t%1, %0
2527   stx\t%r1, %0
2528   std\t%1, %0
2529   ldd\t%1, %0
2530   std\t%1, %0
2531   #
2532   #
2533   #"
2534   [(set_attr "type" "fga,fpmove,load,store,store,load,store,*,*,*")
2535    (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
2536    (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
2538 (define_insn "*movdf_insn_sp32_v9_no_fpu"
2539   [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
2540         (match_operand:DF 1 "input_operand"    "T,U,G,ro,rG"))]
2541   "! TARGET_FPU
2542    && TARGET_V9
2543    && ! TARGET_ARCH64
2544    && (register_operand (operands[0], DFmode)
2545        || register_or_zero_operand (operands[1], DFmode))"
2546   "@
2547   ldd\t%1, %0
2548   std\t%1, %0
2549   stx\t%r1, %0
2550   #
2551   #"
2552   [(set_attr "type" "load,store,store,*,*")
2553    (set_attr "length" "*,*,*,2,2")])
2555 ;; We have available both v9 double floats and 64-bit integer registers.
2556 (define_insn "*movdf_insn_sp64"
2557   [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,W,*r,*r,m,*r")
2558         (match_operand:V64 1 "input_operand"    "GY,e,W#F,e,*rGY,m,*rGY,F"))]
2559   "TARGET_FPU
2560    && TARGET_ARCH64
2561    && (register_operand (operands[0], <V64:MODE>mode)
2562        || register_or_zero_operand (operands[1], <V64:MODE>mode))"
2563   "@
2564   fzero\t%0
2565   fmovd\t%1, %0
2566   ldd\t%1, %0
2567   std\t%1, %0
2568   mov\t%r1, %0
2569   ldx\t%1, %0
2570   stx\t%r1, %0
2571   #"
2572   [(set_attr "type" "fga,fpmove,load,store,*,load,store,*")
2573    (set_attr "length" "*,*,*,*,*,*,*,2")
2574    (set_attr "fptype" "double,double,*,*,*,*,*,*")])
2576 (define_insn "*movdf_insn_sp64_no_fpu"
2577   [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
2578         (match_operand:DF 1 "input_operand"    "r,m,rG"))]
2579   "! TARGET_FPU
2580    && TARGET_ARCH64
2581    && (register_operand (operands[0], DFmode)
2582        || register_or_zero_operand (operands[1], DFmode))"
2583   "@
2584   mov\t%1, %0
2585   ldx\t%1, %0
2586   stx\t%r1, %0"
2587   [(set_attr "type" "*,load,store")])
2589 ;; This pattern build DFmode constants in integer registers.
2590 (define_split
2591   [(set (match_operand:DF 0 "register_operand" "")
2592         (match_operand:DF 1 "const_double_operand" ""))]
2593   "TARGET_FPU
2594    && (GET_CODE (operands[0]) == REG
2595        && REGNO (operands[0]) < 32)
2596    && ! const_zero_operand(operands[1], DFmode)
2597    && reload_completed"
2598   [(clobber (const_int 0))]
2600   REAL_VALUE_TYPE r;
2601   long l[2];
2603   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2604   REAL_VALUE_TO_TARGET_DOUBLE (r, l);
2605   operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
2607   if (TARGET_ARCH64)
2608     {
2609 #if HOST_BITS_PER_WIDE_INT == 32
2610       gcc_unreachable ();
2611 #else
2612       HOST_WIDE_INT val;
2614       val = ((HOST_WIDE_INT)(unsigned long)l[1] |
2615              ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
2616       emit_insn (gen_movdi (operands[0], gen_int_mode (val, DImode)));
2617 #endif
2618     }
2619   else
2620     {
2621       emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2622                             gen_int_mode (l[0], SImode)));
2624       /* Slick... but this trick loses if this subreg constant part
2625          can be done in one insn.  */
2626       if (l[1] == l[0]
2627           && ! SPARC_SETHI32_P (l[0])
2628           && ! SPARC_SIMM13_P (l[0]))
2629         {
2630           emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2631                                 gen_highpart (SImode, operands[0])));
2632         }
2633       else
2634         {
2635           emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2636                                 gen_int_mode (l[1], SImode)));
2637         }
2638     }
2639   DONE;
2642 ;; Ok, now the splits to handle all the multi insn and
2643 ;; mis-aligned memory address cases.
2644 ;; In these splits please take note that we must be
2645 ;; careful when V9 but not ARCH64 because the integer
2646 ;; register DFmode cases must be handled.
2647 (define_split
2648   [(set (match_operand:V64 0 "register_operand" "")
2649         (match_operand:V64 1 "register_operand" ""))]
2650   "(! TARGET_V9
2651     || (! TARGET_ARCH64
2652         && ((GET_CODE (operands[0]) == REG
2653              && REGNO (operands[0]) < 32)
2654             || (GET_CODE (operands[0]) == SUBREG
2655                 && GET_CODE (SUBREG_REG (operands[0])) == REG
2656                 && REGNO (SUBREG_REG (operands[0])) < 32))))
2657    && reload_completed"
2658   [(clobber (const_int 0))]
2660   rtx set_dest = operands[0];
2661   rtx set_src = operands[1];
2662   rtx dest1, dest2;
2663   rtx src1, src2;
2664   enum machine_mode half_mode;
2666   /* We can be expanded for DFmode or integral vector modes.  */
2667   if (<V64:MODE>mode == DFmode)
2668     half_mode = SFmode;
2669   else
2670     half_mode = SImode;
2671   
2672   dest1 = gen_highpart (half_mode, set_dest);
2673   dest2 = gen_lowpart (half_mode, set_dest);
2674   src1 = gen_highpart (half_mode, set_src);
2675   src2 = gen_lowpart (half_mode, set_src);
2677   /* Now emit using the real source and destination we found, swapping
2678      the order if we detect overlap.  */
2679   if (reg_overlap_mentioned_p (dest1, src2))
2680     {
2681       emit_move_insn_1 (dest2, src2);
2682       emit_move_insn_1 (dest1, src1);
2683     }
2684   else
2685     {
2686       emit_move_insn_1 (dest1, src1);
2687       emit_move_insn_1 (dest2, src2);
2688     }
2689   DONE;
2692 (define_split
2693   [(set (match_operand:V64 0 "register_operand" "")
2694         (match_operand:V64 1 "memory_operand" ""))]
2695   "reload_completed
2696    && ! TARGET_ARCH64
2697    && (((REGNO (operands[0]) % 2) != 0)
2698        || ! mem_min_alignment (operands[1], 8))
2699    && offsettable_memref_p (operands[1])"
2700   [(clobber (const_int 0))]
2702   enum machine_mode half_mode;
2703   rtx word0, word1;
2705   /* We can be expanded for DFmode or integral vector modes.  */
2706   if (<V64:MODE>mode == DFmode)
2707     half_mode = SFmode;
2708   else
2709     half_mode = SImode;
2711   word0 = adjust_address (operands[1], half_mode, 0);
2712   word1 = adjust_address (operands[1], half_mode, 4);
2714   if (reg_overlap_mentioned_p (gen_highpart (half_mode, operands[0]), word1))
2715     {
2716       emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2717       emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2718     }
2719   else
2720     {
2721       emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2722       emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2723     }
2724   DONE;
2727 (define_split
2728   [(set (match_operand:V64 0 "memory_operand" "")
2729         (match_operand:V64 1 "register_operand" ""))]
2730   "reload_completed
2731    && ! TARGET_ARCH64
2732    && (((REGNO (operands[1]) % 2) != 0)
2733        || ! mem_min_alignment (operands[0], 8))
2734    && offsettable_memref_p (operands[0])"
2735   [(clobber (const_int 0))]
2737   enum machine_mode half_mode;
2738   rtx word0, word1;
2740   /* We can be expanded for DFmode or integral vector modes.  */
2741   if (<V64:MODE>mode == DFmode)
2742     half_mode = SFmode;
2743   else
2744     half_mode = SImode;
2746   word0 = adjust_address (operands[0], half_mode, 0);
2747   word1 = adjust_address (operands[0], half_mode, 4);
2749   emit_move_insn_1 (word0, gen_highpart (half_mode, operands[1]));
2750   emit_move_insn_1 (word1, gen_lowpart (half_mode, operands[1]));
2751   DONE;
2754 (define_split
2755   [(set (match_operand:V64 0 "memory_operand" "")
2756         (match_operand:V64 1 "const_zero_operand" ""))]
2757   "reload_completed
2758    && (! TARGET_V9
2759        || (! TARGET_ARCH64
2760            && ! mem_min_alignment (operands[0], 8)))
2761    && offsettable_memref_p (operands[0])"
2762   [(clobber (const_int 0))]
2764   enum machine_mode half_mode;
2765   rtx dest1, dest2;
2767   /* We can be expanded for DFmode or integral vector modes.  */
2768   if (<V64:MODE>mode == DFmode)
2769     half_mode = SFmode;
2770   else
2771     half_mode = SImode;
2773   dest1 = adjust_address (operands[0], half_mode, 0);
2774   dest2 = adjust_address (operands[0], half_mode, 4);
2776   emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2777   emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2778   DONE;
2781 (define_split
2782   [(set (match_operand:V64 0 "register_operand" "")
2783         (match_operand:V64 1 "const_zero_operand" ""))]
2784   "reload_completed
2785    && ! TARGET_ARCH64
2786    && ((GET_CODE (operands[0]) == REG
2787         && REGNO (operands[0]) < 32)
2788        || (GET_CODE (operands[0]) == SUBREG
2789            && GET_CODE (SUBREG_REG (operands[0])) == REG
2790            && REGNO (SUBREG_REG (operands[0])) < 32))"
2791   [(clobber (const_int 0))]
2793   enum machine_mode half_mode;
2794   rtx set_dest = operands[0];
2795   rtx dest1, dest2;
2797   /* We can be expanded for DFmode or integral vector modes.  */
2798   if (<V64:MODE>mode == DFmode)
2799     half_mode = SFmode;
2800   else
2801     half_mode = SImode;
2803   dest1 = gen_highpart (half_mode, set_dest);
2804   dest2 = gen_lowpart (half_mode, set_dest);
2805   emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2806   emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2807   DONE;
2810 (define_expand "movtf"
2811   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2812         (match_operand:TF 1 "general_operand" ""))]
2813   ""
2815   if (sparc_expand_move (TFmode, operands))
2816     DONE;
2819 (define_insn "*movtf_insn_sp32"
2820   [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,U,r")
2821         (match_operand:TF 1 "input_operand"    "G,oe,GeUr,o,roG"))]
2822   "TARGET_FPU
2823    && ! TARGET_ARCH64
2824    && (register_operand (operands[0], TFmode)
2825        || register_or_zero_operand (operands[1], TFmode))"
2826   "#"
2827   [(set_attr "length" "4")])
2829 ;; Exactly the same as above, except that all `e' cases are deleted.
2830 ;; This is necessary to prevent reload from ever trying to use a `e' reg
2831 ;; when -mno-fpu.
2833 (define_insn "*movtf_insn_sp32_no_fpu"
2834   [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
2835         (match_operand:TF 1 "input_operand"    "G,o,U,roG,r"))]
2836   "! TARGET_FPU
2837    && ! TARGET_ARCH64
2838    && (register_operand (operands[0], TFmode)
2839        || register_or_zero_operand (operands[1], TFmode))"
2840   "#"
2841   [(set_attr "length" "4")])
2843 (define_insn "*movtf_insn_sp64"
2844   [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,r")
2845         (match_operand:TF 1 "input_operand"    "G,oe,Ger,roG"))]
2846   "TARGET_FPU
2847    && TARGET_ARCH64
2848    && ! TARGET_HARD_QUAD
2849    && (register_operand (operands[0], TFmode)
2850        || register_or_zero_operand (operands[1], TFmode))"
2851   "#"
2852   [(set_attr "length" "2")])
2854 (define_insn "*movtf_insn_sp64_hq"
2855   [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,e,m,o,r")
2856         (match_operand:TF 1 "input_operand"    "G,e,m,e,rG,roG"))]
2857   "TARGET_FPU
2858    && TARGET_ARCH64
2859    && TARGET_HARD_QUAD
2860    && (register_operand (operands[0], TFmode)
2861        || register_or_zero_operand (operands[1], TFmode))"
2862   "@
2863   #
2864   fmovq\t%1, %0
2865   ldq\t%1, %0
2866   stq\t%1, %0
2867   #
2868   #"
2869   [(set_attr "type" "*,fpmove,fpload,fpstore,*,*")
2870    (set_attr "length" "2,*,*,*,2,2")])
2872 (define_insn "*movtf_insn_sp64_no_fpu"
2873   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
2874         (match_operand:TF 1 "input_operand"    "orG,rG"))]
2875   "! TARGET_FPU
2876    && TARGET_ARCH64
2877    && (register_operand (operands[0], TFmode)
2878        || register_or_zero_operand (operands[1], TFmode))"
2879   "#"
2880   [(set_attr "length" "2")])
2882 ;; Now all the splits to handle multi-insn TF mode moves.
2883 (define_split
2884   [(set (match_operand:TF 0 "register_operand" "")
2885         (match_operand:TF 1 "register_operand" ""))]
2886   "reload_completed
2887    && (! TARGET_ARCH64
2888        || (TARGET_FPU
2889            && ! TARGET_HARD_QUAD)
2890        || ! fp_register_operand (operands[0], TFmode))"
2891   [(clobber (const_int 0))]
2893   rtx set_dest = operands[0];
2894   rtx set_src = operands[1];
2895   rtx dest1, dest2;
2896   rtx src1, src2;
2898   dest1 = gen_df_reg (set_dest, 0);
2899   dest2 = gen_df_reg (set_dest, 1);
2900   src1 = gen_df_reg (set_src, 0);
2901   src2 = gen_df_reg (set_src, 1);
2903   /* Now emit using the real source and destination we found, swapping
2904      the order if we detect overlap.  */
2905   if (reg_overlap_mentioned_p (dest1, src2))
2906     {
2907       emit_insn (gen_movdf (dest2, src2));
2908       emit_insn (gen_movdf (dest1, src1));
2909     }
2910   else
2911     {
2912       emit_insn (gen_movdf (dest1, src1));
2913       emit_insn (gen_movdf (dest2, src2));
2914     }
2915   DONE;
2918 (define_split
2919   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2920         (match_operand:TF 1 "const_zero_operand" ""))]
2921   "reload_completed"
2922   [(clobber (const_int 0))]
2924   rtx set_dest = operands[0];
2925   rtx dest1, dest2;
2927   switch (GET_CODE (set_dest))
2928     {
2929     case REG:
2930       dest1 = gen_df_reg (set_dest, 0);
2931       dest2 = gen_df_reg (set_dest, 1);
2932       break;
2933     case MEM:
2934       dest1 = adjust_address (set_dest, DFmode, 0);
2935       dest2 = adjust_address (set_dest, DFmode, 8);
2936       break;
2937     default:
2938       gcc_unreachable ();      
2939     }
2941   emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
2942   emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
2943   DONE;
2946 (define_split
2947   [(set (match_operand:TF 0 "register_operand" "")
2948         (match_operand:TF 1 "memory_operand" ""))]
2949   "(reload_completed
2950     && offsettable_memref_p (operands[1])
2951     && (! TARGET_ARCH64
2952         || ! TARGET_HARD_QUAD
2953         || ! fp_register_operand (operands[0], TFmode)))"
2954   [(clobber (const_int 0))]
2956   rtx word0 = adjust_address (operands[1], DFmode, 0);
2957   rtx word1 = adjust_address (operands[1], DFmode, 8);
2958   rtx set_dest, dest1, dest2;
2960   set_dest = operands[0];
2962   dest1 = gen_df_reg (set_dest, 0);
2963   dest2 = gen_df_reg (set_dest, 1);
2965   /* Now output, ordering such that we don't clobber any registers
2966      mentioned in the address.  */
2967   if (reg_overlap_mentioned_p (dest1, word1))
2969     {
2970       emit_insn (gen_movdf (dest2, word1));
2971       emit_insn (gen_movdf (dest1, word0));
2972     }
2973   else
2974    {
2975       emit_insn (gen_movdf (dest1, word0));
2976       emit_insn (gen_movdf (dest2, word1));
2977    }
2978   DONE;
2981 (define_split
2982   [(set (match_operand:TF 0 "memory_operand" "")
2983         (match_operand:TF 1 "register_operand" ""))]
2984   "(reload_completed
2985     && offsettable_memref_p (operands[0])
2986     && (! TARGET_ARCH64
2987         || ! TARGET_HARD_QUAD
2988         || ! fp_register_operand (operands[1], TFmode)))"
2989   [(clobber (const_int 0))]
2991   rtx set_src = operands[1];
2993   emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
2994                         gen_df_reg (set_src, 0)));
2995   emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
2996                         gen_df_reg (set_src, 1)));
2997   DONE;
3001 ;; SPARC-V9 conditional move instructions.
3003 ;; We can handle larger constants here for some flavors, but for now we keep
3004 ;; it simple and only allow those constants supported by all flavors.
3005 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3006 ;; 3 contains the constant if one is present, but we handle either for
3007 ;; generality (sparc.c puts a constant in operand 2).
3009 (define_expand "movqicc"
3010   [(set (match_operand:QI 0 "register_operand" "")
3011         (if_then_else:QI (match_operand 1 "comparison_operator" "")
3012                          (match_operand:QI 2 "arith10_operand" "")
3013                          (match_operand:QI 3 "arith10_operand" "")))]
3014   "TARGET_V9"
3016   enum rtx_code code = GET_CODE (operands[1]);
3018   if (GET_MODE (sparc_compare_op0) == DImode
3019       && ! TARGET_ARCH64)
3020     FAIL;
3022   if (sparc_compare_op1 == const0_rtx
3023       && GET_CODE (sparc_compare_op0) == REG
3024       && GET_MODE (sparc_compare_op0) == DImode
3025       && v9_regcmp_p (code))
3026     {
3027       operands[1] = gen_rtx_fmt_ee (code, DImode,
3028                              sparc_compare_op0, sparc_compare_op1);
3029     }
3030   else
3031     {
3032       rtx cc_reg = gen_compare_reg (code);
3033       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3034     }
3037 (define_expand "movhicc"
3038   [(set (match_operand:HI 0 "register_operand" "")
3039         (if_then_else:HI (match_operand 1 "comparison_operator" "")
3040                          (match_operand:HI 2 "arith10_operand" "")
3041                          (match_operand:HI 3 "arith10_operand" "")))]
3042   "TARGET_V9"
3044   enum rtx_code code = GET_CODE (operands[1]);
3046   if (GET_MODE (sparc_compare_op0) == DImode
3047       && ! TARGET_ARCH64)
3048     FAIL;
3050   if (sparc_compare_op1 == const0_rtx
3051       && GET_CODE (sparc_compare_op0) == REG
3052       && GET_MODE (sparc_compare_op0) == DImode
3053       && v9_regcmp_p (code))
3054     {
3055       operands[1] = gen_rtx_fmt_ee (code, DImode,
3056                              sparc_compare_op0, sparc_compare_op1);
3057     }
3058   else
3059     {
3060       rtx cc_reg = gen_compare_reg (code);
3061       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3062     }
3065 (define_expand "movsicc"
3066   [(set (match_operand:SI 0 "register_operand" "")
3067         (if_then_else:SI (match_operand 1 "comparison_operator" "")
3068                          (match_operand:SI 2 "arith10_operand" "")
3069                          (match_operand:SI 3 "arith10_operand" "")))]
3070   "TARGET_V9"
3072   enum rtx_code code = GET_CODE (operands[1]);
3073   enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
3075   if (sparc_compare_op1 == const0_rtx
3076       && GET_CODE (sparc_compare_op0) == REG
3077       && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
3078     {
3079       operands[1] = gen_rtx_fmt_ee (code, op0_mode,
3080                              sparc_compare_op0, sparc_compare_op1);
3081     }
3082   else
3083     {
3084       rtx cc_reg = gen_compare_reg (code);
3085       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3086                                     cc_reg, const0_rtx);
3087     }
3090 (define_expand "movdicc"
3091   [(set (match_operand:DI 0 "register_operand" "")
3092         (if_then_else:DI (match_operand 1 "comparison_operator" "")
3093                          (match_operand:DI 2 "arith10_operand" "")
3094                          (match_operand:DI 3 "arith10_operand" "")))]
3095   "TARGET_ARCH64"
3097   enum rtx_code code = GET_CODE (operands[1]);
3099   if (sparc_compare_op1 == const0_rtx
3100       && GET_CODE (sparc_compare_op0) == REG
3101       && GET_MODE (sparc_compare_op0) == DImode
3102       && v9_regcmp_p (code))
3103     {
3104       operands[1] = gen_rtx_fmt_ee (code, DImode,
3105                              sparc_compare_op0, sparc_compare_op1);
3106     }
3107   else
3108     {
3109       rtx cc_reg = gen_compare_reg (code);
3110       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3111                                     cc_reg, const0_rtx);
3112     }
3115 (define_expand "movsfcc"
3116   [(set (match_operand:SF 0 "register_operand" "")
3117         (if_then_else:SF (match_operand 1 "comparison_operator" "")
3118                          (match_operand:SF 2 "register_operand" "")
3119                          (match_operand:SF 3 "register_operand" "")))]
3120   "TARGET_V9 && TARGET_FPU"
3122   enum rtx_code code = GET_CODE (operands[1]);
3124   if (GET_MODE (sparc_compare_op0) == DImode
3125       && ! TARGET_ARCH64)
3126     FAIL;
3128   if (sparc_compare_op1 == const0_rtx
3129       && GET_CODE (sparc_compare_op0) == REG
3130       && GET_MODE (sparc_compare_op0) == DImode
3131       && v9_regcmp_p (code))
3132     {
3133       operands[1] = gen_rtx_fmt_ee (code, DImode,
3134                              sparc_compare_op0, sparc_compare_op1);
3135     }
3136   else
3137     {
3138       rtx cc_reg = gen_compare_reg (code);
3139       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3140     }
3143 (define_expand "movdfcc"
3144   [(set (match_operand:DF 0 "register_operand" "")
3145         (if_then_else:DF (match_operand 1 "comparison_operator" "")
3146                          (match_operand:DF 2 "register_operand" "")
3147                          (match_operand:DF 3 "register_operand" "")))]
3148   "TARGET_V9 && TARGET_FPU"
3150   enum rtx_code code = GET_CODE (operands[1]);
3152   if (GET_MODE (sparc_compare_op0) == DImode
3153       && ! TARGET_ARCH64)
3154     FAIL;
3156   if (sparc_compare_op1 == const0_rtx
3157       && GET_CODE (sparc_compare_op0) == REG
3158       && GET_MODE (sparc_compare_op0) == DImode
3159       && v9_regcmp_p (code))
3160     {
3161       operands[1] = gen_rtx_fmt_ee (code, DImode,
3162                              sparc_compare_op0, sparc_compare_op1);
3163     }
3164   else
3165     {
3166       rtx cc_reg = gen_compare_reg (code);
3167       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3168     }
3171 (define_expand "movtfcc"
3172   [(set (match_operand:TF 0 "register_operand" "")
3173         (if_then_else:TF (match_operand 1 "comparison_operator" "")
3174                          (match_operand:TF 2 "register_operand" "")
3175                          (match_operand:TF 3 "register_operand" "")))]
3176   "TARGET_V9 && TARGET_FPU"
3178   enum rtx_code code = GET_CODE (operands[1]);
3180   if (GET_MODE (sparc_compare_op0) == DImode
3181       && ! TARGET_ARCH64)
3182     FAIL;
3184   if (sparc_compare_op1 == const0_rtx
3185       && GET_CODE (sparc_compare_op0) == REG
3186       && GET_MODE (sparc_compare_op0) == DImode
3187       && v9_regcmp_p (code))
3188     {
3189       operands[1] = gen_rtx_fmt_ee (code, DImode,
3190                              sparc_compare_op0, sparc_compare_op1);
3191     }
3192   else
3193     {
3194       rtx cc_reg = gen_compare_reg (code);
3195       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3196     }
3199 ;; Conditional move define_insns.
3201 (define_insn "*movqi_cc_sp64"
3202   [(set (match_operand:QI 0 "register_operand" "=r,r")
3203         (if_then_else:QI (match_operator 1 "comparison_operator"
3204                                 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3205                                  (const_int 0)])
3206                          (match_operand:QI 3 "arith11_operand" "rL,0")
3207                          (match_operand:QI 4 "arith11_operand" "0,rL")))]
3208   "TARGET_V9"
3209   "@
3210    mov%C1\t%x2, %3, %0
3211    mov%c1\t%x2, %4, %0"
3212   [(set_attr "type" "cmove")])
3214 (define_insn "*movhi_cc_sp64"
3215   [(set (match_operand:HI 0 "register_operand" "=r,r")
3216         (if_then_else:HI (match_operator 1 "comparison_operator"
3217                                 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3218                                  (const_int 0)])
3219                          (match_operand:HI 3 "arith11_operand" "rL,0")
3220                          (match_operand:HI 4 "arith11_operand" "0,rL")))]
3221   "TARGET_V9"
3222   "@
3223    mov%C1\t%x2, %3, %0
3224    mov%c1\t%x2, %4, %0"
3225   [(set_attr "type" "cmove")])
3227 (define_insn "*movsi_cc_sp64"
3228   [(set (match_operand:SI 0 "register_operand" "=r,r")
3229         (if_then_else:SI (match_operator 1 "comparison_operator"
3230                                 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3231                                  (const_int 0)])
3232                          (match_operand:SI 3 "arith11_operand" "rL,0")
3233                          (match_operand:SI 4 "arith11_operand" "0,rL")))]
3234   "TARGET_V9"
3235   "@
3236    mov%C1\t%x2, %3, %0
3237    mov%c1\t%x2, %4, %0"
3238   [(set_attr "type" "cmove")])
3240 (define_insn "*movdi_cc_sp64"
3241   [(set (match_operand:DI 0 "register_operand" "=r,r")
3242         (if_then_else:DI (match_operator 1 "comparison_operator"
3243                                 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3244                                  (const_int 0)])
3245                          (match_operand:DI 3 "arith11_operand" "rL,0")
3246                          (match_operand:DI 4 "arith11_operand" "0,rL")))]
3247   "TARGET_ARCH64"
3248   "@
3249    mov%C1\t%x2, %3, %0
3250    mov%c1\t%x2, %4, %0"
3251   [(set_attr "type" "cmove")])
3253 (define_insn "*movdi_cc_sp64_trunc"
3254   [(set (match_operand:SI 0 "register_operand" "=r,r")
3255         (if_then_else:SI (match_operator 1 "comparison_operator"
3256                                 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3257                                  (const_int 0)])
3258                          (match_operand:SI 3 "arith11_operand" "rL,0")
3259                          (match_operand:SI 4 "arith11_operand" "0,rL")))]
3260   "TARGET_ARCH64"
3261   "@
3262    mov%C1\t%x2, %3, %0
3263    mov%c1\t%x2, %4, %0"
3264   [(set_attr "type" "cmove")])
3266 (define_insn "*movsf_cc_sp64"
3267   [(set (match_operand:SF 0 "register_operand" "=f,f")
3268         (if_then_else:SF (match_operator 1 "comparison_operator"
3269                                 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3270                                  (const_int 0)])
3271                          (match_operand:SF 3 "register_operand" "f,0")
3272                          (match_operand:SF 4 "register_operand" "0,f")))]
3273   "TARGET_V9 && TARGET_FPU"
3274   "@
3275    fmovs%C1\t%x2, %3, %0
3276    fmovs%c1\t%x2, %4, %0"
3277   [(set_attr "type" "fpcmove")])
3279 (define_insn "movdf_cc_sp64"
3280   [(set (match_operand:DF 0 "register_operand" "=e,e")
3281         (if_then_else:DF (match_operator 1 "comparison_operator"
3282                                 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3283                                  (const_int 0)])
3284                          (match_operand:DF 3 "register_operand" "e,0")
3285                          (match_operand:DF 4 "register_operand" "0,e")))]
3286   "TARGET_V9 && TARGET_FPU"
3287   "@
3288    fmovd%C1\t%x2, %3, %0
3289    fmovd%c1\t%x2, %4, %0"
3290   [(set_attr "type" "fpcmove")
3291    (set_attr "fptype" "double")])
3293 (define_insn "*movtf_cc_hq_sp64"
3294   [(set (match_operand:TF 0 "register_operand" "=e,e")
3295         (if_then_else:TF (match_operator 1 "comparison_operator"
3296                                 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3297                                  (const_int 0)])
3298                          (match_operand:TF 3 "register_operand" "e,0")
3299                          (match_operand:TF 4 "register_operand" "0,e")))]
3300   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3301   "@
3302    fmovq%C1\t%x2, %3, %0
3303    fmovq%c1\t%x2, %4, %0"
3304   [(set_attr "type" "fpcmove")])
3306 (define_insn_and_split "*movtf_cc_sp64"
3307   [(set (match_operand:TF 0 "register_operand" "=e,e")
3308         (if_then_else:TF (match_operator 1 "comparison_operator"
3309                             [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3310                              (const_int 0)])
3311                          (match_operand:TF 3 "register_operand" "e,0")
3312                          (match_operand:TF 4 "register_operand" "0,e")))]
3313   "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
3314   "#"
3315   "&& reload_completed"
3316   [(clobber (const_int 0))]
3318   rtx set_dest = operands[0];
3319   rtx set_srca = operands[3];
3320   rtx set_srcb = operands[4];
3321   int third = rtx_equal_p (set_dest, set_srca);
3322   rtx dest1, dest2;
3323   rtx srca1, srca2, srcb1, srcb2;
3325   dest1 = gen_df_reg (set_dest, 0);
3326   dest2 = gen_df_reg (set_dest, 1);
3327   srca1 = gen_df_reg (set_srca, 0);
3328   srca2 = gen_df_reg (set_srca, 1);
3329   srcb1 = gen_df_reg (set_srcb, 0);
3330   srcb2 = gen_df_reg (set_srcb, 1);
3332   /* Now emit using the real source and destination we found, swapping
3333      the order if we detect overlap.  */
3334   if ((third && reg_overlap_mentioned_p (dest1, srcb2))
3335       || (!third && reg_overlap_mentioned_p (dest1, srca2)))
3336     {
3337       emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3338       emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3339     }
3340   else
3341     {
3342       emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3343       emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3344     }
3345   DONE;
3347   [(set_attr "length" "2")])
3349 (define_insn "*movqi_cc_reg_sp64"
3350   [(set (match_operand:QI 0 "register_operand" "=r,r")
3351         (if_then_else:QI (match_operator 1 "v9_register_compare_operator"
3352                                 [(match_operand:DI 2 "register_operand" "r,r")
3353                                  (const_int 0)])
3354                          (match_operand:QI 3 "arith10_operand" "rM,0")
3355                          (match_operand:QI 4 "arith10_operand" "0,rM")))]
3356   "TARGET_ARCH64"
3357   "@
3358    movr%D1\t%2, %r3, %0
3359    movr%d1\t%2, %r4, %0"
3360   [(set_attr "type" "cmove")])
3362 (define_insn "*movhi_cc_reg_sp64"
3363   [(set (match_operand:HI 0 "register_operand" "=r,r")
3364         (if_then_else:HI (match_operator 1 "v9_register_compare_operator"
3365                                 [(match_operand:DI 2 "register_operand" "r,r")
3366                                  (const_int 0)])
3367                          (match_operand:HI 3 "arith10_operand" "rM,0")
3368                          (match_operand:HI 4 "arith10_operand" "0,rM")))]
3369   "TARGET_ARCH64"
3370   "@
3371    movr%D1\t%2, %r3, %0
3372    movr%d1\t%2, %r4, %0"
3373   [(set_attr "type" "cmove")])
3375 (define_insn "*movsi_cc_reg_sp64"
3376   [(set (match_operand:SI 0 "register_operand" "=r,r")
3377         (if_then_else:SI (match_operator 1 "v9_register_compare_operator"
3378                                 [(match_operand:DI 2 "register_operand" "r,r")
3379                                  (const_int 0)])
3380                          (match_operand:SI 3 "arith10_operand" "rM,0")
3381                          (match_operand:SI 4 "arith10_operand" "0,rM")))]
3382   "TARGET_ARCH64"
3383   "@
3384    movr%D1\t%2, %r3, %0
3385    movr%d1\t%2, %r4, %0"
3386   [(set_attr "type" "cmove")])
3388 (define_insn "*movdi_cc_reg_sp64"
3389   [(set (match_operand:DI 0 "register_operand" "=r,r")
3390         (if_then_else:DI (match_operator 1 "v9_register_compare_operator"
3391                                 [(match_operand:DI 2 "register_operand" "r,r")
3392                                  (const_int 0)])
3393                          (match_operand:DI 3 "arith10_operand" "rM,0")
3394                          (match_operand:DI 4 "arith10_operand" "0,rM")))]
3395   "TARGET_ARCH64"
3396   "@
3397    movr%D1\t%2, %r3, %0
3398    movr%d1\t%2, %r4, %0"
3399   [(set_attr "type" "cmove")])
3401 (define_insn "*movsf_cc_reg_sp64"
3402   [(set (match_operand:SF 0 "register_operand" "=f,f")
3403         (if_then_else:SF (match_operator 1 "v9_register_compare_operator"
3404                                 [(match_operand:DI 2 "register_operand" "r,r")
3405                                  (const_int 0)])
3406                          (match_operand:SF 3 "register_operand" "f,0")
3407                          (match_operand:SF 4 "register_operand" "0,f")))]
3408   "TARGET_ARCH64 && TARGET_FPU"
3409   "@
3410    fmovrs%D1\t%2, %3, %0
3411    fmovrs%d1\t%2, %4, %0"
3412   [(set_attr "type" "fpcrmove")])
3414 (define_insn "movdf_cc_reg_sp64"
3415   [(set (match_operand:DF 0 "register_operand" "=e,e")
3416         (if_then_else:DF (match_operator 1 "v9_register_compare_operator"
3417                                 [(match_operand:DI 2 "register_operand" "r,r")
3418                                  (const_int 0)])
3419                          (match_operand:DF 3 "register_operand" "e,0")
3420                          (match_operand:DF 4 "register_operand" "0,e")))]
3421   "TARGET_ARCH64 && TARGET_FPU"
3422   "@
3423    fmovrd%D1\t%2, %3, %0
3424    fmovrd%d1\t%2, %4, %0"
3425   [(set_attr "type" "fpcrmove")
3426    (set_attr "fptype" "double")])
3428 (define_insn "*movtf_cc_reg_hq_sp64"
3429   [(set (match_operand:TF 0 "register_operand" "=e,e")
3430         (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
3431                                 [(match_operand:DI 2 "register_operand" "r,r")
3432                                  (const_int 0)])
3433                          (match_operand:TF 3 "register_operand" "e,0")
3434                          (match_operand:TF 4 "register_operand" "0,e")))]
3435   "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
3436   "@
3437    fmovrq%D1\t%2, %3, %0
3438    fmovrq%d1\t%2, %4, %0"
3439   [(set_attr "type" "fpcrmove")])
3441 (define_insn_and_split "*movtf_cc_reg_sp64"
3442   [(set (match_operand:TF 0 "register_operand" "=e,e")
3443         (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
3444                                 [(match_operand:DI 2 "register_operand" "r,r")
3445                                  (const_int 0)])
3446                          (match_operand:TF 3 "register_operand" "e,0")
3447                          (match_operand:TF 4 "register_operand" "0,e")))]
3448   "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
3449   "#"
3450   "&& reload_completed"
3451   [(clobber (const_int 0))]
3453   rtx set_dest = operands[0];
3454   rtx set_srca = operands[3];
3455   rtx set_srcb = operands[4];
3456   int third = rtx_equal_p (set_dest, set_srca);
3457   rtx dest1, dest2;
3458   rtx srca1, srca2, srcb1, srcb2;
3460   dest1 = gen_df_reg (set_dest, 0);
3461   dest2 = gen_df_reg (set_dest, 1);
3462   srca1 = gen_df_reg (set_srca, 0);
3463   srca2 = gen_df_reg (set_srca, 1);
3464   srcb1 = gen_df_reg (set_srcb, 0);
3465   srcb2 = gen_df_reg (set_srcb, 1);
3467   /* Now emit using the real source and destination we found, swapping
3468      the order if we detect overlap.  */
3469   if ((third && reg_overlap_mentioned_p (dest1, srcb2))
3470       || (!third && reg_overlap_mentioned_p (dest1, srca2)))
3471     {
3472       emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3473       emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3474     }
3475   else
3476     {
3477       emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3478       emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3479     }
3480   DONE;
3482   [(set_attr "length" "2")])
3485 ;; Zero-extension instructions
3487 ;; These patterns originally accepted general_operands, however, slightly
3488 ;; better code is generated by only accepting register_operands, and then
3489 ;; letting combine generate the ldu[hb] insns.
3491 (define_expand "zero_extendhisi2"
3492   [(set (match_operand:SI 0 "register_operand" "")
3493         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
3494   ""
3496   rtx temp = gen_reg_rtx (SImode);
3497   rtx shift_16 = GEN_INT (16);
3498   int op1_subbyte = 0;
3500   if (GET_CODE (operand1) == SUBREG)
3501     {
3502       op1_subbyte = SUBREG_BYTE (operand1);
3503       op1_subbyte /= GET_MODE_SIZE (SImode);
3504       op1_subbyte *= GET_MODE_SIZE (SImode);
3505       operand1 = XEXP (operand1, 0);
3506     }
3508   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3509                           shift_16));
3510   emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
3511   DONE;
3514 (define_insn "*zero_extendhisi2_insn"
3515   [(set (match_operand:SI 0 "register_operand" "=r")
3516         (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3517   ""
3518   "lduh\t%1, %0"
3519   [(set_attr "type" "load")
3520    (set_attr "us3load_type" "3cycle")])
3522 (define_expand "zero_extendqihi2"
3523   [(set (match_operand:HI 0 "register_operand" "")
3524         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
3525   ""
3526   "")
3528 (define_insn "*zero_extendqihi2_insn"
3529   [(set (match_operand:HI 0 "register_operand" "=r,r")
3530         (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
3531   "GET_CODE (operands[1]) != CONST_INT"
3532   "@
3533    and\t%1, 0xff, %0
3534    ldub\t%1, %0"
3535   [(set_attr "type" "*,load")
3536    (set_attr "us3load_type" "*,3cycle")])
3538 (define_expand "zero_extendqisi2"
3539   [(set (match_operand:SI 0 "register_operand" "")
3540         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
3541   ""
3542   "")
3544 (define_insn "*zero_extendqisi2_insn"
3545   [(set (match_operand:SI 0 "register_operand" "=r,r")
3546         (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
3547   "GET_CODE (operands[1]) != CONST_INT"
3548   "@
3549    and\t%1, 0xff, %0
3550    ldub\t%1, %0"
3551   [(set_attr "type" "*,load")
3552    (set_attr "us3load_type" "*,3cycle")])
3554 (define_expand "zero_extendqidi2"
3555   [(set (match_operand:DI 0 "register_operand" "")
3556         (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
3557   "TARGET_ARCH64"
3558   "")
3560 (define_insn "*zero_extendqidi2_insn"
3561   [(set (match_operand:DI 0 "register_operand" "=r,r")
3562         (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
3563   "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
3564   "@
3565    and\t%1, 0xff, %0
3566    ldub\t%1, %0"
3567   [(set_attr "type" "*,load")
3568    (set_attr "us3load_type" "*,3cycle")])
3570 (define_expand "zero_extendhidi2"
3571   [(set (match_operand:DI 0 "register_operand" "")
3572         (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
3573   "TARGET_ARCH64"
3575   rtx temp = gen_reg_rtx (DImode);
3576   rtx shift_48 = GEN_INT (48);
3577   int op1_subbyte = 0;
3579   if (GET_CODE (operand1) == SUBREG)
3580     {
3581       op1_subbyte = SUBREG_BYTE (operand1);
3582       op1_subbyte /= GET_MODE_SIZE (DImode);
3583       op1_subbyte *= GET_MODE_SIZE (DImode);
3584       operand1 = XEXP (operand1, 0);
3585     }
3587   emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3588                           shift_48));
3589   emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
3590   DONE;
3593 (define_insn "*zero_extendhidi2_insn"
3594   [(set (match_operand:DI 0 "register_operand" "=r")
3595         (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3596   "TARGET_ARCH64"
3597   "lduh\t%1, %0"
3598   [(set_attr "type" "load")
3599    (set_attr "us3load_type" "3cycle")])
3601 ;; ??? Write truncdisi pattern using sra?
3603 (define_expand "zero_extendsidi2"
3604   [(set (match_operand:DI 0 "register_operand" "")
3605         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
3606   ""
3607   "")
3609 (define_insn "*zero_extendsidi2_insn_sp64"
3610   [(set (match_operand:DI 0 "register_operand" "=r,r")
3611         (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
3612   "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
3613   "@
3614    srl\t%1, 0, %0
3615    lduw\t%1, %0"
3616   [(set_attr "type" "shift,load")])
3618 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
3619   [(set (match_operand:DI 0 "register_operand" "=r")
3620         (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
3621   "! TARGET_ARCH64"
3622   "#"
3623   "&& reload_completed"
3624   [(set (match_dup 2) (match_dup 3))
3625    (set (match_dup 4) (match_dup 5))]
3627   rtx dest1, dest2;
3629   dest1 = gen_highpart (SImode, operands[0]);
3630   dest2 = gen_lowpart (SImode, operands[0]);
3632   /* Swap the order in case of overlap.  */
3633   if (REGNO (dest1) == REGNO (operands[1]))
3634     {
3635       operands[2] = dest2;
3636       operands[3] = operands[1];
3637       operands[4] = dest1;
3638       operands[5] = const0_rtx;
3639     }
3640   else
3641     {
3642       operands[2] = dest1;
3643       operands[3] = const0_rtx;
3644       operands[4] = dest2;
3645       operands[5] = operands[1];
3646     }
3648   [(set_attr "length" "2")])
3650 ;; Simplify comparisons of extended values.
3652 (define_insn "*cmp_zero_extendqisi2"
3653   [(set (reg:CC 100)
3654         (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
3655                     (const_int 0)))]
3656   ""
3657   "andcc\t%0, 0xff, %%g0"
3658   [(set_attr "type" "compare")])
3660 (define_insn "*cmp_zero_qi"
3661   [(set (reg:CC 100)
3662         (compare:CC (match_operand:QI 0 "register_operand" "r")
3663                     (const_int 0)))]
3664   ""
3665   "andcc\t%0, 0xff, %%g0"
3666   [(set_attr "type" "compare")])
3668 (define_insn "*cmp_zero_extendqisi2_set"
3669   [(set (reg:CC 100)
3670         (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
3671                     (const_int 0)))
3672    (set (match_operand:SI 0 "register_operand" "=r")
3673         (zero_extend:SI (match_dup 1)))]
3674   ""
3675   "andcc\t%1, 0xff, %0"
3676   [(set_attr "type" "compare")])
3678 (define_insn "*cmp_zero_extendqisi2_andcc_set"
3679   [(set (reg:CC 100)
3680         (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
3681                             (const_int 255))
3682                     (const_int 0)))
3683    (set (match_operand:SI 0 "register_operand" "=r")
3684         (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
3685   ""
3686   "andcc\t%1, 0xff, %0"
3687   [(set_attr "type" "compare")])
3689 (define_insn "*cmp_zero_extendqidi2"
3690   [(set (reg:CCX 100)
3691         (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
3692                      (const_int 0)))]
3693   "TARGET_ARCH64"
3694   "andcc\t%0, 0xff, %%g0"
3695   [(set_attr "type" "compare")])
3697 (define_insn "*cmp_zero_qi_sp64"
3698   [(set (reg:CCX 100)
3699         (compare:CCX (match_operand:QI 0 "register_operand" "r")
3700                      (const_int 0)))]
3701   "TARGET_ARCH64"
3702   "andcc\t%0, 0xff, %%g0"
3703   [(set_attr "type" "compare")])
3705 (define_insn "*cmp_zero_extendqidi2_set"
3706   [(set (reg:CCX 100)
3707         (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
3708                      (const_int 0)))
3709    (set (match_operand:DI 0 "register_operand" "=r")
3710         (zero_extend:DI (match_dup 1)))]
3711   "TARGET_ARCH64"
3712   "andcc\t%1, 0xff, %0"
3713   [(set_attr "type" "compare")])
3715 (define_insn "*cmp_zero_extendqidi2_andcc_set"
3716   [(set (reg:CCX 100)
3717         (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
3718                              (const_int 255))
3719                      (const_int 0)))
3720    (set (match_operand:DI 0 "register_operand" "=r")
3721         (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
3722   "TARGET_ARCH64"
3723   "andcc\t%1, 0xff, %0"
3724   [(set_attr "type" "compare")])
3726 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
3728 (define_insn "*cmp_siqi_trunc"
3729   [(set (reg:CC 100)
3730         (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
3731                     (const_int 0)))]
3732   ""
3733   "andcc\t%0, 0xff, %%g0"
3734   [(set_attr "type" "compare")])
3736 (define_insn "*cmp_siqi_trunc_set"
3737   [(set (reg:CC 100)
3738         (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
3739                     (const_int 0)))
3740    (set (match_operand:QI 0 "register_operand" "=r")
3741         (subreg:QI (match_dup 1) 3))]
3742   ""
3743   "andcc\t%1, 0xff, %0"
3744   [(set_attr "type" "compare")])
3746 (define_insn "*cmp_diqi_trunc"
3747   [(set (reg:CC 100)
3748         (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
3749                     (const_int 0)))]
3750   "TARGET_ARCH64"
3751   "andcc\t%0, 0xff, %%g0"
3752   [(set_attr "type" "compare")])
3754 (define_insn "*cmp_diqi_trunc_set"
3755   [(set (reg:CC 100)
3756         (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
3757                     (const_int 0)))
3758    (set (match_operand:QI 0 "register_operand" "=r")
3759         (subreg:QI (match_dup 1) 7))]
3760   "TARGET_ARCH64"
3761   "andcc\t%1, 0xff, %0"
3762   [(set_attr "type" "compare")])
3765 ;; Sign-extension instructions
3767 ;; These patterns originally accepted general_operands, however, slightly
3768 ;; better code is generated by only accepting register_operands, and then
3769 ;; letting combine generate the lds[hb] insns.
3771 (define_expand "extendhisi2"
3772   [(set (match_operand:SI 0 "register_operand" "")
3773         (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
3774   ""
3776   rtx temp = gen_reg_rtx (SImode);
3777   rtx shift_16 = GEN_INT (16);
3778   int op1_subbyte = 0;
3780   if (GET_CODE (operand1) == SUBREG)
3781     {
3782       op1_subbyte = SUBREG_BYTE (operand1);
3783       op1_subbyte /= GET_MODE_SIZE (SImode);
3784       op1_subbyte *= GET_MODE_SIZE (SImode);
3785       operand1 = XEXP (operand1, 0);
3786     }
3788   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3789                           shift_16));
3790   emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
3791   DONE;
3794 (define_insn "*sign_extendhisi2_insn"
3795   [(set (match_operand:SI 0 "register_operand" "=r")
3796         (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3797   ""
3798   "ldsh\t%1, %0"
3799   [(set_attr "type" "sload")
3800    (set_attr "us3load_type" "3cycle")])
3802 (define_expand "extendqihi2"
3803   [(set (match_operand:HI 0 "register_operand" "")
3804         (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
3805   ""
3807   rtx temp = gen_reg_rtx (SImode);
3808   rtx shift_24 = GEN_INT (24);
3809   int op1_subbyte = 0;
3810   int op0_subbyte = 0;
3812   if (GET_CODE (operand1) == SUBREG)
3813     {
3814       op1_subbyte = SUBREG_BYTE (operand1);
3815       op1_subbyte /= GET_MODE_SIZE (SImode);
3816       op1_subbyte *= GET_MODE_SIZE (SImode);
3817       operand1 = XEXP (operand1, 0);
3818     }
3819   if (GET_CODE (operand0) == SUBREG)
3820     {
3821       op0_subbyte = SUBREG_BYTE (operand0);
3822       op0_subbyte /= GET_MODE_SIZE (SImode);
3823       op0_subbyte *= GET_MODE_SIZE (SImode);
3824       operand0 = XEXP (operand0, 0);
3825     }
3826   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3827                           shift_24));
3828   if (GET_MODE (operand0) != SImode)
3829     operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
3830   emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3831   DONE;
3834 (define_insn "*sign_extendqihi2_insn"
3835   [(set (match_operand:HI 0 "register_operand" "=r")
3836         (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3837   ""
3838   "ldsb\t%1, %0"
3839   [(set_attr "type" "sload")
3840    (set_attr "us3load_type" "3cycle")])
3842 (define_expand "extendqisi2"
3843   [(set (match_operand:SI 0 "register_operand" "")
3844         (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
3845   ""
3847   rtx temp = gen_reg_rtx (SImode);
3848   rtx shift_24 = GEN_INT (24);
3849   int op1_subbyte = 0;
3851   if (GET_CODE (operand1) == SUBREG)
3852     {
3853       op1_subbyte = SUBREG_BYTE (operand1);
3854       op1_subbyte /= GET_MODE_SIZE (SImode);
3855       op1_subbyte *= GET_MODE_SIZE (SImode);
3856       operand1 = XEXP (operand1, 0);
3857     }
3859   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3860                           shift_24));
3861   emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3862   DONE;
3865 (define_insn "*sign_extendqisi2_insn"
3866   [(set (match_operand:SI 0 "register_operand" "=r")
3867         (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3868   ""
3869   "ldsb\t%1, %0"
3870   [(set_attr "type" "sload")
3871    (set_attr "us3load_type" "3cycle")])
3873 (define_expand "extendqidi2"
3874   [(set (match_operand:DI 0 "register_operand" "")
3875         (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
3876   "TARGET_ARCH64"
3878   rtx temp = gen_reg_rtx (DImode);
3879   rtx shift_56 = GEN_INT (56);
3880   int op1_subbyte = 0;
3882   if (GET_CODE (operand1) == SUBREG)
3883     {
3884       op1_subbyte = SUBREG_BYTE (operand1);
3885       op1_subbyte /= GET_MODE_SIZE (DImode);
3886       op1_subbyte *= GET_MODE_SIZE (DImode);
3887       operand1 = XEXP (operand1, 0);
3888     }
3890   emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3891                           shift_56));
3892   emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
3893   DONE;
3896 (define_insn "*sign_extendqidi2_insn"
3897   [(set (match_operand:DI 0 "register_operand" "=r")
3898         (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3899   "TARGET_ARCH64"
3900   "ldsb\t%1, %0"
3901   [(set_attr "type" "sload")
3902    (set_attr "us3load_type" "3cycle")])
3904 (define_expand "extendhidi2"
3905   [(set (match_operand:DI 0 "register_operand" "")
3906         (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
3907   "TARGET_ARCH64"
3909   rtx temp = gen_reg_rtx (DImode);
3910   rtx shift_48 = GEN_INT (48);
3911   int op1_subbyte = 0;
3913   if (GET_CODE (operand1) == SUBREG)
3914     {
3915       op1_subbyte = SUBREG_BYTE (operand1);
3916       op1_subbyte /= GET_MODE_SIZE (DImode);
3917       op1_subbyte *= GET_MODE_SIZE (DImode);
3918       operand1 = XEXP (operand1, 0);
3919     }
3921   emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3922                           shift_48));
3923   emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
3924   DONE;
3927 (define_insn "*sign_extendhidi2_insn"
3928   [(set (match_operand:DI 0 "register_operand" "=r")
3929         (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3930   "TARGET_ARCH64"
3931   "ldsh\t%1, %0"
3932   [(set_attr "type" "sload")
3933    (set_attr "us3load_type" "3cycle")])
3935 (define_expand "extendsidi2"
3936   [(set (match_operand:DI 0 "register_operand" "")
3937         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3938   "TARGET_ARCH64"
3939   "")
3941 (define_insn "*sign_extendsidi2_insn"
3942   [(set (match_operand:DI 0 "register_operand" "=r,r")
3943         (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
3944   "TARGET_ARCH64"
3945   "@
3946   sra\t%1, 0, %0
3947   ldsw\t%1, %0"
3948   [(set_attr "type" "shift,sload")
3949    (set_attr "us3load_type" "*,3cycle")])
3952 ;; Special pattern for optimizing bit-field compares.  This is needed
3953 ;; because combine uses this as a canonical form.
3955 (define_insn "*cmp_zero_extract"
3956   [(set (reg:CC 100)
3957         (compare:CC
3958          (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
3959                           (match_operand:SI 1 "small_int_operand" "I")
3960                           (match_operand:SI 2 "small_int_operand" "I"))
3961          (const_int 0)))]
3962   "INTVAL (operands[2]) > 19"
3964   int len = INTVAL (operands[1]);
3965   int pos = 32 - INTVAL (operands[2]) - len;
3966   HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
3967   operands[1] = GEN_INT (mask);
3968   return "andcc\t%0, %1, %%g0";
3970   [(set_attr "type" "compare")])
3972 (define_insn "*cmp_zero_extract_sp64"
3973   [(set (reg:CCX 100)
3974         (compare:CCX
3975          (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
3976                           (match_operand:SI 1 "small_int_operand" "I")
3977                           (match_operand:SI 2 "small_int_operand" "I"))
3978          (const_int 0)))]
3979   "TARGET_ARCH64 && INTVAL (operands[2]) > 51"
3981   int len = INTVAL (operands[1]);
3982   int pos = 64 - INTVAL (operands[2]) - len;
3983   HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
3984   operands[1] = GEN_INT (mask);
3985   return "andcc\t%0, %1, %%g0";
3987   [(set_attr "type" "compare")])
3990 ;; Conversions between float, double and long double.
3992 (define_insn "extendsfdf2"
3993   [(set (match_operand:DF 0 "register_operand" "=e")
3994         (float_extend:DF
3995          (match_operand:SF 1 "register_operand" "f")))]
3996   "TARGET_FPU"
3997   "fstod\t%1, %0"
3998   [(set_attr "type" "fp")
3999    (set_attr "fptype" "double")])
4001 (define_expand "extendsftf2"
4002   [(set (match_operand:TF 0 "nonimmediate_operand" "")
4003         (float_extend:TF
4004          (match_operand:SF 1 "register_operand" "")))]
4005   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4006   "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4008 (define_insn "*extendsftf2_hq"
4009   [(set (match_operand:TF 0 "register_operand" "=e")
4010         (float_extend:TF
4011          (match_operand:SF 1 "register_operand" "f")))]
4012   "TARGET_FPU && TARGET_HARD_QUAD"
4013   "fstoq\t%1, %0"
4014   [(set_attr "type" "fp")])
4016 (define_expand "extenddftf2"
4017   [(set (match_operand:TF 0 "nonimmediate_operand" "")
4018         (float_extend:TF
4019          (match_operand:DF 1 "register_operand" "")))]
4020   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4021   "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4023 (define_insn "*extenddftf2_hq"
4024   [(set (match_operand:TF 0 "register_operand" "=e")
4025         (float_extend:TF
4026          (match_operand:DF 1 "register_operand" "e")))]
4027   "TARGET_FPU && TARGET_HARD_QUAD"
4028   "fdtoq\t%1, %0"
4029   [(set_attr "type" "fp")])
4031 (define_insn "truncdfsf2"
4032   [(set (match_operand:SF 0 "register_operand" "=f")
4033         (float_truncate:SF
4034          (match_operand:DF 1 "register_operand" "e")))]
4035   "TARGET_FPU"
4036   "fdtos\t%1, %0"
4037   [(set_attr "type" "fp")
4038    (set_attr "fptype" "double")])
4040 (define_expand "trunctfsf2"
4041   [(set (match_operand:SF 0 "register_operand" "")
4042         (float_truncate:SF
4043          (match_operand:TF 1 "general_operand" "")))]
4044   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4045   "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4047 (define_insn "*trunctfsf2_hq"
4048   [(set (match_operand:SF 0 "register_operand" "=f")
4049         (float_truncate:SF
4050          (match_operand:TF 1 "register_operand" "e")))]
4051   "TARGET_FPU && TARGET_HARD_QUAD"
4052   "fqtos\t%1, %0"
4053   [(set_attr "type" "fp")])
4055 (define_expand "trunctfdf2"
4056   [(set (match_operand:DF 0 "register_operand" "")
4057         (float_truncate:DF
4058          (match_operand:TF 1 "general_operand" "")))]
4059   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4060   "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4062 (define_insn "*trunctfdf2_hq"
4063   [(set (match_operand:DF 0 "register_operand" "=e")
4064         (float_truncate:DF
4065          (match_operand:TF 1 "register_operand" "e")))]
4066   "TARGET_FPU && TARGET_HARD_QUAD"
4067   "fqtod\t%1, %0"
4068   [(set_attr "type" "fp")])
4071 ;; Conversion between fixed point and floating point.
4073 (define_insn "floatsisf2"
4074   [(set (match_operand:SF 0 "register_operand" "=f")
4075         (float:SF (match_operand:SI 1 "register_operand" "f")))]
4076   "TARGET_FPU"
4077   "fitos\t%1, %0"
4078   [(set_attr "type" "fp")
4079    (set_attr "fptype" "double")])
4081 (define_insn "floatsidf2"
4082   [(set (match_operand:DF 0 "register_operand" "=e")
4083         (float:DF (match_operand:SI 1 "register_operand" "f")))]
4084   "TARGET_FPU"
4085   "fitod\t%1, %0"
4086   [(set_attr "type" "fp")
4087    (set_attr "fptype" "double")])
4089 (define_expand "floatsitf2"
4090   [(set (match_operand:TF 0 "nonimmediate_operand" "")
4091         (float:TF (match_operand:SI 1 "register_operand" "")))]
4092   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4093   "emit_tfmode_cvt (FLOAT, operands); DONE;")
4095 (define_insn "*floatsitf2_hq"
4096   [(set (match_operand:TF 0 "register_operand" "=e")
4097         (float:TF (match_operand:SI 1 "register_operand" "f")))]
4098   "TARGET_FPU && TARGET_HARD_QUAD"
4099   "fitoq\t%1, %0"
4100   [(set_attr "type" "fp")])
4102 (define_expand "floatunssitf2"
4103   [(set (match_operand:TF 0 "nonimmediate_operand" "")
4104         (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
4105   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4106   "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4108 ;; Now the same for 64 bit sources.
4110 (define_insn "floatdisf2"
4111   [(set (match_operand:SF 0 "register_operand" "=f")
4112         (float:SF (match_operand:DI 1 "register_operand" "e")))]
4113   "TARGET_V9 && TARGET_FPU"
4114   "fxtos\t%1, %0"
4115   [(set_attr "type" "fp")
4116    (set_attr "fptype" "double")])
4118 (define_expand "floatunsdisf2"
4119   [(use (match_operand:SF 0 "register_operand" ""))
4120    (use (match_operand:DI 1 "general_operand" ""))]
4121   "TARGET_ARCH64 && TARGET_FPU"
4122   "sparc_emit_floatunsdi (operands, SFmode); DONE;")
4124 (define_insn "floatdidf2"
4125   [(set (match_operand:DF 0 "register_operand" "=e")
4126         (float:DF (match_operand:DI 1 "register_operand" "e")))]
4127   "TARGET_V9 && TARGET_FPU"
4128   "fxtod\t%1, %0"
4129   [(set_attr "type" "fp")
4130    (set_attr "fptype" "double")])
4132 (define_expand "floatunsdidf2"
4133   [(use (match_operand:DF 0 "register_operand" ""))
4134    (use (match_operand:DI 1 "general_operand" ""))]
4135   "TARGET_ARCH64 && TARGET_FPU"
4136   "sparc_emit_floatunsdi (operands, DFmode); DONE;")
4138 (define_expand "floatditf2"
4139   [(set (match_operand:TF 0 "nonimmediate_operand" "")
4140         (float:TF (match_operand:DI 1 "register_operand" "")))]
4141   "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4142   "emit_tfmode_cvt (FLOAT, operands); DONE;")
4144 (define_insn "*floatditf2_hq"
4145   [(set (match_operand:TF 0 "register_operand" "=e")
4146         (float:TF (match_operand:DI 1 "register_operand" "e")))]
4147   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4148   "fxtoq\t%1, %0"
4149   [(set_attr "type" "fp")])
4151 (define_expand "floatunsditf2"
4152   [(set (match_operand:TF 0 "nonimmediate_operand" "")
4153         (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
4154   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4155   "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4157 ;; Convert a float to an actual integer.
4158 ;; Truncation is performed as part of the conversion.
4160 (define_insn "fix_truncsfsi2"
4161   [(set (match_operand:SI 0 "register_operand" "=f")
4162         (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4163   "TARGET_FPU"
4164   "fstoi\t%1, %0"
4165   [(set_attr "type" "fp")
4166    (set_attr "fptype" "double")])
4168 (define_insn "fix_truncdfsi2"
4169   [(set (match_operand:SI 0 "register_operand" "=f")
4170         (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4171   "TARGET_FPU"
4172   "fdtoi\t%1, %0"
4173   [(set_attr "type" "fp")
4174    (set_attr "fptype" "double")])
4176 (define_expand "fix_trunctfsi2"
4177   [(set (match_operand:SI 0 "register_operand" "")
4178         (fix:SI (match_operand:TF 1 "general_operand" "")))]
4179   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4180   "emit_tfmode_cvt (FIX, operands); DONE;")
4182 (define_insn "*fix_trunctfsi2_hq"
4183   [(set (match_operand:SI 0 "register_operand" "=f")
4184         (fix:SI (match_operand:TF 1 "register_operand" "e")))]
4185   "TARGET_FPU && TARGET_HARD_QUAD"
4186   "fqtoi\t%1, %0"
4187   [(set_attr "type" "fp")])
4189 (define_expand "fixuns_trunctfsi2"
4190   [(set (match_operand:SI 0 "register_operand" "")
4191         (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
4192   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4193   "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4195 ;; Now the same, for V9 targets
4197 (define_insn "fix_truncsfdi2"
4198   [(set (match_operand:DI 0 "register_operand" "=e")
4199         (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4200   "TARGET_V9 && TARGET_FPU"
4201   "fstox\t%1, %0"
4202   [(set_attr "type" "fp")
4203    (set_attr "fptype" "double")])
4205 (define_expand "fixuns_truncsfdi2"
4206   [(use (match_operand:DI 0 "register_operand" ""))
4207    (use (match_operand:SF 1 "general_operand" ""))]
4208   "TARGET_ARCH64 && TARGET_FPU"
4209   "sparc_emit_fixunsdi (operands, SFmode); DONE;")
4211 (define_insn "fix_truncdfdi2"
4212   [(set (match_operand:DI 0 "register_operand" "=e")
4213         (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4214   "TARGET_V9 && TARGET_FPU"
4215   "fdtox\t%1, %0"
4216   [(set_attr "type" "fp")
4217    (set_attr "fptype" "double")])
4219 (define_expand "fixuns_truncdfdi2"
4220   [(use (match_operand:DI 0 "register_operand" ""))
4221    (use (match_operand:DF 1 "general_operand" ""))]
4222   "TARGET_ARCH64 && TARGET_FPU"
4223   "sparc_emit_fixunsdi (operands, DFmode); DONE;")
4225 (define_expand "fix_trunctfdi2"
4226   [(set (match_operand:DI 0 "register_operand" "")
4227         (fix:DI (match_operand:TF 1 "general_operand" "")))]
4228   "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4229   "emit_tfmode_cvt (FIX, operands); DONE;")
4231 (define_insn "*fix_trunctfdi2_hq"
4232   [(set (match_operand:DI 0 "register_operand" "=e")
4233         (fix:DI (match_operand:TF 1 "register_operand" "e")))]
4234   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4235   "fqtox\t%1, %0"
4236   [(set_attr "type" "fp")])
4238 (define_expand "fixuns_trunctfdi2"
4239   [(set (match_operand:DI 0 "register_operand" "")
4240         (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
4241   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4242   "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4245 ;; Integer addition/subtraction instructions.
4247 (define_expand "adddi3"
4248   [(set (match_operand:DI 0 "register_operand" "")
4249         (plus:DI (match_operand:DI 1 "register_operand" "")
4250                  (match_operand:DI 2 "arith_double_add_operand" "")))]
4251   ""
4253   if (! TARGET_ARCH64)
4254     {
4255       emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4256                           gen_rtx_SET (VOIDmode, operands[0],
4257                                    gen_rtx_PLUS (DImode, operands[1],
4258                                                  operands[2])),
4259                           gen_rtx_CLOBBER (VOIDmode,
4260                                    gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4261       DONE;
4262     }
4265 (define_insn_and_split "adddi3_insn_sp32"
4266   [(set (match_operand:DI 0 "register_operand" "=r")
4267         (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4268                  (match_operand:DI 2 "arith_double_operand" "rHI")))
4269    (clobber (reg:CC 100))]
4270   "! TARGET_ARCH64"
4271   "#"
4272   "&& reload_completed"
4273   [(parallel [(set (reg:CC_NOOV 100)
4274                    (compare:CC_NOOV (plus:SI (match_dup 4)
4275                                              (match_dup 5))
4276                                     (const_int 0)))
4277               (set (match_dup 3)
4278                    (plus:SI (match_dup 4) (match_dup 5)))])
4279    (set (match_dup 6)
4280         (plus:SI (plus:SI (match_dup 7)
4281                           (match_dup 8))
4282                  (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4284   operands[3] = gen_lowpart (SImode, operands[0]);
4285   operands[4] = gen_lowpart (SImode, operands[1]);
4286   operands[5] = gen_lowpart (SImode, operands[2]);
4287   operands[6] = gen_highpart (SImode, operands[0]);
4288   operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
4289 #if HOST_BITS_PER_WIDE_INT == 32
4290   if (GET_CODE (operands[2]) == CONST_INT)
4291     {
4292       if (INTVAL (operands[2]) < 0)
4293         operands[8] = constm1_rtx;
4294       else
4295         operands[8] = const0_rtx;
4296     }
4297   else
4298 #endif
4299     operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4301   [(set_attr "length" "2")])
4303 ;; LTU here means "carry set"
4304 (define_insn "addx"
4305   [(set (match_operand:SI 0 "register_operand" "=r")
4306         (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4307                           (match_operand:SI 2 "arith_operand" "rI"))
4308                  (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4309   ""
4310   "addx\t%1, %2, %0"
4311   [(set_attr "type" "ialuX")])
4313 (define_insn_and_split "*addx_extend_sp32"
4314   [(set (match_operand:DI 0 "register_operand" "=r")
4315         (zero_extend:DI (plus:SI (plus:SI
4316                                   (match_operand:SI 1 "register_or_zero_operand" "%rJ")
4317                                   (match_operand:SI 2 "arith_operand" "rI"))
4318                                  (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4319   "! TARGET_ARCH64"
4320   "#"
4321   "&& reload_completed"
4322   [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
4323                                (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4324    (set (match_dup 4) (const_int 0))]
4325   "operands[3] = gen_lowpart (SImode, operands[0]);
4326    operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
4327   [(set_attr "length" "2")])
4329 (define_insn "*addx_extend_sp64"
4330   [(set (match_operand:DI 0 "register_operand" "=r")
4331         (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
4332                                           (match_operand:SI 2 "arith_operand" "rI"))
4333                                  (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4334   "TARGET_ARCH64"
4335   "addx\t%r1, %2, %0"
4336   [(set_attr "type" "ialuX")])
4338 (define_insn_and_split ""
4339   [(set (match_operand:DI 0 "register_operand" "=r")
4340         (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4341                  (match_operand:DI 2 "register_operand" "r")))
4342    (clobber (reg:CC 100))]
4343   "! TARGET_ARCH64"
4344   "#"
4345   "&& reload_completed"
4346   [(parallel [(set (reg:CC_NOOV 100)
4347                    (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
4348                                     (const_int 0)))
4349               (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
4350    (set (match_dup 6)
4351         (plus:SI (plus:SI (match_dup 4) (const_int 0))
4352                  (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4353   "operands[3] = gen_lowpart (SImode, operands[2]);
4354    operands[4] = gen_highpart (SImode, operands[2]);
4355    operands[5] = gen_lowpart (SImode, operands[0]);
4356    operands[6] = gen_highpart (SImode, operands[0]);"
4357   [(set_attr "length" "2")])
4359 (define_insn "*adddi3_sp64"
4360   [(set (match_operand:DI 0 "register_operand" "=r,r")
4361         (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
4362                  (match_operand:DI 2 "arith_add_operand" "rI,O")))]
4363   "TARGET_ARCH64"
4364   "@
4365    add\t%1, %2, %0
4366    sub\t%1, -%2, %0")
4368 (define_insn "addsi3"
4369   [(set (match_operand:SI 0 "register_operand" "=r,r,d")
4370         (plus:SI (match_operand:SI 1 "register_operand" "%r,r,d")
4371                  (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
4372   ""
4373   "@
4374    add\t%1, %2, %0
4375    sub\t%1, -%2, %0
4376    fpadd32s\t%1, %2, %0"
4377   [(set_attr "type" "*,*,fga")
4378    (set_attr "fptype" "*,*,single")])
4380 (define_insn "*cmp_cc_plus"
4381   [(set (reg:CC_NOOV 100)
4382         (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
4383                                   (match_operand:SI 1 "arith_operand" "rI"))
4384                          (const_int 0)))]
4385   ""
4386   "addcc\t%0, %1, %%g0"
4387   [(set_attr "type" "compare")])
4389 (define_insn "*cmp_ccx_plus"
4390   [(set (reg:CCX_NOOV 100)
4391         (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_operand" "%r")
4392                                    (match_operand:DI 1 "arith_operand" "rI"))
4393                           (const_int 0)))]
4394   "TARGET_ARCH64"
4395   "addcc\t%0, %1, %%g0"
4396   [(set_attr "type" "compare")])
4398 (define_insn "*cmp_cc_plus_set"
4399   [(set (reg:CC_NOOV 100)
4400         (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4401                                   (match_operand:SI 2 "arith_operand" "rI"))
4402                          (const_int 0)))
4403    (set (match_operand:SI 0 "register_operand" "=r")
4404         (plus:SI (match_dup 1) (match_dup 2)))]
4405   ""
4406   "addcc\t%1, %2, %0"
4407   [(set_attr "type" "compare")])
4409 (define_insn "*cmp_ccx_plus_set"
4410   [(set (reg:CCX_NOOV 100)
4411         (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_operand" "%r")
4412                                    (match_operand:DI 2 "arith_operand" "rI"))
4413                           (const_int 0)))
4414    (set (match_operand:DI 0 "register_operand" "=r")
4415         (plus:DI (match_dup 1) (match_dup 2)))]
4416   "TARGET_ARCH64"
4417   "addcc\t%1, %2, %0"
4418   [(set_attr "type" "compare")])
4420 (define_expand "subdi3"
4421   [(set (match_operand:DI 0 "register_operand" "")
4422         (minus:DI (match_operand:DI 1 "register_operand" "")
4423                   (match_operand:DI 2 "arith_double_add_operand" "")))]
4424   ""
4426   if (! TARGET_ARCH64)
4427     {
4428       emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4429                           gen_rtx_SET (VOIDmode, operands[0],
4430                                    gen_rtx_MINUS (DImode, operands[1],
4431                                                   operands[2])),
4432                           gen_rtx_CLOBBER (VOIDmode,
4433                                    gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4434       DONE;
4435     }
4438 (define_insn_and_split "subdi3_insn_sp32"
4439   [(set (match_operand:DI 0 "register_operand" "=r")
4440         (minus:DI (match_operand:DI 1 "register_operand" "r")
4441                   (match_operand:DI 2 "arith_double_operand" "rHI")))
4442    (clobber (reg:CC 100))]
4443   "! TARGET_ARCH64"
4444   "#"
4445   "&& reload_completed"
4446   [(parallel [(set (reg:CC_NOOV 100)
4447                    (compare:CC_NOOV (minus:SI (match_dup 4)
4448                                               (match_dup 5))
4449                                     (const_int 0)))
4450               (set (match_dup 3)
4451                    (minus:SI (match_dup 4) (match_dup 5)))])
4452    (set (match_dup 6)
4453         (minus:SI (minus:SI (match_dup 7)
4454                             (match_dup 8))
4455                   (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4457   operands[3] = gen_lowpart (SImode, operands[0]);
4458   operands[4] = gen_lowpart (SImode, operands[1]);
4459   operands[5] = gen_lowpart (SImode, operands[2]);
4460   operands[6] = gen_highpart (SImode, operands[0]);
4461   operands[7] = gen_highpart (SImode, operands[1]);
4462 #if HOST_BITS_PER_WIDE_INT == 32
4463   if (GET_CODE (operands[2]) == CONST_INT)
4464     {
4465       if (INTVAL (operands[2]) < 0)
4466         operands[8] = constm1_rtx;
4467       else
4468         operands[8] = const0_rtx;
4469     }
4470   else
4471 #endif
4472     operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4474   [(set_attr "length" "2")])
4476 ;; LTU here means "carry set"
4477 (define_insn "subx"
4478   [(set (match_operand:SI 0 "register_operand" "=r")
4479         (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4480                             (match_operand:SI 2 "arith_operand" "rI"))
4481                   (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4482   ""
4483   "subx\t%r1, %2, %0"
4484   [(set_attr "type" "ialuX")])
4486 (define_insn "*subx_extend_sp64"
4487   [(set (match_operand:DI 0 "register_operand" "=r")
4488         (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4489                                             (match_operand:SI 2 "arith_operand" "rI"))
4490                                   (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4491   "TARGET_ARCH64"
4492   "subx\t%r1, %2, %0"
4493   [(set_attr "type" "ialuX")])
4495 (define_insn_and_split "*subx_extend"
4496   [(set (match_operand:DI 0 "register_operand" "=r")
4497         (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4498                                             (match_operand:SI 2 "arith_operand" "rI"))
4499                                   (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4500   "! TARGET_ARCH64"
4501   "#"
4502   "&& reload_completed"
4503   [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
4504                                 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4505    (set (match_dup 4) (const_int 0))]
4506   "operands[3] = gen_lowpart (SImode, operands[0]);
4507    operands[4] = gen_highpart (SImode, operands[0]);"
4508   [(set_attr "length" "2")])
4510 (define_insn_and_split ""
4511   [(set (match_operand:DI 0 "register_operand" "=r")
4512       (minus:DI (match_operand:DI 1 "register_operand" "r")
4513                 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
4514    (clobber (reg:CC 100))]
4515   "! TARGET_ARCH64"
4516   "#"
4517   "&& reload_completed"
4518   [(parallel [(set (reg:CC_NOOV 100)
4519                    (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
4520                                     (const_int 0)))
4521               (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
4522    (set (match_dup 6)
4523         (minus:SI (minus:SI (match_dup 4) (const_int 0))
4524                   (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4525   "operands[3] = gen_lowpart (SImode, operands[1]);
4526    operands[4] = gen_highpart (SImode, operands[1]);
4527    operands[5] = gen_lowpart (SImode, operands[0]);
4528    operands[6] = gen_highpart (SImode, operands[0]);"
4529   [(set_attr "length" "2")])
4531 (define_insn "*subdi3_sp64"
4532   [(set (match_operand:DI 0 "register_operand" "=r,r")
4533         (minus:DI (match_operand:DI 1 "register_operand" "r,r")
4534                   (match_operand:DI 2 "arith_add_operand" "rI,O")))]
4535   "TARGET_ARCH64"
4536   "@
4537    sub\t%1, %2, %0
4538    add\t%1, -%2, %0")
4540 (define_insn "subsi3"
4541   [(set (match_operand:SI 0 "register_operand" "=r,r,d")
4542         (minus:SI (match_operand:SI 1 "register_operand" "r,r,d")
4543                   (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
4544   ""
4545   "@
4546    sub\t%1, %2, %0
4547    add\t%1, -%2, %0
4548    fpsub32s\t%1, %2, %0"
4549   [(set_attr "type" "*,*,fga")
4550    (set_attr "fptype" "*,*,single")])
4552 (define_insn "*cmp_minus_cc"
4553   [(set (reg:CC_NOOV 100)
4554         (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
4555                                    (match_operand:SI 1 "arith_operand" "rI"))
4556                          (const_int 0)))]
4557   ""
4558   "subcc\t%r0, %1, %%g0"
4559   [(set_attr "type" "compare")])
4561 (define_insn "*cmp_minus_ccx"
4562   [(set (reg:CCX_NOOV 100)
4563         (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
4564                                     (match_operand:DI 1 "arith_operand" "rI"))
4565                           (const_int 0)))]
4566   "TARGET_ARCH64"
4567   "subcc\t%0, %1, %%g0"
4568   [(set_attr "type" "compare")])
4570 (define_insn "cmp_minus_cc_set"
4571   [(set (reg:CC_NOOV 100)
4572         (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4573                                    (match_operand:SI 2 "arith_operand" "rI"))
4574                          (const_int 0)))
4575    (set (match_operand:SI 0 "register_operand" "=r")
4576         (minus:SI (match_dup 1) (match_dup 2)))]
4577   ""
4578   "subcc\t%r1, %2, %0"
4579   [(set_attr "type" "compare")])
4581 (define_insn "*cmp_minus_ccx_set"
4582   [(set (reg:CCX_NOOV 100)
4583         (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
4584                                     (match_operand:DI 2 "arith_operand" "rI"))
4585                           (const_int 0)))
4586    (set (match_operand:DI 0 "register_operand" "=r")
4587         (minus:DI (match_dup 1) (match_dup 2)))]
4588   "TARGET_ARCH64"
4589   "subcc\t%1, %2, %0"
4590   [(set_attr "type" "compare")])
4593 ;; Integer multiply/divide instructions.
4595 ;; The 32 bit multiply/divide instructions are deprecated on v9, but at
4596 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
4598 (define_insn "mulsi3"
4599   [(set (match_operand:SI 0 "register_operand" "=r")
4600         (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4601                  (match_operand:SI 2 "arith_operand" "rI")))]
4602   "TARGET_HARD_MUL"
4603   "smul\t%1, %2, %0"
4604   [(set_attr "type" "imul")])
4606 (define_expand "muldi3"
4607   [(set (match_operand:DI 0 "register_operand" "")
4608         (mult:DI (match_operand:DI 1 "arith_operand" "")
4609                  (match_operand:DI 2 "arith_operand" "")))]
4610   "TARGET_ARCH64 || TARGET_V8PLUS"
4612   if (TARGET_V8PLUS)
4613     {
4614       emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
4615       DONE;
4616     }
4619 (define_insn "*muldi3_sp64"
4620   [(set (match_operand:DI 0 "register_operand" "=r")
4621         (mult:DI (match_operand:DI 1 "arith_operand" "%r")
4622                  (match_operand:DI 2 "arith_operand" "rI")))]
4623   "TARGET_ARCH64"
4624   "mulx\t%1, %2, %0"
4625   [(set_attr "type" "imul")])
4627 ;; V8plus wide multiply.
4628 ;; XXX
4629 (define_insn "muldi3_v8plus"
4630   [(set (match_operand:DI 0 "register_operand" "=r,h")
4631         (mult:DI (match_operand:DI 1 "arith_operand" "%r,0")
4632                  (match_operand:DI 2 "arith_operand" "rI,rI")))
4633    (clobber (match_scratch:SI 3 "=&h,X"))
4634    (clobber (match_scratch:SI 4 "=&h,X"))]
4635   "TARGET_V8PLUS"
4637   if (sparc_check_64 (operands[1], insn) <= 0)
4638     output_asm_insn ("srl\t%L1, 0, %L1", operands);
4639   if (which_alternative == 1)
4640     output_asm_insn ("sllx\t%H1, 32, %H1", operands);
4641   if (GET_CODE (operands[2]) == CONST_INT)
4642     {
4643       if (which_alternative == 1)
4644         return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %2, %L0\;srlx\t%L0, 32, %H0";
4645       else
4646         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";
4647     }
4648   else if (rtx_equal_p (operands[1], operands[2]))
4649     {
4650       if (which_alternative == 1)
4651         return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %H1, %L0\;srlx\t%L0, 32, %H0";
4652       else
4653         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";
4654     }
4655   if (sparc_check_64 (operands[2], insn) <= 0)
4656     output_asm_insn ("srl\t%L2, 0, %L2", operands);
4657   if (which_alternative == 1)
4658     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";
4659   else
4660     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";
4662   [(set_attr "type" "multi")
4663    (set_attr "length" "9,8")])
4665 (define_insn "*cmp_mul_set"
4666   [(set (reg:CC 100)
4667         (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4668                     (match_operand:SI 2 "arith_operand" "rI"))
4669                     (const_int 0)))
4670    (set (match_operand:SI 0 "register_operand" "=r")
4671         (mult:SI (match_dup 1) (match_dup 2)))]
4672   "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
4673   "smulcc\t%1, %2, %0"
4674   [(set_attr "type" "imul")])
4676 (define_expand "mulsidi3"
4677   [(set (match_operand:DI 0 "register_operand" "")
4678         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4679                  (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
4680   "TARGET_HARD_MUL"
4682   if (CONSTANT_P (operands[2]))
4683     {
4684       if (TARGET_V8PLUS)
4685         emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
4686                                               operands[2]));
4687       else if (TARGET_ARCH32)
4688         emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
4689                                             operands[2]));
4690       else 
4691         emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
4692                                             operands[2]));
4693       DONE;
4694     }
4695   if (TARGET_V8PLUS)
4696     {
4697       emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
4698       DONE;
4699     }
4702 ;; V9 puts the 64 bit product in a 64 bit register.  Only out or global
4703 ;; registers can hold 64 bit values in the V8plus environment.
4704 ;; XXX
4705 (define_insn "mulsidi3_v8plus"
4706   [(set (match_operand:DI 0 "register_operand" "=h,r")
4707         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4708                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4709    (clobber (match_scratch:SI 3 "=X,&h"))]
4710   "TARGET_V8PLUS"
4711   "@
4712    smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4713    smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4714   [(set_attr "type" "multi")
4715    (set_attr "length" "2,3")])
4717 ;; XXX
4718 (define_insn "const_mulsidi3_v8plus"
4719   [(set (match_operand:DI 0 "register_operand" "=h,r")
4720         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4721                  (match_operand:DI 2 "small_int_operand" "I,I")))
4722    (clobber (match_scratch:SI 3 "=X,&h"))]
4723   "TARGET_V8PLUS"
4724   "@
4725    smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4726    smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4727   [(set_attr "type" "multi")
4728    (set_attr "length" "2,3")])
4730 ;; XXX
4731 (define_insn "*mulsidi3_sp32"
4732   [(set (match_operand:DI 0 "register_operand" "=r")
4733         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4734                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4735   "TARGET_HARD_MUL32"
4737   return TARGET_SPARCLET
4738          ? "smuld\t%1, %2, %L0"
4739          : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4741   [(set (attr "type")
4742         (if_then_else (eq_attr "isa" "sparclet")
4743                       (const_string "imul") (const_string "multi")))
4744    (set (attr "length")
4745         (if_then_else (eq_attr "isa" "sparclet")
4746                       (const_int 1) (const_int 2)))])
4748 (define_insn "*mulsidi3_sp64"
4749   [(set (match_operand:DI 0 "register_operand" "=r")
4750         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4751                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4752   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4753   "smul\t%1, %2, %0"
4754   [(set_attr "type" "imul")])
4756 ;; Extra pattern, because sign_extend of a constant isn't valid.
4758 ;; XXX
4759 (define_insn "const_mulsidi3_sp32"
4760   [(set (match_operand:DI 0 "register_operand" "=r")
4761         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4762                  (match_operand:DI 2 "small_int_operand" "I")))]
4763   "TARGET_HARD_MUL32"
4765   return TARGET_SPARCLET
4766          ? "smuld\t%1, %2, %L0"
4767          : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4769   [(set (attr "type")
4770         (if_then_else (eq_attr "isa" "sparclet")
4771                       (const_string "imul") (const_string "multi")))
4772    (set (attr "length")
4773         (if_then_else (eq_attr "isa" "sparclet")
4774                       (const_int 1) (const_int 2)))])
4776 (define_insn "const_mulsidi3_sp64"
4777   [(set (match_operand:DI 0 "register_operand" "=r")
4778         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4779                  (match_operand:DI 2 "small_int_operand" "I")))]
4780   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4781   "smul\t%1, %2, %0"
4782   [(set_attr "type" "imul")])
4784 (define_expand "smulsi3_highpart"
4785   [(set (match_operand:SI 0 "register_operand" "")
4786         (truncate:SI
4787          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4788                                (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
4789                       (const_int 32))))]
4790   "TARGET_HARD_MUL && TARGET_ARCH32"
4792   if (CONSTANT_P (operands[2]))
4793     {
4794       if (TARGET_V8PLUS)
4795         {
4796           emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
4797                                                         operands[1],
4798                                                         operands[2],
4799                                                         GEN_INT (32)));
4800           DONE;
4801         }
4802       emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
4803       DONE;
4804     }
4805   if (TARGET_V8PLUS)
4806     {
4807       emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
4808                                               operands[2], GEN_INT (32)));
4809       DONE;
4810     }
4813 ;; XXX
4814 (define_insn "smulsi3_highpart_v8plus"
4815   [(set (match_operand:SI 0 "register_operand" "=h,r")
4816         (truncate:SI
4817          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4818                                (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4819                       (match_operand:SI 3 "small_int_operand" "I,I"))))
4820    (clobber (match_scratch:SI 4 "=X,&h"))]
4821   "TARGET_V8PLUS"
4822   "@
4823    smul\t%1, %2, %0\;srlx\t%0, %3, %0
4824    smul\t%1, %2, %4\;srlx\t%4, %3, %0"
4825   [(set_attr "type" "multi")
4826    (set_attr "length" "2")])
4828 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
4829 ;; XXX
4830 (define_insn ""
4831   [(set (match_operand:SI 0 "register_operand" "=h,r")
4832         (subreg:SI
4833          (lshiftrt:DI
4834           (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4835                    (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4836           (match_operand:SI 3 "small_int_operand" "I,I"))
4837          4))
4838    (clobber (match_scratch:SI 4 "=X,&h"))]
4839   "TARGET_V8PLUS"
4840   "@
4841    smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4842    smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4843   [(set_attr "type" "multi")
4844    (set_attr "length" "2")])
4846 ;; XXX
4847 (define_insn "const_smulsi3_highpart_v8plus"
4848   [(set (match_operand:SI 0 "register_operand" "=h,r")
4849         (truncate:SI
4850          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4851                                (match_operand:DI 2 "small_int_operand" "I,I"))
4852                       (match_operand:SI 3 "small_int_operand" "I,I"))))
4853    (clobber (match_scratch:SI 4 "=X,&h"))]
4854   "TARGET_V8PLUS"
4855   "@
4856    smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4857    smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4858   [(set_attr "type" "multi")
4859    (set_attr "length" "2")])
4861 ;; XXX
4862 (define_insn "*smulsi3_highpart_sp32"
4863   [(set (match_operand:SI 0 "register_operand" "=r")
4864         (truncate:SI
4865          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4866                                (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
4867                       (const_int 32))))]
4868   "TARGET_HARD_MUL32"
4869   "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4870   [(set_attr "type" "multi")
4871    (set_attr "length" "2")])
4873 ;; XXX
4874 (define_insn "const_smulsi3_highpart"
4875   [(set (match_operand:SI 0 "register_operand" "=r")
4876         (truncate:SI
4877          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4878                                (match_operand:DI 2 "small_int_operand" "i"))
4879                       (const_int 32))))]
4880   "TARGET_HARD_MUL32"
4881   "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4882   [(set_attr "type" "multi")
4883    (set_attr "length" "2")])
4885 (define_expand "umulsidi3"
4886   [(set (match_operand:DI 0 "register_operand" "")
4887         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4888                  (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
4889   "TARGET_HARD_MUL"
4891   if (CONSTANT_P (operands[2]))
4892     {
4893       if (TARGET_V8PLUS)
4894         emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
4895                                                operands[2]));
4896       else if (TARGET_ARCH32)
4897         emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
4898                                              operands[2]));
4899       else 
4900         emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
4901                                              operands[2]));
4902       DONE;
4903     }
4904   if (TARGET_V8PLUS)
4905     {
4906       emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
4907       DONE;
4908     }
4911 ;; XXX
4912 (define_insn "umulsidi3_v8plus"
4913   [(set (match_operand:DI 0 "register_operand" "=h,r")
4914         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4915                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4916    (clobber (match_scratch:SI 3 "=X,&h"))]
4917   "TARGET_V8PLUS"
4918   "@
4919    umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4920    umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4921   [(set_attr "type" "multi")
4922    (set_attr "length" "2,3")])
4924 ;; XXX
4925 (define_insn "*umulsidi3_sp32"
4926   [(set (match_operand:DI 0 "register_operand" "=r")
4927         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4928                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4929   "TARGET_HARD_MUL32"
4931   return TARGET_SPARCLET
4932          ? "umuld\t%1, %2, %L0"
4933          : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
4935   [(set (attr "type")
4936         (if_then_else (eq_attr "isa" "sparclet")
4937                       (const_string "imul") (const_string "multi")))
4938    (set (attr "length")
4939         (if_then_else (eq_attr "isa" "sparclet")
4940                       (const_int 1) (const_int 2)))])
4942 (define_insn "*umulsidi3_sp64"
4943   [(set (match_operand:DI 0 "register_operand" "=r")
4944         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4945                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4946   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4947   "umul\t%1, %2, %0"
4948   [(set_attr "type" "imul")])
4950 ;; Extra pattern, because sign_extend of a constant isn't valid.
4952 ;; XXX
4953 (define_insn "const_umulsidi3_sp32"
4954   [(set (match_operand:DI 0 "register_operand" "=r")
4955         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4956                  (match_operand:DI 2 "uns_small_int_operand" "")))]
4957   "TARGET_HARD_MUL32"
4959   return TARGET_SPARCLET
4960          ? "umuld\t%1, %s2, %L0"
4961          : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
4963   [(set (attr "type")
4964         (if_then_else (eq_attr "isa" "sparclet")
4965                       (const_string "imul") (const_string "multi")))
4966    (set (attr "length")
4967         (if_then_else (eq_attr "isa" "sparclet")
4968                       (const_int 1) (const_int 2)))])
4970 (define_insn "const_umulsidi3_sp64"
4971   [(set (match_operand:DI 0 "register_operand" "=r")
4972         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4973                  (match_operand:DI 2 "uns_small_int_operand" "")))]
4974   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4975   "umul\t%1, %s2, %0"
4976   [(set_attr "type" "imul")])
4978 ;; XXX
4979 (define_insn "const_umulsidi3_v8plus"
4980   [(set (match_operand:DI 0 "register_operand" "=h,r")
4981         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4982                  (match_operand:DI 2 "uns_small_int_operand" "")))
4983    (clobber (match_scratch:SI 3 "=X,h"))]
4984   "TARGET_V8PLUS"
4985   "@
4986    umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
4987    umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4988   [(set_attr "type" "multi")
4989    (set_attr "length" "2,3")])
4991 (define_expand "umulsi3_highpart"
4992   [(set (match_operand:SI 0 "register_operand" "")
4993         (truncate:SI
4994          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4995                                (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
4996                       (const_int 32))))]
4997   "TARGET_HARD_MUL && TARGET_ARCH32"
4999   if (CONSTANT_P (operands[2]))
5000     {
5001       if (TARGET_V8PLUS)
5002         {
5003           emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
5004                                                         operands[1],
5005                                                         operands[2],
5006                                                         GEN_INT (32)));
5007           DONE;
5008         }
5009       emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
5010       DONE;
5011     }
5012   if (TARGET_V8PLUS)
5013     {
5014       emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
5015                                               operands[2], GEN_INT (32)));
5016       DONE;
5017     }
5020 ;; XXX
5021 (define_insn "umulsi3_highpart_v8plus"
5022   [(set (match_operand:SI 0 "register_operand" "=h,r")
5023         (truncate:SI
5024          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5025                                (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5026                       (match_operand:SI 3 "small_int_operand" "I,I"))))
5027    (clobber (match_scratch:SI 4 "=X,h"))]
5028   "TARGET_V8PLUS"
5029   "@
5030    umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5031    umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5032   [(set_attr "type" "multi")
5033    (set_attr "length" "2")])
5035 ;; XXX
5036 (define_insn "const_umulsi3_highpart_v8plus"
5037   [(set (match_operand:SI 0 "register_operand" "=h,r")
5038         (truncate:SI
5039          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5040                                (match_operand:DI 2 "uns_small_int_operand" ""))
5041                       (match_operand:SI 3 "small_int_operand" "I,I"))))
5042    (clobber (match_scratch:SI 4 "=X,h"))]
5043   "TARGET_V8PLUS"
5044   "@
5045    umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
5046    umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
5047   [(set_attr "type" "multi")
5048    (set_attr "length" "2")])
5050 ;; XXX
5051 (define_insn "*umulsi3_highpart_sp32"
5052   [(set (match_operand:SI 0 "register_operand" "=r")
5053         (truncate:SI
5054          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5055                                (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
5056                       (const_int 32))))]
5057   "TARGET_HARD_MUL32"
5058   "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
5059   [(set_attr "type" "multi")
5060    (set_attr "length" "2")])
5062 ;; XXX
5063 (define_insn "const_umulsi3_highpart"
5064   [(set (match_operand:SI 0 "register_operand" "=r")
5065         (truncate:SI
5066          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5067                                (match_operand:DI 2 "uns_small_int_operand" ""))
5068                       (const_int 32))))]
5069   "TARGET_HARD_MUL32"
5070   "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
5071   [(set_attr "type" "multi")
5072    (set_attr "length" "2")])
5074 ;; The V8 architecture specifies that there must be 3 instructions between
5075 ;; a Y register write and a use of it for correct results.
5077 (define_expand "divsi3"
5078   [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
5079                    (div:SI (match_operand:SI 1 "register_operand" "r,r")
5080                            (match_operand:SI 2 "input_operand" "rI,m")))
5081               (clobber (match_scratch:SI 3 "=&r,&r"))])]
5082   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5084   if (TARGET_ARCH64)
5085     {
5086       operands[3] = gen_reg_rtx(SImode);
5087       emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
5088       emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
5089                                   operands[3]));
5090       DONE;
5091     }
5094 (define_insn "divsi3_sp32"
5095   [(set (match_operand:SI 0 "register_operand" "=r,r")
5096         (div:SI (match_operand:SI 1 "register_operand" "r,r")
5097                 (match_operand:SI 2 "input_operand" "rI,m")))
5098    (clobber (match_scratch:SI 3 "=&r,&r"))]
5099   "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
5100    && TARGET_ARCH32"
5102   if (which_alternative == 0)
5103     if (TARGET_V9)
5104       return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdiv\t%1, %2, %0";
5105     else
5106       return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
5107   else
5108     if (TARGET_V9)
5109       return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tld\t%2, %3\n\tsdiv\t%1, %3, %0";
5110     else
5111       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";
5113   [(set_attr "type" "multi")
5114    (set (attr "length")
5115         (if_then_else (eq_attr "isa" "v9")
5116                       (const_int 4) (const_int 6)))])
5118 (define_insn "divsi3_sp64"
5119   [(set (match_operand:SI 0 "register_operand" "=r")
5120         (div:SI (match_operand:SI 1 "register_operand" "r")
5121                 (match_operand:SI 2 "input_operand" "rI")))
5122    (use (match_operand:SI 3 "register_operand" "r"))]
5123   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5124   "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
5125   [(set_attr "type" "multi")
5126    (set_attr "length" "2")])
5128 (define_insn "divdi3"
5129   [(set (match_operand:DI 0 "register_operand" "=r")
5130         (div:DI (match_operand:DI 1 "register_operand" "r")
5131                 (match_operand:DI 2 "arith_operand" "rI")))]
5132   "TARGET_ARCH64"
5133   "sdivx\t%1, %2, %0"
5134   [(set_attr "type" "idiv")])
5136 (define_insn "*cmp_sdiv_cc_set"
5137   [(set (reg:CC 100)
5138         (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
5139                             (match_operand:SI 2 "arith_operand" "rI"))
5140                     (const_int 0)))
5141    (set (match_operand:SI 0 "register_operand" "=r")
5142         (div:SI (match_dup 1) (match_dup 2)))
5143    (clobber (match_scratch:SI 3 "=&r"))]
5144   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5146   if (TARGET_V9)
5147     return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdivcc\t%1, %2, %0";
5148   else
5149     return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
5151   [(set_attr "type" "multi")
5152    (set (attr "length")
5153         (if_then_else (eq_attr "isa" "v9")
5154                       (const_int 3) (const_int 6)))])
5156 ;; XXX
5157 (define_expand "udivsi3"
5158   [(set (match_operand:SI 0 "register_operand" "")
5159         (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "")
5160                  (match_operand:SI 2 "input_operand" "")))]
5161   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5162   "")
5164 ;; The V8 architecture specifies that there must be 3 instructions between
5165 ;; a Y register write and a use of it for correct results.
5167 (define_insn "udivsi3_sp32"
5168   [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
5169         (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r,r,m")
5170                  (match_operand:SI 2 "input_operand" "rI,m,r")))]
5171   "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
5172    && TARGET_ARCH32"
5174   output_asm_insn ("wr\t%%g0, %%g0, %%y", operands);
5175   switch (which_alternative)
5176     {
5177     default:
5178       return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
5179     case 1:
5180       return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
5181     case 2:
5182       return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
5183     }
5185   [(set_attr "type" "multi")
5186    (set_attr "length" "5")])
5188 (define_insn "udivsi3_sp64"
5189   [(set (match_operand:SI 0 "register_operand" "=r")
5190         (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r")
5191                  (match_operand:SI 2 "input_operand" "rI")))]
5192   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5193   "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
5194   [(set_attr "type" "multi")
5195    (set_attr "length" "2")])
5197 (define_insn "udivdi3"
5198   [(set (match_operand:DI 0 "register_operand" "=r")
5199         (udiv:DI (match_operand:DI 1 "register_operand" "r")
5200                  (match_operand:DI 2 "arith_operand" "rI")))]
5201   "TARGET_ARCH64"
5202   "udivx\t%1, %2, %0"
5203   [(set_attr "type" "idiv")])
5205 (define_insn "*cmp_udiv_cc_set"
5206   [(set (reg:CC 100)
5207         (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
5208                              (match_operand:SI 2 "arith_operand" "rI"))
5209                     (const_int 0)))
5210    (set (match_operand:SI 0 "register_operand" "=r")
5211         (udiv:SI (match_dup 1) (match_dup 2)))]
5212   "TARGET_V8
5213    || TARGET_DEPRECATED_V8_INSNS"
5215   if (TARGET_V9)
5216     return "wr\t%%g0, %%g0, %%y\n\tudivcc\t%1, %2, %0";
5217   else
5218     return "wr\t%%g0, %%g0, %%y\n\tnop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
5220   [(set_attr "type" "multi")
5221    (set (attr "length")
5222         (if_then_else (eq_attr "isa" "v9")
5223                       (const_int 2) (const_int 5)))])
5225 ; sparclet multiply/accumulate insns
5227 (define_insn "*smacsi"
5228   [(set (match_operand:SI 0 "register_operand" "=r")
5229         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
5230                           (match_operand:SI 2 "arith_operand" "rI"))
5231                  (match_operand:SI 3 "register_operand" "0")))]
5232   "TARGET_SPARCLET"
5233   "smac\t%1, %2, %0"
5234   [(set_attr "type" "imul")])
5236 (define_insn "*smacdi"
5237   [(set (match_operand:DI 0 "register_operand" "=r")
5238         (plus:DI (mult:DI (sign_extend:DI
5239                            (match_operand:SI 1 "register_operand" "%r"))
5240                           (sign_extend:DI
5241                            (match_operand:SI 2 "register_operand" "r")))
5242                  (match_operand:DI 3 "register_operand" "0")))]
5243   "TARGET_SPARCLET"
5244   "smacd\t%1, %2, %L0"
5245   [(set_attr "type" "imul")])
5247 (define_insn "*umacdi"
5248   [(set (match_operand:DI 0 "register_operand" "=r")
5249         (plus:DI (mult:DI (zero_extend:DI
5250                            (match_operand:SI 1 "register_operand" "%r"))
5251                           (zero_extend:DI
5252                            (match_operand:SI 2 "register_operand" "r")))
5253                  (match_operand:DI 3 "register_operand" "0")))]
5254   "TARGET_SPARCLET"
5255   "umacd\t%1, %2, %L0"
5256   [(set_attr "type" "imul")])
5259 ;; Boolean instructions.
5261 ;; We define DImode `and' so with DImode `not' we can get
5262 ;; DImode `andn'.  Other combinations are possible.
5264 (define_mode_macro V64I [DI V2SI V4HI V8QI])
5265 (define_mode_macro V32I [SI V2HI V4QI])
5267 (define_expand "and<V64I:mode>3"
5268   [(set (match_operand:V64I 0 "register_operand" "")
5269         (and:V64I (match_operand:V64I 1 "arith_double_operand" "")
5270                   (match_operand:V64I 2 "arith_double_operand" "")))]
5271   ""
5272   "")
5274 (define_insn "*and<V64I:mode>3_sp32"
5275   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5276         (and:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5277                   (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5278   "! TARGET_ARCH64"
5279   "@
5280   #
5281   fand\t%1, %2, %0"
5282   [(set_attr "type" "*,fga")
5283    (set_attr "length" "2,*")
5284    (set_attr "fptype" "*,double")])
5286 (define_insn "*and<V64I:mode>3_sp64"
5287   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5288         (and:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
5289                   (match_operand:V64I 2 "arith_operand" "rI,b")))]
5290   "TARGET_ARCH64"
5291   "@
5292    and\t%1, %2, %0
5293    fand\t%1, %2, %0"
5294   [(set_attr "type" "*,fga")
5295    (set_attr "fptype" "*,double")])
5297 (define_insn "and<V32I:mode>3"
5298   [(set (match_operand:V32I 0 "register_operand" "=r,d")
5299         (and:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
5300                   (match_operand:V32I 2 "arith_operand" "rI,d")))]
5301   ""
5302   "@
5303    and\t%1, %2, %0
5304    fands\t%1, %2, %0"
5305   [(set_attr "type" "*,fga")
5306    (set_attr "fptype" "*,single")])
5308 (define_split
5309   [(set (match_operand:SI 0 "register_operand" "")
5310         (and:SI (match_operand:SI 1 "register_operand" "")
5311                 (match_operand:SI 2 "const_compl_high_operand" "")))
5312    (clobber (match_operand:SI 3 "register_operand" ""))]
5313   ""
5314   [(set (match_dup 3) (match_dup 4))
5315    (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
5317   operands[4] = GEN_INT (~INTVAL (operands[2]));
5320 (define_insn_and_split "*and_not_<V64I:mode>_sp32"
5321   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5322         (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
5323                   (match_operand:V64I 2 "register_operand" "r,b")))]
5324   "! TARGET_ARCH64"
5325   "@
5326    #
5327    fandnot1\t%1, %2, %0"
5328   "&& reload_completed
5329    && ((GET_CODE (operands[0]) == REG
5330         && REGNO (operands[0]) < 32)
5331        || (GET_CODE (operands[0]) == SUBREG
5332            && GET_CODE (SUBREG_REG (operands[0])) == REG
5333            && REGNO (SUBREG_REG (operands[0])) < 32))"
5334   [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
5335    (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
5336   "operands[3] = gen_highpart (SImode, operands[0]);
5337    operands[4] = gen_highpart (SImode, operands[1]);
5338    operands[5] = gen_highpart (SImode, operands[2]);
5339    operands[6] = gen_lowpart (SImode, operands[0]);
5340    operands[7] = gen_lowpart (SImode, operands[1]);
5341    operands[8] = gen_lowpart (SImode, operands[2]);"
5342   [(set_attr "type" "*,fga")
5343    (set_attr "length" "2,*")
5344    (set_attr "fptype" "*,double")])
5346 (define_insn "*and_not_<V64I:mode>_sp64"
5347   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5348         (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
5349                   (match_operand:V64I 2 "register_operand" "r,b")))]
5350   "TARGET_ARCH64"
5351   "@
5352    andn\t%2, %1, %0
5353    fandnot1\t%1, %2, %0"
5354   [(set_attr "type" "*,fga")
5355    (set_attr "fptype" "*,double")])
5357 (define_insn "*and_not_<V32I:mode>"
5358   [(set (match_operand:V32I 0 "register_operand" "=r,d")
5359         (and:V32I (not:V32I (match_operand:V32I 1 "register_operand" "%r,d"))
5360                   (match_operand:V32I 2 "register_operand" "r,d")))]
5361   ""
5362   "@
5363    andn\t%2, %1, %0
5364    fandnot1s\t%1, %2, %0"
5365   [(set_attr "type" "*,fga")
5366    (set_attr "fptype" "*,single")])
5368 (define_expand "ior<V64I:mode>3"
5369   [(set (match_operand:V64I 0 "register_operand" "")
5370         (ior:V64I (match_operand:V64I 1 "arith_double_operand" "")
5371                   (match_operand:V64I 2 "arith_double_operand" "")))]
5372   ""
5373   "")
5375 (define_insn "*ior<V64I:mode>3_sp32"
5376   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5377         (ior:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5378                   (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5379   "! TARGET_ARCH64"
5380   "@
5381   #
5382   for\t%1, %2, %0"
5383   [(set_attr "type" "*,fga")
5384    (set_attr "length" "2,*")
5385    (set_attr "fptype" "*,double")])
5387 (define_insn "*ior<V64I:mode>3_sp64"
5388   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5389         (ior:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
5390                   (match_operand:V64I 2 "arith_operand" "rI,b")))]
5391   "TARGET_ARCH64"
5392   "@
5393   or\t%1, %2, %0
5394   for\t%1, %2, %0"
5395   [(set_attr "type" "*,fga")
5396    (set_attr "fptype" "*,double")])
5398 (define_insn "ior<V32I:mode>3"
5399   [(set (match_operand:V32I 0 "register_operand" "=r,d")
5400         (ior:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
5401                   (match_operand:V32I 2 "arith_operand" "rI,d")))]
5402   ""
5403   "@
5404    or\t%1, %2, %0
5405    fors\t%1, %2, %0"
5406   [(set_attr "type" "*,fga")
5407    (set_attr "fptype" "*,single")])
5409 (define_split
5410   [(set (match_operand:SI 0 "register_operand" "")
5411         (ior:SI (match_operand:SI 1 "register_operand" "")
5412                 (match_operand:SI 2 "const_compl_high_operand" "")))
5413    (clobber (match_operand:SI 3 "register_operand" ""))]
5414   ""
5415   [(set (match_dup 3) (match_dup 4))
5416    (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
5418   operands[4] = GEN_INT (~INTVAL (operands[2]));
5421 (define_insn_and_split "*or_not_<V64I:mode>_sp32"
5422   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5423         (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
5424                   (match_operand:V64I 2 "register_operand" "r,b")))]
5425   "! TARGET_ARCH64"
5426   "@
5427    #
5428    fornot1\t%1, %2, %0"
5429   "&& reload_completed
5430    && ((GET_CODE (operands[0]) == REG
5431         && REGNO (operands[0]) < 32)
5432        || (GET_CODE (operands[0]) == SUBREG
5433            && GET_CODE (SUBREG_REG (operands[0])) == REG
5434            && REGNO (SUBREG_REG (operands[0])) < 32))"
5435   [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
5436    (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
5437   "operands[3] = gen_highpart (SImode, operands[0]);
5438    operands[4] = gen_highpart (SImode, operands[1]);
5439    operands[5] = gen_highpart (SImode, operands[2]);
5440    operands[6] = gen_lowpart (SImode, operands[0]);
5441    operands[7] = gen_lowpart (SImode, operands[1]);
5442    operands[8] = gen_lowpart (SImode, operands[2]);"
5443   [(set_attr "type" "*,fga")
5444    (set_attr "length" "2,*")
5445    (set_attr "fptype" "*,double")])
5447 (define_insn "*or_not_<V64I:mode>_sp64"
5448   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5449         (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
5450                   (match_operand:V64I 2 "register_operand" "r,b")))]
5451   "TARGET_ARCH64"
5452   "@
5453   orn\t%2, %1, %0
5454   fornot1\t%1, %2, %0"
5455   [(set_attr "type" "*,fga")
5456    (set_attr "fptype" "*,double")])
5458 (define_insn "*or_not_<V32I:mode>"
5459   [(set (match_operand:V32I 0 "register_operand" "=r,d")
5460         (ior:V32I (not:V32I (match_operand:V32I 1 "register_operand" "r,d"))
5461                   (match_operand:V32I 2 "register_operand" "r,d")))]
5462   ""
5463   "@
5464    orn\t%2, %1, %0
5465    fornot1s\t%1, %2, %0"
5466   [(set_attr "type" "*,fga")
5467    (set_attr "fptype" "*,single")])
5469 (define_expand "xor<V64I:mode>3"
5470   [(set (match_operand:V64I 0 "register_operand" "")
5471         (xor:V64I (match_operand:V64I 1 "arith_double_operand" "")
5472                   (match_operand:V64I 2 "arith_double_operand" "")))]
5473   ""
5474   "")
5476 (define_insn "*xor<V64I:mode>3_sp32"
5477   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5478         (xor:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5479                   (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5480   "! TARGET_ARCH64"
5481   "@
5482   #
5483   fxor\t%1, %2, %0"
5484   [(set_attr "type" "*,fga")
5485    (set_attr "length" "2,*")
5486    (set_attr "fptype" "*,double")])
5488 (define_insn "*xor<V64I:mode>3_sp64"
5489   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5490         (xor:V64I (match_operand:V64I 1 "arith_operand" "%rJ,b")
5491                   (match_operand:V64I 2 "arith_operand" "rI,b")))]
5492   "TARGET_ARCH64"
5493   "@
5494   xor\t%r1, %2, %0
5495   fxor\t%1, %2, %0"
5496   [(set_attr "type" "*,fga")
5497    (set_attr "fptype" "*,double")])
5499 (define_insn "xor<V32I:mode>3"
5500   [(set (match_operand:V32I 0 "register_operand" "=r,d")
5501         (xor:V32I (match_operand:V32I 1 "arith_operand" "%rJ,d")
5502                   (match_operand:V32I 2 "arith_operand" "rI,d")))]
5503   ""
5504   "@
5505    xor\t%r1, %2, %0
5506    fxors\t%1, %2, %0"
5507   [(set_attr "type" "*,fga")
5508    (set_attr "fptype" "*,single")])
5510 (define_split
5511   [(set (match_operand:SI 0 "register_operand" "")
5512         (xor:SI (match_operand:SI 1 "register_operand" "")
5513                 (match_operand:SI 2 "const_compl_high_operand" "")))
5514    (clobber (match_operand:SI 3 "register_operand" ""))]
5515    ""
5516   [(set (match_dup 3) (match_dup 4))
5517    (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
5519   operands[4] = GEN_INT (~INTVAL (operands[2]));
5522 (define_split
5523   [(set (match_operand:SI 0 "register_operand" "")
5524         (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
5525                         (match_operand:SI 2 "const_compl_high_operand" ""))))
5526    (clobber (match_operand:SI 3 "register_operand" ""))]
5527   ""
5528   [(set (match_dup 3) (match_dup 4))
5529    (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
5531   operands[4] = GEN_INT (~INTVAL (operands[2]));
5534 ;; Split DImode logical operations requiring two instructions.
5535 (define_split
5536   [(set (match_operand:V64I 0 "register_operand" "")
5537         (match_operator:V64I 1 "cc_arith_operator"      ; AND, IOR, XOR
5538                            [(match_operand:V64I 2 "register_operand" "")
5539                             (match_operand:V64I 3 "arith_double_operand" "")]))]
5540   "! TARGET_ARCH64
5541    && reload_completed
5542    && ((GET_CODE (operands[0]) == REG
5543         && REGNO (operands[0]) < 32)
5544        || (GET_CODE (operands[0]) == SUBREG
5545            && GET_CODE (SUBREG_REG (operands[0])) == REG
5546            && REGNO (SUBREG_REG (operands[0])) < 32))"
5547   [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
5548    (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
5550   operands[4] = gen_highpart (SImode, operands[0]);
5551   operands[5] = gen_lowpart (SImode, operands[0]);
5552   operands[6] = gen_highpart (SImode, operands[2]);
5553   operands[7] = gen_lowpart (SImode, operands[2]);
5554 #if HOST_BITS_PER_WIDE_INT == 32
5555   if (GET_CODE (operands[3]) == CONST_INT && <V64I:MODE>mode == DImode)
5556     {
5557       if (INTVAL (operands[3]) < 0)
5558         operands[8] = constm1_rtx;
5559       else
5560         operands[8] = const0_rtx;
5561     }
5562   else
5563 #endif
5564     operands[8] = gen_highpart_mode (SImode, <V64I:MODE>mode, operands[3]);
5565   operands[9] = gen_lowpart (SImode, operands[3]);
5568 ;; xnor patterns.  Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
5569 ;; Combine now canonicalizes to the rightmost expression.
5570 (define_insn_and_split "*xor_not_<V64I:mode>_sp32"
5571   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5572         (not:V64I (xor:V64I (match_operand:V64I 1 "register_operand" "r,b")
5573                             (match_operand:V64I 2 "register_operand" "r,b"))))]
5574   "! TARGET_ARCH64"
5575   "@
5576    #
5577    fxnor\t%1, %2, %0"
5578   "&& reload_completed
5579    && ((GET_CODE (operands[0]) == REG
5580         && REGNO (operands[0]) < 32)
5581        || (GET_CODE (operands[0]) == SUBREG
5582            && GET_CODE (SUBREG_REG (operands[0])) == REG
5583            && REGNO (SUBREG_REG (operands[0])) < 32))"
5584   [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
5585    (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
5586   "operands[3] = gen_highpart (SImode, operands[0]);
5587    operands[4] = gen_highpart (SImode, operands[1]);
5588    operands[5] = gen_highpart (SImode, operands[2]);
5589    operands[6] = gen_lowpart (SImode, operands[0]);
5590    operands[7] = gen_lowpart (SImode, operands[1]);
5591    operands[8] = gen_lowpart (SImode, operands[2]);"
5592   [(set_attr "type" "*,fga")
5593    (set_attr "length" "2,*")
5594    (set_attr "fptype" "*,double")])
5596 (define_insn "*xor_not_<V64I:mode>_sp64"
5597   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5598         (not:V64I (xor:V64I (match_operand:V64I 1 "register_or_zero_operand" "rJ,b")
5599                             (match_operand:V64I 2 "arith_operand" "rI,b"))))]
5600   "TARGET_ARCH64"
5601   "@
5602   xnor\t%r1, %2, %0
5603   fxnor\t%1, %2, %0"
5604   [(set_attr "type" "*,fga")
5605    (set_attr "fptype" "*,double")])
5607 (define_insn "*xor_not_<V32I:mode>"
5608   [(set (match_operand:V32I 0 "register_operand" "=r,d")
5609         (not:V32I (xor:V32I (match_operand:V32I 1 "register_or_zero_operand" "rJ,d")
5610                             (match_operand:V32I 2 "arith_operand" "rI,d"))))]
5611   ""
5612   "@
5613    xnor\t%r1, %2, %0
5614    fxnors\t%1, %2, %0"
5615   [(set_attr "type" "*,fga")
5616    (set_attr "fptype" "*,single")])
5618 ;; These correspond to the above in the case where we also (or only)
5619 ;; want to set the condition code.  
5621 (define_insn "*cmp_cc_arith_op"
5622   [(set (reg:CC 100)
5623         (compare:CC
5624          (match_operator:SI 2 "cc_arith_operator"
5625                             [(match_operand:SI 0 "arith_operand" "%r")
5626                              (match_operand:SI 1 "arith_operand" "rI")])
5627          (const_int 0)))]
5628   ""
5629   "%A2cc\t%0, %1, %%g0"
5630   [(set_attr "type" "compare")])
5632 (define_insn "*cmp_ccx_arith_op"
5633   [(set (reg:CCX 100)
5634         (compare:CCX
5635          (match_operator:DI 2 "cc_arith_operator"
5636                             [(match_operand:DI 0 "arith_operand" "%r")
5637                              (match_operand:DI 1 "arith_operand" "rI")])
5638          (const_int 0)))]
5639   "TARGET_ARCH64"
5640   "%A2cc\t%0, %1, %%g0"
5641   [(set_attr "type" "compare")])
5643 (define_insn "*cmp_cc_arith_op_set"
5644   [(set (reg:CC 100)
5645         (compare:CC
5646          (match_operator:SI 3 "cc_arith_operator"
5647                             [(match_operand:SI 1 "arith_operand" "%r")
5648                              (match_operand:SI 2 "arith_operand" "rI")])
5649          (const_int 0)))
5650    (set (match_operand:SI 0 "register_operand" "=r")
5651         (match_operator:SI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5652   "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5653   "%A3cc\t%1, %2, %0"
5654   [(set_attr "type" "compare")])
5656 (define_insn "*cmp_ccx_arith_op_set"
5657   [(set (reg:CCX 100)
5658         (compare:CCX
5659          (match_operator:DI 3 "cc_arith_operator"
5660                             [(match_operand:DI 1 "arith_operand" "%r")
5661                              (match_operand:DI 2 "arith_operand" "rI")])
5662          (const_int 0)))
5663    (set (match_operand:DI 0 "register_operand" "=r")
5664         (match_operator:DI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5665   "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5666   "%A3cc\t%1, %2, %0"
5667   [(set_attr "type" "compare")])
5669 (define_insn "*cmp_cc_xor_not"
5670   [(set (reg:CC 100)
5671         (compare:CC
5672          (not:SI (xor:SI (match_operand:SI 0 "register_or_zero_operand" "%rJ")
5673                          (match_operand:SI 1 "arith_operand" "rI")))
5674          (const_int 0)))]
5675   ""
5676   "xnorcc\t%r0, %1, %%g0"
5677   [(set_attr "type" "compare")])
5679 (define_insn "*cmp_ccx_xor_not"
5680   [(set (reg:CCX 100)
5681         (compare:CCX
5682          (not:DI (xor:DI (match_operand:DI 0 "register_or_zero_operand" "%rJ")
5683                          (match_operand:DI 1 "arith_operand" "rI")))
5684          (const_int 0)))]
5685   "TARGET_ARCH64"
5686   "xnorcc\t%r0, %1, %%g0"
5687   [(set_attr "type" "compare")])
5689 (define_insn "*cmp_cc_xor_not_set"
5690   [(set (reg:CC 100)
5691         (compare:CC
5692          (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
5693                          (match_operand:SI 2 "arith_operand" "rI")))
5694          (const_int 0)))
5695    (set (match_operand:SI 0 "register_operand" "=r")
5696         (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
5697   ""
5698   "xnorcc\t%r1, %2, %0"
5699   [(set_attr "type" "compare")])
5701 (define_insn "*cmp_ccx_xor_not_set"
5702   [(set (reg:CCX 100)
5703         (compare:CCX
5704          (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
5705                          (match_operand:DI 2 "arith_operand" "rI")))
5706          (const_int 0)))
5707    (set (match_operand:DI 0 "register_operand" "=r")
5708         (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
5709   "TARGET_ARCH64"
5710   "xnorcc\t%r1, %2, %0"
5711   [(set_attr "type" "compare")])
5713 (define_insn "*cmp_cc_arith_op_not"
5714   [(set (reg:CC 100)
5715         (compare:CC
5716          (match_operator:SI 2 "cc_arith_not_operator"
5717                             [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
5718                              (match_operand:SI 1 "register_or_zero_operand" "rJ")])
5719          (const_int 0)))]
5720   ""
5721   "%B2cc\t%r1, %0, %%g0"
5722   [(set_attr "type" "compare")])
5724 (define_insn "*cmp_ccx_arith_op_not"
5725   [(set (reg:CCX 100)
5726         (compare:CCX
5727          (match_operator:DI 2 "cc_arith_not_operator"
5728                             [(not:DI (match_operand:DI 0 "arith_operand" "rI"))
5729                              (match_operand:DI 1 "register_or_zero_operand" "rJ")])
5730          (const_int 0)))]
5731   "TARGET_ARCH64"
5732   "%B2cc\t%r1, %0, %%g0"
5733   [(set_attr "type" "compare")])
5735 (define_insn "*cmp_cc_arith_op_not_set"
5736   [(set (reg:CC 100)
5737         (compare:CC
5738          (match_operator:SI 3 "cc_arith_not_operator"
5739                             [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
5740                              (match_operand:SI 2 "register_or_zero_operand" "rJ")])
5741          (const_int 0)))
5742    (set (match_operand:SI 0 "register_operand" "=r")
5743         (match_operator:SI 4 "cc_arith_not_operator"
5744                             [(not:SI (match_dup 1)) (match_dup 2)]))]
5745   "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5746   "%B3cc\t%r2, %1, %0"
5747   [(set_attr "type" "compare")])
5749 (define_insn "*cmp_ccx_arith_op_not_set"
5750   [(set (reg:CCX 100)
5751         (compare:CCX
5752          (match_operator:DI 3 "cc_arith_not_operator"
5753                             [(not:DI (match_operand:DI 1 "arith_operand" "rI"))
5754                              (match_operand:DI 2 "register_or_zero_operand" "rJ")])
5755          (const_int 0)))
5756    (set (match_operand:DI 0 "register_operand" "=r")
5757         (match_operator:DI 4 "cc_arith_not_operator"
5758                             [(not:DI (match_dup 1)) (match_dup 2)]))]
5759   "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5760   "%B3cc\t%r2, %1, %0"
5761   [(set_attr "type" "compare")])
5763 ;; We cannot use the "neg" pseudo insn because the Sun assembler
5764 ;; does not know how to make it work for constants.
5766 (define_expand "negdi2"
5767   [(set (match_operand:DI 0 "register_operand" "=r")
5768         (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5769   ""
5771   if (! TARGET_ARCH64)
5772     {
5773       emit_insn (gen_rtx_PARALLEL
5774                  (VOIDmode,
5775                   gen_rtvec (2,
5776                              gen_rtx_SET (VOIDmode, operand0,
5777                                           gen_rtx_NEG (DImode, operand1)),
5778                              gen_rtx_CLOBBER (VOIDmode,
5779                                               gen_rtx_REG (CCmode,
5780                                                            SPARC_ICC_REG)))));
5781       DONE;
5782     }
5785 (define_insn_and_split "*negdi2_sp32"
5786   [(set (match_operand:DI 0 "register_operand" "=r")
5787         (neg:DI (match_operand:DI 1 "register_operand" "r")))
5788    (clobber (reg:CC 100))]
5789   "TARGET_ARCH32"
5790   "#"
5791   "&& reload_completed"
5792   [(parallel [(set (reg:CC_NOOV 100)
5793                    (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
5794                                     (const_int 0)))
5795               (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
5796    (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
5797                                 (ltu:SI (reg:CC 100) (const_int 0))))]
5798   "operands[2] = gen_highpart (SImode, operands[0]);
5799    operands[3] = gen_highpart (SImode, operands[1]);
5800    operands[4] = gen_lowpart (SImode, operands[0]);
5801    operands[5] = gen_lowpart (SImode, operands[1]);"
5802   [(set_attr "length" "2")])
5804 (define_insn "*negdi2_sp64"
5805   [(set (match_operand:DI 0 "register_operand" "=r")
5806         (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5807   "TARGET_ARCH64"
5808   "sub\t%%g0, %1, %0")
5810 (define_insn "negsi2"
5811   [(set (match_operand:SI 0 "register_operand" "=r")
5812         (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
5813   ""
5814   "sub\t%%g0, %1, %0")
5816 (define_insn "*cmp_cc_neg"
5817   [(set (reg:CC_NOOV 100)
5818         (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
5819                          (const_int 0)))]
5820   ""
5821   "subcc\t%%g0, %0, %%g0"
5822   [(set_attr "type" "compare")])
5824 (define_insn "*cmp_ccx_neg"
5825   [(set (reg:CCX_NOOV 100)
5826         (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_operand" "rI"))
5827                           (const_int 0)))]
5828   "TARGET_ARCH64"
5829   "subcc\t%%g0, %0, %%g0"
5830   [(set_attr "type" "compare")])
5832 (define_insn "*cmp_cc_set_neg"
5833   [(set (reg:CC_NOOV 100)
5834         (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
5835                          (const_int 0)))
5836    (set (match_operand:SI 0 "register_operand" "=r")
5837         (neg:SI (match_dup 1)))]
5838   ""
5839   "subcc\t%%g0, %1, %0"
5840   [(set_attr "type" "compare")])
5842 (define_insn "*cmp_ccx_set_neg"
5843   [(set (reg:CCX_NOOV 100)
5844         (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_operand" "rI"))
5845                           (const_int 0)))
5846    (set (match_operand:DI 0 "register_operand" "=r")
5847         (neg:DI (match_dup 1)))]
5848   "TARGET_ARCH64"
5849   "subcc\t%%g0, %1, %0"
5850   [(set_attr "type" "compare")])
5852 ;; We cannot use the "not" pseudo insn because the Sun assembler
5853 ;; does not know how to make it work for constants.
5854 (define_expand "one_cmpl<V64I:mode>2"
5855   [(set (match_operand:V64I 0 "register_operand" "")
5856         (not:V64I (match_operand:V64I 1 "register_operand" "")))]
5857   ""
5858   "")
5860 (define_insn_and_split "*one_cmpl<V64I:mode>2_sp32"
5861   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5862         (not:V64I (match_operand:V64I 1 "register_operand" "r,b")))]
5863   "! TARGET_ARCH64"
5864   "@
5865    #
5866    fnot1\t%1, %0"
5867   "&& reload_completed
5868    && ((GET_CODE (operands[0]) == REG
5869         && REGNO (operands[0]) < 32)
5870        || (GET_CODE (operands[0]) == SUBREG
5871            && GET_CODE (SUBREG_REG (operands[0])) == REG
5872            && REGNO (SUBREG_REG (operands[0])) < 32))"
5873   [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
5874    (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
5875   "operands[2] = gen_highpart (SImode, operands[0]);
5876    operands[3] = gen_highpart (SImode, operands[1]);
5877    operands[4] = gen_lowpart (SImode, operands[0]);
5878    operands[5] = gen_lowpart (SImode, operands[1]);"
5879   [(set_attr "type" "*,fga")
5880    (set_attr "length" "2,*")
5881    (set_attr "fptype" "*,double")])
5883 (define_insn "*one_cmpl<V64I:mode>2_sp64"
5884   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5885         (not:V64I (match_operand:V64I 1 "arith_operand" "rI,b")))]
5886   "TARGET_ARCH64"
5887   "@
5888    xnor\t%%g0, %1, %0
5889    fnot1\t%1, %0"
5890   [(set_attr "type" "*,fga")
5891    (set_attr "fptype" "*,double")])
5893 (define_insn "one_cmpl<V32I:mode>2"
5894   [(set (match_operand:V32I 0 "register_operand" "=r,d")
5895         (not:V32I (match_operand:V32I 1 "arith_operand" "rI,d")))]
5896   ""
5897   "@
5898   xnor\t%%g0, %1, %0
5899   fnot1s\t%1, %0"
5900   [(set_attr "type" "*,fga")
5901    (set_attr "fptype" "*,single")])
5903 (define_insn "*cmp_cc_not"
5904   [(set (reg:CC 100)
5905         (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
5906                     (const_int 0)))]
5907   ""
5908   "xnorcc\t%%g0, %0, %%g0"
5909   [(set_attr "type" "compare")])
5911 (define_insn "*cmp_ccx_not"
5912   [(set (reg:CCX 100)
5913         (compare:CCX (not:DI (match_operand:DI 0 "arith_operand" "rI"))
5914                      (const_int 0)))]
5915   "TARGET_ARCH64"
5916   "xnorcc\t%%g0, %0, %%g0"
5917   [(set_attr "type" "compare")])
5919 (define_insn "*cmp_cc_set_not"
5920   [(set (reg:CC 100)
5921         (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
5922                     (const_int 0)))
5923    (set (match_operand:SI 0 "register_operand" "=r")
5924         (not:SI (match_dup 1)))]
5925   ""
5926   "xnorcc\t%%g0, %1, %0"
5927   [(set_attr "type" "compare")])
5929 (define_insn "*cmp_ccx_set_not"
5930   [(set (reg:CCX 100)
5931         (compare:CCX (not:DI (match_operand:DI 1 "arith_operand" "rI"))
5932                     (const_int 0)))
5933    (set (match_operand:DI 0 "register_operand" "=r")
5934         (not:DI (match_dup 1)))]
5935   "TARGET_ARCH64"
5936   "xnorcc\t%%g0, %1, %0"
5937   [(set_attr "type" "compare")])
5939 (define_insn "*cmp_cc_set"
5940   [(set (match_operand:SI 0 "register_operand" "=r")
5941         (match_operand:SI 1 "register_operand" "r"))
5942    (set (reg:CC 100)
5943         (compare:CC (match_dup 1)
5944                     (const_int 0)))]
5945   ""
5946   "orcc\t%1, 0, %0"
5947   [(set_attr "type" "compare")])
5949 (define_insn "*cmp_ccx_set64"
5950   [(set (match_operand:DI 0 "register_operand" "=r")
5951         (match_operand:DI 1 "register_operand" "r"))
5952    (set (reg:CCX 100)
5953         (compare:CCX (match_dup 1)
5954                      (const_int 0)))]
5955   "TARGET_ARCH64"
5956   "orcc\t%1, 0, %0"
5957    [(set_attr "type" "compare")])
5960 ;; Floating point arithmetic instructions.
5962 (define_expand "addtf3"
5963   [(set (match_operand:TF 0 "nonimmediate_operand" "")
5964         (plus:TF (match_operand:TF 1 "general_operand" "")
5965                  (match_operand:TF 2 "general_operand" "")))]
5966   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5967   "emit_tfmode_binop (PLUS, operands); DONE;")
5969 (define_insn "*addtf3_hq"
5970   [(set (match_operand:TF 0 "register_operand" "=e")
5971         (plus:TF (match_operand:TF 1 "register_operand" "e")
5972                  (match_operand:TF 2 "register_operand" "e")))]
5973   "TARGET_FPU && TARGET_HARD_QUAD"
5974   "faddq\t%1, %2, %0"
5975   [(set_attr "type" "fp")])
5977 (define_insn "adddf3"
5978   [(set (match_operand:DF 0 "register_operand" "=e")
5979         (plus:DF (match_operand:DF 1 "register_operand" "e")
5980                  (match_operand:DF 2 "register_operand" "e")))]
5981   "TARGET_FPU"
5982   "faddd\t%1, %2, %0"
5983   [(set_attr "type" "fp")
5984    (set_attr "fptype" "double")])
5986 (define_insn "addsf3"
5987   [(set (match_operand:SF 0 "register_operand" "=f")
5988         (plus:SF (match_operand:SF 1 "register_operand" "f")
5989                  (match_operand:SF 2 "register_operand" "f")))]
5990   "TARGET_FPU"
5991   "fadds\t%1, %2, %0"
5992   [(set_attr "type" "fp")])
5994 (define_expand "subtf3"
5995   [(set (match_operand:TF 0 "nonimmediate_operand" "")
5996         (minus:TF (match_operand:TF 1 "general_operand" "")
5997                   (match_operand:TF 2 "general_operand" "")))]
5998   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5999   "emit_tfmode_binop (MINUS, operands); DONE;")
6001 (define_insn "*subtf3_hq"
6002   [(set (match_operand:TF 0 "register_operand" "=e")
6003         (minus:TF (match_operand:TF 1 "register_operand" "e")
6004                   (match_operand:TF 2 "register_operand" "e")))]
6005   "TARGET_FPU && TARGET_HARD_QUAD"
6006   "fsubq\t%1, %2, %0"
6007   [(set_attr "type" "fp")])
6009 (define_insn "subdf3"
6010   [(set (match_operand:DF 0 "register_operand" "=e")
6011         (minus:DF (match_operand:DF 1 "register_operand" "e")
6012                   (match_operand:DF 2 "register_operand" "e")))]
6013   "TARGET_FPU"
6014   "fsubd\t%1, %2, %0"
6015   [(set_attr "type" "fp")
6016    (set_attr "fptype" "double")])
6018 (define_insn "subsf3"
6019   [(set (match_operand:SF 0 "register_operand" "=f")
6020         (minus:SF (match_operand:SF 1 "register_operand" "f")
6021                   (match_operand:SF 2 "register_operand" "f")))]
6022   "TARGET_FPU"
6023   "fsubs\t%1, %2, %0"
6024   [(set_attr "type" "fp")])
6026 (define_expand "multf3"
6027   [(set (match_operand:TF 0 "nonimmediate_operand" "")
6028         (mult:TF (match_operand:TF 1 "general_operand" "")
6029                  (match_operand:TF 2 "general_operand" "")))]
6030   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6031   "emit_tfmode_binop (MULT, operands); DONE;")
6033 (define_insn "*multf3_hq"
6034   [(set (match_operand:TF 0 "register_operand" "=e")
6035         (mult:TF (match_operand:TF 1 "register_operand" "e")
6036                  (match_operand:TF 2 "register_operand" "e")))]
6037   "TARGET_FPU && TARGET_HARD_QUAD"
6038   "fmulq\t%1, %2, %0"
6039   [(set_attr "type" "fpmul")])
6041 (define_insn "muldf3"
6042   [(set (match_operand:DF 0 "register_operand" "=e")
6043         (mult:DF (match_operand:DF 1 "register_operand" "e")
6044                  (match_operand:DF 2 "register_operand" "e")))]
6045   "TARGET_FPU"
6046   "fmuld\t%1, %2, %0"
6047   [(set_attr "type" "fpmul")
6048    (set_attr "fptype" "double")])
6050 (define_insn "mulsf3"
6051   [(set (match_operand:SF 0 "register_operand" "=f")
6052         (mult:SF (match_operand:SF 1 "register_operand" "f")
6053                  (match_operand:SF 2 "register_operand" "f")))]
6054   "TARGET_FPU"
6055   "fmuls\t%1, %2, %0"
6056   [(set_attr "type" "fpmul")])
6058 (define_insn "*muldf3_extend"
6059   [(set (match_operand:DF 0 "register_operand" "=e")
6060         (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
6061                  (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
6062   "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
6063   "fsmuld\t%1, %2, %0"
6064   [(set_attr "type" "fpmul")
6065    (set_attr "fptype" "double")])
6067 (define_insn "*multf3_extend"
6068   [(set (match_operand:TF 0 "register_operand" "=e")
6069         (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
6070                  (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
6071   "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
6072   "fdmulq\t%1, %2, %0"
6073   [(set_attr "type" "fpmul")])
6075 (define_expand "divtf3"
6076   [(set (match_operand:TF 0 "nonimmediate_operand" "")
6077         (div:TF (match_operand:TF 1 "general_operand" "")
6078                 (match_operand:TF 2 "general_operand" "")))]
6079   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6080   "emit_tfmode_binop (DIV, operands); DONE;")
6082 ;; don't have timing for quad-prec. divide.
6083 (define_insn "*divtf3_hq"
6084   [(set (match_operand:TF 0 "register_operand" "=e")
6085         (div:TF (match_operand:TF 1 "register_operand" "e")
6086                 (match_operand:TF 2 "register_operand" "e")))]
6087   "TARGET_FPU && TARGET_HARD_QUAD"
6088   "fdivq\t%1, %2, %0"
6089   [(set_attr "type" "fpdivd")])
6091 (define_insn "divdf3"
6092   [(set (match_operand:DF 0 "register_operand" "=e")
6093         (div:DF (match_operand:DF 1 "register_operand" "e")
6094                 (match_operand:DF 2 "register_operand" "e")))]
6095   "TARGET_FPU"
6096   "fdivd\t%1, %2, %0"
6097   [(set_attr "type" "fpdivd")
6098    (set_attr "fptype" "double")])
6100 (define_insn "divsf3"
6101   [(set (match_operand:SF 0 "register_operand" "=f")
6102         (div:SF (match_operand:SF 1 "register_operand" "f")
6103                 (match_operand:SF 2 "register_operand" "f")))]
6104   "TARGET_FPU"
6105   "fdivs\t%1, %2, %0"
6106   [(set_attr "type" "fpdivs")])
6108 (define_expand "negtf2"
6109   [(set (match_operand:TF 0 "register_operand" "=e,e")
6110         (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6111   "TARGET_FPU"
6112   "")
6114 (define_insn_and_split "*negtf2_notv9"
6115   [(set (match_operand:TF 0 "register_operand" "=e,e")
6116         (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6117   ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6118   "TARGET_FPU
6119    && ! TARGET_V9"
6120   "@
6121   fnegs\t%0, %0
6122   #"
6123   "&& reload_completed
6124    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6125   [(set (match_dup 2) (neg:SF (match_dup 3)))
6126    (set (match_dup 4) (match_dup 5))
6127    (set (match_dup 6) (match_dup 7))]
6128   "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6129    operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6130    operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6131    operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6132    operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6133    operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6134   [(set_attr "type" "fpmove,*")
6135    (set_attr "length" "*,2")])
6137 (define_insn_and_split "*negtf2_v9"
6138   [(set (match_operand:TF 0 "register_operand" "=e,e")
6139         (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6140   ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6141   "TARGET_FPU && TARGET_V9"
6142   "@
6143   fnegd\t%0, %0
6144   #"
6145   "&& reload_completed
6146    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6147   [(set (match_dup 2) (neg:DF (match_dup 3)))
6148    (set (match_dup 4) (match_dup 5))]
6149   "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6150    operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6151    operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6152    operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6153   [(set_attr "type" "fpmove,*")
6154    (set_attr "length" "*,2")
6155    (set_attr "fptype" "double")])
6157 (define_expand "negdf2"
6158   [(set (match_operand:DF 0 "register_operand" "")
6159         (neg:DF (match_operand:DF 1 "register_operand" "")))]
6160   "TARGET_FPU"
6161   "")
6163 (define_insn_and_split "*negdf2_notv9"
6164   [(set (match_operand:DF 0 "register_operand" "=e,e")
6165         (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
6166   "TARGET_FPU && ! TARGET_V9"
6167   "@
6168   fnegs\t%0, %0
6169   #"
6170   "&& reload_completed
6171    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6172   [(set (match_dup 2) (neg:SF (match_dup 3)))
6173    (set (match_dup 4) (match_dup 5))]
6174   "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6175    operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6176    operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6177    operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6178   [(set_attr "type" "fpmove,*")
6179    (set_attr "length" "*,2")])
6181 (define_insn "*negdf2_v9"
6182   [(set (match_operand:DF 0 "register_operand" "=e")
6183         (neg:DF (match_operand:DF 1 "register_operand" "e")))]
6184   "TARGET_FPU && TARGET_V9"
6185   "fnegd\t%1, %0"
6186   [(set_attr "type" "fpmove")
6187    (set_attr "fptype" "double")])
6189 (define_insn "negsf2"
6190   [(set (match_operand:SF 0 "register_operand" "=f")
6191         (neg:SF (match_operand:SF 1 "register_operand" "f")))]
6192   "TARGET_FPU"
6193   "fnegs\t%1, %0"
6194   [(set_attr "type" "fpmove")])
6196 (define_expand "abstf2"
6197   [(set (match_operand:TF 0 "register_operand" "")
6198         (abs:TF (match_operand:TF 1 "register_operand" "")))]
6199   "TARGET_FPU"
6200   "")
6202 (define_insn_and_split "*abstf2_notv9"
6203   [(set (match_operand:TF 0 "register_operand" "=e,e")
6204         (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6205   ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6206   "TARGET_FPU && ! TARGET_V9"
6207   "@
6208   fabss\t%0, %0
6209   #"
6210   "&& reload_completed
6211    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6212   [(set (match_dup 2) (abs:SF (match_dup 3)))
6213    (set (match_dup 4) (match_dup 5))
6214    (set (match_dup 6) (match_dup 7))]
6215   "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6216    operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6217    operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6218    operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6219    operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6220    operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6221   [(set_attr "type" "fpmove,*")
6222    (set_attr "length" "*,2")])
6224 (define_insn "*abstf2_hq_v9"
6225   [(set (match_operand:TF 0 "register_operand" "=e,e")
6226         (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6227   "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
6228   "@
6229   fabsd\t%0, %0
6230   fabsq\t%1, %0"
6231   [(set_attr "type" "fpmove")
6232    (set_attr "fptype" "double,*")])
6234 (define_insn_and_split "*abstf2_v9"
6235   [(set (match_operand:TF 0 "register_operand" "=e,e")
6236         (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6237   "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
6238   "@
6239   fabsd\t%0, %0
6240   #"
6241   "&& reload_completed
6242    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6243   [(set (match_dup 2) (abs:DF (match_dup 3)))
6244    (set (match_dup 4) (match_dup 5))]
6245   "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6246    operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6247    operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6248    operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6249   [(set_attr "type" "fpmove,*")
6250    (set_attr "length" "*,2")
6251    (set_attr "fptype" "double,*")])
6253 (define_expand "absdf2"
6254   [(set (match_operand:DF 0 "register_operand" "")
6255         (abs:DF (match_operand:DF 1 "register_operand" "")))]
6256   "TARGET_FPU"
6257   "")
6259 (define_insn_and_split "*absdf2_notv9"
6260   [(set (match_operand:DF 0 "register_operand" "=e,e")
6261         (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
6262   "TARGET_FPU && ! TARGET_V9"
6263   "@
6264   fabss\t%0, %0
6265   #"
6266   "&& reload_completed
6267    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6268   [(set (match_dup 2) (abs:SF (match_dup 3)))
6269    (set (match_dup 4) (match_dup 5))]
6270   "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6271    operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6272    operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6273    operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6274   [(set_attr "type" "fpmove,*")
6275    (set_attr "length" "*,2")])
6277 (define_insn "*absdf2_v9"
6278   [(set (match_operand:DF 0 "register_operand" "=e")
6279         (abs:DF (match_operand:DF 1 "register_operand" "e")))]
6280   "TARGET_FPU && TARGET_V9"
6281   "fabsd\t%1, %0"
6282   [(set_attr "type" "fpmove")
6283    (set_attr "fptype" "double")])
6285 (define_insn "abssf2"
6286   [(set (match_operand:SF 0 "register_operand" "=f")
6287         (abs:SF (match_operand:SF 1 "register_operand" "f")))]
6288   "TARGET_FPU"
6289   "fabss\t%1, %0"
6290   [(set_attr "type" "fpmove")])
6292 (define_expand "sqrttf2"
6293   [(set (match_operand:TF 0 "nonimmediate_operand" "")
6294         (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
6295   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6296   "emit_tfmode_unop (SQRT, operands); DONE;")
6298 (define_insn "*sqrttf2_hq"
6299   [(set (match_operand:TF 0 "register_operand" "=e")
6300         (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
6301   "TARGET_FPU && TARGET_HARD_QUAD"
6302   "fsqrtq\t%1, %0"
6303   [(set_attr "type" "fpsqrtd")])
6305 (define_insn "sqrtdf2"
6306   [(set (match_operand:DF 0 "register_operand" "=e")
6307         (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
6308   "TARGET_FPU"
6309   "fsqrtd\t%1, %0"
6310   [(set_attr "type" "fpsqrtd")
6311    (set_attr "fptype" "double")])
6313 (define_insn "sqrtsf2"
6314   [(set (match_operand:SF 0 "register_operand" "=f")
6315         (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
6316   "TARGET_FPU"
6317   "fsqrts\t%1, %0"
6318   [(set_attr "type" "fpsqrts")])
6321 ;; Arithmetic shift instructions.
6323 (define_insn "ashlsi3"
6324   [(set (match_operand:SI 0 "register_operand" "=r")
6325         (ashift:SI (match_operand:SI 1 "register_operand" "r")
6326                    (match_operand:SI 2 "arith_operand" "rI")))]
6327   ""
6329   if (GET_CODE (operands[2]) == CONST_INT)
6330     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6331   return "sll\t%1, %2, %0";
6333   [(set (attr "type")
6334         (if_then_else (match_operand 2 "const_one_operand" "")
6335                       (const_string "ialu") (const_string "shift")))])
6337 (define_expand "ashldi3"
6338   [(set (match_operand:DI 0 "register_operand" "=r")
6339         (ashift:DI (match_operand:DI 1 "register_operand" "r")
6340                    (match_operand:SI 2 "arith_operand" "rI")))]
6341   "TARGET_ARCH64 || TARGET_V8PLUS"
6343   if (! TARGET_ARCH64)
6344     {
6345       if (GET_CODE (operands[2]) == CONST_INT)
6346         FAIL;
6347       emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
6348       DONE;
6349     }
6352 (define_insn "*ashldi3_sp64"
6353   [(set (match_operand:DI 0 "register_operand" "=r")
6354         (ashift:DI (match_operand:DI 1 "register_operand" "r")
6355                    (match_operand:SI 2 "arith_operand" "rI")))]
6356   "TARGET_ARCH64"
6358   if (GET_CODE (operands[2]) == CONST_INT)
6359     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6360   return "sllx\t%1, %2, %0";
6362   [(set (attr "type")
6363         (if_then_else (match_operand 2 "const_one_operand" "")
6364                       (const_string "ialu") (const_string "shift")))])
6366 ;; XXX UGH!
6367 (define_insn "ashldi3_v8plus"
6368   [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6369         (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6370                    (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6371    (clobber (match_scratch:SI 3 "=X,X,&h"))]
6372   "TARGET_V8PLUS"
6373   "* return output_v8plus_shift (operands, insn, \"sllx\");"
6374   [(set_attr "type" "multi")
6375    (set_attr "length" "5,5,6")])
6377 ;; Optimize (1LL<<x)-1
6378 ;; XXX this also needs to be fixed to handle equal subregs
6379 ;; XXX first before we could re-enable it.
6380 ;(define_insn ""
6381 ;  [(set (match_operand:DI 0 "register_operand" "=h")
6382 ;       (plus:DI (ashift:DI (const_int 1)
6383 ;                           (match_operand:SI 1 "arith_operand" "rI"))
6384 ;                (const_int -1)))]
6385 ;  "0 && TARGET_V8PLUS"
6387 ;  if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
6388 ;    return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
6389 ;  return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
6391 ;  [(set_attr "type" "multi")
6392 ;   (set_attr "length" "4")])
6394 (define_insn "*cmp_cc_ashift_1"
6395   [(set (reg:CC_NOOV 100)
6396         (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
6397                                     (const_int 1))
6398                          (const_int 0)))]
6399   ""
6400   "addcc\t%0, %0, %%g0"
6401   [(set_attr "type" "compare")])
6403 (define_insn "*cmp_cc_set_ashift_1"
6404   [(set (reg:CC_NOOV 100)
6405         (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
6406                                     (const_int 1))
6407                          (const_int 0)))
6408    (set (match_operand:SI 0 "register_operand" "=r")
6409         (ashift:SI (match_dup 1) (const_int 1)))]
6410   ""
6411   "addcc\t%1, %1, %0"
6412   [(set_attr "type" "compare")])
6414 (define_insn "ashrsi3"
6415   [(set (match_operand:SI 0 "register_operand" "=r")
6416         (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
6417                      (match_operand:SI 2 "arith_operand" "rI")))]
6418   ""
6419   {
6420      if (GET_CODE (operands[2]) == CONST_INT)
6421        operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6422      return "sra\t%1, %2, %0";
6423   }
6424   [(set_attr "type" "shift")])
6426 (define_insn "*ashrsi3_extend"
6427   [(set (match_operand:DI 0 "register_operand" "=r")
6428         (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
6429                                      (match_operand:SI 2 "arith_operand" "r"))))]
6430   "TARGET_ARCH64"
6431   "sra\t%1, %2, %0"
6432   [(set_attr "type" "shift")])
6434 ;; This handles the case as above, but with constant shift instead of
6435 ;; register. Combiner "simplifies" it for us a little bit though.
6436 (define_insn "*ashrsi3_extend2"
6437   [(set (match_operand:DI 0 "register_operand" "=r")
6438         (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
6439                                 (const_int 32))
6440                      (match_operand:SI 2 "small_int_operand" "I")))]
6441   "TARGET_ARCH64 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64"
6443   operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
6444   return "sra\t%1, %2, %0";
6446   [(set_attr "type" "shift")])
6448 (define_expand "ashrdi3"
6449   [(set (match_operand:DI 0 "register_operand" "=r")
6450         (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6451                      (match_operand:SI 2 "arith_operand" "rI")))]
6452   "TARGET_ARCH64 || TARGET_V8PLUS"
6454   if (! TARGET_ARCH64)
6455     {
6456       if (GET_CODE (operands[2]) == CONST_INT)
6457         FAIL;   /* prefer generic code in this case */
6458       emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
6459       DONE;
6460     }
6463 (define_insn "*ashrdi3_sp64"
6464   [(set (match_operand:DI 0 "register_operand" "=r")
6465         (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6466                      (match_operand:SI 2 "arith_operand" "rI")))]
6467   "TARGET_ARCH64"
6468   
6469   {
6470     if (GET_CODE (operands[2]) == CONST_INT)
6471       operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6472     return "srax\t%1, %2, %0";
6473   }
6474   [(set_attr "type" "shift")])
6476 ;; XXX
6477 (define_insn "ashrdi3_v8plus"
6478   [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6479         (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6480                      (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6481    (clobber (match_scratch:SI 3 "=X,X,&h"))]
6482   "TARGET_V8PLUS"
6483   "* return output_v8plus_shift (operands, insn, \"srax\");"
6484   [(set_attr "type" "multi")
6485    (set_attr "length" "5,5,6")])
6487 (define_insn "lshrsi3"
6488   [(set (match_operand:SI 0 "register_operand" "=r")
6489         (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
6490                      (match_operand:SI 2 "arith_operand" "rI")))]
6491   ""
6492   {
6493     if (GET_CODE (operands[2]) == CONST_INT)
6494       operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6495     return "srl\t%1, %2, %0";
6496   }
6497   [(set_attr "type" "shift")])
6499 ;; This handles the case where
6500 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
6501 ;; but combiner "simplifies" it for us.
6502 (define_insn "*lshrsi3_extend"
6503   [(set (match_operand:DI 0 "register_operand" "=r")
6504         (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
6505                            (match_operand:SI 2 "arith_operand" "r")) 0)
6506                 (match_operand 3 "const_int_operand" "")))]
6507   "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff"
6508   "srl\t%1, %2, %0"
6509   [(set_attr "type" "shift")])
6511 ;; This handles the case where
6512 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
6513 ;; but combiner "simplifies" it for us.
6514 (define_insn "*lshrsi3_extend2"
6515   [(set (match_operand:DI 0 "register_operand" "=r")
6516         (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
6517                          (match_operand 2 "small_int_operand" "I")
6518                          (const_int 32)))]
6519   "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6521   operands[2] = GEN_INT (32 - INTVAL (operands[2]));
6522   return "srl\t%1, %2, %0";
6524   [(set_attr "type" "shift")])
6526 (define_expand "lshrdi3"
6527   [(set (match_operand:DI 0 "register_operand" "=r")
6528         (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6529                      (match_operand:SI 2 "arith_operand" "rI")))]
6530   "TARGET_ARCH64 || TARGET_V8PLUS"
6532   if (! TARGET_ARCH64)
6533     {
6534       if (GET_CODE (operands[2]) == CONST_INT)
6535         FAIL;
6536       emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
6537       DONE;
6538     }
6541 (define_insn "*lshrdi3_sp64"
6542   [(set (match_operand:DI 0 "register_operand" "=r")
6543         (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6544                      (match_operand:SI 2 "arith_operand" "rI")))]
6545   "TARGET_ARCH64"
6546   {
6547     if (GET_CODE (operands[2]) == CONST_INT)
6548       operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6549     return "srlx\t%1, %2, %0";
6550   }
6551   [(set_attr "type" "shift")])
6553 ;; XXX
6554 (define_insn "lshrdi3_v8plus"
6555   [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6556         (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6557                      (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6558    (clobber (match_scratch:SI 3 "=X,X,&h"))]
6559   "TARGET_V8PLUS"
6560   "* return output_v8plus_shift (operands, insn, \"srlx\");"
6561   [(set_attr "type" "multi")
6562    (set_attr "length" "5,5,6")])
6564 (define_insn ""
6565   [(set (match_operand:SI 0 "register_operand" "=r")
6566         (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6567                                              (const_int 32)) 4)
6568                      (match_operand:SI 2 "small_int_operand" "I")))]
6569   "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6571   operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6572   return "srax\t%1, %2, %0";
6574   [(set_attr "type" "shift")])
6576 (define_insn ""
6577   [(set (match_operand:SI 0 "register_operand" "=r")
6578         (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6579                                              (const_int 32)) 4)
6580                      (match_operand:SI 2 "small_int_operand" "I")))]
6581   "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6583   operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6584   return "srlx\t%1, %2, %0";
6586   [(set_attr "type" "shift")])
6588 (define_insn ""
6589   [(set (match_operand:SI 0 "register_operand" "=r")
6590         (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6591                                              (match_operand:SI 2 "small_int_operand" "I")) 4)
6592                      (match_operand:SI 3 "small_int_operand" "I")))]
6593   "TARGET_ARCH64
6594    && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6595    && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6596    && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6598   operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6600   return "srax\t%1, %2, %0";
6602   [(set_attr "type" "shift")])
6604 (define_insn ""
6605   [(set (match_operand:SI 0 "register_operand" "=r")
6606         (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6607                                              (match_operand:SI 2 "small_int_operand" "I")) 4)
6608                      (match_operand:SI 3 "small_int_operand" "I")))]
6609   "TARGET_ARCH64
6610    && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6611    && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6612    && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6614   operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6616   return "srlx\t%1, %2, %0";
6618   [(set_attr "type" "shift")])
6621 ;; Unconditional and other jump instructions.
6623 (define_insn "jump"
6624   [(set (pc) (label_ref (match_operand 0 "" "")))]
6625   ""
6626   "* return output_ubranch (operands[0], 0, insn);"
6627   [(set_attr "type" "uncond_branch")])
6629 (define_expand "tablejump"
6630   [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
6631               (use (label_ref (match_operand 1 "" "")))])]
6632   ""
6634   gcc_assert (GET_MODE (operands[0]) == CASE_VECTOR_MODE);
6636   /* In pic mode, our address differences are against the base of the
6637      table.  Add that base value back in; CSE ought to be able to combine
6638      the two address loads.  */
6639   if (flag_pic)
6640     {
6641       rtx tmp, tmp2;
6642       tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
6643       tmp2 = operands[0];
6644       if (CASE_VECTOR_MODE != Pmode)
6645         tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
6646       tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
6647       operands[0] = memory_address (Pmode, tmp);
6648     }
6651 (define_insn "*tablejump_sp32"
6652   [(set (pc) (match_operand:SI 0 "address_operand" "p"))
6653    (use (label_ref (match_operand 1 "" "")))]
6654   "! TARGET_ARCH64"
6655   "jmp\t%a0%#"
6656   [(set_attr "type" "uncond_branch")])
6658 (define_insn "*tablejump_sp64"
6659   [(set (pc) (match_operand:DI 0 "address_operand" "p"))
6660    (use (label_ref (match_operand 1 "" "")))]
6661   "TARGET_ARCH64"
6662   "jmp\t%a0%#"
6663   [(set_attr "type" "uncond_branch")])
6666 ;; Jump to subroutine instructions.
6668 (define_expand "call"
6669   ;; Note that this expression is not used for generating RTL.
6670   ;; All the RTL is generated explicitly below.
6671   [(call (match_operand 0 "call_operand" "")
6672          (match_operand 3 "" "i"))]
6673   ;; operands[2] is next_arg_register
6674   ;; operands[3] is struct_value_size_rtx.
6675   ""
6677   rtx fn_rtx;
6679   gcc_assert (GET_MODE (operands[0]) == FUNCTION_MODE);
6681   gcc_assert (GET_CODE (operands[3]) == CONST_INT);
6683   if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
6684     {
6685       /* This is really a PIC sequence.  We want to represent
6686          it as a funny jump so its delay slots can be filled. 
6688          ??? But if this really *is* a CALL, will not it clobber the
6689          call-clobbered registers?  We lose this if it is a JUMP_INSN.
6690          Why cannot we have delay slots filled if it were a CALL?  */
6692       /* We accept negative sizes for untyped calls.  */
6693       if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6694         emit_jump_insn
6695           (gen_rtx_PARALLEL
6696            (VOIDmode,
6697             gen_rtvec (3,
6698                        gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6699                        operands[3],
6700                        gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6701       else
6702         emit_jump_insn
6703           (gen_rtx_PARALLEL
6704            (VOIDmode,
6705             gen_rtvec (2,
6706                        gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6707                        gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6708       goto finish_call;
6709     }
6711   fn_rtx = operands[0];
6713   /* We accept negative sizes for untyped calls.  */
6714   if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6715     emit_call_insn
6716       (gen_rtx_PARALLEL
6717        (VOIDmode,
6718         gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6719                    operands[3],
6720                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6721   else
6722     emit_call_insn
6723       (gen_rtx_PARALLEL
6724        (VOIDmode,
6725         gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6726                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6728  finish_call:
6730   DONE;
6733 ;; We can't use the same pattern for these two insns, because then registers
6734 ;; in the address may not be properly reloaded.
6736 (define_insn "*call_address_sp32"
6737   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6738          (match_operand 1 "" ""))
6739    (clobber (reg:SI 15))]
6740   ;;- Do not use operand 1 for most machines.
6741   "! TARGET_ARCH64"
6742   "call\t%a0, %1%#"
6743   [(set_attr "type" "call")])
6745 (define_insn "*call_symbolic_sp32"
6746   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6747          (match_operand 1 "" ""))
6748    (clobber (reg:SI 15))]
6749   ;;- Do not use operand 1 for most machines.
6750   "! TARGET_ARCH64"
6751   "call\t%a0, %1%#"
6752   [(set_attr "type" "call")])
6754 (define_insn "*call_address_sp64"
6755   [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
6756          (match_operand 1 "" ""))
6757    (clobber (reg:DI 15))]
6758   ;;- Do not use operand 1 for most machines.
6759   "TARGET_ARCH64"
6760   "call\t%a0, %1%#"
6761   [(set_attr "type" "call")])
6763 (define_insn "*call_symbolic_sp64"
6764   [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6765          (match_operand 1 "" ""))
6766    (clobber (reg:DI 15))]
6767   ;;- Do not use operand 1 for most machines.
6768   "TARGET_ARCH64"
6769   "call\t%a0, %1%#"
6770   [(set_attr "type" "call")])
6772 ;; This is a call that wants a structure value.
6773 ;; There is no such critter for v9 (??? we may need one anyway).
6774 (define_insn "*call_address_struct_value_sp32"
6775   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6776          (match_operand 1 "" ""))
6777    (match_operand 2 "immediate_operand" "")
6778    (clobber (reg:SI 15))]
6779   ;;- Do not use operand 1 for most machines.
6780   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6782   operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6783   return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6785   [(set_attr "type" "call_no_delay_slot")
6786    (set_attr "length" "3")])
6788 ;; This is a call that wants a structure value.
6789 ;; There is no such critter for v9 (??? we may need one anyway).
6790 (define_insn "*call_symbolic_struct_value_sp32"
6791   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6792          (match_operand 1 "" ""))
6793    (match_operand 2 "immediate_operand" "")
6794    (clobber (reg:SI 15))]
6795   ;;- Do not use operand 1 for most machines.
6796   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6798   operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6799   return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6801   [(set_attr "type" "call_no_delay_slot")
6802    (set_attr "length" "3")])
6804 ;; This is a call that may want a structure value.  This is used for
6805 ;; untyped_calls.
6806 (define_insn "*call_address_untyped_struct_value_sp32"
6807   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6808          (match_operand 1 "" ""))
6809    (match_operand 2 "immediate_operand" "")
6810    (clobber (reg:SI 15))]
6811   ;;- Do not use operand 1 for most machines.
6812   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6813   "call\t%a0, %1\n\t nop\n\tnop"
6814   [(set_attr "type" "call_no_delay_slot")
6815    (set_attr "length" "3")])
6817 ;; This is a call that may want a structure value.  This is used for
6818 ;; untyped_calls.
6819 (define_insn "*call_symbolic_untyped_struct_value_sp32"
6820   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6821          (match_operand 1 "" ""))
6822    (match_operand 2 "immediate_operand" "")
6823    (clobber (reg:SI 15))]
6824   ;;- Do not use operand 1 for most machines.
6825   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6826   "call\t%a0, %1\n\t nop\n\tnop"
6827   [(set_attr "type" "call_no_delay_slot")
6828    (set_attr "length" "3")])
6830 (define_expand "call_value"
6831   ;; Note that this expression is not used for generating RTL.
6832   ;; All the RTL is generated explicitly below.
6833   [(set (match_operand 0 "register_operand" "=rf")
6834         (call (match_operand 1 "" "")
6835               (match_operand 4 "" "")))]
6836   ;; operand 2 is stack_size_rtx
6837   ;; operand 3 is next_arg_register
6838   ""
6840   rtx fn_rtx;
6841   rtvec vec;
6843   gcc_assert (GET_MODE (operands[1]) == FUNCTION_MODE);
6845   fn_rtx = operands[1];
6847   vec = gen_rtvec (2,
6848                    gen_rtx_SET (VOIDmode, operands[0],
6849                                 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
6850                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
6852   emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
6854   DONE;
6857 (define_insn "*call_value_address_sp32"
6858   [(set (match_operand 0 "" "=rf")
6859         (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
6860               (match_operand 2 "" "")))
6861    (clobber (reg:SI 15))]
6862   ;;- Do not use operand 2 for most machines.
6863   "! TARGET_ARCH64"
6864   "call\t%a1, %2%#"
6865   [(set_attr "type" "call")])
6867 (define_insn "*call_value_symbolic_sp32"
6868   [(set (match_operand 0 "" "=rf")
6869         (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6870               (match_operand 2 "" "")))
6871    (clobber (reg:SI 15))]
6872   ;;- Do not use operand 2 for most machines.
6873   "! TARGET_ARCH64"
6874   "call\t%a1, %2%#"
6875   [(set_attr "type" "call")])
6877 (define_insn "*call_value_address_sp64"
6878   [(set (match_operand 0 "" "")
6879         (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
6880               (match_operand 2 "" "")))
6881    (clobber (reg:DI 15))]
6882   ;;- Do not use operand 2 for most machines.
6883   "TARGET_ARCH64"
6884   "call\t%a1, %2%#"
6885   [(set_attr "type" "call")])
6887 (define_insn "*call_value_symbolic_sp64"
6888   [(set (match_operand 0 "" "")
6889         (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6890               (match_operand 2 "" "")))
6891    (clobber (reg:DI 15))]
6892   ;;- Do not use operand 2 for most machines.
6893   "TARGET_ARCH64"
6894   "call\t%a1, %2%#"
6895   [(set_attr "type" "call")])
6897 (define_expand "untyped_call"
6898   [(parallel [(call (match_operand 0 "" "")
6899                     (const_int 0))
6900               (match_operand:BLK 1 "memory_operand" "")
6901               (match_operand 2 "" "")])]
6902   ""
6904   rtx valreg1 = gen_rtx_REG (DImode, 8);
6905   rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6906   rtx result = operands[1];
6908   /* Pass constm1 to indicate that it may expect a structure value, but
6909      we don't know what size it is.  */
6910   emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
6912   /* Save the function value registers.  */
6913   emit_move_insn (adjust_address (result, DImode, 0), valreg1);
6914   emit_move_insn (adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8),
6915                                   valreg2);
6917   /* The optimizer does not know that the call sets the function value
6918      registers we stored in the result block.  We avoid problems by
6919      claiming that all hard registers are used and clobbered at this
6920      point.  */
6921   emit_insn (gen_blockage ());
6923   DONE;
6926 ;;  Tail call instructions.
6928 (define_expand "sibcall"
6929   [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
6930               (return)])]
6931   ""
6932   "")
6934 (define_insn "*sibcall_symbolic_sp32"
6935   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6936          (match_operand 1 "" ""))
6937    (return)]
6938   "! TARGET_ARCH64"
6939   "* return output_sibcall(insn, operands[0]);"
6940   [(set_attr "type" "sibcall")])
6942 (define_insn "*sibcall_symbolic_sp64"
6943   [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6944          (match_operand 1 "" ""))
6945    (return)]
6946   "TARGET_ARCH64"
6947   "* return output_sibcall(insn, operands[0]);"
6948   [(set_attr "type" "sibcall")])
6950 (define_expand "sibcall_value"
6951   [(parallel [(set (match_operand 0 "register_operand" "=rf")
6952                 (call (match_operand 1 "" "") (const_int 0)))
6953               (return)])]
6954   ""
6955   "")
6957 (define_insn "*sibcall_value_symbolic_sp32"
6958   [(set (match_operand 0 "" "=rf")
6959         (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6960               (match_operand 2 "" "")))
6961    (return)]
6962   "! TARGET_ARCH64"
6963   "* return output_sibcall(insn, operands[1]);"
6964   [(set_attr "type" "sibcall")])
6966 (define_insn "*sibcall_value_symbolic_sp64"
6967   [(set (match_operand 0 "" "")
6968         (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6969               (match_operand 2 "" "")))
6970    (return)]
6971   "TARGET_ARCH64"
6972   "* return output_sibcall(insn, operands[1]);"
6973   [(set_attr "type" "sibcall")])
6976 ;; Special instructions.
6978 (define_expand "prologue"
6979   [(const_int 0)]
6980   ""
6982   sparc_expand_prologue ();
6983   DONE;
6986 ;; The "save register window" insn is modelled as follows so that the DWARF-2
6987 ;; backend automatically emits the required call frame debugging information
6988 ;; while it is parsing it.  Therefore, the pattern should not be modified
6989 ;; without first studying the impact of the changes on the debug info.
6990 ;; [(set (%fp) (%sp))
6991 ;;  (set (%sp) (unspec_volatile [(%sp) (-frame_size)] UNSPECV_SAVEW))
6992 ;;  (set (%i7) (%o7))]
6994 (define_insn "save_register_window<P:mode>"
6995   [(set (reg:P 30) (reg:P 14))
6996    (set (reg:P 14) (unspec_volatile:P [(reg:P 14)
6997                                        (match_operand:P 0 "arith_operand" "rI")] UNSPECV_SAVEW))
6998    (set (reg:P 31) (reg:P 15))]
6999   ""
7000   "save\t%%sp, %0, %%sp"
7001   [(set_attr "type" "savew")])
7003 (define_expand "epilogue"
7004   [(return)]
7005   ""
7007   sparc_expand_epilogue ();
7010 (define_expand "sibcall_epilogue"
7011   [(return)]
7012   ""
7014   sparc_expand_epilogue ();
7015   DONE;
7018 (define_expand "return"
7019   [(return)]
7020   "sparc_can_use_return_insn_p ()"
7021   "")
7023 (define_insn "*return_internal"
7024   [(return)]
7025   ""
7026   "* return output_return (insn);"
7027   [(set_attr "type" "return")
7028    (set (attr "length")
7029         (cond [(eq_attr "leaf_function" "true")
7030                  (if_then_else (eq_attr "empty_delay_slot" "true")
7031                                (const_int 2)
7032                                (const_int 1))
7033                (eq_attr "calls_eh_return" "true")
7034                  (if_then_else (eq_attr "delayed_branch" "true")
7035                                (if_then_else (eq_attr "isa" "v9")
7036                                              (const_int 2)
7037                                              (const_int 3))
7038                                (if_then_else (eq_attr "isa" "v9")
7039                                              (const_int 3)
7040                                              (const_int 4)))
7041                (eq_attr "empty_delay_slot" "true")
7042                  (if_then_else (eq_attr "delayed_branch" "true")
7043                                (const_int 2)
7044                                (const_int 3))
7045               ] (const_int 1)))])
7047 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
7048 ;; all of memory.  This blocks insns from being moved across this point.
7050 (define_insn "blockage"
7051   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7052   ""
7053   ""
7054   [(set_attr "length" "0")])
7056 ;; Prepare to return any type including a structure value.
7058 (define_expand "untyped_return"
7059   [(match_operand:BLK 0 "memory_operand" "")
7060    (match_operand 1 "" "")]
7061   ""
7063   rtx valreg1 = gen_rtx_REG (DImode, 24);
7064   rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
7065   rtx result = operands[0];
7067   if (! TARGET_ARCH64)
7068     {
7069       rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
7070                                          ? 15 : 31));
7071       rtx value = gen_reg_rtx (SImode);
7073       /* Fetch the instruction where we will return to and see if it's an unimp
7074          instruction (the most significant 10 bits will be zero).  If so,
7075          update the return address to skip the unimp instruction.  */
7076       emit_move_insn (value,
7077                       gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
7078       emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
7079       emit_insn (gen_update_return (rtnreg, value));
7080     }
7082   /* Reload the function value registers.  */
7083   emit_move_insn (valreg1, adjust_address (result, DImode, 0));
7084   emit_move_insn (valreg2,
7085                   adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
7087   /* Put USE insns before the return.  */
7088   emit_insn (gen_rtx_USE (VOIDmode, valreg1));
7089   emit_insn (gen_rtx_USE (VOIDmode, valreg2));
7091   /* Construct the return.  */
7092   expand_naked_return ();
7094   DONE;
7097 ;; This is a bit of a hack.  We're incrementing a fixed register (%i7),
7098 ;; and parts of the compiler don't want to believe that the add is needed.
7100 (define_insn "update_return"
7101   [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
7102                (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
7103   "! TARGET_ARCH64"
7105   if (flag_delayed_branch)
7106     return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
7107   else
7108     return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
7110   [(set (attr "type") (const_string "multi"))
7111    (set (attr "length")
7112         (if_then_else (eq_attr "delayed_branch" "true")
7113                       (const_int 3)
7114                       (const_int 4)))])
7116 (define_insn "nop"
7117   [(const_int 0)]
7118   ""
7119   "nop")
7121 (define_expand "indirect_jump"
7122   [(set (pc) (match_operand 0 "address_operand" "p"))]
7123   ""
7124   "")
7126 (define_insn "*branch_sp32"
7127   [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
7128   "! TARGET_ARCH64"
7129  "jmp\t%a0%#"
7130  [(set_attr "type" "uncond_branch")])
7132 (define_insn "*branch_sp64"
7133   [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
7134   "TARGET_ARCH64"
7135   "jmp\t%a0%#"
7136   [(set_attr "type" "uncond_branch")])
7138 (define_expand "nonlocal_goto"
7139   [(match_operand:SI 0 "general_operand" "")
7140    (match_operand:SI 1 "general_operand" "")
7141    (match_operand:SI 2 "general_operand" "")
7142    (match_operand:SI 3 "" "")]
7143   ""
7145   rtx lab = operands[1];
7146   rtx stack = operands[2];
7147   rtx fp = operands[3];
7148   rtx labreg;
7150   /* Trap instruction to flush all the register windows.  */
7151   emit_insn (gen_flush_register_windows ());
7153   /* Load the fp value for the containing fn into %fp.  This is needed
7154      because STACK refers to %fp.  Note that virtual register instantiation
7155      fails if the virtual %fp isn't set from a register.  */
7156   if (GET_CODE (fp) != REG)
7157     fp = force_reg (Pmode, fp);
7158   emit_move_insn (virtual_stack_vars_rtx, fp);
7160   /* Find the containing function's current nonlocal goto handler,
7161      which will do any cleanups and then jump to the label.  */
7162   labreg = gen_rtx_REG (Pmode, 8);
7163   emit_move_insn (labreg, lab);
7165   /* Restore %fp from stack pointer value for containing function.
7166      The restore insn that follows will move this to %sp,
7167      and reload the appropriate value into %fp.  */
7168   emit_move_insn (hard_frame_pointer_rtx, stack);
7170   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
7171   emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
7173   /* ??? The V9-specific version was disabled in rev 1.65.  */
7174   emit_jump_insn (gen_goto_handler_and_restore (labreg));
7175   emit_barrier ();
7176   DONE;
7179 ;; Special trap insn to flush register windows.
7180 (define_insn "flush_register_windows"
7181   [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
7182   ""
7183   { return TARGET_V9 ? "flushw" : "ta\t3"; }
7184   [(set_attr "type" "flushw")])
7186 (define_insn "goto_handler_and_restore"
7187   [(unspec_volatile [(match_operand 0 "register_operand" "=r")] UNSPECV_GOTO)]
7188   "GET_MODE (operands[0]) == Pmode"
7190   if (flag_delayed_branch)
7191     return "jmp\t%0\n\t restore";
7192   else
7193     return "mov\t%0,%%g1\n\trestore\n\tjmp\t%%g1\n\t nop";
7195   [(set (attr "type") (const_string "multi"))
7196    (set (attr "length")
7197         (if_then_else (eq_attr "delayed_branch" "true")
7198                       (const_int 2)
7199                       (const_int 4)))])
7201 ;; For __builtin_setjmp we need to flush register windows iff the function
7202 ;; calls alloca as well, because otherwise the register window might be
7203 ;; saved after %sp adjustment and thus setjmp would crash
7204 (define_expand "builtin_setjmp_setup"
7205   [(match_operand 0 "register_operand" "r")]
7206   ""
7208   emit_insn (gen_do_builtin_setjmp_setup ());
7209   DONE;
7212 (define_insn "do_builtin_setjmp_setup"
7213   [(unspec_volatile [(const_int 0)] UNSPECV_SETJMP)]
7214   ""
7216   if (! current_function_calls_alloca)
7217     return "";
7218   if (! TARGET_V9)
7219     return "\tta\t3\n";
7220   fputs ("\tflushw\n", asm_out_file);
7221   if (flag_pic)
7222     fprintf (asm_out_file, "\tst%c\t%%l7, [%%sp+%d]\n",
7223              TARGET_ARCH64 ? 'x' : 'w',
7224              SPARC_STACK_BIAS + 7 * UNITS_PER_WORD);
7225   fprintf (asm_out_file, "\tst%c\t%%fp, [%%sp+%d]\n",
7226            TARGET_ARCH64 ? 'x' : 'w',
7227            SPARC_STACK_BIAS + 14 * UNITS_PER_WORD);
7228   fprintf (asm_out_file, "\tst%c\t%%i7, [%%sp+%d]\n",
7229            TARGET_ARCH64 ? 'x' : 'w',
7230            SPARC_STACK_BIAS + 15 * UNITS_PER_WORD);
7231   return "";
7233   [(set_attr "type" "multi")
7234    (set (attr "length")
7235         (cond [(eq_attr "calls_alloca" "false")
7236                  (const_int 0)
7237                (eq_attr "isa" "!v9")
7238                  (const_int 1)
7239                (eq_attr "pic" "true")
7240                  (const_int 4)] (const_int 3)))])
7242 ;; Pattern for use after a setjmp to store FP and the return register
7243 ;; into the stack area.
7245 (define_expand "setjmp"
7246   [(const_int 0)]
7247   ""
7249   rtx mem;
7250   
7251   mem = gen_rtx_MEM (Pmode,
7252                      plus_constant (stack_pointer_rtx,
7253                                     SPARC_STACK_BIAS + 14 * UNITS_PER_WORD));
7254   emit_insn (gen_rtx_SET (VOIDmode, mem, frame_pointer_rtx));
7256   mem = gen_rtx_MEM (Pmode,
7257                      plus_constant (stack_pointer_rtx,
7258                                     SPARC_STACK_BIAS + 15 * UNITS_PER_WORD));
7259   emit_insn (gen_rtx_SET (VOIDmode, mem, gen_rtx_REG (Pmode, 31)));
7260   DONE;
7263 ;; Special pattern for the FLUSH instruction.
7265 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
7266 ; of the define_insn otherwise missing a mode.  We make "flush", aka
7267 ; gen_flush, the default one since sparc_initialize_trampoline uses
7268 ; it on SImode mem values.
7270 (define_insn "flush"
7271   [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7272   ""
7273   { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7274   [(set_attr "type" "iflush")])
7276 (define_insn "flushdi"
7277   [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7278   ""
7279   { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7280   [(set_attr "type" "iflush")])
7283 ;; Find first set instructions.
7285 ;; The scan instruction searches from the most significant bit while ffs
7286 ;; searches from the least significant bit.  The bit index and treatment of
7287 ;; zero also differ.  It takes at least 7 instructions to get the proper
7288 ;; result.  Here is an obvious 8 instruction sequence.
7290 ;; XXX
7291 (define_insn "ffssi2"
7292   [(set (match_operand:SI 0 "register_operand" "=&r")
7293         (ffs:SI (match_operand:SI 1 "register_operand" "r")))
7294    (clobber (match_scratch:SI 2 "=&r"))]
7295   "TARGET_SPARCLITE || TARGET_SPARCLET"
7297   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";
7299   [(set_attr "type" "multi")
7300    (set_attr "length" "8")])
7302 ;; ??? This should be a define expand, so that the extra instruction have
7303 ;; a chance of being optimized away.
7305 ;; Disabled because none of the UltraSPARCs implement popc.  The HAL R1
7306 ;; does, but no one uses that and we don't have a switch for it.
7308 ;(define_insn "ffsdi2"
7309 ;  [(set (match_operand:DI 0 "register_operand" "=&r")
7310 ;       (ffs:DI (match_operand:DI 1 "register_operand" "r")))
7311 ;   (clobber (match_scratch:DI 2 "=&r"))]
7312 ;  "TARGET_ARCH64"
7313 ;  "neg\t%1, %2\;xnor\t%1, %2, %2\;popc\t%2, %0\;movzr\t%1, 0, %0"
7314 ;  [(set_attr "type" "multi")
7315 ;   (set_attr "length" "4")])
7319 ;; Peepholes go at the end.
7321 ;; Optimize consecutive loads or stores into ldd and std when possible.
7322 ;; The conditions in which we do this are very restricted and are 
7323 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
7325 (define_peephole2
7326   [(set (match_operand:SI 0 "memory_operand" "")
7327       (const_int 0))
7328    (set (match_operand:SI 1 "memory_operand" "")
7329       (const_int 0))]
7330   "TARGET_V9
7331    && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
7332   [(set (match_dup 0)
7333        (const_int 0))]
7334   "operands[0] = widen_memory_access (operands[0], DImode, 0);")
7336 (define_peephole2
7337   [(set (match_operand:SI 0 "memory_operand" "")
7338       (const_int 0))
7339    (set (match_operand:SI 1 "memory_operand" "")
7340       (const_int 0))]
7341   "TARGET_V9
7342    && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
7343   [(set (match_dup 1)
7344        (const_int 0))]
7345   "operands[1] = widen_memory_access (operands[1], DImode, 0);")
7347 (define_peephole2
7348   [(set (match_operand:SI 0 "register_operand" "")
7349         (match_operand:SI 1 "memory_operand" ""))
7350    (set (match_operand:SI 2 "register_operand" "")
7351         (match_operand:SI 3 "memory_operand" ""))]
7352   "registers_ok_for_ldd_peep (operands[0], operands[2]) 
7353    && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])" 
7354   [(set (match_dup 0)
7355         (match_dup 1))]
7356   "operands[1] = widen_memory_access (operands[1], DImode, 0);
7357    operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
7359 (define_peephole2
7360   [(set (match_operand:SI 0 "memory_operand" "")
7361         (match_operand:SI 1 "register_operand" ""))
7362    (set (match_operand:SI 2 "memory_operand" "")
7363         (match_operand:SI 3 "register_operand" ""))]
7364   "registers_ok_for_ldd_peep (operands[1], operands[3]) 
7365    && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7366   [(set (match_dup 0)
7367         (match_dup 1))]
7368   "operands[0] = widen_memory_access (operands[0], DImode, 0);
7369    operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
7371 (define_peephole2
7372   [(set (match_operand:SF 0 "register_operand" "")
7373         (match_operand:SF 1 "memory_operand" ""))
7374    (set (match_operand:SF 2 "register_operand" "")
7375         (match_operand:SF 3 "memory_operand" ""))]
7376   "registers_ok_for_ldd_peep (operands[0], operands[2]) 
7377    && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
7378   [(set (match_dup 0)
7379         (match_dup 1))]
7380   "operands[1] = widen_memory_access (operands[1], DFmode, 0);
7381    operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
7383 (define_peephole2
7384   [(set (match_operand:SF 0 "memory_operand" "")
7385         (match_operand:SF 1 "register_operand" ""))
7386    (set (match_operand:SF 2 "memory_operand" "")
7387         (match_operand:SF 3 "register_operand" ""))]
7388   "registers_ok_for_ldd_peep (operands[1], operands[3]) 
7389   && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7390   [(set (match_dup 0)
7391         (match_dup 1))]
7392   "operands[0] = widen_memory_access (operands[0], DFmode, 0);
7393    operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
7395 (define_peephole2
7396   [(set (match_operand:SI 0 "register_operand" "")
7397         (match_operand:SI 1 "memory_operand" ""))
7398    (set (match_operand:SI 2 "register_operand" "")
7399         (match_operand:SI 3 "memory_operand" ""))]
7400   "registers_ok_for_ldd_peep (operands[2], operands[0]) 
7401   && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
7402   [(set (match_dup 2)
7403         (match_dup 3))]
7404    "operands[3] = widen_memory_access (operands[3], DImode, 0);
7405     operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
7407 (define_peephole2
7408   [(set (match_operand:SI 0 "memory_operand" "")
7409         (match_operand:SI 1 "register_operand" ""))
7410    (set (match_operand:SI 2 "memory_operand" "")
7411         (match_operand:SI 3 "register_operand" ""))]
7412   "registers_ok_for_ldd_peep (operands[3], operands[1]) 
7413   && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)" 
7414   [(set (match_dup 2)
7415         (match_dup 3))]
7416   "operands[2] = widen_memory_access (operands[2], DImode, 0);
7417    operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
7418    ")
7420 (define_peephole2
7421   [(set (match_operand:SF 0 "register_operand" "")
7422         (match_operand:SF 1 "memory_operand" ""))
7423    (set (match_operand:SF 2 "register_operand" "")
7424         (match_operand:SF 3 "memory_operand" ""))]
7425   "registers_ok_for_ldd_peep (operands[2], operands[0]) 
7426   && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
7427   [(set (match_dup 2)
7428         (match_dup 3))]
7429   "operands[3] = widen_memory_access (operands[3], DFmode, 0);
7430    operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
7432 (define_peephole2
7433   [(set (match_operand:SF 0 "memory_operand" "")
7434         (match_operand:SF 1 "register_operand" ""))
7435    (set (match_operand:SF 2 "memory_operand" "")
7436         (match_operand:SF 3 "register_operand" ""))]
7437   "registers_ok_for_ldd_peep (operands[3], operands[1]) 
7438   && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
7439   [(set (match_dup 2)
7440         (match_dup 3))]
7441   "operands[2] = widen_memory_access (operands[2], DFmode, 0);
7442    operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
7444 ;; Optimize the case of following a reg-reg move with a test
7445 ;; of reg just moved.  Don't allow floating point regs for operand 0 or 1.
7446 ;; This can result from a float to fix conversion.
7448 (define_peephole2
7449   [(set (match_operand:SI 0 "register_operand" "")
7450         (match_operand:SI 1 "register_operand" ""))
7451    (set (reg:CC 100)
7452         (compare:CC (match_operand:SI 2 "register_operand" "")
7453                     (const_int 0)))]
7454   "(rtx_equal_p (operands[2], operands[0])
7455     || rtx_equal_p (operands[2], operands[1]))
7456     && ! SPARC_FP_REG_P (REGNO (operands[0]))
7457     && ! SPARC_FP_REG_P (REGNO (operands[1]))"
7458   [(parallel [(set (match_dup 0) (match_dup 1))
7459               (set (reg:CC 100)
7460                    (compare:CC (match_dup 1) (const_int 0)))])]
7461   "")
7463 (define_peephole2
7464   [(set (match_operand:DI 0 "register_operand" "")
7465         (match_operand:DI 1 "register_operand" ""))
7466    (set (reg:CCX 100)
7467         (compare:CCX (match_operand:DI 2 "register_operand" "")
7468                     (const_int 0)))]
7469   "TARGET_ARCH64
7470    && (rtx_equal_p (operands[2], operands[0])
7471        || rtx_equal_p (operands[2], operands[1]))
7472    && ! SPARC_FP_REG_P (REGNO (operands[0]))
7473    && ! SPARC_FP_REG_P (REGNO (operands[1]))"
7474   [(parallel [(set (match_dup 0) (match_dup 1))
7475               (set (reg:CCX 100)
7476                    (compare:CCX (match_dup 1) (const_int 0)))])]
7477   "")
7480 ;; Prefetch instructions.
7482 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
7483 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
7484 ;; ??? operations.  With DFA we might be able to model this, but it requires a lot of
7485 ;; ??? state.
7486 (define_expand "prefetch"
7487   [(match_operand 0 "address_operand" "")
7488    (match_operand 1 "const_int_operand" "")
7489    (match_operand 2 "const_int_operand" "")]
7490   "TARGET_V9"
7492   if (TARGET_ARCH64)
7493     emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
7494   else
7495     emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
7496   DONE;
7499 (define_insn "prefetch_64"
7500   [(prefetch (match_operand:DI 0 "address_operand" "p")
7501              (match_operand:DI 1 "const_int_operand" "n")
7502              (match_operand:DI 2 "const_int_operand" "n"))]
7503   ""
7505   static const char * const prefetch_instr[2][2] = {
7506     {
7507       "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7508       "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7509     },
7510     {
7511       "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7512       "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7513     }
7514   };
7515   int read_or_write = INTVAL (operands[1]);
7516   int locality = INTVAL (operands[2]);
7518   gcc_assert (read_or_write == 0 || read_or_write == 1);
7519   gcc_assert (locality >= 0 && locality < 4);
7520   return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7522   [(set_attr "type" "load")])
7524 (define_insn "prefetch_32"
7525   [(prefetch (match_operand:SI 0 "address_operand" "p")
7526              (match_operand:SI 1 "const_int_operand" "n")
7527              (match_operand:SI 2 "const_int_operand" "n"))]
7528   ""
7530   static const char * const prefetch_instr[2][2] = {
7531     {
7532       "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7533       "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7534     },
7535     {
7536       "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7537       "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7538     }
7539   };
7540   int read_or_write = INTVAL (operands[1]);
7541   int locality = INTVAL (operands[2]);
7543   gcc_assert (read_or_write == 0 || read_or_write == 1);
7544   gcc_assert (locality >= 0 && locality < 4);
7545   return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7547   [(set_attr "type" "load")])
7550 ;; Trap instructions.
7552 (define_insn "trap"
7553   [(trap_if (const_int 1) (const_int 5))]
7554   ""
7555   "ta\t5"
7556   [(set_attr "type" "trap")])
7558 (define_expand "conditional_trap"
7559   [(trap_if (match_operator 0 "noov_compare_operator" [(match_dup 2) (match_dup 3)])
7560             (match_operand:SI 1 "arith_operand" ""))]
7561   ""
7562   "operands[2] = gen_compare_reg (GET_CODE (operands[0]));
7563    if (GET_MODE (operands[2]) != CCmode && GET_MODE (operands[2]) != CCXmode)
7564      FAIL;
7565    operands[3] = const0_rtx;")
7567 (define_insn ""
7568   [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CC 100) (const_int 0)])
7569             (match_operand:SI 1 "arith_operand" "rM"))]
7570   ""
7572   if (TARGET_V9)
7573     return "t%C0\t%%icc, %1";
7574   else
7575     return "t%C0\t%1";
7577   [(set_attr "type" "trap")])
7579 (define_insn ""
7580   [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CCX 100) (const_int 0)])
7581             (match_operand:SI 1 "arith_operand" "rM"))]
7582   "TARGET_V9"
7583   "t%C0\t%%xcc, %1"
7584   [(set_attr "type" "trap")])
7587 ;; TLS support instructions.
7589 (define_insn "tgd_hi22"
7590   [(set (match_operand:SI 0 "register_operand" "=r")
7591         (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
7592                             UNSPEC_TLSGD)))]
7593   "TARGET_TLS"
7594   "sethi\\t%%tgd_hi22(%a1), %0")
7596 (define_insn "tgd_lo10"
7597   [(set (match_operand:SI 0 "register_operand" "=r")
7598         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7599                    (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
7600                               UNSPEC_TLSGD)))]
7601   "TARGET_TLS"
7602   "add\\t%1, %%tgd_lo10(%a2), %0")
7604 (define_insn "tgd_add32"
7605   [(set (match_operand:SI 0 "register_operand" "=r")
7606         (plus:SI (match_operand:SI 1 "register_operand" "r")
7607                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7608                              (match_operand 3 "tgd_symbolic_operand" "")]
7609                             UNSPEC_TLSGD)))]
7610   "TARGET_TLS && TARGET_ARCH32"
7611   "add\\t%1, %2, %0, %%tgd_add(%a3)")
7613 (define_insn "tgd_add64"
7614   [(set (match_operand:DI 0 "register_operand" "=r")
7615         (plus:DI (match_operand:DI 1 "register_operand" "r")
7616                  (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7617                              (match_operand 3 "tgd_symbolic_operand" "")]
7618                             UNSPEC_TLSGD)))]
7619   "TARGET_TLS && TARGET_ARCH64"
7620   "add\\t%1, %2, %0, %%tgd_add(%a3)")
7622 (define_insn "tgd_call32"
7623   [(set (match_operand 0 "register_operand" "=r")
7624         (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
7625                                   (match_operand 2 "tgd_symbolic_operand" "")]
7626                                  UNSPEC_TLSGD))
7627               (match_operand 3 "" "")))
7628    (clobber (reg:SI 15))]
7629   "TARGET_TLS && TARGET_ARCH32"
7630   "call\t%a1, %%tgd_call(%a2)%#"
7631   [(set_attr "type" "call")])
7633 (define_insn "tgd_call64"
7634   [(set (match_operand 0 "register_operand" "=r")
7635         (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
7636                                   (match_operand 2 "tgd_symbolic_operand" "")]
7637                                  UNSPEC_TLSGD))
7638               (match_operand 3 "" "")))
7639    (clobber (reg:DI 15))]
7640   "TARGET_TLS && TARGET_ARCH64"
7641   "call\t%a1, %%tgd_call(%a2)%#"
7642   [(set_attr "type" "call")])
7644 (define_insn "tldm_hi22"
7645   [(set (match_operand:SI 0 "register_operand" "=r")
7646         (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7647   "TARGET_TLS"
7648   "sethi\\t%%tldm_hi22(%&), %0")
7650 (define_insn "tldm_lo10"
7651   [(set (match_operand:SI 0 "register_operand" "=r")
7652         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7653                     (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7654   "TARGET_TLS"
7655   "add\\t%1, %%tldm_lo10(%&), %0")
7657 (define_insn "tldm_add32"
7658   [(set (match_operand:SI 0 "register_operand" "=r")
7659         (plus:SI (match_operand:SI 1 "register_operand" "r")
7660                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
7661                             UNSPEC_TLSLDM)))]
7662   "TARGET_TLS && TARGET_ARCH32"
7663   "add\\t%1, %2, %0, %%tldm_add(%&)")
7665 (define_insn "tldm_add64"
7666   [(set (match_operand:DI 0 "register_operand" "=r")
7667         (plus:DI (match_operand:DI 1 "register_operand" "r")
7668                  (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
7669                             UNSPEC_TLSLDM)))]
7670   "TARGET_TLS && TARGET_ARCH64"
7671   "add\\t%1, %2, %0, %%tldm_add(%&)")
7673 (define_insn "tldm_call32"
7674   [(set (match_operand 0 "register_operand" "=r")
7675         (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
7676                                  UNSPEC_TLSLDM))
7677               (match_operand 2 "" "")))
7678    (clobber (reg:SI 15))]
7679   "TARGET_TLS && TARGET_ARCH32"
7680   "call\t%a1, %%tldm_call(%&)%#"
7681   [(set_attr "type" "call")])
7683 (define_insn "tldm_call64"
7684   [(set (match_operand 0 "register_operand" "=r")
7685         (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
7686                                  UNSPEC_TLSLDM))
7687               (match_operand 2 "" "")))
7688    (clobber (reg:DI 15))]
7689   "TARGET_TLS && TARGET_ARCH64"
7690   "call\t%a1, %%tldm_call(%&)%#"
7691   [(set_attr "type" "call")])
7693 (define_insn "tldo_hix22"
7694   [(set (match_operand:SI 0 "register_operand" "=r")
7695         (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
7696                             UNSPEC_TLSLDO)))]
7697   "TARGET_TLS"
7698   "sethi\\t%%tldo_hix22(%a1), %0")
7700 (define_insn "tldo_lox10"
7701   [(set (match_operand:SI 0 "register_operand" "=r")
7702         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7703                    (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
7704                               UNSPEC_TLSLDO)))]
7705   "TARGET_TLS"
7706   "xor\\t%1, %%tldo_lox10(%a2), %0")
7708 (define_insn "tldo_add32"
7709   [(set (match_operand:SI 0 "register_operand" "=r")
7710         (plus:SI (match_operand:SI 1 "register_operand" "r")
7711                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7712                              (match_operand 3 "tld_symbolic_operand" "")]
7713                             UNSPEC_TLSLDO)))]
7714   "TARGET_TLS && TARGET_ARCH32"
7715   "add\\t%1, %2, %0, %%tldo_add(%a3)")
7717 (define_insn "tldo_add64"
7718   [(set (match_operand:DI 0 "register_operand" "=r")
7719         (plus:DI (match_operand:DI 1 "register_operand" "r")
7720                  (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7721                              (match_operand 3 "tld_symbolic_operand" "")]
7722                             UNSPEC_TLSLDO)))]
7723   "TARGET_TLS && TARGET_ARCH64"
7724   "add\\t%1, %2, %0, %%tldo_add(%a3)")
7726 (define_insn "tie_hi22"
7727   [(set (match_operand:SI 0 "register_operand" "=r")
7728         (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
7729                             UNSPEC_TLSIE)))]
7730   "TARGET_TLS"
7731   "sethi\\t%%tie_hi22(%a1), %0")
7733 (define_insn "tie_lo10"
7734   [(set (match_operand:SI 0 "register_operand" "=r")
7735         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7736                    (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
7737                               UNSPEC_TLSIE)))]
7738   "TARGET_TLS"
7739   "add\\t%1, %%tie_lo10(%a2), %0")
7741 (define_insn "tie_ld32"
7742   [(set (match_operand:SI 0 "register_operand" "=r")
7743         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
7744                     (match_operand:SI 2 "register_operand" "r")
7745                     (match_operand 3 "tie_symbolic_operand" "")]
7746                    UNSPEC_TLSIE))]
7747   "TARGET_TLS && TARGET_ARCH32"
7748   "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
7749   [(set_attr "type" "load")])
7751 (define_insn "tie_ld64"
7752   [(set (match_operand:DI 0 "register_operand" "=r")
7753         (unspec:DI [(match_operand:DI 1 "register_operand" "r")
7754                     (match_operand:SI 2 "register_operand" "r")
7755                     (match_operand 3 "tie_symbolic_operand" "")]
7756                    UNSPEC_TLSIE))]
7757   "TARGET_TLS && TARGET_ARCH64"
7758   "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
7759   [(set_attr "type" "load")])
7761 (define_insn "tie_add32"
7762   [(set (match_operand:SI 0 "register_operand" "=r")
7763         (plus:SI (match_operand:SI 1 "register_operand" "r")
7764                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7765                              (match_operand 3 "tie_symbolic_operand" "")]
7766                             UNSPEC_TLSIE)))]
7767   "TARGET_SUN_TLS && TARGET_ARCH32"
7768   "add\\t%1, %2, %0, %%tie_add(%a3)")
7770 (define_insn "tie_add64"
7771   [(set (match_operand:DI 0 "register_operand" "=r")
7772         (plus:DI (match_operand:DI 1 "register_operand" "r")
7773                  (unspec:DI [(match_operand:DI 2 "register_operand" "r")
7774                              (match_operand 3 "tie_symbolic_operand" "")]
7775                             UNSPEC_TLSIE)))]
7776   "TARGET_SUN_TLS && TARGET_ARCH64"
7777   "add\\t%1, %2, %0, %%tie_add(%a3)")
7779 (define_insn "tle_hix22_sp32"
7780   [(set (match_operand:SI 0 "register_operand" "=r")
7781         (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
7782                             UNSPEC_TLSLE)))]
7783   "TARGET_TLS && TARGET_ARCH32"
7784   "sethi\\t%%tle_hix22(%a1), %0")
7786 (define_insn "tle_lox10_sp32"
7787   [(set (match_operand:SI 0 "register_operand" "=r")
7788         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7789                    (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
7790                               UNSPEC_TLSLE)))]
7791   "TARGET_TLS && TARGET_ARCH32"
7792   "xor\\t%1, %%tle_lox10(%a2), %0")
7794 (define_insn "tle_hix22_sp64"
7795   [(set (match_operand:DI 0 "register_operand" "=r")
7796         (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
7797                             UNSPEC_TLSLE)))]
7798   "TARGET_TLS && TARGET_ARCH64"
7799   "sethi\\t%%tle_hix22(%a1), %0")
7801 (define_insn "tle_lox10_sp64"
7802   [(set (match_operand:DI 0 "register_operand" "=r")
7803         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
7804                    (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
7805                               UNSPEC_TLSLE)))]
7806   "TARGET_TLS && TARGET_ARCH64"
7807   "xor\\t%1, %%tle_lox10(%a2), %0")
7809 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
7810 (define_insn "*tldo_ldub_sp32"
7811   [(set (match_operand:QI 0 "register_operand" "=r")
7812         (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7813                                      (match_operand 3 "tld_symbolic_operand" "")]
7814                                     UNSPEC_TLSLDO)
7815                          (match_operand:SI 1 "register_operand" "r"))))]
7816   "TARGET_TLS && TARGET_ARCH32"
7817   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7818   [(set_attr "type" "load")
7819    (set_attr "us3load_type" "3cycle")])
7821 (define_insn "*tldo_ldub1_sp32"
7822   [(set (match_operand:HI 0 "register_operand" "=r")
7823         (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7824                                                      (match_operand 3 "tld_symbolic_operand" "")]
7825                                                     UNSPEC_TLSLDO)
7826                                          (match_operand:SI 1 "register_operand" "r")))))]
7827   "TARGET_TLS && TARGET_ARCH32"
7828   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7829   [(set_attr "type" "load")
7830    (set_attr "us3load_type" "3cycle")])
7832 (define_insn "*tldo_ldub2_sp32"
7833   [(set (match_operand:SI 0 "register_operand" "=r")
7834         (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7835                                                      (match_operand 3 "tld_symbolic_operand" "")]
7836                                                     UNSPEC_TLSLDO)
7837                                          (match_operand:SI 1 "register_operand" "r")))))]
7838   "TARGET_TLS && TARGET_ARCH32"
7839   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7840   [(set_attr "type" "load")
7841    (set_attr "us3load_type" "3cycle")])
7843 (define_insn "*tldo_ldsb1_sp32"
7844   [(set (match_operand:HI 0 "register_operand" "=r")
7845         (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7846                                                      (match_operand 3 "tld_symbolic_operand" "")]
7847                                                     UNSPEC_TLSLDO)
7848                                          (match_operand:SI 1 "register_operand" "r")))))]
7849   "TARGET_TLS && TARGET_ARCH32"
7850   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7851   [(set_attr "type" "sload")
7852    (set_attr "us3load_type" "3cycle")])
7854 (define_insn "*tldo_ldsb2_sp32"
7855   [(set (match_operand:SI 0 "register_operand" "=r")
7856         (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7857                                                      (match_operand 3 "tld_symbolic_operand" "")]
7858                                                     UNSPEC_TLSLDO)
7859                                          (match_operand:SI 1 "register_operand" "r")))))]
7860   "TARGET_TLS && TARGET_ARCH32"
7861   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7862   [(set_attr "type" "sload")
7863    (set_attr "us3load_type" "3cycle")])
7865 (define_insn "*tldo_ldub_sp64"
7866   [(set (match_operand:QI 0 "register_operand" "=r")
7867         (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7868                                      (match_operand 3 "tld_symbolic_operand" "")]
7869                                     UNSPEC_TLSLDO)
7870                          (match_operand:DI 1 "register_operand" "r"))))]
7871   "TARGET_TLS && TARGET_ARCH64"
7872   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7873   [(set_attr "type" "load")
7874    (set_attr "us3load_type" "3cycle")])
7876 (define_insn "*tldo_ldub1_sp64"
7877   [(set (match_operand:HI 0 "register_operand" "=r")
7878         (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7879                                                      (match_operand 3 "tld_symbolic_operand" "")]
7880                                                     UNSPEC_TLSLDO)
7881                                          (match_operand:DI 1 "register_operand" "r")))))]
7882   "TARGET_TLS && TARGET_ARCH64"
7883   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7884   [(set_attr "type" "load")
7885    (set_attr "us3load_type" "3cycle")])
7887 (define_insn "*tldo_ldub2_sp64"
7888   [(set (match_operand:SI 0 "register_operand" "=r")
7889         (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7890                                                      (match_operand 3 "tld_symbolic_operand" "")]
7891                                                     UNSPEC_TLSLDO)
7892                                          (match_operand:DI 1 "register_operand" "r")))))]
7893   "TARGET_TLS && TARGET_ARCH64"
7894   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7895   [(set_attr "type" "load")
7896    (set_attr "us3load_type" "3cycle")])
7898 (define_insn "*tldo_ldub3_sp64"
7899   [(set (match_operand:DI 0 "register_operand" "=r")
7900         (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7901                                                      (match_operand 3 "tld_symbolic_operand" "")]
7902                                                     UNSPEC_TLSLDO)
7903                                          (match_operand:DI 1 "register_operand" "r")))))]
7904   "TARGET_TLS && TARGET_ARCH64"
7905   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7906   [(set_attr "type" "load")
7907    (set_attr "us3load_type" "3cycle")])
7909 (define_insn "*tldo_ldsb1_sp64"
7910   [(set (match_operand:HI 0 "register_operand" "=r")
7911         (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7912                                                      (match_operand 3 "tld_symbolic_operand" "")]
7913                                                     UNSPEC_TLSLDO)
7914                                          (match_operand:DI 1 "register_operand" "r")))))]
7915   "TARGET_TLS && TARGET_ARCH64"
7916   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7917   [(set_attr "type" "sload")
7918    (set_attr "us3load_type" "3cycle")])
7920 (define_insn "*tldo_ldsb2_sp64"
7921   [(set (match_operand:SI 0 "register_operand" "=r")
7922         (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7923                                                      (match_operand 3 "tld_symbolic_operand" "")]
7924                                                     UNSPEC_TLSLDO)
7925                                          (match_operand:DI 1 "register_operand" "r")))))]
7926   "TARGET_TLS && TARGET_ARCH64"
7927   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7928   [(set_attr "type" "sload")
7929    (set_attr "us3load_type" "3cycle")])
7931 (define_insn "*tldo_ldsb3_sp64"
7932   [(set (match_operand:DI 0 "register_operand" "=r")
7933         (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7934                                                      (match_operand 3 "tld_symbolic_operand" "")]
7935                                                     UNSPEC_TLSLDO)
7936                                          (match_operand:DI 1 "register_operand" "r")))))]
7937   "TARGET_TLS && TARGET_ARCH64"
7938   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7939   [(set_attr "type" "sload")
7940    (set_attr "us3load_type" "3cycle")])
7942 (define_insn "*tldo_lduh_sp32"
7943   [(set (match_operand:HI 0 "register_operand" "=r")
7944         (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7945                                      (match_operand 3 "tld_symbolic_operand" "")]
7946                                     UNSPEC_TLSLDO)
7947                          (match_operand:SI 1 "register_operand" "r"))))]
7948   "TARGET_TLS && TARGET_ARCH32"
7949   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7950   [(set_attr "type" "load")
7951    (set_attr "us3load_type" "3cycle")])
7953 (define_insn "*tldo_lduh1_sp32"
7954   [(set (match_operand:SI 0 "register_operand" "=r")
7955         (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7956                                                      (match_operand 3 "tld_symbolic_operand" "")]
7957                                                     UNSPEC_TLSLDO)
7958                                          (match_operand:SI 1 "register_operand" "r")))))]
7959   "TARGET_TLS && TARGET_ARCH32"
7960   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7961   [(set_attr "type" "load")
7962    (set_attr "us3load_type" "3cycle")])
7964 (define_insn "*tldo_ldsh1_sp32"
7965   [(set (match_operand:SI 0 "register_operand" "=r")
7966         (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7967                                                      (match_operand 3 "tld_symbolic_operand" "")]
7968                                                     UNSPEC_TLSLDO)
7969                                          (match_operand:SI 1 "register_operand" "r")))))]
7970   "TARGET_TLS && TARGET_ARCH32"
7971   "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7972   [(set_attr "type" "sload")
7973    (set_attr "us3load_type" "3cycle")])
7975 (define_insn "*tldo_lduh_sp64"
7976   [(set (match_operand:HI 0 "register_operand" "=r")
7977         (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7978                                      (match_operand 3 "tld_symbolic_operand" "")]
7979                                     UNSPEC_TLSLDO)
7980                          (match_operand:DI 1 "register_operand" "r"))))]
7981   "TARGET_TLS && TARGET_ARCH64"
7982   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7983   [(set_attr "type" "load")
7984    (set_attr "us3load_type" "3cycle")])
7986 (define_insn "*tldo_lduh1_sp64"
7987   [(set (match_operand:SI 0 "register_operand" "=r")
7988         (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7989                                                      (match_operand 3 "tld_symbolic_operand" "")]
7990                                                     UNSPEC_TLSLDO)
7991                                          (match_operand:DI 1 "register_operand" "r")))))]
7992   "TARGET_TLS && TARGET_ARCH64"
7993   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7994   [(set_attr "type" "load")
7995    (set_attr "us3load_type" "3cycle")])
7997 (define_insn "*tldo_lduh2_sp64"
7998   [(set (match_operand:DI 0 "register_operand" "=r")
7999         (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8000                                                      (match_operand 3 "tld_symbolic_operand" "")]
8001                                                     UNSPEC_TLSLDO)
8002                                          (match_operand:DI 1 "register_operand" "r")))))]
8003   "TARGET_TLS && TARGET_ARCH64"
8004   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8005   [(set_attr "type" "load")
8006    (set_attr "us3load_type" "3cycle")])
8008 (define_insn "*tldo_ldsh1_sp64"
8009   [(set (match_operand:SI 0 "register_operand" "=r")
8010         (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8011                                                      (match_operand 3 "tld_symbolic_operand" "")]
8012                                                     UNSPEC_TLSLDO)
8013                                          (match_operand:DI 1 "register_operand" "r")))))]
8014   "TARGET_TLS && TARGET_ARCH64"
8015   "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8016   [(set_attr "type" "sload")
8017    (set_attr "us3load_type" "3cycle")])
8019 (define_insn "*tldo_ldsh2_sp64"
8020   [(set (match_operand:DI 0 "register_operand" "=r")
8021         (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8022                                                      (match_operand 3 "tld_symbolic_operand" "")]
8023                                                     UNSPEC_TLSLDO)
8024                                          (match_operand:DI 1 "register_operand" "r")))))]
8025   "TARGET_TLS && TARGET_ARCH64"
8026   "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8027   [(set_attr "type" "sload")
8028    (set_attr "us3load_type" "3cycle")])
8030 (define_insn "*tldo_lduw_sp32"
8031   [(set (match_operand:SI 0 "register_operand" "=r")
8032         (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8033                                      (match_operand 3 "tld_symbolic_operand" "")]
8034                                     UNSPEC_TLSLDO)
8035                          (match_operand:SI 1 "register_operand" "r"))))]
8036   "TARGET_TLS && TARGET_ARCH32"
8037   "ld\t[%1 + %2], %0, %%tldo_add(%3)"
8038   [(set_attr "type" "load")])
8040 (define_insn "*tldo_lduw_sp64"
8041   [(set (match_operand:SI 0 "register_operand" "=r")
8042         (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8043                                      (match_operand 3 "tld_symbolic_operand" "")]
8044                                     UNSPEC_TLSLDO)
8045                          (match_operand:DI 1 "register_operand" "r"))))]
8046   "TARGET_TLS && TARGET_ARCH64"
8047   "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8048   [(set_attr "type" "load")])
8050 (define_insn "*tldo_lduw1_sp64"
8051   [(set (match_operand:DI 0 "register_operand" "=r")
8052         (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8053                                                      (match_operand 3 "tld_symbolic_operand" "")]
8054                                                     UNSPEC_TLSLDO)
8055                                          (match_operand:DI 1 "register_operand" "r")))))]
8056   "TARGET_TLS && TARGET_ARCH64"
8057   "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8058   [(set_attr "type" "load")])
8060 (define_insn "*tldo_ldsw1_sp64"
8061   [(set (match_operand:DI 0 "register_operand" "=r")
8062         (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8063                                                      (match_operand 3 "tld_symbolic_operand" "")]
8064                                                     UNSPEC_TLSLDO)
8065                                          (match_operand:DI 1 "register_operand" "r")))))]
8066   "TARGET_TLS && TARGET_ARCH64"
8067   "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
8068   [(set_attr "type" "sload")
8069    (set_attr "us3load_type" "3cycle")])
8071 (define_insn "*tldo_ldx_sp64"
8072   [(set (match_operand:DI 0 "register_operand" "=r")
8073         (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8074                                      (match_operand 3 "tld_symbolic_operand" "")]
8075                                     UNSPEC_TLSLDO)
8076                          (match_operand:DI 1 "register_operand" "r"))))]
8077   "TARGET_TLS && TARGET_ARCH64"
8078   "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
8079   [(set_attr "type" "load")])
8081 (define_insn "*tldo_stb_sp32"
8082   [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8083                                      (match_operand 3 "tld_symbolic_operand" "")]
8084                                     UNSPEC_TLSLDO)
8085                          (match_operand:SI 1 "register_operand" "r")))
8086         (match_operand:QI 0 "register_operand" "=r"))]
8087   "TARGET_TLS && TARGET_ARCH32"
8088   "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8089   [(set_attr "type" "store")])
8091 (define_insn "*tldo_stb_sp64"
8092   [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8093                                      (match_operand 3 "tld_symbolic_operand" "")]
8094                                     UNSPEC_TLSLDO)
8095                          (match_operand:DI 1 "register_operand" "r")))
8096         (match_operand:QI 0 "register_operand" "=r"))]
8097   "TARGET_TLS && TARGET_ARCH64"
8098   "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8099   [(set_attr "type" "store")])
8101 (define_insn "*tldo_sth_sp32"
8102   [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8103                                      (match_operand 3 "tld_symbolic_operand" "")]
8104                                     UNSPEC_TLSLDO)
8105                          (match_operand:SI 1 "register_operand" "r")))
8106         (match_operand:HI 0 "register_operand" "=r"))]
8107   "TARGET_TLS && TARGET_ARCH32"
8108   "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8109   [(set_attr "type" "store")])
8111 (define_insn "*tldo_sth_sp64"
8112   [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8113                                      (match_operand 3 "tld_symbolic_operand" "")]
8114                                     UNSPEC_TLSLDO)
8115                          (match_operand:DI 1 "register_operand" "r")))
8116         (match_operand:HI 0 "register_operand" "=r"))]
8117   "TARGET_TLS && TARGET_ARCH64"
8118   "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8119   [(set_attr "type" "store")])
8121 (define_insn "*tldo_stw_sp32"
8122   [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8123                                      (match_operand 3 "tld_symbolic_operand" "")]
8124                                     UNSPEC_TLSLDO)
8125                          (match_operand:SI 1 "register_operand" "r")))
8126         (match_operand:SI 0 "register_operand" "=r"))]
8127   "TARGET_TLS && TARGET_ARCH32"
8128   "st\t%0, [%1 + %2], %%tldo_add(%3)"
8129   [(set_attr "type" "store")])
8131 (define_insn "*tldo_stw_sp64"
8132   [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8133                                      (match_operand 3 "tld_symbolic_operand" "")]
8134                                     UNSPEC_TLSLDO)
8135                          (match_operand:DI 1 "register_operand" "r")))
8136         (match_operand:SI 0 "register_operand" "=r"))]
8137   "TARGET_TLS && TARGET_ARCH64"
8138   "stw\t%0, [%1 + %2], %%tldo_add(%3)"
8139   [(set_attr "type" "store")])
8141 (define_insn "*tldo_stx_sp64"
8142   [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8143                                      (match_operand 3 "tld_symbolic_operand" "")]
8144                                     UNSPEC_TLSLDO)
8145                          (match_operand:DI 1 "register_operand" "r")))
8146         (match_operand:DI 0 "register_operand" "=r"))]
8147   "TARGET_TLS && TARGET_ARCH64"
8148   "stx\t%0, [%1 + %2], %%tldo_add(%3)"
8149   [(set_attr "type" "store")])
8152 ;; Stack protector instructions.
8154 (define_expand "stack_protect_set"
8155   [(match_operand 0 "memory_operand" "")
8156    (match_operand 1 "memory_operand" "")]
8157   ""
8159 #ifdef TARGET_THREAD_SSP_OFFSET
8160   rtx tlsreg = gen_rtx_REG (Pmode, 7);
8161   rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
8162   operands[1] = gen_rtx_MEM (Pmode, addr);
8163 #endif
8164   if (TARGET_ARCH64)
8165     emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
8166   else
8167     emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
8168   DONE;
8171 (define_insn "stack_protect_setsi"
8172   [(set (match_operand:SI 0 "memory_operand" "=m")
8173         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
8174    (set (match_scratch:SI 2 "=&r") (const_int 0))]
8175   "TARGET_ARCH32"
8176   "ld\t%1, %2\;st\t%2, %0\;mov\t0, %2"
8177   [(set_attr "type" "multi")
8178    (set_attr "length" "3")])
8180 (define_insn "stack_protect_setdi"
8181   [(set (match_operand:DI 0 "memory_operand" "=m")
8182         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
8183    (set (match_scratch:DI 2 "=&r") (const_int 0))]
8184   "TARGET_ARCH64"
8185   "ldx\t%1, %2\;stx\t%2, %0\;mov\t0, %2"
8186   [(set_attr "type" "multi")
8187    (set_attr "length" "3")])
8189 (define_expand "stack_protect_test"
8190   [(match_operand 0 "memory_operand" "")
8191    (match_operand 1 "memory_operand" "")
8192    (match_operand 2 "" "")]
8193   ""
8195 #ifdef TARGET_THREAD_SSP_OFFSET
8196   rtx tlsreg = gen_rtx_REG (Pmode, 7);
8197   rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
8198   operands[1] = gen_rtx_MEM (Pmode, addr);
8199 #endif
8200   if (TARGET_ARCH64)
8201     {
8202       rtx temp = gen_reg_rtx (Pmode);
8203       emit_insn (gen_stack_protect_testdi (temp, operands[0], operands[1]));
8204       sparc_compare_op0 = temp;
8205       sparc_compare_op1 = const0_rtx;
8206     }
8207   else
8208     {
8209       emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
8210       sparc_compare_op0 = operands[0];
8211       sparc_compare_op1 = operands[1];
8212       sparc_compare_emitted = gen_rtx_REG (CCmode, SPARC_ICC_REG);
8213     }
8214   emit_jump_insn (gen_beq (operands[2]));
8215   DONE;
8218 (define_insn "stack_protect_testsi"
8219   [(set (reg:CC 100)
8220         (unspec:CC [(match_operand:SI 0 "memory_operand" "m")
8221                     (match_operand:SI 1 "memory_operand" "m")]
8222                    UNSPEC_SP_TEST))
8223    (set (match_scratch:SI 3 "=r") (const_int 0))
8224    (clobber (match_scratch:SI 2 "=&r"))]
8225   "TARGET_ARCH32"
8226   "ld\t%0, %2\;ld\t%1, %3\;xorcc\t%2, %3, %2\;mov\t0, %3"
8227   [(set_attr "type" "multi")
8228    (set_attr "length" "4")])
8230 (define_insn "stack_protect_testdi"
8231   [(set (match_operand:DI 0 "register_operand" "=&r")
8232         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
8233                     (match_operand:DI 2 "memory_operand" "m")]
8234                    UNSPEC_SP_TEST))
8235    (set (match_scratch:DI 3 "=r") (const_int 0))]
8236   "TARGET_ARCH64"
8237   "ldx\t%1, %0\;ldx\t%2, %3\;xor\t%0, %3, %0\;mov\t0, %3"
8238   [(set_attr "type" "multi")
8239    (set_attr "length" "4")])
8242 ;; Vector instructions.
8244 (define_insn "addv2si3"
8245   [(set (match_operand:V2SI 0 "register_operand" "=e")
8246         (plus:V2SI (match_operand:V2SI 1 "register_operand" "e")
8247                    (match_operand:V2SI 2 "register_operand" "e")))]
8248   "TARGET_VIS"
8249   "fpadd32\t%1, %2, %0"
8250   [(set_attr "type" "fga")
8251    (set_attr "fptype" "double")])
8253 (define_insn "addv4hi3"
8254   [(set (match_operand:V4HI 0 "register_operand" "=e")
8255          (plus:V4HI (match_operand:V4HI 1 "register_operand" "e")
8256                     (match_operand:V4HI 2 "register_operand" "e")))]
8257   "TARGET_VIS"
8258   "fpadd16\t%1, %2, %0"
8259   [(set_attr "type" "fga")
8260    (set_attr "fptype" "double")])
8262 ;; fpadd32s is emitted by the addsi3 pattern.
8264 (define_insn "addv2hi3"
8265   [(set (match_operand:V2HI 0 "register_operand" "=f")
8266         (plus:V2HI (match_operand:V2HI 1 "register_operand" "f")
8267                    (match_operand:V2HI 2 "register_operand" "f")))]
8268   "TARGET_VIS"
8269   "fpadd16s\t%1, %2, %0"
8270   [(set_attr "type" "fga")
8271    (set_attr "fptype" "single")])
8273 (define_insn "subv2si3"
8274   [(set (match_operand:V2SI 0 "register_operand" "=e")
8275         (minus:V2SI (match_operand:V2SI 1 "register_operand" "e")
8276                     (match_operand:V2SI 2 "register_operand" "e")))]
8277   "TARGET_VIS"
8278   "fpsub32\t%1, %2, %0"
8279   [(set_attr "type" "fga")
8280    (set_attr "fptype" "double")])
8282 (define_insn "subv4hi3"
8283   [(set (match_operand:V4HI 0 "register_operand" "=e")
8284         (minus:V4HI (match_operand:V4HI 1 "register_operand" "e")
8285                     (match_operand:V4HI 2 "register_operand" "e")))]
8286   "TARGET_VIS"
8287   "fpsub16\t%1, %2, %0"
8288   [(set_attr "type" "fga")
8289    (set_attr "fptype" "double")])
8291 ;; fpsub32s is emitted by the subsi3 pattern.
8293 (define_insn "subv2hi3"
8294   [(set (match_operand:V2HI 0 "register_operand" "=f")
8295         (minus:V2HI (match_operand:V2HI 1 "register_operand" "f")
8296                     (match_operand:V2HI 2 "register_operand" "f")))]
8297   "TARGET_VIS"
8298   "fpsub16s\t%1, %2, %0"
8299   [(set_attr "type" "fga")
8300    (set_attr "fptype" "single")])
8302 ;; All other logical instructions have integer equivalents so they
8303 ;; are defined together.
8305 ;; (ior (not (op1)) (not (op2))) is the canonical form of NAND.
8307 (define_insn "*nand<V64mode>_vis"
8308   [(set (match_operand:V64 0 "register_operand" "=e")
8309         (ior:V64 (not:V64 (match_operand:V64 1 "register_operand" "e"))
8310                  (not:V64 (match_operand:V64 2 "register_operand" "e"))))]
8311   "TARGET_VIS"
8312   "fnand\t%1, %2, %0"
8313   [(set_attr "type" "fga")
8314    (set_attr "fptype" "double")])
8316 (define_insn "*nand<V32mode>_vis"
8317   [(set (match_operand:V32 0 "register_operand" "=f")
8318          (ior:V32 (not:V32 (match_operand:V32 1 "register_operand" "f"))
8319                   (not:V32 (match_operand:V32 2 "register_operand" "f"))))]
8320   "TARGET_VIS"
8321   "fnands\t%1, %2, %0"
8322   [(set_attr "type" "fga")
8323    (set_attr "fptype" "single")])
8325 ;; Hard to generate VIS instructions.  We have builtins for these.
8327 (define_insn "fpack16_vis"
8328   [(set (match_operand:V4QI 0 "register_operand" "=f")
8329         (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e")]
8330                       UNSPEC_FPACK16))]
8331   "TARGET_VIS"
8332   "fpack16\t%1, %0"
8333   [(set_attr "type" "fga")
8334    (set_attr "fptype" "double")])
8336 (define_insn "fpackfix_vis"
8337   [(set (match_operand:V2HI 0 "register_operand" "=f")
8338         (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e")]
8339                       UNSPEC_FPACKFIX))]
8340   "TARGET_VIS"
8341   "fpackfix\t%1, %0"
8342   [(set_attr "type" "fga")
8343    (set_attr "fptype" "double")])
8345 (define_insn "fpack32_vis"
8346   [(set (match_operand:V8QI 0 "register_operand" "=e")
8347         (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e")
8348                       (match_operand:V8QI 2 "register_operand" "e")]
8349                      UNSPEC_FPACK32))]
8350   "TARGET_VIS"
8351   "fpack32\t%1, %2, %0"
8352   [(set_attr "type" "fga")
8353    (set_attr "fptype" "double")])
8355 (define_insn "fexpand_vis"
8356   [(set (match_operand:V4HI 0 "register_operand" "=e")
8357         (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")]
8358          UNSPEC_FEXPAND))]
8359  "TARGET_VIS"
8360  "fexpand\t%1, %0"
8361  [(set_attr "type" "fga")
8362   (set_attr "fptype" "double")])
8364 ;; It may be possible to describe this operation as (1 indexed):
8365 ;; (vec_select (vec_duplicate (vec_duplicate (vec_concat 1 2)))
8366 ;;  1,5,10,14,19,23,28,32)
8367 ;; Note that (vec_merge:V8QI [(V4QI) (V4QI)] (10101010 = 170) doesn't work
8368 ;; because vec_merge expects all the operands to be of the same type.
8369 (define_insn "fpmerge_vis"
8370   [(set (match_operand:V8QI 0 "register_operand" "=e")
8371         (unspec:V8QI [(match_operand:V4QI 1 "register_operand" "f")
8372                       (match_operand:V4QI 2 "register_operand" "f")]
8373          UNSPEC_FPMERGE))]
8374  "TARGET_VIS"
8375  "fpmerge\t%1, %2, %0"
8376  [(set_attr "type" "fga")
8377   (set_attr "fptype" "double")])
8379 ;; Partitioned multiply instructions
8380 (define_insn "fmul8x16_vis"
8381   [(set (match_operand:V4HI 0 "register_operand" "=e")
8382         (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
8383                    (match_operand:V4HI 2 "register_operand" "e")))]
8384   "TARGET_VIS"
8385   "fmul8x16\t%1, %2, %0"
8386   [(set_attr "type" "fpmul")
8387    (set_attr "fptype" "double")])
8389 ;; Only one of the following two insns can be a multiply.
8390 (define_insn "fmul8x16au_vis"
8391   [(set (match_operand:V4HI 0 "register_operand" "=e")
8392         (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
8393                    (match_operand:V2HI 2 "register_operand" "f")))]
8394   "TARGET_VIS"
8395   "fmul8x16au\t%1, %2, %0"
8396   [(set_attr "type" "fpmul")
8397    (set_attr "fptype" "double")])
8399 (define_insn "fmul8x16al_vis"
8400   [(set (match_operand:V4HI 0 "register_operand" "=e")
8401         (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8402                       (match_operand:V2HI 2 "register_operand" "f")]
8403          UNSPEC_MUL16AL))]
8404   "TARGET_VIS"
8405   "fmul8x16al\t%1, %2, %0"
8406   [(set_attr "type" "fpmul")
8407    (set_attr "fptype" "double")])
8409 ;; Only one of the following two insns can be a multiply.
8410 (define_insn "fmul8sux16_vis"
8411   [(set (match_operand:V4HI 0 "register_operand" "=e")
8412         (mult:V4HI (match_operand:V8QI 1 "register_operand" "e")
8413                    (match_operand:V4HI 2 "register_operand" "e")))]
8414   "TARGET_VIS"
8415   "fmul8sux16\t%1, %2, %0"
8416   [(set_attr "type" "fpmul")
8417    (set_attr "fptype" "double")])
8419 (define_insn "fmul8ulx16_vis"
8420   [(set (match_operand:V4HI 0 "register_operand" "=e")
8421         (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
8422                       (match_operand:V4HI 2 "register_operand" "e")]
8423          UNSPEC_MUL8UL))]
8424   "TARGET_VIS"
8425   "fmul8ulx16\t%1, %2, %0"
8426   [(set_attr "type" "fpmul")
8427    (set_attr "fptype" "double")])
8429 ;; Only one of the following two insns can be a multiply.
8430 (define_insn "fmuld8sux16_vis"
8431   [(set (match_operand:V2SI 0 "register_operand" "=e")
8432         (mult:V2SI (match_operand:V4QI 1 "register_operand" "f")
8433                    (match_operand:V2HI 2 "register_operand" "f")))]
8434   "TARGET_VIS"
8435   "fmuld8sux16\t%1, %2, %0"
8436   [(set_attr "type" "fpmul")
8437    (set_attr "fptype" "double")])
8439 (define_insn "fmuld8ulx16_vis"
8440   [(set (match_operand:V2SI 0 "register_operand" "=e")
8441         (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
8442                       (match_operand:V2HI 2 "register_operand" "f")]
8443          UNSPEC_MULDUL))]
8444   "TARGET_VIS"
8445   "fmuld8ulx16\t%1, %2, %0"
8446   [(set_attr "type" "fpmul")
8447    (set_attr "fptype" "double")])
8449 ;; Using faligndata only makes sense after an alignaddr since the choice of
8450 ;; bytes to take out of each operand is dependent on the results of the last
8451 ;; alignaddr.
8452 (define_insn "faligndata<V64I:mode>_vis"
8453   [(set (match_operand:V64I 0 "register_operand" "=e")
8454         (unspec:V64I [(match_operand:V64I 1 "register_operand" "e")
8455                       (match_operand:V64I 2 "register_operand" "e")]
8456          UNSPEC_ALIGNDATA))]
8457   "TARGET_VIS"
8458   "faligndata\t%1, %2, %0"
8459   [(set_attr "type" "fga")
8460    (set_attr "fptype" "double")])
8462 (define_insn "alignaddr<P:mode>_vis"
8463   [(set (match_operand:P 0 "register_operand" "=r")
8464         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8465                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
8466          UNSPEC_ALIGNADDR))]
8467   "TARGET_VIS"
8468   "alignaddr\t%r1, %r2, %0")
8470 (define_insn "pdist_vis"
8471   [(set (match_operand:DI 0 "register_operand" "=e")
8472         (unspec:DI [(match_operand:V8QI 1 "register_operand" "e")
8473                     (match_operand:V8QI 2 "register_operand" "e")
8474                     (match_operand:DI 3 "register_operand" "0")]
8475          UNSPEC_PDIST))]
8476   "TARGET_VIS"
8477   "pdist\t%1, %2, %0"
8478   [(set_attr "type" "fga")
8479    (set_attr "fptype" "double")])
8481 (include "sync.md")