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