OSDN Git Service

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