Sync usage with man page.
[netbsd-mini2440.git] / gnu / dist / gcc4 / gcc / config / sparc / sparc.md
blobdb0348888b0be4f3e7d62e796b044653f8b3f413
1 ;; Machine description for SPARC chip for GCC
2 ;;  Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 ;;  1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
4 ;;  Contributed by Michael Tiemann (tiemann@cygnus.com)
5 ;;  64-bit SPARC-V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
6 ;;  at Cygnus Support.
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING.  If not, write to
22 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, USA.
25 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
27 (define_constants
28   [(UNSPEC_MOVE_PIC             0)
29    (UNSPEC_UPDATE_RETURN        1)
30    (UNSPEC_LOAD_PCREL_SYM       2)
31    (UNSPEC_MOVE_PIC_LABEL       5)
32    (UNSPEC_SETH44               6)
33    (UNSPEC_SETM44               7)
34    (UNSPEC_SETHH                9)
35    (UNSPEC_SETLM                10)
36    (UNSPEC_EMB_HISUM            11)
37    (UNSPEC_EMB_TEXTUHI          13)
38    (UNSPEC_EMB_TEXTHI           14)
39    (UNSPEC_EMB_TEXTULO          15)
40    (UNSPEC_EMB_SETHM            18)
42    (UNSPEC_TLSGD                30)
43    (UNSPEC_TLSLDM               31)
44    (UNSPEC_TLSLDO               32)
45    (UNSPEC_TLSIE                33)
46    (UNSPEC_TLSLE                34)
47    (UNSPEC_TLSLD_BASE           35)
49    (UNSPEC_FPACK16              40)
50    (UNSPEC_FPACK32              41)
51    (UNSPEC_FPACKFIX             42)
52    (UNSPEC_FEXPAND              43)
53    (UNSPEC_FPMERGE              44)
54    (UNSPEC_MUL16AL              45)
55    (UNSPEC_MUL8UL               46)
56    (UNSPEC_MULDUL               47)
57    (UNSPEC_ALIGNDATA            48)
58    (UNSPEC_ALIGNADDR            49)
59    (UNSPEC_PDIST                50)
61    (UNSPEC_SP_SET               60)
62    (UNSPEC_SP_TEST              61)
63   ])
65 (define_constants
66   [(UNSPECV_BLOCKAGE            0)
67    (UNSPECV_FLUSHW              1)
68    (UNSPECV_GOTO                2)
69    (UNSPECV_FLUSH               4)
70    (UNSPECV_SETJMP              5)
71    (UNSPECV_SAVEW               6)
72   ])
74 ;; The upper 32 fp regs on the v9 can't hold SFmode values.  To deal with this
75 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip.  The name
76 ;; is a bit of a misnomer as it covers all 64 fp regs.  The corresponding
77 ;; constraint letter is 'e'.  To avoid any confusion, 'e' is used instead of
78 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
81 ;; Attribute for cpu type.
82 ;; These must match the values for enum processor_type in sparc.h.
83 (define_attr "cpu"
84   "v7,
85    cypress,
86    v8,
87    supersparc,
88    sparclite,f930,f934,
89    hypersparc,sparclite86x,
90    sparclet,tsc701,
91    v9,
92    ultrasparc,
93    ultrasparc3"
94   (const (symbol_ref "sparc_cpu_attr")))
96 ;; Attribute for the instruction set.
97 ;; At present we only need to distinguish v9/!v9, but for clarity we
98 ;; test TARGET_V8 too.
99 (define_attr "isa" "v7,v8,v9,sparclet"
100  (const
101   (cond [(symbol_ref "TARGET_V9") (const_string "v9")
102          (symbol_ref "TARGET_V8") (const_string "v8")
103          (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
104         (const_string "v7"))))
106 ;; Insn type.
107 (define_attr "type"
108   "ialu,compare,shift,
109    load,sload,store,
110    uncond_branch,branch,call,sibcall,call_no_delay_slot,return,
111    imul,idiv,
112    fpload,fpstore,
113    fp,fpmove,
114    fpcmove,fpcrmove,
115    fpcmp,
116    fpmul,fpdivs,fpdivd,
117    fpsqrts,fpsqrtd,
118    fga,fgm_pack,fgm_mul,fgm_pdist,fgm_cmp,
119    cmove,
120    ialuX,
121    multi,savew,flushw,iflush,trap"
122   (const_string "ialu"))
124 ;; True if branch/call has empty delay slot and will emit a nop in it
125 (define_attr "empty_delay_slot" "false,true"
126   (symbol_ref "empty_delay_slot (insn)"))
128 (define_attr "branch_type" "none,icc,fcc,reg"
129   (const_string "none"))
131 (define_attr "pic" "false,true"
132   (symbol_ref "flag_pic != 0"))
134 (define_attr "calls_alloca" "false,true"
135   (symbol_ref "current_function_calls_alloca != 0"))
137 (define_attr "calls_eh_return" "false,true"
138    (symbol_ref "current_function_calls_eh_return !=0 "))
139    
140 (define_attr "leaf_function" "false,true"
141   (symbol_ref "current_function_uses_only_leaf_regs != 0"))
143 (define_attr "delayed_branch" "false,true"
144   (symbol_ref "flag_delayed_branch != 0"))
146 ;; Length (in # of insns).
147 ;; Beware that setting a length greater or equal to 3 for conditional branches
148 ;; has a side-effect (see output_cbranch and output_v9branch).
149 (define_attr "length" ""
150   (cond [(eq_attr "type" "uncond_branch,call")
151            (if_then_else (eq_attr "empty_delay_slot" "true")
152              (const_int 2)
153              (const_int 1))
154          (eq_attr "type" "sibcall")
155            (if_then_else (eq_attr "leaf_function" "true")
156              (if_then_else (eq_attr "empty_delay_slot" "true")
157                (const_int 3)
158                (const_int 2))
159              (if_then_else (eq_attr "empty_delay_slot" "true")
160                (const_int 2)
161                (const_int 1)))
162          (eq_attr "branch_type" "icc")
163            (if_then_else (match_operand 0 "noov_compare64_operator" "")
164              (if_then_else (lt (pc) (match_dup 1))
165                (if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000))
166                  (if_then_else (eq_attr "empty_delay_slot" "true")
167                    (const_int 2)
168                    (const_int 1))
169                  (if_then_else (eq_attr "empty_delay_slot" "true")
170                    (const_int 4)
171                    (const_int 3)))
172                (if_then_else (lt (minus (pc) (match_dup 1)) (const_int 260000))
173                  (if_then_else (eq_attr "empty_delay_slot" "true")
174                    (const_int 2)
175                    (const_int 1))
176                  (if_then_else (eq_attr "empty_delay_slot" "true")
177                    (const_int 4)
178                    (const_int 3))))
179              (if_then_else (eq_attr "empty_delay_slot" "true")
180                (const_int 2)
181                (const_int 1)))
182          (eq_attr "branch_type" "fcc")
183            (if_then_else (match_operand 0 "fcc0_register_operand" "")
184              (if_then_else (eq_attr "empty_delay_slot" "true")
185                (if_then_else (eq (symbol_ref "TARGET_V9") (const_int 0))
186                  (const_int 3)
187                  (const_int 2))
188                (if_then_else (eq (symbol_ref "TARGET_V9") (const_int 0))
189                  (const_int 2)
190                  (const_int 1)))
191              (if_then_else (lt (pc) (match_dup 2))
192                (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000))
193                  (if_then_else (eq_attr "empty_delay_slot" "true")
194                    (const_int 2)
195                    (const_int 1))
196                  (if_then_else (eq_attr "empty_delay_slot" "true")
197                    (const_int 4)
198                    (const_int 3)))
199                (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000))
200                  (if_then_else (eq_attr "empty_delay_slot" "true")
201                    (const_int 2)
202                    (const_int 1))
203                  (if_then_else (eq_attr "empty_delay_slot" "true")
204                    (const_int 4)
205                    (const_int 3)))))
206          (eq_attr "branch_type" "reg")
207            (if_then_else (lt (pc) (match_dup 2))
208              (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000))
209                (if_then_else (eq_attr "empty_delay_slot" "true")
210                  (const_int 2)
211                  (const_int 1))
212                (if_then_else (eq_attr "empty_delay_slot" "true")
213                  (const_int 4)
214                  (const_int 3)))
215              (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000))
216                (if_then_else (eq_attr "empty_delay_slot" "true")
217                  (const_int 2)
218                  (const_int 1))
219                (if_then_else (eq_attr "empty_delay_slot" "true")
220                  (const_int 4)
221                  (const_int 3))))
222          ] (const_int 1)))
224 ;; FP precision.
225 (define_attr "fptype" "single,double"
226   (const_string "single"))
228 ;; UltraSPARC-III integer load type.
229 (define_attr "us3load_type" "2cycle,3cycle"
230   (const_string "2cycle"))
232 (define_asm_attributes
233   [(set_attr "length" "2")
234    (set_attr "type" "multi")])
236 ;; Attributes for instruction and branch scheduling
237 (define_attr "tls_call_delay" "false,true"
238   (symbol_ref "tls_call_delay (insn)"))
240 (define_attr "in_call_delay" "false,true"
241   (cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
242                 (const_string "false")
243          (eq_attr "type" "load,fpload,store,fpstore")
244                 (if_then_else (eq_attr "length" "1")
245                               (const_string "true")
246                               (const_string "false"))]
247         (if_then_else (and (eq_attr "length" "1")
248                            (eq_attr "tls_call_delay" "true"))
249                       (const_string "true")
250                       (const_string "false"))))
252 (define_attr "eligible_for_sibcall_delay" "false,true"
253   (symbol_ref "eligible_for_sibcall_delay (insn)"))
255 (define_attr "eligible_for_return_delay" "false,true"
256   (symbol_ref "eligible_for_return_delay (insn)"))
258 ;; ??? !v9: Should implement the notion of predelay slots for floating-point
259 ;; branches.  This would allow us to remove the nop always inserted before
260 ;; a floating point branch.
262 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
263 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
264 ;; This is because doing so will add several pipeline stalls to the path
265 ;; that the load/store did not come from.  Unfortunately, there is no way
266 ;; to prevent fill_eager_delay_slots from using load/store without completely
267 ;; disabling them.  For the SPEC benchmark set, this is a serious lose,
268 ;; because it prevents us from moving back the final store of inner loops.
270 (define_attr "in_branch_delay" "false,true"
271   (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
272                      (eq_attr "length" "1"))
273                 (const_string "true")
274                 (const_string "false")))
276 (define_attr "in_uncond_branch_delay" "false,true"
277   (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
278                      (eq_attr "length" "1"))
279                 (const_string "true")
280                 (const_string "false")))
282 (define_attr "in_annul_branch_delay" "false,true"
283   (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
284                      (eq_attr "length" "1"))
285                 (const_string "true")
286                 (const_string "false")))
288 (define_delay (eq_attr "type" "call")
289   [(eq_attr "in_call_delay" "true") (nil) (nil)])
291 (define_delay (eq_attr "type" "sibcall")
292   [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
294 (define_delay (eq_attr "type" "branch")
295   [(eq_attr "in_branch_delay" "true")
296    (nil) (eq_attr "in_annul_branch_delay" "true")])
298 (define_delay (eq_attr "type" "uncond_branch")
299   [(eq_attr "in_uncond_branch_delay" "true")
300    (nil) (nil)])
302 (define_delay (eq_attr "type" "return")
303   [(eq_attr "eligible_for_return_delay" "true") (nil) (nil)])
306 ;; Include SPARC DFA schedulers
308 (include "cypress.md")
309 (include "supersparc.md")
310 (include "hypersparc.md")
311 (include "sparclet.md")
312 (include "ultra1_2.md")
313 (include "ultra3.md")
316 ;; Operand and operator predicates.
318 (include "predicates.md")
321 ;; Compare instructions.
323 ;; We generate RTL for comparisons and branches by having the cmpxx 
324 ;; patterns store away the operands.  Then, the scc and bcc patterns
325 ;; emit RTL for both the compare and the branch.
327 ;; We do this because we want to generate different code for an sne and
328 ;; seq insn.  In those cases, if the second operand of the compare is not
329 ;; const0_rtx, we want to compute the xor of the two operands and test
330 ;; it against zero.
332 ;; We start with the DEFINE_EXPANDs, then the DEFINE_INSNs to match
333 ;; the patterns.  Finally, we have the DEFINE_SPLITs for some of the scc
334 ;; insns that actually require more than one machine instruction.
336 (define_expand "cmpsi"
337   [(set (reg:CC 100)
338         (compare:CC (match_operand:SI 0 "compare_operand" "")
339                     (match_operand:SI 1 "arith_operand" "")))]
340   ""
342   if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx)
343     operands[0] = force_reg (SImode, operands[0]);
345   sparc_compare_op0 = operands[0];
346   sparc_compare_op1 = operands[1];
347   DONE;
350 (define_expand "cmpdi"
351   [(set (reg:CCX 100)
352         (compare:CCX (match_operand:DI 0 "compare_operand" "")
353                      (match_operand:DI 1 "arith_operand" "")))]
354   "TARGET_ARCH64"
356   if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx)
357     operands[0] = force_reg (DImode, operands[0]);
359   sparc_compare_op0 = operands[0];
360   sparc_compare_op1 = operands[1];
361   DONE;
364 (define_expand "cmpsf"
365   ;; The 96 here isn't ever used by anyone.
366   [(set (reg:CCFP 96)
367         (compare:CCFP (match_operand:SF 0 "register_operand" "")
368                       (match_operand:SF 1 "register_operand" "")))]
369   "TARGET_FPU"
371   sparc_compare_op0 = operands[0];
372   sparc_compare_op1 = operands[1];
373   DONE;
376 (define_expand "cmpdf"
377   ;; The 96 here isn't ever used by anyone.
378   [(set (reg:CCFP 96)
379         (compare:CCFP (match_operand:DF 0 "register_operand" "")
380                       (match_operand:DF 1 "register_operand" "")))]
381   "TARGET_FPU"
383   sparc_compare_op0 = operands[0];
384   sparc_compare_op1 = operands[1];
385   DONE;
388 (define_expand "cmptf"
389   ;; The 96 here isn't ever used by anyone.
390   [(set (reg:CCFP 96)
391         (compare:CCFP (match_operand:TF 0 "register_operand" "")
392                       (match_operand:TF 1 "register_operand" "")))]
393   "TARGET_FPU"
395   sparc_compare_op0 = operands[0];
396   sparc_compare_op1 = operands[1];
397   DONE;
400 ;; Now the compare DEFINE_INSNs.
402 (define_insn "*cmpsi_insn"
403   [(set (reg:CC 100)
404         (compare:CC (match_operand:SI 0 "register_operand" "r")
405                     (match_operand:SI 1 "arith_operand" "rI")))]
406   ""
407   "cmp\t%0, %1"
408   [(set_attr "type" "compare")])
410 (define_insn "*cmpdi_sp64"
411   [(set (reg:CCX 100)
412         (compare:CCX (match_operand:DI 0 "register_operand" "r")
413                      (match_operand:DI 1 "arith_operand" "rI")))]
414   "TARGET_ARCH64"
415   "cmp\t%0, %1"
416   [(set_attr "type" "compare")])
418 (define_insn "*cmpsf_fpe"
419   [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
420         (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
421                        (match_operand:SF 2 "register_operand" "f")))]
422   "TARGET_FPU"
424   if (TARGET_V9)
425     return "fcmpes\t%0, %1, %2";
426   return "fcmpes\t%1, %2";
428   [(set_attr "type" "fpcmp")])
430 (define_insn "*cmpdf_fpe"
431   [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
432         (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
433                        (match_operand:DF 2 "register_operand" "e")))]
434   "TARGET_FPU"
436   if (TARGET_V9)
437     return "fcmped\t%0, %1, %2";
438   return "fcmped\t%1, %2";
440   [(set_attr "type" "fpcmp")
441    (set_attr "fptype" "double")])
443 (define_insn "*cmptf_fpe"
444   [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
445         (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
446                        (match_operand:TF 2 "register_operand" "e")))]
447   "TARGET_FPU && TARGET_HARD_QUAD"
449   if (TARGET_V9)
450     return "fcmpeq\t%0, %1, %2";
451   return "fcmpeq\t%1, %2";
453   [(set_attr "type" "fpcmp")])
455 (define_insn "*cmpsf_fp"
456   [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
457         (compare:CCFP (match_operand:SF 1 "register_operand" "f")
458                       (match_operand:SF 2 "register_operand" "f")))]
459   "TARGET_FPU"
461   if (TARGET_V9)
462     return "fcmps\t%0, %1, %2";
463   return "fcmps\t%1, %2";
465   [(set_attr "type" "fpcmp")])
467 (define_insn "*cmpdf_fp"
468   [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
469         (compare:CCFP (match_operand:DF 1 "register_operand" "e")
470                       (match_operand:DF 2 "register_operand" "e")))]
471   "TARGET_FPU"
473   if (TARGET_V9)
474     return "fcmpd\t%0, %1, %2";
475   return "fcmpd\t%1, %2";
477   [(set_attr "type" "fpcmp")
478    (set_attr "fptype" "double")])
480 (define_insn "*cmptf_fp"
481   [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
482         (compare:CCFP (match_operand:TF 1 "register_operand" "e")
483                       (match_operand:TF 2 "register_operand" "e")))]
484   "TARGET_FPU && TARGET_HARD_QUAD"
486   if (TARGET_V9)
487     return "fcmpq\t%0, %1, %2";
488   return "fcmpq\t%1, %2";
490   [(set_attr "type" "fpcmp")])
492 ;; Next come the scc insns.  For seq, sne, sgeu, and sltu, we can do this
493 ;; without jumps using the addx/subx instructions.  For seq/sne on v9 we use
494 ;; the same code as v8 (the addx/subx method has more applications).  The
495 ;; exception to this is "reg != 0" which can be done in one instruction on v9
496 ;; (so we do it).  For the rest, on v9 we use conditional moves; on v8, we do
497 ;; branches.
499 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
500 ;; generate addcc/subcc instructions.
502 (define_expand "seqsi_special"
503   [(set (match_dup 3)
504         (xor:SI (match_operand:SI 1 "register_operand" "")
505                 (match_operand:SI 2 "register_operand" "")))
506    (parallel [(set (match_operand:SI 0 "register_operand" "")
507                    (eq:SI (match_dup 3) (const_int 0)))
508               (clobber (reg:CC 100))])]
509   ""
510   { operands[3] = gen_reg_rtx (SImode); })
512 (define_expand "seqdi_special"
513   [(set (match_dup 3)
514         (xor:DI (match_operand:DI 1 "register_operand" "")
515                 (match_operand:DI 2 "register_operand" "")))
516    (set (match_operand:DI 0 "register_operand" "")
517         (eq:DI (match_dup 3) (const_int 0)))]
518   "TARGET_ARCH64"
519   { operands[3] = gen_reg_rtx (DImode); })
521 (define_expand "snesi_special"
522   [(set (match_dup 3)
523         (xor:SI (match_operand:SI 1 "register_operand" "")
524                 (match_operand:SI 2 "register_operand" "")))
525    (parallel [(set (match_operand:SI 0 "register_operand" "")
526                    (ne:SI (match_dup 3) (const_int 0)))
527               (clobber (reg:CC 100))])]
528   ""
529   { operands[3] = gen_reg_rtx (SImode); })
531 (define_expand "snedi_special"
532   [(set (match_dup 3)
533         (xor:DI (match_operand:DI 1 "register_operand" "")
534                 (match_operand:DI 2 "register_operand" "")))
535    (set (match_operand:DI 0 "register_operand" "")
536         (ne:DI (match_dup 3) (const_int 0)))]
537   "TARGET_ARCH64"
538   { operands[3] = gen_reg_rtx (DImode); })
540 (define_expand "seqdi_special_trunc"
541   [(set (match_dup 3)
542         (xor:DI (match_operand:DI 1 "register_operand" "")
543                 (match_operand:DI 2 "register_operand" "")))
544    (set (match_operand:SI 0 "register_operand" "")
545         (eq:SI (match_dup 3) (const_int 0)))]
546   "TARGET_ARCH64"
547   { operands[3] = gen_reg_rtx (DImode); })
549 (define_expand "snedi_special_trunc"
550   [(set (match_dup 3)
551         (xor:DI (match_operand:DI 1 "register_operand" "")
552                 (match_operand:DI 2 "register_operand" "")))
553    (set (match_operand:SI 0 "register_operand" "")
554         (ne:SI (match_dup 3) (const_int 0)))]
555   "TARGET_ARCH64"
556   { operands[3] = gen_reg_rtx (DImode); })
558 (define_expand "seqsi_special_extend"
559   [(set (match_dup 3)
560         (xor:SI (match_operand:SI 1 "register_operand" "")
561                 (match_operand:SI 2 "register_operand" "")))
562    (parallel [(set (match_operand:DI 0 "register_operand" "")
563                    (eq:DI (match_dup 3) (const_int 0)))
564               (clobber (reg:CC 100))])]
565   "TARGET_ARCH64"
566   { operands[3] = gen_reg_rtx (SImode); })
568 (define_expand "snesi_special_extend"
569   [(set (match_dup 3)
570         (xor:SI (match_operand:SI 1 "register_operand" "")
571                 (match_operand:SI 2 "register_operand" "")))
572    (parallel [(set (match_operand:DI 0 "register_operand" "")
573                    (ne:DI (match_dup 3) (const_int 0)))
574               (clobber (reg:CC 100))])]
575   "TARGET_ARCH64"
576   { operands[3] = gen_reg_rtx (SImode); })
578 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
579 ;; However, the code handles both SImode and DImode.
580 (define_expand "seq"
581   [(set (match_operand:SI 0 "int_register_operand" "")
582         (eq:SI (match_dup 1) (const_int 0)))]
583   ""
585   if (GET_MODE (sparc_compare_op0) == SImode)
586     {
587       rtx pat;
589       if (GET_MODE (operands[0]) == SImode)
590         pat = gen_seqsi_special (operands[0], sparc_compare_op0,
591                                  sparc_compare_op1);
592       else if (! TARGET_ARCH64)
593         FAIL;
594       else
595         pat = gen_seqsi_special_extend (operands[0], sparc_compare_op0,
596                                         sparc_compare_op1);
597       emit_insn (pat);
598       DONE;
599     }
600   else if (GET_MODE (sparc_compare_op0) == DImode)
601     {
602       rtx pat;
604       if (! TARGET_ARCH64)
605         FAIL;
606       else if (GET_MODE (operands[0]) == SImode)
607         pat = gen_seqdi_special_trunc (operands[0], sparc_compare_op0,
608                                        sparc_compare_op1);
609       else
610         pat = gen_seqdi_special (operands[0], sparc_compare_op0,
611                                  sparc_compare_op1);
612       emit_insn (pat);
613       DONE;
614     }
615   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
616     {
617       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
618       emit_jump_insn (gen_sne (operands[0]));
619       DONE;
620     }
621   else if (TARGET_V9)
622     {
623       if (gen_v9_scc (EQ, operands))
624         DONE;
625       /* fall through */
626     }
627   FAIL;
630 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
631 ;; However, the code handles both SImode and DImode.
632 (define_expand "sne"
633   [(set (match_operand:SI 0 "int_register_operand" "")
634         (ne:SI (match_dup 1) (const_int 0)))]
635   ""
637   if (GET_MODE (sparc_compare_op0) == SImode)
638     {
639       rtx pat;
641       if (GET_MODE (operands[0]) == SImode)
642         pat = gen_snesi_special (operands[0], sparc_compare_op0,
643                                  sparc_compare_op1);
644       else if (! TARGET_ARCH64)
645         FAIL;
646       else
647         pat = gen_snesi_special_extend (operands[0], sparc_compare_op0,
648                                         sparc_compare_op1);
649       emit_insn (pat);
650       DONE;
651     }
652   else if (GET_MODE (sparc_compare_op0) == DImode)
653     {
654       rtx pat;
656       if (! TARGET_ARCH64)
657         FAIL;
658       else if (GET_MODE (operands[0]) == SImode)
659         pat = gen_snedi_special_trunc (operands[0], sparc_compare_op0,
660                                        sparc_compare_op1);
661       else
662         pat = gen_snedi_special (operands[0], sparc_compare_op0,
663                                  sparc_compare_op1);
664       emit_insn (pat);
665       DONE;
666     }
667   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
668     {
669       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
670       emit_jump_insn (gen_sne (operands[0]));
671       DONE;
672     }
673   else if (TARGET_V9)
674     {
675       if (gen_v9_scc (NE, operands))
676         DONE;
677       /* fall through */
678     }
679   FAIL;
682 (define_expand "sgt"
683   [(set (match_operand:SI 0 "int_register_operand" "")
684         (gt:SI (match_dup 1) (const_int 0)))]
685   ""
687   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
688     {
689       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
690       emit_jump_insn (gen_sne (operands[0]));
691       DONE;
692     }
693   else if (TARGET_V9)
694     {
695       if (gen_v9_scc (GT, operands))
696         DONE;
697       /* fall through */
698     }
699   FAIL;
702 (define_expand "slt"
703   [(set (match_operand:SI 0 "int_register_operand" "")
704         (lt:SI (match_dup 1) (const_int 0)))]
705   ""
707   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
708     {
709       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
710       emit_jump_insn (gen_sne (operands[0]));
711       DONE;
712     }
713   else if (TARGET_V9)
714     {
715       if (gen_v9_scc (LT, operands))
716         DONE;
717       /* fall through */
718     }
719   FAIL;
722 (define_expand "sge"
723   [(set (match_operand:SI 0 "int_register_operand" "")
724         (ge:SI (match_dup 1) (const_int 0)))]
725   ""
727   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
728     {
729       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
730       emit_jump_insn (gen_sne (operands[0]));
731       DONE;
732     }
733   else if (TARGET_V9)
734     {
735       if (gen_v9_scc (GE, operands))
736         DONE;
737       /* fall through */
738     }
739   FAIL;
742 (define_expand "sle"
743   [(set (match_operand:SI 0 "int_register_operand" "")
744         (le:SI (match_dup 1) (const_int 0)))]
745   ""
747   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
748     {
749       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
750       emit_jump_insn (gen_sne (operands[0]));
751       DONE;
752     }
753   else if (TARGET_V9)
754     {
755       if (gen_v9_scc (LE, operands))
756         DONE;
757       /* fall through */
758     }
759   FAIL;
762 (define_expand "sgtu"
763   [(set (match_operand:SI 0 "int_register_operand" "")
764         (gtu:SI (match_dup 1) (const_int 0)))]
765   ""
767   if (! TARGET_V9)
768     {
769       rtx tem, pat;
771       /* We can do ltu easily, so if both operands are registers, swap them and
772          do a LTU.  */
773       if ((GET_CODE (sparc_compare_op0) == REG
774            || GET_CODE (sparc_compare_op0) == SUBREG)
775           && (GET_CODE (sparc_compare_op1) == REG
776               || GET_CODE (sparc_compare_op1) == SUBREG))
777         {
778           tem = sparc_compare_op0;
779           sparc_compare_op0 = sparc_compare_op1;
780           sparc_compare_op1 = tem;
781           pat = gen_sltu (operands[0]);
782           if (pat == NULL_RTX)
783             FAIL;
784           emit_insn (pat);
785           DONE;
786         }
787     }
788   else
789     {
790       if (gen_v9_scc (GTU, operands))
791         DONE;
792     }
793   FAIL;
796 (define_expand "sltu"
797   [(set (match_operand:SI 0 "int_register_operand" "")
798         (ltu:SI (match_dup 1) (const_int 0)))]
799   ""
801   if (TARGET_V9)
802     {
803       if (gen_v9_scc (LTU, operands))
804         DONE;
805     }
806   operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
809 (define_expand "sgeu"
810   [(set (match_operand:SI 0 "int_register_operand" "")
811         (geu:SI (match_dup 1) (const_int 0)))]
812   ""
814   if (TARGET_V9)
815     {
816       if (gen_v9_scc (GEU, operands))
817         DONE;
818     }
819   operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
822 (define_expand "sleu"
823   [(set (match_operand:SI 0 "int_register_operand" "")
824         (leu:SI (match_dup 1) (const_int 0)))]
825   ""
827   if (! TARGET_V9)
828     {
829       rtx tem, pat;
831       /* We can do geu easily, so if both operands are registers, swap them and
832          do a GEU.  */
833       if ((GET_CODE (sparc_compare_op0) == REG
834            || GET_CODE (sparc_compare_op0) == SUBREG)
835           && (GET_CODE (sparc_compare_op1) == REG
836               || GET_CODE (sparc_compare_op1) == SUBREG))
837         {
838           tem = sparc_compare_op0;
839           sparc_compare_op0 = sparc_compare_op1;
840           sparc_compare_op1 = tem;
841           pat = gen_sgeu (operands[0]);
842           if (pat == NULL_RTX)
843             FAIL;
844           emit_insn (pat);
845           DONE;
846         }
847     }
848   else
849     {
850       if (gen_v9_scc (LEU, operands))
851         DONE;
852     }
853   FAIL;
856 ;; Now the DEFINE_INSNs for the scc cases.
858 ;; The SEQ and SNE patterns are special because they can be done
859 ;; without any branching and do not involve a COMPARE.  We want
860 ;; them to always use the splits below so the results can be
861 ;; scheduled.
863 (define_insn_and_split "*snesi_zero"
864   [(set (match_operand:SI 0 "register_operand" "=r")
865         (ne:SI (match_operand:SI 1 "register_operand" "r")
866                (const_int 0)))
867    (clobber (reg:CC 100))]
868   ""
869   "#"
870   ""
871   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
872                                            (const_int 0)))
873    (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))]
874   ""
875   [(set_attr "length" "2")])
877 (define_insn_and_split "*neg_snesi_zero"
878   [(set (match_operand:SI 0 "register_operand" "=r")
879         (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
880                        (const_int 0))))
881    (clobber (reg:CC 100))]
882   ""
883   "#"
884   ""
885   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
886                                            (const_int 0)))
887    (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
888   ""
889   [(set_attr "length" "2")])
891 (define_insn_and_split "*snesi_zero_extend"
892   [(set (match_operand:DI 0 "register_operand" "=r")
893         (ne:DI (match_operand:SI 1 "register_operand" "r")
894                (const_int 0)))
895    (clobber (reg:CC 100))]
896   "TARGET_ARCH64"
897   "#"
898   "&& 1"
899   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
900                                                      (match_dup 1))
901                                            (const_int 0)))
902    (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
903                                                         (const_int 0))
904                                                (ltu:SI (reg:CC_NOOV 100)
905                                                        (const_int 0)))))]
906   ""
907   [(set_attr "length" "2")])
909 (define_insn_and_split "*snedi_zero"
910   [(set (match_operand:DI 0 "register_operand" "=&r")
911         (ne:DI (match_operand:DI 1 "register_operand" "r")
912                (const_int 0)))]
913   "TARGET_ARCH64"
914   "#"
915   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
916   [(set (match_dup 0) (const_int 0))
917    (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
918                                               (const_int 0))
919                                        (const_int 1)
920                                        (match_dup 0)))]
921   ""
922   [(set_attr "length" "2")])
924 (define_insn_and_split "*neg_snedi_zero"
925   [(set (match_operand:DI 0 "register_operand" "=&r")
926         (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
927                        (const_int 0))))]
928   "TARGET_ARCH64"
929   "#"
930   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
931   [(set (match_dup 0) (const_int 0))
932    (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
933                                               (const_int 0))
934                                        (const_int -1)
935                                        (match_dup 0)))]
936   ""
937   [(set_attr "length" "2")])
939 (define_insn_and_split "*snedi_zero_trunc"
940   [(set (match_operand:SI 0 "register_operand" "=&r")
941         (ne:SI (match_operand:DI 1 "register_operand" "r")
942                (const_int 0)))]
943   "TARGET_ARCH64"
944   "#"
945   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
946   [(set (match_dup 0) (const_int 0))
947    (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
948                                               (const_int 0))
949                                        (const_int 1)
950                                        (match_dup 0)))]
951   ""
952   [(set_attr "length" "2")])
954 (define_insn_and_split "*seqsi_zero"
955   [(set (match_operand:SI 0 "register_operand" "=r")
956         (eq:SI (match_operand:SI 1 "register_operand" "r")
957                (const_int 0)))
958    (clobber (reg:CC 100))]
959   ""
960   "#"
961   ""
962   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
963                                            (const_int 0)))
964    (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))]
965   ""
966   [(set_attr "length" "2")])
968 (define_insn_and_split "*neg_seqsi_zero"
969   [(set (match_operand:SI 0 "register_operand" "=r")
970         (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
971                        (const_int 0))))
972    (clobber (reg:CC 100))]
973   ""
974   "#"
975   ""
976   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
977                                            (const_int 0)))
978    (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
979   ""
980   [(set_attr "length" "2")])
982 (define_insn_and_split "*seqsi_zero_extend"
983   [(set (match_operand:DI 0 "register_operand" "=r")
984         (eq:DI (match_operand:SI 1 "register_operand" "r")
985                (const_int 0)))
986    (clobber (reg:CC 100))]
987   "TARGET_ARCH64"
988   "#"
989   "&& 1"
990   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
991                                                      (match_dup 1))
992                                            (const_int 0)))
993    (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
994                                                           (const_int -1))
995                                                 (ltu:SI (reg:CC_NOOV 100)
996                                                         (const_int 0)))))]
997   ""
998   [(set_attr "length" "2")])
1000 (define_insn_and_split "*seqdi_zero"
1001   [(set (match_operand:DI 0 "register_operand" "=&r")
1002         (eq:DI (match_operand:DI 1 "register_operand" "r")
1003                (const_int 0)))]
1004   "TARGET_ARCH64"
1005   "#"
1006   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1007   [(set (match_dup 0) (const_int 0))
1008    (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1009                                               (const_int 0))
1010                                        (const_int 1)
1011                                        (match_dup 0)))]
1012   ""
1013   [(set_attr "length" "2")])
1015 (define_insn_and_split "*neg_seqdi_zero"
1016   [(set (match_operand:DI 0 "register_operand" "=&r")
1017         (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
1018                        (const_int 0))))]
1019   "TARGET_ARCH64"
1020   "#"
1021   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1022   [(set (match_dup 0) (const_int 0))
1023    (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1024                                               (const_int 0))
1025                                        (const_int -1)
1026                                        (match_dup 0)))]
1027   ""
1028   [(set_attr "length" "2")]) 
1030 (define_insn_and_split "*seqdi_zero_trunc"
1031   [(set (match_operand:SI 0 "register_operand" "=&r")
1032         (eq:SI (match_operand:DI 1 "register_operand" "r")
1033                (const_int 0)))]
1034   "TARGET_ARCH64"
1035   "#"
1036   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1037   [(set (match_dup 0) (const_int 0))
1038    (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
1039                                               (const_int 0))
1040                                        (const_int 1)
1041                                        (match_dup 0)))]
1042   ""
1043   [(set_attr "length" "2")])
1045 ;; We can also do (x + (i == 0)) and related, so put them in.
1046 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1047 ;; versions for v9.
1049 (define_insn_and_split "*x_plus_i_ne_0"
1050   [(set (match_operand:SI 0 "register_operand" "=r")
1051         (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
1052                         (const_int 0))
1053                  (match_operand:SI 2 "register_operand" "r")))
1054    (clobber (reg:CC 100))]
1055   ""
1056   "#"
1057   ""
1058   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1059                                            (const_int 0)))
1060    (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1061                                (match_dup 2)))]
1062   ""
1063   [(set_attr "length" "2")])
1065 (define_insn_and_split "*x_minus_i_ne_0"
1066   [(set (match_operand:SI 0 "register_operand" "=r")
1067         (minus:SI (match_operand:SI 2 "register_operand" "r")
1068                   (ne:SI (match_operand:SI 1 "register_operand" "r")
1069                          (const_int 0))))
1070    (clobber (reg:CC 100))]
1071   ""
1072   "#"
1073   ""
1074   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1075                                            (const_int 0)))
1076    (set (match_dup 0) (minus:SI (match_dup 2)
1077                                 (ltu:SI (reg:CC 100) (const_int 0))))]
1078   ""
1079   [(set_attr "length" "2")])
1081 (define_insn_and_split "*x_plus_i_eq_0"
1082   [(set (match_operand:SI 0 "register_operand" "=r")
1083         (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1084                         (const_int 0))
1085                  (match_operand:SI 2 "register_operand" "r")))
1086    (clobber (reg:CC 100))]
1087   ""
1088   "#"
1089   ""
1090   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1091                                            (const_int 0)))
1092    (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1093                                (match_dup 2)))]
1094   ""
1095   [(set_attr "length" "2")])
1097 (define_insn_and_split "*x_minus_i_eq_0"
1098   [(set (match_operand:SI 0 "register_operand" "=r")
1099         (minus:SI (match_operand:SI 2 "register_operand" "r")
1100                   (eq:SI (match_operand:SI 1 "register_operand" "r")
1101                          (const_int 0))))
1102    (clobber (reg:CC 100))]
1103   ""
1104   "#"
1105   ""
1106   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1107                                            (const_int 0)))
1108    (set (match_dup 0) (minus:SI (match_dup 2)
1109                                 (geu:SI (reg:CC 100) (const_int 0))))]
1110   ""
1111   [(set_attr "length" "2")])
1113 ;; We can also do GEU and LTU directly, but these operate after a compare.
1114 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1115 ;; versions for v9.
1117 (define_insn "*sltu_insn"
1118   [(set (match_operand:SI 0 "register_operand" "=r")
1119         (ltu:SI (reg:CC 100) (const_int 0)))]
1120   ""
1121   "addx\t%%g0, 0, %0"
1122   [(set_attr "type" "ialuX")])
1124 (define_insn "*neg_sltu_insn"
1125   [(set (match_operand:SI 0 "register_operand" "=r")
1126         (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1127   ""
1128   "subx\t%%g0, 0, %0"
1129   [(set_attr "type" "ialuX")])
1131 ;; ??? Combine should canonicalize these next two to the same pattern.
1132 (define_insn "*neg_sltu_minus_x"
1133   [(set (match_operand:SI 0 "register_operand" "=r")
1134         (minus:SI (neg:SI (ltu:SI (reg:CC 100) (const_int 0)))
1135                   (match_operand:SI 1 "arith_operand" "rI")))]
1136   ""
1137   "subx\t%%g0, %1, %0"
1138   [(set_attr "type" "ialuX")])
1140 (define_insn "*neg_sltu_plus_x"
1141   [(set (match_operand:SI 0 "register_operand" "=r")
1142         (neg:SI (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1143                          (match_operand:SI 1 "arith_operand" "rI"))))]
1144   ""
1145   "subx\t%%g0, %1, %0"
1146   [(set_attr "type" "ialuX")])
1148 (define_insn "*sgeu_insn"
1149   [(set (match_operand:SI 0 "register_operand" "=r")
1150         (geu:SI (reg:CC 100) (const_int 0)))]
1151   ""
1152   "subx\t%%g0, -1, %0"
1153   [(set_attr "type" "ialuX")])
1155 (define_insn "*neg_sgeu_insn"
1156   [(set (match_operand:SI 0 "register_operand" "=r")
1157         (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1158   ""
1159   "addx\t%%g0, -1, %0"
1160   [(set_attr "type" "ialuX")])
1162 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
1163 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1164 ;; versions for v9.
1166 (define_insn "*sltu_plus_x"
1167   [(set (match_operand:SI 0 "register_operand" "=r")
1168         (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1169                  (match_operand:SI 1 "arith_operand" "rI")))]
1170   ""
1171   "addx\t%%g0, %1, %0"
1172   [(set_attr "type" "ialuX")])
1174 (define_insn "*sltu_plus_x_plus_y"
1175   [(set (match_operand:SI 0 "register_operand" "=r")
1176         (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1177                  (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1178                           (match_operand:SI 2 "arith_operand" "rI"))))]
1179   ""
1180   "addx\t%1, %2, %0"
1181   [(set_attr "type" "ialuX")])
1183 (define_insn "*x_minus_sltu"
1184   [(set (match_operand:SI 0 "register_operand" "=r")
1185         (minus:SI (match_operand:SI 1 "register_operand" "r")
1186                   (ltu:SI (reg:CC 100) (const_int 0))))]
1187   ""
1188   "subx\t%1, 0, %0"
1189   [(set_attr "type" "ialuX")])
1191 ;; ??? Combine should canonicalize these next two to the same pattern.
1192 (define_insn "*x_minus_y_minus_sltu"
1193   [(set (match_operand:SI 0 "register_operand" "=r")
1194         (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
1195                             (match_operand:SI 2 "arith_operand" "rI"))
1196                   (ltu:SI (reg:CC 100) (const_int 0))))]
1197   ""
1198   "subx\t%r1, %2, %0"
1199   [(set_attr "type" "ialuX")])
1201 (define_insn "*x_minus_sltu_plus_y"
1202   [(set (match_operand:SI 0 "register_operand" "=r")
1203         (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
1204                   (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1205                            (match_operand:SI 2 "arith_operand" "rI"))))]
1206   ""
1207   "subx\t%r1, %2, %0"
1208   [(set_attr "type" "ialuX")])
1210 (define_insn "*sgeu_plus_x"
1211   [(set (match_operand:SI 0 "register_operand" "=r")
1212         (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1213                  (match_operand:SI 1 "register_operand" "r")))]
1214   ""
1215   "subx\t%1, -1, %0"
1216   [(set_attr "type" "ialuX")])
1218 (define_insn "*x_minus_sgeu"
1219   [(set (match_operand:SI 0 "register_operand" "=r")
1220         (minus:SI (match_operand:SI 1 "register_operand" "r")
1221                   (geu:SI (reg:CC 100) (const_int 0))))]
1222   ""
1223   "addx\t%1, -1, %0"
1224   [(set_attr "type" "ialuX")])
1226 (define_split
1227   [(set (match_operand:SI 0 "register_operand" "")
1228         (match_operator:SI 2 "noov_compare_operator"
1229                            [(match_operand 1 "icc_or_fcc_register_operand" "")
1230                             (const_int 0)]))]
1231   "TARGET_V9
1232    && REGNO (operands[1]) == SPARC_ICC_REG
1233    && (GET_MODE (operands[1]) == CCXmode
1234        /* 32 bit LTU/GEU are better implemented using addx/subx.  */
1235        || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1236   [(set (match_dup 0) (const_int 0))
1237    (set (match_dup 0)
1238         (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1239                          (const_int 1)
1240                          (match_dup 0)))]
1241   "")
1244 ;; These control RTL generation for conditional jump insns
1246 ;; The quad-word fp compare library routines all return nonzero to indicate
1247 ;; true, which is different from the equivalent libgcc routines, so we must
1248 ;; handle them specially here.
1250 (define_expand "beq"
1251   [(set (pc)
1252         (if_then_else (eq (match_dup 1) (const_int 0))
1253                       (label_ref (match_operand 0 "" ""))
1254                       (pc)))]
1255   ""
1257   if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1258       && GET_CODE (sparc_compare_op0) == REG
1259       && GET_MODE (sparc_compare_op0) == DImode)
1260     {
1261       emit_v9_brxx_insn (EQ, sparc_compare_op0, operands[0]);
1262       DONE;
1263     }
1264   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1265     {
1266       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
1267       emit_jump_insn (gen_bne (operands[0]));
1268       DONE;
1269     }
1270   operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1);
1273 (define_expand "bne"
1274   [(set (pc)
1275         (if_then_else (ne (match_dup 1) (const_int 0))
1276                       (label_ref (match_operand 0 "" ""))
1277                       (pc)))]
1278   ""
1280   if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1281       && GET_CODE (sparc_compare_op0) == REG
1282       && GET_MODE (sparc_compare_op0) == DImode)
1283     {
1284       emit_v9_brxx_insn (NE, sparc_compare_op0, operands[0]);
1285       DONE;
1286     }
1287   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1288     {
1289       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
1290       emit_jump_insn (gen_bne (operands[0]));
1291       DONE;
1292     }
1293   operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1);
1296 (define_expand "bgt"
1297   [(set (pc)
1298         (if_then_else (gt (match_dup 1) (const_int 0))
1299                       (label_ref (match_operand 0 "" ""))
1300                       (pc)))]
1301   ""
1303   if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1304       && GET_CODE (sparc_compare_op0) == REG
1305       && GET_MODE (sparc_compare_op0) == DImode)
1306     {
1307       emit_v9_brxx_insn (GT, sparc_compare_op0, operands[0]);
1308       DONE;
1309     }
1310   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1311     {
1312       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
1313       emit_jump_insn (gen_bne (operands[0]));
1314       DONE;
1315     }
1316   operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1);
1319 (define_expand "bgtu"
1320   [(set (pc)
1321         (if_then_else (gtu (match_dup 1) (const_int 0))
1322                       (label_ref (match_operand 0 "" ""))
1323                       (pc)))]
1324   ""
1326   operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1);
1329 (define_expand "blt"
1330   [(set (pc)
1331         (if_then_else (lt (match_dup 1) (const_int 0))
1332                       (label_ref (match_operand 0 "" ""))
1333                       (pc)))]
1334   ""
1336   if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1337       && GET_CODE (sparc_compare_op0) == REG
1338       && GET_MODE (sparc_compare_op0) == DImode)
1339     {
1340       emit_v9_brxx_insn (LT, sparc_compare_op0, operands[0]);
1341       DONE;
1342     }
1343   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1344     {
1345       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
1346       emit_jump_insn (gen_bne (operands[0]));
1347       DONE;
1348     }
1349   operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1);
1352 (define_expand "bltu"
1353   [(set (pc)
1354         (if_then_else (ltu (match_dup 1) (const_int 0))
1355                       (label_ref (match_operand 0 "" ""))
1356                       (pc)))]
1357   ""
1359   operands[1] = gen_compare_reg (LTU, sparc_compare_op0, sparc_compare_op1);
1362 (define_expand "bge"
1363   [(set (pc)
1364         (if_then_else (ge (match_dup 1) (const_int 0))
1365                       (label_ref (match_operand 0 "" ""))
1366                       (pc)))]
1367   ""
1369   if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1370       && GET_CODE (sparc_compare_op0) == REG
1371       && GET_MODE (sparc_compare_op0) == DImode)
1372     {
1373       emit_v9_brxx_insn (GE, sparc_compare_op0, operands[0]);
1374       DONE;
1375     }
1376   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1377     {
1378       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
1379       emit_jump_insn (gen_bne (operands[0]));
1380       DONE;
1381     }
1382   operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1);
1385 (define_expand "bgeu"
1386   [(set (pc)
1387         (if_then_else (geu (match_dup 1) (const_int 0))
1388                       (label_ref (match_operand 0 "" ""))
1389                       (pc)))]
1390   ""
1392   operands[1] = gen_compare_reg (GEU, sparc_compare_op0, sparc_compare_op1);
1395 (define_expand "ble"
1396   [(set (pc)
1397         (if_then_else (le (match_dup 1) (const_int 0))
1398                       (label_ref (match_operand 0 "" ""))
1399                       (pc)))]
1400   ""
1402   if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1403       && GET_CODE (sparc_compare_op0) == REG
1404       && GET_MODE (sparc_compare_op0) == DImode)
1405     {
1406       emit_v9_brxx_insn (LE, sparc_compare_op0, operands[0]);
1407       DONE;
1408     }
1409   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1410     {
1411       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
1412       emit_jump_insn (gen_bne (operands[0]));
1413       DONE;
1414     }
1415   operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1);
1418 (define_expand "bleu"
1419   [(set (pc)
1420         (if_then_else (leu (match_dup 1) (const_int 0))
1421                       (label_ref (match_operand 0 "" ""))
1422                       (pc)))]
1423   ""
1425   operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1);
1428 (define_expand "bunordered"
1429   [(set (pc)
1430         (if_then_else (unordered (match_dup 1) (const_int 0))
1431                       (label_ref (match_operand 0 "" ""))
1432                       (pc)))]
1433   ""
1435   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1436     {
1437       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1,
1438                                 UNORDERED);
1439       emit_jump_insn (gen_beq (operands[0]));
1440       DONE;
1441     }
1442   operands[1] = gen_compare_reg (UNORDERED, sparc_compare_op0,
1443                                  sparc_compare_op1);
1446 (define_expand "bordered"
1447   [(set (pc)
1448         (if_then_else (ordered (match_dup 1) (const_int 0))
1449                       (label_ref (match_operand 0 "" ""))
1450                       (pc)))]
1451   ""
1453   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1454     {
1455       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, ORDERED);
1456       emit_jump_insn (gen_bne (operands[0]));
1457       DONE;
1458     }
1459   operands[1] = gen_compare_reg (ORDERED, sparc_compare_op0,
1460                                  sparc_compare_op1);
1463 (define_expand "bungt"
1464   [(set (pc)
1465         (if_then_else (ungt (match_dup 1) (const_int 0))
1466                       (label_ref (match_operand 0 "" ""))
1467                       (pc)))]
1468   ""
1470   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1471     {
1472       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGT);
1473       emit_jump_insn (gen_bgt (operands[0]));
1474       DONE;
1475     }
1476   operands[1] = gen_compare_reg (UNGT, sparc_compare_op0, sparc_compare_op1);
1479 (define_expand "bunlt"
1480   [(set (pc)
1481         (if_then_else (unlt (match_dup 1) (const_int 0))
1482                       (label_ref (match_operand 0 "" ""))
1483                       (pc)))]
1484   ""
1486   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1487     {
1488       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLT);
1489       emit_jump_insn (gen_bne (operands[0]));
1490       DONE;
1491     }
1492   operands[1] = gen_compare_reg (UNLT, sparc_compare_op0, sparc_compare_op1);
1495 (define_expand "buneq"
1496   [(set (pc)
1497         (if_then_else (uneq (match_dup 1) (const_int 0))
1498                       (label_ref (match_operand 0 "" ""))
1499                       (pc)))]
1500   ""
1502   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1503     {
1504       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNEQ);
1505       emit_jump_insn (gen_beq (operands[0]));
1506       DONE;
1507     }
1508   operands[1] = gen_compare_reg (UNEQ, sparc_compare_op0, sparc_compare_op1);
1511 (define_expand "bunge"
1512   [(set (pc)
1513         (if_then_else (unge (match_dup 1) (const_int 0))
1514                       (label_ref (match_operand 0 "" ""))
1515                       (pc)))]
1516   ""
1518   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1519     {
1520       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGE);
1521       emit_jump_insn (gen_bne (operands[0]));
1522       DONE;
1523     }
1524   operands[1] = gen_compare_reg (UNGE, sparc_compare_op0, sparc_compare_op1);
1527 (define_expand "bunle"
1528   [(set (pc)
1529         (if_then_else (unle (match_dup 1) (const_int 0))
1530                       (label_ref (match_operand 0 "" ""))
1531                       (pc)))]
1532   ""
1534   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1535     {
1536       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLE);
1537       emit_jump_insn (gen_bne (operands[0]));
1538       DONE;
1539     }
1540   operands[1] = gen_compare_reg (UNLE, sparc_compare_op0, sparc_compare_op1);
1543 (define_expand "bltgt"
1544   [(set (pc)
1545         (if_then_else (ltgt (match_dup 1) (const_int 0))
1546                       (label_ref (match_operand 0 "" ""))
1547                       (pc)))]
1548   ""
1550   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1551     {
1552       sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LTGT);
1553       emit_jump_insn (gen_bne (operands[0]));
1554       DONE;
1555     }
1556   operands[1] = gen_compare_reg (LTGT, sparc_compare_op0, sparc_compare_op1);
1559 ;; Now match both normal and inverted jump.
1561 ;; XXX fpcmp nop braindamage
1562 (define_insn "*normal_branch"
1563   [(set (pc)
1564         (if_then_else (match_operator 0 "noov_compare_operator"
1565                                       [(reg 100) (const_int 0)])
1566                       (label_ref (match_operand 1 "" ""))
1567                       (pc)))]
1568   ""
1570   return output_cbranch (operands[0], operands[1], 1, 0,
1571                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1572                          insn);
1574   [(set_attr "type" "branch")
1575    (set_attr "branch_type" "icc")])
1577 ;; XXX fpcmp nop braindamage
1578 (define_insn "*inverted_branch"
1579   [(set (pc)
1580         (if_then_else (match_operator 0 "noov_compare_operator"
1581                                       [(reg 100) (const_int 0)])
1582                       (pc)
1583                       (label_ref (match_operand 1 "" ""))))]
1584   ""
1586   return output_cbranch (operands[0], operands[1], 1, 1,
1587                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1588                          insn);
1590   [(set_attr "type" "branch")
1591    (set_attr "branch_type" "icc")])
1593 ;; XXX fpcmp nop braindamage
1594 (define_insn "*normal_fp_branch"
1595   [(set (pc)
1596         (if_then_else (match_operator 1 "comparison_operator"
1597                                       [(match_operand:CCFP 0 "fcc_register_operand" "c")
1598                                        (const_int 0)])
1599                       (label_ref (match_operand 2 "" ""))
1600                       (pc)))]
1601   ""
1603   return output_cbranch (operands[1], operands[2], 2, 0,
1604                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1605                          insn);
1607   [(set_attr "type" "branch")
1608    (set_attr "branch_type" "fcc")])
1610 ;; XXX fpcmp nop braindamage
1611 (define_insn "*inverted_fp_branch"
1612   [(set (pc)
1613         (if_then_else (match_operator 1 "comparison_operator"
1614                                       [(match_operand:CCFP 0 "fcc_register_operand" "c")
1615                                        (const_int 0)])
1616                       (pc)
1617                       (label_ref (match_operand 2 "" ""))))]
1618   ""
1620   return output_cbranch (operands[1], operands[2], 2, 1,
1621                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1622                          insn);
1624   [(set_attr "type" "branch")
1625    (set_attr "branch_type" "fcc")])
1627 ;; XXX fpcmp nop braindamage
1628 (define_insn "*normal_fpe_branch"
1629   [(set (pc)
1630         (if_then_else (match_operator 1 "comparison_operator"
1631                                       [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1632                                        (const_int 0)])
1633                       (label_ref (match_operand 2 "" ""))
1634                       (pc)))]
1635   ""
1637   return output_cbranch (operands[1], operands[2], 2, 0,
1638                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1639                          insn);
1641   [(set_attr "type" "branch")
1642    (set_attr "branch_type" "fcc")])
1644 ;; XXX fpcmp nop braindamage
1645 (define_insn "*inverted_fpe_branch"
1646   [(set (pc)
1647         (if_then_else (match_operator 1 "comparison_operator"
1648                                       [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1649                                        (const_int 0)])
1650                       (pc)
1651                       (label_ref (match_operand 2 "" ""))))]
1652   ""
1654   return output_cbranch (operands[1], operands[2], 2, 1,
1655                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1656                          insn);
1658   [(set_attr "type" "branch")
1659    (set_attr "branch_type" "fcc")])
1661 ;; SPARC V9-specific jump insns.  None of these are guaranteed to be
1662 ;; in the architecture.
1664 ;; There are no 32 bit brreg insns.
1666 ;; XXX
1667 (define_insn "*normal_int_branch_sp64"
1668   [(set (pc)
1669         (if_then_else (match_operator 0 "v9_register_compare_operator"
1670                                       [(match_operand:DI 1 "register_operand" "r")
1671                                        (const_int 0)])
1672                       (label_ref (match_operand 2 "" ""))
1673                       (pc)))]
1674   "TARGET_ARCH64"
1676   return output_v9branch (operands[0], operands[2], 1, 2, 0,
1677                           final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1678                           insn);
1680   [(set_attr "type" "branch")
1681    (set_attr "branch_type" "reg")])
1683 ;; XXX
1684 (define_insn "*inverted_int_branch_sp64"
1685   [(set (pc)
1686         (if_then_else (match_operator 0 "v9_register_compare_operator"
1687                                       [(match_operand:DI 1 "register_operand" "r")
1688                                        (const_int 0)])
1689                       (pc)
1690                       (label_ref (match_operand 2 "" ""))))]
1691   "TARGET_ARCH64"
1693   return output_v9branch (operands[0], operands[2], 1, 2, 1,
1694                           final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1695                           insn);
1697   [(set_attr "type" "branch")
1698    (set_attr "branch_type" "reg")])
1701 (define_mode_macro P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1703 ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic
1704 ;; value subject to a PC-relative relocation.  Operand 2 is a helper function
1705 ;; that adds the PC value at the call point to operand 0.
1707 (define_insn "load_pcrel_sym<P:mode>"
1708   [(set (match_operand:P 0 "register_operand" "=r")
1709         (unspec:P [(match_operand:P 1 "symbolic_operand" "")
1710                    (match_operand:P 2 "call_address_operand" "")] UNSPEC_LOAD_PCREL_SYM))
1711    (clobber (reg:P 15))]
1712   ""
1714   if (flag_delayed_branch)
1715     return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0";
1716   else
1717     return "sethi\t%%hi(%a1-8), %0\n\tadd\t%0, %%lo(%a1-4), %0\n\tcall\t%a2\n\t nop";
1719   [(set (attr "type") (const_string "multi"))
1720    (set (attr "length")
1721         (if_then_else (eq_attr "delayed_branch" "true")
1722                       (const_int 3)
1723                       (const_int 4)))])
1726 ;; Integer move instructions
1728 (define_expand "movqi"
1729   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1730         (match_operand:QI 1 "general_operand" ""))]
1731   ""
1733   if (sparc_expand_move (QImode, operands))
1734     DONE;
1737 (define_insn "*movqi_insn"
1738   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1739         (match_operand:QI 1 "input_operand"   "rI,m,rJ"))]
1740   "(register_operand (operands[0], QImode)
1741     || register_or_zero_operand (operands[1], QImode))"
1742   "@
1743    mov\t%1, %0
1744    ldub\t%1, %0
1745    stb\t%r1, %0"
1746   [(set_attr "type" "*,load,store")
1747    (set_attr "us3load_type" "*,3cycle,*")])
1749 (define_expand "movhi"
1750   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1751         (match_operand:HI 1 "general_operand" ""))]
1752   ""
1754   if (sparc_expand_move (HImode, operands))
1755     DONE;
1758 (define_insn "*movhi_insn"
1759   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1760         (match_operand:HI 1 "input_operand"   "rI,K,m,rJ"))]
1761   "(register_operand (operands[0], HImode)
1762     || register_or_zero_operand (operands[1], HImode))"
1763   "@
1764    mov\t%1, %0
1765    sethi\t%%hi(%a1), %0
1766    lduh\t%1, %0
1767    sth\t%r1, %0"
1768   [(set_attr "type" "*,*,load,store")
1769    (set_attr "us3load_type" "*,*,3cycle,*")])
1771 ;; We always work with constants here.
1772 (define_insn "*movhi_lo_sum"
1773   [(set (match_operand:HI 0 "register_operand" "=r")
1774         (ior:HI (match_operand:HI 1 "register_operand" "%r")
1775                 (match_operand:HI 2 "small_int_operand" "I")))]
1776   ""
1777   "or\t%1, %2, %0")
1779 (define_expand "movsi"
1780   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1781         (match_operand:SI 1 "general_operand" ""))]
1782   ""
1784   if (sparc_expand_move (SImode, operands))
1785     DONE;
1788 (define_insn "*movsi_insn"
1789   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m,!f,!f,!m,d")
1790         (match_operand:SI 1 "input_operand"   "rI,K,m,rJ,f,m,f,J"))]
1791   "(register_operand (operands[0], SImode)
1792     || register_or_zero_operand (operands[1], SImode))"
1793   "@
1794    mov\t%1, %0
1795    sethi\t%%hi(%a1), %0
1796    ld\t%1, %0
1797    st\t%r1, %0
1798    fmovs\t%1, %0
1799    ld\t%1, %0
1800    st\t%1, %0
1801    fzeros\t%0"
1802   [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga")])
1804 (define_insn "*movsi_lo_sum"
1805   [(set (match_operand:SI 0 "register_operand" "=r")
1806         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1807                    (match_operand:SI 2 "immediate_operand" "in")))]
1808   ""
1809   "or\t%1, %%lo(%a2), %0")
1811 (define_insn "*movsi_high"
1812   [(set (match_operand:SI 0 "register_operand" "=r")
1813         (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1814   ""
1815   "sethi\t%%hi(%a1), %0")
1817 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1818 ;; so that CSE won't optimize the address computation away.
1819 (define_insn "movsi_lo_sum_pic"
1820   [(set (match_operand:SI 0 "register_operand" "=r")
1821         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1822                    (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1823   "flag_pic"
1824   "or\t%1, %%lo(%a2), %0")
1826 (define_insn "movsi_high_pic"
1827   [(set (match_operand:SI 0 "register_operand" "=r")
1828         (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1829   "flag_pic && check_pic (1)"
1830   "sethi\t%%hi(%a1), %0")
1832 (define_expand "movsi_pic_label_ref"
1833   [(set (match_dup 3) (high:SI
1834      (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1835                  (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1836    (set (match_dup 4) (lo_sum:SI (match_dup 3)
1837      (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1838    (set (match_operand:SI 0 "register_operand" "=r")
1839         (minus:SI (match_dup 5) (match_dup 4)))]
1840   "flag_pic"
1842   current_function_uses_pic_offset_table = 1;
1843   operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1844   if (no_new_pseudos)
1845     {
1846       operands[3] = operands[0];
1847       operands[4] = operands[0];
1848     }
1849   else
1850     {
1851       operands[3] = gen_reg_rtx (SImode);
1852       operands[4] = gen_reg_rtx (SImode);
1853     }
1854   operands[5] = pic_offset_table_rtx;
1857 (define_insn "*movsi_high_pic_label_ref"
1858   [(set (match_operand:SI 0 "register_operand" "=r")
1859       (high:SI
1860         (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1861                     (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1862   "flag_pic"
1863   "sethi\t%%hi(%a2-(%a1-.)), %0")
1865 (define_insn "*movsi_lo_sum_pic_label_ref"
1866   [(set (match_operand:SI 0 "register_operand" "=r")
1867       (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1868         (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
1869                     (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1870   "flag_pic"
1871   "or\t%1, %%lo(%a3-(%a2-.)), %0")
1873 (define_expand "movdi"
1874   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1875         (match_operand:DI 1 "general_operand" ""))]
1876   ""
1878   if (sparc_expand_move (DImode, operands))
1879     DONE;
1882 ;; Be careful, fmovd does not exist when !v9.
1883 ;; We match MEM moves directly when we have correct even
1884 ;; numbered registers, but fall into splits otherwise.
1885 ;; The constraint ordering here is really important to
1886 ;; avoid insane problems in reload, especially for patterns
1887 ;; of the form:
1889 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
1890 ;;                       (const_int -5016)))
1891 ;;      (reg:DI 2 %g2))
1894 (define_insn "*movdi_insn_sp32"
1895   [(set (match_operand:DI 0 "nonimmediate_operand"
1896                                 "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
1897         (match_operand:DI 1 "input_operand"
1898                                 " J,U,T,r,o,i,r, f, T, o, f, f"))]
1899   "! TARGET_V9
1900    && (register_operand (operands[0], DImode)
1901        || register_or_zero_operand (operands[1], DImode))"
1902   "@
1903    #
1904    std\t%1, %0
1905    ldd\t%1, %0
1906    #
1907    #
1908    #
1909    #
1910    std\t%1, %0
1911    ldd\t%1, %0
1912    #
1913    #
1914    #"
1915   [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
1916    (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
1918 (define_insn "*movdi_insn_sp32_v9"
1919   [(set (match_operand:DI 0 "nonimmediate_operand"
1920                                         "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?e,?e,?W")
1921         (match_operand:DI 1 "input_operand"
1922                                         " J,J,U,T,r,o,i,r, f, T, o, f, e, W, e"))]
1923   "! TARGET_ARCH64
1924    && TARGET_V9
1925    && (register_operand (operands[0], DImode)
1926        || register_or_zero_operand (operands[1], DImode))"
1927   "@
1928    stx\t%%g0, %0
1929    #
1930    std\t%1, %0
1931    ldd\t%1, %0
1932    #
1933    #
1934    #
1935    #
1936    std\t%1, %0
1937    ldd\t%1, %0
1938    #
1939    #
1940    fmovd\\t%1, %0
1941    ldd\\t%1, %0
1942    std\\t%1, %0"
1943   [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,fpload,fpstore")
1944    (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,*,*")
1945    (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])
1947 (define_insn "*movdi_insn_sp64"
1948   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,m,?e,?e,?W,b")
1949         (match_operand:DI 1 "input_operand"   "rI,N,m,rJ,e,W,e,J"))]
1950   "TARGET_ARCH64
1951    && (register_operand (operands[0], DImode)
1952        || register_or_zero_operand (operands[1], DImode))"
1953   "@
1954    mov\t%1, %0
1955    sethi\t%%hi(%a1), %0
1956    ldx\t%1, %0
1957    stx\t%r1, %0
1958    fmovd\t%1, %0
1959    ldd\t%1, %0
1960    std\t%1, %0
1961    fzero\t%0"
1962   [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga")
1963    (set_attr "fptype" "*,*,*,*,double,*,*,double")])
1965 (define_expand "movdi_pic_label_ref"
1966   [(set (match_dup 3) (high:DI
1967      (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1968                  (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1969    (set (match_dup 4) (lo_sum:DI (match_dup 3)
1970      (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1971    (set (match_operand:DI 0 "register_operand" "=r")
1972         (minus:DI (match_dup 5) (match_dup 4)))]
1973   "TARGET_ARCH64 && flag_pic"
1975   current_function_uses_pic_offset_table = 1;
1976   operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1977   if (no_new_pseudos)
1978     {
1979       operands[3] = operands[0];
1980       operands[4] = operands[0];
1981     }
1982   else
1983     {
1984       operands[3] = gen_reg_rtx (DImode);
1985       operands[4] = gen_reg_rtx (DImode);
1986     }
1987   operands[5] = pic_offset_table_rtx;
1990 (define_insn "*movdi_high_pic_label_ref"
1991   [(set (match_operand:DI 0 "register_operand" "=r")
1992         (high:DI
1993           (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1994                       (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1995   "TARGET_ARCH64 && flag_pic"
1996   "sethi\t%%hi(%a2-(%a1-.)), %0")
1998 (define_insn "*movdi_lo_sum_pic_label_ref"
1999   [(set (match_operand:DI 0 "register_operand" "=r")
2000       (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2001         (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
2002                     (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2003   "TARGET_ARCH64 && flag_pic"
2004   "or\t%1, %%lo(%a3-(%a2-.)), %0")
2006 ;; SPARC-v9 code model support insns.  See sparc_emit_set_symbolic_const64
2007 ;; in sparc.c to see what is going on here... PIC stuff comes first.
2009 (define_insn "movdi_lo_sum_pic"
2010   [(set (match_operand:DI 0 "register_operand" "=r")
2011         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2012                    (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
2013   "TARGET_ARCH64 && flag_pic"
2014   "or\t%1, %%lo(%a2), %0")
2016 (define_insn "movdi_high_pic"
2017   [(set (match_operand:DI 0 "register_operand" "=r")
2018         (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
2019   "TARGET_ARCH64 && flag_pic && check_pic (1)"
2020   "sethi\t%%hi(%a1), %0")
2022 (define_insn "*sethi_di_medlow_embmedany_pic"
2023   [(set (match_operand:DI 0 "register_operand" "=r")
2024         (high:DI (match_operand:DI 1 "medium_pic_operand" "")))]
2025   "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
2026   "sethi\t%%hi(%a1), %0")
2028 (define_insn "*sethi_di_medlow"
2029   [(set (match_operand:DI 0 "register_operand" "=r")
2030         (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
2031   "TARGET_CM_MEDLOW && check_pic (1)"
2032   "sethi\t%%hi(%a1), %0")
2034 (define_insn "*losum_di_medlow"
2035   [(set (match_operand:DI 0 "register_operand" "=r")
2036         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2037                    (match_operand:DI 2 "symbolic_operand" "")))]
2038   "TARGET_CM_MEDLOW"
2039   "or\t%1, %%lo(%a2), %0")
2041 (define_insn "seth44"
2042   [(set (match_operand:DI 0 "register_operand" "=r")
2043         (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
2044   "TARGET_CM_MEDMID"
2045   "sethi\t%%h44(%a1), %0")
2047 (define_insn "setm44"
2048   [(set (match_operand:DI 0 "register_operand" "=r")
2049         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2050                    (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
2051   "TARGET_CM_MEDMID"
2052   "or\t%1, %%m44(%a2), %0")
2054 (define_insn "setl44"
2055   [(set (match_operand:DI 0 "register_operand" "=r")
2056         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2057                    (match_operand:DI 2 "symbolic_operand" "")))]
2058   "TARGET_CM_MEDMID"
2059   "or\t%1, %%l44(%a2), %0")
2061 (define_insn "sethh"
2062   [(set (match_operand:DI 0 "register_operand" "=r")
2063         (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
2064   "TARGET_CM_MEDANY"
2065   "sethi\t%%hh(%a1), %0")
2067 (define_insn "setlm"
2068   [(set (match_operand:DI 0 "register_operand" "=r")
2069         (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
2070   "TARGET_CM_MEDANY"
2071   "sethi\t%%lm(%a1), %0")
2073 (define_insn "sethm"
2074   [(set (match_operand:DI 0 "register_operand" "=r")
2075         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2076                    (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
2077   "TARGET_CM_MEDANY"
2078   "or\t%1, %%hm(%a2), %0")
2080 (define_insn "setlo"
2081   [(set (match_operand:DI 0 "register_operand" "=r")
2082         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2083                    (match_operand:DI 2 "symbolic_operand" "")))]
2084   "TARGET_CM_MEDANY"
2085   "or\t%1, %%lo(%a2), %0")
2087 (define_insn "embmedany_sethi"
2088   [(set (match_operand:DI 0 "register_operand" "=r")
2089         (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
2090   "TARGET_CM_EMBMEDANY && check_pic (1)"
2091   "sethi\t%%hi(%a1), %0")
2093 (define_insn "embmedany_losum"
2094   [(set (match_operand:DI 0 "register_operand" "=r")
2095         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2096                    (match_operand:DI 2 "data_segment_operand" "")))]
2097   "TARGET_CM_EMBMEDANY"
2098   "add\t%1, %%lo(%a2), %0")
2100 (define_insn "embmedany_brsum"
2101   [(set (match_operand:DI 0 "register_operand" "=r")
2102         (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
2103   "TARGET_CM_EMBMEDANY"
2104   "add\t%1, %_, %0")
2106 (define_insn "embmedany_textuhi"
2107   [(set (match_operand:DI 0 "register_operand" "=r")
2108         (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
2109   "TARGET_CM_EMBMEDANY && check_pic (1)"
2110   "sethi\t%%uhi(%a1), %0")
2112 (define_insn "embmedany_texthi"
2113   [(set (match_operand:DI 0 "register_operand" "=r")
2114         (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
2115   "TARGET_CM_EMBMEDANY && check_pic (1)"
2116   "sethi\t%%hi(%a1), %0")
2118 (define_insn "embmedany_textulo"
2119   [(set (match_operand:DI 0 "register_operand" "=r")
2120         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2121                    (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
2122   "TARGET_CM_EMBMEDANY"
2123   "or\t%1, %%ulo(%a2), %0")
2125 (define_insn "embmedany_textlo"
2126   [(set (match_operand:DI 0 "register_operand" "=r")
2127         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2128                    (match_operand:DI 2 "text_segment_operand" "")))]
2129   "TARGET_CM_EMBMEDANY"
2130   "or\t%1, %%lo(%a2), %0")
2132 ;; Now some patterns to help reload out a bit.
2133 (define_expand "reload_indi"
2134   [(parallel [(match_operand:DI 0 "register_operand" "=r")
2135               (match_operand:DI 1 "immediate_operand" "")
2136               (match_operand:TI 2 "register_operand" "=&r")])]
2137   "(TARGET_CM_MEDANY
2138     || TARGET_CM_EMBMEDANY)
2139    && ! flag_pic"
2141   sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2142   DONE;
2145 (define_expand "reload_outdi"
2146   [(parallel [(match_operand:DI 0 "register_operand" "=r")
2147               (match_operand:DI 1 "immediate_operand" "")
2148               (match_operand:TI 2 "register_operand" "=&r")])]
2149   "(TARGET_CM_MEDANY
2150     || TARGET_CM_EMBMEDANY)
2151    && ! flag_pic"
2153   sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2154   DONE;
2157 ;; Split up putting CONSTs and REGs into DI regs when !arch64
2158 (define_split
2159   [(set (match_operand:DI 0 "register_operand" "")
2160         (match_operand:DI 1 "const_int_operand" ""))]
2161   "! TARGET_ARCH64 && reload_completed"
2162   [(clobber (const_int 0))]
2164 #if HOST_BITS_PER_WIDE_INT == 32
2165   emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2166                         (INTVAL (operands[1]) < 0) ?
2167                         constm1_rtx :
2168                         const0_rtx));
2169   emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2170                         operands[1]));
2171 #else
2172   unsigned int low, high;
2174   low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
2175   high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
2176   emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
2178   /* Slick... but this trick loses if this subreg constant part
2179      can be done in one insn.  */
2180   if (low == high
2181       && ! SPARC_SETHI32_P (high)
2182       && ! SPARC_SIMM13_P (high))
2183     emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2184                           gen_highpart (SImode, operands[0])));
2185   else
2186     emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
2187 #endif
2188   DONE;
2191 (define_split
2192   [(set (match_operand:DI 0 "register_operand" "")
2193         (match_operand:DI 1 "const_double_operand" ""))]
2194   "reload_completed
2195    && (! TARGET_V9
2196        || (! TARGET_ARCH64
2197            && ((GET_CODE (operands[0]) == REG
2198                 && REGNO (operands[0]) < 32)
2199                || (GET_CODE (operands[0]) == SUBREG
2200                    && GET_CODE (SUBREG_REG (operands[0])) == REG
2201                    && REGNO (SUBREG_REG (operands[0])) < 32))))"
2202   [(clobber (const_int 0))]
2204   emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2205                         GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
2207   /* Slick... but this trick loses if this subreg constant part
2208      can be done in one insn.  */
2209   if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
2210       && ! SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
2211       && ! SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1])))
2212     {
2213       emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2214                             gen_highpart (SImode, operands[0])));
2215     }
2216   else
2217     {
2218       emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2219                             GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
2220     }
2221   DONE;
2224 (define_split
2225   [(set (match_operand:DI 0 "register_operand" "")
2226         (match_operand:DI 1 "register_operand" ""))]
2227   "reload_completed
2228    && (! TARGET_V9
2229        || (! TARGET_ARCH64
2230            && ((GET_CODE (operands[0]) == REG
2231                 && REGNO (operands[0]) < 32)
2232                || (GET_CODE (operands[0]) == SUBREG
2233                    && GET_CODE (SUBREG_REG (operands[0])) == REG
2234                    && REGNO (SUBREG_REG (operands[0])) < 32))))"
2235   [(clobber (const_int 0))]
2237   rtx set_dest = operands[0];
2238   rtx set_src = operands[1];
2239   rtx dest1, dest2;
2240   rtx src1, src2;
2242   dest1 = gen_highpart (SImode, set_dest);
2243   dest2 = gen_lowpart (SImode, set_dest);
2244   src1 = gen_highpart (SImode, set_src);
2245   src2 = gen_lowpart (SImode, set_src);
2247   /* Now emit using the real source and destination we found, swapping
2248      the order if we detect overlap.  */
2249   if (reg_overlap_mentioned_p (dest1, src2))
2250     {
2251       emit_insn (gen_movsi (dest2, src2));
2252       emit_insn (gen_movsi (dest1, src1));
2253     }
2254   else
2255     {
2256       emit_insn (gen_movsi (dest1, src1));
2257       emit_insn (gen_movsi (dest2, src2));
2258     }
2259   DONE;
2262 ;; Now handle the cases of memory moves from/to non-even
2263 ;; DI mode register pairs.
2264 (define_split
2265   [(set (match_operand:DI 0 "register_operand" "")
2266         (match_operand:DI 1 "memory_operand" ""))]
2267   "(! TARGET_ARCH64
2268     && reload_completed
2269     && sparc_splitdi_legitimate (operands[0], operands[1]))"
2270   [(clobber (const_int 0))]
2272   rtx word0 = adjust_address (operands[1], SImode, 0);
2273   rtx word1 = adjust_address (operands[1], SImode, 4);
2274   rtx high_part = gen_highpart (SImode, operands[0]);
2275   rtx low_part = gen_lowpart (SImode, operands[0]);
2277   if (reg_overlap_mentioned_p (high_part, word1))
2278     {
2279       emit_insn (gen_movsi (low_part, word1));
2280       emit_insn (gen_movsi (high_part, word0));
2281     }
2282   else
2283     {
2284       emit_insn (gen_movsi (high_part, word0));
2285       emit_insn (gen_movsi (low_part, word1));
2286     }
2287   DONE;
2290 (define_split
2291   [(set (match_operand:DI 0 "memory_operand" "")
2292         (match_operand:DI 1 "register_operand" ""))]
2293   "(! TARGET_ARCH64
2294     && reload_completed
2295     && sparc_splitdi_legitimate (operands[1], operands[0]))"
2296   [(clobber (const_int 0))]
2298   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
2299                         gen_highpart (SImode, operands[1])));
2300   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
2301                         gen_lowpart (SImode, operands[1])));
2302   DONE;
2305 (define_split
2306   [(set (match_operand:DI 0 "memory_operand" "")
2307         (match_operand:DI 1 "const_zero_operand" ""))]
2308   "reload_completed
2309    && (! TARGET_V9
2310        || (! TARGET_ARCH64
2311            && ! mem_min_alignment (operands[0], 8)))
2312    && offsettable_memref_p (operands[0])"
2313   [(clobber (const_int 0))]
2315   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
2316   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
2317   DONE;
2321 ;; Floating point and vector move instructions
2323 ;; We don't define V1SI because SI should work just fine.
2324 (define_mode_macro V32 [SF V2HI V4QI])
2326 ;; Yes, you guessed it right, the former movsf expander.
2327 (define_expand "mov<V32:mode>"
2328   [(set (match_operand:V32 0 "nonimmediate_operand" "")
2329         (match_operand:V32 1 "general_operand" ""))]
2330   "<V32:MODE>mode == SFmode || TARGET_VIS"
2332   if (sparc_expand_move (<V32:MODE>mode, operands))
2333     DONE;
2336 (define_insn "*movsf_insn"
2337   [(set (match_operand:V32 0 "nonimmediate_operand" "=d,f,*r,*r,*r,f,*r,m,m")
2338         (match_operand:V32 1 "input_operand"        "GY,f,*rRY,Q,S,m,m,f,*rGY"))]
2339   "TARGET_FPU
2340    && (register_operand (operands[0], <V32:MODE>mode)
2341        || register_or_zero_operand (operands[1], <V32:MODE>mode))"
2343   if (GET_CODE (operands[1]) == CONST_DOUBLE
2344       && (which_alternative == 2
2345           || which_alternative == 3
2346           || which_alternative == 4))
2347     {
2348       REAL_VALUE_TYPE r;
2349       long i;
2351       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2352       REAL_VALUE_TO_TARGET_SINGLE (r, i);
2353       operands[1] = GEN_INT (i);
2354     }
2356   switch (which_alternative)
2357     {
2358     case 0:
2359       return "fzeros\t%0";
2360     case 1:
2361       return "fmovs\t%1, %0";
2362     case 2:
2363       return "mov\t%1, %0";
2364     case 3:
2365       return "sethi\t%%hi(%a1), %0";
2366     case 4:
2367       return "#";
2368     case 5:
2369     case 6:
2370       return "ld\t%1, %0";
2371     case 7:
2372     case 8:
2373       return "st\t%r1, %0";
2374     default:
2375       gcc_unreachable ();
2376     }
2378   [(set_attr "type" "fga,fpmove,*,*,*,fpload,load,fpstore,store")])
2380 ;; Exactly the same as above, except that all `f' cases are deleted.
2381 ;; This is necessary to prevent reload from ever trying to use a `f' reg
2382 ;; when -mno-fpu.
2384 (define_insn "*movsf_insn_no_fpu"
2385   [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,m")
2386         (match_operand:SF 1 "input_operand"    "rR,Q,S,m,rG"))]
2387   "! TARGET_FPU
2388    && (register_operand (operands[0], SFmode)
2389        || register_or_zero_operand (operands[1], SFmode))"
2391   if (GET_CODE (operands[1]) == CONST_DOUBLE
2392       && (which_alternative == 0
2393           || which_alternative == 1
2394           || which_alternative == 2))
2395     {
2396       REAL_VALUE_TYPE r;
2397       long i;
2399       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2400       REAL_VALUE_TO_TARGET_SINGLE (r, i);
2401       operands[1] = GEN_INT (i);
2402     }
2404   switch (which_alternative)
2405     {
2406     case 0:
2407       return "mov\t%1, %0";
2408     case 1:
2409       return "sethi\t%%hi(%a1), %0";
2410     case 2:
2411       return "#";
2412     case 3:
2413       return "ld\t%1, %0";
2414     case 4:
2415       return "st\t%r1, %0";
2416     default:
2417       gcc_unreachable ();
2418     }
2420   [(set_attr "type" "*,*,*,load,store")])
2422 ;; The following 3 patterns build SFmode constants in integer registers.
2424 (define_insn "*movsf_lo_sum"
2425   [(set (match_operand:SF 0 "register_operand" "=r")
2426         (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
2427                    (match_operand:SF 2 "fp_const_high_losum_operand" "S")))]
2428   ""
2430   REAL_VALUE_TYPE r;
2431   long i;
2433   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
2434   REAL_VALUE_TO_TARGET_SINGLE (r, i);
2435   operands[2] = GEN_INT (i);
2436   return "or\t%1, %%lo(%a2), %0";
2439 (define_insn "*movsf_high"
2440   [(set (match_operand:SF 0 "register_operand" "=r")
2441         (high:SF (match_operand:SF 1 "fp_const_high_losum_operand" "S")))]
2442   ""
2444   REAL_VALUE_TYPE r;
2445   long i;
2447   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2448   REAL_VALUE_TO_TARGET_SINGLE (r, i);
2449   operands[1] = GEN_INT (i);
2450   return "sethi\t%%hi(%1), %0";
2453 (define_split
2454   [(set (match_operand:SF 0 "register_operand" "")
2455         (match_operand:SF 1 "fp_const_high_losum_operand" ""))]
2456   "REG_P (operands[0]) && REGNO (operands[0]) < 32"
2457   [(set (match_dup 0) (high:SF (match_dup 1)))
2458    (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
2460 (define_mode_macro V64 [DF V2SI V4HI V8QI])
2462 ;; Yes, you again guessed it right, the former movdf expander.
2463 (define_expand "mov<V64:mode>"
2464   [(set (match_operand:V64 0 "nonimmediate_operand" "")
2465         (match_operand:V64 1 "general_operand" ""))]
2466   "<V64:MODE>mode == DFmode || TARGET_VIS"
2468   if (sparc_expand_move (<V64:MODE>mode, operands))
2469     DONE;
2472 ;; Be careful, fmovd does not exist when !v9.
2473 (define_insn "*movdf_insn_sp32"
2474   [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o")
2475         (match_operand:DF 1 "input_operand"    "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
2476   "TARGET_FPU
2477    && ! TARGET_V9
2478    && (register_operand (operands[0], DFmode)
2479        || register_or_zero_operand (operands[1], DFmode))"
2480   "@
2481   ldd\t%1, %0
2482   std\t%1, %0
2483   ldd\t%1, %0
2484   std\t%1, %0
2485   #
2486   #
2487   #
2488   #
2489   #
2490   #"
2491  [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
2492   (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
2494 (define_insn "*movdf_insn_sp32_no_fpu"
2495   [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
2496         (match_operand:DF 1 "input_operand"    "T,U,G,ro,r"))]
2497   "! TARGET_FPU
2498    && ! TARGET_V9
2499    && (register_operand (operands[0], DFmode)
2500        || register_or_zero_operand (operands[1], DFmode))"
2501   "@
2502   ldd\t%1, %0
2503   std\t%1, %0
2504   #
2505   #
2506   #"
2507   [(set_attr "type" "load,store,*,*,*")
2508    (set_attr "length" "*,*,2,2,2")])
2510 ;; We have available v9 double floats but not 64-bit integer registers.
2511 (define_insn "*movdf_insn_sp32_v9"
2512   [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,T,W,U,T,f,*r,o")
2513         (match_operand:V64 1 "input_operand" "GY,e,W#F,GY,e,T,U,o#F,*roGYF,*rGYf"))]
2514   "TARGET_FPU
2515    && TARGET_V9
2516    && ! TARGET_ARCH64
2517    && (register_operand (operands[0], <V64:MODE>mode)
2518        || register_or_zero_operand (operands[1], <V64:MODE>mode))"
2519   "@
2520   fzero\t%0
2521   fmovd\t%1, %0
2522   ldd\t%1, %0
2523   stx\t%r1, %0
2524   std\t%1, %0
2525   ldd\t%1, %0
2526   std\t%1, %0
2527   #
2528   #
2529   #"
2530   [(set_attr "type" "fga,fpmove,load,store,store,load,store,*,*,*")
2531    (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
2532    (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
2534 (define_insn "*movdf_insn_sp32_v9_no_fpu"
2535   [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
2536         (match_operand:DF 1 "input_operand"    "T,U,G,ro,rG"))]
2537   "! TARGET_FPU
2538    && TARGET_V9
2539    && ! TARGET_ARCH64
2540    && (register_operand (operands[0], DFmode)
2541        || register_or_zero_operand (operands[1], DFmode))"
2542   "@
2543   ldd\t%1, %0
2544   std\t%1, %0
2545   stx\t%r1, %0
2546   #
2547   #"
2548   [(set_attr "type" "load,store,store,*,*")
2549    (set_attr "length" "*,*,*,2,2")])
2551 ;; We have available both v9 double floats and 64-bit integer registers.
2552 (define_insn "*movdf_insn_sp64"
2553   [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,W,*r,*r,m,*r")
2554         (match_operand:V64 1 "input_operand"    "GY,e,W#F,e,*rGY,m,*rGY,F"))]
2555   "TARGET_FPU
2556    && TARGET_ARCH64
2557    && (register_operand (operands[0], <V64:MODE>mode)
2558        || register_or_zero_operand (operands[1], <V64:MODE>mode))"
2559   "@
2560   fzero\t%0
2561   fmovd\t%1, %0
2562   ldd\t%1, %0
2563   std\t%1, %0
2564   mov\t%r1, %0
2565   ldx\t%1, %0
2566   stx\t%r1, %0
2567   #"
2568   [(set_attr "type" "fga,fpmove,load,store,*,load,store,*")
2569    (set_attr "length" "*,*,*,*,*,*,*,2")
2570    (set_attr "fptype" "double,double,*,*,*,*,*,*")])
2572 (define_insn "*movdf_insn_sp64_no_fpu"
2573   [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
2574         (match_operand:DF 1 "input_operand"    "r,m,rG"))]
2575   "! TARGET_FPU
2576    && TARGET_ARCH64
2577    && (register_operand (operands[0], DFmode)
2578        || register_or_zero_operand (operands[1], DFmode))"
2579   "@
2580   mov\t%1, %0
2581   ldx\t%1, %0
2582   stx\t%r1, %0"
2583   [(set_attr "type" "*,load,store")])
2585 ;; This pattern build DFmode constants in integer registers.
2586 (define_split
2587   [(set (match_operand:DF 0 "register_operand" "")
2588         (match_operand:DF 1 "const_double_operand" ""))]
2589   "TARGET_FPU
2590    && (GET_CODE (operands[0]) == REG
2591        && REGNO (operands[0]) < 32)
2592    && ! const_zero_operand(operands[1], DFmode)
2593    && reload_completed"
2594   [(clobber (const_int 0))]
2596   REAL_VALUE_TYPE r;
2597   long l[2];
2599   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2600   REAL_VALUE_TO_TARGET_DOUBLE (r, l);
2601   operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
2603   if (TARGET_ARCH64)
2604     {
2605 #if HOST_BITS_PER_WIDE_INT == 32
2606       gcc_unreachable ();
2607 #else
2608       HOST_WIDE_INT val;
2610       val = ((HOST_WIDE_INT)(unsigned long)l[1] |
2611              ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
2612       emit_insn (gen_movdi (operands[0], gen_int_mode (val, DImode)));
2613 #endif
2614     }
2615   else
2616     {
2617       emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2618                             gen_int_mode (l[0], SImode)));
2620       /* Slick... but this trick loses if this subreg constant part
2621          can be done in one insn.  */
2622       if (l[1] == l[0]
2623           && ! SPARC_SETHI32_P (l[0])
2624           && ! SPARC_SIMM13_P (l[0]))
2625         {
2626           emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2627                                 gen_highpart (SImode, operands[0])));
2628         }
2629       else
2630         {
2631           emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2632                                 gen_int_mode (l[1], SImode)));
2633         }
2634     }
2635   DONE;
2638 ;; Ok, now the splits to handle all the multi insn and
2639 ;; mis-aligned memory address cases.
2640 ;; In these splits please take note that we must be
2641 ;; careful when V9 but not ARCH64 because the integer
2642 ;; register DFmode cases must be handled.
2643 (define_split
2644   [(set (match_operand:V64 0 "register_operand" "")
2645         (match_operand:V64 1 "register_operand" ""))]
2646   "(! TARGET_V9
2647     || (! TARGET_ARCH64
2648         && ((GET_CODE (operands[0]) == REG
2649              && REGNO (operands[0]) < 32)
2650             || (GET_CODE (operands[0]) == SUBREG
2651                 && GET_CODE (SUBREG_REG (operands[0])) == REG
2652                 && REGNO (SUBREG_REG (operands[0])) < 32))))
2653    && reload_completed"
2654   [(clobber (const_int 0))]
2656   rtx set_dest = operands[0];
2657   rtx set_src = operands[1];
2658   rtx dest1, dest2;
2659   rtx src1, src2;
2660   enum machine_mode half_mode;
2662   /* We can be expanded for DFmode or integral vector modes.  */
2663   if (<V64:MODE>mode == DFmode)
2664     half_mode = SFmode;
2665   else
2666     half_mode = SImode;
2667   
2668   dest1 = gen_highpart (half_mode, set_dest);
2669   dest2 = gen_lowpart (half_mode, set_dest);
2670   src1 = gen_highpart (half_mode, set_src);
2671   src2 = gen_lowpart (half_mode, set_src);
2673   /* Now emit using the real source and destination we found, swapping
2674      the order if we detect overlap.  */
2675   if (reg_overlap_mentioned_p (dest1, src2))
2676     {
2677       emit_move_insn_1 (dest2, src2);
2678       emit_move_insn_1 (dest1, src1);
2679     }
2680   else
2681     {
2682       emit_move_insn_1 (dest1, src1);
2683       emit_move_insn_1 (dest2, src2);
2684     }
2685   DONE;
2688 (define_split
2689   [(set (match_operand:V64 0 "register_operand" "")
2690         (match_operand:V64 1 "memory_operand" ""))]
2691   "reload_completed
2692    && ! TARGET_ARCH64
2693    && (((REGNO (operands[0]) % 2) != 0)
2694        || ! mem_min_alignment (operands[1], 8))
2695    && offsettable_memref_p (operands[1])"
2696   [(clobber (const_int 0))]
2698   enum machine_mode half_mode;
2699   rtx word0, word1;
2701   /* We can be expanded for DFmode or integral vector modes.  */
2702   if (<V64:MODE>mode == DFmode)
2703     half_mode = SFmode;
2704   else
2705     half_mode = SImode;
2707   word0 = adjust_address (operands[1], half_mode, 0);
2708   word1 = adjust_address (operands[1], half_mode, 4);
2710   if (reg_overlap_mentioned_p (gen_highpart (half_mode, operands[0]), word1))
2711     {
2712       emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2713       emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2714     }
2715   else
2716     {
2717       emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2718       emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2719     }
2720   DONE;
2723 (define_split
2724   [(set (match_operand:V64 0 "memory_operand" "")
2725         (match_operand:V64 1 "register_operand" ""))]
2726   "reload_completed
2727    && ! TARGET_ARCH64
2728    && (((REGNO (operands[1]) % 2) != 0)
2729        || ! mem_min_alignment (operands[0], 8))
2730    && offsettable_memref_p (operands[0])"
2731   [(clobber (const_int 0))]
2733   enum machine_mode half_mode;
2734   rtx word0, word1;
2736   /* We can be expanded for DFmode or integral vector modes.  */
2737   if (<V64:MODE>mode == DFmode)
2738     half_mode = SFmode;
2739   else
2740     half_mode = SImode;
2742   word0 = adjust_address (operands[0], half_mode, 0);
2743   word1 = adjust_address (operands[0], half_mode, 4);
2745   emit_move_insn_1 (word0, gen_highpart (half_mode, operands[1]));
2746   emit_move_insn_1 (word1, gen_lowpart (half_mode, operands[1]));
2747   DONE;
2750 (define_split
2751   [(set (match_operand:V64 0 "memory_operand" "")
2752         (match_operand:V64 1 "const_zero_operand" ""))]
2753   "reload_completed
2754    && (! TARGET_V9
2755        || (! TARGET_ARCH64
2756            && ! mem_min_alignment (operands[0], 8)))
2757    && offsettable_memref_p (operands[0])"
2758   [(clobber (const_int 0))]
2760   enum machine_mode half_mode;
2761   rtx dest1, dest2;
2763   /* We can be expanded for DFmode or integral vector modes.  */
2764   if (<V64:MODE>mode == DFmode)
2765     half_mode = SFmode;
2766   else
2767     half_mode = SImode;
2769   dest1 = adjust_address (operands[0], half_mode, 0);
2770   dest2 = adjust_address (operands[0], half_mode, 4);
2772   emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2773   emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2774   DONE;
2777 (define_split
2778   [(set (match_operand:V64 0 "register_operand" "")
2779         (match_operand:V64 1 "const_zero_operand" ""))]
2780   "reload_completed
2781    && ! TARGET_ARCH64
2782    && ((GET_CODE (operands[0]) == REG
2783         && REGNO (operands[0]) < 32)
2784        || (GET_CODE (operands[0]) == SUBREG
2785            && GET_CODE (SUBREG_REG (operands[0])) == REG
2786            && REGNO (SUBREG_REG (operands[0])) < 32))"
2787   [(clobber (const_int 0))]
2789   enum machine_mode half_mode;
2790   rtx set_dest = operands[0];
2791   rtx dest1, dest2;
2793   /* We can be expanded for DFmode or integral vector modes.  */
2794   if (<V64:MODE>mode == DFmode)
2795     half_mode = SFmode;
2796   else
2797     half_mode = SImode;
2799   dest1 = gen_highpart (half_mode, set_dest);
2800   dest2 = gen_lowpart (half_mode, set_dest);
2801   emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2802   emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2803   DONE;
2806 (define_expand "movtf"
2807   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2808         (match_operand:TF 1 "general_operand" ""))]
2809   ""
2811   if (sparc_expand_move (TFmode, operands))
2812     DONE;
2815 (define_insn "*movtf_insn_sp32"
2816   [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,U,r")
2817         (match_operand:TF 1 "input_operand"    "G,oe,GeUr,o,roG"))]
2818   "TARGET_FPU
2819    && ! TARGET_ARCH64
2820    && (register_operand (operands[0], TFmode)
2821        || register_or_zero_operand (operands[1], TFmode))"
2822   "#"
2823   [(set_attr "length" "4")])
2825 ;; Exactly the same as above, except that all `e' cases are deleted.
2826 ;; This is necessary to prevent reload from ever trying to use a `e' reg
2827 ;; when -mno-fpu.
2829 (define_insn "*movtf_insn_sp32_no_fpu"
2830   [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
2831         (match_operand:TF 1 "input_operand"    "G,o,U,roG,r"))]
2832   "! TARGET_FPU
2833    && ! TARGET_ARCH64
2834    && (register_operand (operands[0], TFmode)
2835        || register_or_zero_operand (operands[1], TFmode))"
2836   "#"
2837   [(set_attr "length" "4")])
2839 (define_insn "*movtf_insn_sp64"
2840   [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,r")
2841         (match_operand:TF 1 "input_operand"    "G,oe,Ger,roG"))]
2842   "TARGET_FPU
2843    && TARGET_ARCH64
2844    && ! TARGET_HARD_QUAD
2845    && (register_operand (operands[0], TFmode)
2846        || register_or_zero_operand (operands[1], TFmode))"
2847   "#"
2848   [(set_attr "length" "2")])
2850 (define_insn "*movtf_insn_sp64_hq"
2851   [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,e,m,o,r")
2852         (match_operand:TF 1 "input_operand"    "G,e,m,e,rG,roG"))]
2853   "TARGET_FPU
2854    && TARGET_ARCH64
2855    && TARGET_HARD_QUAD
2856    && (register_operand (operands[0], TFmode)
2857        || register_or_zero_operand (operands[1], TFmode))"
2858   "@
2859   #
2860   fmovq\t%1, %0
2861   ldq\t%1, %0
2862   stq\t%1, %0
2863   #
2864   #"
2865   [(set_attr "type" "*,fpmove,fpload,fpstore,*,*")
2866    (set_attr "length" "2,*,*,*,2,2")])
2868 (define_insn "*movtf_insn_sp64_no_fpu"
2869   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
2870         (match_operand:TF 1 "input_operand"    "orG,rG"))]
2871   "! TARGET_FPU
2872    && TARGET_ARCH64
2873    && (register_operand (operands[0], TFmode)
2874        || register_or_zero_operand (operands[1], TFmode))"
2875   "#"
2876   [(set_attr "length" "2")])
2878 ;; Now all the splits to handle multi-insn TF mode moves.
2879 (define_split
2880   [(set (match_operand:TF 0 "register_operand" "")
2881         (match_operand:TF 1 "register_operand" ""))]
2882   "reload_completed
2883    && (! TARGET_ARCH64
2884        || (TARGET_FPU
2885            && ! TARGET_HARD_QUAD)
2886        || ! fp_register_operand (operands[0], TFmode))"
2887   [(clobber (const_int 0))]
2889   rtx set_dest = operands[0];
2890   rtx set_src = operands[1];
2891   rtx dest1, dest2;
2892   rtx src1, src2;
2894   dest1 = gen_df_reg (set_dest, 0);
2895   dest2 = gen_df_reg (set_dest, 1);
2896   src1 = gen_df_reg (set_src, 0);
2897   src2 = gen_df_reg (set_src, 1);
2899   /* Now emit using the real source and destination we found, swapping
2900      the order if we detect overlap.  */
2901   if (reg_overlap_mentioned_p (dest1, src2))
2902     {
2903       emit_insn (gen_movdf (dest2, src2));
2904       emit_insn (gen_movdf (dest1, src1));
2905     }
2906   else
2907     {
2908       emit_insn (gen_movdf (dest1, src1));
2909       emit_insn (gen_movdf (dest2, src2));
2910     }
2911   DONE;
2914 (define_split
2915   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2916         (match_operand:TF 1 "const_zero_operand" ""))]
2917   "reload_completed"
2918   [(clobber (const_int 0))]
2920   rtx set_dest = operands[0];
2921   rtx dest1, dest2;
2923   switch (GET_CODE (set_dest))
2924     {
2925     case REG:
2926       dest1 = gen_df_reg (set_dest, 0);
2927       dest2 = gen_df_reg (set_dest, 1);
2928       break;
2929     case MEM:
2930       dest1 = adjust_address (set_dest, DFmode, 0);
2931       dest2 = adjust_address (set_dest, DFmode, 8);
2932       break;
2933     default:
2934       gcc_unreachable ();      
2935     }
2937   emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
2938   emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
2939   DONE;
2942 (define_split
2943   [(set (match_operand:TF 0 "register_operand" "")
2944         (match_operand:TF 1 "memory_operand" ""))]
2945   "(reload_completed
2946     && offsettable_memref_p (operands[1])
2947     && (! TARGET_ARCH64
2948         || ! TARGET_HARD_QUAD
2949         || ! fp_register_operand (operands[0], TFmode)))"
2950   [(clobber (const_int 0))]
2952   rtx word0 = adjust_address (operands[1], DFmode, 0);
2953   rtx word1 = adjust_address (operands[1], DFmode, 8);
2954   rtx set_dest, dest1, dest2;
2956   set_dest = operands[0];
2958   dest1 = gen_df_reg (set_dest, 0);
2959   dest2 = gen_df_reg (set_dest, 1);
2961   /* Now output, ordering such that we don't clobber any registers
2962      mentioned in the address.  */
2963   if (reg_overlap_mentioned_p (dest1, word1))
2965     {
2966       emit_insn (gen_movdf (dest2, word1));
2967       emit_insn (gen_movdf (dest1, word0));
2968     }
2969   else
2970    {
2971       emit_insn (gen_movdf (dest1, word0));
2972       emit_insn (gen_movdf (dest2, word1));
2973    }
2974   DONE;
2977 (define_split
2978   [(set (match_operand:TF 0 "memory_operand" "")
2979         (match_operand:TF 1 "register_operand" ""))]
2980   "(reload_completed
2981     && offsettable_memref_p (operands[0])
2982     && (! TARGET_ARCH64
2983         || ! TARGET_HARD_QUAD
2984         || ! fp_register_operand (operands[1], TFmode)))"
2985   [(clobber (const_int 0))]
2987   rtx set_src = operands[1];
2989   emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
2990                         gen_df_reg (set_src, 0)));
2991   emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
2992                         gen_df_reg (set_src, 1)));
2993   DONE;
2997 ;; SPARC-V9 conditional move instructions.
2999 ;; We can handle larger constants here for some flavors, but for now we keep
3000 ;; it simple and only allow those constants supported by all flavors.
3001 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3002 ;; 3 contains the constant if one is present, but we handle either for
3003 ;; generality (sparc.c puts a constant in operand 2).
3005 (define_expand "movqicc"
3006   [(set (match_operand:QI 0 "register_operand" "")
3007         (if_then_else:QI (match_operand 1 "comparison_operator" "")
3008                          (match_operand:QI 2 "arith10_operand" "")
3009                          (match_operand:QI 3 "arith10_operand" "")))]
3010   "TARGET_V9"
3012   enum rtx_code code = GET_CODE (operands[1]);
3014   if (GET_MODE (sparc_compare_op0) == DImode
3015       && ! TARGET_ARCH64)
3016     FAIL;
3018   if (sparc_compare_op1 == const0_rtx
3019       && GET_CODE (sparc_compare_op0) == REG
3020       && GET_MODE (sparc_compare_op0) == DImode
3021       && v9_regcmp_p (code))
3022     {
3023       operands[1] = gen_rtx_fmt_ee (code, DImode,
3024                              sparc_compare_op0, sparc_compare_op1);
3025     }
3026   else
3027     {
3028       rtx cc_reg = gen_compare_reg (code,
3029                                     sparc_compare_op0, sparc_compare_op1);
3030       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3031     }
3034 (define_expand "movhicc"
3035   [(set (match_operand:HI 0 "register_operand" "")
3036         (if_then_else:HI (match_operand 1 "comparison_operator" "")
3037                          (match_operand:HI 2 "arith10_operand" "")
3038                          (match_operand:HI 3 "arith10_operand" "")))]
3039   "TARGET_V9"
3041   enum rtx_code code = GET_CODE (operands[1]);
3043   if (GET_MODE (sparc_compare_op0) == DImode
3044       && ! TARGET_ARCH64)
3045     FAIL;
3047   if (sparc_compare_op1 == const0_rtx
3048       && GET_CODE (sparc_compare_op0) == REG
3049       && GET_MODE (sparc_compare_op0) == DImode
3050       && v9_regcmp_p (code))
3051     {
3052       operands[1] = gen_rtx_fmt_ee (code, DImode,
3053                              sparc_compare_op0, sparc_compare_op1);
3054     }
3055   else
3056     {
3057       rtx cc_reg = gen_compare_reg (code,
3058                                     sparc_compare_op0, sparc_compare_op1);
3059       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3060     }
3063 (define_expand "movsicc"
3064   [(set (match_operand:SI 0 "register_operand" "")
3065         (if_then_else:SI (match_operand 1 "comparison_operator" "")
3066                          (match_operand:SI 2 "arith10_operand" "")
3067                          (match_operand:SI 3 "arith10_operand" "")))]
3068   "TARGET_V9"
3070   enum rtx_code code = GET_CODE (operands[1]);
3071   enum machine_mode op0_mode = GET_MODE (sparc_compare_op0);
3073   if (sparc_compare_op1 == const0_rtx
3074       && GET_CODE (sparc_compare_op0) == REG
3075       && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)))
3076     {
3077       operands[1] = gen_rtx_fmt_ee (code, op0_mode,
3078                              sparc_compare_op0, sparc_compare_op1);
3079     }
3080   else
3081     {
3082       rtx cc_reg = gen_compare_reg (code,
3083                                     sparc_compare_op0, sparc_compare_op1);
3084       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3085                                     cc_reg, const0_rtx);
3086     }
3089 (define_expand "movdicc"
3090   [(set (match_operand:DI 0 "register_operand" "")
3091         (if_then_else:DI (match_operand 1 "comparison_operator" "")
3092                          (match_operand:DI 2 "arith10_operand" "")
3093                          (match_operand:DI 3 "arith10_operand" "")))]
3094   "TARGET_ARCH64"
3096   enum rtx_code code = GET_CODE (operands[1]);
3098   if (sparc_compare_op1 == const0_rtx
3099       && GET_CODE (sparc_compare_op0) == REG
3100       && GET_MODE (sparc_compare_op0) == DImode
3101       && v9_regcmp_p (code))
3102     {
3103       operands[1] = gen_rtx_fmt_ee (code, DImode,
3104                              sparc_compare_op0, sparc_compare_op1);
3105     }
3106   else
3107     {
3108       rtx cc_reg = gen_compare_reg (code,
3109                                     sparc_compare_op0, sparc_compare_op1);
3110       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg),
3111                                     cc_reg, const0_rtx);
3112     }
3115 (define_expand "movsfcc"
3116   [(set (match_operand:SF 0 "register_operand" "")
3117         (if_then_else:SF (match_operand 1 "comparison_operator" "")
3118                          (match_operand:SF 2 "register_operand" "")
3119                          (match_operand:SF 3 "register_operand" "")))]
3120   "TARGET_V9 && TARGET_FPU"
3122   enum rtx_code code = GET_CODE (operands[1]);
3124   if (GET_MODE (sparc_compare_op0) == DImode
3125       && ! TARGET_ARCH64)
3126     FAIL;
3128   if (sparc_compare_op1 == const0_rtx
3129       && GET_CODE (sparc_compare_op0) == REG
3130       && GET_MODE (sparc_compare_op0) == DImode
3131       && v9_regcmp_p (code))
3132     {
3133       operands[1] = gen_rtx_fmt_ee (code, DImode,
3134                              sparc_compare_op0, sparc_compare_op1);
3135     }
3136   else
3137     {
3138       rtx cc_reg = gen_compare_reg (code,
3139                                     sparc_compare_op0, sparc_compare_op1);
3140       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3141     }
3144 (define_expand "movdfcc"
3145   [(set (match_operand:DF 0 "register_operand" "")
3146         (if_then_else:DF (match_operand 1 "comparison_operator" "")
3147                          (match_operand:DF 2 "register_operand" "")
3148                          (match_operand:DF 3 "register_operand" "")))]
3149   "TARGET_V9 && TARGET_FPU"
3151   enum rtx_code code = GET_CODE (operands[1]);
3153   if (GET_MODE (sparc_compare_op0) == DImode
3154       && ! TARGET_ARCH64)
3155     FAIL;
3157   if (sparc_compare_op1 == const0_rtx
3158       && GET_CODE (sparc_compare_op0) == REG
3159       && GET_MODE (sparc_compare_op0) == DImode
3160       && v9_regcmp_p (code))
3161     {
3162       operands[1] = gen_rtx_fmt_ee (code, DImode,
3163                              sparc_compare_op0, sparc_compare_op1);
3164     }
3165   else
3166     {
3167       rtx cc_reg = gen_compare_reg (code,
3168                                     sparc_compare_op0, sparc_compare_op1);
3169       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3170     }
3173 (define_expand "movtfcc"
3174   [(set (match_operand:TF 0 "register_operand" "")
3175         (if_then_else:TF (match_operand 1 "comparison_operator" "")
3176                          (match_operand:TF 2 "register_operand" "")
3177                          (match_operand:TF 3 "register_operand" "")))]
3178   "TARGET_V9 && TARGET_FPU"
3180   enum rtx_code code = GET_CODE (operands[1]);
3182   if (GET_MODE (sparc_compare_op0) == DImode
3183       && ! TARGET_ARCH64)
3184     FAIL;
3186   if (sparc_compare_op1 == const0_rtx
3187       && GET_CODE (sparc_compare_op0) == REG
3188       && GET_MODE (sparc_compare_op0) == DImode
3189       && v9_regcmp_p (code))
3190     {
3191       operands[1] = gen_rtx_fmt_ee (code, DImode,
3192                              sparc_compare_op0, sparc_compare_op1);
3193     }
3194   else
3195     {
3196       rtx cc_reg = gen_compare_reg (code,
3197                                     sparc_compare_op0, sparc_compare_op1);
3198       operands[1] = gen_rtx_fmt_ee (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
3199     }
3202 ;; Conditional move define_insns.
3204 (define_insn "*movqi_cc_sp64"
3205   [(set (match_operand:QI 0 "register_operand" "=r,r")
3206         (if_then_else:QI (match_operator 1 "comparison_operator"
3207                                 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3208                                  (const_int 0)])
3209                          (match_operand:QI 3 "arith11_operand" "rL,0")
3210                          (match_operand:QI 4 "arith11_operand" "0,rL")))]
3211   "TARGET_V9"
3212   "@
3213    mov%C1\t%x2, %3, %0
3214    mov%c1\t%x2, %4, %0"
3215   [(set_attr "type" "cmove")])
3217 (define_insn "*movhi_cc_sp64"
3218   [(set (match_operand:HI 0 "register_operand" "=r,r")
3219         (if_then_else:HI (match_operator 1 "comparison_operator"
3220                                 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3221                                  (const_int 0)])
3222                          (match_operand:HI 3 "arith11_operand" "rL,0")
3223                          (match_operand:HI 4 "arith11_operand" "0,rL")))]
3224   "TARGET_V9"
3225   "@
3226    mov%C1\t%x2, %3, %0
3227    mov%c1\t%x2, %4, %0"
3228   [(set_attr "type" "cmove")])
3230 (define_insn "*movsi_cc_sp64"
3231   [(set (match_operand:SI 0 "register_operand" "=r,r")
3232         (if_then_else:SI (match_operator 1 "comparison_operator"
3233                                 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3234                                  (const_int 0)])
3235                          (match_operand:SI 3 "arith11_operand" "rL,0")
3236                          (match_operand:SI 4 "arith11_operand" "0,rL")))]
3237   "TARGET_V9"
3238   "@
3239    mov%C1\t%x2, %3, %0
3240    mov%c1\t%x2, %4, %0"
3241   [(set_attr "type" "cmove")])
3243 (define_insn "*movdi_cc_sp64"
3244   [(set (match_operand:DI 0 "register_operand" "=r,r")
3245         (if_then_else:DI (match_operator 1 "comparison_operator"
3246                                 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3247                                  (const_int 0)])
3248                          (match_operand:DI 3 "arith11_operand" "rL,0")
3249                          (match_operand:DI 4 "arith11_operand" "0,rL")))]
3250   "TARGET_ARCH64"
3251   "@
3252    mov%C1\t%x2, %3, %0
3253    mov%c1\t%x2, %4, %0"
3254   [(set_attr "type" "cmove")])
3256 (define_insn "*movdi_cc_sp64_trunc"
3257   [(set (match_operand:SI 0 "register_operand" "=r,r")
3258         (if_then_else:SI (match_operator 1 "comparison_operator"
3259                                 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3260                                  (const_int 0)])
3261                          (match_operand:SI 3 "arith11_operand" "rL,0")
3262                          (match_operand:SI 4 "arith11_operand" "0,rL")))]
3263   "TARGET_ARCH64"
3264   "@
3265    mov%C1\t%x2, %3, %0
3266    mov%c1\t%x2, %4, %0"
3267   [(set_attr "type" "cmove")])
3269 (define_insn "*movsf_cc_sp64"
3270   [(set (match_operand:SF 0 "register_operand" "=f,f")
3271         (if_then_else:SF (match_operator 1 "comparison_operator"
3272                                 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3273                                  (const_int 0)])
3274                          (match_operand:SF 3 "register_operand" "f,0")
3275                          (match_operand:SF 4 "register_operand" "0,f")))]
3276   "TARGET_V9 && TARGET_FPU"
3277   "@
3278    fmovs%C1\t%x2, %3, %0
3279    fmovs%c1\t%x2, %4, %0"
3280   [(set_attr "type" "fpcmove")])
3282 (define_insn "movdf_cc_sp64"
3283   [(set (match_operand:DF 0 "register_operand" "=e,e")
3284         (if_then_else:DF (match_operator 1 "comparison_operator"
3285                                 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3286                                  (const_int 0)])
3287                          (match_operand:DF 3 "register_operand" "e,0")
3288                          (match_operand:DF 4 "register_operand" "0,e")))]
3289   "TARGET_V9 && TARGET_FPU"
3290   "@
3291    fmovd%C1\t%x2, %3, %0
3292    fmovd%c1\t%x2, %4, %0"
3293   [(set_attr "type" "fpcmove")
3294    (set_attr "fptype" "double")])
3296 (define_insn "*movtf_cc_hq_sp64"
3297   [(set (match_operand:TF 0 "register_operand" "=e,e")
3298         (if_then_else:TF (match_operator 1 "comparison_operator"
3299                                 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3300                                  (const_int 0)])
3301                          (match_operand:TF 3 "register_operand" "e,0")
3302                          (match_operand:TF 4 "register_operand" "0,e")))]
3303   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3304   "@
3305    fmovq%C1\t%x2, %3, %0
3306    fmovq%c1\t%x2, %4, %0"
3307   [(set_attr "type" "fpcmove")])
3309 (define_insn_and_split "*movtf_cc_sp64"
3310   [(set (match_operand:TF 0 "register_operand" "=e,e")
3311         (if_then_else:TF (match_operator 1 "comparison_operator"
3312                             [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3313                              (const_int 0)])
3314                          (match_operand:TF 3 "register_operand" "e,0")
3315                          (match_operand:TF 4 "register_operand" "0,e")))]
3316   "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
3317   "#"
3318   "&& reload_completed"
3319   [(clobber (const_int 0))]
3321   rtx set_dest = operands[0];
3322   rtx set_srca = operands[3];
3323   rtx set_srcb = operands[4];
3324   int third = rtx_equal_p (set_dest, set_srca);
3325   rtx dest1, dest2;
3326   rtx srca1, srca2, srcb1, srcb2;
3328   dest1 = gen_df_reg (set_dest, 0);
3329   dest2 = gen_df_reg (set_dest, 1);
3330   srca1 = gen_df_reg (set_srca, 0);
3331   srca2 = gen_df_reg (set_srca, 1);
3332   srcb1 = gen_df_reg (set_srcb, 0);
3333   srcb2 = gen_df_reg (set_srcb, 1);
3335   /* Now emit using the real source and destination we found, swapping
3336      the order if we detect overlap.  */
3337   if ((third && reg_overlap_mentioned_p (dest1, srcb2))
3338       || (!third && reg_overlap_mentioned_p (dest1, srca2)))
3339     {
3340       emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3341       emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3342     }
3343   else
3344     {
3345       emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3346       emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3347     }
3348   DONE;
3350   [(set_attr "length" "2")])
3352 (define_insn "*movqi_cc_reg_sp64"
3353   [(set (match_operand:QI 0 "register_operand" "=r,r")
3354         (if_then_else:QI (match_operator 1 "v9_register_compare_operator"
3355                                 [(match_operand:DI 2 "register_operand" "r,r")
3356                                  (const_int 0)])
3357                          (match_operand:QI 3 "arith10_operand" "rM,0")
3358                          (match_operand:QI 4 "arith10_operand" "0,rM")))]
3359   "TARGET_ARCH64"
3360   "@
3361    movr%D1\t%2, %r3, %0
3362    movr%d1\t%2, %r4, %0"
3363   [(set_attr "type" "cmove")])
3365 (define_insn "*movhi_cc_reg_sp64"
3366   [(set (match_operand:HI 0 "register_operand" "=r,r")
3367         (if_then_else:HI (match_operator 1 "v9_register_compare_operator"
3368                                 [(match_operand:DI 2 "register_operand" "r,r")
3369                                  (const_int 0)])
3370                          (match_operand:HI 3 "arith10_operand" "rM,0")
3371                          (match_operand:HI 4 "arith10_operand" "0,rM")))]
3372   "TARGET_ARCH64"
3373   "@
3374    movr%D1\t%2, %r3, %0
3375    movr%d1\t%2, %r4, %0"
3376   [(set_attr "type" "cmove")])
3378 (define_insn "*movsi_cc_reg_sp64"
3379   [(set (match_operand:SI 0 "register_operand" "=r,r")
3380         (if_then_else:SI (match_operator 1 "v9_register_compare_operator"
3381                                 [(match_operand:DI 2 "register_operand" "r,r")
3382                                  (const_int 0)])
3383                          (match_operand:SI 3 "arith10_operand" "rM,0")
3384                          (match_operand:SI 4 "arith10_operand" "0,rM")))]
3385   "TARGET_ARCH64"
3386   "@
3387    movr%D1\t%2, %r3, %0
3388    movr%d1\t%2, %r4, %0"
3389   [(set_attr "type" "cmove")])
3391 (define_insn "*movdi_cc_reg_sp64"
3392   [(set (match_operand:DI 0 "register_operand" "=r,r")
3393         (if_then_else:DI (match_operator 1 "v9_register_compare_operator"
3394                                 [(match_operand:DI 2 "register_operand" "r,r")
3395                                  (const_int 0)])
3396                          (match_operand:DI 3 "arith10_operand" "rM,0")
3397                          (match_operand:DI 4 "arith10_operand" "0,rM")))]
3398   "TARGET_ARCH64"
3399   "@
3400    movr%D1\t%2, %r3, %0
3401    movr%d1\t%2, %r4, %0"
3402   [(set_attr "type" "cmove")])
3404 (define_insn "*movsf_cc_reg_sp64"
3405   [(set (match_operand:SF 0 "register_operand" "=f,f")
3406         (if_then_else:SF (match_operator 1 "v9_register_compare_operator"
3407                                 [(match_operand:DI 2 "register_operand" "r,r")
3408                                  (const_int 0)])
3409                          (match_operand:SF 3 "register_operand" "f,0")
3410                          (match_operand:SF 4 "register_operand" "0,f")))]
3411   "TARGET_ARCH64 && TARGET_FPU"
3412   "@
3413    fmovrs%D1\t%2, %3, %0
3414    fmovrs%d1\t%2, %4, %0"
3415   [(set_attr "type" "fpcrmove")])
3417 (define_insn "movdf_cc_reg_sp64"
3418   [(set (match_operand:DF 0 "register_operand" "=e,e")
3419         (if_then_else:DF (match_operator 1 "v9_register_compare_operator"
3420                                 [(match_operand:DI 2 "register_operand" "r,r")
3421                                  (const_int 0)])
3422                          (match_operand:DF 3 "register_operand" "e,0")
3423                          (match_operand:DF 4 "register_operand" "0,e")))]
3424   "TARGET_ARCH64 && TARGET_FPU"
3425   "@
3426    fmovrd%D1\t%2, %3, %0
3427    fmovrd%d1\t%2, %4, %0"
3428   [(set_attr "type" "fpcrmove")
3429    (set_attr "fptype" "double")])
3431 (define_insn "*movtf_cc_reg_hq_sp64"
3432   [(set (match_operand:TF 0 "register_operand" "=e,e")
3433         (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
3434                                 [(match_operand:DI 2 "register_operand" "r,r")
3435                                  (const_int 0)])
3436                          (match_operand:TF 3 "register_operand" "e,0")
3437                          (match_operand:TF 4 "register_operand" "0,e")))]
3438   "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
3439   "@
3440    fmovrq%D1\t%2, %3, %0
3441    fmovrq%d1\t%2, %4, %0"
3442   [(set_attr "type" "fpcrmove")])
3444 (define_insn_and_split "*movtf_cc_reg_sp64"
3445   [(set (match_operand:TF 0 "register_operand" "=e,e")
3446         (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
3447                                 [(match_operand:DI 2 "register_operand" "r,r")
3448                                  (const_int 0)])
3449                          (match_operand:TF 3 "register_operand" "e,0")
3450                          (match_operand:TF 4 "register_operand" "0,e")))]
3451   "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
3452   "#"
3453   "&& reload_completed"
3454   [(clobber (const_int 0))]
3456   rtx set_dest = operands[0];
3457   rtx set_srca = operands[3];
3458   rtx set_srcb = operands[4];
3459   int third = rtx_equal_p (set_dest, set_srca);
3460   rtx dest1, dest2;
3461   rtx srca1, srca2, srcb1, srcb2;
3463   dest1 = gen_df_reg (set_dest, 0);
3464   dest2 = gen_df_reg (set_dest, 1);
3465   srca1 = gen_df_reg (set_srca, 0);
3466   srca2 = gen_df_reg (set_srca, 1);
3467   srcb1 = gen_df_reg (set_srcb, 0);
3468   srcb2 = gen_df_reg (set_srcb, 1);
3470   /* Now emit using the real source and destination we found, swapping
3471      the order if we detect overlap.  */
3472   if ((third && reg_overlap_mentioned_p (dest1, srcb2))
3473       || (!third && reg_overlap_mentioned_p (dest1, srca2)))
3474     {
3475       emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3476       emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3477     }
3478   else
3479     {
3480       emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3481       emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3482     }
3483   DONE;
3485   [(set_attr "length" "2")])
3488 ;; Zero-extension instructions
3490 ;; These patterns originally accepted general_operands, however, slightly
3491 ;; better code is generated by only accepting register_operands, and then
3492 ;; letting combine generate the ldu[hb] insns.
3494 (define_expand "zero_extendhisi2"
3495   [(set (match_operand:SI 0 "register_operand" "")
3496         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
3497   ""
3499   rtx temp = gen_reg_rtx (SImode);
3500   rtx shift_16 = GEN_INT (16);
3501   int op1_subbyte = 0;
3503   if (GET_CODE (operand1) == SUBREG)
3504     {
3505       op1_subbyte = SUBREG_BYTE (operand1);
3506       op1_subbyte /= GET_MODE_SIZE (SImode);
3507       op1_subbyte *= GET_MODE_SIZE (SImode);
3508       operand1 = XEXP (operand1, 0);
3509     }
3511   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3512                           shift_16));
3513   emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
3514   DONE;
3517 (define_insn "*zero_extendhisi2_insn"
3518   [(set (match_operand:SI 0 "register_operand" "=r")
3519         (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3520   ""
3521   "lduh\t%1, %0"
3522   [(set_attr "type" "load")
3523    (set_attr "us3load_type" "3cycle")])
3525 (define_expand "zero_extendqihi2"
3526   [(set (match_operand:HI 0 "register_operand" "")
3527         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
3528   ""
3529   "")
3531 (define_insn "*zero_extendqihi2_insn"
3532   [(set (match_operand:HI 0 "register_operand" "=r,r")
3533         (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
3534   "GET_CODE (operands[1]) != CONST_INT"
3535   "@
3536    and\t%1, 0xff, %0
3537    ldub\t%1, %0"
3538   [(set_attr "type" "*,load")
3539    (set_attr "us3load_type" "*,3cycle")])
3541 (define_expand "zero_extendqisi2"
3542   [(set (match_operand:SI 0 "register_operand" "")
3543         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
3544   ""
3545   "")
3547 (define_insn "*zero_extendqisi2_insn"
3548   [(set (match_operand:SI 0 "register_operand" "=r,r")
3549         (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
3550   "GET_CODE (operands[1]) != CONST_INT"
3551   "@
3552    and\t%1, 0xff, %0
3553    ldub\t%1, %0"
3554   [(set_attr "type" "*,load")
3555    (set_attr "us3load_type" "*,3cycle")])
3557 (define_expand "zero_extendqidi2"
3558   [(set (match_operand:DI 0 "register_operand" "")
3559         (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
3560   "TARGET_ARCH64"
3561   "")
3563 (define_insn "*zero_extendqidi2_insn"
3564   [(set (match_operand:DI 0 "register_operand" "=r,r")
3565         (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
3566   "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
3567   "@
3568    and\t%1, 0xff, %0
3569    ldub\t%1, %0"
3570   [(set_attr "type" "*,load")
3571    (set_attr "us3load_type" "*,3cycle")])
3573 (define_expand "zero_extendhidi2"
3574   [(set (match_operand:DI 0 "register_operand" "")
3575         (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
3576   "TARGET_ARCH64"
3578   rtx temp = gen_reg_rtx (DImode);
3579   rtx shift_48 = GEN_INT (48);
3580   int op1_subbyte = 0;
3582   if (GET_CODE (operand1) == SUBREG)
3583     {
3584       op1_subbyte = SUBREG_BYTE (operand1);
3585       op1_subbyte /= GET_MODE_SIZE (DImode);
3586       op1_subbyte *= GET_MODE_SIZE (DImode);
3587       operand1 = XEXP (operand1, 0);
3588     }
3590   emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3591                           shift_48));
3592   emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
3593   DONE;
3596 (define_insn "*zero_extendhidi2_insn"
3597   [(set (match_operand:DI 0 "register_operand" "=r")
3598         (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3599   "TARGET_ARCH64"
3600   "lduh\t%1, %0"
3601   [(set_attr "type" "load")
3602    (set_attr "us3load_type" "3cycle")])
3604 ;; ??? Write truncdisi pattern using sra?
3606 (define_expand "zero_extendsidi2"
3607   [(set (match_operand:DI 0 "register_operand" "")
3608         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
3609   ""
3610   "")
3612 (define_insn "*zero_extendsidi2_insn_sp64"
3613   [(set (match_operand:DI 0 "register_operand" "=r,r")
3614         (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
3615   "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
3616   "@
3617    srl\t%1, 0, %0
3618    lduw\t%1, %0"
3619   [(set_attr "type" "shift,load")])
3621 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
3622   [(set (match_operand:DI 0 "register_operand" "=r")
3623         (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
3624   "! TARGET_ARCH64"
3625   "#"
3626   "&& reload_completed"
3627   [(set (match_dup 2) (match_dup 3))
3628    (set (match_dup 4) (match_dup 5))]
3630   rtx dest1, dest2;
3632   dest1 = gen_highpart (SImode, operands[0]);
3633   dest2 = gen_lowpart (SImode, operands[0]);
3635   /* Swap the order in case of overlap.  */
3636   if (REGNO (dest1) == REGNO (operands[1]))
3637     {
3638       operands[2] = dest2;
3639       operands[3] = operands[1];
3640       operands[4] = dest1;
3641       operands[5] = const0_rtx;
3642     }
3643   else
3644     {
3645       operands[2] = dest1;
3646       operands[3] = const0_rtx;
3647       operands[4] = dest2;
3648       operands[5] = operands[1];
3649     }
3651   [(set_attr "length" "2")])
3653 ;; Simplify comparisons of extended values.
3655 (define_insn "*cmp_zero_extendqisi2"
3656   [(set (reg:CC 100)
3657         (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
3658                     (const_int 0)))]
3659   ""
3660   "andcc\t%0, 0xff, %%g0"
3661   [(set_attr "type" "compare")])
3663 (define_insn "*cmp_zero_qi"
3664   [(set (reg:CC 100)
3665         (compare:CC (match_operand:QI 0 "register_operand" "r")
3666                     (const_int 0)))]
3667   ""
3668   "andcc\t%0, 0xff, %%g0"
3669   [(set_attr "type" "compare")])
3671 (define_insn "*cmp_zero_extendqisi2_set"
3672   [(set (reg:CC 100)
3673         (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
3674                     (const_int 0)))
3675    (set (match_operand:SI 0 "register_operand" "=r")
3676         (zero_extend:SI (match_dup 1)))]
3677   ""
3678   "andcc\t%1, 0xff, %0"
3679   [(set_attr "type" "compare")])
3681 (define_insn "*cmp_zero_extendqisi2_andcc_set"
3682   [(set (reg:CC 100)
3683         (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
3684                             (const_int 255))
3685                     (const_int 0)))
3686    (set (match_operand:SI 0 "register_operand" "=r")
3687         (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
3688   ""
3689   "andcc\t%1, 0xff, %0"
3690   [(set_attr "type" "compare")])
3692 (define_insn "*cmp_zero_extendqidi2"
3693   [(set (reg:CCX 100)
3694         (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
3695                      (const_int 0)))]
3696   "TARGET_ARCH64"
3697   "andcc\t%0, 0xff, %%g0"
3698   [(set_attr "type" "compare")])
3700 (define_insn "*cmp_zero_qi_sp64"
3701   [(set (reg:CCX 100)
3702         (compare:CCX (match_operand:QI 0 "register_operand" "r")
3703                      (const_int 0)))]
3704   "TARGET_ARCH64"
3705   "andcc\t%0, 0xff, %%g0"
3706   [(set_attr "type" "compare")])
3708 (define_insn "*cmp_zero_extendqidi2_set"
3709   [(set (reg:CCX 100)
3710         (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
3711                      (const_int 0)))
3712    (set (match_operand:DI 0 "register_operand" "=r")
3713         (zero_extend:DI (match_dup 1)))]
3714   "TARGET_ARCH64"
3715   "andcc\t%1, 0xff, %0"
3716   [(set_attr "type" "compare")])
3718 (define_insn "*cmp_zero_extendqidi2_andcc_set"
3719   [(set (reg:CCX 100)
3720         (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
3721                              (const_int 255))
3722                      (const_int 0)))
3723    (set (match_operand:DI 0 "register_operand" "=r")
3724         (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
3725   "TARGET_ARCH64"
3726   "andcc\t%1, 0xff, %0"
3727   [(set_attr "type" "compare")])
3729 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
3731 (define_insn "*cmp_siqi_trunc"
3732   [(set (reg:CC 100)
3733         (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
3734                     (const_int 0)))]
3735   ""
3736   "andcc\t%0, 0xff, %%g0"
3737   [(set_attr "type" "compare")])
3739 (define_insn "*cmp_siqi_trunc_set"
3740   [(set (reg:CC 100)
3741         (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
3742                     (const_int 0)))
3743    (set (match_operand:QI 0 "register_operand" "=r")
3744         (subreg:QI (match_dup 1) 3))]
3745   ""
3746   "andcc\t%1, 0xff, %0"
3747   [(set_attr "type" "compare")])
3749 (define_insn "*cmp_diqi_trunc"
3750   [(set (reg:CC 100)
3751         (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
3752                     (const_int 0)))]
3753   "TARGET_ARCH64"
3754   "andcc\t%0, 0xff, %%g0"
3755   [(set_attr "type" "compare")])
3757 (define_insn "*cmp_diqi_trunc_set"
3758   [(set (reg:CC 100)
3759         (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
3760                     (const_int 0)))
3761    (set (match_operand:QI 0 "register_operand" "=r")
3762         (subreg:QI (match_dup 1) 7))]
3763   "TARGET_ARCH64"
3764   "andcc\t%1, 0xff, %0"
3765   [(set_attr "type" "compare")])
3768 ;; Sign-extension instructions
3770 ;; These patterns originally accepted general_operands, however, slightly
3771 ;; better code is generated by only accepting register_operands, and then
3772 ;; letting combine generate the lds[hb] insns.
3774 (define_expand "extendhisi2"
3775   [(set (match_operand:SI 0 "register_operand" "")
3776         (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
3777   ""
3779   rtx temp = gen_reg_rtx (SImode);
3780   rtx shift_16 = GEN_INT (16);
3781   int op1_subbyte = 0;
3783   if (GET_CODE (operand1) == SUBREG)
3784     {
3785       op1_subbyte = SUBREG_BYTE (operand1);
3786       op1_subbyte /= GET_MODE_SIZE (SImode);
3787       op1_subbyte *= GET_MODE_SIZE (SImode);
3788       operand1 = XEXP (operand1, 0);
3789     }
3791   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3792                           shift_16));
3793   emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
3794   DONE;
3797 (define_insn "*sign_extendhisi2_insn"
3798   [(set (match_operand:SI 0 "register_operand" "=r")
3799         (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3800   ""
3801   "ldsh\t%1, %0"
3802   [(set_attr "type" "sload")
3803    (set_attr "us3load_type" "3cycle")])
3805 (define_expand "extendqihi2"
3806   [(set (match_operand:HI 0 "register_operand" "")
3807         (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
3808   ""
3810   rtx temp = gen_reg_rtx (SImode);
3811   rtx shift_24 = GEN_INT (24);
3812   int op1_subbyte = 0;
3813   int op0_subbyte = 0;
3815   if (GET_CODE (operand1) == SUBREG)
3816     {
3817       op1_subbyte = SUBREG_BYTE (operand1);
3818       op1_subbyte /= GET_MODE_SIZE (SImode);
3819       op1_subbyte *= GET_MODE_SIZE (SImode);
3820       operand1 = XEXP (operand1, 0);
3821     }
3822   if (GET_CODE (operand0) == SUBREG)
3823     {
3824       op0_subbyte = SUBREG_BYTE (operand0);
3825       op0_subbyte /= GET_MODE_SIZE (SImode);
3826       op0_subbyte *= GET_MODE_SIZE (SImode);
3827       operand0 = XEXP (operand0, 0);
3828     }
3829   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3830                           shift_24));
3831   if (GET_MODE (operand0) != SImode)
3832     operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
3833   emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3834   DONE;
3837 (define_insn "*sign_extendqihi2_insn"
3838   [(set (match_operand:HI 0 "register_operand" "=r")
3839         (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3840   ""
3841   "ldsb\t%1, %0"
3842   [(set_attr "type" "sload")
3843    (set_attr "us3load_type" "3cycle")])
3845 (define_expand "extendqisi2"
3846   [(set (match_operand:SI 0 "register_operand" "")
3847         (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
3848   ""
3850   rtx temp = gen_reg_rtx (SImode);
3851   rtx shift_24 = GEN_INT (24);
3852   int op1_subbyte = 0;
3854   if (GET_CODE (operand1) == SUBREG)
3855     {
3856       op1_subbyte = SUBREG_BYTE (operand1);
3857       op1_subbyte /= GET_MODE_SIZE (SImode);
3858       op1_subbyte *= GET_MODE_SIZE (SImode);
3859       operand1 = XEXP (operand1, 0);
3860     }
3862   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3863                           shift_24));
3864   emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3865   DONE;
3868 (define_insn "*sign_extendqisi2_insn"
3869   [(set (match_operand:SI 0 "register_operand" "=r")
3870         (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3871   ""
3872   "ldsb\t%1, %0"
3873   [(set_attr "type" "sload")
3874    (set_attr "us3load_type" "3cycle")])
3876 (define_expand "extendqidi2"
3877   [(set (match_operand:DI 0 "register_operand" "")
3878         (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
3879   "TARGET_ARCH64"
3881   rtx temp = gen_reg_rtx (DImode);
3882   rtx shift_56 = GEN_INT (56);
3883   int op1_subbyte = 0;
3885   if (GET_CODE (operand1) == SUBREG)
3886     {
3887       op1_subbyte = SUBREG_BYTE (operand1);
3888       op1_subbyte /= GET_MODE_SIZE (DImode);
3889       op1_subbyte *= GET_MODE_SIZE (DImode);
3890       operand1 = XEXP (operand1, 0);
3891     }
3893   emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3894                           shift_56));
3895   emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
3896   DONE;
3899 (define_insn "*sign_extendqidi2_insn"
3900   [(set (match_operand:DI 0 "register_operand" "=r")
3901         (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3902   "TARGET_ARCH64"
3903   "ldsb\t%1, %0"
3904   [(set_attr "type" "sload")
3905    (set_attr "us3load_type" "3cycle")])
3907 (define_expand "extendhidi2"
3908   [(set (match_operand:DI 0 "register_operand" "")
3909         (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
3910   "TARGET_ARCH64"
3912   rtx temp = gen_reg_rtx (DImode);
3913   rtx shift_48 = GEN_INT (48);
3914   int op1_subbyte = 0;
3916   if (GET_CODE (operand1) == SUBREG)
3917     {
3918       op1_subbyte = SUBREG_BYTE (operand1);
3919       op1_subbyte /= GET_MODE_SIZE (DImode);
3920       op1_subbyte *= GET_MODE_SIZE (DImode);
3921       operand1 = XEXP (operand1, 0);
3922     }
3924   emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3925                           shift_48));
3926   emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
3927   DONE;
3930 (define_insn "*sign_extendhidi2_insn"
3931   [(set (match_operand:DI 0 "register_operand" "=r")
3932         (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3933   "TARGET_ARCH64"
3934   "ldsh\t%1, %0"
3935   [(set_attr "type" "sload")
3936    (set_attr "us3load_type" "3cycle")])
3938 (define_expand "extendsidi2"
3939   [(set (match_operand:DI 0 "register_operand" "")
3940         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3941   "TARGET_ARCH64"
3942   "")
3944 (define_insn "*sign_extendsidi2_insn"
3945   [(set (match_operand:DI 0 "register_operand" "=r,r")
3946         (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
3947   "TARGET_ARCH64"
3948   "@
3949   sra\t%1, 0, %0
3950   ldsw\t%1, %0"
3951   [(set_attr "type" "shift,sload")
3952    (set_attr "us3load_type" "*,3cycle")])
3955 ;; Special pattern for optimizing bit-field compares.  This is needed
3956 ;; because combine uses this as a canonical form.
3958 (define_insn "*cmp_zero_extract"
3959   [(set (reg:CC 100)
3960         (compare:CC
3961          (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
3962                           (match_operand:SI 1 "small_int_operand" "I")
3963                           (match_operand:SI 2 "small_int_operand" "I"))
3964          (const_int 0)))]
3965   "INTVAL (operands[2]) > 19"
3967   int len = INTVAL (operands[1]);
3968   int pos = 32 - INTVAL (operands[2]) - len;
3969   HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
3970   operands[1] = GEN_INT (mask);
3971   return "andcc\t%0, %1, %%g0";
3973   [(set_attr "type" "compare")])
3975 (define_insn "*cmp_zero_extract_sp64"
3976   [(set (reg:CCX 100)
3977         (compare:CCX
3978          (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
3979                           (match_operand:SI 1 "small_int_operand" "I")
3980                           (match_operand:SI 2 "small_int_operand" "I"))
3981          (const_int 0)))]
3982   "TARGET_ARCH64 && INTVAL (operands[2]) > 51"
3984   int len = INTVAL (operands[1]);
3985   int pos = 64 - INTVAL (operands[2]) - len;
3986   HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
3987   operands[1] = GEN_INT (mask);
3988   return "andcc\t%0, %1, %%g0";
3990   [(set_attr "type" "compare")])
3993 ;; Conversions between float, double and long double.
3995 (define_insn "extendsfdf2"
3996   [(set (match_operand:DF 0 "register_operand" "=e")
3997         (float_extend:DF
3998          (match_operand:SF 1 "register_operand" "f")))]
3999   "TARGET_FPU"
4000   "fstod\t%1, %0"
4001   [(set_attr "type" "fp")
4002    (set_attr "fptype" "double")])
4004 (define_expand "extendsftf2"
4005   [(set (match_operand:TF 0 "nonimmediate_operand" "")
4006         (float_extend:TF
4007          (match_operand:SF 1 "register_operand" "")))]
4008   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4009   "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4011 (define_insn "*extendsftf2_hq"
4012   [(set (match_operand:TF 0 "register_operand" "=e")
4013         (float_extend:TF
4014          (match_operand:SF 1 "register_operand" "f")))]
4015   "TARGET_FPU && TARGET_HARD_QUAD"
4016   "fstoq\t%1, %0"
4017   [(set_attr "type" "fp")])
4019 (define_expand "extenddftf2"
4020   [(set (match_operand:TF 0 "nonimmediate_operand" "")
4021         (float_extend:TF
4022          (match_operand:DF 1 "register_operand" "")))]
4023   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4024   "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
4026 (define_insn "*extenddftf2_hq"
4027   [(set (match_operand:TF 0 "register_operand" "=e")
4028         (float_extend:TF
4029          (match_operand:DF 1 "register_operand" "e")))]
4030   "TARGET_FPU && TARGET_HARD_QUAD"
4031   "fdtoq\t%1, %0"
4032   [(set_attr "type" "fp")])
4034 (define_insn "truncdfsf2"
4035   [(set (match_operand:SF 0 "register_operand" "=f")
4036         (float_truncate:SF
4037          (match_operand:DF 1 "register_operand" "e")))]
4038   "TARGET_FPU"
4039   "fdtos\t%1, %0"
4040   [(set_attr "type" "fp")
4041    (set_attr "fptype" "double")])
4043 (define_expand "trunctfsf2"
4044   [(set (match_operand:SF 0 "register_operand" "")
4045         (float_truncate:SF
4046          (match_operand:TF 1 "general_operand" "")))]
4047   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4048   "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4050 (define_insn "*trunctfsf2_hq"
4051   [(set (match_operand:SF 0 "register_operand" "=f")
4052         (float_truncate:SF
4053          (match_operand:TF 1 "register_operand" "e")))]
4054   "TARGET_FPU && TARGET_HARD_QUAD"
4055   "fqtos\t%1, %0"
4056   [(set_attr "type" "fp")])
4058 (define_expand "trunctfdf2"
4059   [(set (match_operand:DF 0 "register_operand" "")
4060         (float_truncate:DF
4061          (match_operand:TF 1 "general_operand" "")))]
4062   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4063   "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
4065 (define_insn "*trunctfdf2_hq"
4066   [(set (match_operand:DF 0 "register_operand" "=e")
4067         (float_truncate:DF
4068          (match_operand:TF 1 "register_operand" "e")))]
4069   "TARGET_FPU && TARGET_HARD_QUAD"
4070   "fqtod\t%1, %0"
4071   [(set_attr "type" "fp")])
4074 ;; Conversion between fixed point and floating point.
4076 (define_insn "floatsisf2"
4077   [(set (match_operand:SF 0 "register_operand" "=f")
4078         (float:SF (match_operand:SI 1 "register_operand" "f")))]
4079   "TARGET_FPU"
4080   "fitos\t%1, %0"
4081   [(set_attr "type" "fp")
4082    (set_attr "fptype" "double")])
4084 (define_insn "floatsidf2"
4085   [(set (match_operand:DF 0 "register_operand" "=e")
4086         (float:DF (match_operand:SI 1 "register_operand" "f")))]
4087   "TARGET_FPU"
4088   "fitod\t%1, %0"
4089   [(set_attr "type" "fp")
4090    (set_attr "fptype" "double")])
4092 (define_expand "floatsitf2"
4093   [(set (match_operand:TF 0 "nonimmediate_operand" "")
4094         (float:TF (match_operand:SI 1 "register_operand" "")))]
4095   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4096   "emit_tfmode_cvt (FLOAT, operands); DONE;")
4098 (define_insn "*floatsitf2_hq"
4099   [(set (match_operand:TF 0 "register_operand" "=e")
4100         (float:TF (match_operand:SI 1 "register_operand" "f")))]
4101   "TARGET_FPU && TARGET_HARD_QUAD"
4102   "fitoq\t%1, %0"
4103   [(set_attr "type" "fp")])
4105 (define_expand "floatunssitf2"
4106   [(set (match_operand:TF 0 "nonimmediate_operand" "")
4107         (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
4108   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4109   "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4111 ;; Now the same for 64 bit sources.
4113 (define_insn "floatdisf2"
4114   [(set (match_operand:SF 0 "register_operand" "=f")
4115         (float:SF (match_operand:DI 1 "register_operand" "e")))]
4116   "TARGET_V9 && TARGET_FPU"
4117   "fxtos\t%1, %0"
4118   [(set_attr "type" "fp")
4119    (set_attr "fptype" "double")])
4121 (define_expand "floatunsdisf2"
4122   [(use (match_operand:SF 0 "register_operand" ""))
4123    (use (match_operand:DI 1 "general_operand" ""))]
4124   "TARGET_ARCH64 && TARGET_FPU"
4125   "sparc_emit_floatunsdi (operands, SFmode); DONE;")
4127 (define_insn "floatdidf2"
4128   [(set (match_operand:DF 0 "register_operand" "=e")
4129         (float:DF (match_operand:DI 1 "register_operand" "e")))]
4130   "TARGET_V9 && TARGET_FPU"
4131   "fxtod\t%1, %0"
4132   [(set_attr "type" "fp")
4133    (set_attr "fptype" "double")])
4135 (define_expand "floatunsdidf2"
4136   [(use (match_operand:DF 0 "register_operand" ""))
4137    (use (match_operand:DI 1 "general_operand" ""))]
4138   "TARGET_ARCH64 && TARGET_FPU"
4139   "sparc_emit_floatunsdi (operands, DFmode); DONE;")
4141 (define_expand "floatditf2"
4142   [(set (match_operand:TF 0 "nonimmediate_operand" "")
4143         (float:TF (match_operand:DI 1 "register_operand" "")))]
4144   "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4145   "emit_tfmode_cvt (FLOAT, operands); DONE;")
4147 (define_insn "*floatditf2_hq"
4148   [(set (match_operand:TF 0 "register_operand" "=e")
4149         (float:TF (match_operand:DI 1 "register_operand" "e")))]
4150   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4151   "fxtoq\t%1, %0"
4152   [(set_attr "type" "fp")])
4154 (define_expand "floatunsditf2"
4155   [(set (match_operand:TF 0 "nonimmediate_operand" "")
4156         (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
4157   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4158   "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
4160 ;; Convert a float to an actual integer.
4161 ;; Truncation is performed as part of the conversion.
4163 (define_insn "fix_truncsfsi2"
4164   [(set (match_operand:SI 0 "register_operand" "=f")
4165         (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4166   "TARGET_FPU"
4167   "fstoi\t%1, %0"
4168   [(set_attr "type" "fp")
4169    (set_attr "fptype" "double")])
4171 (define_insn "fix_truncdfsi2"
4172   [(set (match_operand:SI 0 "register_operand" "=f")
4173         (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4174   "TARGET_FPU"
4175   "fdtoi\t%1, %0"
4176   [(set_attr "type" "fp")
4177    (set_attr "fptype" "double")])
4179 (define_expand "fix_trunctfsi2"
4180   [(set (match_operand:SI 0 "register_operand" "")
4181         (fix:SI (match_operand:TF 1 "general_operand" "")))]
4182   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4183   "emit_tfmode_cvt (FIX, operands); DONE;")
4185 (define_insn "*fix_trunctfsi2_hq"
4186   [(set (match_operand:SI 0 "register_operand" "=f")
4187         (fix:SI (match_operand:TF 1 "register_operand" "e")))]
4188   "TARGET_FPU && TARGET_HARD_QUAD"
4189   "fqtoi\t%1, %0"
4190   [(set_attr "type" "fp")])
4192 (define_expand "fixuns_trunctfsi2"
4193   [(set (match_operand:SI 0 "register_operand" "")
4194         (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
4195   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4196   "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4198 ;; Now the same, for V9 targets
4200 (define_insn "fix_truncsfdi2"
4201   [(set (match_operand:DI 0 "register_operand" "=e")
4202         (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4203   "TARGET_V9 && TARGET_FPU"
4204   "fstox\t%1, %0"
4205   [(set_attr "type" "fp")
4206    (set_attr "fptype" "double")])
4208 (define_expand "fixuns_truncsfdi2"
4209   [(use (match_operand:DI 0 "register_operand" ""))
4210    (use (match_operand:SF 1 "general_operand" ""))]
4211   "TARGET_ARCH64 && TARGET_FPU"
4212   "sparc_emit_fixunsdi (operands, SFmode); DONE;")
4214 (define_insn "fix_truncdfdi2"
4215   [(set (match_operand:DI 0 "register_operand" "=e")
4216         (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4217   "TARGET_V9 && TARGET_FPU"
4218   "fdtox\t%1, %0"
4219   [(set_attr "type" "fp")
4220    (set_attr "fptype" "double")])
4222 (define_expand "fixuns_truncdfdi2"
4223   [(use (match_operand:DI 0 "register_operand" ""))
4224    (use (match_operand:DF 1 "general_operand" ""))]
4225   "TARGET_ARCH64 && TARGET_FPU"
4226   "sparc_emit_fixunsdi (operands, DFmode); DONE;")
4228 (define_expand "fix_trunctfdi2"
4229   [(set (match_operand:DI 0 "register_operand" "")
4230         (fix:DI (match_operand:TF 1 "general_operand" "")))]
4231   "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4232   "emit_tfmode_cvt (FIX, operands); DONE;")
4234 (define_insn "*fix_trunctfdi2_hq"
4235   [(set (match_operand:DI 0 "register_operand" "=e")
4236         (fix:DI (match_operand:TF 1 "register_operand" "e")))]
4237   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4238   "fqtox\t%1, %0"
4239   [(set_attr "type" "fp")])
4241 (define_expand "fixuns_trunctfdi2"
4242   [(set (match_operand:DI 0 "register_operand" "")
4243         (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
4244   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4245   "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4248 ;; Integer addition/subtraction instructions.
4250 (define_expand "adddi3"
4251   [(set (match_operand:DI 0 "register_operand" "")
4252         (plus:DI (match_operand:DI 1 "register_operand" "")
4253                  (match_operand:DI 2 "arith_double_add_operand" "")))]
4254   ""
4256   if (! TARGET_ARCH64)
4257     {
4258       emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4259                           gen_rtx_SET (VOIDmode, operands[0],
4260                                    gen_rtx_PLUS (DImode, operands[1],
4261                                                  operands[2])),
4262                           gen_rtx_CLOBBER (VOIDmode,
4263                                    gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4264       DONE;
4265     }
4268 (define_insn_and_split "adddi3_insn_sp32"
4269   [(set (match_operand:DI 0 "register_operand" "=r")
4270         (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4271                  (match_operand:DI 2 "arith_double_operand" "rHI")))
4272    (clobber (reg:CC 100))]
4273   "! TARGET_ARCH64"
4274   "#"
4275   "&& reload_completed"
4276   [(parallel [(set (reg:CC_NOOV 100)
4277                    (compare:CC_NOOV (plus:SI (match_dup 4)
4278                                              (match_dup 5))
4279                                     (const_int 0)))
4280               (set (match_dup 3)
4281                    (plus:SI (match_dup 4) (match_dup 5)))])
4282    (set (match_dup 6)
4283         (plus:SI (plus:SI (match_dup 7)
4284                           (match_dup 8))
4285                  (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4287   operands[3] = gen_lowpart (SImode, operands[0]);
4288   operands[4] = gen_lowpart (SImode, operands[1]);
4289   operands[5] = gen_lowpart (SImode, operands[2]);
4290   operands[6] = gen_highpart (SImode, operands[0]);
4291   operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
4292 #if HOST_BITS_PER_WIDE_INT == 32
4293   if (GET_CODE (operands[2]) == CONST_INT)
4294     {
4295       if (INTVAL (operands[2]) < 0)
4296         operands[8] = constm1_rtx;
4297       else
4298         operands[8] = const0_rtx;
4299     }
4300   else
4301 #endif
4302     operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4304   [(set_attr "length" "2")])
4306 ;; LTU here means "carry set"
4307 (define_insn "addx"
4308   [(set (match_operand:SI 0 "register_operand" "=r")
4309         (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4310                           (match_operand:SI 2 "arith_operand" "rI"))
4311                  (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4312   ""
4313   "addx\t%1, %2, %0"
4314   [(set_attr "type" "ialuX")])
4316 (define_insn_and_split "*addx_extend_sp32"
4317   [(set (match_operand:DI 0 "register_operand" "=r")
4318         (zero_extend:DI (plus:SI (plus:SI
4319                                   (match_operand:SI 1 "register_or_zero_operand" "%rJ")
4320                                   (match_operand:SI 2 "arith_operand" "rI"))
4321                                  (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4322   "! TARGET_ARCH64"
4323   "#"
4324   "&& reload_completed"
4325   [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
4326                                (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4327    (set (match_dup 4) (const_int 0))]
4328   "operands[3] = gen_lowpart (SImode, operands[0]);
4329    operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
4330   [(set_attr "length" "2")])
4332 (define_insn "*addx_extend_sp64"
4333   [(set (match_operand:DI 0 "register_operand" "=r")
4334         (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
4335                                           (match_operand:SI 2 "arith_operand" "rI"))
4336                                  (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4337   "TARGET_ARCH64"
4338   "addx\t%r1, %2, %0"
4339   [(set_attr "type" "ialuX")])
4341 (define_insn_and_split ""
4342   [(set (match_operand:DI 0 "register_operand" "=r")
4343         (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4344                  (match_operand:DI 2 "register_operand" "r")))
4345    (clobber (reg:CC 100))]
4346   "! TARGET_ARCH64"
4347   "#"
4348   "&& reload_completed"
4349   [(parallel [(set (reg:CC_NOOV 100)
4350                    (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
4351                                     (const_int 0)))
4352               (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
4353    (set (match_dup 6)
4354         (plus:SI (plus:SI (match_dup 4) (const_int 0))
4355                  (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4356   "operands[3] = gen_lowpart (SImode, operands[2]);
4357    operands[4] = gen_highpart (SImode, operands[2]);
4358    operands[5] = gen_lowpart (SImode, operands[0]);
4359    operands[6] = gen_highpart (SImode, operands[0]);"
4360   [(set_attr "length" "2")])
4362 (define_insn "*adddi3_sp64"
4363   [(set (match_operand:DI 0 "register_operand" "=r,r")
4364         (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
4365                  (match_operand:DI 2 "arith_add_operand" "rI,O")))]
4366   "TARGET_ARCH64"
4367   "@
4368    add\t%1, %2, %0
4369    sub\t%1, -%2, %0")
4371 (define_insn "addsi3"
4372   [(set (match_operand:SI 0 "register_operand" "=r,r,d")
4373         (plus:SI (match_operand:SI 1 "register_operand" "%r,r,d")
4374                  (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
4375   ""
4376   "@
4377    add\t%1, %2, %0
4378    sub\t%1, -%2, %0
4379    fpadd32s\t%1, %2, %0"
4380   [(set_attr "type" "*,*,fga")
4381    (set_attr "fptype" "*,*,single")])
4383 (define_insn "*cmp_cc_plus"
4384   [(set (reg:CC_NOOV 100)
4385         (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
4386                                   (match_operand:SI 1 "arith_operand" "rI"))
4387                          (const_int 0)))]
4388   ""
4389   "addcc\t%0, %1, %%g0"
4390   [(set_attr "type" "compare")])
4392 (define_insn "*cmp_ccx_plus"
4393   [(set (reg:CCX_NOOV 100)
4394         (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_operand" "%r")
4395                                    (match_operand:DI 1 "arith_operand" "rI"))
4396                           (const_int 0)))]
4397   "TARGET_ARCH64"
4398   "addcc\t%0, %1, %%g0"
4399   [(set_attr "type" "compare")])
4401 (define_insn "*cmp_cc_plus_set"
4402   [(set (reg:CC_NOOV 100)
4403         (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4404                                   (match_operand:SI 2 "arith_operand" "rI"))
4405                          (const_int 0)))
4406    (set (match_operand:SI 0 "register_operand" "=r")
4407         (plus:SI (match_dup 1) (match_dup 2)))]
4408   ""
4409   "addcc\t%1, %2, %0"
4410   [(set_attr "type" "compare")])
4412 (define_insn "*cmp_ccx_plus_set"
4413   [(set (reg:CCX_NOOV 100)
4414         (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_operand" "%r")
4415                                    (match_operand:DI 2 "arith_operand" "rI"))
4416                           (const_int 0)))
4417    (set (match_operand:DI 0 "register_operand" "=r")
4418         (plus:DI (match_dup 1) (match_dup 2)))]
4419   "TARGET_ARCH64"
4420   "addcc\t%1, %2, %0"
4421   [(set_attr "type" "compare")])
4423 (define_expand "subdi3"
4424   [(set (match_operand:DI 0 "register_operand" "")
4425         (minus:DI (match_operand:DI 1 "register_operand" "")
4426                   (match_operand:DI 2 "arith_double_add_operand" "")))]
4427   ""
4429   if (! TARGET_ARCH64)
4430     {
4431       emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4432                           gen_rtx_SET (VOIDmode, operands[0],
4433                                    gen_rtx_MINUS (DImode, operands[1],
4434                                                   operands[2])),
4435                           gen_rtx_CLOBBER (VOIDmode,
4436                                    gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4437       DONE;
4438     }
4441 (define_insn_and_split "subdi3_insn_sp32"
4442   [(set (match_operand:DI 0 "register_operand" "=r")
4443         (minus:DI (match_operand:DI 1 "register_operand" "r")
4444                   (match_operand:DI 2 "arith_double_operand" "rHI")))
4445    (clobber (reg:CC 100))]
4446   "! TARGET_ARCH64"
4447   "#"
4448   "&& reload_completed"
4449   [(parallel [(set (reg:CC_NOOV 100)
4450                    (compare:CC_NOOV (minus:SI (match_dup 4)
4451                                               (match_dup 5))
4452                                     (const_int 0)))
4453               (set (match_dup 3)
4454                    (minus:SI (match_dup 4) (match_dup 5)))])
4455    (set (match_dup 6)
4456         (minus:SI (minus:SI (match_dup 7)
4457                             (match_dup 8))
4458                   (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4460   operands[3] = gen_lowpart (SImode, operands[0]);
4461   operands[4] = gen_lowpart (SImode, operands[1]);
4462   operands[5] = gen_lowpart (SImode, operands[2]);
4463   operands[6] = gen_highpart (SImode, operands[0]);
4464   operands[7] = gen_highpart (SImode, operands[1]);
4465 #if HOST_BITS_PER_WIDE_INT == 32
4466   if (GET_CODE (operands[2]) == CONST_INT)
4467     {
4468       if (INTVAL (operands[2]) < 0)
4469         operands[8] = constm1_rtx;
4470       else
4471         operands[8] = const0_rtx;
4472     }
4473   else
4474 #endif
4475     operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4477   [(set_attr "length" "2")])
4479 ;; LTU here means "carry set"
4480 (define_insn "subx"
4481   [(set (match_operand:SI 0 "register_operand" "=r")
4482         (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4483                             (match_operand:SI 2 "arith_operand" "rI"))
4484                   (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4485   ""
4486   "subx\t%r1, %2, %0"
4487   [(set_attr "type" "ialuX")])
4489 (define_insn "*subx_extend_sp64"
4490   [(set (match_operand:DI 0 "register_operand" "=r")
4491         (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4492                                             (match_operand:SI 2 "arith_operand" "rI"))
4493                                   (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4494   "TARGET_ARCH64"
4495   "subx\t%r1, %2, %0"
4496   [(set_attr "type" "ialuX")])
4498 (define_insn_and_split "*subx_extend"
4499   [(set (match_operand:DI 0 "register_operand" "=r")
4500         (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4501                                             (match_operand:SI 2 "arith_operand" "rI"))
4502                                   (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4503   "! TARGET_ARCH64"
4504   "#"
4505   "&& reload_completed"
4506   [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
4507                                 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4508    (set (match_dup 4) (const_int 0))]
4509   "operands[3] = gen_lowpart (SImode, operands[0]);
4510    operands[4] = gen_highpart (SImode, operands[0]);"
4511   [(set_attr "length" "2")])
4513 (define_insn_and_split ""
4514   [(set (match_operand:DI 0 "register_operand" "=r")
4515       (minus:DI (match_operand:DI 1 "register_operand" "r")
4516                 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
4517    (clobber (reg:CC 100))]
4518   "! TARGET_ARCH64"
4519   "#"
4520   "&& reload_completed"
4521   [(parallel [(set (reg:CC_NOOV 100)
4522                    (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
4523                                     (const_int 0)))
4524               (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
4525    (set (match_dup 6)
4526         (minus:SI (minus:SI (match_dup 4) (const_int 0))
4527                   (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4528   "operands[3] = gen_lowpart (SImode, operands[1]);
4529    operands[4] = gen_highpart (SImode, operands[1]);
4530    operands[5] = gen_lowpart (SImode, operands[0]);
4531    operands[6] = gen_highpart (SImode, operands[0]);"
4532   [(set_attr "length" "2")])
4534 (define_insn "*subdi3_sp64"
4535   [(set (match_operand:DI 0 "register_operand" "=r,r")
4536         (minus:DI (match_operand:DI 1 "register_operand" "r,r")
4537                   (match_operand:DI 2 "arith_add_operand" "rI,O")))]
4538   "TARGET_ARCH64"
4539   "@
4540    sub\t%1, %2, %0
4541    add\t%1, -%2, %0")
4543 (define_insn "subsi3"
4544   [(set (match_operand:SI 0 "register_operand" "=r,r,d")
4545         (minus:SI (match_operand:SI 1 "register_operand" "r,r,d")
4546                   (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
4547   ""
4548   "@
4549    sub\t%1, %2, %0
4550    add\t%1, -%2, %0
4551    fpsub32s\t%1, %2, %0"
4552   [(set_attr "type" "*,*,fga")
4553    (set_attr "fptype" "*,*,single")])
4555 (define_insn "*cmp_minus_cc"
4556   [(set (reg:CC_NOOV 100)
4557         (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
4558                                    (match_operand:SI 1 "arith_operand" "rI"))
4559                          (const_int 0)))]
4560   ""
4561   "subcc\t%r0, %1, %%g0"
4562   [(set_attr "type" "compare")])
4564 (define_insn "*cmp_minus_ccx"
4565   [(set (reg:CCX_NOOV 100)
4566         (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
4567                                     (match_operand:DI 1 "arith_operand" "rI"))
4568                           (const_int 0)))]
4569   "TARGET_ARCH64"
4570   "subcc\t%0, %1, %%g0"
4571   [(set_attr "type" "compare")])
4573 (define_insn "cmp_minus_cc_set"
4574   [(set (reg:CC_NOOV 100)
4575         (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4576                                    (match_operand:SI 2 "arith_operand" "rI"))
4577                          (const_int 0)))
4578    (set (match_operand:SI 0 "register_operand" "=r")
4579         (minus:SI (match_dup 1) (match_dup 2)))]
4580   ""
4581   "subcc\t%r1, %2, %0"
4582   [(set_attr "type" "compare")])
4584 (define_insn "*cmp_minus_ccx_set"
4585   [(set (reg:CCX_NOOV 100)
4586         (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
4587                                     (match_operand:DI 2 "arith_operand" "rI"))
4588                           (const_int 0)))
4589    (set (match_operand:DI 0 "register_operand" "=r")
4590         (minus:DI (match_dup 1) (match_dup 2)))]
4591   "TARGET_ARCH64"
4592   "subcc\t%1, %2, %0"
4593   [(set_attr "type" "compare")])
4596 ;; Integer multiply/divide instructions.
4598 ;; The 32 bit multiply/divide instructions are deprecated on v9, but at
4599 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
4601 (define_insn "mulsi3"
4602   [(set (match_operand:SI 0 "register_operand" "=r")
4603         (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4604                  (match_operand:SI 2 "arith_operand" "rI")))]
4605   "TARGET_HARD_MUL"
4606   "smul\t%1, %2, %0"
4607   [(set_attr "type" "imul")])
4609 (define_expand "muldi3"
4610   [(set (match_operand:DI 0 "register_operand" "")
4611         (mult:DI (match_operand:DI 1 "arith_operand" "")
4612                  (match_operand:DI 2 "arith_operand" "")))]
4613   "TARGET_ARCH64 || TARGET_V8PLUS"
4615   if (TARGET_V8PLUS)
4616     {
4617       emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
4618       DONE;
4619     }
4622 (define_insn "*muldi3_sp64"
4623   [(set (match_operand:DI 0 "register_operand" "=r")
4624         (mult:DI (match_operand:DI 1 "arith_operand" "%r")
4625                  (match_operand:DI 2 "arith_operand" "rI")))]
4626   "TARGET_ARCH64"
4627   "mulx\t%1, %2, %0"
4628   [(set_attr "type" "imul")])
4630 ;; V8plus wide multiply.
4631 ;; XXX
4632 (define_insn "muldi3_v8plus"
4633   [(set (match_operand:DI 0 "register_operand" "=r,h")
4634         (mult:DI (match_operand:DI 1 "arith_operand" "%r,0")
4635                  (match_operand:DI 2 "arith_operand" "rI,rI")))
4636    (clobber (match_scratch:SI 3 "=&h,X"))
4637    (clobber (match_scratch:SI 4 "=&h,X"))]
4638   "TARGET_V8PLUS"
4640   if (sparc_check_64 (operands[1], insn) <= 0)
4641     output_asm_insn ("srl\t%L1, 0, %L1", operands);
4642   if (which_alternative == 1)
4643     output_asm_insn ("sllx\t%H1, 32, %H1", operands);
4644   if (GET_CODE (operands[2]) == CONST_INT)
4645     {
4646       if (which_alternative == 1)
4647         return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %2, %L0\;srlx\t%L0, 32, %H0";
4648       else
4649         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";
4650     }
4651   else if (rtx_equal_p (operands[1], operands[2]))
4652     {
4653       if (which_alternative == 1)
4654         return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %H1, %L0\;srlx\t%L0, 32, %H0";
4655       else
4656         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";
4657     }
4658   if (sparc_check_64 (operands[2], insn) <= 0)
4659     output_asm_insn ("srl\t%L2, 0, %L2", operands);
4660   if (which_alternative == 1)
4661     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";
4662   else
4663     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";
4665   [(set_attr "type" "multi")
4666    (set_attr "length" "9,8")])
4668 (define_insn "*cmp_mul_set"
4669   [(set (reg:CC 100)
4670         (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4671                     (match_operand:SI 2 "arith_operand" "rI"))
4672                     (const_int 0)))
4673    (set (match_operand:SI 0 "register_operand" "=r")
4674         (mult:SI (match_dup 1) (match_dup 2)))]
4675   "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
4676   "smulcc\t%1, %2, %0"
4677   [(set_attr "type" "imul")])
4679 (define_expand "mulsidi3"
4680   [(set (match_operand:DI 0 "register_operand" "")
4681         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4682                  (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
4683   "TARGET_HARD_MUL"
4685   if (CONSTANT_P (operands[2]))
4686     {
4687       if (TARGET_V8PLUS)
4688         emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
4689                                               operands[2]));
4690       else if (TARGET_ARCH32)
4691         emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
4692                                             operands[2]));
4693       else 
4694         emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
4695                                             operands[2]));
4696       DONE;
4697     }
4698   if (TARGET_V8PLUS)
4699     {
4700       emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
4701       DONE;
4702     }
4705 ;; V9 puts the 64 bit product in a 64 bit register.  Only out or global
4706 ;; registers can hold 64 bit values in the V8plus environment.
4707 ;; XXX
4708 (define_insn "mulsidi3_v8plus"
4709   [(set (match_operand:DI 0 "register_operand" "=h,r")
4710         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4711                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4712    (clobber (match_scratch:SI 3 "=X,&h"))]
4713   "TARGET_V8PLUS"
4714   "@
4715    smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4716    smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4717   [(set_attr "type" "multi")
4718    (set_attr "length" "2,3")])
4720 ;; XXX
4721 (define_insn "const_mulsidi3_v8plus"
4722   [(set (match_operand:DI 0 "register_operand" "=h,r")
4723         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4724                  (match_operand:DI 2 "small_int_operand" "I,I")))
4725    (clobber (match_scratch:SI 3 "=X,&h"))]
4726   "TARGET_V8PLUS"
4727   "@
4728    smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4729    smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4730   [(set_attr "type" "multi")
4731    (set_attr "length" "2,3")])
4733 ;; XXX
4734 (define_insn "*mulsidi3_sp32"
4735   [(set (match_operand:DI 0 "register_operand" "=r")
4736         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4737                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4738   "TARGET_HARD_MUL32"
4740   return TARGET_SPARCLET
4741          ? "smuld\t%1, %2, %L0"
4742          : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4744   [(set (attr "type")
4745         (if_then_else (eq_attr "isa" "sparclet")
4746                       (const_string "imul") (const_string "multi")))
4747    (set (attr "length")
4748         (if_then_else (eq_attr "isa" "sparclet")
4749                       (const_int 1) (const_int 2)))])
4751 (define_insn "*mulsidi3_sp64"
4752   [(set (match_operand:DI 0 "register_operand" "=r")
4753         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4754                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4755   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4756   "smul\t%1, %2, %0"
4757   [(set_attr "type" "imul")])
4759 ;; Extra pattern, because sign_extend of a constant isn't valid.
4761 ;; XXX
4762 (define_insn "const_mulsidi3_sp32"
4763   [(set (match_operand:DI 0 "register_operand" "=r")
4764         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4765                  (match_operand:DI 2 "small_int_operand" "I")))]
4766   "TARGET_HARD_MUL32"
4768   return TARGET_SPARCLET
4769          ? "smuld\t%1, %2, %L0"
4770          : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4772   [(set (attr "type")
4773         (if_then_else (eq_attr "isa" "sparclet")
4774                       (const_string "imul") (const_string "multi")))
4775    (set (attr "length")
4776         (if_then_else (eq_attr "isa" "sparclet")
4777                       (const_int 1) (const_int 2)))])
4779 (define_insn "const_mulsidi3_sp64"
4780   [(set (match_operand:DI 0 "register_operand" "=r")
4781         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4782                  (match_operand:DI 2 "small_int_operand" "I")))]
4783   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4784   "smul\t%1, %2, %0"
4785   [(set_attr "type" "imul")])
4787 (define_expand "smulsi3_highpart"
4788   [(set (match_operand:SI 0 "register_operand" "")
4789         (truncate:SI
4790          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4791                                (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
4792                       (const_int 32))))]
4793   "TARGET_HARD_MUL && TARGET_ARCH32"
4795   if (CONSTANT_P (operands[2]))
4796     {
4797       if (TARGET_V8PLUS)
4798         {
4799           emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
4800                                                         operands[1],
4801                                                         operands[2],
4802                                                         GEN_INT (32)));
4803           DONE;
4804         }
4805       emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
4806       DONE;
4807     }
4808   if (TARGET_V8PLUS)
4809     {
4810       emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
4811                                               operands[2], GEN_INT (32)));
4812       DONE;
4813     }
4816 ;; XXX
4817 (define_insn "smulsi3_highpart_v8plus"
4818   [(set (match_operand:SI 0 "register_operand" "=h,r")
4819         (truncate:SI
4820          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4821                                (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4822                       (match_operand:SI 3 "small_int_operand" "I,I"))))
4823    (clobber (match_scratch:SI 4 "=X,&h"))]
4824   "TARGET_V8PLUS"
4825   "@
4826    smul\t%1, %2, %0\;srlx\t%0, %3, %0
4827    smul\t%1, %2, %4\;srlx\t%4, %3, %0"
4828   [(set_attr "type" "multi")
4829    (set_attr "length" "2")])
4831 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
4832 ;; XXX
4833 (define_insn ""
4834   [(set (match_operand:SI 0 "register_operand" "=h,r")
4835         (subreg:SI
4836          (lshiftrt:DI
4837           (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4838                    (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4839           (match_operand:SI 3 "small_int_operand" "I,I"))
4840          4))
4841    (clobber (match_scratch:SI 4 "=X,&h"))]
4842   "TARGET_V8PLUS"
4843   "@
4844    smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4845    smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4846   [(set_attr "type" "multi")
4847    (set_attr "length" "2")])
4849 ;; XXX
4850 (define_insn "const_smulsi3_highpart_v8plus"
4851   [(set (match_operand:SI 0 "register_operand" "=h,r")
4852         (truncate:SI
4853          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4854                                (match_operand:DI 2 "small_int_operand" "I,I"))
4855                       (match_operand:SI 3 "small_int_operand" "I,I"))))
4856    (clobber (match_scratch:SI 4 "=X,&h"))]
4857   "TARGET_V8PLUS"
4858   "@
4859    smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4860    smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4861   [(set_attr "type" "multi")
4862    (set_attr "length" "2")])
4864 ;; XXX
4865 (define_insn "*smulsi3_highpart_sp32"
4866   [(set (match_operand:SI 0 "register_operand" "=r")
4867         (truncate:SI
4868          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4869                                (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
4870                       (const_int 32))))]
4871   "TARGET_HARD_MUL32"
4872   "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4873   [(set_attr "type" "multi")
4874    (set_attr "length" "2")])
4876 ;; XXX
4877 (define_insn "const_smulsi3_highpart"
4878   [(set (match_operand:SI 0 "register_operand" "=r")
4879         (truncate:SI
4880          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4881                                (match_operand:DI 2 "small_int_operand" "i"))
4882                       (const_int 32))))]
4883   "TARGET_HARD_MUL32"
4884   "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4885   [(set_attr "type" "multi")
4886    (set_attr "length" "2")])
4888 (define_expand "umulsidi3"
4889   [(set (match_operand:DI 0 "register_operand" "")
4890         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4891                  (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
4892   "TARGET_HARD_MUL"
4894   if (CONSTANT_P (operands[2]))
4895     {
4896       if (TARGET_V8PLUS)
4897         emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
4898                                                operands[2]));
4899       else if (TARGET_ARCH32)
4900         emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
4901                                              operands[2]));
4902       else 
4903         emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
4904                                              operands[2]));
4905       DONE;
4906     }
4907   if (TARGET_V8PLUS)
4908     {
4909       emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
4910       DONE;
4911     }
4914 ;; XXX
4915 (define_insn "umulsidi3_v8plus"
4916   [(set (match_operand:DI 0 "register_operand" "=h,r")
4917         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4918                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4919    (clobber (match_scratch:SI 3 "=X,&h"))]
4920   "TARGET_V8PLUS"
4921   "@
4922    umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4923    umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4924   [(set_attr "type" "multi")
4925    (set_attr "length" "2,3")])
4927 ;; XXX
4928 (define_insn "*umulsidi3_sp32"
4929   [(set (match_operand:DI 0 "register_operand" "=r")
4930         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4931                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4932   "TARGET_HARD_MUL32"
4934   return TARGET_SPARCLET
4935          ? "umuld\t%1, %2, %L0"
4936          : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
4938   [(set (attr "type")
4939         (if_then_else (eq_attr "isa" "sparclet")
4940                       (const_string "imul") (const_string "multi")))
4941    (set (attr "length")
4942         (if_then_else (eq_attr "isa" "sparclet")
4943                       (const_int 1) (const_int 2)))])
4945 (define_insn "*umulsidi3_sp64"
4946   [(set (match_operand:DI 0 "register_operand" "=r")
4947         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4948                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4949   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4950   "umul\t%1, %2, %0"
4951   [(set_attr "type" "imul")])
4953 ;; Extra pattern, because sign_extend of a constant isn't valid.
4955 ;; XXX
4956 (define_insn "const_umulsidi3_sp32"
4957   [(set (match_operand:DI 0 "register_operand" "=r")
4958         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4959                  (match_operand:DI 2 "uns_small_int_operand" "")))]
4960   "TARGET_HARD_MUL32"
4962   return TARGET_SPARCLET
4963          ? "umuld\t%1, %s2, %L0"
4964          : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
4966   [(set (attr "type")
4967         (if_then_else (eq_attr "isa" "sparclet")
4968                       (const_string "imul") (const_string "multi")))
4969    (set (attr "length")
4970         (if_then_else (eq_attr "isa" "sparclet")
4971                       (const_int 1) (const_int 2)))])
4973 (define_insn "const_umulsidi3_sp64"
4974   [(set (match_operand:DI 0 "register_operand" "=r")
4975         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4976                  (match_operand:DI 2 "uns_small_int_operand" "")))]
4977   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4978   "umul\t%1, %s2, %0"
4979   [(set_attr "type" "imul")])
4981 ;; XXX
4982 (define_insn "const_umulsidi3_v8plus"
4983   [(set (match_operand:DI 0 "register_operand" "=h,r")
4984         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4985                  (match_operand:DI 2 "uns_small_int_operand" "")))
4986    (clobber (match_scratch:SI 3 "=X,h"))]
4987   "TARGET_V8PLUS"
4988   "@
4989    umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
4990    umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4991   [(set_attr "type" "multi")
4992    (set_attr "length" "2,3")])
4994 (define_expand "umulsi3_highpart"
4995   [(set (match_operand:SI 0 "register_operand" "")
4996         (truncate:SI
4997          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4998                                (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
4999                       (const_int 32))))]
5000   "TARGET_HARD_MUL && TARGET_ARCH32"
5002   if (CONSTANT_P (operands[2]))
5003     {
5004       if (TARGET_V8PLUS)
5005         {
5006           emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
5007                                                         operands[1],
5008                                                         operands[2],
5009                                                         GEN_INT (32)));
5010           DONE;
5011         }
5012       emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
5013       DONE;
5014     }
5015   if (TARGET_V8PLUS)
5016     {
5017       emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
5018                                               operands[2], GEN_INT (32)));
5019       DONE;
5020     }
5023 ;; XXX
5024 (define_insn "umulsi3_highpart_v8plus"
5025   [(set (match_operand:SI 0 "register_operand" "=h,r")
5026         (truncate:SI
5027          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5028                                (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
5029                       (match_operand:SI 3 "small_int_operand" "I,I"))))
5030    (clobber (match_scratch:SI 4 "=X,h"))]
5031   "TARGET_V8PLUS"
5032   "@
5033    umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
5034    umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
5035   [(set_attr "type" "multi")
5036    (set_attr "length" "2")])
5038 ;; XXX
5039 (define_insn "const_umulsi3_highpart_v8plus"
5040   [(set (match_operand:SI 0 "register_operand" "=h,r")
5041         (truncate:SI
5042          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
5043                                (match_operand:DI 2 "uns_small_int_operand" ""))
5044                       (match_operand:SI 3 "small_int_operand" "I,I"))))
5045    (clobber (match_scratch:SI 4 "=X,h"))]
5046   "TARGET_V8PLUS"
5047   "@
5048    umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
5049    umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
5050   [(set_attr "type" "multi")
5051    (set_attr "length" "2")])
5053 ;; XXX
5054 (define_insn "*umulsi3_highpart_sp32"
5055   [(set (match_operand:SI 0 "register_operand" "=r")
5056         (truncate:SI
5057          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5058                                (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
5059                       (const_int 32))))]
5060   "TARGET_HARD_MUL32"
5061   "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
5062   [(set_attr "type" "multi")
5063    (set_attr "length" "2")])
5065 ;; XXX
5066 (define_insn "const_umulsi3_highpart"
5067   [(set (match_operand:SI 0 "register_operand" "=r")
5068         (truncate:SI
5069          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
5070                                (match_operand:DI 2 "uns_small_int_operand" ""))
5071                       (const_int 32))))]
5072   "TARGET_HARD_MUL32"
5073   "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
5074   [(set_attr "type" "multi")
5075    (set_attr "length" "2")])
5077 ;; The V8 architecture specifies that there must be 3 instructions between
5078 ;; a Y register write and a use of it for correct results.
5080 (define_expand "divsi3"
5081   [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
5082                    (div:SI (match_operand:SI 1 "register_operand" "r,r")
5083                            (match_operand:SI 2 "input_operand" "rI,m")))
5084               (clobber (match_scratch:SI 3 "=&r,&r"))])]
5085   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5087   if (TARGET_ARCH64)
5088     {
5089       operands[3] = gen_reg_rtx(SImode);
5090       emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
5091       emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
5092                                   operands[3]));
5093       DONE;
5094     }
5097 (define_insn "divsi3_sp32"
5098   [(set (match_operand:SI 0 "register_operand" "=r,r")
5099         (div:SI (match_operand:SI 1 "register_operand" "r,r")
5100                 (match_operand:SI 2 "input_operand" "rI,m")))
5101    (clobber (match_scratch:SI 3 "=&r,&r"))]
5102   "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
5103    && TARGET_ARCH32"
5105   if (which_alternative == 0)
5106     if (TARGET_V9)
5107       return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdiv\t%1, %2, %0";
5108     else
5109       return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
5110   else
5111     if (TARGET_V9)
5112       return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tld\t%2, %3\n\tsdiv\t%1, %3, %0";
5113     else
5114       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";
5116   [(set_attr "type" "multi")
5117    (set (attr "length")
5118         (if_then_else (eq_attr "isa" "v9")
5119                       (const_int 4) (const_int 6)))])
5121 (define_insn "divsi3_sp64"
5122   [(set (match_operand:SI 0 "register_operand" "=r")
5123         (div:SI (match_operand:SI 1 "register_operand" "r")
5124                 (match_operand:SI 2 "input_operand" "rI")))
5125    (use (match_operand:SI 3 "register_operand" "r"))]
5126   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5127   "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
5128   [(set_attr "type" "multi")
5129    (set_attr "length" "2")])
5131 (define_insn "divdi3"
5132   [(set (match_operand:DI 0 "register_operand" "=r")
5133         (div:DI (match_operand:DI 1 "register_operand" "r")
5134                 (match_operand:DI 2 "arith_operand" "rI")))]
5135   "TARGET_ARCH64"
5136   "sdivx\t%1, %2, %0"
5137   [(set_attr "type" "idiv")])
5139 (define_insn "*cmp_sdiv_cc_set"
5140   [(set (reg:CC 100)
5141         (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
5142                             (match_operand:SI 2 "arith_operand" "rI"))
5143                     (const_int 0)))
5144    (set (match_operand:SI 0 "register_operand" "=r")
5145         (div:SI (match_dup 1) (match_dup 2)))
5146    (clobber (match_scratch:SI 3 "=&r"))]
5147   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5149   if (TARGET_V9)
5150     return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tsdivcc\t%1, %2, %0";
5151   else
5152     return "sra\t%1, 31, %3\n\twr\t%3, 0, %%y\n\tnop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
5154   [(set_attr "type" "multi")
5155    (set (attr "length")
5156         (if_then_else (eq_attr "isa" "v9")
5157                       (const_int 3) (const_int 6)))])
5159 ;; XXX
5160 (define_expand "udivsi3"
5161   [(set (match_operand:SI 0 "register_operand" "")
5162         (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "")
5163                  (match_operand:SI 2 "input_operand" "")))]
5164   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5165   "")
5167 ;; The V8 architecture specifies that there must be 3 instructions between
5168 ;; a Y register write and a use of it for correct results.
5170 (define_insn "udivsi3_sp32"
5171   [(set (match_operand:SI 0 "register_operand" "=r,&r,&r")
5172         (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r,r,m")
5173                  (match_operand:SI 2 "input_operand" "rI,m,r")))]
5174   "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS)
5175    && TARGET_ARCH32"
5177   output_asm_insn ("wr\t%%g0, %%g0, %%y", operands);
5178   switch (which_alternative)
5179     {
5180     default:
5181       return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
5182     case 1:
5183       return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
5184     case 2:
5185       return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
5186     }
5188   [(set_attr "type" "multi")
5189    (set_attr "length" "5")])
5191 (define_insn "udivsi3_sp64"
5192   [(set (match_operand:SI 0 "register_operand" "=r")
5193         (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r")
5194                  (match_operand:SI 2 "input_operand" "rI")))]
5195   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5196   "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
5197   [(set_attr "type" "multi")
5198    (set_attr "length" "2")])
5200 (define_insn "udivdi3"
5201   [(set (match_operand:DI 0 "register_operand" "=r")
5202         (udiv:DI (match_operand:DI 1 "register_operand" "r")
5203                  (match_operand:DI 2 "arith_operand" "rI")))]
5204   "TARGET_ARCH64"
5205   "udivx\t%1, %2, %0"
5206   [(set_attr "type" "idiv")])
5208 (define_insn "*cmp_udiv_cc_set"
5209   [(set (reg:CC 100)
5210         (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
5211                              (match_operand:SI 2 "arith_operand" "rI"))
5212                     (const_int 0)))
5213    (set (match_operand:SI 0 "register_operand" "=r")
5214         (udiv:SI (match_dup 1) (match_dup 2)))]
5215   "TARGET_V8
5216    || TARGET_DEPRECATED_V8_INSNS"
5218   if (TARGET_V9)
5219     return "wr\t%%g0, %%g0, %%y\n\tudivcc\t%1, %2, %0";
5220   else
5221     return "wr\t%%g0, %%g0, %%y\n\tnop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
5223   [(set_attr "type" "multi")
5224    (set (attr "length")
5225         (if_then_else (eq_attr "isa" "v9")
5226                       (const_int 2) (const_int 5)))])
5228 ; sparclet multiply/accumulate insns
5230 (define_insn "*smacsi"
5231   [(set (match_operand:SI 0 "register_operand" "=r")
5232         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
5233                           (match_operand:SI 2 "arith_operand" "rI"))
5234                  (match_operand:SI 3 "register_operand" "0")))]
5235   "TARGET_SPARCLET"
5236   "smac\t%1, %2, %0"
5237   [(set_attr "type" "imul")])
5239 (define_insn "*smacdi"
5240   [(set (match_operand:DI 0 "register_operand" "=r")
5241         (plus:DI (mult:DI (sign_extend:DI
5242                            (match_operand:SI 1 "register_operand" "%r"))
5243                           (sign_extend:DI
5244                            (match_operand:SI 2 "register_operand" "r")))
5245                  (match_operand:DI 3 "register_operand" "0")))]
5246   "TARGET_SPARCLET"
5247   "smacd\t%1, %2, %L0"
5248   [(set_attr "type" "imul")])
5250 (define_insn "*umacdi"
5251   [(set (match_operand:DI 0 "register_operand" "=r")
5252         (plus:DI (mult:DI (zero_extend:DI
5253                            (match_operand:SI 1 "register_operand" "%r"))
5254                           (zero_extend:DI
5255                            (match_operand:SI 2 "register_operand" "r")))
5256                  (match_operand:DI 3 "register_operand" "0")))]
5257   "TARGET_SPARCLET"
5258   "umacd\t%1, %2, %L0"
5259   [(set_attr "type" "imul")])
5262 ;; Boolean instructions.
5264 ;; We define DImode `and' so with DImode `not' we can get
5265 ;; DImode `andn'.  Other combinations are possible.
5267 (define_mode_macro V64I [DI V2SI V4HI V8QI])
5268 (define_mode_macro V32I [SI V2HI V4QI])
5270 (define_expand "and<V64I:mode>3"
5271   [(set (match_operand:V64I 0 "register_operand" "")
5272         (and:V64I (match_operand:V64I 1 "arith_double_operand" "")
5273                   (match_operand:V64I 2 "arith_double_operand" "")))]
5274   ""
5275   "")
5277 (define_insn "*and<V64I:mode>3_sp32"
5278   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5279         (and:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5280                   (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5281   "! TARGET_ARCH64"
5282   "@
5283   #
5284   fand\t%1, %2, %0"
5285   [(set_attr "type" "*,fga")
5286    (set_attr "length" "2,*")
5287    (set_attr "fptype" "*,double")])
5289 (define_insn "*and<V64I:mode>3_sp64"
5290   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5291         (and:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
5292                   (match_operand:V64I 2 "arith_operand" "rI,b")))]
5293   "TARGET_ARCH64"
5294   "@
5295    and\t%1, %2, %0
5296    fand\t%1, %2, %0"
5297   [(set_attr "type" "*,fga")
5298    (set_attr "fptype" "*,double")])
5300 (define_insn "and<V32I:mode>3"
5301   [(set (match_operand:V32I 0 "register_operand" "=r,d")
5302         (and:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
5303                   (match_operand:V32I 2 "arith_operand" "rI,d")))]
5304   ""
5305   "@
5306    and\t%1, %2, %0
5307    fands\t%1, %2, %0"
5308   [(set_attr "type" "*,fga")
5309    (set_attr "fptype" "*,single")])
5311 (define_split
5312   [(set (match_operand:SI 0 "register_operand" "")
5313         (and:SI (match_operand:SI 1 "register_operand" "")
5314                 (match_operand:SI 2 "const_compl_high_operand" "")))
5315    (clobber (match_operand:SI 3 "register_operand" ""))]
5316   ""
5317   [(set (match_dup 3) (match_dup 4))
5318    (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
5320   operands[4] = GEN_INT (~INTVAL (operands[2]));
5323 (define_insn_and_split "*and_not_<V64I:mode>_sp32"
5324   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5325         (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
5326                   (match_operand:V64I 2 "register_operand" "r,b")))]
5327   "! TARGET_ARCH64"
5328   "@
5329    #
5330    fandnot1\t%1, %2, %0"
5331   "&& reload_completed
5332    && ((GET_CODE (operands[0]) == REG
5333         && REGNO (operands[0]) < 32)
5334        || (GET_CODE (operands[0]) == SUBREG
5335            && GET_CODE (SUBREG_REG (operands[0])) == REG
5336            && REGNO (SUBREG_REG (operands[0])) < 32))"
5337   [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
5338    (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
5339   "operands[3] = gen_highpart (SImode, operands[0]);
5340    operands[4] = gen_highpart (SImode, operands[1]);
5341    operands[5] = gen_highpart (SImode, operands[2]);
5342    operands[6] = gen_lowpart (SImode, operands[0]);
5343    operands[7] = gen_lowpart (SImode, operands[1]);
5344    operands[8] = gen_lowpart (SImode, operands[2]);"
5345   [(set_attr "type" "*,fga")
5346    (set_attr "length" "2,*")
5347    (set_attr "fptype" "*,double")])
5349 (define_insn "*and_not_<V64I:mode>_sp64"
5350   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5351         (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
5352                   (match_operand:V64I 2 "register_operand" "r,b")))]
5353   "TARGET_ARCH64"
5354   "@
5355    andn\t%2, %1, %0
5356    fandnot1\t%1, %2, %0"
5357   [(set_attr "type" "*,fga")
5358    (set_attr "fptype" "*,double")])
5360 (define_insn "*and_not_<V32I:mode>"
5361   [(set (match_operand:V32I 0 "register_operand" "=r,d")
5362         (and:V32I (not:V32I (match_operand:V32I 1 "register_operand" "%r,d"))
5363                   (match_operand:V32I 2 "register_operand" "r,d")))]
5364   ""
5365   "@
5366    andn\t%2, %1, %0
5367    fandnot1s\t%1, %2, %0"
5368   [(set_attr "type" "*,fga")
5369    (set_attr "fptype" "*,single")])
5371 (define_expand "ior<V64I:mode>3"
5372   [(set (match_operand:V64I 0 "register_operand" "")
5373         (ior:V64I (match_operand:V64I 1 "arith_double_operand" "")
5374                   (match_operand:V64I 2 "arith_double_operand" "")))]
5375   ""
5376   "")
5378 (define_insn "*ior<V64I:mode>3_sp32"
5379   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5380         (ior:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5381                   (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5382   "! TARGET_ARCH64"
5383   "@
5384   #
5385   for\t%1, %2, %0"
5386   [(set_attr "type" "*,fga")
5387    (set_attr "length" "2,*")
5388    (set_attr "fptype" "*,double")])
5390 (define_insn "*ior<V64I:mode>3_sp64"
5391   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5392         (ior:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
5393                   (match_operand:V64I 2 "arith_operand" "rI,b")))]
5394   "TARGET_ARCH64"
5395   "@
5396   or\t%1, %2, %0
5397   for\t%1, %2, %0"
5398   [(set_attr "type" "*,fga")
5399    (set_attr "fptype" "*,double")])
5401 (define_insn "ior<V32I:mode>3"
5402   [(set (match_operand:V32I 0 "register_operand" "=r,d")
5403         (ior:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
5404                   (match_operand:V32I 2 "arith_operand" "rI,d")))]
5405   ""
5406   "@
5407    or\t%1, %2, %0
5408    fors\t%1, %2, %0"
5409   [(set_attr "type" "*,fga")
5410    (set_attr "fptype" "*,single")])
5412 (define_split
5413   [(set (match_operand:SI 0 "register_operand" "")
5414         (ior:SI (match_operand:SI 1 "register_operand" "")
5415                 (match_operand:SI 2 "const_compl_high_operand" "")))
5416    (clobber (match_operand:SI 3 "register_operand" ""))]
5417   ""
5418   [(set (match_dup 3) (match_dup 4))
5419    (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
5421   operands[4] = GEN_INT (~INTVAL (operands[2]));
5424 (define_insn_and_split "*or_not_<V64I:mode>_sp32"
5425   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5426         (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
5427                   (match_operand:V64I 2 "register_operand" "r,b")))]
5428   "! TARGET_ARCH64"
5429   "@
5430    #
5431    fornot1\t%1, %2, %0"
5432   "&& reload_completed
5433    && ((GET_CODE (operands[0]) == REG
5434         && REGNO (operands[0]) < 32)
5435        || (GET_CODE (operands[0]) == SUBREG
5436            && GET_CODE (SUBREG_REG (operands[0])) == REG
5437            && REGNO (SUBREG_REG (operands[0])) < 32))"
5438   [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
5439    (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
5440   "operands[3] = gen_highpart (SImode, operands[0]);
5441    operands[4] = gen_highpart (SImode, operands[1]);
5442    operands[5] = gen_highpart (SImode, operands[2]);
5443    operands[6] = gen_lowpart (SImode, operands[0]);
5444    operands[7] = gen_lowpart (SImode, operands[1]);
5445    operands[8] = gen_lowpart (SImode, operands[2]);"
5446   [(set_attr "type" "*,fga")
5447    (set_attr "length" "2,*")
5448    (set_attr "fptype" "*,double")])
5450 (define_insn "*or_not_<V64I:mode>_sp64"
5451   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5452         (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
5453                   (match_operand:V64I 2 "register_operand" "r,b")))]
5454   "TARGET_ARCH64"
5455   "@
5456   orn\t%2, %1, %0
5457   fornot1\t%1, %2, %0"
5458   [(set_attr "type" "*,fga")
5459    (set_attr "fptype" "*,double")])
5461 (define_insn "*or_not_<V32I:mode>"
5462   [(set (match_operand:V32I 0 "register_operand" "=r,d")
5463         (ior:V32I (not:V32I (match_operand:V32I 1 "register_operand" "r,d"))
5464                   (match_operand:V32I 2 "register_operand" "r,d")))]
5465   ""
5466   "@
5467    orn\t%2, %1, %0
5468    fornot1s\t%1, %2, %0"
5469   [(set_attr "type" "*,fga")
5470    (set_attr "fptype" "*,single")])
5472 (define_expand "xor<V64I:mode>3"
5473   [(set (match_operand:V64I 0 "register_operand" "")
5474         (xor:V64I (match_operand:V64I 1 "arith_double_operand" "")
5475                   (match_operand:V64I 2 "arith_double_operand" "")))]
5476   ""
5477   "")
5479 (define_insn "*xor<V64I:mode>3_sp32"
5480   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5481         (xor:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5482                   (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5483   "! TARGET_ARCH64"
5484   "@
5485   #
5486   fxor\t%1, %2, %0"
5487   [(set_attr "type" "*,fga")
5488    (set_attr "length" "2,*")
5489    (set_attr "fptype" "*,double")])
5491 (define_insn "*xor<V64I:mode>3_sp64"
5492   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5493         (xor:V64I (match_operand:V64I 1 "arith_operand" "%rJ,b")
5494                   (match_operand:V64I 2 "arith_operand" "rI,b")))]
5495   "TARGET_ARCH64"
5496   "@
5497   xor\t%r1, %2, %0
5498   fxor\t%1, %2, %0"
5499   [(set_attr "type" "*,fga")
5500    (set_attr "fptype" "*,double")])
5502 (define_insn "xor<V32I:mode>3"
5503   [(set (match_operand:V32I 0 "register_operand" "=r,d")
5504         (xor:V32I (match_operand:V32I 1 "arith_operand" "%rJ,d")
5505                   (match_operand:V32I 2 "arith_operand" "rI,d")))]
5506   ""
5507   "@
5508    xor\t%r1, %2, %0
5509    fxors\t%1, %2, %0"
5510   [(set_attr "type" "*,fga")
5511    (set_attr "fptype" "*,single")])
5513 (define_split
5514   [(set (match_operand:SI 0 "register_operand" "")
5515         (xor:SI (match_operand:SI 1 "register_operand" "")
5516                 (match_operand:SI 2 "const_compl_high_operand" "")))
5517    (clobber (match_operand:SI 3 "register_operand" ""))]
5518    ""
5519   [(set (match_dup 3) (match_dup 4))
5520    (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
5522   operands[4] = GEN_INT (~INTVAL (operands[2]));
5525 (define_split
5526   [(set (match_operand:SI 0 "register_operand" "")
5527         (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
5528                         (match_operand:SI 2 "const_compl_high_operand" ""))))
5529    (clobber (match_operand:SI 3 "register_operand" ""))]
5530   ""
5531   [(set (match_dup 3) (match_dup 4))
5532    (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
5534   operands[4] = GEN_INT (~INTVAL (operands[2]));
5537 ;; Split DImode logical operations requiring two instructions.
5538 (define_split
5539   [(set (match_operand:V64I 0 "register_operand" "")
5540         (match_operator:V64I 1 "cc_arith_operator"      ; AND, IOR, XOR
5541                            [(match_operand:V64I 2 "register_operand" "")
5542                             (match_operand:V64I 3 "arith_double_operand" "")]))]
5543   "! TARGET_ARCH64
5544    && reload_completed
5545    && ((GET_CODE (operands[0]) == REG
5546         && REGNO (operands[0]) < 32)
5547        || (GET_CODE (operands[0]) == SUBREG
5548            && GET_CODE (SUBREG_REG (operands[0])) == REG
5549            && REGNO (SUBREG_REG (operands[0])) < 32))"
5550   [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
5551    (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
5553   operands[4] = gen_highpart (SImode, operands[0]);
5554   operands[5] = gen_lowpart (SImode, operands[0]);
5555   operands[6] = gen_highpart (SImode, operands[2]);
5556   operands[7] = gen_lowpart (SImode, operands[2]);
5557 #if HOST_BITS_PER_WIDE_INT == 32
5558   if (GET_CODE (operands[3]) == CONST_INT && <V64I:MODE>mode == DImode)
5559     {
5560       if (INTVAL (operands[3]) < 0)
5561         operands[8] = constm1_rtx;
5562       else
5563         operands[8] = const0_rtx;
5564     }
5565   else
5566 #endif
5567     operands[8] = gen_highpart_mode (SImode, <V64I:MODE>mode, operands[3]);
5568   operands[9] = gen_lowpart (SImode, operands[3]);
5571 ;; xnor patterns.  Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
5572 ;; Combine now canonicalizes to the rightmost expression.
5573 (define_insn_and_split "*xor_not_<V64I:mode>_sp32"
5574   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5575         (not:V64I (xor:V64I (match_operand:V64I 1 "register_operand" "r,b")
5576                             (match_operand:V64I 2 "register_operand" "r,b"))))]
5577   "! TARGET_ARCH64"
5578   "@
5579    #
5580    fxnor\t%1, %2, %0"
5581   "&& reload_completed
5582    && ((GET_CODE (operands[0]) == REG
5583         && REGNO (operands[0]) < 32)
5584        || (GET_CODE (operands[0]) == SUBREG
5585            && GET_CODE (SUBREG_REG (operands[0])) == REG
5586            && REGNO (SUBREG_REG (operands[0])) < 32))"
5587   [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
5588    (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
5589   "operands[3] = gen_highpart (SImode, operands[0]);
5590    operands[4] = gen_highpart (SImode, operands[1]);
5591    operands[5] = gen_highpart (SImode, operands[2]);
5592    operands[6] = gen_lowpart (SImode, operands[0]);
5593    operands[7] = gen_lowpart (SImode, operands[1]);
5594    operands[8] = gen_lowpart (SImode, operands[2]);"
5595   [(set_attr "type" "*,fga")
5596    (set_attr "length" "2,*")
5597    (set_attr "fptype" "*,double")])
5599 (define_insn "*xor_not_<V64I:mode>_sp64"
5600   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5601         (not:V64I (xor:V64I (match_operand:V64I 1 "register_or_zero_operand" "rJ,b")
5602                             (match_operand:V64I 2 "arith_operand" "rI,b"))))]
5603   "TARGET_ARCH64"
5604   "@
5605   xnor\t%r1, %2, %0
5606   fxnor\t%1, %2, %0"
5607   [(set_attr "type" "*,fga")
5608    (set_attr "fptype" "*,double")])
5610 (define_insn "*xor_not_<V32I:mode>"
5611   [(set (match_operand:V32I 0 "register_operand" "=r,d")
5612         (not:V32I (xor:V32I (match_operand:V32I 1 "register_or_zero_operand" "rJ,d")
5613                             (match_operand:V32I 2 "arith_operand" "rI,d"))))]
5614   ""
5615   "@
5616    xnor\t%r1, %2, %0
5617    fxnors\t%1, %2, %0"
5618   [(set_attr "type" "*,fga")
5619    (set_attr "fptype" "*,single")])
5621 ;; These correspond to the above in the case where we also (or only)
5622 ;; want to set the condition code.  
5624 (define_insn "*cmp_cc_arith_op"
5625   [(set (reg:CC 100)
5626         (compare:CC
5627          (match_operator:SI 2 "cc_arith_operator"
5628                             [(match_operand:SI 0 "arith_operand" "%r")
5629                              (match_operand:SI 1 "arith_operand" "rI")])
5630          (const_int 0)))]
5631   ""
5632   "%A2cc\t%0, %1, %%g0"
5633   [(set_attr "type" "compare")])
5635 (define_insn "*cmp_ccx_arith_op"
5636   [(set (reg:CCX 100)
5637         (compare:CCX
5638          (match_operator:DI 2 "cc_arith_operator"
5639                             [(match_operand:DI 0 "arith_operand" "%r")
5640                              (match_operand:DI 1 "arith_operand" "rI")])
5641          (const_int 0)))]
5642   "TARGET_ARCH64"
5643   "%A2cc\t%0, %1, %%g0"
5644   [(set_attr "type" "compare")])
5646 (define_insn "*cmp_cc_arith_op_set"
5647   [(set (reg:CC 100)
5648         (compare:CC
5649          (match_operator:SI 3 "cc_arith_operator"
5650                             [(match_operand:SI 1 "arith_operand" "%r")
5651                              (match_operand:SI 2 "arith_operand" "rI")])
5652          (const_int 0)))
5653    (set (match_operand:SI 0 "register_operand" "=r")
5654         (match_operator:SI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5655   "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5656   "%A3cc\t%1, %2, %0"
5657   [(set_attr "type" "compare")])
5659 (define_insn "*cmp_ccx_arith_op_set"
5660   [(set (reg:CCX 100)
5661         (compare:CCX
5662          (match_operator:DI 3 "cc_arith_operator"
5663                             [(match_operand:DI 1 "arith_operand" "%r")
5664                              (match_operand:DI 2 "arith_operand" "rI")])
5665          (const_int 0)))
5666    (set (match_operand:DI 0 "register_operand" "=r")
5667         (match_operator:DI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5668   "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5669   "%A3cc\t%1, %2, %0"
5670   [(set_attr "type" "compare")])
5672 (define_insn "*cmp_cc_xor_not"
5673   [(set (reg:CC 100)
5674         (compare:CC
5675          (not:SI (xor:SI (match_operand:SI 0 "register_or_zero_operand" "%rJ")
5676                          (match_operand:SI 1 "arith_operand" "rI")))
5677          (const_int 0)))]
5678   ""
5679   "xnorcc\t%r0, %1, %%g0"
5680   [(set_attr "type" "compare")])
5682 (define_insn "*cmp_ccx_xor_not"
5683   [(set (reg:CCX 100)
5684         (compare:CCX
5685          (not:DI (xor:DI (match_operand:DI 0 "register_or_zero_operand" "%rJ")
5686                          (match_operand:DI 1 "arith_operand" "rI")))
5687          (const_int 0)))]
5688   "TARGET_ARCH64"
5689   "xnorcc\t%r0, %1, %%g0"
5690   [(set_attr "type" "compare")])
5692 (define_insn "*cmp_cc_xor_not_set"
5693   [(set (reg:CC 100)
5694         (compare:CC
5695          (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
5696                          (match_operand:SI 2 "arith_operand" "rI")))
5697          (const_int 0)))
5698    (set (match_operand:SI 0 "register_operand" "=r")
5699         (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
5700   ""
5701   "xnorcc\t%r1, %2, %0"
5702   [(set_attr "type" "compare")])
5704 (define_insn "*cmp_ccx_xor_not_set"
5705   [(set (reg:CCX 100)
5706         (compare:CCX
5707          (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
5708                          (match_operand:DI 2 "arith_operand" "rI")))
5709          (const_int 0)))
5710    (set (match_operand:DI 0 "register_operand" "=r")
5711         (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
5712   "TARGET_ARCH64"
5713   "xnorcc\t%r1, %2, %0"
5714   [(set_attr "type" "compare")])
5716 (define_insn "*cmp_cc_arith_op_not"
5717   [(set (reg:CC 100)
5718         (compare:CC
5719          (match_operator:SI 2 "cc_arith_not_operator"
5720                             [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
5721                              (match_operand:SI 1 "register_or_zero_operand" "rJ")])
5722          (const_int 0)))]
5723   ""
5724   "%B2cc\t%r1, %0, %%g0"
5725   [(set_attr "type" "compare")])
5727 (define_insn "*cmp_ccx_arith_op_not"
5728   [(set (reg:CCX 100)
5729         (compare:CCX
5730          (match_operator:DI 2 "cc_arith_not_operator"
5731                             [(not:DI (match_operand:DI 0 "arith_operand" "rI"))
5732                              (match_operand:DI 1 "register_or_zero_operand" "rJ")])
5733          (const_int 0)))]
5734   "TARGET_ARCH64"
5735   "%B2cc\t%r1, %0, %%g0"
5736   [(set_attr "type" "compare")])
5738 (define_insn "*cmp_cc_arith_op_not_set"
5739   [(set (reg:CC 100)
5740         (compare:CC
5741          (match_operator:SI 3 "cc_arith_not_operator"
5742                             [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
5743                              (match_operand:SI 2 "register_or_zero_operand" "rJ")])
5744          (const_int 0)))
5745    (set (match_operand:SI 0 "register_operand" "=r")
5746         (match_operator:SI 4 "cc_arith_not_operator"
5747                             [(not:SI (match_dup 1)) (match_dup 2)]))]
5748   "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5749   "%B3cc\t%r2, %1, %0"
5750   [(set_attr "type" "compare")])
5752 (define_insn "*cmp_ccx_arith_op_not_set"
5753   [(set (reg:CCX 100)
5754         (compare:CCX
5755          (match_operator:DI 3 "cc_arith_not_operator"
5756                             [(not:DI (match_operand:DI 1 "arith_operand" "rI"))
5757                              (match_operand:DI 2 "register_or_zero_operand" "rJ")])
5758          (const_int 0)))
5759    (set (match_operand:DI 0 "register_operand" "=r")
5760         (match_operator:DI 4 "cc_arith_not_operator"
5761                             [(not:DI (match_dup 1)) (match_dup 2)]))]
5762   "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5763   "%B3cc\t%r2, %1, %0"
5764   [(set_attr "type" "compare")])
5766 ;; We cannot use the "neg" pseudo insn because the Sun assembler
5767 ;; does not know how to make it work for constants.
5769 (define_expand "negdi2"
5770   [(set (match_operand:DI 0 "register_operand" "=r")
5771         (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5772   ""
5774   if (! TARGET_ARCH64)
5775     {
5776       emit_insn (gen_rtx_PARALLEL
5777                  (VOIDmode,
5778                   gen_rtvec (2,
5779                              gen_rtx_SET (VOIDmode, operand0,
5780                                           gen_rtx_NEG (DImode, operand1)),
5781                              gen_rtx_CLOBBER (VOIDmode,
5782                                               gen_rtx_REG (CCmode,
5783                                                            SPARC_ICC_REG)))));
5784       DONE;
5785     }
5788 (define_insn_and_split "*negdi2_sp32"
5789   [(set (match_operand:DI 0 "register_operand" "=r")
5790         (neg:DI (match_operand:DI 1 "register_operand" "r")))
5791    (clobber (reg:CC 100))]
5792   "TARGET_ARCH32"
5793   "#"
5794   "&& reload_completed"
5795   [(parallel [(set (reg:CC_NOOV 100)
5796                    (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
5797                                     (const_int 0)))
5798               (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
5799    (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
5800                                 (ltu:SI (reg:CC 100) (const_int 0))))]
5801   "operands[2] = gen_highpart (SImode, operands[0]);
5802    operands[3] = gen_highpart (SImode, operands[1]);
5803    operands[4] = gen_lowpart (SImode, operands[0]);
5804    operands[5] = gen_lowpart (SImode, operands[1]);"
5805   [(set_attr "length" "2")])
5807 (define_insn "*negdi2_sp64"
5808   [(set (match_operand:DI 0 "register_operand" "=r")
5809         (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5810   "TARGET_ARCH64"
5811   "sub\t%%g0, %1, %0")
5813 (define_insn "negsi2"
5814   [(set (match_operand:SI 0 "register_operand" "=r")
5815         (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
5816   ""
5817   "sub\t%%g0, %1, %0")
5819 (define_insn "*cmp_cc_neg"
5820   [(set (reg:CC_NOOV 100)
5821         (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
5822                          (const_int 0)))]
5823   ""
5824   "subcc\t%%g0, %0, %%g0"
5825   [(set_attr "type" "compare")])
5827 (define_insn "*cmp_ccx_neg"
5828   [(set (reg:CCX_NOOV 100)
5829         (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_operand" "rI"))
5830                           (const_int 0)))]
5831   "TARGET_ARCH64"
5832   "subcc\t%%g0, %0, %%g0"
5833   [(set_attr "type" "compare")])
5835 (define_insn "*cmp_cc_set_neg"
5836   [(set (reg:CC_NOOV 100)
5837         (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
5838                          (const_int 0)))
5839    (set (match_operand:SI 0 "register_operand" "=r")
5840         (neg:SI (match_dup 1)))]
5841   ""
5842   "subcc\t%%g0, %1, %0"
5843   [(set_attr "type" "compare")])
5845 (define_insn "*cmp_ccx_set_neg"
5846   [(set (reg:CCX_NOOV 100)
5847         (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_operand" "rI"))
5848                           (const_int 0)))
5849    (set (match_operand:DI 0 "register_operand" "=r")
5850         (neg:DI (match_dup 1)))]
5851   "TARGET_ARCH64"
5852   "subcc\t%%g0, %1, %0"
5853   [(set_attr "type" "compare")])
5855 ;; We cannot use the "not" pseudo insn because the Sun assembler
5856 ;; does not know how to make it work for constants.
5857 (define_expand "one_cmpl<V64I:mode>2"
5858   [(set (match_operand:V64I 0 "register_operand" "")
5859         (not:V64I (match_operand:V64I 1 "register_operand" "")))]
5860   ""
5861   "")
5863 (define_insn_and_split "*one_cmpl<V64I:mode>2_sp32"
5864   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5865         (not:V64I (match_operand:V64I 1 "register_operand" "r,b")))]
5866   "! TARGET_ARCH64"
5867   "@
5868    #
5869    fnot1\t%1, %0"
5870   "&& reload_completed
5871    && ((GET_CODE (operands[0]) == REG
5872         && REGNO (operands[0]) < 32)
5873        || (GET_CODE (operands[0]) == SUBREG
5874            && GET_CODE (SUBREG_REG (operands[0])) == REG
5875            && REGNO (SUBREG_REG (operands[0])) < 32))"
5876   [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
5877    (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
5878   "operands[2] = gen_highpart (SImode, operands[0]);
5879    operands[3] = gen_highpart (SImode, operands[1]);
5880    operands[4] = gen_lowpart (SImode, operands[0]);
5881    operands[5] = gen_lowpart (SImode, operands[1]);"
5882   [(set_attr "type" "*,fga")
5883    (set_attr "length" "2,*")
5884    (set_attr "fptype" "*,double")])
5886 (define_insn "*one_cmpl<V64I:mode>2_sp64"
5887   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5888         (not:V64I (match_operand:V64I 1 "arith_operand" "rI,b")))]
5889   "TARGET_ARCH64"
5890   "@
5891    xnor\t%%g0, %1, %0
5892    fnot1\t%1, %0"
5893   [(set_attr "type" "*,fga")
5894    (set_attr "fptype" "*,double")])
5896 (define_insn "one_cmpl<V32I:mode>2"
5897   [(set (match_operand:V32I 0 "register_operand" "=r,d")
5898         (not:V32I (match_operand:V32I 1 "arith_operand" "rI,d")))]
5899   ""
5900   "@
5901   xnor\t%%g0, %1, %0
5902   fnot1s\t%1, %0"
5903   [(set_attr "type" "*,fga")
5904    (set_attr "fptype" "*,single")])
5906 (define_insn "*cmp_cc_not"
5907   [(set (reg:CC 100)
5908         (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
5909                     (const_int 0)))]
5910   ""
5911   "xnorcc\t%%g0, %0, %%g0"
5912   [(set_attr "type" "compare")])
5914 (define_insn "*cmp_ccx_not"
5915   [(set (reg:CCX 100)
5916         (compare:CCX (not:DI (match_operand:DI 0 "arith_operand" "rI"))
5917                      (const_int 0)))]
5918   "TARGET_ARCH64"
5919   "xnorcc\t%%g0, %0, %%g0"
5920   [(set_attr "type" "compare")])
5922 (define_insn "*cmp_cc_set_not"
5923   [(set (reg:CC 100)
5924         (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
5925                     (const_int 0)))
5926    (set (match_operand:SI 0 "register_operand" "=r")
5927         (not:SI (match_dup 1)))]
5928   ""
5929   "xnorcc\t%%g0, %1, %0"
5930   [(set_attr "type" "compare")])
5932 (define_insn "*cmp_ccx_set_not"
5933   [(set (reg:CCX 100)
5934         (compare:CCX (not:DI (match_operand:DI 1 "arith_operand" "rI"))
5935                     (const_int 0)))
5936    (set (match_operand:DI 0 "register_operand" "=r")
5937         (not:DI (match_dup 1)))]
5938   "TARGET_ARCH64"
5939   "xnorcc\t%%g0, %1, %0"
5940   [(set_attr "type" "compare")])
5942 (define_insn "*cmp_cc_set"
5943   [(set (match_operand:SI 0 "register_operand" "=r")
5944         (match_operand:SI 1 "register_operand" "r"))
5945    (set (reg:CC 100)
5946         (compare:CC (match_dup 1)
5947                     (const_int 0)))]
5948   ""
5949   "orcc\t%1, 0, %0"
5950   [(set_attr "type" "compare")])
5952 (define_insn "*cmp_ccx_set64"
5953   [(set (match_operand:DI 0 "register_operand" "=r")
5954         (match_operand:DI 1 "register_operand" "r"))
5955    (set (reg:CCX 100)
5956         (compare:CCX (match_dup 1)
5957                      (const_int 0)))]
5958   "TARGET_ARCH64"
5959   "orcc\t%1, 0, %0"
5960    [(set_attr "type" "compare")])
5963 ;; Floating point arithmetic instructions.
5965 (define_expand "addtf3"
5966   [(set (match_operand:TF 0 "nonimmediate_operand" "")
5967         (plus:TF (match_operand:TF 1 "general_operand" "")
5968                  (match_operand:TF 2 "general_operand" "")))]
5969   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5970   "emit_tfmode_binop (PLUS, operands); DONE;")
5972 (define_insn "*addtf3_hq"
5973   [(set (match_operand:TF 0 "register_operand" "=e")
5974         (plus:TF (match_operand:TF 1 "register_operand" "e")
5975                  (match_operand:TF 2 "register_operand" "e")))]
5976   "TARGET_FPU && TARGET_HARD_QUAD"
5977   "faddq\t%1, %2, %0"
5978   [(set_attr "type" "fp")])
5980 (define_insn "adddf3"
5981   [(set (match_operand:DF 0 "register_operand" "=e")
5982         (plus:DF (match_operand:DF 1 "register_operand" "e")
5983                  (match_operand:DF 2 "register_operand" "e")))]
5984   "TARGET_FPU"
5985   "faddd\t%1, %2, %0"
5986   [(set_attr "type" "fp")
5987    (set_attr "fptype" "double")])
5989 (define_insn "addsf3"
5990   [(set (match_operand:SF 0 "register_operand" "=f")
5991         (plus:SF (match_operand:SF 1 "register_operand" "f")
5992                  (match_operand:SF 2 "register_operand" "f")))]
5993   "TARGET_FPU"
5994   "fadds\t%1, %2, %0"
5995   [(set_attr "type" "fp")])
5997 (define_expand "subtf3"
5998   [(set (match_operand:TF 0 "nonimmediate_operand" "")
5999         (minus:TF (match_operand:TF 1 "general_operand" "")
6000                   (match_operand:TF 2 "general_operand" "")))]
6001   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6002   "emit_tfmode_binop (MINUS, operands); DONE;")
6004 (define_insn "*subtf3_hq"
6005   [(set (match_operand:TF 0 "register_operand" "=e")
6006         (minus:TF (match_operand:TF 1 "register_operand" "e")
6007                   (match_operand:TF 2 "register_operand" "e")))]
6008   "TARGET_FPU && TARGET_HARD_QUAD"
6009   "fsubq\t%1, %2, %0"
6010   [(set_attr "type" "fp")])
6012 (define_insn "subdf3"
6013   [(set (match_operand:DF 0 "register_operand" "=e")
6014         (minus:DF (match_operand:DF 1 "register_operand" "e")
6015                   (match_operand:DF 2 "register_operand" "e")))]
6016   "TARGET_FPU"
6017   "fsubd\t%1, %2, %0"
6018   [(set_attr "type" "fp")
6019    (set_attr "fptype" "double")])
6021 (define_insn "subsf3"
6022   [(set (match_operand:SF 0 "register_operand" "=f")
6023         (minus:SF (match_operand:SF 1 "register_operand" "f")
6024                   (match_operand:SF 2 "register_operand" "f")))]
6025   "TARGET_FPU"
6026   "fsubs\t%1, %2, %0"
6027   [(set_attr "type" "fp")])
6029 (define_expand "multf3"
6030   [(set (match_operand:TF 0 "nonimmediate_operand" "")
6031         (mult:TF (match_operand:TF 1 "general_operand" "")
6032                  (match_operand:TF 2 "general_operand" "")))]
6033   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6034   "emit_tfmode_binop (MULT, operands); DONE;")
6036 (define_insn "*multf3_hq"
6037   [(set (match_operand:TF 0 "register_operand" "=e")
6038         (mult:TF (match_operand:TF 1 "register_operand" "e")
6039                  (match_operand:TF 2 "register_operand" "e")))]
6040   "TARGET_FPU && TARGET_HARD_QUAD"
6041   "fmulq\t%1, %2, %0"
6042   [(set_attr "type" "fpmul")])
6044 (define_insn "muldf3"
6045   [(set (match_operand:DF 0 "register_operand" "=e")
6046         (mult:DF (match_operand:DF 1 "register_operand" "e")
6047                  (match_operand:DF 2 "register_operand" "e")))]
6048   "TARGET_FPU"
6049   "fmuld\t%1, %2, %0"
6050   [(set_attr "type" "fpmul")
6051    (set_attr "fptype" "double")])
6053 (define_insn "mulsf3"
6054   [(set (match_operand:SF 0 "register_operand" "=f")
6055         (mult:SF (match_operand:SF 1 "register_operand" "f")
6056                  (match_operand:SF 2 "register_operand" "f")))]
6057   "TARGET_FPU"
6058   "fmuls\t%1, %2, %0"
6059   [(set_attr "type" "fpmul")])
6061 (define_insn "*muldf3_extend"
6062   [(set (match_operand:DF 0 "register_operand" "=e")
6063         (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
6064                  (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
6065   "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
6066   "fsmuld\t%1, %2, %0"
6067   [(set_attr "type" "fpmul")
6068    (set_attr "fptype" "double")])
6070 (define_insn "*multf3_extend"
6071   [(set (match_operand:TF 0 "register_operand" "=e")
6072         (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
6073                  (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
6074   "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
6075   "fdmulq\t%1, %2, %0"
6076   [(set_attr "type" "fpmul")])
6078 (define_expand "divtf3"
6079   [(set (match_operand:TF 0 "nonimmediate_operand" "")
6080         (div:TF (match_operand:TF 1 "general_operand" "")
6081                 (match_operand:TF 2 "general_operand" "")))]
6082   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6083   "emit_tfmode_binop (DIV, operands); DONE;")
6085 ;; don't have timing for quad-prec. divide.
6086 (define_insn "*divtf3_hq"
6087   [(set (match_operand:TF 0 "register_operand" "=e")
6088         (div:TF (match_operand:TF 1 "register_operand" "e")
6089                 (match_operand:TF 2 "register_operand" "e")))]
6090   "TARGET_FPU && TARGET_HARD_QUAD"
6091   "fdivq\t%1, %2, %0"
6092   [(set_attr "type" "fpdivd")])
6094 (define_insn "divdf3"
6095   [(set (match_operand:DF 0 "register_operand" "=e")
6096         (div:DF (match_operand:DF 1 "register_operand" "e")
6097                 (match_operand:DF 2 "register_operand" "e")))]
6098   "TARGET_FPU"
6099   "fdivd\t%1, %2, %0"
6100   [(set_attr "type" "fpdivd")
6101    (set_attr "fptype" "double")])
6103 (define_insn "divsf3"
6104   [(set (match_operand:SF 0 "register_operand" "=f")
6105         (div:SF (match_operand:SF 1 "register_operand" "f")
6106                 (match_operand:SF 2 "register_operand" "f")))]
6107   "TARGET_FPU"
6108   "fdivs\t%1, %2, %0"
6109   [(set_attr "type" "fpdivs")])
6111 (define_expand "negtf2"
6112   [(set (match_operand:TF 0 "register_operand" "=e,e")
6113         (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6114   "TARGET_FPU"
6115   "")
6117 (define_insn_and_split "*negtf2_notv9"
6118   [(set (match_operand:TF 0 "register_operand" "=e,e")
6119         (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6120   ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6121   "TARGET_FPU
6122    && ! TARGET_V9"
6123   "@
6124   fnegs\t%0, %0
6125   #"
6126   "&& reload_completed
6127    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6128   [(set (match_dup 2) (neg:SF (match_dup 3)))
6129    (set (match_dup 4) (match_dup 5))
6130    (set (match_dup 6) (match_dup 7))]
6131   "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6132    operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6133    operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6134    operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6135    operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6136    operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6137   [(set_attr "type" "fpmove,*")
6138    (set_attr "length" "*,2")])
6140 (define_insn_and_split "*negtf2_v9"
6141   [(set (match_operand:TF 0 "register_operand" "=e,e")
6142         (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6143   ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6144   "TARGET_FPU && TARGET_V9"
6145   "@
6146   fnegd\t%0, %0
6147   #"
6148   "&& reload_completed
6149    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6150   [(set (match_dup 2) (neg:DF (match_dup 3)))
6151    (set (match_dup 4) (match_dup 5))]
6152   "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6153    operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6154    operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6155    operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6156   [(set_attr "type" "fpmove,*")
6157    (set_attr "length" "*,2")
6158    (set_attr "fptype" "double")])
6160 (define_expand "negdf2"
6161   [(set (match_operand:DF 0 "register_operand" "")
6162         (neg:DF (match_operand:DF 1 "register_operand" "")))]
6163   "TARGET_FPU"
6164   "")
6166 (define_insn_and_split "*negdf2_notv9"
6167   [(set (match_operand:DF 0 "register_operand" "=e,e")
6168         (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
6169   "TARGET_FPU && ! TARGET_V9"
6170   "@
6171   fnegs\t%0, %0
6172   #"
6173   "&& reload_completed
6174    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6175   [(set (match_dup 2) (neg:SF (match_dup 3)))
6176    (set (match_dup 4) (match_dup 5))]
6177   "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6178    operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6179    operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6180    operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6181   [(set_attr "type" "fpmove,*")
6182    (set_attr "length" "*,2")])
6184 (define_insn "*negdf2_v9"
6185   [(set (match_operand:DF 0 "register_operand" "=e")
6186         (neg:DF (match_operand:DF 1 "register_operand" "e")))]
6187   "TARGET_FPU && TARGET_V9"
6188   "fnegd\t%1, %0"
6189   [(set_attr "type" "fpmove")
6190    (set_attr "fptype" "double")])
6192 (define_insn "negsf2"
6193   [(set (match_operand:SF 0 "register_operand" "=f")
6194         (neg:SF (match_operand:SF 1 "register_operand" "f")))]
6195   "TARGET_FPU"
6196   "fnegs\t%1, %0"
6197   [(set_attr "type" "fpmove")])
6199 (define_expand "abstf2"
6200   [(set (match_operand:TF 0 "register_operand" "")
6201         (abs:TF (match_operand:TF 1 "register_operand" "")))]
6202   "TARGET_FPU"
6203   "")
6205 (define_insn_and_split "*abstf2_notv9"
6206   [(set (match_operand:TF 0 "register_operand" "=e,e")
6207         (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6208   ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6209   "TARGET_FPU && ! TARGET_V9"
6210   "@
6211   fabss\t%0, %0
6212   #"
6213   "&& reload_completed
6214    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6215   [(set (match_dup 2) (abs:SF (match_dup 3)))
6216    (set (match_dup 4) (match_dup 5))
6217    (set (match_dup 6) (match_dup 7))]
6218   "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6219    operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6220    operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6221    operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6222    operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6223    operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6224   [(set_attr "type" "fpmove,*")
6225    (set_attr "length" "*,2")])
6227 (define_insn "*abstf2_hq_v9"
6228   [(set (match_operand:TF 0 "register_operand" "=e,e")
6229         (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6230   "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
6231   "@
6232   fabsd\t%0, %0
6233   fabsq\t%1, %0"
6234   [(set_attr "type" "fpmove")
6235    (set_attr "fptype" "double,*")])
6237 (define_insn_and_split "*abstf2_v9"
6238   [(set (match_operand:TF 0 "register_operand" "=e,e")
6239         (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6240   "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
6241   "@
6242   fabsd\t%0, %0
6243   #"
6244   "&& reload_completed
6245    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6246   [(set (match_dup 2) (abs:DF (match_dup 3)))
6247    (set (match_dup 4) (match_dup 5))]
6248   "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6249    operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6250    operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6251    operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6252   [(set_attr "type" "fpmove,*")
6253    (set_attr "length" "*,2")
6254    (set_attr "fptype" "double,*")])
6256 (define_expand "absdf2"
6257   [(set (match_operand:DF 0 "register_operand" "")
6258         (abs:DF (match_operand:DF 1 "register_operand" "")))]
6259   "TARGET_FPU"
6260   "")
6262 (define_insn_and_split "*absdf2_notv9"
6263   [(set (match_operand:DF 0 "register_operand" "=e,e")
6264         (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
6265   "TARGET_FPU && ! TARGET_V9"
6266   "@
6267   fabss\t%0, %0
6268   #"
6269   "&& reload_completed
6270    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6271   [(set (match_dup 2) (abs:SF (match_dup 3)))
6272    (set (match_dup 4) (match_dup 5))]
6273   "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6274    operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6275    operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6276    operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6277   [(set_attr "type" "fpmove,*")
6278    (set_attr "length" "*,2")])
6280 (define_insn "*absdf2_v9"
6281   [(set (match_operand:DF 0 "register_operand" "=e")
6282         (abs:DF (match_operand:DF 1 "register_operand" "e")))]
6283   "TARGET_FPU && TARGET_V9"
6284   "fabsd\t%1, %0"
6285   [(set_attr "type" "fpmove")
6286    (set_attr "fptype" "double")])
6288 (define_insn "abssf2"
6289   [(set (match_operand:SF 0 "register_operand" "=f")
6290         (abs:SF (match_operand:SF 1 "register_operand" "f")))]
6291   "TARGET_FPU"
6292   "fabss\t%1, %0"
6293   [(set_attr "type" "fpmove")])
6295 (define_expand "sqrttf2"
6296   [(set (match_operand:TF 0 "nonimmediate_operand" "")
6297         (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
6298   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6299   "emit_tfmode_unop (SQRT, operands); DONE;")
6301 (define_insn "*sqrttf2_hq"
6302   [(set (match_operand:TF 0 "register_operand" "=e")
6303         (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
6304   "TARGET_FPU && TARGET_HARD_QUAD"
6305   "fsqrtq\t%1, %0"
6306   [(set_attr "type" "fpsqrtd")])
6308 (define_insn "sqrtdf2"
6309   [(set (match_operand:DF 0 "register_operand" "=e")
6310         (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
6311   "TARGET_FPU"
6312   "fsqrtd\t%1, %0"
6313   [(set_attr "type" "fpsqrtd")
6314    (set_attr "fptype" "double")])
6316 (define_insn "sqrtsf2"
6317   [(set (match_operand:SF 0 "register_operand" "=f")
6318         (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
6319   "TARGET_FPU"
6320   "fsqrts\t%1, %0"
6321   [(set_attr "type" "fpsqrts")])
6324 ;; Arithmetic shift instructions.
6326 (define_insn "ashlsi3"
6327   [(set (match_operand:SI 0 "register_operand" "=r")
6328         (ashift:SI (match_operand:SI 1 "register_operand" "r")
6329                    (match_operand:SI 2 "arith_operand" "rI")))]
6330   ""
6332   if (GET_CODE (operands[2]) == CONST_INT)
6333     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6334   return "sll\t%1, %2, %0";
6336   [(set (attr "type")
6337         (if_then_else (match_operand 2 "const_one_operand" "")
6338                       (const_string "ialu") (const_string "shift")))])
6340 (define_expand "ashldi3"
6341   [(set (match_operand:DI 0 "register_operand" "=r")
6342         (ashift:DI (match_operand:DI 1 "register_operand" "r")
6343                    (match_operand:SI 2 "arith_operand" "rI")))]
6344   "TARGET_ARCH64 || TARGET_V8PLUS"
6346   if (! TARGET_ARCH64)
6347     {
6348       if (GET_CODE (operands[2]) == CONST_INT)
6349         FAIL;
6350       emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
6351       DONE;
6352     }
6355 (define_insn "*ashldi3_sp64"
6356   [(set (match_operand:DI 0 "register_operand" "=r")
6357         (ashift:DI (match_operand:DI 1 "register_operand" "r")
6358                    (match_operand:SI 2 "arith_operand" "rI")))]
6359   "TARGET_ARCH64"
6361   if (GET_CODE (operands[2]) == CONST_INT)
6362     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6363   return "sllx\t%1, %2, %0";
6365   [(set (attr "type")
6366         (if_then_else (match_operand 2 "const_one_operand" "")
6367                       (const_string "ialu") (const_string "shift")))])
6369 ;; XXX UGH!
6370 (define_insn "ashldi3_v8plus"
6371   [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6372         (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6373                    (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6374    (clobber (match_scratch:SI 3 "=X,X,&h"))]
6375   "TARGET_V8PLUS"
6376   "* return output_v8plus_shift (operands, insn, \"sllx\");"
6377   [(set_attr "type" "multi")
6378    (set_attr "length" "5,5,6")])
6380 ;; Optimize (1LL<<x)-1
6381 ;; XXX this also needs to be fixed to handle equal subregs
6382 ;; XXX first before we could re-enable it.
6383 ;(define_insn ""
6384 ;  [(set (match_operand:DI 0 "register_operand" "=h")
6385 ;       (plus:DI (ashift:DI (const_int 1)
6386 ;                           (match_operand:SI 1 "arith_operand" "rI"))
6387 ;                (const_int -1)))]
6388 ;  "0 && TARGET_V8PLUS"
6390 ;  if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
6391 ;    return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
6392 ;  return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
6394 ;  [(set_attr "type" "multi")
6395 ;   (set_attr "length" "4")])
6397 (define_insn "*cmp_cc_ashift_1"
6398   [(set (reg:CC_NOOV 100)
6399         (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
6400                                     (const_int 1))
6401                          (const_int 0)))]
6402   ""
6403   "addcc\t%0, %0, %%g0"
6404   [(set_attr "type" "compare")])
6406 (define_insn "*cmp_cc_set_ashift_1"
6407   [(set (reg:CC_NOOV 100)
6408         (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
6409                                     (const_int 1))
6410                          (const_int 0)))
6411    (set (match_operand:SI 0 "register_operand" "=r")
6412         (ashift:SI (match_dup 1) (const_int 1)))]
6413   ""
6414   "addcc\t%1, %1, %0"
6415   [(set_attr "type" "compare")])
6417 (define_insn "ashrsi3"
6418   [(set (match_operand:SI 0 "register_operand" "=r")
6419         (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
6420                      (match_operand:SI 2 "arith_operand" "rI")))]
6421   ""
6422   {
6423      if (GET_CODE (operands[2]) == CONST_INT)
6424        operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6425      return "sra\t%1, %2, %0";
6426   }
6427   [(set_attr "type" "shift")])
6429 (define_insn "*ashrsi3_extend"
6430   [(set (match_operand:DI 0 "register_operand" "=r")
6431         (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
6432                                      (match_operand:SI 2 "arith_operand" "r"))))]
6433   "TARGET_ARCH64"
6434   "sra\t%1, %2, %0"
6435   [(set_attr "type" "shift")])
6437 ;; This handles the case as above, but with constant shift instead of
6438 ;; register. Combiner "simplifies" it for us a little bit though.
6439 (define_insn "*ashrsi3_extend2"
6440   [(set (match_operand:DI 0 "register_operand" "=r")
6441         (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
6442                                 (const_int 32))
6443                      (match_operand:SI 2 "small_int_operand" "I")))]
6444   "TARGET_ARCH64 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64"
6446   operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
6447   return "sra\t%1, %2, %0";
6449   [(set_attr "type" "shift")])
6451 (define_expand "ashrdi3"
6452   [(set (match_operand:DI 0 "register_operand" "=r")
6453         (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6454                      (match_operand:SI 2 "arith_operand" "rI")))]
6455   "TARGET_ARCH64 || TARGET_V8PLUS"
6457   if (! TARGET_ARCH64)
6458     {
6459       if (GET_CODE (operands[2]) == CONST_INT)
6460         FAIL;   /* prefer generic code in this case */
6461       emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
6462       DONE;
6463     }
6466 (define_insn "*ashrdi3_sp64"
6467   [(set (match_operand:DI 0 "register_operand" "=r")
6468         (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6469                      (match_operand:SI 2 "arith_operand" "rI")))]
6470   "TARGET_ARCH64"
6471   
6472   {
6473     if (GET_CODE (operands[2]) == CONST_INT)
6474       operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6475     return "srax\t%1, %2, %0";
6476   }
6477   [(set_attr "type" "shift")])
6479 ;; XXX
6480 (define_insn "ashrdi3_v8plus"
6481   [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6482         (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6483                      (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6484    (clobber (match_scratch:SI 3 "=X,X,&h"))]
6485   "TARGET_V8PLUS"
6486   "* return output_v8plus_shift (operands, insn, \"srax\");"
6487   [(set_attr "type" "multi")
6488    (set_attr "length" "5,5,6")])
6490 (define_insn "lshrsi3"
6491   [(set (match_operand:SI 0 "register_operand" "=r")
6492         (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
6493                      (match_operand:SI 2 "arith_operand" "rI")))]
6494   ""
6495   {
6496     if (GET_CODE (operands[2]) == CONST_INT)
6497       operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6498     return "srl\t%1, %2, %0";
6499   }
6500   [(set_attr "type" "shift")])
6502 ;; This handles the case where
6503 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
6504 ;; but combiner "simplifies" it for us.
6505 (define_insn "*lshrsi3_extend"
6506   [(set (match_operand:DI 0 "register_operand" "=r")
6507         (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
6508                            (match_operand:SI 2 "arith_operand" "r")) 0)
6509                 (match_operand 3 "const_int_operand" "")))]
6510   "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff"
6511   "srl\t%1, %2, %0"
6512   [(set_attr "type" "shift")])
6514 ;; This handles the case where
6515 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
6516 ;; but combiner "simplifies" it for us.
6517 (define_insn "*lshrsi3_extend2"
6518   [(set (match_operand:DI 0 "register_operand" "=r")
6519         (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
6520                          (match_operand 2 "small_int_operand" "I")
6521                          (const_int 32)))]
6522   "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6524   operands[2] = GEN_INT (32 - INTVAL (operands[2]));
6525   return "srl\t%1, %2, %0";
6527   [(set_attr "type" "shift")])
6529 (define_expand "lshrdi3"
6530   [(set (match_operand:DI 0 "register_operand" "=r")
6531         (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6532                      (match_operand:SI 2 "arith_operand" "rI")))]
6533   "TARGET_ARCH64 || TARGET_V8PLUS"
6535   if (! TARGET_ARCH64)
6536     {
6537       if (GET_CODE (operands[2]) == CONST_INT)
6538         FAIL;
6539       emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
6540       DONE;
6541     }
6544 (define_insn "*lshrdi3_sp64"
6545   [(set (match_operand:DI 0 "register_operand" "=r")
6546         (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6547                      (match_operand:SI 2 "arith_operand" "rI")))]
6548   "TARGET_ARCH64"
6549   {
6550     if (GET_CODE (operands[2]) == CONST_INT)
6551       operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6552     return "srlx\t%1, %2, %0";
6553   }
6554   [(set_attr "type" "shift")])
6556 ;; XXX
6557 (define_insn "lshrdi3_v8plus"
6558   [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6559         (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6560                      (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6561    (clobber (match_scratch:SI 3 "=X,X,&h"))]
6562   "TARGET_V8PLUS"
6563   "* return output_v8plus_shift (operands, insn, \"srlx\");"
6564   [(set_attr "type" "multi")
6565    (set_attr "length" "5,5,6")])
6567 (define_insn ""
6568   [(set (match_operand:SI 0 "register_operand" "=r")
6569         (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6570                                              (const_int 32)) 4)
6571                      (match_operand:SI 2 "small_int_operand" "I")))]
6572   "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6574   operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6575   return "srax\t%1, %2, %0";
6577   [(set_attr "type" "shift")])
6579 (define_insn ""
6580   [(set (match_operand:SI 0 "register_operand" "=r")
6581         (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6582                                              (const_int 32)) 4)
6583                      (match_operand:SI 2 "small_int_operand" "I")))]
6584   "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6586   operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6587   return "srlx\t%1, %2, %0";
6589   [(set_attr "type" "shift")])
6591 (define_insn ""
6592   [(set (match_operand:SI 0 "register_operand" "=r")
6593         (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6594                                              (match_operand:SI 2 "small_int_operand" "I")) 4)
6595                      (match_operand:SI 3 "small_int_operand" "I")))]
6596   "TARGET_ARCH64
6597    && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6598    && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6599    && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6601   operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6603   return "srax\t%1, %2, %0";
6605   [(set_attr "type" "shift")])
6607 (define_insn ""
6608   [(set (match_operand:SI 0 "register_operand" "=r")
6609         (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6610                                              (match_operand:SI 2 "small_int_operand" "I")) 4)
6611                      (match_operand:SI 3 "small_int_operand" "I")))]
6612   "TARGET_ARCH64
6613    && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6614    && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6615    && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6617   operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6619   return "srlx\t%1, %2, %0";
6621   [(set_attr "type" "shift")])
6624 ;; Unconditional and other jump instructions.
6626 (define_insn "jump"
6627   [(set (pc) (label_ref (match_operand 0 "" "")))]
6628   ""
6629   "* return output_ubranch (operands[0], 0, insn);"
6630   [(set_attr "type" "uncond_branch")])
6632 (define_expand "tablejump"
6633   [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
6634               (use (label_ref (match_operand 1 "" "")))])]
6635   ""
6637   gcc_assert (GET_MODE (operands[0]) == CASE_VECTOR_MODE);
6639   /* In pic mode, our address differences are against the base of the
6640      table.  Add that base value back in; CSE ought to be able to combine
6641      the two address loads.  */
6642   if (flag_pic)
6643     {
6644       rtx tmp, tmp2;
6645       tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
6646       tmp2 = operands[0];
6647       if (CASE_VECTOR_MODE != Pmode)
6648         tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
6649       tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
6650       operands[0] = memory_address (Pmode, tmp);
6651     }
6654 (define_insn "*tablejump_sp32"
6655   [(set (pc) (match_operand:SI 0 "address_operand" "p"))
6656    (use (label_ref (match_operand 1 "" "")))]
6657   "! TARGET_ARCH64"
6658   "jmp\t%a0%#"
6659   [(set_attr "type" "uncond_branch")])
6661 (define_insn "*tablejump_sp64"
6662   [(set (pc) (match_operand:DI 0 "address_operand" "p"))
6663    (use (label_ref (match_operand 1 "" "")))]
6664   "TARGET_ARCH64"
6665   "jmp\t%a0%#"
6666   [(set_attr "type" "uncond_branch")])
6669 ;; Jump to subroutine instructions.
6671 (define_expand "call"
6672   ;; Note that this expression is not used for generating RTL.
6673   ;; All the RTL is generated explicitly below.
6674   [(call (match_operand 0 "call_operand" "")
6675          (match_operand 3 "" "i"))]
6676   ;; operands[2] is next_arg_register
6677   ;; operands[3] is struct_value_size_rtx.
6678   ""
6680   rtx fn_rtx;
6682   gcc_assert (GET_MODE (operands[0]) == FUNCTION_MODE);
6684   gcc_assert (GET_CODE (operands[3]) == CONST_INT);
6686   if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
6687     {
6688       /* This is really a PIC sequence.  We want to represent
6689          it as a funny jump so its delay slots can be filled. 
6691          ??? But if this really *is* a CALL, will not it clobber the
6692          call-clobbered registers?  We lose this if it is a JUMP_INSN.
6693          Why cannot we have delay slots filled if it were a CALL?  */
6695       /* We accept negative sizes for untyped calls.  */
6696       if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6697         emit_jump_insn
6698           (gen_rtx_PARALLEL
6699            (VOIDmode,
6700             gen_rtvec (3,
6701                        gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6702                        operands[3],
6703                        gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6704       else
6705         emit_jump_insn
6706           (gen_rtx_PARALLEL
6707            (VOIDmode,
6708             gen_rtvec (2,
6709                        gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6710                        gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6711       goto finish_call;
6712     }
6714   fn_rtx = operands[0];
6716   /* We accept negative sizes for untyped calls.  */
6717   if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6718     emit_call_insn
6719       (gen_rtx_PARALLEL
6720        (VOIDmode,
6721         gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6722                    operands[3],
6723                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6724   else
6725     emit_call_insn
6726       (gen_rtx_PARALLEL
6727        (VOIDmode,
6728         gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6729                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6731  finish_call:
6733   DONE;
6736 ;; We can't use the same pattern for these two insns, because then registers
6737 ;; in the address may not be properly reloaded.
6739 (define_insn "*call_address_sp32"
6740   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6741          (match_operand 1 "" ""))
6742    (clobber (reg:SI 15))]
6743   ;;- Do not use operand 1 for most machines.
6744   "! TARGET_ARCH64"
6745   "call\t%a0, %1%#"
6746   [(set_attr "type" "call")])
6748 (define_insn "*call_symbolic_sp32"
6749   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6750          (match_operand 1 "" ""))
6751    (clobber (reg:SI 15))]
6752   ;;- Do not use operand 1 for most machines.
6753   "! TARGET_ARCH64"
6754   "call\t%a0, %1%#"
6755   [(set_attr "type" "call")])
6757 (define_insn "*call_address_sp64"
6758   [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
6759          (match_operand 1 "" ""))
6760    (clobber (reg:DI 15))]
6761   ;;- Do not use operand 1 for most machines.
6762   "TARGET_ARCH64"
6763   "call\t%a0, %1%#"
6764   [(set_attr "type" "call")])
6766 (define_insn "*call_symbolic_sp64"
6767   [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6768          (match_operand 1 "" ""))
6769    (clobber (reg:DI 15))]
6770   ;;- Do not use operand 1 for most machines.
6771   "TARGET_ARCH64"
6772   "call\t%a0, %1%#"
6773   [(set_attr "type" "call")])
6775 ;; This is a call that wants a structure value.
6776 ;; There is no such critter for v9 (??? we may need one anyway).
6777 (define_insn "*call_address_struct_value_sp32"
6778   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6779          (match_operand 1 "" ""))
6780    (match_operand 2 "immediate_operand" "")
6781    (clobber (reg:SI 15))]
6782   ;;- Do not use operand 1 for most machines.
6783   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6785   operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6786   return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6788   [(set_attr "type" "call_no_delay_slot")
6789    (set_attr "length" "3")])
6791 ;; This is a call that wants a structure value.
6792 ;; There is no such critter for v9 (??? we may need one anyway).
6793 (define_insn "*call_symbolic_struct_value_sp32"
6794   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6795          (match_operand 1 "" ""))
6796    (match_operand 2 "immediate_operand" "")
6797    (clobber (reg:SI 15))]
6798   ;;- Do not use operand 1 for most machines.
6799   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6801   operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6802   return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6804   [(set_attr "type" "call_no_delay_slot")
6805    (set_attr "length" "3")])
6807 ;; This is a call that may want a structure value.  This is used for
6808 ;; untyped_calls.
6809 (define_insn "*call_address_untyped_struct_value_sp32"
6810   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6811          (match_operand 1 "" ""))
6812    (match_operand 2 "immediate_operand" "")
6813    (clobber (reg:SI 15))]
6814   ;;- Do not use operand 1 for most machines.
6815   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6816   "call\t%a0, %1\n\t nop\n\tnop"
6817   [(set_attr "type" "call_no_delay_slot")
6818    (set_attr "length" "3")])
6820 ;; This is a call that may want a structure value.  This is used for
6821 ;; untyped_calls.
6822 (define_insn "*call_symbolic_untyped_struct_value_sp32"
6823   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6824          (match_operand 1 "" ""))
6825    (match_operand 2 "immediate_operand" "")
6826    (clobber (reg:SI 15))]
6827   ;;- Do not use operand 1 for most machines.
6828   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6829   "call\t%a0, %1\n\t nop\n\tnop"
6830   [(set_attr "type" "call_no_delay_slot")
6831    (set_attr "length" "3")])
6833 (define_expand "call_value"
6834   ;; Note that this expression is not used for generating RTL.
6835   ;; All the RTL is generated explicitly below.
6836   [(set (match_operand 0 "register_operand" "=rf")
6837         (call (match_operand 1 "" "")
6838               (match_operand 4 "" "")))]
6839   ;; operand 2 is stack_size_rtx
6840   ;; operand 3 is next_arg_register
6841   ""
6843   rtx fn_rtx;
6844   rtvec vec;
6846   gcc_assert (GET_MODE (operands[1]) == FUNCTION_MODE);
6848   fn_rtx = operands[1];
6850   vec = gen_rtvec (2,
6851                    gen_rtx_SET (VOIDmode, operands[0],
6852                                 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
6853                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
6855   emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec));
6857   DONE;
6860 (define_insn "*call_value_address_sp32"
6861   [(set (match_operand 0 "" "=rf")
6862         (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
6863               (match_operand 2 "" "")))
6864    (clobber (reg:SI 15))]
6865   ;;- Do not use operand 2 for most machines.
6866   "! TARGET_ARCH64"
6867   "call\t%a1, %2%#"
6868   [(set_attr "type" "call")])
6870 (define_insn "*call_value_symbolic_sp32"
6871   [(set (match_operand 0 "" "=rf")
6872         (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6873               (match_operand 2 "" "")))
6874    (clobber (reg:SI 15))]
6875   ;;- Do not use operand 2 for most machines.
6876   "! TARGET_ARCH64"
6877   "call\t%a1, %2%#"
6878   [(set_attr "type" "call")])
6880 (define_insn "*call_value_address_sp64"
6881   [(set (match_operand 0 "" "")
6882         (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
6883               (match_operand 2 "" "")))
6884    (clobber (reg:DI 15))]
6885   ;;- Do not use operand 2 for most machines.
6886   "TARGET_ARCH64"
6887   "call\t%a1, %2%#"
6888   [(set_attr "type" "call")])
6890 (define_insn "*call_value_symbolic_sp64"
6891   [(set (match_operand 0 "" "")
6892         (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6893               (match_operand 2 "" "")))
6894    (clobber (reg:DI 15))]
6895   ;;- Do not use operand 2 for most machines.
6896   "TARGET_ARCH64"
6897   "call\t%a1, %2%#"
6898   [(set_attr "type" "call")])
6900 (define_expand "untyped_call"
6901   [(parallel [(call (match_operand 0 "" "")
6902                     (const_int 0))
6903               (match_operand:BLK 1 "memory_operand" "")
6904               (match_operand 2 "" "")])]
6905   ""
6907   rtx valreg1 = gen_rtx_REG (DImode, 8);
6908   rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6909   rtx result = operands[1];
6911   /* Pass constm1 to indicate that it may expect a structure value, but
6912      we don't know what size it is.  */
6913   emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
6915   /* Save the function value registers.  */
6916   emit_move_insn (adjust_address (result, DImode, 0), valreg1);
6917   emit_move_insn (adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8),
6918                                   valreg2);
6920   /* The optimizer does not know that the call sets the function value
6921      registers we stored in the result block.  We avoid problems by
6922      claiming that all hard registers are used and clobbered at this
6923      point.  */
6924   emit_insn (gen_blockage ());
6926   DONE;
6929 ;;  Tail call instructions.
6931 (define_expand "sibcall"
6932   [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
6933               (return)])]
6934   ""
6935   "")
6937 (define_insn "*sibcall_symbolic_sp32"
6938   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6939          (match_operand 1 "" ""))
6940    (return)]
6941   "! TARGET_ARCH64"
6942   "* return output_sibcall(insn, operands[0]);"
6943   [(set_attr "type" "sibcall")])
6945 (define_insn "*sibcall_symbolic_sp64"
6946   [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6947          (match_operand 1 "" ""))
6948    (return)]
6949   "TARGET_ARCH64"
6950   "* return output_sibcall(insn, operands[0]);"
6951   [(set_attr "type" "sibcall")])
6953 (define_expand "sibcall_value"
6954   [(parallel [(set (match_operand 0 "register_operand" "=rf")
6955                 (call (match_operand 1 "" "") (const_int 0)))
6956               (return)])]
6957   ""
6958   "")
6960 (define_insn "*sibcall_value_symbolic_sp32"
6961   [(set (match_operand 0 "" "=rf")
6962         (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6963               (match_operand 2 "" "")))
6964    (return)]
6965   "! TARGET_ARCH64"
6966   "* return output_sibcall(insn, operands[1]);"
6967   [(set_attr "type" "sibcall")])
6969 (define_insn "*sibcall_value_symbolic_sp64"
6970   [(set (match_operand 0 "" "")
6971         (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6972               (match_operand 2 "" "")))
6973    (return)]
6974   "TARGET_ARCH64"
6975   "* return output_sibcall(insn, operands[1]);"
6976   [(set_attr "type" "sibcall")])
6979 ;; Special instructions.
6981 (define_expand "prologue"
6982   [(const_int 0)]
6983   ""
6985   sparc_expand_prologue ();
6986   DONE;
6989 ;; The "save register window" insn is modelled as follows so that the DWARF-2
6990 ;; backend automatically emits the required call frame debugging information
6991 ;; while it is parsing it.  Therefore, the pattern should not be modified
6992 ;; without first studying the impact of the changes on the debug info.
6993 ;; [(set (%fp) (%sp))
6994 ;;  (set (%sp) (unspec_volatile [(%sp) (-frame_size)] UNSPECV_SAVEW))
6995 ;;  (set (%i7) (%o7))]
6997 (define_insn "save_register_window<P:mode>"
6998   [(set (reg:P 30) (reg:P 14))
6999    (set (reg:P 14) (unspec_volatile:P [(reg:P 14)
7000                                        (match_operand:P 0 "arith_operand" "rI")] UNSPECV_SAVEW))
7001    (set (reg:P 31) (reg:P 15))]
7002   ""
7003   "save\t%%sp, %0, %%sp"
7004   [(set_attr "type" "savew")])
7006 (define_expand "epilogue"
7007   [(return)]
7008   ""
7010   sparc_expand_epilogue ();
7013 (define_expand "sibcall_epilogue"
7014   [(return)]
7015   ""
7017   sparc_expand_epilogue ();
7018   DONE;
7021 (define_expand "return"
7022   [(return)]
7023   "sparc_can_use_return_insn_p ()"
7024   "")
7026 (define_insn "*return_internal"
7027   [(return)]
7028   ""
7029   "* return output_return (insn);"
7030   [(set_attr "type" "return")
7031    (set (attr "length")
7032         (cond [(eq_attr "leaf_function" "true")
7033                  (if_then_else (eq_attr "empty_delay_slot" "true")
7034                                (const_int 2)
7035                                (const_int 1))
7036                (eq_attr "calls_eh_return" "true")
7037                  (if_then_else (eq_attr "delayed_branch" "true")
7038                                (if_then_else (eq_attr "isa" "v9")
7039                                              (const_int 2)
7040                                              (const_int 3))
7041                                (if_then_else (eq_attr "isa" "v9")
7042                                              (const_int 3)
7043                                              (const_int 4)))
7044                (eq_attr "empty_delay_slot" "true")
7045                  (if_then_else (eq_attr "delayed_branch" "true")
7046                                (const_int 2)
7047                                (const_int 3))
7048               ] (const_int 1)))])
7050 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
7051 ;; all of memory.  This blocks insns from being moved across this point.
7053 (define_insn "blockage"
7054   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7055   ""
7056   ""
7057   [(set_attr "length" "0")])
7059 ;; Prepare to return any type including a structure value.
7061 (define_expand "untyped_return"
7062   [(match_operand:BLK 0 "memory_operand" "")
7063    (match_operand 1 "" "")]
7064   ""
7066   rtx valreg1 = gen_rtx_REG (DImode, 24);
7067   rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
7068   rtx result = operands[0];
7070   if (! TARGET_ARCH64)
7071     {
7072       rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
7073                                          ? 15 : 31));
7074       rtx value = gen_reg_rtx (SImode);
7076       /* Fetch the instruction where we will return to and see if it's an unimp
7077          instruction (the most significant 10 bits will be zero).  If so,
7078          update the return address to skip the unimp instruction.  */
7079       emit_move_insn (value,
7080                       gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
7081       emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
7082       emit_insn (gen_update_return (rtnreg, value));
7083     }
7085   /* Reload the function value registers.  */
7086   emit_move_insn (valreg1, adjust_address (result, DImode, 0));
7087   emit_move_insn (valreg2,
7088                   adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
7090   /* Put USE insns before the return.  */
7091   emit_insn (gen_rtx_USE (VOIDmode, valreg1));
7092   emit_insn (gen_rtx_USE (VOIDmode, valreg2));
7094   /* Construct the return.  */
7095   expand_naked_return ();
7097   DONE;
7100 ;; This is a bit of a hack.  We're incrementing a fixed register (%i7),
7101 ;; and parts of the compiler don't want to believe that the add is needed.
7103 (define_insn "update_return"
7104   [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
7105                (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
7106   "! TARGET_ARCH64"
7108   if (flag_delayed_branch)
7109     return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
7110   else
7111     return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
7113   [(set (attr "type") (const_string "multi"))
7114    (set (attr "length")
7115         (if_then_else (eq_attr "delayed_branch" "true")
7116                       (const_int 3)
7117                       (const_int 4)))])
7119 (define_insn "nop"
7120   [(const_int 0)]
7121   ""
7122   "nop")
7124 (define_expand "indirect_jump"
7125   [(set (pc) (match_operand 0 "address_operand" "p"))]
7126   ""
7127   "")
7129 (define_insn "*branch_sp32"
7130   [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
7131   "! TARGET_ARCH64"
7132  "jmp\t%a0%#"
7133  [(set_attr "type" "uncond_branch")])
7135 (define_insn "*branch_sp64"
7136   [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
7137   "TARGET_ARCH64"
7138   "jmp\t%a0%#"
7139   [(set_attr "type" "uncond_branch")])
7141 (define_expand "nonlocal_goto"
7142   [(match_operand:SI 0 "general_operand" "")
7143    (match_operand:SI 1 "general_operand" "")
7144    (match_operand:SI 2 "general_operand" "")
7145    (match_operand:SI 3 "" "")]
7146   ""
7148   rtx lab = operands[1];
7149   rtx stack = operands[2];
7150   rtx fp = operands[3];
7151   rtx labreg;
7153   /* Trap instruction to flush all the register windows.  */
7154   emit_insn (gen_flush_register_windows ());
7156   /* Load the fp value for the containing fn into %fp.  This is needed
7157      because STACK refers to %fp.  Note that virtual register instantiation
7158      fails if the virtual %fp isn't set from a register.  */
7159   if (GET_CODE (fp) != REG)
7160     fp = force_reg (Pmode, fp);
7161   emit_move_insn (virtual_stack_vars_rtx, fp);
7163   /* Find the containing function's current nonlocal goto handler,
7164      which will do any cleanups and then jump to the label.  */
7165   labreg = gen_rtx_REG (Pmode, 8);
7166   emit_move_insn (labreg, lab);
7168   /* Restore %fp from stack pointer value for containing function.
7169      The restore insn that follows will move this to %sp,
7170      and reload the appropriate value into %fp.  */
7171   emit_move_insn (hard_frame_pointer_rtx, stack);
7173   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
7174   emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
7176   /* ??? The V9-specific version was disabled in rev 1.65.  */
7177   emit_jump_insn (gen_goto_handler_and_restore (labreg));
7178   emit_barrier ();
7179   DONE;
7182 ;; Special trap insn to flush register windows.
7183 (define_insn "flush_register_windows"
7184   [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
7185   ""
7186   { return TARGET_V9 ? "flushw" : "ta\t3"; }
7187   [(set_attr "type" "flushw")])
7189 (define_insn "goto_handler_and_restore"
7190   [(unspec_volatile [(match_operand 0 "register_operand" "=r")] UNSPECV_GOTO)]
7191   "GET_MODE (operands[0]) == Pmode"
7193   if (flag_delayed_branch)
7194     return "jmp\t%0\n\t restore";
7195   else
7196     return "mov\t%0,%%g1\n\trestore\n\tjmp\t%%g1\n\t nop";
7198   [(set (attr "type") (const_string "multi"))
7199    (set (attr "length")
7200         (if_then_else (eq_attr "delayed_branch" "true")
7201                       (const_int 2)
7202                       (const_int 4)))])
7204 ;; For __builtin_setjmp we need to flush register windows iff the function
7205 ;; calls alloca as well, because otherwise the register window might be
7206 ;; saved after %sp adjustment and thus setjmp would crash
7207 (define_expand "builtin_setjmp_setup"
7208   [(match_operand 0 "register_operand" "r")]
7209   ""
7211   emit_insn (gen_do_builtin_setjmp_setup ());
7212   DONE;
7215 (define_insn "do_builtin_setjmp_setup"
7216   [(unspec_volatile [(const_int 0)] UNSPECV_SETJMP)]
7217   ""
7219   if (! current_function_calls_alloca)
7220     return "";
7221   if (! TARGET_V9)
7222     return "\tta\t3\n";
7223   fputs ("\tflushw\n", asm_out_file);
7224   if (flag_pic)
7225     fprintf (asm_out_file, "\tst%c\t%%l7, [%%sp+%d]\n",
7226              TARGET_ARCH64 ? 'x' : 'w',
7227              SPARC_STACK_BIAS + 7 * UNITS_PER_WORD);
7228   fprintf (asm_out_file, "\tst%c\t%%fp, [%%sp+%d]\n",
7229            TARGET_ARCH64 ? 'x' : 'w',
7230            SPARC_STACK_BIAS + 14 * UNITS_PER_WORD);
7231   fprintf (asm_out_file, "\tst%c\t%%i7, [%%sp+%d]\n",
7232            TARGET_ARCH64 ? 'x' : 'w',
7233            SPARC_STACK_BIAS + 15 * UNITS_PER_WORD);
7234   return "";
7236   [(set_attr "type" "multi")
7237    (set (attr "length")
7238         (cond [(eq_attr "calls_alloca" "false")
7239                  (const_int 0)
7240                (eq_attr "isa" "!v9")
7241                  (const_int 1)
7242                (eq_attr "pic" "true")
7243                  (const_int 4)] (const_int 3)))])
7245 ;; Pattern for use after a setjmp to store FP and the return register
7246 ;; into the stack area.
7248 (define_expand "setjmp"
7249   [(const_int 0)]
7250   ""
7252   if (TARGET_ARCH64)
7253     emit_insn (gen_setjmp_64 ());
7254   else
7255     emit_insn (gen_setjmp_32 ());
7256   DONE;
7259 (define_expand "setjmp_32"
7260   [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
7261    (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
7262   ""
7263   { operands[0] = frame_pointer_rtx; })
7265 (define_expand "setjmp_64"
7266   [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
7267    (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
7268   ""
7269   { operands[0] = frame_pointer_rtx; })
7271 ;; Special pattern for the FLUSH instruction.
7273 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
7274 ; of the define_insn otherwise missing a mode.  We make "flush", aka
7275 ; gen_flush, the default one since sparc_initialize_trampoline uses
7276 ; it on SImode mem values.
7278 (define_insn "flush"
7279   [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7280   ""
7281   { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7282   [(set_attr "type" "iflush")])
7284 (define_insn "flushdi"
7285   [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7286   ""
7287   { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7288   [(set_attr "type" "iflush")])
7291 ;; Find first set instructions.
7293 ;; The scan instruction searches from the most significant bit while ffs
7294 ;; searches from the least significant bit.  The bit index and treatment of
7295 ;; zero also differ.  It takes at least 7 instructions to get the proper
7296 ;; result.  Here is an obvious 8 instruction sequence.
7298 ;; XXX
7299 (define_insn "ffssi2"
7300   [(set (match_operand:SI 0 "register_operand" "=&r")
7301         (ffs:SI (match_operand:SI 1 "register_operand" "r")))
7302    (clobber (match_scratch:SI 2 "=&r"))]
7303   "TARGET_SPARCLITE || TARGET_SPARCLET"
7305   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";
7307   [(set_attr "type" "multi")
7308    (set_attr "length" "8")])
7310 ;; ??? This should be a define expand, so that the extra instruction have
7311 ;; a chance of being optimized away.
7313 ;; Disabled because none of the UltraSPARCs implement popc.  The HAL R1
7314 ;; does, but no one uses that and we don't have a switch for it.
7316 ;(define_insn "ffsdi2"
7317 ;  [(set (match_operand:DI 0 "register_operand" "=&r")
7318 ;       (ffs:DI (match_operand:DI 1 "register_operand" "r")))
7319 ;   (clobber (match_scratch:DI 2 "=&r"))]
7320 ;  "TARGET_ARCH64"
7321 ;  "neg\t%1, %2\;xnor\t%1, %2, %2\;popc\t%2, %0\;movzr\t%1, 0, %0"
7322 ;  [(set_attr "type" "multi")
7323 ;   (set_attr "length" "4")])
7327 ;; Peepholes go at the end.
7329 ;; Optimize consecutive loads or stores into ldd and std when possible.
7330 ;; The conditions in which we do this are very restricted and are 
7331 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
7333 (define_peephole2
7334   [(set (match_operand:SI 0 "memory_operand" "")
7335       (const_int 0))
7336    (set (match_operand:SI 1 "memory_operand" "")
7337       (const_int 0))]
7338   "TARGET_V9
7339    && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
7340   [(set (match_dup 0)
7341        (const_int 0))]
7342   "operands[0] = widen_memory_access (operands[0], DImode, 0);")
7344 (define_peephole2
7345   [(set (match_operand:SI 0 "memory_operand" "")
7346       (const_int 0))
7347    (set (match_operand:SI 1 "memory_operand" "")
7348       (const_int 0))]
7349   "TARGET_V9
7350    && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
7351   [(set (match_dup 1)
7352        (const_int 0))]
7353   "operands[1] = widen_memory_access (operands[1], DImode, 0);")
7355 (define_peephole2
7356   [(set (match_operand:SI 0 "register_operand" "")
7357         (match_operand:SI 1 "memory_operand" ""))
7358    (set (match_operand:SI 2 "register_operand" "")
7359         (match_operand:SI 3 "memory_operand" ""))]
7360   "registers_ok_for_ldd_peep (operands[0], operands[2]) 
7361    && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])" 
7362   [(set (match_dup 0)
7363         (match_dup 1))]
7364   "operands[1] = widen_memory_access (operands[1], DImode, 0);
7365    operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
7367 (define_peephole2
7368   [(set (match_operand:SI 0 "memory_operand" "")
7369         (match_operand:SI 1 "register_operand" ""))
7370    (set (match_operand:SI 2 "memory_operand" "")
7371         (match_operand:SI 3 "register_operand" ""))]
7372   "registers_ok_for_ldd_peep (operands[1], operands[3]) 
7373    && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7374   [(set (match_dup 0)
7375         (match_dup 1))]
7376   "operands[0] = widen_memory_access (operands[0], DImode, 0);
7377    operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
7379 (define_peephole2
7380   [(set (match_operand:SF 0 "register_operand" "")
7381         (match_operand:SF 1 "memory_operand" ""))
7382    (set (match_operand:SF 2 "register_operand" "")
7383         (match_operand:SF 3 "memory_operand" ""))]
7384   "registers_ok_for_ldd_peep (operands[0], operands[2]) 
7385    && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
7386   [(set (match_dup 0)
7387         (match_dup 1))]
7388   "operands[1] = widen_memory_access (operands[1], DFmode, 0);
7389    operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
7391 (define_peephole2
7392   [(set (match_operand:SF 0 "memory_operand" "")
7393         (match_operand:SF 1 "register_operand" ""))
7394    (set (match_operand:SF 2 "memory_operand" "")
7395         (match_operand:SF 3 "register_operand" ""))]
7396   "registers_ok_for_ldd_peep (operands[1], operands[3]) 
7397   && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7398   [(set (match_dup 0)
7399         (match_dup 1))]
7400   "operands[0] = widen_memory_access (operands[0], DFmode, 0);
7401    operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
7403 (define_peephole2
7404   [(set (match_operand:SI 0 "register_operand" "")
7405         (match_operand:SI 1 "memory_operand" ""))
7406    (set (match_operand:SI 2 "register_operand" "")
7407         (match_operand:SI 3 "memory_operand" ""))]
7408   "registers_ok_for_ldd_peep (operands[2], operands[0]) 
7409   && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
7410   [(set (match_dup 2)
7411         (match_dup 3))]
7412    "operands[3] = widen_memory_access (operands[3], DImode, 0);
7413     operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
7415 (define_peephole2
7416   [(set (match_operand:SI 0 "memory_operand" "")
7417         (match_operand:SI 1 "register_operand" ""))
7418    (set (match_operand:SI 2 "memory_operand" "")
7419         (match_operand:SI 3 "register_operand" ""))]
7420   "registers_ok_for_ldd_peep (operands[3], operands[1]) 
7421   && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)" 
7422   [(set (match_dup 2)
7423         (match_dup 3))]
7424   "operands[2] = widen_memory_access (operands[2], DImode, 0);
7425    operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
7426    ")
7428 (define_peephole2
7429   [(set (match_operand:SF 0 "register_operand" "")
7430         (match_operand:SF 1 "memory_operand" ""))
7431    (set (match_operand:SF 2 "register_operand" "")
7432         (match_operand:SF 3 "memory_operand" ""))]
7433   "registers_ok_for_ldd_peep (operands[2], operands[0]) 
7434   && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
7435   [(set (match_dup 2)
7436         (match_dup 3))]
7437   "operands[3] = widen_memory_access (operands[3], DFmode, 0);
7438    operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
7440 (define_peephole2
7441   [(set (match_operand:SF 0 "memory_operand" "")
7442         (match_operand:SF 1 "register_operand" ""))
7443    (set (match_operand:SF 2 "memory_operand" "")
7444         (match_operand:SF 3 "register_operand" ""))]
7445   "registers_ok_for_ldd_peep (operands[3], operands[1]) 
7446   && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
7447   [(set (match_dup 2)
7448         (match_dup 3))]
7449   "operands[2] = widen_memory_access (operands[2], DFmode, 0);
7450    operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
7452 ;; Optimize the case of following a reg-reg move with a test
7453 ;; of reg just moved.  Don't allow floating point regs for operand 0 or 1.
7454 ;; This can result from a float to fix conversion.
7456 (define_peephole2
7457   [(set (match_operand:SI 0 "register_operand" "")
7458         (match_operand:SI 1 "register_operand" ""))
7459    (set (reg:CC 100)
7460         (compare:CC (match_operand:SI 2 "register_operand" "")
7461                     (const_int 0)))]
7462   "(rtx_equal_p (operands[2], operands[0])
7463     || rtx_equal_p (operands[2], operands[1]))
7464     && ! SPARC_FP_REG_P (REGNO (operands[0]))
7465     && ! SPARC_FP_REG_P (REGNO (operands[1]))"
7466   [(parallel [(set (match_dup 0) (match_dup 1))
7467               (set (reg:CC 100)
7468                    (compare:CC (match_dup 1) (const_int 0)))])]
7469   "")
7471 (define_peephole2
7472   [(set (match_operand:DI 0 "register_operand" "")
7473         (match_operand:DI 1 "register_operand" ""))
7474    (set (reg:CCX 100)
7475         (compare:CCX (match_operand:DI 2 "register_operand" "")
7476                     (const_int 0)))]
7477   "TARGET_ARCH64
7478    && (rtx_equal_p (operands[2], operands[0])
7479        || rtx_equal_p (operands[2], operands[1]))
7480    && ! SPARC_FP_REG_P (REGNO (operands[0]))
7481    && ! SPARC_FP_REG_P (REGNO (operands[1]))"
7482   [(parallel [(set (match_dup 0) (match_dup 1))
7483               (set (reg:CCX 100)
7484                    (compare:CCX (match_dup 1) (const_int 0)))])]
7485   "")
7488 ;; Prefetch instructions.
7490 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
7491 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
7492 ;; ??? operations.  With DFA we might be able to model this, but it requires a lot of
7493 ;; ??? state.
7494 (define_expand "prefetch"
7495   [(match_operand 0 "address_operand" "")
7496    (match_operand 1 "const_int_operand" "")
7497    (match_operand 2 "const_int_operand" "")]
7498   "TARGET_V9"
7500   if (TARGET_ARCH64)
7501     emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
7502   else
7503     emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
7504   DONE;
7507 (define_insn "prefetch_64"
7508   [(prefetch (match_operand:DI 0 "address_operand" "p")
7509              (match_operand:DI 1 "const_int_operand" "n")
7510              (match_operand:DI 2 "const_int_operand" "n"))]
7511   ""
7513   static const char * const prefetch_instr[2][2] = {
7514     {
7515       "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7516       "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7517     },
7518     {
7519       "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7520       "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7521     }
7522   };
7523   int read_or_write = INTVAL (operands[1]);
7524   int locality = INTVAL (operands[2]);
7526   gcc_assert (read_or_write == 0 || read_or_write == 1);
7527   gcc_assert (locality >= 0 && locality < 4);
7528   return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7530   [(set_attr "type" "load")])
7532 (define_insn "prefetch_32"
7533   [(prefetch (match_operand:SI 0 "address_operand" "p")
7534              (match_operand:SI 1 "const_int_operand" "n")
7535              (match_operand:SI 2 "const_int_operand" "n"))]
7536   ""
7538   static const char * const prefetch_instr[2][2] = {
7539     {
7540       "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7541       "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7542     },
7543     {
7544       "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7545       "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7546     }
7547   };
7548   int read_or_write = INTVAL (operands[1]);
7549   int locality = INTVAL (operands[2]);
7551   gcc_assert (read_or_write == 0 || read_or_write == 1);
7552   gcc_assert (locality >= 0 && locality < 4);
7553   return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7555   [(set_attr "type" "load")])
7558 ;; Trap instructions.
7560 (define_insn "trap"
7561   [(trap_if (const_int 1) (const_int 5))]
7562   ""
7563   "ta\t5"
7564   [(set_attr "type" "trap")])
7566 (define_expand "conditional_trap"
7567   [(trap_if (match_operator 0 "noov_compare_operator" [(match_dup 2) (match_dup 3)])
7568             (match_operand:SI 1 "arith_operand" ""))]
7569   ""
7570   "operands[2] = gen_compare_reg (GET_CODE (operands[0]),
7571                                   sparc_compare_op0, sparc_compare_op1);
7572    if (GET_MODE (operands[2]) != CCmode && GET_MODE (operands[2]) != CCXmode)
7573      FAIL;
7574    operands[3] = const0_rtx;")
7576 (define_insn ""
7577   [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CC 100) (const_int 0)])
7578             (match_operand:SI 1 "arith_operand" "rM"))]
7579   ""
7581   if (TARGET_V9)
7582     return "t%C0\t%%icc, %1";
7583   else
7584     return "t%C0\t%1";
7586   [(set_attr "type" "trap")])
7588 (define_insn ""
7589   [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CCX 100) (const_int 0)])
7590             (match_operand:SI 1 "arith_operand" "rM"))]
7591   "TARGET_V9"
7592   "t%C0\t%%xcc, %1"
7593   [(set_attr "type" "trap")])
7596 ;; TLS support instructions.
7598 (define_insn "tgd_hi22"
7599   [(set (match_operand:SI 0 "register_operand" "=r")
7600         (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
7601                             UNSPEC_TLSGD)))]
7602   "TARGET_TLS"
7603   "sethi\\t%%tgd_hi22(%a1), %0")
7605 (define_insn "tgd_lo10"
7606   [(set (match_operand:SI 0 "register_operand" "=r")
7607         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7608                    (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
7609                               UNSPEC_TLSGD)))]
7610   "TARGET_TLS"
7611   "add\\t%1, %%tgd_lo10(%a2), %0")
7613 (define_insn "tgd_add32"
7614   [(set (match_operand:SI 0 "register_operand" "=r")
7615         (plus:SI (match_operand:SI 1 "register_operand" "r")
7616                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7617                              (match_operand 3 "tgd_symbolic_operand" "")]
7618                             UNSPEC_TLSGD)))]
7619   "TARGET_TLS && TARGET_ARCH32"
7620   "add\\t%1, %2, %0, %%tgd_add(%a3)")
7622 (define_insn "tgd_add64"
7623   [(set (match_operand:DI 0 "register_operand" "=r")
7624         (plus:DI (match_operand:DI 1 "register_operand" "r")
7625                  (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7626                              (match_operand 3 "tgd_symbolic_operand" "")]
7627                             UNSPEC_TLSGD)))]
7628   "TARGET_TLS && TARGET_ARCH64"
7629   "add\\t%1, %2, %0, %%tgd_add(%a3)")
7631 (define_insn "tgd_call32"
7632   [(set (match_operand 0 "register_operand" "=r")
7633         (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
7634                                   (match_operand 2 "tgd_symbolic_operand" "")]
7635                                  UNSPEC_TLSGD))
7636               (match_operand 3 "" "")))
7637    (clobber (reg:SI 15))]
7638   "TARGET_TLS && TARGET_ARCH32"
7639   "call\t%a1, %%tgd_call(%a2)%#"
7640   [(set_attr "type" "call")])
7642 (define_insn "tgd_call64"
7643   [(set (match_operand 0 "register_operand" "=r")
7644         (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
7645                                   (match_operand 2 "tgd_symbolic_operand" "")]
7646                                  UNSPEC_TLSGD))
7647               (match_operand 3 "" "")))
7648    (clobber (reg:DI 15))]
7649   "TARGET_TLS && TARGET_ARCH64"
7650   "call\t%a1, %%tgd_call(%a2)%#"
7651   [(set_attr "type" "call")])
7653 (define_insn "tldm_hi22"
7654   [(set (match_operand:SI 0 "register_operand" "=r")
7655         (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7656   "TARGET_TLS"
7657   "sethi\\t%%tldm_hi22(%&), %0")
7659 (define_insn "tldm_lo10"
7660   [(set (match_operand:SI 0 "register_operand" "=r")
7661         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7662                     (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7663   "TARGET_TLS"
7664   "add\\t%1, %%tldm_lo10(%&), %0")
7666 (define_insn "tldm_add32"
7667   [(set (match_operand:SI 0 "register_operand" "=r")
7668         (plus:SI (match_operand:SI 1 "register_operand" "r")
7669                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
7670                             UNSPEC_TLSLDM)))]
7671   "TARGET_TLS && TARGET_ARCH32"
7672   "add\\t%1, %2, %0, %%tldm_add(%&)")
7674 (define_insn "tldm_add64"
7675   [(set (match_operand:DI 0 "register_operand" "=r")
7676         (plus:DI (match_operand:DI 1 "register_operand" "r")
7677                  (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
7678                             UNSPEC_TLSLDM)))]
7679   "TARGET_TLS && TARGET_ARCH64"
7680   "add\\t%1, %2, %0, %%tldm_add(%&)")
7682 (define_insn "tldm_call32"
7683   [(set (match_operand 0 "register_operand" "=r")
7684         (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
7685                                  UNSPEC_TLSLDM))
7686               (match_operand 2 "" "")))
7687    (clobber (reg:SI 15))]
7688   "TARGET_TLS && TARGET_ARCH32"
7689   "call\t%a1, %%tldm_call(%&)%#"
7690   [(set_attr "type" "call")])
7692 (define_insn "tldm_call64"
7693   [(set (match_operand 0 "register_operand" "=r")
7694         (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
7695                                  UNSPEC_TLSLDM))
7696               (match_operand 2 "" "")))
7697    (clobber (reg:DI 15))]
7698   "TARGET_TLS && TARGET_ARCH64"
7699   "call\t%a1, %%tldm_call(%&)%#"
7700   [(set_attr "type" "call")])
7702 (define_insn "tldo_hix22"
7703   [(set (match_operand:SI 0 "register_operand" "=r")
7704         (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
7705                             UNSPEC_TLSLDO)))]
7706   "TARGET_TLS"
7707   "sethi\\t%%tldo_hix22(%a1), %0")
7709 (define_insn "tldo_lox10"
7710   [(set (match_operand:SI 0 "register_operand" "=r")
7711         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7712                    (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
7713                               UNSPEC_TLSLDO)))]
7714   "TARGET_TLS"
7715   "xor\\t%1, %%tldo_lox10(%a2), %0")
7717 (define_insn "tldo_add32"
7718   [(set (match_operand:SI 0 "register_operand" "=r")
7719         (plus:SI (match_operand:SI 1 "register_operand" "r")
7720                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7721                              (match_operand 3 "tld_symbolic_operand" "")]
7722                             UNSPEC_TLSLDO)))]
7723   "TARGET_TLS && TARGET_ARCH32"
7724   "add\\t%1, %2, %0, %%tldo_add(%a3)")
7726 (define_insn "tldo_add64"
7727   [(set (match_operand:DI 0 "register_operand" "=r")
7728         (plus:DI (match_operand:DI 1 "register_operand" "r")
7729                  (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7730                              (match_operand 3 "tld_symbolic_operand" "")]
7731                             UNSPEC_TLSLDO)))]
7732   "TARGET_TLS && TARGET_ARCH64"
7733   "add\\t%1, %2, %0, %%tldo_add(%a3)")
7735 (define_insn "tie_hi22"
7736   [(set (match_operand:SI 0 "register_operand" "=r")
7737         (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
7738                             UNSPEC_TLSIE)))]
7739   "TARGET_TLS"
7740   "sethi\\t%%tie_hi22(%a1), %0")
7742 (define_insn "tie_lo10"
7743   [(set (match_operand:SI 0 "register_operand" "=r")
7744         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7745                    (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
7746                               UNSPEC_TLSIE)))]
7747   "TARGET_TLS"
7748   "add\\t%1, %%tie_lo10(%a2), %0")
7750 (define_insn "tie_ld32"
7751   [(set (match_operand:SI 0 "register_operand" "=r")
7752         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
7753                     (match_operand:SI 2 "register_operand" "r")
7754                     (match_operand 3 "tie_symbolic_operand" "")]
7755                    UNSPEC_TLSIE))]
7756   "TARGET_TLS && TARGET_ARCH32"
7757   "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
7758   [(set_attr "type" "load")])
7760 (define_insn "tie_ld64"
7761   [(set (match_operand:DI 0 "register_operand" "=r")
7762         (unspec:DI [(match_operand:DI 1 "register_operand" "r")
7763                     (match_operand:SI 2 "register_operand" "r")
7764                     (match_operand 3 "tie_symbolic_operand" "")]
7765                    UNSPEC_TLSIE))]
7766   "TARGET_TLS && TARGET_ARCH64"
7767   "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
7768   [(set_attr "type" "load")])
7770 (define_insn "tie_add32"
7771   [(set (match_operand:SI 0 "register_operand" "=r")
7772         (plus:SI (match_operand:SI 1 "register_operand" "r")
7773                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7774                              (match_operand 3 "tie_symbolic_operand" "")]
7775                             UNSPEC_TLSIE)))]
7776   "TARGET_SUN_TLS && TARGET_ARCH32"
7777   "add\\t%1, %2, %0, %%tie_add(%a3)")
7779 (define_insn "tie_add64"
7780   [(set (match_operand:DI 0 "register_operand" "=r")
7781         (plus:DI (match_operand:DI 1 "register_operand" "r")
7782                  (unspec:DI [(match_operand:DI 2 "register_operand" "r")
7783                              (match_operand 3 "tie_symbolic_operand" "")]
7784                             UNSPEC_TLSIE)))]
7785   "TARGET_SUN_TLS && TARGET_ARCH64"
7786   "add\\t%1, %2, %0, %%tie_add(%a3)")
7788 (define_insn "tle_hix22_sp32"
7789   [(set (match_operand:SI 0 "register_operand" "=r")
7790         (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
7791                             UNSPEC_TLSLE)))]
7792   "TARGET_TLS && TARGET_ARCH32"
7793   "sethi\\t%%tle_hix22(%a1), %0")
7795 (define_insn "tle_lox10_sp32"
7796   [(set (match_operand:SI 0 "register_operand" "=r")
7797         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7798                    (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
7799                               UNSPEC_TLSLE)))]
7800   "TARGET_TLS && TARGET_ARCH32"
7801   "xor\\t%1, %%tle_lox10(%a2), %0")
7803 (define_insn "tle_hix22_sp64"
7804   [(set (match_operand:DI 0 "register_operand" "=r")
7805         (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
7806                             UNSPEC_TLSLE)))]
7807   "TARGET_TLS && TARGET_ARCH64"
7808   "sethi\\t%%tle_hix22(%a1), %0")
7810 (define_insn "tle_lox10_sp64"
7811   [(set (match_operand:DI 0 "register_operand" "=r")
7812         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
7813                    (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
7814                               UNSPEC_TLSLE)))]
7815   "TARGET_TLS && TARGET_ARCH64"
7816   "xor\\t%1, %%tle_lox10(%a2), %0")
7818 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
7819 (define_insn "*tldo_ldub_sp32"
7820   [(set (match_operand:QI 0 "register_operand" "=r")
7821         (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7822                                      (match_operand 3 "tld_symbolic_operand" "")]
7823                                     UNSPEC_TLSLDO)
7824                          (match_operand:SI 1 "register_operand" "r"))))]
7825   "TARGET_TLS && TARGET_ARCH32"
7826   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7827   [(set_attr "type" "load")
7828    (set_attr "us3load_type" "3cycle")])
7830 (define_insn "*tldo_ldub1_sp32"
7831   [(set (match_operand:HI 0 "register_operand" "=r")
7832         (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7833                                                      (match_operand 3 "tld_symbolic_operand" "")]
7834                                                     UNSPEC_TLSLDO)
7835                                          (match_operand:SI 1 "register_operand" "r")))))]
7836   "TARGET_TLS && TARGET_ARCH32"
7837   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7838   [(set_attr "type" "load")
7839    (set_attr "us3load_type" "3cycle")])
7841 (define_insn "*tldo_ldub2_sp32"
7842   [(set (match_operand:SI 0 "register_operand" "=r")
7843         (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7844                                                      (match_operand 3 "tld_symbolic_operand" "")]
7845                                                     UNSPEC_TLSLDO)
7846                                          (match_operand:SI 1 "register_operand" "r")))))]
7847   "TARGET_TLS && TARGET_ARCH32"
7848   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7849   [(set_attr "type" "load")
7850    (set_attr "us3load_type" "3cycle")])
7852 (define_insn "*tldo_ldsb1_sp32"
7853   [(set (match_operand:HI 0 "register_operand" "=r")
7854         (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7855                                                      (match_operand 3 "tld_symbolic_operand" "")]
7856                                                     UNSPEC_TLSLDO)
7857                                          (match_operand:SI 1 "register_operand" "r")))))]
7858   "TARGET_TLS && TARGET_ARCH32"
7859   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7860   [(set_attr "type" "sload")
7861    (set_attr "us3load_type" "3cycle")])
7863 (define_insn "*tldo_ldsb2_sp32"
7864   [(set (match_operand:SI 0 "register_operand" "=r")
7865         (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7866                                                      (match_operand 3 "tld_symbolic_operand" "")]
7867                                                     UNSPEC_TLSLDO)
7868                                          (match_operand:SI 1 "register_operand" "r")))))]
7869   "TARGET_TLS && TARGET_ARCH32"
7870   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7871   [(set_attr "type" "sload")
7872    (set_attr "us3load_type" "3cycle")])
7874 (define_insn "*tldo_ldub_sp64"
7875   [(set (match_operand:QI 0 "register_operand" "=r")
7876         (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7877                                      (match_operand 3 "tld_symbolic_operand" "")]
7878                                     UNSPEC_TLSLDO)
7879                          (match_operand:DI 1 "register_operand" "r"))))]
7880   "TARGET_TLS && TARGET_ARCH64"
7881   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7882   [(set_attr "type" "load")
7883    (set_attr "us3load_type" "3cycle")])
7885 (define_insn "*tldo_ldub1_sp64"
7886   [(set (match_operand:HI 0 "register_operand" "=r")
7887         (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7888                                                      (match_operand 3 "tld_symbolic_operand" "")]
7889                                                     UNSPEC_TLSLDO)
7890                                          (match_operand:DI 1 "register_operand" "r")))))]
7891   "TARGET_TLS && TARGET_ARCH64"
7892   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7893   [(set_attr "type" "load")
7894    (set_attr "us3load_type" "3cycle")])
7896 (define_insn "*tldo_ldub2_sp64"
7897   [(set (match_operand:SI 0 "register_operand" "=r")
7898         (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7899                                                      (match_operand 3 "tld_symbolic_operand" "")]
7900                                                     UNSPEC_TLSLDO)
7901                                          (match_operand:DI 1 "register_operand" "r")))))]
7902   "TARGET_TLS && TARGET_ARCH64"
7903   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7904   [(set_attr "type" "load")
7905    (set_attr "us3load_type" "3cycle")])
7907 (define_insn "*tldo_ldub3_sp64"
7908   [(set (match_operand:DI 0 "register_operand" "=r")
7909         (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7910                                                      (match_operand 3 "tld_symbolic_operand" "")]
7911                                                     UNSPEC_TLSLDO)
7912                                          (match_operand:DI 1 "register_operand" "r")))))]
7913   "TARGET_TLS && TARGET_ARCH64"
7914   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7915   [(set_attr "type" "load")
7916    (set_attr "us3load_type" "3cycle")])
7918 (define_insn "*tldo_ldsb1_sp64"
7919   [(set (match_operand:HI 0 "register_operand" "=r")
7920         (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7921                                                      (match_operand 3 "tld_symbolic_operand" "")]
7922                                                     UNSPEC_TLSLDO)
7923                                          (match_operand:DI 1 "register_operand" "r")))))]
7924   "TARGET_TLS && TARGET_ARCH64"
7925   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7926   [(set_attr "type" "sload")
7927    (set_attr "us3load_type" "3cycle")])
7929 (define_insn "*tldo_ldsb2_sp64"
7930   [(set (match_operand:SI 0 "register_operand" "=r")
7931         (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7932                                                      (match_operand 3 "tld_symbolic_operand" "")]
7933                                                     UNSPEC_TLSLDO)
7934                                          (match_operand:DI 1 "register_operand" "r")))))]
7935   "TARGET_TLS && TARGET_ARCH64"
7936   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7937   [(set_attr "type" "sload")
7938    (set_attr "us3load_type" "3cycle")])
7940 (define_insn "*tldo_ldsb3_sp64"
7941   [(set (match_operand:DI 0 "register_operand" "=r")
7942         (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7943                                                      (match_operand 3 "tld_symbolic_operand" "")]
7944                                                     UNSPEC_TLSLDO)
7945                                          (match_operand:DI 1 "register_operand" "r")))))]
7946   "TARGET_TLS && TARGET_ARCH64"
7947   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7948   [(set_attr "type" "sload")
7949    (set_attr "us3load_type" "3cycle")])
7951 (define_insn "*tldo_lduh_sp32"
7952   [(set (match_operand:HI 0 "register_operand" "=r")
7953         (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7954                                      (match_operand 3 "tld_symbolic_operand" "")]
7955                                     UNSPEC_TLSLDO)
7956                          (match_operand:SI 1 "register_operand" "r"))))]
7957   "TARGET_TLS && TARGET_ARCH32"
7958   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7959   [(set_attr "type" "load")
7960    (set_attr "us3load_type" "3cycle")])
7962 (define_insn "*tldo_lduh1_sp32"
7963   [(set (match_operand:SI 0 "register_operand" "=r")
7964         (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7965                                                      (match_operand 3 "tld_symbolic_operand" "")]
7966                                                     UNSPEC_TLSLDO)
7967                                          (match_operand:SI 1 "register_operand" "r")))))]
7968   "TARGET_TLS && TARGET_ARCH32"
7969   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7970   [(set_attr "type" "load")
7971    (set_attr "us3load_type" "3cycle")])
7973 (define_insn "*tldo_ldsh1_sp32"
7974   [(set (match_operand:SI 0 "register_operand" "=r")
7975         (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7976                                                      (match_operand 3 "tld_symbolic_operand" "")]
7977                                                     UNSPEC_TLSLDO)
7978                                          (match_operand:SI 1 "register_operand" "r")))))]
7979   "TARGET_TLS && TARGET_ARCH32"
7980   "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7981   [(set_attr "type" "sload")
7982    (set_attr "us3load_type" "3cycle")])
7984 (define_insn "*tldo_lduh_sp64"
7985   [(set (match_operand:HI 0 "register_operand" "=r")
7986         (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7987                                      (match_operand 3 "tld_symbolic_operand" "")]
7988                                     UNSPEC_TLSLDO)
7989                          (match_operand:DI 1 "register_operand" "r"))))]
7990   "TARGET_TLS && TARGET_ARCH64"
7991   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7992   [(set_attr "type" "load")
7993    (set_attr "us3load_type" "3cycle")])
7995 (define_insn "*tldo_lduh1_sp64"
7996   [(set (match_operand:SI 0 "register_operand" "=r")
7997         (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7998                                                      (match_operand 3 "tld_symbolic_operand" "")]
7999                                                     UNSPEC_TLSLDO)
8000                                          (match_operand:DI 1 "register_operand" "r")))))]
8001   "TARGET_TLS && TARGET_ARCH64"
8002   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8003   [(set_attr "type" "load")
8004    (set_attr "us3load_type" "3cycle")])
8006 (define_insn "*tldo_lduh2_sp64"
8007   [(set (match_operand:DI 0 "register_operand" "=r")
8008         (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8009                                                      (match_operand 3 "tld_symbolic_operand" "")]
8010                                                     UNSPEC_TLSLDO)
8011                                          (match_operand:DI 1 "register_operand" "r")))))]
8012   "TARGET_TLS && TARGET_ARCH64"
8013   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8014   [(set_attr "type" "load")
8015    (set_attr "us3load_type" "3cycle")])
8017 (define_insn "*tldo_ldsh1_sp64"
8018   [(set (match_operand:SI 0 "register_operand" "=r")
8019         (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8020                                                      (match_operand 3 "tld_symbolic_operand" "")]
8021                                                     UNSPEC_TLSLDO)
8022                                          (match_operand:DI 1 "register_operand" "r")))))]
8023   "TARGET_TLS && TARGET_ARCH64"
8024   "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8025   [(set_attr "type" "sload")
8026    (set_attr "us3load_type" "3cycle")])
8028 (define_insn "*tldo_ldsh2_sp64"
8029   [(set (match_operand:DI 0 "register_operand" "=r")
8030         (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8031                                                      (match_operand 3 "tld_symbolic_operand" "")]
8032                                                     UNSPEC_TLSLDO)
8033                                          (match_operand:DI 1 "register_operand" "r")))))]
8034   "TARGET_TLS && TARGET_ARCH64"
8035   "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8036   [(set_attr "type" "sload")
8037    (set_attr "us3load_type" "3cycle")])
8039 (define_insn "*tldo_lduw_sp32"
8040   [(set (match_operand:SI 0 "register_operand" "=r")
8041         (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8042                                      (match_operand 3 "tld_symbolic_operand" "")]
8043                                     UNSPEC_TLSLDO)
8044                          (match_operand:SI 1 "register_operand" "r"))))]
8045   "TARGET_TLS && TARGET_ARCH32"
8046   "ld\t[%1 + %2], %0, %%tldo_add(%3)"
8047   [(set_attr "type" "load")])
8049 (define_insn "*tldo_lduw_sp64"
8050   [(set (match_operand:SI 0 "register_operand" "=r")
8051         (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8052                                      (match_operand 3 "tld_symbolic_operand" "")]
8053                                     UNSPEC_TLSLDO)
8054                          (match_operand:DI 1 "register_operand" "r"))))]
8055   "TARGET_TLS && TARGET_ARCH64"
8056   "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8057   [(set_attr "type" "load")])
8059 (define_insn "*tldo_lduw1_sp64"
8060   [(set (match_operand:DI 0 "register_operand" "=r")
8061         (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8062                                                      (match_operand 3 "tld_symbolic_operand" "")]
8063                                                     UNSPEC_TLSLDO)
8064                                          (match_operand:DI 1 "register_operand" "r")))))]
8065   "TARGET_TLS && TARGET_ARCH64"
8066   "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8067   [(set_attr "type" "load")])
8069 (define_insn "*tldo_ldsw1_sp64"
8070   [(set (match_operand:DI 0 "register_operand" "=r")
8071         (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8072                                                      (match_operand 3 "tld_symbolic_operand" "")]
8073                                                     UNSPEC_TLSLDO)
8074                                          (match_operand:DI 1 "register_operand" "r")))))]
8075   "TARGET_TLS && TARGET_ARCH64"
8076   "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
8077   [(set_attr "type" "sload")
8078    (set_attr "us3load_type" "3cycle")])
8080 (define_insn "*tldo_ldx_sp64"
8081   [(set (match_operand:DI 0 "register_operand" "=r")
8082         (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8083                                      (match_operand 3 "tld_symbolic_operand" "")]
8084                                     UNSPEC_TLSLDO)
8085                          (match_operand:DI 1 "register_operand" "r"))))]
8086   "TARGET_TLS && TARGET_ARCH64"
8087   "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
8088   [(set_attr "type" "load")])
8090 (define_insn "*tldo_stb_sp32"
8091   [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8092                                      (match_operand 3 "tld_symbolic_operand" "")]
8093                                     UNSPEC_TLSLDO)
8094                          (match_operand:SI 1 "register_operand" "r")))
8095         (match_operand:QI 0 "register_operand" "=r"))]
8096   "TARGET_TLS && TARGET_ARCH32"
8097   "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8098   [(set_attr "type" "store")])
8100 (define_insn "*tldo_stb_sp64"
8101   [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8102                                      (match_operand 3 "tld_symbolic_operand" "")]
8103                                     UNSPEC_TLSLDO)
8104                          (match_operand:DI 1 "register_operand" "r")))
8105         (match_operand:QI 0 "register_operand" "=r"))]
8106   "TARGET_TLS && TARGET_ARCH64"
8107   "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8108   [(set_attr "type" "store")])
8110 (define_insn "*tldo_sth_sp32"
8111   [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8112                                      (match_operand 3 "tld_symbolic_operand" "")]
8113                                     UNSPEC_TLSLDO)
8114                          (match_operand:SI 1 "register_operand" "r")))
8115         (match_operand:HI 0 "register_operand" "=r"))]
8116   "TARGET_TLS && TARGET_ARCH32"
8117   "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8118   [(set_attr "type" "store")])
8120 (define_insn "*tldo_sth_sp64"
8121   [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8122                                      (match_operand 3 "tld_symbolic_operand" "")]
8123                                     UNSPEC_TLSLDO)
8124                          (match_operand:DI 1 "register_operand" "r")))
8125         (match_operand:HI 0 "register_operand" "=r"))]
8126   "TARGET_TLS && TARGET_ARCH64"
8127   "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8128   [(set_attr "type" "store")])
8130 (define_insn "*tldo_stw_sp32"
8131   [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8132                                      (match_operand 3 "tld_symbolic_operand" "")]
8133                                     UNSPEC_TLSLDO)
8134                          (match_operand:SI 1 "register_operand" "r")))
8135         (match_operand:SI 0 "register_operand" "=r"))]
8136   "TARGET_TLS && TARGET_ARCH32"
8137   "st\t%0, [%1 + %2], %%tldo_add(%3)"
8138   [(set_attr "type" "store")])
8140 (define_insn "*tldo_stw_sp64"
8141   [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8142                                      (match_operand 3 "tld_symbolic_operand" "")]
8143                                     UNSPEC_TLSLDO)
8144                          (match_operand:DI 1 "register_operand" "r")))
8145         (match_operand:SI 0 "register_operand" "=r"))]
8146   "TARGET_TLS && TARGET_ARCH64"
8147   "stw\t%0, [%1 + %2], %%tldo_add(%3)"
8148   [(set_attr "type" "store")])
8150 (define_insn "*tldo_stx_sp64"
8151   [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8152                                      (match_operand 3 "tld_symbolic_operand" "")]
8153                                     UNSPEC_TLSLDO)
8154                          (match_operand:DI 1 "register_operand" "r")))
8155         (match_operand:DI 0 "register_operand" "=r"))]
8156   "TARGET_TLS && TARGET_ARCH64"
8157   "stx\t%0, [%1 + %2], %%tldo_add(%3)"
8158   [(set_attr "type" "store")])
8161 ;; Stack protector instructions.
8163 (define_expand "stack_protect_set"
8164   [(match_operand 0 "memory_operand" "")
8165    (match_operand 1 "memory_operand" "")]
8166   ""
8168 #ifdef TARGET_THREAD_SSP_OFFSET
8169   rtx tlsreg = gen_rtx_REG (Pmode, 7);
8170   rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
8171   operands[1] = gen_rtx_MEM (Pmode, addr);
8172 #endif
8173   if (TARGET_ARCH64)
8174     emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
8175   else
8176     emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
8177   DONE;
8180 (define_insn "stack_protect_setsi"
8181   [(set (match_operand:SI 0 "memory_operand" "=m")
8182         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
8183    (set (match_scratch:SI 2 "=&r") (const_int 0))]
8184   "TARGET_ARCH32"
8185   "ld\t%1, %2\;st\t%2, %0\;mov\t0, %2"
8186   [(set_attr "type" "multi")
8187    (set_attr "length" "3")])
8189 (define_insn "stack_protect_setdi"
8190   [(set (match_operand:DI 0 "memory_operand" "=m")
8191         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
8192    (set (match_scratch:DI 2 "=&r") (const_int 0))]
8193   "TARGET_ARCH64"
8194   "ldx\t%1, %2\;stx\t%2, %0\;mov\t0, %2"
8195   [(set_attr "type" "multi")
8196    (set_attr "length" "3")])
8198 (define_expand "stack_protect_test"
8199   [(match_operand 0 "memory_operand" "")
8200    (match_operand 1 "memory_operand" "")
8201    (match_operand 2 "" "")]
8202   ""
8204 #ifdef TARGET_THREAD_SSP_OFFSET
8205   rtx tlsreg = gen_rtx_REG (Pmode, 7);
8206   rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
8207   operands[1] = gen_rtx_MEM (Pmode, addr);
8208 #endif
8209   if (TARGET_ARCH64)
8210     {
8211       rtx temp = gen_reg_rtx (Pmode);
8212       emit_insn (gen_stack_protect_testdi (temp, operands[0], operands[1]));
8213       sparc_compare_op0 = temp;
8214       sparc_compare_op1 = const0_rtx;
8215     }
8216   else
8217     {
8218       emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
8219       sparc_compare_op0 = operands[0];
8220       sparc_compare_op1 = operands[1];
8221       sparc_compare_emitted = gen_rtx_REG (CCmode, SPARC_ICC_REG);
8222     }
8223   emit_jump_insn (gen_beq (operands[2]));
8224   DONE;
8227 (define_insn "stack_protect_testsi"
8228   [(set (reg:CC 100)
8229         (unspec:CC [(match_operand:SI 0 "memory_operand" "m")
8230                     (match_operand:SI 1 "memory_operand" "m")]
8231                    UNSPEC_SP_TEST))
8232    (set (match_scratch:SI 3 "=r") (const_int 0))
8233    (clobber (match_scratch:SI 2 "=&r"))]
8234   "TARGET_ARCH32"
8235   "ld\t%0, %2\;ld\t%1, %3\;xorcc\t%2, %3, %2\;mov\t0, %3"
8236   [(set_attr "type" "multi")
8237    (set_attr "length" "4")])
8239 (define_insn "stack_protect_testdi"
8240   [(set (match_operand:DI 0 "register_operand" "=&r")
8241         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
8242                     (match_operand:DI 2 "memory_operand" "m")]
8243                    UNSPEC_SP_TEST))
8244    (set (match_scratch:DI 3 "=r") (const_int 0))]
8245   "TARGET_ARCH64"
8246   "ldx\t%1, %0\;ldx\t%2, %3\;xor\t%0, %3, %0\;mov\t0, %3"
8247   [(set_attr "type" "multi")
8248    (set_attr "length" "4")])
8251 ;; Vector instructions.
8253 (define_insn "addv2si3"
8254   [(set (match_operand:V2SI 0 "register_operand" "=e")
8255         (plus:V2SI (match_operand:V2SI 1 "register_operand" "e")
8256                    (match_operand:V2SI 2 "register_operand" "e")))]
8257   "TARGET_VIS"
8258   "fpadd32\t%1, %2, %0"
8259   [(set_attr "type" "fga")
8260    (set_attr "fptype" "double")])
8262 (define_insn "addv4hi3"
8263   [(set (match_operand:V4HI 0 "register_operand" "=e")
8264          (plus:V4HI (match_operand:V4HI 1 "register_operand" "e")
8265                     (match_operand:V4HI 2 "register_operand" "e")))]
8266   "TARGET_VIS"
8267   "fpadd16\t%1, %2, %0"
8268   [(set_attr "type" "fga")
8269    (set_attr "fptype" "double")])
8271 ;; fpadd32s is emitted by the addsi3 pattern.
8273 (define_insn "addv2hi3"
8274   [(set (match_operand:V2HI 0 "register_operand" "=f")
8275         (plus:V2HI (match_operand:V2HI 1 "register_operand" "f")
8276                    (match_operand:V2HI 2 "register_operand" "f")))]
8277   "TARGET_VIS"
8278   "fpadd16s\t%1, %2, %0"
8279   [(set_attr "type" "fga")
8280    (set_attr "fptype" "single")])
8282 (define_insn "subv2si3"
8283   [(set (match_operand:V2SI 0 "register_operand" "=e")
8284         (minus:V2SI (match_operand:V2SI 1 "register_operand" "e")
8285                     (match_operand:V2SI 2 "register_operand" "e")))]
8286   "TARGET_VIS"
8287   "fpsub32\t%1, %2, %0"
8288   [(set_attr "type" "fga")
8289    (set_attr "fptype" "double")])
8291 (define_insn "subv4hi3"
8292   [(set (match_operand:V4HI 0 "register_operand" "=e")
8293         (minus:V4HI (match_operand:V4HI 1 "register_operand" "e")
8294                     (match_operand:V4HI 2 "register_operand" "e")))]
8295   "TARGET_VIS"
8296   "fpsub16\t%1, %2, %0"
8297   [(set_attr "type" "fga")
8298    (set_attr "fptype" "double")])
8300 ;; fpsub32s is emitted by the subsi3 pattern.
8302 (define_insn "subv2hi3"
8303   [(set (match_operand:V2HI 0 "register_operand" "=f")
8304         (minus:V2HI (match_operand:V2HI 1 "register_operand" "f")
8305                     (match_operand:V2HI 2 "register_operand" "f")))]
8306   "TARGET_VIS"
8307   "fpsub16s\t%1, %2, %0"
8308   [(set_attr "type" "fga")
8309    (set_attr "fptype" "single")])
8311 ;; All other logical instructions have integer equivalents so they
8312 ;; are defined together.
8314 ;; (ior (not (op1)) (not (op2))) is the canonical form of NAND.
8316 (define_insn "*nand<V64mode>_vis"
8317   [(set (match_operand:V64 0 "register_operand" "=e")
8318         (ior:V64 (not:V64 (match_operand:V64 1 "register_operand" "e"))
8319                  (not:V64 (match_operand:V64 2 "register_operand" "e"))))]
8320   "TARGET_VIS"
8321   "fnand\t%1, %2, %0"
8322   [(set_attr "type" "fga")
8323    (set_attr "fptype" "double")])
8325 (define_insn "*nand<V32mode>_vis"
8326   [(set (match_operand:V32 0 "register_operand" "=f")
8327          (ior:V32 (not:V32 (match_operand:V32 1 "register_operand" "f"))
8328                   (not:V32 (match_operand:V32 2 "register_operand" "f"))))]
8329   "TARGET_VIS"
8330   "fnands\t%1, %2, %0"
8331   [(set_attr "type" "fga")
8332    (set_attr "fptype" "single")])
8334 ;; Hard to generate VIS instructions.  We have builtins for these.
8336 (define_insn "fpack16_vis"
8337   [(set (match_operand:V4QI 0 "register_operand" "=f")
8338         (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e")]
8339                       UNSPEC_FPACK16))]
8340   "TARGET_VIS"
8341   "fpack16\t%1, %0"
8342   [(set_attr "type" "fga")
8343    (set_attr "fptype" "double")])
8345 (define_insn "fpackfix_vis"
8346   [(set (match_operand:V2HI 0 "register_operand" "=f")
8347         (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e")]
8348                       UNSPEC_FPACKFIX))]
8349   "TARGET_VIS"
8350   "fpackfix\t%1, %0"
8351   [(set_attr "type" "fga")
8352    (set_attr "fptype" "double")])
8354 (define_insn "fpack32_vis"
8355   [(set (match_operand:V8QI 0 "register_operand" "=e")
8356         (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e")
8357                       (match_operand:V8QI 2 "register_operand" "e")]
8358                      UNSPEC_FPACK32))]
8359   "TARGET_VIS"
8360   "fpack32\t%1, %2, %0"
8361   [(set_attr "type" "fga")
8362    (set_attr "fptype" "double")])
8364 (define_insn "fexpand_vis"
8365   [(set (match_operand:V4HI 0 "register_operand" "=e")
8366         (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")]
8367          UNSPEC_FEXPAND))]
8368  "TARGET_VIS"
8369  "fexpand\t%1, %0"
8370  [(set_attr "type" "fga")
8371   (set_attr "fptype" "double")])
8373 ;; It may be possible to describe this operation as (1 indexed):
8374 ;; (vec_select (vec_duplicate (vec_duplicate (vec_concat 1 2)))
8375 ;;  1,5,10,14,19,23,28,32)
8376 ;; Note that (vec_merge:V8QI [(V4QI) (V4QI)] (10101010 = 170) doesn't work
8377 ;; because vec_merge expects all the operands to be of the same type.
8378 (define_insn "fpmerge_vis"
8379   [(set (match_operand:V8QI 0 "register_operand" "=e")
8380         (unspec:V8QI [(match_operand:V4QI 1 "register_operand" "f")
8381                       (match_operand:V4QI 2 "register_operand" "f")]
8382          UNSPEC_FPMERGE))]
8383  "TARGET_VIS"
8384  "fpmerge\t%1, %2, %0"
8385  [(set_attr "type" "fga")
8386   (set_attr "fptype" "double")])
8388 ;; Partitioned multiply instructions
8389 (define_insn "fmul8x16_vis"
8390   [(set (match_operand:V4HI 0 "register_operand" "=e")
8391         (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
8392                    (match_operand:V4HI 2 "register_operand" "e")))]
8393   "TARGET_VIS"
8394   "fmul8x16\t%1, %2, %0"
8395   [(set_attr "type" "fpmul")
8396    (set_attr "fptype" "double")])
8398 ;; Only one of the following two insns can be a multiply.
8399 (define_insn "fmul8x16au_vis"
8400   [(set (match_operand:V4HI 0 "register_operand" "=e")
8401         (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
8402                    (match_operand:V2HI 2 "register_operand" "f")))]
8403   "TARGET_VIS"
8404   "fmul8x16au\t%1, %2, %0"
8405   [(set_attr "type" "fpmul")
8406    (set_attr "fptype" "double")])
8408 (define_insn "fmul8x16al_vis"
8409   [(set (match_operand:V4HI 0 "register_operand" "=e")
8410         (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8411                       (match_operand:V2HI 2 "register_operand" "f")]
8412          UNSPEC_MUL16AL))]
8413   "TARGET_VIS"
8414   "fmul8x16al\t%1, %2, %0"
8415   [(set_attr "type" "fpmul")
8416    (set_attr "fptype" "double")])
8418 ;; Only one of the following two insns can be a multiply.
8419 (define_insn "fmul8sux16_vis"
8420   [(set (match_operand:V4HI 0 "register_operand" "=e")
8421         (mult:V4HI (match_operand:V8QI 1 "register_operand" "e")
8422                    (match_operand:V4HI 2 "register_operand" "e")))]
8423   "TARGET_VIS"
8424   "fmul8sux16\t%1, %2, %0"
8425   [(set_attr "type" "fpmul")
8426    (set_attr "fptype" "double")])
8428 (define_insn "fmul8ulx16_vis"
8429   [(set (match_operand:V4HI 0 "register_operand" "=e")
8430         (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
8431                       (match_operand:V4HI 2 "register_operand" "e")]
8432          UNSPEC_MUL8UL))]
8433   "TARGET_VIS"
8434   "fmul8ulx16\t%1, %2, %0"
8435   [(set_attr "type" "fpmul")
8436    (set_attr "fptype" "double")])
8438 ;; Only one of the following two insns can be a multiply.
8439 (define_insn "fmuld8sux16_vis"
8440   [(set (match_operand:V2SI 0 "register_operand" "=e")
8441         (mult:V2SI (match_operand:V4QI 1 "register_operand" "f")
8442                    (match_operand:V2HI 2 "register_operand" "f")))]
8443   "TARGET_VIS"
8444   "fmuld8sux16\t%1, %2, %0"
8445   [(set_attr "type" "fpmul")
8446    (set_attr "fptype" "double")])
8448 (define_insn "fmuld8ulx16_vis"
8449   [(set (match_operand:V2SI 0 "register_operand" "=e")
8450         (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
8451                       (match_operand:V2HI 2 "register_operand" "f")]
8452          UNSPEC_MULDUL))]
8453   "TARGET_VIS"
8454   "fmuld8ulx16\t%1, %2, %0"
8455   [(set_attr "type" "fpmul")
8456    (set_attr "fptype" "double")])
8458 ;; Using faligndata only makes sense after an alignaddr since the choice of
8459 ;; bytes to take out of each operand is dependent on the results of the last
8460 ;; alignaddr.
8461 (define_insn "faligndata<V64I:mode>_vis"
8462   [(set (match_operand:V64I 0 "register_operand" "=e")
8463         (unspec:V64I [(match_operand:V64I 1 "register_operand" "e")
8464                       (match_operand:V64I 2 "register_operand" "e")]
8465          UNSPEC_ALIGNDATA))]
8466   "TARGET_VIS"
8467   "faligndata\t%1, %2, %0"
8468   [(set_attr "type" "fga")
8469    (set_attr "fptype" "double")])
8471 (define_insn "alignaddr<P:mode>_vis"
8472   [(set (match_operand:P 0 "register_operand" "=r")
8473         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8474                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
8475          UNSPEC_ALIGNADDR))]
8476   "TARGET_VIS"
8477   "alignaddr\t%r1, %r2, %0")
8479 (define_insn "pdist_vis"
8480   [(set (match_operand:DI 0 "register_operand" "=e")
8481         (unspec:DI [(match_operand:V8QI 1 "register_operand" "e")
8482                     (match_operand:V8QI 2 "register_operand" "e")
8483                     (match_operand:DI 3 "register_operand" "0")]
8484          UNSPEC_PDIST))]
8485   "TARGET_VIS"
8486   "pdist\t%1, %2, %0"
8487   [(set_attr "type" "fga")
8488    (set_attr "fptype" "double")])