OSDN Git Service

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