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