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