OSDN Git Service

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