OSDN Git Service

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