OSDN Git Service

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