* config/darwin.c, config/darwin.h, config/freebsd-spec.h,
[official-gcc.git] / gcc / config / sparc / sparc.md
blob34839bee7e684d406d0a433053502c9f42cf0e2a
1 ;; Machine description for SPARC chip for GCC
2 ;;  Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 ;;  1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
4 ;;  Contributed by Michael Tiemann (tiemann@cygnus.com)
5 ;;  64-bit SPARC-V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
6 ;;  at Cygnus Support.
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING.  If not, write to
22 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, 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)
60   ])
62 (define_constants
63   [(UNSPECV_BLOCKAGE            0)
64    (UNSPECV_FLUSHW              1)
65    (UNSPECV_GOTO                2)
66    (UNSPECV_FLUSH               4)
67    (UNSPECV_SETJMP              5)
68    (UNSPECV_SAVEW               6)
69   ])
71 ;; The upper 32 fp regs on the v9 can't hold SFmode values.  To deal with this
72 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip.  The name
73 ;; is a bit of a misnomer as it covers all 64 fp regs.  The corresponding
74 ;; constraint letter is 'e'.  To avoid any confusion, 'e' is used instead of
75 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
77 ;; Attribute for cpu type.
78 ;; These must match the values for enum processor_type in sparc.h.
79 (define_attr "cpu"
80   "v7,
81    cypress,
82    v8,
83    supersparc,
84    sparclite,f930,f934,
85    hypersparc,sparclite86x,
86    sparclet,tsc701,
87    v9,
88    ultrasparc,
89    ultrasparc3"
90   (const (symbol_ref "sparc_cpu_attr")))
92 ;; Attribute for the instruction set.
93 ;; At present we only need to distinguish v9/!v9, but for clarity we
94 ;; test TARGET_V8 too.
95 (define_attr "isa" "v7,v8,v9,sparclet"
96  (const
97   (cond [(symbol_ref "TARGET_V9") (const_string "v9")
98          (symbol_ref "TARGET_V8") (const_string "v8")
99          (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
100         (const_string "v7"))))
102 ;; Insn type.
103 (define_attr "type"
104   "ialu,compare,shift,
105    load,sload,store,
106    uncond_branch,branch,call,sibcall,call_no_delay_slot,return,
107    imul,idiv,
108    fpload,fpstore,
109    fp,fpmove,
110    fpcmove,fpcrmove,
111    fpcmp,
112    fpmul,fpdivs,fpdivd,
113    fpsqrts,fpsqrtd,
114    fga,fgm_pack,fgm_mul,fgm_pdist,fgm_cmp,
115    cmove,
116    ialuX,
117    multi,savew,flushw,iflush,trap"
118   (const_string "ialu"))
120 ;; True if branch/call has empty delay slot and will emit a nop in it
121 (define_attr "empty_delay_slot" "false,true"
122   (symbol_ref "empty_delay_slot (insn)"))
124 (define_attr "branch_type" "none,icc,fcc,reg"
125   (const_string "none"))
127 (define_attr "pic" "false,true"
128   (symbol_ref "flag_pic != 0"))
130 (define_attr "calls_alloca" "false,true"
131   (symbol_ref "current_function_calls_alloca != 0"))
133 (define_attr "calls_eh_return" "false,true"
134    (symbol_ref "current_function_calls_eh_return !=0 "))
135    
136 (define_attr "leaf_function" "false,true"
137   (symbol_ref "current_function_uses_only_leaf_regs != 0"))
139 (define_attr "delayed_branch" "false,true"
140   (symbol_ref "flag_delayed_branch != 0"))
142 ;; Length (in # of insns).
143 ;; Beware that setting a length greater or equal to 3 for conditional branches
144 ;; has a side-effect (see output_cbranch and output_v9branch).
145 (define_attr "length" ""
146   (cond [(eq_attr "type" "uncond_branch,call")
147            (if_then_else (eq_attr "empty_delay_slot" "true")
148              (const_int 2)
149              (const_int 1))
150          (eq_attr "type" "sibcall")
151            (if_then_else (eq_attr "leaf_function" "true")
152              (if_then_else (eq_attr "empty_delay_slot" "true")
153                (const_int 3)
154                (const_int 2))
155              (if_then_else (eq_attr "empty_delay_slot" "true")
156                (const_int 2)
157                (const_int 1)))
158          (eq_attr "branch_type" "icc")
159            (if_then_else (match_operand 0 "noov_compare64_op" "")
160              (if_then_else (lt (pc) (match_dup 1))
161                (if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000))
162                  (if_then_else (eq_attr "empty_delay_slot" "true")
163                    (const_int 2)
164                    (const_int 1))
165                  (if_then_else (eq_attr "empty_delay_slot" "true")
166                    (const_int 4)
167                    (const_int 3)))
168                (if_then_else (lt (minus (pc) (match_dup 1)) (const_int 260000))
169                  (if_then_else (eq_attr "empty_delay_slot" "true")
170                    (const_int 2)
171                    (const_int 1))
172                  (if_then_else (eq_attr "empty_delay_slot" "true")
173                    (const_int 4)
174                    (const_int 3))))
175              (if_then_else (eq_attr "empty_delay_slot" "true")
176                (const_int 2)
177                (const_int 1)))
178          (eq_attr "branch_type" "fcc")
179            (if_then_else (match_operand 0 "fcc0_reg_operand" "")
180              (if_then_else (eq_attr "empty_delay_slot" "true")
181                (if_then_else (eq (symbol_ref "TARGET_V9") (const_int 0))
182                  (const_int 3)
183                  (const_int 2))
184                (if_then_else (eq (symbol_ref "TARGET_V9") (const_int 0))
185                  (const_int 2)
186                  (const_int 1)))
187              (if_then_else (lt (pc) (match_dup 2))
188                (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000))
189                  (if_then_else (eq_attr "empty_delay_slot" "true")
190                    (const_int 2)
191                    (const_int 1))
192                  (if_then_else (eq_attr "empty_delay_slot" "true")
193                    (const_int 4)
194                    (const_int 3)))
195                (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000))
196                  (if_then_else (eq_attr "empty_delay_slot" "true")
197                    (const_int 2)
198                    (const_int 1))
199                  (if_then_else (eq_attr "empty_delay_slot" "true")
200                    (const_int 4)
201                    (const_int 3)))))
202          (eq_attr "branch_type" "reg")
203            (if_then_else (lt (pc) (match_dup 2))
204              (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000))
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              (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000))
212                (if_then_else (eq_attr "empty_delay_slot" "true")
213                  (const_int 2)
214                  (const_int 1))
215                (if_then_else (eq_attr "empty_delay_slot" "true")
216                  (const_int 4)
217                  (const_int 3))))
218          ] (const_int 1)))
220 ;; FP precision.
221 (define_attr "fptype" "single,double"
222   (const_string "single"))
224 ;; UltraSPARC-III integer load type.
225 (define_attr "us3load_type" "2cycle,3cycle"
226   (const_string "2cycle"))
228 (define_asm_attributes
229   [(set_attr "length" "2")
230    (set_attr "type" "multi")])
232 ;; Attributes for instruction and branch scheduling
233 (define_attr "tls_call_delay" "false,true"
234   (symbol_ref "tls_call_delay (insn)"))
236 (define_attr "in_call_delay" "false,true"
237   (cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
238                 (const_string "false")
239          (eq_attr "type" "load,fpload,store,fpstore")
240                 (if_then_else (eq_attr "length" "1")
241                               (const_string "true")
242                               (const_string "false"))]
243         (if_then_else (and (eq_attr "length" "1")
244                            (eq_attr "tls_call_delay" "true"))
245                       (const_string "true")
246                       (const_string "false"))))
248 (define_attr "eligible_for_sibcall_delay" "false,true"
249   (symbol_ref "eligible_for_sibcall_delay (insn)"))
251 (define_attr "eligible_for_return_delay" "false,true"
252   (symbol_ref "eligible_for_return_delay (insn)"))
254 ;; ??? !v9: Should implement the notion of predelay slots for floating-point
255 ;; branches.  This would allow us to remove the nop always inserted before
256 ;; a floating point branch.
258 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
259 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
260 ;; This is because doing so will add several pipeline stalls to the path
261 ;; that the load/store did not come from.  Unfortunately, there is no way
262 ;; to prevent fill_eager_delay_slots from using load/store without completely
263 ;; disabling them.  For the SPEC benchmark set, this is a serious lose,
264 ;; because it prevents us from moving back the final store of inner loops.
266 (define_attr "in_branch_delay" "false,true"
267   (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
268                      (eq_attr "length" "1"))
269                 (const_string "true")
270                 (const_string "false")))
272 (define_attr "in_uncond_branch_delay" "false,true"
273   (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
274                      (eq_attr "length" "1"))
275                 (const_string "true")
276                 (const_string "false")))
278 (define_attr "in_annul_branch_delay" "false,true"
279   (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
280                      (eq_attr "length" "1"))
281                 (const_string "true")
282                 (const_string "false")))
284 (define_delay (eq_attr "type" "call")
285   [(eq_attr "in_call_delay" "true") (nil) (nil)])
287 (define_delay (eq_attr "type" "sibcall")
288   [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
290 (define_delay (eq_attr "type" "branch")
291   [(eq_attr "in_branch_delay" "true")
292    (nil) (eq_attr "in_annul_branch_delay" "true")])
294 (define_delay (eq_attr "type" "uncond_branch")
295   [(eq_attr "in_uncond_branch_delay" "true")
296    (nil) (nil)])
298 (define_delay (eq_attr "type" "return")
299   [(eq_attr "eligible_for_return_delay" "true") (nil) (nil)])
301 ;; Include SPARC DFA schedulers
303 (include "cypress.md")
304 (include "supersparc.md")
305 (include "hypersparc.md")
306 (include "sparclet.md")
307 (include "ultra1_2.md")
308 (include "ultra3.md")
311 ;; Compare instructions.
312 ;; This controls RTL generation and register allocation.
314 ;; We generate RTL for comparisons and branches by having the cmpxx 
315 ;; patterns store away the operands.  Then, the scc and bcc patterns
316 ;; emit RTL for both the compare and the branch.
318 ;; We do this because we want to generate different code for an sne and
319 ;; seq insn.  In those cases, if the second operand of the compare is not
320 ;; const0_rtx, we want to compute the xor of the two operands and test
321 ;; it against zero.
323 ;; We start with the DEFINE_EXPANDs, then the DEFINE_INSNs to match
324 ;; the patterns.  Finally, we have the DEFINE_SPLITs for some of the scc
325 ;; insns that actually require more than one machine instruction.
327 ;; Put cmpsi first among compare insns so it matches two CONST_INT operands.
329 (define_expand "cmpsi"
330   [(set (reg:CC 100)
331         (compare:CC (match_operand:SI 0 "compare_operand" "")
332                     (match_operand:SI 1 "arith_operand" "")))]
333   ""
335   if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx)
336     operands[0] = force_reg (SImode, operands[0]);
338   sparc_compare_op0 = operands[0];
339   sparc_compare_op1 = operands[1];
340   DONE;
343 (define_expand "cmpdi"
344   [(set (reg:CCX 100)
345         (compare:CCX (match_operand:DI 0 "compare_operand" "")
346                      (match_operand:DI 1 "arith_double_operand" "")))]
347   "TARGET_ARCH64"
349   if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx)
350     operands[0] = force_reg (DImode, operands[0]);
352   sparc_compare_op0 = operands[0];
353   sparc_compare_op1 = operands[1];
354   DONE;
357 (define_expand "cmpsf"
358   ;; The 96 here isn't ever used by anyone.
359   [(set (reg:CCFP 96)
360         (compare:CCFP (match_operand:SF 0 "register_operand" "")
361                       (match_operand:SF 1 "register_operand" "")))]
362   "TARGET_FPU"
364   sparc_compare_op0 = operands[0];
365   sparc_compare_op1 = operands[1];
366   DONE;
369 (define_expand "cmpdf"
370   ;; The 96 here isn't ever used by anyone.
371   [(set (reg:CCFP 96)
372         (compare:CCFP (match_operand:DF 0 "register_operand" "")
373                       (match_operand:DF 1 "register_operand" "")))]
374   "TARGET_FPU"
376   sparc_compare_op0 = operands[0];
377   sparc_compare_op1 = operands[1];
378   DONE;
381 (define_expand "cmptf"
382   ;; The 96 here isn't ever used by anyone.
383   [(set (reg:CCFP 96)
384         (compare:CCFP (match_operand:TF 0 "register_operand" "")
385                       (match_operand:TF 1 "register_operand" "")))]
386   "TARGET_FPU"
388   sparc_compare_op0 = operands[0];
389   sparc_compare_op1 = operands[1];
390   DONE;
393 ;; Now the compare DEFINE_INSNs.
395 (define_insn "*cmpsi_insn"
396   [(set (reg:CC 100)
397         (compare:CC (match_operand:SI 0 "register_operand" "r")
398                     (match_operand:SI 1 "arith_operand" "rI")))]
399   ""
400   "cmp\t%0, %1"
401   [(set_attr "type" "compare")])
403 (define_insn "*cmpdi_sp64"
404   [(set (reg:CCX 100)
405         (compare:CCX (match_operand:DI 0 "register_operand" "r")
406                      (match_operand:DI 1 "arith_double_operand" "rHI")))]
407   "TARGET_ARCH64"
408   "cmp\t%0, %1"
409   [(set_attr "type" "compare")])
411 (define_insn "*cmpsf_fpe"
412   [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
413         (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
414                        (match_operand:SF 2 "register_operand" "f")))]
415   "TARGET_FPU"
417   if (TARGET_V9)
418     return "fcmpes\t%0, %1, %2";
419   return "fcmpes\t%1, %2";
421   [(set_attr "type" "fpcmp")])
423 (define_insn "*cmpdf_fpe"
424   [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
425         (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
426                        (match_operand:DF 2 "register_operand" "e")))]
427   "TARGET_FPU"
429   if (TARGET_V9)
430     return "fcmped\t%0, %1, %2";
431   return "fcmped\t%1, %2";
433   [(set_attr "type" "fpcmp")
434    (set_attr "fptype" "double")])
436 (define_insn "*cmptf_fpe"
437   [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
438         (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
439                        (match_operand:TF 2 "register_operand" "e")))]
440   "TARGET_FPU && TARGET_HARD_QUAD"
442   if (TARGET_V9)
443     return "fcmpeq\t%0, %1, %2";
444   return "fcmpeq\t%1, %2";
446   [(set_attr "type" "fpcmp")])
448 (define_insn "*cmpsf_fp"
449   [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
450         (compare:CCFP (match_operand:SF 1 "register_operand" "f")
451                       (match_operand:SF 2 "register_operand" "f")))]
452   "TARGET_FPU"
454   if (TARGET_V9)
455     return "fcmps\t%0, %1, %2";
456   return "fcmps\t%1, %2";
458   [(set_attr "type" "fpcmp")])
460 (define_insn "*cmpdf_fp"
461   [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
462         (compare:CCFP (match_operand:DF 1 "register_operand" "e")
463                       (match_operand:DF 2 "register_operand" "e")))]
464   "TARGET_FPU"
466   if (TARGET_V9)
467     return "fcmpd\t%0, %1, %2";
468   return "fcmpd\t%1, %2";
470   [(set_attr "type" "fpcmp")
471    (set_attr "fptype" "double")])
473 (define_insn "*cmptf_fp"
474   [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
475         (compare:CCFP (match_operand:TF 1 "register_operand" "e")
476                       (match_operand:TF 2 "register_operand" "e")))]
477   "TARGET_FPU && TARGET_HARD_QUAD"
479   if (TARGET_V9)
480     return "fcmpq\t%0, %1, %2";
481   return "fcmpq\t%1, %2";
483   [(set_attr "type" "fpcmp")])
485 ;; Next come the scc insns.  For seq, sne, sgeu, and sltu, we can do this
486 ;; without jumps using the addx/subx instructions.  For seq/sne on v9 we use
487 ;; the same code as v8 (the addx/subx method has more applications).  The
488 ;; exception to this is "reg != 0" which can be done in one instruction on v9
489 ;; (so we do it).  For the rest, on v9 we use conditional moves; on v8, we do
490 ;; branches.
492 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
493 ;; generate addcc/subcc instructions.
495 (define_expand "seqsi_special"
496   [(set (match_dup 3)
497         (xor:SI (match_operand:SI 1 "register_operand" "")
498                 (match_operand:SI 2 "register_operand" "")))
499    (parallel [(set (match_operand:SI 0 "register_operand" "")
500                    (eq:SI (match_dup 3) (const_int 0)))
501               (clobber (reg:CC 100))])]
502   ""
503   { operands[3] = gen_reg_rtx (SImode); })
505 (define_expand "seqdi_special"
506   [(set (match_dup 3)
507         (xor:DI (match_operand:DI 1 "register_operand" "")
508                 (match_operand:DI 2 "register_operand" "")))
509    (set (match_operand:DI 0 "register_operand" "")
510         (eq:DI (match_dup 3) (const_int 0)))]
511   "TARGET_ARCH64"
512   { operands[3] = gen_reg_rtx (DImode); })
514 (define_expand "snesi_special"
515   [(set (match_dup 3)
516         (xor:SI (match_operand:SI 1 "register_operand" "")
517                 (match_operand:SI 2 "register_operand" "")))
518    (parallel [(set (match_operand:SI 0 "register_operand" "")
519                    (ne:SI (match_dup 3) (const_int 0)))
520               (clobber (reg:CC 100))])]
521   ""
522   { operands[3] = gen_reg_rtx (SImode); })
524 (define_expand "snedi_special"
525   [(set (match_dup 3)
526         (xor:DI (match_operand:DI 1 "register_operand" "")
527                 (match_operand:DI 2 "register_operand" "")))
528    (set (match_operand:DI 0 "register_operand" "")
529         (ne:DI (match_dup 3) (const_int 0)))]
530   "TARGET_ARCH64"
531   { operands[3] = gen_reg_rtx (DImode); })
533 (define_expand "seqdi_special_trunc"
534   [(set (match_dup 3)
535         (xor:DI (match_operand:DI 1 "register_operand" "")
536                 (match_operand:DI 2 "register_operand" "")))
537    (set (match_operand:SI 0 "register_operand" "")
538         (eq:SI (match_dup 3) (const_int 0)))]
539   "TARGET_ARCH64"
540   { operands[3] = gen_reg_rtx (DImode); })
542 (define_expand "snedi_special_trunc"
543   [(set (match_dup 3)
544         (xor:DI (match_operand:DI 1 "register_operand" "")
545                 (match_operand:DI 2 "register_operand" "")))
546    (set (match_operand:SI 0 "register_operand" "")
547         (ne:SI (match_dup 3) (const_int 0)))]
548   "TARGET_ARCH64"
549   { operands[3] = gen_reg_rtx (DImode); })
551 (define_expand "seqsi_special_extend"
552   [(set (match_dup 3)
553         (xor:SI (match_operand:SI 1 "register_operand" "")
554                 (match_operand:SI 2 "register_operand" "")))
555    (parallel [(set (match_operand:DI 0 "register_operand" "")
556                    (eq:DI (match_dup 3) (const_int 0)))
557               (clobber (reg:CC 100))])]
558   "TARGET_ARCH64"
559   { operands[3] = gen_reg_rtx (SImode); })
561 (define_expand "snesi_special_extend"
562   [(set (match_dup 3)
563         (xor:SI (match_operand:SI 1 "register_operand" "")
564                 (match_operand:SI 2 "register_operand" "")))
565    (parallel [(set (match_operand:DI 0 "register_operand" "")
566                    (ne:DI (match_dup 3) (const_int 0)))
567               (clobber (reg:CC 100))])]
568   "TARGET_ARCH64"
569   { operands[3] = gen_reg_rtx (SImode); })
571 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
572 ;; However, the code handles both SImode and DImode.
573 (define_expand "seq"
574   [(set (match_operand:SI 0 "intreg_operand" "")
575         (eq:SI (match_dup 1) (const_int 0)))]
576   ""
578   if (GET_MODE (sparc_compare_op0) == SImode)
579     {
580       rtx pat;
582       if (GET_MODE (operands[0]) == SImode)
583         pat = gen_seqsi_special (operands[0], sparc_compare_op0,
584                                  sparc_compare_op1);
585       else if (! TARGET_ARCH64)
586         FAIL;
587       else
588         pat = gen_seqsi_special_extend (operands[0], sparc_compare_op0,
589                                         sparc_compare_op1);
590       emit_insn (pat);
591       DONE;
592     }
593   else if (GET_MODE (sparc_compare_op0) == DImode)
594     {
595       rtx pat;
597       if (! TARGET_ARCH64)
598         FAIL;
599       else if (GET_MODE (operands[0]) == SImode)
600         pat = gen_seqdi_special_trunc (operands[0], sparc_compare_op0,
601                                        sparc_compare_op1);
602       else
603         pat = gen_seqdi_special (operands[0], sparc_compare_op0,
604                                  sparc_compare_op1);
605       emit_insn (pat);
606       DONE;
607     }
608   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
609     {
610       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
611       emit_jump_insn (gen_sne (operands[0]));
612       DONE;
613     }
614   else if (TARGET_V9)
615     {
616       if (gen_v9_scc (EQ, operands))
617         DONE;
618       /* fall through */
619     }
620   FAIL;
623 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
624 ;; However, the code handles both SImode and DImode.
625 (define_expand "sne"
626   [(set (match_operand:SI 0 "intreg_operand" "")
627         (ne:SI (match_dup 1) (const_int 0)))]
628   ""
630   if (GET_MODE (sparc_compare_op0) == SImode)
631     {
632       rtx pat;
634       if (GET_MODE (operands[0]) == SImode)
635         pat = gen_snesi_special (operands[0], sparc_compare_op0,
636                                  sparc_compare_op1);
637       else if (! TARGET_ARCH64)
638         FAIL;
639       else
640         pat = gen_snesi_special_extend (operands[0], sparc_compare_op0,
641                                         sparc_compare_op1);
642       emit_insn (pat);
643       DONE;
644     }
645   else if (GET_MODE (sparc_compare_op0) == DImode)
646     {
647       rtx pat;
649       if (! TARGET_ARCH64)
650         FAIL;
651       else if (GET_MODE (operands[0]) == SImode)
652         pat = gen_snedi_special_trunc (operands[0], sparc_compare_op0,
653                                        sparc_compare_op1);
654       else
655         pat = gen_snedi_special (operands[0], sparc_compare_op0,
656                                  sparc_compare_op1);
657       emit_insn (pat);
658       DONE;
659     }
660   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
661     {
662       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
663       emit_jump_insn (gen_sne (operands[0]));
664       DONE;
665     }
666   else if (TARGET_V9)
667     {
668       if (gen_v9_scc (NE, operands))
669         DONE;
670       /* fall through */
671     }
672   FAIL;
675 (define_expand "sgt"
676   [(set (match_operand:SI 0 "intreg_operand" "")
677         (gt:SI (match_dup 1) (const_int 0)))]
678   ""
680   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
681     {
682       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
683       emit_jump_insn (gen_sne (operands[0]));
684       DONE;
685     }
686   else if (TARGET_V9)
687     {
688       if (gen_v9_scc (GT, operands))
689         DONE;
690       /* fall through */
691     }
692   FAIL;
695 (define_expand "slt"
696   [(set (match_operand:SI 0 "intreg_operand" "")
697         (lt:SI (match_dup 1) (const_int 0)))]
698   ""
700   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
701     {
702       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
703       emit_jump_insn (gen_sne (operands[0]));
704       DONE;
705     }
706   else if (TARGET_V9)
707     {
708       if (gen_v9_scc (LT, operands))
709         DONE;
710       /* fall through */
711     }
712   FAIL;
715 (define_expand "sge"
716   [(set (match_operand:SI 0 "intreg_operand" "")
717         (ge:SI (match_dup 1) (const_int 0)))]
718   ""
720   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
721     {
722       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
723       emit_jump_insn (gen_sne (operands[0]));
724       DONE;
725     }
726   else if (TARGET_V9)
727     {
728       if (gen_v9_scc (GE, operands))
729         DONE;
730       /* fall through */
731     }
732   FAIL;
735 (define_expand "sle"
736   [(set (match_operand:SI 0 "intreg_operand" "")
737         (le:SI (match_dup 1) (const_int 0)))]
738   ""
740   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
741     {
742       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
743       emit_jump_insn (gen_sne (operands[0]));
744       DONE;
745     }
746   else if (TARGET_V9)
747     {
748       if (gen_v9_scc (LE, operands))
749         DONE;
750       /* fall through */
751     }
752   FAIL;
755 (define_expand "sgtu"
756   [(set (match_operand:SI 0 "intreg_operand" "")
757         (gtu:SI (match_dup 1) (const_int 0)))]
758   ""
760   if (! TARGET_V9)
761     {
762       rtx tem, pat;
764       /* We can do ltu easily, so if both operands are registers, swap them and
765          do a LTU.  */
766       if ((GET_CODE (sparc_compare_op0) == REG
767            || GET_CODE (sparc_compare_op0) == SUBREG)
768           && (GET_CODE (sparc_compare_op1) == REG
769               || GET_CODE (sparc_compare_op1) == SUBREG))
770         {
771           tem = sparc_compare_op0;
772           sparc_compare_op0 = sparc_compare_op1;
773           sparc_compare_op1 = tem;
774           pat = gen_sltu (operands[0]);
775           if (pat == NULL_RTX)
776             FAIL;
777           emit_insn (pat);
778           DONE;
779         }
780     }
781   else
782     {
783       if (gen_v9_scc (GTU, operands))
784         DONE;
785     }
786   FAIL;
789 (define_expand "sltu"
790   [(set (match_operand:SI 0 "intreg_operand" "")
791         (ltu:SI (match_dup 1) (const_int 0)))]
792   ""
794   if (TARGET_V9)
795     {
796       if (gen_v9_scc (LTU, operands))
797         DONE;
798     }
799   operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
802 (define_expand "sgeu"
803   [(set (match_operand:SI 0 "intreg_operand" "")
804         (geu:SI (match_dup 1) (const_int 0)))]
805   ""
807   if (TARGET_V9)
808     {
809       if (gen_v9_scc (GEU, operands))
810         DONE;
811     }
812   operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
815 (define_expand "sleu"
816   [(set (match_operand:SI 0 "intreg_operand" "")
817         (leu:SI (match_dup 1) (const_int 0)))]
818   ""
820   if (! TARGET_V9)
821     {
822       rtx tem, pat;
824       /* We can do geu easily, so if both operands are registers, swap them and
825          do a GEU.  */
826       if ((GET_CODE (sparc_compare_op0) == REG
827            || GET_CODE (sparc_compare_op0) == SUBREG)
828           && (GET_CODE (sparc_compare_op1) == REG
829               || GET_CODE (sparc_compare_op1) == SUBREG))
830         {
831           tem = sparc_compare_op0;
832           sparc_compare_op0 = sparc_compare_op1;
833           sparc_compare_op1 = tem;
834           pat = gen_sgeu (operands[0]);
835           if (pat == NULL_RTX)
836             FAIL;
837           emit_insn (pat);
838           DONE;
839         }
840     }
841   else
842     {
843       if (gen_v9_scc (LEU, operands))
844         DONE;
845     }
846   FAIL;
849 ;; Now the DEFINE_INSNs for the scc cases.
851 ;; The SEQ and SNE patterns are special because they can be done
852 ;; without any branching and do not involve a COMPARE.  We want
853 ;; them to always use the splitz below so the results can be
854 ;; scheduled.
856 (define_insn_and_split "*snesi_zero"
857   [(set (match_operand:SI 0 "register_operand" "=r")
858         (ne:SI (match_operand:SI 1 "register_operand" "r")
859                (const_int 0)))
860    (clobber (reg:CC 100))]
861   ""
862   "#"
863   ""
864   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
865                                            (const_int 0)))
866    (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))]
867   ""
868   [(set_attr "length" "2")])
870 (define_insn_and_split "*neg_snesi_zero"
871   [(set (match_operand:SI 0 "register_operand" "=r")
872         (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
873                        (const_int 0))))
874    (clobber (reg:CC 100))]
875   ""
876   "#"
877   ""
878   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
879                                            (const_int 0)))
880    (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
881   ""
882   [(set_attr "length" "2")])
884 (define_insn_and_split "*snesi_zero_extend"
885   [(set (match_operand:DI 0 "register_operand" "=r")
886         (ne:DI (match_operand:SI 1 "register_operand" "r")
887                (const_int 0)))
888    (clobber (reg:CC 100))]
889   "TARGET_ARCH64"
890   "#"
891   "&& 1"
892   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
893                                                      (match_dup 1))
894                                            (const_int 0)))
895    (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
896                                                         (const_int 0))
897                                                (ltu:SI (reg:CC_NOOV 100)
898                                                        (const_int 0)))))]
899   ""
900   [(set_attr "length" "2")])
902 (define_insn_and_split "*snedi_zero"
903   [(set (match_operand:DI 0 "register_operand" "=&r")
904         (ne:DI (match_operand:DI 1 "register_operand" "r")
905                (const_int 0)))]
906   "TARGET_ARCH64"
907   "#"
908   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
909   [(set (match_dup 0) (const_int 0))
910    (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
911                                               (const_int 0))
912                                        (const_int 1)
913                                        (match_dup 0)))]
914   ""
915   [(set_attr "length" "2")])
917 (define_insn_and_split "*neg_snedi_zero"
918   [(set (match_operand:DI 0 "register_operand" "=&r")
919         (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
920                        (const_int 0))))]
921   "TARGET_ARCH64"
922   "#"
923   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
924   [(set (match_dup 0) (const_int 0))
925    (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
926                                               (const_int 0))
927                                        (const_int -1)
928                                        (match_dup 0)))]
929   ""
930   [(set_attr "length" "2")])
932 (define_insn_and_split "*snedi_zero_trunc"
933   [(set (match_operand:SI 0 "register_operand" "=&r")
934         (ne:SI (match_operand:DI 1 "register_operand" "r")
935                (const_int 0)))]
936   "TARGET_ARCH64"
937   "#"
938   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
939   [(set (match_dup 0) (const_int 0))
940    (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
941                                               (const_int 0))
942                                        (const_int 1)
943                                        (match_dup 0)))]
944   ""
945   [(set_attr "length" "2")])
947 (define_insn_and_split "*seqsi_zero"
948   [(set (match_operand:SI 0 "register_operand" "=r")
949         (eq:SI (match_operand:SI 1 "register_operand" "r")
950                (const_int 0)))
951    (clobber (reg:CC 100))]
952   ""
953   "#"
954   ""
955   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
956                                            (const_int 0)))
957    (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))]
958   ""
959   [(set_attr "length" "2")])
961 (define_insn_and_split "*neg_seqsi_zero"
962   [(set (match_operand:SI 0 "register_operand" "=r")
963         (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
964                        (const_int 0))))
965    (clobber (reg:CC 100))]
966   ""
967   "#"
968   ""
969   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
970                                            (const_int 0)))
971    (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
972   ""
973   [(set_attr "length" "2")])
975 (define_insn_and_split "*seqsi_zero_extend"
976   [(set (match_operand:DI 0 "register_operand" "=r")
977         (eq:DI (match_operand:SI 1 "register_operand" "r")
978                (const_int 0)))
979    (clobber (reg:CC 100))]
980   "TARGET_ARCH64"
981   "#"
982   "&& 1"
983   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
984                                                      (match_dup 1))
985                                            (const_int 0)))
986    (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
987                                                           (const_int -1))
988                                                 (ltu:SI (reg:CC_NOOV 100)
989                                                         (const_int 0)))))]
990   ""
991   [(set_attr "length" "2")])
993 (define_insn_and_split "*seqdi_zero"
994   [(set (match_operand:DI 0 "register_operand" "=&r")
995         (eq:DI (match_operand:DI 1 "register_operand" "r")
996                (const_int 0)))]
997   "TARGET_ARCH64"
998   "#"
999   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1000   [(set (match_dup 0) (const_int 0))
1001    (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1002                                               (const_int 0))
1003                                        (const_int 1)
1004                                        (match_dup 0)))]
1005   ""
1006   [(set_attr "length" "2")])
1008 (define_insn_and_split "*neg_seqdi_zero"
1009   [(set (match_operand:DI 0 "register_operand" "=&r")
1010         (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
1011                        (const_int 0))))]
1012   "TARGET_ARCH64"
1013   "#"
1014   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1015   [(set (match_dup 0) (const_int 0))
1016    (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1017                                               (const_int 0))
1018                                        (const_int -1)
1019                                        (match_dup 0)))]
1020   ""
1021   [(set_attr "length" "2")]) 
1023 (define_insn_and_split "*seqdi_zero_trunc"
1024   [(set (match_operand:SI 0 "register_operand" "=&r")
1025         (eq:SI (match_operand:DI 1 "register_operand" "r")
1026                (const_int 0)))]
1027   "TARGET_ARCH64"
1028   "#"
1029   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1030   [(set (match_dup 0) (const_int 0))
1031    (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
1032                                               (const_int 0))
1033                                        (const_int 1)
1034                                        (match_dup 0)))]
1035   ""
1036   [(set_attr "length" "2")])
1038 ;; We can also do (x + (i == 0)) and related, so put them in.
1039 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1040 ;; versions for v9.
1042 (define_insn_and_split "*x_plus_i_ne_0"
1043   [(set (match_operand:SI 0 "register_operand" "=r")
1044         (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
1045                         (const_int 0))
1046                  (match_operand:SI 2 "register_operand" "r")))
1047    (clobber (reg:CC 100))]
1048   ""
1049   "#"
1050   ""
1051   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1052                                            (const_int 0)))
1053    (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1054                                (match_dup 2)))]
1055   ""
1056   [(set_attr "length" "2")])
1058 (define_insn_and_split "*x_minus_i_ne_0"
1059   [(set (match_operand:SI 0 "register_operand" "=r")
1060         (minus:SI (match_operand:SI 2 "register_operand" "r")
1061                   (ne:SI (match_operand:SI 1 "register_operand" "r")
1062                          (const_int 0))))
1063    (clobber (reg:CC 100))]
1064   ""
1065   "#"
1066   ""
1067   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1068                                            (const_int 0)))
1069    (set (match_dup 0) (minus:SI (match_dup 2)
1070                                 (ltu:SI (reg:CC 100) (const_int 0))))]
1071   ""
1072   [(set_attr "length" "2")])
1074 (define_insn_and_split "*x_plus_i_eq_0"
1075   [(set (match_operand:SI 0 "register_operand" "=r")
1076         (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1077                         (const_int 0))
1078                  (match_operand:SI 2 "register_operand" "r")))
1079    (clobber (reg:CC 100))]
1080   ""
1081   "#"
1082   ""
1083   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1084                                            (const_int 0)))
1085    (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1086                                (match_dup 2)))]
1087   ""
1088   [(set_attr "length" "2")])
1090 (define_insn_and_split "*x_minus_i_eq_0"
1091   [(set (match_operand:SI 0 "register_operand" "=r")
1092         (minus:SI (match_operand:SI 2 "register_operand" "r")
1093                   (eq:SI (match_operand:SI 1 "register_operand" "r")
1094                          (const_int 0))))
1095    (clobber (reg:CC 100))]
1096   ""
1097   "#"
1098   ""
1099   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1100                                            (const_int 0)))
1101    (set (match_dup 0) (minus:SI (match_dup 2)
1102                                 (geu:SI (reg:CC 100) (const_int 0))))]
1103   ""
1104   [(set_attr "length" "2")])
1106 ;; We can also do GEU and LTU directly, but these operate after a compare.
1107 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1108 ;; versions for v9.
1110 (define_insn "*sltu_insn"
1111   [(set (match_operand:SI 0 "register_operand" "=r")
1112         (ltu:SI (reg:CC 100) (const_int 0)))]
1113   ""
1114   "addx\t%%g0, 0, %0"
1115   [(set_attr "type" "ialuX")])
1117 (define_insn "*neg_sltu_insn"
1118   [(set (match_operand:SI 0 "register_operand" "=r")
1119         (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1120   ""
1121   "subx\t%%g0, 0, %0"
1122   [(set_attr "type" "ialuX")])
1124 ;; ??? Combine should canonicalize these next two to the same pattern.
1125 (define_insn "*neg_sltu_minus_x"
1126   [(set (match_operand:SI 0 "register_operand" "=r")
1127         (minus:SI (neg:SI (ltu:SI (reg:CC 100) (const_int 0)))
1128                   (match_operand:SI 1 "arith_operand" "rI")))]
1129   ""
1130   "subx\t%%g0, %1, %0"
1131   [(set_attr "type" "ialuX")])
1133 (define_insn "*neg_sltu_plus_x"
1134   [(set (match_operand:SI 0 "register_operand" "=r")
1135         (neg:SI (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1136                          (match_operand:SI 1 "arith_operand" "rI"))))]
1137   ""
1138   "subx\t%%g0, %1, %0"
1139   [(set_attr "type" "ialuX")])
1141 (define_insn "*sgeu_insn"
1142   [(set (match_operand:SI 0 "register_operand" "=r")
1143         (geu:SI (reg:CC 100) (const_int 0)))]
1144   ""
1145   "subx\t%%g0, -1, %0"
1146   [(set_attr "type" "ialuX")])
1148 (define_insn "*neg_sgeu_insn"
1149   [(set (match_operand:SI 0 "register_operand" "=r")
1150         (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1151   ""
1152   "addx\t%%g0, -1, %0"
1153   [(set_attr "type" "ialuX")])
1155 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
1156 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1157 ;; versions for v9.
1159 (define_insn "*sltu_plus_x"
1160   [(set (match_operand:SI 0 "register_operand" "=r")
1161         (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1162                  (match_operand:SI 1 "arith_operand" "rI")))]
1163   ""
1164   "addx\t%%g0, %1, %0"
1165   [(set_attr "type" "ialuX")])
1167 (define_insn "*sltu_plus_x_plus_y"
1168   [(set (match_operand:SI 0 "register_operand" "=r")
1169         (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1170                  (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1171                           (match_operand:SI 2 "arith_operand" "rI"))))]
1172   ""
1173   "addx\t%1, %2, %0"
1174   [(set_attr "type" "ialuX")])
1176 (define_insn "*x_minus_sltu"
1177   [(set (match_operand:SI 0 "register_operand" "=r")
1178         (minus:SI (match_operand:SI 1 "register_operand" "r")
1179                   (ltu:SI (reg:CC 100) (const_int 0))))]
1180   ""
1181   "subx\t%1, 0, %0"
1182   [(set_attr "type" "ialuX")])
1184 ;; ??? Combine should canonicalize these next two to the same pattern.
1185 (define_insn "*x_minus_y_minus_sltu"
1186   [(set (match_operand:SI 0 "register_operand" "=r")
1187         (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1188                             (match_operand:SI 2 "arith_operand" "rI"))
1189                   (ltu:SI (reg:CC 100) (const_int 0))))]
1190   ""
1191   "subx\t%r1, %2, %0"
1192   [(set_attr "type" "ialuX")])
1194 (define_insn "*x_minus_sltu_plus_y"
1195   [(set (match_operand:SI 0 "register_operand" "=r")
1196         (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1197                   (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1198                            (match_operand:SI 2 "arith_operand" "rI"))))]
1199   ""
1200   "subx\t%r1, %2, %0"
1201   [(set_attr "type" "ialuX")])
1203 (define_insn "*sgeu_plus_x"
1204   [(set (match_operand:SI 0 "register_operand" "=r")
1205         (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1206                  (match_operand:SI 1 "register_operand" "r")))]
1207   ""
1208   "subx\t%1, -1, %0"
1209   [(set_attr "type" "ialuX")])
1211 (define_insn "*x_minus_sgeu"
1212   [(set (match_operand:SI 0 "register_operand" "=r")
1213         (minus:SI (match_operand:SI 1 "register_operand" "r")
1214                   (geu:SI (reg:CC 100) (const_int 0))))]
1215   ""
1216   "addx\t%1, -1, %0"
1217   [(set_attr "type" "ialuX")])
1219 (define_split
1220   [(set (match_operand:SI 0 "register_operand" "")
1221         (match_operator:SI 2 "noov_compare_op"
1222                            [(match_operand 1 "icc_or_fcc_reg_operand" "")
1223                             (const_int 0)]))]
1224   "TARGET_V9
1225    && REGNO (operands[1]) == SPARC_ICC_REG
1226    && (GET_MODE (operands[1]) == CCXmode
1227        /* 32 bit LTU/GEU are better implemented using addx/subx.  */
1228        || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1229   [(set (match_dup 0) (const_int 0))
1230    (set (match_dup 0)
1231         (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1232                          (const_int 1)
1233                          (match_dup 0)))]
1234   "")
1237 ;; These control RTL generation for conditional jump insns
1239 ;; The quad-word fp compare library routines all return nonzero to indicate
1240 ;; true, which is different from the equivalent libgcc routines, so we must
1241 ;; handle them specially here.
1243 (define_expand "beq"
1244   [(set (pc)
1245         (if_then_else (eq (match_dup 1) (const_int 0))
1246                       (label_ref (match_operand 0 "" ""))
1247                       (pc)))]
1248   ""
1250   if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1251       && GET_CODE (sparc_compare_op0) == REG
1252       && GET_MODE (sparc_compare_op0) == DImode)
1253     {
1254       emit_v9_brxx_insn (EQ, sparc_compare_op0, operands[0]);
1255       DONE;
1256     }
1257   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1258     {
1259       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
1260       emit_jump_insn (gen_bne (operands[0]));
1261       DONE;
1262     }
1263   operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1);
1266 (define_expand "bne"
1267   [(set (pc)
1268         (if_then_else (ne (match_dup 1) (const_int 0))
1269                       (label_ref (match_operand 0 "" ""))
1270                       (pc)))]
1271   ""
1273   if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1274       && GET_CODE (sparc_compare_op0) == REG
1275       && GET_MODE (sparc_compare_op0) == DImode)
1276     {
1277       emit_v9_brxx_insn (NE, sparc_compare_op0, operands[0]);
1278       DONE;
1279     }
1280   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1281     {
1282       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
1283       emit_jump_insn (gen_bne (operands[0]));
1284       DONE;
1285     }
1286   operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1);
1289 (define_expand "bgt"
1290   [(set (pc)
1291         (if_then_else (gt (match_dup 1) (const_int 0))
1292                       (label_ref (match_operand 0 "" ""))
1293                       (pc)))]
1294   ""
1296   if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1297       && GET_CODE (sparc_compare_op0) == REG
1298       && GET_MODE (sparc_compare_op0) == DImode)
1299     {
1300       emit_v9_brxx_insn (GT, sparc_compare_op0, operands[0]);
1301       DONE;
1302     }
1303   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1304     {
1305       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
1306       emit_jump_insn (gen_bne (operands[0]));
1307       DONE;
1308     }
1309   operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1);
1312 (define_expand "bgtu"
1313   [(set (pc)
1314         (if_then_else (gtu (match_dup 1) (const_int 0))
1315                       (label_ref (match_operand 0 "" ""))
1316                       (pc)))]
1317   ""
1319   operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1);
1322 (define_expand "blt"
1323   [(set (pc)
1324         (if_then_else (lt (match_dup 1) (const_int 0))
1325                       (label_ref (match_operand 0 "" ""))
1326                       (pc)))]
1327   ""
1329   if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1330       && GET_CODE (sparc_compare_op0) == REG
1331       && GET_MODE (sparc_compare_op0) == DImode)
1332     {
1333       emit_v9_brxx_insn (LT, sparc_compare_op0, operands[0]);
1334       DONE;
1335     }
1336   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1337     {
1338       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
1339       emit_jump_insn (gen_bne (operands[0]));
1340       DONE;
1341     }
1342   operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1);
1345 (define_expand "bltu"
1346   [(set (pc)
1347         (if_then_else (ltu (match_dup 1) (const_int 0))
1348                       (label_ref (match_operand 0 "" ""))
1349                       (pc)))]
1350   ""
1352   operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
1355 (define_expand "bge"
1356   [(set (pc)
1357         (if_then_else (ge (match_dup 1) (const_int 0))
1358                       (label_ref (match_operand 0 "" ""))
1359                       (pc)))]
1360   ""
1362   if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1363       && GET_CODE (sparc_compare_op0) == REG
1364       && GET_MODE (sparc_compare_op0) == DImode)
1365     {
1366       emit_v9_brxx_insn (GE, sparc_compare_op0, operands[0]);
1367       DONE;
1368     }
1369   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1370     {
1371       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
1372       emit_jump_insn (gen_bne (operands[0]));
1373       DONE;
1374     }
1375   operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1);
1378 (define_expand "bgeu"
1379   [(set (pc)
1380         (if_then_else (geu (match_dup 1) (const_int 0))
1381                       (label_ref (match_operand 0 "" ""))
1382                       (pc)))]
1383   ""
1385   operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
1388 (define_expand "ble"
1389   [(set (pc)
1390         (if_then_else (le (match_dup 1) (const_int 0))
1391                       (label_ref (match_operand 0 "" ""))
1392                       (pc)))]
1393   ""
1395   if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1396       && GET_CODE (sparc_compare_op0) == REG
1397       && GET_MODE (sparc_compare_op0) == DImode)
1398     {
1399       emit_v9_brxx_insn (LE, sparc_compare_op0, operands[0]);
1400       DONE;
1401     }
1402   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1403     {
1404       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
1405       emit_jump_insn (gen_bne (operands[0]));
1406       DONE;
1407     }
1408   operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1);
1411 (define_expand "bleu"
1412   [(set (pc)
1413         (if_then_else (leu (match_dup 1) (const_int 0))
1414                       (label_ref (match_operand 0 "" ""))
1415                       (pc)))]
1416   ""
1418   operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
1421 (define_expand "bunordered"
1422   [(set (pc)
1423         (if_then_else (unordered (match_dup 1) (const_int 0))
1424                       (label_ref (match_operand 0 "" ""))
1425                       (pc)))]
1426   ""
1428   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1429     {
1430       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1,
1431                                 UNORDERED);
1432       emit_jump_insn (gen_beq (operands[0]));
1433       DONE;
1434     }
1435   operands[1] = gen_compare_reg (UNORDERED, sparc_compare_op0,
1436                                  sparc_compare_op1);
1439 (define_expand "bordered"
1440   [(set (pc)
1441         (if_then_else (ordered (match_dup 1) (const_int 0))
1442                       (label_ref (match_operand 0 "" ""))
1443                       (pc)))]
1444   ""
1446   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1447     {
1448       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, ORDERED);
1449       emit_jump_insn (gen_bne (operands[0]));
1450       DONE;
1451     }
1452   operands[1] = gen_compare_reg (ORDERED, sparc_compare_op0,
1453                                  sparc_compare_op1);
1456 (define_expand "bungt"
1457   [(set (pc)
1458         (if_then_else (ungt (match_dup 1) (const_int 0))
1459                       (label_ref (match_operand 0 "" ""))
1460                       (pc)))]
1461   ""
1463   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1464     {
1465       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGT);
1466       emit_jump_insn (gen_bgt (operands[0]));
1467       DONE;
1468     }
1469   operands[1] = gen_compare_reg (UNGT, sparc_compare_op0, sparc_compare_op1);
1472 (define_expand "bunlt"
1473   [(set (pc)
1474         (if_then_else (unlt (match_dup 1) (const_int 0))
1475                       (label_ref (match_operand 0 "" ""))
1476                       (pc)))]
1477   ""
1479   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1480     {
1481       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLT);
1482       emit_jump_insn (gen_bne (operands[0]));
1483       DONE;
1484     }
1485   operands[1] = gen_compare_reg (UNLT, sparc_compare_op0, sparc_compare_op1);
1488 (define_expand "buneq"
1489   [(set (pc)
1490         (if_then_else (uneq (match_dup 1) (const_int 0))
1491                       (label_ref (match_operand 0 "" ""))
1492                       (pc)))]
1493   ""
1495   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1496     {
1497       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNEQ);
1498       emit_jump_insn (gen_beq (operands[0]));
1499       DONE;
1500     }
1501   operands[1] = gen_compare_reg (UNEQ, sparc_compare_op0, sparc_compare_op1);
1504 (define_expand "bunge"
1505   [(set (pc)
1506         (if_then_else (unge (match_dup 1) (const_int 0))
1507                       (label_ref (match_operand 0 "" ""))
1508                       (pc)))]
1509   ""
1511   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1512     {
1513       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGE);
1514       emit_jump_insn (gen_bne (operands[0]));
1515       DONE;
1516     }
1517   operands[1] = gen_compare_reg (UNGE, sparc_compare_op0, sparc_compare_op1);
1520 (define_expand "bunle"
1521   [(set (pc)
1522         (if_then_else (unle (match_dup 1) (const_int 0))
1523                       (label_ref (match_operand 0 "" ""))
1524                       (pc)))]
1525   ""
1527   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1528     {
1529       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLE);
1530       emit_jump_insn (gen_bne (operands[0]));
1531       DONE;
1532     }
1533   operands[1] = gen_compare_reg (UNLE, sparc_compare_op0, sparc_compare_op1);
1536 (define_expand "bltgt"
1537   [(set (pc)
1538         (if_then_else (ltgt (match_dup 1) (const_int 0))
1539                       (label_ref (match_operand 0 "" ""))
1540                       (pc)))]
1541   ""
1543   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1544     {
1545       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LTGT);
1546       emit_jump_insn (gen_bne (operands[0]));
1547       DONE;
1548     }
1549   operands[1] = gen_compare_reg (LTGT, sparc_compare_op0, sparc_compare_op1);
1552 ;; Now match both normal and inverted jump.
1554 ;; XXX fpcmp nop braindamage
1555 (define_insn "*normal_branch"
1556   [(set (pc)
1557         (if_then_else (match_operator 0 "noov_compare_op"
1558                                       [(reg 100) (const_int 0)])
1559                       (label_ref (match_operand 1 "" ""))
1560                       (pc)))]
1561   ""
1563   return output_cbranch (operands[0], operands[1], 1, 0,
1564                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1565                          insn);
1567   [(set_attr "type" "branch")
1568    (set_attr "branch_type" "icc")])
1570 ;; XXX fpcmp nop braindamage
1571 (define_insn "*inverted_branch"
1572   [(set (pc)
1573         (if_then_else (match_operator 0 "noov_compare_op"
1574                                       [(reg 100) (const_int 0)])
1575                       (pc)
1576                       (label_ref (match_operand 1 "" ""))))]
1577   ""
1579   return output_cbranch (operands[0], operands[1], 1, 1,
1580                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1581                          insn);
1583   [(set_attr "type" "branch")
1584    (set_attr "branch_type" "icc")])
1586 ;; XXX fpcmp nop braindamage
1587 (define_insn "*normal_fp_branch"
1588   [(set (pc)
1589         (if_then_else (match_operator 1 "comparison_operator"
1590                                       [(match_operand:CCFP 0 "fcc_reg_operand" "c")
1591                                        (const_int 0)])
1592                       (label_ref (match_operand 2 "" ""))
1593                       (pc)))]
1594   ""
1596   return output_cbranch (operands[1], operands[2], 2, 0,
1597                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1598                          insn);
1600   [(set_attr "type" "branch")
1601    (set_attr "branch_type" "fcc")])
1603 ;; XXX fpcmp nop braindamage
1604 (define_insn "*inverted_fp_branch"
1605   [(set (pc)
1606         (if_then_else (match_operator 1 "comparison_operator"
1607                                       [(match_operand:CCFP 0 "fcc_reg_operand" "c")
1608                                        (const_int 0)])
1609                       (pc)
1610                       (label_ref (match_operand 2 "" ""))))]
1611   ""
1613   return output_cbranch (operands[1], operands[2], 2, 1,
1614                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1615                          insn);
1617   [(set_attr "type" "branch")
1618    (set_attr "branch_type" "fcc")])
1620 ;; XXX fpcmp nop braindamage
1621 (define_insn "*normal_fpe_branch"
1622   [(set (pc)
1623         (if_then_else (match_operator 1 "comparison_operator"
1624                                       [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
1625                                        (const_int 0)])
1626                       (label_ref (match_operand 2 "" ""))
1627                       (pc)))]
1628   ""
1630   return output_cbranch (operands[1], operands[2], 2, 0,
1631                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1632                          insn);
1634   [(set_attr "type" "branch")
1635    (set_attr "branch_type" "fcc")])
1637 ;; XXX fpcmp nop braindamage
1638 (define_insn "*inverted_fpe_branch"
1639   [(set (pc)
1640         (if_then_else (match_operator 1 "comparison_operator"
1641                                       [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
1642                                        (const_int 0)])
1643                       (pc)
1644                       (label_ref (match_operand 2 "" ""))))]
1645   ""
1647   return output_cbranch (operands[1], operands[2], 2, 1,
1648                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1649                          insn);
1651   [(set_attr "type" "branch")
1652    (set_attr "branch_type" "fcc")])
1654 ;; SPARC V9-specific jump insns.  None of these are guaranteed to be
1655 ;; in the architecture.
1657 ;; There are no 32 bit brreg insns.
1659 ;; XXX
1660 (define_insn "*normal_int_branch_sp64"
1661   [(set (pc)
1662         (if_then_else (match_operator 0 "v9_regcmp_op"
1663                                       [(match_operand:DI 1 "register_operand" "r")
1664                                        (const_int 0)])
1665                       (label_ref (match_operand 2 "" ""))
1666                       (pc)))]
1667   "TARGET_ARCH64"
1669   return output_v9branch (operands[0], operands[2], 1, 2, 0,
1670                           final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1671                           insn);
1673   [(set_attr "type" "branch")
1674    (set_attr "branch_type" "reg")])
1676 ;; XXX
1677 (define_insn "*inverted_int_branch_sp64"
1678   [(set (pc)
1679         (if_then_else (match_operator 0 "v9_regcmp_op"
1680                                       [(match_operand:DI 1 "register_operand" "r")
1681                                        (const_int 0)])
1682                       (pc)
1683                       (label_ref (match_operand 2 "" ""))))]
1684   "TARGET_ARCH64"
1686   return output_v9branch (operands[0], operands[2], 1, 2, 1,
1687                           final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1688                           insn);
1690   [(set_attr "type" "branch")
1691    (set_attr "branch_type" "reg")])
1693 ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic
1694 ;; value subject to a PC-relative relocation.  Operand 2 is a helper function
1695 ;; that adds the PC value at the call point to operand 0.
1697 (define_insn "load_pcrel_sym"
1698   [(set (match_operand 0 "register_operand" "=r")
1699         (unspec [(match_operand 1 "symbolic_operand" "")
1700                  (match_operand 2 "call_operand_address" "")] UNSPEC_LOAD_PCREL_SYM))
1701    (clobber (reg:SI 15))]
1702   ""
1704   if (flag_delayed_branch)
1705     return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0";
1706   else
1707     return "sethi\t%%hi(%a1-8), %0\n\tadd\t%0, %%lo(%a1-4), %0\n\tcall\t%a2\n\t nop";
1709   [(set (attr "type") (const_string "multi"))
1710    (set (attr "length")
1711         (if_then_else (eq_attr "delayed_branch" "true")
1712                       (const_int 3)
1713                       (const_int 4)))])
1715 ;; Move instructions
1717 (define_expand "movqi"
1718   [(set (match_operand:QI 0 "general_operand" "")
1719         (match_operand:QI 1 "general_operand" ""))]
1720   ""
1722   /* Working with CONST_INTs is easier, so convert
1723      a double if needed.  */
1724   if (GET_CODE (operands[1]) == CONST_DOUBLE)
1725     {
1726       operands[1] = GEN_INT (trunc_int_for_mode
1727                              (CONST_DOUBLE_LOW (operands[1]), QImode));
1728     }
1730   /* Handle sets of MEM first.  */
1731   if (GET_CODE (operands[0]) == MEM)
1732     {
1733       if (reg_or_0_operand (operands[1], QImode))
1734         goto movqi_is_ok;
1736       if (! reload_in_progress)
1737         {
1738           operands[0] = validize_mem (operands[0]);
1739           operands[1] = force_reg (QImode, operands[1]);
1740         }
1741     }
1743   /* Fixup TLS cases.  */
1744   if (tls_symbolic_operand (operands [1]))
1745     operands[1] = legitimize_tls_address (operands[1]);
1747   /* Fixup PIC cases.  */
1748   if (flag_pic)
1749     {
1750       if (CONSTANT_P (operands[1])
1751           && pic_address_needs_scratch (operands[1]))
1752         operands[1] = legitimize_pic_address (operands[1], QImode, 0);
1754       if (symbolic_operand (operands[1], QImode))
1755         {
1756           operands[1] = legitimize_pic_address (operands[1],
1757                                                 QImode,
1758                                                 (reload_in_progress ?
1759                                                  operands[0] :
1760                                                  NULL_RTX));
1761           goto movqi_is_ok;
1762         }
1763     }
1765   /* All QI constants require only one insn, so proceed.  */
1767  movqi_is_ok:
1768   ;
1771 (define_insn "*movqi_insn"
1772   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1773         (match_operand:QI 1 "input_operand"   "rI,m,rJ"))]
1774   "(register_operand (operands[0], QImode)
1775     || reg_or_0_operand (operands[1], QImode))"
1776   "@
1777    mov\t%1, %0
1778    ldub\t%1, %0
1779    stb\t%r1, %0"
1780   [(set_attr "type" "*,load,store")
1781    (set_attr "us3load_type" "*,3cycle,*")])
1783 (define_expand "movhi"
1784   [(set (match_operand:HI 0 "general_operand" "")
1785         (match_operand:HI 1 "general_operand" ""))]
1786   ""
1788   /* Working with CONST_INTs is easier, so convert
1789      a double if needed.  */
1790   if (GET_CODE (operands[1]) == CONST_DOUBLE)
1791     operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
1793   /* Handle sets of MEM first.  */
1794   if (GET_CODE (operands[0]) == MEM)
1795     {
1796       if (reg_or_0_operand (operands[1], HImode))
1797         goto movhi_is_ok;
1799       if (! reload_in_progress)
1800         {
1801           operands[0] = validize_mem (operands[0]);
1802           operands[1] = force_reg (HImode, operands[1]);
1803         }
1804     }
1806   /* Fixup TLS cases.  */
1807   if (tls_symbolic_operand (operands [1]))
1808     operands[1] = legitimize_tls_address (operands[1]);
1810   /* Fixup PIC cases.  */
1811   if (flag_pic)
1812     {
1813       if (CONSTANT_P (operands[1])
1814           && pic_address_needs_scratch (operands[1]))
1815         operands[1] = legitimize_pic_address (operands[1], HImode, 0);
1817       if (symbolic_operand (operands[1], HImode))
1818         {
1819           operands[1] = legitimize_pic_address (operands[1],
1820                                                 HImode,
1821                                                 (reload_in_progress ?
1822                                                  operands[0] :
1823                                                  NULL_RTX));
1824           goto movhi_is_ok;
1825         }
1826     }
1828   /* This makes sure we will not get rematched due to splittage.  */
1829   if (! CONSTANT_P (operands[1]) || input_operand (operands[1], HImode))
1830     ;
1831   else if (CONSTANT_P (operands[1])
1832            && GET_CODE (operands[1]) != HIGH
1833            && GET_CODE (operands[1]) != LO_SUM)
1834     {
1835       sparc_emit_set_const32 (operands[0], operands[1]);
1836       DONE;
1837     }
1838  movhi_is_ok:
1839   ;
1842 (define_insn "*movhi_const64_special"
1843   [(set (match_operand:HI 0 "register_operand" "=r")
1844         (match_operand:HI 1 "const64_high_operand" ""))]
1845   "TARGET_ARCH64"
1846   "sethi\t%%hi(%a1), %0")
1848 (define_insn "*movhi_insn"
1849   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1850         (match_operand:HI 1 "input_operand"   "rI,K,m,rJ"))]
1851   "(register_operand (operands[0], HImode)
1852     || reg_or_0_operand (operands[1], HImode))"
1853   "@
1854    mov\t%1, %0
1855    sethi\t%%hi(%a1), %0
1856    lduh\t%1, %0
1857    sth\t%r1, %0"
1858   [(set_attr "type" "*,*,load,store")
1859    (set_attr "us3load_type" "*,*,3cycle,*")])
1861 ;; We always work with constants here.
1862 (define_insn "*movhi_lo_sum"
1863   [(set (match_operand:HI 0 "register_operand" "=r")
1864         (ior:HI (match_operand:HI 1 "register_operand" "%r")
1865                 (match_operand:HI 2 "small_int" "I")))]
1866   ""
1867   "or\t%1, %2, %0")
1869 (define_expand "movsi"
1870   [(set (match_operand:SI 0 "general_operand" "")
1871         (match_operand:SI 1 "general_operand" ""))]
1872   ""
1874   /* Working with CONST_INTs is easier, so convert
1875      a double if needed.  */
1876   if (GET_CODE (operands[1]) == CONST_DOUBLE)
1877     operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
1879   /* Handle sets of MEM first.  */
1880   if (GET_CODE (operands[0]) == MEM)
1881     {
1882       if (reg_or_0_operand (operands[1], SImode))
1883         goto movsi_is_ok;
1885       if (! reload_in_progress)
1886         {
1887           operands[0] = validize_mem (operands[0]);
1888           operands[1] = force_reg (SImode, operands[1]);
1889         }
1890     }
1892   /* Fixup TLS cases.  */
1893   if (tls_symbolic_operand (operands [1]))
1894     operands[1] = legitimize_tls_address (operands[1]);
1896   /* Fixup PIC cases.  */
1897   if (flag_pic)
1898     {
1899       if (CONSTANT_P (operands[1])
1900           && pic_address_needs_scratch (operands[1]))
1901         operands[1] = legitimize_pic_address (operands[1], SImode, 0);
1903       if (GET_CODE (operands[1]) == LABEL_REF)
1904         {
1905           /* shit */
1906           emit_insn (gen_movsi_pic_label_ref (operands[0], operands[1]));
1907           DONE;
1908         }
1910       if (symbolic_operand (operands[1], SImode))
1911         {
1912           operands[1] = legitimize_pic_address (operands[1],
1913                                                 SImode,
1914                                                 (reload_in_progress ?
1915                                                  operands[0] :
1916                                                  NULL_RTX));
1917           goto movsi_is_ok;
1918         }
1919     }
1921   /* If we are trying to toss an integer constant into the
1922      FPU registers, force it into memory.  */
1923   if (GET_CODE (operands[0]) == REG
1924       && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
1925       && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
1926       && CONSTANT_P (operands[1]))
1927     operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
1928                                                  operands[1]));
1930   /* This makes sure we will not get rematched due to splittage.  */
1931   if (! CONSTANT_P (operands[1]) || input_operand (operands[1], SImode))
1932     ;
1933   else if (CONSTANT_P (operands[1])
1934            && GET_CODE (operands[1]) != HIGH
1935            && GET_CODE (operands[1]) != LO_SUM)
1936     {
1937       sparc_emit_set_const32 (operands[0], operands[1]);
1938       DONE;
1939     }
1940  movsi_is_ok:
1941   ;
1944 ;; This is needed to show CSE exactly which bits are set
1945 ;; in a 64-bit register by sethi instructions.
1946 (define_insn "*movsi_const64_special"
1947   [(set (match_operand:SI 0 "register_operand" "=r")
1948         (match_operand:SI 1 "const64_high_operand" ""))]
1949   "TARGET_ARCH64"
1950   "sethi\t%%hi(%a1), %0")
1952 (define_insn "*movsi_insn"
1953   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,f,r,r,r,f,m,m,d")
1954         (match_operand:SI 1 "input_operand"   "rI,!f,K,J,m,!m,rJ,!f,J"))]
1955   "(register_operand (operands[0], SImode)
1956     || reg_or_0_operand (operands[1], SImode))"
1957   "@
1958    mov\t%1, %0
1959    fmovs\t%1, %0
1960    sethi\t%%hi(%a1), %0
1961    clr\t%0
1962    ld\t%1, %0
1963    ld\t%1, %0
1964    st\t%r1, %0
1965    st\t%1, %0
1966    fzeros\t%0"
1967   [(set_attr "type" "*,fpmove,*,*,load,fpload,store,fpstore,fga")])
1969 (define_insn "*movsi_lo_sum"
1970   [(set (match_operand:SI 0 "register_operand" "=r")
1971         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1972                    (match_operand:SI 2 "immediate_operand" "in")))]
1973   ""
1974   "or\t%1, %%lo(%a2), %0")
1976 (define_insn "*movsi_high"
1977   [(set (match_operand:SI 0 "register_operand" "=r")
1978         (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1979   ""
1980   "sethi\t%%hi(%a1), %0")
1982 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1983 ;; so that CSE won't optimize the address computation away.
1984 (define_insn "movsi_lo_sum_pic"
1985   [(set (match_operand:SI 0 "register_operand" "=r")
1986         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1987                    (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1988   "flag_pic"
1989   "or\t%1, %%lo(%a2), %0")
1991 (define_insn "movsi_high_pic"
1992   [(set (match_operand:SI 0 "register_operand" "=r")
1993         (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1994   "flag_pic && check_pic (1)"
1995   "sethi\t%%hi(%a1), %0")
1997 (define_expand "movsi_pic_label_ref"
1998   [(set (match_dup 3) (high:SI
1999      (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
2000                  (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2001    (set (match_dup 4) (lo_sum:SI (match_dup 3)
2002      (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2003    (set (match_operand:SI 0 "register_operand" "=r")
2004         (minus:SI (match_dup 5) (match_dup 4)))]
2005   "flag_pic"
2007   current_function_uses_pic_offset_table = 1;
2008   operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
2009   if (no_new_pseudos)
2010     {
2011       operands[3] = operands[0];
2012       operands[4] = operands[0];
2013     }
2014   else
2015     {
2016       operands[3] = gen_reg_rtx (SImode);
2017       operands[4] = gen_reg_rtx (SImode);
2018     }
2019   operands[5] = pic_offset_table_rtx;
2022 (define_insn "*movsi_high_pic_label_ref"
2023   [(set (match_operand:SI 0 "register_operand" "=r")
2024       (high:SI
2025         (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
2026                     (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2027   "flag_pic"
2028   "sethi\t%%hi(%a2-(%a1-.)), %0")
2030 (define_insn "*movsi_lo_sum_pic_label_ref"
2031   [(set (match_operand:SI 0 "register_operand" "=r")
2032       (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2033         (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
2034                     (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2035   "flag_pic"
2036   "or\t%1, %%lo(%a3-(%a2-.)), %0")
2038 (define_expand "movdi"
2039   [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
2040         (match_operand:DI 1 "general_operand" ""))]
2041   ""
2043   /* Where possible, convert CONST_DOUBLE into a CONST_INT.  */
2044   if (GET_CODE (operands[1]) == CONST_DOUBLE
2045 #if HOST_BITS_PER_WIDE_INT == 32
2046       && ((CONST_DOUBLE_HIGH (operands[1]) == 0
2047            && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) == 0)
2048           || (CONST_DOUBLE_HIGH (operands[1]) == (HOST_WIDE_INT) 0xffffffff
2049               && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) != 0))
2050 #endif
2051       )
2052     operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2054   /* Handle MEM cases first.  */
2055   if (GET_CODE (operands[0]) == MEM)
2056     {
2057       /* If it's a REG, we can always do it.
2058          The const zero case is more complex, on v9
2059          we can always perform it.  */
2060       if (register_operand (operands[1], DImode)
2061           || (TARGET_V9
2062               && (operands[1] == const0_rtx)))
2063         goto movdi_is_ok;
2065       if (! reload_in_progress)
2066         {
2067           operands[0] = validize_mem (operands[0]);
2068           operands[1] = force_reg (DImode, operands[1]);
2069         }
2070     }
2072   /* Fixup TLS cases.  */
2073   if (tls_symbolic_operand (operands [1]))
2074     operands[1] = legitimize_tls_address (operands[1]);
2076   if (flag_pic)
2077     {
2078       if (CONSTANT_P (operands[1])
2079           && pic_address_needs_scratch (operands[1]))
2080         operands[1] = legitimize_pic_address (operands[1], DImode, 0);
2082       if (GET_CODE (operands[1]) == LABEL_REF)
2083         {
2084           if (! TARGET_ARCH64)
2085             abort ();
2086           emit_insn (gen_movdi_pic_label_ref (operands[0], operands[1]));
2087           DONE;
2088         }
2090       if (symbolic_operand (operands[1], DImode))
2091         {
2092           operands[1] = legitimize_pic_address (operands[1],
2093                                                 DImode,
2094                                                 (reload_in_progress ?
2095                                                  operands[0] :
2096                                                  NULL_RTX));
2097           goto movdi_is_ok;
2098         }
2099     }
2101   /* If we are trying to toss an integer constant into the
2102      FPU registers, force it into memory.  */
2103   if (GET_CODE (operands[0]) == REG
2104       && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
2105       && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
2106       && CONSTANT_P (operands[1]))
2107     operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2108                                                  operands[1]));
2110   /* This makes sure we will not get rematched due to splittage.  */
2111   if (! CONSTANT_P (operands[1]) || input_operand (operands[1], DImode))
2112     ;
2113   else if (TARGET_ARCH64
2114            && GET_CODE (operands[1]) != HIGH
2115            && GET_CODE (operands[1]) != LO_SUM)
2116     {
2117       sparc_emit_set_const64 (operands[0], operands[1]);
2118       DONE;
2119     }
2121  movdi_is_ok:
2122   ;
2125 ;; Be careful, fmovd does not exist when !v9.
2126 ;; We match MEM moves directly when we have correct even
2127 ;; numbered registers, but fall into splits otherwise.
2128 ;; The constraint ordering here is really important to
2129 ;; avoid insane problems in reload, especially for patterns
2130 ;; of the form:
2132 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
2133 ;;                       (const_int -5016)))
2134 ;;      (reg:DI 2 %g2))
2137 (define_insn "*movdi_insn_sp32_v9"
2138   [(set (match_operand:DI 0 "nonimmediate_operand"
2139                                         "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?e,?e,?W")
2140         (match_operand:DI 1 "input_operand"
2141                                         " J,J,U,T,r,o,i,r, f, T, o, f, e, W, e"))]
2142   "! TARGET_ARCH64 && TARGET_V9
2143    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2144   "@
2145    stx\t%%g0, %0
2146    #
2147    std\t%1, %0
2148    ldd\t%1, %0
2149    #
2150    #
2151    #
2152    #
2153    std\t%1, %0
2154    ldd\t%1, %0
2155    #
2156    #
2157    fmovd\\t%1, %0
2158    ldd\\t%1, %0
2159    std\\t%1, %0"
2160   [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,fpload,fpstore")
2161    (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,*,*")
2162    (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])
2164 (define_insn "*movdi_insn_sp32"
2165   [(set (match_operand:DI 0 "nonimmediate_operand"
2166                                 "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
2167         (match_operand:DI 1 "input_operand"
2168                                 " J,U,T,r,o,i,r, f, T, o, f, f"))]
2169   "! TARGET_ARCH64
2170    && (register_operand (operands[0], DImode)
2171        || register_operand (operands[1], DImode))"
2172   "@
2173    #
2174    std\t%1, %0
2175    ldd\t%1, %0
2176    #
2177    #
2178    #
2179    #
2180    std\t%1, %0
2181    ldd\t%1, %0
2182    #
2183    #
2184    #"
2185   [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
2186    (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
2188 ;; The following are generated by sparc_emit_set_const64
2189 (define_insn "*movdi_sp64_dbl"
2190   [(set (match_operand:DI 0 "register_operand" "=r")
2191         (match_operand:DI 1 "const64_operand" ""))]
2192   "(TARGET_ARCH64
2193     && HOST_BITS_PER_WIDE_INT != 64)"
2194   "mov\t%1, %0")
2196 ;; This is needed to show CSE exactly which bits are set
2197 ;; in a 64-bit register by sethi instructions.
2198 (define_insn "*movdi_const64_special"
2199   [(set (match_operand:DI 0 "register_operand" "=r")
2200         (match_operand:DI 1 "const64_high_operand" ""))]
2201   "TARGET_ARCH64"
2202   "sethi\t%%hi(%a1), %0")
2204 (define_insn "*movdi_insn_sp64_novis"
2205   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?W")
2206         (match_operand:DI 1 "input_operand"   "rI,N,J,m,rJ,e,W,e"))]
2207   "TARGET_ARCH64 && ! TARGET_VIS
2208    && (register_operand (operands[0], DImode)
2209        || reg_or_0_operand (operands[1], DImode))"
2210   "@
2211    mov\t%1, %0
2212    sethi\t%%hi(%a1), %0
2213    clr\t%0
2214    ldx\t%1, %0
2215    stx\t%r1, %0
2216    fmovd\t%1, %0
2217    ldd\t%1, %0
2218    std\t%1, %0"
2219   [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore")
2220    (set_attr "fptype" "*,*,*,*,*,double,*,*")])
2222 ;; We don't define V1SI because SI should work just fine.
2223 (define_mode_macro V64 [DF V2SI V4HI V8QI])
2224 (define_mode_macro V32 [SF V2HI V4QI])
2226 (define_insn "*movdi_insn_sp64_vis"
2227   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?W,b")
2228         (match_operand:DI 1 "input_operand"   "rI,N,J,m,rJ,e,W,e,J"))]
2229   "TARGET_ARCH64 && TARGET_VIS &&
2230    (register_operand (operands[0], DImode)
2231     || reg_or_0_operand (operands[1], DImode))"
2232   "@
2233    mov\t%1, %0
2234    sethi\t%%hi(%a1), %0
2235    clr\t%0
2236    ldx\t%1, %0
2237    stx\t%r1, %0
2238    fmovd\t%1, %0
2239    ldd\t%1, %0
2240    std\t%1, %0
2241    fzero\t%0"
2242   [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore,fga")
2243    (set_attr "fptype" "*,*,*,*,*,double,*,*,double")])
2245 (define_expand "movdi_pic_label_ref"
2246   [(set (match_dup 3) (high:DI
2247      (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2248                  (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2249    (set (match_dup 4) (lo_sum:DI (match_dup 3)
2250      (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2251    (set (match_operand:DI 0 "register_operand" "=r")
2252         (minus:DI (match_dup 5) (match_dup 4)))]
2253   "TARGET_ARCH64 && flag_pic"
2255   current_function_uses_pic_offset_table = 1;
2256   operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
2257   if (no_new_pseudos)
2258     {
2259       operands[3] = operands[0];
2260       operands[4] = operands[0];
2261     }
2262   else
2263     {
2264       operands[3] = gen_reg_rtx (DImode);
2265       operands[4] = gen_reg_rtx (DImode);
2266     }
2267   operands[5] = pic_offset_table_rtx;
2270 (define_insn "*movdi_high_pic_label_ref"
2271   [(set (match_operand:DI 0 "register_operand" "=r")
2272         (high:DI
2273           (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2274                       (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2275   "TARGET_ARCH64 && flag_pic"
2276   "sethi\t%%hi(%a2-(%a1-.)), %0")
2278 (define_insn "*movdi_lo_sum_pic_label_ref"
2279   [(set (match_operand:DI 0 "register_operand" "=r")
2280       (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2281         (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
2282                     (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2283   "TARGET_ARCH64 && flag_pic"
2284   "or\t%1, %%lo(%a3-(%a2-.)), %0")
2286 ;; SPARC-v9 code model support insns.  See sparc_emit_set_symbolic_const64
2287 ;; in sparc.c to see what is going on here... PIC stuff comes first.
2289 (define_insn "movdi_lo_sum_pic"
2290   [(set (match_operand:DI 0 "register_operand" "=r")
2291         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2292                    (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
2293   "TARGET_ARCH64 && flag_pic"
2294   "or\t%1, %%lo(%a2), %0")
2296 (define_insn "movdi_high_pic"
2297   [(set (match_operand:DI 0 "register_operand" "=r")
2298         (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
2299   "TARGET_ARCH64 && flag_pic && check_pic (1)"
2300   "sethi\t%%hi(%a1), %0")
2302 (define_insn "*sethi_di_medlow_embmedany_pic"
2303   [(set (match_operand:DI 0 "register_operand" "=r")
2304         (high:DI (match_operand:DI 1 "sp64_medium_pic_operand" "")))]
2305   "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
2306   "sethi\t%%hi(%a1), %0")
2308 (define_insn "*sethi_di_medlow"
2309   [(set (match_operand:DI 0 "register_operand" "=r")
2310         (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
2311   "TARGET_CM_MEDLOW && check_pic (1)"
2312   "sethi\t%%hi(%a1), %0")
2314 (define_insn "*losum_di_medlow"
2315   [(set (match_operand:DI 0 "register_operand" "=r")
2316         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2317                    (match_operand:DI 2 "symbolic_operand" "")))]
2318   "TARGET_CM_MEDLOW"
2319   "or\t%1, %%lo(%a2), %0")
2321 (define_insn "seth44"
2322   [(set (match_operand:DI 0 "register_operand" "=r")
2323         (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
2324   "TARGET_CM_MEDMID"
2325   "sethi\t%%h44(%a1), %0")
2327 (define_insn "setm44"
2328   [(set (match_operand:DI 0 "register_operand" "=r")
2329         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2330                    (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
2331   "TARGET_CM_MEDMID"
2332   "or\t%1, %%m44(%a2), %0")
2334 (define_insn "setl44"
2335   [(set (match_operand:DI 0 "register_operand" "=r")
2336         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2337                    (match_operand:DI 2 "symbolic_operand" "")))]
2338   "TARGET_CM_MEDMID"
2339   "or\t%1, %%l44(%a2), %0")
2341 (define_insn "sethh"
2342   [(set (match_operand:DI 0 "register_operand" "=r")
2343         (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
2344   "TARGET_CM_MEDANY"
2345   "sethi\t%%hh(%a1), %0")
2347 (define_insn "setlm"
2348   [(set (match_operand:DI 0 "register_operand" "=r")
2349         (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
2350   "TARGET_CM_MEDANY"
2351   "sethi\t%%lm(%a1), %0")
2353 (define_insn "sethm"
2354   [(set (match_operand:DI 0 "register_operand" "=r")
2355         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2356                    (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
2357   "TARGET_CM_MEDANY"
2358   "or\t%1, %%hm(%a2), %0")
2360 (define_insn "setlo"
2361   [(set (match_operand:DI 0 "register_operand" "=r")
2362         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2363                    (match_operand:DI 2 "symbolic_operand" "")))]
2364   "TARGET_CM_MEDANY"
2365   "or\t%1, %%lo(%a2), %0")
2367 (define_insn "embmedany_sethi"
2368   [(set (match_operand:DI 0 "register_operand" "=r")
2369         (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
2370   "TARGET_CM_EMBMEDANY && check_pic (1)"
2371   "sethi\t%%hi(%a1), %0")
2373 (define_insn "embmedany_losum"
2374   [(set (match_operand:DI 0 "register_operand" "=r")
2375         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2376                    (match_operand:DI 2 "data_segment_operand" "")))]
2377   "TARGET_CM_EMBMEDANY"
2378   "add\t%1, %%lo(%a2), %0")
2380 (define_insn "embmedany_brsum"
2381   [(set (match_operand:DI 0 "register_operand" "=r")
2382         (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
2383   "TARGET_CM_EMBMEDANY"
2384   "add\t%1, %_, %0")
2386 (define_insn "embmedany_textuhi"
2387   [(set (match_operand:DI 0 "register_operand" "=r")
2388         (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
2389   "TARGET_CM_EMBMEDANY && check_pic (1)"
2390   "sethi\t%%uhi(%a1), %0")
2392 (define_insn "embmedany_texthi"
2393   [(set (match_operand:DI 0 "register_operand" "=r")
2394         (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
2395   "TARGET_CM_EMBMEDANY && check_pic (1)"
2396   "sethi\t%%hi(%a1), %0")
2398 (define_insn "embmedany_textulo"
2399   [(set (match_operand:DI 0 "register_operand" "=r")
2400         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2401                    (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
2402   "TARGET_CM_EMBMEDANY"
2403   "or\t%1, %%ulo(%a2), %0")
2405 (define_insn "embmedany_textlo"
2406   [(set (match_operand:DI 0 "register_operand" "=r")
2407         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2408                    (match_operand:DI 2 "text_segment_operand" "")))]
2409   "TARGET_CM_EMBMEDANY"
2410   "or\t%1, %%lo(%a2), %0")
2412 ;; Now some patterns to help reload out a bit.
2413 (define_expand "reload_indi"
2414   [(parallel [(match_operand:DI 0 "register_operand" "=r")
2415               (match_operand:DI 1 "immediate_operand" "")
2416               (match_operand:TI 2 "register_operand" "=&r")])]
2417   "(TARGET_CM_MEDANY
2418     || TARGET_CM_EMBMEDANY)
2419    && ! flag_pic"
2421   sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2422   DONE;
2425 (define_expand "reload_outdi"
2426   [(parallel [(match_operand:DI 0 "register_operand" "=r")
2427               (match_operand:DI 1 "immediate_operand" "")
2428               (match_operand:TI 2 "register_operand" "=&r")])]
2429   "(TARGET_CM_MEDANY
2430     || TARGET_CM_EMBMEDANY)
2431    && ! flag_pic"
2433   sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2434   DONE;
2437 ;; Split up putting CONSTs and REGs into DI regs when !arch64
2438 (define_split
2439   [(set (match_operand:DI 0 "register_operand" "")
2440         (match_operand:DI 1 "const_int_operand" ""))]
2441   "! TARGET_ARCH64 && reload_completed"
2442   [(clobber (const_int 0))]
2444 #if HOST_BITS_PER_WIDE_INT == 32
2445   emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2446                         (INTVAL (operands[1]) < 0) ?
2447                         constm1_rtx :
2448                         const0_rtx));
2449   emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2450                         operands[1]));
2451 #else
2452   unsigned int low, high;
2454   low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
2455   high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
2456   emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
2458   /* Slick... but this trick loses if this subreg constant part
2459      can be done in one insn.  */
2460   if (low == high && (low & 0x3ff) != 0 && low + 0x1000 >= 0x2000)
2461     emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2462                           gen_highpart (SImode, operands[0])));
2463   else
2464     emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
2465 #endif
2466   DONE;
2469 (define_split
2470   [(set (match_operand:DI 0 "register_operand" "")
2471         (match_operand:DI 1 "const_double_operand" ""))]
2472   "reload_completed
2473    && (! TARGET_V9
2474        || (! TARGET_ARCH64
2475            && ((GET_CODE (operands[0]) == REG
2476                 && REGNO (operands[0]) < 32)
2477                || (GET_CODE (operands[0]) == SUBREG
2478                    && GET_CODE (SUBREG_REG (operands[0])) == REG
2479                    && REGNO (SUBREG_REG (operands[0])) < 32))))"
2480   [(clobber (const_int 0))]
2482   emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2483                         GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
2485   /* Slick... but this trick loses if this subreg constant part
2486      can be done in one insn.  */
2487   if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
2488       && !(SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
2489            || SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1]))))
2490     {
2491       emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2492                             gen_highpart (SImode, operands[0])));
2493     }
2494   else
2495     {
2496       emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2497                             GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
2498     }
2499   DONE;
2502 (define_split
2503   [(set (match_operand:DI 0 "register_operand" "")
2504         (match_operand:DI 1 "register_operand" ""))]
2505   "reload_completed
2506    && (! TARGET_V9
2507        || (! TARGET_ARCH64
2508            && ((GET_CODE (operands[0]) == REG
2509                 && REGNO (operands[0]) < 32)
2510                || (GET_CODE (operands[0]) == SUBREG
2511                    && GET_CODE (SUBREG_REG (operands[0])) == REG
2512                    && REGNO (SUBREG_REG (operands[0])) < 32))))"
2513   [(clobber (const_int 0))]
2515   rtx set_dest = operands[0];
2516   rtx set_src = operands[1];
2517   rtx dest1, dest2;
2518   rtx src1, src2;
2520   dest1 = gen_highpart (SImode, set_dest);
2521   dest2 = gen_lowpart (SImode, set_dest);
2522   src1 = gen_highpart (SImode, set_src);
2523   src2 = gen_lowpart (SImode, set_src);
2525   /* Now emit using the real source and destination we found, swapping
2526      the order if we detect overlap.  */
2527   if (reg_overlap_mentioned_p (dest1, src2))
2528     {
2529       emit_insn (gen_movsi (dest2, src2));
2530       emit_insn (gen_movsi (dest1, src1));
2531     }
2532   else
2533     {
2534       emit_insn (gen_movsi (dest1, src1));
2535       emit_insn (gen_movsi (dest2, src2));
2536     }
2537   DONE;
2540 ;; Now handle the cases of memory moves from/to non-even
2541 ;; DI mode register pairs.
2542 (define_split
2543   [(set (match_operand:DI 0 "register_operand" "")
2544         (match_operand:DI 1 "memory_operand" ""))]
2545   "(! TARGET_ARCH64
2546     && reload_completed
2547     && sparc_splitdi_legitimate (operands[0], operands[1]))"
2548   [(clobber (const_int 0))]
2550   rtx word0 = adjust_address (operands[1], SImode, 0);
2551   rtx word1 = adjust_address (operands[1], SImode, 4);
2552   rtx high_part = gen_highpart (SImode, operands[0]);
2553   rtx low_part = gen_lowpart (SImode, operands[0]);
2555   if (reg_overlap_mentioned_p (high_part, word1))
2556     {
2557       emit_insn (gen_movsi (low_part, word1));
2558       emit_insn (gen_movsi (high_part, word0));
2559     }
2560   else
2561     {
2562       emit_insn (gen_movsi (high_part, word0));
2563       emit_insn (gen_movsi (low_part, word1));
2564     }
2565   DONE;
2568 (define_split
2569   [(set (match_operand:DI 0 "memory_operand" "")
2570         (match_operand:DI 1 "register_operand" ""))]
2571   "(! TARGET_ARCH64
2572     && reload_completed
2573     && sparc_splitdi_legitimate (operands[1], operands[0]))"
2574   [(clobber (const_int 0))]
2576   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
2577                         gen_highpart (SImode, operands[1])));
2578   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
2579                         gen_lowpart (SImode, operands[1])));
2580   DONE;
2583 (define_split
2584   [(set (match_operand:DI 0 "memory_operand" "")
2585         (const_int 0))]
2586   "reload_completed
2587    && (! TARGET_V9
2588        || (! TARGET_ARCH64
2589            && ! mem_min_alignment (operands[0], 8)))
2590    && offsettable_memref_p (operands[0])"
2591   [(clobber (const_int 0))]
2593   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
2594   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
2595   DONE;
2598 ;; Floating point move insns
2600 (define_insn "*movsf_insn_novis"
2601   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,*r,*r,*r,*r,*r,f,m,m")
2602         (match_operand:SF 1 "input_operand"         "f,G,Q,*rR,S,m,m,f,*rG"))]
2603   "(TARGET_FPU && ! TARGET_VIS)
2604    && (register_operand (operands[0], SFmode)
2605        || register_operand (operands[1], SFmode)
2606        || fp_zero_operand (operands[1], SFmode))"
2608   if (GET_CODE (operands[1]) == CONST_DOUBLE
2609       && (which_alternative == 2
2610           || which_alternative == 3
2611           || which_alternative == 4))
2612     {
2613       REAL_VALUE_TYPE r;
2614       long i;
2616       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2617       REAL_VALUE_TO_TARGET_SINGLE (r, i);
2618       operands[1] = GEN_INT (i);
2619     }
2621   switch (which_alternative)
2622     {
2623     case 0:
2624       return "fmovs\t%1, %0";
2625     case 1:
2626       return "clr\t%0";
2627     case 2:
2628       return "sethi\t%%hi(%a1), %0";
2629     case 3:
2630       return "mov\t%1, %0";
2631     case 4:
2632       return "#";
2633     case 5:
2634     case 6:
2635       return "ld\t%1, %0";
2636     case 7:
2637     case 8:
2638       return "st\t%r1, %0";
2639     default:
2640       abort();
2641     }
2643   [(set_attr "type" "fpmove,*,*,*,*,load,fpload,fpstore,store")])
2645 (define_insn "*movsf_insn_vis"
2646   [(set (match_operand:V32 0 "nonimmediate_operand" "=f,f,*r,*r,*r,*r,*r,f,m,m")
2647         (match_operand:V32 1 "input_operand"         "f,GY,GY,Q,*rR,S,m,m,f,*rGY"))]
2648   "(TARGET_FPU && TARGET_VIS)
2649    && (register_operand (operands[0], <V32:MODE>mode)
2650        || register_operand (operands[1], <V32:MODE>mode)
2651        || fp_zero_operand (operands[1], <V32:MODE>mode))"
2653   if (GET_CODE (operands[1]) == CONST_DOUBLE
2654       && (which_alternative == 3
2655           || which_alternative == 4
2656           || which_alternative == 5))
2657     {
2658       REAL_VALUE_TYPE r;
2659       long i;
2661       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2662       REAL_VALUE_TO_TARGET_SINGLE (r, i);
2663       operands[1] = GEN_INT (i);
2664     }
2666   switch (which_alternative)
2667     {
2668     case 0:
2669       return "fmovs\t%1, %0";
2670     case 1:
2671       return "fzeros\t%0";
2672     case 2:
2673       return "clr\t%0";
2674     case 3:
2675       return "sethi\t%%hi(%a1), %0";
2676     case 4:
2677       return "mov\t%1, %0";
2678     case 5:
2679       return "#";
2680     case 6:
2681     case 7:
2682       return "ld\t%1, %0";
2683     case 8:
2684     case 9:
2685       return "st\t%r1, %0";
2686     default:
2687       abort();
2688     }
2690   [(set_attr "type" "fpmove,fga,*,*,*,*,load,fpload,fpstore,store")])
2692 ;; Exactly the same as above, except that all `f' cases are deleted.
2693 ;; This is necessary to prevent reload from ever trying to use a `f' reg
2694 ;; when -mno-fpu.
2696 (define_insn "*movsf_no_f_insn"
2697   [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,r,m")
2698         (match_operand:SF 1 "input_operand"    "G,Q,rR,S,m,rG"))]
2699   "! TARGET_FPU
2700    && (register_operand (operands[0], SFmode)
2701        || register_operand (operands[1], SFmode)
2702        || fp_zero_operand (operands[1], SFmode))"
2704   if (GET_CODE (operands[1]) == CONST_DOUBLE
2705       && (which_alternative == 1
2706           || which_alternative == 2
2707           || which_alternative == 3))
2708     {
2709       REAL_VALUE_TYPE r;
2710       long i;
2712       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2713       REAL_VALUE_TO_TARGET_SINGLE (r, i);
2714       operands[1] = GEN_INT (i);
2715     }
2717   switch (which_alternative)
2718     {
2719     case 0:
2720       return "clr\t%0";
2721     case 1:
2722       return "sethi\t%%hi(%a1), %0";
2723     case 2:
2724       return "mov\t%1, %0";
2725     case 3:
2726       return "#";
2727     case 4:
2728       return "ld\t%1, %0";
2729     case 5:
2730       return "st\t%r1, %0";
2731     default:
2732       abort();
2733     }
2735   [(set_attr "type" "*,*,*,*,load,store")])
2737 ;; The following 3 patterns build SFmode constants in integer registers.
2739 (define_insn "*movsf_lo_sum"
2740   [(set (match_operand:SF 0 "register_operand" "=r")
2741         (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
2742                    (match_operand:SF 2 "const_double_operand" "S")))]
2743   "fp_high_losum_p (operands[2])"
2745   REAL_VALUE_TYPE r;
2746   long i;
2748   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
2749   REAL_VALUE_TO_TARGET_SINGLE (r, i);
2750   operands[2] = GEN_INT (i);
2751   return "or\t%1, %%lo(%a2), %0";
2754 (define_insn "*movsf_high"
2755   [(set (match_operand:SF 0 "register_operand" "=r")
2756         (high:SF (match_operand:SF 1 "const_double_operand" "S")))]
2757   "fp_high_losum_p (operands[1])"
2759   REAL_VALUE_TYPE r;
2760   long i;
2762   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2763   REAL_VALUE_TO_TARGET_SINGLE (r, i);
2764   operands[1] = GEN_INT (i);
2765   return "sethi\t%%hi(%1), %0";
2768 (define_split
2769   [(set (match_operand:SF 0 "register_operand" "")
2770         (match_operand:SF 1 "const_double_operand" ""))]
2771   "fp_high_losum_p (operands[1])
2772    && (GET_CODE (operands[0]) == REG
2773        && REGNO (operands[0]) < 32)"
2774   [(set (match_dup 0) (high:SF (match_dup 1)))
2775    (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
2777 ;; Yes, you guessed it right, the former movsf expander.
2778 (define_expand "mov<V32:mode>"
2779   [(set (match_operand:V32 0 "general_operand" "")
2780         (match_operand:V32 1 "general_operand" ""))]
2781   "<V32:MODE>mode == SFmode || TARGET_VIS"
2783   /* Force constants into memory.  */
2784   if (GET_CODE (operands[0]) == REG && CONSTANT_P (operands[1]))
2785     {
2786       /* emit_group_store will send such bogosity to us when it is
2787          not storing directly into memory.  So fix this up to avoid
2788          crashes in output_constant_pool.  */
2789       if (operands [1] == const0_rtx)
2790         operands[1] = CONST0_RTX (<V32:MODE>mode);
2792       if ((TARGET_VIS || REGNO (operands[0]) < 32)
2793           && fp_zero_operand (operands[1], <V32:MODE>mode))
2794         goto movsf_is_ok;
2796       /* We are able to build any SF constant in integer registers
2797          with at most 2 instructions.  */
2798       if (REGNO (operands[0]) < 32
2799           && <V32:MODE>mode == SFmode)
2800         goto movsf_is_ok;
2802       operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2803                                                    operands[1]));
2804     }
2806   /* Handle sets of MEM first.  */
2807   if (GET_CODE (operands[0]) == MEM)
2808     {
2809       if (register_operand (operands[1], <V32:MODE>mode)
2810           || fp_zero_operand (operands[1], <V32:MODE>mode))
2811         goto movsf_is_ok;
2813       if (! reload_in_progress)
2814         {
2815           operands[0] = validize_mem (operands[0]);
2816           operands[1] = force_reg (<V32:MODE>mode, operands[1]);
2817         }
2818     }
2820   /* Fixup PIC cases.  */
2821   if (flag_pic)
2822     {
2823       if (CONSTANT_P (operands[1])
2824           && pic_address_needs_scratch (operands[1]))
2825         operands[1] = legitimize_pic_address (operands[1], <V32:MODE>mode, 0);
2827       if (symbolic_operand (operands[1], <V32:MODE>mode))
2828         {
2829           operands[1] = legitimize_pic_address (operands[1],
2830                                                 <V32:MODE>mode,
2831                                                 (reload_in_progress ?
2832                                                  operands[0] :
2833                                                  NULL_RTX));
2834         }
2835     }
2837  movsf_is_ok:
2838   ;
2841 ;; Yes, you again guessed it right, the former movdf expander.
2842 (define_expand "mov<V64:mode>"
2843   [(set (match_operand:V64 0 "general_operand" "")
2844         (match_operand:V64 1 "general_operand" ""))]
2845   "<V64:MODE>mode == DFmode || TARGET_VIS"
2847   /* Force constants into memory.  */
2848   if (GET_CODE (operands[0]) == REG && CONSTANT_P (operands[1]))
2849     {
2850       /* emit_group_store will send such bogosity to us when it is
2851          not storing directly into memory.  So fix this up to avoid
2852          crashes in output_constant_pool.  */
2853       if (operands [1] == const0_rtx)
2854         operands[1] = CONST0_RTX (<V64:MODE>mode);
2856       if ((TARGET_VIS || REGNO (operands[0]) < 32)
2857           && fp_zero_operand (operands[1], <V64:MODE>mode))
2858         goto movdf_is_ok;
2860       /* We are able to build any DF constant in integer registers.  */
2861       if (REGNO (operands[0]) < 32
2862           && <V64:MODE>mode == DFmode
2863           && (reload_completed || reload_in_progress))
2864         goto movdf_is_ok;
2866       operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2867                                                    operands[1]));
2868     }
2870   /* Handle MEM cases first.  */
2871   if (GET_CODE (operands[0]) == MEM)
2872     {
2873       if (register_operand (operands[1], <V64:MODE>mode)
2874           || fp_zero_operand (operands[1], <V64:MODE>mode))
2875         goto movdf_is_ok;
2877       if (! reload_in_progress)
2878         {
2879           operands[0] = validize_mem (operands[0]);
2880           operands[1] = force_reg (<V64:MODE>mode, operands[1]);
2881         }
2882     }
2884   /* Fixup PIC cases.  */
2885   if (flag_pic)
2886     {
2887       if (CONSTANT_P (operands[1])
2888           && pic_address_needs_scratch (operands[1]))
2889         operands[1] = legitimize_pic_address (operands[1], <V64:MODE>mode, 0);
2891       if (symbolic_operand (operands[1], <V64:MODE>mode))
2892         {
2893           operands[1] = legitimize_pic_address (operands[1],
2894                                                 <V64:MODE>mode,
2895                                                 (reload_in_progress ?
2896                                                  operands[0] :
2897                                                  NULL_RTX));
2898         }
2899     }
2901  movdf_is_ok:
2902   ;
2905 ;; Be careful, fmovd does not exist when !v9.
2906 (define_insn "*movdf_insn_sp32"
2907   [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o")
2908         (match_operand:DF 1 "input_operand"    "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
2909   "TARGET_FPU
2910    && ! TARGET_V9
2911    && (register_operand (operands[0], DFmode)
2912        || register_operand (operands[1], DFmode)
2913        || fp_zero_operand (operands[1], DFmode))"
2914   "@
2915   ldd\t%1, %0
2916   std\t%1, %0
2917   ldd\t%1, %0
2918   std\t%1, %0
2919   #
2920   #
2921   #
2922   #
2923   #
2924   #"
2925  [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
2926   (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
2928 (define_insn "*movdf_no_e_insn_sp32"
2929   [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
2930         (match_operand:DF 1 "input_operand"    "T,U,G,ro,r"))]
2931   "! TARGET_FPU
2932    && ! TARGET_V9
2933    && ! TARGET_ARCH64
2934    && (register_operand (operands[0], DFmode)
2935        || register_operand (operands[1], DFmode)
2936        || fp_zero_operand (operands[1], DFmode))"
2937   "@
2938   ldd\t%1, %0
2939   std\t%1, %0
2940   #
2941   #
2942   #"
2943   [(set_attr "type" "load,store,*,*,*")
2944    (set_attr "length" "*,*,2,2,2")])
2946 (define_insn "*movdf_no_e_insn_v9_sp32"
2947   [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
2948         (match_operand:DF 1 "input_operand"    "T,U,G,ro,rG"))]
2949   "! TARGET_FPU
2950    && TARGET_V9
2951    && ! TARGET_ARCH64
2952    && (register_operand (operands[0], DFmode)
2953        || register_operand (operands[1], DFmode)
2954        || fp_zero_operand (operands[1], DFmode))"
2955   "@
2956   ldd\t%1, %0
2957   std\t%1, %0
2958   stx\t%r1, %0
2959   #
2960   #"
2961   [(set_attr "type" "load,store,store,*,*")
2962    (set_attr "length" "*,*,*,2,2")])
2964 ;; We have available v9 double floats but not 64-bit
2965 ;; integer registers and no VIS.
2966 (define_insn "*movdf_insn_v9only_novis"
2967   [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,T,W,U,T,f,*r,o")
2968         (match_operand:DF 1 "input_operand"    "e,W#F,G,e,T,U,o#F,*roF,*rGf"))]
2969   "TARGET_FPU
2970    && TARGET_V9
2971    && ! TARGET_VIS
2972    && ! TARGET_ARCH64
2973    && (register_operand (operands[0], DFmode)
2974        || register_operand (operands[1], DFmode)
2975        || fp_zero_operand (operands[1], DFmode))"
2976   "@
2977   fmovd\t%1, %0
2978   ldd\t%1, %0
2979   stx\t%r1, %0
2980   std\t%1, %0
2981   ldd\t%1, %0
2982   std\t%1, %0
2983   #
2984   #
2985   #"
2986   [(set_attr "type" "fpmove,load,store,store,load,store,*,*,*")
2987    (set_attr "length" "*,*,*,*,*,*,2,2,2")
2988    (set_attr "fptype" "double,*,*,*,*,*,*,*,*")])
2990 ;; We have available v9 double floats but not 64-bit
2991 ;; integer registers but we have VIS.
2992 (define_insn "*movdf_insn_v9only_vis"
2993   [(set (match_operand:V64 0 "nonimmediate_operand" "=e,e,e,T,W,U,T,f,*r,o")
2994         (match_operand:V64 1 "input_operand" "GY,e,W#F,GY,e,T,U,o#F,*roGYF,*rGYf"))]
2995   "TARGET_FPU
2996    && TARGET_VIS
2997    && ! TARGET_ARCH64
2998    && (register_operand (operands[0], <V64:MODE>mode)
2999        || register_operand (operands[1], <V64:MODE>mode)
3000        || fp_zero_operand (operands[1], <V64:MODE>mode))"
3001   "@
3002   fzero\t%0
3003   fmovd\t%1, %0
3004   ldd\t%1, %0
3005   stx\t%r1, %0
3006   std\t%1, %0
3007   ldd\t%1, %0
3008   std\t%1, %0
3009   #
3010   #
3011   #"
3012   [(set_attr "type" "fga,fpmove,load,store,store,load,store,*,*,*")
3013    (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
3014    (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
3016 ;; We have available both v9 double floats and 64-bit
3017 ;; integer registers. No VIS though.
3018 (define_insn "*movdf_insn_sp64_novis"
3019   [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,W,*r,*r,m,*r")
3020         (match_operand:DF 1 "input_operand"    "e,W#F,e,*rG,m,*rG,F"))]
3021   "TARGET_FPU
3022    && ! TARGET_VIS
3023    && TARGET_ARCH64
3024    && (register_operand (operands[0], DFmode)
3025        || register_operand (operands[1], DFmode)
3026        || fp_zero_operand (operands[1], DFmode))"
3027   "@
3028   fmovd\t%1, %0
3029   ldd\t%1, %0
3030   std\t%1, %0
3031   mov\t%r1, %0
3032   ldx\t%1, %0
3033   stx\t%r1, %0
3034   #"
3035   [(set_attr "type" "fpmove,load,store,*,load,store,*")
3036    (set_attr "length" "*,*,*,*,*,*,2")
3037    (set_attr "fptype" "double,*,*,*,*,*,*")])
3039 ;; We have available both v9 double floats and 64-bit
3040 ;; integer registers. And we have VIS.
3041 (define_insn "*movdf_insn_sp64_vis"
3042   [(set (match_operand:V64 0 "nonimmediate_operand" "=e,e,e,W,*r,*r,m,*r")
3043         (match_operand:V64 1 "input_operand"    "GY,e,W#F,e,*rGY,m,*rGY,F"))]
3044   "TARGET_FPU
3045    && TARGET_VIS
3046    && TARGET_ARCH64
3047    && (register_operand (operands[0], <V64:MODE>mode)
3048        || register_operand (operands[1], <V64:MODE>mode)
3049        || fp_zero_operand (operands[1], <V64:MODE>mode))"
3050   "@
3051   fzero\t%0
3052   fmovd\t%1, %0
3053   ldd\t%1, %0
3054   std\t%1, %0
3055   mov\t%r1, %0
3056   ldx\t%1, %0
3057   stx\t%r1, %0
3058   #"
3059   [(set_attr "type" "fga,fpmove,load,store,*,load,store,*")
3060    (set_attr "length" "*,*,*,*,*,*,*,2")
3061    (set_attr "fptype" "double,double,*,*,*,*,*,*")])
3063 (define_insn "*movdf_no_e_insn_sp64"
3064   [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
3065         (match_operand:DF 1 "input_operand"    "r,m,rG"))]
3066   "! TARGET_FPU
3067    && TARGET_ARCH64
3068    && (register_operand (operands[0], DFmode)
3069        || register_operand (operands[1], DFmode)
3070        || fp_zero_operand (operands[1], DFmode))"
3071   "@
3072   mov\t%1, %0
3073   ldx\t%1, %0
3074   stx\t%r1, %0"
3075   [(set_attr "type" "*,load,store")])
3077 ;; This pattern build DFmode constants in integer registers.
3078 (define_split
3079   [(set (match_operand:DF 0 "register_operand" "")
3080         (match_operand:DF 1 "const_double_operand" ""))]
3081   "TARGET_FPU
3082    && (GET_CODE (operands[0]) == REG
3083        && REGNO (operands[0]) < 32)
3084    && ! fp_zero_operand(operands[1], DFmode)
3085    && reload_completed"
3086   [(clobber (const_int 0))]
3088   REAL_VALUE_TYPE r;
3089   long l[2];
3091   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3092   REAL_VALUE_TO_TARGET_DOUBLE (r, l);
3093   operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
3095   if (TARGET_ARCH64)
3096     {
3097 #if HOST_BITS_PER_WIDE_INT == 64
3098       HOST_WIDE_INT val;
3100       val = ((HOST_WIDE_INT)(unsigned long)l[1] |
3101              ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
3102       emit_insn (gen_movdi (operands[0], GEN_INT (val)));
3103 #else
3104       emit_insn (gen_movdi (operands[0],
3105                             immed_double_const (l[1], l[0], DImode)));
3106 #endif
3107     }
3108   else
3109     {
3110       emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
3111                             GEN_INT (l[0])));
3113       /* Slick... but this trick loses if this subreg constant part
3114          can be done in one insn.  */
3115       if (l[1] == l[0]
3116           && !(SPARC_SETHI32_P (l[0])
3117                || SPARC_SIMM13_P (l[0])))
3118         {
3119           emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3120                                 gen_highpart (SImode, operands[0])));
3121         }
3122       else
3123         {
3124           emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3125                                 GEN_INT (l[1])));
3126         }
3127     }
3128   DONE;
3131 ;; Ok, now the splits to handle all the multi insn and
3132 ;; mis-aligned memory address cases.
3133 ;; In these splits please take note that we must be
3134 ;; careful when V9 but not ARCH64 because the integer
3135 ;; register DFmode cases must be handled.
3136 (define_split
3137   [(set (match_operand:V64 0 "register_operand" "")
3138         (match_operand:V64 1 "register_operand" ""))]
3139   "(! TARGET_V9
3140     || (! TARGET_ARCH64
3141         && ((GET_CODE (operands[0]) == REG
3142              && REGNO (operands[0]) < 32)
3143             || (GET_CODE (operands[0]) == SUBREG
3144                 && GET_CODE (SUBREG_REG (operands[0])) == REG
3145                 && REGNO (SUBREG_REG (operands[0])) < 32))))
3146    && reload_completed"
3147   [(clobber (const_int 0))]
3149   rtx set_dest = operands[0];
3150   rtx set_src = operands[1];
3151   rtx dest1, dest2;
3152   rtx src1, src2;
3153   enum machine_mode half_mode;
3155   /* We can be expanded for DFmode or integral vector modes.  */
3156   if (<V64:MODE>mode == DFmode)
3157     half_mode = SFmode;
3158   else
3159     half_mode = SImode;
3160   
3161   dest1 = gen_highpart (half_mode, set_dest);
3162   dest2 = gen_lowpart (half_mode, set_dest);
3163   src1 = gen_highpart (half_mode, set_src);
3164   src2 = gen_lowpart (half_mode, set_src);
3166   /* Now emit using the real source and destination we found, swapping
3167      the order if we detect overlap.  */
3168   if (reg_overlap_mentioned_p (dest1, src2))
3169     {
3170       emit_move_insn_1 (dest2, src2);
3171       emit_move_insn_1 (dest1, src1);
3172     }
3173   else
3174     {
3175       emit_move_insn_1 (dest1, src1);
3176       emit_move_insn_1 (dest2, src2);
3177     }
3178   DONE;
3181 (define_split
3182   [(set (match_operand:V64 0 "register_operand" "")
3183         (match_operand:V64 1 "memory_operand" ""))]
3184   "reload_completed
3185    && ! TARGET_ARCH64
3186    && (((REGNO (operands[0]) % 2) != 0)
3187        || ! mem_min_alignment (operands[1], 8))
3188    && offsettable_memref_p (operands[1])"
3189   [(clobber (const_int 0))]
3191   enum machine_mode half_mode;
3192   rtx word0, word1;
3194   /* We can be expanded for DFmode or integral vector modes.  */
3195   if (<V64:MODE>mode == DFmode)
3196     half_mode = SFmode;
3197   else
3198     half_mode = SImode;
3200   word0 = adjust_address (operands[1], half_mode, 0);
3201   word1 = adjust_address (operands[1], half_mode, 4);
3203   if (reg_overlap_mentioned_p (gen_highpart (half_mode, operands[0]), word1))
3204     {
3205       emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
3206       emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
3207     }
3208   else
3209     {
3210       emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
3211       emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
3212     }
3213   DONE;
3216 (define_split
3217   [(set (match_operand:V64 0 "memory_operand" "")
3218         (match_operand:V64 1 "register_operand" ""))]
3219   "reload_completed
3220    && ! TARGET_ARCH64
3221    && (((REGNO (operands[1]) % 2) != 0)
3222        || ! mem_min_alignment (operands[0], 8))
3223    && offsettable_memref_p (operands[0])"
3224   [(clobber (const_int 0))]
3226   enum machine_mode half_mode;
3227   rtx word0, word1;
3229   /* We can be expanded for DFmode or integral vector modes.  */
3230   if (<V64:MODE>mode == DFmode)
3231     half_mode = SFmode;
3232   else
3233     half_mode = SImode;
3235   word0 = adjust_address (operands[0], half_mode, 0);
3236   word1 = adjust_address (operands[0], half_mode, 4);
3238   emit_move_insn_1 (word0, gen_highpart (half_mode, operands[1]));
3239   emit_move_insn_1 (word1, gen_lowpart (half_mode, operands[1]));
3240   DONE;
3243 (define_split
3244   [(set (match_operand:V64 0 "memory_operand" "")
3245         (match_operand:V64 1 "fp_zero_operand" ""))]
3246   "reload_completed
3247    && (! TARGET_V9
3248        || (! TARGET_ARCH64
3249            && ! mem_min_alignment (operands[0], 8)))
3250    && offsettable_memref_p (operands[0])"
3251   [(clobber (const_int 0))]
3253   enum machine_mode half_mode;
3254   rtx dest1, dest2;
3256   /* We can be expanded for DFmode or integral vector modes.  */
3257   if (<V64:MODE>mode == DFmode)
3258     half_mode = SFmode;
3259   else
3260     half_mode = SImode;
3262   dest1 = adjust_address (operands[0], half_mode, 0);
3263   dest2 = adjust_address (operands[0], half_mode, 4);
3265   emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
3266   emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
3267   DONE;
3270 (define_split
3271   [(set (match_operand:V64 0 "register_operand" "")
3272         (match_operand:V64 1 "fp_zero_operand" ""))]
3273   "reload_completed
3274    && ! TARGET_ARCH64
3275    && ((GET_CODE (operands[0]) == REG
3276         && REGNO (operands[0]) < 32)
3277        || (GET_CODE (operands[0]) == SUBREG
3278            && GET_CODE (SUBREG_REG (operands[0])) == REG
3279            && REGNO (SUBREG_REG (operands[0])) < 32))"
3280   [(clobber (const_int 0))]
3282   enum machine_mode half_mode;
3283   rtx set_dest = operands[0];
3284   rtx dest1, dest2;
3286   /* We can be expanded for DFmode or integral vector modes.  */
3287   if (<V64:MODE>mode == DFmode)
3288     half_mode = SFmode;
3289   else
3290     half_mode = SImode;
3292   dest1 = gen_highpart (half_mode, set_dest);
3293   dest2 = gen_lowpart (half_mode, set_dest);
3294   emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
3295   emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
3296   DONE;
3299 (define_expand "movtf"
3300   [(set (match_operand:TF 0 "general_operand" "")
3301         (match_operand:TF 1 "general_operand" ""))]
3302   ""
3304   /* Force TFmode constants into memory.  */
3305   if (GET_CODE (operands[0]) == REG
3306       && CONSTANT_P (operands[1]))
3307     {
3308       /* emit_group_store will send such bogosity to us when it is
3309          not storing directly into memory.  So fix this up to avoid
3310          crashes in output_constant_pool.  */
3311       if (operands [1] == const0_rtx)
3312         operands[1] = CONST0_RTX (TFmode);
3314       if (TARGET_VIS && fp_zero_operand (operands[1], TFmode))
3315         goto movtf_is_ok;
3317       operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3318                                                    operands[1]));
3319     }
3321   /* Handle MEM cases first, note that only v9 guarantees
3322      full 16-byte alignment for quads.  */
3323   if (GET_CODE (operands[0]) == MEM)
3324     {
3325       if (register_operand (operands[1], TFmode)
3326           || fp_zero_operand (operands[1], TFmode))
3327         goto movtf_is_ok;
3329       if (! reload_in_progress)
3330         {
3331           operands[0] = validize_mem (operands[0]);
3332           operands[1] = force_reg (TFmode, operands[1]);
3333         }
3334     }
3336   /* Fixup PIC cases.  */
3337   if (flag_pic)
3338     {
3339       if (CONSTANT_P (operands[1])
3340           && pic_address_needs_scratch (operands[1]))
3341         operands[1] = legitimize_pic_address (operands[1], TFmode, 0);
3343       if (symbolic_operand (operands[1], TFmode))
3344         {
3345           operands[1] = legitimize_pic_address (operands[1],
3346                                                 TFmode,
3347                                                 (reload_in_progress ?
3348                                                  operands[0] :
3349                                                  NULL_RTX));
3350         }
3351     }
3353  movtf_is_ok:
3354   ;
3357 ;; Be careful, fmovq and {st,ld}{x,q} do not exist when !arch64 so
3358 ;; we must split them all.  :-(
3359 (define_insn "*movtf_insn_sp32"
3360   [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3361         (match_operand:TF 1 "input_operand"    "oe,GeUr,o,roG"))]
3362   "TARGET_FPU
3363    && ! TARGET_VIS
3364    && ! TARGET_ARCH64
3365    && (register_operand (operands[0], TFmode)
3366        || register_operand (operands[1], TFmode)
3367        || fp_zero_operand (operands[1], TFmode))"
3368   "#"
3369   [(set_attr "length" "4")])
3371 (define_insn "*movtf_insn_vis_sp32"
3372   [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3373         (match_operand:TF 1 "input_operand"    "Goe,GeUr,o,roG"))]
3374   "TARGET_FPU
3375    && TARGET_VIS
3376    && ! TARGET_ARCH64
3377    && (register_operand (operands[0], TFmode)
3378        || register_operand (operands[1], TFmode)
3379        || fp_zero_operand (operands[1], TFmode))"
3380   "#"
3381   [(set_attr "length" "4")])
3383 ;; Exactly the same as above, except that all `e' cases are deleted.
3384 ;; This is necessary to prevent reload from ever trying to use a `e' reg
3385 ;; when -mno-fpu.
3387 (define_insn "*movtf_no_e_insn_sp32"
3388   [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
3389         (match_operand:TF 1 "input_operand"    "G,o,U,roG,r"))]
3390   "! TARGET_FPU
3391    && ! TARGET_ARCH64
3392    && (register_operand (operands[0], TFmode)
3393        || register_operand (operands[1], TFmode)
3394        || fp_zero_operand (operands[1], TFmode))"
3395   "#"
3396   [(set_attr "length" "4")])
3398 ;; Now handle the float reg cases directly when arch64,
3399 ;; hard_quad, and proper reg number alignment are all true.
3400 (define_insn "*movtf_insn_hq_sp64"
3401   [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,o,r")
3402         (match_operand:TF 1 "input_operand"    "e,m,e,Gr,roG"))]
3403   "TARGET_FPU
3404    && ! TARGET_VIS
3405    && TARGET_ARCH64
3406    && TARGET_HARD_QUAD
3407    && (register_operand (operands[0], TFmode)
3408        || register_operand (operands[1], TFmode)
3409        || fp_zero_operand (operands[1], TFmode))"
3410   "@
3411   fmovq\t%1, %0
3412   ldq\t%1, %0
3413   stq\t%1, %0
3414   #
3415   #"
3416   [(set_attr "type" "fpmove,fpload,fpstore,*,*")
3417    (set_attr "length" "*,*,*,2,2")])
3419 (define_insn "*movtf_insn_hq_vis_sp64"
3420   [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,eo,r,o")
3421         (match_operand:TF 1 "input_operand"    "e,m,e,G,roG,r"))]
3422   "TARGET_FPU
3423    && TARGET_VIS
3424    && TARGET_ARCH64
3425    && TARGET_HARD_QUAD
3426    && (register_operand (operands[0], TFmode)
3427        || register_operand (operands[1], TFmode)
3428        || fp_zero_operand (operands[1], TFmode))"
3429   "@
3430   fmovq\t%1, %0
3431   ldq\t%1, %0
3432   stq\t%1, %0
3433   #
3434   #
3435   #"
3436   [(set_attr "type" "fpmove,fpload,fpstore,*,*,*")
3437    (set_attr "length" "*,*,*,2,2,2")])
3439 ;; Now we allow the integer register cases even when
3440 ;; only arch64 is true.
3441 (define_insn "*movtf_insn_sp64"
3442   [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3443         (match_operand:TF 1 "input_operand"    "oe,Ger,orG"))]
3444   "TARGET_FPU
3445    && ! TARGET_VIS
3446    && TARGET_ARCH64
3447    && ! TARGET_HARD_QUAD
3448    && (register_operand (operands[0], TFmode)
3449        || register_operand (operands[1], TFmode)
3450        || fp_zero_operand (operands[1], TFmode))"
3451   "#"
3452   [(set_attr "length" "2")])
3454 (define_insn "*movtf_insn_vis_sp64"
3455   [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3456         (match_operand:TF 1 "input_operand"    "Goe,Ger,orG"))]
3457   "TARGET_FPU
3458    && TARGET_VIS
3459    && TARGET_ARCH64
3460    && ! TARGET_HARD_QUAD
3461    && (register_operand (operands[0], TFmode)
3462        || register_operand (operands[1], TFmode)
3463        || fp_zero_operand (operands[1], TFmode))"
3464   "#"
3465   [(set_attr "length" "2")])
3467 (define_insn "*movtf_no_e_insn_sp64"
3468   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
3469         (match_operand:TF 1 "input_operand"    "orG,rG"))]
3470   "! TARGET_FPU
3471    && TARGET_ARCH64
3472    && (register_operand (operands[0], TFmode)
3473        || register_operand (operands[1], TFmode)
3474        || fp_zero_operand (operands[1], TFmode))"
3475   "#"
3476   [(set_attr "length" "2")])
3478 ;; Now all the splits to handle multi-insn TF mode moves.
3479 (define_split
3480   [(set (match_operand:TF 0 "register_operand" "")
3481         (match_operand:TF 1 "register_operand" ""))]
3482   "reload_completed
3483    && (! TARGET_ARCH64
3484        || (TARGET_FPU
3485            && ! TARGET_HARD_QUAD)
3486        || ! fp_register_operand (operands[0], TFmode))"
3487   [(clobber (const_int 0))]
3489   rtx set_dest = operands[0];
3490   rtx set_src = operands[1];
3491   rtx dest1, dest2;
3492   rtx src1, src2;
3494   dest1 = gen_df_reg (set_dest, 0);
3495   dest2 = gen_df_reg (set_dest, 1);
3496   src1 = gen_df_reg (set_src, 0);
3497   src2 = gen_df_reg (set_src, 1);
3499   /* Now emit using the real source and destination we found, swapping
3500      the order if we detect overlap.  */
3501   if (reg_overlap_mentioned_p (dest1, src2))
3502     {
3503       emit_insn (gen_movdf (dest2, src2));
3504       emit_insn (gen_movdf (dest1, src1));
3505     }
3506   else
3507     {
3508       emit_insn (gen_movdf (dest1, src1));
3509       emit_insn (gen_movdf (dest2, src2));
3510     }
3511   DONE;
3514 (define_split
3515   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3516         (match_operand:TF 1 "fp_zero_operand" ""))]
3517   "reload_completed"
3518   [(clobber (const_int 0))]
3520   rtx set_dest = operands[0];
3521   rtx dest1, dest2;
3523   switch (GET_CODE (set_dest))
3524     {
3525     case REG:
3526       dest1 = gen_df_reg (set_dest, 0);
3527       dest2 = gen_df_reg (set_dest, 1);
3528       break;
3529     case MEM:
3530       dest1 = adjust_address (set_dest, DFmode, 0);
3531       dest2 = adjust_address (set_dest, DFmode, 8);
3532       break;
3533     default:
3534       abort ();      
3535     }
3537   emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
3538   emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
3539   DONE;
3542 (define_split
3543   [(set (match_operand:TF 0 "register_operand" "")
3544         (match_operand:TF 1 "memory_operand" ""))]
3545   "(reload_completed
3546     && offsettable_memref_p (operands[1])
3547     && (! TARGET_ARCH64
3548         || ! TARGET_HARD_QUAD
3549         || ! fp_register_operand (operands[0], TFmode)))"
3550   [(clobber (const_int 0))]
3552   rtx word0 = adjust_address (operands[1], DFmode, 0);
3553   rtx word1 = adjust_address (operands[1], DFmode, 8);
3554   rtx set_dest, dest1, dest2;
3556   set_dest = operands[0];
3558   dest1 = gen_df_reg (set_dest, 0);
3559   dest2 = gen_df_reg (set_dest, 1);
3561   /* Now output, ordering such that we don't clobber any registers
3562      mentioned in the address.  */
3563   if (reg_overlap_mentioned_p (dest1, word1))
3565     {
3566       emit_insn (gen_movdf (dest2, word1));
3567       emit_insn (gen_movdf (dest1, word0));
3568     }
3569   else
3570    {
3571       emit_insn (gen_movdf (dest1, word0));
3572       emit_insn (gen_movdf (dest2, word1));
3573    }
3574   DONE;
3577 (define_split
3578   [(set (match_operand:TF 0 "memory_operand" "")
3579         (match_operand:TF 1 "register_operand" ""))]
3580   "(reload_completed
3581     && offsettable_memref_p (operands[0])
3582     && (! TARGET_ARCH64
3583         || ! TARGET_HARD_QUAD
3584         || ! fp_register_operand (operands[1], TFmode)))"
3585   [(clobber (const_int 0))]
3587   rtx set_src = operands[1];
3589   emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
3590                         gen_df_reg (set_src, 0)));
3591   emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
3592                         gen_df_reg (set_src, 1)));
3593   DONE;
3596 ;; SPARC V9 conditional move instructions.
3598 ;; We can handle larger constants here for some flavors, but for now we keep
3599 ;; it simple and only allow those constants supported by all flavors.
3600 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3601 ;; 3 contains the constant if one is present, but we handle either for
3602 ;; generality (sparc.c puts a constant in operand 2).
3604 (define_expand "movqicc"
3605   [(set (match_operand:QI 0 "register_operand" "")
3606         (if_then_else:QI (match_operand 1 "comparison_operator" "")
3607                          (match_operand:QI 2 "arith10_operand" "")
3608                          (match_operand:QI 3 "arith10_operand" "")))]
3609   "TARGET_V9"
3611   enum rtx_code code = GET_CODE (operands[1]);
3613   if (GET_MODE (sparc_compare_op0) == DImode
3614       && ! TARGET_ARCH64)
3615     FAIL;
3617   if (sparc_compare_op1 == const0_rtx
3618       && GET_CODE (sparc_compare_op0) == REG
3619       && GET_MODE (sparc_compare_op0) == DImode
3620       && v9_regcmp_p (code))
3621     {
3622       operands[1] = gen_rtx_fmt_ee (code, DImode,
3623                              sparc_compare_op0, sparc_compare_op1);
3624     }
3625   else
3626     {
3627       rtx cc_reg = gen_compare_reg (code,
3628                                     sparc_compare_op0, sparc_compare_op1);
3629       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3630     }
3633 (define_expand "movhicc"
3634   [(set (match_operand:HI 0 "register_operand" "")
3635         (if_then_else:HI (match_operand 1 "comparison_operator" "")
3636                          (match_operand:HI 2 "arith10_operand" "")
3637                          (match_operand:HI 3 "arith10_operand" "")))]
3638   "TARGET_V9"
3640   enum rtx_code code = GET_CODE (operands[1]);
3642   if (GET_MODE (sparc_compare_op0) == DImode
3643       && ! TARGET_ARCH64)
3644     FAIL;
3646   if (sparc_compare_op1 == const0_rtx
3647       && GET_CODE (sparc_compare_op0) == REG
3648       && GET_MODE (sparc_compare_op0) == DImode
3649       && v9_regcmp_p (code))
3650     {
3651       operands[1] = gen_rtx_fmt_ee (code, DImode,
3652                              sparc_compare_op0, sparc_compare_op1);
3653     }
3654   else
3655     {
3656       rtx cc_reg = gen_compare_reg (code,
3657                                     sparc_compare_op0, sparc_compare_op1);
3658       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3659     }
3662 (define_expand "movsicc"
3663   [(set (match_operand:SI 0 "register_operand" "")
3664         (if_then_else:SI (match_operand 1 "comparison_operator" "")
3665                          (match_operand:SI 2 "arith10_operand" "")
3666                          (match_operand:SI 3 "arith10_operand" "")))]
3667   "TARGET_V9"
3669   enum rtx_code code = GET_CODE (operands[1]);
3670   enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
3672   if (sparc_compare_op1 == const0_rtx
3673       && GET_CODE (sparc_compare_op0) == REG
3674       && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
3675     {
3676       operands[1] = gen_rtx_fmt_ee (code, op0_mode,
3677                              sparc_compare_op0, sparc_compare_op1);
3678     }
3679   else
3680     {
3681       rtx cc_reg = gen_compare_reg (code,
3682                                     sparc_compare_op0, sparc_compare_op1);
3683       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3684                                     cc_reg, const0_rtx);
3685     }
3688 (define_expand "movdicc"
3689   [(set (match_operand:DI 0 "register_operand" "")
3690         (if_then_else:DI (match_operand 1 "comparison_operator" "")
3691                          (match_operand:DI 2 "arith10_double_operand" "")
3692                          (match_operand:DI 3 "arith10_double_operand" "")))]
3693   "TARGET_ARCH64"
3695   enum rtx_code code = GET_CODE (operands[1]);
3697   if (sparc_compare_op1 == const0_rtx
3698       && GET_CODE (sparc_compare_op0) == REG
3699       && GET_MODE (sparc_compare_op0) == DImode
3700       && v9_regcmp_p (code))
3701     {
3702       operands[1] = gen_rtx_fmt_ee (code, DImode,
3703                              sparc_compare_op0, sparc_compare_op1);
3704     }
3705   else
3706     {
3707       rtx cc_reg = gen_compare_reg (code,
3708                                     sparc_compare_op0, sparc_compare_op1);
3709       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3710                                     cc_reg, const0_rtx);
3711     }
3714 (define_expand "movsfcc"
3715   [(set (match_operand:SF 0 "register_operand" "")
3716         (if_then_else:SF (match_operand 1 "comparison_operator" "")
3717                          (match_operand:SF 2 "register_operand" "")
3718                          (match_operand:SF 3 "register_operand" "")))]
3719   "TARGET_V9 && TARGET_FPU"
3721   enum rtx_code code = GET_CODE (operands[1]);
3723   if (GET_MODE (sparc_compare_op0) == DImode
3724       && ! TARGET_ARCH64)
3725     FAIL;
3727   if (sparc_compare_op1 == const0_rtx
3728       && GET_CODE (sparc_compare_op0) == REG
3729       && GET_MODE (sparc_compare_op0) == DImode
3730       && v9_regcmp_p (code))
3731     {
3732       operands[1] = gen_rtx_fmt_ee (code, DImode,
3733                              sparc_compare_op0, sparc_compare_op1);
3734     }
3735   else
3736     {
3737       rtx cc_reg = gen_compare_reg (code,
3738                                     sparc_compare_op0, sparc_compare_op1);
3739       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3740     }
3743 (define_expand "movdfcc"
3744   [(set (match_operand:DF 0 "register_operand" "")
3745         (if_then_else:DF (match_operand 1 "comparison_operator" "")
3746                          (match_operand:DF 2 "register_operand" "")
3747                          (match_operand:DF 3 "register_operand" "")))]
3748   "TARGET_V9 && TARGET_FPU"
3750   enum rtx_code code = GET_CODE (operands[1]);
3752   if (GET_MODE (sparc_compare_op0) == DImode
3753       && ! TARGET_ARCH64)
3754     FAIL;
3756   if (sparc_compare_op1 == const0_rtx
3757       && GET_CODE (sparc_compare_op0) == REG
3758       && GET_MODE (sparc_compare_op0) == DImode
3759       && v9_regcmp_p (code))
3760     {
3761       operands[1] = gen_rtx_fmt_ee (code, DImode,
3762                              sparc_compare_op0, sparc_compare_op1);
3763     }
3764   else
3765     {
3766       rtx cc_reg = gen_compare_reg (code,
3767                                     sparc_compare_op0, sparc_compare_op1);
3768       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3769     }
3772 (define_expand "movtfcc"
3773   [(set (match_operand:TF 0 "register_operand" "")
3774         (if_then_else:TF (match_operand 1 "comparison_operator" "")
3775                          (match_operand:TF 2 "register_operand" "")
3776                          (match_operand:TF 3 "register_operand" "")))]
3777   "TARGET_V9 && TARGET_FPU"
3779   enum rtx_code code = GET_CODE (operands[1]);
3781   if (GET_MODE (sparc_compare_op0) == DImode
3782       && ! TARGET_ARCH64)
3783     FAIL;
3785   if (sparc_compare_op1 == const0_rtx
3786       && GET_CODE (sparc_compare_op0) == REG
3787       && GET_MODE (sparc_compare_op0) == DImode
3788       && v9_regcmp_p (code))
3789     {
3790       operands[1] = gen_rtx_fmt_ee (code, DImode,
3791                              sparc_compare_op0, sparc_compare_op1);
3792     }
3793   else
3794     {
3795       rtx cc_reg = gen_compare_reg (code,
3796                                     sparc_compare_op0, sparc_compare_op1);
3797       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3798     }
3801 ;; Conditional move define_insns.
3803 (define_insn "*movqi_cc_sp64"
3804   [(set (match_operand:QI 0 "register_operand" "=r,r")
3805         (if_then_else:QI (match_operator 1 "comparison_operator"
3806                                 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3807                                  (const_int 0)])
3808                          (match_operand:QI 3 "arith11_operand" "rL,0")
3809                          (match_operand:QI 4 "arith11_operand" "0,rL")))]
3810   "TARGET_V9"
3811   "@
3812    mov%C1\t%x2, %3, %0
3813    mov%c1\t%x2, %4, %0"
3814   [(set_attr "type" "cmove")])
3816 (define_insn "*movhi_cc_sp64"
3817   [(set (match_operand:HI 0 "register_operand" "=r,r")
3818         (if_then_else:HI (match_operator 1 "comparison_operator"
3819                                 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3820                                  (const_int 0)])
3821                          (match_operand:HI 3 "arith11_operand" "rL,0")
3822                          (match_operand:HI 4 "arith11_operand" "0,rL")))]
3823   "TARGET_V9"
3824   "@
3825    mov%C1\t%x2, %3, %0
3826    mov%c1\t%x2, %4, %0"
3827   [(set_attr "type" "cmove")])
3829 (define_insn "*movsi_cc_sp64"
3830   [(set (match_operand:SI 0 "register_operand" "=r,r")
3831         (if_then_else:SI (match_operator 1 "comparison_operator"
3832                                 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3833                                  (const_int 0)])
3834                          (match_operand:SI 3 "arith11_operand" "rL,0")
3835                          (match_operand:SI 4 "arith11_operand" "0,rL")))]
3836   "TARGET_V9"
3837   "@
3838    mov%C1\t%x2, %3, %0
3839    mov%c1\t%x2, %4, %0"
3840   [(set_attr "type" "cmove")])
3842 ;; ??? The constraints of operands 3,4 need work.
3843 (define_insn "*movdi_cc_sp64"
3844   [(set (match_operand:DI 0 "register_operand" "=r,r")
3845         (if_then_else:DI (match_operator 1 "comparison_operator"
3846                                 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3847                                  (const_int 0)])
3848                          (match_operand:DI 3 "arith11_double_operand" "rLH,0")
3849                          (match_operand:DI 4 "arith11_double_operand" "0,rLH")))]
3850   "TARGET_ARCH64"
3851   "@
3852    mov%C1\t%x2, %3, %0
3853    mov%c1\t%x2, %4, %0"
3854   [(set_attr "type" "cmove")])
3856 (define_insn "*movdi_cc_sp64_trunc"
3857   [(set (match_operand:SI 0 "register_operand" "=r,r")
3858         (if_then_else:SI (match_operator 1 "comparison_operator"
3859                                 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3860                                  (const_int 0)])
3861                          (match_operand:SI 3 "arith11_double_operand" "rLH,0")
3862                          (match_operand:SI 4 "arith11_double_operand" "0,rLH")))]
3863   "TARGET_ARCH64"
3864   "@
3865    mov%C1\t%x2, %3, %0
3866    mov%c1\t%x2, %4, %0"
3867   [(set_attr "type" "cmove")])
3869 (define_insn "*movsf_cc_sp64"
3870   [(set (match_operand:SF 0 "register_operand" "=f,f")
3871         (if_then_else:SF (match_operator 1 "comparison_operator"
3872                                 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3873                                  (const_int 0)])
3874                          (match_operand:SF 3 "register_operand" "f,0")
3875                          (match_operand:SF 4 "register_operand" "0,f")))]
3876   "TARGET_V9 && TARGET_FPU"
3877   "@
3878    fmovs%C1\t%x2, %3, %0
3879    fmovs%c1\t%x2, %4, %0"
3880   [(set_attr "type" "fpcmove")])
3882 (define_insn "movdf_cc_sp64"
3883   [(set (match_operand:DF 0 "register_operand" "=e,e")
3884         (if_then_else:DF (match_operator 1 "comparison_operator"
3885                                 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3886                                  (const_int 0)])
3887                          (match_operand:DF 3 "register_operand" "e,0")
3888                          (match_operand:DF 4 "register_operand" "0,e")))]
3889   "TARGET_V9 && TARGET_FPU"
3890   "@
3891    fmovd%C1\t%x2, %3, %0
3892    fmovd%c1\t%x2, %4, %0"
3893   [(set_attr "type" "fpcmove")
3894    (set_attr "fptype" "double")])
3896 (define_insn "*movtf_cc_hq_sp64"
3897   [(set (match_operand:TF 0 "register_operand" "=e,e")
3898         (if_then_else:TF (match_operator 1 "comparison_operator"
3899                                 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3900                                  (const_int 0)])
3901                          (match_operand:TF 3 "register_operand" "e,0")
3902                          (match_operand:TF 4 "register_operand" "0,e")))]
3903   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3904   "@
3905    fmovq%C1\t%x2, %3, %0
3906    fmovq%c1\t%x2, %4, %0"
3907   [(set_attr "type" "fpcmove")])
3909 (define_insn_and_split "*movtf_cc_sp64"
3910   [(set (match_operand:TF 0 "register_operand" "=e,e")
3911         (if_then_else:TF (match_operator 1 "comparison_operator"
3912                             [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3913                              (const_int 0)])
3914                          (match_operand:TF 3 "register_operand" "e,0")
3915                          (match_operand:TF 4 "register_operand" "0,e")))]
3916   "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
3917   "#"
3918   "&& reload_completed"
3919   [(clobber (const_int 0))]
3921   rtx set_dest = operands[0];
3922   rtx set_srca = operands[3];
3923   rtx set_srcb = operands[4];
3924   int third = rtx_equal_p (set_dest, set_srca);
3925   rtx dest1, dest2;
3926   rtx srca1, srca2, srcb1, srcb2;
3928   dest1 = gen_df_reg (set_dest, 0);
3929   dest2 = gen_df_reg (set_dest, 1);
3930   srca1 = gen_df_reg (set_srca, 0);
3931   srca2 = gen_df_reg (set_srca, 1);
3932   srcb1 = gen_df_reg (set_srcb, 0);
3933   srcb2 = gen_df_reg (set_srcb, 1);
3935   /* Now emit using the real source and destination we found, swapping
3936      the order if we detect overlap.  */
3937   if ((third && reg_overlap_mentioned_p (dest1, srcb2))
3938       || (!third && reg_overlap_mentioned_p (dest1, srca2)))
3939     {
3940       emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3941       emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3942     }
3943   else
3944     {
3945       emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3946       emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3947     }
3948   DONE;
3950   [(set_attr "length" "2")])
3952 (define_insn "*movqi_cc_reg_sp64"
3953   [(set (match_operand:QI 0 "register_operand" "=r,r")
3954         (if_then_else:QI (match_operator 1 "v9_regcmp_op"
3955                                 [(match_operand:DI 2 "register_operand" "r,r")
3956                                  (const_int 0)])
3957                          (match_operand:QI 3 "arith10_operand" "rM,0")
3958                          (match_operand:QI 4 "arith10_operand" "0,rM")))]
3959   "TARGET_ARCH64"
3960   "@
3961    movr%D1\t%2, %r3, %0
3962    movr%d1\t%2, %r4, %0"
3963   [(set_attr "type" "cmove")])
3965 (define_insn "*movhi_cc_reg_sp64"
3966   [(set (match_operand:HI 0 "register_operand" "=r,r")
3967         (if_then_else:HI (match_operator 1 "v9_regcmp_op"
3968                                 [(match_operand:DI 2 "register_operand" "r,r")
3969                                  (const_int 0)])
3970                          (match_operand:HI 3 "arith10_operand" "rM,0")
3971                          (match_operand:HI 4 "arith10_operand" "0,rM")))]
3972   "TARGET_ARCH64"
3973   "@
3974    movr%D1\t%2, %r3, %0
3975    movr%d1\t%2, %r4, %0"
3976   [(set_attr "type" "cmove")])
3978 (define_insn "*movsi_cc_reg_sp64"
3979   [(set (match_operand:SI 0 "register_operand" "=r,r")
3980         (if_then_else:SI (match_operator 1 "v9_regcmp_op"
3981                                 [(match_operand:DI 2 "register_operand" "r,r")
3982                                  (const_int 0)])
3983                          (match_operand:SI 3 "arith10_operand" "rM,0")
3984                          (match_operand:SI 4 "arith10_operand" "0,rM")))]
3985   "TARGET_ARCH64"
3986   "@
3987    movr%D1\t%2, %r3, %0
3988    movr%d1\t%2, %r4, %0"
3989   [(set_attr "type" "cmove")])
3991 ;; ??? The constraints of operands 3,4 need work.
3992 (define_insn "*movdi_cc_reg_sp64"
3993   [(set (match_operand:DI 0 "register_operand" "=r,r")
3994         (if_then_else:DI (match_operator 1 "v9_regcmp_op"
3995                                 [(match_operand:DI 2 "register_operand" "r,r")
3996                                  (const_int 0)])
3997                          (match_operand:DI 3 "arith10_double_operand" "rMH,0")
3998                          (match_operand:DI 4 "arith10_double_operand" "0,rMH")))]
3999   "TARGET_ARCH64"
4000   "@
4001    movr%D1\t%2, %r3, %0
4002    movr%d1\t%2, %r4, %0"
4003   [(set_attr "type" "cmove")])
4005 (define_insn "*movdi_cc_reg_sp64_trunc"
4006   [(set (match_operand:SI 0 "register_operand" "=r,r")
4007         (if_then_else:SI (match_operator 1 "v9_regcmp_op"
4008                                 [(match_operand:DI 2 "register_operand" "r,r")
4009                                  (const_int 0)])
4010                          (match_operand:SI 3 "arith10_double_operand" "rMH,0")
4011                          (match_operand:SI 4 "arith10_double_operand" "0,rMH")))]
4012   "TARGET_ARCH64"
4013   "@
4014    movr%D1\t%2, %r3, %0
4015    movr%d1\t%2, %r4, %0"
4016   [(set_attr "type" "cmove")])
4018 (define_insn "*movsf_cc_reg_sp64"
4019   [(set (match_operand:SF 0 "register_operand" "=f,f")
4020         (if_then_else:SF (match_operator 1 "v9_regcmp_op"
4021                                 [(match_operand:DI 2 "register_operand" "r,r")
4022                                  (const_int 0)])
4023                          (match_operand:SF 3 "register_operand" "f,0")
4024                          (match_operand:SF 4 "register_operand" "0,f")))]
4025   "TARGET_ARCH64 && TARGET_FPU"
4026   "@
4027    fmovrs%D1\t%2, %3, %0
4028    fmovrs%d1\t%2, %4, %0"
4029   [(set_attr "type" "fpcrmove")])
4031 (define_insn "movdf_cc_reg_sp64"
4032   [(set (match_operand:DF 0 "register_operand" "=e,e")
4033         (if_then_else:DF (match_operator 1 "v9_regcmp_op"
4034                                 [(match_operand:DI 2 "register_operand" "r,r")
4035                                  (const_int 0)])
4036                          (match_operand:DF 3 "register_operand" "e,0")
4037                          (match_operand:DF 4 "register_operand" "0,e")))]
4038   "TARGET_ARCH64 && TARGET_FPU"
4039   "@
4040    fmovrd%D1\t%2, %3, %0
4041    fmovrd%d1\t%2, %4, %0"
4042   [(set_attr "type" "fpcrmove")
4043    (set_attr "fptype" "double")])
4045 (define_insn "*movtf_cc_reg_hq_sp64"
4046   [(set (match_operand:TF 0 "register_operand" "=e,e")
4047         (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4048                                 [(match_operand:DI 2 "register_operand" "r,r")
4049                                  (const_int 0)])
4050                          (match_operand:TF 3 "register_operand" "e,0")
4051                          (match_operand:TF 4 "register_operand" "0,e")))]
4052   "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
4053   "@
4054    fmovrq%D1\t%2, %3, %0
4055    fmovrq%d1\t%2, %4, %0"
4056   [(set_attr "type" "fpcrmove")])
4058 (define_insn_and_split "*movtf_cc_reg_sp64"
4059   [(set (match_operand:TF 0 "register_operand" "=e,e")
4060         (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4061                                 [(match_operand:DI 2 "register_operand" "r,r")
4062                                  (const_int 0)])
4063                          (match_operand:TF 3 "register_operand" "e,0")
4064                          (match_operand:TF 4 "register_operand" "0,e")))]
4065   "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
4066   "#"
4067   "&& reload_completed"
4068   [(clobber (const_int 0))]
4070   rtx set_dest = operands[0];
4071   rtx set_srca = operands[3];
4072   rtx set_srcb = operands[4];
4073   int third = rtx_equal_p (set_dest, set_srca);
4074   rtx dest1, dest2;
4075   rtx srca1, srca2, srcb1, srcb2;
4077   dest1 = gen_df_reg (set_dest, 0);
4078   dest2 = gen_df_reg (set_dest, 1);
4079   srca1 = gen_df_reg (set_srca, 0);
4080   srca2 = gen_df_reg (set_srca, 1);
4081   srcb1 = gen_df_reg (set_srcb, 0);
4082   srcb2 = gen_df_reg (set_srcb, 1);
4084   /* Now emit using the real source and destination we found, swapping
4085      the order if we detect overlap.  */
4086   if ((third && reg_overlap_mentioned_p (dest1, srcb2))
4087       || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4088     {
4089       emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4090       emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4091     }
4092   else
4093     {
4094       emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4095       emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4096     }
4097   DONE;
4099   [(set_attr "length" "2")])
4102 ;;- zero extension instructions
4104 ;; These patterns originally accepted general_operands, however, slightly
4105 ;; better code is generated by only accepting register_operands, and then
4106 ;; letting combine generate the ldu[hb] insns.
4108 (define_expand "zero_extendhisi2"
4109   [(set (match_operand:SI 0 "register_operand" "")
4110         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
4111   ""
4113   rtx temp = gen_reg_rtx (SImode);
4114   rtx shift_16 = GEN_INT (16);
4115   int op1_subbyte = 0;
4117   if (GET_CODE (operand1) == SUBREG)
4118     {
4119       op1_subbyte = SUBREG_BYTE (operand1);
4120       op1_subbyte /= GET_MODE_SIZE (SImode);
4121       op1_subbyte *= GET_MODE_SIZE (SImode);
4122       operand1 = XEXP (operand1, 0);
4123     }
4125   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4126                           shift_16));
4127   emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
4128   DONE;
4131 (define_insn "*zero_extendhisi2_insn"
4132   [(set (match_operand:SI 0 "register_operand" "=r")
4133         (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4134   ""
4135   "lduh\t%1, %0"
4136   [(set_attr "type" "load")
4137    (set_attr "us3load_type" "3cycle")])
4139 (define_expand "zero_extendqihi2"
4140   [(set (match_operand:HI 0 "register_operand" "")
4141         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
4142   ""
4143   "")
4145 (define_insn "*zero_extendqihi2_insn"
4146   [(set (match_operand:HI 0 "register_operand" "=r,r")
4147         (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
4148   "GET_CODE (operands[1]) != CONST_INT"
4149   "@
4150    and\t%1, 0xff, %0
4151    ldub\t%1, %0"
4152   [(set_attr "type" "*,load")
4153    (set_attr "us3load_type" "*,3cycle")])
4155 (define_expand "zero_extendqisi2"
4156   [(set (match_operand:SI 0 "register_operand" "")
4157         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
4158   ""
4159   "")
4161 (define_insn "*zero_extendqisi2_insn"
4162   [(set (match_operand:SI 0 "register_operand" "=r,r")
4163         (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
4164   "GET_CODE (operands[1]) != CONST_INT"
4165   "@
4166    and\t%1, 0xff, %0
4167    ldub\t%1, %0"
4168   [(set_attr "type" "*,load")
4169    (set_attr "us3load_type" "*,3cycle")])
4171 (define_expand "zero_extendqidi2"
4172   [(set (match_operand:DI 0 "register_operand" "")
4173         (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
4174   "TARGET_ARCH64"
4175   "")
4177 (define_insn "*zero_extendqidi2_insn"
4178   [(set (match_operand:DI 0 "register_operand" "=r,r")
4179         (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
4180   "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4181   "@
4182    and\t%1, 0xff, %0
4183    ldub\t%1, %0"
4184   [(set_attr "type" "*,load")
4185    (set_attr "us3load_type" "*,3cycle")])
4187 (define_expand "zero_extendhidi2"
4188   [(set (match_operand:DI 0 "register_operand" "")
4189         (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
4190   "TARGET_ARCH64"
4192   rtx temp = gen_reg_rtx (DImode);
4193   rtx shift_48 = GEN_INT (48);
4194   int op1_subbyte = 0;
4196   if (GET_CODE (operand1) == SUBREG)
4197     {
4198       op1_subbyte = SUBREG_BYTE (operand1);
4199       op1_subbyte /= GET_MODE_SIZE (DImode);
4200       op1_subbyte *= GET_MODE_SIZE (DImode);
4201       operand1 = XEXP (operand1, 0);
4202     }
4204   emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4205                           shift_48));
4206   emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
4207   DONE;
4210 (define_insn "*zero_extendhidi2_insn"
4211   [(set (match_operand:DI 0 "register_operand" "=r")
4212         (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4213   "TARGET_ARCH64"
4214   "lduh\t%1, %0"
4215   [(set_attr "type" "load")
4216    (set_attr "us3load_type" "3cycle")])
4219 ;; ??? Write truncdisi pattern using sra?
4221 (define_expand "zero_extendsidi2"
4222   [(set (match_operand:DI 0 "register_operand" "")
4223         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4224   ""
4225   "")
4227 (define_insn "*zero_extendsidi2_insn_sp64"
4228   [(set (match_operand:DI 0 "register_operand" "=r,r")
4229         (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4230   "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4231   "@
4232    srl\t%1, 0, %0
4233    lduw\t%1, %0"
4234   [(set_attr "type" "shift,load")])
4236 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
4237   [(set (match_operand:DI 0 "register_operand" "=r")
4238         (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4239   "! TARGET_ARCH64"
4240   "#"
4241   "&& reload_completed"
4242   [(set (match_dup 2) (match_dup 3))
4243    (set (match_dup 4) (match_dup 5))]
4245   rtx dest1, dest2;
4247   dest1 = gen_highpart (SImode, operands[0]);
4248   dest2 = gen_lowpart (SImode, operands[0]);
4250   /* Swap the order in case of overlap.  */
4251   if (REGNO (dest1) == REGNO (operands[1]))
4252     {
4253       operands[2] = dest2;
4254       operands[3] = operands[1];
4255       operands[4] = dest1;
4256       operands[5] = const0_rtx;
4257     }
4258   else
4259     {
4260       operands[2] = dest1;
4261       operands[3] = const0_rtx;
4262       operands[4] = dest2;
4263       operands[5] = operands[1];
4264     }
4266   [(set_attr "length" "2")])
4268 ;; Simplify comparisons of extended values.
4270 (define_insn "*cmp_zero_extendqisi2"
4271   [(set (reg:CC 100)
4272         (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
4273                     (const_int 0)))]
4274   ""
4275   "andcc\t%0, 0xff, %%g0"
4276   [(set_attr "type" "compare")])
4278 (define_insn "*cmp_zero_qi"
4279   [(set (reg:CC 100)
4280         (compare:CC (match_operand:QI 0 "register_operand" "r")
4281                     (const_int 0)))]
4282   ""
4283   "andcc\t%0, 0xff, %%g0"
4284   [(set_attr "type" "compare")])
4286 (define_insn "*cmp_zero_extendqisi2_set"
4287   [(set (reg:CC 100)
4288         (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
4289                     (const_int 0)))
4290    (set (match_operand:SI 0 "register_operand" "=r")
4291         (zero_extend:SI (match_dup 1)))]
4292   ""
4293   "andcc\t%1, 0xff, %0"
4294   [(set_attr "type" "compare")])
4296 (define_insn "*cmp_zero_extendqisi2_andcc_set"
4297   [(set (reg:CC 100)
4298         (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
4299                             (const_int 255))
4300                     (const_int 0)))
4301    (set (match_operand:SI 0 "register_operand" "=r")
4302         (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
4303   ""
4304   "andcc\t%1, 0xff, %0"
4305   [(set_attr "type" "compare")])
4307 (define_insn "*cmp_zero_extendqidi2"
4308   [(set (reg:CCX 100)
4309         (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
4310                      (const_int 0)))]
4311   "TARGET_ARCH64"
4312   "andcc\t%0, 0xff, %%g0"
4313   [(set_attr "type" "compare")])
4315 (define_insn "*cmp_zero_qi_sp64"
4316   [(set (reg:CCX 100)
4317         (compare:CCX (match_operand:QI 0 "register_operand" "r")
4318                      (const_int 0)))]
4319   "TARGET_ARCH64"
4320   "andcc\t%0, 0xff, %%g0"
4321   [(set_attr "type" "compare")])
4323 (define_insn "*cmp_zero_extendqidi2_set"
4324   [(set (reg:CCX 100)
4325         (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
4326                      (const_int 0)))
4327    (set (match_operand:DI 0 "register_operand" "=r")
4328         (zero_extend:DI (match_dup 1)))]
4329   "TARGET_ARCH64"
4330   "andcc\t%1, 0xff, %0"
4331   [(set_attr "type" "compare")])
4333 (define_insn "*cmp_zero_extendqidi2_andcc_set"
4334   [(set (reg:CCX 100)
4335         (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
4336                              (const_int 255))
4337                      (const_int 0)))
4338    (set (match_operand:DI 0 "register_operand" "=r")
4339         (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
4340   "TARGET_ARCH64"
4341   "andcc\t%1, 0xff, %0"
4342   [(set_attr "type" "compare")])
4344 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
4346 (define_insn "*cmp_siqi_trunc"
4347   [(set (reg:CC 100)
4348         (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
4349                     (const_int 0)))]
4350   ""
4351   "andcc\t%0, 0xff, %%g0"
4352   [(set_attr "type" "compare")])
4354 (define_insn "*cmp_siqi_trunc_set"
4355   [(set (reg:CC 100)
4356         (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
4357                     (const_int 0)))
4358    (set (match_operand:QI 0 "register_operand" "=r")
4359         (subreg:QI (match_dup 1) 3))]
4360   ""
4361   "andcc\t%1, 0xff, %0"
4362   [(set_attr "type" "compare")])
4364 (define_insn "*cmp_diqi_trunc"
4365   [(set (reg:CC 100)
4366         (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
4367                     (const_int 0)))]
4368   "TARGET_ARCH64"
4369   "andcc\t%0, 0xff, %%g0"
4370   [(set_attr "type" "compare")])
4372 (define_insn "*cmp_diqi_trunc_set"
4373   [(set (reg:CC 100)
4374         (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
4375                     (const_int 0)))
4376    (set (match_operand:QI 0 "register_operand" "=r")
4377         (subreg:QI (match_dup 1) 7))]
4378   "TARGET_ARCH64"
4379   "andcc\t%1, 0xff, %0"
4380   [(set_attr "type" "compare")])
4382 ;;- sign extension instructions
4384 ;; These patterns originally accepted general_operands, however, slightly
4385 ;; better code is generated by only accepting register_operands, and then
4386 ;; letting combine generate the lds[hb] insns.
4388 (define_expand "extendhisi2"
4389   [(set (match_operand:SI 0 "register_operand" "")
4390         (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
4391   ""
4393   rtx temp = gen_reg_rtx (SImode);
4394   rtx shift_16 = GEN_INT (16);
4395   int op1_subbyte = 0;
4397   if (GET_CODE (operand1) == SUBREG)
4398     {
4399       op1_subbyte = SUBREG_BYTE (operand1);
4400       op1_subbyte /= GET_MODE_SIZE (SImode);
4401       op1_subbyte *= GET_MODE_SIZE (SImode);
4402       operand1 = XEXP (operand1, 0);
4403     }
4405   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4406                           shift_16));
4407   emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
4408   DONE;
4411 (define_insn "*sign_extendhisi2_insn"
4412   [(set (match_operand:SI 0 "register_operand" "=r")
4413         (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4414   ""
4415   "ldsh\t%1, %0"
4416   [(set_attr "type" "sload")
4417    (set_attr "us3load_type" "3cycle")])
4419 (define_expand "extendqihi2"
4420   [(set (match_operand:HI 0 "register_operand" "")
4421         (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
4422   ""
4424   rtx temp = gen_reg_rtx (SImode);
4425   rtx shift_24 = GEN_INT (24);
4426   int op1_subbyte = 0;
4427   int op0_subbyte = 0;
4429   if (GET_CODE (operand1) == SUBREG)
4430     {
4431       op1_subbyte = SUBREG_BYTE (operand1);
4432       op1_subbyte /= GET_MODE_SIZE (SImode);
4433       op1_subbyte *= GET_MODE_SIZE (SImode);
4434       operand1 = XEXP (operand1, 0);
4435     }
4436   if (GET_CODE (operand0) == SUBREG)
4437     {
4438       op0_subbyte = SUBREG_BYTE (operand0);
4439       op0_subbyte /= GET_MODE_SIZE (SImode);
4440       op0_subbyte *= GET_MODE_SIZE (SImode);
4441       operand0 = XEXP (operand0, 0);
4442     }
4443   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4444                           shift_24));
4445   if (GET_MODE (operand0) != SImode)
4446     operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
4447   emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4448   DONE;
4451 (define_insn "*sign_extendqihi2_insn"
4452   [(set (match_operand:HI 0 "register_operand" "=r")
4453         (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
4454   ""
4455   "ldsb\t%1, %0"
4456   [(set_attr "type" "sload")
4457    (set_attr "us3load_type" "3cycle")])
4459 (define_expand "extendqisi2"
4460   [(set (match_operand:SI 0 "register_operand" "")
4461         (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
4462   ""
4464   rtx temp = gen_reg_rtx (SImode);
4465   rtx shift_24 = GEN_INT (24);
4466   int op1_subbyte = 0;
4468   if (GET_CODE (operand1) == SUBREG)
4469     {
4470       op1_subbyte = SUBREG_BYTE (operand1);
4471       op1_subbyte /= GET_MODE_SIZE (SImode);
4472       op1_subbyte *= GET_MODE_SIZE (SImode);
4473       operand1 = XEXP (operand1, 0);
4474     }
4476   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4477                           shift_24));
4478   emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4479   DONE;
4482 (define_insn "*sign_extendqisi2_insn"
4483   [(set (match_operand:SI 0 "register_operand" "=r")
4484         (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
4485   ""
4486   "ldsb\t%1, %0"
4487   [(set_attr "type" "sload")
4488    (set_attr "us3load_type" "3cycle")])
4490 (define_expand "extendqidi2"
4491   [(set (match_operand:DI 0 "register_operand" "")
4492         (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
4493   "TARGET_ARCH64"
4495   rtx temp = gen_reg_rtx (DImode);
4496   rtx shift_56 = GEN_INT (56);
4497   int op1_subbyte = 0;
4499   if (GET_CODE (operand1) == SUBREG)
4500     {
4501       op1_subbyte = SUBREG_BYTE (operand1);
4502       op1_subbyte /= GET_MODE_SIZE (DImode);
4503       op1_subbyte *= GET_MODE_SIZE (DImode);
4504       operand1 = XEXP (operand1, 0);
4505     }
4507   emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4508                           shift_56));
4509   emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
4510   DONE;
4513 (define_insn "*sign_extendqidi2_insn"
4514   [(set (match_operand:DI 0 "register_operand" "=r")
4515         (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
4516   "TARGET_ARCH64"
4517   "ldsb\t%1, %0"
4518   [(set_attr "type" "sload")
4519    (set_attr "us3load_type" "3cycle")])
4521 (define_expand "extendhidi2"
4522   [(set (match_operand:DI 0 "register_operand" "")
4523         (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
4524   "TARGET_ARCH64"
4526   rtx temp = gen_reg_rtx (DImode);
4527   rtx shift_48 = GEN_INT (48);
4528   int op1_subbyte = 0;
4530   if (GET_CODE (operand1) == SUBREG)
4531     {
4532       op1_subbyte = SUBREG_BYTE (operand1);
4533       op1_subbyte /= GET_MODE_SIZE (DImode);
4534       op1_subbyte *= GET_MODE_SIZE (DImode);
4535       operand1 = XEXP (operand1, 0);
4536     }
4538   emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4539                           shift_48));
4540   emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
4541   DONE;
4544 (define_insn "*sign_extendhidi2_insn"
4545   [(set (match_operand:DI 0 "register_operand" "=r")
4546         (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4547   "TARGET_ARCH64"
4548   "ldsh\t%1, %0"
4549   [(set_attr "type" "sload")
4550    (set_attr "us3load_type" "3cycle")])
4552 (define_expand "extendsidi2"
4553   [(set (match_operand:DI 0 "register_operand" "")
4554         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
4555   "TARGET_ARCH64"
4556   "")
4558 (define_insn "*sign_extendsidi2_insn"
4559   [(set (match_operand:DI 0 "register_operand" "=r,r")
4560         (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4561   "TARGET_ARCH64"
4562   "@
4563   sra\t%1, 0, %0
4564   ldsw\t%1, %0"
4565   [(set_attr "type" "shift,sload")
4566    (set_attr "us3load_type" "*,3cycle")])
4568 ;; Special pattern for optimizing bit-field compares.  This is needed
4569 ;; because combine uses this as a canonical form.
4571 (define_insn "*cmp_zero_extract"
4572   [(set (reg:CC 100)
4573         (compare:CC
4574          (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
4575                           (match_operand:SI 1 "small_int_or_double" "n")
4576                           (match_operand:SI 2 "small_int_or_double" "n"))
4577          (const_int 0)))]
4578   "(GET_CODE (operands[2]) == CONST_INT
4579     && INTVAL (operands[2]) > 19)
4580    || (GET_CODE (operands[2]) == CONST_DOUBLE
4581        && CONST_DOUBLE_LOW (operands[2]) > 19)"
4583   int len = (GET_CODE (operands[1]) == CONST_INT
4584              ? INTVAL (operands[1])
4585              : CONST_DOUBLE_LOW (operands[1]));
4586   int pos = 32 -
4587             (GET_CODE (operands[2]) == CONST_INT
4588              ? INTVAL (operands[2])
4589              : CONST_DOUBLE_LOW (operands[2])) - len;
4590   HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
4592   operands[1] = GEN_INT (mask);
4593   return "andcc\t%0, %1, %%g0";
4595   [(set_attr "type" "compare")])
4597 (define_insn "*cmp_zero_extract_sp64"
4598   [(set (reg:CCX 100)
4599         (compare:CCX
4600          (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
4601                           (match_operand:SI 1 "small_int_or_double" "n")
4602                           (match_operand:SI 2 "small_int_or_double" "n"))
4603          (const_int 0)))]
4604   "TARGET_ARCH64
4605    && ((GET_CODE (operands[2]) == CONST_INT
4606         && INTVAL (operands[2]) > 51)
4607        || (GET_CODE (operands[2]) == CONST_DOUBLE
4608            && CONST_DOUBLE_LOW (operands[2]) > 51))"
4610   int len = (GET_CODE (operands[1]) == CONST_INT
4611              ? INTVAL (operands[1])
4612              : CONST_DOUBLE_LOW (operands[1]));
4613   int pos = 64 -
4614             (GET_CODE (operands[2]) == CONST_INT
4615              ? INTVAL (operands[2])
4616              : CONST_DOUBLE_LOW (operands[2])) - len;
4617   HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
4619   operands[1] = GEN_INT (mask);
4620   return "andcc\t%0, %1, %%g0";
4622   [(set_attr "type" "compare")])
4624 ;; Conversions between float, double and long double.
4626 (define_insn "extendsfdf2"
4627   [(set (match_operand:DF 0 "register_operand" "=e")
4628         (float_extend:DF
4629          (match_operand:SF 1 "register_operand" "f")))]
4630   "TARGET_FPU"
4631   "fstod\t%1, %0"
4632   [(set_attr "type" "fp")
4633    (set_attr "fptype" "double")])
4635 (define_expand "extendsftf2"
4636   [(set (match_operand:TF 0 "nonimmediate_operand" "")
4637         (float_extend:TF
4638          (match_operand:SF 1 "register_operand" "")))]
4639   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4640   "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4642 (define_insn "*extendsftf2_hq"
4643   [(set (match_operand:TF 0 "register_operand" "=e")
4644         (float_extend:TF
4645          (match_operand:SF 1 "register_operand" "f")))]
4646   "TARGET_FPU && TARGET_HARD_QUAD"
4647   "fstoq\t%1, %0"
4648   [(set_attr "type" "fp")])
4650 (define_expand "extenddftf2"
4651   [(set (match_operand:TF 0 "nonimmediate_operand" "")
4652         (float_extend:TF
4653          (match_operand:DF 1 "register_operand" "")))]
4654   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4655   "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4657 (define_insn "*extenddftf2_hq"
4658   [(set (match_operand:TF 0 "register_operand" "=e")
4659         (float_extend:TF
4660          (match_operand:DF 1 "register_operand" "e")))]
4661   "TARGET_FPU && TARGET_HARD_QUAD"
4662   "fdtoq\t%1, %0"
4663   [(set_attr "type" "fp")])
4665 (define_insn "truncdfsf2"
4666   [(set (match_operand:SF 0 "register_operand" "=f")
4667         (float_truncate:SF
4668          (match_operand:DF 1 "register_operand" "e")))]
4669   "TARGET_FPU"
4670   "fdtos\t%1, %0"
4671   [(set_attr "type" "fp")
4672    (set_attr "fptype" "double")])
4674 (define_expand "trunctfsf2"
4675   [(set (match_operand:SF 0 "register_operand" "")
4676         (float_truncate:SF
4677          (match_operand:TF 1 "general_operand" "")))]
4678   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4679   "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4681 (define_insn "*trunctfsf2_hq"
4682   [(set (match_operand:SF 0 "register_operand" "=f")
4683         (float_truncate:SF
4684          (match_operand:TF 1 "register_operand" "e")))]
4685   "TARGET_FPU && TARGET_HARD_QUAD"
4686   "fqtos\t%1, %0"
4687   [(set_attr "type" "fp")])
4689 (define_expand "trunctfdf2"
4690   [(set (match_operand:DF 0 "register_operand" "")
4691         (float_truncate:DF
4692          (match_operand:TF 1 "general_operand" "")))]
4693   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4694   "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4696 (define_insn "*trunctfdf2_hq"
4697   [(set (match_operand:DF 0 "register_operand" "=e")
4698         (float_truncate:DF
4699          (match_operand:TF 1 "register_operand" "e")))]
4700   "TARGET_FPU && TARGET_HARD_QUAD"
4701   "fqtod\t%1, %0"
4702   [(set_attr "type" "fp")])
4704 ;; Conversion between fixed point and floating point.
4706 (define_insn "floatsisf2"
4707   [(set (match_operand:SF 0 "register_operand" "=f")
4708         (float:SF (match_operand:SI 1 "register_operand" "f")))]
4709   "TARGET_FPU"
4710   "fitos\t%1, %0"
4711   [(set_attr "type" "fp")
4712    (set_attr "fptype" "double")])
4714 (define_insn "floatsidf2"
4715   [(set (match_operand:DF 0 "register_operand" "=e")
4716         (float:DF (match_operand:SI 1 "register_operand" "f")))]
4717   "TARGET_FPU"
4718   "fitod\t%1, %0"
4719   [(set_attr "type" "fp")
4720    (set_attr "fptype" "double")])
4722 (define_expand "floatsitf2"
4723   [(set (match_operand:TF 0 "nonimmediate_operand" "")
4724         (float:TF (match_operand:SI 1 "register_operand" "")))]
4725   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4726   "emit_tfmode_cvt (FLOAT, operands); DONE;")
4728 (define_insn "*floatsitf2_hq"
4729   [(set (match_operand:TF 0 "register_operand" "=e")
4730         (float:TF (match_operand:SI 1 "register_operand" "f")))]
4731   "TARGET_FPU && TARGET_HARD_QUAD"
4732   "fitoq\t%1, %0"
4733   [(set_attr "type" "fp")])
4735 (define_expand "floatunssitf2"
4736   [(set (match_operand:TF 0 "nonimmediate_operand" "")
4737         (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
4738   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4739   "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4741 ;; Now the same for 64 bit sources.
4743 (define_insn "floatdisf2"
4744   [(set (match_operand:SF 0 "register_operand" "=f")
4745         (float:SF (match_operand:DI 1 "register_operand" "e")))]
4746   "TARGET_V9 && TARGET_FPU"
4747   "fxtos\t%1, %0"
4748   [(set_attr "type" "fp")
4749    (set_attr "fptype" "double")])
4751 (define_expand "floatunsdisf2"
4752   [(use (match_operand:SF 0 "register_operand" ""))
4753    (use (match_operand:DI 1 "general_operand" ""))]
4754   "TARGET_ARCH64 && TARGET_FPU"
4755   "sparc_emit_floatunsdi (operands, SFmode); DONE;")
4757 (define_insn "floatdidf2"
4758   [(set (match_operand:DF 0 "register_operand" "=e")
4759         (float:DF (match_operand:DI 1 "register_operand" "e")))]
4760   "TARGET_V9 && TARGET_FPU"
4761   "fxtod\t%1, %0"
4762   [(set_attr "type" "fp")
4763    (set_attr "fptype" "double")])
4765 (define_expand "floatunsdidf2"
4766   [(use (match_operand:DF 0 "register_operand" ""))
4767    (use (match_operand:DI 1 "general_operand" ""))]
4768   "TARGET_ARCH64 && TARGET_FPU"
4769   "sparc_emit_floatunsdi (operands, DFmode); DONE;")
4771 (define_expand "floatditf2"
4772   [(set (match_operand:TF 0 "nonimmediate_operand" "")
4773         (float:TF (match_operand:DI 1 "register_operand" "")))]
4774   "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4775   "emit_tfmode_cvt (FLOAT, operands); DONE;")
4777 (define_insn "*floatditf2_hq"
4778   [(set (match_operand:TF 0 "register_operand" "=e")
4779         (float:TF (match_operand:DI 1 "register_operand" "e")))]
4780   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4781   "fxtoq\t%1, %0"
4782   [(set_attr "type" "fp")])
4784 (define_expand "floatunsditf2"
4785   [(set (match_operand:TF 0 "nonimmediate_operand" "")
4786         (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
4787   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4788   "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4790 ;; Convert a float to an actual integer.
4791 ;; Truncation is performed as part of the conversion.
4793 (define_insn "fix_truncsfsi2"
4794   [(set (match_operand:SI 0 "register_operand" "=f")
4795         (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4796   "TARGET_FPU"
4797   "fstoi\t%1, %0"
4798   [(set_attr "type" "fp")
4799    (set_attr "fptype" "double")])
4801 (define_insn "fix_truncdfsi2"
4802   [(set (match_operand:SI 0 "register_operand" "=f")
4803         (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4804   "TARGET_FPU"
4805   "fdtoi\t%1, %0"
4806   [(set_attr "type" "fp")
4807    (set_attr "fptype" "double")])
4809 (define_expand "fix_trunctfsi2"
4810   [(set (match_operand:SI 0 "register_operand" "")
4811         (fix:SI (match_operand:TF 1 "general_operand" "")))]
4812   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4813   "emit_tfmode_cvt (FIX, operands); DONE;")
4815 (define_insn "*fix_trunctfsi2_hq"
4816   [(set (match_operand:SI 0 "register_operand" "=f")
4817         (fix:SI (match_operand:TF 1 "register_operand" "e")))]
4818   "TARGET_FPU && TARGET_HARD_QUAD"
4819   "fqtoi\t%1, %0"
4820   [(set_attr "type" "fp")])
4822 (define_expand "fixuns_trunctfsi2"
4823   [(set (match_operand:SI 0 "register_operand" "")
4824         (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
4825   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4826   "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4828 ;; Now the same, for V9 targets
4830 (define_insn "fix_truncsfdi2"
4831   [(set (match_operand:DI 0 "register_operand" "=e")
4832         (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4833   "TARGET_V9 && TARGET_FPU"
4834   "fstox\t%1, %0"
4835   [(set_attr "type" "fp")
4836    (set_attr "fptype" "double")])
4838 (define_expand "fixuns_truncsfdi2"
4839   [(use (match_operand:DI 0 "register_operand" ""))
4840    (use (match_operand:SF 1 "general_operand" ""))]
4841   "TARGET_ARCH64 && TARGET_FPU"
4842   "sparc_emit_fixunsdi (operands, SFmode); DONE;")
4844 (define_insn "fix_truncdfdi2"
4845   [(set (match_operand:DI 0 "register_operand" "=e")
4846         (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4847   "TARGET_V9 && TARGET_FPU"
4848   "fdtox\t%1, %0"
4849   [(set_attr "type" "fp")
4850    (set_attr "fptype" "double")])
4852 (define_expand "fixuns_truncdfdi2"
4853   [(use (match_operand:DI 0 "register_operand" ""))
4854    (use (match_operand:DF 1 "general_operand" ""))]
4855   "TARGET_ARCH64 && TARGET_FPU"
4856   "sparc_emit_fixunsdi (operands, DFmode); DONE;")
4858 (define_expand "fix_trunctfdi2"
4859   [(set (match_operand:DI 0 "register_operand" "")
4860         (fix:DI (match_operand:TF 1 "general_operand" "")))]
4861   "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4862   "emit_tfmode_cvt (FIX, operands); DONE;")
4864 (define_insn "*fix_trunctfdi2_hq"
4865   [(set (match_operand:DI 0 "register_operand" "=e")
4866         (fix:DI (match_operand:TF 1 "register_operand" "e")))]
4867   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4868   "fqtox\t%1, %0"
4869   [(set_attr "type" "fp")])
4871 (define_expand "fixuns_trunctfdi2"
4872   [(set (match_operand:DI 0 "register_operand" "")
4873         (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
4874   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4875   "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4877 ;;- arithmetic instructions
4879 (define_expand "adddi3"
4880   [(set (match_operand:DI 0 "register_operand" "")
4881         (plus:DI (match_operand:DI 1 "register_operand" "")
4882                  (match_operand:DI 2 "arith_double_add_operand" "")))]
4883   ""
4885   if (! TARGET_ARCH64)
4886     {
4887       emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4888                           gen_rtx_SET (VOIDmode, operands[0],
4889                                    gen_rtx_PLUS (DImode, operands[1],
4890                                                  operands[2])),
4891                           gen_rtx_CLOBBER (VOIDmode,
4892                                    gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4893       DONE;
4894     }
4897 (define_insn_and_split "adddi3_insn_sp32"
4898   [(set (match_operand:DI 0 "register_operand" "=r")
4899         (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4900                  (match_operand:DI 2 "arith_double_operand" "rHI")))
4901    (clobber (reg:CC 100))]
4902   "! TARGET_ARCH64"
4903   "#"
4904   "&& reload_completed"
4905   [(parallel [(set (reg:CC_NOOV 100)
4906                    (compare:CC_NOOV (plus:SI (match_dup 4)
4907                                              (match_dup 5))
4908                                     (const_int 0)))
4909               (set (match_dup 3)
4910                    (plus:SI (match_dup 4) (match_dup 5)))])
4911    (set (match_dup 6)
4912         (plus:SI (plus:SI (match_dup 7)
4913                           (match_dup 8))
4914                  (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4916   operands[3] = gen_lowpart (SImode, operands[0]);
4917   operands[4] = gen_lowpart (SImode, operands[1]);
4918   operands[5] = gen_lowpart (SImode, operands[2]);
4919   operands[6] = gen_highpart (SImode, operands[0]);
4920   operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
4921 #if HOST_BITS_PER_WIDE_INT == 32
4922   if (GET_CODE (operands[2]) == CONST_INT)
4923     {
4924       if (INTVAL (operands[2]) < 0)
4925         operands[8] = constm1_rtx;
4926       else
4927         operands[8] = const0_rtx;
4928     }
4929   else
4930 #endif
4931     operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4933   [(set_attr "length" "2")])
4935 (define_split
4936   [(set (match_operand:DI 0 "register_operand" "")
4937         (minus:DI (match_operand:DI 1 "arith_double_operand" "")
4938                   (match_operand:DI 2 "arith_double_operand" "")))
4939    (clobber (reg:CC 100))]
4940   "! TARGET_ARCH64 && reload_completed"
4941   [(parallel [(set (reg:CC_NOOV 100)
4942                    (compare:CC_NOOV (minus:SI (match_dup 4)
4943                                               (match_dup 5))
4944                                     (const_int 0)))
4945               (set (match_dup 3)
4946                    (minus:SI (match_dup 4) (match_dup 5)))])
4947    (set (match_dup 6)
4948         (minus:SI (minus:SI (match_dup 7)
4949                             (match_dup 8))
4950                   (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4952   operands[3] = gen_lowpart (SImode, operands[0]);
4953   operands[4] = gen_lowpart (SImode, operands[1]);
4954   operands[5] = gen_lowpart (SImode, operands[2]);
4955   operands[6] = gen_highpart (SImode, operands[0]);
4956   operands[7] = gen_highpart (SImode, operands[1]);
4957 #if HOST_BITS_PER_WIDE_INT == 32
4958   if (GET_CODE (operands[2]) == CONST_INT)
4959     {
4960       if (INTVAL (operands[2]) < 0)
4961         operands[8] = constm1_rtx;
4962       else
4963         operands[8] = const0_rtx;
4964     }
4965   else
4966 #endif
4967     operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4970 ;; LTU here means "carry set"
4971 (define_insn "addx"
4972   [(set (match_operand:SI 0 "register_operand" "=r")
4973         (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4974                           (match_operand:SI 2 "arith_operand" "rI"))
4975                  (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4976   ""
4977   "addx\t%1, %2, %0"
4978   [(set_attr "type" "ialuX")])
4980 (define_insn_and_split "*addx_extend_sp32"
4981   [(set (match_operand:DI 0 "register_operand" "=r")
4982         (zero_extend:DI (plus:SI (plus:SI
4983                                   (match_operand:SI 1 "reg_or_0_operand" "%rJ")
4984                                   (match_operand:SI 2 "arith_operand" "rI"))
4985                                  (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4986   "! TARGET_ARCH64"
4987   "#"
4988   "&& reload_completed"
4989   [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
4990                                (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4991    (set (match_dup 4) (const_int 0))]
4992   "operands[3] = gen_lowpart (SImode, operands[0]);
4993    operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
4994   [(set_attr "length" "2")])
4996 (define_insn "*addx_extend_sp64"
4997   [(set (match_operand:DI 0 "register_operand" "=r")
4998         (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
4999                                           (match_operand:SI 2 "arith_operand" "rI"))
5000                                  (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5001   "TARGET_ARCH64"
5002   "addx\t%r1, %2, %0"
5003   [(set_attr "type" "ialuX")])
5005 (define_insn "subx"
5006   [(set (match_operand:SI 0 "register_operand" "=r")
5007         (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5008                             (match_operand:SI 2 "arith_operand" "rI"))
5009                   (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5010   ""
5011   "subx\t%r1, %2, %0"
5012   [(set_attr "type" "ialuX")])
5014 (define_insn "*subx_extend_sp64"
5015   [(set (match_operand:DI 0 "register_operand" "=r")
5016         (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5017                                             (match_operand:SI 2 "arith_operand" "rI"))
5018                                   (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5019   "TARGET_ARCH64"
5020   "subx\t%r1, %2, %0"
5021   [(set_attr "type" "ialuX")])
5023 (define_insn_and_split "*subx_extend"
5024   [(set (match_operand:DI 0 "register_operand" "=r")
5025         (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5026                                             (match_operand:SI 2 "arith_operand" "rI"))
5027                                   (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5028   "! TARGET_ARCH64"
5029   "#"
5030   "&& reload_completed"
5031   [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
5032                                 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
5033    (set (match_dup 4) (const_int 0))]
5034   "operands[3] = gen_lowpart (SImode, operands[0]);
5035    operands[4] = gen_highpart (SImode, operands[0]);"
5036   [(set_attr "length" "2")])
5038 (define_insn_and_split ""
5039   [(set (match_operand:DI 0 "register_operand" "=r")
5040         (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5041                  (match_operand:DI 2 "register_operand" "r")))
5042    (clobber (reg:CC 100))]
5043   "! TARGET_ARCH64"
5044   "#"
5045   "&& reload_completed"
5046   [(parallel [(set (reg:CC_NOOV 100)
5047                    (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
5048                                     (const_int 0)))
5049               (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
5050    (set (match_dup 6)
5051         (plus:SI (plus:SI (match_dup 4) (const_int 0))
5052                  (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5053   "operands[3] = gen_lowpart (SImode, operands[2]);
5054    operands[4] = gen_highpart (SImode, operands[2]);
5055    operands[5] = gen_lowpart (SImode, operands[0]);
5056    operands[6] = gen_highpart (SImode, operands[0]);"
5057   [(set_attr "length" "2")])
5059 (define_insn "*adddi3_sp64"
5060   [(set (match_operand:DI 0 "register_operand" "=r,r")
5061         (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
5062                  (match_operand:DI 2 "arith_double_add_operand" "rHI,O")))]
5063   "TARGET_ARCH64"
5064   "@
5065    add\t%1, %2, %0
5066    sub\t%1, -%2, %0")
5068 (define_insn "addsi3"
5069   [(set (match_operand:SI 0 "register_operand" "=r,r,d")
5070         (plus:SI (match_operand:SI 1 "register_operand" "%r,r,d")
5071                  (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
5072   ""
5073   "@
5074    add\t%1, %2, %0
5075    sub\t%1, -%2, %0
5076    fpadd32s\t%1, %2, %0"
5077   [(set_attr "type" "*,*,fga")
5078    (set_attr "fptype" "*,*,single")])
5080 (define_insn "*cmp_cc_plus"
5081   [(set (reg:CC_NOOV 100)
5082         (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
5083                                   (match_operand:SI 1 "arith_operand" "rI"))
5084                          (const_int 0)))]
5085   ""
5086   "addcc\t%0, %1, %%g0"
5087   [(set_attr "type" "compare")])
5089 (define_insn "*cmp_ccx_plus"
5090   [(set (reg:CCX_NOOV 100)
5091         (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_double_operand" "%r")
5092                                    (match_operand:DI 1 "arith_double_operand" "rHI"))
5093                           (const_int 0)))]
5094   "TARGET_ARCH64"
5095   "addcc\t%0, %1, %%g0"
5096   [(set_attr "type" "compare")])
5098 (define_insn "*cmp_cc_plus_set"
5099   [(set (reg:CC_NOOV 100)
5100         (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5101                                   (match_operand:SI 2 "arith_operand" "rI"))
5102                          (const_int 0)))
5103    (set (match_operand:SI 0 "register_operand" "=r")
5104         (plus:SI (match_dup 1) (match_dup 2)))]
5105   ""
5106   "addcc\t%1, %2, %0"
5107   [(set_attr "type" "compare")])
5109 (define_insn "*cmp_ccx_plus_set"
5110   [(set (reg:CCX_NOOV 100)
5111         (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5112                                    (match_operand:DI 2 "arith_double_operand" "rHI"))
5113                           (const_int 0)))
5114    (set (match_operand:DI 0 "register_operand" "=r")
5115         (plus:DI (match_dup 1) (match_dup 2)))]
5116   "TARGET_ARCH64"
5117   "addcc\t%1, %2, %0"
5118   [(set_attr "type" "compare")])
5120 (define_expand "subdi3"
5121   [(set (match_operand:DI 0 "register_operand" "")
5122         (minus:DI (match_operand:DI 1 "register_operand" "")
5123                   (match_operand:DI 2 "arith_double_add_operand" "")))]
5124   ""
5126   if (! TARGET_ARCH64)
5127     {
5128       emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5129                           gen_rtx_SET (VOIDmode, operands[0],
5130                                    gen_rtx_MINUS (DImode, operands[1],
5131                                                   operands[2])),
5132                           gen_rtx_CLOBBER (VOIDmode,
5133                                    gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5134       DONE;
5135     }
5138 (define_insn_and_split "*subdi3_sp32"
5139   [(set (match_operand:DI 0 "register_operand" "=r")
5140         (minus:DI (match_operand:DI 1 "register_operand" "r")
5141                   (match_operand:DI 2 "arith_double_operand" "rHI")))
5142    (clobber (reg:CC 100))]
5143   "! TARGET_ARCH64"
5144   "#"
5145   "&& reload_completed
5146    && (GET_CODE (operands[2]) == CONST_INT
5147        || GET_CODE (operands[2]) == CONST_DOUBLE)"
5148   [(clobber (const_int 0))]
5150   rtx highp, lowp;
5152   highp = gen_highpart_mode (SImode, DImode, operands[2]);
5153   lowp = gen_lowpart (SImode, operands[2]);
5154   if ((lowp == const0_rtx)
5155       && (operands[0] == operands[1]))
5156     {
5157       emit_insn (gen_rtx_SET (VOIDmode,
5158                               gen_highpart (SImode, operands[0]),
5159                               gen_rtx_MINUS (SImode,
5160                                              gen_highpart_mode (SImode, DImode,
5161                                                                 operands[1]),
5162                                              highp)));
5163     }
5164   else
5165     {
5166       emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5167                                        gen_lowpart (SImode, operands[1]),
5168                                        lowp));
5169       emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5170                            gen_highpart_mode (SImode, DImode, operands[1]),
5171                            highp));
5172     }
5173   DONE;
5175   [(set_attr "length" "2")])
5177 (define_split
5178   [(set (match_operand:DI 0 "register_operand" "")
5179         (minus:DI (match_operand:DI 1 "register_operand" "")
5180                   (match_operand:DI 2 "register_operand" "")))
5181    (clobber (reg:CC 100))]
5182   "! TARGET_ARCH64
5183    && reload_completed"
5184   [(clobber (const_int 0))]
5186   emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5187                                    gen_lowpart (SImode, operands[1]),
5188                                    gen_lowpart (SImode, operands[2])));
5189   emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5190                        gen_highpart (SImode, operands[1]),
5191                        gen_highpart (SImode, operands[2])));
5192   DONE;
5195 (define_insn_and_split ""
5196   [(set (match_operand:DI 0 "register_operand" "=r")
5197       (minus:DI (match_operand:DI 1 "register_operand" "r")
5198                 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
5199    (clobber (reg:CC 100))]
5200   "! TARGET_ARCH64"
5201   "#"
5202   "&& reload_completed"
5203   [(parallel [(set (reg:CC_NOOV 100)
5204                    (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
5205                                     (const_int 0)))
5206               (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
5207    (set (match_dup 6)
5208         (minus:SI (minus:SI (match_dup 4) (const_int 0))
5209                   (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5210   "operands[3] = gen_lowpart (SImode, operands[1]);
5211    operands[4] = gen_highpart (SImode, operands[1]);
5212    operands[5] = gen_lowpart (SImode, operands[0]);
5213    operands[6] = gen_highpart (SImode, operands[0]);"
5214   [(set_attr "length" "2")])
5216 (define_insn "*subdi3_sp64"
5217   [(set (match_operand:DI 0 "register_operand" "=r,r")
5218         (minus:DI (match_operand:DI 1 "register_operand" "r,r")
5219                   (match_operand:DI 2 "arith_double_add_operand" "rHI,O")))]
5220   "TARGET_ARCH64"
5221   "@
5222    sub\t%1, %2, %0
5223    add\t%1, -%2, %0")
5225 (define_insn "subsi3"
5226   [(set (match_operand:SI 0 "register_operand" "=r,r,d")
5227         (minus:SI (match_operand:SI 1 "register_operand" "r,r,d")
5228                   (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
5229   ""
5230   "@
5231    sub\t%1, %2, %0
5232    add\t%1, -%2, %0
5233    fpsub32s\t%1, %2, %0"
5234   [(set_attr "type" "*,*,fga")
5235    (set_attr "fptype" "*,*,single")])
5237 (define_insn "*cmp_minus_cc"
5238   [(set (reg:CC_NOOV 100)
5239         (compare:CC_NOOV (minus:SI (match_operand:SI 0 "reg_or_0_operand" "rJ")
5240                                    (match_operand:SI 1 "arith_operand" "rI"))
5241                          (const_int 0)))]
5242   ""
5243   "subcc\t%r0, %1, %%g0"
5244   [(set_attr "type" "compare")])
5246 (define_insn "*cmp_minus_ccx"
5247   [(set (reg:CCX_NOOV 100)
5248         (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
5249                                     (match_operand:DI 1 "arith_double_operand" "rHI"))
5250                           (const_int 0)))]
5251   "TARGET_ARCH64"
5252   "subcc\t%0, %1, %%g0"
5253   [(set_attr "type" "compare")])
5255 (define_insn "cmp_minus_cc_set"
5256   [(set (reg:CC_NOOV 100)
5257         (compare:CC_NOOV (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5258                                    (match_operand:SI 2 "arith_operand" "rI"))
5259                          (const_int 0)))
5260    (set (match_operand:SI 0 "register_operand" "=r")
5261         (minus:SI (match_dup 1) (match_dup 2)))]
5262   ""
5263   "subcc\t%r1, %2, %0"
5264   [(set_attr "type" "compare")])
5266 (define_insn "*cmp_minus_ccx_set"
5267   [(set (reg:CCX_NOOV 100)
5268         (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
5269                                     (match_operand:DI 2 "arith_double_operand" "rHI"))
5270                           (const_int 0)))
5271    (set (match_operand:DI 0 "register_operand" "=r")
5272         (minus:DI (match_dup 1) (match_dup 2)))]
5273   "TARGET_ARCH64"
5274   "subcc\t%1, %2, %0"
5275   [(set_attr "type" "compare")])
5277 ;; Integer Multiply/Divide.
5279 ;; The 32 bit multiply/divide instructions are deprecated on v9, but at
5280 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
5282 (define_insn "mulsi3"
5283   [(set (match_operand:SI 0 "register_operand" "=r")
5284         (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5285                  (match_operand:SI 2 "arith_operand" "rI")))]
5286   "TARGET_HARD_MUL"
5287   "smul\t%1, %2, %0"
5288   [(set_attr "type" "imul")])
5290 (define_expand "muldi3"
5291   [(set (match_operand:DI 0 "register_operand" "=r")
5292         (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5293                  (match_operand:DI 2 "arith_double_operand" "rHI")))]
5294   "TARGET_ARCH64 || TARGET_V8PLUS"
5296   if (TARGET_V8PLUS)
5297     {
5298       emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
5299       DONE;
5300     }
5303 (define_insn "*muldi3_sp64"
5304   [(set (match_operand:DI 0 "register_operand" "=r")
5305         (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5306                  (match_operand:DI 2 "arith_double_operand" "rHI")))]
5307   "TARGET_ARCH64"
5308   "mulx\t%1, %2, %0"
5309   [(set_attr "type" "imul")])
5311 ;; V8plus wide multiply.
5312 ;; XXX
5313 (define_insn "muldi3_v8plus"
5314   [(set (match_operand:DI 0 "register_operand" "=r,h")
5315         (mult:DI (match_operand:DI 1 "arith_double_operand" "%r,0")
5316                  (match_operand:DI 2 "arith_double_operand" "rI,rI")))
5317    (clobber (match_scratch:SI 3 "=&h,X"))
5318    (clobber (match_scratch:SI 4 "=&h,X"))]
5319   "TARGET_V8PLUS"
5321   if (sparc_check_64 (operands[1], insn) <= 0)
5322     output_asm_insn ("srl\t%L1, 0, %L1", operands);
5323   if (which_alternative == 1)
5324     output_asm_insn ("sllx\t%H1, 32, %H1", operands);
5325   if (GET_CODE (operands[2]) == CONST_INT)
5326     {
5327       if (which_alternative == 1)
5328         return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %2, %L0\;srlx\t%L0, 32, %H0";
5329       else
5330         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";
5331     }
5332   else if (rtx_equal_p (operands[1], operands[2]))
5333     {
5334       if (which_alternative == 1)
5335         return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %H1, %L0\;srlx\t%L0, 32, %H0";
5336       else
5337         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";
5338     }
5339   if (sparc_check_64 (operands[2], insn) <= 0)
5340     output_asm_insn ("srl\t%L2, 0, %L2", operands);
5341   if (which_alternative == 1)
5342     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";
5343   else
5344     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";
5346   [(set_attr "type" "multi")
5347    (set_attr "length" "9,8")])
5349 (define_insn "*cmp_mul_set"
5350   [(set (reg:CC 100)
5351         (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5352                     (match_operand:SI 2 "arith_operand" "rI"))
5353                     (const_int 0)))
5354    (set (match_operand:SI 0 "register_operand" "=r")
5355         (mult:SI (match_dup 1) (match_dup 2)))]
5356   "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
5357   "smulcc\t%1, %2, %0"
5358   [(set_attr "type" "imul")])
5360 (define_expand "mulsidi3"
5361   [(set (match_operand:DI 0 "register_operand" "")
5362         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5363                  (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
5364   "TARGET_HARD_MUL"
5366   if (CONSTANT_P (operands[2]))
5367     {
5368       if (TARGET_V8PLUS)
5369         emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
5370                                               operands[2]));
5371       else if (TARGET_ARCH32)
5372         emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
5373                                             operands[2]));
5374       else 
5375         emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
5376                                             operands[2]));
5377       DONE;
5378     }
5379   if (TARGET_V8PLUS)
5380     {
5381       emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
5382       DONE;
5383     }
5386 ;; V9 puts the 64 bit product in a 64 bit register.  Only out or global
5387 ;; registers can hold 64 bit values in the V8plus environment.
5388 ;; XXX
5389 (define_insn "mulsidi3_v8plus"
5390   [(set (match_operand:DI 0 "register_operand" "=h,r")
5391         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5392                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5393    (clobber (match_scratch:SI 3 "=X,&h"))]
5394   "TARGET_V8PLUS"
5395   "@
5396    smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5397    smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5398   [(set_attr "type" "multi")
5399    (set_attr "length" "2,3")])
5401 ;; XXX
5402 (define_insn "const_mulsidi3_v8plus"
5403   [(set (match_operand:DI 0 "register_operand" "=h,r")
5404         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5405                  (match_operand:DI 2 "small_int" "I,I")))
5406    (clobber (match_scratch:SI 3 "=X,&h"))]
5407   "TARGET_V8PLUS"
5408   "@
5409    smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5410    smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5411   [(set_attr "type" "multi")
5412    (set_attr "length" "2,3")])
5414 ;; XXX
5415 (define_insn "*mulsidi3_sp32"
5416   [(set (match_operand:DI 0 "register_operand" "=r")
5417         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5418                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5419   "TARGET_HARD_MUL32"
5421   return TARGET_SPARCLET
5422          ? "smuld\t%1, %2, %L0"
5423          : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
5425   [(set (attr "type")
5426         (if_then_else (eq_attr "isa" "sparclet")
5427                       (const_string "imul") (const_string "multi")))
5428    (set (attr "length")
5429         (if_then_else (eq_attr "isa" "sparclet")
5430                       (const_int 1) (const_int 2)))])
5432 (define_insn "*mulsidi3_sp64"
5433   [(set (match_operand:DI 0 "register_operand" "=r")
5434         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5435                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5436   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5437   "smul\t%1, %2, %0"
5438   [(set_attr "type" "imul")])
5440 ;; Extra pattern, because sign_extend of a constant isn't valid.
5442 ;; XXX
5443 (define_insn "const_mulsidi3_sp32"
5444   [(set (match_operand:DI 0 "register_operand" "=r")
5445         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5446                  (match_operand:DI 2 "small_int" "I")))]
5447   "TARGET_HARD_MUL32"
5449   return TARGET_SPARCLET
5450          ? "smuld\t%1, %2, %L0"
5451          : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
5453   [(set (attr "type")
5454         (if_then_else (eq_attr "isa" "sparclet")
5455                       (const_string "imul") (const_string "multi")))
5456    (set (attr "length")
5457         (if_then_else (eq_attr "isa" "sparclet")
5458                       (const_int 1) (const_int 2)))])
5460 (define_insn "const_mulsidi3_sp64"
5461   [(set (match_operand:DI 0 "register_operand" "=r")
5462         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5463                  (match_operand:DI 2 "small_int" "I")))]
5464   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5465   "smul\t%1, %2, %0"
5466   [(set_attr "type" "imul")])
5468 (define_expand "smulsi3_highpart"
5469   [(set (match_operand:SI 0 "register_operand" "")
5470         (truncate:SI
5471          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5472                                (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
5473                       (const_int 32))))]
5474   "TARGET_HARD_MUL && TARGET_ARCH32"
5476   if (CONSTANT_P (operands[2]))
5477     {
5478       if (TARGET_V8PLUS)
5479         {
5480           emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
5481                                                         operands[1],
5482                                                         operands[2],
5483                                                         GEN_INT (32)));
5484           DONE;
5485         }
5486       emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
5487       DONE;
5488     }
5489   if (TARGET_V8PLUS)
5490     {
5491       emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
5492                                               operands[2], GEN_INT (32)));
5493       DONE;
5494     }
5497 ;; XXX
5498 (define_insn "smulsi3_highpart_v8plus"
5499   [(set (match_operand:SI 0 "register_operand" "=h,r")
5500         (truncate:SI
5501          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5502                                (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5503                       (match_operand:SI 3 "const_int_operand" "i,i"))))
5504    (clobber (match_scratch:SI 4 "=X,&h"))]
5505   "TARGET_V8PLUS"
5506   "@
5507    smul\t%1, %2, %0\;srlx\t%0, %3, %0
5508    smul\t%1, %2, %4\;srlx\t%4, %3, %0"
5509   [(set_attr "type" "multi")
5510    (set_attr "length" "2")])
5512 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
5513 ;; XXX
5514 (define_insn ""
5515   [(set (match_operand:SI 0 "register_operand" "=h,r")
5516         (subreg:SI
5517          (lshiftrt:DI
5518           (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5519                    (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5520           (match_operand:SI 3 "const_int_operand" "i,i"))
5521          4))
5522    (clobber (match_scratch:SI 4 "=X,&h"))]
5523   "TARGET_V8PLUS"
5524   "@
5525    smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5526    smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5527   [(set_attr "type" "multi")
5528    (set_attr "length" "2")])
5530 ;; XXX
5531 (define_insn "const_smulsi3_highpart_v8plus"
5532   [(set (match_operand:SI 0 "register_operand" "=h,r")
5533         (truncate:SI
5534          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5535                                (match_operand:DI 2 "small_int" "i,i"))
5536                       (match_operand:SI 3 "const_int_operand" "i,i"))))
5537    (clobber (match_scratch:SI 4 "=X,&h"))]
5538   "TARGET_V8PLUS"
5539   "@
5540    smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5541    smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5542   [(set_attr "type" "multi")
5543    (set_attr "length" "2")])
5545 ;; XXX
5546 (define_insn "*smulsi3_highpart_sp32"
5547   [(set (match_operand:SI 0 "register_operand" "=r")
5548         (truncate:SI
5549          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5550                                (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
5551                       (const_int 32))))]
5552   "TARGET_HARD_MUL32"
5553   "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
5554   [(set_attr "type" "multi")
5555    (set_attr "length" "2")])
5557 ;; XXX
5558 (define_insn "const_smulsi3_highpart"
5559   [(set (match_operand:SI 0 "register_operand" "=r")
5560         (truncate:SI
5561          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5562                                (match_operand:DI 2 "small_int" "i"))
5563                       (const_int 32))))]
5564   "TARGET_HARD_MUL32"
5565   "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
5566   [(set_attr "type" "multi")
5567    (set_attr "length" "2")])
5569 (define_expand "umulsidi3"
5570   [(set (match_operand:DI 0 "register_operand" "")
5571         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5572                  (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
5573   "TARGET_HARD_MUL"
5575   if (CONSTANT_P (operands[2]))
5576     {
5577       if (TARGET_V8PLUS)
5578         emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
5579                                                operands[2]));
5580       else if (TARGET_ARCH32)
5581         emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
5582                                              operands[2]));
5583       else 
5584         emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
5585                                              operands[2]));
5586       DONE;
5587     }
5588   if (TARGET_V8PLUS)
5589     {
5590       emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
5591       DONE;
5592     }
5595 ;; XXX
5596 (define_insn "umulsidi3_v8plus"
5597   [(set (match_operand:DI 0 "register_operand" "=h,r")
5598         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5599                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5600    (clobber (match_scratch:SI 3 "=X,&h"))]
5601   "TARGET_V8PLUS"
5602   "@
5603    umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5604    umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5605   [(set_attr "type" "multi")
5606    (set_attr "length" "2,3")])
5608 ;; XXX
5609 (define_insn "*umulsidi3_sp32"
5610   [(set (match_operand:DI 0 "register_operand" "=r")
5611         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5612                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5613   "TARGET_HARD_MUL32"
5615   return TARGET_SPARCLET
5616          ? "umuld\t%1, %2, %L0"
5617          : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
5619   [(set (attr "type")
5620         (if_then_else (eq_attr "isa" "sparclet")
5621                       (const_string "imul") (const_string "multi")))
5622    (set (attr "length")
5623         (if_then_else (eq_attr "isa" "sparclet")
5624                       (const_int 1) (const_int 2)))])
5626 (define_insn "*umulsidi3_sp64"
5627   [(set (match_operand:DI 0 "register_operand" "=r")
5628         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5629                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5630   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5631   "umul\t%1, %2, %0"
5632   [(set_attr "type" "imul")])
5634 ;; Extra pattern, because sign_extend of a constant isn't valid.
5636 ;; XXX
5637 (define_insn "const_umulsidi3_sp32"
5638   [(set (match_operand:DI 0 "register_operand" "=r")
5639         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5640                  (match_operand:DI 2 "uns_small_int" "")))]
5641   "TARGET_HARD_MUL32"
5643   return TARGET_SPARCLET
5644          ? "umuld\t%1, %s2, %L0"
5645          : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
5647   [(set (attr "type")
5648         (if_then_else (eq_attr "isa" "sparclet")
5649                       (const_string "imul") (const_string "multi")))
5650    (set (attr "length")
5651         (if_then_else (eq_attr "isa" "sparclet")
5652                       (const_int 1) (const_int 2)))])
5654 (define_insn "const_umulsidi3_sp64"
5655   [(set (match_operand:DI 0 "register_operand" "=r")
5656         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5657                  (match_operand:DI 2 "uns_small_int" "")))]
5658   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5659   "umul\t%1, %s2, %0"
5660   [(set_attr "type" "imul")])
5662 ;; XXX
5663 (define_insn "const_umulsidi3_v8plus"
5664   [(set (match_operand:DI 0 "register_operand" "=h,r")
5665         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5666                  (match_operand:DI 2 "uns_small_int" "")))
5667    (clobber (match_scratch:SI 3 "=X,h"))]
5668   "TARGET_V8PLUS"
5669   "@
5670    umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
5671    umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5672   [(set_attr "type" "multi")
5673    (set_attr "length" "2,3")])
5675 (define_expand "umulsi3_highpart"
5676   [(set (match_operand:SI 0 "register_operand" "")
5677         (truncate:SI
5678          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5679                                (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
5680                       (const_int 32))))]
5681   "TARGET_HARD_MUL && TARGET_ARCH32"
5683   if (CONSTANT_P (operands[2]))
5684     {
5685       if (TARGET_V8PLUS)
5686         {
5687           emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
5688                                                         operands[1],
5689                                                         operands[2],
5690                                                         GEN_INT (32)));
5691           DONE;
5692         }
5693       emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
5694       DONE;
5695     }
5696   if (TARGET_V8PLUS)
5697     {
5698       emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
5699                                               operands[2], GEN_INT (32)));
5700       DONE;
5701     }
5704 ;; XXX
5705 (define_insn "umulsi3_highpart_v8plus"
5706   [(set (match_operand:SI 0 "register_operand" "=h,r")
5707         (truncate:SI
5708          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5709                                (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5710                       (match_operand:SI 3 "const_int_operand" "i,i"))))
5711    (clobber (match_scratch:SI 4 "=X,h"))]
5712   "TARGET_V8PLUS"
5713   "@
5714    umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5715    umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5716   [(set_attr "type" "multi")
5717    (set_attr "length" "2")])
5719 ;; XXX
5720 (define_insn "const_umulsi3_highpart_v8plus"
5721   [(set (match_operand:SI 0 "register_operand" "=h,r")
5722         (truncate:SI
5723          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5724                                (match_operand:DI 2 "uns_small_int" ""))
5725                       (match_operand:SI 3 "const_int_operand" "i,i"))))
5726    (clobber (match_scratch:SI 4 "=X,h"))]
5727   "TARGET_V8PLUS"
5728   "@
5729    umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
5730    umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
5731   [(set_attr "type" "multi")
5732    (set_attr "length" "2")])
5734 ;; XXX
5735 (define_insn "*umulsi3_highpart_sp32"
5736   [(set (match_operand:SI 0 "register_operand" "=r")
5737         (truncate:SI
5738          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5739                                (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
5740                       (const_int 32))))]
5741   "TARGET_HARD_MUL32"
5742   "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
5743   [(set_attr "type" "multi")
5744    (set_attr "length" "2")])
5746 ;; XXX
5747 (define_insn "const_umulsi3_highpart"
5748   [(set (match_operand:SI 0 "register_operand" "=r")
5749         (truncate:SI
5750          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5751                                (match_operand:DI 2 "uns_small_int" ""))
5752                       (const_int 32))))]
5753   "TARGET_HARD_MUL32"
5754   "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
5755   [(set_attr "type" "multi")
5756    (set_attr "length" "2")])
5758 ;; The v8 architecture specifies that there must be 3 instructions between
5759 ;; a y register write and a use of it for correct results.
5761 (define_expand "divsi3"
5762   [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
5763                    (div:SI (match_operand:SI 1 "register_operand" "r,r")
5764                            (match_operand:SI 2 "input_operand" "rI,m")))
5765               (clobber (match_scratch:SI 3 "=&r,&r"))])]
5766   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5768   if (TARGET_ARCH64)
5769     {
5770       operands[3] = gen_reg_rtx(SImode);
5771       emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
5772       emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
5773                                   operands[3]));
5774       DONE;
5775     }
5778 (define_insn "divsi3_sp32"
5779   [(set (match_operand:SI 0 "register_operand" "=r,r")
5780         (div:SI (match_operand:SI 1 "register_operand" "r,r")
5781                 (match_operand:SI 2 "input_operand" "rI,m")))
5782    (clobber (match_scratch:SI 3 "=&r,&r"))]
5783   "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
5784    && TARGET_ARCH32"
5786   if (which_alternative == 0)
5787     if (TARGET_V9)
5788       return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdiv\t%1, %2, %0";
5789     else
5790       return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
5791   else
5792     if (TARGET_V9)
5793       return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tld\t%2, %3\n\tsdiv\t%1, %3, %0";
5794     else
5795       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";
5797   [(set_attr "type" "multi")
5798    (set (attr "length")
5799         (if_then_else (eq_attr "isa" "v9")
5800                       (const_int 4) (const_int 6)))])
5802 (define_insn "divsi3_sp64"
5803   [(set (match_operand:SI 0 "register_operand" "=r")
5804         (div:SI (match_operand:SI 1 "register_operand" "r")
5805                 (match_operand:SI 2 "input_operand" "rI")))
5806    (use (match_operand:SI 3 "register_operand" "r"))]
5807   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5808   "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
5809   [(set_attr "type" "multi")
5810    (set_attr "length" "2")])
5812 (define_insn "divdi3"
5813   [(set (match_operand:DI 0 "register_operand" "=r")
5814         (div:DI (match_operand:DI 1 "register_operand" "r")
5815                 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5816   "TARGET_ARCH64"
5817   "sdivx\t%1, %2, %0"
5818   [(set_attr "type" "idiv")])
5820 (define_insn "*cmp_sdiv_cc_set"
5821   [(set (reg:CC 100)
5822         (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
5823                             (match_operand:SI 2 "arith_operand" "rI"))
5824                     (const_int 0)))
5825    (set (match_operand:SI 0 "register_operand" "=r")
5826         (div:SI (match_dup 1) (match_dup 2)))
5827    (clobber (match_scratch:SI 3 "=&r"))]
5828   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5830   if (TARGET_V9)
5831     return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdivcc\t%1, %2, %0";
5832   else
5833     return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
5835   [(set_attr "type" "multi")
5836    (set (attr "length")
5837         (if_then_else (eq_attr "isa" "v9")
5838                       (const_int 3) (const_int 6)))])
5840 ;; XXX
5841 (define_expand "udivsi3"
5842   [(set (match_operand:SI 0 "register_operand" "")
5843         (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "")
5844                  (match_operand:SI 2 "input_operand" "")))]
5845   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5846   "")
5848 (define_insn "udivsi3_sp32"
5849   [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
5850         (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r,r,m")
5851                  (match_operand:SI 2 "input_operand" "rI,m,r")))]
5852   "(TARGET_V8
5853     || TARGET_DEPRECATED_V8_INSNS)
5854    && TARGET_ARCH32"
5856   output_asm_insn ("wr\t%%g0, %%g0, %%y", operands);
5857   switch (which_alternative)
5858     {
5859     default:
5860       return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
5861     case 1:
5862       return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
5863     case 2:
5864       return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
5865     }
5867   [(set_attr "type" "multi")
5868    (set_attr "length" "5")])
5870 (define_insn "udivsi3_sp64"
5871   [(set (match_operand:SI 0 "register_operand" "=r")
5872         (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r")
5873                  (match_operand:SI 2 "input_operand" "rI")))]
5874   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5875   "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
5876   [(set_attr "type" "multi")
5877    (set_attr "length" "2")])
5879 (define_insn "udivdi3"
5880   [(set (match_operand:DI 0 "register_operand" "=r")
5881         (udiv:DI (match_operand:DI 1 "register_operand" "r")
5882                  (match_operand:DI 2 "arith_double_operand" "rHI")))]
5883   "TARGET_ARCH64"
5884   "udivx\t%1, %2, %0"
5885   [(set_attr "type" "idiv")])
5887 (define_insn "*cmp_udiv_cc_set"
5888   [(set (reg:CC 100)
5889         (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
5890                              (match_operand:SI 2 "arith_operand" "rI"))
5891                     (const_int 0)))
5892    (set (match_operand:SI 0 "register_operand" "=r")
5893         (udiv:SI (match_dup 1) (match_dup 2)))]
5894   "TARGET_V8
5895    || TARGET_DEPRECATED_V8_INSNS"
5897   if (TARGET_V9)
5898     return "wr\t%%g0, %%g0, %%y\n\tudivcc\t%1, %2, %0";
5899   else
5900     return "wr\t%%g0, %%g0, %%y\n\tnop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
5902   [(set_attr "type" "multi")
5903    (set (attr "length")
5904         (if_then_else (eq_attr "isa" "v9")
5905                       (const_int 2) (const_int 5)))])
5907 ; sparclet multiply/accumulate insns
5909 (define_insn "*smacsi"
5910   [(set (match_operand:SI 0 "register_operand" "=r")
5911         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
5912                           (match_operand:SI 2 "arith_operand" "rI"))
5913                  (match_operand:SI 3 "register_operand" "0")))]
5914   "TARGET_SPARCLET"
5915   "smac\t%1, %2, %0"
5916   [(set_attr "type" "imul")])
5918 (define_insn "*smacdi"
5919   [(set (match_operand:DI 0 "register_operand" "=r")
5920         (plus:DI (mult:DI (sign_extend:DI
5921                            (match_operand:SI 1 "register_operand" "%r"))
5922                           (sign_extend:DI
5923                            (match_operand:SI 2 "register_operand" "r")))
5924                  (match_operand:DI 3 "register_operand" "0")))]
5925   "TARGET_SPARCLET"
5926   "smacd\t%1, %2, %L0"
5927   [(set_attr "type" "imul")])
5929 (define_insn "*umacdi"
5930   [(set (match_operand:DI 0 "register_operand" "=r")
5931         (plus:DI (mult:DI (zero_extend:DI
5932                            (match_operand:SI 1 "register_operand" "%r"))
5933                           (zero_extend:DI
5934                            (match_operand:SI 2 "register_operand" "r")))
5935                  (match_operand:DI 3 "register_operand" "0")))]
5936   "TARGET_SPARCLET"
5937   "umacd\t%1, %2, %L0"
5938   [(set_attr "type" "imul")])
5940 ;;- Boolean instructions
5941 ;; We define DImode `and' so with DImode `not' we can get
5942 ;; DImode `andn'.  Other combinations are possible.
5944 (define_mode_macro V64I [DI V2SI V4HI V8QI])
5945 (define_mode_macro V32I [SI V2HI V4QI])
5947 (define_expand "and<V64I:mode>3"
5948   [(set (match_operand:V64I 0 "register_operand" "")
5949         (and:V64I (match_operand:V64I 1 "arith_double_operand" "")
5950                   (match_operand:V64I 2 "arith_double_operand" "")))]
5951   ""
5952   "")
5954 (define_insn "*and<V64I:mode>3_sp32"
5955   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5956         (and:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5957                   (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5958   "! TARGET_ARCH64"
5959   "@
5960   #
5961   fand\t%1, %2, %0"
5962   [(set_attr "type" "*,fga")
5963    (set_attr "length" "2,*")
5964    (set_attr "fptype" "*,double")])
5966 (define_insn "*and<V64I:mode>3_sp64"
5967   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5968         (and:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5969                   (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5970   "TARGET_ARCH64"
5971   "@
5972    and\t%1, %2, %0
5973    fand\t%1, %2, %0"
5974   [(set_attr "type" "*,fga")
5975    (set_attr "fptype" "*,double")])
5977 (define_insn "and<V32I:mode>3"
5978   [(set (match_operand:V32I 0 "register_operand" "=r,d")
5979         (and:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
5980                 (match_operand:V32I 2 "arith_operand" "rI,d")))]
5981   ""
5982   "@
5983    and\t%1, %2, %0
5984    fands\t%1, %2, %0"
5985   [(set_attr "type" "*,fga")
5986    (set_attr "fptype" "*,single")])
5988 (define_split
5989   [(set (match_operand:SI 0 "register_operand" "")
5990         (and:SI (match_operand:SI 1 "register_operand" "")
5991                 (match_operand:SI 2 "" "")))
5992    (clobber (match_operand:SI 3 "register_operand" ""))]
5993   "GET_CODE (operands[2]) == CONST_INT
5994    && !SMALL_INT32 (operands[2])
5995    && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
5996   [(set (match_dup 3) (match_dup 4))
5997    (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
5999   operands[4] = GEN_INT (~INTVAL (operands[2]));
6002 (define_insn_and_split "*and_not_<V64I:mode>_sp32"
6003   [(set (match_operand:V64I 0 "register_operand" "=r,b")
6004         (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
6005                   (match_operand:V64I 2 "register_operand" "r,b")))]
6006   "! TARGET_ARCH64"
6007   "@
6008    #
6009    fandnot1\t%1, %2, %0"
6010   "&& reload_completed
6011    && ((GET_CODE (operands[0]) == REG
6012         && REGNO (operands[0]) < 32)
6013        || (GET_CODE (operands[0]) == SUBREG
6014            && GET_CODE (SUBREG_REG (operands[0])) == REG
6015            && REGNO (SUBREG_REG (operands[0])) < 32))"
6016   [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
6017    (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
6018   "operands[3] = gen_highpart (SImode, operands[0]);
6019    operands[4] = gen_highpart (SImode, operands[1]);
6020    operands[5] = gen_highpart (SImode, operands[2]);
6021    operands[6] = gen_lowpart (SImode, operands[0]);
6022    operands[7] = gen_lowpart (SImode, operands[1]);
6023    operands[8] = gen_lowpart (SImode, operands[2]);"
6024   [(set_attr "type" "*,fga")
6025    (set_attr "length" "2,*")
6026    (set_attr "fptype" "*,double")])
6028 (define_insn "*and_not_<V64I:mode>_sp64"
6029   [(set (match_operand:V64I 0 "register_operand" "=r,b")
6030         (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
6031                   (match_operand:V64I 2 "register_operand" "r,b")))]
6032   "TARGET_ARCH64"
6033   "@
6034    andn\t%2, %1, %0
6035    fandnot1\t%1, %2, %0"
6036   [(set_attr "type" "*,fga")
6037    (set_attr "fptype" "*,double")])
6039 (define_insn "*and_not_<V32I:mode>"
6040   [(set (match_operand:V32I 0 "register_operand" "=r,d")
6041         (and:V32I (not:V32I (match_operand:V32I 1 "register_operand" "%r,d"))
6042                   (match_operand:V32I 2 "register_operand" "r,d")))]
6043   ""
6044   "@
6045    andn\t%2, %1, %0
6046    fandnot1s\t%1, %2, %0"
6047   [(set_attr "type" "*,fga")
6048    (set_attr "fptype" "*,single")])
6050 (define_expand "ior<V64I:mode>3"
6051   [(set (match_operand:V64I 0 "register_operand" "")
6052         (ior:V64I (match_operand:V64I 1 "arith_double_operand" "")
6053                   (match_operand:V64I 2 "arith_double_operand" "")))]
6054   ""
6055   "")
6057 (define_insn "*ior<V64I:mode>3_sp32"
6058   [(set (match_operand:V64I 0 "register_operand" "=r,b")
6059         (ior:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
6060                   (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
6061   "! TARGET_ARCH64"
6062   "@
6063   #
6064   for\t%1, %2, %0"
6065   [(set_attr "type" "*,fga")
6066    (set_attr "length" "2,*")
6067    (set_attr "fptype" "*,double")])
6069 (define_insn "*ior<V64I:mode>3_sp64"
6070   [(set (match_operand:V64I 0 "register_operand" "=r,b")
6071         (ior:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
6072                   (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
6073   "TARGET_ARCH64"
6074   "@
6075   or\t%1, %2, %0
6076   for\t%1, %2, %0"
6077   [(set_attr "type" "*,fga")
6078    (set_attr "fptype" "*,double")])
6080 (define_insn "ior<V32I:mode>3"
6081   [(set (match_operand:V32I 0 "register_operand" "=r,d")
6082         (ior:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
6083                   (match_operand:V32I 2 "arith_operand" "rI,d")))]
6084   ""
6085   "@
6086    or\t%1, %2, %0
6087    fors\t%1, %2, %0"
6088   [(set_attr "type" "*,fga")
6089    (set_attr "fptype" "*,single")])
6091 (define_split
6092   [(set (match_operand:SI 0 "register_operand" "")
6093         (ior:SI (match_operand:SI 1 "register_operand" "")
6094                 (match_operand:SI 2 "" "")))
6095    (clobber (match_operand:SI 3 "register_operand" ""))]
6096   "GET_CODE (operands[2]) == CONST_INT
6097    && !SMALL_INT32 (operands[2])
6098    && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6099   [(set (match_dup 3) (match_dup 4))
6100    (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
6102   operands[4] = GEN_INT (~INTVAL (operands[2]));
6105 (define_insn_and_split "*or_not_<V64I:mode>_sp32"
6106   [(set (match_operand:V64I 0 "register_operand" "=r,b")
6107         (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
6108                   (match_operand:V64I 2 "register_operand" "r,b")))]
6109   "! TARGET_ARCH64"
6110   "@
6111    #
6112    fornot1\t%1, %2, %0"
6113   "&& reload_completed
6114    && ((GET_CODE (operands[0]) == REG
6115         && REGNO (operands[0]) < 32)
6116        || (GET_CODE (operands[0]) == SUBREG
6117            && GET_CODE (SUBREG_REG (operands[0])) == REG
6118            && REGNO (SUBREG_REG (operands[0])) < 32))"
6119   [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
6120    (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
6121   "operands[3] = gen_highpart (SImode, operands[0]);
6122    operands[4] = gen_highpart (SImode, operands[1]);
6123    operands[5] = gen_highpart (SImode, operands[2]);
6124    operands[6] = gen_lowpart (SImode, operands[0]);
6125    operands[7] = gen_lowpart (SImode, operands[1]);
6126    operands[8] = gen_lowpart (SImode, operands[2]);"
6127   [(set_attr "type" "*,fga")
6128    (set_attr "length" "2,*")
6129    (set_attr "fptype" "*,double")])
6131 (define_insn "*or_not_<V64I:mode>_sp64"
6132   [(set (match_operand:V64I 0 "register_operand" "=r,b")
6133         (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
6134                   (match_operand:V64I 2 "register_operand" "r,b")))]
6135   "TARGET_ARCH64"
6136   "@
6137   orn\t%2, %1, %0
6138   fornot1\t%1, %2, %0"
6139   [(set_attr "type" "*,fga")
6140    (set_attr "fptype" "*,double")])
6142 (define_insn "*or_not_<V32I:mode>"
6143   [(set (match_operand:V32I 0 "register_operand" "=r,d")
6144         (ior:V32I (not:V32I (match_operand:V32I 1 "register_operand" "r,d"))
6145                   (match_operand:V32I 2 "register_operand" "r,d")))]
6146   ""
6147   "@
6148    orn\t%2, %1, %0
6149    fornot1s\t%1, %2, %0"
6150   [(set_attr "type" "*,fga")
6151    (set_attr "fptype" "*,single")])
6153 (define_expand "xor<V64I:mode>3"
6154   [(set (match_operand:V64I 0 "register_operand" "")
6155         (xor:V64I (match_operand:V64I 1 "arith_double_operand" "")
6156                   (match_operand:V64I 2 "arith_double_operand" "")))]
6157   ""
6158   "")
6160 (define_insn "*xor<V64I:mode>3_sp32"
6161   [(set (match_operand:V64I 0 "register_operand" "=r,b")
6162         (xor:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
6163                   (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
6164   "! TARGET_ARCH64"
6165   "@
6166   #
6167   fxor\t%1, %2, %0"
6168   [(set_attr "type" "*,fga")
6169    (set_attr "length" "2,*")
6170    (set_attr "fptype" "*,double")])
6172 (define_insn "*xor<V64I:mode>3_sp64"
6173   [(set (match_operand:V64I 0 "register_operand" "=r,b")
6174         (xor:V64I (match_operand:V64I 1 "arith_double_operand" "%rJ,b")
6175                   (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
6176   "TARGET_ARCH64"
6177   "@
6178   xor\t%r1, %2, %0
6179   fxor\t%1, %2, %0"
6180   [(set_attr "type" "*,fga")
6181    (set_attr "fptype" "*,double")])
6183 (define_insn "*xordi3_sp64_dbl"
6184   [(set (match_operand:DI 0 "register_operand" "=r")
6185         (xor:DI (match_operand:DI 1 "register_operand" "r")
6186                 (match_operand:DI 2 "const64_operand" "")))]
6187   "(TARGET_ARCH64
6188     && HOST_BITS_PER_WIDE_INT != 64)"
6189   "xor\t%1, %2, %0")
6191 (define_insn "xor<V32I:mode>3"
6192   [(set (match_operand:V32I 0 "register_operand" "=r,d")
6193         (xor:V32I (match_operand:V32I 1 "arith_operand" "%rJ,d")
6194                   (match_operand:V32I 2 "arith_operand" "rI,d")))]
6195   ""
6196   "@
6197    xor\t%r1, %2, %0
6198    fxors\t%1, %2, %0"
6199   [(set_attr "type" "*,fga")
6200    (set_attr "fptype" "*,single")])
6202 (define_split
6203   [(set (match_operand:SI 0 "register_operand" "")
6204         (xor:SI (match_operand:SI 1 "register_operand" "")
6205                 (match_operand:SI 2 "" "")))
6206    (clobber (match_operand:SI 3 "register_operand" ""))]
6207   "GET_CODE (operands[2]) == CONST_INT
6208    && !SMALL_INT32 (operands[2])
6209    && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6210   [(set (match_dup 3) (match_dup 4))
6211    (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
6213   operands[4] = GEN_INT (~INTVAL (operands[2]));
6216 (define_split
6217   [(set (match_operand:SI 0 "register_operand" "")
6218         (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
6219                         (match_operand:SI 2 "" ""))))
6220    (clobber (match_operand:SI 3 "register_operand" ""))]
6221   "GET_CODE (operands[2]) == CONST_INT
6222    && !SMALL_INT32 (operands[2])
6223    && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6224   [(set (match_dup 3) (match_dup 4))
6225    (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
6227   operands[4] = GEN_INT (~INTVAL (operands[2]));
6230 ;; Split DImode logical operations requiring two instructions.
6231 (define_split
6232   [(set (match_operand:V64I 0 "register_operand" "")
6233         (match_operator:V64I 1 "cc_arithop"     ; AND, IOR, XOR
6234                            [(match_operand:V64I 2 "register_operand" "")
6235                             (match_operand:V64I 3 "arith_double_operand" "")]))]
6236   "! TARGET_ARCH64
6237    && reload_completed
6238    && ((GET_CODE (operands[0]) == REG
6239         && REGNO (operands[0]) < 32)
6240        || (GET_CODE (operands[0]) == SUBREG
6241            && GET_CODE (SUBREG_REG (operands[0])) == REG
6242            && REGNO (SUBREG_REG (operands[0])) < 32))"
6243   [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
6244    (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
6246   operands[4] = gen_highpart (SImode, operands[0]);
6247   operands[5] = gen_lowpart (SImode, operands[0]);
6248   operands[6] = gen_highpart (SImode, operands[2]);
6249   operands[7] = gen_lowpart (SImode, operands[2]);
6250 #if HOST_BITS_PER_WIDE_INT == 32
6251   if (GET_CODE (operands[3]) == CONST_INT && <V64I:MODE>mode == DImode)
6252     {
6253       if (INTVAL (operands[3]) < 0)
6254         operands[8] = constm1_rtx;
6255       else
6256         operands[8] = const0_rtx;
6257     }
6258   else
6259 #endif
6260     operands[8] = gen_highpart_mode (SImode, <V64I:MODE>mode, operands[3]);
6261   operands[9] = gen_lowpart (SImode, operands[3]);
6264 ;; xnor patterns.  Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
6265 ;; Combine now canonicalizes to the rightmost expression.
6266 (define_insn_and_split "*xor_not_<V64I:mode>_sp32"
6267   [(set (match_operand:V64I 0 "register_operand" "=r,b")
6268         (not:V64I (xor:V64I (match_operand:V64I 1 "register_operand" "r,b")
6269                             (match_operand:V64I 2 "register_operand" "r,b"))))]
6270   "! TARGET_ARCH64"
6271   "@
6272    #
6273    fxnor\t%1, %2, %0"
6274   "&& reload_completed
6275    && ((GET_CODE (operands[0]) == REG
6276         && REGNO (operands[0]) < 32)
6277        || (GET_CODE (operands[0]) == SUBREG
6278            && GET_CODE (SUBREG_REG (operands[0])) == REG
6279            && REGNO (SUBREG_REG (operands[0])) < 32))"
6280   [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
6281    (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
6282   "operands[3] = gen_highpart (SImode, operands[0]);
6283    operands[4] = gen_highpart (SImode, operands[1]);
6284    operands[5] = gen_highpart (SImode, operands[2]);
6285    operands[6] = gen_lowpart (SImode, operands[0]);
6286    operands[7] = gen_lowpart (SImode, operands[1]);
6287    operands[8] = gen_lowpart (SImode, operands[2]);"
6288   [(set_attr "type" "*,fga")
6289    (set_attr "length" "2,*")
6290    (set_attr "fptype" "*,double")])
6292 (define_insn "*xor_not_<V64I:mode>_sp64"
6293   [(set (match_operand:V64I 0 "register_operand" "=r,b")
6294         (not:V64I (xor:V64I (match_operand:V64I 1 "reg_or_0_operand" "rJ,b")
6295                             (match_operand:V64I 2 "arith_double_operand" "rHI,b"))))]
6296   "TARGET_ARCH64"
6297   "@
6298   xnor\t%r1, %2, %0
6299   fxnor\t%1, %2, %0"
6300   [(set_attr "type" "*,fga")
6301    (set_attr "fptype" "*,double")])
6303 (define_insn "*xor_not_<V32I:mode>"
6304   [(set (match_operand:V32I 0 "register_operand" "=r,d")
6305         (not:V32I (xor:V32I (match_operand:V32I 1 "reg_or_0_operand" "rJ,d")
6306                             (match_operand:V32I 2 "arith_operand" "rI,d"))))]
6307   ""
6308   "@
6309    xnor\t%r1, %2, %0
6310    fxnors\t%1, %2, %0"
6311   [(set_attr "type" "*,fga")
6312    (set_attr "fptype" "*,single")])
6314 ;; These correspond to the above in the case where we also (or only)
6315 ;; want to set the condition code.  
6317 (define_insn "*cmp_cc_arith_op"
6318   [(set (reg:CC 100)
6319         (compare:CC
6320          (match_operator:SI 2 "cc_arithop"
6321                             [(match_operand:SI 0 "arith_operand" "%r")
6322                              (match_operand:SI 1 "arith_operand" "rI")])
6323          (const_int 0)))]
6324   ""
6325   "%A2cc\t%0, %1, %%g0"
6326   [(set_attr "type" "compare")])
6328 (define_insn "*cmp_ccx_arith_op"
6329   [(set (reg:CCX 100)
6330         (compare:CCX
6331          (match_operator:DI 2 "cc_arithop"
6332                             [(match_operand:DI 0 "arith_double_operand" "%r")
6333                              (match_operand:DI 1 "arith_double_operand" "rHI")])
6334          (const_int 0)))]
6335   "TARGET_ARCH64"
6336   "%A2cc\t%0, %1, %%g0"
6337   [(set_attr "type" "compare")])
6339 (define_insn "*cmp_cc_arith_op_set"
6340   [(set (reg:CC 100)
6341         (compare:CC
6342          (match_operator:SI 3 "cc_arithop"
6343                             [(match_operand:SI 1 "arith_operand" "%r")
6344                              (match_operand:SI 2 "arith_operand" "rI")])
6345          (const_int 0)))
6346    (set (match_operand:SI 0 "register_operand" "=r")
6347         (match_operator:SI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6348   "GET_CODE (operands[3]) == GET_CODE (operands[4])"
6349   "%A3cc\t%1, %2, %0"
6350   [(set_attr "type" "compare")])
6352 (define_insn "*cmp_ccx_arith_op_set"
6353   [(set (reg:CCX 100)
6354         (compare:CCX
6355          (match_operator:DI 3 "cc_arithop"
6356                             [(match_operand:DI 1 "arith_double_operand" "%r")
6357                              (match_operand:DI 2 "arith_double_operand" "rHI")])
6358          (const_int 0)))
6359    (set (match_operand:DI 0 "register_operand" "=r")
6360         (match_operator:DI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6361   "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
6362   "%A3cc\t%1, %2, %0"
6363   [(set_attr "type" "compare")])
6365 (define_insn "*cmp_cc_xor_not"
6366   [(set (reg:CC 100)
6367         (compare:CC
6368          (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
6369                          (match_operand:SI 1 "arith_operand" "rI")))
6370          (const_int 0)))]
6371   ""
6372   "xnorcc\t%r0, %1, %%g0"
6373   [(set_attr "type" "compare")])
6375 (define_insn "*cmp_ccx_xor_not"
6376   [(set (reg:CCX 100)
6377         (compare:CCX
6378          (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ")
6379                          (match_operand:DI 1 "arith_double_operand" "rHI")))
6380          (const_int 0)))]
6381   "TARGET_ARCH64"
6382   "xnorcc\t%r0, %1, %%g0"
6383   [(set_attr "type" "compare")])
6385 (define_insn "*cmp_cc_xor_not_set"
6386   [(set (reg:CC 100)
6387         (compare:CC
6388          (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
6389                          (match_operand:SI 2 "arith_operand" "rI")))
6390          (const_int 0)))
6391    (set (match_operand:SI 0 "register_operand" "=r")
6392         (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
6393   ""
6394   "xnorcc\t%r1, %2, %0"
6395   [(set_attr "type" "compare")])
6397 (define_insn "*cmp_ccx_xor_not_set"
6398   [(set (reg:CCX 100)
6399         (compare:CCX
6400          (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
6401                          (match_operand:DI 2 "arith_double_operand" "rHI")))
6402          (const_int 0)))
6403    (set (match_operand:DI 0 "register_operand" "=r")
6404         (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
6405   "TARGET_ARCH64"
6406   "xnorcc\t%r1, %2, %0"
6407   [(set_attr "type" "compare")])
6409 (define_insn "*cmp_cc_arith_op_not"
6410   [(set (reg:CC 100)
6411         (compare:CC
6412          (match_operator:SI 2 "cc_arithopn"
6413                             [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
6414                              (match_operand:SI 1 "reg_or_0_operand" "rJ")])
6415          (const_int 0)))]
6416   ""
6417   "%B2cc\t%r1, %0, %%g0"
6418   [(set_attr "type" "compare")])
6420 (define_insn "*cmp_ccx_arith_op_not"
6421   [(set (reg:CCX 100)
6422         (compare:CCX
6423          (match_operator:DI 2 "cc_arithopn"
6424                             [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6425                              (match_operand:DI 1 "reg_or_0_operand" "rJ")])
6426          (const_int 0)))]
6427   "TARGET_ARCH64"
6428   "%B2cc\t%r1, %0, %%g0"
6429   [(set_attr "type" "compare")])
6431 (define_insn "*cmp_cc_arith_op_not_set"
6432   [(set (reg:CC 100)
6433         (compare:CC
6434          (match_operator:SI 3 "cc_arithopn"
6435                             [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
6436                              (match_operand:SI 2 "reg_or_0_operand" "rJ")])
6437          (const_int 0)))
6438    (set (match_operand:SI 0 "register_operand" "=r")
6439         (match_operator:SI 4 "cc_arithopn"
6440                             [(not:SI (match_dup 1)) (match_dup 2)]))]
6441   "GET_CODE (operands[3]) == GET_CODE (operands[4])"
6442   "%B3cc\t%r2, %1, %0"
6443   [(set_attr "type" "compare")])
6445 (define_insn "*cmp_ccx_arith_op_not_set"
6446   [(set (reg:CCX 100)
6447         (compare:CCX
6448          (match_operator:DI 3 "cc_arithopn"
6449                             [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6450                              (match_operand:DI 2 "reg_or_0_operand" "rJ")])
6451          (const_int 0)))
6452    (set (match_operand:DI 0 "register_operand" "=r")
6453         (match_operator:DI 4 "cc_arithopn"
6454                             [(not:DI (match_dup 1)) (match_dup 2)]))]
6455   "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
6456   "%B3cc\t%r2, %1, %0"
6457   [(set_attr "type" "compare")])
6459 ;; We cannot use the "neg" pseudo insn because the Sun assembler
6460 ;; does not know how to make it work for constants.
6462 (define_expand "negdi2"
6463   [(set (match_operand:DI 0 "register_operand" "=r")
6464         (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6465   ""
6467   if (! TARGET_ARCH64)
6468     {
6469       emit_insn (gen_rtx_PARALLEL
6470                  (VOIDmode,
6471                   gen_rtvec (2,
6472                              gen_rtx_SET (VOIDmode, operand0,
6473                                           gen_rtx_NEG (DImode, operand1)),
6474                              gen_rtx_CLOBBER (VOIDmode,
6475                                               gen_rtx_REG (CCmode,
6476                                                            SPARC_ICC_REG)))));
6477       DONE;
6478     }
6481 (define_insn_and_split "*negdi2_sp32"
6482   [(set (match_operand:DI 0 "register_operand" "=r")
6483         (neg:DI (match_operand:DI 1 "register_operand" "r")))
6484    (clobber (reg:CC 100))]
6485   "TARGET_ARCH32"
6486   "#"
6487   "&& reload_completed"
6488   [(parallel [(set (reg:CC_NOOV 100)
6489                    (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
6490                                     (const_int 0)))
6491               (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
6492    (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
6493                                 (ltu:SI (reg:CC 100) (const_int 0))))]
6494   "operands[2] = gen_highpart (SImode, operands[0]);
6495    operands[3] = gen_highpart (SImode, operands[1]);
6496    operands[4] = gen_lowpart (SImode, operands[0]);
6497    operands[5] = gen_lowpart (SImode, operands[1]);"
6498   [(set_attr "length" "2")])
6500 (define_insn "*negdi2_sp64"
6501   [(set (match_operand:DI 0 "register_operand" "=r")
6502         (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6503   "TARGET_ARCH64"
6504   "sub\t%%g0, %1, %0")
6506 (define_insn "negsi2"
6507   [(set (match_operand:SI 0 "register_operand" "=r")
6508         (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
6509   ""
6510   "sub\t%%g0, %1, %0")
6512 (define_insn "*cmp_cc_neg"
6513   [(set (reg:CC_NOOV 100)
6514         (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
6515                          (const_int 0)))]
6516   ""
6517   "subcc\t%%g0, %0, %%g0"
6518   [(set_attr "type" "compare")])
6520 (define_insn "*cmp_ccx_neg"
6521   [(set (reg:CCX_NOOV 100)
6522         (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6523                           (const_int 0)))]
6524   "TARGET_ARCH64"
6525   "subcc\t%%g0, %0, %%g0"
6526   [(set_attr "type" "compare")])
6528 (define_insn "*cmp_cc_set_neg"
6529   [(set (reg:CC_NOOV 100)
6530         (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
6531                          (const_int 0)))
6532    (set (match_operand:SI 0 "register_operand" "=r")
6533         (neg:SI (match_dup 1)))]
6534   ""
6535   "subcc\t%%g0, %1, %0"
6536   [(set_attr "type" "compare")])
6538 (define_insn "*cmp_ccx_set_neg"
6539   [(set (reg:CCX_NOOV 100)
6540         (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6541                           (const_int 0)))
6542    (set (match_operand:DI 0 "register_operand" "=r")
6543         (neg:DI (match_dup 1)))]
6544   "TARGET_ARCH64"
6545   "subcc\t%%g0, %1, %0"
6546   [(set_attr "type" "compare")])
6548 ;; We cannot use the "not" pseudo insn because the Sun assembler
6549 ;; does not know how to make it work for constants.
6550 (define_expand "one_cmpl<V64I:mode>2"
6551   [(set (match_operand:V64I 0 "register_operand" "")
6552         (not:V64I (match_operand:V64I 1 "register_operand" "")))]
6553   ""
6554   "")
6556 (define_insn_and_split "*one_cmpl<V64I:mode>2_sp32"
6557   [(set (match_operand:V64I 0 "register_operand" "=r,b")
6558         (not:V64I (match_operand:V64I 1 "register_operand" "r,b")))]
6559   "! TARGET_ARCH64"
6560   "@
6561    #
6562    fnot1\t%1, %0"
6563   "&& reload_completed
6564    && ((GET_CODE (operands[0]) == REG
6565         && REGNO (operands[0]) < 32)
6566        || (GET_CODE (operands[0]) == SUBREG
6567            && GET_CODE (SUBREG_REG (operands[0])) == REG
6568            && REGNO (SUBREG_REG (operands[0])) < 32))"
6569   [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
6570    (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
6571   "operands[2] = gen_highpart (SImode, operands[0]);
6572    operands[3] = gen_highpart (SImode, operands[1]);
6573    operands[4] = gen_lowpart (SImode, operands[0]);
6574    operands[5] = gen_lowpart (SImode, operands[1]);"
6575   [(set_attr "type" "*,fga")
6576    (set_attr "length" "2,*")
6577    (set_attr "fptype" "*,double")])
6579 (define_insn "*one_cmpl<V64I:mode>2_sp64"
6580   [(set (match_operand:V64I 0 "register_operand" "=r,b")
6581         (not:V64I (match_operand:V64I 1 "arith_double_operand" "rHI,b")))]
6582   "TARGET_ARCH64"
6583   "@
6584    xnor\t%%g0, %1, %0
6585    fnot1\t%1, %0"
6586   [(set_attr "type" "*,fga")
6587    (set_attr "fptype" "*,double")])
6589 (define_insn "one_cmpl<V32I:mode>2"
6590   [(set (match_operand:V32I 0 "register_operand" "=r,d")
6591         (not:V32I (match_operand:V32I 1 "arith_operand" "rI,d")))]
6592   ""
6593   "@
6594   xnor\t%%g0, %1, %0
6595   fnot1s\t%1, %0"
6596   [(set_attr "type" "*,fga")
6597    (set_attr "fptype" "*,single")])
6599 (define_insn "*cmp_cc_not"
6600   [(set (reg:CC 100)
6601         (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
6602                     (const_int 0)))]
6603   ""
6604   "xnorcc\t%%g0, %0, %%g0"
6605   [(set_attr "type" "compare")])
6607 (define_insn "*cmp_ccx_not"
6608   [(set (reg:CCX 100)
6609         (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6610                      (const_int 0)))]
6611   "TARGET_ARCH64"
6612   "xnorcc\t%%g0, %0, %%g0"
6613   [(set_attr "type" "compare")])
6615 (define_insn "*cmp_cc_set_not"
6616   [(set (reg:CC 100)
6617         (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
6618                     (const_int 0)))
6619    (set (match_operand:SI 0 "register_operand" "=r")
6620         (not:SI (match_dup 1)))]
6621   ""
6622   "xnorcc\t%%g0, %1, %0"
6623   [(set_attr "type" "compare")])
6625 (define_insn "*cmp_ccx_set_not"
6626   [(set (reg:CCX 100)
6627         (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6628                     (const_int 0)))
6629    (set (match_operand:DI 0 "register_operand" "=r")
6630         (not:DI (match_dup 1)))]
6631   "TARGET_ARCH64"
6632   "xnorcc\t%%g0, %1, %0"
6633   [(set_attr "type" "compare")])
6635 (define_insn "*cmp_cc_set"
6636   [(set (match_operand:SI 0 "register_operand" "=r")
6637         (match_operand:SI 1 "register_operand" "r"))
6638    (set (reg:CC 100)
6639         (compare:CC (match_dup 1)
6640                     (const_int 0)))]
6641   ""
6642   "orcc\t%1, 0, %0"
6643   [(set_attr "type" "compare")])
6645 (define_insn "*cmp_ccx_set64"
6646   [(set (match_operand:DI 0 "register_operand" "=r")
6647         (match_operand:DI 1 "register_operand" "r"))
6648    (set (reg:CCX 100)
6649         (compare:CCX (match_dup 1)
6650                      (const_int 0)))]
6651   "TARGET_ARCH64"
6652   "orcc\t%1, 0, %0"
6653    [(set_attr "type" "compare")])
6655 ;; Floating point arithmetic instructions.
6657 (define_expand "addtf3"
6658   [(set (match_operand:TF 0 "nonimmediate_operand" "")
6659         (plus:TF (match_operand:TF 1 "general_operand" "")
6660                  (match_operand:TF 2 "general_operand" "")))]
6661   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6662   "emit_tfmode_binop (PLUS, operands); DONE;")
6664 (define_insn "*addtf3_hq"
6665   [(set (match_operand:TF 0 "register_operand" "=e")
6666         (plus:TF (match_operand:TF 1 "register_operand" "e")
6667                  (match_operand:TF 2 "register_operand" "e")))]
6668   "TARGET_FPU && TARGET_HARD_QUAD"
6669   "faddq\t%1, %2, %0"
6670   [(set_attr "type" "fp")])
6672 (define_insn "adddf3"
6673   [(set (match_operand:DF 0 "register_operand" "=e")
6674         (plus:DF (match_operand:DF 1 "register_operand" "e")
6675                  (match_operand:DF 2 "register_operand" "e")))]
6676   "TARGET_FPU"
6677   "faddd\t%1, %2, %0"
6678   [(set_attr "type" "fp")
6679    (set_attr "fptype" "double")])
6681 (define_insn "addsf3"
6682   [(set (match_operand:SF 0 "register_operand" "=f")
6683         (plus:SF (match_operand:SF 1 "register_operand" "f")
6684                  (match_operand:SF 2 "register_operand" "f")))]
6685   "TARGET_FPU"
6686   "fadds\t%1, %2, %0"
6687   [(set_attr "type" "fp")])
6689 (define_expand "subtf3"
6690   [(set (match_operand:TF 0 "nonimmediate_operand" "")
6691         (minus:TF (match_operand:TF 1 "general_operand" "")
6692                   (match_operand:TF 2 "general_operand" "")))]
6693   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6694   "emit_tfmode_binop (MINUS, operands); DONE;")
6696 (define_insn "*subtf3_hq"
6697   [(set (match_operand:TF 0 "register_operand" "=e")
6698         (minus:TF (match_operand:TF 1 "register_operand" "e")
6699                   (match_operand:TF 2 "register_operand" "e")))]
6700   "TARGET_FPU && TARGET_HARD_QUAD"
6701   "fsubq\t%1, %2, %0"
6702   [(set_attr "type" "fp")])
6704 (define_insn "subdf3"
6705   [(set (match_operand:DF 0 "register_operand" "=e")
6706         (minus:DF (match_operand:DF 1 "register_operand" "e")
6707                   (match_operand:DF 2 "register_operand" "e")))]
6708   "TARGET_FPU"
6709   "fsubd\t%1, %2, %0"
6710   [(set_attr "type" "fp")
6711    (set_attr "fptype" "double")])
6713 (define_insn "subsf3"
6714   [(set (match_operand:SF 0 "register_operand" "=f")
6715         (minus:SF (match_operand:SF 1 "register_operand" "f")
6716                   (match_operand:SF 2 "register_operand" "f")))]
6717   "TARGET_FPU"
6718   "fsubs\t%1, %2, %0"
6719   [(set_attr "type" "fp")])
6721 (define_expand "multf3"
6722   [(set (match_operand:TF 0 "nonimmediate_operand" "")
6723         (mult:TF (match_operand:TF 1 "general_operand" "")
6724                  (match_operand:TF 2 "general_operand" "")))]
6725   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6726   "emit_tfmode_binop (MULT, operands); DONE;")
6728 (define_insn "*multf3_hq"
6729   [(set (match_operand:TF 0 "register_operand" "=e")
6730         (mult:TF (match_operand:TF 1 "register_operand" "e")
6731                  (match_operand:TF 2 "register_operand" "e")))]
6732   "TARGET_FPU && TARGET_HARD_QUAD"
6733   "fmulq\t%1, %2, %0"
6734   [(set_attr "type" "fpmul")])
6736 (define_insn "muldf3"
6737   [(set (match_operand:DF 0 "register_operand" "=e")
6738         (mult:DF (match_operand:DF 1 "register_operand" "e")
6739                  (match_operand:DF 2 "register_operand" "e")))]
6740   "TARGET_FPU"
6741   "fmuld\t%1, %2, %0"
6742   [(set_attr "type" "fpmul")
6743    (set_attr "fptype" "double")])
6745 (define_insn "mulsf3"
6746   [(set (match_operand:SF 0 "register_operand" "=f")
6747         (mult:SF (match_operand:SF 1 "register_operand" "f")
6748                  (match_operand:SF 2 "register_operand" "f")))]
6749   "TARGET_FPU"
6750   "fmuls\t%1, %2, %0"
6751   [(set_attr "type" "fpmul")])
6753 (define_insn "*muldf3_extend"
6754   [(set (match_operand:DF 0 "register_operand" "=e")
6755         (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
6756                  (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
6757   "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
6758   "fsmuld\t%1, %2, %0"
6759   [(set_attr "type" "fpmul")
6760    (set_attr "fptype" "double")])
6762 (define_insn "*multf3_extend"
6763   [(set (match_operand:TF 0 "register_operand" "=e")
6764         (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
6765                  (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
6766   "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
6767   "fdmulq\t%1, %2, %0"
6768   [(set_attr "type" "fpmul")])
6770 (define_expand "divtf3"
6771   [(set (match_operand:TF 0 "nonimmediate_operand" "")
6772         (div:TF (match_operand:TF 1 "general_operand" "")
6773                 (match_operand:TF 2 "general_operand" "")))]
6774   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6775   "emit_tfmode_binop (DIV, operands); DONE;")
6777 ;; don't have timing for quad-prec. divide.
6778 (define_insn "*divtf3_hq"
6779   [(set (match_operand:TF 0 "register_operand" "=e")
6780         (div:TF (match_operand:TF 1 "register_operand" "e")
6781                 (match_operand:TF 2 "register_operand" "e")))]
6782   "TARGET_FPU && TARGET_HARD_QUAD"
6783   "fdivq\t%1, %2, %0"
6784   [(set_attr "type" "fpdivd")])
6786 (define_insn "divdf3"
6787   [(set (match_operand:DF 0 "register_operand" "=e")
6788         (div:DF (match_operand:DF 1 "register_operand" "e")
6789                 (match_operand:DF 2 "register_operand" "e")))]
6790   "TARGET_FPU"
6791   "fdivd\t%1, %2, %0"
6792   [(set_attr "type" "fpdivd")
6793    (set_attr "fptype" "double")])
6795 (define_insn "divsf3"
6796   [(set (match_operand:SF 0 "register_operand" "=f")
6797         (div:SF (match_operand:SF 1 "register_operand" "f")
6798                 (match_operand:SF 2 "register_operand" "f")))]
6799   "TARGET_FPU"
6800   "fdivs\t%1, %2, %0"
6801   [(set_attr "type" "fpdivs")])
6803 (define_expand "negtf2"
6804   [(set (match_operand:TF 0 "register_operand" "=e,e")
6805         (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6806   "TARGET_FPU"
6807   "")
6809 (define_insn_and_split "*negtf2_notv9"
6810   [(set (match_operand:TF 0 "register_operand" "=e,e")
6811         (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6812   ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6813   "TARGET_FPU
6814    && ! TARGET_V9"
6815   "@
6816   fnegs\t%0, %0
6817   #"
6818   "&& reload_completed
6819    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6820   [(set (match_dup 2) (neg:SF (match_dup 3)))
6821    (set (match_dup 4) (match_dup 5))
6822    (set (match_dup 6) (match_dup 7))]
6823   "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6824    operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6825    operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6826    operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6827    operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6828    operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6829   [(set_attr "type" "fpmove,*")
6830    (set_attr "length" "*,2")])
6832 (define_insn_and_split "*negtf2_v9"
6833   [(set (match_operand:TF 0 "register_operand" "=e,e")
6834         (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6835   ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6836   "TARGET_FPU && TARGET_V9"
6837   "@
6838   fnegd\t%0, %0
6839   #"
6840   "&& reload_completed
6841    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6842   [(set (match_dup 2) (neg:DF (match_dup 3)))
6843    (set (match_dup 4) (match_dup 5))]
6844   "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6845    operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6846    operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6847    operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6848   [(set_attr "type" "fpmove,*")
6849    (set_attr "length" "*,2")
6850    (set_attr "fptype" "double")])
6852 (define_expand "negdf2"
6853   [(set (match_operand:DF 0 "register_operand" "")
6854         (neg:DF (match_operand:DF 1 "register_operand" "")))]
6855   "TARGET_FPU"
6856   "")
6858 (define_insn_and_split "*negdf2_notv9"
6859   [(set (match_operand:DF 0 "register_operand" "=e,e")
6860         (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
6861   "TARGET_FPU && ! TARGET_V9"
6862   "@
6863   fnegs\t%0, %0
6864   #"
6865   "&& reload_completed
6866    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6867   [(set (match_dup 2) (neg:SF (match_dup 3)))
6868    (set (match_dup 4) (match_dup 5))]
6869   "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6870    operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6871    operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6872    operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6873   [(set_attr "type" "fpmove,*")
6874    (set_attr "length" "*,2")])
6876 (define_insn "*negdf2_v9"
6877   [(set (match_operand:DF 0 "register_operand" "=e")
6878         (neg:DF (match_operand:DF 1 "register_operand" "e")))]
6879   "TARGET_FPU && TARGET_V9"
6880   "fnegd\t%1, %0"
6881   [(set_attr "type" "fpmove")
6882    (set_attr "fptype" "double")])
6884 (define_insn "negsf2"
6885   [(set (match_operand:SF 0 "register_operand" "=f")
6886         (neg:SF (match_operand:SF 1 "register_operand" "f")))]
6887   "TARGET_FPU"
6888   "fnegs\t%1, %0"
6889   [(set_attr "type" "fpmove")])
6891 (define_expand "abstf2"
6892   [(set (match_operand:TF 0 "register_operand" "")
6893         (abs:TF (match_operand:TF 1 "register_operand" "")))]
6894   "TARGET_FPU"
6895   "")
6897 (define_insn_and_split "*abstf2_notv9"
6898   [(set (match_operand:TF 0 "register_operand" "=e,e")
6899         (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6900   ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6901   "TARGET_FPU && ! TARGET_V9"
6902   "@
6903   fabss\t%0, %0
6904   #"
6905   "&& reload_completed
6906    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6907   [(set (match_dup 2) (abs:SF (match_dup 3)))
6908    (set (match_dup 4) (match_dup 5))
6909    (set (match_dup 6) (match_dup 7))]
6910   "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6911    operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6912    operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6913    operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6914    operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6915    operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6916   [(set_attr "type" "fpmove,*")
6917    (set_attr "length" "*,2")])
6919 (define_insn "*abstf2_hq_v9"
6920   [(set (match_operand:TF 0 "register_operand" "=e,e")
6921         (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6922   "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
6923   "@
6924   fabsd\t%0, %0
6925   fabsq\t%1, %0"
6926   [(set_attr "type" "fpmove")
6927    (set_attr "fptype" "double,*")])
6929 (define_insn_and_split "*abstf2_v9"
6930   [(set (match_operand:TF 0 "register_operand" "=e,e")
6931         (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6932   "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
6933   "@
6934   fabsd\t%0, %0
6935   #"
6936   "&& reload_completed
6937    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6938   [(set (match_dup 2) (abs:DF (match_dup 3)))
6939    (set (match_dup 4) (match_dup 5))]
6940   "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6941    operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6942    operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6943    operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6944   [(set_attr "type" "fpmove,*")
6945    (set_attr "length" "*,2")
6946    (set_attr "fptype" "double,*")])
6948 (define_expand "absdf2"
6949   [(set (match_operand:DF 0 "register_operand" "")
6950         (abs:DF (match_operand:DF 1 "register_operand" "")))]
6951   "TARGET_FPU"
6952   "")
6954 (define_insn_and_split "*absdf2_notv9"
6955   [(set (match_operand:DF 0 "register_operand" "=e,e")
6956         (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
6957   "TARGET_FPU && ! TARGET_V9"
6958   "@
6959   fabss\t%0, %0
6960   #"
6961   "&& reload_completed
6962    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6963   [(set (match_dup 2) (abs:SF (match_dup 3)))
6964    (set (match_dup 4) (match_dup 5))]
6965   "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6966    operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6967    operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6968    operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6969   [(set_attr "type" "fpmove,*")
6970    (set_attr "length" "*,2")])
6972 (define_insn "*absdf2_v9"
6973   [(set (match_operand:DF 0 "register_operand" "=e")
6974         (abs:DF (match_operand:DF 1 "register_operand" "e")))]
6975   "TARGET_FPU && TARGET_V9"
6976   "fabsd\t%1, %0"
6977   [(set_attr "type" "fpmove")
6978    (set_attr "fptype" "double")])
6980 (define_insn "abssf2"
6981   [(set (match_operand:SF 0 "register_operand" "=f")
6982         (abs:SF (match_operand:SF 1 "register_operand" "f")))]
6983   "TARGET_FPU"
6984   "fabss\t%1, %0"
6985   [(set_attr "type" "fpmove")])
6987 (define_expand "sqrttf2"
6988   [(set (match_operand:TF 0 "nonimmediate_operand" "")
6989         (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
6990   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6991   "emit_tfmode_unop (SQRT, operands); DONE;")
6993 (define_insn "*sqrttf2_hq"
6994   [(set (match_operand:TF 0 "register_operand" "=e")
6995         (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
6996   "TARGET_FPU && TARGET_HARD_QUAD"
6997   "fsqrtq\t%1, %0"
6998   [(set_attr "type" "fpsqrtd")])
7000 (define_insn "sqrtdf2"
7001   [(set (match_operand:DF 0 "register_operand" "=e")
7002         (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
7003   "TARGET_FPU"
7004   "fsqrtd\t%1, %0"
7005   [(set_attr "type" "fpsqrtd")
7006    (set_attr "fptype" "double")])
7008 (define_insn "sqrtsf2"
7009   [(set (match_operand:SF 0 "register_operand" "=f")
7010         (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
7011   "TARGET_FPU"
7012   "fsqrts\t%1, %0"
7013   [(set_attr "type" "fpsqrts")])
7015 ;;- arithmetic shift instructions
7017 (define_insn "ashlsi3"
7018   [(set (match_operand:SI 0 "register_operand" "=r")
7019         (ashift:SI (match_operand:SI 1 "register_operand" "r")
7020                    (match_operand:SI 2 "arith_operand" "rI")))]
7021   ""
7023   if (GET_CODE (operands[2]) == CONST_INT)
7024     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7025   return "sll\t%1, %2, %0";
7027   [(set (attr "type")
7028         (if_then_else (match_operand 2 "const1_operand" "")
7029                       (const_string "ialu") (const_string "shift")))])
7031 (define_expand "ashldi3"
7032   [(set (match_operand:DI 0 "register_operand" "=r")
7033         (ashift:DI (match_operand:DI 1 "register_operand" "r")
7034                    (match_operand:SI 2 "arith_operand" "rI")))]
7035   "TARGET_ARCH64 || TARGET_V8PLUS"
7037   if (! TARGET_ARCH64)
7038     {
7039       if (GET_CODE (operands[2]) == CONST_INT)
7040         FAIL;
7041       emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
7042       DONE;
7043     }
7046 (define_insn "*ashldi3_sp64"
7047   [(set (match_operand:DI 0 "register_operand" "=r")
7048         (ashift:DI (match_operand:DI 1 "register_operand" "r")
7049                    (match_operand:SI 2 "arith_operand" "rI")))]
7050   "TARGET_ARCH64"
7052   if (GET_CODE (operands[2]) == CONST_INT)
7053     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7054   return "sllx\t%1, %2, %0";
7056   [(set (attr "type")
7057         (if_then_else (match_operand 2 "const1_operand" "")
7058                       (const_string "ialu") (const_string "shift")))])
7060 ;; XXX UGH!
7061 (define_insn "ashldi3_v8plus"
7062   [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7063         (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7064                    (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7065    (clobber (match_scratch:SI 3 "=X,X,&h"))]
7066   "TARGET_V8PLUS"
7067   "* return output_v8plus_shift (operands, insn, \"sllx\");"
7068   [(set_attr "type" "multi")
7069    (set_attr "length" "5,5,6")])
7071 ;; Optimize (1LL<<x)-1
7072 ;; XXX this also needs to be fixed to handle equal subregs
7073 ;; XXX first before we could re-enable it.
7074 ;(define_insn ""
7075 ;  [(set (match_operand:DI 0 "register_operand" "=h")
7076 ;       (plus:DI (ashift:DI (const_int 1)
7077 ;                           (match_operand:SI 1 "arith_operand" "rI"))
7078 ;                (const_int -1)))]
7079 ;  "0 && TARGET_V8PLUS"
7081 ;  if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
7082 ;    return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
7083 ;  return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
7085 ;  [(set_attr "type" "multi")
7086 ;   (set_attr "length" "4")])
7088 (define_insn "*cmp_cc_ashift_1"
7089   [(set (reg:CC_NOOV 100)
7090         (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
7091                                     (const_int 1))
7092                          (const_int 0)))]
7093   ""
7094   "addcc\t%0, %0, %%g0"
7095   [(set_attr "type" "compare")])
7097 (define_insn "*cmp_cc_set_ashift_1"
7098   [(set (reg:CC_NOOV 100)
7099         (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
7100                                     (const_int 1))
7101                          (const_int 0)))
7102    (set (match_operand:SI 0 "register_operand" "=r")
7103         (ashift:SI (match_dup 1) (const_int 1)))]
7104   ""
7105   "addcc\t%1, %1, %0"
7106   [(set_attr "type" "compare")])
7108 (define_insn "ashrsi3"
7109   [(set (match_operand:SI 0 "register_operand" "=r")
7110         (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7111                      (match_operand:SI 2 "arith_operand" "rI")))]
7112   ""
7113   {
7114      if (GET_CODE (operands[2]) == CONST_INT)
7115        operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7116      return "sra\t%1, %2, %0";
7117   }
7118   [(set_attr "type" "shift")])
7120 (define_insn "*ashrsi3_extend"
7121   [(set (match_operand:DI 0 "register_operand" "=r")
7122         (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7123                                      (match_operand:SI 2 "arith_operand" "r"))))]
7124   "TARGET_ARCH64"
7125   "sra\t%1, %2, %0"
7126   [(set_attr "type" "shift")])
7128 ;; This handles the case as above, but with constant shift instead of
7129 ;; register. Combiner "simplifies" it for us a little bit though.
7130 (define_insn "*ashrsi3_extend2"
7131   [(set (match_operand:DI 0 "register_operand" "=r")
7132         (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7133                                 (const_int 32))
7134                      (match_operand:SI 2 "small_int_or_double" "n")))]
7135   "TARGET_ARCH64
7136    && ((GET_CODE (operands[2]) == CONST_INT
7137         && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64)
7138        || (GET_CODE (operands[2]) == CONST_DOUBLE
7139            && !CONST_DOUBLE_HIGH (operands[2])
7140            && CONST_DOUBLE_LOW (operands[2]) >= 32
7141            && CONST_DOUBLE_LOW (operands[2]) < 64))"
7143   operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
7145   return "sra\t%1, %2, %0";
7147   [(set_attr "type" "shift")])
7149 (define_expand "ashrdi3"
7150   [(set (match_operand:DI 0 "register_operand" "=r")
7151         (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7152                      (match_operand:SI 2 "arith_operand" "rI")))]
7153   "TARGET_ARCH64 || TARGET_V8PLUS"
7155   if (! TARGET_ARCH64)
7156     {
7157       if (GET_CODE (operands[2]) == CONST_INT)
7158         FAIL;   /* prefer generic code in this case */
7159       emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
7160       DONE;
7161     }
7164 (define_insn "*ashrdi3_sp64"
7165   [(set (match_operand:DI 0 "register_operand" "=r")
7166         (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7167                      (match_operand:SI 2 "arith_operand" "rI")))]
7168   "TARGET_ARCH64"
7169   
7170   {
7171     if (GET_CODE (operands[2]) == CONST_INT)
7172       operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7173     return "srax\t%1, %2, %0";
7174   }
7175   [(set_attr "type" "shift")])
7177 ;; XXX
7178 (define_insn "ashrdi3_v8plus"
7179   [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7180         (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7181                      (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7182    (clobber (match_scratch:SI 3 "=X,X,&h"))]
7183   "TARGET_V8PLUS"
7184   "* return output_v8plus_shift (operands, insn, \"srax\");"
7185   [(set_attr "type" "multi")
7186    (set_attr "length" "5,5,6")])
7188 (define_insn "lshrsi3"
7189   [(set (match_operand:SI 0 "register_operand" "=r")
7190         (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
7191                      (match_operand:SI 2 "arith_operand" "rI")))]
7192   ""
7193   {
7194     if (GET_CODE (operands[2]) == CONST_INT)
7195       operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7196     return "srl\t%1, %2, %0";
7197   }
7198   [(set_attr "type" "shift")])
7200 ;; This handles the case where
7201 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
7202 ;; but combiner "simplifies" it for us.
7203 (define_insn "*lshrsi3_extend"
7204   [(set (match_operand:DI 0 "register_operand" "=r")
7205         (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
7206                            (match_operand:SI 2 "arith_operand" "r")) 0)
7207                 (match_operand 3 "" "")))]
7208   "TARGET_ARCH64
7209    && ((GET_CODE (operands[3]) == CONST_DOUBLE
7210            && CONST_DOUBLE_HIGH (operands[3]) == 0
7211            && CONST_DOUBLE_LOW (operands[3]) == 0xffffffff)
7212        || (HOST_BITS_PER_WIDE_INT >= 64
7213            && GET_CODE (operands[3]) == CONST_INT
7214            && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff))"
7215   "srl\t%1, %2, %0"
7216   [(set_attr "type" "shift")])
7218 ;; This handles the case where
7219 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
7220 ;; but combiner "simplifies" it for us.
7221 (define_insn "*lshrsi3_extend2"
7222   [(set (match_operand:DI 0 "register_operand" "=r")
7223         (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7224                          (match_operand 2 "small_int_or_double" "n")
7225                          (const_int 32)))]
7226   "TARGET_ARCH64
7227    && ((GET_CODE (operands[2]) == CONST_INT
7228         && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7229        || (GET_CODE (operands[2]) == CONST_DOUBLE
7230            && CONST_DOUBLE_HIGH (operands[2]) == 0
7231            && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7233   operands[2] = GEN_INT (32 - INTVAL (operands[2]));
7235   return "srl\t%1, %2, %0";
7237   [(set_attr "type" "shift")])
7239 (define_expand "lshrdi3"
7240   [(set (match_operand:DI 0 "register_operand" "=r")
7241         (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7242                      (match_operand:SI 2 "arith_operand" "rI")))]
7243   "TARGET_ARCH64 || TARGET_V8PLUS"
7245   if (! TARGET_ARCH64)
7246     {
7247       if (GET_CODE (operands[2]) == CONST_INT)
7248         FAIL;
7249       emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
7250       DONE;
7251     }
7254 (define_insn "*lshrdi3_sp64"
7255   [(set (match_operand:DI 0 "register_operand" "=r")
7256         (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7257                      (match_operand:SI 2 "arith_operand" "rI")))]
7258   "TARGET_ARCH64"
7259   {
7260     if (GET_CODE (operands[2]) == CONST_INT)
7261       operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7262     return "srlx\t%1, %2, %0";
7263   }
7264   [(set_attr "type" "shift")])
7266 ;; XXX
7267 (define_insn "lshrdi3_v8plus"
7268   [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7269         (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7270                      (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7271    (clobber (match_scratch:SI 3 "=X,X,&h"))]
7272   "TARGET_V8PLUS"
7273   "* return output_v8plus_shift (operands, insn, \"srlx\");"
7274   [(set_attr "type" "multi")
7275    (set_attr "length" "5,5,6")])
7277 (define_insn ""
7278   [(set (match_operand:SI 0 "register_operand" "=r")
7279         (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7280                                              (const_int 32)) 4)
7281                      (match_operand:SI 2 "small_int_or_double" "n")))]
7282   "TARGET_ARCH64
7283    && ((GET_CODE (operands[2]) == CONST_INT
7284         && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7285        || (GET_CODE (operands[2]) == CONST_DOUBLE
7286            && !CONST_DOUBLE_HIGH (operands[2])
7287            && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7289   operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
7291   return "srax\t%1, %2, %0";
7293   [(set_attr "type" "shift")])
7295 (define_insn ""
7296   [(set (match_operand:SI 0 "register_operand" "=r")
7297         (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7298                                              (const_int 32)) 4)
7299                      (match_operand:SI 2 "small_int_or_double" "n")))]
7300   "TARGET_ARCH64
7301    && ((GET_CODE (operands[2]) == CONST_INT
7302         && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7303        || (GET_CODE (operands[2]) == CONST_DOUBLE
7304            && !CONST_DOUBLE_HIGH (operands[2])
7305            && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7307   operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
7309   return "srlx\t%1, %2, %0";
7311   [(set_attr "type" "shift")])
7313 (define_insn ""
7314   [(set (match_operand:SI 0 "register_operand" "=r")
7315         (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7316                                              (match_operand:SI 2 "small_int_or_double" "n")) 4)
7317                      (match_operand:SI 3 "small_int_or_double" "n")))]
7318   "TARGET_ARCH64
7319    && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
7320    && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
7321    && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
7322    && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
7324   operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
7326   return "srax\t%1, %2, %0";
7328   [(set_attr "type" "shift")])
7330 (define_insn ""
7331   [(set (match_operand:SI 0 "register_operand" "=r")
7332         (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7333                                              (match_operand:SI 2 "small_int_or_double" "n")) 4)
7334                      (match_operand:SI 3 "small_int_or_double" "n")))]
7335   "TARGET_ARCH64
7336    && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
7337    && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
7338    && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
7339    && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
7341   operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
7343   return "srlx\t%1, %2, %0";
7345   [(set_attr "type" "shift")])
7347 ;; Unconditional and other jump instructions
7348 (define_insn "jump"
7349   [(set (pc) (label_ref (match_operand 0 "" "")))]
7350   ""
7351   "* return output_ubranch (operands[0], 0, insn);"
7352   [(set_attr "type" "uncond_branch")])
7354 (define_expand "tablejump"
7355   [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
7356               (use (label_ref (match_operand 1 "" "")))])]
7357   ""
7359   if (GET_MODE (operands[0]) != CASE_VECTOR_MODE)
7360     abort ();
7362   /* In pic mode, our address differences are against the base of the
7363      table.  Add that base value back in; CSE ought to be able to combine
7364      the two address loads.  */
7365   if (flag_pic)
7366     {
7367       rtx tmp, tmp2;
7368       tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
7369       tmp2 = operands[0];
7370       if (CASE_VECTOR_MODE != Pmode)
7371         tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
7372       tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
7373       operands[0] = memory_address (Pmode, tmp);
7374     }
7377 (define_insn "*tablejump_sp32"
7378   [(set (pc) (match_operand:SI 0 "address_operand" "p"))
7379    (use (label_ref (match_operand 1 "" "")))]
7380   "! TARGET_ARCH64"
7381   "jmp\t%a0%#"
7382   [(set_attr "type" "uncond_branch")])
7384 (define_insn "*tablejump_sp64"
7385   [(set (pc) (match_operand:DI 0 "address_operand" "p"))
7386    (use (label_ref (match_operand 1 "" "")))]
7387   "TARGET_ARCH64"
7388   "jmp\t%a0%#"
7389   [(set_attr "type" "uncond_branch")])
7391 ;;- jump to subroutine
7392 (define_expand "call"
7393   ;; Note that this expression is not used for generating RTL.
7394   ;; All the RTL is generated explicitly below.
7395   [(call (match_operand 0 "call_operand" "")
7396          (match_operand 3 "" "i"))]
7397   ;; operands[2] is next_arg_register
7398   ;; operands[3] is struct_value_size_rtx.
7399   ""
7401   rtx fn_rtx;
7403   if (GET_MODE (operands[0]) != FUNCTION_MODE)
7404     abort ();
7406   if (GET_CODE (operands[3]) != CONST_INT)
7407     abort();
7409   if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
7410     {
7411       /* This is really a PIC sequence.  We want to represent
7412          it as a funny jump so its delay slots can be filled. 
7414          ??? But if this really *is* a CALL, will not it clobber the
7415          call-clobbered registers?  We lose this if it is a JUMP_INSN.
7416          Why cannot we have delay slots filled if it were a CALL?  */
7418       /* We accept negative sizes for untyped calls.  */
7419       if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7420         emit_jump_insn
7421           (gen_rtx_PARALLEL
7422            (VOIDmode,
7423             gen_rtvec (3,
7424                        gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
7425                        operands[3],
7426                        gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7427       else
7428         emit_jump_insn
7429           (gen_rtx_PARALLEL
7430            (VOIDmode,
7431             gen_rtvec (2,
7432                        gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
7433                        gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7434       goto finish_call;
7435     }
7437   fn_rtx = operands[0];
7439   /* We accept negative sizes for untyped calls.  */
7440   if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7441     emit_call_insn
7442       (gen_rtx_PARALLEL
7443        (VOIDmode,
7444         gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
7445                    operands[3],
7446                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7447   else
7448     emit_call_insn
7449       (gen_rtx_PARALLEL
7450        (VOIDmode,
7451         gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
7452                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7454  finish_call:
7456   DONE;
7459 ;; We can't use the same pattern for these two insns, because then registers
7460 ;; in the address may not be properly reloaded.
7462 (define_insn "*call_address_sp32"
7463   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7464          (match_operand 1 "" ""))
7465    (clobber (reg:SI 15))]
7466   ;;- Do not use operand 1 for most machines.
7467   "! TARGET_ARCH64"
7468   "call\t%a0, %1%#"
7469   [(set_attr "type" "call")])
7471 (define_insn "*call_symbolic_sp32"
7472   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7473          (match_operand 1 "" ""))
7474    (clobber (reg:SI 15))]
7475   ;;- Do not use operand 1 for most machines.
7476   "! TARGET_ARCH64"
7477   "call\t%a0, %1%#"
7478   [(set_attr "type" "call")])
7480 (define_insn "*call_address_sp64"
7481   [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
7482          (match_operand 1 "" ""))
7483    (clobber (reg:DI 15))]
7484   ;;- Do not use operand 1 for most machines.
7485   "TARGET_ARCH64"
7486   "call\t%a0, %1%#"
7487   [(set_attr "type" "call")])
7489 (define_insn "*call_symbolic_sp64"
7490   [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
7491          (match_operand 1 "" ""))
7492    (clobber (reg:DI 15))]
7493   ;;- Do not use operand 1 for most machines.
7494   "TARGET_ARCH64"
7495   "call\t%a0, %1%#"
7496   [(set_attr "type" "call")])
7498 ;; This is a call that wants a structure value.
7499 ;; There is no such critter for v9 (??? we may need one anyway).
7500 (define_insn "*call_address_struct_value_sp32"
7501   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7502          (match_operand 1 "" ""))
7503    (match_operand 2 "immediate_operand" "")
7504    (clobber (reg:SI 15))]
7505   ;;- Do not use operand 1 for most machines.
7506   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
7508   operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
7509   return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
7511   [(set_attr "type" "call_no_delay_slot")
7512    (set_attr "length" "3")])
7514 ;; This is a call that wants a structure value.
7515 ;; There is no such critter for v9 (??? we may need one anyway).
7516 (define_insn "*call_symbolic_struct_value_sp32"
7517   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7518          (match_operand 1 "" ""))
7519    (match_operand 2 "immediate_operand" "")
7520    (clobber (reg:SI 15))]
7521   ;;- Do not use operand 1 for most machines.
7522   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
7524   operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
7525   return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
7527   [(set_attr "type" "call_no_delay_slot")
7528    (set_attr "length" "3")])
7530 ;; This is a call that may want a structure value.  This is used for
7531 ;; untyped_calls.
7532 (define_insn "*call_address_untyped_struct_value_sp32"
7533   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7534          (match_operand 1 "" ""))
7535    (match_operand 2 "immediate_operand" "")
7536    (clobber (reg:SI 15))]
7537   ;;- Do not use operand 1 for most machines.
7538   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7539   "call\t%a0, %1\n\t nop\n\tnop"
7540   [(set_attr "type" "call_no_delay_slot")
7541    (set_attr "length" "3")])
7543 ;; This is a call that may want a structure value.  This is used for
7544 ;; untyped_calls.
7545 (define_insn "*call_symbolic_untyped_struct_value_sp32"
7546   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7547          (match_operand 1 "" ""))
7548    (match_operand 2 "immediate_operand" "")
7549    (clobber (reg:SI 15))]
7550   ;;- Do not use operand 1 for most machines.
7551   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7552   "call\t%a0, %1\n\t nop\n\tnop"
7553   [(set_attr "type" "call_no_delay_slot")
7554    (set_attr "length" "3")])
7556 (define_expand "call_value"
7557   ;; Note that this expression is not used for generating RTL.
7558   ;; All the RTL is generated explicitly below.
7559   [(set (match_operand 0 "register_operand" "=rf")
7560         (call (match_operand 1 "" "")
7561               (match_operand 4 "" "")))]
7562   ;; operand 2 is stack_size_rtx
7563   ;; operand 3 is next_arg_register
7564   ""
7566   rtx fn_rtx;
7567   rtvec vec;
7569   if (GET_MODE (operands[1]) != FUNCTION_MODE)
7570     abort ();
7572   fn_rtx = operands[1];
7574   vec = gen_rtvec (2,
7575                    gen_rtx_SET (VOIDmode, operands[0],
7576                                 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
7577                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
7579   emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
7581   DONE;
7584 (define_insn "*call_value_address_sp32"
7585   [(set (match_operand 0 "" "=rf")
7586         (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
7587               (match_operand 2 "" "")))
7588    (clobber (reg:SI 15))]
7589   ;;- Do not use operand 2 for most machines.
7590   "! TARGET_ARCH64"
7591   "call\t%a1, %2%#"
7592   [(set_attr "type" "call")])
7594 (define_insn "*call_value_symbolic_sp32"
7595   [(set (match_operand 0 "" "=rf")
7596         (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7597               (match_operand 2 "" "")))
7598    (clobber (reg:SI 15))]
7599   ;;- Do not use operand 2 for most machines.
7600   "! TARGET_ARCH64"
7601   "call\t%a1, %2%#"
7602   [(set_attr "type" "call")])
7604 (define_insn "*call_value_address_sp64"
7605   [(set (match_operand 0 "" "")
7606         (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
7607               (match_operand 2 "" "")))
7608    (clobber (reg:DI 15))]
7609   ;;- Do not use operand 2 for most machines.
7610   "TARGET_ARCH64"
7611   "call\t%a1, %2%#"
7612   [(set_attr "type" "call")])
7614 (define_insn "*call_value_symbolic_sp64"
7615   [(set (match_operand 0 "" "")
7616         (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
7617               (match_operand 2 "" "")))
7618    (clobber (reg:DI 15))]
7619   ;;- Do not use operand 2 for most machines.
7620   "TARGET_ARCH64"
7621   "call\t%a1, %2%#"
7622   [(set_attr "type" "call")])
7624 (define_expand "untyped_call"
7625   [(parallel [(call (match_operand 0 "" "")
7626                     (const_int 0))
7627               (match_operand 1 "" "")
7628               (match_operand 2 "" "")])]
7629   ""
7631   int i;
7633   /* Pass constm1 to indicate that it may expect a structure value, but
7634      we don't know what size it is.  */
7635   emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
7637   for (i = 0; i < XVECLEN (operands[2], 0); i++)
7638     {
7639       rtx set = XVECEXP (operands[2], 0, i);
7640       emit_move_insn (SET_DEST (set), SET_SRC (set));
7641     }
7643   /* The optimizer does not know that the call sets the function value
7644      registers we stored in the result block.  We avoid problems by
7645      claiming that all hard registers are used and clobbered at this
7646      point.  */
7647   emit_insn (gen_blockage ());
7649   DONE;
7652 ;;- tail calls
7653 (define_expand "sibcall"
7654   [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
7655               (return)])]
7656   ""
7657   "")
7659 (define_insn "*sibcall_symbolic_sp32"
7660   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7661          (match_operand 1 "" ""))
7662    (return)]
7663   "! TARGET_ARCH64"
7664   "* return output_sibcall(insn, operands[0]);"
7665   [(set_attr "type" "sibcall")])
7667 (define_insn "*sibcall_symbolic_sp64"
7668   [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
7669          (match_operand 1 "" ""))
7670    (return)]
7671   "TARGET_ARCH64"
7672   "* return output_sibcall(insn, operands[0]);"
7673   [(set_attr "type" "sibcall")])
7675 (define_expand "sibcall_value"
7676   [(parallel [(set (match_operand 0 "register_operand" "=rf")
7677                 (call (match_operand 1 "" "") (const_int 0)))
7678               (return)])]
7679   ""
7680   "")
7682 (define_insn "*sibcall_value_symbolic_sp32"
7683   [(set (match_operand 0 "" "=rf")
7684         (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7685               (match_operand 2 "" "")))
7686    (return)]
7687   "! TARGET_ARCH64"
7688   "* return output_sibcall(insn, operands[1]);"
7689   [(set_attr "type" "sibcall")])
7691 (define_insn "*sibcall_value_symbolic_sp64"
7692   [(set (match_operand 0 "" "")
7693         (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
7694               (match_operand 2 "" "")))
7695    (return)]
7696   "TARGET_ARCH64"
7697   "* return output_sibcall(insn, operands[1]);"
7698   [(set_attr "type" "sibcall")])
7700 (define_expand "sibcall_epilogue"
7701   [(return)]
7702   ""
7704   sparc_expand_epilogue ();
7705   DONE;
7708 (define_expand "prologue"
7709   [(const_int 0)]
7710   ""
7712   sparc_expand_prologue ();
7713   DONE;
7716 ;; The "save register window" insn is modelled as follows so that the DWARF-2
7717 ;; backend automatically emits the required call frame debugging information
7718 ;; while it is parsing it.  Therefore, the pattern should not be modified
7719 ;; without first studying the impact of the changes on the debug info.
7720 ;; [(set (%fp) (%sp))
7721 ;;  (set (%sp) (unspec_volatile [(%sp) (-frame_size)] UNSPECV_SAVEW))
7722 ;;  (set (%i7) (%o7))]
7724 (define_insn "save_register_windowdi"
7725   [(set (reg:DI 30) (reg:DI 14))
7726    (set (reg:DI 14) (unspec_volatile:DI [(reg:DI 14)
7727                                          (match_operand:DI 0 "arith_operand" "rI")]
7728                                         UNSPECV_SAVEW))
7729    (set (reg:DI 31) (reg:DI 15))]
7730   "TARGET_ARCH64"
7731   "save\t%%sp, %0, %%sp"
7732   [(set_attr "type" "savew")])
7734 (define_insn "save_register_windowsi"
7735   [(set (reg:SI 30) (reg:SI 14))
7736    (set (reg:SI 14) (unspec_volatile:SI [(reg:SI 14)
7737                                          (match_operand:SI 0 "arith_operand" "rI")]
7738                                         UNSPECV_SAVEW))
7739    (set (reg:SI 31) (reg:SI 15))]
7740   "!TARGET_ARCH64"
7741   "save\t%%sp, %0, %%sp"
7742   [(set_attr "type" "savew")])
7744 (define_expand "epilogue"
7745   [(return)]
7746   ""
7748   sparc_expand_epilogue ();
7751 (define_expand "return"
7752   [(return)]
7753   "sparc_can_use_return_insn_p ()"
7754   "")
7756 (define_insn "*return_internal"
7757   [(return)]
7758   ""
7759   "* return output_return (insn);"
7760   [(set_attr "type" "return")
7761    (set (attr "length")
7762         (cond [(eq_attr "leaf_function" "true")
7763                  (if_then_else (eq_attr "empty_delay_slot" "true")
7764                                (const_int 2)
7765                                (const_int 1))
7766                (eq_attr "calls_eh_return" "true")
7767                  (if_then_else (eq_attr "delayed_branch" "true")
7768                                (if_then_else (eq_attr "isa" "v9")
7769                                              (const_int 2)
7770                                              (const_int 3))
7771                                (if_then_else (eq_attr "isa" "v9")
7772                                              (const_int 3)
7773                                              (const_int 4)))
7774                (eq_attr "empty_delay_slot" "true")
7775                  (if_then_else (eq_attr "delayed_branch" "true")
7776                                (const_int 2)
7777                                (const_int 3))
7778               ] (const_int 1)))])
7780 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
7781 ;; all of memory.  This blocks insns from being moved across this point.
7783 (define_insn "blockage"
7784   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7785   ""
7786   ""
7787   [(set_attr "length" "0")])
7789 ;; Prepare to return any type including a structure value.
7791 (define_expand "untyped_return"
7792   [(match_operand:BLK 0 "memory_operand" "")
7793    (match_operand 1 "" "")]
7794   ""
7796   rtx valreg1 = gen_rtx_REG (DImode, 24);
7797   rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
7798   rtx result = operands[0];
7800   if (! TARGET_ARCH64)
7801     {
7802       rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
7803                                          ? 15 : 31));
7804       rtx value = gen_reg_rtx (SImode);
7806       /* Fetch the instruction where we will return to and see if it's an unimp
7807          instruction (the most significant 10 bits will be zero).  If so,
7808          update the return address to skip the unimp instruction.  */
7809       emit_move_insn (value,
7810                       gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
7811       emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
7812       emit_insn (gen_update_return (rtnreg, value));
7813     }
7815   /* Reload the function value registers.  */
7816   emit_move_insn (valreg1, adjust_address (result, DImode, 0));
7817   emit_move_insn (valreg2,
7818                   adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
7820   /* Put USE insns before the return.  */
7821   emit_insn (gen_rtx_USE (VOIDmode, valreg1));
7822   emit_insn (gen_rtx_USE (VOIDmode, valreg2));
7824   /* Construct the return.  */
7825   expand_naked_return ();
7827   DONE;
7830 ;; This is a bit of a hack.  We're incrementing a fixed register (%i7),
7831 ;; and parts of the compiler don't want to believe that the add is needed.
7833 (define_insn "update_return"
7834   [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
7835                (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
7836   "! TARGET_ARCH64"
7838   if (flag_delayed_branch)
7839     return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
7840   else
7841     return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
7843   [(set (attr "type") (const_string "multi"))
7844    (set (attr "length")
7845         (if_then_else (eq_attr "delayed_branch" "true")
7846                       (const_int 3)
7847                       (const_int 4)))])
7849 (define_insn "nop"
7850   [(const_int 0)]
7851   ""
7852   "nop")
7854 (define_expand "indirect_jump"
7855   [(set (pc) (match_operand 0 "address_operand" "p"))]
7856   ""
7857   "")
7859 (define_insn "*branch_sp32"
7860   [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
7861   "! TARGET_ARCH64"
7862  "jmp\t%a0%#"
7863  [(set_attr "type" "uncond_branch")])
7865 (define_insn "*branch_sp64"
7866   [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
7867   "TARGET_ARCH64"
7868   "jmp\t%a0%#"
7869   [(set_attr "type" "uncond_branch")])
7871 (define_expand "nonlocal_goto"
7872   [(match_operand:SI 0 "general_operand" "")
7873    (match_operand:SI 1 "general_operand" "")
7874    (match_operand:SI 2 "general_operand" "")
7875    (match_operand:SI 3 "" "")]
7876   ""
7878   rtx lab = operands[1];
7879   rtx stack = operands[2];
7880   rtx fp = operands[3];
7881   rtx labreg;
7883   /* Trap instruction to flush all the register windows.  */
7884   emit_insn (gen_flush_register_windows ());
7886   /* Load the fp value for the containing fn into %fp.  This is needed
7887      because STACK refers to %fp.  Note that virtual register instantiation
7888      fails if the virtual %fp isn't set from a register.  */
7889   if (GET_CODE (fp) != REG)
7890     fp = force_reg (Pmode, fp);
7891   emit_move_insn (virtual_stack_vars_rtx, fp);
7893   /* Find the containing function's current nonlocal goto handler,
7894      which will do any cleanups and then jump to the label.  */
7895   labreg = gen_rtx_REG (Pmode, 8);
7896   emit_move_insn (labreg, lab);
7898   /* Restore %fp from stack pointer value for containing function.
7899      The restore insn that follows will move this to %sp,
7900      and reload the appropriate value into %fp.  */
7901   emit_move_insn (hard_frame_pointer_rtx, stack);
7903   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
7904   emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
7906   /* ??? The V9-specific version was disabled in rev 1.65.  */
7907   emit_jump_insn (gen_goto_handler_and_restore (labreg));
7908   emit_barrier ();
7909   DONE;
7912 ;; Special trap insn to flush register windows.
7913 (define_insn "flush_register_windows"
7914   [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
7915   ""
7916   { return TARGET_V9 ? "flushw" : "ta\t3"; }
7917   [(set_attr "type" "flushw")])
7919 (define_insn "goto_handler_and_restore"
7920   [(unspec_volatile [(match_operand 0 "register_operand" "=r")] UNSPECV_GOTO)]
7921   "GET_MODE (operands[0]) == Pmode"
7923   if (flag_delayed_branch)
7924     return "jmp\t%0\n\t restore";
7925   else
7926     return "mov\t%0,%%g1\n\trestore\n\tjmp\t%%g1\n\t nop";
7928   [(set (attr "type") (const_string "multi"))
7929    (set (attr "length")
7930         (if_then_else (eq_attr "delayed_branch" "true")
7931                       (const_int 2)
7932                       (const_int 4)))])
7934 ;; For __builtin_setjmp we need to flush register windows iff the function
7935 ;; calls alloca as well, because otherwise the register window might be
7936 ;; saved after %sp adjustment and thus setjmp would crash
7937 (define_expand "builtin_setjmp_setup"
7938   [(match_operand 0 "register_operand" "r")]
7939   ""
7941   emit_insn (gen_do_builtin_setjmp_setup ());
7942   DONE;
7945 (define_insn "do_builtin_setjmp_setup"
7946   [(unspec_volatile [(const_int 0)] UNSPECV_SETJMP)]
7947   ""
7949   if (! current_function_calls_alloca)
7950     return "";
7951   if (! TARGET_V9)
7952     return "\tta\t3\n";
7953   fputs ("\tflushw\n", asm_out_file);
7954   if (flag_pic)
7955     fprintf (asm_out_file, "\tst%c\t%%l7, [%%sp+%d]\n",
7956              TARGET_ARCH64 ? 'x' : 'w',
7957              SPARC_STACK_BIAS + 7 * UNITS_PER_WORD);
7958   fprintf (asm_out_file, "\tst%c\t%%fp, [%%sp+%d]\n",
7959            TARGET_ARCH64 ? 'x' : 'w',
7960            SPARC_STACK_BIAS + 14 * UNITS_PER_WORD);
7961   fprintf (asm_out_file, "\tst%c\t%%i7, [%%sp+%d]\n",
7962            TARGET_ARCH64 ? 'x' : 'w',
7963            SPARC_STACK_BIAS + 15 * UNITS_PER_WORD);
7964   return "";
7966   [(set_attr "type" "multi")
7967    (set (attr "length")
7968         (cond [(eq_attr "calls_alloca" "false")
7969                  (const_int 0)
7970                (eq_attr "isa" "!v9")
7971                  (const_int 1)
7972                (eq_attr "pic" "true")
7973                  (const_int 4)] (const_int 3)))])
7975 ;; Pattern for use after a setjmp to store FP and the return register
7976 ;; into the stack area.
7978 (define_expand "setjmp"
7979   [(const_int 0)]
7980   ""
7982   if (TARGET_ARCH64)
7983     emit_insn (gen_setjmp_64 ());
7984   else
7985     emit_insn (gen_setjmp_32 ());
7986   DONE;
7989 (define_expand "setjmp_32"
7990   [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
7991    (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
7992   ""
7993   { operands[0] = frame_pointer_rtx; })
7995 (define_expand "setjmp_64"
7996   [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
7997    (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
7998   ""
7999   { operands[0] = frame_pointer_rtx; })
8001 ;; Special pattern for the FLUSH instruction.
8003 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
8004 ; of the define_insn otherwise missing a mode.  We make "flush", aka
8005 ; gen_flush, the default one since sparc_initialize_trampoline uses
8006 ; it on SImode mem values.
8008 (define_insn "flush"
8009   [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
8010   ""
8011   { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
8012   [(set_attr "type" "iflush")])
8014 (define_insn "flushdi"
8015   [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
8016   ""
8017   { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
8018   [(set_attr "type" "iflush")])
8021 ;; find first set.
8023 ;; The scan instruction searches from the most significant bit while ffs
8024 ;; searches from the least significant bit.  The bit index and treatment of
8025 ;; zero also differ.  It takes at least 7 instructions to get the proper
8026 ;; result.  Here is an obvious 8 instruction sequence.
8028 ;; XXX
8029 (define_insn "ffssi2"
8030   [(set (match_operand:SI 0 "register_operand" "=&r")
8031         (ffs:SI (match_operand:SI 1 "register_operand" "r")))
8032    (clobber (match_scratch:SI 2 "=&r"))]
8033   "TARGET_SPARCLITE || TARGET_SPARCLET"
8035   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";
8037   [(set_attr "type" "multi")
8038    (set_attr "length" "8")])
8040 ;; ??? This should be a define expand, so that the extra instruction have
8041 ;; a chance of being optimized away.
8043 ;; Disabled because none of the UltraSPARCs implement popc.  The HAL R1
8044 ;; does, but no one uses that and we don't have a switch for it.
8046 ;(define_insn "ffsdi2"
8047 ;  [(set (match_operand:DI 0 "register_operand" "=&r")
8048 ;       (ffs:DI (match_operand:DI 1 "register_operand" "r")))
8049 ;   (clobber (match_scratch:DI 2 "=&r"))]
8050 ;  "TARGET_ARCH64"
8051 ;  "neg\t%1, %2\;xnor\t%1, %2, %2\;popc\t%2, %0\;movzr\t%1, 0, %0"
8052 ;  [(set_attr "type" "multi")
8053 ;   (set_attr "length" "4")])
8057 ;; Peepholes go at the end.
8059 ;; Optimize consecutive loads or stores into ldd and std when possible.
8060 ;; The conditions in which we do this are very restricted and are 
8061 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
8063 (define_peephole2
8064   [(set (match_operand:SI 0 "memory_operand" "")
8065       (const_int 0))
8066    (set (match_operand:SI 1 "memory_operand" "")
8067       (const_int 0))]
8068   "TARGET_V9
8069    && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
8070   [(set (match_dup 0)
8071        (const_int 0))]
8072   "operands[0] = widen_memory_access (operands[0], DImode, 0);")
8074 (define_peephole2
8075   [(set (match_operand:SI 0 "memory_operand" "")
8076       (const_int 0))
8077    (set (match_operand:SI 1 "memory_operand" "")
8078       (const_int 0))]
8079   "TARGET_V9
8080    && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
8081   [(set (match_dup 1)
8082        (const_int 0))]
8083   "operands[1] = widen_memory_access (operands[1], DImode, 0);")
8085 (define_peephole2
8086   [(set (match_operand:SI 0 "register_operand" "")
8087         (match_operand:SI 1 "memory_operand" ""))
8088    (set (match_operand:SI 2 "register_operand" "")
8089         (match_operand:SI 3 "memory_operand" ""))]
8090   "registers_ok_for_ldd_peep (operands[0], operands[2]) 
8091    && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])" 
8092   [(set (match_dup 0)
8093         (match_dup 1))]
8094   "operands[1] = widen_memory_access (operands[1], DImode, 0);
8095    operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
8097 (define_peephole2
8098   [(set (match_operand:SI 0 "memory_operand" "")
8099         (match_operand:SI 1 "register_operand" ""))
8100    (set (match_operand:SI 2 "memory_operand" "")
8101         (match_operand:SI 3 "register_operand" ""))]
8102   "registers_ok_for_ldd_peep (operands[1], operands[3]) 
8103    && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
8104   [(set (match_dup 0)
8105         (match_dup 1))]
8106   "operands[0] = widen_memory_access (operands[0], DImode, 0);
8107    operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
8109 (define_peephole2
8110   [(set (match_operand:SF 0 "register_operand" "")
8111         (match_operand:SF 1 "memory_operand" ""))
8112    (set (match_operand:SF 2 "register_operand" "")
8113         (match_operand:SF 3 "memory_operand" ""))]
8114   "registers_ok_for_ldd_peep (operands[0], operands[2]) 
8115    && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
8116   [(set (match_dup 0)
8117         (match_dup 1))]
8118   "operands[1] = widen_memory_access (operands[1], DFmode, 0);
8119    operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
8121 (define_peephole2
8122   [(set (match_operand:SF 0 "memory_operand" "")
8123         (match_operand:SF 1 "register_operand" ""))
8124    (set (match_operand:SF 2 "memory_operand" "")
8125         (match_operand:SF 3 "register_operand" ""))]
8126   "registers_ok_for_ldd_peep (operands[1], operands[3]) 
8127   && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
8128   [(set (match_dup 0)
8129         (match_dup 1))]
8130   "operands[0] = widen_memory_access (operands[0], DFmode, 0);
8131    operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
8133 (define_peephole2
8134   [(set (match_operand:SI 0 "register_operand" "")
8135         (match_operand:SI 1 "memory_operand" ""))
8136    (set (match_operand:SI 2 "register_operand" "")
8137         (match_operand:SI 3 "memory_operand" ""))]
8138   "registers_ok_for_ldd_peep (operands[2], operands[0]) 
8139   && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
8140   [(set (match_dup 2)
8141         (match_dup 3))]
8142    "operands[3] = widen_memory_access (operands[3], DImode, 0);
8143     operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
8145 (define_peephole2
8146   [(set (match_operand:SI 0 "memory_operand" "")
8147         (match_operand:SI 1 "register_operand" ""))
8148    (set (match_operand:SI 2 "memory_operand" "")
8149         (match_operand:SI 3 "register_operand" ""))]
8150   "registers_ok_for_ldd_peep (operands[3], operands[1]) 
8151   && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)" 
8152   [(set (match_dup 2)
8153         (match_dup 3))]
8154   "operands[2] = widen_memory_access (operands[2], DImode, 0);
8155    operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
8156    ")
8158 (define_peephole2
8159   [(set (match_operand:SF 0 "register_operand" "")
8160         (match_operand:SF 1 "memory_operand" ""))
8161    (set (match_operand:SF 2 "register_operand" "")
8162         (match_operand:SF 3 "memory_operand" ""))]
8163   "registers_ok_for_ldd_peep (operands[2], operands[0]) 
8164   && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
8165   [(set (match_dup 2)
8166         (match_dup 3))]
8167   "operands[3] = widen_memory_access (operands[3], DFmode, 0);
8168    operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
8170 (define_peephole2
8171   [(set (match_operand:SF 0 "memory_operand" "")
8172         (match_operand:SF 1 "register_operand" ""))
8173    (set (match_operand:SF 2 "memory_operand" "")
8174         (match_operand:SF 3 "register_operand" ""))]
8175   "registers_ok_for_ldd_peep (operands[3], operands[1]) 
8176   && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
8177   [(set (match_dup 2)
8178         (match_dup 3))]
8179   "operands[2] = widen_memory_access (operands[2], DFmode, 0);
8180    operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
8182 ;; Optimize the case of following a reg-reg move with a test
8183 ;; of reg just moved.  Don't allow floating point regs for operand 0 or 1.
8184 ;; This can result from a float to fix conversion.
8186 (define_peephole2
8187   [(set (match_operand:SI 0 "register_operand" "")
8188         (match_operand:SI 1 "register_operand" ""))
8189    (set (reg:CC 100)
8190         (compare:CC (match_operand:SI 2 "register_operand" "")
8191                     (const_int 0)))]
8192   "(rtx_equal_p (operands[2], operands[0])
8193     || rtx_equal_p (operands[2], operands[1]))
8194     && ! SPARC_FP_REG_P (REGNO (operands[0]))
8195     && ! SPARC_FP_REG_P (REGNO (operands[1]))"
8196   [(parallel [(set (match_dup 0) (match_dup 1))
8197               (set (reg:CC 100)
8198                    (compare:CC (match_dup 1) (const_int 0)))])]
8199   "")
8201 (define_peephole2
8202   [(set (match_operand:DI 0 "register_operand" "")
8203         (match_operand:DI 1 "register_operand" ""))
8204    (set (reg:CCX 100)
8205         (compare:CCX (match_operand:DI 2 "register_operand" "")
8206                     (const_int 0)))]
8207   "TARGET_ARCH64
8208    && (rtx_equal_p (operands[2], operands[0])
8209        || rtx_equal_p (operands[2], operands[1]))
8210    && ! SPARC_FP_REG_P (REGNO (operands[0]))
8211    && ! SPARC_FP_REG_P (REGNO (operands[1]))"
8212   [(parallel [(set (match_dup 0) (match_dup 1))
8213               (set (reg:CCX 100)
8214                    (compare:CCX (match_dup 1) (const_int 0)))])]
8215   "")
8217 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
8218 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
8219 ;; ??? operations.  With DFA we might be able to model this, but it requires a lot of
8220 ;; ??? state.
8221 (define_expand "prefetch"
8222   [(match_operand 0 "address_operand" "")
8223    (match_operand 1 "const_int_operand" "")
8224    (match_operand 2 "const_int_operand" "")]
8225   "TARGET_V9"
8227   if (TARGET_ARCH64)
8228     emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
8229   else
8230     emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
8231   DONE;
8234 (define_insn "prefetch_64"
8235   [(prefetch (match_operand:DI 0 "address_operand" "p")
8236              (match_operand:DI 1 "const_int_operand" "n")
8237              (match_operand:DI 2 "const_int_operand" "n"))]
8238   ""
8240   static const char * const prefetch_instr[2][2] = {
8241     {
8242       "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
8243       "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
8244     },
8245     {
8246       "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
8247       "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
8248     }
8249   };
8250   int read_or_write = INTVAL (operands[1]);
8251   int locality = INTVAL (operands[2]);
8253   if (read_or_write != 0 && read_or_write != 1)
8254     abort ();
8255   if (locality < 0 || locality > 3)
8256     abort ();
8257   return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
8259   [(set_attr "type" "load")])
8261 (define_insn "prefetch_32"
8262   [(prefetch (match_operand:SI 0 "address_operand" "p")
8263              (match_operand:SI 1 "const_int_operand" "n")
8264              (match_operand:SI 2 "const_int_operand" "n"))]
8265   ""
8267   static const char * const prefetch_instr[2][2] = {
8268     {
8269       "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
8270       "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
8271     },
8272     {
8273       "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
8274       "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
8275     }
8276   };
8277   int read_or_write = INTVAL (operands[1]);
8278   int locality = INTVAL (operands[2]);
8280   if (read_or_write != 0 && read_or_write != 1)
8281     abort ();
8282   if (locality < 0 || locality > 3)
8283     abort ();
8284   return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
8286   [(set_attr "type" "load")])
8288 (define_insn "trap"
8289   [(trap_if (const_int 1) (const_int 5))]
8290   ""
8291   "ta\t5"
8292   [(set_attr "type" "trap")])
8294 (define_expand "conditional_trap"
8295   [(trap_if (match_operator 0 "noov_compare_op" [(match_dup 2) (match_dup 3)])
8296             (match_operand:SI 1 "arith_operand" ""))]
8297   ""
8298   "operands[2] = gen_compare_reg (GET_CODE (operands[0]),
8299                                   sparc_compare_op0, sparc_compare_op1);
8300    if (GET_MODE (operands[2]) != CCmode && GET_MODE (operands[2]) != CCXmode)
8301      FAIL;
8302    operands[3] = const0_rtx;")
8304 (define_insn ""
8305   [(trap_if (match_operator 0 "noov_compare_op" [(reg:CC 100) (const_int 0)])
8306             (match_operand:SI 1 "arith_operand" "rM"))]
8307   ""
8309   if (TARGET_V9)
8310     return "t%C0\t%%icc, %1";
8311   else
8312     return "t%C0\t%1";
8314   [(set_attr "type" "trap")])
8316 (define_insn ""
8317   [(trap_if (match_operator 0 "noov_compare_op" [(reg:CCX 100) (const_int 0)])
8318             (match_operand:SI 1 "arith_operand" "rM"))]
8319   "TARGET_V9"
8320   "t%C0\t%%xcc, %1"
8321   [(set_attr "type" "trap")])
8323 ;; TLS support
8324 (define_insn "tgd_hi22"
8325   [(set (match_operand:SI 0 "register_operand" "=r")
8326         (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
8327                             UNSPEC_TLSGD)))]
8328   "TARGET_TLS"
8329   "sethi\\t%%tgd_hi22(%a1), %0")
8331 (define_insn "tgd_lo10"
8332   [(set (match_operand:SI 0 "register_operand" "=r")
8333         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8334                    (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
8335                               UNSPEC_TLSGD)))]
8336   "TARGET_TLS"
8337   "add\\t%1, %%tgd_lo10(%a2), %0")
8339 (define_insn "tgd_add32"
8340   [(set (match_operand:SI 0 "register_operand" "=r")
8341         (plus:SI (match_operand:SI 1 "register_operand" "r")
8342                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8343                              (match_operand 3 "tgd_symbolic_operand" "")]
8344                             UNSPEC_TLSGD)))]
8345   "TARGET_TLS && TARGET_ARCH32"
8346   "add\\t%1, %2, %0, %%tgd_add(%a3)")
8348 (define_insn "tgd_add64"
8349   [(set (match_operand:DI 0 "register_operand" "=r")
8350         (plus:DI (match_operand:DI 1 "register_operand" "r")
8351                  (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8352                              (match_operand 3 "tgd_symbolic_operand" "")]
8353                             UNSPEC_TLSGD)))]
8354   "TARGET_TLS && TARGET_ARCH64"
8355   "add\\t%1, %2, %0, %%tgd_add(%a3)")
8357 (define_insn "tgd_call32"
8358   [(set (match_operand 0 "register_operand" "=r")
8359         (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
8360                                   (match_operand 2 "tgd_symbolic_operand" "")]
8361                                  UNSPEC_TLSGD))
8362               (match_operand 3 "" "")))
8363    (clobber (reg:SI 15))]
8364   "TARGET_TLS && TARGET_ARCH32"
8365   "call\t%a1, %%tgd_call(%a2)%#"
8366   [(set_attr "type" "call")])
8368 (define_insn "tgd_call64"
8369   [(set (match_operand 0 "register_operand" "=r")
8370         (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
8371                                   (match_operand 2 "tgd_symbolic_operand" "")]
8372                                  UNSPEC_TLSGD))
8373               (match_operand 3 "" "")))
8374    (clobber (reg:DI 15))]
8375   "TARGET_TLS && TARGET_ARCH64"
8376   "call\t%a1, %%tgd_call(%a2)%#"
8377   [(set_attr "type" "call")])
8379 (define_insn "tldm_hi22"
8380   [(set (match_operand:SI 0 "register_operand" "=r")
8381         (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
8382   "TARGET_TLS"
8383   "sethi\\t%%tldm_hi22(%&), %0")
8385 (define_insn "tldm_lo10"
8386   [(set (match_operand:SI 0 "register_operand" "=r")
8387         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8388                     (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
8389   "TARGET_TLS"
8390   "add\\t%1, %%tldm_lo10(%&), %0")
8392 (define_insn "tldm_add32"
8393   [(set (match_operand:SI 0 "register_operand" "=r")
8394         (plus:SI (match_operand:SI 1 "register_operand" "r")
8395                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
8396                             UNSPEC_TLSLDM)))]
8397   "TARGET_TLS && TARGET_ARCH32"
8398   "add\\t%1, %2, %0, %%tldm_add(%&)")
8400 (define_insn "tldm_add64"
8401   [(set (match_operand:DI 0 "register_operand" "=r")
8402         (plus:DI (match_operand:DI 1 "register_operand" "r")
8403                  (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
8404                             UNSPEC_TLSLDM)))]
8405   "TARGET_TLS && TARGET_ARCH64"
8406   "add\\t%1, %2, %0, %%tldm_add(%&)")
8408 (define_insn "tldm_call32"
8409   [(set (match_operand 0 "register_operand" "=r")
8410         (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
8411                                  UNSPEC_TLSLDM))
8412               (match_operand 2 "" "")))
8413    (clobber (reg:SI 15))]
8414   "TARGET_TLS && TARGET_ARCH32"
8415   "call\t%a1, %%tldm_call(%&)%#"
8416   [(set_attr "type" "call")])
8418 (define_insn "tldm_call64"
8419   [(set (match_operand 0 "register_operand" "=r")
8420         (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
8421                                  UNSPEC_TLSLDM))
8422               (match_operand 2 "" "")))
8423    (clobber (reg:DI 15))]
8424   "TARGET_TLS && TARGET_ARCH64"
8425   "call\t%a1, %%tldm_call(%&)%#"
8426   [(set_attr "type" "call")])
8428 (define_insn "tldo_hix22"
8429   [(set (match_operand:SI 0 "register_operand" "=r")
8430         (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
8431                             UNSPEC_TLSLDO)))]
8432   "TARGET_TLS"
8433   "sethi\\t%%tldo_hix22(%a1), %0")
8435 (define_insn "tldo_lox10"
8436   [(set (match_operand:SI 0 "register_operand" "=r")
8437         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8438                    (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
8439                               UNSPEC_TLSLDO)))]
8440   "TARGET_TLS"
8441   "xor\\t%1, %%tldo_lox10(%a2), %0")
8443 (define_insn "tldo_add32"
8444   [(set (match_operand:SI 0 "register_operand" "=r")
8445         (plus:SI (match_operand:SI 1 "register_operand" "r")
8446                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8447                              (match_operand 3 "tld_symbolic_operand" "")]
8448                             UNSPEC_TLSLDO)))]
8449   "TARGET_TLS && TARGET_ARCH32"
8450   "add\\t%1, %2, %0, %%tldo_add(%a3)")
8452 (define_insn "tldo_add64"
8453   [(set (match_operand:DI 0 "register_operand" "=r")
8454         (plus:DI (match_operand:DI 1 "register_operand" "r")
8455                  (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8456                              (match_operand 3 "tld_symbolic_operand" "")]
8457                             UNSPEC_TLSLDO)))]
8458   "TARGET_TLS && TARGET_ARCH64"
8459   "add\\t%1, %2, %0, %%tldo_add(%a3)")
8461 (define_insn "tie_hi22"
8462   [(set (match_operand:SI 0 "register_operand" "=r")
8463         (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
8464                             UNSPEC_TLSIE)))]
8465   "TARGET_TLS"
8466   "sethi\\t%%tie_hi22(%a1), %0")
8468 (define_insn "tie_lo10"
8469   [(set (match_operand:SI 0 "register_operand" "=r")
8470         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8471                    (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
8472                               UNSPEC_TLSIE)))]
8473   "TARGET_TLS"
8474   "add\\t%1, %%tie_lo10(%a2), %0")
8476 (define_insn "tie_ld32"
8477   [(set (match_operand:SI 0 "register_operand" "=r")
8478         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
8479                     (match_operand:SI 2 "register_operand" "r")
8480                     (match_operand 3 "tie_symbolic_operand" "")]
8481                    UNSPEC_TLSIE))]
8482   "TARGET_TLS && TARGET_ARCH32"
8483   "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
8484   [(set_attr "type" "load")])
8486 (define_insn "tie_ld64"
8487   [(set (match_operand:DI 0 "register_operand" "=r")
8488         (unspec:DI [(match_operand:DI 1 "register_operand" "r")
8489                     (match_operand:SI 2 "register_operand" "r")
8490                     (match_operand 3 "tie_symbolic_operand" "")]
8491                    UNSPEC_TLSIE))]
8492   "TARGET_TLS && TARGET_ARCH64"
8493   "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
8494   [(set_attr "type" "load")])
8496 (define_insn "tie_add32"
8497   [(set (match_operand:SI 0 "register_operand" "=r")
8498         (plus:SI (match_operand:SI 1 "register_operand" "r")
8499                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8500                              (match_operand 3 "tie_symbolic_operand" "")]
8501                             UNSPEC_TLSIE)))]
8502   "TARGET_SUN_TLS && TARGET_ARCH32"
8503   "add\\t%1, %2, %0, %%tie_add(%a3)")
8505 (define_insn "tie_add64"
8506   [(set (match_operand:DI 0 "register_operand" "=r")
8507         (plus:DI (match_operand:DI 1 "register_operand" "r")
8508                  (unspec:DI [(match_operand:DI 2 "register_operand" "r")
8509                              (match_operand 3 "tie_symbolic_operand" "")]
8510                             UNSPEC_TLSIE)))]
8511   "TARGET_SUN_TLS && TARGET_ARCH64"
8512   "add\\t%1, %2, %0, %%tie_add(%a3)")
8514 (define_insn "tle_hix22_sp32"
8515   [(set (match_operand:SI 0 "register_operand" "=r")
8516         (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
8517                             UNSPEC_TLSLE)))]
8518   "TARGET_TLS && TARGET_ARCH32"
8519   "sethi\\t%%tle_hix22(%a1), %0")
8521 (define_insn "tle_lox10_sp32"
8522   [(set (match_operand:SI 0 "register_operand" "=r")
8523         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8524                    (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
8525                               UNSPEC_TLSLE)))]
8526   "TARGET_TLS && TARGET_ARCH32"
8527   "xor\\t%1, %%tle_lox10(%a2), %0")
8529 (define_insn "tle_hix22_sp64"
8530   [(set (match_operand:DI 0 "register_operand" "=r")
8531         (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
8532                             UNSPEC_TLSLE)))]
8533   "TARGET_TLS && TARGET_ARCH64"
8534   "sethi\\t%%tle_hix22(%a1), %0")
8536 (define_insn "tle_lox10_sp64"
8537   [(set (match_operand:DI 0 "register_operand" "=r")
8538         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
8539                    (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
8540                               UNSPEC_TLSLE)))]
8541   "TARGET_TLS && TARGET_ARCH64"
8542   "xor\\t%1, %%tle_lox10(%a2), %0")
8544 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
8545 (define_insn "*tldo_ldub_sp32"
8546   [(set (match_operand:QI 0 "register_operand" "=r")
8547         (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8548                                      (match_operand 3 "tld_symbolic_operand" "")]
8549                                     UNSPEC_TLSLDO)
8550                          (match_operand:SI 1 "register_operand" "r"))))]
8551   "TARGET_TLS && TARGET_ARCH32"
8552   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8553   [(set_attr "type" "load")
8554    (set_attr "us3load_type" "3cycle")])
8556 (define_insn "*tldo_ldub1_sp32"
8557   [(set (match_operand:HI 0 "register_operand" "=r")
8558         (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8559                                                      (match_operand 3 "tld_symbolic_operand" "")]
8560                                                     UNSPEC_TLSLDO)
8561                                          (match_operand:SI 1 "register_operand" "r")))))]
8562   "TARGET_TLS && TARGET_ARCH32"
8563   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8564   [(set_attr "type" "load")
8565    (set_attr "us3load_type" "3cycle")])
8567 (define_insn "*tldo_ldub2_sp32"
8568   [(set (match_operand:SI 0 "register_operand" "=r")
8569         (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8570                                                      (match_operand 3 "tld_symbolic_operand" "")]
8571                                                     UNSPEC_TLSLDO)
8572                                          (match_operand:SI 1 "register_operand" "r")))))]
8573   "TARGET_TLS && TARGET_ARCH32"
8574   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8575   [(set_attr "type" "load")
8576    (set_attr "us3load_type" "3cycle")])
8578 (define_insn "*tldo_ldsb1_sp32"
8579   [(set (match_operand:HI 0 "register_operand" "=r")
8580         (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8581                                                      (match_operand 3 "tld_symbolic_operand" "")]
8582                                                     UNSPEC_TLSLDO)
8583                                          (match_operand:SI 1 "register_operand" "r")))))]
8584   "TARGET_TLS && TARGET_ARCH32"
8585   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8586   [(set_attr "type" "sload")
8587    (set_attr "us3load_type" "3cycle")])
8589 (define_insn "*tldo_ldsb2_sp32"
8590   [(set (match_operand:SI 0 "register_operand" "=r")
8591         (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8592                                                      (match_operand 3 "tld_symbolic_operand" "")]
8593                                                     UNSPEC_TLSLDO)
8594                                          (match_operand:SI 1 "register_operand" "r")))))]
8595   "TARGET_TLS && TARGET_ARCH32"
8596   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8597   [(set_attr "type" "sload")
8598    (set_attr "us3load_type" "3cycle")])
8600 (define_insn "*tldo_ldub_sp64"
8601   [(set (match_operand:QI 0 "register_operand" "=r")
8602         (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8603                                      (match_operand 3 "tld_symbolic_operand" "")]
8604                                     UNSPEC_TLSLDO)
8605                          (match_operand:DI 1 "register_operand" "r"))))]
8606   "TARGET_TLS && TARGET_ARCH64"
8607   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8608   [(set_attr "type" "load")
8609    (set_attr "us3load_type" "3cycle")])
8611 (define_insn "*tldo_ldub1_sp64"
8612   [(set (match_operand:HI 0 "register_operand" "=r")
8613         (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8614                                                      (match_operand 3 "tld_symbolic_operand" "")]
8615                                                     UNSPEC_TLSLDO)
8616                                          (match_operand:DI 1 "register_operand" "r")))))]
8617   "TARGET_TLS && TARGET_ARCH64"
8618   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8619   [(set_attr "type" "load")
8620    (set_attr "us3load_type" "3cycle")])
8622 (define_insn "*tldo_ldub2_sp64"
8623   [(set (match_operand:SI 0 "register_operand" "=r")
8624         (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8625                                                      (match_operand 3 "tld_symbolic_operand" "")]
8626                                                     UNSPEC_TLSLDO)
8627                                          (match_operand:DI 1 "register_operand" "r")))))]
8628   "TARGET_TLS && TARGET_ARCH64"
8629   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8630   [(set_attr "type" "load")
8631    (set_attr "us3load_type" "3cycle")])
8633 (define_insn "*tldo_ldub3_sp64"
8634   [(set (match_operand:DI 0 "register_operand" "=r")
8635         (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8636                                                      (match_operand 3 "tld_symbolic_operand" "")]
8637                                                     UNSPEC_TLSLDO)
8638                                          (match_operand:DI 1 "register_operand" "r")))))]
8639   "TARGET_TLS && TARGET_ARCH64"
8640   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8641   [(set_attr "type" "load")
8642    (set_attr "us3load_type" "3cycle")])
8644 (define_insn "*tldo_ldsb1_sp64"
8645   [(set (match_operand:HI 0 "register_operand" "=r")
8646         (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8647                                                      (match_operand 3 "tld_symbolic_operand" "")]
8648                                                     UNSPEC_TLSLDO)
8649                                          (match_operand:DI 1 "register_operand" "r")))))]
8650   "TARGET_TLS && TARGET_ARCH64"
8651   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8652   [(set_attr "type" "sload")
8653    (set_attr "us3load_type" "3cycle")])
8655 (define_insn "*tldo_ldsb2_sp64"
8656   [(set (match_operand:SI 0 "register_operand" "=r")
8657         (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8658                                                      (match_operand 3 "tld_symbolic_operand" "")]
8659                                                     UNSPEC_TLSLDO)
8660                                          (match_operand:DI 1 "register_operand" "r")))))]
8661   "TARGET_TLS && TARGET_ARCH64"
8662   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8663   [(set_attr "type" "sload")
8664    (set_attr "us3load_type" "3cycle")])
8666 (define_insn "*tldo_ldsb3_sp64"
8667   [(set (match_operand:DI 0 "register_operand" "=r")
8668         (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8669                                                      (match_operand 3 "tld_symbolic_operand" "")]
8670                                                     UNSPEC_TLSLDO)
8671                                          (match_operand:DI 1 "register_operand" "r")))))]
8672   "TARGET_TLS && TARGET_ARCH64"
8673   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8674   [(set_attr "type" "sload")
8675    (set_attr "us3load_type" "3cycle")])
8677 (define_insn "*tldo_lduh_sp32"
8678   [(set (match_operand:HI 0 "register_operand" "=r")
8679         (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8680                                      (match_operand 3 "tld_symbolic_operand" "")]
8681                                     UNSPEC_TLSLDO)
8682                          (match_operand:SI 1 "register_operand" "r"))))]
8683   "TARGET_TLS && TARGET_ARCH32"
8684   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8685   [(set_attr "type" "load")
8686    (set_attr "us3load_type" "3cycle")])
8688 (define_insn "*tldo_lduh1_sp32"
8689   [(set (match_operand:SI 0 "register_operand" "=r")
8690         (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8691                                                      (match_operand 3 "tld_symbolic_operand" "")]
8692                                                     UNSPEC_TLSLDO)
8693                                          (match_operand:SI 1 "register_operand" "r")))))]
8694   "TARGET_TLS && TARGET_ARCH32"
8695   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8696   [(set_attr "type" "load")
8697    (set_attr "us3load_type" "3cycle")])
8699 (define_insn "*tldo_ldsh1_sp32"
8700   [(set (match_operand:SI 0 "register_operand" "=r")
8701         (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8702                                                      (match_operand 3 "tld_symbolic_operand" "")]
8703                                                     UNSPEC_TLSLDO)
8704                                          (match_operand:SI 1 "register_operand" "r")))))]
8705   "TARGET_TLS && TARGET_ARCH32"
8706   "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8707   [(set_attr "type" "sload")
8708    (set_attr "us3load_type" "3cycle")])
8710 (define_insn "*tldo_lduh_sp64"
8711   [(set (match_operand:HI 0 "register_operand" "=r")
8712         (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8713                                      (match_operand 3 "tld_symbolic_operand" "")]
8714                                     UNSPEC_TLSLDO)
8715                          (match_operand:DI 1 "register_operand" "r"))))]
8716   "TARGET_TLS && TARGET_ARCH64"
8717   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8718   [(set_attr "type" "load")
8719    (set_attr "us3load_type" "3cycle")])
8721 (define_insn "*tldo_lduh1_sp64"
8722   [(set (match_operand:SI 0 "register_operand" "=r")
8723         (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8724                                                      (match_operand 3 "tld_symbolic_operand" "")]
8725                                                     UNSPEC_TLSLDO)
8726                                          (match_operand:DI 1 "register_operand" "r")))))]
8727   "TARGET_TLS && TARGET_ARCH64"
8728   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8729   [(set_attr "type" "load")
8730    (set_attr "us3load_type" "3cycle")])
8732 (define_insn "*tldo_lduh2_sp64"
8733   [(set (match_operand:DI 0 "register_operand" "=r")
8734         (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8735                                                      (match_operand 3 "tld_symbolic_operand" "")]
8736                                                     UNSPEC_TLSLDO)
8737                                          (match_operand:DI 1 "register_operand" "r")))))]
8738   "TARGET_TLS && TARGET_ARCH64"
8739   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8740   [(set_attr "type" "load")
8741    (set_attr "us3load_type" "3cycle")])
8743 (define_insn "*tldo_ldsh1_sp64"
8744   [(set (match_operand:SI 0 "register_operand" "=r")
8745         (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8746                                                      (match_operand 3 "tld_symbolic_operand" "")]
8747                                                     UNSPEC_TLSLDO)
8748                                          (match_operand:DI 1 "register_operand" "r")))))]
8749   "TARGET_TLS && TARGET_ARCH64"
8750   "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8751   [(set_attr "type" "sload")
8752    (set_attr "us3load_type" "3cycle")])
8754 (define_insn "*tldo_ldsh2_sp64"
8755   [(set (match_operand:DI 0 "register_operand" "=r")
8756         (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8757                                                      (match_operand 3 "tld_symbolic_operand" "")]
8758                                                     UNSPEC_TLSLDO)
8759                                          (match_operand:DI 1 "register_operand" "r")))))]
8760   "TARGET_TLS && TARGET_ARCH64"
8761   "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8762   [(set_attr "type" "sload")
8763    (set_attr "us3load_type" "3cycle")])
8765 (define_insn "*tldo_lduw_sp32"
8766   [(set (match_operand:SI 0 "register_operand" "=r")
8767         (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8768                                      (match_operand 3 "tld_symbolic_operand" "")]
8769                                     UNSPEC_TLSLDO)
8770                          (match_operand:SI 1 "register_operand" "r"))))]
8771   "TARGET_TLS && TARGET_ARCH32"
8772   "ld\t[%1 + %2], %0, %%tldo_add(%3)"
8773   [(set_attr "type" "load")])
8775 (define_insn "*tldo_lduw_sp64"
8776   [(set (match_operand:SI 0 "register_operand" "=r")
8777         (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8778                                      (match_operand 3 "tld_symbolic_operand" "")]
8779                                     UNSPEC_TLSLDO)
8780                          (match_operand:DI 1 "register_operand" "r"))))]
8781   "TARGET_TLS && TARGET_ARCH64"
8782   "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8783   [(set_attr "type" "load")])
8785 (define_insn "*tldo_lduw1_sp64"
8786   [(set (match_operand:DI 0 "register_operand" "=r")
8787         (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8788                                                      (match_operand 3 "tld_symbolic_operand" "")]
8789                                                     UNSPEC_TLSLDO)
8790                                          (match_operand:DI 1 "register_operand" "r")))))]
8791   "TARGET_TLS && TARGET_ARCH64"
8792   "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8793   [(set_attr "type" "load")])
8795 (define_insn "*tldo_ldsw1_sp64"
8796   [(set (match_operand:DI 0 "register_operand" "=r")
8797         (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8798                                                      (match_operand 3 "tld_symbolic_operand" "")]
8799                                                     UNSPEC_TLSLDO)
8800                                          (match_operand:DI 1 "register_operand" "r")))))]
8801   "TARGET_TLS && TARGET_ARCH64"
8802   "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
8803   [(set_attr "type" "sload")
8804    (set_attr "us3load_type" "3cycle")])
8806 (define_insn "*tldo_ldx_sp64"
8807   [(set (match_operand:DI 0 "register_operand" "=r")
8808         (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8809                                      (match_operand 3 "tld_symbolic_operand" "")]
8810                                     UNSPEC_TLSLDO)
8811                          (match_operand:DI 1 "register_operand" "r"))))]
8812   "TARGET_TLS && TARGET_ARCH64"
8813   "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
8814   [(set_attr "type" "load")])
8816 (define_insn "*tldo_stb_sp32"
8817   [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8818                                      (match_operand 3 "tld_symbolic_operand" "")]
8819                                     UNSPEC_TLSLDO)
8820                          (match_operand:SI 1 "register_operand" "r")))
8821         (match_operand:QI 0 "register_operand" "=r"))]
8822   "TARGET_TLS && TARGET_ARCH32"
8823   "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8824   [(set_attr "type" "store")])
8826 (define_insn "*tldo_stb_sp64"
8827   [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8828                                      (match_operand 3 "tld_symbolic_operand" "")]
8829                                     UNSPEC_TLSLDO)
8830                          (match_operand:DI 1 "register_operand" "r")))
8831         (match_operand:QI 0 "register_operand" "=r"))]
8832   "TARGET_TLS && TARGET_ARCH64"
8833   "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8834   [(set_attr "type" "store")])
8836 (define_insn "*tldo_sth_sp32"
8837   [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8838                                      (match_operand 3 "tld_symbolic_operand" "")]
8839                                     UNSPEC_TLSLDO)
8840                          (match_operand:SI 1 "register_operand" "r")))
8841         (match_operand:HI 0 "register_operand" "=r"))]
8842   "TARGET_TLS && TARGET_ARCH32"
8843   "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8844   [(set_attr "type" "store")])
8846 (define_insn "*tldo_sth_sp64"
8847   [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8848                                      (match_operand 3 "tld_symbolic_operand" "")]
8849                                     UNSPEC_TLSLDO)
8850                          (match_operand:DI 1 "register_operand" "r")))
8851         (match_operand:HI 0 "register_operand" "=r"))]
8852   "TARGET_TLS && TARGET_ARCH64"
8853   "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8854   [(set_attr "type" "store")])
8856 (define_insn "*tldo_stw_sp32"
8857   [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8858                                      (match_operand 3 "tld_symbolic_operand" "")]
8859                                     UNSPEC_TLSLDO)
8860                          (match_operand:SI 1 "register_operand" "r")))
8861         (match_operand:SI 0 "register_operand" "=r"))]
8862   "TARGET_TLS && TARGET_ARCH32"
8863   "st\t%0, [%1 + %2], %%tldo_add(%3)"
8864   [(set_attr "type" "store")])
8866 (define_insn "*tldo_stw_sp64"
8867   [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8868                                      (match_operand 3 "tld_symbolic_operand" "")]
8869                                     UNSPEC_TLSLDO)
8870                          (match_operand:DI 1 "register_operand" "r")))
8871         (match_operand:SI 0 "register_operand" "=r"))]
8872   "TARGET_TLS && TARGET_ARCH64"
8873   "stw\t%0, [%1 + %2], %%tldo_add(%3)"
8874   [(set_attr "type" "store")])
8876 (define_insn "*tldo_stx_sp64"
8877   [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8878                                      (match_operand 3 "tld_symbolic_operand" "")]
8879                                     UNSPEC_TLSLDO)
8880                          (match_operand:DI 1 "register_operand" "r")))
8881         (match_operand:DI 0 "register_operand" "=r"))]
8882   "TARGET_TLS && TARGET_ARCH64"
8883   "stx\t%0, [%1 + %2], %%tldo_add(%3)"
8884   [(set_attr "type" "store")])
8886 ;; Vector instructions.
8888 (define_insn "addv2si3"
8889   [(set (match_operand:V2SI 0 "register_operand" "=e")
8890         (plus:V2SI (match_operand:V2SI 1 "register_operand" "e")
8891                    (match_operand:V2SI 2 "register_operand" "e")))]
8892   "TARGET_VIS"
8893   "fpadd32\t%1, %2, %0"
8894   [(set_attr "type" "fga")
8895    (set_attr "fptype" "double")])
8897 (define_insn "addv4hi3"
8898   [(set (match_operand:V4HI 0 "register_operand" "=e")
8899          (plus:V4HI (match_operand:V4HI 1 "register_operand" "e")
8900                     (match_operand:V4HI 2 "register_operand" "e")))]
8901   "TARGET_VIS"
8902   "fpadd16\t%1, %2, %0"
8903   [(set_attr "type" "fga")
8904    (set_attr "fptype" "double")])
8906 ;; fpadd32s is emitted by the addsi3 pattern.
8908 (define_insn "addv2hi3"
8909   [(set (match_operand:V2HI 0 "register_operand" "=f")
8910         (plus:V2HI (match_operand:V2HI 1 "register_operand" "f")
8911                    (match_operand:V2HI 2 "register_operand" "f")))]
8912   "TARGET_VIS"
8913   "fpadd16s\t%1, %2, %0"
8914   [(set_attr "type" "fga")
8915    (set_attr "fptype" "single")])
8917 (define_insn "subv2si3"
8918   [(set (match_operand:V2SI 0 "register_operand" "=e")
8919         (minus:V2SI (match_operand:V2SI 1 "register_operand" "e")
8920                     (match_operand:V2SI 2 "register_operand" "e")))]
8921   "TARGET_VIS"
8922   "fpsub32\t%1, %2, %0"
8923   [(set_attr "type" "fga")
8924    (set_attr "fptype" "double")])
8926 (define_insn "subv4hi3"
8927   [(set (match_operand:V4HI 0 "register_operand" "=e")
8928         (minus:V4HI (match_operand:V4HI 1 "register_operand" "e")
8929                     (match_operand:V4HI 2 "register_operand" "e")))]
8930   "TARGET_VIS"
8931   "fpsub16\t%1, %2, %0"
8932   [(set_attr "type" "fga")
8933    (set_attr "fptype" "double")])
8935 ;; fpsub32s is emitted by the subsi3 pattern.
8937 (define_insn "subv2hi3"
8938   [(set (match_operand:V2HI 0 "register_operand" "=f")
8939         (minus:V2HI (match_operand:V2HI 1 "register_operand" "f")
8940                     (match_operand:V2HI 2 "register_operand" "f")))]
8941   "TARGET_VIS"
8942   "fpsub16s\t%1, %2, %0"
8943   [(set_attr "type" "fga")
8944    (set_attr "fptype" "single")])
8946 ;; All other logical instructions have integer equivalents so they
8947 ;; are defined together.
8949 ;; (ior (not (op1)) (not (op2))) is the canonical form of NAND.
8951 (define_insn "*nand<V64mode>_vis"
8952   [(set (match_operand:V64 0 "register_operand" "=e")
8953         (ior:V64 (not:V64 (match_operand:V64 1 "register_operand" "e"))
8954                  (not:V64 (match_operand:V64 2 "register_operand" "e"))))]
8955   "TARGET_VIS"
8956   "fnand\t%1, %2, %0"
8957   [(set_attr "type" "fga")
8958    (set_attr "fptype" "double")])
8960 (define_insn "*nand<V32mode>_vis"
8961   [(set (match_operand:V32 0 "register_operand" "=f")
8962          (ior:V32 (not:V32 (match_operand:V32 1 "register_operand" "f"))
8963                   (not:V32 (match_operand:V32 2 "register_operand" "f"))))]
8964   "TARGET_VIS"
8965   "fnands\t%1, %2, %0"
8966   [(set_attr "type" "fga")
8967    (set_attr "fptype" "single")])
8969 ;; Hard to generate VIS instructions.  We have builtins for these.
8971 (define_insn "fpack16_vis"
8972   [(set (match_operand:V4QI 0 "register_operand" "=f")
8973         (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e")]
8974                       UNSPEC_FPACK16))]
8975   "TARGET_VIS"
8976   "fpack16\t%1, %0"
8977   [(set_attr "type" "fga")
8978    (set_attr "fptype" "double")])
8980 (define_insn "fpackfix_vis"
8981   [(set (match_operand:V2HI 0 "register_operand" "=f")
8982         (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e")]
8983                       UNSPEC_FPACKFIX))]
8984   "TARGET_VIS"
8985   "fpackfix\t%1, %0"
8986   [(set_attr "type" "fga")
8987    (set_attr "fptype" "double")])
8989 (define_insn "fpack32_vis"
8990   [(set (match_operand:V8QI 0 "register_operand" "=e")
8991         (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e")
8992                       (match_operand:V8QI 2 "register_operand" "e")]
8993                      UNSPEC_FPACK32))]
8994   "TARGET_VIS"
8995   "fpack32\t%1, %2, %0"
8996   [(set_attr "type" "fga")
8997    (set_attr "fptype" "double")])
8999 (define_insn "fexpand_vis"
9000   [(set (match_operand:V4HI 0 "register_operand" "=e")
9001         (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")]
9002          UNSPEC_FEXPAND))]
9003  "TARGET_VIS"
9004  "fexpand\t%1, %0"
9005  [(set_attr "type" "fga")
9006   (set_attr "fptype" "double")])
9008 ;; It may be possible to describe this operation as (1 indexed):
9009 ;; (vec_select (vec_duplicate (vec_duplicate (vec_concat 1 2)))
9010 ;;  1,5,10,14,19,23,28,32)
9011 ;; Note that (vec_merge:V8QI [(V4QI) (V4QI)] (10101010 = 170) doesn't work
9012 ;; because vec_merge expects all the operands to be of the same type.
9013 (define_insn "fpmerge_vis"
9014   [(set (match_operand:V8QI 0 "register_operand" "=e")
9015         (unspec:V8QI [(match_operand:V4QI 1 "register_operand" "f")
9016                       (match_operand:V4QI 2 "register_operand" "f")]
9017          UNSPEC_FPMERGE))]
9018  "TARGET_VIS"
9019  "fpmerge\t%1, %2, %0"
9020  [(set_attr "type" "fga")
9021   (set_attr "fptype" "double")])
9023 ;; Partitioned multiply instructions
9024 (define_insn "fmul8x16_vis"
9025   [(set (match_operand:V4HI 0 "register_operand" "=e")
9026         (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
9027                    (match_operand:V4HI 2 "register_operand" "e")))]
9028   "TARGET_VIS"
9029   "fmul8x16\t%1, %2, %0"
9030   [(set_attr "type" "fpmul")
9031    (set_attr "fptype" "double")])
9033 ;; Only one of the following two insns can be a multiply.
9034 (define_insn "fmul8x16au_vis"
9035   [(set (match_operand:V4HI 0 "register_operand" "=e")
9036         (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
9037                    (match_operand:V2HI 2 "register_operand" "f")))]
9038   "TARGET_VIS"
9039   "fmul8x16au\t%1, %2, %0"
9040   [(set_attr "type" "fpmul")
9041    (set_attr "fptype" "double")])
9043 (define_insn "fmul8x16al_vis"
9044   [(set (match_operand:V4HI 0 "register_operand" "=e")
9045         (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
9046                       (match_operand:V2HI 2 "register_operand" "f")]
9047          UNSPEC_MUL16AL))]
9048   "TARGET_VIS"
9049   "fmul8x16al\t%1, %2, %0"
9050   [(set_attr "type" "fpmul")
9051    (set_attr "fptype" "double")])
9053 ;; Only one of the following two insns can be a multiply.
9054 (define_insn "fmul8sux16_vis"
9055   [(set (match_operand:V4HI 0 "register_operand" "=e")
9056         (mult:V4HI (match_operand:V8QI 1 "register_operand" "e")
9057                    (match_operand:V4HI 2 "register_operand" "e")))]
9058   "TARGET_VIS"
9059   "fmul8sux16\t%1, %2, %0"
9060   [(set_attr "type" "fpmul")
9061    (set_attr "fptype" "double")])
9063 (define_insn "fmul8ulx16_vis"
9064   [(set (match_operand:V4HI 0 "register_operand" "=e")
9065         (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
9066                       (match_operand:V4HI 2 "register_operand" "e")]
9067          UNSPEC_MUL8UL))]
9068   "TARGET_VIS"
9069   "fmul8ulx16\t%1, %2, %0"
9070   [(set_attr "type" "fpmul")
9071    (set_attr "fptype" "double")])
9073 ;; Only one of the following two insns can be a multiply.
9074 (define_insn "fmuld8sux16_vis"
9075   [(set (match_operand:V2SI 0 "register_operand" "=e")
9076         (mult:V2SI (match_operand:V4QI 1 "register_operand" "f")
9077                    (match_operand:V2HI 2 "register_operand" "f")))]
9078   "TARGET_VIS"
9079   "fmuld8sux16\t%1, %2, %0"
9080   [(set_attr "type" "fpmul")
9081    (set_attr "fptype" "double")])
9083 (define_insn "fmuld8ulx16_vis"
9084   [(set (match_operand:V2SI 0 "register_operand" "=e")
9085         (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
9086                       (match_operand:V2HI 2 "register_operand" "f")]
9087          UNSPEC_MULDUL))]
9088   "TARGET_VIS"
9089   "fmuld8ulx16\t%1, %2, %0"
9090   [(set_attr "type" "fpmul")
9091    (set_attr "fptype" "double")])
9093 ;; Using faligndata only makes sense after an alignaddr since the choice of
9094 ;; bytes to take out of each operand is dependant on the results of the last
9095 ;; alignaddr.
9096 (define_insn "faligndata<V64I:mode>_vis"
9097   [(set (match_operand:V64I 0 "register_operand" "=e")
9098         (unspec:V64I [(match_operand:V64I 1 "register_operand" "e")
9099                       (match_operand:V64I 2 "register_operand" "e")]
9100          UNSPEC_ALIGNDATA))]
9101   "TARGET_VIS"
9102   "faligndata\t%1, %2, %0"
9103   [(set_attr "type" "fga")
9104    (set_attr "fptype" "double")])
9106 (define_mode_macro P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
9108 (define_insn "alignaddr<P:mode>_vis"
9109   [(set (match_operand:P 0 "register_operand" "=r")
9110         (unspec:P [(match_operand:P 1 "reg_or_0_operand" "rJ")
9111                    (match_operand:P 2 "reg_or_0_operand" "rJ")]
9112          UNSPEC_ALIGNADDR))]
9113   "TARGET_VIS"
9114   "alignaddr\t%r1, %r2, %0")
9116 (define_insn "pdist_vis"
9117   [(set (match_operand:DI 0 "register_operand" "=e")
9118         (unspec:DI [(match_operand:V8QI 1 "register_operand" "e")
9119                     (match_operand:V8QI 2 "register_operand" "e")
9120                     (match_operand:DI 3 "register_operand" "0")]
9121          UNSPEC_PDIST))]
9122   "TARGET_VIS"
9123   "pdist\t%1, %2, %0"
9124   [(set_attr "type" "fga")
9125    (set_attr "fptype" "double")])