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