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