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