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