OSDN Git Service

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