Merge from mainline (gomp-merge-2005-02-26).
[official-gcc.git] / gcc / config / sparc / sparc.md
blob6153b5adbe68919a4a4c5346195ad62c262d4105
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 (define_mode_macro P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
73 ;; The upper 32 fp regs on the v9 can't hold SFmode values.  To deal with this
74 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip.  The name
75 ;; is a bit of a misnomer as it covers all 64 fp regs.  The corresponding
76 ;; constraint letter is 'e'.  To avoid any confusion, 'e' is used instead of
77 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
79 ;; Attribute for cpu type.
80 ;; These must match the values for enum processor_type in sparc.h.
81 (define_attr "cpu"
82   "v7,
83    cypress,
84    v8,
85    supersparc,
86    sparclite,f930,f934,
87    hypersparc,sparclite86x,
88    sparclet,tsc701,
89    v9,
90    ultrasparc,
91    ultrasparc3"
92   (const (symbol_ref "sparc_cpu_attr")))
94 ;; Attribute for the instruction set.
95 ;; At present we only need to distinguish v9/!v9, but for clarity we
96 ;; test TARGET_V8 too.
97 (define_attr "isa" "v7,v8,v9,sparclet"
98  (const
99   (cond [(symbol_ref "TARGET_V9") (const_string "v9")
100          (symbol_ref "TARGET_V8") (const_string "v8")
101          (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
102         (const_string "v7"))))
104 ;; Insn type.
105 (define_attr "type"
106   "ialu,compare,shift,
107    load,sload,store,
108    uncond_branch,branch,call,sibcall,call_no_delay_slot,return,
109    imul,idiv,
110    fpload,fpstore,
111    fp,fpmove,
112    fpcmove,fpcrmove,
113    fpcmp,
114    fpmul,fpdivs,fpdivd,
115    fpsqrts,fpsqrtd,
116    fga,fgm_pack,fgm_mul,fgm_pdist,fgm_cmp,
117    cmove,
118    ialuX,
119    multi,savew,flushw,iflush,trap"
120   (const_string "ialu"))
122 ;; True if branch/call has empty delay slot and will emit a nop in it
123 (define_attr "empty_delay_slot" "false,true"
124   (symbol_ref "empty_delay_slot (insn)"))
126 (define_attr "branch_type" "none,icc,fcc,reg"
127   (const_string "none"))
129 (define_attr "pic" "false,true"
130   (symbol_ref "flag_pic != 0"))
132 (define_attr "calls_alloca" "false,true"
133   (symbol_ref "current_function_calls_alloca != 0"))
135 (define_attr "calls_eh_return" "false,true"
136    (symbol_ref "current_function_calls_eh_return !=0 "))
137    
138 (define_attr "leaf_function" "false,true"
139   (symbol_ref "current_function_uses_only_leaf_regs != 0"))
141 (define_attr "delayed_branch" "false,true"
142   (symbol_ref "flag_delayed_branch != 0"))
144 ;; Length (in # of insns).
145 ;; Beware that setting a length greater or equal to 3 for conditional branches
146 ;; has a side-effect (see output_cbranch and output_v9branch).
147 (define_attr "length" ""
148   (cond [(eq_attr "type" "uncond_branch,call")
149            (if_then_else (eq_attr "empty_delay_slot" "true")
150              (const_int 2)
151              (const_int 1))
152          (eq_attr "type" "sibcall")
153            (if_then_else (eq_attr "leaf_function" "true")
154              (if_then_else (eq_attr "empty_delay_slot" "true")
155                (const_int 3)
156                (const_int 2))
157              (if_then_else (eq_attr "empty_delay_slot" "true")
158                (const_int 2)
159                (const_int 1)))
160          (eq_attr "branch_type" "icc")
161            (if_then_else (match_operand 0 "noov_compare64_op" "")
162              (if_then_else (lt (pc) (match_dup 1))
163                (if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000))
164                  (if_then_else (eq_attr "empty_delay_slot" "true")
165                    (const_int 2)
166                    (const_int 1))
167                  (if_then_else (eq_attr "empty_delay_slot" "true")
168                    (const_int 4)
169                    (const_int 3)))
170                (if_then_else (lt (minus (pc) (match_dup 1)) (const_int 260000))
171                  (if_then_else (eq_attr "empty_delay_slot" "true")
172                    (const_int 2)
173                    (const_int 1))
174                  (if_then_else (eq_attr "empty_delay_slot" "true")
175                    (const_int 4)
176                    (const_int 3))))
177              (if_then_else (eq_attr "empty_delay_slot" "true")
178                (const_int 2)
179                (const_int 1)))
180          (eq_attr "branch_type" "fcc")
181            (if_then_else (match_operand 0 "fcc0_reg_operand" "")
182              (if_then_else (eq_attr "empty_delay_slot" "true")
183                (if_then_else (eq (symbol_ref "TARGET_V9") (const_int 0))
184                  (const_int 3)
185                  (const_int 2))
186                (if_then_else (eq (symbol_ref "TARGET_V9") (const_int 0))
187                  (const_int 2)
188                  (const_int 1)))
189              (if_then_else (lt (pc) (match_dup 2))
190                (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000))
191                  (if_then_else (eq_attr "empty_delay_slot" "true")
192                    (const_int 2)
193                    (const_int 1))
194                  (if_then_else (eq_attr "empty_delay_slot" "true")
195                    (const_int 4)
196                    (const_int 3)))
197                (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000))
198                  (if_then_else (eq_attr "empty_delay_slot" "true")
199                    (const_int 2)
200                    (const_int 1))
201                  (if_then_else (eq_attr "empty_delay_slot" "true")
202                    (const_int 4)
203                    (const_int 3)))))
204          (eq_attr "branch_type" "reg")
205            (if_then_else (lt (pc) (match_dup 2))
206              (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000))
207                (if_then_else (eq_attr "empty_delay_slot" "true")
208                  (const_int 2)
209                  (const_int 1))
210                (if_then_else (eq_attr "empty_delay_slot" "true")
211                  (const_int 4)
212                  (const_int 3)))
213              (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000))
214                (if_then_else (eq_attr "empty_delay_slot" "true")
215                  (const_int 2)
216                  (const_int 1))
217                (if_then_else (eq_attr "empty_delay_slot" "true")
218                  (const_int 4)
219                  (const_int 3))))
220          ] (const_int 1)))
222 ;; FP precision.
223 (define_attr "fptype" "single,double"
224   (const_string "single"))
226 ;; UltraSPARC-III integer load type.
227 (define_attr "us3load_type" "2cycle,3cycle"
228   (const_string "2cycle"))
230 (define_asm_attributes
231   [(set_attr "length" "2")
232    (set_attr "type" "multi")])
234 ;; Attributes for instruction and branch scheduling
235 (define_attr "tls_call_delay" "false,true"
236   (symbol_ref "tls_call_delay (insn)"))
238 (define_attr "in_call_delay" "false,true"
239   (cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
240                 (const_string "false")
241          (eq_attr "type" "load,fpload,store,fpstore")
242                 (if_then_else (eq_attr "length" "1")
243                               (const_string "true")
244                               (const_string "false"))]
245         (if_then_else (and (eq_attr "length" "1")
246                            (eq_attr "tls_call_delay" "true"))
247                       (const_string "true")
248                       (const_string "false"))))
250 (define_attr "eligible_for_sibcall_delay" "false,true"
251   (symbol_ref "eligible_for_sibcall_delay (insn)"))
253 (define_attr "eligible_for_return_delay" "false,true"
254   (symbol_ref "eligible_for_return_delay (insn)"))
256 ;; ??? !v9: Should implement the notion of predelay slots for floating-point
257 ;; branches.  This would allow us to remove the nop always inserted before
258 ;; a floating point branch.
260 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
261 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
262 ;; This is because doing so will add several pipeline stalls to the path
263 ;; that the load/store did not come from.  Unfortunately, there is no way
264 ;; to prevent fill_eager_delay_slots from using load/store without completely
265 ;; disabling them.  For the SPEC benchmark set, this is a serious lose,
266 ;; because it prevents us from moving back the final store of inner loops.
268 (define_attr "in_branch_delay" "false,true"
269   (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
270                      (eq_attr "length" "1"))
271                 (const_string "true")
272                 (const_string "false")))
274 (define_attr "in_uncond_branch_delay" "false,true"
275   (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
276                      (eq_attr "length" "1"))
277                 (const_string "true")
278                 (const_string "false")))
280 (define_attr "in_annul_branch_delay" "false,true"
281   (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
282                      (eq_attr "length" "1"))
283                 (const_string "true")
284                 (const_string "false")))
286 (define_delay (eq_attr "type" "call")
287   [(eq_attr "in_call_delay" "true") (nil) (nil)])
289 (define_delay (eq_attr "type" "sibcall")
290   [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
292 (define_delay (eq_attr "type" "branch")
293   [(eq_attr "in_branch_delay" "true")
294    (nil) (eq_attr "in_annul_branch_delay" "true")])
296 (define_delay (eq_attr "type" "uncond_branch")
297   [(eq_attr "in_uncond_branch_delay" "true")
298    (nil) (nil)])
300 (define_delay (eq_attr "type" "return")
301   [(eq_attr "eligible_for_return_delay" "true") (nil) (nil)])
303 ;; Include SPARC DFA schedulers
305 (include "cypress.md")
306 (include "supersparc.md")
307 (include "hypersparc.md")
308 (include "sparclet.md")
309 (include "ultra1_2.md")
310 (include "ultra3.md")
313 ;; Compare instructions.
314 ;; This controls RTL generation and register allocation.
316 ;; We generate RTL for comparisons and branches by having the cmpxx 
317 ;; patterns store away the operands.  Then, the scc and bcc patterns
318 ;; emit RTL for both the compare and the branch.
320 ;; We do this because we want to generate different code for an sne and
321 ;; seq insn.  In those cases, if the second operand of the compare is not
322 ;; const0_rtx, we want to compute the xor of the two operands and test
323 ;; it against zero.
325 ;; We start with the DEFINE_EXPANDs, then the DEFINE_INSNs to match
326 ;; the patterns.  Finally, we have the DEFINE_SPLITs for some of the scc
327 ;; insns that actually require more than one machine instruction.
329 ;; Put cmpsi first among compare insns so it matches two CONST_INT operands.
331 (define_expand "cmpsi"
332   [(set (reg:CC 100)
333         (compare:CC (match_operand:SI 0 "compare_operand" "")
334                     (match_operand:SI 1 "arith_operand" "")))]
335   ""
337   if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx)
338     operands[0] = force_reg (SImode, operands[0]);
340   sparc_compare_op0 = operands[0];
341   sparc_compare_op1 = operands[1];
342   DONE;
345 (define_expand "cmpdi"
346   [(set (reg:CCX 100)
347         (compare:CCX (match_operand:DI 0 "compare_operand" "")
348                      (match_operand:DI 1 "arith_double_operand" "")))]
349   "TARGET_ARCH64"
351   if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx)
352     operands[0] = force_reg (DImode, operands[0]);
354   sparc_compare_op0 = operands[0];
355   sparc_compare_op1 = operands[1];
356   DONE;
359 (define_expand "cmpsf"
360   ;; The 96 here isn't ever used by anyone.
361   [(set (reg:CCFP 96)
362         (compare:CCFP (match_operand:SF 0 "register_operand" "")
363                       (match_operand:SF 1 "register_operand" "")))]
364   "TARGET_FPU"
366   sparc_compare_op0 = operands[0];
367   sparc_compare_op1 = operands[1];
368   DONE;
371 (define_expand "cmpdf"
372   ;; The 96 here isn't ever used by anyone.
373   [(set (reg:CCFP 96)
374         (compare:CCFP (match_operand:DF 0 "register_operand" "")
375                       (match_operand:DF 1 "register_operand" "")))]
376   "TARGET_FPU"
378   sparc_compare_op0 = operands[0];
379   sparc_compare_op1 = operands[1];
380   DONE;
383 (define_expand "cmptf"
384   ;; The 96 here isn't ever used by anyone.
385   [(set (reg:CCFP 96)
386         (compare:CCFP (match_operand:TF 0 "register_operand" "")
387                       (match_operand:TF 1 "register_operand" "")))]
388   "TARGET_FPU"
390   sparc_compare_op0 = operands[0];
391   sparc_compare_op1 = operands[1];
392   DONE;
395 ;; Now the compare DEFINE_INSNs.
397 (define_insn "*cmpsi_insn"
398   [(set (reg:CC 100)
399         (compare:CC (match_operand:SI 0 "register_operand" "r")
400                     (match_operand:SI 1 "arith_operand" "rI")))]
401   ""
402   "cmp\t%0, %1"
403   [(set_attr "type" "compare")])
405 (define_insn "*cmpdi_sp64"
406   [(set (reg:CCX 100)
407         (compare:CCX (match_operand:DI 0 "register_operand" "r")
408                      (match_operand:DI 1 "arith_double_operand" "rHI")))]
409   "TARGET_ARCH64"
410   "cmp\t%0, %1"
411   [(set_attr "type" "compare")])
413 (define_insn "*cmpsf_fpe"
414   [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
415         (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
416                        (match_operand:SF 2 "register_operand" "f")))]
417   "TARGET_FPU"
419   if (TARGET_V9)
420     return "fcmpes\t%0, %1, %2";
421   return "fcmpes\t%1, %2";
423   [(set_attr "type" "fpcmp")])
425 (define_insn "*cmpdf_fpe"
426   [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
427         (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
428                        (match_operand:DF 2 "register_operand" "e")))]
429   "TARGET_FPU"
431   if (TARGET_V9)
432     return "fcmped\t%0, %1, %2";
433   return "fcmped\t%1, %2";
435   [(set_attr "type" "fpcmp")
436    (set_attr "fptype" "double")])
438 (define_insn "*cmptf_fpe"
439   [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c")
440         (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
441                        (match_operand:TF 2 "register_operand" "e")))]
442   "TARGET_FPU && TARGET_HARD_QUAD"
444   if (TARGET_V9)
445     return "fcmpeq\t%0, %1, %2";
446   return "fcmpeq\t%1, %2";
448   [(set_attr "type" "fpcmp")])
450 (define_insn "*cmpsf_fp"
451   [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
452         (compare:CCFP (match_operand:SF 1 "register_operand" "f")
453                       (match_operand:SF 2 "register_operand" "f")))]
454   "TARGET_FPU"
456   if (TARGET_V9)
457     return "fcmps\t%0, %1, %2";
458   return "fcmps\t%1, %2";
460   [(set_attr "type" "fpcmp")])
462 (define_insn "*cmpdf_fp"
463   [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
464         (compare:CCFP (match_operand:DF 1 "register_operand" "e")
465                       (match_operand:DF 2 "register_operand" "e")))]
466   "TARGET_FPU"
468   if (TARGET_V9)
469     return "fcmpd\t%0, %1, %2";
470   return "fcmpd\t%1, %2";
472   [(set_attr "type" "fpcmp")
473    (set_attr "fptype" "double")])
475 (define_insn "*cmptf_fp"
476   [(set (match_operand:CCFP 0 "fcc_reg_operand" "=c")
477         (compare:CCFP (match_operand:TF 1 "register_operand" "e")
478                       (match_operand:TF 2 "register_operand" "e")))]
479   "TARGET_FPU && TARGET_HARD_QUAD"
481   if (TARGET_V9)
482     return "fcmpq\t%0, %1, %2";
483   return "fcmpq\t%1, %2";
485   [(set_attr "type" "fpcmp")])
487 ;; Next come the scc insns.  For seq, sne, sgeu, and sltu, we can do this
488 ;; without jumps using the addx/subx instructions.  For seq/sne on v9 we use
489 ;; the same code as v8 (the addx/subx method has more applications).  The
490 ;; exception to this is "reg != 0" which can be done in one instruction on v9
491 ;; (so we do it).  For the rest, on v9 we use conditional moves; on v8, we do
492 ;; branches.
494 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
495 ;; generate addcc/subcc instructions.
497 (define_expand "seqsi_special"
498   [(set (match_dup 3)
499         (xor:SI (match_operand:SI 1 "register_operand" "")
500                 (match_operand:SI 2 "register_operand" "")))
501    (parallel [(set (match_operand:SI 0 "register_operand" "")
502                    (eq:SI (match_dup 3) (const_int 0)))
503               (clobber (reg:CC 100))])]
504   ""
505   { operands[3] = gen_reg_rtx (SImode); })
507 (define_expand "seqdi_special"
508   [(set (match_dup 3)
509         (xor:DI (match_operand:DI 1 "register_operand" "")
510                 (match_operand:DI 2 "register_operand" "")))
511    (set (match_operand:DI 0 "register_operand" "")
512         (eq:DI (match_dup 3) (const_int 0)))]
513   "TARGET_ARCH64"
514   { operands[3] = gen_reg_rtx (DImode); })
516 (define_expand "snesi_special"
517   [(set (match_dup 3)
518         (xor:SI (match_operand:SI 1 "register_operand" "")
519                 (match_operand:SI 2 "register_operand" "")))
520    (parallel [(set (match_operand:SI 0 "register_operand" "")
521                    (ne:SI (match_dup 3) (const_int 0)))
522               (clobber (reg:CC 100))])]
523   ""
524   { operands[3] = gen_reg_rtx (SImode); })
526 (define_expand "snedi_special"
527   [(set (match_dup 3)
528         (xor:DI (match_operand:DI 1 "register_operand" "")
529                 (match_operand:DI 2 "register_operand" "")))
530    (set (match_operand:DI 0 "register_operand" "")
531         (ne:DI (match_dup 3) (const_int 0)))]
532   "TARGET_ARCH64"
533   { operands[3] = gen_reg_rtx (DImode); })
535 (define_expand "seqdi_special_trunc"
536   [(set (match_dup 3)
537         (xor:DI (match_operand:DI 1 "register_operand" "")
538                 (match_operand:DI 2 "register_operand" "")))
539    (set (match_operand:SI 0 "register_operand" "")
540         (eq:SI (match_dup 3) (const_int 0)))]
541   "TARGET_ARCH64"
542   { operands[3] = gen_reg_rtx (DImode); })
544 (define_expand "snedi_special_trunc"
545   [(set (match_dup 3)
546         (xor:DI (match_operand:DI 1 "register_operand" "")
547                 (match_operand:DI 2 "register_operand" "")))
548    (set (match_operand:SI 0 "register_operand" "")
549         (ne:SI (match_dup 3) (const_int 0)))]
550   "TARGET_ARCH64"
551   { operands[3] = gen_reg_rtx (DImode); })
553 (define_expand "seqsi_special_extend"
554   [(set (match_dup 3)
555         (xor:SI (match_operand:SI 1 "register_operand" "")
556                 (match_operand:SI 2 "register_operand" "")))
557    (parallel [(set (match_operand:DI 0 "register_operand" "")
558                    (eq:DI (match_dup 3) (const_int 0)))
559               (clobber (reg:CC 100))])]
560   "TARGET_ARCH64"
561   { operands[3] = gen_reg_rtx (SImode); })
563 (define_expand "snesi_special_extend"
564   [(set (match_dup 3)
565         (xor:SI (match_operand:SI 1 "register_operand" "")
566                 (match_operand:SI 2 "register_operand" "")))
567    (parallel [(set (match_operand:DI 0 "register_operand" "")
568                    (ne:DI (match_dup 3) (const_int 0)))
569               (clobber (reg:CC 100))])]
570   "TARGET_ARCH64"
571   { operands[3] = gen_reg_rtx (SImode); })
573 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
574 ;; However, the code handles both SImode and DImode.
575 (define_expand "seq"
576   [(set (match_operand:SI 0 "intreg_operand" "")
577         (eq:SI (match_dup 1) (const_int 0)))]
578   ""
580   if (GET_MODE (sparc_compare_op0) == SImode)
581     {
582       rtx pat;
584       if (GET_MODE (operands[0]) == SImode)
585         pat = gen_seqsi_special (operands[0], sparc_compare_op0,
586                                  sparc_compare_op1);
587       else if (! TARGET_ARCH64)
588         FAIL;
589       else
590         pat = gen_seqsi_special_extend (operands[0], sparc_compare_op0,
591                                         sparc_compare_op1);
592       emit_insn (pat);
593       DONE;
594     }
595   else if (GET_MODE (sparc_compare_op0) == DImode)
596     {
597       rtx pat;
599       if (! TARGET_ARCH64)
600         FAIL;
601       else if (GET_MODE (operands[0]) == SImode)
602         pat = gen_seqdi_special_trunc (operands[0], sparc_compare_op0,
603                                        sparc_compare_op1);
604       else
605         pat = gen_seqdi_special (operands[0], sparc_compare_op0,
606                                  sparc_compare_op1);
607       emit_insn (pat);
608       DONE;
609     }
610   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
611     {
612       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
613       emit_jump_insn (gen_sne (operands[0]));
614       DONE;
615     }
616   else if (TARGET_V9)
617     {
618       if (gen_v9_scc (EQ, operands))
619         DONE;
620       /* fall through */
621     }
622   FAIL;
625 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
626 ;; However, the code handles both SImode and DImode.
627 (define_expand "sne"
628   [(set (match_operand:SI 0 "intreg_operand" "")
629         (ne:SI (match_dup 1) (const_int 0)))]
630   ""
632   if (GET_MODE (sparc_compare_op0) == SImode)
633     {
634       rtx pat;
636       if (GET_MODE (operands[0]) == SImode)
637         pat = gen_snesi_special (operands[0], sparc_compare_op0,
638                                  sparc_compare_op1);
639       else if (! TARGET_ARCH64)
640         FAIL;
641       else
642         pat = gen_snesi_special_extend (operands[0], sparc_compare_op0,
643                                         sparc_compare_op1);
644       emit_insn (pat);
645       DONE;
646     }
647   else if (GET_MODE (sparc_compare_op0) == DImode)
648     {
649       rtx pat;
651       if (! TARGET_ARCH64)
652         FAIL;
653       else if (GET_MODE (operands[0]) == SImode)
654         pat = gen_snedi_special_trunc (operands[0], sparc_compare_op0,
655                                        sparc_compare_op1);
656       else
657         pat = gen_snedi_special (operands[0], sparc_compare_op0,
658                                  sparc_compare_op1);
659       emit_insn (pat);
660       DONE;
661     }
662   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
663     {
664       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
665       emit_jump_insn (gen_sne (operands[0]));
666       DONE;
667     }
668   else if (TARGET_V9)
669     {
670       if (gen_v9_scc (NE, operands))
671         DONE;
672       /* fall through */
673     }
674   FAIL;
677 (define_expand "sgt"
678   [(set (match_operand:SI 0 "intreg_operand" "")
679         (gt:SI (match_dup 1) (const_int 0)))]
680   ""
682   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
683     {
684       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
685       emit_jump_insn (gen_sne (operands[0]));
686       DONE;
687     }
688   else if (TARGET_V9)
689     {
690       if (gen_v9_scc (GT, operands))
691         DONE;
692       /* fall through */
693     }
694   FAIL;
697 (define_expand "slt"
698   [(set (match_operand:SI 0 "intreg_operand" "")
699         (lt:SI (match_dup 1) (const_int 0)))]
700   ""
702   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
703     {
704       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
705       emit_jump_insn (gen_sne (operands[0]));
706       DONE;
707     }
708   else if (TARGET_V9)
709     {
710       if (gen_v9_scc (LT, operands))
711         DONE;
712       /* fall through */
713     }
714   FAIL;
717 (define_expand "sge"
718   [(set (match_operand:SI 0 "intreg_operand" "")
719         (ge:SI (match_dup 1) (const_int 0)))]
720   ""
722   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
723     {
724       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
725       emit_jump_insn (gen_sne (operands[0]));
726       DONE;
727     }
728   else if (TARGET_V9)
729     {
730       if (gen_v9_scc (GE, operands))
731         DONE;
732       /* fall through */
733     }
734   FAIL;
737 (define_expand "sle"
738   [(set (match_operand:SI 0 "intreg_operand" "")
739         (le:SI (match_dup 1) (const_int 0)))]
740   ""
742   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
743     {
744       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
745       emit_jump_insn (gen_sne (operands[0]));
746       DONE;
747     }
748   else if (TARGET_V9)
749     {
750       if (gen_v9_scc (LE, operands))
751         DONE;
752       /* fall through */
753     }
754   FAIL;
757 (define_expand "sgtu"
758   [(set (match_operand:SI 0 "intreg_operand" "")
759         (gtu:SI (match_dup 1) (const_int 0)))]
760   ""
762   if (! TARGET_V9)
763     {
764       rtx tem, pat;
766       /* We can do ltu easily, so if both operands are registers, swap them and
767          do a LTU.  */
768       if ((GET_CODE (sparc_compare_op0) == REG
769            || GET_CODE (sparc_compare_op0) == SUBREG)
770           && (GET_CODE (sparc_compare_op1) == REG
771               || GET_CODE (sparc_compare_op1) == SUBREG))
772         {
773           tem = sparc_compare_op0;
774           sparc_compare_op0 = sparc_compare_op1;
775           sparc_compare_op1 = tem;
776           pat = gen_sltu (operands[0]);
777           if (pat == NULL_RTX)
778             FAIL;
779           emit_insn (pat);
780           DONE;
781         }
782     }
783   else
784     {
785       if (gen_v9_scc (GTU, operands))
786         DONE;
787     }
788   FAIL;
791 (define_expand "sltu"
792   [(set (match_operand:SI 0 "intreg_operand" "")
793         (ltu:SI (match_dup 1) (const_int 0)))]
794   ""
796   if (TARGET_V9)
797     {
798       if (gen_v9_scc (LTU, operands))
799         DONE;
800     }
801   operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
804 (define_expand "sgeu"
805   [(set (match_operand:SI 0 "intreg_operand" "")
806         (geu:SI (match_dup 1) (const_int 0)))]
807   ""
809   if (TARGET_V9)
810     {
811       if (gen_v9_scc (GEU, operands))
812         DONE;
813     }
814   operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
817 (define_expand "sleu"
818   [(set (match_operand:SI 0 "intreg_operand" "")
819         (leu:SI (match_dup 1) (const_int 0)))]
820   ""
822   if (! TARGET_V9)
823     {
824       rtx tem, pat;
826       /* We can do geu easily, so if both operands are registers, swap them and
827          do a GEU.  */
828       if ((GET_CODE (sparc_compare_op0) == REG
829            || GET_CODE (sparc_compare_op0) == SUBREG)
830           && (GET_CODE (sparc_compare_op1) == REG
831               || GET_CODE (sparc_compare_op1) == SUBREG))
832         {
833           tem = sparc_compare_op0;
834           sparc_compare_op0 = sparc_compare_op1;
835           sparc_compare_op1 = tem;
836           pat = gen_sgeu (operands[0]);
837           if (pat == NULL_RTX)
838             FAIL;
839           emit_insn (pat);
840           DONE;
841         }
842     }
843   else
844     {
845       if (gen_v9_scc (LEU, operands))
846         DONE;
847     }
848   FAIL;
851 ;; Now the DEFINE_INSNs for the scc cases.
853 ;; The SEQ and SNE patterns are special because they can be done
854 ;; without any branching and do not involve a COMPARE.  We want
855 ;; them to always use the splitz below so the results can be
856 ;; scheduled.
858 (define_insn_and_split "*snesi_zero"
859   [(set (match_operand:SI 0 "register_operand" "=r")
860         (ne:SI (match_operand:SI 1 "register_operand" "r")
861                (const_int 0)))
862    (clobber (reg:CC 100))]
863   ""
864   "#"
865   ""
866   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
867                                            (const_int 0)))
868    (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))]
869   ""
870   [(set_attr "length" "2")])
872 (define_insn_and_split "*neg_snesi_zero"
873   [(set (match_operand:SI 0 "register_operand" "=r")
874         (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
875                        (const_int 0))))
876    (clobber (reg:CC 100))]
877   ""
878   "#"
879   ""
880   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
881                                            (const_int 0)))
882    (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
883   ""
884   [(set_attr "length" "2")])
886 (define_insn_and_split "*snesi_zero_extend"
887   [(set (match_operand:DI 0 "register_operand" "=r")
888         (ne:DI (match_operand:SI 1 "register_operand" "r")
889                (const_int 0)))
890    (clobber (reg:CC 100))]
891   "TARGET_ARCH64"
892   "#"
893   "&& 1"
894   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
895                                                      (match_dup 1))
896                                            (const_int 0)))
897    (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
898                                                         (const_int 0))
899                                                (ltu:SI (reg:CC_NOOV 100)
900                                                        (const_int 0)))))]
901   ""
902   [(set_attr "length" "2")])
904 (define_insn_and_split "*snedi_zero"
905   [(set (match_operand:DI 0 "register_operand" "=&r")
906         (ne:DI (match_operand:DI 1 "register_operand" "r")
907                (const_int 0)))]
908   "TARGET_ARCH64"
909   "#"
910   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
911   [(set (match_dup 0) (const_int 0))
912    (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
913                                               (const_int 0))
914                                        (const_int 1)
915                                        (match_dup 0)))]
916   ""
917   [(set_attr "length" "2")])
919 (define_insn_and_split "*neg_snedi_zero"
920   [(set (match_operand:DI 0 "register_operand" "=&r")
921         (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
922                        (const_int 0))))]
923   "TARGET_ARCH64"
924   "#"
925   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
926   [(set (match_dup 0) (const_int 0))
927    (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
928                                               (const_int 0))
929                                        (const_int -1)
930                                        (match_dup 0)))]
931   ""
932   [(set_attr "length" "2")])
934 (define_insn_and_split "*snedi_zero_trunc"
935   [(set (match_operand:SI 0 "register_operand" "=&r")
936         (ne:SI (match_operand:DI 1 "register_operand" "r")
937                (const_int 0)))]
938   "TARGET_ARCH64"
939   "#"
940   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
941   [(set (match_dup 0) (const_int 0))
942    (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
943                                               (const_int 0))
944                                        (const_int 1)
945                                        (match_dup 0)))]
946   ""
947   [(set_attr "length" "2")])
949 (define_insn_and_split "*seqsi_zero"
950   [(set (match_operand:SI 0 "register_operand" "=r")
951         (eq:SI (match_operand:SI 1 "register_operand" "r")
952                (const_int 0)))
953    (clobber (reg:CC 100))]
954   ""
955   "#"
956   ""
957   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
958                                            (const_int 0)))
959    (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))]
960   ""
961   [(set_attr "length" "2")])
963 (define_insn_and_split "*neg_seqsi_zero"
964   [(set (match_operand:SI 0 "register_operand" "=r")
965         (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
966                        (const_int 0))))
967    (clobber (reg:CC 100))]
968   ""
969   "#"
970   ""
971   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
972                                            (const_int 0)))
973    (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
974   ""
975   [(set_attr "length" "2")])
977 (define_insn_and_split "*seqsi_zero_extend"
978   [(set (match_operand:DI 0 "register_operand" "=r")
979         (eq:DI (match_operand:SI 1 "register_operand" "r")
980                (const_int 0)))
981    (clobber (reg:CC 100))]
982   "TARGET_ARCH64"
983   "#"
984   "&& 1"
985   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
986                                                      (match_dup 1))
987                                            (const_int 0)))
988    (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
989                                                           (const_int -1))
990                                                 (ltu:SI (reg:CC_NOOV 100)
991                                                         (const_int 0)))))]
992   ""
993   [(set_attr "length" "2")])
995 (define_insn_and_split "*seqdi_zero"
996   [(set (match_operand:DI 0 "register_operand" "=&r")
997         (eq:DI (match_operand:DI 1 "register_operand" "r")
998                (const_int 0)))]
999   "TARGET_ARCH64"
1000   "#"
1001   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1002   [(set (match_dup 0) (const_int 0))
1003    (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1004                                               (const_int 0))
1005                                        (const_int 1)
1006                                        (match_dup 0)))]
1007   ""
1008   [(set_attr "length" "2")])
1010 (define_insn_and_split "*neg_seqdi_zero"
1011   [(set (match_operand:DI 0 "register_operand" "=&r")
1012         (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
1013                        (const_int 0))))]
1014   "TARGET_ARCH64"
1015   "#"
1016   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1017   [(set (match_dup 0) (const_int 0))
1018    (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1019                                               (const_int 0))
1020                                        (const_int -1)
1021                                        (match_dup 0)))]
1022   ""
1023   [(set_attr "length" "2")]) 
1025 (define_insn_and_split "*seqdi_zero_trunc"
1026   [(set (match_operand:SI 0 "register_operand" "=&r")
1027         (eq:SI (match_operand:DI 1 "register_operand" "r")
1028                (const_int 0)))]
1029   "TARGET_ARCH64"
1030   "#"
1031   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1032   [(set (match_dup 0) (const_int 0))
1033    (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
1034                                               (const_int 0))
1035                                        (const_int 1)
1036                                        (match_dup 0)))]
1037   ""
1038   [(set_attr "length" "2")])
1040 ;; We can also do (x + (i == 0)) and related, so put them in.
1041 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1042 ;; versions for v9.
1044 (define_insn_and_split "*x_plus_i_ne_0"
1045   [(set (match_operand:SI 0 "register_operand" "=r")
1046         (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
1047                         (const_int 0))
1048                  (match_operand:SI 2 "register_operand" "r")))
1049    (clobber (reg:CC 100))]
1050   ""
1051   "#"
1052   ""
1053   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1054                                            (const_int 0)))
1055    (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1056                                (match_dup 2)))]
1057   ""
1058   [(set_attr "length" "2")])
1060 (define_insn_and_split "*x_minus_i_ne_0"
1061   [(set (match_operand:SI 0 "register_operand" "=r")
1062         (minus:SI (match_operand:SI 2 "register_operand" "r")
1063                   (ne:SI (match_operand:SI 1 "register_operand" "r")
1064                          (const_int 0))))
1065    (clobber (reg:CC 100))]
1066   ""
1067   "#"
1068   ""
1069   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1070                                            (const_int 0)))
1071    (set (match_dup 0) (minus:SI (match_dup 2)
1072                                 (ltu:SI (reg:CC 100) (const_int 0))))]
1073   ""
1074   [(set_attr "length" "2")])
1076 (define_insn_and_split "*x_plus_i_eq_0"
1077   [(set (match_operand:SI 0 "register_operand" "=r")
1078         (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1079                         (const_int 0))
1080                  (match_operand:SI 2 "register_operand" "r")))
1081    (clobber (reg:CC 100))]
1082   ""
1083   "#"
1084   ""
1085   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1086                                            (const_int 0)))
1087    (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1088                                (match_dup 2)))]
1089   ""
1090   [(set_attr "length" "2")])
1092 (define_insn_and_split "*x_minus_i_eq_0"
1093   [(set (match_operand:SI 0 "register_operand" "=r")
1094         (minus:SI (match_operand:SI 2 "register_operand" "r")
1095                   (eq:SI (match_operand:SI 1 "register_operand" "r")
1096                          (const_int 0))))
1097    (clobber (reg:CC 100))]
1098   ""
1099   "#"
1100   ""
1101   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1102                                            (const_int 0)))
1103    (set (match_dup 0) (minus:SI (match_dup 2)
1104                                 (geu:SI (reg:CC 100) (const_int 0))))]
1105   ""
1106   [(set_attr "length" "2")])
1108 ;; We can also do GEU and LTU directly, but these operate after a compare.
1109 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1110 ;; versions for v9.
1112 (define_insn "*sltu_insn"
1113   [(set (match_operand:SI 0 "register_operand" "=r")
1114         (ltu:SI (reg:CC 100) (const_int 0)))]
1115   ""
1116   "addx\t%%g0, 0, %0"
1117   [(set_attr "type" "ialuX")])
1119 (define_insn "*neg_sltu_insn"
1120   [(set (match_operand:SI 0 "register_operand" "=r")
1121         (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1122   ""
1123   "subx\t%%g0, 0, %0"
1124   [(set_attr "type" "ialuX")])
1126 ;; ??? Combine should canonicalize these next two to the same pattern.
1127 (define_insn "*neg_sltu_minus_x"
1128   [(set (match_operand:SI 0 "register_operand" "=r")
1129         (minus:SI (neg:SI (ltu:SI (reg:CC 100) (const_int 0)))
1130                   (match_operand:SI 1 "arith_operand" "rI")))]
1131   ""
1132   "subx\t%%g0, %1, %0"
1133   [(set_attr "type" "ialuX")])
1135 (define_insn "*neg_sltu_plus_x"
1136   [(set (match_operand:SI 0 "register_operand" "=r")
1137         (neg:SI (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1138                          (match_operand:SI 1 "arith_operand" "rI"))))]
1139   ""
1140   "subx\t%%g0, %1, %0"
1141   [(set_attr "type" "ialuX")])
1143 (define_insn "*sgeu_insn"
1144   [(set (match_operand:SI 0 "register_operand" "=r")
1145         (geu:SI (reg:CC 100) (const_int 0)))]
1146   ""
1147   "subx\t%%g0, -1, %0"
1148   [(set_attr "type" "ialuX")])
1150 (define_insn "*neg_sgeu_insn"
1151   [(set (match_operand:SI 0 "register_operand" "=r")
1152         (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1153   ""
1154   "addx\t%%g0, -1, %0"
1155   [(set_attr "type" "ialuX")])
1157 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
1158 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1159 ;; versions for v9.
1161 (define_insn "*sltu_plus_x"
1162   [(set (match_operand:SI 0 "register_operand" "=r")
1163         (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1164                  (match_operand:SI 1 "arith_operand" "rI")))]
1165   ""
1166   "addx\t%%g0, %1, %0"
1167   [(set_attr "type" "ialuX")])
1169 (define_insn "*sltu_plus_x_plus_y"
1170   [(set (match_operand:SI 0 "register_operand" "=r")
1171         (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1172                  (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1173                           (match_operand:SI 2 "arith_operand" "rI"))))]
1174   ""
1175   "addx\t%1, %2, %0"
1176   [(set_attr "type" "ialuX")])
1178 (define_insn "*x_minus_sltu"
1179   [(set (match_operand:SI 0 "register_operand" "=r")
1180         (minus:SI (match_operand:SI 1 "register_operand" "r")
1181                   (ltu:SI (reg:CC 100) (const_int 0))))]
1182   ""
1183   "subx\t%1, 0, %0"
1184   [(set_attr "type" "ialuX")])
1186 ;; ??? Combine should canonicalize these next two to the same pattern.
1187 (define_insn "*x_minus_y_minus_sltu"
1188   [(set (match_operand:SI 0 "register_operand" "=r")
1189         (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1190                             (match_operand:SI 2 "arith_operand" "rI"))
1191                   (ltu:SI (reg:CC 100) (const_int 0))))]
1192   ""
1193   "subx\t%r1, %2, %0"
1194   [(set_attr "type" "ialuX")])
1196 (define_insn "*x_minus_sltu_plus_y"
1197   [(set (match_operand:SI 0 "register_operand" "=r")
1198         (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
1199                   (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1200                            (match_operand:SI 2 "arith_operand" "rI"))))]
1201   ""
1202   "subx\t%r1, %2, %0"
1203   [(set_attr "type" "ialuX")])
1205 (define_insn "*sgeu_plus_x"
1206   [(set (match_operand:SI 0 "register_operand" "=r")
1207         (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1208                  (match_operand:SI 1 "register_operand" "r")))]
1209   ""
1210   "subx\t%1, -1, %0"
1211   [(set_attr "type" "ialuX")])
1213 (define_insn "*x_minus_sgeu"
1214   [(set (match_operand:SI 0 "register_operand" "=r")
1215         (minus:SI (match_operand:SI 1 "register_operand" "r")
1216                   (geu:SI (reg:CC 100) (const_int 0))))]
1217   ""
1218   "addx\t%1, -1, %0"
1219   [(set_attr "type" "ialuX")])
1221 (define_split
1222   [(set (match_operand:SI 0 "register_operand" "")
1223         (match_operator:SI 2 "noov_compare_op"
1224                            [(match_operand 1 "icc_or_fcc_reg_operand" "")
1225                             (const_int 0)]))]
1226   "TARGET_V9
1227    && REGNO (operands[1]) == SPARC_ICC_REG
1228    && (GET_MODE (operands[1]) == CCXmode
1229        /* 32 bit LTU/GEU are better implemented using addx/subx.  */
1230        || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1231   [(set (match_dup 0) (const_int 0))
1232    (set (match_dup 0)
1233         (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1234                          (const_int 1)
1235                          (match_dup 0)))]
1236   "")
1239 ;; These control RTL generation for conditional jump insns
1241 ;; The quad-word fp compare library routines all return nonzero to indicate
1242 ;; true, which is different from the equivalent libgcc routines, so we must
1243 ;; handle them specially here.
1245 (define_expand "beq"
1246   [(set (pc)
1247         (if_then_else (eq (match_dup 1) (const_int 0))
1248                       (label_ref (match_operand 0 "" ""))
1249                       (pc)))]
1250   ""
1252   if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1253       && GET_CODE (sparc_compare_op0) == REG
1254       && GET_MODE (sparc_compare_op0) == DImode)
1255     {
1256       emit_v9_brxx_insn (EQ, sparc_compare_op0, operands[0]);
1257       DONE;
1258     }
1259   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1260     {
1261       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
1262       emit_jump_insn (gen_bne (operands[0]));
1263       DONE;
1264     }
1265   operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1);
1268 (define_expand "bne"
1269   [(set (pc)
1270         (if_then_else (ne (match_dup 1) (const_int 0))
1271                       (label_ref (match_operand 0 "" ""))
1272                       (pc)))]
1273   ""
1275   if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1276       && GET_CODE (sparc_compare_op0) == REG
1277       && GET_MODE (sparc_compare_op0) == DImode)
1278     {
1279       emit_v9_brxx_insn (NE, sparc_compare_op0, operands[0]);
1280       DONE;
1281     }
1282   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1283     {
1284       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
1285       emit_jump_insn (gen_bne (operands[0]));
1286       DONE;
1287     }
1288   operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1);
1291 (define_expand "bgt"
1292   [(set (pc)
1293         (if_then_else (gt (match_dup 1) (const_int 0))
1294                       (label_ref (match_operand 0 "" ""))
1295                       (pc)))]
1296   ""
1298   if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1299       && GET_CODE (sparc_compare_op0) == REG
1300       && GET_MODE (sparc_compare_op0) == DImode)
1301     {
1302       emit_v9_brxx_insn (GT, sparc_compare_op0, operands[0]);
1303       DONE;
1304     }
1305   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1306     {
1307       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
1308       emit_jump_insn (gen_bne (operands[0]));
1309       DONE;
1310     }
1311   operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1);
1314 (define_expand "bgtu"
1315   [(set (pc)
1316         (if_then_else (gtu (match_dup 1) (const_int 0))
1317                       (label_ref (match_operand 0 "" ""))
1318                       (pc)))]
1319   ""
1321   operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1);
1324 (define_expand "blt"
1325   [(set (pc)
1326         (if_then_else (lt (match_dup 1) (const_int 0))
1327                       (label_ref (match_operand 0 "" ""))
1328                       (pc)))]
1329   ""
1331   if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1332       && GET_CODE (sparc_compare_op0) == REG
1333       && GET_MODE (sparc_compare_op0) == DImode)
1334     {
1335       emit_v9_brxx_insn (LT, sparc_compare_op0, operands[0]);
1336       DONE;
1337     }
1338   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1339     {
1340       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
1341       emit_jump_insn (gen_bne (operands[0]));
1342       DONE;
1343     }
1344   operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1);
1347 (define_expand "bltu"
1348   [(set (pc)
1349         (if_then_else (ltu (match_dup 1) (const_int 0))
1350                       (label_ref (match_operand 0 "" ""))
1351                       (pc)))]
1352   ""
1354   operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
1357 (define_expand "bge"
1358   [(set (pc)
1359         (if_then_else (ge (match_dup 1) (const_int 0))
1360                       (label_ref (match_operand 0 "" ""))
1361                       (pc)))]
1362   ""
1364   if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1365       && GET_CODE (sparc_compare_op0) == REG
1366       && GET_MODE (sparc_compare_op0) == DImode)
1367     {
1368       emit_v9_brxx_insn (GE, sparc_compare_op0, operands[0]);
1369       DONE;
1370     }
1371   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1372     {
1373       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
1374       emit_jump_insn (gen_bne (operands[0]));
1375       DONE;
1376     }
1377   operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1);
1380 (define_expand "bgeu"
1381   [(set (pc)
1382         (if_then_else (geu (match_dup 1) (const_int 0))
1383                       (label_ref (match_operand 0 "" ""))
1384                       (pc)))]
1385   ""
1387   operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
1390 (define_expand "ble"
1391   [(set (pc)
1392         (if_then_else (le (match_dup 1) (const_int 0))
1393                       (label_ref (match_operand 0 "" ""))
1394                       (pc)))]
1395   ""
1397   if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1398       && GET_CODE (sparc_compare_op0) == REG
1399       && GET_MODE (sparc_compare_op0) == DImode)
1400     {
1401       emit_v9_brxx_insn (LE, sparc_compare_op0, operands[0]);
1402       DONE;
1403     }
1404   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1405     {
1406       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
1407       emit_jump_insn (gen_bne (operands[0]));
1408       DONE;
1409     }
1410   operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1);
1413 (define_expand "bleu"
1414   [(set (pc)
1415         (if_then_else (leu (match_dup 1) (const_int 0))
1416                       (label_ref (match_operand 0 "" ""))
1417                       (pc)))]
1418   ""
1420   operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
1423 (define_expand "bunordered"
1424   [(set (pc)
1425         (if_then_else (unordered (match_dup 1) (const_int 0))
1426                       (label_ref (match_operand 0 "" ""))
1427                       (pc)))]
1428   ""
1430   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1431     {
1432       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1,
1433                                 UNORDERED);
1434       emit_jump_insn (gen_beq (operands[0]));
1435       DONE;
1436     }
1437   operands[1] = gen_compare_reg (UNORDERED, sparc_compare_op0,
1438                                  sparc_compare_op1);
1441 (define_expand "bordered"
1442   [(set (pc)
1443         (if_then_else (ordered (match_dup 1) (const_int 0))
1444                       (label_ref (match_operand 0 "" ""))
1445                       (pc)))]
1446   ""
1448   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1449     {
1450       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, ORDERED);
1451       emit_jump_insn (gen_bne (operands[0]));
1452       DONE;
1453     }
1454   operands[1] = gen_compare_reg (ORDERED, sparc_compare_op0,
1455                                  sparc_compare_op1);
1458 (define_expand "bungt"
1459   [(set (pc)
1460         (if_then_else (ungt (match_dup 1) (const_int 0))
1461                       (label_ref (match_operand 0 "" ""))
1462                       (pc)))]
1463   ""
1465   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1466     {
1467       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGT);
1468       emit_jump_insn (gen_bgt (operands[0]));
1469       DONE;
1470     }
1471   operands[1] = gen_compare_reg (UNGT, sparc_compare_op0, sparc_compare_op1);
1474 (define_expand "bunlt"
1475   [(set (pc)
1476         (if_then_else (unlt (match_dup 1) (const_int 0))
1477                       (label_ref (match_operand 0 "" ""))
1478                       (pc)))]
1479   ""
1481   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1482     {
1483       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLT);
1484       emit_jump_insn (gen_bne (operands[0]));
1485       DONE;
1486     }
1487   operands[1] = gen_compare_reg (UNLT, sparc_compare_op0, sparc_compare_op1);
1490 (define_expand "buneq"
1491   [(set (pc)
1492         (if_then_else (uneq (match_dup 1) (const_int 0))
1493                       (label_ref (match_operand 0 "" ""))
1494                       (pc)))]
1495   ""
1497   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1498     {
1499       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNEQ);
1500       emit_jump_insn (gen_beq (operands[0]));
1501       DONE;
1502     }
1503   operands[1] = gen_compare_reg (UNEQ, sparc_compare_op0, sparc_compare_op1);
1506 (define_expand "bunge"
1507   [(set (pc)
1508         (if_then_else (unge (match_dup 1) (const_int 0))
1509                       (label_ref (match_operand 0 "" ""))
1510                       (pc)))]
1511   ""
1513   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1514     {
1515       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGE);
1516       emit_jump_insn (gen_bne (operands[0]));
1517       DONE;
1518     }
1519   operands[1] = gen_compare_reg (UNGE, sparc_compare_op0, sparc_compare_op1);
1522 (define_expand "bunle"
1523   [(set (pc)
1524         (if_then_else (unle (match_dup 1) (const_int 0))
1525                       (label_ref (match_operand 0 "" ""))
1526                       (pc)))]
1527   ""
1529   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1530     {
1531       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLE);
1532       emit_jump_insn (gen_bne (operands[0]));
1533       DONE;
1534     }
1535   operands[1] = gen_compare_reg (UNLE, sparc_compare_op0, sparc_compare_op1);
1538 (define_expand "bltgt"
1539   [(set (pc)
1540         (if_then_else (ltgt (match_dup 1) (const_int 0))
1541                       (label_ref (match_operand 0 "" ""))
1542                       (pc)))]
1543   ""
1545   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1546     {
1547       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LTGT);
1548       emit_jump_insn (gen_bne (operands[0]));
1549       DONE;
1550     }
1551   operands[1] = gen_compare_reg (LTGT, sparc_compare_op0, sparc_compare_op1);
1554 ;; Now match both normal and inverted jump.
1556 ;; XXX fpcmp nop braindamage
1557 (define_insn "*normal_branch"
1558   [(set (pc)
1559         (if_then_else (match_operator 0 "noov_compare_op"
1560                                       [(reg 100) (const_int 0)])
1561                       (label_ref (match_operand 1 "" ""))
1562                       (pc)))]
1563   ""
1565   return output_cbranch (operands[0], operands[1], 1, 0,
1566                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1567                          insn);
1569   [(set_attr "type" "branch")
1570    (set_attr "branch_type" "icc")])
1572 ;; XXX fpcmp nop braindamage
1573 (define_insn "*inverted_branch"
1574   [(set (pc)
1575         (if_then_else (match_operator 0 "noov_compare_op"
1576                                       [(reg 100) (const_int 0)])
1577                       (pc)
1578                       (label_ref (match_operand 1 "" ""))))]
1579   ""
1581   return output_cbranch (operands[0], operands[1], 1, 1,
1582                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1583                          insn);
1585   [(set_attr "type" "branch")
1586    (set_attr "branch_type" "icc")])
1588 ;; XXX fpcmp nop braindamage
1589 (define_insn "*normal_fp_branch"
1590   [(set (pc)
1591         (if_then_else (match_operator 1 "comparison_operator"
1592                                       [(match_operand:CCFP 0 "fcc_reg_operand" "c")
1593                                        (const_int 0)])
1594                       (label_ref (match_operand 2 "" ""))
1595                       (pc)))]
1596   ""
1598   return output_cbranch (operands[1], operands[2], 2, 0,
1599                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1600                          insn);
1602   [(set_attr "type" "branch")
1603    (set_attr "branch_type" "fcc")])
1605 ;; XXX fpcmp nop braindamage
1606 (define_insn "*inverted_fp_branch"
1607   [(set (pc)
1608         (if_then_else (match_operator 1 "comparison_operator"
1609                                       [(match_operand:CCFP 0 "fcc_reg_operand" "c")
1610                                        (const_int 0)])
1611                       (pc)
1612                       (label_ref (match_operand 2 "" ""))))]
1613   ""
1615   return output_cbranch (operands[1], operands[2], 2, 1,
1616                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1617                          insn);
1619   [(set_attr "type" "branch")
1620    (set_attr "branch_type" "fcc")])
1622 ;; XXX fpcmp nop braindamage
1623 (define_insn "*normal_fpe_branch"
1624   [(set (pc)
1625         (if_then_else (match_operator 1 "comparison_operator"
1626                                       [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
1627                                        (const_int 0)])
1628                       (label_ref (match_operand 2 "" ""))
1629                       (pc)))]
1630   ""
1632   return output_cbranch (operands[1], operands[2], 2, 0,
1633                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1634                          insn);
1636   [(set_attr "type" "branch")
1637    (set_attr "branch_type" "fcc")])
1639 ;; XXX fpcmp nop braindamage
1640 (define_insn "*inverted_fpe_branch"
1641   [(set (pc)
1642         (if_then_else (match_operator 1 "comparison_operator"
1643                                       [(match_operand:CCFPE 0 "fcc_reg_operand" "c")
1644                                        (const_int 0)])
1645                       (pc)
1646                       (label_ref (match_operand 2 "" ""))))]
1647   ""
1649   return output_cbranch (operands[1], operands[2], 2, 1,
1650                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1651                          insn);
1653   [(set_attr "type" "branch")
1654    (set_attr "branch_type" "fcc")])
1656 ;; SPARC V9-specific jump insns.  None of these are guaranteed to be
1657 ;; in the architecture.
1659 ;; There are no 32 bit brreg insns.
1661 ;; XXX
1662 (define_insn "*normal_int_branch_sp64"
1663   [(set (pc)
1664         (if_then_else (match_operator 0 "v9_regcmp_op"
1665                                       [(match_operand:DI 1 "register_operand" "r")
1666                                        (const_int 0)])
1667                       (label_ref (match_operand 2 "" ""))
1668                       (pc)))]
1669   "TARGET_ARCH64"
1671   return output_v9branch (operands[0], operands[2], 1, 2, 0,
1672                           final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1673                           insn);
1675   [(set_attr "type" "branch")
1676    (set_attr "branch_type" "reg")])
1678 ;; XXX
1679 (define_insn "*inverted_int_branch_sp64"
1680   [(set (pc)
1681         (if_then_else (match_operator 0 "v9_regcmp_op"
1682                                       [(match_operand:DI 1 "register_operand" "r")
1683                                        (const_int 0)])
1684                       (pc)
1685                       (label_ref (match_operand 2 "" ""))))]
1686   "TARGET_ARCH64"
1688   return output_v9branch (operands[0], operands[2], 1, 2, 1,
1689                           final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1690                           insn);
1692   [(set_attr "type" "branch")
1693    (set_attr "branch_type" "reg")])
1695 ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic
1696 ;; value subject to a PC-relative relocation.  Operand 2 is a helper function
1697 ;; that adds the PC value at the call point to operand 0.
1699 (define_insn "load_pcrel_sym<P:mode>"
1700   [(set (match_operand:P 0 "register_operand" "=r")
1701         (unspec:P [(match_operand:P 1 "symbolic_operand" "")
1702                    (match_operand:P 2 "call_operand_address" "")] UNSPEC_LOAD_PCREL_SYM))
1703    (clobber (reg:P 15))]
1704   ""
1706   if (flag_delayed_branch)
1707     return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0";
1708   else
1709     return "sethi\t%%hi(%a1-8), %0\n\tadd\t%0, %%lo(%a1-4), %0\n\tcall\t%a2\n\t nop";
1711   [(set (attr "type") (const_string "multi"))
1712    (set (attr "length")
1713         (if_then_else (eq_attr "delayed_branch" "true")
1714                       (const_int 3)
1715                       (const_int 4)))])
1717 ;; Move instructions
1719 (define_expand "movqi"
1720   [(set (match_operand:QI 0 "general_operand" "")
1721         (match_operand:QI 1 "general_operand" ""))]
1722   ""
1724   /* Working with CONST_INTs is easier, so convert
1725      a double if needed.  */
1726   if (GET_CODE (operands[1]) == CONST_DOUBLE)
1727     {
1728       operands[1] = GEN_INT (trunc_int_for_mode
1729                              (CONST_DOUBLE_LOW (operands[1]), QImode));
1730     }
1732   /* Handle sets of MEM first.  */
1733   if (GET_CODE (operands[0]) == MEM)
1734     {
1735       if (reg_or_0_operand (operands[1], QImode))
1736         goto movqi_is_ok;
1738       if (! reload_in_progress)
1739         {
1740           operands[0] = validize_mem (operands[0]);
1741           operands[1] = force_reg (QImode, operands[1]);
1742         }
1743     }
1745   /* Fixup TLS cases.  */
1746   if (tls_symbolic_operand (operands [1]))
1747     operands[1] = legitimize_tls_address (operands[1]);
1749   /* Fixup PIC cases.  */
1750   if (flag_pic)
1751     {
1752       if (CONSTANT_P (operands[1])
1753           && pic_address_needs_scratch (operands[1]))
1754         operands[1] = legitimize_pic_address (operands[1], QImode, 0);
1756       if (symbolic_operand (operands[1], QImode))
1757         {
1758           operands[1] = legitimize_pic_address (operands[1],
1759                                                 QImode,
1760                                                 (reload_in_progress ?
1761                                                  operands[0] :
1762                                                  NULL_RTX));
1763           goto movqi_is_ok;
1764         }
1765     }
1767   /* All QI constants require only one insn, so proceed.  */
1769  movqi_is_ok:
1770   ;
1773 (define_insn "*movqi_insn"
1774   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1775         (match_operand:QI 1 "input_operand"   "rI,m,rJ"))]
1776   "(register_operand (operands[0], QImode)
1777     || reg_or_0_operand (operands[1], QImode))"
1778   "@
1779    mov\t%1, %0
1780    ldub\t%1, %0
1781    stb\t%r1, %0"
1782   [(set_attr "type" "*,load,store")
1783    (set_attr "us3load_type" "*,3cycle,*")])
1785 (define_expand "movhi"
1786   [(set (match_operand:HI 0 "general_operand" "")
1787         (match_operand:HI 1 "general_operand" ""))]
1788   ""
1790   /* Working with CONST_INTs is easier, so convert
1791      a double if needed.  */
1792   if (GET_CODE (operands[1]) == CONST_DOUBLE)
1793     operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
1795   /* Handle sets of MEM first.  */
1796   if (GET_CODE (operands[0]) == MEM)
1797     {
1798       if (reg_or_0_operand (operands[1], HImode))
1799         goto movhi_is_ok;
1801       if (! reload_in_progress)
1802         {
1803           operands[0] = validize_mem (operands[0]);
1804           operands[1] = force_reg (HImode, operands[1]);
1805         }
1806     }
1808   /* Fixup TLS cases.  */
1809   if (tls_symbolic_operand (operands [1]))
1810     operands[1] = legitimize_tls_address (operands[1]);
1812   /* Fixup PIC cases.  */
1813   if (flag_pic)
1814     {
1815       if (CONSTANT_P (operands[1])
1816           && pic_address_needs_scratch (operands[1]))
1817         operands[1] = legitimize_pic_address (operands[1], HImode, 0);
1819       if (symbolic_operand (operands[1], HImode))
1820         {
1821           operands[1] = legitimize_pic_address (operands[1],
1822                                                 HImode,
1823                                                 (reload_in_progress ?
1824                                                  operands[0] :
1825                                                  NULL_RTX));
1826           goto movhi_is_ok;
1827         }
1828     }
1830   /* This makes sure we will not get rematched due to splittage.  */
1831   if (! CONSTANT_P (operands[1]) || input_operand (operands[1], HImode))
1832     ;
1833   else if (CONSTANT_P (operands[1])
1834            && GET_CODE (operands[1]) != HIGH
1835            && GET_CODE (operands[1]) != LO_SUM)
1836     {
1837       sparc_emit_set_const32 (operands[0], operands[1]);
1838       DONE;
1839     }
1840  movhi_is_ok:
1841   ;
1844 (define_insn "*movhi_const64_special"
1845   [(set (match_operand:HI 0 "register_operand" "=r")
1846         (match_operand:HI 1 "const64_high_operand" ""))]
1847   "TARGET_ARCH64"
1848   "sethi\t%%hi(%a1), %0")
1850 (define_insn "*movhi_insn"
1851   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1852         (match_operand:HI 1 "input_operand"   "rI,K,m,rJ"))]
1853   "(register_operand (operands[0], HImode)
1854     || reg_or_0_operand (operands[1], HImode))"
1855   "@
1856    mov\t%1, %0
1857    sethi\t%%hi(%a1), %0
1858    lduh\t%1, %0
1859    sth\t%r1, %0"
1860   [(set_attr "type" "*,*,load,store")
1861    (set_attr "us3load_type" "*,*,3cycle,*")])
1863 ;; We always work with constants here.
1864 (define_insn "*movhi_lo_sum"
1865   [(set (match_operand:HI 0 "register_operand" "=r")
1866         (ior:HI (match_operand:HI 1 "register_operand" "%r")
1867                 (match_operand:HI 2 "small_int" "I")))]
1868   ""
1869   "or\t%1, %2, %0")
1871 (define_expand "movsi"
1872   [(set (match_operand:SI 0 "general_operand" "")
1873         (match_operand:SI 1 "general_operand" ""))]
1874   ""
1876   /* Working with CONST_INTs is easier, so convert
1877      a double if needed.  */
1878   if (GET_CODE (operands[1]) == CONST_DOUBLE)
1879     operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
1881   /* Handle sets of MEM first.  */
1882   if (GET_CODE (operands[0]) == MEM)
1883     {
1884       if (reg_or_0_operand (operands[1], SImode))
1885         goto movsi_is_ok;
1887       if (! reload_in_progress)
1888         {
1889           operands[0] = validize_mem (operands[0]);
1890           operands[1] = force_reg (SImode, operands[1]);
1891         }
1892     }
1894   /* Fixup TLS cases.  */
1895   if (tls_symbolic_operand (operands [1]))
1896     operands[1] = legitimize_tls_address (operands[1]);
1898   /* Fixup PIC cases.  */
1899   if (flag_pic)
1900     {
1901       if (CONSTANT_P (operands[1])
1902           && pic_address_needs_scratch (operands[1]))
1903         operands[1] = legitimize_pic_address (operands[1], SImode, 0);
1905       if (GET_CODE (operands[1]) == LABEL_REF)
1906         {
1907           /* shit */
1908           emit_insn (gen_movsi_pic_label_ref (operands[0], operands[1]));
1909           DONE;
1910         }
1912       if (symbolic_operand (operands[1], SImode))
1913         {
1914           operands[1] = legitimize_pic_address (operands[1],
1915                                                 SImode,
1916                                                 (reload_in_progress ?
1917                                                  operands[0] :
1918                                                  NULL_RTX));
1919           goto movsi_is_ok;
1920         }
1921     }
1923   /* If we are trying to toss an integer constant into the
1924      FPU registers, force it into memory.  */
1925   if (GET_CODE (operands[0]) == REG
1926       && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
1927       && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
1928       && CONSTANT_P (operands[1]))
1929     operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
1930                                                  operands[1]));
1932   /* This makes sure we will not get rematched due to splittage.  */
1933   if (! CONSTANT_P (operands[1]) || input_operand (operands[1], SImode))
1934     ;
1935   else if (CONSTANT_P (operands[1])
1936            && GET_CODE (operands[1]) != HIGH
1937            && GET_CODE (operands[1]) != LO_SUM)
1938     {
1939       sparc_emit_set_const32 (operands[0], operands[1]);
1940       DONE;
1941     }
1942  movsi_is_ok:
1943   ;
1946 ;; This is needed to show CSE exactly which bits are set
1947 ;; in a 64-bit register by sethi instructions.
1948 (define_insn "*movsi_const64_special"
1949   [(set (match_operand:SI 0 "register_operand" "=r")
1950         (match_operand:SI 1 "const64_high_operand" ""))]
1951   "TARGET_ARCH64"
1952   "sethi\t%%hi(%a1), %0")
1954 (define_insn "*movsi_insn"
1955   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,f,r,r,r,f,m,m,d")
1956         (match_operand:SI 1 "input_operand"   "rI,!f,K,J,m,!m,rJ,!f,J"))]
1957   "(register_operand (operands[0], SImode)
1958     || reg_or_0_operand (operands[1], SImode))"
1959   "@
1960    mov\t%1, %0
1961    fmovs\t%1, %0
1962    sethi\t%%hi(%a1), %0
1963    clr\t%0
1964    ld\t%1, %0
1965    ld\t%1, %0
1966    st\t%r1, %0
1967    st\t%1, %0
1968    fzeros\t%0"
1969   [(set_attr "type" "*,fpmove,*,*,load,fpload,store,fpstore,fga")])
1971 (define_insn "*movsi_lo_sum"
1972   [(set (match_operand:SI 0 "register_operand" "=r")
1973         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1974                    (match_operand:SI 2 "immediate_operand" "in")))]
1975   ""
1976   "or\t%1, %%lo(%a2), %0")
1978 (define_insn "*movsi_high"
1979   [(set (match_operand:SI 0 "register_operand" "=r")
1980         (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1981   ""
1982   "sethi\t%%hi(%a1), %0")
1984 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1985 ;; so that CSE won't optimize the address computation away.
1986 (define_insn "movsi_lo_sum_pic"
1987   [(set (match_operand:SI 0 "register_operand" "=r")
1988         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1989                    (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1990   "flag_pic"
1991   "or\t%1, %%lo(%a2), %0")
1993 (define_insn "movsi_high_pic"
1994   [(set (match_operand:SI 0 "register_operand" "=r")
1995         (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1996   "flag_pic && check_pic (1)"
1997   "sethi\t%%hi(%a1), %0")
1999 (define_expand "movsi_pic_label_ref"
2000   [(set (match_dup 3) (high:SI
2001      (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
2002                  (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2003    (set (match_dup 4) (lo_sum:SI (match_dup 3)
2004      (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2005    (set (match_operand:SI 0 "register_operand" "=r")
2006         (minus:SI (match_dup 5) (match_dup 4)))]
2007   "flag_pic"
2009   current_function_uses_pic_offset_table = 1;
2010   operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
2011   if (no_new_pseudos)
2012     {
2013       operands[3] = operands[0];
2014       operands[4] = operands[0];
2015     }
2016   else
2017     {
2018       operands[3] = gen_reg_rtx (SImode);
2019       operands[4] = gen_reg_rtx (SImode);
2020     }
2021   operands[5] = pic_offset_table_rtx;
2024 (define_insn "*movsi_high_pic_label_ref"
2025   [(set (match_operand:SI 0 "register_operand" "=r")
2026       (high:SI
2027         (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
2028                     (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2029   "flag_pic"
2030   "sethi\t%%hi(%a2-(%a1-.)), %0")
2032 (define_insn "*movsi_lo_sum_pic_label_ref"
2033   [(set (match_operand:SI 0 "register_operand" "=r")
2034       (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
2035         (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
2036                     (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2037   "flag_pic"
2038   "or\t%1, %%lo(%a3-(%a2-.)), %0")
2040 (define_expand "movdi"
2041   [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
2042         (match_operand:DI 1 "general_operand" ""))]
2043   ""
2045   /* Where possible, convert CONST_DOUBLE into a CONST_INT.  */
2046   if (GET_CODE (operands[1]) == CONST_DOUBLE
2047 #if HOST_BITS_PER_WIDE_INT == 32
2048       && ((CONST_DOUBLE_HIGH (operands[1]) == 0
2049            && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) == 0)
2050           || (CONST_DOUBLE_HIGH (operands[1]) == (HOST_WIDE_INT) 0xffffffff
2051               && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) != 0))
2052 #endif
2053       )
2054     operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
2056   /* Handle MEM cases first.  */
2057   if (GET_CODE (operands[0]) == MEM)
2058     {
2059       /* If it's a REG, we can always do it.
2060          The const zero case is more complex, on v9
2061          we can always perform it.  */
2062       if (register_operand (operands[1], DImode)
2063           || (TARGET_V9
2064               && (operands[1] == const0_rtx)))
2065         goto movdi_is_ok;
2067       if (! reload_in_progress)
2068         {
2069           operands[0] = validize_mem (operands[0]);
2070           operands[1] = force_reg (DImode, operands[1]);
2071         }
2072     }
2074   /* Fixup TLS cases.  */
2075   if (tls_symbolic_operand (operands [1]))
2076     operands[1] = legitimize_tls_address (operands[1]);
2078   if (flag_pic)
2079     {
2080       if (CONSTANT_P (operands[1])
2081           && pic_address_needs_scratch (operands[1]))
2082         operands[1] = legitimize_pic_address (operands[1], DImode, 0);
2084       if (GET_CODE (operands[1]) == LABEL_REF)
2085         {
2086           if (! TARGET_ARCH64)
2087             abort ();
2088           emit_insn (gen_movdi_pic_label_ref (operands[0], operands[1]));
2089           DONE;
2090         }
2092       if (symbolic_operand (operands[1], DImode))
2093         {
2094           operands[1] = legitimize_pic_address (operands[1],
2095                                                 DImode,
2096                                                 (reload_in_progress ?
2097                                                  operands[0] :
2098                                                  NULL_RTX));
2099           goto movdi_is_ok;
2100         }
2101     }
2103   /* If we are trying to toss an integer constant into the
2104      FPU registers, force it into memory.  */
2105   if (GET_CODE (operands[0]) == REG
2106       && REGNO (operands[0]) >= SPARC_FIRST_FP_REG
2107       && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
2108       && CONSTANT_P (operands[1]))
2109     operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2110                                                  operands[1]));
2112   /* This makes sure we will not get rematched due to splittage.  */
2113   if (! CONSTANT_P (operands[1]) || input_operand (operands[1], DImode))
2114     ;
2115   else if (TARGET_ARCH64
2116            && GET_CODE (operands[1]) != HIGH
2117            && GET_CODE (operands[1]) != LO_SUM)
2118     {
2119       sparc_emit_set_const64 (operands[0], operands[1]);
2120       DONE;
2121     }
2123  movdi_is_ok:
2124   ;
2127 ;; Be careful, fmovd does not exist when !v9.
2128 ;; We match MEM moves directly when we have correct even
2129 ;; numbered registers, but fall into splits otherwise.
2130 ;; The constraint ordering here is really important to
2131 ;; avoid insane problems in reload, especially for patterns
2132 ;; of the form:
2134 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
2135 ;;                       (const_int -5016)))
2136 ;;      (reg:DI 2 %g2))
2139 (define_insn "*movdi_insn_sp32_v9"
2140   [(set (match_operand:DI 0 "nonimmediate_operand"
2141                                         "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?e,?e,?W")
2142         (match_operand:DI 1 "input_operand"
2143                                         " J,J,U,T,r,o,i,r, f, T, o, f, e, W, e"))]
2144   "! TARGET_ARCH64 && TARGET_V9
2145    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2146   "@
2147    stx\t%%g0, %0
2148    #
2149    std\t%1, %0
2150    ldd\t%1, %0
2151    #
2152    #
2153    #
2154    #
2155    std\t%1, %0
2156    ldd\t%1, %0
2157    #
2158    #
2159    fmovd\\t%1, %0
2160    ldd\\t%1, %0
2161    std\\t%1, %0"
2162   [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,fpload,fpstore")
2163    (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,*,*")
2164    (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])
2166 (define_insn "*movdi_insn_sp32"
2167   [(set (match_operand:DI 0 "nonimmediate_operand"
2168                                 "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
2169         (match_operand:DI 1 "input_operand"
2170                                 " J,U,T,r,o,i,r, f, T, o, f, f"))]
2171   "! TARGET_ARCH64
2172    && (register_operand (operands[0], DImode)
2173        || register_operand (operands[1], DImode))"
2174   "@
2175    #
2176    std\t%1, %0
2177    ldd\t%1, %0
2178    #
2179    #
2180    #
2181    #
2182    std\t%1, %0
2183    ldd\t%1, %0
2184    #
2185    #
2186    #"
2187   [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
2188    (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
2190 ;; The following are generated by sparc_emit_set_const64
2191 (define_insn "*movdi_sp64_dbl"
2192   [(set (match_operand:DI 0 "register_operand" "=r")
2193         (match_operand:DI 1 "const64_operand" ""))]
2194   "(TARGET_ARCH64
2195     && HOST_BITS_PER_WIDE_INT != 64)"
2196   "mov\t%1, %0")
2198 ;; This is needed to show CSE exactly which bits are set
2199 ;; in a 64-bit register by sethi instructions.
2200 (define_insn "*movdi_const64_special"
2201   [(set (match_operand:DI 0 "register_operand" "=r")
2202         (match_operand:DI 1 "const64_high_operand" ""))]
2203   "TARGET_ARCH64"
2204   "sethi\t%%hi(%a1), %0")
2206 (define_insn "*movdi_insn_sp64_novis"
2207   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?W")
2208         (match_operand:DI 1 "input_operand"   "rI,N,J,m,rJ,e,W,e"))]
2209   "TARGET_ARCH64 && ! TARGET_VIS
2210    && (register_operand (operands[0], DImode)
2211        || reg_or_0_operand (operands[1], DImode))"
2212   "@
2213    mov\t%1, %0
2214    sethi\t%%hi(%a1), %0
2215    clr\t%0
2216    ldx\t%1, %0
2217    stx\t%r1, %0
2218    fmovd\t%1, %0
2219    ldd\t%1, %0
2220    std\t%1, %0"
2221   [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore")
2222    (set_attr "fptype" "*,*,*,*,*,double,*,*")])
2224 ;; We don't define V1SI because SI should work just fine.
2225 (define_mode_macro V64 [DF V2SI V4HI V8QI])
2226 (define_mode_macro V32 [SF V2HI V4QI])
2228 (define_insn "*movdi_insn_sp64_vis"
2229   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?W,b")
2230         (match_operand:DI 1 "input_operand"   "rI,N,J,m,rJ,e,W,e,J"))]
2231   "TARGET_ARCH64 && TARGET_VIS &&
2232    (register_operand (operands[0], DImode)
2233     || reg_or_0_operand (operands[1], DImode))"
2234   "@
2235    mov\t%1, %0
2236    sethi\t%%hi(%a1), %0
2237    clr\t%0
2238    ldx\t%1, %0
2239    stx\t%r1, %0
2240    fmovd\t%1, %0
2241    ldd\t%1, %0
2242    std\t%1, %0
2243    fzero\t%0"
2244   [(set_attr "type" "*,*,*,load,store,fpmove,fpload,fpstore,fga")
2245    (set_attr "fptype" "*,*,*,*,*,double,*,*,double")])
2247 (define_expand "movdi_pic_label_ref"
2248   [(set (match_dup 3) (high:DI
2249      (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2250                  (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2251    (set (match_dup 4) (lo_sum:DI (match_dup 3)
2252      (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2253    (set (match_operand:DI 0 "register_operand" "=r")
2254         (minus:DI (match_dup 5) (match_dup 4)))]
2255   "TARGET_ARCH64 && flag_pic"
2257   current_function_uses_pic_offset_table = 1;
2258   operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
2259   if (no_new_pseudos)
2260     {
2261       operands[3] = operands[0];
2262       operands[4] = operands[0];
2263     }
2264   else
2265     {
2266       operands[3] = gen_reg_rtx (DImode);
2267       operands[4] = gen_reg_rtx (DImode);
2268     }
2269   operands[5] = pic_offset_table_rtx;
2272 (define_insn "*movdi_high_pic_label_ref"
2273   [(set (match_operand:DI 0 "register_operand" "=r")
2274         (high:DI
2275           (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2276                       (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2277   "TARGET_ARCH64 && flag_pic"
2278   "sethi\t%%hi(%a2-(%a1-.)), %0")
2280 (define_insn "*movdi_lo_sum_pic_label_ref"
2281   [(set (match_operand:DI 0 "register_operand" "=r")
2282       (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2283         (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
2284                     (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2285   "TARGET_ARCH64 && flag_pic"
2286   "or\t%1, %%lo(%a3-(%a2-.)), %0")
2288 ;; SPARC-v9 code model support insns.  See sparc_emit_set_symbolic_const64
2289 ;; in sparc.c to see what is going on here... PIC stuff comes first.
2291 (define_insn "movdi_lo_sum_pic"
2292   [(set (match_operand:DI 0 "register_operand" "=r")
2293         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2294                    (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
2295   "TARGET_ARCH64 && flag_pic"
2296   "or\t%1, %%lo(%a2), %0")
2298 (define_insn "movdi_high_pic"
2299   [(set (match_operand:DI 0 "register_operand" "=r")
2300         (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
2301   "TARGET_ARCH64 && flag_pic && check_pic (1)"
2302   "sethi\t%%hi(%a1), %0")
2304 (define_insn "*sethi_di_medlow_embmedany_pic"
2305   [(set (match_operand:DI 0 "register_operand" "=r")
2306         (high:DI (match_operand:DI 1 "sp64_medium_pic_operand" "")))]
2307   "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
2308   "sethi\t%%hi(%a1), %0")
2310 (define_insn "*sethi_di_medlow"
2311   [(set (match_operand:DI 0 "register_operand" "=r")
2312         (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
2313   "TARGET_CM_MEDLOW && check_pic (1)"
2314   "sethi\t%%hi(%a1), %0")
2316 (define_insn "*losum_di_medlow"
2317   [(set (match_operand:DI 0 "register_operand" "=r")
2318         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2319                    (match_operand:DI 2 "symbolic_operand" "")))]
2320   "TARGET_CM_MEDLOW"
2321   "or\t%1, %%lo(%a2), %0")
2323 (define_insn "seth44"
2324   [(set (match_operand:DI 0 "register_operand" "=r")
2325         (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
2326   "TARGET_CM_MEDMID"
2327   "sethi\t%%h44(%a1), %0")
2329 (define_insn "setm44"
2330   [(set (match_operand:DI 0 "register_operand" "=r")
2331         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2332                    (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
2333   "TARGET_CM_MEDMID"
2334   "or\t%1, %%m44(%a2), %0")
2336 (define_insn "setl44"
2337   [(set (match_operand:DI 0 "register_operand" "=r")
2338         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2339                    (match_operand:DI 2 "symbolic_operand" "")))]
2340   "TARGET_CM_MEDMID"
2341   "or\t%1, %%l44(%a2), %0")
2343 (define_insn "sethh"
2344   [(set (match_operand:DI 0 "register_operand" "=r")
2345         (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
2346   "TARGET_CM_MEDANY"
2347   "sethi\t%%hh(%a1), %0")
2349 (define_insn "setlm"
2350   [(set (match_operand:DI 0 "register_operand" "=r")
2351         (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
2352   "TARGET_CM_MEDANY"
2353   "sethi\t%%lm(%a1), %0")
2355 (define_insn "sethm"
2356   [(set (match_operand:DI 0 "register_operand" "=r")
2357         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2358                    (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
2359   "TARGET_CM_MEDANY"
2360   "or\t%1, %%hm(%a2), %0")
2362 (define_insn "setlo"
2363   [(set (match_operand:DI 0 "register_operand" "=r")
2364         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2365                    (match_operand:DI 2 "symbolic_operand" "")))]
2366   "TARGET_CM_MEDANY"
2367   "or\t%1, %%lo(%a2), %0")
2369 (define_insn "embmedany_sethi"
2370   [(set (match_operand:DI 0 "register_operand" "=r")
2371         (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
2372   "TARGET_CM_EMBMEDANY && check_pic (1)"
2373   "sethi\t%%hi(%a1), %0")
2375 (define_insn "embmedany_losum"
2376   [(set (match_operand:DI 0 "register_operand" "=r")
2377         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2378                    (match_operand:DI 2 "data_segment_operand" "")))]
2379   "TARGET_CM_EMBMEDANY"
2380   "add\t%1, %%lo(%a2), %0")
2382 (define_insn "embmedany_brsum"
2383   [(set (match_operand:DI 0 "register_operand" "=r")
2384         (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
2385   "TARGET_CM_EMBMEDANY"
2386   "add\t%1, %_, %0")
2388 (define_insn "embmedany_textuhi"
2389   [(set (match_operand:DI 0 "register_operand" "=r")
2390         (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
2391   "TARGET_CM_EMBMEDANY && check_pic (1)"
2392   "sethi\t%%uhi(%a1), %0")
2394 (define_insn "embmedany_texthi"
2395   [(set (match_operand:DI 0 "register_operand" "=r")
2396         (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
2397   "TARGET_CM_EMBMEDANY && check_pic (1)"
2398   "sethi\t%%hi(%a1), %0")
2400 (define_insn "embmedany_textulo"
2401   [(set (match_operand:DI 0 "register_operand" "=r")
2402         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2403                    (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
2404   "TARGET_CM_EMBMEDANY"
2405   "or\t%1, %%ulo(%a2), %0")
2407 (define_insn "embmedany_textlo"
2408   [(set (match_operand:DI 0 "register_operand" "=r")
2409         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2410                    (match_operand:DI 2 "text_segment_operand" "")))]
2411   "TARGET_CM_EMBMEDANY"
2412   "or\t%1, %%lo(%a2), %0")
2414 ;; Now some patterns to help reload out a bit.
2415 (define_expand "reload_indi"
2416   [(parallel [(match_operand:DI 0 "register_operand" "=r")
2417               (match_operand:DI 1 "immediate_operand" "")
2418               (match_operand:TI 2 "register_operand" "=&r")])]
2419   "(TARGET_CM_MEDANY
2420     || TARGET_CM_EMBMEDANY)
2421    && ! flag_pic"
2423   sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2424   DONE;
2427 (define_expand "reload_outdi"
2428   [(parallel [(match_operand:DI 0 "register_operand" "=r")
2429               (match_operand:DI 1 "immediate_operand" "")
2430               (match_operand:TI 2 "register_operand" "=&r")])]
2431   "(TARGET_CM_MEDANY
2432     || TARGET_CM_EMBMEDANY)
2433    && ! flag_pic"
2435   sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2436   DONE;
2439 ;; Split up putting CONSTs and REGs into DI regs when !arch64
2440 (define_split
2441   [(set (match_operand:DI 0 "register_operand" "")
2442         (match_operand:DI 1 "const_int_operand" ""))]
2443   "! TARGET_ARCH64 && reload_completed"
2444   [(clobber (const_int 0))]
2446 #if HOST_BITS_PER_WIDE_INT == 32
2447   emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2448                         (INTVAL (operands[1]) < 0) ?
2449                         constm1_rtx :
2450                         const0_rtx));
2451   emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2452                         operands[1]));
2453 #else
2454   unsigned int low, high;
2456   low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
2457   high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
2458   emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
2460   /* Slick... but this trick loses if this subreg constant part
2461      can be done in one insn.  */
2462   if (low == high && (low & 0x3ff) != 0 && low + 0x1000 >= 0x2000)
2463     emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2464                           gen_highpart (SImode, operands[0])));
2465   else
2466     emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
2467 #endif
2468   DONE;
2471 (define_split
2472   [(set (match_operand:DI 0 "register_operand" "")
2473         (match_operand:DI 1 "const_double_operand" ""))]
2474   "reload_completed
2475    && (! TARGET_V9
2476        || (! TARGET_ARCH64
2477            && ((GET_CODE (operands[0]) == REG
2478                 && REGNO (operands[0]) < 32)
2479                || (GET_CODE (operands[0]) == SUBREG
2480                    && GET_CODE (SUBREG_REG (operands[0])) == REG
2481                    && REGNO (SUBREG_REG (operands[0])) < 32))))"
2482   [(clobber (const_int 0))]
2484   emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2485                         GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
2487   /* Slick... but this trick loses if this subreg constant part
2488      can be done in one insn.  */
2489   if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
2490       && !(SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
2491            || SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1]))))
2492     {
2493       emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2494                             gen_highpart (SImode, operands[0])));
2495     }
2496   else
2497     {
2498       emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2499                             GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
2500     }
2501   DONE;
2504 (define_split
2505   [(set (match_operand:DI 0 "register_operand" "")
2506         (match_operand:DI 1 "register_operand" ""))]
2507   "reload_completed
2508    && (! TARGET_V9
2509        || (! TARGET_ARCH64
2510            && ((GET_CODE (operands[0]) == REG
2511                 && REGNO (operands[0]) < 32)
2512                || (GET_CODE (operands[0]) == SUBREG
2513                    && GET_CODE (SUBREG_REG (operands[0])) == REG
2514                    && REGNO (SUBREG_REG (operands[0])) < 32))))"
2515   [(clobber (const_int 0))]
2517   rtx set_dest = operands[0];
2518   rtx set_src = operands[1];
2519   rtx dest1, dest2;
2520   rtx src1, src2;
2522   dest1 = gen_highpart (SImode, set_dest);
2523   dest2 = gen_lowpart (SImode, set_dest);
2524   src1 = gen_highpart (SImode, set_src);
2525   src2 = gen_lowpart (SImode, set_src);
2527   /* Now emit using the real source and destination we found, swapping
2528      the order if we detect overlap.  */
2529   if (reg_overlap_mentioned_p (dest1, src2))
2530     {
2531       emit_insn (gen_movsi (dest2, src2));
2532       emit_insn (gen_movsi (dest1, src1));
2533     }
2534   else
2535     {
2536       emit_insn (gen_movsi (dest1, src1));
2537       emit_insn (gen_movsi (dest2, src2));
2538     }
2539   DONE;
2542 ;; Now handle the cases of memory moves from/to non-even
2543 ;; DI mode register pairs.
2544 (define_split
2545   [(set (match_operand:DI 0 "register_operand" "")
2546         (match_operand:DI 1 "memory_operand" ""))]
2547   "(! TARGET_ARCH64
2548     && reload_completed
2549     && sparc_splitdi_legitimate (operands[0], operands[1]))"
2550   [(clobber (const_int 0))]
2552   rtx word0 = adjust_address (operands[1], SImode, 0);
2553   rtx word1 = adjust_address (operands[1], SImode, 4);
2554   rtx high_part = gen_highpart (SImode, operands[0]);
2555   rtx low_part = gen_lowpart (SImode, operands[0]);
2557   if (reg_overlap_mentioned_p (high_part, word1))
2558     {
2559       emit_insn (gen_movsi (low_part, word1));
2560       emit_insn (gen_movsi (high_part, word0));
2561     }
2562   else
2563     {
2564       emit_insn (gen_movsi (high_part, word0));
2565       emit_insn (gen_movsi (low_part, word1));
2566     }
2567   DONE;
2570 (define_split
2571   [(set (match_operand:DI 0 "memory_operand" "")
2572         (match_operand:DI 1 "register_operand" ""))]
2573   "(! TARGET_ARCH64
2574     && reload_completed
2575     && sparc_splitdi_legitimate (operands[1], operands[0]))"
2576   [(clobber (const_int 0))]
2578   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
2579                         gen_highpart (SImode, operands[1])));
2580   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
2581                         gen_lowpart (SImode, operands[1])));
2582   DONE;
2585 (define_split
2586   [(set (match_operand:DI 0 "memory_operand" "")
2587         (const_int 0))]
2588   "reload_completed
2589    && (! TARGET_V9
2590        || (! TARGET_ARCH64
2591            && ! mem_min_alignment (operands[0], 8)))
2592    && offsettable_memref_p (operands[0])"
2593   [(clobber (const_int 0))]
2595   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
2596   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
2597   DONE;
2600 ;; Floating point move insns
2602 (define_insn "*movsf_insn_novis"
2603   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,*r,*r,*r,*r,*r,f,m,m")
2604         (match_operand:SF 1 "input_operand"         "f,G,Q,*rR,S,m,m,f,*rG"))]
2605   "(TARGET_FPU && ! TARGET_VIS)
2606    && (register_operand (operands[0], SFmode)
2607        || register_operand (operands[1], SFmode)
2608        || fp_zero_operand (operands[1], SFmode))"
2610   if (GET_CODE (operands[1]) == CONST_DOUBLE
2611       && (which_alternative == 2
2612           || which_alternative == 3
2613           || which_alternative == 4))
2614     {
2615       REAL_VALUE_TYPE r;
2616       long i;
2618       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2619       REAL_VALUE_TO_TARGET_SINGLE (r, i);
2620       operands[1] = GEN_INT (i);
2621     }
2623   switch (which_alternative)
2624     {
2625     case 0:
2626       return "fmovs\t%1, %0";
2627     case 1:
2628       return "clr\t%0";
2629     case 2:
2630       return "sethi\t%%hi(%a1), %0";
2631     case 3:
2632       return "mov\t%1, %0";
2633     case 4:
2634       return "#";
2635     case 5:
2636     case 6:
2637       return "ld\t%1, %0";
2638     case 7:
2639     case 8:
2640       return "st\t%r1, %0";
2641     default:
2642       abort();
2643     }
2645   [(set_attr "type" "fpmove,*,*,*,*,load,fpload,fpstore,store")])
2647 (define_insn "*movsf_insn_vis"
2648   [(set (match_operand:V32 0 "nonimmediate_operand" "=f,f,*r,*r,*r,*r,*r,f,m,m")
2649         (match_operand:V32 1 "input_operand"         "f,GY,GY,Q,*rR,S,m,m,f,*rGY"))]
2650   "(TARGET_FPU && TARGET_VIS)
2651    && (register_operand (operands[0], <V32:MODE>mode)
2652        || register_operand (operands[1], <V32:MODE>mode)
2653        || fp_zero_operand (operands[1], <V32:MODE>mode))"
2655   if (GET_CODE (operands[1]) == CONST_DOUBLE
2656       && (which_alternative == 3
2657           || which_alternative == 4
2658           || which_alternative == 5))
2659     {
2660       REAL_VALUE_TYPE r;
2661       long i;
2663       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2664       REAL_VALUE_TO_TARGET_SINGLE (r, i);
2665       operands[1] = GEN_INT (i);
2666     }
2668   switch (which_alternative)
2669     {
2670     case 0:
2671       return "fmovs\t%1, %0";
2672     case 1:
2673       return "fzeros\t%0";
2674     case 2:
2675       return "clr\t%0";
2676     case 3:
2677       return "sethi\t%%hi(%a1), %0";
2678     case 4:
2679       return "mov\t%1, %0";
2680     case 5:
2681       return "#";
2682     case 6:
2683     case 7:
2684       return "ld\t%1, %0";
2685     case 8:
2686     case 9:
2687       return "st\t%r1, %0";
2688     default:
2689       abort();
2690     }
2692   [(set_attr "type" "fpmove,fga,*,*,*,*,load,fpload,fpstore,store")])
2694 ;; Exactly the same as above, except that all `f' cases are deleted.
2695 ;; This is necessary to prevent reload from ever trying to use a `f' reg
2696 ;; when -mno-fpu.
2698 (define_insn "*movsf_no_f_insn"
2699   [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,r,m")
2700         (match_operand:SF 1 "input_operand"    "G,Q,rR,S,m,rG"))]
2701   "! TARGET_FPU
2702    && (register_operand (operands[0], SFmode)
2703        || register_operand (operands[1], SFmode)
2704        || fp_zero_operand (operands[1], SFmode))"
2706   if (GET_CODE (operands[1]) == CONST_DOUBLE
2707       && (which_alternative == 1
2708           || which_alternative == 2
2709           || which_alternative == 3))
2710     {
2711       REAL_VALUE_TYPE r;
2712       long i;
2714       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2715       REAL_VALUE_TO_TARGET_SINGLE (r, i);
2716       operands[1] = GEN_INT (i);
2717     }
2719   switch (which_alternative)
2720     {
2721     case 0:
2722       return "clr\t%0";
2723     case 1:
2724       return "sethi\t%%hi(%a1), %0";
2725     case 2:
2726       return "mov\t%1, %0";
2727     case 3:
2728       return "#";
2729     case 4:
2730       return "ld\t%1, %0";
2731     case 5:
2732       return "st\t%r1, %0";
2733     default:
2734       abort();
2735     }
2737   [(set_attr "type" "*,*,*,*,load,store")])
2739 ;; The following 3 patterns build SFmode constants in integer registers.
2741 (define_insn "*movsf_lo_sum"
2742   [(set (match_operand:SF 0 "register_operand" "=r")
2743         (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
2744                    (match_operand:SF 2 "const_double_operand" "S")))]
2745   "fp_high_losum_p (operands[2])"
2747   REAL_VALUE_TYPE r;
2748   long i;
2750   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
2751   REAL_VALUE_TO_TARGET_SINGLE (r, i);
2752   operands[2] = GEN_INT (i);
2753   return "or\t%1, %%lo(%a2), %0";
2756 (define_insn "*movsf_high"
2757   [(set (match_operand:SF 0 "register_operand" "=r")
2758         (high:SF (match_operand:SF 1 "const_double_operand" "S")))]
2759   "fp_high_losum_p (operands[1])"
2761   REAL_VALUE_TYPE r;
2762   long i;
2764   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2765   REAL_VALUE_TO_TARGET_SINGLE (r, i);
2766   operands[1] = GEN_INT (i);
2767   return "sethi\t%%hi(%1), %0";
2770 (define_split
2771   [(set (match_operand:SF 0 "register_operand" "")
2772         (match_operand:SF 1 "const_double_operand" ""))]
2773   "fp_high_losum_p (operands[1])
2774    && (GET_CODE (operands[0]) == REG
2775        && REGNO (operands[0]) < 32)"
2776   [(set (match_dup 0) (high:SF (match_dup 1)))
2777    (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
2779 ;; Yes, you guessed it right, the former movsf expander.
2780 (define_expand "mov<V32:mode>"
2781   [(set (match_operand:V32 0 "general_operand" "")
2782         (match_operand:V32 1 "general_operand" ""))]
2783   "<V32:MODE>mode == SFmode || TARGET_VIS"
2785   /* Force constants into memory.  */
2786   if (GET_CODE (operands[0]) == REG && CONSTANT_P (operands[1]))
2787     {
2788       /* emit_group_store will send such bogosity to us when it is
2789          not storing directly into memory.  So fix this up to avoid
2790          crashes in output_constant_pool.  */
2791       if (operands [1] == const0_rtx)
2792         operands[1] = CONST0_RTX (<V32:MODE>mode);
2794       if ((TARGET_VIS || REGNO (operands[0]) < 32)
2795           && fp_zero_operand (operands[1], <V32:MODE>mode))
2796         goto movsf_is_ok;
2798       /* We are able to build any SF constant in integer registers
2799          with at most 2 instructions.  */
2800       if (REGNO (operands[0]) < 32
2801           && <V32:MODE>mode == SFmode)
2802         goto movsf_is_ok;
2804       operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2805                                                    operands[1]));
2806     }
2808   /* Handle sets of MEM first.  */
2809   if (GET_CODE (operands[0]) == MEM)
2810     {
2811       if (register_operand (operands[1], <V32:MODE>mode)
2812           || fp_zero_operand (operands[1], <V32:MODE>mode))
2813         goto movsf_is_ok;
2815       if (! reload_in_progress)
2816         {
2817           operands[0] = validize_mem (operands[0]);
2818           operands[1] = force_reg (<V32:MODE>mode, operands[1]);
2819         }
2820     }
2822   /* Fixup PIC cases.  */
2823   if (flag_pic)
2824     {
2825       if (CONSTANT_P (operands[1])
2826           && pic_address_needs_scratch (operands[1]))
2827         operands[1] = legitimize_pic_address (operands[1], <V32:MODE>mode, 0);
2829       if (symbolic_operand (operands[1], <V32:MODE>mode))
2830         {
2831           operands[1] = legitimize_pic_address (operands[1],
2832                                                 <V32:MODE>mode,
2833                                                 (reload_in_progress ?
2834                                                  operands[0] :
2835                                                  NULL_RTX));
2836         }
2837     }
2839  movsf_is_ok:
2840   ;
2843 ;; Yes, you again guessed it right, the former movdf expander.
2844 (define_expand "mov<V64:mode>"
2845   [(set (match_operand:V64 0 "general_operand" "")
2846         (match_operand:V64 1 "general_operand" ""))]
2847   "<V64:MODE>mode == DFmode || TARGET_VIS"
2849   /* Force constants into memory.  */
2850   if (GET_CODE (operands[0]) == REG && CONSTANT_P (operands[1]))
2851     {
2852       /* emit_group_store will send such bogosity to us when it is
2853          not storing directly into memory.  So fix this up to avoid
2854          crashes in output_constant_pool.  */
2855       if (operands [1] == const0_rtx)
2856         operands[1] = CONST0_RTX (<V64:MODE>mode);
2858       if ((TARGET_VIS || REGNO (operands[0]) < 32)
2859           && fp_zero_operand (operands[1], <V64:MODE>mode))
2860         goto movdf_is_ok;
2862       /* We are able to build any DF constant in integer registers.  */
2863       if (REGNO (operands[0]) < 32
2864           && <V64:MODE>mode == DFmode
2865           && (reload_completed || reload_in_progress))
2866         goto movdf_is_ok;
2868       operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
2869                                                    operands[1]));
2870     }
2872   /* Handle MEM cases first.  */
2873   if (GET_CODE (operands[0]) == MEM)
2874     {
2875       if (register_operand (operands[1], <V64:MODE>mode)
2876           || fp_zero_operand (operands[1], <V64:MODE>mode))
2877         goto movdf_is_ok;
2879       if (! reload_in_progress)
2880         {
2881           operands[0] = validize_mem (operands[0]);
2882           operands[1] = force_reg (<V64:MODE>mode, operands[1]);
2883         }
2884     }
2886   /* Fixup PIC cases.  */
2887   if (flag_pic)
2888     {
2889       if (CONSTANT_P (operands[1])
2890           && pic_address_needs_scratch (operands[1]))
2891         operands[1] = legitimize_pic_address (operands[1], <V64:MODE>mode, 0);
2893       if (symbolic_operand (operands[1], <V64:MODE>mode))
2894         {
2895           operands[1] = legitimize_pic_address (operands[1],
2896                                                 <V64:MODE>mode,
2897                                                 (reload_in_progress ?
2898                                                  operands[0] :
2899                                                  NULL_RTX));
2900         }
2901     }
2903  movdf_is_ok:
2904   ;
2907 ;; Be careful, fmovd does not exist when !v9.
2908 (define_insn "*movdf_insn_sp32"
2909   [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o")
2910         (match_operand:DF 1 "input_operand"    "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
2911   "TARGET_FPU
2912    && ! TARGET_V9
2913    && (register_operand (operands[0], DFmode)
2914        || register_operand (operands[1], DFmode)
2915        || fp_zero_operand (operands[1], DFmode))"
2916   "@
2917   ldd\t%1, %0
2918   std\t%1, %0
2919   ldd\t%1, %0
2920   std\t%1, %0
2921   #
2922   #
2923   #
2924   #
2925   #
2926   #"
2927  [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
2928   (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
2930 (define_insn "*movdf_no_e_insn_sp32"
2931   [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
2932         (match_operand:DF 1 "input_operand"    "T,U,G,ro,r"))]
2933   "! TARGET_FPU
2934    && ! TARGET_V9
2935    && ! TARGET_ARCH64
2936    && (register_operand (operands[0], DFmode)
2937        || register_operand (operands[1], DFmode)
2938        || fp_zero_operand (operands[1], DFmode))"
2939   "@
2940   ldd\t%1, %0
2941   std\t%1, %0
2942   #
2943   #
2944   #"
2945   [(set_attr "type" "load,store,*,*,*")
2946    (set_attr "length" "*,*,2,2,2")])
2948 (define_insn "*movdf_no_e_insn_v9_sp32"
2949   [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
2950         (match_operand:DF 1 "input_operand"    "T,U,G,ro,rG"))]
2951   "! TARGET_FPU
2952    && TARGET_V9
2953    && ! TARGET_ARCH64
2954    && (register_operand (operands[0], DFmode)
2955        || register_operand (operands[1], DFmode)
2956        || fp_zero_operand (operands[1], DFmode))"
2957   "@
2958   ldd\t%1, %0
2959   std\t%1, %0
2960   stx\t%r1, %0
2961   #
2962   #"
2963   [(set_attr "type" "load,store,store,*,*")
2964    (set_attr "length" "*,*,*,2,2")])
2966 ;; We have available v9 double floats but not 64-bit
2967 ;; integer registers and no VIS.
2968 (define_insn "*movdf_insn_v9only_novis"
2969   [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,T,W,U,T,f,*r,o")
2970         (match_operand:DF 1 "input_operand"    "e,W#F,G,e,T,U,o#F,*roF,*rGf"))]
2971   "TARGET_FPU
2972    && TARGET_V9
2973    && ! TARGET_VIS
2974    && ! TARGET_ARCH64
2975    && (register_operand (operands[0], DFmode)
2976        || register_operand (operands[1], DFmode)
2977        || fp_zero_operand (operands[1], DFmode))"
2978   "@
2979   fmovd\t%1, %0
2980   ldd\t%1, %0
2981   stx\t%r1, %0
2982   std\t%1, %0
2983   ldd\t%1, %0
2984   std\t%1, %0
2985   #
2986   #
2987   #"
2988   [(set_attr "type" "fpmove,load,store,store,load,store,*,*,*")
2989    (set_attr "length" "*,*,*,*,*,*,2,2,2")
2990    (set_attr "fptype" "double,*,*,*,*,*,*,*,*")])
2992 ;; We have available v9 double floats but not 64-bit
2993 ;; integer registers but we have VIS.
2994 (define_insn "*movdf_insn_v9only_vis"
2995   [(set (match_operand:V64 0 "nonimmediate_operand" "=e,e,e,T,W,U,T,f,*r,o")
2996         (match_operand:V64 1 "input_operand" "GY,e,W#F,GY,e,T,U,o#F,*roGYF,*rGYf"))]
2997   "TARGET_FPU
2998    && TARGET_VIS
2999    && ! TARGET_ARCH64
3000    && (register_operand (operands[0], <V64:MODE>mode)
3001        || register_operand (operands[1], <V64:MODE>mode)
3002        || fp_zero_operand (operands[1], <V64:MODE>mode))"
3003   "@
3004   fzero\t%0
3005   fmovd\t%1, %0
3006   ldd\t%1, %0
3007   stx\t%r1, %0
3008   std\t%1, %0
3009   ldd\t%1, %0
3010   std\t%1, %0
3011   #
3012   #
3013   #"
3014   [(set_attr "type" "fga,fpmove,load,store,store,load,store,*,*,*")
3015    (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
3016    (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
3018 ;; We have available both v9 double floats and 64-bit
3019 ;; integer registers. No VIS though.
3020 (define_insn "*movdf_insn_sp64_novis"
3021   [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,W,*r,*r,m,*r")
3022         (match_operand:DF 1 "input_operand"    "e,W#F,e,*rG,m,*rG,F"))]
3023   "TARGET_FPU
3024    && ! TARGET_VIS
3025    && TARGET_ARCH64
3026    && (register_operand (operands[0], DFmode)
3027        || register_operand (operands[1], DFmode)
3028        || fp_zero_operand (operands[1], DFmode))"
3029   "@
3030   fmovd\t%1, %0
3031   ldd\t%1, %0
3032   std\t%1, %0
3033   mov\t%r1, %0
3034   ldx\t%1, %0
3035   stx\t%r1, %0
3036   #"
3037   [(set_attr "type" "fpmove,load,store,*,load,store,*")
3038    (set_attr "length" "*,*,*,*,*,*,2")
3039    (set_attr "fptype" "double,*,*,*,*,*,*")])
3041 ;; We have available both v9 double floats and 64-bit
3042 ;; integer registers. And we have VIS.
3043 (define_insn "*movdf_insn_sp64_vis"
3044   [(set (match_operand:V64 0 "nonimmediate_operand" "=e,e,e,W,*r,*r,m,*r")
3045         (match_operand:V64 1 "input_operand"    "GY,e,W#F,e,*rGY,m,*rGY,F"))]
3046   "TARGET_FPU
3047    && TARGET_VIS
3048    && TARGET_ARCH64
3049    && (register_operand (operands[0], <V64:MODE>mode)
3050        || register_operand (operands[1], <V64:MODE>mode)
3051        || fp_zero_operand (operands[1], <V64:MODE>mode))"
3052   "@
3053   fzero\t%0
3054   fmovd\t%1, %0
3055   ldd\t%1, %0
3056   std\t%1, %0
3057   mov\t%r1, %0
3058   ldx\t%1, %0
3059   stx\t%r1, %0
3060   #"
3061   [(set_attr "type" "fga,fpmove,load,store,*,load,store,*")
3062    (set_attr "length" "*,*,*,*,*,*,*,2")
3063    (set_attr "fptype" "double,double,*,*,*,*,*,*")])
3065 (define_insn "*movdf_no_e_insn_sp64"
3066   [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
3067         (match_operand:DF 1 "input_operand"    "r,m,rG"))]
3068   "! TARGET_FPU
3069    && TARGET_ARCH64
3070    && (register_operand (operands[0], DFmode)
3071        || register_operand (operands[1], DFmode)
3072        || fp_zero_operand (operands[1], DFmode))"
3073   "@
3074   mov\t%1, %0
3075   ldx\t%1, %0
3076   stx\t%r1, %0"
3077   [(set_attr "type" "*,load,store")])
3079 ;; This pattern build DFmode constants in integer registers.
3080 (define_split
3081   [(set (match_operand:DF 0 "register_operand" "")
3082         (match_operand:DF 1 "const_double_operand" ""))]
3083   "TARGET_FPU
3084    && (GET_CODE (operands[0]) == REG
3085        && REGNO (operands[0]) < 32)
3086    && ! fp_zero_operand(operands[1], DFmode)
3087    && reload_completed"
3088   [(clobber (const_int 0))]
3090   REAL_VALUE_TYPE r;
3091   long l[2];
3093   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3094   REAL_VALUE_TO_TARGET_DOUBLE (r, l);
3095   operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
3097   if (TARGET_ARCH64)
3098     {
3099 #if HOST_BITS_PER_WIDE_INT == 64
3100       HOST_WIDE_INT val;
3102       val = ((HOST_WIDE_INT)(unsigned long)l[1] |
3103              ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
3104       emit_insn (gen_movdi (operands[0], GEN_INT (val)));
3105 #else
3106       emit_insn (gen_movdi (operands[0],
3107                             immed_double_const (l[1], l[0], DImode)));
3108 #endif
3109     }
3110   else
3111     {
3112       emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
3113                             GEN_INT (l[0])));
3115       /* Slick... but this trick loses if this subreg constant part
3116          can be done in one insn.  */
3117       if (l[1] == l[0]
3118           && !(SPARC_SETHI32_P (l[0])
3119                || SPARC_SIMM13_P (l[0])))
3120         {
3121           emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3122                                 gen_highpart (SImode, operands[0])));
3123         }
3124       else
3125         {
3126           emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
3127                                 GEN_INT (l[1])));
3128         }
3129     }
3130   DONE;
3133 ;; Ok, now the splits to handle all the multi insn and
3134 ;; mis-aligned memory address cases.
3135 ;; In these splits please take note that we must be
3136 ;; careful when V9 but not ARCH64 because the integer
3137 ;; register DFmode cases must be handled.
3138 (define_split
3139   [(set (match_operand:V64 0 "register_operand" "")
3140         (match_operand:V64 1 "register_operand" ""))]
3141   "(! TARGET_V9
3142     || (! TARGET_ARCH64
3143         && ((GET_CODE (operands[0]) == REG
3144              && REGNO (operands[0]) < 32)
3145             || (GET_CODE (operands[0]) == SUBREG
3146                 && GET_CODE (SUBREG_REG (operands[0])) == REG
3147                 && REGNO (SUBREG_REG (operands[0])) < 32))))
3148    && reload_completed"
3149   [(clobber (const_int 0))]
3151   rtx set_dest = operands[0];
3152   rtx set_src = operands[1];
3153   rtx dest1, dest2;
3154   rtx src1, src2;
3155   enum machine_mode half_mode;
3157   /* We can be expanded for DFmode or integral vector modes.  */
3158   if (<V64:MODE>mode == DFmode)
3159     half_mode = SFmode;
3160   else
3161     half_mode = SImode;
3162   
3163   dest1 = gen_highpart (half_mode, set_dest);
3164   dest2 = gen_lowpart (half_mode, set_dest);
3165   src1 = gen_highpart (half_mode, set_src);
3166   src2 = gen_lowpart (half_mode, set_src);
3168   /* Now emit using the real source and destination we found, swapping
3169      the order if we detect overlap.  */
3170   if (reg_overlap_mentioned_p (dest1, src2))
3171     {
3172       emit_move_insn_1 (dest2, src2);
3173       emit_move_insn_1 (dest1, src1);
3174     }
3175   else
3176     {
3177       emit_move_insn_1 (dest1, src1);
3178       emit_move_insn_1 (dest2, src2);
3179     }
3180   DONE;
3183 (define_split
3184   [(set (match_operand:V64 0 "register_operand" "")
3185         (match_operand:V64 1 "memory_operand" ""))]
3186   "reload_completed
3187    && ! TARGET_ARCH64
3188    && (((REGNO (operands[0]) % 2) != 0)
3189        || ! mem_min_alignment (operands[1], 8))
3190    && offsettable_memref_p (operands[1])"
3191   [(clobber (const_int 0))]
3193   enum machine_mode half_mode;
3194   rtx word0, word1;
3196   /* We can be expanded for DFmode or integral vector modes.  */
3197   if (<V64:MODE>mode == DFmode)
3198     half_mode = SFmode;
3199   else
3200     half_mode = SImode;
3202   word0 = adjust_address (operands[1], half_mode, 0);
3203   word1 = adjust_address (operands[1], half_mode, 4);
3205   if (reg_overlap_mentioned_p (gen_highpart (half_mode, operands[0]), word1))
3206     {
3207       emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
3208       emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
3209     }
3210   else
3211     {
3212       emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
3213       emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
3214     }
3215   DONE;
3218 (define_split
3219   [(set (match_operand:V64 0 "memory_operand" "")
3220         (match_operand:V64 1 "register_operand" ""))]
3221   "reload_completed
3222    && ! TARGET_ARCH64
3223    && (((REGNO (operands[1]) % 2) != 0)
3224        || ! mem_min_alignment (operands[0], 8))
3225    && offsettable_memref_p (operands[0])"
3226   [(clobber (const_int 0))]
3228   enum machine_mode half_mode;
3229   rtx word0, word1;
3231   /* We can be expanded for DFmode or integral vector modes.  */
3232   if (<V64:MODE>mode == DFmode)
3233     half_mode = SFmode;
3234   else
3235     half_mode = SImode;
3237   word0 = adjust_address (operands[0], half_mode, 0);
3238   word1 = adjust_address (operands[0], half_mode, 4);
3240   emit_move_insn_1 (word0, gen_highpart (half_mode, operands[1]));
3241   emit_move_insn_1 (word1, gen_lowpart (half_mode, operands[1]));
3242   DONE;
3245 (define_split
3246   [(set (match_operand:V64 0 "memory_operand" "")
3247         (match_operand:V64 1 "fp_zero_operand" ""))]
3248   "reload_completed
3249    && (! TARGET_V9
3250        || (! TARGET_ARCH64
3251            && ! mem_min_alignment (operands[0], 8)))
3252    && offsettable_memref_p (operands[0])"
3253   [(clobber (const_int 0))]
3255   enum machine_mode half_mode;
3256   rtx dest1, dest2;
3258   /* We can be expanded for DFmode or integral vector modes.  */
3259   if (<V64:MODE>mode == DFmode)
3260     half_mode = SFmode;
3261   else
3262     half_mode = SImode;
3264   dest1 = adjust_address (operands[0], half_mode, 0);
3265   dest2 = adjust_address (operands[0], half_mode, 4);
3267   emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
3268   emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
3269   DONE;
3272 (define_split
3273   [(set (match_operand:V64 0 "register_operand" "")
3274         (match_operand:V64 1 "fp_zero_operand" ""))]
3275   "reload_completed
3276    && ! TARGET_ARCH64
3277    && ((GET_CODE (operands[0]) == REG
3278         && REGNO (operands[0]) < 32)
3279        || (GET_CODE (operands[0]) == SUBREG
3280            && GET_CODE (SUBREG_REG (operands[0])) == REG
3281            && REGNO (SUBREG_REG (operands[0])) < 32))"
3282   [(clobber (const_int 0))]
3284   enum machine_mode half_mode;
3285   rtx set_dest = operands[0];
3286   rtx dest1, dest2;
3288   /* We can be expanded for DFmode or integral vector modes.  */
3289   if (<V64:MODE>mode == DFmode)
3290     half_mode = SFmode;
3291   else
3292     half_mode = SImode;
3294   dest1 = gen_highpart (half_mode, set_dest);
3295   dest2 = gen_lowpart (half_mode, set_dest);
3296   emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
3297   emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
3298   DONE;
3301 (define_expand "movtf"
3302   [(set (match_operand:TF 0 "general_operand" "")
3303         (match_operand:TF 1 "general_operand" ""))]
3304   ""
3306   /* Force TFmode constants into memory.  */
3307   if (GET_CODE (operands[0]) == REG
3308       && CONSTANT_P (operands[1]))
3309     {
3310       /* emit_group_store will send such bogosity to us when it is
3311          not storing directly into memory.  So fix this up to avoid
3312          crashes in output_constant_pool.  */
3313       if (operands [1] == const0_rtx)
3314         operands[1] = CONST0_RTX (TFmode);
3316       if (TARGET_VIS && fp_zero_operand (operands[1], TFmode))
3317         goto movtf_is_ok;
3319       operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
3320                                                    operands[1]));
3321     }
3323   /* Handle MEM cases first, note that only v9 guarantees
3324      full 16-byte alignment for quads.  */
3325   if (GET_CODE (operands[0]) == MEM)
3326     {
3327       if (register_operand (operands[1], TFmode)
3328           || fp_zero_operand (operands[1], TFmode))
3329         goto movtf_is_ok;
3331       if (! reload_in_progress)
3332         {
3333           operands[0] = validize_mem (operands[0]);
3334           operands[1] = force_reg (TFmode, operands[1]);
3335         }
3336     }
3338   /* Fixup PIC cases.  */
3339   if (flag_pic)
3340     {
3341       if (CONSTANT_P (operands[1])
3342           && pic_address_needs_scratch (operands[1]))
3343         operands[1] = legitimize_pic_address (operands[1], TFmode, 0);
3345       if (symbolic_operand (operands[1], TFmode))
3346         {
3347           operands[1] = legitimize_pic_address (operands[1],
3348                                                 TFmode,
3349                                                 (reload_in_progress ?
3350                                                  operands[0] :
3351                                                  NULL_RTX));
3352         }
3353     }
3355  movtf_is_ok:
3356   ;
3359 ;; Be careful, fmovq and {st,ld}{x,q} do not exist when !arch64 so
3360 ;; we must split them all.  :-(
3361 (define_insn "*movtf_insn_sp32"
3362   [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3363         (match_operand:TF 1 "input_operand"    "oe,GeUr,o,roG"))]
3364   "TARGET_FPU
3365    && ! TARGET_VIS
3366    && ! TARGET_ARCH64
3367    && (register_operand (operands[0], TFmode)
3368        || register_operand (operands[1], TFmode)
3369        || fp_zero_operand (operands[1], TFmode))"
3370   "#"
3371   [(set_attr "length" "4")])
3373 (define_insn "*movtf_insn_vis_sp32"
3374   [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
3375         (match_operand:TF 1 "input_operand"    "Goe,GeUr,o,roG"))]
3376   "TARGET_FPU
3377    && TARGET_VIS
3378    && ! TARGET_ARCH64
3379    && (register_operand (operands[0], TFmode)
3380        || register_operand (operands[1], TFmode)
3381        || fp_zero_operand (operands[1], TFmode))"
3382   "#"
3383   [(set_attr "length" "4")])
3385 ;; Exactly the same as above, except that all `e' cases are deleted.
3386 ;; This is necessary to prevent reload from ever trying to use a `e' reg
3387 ;; when -mno-fpu.
3389 (define_insn "*movtf_no_e_insn_sp32"
3390   [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
3391         (match_operand:TF 1 "input_operand"    "G,o,U,roG,r"))]
3392   "! TARGET_FPU
3393    && ! TARGET_ARCH64
3394    && (register_operand (operands[0], TFmode)
3395        || register_operand (operands[1], TFmode)
3396        || fp_zero_operand (operands[1], TFmode))"
3397   "#"
3398   [(set_attr "length" "4")])
3400 ;; Now handle the float reg cases directly when arch64,
3401 ;; hard_quad, and proper reg number alignment are all true.
3402 (define_insn "*movtf_insn_hq_sp64"
3403   [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,o,r")
3404         (match_operand:TF 1 "input_operand"    "e,m,e,Gr,roG"))]
3405   "TARGET_FPU
3406    && ! TARGET_VIS
3407    && TARGET_ARCH64
3408    && TARGET_HARD_QUAD
3409    && (register_operand (operands[0], TFmode)
3410        || register_operand (operands[1], TFmode)
3411        || fp_zero_operand (operands[1], TFmode))"
3412   "@
3413   fmovq\t%1, %0
3414   ldq\t%1, %0
3415   stq\t%1, %0
3416   #
3417   #"
3418   [(set_attr "type" "fpmove,fpload,fpstore,*,*")
3419    (set_attr "length" "*,*,*,2,2")])
3421 (define_insn "*movtf_insn_hq_vis_sp64"
3422   [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,eo,r,o")
3423         (match_operand:TF 1 "input_operand"    "e,m,e,G,roG,r"))]
3424   "TARGET_FPU
3425    && TARGET_VIS
3426    && TARGET_ARCH64
3427    && TARGET_HARD_QUAD
3428    && (register_operand (operands[0], TFmode)
3429        || register_operand (operands[1], TFmode)
3430        || fp_zero_operand (operands[1], TFmode))"
3431   "@
3432   fmovq\t%1, %0
3433   ldq\t%1, %0
3434   stq\t%1, %0
3435   #
3436   #
3437   #"
3438   [(set_attr "type" "fpmove,fpload,fpstore,*,*,*")
3439    (set_attr "length" "*,*,*,2,2,2")])
3441 ;; Now we allow the integer register cases even when
3442 ;; only arch64 is true.
3443 (define_insn "*movtf_insn_sp64"
3444   [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3445         (match_operand:TF 1 "input_operand"    "oe,Ger,orG"))]
3446   "TARGET_FPU
3447    && ! TARGET_VIS
3448    && TARGET_ARCH64
3449    && ! TARGET_HARD_QUAD
3450    && (register_operand (operands[0], TFmode)
3451        || register_operand (operands[1], TFmode)
3452        || fp_zero_operand (operands[1], TFmode))"
3453   "#"
3454   [(set_attr "length" "2")])
3456 (define_insn "*movtf_insn_vis_sp64"
3457   [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
3458         (match_operand:TF 1 "input_operand"    "Goe,Ger,orG"))]
3459   "TARGET_FPU
3460    && TARGET_VIS
3461    && TARGET_ARCH64
3462    && ! TARGET_HARD_QUAD
3463    && (register_operand (operands[0], TFmode)
3464        || register_operand (operands[1], TFmode)
3465        || fp_zero_operand (operands[1], TFmode))"
3466   "#"
3467   [(set_attr "length" "2")])
3469 (define_insn "*movtf_no_e_insn_sp64"
3470   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
3471         (match_operand:TF 1 "input_operand"    "orG,rG"))]
3472   "! TARGET_FPU
3473    && TARGET_ARCH64
3474    && (register_operand (operands[0], TFmode)
3475        || register_operand (operands[1], TFmode)
3476        || fp_zero_operand (operands[1], TFmode))"
3477   "#"
3478   [(set_attr "length" "2")])
3480 ;; Now all the splits to handle multi-insn TF mode moves.
3481 (define_split
3482   [(set (match_operand:TF 0 "register_operand" "")
3483         (match_operand:TF 1 "register_operand" ""))]
3484   "reload_completed
3485    && (! TARGET_ARCH64
3486        || (TARGET_FPU
3487            && ! TARGET_HARD_QUAD)
3488        || ! fp_register_operand (operands[0], TFmode))"
3489   [(clobber (const_int 0))]
3491   rtx set_dest = operands[0];
3492   rtx set_src = operands[1];
3493   rtx dest1, dest2;
3494   rtx src1, src2;
3496   dest1 = gen_df_reg (set_dest, 0);
3497   dest2 = gen_df_reg (set_dest, 1);
3498   src1 = gen_df_reg (set_src, 0);
3499   src2 = gen_df_reg (set_src, 1);
3501   /* Now emit using the real source and destination we found, swapping
3502      the order if we detect overlap.  */
3503   if (reg_overlap_mentioned_p (dest1, src2))
3504     {
3505       emit_insn (gen_movdf (dest2, src2));
3506       emit_insn (gen_movdf (dest1, src1));
3507     }
3508   else
3509     {
3510       emit_insn (gen_movdf (dest1, src1));
3511       emit_insn (gen_movdf (dest2, src2));
3512     }
3513   DONE;
3516 (define_split
3517   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3518         (match_operand:TF 1 "fp_zero_operand" ""))]
3519   "reload_completed"
3520   [(clobber (const_int 0))]
3522   rtx set_dest = operands[0];
3523   rtx dest1, dest2;
3525   switch (GET_CODE (set_dest))
3526     {
3527     case REG:
3528       dest1 = gen_df_reg (set_dest, 0);
3529       dest2 = gen_df_reg (set_dest, 1);
3530       break;
3531     case MEM:
3532       dest1 = adjust_address (set_dest, DFmode, 0);
3533       dest2 = adjust_address (set_dest, DFmode, 8);
3534       break;
3535     default:
3536       abort ();      
3537     }
3539   emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
3540   emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
3541   DONE;
3544 (define_split
3545   [(set (match_operand:TF 0 "register_operand" "")
3546         (match_operand:TF 1 "memory_operand" ""))]
3547   "(reload_completed
3548     && offsettable_memref_p (operands[1])
3549     && (! TARGET_ARCH64
3550         || ! TARGET_HARD_QUAD
3551         || ! fp_register_operand (operands[0], TFmode)))"
3552   [(clobber (const_int 0))]
3554   rtx word0 = adjust_address (operands[1], DFmode, 0);
3555   rtx word1 = adjust_address (operands[1], DFmode, 8);
3556   rtx set_dest, dest1, dest2;
3558   set_dest = operands[0];
3560   dest1 = gen_df_reg (set_dest, 0);
3561   dest2 = gen_df_reg (set_dest, 1);
3563   /* Now output, ordering such that we don't clobber any registers
3564      mentioned in the address.  */
3565   if (reg_overlap_mentioned_p (dest1, word1))
3567     {
3568       emit_insn (gen_movdf (dest2, word1));
3569       emit_insn (gen_movdf (dest1, word0));
3570     }
3571   else
3572    {
3573       emit_insn (gen_movdf (dest1, word0));
3574       emit_insn (gen_movdf (dest2, word1));
3575    }
3576   DONE;
3579 (define_split
3580   [(set (match_operand:TF 0 "memory_operand" "")
3581         (match_operand:TF 1 "register_operand" ""))]
3582   "(reload_completed
3583     && offsettable_memref_p (operands[0])
3584     && (! TARGET_ARCH64
3585         || ! TARGET_HARD_QUAD
3586         || ! fp_register_operand (operands[1], TFmode)))"
3587   [(clobber (const_int 0))]
3589   rtx set_src = operands[1];
3591   emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
3592                         gen_df_reg (set_src, 0)));
3593   emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
3594                         gen_df_reg (set_src, 1)));
3595   DONE;
3598 ;; SPARC V9 conditional move instructions.
3600 ;; We can handle larger constants here for some flavors, but for now we keep
3601 ;; it simple and only allow those constants supported by all flavors.
3602 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3603 ;; 3 contains the constant if one is present, but we handle either for
3604 ;; generality (sparc.c puts a constant in operand 2).
3606 (define_expand "movqicc"
3607   [(set (match_operand:QI 0 "register_operand" "")
3608         (if_then_else:QI (match_operand 1 "comparison_operator" "")
3609                          (match_operand:QI 2 "arith10_operand" "")
3610                          (match_operand:QI 3 "arith10_operand" "")))]
3611   "TARGET_V9"
3613   enum rtx_code code = GET_CODE (operands[1]);
3615   if (GET_MODE (sparc_compare_op0) == DImode
3616       && ! TARGET_ARCH64)
3617     FAIL;
3619   if (sparc_compare_op1 == const0_rtx
3620       && GET_CODE (sparc_compare_op0) == REG
3621       && GET_MODE (sparc_compare_op0) == DImode
3622       && v9_regcmp_p (code))
3623     {
3624       operands[1] = gen_rtx_fmt_ee (code, DImode,
3625                              sparc_compare_op0, sparc_compare_op1);
3626     }
3627   else
3628     {
3629       rtx cc_reg = gen_compare_reg (code,
3630                                     sparc_compare_op0, sparc_compare_op1);
3631       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3632     }
3635 (define_expand "movhicc"
3636   [(set (match_operand:HI 0 "register_operand" "")
3637         (if_then_else:HI (match_operand 1 "comparison_operator" "")
3638                          (match_operand:HI 2 "arith10_operand" "")
3639                          (match_operand:HI 3 "arith10_operand" "")))]
3640   "TARGET_V9"
3642   enum rtx_code code = GET_CODE (operands[1]);
3644   if (GET_MODE (sparc_compare_op0) == DImode
3645       && ! TARGET_ARCH64)
3646     FAIL;
3648   if (sparc_compare_op1 == const0_rtx
3649       && GET_CODE (sparc_compare_op0) == REG
3650       && GET_MODE (sparc_compare_op0) == DImode
3651       && v9_regcmp_p (code))
3652     {
3653       operands[1] = gen_rtx_fmt_ee (code, DImode,
3654                              sparc_compare_op0, sparc_compare_op1);
3655     }
3656   else
3657     {
3658       rtx cc_reg = gen_compare_reg (code,
3659                                     sparc_compare_op0, sparc_compare_op1);
3660       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3661     }
3664 (define_expand "movsicc"
3665   [(set (match_operand:SI 0 "register_operand" "")
3666         (if_then_else:SI (match_operand 1 "comparison_operator" "")
3667                          (match_operand:SI 2 "arith10_operand" "")
3668                          (match_operand:SI 3 "arith10_operand" "")))]
3669   "TARGET_V9"
3671   enum rtx_code code = GET_CODE (operands[1]);
3672   enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
3674   if (sparc_compare_op1 == const0_rtx
3675       && GET_CODE (sparc_compare_op0) == REG
3676       && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
3677     {
3678       operands[1] = gen_rtx_fmt_ee (code, op0_mode,
3679                              sparc_compare_op0, sparc_compare_op1);
3680     }
3681   else
3682     {
3683       rtx cc_reg = gen_compare_reg (code,
3684                                     sparc_compare_op0, sparc_compare_op1);
3685       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3686                                     cc_reg, const0_rtx);
3687     }
3690 (define_expand "movdicc"
3691   [(set (match_operand:DI 0 "register_operand" "")
3692         (if_then_else:DI (match_operand 1 "comparison_operator" "")
3693                          (match_operand:DI 2 "arith10_double_operand" "")
3694                          (match_operand:DI 3 "arith10_double_operand" "")))]
3695   "TARGET_ARCH64"
3697   enum rtx_code code = GET_CODE (operands[1]);
3699   if (sparc_compare_op1 == const0_rtx
3700       && GET_CODE (sparc_compare_op0) == REG
3701       && GET_MODE (sparc_compare_op0) == DImode
3702       && v9_regcmp_p (code))
3703     {
3704       operands[1] = gen_rtx_fmt_ee (code, DImode,
3705                              sparc_compare_op0, sparc_compare_op1);
3706     }
3707   else
3708     {
3709       rtx cc_reg = gen_compare_reg (code,
3710                                     sparc_compare_op0, sparc_compare_op1);
3711       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3712                                     cc_reg, const0_rtx);
3713     }
3716 (define_expand "movsfcc"
3717   [(set (match_operand:SF 0 "register_operand" "")
3718         (if_then_else:SF (match_operand 1 "comparison_operator" "")
3719                          (match_operand:SF 2 "register_operand" "")
3720                          (match_operand:SF 3 "register_operand" "")))]
3721   "TARGET_V9 && TARGET_FPU"
3723   enum rtx_code code = GET_CODE (operands[1]);
3725   if (GET_MODE (sparc_compare_op0) == DImode
3726       && ! TARGET_ARCH64)
3727     FAIL;
3729   if (sparc_compare_op1 == const0_rtx
3730       && GET_CODE (sparc_compare_op0) == REG
3731       && GET_MODE (sparc_compare_op0) == DImode
3732       && v9_regcmp_p (code))
3733     {
3734       operands[1] = gen_rtx_fmt_ee (code, DImode,
3735                              sparc_compare_op0, sparc_compare_op1);
3736     }
3737   else
3738     {
3739       rtx cc_reg = gen_compare_reg (code,
3740                                     sparc_compare_op0, sparc_compare_op1);
3741       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3742     }
3745 (define_expand "movdfcc"
3746   [(set (match_operand:DF 0 "register_operand" "")
3747         (if_then_else:DF (match_operand 1 "comparison_operator" "")
3748                          (match_operand:DF 2 "register_operand" "")
3749                          (match_operand:DF 3 "register_operand" "")))]
3750   "TARGET_V9 && TARGET_FPU"
3752   enum rtx_code code = GET_CODE (operands[1]);
3754   if (GET_MODE (sparc_compare_op0) == DImode
3755       && ! TARGET_ARCH64)
3756     FAIL;
3758   if (sparc_compare_op1 == const0_rtx
3759       && GET_CODE (sparc_compare_op0) == REG
3760       && GET_MODE (sparc_compare_op0) == DImode
3761       && v9_regcmp_p (code))
3762     {
3763       operands[1] = gen_rtx_fmt_ee (code, DImode,
3764                              sparc_compare_op0, sparc_compare_op1);
3765     }
3766   else
3767     {
3768       rtx cc_reg = gen_compare_reg (code,
3769                                     sparc_compare_op0, sparc_compare_op1);
3770       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3771     }
3774 (define_expand "movtfcc"
3775   [(set (match_operand:TF 0 "register_operand" "")
3776         (if_then_else:TF (match_operand 1 "comparison_operator" "")
3777                          (match_operand:TF 2 "register_operand" "")
3778                          (match_operand:TF 3 "register_operand" "")))]
3779   "TARGET_V9 && TARGET_FPU"
3781   enum rtx_code code = GET_CODE (operands[1]);
3783   if (GET_MODE (sparc_compare_op0) == DImode
3784       && ! TARGET_ARCH64)
3785     FAIL;
3787   if (sparc_compare_op1 == const0_rtx
3788       && GET_CODE (sparc_compare_op0) == REG
3789       && GET_MODE (sparc_compare_op0) == DImode
3790       && v9_regcmp_p (code))
3791     {
3792       operands[1] = gen_rtx_fmt_ee (code, DImode,
3793                              sparc_compare_op0, sparc_compare_op1);
3794     }
3795   else
3796     {
3797       rtx cc_reg = gen_compare_reg (code,
3798                                     sparc_compare_op0, sparc_compare_op1);
3799       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3800     }
3803 ;; Conditional move define_insns.
3805 (define_insn "*movqi_cc_sp64"
3806   [(set (match_operand:QI 0 "register_operand" "=r,r")
3807         (if_then_else:QI (match_operator 1 "comparison_operator"
3808                                 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3809                                  (const_int 0)])
3810                          (match_operand:QI 3 "arith11_operand" "rL,0")
3811                          (match_operand:QI 4 "arith11_operand" "0,rL")))]
3812   "TARGET_V9"
3813   "@
3814    mov%C1\t%x2, %3, %0
3815    mov%c1\t%x2, %4, %0"
3816   [(set_attr "type" "cmove")])
3818 (define_insn "*movhi_cc_sp64"
3819   [(set (match_operand:HI 0 "register_operand" "=r,r")
3820         (if_then_else:HI (match_operator 1 "comparison_operator"
3821                                 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3822                                  (const_int 0)])
3823                          (match_operand:HI 3 "arith11_operand" "rL,0")
3824                          (match_operand:HI 4 "arith11_operand" "0,rL")))]
3825   "TARGET_V9"
3826   "@
3827    mov%C1\t%x2, %3, %0
3828    mov%c1\t%x2, %4, %0"
3829   [(set_attr "type" "cmove")])
3831 (define_insn "*movsi_cc_sp64"
3832   [(set (match_operand:SI 0 "register_operand" "=r,r")
3833         (if_then_else:SI (match_operator 1 "comparison_operator"
3834                                 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3835                                  (const_int 0)])
3836                          (match_operand:SI 3 "arith11_operand" "rL,0")
3837                          (match_operand:SI 4 "arith11_operand" "0,rL")))]
3838   "TARGET_V9"
3839   "@
3840    mov%C1\t%x2, %3, %0
3841    mov%c1\t%x2, %4, %0"
3842   [(set_attr "type" "cmove")])
3844 ;; ??? The constraints of operands 3,4 need work.
3845 (define_insn "*movdi_cc_sp64"
3846   [(set (match_operand:DI 0 "register_operand" "=r,r")
3847         (if_then_else:DI (match_operator 1 "comparison_operator"
3848                                 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3849                                  (const_int 0)])
3850                          (match_operand:DI 3 "arith11_double_operand" "rLH,0")
3851                          (match_operand:DI 4 "arith11_double_operand" "0,rLH")))]
3852   "TARGET_ARCH64"
3853   "@
3854    mov%C1\t%x2, %3, %0
3855    mov%c1\t%x2, %4, %0"
3856   [(set_attr "type" "cmove")])
3858 (define_insn "*movdi_cc_sp64_trunc"
3859   [(set (match_operand:SI 0 "register_operand" "=r,r")
3860         (if_then_else:SI (match_operator 1 "comparison_operator"
3861                                 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3862                                  (const_int 0)])
3863                          (match_operand:SI 3 "arith11_double_operand" "rLH,0")
3864                          (match_operand:SI 4 "arith11_double_operand" "0,rLH")))]
3865   "TARGET_ARCH64"
3866   "@
3867    mov%C1\t%x2, %3, %0
3868    mov%c1\t%x2, %4, %0"
3869   [(set_attr "type" "cmove")])
3871 (define_insn "*movsf_cc_sp64"
3872   [(set (match_operand:SF 0 "register_operand" "=f,f")
3873         (if_then_else:SF (match_operator 1 "comparison_operator"
3874                                 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3875                                  (const_int 0)])
3876                          (match_operand:SF 3 "register_operand" "f,0")
3877                          (match_operand:SF 4 "register_operand" "0,f")))]
3878   "TARGET_V9 && TARGET_FPU"
3879   "@
3880    fmovs%C1\t%x2, %3, %0
3881    fmovs%c1\t%x2, %4, %0"
3882   [(set_attr "type" "fpcmove")])
3884 (define_insn "movdf_cc_sp64"
3885   [(set (match_operand:DF 0 "register_operand" "=e,e")
3886         (if_then_else:DF (match_operator 1 "comparison_operator"
3887                                 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3888                                  (const_int 0)])
3889                          (match_operand:DF 3 "register_operand" "e,0")
3890                          (match_operand:DF 4 "register_operand" "0,e")))]
3891   "TARGET_V9 && TARGET_FPU"
3892   "@
3893    fmovd%C1\t%x2, %3, %0
3894    fmovd%c1\t%x2, %4, %0"
3895   [(set_attr "type" "fpcmove")
3896    (set_attr "fptype" "double")])
3898 (define_insn "*movtf_cc_hq_sp64"
3899   [(set (match_operand:TF 0 "register_operand" "=e,e")
3900         (if_then_else:TF (match_operator 1 "comparison_operator"
3901                                 [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3902                                  (const_int 0)])
3903                          (match_operand:TF 3 "register_operand" "e,0")
3904                          (match_operand:TF 4 "register_operand" "0,e")))]
3905   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3906   "@
3907    fmovq%C1\t%x2, %3, %0
3908    fmovq%c1\t%x2, %4, %0"
3909   [(set_attr "type" "fpcmove")])
3911 (define_insn_and_split "*movtf_cc_sp64"
3912   [(set (match_operand:TF 0 "register_operand" "=e,e")
3913         (if_then_else:TF (match_operator 1 "comparison_operator"
3914                             [(match_operand 2 "icc_or_fcc_reg_operand" "X,X")
3915                              (const_int 0)])
3916                          (match_operand:TF 3 "register_operand" "e,0")
3917                          (match_operand:TF 4 "register_operand" "0,e")))]
3918   "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
3919   "#"
3920   "&& reload_completed"
3921   [(clobber (const_int 0))]
3923   rtx set_dest = operands[0];
3924   rtx set_srca = operands[3];
3925   rtx set_srcb = operands[4];
3926   int third = rtx_equal_p (set_dest, set_srca);
3927   rtx dest1, dest2;
3928   rtx srca1, srca2, srcb1, srcb2;
3930   dest1 = gen_df_reg (set_dest, 0);
3931   dest2 = gen_df_reg (set_dest, 1);
3932   srca1 = gen_df_reg (set_srca, 0);
3933   srca2 = gen_df_reg (set_srca, 1);
3934   srcb1 = gen_df_reg (set_srcb, 0);
3935   srcb2 = gen_df_reg (set_srcb, 1);
3937   /* Now emit using the real source and destination we found, swapping
3938      the order if we detect overlap.  */
3939   if ((third && reg_overlap_mentioned_p (dest1, srcb2))
3940       || (!third && reg_overlap_mentioned_p (dest1, srca2)))
3941     {
3942       emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3943       emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3944     }
3945   else
3946     {
3947       emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3948       emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3949     }
3950   DONE;
3952   [(set_attr "length" "2")])
3954 (define_insn "*movqi_cc_reg_sp64"
3955   [(set (match_operand:QI 0 "register_operand" "=r,r")
3956         (if_then_else:QI (match_operator 1 "v9_regcmp_op"
3957                                 [(match_operand:DI 2 "register_operand" "r,r")
3958                                  (const_int 0)])
3959                          (match_operand:QI 3 "arith10_operand" "rM,0")
3960                          (match_operand:QI 4 "arith10_operand" "0,rM")))]
3961   "TARGET_ARCH64"
3962   "@
3963    movr%D1\t%2, %r3, %0
3964    movr%d1\t%2, %r4, %0"
3965   [(set_attr "type" "cmove")])
3967 (define_insn "*movhi_cc_reg_sp64"
3968   [(set (match_operand:HI 0 "register_operand" "=r,r")
3969         (if_then_else:HI (match_operator 1 "v9_regcmp_op"
3970                                 [(match_operand:DI 2 "register_operand" "r,r")
3971                                  (const_int 0)])
3972                          (match_operand:HI 3 "arith10_operand" "rM,0")
3973                          (match_operand:HI 4 "arith10_operand" "0,rM")))]
3974   "TARGET_ARCH64"
3975   "@
3976    movr%D1\t%2, %r3, %0
3977    movr%d1\t%2, %r4, %0"
3978   [(set_attr "type" "cmove")])
3980 (define_insn "*movsi_cc_reg_sp64"
3981   [(set (match_operand:SI 0 "register_operand" "=r,r")
3982         (if_then_else:SI (match_operator 1 "v9_regcmp_op"
3983                                 [(match_operand:DI 2 "register_operand" "r,r")
3984                                  (const_int 0)])
3985                          (match_operand:SI 3 "arith10_operand" "rM,0")
3986                          (match_operand:SI 4 "arith10_operand" "0,rM")))]
3987   "TARGET_ARCH64"
3988   "@
3989    movr%D1\t%2, %r3, %0
3990    movr%d1\t%2, %r4, %0"
3991   [(set_attr "type" "cmove")])
3993 ;; ??? The constraints of operands 3,4 need work.
3994 (define_insn "*movdi_cc_reg_sp64"
3995   [(set (match_operand:DI 0 "register_operand" "=r,r")
3996         (if_then_else:DI (match_operator 1 "v9_regcmp_op"
3997                                 [(match_operand:DI 2 "register_operand" "r,r")
3998                                  (const_int 0)])
3999                          (match_operand:DI 3 "arith10_double_operand" "rMH,0")
4000                          (match_operand:DI 4 "arith10_double_operand" "0,rMH")))]
4001   "TARGET_ARCH64"
4002   "@
4003    movr%D1\t%2, %r3, %0
4004    movr%d1\t%2, %r4, %0"
4005   [(set_attr "type" "cmove")])
4007 (define_insn "*movdi_cc_reg_sp64_trunc"
4008   [(set (match_operand:SI 0 "register_operand" "=r,r")
4009         (if_then_else:SI (match_operator 1 "v9_regcmp_op"
4010                                 [(match_operand:DI 2 "register_operand" "r,r")
4011                                  (const_int 0)])
4012                          (match_operand:SI 3 "arith10_double_operand" "rMH,0")
4013                          (match_operand:SI 4 "arith10_double_operand" "0,rMH")))]
4014   "TARGET_ARCH64"
4015   "@
4016    movr%D1\t%2, %r3, %0
4017    movr%d1\t%2, %r4, %0"
4018   [(set_attr "type" "cmove")])
4020 (define_insn "*movsf_cc_reg_sp64"
4021   [(set (match_operand:SF 0 "register_operand" "=f,f")
4022         (if_then_else:SF (match_operator 1 "v9_regcmp_op"
4023                                 [(match_operand:DI 2 "register_operand" "r,r")
4024                                  (const_int 0)])
4025                          (match_operand:SF 3 "register_operand" "f,0")
4026                          (match_operand:SF 4 "register_operand" "0,f")))]
4027   "TARGET_ARCH64 && TARGET_FPU"
4028   "@
4029    fmovrs%D1\t%2, %3, %0
4030    fmovrs%d1\t%2, %4, %0"
4031   [(set_attr "type" "fpcrmove")])
4033 (define_insn "movdf_cc_reg_sp64"
4034   [(set (match_operand:DF 0 "register_operand" "=e,e")
4035         (if_then_else:DF (match_operator 1 "v9_regcmp_op"
4036                                 [(match_operand:DI 2 "register_operand" "r,r")
4037                                  (const_int 0)])
4038                          (match_operand:DF 3 "register_operand" "e,0")
4039                          (match_operand:DF 4 "register_operand" "0,e")))]
4040   "TARGET_ARCH64 && TARGET_FPU"
4041   "@
4042    fmovrd%D1\t%2, %3, %0
4043    fmovrd%d1\t%2, %4, %0"
4044   [(set_attr "type" "fpcrmove")
4045    (set_attr "fptype" "double")])
4047 (define_insn "*movtf_cc_reg_hq_sp64"
4048   [(set (match_operand:TF 0 "register_operand" "=e,e")
4049         (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4050                                 [(match_operand:DI 2 "register_operand" "r,r")
4051                                  (const_int 0)])
4052                          (match_operand:TF 3 "register_operand" "e,0")
4053                          (match_operand:TF 4 "register_operand" "0,e")))]
4054   "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
4055   "@
4056    fmovrq%D1\t%2, %3, %0
4057    fmovrq%d1\t%2, %4, %0"
4058   [(set_attr "type" "fpcrmove")])
4060 (define_insn_and_split "*movtf_cc_reg_sp64"
4061   [(set (match_operand:TF 0 "register_operand" "=e,e")
4062         (if_then_else:TF (match_operator 1 "v9_regcmp_op"
4063                                 [(match_operand:DI 2 "register_operand" "r,r")
4064                                  (const_int 0)])
4065                          (match_operand:TF 3 "register_operand" "e,0")
4066                          (match_operand:TF 4 "register_operand" "0,e")))]
4067   "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
4068   "#"
4069   "&& reload_completed"
4070   [(clobber (const_int 0))]
4072   rtx set_dest = operands[0];
4073   rtx set_srca = operands[3];
4074   rtx set_srcb = operands[4];
4075   int third = rtx_equal_p (set_dest, set_srca);
4076   rtx dest1, dest2;
4077   rtx srca1, srca2, srcb1, srcb2;
4079   dest1 = gen_df_reg (set_dest, 0);
4080   dest2 = gen_df_reg (set_dest, 1);
4081   srca1 = gen_df_reg (set_srca, 0);
4082   srca2 = gen_df_reg (set_srca, 1);
4083   srcb1 = gen_df_reg (set_srcb, 0);
4084   srcb2 = gen_df_reg (set_srcb, 1);
4086   /* Now emit using the real source and destination we found, swapping
4087      the order if we detect overlap.  */
4088   if ((third && reg_overlap_mentioned_p (dest1, srcb2))
4089       || (!third && reg_overlap_mentioned_p (dest1, srca2)))
4090     {
4091       emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4092       emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4093     }
4094   else
4095     {
4096       emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
4097       emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
4098     }
4099   DONE;
4101   [(set_attr "length" "2")])
4104 ;;- zero extension instructions
4106 ;; These patterns originally accepted general_operands, however, slightly
4107 ;; better code is generated by only accepting register_operands, and then
4108 ;; letting combine generate the ldu[hb] insns.
4110 (define_expand "zero_extendhisi2"
4111   [(set (match_operand:SI 0 "register_operand" "")
4112         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
4113   ""
4115   rtx temp = gen_reg_rtx (SImode);
4116   rtx shift_16 = GEN_INT (16);
4117   int op1_subbyte = 0;
4119   if (GET_CODE (operand1) == SUBREG)
4120     {
4121       op1_subbyte = SUBREG_BYTE (operand1);
4122       op1_subbyte /= GET_MODE_SIZE (SImode);
4123       op1_subbyte *= GET_MODE_SIZE (SImode);
4124       operand1 = XEXP (operand1, 0);
4125     }
4127   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4128                           shift_16));
4129   emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
4130   DONE;
4133 (define_insn "*zero_extendhisi2_insn"
4134   [(set (match_operand:SI 0 "register_operand" "=r")
4135         (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4136   ""
4137   "lduh\t%1, %0"
4138   [(set_attr "type" "load")
4139    (set_attr "us3load_type" "3cycle")])
4141 (define_expand "zero_extendqihi2"
4142   [(set (match_operand:HI 0 "register_operand" "")
4143         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
4144   ""
4145   "")
4147 (define_insn "*zero_extendqihi2_insn"
4148   [(set (match_operand:HI 0 "register_operand" "=r,r")
4149         (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
4150   "GET_CODE (operands[1]) != CONST_INT"
4151   "@
4152    and\t%1, 0xff, %0
4153    ldub\t%1, %0"
4154   [(set_attr "type" "*,load")
4155    (set_attr "us3load_type" "*,3cycle")])
4157 (define_expand "zero_extendqisi2"
4158   [(set (match_operand:SI 0 "register_operand" "")
4159         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
4160   ""
4161   "")
4163 (define_insn "*zero_extendqisi2_insn"
4164   [(set (match_operand:SI 0 "register_operand" "=r,r")
4165         (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
4166   "GET_CODE (operands[1]) != CONST_INT"
4167   "@
4168    and\t%1, 0xff, %0
4169    ldub\t%1, %0"
4170   [(set_attr "type" "*,load")
4171    (set_attr "us3load_type" "*,3cycle")])
4173 (define_expand "zero_extendqidi2"
4174   [(set (match_operand:DI 0 "register_operand" "")
4175         (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
4176   "TARGET_ARCH64"
4177   "")
4179 (define_insn "*zero_extendqidi2_insn"
4180   [(set (match_operand:DI 0 "register_operand" "=r,r")
4181         (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
4182   "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4183   "@
4184    and\t%1, 0xff, %0
4185    ldub\t%1, %0"
4186   [(set_attr "type" "*,load")
4187    (set_attr "us3load_type" "*,3cycle")])
4189 (define_expand "zero_extendhidi2"
4190   [(set (match_operand:DI 0 "register_operand" "")
4191         (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
4192   "TARGET_ARCH64"
4194   rtx temp = gen_reg_rtx (DImode);
4195   rtx shift_48 = GEN_INT (48);
4196   int op1_subbyte = 0;
4198   if (GET_CODE (operand1) == SUBREG)
4199     {
4200       op1_subbyte = SUBREG_BYTE (operand1);
4201       op1_subbyte /= GET_MODE_SIZE (DImode);
4202       op1_subbyte *= GET_MODE_SIZE (DImode);
4203       operand1 = XEXP (operand1, 0);
4204     }
4206   emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4207                           shift_48));
4208   emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
4209   DONE;
4212 (define_insn "*zero_extendhidi2_insn"
4213   [(set (match_operand:DI 0 "register_operand" "=r")
4214         (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4215   "TARGET_ARCH64"
4216   "lduh\t%1, %0"
4217   [(set_attr "type" "load")
4218    (set_attr "us3load_type" "3cycle")])
4221 ;; ??? Write truncdisi pattern using sra?
4223 (define_expand "zero_extendsidi2"
4224   [(set (match_operand:DI 0 "register_operand" "")
4225         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
4226   ""
4227   "")
4229 (define_insn "*zero_extendsidi2_insn_sp64"
4230   [(set (match_operand:DI 0 "register_operand" "=r,r")
4231         (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4232   "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
4233   "@
4234    srl\t%1, 0, %0
4235    lduw\t%1, %0"
4236   [(set_attr "type" "shift,load")])
4238 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
4239   [(set (match_operand:DI 0 "register_operand" "=r")
4240         (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
4241   "! TARGET_ARCH64"
4242   "#"
4243   "&& reload_completed"
4244   [(set (match_dup 2) (match_dup 3))
4245    (set (match_dup 4) (match_dup 5))]
4247   rtx dest1, dest2;
4249   dest1 = gen_highpart (SImode, operands[0]);
4250   dest2 = gen_lowpart (SImode, operands[0]);
4252   /* Swap the order in case of overlap.  */
4253   if (REGNO (dest1) == REGNO (operands[1]))
4254     {
4255       operands[2] = dest2;
4256       operands[3] = operands[1];
4257       operands[4] = dest1;
4258       operands[5] = const0_rtx;
4259     }
4260   else
4261     {
4262       operands[2] = dest1;
4263       operands[3] = const0_rtx;
4264       operands[4] = dest2;
4265       operands[5] = operands[1];
4266     }
4268   [(set_attr "length" "2")])
4270 ;; Simplify comparisons of extended values.
4272 (define_insn "*cmp_zero_extendqisi2"
4273   [(set (reg:CC 100)
4274         (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
4275                     (const_int 0)))]
4276   ""
4277   "andcc\t%0, 0xff, %%g0"
4278   [(set_attr "type" "compare")])
4280 (define_insn "*cmp_zero_qi"
4281   [(set (reg:CC 100)
4282         (compare:CC (match_operand:QI 0 "register_operand" "r")
4283                     (const_int 0)))]
4284   ""
4285   "andcc\t%0, 0xff, %%g0"
4286   [(set_attr "type" "compare")])
4288 (define_insn "*cmp_zero_extendqisi2_set"
4289   [(set (reg:CC 100)
4290         (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
4291                     (const_int 0)))
4292    (set (match_operand:SI 0 "register_operand" "=r")
4293         (zero_extend:SI (match_dup 1)))]
4294   ""
4295   "andcc\t%1, 0xff, %0"
4296   [(set_attr "type" "compare")])
4298 (define_insn "*cmp_zero_extendqisi2_andcc_set"
4299   [(set (reg:CC 100)
4300         (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
4301                             (const_int 255))
4302                     (const_int 0)))
4303    (set (match_operand:SI 0 "register_operand" "=r")
4304         (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
4305   ""
4306   "andcc\t%1, 0xff, %0"
4307   [(set_attr "type" "compare")])
4309 (define_insn "*cmp_zero_extendqidi2"
4310   [(set (reg:CCX 100)
4311         (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
4312                      (const_int 0)))]
4313   "TARGET_ARCH64"
4314   "andcc\t%0, 0xff, %%g0"
4315   [(set_attr "type" "compare")])
4317 (define_insn "*cmp_zero_qi_sp64"
4318   [(set (reg:CCX 100)
4319         (compare:CCX (match_operand:QI 0 "register_operand" "r")
4320                      (const_int 0)))]
4321   "TARGET_ARCH64"
4322   "andcc\t%0, 0xff, %%g0"
4323   [(set_attr "type" "compare")])
4325 (define_insn "*cmp_zero_extendqidi2_set"
4326   [(set (reg:CCX 100)
4327         (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
4328                      (const_int 0)))
4329    (set (match_operand:DI 0 "register_operand" "=r")
4330         (zero_extend:DI (match_dup 1)))]
4331   "TARGET_ARCH64"
4332   "andcc\t%1, 0xff, %0"
4333   [(set_attr "type" "compare")])
4335 (define_insn "*cmp_zero_extendqidi2_andcc_set"
4336   [(set (reg:CCX 100)
4337         (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
4338                              (const_int 255))
4339                      (const_int 0)))
4340    (set (match_operand:DI 0 "register_operand" "=r")
4341         (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
4342   "TARGET_ARCH64"
4343   "andcc\t%1, 0xff, %0"
4344   [(set_attr "type" "compare")])
4346 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
4348 (define_insn "*cmp_siqi_trunc"
4349   [(set (reg:CC 100)
4350         (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
4351                     (const_int 0)))]
4352   ""
4353   "andcc\t%0, 0xff, %%g0"
4354   [(set_attr "type" "compare")])
4356 (define_insn "*cmp_siqi_trunc_set"
4357   [(set (reg:CC 100)
4358         (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
4359                     (const_int 0)))
4360    (set (match_operand:QI 0 "register_operand" "=r")
4361         (subreg:QI (match_dup 1) 3))]
4362   ""
4363   "andcc\t%1, 0xff, %0"
4364   [(set_attr "type" "compare")])
4366 (define_insn "*cmp_diqi_trunc"
4367   [(set (reg:CC 100)
4368         (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
4369                     (const_int 0)))]
4370   "TARGET_ARCH64"
4371   "andcc\t%0, 0xff, %%g0"
4372   [(set_attr "type" "compare")])
4374 (define_insn "*cmp_diqi_trunc_set"
4375   [(set (reg:CC 100)
4376         (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
4377                     (const_int 0)))
4378    (set (match_operand:QI 0 "register_operand" "=r")
4379         (subreg:QI (match_dup 1) 7))]
4380   "TARGET_ARCH64"
4381   "andcc\t%1, 0xff, %0"
4382   [(set_attr "type" "compare")])
4384 ;;- sign extension instructions
4386 ;; These patterns originally accepted general_operands, however, slightly
4387 ;; better code is generated by only accepting register_operands, and then
4388 ;; letting combine generate the lds[hb] insns.
4390 (define_expand "extendhisi2"
4391   [(set (match_operand:SI 0 "register_operand" "")
4392         (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
4393   ""
4395   rtx temp = gen_reg_rtx (SImode);
4396   rtx shift_16 = GEN_INT (16);
4397   int op1_subbyte = 0;
4399   if (GET_CODE (operand1) == SUBREG)
4400     {
4401       op1_subbyte = SUBREG_BYTE (operand1);
4402       op1_subbyte /= GET_MODE_SIZE (SImode);
4403       op1_subbyte *= GET_MODE_SIZE (SImode);
4404       operand1 = XEXP (operand1, 0);
4405     }
4407   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4408                           shift_16));
4409   emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
4410   DONE;
4413 (define_insn "*sign_extendhisi2_insn"
4414   [(set (match_operand:SI 0 "register_operand" "=r")
4415         (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
4416   ""
4417   "ldsh\t%1, %0"
4418   [(set_attr "type" "sload")
4419    (set_attr "us3load_type" "3cycle")])
4421 (define_expand "extendqihi2"
4422   [(set (match_operand:HI 0 "register_operand" "")
4423         (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
4424   ""
4426   rtx temp = gen_reg_rtx (SImode);
4427   rtx shift_24 = GEN_INT (24);
4428   int op1_subbyte = 0;
4429   int op0_subbyte = 0;
4431   if (GET_CODE (operand1) == SUBREG)
4432     {
4433       op1_subbyte = SUBREG_BYTE (operand1);
4434       op1_subbyte /= GET_MODE_SIZE (SImode);
4435       op1_subbyte *= GET_MODE_SIZE (SImode);
4436       operand1 = XEXP (operand1, 0);
4437     }
4438   if (GET_CODE (operand0) == SUBREG)
4439     {
4440       op0_subbyte = SUBREG_BYTE (operand0);
4441       op0_subbyte /= GET_MODE_SIZE (SImode);
4442       op0_subbyte *= GET_MODE_SIZE (SImode);
4443       operand0 = XEXP (operand0, 0);
4444     }
4445   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4446                           shift_24));
4447   if (GET_MODE (operand0) != SImode)
4448     operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
4449   emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4450   DONE;
4453 (define_insn "*sign_extendqihi2_insn"
4454   [(set (match_operand:HI 0 "register_operand" "=r")
4455         (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
4456   ""
4457   "ldsb\t%1, %0"
4458   [(set_attr "type" "sload")
4459    (set_attr "us3load_type" "3cycle")])
4461 (define_expand "extendqisi2"
4462   [(set (match_operand:SI 0 "register_operand" "")
4463         (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
4464   ""
4466   rtx temp = gen_reg_rtx (SImode);
4467   rtx shift_24 = GEN_INT (24);
4468   int op1_subbyte = 0;
4470   if (GET_CODE (operand1) == SUBREG)
4471     {
4472       op1_subbyte = SUBREG_BYTE (operand1);
4473       op1_subbyte /= GET_MODE_SIZE (SImode);
4474       op1_subbyte *= GET_MODE_SIZE (SImode);
4475       operand1 = XEXP (operand1, 0);
4476     }
4478   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
4479                           shift_24));
4480   emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
4481   DONE;
4484 (define_insn "*sign_extendqisi2_insn"
4485   [(set (match_operand:SI 0 "register_operand" "=r")
4486         (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
4487   ""
4488   "ldsb\t%1, %0"
4489   [(set_attr "type" "sload")
4490    (set_attr "us3load_type" "3cycle")])
4492 (define_expand "extendqidi2"
4493   [(set (match_operand:DI 0 "register_operand" "")
4494         (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
4495   "TARGET_ARCH64"
4497   rtx temp = gen_reg_rtx (DImode);
4498   rtx shift_56 = GEN_INT (56);
4499   int op1_subbyte = 0;
4501   if (GET_CODE (operand1) == SUBREG)
4502     {
4503       op1_subbyte = SUBREG_BYTE (operand1);
4504       op1_subbyte /= GET_MODE_SIZE (DImode);
4505       op1_subbyte *= GET_MODE_SIZE (DImode);
4506       operand1 = XEXP (operand1, 0);
4507     }
4509   emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4510                           shift_56));
4511   emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
4512   DONE;
4515 (define_insn "*sign_extendqidi2_insn"
4516   [(set (match_operand:DI 0 "register_operand" "=r")
4517         (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
4518   "TARGET_ARCH64"
4519   "ldsb\t%1, %0"
4520   [(set_attr "type" "sload")
4521    (set_attr "us3load_type" "3cycle")])
4523 (define_expand "extendhidi2"
4524   [(set (match_operand:DI 0 "register_operand" "")
4525         (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
4526   "TARGET_ARCH64"
4528   rtx temp = gen_reg_rtx (DImode);
4529   rtx shift_48 = GEN_INT (48);
4530   int op1_subbyte = 0;
4532   if (GET_CODE (operand1) == SUBREG)
4533     {
4534       op1_subbyte = SUBREG_BYTE (operand1);
4535       op1_subbyte /= GET_MODE_SIZE (DImode);
4536       op1_subbyte *= GET_MODE_SIZE (DImode);
4537       operand1 = XEXP (operand1, 0);
4538     }
4540   emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
4541                           shift_48));
4542   emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
4543   DONE;
4546 (define_insn "*sign_extendhidi2_insn"
4547   [(set (match_operand:DI 0 "register_operand" "=r")
4548         (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
4549   "TARGET_ARCH64"
4550   "ldsh\t%1, %0"
4551   [(set_attr "type" "sload")
4552    (set_attr "us3load_type" "3cycle")])
4554 (define_expand "extendsidi2"
4555   [(set (match_operand:DI 0 "register_operand" "")
4556         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
4557   "TARGET_ARCH64"
4558   "")
4560 (define_insn "*sign_extendsidi2_insn"
4561   [(set (match_operand:DI 0 "register_operand" "=r,r")
4562         (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
4563   "TARGET_ARCH64"
4564   "@
4565   sra\t%1, 0, %0
4566   ldsw\t%1, %0"
4567   [(set_attr "type" "shift,sload")
4568    (set_attr "us3load_type" "*,3cycle")])
4570 ;; Special pattern for optimizing bit-field compares.  This is needed
4571 ;; because combine uses this as a canonical form.
4573 (define_insn "*cmp_zero_extract"
4574   [(set (reg:CC 100)
4575         (compare:CC
4576          (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
4577                           (match_operand:SI 1 "small_int_or_double" "n")
4578                           (match_operand:SI 2 "small_int_or_double" "n"))
4579          (const_int 0)))]
4580   "(GET_CODE (operands[2]) == CONST_INT
4581     && INTVAL (operands[2]) > 19)
4582    || (GET_CODE (operands[2]) == CONST_DOUBLE
4583        && CONST_DOUBLE_LOW (operands[2]) > 19)"
4585   int len = (GET_CODE (operands[1]) == CONST_INT
4586              ? INTVAL (operands[1])
4587              : CONST_DOUBLE_LOW (operands[1]));
4588   int pos = 32 -
4589             (GET_CODE (operands[2]) == CONST_INT
4590              ? INTVAL (operands[2])
4591              : CONST_DOUBLE_LOW (operands[2])) - len;
4592   HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
4594   operands[1] = GEN_INT (mask);
4595   return "andcc\t%0, %1, %%g0";
4597   [(set_attr "type" "compare")])
4599 (define_insn "*cmp_zero_extract_sp64"
4600   [(set (reg:CCX 100)
4601         (compare:CCX
4602          (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
4603                           (match_operand:SI 1 "small_int_or_double" "n")
4604                           (match_operand:SI 2 "small_int_or_double" "n"))
4605          (const_int 0)))]
4606   "TARGET_ARCH64
4607    && ((GET_CODE (operands[2]) == CONST_INT
4608         && INTVAL (operands[2]) > 51)
4609        || (GET_CODE (operands[2]) == CONST_DOUBLE
4610            && CONST_DOUBLE_LOW (operands[2]) > 51))"
4612   int len = (GET_CODE (operands[1]) == CONST_INT
4613              ? INTVAL (operands[1])
4614              : CONST_DOUBLE_LOW (operands[1]));
4615   int pos = 64 -
4616             (GET_CODE (operands[2]) == CONST_INT
4617              ? INTVAL (operands[2])
4618              : CONST_DOUBLE_LOW (operands[2])) - len;
4619   HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
4621   operands[1] = GEN_INT (mask);
4622   return "andcc\t%0, %1, %%g0";
4624   [(set_attr "type" "compare")])
4626 ;; Conversions between float, double and long double.
4628 (define_insn "extendsfdf2"
4629   [(set (match_operand:DF 0 "register_operand" "=e")
4630         (float_extend:DF
4631          (match_operand:SF 1 "register_operand" "f")))]
4632   "TARGET_FPU"
4633   "fstod\t%1, %0"
4634   [(set_attr "type" "fp")
4635    (set_attr "fptype" "double")])
4637 (define_expand "extendsftf2"
4638   [(set (match_operand:TF 0 "nonimmediate_operand" "")
4639         (float_extend:TF
4640          (match_operand:SF 1 "register_operand" "")))]
4641   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4642   "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4644 (define_insn "*extendsftf2_hq"
4645   [(set (match_operand:TF 0 "register_operand" "=e")
4646         (float_extend:TF
4647          (match_operand:SF 1 "register_operand" "f")))]
4648   "TARGET_FPU && TARGET_HARD_QUAD"
4649   "fstoq\t%1, %0"
4650   [(set_attr "type" "fp")])
4652 (define_expand "extenddftf2"
4653   [(set (match_operand:TF 0 "nonimmediate_operand" "")
4654         (float_extend:TF
4655          (match_operand:DF 1 "register_operand" "")))]
4656   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4657   "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4659 (define_insn "*extenddftf2_hq"
4660   [(set (match_operand:TF 0 "register_operand" "=e")
4661         (float_extend:TF
4662          (match_operand:DF 1 "register_operand" "e")))]
4663   "TARGET_FPU && TARGET_HARD_QUAD"
4664   "fdtoq\t%1, %0"
4665   [(set_attr "type" "fp")])
4667 (define_insn "truncdfsf2"
4668   [(set (match_operand:SF 0 "register_operand" "=f")
4669         (float_truncate:SF
4670          (match_operand:DF 1 "register_operand" "e")))]
4671   "TARGET_FPU"
4672   "fdtos\t%1, %0"
4673   [(set_attr "type" "fp")
4674    (set_attr "fptype" "double")])
4676 (define_expand "trunctfsf2"
4677   [(set (match_operand:SF 0 "register_operand" "")
4678         (float_truncate:SF
4679          (match_operand:TF 1 "general_operand" "")))]
4680   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4681   "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4683 (define_insn "*trunctfsf2_hq"
4684   [(set (match_operand:SF 0 "register_operand" "=f")
4685         (float_truncate:SF
4686          (match_operand:TF 1 "register_operand" "e")))]
4687   "TARGET_FPU && TARGET_HARD_QUAD"
4688   "fqtos\t%1, %0"
4689   [(set_attr "type" "fp")])
4691 (define_expand "trunctfdf2"
4692   [(set (match_operand:DF 0 "register_operand" "")
4693         (float_truncate:DF
4694          (match_operand:TF 1 "general_operand" "")))]
4695   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4696   "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4698 (define_insn "*trunctfdf2_hq"
4699   [(set (match_operand:DF 0 "register_operand" "=e")
4700         (float_truncate:DF
4701          (match_operand:TF 1 "register_operand" "e")))]
4702   "TARGET_FPU && TARGET_HARD_QUAD"
4703   "fqtod\t%1, %0"
4704   [(set_attr "type" "fp")])
4706 ;; Conversion between fixed point and floating point.
4708 (define_insn "floatsisf2"
4709   [(set (match_operand:SF 0 "register_operand" "=f")
4710         (float:SF (match_operand:SI 1 "register_operand" "f")))]
4711   "TARGET_FPU"
4712   "fitos\t%1, %0"
4713   [(set_attr "type" "fp")
4714    (set_attr "fptype" "double")])
4716 (define_insn "floatsidf2"
4717   [(set (match_operand:DF 0 "register_operand" "=e")
4718         (float:DF (match_operand:SI 1 "register_operand" "f")))]
4719   "TARGET_FPU"
4720   "fitod\t%1, %0"
4721   [(set_attr "type" "fp")
4722    (set_attr "fptype" "double")])
4724 (define_expand "floatsitf2"
4725   [(set (match_operand:TF 0 "nonimmediate_operand" "")
4726         (float:TF (match_operand:SI 1 "register_operand" "")))]
4727   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4728   "emit_tfmode_cvt (FLOAT, operands); DONE;")
4730 (define_insn "*floatsitf2_hq"
4731   [(set (match_operand:TF 0 "register_operand" "=e")
4732         (float:TF (match_operand:SI 1 "register_operand" "f")))]
4733   "TARGET_FPU && TARGET_HARD_QUAD"
4734   "fitoq\t%1, %0"
4735   [(set_attr "type" "fp")])
4737 (define_expand "floatunssitf2"
4738   [(set (match_operand:TF 0 "nonimmediate_operand" "")
4739         (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
4740   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4741   "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4743 ;; Now the same for 64 bit sources.
4745 (define_insn "floatdisf2"
4746   [(set (match_operand:SF 0 "register_operand" "=f")
4747         (float:SF (match_operand:DI 1 "register_operand" "e")))]
4748   "TARGET_V9 && TARGET_FPU"
4749   "fxtos\t%1, %0"
4750   [(set_attr "type" "fp")
4751    (set_attr "fptype" "double")])
4753 (define_expand "floatunsdisf2"
4754   [(use (match_operand:SF 0 "register_operand" ""))
4755    (use (match_operand:DI 1 "general_operand" ""))]
4756   "TARGET_ARCH64 && TARGET_FPU"
4757   "sparc_emit_floatunsdi (operands, SFmode); DONE;")
4759 (define_insn "floatdidf2"
4760   [(set (match_operand:DF 0 "register_operand" "=e")
4761         (float:DF (match_operand:DI 1 "register_operand" "e")))]
4762   "TARGET_V9 && TARGET_FPU"
4763   "fxtod\t%1, %0"
4764   [(set_attr "type" "fp")
4765    (set_attr "fptype" "double")])
4767 (define_expand "floatunsdidf2"
4768   [(use (match_operand:DF 0 "register_operand" ""))
4769    (use (match_operand:DI 1 "general_operand" ""))]
4770   "TARGET_ARCH64 && TARGET_FPU"
4771   "sparc_emit_floatunsdi (operands, DFmode); DONE;")
4773 (define_expand "floatditf2"
4774   [(set (match_operand:TF 0 "nonimmediate_operand" "")
4775         (float:TF (match_operand:DI 1 "register_operand" "")))]
4776   "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4777   "emit_tfmode_cvt (FLOAT, operands); DONE;")
4779 (define_insn "*floatditf2_hq"
4780   [(set (match_operand:TF 0 "register_operand" "=e")
4781         (float:TF (match_operand:DI 1 "register_operand" "e")))]
4782   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4783   "fxtoq\t%1, %0"
4784   [(set_attr "type" "fp")])
4786 (define_expand "floatunsditf2"
4787   [(set (match_operand:TF 0 "nonimmediate_operand" "")
4788         (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
4789   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4790   "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4792 ;; Convert a float to an actual integer.
4793 ;; Truncation is performed as part of the conversion.
4795 (define_insn "fix_truncsfsi2"
4796   [(set (match_operand:SI 0 "register_operand" "=f")
4797         (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4798   "TARGET_FPU"
4799   "fstoi\t%1, %0"
4800   [(set_attr "type" "fp")
4801    (set_attr "fptype" "double")])
4803 (define_insn "fix_truncdfsi2"
4804   [(set (match_operand:SI 0 "register_operand" "=f")
4805         (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4806   "TARGET_FPU"
4807   "fdtoi\t%1, %0"
4808   [(set_attr "type" "fp")
4809    (set_attr "fptype" "double")])
4811 (define_expand "fix_trunctfsi2"
4812   [(set (match_operand:SI 0 "register_operand" "")
4813         (fix:SI (match_operand:TF 1 "general_operand" "")))]
4814   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4815   "emit_tfmode_cvt (FIX, operands); DONE;")
4817 (define_insn "*fix_trunctfsi2_hq"
4818   [(set (match_operand:SI 0 "register_operand" "=f")
4819         (fix:SI (match_operand:TF 1 "register_operand" "e")))]
4820   "TARGET_FPU && TARGET_HARD_QUAD"
4821   "fqtoi\t%1, %0"
4822   [(set_attr "type" "fp")])
4824 (define_expand "fixuns_trunctfsi2"
4825   [(set (match_operand:SI 0 "register_operand" "")
4826         (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
4827   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4828   "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4830 ;; Now the same, for V9 targets
4832 (define_insn "fix_truncsfdi2"
4833   [(set (match_operand:DI 0 "register_operand" "=e")
4834         (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4835   "TARGET_V9 && TARGET_FPU"
4836   "fstox\t%1, %0"
4837   [(set_attr "type" "fp")
4838    (set_attr "fptype" "double")])
4840 (define_expand "fixuns_truncsfdi2"
4841   [(use (match_operand:DI 0 "register_operand" ""))
4842    (use (match_operand:SF 1 "general_operand" ""))]
4843   "TARGET_ARCH64 && TARGET_FPU"
4844   "sparc_emit_fixunsdi (operands, SFmode); DONE;")
4846 (define_insn "fix_truncdfdi2"
4847   [(set (match_operand:DI 0 "register_operand" "=e")
4848         (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4849   "TARGET_V9 && TARGET_FPU"
4850   "fdtox\t%1, %0"
4851   [(set_attr "type" "fp")
4852    (set_attr "fptype" "double")])
4854 (define_expand "fixuns_truncdfdi2"
4855   [(use (match_operand:DI 0 "register_operand" ""))
4856    (use (match_operand:DF 1 "general_operand" ""))]
4857   "TARGET_ARCH64 && TARGET_FPU"
4858   "sparc_emit_fixunsdi (operands, DFmode); DONE;")
4860 (define_expand "fix_trunctfdi2"
4861   [(set (match_operand:DI 0 "register_operand" "")
4862         (fix:DI (match_operand:TF 1 "general_operand" "")))]
4863   "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4864   "emit_tfmode_cvt (FIX, operands); DONE;")
4866 (define_insn "*fix_trunctfdi2_hq"
4867   [(set (match_operand:DI 0 "register_operand" "=e")
4868         (fix:DI (match_operand:TF 1 "register_operand" "e")))]
4869   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4870   "fqtox\t%1, %0"
4871   [(set_attr "type" "fp")])
4873 (define_expand "fixuns_trunctfdi2"
4874   [(set (match_operand:DI 0 "register_operand" "")
4875         (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
4876   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4877   "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4879 ;;- arithmetic instructions
4881 (define_expand "adddi3"
4882   [(set (match_operand:DI 0 "register_operand" "")
4883         (plus:DI (match_operand:DI 1 "register_operand" "")
4884                  (match_operand:DI 2 "arith_double_add_operand" "")))]
4885   ""
4887   if (! TARGET_ARCH64)
4888     {
4889       emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4890                           gen_rtx_SET (VOIDmode, operands[0],
4891                                    gen_rtx_PLUS (DImode, operands[1],
4892                                                  operands[2])),
4893                           gen_rtx_CLOBBER (VOIDmode,
4894                                    gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4895       DONE;
4896     }
4899 (define_insn_and_split "adddi3_insn_sp32"
4900   [(set (match_operand:DI 0 "register_operand" "=r")
4901         (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4902                  (match_operand:DI 2 "arith_double_operand" "rHI")))
4903    (clobber (reg:CC 100))]
4904   "! TARGET_ARCH64"
4905   "#"
4906   "&& reload_completed"
4907   [(parallel [(set (reg:CC_NOOV 100)
4908                    (compare:CC_NOOV (plus:SI (match_dup 4)
4909                                              (match_dup 5))
4910                                     (const_int 0)))
4911               (set (match_dup 3)
4912                    (plus:SI (match_dup 4) (match_dup 5)))])
4913    (set (match_dup 6)
4914         (plus:SI (plus:SI (match_dup 7)
4915                           (match_dup 8))
4916                  (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4918   operands[3] = gen_lowpart (SImode, operands[0]);
4919   operands[4] = gen_lowpart (SImode, operands[1]);
4920   operands[5] = gen_lowpart (SImode, operands[2]);
4921   operands[6] = gen_highpart (SImode, operands[0]);
4922   operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
4923 #if HOST_BITS_PER_WIDE_INT == 32
4924   if (GET_CODE (operands[2]) == CONST_INT)
4925     {
4926       if (INTVAL (operands[2]) < 0)
4927         operands[8] = constm1_rtx;
4928       else
4929         operands[8] = const0_rtx;
4930     }
4931   else
4932 #endif
4933     operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4935   [(set_attr "length" "2")])
4937 (define_split
4938   [(set (match_operand:DI 0 "register_operand" "")
4939         (minus:DI (match_operand:DI 1 "arith_double_operand" "")
4940                   (match_operand:DI 2 "arith_double_operand" "")))
4941    (clobber (reg:CC 100))]
4942   "! TARGET_ARCH64 && reload_completed"
4943   [(parallel [(set (reg:CC_NOOV 100)
4944                    (compare:CC_NOOV (minus:SI (match_dup 4)
4945                                               (match_dup 5))
4946                                     (const_int 0)))
4947               (set (match_dup 3)
4948                    (minus:SI (match_dup 4) (match_dup 5)))])
4949    (set (match_dup 6)
4950         (minus:SI (minus:SI (match_dup 7)
4951                             (match_dup 8))
4952                   (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4954   operands[3] = gen_lowpart (SImode, operands[0]);
4955   operands[4] = gen_lowpart (SImode, operands[1]);
4956   operands[5] = gen_lowpart (SImode, operands[2]);
4957   operands[6] = gen_highpart (SImode, operands[0]);
4958   operands[7] = gen_highpart (SImode, operands[1]);
4959 #if HOST_BITS_PER_WIDE_INT == 32
4960   if (GET_CODE (operands[2]) == CONST_INT)
4961     {
4962       if (INTVAL (operands[2]) < 0)
4963         operands[8] = constm1_rtx;
4964       else
4965         operands[8] = const0_rtx;
4966     }
4967   else
4968 #endif
4969     operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4972 ;; LTU here means "carry set"
4973 (define_insn "addx"
4974   [(set (match_operand:SI 0 "register_operand" "=r")
4975         (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4976                           (match_operand:SI 2 "arith_operand" "rI"))
4977                  (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4978   ""
4979   "addx\t%1, %2, %0"
4980   [(set_attr "type" "ialuX")])
4982 (define_insn_and_split "*addx_extend_sp32"
4983   [(set (match_operand:DI 0 "register_operand" "=r")
4984         (zero_extend:DI (plus:SI (plus:SI
4985                                   (match_operand:SI 1 "reg_or_0_operand" "%rJ")
4986                                   (match_operand:SI 2 "arith_operand" "rI"))
4987                                  (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4988   "! TARGET_ARCH64"
4989   "#"
4990   "&& reload_completed"
4991   [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
4992                                (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4993    (set (match_dup 4) (const_int 0))]
4994   "operands[3] = gen_lowpart (SImode, operands[0]);
4995    operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
4996   [(set_attr "length" "2")])
4998 (define_insn "*addx_extend_sp64"
4999   [(set (match_operand:DI 0 "register_operand" "=r")
5000         (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
5001                                           (match_operand:SI 2 "arith_operand" "rI"))
5002                                  (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5003   "TARGET_ARCH64"
5004   "addx\t%r1, %2, %0"
5005   [(set_attr "type" "ialuX")])
5007 (define_insn "subx"
5008   [(set (match_operand:SI 0 "register_operand" "=r")
5009         (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5010                             (match_operand:SI 2 "arith_operand" "rI"))
5011                   (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5012   ""
5013   "subx\t%r1, %2, %0"
5014   [(set_attr "type" "ialuX")])
5016 (define_insn "*subx_extend_sp64"
5017   [(set (match_operand:DI 0 "register_operand" "=r")
5018         (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5019                                             (match_operand:SI 2 "arith_operand" "rI"))
5020                                   (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5021   "TARGET_ARCH64"
5022   "subx\t%r1, %2, %0"
5023   [(set_attr "type" "ialuX")])
5025 (define_insn_and_split "*subx_extend"
5026   [(set (match_operand:DI 0 "register_operand" "=r")
5027         (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5028                                             (match_operand:SI 2 "arith_operand" "rI"))
5029                                   (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
5030   "! TARGET_ARCH64"
5031   "#"
5032   "&& reload_completed"
5033   [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
5034                                 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
5035    (set (match_dup 4) (const_int 0))]
5036   "operands[3] = gen_lowpart (SImode, operands[0]);
5037    operands[4] = gen_highpart (SImode, operands[0]);"
5038   [(set_attr "length" "2")])
5040 (define_insn_and_split ""
5041   [(set (match_operand:DI 0 "register_operand" "=r")
5042         (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5043                  (match_operand:DI 2 "register_operand" "r")))
5044    (clobber (reg:CC 100))]
5045   "! TARGET_ARCH64"
5046   "#"
5047   "&& reload_completed"
5048   [(parallel [(set (reg:CC_NOOV 100)
5049                    (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
5050                                     (const_int 0)))
5051               (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
5052    (set (match_dup 6)
5053         (plus:SI (plus:SI (match_dup 4) (const_int 0))
5054                  (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5055   "operands[3] = gen_lowpart (SImode, operands[2]);
5056    operands[4] = gen_highpart (SImode, operands[2]);
5057    operands[5] = gen_lowpart (SImode, operands[0]);
5058    operands[6] = gen_highpart (SImode, operands[0]);"
5059   [(set_attr "length" "2")])
5061 (define_insn "*adddi3_sp64"
5062   [(set (match_operand:DI 0 "register_operand" "=r,r")
5063         (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
5064                  (match_operand:DI 2 "arith_double_add_operand" "rHI,O")))]
5065   "TARGET_ARCH64"
5066   "@
5067    add\t%1, %2, %0
5068    sub\t%1, -%2, %0")
5070 (define_insn "addsi3"
5071   [(set (match_operand:SI 0 "register_operand" "=r,r,d")
5072         (plus:SI (match_operand:SI 1 "register_operand" "%r,r,d")
5073                  (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
5074   ""
5075   "@
5076    add\t%1, %2, %0
5077    sub\t%1, -%2, %0
5078    fpadd32s\t%1, %2, %0"
5079   [(set_attr "type" "*,*,fga")
5080    (set_attr "fptype" "*,*,single")])
5082 (define_insn "*cmp_cc_plus"
5083   [(set (reg:CC_NOOV 100)
5084         (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
5085                                   (match_operand:SI 1 "arith_operand" "rI"))
5086                          (const_int 0)))]
5087   ""
5088   "addcc\t%0, %1, %%g0"
5089   [(set_attr "type" "compare")])
5091 (define_insn "*cmp_ccx_plus"
5092   [(set (reg:CCX_NOOV 100)
5093         (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_double_operand" "%r")
5094                                    (match_operand:DI 1 "arith_double_operand" "rHI"))
5095                           (const_int 0)))]
5096   "TARGET_ARCH64"
5097   "addcc\t%0, %1, %%g0"
5098   [(set_attr "type" "compare")])
5100 (define_insn "*cmp_cc_plus_set"
5101   [(set (reg:CC_NOOV 100)
5102         (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
5103                                   (match_operand:SI 2 "arith_operand" "rI"))
5104                          (const_int 0)))
5105    (set (match_operand:SI 0 "register_operand" "=r")
5106         (plus:SI (match_dup 1) (match_dup 2)))]
5107   ""
5108   "addcc\t%1, %2, %0"
5109   [(set_attr "type" "compare")])
5111 (define_insn "*cmp_ccx_plus_set"
5112   [(set (reg:CCX_NOOV 100)
5113         (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
5114                                    (match_operand:DI 2 "arith_double_operand" "rHI"))
5115                           (const_int 0)))
5116    (set (match_operand:DI 0 "register_operand" "=r")
5117         (plus:DI (match_dup 1) (match_dup 2)))]
5118   "TARGET_ARCH64"
5119   "addcc\t%1, %2, %0"
5120   [(set_attr "type" "compare")])
5122 (define_expand "subdi3"
5123   [(set (match_operand:DI 0 "register_operand" "")
5124         (minus:DI (match_operand:DI 1 "register_operand" "")
5125                   (match_operand:DI 2 "arith_double_add_operand" "")))]
5126   ""
5128   if (! TARGET_ARCH64)
5129     {
5130       emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
5131                           gen_rtx_SET (VOIDmode, operands[0],
5132                                    gen_rtx_MINUS (DImode, operands[1],
5133                                                   operands[2])),
5134                           gen_rtx_CLOBBER (VOIDmode,
5135                                    gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
5136       DONE;
5137     }
5140 (define_insn_and_split "*subdi3_sp32"
5141   [(set (match_operand:DI 0 "register_operand" "=r")
5142         (minus:DI (match_operand:DI 1 "register_operand" "r")
5143                   (match_operand:DI 2 "arith_double_operand" "rHI")))
5144    (clobber (reg:CC 100))]
5145   "! TARGET_ARCH64"
5146   "#"
5147   "&& reload_completed
5148    && (GET_CODE (operands[2]) == CONST_INT
5149        || GET_CODE (operands[2]) == CONST_DOUBLE)"
5150   [(clobber (const_int 0))]
5152   rtx highp, lowp;
5154   highp = gen_highpart_mode (SImode, DImode, operands[2]);
5155   lowp = gen_lowpart (SImode, operands[2]);
5156   if ((lowp == const0_rtx)
5157       && (operands[0] == operands[1]))
5158     {
5159       emit_insn (gen_rtx_SET (VOIDmode,
5160                               gen_highpart (SImode, operands[0]),
5161                               gen_rtx_MINUS (SImode,
5162                                              gen_highpart_mode (SImode, DImode,
5163                                                                 operands[1]),
5164                                              highp)));
5165     }
5166   else
5167     {
5168       emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5169                                        gen_lowpart (SImode, operands[1]),
5170                                        lowp));
5171       emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5172                            gen_highpart_mode (SImode, DImode, operands[1]),
5173                            highp));
5174     }
5175   DONE;
5177   [(set_attr "length" "2")])
5179 (define_split
5180   [(set (match_operand:DI 0 "register_operand" "")
5181         (minus:DI (match_operand:DI 1 "register_operand" "")
5182                   (match_operand:DI 2 "register_operand" "")))
5183    (clobber (reg:CC 100))]
5184   "! TARGET_ARCH64
5185    && reload_completed"
5186   [(clobber (const_int 0))]
5188   emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]),
5189                                    gen_lowpart (SImode, operands[1]),
5190                                    gen_lowpart (SImode, operands[2])));
5191   emit_insn (gen_subx (gen_highpart (SImode, operands[0]),
5192                        gen_highpart (SImode, operands[1]),
5193                        gen_highpart (SImode, operands[2])));
5194   DONE;
5197 (define_insn_and_split ""
5198   [(set (match_operand:DI 0 "register_operand" "=r")
5199       (minus:DI (match_operand:DI 1 "register_operand" "r")
5200                 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
5201    (clobber (reg:CC 100))]
5202   "! TARGET_ARCH64"
5203   "#"
5204   "&& reload_completed"
5205   [(parallel [(set (reg:CC_NOOV 100)
5206                    (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
5207                                     (const_int 0)))
5208               (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
5209    (set (match_dup 6)
5210         (minus:SI (minus:SI (match_dup 4) (const_int 0))
5211                   (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
5212   "operands[3] = gen_lowpart (SImode, operands[1]);
5213    operands[4] = gen_highpart (SImode, operands[1]);
5214    operands[5] = gen_lowpart (SImode, operands[0]);
5215    operands[6] = gen_highpart (SImode, operands[0]);"
5216   [(set_attr "length" "2")])
5218 (define_insn "*subdi3_sp64"
5219   [(set (match_operand:DI 0 "register_operand" "=r,r")
5220         (minus:DI (match_operand:DI 1 "register_operand" "r,r")
5221                   (match_operand:DI 2 "arith_double_add_operand" "rHI,O")))]
5222   "TARGET_ARCH64"
5223   "@
5224    sub\t%1, %2, %0
5225    add\t%1, -%2, %0")
5227 (define_insn "subsi3"
5228   [(set (match_operand:SI 0 "register_operand" "=r,r,d")
5229         (minus:SI (match_operand:SI 1 "register_operand" "r,r,d")
5230                   (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
5231   ""
5232   "@
5233    sub\t%1, %2, %0
5234    add\t%1, -%2, %0
5235    fpsub32s\t%1, %2, %0"
5236   [(set_attr "type" "*,*,fga")
5237    (set_attr "fptype" "*,*,single")])
5239 (define_insn "*cmp_minus_cc"
5240   [(set (reg:CC_NOOV 100)
5241         (compare:CC_NOOV (minus:SI (match_operand:SI 0 "reg_or_0_operand" "rJ")
5242                                    (match_operand:SI 1 "arith_operand" "rI"))
5243                          (const_int 0)))]
5244   ""
5245   "subcc\t%r0, %1, %%g0"
5246   [(set_attr "type" "compare")])
5248 (define_insn "*cmp_minus_ccx"
5249   [(set (reg:CCX_NOOV 100)
5250         (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
5251                                     (match_operand:DI 1 "arith_double_operand" "rHI"))
5252                           (const_int 0)))]
5253   "TARGET_ARCH64"
5254   "subcc\t%0, %1, %%g0"
5255   [(set_attr "type" "compare")])
5257 (define_insn "cmp_minus_cc_set"
5258   [(set (reg:CC_NOOV 100)
5259         (compare:CC_NOOV (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
5260                                    (match_operand:SI 2 "arith_operand" "rI"))
5261                          (const_int 0)))
5262    (set (match_operand:SI 0 "register_operand" "=r")
5263         (minus:SI (match_dup 1) (match_dup 2)))]
5264   ""
5265   "subcc\t%r1, %2, %0"
5266   [(set_attr "type" "compare")])
5268 (define_insn "*cmp_minus_ccx_set"
5269   [(set (reg:CCX_NOOV 100)
5270         (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
5271                                     (match_operand:DI 2 "arith_double_operand" "rHI"))
5272                           (const_int 0)))
5273    (set (match_operand:DI 0 "register_operand" "=r")
5274         (minus:DI (match_dup 1) (match_dup 2)))]
5275   "TARGET_ARCH64"
5276   "subcc\t%1, %2, %0"
5277   [(set_attr "type" "compare")])
5279 ;; Integer Multiply/Divide.
5281 ;; The 32 bit multiply/divide instructions are deprecated on v9, but at
5282 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
5284 (define_insn "mulsi3"
5285   [(set (match_operand:SI 0 "register_operand" "=r")
5286         (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5287                  (match_operand:SI 2 "arith_operand" "rI")))]
5288   "TARGET_HARD_MUL"
5289   "smul\t%1, %2, %0"
5290   [(set_attr "type" "imul")])
5292 (define_expand "muldi3"
5293   [(set (match_operand:DI 0 "register_operand" "=r")
5294         (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5295                  (match_operand:DI 2 "arith_double_operand" "rHI")))]
5296   "TARGET_ARCH64 || TARGET_V8PLUS"
5298   if (TARGET_V8PLUS)
5299     {
5300       emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
5301       DONE;
5302     }
5305 (define_insn "*muldi3_sp64"
5306   [(set (match_operand:DI 0 "register_operand" "=r")
5307         (mult:DI (match_operand:DI 1 "arith_double_operand" "%r")
5308                  (match_operand:DI 2 "arith_double_operand" "rHI")))]
5309   "TARGET_ARCH64"
5310   "mulx\t%1, %2, %0"
5311   [(set_attr "type" "imul")])
5313 ;; V8plus wide multiply.
5314 ;; XXX
5315 (define_insn "muldi3_v8plus"
5316   [(set (match_operand:DI 0 "register_operand" "=r,h")
5317         (mult:DI (match_operand:DI 1 "arith_double_operand" "%r,0")
5318                  (match_operand:DI 2 "arith_double_operand" "rI,rI")))
5319    (clobber (match_scratch:SI 3 "=&h,X"))
5320    (clobber (match_scratch:SI 4 "=&h,X"))]
5321   "TARGET_V8PLUS"
5323   if (sparc_check_64 (operands[1], insn) <= 0)
5324     output_asm_insn ("srl\t%L1, 0, %L1", operands);
5325   if (which_alternative == 1)
5326     output_asm_insn ("sllx\t%H1, 32, %H1", operands);
5327   if (GET_CODE (operands[2]) == CONST_INT)
5328     {
5329       if (which_alternative == 1)
5330         return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %2, %L0\;srlx\t%L0, 32, %H0";
5331       else
5332         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";
5333     }
5334   else if (rtx_equal_p (operands[1], operands[2]))
5335     {
5336       if (which_alternative == 1)
5337         return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %H1, %L0\;srlx\t%L0, 32, %H0";
5338       else
5339         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";
5340     }
5341   if (sparc_check_64 (operands[2], insn) <= 0)
5342     output_asm_insn ("srl\t%L2, 0, %L2", operands);
5343   if (which_alternative == 1)
5344     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";
5345   else
5346     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";
5348   [(set_attr "type" "multi")
5349    (set_attr "length" "9,8")])
5351 (define_insn "*cmp_mul_set"
5352   [(set (reg:CC 100)
5353         (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
5354                     (match_operand:SI 2 "arith_operand" "rI"))
5355                     (const_int 0)))
5356    (set (match_operand:SI 0 "register_operand" "=r")
5357         (mult:SI (match_dup 1) (match_dup 2)))]
5358   "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
5359   "smulcc\t%1, %2, %0"
5360   [(set_attr "type" "imul")])
5362 (define_expand "mulsidi3"
5363   [(set (match_operand:DI 0 "register_operand" "")
5364         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5365                  (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
5366   "TARGET_HARD_MUL"
5368   if (CONSTANT_P (operands[2]))
5369     {
5370       if (TARGET_V8PLUS)
5371         emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
5372                                               operands[2]));
5373       else if (TARGET_ARCH32)
5374         emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
5375                                             operands[2]));
5376       else 
5377         emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
5378                                             operands[2]));
5379       DONE;
5380     }
5381   if (TARGET_V8PLUS)
5382     {
5383       emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
5384       DONE;
5385     }
5388 ;; V9 puts the 64 bit product in a 64 bit register.  Only out or global
5389 ;; registers can hold 64 bit values in the V8plus environment.
5390 ;; XXX
5391 (define_insn "mulsidi3_v8plus"
5392   [(set (match_operand:DI 0 "register_operand" "=h,r")
5393         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5394                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5395    (clobber (match_scratch:SI 3 "=X,&h"))]
5396   "TARGET_V8PLUS"
5397   "@
5398    smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5399    smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5400   [(set_attr "type" "multi")
5401    (set_attr "length" "2,3")])
5403 ;; XXX
5404 (define_insn "const_mulsidi3_v8plus"
5405   [(set (match_operand:DI 0 "register_operand" "=h,r")
5406         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5407                  (match_operand:DI 2 "small_int" "I,I")))
5408    (clobber (match_scratch:SI 3 "=X,&h"))]
5409   "TARGET_V8PLUS"
5410   "@
5411    smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5412    smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5413   [(set_attr "type" "multi")
5414    (set_attr "length" "2,3")])
5416 ;; XXX
5417 (define_insn "*mulsidi3_sp32"
5418   [(set (match_operand:DI 0 "register_operand" "=r")
5419         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5420                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5421   "TARGET_HARD_MUL32"
5423   return TARGET_SPARCLET
5424          ? "smuld\t%1, %2, %L0"
5425          : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
5427   [(set (attr "type")
5428         (if_then_else (eq_attr "isa" "sparclet")
5429                       (const_string "imul") (const_string "multi")))
5430    (set (attr "length")
5431         (if_then_else (eq_attr "isa" "sparclet")
5432                       (const_int 1) (const_int 2)))])
5434 (define_insn "*mulsidi3_sp64"
5435   [(set (match_operand:DI 0 "register_operand" "=r")
5436         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5437                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5438   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5439   "smul\t%1, %2, %0"
5440   [(set_attr "type" "imul")])
5442 ;; Extra pattern, because sign_extend of a constant isn't valid.
5444 ;; XXX
5445 (define_insn "const_mulsidi3_sp32"
5446   [(set (match_operand:DI 0 "register_operand" "=r")
5447         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5448                  (match_operand:DI 2 "small_int" "I")))]
5449   "TARGET_HARD_MUL32"
5451   return TARGET_SPARCLET
5452          ? "smuld\t%1, %2, %L0"
5453          : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
5455   [(set (attr "type")
5456         (if_then_else (eq_attr "isa" "sparclet")
5457                       (const_string "imul") (const_string "multi")))
5458    (set (attr "length")
5459         (if_then_else (eq_attr "isa" "sparclet")
5460                       (const_int 1) (const_int 2)))])
5462 (define_insn "const_mulsidi3_sp64"
5463   [(set (match_operand:DI 0 "register_operand" "=r")
5464         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5465                  (match_operand:DI 2 "small_int" "I")))]
5466   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5467   "smul\t%1, %2, %0"
5468   [(set_attr "type" "imul")])
5470 (define_expand "smulsi3_highpart"
5471   [(set (match_operand:SI 0 "register_operand" "")
5472         (truncate:SI
5473          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
5474                                (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
5475                       (const_int 32))))]
5476   "TARGET_HARD_MUL && TARGET_ARCH32"
5478   if (CONSTANT_P (operands[2]))
5479     {
5480       if (TARGET_V8PLUS)
5481         {
5482           emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
5483                                                         operands[1],
5484                                                         operands[2],
5485                                                         GEN_INT (32)));
5486           DONE;
5487         }
5488       emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
5489       DONE;
5490     }
5491   if (TARGET_V8PLUS)
5492     {
5493       emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
5494                                               operands[2], GEN_INT (32)));
5495       DONE;
5496     }
5499 ;; XXX
5500 (define_insn "smulsi3_highpart_v8plus"
5501   [(set (match_operand:SI 0 "register_operand" "=h,r")
5502         (truncate:SI
5503          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5504                                (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5505                       (match_operand:SI 3 "const_int_operand" "i,i"))))
5506    (clobber (match_scratch:SI 4 "=X,&h"))]
5507   "TARGET_V8PLUS"
5508   "@
5509    smul\t%1, %2, %0\;srlx\t%0, %3, %0
5510    smul\t%1, %2, %4\;srlx\t%4, %3, %0"
5511   [(set_attr "type" "multi")
5512    (set_attr "length" "2")])
5514 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
5515 ;; XXX
5516 (define_insn ""
5517   [(set (match_operand:SI 0 "register_operand" "=h,r")
5518         (subreg:SI
5519          (lshiftrt:DI
5520           (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5521                    (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5522           (match_operand:SI 3 "const_int_operand" "i,i"))
5523          4))
5524    (clobber (match_scratch:SI 4 "=X,&h"))]
5525   "TARGET_V8PLUS"
5526   "@
5527    smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5528    smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5529   [(set_attr "type" "multi")
5530    (set_attr "length" "2")])
5532 ;; XXX
5533 (define_insn "const_smulsi3_highpart_v8plus"
5534   [(set (match_operand:SI 0 "register_operand" "=h,r")
5535         (truncate:SI
5536          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5537                                (match_operand:DI 2 "small_int" "i,i"))
5538                       (match_operand:SI 3 "const_int_operand" "i,i"))))
5539    (clobber (match_scratch:SI 4 "=X,&h"))]
5540   "TARGET_V8PLUS"
5541   "@
5542    smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5543    smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5544   [(set_attr "type" "multi")
5545    (set_attr "length" "2")])
5547 ;; XXX
5548 (define_insn "*smulsi3_highpart_sp32"
5549   [(set (match_operand:SI 0 "register_operand" "=r")
5550         (truncate:SI
5551          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5552                                (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
5553                       (const_int 32))))]
5554   "TARGET_HARD_MUL32"
5555   "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
5556   [(set_attr "type" "multi")
5557    (set_attr "length" "2")])
5559 ;; XXX
5560 (define_insn "const_smulsi3_highpart"
5561   [(set (match_operand:SI 0 "register_operand" "=r")
5562         (truncate:SI
5563          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
5564                                (match_operand:DI 2 "small_int" "i"))
5565                       (const_int 32))))]
5566   "TARGET_HARD_MUL32"
5567   "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
5568   [(set_attr "type" "multi")
5569    (set_attr "length" "2")])
5571 (define_expand "umulsidi3"
5572   [(set (match_operand:DI 0 "register_operand" "")
5573         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5574                  (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
5575   "TARGET_HARD_MUL"
5577   if (CONSTANT_P (operands[2]))
5578     {
5579       if (TARGET_V8PLUS)
5580         emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
5581                                                operands[2]));
5582       else if (TARGET_ARCH32)
5583         emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
5584                                              operands[2]));
5585       else 
5586         emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
5587                                              operands[2]));
5588       DONE;
5589     }
5590   if (TARGET_V8PLUS)
5591     {
5592       emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
5593       DONE;
5594     }
5597 ;; XXX
5598 (define_insn "umulsidi3_v8plus"
5599   [(set (match_operand:DI 0 "register_operand" "=h,r")
5600         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5601                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
5602    (clobber (match_scratch:SI 3 "=X,&h"))]
5603   "TARGET_V8PLUS"
5604   "@
5605    umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
5606    umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5607   [(set_attr "type" "multi")
5608    (set_attr "length" "2,3")])
5610 ;; XXX
5611 (define_insn "*umulsidi3_sp32"
5612   [(set (match_operand:DI 0 "register_operand" "=r")
5613         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5614                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5615   "TARGET_HARD_MUL32"
5617   return TARGET_SPARCLET
5618          ? "umuld\t%1, %2, %L0"
5619          : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
5621   [(set (attr "type")
5622         (if_then_else (eq_attr "isa" "sparclet")
5623                       (const_string "imul") (const_string "multi")))
5624    (set (attr "length")
5625         (if_then_else (eq_attr "isa" "sparclet")
5626                       (const_int 1) (const_int 2)))])
5628 (define_insn "*umulsidi3_sp64"
5629   [(set (match_operand:DI 0 "register_operand" "=r")
5630         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5631                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
5632   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5633   "umul\t%1, %2, %0"
5634   [(set_attr "type" "imul")])
5636 ;; Extra pattern, because sign_extend of a constant isn't valid.
5638 ;; XXX
5639 (define_insn "const_umulsidi3_sp32"
5640   [(set (match_operand:DI 0 "register_operand" "=r")
5641         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5642                  (match_operand:DI 2 "uns_small_int" "")))]
5643   "TARGET_HARD_MUL32"
5645   return TARGET_SPARCLET
5646          ? "umuld\t%1, %s2, %L0"
5647          : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
5649   [(set (attr "type")
5650         (if_then_else (eq_attr "isa" "sparclet")
5651                       (const_string "imul") (const_string "multi")))
5652    (set (attr "length")
5653         (if_then_else (eq_attr "isa" "sparclet")
5654                       (const_int 1) (const_int 2)))])
5656 (define_insn "const_umulsidi3_sp64"
5657   [(set (match_operand:DI 0 "register_operand" "=r")
5658         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5659                  (match_operand:DI 2 "uns_small_int" "")))]
5660   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5661   "umul\t%1, %s2, %0"
5662   [(set_attr "type" "imul")])
5664 ;; XXX
5665 (define_insn "const_umulsidi3_v8plus"
5666   [(set (match_operand:DI 0 "register_operand" "=h,r")
5667         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5668                  (match_operand:DI 2 "uns_small_int" "")))
5669    (clobber (match_scratch:SI 3 "=X,h"))]
5670   "TARGET_V8PLUS"
5671   "@
5672    umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
5673    umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
5674   [(set_attr "type" "multi")
5675    (set_attr "length" "2,3")])
5677 (define_expand "umulsi3_highpart"
5678   [(set (match_operand:SI 0 "register_operand" "")
5679         (truncate:SI
5680          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
5681                                (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
5682                       (const_int 32))))]
5683   "TARGET_HARD_MUL && TARGET_ARCH32"
5685   if (CONSTANT_P (operands[2]))
5686     {
5687       if (TARGET_V8PLUS)
5688         {
5689           emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
5690                                                         operands[1],
5691                                                         operands[2],
5692                                                         GEN_INT (32)));
5693           DONE;
5694         }
5695       emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
5696       DONE;
5697     }
5698   if (TARGET_V8PLUS)
5699     {
5700       emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
5701                                               operands[2], GEN_INT (32)));
5702       DONE;
5703     }
5706 ;; XXX
5707 (define_insn "umulsi3_highpart_v8plus"
5708   [(set (match_operand:SI 0 "register_operand" "=h,r")
5709         (truncate:SI
5710          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5711                                (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5712                       (match_operand:SI 3 "const_int_operand" "i,i"))))
5713    (clobber (match_scratch:SI 4 "=X,h"))]
5714   "TARGET_V8PLUS"
5715   "@
5716    umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5717    umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5718   [(set_attr "type" "multi")
5719    (set_attr "length" "2")])
5721 ;; XXX
5722 (define_insn "const_umulsi3_highpart_v8plus"
5723   [(set (match_operand:SI 0 "register_operand" "=h,r")
5724         (truncate:SI
5725          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5726                                (match_operand:DI 2 "uns_small_int" ""))
5727                       (match_operand:SI 3 "const_int_operand" "i,i"))))
5728    (clobber (match_scratch:SI 4 "=X,h"))]
5729   "TARGET_V8PLUS"
5730   "@
5731    umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
5732    umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
5733   [(set_attr "type" "multi")
5734    (set_attr "length" "2")])
5736 ;; XXX
5737 (define_insn "*umulsi3_highpart_sp32"
5738   [(set (match_operand:SI 0 "register_operand" "=r")
5739         (truncate:SI
5740          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5741                                (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
5742                       (const_int 32))))]
5743   "TARGET_HARD_MUL32"
5744   "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
5745   [(set_attr "type" "multi")
5746    (set_attr "length" "2")])
5748 ;; XXX
5749 (define_insn "const_umulsi3_highpart"
5750   [(set (match_operand:SI 0 "register_operand" "=r")
5751         (truncate:SI
5752          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5753                                (match_operand:DI 2 "uns_small_int" ""))
5754                       (const_int 32))))]
5755   "TARGET_HARD_MUL32"
5756   "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
5757   [(set_attr "type" "multi")
5758    (set_attr "length" "2")])
5760 ;; The v8 architecture specifies that there must be 3 instructions between
5761 ;; a y register write and a use of it for correct results.
5763 (define_expand "divsi3"
5764   [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
5765                    (div:SI (match_operand:SI 1 "register_operand" "r,r")
5766                            (match_operand:SI 2 "input_operand" "rI,m")))
5767               (clobber (match_scratch:SI 3 "=&r,&r"))])]
5768   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5770   if (TARGET_ARCH64)
5771     {
5772       operands[3] = gen_reg_rtx(SImode);
5773       emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
5774       emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
5775                                   operands[3]));
5776       DONE;
5777     }
5780 (define_insn "divsi3_sp32"
5781   [(set (match_operand:SI 0 "register_operand" "=r,r")
5782         (div:SI (match_operand:SI 1 "register_operand" "r,r")
5783                 (match_operand:SI 2 "input_operand" "rI,m")))
5784    (clobber (match_scratch:SI 3 "=&r,&r"))]
5785   "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
5786    && TARGET_ARCH32"
5788   if (which_alternative == 0)
5789     if (TARGET_V9)
5790       return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdiv\t%1, %2, %0";
5791     else
5792       return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
5793   else
5794     if (TARGET_V9)
5795       return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tld\t%2, %3\n\tsdiv\t%1, %3, %0";
5796     else
5797       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";
5799   [(set_attr "type" "multi")
5800    (set (attr "length")
5801         (if_then_else (eq_attr "isa" "v9")
5802                       (const_int 4) (const_int 6)))])
5804 (define_insn "divsi3_sp64"
5805   [(set (match_operand:SI 0 "register_operand" "=r")
5806         (div:SI (match_operand:SI 1 "register_operand" "r")
5807                 (match_operand:SI 2 "input_operand" "rI")))
5808    (use (match_operand:SI 3 "register_operand" "r"))]
5809   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5810   "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
5811   [(set_attr "type" "multi")
5812    (set_attr "length" "2")])
5814 (define_insn "divdi3"
5815   [(set (match_operand:DI 0 "register_operand" "=r")
5816         (div:DI (match_operand:DI 1 "register_operand" "r")
5817                 (match_operand:DI 2 "arith_double_operand" "rHI")))]
5818   "TARGET_ARCH64"
5819   "sdivx\t%1, %2, %0"
5820   [(set_attr "type" "idiv")])
5822 (define_insn "*cmp_sdiv_cc_set"
5823   [(set (reg:CC 100)
5824         (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
5825                             (match_operand:SI 2 "arith_operand" "rI"))
5826                     (const_int 0)))
5827    (set (match_operand:SI 0 "register_operand" "=r")
5828         (div:SI (match_dup 1) (match_dup 2)))
5829    (clobber (match_scratch:SI 3 "=&r"))]
5830   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5832   if (TARGET_V9)
5833     return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdivcc\t%1, %2, %0";
5834   else
5835     return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
5837   [(set_attr "type" "multi")
5838    (set (attr "length")
5839         (if_then_else (eq_attr "isa" "v9")
5840                       (const_int 3) (const_int 6)))])
5842 ;; XXX
5843 (define_expand "udivsi3"
5844   [(set (match_operand:SI 0 "register_operand" "")
5845         (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "")
5846                  (match_operand:SI 2 "input_operand" "")))]
5847   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5848   "")
5850 (define_insn "udivsi3_sp32"
5851   [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
5852         (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r,r,m")
5853                  (match_operand:SI 2 "input_operand" "rI,m,r")))]
5854   "(TARGET_V8
5855     || TARGET_DEPRECATED_V8_INSNS)
5856    && TARGET_ARCH32"
5858   output_asm_insn ("wr\t%%g0, %%g0, %%y", operands);
5859   switch (which_alternative)
5860     {
5861     default:
5862       return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
5863     case 1:
5864       return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
5865     case 2:
5866       return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
5867     }
5869   [(set_attr "type" "multi")
5870    (set_attr "length" "5")])
5872 (define_insn "udivsi3_sp64"
5873   [(set (match_operand:SI 0 "register_operand" "=r")
5874         (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r")
5875                  (match_operand:SI 2 "input_operand" "rI")))]
5876   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5877   "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
5878   [(set_attr "type" "multi")
5879    (set_attr "length" "2")])
5881 (define_insn "udivdi3"
5882   [(set (match_operand:DI 0 "register_operand" "=r")
5883         (udiv:DI (match_operand:DI 1 "register_operand" "r")
5884                  (match_operand:DI 2 "arith_double_operand" "rHI")))]
5885   "TARGET_ARCH64"
5886   "udivx\t%1, %2, %0"
5887   [(set_attr "type" "idiv")])
5889 (define_insn "*cmp_udiv_cc_set"
5890   [(set (reg:CC 100)
5891         (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
5892                              (match_operand:SI 2 "arith_operand" "rI"))
5893                     (const_int 0)))
5894    (set (match_operand:SI 0 "register_operand" "=r")
5895         (udiv:SI (match_dup 1) (match_dup 2)))]
5896   "TARGET_V8
5897    || TARGET_DEPRECATED_V8_INSNS"
5899   if (TARGET_V9)
5900     return "wr\t%%g0, %%g0, %%y\n\tudivcc\t%1, %2, %0";
5901   else
5902     return "wr\t%%g0, %%g0, %%y\n\tnop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
5904   [(set_attr "type" "multi")
5905    (set (attr "length")
5906         (if_then_else (eq_attr "isa" "v9")
5907                       (const_int 2) (const_int 5)))])
5909 ; sparclet multiply/accumulate insns
5911 (define_insn "*smacsi"
5912   [(set (match_operand:SI 0 "register_operand" "=r")
5913         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
5914                           (match_operand:SI 2 "arith_operand" "rI"))
5915                  (match_operand:SI 3 "register_operand" "0")))]
5916   "TARGET_SPARCLET"
5917   "smac\t%1, %2, %0"
5918   [(set_attr "type" "imul")])
5920 (define_insn "*smacdi"
5921   [(set (match_operand:DI 0 "register_operand" "=r")
5922         (plus:DI (mult:DI (sign_extend:DI
5923                            (match_operand:SI 1 "register_operand" "%r"))
5924                           (sign_extend:DI
5925                            (match_operand:SI 2 "register_operand" "r")))
5926                  (match_operand:DI 3 "register_operand" "0")))]
5927   "TARGET_SPARCLET"
5928   "smacd\t%1, %2, %L0"
5929   [(set_attr "type" "imul")])
5931 (define_insn "*umacdi"
5932   [(set (match_operand:DI 0 "register_operand" "=r")
5933         (plus:DI (mult:DI (zero_extend:DI
5934                            (match_operand:SI 1 "register_operand" "%r"))
5935                           (zero_extend:DI
5936                            (match_operand:SI 2 "register_operand" "r")))
5937                  (match_operand:DI 3 "register_operand" "0")))]
5938   "TARGET_SPARCLET"
5939   "umacd\t%1, %2, %L0"
5940   [(set_attr "type" "imul")])
5942 ;;- Boolean instructions
5943 ;; We define DImode `and' so with DImode `not' we can get
5944 ;; DImode `andn'.  Other combinations are possible.
5946 (define_mode_macro V64I [DI V2SI V4HI V8QI])
5947 (define_mode_macro V32I [SI V2HI V4QI])
5949 (define_expand "and<V64I:mode>3"
5950   [(set (match_operand:V64I 0 "register_operand" "")
5951         (and:V64I (match_operand:V64I 1 "arith_double_operand" "")
5952                   (match_operand:V64I 2 "arith_double_operand" "")))]
5953   ""
5954   "")
5956 (define_insn "*and<V64I:mode>3_sp32"
5957   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5958         (and:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5959                   (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5960   "! TARGET_ARCH64"
5961   "@
5962   #
5963   fand\t%1, %2, %0"
5964   [(set_attr "type" "*,fga")
5965    (set_attr "length" "2,*")
5966    (set_attr "fptype" "*,double")])
5968 (define_insn "*and<V64I:mode>3_sp64"
5969   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5970         (and:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5971                   (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5972   "TARGET_ARCH64"
5973   "@
5974    and\t%1, %2, %0
5975    fand\t%1, %2, %0"
5976   [(set_attr "type" "*,fga")
5977    (set_attr "fptype" "*,double")])
5979 (define_insn "and<V32I:mode>3"
5980   [(set (match_operand:V32I 0 "register_operand" "=r,d")
5981         (and:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
5982                 (match_operand:V32I 2 "arith_operand" "rI,d")))]
5983   ""
5984   "@
5985    and\t%1, %2, %0
5986    fands\t%1, %2, %0"
5987   [(set_attr "type" "*,fga")
5988    (set_attr "fptype" "*,single")])
5990 (define_split
5991   [(set (match_operand:SI 0 "register_operand" "")
5992         (and:SI (match_operand:SI 1 "register_operand" "")
5993                 (match_operand:SI 2 "" "")))
5994    (clobber (match_operand:SI 3 "register_operand" ""))]
5995   "GET_CODE (operands[2]) == CONST_INT
5996    && !SMALL_INT32 (operands[2])
5997    && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
5998   [(set (match_dup 3) (match_dup 4))
5999    (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
6001   operands[4] = GEN_INT (~INTVAL (operands[2]));
6004 (define_insn_and_split "*and_not_<V64I:mode>_sp32"
6005   [(set (match_operand:V64I 0 "register_operand" "=r,b")
6006         (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
6007                   (match_operand:V64I 2 "register_operand" "r,b")))]
6008   "! TARGET_ARCH64"
6009   "@
6010    #
6011    fandnot1\t%1, %2, %0"
6012   "&& reload_completed
6013    && ((GET_CODE (operands[0]) == REG
6014         && REGNO (operands[0]) < 32)
6015        || (GET_CODE (operands[0]) == SUBREG
6016            && GET_CODE (SUBREG_REG (operands[0])) == REG
6017            && REGNO (SUBREG_REG (operands[0])) < 32))"
6018   [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
6019    (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
6020   "operands[3] = gen_highpart (SImode, operands[0]);
6021    operands[4] = gen_highpart (SImode, operands[1]);
6022    operands[5] = gen_highpart (SImode, operands[2]);
6023    operands[6] = gen_lowpart (SImode, operands[0]);
6024    operands[7] = gen_lowpart (SImode, operands[1]);
6025    operands[8] = gen_lowpart (SImode, operands[2]);"
6026   [(set_attr "type" "*,fga")
6027    (set_attr "length" "2,*")
6028    (set_attr "fptype" "*,double")])
6030 (define_insn "*and_not_<V64I:mode>_sp64"
6031   [(set (match_operand:V64I 0 "register_operand" "=r,b")
6032         (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
6033                   (match_operand:V64I 2 "register_operand" "r,b")))]
6034   "TARGET_ARCH64"
6035   "@
6036    andn\t%2, %1, %0
6037    fandnot1\t%1, %2, %0"
6038   [(set_attr "type" "*,fga")
6039    (set_attr "fptype" "*,double")])
6041 (define_insn "*and_not_<V32I:mode>"
6042   [(set (match_operand:V32I 0 "register_operand" "=r,d")
6043         (and:V32I (not:V32I (match_operand:V32I 1 "register_operand" "%r,d"))
6044                   (match_operand:V32I 2 "register_operand" "r,d")))]
6045   ""
6046   "@
6047    andn\t%2, %1, %0
6048    fandnot1s\t%1, %2, %0"
6049   [(set_attr "type" "*,fga")
6050    (set_attr "fptype" "*,single")])
6052 (define_expand "ior<V64I:mode>3"
6053   [(set (match_operand:V64I 0 "register_operand" "")
6054         (ior:V64I (match_operand:V64I 1 "arith_double_operand" "")
6055                   (match_operand:V64I 2 "arith_double_operand" "")))]
6056   ""
6057   "")
6059 (define_insn "*ior<V64I:mode>3_sp32"
6060   [(set (match_operand:V64I 0 "register_operand" "=r,b")
6061         (ior:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
6062                   (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
6063   "! TARGET_ARCH64"
6064   "@
6065   #
6066   for\t%1, %2, %0"
6067   [(set_attr "type" "*,fga")
6068    (set_attr "length" "2,*")
6069    (set_attr "fptype" "*,double")])
6071 (define_insn "*ior<V64I:mode>3_sp64"
6072   [(set (match_operand:V64I 0 "register_operand" "=r,b")
6073         (ior:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
6074                   (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
6075   "TARGET_ARCH64"
6076   "@
6077   or\t%1, %2, %0
6078   for\t%1, %2, %0"
6079   [(set_attr "type" "*,fga")
6080    (set_attr "fptype" "*,double")])
6082 (define_insn "ior<V32I:mode>3"
6083   [(set (match_operand:V32I 0 "register_operand" "=r,d")
6084         (ior:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
6085                   (match_operand:V32I 2 "arith_operand" "rI,d")))]
6086   ""
6087   "@
6088    or\t%1, %2, %0
6089    fors\t%1, %2, %0"
6090   [(set_attr "type" "*,fga")
6091    (set_attr "fptype" "*,single")])
6093 (define_split
6094   [(set (match_operand:SI 0 "register_operand" "")
6095         (ior:SI (match_operand:SI 1 "register_operand" "")
6096                 (match_operand:SI 2 "" "")))
6097    (clobber (match_operand:SI 3 "register_operand" ""))]
6098   "GET_CODE (operands[2]) == CONST_INT
6099    && !SMALL_INT32 (operands[2])
6100    && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6101   [(set (match_dup 3) (match_dup 4))
6102    (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
6104   operands[4] = GEN_INT (~INTVAL (operands[2]));
6107 (define_insn_and_split "*or_not_<V64I:mode>_sp32"
6108   [(set (match_operand:V64I 0 "register_operand" "=r,b")
6109         (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
6110                   (match_operand:V64I 2 "register_operand" "r,b")))]
6111   "! TARGET_ARCH64"
6112   "@
6113    #
6114    fornot1\t%1, %2, %0"
6115   "&& reload_completed
6116    && ((GET_CODE (operands[0]) == REG
6117         && REGNO (operands[0]) < 32)
6118        || (GET_CODE (operands[0]) == SUBREG
6119            && GET_CODE (SUBREG_REG (operands[0])) == REG
6120            && REGNO (SUBREG_REG (operands[0])) < 32))"
6121   [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
6122    (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
6123   "operands[3] = gen_highpart (SImode, operands[0]);
6124    operands[4] = gen_highpart (SImode, operands[1]);
6125    operands[5] = gen_highpart (SImode, operands[2]);
6126    operands[6] = gen_lowpart (SImode, operands[0]);
6127    operands[7] = gen_lowpart (SImode, operands[1]);
6128    operands[8] = gen_lowpart (SImode, operands[2]);"
6129   [(set_attr "type" "*,fga")
6130    (set_attr "length" "2,*")
6131    (set_attr "fptype" "*,double")])
6133 (define_insn "*or_not_<V64I:mode>_sp64"
6134   [(set (match_operand:V64I 0 "register_operand" "=r,b")
6135         (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
6136                   (match_operand:V64I 2 "register_operand" "r,b")))]
6137   "TARGET_ARCH64"
6138   "@
6139   orn\t%2, %1, %0
6140   fornot1\t%1, %2, %0"
6141   [(set_attr "type" "*,fga")
6142    (set_attr "fptype" "*,double")])
6144 (define_insn "*or_not_<V32I:mode>"
6145   [(set (match_operand:V32I 0 "register_operand" "=r,d")
6146         (ior:V32I (not:V32I (match_operand:V32I 1 "register_operand" "r,d"))
6147                   (match_operand:V32I 2 "register_operand" "r,d")))]
6148   ""
6149   "@
6150    orn\t%2, %1, %0
6151    fornot1s\t%1, %2, %0"
6152   [(set_attr "type" "*,fga")
6153    (set_attr "fptype" "*,single")])
6155 (define_expand "xor<V64I:mode>3"
6156   [(set (match_operand:V64I 0 "register_operand" "")
6157         (xor:V64I (match_operand:V64I 1 "arith_double_operand" "")
6158                   (match_operand:V64I 2 "arith_double_operand" "")))]
6159   ""
6160   "")
6162 (define_insn "*xor<V64I:mode>3_sp32"
6163   [(set (match_operand:V64I 0 "register_operand" "=r,b")
6164         (xor:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
6165                   (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
6166   "! TARGET_ARCH64"
6167   "@
6168   #
6169   fxor\t%1, %2, %0"
6170   [(set_attr "type" "*,fga")
6171    (set_attr "length" "2,*")
6172    (set_attr "fptype" "*,double")])
6174 (define_insn "*xor<V64I:mode>3_sp64"
6175   [(set (match_operand:V64I 0 "register_operand" "=r,b")
6176         (xor:V64I (match_operand:V64I 1 "arith_double_operand" "%rJ,b")
6177                   (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
6178   "TARGET_ARCH64"
6179   "@
6180   xor\t%r1, %2, %0
6181   fxor\t%1, %2, %0"
6182   [(set_attr "type" "*,fga")
6183    (set_attr "fptype" "*,double")])
6185 (define_insn "*xordi3_sp64_dbl"
6186   [(set (match_operand:DI 0 "register_operand" "=r")
6187         (xor:DI (match_operand:DI 1 "register_operand" "r")
6188                 (match_operand:DI 2 "const64_operand" "")))]
6189   "(TARGET_ARCH64
6190     && HOST_BITS_PER_WIDE_INT != 64)"
6191   "xor\t%1, %2, %0")
6193 (define_insn "xor<V32I:mode>3"
6194   [(set (match_operand:V32I 0 "register_operand" "=r,d")
6195         (xor:V32I (match_operand:V32I 1 "arith_operand" "%rJ,d")
6196                   (match_operand:V32I 2 "arith_operand" "rI,d")))]
6197   ""
6198   "@
6199    xor\t%r1, %2, %0
6200    fxors\t%1, %2, %0"
6201   [(set_attr "type" "*,fga")
6202    (set_attr "fptype" "*,single")])
6204 (define_split
6205   [(set (match_operand:SI 0 "register_operand" "")
6206         (xor:SI (match_operand:SI 1 "register_operand" "")
6207                 (match_operand:SI 2 "" "")))
6208    (clobber (match_operand:SI 3 "register_operand" ""))]
6209   "GET_CODE (operands[2]) == CONST_INT
6210    && !SMALL_INT32 (operands[2])
6211    && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6212   [(set (match_dup 3) (match_dup 4))
6213    (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
6215   operands[4] = GEN_INT (~INTVAL (operands[2]));
6218 (define_split
6219   [(set (match_operand:SI 0 "register_operand" "")
6220         (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
6221                         (match_operand:SI 2 "" ""))))
6222    (clobber (match_operand:SI 3 "register_operand" ""))]
6223   "GET_CODE (operands[2]) == CONST_INT
6224    && !SMALL_INT32 (operands[2])
6225    && (INTVAL (operands[2]) & 0x3ff) == 0x3ff"
6226   [(set (match_dup 3) (match_dup 4))
6227    (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
6229   operands[4] = GEN_INT (~INTVAL (operands[2]));
6232 ;; Split DImode logical operations requiring two instructions.
6233 (define_split
6234   [(set (match_operand:V64I 0 "register_operand" "")
6235         (match_operator:V64I 1 "cc_arithop"     ; AND, IOR, XOR
6236                            [(match_operand:V64I 2 "register_operand" "")
6237                             (match_operand:V64I 3 "arith_double_operand" "")]))]
6238   "! TARGET_ARCH64
6239    && reload_completed
6240    && ((GET_CODE (operands[0]) == REG
6241         && REGNO (operands[0]) < 32)
6242        || (GET_CODE (operands[0]) == SUBREG
6243            && GET_CODE (SUBREG_REG (operands[0])) == REG
6244            && REGNO (SUBREG_REG (operands[0])) < 32))"
6245   [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
6246    (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
6248   operands[4] = gen_highpart (SImode, operands[0]);
6249   operands[5] = gen_lowpart (SImode, operands[0]);
6250   operands[6] = gen_highpart (SImode, operands[2]);
6251   operands[7] = gen_lowpart (SImode, operands[2]);
6252 #if HOST_BITS_PER_WIDE_INT == 32
6253   if (GET_CODE (operands[3]) == CONST_INT && <V64I:MODE>mode == DImode)
6254     {
6255       if (INTVAL (operands[3]) < 0)
6256         operands[8] = constm1_rtx;
6257       else
6258         operands[8] = const0_rtx;
6259     }
6260   else
6261 #endif
6262     operands[8] = gen_highpart_mode (SImode, <V64I:MODE>mode, operands[3]);
6263   operands[9] = gen_lowpart (SImode, operands[3]);
6266 ;; xnor patterns.  Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
6267 ;; Combine now canonicalizes to the rightmost expression.
6268 (define_insn_and_split "*xor_not_<V64I:mode>_sp32"
6269   [(set (match_operand:V64I 0 "register_operand" "=r,b")
6270         (not:V64I (xor:V64I (match_operand:V64I 1 "register_operand" "r,b")
6271                             (match_operand:V64I 2 "register_operand" "r,b"))))]
6272   "! TARGET_ARCH64"
6273   "@
6274    #
6275    fxnor\t%1, %2, %0"
6276   "&& reload_completed
6277    && ((GET_CODE (operands[0]) == REG
6278         && REGNO (operands[0]) < 32)
6279        || (GET_CODE (operands[0]) == SUBREG
6280            && GET_CODE (SUBREG_REG (operands[0])) == REG
6281            && REGNO (SUBREG_REG (operands[0])) < 32))"
6282   [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
6283    (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
6284   "operands[3] = gen_highpart (SImode, operands[0]);
6285    operands[4] = gen_highpart (SImode, operands[1]);
6286    operands[5] = gen_highpart (SImode, operands[2]);
6287    operands[6] = gen_lowpart (SImode, operands[0]);
6288    operands[7] = gen_lowpart (SImode, operands[1]);
6289    operands[8] = gen_lowpart (SImode, operands[2]);"
6290   [(set_attr "type" "*,fga")
6291    (set_attr "length" "2,*")
6292    (set_attr "fptype" "*,double")])
6294 (define_insn "*xor_not_<V64I:mode>_sp64"
6295   [(set (match_operand:V64I 0 "register_operand" "=r,b")
6296         (not:V64I (xor:V64I (match_operand:V64I 1 "reg_or_0_operand" "rJ,b")
6297                             (match_operand:V64I 2 "arith_double_operand" "rHI,b"))))]
6298   "TARGET_ARCH64"
6299   "@
6300   xnor\t%r1, %2, %0
6301   fxnor\t%1, %2, %0"
6302   [(set_attr "type" "*,fga")
6303    (set_attr "fptype" "*,double")])
6305 (define_insn "*xor_not_<V32I:mode>"
6306   [(set (match_operand:V32I 0 "register_operand" "=r,d")
6307         (not:V32I (xor:V32I (match_operand:V32I 1 "reg_or_0_operand" "rJ,d")
6308                             (match_operand:V32I 2 "arith_operand" "rI,d"))))]
6309   ""
6310   "@
6311    xnor\t%r1, %2, %0
6312    fxnors\t%1, %2, %0"
6313   [(set_attr "type" "*,fga")
6314    (set_attr "fptype" "*,single")])
6316 ;; These correspond to the above in the case where we also (or only)
6317 ;; want to set the condition code.  
6319 (define_insn "*cmp_cc_arith_op"
6320   [(set (reg:CC 100)
6321         (compare:CC
6322          (match_operator:SI 2 "cc_arithop"
6323                             [(match_operand:SI 0 "arith_operand" "%r")
6324                              (match_operand:SI 1 "arith_operand" "rI")])
6325          (const_int 0)))]
6326   ""
6327   "%A2cc\t%0, %1, %%g0"
6328   [(set_attr "type" "compare")])
6330 (define_insn "*cmp_ccx_arith_op"
6331   [(set (reg:CCX 100)
6332         (compare:CCX
6333          (match_operator:DI 2 "cc_arithop"
6334                             [(match_operand:DI 0 "arith_double_operand" "%r")
6335                              (match_operand:DI 1 "arith_double_operand" "rHI")])
6336          (const_int 0)))]
6337   "TARGET_ARCH64"
6338   "%A2cc\t%0, %1, %%g0"
6339   [(set_attr "type" "compare")])
6341 (define_insn "*cmp_cc_arith_op_set"
6342   [(set (reg:CC 100)
6343         (compare:CC
6344          (match_operator:SI 3 "cc_arithop"
6345                             [(match_operand:SI 1 "arith_operand" "%r")
6346                              (match_operand:SI 2 "arith_operand" "rI")])
6347          (const_int 0)))
6348    (set (match_operand:SI 0 "register_operand" "=r")
6349         (match_operator:SI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6350   "GET_CODE (operands[3]) == GET_CODE (operands[4])"
6351   "%A3cc\t%1, %2, %0"
6352   [(set_attr "type" "compare")])
6354 (define_insn "*cmp_ccx_arith_op_set"
6355   [(set (reg:CCX 100)
6356         (compare:CCX
6357          (match_operator:DI 3 "cc_arithop"
6358                             [(match_operand:DI 1 "arith_double_operand" "%r")
6359                              (match_operand:DI 2 "arith_double_operand" "rHI")])
6360          (const_int 0)))
6361    (set (match_operand:DI 0 "register_operand" "=r")
6362         (match_operator:DI 4 "cc_arithop" [(match_dup 1) (match_dup 2)]))]
6363   "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
6364   "%A3cc\t%1, %2, %0"
6365   [(set_attr "type" "compare")])
6367 (define_insn "*cmp_cc_xor_not"
6368   [(set (reg:CC 100)
6369         (compare:CC
6370          (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ")
6371                          (match_operand:SI 1 "arith_operand" "rI")))
6372          (const_int 0)))]
6373   ""
6374   "xnorcc\t%r0, %1, %%g0"
6375   [(set_attr "type" "compare")])
6377 (define_insn "*cmp_ccx_xor_not"
6378   [(set (reg:CCX 100)
6379         (compare:CCX
6380          (not:DI (xor:DI (match_operand:DI 0 "reg_or_0_operand" "%rJ")
6381                          (match_operand:DI 1 "arith_double_operand" "rHI")))
6382          (const_int 0)))]
6383   "TARGET_ARCH64"
6384   "xnorcc\t%r0, %1, %%g0"
6385   [(set_attr "type" "compare")])
6387 (define_insn "*cmp_cc_xor_not_set"
6388   [(set (reg:CC 100)
6389         (compare:CC
6390          (not:SI (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
6391                          (match_operand:SI 2 "arith_operand" "rI")))
6392          (const_int 0)))
6393    (set (match_operand:SI 0 "register_operand" "=r")
6394         (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
6395   ""
6396   "xnorcc\t%r1, %2, %0"
6397   [(set_attr "type" "compare")])
6399 (define_insn "*cmp_ccx_xor_not_set"
6400   [(set (reg:CCX 100)
6401         (compare:CCX
6402          (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
6403                          (match_operand:DI 2 "arith_double_operand" "rHI")))
6404          (const_int 0)))
6405    (set (match_operand:DI 0 "register_operand" "=r")
6406         (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
6407   "TARGET_ARCH64"
6408   "xnorcc\t%r1, %2, %0"
6409   [(set_attr "type" "compare")])
6411 (define_insn "*cmp_cc_arith_op_not"
6412   [(set (reg:CC 100)
6413         (compare:CC
6414          (match_operator:SI 2 "cc_arithopn"
6415                             [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
6416                              (match_operand:SI 1 "reg_or_0_operand" "rJ")])
6417          (const_int 0)))]
6418   ""
6419   "%B2cc\t%r1, %0, %%g0"
6420   [(set_attr "type" "compare")])
6422 (define_insn "*cmp_ccx_arith_op_not"
6423   [(set (reg:CCX 100)
6424         (compare:CCX
6425          (match_operator:DI 2 "cc_arithopn"
6426                             [(not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6427                              (match_operand:DI 1 "reg_or_0_operand" "rJ")])
6428          (const_int 0)))]
6429   "TARGET_ARCH64"
6430   "%B2cc\t%r1, %0, %%g0"
6431   [(set_attr "type" "compare")])
6433 (define_insn "*cmp_cc_arith_op_not_set"
6434   [(set (reg:CC 100)
6435         (compare:CC
6436          (match_operator:SI 3 "cc_arithopn"
6437                             [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
6438                              (match_operand:SI 2 "reg_or_0_operand" "rJ")])
6439          (const_int 0)))
6440    (set (match_operand:SI 0 "register_operand" "=r")
6441         (match_operator:SI 4 "cc_arithopn"
6442                             [(not:SI (match_dup 1)) (match_dup 2)]))]
6443   "GET_CODE (operands[3]) == GET_CODE (operands[4])"
6444   "%B3cc\t%r2, %1, %0"
6445   [(set_attr "type" "compare")])
6447 (define_insn "*cmp_ccx_arith_op_not_set"
6448   [(set (reg:CCX 100)
6449         (compare:CCX
6450          (match_operator:DI 3 "cc_arithopn"
6451                             [(not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6452                              (match_operand:DI 2 "reg_or_0_operand" "rJ")])
6453          (const_int 0)))
6454    (set (match_operand:DI 0 "register_operand" "=r")
6455         (match_operator:DI 4 "cc_arithopn"
6456                             [(not:DI (match_dup 1)) (match_dup 2)]))]
6457   "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
6458   "%B3cc\t%r2, %1, %0"
6459   [(set_attr "type" "compare")])
6461 ;; We cannot use the "neg" pseudo insn because the Sun assembler
6462 ;; does not know how to make it work for constants.
6464 (define_expand "negdi2"
6465   [(set (match_operand:DI 0 "register_operand" "=r")
6466         (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6467   ""
6469   if (! TARGET_ARCH64)
6470     {
6471       emit_insn (gen_rtx_PARALLEL
6472                  (VOIDmode,
6473                   gen_rtvec (2,
6474                              gen_rtx_SET (VOIDmode, operand0,
6475                                           gen_rtx_NEG (DImode, operand1)),
6476                              gen_rtx_CLOBBER (VOIDmode,
6477                                               gen_rtx_REG (CCmode,
6478                                                            SPARC_ICC_REG)))));
6479       DONE;
6480     }
6483 (define_insn_and_split "*negdi2_sp32"
6484   [(set (match_operand:DI 0 "register_operand" "=r")
6485         (neg:DI (match_operand:DI 1 "register_operand" "r")))
6486    (clobber (reg:CC 100))]
6487   "TARGET_ARCH32"
6488   "#"
6489   "&& reload_completed"
6490   [(parallel [(set (reg:CC_NOOV 100)
6491                    (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
6492                                     (const_int 0)))
6493               (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
6494    (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
6495                                 (ltu:SI (reg:CC 100) (const_int 0))))]
6496   "operands[2] = gen_highpart (SImode, operands[0]);
6497    operands[3] = gen_highpart (SImode, operands[1]);
6498    operands[4] = gen_lowpart (SImode, operands[0]);
6499    operands[5] = gen_lowpart (SImode, operands[1]);"
6500   [(set_attr "length" "2")])
6502 (define_insn "*negdi2_sp64"
6503   [(set (match_operand:DI 0 "register_operand" "=r")
6504         (neg:DI (match_operand:DI 1 "register_operand" "r")))]
6505   "TARGET_ARCH64"
6506   "sub\t%%g0, %1, %0")
6508 (define_insn "negsi2"
6509   [(set (match_operand:SI 0 "register_operand" "=r")
6510         (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
6511   ""
6512   "sub\t%%g0, %1, %0")
6514 (define_insn "*cmp_cc_neg"
6515   [(set (reg:CC_NOOV 100)
6516         (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
6517                          (const_int 0)))]
6518   ""
6519   "subcc\t%%g0, %0, %%g0"
6520   [(set_attr "type" "compare")])
6522 (define_insn "*cmp_ccx_neg"
6523   [(set (reg:CCX_NOOV 100)
6524         (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6525                           (const_int 0)))]
6526   "TARGET_ARCH64"
6527   "subcc\t%%g0, %0, %%g0"
6528   [(set_attr "type" "compare")])
6530 (define_insn "*cmp_cc_set_neg"
6531   [(set (reg:CC_NOOV 100)
6532         (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
6533                          (const_int 0)))
6534    (set (match_operand:SI 0 "register_operand" "=r")
6535         (neg:SI (match_dup 1)))]
6536   ""
6537   "subcc\t%%g0, %1, %0"
6538   [(set_attr "type" "compare")])
6540 (define_insn "*cmp_ccx_set_neg"
6541   [(set (reg:CCX_NOOV 100)
6542         (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6543                           (const_int 0)))
6544    (set (match_operand:DI 0 "register_operand" "=r")
6545         (neg:DI (match_dup 1)))]
6546   "TARGET_ARCH64"
6547   "subcc\t%%g0, %1, %0"
6548   [(set_attr "type" "compare")])
6550 ;; We cannot use the "not" pseudo insn because the Sun assembler
6551 ;; does not know how to make it work for constants.
6552 (define_expand "one_cmpl<V64I:mode>2"
6553   [(set (match_operand:V64I 0 "register_operand" "")
6554         (not:V64I (match_operand:V64I 1 "register_operand" "")))]
6555   ""
6556   "")
6558 (define_insn_and_split "*one_cmpl<V64I:mode>2_sp32"
6559   [(set (match_operand:V64I 0 "register_operand" "=r,b")
6560         (not:V64I (match_operand:V64I 1 "register_operand" "r,b")))]
6561   "! TARGET_ARCH64"
6562   "@
6563    #
6564    fnot1\t%1, %0"
6565   "&& reload_completed
6566    && ((GET_CODE (operands[0]) == REG
6567         && REGNO (operands[0]) < 32)
6568        || (GET_CODE (operands[0]) == SUBREG
6569            && GET_CODE (SUBREG_REG (operands[0])) == REG
6570            && REGNO (SUBREG_REG (operands[0])) < 32))"
6571   [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
6572    (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
6573   "operands[2] = gen_highpart (SImode, operands[0]);
6574    operands[3] = gen_highpart (SImode, operands[1]);
6575    operands[4] = gen_lowpart (SImode, operands[0]);
6576    operands[5] = gen_lowpart (SImode, operands[1]);"
6577   [(set_attr "type" "*,fga")
6578    (set_attr "length" "2,*")
6579    (set_attr "fptype" "*,double")])
6581 (define_insn "*one_cmpl<V64I:mode>2_sp64"
6582   [(set (match_operand:V64I 0 "register_operand" "=r,b")
6583         (not:V64I (match_operand:V64I 1 "arith_double_operand" "rHI,b")))]
6584   "TARGET_ARCH64"
6585   "@
6586    xnor\t%%g0, %1, %0
6587    fnot1\t%1, %0"
6588   [(set_attr "type" "*,fga")
6589    (set_attr "fptype" "*,double")])
6591 (define_insn "one_cmpl<V32I:mode>2"
6592   [(set (match_operand:V32I 0 "register_operand" "=r,d")
6593         (not:V32I (match_operand:V32I 1 "arith_operand" "rI,d")))]
6594   ""
6595   "@
6596   xnor\t%%g0, %1, %0
6597   fnot1s\t%1, %0"
6598   [(set_attr "type" "*,fga")
6599    (set_attr "fptype" "*,single")])
6601 (define_insn "*cmp_cc_not"
6602   [(set (reg:CC 100)
6603         (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
6604                     (const_int 0)))]
6605   ""
6606   "xnorcc\t%%g0, %0, %%g0"
6607   [(set_attr "type" "compare")])
6609 (define_insn "*cmp_ccx_not"
6610   [(set (reg:CCX 100)
6611         (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI"))
6612                      (const_int 0)))]
6613   "TARGET_ARCH64"
6614   "xnorcc\t%%g0, %0, %%g0"
6615   [(set_attr "type" "compare")])
6617 (define_insn "*cmp_cc_set_not"
6618   [(set (reg:CC 100)
6619         (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
6620                     (const_int 0)))
6621    (set (match_operand:SI 0 "register_operand" "=r")
6622         (not:SI (match_dup 1)))]
6623   ""
6624   "xnorcc\t%%g0, %1, %0"
6625   [(set_attr "type" "compare")])
6627 (define_insn "*cmp_ccx_set_not"
6628   [(set (reg:CCX 100)
6629         (compare:CCX (not:DI (match_operand:DI 1 "arith_double_operand" "rHI"))
6630                     (const_int 0)))
6631    (set (match_operand:DI 0 "register_operand" "=r")
6632         (not:DI (match_dup 1)))]
6633   "TARGET_ARCH64"
6634   "xnorcc\t%%g0, %1, %0"
6635   [(set_attr "type" "compare")])
6637 (define_insn "*cmp_cc_set"
6638   [(set (match_operand:SI 0 "register_operand" "=r")
6639         (match_operand:SI 1 "register_operand" "r"))
6640    (set (reg:CC 100)
6641         (compare:CC (match_dup 1)
6642                     (const_int 0)))]
6643   ""
6644   "orcc\t%1, 0, %0"
6645   [(set_attr "type" "compare")])
6647 (define_insn "*cmp_ccx_set64"
6648   [(set (match_operand:DI 0 "register_operand" "=r")
6649         (match_operand:DI 1 "register_operand" "r"))
6650    (set (reg:CCX 100)
6651         (compare:CCX (match_dup 1)
6652                      (const_int 0)))]
6653   "TARGET_ARCH64"
6654   "orcc\t%1, 0, %0"
6655    [(set_attr "type" "compare")])
6657 ;; Floating point arithmetic instructions.
6659 (define_expand "addtf3"
6660   [(set (match_operand:TF 0 "nonimmediate_operand" "")
6661         (plus:TF (match_operand:TF 1 "general_operand" "")
6662                  (match_operand:TF 2 "general_operand" "")))]
6663   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6664   "emit_tfmode_binop (PLUS, operands); DONE;")
6666 (define_insn "*addtf3_hq"
6667   [(set (match_operand:TF 0 "register_operand" "=e")
6668         (plus:TF (match_operand:TF 1 "register_operand" "e")
6669                  (match_operand:TF 2 "register_operand" "e")))]
6670   "TARGET_FPU && TARGET_HARD_QUAD"
6671   "faddq\t%1, %2, %0"
6672   [(set_attr "type" "fp")])
6674 (define_insn "adddf3"
6675   [(set (match_operand:DF 0 "register_operand" "=e")
6676         (plus:DF (match_operand:DF 1 "register_operand" "e")
6677                  (match_operand:DF 2 "register_operand" "e")))]
6678   "TARGET_FPU"
6679   "faddd\t%1, %2, %0"
6680   [(set_attr "type" "fp")
6681    (set_attr "fptype" "double")])
6683 (define_insn "addsf3"
6684   [(set (match_operand:SF 0 "register_operand" "=f")
6685         (plus:SF (match_operand:SF 1 "register_operand" "f")
6686                  (match_operand:SF 2 "register_operand" "f")))]
6687   "TARGET_FPU"
6688   "fadds\t%1, %2, %0"
6689   [(set_attr "type" "fp")])
6691 (define_expand "subtf3"
6692   [(set (match_operand:TF 0 "nonimmediate_operand" "")
6693         (minus:TF (match_operand:TF 1 "general_operand" "")
6694                   (match_operand:TF 2 "general_operand" "")))]
6695   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6696   "emit_tfmode_binop (MINUS, operands); DONE;")
6698 (define_insn "*subtf3_hq"
6699   [(set (match_operand:TF 0 "register_operand" "=e")
6700         (minus:TF (match_operand:TF 1 "register_operand" "e")
6701                   (match_operand:TF 2 "register_operand" "e")))]
6702   "TARGET_FPU && TARGET_HARD_QUAD"
6703   "fsubq\t%1, %2, %0"
6704   [(set_attr "type" "fp")])
6706 (define_insn "subdf3"
6707   [(set (match_operand:DF 0 "register_operand" "=e")
6708         (minus:DF (match_operand:DF 1 "register_operand" "e")
6709                   (match_operand:DF 2 "register_operand" "e")))]
6710   "TARGET_FPU"
6711   "fsubd\t%1, %2, %0"
6712   [(set_attr "type" "fp")
6713    (set_attr "fptype" "double")])
6715 (define_insn "subsf3"
6716   [(set (match_operand:SF 0 "register_operand" "=f")
6717         (minus:SF (match_operand:SF 1 "register_operand" "f")
6718                   (match_operand:SF 2 "register_operand" "f")))]
6719   "TARGET_FPU"
6720   "fsubs\t%1, %2, %0"
6721   [(set_attr "type" "fp")])
6723 (define_expand "multf3"
6724   [(set (match_operand:TF 0 "nonimmediate_operand" "")
6725         (mult:TF (match_operand:TF 1 "general_operand" "")
6726                  (match_operand:TF 2 "general_operand" "")))]
6727   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6728   "emit_tfmode_binop (MULT, operands); DONE;")
6730 (define_insn "*multf3_hq"
6731   [(set (match_operand:TF 0 "register_operand" "=e")
6732         (mult:TF (match_operand:TF 1 "register_operand" "e")
6733                  (match_operand:TF 2 "register_operand" "e")))]
6734   "TARGET_FPU && TARGET_HARD_QUAD"
6735   "fmulq\t%1, %2, %0"
6736   [(set_attr "type" "fpmul")])
6738 (define_insn "muldf3"
6739   [(set (match_operand:DF 0 "register_operand" "=e")
6740         (mult:DF (match_operand:DF 1 "register_operand" "e")
6741                  (match_operand:DF 2 "register_operand" "e")))]
6742   "TARGET_FPU"
6743   "fmuld\t%1, %2, %0"
6744   [(set_attr "type" "fpmul")
6745    (set_attr "fptype" "double")])
6747 (define_insn "mulsf3"
6748   [(set (match_operand:SF 0 "register_operand" "=f")
6749         (mult:SF (match_operand:SF 1 "register_operand" "f")
6750                  (match_operand:SF 2 "register_operand" "f")))]
6751   "TARGET_FPU"
6752   "fmuls\t%1, %2, %0"
6753   [(set_attr "type" "fpmul")])
6755 (define_insn "*muldf3_extend"
6756   [(set (match_operand:DF 0 "register_operand" "=e")
6757         (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
6758                  (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
6759   "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
6760   "fsmuld\t%1, %2, %0"
6761   [(set_attr "type" "fpmul")
6762    (set_attr "fptype" "double")])
6764 (define_insn "*multf3_extend"
6765   [(set (match_operand:TF 0 "register_operand" "=e")
6766         (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
6767                  (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
6768   "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
6769   "fdmulq\t%1, %2, %0"
6770   [(set_attr "type" "fpmul")])
6772 (define_expand "divtf3"
6773   [(set (match_operand:TF 0 "nonimmediate_operand" "")
6774         (div:TF (match_operand:TF 1 "general_operand" "")
6775                 (match_operand:TF 2 "general_operand" "")))]
6776   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6777   "emit_tfmode_binop (DIV, operands); DONE;")
6779 ;; don't have timing for quad-prec. divide.
6780 (define_insn "*divtf3_hq"
6781   [(set (match_operand:TF 0 "register_operand" "=e")
6782         (div:TF (match_operand:TF 1 "register_operand" "e")
6783                 (match_operand:TF 2 "register_operand" "e")))]
6784   "TARGET_FPU && TARGET_HARD_QUAD"
6785   "fdivq\t%1, %2, %0"
6786   [(set_attr "type" "fpdivd")])
6788 (define_insn "divdf3"
6789   [(set (match_operand:DF 0 "register_operand" "=e")
6790         (div:DF (match_operand:DF 1 "register_operand" "e")
6791                 (match_operand:DF 2 "register_operand" "e")))]
6792   "TARGET_FPU"
6793   "fdivd\t%1, %2, %0"
6794   [(set_attr "type" "fpdivd")
6795    (set_attr "fptype" "double")])
6797 (define_insn "divsf3"
6798   [(set (match_operand:SF 0 "register_operand" "=f")
6799         (div:SF (match_operand:SF 1 "register_operand" "f")
6800                 (match_operand:SF 2 "register_operand" "f")))]
6801   "TARGET_FPU"
6802   "fdivs\t%1, %2, %0"
6803   [(set_attr "type" "fpdivs")])
6805 (define_expand "negtf2"
6806   [(set (match_operand:TF 0 "register_operand" "=e,e")
6807         (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6808   "TARGET_FPU"
6809   "")
6811 (define_insn_and_split "*negtf2_notv9"
6812   [(set (match_operand:TF 0 "register_operand" "=e,e")
6813         (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6814   ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6815   "TARGET_FPU
6816    && ! TARGET_V9"
6817   "@
6818   fnegs\t%0, %0
6819   #"
6820   "&& reload_completed
6821    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6822   [(set (match_dup 2) (neg:SF (match_dup 3)))
6823    (set (match_dup 4) (match_dup 5))
6824    (set (match_dup 6) (match_dup 7))]
6825   "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6826    operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6827    operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6828    operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6829    operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6830    operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6831   [(set_attr "type" "fpmove,*")
6832    (set_attr "length" "*,2")])
6834 (define_insn_and_split "*negtf2_v9"
6835   [(set (match_operand:TF 0 "register_operand" "=e,e")
6836         (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6837   ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6838   "TARGET_FPU && TARGET_V9"
6839   "@
6840   fnegd\t%0, %0
6841   #"
6842   "&& reload_completed
6843    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6844   [(set (match_dup 2) (neg:DF (match_dup 3)))
6845    (set (match_dup 4) (match_dup 5))]
6846   "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6847    operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6848    operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6849    operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6850   [(set_attr "type" "fpmove,*")
6851    (set_attr "length" "*,2")
6852    (set_attr "fptype" "double")])
6854 (define_expand "negdf2"
6855   [(set (match_operand:DF 0 "register_operand" "")
6856         (neg:DF (match_operand:DF 1 "register_operand" "")))]
6857   "TARGET_FPU"
6858   "")
6860 (define_insn_and_split "*negdf2_notv9"
6861   [(set (match_operand:DF 0 "register_operand" "=e,e")
6862         (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
6863   "TARGET_FPU && ! TARGET_V9"
6864   "@
6865   fnegs\t%0, %0
6866   #"
6867   "&& reload_completed
6868    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6869   [(set (match_dup 2) (neg:SF (match_dup 3)))
6870    (set (match_dup 4) (match_dup 5))]
6871   "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6872    operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6873    operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6874    operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6875   [(set_attr "type" "fpmove,*")
6876    (set_attr "length" "*,2")])
6878 (define_insn "*negdf2_v9"
6879   [(set (match_operand:DF 0 "register_operand" "=e")
6880         (neg:DF (match_operand:DF 1 "register_operand" "e")))]
6881   "TARGET_FPU && TARGET_V9"
6882   "fnegd\t%1, %0"
6883   [(set_attr "type" "fpmove")
6884    (set_attr "fptype" "double")])
6886 (define_insn "negsf2"
6887   [(set (match_operand:SF 0 "register_operand" "=f")
6888         (neg:SF (match_operand:SF 1 "register_operand" "f")))]
6889   "TARGET_FPU"
6890   "fnegs\t%1, %0"
6891   [(set_attr "type" "fpmove")])
6893 (define_expand "abstf2"
6894   [(set (match_operand:TF 0 "register_operand" "")
6895         (abs:TF (match_operand:TF 1 "register_operand" "")))]
6896   "TARGET_FPU"
6897   "")
6899 (define_insn_and_split "*abstf2_notv9"
6900   [(set (match_operand:TF 0 "register_operand" "=e,e")
6901         (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6902   ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6903   "TARGET_FPU && ! TARGET_V9"
6904   "@
6905   fabss\t%0, %0
6906   #"
6907   "&& reload_completed
6908    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6909   [(set (match_dup 2) (abs:SF (match_dup 3)))
6910    (set (match_dup 4) (match_dup 5))
6911    (set (match_dup 6) (match_dup 7))]
6912   "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6913    operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6914    operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6915    operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6916    operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6917    operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6918   [(set_attr "type" "fpmove,*")
6919    (set_attr "length" "*,2")])
6921 (define_insn "*abstf2_hq_v9"
6922   [(set (match_operand:TF 0 "register_operand" "=e,e")
6923         (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6924   "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
6925   "@
6926   fabsd\t%0, %0
6927   fabsq\t%1, %0"
6928   [(set_attr "type" "fpmove")
6929    (set_attr "fptype" "double,*")])
6931 (define_insn_and_split "*abstf2_v9"
6932   [(set (match_operand:TF 0 "register_operand" "=e,e")
6933         (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6934   "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
6935   "@
6936   fabsd\t%0, %0
6937   #"
6938   "&& reload_completed
6939    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6940   [(set (match_dup 2) (abs:DF (match_dup 3)))
6941    (set (match_dup 4) (match_dup 5))]
6942   "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6943    operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6944    operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6945    operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6946   [(set_attr "type" "fpmove,*")
6947    (set_attr "length" "*,2")
6948    (set_attr "fptype" "double,*")])
6950 (define_expand "absdf2"
6951   [(set (match_operand:DF 0 "register_operand" "")
6952         (abs:DF (match_operand:DF 1 "register_operand" "")))]
6953   "TARGET_FPU"
6954   "")
6956 (define_insn_and_split "*absdf2_notv9"
6957   [(set (match_operand:DF 0 "register_operand" "=e,e")
6958         (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
6959   "TARGET_FPU && ! TARGET_V9"
6960   "@
6961   fabss\t%0, %0
6962   #"
6963   "&& reload_completed
6964    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6965   [(set (match_dup 2) (abs:SF (match_dup 3)))
6966    (set (match_dup 4) (match_dup 5))]
6967   "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6968    operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6969    operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6970    operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6971   [(set_attr "type" "fpmove,*")
6972    (set_attr "length" "*,2")])
6974 (define_insn "*absdf2_v9"
6975   [(set (match_operand:DF 0 "register_operand" "=e")
6976         (abs:DF (match_operand:DF 1 "register_operand" "e")))]
6977   "TARGET_FPU && TARGET_V9"
6978   "fabsd\t%1, %0"
6979   [(set_attr "type" "fpmove")
6980    (set_attr "fptype" "double")])
6982 (define_insn "abssf2"
6983   [(set (match_operand:SF 0 "register_operand" "=f")
6984         (abs:SF (match_operand:SF 1 "register_operand" "f")))]
6985   "TARGET_FPU"
6986   "fabss\t%1, %0"
6987   [(set_attr "type" "fpmove")])
6989 (define_expand "sqrttf2"
6990   [(set (match_operand:TF 0 "nonimmediate_operand" "")
6991         (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
6992   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6993   "emit_tfmode_unop (SQRT, operands); DONE;")
6995 (define_insn "*sqrttf2_hq"
6996   [(set (match_operand:TF 0 "register_operand" "=e")
6997         (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
6998   "TARGET_FPU && TARGET_HARD_QUAD"
6999   "fsqrtq\t%1, %0"
7000   [(set_attr "type" "fpsqrtd")])
7002 (define_insn "sqrtdf2"
7003   [(set (match_operand:DF 0 "register_operand" "=e")
7004         (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
7005   "TARGET_FPU"
7006   "fsqrtd\t%1, %0"
7007   [(set_attr "type" "fpsqrtd")
7008    (set_attr "fptype" "double")])
7010 (define_insn "sqrtsf2"
7011   [(set (match_operand:SF 0 "register_operand" "=f")
7012         (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
7013   "TARGET_FPU"
7014   "fsqrts\t%1, %0"
7015   [(set_attr "type" "fpsqrts")])
7017 ;;- arithmetic shift instructions
7019 (define_insn "ashlsi3"
7020   [(set (match_operand:SI 0 "register_operand" "=r")
7021         (ashift:SI (match_operand:SI 1 "register_operand" "r")
7022                    (match_operand:SI 2 "arith_operand" "rI")))]
7023   ""
7025   if (GET_CODE (operands[2]) == CONST_INT)
7026     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7027   return "sll\t%1, %2, %0";
7029   [(set (attr "type")
7030         (if_then_else (match_operand 2 "const1_operand" "")
7031                       (const_string "ialu") (const_string "shift")))])
7033 (define_expand "ashldi3"
7034   [(set (match_operand:DI 0 "register_operand" "=r")
7035         (ashift:DI (match_operand:DI 1 "register_operand" "r")
7036                    (match_operand:SI 2 "arith_operand" "rI")))]
7037   "TARGET_ARCH64 || TARGET_V8PLUS"
7039   if (! TARGET_ARCH64)
7040     {
7041       if (GET_CODE (operands[2]) == CONST_INT)
7042         FAIL;
7043       emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
7044       DONE;
7045     }
7048 (define_insn "*ashldi3_sp64"
7049   [(set (match_operand:DI 0 "register_operand" "=r")
7050         (ashift:DI (match_operand:DI 1 "register_operand" "r")
7051                    (match_operand:SI 2 "arith_operand" "rI")))]
7052   "TARGET_ARCH64"
7054   if (GET_CODE (operands[2]) == CONST_INT)
7055     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7056   return "sllx\t%1, %2, %0";
7058   [(set (attr "type")
7059         (if_then_else (match_operand 2 "const1_operand" "")
7060                       (const_string "ialu") (const_string "shift")))])
7062 ;; XXX UGH!
7063 (define_insn "ashldi3_v8plus"
7064   [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7065         (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7066                    (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7067    (clobber (match_scratch:SI 3 "=X,X,&h"))]
7068   "TARGET_V8PLUS"
7069   "* return output_v8plus_shift (operands, insn, \"sllx\");"
7070   [(set_attr "type" "multi")
7071    (set_attr "length" "5,5,6")])
7073 ;; Optimize (1LL<<x)-1
7074 ;; XXX this also needs to be fixed to handle equal subregs
7075 ;; XXX first before we could re-enable it.
7076 ;(define_insn ""
7077 ;  [(set (match_operand:DI 0 "register_operand" "=h")
7078 ;       (plus:DI (ashift:DI (const_int 1)
7079 ;                           (match_operand:SI 1 "arith_operand" "rI"))
7080 ;                (const_int -1)))]
7081 ;  "0 && TARGET_V8PLUS"
7083 ;  if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
7084 ;    return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
7085 ;  return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
7087 ;  [(set_attr "type" "multi")
7088 ;   (set_attr "length" "4")])
7090 (define_insn "*cmp_cc_ashift_1"
7091   [(set (reg:CC_NOOV 100)
7092         (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
7093                                     (const_int 1))
7094                          (const_int 0)))]
7095   ""
7096   "addcc\t%0, %0, %%g0"
7097   [(set_attr "type" "compare")])
7099 (define_insn "*cmp_cc_set_ashift_1"
7100   [(set (reg:CC_NOOV 100)
7101         (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
7102                                     (const_int 1))
7103                          (const_int 0)))
7104    (set (match_operand:SI 0 "register_operand" "=r")
7105         (ashift:SI (match_dup 1) (const_int 1)))]
7106   ""
7107   "addcc\t%1, %1, %0"
7108   [(set_attr "type" "compare")])
7110 (define_insn "ashrsi3"
7111   [(set (match_operand:SI 0 "register_operand" "=r")
7112         (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7113                      (match_operand:SI 2 "arith_operand" "rI")))]
7114   ""
7115   {
7116      if (GET_CODE (operands[2]) == CONST_INT)
7117        operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7118      return "sra\t%1, %2, %0";
7119   }
7120   [(set_attr "type" "shift")])
7122 (define_insn "*ashrsi3_extend"
7123   [(set (match_operand:DI 0 "register_operand" "=r")
7124         (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
7125                                      (match_operand:SI 2 "arith_operand" "r"))))]
7126   "TARGET_ARCH64"
7127   "sra\t%1, %2, %0"
7128   [(set_attr "type" "shift")])
7130 ;; This handles the case as above, but with constant shift instead of
7131 ;; register. Combiner "simplifies" it for us a little bit though.
7132 (define_insn "*ashrsi3_extend2"
7133   [(set (match_operand:DI 0 "register_operand" "=r")
7134         (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7135                                 (const_int 32))
7136                      (match_operand:SI 2 "small_int_or_double" "n")))]
7137   "TARGET_ARCH64
7138    && ((GET_CODE (operands[2]) == CONST_INT
7139         && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64)
7140        || (GET_CODE (operands[2]) == CONST_DOUBLE
7141            && !CONST_DOUBLE_HIGH (operands[2])
7142            && CONST_DOUBLE_LOW (operands[2]) >= 32
7143            && CONST_DOUBLE_LOW (operands[2]) < 64))"
7145   operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
7147   return "sra\t%1, %2, %0";
7149   [(set_attr "type" "shift")])
7151 (define_expand "ashrdi3"
7152   [(set (match_operand:DI 0 "register_operand" "=r")
7153         (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7154                      (match_operand:SI 2 "arith_operand" "rI")))]
7155   "TARGET_ARCH64 || TARGET_V8PLUS"
7157   if (! TARGET_ARCH64)
7158     {
7159       if (GET_CODE (operands[2]) == CONST_INT)
7160         FAIL;   /* prefer generic code in this case */
7161       emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
7162       DONE;
7163     }
7166 (define_insn "*ashrdi3_sp64"
7167   [(set (match_operand:DI 0 "register_operand" "=r")
7168         (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7169                      (match_operand:SI 2 "arith_operand" "rI")))]
7170   "TARGET_ARCH64"
7171   
7172   {
7173     if (GET_CODE (operands[2]) == CONST_INT)
7174       operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7175     return "srax\t%1, %2, %0";
7176   }
7177   [(set_attr "type" "shift")])
7179 ;; XXX
7180 (define_insn "ashrdi3_v8plus"
7181   [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7182         (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7183                      (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7184    (clobber (match_scratch:SI 3 "=X,X,&h"))]
7185   "TARGET_V8PLUS"
7186   "* return output_v8plus_shift (operands, insn, \"srax\");"
7187   [(set_attr "type" "multi")
7188    (set_attr "length" "5,5,6")])
7190 (define_insn "lshrsi3"
7191   [(set (match_operand:SI 0 "register_operand" "=r")
7192         (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
7193                      (match_operand:SI 2 "arith_operand" "rI")))]
7194   ""
7195   {
7196     if (GET_CODE (operands[2]) == CONST_INT)
7197       operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
7198     return "srl\t%1, %2, %0";
7199   }
7200   [(set_attr "type" "shift")])
7202 ;; This handles the case where
7203 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
7204 ;; but combiner "simplifies" it for us.
7205 (define_insn "*lshrsi3_extend"
7206   [(set (match_operand:DI 0 "register_operand" "=r")
7207         (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
7208                            (match_operand:SI 2 "arith_operand" "r")) 0)
7209                 (match_operand 3 "" "")))]
7210   "TARGET_ARCH64
7211    && ((GET_CODE (operands[3]) == CONST_DOUBLE
7212            && CONST_DOUBLE_HIGH (operands[3]) == 0
7213            && CONST_DOUBLE_LOW (operands[3]) == 0xffffffff)
7214        || (HOST_BITS_PER_WIDE_INT >= 64
7215            && GET_CODE (operands[3]) == CONST_INT
7216            && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff))"
7217   "srl\t%1, %2, %0"
7218   [(set_attr "type" "shift")])
7220 ;; This handles the case where
7221 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
7222 ;; but combiner "simplifies" it for us.
7223 (define_insn "*lshrsi3_extend2"
7224   [(set (match_operand:DI 0 "register_operand" "=r")
7225         (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
7226                          (match_operand 2 "small_int_or_double" "n")
7227                          (const_int 32)))]
7228   "TARGET_ARCH64
7229    && ((GET_CODE (operands[2]) == CONST_INT
7230         && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7231        || (GET_CODE (operands[2]) == CONST_DOUBLE
7232            && CONST_DOUBLE_HIGH (operands[2]) == 0
7233            && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7235   operands[2] = GEN_INT (32 - INTVAL (operands[2]));
7237   return "srl\t%1, %2, %0";
7239   [(set_attr "type" "shift")])
7241 (define_expand "lshrdi3"
7242   [(set (match_operand:DI 0 "register_operand" "=r")
7243         (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7244                      (match_operand:SI 2 "arith_operand" "rI")))]
7245   "TARGET_ARCH64 || TARGET_V8PLUS"
7247   if (! TARGET_ARCH64)
7248     {
7249       if (GET_CODE (operands[2]) == CONST_INT)
7250         FAIL;
7251       emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
7252       DONE;
7253     }
7256 (define_insn "*lshrdi3_sp64"
7257   [(set (match_operand:DI 0 "register_operand" "=r")
7258         (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7259                      (match_operand:SI 2 "arith_operand" "rI")))]
7260   "TARGET_ARCH64"
7261   {
7262     if (GET_CODE (operands[2]) == CONST_INT)
7263       operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
7264     return "srlx\t%1, %2, %0";
7265   }
7266   [(set_attr "type" "shift")])
7268 ;; XXX
7269 (define_insn "lshrdi3_v8plus"
7270   [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
7271         (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
7272                      (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
7273    (clobber (match_scratch:SI 3 "=X,X,&h"))]
7274   "TARGET_V8PLUS"
7275   "* return output_v8plus_shift (operands, insn, \"srlx\");"
7276   [(set_attr "type" "multi")
7277    (set_attr "length" "5,5,6")])
7279 (define_insn ""
7280   [(set (match_operand:SI 0 "register_operand" "=r")
7281         (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7282                                              (const_int 32)) 4)
7283                      (match_operand:SI 2 "small_int_or_double" "n")))]
7284   "TARGET_ARCH64
7285    && ((GET_CODE (operands[2]) == CONST_INT
7286         && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7287        || (GET_CODE (operands[2]) == CONST_DOUBLE
7288            && !CONST_DOUBLE_HIGH (operands[2])
7289            && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7291   operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
7293   return "srax\t%1, %2, %0";
7295   [(set_attr "type" "shift")])
7297 (define_insn ""
7298   [(set (match_operand:SI 0 "register_operand" "=r")
7299         (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7300                                              (const_int 32)) 4)
7301                      (match_operand:SI 2 "small_int_or_double" "n")))]
7302   "TARGET_ARCH64
7303    && ((GET_CODE (operands[2]) == CONST_INT
7304         && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32)
7305        || (GET_CODE (operands[2]) == CONST_DOUBLE
7306            && !CONST_DOUBLE_HIGH (operands[2])
7307            && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))"
7309   operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
7311   return "srlx\t%1, %2, %0";
7313   [(set_attr "type" "shift")])
7315 (define_insn ""
7316   [(set (match_operand:SI 0 "register_operand" "=r")
7317         (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
7318                                              (match_operand:SI 2 "small_int_or_double" "n")) 4)
7319                      (match_operand:SI 3 "small_int_or_double" "n")))]
7320   "TARGET_ARCH64
7321    && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
7322    && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
7323    && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
7324    && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
7326   operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
7328   return "srax\t%1, %2, %0";
7330   [(set_attr "type" "shift")])
7332 (define_insn ""
7333   [(set (match_operand:SI 0 "register_operand" "=r")
7334         (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
7335                                              (match_operand:SI 2 "small_int_or_double" "n")) 4)
7336                      (match_operand:SI 3 "small_int_or_double" "n")))]
7337   "TARGET_ARCH64
7338    && GET_CODE (operands[2]) == CONST_INT && GET_CODE (operands[3]) == CONST_INT
7339    && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
7340    && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
7341    && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
7343   operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
7345   return "srlx\t%1, %2, %0";
7347   [(set_attr "type" "shift")])
7349 ;; Unconditional and other jump instructions
7350 (define_insn "jump"
7351   [(set (pc) (label_ref (match_operand 0 "" "")))]
7352   ""
7353   "* return output_ubranch (operands[0], 0, insn);"
7354   [(set_attr "type" "uncond_branch")])
7356 (define_expand "tablejump"
7357   [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
7358               (use (label_ref (match_operand 1 "" "")))])]
7359   ""
7361   if (GET_MODE (operands[0]) != CASE_VECTOR_MODE)
7362     abort ();
7364   /* In pic mode, our address differences are against the base of the
7365      table.  Add that base value back in; CSE ought to be able to combine
7366      the two address loads.  */
7367   if (flag_pic)
7368     {
7369       rtx tmp, tmp2;
7370       tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
7371       tmp2 = operands[0];
7372       if (CASE_VECTOR_MODE != Pmode)
7373         tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
7374       tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
7375       operands[0] = memory_address (Pmode, tmp);
7376     }
7379 (define_insn "*tablejump_sp32"
7380   [(set (pc) (match_operand:SI 0 "address_operand" "p"))
7381    (use (label_ref (match_operand 1 "" "")))]
7382   "! TARGET_ARCH64"
7383   "jmp\t%a0%#"
7384   [(set_attr "type" "uncond_branch")])
7386 (define_insn "*tablejump_sp64"
7387   [(set (pc) (match_operand:DI 0 "address_operand" "p"))
7388    (use (label_ref (match_operand 1 "" "")))]
7389   "TARGET_ARCH64"
7390   "jmp\t%a0%#"
7391   [(set_attr "type" "uncond_branch")])
7393 ;;- jump to subroutine
7394 (define_expand "call"
7395   ;; Note that this expression is not used for generating RTL.
7396   ;; All the RTL is generated explicitly below.
7397   [(call (match_operand 0 "call_operand" "")
7398          (match_operand 3 "" "i"))]
7399   ;; operands[2] is next_arg_register
7400   ;; operands[3] is struct_value_size_rtx.
7401   ""
7403   rtx fn_rtx;
7405   if (GET_MODE (operands[0]) != FUNCTION_MODE)
7406     abort ();
7408   if (GET_CODE (operands[3]) != CONST_INT)
7409     abort();
7411   if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
7412     {
7413       /* This is really a PIC sequence.  We want to represent
7414          it as a funny jump so its delay slots can be filled. 
7416          ??? But if this really *is* a CALL, will not it clobber the
7417          call-clobbered registers?  We lose this if it is a JUMP_INSN.
7418          Why cannot we have delay slots filled if it were a CALL?  */
7420       /* We accept negative sizes for untyped calls.  */
7421       if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7422         emit_jump_insn
7423           (gen_rtx_PARALLEL
7424            (VOIDmode,
7425             gen_rtvec (3,
7426                        gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
7427                        operands[3],
7428                        gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7429       else
7430         emit_jump_insn
7431           (gen_rtx_PARALLEL
7432            (VOIDmode,
7433             gen_rtvec (2,
7434                        gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
7435                        gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7436       goto finish_call;
7437     }
7439   fn_rtx = operands[0];
7441   /* We accept negative sizes for untyped calls.  */
7442   if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
7443     emit_call_insn
7444       (gen_rtx_PARALLEL
7445        (VOIDmode,
7446         gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
7447                    operands[3],
7448                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7449   else
7450     emit_call_insn
7451       (gen_rtx_PARALLEL
7452        (VOIDmode,
7453         gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
7454                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
7456  finish_call:
7458   DONE;
7461 ;; We can't use the same pattern for these two insns, because then registers
7462 ;; in the address may not be properly reloaded.
7464 (define_insn "*call_address_sp32"
7465   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7466          (match_operand 1 "" ""))
7467    (clobber (reg:SI 15))]
7468   ;;- Do not use operand 1 for most machines.
7469   "! TARGET_ARCH64"
7470   "call\t%a0, %1%#"
7471   [(set_attr "type" "call")])
7473 (define_insn "*call_symbolic_sp32"
7474   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7475          (match_operand 1 "" ""))
7476    (clobber (reg:SI 15))]
7477   ;;- Do not use operand 1 for most machines.
7478   "! TARGET_ARCH64"
7479   "call\t%a0, %1%#"
7480   [(set_attr "type" "call")])
7482 (define_insn "*call_address_sp64"
7483   [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
7484          (match_operand 1 "" ""))
7485    (clobber (reg:DI 15))]
7486   ;;- Do not use operand 1 for most machines.
7487   "TARGET_ARCH64"
7488   "call\t%a0, %1%#"
7489   [(set_attr "type" "call")])
7491 (define_insn "*call_symbolic_sp64"
7492   [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
7493          (match_operand 1 "" ""))
7494    (clobber (reg:DI 15))]
7495   ;;- Do not use operand 1 for most machines.
7496   "TARGET_ARCH64"
7497   "call\t%a0, %1%#"
7498   [(set_attr "type" "call")])
7500 ;; This is a call that wants a structure value.
7501 ;; There is no such critter for v9 (??? we may need one anyway).
7502 (define_insn "*call_address_struct_value_sp32"
7503   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7504          (match_operand 1 "" ""))
7505    (match_operand 2 "immediate_operand" "")
7506    (clobber (reg:SI 15))]
7507   ;;- Do not use operand 1 for most machines.
7508   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
7510   operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
7511   return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
7513   [(set_attr "type" "call_no_delay_slot")
7514    (set_attr "length" "3")])
7516 ;; This is a call that wants a structure value.
7517 ;; There is no such critter for v9 (??? we may need one anyway).
7518 (define_insn "*call_symbolic_struct_value_sp32"
7519   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7520          (match_operand 1 "" ""))
7521    (match_operand 2 "immediate_operand" "")
7522    (clobber (reg:SI 15))]
7523   ;;- Do not use operand 1 for most machines.
7524   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
7526   operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
7527   return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
7529   [(set_attr "type" "call_no_delay_slot")
7530    (set_attr "length" "3")])
7532 ;; This is a call that may want a structure value.  This is used for
7533 ;; untyped_calls.
7534 (define_insn "*call_address_untyped_struct_value_sp32"
7535   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7536          (match_operand 1 "" ""))
7537    (match_operand 2 "immediate_operand" "")
7538    (clobber (reg:SI 15))]
7539   ;;- Do not use operand 1 for most machines.
7540   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7541   "call\t%a0, %1\n\t nop\n\tnop"
7542   [(set_attr "type" "call_no_delay_slot")
7543    (set_attr "length" "3")])
7545 ;; This is a call that may want a structure value.  This is used for
7546 ;; untyped_calls.
7547 (define_insn "*call_symbolic_untyped_struct_value_sp32"
7548   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7549          (match_operand 1 "" ""))
7550    (match_operand 2 "immediate_operand" "")
7551    (clobber (reg:SI 15))]
7552   ;;- Do not use operand 1 for most machines.
7553   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7554   "call\t%a0, %1\n\t nop\n\tnop"
7555   [(set_attr "type" "call_no_delay_slot")
7556    (set_attr "length" "3")])
7558 (define_expand "call_value"
7559   ;; Note that this expression is not used for generating RTL.
7560   ;; All the RTL is generated explicitly below.
7561   [(set (match_operand 0 "register_operand" "=rf")
7562         (call (match_operand 1 "" "")
7563               (match_operand 4 "" "")))]
7564   ;; operand 2 is stack_size_rtx
7565   ;; operand 3 is next_arg_register
7566   ""
7568   rtx fn_rtx;
7569   rtvec vec;
7571   if (GET_MODE (operands[1]) != FUNCTION_MODE)
7572     abort ();
7574   fn_rtx = operands[1];
7576   vec = gen_rtvec (2,
7577                    gen_rtx_SET (VOIDmode, operands[0],
7578                                 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
7579                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
7581   emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
7583   DONE;
7586 (define_insn "*call_value_address_sp32"
7587   [(set (match_operand 0 "" "=rf")
7588         (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
7589               (match_operand 2 "" "")))
7590    (clobber (reg:SI 15))]
7591   ;;- Do not use operand 2 for most machines.
7592   "! TARGET_ARCH64"
7593   "call\t%a1, %2%#"
7594   [(set_attr "type" "call")])
7596 (define_insn "*call_value_symbolic_sp32"
7597   [(set (match_operand 0 "" "=rf")
7598         (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7599               (match_operand 2 "" "")))
7600    (clobber (reg:SI 15))]
7601   ;;- Do not use operand 2 for most machines.
7602   "! TARGET_ARCH64"
7603   "call\t%a1, %2%#"
7604   [(set_attr "type" "call")])
7606 (define_insn "*call_value_address_sp64"
7607   [(set (match_operand 0 "" "")
7608         (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
7609               (match_operand 2 "" "")))
7610    (clobber (reg:DI 15))]
7611   ;;- Do not use operand 2 for most machines.
7612   "TARGET_ARCH64"
7613   "call\t%a1, %2%#"
7614   [(set_attr "type" "call")])
7616 (define_insn "*call_value_symbolic_sp64"
7617   [(set (match_operand 0 "" "")
7618         (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
7619               (match_operand 2 "" "")))
7620    (clobber (reg:DI 15))]
7621   ;;- Do not use operand 2 for most machines.
7622   "TARGET_ARCH64"
7623   "call\t%a1, %2%#"
7624   [(set_attr "type" "call")])
7626 (define_expand "untyped_call"
7627   [(parallel [(call (match_operand 0 "" "")
7628                     (const_int 0))
7629               (match_operand 1 "" "")
7630               (match_operand 2 "" "")])]
7631   ""
7633   int i;
7635   /* Pass constm1 to indicate that it may expect a structure value, but
7636      we don't know what size it is.  */
7637   emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
7639   for (i = 0; i < XVECLEN (operands[2], 0); i++)
7640     {
7641       rtx set = XVECEXP (operands[2], 0, i);
7642       emit_move_insn (SET_DEST (set), SET_SRC (set));
7643     }
7645   /* The optimizer does not know that the call sets the function value
7646      registers we stored in the result block.  We avoid problems by
7647      claiming that all hard registers are used and clobbered at this
7648      point.  */
7649   emit_insn (gen_blockage ());
7651   DONE;
7654 ;;- tail calls
7655 (define_expand "sibcall"
7656   [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
7657               (return)])]
7658   ""
7659   "")
7661 (define_insn "*sibcall_symbolic_sp32"
7662   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7663          (match_operand 1 "" ""))
7664    (return)]
7665   "! TARGET_ARCH64"
7666   "* return output_sibcall(insn, operands[0]);"
7667   [(set_attr "type" "sibcall")])
7669 (define_insn "*sibcall_symbolic_sp64"
7670   [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
7671          (match_operand 1 "" ""))
7672    (return)]
7673   "TARGET_ARCH64"
7674   "* return output_sibcall(insn, operands[0]);"
7675   [(set_attr "type" "sibcall")])
7677 (define_expand "sibcall_value"
7678   [(parallel [(set (match_operand 0 "register_operand" "=rf")
7679                 (call (match_operand 1 "" "") (const_int 0)))
7680               (return)])]
7681   ""
7682   "")
7684 (define_insn "*sibcall_value_symbolic_sp32"
7685   [(set (match_operand 0 "" "=rf")
7686         (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7687               (match_operand 2 "" "")))
7688    (return)]
7689   "! TARGET_ARCH64"
7690   "* return output_sibcall(insn, operands[1]);"
7691   [(set_attr "type" "sibcall")])
7693 (define_insn "*sibcall_value_symbolic_sp64"
7694   [(set (match_operand 0 "" "")
7695         (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
7696               (match_operand 2 "" "")))
7697    (return)]
7698   "TARGET_ARCH64"
7699   "* return output_sibcall(insn, operands[1]);"
7700   [(set_attr "type" "sibcall")])
7702 (define_expand "sibcall_epilogue"
7703   [(return)]
7704   ""
7706   sparc_expand_epilogue ();
7707   DONE;
7710 (define_expand "prologue"
7711   [(const_int 0)]
7712   ""
7714   sparc_expand_prologue ();
7715   DONE;
7718 ;; The "save register window" insn is modelled as follows so that the DWARF-2
7719 ;; backend automatically emits the required call frame debugging information
7720 ;; while it is parsing it.  Therefore, the pattern should not be modified
7721 ;; without first studying the impact of the changes on the debug info.
7722 ;; [(set (%fp) (%sp))
7723 ;;  (set (%sp) (unspec_volatile [(%sp) (-frame_size)] UNSPECV_SAVEW))
7724 ;;  (set (%i7) (%o7))]
7726 (define_insn "save_register_window<P:mode>"
7727   [(set (reg:P 30) (reg:P 14))
7728    (set (reg:P 14) (unspec_volatile:P [(reg:P 14)
7729                                        (match_operand:P 0 "arith_operand" "rI")] UNSPECV_SAVEW))
7730    (set (reg:P 31) (reg:P 15))]
7731   ""
7732   "save\t%%sp, %0, %%sp"
7733   [(set_attr "type" "savew")])
7735 (define_expand "epilogue"
7736   [(return)]
7737   ""
7739   sparc_expand_epilogue ();
7742 (define_expand "return"
7743   [(return)]
7744   "sparc_can_use_return_insn_p ()"
7745   "")
7747 (define_insn "*return_internal"
7748   [(return)]
7749   ""
7750   "* return output_return (insn);"
7751   [(set_attr "type" "return")
7752    (set (attr "length")
7753         (cond [(eq_attr "leaf_function" "true")
7754                  (if_then_else (eq_attr "empty_delay_slot" "true")
7755                                (const_int 2)
7756                                (const_int 1))
7757                (eq_attr "calls_eh_return" "true")
7758                  (if_then_else (eq_attr "delayed_branch" "true")
7759                                (if_then_else (eq_attr "isa" "v9")
7760                                              (const_int 2)
7761                                              (const_int 3))
7762                                (if_then_else (eq_attr "isa" "v9")
7763                                              (const_int 3)
7764                                              (const_int 4)))
7765                (eq_attr "empty_delay_slot" "true")
7766                  (if_then_else (eq_attr "delayed_branch" "true")
7767                                (const_int 2)
7768                                (const_int 3))
7769               ] (const_int 1)))])
7771 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
7772 ;; all of memory.  This blocks insns from being moved across this point.
7774 (define_insn "blockage"
7775   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7776   ""
7777   ""
7778   [(set_attr "length" "0")])
7780 ;; Prepare to return any type including a structure value.
7782 (define_expand "untyped_return"
7783   [(match_operand:BLK 0 "memory_operand" "")
7784    (match_operand 1 "" "")]
7785   ""
7787   rtx valreg1 = gen_rtx_REG (DImode, 24);
7788   rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
7789   rtx result = operands[0];
7791   if (! TARGET_ARCH64)
7792     {
7793       rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
7794                                          ? 15 : 31));
7795       rtx value = gen_reg_rtx (SImode);
7797       /* Fetch the instruction where we will return to and see if it's an unimp
7798          instruction (the most significant 10 bits will be zero).  If so,
7799          update the return address to skip the unimp instruction.  */
7800       emit_move_insn (value,
7801                       gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
7802       emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
7803       emit_insn (gen_update_return (rtnreg, value));
7804     }
7806   /* Reload the function value registers.  */
7807   emit_move_insn (valreg1, adjust_address (result, DImode, 0));
7808   emit_move_insn (valreg2,
7809                   adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
7811   /* Put USE insns before the return.  */
7812   emit_insn (gen_rtx_USE (VOIDmode, valreg1));
7813   emit_insn (gen_rtx_USE (VOIDmode, valreg2));
7815   /* Construct the return.  */
7816   expand_naked_return ();
7818   DONE;
7821 ;; This is a bit of a hack.  We're incrementing a fixed register (%i7),
7822 ;; and parts of the compiler don't want to believe that the add is needed.
7824 (define_insn "update_return"
7825   [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
7826                (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
7827   "! TARGET_ARCH64"
7829   if (flag_delayed_branch)
7830     return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
7831   else
7832     return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
7834   [(set (attr "type") (const_string "multi"))
7835    (set (attr "length")
7836         (if_then_else (eq_attr "delayed_branch" "true")
7837                       (const_int 3)
7838                       (const_int 4)))])
7840 (define_insn "nop"
7841   [(const_int 0)]
7842   ""
7843   "nop")
7845 (define_expand "indirect_jump"
7846   [(set (pc) (match_operand 0 "address_operand" "p"))]
7847   ""
7848   "")
7850 (define_insn "*branch_sp32"
7851   [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
7852   "! TARGET_ARCH64"
7853  "jmp\t%a0%#"
7854  [(set_attr "type" "uncond_branch")])
7856 (define_insn "*branch_sp64"
7857   [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
7858   "TARGET_ARCH64"
7859   "jmp\t%a0%#"
7860   [(set_attr "type" "uncond_branch")])
7862 (define_expand "nonlocal_goto"
7863   [(match_operand:SI 0 "general_operand" "")
7864    (match_operand:SI 1 "general_operand" "")
7865    (match_operand:SI 2 "general_operand" "")
7866    (match_operand:SI 3 "" "")]
7867   ""
7869   rtx lab = operands[1];
7870   rtx stack = operands[2];
7871   rtx fp = operands[3];
7872   rtx labreg;
7874   /* Trap instruction to flush all the register windows.  */
7875   emit_insn (gen_flush_register_windows ());
7877   /* Load the fp value for the containing fn into %fp.  This is needed
7878      because STACK refers to %fp.  Note that virtual register instantiation
7879      fails if the virtual %fp isn't set from a register.  */
7880   if (GET_CODE (fp) != REG)
7881     fp = force_reg (Pmode, fp);
7882   emit_move_insn (virtual_stack_vars_rtx, fp);
7884   /* Find the containing function's current nonlocal goto handler,
7885      which will do any cleanups and then jump to the label.  */
7886   labreg = gen_rtx_REG (Pmode, 8);
7887   emit_move_insn (labreg, lab);
7889   /* Restore %fp from stack pointer value for containing function.
7890      The restore insn that follows will move this to %sp,
7891      and reload the appropriate value into %fp.  */
7892   emit_move_insn (hard_frame_pointer_rtx, stack);
7894   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
7895   emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
7897   /* ??? The V9-specific version was disabled in rev 1.65.  */
7898   emit_jump_insn (gen_goto_handler_and_restore (labreg));
7899   emit_barrier ();
7900   DONE;
7903 ;; Special trap insn to flush register windows.
7904 (define_insn "flush_register_windows"
7905   [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
7906   ""
7907   { return TARGET_V9 ? "flushw" : "ta\t3"; }
7908   [(set_attr "type" "flushw")])
7910 (define_insn "goto_handler_and_restore"
7911   [(unspec_volatile [(match_operand 0 "register_operand" "=r")] UNSPECV_GOTO)]
7912   "GET_MODE (operands[0]) == Pmode"
7914   if (flag_delayed_branch)
7915     return "jmp\t%0\n\t restore";
7916   else
7917     return "mov\t%0,%%g1\n\trestore\n\tjmp\t%%g1\n\t nop";
7919   [(set (attr "type") (const_string "multi"))
7920    (set (attr "length")
7921         (if_then_else (eq_attr "delayed_branch" "true")
7922                       (const_int 2)
7923                       (const_int 4)))])
7925 ;; For __builtin_setjmp we need to flush register windows iff the function
7926 ;; calls alloca as well, because otherwise the register window might be
7927 ;; saved after %sp adjustment and thus setjmp would crash
7928 (define_expand "builtin_setjmp_setup"
7929   [(match_operand 0 "register_operand" "r")]
7930   ""
7932   emit_insn (gen_do_builtin_setjmp_setup ());
7933   DONE;
7936 (define_insn "do_builtin_setjmp_setup"
7937   [(unspec_volatile [(const_int 0)] UNSPECV_SETJMP)]
7938   ""
7940   if (! current_function_calls_alloca)
7941     return "";
7942   if (! TARGET_V9)
7943     return "\tta\t3\n";
7944   fputs ("\tflushw\n", asm_out_file);
7945   if (flag_pic)
7946     fprintf (asm_out_file, "\tst%c\t%%l7, [%%sp+%d]\n",
7947              TARGET_ARCH64 ? 'x' : 'w',
7948              SPARC_STACK_BIAS + 7 * UNITS_PER_WORD);
7949   fprintf (asm_out_file, "\tst%c\t%%fp, [%%sp+%d]\n",
7950            TARGET_ARCH64 ? 'x' : 'w',
7951            SPARC_STACK_BIAS + 14 * UNITS_PER_WORD);
7952   fprintf (asm_out_file, "\tst%c\t%%i7, [%%sp+%d]\n",
7953            TARGET_ARCH64 ? 'x' : 'w',
7954            SPARC_STACK_BIAS + 15 * UNITS_PER_WORD);
7955   return "";
7957   [(set_attr "type" "multi")
7958    (set (attr "length")
7959         (cond [(eq_attr "calls_alloca" "false")
7960                  (const_int 0)
7961                (eq_attr "isa" "!v9")
7962                  (const_int 1)
7963                (eq_attr "pic" "true")
7964                  (const_int 4)] (const_int 3)))])
7966 ;; Pattern for use after a setjmp to store FP and the return register
7967 ;; into the stack area.
7969 (define_expand "setjmp"
7970   [(const_int 0)]
7971   ""
7973   if (TARGET_ARCH64)
7974     emit_insn (gen_setjmp_64 ());
7975   else
7976     emit_insn (gen_setjmp_32 ());
7977   DONE;
7980 (define_expand "setjmp_32"
7981   [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
7982    (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
7983   ""
7984   { operands[0] = frame_pointer_rtx; })
7986 (define_expand "setjmp_64"
7987   [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
7988    (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
7989   ""
7990   { operands[0] = frame_pointer_rtx; })
7992 ;; Special pattern for the FLUSH instruction.
7994 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
7995 ; of the define_insn otherwise missing a mode.  We make "flush", aka
7996 ; gen_flush, the default one since sparc_initialize_trampoline uses
7997 ; it on SImode mem values.
7999 (define_insn "flush"
8000   [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
8001   ""
8002   { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
8003   [(set_attr "type" "iflush")])
8005 (define_insn "flushdi"
8006   [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
8007   ""
8008   { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
8009   [(set_attr "type" "iflush")])
8012 ;; find first set.
8014 ;; The scan instruction searches from the most significant bit while ffs
8015 ;; searches from the least significant bit.  The bit index and treatment of
8016 ;; zero also differ.  It takes at least 7 instructions to get the proper
8017 ;; result.  Here is an obvious 8 instruction sequence.
8019 ;; XXX
8020 (define_insn "ffssi2"
8021   [(set (match_operand:SI 0 "register_operand" "=&r")
8022         (ffs:SI (match_operand:SI 1 "register_operand" "r")))
8023    (clobber (match_scratch:SI 2 "=&r"))]
8024   "TARGET_SPARCLITE || TARGET_SPARCLET"
8026   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";
8028   [(set_attr "type" "multi")
8029    (set_attr "length" "8")])
8031 ;; ??? This should be a define expand, so that the extra instruction have
8032 ;; a chance of being optimized away.
8034 ;; Disabled because none of the UltraSPARCs implement popc.  The HAL R1
8035 ;; does, but no one uses that and we don't have a switch for it.
8037 ;(define_insn "ffsdi2"
8038 ;  [(set (match_operand:DI 0 "register_operand" "=&r")
8039 ;       (ffs:DI (match_operand:DI 1 "register_operand" "r")))
8040 ;   (clobber (match_scratch:DI 2 "=&r"))]
8041 ;  "TARGET_ARCH64"
8042 ;  "neg\t%1, %2\;xnor\t%1, %2, %2\;popc\t%2, %0\;movzr\t%1, 0, %0"
8043 ;  [(set_attr "type" "multi")
8044 ;   (set_attr "length" "4")])
8048 ;; Peepholes go at the end.
8050 ;; Optimize consecutive loads or stores into ldd and std when possible.
8051 ;; The conditions in which we do this are very restricted and are 
8052 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
8054 (define_peephole2
8055   [(set (match_operand:SI 0 "memory_operand" "")
8056       (const_int 0))
8057    (set (match_operand:SI 1 "memory_operand" "")
8058       (const_int 0))]
8059   "TARGET_V9
8060    && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
8061   [(set (match_dup 0)
8062        (const_int 0))]
8063   "operands[0] = widen_memory_access (operands[0], DImode, 0);")
8065 (define_peephole2
8066   [(set (match_operand:SI 0 "memory_operand" "")
8067       (const_int 0))
8068    (set (match_operand:SI 1 "memory_operand" "")
8069       (const_int 0))]
8070   "TARGET_V9
8071    && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
8072   [(set (match_dup 1)
8073        (const_int 0))]
8074   "operands[1] = widen_memory_access (operands[1], DImode, 0);")
8076 (define_peephole2
8077   [(set (match_operand:SI 0 "register_operand" "")
8078         (match_operand:SI 1 "memory_operand" ""))
8079    (set (match_operand:SI 2 "register_operand" "")
8080         (match_operand:SI 3 "memory_operand" ""))]
8081   "registers_ok_for_ldd_peep (operands[0], operands[2]) 
8082    && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])" 
8083   [(set (match_dup 0)
8084         (match_dup 1))]
8085   "operands[1] = widen_memory_access (operands[1], DImode, 0);
8086    operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
8088 (define_peephole2
8089   [(set (match_operand:SI 0 "memory_operand" "")
8090         (match_operand:SI 1 "register_operand" ""))
8091    (set (match_operand:SI 2 "memory_operand" "")
8092         (match_operand:SI 3 "register_operand" ""))]
8093   "registers_ok_for_ldd_peep (operands[1], operands[3]) 
8094    && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
8095   [(set (match_dup 0)
8096         (match_dup 1))]
8097   "operands[0] = widen_memory_access (operands[0], DImode, 0);
8098    operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
8100 (define_peephole2
8101   [(set (match_operand:SF 0 "register_operand" "")
8102         (match_operand:SF 1 "memory_operand" ""))
8103    (set (match_operand:SF 2 "register_operand" "")
8104         (match_operand:SF 3 "memory_operand" ""))]
8105   "registers_ok_for_ldd_peep (operands[0], operands[2]) 
8106    && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
8107   [(set (match_dup 0)
8108         (match_dup 1))]
8109   "operands[1] = widen_memory_access (operands[1], DFmode, 0);
8110    operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
8112 (define_peephole2
8113   [(set (match_operand:SF 0 "memory_operand" "")
8114         (match_operand:SF 1 "register_operand" ""))
8115    (set (match_operand:SF 2 "memory_operand" "")
8116         (match_operand:SF 3 "register_operand" ""))]
8117   "registers_ok_for_ldd_peep (operands[1], operands[3]) 
8118   && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
8119   [(set (match_dup 0)
8120         (match_dup 1))]
8121   "operands[0] = widen_memory_access (operands[0], DFmode, 0);
8122    operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
8124 (define_peephole2
8125   [(set (match_operand:SI 0 "register_operand" "")
8126         (match_operand:SI 1 "memory_operand" ""))
8127    (set (match_operand:SI 2 "register_operand" "")
8128         (match_operand:SI 3 "memory_operand" ""))]
8129   "registers_ok_for_ldd_peep (operands[2], operands[0]) 
8130   && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
8131   [(set (match_dup 2)
8132         (match_dup 3))]
8133    "operands[3] = widen_memory_access (operands[3], DImode, 0);
8134     operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
8136 (define_peephole2
8137   [(set (match_operand:SI 0 "memory_operand" "")
8138         (match_operand:SI 1 "register_operand" ""))
8139    (set (match_operand:SI 2 "memory_operand" "")
8140         (match_operand:SI 3 "register_operand" ""))]
8141   "registers_ok_for_ldd_peep (operands[3], operands[1]) 
8142   && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)" 
8143   [(set (match_dup 2)
8144         (match_dup 3))]
8145   "operands[2] = widen_memory_access (operands[2], DImode, 0);
8146    operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
8147    ")
8149 (define_peephole2
8150   [(set (match_operand:SF 0 "register_operand" "")
8151         (match_operand:SF 1 "memory_operand" ""))
8152    (set (match_operand:SF 2 "register_operand" "")
8153         (match_operand:SF 3 "memory_operand" ""))]
8154   "registers_ok_for_ldd_peep (operands[2], operands[0]) 
8155   && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
8156   [(set (match_dup 2)
8157         (match_dup 3))]
8158   "operands[3] = widen_memory_access (operands[3], DFmode, 0);
8159    operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
8161 (define_peephole2
8162   [(set (match_operand:SF 0 "memory_operand" "")
8163         (match_operand:SF 1 "register_operand" ""))
8164    (set (match_operand:SF 2 "memory_operand" "")
8165         (match_operand:SF 3 "register_operand" ""))]
8166   "registers_ok_for_ldd_peep (operands[3], operands[1]) 
8167   && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
8168   [(set (match_dup 2)
8169         (match_dup 3))]
8170   "operands[2] = widen_memory_access (operands[2], DFmode, 0);
8171    operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
8173 ;; Optimize the case of following a reg-reg move with a test
8174 ;; of reg just moved.  Don't allow floating point regs for operand 0 or 1.
8175 ;; This can result from a float to fix conversion.
8177 (define_peephole2
8178   [(set (match_operand:SI 0 "register_operand" "")
8179         (match_operand:SI 1 "register_operand" ""))
8180    (set (reg:CC 100)
8181         (compare:CC (match_operand:SI 2 "register_operand" "")
8182                     (const_int 0)))]
8183   "(rtx_equal_p (operands[2], operands[0])
8184     || rtx_equal_p (operands[2], operands[1]))
8185     && ! SPARC_FP_REG_P (REGNO (operands[0]))
8186     && ! SPARC_FP_REG_P (REGNO (operands[1]))"
8187   [(parallel [(set (match_dup 0) (match_dup 1))
8188               (set (reg:CC 100)
8189                    (compare:CC (match_dup 1) (const_int 0)))])]
8190   "")
8192 (define_peephole2
8193   [(set (match_operand:DI 0 "register_operand" "")
8194         (match_operand:DI 1 "register_operand" ""))
8195    (set (reg:CCX 100)
8196         (compare:CCX (match_operand:DI 2 "register_operand" "")
8197                     (const_int 0)))]
8198   "TARGET_ARCH64
8199    && (rtx_equal_p (operands[2], operands[0])
8200        || rtx_equal_p (operands[2], operands[1]))
8201    && ! SPARC_FP_REG_P (REGNO (operands[0]))
8202    && ! SPARC_FP_REG_P (REGNO (operands[1]))"
8203   [(parallel [(set (match_dup 0) (match_dup 1))
8204               (set (reg:CCX 100)
8205                    (compare:CCX (match_dup 1) (const_int 0)))])]
8206   "")
8208 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
8209 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
8210 ;; ??? operations.  With DFA we might be able to model this, but it requires a lot of
8211 ;; ??? state.
8212 (define_expand "prefetch"
8213   [(match_operand 0 "address_operand" "")
8214    (match_operand 1 "const_int_operand" "")
8215    (match_operand 2 "const_int_operand" "")]
8216   "TARGET_V9"
8218   if (TARGET_ARCH64)
8219     emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
8220   else
8221     emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
8222   DONE;
8225 (define_insn "prefetch_64"
8226   [(prefetch (match_operand:DI 0 "address_operand" "p")
8227              (match_operand:DI 1 "const_int_operand" "n")
8228              (match_operand:DI 2 "const_int_operand" "n"))]
8229   ""
8231   static const char * const prefetch_instr[2][2] = {
8232     {
8233       "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
8234       "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
8235     },
8236     {
8237       "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
8238       "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
8239     }
8240   };
8241   int read_or_write = INTVAL (operands[1]);
8242   int locality = INTVAL (operands[2]);
8244   if (read_or_write != 0 && read_or_write != 1)
8245     abort ();
8246   if (locality < 0 || locality > 3)
8247     abort ();
8248   return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
8250   [(set_attr "type" "load")])
8252 (define_insn "prefetch_32"
8253   [(prefetch (match_operand:SI 0 "address_operand" "p")
8254              (match_operand:SI 1 "const_int_operand" "n")
8255              (match_operand:SI 2 "const_int_operand" "n"))]
8256   ""
8258   static const char * const prefetch_instr[2][2] = {
8259     {
8260       "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
8261       "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
8262     },
8263     {
8264       "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
8265       "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
8266     }
8267   };
8268   int read_or_write = INTVAL (operands[1]);
8269   int locality = INTVAL (operands[2]);
8271   if (read_or_write != 0 && read_or_write != 1)
8272     abort ();
8273   if (locality < 0 || locality > 3)
8274     abort ();
8275   return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
8277   [(set_attr "type" "load")])
8279 (define_insn "trap"
8280   [(trap_if (const_int 1) (const_int 5))]
8281   ""
8282   "ta\t5"
8283   [(set_attr "type" "trap")])
8285 (define_expand "conditional_trap"
8286   [(trap_if (match_operator 0 "noov_compare_op" [(match_dup 2) (match_dup 3)])
8287             (match_operand:SI 1 "arith_operand" ""))]
8288   ""
8289   "operands[2] = gen_compare_reg (GET_CODE (operands[0]),
8290                                   sparc_compare_op0, sparc_compare_op1);
8291    if (GET_MODE (operands[2]) != CCmode && GET_MODE (operands[2]) != CCXmode)
8292      FAIL;
8293    operands[3] = const0_rtx;")
8295 (define_insn ""
8296   [(trap_if (match_operator 0 "noov_compare_op" [(reg:CC 100) (const_int 0)])
8297             (match_operand:SI 1 "arith_operand" "rM"))]
8298   ""
8300   if (TARGET_V9)
8301     return "t%C0\t%%icc, %1";
8302   else
8303     return "t%C0\t%1";
8305   [(set_attr "type" "trap")])
8307 (define_insn ""
8308   [(trap_if (match_operator 0 "noov_compare_op" [(reg:CCX 100) (const_int 0)])
8309             (match_operand:SI 1 "arith_operand" "rM"))]
8310   "TARGET_V9"
8311   "t%C0\t%%xcc, %1"
8312   [(set_attr "type" "trap")])
8314 ;; TLS support
8315 (define_insn "tgd_hi22"
8316   [(set (match_operand:SI 0 "register_operand" "=r")
8317         (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
8318                             UNSPEC_TLSGD)))]
8319   "TARGET_TLS"
8320   "sethi\\t%%tgd_hi22(%a1), %0")
8322 (define_insn "tgd_lo10"
8323   [(set (match_operand:SI 0 "register_operand" "=r")
8324         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8325                    (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
8326                               UNSPEC_TLSGD)))]
8327   "TARGET_TLS"
8328   "add\\t%1, %%tgd_lo10(%a2), %0")
8330 (define_insn "tgd_add32"
8331   [(set (match_operand:SI 0 "register_operand" "=r")
8332         (plus:SI (match_operand:SI 1 "register_operand" "r")
8333                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8334                              (match_operand 3 "tgd_symbolic_operand" "")]
8335                             UNSPEC_TLSGD)))]
8336   "TARGET_TLS && TARGET_ARCH32"
8337   "add\\t%1, %2, %0, %%tgd_add(%a3)")
8339 (define_insn "tgd_add64"
8340   [(set (match_operand:DI 0 "register_operand" "=r")
8341         (plus:DI (match_operand:DI 1 "register_operand" "r")
8342                  (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8343                              (match_operand 3 "tgd_symbolic_operand" "")]
8344                             UNSPEC_TLSGD)))]
8345   "TARGET_TLS && TARGET_ARCH64"
8346   "add\\t%1, %2, %0, %%tgd_add(%a3)")
8348 (define_insn "tgd_call32"
8349   [(set (match_operand 0 "register_operand" "=r")
8350         (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
8351                                   (match_operand 2 "tgd_symbolic_operand" "")]
8352                                  UNSPEC_TLSGD))
8353               (match_operand 3 "" "")))
8354    (clobber (reg:SI 15))]
8355   "TARGET_TLS && TARGET_ARCH32"
8356   "call\t%a1, %%tgd_call(%a2)%#"
8357   [(set_attr "type" "call")])
8359 (define_insn "tgd_call64"
8360   [(set (match_operand 0 "register_operand" "=r")
8361         (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
8362                                   (match_operand 2 "tgd_symbolic_operand" "")]
8363                                  UNSPEC_TLSGD))
8364               (match_operand 3 "" "")))
8365    (clobber (reg:DI 15))]
8366   "TARGET_TLS && TARGET_ARCH64"
8367   "call\t%a1, %%tgd_call(%a2)%#"
8368   [(set_attr "type" "call")])
8370 (define_insn "tldm_hi22"
8371   [(set (match_operand:SI 0 "register_operand" "=r")
8372         (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
8373   "TARGET_TLS"
8374   "sethi\\t%%tldm_hi22(%&), %0")
8376 (define_insn "tldm_lo10"
8377   [(set (match_operand:SI 0 "register_operand" "=r")
8378         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8379                     (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
8380   "TARGET_TLS"
8381   "add\\t%1, %%tldm_lo10(%&), %0")
8383 (define_insn "tldm_add32"
8384   [(set (match_operand:SI 0 "register_operand" "=r")
8385         (plus:SI (match_operand:SI 1 "register_operand" "r")
8386                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
8387                             UNSPEC_TLSLDM)))]
8388   "TARGET_TLS && TARGET_ARCH32"
8389   "add\\t%1, %2, %0, %%tldm_add(%&)")
8391 (define_insn "tldm_add64"
8392   [(set (match_operand:DI 0 "register_operand" "=r")
8393         (plus:DI (match_operand:DI 1 "register_operand" "r")
8394                  (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
8395                             UNSPEC_TLSLDM)))]
8396   "TARGET_TLS && TARGET_ARCH64"
8397   "add\\t%1, %2, %0, %%tldm_add(%&)")
8399 (define_insn "tldm_call32"
8400   [(set (match_operand 0 "register_operand" "=r")
8401         (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
8402                                  UNSPEC_TLSLDM))
8403               (match_operand 2 "" "")))
8404    (clobber (reg:SI 15))]
8405   "TARGET_TLS && TARGET_ARCH32"
8406   "call\t%a1, %%tldm_call(%&)%#"
8407   [(set_attr "type" "call")])
8409 (define_insn "tldm_call64"
8410   [(set (match_operand 0 "register_operand" "=r")
8411         (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
8412                                  UNSPEC_TLSLDM))
8413               (match_operand 2 "" "")))
8414    (clobber (reg:DI 15))]
8415   "TARGET_TLS && TARGET_ARCH64"
8416   "call\t%a1, %%tldm_call(%&)%#"
8417   [(set_attr "type" "call")])
8419 (define_insn "tldo_hix22"
8420   [(set (match_operand:SI 0 "register_operand" "=r")
8421         (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
8422                             UNSPEC_TLSLDO)))]
8423   "TARGET_TLS"
8424   "sethi\\t%%tldo_hix22(%a1), %0")
8426 (define_insn "tldo_lox10"
8427   [(set (match_operand:SI 0 "register_operand" "=r")
8428         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8429                    (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
8430                               UNSPEC_TLSLDO)))]
8431   "TARGET_TLS"
8432   "xor\\t%1, %%tldo_lox10(%a2), %0")
8434 (define_insn "tldo_add32"
8435   [(set (match_operand:SI 0 "register_operand" "=r")
8436         (plus:SI (match_operand:SI 1 "register_operand" "r")
8437                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8438                              (match_operand 3 "tld_symbolic_operand" "")]
8439                             UNSPEC_TLSLDO)))]
8440   "TARGET_TLS && TARGET_ARCH32"
8441   "add\\t%1, %2, %0, %%tldo_add(%a3)")
8443 (define_insn "tldo_add64"
8444   [(set (match_operand:DI 0 "register_operand" "=r")
8445         (plus:DI (match_operand:DI 1 "register_operand" "r")
8446                  (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8447                              (match_operand 3 "tld_symbolic_operand" "")]
8448                             UNSPEC_TLSLDO)))]
8449   "TARGET_TLS && TARGET_ARCH64"
8450   "add\\t%1, %2, %0, %%tldo_add(%a3)")
8452 (define_insn "tie_hi22"
8453   [(set (match_operand:SI 0 "register_operand" "=r")
8454         (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
8455                             UNSPEC_TLSIE)))]
8456   "TARGET_TLS"
8457   "sethi\\t%%tie_hi22(%a1), %0")
8459 (define_insn "tie_lo10"
8460   [(set (match_operand:SI 0 "register_operand" "=r")
8461         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8462                    (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
8463                               UNSPEC_TLSIE)))]
8464   "TARGET_TLS"
8465   "add\\t%1, %%tie_lo10(%a2), %0")
8467 (define_insn "tie_ld32"
8468   [(set (match_operand:SI 0 "register_operand" "=r")
8469         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
8470                     (match_operand:SI 2 "register_operand" "r")
8471                     (match_operand 3 "tie_symbolic_operand" "")]
8472                    UNSPEC_TLSIE))]
8473   "TARGET_TLS && TARGET_ARCH32"
8474   "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
8475   [(set_attr "type" "load")])
8477 (define_insn "tie_ld64"
8478   [(set (match_operand:DI 0 "register_operand" "=r")
8479         (unspec:DI [(match_operand:DI 1 "register_operand" "r")
8480                     (match_operand:SI 2 "register_operand" "r")
8481                     (match_operand 3 "tie_symbolic_operand" "")]
8482                    UNSPEC_TLSIE))]
8483   "TARGET_TLS && TARGET_ARCH64"
8484   "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
8485   [(set_attr "type" "load")])
8487 (define_insn "tie_add32"
8488   [(set (match_operand:SI 0 "register_operand" "=r")
8489         (plus:SI (match_operand:SI 1 "register_operand" "r")
8490                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8491                              (match_operand 3 "tie_symbolic_operand" "")]
8492                             UNSPEC_TLSIE)))]
8493   "TARGET_SUN_TLS && TARGET_ARCH32"
8494   "add\\t%1, %2, %0, %%tie_add(%a3)")
8496 (define_insn "tie_add64"
8497   [(set (match_operand:DI 0 "register_operand" "=r")
8498         (plus:DI (match_operand:DI 1 "register_operand" "r")
8499                  (unspec:DI [(match_operand:DI 2 "register_operand" "r")
8500                              (match_operand 3 "tie_symbolic_operand" "")]
8501                             UNSPEC_TLSIE)))]
8502   "TARGET_SUN_TLS && TARGET_ARCH64"
8503   "add\\t%1, %2, %0, %%tie_add(%a3)")
8505 (define_insn "tle_hix22_sp32"
8506   [(set (match_operand:SI 0 "register_operand" "=r")
8507         (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
8508                             UNSPEC_TLSLE)))]
8509   "TARGET_TLS && TARGET_ARCH32"
8510   "sethi\\t%%tle_hix22(%a1), %0")
8512 (define_insn "tle_lox10_sp32"
8513   [(set (match_operand:SI 0 "register_operand" "=r")
8514         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8515                    (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
8516                               UNSPEC_TLSLE)))]
8517   "TARGET_TLS && TARGET_ARCH32"
8518   "xor\\t%1, %%tle_lox10(%a2), %0")
8520 (define_insn "tle_hix22_sp64"
8521   [(set (match_operand:DI 0 "register_operand" "=r")
8522         (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
8523                             UNSPEC_TLSLE)))]
8524   "TARGET_TLS && TARGET_ARCH64"
8525   "sethi\\t%%tle_hix22(%a1), %0")
8527 (define_insn "tle_lox10_sp64"
8528   [(set (match_operand:DI 0 "register_operand" "=r")
8529         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
8530                    (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
8531                               UNSPEC_TLSLE)))]
8532   "TARGET_TLS && TARGET_ARCH64"
8533   "xor\\t%1, %%tle_lox10(%a2), %0")
8535 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
8536 (define_insn "*tldo_ldub_sp32"
8537   [(set (match_operand:QI 0 "register_operand" "=r")
8538         (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8539                                      (match_operand 3 "tld_symbolic_operand" "")]
8540                                     UNSPEC_TLSLDO)
8541                          (match_operand:SI 1 "register_operand" "r"))))]
8542   "TARGET_TLS && TARGET_ARCH32"
8543   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8544   [(set_attr "type" "load")
8545    (set_attr "us3load_type" "3cycle")])
8547 (define_insn "*tldo_ldub1_sp32"
8548   [(set (match_operand:HI 0 "register_operand" "=r")
8549         (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8550                                                      (match_operand 3 "tld_symbolic_operand" "")]
8551                                                     UNSPEC_TLSLDO)
8552                                          (match_operand:SI 1 "register_operand" "r")))))]
8553   "TARGET_TLS && TARGET_ARCH32"
8554   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8555   [(set_attr "type" "load")
8556    (set_attr "us3load_type" "3cycle")])
8558 (define_insn "*tldo_ldub2_sp32"
8559   [(set (match_operand:SI 0 "register_operand" "=r")
8560         (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8561                                                      (match_operand 3 "tld_symbolic_operand" "")]
8562                                                     UNSPEC_TLSLDO)
8563                                          (match_operand:SI 1 "register_operand" "r")))))]
8564   "TARGET_TLS && TARGET_ARCH32"
8565   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8566   [(set_attr "type" "load")
8567    (set_attr "us3load_type" "3cycle")])
8569 (define_insn "*tldo_ldsb1_sp32"
8570   [(set (match_operand:HI 0 "register_operand" "=r")
8571         (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8572                                                      (match_operand 3 "tld_symbolic_operand" "")]
8573                                                     UNSPEC_TLSLDO)
8574                                          (match_operand:SI 1 "register_operand" "r")))))]
8575   "TARGET_TLS && TARGET_ARCH32"
8576   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8577   [(set_attr "type" "sload")
8578    (set_attr "us3load_type" "3cycle")])
8580 (define_insn "*tldo_ldsb2_sp32"
8581   [(set (match_operand:SI 0 "register_operand" "=r")
8582         (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8583                                                      (match_operand 3 "tld_symbolic_operand" "")]
8584                                                     UNSPEC_TLSLDO)
8585                                          (match_operand:SI 1 "register_operand" "r")))))]
8586   "TARGET_TLS && TARGET_ARCH32"
8587   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8588   [(set_attr "type" "sload")
8589    (set_attr "us3load_type" "3cycle")])
8591 (define_insn "*tldo_ldub_sp64"
8592   [(set (match_operand:QI 0 "register_operand" "=r")
8593         (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8594                                      (match_operand 3 "tld_symbolic_operand" "")]
8595                                     UNSPEC_TLSLDO)
8596                          (match_operand:DI 1 "register_operand" "r"))))]
8597   "TARGET_TLS && TARGET_ARCH64"
8598   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8599   [(set_attr "type" "load")
8600    (set_attr "us3load_type" "3cycle")])
8602 (define_insn "*tldo_ldub1_sp64"
8603   [(set (match_operand:HI 0 "register_operand" "=r")
8604         (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8605                                                      (match_operand 3 "tld_symbolic_operand" "")]
8606                                                     UNSPEC_TLSLDO)
8607                                          (match_operand:DI 1 "register_operand" "r")))))]
8608   "TARGET_TLS && TARGET_ARCH64"
8609   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8610   [(set_attr "type" "load")
8611    (set_attr "us3load_type" "3cycle")])
8613 (define_insn "*tldo_ldub2_sp64"
8614   [(set (match_operand:SI 0 "register_operand" "=r")
8615         (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8616                                                      (match_operand 3 "tld_symbolic_operand" "")]
8617                                                     UNSPEC_TLSLDO)
8618                                          (match_operand:DI 1 "register_operand" "r")))))]
8619   "TARGET_TLS && TARGET_ARCH64"
8620   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8621   [(set_attr "type" "load")
8622    (set_attr "us3load_type" "3cycle")])
8624 (define_insn "*tldo_ldub3_sp64"
8625   [(set (match_operand:DI 0 "register_operand" "=r")
8626         (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8627                                                      (match_operand 3 "tld_symbolic_operand" "")]
8628                                                     UNSPEC_TLSLDO)
8629                                          (match_operand:DI 1 "register_operand" "r")))))]
8630   "TARGET_TLS && TARGET_ARCH64"
8631   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8632   [(set_attr "type" "load")
8633    (set_attr "us3load_type" "3cycle")])
8635 (define_insn "*tldo_ldsb1_sp64"
8636   [(set (match_operand:HI 0 "register_operand" "=r")
8637         (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8638                                                      (match_operand 3 "tld_symbolic_operand" "")]
8639                                                     UNSPEC_TLSLDO)
8640                                          (match_operand:DI 1 "register_operand" "r")))))]
8641   "TARGET_TLS && TARGET_ARCH64"
8642   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8643   [(set_attr "type" "sload")
8644    (set_attr "us3load_type" "3cycle")])
8646 (define_insn "*tldo_ldsb2_sp64"
8647   [(set (match_operand:SI 0 "register_operand" "=r")
8648         (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8649                                                      (match_operand 3 "tld_symbolic_operand" "")]
8650                                                     UNSPEC_TLSLDO)
8651                                          (match_operand:DI 1 "register_operand" "r")))))]
8652   "TARGET_TLS && TARGET_ARCH64"
8653   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8654   [(set_attr "type" "sload")
8655    (set_attr "us3load_type" "3cycle")])
8657 (define_insn "*tldo_ldsb3_sp64"
8658   [(set (match_operand:DI 0 "register_operand" "=r")
8659         (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8660                                                      (match_operand 3 "tld_symbolic_operand" "")]
8661                                                     UNSPEC_TLSLDO)
8662                                          (match_operand:DI 1 "register_operand" "r")))))]
8663   "TARGET_TLS && TARGET_ARCH64"
8664   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8665   [(set_attr "type" "sload")
8666    (set_attr "us3load_type" "3cycle")])
8668 (define_insn "*tldo_lduh_sp32"
8669   [(set (match_operand:HI 0 "register_operand" "=r")
8670         (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8671                                      (match_operand 3 "tld_symbolic_operand" "")]
8672                                     UNSPEC_TLSLDO)
8673                          (match_operand:SI 1 "register_operand" "r"))))]
8674   "TARGET_TLS && TARGET_ARCH32"
8675   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8676   [(set_attr "type" "load")
8677    (set_attr "us3load_type" "3cycle")])
8679 (define_insn "*tldo_lduh1_sp32"
8680   [(set (match_operand:SI 0 "register_operand" "=r")
8681         (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8682                                                      (match_operand 3 "tld_symbolic_operand" "")]
8683                                                     UNSPEC_TLSLDO)
8684                                          (match_operand:SI 1 "register_operand" "r")))))]
8685   "TARGET_TLS && TARGET_ARCH32"
8686   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8687   [(set_attr "type" "load")
8688    (set_attr "us3load_type" "3cycle")])
8690 (define_insn "*tldo_ldsh1_sp32"
8691   [(set (match_operand:SI 0 "register_operand" "=r")
8692         (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8693                                                      (match_operand 3 "tld_symbolic_operand" "")]
8694                                                     UNSPEC_TLSLDO)
8695                                          (match_operand:SI 1 "register_operand" "r")))))]
8696   "TARGET_TLS && TARGET_ARCH32"
8697   "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8698   [(set_attr "type" "sload")
8699    (set_attr "us3load_type" "3cycle")])
8701 (define_insn "*tldo_lduh_sp64"
8702   [(set (match_operand:HI 0 "register_operand" "=r")
8703         (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8704                                      (match_operand 3 "tld_symbolic_operand" "")]
8705                                     UNSPEC_TLSLDO)
8706                          (match_operand:DI 1 "register_operand" "r"))))]
8707   "TARGET_TLS && TARGET_ARCH64"
8708   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8709   [(set_attr "type" "load")
8710    (set_attr "us3load_type" "3cycle")])
8712 (define_insn "*tldo_lduh1_sp64"
8713   [(set (match_operand:SI 0 "register_operand" "=r")
8714         (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8715                                                      (match_operand 3 "tld_symbolic_operand" "")]
8716                                                     UNSPEC_TLSLDO)
8717                                          (match_operand:DI 1 "register_operand" "r")))))]
8718   "TARGET_TLS && TARGET_ARCH64"
8719   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8720   [(set_attr "type" "load")
8721    (set_attr "us3load_type" "3cycle")])
8723 (define_insn "*tldo_lduh2_sp64"
8724   [(set (match_operand:DI 0 "register_operand" "=r")
8725         (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8726                                                      (match_operand 3 "tld_symbolic_operand" "")]
8727                                                     UNSPEC_TLSLDO)
8728                                          (match_operand:DI 1 "register_operand" "r")))))]
8729   "TARGET_TLS && TARGET_ARCH64"
8730   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8731   [(set_attr "type" "load")
8732    (set_attr "us3load_type" "3cycle")])
8734 (define_insn "*tldo_ldsh1_sp64"
8735   [(set (match_operand:SI 0 "register_operand" "=r")
8736         (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8737                                                      (match_operand 3 "tld_symbolic_operand" "")]
8738                                                     UNSPEC_TLSLDO)
8739                                          (match_operand:DI 1 "register_operand" "r")))))]
8740   "TARGET_TLS && TARGET_ARCH64"
8741   "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8742   [(set_attr "type" "sload")
8743    (set_attr "us3load_type" "3cycle")])
8745 (define_insn "*tldo_ldsh2_sp64"
8746   [(set (match_operand:DI 0 "register_operand" "=r")
8747         (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8748                                                      (match_operand 3 "tld_symbolic_operand" "")]
8749                                                     UNSPEC_TLSLDO)
8750                                          (match_operand:DI 1 "register_operand" "r")))))]
8751   "TARGET_TLS && TARGET_ARCH64"
8752   "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8753   [(set_attr "type" "sload")
8754    (set_attr "us3load_type" "3cycle")])
8756 (define_insn "*tldo_lduw_sp32"
8757   [(set (match_operand:SI 0 "register_operand" "=r")
8758         (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8759                                      (match_operand 3 "tld_symbolic_operand" "")]
8760                                     UNSPEC_TLSLDO)
8761                          (match_operand:SI 1 "register_operand" "r"))))]
8762   "TARGET_TLS && TARGET_ARCH32"
8763   "ld\t[%1 + %2], %0, %%tldo_add(%3)"
8764   [(set_attr "type" "load")])
8766 (define_insn "*tldo_lduw_sp64"
8767   [(set (match_operand:SI 0 "register_operand" "=r")
8768         (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8769                                      (match_operand 3 "tld_symbolic_operand" "")]
8770                                     UNSPEC_TLSLDO)
8771                          (match_operand:DI 1 "register_operand" "r"))))]
8772   "TARGET_TLS && TARGET_ARCH64"
8773   "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8774   [(set_attr "type" "load")])
8776 (define_insn "*tldo_lduw1_sp64"
8777   [(set (match_operand:DI 0 "register_operand" "=r")
8778         (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8779                                                      (match_operand 3 "tld_symbolic_operand" "")]
8780                                                     UNSPEC_TLSLDO)
8781                                          (match_operand:DI 1 "register_operand" "r")))))]
8782   "TARGET_TLS && TARGET_ARCH64"
8783   "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8784   [(set_attr "type" "load")])
8786 (define_insn "*tldo_ldsw1_sp64"
8787   [(set (match_operand:DI 0 "register_operand" "=r")
8788         (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8789                                                      (match_operand 3 "tld_symbolic_operand" "")]
8790                                                     UNSPEC_TLSLDO)
8791                                          (match_operand:DI 1 "register_operand" "r")))))]
8792   "TARGET_TLS && TARGET_ARCH64"
8793   "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
8794   [(set_attr "type" "sload")
8795    (set_attr "us3load_type" "3cycle")])
8797 (define_insn "*tldo_ldx_sp64"
8798   [(set (match_operand:DI 0 "register_operand" "=r")
8799         (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8800                                      (match_operand 3 "tld_symbolic_operand" "")]
8801                                     UNSPEC_TLSLDO)
8802                          (match_operand:DI 1 "register_operand" "r"))))]
8803   "TARGET_TLS && TARGET_ARCH64"
8804   "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
8805   [(set_attr "type" "load")])
8807 (define_insn "*tldo_stb_sp32"
8808   [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8809                                      (match_operand 3 "tld_symbolic_operand" "")]
8810                                     UNSPEC_TLSLDO)
8811                          (match_operand:SI 1 "register_operand" "r")))
8812         (match_operand:QI 0 "register_operand" "=r"))]
8813   "TARGET_TLS && TARGET_ARCH32"
8814   "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8815   [(set_attr "type" "store")])
8817 (define_insn "*tldo_stb_sp64"
8818   [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8819                                      (match_operand 3 "tld_symbolic_operand" "")]
8820                                     UNSPEC_TLSLDO)
8821                          (match_operand:DI 1 "register_operand" "r")))
8822         (match_operand:QI 0 "register_operand" "=r"))]
8823   "TARGET_TLS && TARGET_ARCH64"
8824   "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8825   [(set_attr "type" "store")])
8827 (define_insn "*tldo_sth_sp32"
8828   [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8829                                      (match_operand 3 "tld_symbolic_operand" "")]
8830                                     UNSPEC_TLSLDO)
8831                          (match_operand:SI 1 "register_operand" "r")))
8832         (match_operand:HI 0 "register_operand" "=r"))]
8833   "TARGET_TLS && TARGET_ARCH32"
8834   "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8835   [(set_attr "type" "store")])
8837 (define_insn "*tldo_sth_sp64"
8838   [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8839                                      (match_operand 3 "tld_symbolic_operand" "")]
8840                                     UNSPEC_TLSLDO)
8841                          (match_operand:DI 1 "register_operand" "r")))
8842         (match_operand:HI 0 "register_operand" "=r"))]
8843   "TARGET_TLS && TARGET_ARCH64"
8844   "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8845   [(set_attr "type" "store")])
8847 (define_insn "*tldo_stw_sp32"
8848   [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8849                                      (match_operand 3 "tld_symbolic_operand" "")]
8850                                     UNSPEC_TLSLDO)
8851                          (match_operand:SI 1 "register_operand" "r")))
8852         (match_operand:SI 0 "register_operand" "=r"))]
8853   "TARGET_TLS && TARGET_ARCH32"
8854   "st\t%0, [%1 + %2], %%tldo_add(%3)"
8855   [(set_attr "type" "store")])
8857 (define_insn "*tldo_stw_sp64"
8858   [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8859                                      (match_operand 3 "tld_symbolic_operand" "")]
8860                                     UNSPEC_TLSLDO)
8861                          (match_operand:DI 1 "register_operand" "r")))
8862         (match_operand:SI 0 "register_operand" "=r"))]
8863   "TARGET_TLS && TARGET_ARCH64"
8864   "stw\t%0, [%1 + %2], %%tldo_add(%3)"
8865   [(set_attr "type" "store")])
8867 (define_insn "*tldo_stx_sp64"
8868   [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8869                                      (match_operand 3 "tld_symbolic_operand" "")]
8870                                     UNSPEC_TLSLDO)
8871                          (match_operand:DI 1 "register_operand" "r")))
8872         (match_operand:DI 0 "register_operand" "=r"))]
8873   "TARGET_TLS && TARGET_ARCH64"
8874   "stx\t%0, [%1 + %2], %%tldo_add(%3)"
8875   [(set_attr "type" "store")])
8877 ;; Vector instructions.
8879 (define_insn "addv2si3"
8880   [(set (match_operand:V2SI 0 "register_operand" "=e")
8881         (plus:V2SI (match_operand:V2SI 1 "register_operand" "e")
8882                    (match_operand:V2SI 2 "register_operand" "e")))]
8883   "TARGET_VIS"
8884   "fpadd32\t%1, %2, %0"
8885   [(set_attr "type" "fga")
8886    (set_attr "fptype" "double")])
8888 (define_insn "addv4hi3"
8889   [(set (match_operand:V4HI 0 "register_operand" "=e")
8890          (plus:V4HI (match_operand:V4HI 1 "register_operand" "e")
8891                     (match_operand:V4HI 2 "register_operand" "e")))]
8892   "TARGET_VIS"
8893   "fpadd16\t%1, %2, %0"
8894   [(set_attr "type" "fga")
8895    (set_attr "fptype" "double")])
8897 ;; fpadd32s is emitted by the addsi3 pattern.
8899 (define_insn "addv2hi3"
8900   [(set (match_operand:V2HI 0 "register_operand" "=f")
8901         (plus:V2HI (match_operand:V2HI 1 "register_operand" "f")
8902                    (match_operand:V2HI 2 "register_operand" "f")))]
8903   "TARGET_VIS"
8904   "fpadd16s\t%1, %2, %0"
8905   [(set_attr "type" "fga")
8906    (set_attr "fptype" "single")])
8908 (define_insn "subv2si3"
8909   [(set (match_operand:V2SI 0 "register_operand" "=e")
8910         (minus:V2SI (match_operand:V2SI 1 "register_operand" "e")
8911                     (match_operand:V2SI 2 "register_operand" "e")))]
8912   "TARGET_VIS"
8913   "fpsub32\t%1, %2, %0"
8914   [(set_attr "type" "fga")
8915    (set_attr "fptype" "double")])
8917 (define_insn "subv4hi3"
8918   [(set (match_operand:V4HI 0 "register_operand" "=e")
8919         (minus:V4HI (match_operand:V4HI 1 "register_operand" "e")
8920                     (match_operand:V4HI 2 "register_operand" "e")))]
8921   "TARGET_VIS"
8922   "fpsub16\t%1, %2, %0"
8923   [(set_attr "type" "fga")
8924    (set_attr "fptype" "double")])
8926 ;; fpsub32s is emitted by the subsi3 pattern.
8928 (define_insn "subv2hi3"
8929   [(set (match_operand:V2HI 0 "register_operand" "=f")
8930         (minus:V2HI (match_operand:V2HI 1 "register_operand" "f")
8931                     (match_operand:V2HI 2 "register_operand" "f")))]
8932   "TARGET_VIS"
8933   "fpsub16s\t%1, %2, %0"
8934   [(set_attr "type" "fga")
8935    (set_attr "fptype" "single")])
8937 ;; All other logical instructions have integer equivalents so they
8938 ;; are defined together.
8940 ;; (ior (not (op1)) (not (op2))) is the canonical form of NAND.
8942 (define_insn "*nand<V64mode>_vis"
8943   [(set (match_operand:V64 0 "register_operand" "=e")
8944         (ior:V64 (not:V64 (match_operand:V64 1 "register_operand" "e"))
8945                  (not:V64 (match_operand:V64 2 "register_operand" "e"))))]
8946   "TARGET_VIS"
8947   "fnand\t%1, %2, %0"
8948   [(set_attr "type" "fga")
8949    (set_attr "fptype" "double")])
8951 (define_insn "*nand<V32mode>_vis"
8952   [(set (match_operand:V32 0 "register_operand" "=f")
8953          (ior:V32 (not:V32 (match_operand:V32 1 "register_operand" "f"))
8954                   (not:V32 (match_operand:V32 2 "register_operand" "f"))))]
8955   "TARGET_VIS"
8956   "fnands\t%1, %2, %0"
8957   [(set_attr "type" "fga")
8958    (set_attr "fptype" "single")])
8960 ;; Hard to generate VIS instructions.  We have builtins for these.
8962 (define_insn "fpack16_vis"
8963   [(set (match_operand:V4QI 0 "register_operand" "=f")
8964         (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e")]
8965                       UNSPEC_FPACK16))]
8966   "TARGET_VIS"
8967   "fpack16\t%1, %0"
8968   [(set_attr "type" "fga")
8969    (set_attr "fptype" "double")])
8971 (define_insn "fpackfix_vis"
8972   [(set (match_operand:V2HI 0 "register_operand" "=f")
8973         (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e")]
8974                       UNSPEC_FPACKFIX))]
8975   "TARGET_VIS"
8976   "fpackfix\t%1, %0"
8977   [(set_attr "type" "fga")
8978    (set_attr "fptype" "double")])
8980 (define_insn "fpack32_vis"
8981   [(set (match_operand:V8QI 0 "register_operand" "=e")
8982         (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e")
8983                       (match_operand:V8QI 2 "register_operand" "e")]
8984                      UNSPEC_FPACK32))]
8985   "TARGET_VIS"
8986   "fpack32\t%1, %2, %0"
8987   [(set_attr "type" "fga")
8988    (set_attr "fptype" "double")])
8990 (define_insn "fexpand_vis"
8991   [(set (match_operand:V4HI 0 "register_operand" "=e")
8992         (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")]
8993          UNSPEC_FEXPAND))]
8994  "TARGET_VIS"
8995  "fexpand\t%1, %0"
8996  [(set_attr "type" "fga")
8997   (set_attr "fptype" "double")])
8999 ;; It may be possible to describe this operation as (1 indexed):
9000 ;; (vec_select (vec_duplicate (vec_duplicate (vec_concat 1 2)))
9001 ;;  1,5,10,14,19,23,28,32)
9002 ;; Note that (vec_merge:V8QI [(V4QI) (V4QI)] (10101010 = 170) doesn't work
9003 ;; because vec_merge expects all the operands to be of the same type.
9004 (define_insn "fpmerge_vis"
9005   [(set (match_operand:V8QI 0 "register_operand" "=e")
9006         (unspec:V8QI [(match_operand:V4QI 1 "register_operand" "f")
9007                       (match_operand:V4QI 2 "register_operand" "f")]
9008          UNSPEC_FPMERGE))]
9009  "TARGET_VIS"
9010  "fpmerge\t%1, %2, %0"
9011  [(set_attr "type" "fga")
9012   (set_attr "fptype" "double")])
9014 ;; Partitioned multiply instructions
9015 (define_insn "fmul8x16_vis"
9016   [(set (match_operand:V4HI 0 "register_operand" "=e")
9017         (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
9018                    (match_operand:V4HI 2 "register_operand" "e")))]
9019   "TARGET_VIS"
9020   "fmul8x16\t%1, %2, %0"
9021   [(set_attr "type" "fpmul")
9022    (set_attr "fptype" "double")])
9024 ;; Only one of the following two insns can be a multiply.
9025 (define_insn "fmul8x16au_vis"
9026   [(set (match_operand:V4HI 0 "register_operand" "=e")
9027         (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
9028                    (match_operand:V2HI 2 "register_operand" "f")))]
9029   "TARGET_VIS"
9030   "fmul8x16au\t%1, %2, %0"
9031   [(set_attr "type" "fpmul")
9032    (set_attr "fptype" "double")])
9034 (define_insn "fmul8x16al_vis"
9035   [(set (match_operand:V4HI 0 "register_operand" "=e")
9036         (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
9037                       (match_operand:V2HI 2 "register_operand" "f")]
9038          UNSPEC_MUL16AL))]
9039   "TARGET_VIS"
9040   "fmul8x16al\t%1, %2, %0"
9041   [(set_attr "type" "fpmul")
9042    (set_attr "fptype" "double")])
9044 ;; Only one of the following two insns can be a multiply.
9045 (define_insn "fmul8sux16_vis"
9046   [(set (match_operand:V4HI 0 "register_operand" "=e")
9047         (mult:V4HI (match_operand:V8QI 1 "register_operand" "e")
9048                    (match_operand:V4HI 2 "register_operand" "e")))]
9049   "TARGET_VIS"
9050   "fmul8sux16\t%1, %2, %0"
9051   [(set_attr "type" "fpmul")
9052    (set_attr "fptype" "double")])
9054 (define_insn "fmul8ulx16_vis"
9055   [(set (match_operand:V4HI 0 "register_operand" "=e")
9056         (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
9057                       (match_operand:V4HI 2 "register_operand" "e")]
9058          UNSPEC_MUL8UL))]
9059   "TARGET_VIS"
9060   "fmul8ulx16\t%1, %2, %0"
9061   [(set_attr "type" "fpmul")
9062    (set_attr "fptype" "double")])
9064 ;; Only one of the following two insns can be a multiply.
9065 (define_insn "fmuld8sux16_vis"
9066   [(set (match_operand:V2SI 0 "register_operand" "=e")
9067         (mult:V2SI (match_operand:V4QI 1 "register_operand" "f")
9068                    (match_operand:V2HI 2 "register_operand" "f")))]
9069   "TARGET_VIS"
9070   "fmuld8sux16\t%1, %2, %0"
9071   [(set_attr "type" "fpmul")
9072    (set_attr "fptype" "double")])
9074 (define_insn "fmuld8ulx16_vis"
9075   [(set (match_operand:V2SI 0 "register_operand" "=e")
9076         (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
9077                       (match_operand:V2HI 2 "register_operand" "f")]
9078          UNSPEC_MULDUL))]
9079   "TARGET_VIS"
9080   "fmuld8ulx16\t%1, %2, %0"
9081   [(set_attr "type" "fpmul")
9082    (set_attr "fptype" "double")])
9084 ;; Using faligndata only makes sense after an alignaddr since the choice of
9085 ;; bytes to take out of each operand is dependant on the results of the last
9086 ;; alignaddr.
9087 (define_insn "faligndata<V64I:mode>_vis"
9088   [(set (match_operand:V64I 0 "register_operand" "=e")
9089         (unspec:V64I [(match_operand:V64I 1 "register_operand" "e")
9090                       (match_operand:V64I 2 "register_operand" "e")]
9091          UNSPEC_ALIGNDATA))]
9092   "TARGET_VIS"
9093   "faligndata\t%1, %2, %0"
9094   [(set_attr "type" "fga")
9095    (set_attr "fptype" "double")])
9097 (define_insn "alignaddr<P:mode>_vis"
9098   [(set (match_operand:P 0 "register_operand" "=r")
9099         (unspec:P [(match_operand:P 1 "reg_or_0_operand" "rJ")
9100                    (match_operand:P 2 "reg_or_0_operand" "rJ")]
9101          UNSPEC_ALIGNADDR))]
9102   "TARGET_VIS"
9103   "alignaddr\t%r1, %r2, %0")
9105 (define_insn "pdist_vis"
9106   [(set (match_operand:DI 0 "register_operand" "=e")
9107         (unspec:DI [(match_operand:V8QI 1 "register_operand" "e")
9108                     (match_operand:V8QI 2 "register_operand" "e")
9109                     (match_operand:DI 3 "register_operand" "0")]
9110          UNSPEC_PDIST))]
9111   "TARGET_VIS"
9112   "pdist\t%1, %2, %0"
9113   [(set_attr "type" "fga")
9114    (set_attr "fptype" "double")])