c++: retval dtor on rethrow [PR112301]
[official-gcc.git] / gcc / config / sparc / sparc.md
blob94779c16c63d84f64203ad8f7c17df153aa167a7
1 ;; Machine description for SPARC.
2 ;; Copyright (C) 1987-2023 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.
7 ;; This file is part of GCC.
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.
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.
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/>.
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
40   UNSPEC_MEMBAR
41   UNSPEC_ATOMIC
43   UNSPEC_TLSGD
44   UNSPEC_TLSLDM
45   UNSPEC_TLSLDO
46   UNSPEC_TLSIE
47   UNSPEC_TLSLE
48   UNSPEC_TLSLD_BASE
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
71   UNSPEC_SP_SET
72   UNSPEC_SP_TEST
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
94   UNSPEC_ADDV
95   UNSPEC_SUBV
96   UNSPEC_NEGV
98   UNSPEC_DICTUNPACK
99   UNSPEC_FPCMPSHL
100   UNSPEC_FPUCMPSHL
101   UNSPEC_FPCMPDESHL
102   UNSPEC_FPCMPURSHL
105 (define_c_enum "unspecv" [
106   UNSPECV_BLOCKAGE
108   UNSPECV_SPECULATION_BARRIER
110   UNSPECV_PROBE_STACK_RANGE
112   UNSPECV_FLUSHW
113   UNSPECV_SAVEW
115   UNSPECV_FLUSH
117   UNSPECV_LDSTUB
118   UNSPECV_SWAP
119   UNSPECV_CAS
121   UNSPECV_LDFSR
122   UNSPECV_STFSR
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  ])
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])
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.
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")))
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"))))
265 (define_attr "cpu_feature" "none,fpu,fpunotv9,v9,vis,vis3,vis4,vis4b"
266   (const_string "none"))
268 (define_attr "lra" "disabled,enabled"
269   (const_string "enabled"))
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)))
283 ;; The SPARC instructions used by the backend are organized into a
284 ;; hierarchy using the insn attributes "type" and "subtype".
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.
292 ;; Please keep this list updated.  It is of great help for keeping the
293 ;; correctness and coherence of the DFA schedulers.
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
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"))
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"))
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)"))
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)"))
402 (define_attr "branch_type" "none,icc,fcc,reg"
403   (const_string "none"))
405 (define_attr "pic" "false,true"
406   (symbol_ref "(flag_pic != 0
407                 ? PIC_TRUE : PIC_FALSE)"))
409 (define_attr "calls_alloca" "false,true"
410   (symbol_ref "(cfun->calls_alloca != 0
411                 ? CALLS_ALLOCA_TRUE : CALLS_ALLOCA_FALSE)"))
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)"))
417 (define_attr "leaf_function" "false,true"
418   (symbol_ref "(crtl->uses_only_leaf_regs != 0
419                 ? LEAF_FUNCTION_TRUE : LEAF_FUNCTION_FALSE)"))
421 (define_attr "delayed_branch" "false,true"
422   (symbol_ref "(flag_delayed_branch != 0
423                 ? DELAYED_BRANCH_TRUE : DELAYED_BRANCH_FALSE)"))
425 (define_attr "flat" "false,true"
426   (symbol_ref "(TARGET_FLAT != 0
427                 ? FLAT_TRUE : FLAT_FALSE)"))
429 (define_attr "fix_ut699" "false,true"
430    (symbol_ref "(sparc_fix_ut699 != 0
431                  ? FIX_UT699_TRUE : FIX_UT699_FALSE)"))
433 (define_attr "fix_b2bst" "false,true"
434    (symbol_ref "(sparc_fix_b2bst != 0
435                  ? FIX_B2BST_TRUE : FIX_B2BST_FALSE)"))
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)"))
441 (define_attr "fix_gr712rc" "false,true"
442    (symbol_ref "(sparc_fix_gr712rc != 0
443                  ? FIX_GR712RC_TRUE : FIX_GR712RC_FALSE)"))
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)))
548 ;; FP precision.
549 (define_attr "fptype" "single,double"
550   (const_string "single"))
552 ;; FP precision specific to the UT699.
553 (define_attr "fptype_ut699" "none,single"
554   (const_string "none"))
556 ;; UltraSPARC-III integer load type.
557 (define_attr "us3load_type" "2cycle,3cycle"
558   (const_string "2cycle"))
560 (define_asm_attributes
561   [(set_attr "length" "2")
562    (set_attr "type" "multi")])
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)"))
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)"))
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)"))
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.
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.
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")))
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")))
617 (define_delay (eq_attr "type" "sibcall")
618   [(eq_attr "in_sibcall_delay" "true") (nil) (nil)])
620 (define_delay (eq_attr "type" "return")
621   [(eq_attr "in_return_delay" "true") (nil) (nil)])
623 (define_delay (ior (eq_attr "type" "call") (eq_attr "type" "uncond_branch"))
624   [(eq_attr "in_branch_delay" "true") (nil) (nil)])
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")])
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")])
636 ;; Include SPARC DFA schedulers
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")
653 ;; Operand and operator predicates and constraints
655 (include "predicates.md")
656 (include "constraints.md")
659 ;; Compare instructions.
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.
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")])
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")])
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")])
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")])
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"
703   if (TARGET_V9)
704     return "fcmpes\t%0, %1, %2";
705   return "fcmpes\t%1, %2";
707   [(set_attr "type" "fpcmp")])
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"
715   if (TARGET_V9)
716     return "fcmped\t%0, %1, %2";
717   return "fcmped\t%1, %2";
719   [(set_attr "type" "fpcmp")
720    (set_attr "fptype" "double")])
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"
728   if (TARGET_V9)
729     return "fcmpeq\t%0, %1, %2";
730   return "fcmpeq\t%1, %2";
732   [(set_attr "type" "fpcmp")])
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"
740   if (TARGET_V9)
741     return "fcmps\t%0, %1, %2";
742   return "fcmps\t%1, %2";
744   [(set_attr "type" "fpcmp")])
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"
752   if (TARGET_V9)
753     return "fcmpd\t%0, %1, %2";
754   return "fcmpd\t%1, %2";
756   [(set_attr "type" "fpcmp")
757    (set_attr "fptype" "double")])
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"
765   if (TARGET_V9)
766     return "fcmpq\t%0, %1, %2";
767   return "fcmpq\t%1, %2";
769   [(set_attr "type" "fpcmp")])
771 ;; Next come the scc insns.
773 ;; Note that the boolean result (operand 0) takes on DImode
774 ;; (not SImode) when TARGET_ARCH64.
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   ""
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;
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"
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;
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"
807   if (emit_scc_insn (operands)) DONE; else FAIL;
810 ;; The SNE and SEQ patterns are special because they can be done
811 ;; without any branching and do not involve a COMPARE.
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")])
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")])
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")])
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   "&& 1"
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")])
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")])
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   "&& 1"
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")])
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")])
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")])
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")])
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")]) 
947 ;; We can also do (x + (i == 0)) and related, so put them in.
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")])
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")])
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   "&& 1"
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")])
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   "&& 1"
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")])
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")])
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")])
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   "&& 1"
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")])
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   "&& 1"
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")])
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")])
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")])
1107 ;; We can also do GEU and LTU directly, but these operate after a compare.
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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   "")
1373 ;; These control RTL generation for conditional jump insns
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   "")
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   ""
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;
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"
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;
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"
1418   emit_conditional_branch_insn (operands);
1419   DONE;
1423 ;; Now match both normal and inverted jump.
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   ""
1434   return output_cbranch (operands[0], operands[1], 1, 0,
1435                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1436                          insn);
1438   [(set_attr "type" "branch")
1439    (set_attr "branch_type" "icc")])
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   ""
1450   return output_cbranch (operands[0], operands[1], 1, 1,
1451                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1452                          insn);
1454   [(set_attr "type" "branch")
1455    (set_attr "branch_type" "icc")])
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   ""
1467   return output_cbranch (operands[1], operands[2], 2, 0,
1468                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1469                          insn);
1471   [(set_attr "type" "branch")
1472    (set_attr "branch_type" "fcc")])
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   ""
1484   return output_cbranch (operands[1], operands[2], 2, 1,
1485                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1486                          insn);
1488   [(set_attr "type" "branch")
1489    (set_attr "branch_type" "fcc")])
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   ""
1501   return output_cbranch (operands[1], operands[2], 2, 0,
1502                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1503                          insn);
1505   [(set_attr "type" "branch")
1506    (set_attr "branch_type" "fcc")])
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   ""
1518   return output_cbranch (operands[1], operands[2], 2, 1,
1519                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1520                          insn);
1522   [(set_attr "type" "branch")
1523    (set_attr "branch_type" "fcc")])
1525 ;; SPARC V9-specific jump insns.  None of these are guaranteed to be
1526 ;; in the architecture.
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"
1537   return output_cbcond (operands[0], operands[3], insn);
1539   [(set_attr "type" "cbcond")])
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"
1550   return output_cbcond (operands[0], operands[3], insn);
1552   [(set_attr "type" "cbcond")])
1554 ;; There are no 32-bit brreg insns.
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"
1565   return output_v9branch (operands[0], operands[2], 1, 2, 0,
1566                           final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1567                           insn);
1569   [(set_attr "type" "branch")
1570    (set_attr "branch_type" "reg")])
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"
1581   return output_v9branch (operands[0], operands[2], 1, 2, 1,
1582                           final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1583                           insn);
1585   [(set_attr "type" "branch")
1586    (set_attr "branch_type" "reg")])
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).
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.
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])"
1606   return output_load_pcrel_sym (operands);
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)))])
1615 ;; Integer move instructions
1617 (define_expand "movqi"
1618   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1619         (match_operand:QI 1 "general_operand" ""))]
1620   ""
1622   if (sparc_expand_move (QImode, operands))
1623     DONE;
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,*")])
1639 (define_expand "movhi"
1640   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1641         (match_operand:HI 1 "general_operand" ""))]
1642   ""
1644   if (sparc_expand_move (HImode, operands))
1645     DONE;
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,*")])
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")
1670 (define_expand "movsi"
1671   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1672         (match_operand:SI 1 "general_operand" ""))]
1673   ""
1675   if (sparc_expand_move (SImode, operands))
1676     DONE;
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")])
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")
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")
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"
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
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)"
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
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)"
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
1755   [(set_attr "type" "load")
1756    (set_attr "subtype" "regular")])
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"
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;
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")
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")
1799 ;; Set up the PIC register for VxWorks.
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"
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);
1815 (define_expand "movdi"
1816   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1817         (match_operand:DI 1 "general_operand" ""))]
1818   ""
1820   if (sparc_expand_move (DImode, operands))
1821     DONE;
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:
1831 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
1832 ;;                       (const_int -5016)))
1833 ;;      (reg:DI 2 %g2))
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,
1866 visl")
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,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
1873 (define_insn "*movdi_insn_sp64"
1874   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r, m, r,*e,?*e,?*e,  m,b,b")
1875         (match_operand:DI 1 "input_operand"        "rI,N,m,rJ,*e, r, *e,  m,?*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")])
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"
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;
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")
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")
1937 ;; SPARC-v9 code model support insns.  See sparc_emit_set_symbolic_const64
1938 ;; in sparc.cc to see what is going on here... PIC stuff comes first.
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"
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
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)"
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
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)"
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
1980   [(set_attr "type" "load")
1981    (set_attr "subtype" "regular")])
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")
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")
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")
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")
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")
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")
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")
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")
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")
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")
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")
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")
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")
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")
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")
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")
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")
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"
2110   sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2111   DONE;
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"
2120   sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2121   DONE;
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))]
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]);
2142   emit_move_insn_1 (high_part, GEN_INT (high));
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));
2150   DONE;
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))]
2162   sparc_split_reg_reg (operands[0], operands[1], SImode);
2163   DONE;
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))]
2176   sparc_split_reg_mem (operands[0], operands[1], SImode);
2177   DONE;
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))]
2188   sparc_split_mem_reg (operands[0], operands[1], SImode);
2189   DONE;
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))]
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;
2207 (define_expand "movti"
2208   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2209         (match_operand:TI 1 "general_operand" ""))]
2210   "TARGET_ARCH64"
2212   if (sparc_expand_move (TImode, operands))
2213     DONE;
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.
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")])
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")])
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))]
2260   rtx set_dest = operands[0];
2261   rtx set_src = operands[1];
2262   rtx dest1, dest2;
2263   rtx src1, src2;
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);
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;
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))]
2291   rtx set_dest = operands[0];
2292   rtx dest1, dest2;
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     }
2308   emit_insn (gen_movdi (dest1, const0_rtx));
2309   emit_insn (gen_movdi (dest2, const0_rtx));
2310   DONE;
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))]
2322   rtx word0 = adjust_address (operands[1], DImode, 0);
2323   rtx word1 = adjust_address (operands[1], DImode, 8);
2324   rtx set_dest, dest1, dest2;
2326   set_dest = operands[0];
2328   dest1 = gen_highpart (DImode, set_dest);
2329   dest2 = gen_lowpart (DImode, set_dest);
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))
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;
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))]
2356   rtx set_src = operands[1];
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;
2366 ;; Floating point move instructions
2368 (define_expand "movsf"
2369   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2370         (match_operand:SF 1 "general_operand" ""))]
2371   ""
2373   if (sparc_expand_move (SFmode, operands))
2374     DONE;
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))"
2383   if (GET_CODE (operands[1]) == CONST_DOUBLE
2384       && (which_alternative == 3
2385           || which_alternative == 4
2386           || which_alternative == 5))
2387     {
2388       long i;
2390       REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (operands[1]), i);
2391       operands[1] = GEN_INT (i);
2392     }
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     }
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,*")])
2426 ;; The following 3 patterns build SFmode constants in integer registers.
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   ""
2434   long i;
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";
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   ""
2446   long i;
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";
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)))])
2460 (define_expand "movdf"
2461   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2462         (match_operand:DF 1 "general_operand" ""))]
2463   ""
2465   if (sparc_expand_move (DFmode, operands))
2466     DONE;
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,*,*,*,*,*")])
2502 (define_insn "*movdf_insn_sp64"
2503   [(set (match_operand:DF 0 "nonimmediate_operand" "=b,b,e,*r, e,  e,m, *r,*r,  m,*r")
2504         (match_operand:DF 1 "input_operand"         "G,C,e, e,*r,m#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,*,*,*,*")])
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))]
2536   operands[0] = gen_raw_REG (DImode, REGNO (operands[0]));
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]);
2550       gcc_assert (GET_CODE (hi) == CONST_INT);
2551       gcc_assert (GET_CODE (lo) == CONST_INT);
2553       emit_move_insn_1 (high_part, hi);
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;
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))]
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;
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))]
2597   sparc_split_reg_reg (operands[0], operands[1], SFmode);
2598   DONE;
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))]
2609   sparc_split_reg_mem (operands[0], operands[1], SFmode);
2610   DONE;
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))]
2621   sparc_split_mem_reg (operands[0], operands[1], SFmode);
2622   DONE;
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))]
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;
2640 (define_expand "movtf"
2641   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2642         (match_operand:TF 1 "general_operand" ""))]
2643   ""
2645   if (sparc_expand_move (TFmode, operands))
2646     DONE;
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,*,*")])
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,*,*")])
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")])
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))]
2699   rtx set_dest = operands[0];
2700   rtx set_src = operands[1];
2701   rtx dest1, dest2;
2702   rtx src1, src2;
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);
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;
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))]
2730   rtx set_dest = operands[0];
2731   rtx dest1, dest2;
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     }
2747   emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
2748   emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
2749   DONE;
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))]
2762   rtx word0 = adjust_address (operands[1], DFmode, 0);
2763   rtx word1 = adjust_address (operands[1], DFmode, 8);
2764   rtx set_dest, dest1, dest2;
2766   set_dest = operands[0];
2768   dest1 = gen_df_reg (set_dest, 0);
2769   dest2 = gen_df_reg (set_dest, 1);
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))
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;
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))]
2797   rtx set_src = operands[1];
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;
2807 ;; SPARC-V9 conditional move instructions
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.cc puts a constant in operand 2).
2815 ;; Our instruction patterns, on the other hand, canonicalize such that
2816 ;; operand 3 must be the set destination.
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)"
2825   if (!sparc_expand_conditional_move (<I:MODE>mode, operands))
2826     FAIL;
2827   DONE;
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"
2837   if (!sparc_expand_conditional_move (<F:MODE>mode, operands))
2838     FAIL;
2839   DONE;
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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))]
2946   rtx set_dest = operands[0];
2947   rtx set_srca = operands[3];
2948   rtx dest1, dest2;
2949   rtx srca1, srca2;
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);
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;
2972   [(set_attr "length" "2")])
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))]
2986   rtx set_dest = operands[0];
2987   rtx set_srca = operands[3];
2988   rtx dest1, dest2;
2989   rtx srca1, srca2;
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);
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;
3012   [(set_attr "length" "2")])
3015 ;; Zero-extension instructions
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.
3021 (define_expand "zero_extendhisi2"
3022   [(set (match_operand:SI 0 "register_operand" "")
3023         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
3024   ""
3026   rtx temp = gen_reg_rtx (SImode);
3027   rtx shift_16 = GEN_INT (16);
3028   int op1_subbyte = 0;
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     }
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;
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")])
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   "")
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")])
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   "")
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")])
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   "")
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")])
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"
3109   rtx temp = gen_reg_rtx (DImode);
3110   rtx shift_48 = GEN_INT (48);
3111   int op1_subbyte = 0;
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     }
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;
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")])
3136 ;; ??? Write truncdisi pattern using sra?
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   "")
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")])
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")])
3169 ;; Simplify comparisons of extended values.
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
3245 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
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")])
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")])
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")])
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")])
3284 ;; Sign-extension instructions
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.
3290 (define_expand "extendhisi2"
3291   [(set (match_operand:SI 0 "register_operand" "")
3292         (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
3293   ""
3295   rtx temp = gen_reg_rtx (SImode);
3296   rtx shift_16 = GEN_INT (16);
3297   int op1_subbyte = 0;
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     }
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;
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")])
3321 (define_expand "extendqihi2"
3322   [(set (match_operand:HI 0 "register_operand" "")
3323         (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
3324   ""
3326   rtx temp = gen_reg_rtx (SImode);
3327   rtx shift_24 = GEN_INT (24);
3328   int op1_subbyte = 0;
3329   int op0_subbyte = 0;
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;
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")])
3361 (define_expand "extendqisi2"
3362   [(set (match_operand:SI 0 "register_operand" "")
3363         (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
3364   ""
3366   rtx temp = gen_reg_rtx (SImode);
3367   rtx shift_24 = GEN_INT (24);
3368   int op1_subbyte = 0;
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     }
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;
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")])
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"
3397   rtx temp = gen_reg_rtx (DImode);
3398   rtx shift_56 = GEN_INT (56);
3399   int op1_subbyte = 0;
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     }
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;
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")])
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"
3428   rtx temp = gen_reg_rtx (DImode);
3429   rtx shift_48 = GEN_INT (48);
3430   int op1_subbyte = 0;
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     }
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;
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")])
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   "")
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")])
3473 ;; Special pattern for optimizing bit-field compares.  This is needed
3474 ;; because combine uses this as a canonical form.
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"
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";
3491   [(set_attr "type" "compare")])
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"
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";
3508   [(set_attr "type" "compare")])
3511 ;; Conversions between float, double and long double.
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")])
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;")
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")])
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;")
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")])
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")])
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;")
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")])
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;")
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")])
3583 ;; Conversion between fixed point and floating point.
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")])
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")])
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;")
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")])
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;")
3620 ;; Now the same for 64 bit sources.
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")])
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;")
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")])
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;")
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;")
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")])
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;")
3669 ;; Convert a float to an actual integer.
3670 ;; Truncation is performed as part of the conversion.
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")])
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")])
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;")
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")])
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;")
3708 ;; Now the same, for V9 targets
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")])
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;")
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")])
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;")
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;")
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")])
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;")
3758 ;; Integer addition/subtraction instructions.
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   ""
3766   if (TARGET_ARCH32)
3767     {
3768       emit_insn (gen_adddi3_sp32 (operands[0], operands[1], operands[2]));
3769       DONE;
3770     }
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.
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  ""
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     }
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.
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  ""
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     }
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))))]
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]);
3848   [(set_attr "length" "2")])
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))))])]
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]);
3886   [(set_attr "length" "2")])
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))))])]
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]);
3922   [(set_attr "length" "2")])
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")])
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")])
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")
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")
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.
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  "")
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.
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  "")
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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   ""
4177   if (TARGET_ARCH32)
4178     {
4179       emit_insn (gen_subdi3_sp32 (operands[0], operands[1], operands[2]));
4180       DONE;
4181     }
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.
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  ""
4198   if (operands[1] == const0_rtx)
4199     {
4200       emit_insn (gen_unegvdi3 (operands[0], operands[2], operands[3]));
4201       DONE;
4202     }
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     }
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.
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  ""
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     }
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))))]
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]);
4263   [(set_attr "length" "2")])
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)))])]
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]);
4302   [(set_attr "length" "2")])
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))))])]
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]);
4337   [(set_attr "length" "2")])
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")])
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")])
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")
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")
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.
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  ""
4407   if (operands[1] == const0_rtx)
4408     {
4409       emit_insn (gen_unegvsi3 (operands[0], operands[2], operands[3]));
4410       DONE;
4411     }
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.
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  "")
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
4576 ;; Integer multiply/divide instructions.
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.
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   "")
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")])
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")])
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"
4610   if (TARGET_V8PLUS)
4611     {
4612       emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
4613       DONE;
4614     }
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")])
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"
4634   return output_v8plus_mult (insn, operands, \"mulx\");
4636   [(set_attr "type" "multi")
4637    (set_attr "length" "9,8")])
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")])
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"
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     }
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")])
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")])
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"
4708   return TARGET_SPARCLET
4709          ? "smuld\t%1, %2, %L0"
4710          : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
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)))])
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")])
4727 ;; Extra pattern, because sign_extend of a constant isn't valid.
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"
4735   return TARGET_SPARCLET
4736          ? "smuld\t%1, %2, %L0"
4737          : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
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)))])
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")])
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"
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     }
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")])
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")])
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")])
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")])
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")])
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"
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     }
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")])
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"
4898   return TARGET_SPARCLET
4899          ? "umuld\t%1, %2, %L0"
4900          : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
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)))])
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")])
4917 ;; Extra pattern, because sign_extend of a constant isn't valid.
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"
4925   return TARGET_SPARCLET
4926          ? "umuld\t%1, %s2, %L0"
4927          : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
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)))])
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")])
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")])
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"
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     }
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")])
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")])
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")])
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")])
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"
5050   if (TARGET_ARCH32)
5051     {
5052       emit_insn (gen_umulxhi_v8plus (operands[0], operands[1], operands[2]));
5053       DONE;
5054     }
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")])
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"
5079   return output_v8plus_mult (insn, operands, \"umulxhi\");
5081   [(set_attr "type" "imul")
5082    (set_attr "length" "9,8")])
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"
5092   if (TARGET_ARCH32)
5093     {
5094       emit_insn (gen_xmulx_v8plus (operands[0], operands[1], operands[2]));
5095       DONE;
5096     }
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")])
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"
5119   return output_v8plus_mult (insn, operands, \"xmulx\");
5121   [(set_attr "type" "imul")
5122    (set_attr "length" "9,8")])
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"
5134   if (TARGET_ARCH32)
5135     {
5136       emit_insn (gen_xmulxhi_v8plus (operands[0], operands[1], operands[2]));
5137       DONE;
5138     }
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")])
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"
5165   return output_v8plus_mult (insn, operands, \"xmulxhi\");
5167   [(set_attr "type" "imul")
5168    (set_attr "length" "9,8")])
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"
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     }
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.
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"
5198   output_asm_insn ("sra\t%1, 31, %3", operands);
5199   output_asm_insn ("wr\t%3, 0, %%y", operands);
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     }
5222   [(set_attr "type" "multi")
5223    (set (attr "length")
5224         (if_then_else (eq_attr "isa" "v9")
5225                       (const_int 4) (const_int 6)))])
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")])
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")])
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"
5255   output_asm_insn ("sra\t%1, 31, %3", operands);
5256   output_asm_insn ("wr\t%3, 0, %%y", operands);
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";
5263   [(set_attr "type" "multi")
5264    (set (attr "length")
5265         (if_then_else (eq_attr "isa" "v9")
5266                       (const_int 3) (const_int 6)))])
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   "")
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.
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"
5285   output_asm_insn ("wr\t%%g0, 0, %%y", operands);
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     }
5313   [(set_attr "type" "multi")
5314    (set (attr "length")
5315         (if_then_else (eq_attr "isa" "v9")
5316                       (const_int 3) (const_int 5)))])
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")])
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")])
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"
5344   output_asm_insn ("wr\t%%g0, 0, %%y", operands);
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";
5351   [(set_attr "type" "multi")
5352    (set (attr "length")
5353         (if_then_else (eq_attr "isa" "v9")
5354                       (const_int 2) (const_int 5)))])
5357 ;; SPARClet multiply/accumulate insns
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")])
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")])
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")])
5391 ;; Boolean instructions.
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")
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")
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)))]
5416   operands[4] = GEN_INT (~INTVAL (operands[2]));
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")
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")
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")
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")
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)))]
5456   operands[4] = gen_int_mode (~INTVAL (operands[2]), SImode);
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")
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")
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")
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")
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))))]
5496   operands[4] = gen_int_mode (~INTVAL (operands[2]), SImode);
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)))]
5508   operands[4] = gen_int_mode (~INTVAL (operands[2]), SImode);
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")
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")
5525 ;; These correspond to the above in the case where we also (or only)
5526 ;; want to set the condition code.  
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
5664 ;; We cannot use the "neg" pseudo insn because the Sun assembler
5665 ;; does not know how to make it work for constants.
5667 (define_expand "negdi2"
5668   [(set (match_operand:DI 0 "register_operand" "=r")
5669         (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5670   ""
5672   if (TARGET_ARCH32)
5673     {
5674       emit_insn (gen_negdi2_sp32 (operands[0], operands[1]));
5675       DONE;
5676     }
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   ""
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     }
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   ""
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     }
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")])
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")])
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")])
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")
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")
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   "")
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)))]
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")
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")
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")])
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")])
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")])
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")])
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")])
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")])
6026 ;; Floating point arithmetic instructions.
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;")
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")])
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")])
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")])
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;")
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")])
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")])
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")])
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;")
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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;")
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")])
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   "")
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")])
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")])
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")])
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   "")
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")])
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))]
6284   rtx set_dest = operands[0];
6285   rtx set_src = operands[1];
6286   rtx dest1, dest2;
6287   rtx src1, src2;
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);
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;
6309   [(set_attr "length" "2")])
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   "")
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))]
6325   rtx set_dest = operands[0];
6326   rtx set_src = operands[1];
6327   rtx dest1, dest2;
6328   rtx src1, src2;
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);
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;
6350   [(set_attr "length" "2")])
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")])
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")])
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   "")
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")])
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))]
6388   rtx set_dest = operands[0];
6389   rtx set_src = operands[1];
6390   rtx dest1, dest2;
6391   rtx src1, src2;
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);
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;
6413   [(set_attr "length" "2")])
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   "")
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))]
6429   rtx set_dest = operands[0];
6430   rtx set_src = operands[1];
6431   rtx dest1, dest2;
6432   rtx src1, src2;
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);
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;
6454   [(set_attr "length" "2")])
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")])
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")])
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;")
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")])
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   "")
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")])
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")])
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")])
6515 ;; Arithmetic shift instructions.
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   ""
6523   if (GET_CODE (operands[2]) == CONST_INT)
6524     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6525   return "sll\t%1, %2, %0";
6527   [(set_attr "type" "shift")])
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"
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     }
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"
6550   if (GET_CODE (operands[2]) == CONST_INT)
6551     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6552   return "sllx\t%1, %2, %0";
6554   [(set_attr "type" "shift")])
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"
6563   return output_v8plus_shift (insn ,operands, \"sllx\");
6565   [(set_attr "type" "multi")
6566    (set_attr "length" "5,5,6")])
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")])
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")])
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   ""
6594   if (GET_CODE (operands[2]) == CONST_INT)
6595    operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6596   return "sra\t%1, %2, %0";
6598   [(set_attr "type" "shift")])
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"
6606   if (GET_CODE (operands[2]) == CONST_INT)
6607    operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6608   return "sra\t%1, %2, %0";
6610   [(set_attr "type" "shift")])
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"
6622   operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
6623   return "sra\t%1, %2, %0";
6625   [(set_attr "type" "shift")])
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"
6637   operands[2] = GEN_INT (32 - INTVAL (operands[2]));
6638   return "sra\t%1, %2, %0";
6640   [(set_attr "type" "shift")])
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"
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     }
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"
6663   if (GET_CODE (operands[2]) == CONST_INT)
6664     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6665   return "srax\t%1, %2, %0";
6667   [(set_attr "type" "shift")])
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"
6676   return output_v8plus_shift (insn, operands, \"srax\");
6678   [(set_attr "type" "multi")
6679    (set_attr "length" "5,5,6")])
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   ""
6687   if (GET_CODE (operands[2]) == CONST_INT)
6688     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6689   return "srl\t%1, %2, %0";
6691   [(set_attr "type" "shift")])
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"
6700   if (GET_CODE (operands[2]) == CONST_INT)
6701     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6702   return "srl\t%1, %2, %0";
6704   [(set_attr "type" "shift")])
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"
6716   if (GET_CODE (operands[2]) == CONST_INT)
6717     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6718   return "srl\t%1, %2, %0";
6720   [(set_attr "type" "shift")])
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"
6732   operands[2] = GEN_INT (32 - INTVAL (operands[2]));
6733   return "srl\t%1, %2, %0";
6735   [(set_attr "type" "shift")])
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"
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     }
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"
6758   if (GET_CODE (operands[2]) == CONST_INT)
6759     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6760   return "srlx\t%1, %2, %0";
6762   [(set_attr "type" "shift")])
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"
6771   return output_v8plus_shift (insn, operands, \"srlx\");
6773   [(set_attr "type" "multi")
6774    (set_attr "length" "5,5,6")])
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"
6783   operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6784   return "srax\t%1, %2, %0";
6786   [(set_attr "type" "shift")])
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"
6795   operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6796   return "srlx\t%1, %2, %0";
6798   [(set_attr "type" "shift")])
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"
6810   operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6812   return "srax\t%1, %2, %0";
6814   [(set_attr "type" "shift")])
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"
6826   operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6828   return "srlx\t%1, %2, %0";
6830   [(set_attr "type" "shift")])
6833 ;; Unconditional and other jump instructions.
6835 (define_expand "jump"
6836   [(set (pc) (label_ref (match_operand 0 "" "")))]
6837   "")
6839 (define_insn "*jump_ubranch"
6840   [(set (pc) (label_ref (match_operand 0 "" "")))]
6841   "!TARGET_CBCOND"
6843   return output_ubranch (operands[0], insn);
6845   [(set_attr "type" "uncond_branch")])
6847 (define_insn "*jump_cbcond"
6848   [(set (pc) (label_ref (match_operand 0 "" "")))]
6849   "TARGET_CBCOND"
6851   return output_ubranch (operands[0], insn);
6853   [(set_attr "type" "uncond_cbcond")])
6855 (define_expand "tablejump"
6856   [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
6857               (use (label_ref (match_operand 1 "" "")))])]
6858   ""
6860   gcc_assert (GET_MODE (operands[0]) == CASE_VECTOR_MODE);
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     }
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")])
6885 ;; Jump to subroutine instructions.
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   ""
6896   rtx fn_rtx;
6898   gcc_assert (MEM_P (operands[0]) && GET_MODE (operands[0]) == FUNCTION_MODE);
6900   gcc_assert (GET_CODE (operands[3]) == CONST_INT);
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. 
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?  */
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     }
6930   fn_rtx = operands[0];
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));
6949  finish_call:
6951   DONE;
6954 ;; We can't use the same pattern for these two insns, because then registers
6955 ;; in the address may not be properly reloaded.
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")])
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")])
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"
6985   operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6986   return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6988   [(set_attr "type" "call_no_delay_slot")
6989    (set_attr "length" "3")])
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"
7001   operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
7002   return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
7004   [(set_attr "type" "call_no_delay_slot")
7005    (set_attr "length" "3")])
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")])
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")])
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   ""
7043   rtx fn_rtx;
7044   rtvec vec;
7046   gcc_assert (MEM_P (operands[1]) && GET_MODE (operands[1]) == FUNCTION_MODE);
7048   fn_rtx = operands[1];
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)));
7055   sparc_emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec), XEXP (fn_rtx, 0));
7057   DONE;
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")])
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")])
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   ""
7087   rtx valreg1 = gen_rtx_REG (DImode, 8);
7088   rtx result = operands[1];
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));
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     }
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 ());
7109   DONE;
7113 ;;  Tail call instructions.
7115 (define_expand "sibcall"
7116   [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
7117               (return)])]
7118   ""
7119   "")
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   ""
7127   return output_sibcall (insn, operands[0]);
7129   [(set_attr "type" "sibcall")])
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   "")
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   ""
7145   return output_sibcall (insn, operands[1]);
7147   [(set_attr "type" "sibcall")])
7150 ;; Special instructions.
7152 (define_expand "prologue"
7153   [(const_int 0)]
7154   ""
7156   if (TARGET_FLAT)
7157     sparc_flat_expand_prologue ();
7158   else
7159     sparc_expand_prologue ();
7160   DONE;
7163 ;; The "register window save" insn is modelled as follows.  The dwarf2
7164 ;; information is manually added in emit_window_save.
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")])
7172 (define_expand "epilogue"
7173   [(return)]
7174   ""
7176   if (TARGET_FLAT)
7177     sparc_flat_expand_epilogue (false);
7178   else
7179     sparc_expand_epilogue (false);
7182 (define_expand "sibcall_epilogue"
7183   [(return)]
7184   ""
7186   if (TARGET_FLAT)
7187     sparc_flat_expand_epilogue (false);
7188   else
7189     sparc_expand_epilogue (false);
7190   DONE;
7193 (define_expand "eh_return"
7194   [(use (match_operand 0 "general_operand" ""))]
7195   ""
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;
7203 (define_insn_and_split "eh_return_internal"
7204   [(eh_return)]
7205   ""
7206   "#"
7207   "epilogue_completed"
7208   [(return)]
7210   if (TARGET_FLAT)
7211     sparc_flat_expand_epilogue (true);
7212   else
7213     sparc_expand_epilogue (true);
7216 (define_expand "return"
7217   [(return)]
7218   "sparc_can_use_return_insn_p ()"
7220   if (cfun->calls_alloca)
7221     emit_insn (gen_frame_blockage ());
7224 (define_insn "*return_internal"
7225   [(return)]
7226   ""
7228   return output_return (insn);
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)))])
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.
7254 (define_insn "blockage"
7255   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7256   ""
7257   ""
7258   [(set_attr "length" "0")])
7260 ;; Do not schedule instructions accessing memory before this point.
7262 (define_expand "frame_blockage"
7263   [(set (match_dup 0)
7264         (unspec:BLK [(match_dup 1)] UNSPEC_FRAME_BLOCKAGE))]
7265   ""
7267   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
7268   MEM_VOLATILE_P (operands[0]) = 1;
7269   operands[1] = stack_pointer_rtx;
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")])
7279 ;; We use membar #Sync for the speculation barrier on V9.
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")])
7287 (define_expand "probe_stack"
7288   [(set (match_operand 0 "memory_operand" "") (const_int 0))]
7289   ""
7291   operands[0]
7292     = adjust_address (operands[0], GET_MODE (operands[0]), SPARC_STACK_BIAS);
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   ""
7302   return output_probe_stack_range (operands[0], operands[2]);
7304   [(set_attr "type" "multi")])
7306 ;; Prepare to return any type including a structure value.
7308 (define_expand "untyped_return"
7309   [(match_operand:BLK 0 "memory_operand" "")
7310    (match_operand 1 "" "")]
7311   ""
7313   rtx valreg1 = gen_rtx_REG (DImode, 24);
7314   rtx result = operands[0];
7316   if (TARGET_ARCH32)
7317     {
7318       rtx rtnreg = gen_rtx_REG (SImode, RETURN_ADDR_REGNUM);
7319       rtx value = gen_reg_rtx (SImode);
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     }
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);
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     }
7343   /* Construct the return.  */
7344   expand_naked_return ();
7346   DONE;
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".
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"
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";
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)))])
7373 (define_insn "nop"
7374   [(const_int 0)]
7375   ""
7376   "nop")
7378 (define_expand "indirect_jump"
7379   [(set (pc) (match_operand 0 "address_operand" "p"))]
7380   ""
7381   "")
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")])
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   ""
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);
7400 (define_expand "restore_stack_nonlocal"
7401   [(set (match_operand 0 "register_operand" "")
7402         (match_operand 1 "memory_operand" ""))]
7403   ""
7405   operands[1] = adjust_address (operands[1], Pmode, 0);
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   ""
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));
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 ());
7426   emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
7427   emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
7429   r_label = copy_to_reg (r_label);
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);
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);
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);
7449   emit_indirect_jump (r_label);
7450   DONE;
7453 (define_expand "builtin_setjmp_receiver"
7454   [(label_ref (match_operand 0 "" ""))]
7455   "TARGET_VXWORKS_RTP && flag_pic"
7457   load_got_register ();
7458   DONE;
7461 ;; Special insn to flush register windows.
7463 (define_insn "flush_register_windows"
7464   [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
7465   ""
7467   return TARGET_V9 ? "flushw" : "ta\t3";
7469   [(set_attr "type" "flushw")])
7471 ;; Special pattern for the FLUSH instruction.
7473 (define_insn "@flush<P:mode>"
7474   [(unspec_volatile [(match_operand:P 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7475   ""
7477   return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0";
7479   [(set_attr "type" "iflush")])
7481 ;; Special insns to load and store the 32-bit FP Status Register.
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")])
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")])
7498 ;; Find first set instructions.
7500 (define_expand "popcountdi2"
7501   [(set (match_operand:DI 0 "register_operand" "")
7502         (popcount:DI (match_operand:DI 1 "register_operand" "")))]
7503   "TARGET_POPC"
7505   if (TARGET_ARCH32)
7506     {
7507       emit_insn (gen_popcountdi_v8plus (operands[0], operands[1]));
7508       DONE;
7509     }
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")
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"
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";
7528   [(set_attr "type" "multi")
7529    (set_attr "length" "5")])
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"
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);
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")
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"
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";
7563   [(set_attr "type" "multi")
7564    (set_attr "length" "2")])
7566 (define_expand "clzdi2"
7567   [(set (match_operand:DI 0 "register_operand" "")
7568         (clz:DI (match_operand:DI 1 "register_operand" "")))]
7569   "TARGET_VIS3"
7571   if (TARGET_ARCH32)
7572     {
7573       emit_insn (gen_clzdi_v8plus (operands[0], operands[1]));
7574       DONE;
7575     }
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")])
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"
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";
7595   [(set_attr "type" "multi")
7596    (set_attr "length" "5")])
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"
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     }
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")])
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"
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";
7636   [(set_attr "type" "multi")
7637    (set_attr "length" "3")])
7640 ;; Peepholes go at the end.
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.
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))]
7655   operands[0] = widen_mem_for_ldd_peep (operands[0], operands[1], DImode);
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))]
7667   operands[1] = widen_mem_for_ldd_peep (operands[1], operands[0], DImode);
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))]
7679   operands[1] = widen_mem_for_ldd_peep (operands[1], operands[3], DImode);
7680   operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
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))]
7692   operands[0] = widen_mem_for_ldd_peep (operands[0], operands[2], DImode);
7693   operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));
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))]
7705   operands[1] = widen_mem_for_ldd_peep (operands[1], operands[3], DFmode);
7706   operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));
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))]
7718   operands[0] = widen_mem_for_ldd_peep (operands[0], operands[2], DFmode);
7719   operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));
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))]
7731   operands[3] = widen_mem_for_ldd_peep (operands[3], operands[1], DImode);
7732   operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));
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))]
7744   operands[2] = widen_mem_for_ldd_peep (operands[2],  operands[0], DImode);
7745   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
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))]
7757   operands[3] = widen_mem_for_ldd_peep (operands[3], operands[1], DFmode);
7758   operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));
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))]
7770   operands[2] = widen_mem_for_ldd_peep (operands[2], operands[0], DFmode);
7771   operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));
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.
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   "")
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   "")
7810 ;; Prefetch instructions.
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"
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;
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   ""
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]);
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];
7852   [(set_attr "type" "load")
7853    (set_attr "subtype" "prefetch")])
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   ""
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]);
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];
7878   [(set_attr "type" "load")
7879    (set_attr "subtype" "prefetch")])
7882 ;; Trap instructions.
7884 (define_insn "trap"
7885   [(trap_if (const_int 1) (const_int 5))]
7886   ""
7887   "ta\t5"
7888   [(set_attr "type" "trap")])
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   ""
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;
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"
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;
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   ""
7922   if (TARGET_V9)
7923     return "t%C0\t%%icc, %1";
7924   else
7925     return "t%C0\t%1";
7927   [(set_attr "type" "trap")])
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")])
7938 ;; TLS support instructions.
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")
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")
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)")
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")))])
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")
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")
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(%&)")
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")))])
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")
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")
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)")
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")
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")
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")])
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")])
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)")
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")
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")
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
8334 ;; Stack protector instructions.
8336 (define_expand "stack_protect_set"
8337   [(match_operand 0 "memory_operand" "")
8338    (match_operand 1 "memory_operand" "")]
8339   ""
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_set64 (operands[0], operands[1]));
8348   else
8349     emit_insn (gen_stack_protect_set32 (operands[0], operands[1]));
8350   DONE;
8353 (define_insn "stack_protect_set32"
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"
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";
8364   [(set_attr "type" "multi")
8365    (set (attr "length") (if_then_else (eq_attr "fix_b2bst" "true")
8366                       (const_int 4) (const_int 3)))])
8368 (define_insn "stack_protect_set64"
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")])
8377 (define_expand "stack_protect_test"
8378   [(match_operand 0 "memory_operand" "")
8379    (match_operand 1 "memory_operand" "")
8380    (match_operand 2 "" "")]
8381   ""
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_test64 (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_test32 (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;
8406 (define_insn "stack_protect_test32"
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")])
8418 (define_insn "stack_protect_test64"
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")])
8430 ;; Vector instructions.
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])
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")])
8446 (define_expand "mov<VMALL:mode>"
8447   [(set (match_operand:VMALL 0 "nonimmediate_operand" "")
8448         (match_operand:VMALL 1 "general_operand" ""))]
8449   "TARGET_VIS"
8451   if (sparc_expand_move (<VMALL:MODE>mode, operands))
8452     DONE;
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")])
8477 (define_insn "*mov<VM64:mode>_insn_sp64"
8478   [(set (match_operand:VM64 0 "nonimmediate_operand" "=e,e,e,e,m,m,*r, m,*r, e,*r")
8479         (match_operand:VM64 1 "input_operand"         "Y,Z,e,m,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,*")])
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,*,*,*,*,*")])
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))]
8541   sparc_split_reg_reg (operands[0], operands[1], SImode);
8542   DONE;
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))]
8554   sparc_split_reg_mem (operands[0], operands[1], SImode);
8555   DONE;
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))]
8567   sparc_split_mem_reg (operands[0], operands[1], SImode);
8568   DONE;
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))]
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;
8586 (define_expand "vec_init<VMALL:mode><VMALL:veltmode>"
8587   [(match_operand:VMALL 0 "register_operand" "")
8588    (match_operand:VMALL 1 "" "")]
8589   "TARGET_VIS"
8591   sparc_expand_vector_init (operands[0], operands[1]);
8592   DONE;
8595 (define_code_iterator plusminus [plus minus])
8596 (define_code_attr plusminus_insn [(plus "add") (minus "sub")])
8598 (define_mode_iterator VADDSUB [V1SI V2SI V2HI V4HI])
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>")])
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")])
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>")])
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>")])
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>")])
8645 (define_code_iterator vlnotop [ior and])
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>")])
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>")])
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>")])
8673 ;; Hard to generate VIS instructions.  We have builtins for these.
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
8802 (define_expand "wrgsr_vis"
8803   [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" ""))]
8804   "TARGET_VIS"
8806   if (TARGET_ARCH32)
8807     {
8808       emit_insn (gen_wrgsr_v8plus (operands[0]));
8809       DONE;
8810     }
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")])
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"
8825   if (GET_CODE (operands[0]) == CONST_INT
8826       || sparc_check_64 (operands[0], insn))
8827     return "wr\t%%g0, %0, %%gsr";
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";
8832   [(set_attr "type" "multi")])
8834 (define_expand "rdgsr_vis"
8835   [(set (match_operand:DI 0 "register_operand" "") (reg:DI GSR_REG))]
8836   "TARGET_VIS"
8838   if (TARGET_ARCH32)
8839     {
8840       emit_insn (gen_rdgsr_v8plus (operands[0]));
8841       DONE;
8842     }
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")])
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"
8857   return "rd\t%%gsr, %1\n\tsrlx\t%1, 32, %H0\n\tmov %1, %L0";
8859   [(set_attr "type" "multi")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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")])
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"
9032   sparc_expand_vcond (<MODE>mode, operands, UNSPEC_CMASK<gcm_name>, UNSPEC_FCMP);
9033   DONE;
9036 (define_expand "vcondv8qiv8qi"
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_VIS4"
9045   sparc_expand_vcond (V8QImode, operands, UNSPEC_CMASK8, UNSPEC_FCMP);
9046   DONE;
9049 (define_insn "fucmp<gcond:code>8<P:mode>_vis"
9050   [(set (match_operand:P 0 "register_operand" "=r")
9051         (unspec:P [(gcond:V8QI (match_operand:V8QI 1 "register_operand" "e")
9052                                (match_operand:V8QI 2 "register_operand" "e"))]
9053          UNSPEC_FUCMP))]
9054   "TARGET_VIS3"
9055   "fucmp<gcond:code>8\t%1, %2, %0"
9056   [(set_attr "type" "viscmp")])
9058 (define_insn "fpcmpu<gcond:code><GCM:gcm_name><P:mode>_vis"
9059   [(set (match_operand:P 0 "register_operand" "=r")
9060         (unspec:P [(gcond:GCM (match_operand:GCM 1 "register_operand" "e")
9061                               (match_operand:GCM 2 "register_operand" "e"))]
9062          UNSPEC_FUCMP))]
9063   "TARGET_VIS4"
9064   "fpcmpu<gcond:code><GCM:gcm_name>\t%1, %2, %0"
9065   [(set_attr "type" "viscmp")])
9067 (define_expand "vcondu<GCM:mode><GCM:mode>"
9068   [(match_operand:GCM 0 "register_operand" "")
9069    (match_operand:GCM 1 "register_operand" "")
9070    (match_operand:GCM 2 "register_operand" "")
9071    (match_operator 3 ""
9072      [(match_operand:GCM 4 "register_operand" "")
9073       (match_operand:GCM 5 "register_operand" "")])]
9074   "TARGET_VIS4"
9076   sparc_expand_vcond (<MODE>mode, operands, UNSPEC_CMASK<gcm_name>, UNSPEC_FUCMP);
9077   DONE;
9080 (define_expand "vconduv8qiv8qi"
9081   [(match_operand:V8QI 0 "register_operand" "")
9082    (match_operand:V8QI 1 "register_operand" "")
9083    (match_operand:V8QI 2 "register_operand" "")
9084    (match_operator 3 ""
9085      [(match_operand:V8QI 4 "register_operand" "")
9086       (match_operand:V8QI 5 "register_operand" "")])]
9087   "TARGET_VIS3"
9089   sparc_expand_vcond (V8QImode, operands, UNSPEC_CMASK8, UNSPEC_FUCMP);
9090   DONE;
9093 (define_insn "array8<P:mode>_vis"
9094   [(set (match_operand:P 0 "register_operand" "=r")
9095         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
9096                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
9097                   UNSPEC_ARRAY8))]
9098   "TARGET_VIS"
9099   "array8\t%r1, %r2, %0"
9100   [(set_attr "type" "array")])
9102 (define_insn "array16<P:mode>_vis"
9103   [(set (match_operand:P 0 "register_operand" "=r")
9104         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
9105                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
9106                   UNSPEC_ARRAY16))]
9107   "TARGET_VIS"
9108   "array16\t%r1, %r2, %0"
9109   [(set_attr "type" "array")])
9111 (define_insn "array32<P:mode>_vis"
9112   [(set (match_operand:P 0 "register_operand" "=r")
9113         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
9114                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
9115                   UNSPEC_ARRAY32))]
9116   "TARGET_VIS"
9117   "array32\t%r1, %r2, %0"
9118   [(set_attr "type" "array")])
9120 (define_insn "bmaskdi_vis"
9121   [(set (match_operand:DI 0 "register_operand" "=r")
9122         (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
9123                  (match_operand:DI 2 "register_or_zero_operand" "rJ")))
9124    (set (zero_extract:DI (reg:DI GSR_REG) (const_int 32) (const_int 32))
9125         (plus:DI (match_dup 1) (match_dup 2)))]
9126   "TARGET_VIS2 && TARGET_ARCH64"
9127   "bmask\t%r1, %r2, %0"
9128   [(set_attr "type" "bmask")])
9130 (define_insn "bmasksi_vis"
9131   [(set (match_operand:SI 0 "register_operand" "=r")
9132         (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
9133                  (match_operand:SI 2 "register_or_zero_operand" "rJ")))
9134    (set (zero_extract:DI (reg:DI GSR_REG) (const_int 32) (const_int 32))
9135         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
9136   "TARGET_VIS2"
9137   "bmask\t%r1, %r2, %0"
9138   [(set_attr "type" "bmask")])
9140 (define_insn "bshuffle<VM64:mode>_vis"
9141   [(set (match_operand:VM64 0 "register_operand" "=e")
9142         (unspec:VM64 [(match_operand:VM64 1 "register_operand" "e")
9143                       (match_operand:VM64 2 "register_operand" "e")
9144                       (reg:DI GSR_REG)]
9145                      UNSPEC_BSHUFFLE))]
9146   "TARGET_VIS2"
9147   "bshuffle\t%1, %2, %0"
9148   [(set_attr "type" "fga")
9149    (set_attr "subtype" "other")
9150    (set_attr "fptype" "double")])
9152 ;; Unlike constant permutation, we can vastly simplify the compression of
9153 ;; the 64-bit selector input to the 32-bit %gsr value by knowing what the
9154 ;; width of the input is.
9155 (define_expand "vec_perm<VM64:mode>"
9156   [(match_operand:VM64 0 "register_operand" "")
9157    (match_operand:VM64 1 "register_operand" "")
9158    (match_operand:VM64 2 "register_operand" "")
9159    (match_operand:VM64 3 "register_operand" "")]
9160   "TARGET_VIS2"
9162   sparc_expand_vec_perm_bmask (<MODE>mode, operands[3]);
9163   emit_insn (gen_bshuffle<VM64:mode>_vis (operands[0], operands[1], operands[2]));
9164   DONE;
9167 ;; VIS 2.0 adds edge variants which do not set the condition codes
9168 (define_insn "edge8n<P:mode>_vis"
9169   [(set (match_operand:P 0 "register_operand" "=r")
9170         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
9171                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
9172                   UNSPEC_EDGE8N))]
9173   "TARGET_VIS2"
9174   "edge8n\t%r1, %r2, %0"
9175   [(set_attr "type" "edgen")])
9177 (define_insn "edge8ln<P:mode>_vis"
9178   [(set (match_operand:P 0 "register_operand" "=r")
9179         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
9180                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
9181                   UNSPEC_EDGE8LN))]
9182   "TARGET_VIS2"
9183   "edge8ln\t%r1, %r2, %0"
9184   [(set_attr "type" "edgen")])
9186 (define_insn "edge16n<P:mode>_vis"
9187   [(set (match_operand:P 0 "register_operand" "=r")
9188         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
9189                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
9190                   UNSPEC_EDGE16N))]
9191   "TARGET_VIS2"
9192   "edge16n\t%r1, %r2, %0"
9193   [(set_attr "type" "edgen")])
9195 (define_insn "edge16ln<P:mode>_vis"
9196   [(set (match_operand:P 0 "register_operand" "=r")
9197         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
9198                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
9199                   UNSPEC_EDGE16LN))]
9200   "TARGET_VIS2"
9201   "edge16ln\t%r1, %r2, %0"
9202   [(set_attr "type" "edgen")])
9204 (define_insn "edge32n<P:mode>_vis"
9205   [(set (match_operand:P 0 "register_operand" "=r")
9206         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
9207                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
9208                   UNSPEC_EDGE32N))]
9209   "TARGET_VIS2"
9210   "edge32n\t%r1, %r2, %0"
9211   [(set_attr "type" "edgen")])
9213 (define_insn "edge32ln<P:mode>_vis"
9214   [(set (match_operand:P 0 "register_operand" "=r")
9215         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
9216                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
9217                   UNSPEC_EDGE32LN))]
9218   "TARGET_VIS2"
9219   "edge32ln\t%r1, %r2, %0"
9220   [(set_attr "type" "edge")])
9222 ;; Conditional moves are possible via fcmpX --> cmaskX -> bshuffle
9223 (define_insn "cmask8<P:mode>_vis"
9224   [(set (reg:DI GSR_REG)
9225         (unspec:DI [(match_operand:P 0 "register_or_zero_operand" "rJ")
9226                     (reg:DI GSR_REG)]
9227                    UNSPEC_CMASK8))]
9228   "TARGET_VIS3"
9229   "cmask8\t%r0"
9230   [(set_attr "type" "fga")
9231    (set_attr "subtype" "cmask")])
9233 (define_insn "cmask16<P:mode>_vis"
9234   [(set (reg:DI GSR_REG)
9235         (unspec:DI [(match_operand:P 0 "register_or_zero_operand" "rJ")
9236                     (reg:DI GSR_REG)]
9237                    UNSPEC_CMASK16))]
9238   "TARGET_VIS3"
9239   "cmask16\t%r0"
9240   [(set_attr "type" "fga")
9241    (set_attr "subtype" "cmask")])
9243 (define_insn "cmask32<P:mode>_vis"
9244   [(set (reg:DI GSR_REG)
9245         (unspec:DI [(match_operand:P 0 "register_or_zero_operand" "rJ")
9246                     (reg:DI GSR_REG)]
9247                    UNSPEC_CMASK32))]
9248   "TARGET_VIS3"
9249   "cmask32\t%r0"
9250   [(set_attr "type" "fga")
9251    (set_attr "subtype" "cmask")])
9253 (define_insn "fchksm16_vis"
9254   [(set (match_operand:V4HI 0 "register_operand" "=e")
9255         (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "e")
9256                       (match_operand:V4HI 2 "register_operand" "e")]
9257                      UNSPEC_FCHKSM16))]
9258   "TARGET_VIS3"
9259   "fchksm16\t%1, %2, %0"
9260   [(set_attr "type" "fga")
9261    (set_attr "subtype" "fpu")])
9263 (define_code_iterator vis3_shift [ashift ss_ashift lshiftrt ashiftrt])
9264 (define_code_attr vis3_shift_insn
9265   [(ashift "fsll") (ss_ashift "fslas") (lshiftrt "fsrl") (ashiftrt "fsra")])
9266 (define_code_attr vis3_shift_patname
9267   [(ashift "ashl") (ss_ashift "ssashl") (lshiftrt "lshr") (ashiftrt "ashr")])
9268    
9269 (define_insn "v<vis3_shift_patname><GCM:mode>3"
9270   [(set (match_operand:GCM 0 "register_operand" "=<vconstr>")
9271         (vis3_shift:GCM (match_operand:GCM 1 "register_operand" "<vconstr>")
9272                         (match_operand:GCM 2 "register_operand" "<vconstr>")))]
9273   "TARGET_VIS3"
9274   "<vis3_shift_insn><vbits>\t%1, %2, %0"
9275   [(set_attr "type" "fga")
9276    (set_attr "subtype" "fpu")])
9278 (define_insn "pdistn<P:mode>_vis"
9279   [(set (match_operand:P 0 "register_operand" "=r")
9280         (unspec:P [(match_operand:V8QI 1 "register_operand" "e")
9281                    (match_operand:V8QI 2 "register_operand" "e")]
9282          UNSPEC_PDISTN))]
9283   "TARGET_VIS3"
9284   "pdistn\t%1, %2, %0"
9285   [(set_attr "type" "pdistn")
9286    (set_attr "fptype" "double")])
9288 (define_insn "fmean16_vis"
9289   [(set (match_operand:V4HI 0 "register_operand" "=e")
9290         (truncate:V4HI
9291           (lshiftrt:V4SI
9292             (plus:V4SI
9293               (plus:V4SI
9294                 (zero_extend:V4SI
9295                   (match_operand:V4HI 1 "register_operand" "e"))
9296                 (zero_extend:V4SI
9297                   (match_operand:V4HI 2 "register_operand" "e")))
9298               (const_vector:V4SI [(const_int 1) (const_int 1)
9299                                   (const_int 1) (const_int 1)]))
9300           (const_int 1))))]
9301   "TARGET_VIS3"
9302   "fmean16\t%1, %2, %0"
9303   [(set_attr "type" "fga")
9304    (set_attr "subtype" "fpu")])
9306 (define_insn "fp<plusminus_insn>64_vis"
9307   [(set (match_operand:V1DI 0 "register_operand" "=e")
9308         (plusminus:V1DI (match_operand:V1DI 1 "register_operand" "e")
9309                         (match_operand:V1DI 2 "register_operand" "e")))]
9310   "TARGET_VIS3"
9311   "fp<plusminus_insn>64\t%1, %2, %0"
9312   [(set_attr "type" "fga")
9313    (set_attr "subtype" "addsub64")])
9315 (define_insn "<plusminus_insn>v8qi3"
9316   [(set (match_operand:V8QI 0 "register_operand" "=e")
9317         (plusminus:V8QI (match_operand:V8QI 1 "register_operand" "e")
9318                         (match_operand:V8QI 2 "register_operand" "e")))]
9319   "TARGET_VIS4"
9320   "fp<plusminus_insn>8\t%1, %2, %0"
9321   [(set_attr "type" "fga")
9322    (set_attr "subtype" "other")])
9324 (define_mode_iterator VASS [V4HI V2SI V2HI V1SI])
9325 (define_code_iterator vis3_addsub_ss [ss_plus ss_minus])
9326 (define_code_attr vis3_addsub_ss_insn
9327   [(ss_plus "fpadds") (ss_minus "fpsubs")])
9328 (define_code_attr vis3_addsub_ss_patname
9329   [(ss_plus "ssadd") (ss_minus "sssub")])
9331 (define_insn "<vis3_addsub_ss_patname><VASS:mode>3"
9332   [(set (match_operand:VASS 0 "register_operand" "=<vconstr>")
9333         (vis3_addsub_ss:VASS (match_operand:VASS 1 "register_operand" "<vconstr>")
9334                              (match_operand:VASS 2 "register_operand" "<vconstr>")))]
9335   "TARGET_VIS3"
9336   "<vis3_addsub_ss_insn><vbits>\t%1, %2, %0"
9337   [(set_attr "type" "fga")
9338    (set_attr "subtype" "other")])
9340 (define_mode_iterator VMMAX [V8QI V4HI V2SI])
9341 (define_code_iterator vis4_minmax [smin smax])
9342 (define_code_attr vis4_minmax_insn
9343   [(smin "fpmin") (smax "fpmax")])
9344 (define_code_attr vis4_minmax_patname
9345   [(smin "min") (smax "max")])
9347 (define_insn "<vis4_minmax_patname><VMMAX:mode>3"
9348   [(set (match_operand:VMMAX 0 "register_operand" "=<vconstr>")
9349         (vis4_minmax:VMMAX (match_operand:VMMAX 1 "register_operand" "<vconstr>")
9350                            (match_operand:VMMAX 2 "register_operand" "<vconstr>")))]
9351   "TARGET_VIS4"
9352   "<vis4_minmax_insn><vbits>\t%1, %2, %0"
9353   [(set_attr "type" "fga")
9354    (set_attr "subtype" "maxmin")])
9356 (define_code_iterator vis4_uminmax [umin umax])
9357 (define_code_attr vis4_uminmax_insn
9358   [(umin "fpminu") (umax "fpmaxu")])
9359 (define_code_attr vis4_uminmax_patname
9360  [(umin "minu") (umax "maxu")])
9362 (define_insn "<vis4_uminmax_patname><VMMAX:mode>3"
9363   [(set (match_operand:VMMAX 0 "register_operand" "=<vconstr>")
9364         (vis4_uminmax:VMMAX (match_operand:VMMAX 1 "register_operand" "<vconstr>")
9365                             (match_operand:VMMAX 2 "register_operand" "<vconstr>")))]
9366   "TARGET_VIS4"
9367   "<vis4_uminmax_insn><vbits>\t%1, %2, %0"
9368   [(set_attr "type" "fga")
9369    (set_attr "subtype" "maxmin")])
9371 ;; The use of vis3_addsub_ss_patname in the VIS4 instruction below is
9372 ;; intended.
9373 (define_insn "<vis3_addsub_ss_patname>v8qi3"
9374   [(set (match_operand:V8QI 0 "register_operand" "=e")
9375         (vis3_addsub_ss:V8QI (match_operand:V8QI 1 "register_operand" "e")
9376                              (match_operand:V8QI 2 "register_operand" "e")))]
9377   "TARGET_VIS4"
9378   "<vis3_addsub_ss_insn>8\t%1, %2, %0"
9379   [(set_attr "type" "fga")
9380    (set_attr "subtype" "other")])
9382 (define_mode_iterator VAUS [V4HI V8QI])
9383 (define_code_iterator vis4_addsub_us [us_plus us_minus])
9384 (define_code_attr vis4_addsub_us_insn
9385   [(us_plus "fpaddus") (us_minus "fpsubus")])
9386 (define_code_attr vis4_addsub_us_patname
9387   [(us_plus "usadd") (us_minus "ussub")])
9389 (define_insn "<vis4_addsub_us_patname><VAUS:mode>3"
9390  [(set (match_operand:VAUS 0 "register_operand" "=<vconstr>")
9391        (vis4_addsub_us:VAUS (match_operand:VAUS 1 "register_operand" "<vconstr>")
9392                             (match_operand:VAUS 2 "register_operand" "<vconstr>")))]
9393  "TARGET_VIS4"
9394  "<vis4_addsub_us_insn><vbits>\t%1, %2, %0"
9395  [(set_attr "type" "fga")
9396   (set_attr "subtype" "other")])
9398 (define_insn "*naddsf3"
9399   [(set (match_operand:SF 0 "register_operand" "=f")
9400         (neg:SF (plus:SF (match_operand:SF 1 "register_operand" "f")
9401                          (match_operand:SF 2 "register_operand" "f"))))]
9402   "TARGET_VIS3"
9403   "fnadds\t%1, %2, %0"
9404   [(set_attr "type" "fp")])
9406 (define_insn "*nadddf3"
9407   [(set (match_operand:DF 0 "register_operand" "=e")
9408         (neg:DF (plus:DF (match_operand:DF 1 "register_operand" "e")
9409                          (match_operand:DF 2 "register_operand" "e"))))]
9410   "TARGET_VIS3"
9411   "fnaddd\t%1, %2, %0"
9412   [(set_attr "type" "fp")
9413    (set_attr "fptype" "double")])
9415 (define_insn "*nmulsf3"
9416   [(set (match_operand:SF 0 "register_operand" "=f")
9417         (mult:SF (neg:SF (match_operand:SF 1 "register_operand" "f"))
9418                  (match_operand:SF 2 "register_operand" "f")))]
9419   "TARGET_VIS3"
9420   "fnmuls\t%1, %2, %0"
9421   [(set_attr "type" "fpmul")])
9423 (define_insn "*nmuldf3"
9424   [(set (match_operand:DF 0 "register_operand" "=e")
9425         (mult:DF (neg:DF (match_operand:DF 1 "register_operand" "e"))
9426                  (match_operand:DF 2 "register_operand" "e")))]
9427   "TARGET_VIS3"
9428   "fnmuld\t%1, %2, %0"
9429   [(set_attr "type" "fpmul")
9430    (set_attr "fptype" "double")])
9432 (define_insn "*nmuldf3_extend"
9433   [(set (match_operand:DF 0 "register_operand" "=e")
9434         (mult:DF (neg:DF (float_extend:DF
9435                            (match_operand:SF 1 "register_operand" "f")))
9436                  (float_extend:DF
9437                    (match_operand:SF 2 "register_operand" "f"))))]
9438   "TARGET_VIS3"
9439   "fnsmuld\t%1, %2, %0"
9440   [(set_attr "type" "fpmul")
9441    (set_attr "fptype" "double")])
9443 (define_insn "fhaddsf_vis"
9444   [(set (match_operand:SF 0 "register_operand" "=f")
9445         (unspec:SF [(match_operand:SF 1 "register_operand" "f")
9446                     (match_operand:SF 2 "register_operand" "f")]
9447                    UNSPEC_FHADD))]
9448   "TARGET_VIS3"
9449   "fhadds\t%1, %2, %0"
9450   [(set_attr "type" "fp")])
9452 (define_insn "fhadddf_vis"
9453   [(set (match_operand:DF 0 "register_operand" "=f")
9454         (unspec:DF [(match_operand:DF 1 "register_operand" "f")
9455                     (match_operand:DF 2 "register_operand" "f")]
9456                    UNSPEC_FHADD))]
9457   "TARGET_VIS3"
9458   "fhaddd\t%1, %2, %0"
9459   [(set_attr "type" "fp")
9460    (set_attr "fptype" "double")])
9462 (define_insn "fhsubsf_vis"
9463   [(set (match_operand:SF 0 "register_operand" "=f")
9464         (unspec:SF [(match_operand:SF 1 "register_operand" "f")
9465                     (match_operand:SF 2 "register_operand" "f")]
9466                    UNSPEC_FHSUB))]
9467   "TARGET_VIS3"
9468   "fhsubs\t%1, %2, %0"
9469   [(set_attr "type" "fp")])
9471 (define_insn "fhsubdf_vis"
9472   [(set (match_operand:DF 0 "register_operand" "=f")
9473         (unspec:DF [(match_operand:DF 1 "register_operand" "f")
9474                     (match_operand:DF 2 "register_operand" "f")]
9475                    UNSPEC_FHSUB))]
9476   "TARGET_VIS3"
9477   "fhsubd\t%1, %2, %0"
9478   [(set_attr "type" "fp")
9479    (set_attr "fptype" "double")])
9481 (define_insn "fnhaddsf_vis"
9482   [(set (match_operand:SF 0 "register_operand" "=f")
9483         (neg:SF (unspec:SF [(match_operand:SF 1 "register_operand" "f")
9484                             (match_operand:SF 2 "register_operand" "f")]
9485                            UNSPEC_FHADD)))]
9486   "TARGET_VIS3"
9487   "fnhadds\t%1, %2, %0"
9488   [(set_attr "type" "fp")])
9490 (define_insn "fnhadddf_vis"
9491   [(set (match_operand:DF 0 "register_operand" "=f")
9492         (neg:DF (unspec:DF [(match_operand:DF 1 "register_operand" "f")
9493                             (match_operand:DF 2 "register_operand" "f")]
9494                            UNSPEC_FHADD)))]
9495   "TARGET_VIS3"
9496   "fnhaddd\t%1, %2, %0"
9497   [(set_attr "type" "fp")
9498    (set_attr "fptype" "double")])
9500 ;; VIS4B instructions.
9502 (define_mode_iterator DUMODE [V2SI V4HI V8QI])
9504 (define_insn "dictunpack<DUMODE:vbits>"
9505   [(set (match_operand:DUMODE 0 "register_operand" "=e")
9506         (unspec:DUMODE [(match_operand:DF 1 "register_operand" "e")
9507                         (match_operand:SI 2 "imm5_operand_dictunpack<DUMODE:vbits>" "t")]
9508          UNSPEC_DICTUNPACK))]
9509   "TARGET_VIS4B"
9510   "dictunpack\t%1, %2, %0"
9511   [(set_attr "type" "fga")
9512    (set_attr "subtype" "other")])
9514 (define_mode_iterator FPCSMODE [V2SI V4HI V8QI])
9515 (define_code_iterator fpcscond [le gt eq ne])
9516 (define_code_iterator fpcsucond [le gt])
9518 (define_insn "fpcmp<fpcscond:code><FPCSMODE:vbits><P:mode>shl"
9519   [(set (match_operand:P 0 "register_operand" "=r")
9520         (unspec:P [(fpcscond:FPCSMODE (match_operand:FPCSMODE 1 "register_operand" "e")
9521                                       (match_operand:FPCSMODE 2 "register_operand" "e"))
9522                    (match_operand:SI 3 "imm2_operand" "q")]
9523          UNSPEC_FPCMPSHL))]
9524    "TARGET_VIS4B"
9525    "fpcmp<fpcscond:code><FPCSMODE:vbits>shl\t%1, %2, %3, %0"
9526    [(set_attr "type" "viscmp")])
9528 (define_insn "fpcmpu<fpcsucond:code><FPCSMODE:vbits><P:mode>shl"
9529   [(set (match_operand:P 0 "register_operand" "=r")
9530         (unspec:P [(fpcsucond:FPCSMODE (match_operand:FPCSMODE 1 "register_operand" "e")
9531                                        (match_operand:FPCSMODE 2 "register_operand" "e"))
9532                    (match_operand:SI 3 "imm2_operand" "q")]
9533          UNSPEC_FPUCMPSHL))]
9534    "TARGET_VIS4B"
9535    "fpcmpu<fpcsucond:code><FPCSMODE:vbits>shl\t%1, %2, %3, %0"
9536    [(set_attr "type" "viscmp")])
9538 (define_insn "fpcmpde<FPCSMODE:vbits><P:mode>shl"
9539   [(set (match_operand:P 0 "register_operand" "=r")
9540         (unspec:P [(match_operand:FPCSMODE 1 "register_operand" "e")
9541                    (match_operand:FPCSMODE 2 "register_operand" "e")
9542                    (match_operand:SI 3 "imm2_operand" "q")]
9543          UNSPEC_FPCMPDESHL))]
9544    "TARGET_VIS4B"
9545    "fpcmpde<FPCSMODE:vbits>shl\t%1, %2, %3, %0"
9546    [(set_attr "type" "viscmp")])
9548 (define_insn "fpcmpur<FPCSMODE:vbits><P:mode>shl"
9549   [(set (match_operand:P 0 "register_operand" "=r")
9550         (unspec:P [(match_operand:FPCSMODE 1 "register_operand" "e")
9551                    (match_operand:FPCSMODE 2 "register_operand" "e")
9552                    (match_operand:SI 3 "imm2_operand" "q")]
9553          UNSPEC_FPCMPURSHL))]
9554    "TARGET_VIS4B"
9555    "fpcmpur<FPCSMODE:vbits>shl\t%1, %2, %3, %0"
9556    [(set_attr "type" "viscmp")])
9558 (include "sync.md")