PR target/81988
[official-gcc.git] / gcc / config / sparc / sparc.md
blobd9cbd4fb10d69955f4584391ffcfc62c23c8f008
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_expand "mulsi3"
4521   [(set (match_operand:SI 0 "register_operand" "")
4522         (mult:SI (match_operand:SI 1 "arith_operand" "")
4523                  (match_operand:SI 2 "arith_operand" "")))]
4524   "TARGET_HARD_MUL || TARGET_ARCH64"
4525   "")
4527 (define_insn "*mulsi3_sp32"
4528   [(set (match_operand:SI 0 "register_operand" "=r")
4529         (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4530                  (match_operand:SI 2 "arith_operand" "rI")))]
4531   "TARGET_HARD_MUL"
4532   "smul\t%1, %2, %0"
4533   [(set_attr "type" "imul")])
4535 (define_insn "*mulsi3_sp64"
4536   [(set (match_operand:SI 0 "register_operand" "=r")
4537         (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4538                  (match_operand:SI 2 "arith_operand" "rI")))]
4539   "TARGET_ARCH64"
4540   "mulx\t%1, %2, %0"
4541   [(set_attr "type" "imul")])
4543 (define_expand "muldi3"
4544   [(set (match_operand:DI 0 "register_operand" "")
4545         (mult:DI (match_operand:DI 1 "arith_operand" "")
4546                  (match_operand:DI 2 "arith_operand" "")))]
4547   "TARGET_ARCH64 || TARGET_V8PLUS"
4549   if (TARGET_V8PLUS)
4550     {
4551       emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
4552       DONE;
4553     }
4556 (define_insn "*muldi3_sp64"
4557   [(set (match_operand:DI 0 "register_operand" "=r")
4558         (mult:DI (match_operand:DI 1 "arith_operand" "%r")
4559                  (match_operand:DI 2 "arith_operand" "rI")))]
4560   "TARGET_ARCH64"
4561   "mulx\t%1, %2, %0"
4562   [(set_attr "type" "imul")])
4564 ;; V8plus wide multiply.
4565 (define_insn "muldi3_v8plus"
4566   [(set (match_operand:DI 0 "register_operand" "=r,h")
4567         (mult:DI (match_operand:DI 1 "arith_operand" "%r,0")
4568                  (match_operand:DI 2 "arith_operand" "rI,rI")))
4569    (clobber (match_scratch:SI 3 "=&h,X"))
4570    (clobber (match_scratch:SI 4 "=&h,X"))]
4571   "TARGET_V8PLUS"
4573   return output_v8plus_mult (insn, operands, \"mulx\");
4575   [(set_attr "type" "multi")
4576    (set_attr "length" "9,8")])
4578 (define_insn "*cmp_mul_set"
4579   [(set (reg:CC CC_REG)
4580         (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4581                     (match_operand:SI 2 "arith_operand" "rI"))
4582                     (const_int 0)))
4583    (set (match_operand:SI 0 "register_operand" "=r")
4584         (mult:SI (match_dup 1) (match_dup 2)))]
4585   "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
4586   "smulcc\t%1, %2, %0"
4587   [(set_attr "type" "imul")])
4589 (define_expand "mulsidi3"
4590   [(set (match_operand:DI 0 "register_operand" "")
4591         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4592                  (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
4593   "TARGET_HARD_MUL"
4595   if (CONSTANT_P (operands[2]))
4596     {
4597       if (TARGET_V8PLUS)
4598         emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
4599                                               operands[2]));
4600       else if (TARGET_ARCH32)
4601         emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
4602                                             operands[2]));
4603       else 
4604         emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
4605                                             operands[2]));
4606       DONE;
4607     }
4608   if (TARGET_V8PLUS)
4609     {
4610       emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
4611       DONE;
4612     }
4615 ;; V9 puts the 64-bit product in a 64-bit register.  Only out or global
4616 ;; registers can hold 64-bit values in the V8plus environment.
4617 (define_insn "mulsidi3_v8plus"
4618   [(set (match_operand:DI 0 "register_operand" "=h,r")
4619         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4620                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4621    (clobber (match_scratch:SI 3 "=X,&h"))]
4622   "TARGET_V8PLUS"
4623   "@
4624    smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4625    smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4626   [(set_attr "type" "multi")
4627    (set_attr "length" "2,3")])
4629 (define_insn "const_mulsidi3_v8plus"
4630   [(set (match_operand:DI 0 "register_operand" "=h,r")
4631         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4632                  (match_operand:DI 2 "small_int_operand" "I,I")))
4633    (clobber (match_scratch:SI 3 "=X,&h"))]
4634   "TARGET_V8PLUS"
4635   "@
4636    smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4637    smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4638   [(set_attr "type" "multi")
4639    (set_attr "length" "2,3")])
4641 (define_insn "*mulsidi3_sp32"
4642   [(set (match_operand:DI 0 "register_operand" "=r")
4643         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4644                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4645   "TARGET_HARD_MUL32"
4647   return TARGET_SPARCLET
4648          ? "smuld\t%1, %2, %L0"
4649          : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4651   [(set (attr "type")
4652         (if_then_else (eq_attr "isa" "sparclet")
4653                       (const_string "imul") (const_string "multi")))
4654    (set (attr "length")
4655         (if_then_else (eq_attr "isa" "sparclet")
4656                       (const_int 1) (const_int 2)))])
4658 (define_insn "*mulsidi3_sp64"
4659   [(set (match_operand:DI 0 "register_operand" "=r")
4660         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4661                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4662   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4663   "smul\t%1, %2, %0"
4664   [(set_attr "type" "imul")])
4666 ;; Extra pattern, because sign_extend of a constant isn't valid.
4668 (define_insn "const_mulsidi3_sp32"
4669   [(set (match_operand:DI 0 "register_operand" "=r")
4670         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4671                  (match_operand:DI 2 "small_int_operand" "I")))]
4672   "TARGET_HARD_MUL32"
4674   return TARGET_SPARCLET
4675          ? "smuld\t%1, %2, %L0"
4676          : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4678   [(set (attr "type")
4679         (if_then_else (eq_attr "isa" "sparclet")
4680                       (const_string "imul") (const_string "multi")))
4681    (set (attr "length")
4682         (if_then_else (eq_attr "isa" "sparclet")
4683                       (const_int 1) (const_int 2)))])
4685 (define_insn "const_mulsidi3_sp64"
4686   [(set (match_operand:DI 0 "register_operand" "=r")
4687         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4688                  (match_operand:DI 2 "small_int_operand" "I")))]
4689   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4690   "smul\t%1, %2, %0"
4691   [(set_attr "type" "imul")])
4693 (define_expand "smulsi3_highpart"
4694   [(set (match_operand:SI 0 "register_operand" "")
4695         (truncate:SI
4696           (lshiftrt:DI
4697             (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4698                      (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
4699             (const_int 32))))]
4700   "TARGET_HARD_MUL && TARGET_ARCH32"
4702   if (CONSTANT_P (operands[2]))
4703     {
4704       if (TARGET_V8PLUS)
4705         {
4706           emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
4707                                                         operands[1],
4708                                                         operands[2],
4709                                                         GEN_INT (32)));
4710           DONE;
4711         }
4712       emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
4713       DONE;
4714     }
4715   if (TARGET_V8PLUS)
4716     {
4717       emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
4718                                               operands[2], GEN_INT (32)));
4719       DONE;
4720     }
4723 (define_insn "smulsi3_highpart_v8plus"
4724   [(set (match_operand:SI 0 "register_operand" "=h,r")
4725         (truncate:SI
4726           (lshiftrt:DI
4727             (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4728                      (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4729             (match_operand:SI 3 "small_int_operand" "I,I"))))
4730    (clobber (match_scratch:SI 4 "=X,&h"))]
4731   "TARGET_V8PLUS"
4732   "@
4733    smul\t%1, %2, %0\;srlx\t%0, %3, %0
4734    smul\t%1, %2, %4\;srlx\t%4, %3, %0"
4735   [(set_attr "type" "multi")
4736    (set_attr "length" "2")])
4738 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
4739 (define_insn ""
4740   [(set (match_operand:SI 0 "register_operand" "=h,r")
4741         (subreg:SI
4742           (lshiftrt:DI
4743             (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4744                      (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4745             (match_operand:SI 3 "small_int_operand" "I,I")) 4))
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 "const_smulsi3_highpart_v8plus"
4755   [(set (match_operand:SI 0 "register_operand" "=h,r")
4756         (truncate:SI
4757           (lshiftrt:DI
4758             (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4759                      (match_operand:DI 2 "small_int_operand" "I,I"))
4760           (match_operand:SI 3 "small_int_operand" "I,I"))))
4761    (clobber (match_scratch:SI 4 "=X,&h"))]
4762   "TARGET_V8PLUS"
4763   "@
4764    smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4765    smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4766   [(set_attr "type" "multi")
4767    (set_attr "length" "2")])
4769 (define_insn "*smulsi3_highpart_sp32"
4770   [(set (match_operand:SI 0 "register_operand" "=r")
4771         (truncate:SI
4772           (lshiftrt:DI
4773             (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4774                      (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
4775           (const_int 32))))]
4776   "TARGET_HARD_MUL32"
4777   "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4778   [(set_attr "type" "multi")
4779    (set_attr "length" "2")])
4781 (define_insn "const_smulsi3_highpart"
4782   [(set (match_operand:SI 0 "register_operand" "=r")
4783         (truncate:SI
4784           (lshiftrt:DI
4785             (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4786                      (match_operand:DI 2 "small_int_operand" "i"))
4787             (const_int 32))))]
4788   "TARGET_HARD_MUL32"
4789   "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4790   [(set_attr "type" "multi")
4791    (set_attr "length" "2")])
4793 (define_expand "umulsidi3"
4794   [(set (match_operand:DI 0 "register_operand" "")
4795         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4796                  (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
4797   "TARGET_HARD_MUL"
4799   if (CONSTANT_P (operands[2]))
4800     {
4801       if (TARGET_V8PLUS)
4802         emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
4803                                                operands[2]));
4804       else if (TARGET_ARCH32)
4805         emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
4806                                              operands[2]));
4807       else 
4808         emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
4809                                              operands[2]));
4810       DONE;
4811     }
4812   if (TARGET_V8PLUS)
4813     {
4814       emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
4815       DONE;
4816     }
4819 (define_insn "umulsidi3_v8plus"
4820   [(set (match_operand:DI 0 "register_operand" "=h,r")
4821         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4822                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4823    (clobber (match_scratch:SI 3 "=X,&h"))]
4824   "TARGET_V8PLUS"
4825   "@
4826    umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4827    umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4828   [(set_attr "type" "multi")
4829    (set_attr "length" "2,3")])
4831 (define_insn "*umulsidi3_sp32"
4832   [(set (match_operand:DI 0 "register_operand" "=r")
4833         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4834                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4835   "TARGET_HARD_MUL32"
4837   return TARGET_SPARCLET
4838          ? "umuld\t%1, %2, %L0"
4839          : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
4841   [(set (attr "type")
4842         (if_then_else (eq_attr "isa" "sparclet")
4843                       (const_string "imul") (const_string "multi")))
4844    (set (attr "length")
4845         (if_then_else (eq_attr "isa" "sparclet")
4846                       (const_int 1) (const_int 2)))])
4848 (define_insn "*umulsidi3_sp64"
4849   [(set (match_operand:DI 0 "register_operand" "=r")
4850         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4851                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4852   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4853   "umul\t%1, %2, %0"
4854   [(set_attr "type" "imul")])
4856 ;; Extra pattern, because sign_extend of a constant isn't valid.
4858 (define_insn "const_umulsidi3_sp32"
4859   [(set (match_operand:DI 0 "register_operand" "=r")
4860         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4861                  (match_operand:DI 2 "uns_small_int_operand" "")))]
4862   "TARGET_HARD_MUL32"
4864   return TARGET_SPARCLET
4865          ? "umuld\t%1, %s2, %L0"
4866          : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
4868   [(set (attr "type")
4869         (if_then_else (eq_attr "isa" "sparclet")
4870                       (const_string "imul") (const_string "multi")))
4871    (set (attr "length")
4872         (if_then_else (eq_attr "isa" "sparclet")
4873                       (const_int 1) (const_int 2)))])
4875 (define_insn "const_umulsidi3_sp64"
4876   [(set (match_operand:DI 0 "register_operand" "=r")
4877         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4878                  (match_operand:DI 2 "uns_small_int_operand" "")))]
4879   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4880   "umul\t%1, %s2, %0"
4881   [(set_attr "type" "imul")])
4883 (define_insn "const_umulsidi3_v8plus"
4884   [(set (match_operand:DI 0 "register_operand" "=h,r")
4885         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4886                  (match_operand:DI 2 "uns_small_int_operand" "")))
4887    (clobber (match_scratch:SI 3 "=X,h"))]
4888   "TARGET_V8PLUS"
4889   "@
4890    umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
4891    umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4892   [(set_attr "type" "multi")
4893    (set_attr "length" "2,3")])
4895 (define_expand "umulsi3_highpart"
4896   [(set (match_operand:SI 0 "register_operand" "")
4897         (truncate:SI
4898           (lshiftrt:DI
4899             (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4900                      (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
4901           (const_int 32))))]
4902   "TARGET_HARD_MUL && TARGET_ARCH32"
4904   if (CONSTANT_P (operands[2]))
4905     {
4906       if (TARGET_V8PLUS)
4907         {
4908           emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
4909                                                         operands[1],
4910                                                         operands[2],
4911                                                         GEN_INT (32)));
4912           DONE;
4913         }
4914       emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
4915       DONE;
4916     }
4917   if (TARGET_V8PLUS)
4918     {
4919       emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
4920                                               operands[2], GEN_INT (32)));
4921       DONE;
4922     }
4925 (define_insn "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                      (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
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, %2, %0\n\tsrlx\t%0, %3, %0
4936    umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4937   [(set_attr "type" "multi")
4938    (set_attr "length" "2")])
4940 (define_insn "const_umulsi3_highpart_v8plus"
4941   [(set (match_operand:SI 0 "register_operand" "=h,r")
4942         (truncate:SI
4943           (lshiftrt:DI
4944             (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4945                      (match_operand:DI 2 "uns_small_int_operand" ""))
4946             (match_operand:SI 3 "small_int_operand" "I,I"))))
4947    (clobber (match_scratch:SI 4 "=X,h"))]
4948   "TARGET_V8PLUS"
4949   "@
4950    umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
4951    umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
4952   [(set_attr "type" "multi")
4953    (set_attr "length" "2")])
4955 (define_insn "*umulsi3_highpart_sp32"
4956   [(set (match_operand:SI 0 "register_operand" "=r")
4957         (truncate:SI
4958           (lshiftrt:DI
4959             (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4960                      (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
4961             (const_int 32))))]
4962   "TARGET_HARD_MUL32"
4963   "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
4964   [(set_attr "type" "multi")
4965    (set_attr "length" "2")])
4967 (define_insn "const_umulsi3_highpart"
4968   [(set (match_operand:SI 0 "register_operand" "=r")
4969         (truncate:SI
4970           (lshiftrt:DI
4971             (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4972                      (match_operand:DI 2 "uns_small_int_operand" ""))
4973             (const_int 32))))]
4974   "TARGET_HARD_MUL32"
4975   "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
4976   [(set_attr "type" "multi")
4977    (set_attr "length" "2")])
4980 (define_expand "umulxhi_vis"
4981   [(set (match_operand:DI 0 "register_operand" "")
4982         (truncate:DI
4983           (lshiftrt:TI
4984             (mult:TI (zero_extend:TI (match_operand:DI 1 "arith_operand" ""))
4985                      (zero_extend:TI (match_operand:DI 2 "arith_operand" "")))
4986           (const_int 64))))]
4987  "TARGET_VIS3"
4989   if (TARGET_ARCH32)
4990     {
4991       emit_insn (gen_umulxhi_v8plus (operands[0], operands[1], operands[2]));
4992       DONE;
4993     }
4996 (define_insn "*umulxhi_sp64"
4997   [(set (match_operand:DI 0 "register_operand" "=r")
4998         (truncate:DI
4999           (lshiftrt:TI
5000             (mult:TI (zero_extend:TI (match_operand:DI 1 "arith_operand" "%r"))
5001                      (zero_extend:TI (match_operand:DI 2 "arith_operand" "rI")))
5002           (const_int 64))))]
5003   "TARGET_VIS3 && TARGET_ARCH64"
5004   "umulxhi\t%1, %2, %0"
5005   [(set_attr "type" "imul")])
5007 (define_insn "umulxhi_v8plus"
5008   [(set (match_operand:DI 0 "register_operand" "=r,h")
5009         (truncate:DI
5010           (lshiftrt:TI
5011             (mult:TI (zero_extend:TI (match_operand:DI 1 "arith_operand" "%r,0"))
5012                      (zero_extend:TI (match_operand:DI 2 "arith_operand" "rI,rI")))
5013           (const_int 64))))
5014    (clobber (match_scratch:SI 3 "=&h,X"))
5015    (clobber (match_scratch:SI 4 "=&h,X"))]
5016   "TARGET_VIS3 && TARGET_ARCH32"
5018   return output_v8plus_mult (insn, operands, \"umulxhi\");
5020   [(set_attr "type" "imul")
5021    (set_attr "length" "9,8")])
5023 (define_expand "xmulx_vis"
5024   [(set (match_operand:DI 0 "register_operand" "")
5025         (truncate:DI
5026           (unspec:TI [(zero_extend:TI (match_operand:DI 1 "arith_operand" ""))
5027                       (zero_extend:TI (match_operand:DI 2 "arith_operand" ""))]
5028                      UNSPEC_XMUL)))]
5029   "TARGET_VIS3"
5031   if (TARGET_ARCH32)
5032     {
5033       emit_insn (gen_xmulx_v8plus (operands[0], operands[1], operands[2]));
5034       DONE;
5035     }
5038 (define_insn "*xmulx_sp64"
5039   [(set (match_operand:DI 0 "register_operand" "=r")
5040         (truncate:DI
5041           (unspec:TI [(zero_extend:TI (match_operand:DI 1 "arith_operand" "%r"))
5042                       (zero_extend:TI (match_operand:DI 2 "arith_operand" "rI"))]
5043                      UNSPEC_XMUL)))]
5044   "TARGET_VIS3 && TARGET_ARCH64"
5045   "xmulx\t%1, %2, %0"
5046   [(set_attr "type" "imul")])
5048 (define_insn "xmulx_v8plus"
5049   [(set (match_operand:DI 0 "register_operand" "=r,h")
5050         (truncate:DI
5051           (unspec:TI [(zero_extend:TI (match_operand:DI 1 "arith_operand" "%r,0"))
5052                       (zero_extend:TI (match_operand:DI 2 "arith_operand" "rI,rI"))]
5053                      UNSPEC_XMUL)))
5054    (clobber (match_scratch:SI 3 "=&h,X"))
5055    (clobber (match_scratch:SI 4 "=&h,X"))]
5056   "TARGET_VIS3 && TARGET_ARCH32"
5058   return output_v8plus_mult (insn, operands, \"xmulx\");
5060   [(set_attr "type" "imul")
5061    (set_attr "length" "9,8")])
5063 (define_expand "xmulxhi_vis"
5064   [(set (match_operand:DI 0 "register_operand" "")
5065         (truncate:DI
5066           (lshiftrt:TI
5067              (unspec:TI [(zero_extend:TI (match_operand:DI 1 "arith_operand" ""))
5068                          (zero_extend:TI (match_operand:DI 2 "arith_operand" ""))]
5069                         UNSPEC_XMUL)
5070           (const_int 64))))]
5071   "TARGET_VIS3"
5073   if (TARGET_ARCH32)
5074     {
5075       emit_insn (gen_xmulxhi_v8plus (operands[0], operands[1], operands[2]));
5076       DONE;
5077     }
5080 (define_insn "*xmulxhi_sp64"
5081   [(set (match_operand:DI 0 "register_operand" "=r")
5082         (truncate:DI
5083           (lshiftrt:TI
5084             (unspec:TI [(zero_extend:TI (match_operand:DI 1 "arith_operand" "%r"))
5085                         (zero_extend:TI (match_operand:DI 2 "arith_operand" "rI"))]
5086                        UNSPEC_XMUL)
5087             (const_int 64))))]
5088   "TARGET_VIS3 && TARGET_ARCH64"
5089   "xmulxhi\t%1, %2, %0"
5090   [(set_attr "type" "imul")])
5092 (define_insn "xmulxhi_v8plus"
5093   [(set (match_operand:DI 0 "register_operand" "=r,h")
5094         (truncate:DI
5095           (lshiftrt:TI
5096             (unspec:TI [(zero_extend:TI (match_operand:DI 1 "arith_operand" "%r,0"))
5097                         (zero_extend:TI (match_operand:DI 2 "arith_operand" "rI,rI"))]
5098                        UNSPEC_XMUL)
5099           (const_int 64))))
5100    (clobber (match_scratch:SI 3 "=&h,X"))
5101    (clobber (match_scratch:SI 4 "=&h,X"))]
5102   "TARGET_VIS3 && TARGET_ARCH32"
5104   return output_v8plus_mult (insn, operands, \"xmulxhi\");
5106   [(set_attr "type" "imul")
5107    (set_attr "length" "9,8")])
5109 (define_expand "divsi3"
5110   [(parallel [(set (match_operand:SI 0 "register_operand" "")
5111                    (div:SI (match_operand:SI 1 "register_operand" "")
5112                            (match_operand:SI 2 "input_operand" "")))
5113               (clobber (match_scratch:SI 3 ""))])]
5114   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5116   if (TARGET_ARCH64)
5117     {
5118       operands[3] = gen_reg_rtx(SImode);
5119       emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
5120       emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
5121                                   operands[3]));
5122       DONE;
5123     }
5126 ;; The V8 architecture specifies that there must be at least 3 instructions
5127 ;; between a write to the Y register and a use of it for correct results.
5128 ;; We try to fill one of them with a simple constant or a memory load.
5130 (define_insn "divsi3_sp32"
5131   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
5132         (div:SI (match_operand:SI 1 "register_operand" "r,r,r")
5133                 (match_operand:SI 2 "input_operand" "rI,K,m")))
5134    (clobber (match_scratch:SI 3 "=&r,&r,&r"))]
5135   "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
5137   output_asm_insn ("sra\t%1, 31, %3", operands);
5138   output_asm_insn ("wr\t%3, 0, %%y", operands);
5140   switch (which_alternative)
5141     {
5142     case 0:
5143       if (TARGET_V9)
5144         return "sdiv\t%1, %2, %0";
5145       else
5146         return "nop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
5147     case 1:
5148       if (TARGET_V9)
5149         return "sethi\t%%hi(%a2), %3\n\tsdiv\t%1, %3, %0";
5150       else
5151         return "sethi\t%%hi(%a2), %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
5152     case 2:
5153       if (TARGET_V9)
5154         return "ld\t%2, %3\n\tsdiv\t%1, %3, %0";
5155       else
5156         return "ld\t%2, %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
5157     default:
5158       gcc_unreachable ();
5159     }
5161   [(set_attr "type" "multi")
5162    (set (attr "length")
5163         (if_then_else (eq_attr "isa" "v9")
5164                       (const_int 4) (const_int 6)))])
5166 (define_insn "divsi3_sp64"
5167   [(set (match_operand:SI 0 "register_operand" "=r")
5168         (div:SI (match_operand:SI 1 "register_operand" "r")
5169                 (match_operand:SI 2 "input_operand" "rI")))
5170    (use (match_operand:SI 3 "register_operand" "r"))]
5171   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5172   "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
5173   [(set_attr "type" "multi")
5174    (set_attr "length" "2")])
5176 (define_insn "divdi3"
5177   [(set (match_operand:DI 0 "register_operand" "=r")
5178         (div:DI (match_operand:DI 1 "register_operand" "r")
5179                 (match_operand:DI 2 "arith_operand" "rI")))]
5180   "TARGET_ARCH64"
5181   "sdivx\t%1, %2, %0"
5182   [(set_attr "type" "idiv")])
5184 (define_insn "*cmp_sdiv_cc_set"
5185   [(set (reg:CC CC_REG)
5186         (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
5187                             (match_operand:SI 2 "arith_operand" "rI"))
5188                     (const_int 0)))
5189    (set (match_operand:SI 0 "register_operand" "=r")
5190         (div:SI (match_dup 1) (match_dup 2)))
5191    (clobber (match_scratch:SI 3 "=&r"))]
5192   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5194   output_asm_insn ("sra\t%1, 31, %3", operands);
5195   output_asm_insn ("wr\t%3, 0, %%y", operands);
5197   if (TARGET_V9)
5198     return "sdivcc\t%1, %2, %0";
5199   else
5200     return "nop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
5202   [(set_attr "type" "multi")
5203    (set (attr "length")
5204         (if_then_else (eq_attr "isa" "v9")
5205                       (const_int 3) (const_int 6)))])
5207 (define_expand "udivsi3"
5208   [(set (match_operand:SI 0 "register_operand" "")
5209         (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "")
5210                  (match_operand:SI 2 "input_operand" "")))]
5211   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5212   "")
5214 ;; The V8 architecture specifies that there must be at least 3 instructions
5215 ;; between a write to the Y register and a use of it for correct results.
5216 ;; We try to fill one of them with a simple constant or a memory load.
5218 (define_insn "udivsi3_sp32"
5219   [(set (match_operand:SI 0 "register_operand" "=r,&r,&r,&r")
5220         (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r,r,r,m")
5221                  (match_operand:SI 2 "input_operand" "rI,K,m,r")))]
5222   "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
5224   output_asm_insn ("wr\t%%g0, 0, %%y", operands);
5226   switch (which_alternative)
5227     {
5228     case 0:
5229       if (TARGET_V9)
5230         return "udiv\t%1, %2, %0";
5231       else
5232         return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
5233     case 1:
5234       if (TARGET_V9)
5235         return "sethi\t%%hi(%a2), %0\n\tudiv\t%1, %0, %0";
5236       else
5237         return "sethi\t%%hi(%a2), %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
5238     case 2:
5239       if (TARGET_V9)
5240         return "ld\t%2, %0\n\tudiv\t%1, %0, %0";
5241       else
5242         return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
5243     case 3:
5244       if (TARGET_V9)
5245         return "ld\t%1, %0\n\tudiv\t%0, %2, %0";
5246       else
5247         return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
5248     default:
5249       gcc_unreachable ();
5250     }
5252   [(set_attr "type" "multi")
5253    (set (attr "length")
5254         (if_then_else (eq_attr "isa" "v9")
5255                       (const_int 3) (const_int 5)))])
5257 (define_insn "udivsi3_sp64"
5258   [(set (match_operand:SI 0 "register_operand" "=r")
5259         (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r")
5260                  (match_operand:SI 2 "input_operand" "rI")))]
5261   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5262   "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
5263   [(set_attr "type" "multi")
5264    (set_attr "length" "2")])
5266 (define_insn "udivdi3"
5267   [(set (match_operand:DI 0 "register_operand" "=r")
5268         (udiv:DI (match_operand:DI 1 "register_operand" "r")
5269                  (match_operand:DI 2 "arith_operand" "rI")))]
5270   "TARGET_ARCH64"
5271   "udivx\t%1, %2, %0"
5272   [(set_attr "type" "idiv")])
5274 (define_insn "*cmp_udiv_cc_set"
5275   [(set (reg:CC CC_REG)
5276         (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
5277                              (match_operand:SI 2 "arith_operand" "rI"))
5278                     (const_int 0)))
5279    (set (match_operand:SI 0 "register_operand" "=r")
5280         (udiv:SI (match_dup 1) (match_dup 2)))]
5281   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5283   output_asm_insn ("wr\t%%g0, 0, %%y", operands);
5285   if (TARGET_V9)
5286     return "udivcc\t%1, %2, %0";
5287   else
5288     return "nop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
5290   [(set_attr "type" "multi")
5291    (set (attr "length")
5292         (if_then_else (eq_attr "isa" "v9")
5293                       (const_int 2) (const_int 5)))])
5296 ;; SPARClet multiply/accumulate insns
5298 (define_insn "*smacsi"
5299   [(set (match_operand:SI 0 "register_operand" "=r")
5300         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
5301                           (match_operand:SI 2 "arith_operand" "rI"))
5302                  (match_operand:SI 3 "register_operand" "0")))]
5303   "TARGET_SPARCLET"
5304   "smac\t%1, %2, %0"
5305   [(set_attr "type" "imul")])
5307 (define_insn "*smacdi"
5308   [(set (match_operand:DI 0 "register_operand" "=r")
5309         (plus:DI (mult:DI (sign_extend:DI
5310                            (match_operand:SI 1 "register_operand" "%r"))
5311                           (sign_extend:DI
5312                            (match_operand:SI 2 "register_operand" "r")))
5313                  (match_operand:DI 3 "register_operand" "0")))]
5314   "TARGET_SPARCLET"
5315   "smacd\t%1, %2, %L0"
5316   [(set_attr "type" "imul")])
5318 (define_insn "*umacdi"
5319   [(set (match_operand:DI 0 "register_operand" "=r")
5320         (plus:DI (mult:DI (zero_extend:DI
5321                            (match_operand:SI 1 "register_operand" "%r"))
5322                           (zero_extend:DI
5323                            (match_operand:SI 2 "register_operand" "r")))
5324                  (match_operand:DI 3 "register_operand" "0")))]
5325   "TARGET_SPARCLET"
5326   "umacd\t%1, %2, %L0"
5327   [(set_attr "type" "imul")])
5330 ;; Boolean instructions.
5332 (define_insn "anddi3"
5333   [(set (match_operand:DI 0 "register_operand" "=r")
5334         (and:DI (match_operand:DI 1 "arith_operand" "%r")
5335                 (match_operand:DI 2 "arith_operand" "rI")))]
5336   "TARGET_ARCH64"
5337   "and\t%1, %2, %0")
5339 (define_insn "andsi3"
5340   [(set (match_operand:SI 0 "register_operand" "=r")
5341         (and:SI (match_operand:SI 1 "arith_operand" "%r")
5342                 (match_operand:SI 2 "arith_operand" "rI")))]
5343   ""
5344   "and\t%1, %2, %0")
5346 (define_split
5347   [(set (match_operand:SI 0 "register_operand" "")
5348         (and:SI (match_operand:SI 1 "register_operand" "")
5349                 (match_operand:SI 2 "const_compl_high_operand" "")))
5350    (clobber (match_operand:SI 3 "register_operand" ""))]
5351   ""
5352   [(set (match_dup 3) (match_dup 4))
5353    (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
5355   operands[4] = GEN_INT (~INTVAL (operands[2]));
5358 (define_insn "*and_not_di_sp64"
5359   [(set (match_operand:DI 0 "register_operand" "=r")
5360         (and:DI (not:DI (match_operand:DI 1 "register_operand" "%r"))
5361                 (match_operand:DI 2 "register_operand" "r")))]
5362   "TARGET_ARCH64"
5363   "andn\t%2, %1, %0")
5365 (define_insn "*and_not_si"
5366   [(set (match_operand:SI 0 "register_operand" "=r")
5367         (and:SI (not:SI (match_operand:SI 1 "register_operand" "%r"))
5368                 (match_operand:SI 2 "register_operand" "r")))]
5369   ""
5370   "andn\t%2, %1, %0")
5372 (define_insn "iordi3"
5373   [(set (match_operand:DI 0 "register_operand" "=r")
5374         (ior:DI (match_operand:DI 1 "arith_operand" "%r")
5375                 (match_operand:DI 2 "arith_operand" "rI")))]
5376   "TARGET_ARCH64"
5377   "or\t%1, %2, %0")
5379 (define_insn "iorsi3"
5380   [(set (match_operand:SI 0 "register_operand" "=r")
5381         (ior:SI (match_operand:SI 1 "arith_operand" "%r")
5382                 (match_operand:SI 2 "arith_operand" "rI")))]
5383   ""
5384   "or\t%1, %2, %0")
5386 (define_split
5387   [(set (match_operand:SI 0 "register_operand" "")
5388         (ior:SI (match_operand:SI 1 "register_operand" "")
5389                 (match_operand:SI 2 "const_compl_high_operand" "")))
5390    (clobber (match_operand:SI 3 "register_operand" ""))]
5391   ""
5392   [(set (match_dup 3) (match_dup 4))
5393    (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
5395   operands[4] = gen_int_mode (~INTVAL (operands[2]), SImode);
5398 (define_insn "*or_not_di_sp64"
5399   [(set (match_operand:DI 0 "register_operand" "=r")
5400         (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
5401                 (match_operand:DI 2 "register_operand" "r")))]
5402   "TARGET_ARCH64"
5403   "orn\t%2, %1, %0")
5405 (define_insn "*or_not_si"
5406   [(set (match_operand:SI 0 "register_operand" "=r")
5407         (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
5408                 (match_operand:SI 2 "register_operand" "r")))]
5409   ""
5410   "orn\t%2, %1, %0")
5412 (define_insn "xordi3"
5413   [(set (match_operand:DI 0 "register_operand" "=r")
5414         (xor:DI (match_operand:DI 1 "arith_operand" "%rJ")
5415                 (match_operand:DI 2 "arith_operand" "rI")))]
5416   "TARGET_ARCH64"
5417   "xor\t%r1, %2, %0")
5419 (define_insn "xorsi3"
5420   [(set (match_operand:SI 0 "register_operand" "=r")
5421         (xor:SI (match_operand:SI 1 "arith_operand" "%rJ")
5422                   (match_operand:SI 2 "arith_operand" "rI")))]
5423   ""
5424   "xor\t%r1, %2, %0")
5426 (define_split
5427   [(set (match_operand:SI 0 "register_operand" "")
5428         (xor:SI (match_operand:SI 1 "register_operand" "")
5429                 (match_operand:SI 2 "const_compl_high_operand" "")))
5430    (clobber (match_operand:SI 3 "register_operand" ""))]
5431    ""
5432   [(set (match_dup 3) (match_dup 4))
5433    (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
5435   operands[4] = gen_int_mode (~INTVAL (operands[2]), SImode);
5438 (define_split
5439   [(set (match_operand:SI 0 "register_operand" "")
5440         (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
5441                         (match_operand:SI 2 "const_compl_high_operand" ""))))
5442    (clobber (match_operand:SI 3 "register_operand" ""))]
5443   ""
5444   [(set (match_dup 3) (match_dup 4))
5445    (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
5447   operands[4] = gen_int_mode (~INTVAL (operands[2]), SImode);
5450 (define_insn "*xor_not_di_sp64"
5451   [(set (match_operand:DI 0 "register_operand" "=r")
5452         (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
5453                         (match_operand:DI 2 "arith_operand" "rI"))))]
5454   "TARGET_ARCH64"
5455   "xnor\t%r1, %2, %0")
5457 (define_insn "*xor_not_si"
5458   [(set (match_operand:SI 0 "register_operand" "=r")
5459         (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
5460                         (match_operand:SI 2 "arith_operand" "rI"))))]
5461   ""
5462   "xnor\t%r1, %2, %0")
5464 ;; These correspond to the above in the case where we also (or only)
5465 ;; want to set the condition code.  
5467 (define_insn "*cmp_cc_arith_op"
5468   [(set (reg:CC CC_REG)
5469         (compare:CC (match_operator:SI 2 "cc_arith_operator"
5470                      [(match_operand:SI 0 "arith_operand" "%r")
5471                       (match_operand:SI 1 "arith_operand" "rI")])
5472          (const_int 0)))]
5473   ""
5474   "%A2cc\t%0, %1, %%g0"
5475   [(set_attr "type" "compare")])
5477 (define_insn "*cmp_ccx_arith_op"
5478   [(set (reg:CCX CC_REG)
5479         (compare:CCX (match_operator:DI 2 "cc_arith_operator"
5480                       [(match_operand:DI 0 "arith_operand" "%r")
5481                        (match_operand:DI 1 "arith_operand" "rI")])
5482          (const_int 0)))]
5483   "TARGET_ARCH64"
5484   "%A2cc\t%0, %1, %%g0"
5485   [(set_attr "type" "compare")])
5487 (define_insn "*cmp_cc_arith_op_set"
5488   [(set (reg:CC CC_REG)
5489         (compare:CC (match_operator:SI 3 "cc_arith_operator"
5490                      [(match_operand:SI 1 "arith_operand" "%r")
5491                       (match_operand:SI 2 "arith_operand" "rI")])
5492          (const_int 0)))
5493    (set (match_operand:SI 0 "register_operand" "=r")
5494         (match_operator:SI 4 "cc_arith_operator"
5495          [(match_dup 1) (match_dup 2)]))]
5496   "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5497   "%A3cc\t%1, %2, %0"
5498   [(set_attr "type" "compare")])
5500 (define_insn "*cmp_ccx_arith_op_set"
5501   [(set (reg:CCX CC_REG)
5502         (compare:CCX (match_operator:DI 3 "cc_arith_operator"
5503                       [(match_operand:DI 1 "arith_operand" "%r")
5504                        (match_operand:DI 2 "arith_operand" "rI")])
5505          (const_int 0)))
5506    (set (match_operand:DI 0 "register_operand" "=r")
5507         (match_operator:DI 4 "cc_arith_operator"
5508          [(match_dup 1) (match_dup 2)]))]
5509   "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5510   "%A3cc\t%1, %2, %0"
5511   [(set_attr "type" "compare")])
5513 (define_insn "*cmp_cc_xor_not"
5514   [(set (reg:CC CC_REG)
5515         (compare:CC
5516          (not:SI (xor:SI (match_operand:SI 0 "register_or_zero_operand" "%rJ")
5517                          (match_operand:SI 1 "arith_operand" "rI")))
5518          (const_int 0)))]
5519   ""
5520   "xnorcc\t%r0, %1, %%g0"
5521   [(set_attr "type" "compare")])
5523 (define_insn "*cmp_ccx_xor_not"
5524   [(set (reg:CCX CC_REG)
5525         (compare:CCX
5526          (not:DI (xor:DI (match_operand:DI 0 "register_or_zero_operand" "%rJ")
5527                          (match_operand:DI 1 "arith_operand" "rI")))
5528          (const_int 0)))]
5529   "TARGET_ARCH64"
5530   "xnorcc\t%r0, %1, %%g0"
5531   [(set_attr "type" "compare")])
5533 (define_insn "*cmp_cc_xor_not_set"
5534   [(set (reg:CC CC_REG)
5535         (compare:CC
5536          (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
5537                          (match_operand:SI 2 "arith_operand" "rI")))
5538          (const_int 0)))
5539    (set (match_operand:SI 0 "register_operand" "=r")
5540         (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
5541   ""
5542   "xnorcc\t%r1, %2, %0"
5543   [(set_attr "type" "compare")])
5545 (define_insn "*cmp_ccx_xor_not_set"
5546   [(set (reg:CCX CC_REG)
5547         (compare:CCX
5548          (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
5549                          (match_operand:DI 2 "arith_operand" "rI")))
5550          (const_int 0)))
5551    (set (match_operand:DI 0 "register_operand" "=r")
5552         (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
5553   "TARGET_ARCH64"
5554   "xnorcc\t%r1, %2, %0"
5555   [(set_attr "type" "compare")])
5557 (define_insn "*cmp_cc_arith_op_not"
5558   [(set (reg:CC CC_REG)
5559         (compare:CC (match_operator:SI 2 "cc_arith_not_operator"
5560                      [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
5561                       (match_operand:SI 1 "register_or_zero_operand" "rJ")])
5562          (const_int 0)))]
5563   ""
5564   "%B2cc\t%r1, %0, %%g0"
5565   [(set_attr "type" "compare")])
5567 (define_insn "*cmp_ccx_arith_op_not"
5568   [(set (reg:CCX CC_REG)
5569         (compare:CCX (match_operator:DI 2 "cc_arith_not_operator"
5570                       [(not:DI (match_operand:DI 0 "arith_operand" "rI"))
5571                        (match_operand:DI 1 "register_or_zero_operand" "rJ")])
5572          (const_int 0)))]
5573   "TARGET_ARCH64"
5574   "%B2cc\t%r1, %0, %%g0"
5575   [(set_attr "type" "compare")])
5577 (define_insn "*cmp_cc_arith_op_not_set"
5578   [(set (reg:CC CC_REG)
5579         (compare:CC (match_operator:SI 3 "cc_arith_not_operator"
5580                      [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
5581                       (match_operand:SI 2 "register_or_zero_operand" "rJ")])
5582          (const_int 0)))
5583    (set (match_operand:SI 0 "register_operand" "=r")
5584         (match_operator:SI 4 "cc_arith_not_operator"
5585          [(not:SI (match_dup 1)) (match_dup 2)]))]
5586   "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5587   "%B3cc\t%r2, %1, %0"
5588   [(set_attr "type" "compare")])
5590 (define_insn "*cmp_ccx_arith_op_not_set"
5591   [(set (reg:CCX CC_REG)
5592         (compare:CCX (match_operator:DI 3 "cc_arith_not_operator"
5593                       [(not:DI (match_operand:DI 1 "arith_operand" "rI"))
5594                        (match_operand:DI 2 "register_or_zero_operand" "rJ")])
5595          (const_int 0)))
5596    (set (match_operand:DI 0 "register_operand" "=r")
5597         (match_operator:DI 4 "cc_arith_not_operator"
5598          [(not:DI (match_dup 1)) (match_dup 2)]))]
5599   "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5600   "%B3cc\t%r2, %1, %0"
5601   [(set_attr "type" "compare")])
5603 ;; We cannot use the "neg" pseudo insn because the Sun assembler
5604 ;; does not know how to make it work for constants.
5606 (define_expand "negdi2"
5607   [(set (match_operand:DI 0 "register_operand" "=r")
5608         (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5609   ""
5611   if (TARGET_ARCH32)
5612     {
5613       emit_insn (gen_negdi2_sp32 (operands[0], operands[1]));
5614       DONE;
5615     }
5618 (define_expand "unegvdi3"
5619   [(parallel [(set (reg:CCXC CC_REG)
5620                    (compare:CCXC (not:DI (match_operand:DI 1 "register_operand" ""))
5621                                  (const_int -1)))
5622               (set (match_operand:DI 0 "register_operand" "")
5623                    (neg:DI (match_dup 1)))])
5624    (set (pc)
5625         (if_then_else (ltu (reg:CCXC CC_REG) (const_int 0))
5626                       (label_ref (match_operand 2 ""))
5627                       (pc)))]
5628   ""
5630   if (TARGET_ARCH32)
5631     {
5632       emit_insn (gen_unegvdi3_sp32 (operands[0], operands[1]));
5633       rtx x = gen_rtx_LTU (VOIDmode, gen_rtx_REG (CCCmode, SPARC_ICC_REG),
5634                                      const0_rtx);
5635       emit_jump_insn (gen_cbranchcc4 (x, XEXP (x, 0), XEXP (x, 1), operands[2]));
5636       DONE;
5637     }
5640 (define_expand "negvdi3"
5641   [(parallel [(set (reg:CCXV CC_REG)
5642                    (compare:CCXV (neg:DI (match_operand:DI 1 "register_operand" ""))
5643                                  (unspec:DI [(match_dup 1)] UNSPEC_NEGV)))
5644               (set (match_operand:DI 0 "register_operand" "")
5645                    (neg:DI (match_dup 1)))])
5646    (set (pc)
5647         (if_then_else (ne (reg:CCXV CC_REG) (const_int 0))
5648                       (label_ref (match_operand 2 ""))
5649                       (pc)))]
5650   ""
5652   if (TARGET_ARCH32)
5653     {
5654       emit_insn (gen_negvdi3_sp32 (operands[0], operands[1]));
5655       rtx x = gen_rtx_NE (VOIDmode, gen_rtx_REG (CCVmode, SPARC_ICC_REG),
5656                                     const0_rtx);
5657       emit_jump_insn (gen_cbranchcc4 (x, XEXP (x, 0), XEXP (x, 1), operands[2]));
5658       DONE;
5659     }
5662 (define_insn_and_split "negdi2_sp32"
5663   [(set (match_operand:DI 0 "register_operand" "=&r")
5664         (neg:DI (match_operand:DI 1 "register_operand" "r")))
5665    (clobber (reg:CC CC_REG))]
5666   "TARGET_ARCH32"
5667   "#"
5668   "&& reload_completed"
5669   [(parallel [(set (reg:CCC CC_REG)
5670                    (compare:CCC (not:SI (match_dup 5)) (const_int -1)))
5671               (set (match_dup 4) (neg:SI (match_dup 5)))])
5672    (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
5673                                 (ltu:SI (reg:CCC CC_REG) (const_int 0))))]
5674   "operands[2] = gen_highpart (SImode, operands[0]);
5675    operands[3] = gen_highpart (SImode, operands[1]);
5676    operands[4] = gen_lowpart (SImode, operands[0]);
5677    operands[5] = gen_lowpart (SImode, operands[1]);"
5678   [(set_attr "length" "2")])
5680 (define_insn_and_split "unegvdi3_sp32"
5681   [(set (reg:CCC CC_REG)
5682         (compare:CCC (not:DI (match_operand:DI 1 "register_operand" "r"))
5683                      (const_int -1)))
5684    (set (match_operand:DI 0 "register_operand" "=&r")
5685         (neg:DI (match_dup 1)))]
5686   "TARGET_ARCH32"
5687   "#"
5688   "&& reload_completed"
5689   [(parallel [(set (reg:CCC CC_REG)
5690                    (compare:CCC (not:SI (match_dup 5)) (const_int -1)))
5691               (set (match_dup 4) (neg:SI (match_dup 5)))])
5692    (parallel [(set (reg:CCC CC_REG)
5693                    (compare:CCC (zero_extend:DI
5694                                   (neg:SI (plus:SI (match_dup 3)
5695                                                    (ltu:SI (reg:CCC CC_REG)
5696                                                            (const_int 0)))))
5697                                 (neg:DI (plus:DI (zero_extend:DI (match_dup 3))
5698                                                  (ltu:DI (reg:CCC CC_REG)
5699                                                          (const_int 0))))))
5700               (set (match_dup 2) (neg:SI (plus:SI (match_dup 3)
5701                                                   (ltu:SI (reg:CCC CC_REG)
5702                                                           (const_int 0)))))])]
5703   "operands[2] = gen_highpart (SImode, operands[0]);
5704    operands[3] = gen_highpart (SImode, operands[1]);
5705    operands[4] = gen_lowpart (SImode, operands[0]);
5706    operands[5] = gen_lowpart (SImode, operands[1]);"
5707   [(set_attr "length" "2")])
5709 (define_insn_and_split "negvdi3_sp32"
5710   [(set (reg:CCV CC_REG)
5711         (compare:CCV (neg:DI (match_operand:DI 1 "register_operand" "r"))
5712                      (unspec:DI [(match_dup 1)] UNSPEC_NEGV)))
5713    (set (match_operand:DI 0 "register_operand" "=&r")
5714         (neg:DI (match_dup 1)))]
5715   "TARGET_ARCH32"
5716   "#"
5717   "&& reload_completed"
5718   [(parallel [(set (reg:CCC CC_REG)
5719                    (compare:CCC (not:SI (match_dup 5)) (const_int -1)))
5720               (set (match_dup 4) (neg:SI (match_dup 5)))])
5721    (parallel [(set (reg:CCV CC_REG)
5722                    (compare:CCV (neg:SI (plus:SI (match_dup 3)
5723                                                  (ltu:SI (reg:CCC CC_REG)
5724                                                          (const_int 0))))
5725                                 (unspec:SI [(plus:SI (match_dup 3)
5726                                                      (ltu:SI (reg:CCC CC_REG)
5727                                                              (const_int 0)))]
5728                                            UNSPEC_NEGV)))
5729               (set (match_dup 2) (neg:SI (plus:SI (match_dup 3)
5730                                                   (ltu:SI (reg:CCC CC_REG)
5731                                                           (const_int 0)))))])]
5732   "operands[2] = gen_highpart (SImode, operands[0]);
5733    operands[3] = gen_highpart (SImode, operands[1]);
5734    operands[4] = gen_lowpart (SImode, operands[0]);
5735    operands[5] = gen_lowpart (SImode, operands[1]);"
5736   [(set_attr "length" "2")])
5738 (define_insn "*negdi2_sp64"
5739   [(set (match_operand:DI 0 "register_operand" "=r")
5740         (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5741   "TARGET_ARCH64"
5742   "sub\t%%g0, %1, %0")
5744 (define_insn "negsi2"
5745   [(set (match_operand:SI 0 "register_operand" "=r")
5746         (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
5747   ""
5748   "sub\t%%g0, %1, %0")
5750 (define_expand "unegvsi3"
5751   [(parallel [(set (reg:CCC CC_REG)
5752                    (compare:CCC (not:SI (match_operand:SI 1 "arith_operand" ""))
5753                                 (const_int -1)))
5754               (set (match_operand:SI 0 "register_operand" "")
5755                    (neg:SI (match_dup 1)))])
5756    (set (pc)
5757         (if_then_else (ltu (reg:CCC CC_REG) (const_int 0))
5758                       (label_ref (match_operand 2 ""))
5759                       (pc)))]
5760   "")
5762 (define_expand "negvsi3"
5763   [(parallel [(set (reg:CCV CC_REG)
5764                    (compare:CCV (neg:SI (match_operand:SI 1 "arith_operand" ""))
5765                                 (unspec:SI [(match_dup 1)] UNSPEC_NEGV)))
5766               (set (match_operand:SI 0 "register_operand" "")
5767                    (neg:SI (match_dup 1)))])
5768    (set (pc)
5769         (if_then_else (ne (reg:CCV CC_REG) (const_int 0))
5770                       (label_ref (match_operand 2 ""))
5771                       (pc)))]
5774 (define_insn "*cmp_ccnz_neg"
5775   [(set (reg:CCNZ CC_REG)
5776         (compare:CCNZ (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
5777                       (const_int 0)))]
5778   ""
5779   "subcc\t%%g0, %0, %%g0"
5780   [(set_attr "type" "compare")])
5782 (define_insn "*cmp_ccxnz_neg"
5783   [(set (reg:CCXNZ CC_REG)
5784         (compare:CCXNZ (neg:DI (match_operand:DI 0 "arith_operand" "rI"))
5785                        (const_int 0)))]
5786   "TARGET_ARCH64"
5787   "subcc\t%%g0, %0, %%g0"
5788   [(set_attr "type" "compare")])
5790 (define_insn "*cmp_ccnz_neg_set"
5791   [(set (reg:CCNZ CC_REG)
5792         (compare:CCNZ (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
5793                       (const_int 0)))
5794    (set (match_operand:SI 0 "register_operand" "=r")
5795         (neg:SI (match_dup 1)))]
5796   ""
5797   "subcc\t%%g0, %1, %0"
5798   [(set_attr "type" "compare")])
5800 (define_insn "*cmp_ccxnz_neg_set"
5801   [(set (reg:CCXNZ CC_REG)
5802         (compare:CCXNZ (neg:DI (match_operand:DI 1 "arith_operand" "rI"))
5803                        (const_int 0)))
5804    (set (match_operand:DI 0 "register_operand" "=r")
5805         (neg:DI (match_dup 1)))]
5806   "TARGET_ARCH64"
5807   "subcc\t%%g0, %1, %0"
5808   [(set_attr "type" "compare")])
5810 (define_insn "*cmp_ccc_neg_set"
5811   [(set (reg:CCC CC_REG)
5812         (compare:CCC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
5813                      (const_int -1)))
5814    (set (match_operand:SI 0 "register_operand" "=r")
5815         (neg:SI (match_dup 1)))]
5816   ""
5817   "subcc\t%%g0, %1, %0"
5818   [(set_attr "type" "compare")])
5820 (define_insn "*cmp_ccxc_neg_set"
5821   [(set (reg:CCXC CC_REG)
5822         (compare:CCXC (not:DI (match_operand:DI 1 "arith_operand" "rI"))
5823                       (const_int -1)))
5824    (set (match_operand:DI 0 "register_operand" "=r")
5825         (neg:DI (match_dup 1)))]
5826   "TARGET_ARCH64"
5827   "subcc\t%%g0, %1, %0"
5828   [(set_attr "type" "compare")])
5830 (define_insn "*cmp_ccc_neg_sltu_set"
5831   [(set (reg:CCC CC_REG)
5832         (compare:CCC (zero_extend:DI
5833                        (neg:SI (plus:SI (match_operand:SI 1 "arith_operand" "rI")
5834                                         (ltu:SI (reg:CCC CC_REG)
5835                                                 (const_int 0)))))
5836                      (neg:DI (plus:DI (zero_extend:DI (match_dup 1))
5837                                       (ltu:DI (reg:CCC CC_REG)
5838                                               (const_int 0))))))
5839    (set (match_operand:SI 0 "register_operand" "=r")
5840         (neg:SI (plus:SI (match_dup 1)
5841                          (ltu:SI (reg:CCC CC_REG) (const_int 0)))))]
5842   ""
5843   "subxcc\t%%g0, %1, %0"
5844   [(set_attr "type" "compare")])
5846 (define_insn "*cmp_ccv_neg"
5847   [(set (reg:CCV CC_REG)
5848         (compare:CCV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
5849                      (unspec:SI [(match_dup 0)] UNSPEC_NEGV)))]
5850   ""
5851   "subcc\t%%g0, %0, %%g0"
5852   [(set_attr "type" "compare")])
5854 (define_insn "*cmp_ccxv_neg"
5855   [(set (reg:CCXV CC_REG)
5856         (compare:CCXV (neg:DI (match_operand:DI 0 "arith_operand" "rI"))
5857                       (unspec:DI [(match_dup 0)] UNSPEC_NEGV)))]
5858   "TARGET_ARCH64"
5859   "subcc\t%%g0, %0, %%g0"
5860   [(set_attr "type" "compare")])
5862 (define_insn "*cmp_ccv_neg_set"
5863   [(set (reg:CCV CC_REG)
5864         (compare:CCV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
5865                      (unspec:SI [(match_dup 1)] UNSPEC_NEGV)))
5866    (set (match_operand:SI 0 "register_operand" "=r")
5867         (neg:SI (match_dup 1)))]
5868   ""
5869   "subcc\t%%g0, %1, %0"
5870   [(set_attr "type" "compare")])
5872 (define_insn "*cmp_ccxv_neg_set"
5873   [(set (reg:CCXV CC_REG)
5874         (compare:CCXV (neg:DI (match_operand:DI 1 "arith_operand" "rI"))
5875                       (unspec:DI [(match_dup 1)] UNSPEC_NEGV)))
5876    (set (match_operand:DI 0 "register_operand" "=r")
5877         (neg:DI (match_dup 1)))]
5878   "TARGET_ARCH64"
5879   "subcc\t%%g0, %1, %0"
5880   [(set_attr "type" "compare")])
5882 (define_insn "*cmp_ccv_neg_sltu_set"
5883   [(set (reg:CCV CC_REG)
5884         (compare:CCV (neg:SI (plus:SI (match_operand:SI 1 "arith_operand" "rI")
5885                                       (ltu:SI (reg:CCC CC_REG) (const_int 0))))
5886                      (unspec:SI [(plus:SI (match_dup 1)
5887                                           (ltu:SI (reg:CCC CC_REG)
5888                                                   (const_int 0)))]
5889                                 UNSPEC_NEGV)))
5890    (set (match_operand:SI 0 "register_operand" "=r")
5891         (neg:SI (plus:SI (match_dup 1)
5892                          (ltu:SI (reg:CCC CC_REG) (const_int 0)))))]
5893   ""
5894   "subxcc\t%%g0, %1, %0"
5895   [(set_attr "type" "compare")])
5898 (define_insn "one_cmpldi2"
5899   [(set (match_operand:DI 0 "register_operand" "=r")
5900         (not:DI (match_operand:DI 1 "arith_operand" "rI")))]
5901   "TARGET_ARCH64"
5902   "xnor\t%%g0, %1, %0")
5904 (define_insn "one_cmplsi2"
5905   [(set (match_operand:SI 0 "register_operand" "=r")
5906         (not:SI (match_operand:SI 1 "arith_operand" "rI")))]
5907   ""
5908   "xnor\t%%g0, %1, %0")
5910 (define_insn "*cmp_cc_not"
5911   [(set (reg:CC CC_REG)
5912         (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
5913                     (const_int 0)))]
5914   ""
5915   "xnorcc\t%%g0, %0, %%g0"
5916   [(set_attr "type" "compare")])
5918 (define_insn "*cmp_ccx_not"
5919   [(set (reg:CCX CC_REG)
5920         (compare:CCX (not:DI (match_operand:DI 0 "arith_operand" "rI"))
5921                      (const_int 0)))]
5922   "TARGET_ARCH64"
5923   "xnorcc\t%%g0, %0, %%g0"
5924   [(set_attr "type" "compare")])
5926 (define_insn "*cmp_cc_set_not"
5927   [(set (reg:CC CC_REG)
5928         (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
5929                     (const_int 0)))
5930    (set (match_operand:SI 0 "register_operand" "=r")
5931         (not:SI (match_dup 1)))]
5932   ""
5933   "xnorcc\t%%g0, %1, %0"
5934   [(set_attr "type" "compare")])
5936 (define_insn "*cmp_ccx_set_not"
5937   [(set (reg:CCX CC_REG)
5938         (compare:CCX (not:DI (match_operand:DI 1 "arith_operand" "rI"))
5939                     (const_int 0)))
5940    (set (match_operand:DI 0 "register_operand" "=r")
5941         (not:DI (match_dup 1)))]
5942   "TARGET_ARCH64"
5943   "xnorcc\t%%g0, %1, %0"
5944   [(set_attr "type" "compare")])
5946 (define_insn "*cmp_cc_set"
5947   [(set (match_operand:SI 0 "register_operand" "=r")
5948         (match_operand:SI 1 "register_operand" "r"))
5949    (set (reg:CC CC_REG)
5950         (compare:CC (match_dup 1) (const_int 0)))]
5951   ""
5952   "orcc\t%1, 0, %0"
5953   [(set_attr "type" "compare")])
5955 (define_insn "*cmp_ccx_set64"
5956   [(set (match_operand:DI 0 "register_operand" "=r")
5957         (match_operand:DI 1 "register_operand" "r"))
5958    (set (reg:CCX CC_REG)
5959         (compare:CCX (match_dup 1) (const_int 0)))]
5960   "TARGET_ARCH64"
5961   "orcc\t%1, 0, %0"
5962    [(set_attr "type" "compare")])
5965 ;; Floating point arithmetic instructions.
5967 (define_expand "addtf3"
5968   [(set (match_operand:TF 0 "nonimmediate_operand" "")
5969         (plus:TF (match_operand:TF 1 "general_operand" "")
5970                  (match_operand:TF 2 "general_operand" "")))]
5971   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5972   "emit_tfmode_binop (PLUS, operands); DONE;")
5974 (define_insn "*addtf3_hq"
5975   [(set (match_operand:TF 0 "register_operand" "=e")
5976         (plus:TF (match_operand:TF 1 "register_operand" "e")
5977                  (match_operand:TF 2 "register_operand" "e")))]
5978   "TARGET_FPU && TARGET_HARD_QUAD"
5979   "faddq\t%1, %2, %0"
5980   [(set_attr "type" "fp")])
5982 (define_insn "adddf3"
5983   [(set (match_operand:DF 0 "register_operand" "=e")
5984         (plus:DF (match_operand:DF 1 "register_operand" "e")
5985                  (match_operand:DF 2 "register_operand" "e")))]
5986   "TARGET_FPU"
5987   "faddd\t%1, %2, %0"
5988   [(set_attr "type" "fp")
5989    (set_attr "fptype" "double")])
5991 (define_insn "addsf3"
5992   [(set (match_operand:SF 0 "register_operand" "=f")
5993         (plus:SF (match_operand:SF 1 "register_operand" "f")
5994                  (match_operand:SF 2 "register_operand" "f")))]
5995   "TARGET_FPU"
5996   "fadds\t%1, %2, %0"
5997   [(set_attr "type" "fp")])
5999 (define_expand "subtf3"
6000   [(set (match_operand:TF 0 "nonimmediate_operand" "")
6001         (minus:TF (match_operand:TF 1 "general_operand" "")
6002                   (match_operand:TF 2 "general_operand" "")))]
6003   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6004   "emit_tfmode_binop (MINUS, operands); DONE;")
6006 (define_insn "*subtf3_hq"
6007   [(set (match_operand:TF 0 "register_operand" "=e")
6008         (minus:TF (match_operand:TF 1 "register_operand" "e")
6009                   (match_operand:TF 2 "register_operand" "e")))]
6010   "TARGET_FPU && TARGET_HARD_QUAD"
6011   "fsubq\t%1, %2, %0"
6012   [(set_attr "type" "fp")])
6014 (define_insn "subdf3"
6015   [(set (match_operand:DF 0 "register_operand" "=e")
6016         (minus:DF (match_operand:DF 1 "register_operand" "e")
6017                   (match_operand:DF 2 "register_operand" "e")))]
6018   "TARGET_FPU"
6019   "fsubd\t%1, %2, %0"
6020   [(set_attr "type" "fp")
6021    (set_attr "fptype" "double")])
6023 (define_insn "subsf3"
6024   [(set (match_operand:SF 0 "register_operand" "=f")
6025         (minus:SF (match_operand:SF 1 "register_operand" "f")
6026                   (match_operand:SF 2 "register_operand" "f")))]
6027   "TARGET_FPU"
6028   "fsubs\t%1, %2, %0"
6029   [(set_attr "type" "fp")])
6031 (define_expand "multf3"
6032   [(set (match_operand:TF 0 "nonimmediate_operand" "")
6033         (mult:TF (match_operand:TF 1 "general_operand" "")
6034                  (match_operand:TF 2 "general_operand" "")))]
6035   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6036   "emit_tfmode_binop (MULT, operands); DONE;")
6038 (define_insn "*multf3_hq"
6039   [(set (match_operand:TF 0 "register_operand" "=e")
6040         (mult:TF (match_operand:TF 1 "register_operand" "e")
6041                  (match_operand:TF 2 "register_operand" "e")))]
6042   "TARGET_FPU && TARGET_HARD_QUAD"
6043   "fmulq\t%1, %2, %0"
6044   [(set_attr "type" "fpmul")])
6046 (define_insn "muldf3"
6047   [(set (match_operand:DF 0 "register_operand" "=e")
6048         (mult:DF (match_operand:DF 1 "register_operand" "e")
6049                  (match_operand:DF 2 "register_operand" "e")))]
6050   "TARGET_FPU"
6051   "fmuld\t%1, %2, %0"
6052   [(set_attr "type" "fpmul")
6053    (set_attr "fptype" "double")])
6055 (define_insn "mulsf3"
6056   [(set (match_operand:SF 0 "register_operand" "=f")
6057         (mult:SF (match_operand:SF 1 "register_operand" "f")
6058                  (match_operand:SF 2 "register_operand" "f")))]
6059   "TARGET_FPU"
6060   "fmuls\t%1, %2, %0"
6061   [(set_attr "type" "fpmul")])
6063 (define_insn "fmadf4"
6064   [(set (match_operand:DF 0 "register_operand" "=e")
6065         (fma:DF (match_operand:DF 1 "register_operand" "e")
6066                 (match_operand:DF 2 "register_operand" "e")
6067                 (match_operand:DF 3 "register_operand" "e")))]
6068   "TARGET_FMAF"
6069   "fmaddd\t%1, %2, %3, %0"
6070   [(set_attr "type" "fpmul")])
6072 (define_insn "fmsdf4"
6073   [(set (match_operand:DF 0 "register_operand" "=e")
6074         (fma:DF (match_operand:DF 1 "register_operand" "e")
6075                 (match_operand:DF 2 "register_operand" "e")
6076                 (neg:DF (match_operand:DF 3 "register_operand" "e"))))]
6077   "TARGET_FMAF"
6078   "fmsubd\t%1, %2, %3, %0"
6079   [(set_attr "type" "fpmul")])
6081 (define_insn "*nfmadf4"
6082   [(set (match_operand:DF 0 "register_operand" "=e")
6083         (neg:DF (fma:DF (match_operand:DF 1 "register_operand" "e")
6084                         (match_operand:DF 2 "register_operand" "e")
6085                         (match_operand:DF 3 "register_operand" "e"))))]
6086   "TARGET_FMAF"
6087   "fnmaddd\t%1, %2, %3, %0"
6088   [(set_attr "type" "fpmul")])
6090 (define_insn "*nfmsdf4"
6091   [(set (match_operand:DF 0 "register_operand" "=e")
6092         (neg:DF (fma:DF (match_operand:DF 1 "register_operand" "e")
6093                         (match_operand:DF 2 "register_operand" "e")
6094                         (neg:DF (match_operand:DF 3 "register_operand" "e")))))]
6095   "TARGET_FMAF"
6096   "fnmsubd\t%1, %2, %3, %0"
6097   [(set_attr "type" "fpmul")])
6099 (define_insn "fmasf4"
6100   [(set (match_operand:SF 0 "register_operand" "=f")
6101         (fma:SF (match_operand:SF 1 "register_operand" "f")
6102                 (match_operand:SF 2 "register_operand" "f")
6103                 (match_operand:SF 3 "register_operand" "f")))]
6104   "TARGET_FMAF"
6105   "fmadds\t%1, %2, %3, %0"
6106   [(set_attr "type" "fpmul")])
6108 (define_insn "fmssf4"
6109   [(set (match_operand:SF 0 "register_operand" "=f")
6110         (fma:SF (match_operand:SF 1 "register_operand" "f")
6111                 (match_operand:SF 2 "register_operand" "f")
6112                 (neg:SF (match_operand:SF 3 "register_operand" "f"))))]
6113   "TARGET_FMAF"
6114   "fmsubs\t%1, %2, %3, %0"
6115   [(set_attr "type" "fpmul")])
6117 (define_insn "*nfmasf4"
6118   [(set (match_operand:SF 0 "register_operand" "=f")
6119         (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "f")
6120                         (match_operand:SF 2 "register_operand" "f")
6121                         (match_operand:SF 3 "register_operand" "f"))))]
6122   "TARGET_FMAF"
6123   "fnmadds\t%1, %2, %3, %0"
6124   [(set_attr "type" "fpmul")])
6126 (define_insn "*nfmssf4"
6127   [(set (match_operand:SF 0 "register_operand" "=f")
6128         (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "f")
6129                         (match_operand:SF 2 "register_operand" "f")
6130                         (neg:SF (match_operand:SF 3 "register_operand" "f")))))]
6131   "TARGET_FMAF"
6132   "fnmsubs\t%1, %2, %3, %0"
6133   [(set_attr "type" "fpmul")])
6135 (define_insn "*muldf3_extend"
6136   [(set (match_operand:DF 0 "register_operand" "=e")
6137         (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
6138                  (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
6139   "TARGET_FSMULD"
6140   "fsmuld\t%1, %2, %0"
6141   [(set_attr "type" "fpmul")
6142    (set_attr "fptype" "double")])
6144 (define_insn "*multf3_extend"
6145   [(set (match_operand:TF 0 "register_operand" "=e")
6146         (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
6147                  (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
6148   "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
6149   "fdmulq\t%1, %2, %0"
6150   [(set_attr "type" "fpmul")])
6152 (define_expand "divtf3"
6153   [(set (match_operand:TF 0 "nonimmediate_operand" "")
6154         (div:TF (match_operand:TF 1 "general_operand" "")
6155                 (match_operand:TF 2 "general_operand" "")))]
6156   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6157   "emit_tfmode_binop (DIV, operands); DONE;")
6159 ;; don't have timing for quad-prec. divide.
6160 (define_insn "*divtf3_hq"
6161   [(set (match_operand:TF 0 "register_operand" "=e")
6162         (div:TF (match_operand:TF 1 "register_operand" "e")
6163                 (match_operand:TF 2 "register_operand" "e")))]
6164   "TARGET_FPU && TARGET_HARD_QUAD"
6165   "fdivq\t%1, %2, %0"
6166   [(set_attr "type" "fpdivs")])
6168 (define_expand "divdf3"
6169   [(set (match_operand:DF 0 "register_operand" "=e")
6170         (div:DF (match_operand:DF 1 "register_operand" "e")
6171                 (match_operand:DF 2 "register_operand" "e")))]
6172   "TARGET_FPU"
6173   "")
6175 (define_insn "*divdf3_nofix"
6176   [(set (match_operand:DF 0 "register_operand" "=e")
6177         (div:DF (match_operand:DF 1 "register_operand" "e")
6178                 (match_operand:DF 2 "register_operand" "e")))]
6179   "TARGET_FPU && !sparc_fix_ut699"
6180   "fdivd\t%1, %2, %0"
6181   [(set_attr "type" "fpdivd")
6182    (set_attr "fptype" "double")])
6184 (define_insn "*divdf3_fix"
6185   [(set (match_operand:DF 0 "register_operand" "=e")
6186         (div:DF (match_operand:DF 1 "register_operand" "e")
6187                 (match_operand:DF 2 "register_operand" "e")))]
6188   "TARGET_FPU && sparc_fix_ut699"
6189   "fdivd\t%1, %2, %0\n\tstd\t%0, [%%sp-8]\n\tnop"
6190   [(set_attr "type" "fpdivd")
6191    (set_attr "fptype" "double")
6192    (set_attr "length" "3")])
6194 (define_insn "divsf3"
6195   [(set (match_operand:SF 0 "register_operand" "=f")
6196         (div:SF (match_operand:SF 1 "register_operand" "f")
6197                 (match_operand:SF 2 "register_operand" "f")))]
6198   "TARGET_FPU && !sparc_fix_ut699"
6199   "fdivs\t%1, %2, %0"
6200   [(set_attr "type" "fpdivs")])
6202 (define_expand "negtf2"
6203   [(set (match_operand:TF 0 "register_operand" "")
6204         (neg:TF (match_operand:TF 1 "register_operand" "")))]
6205   "TARGET_FPU"
6206   "")
6208 (define_insn "*negtf2_hq"
6209   [(set (match_operand:TF 0 "register_operand" "=e")
6210         (neg:TF (match_operand:TF 1 "register_operand" "e")))]
6211   "TARGET_FPU && TARGET_HARD_QUAD"
6212   "fnegq\t%1, %0"
6213   [(set_attr "type" "fpmove")])
6215 (define_insn_and_split "*negtf2"
6216   [(set (match_operand:TF 0 "register_operand" "=e")
6217         (neg:TF (match_operand:TF 1 "register_operand" "e")))]
6218   "TARGET_FPU && !TARGET_HARD_QUAD"
6219   "#"
6220   "&& reload_completed"
6221   [(clobber (const_int 0))]
6223   rtx set_dest = operands[0];
6224   rtx set_src = operands[1];
6225   rtx dest1, dest2;
6226   rtx src1, src2;
6228   dest1 = gen_df_reg (set_dest, 0);
6229   dest2 = gen_df_reg (set_dest, 1);
6230   src1 = gen_df_reg (set_src, 0);
6231   src2 = gen_df_reg (set_src, 1);
6233   /* Now emit using the real source and destination we found, swapping
6234      the order if we detect overlap.  */
6235   if (reg_overlap_mentioned_p (dest1, src2))
6236     {
6237       emit_insn (gen_movdf (dest2, src2));
6238       emit_insn (gen_negdf2 (dest1, src1));
6239     }
6240   else
6241     {
6242       emit_insn (gen_negdf2 (dest1, src1));
6243       if (REGNO (dest2) != REGNO (src2))
6244         emit_insn (gen_movdf (dest2, src2));
6245     }
6246   DONE;
6248   [(set_attr "length" "2")])
6250 (define_expand "negdf2"
6251   [(set (match_operand:DF 0 "register_operand" "")
6252         (neg:DF (match_operand:DF 1 "register_operand" "")))]
6253   "TARGET_FPU"
6254   "")
6256 (define_insn_and_split "*negdf2_notv9"
6257   [(set (match_operand:DF 0 "register_operand" "=e")
6258         (neg:DF (match_operand:DF 1 "register_operand" "e")))]
6259   "TARGET_FPU && !TARGET_V9"
6260   "#"
6261   "&& reload_completed"
6262   [(clobber (const_int 0))]
6264   rtx set_dest = operands[0];
6265   rtx set_src = operands[1];
6266   rtx dest1, dest2;
6267   rtx src1, src2;
6269   dest1 = gen_highpart (SFmode, set_dest);
6270   dest2 = gen_lowpart (SFmode, set_dest);
6271   src1 = gen_highpart (SFmode, set_src);
6272   src2 = gen_lowpart (SFmode, set_src);
6274   /* Now emit using the real source and destination we found, swapping
6275      the order if we detect overlap.  */
6276   if (reg_overlap_mentioned_p (dest1, src2))
6277     {
6278       emit_insn (gen_movsf (dest2, src2));
6279       emit_insn (gen_negsf2 (dest1, src1));
6280     }
6281   else
6282     {
6283       emit_insn (gen_negsf2 (dest1, src1));
6284       if (REGNO (dest2) != REGNO (src2))
6285         emit_insn (gen_movsf (dest2, src2));
6286     }
6287   DONE;
6289   [(set_attr "length" "2")])
6291 (define_insn "*negdf2_v9"
6292   [(set (match_operand:DF 0 "register_operand" "=e")
6293         (neg:DF (match_operand:DF 1 "register_operand" "e")))]
6294   "TARGET_FPU && TARGET_V9"
6295   "fnegd\t%1, %0"
6296   [(set_attr "type" "fpmove")
6297    (set_attr "fptype" "double")])
6299 (define_insn "negsf2"
6300   [(set (match_operand:SF 0 "register_operand" "=f")
6301         (neg:SF (match_operand:SF 1 "register_operand" "f")))]
6302   "TARGET_FPU"
6303   "fnegs\t%1, %0"
6304   [(set_attr "type" "fpmove")])
6306 (define_expand "abstf2"
6307   [(set (match_operand:TF 0 "register_operand" "")
6308         (abs:TF (match_operand:TF 1 "register_operand" "")))]
6309   "TARGET_FPU"
6310   "")
6312 (define_insn "*abstf2_hq"
6313   [(set (match_operand:TF 0 "register_operand" "=e")
6314         (abs:TF (match_operand:TF 1 "register_operand" "e")))]
6315   "TARGET_FPU && TARGET_HARD_QUAD"
6316   "fabsq\t%1, %0"
6317   [(set_attr "type" "fpmove")])
6319 (define_insn_and_split "*abstf2"
6320   [(set (match_operand:TF 0 "register_operand" "=e")
6321         (abs:TF (match_operand:TF 1 "register_operand" "e")))]
6322   "TARGET_FPU && !TARGET_HARD_QUAD"
6323   "#"
6324   "&& reload_completed"
6325   [(clobber (const_int 0))]
6327   rtx set_dest = operands[0];
6328   rtx set_src = operands[1];
6329   rtx dest1, dest2;
6330   rtx src1, src2;
6332   dest1 = gen_df_reg (set_dest, 0);
6333   dest2 = gen_df_reg (set_dest, 1);
6334   src1 = gen_df_reg (set_src, 0);
6335   src2 = gen_df_reg (set_src, 1);
6337   /* Now emit using the real source and destination we found, swapping
6338      the order if we detect overlap.  */
6339   if (reg_overlap_mentioned_p (dest1, src2))
6340     {
6341       emit_insn (gen_movdf (dest2, src2));
6342       emit_insn (gen_absdf2 (dest1, src1));
6343     }
6344   else
6345     {
6346       emit_insn (gen_absdf2 (dest1, src1));
6347       if (REGNO (dest2) != REGNO (src2))
6348         emit_insn (gen_movdf (dest2, src2));
6349     }
6350   DONE;
6352   [(set_attr "length" "2")])
6354 (define_expand "absdf2"
6355   [(set (match_operand:DF 0 "register_operand" "")
6356         (abs:DF (match_operand:DF 1 "register_operand" "")))]
6357   "TARGET_FPU"
6358   "")
6360 (define_insn_and_split "*absdf2_notv9"
6361   [(set (match_operand:DF 0 "register_operand" "=e")
6362         (abs:DF (match_operand:DF 1 "register_operand" "e")))]
6363   "TARGET_FPU && !TARGET_V9"
6364   "#"
6365   "&& reload_completed"
6366   [(clobber (const_int 0))]
6368   rtx set_dest = operands[0];
6369   rtx set_src = operands[1];
6370   rtx dest1, dest2;
6371   rtx src1, src2;
6373   dest1 = gen_highpart (SFmode, set_dest);
6374   dest2 = gen_lowpart (SFmode, set_dest);
6375   src1 = gen_highpart (SFmode, set_src);
6376   src2 = gen_lowpart (SFmode, set_src);
6378   /* Now emit using the real source and destination we found, swapping
6379      the order if we detect overlap.  */
6380   if (reg_overlap_mentioned_p (dest1, src2))
6381     {
6382       emit_insn (gen_movsf (dest2, src2));
6383       emit_insn (gen_abssf2 (dest1, src1));
6384     }
6385   else
6386     {
6387       emit_insn (gen_abssf2 (dest1, src1));
6388       if (REGNO (dest2) != REGNO (src2))
6389         emit_insn (gen_movsf (dest2, src2));
6390     }
6391   DONE;
6393   [(set_attr "length" "2")])
6395 (define_insn "*absdf2_v9"
6396   [(set (match_operand:DF 0 "register_operand" "=e")
6397         (abs:DF (match_operand:DF 1 "register_operand" "e")))]
6398   "TARGET_FPU && TARGET_V9"
6399   "fabsd\t%1, %0"
6400   [(set_attr "type" "fpmove")
6401    (set_attr "fptype" "double")])
6403 (define_insn "abssf2"
6404   [(set (match_operand:SF 0 "register_operand" "=f")
6405         (abs:SF (match_operand:SF 1 "register_operand" "f")))]
6406   "TARGET_FPU"
6407   "fabss\t%1, %0"
6408   [(set_attr "type" "fpmove")])
6410 (define_expand "sqrttf2"
6411   [(set (match_operand:TF 0 "nonimmediate_operand" "")
6412         (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
6413   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6414   "emit_tfmode_unop (SQRT, operands); DONE;")
6416 (define_insn "*sqrttf2_hq"
6417   [(set (match_operand:TF 0 "register_operand" "=e")
6418         (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
6419   "TARGET_FPU && TARGET_HARD_QUAD"
6420   "fsqrtq\t%1, %0"
6421   [(set_attr "type" "fpsqrts")])
6423 (define_expand "sqrtdf2"
6424   [(set (match_operand:DF 0 "register_operand" "=e")
6425         (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
6426   "TARGET_FPU"
6427   "")
6429 (define_insn "*sqrtdf2_nofix"
6430   [(set (match_operand:DF 0 "register_operand" "=e")
6431         (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
6432   "TARGET_FPU && !sparc_fix_ut699"
6433   "fsqrtd\t%1, %0"
6434   [(set_attr "type" "fpsqrtd")
6435    (set_attr "fptype" "double")])
6437 (define_insn "*sqrtdf2_fix"
6438   [(set (match_operand:DF 0 "register_operand" "=e")
6439         (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
6440   "TARGET_FPU && sparc_fix_ut699"
6441   "fsqrtd\t%1, %0\n\tstd\t%0, [%%sp-8]\n\tnop"
6442   [(set_attr "type" "fpsqrtd")
6443    (set_attr "fptype" "double")
6444    (set_attr "length" "3")])
6446 (define_insn "sqrtsf2"
6447   [(set (match_operand:SF 0 "register_operand" "=f")
6448         (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
6449   "TARGET_FPU && !sparc_fix_ut699"
6450   "fsqrts\t%1, %0"
6451   [(set_attr "type" "fpsqrts")])
6454 ;; Arithmetic shift instructions.
6456 (define_insn "ashlsi3"
6457   [(set (match_operand:SI 0 "register_operand" "=r")
6458         (ashift:SI (match_operand:SI 1 "register_operand" "r")
6459                    (match_operand:SI 2 "arith_operand" "rI")))]
6460   ""
6462   if (GET_CODE (operands[2]) == CONST_INT)
6463     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6464   return "sll\t%1, %2, %0";
6466   [(set_attr "type" "shift")])
6468 (define_expand "ashldi3"
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 || TARGET_V8PLUS"
6474   if (TARGET_ARCH32)
6475     {
6476       if (GET_CODE (operands[2]) == CONST_INT)
6477         FAIL;
6478       emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
6479       DONE;
6480     }
6483 (define_insn "*ashldi3_sp64"
6484   [(set (match_operand:DI 0 "register_operand" "=r")
6485         (ashift:DI (match_operand:DI 1 "register_operand" "r")
6486                    (match_operand:SI 2 "arith_operand" "rI")))]
6487   "TARGET_ARCH64"
6489   if (GET_CODE (operands[2]) == CONST_INT)
6490     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6491   return "sllx\t%1, %2, %0";
6493   [(set_attr "type" "shift")])
6495 (define_insn "ashldi3_v8plus"
6496   [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6497         (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6498                    (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6499    (clobber (match_scratch:SI 3 "=X,X,&h"))]
6500   "TARGET_V8PLUS"
6502   return output_v8plus_shift (insn ,operands, \"sllx\");
6504   [(set_attr "type" "multi")
6505    (set_attr "length" "5,5,6")])
6507 (define_insn "*cmp_ccnz_ashift_1"
6508   [(set (reg:CCNZ CC_REG)
6509         (compare:CCNZ (ashift:SI (match_operand:SI 0 "register_operand" "r")
6510                                  (const_int 1))
6511                       (const_int 0)))]
6512   ""
6513   "addcc\t%0, %0, %%g0"
6514   [(set_attr "type" "compare")])
6516 (define_insn "*cmp_ccnz_set_ashift_1"
6517   [(set (reg:CCNZ CC_REG)
6518         (compare:CCNZ (ashift:SI (match_operand:SI 1 "register_operand" "r")
6519                                  (const_int 1))
6520                       (const_int 0)))
6521    (set (match_operand:SI 0 "register_operand" "=r")
6522         (ashift:SI (match_dup 1) (const_int 1)))]
6523   ""
6524   "addcc\t%1, %1, %0"
6525   [(set_attr "type" "compare")])
6527 (define_insn "ashrsi3"
6528   [(set (match_operand:SI 0 "register_operand" "=r")
6529         (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
6530                      (match_operand:SI 2 "arith_operand" "rI")))]
6531   ""
6533   if (GET_CODE (operands[2]) == CONST_INT)
6534    operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6535   return "sra\t%1, %2, %0";
6537   [(set_attr "type" "shift")])
6539 (define_insn "*ashrsi3_extend0"
6540   [(set (match_operand:DI 0 "register_operand" "=r")
6541         (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
6542                                      (match_operand:SI 2 "arith_operand" "rI"))))]
6543   "TARGET_ARCH64"
6545   if (GET_CODE (operands[2]) == CONST_INT)
6546    operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6547   return "sra\t%1, %2, %0";
6549   [(set_attr "type" "shift")])
6551 ;; This handles the case where
6552 ;; (sign_extend:DI (ashiftrt:SI (match_operand:SI) (match_operand:SI)))
6553 ;; but combiner "simplifies" it for us.
6554 (define_insn "*ashrsi3_extend1"
6555   [(set (match_operand:DI 0 "register_operand" "=r")
6556         (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
6557                                 (const_int 32))
6558                      (match_operand:SI 2 "small_int_operand" "I")))]
6559   "TARGET_ARCH64 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64"
6561   operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
6562   return "sra\t%1, %2, %0";
6564   [(set_attr "type" "shift")])
6566 ;; This handles the case where
6567 ;; (ashiftrt:DI (sign_extend:DI (match_operand:SI)) (const_int))
6568 ;; but combiner "simplifies" it for us.
6569 (define_insn "*ashrsi3_extend2"
6570   [(set (match_operand:DI 0 "register_operand" "=r")
6571         (sign_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
6572                          (match_operand 2 "small_int_operand" "I")
6573                          (const_int 32)))]
6574   "TARGET_ARCH64 && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 32"
6576   operands[2] = GEN_INT (32 - INTVAL (operands[2]));
6577   return "sra\t%1, %2, %0";
6579   [(set_attr "type" "shift")])
6581 (define_expand "ashrdi3"
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 || TARGET_V8PLUS"
6587   if (TARGET_ARCH32)
6588     {
6589       if (GET_CODE (operands[2]) == CONST_INT)
6590         FAIL;   /* prefer generic code in this case */
6591       emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
6592       DONE;
6593     }
6596 (define_insn "*ashrdi3_sp64"
6597   [(set (match_operand:DI 0 "register_operand" "=r")
6598         (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6599                      (match_operand:SI 2 "arith_operand" "rI")))]
6600   "TARGET_ARCH64"
6602   if (GET_CODE (operands[2]) == CONST_INT)
6603     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6604   return "srax\t%1, %2, %0";
6606   [(set_attr "type" "shift")])
6608 (define_insn "ashrdi3_v8plus"
6609   [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6610         (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6611                      (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6612    (clobber (match_scratch:SI 3 "=X,X,&h"))]
6613   "TARGET_V8PLUS"
6615   return output_v8plus_shift (insn, operands, \"srax\");
6617   [(set_attr "type" "multi")
6618    (set_attr "length" "5,5,6")])
6620 (define_insn "lshrsi3"
6621   [(set (match_operand:SI 0 "register_operand" "=r")
6622         (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
6623                      (match_operand:SI 2 "arith_operand" "rI")))]
6624   ""
6626   if (GET_CODE (operands[2]) == CONST_INT)
6627     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6628   return "srl\t%1, %2, %0";
6630   [(set_attr "type" "shift")])
6632 (define_insn "*lshrsi3_extend0"
6633   [(set (match_operand:DI 0 "register_operand" "=r")
6634         (zero_extend:DI
6635           (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
6636                        (match_operand:SI 2 "arith_operand" "rI"))))]
6637   "TARGET_ARCH64"
6639   if (GET_CODE (operands[2]) == CONST_INT)
6640     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6641   return "srl\t%1, %2, %0";
6643   [(set_attr "type" "shift")])
6645 ;; This handles the case where
6646 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI)))
6647 ;; but combiner "simplifies" it for us.
6648 (define_insn "*lshrsi3_extend1"
6649   [(set (match_operand:DI 0 "register_operand" "=r")
6650         (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
6651                                         (match_operand:SI 2 "arith_operand" "rI")) 0)
6652                 (match_operand 3 "const_int_operand" "")))]
6653   "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff"
6655   if (GET_CODE (operands[2]) == CONST_INT)
6656     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6657   return "srl\t%1, %2, %0";
6659   [(set_attr "type" "shift")])
6661 ;; This handles the case where
6662 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int))
6663 ;; but combiner "simplifies" it for us.
6664 (define_insn "*lshrsi3_extend2"
6665   [(set (match_operand:DI 0 "register_operand" "=r")
6666         (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
6667                          (match_operand 2 "small_int_operand" "I")
6668                          (const_int 32)))]
6669   "TARGET_ARCH64 && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 32"
6671   operands[2] = GEN_INT (32 - INTVAL (operands[2]));
6672   return "srl\t%1, %2, %0";
6674   [(set_attr "type" "shift")])
6676 (define_expand "lshrdi3"
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 || TARGET_V8PLUS"
6682   if (TARGET_ARCH32)
6683     {
6684       if (GET_CODE (operands[2]) == CONST_INT)
6685         FAIL;
6686       emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
6687       DONE;
6688     }
6691 (define_insn "*lshrdi3_sp64"
6692   [(set (match_operand:DI 0 "register_operand" "=r")
6693         (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6694                      (match_operand:SI 2 "arith_operand" "rI")))]
6695   "TARGET_ARCH64"
6697   if (GET_CODE (operands[2]) == CONST_INT)
6698     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6699   return "srlx\t%1, %2, %0";
6701   [(set_attr "type" "shift")])
6703 (define_insn "lshrdi3_v8plus"
6704   [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6705         (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6706                      (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6707    (clobber (match_scratch:SI 3 "=X,X,&h"))]
6708   "TARGET_V8PLUS"
6710   return output_v8plus_shift (insn, operands, \"srlx\");
6712   [(set_attr "type" "multi")
6713    (set_attr "length" "5,5,6")])
6715 (define_insn ""
6716   [(set (match_operand:SI 0 "register_operand" "=r")
6717         (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6718                                              (const_int 32)) 4)
6719                      (match_operand:SI 2 "small_int_operand" "I")))]
6720   "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6722   operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6723   return "srax\t%1, %2, %0";
6725   [(set_attr "type" "shift")])
6727 (define_insn ""
6728   [(set (match_operand:SI 0 "register_operand" "=r")
6729         (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6730                                              (const_int 32)) 4)
6731                      (match_operand:SI 2 "small_int_operand" "I")))]
6732   "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6734   operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6735   return "srlx\t%1, %2, %0";
6737   [(set_attr "type" "shift")])
6739 (define_insn ""
6740   [(set (match_operand:SI 0 "register_operand" "=r")
6741         (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6742                                              (match_operand:SI 2 "small_int_operand" "I")) 4)
6743                      (match_operand:SI 3 "small_int_operand" "I")))]
6744   "TARGET_ARCH64
6745    && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6746    && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6747    && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6749   operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6751   return "srax\t%1, %2, %0";
6753   [(set_attr "type" "shift")])
6755 (define_insn ""
6756   [(set (match_operand:SI 0 "register_operand" "=r")
6757         (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6758                                              (match_operand:SI 2 "small_int_operand" "I")) 4)
6759                      (match_operand:SI 3 "small_int_operand" "I")))]
6760   "TARGET_ARCH64
6761    && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6762    && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6763    && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6765   operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6767   return "srlx\t%1, %2, %0";
6769   [(set_attr "type" "shift")])
6772 ;; Unconditional and other jump instructions.
6774 (define_expand "jump"
6775   [(set (pc) (label_ref (match_operand 0 "" "")))]
6776   "")
6778 (define_insn "*jump_ubranch"
6779   [(set (pc) (label_ref (match_operand 0 "" "")))]
6780   "!TARGET_CBCOND"
6782   return output_ubranch (operands[0], insn);
6784   [(set_attr "type" "uncond_branch")])
6786 (define_insn "*jump_cbcond"
6787   [(set (pc) (label_ref (match_operand 0 "" "")))]
6788   "TARGET_CBCOND"
6790   return output_ubranch (operands[0], insn);
6792   [(set_attr "type" "uncond_cbcond")])
6794 (define_expand "tablejump"
6795   [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
6796               (use (label_ref (match_operand 1 "" "")))])]
6797   ""
6799   gcc_assert (GET_MODE (operands[0]) == CASE_VECTOR_MODE);
6801   /* In pic mode, our address differences are against the base of the
6802      table.  Add that base value back in; CSE ought to be able to combine
6803      the two address loads.  */
6804   if (flag_pic)
6805     {
6806       rtx tmp, tmp2;
6807       tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
6808       tmp2 = operands[0];
6809       if (CASE_VECTOR_MODE != Pmode)
6810         tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
6811       tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
6812       operands[0] = memory_address (Pmode, tmp);
6813     }
6816 (define_insn "*tablejump_sp32"
6817   [(set (pc) (match_operand:SI 0 "address_operand" "p"))
6818    (use (label_ref (match_operand 1 "" "")))]
6819   "TARGET_ARCH32"
6820   "jmp\t%a0%#"
6821   [(set_attr "type" "uncond_branch")])
6823 (define_insn "*tablejump_sp64"
6824   [(set (pc) (match_operand:DI 0 "address_operand" "p"))
6825    (use (label_ref (match_operand 1 "" "")))]
6826   "TARGET_ARCH64"
6827   "jmp\t%a0%#"
6828   [(set_attr "type" "uncond_branch")])
6831 ;; Jump to subroutine instructions.
6833 (define_expand "call"
6834   ;; Note that this expression is not used for generating RTL.
6835   ;; All the RTL is generated explicitly below.
6836   [(call (match_operand 0 "call_operand" "")
6837          (match_operand 3 "" "i"))]
6838   ;; operands[2] is next_arg_register
6839   ;; operands[3] is struct_value_size_rtx.
6840   ""
6842   rtx fn_rtx;
6844   gcc_assert (MEM_P (operands[0]) && GET_MODE (operands[0]) == FUNCTION_MODE);
6846   gcc_assert (GET_CODE (operands[3]) == CONST_INT);
6848   if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
6849     {
6850       /* This is really a PIC sequence.  We want to represent
6851          it as a funny jump so its delay slots can be filled. 
6853          ??? But if this really *is* a CALL, will not it clobber the
6854          call-clobbered registers?  We lose this if it is a JUMP_INSN.
6855          Why cannot we have delay slots filled if it were a CALL?  */
6857       /* We accept negative sizes for untyped calls.  */
6858       if (TARGET_ARCH32 && INTVAL (operands[3]) != 0)
6859         emit_jump_insn
6860           (gen_rtx_PARALLEL
6861            (VOIDmode,
6862             gen_rtvec (3,
6863                        gen_rtx_SET (pc_rtx, XEXP (operands[0], 0)),
6864                        operands[3],
6865                        gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6866       else
6867         emit_jump_insn
6868           (gen_rtx_PARALLEL
6869            (VOIDmode,
6870             gen_rtvec (2,
6871                        gen_rtx_SET (pc_rtx, XEXP (operands[0], 0)),
6872                        gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6873       goto finish_call;
6874     }
6876   fn_rtx = operands[0];
6878   /* We accept negative sizes for untyped calls.  */
6879   if (TARGET_ARCH32 && INTVAL (operands[3]) != 0)
6880     sparc_emit_call_insn
6881       (gen_rtx_PARALLEL
6882        (VOIDmode,
6883         gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6884                    operands[3],
6885                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6886        XEXP (fn_rtx, 0));
6887   else
6888     sparc_emit_call_insn
6889       (gen_rtx_PARALLEL
6890        (VOIDmode,
6891         gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6892                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6893        XEXP (fn_rtx, 0));
6895  finish_call:
6897   DONE;
6900 ;; We can't use the same pattern for these two insns, because then registers
6901 ;; in the address may not be properly reloaded.
6903 (define_insn "*call_address_sp32"
6904   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6905          (match_operand 1 "" ""))
6906    (clobber (reg:SI O7_REG))]
6907   ;;- Do not use operand 1 for most machines.
6908   "TARGET_ARCH32"
6909   "call\t%a0, %1%#"
6910   [(set_attr "type" "call")])
6912 (define_insn "*call_symbolic_sp32"
6913   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6914          (match_operand 1 "" ""))
6915    (clobber (reg:SI O7_REG))]
6916   ;;- Do not use operand 1 for most machines.
6917   "TARGET_ARCH32"
6918   "call\t%a0, %1%#"
6919   [(set_attr "type" "call")])
6921 (define_insn "*call_address_sp64"
6922   [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
6923          (match_operand 1 "" ""))
6924    (clobber (reg:DI O7_REG))]
6925   ;;- Do not use operand 1 for most machines.
6926   "TARGET_ARCH64"
6927   "call\t%a0, %1%#"
6928   [(set_attr "type" "call")])
6930 (define_insn "*call_symbolic_sp64"
6931   [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6932          (match_operand 1 "" ""))
6933    (clobber (reg:DI O7_REG))]
6934   ;;- Do not use operand 1 for most machines.
6935   "TARGET_ARCH64"
6936   "call\t%a0, %1%#"
6937   [(set_attr "type" "call")])
6939 ;; This is a call that wants a structure value.
6940 ;; There is no such critter for v9 (??? we may need one anyway).
6941 (define_insn "*call_address_struct_value_sp32"
6942   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6943          (match_operand 1 "" ""))
6944    (match_operand 2 "immediate_operand" "")
6945    (clobber (reg:SI O7_REG))]
6946   ;;- Do not use operand 1 for most machines.
6947   "TARGET_ARCH32 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6949   operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6950   return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6952   [(set_attr "type" "call_no_delay_slot")
6953    (set_attr "length" "3")])
6955 ;; This is a call that wants a structure value.
6956 ;; There is no such critter for v9 (??? we may need one anyway).
6957 (define_insn "*call_symbolic_struct_value_sp32"
6958   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6959          (match_operand 1 "" ""))
6960    (match_operand 2 "immediate_operand" "")
6961    (clobber (reg:SI O7_REG))]
6962   ;;- Do not use operand 1 for most machines.
6963   "TARGET_ARCH32 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6965   operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6966   return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6968   [(set_attr "type" "call_no_delay_slot")
6969    (set_attr "length" "3")])
6971 ;; This is a call that may want a structure value.  This is used for
6972 ;; untyped_calls.
6973 (define_insn "*call_address_untyped_struct_value_sp32"
6974   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6975          (match_operand 1 "" ""))
6976    (match_operand 2 "immediate_operand" "")
6977    (clobber (reg:SI O7_REG))]
6978   ;;- Do not use operand 1 for most machines.
6979   "TARGET_ARCH32 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6980   "call\t%a0, %1\n\t nop\n\tnop"
6981   [(set_attr "type" "call_no_delay_slot")
6982    (set_attr "length" "3")])
6984 ;; This is a call that may want a structure value.  This is used for
6985 ;; untyped_calls.
6986 (define_insn "*call_symbolic_untyped_struct_value_sp32"
6987   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6988          (match_operand 1 "" ""))
6989    (match_operand 2 "immediate_operand" "")
6990    (clobber (reg:SI O7_REG))]
6991   ;;- Do not use operand 1 for most machines.
6992   "TARGET_ARCH32 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6993   "call\t%a0, %1\n\t nop\n\tnop"
6994   [(set_attr "type" "call_no_delay_slot")
6995    (set_attr "length" "3")])
6997 (define_expand "call_value"
6998   ;; Note that this expression is not used for generating RTL.
6999   ;; All the RTL is generated explicitly below.
7000   [(set (match_operand 0 "register_operand" "=rf")
7001         (call (match_operand 1 "" "")
7002               (match_operand 4 "" "")))]
7003   ;; operand 2 is stack_size_rtx
7004   ;; operand 3 is next_arg_register
7005   ""
7007   rtx fn_rtx;
7008   rtvec vec;
7010   gcc_assert (MEM_P (operands[1]) && GET_MODE (operands[1]) == FUNCTION_MODE);
7012   fn_rtx = operands[1];
7014   vec = gen_rtvec (2,
7015                    gen_rtx_SET (operands[0],
7016                                 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
7017                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
7019   sparc_emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec), XEXP (fn_rtx, 0));
7021   DONE;
7024 (define_insn "*call_value_address_sp32"
7025   [(set (match_operand 0 "" "=rf")
7026         (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
7027               (match_operand 2 "" "")))
7028    (clobber (reg:SI O7_REG))]
7029   ;;- Do not use operand 2 for most machines.
7030   "TARGET_ARCH32"
7031   "call\t%a1, %2%#"
7032   [(set_attr "type" "call")])
7034 (define_insn "*call_value_symbolic_sp32"
7035   [(set (match_operand 0 "" "=rf")
7036         (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7037               (match_operand 2 "" "")))
7038    (clobber (reg:SI O7_REG))]
7039   ;;- Do not use operand 2 for most machines.
7040   "TARGET_ARCH32"
7041   "call\t%a1, %2%#"
7042   [(set_attr "type" "call")])
7044 (define_insn "*call_value_address_sp64"
7045   [(set (match_operand 0 "" "")
7046         (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
7047               (match_operand 2 "" "")))
7048    (clobber (reg:DI O7_REG))]
7049   ;;- Do not use operand 2 for most machines.
7050   "TARGET_ARCH64"
7051   "call\t%a1, %2%#"
7052   [(set_attr "type" "call")])
7054 (define_insn "*call_value_symbolic_sp64"
7055   [(set (match_operand 0 "" "")
7056         (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
7057               (match_operand 2 "" "")))
7058    (clobber (reg:DI O7_REG))]
7059   ;;- Do not use operand 2 for most machines.
7060   "TARGET_ARCH64"
7061   "call\t%a1, %2%#"
7062   [(set_attr "type" "call")])
7064 (define_expand "untyped_call"
7065   [(parallel [(call (match_operand 0 "" "")
7066                     (const_int 0))
7067               (match_operand:BLK 1 "memory_operand" "")
7068               (match_operand 2 "" "")])]
7069   ""
7071   rtx valreg1 = gen_rtx_REG (DImode, 8);
7072   rtx result = operands[1];
7074   /* Pass constm1 to indicate that it may expect a structure value, but
7075      we don't know what size it is.  */
7076   emit_call_insn (gen_call (operands[0], const0_rtx, NULL, constm1_rtx));
7078   /* Save the function value registers.  */
7079   emit_move_insn (adjust_address (result, DImode, 0), valreg1);
7080   if (TARGET_FPU)
7081     {
7082       rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
7083       emit_move_insn (adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8),
7084                       valreg2);
7085     }
7087   /* The optimizer does not know that the call sets the function value
7088      registers we stored in the result block.  We avoid problems by
7089      claiming that all hard registers are used and clobbered at this
7090      point.  */
7091   emit_insn (gen_blockage ());
7093   DONE;
7097 ;;  Tail call instructions.
7099 (define_expand "sibcall"
7100   [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
7101               (return)])]
7102   ""
7103   "")
7105 (define_insn "*sibcall_symbolic_sp32"
7106   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7107          (match_operand 1 "" ""))
7108    (return)]
7109   "TARGET_ARCH32"
7111   return output_sibcall(insn, operands[0]);
7113   [(set_attr "type" "sibcall")])
7115 (define_insn "*sibcall_symbolic_sp64"
7116   [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
7117          (match_operand 1 "" ""))
7118    (return)]
7119   "TARGET_ARCH64"
7121   return output_sibcall(insn, operands[0]);
7123   [(set_attr "type" "sibcall")])
7125 (define_expand "sibcall_value"
7126   [(parallel [(set (match_operand 0 "register_operand" "=rf")
7127                 (call (match_operand 1 "" "") (const_int 0)))
7128               (return)])]
7129   ""
7130   "")
7132 (define_insn "*sibcall_value_symbolic_sp32"
7133   [(set (match_operand 0 "" "=rf")
7134         (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7135               (match_operand 2 "" "")))
7136    (return)]
7137   "TARGET_ARCH32"
7139   return output_sibcall(insn, operands[1]);
7141   [(set_attr "type" "sibcall")])
7143 (define_insn "*sibcall_value_symbolic_sp64"
7144   [(set (match_operand 0 "" "")
7145         (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
7146               (match_operand 2 "" "")))
7147    (return)]
7148   "TARGET_ARCH64"
7150   return output_sibcall(insn, operands[1]);
7152   [(set_attr "type" "sibcall")])
7155 ;; Special instructions.
7157 (define_expand "prologue"
7158   [(const_int 0)]
7159   ""
7161   if (TARGET_FLAT)
7162     sparc_flat_expand_prologue ();
7163   else
7164     sparc_expand_prologue ();
7165   DONE;
7168 ;; The "register window save" insn is modelled as follows.  The dwarf2
7169 ;; information is manually added in emit_window_save.
7171 (define_insn "window_save"
7172   [(unspec_volatile
7173         [(match_operand 0 "arith_operand" "rI")]
7174         UNSPECV_SAVEW)]
7175   "!TARGET_FLAT"
7176   "save\t%%sp, %0, %%sp"
7177   [(set_attr "type" "savew")])
7179 (define_expand "epilogue"
7180   [(return)]
7181   ""
7183   if (TARGET_FLAT)
7184     sparc_flat_expand_epilogue (false);
7185   else
7186     sparc_expand_epilogue (false);
7189 (define_expand "sibcall_epilogue"
7190   [(return)]
7191   ""
7193   if (TARGET_FLAT)
7194     sparc_flat_expand_epilogue (false);
7195   else
7196     sparc_expand_epilogue (false);
7197   DONE;
7200 (define_expand "eh_return"
7201   [(use (match_operand 0 "general_operand" ""))]
7202   ""
7204   emit_move_insn (gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM), operands[0]);
7205   emit_jump_insn (gen_eh_return_internal ());
7206   emit_barrier ();
7207   DONE;
7210 (define_insn_and_split "eh_return_internal"
7211   [(eh_return)]
7212   ""
7213   "#"
7214   "epilogue_completed"
7215   [(return)]
7217   if (TARGET_FLAT)
7218     sparc_flat_expand_epilogue (true);
7219   else
7220     sparc_expand_epilogue (true);
7223 (define_expand "return"
7224   [(return)]
7225   "sparc_can_use_return_insn_p ()"
7227   if (cfun->calls_alloca)
7228     emit_insn (gen_frame_blockage ());
7231 (define_insn "*return_internal"
7232   [(return)]
7233   ""
7235   return output_return (insn);
7237   [(set_attr "type" "return")
7238    (set (attr "length")
7239         (cond [(eq_attr "calls_eh_return" "true")
7240                  (if_then_else (eq_attr "delayed_branch" "true")
7241                                 (if_then_else (ior (eq_attr "isa" "v9")
7242                                                    (eq_attr "flat" "true"))
7243                                         (const_int 2)
7244                                         (const_int 3))
7245                                 (if_then_else (eq_attr "flat" "true")
7246                                         (const_int 3)
7247                                         (const_int 4)))
7248                (ior (eq_attr "leaf_function" "true") (eq_attr "flat" "true"))
7249                  (if_then_else (eq_attr "empty_delay_slot" "true")
7250                                (const_int 2)
7251                                (const_int 1))
7252                (eq_attr "empty_delay_slot" "true")
7253                  (if_then_else (eq_attr "delayed_branch" "true")
7254                                (const_int 2)
7255                                (const_int 3))
7256               ] (const_int 1)))])
7258 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
7259 ;; all of memory.  This blocks insns from being moved across this point.
7261 (define_insn "blockage"
7262   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7263   ""
7264   ""
7265   [(set_attr "length" "0")])
7267 ;; Do not schedule instructions accessing memory before this point.
7269 (define_expand "frame_blockage"
7270   [(set (match_dup 0)
7271         (unspec:BLK [(match_dup 1)] UNSPEC_FRAME_BLOCKAGE))]
7272   ""
7274   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
7275   MEM_VOLATILE_P (operands[0]) = 1;
7276   operands[1] = stack_pointer_rtx;
7279 (define_insn "*frame_blockage<P:mode>"
7280   [(set (match_operand:BLK 0 "" "")
7281         (unspec:BLK [(match_operand:P 1 "" "")] UNSPEC_FRAME_BLOCKAGE))]
7282   ""
7283   ""
7284   [(set_attr "length" "0")])
7286 (define_expand "probe_stack"
7287   [(set (match_operand 0 "memory_operand" "") (const_int 0))]
7288   ""
7290   operands[0]
7291     = adjust_address (operands[0], GET_MODE (operands[0]), SPARC_STACK_BIAS);
7294 (define_insn "probe_stack_range<P:mode>"
7295   [(set (match_operand:P 0 "register_operand" "=r")
7296         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
7297                             (match_operand:P 2 "register_operand" "r")]
7298                             UNSPECV_PROBE_STACK_RANGE))]
7299   ""
7301   return output_probe_stack_range (operands[0], operands[2]);
7303   [(set_attr "type" "multi")])
7305 ;; Prepare to return any type including a structure value.
7307 (define_expand "untyped_return"
7308   [(match_operand:BLK 0 "memory_operand" "")
7309    (match_operand 1 "" "")]
7310   ""
7312   rtx valreg1 = gen_rtx_REG (DImode, 24);
7313   rtx result = operands[0];
7315   if (TARGET_ARCH32)
7316     {
7317       rtx rtnreg = gen_rtx_REG (SImode, RETURN_ADDR_REGNUM);
7318       rtx value = gen_reg_rtx (SImode);
7320       /* Fetch the instruction where we will return to and see if it's an unimp
7321          instruction (the most significant 10 bits will be zero).  If so,
7322          update the return address to skip the unimp instruction.  */
7323       emit_move_insn (value,
7324                       gen_rtx_MEM (SImode, plus_constant (SImode, rtnreg, 8)));
7325       emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
7326       emit_insn (gen_update_return (rtnreg, value));
7327     }
7329   /* Reload the function value registers.
7330      Put USE insns before the return.  */
7331   emit_move_insn (valreg1, adjust_address (result, DImode, 0));
7332   emit_use (valreg1);
7334   if (TARGET_FPU)
7335     {
7336       rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
7337       emit_move_insn (valreg2,
7338                       adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
7339       emit_use (valreg2);
7340     }
7342   /* Construct the return.  */
7343   expand_naked_return ();
7345   DONE;
7348 ;; Adjust the return address conditionally. If the value of op1 is equal
7349 ;; to all zero then adjust the return address i.e. op0 = op0 + 4.
7350 ;; This is technically *half* the check required by the 32-bit SPARC
7351 ;; psABI. This check only ensures that an "unimp" insn was written by
7352 ;; the caller, but doesn't check to see if the expected size matches
7353 ;; (this is encoded in the 12 lower bits). This check is obsolete and
7354 ;; only used by the above code "untyped_return".
7356 (define_insn "update_return"
7357   [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
7358                (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
7359   "TARGET_ARCH32"
7361   if (flag_delayed_branch)
7362     return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
7363   else
7364     return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
7366   [(set (attr "type") (const_string "multi"))
7367    (set (attr "length")
7368         (if_then_else (eq_attr "delayed_branch" "true")
7369                       (const_int 3)
7370                       (const_int 4)))])
7372 (define_insn "nop"
7373   [(const_int 0)]
7374   ""
7375   "nop")
7377 (define_expand "indirect_jump"
7378   [(set (pc) (match_operand 0 "address_operand" "p"))]
7379   ""
7380   "")
7382 (define_insn "*branch_sp32"
7383   [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
7384   "TARGET_ARCH32"
7385  "jmp\t%a0%#"
7386  [(set_attr "type" "uncond_branch")])
7388 (define_insn "*branch_sp64"
7389   [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
7390   "TARGET_ARCH64"
7391   "jmp\t%a0%#"
7392   [(set_attr "type" "uncond_branch")])
7394 (define_expand "save_stack_nonlocal"
7395   [(set (match_operand 0 "memory_operand" "")
7396         (match_operand 1 "register_operand" ""))
7397    (set (match_dup 2) (match_dup 3))]
7398   ""
7400   operands[0] = adjust_address (operands[0], Pmode, 0);
7401   operands[2] = adjust_address (operands[0], Pmode, GET_MODE_SIZE (Pmode));
7402   operands[3] = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
7405 (define_expand "restore_stack_nonlocal"
7406   [(set (match_operand 0 "register_operand" "")
7407         (match_operand 1 "memory_operand" ""))]
7408   ""
7410   operands[1] = adjust_address (operands[1], Pmode, 0);
7413 (define_expand "nonlocal_goto"
7414   [(match_operand 0 "general_operand" "")
7415    (match_operand 1 "general_operand" "")
7416    (match_operand 2 "memory_operand" "")
7417    (match_operand 3 "memory_operand" "")]
7418   ""
7420   rtx i7 = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
7421   rtx r_label = copy_to_reg (operands[1]);
7422   rtx r_sp = adjust_address (operands[2], Pmode, 0);
7423   rtx r_fp = operands[3];
7424   rtx r_i7 = adjust_address (operands[2], Pmode, GET_MODE_SIZE (Pmode));
7426   /* We need to flush all the register windows so that their contents will
7427      be re-synchronized by the restore insn of the target function.  */
7428   if (!TARGET_FLAT)
7429     emit_insn (gen_flush_register_windows ());
7431   emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
7432   emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
7434   /* Restore frame pointer for containing function.  */
7435   emit_move_insn (hard_frame_pointer_rtx, r_fp);
7436   emit_stack_restore (SAVE_NONLOCAL, r_sp);
7437   emit_move_insn (i7, r_i7);
7439   /* USE of hard_frame_pointer_rtx added for consistency;
7440      not clear if really needed.  */
7441   emit_use (hard_frame_pointer_rtx);
7442   emit_use (stack_pointer_rtx);
7443   emit_use (i7);
7445   emit_jump_insn (gen_indirect_jump (r_label));
7446   emit_barrier ();
7447   DONE;
7450 (define_expand "builtin_setjmp_receiver"
7451   [(label_ref (match_operand 0 "" ""))]
7452   "flag_pic"
7454   load_got_register ();
7455   DONE;
7458 ;; Special insn to flush register windows.
7460 (define_insn "flush_register_windows"
7461   [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
7462   ""
7464   return TARGET_V9 ? "flushw" : "ta\t3";
7466   [(set_attr "type" "flushw")])
7468 ;; Special pattern for the FLUSH instruction.
7470 (define_insn "flush<P:mode>"
7471   [(unspec_volatile [(match_operand:P 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7472   ""
7474   return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0";
7476   [(set_attr "type" "iflush")])
7478 ;; Special insns to load and store the 32-bit FP Status Register.
7480 (define_insn "ldfsr"
7481   [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_LDFSR)]
7482   "TARGET_FPU"
7483   "ld\t%0, %%fsr"
7484   [(set_attr "type" "load")
7485    (set_attr "subtype" "regular")])
7487 (define_insn "stfsr"
7488   [(set (match_operand:SI 0 "memory_operand" "=m")
7489         (unspec_volatile:SI [(const_int 0)] UNSPECV_STFSR))]
7490   "TARGET_FPU"
7491   "st\t%%fsr, %0"
7492   [(set_attr "type" "store")])
7495 ;; Find first set instructions.
7497 (define_expand "popcountdi2"
7498   [(set (match_operand:DI 0 "register_operand" "")
7499         (popcount:DI (match_operand:DI 1 "register_operand" "")))]
7500   "TARGET_POPC"
7502   if (TARGET_ARCH32)
7503     {
7504       emit_insn (gen_popcountdi_v8plus (operands[0], operands[1]));
7505       DONE;
7506     }
7509 (define_insn "*popcountdi_sp64"
7510   [(set (match_operand:DI 0 "register_operand" "=r")
7511         (popcount:DI (match_operand:DI 1 "register_operand" "r")))]
7512   "TARGET_POPC && TARGET_ARCH64"
7513   "popc\t%1, %0")
7515 (define_insn "popcountdi_v8plus"
7516   [(set (match_operand:DI 0 "register_operand" "=r")
7517         (popcount:DI (match_operand:DI 1 "register_operand" "r")))
7518    (clobber (match_scratch:SI 2 "=&h"))]
7519   "TARGET_POPC && TARGET_ARCH32"
7521   if (sparc_check_64 (operands[1], insn) <= 0)
7522     output_asm_insn ("srl\t%L1, 0, %L1", operands);
7523   return "sllx\t%H1, 32, %2\n\tor\t%L1, %2, %2\n\tpopc\t%2, %L0\n\tclr\t%H0";
7525   [(set_attr "type" "multi")
7526    (set_attr "length" "5")])
7528 (define_expand "popcountsi2"
7529   [(set (match_dup 2)
7530         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
7531    (set (match_operand:SI 0 "register_operand" "")
7532         (truncate:SI (popcount:DI (match_dup 2))))]
7533   "TARGET_POPC"
7535   if (TARGET_ARCH32)
7536     {
7537       emit_insn (gen_popcountsi_v8plus (operands[0], operands[1]));
7538       DONE;
7539     }
7540   else
7541     operands[2] = gen_reg_rtx (DImode);
7544 (define_insn "*popcountsi_sp64"
7545   [(set (match_operand:SI 0 "register_operand" "=r")
7546         (truncate:SI
7547           (popcount:DI (match_operand:DI 1 "register_operand" "r"))))]
7548   "TARGET_POPC && TARGET_ARCH64"
7549   "popc\t%1, %0")
7551 (define_insn "popcountsi_v8plus"
7552   [(set (match_operand:SI 0 "register_operand" "=r")
7553         (popcount:SI (match_operand:SI 1 "register_operand" "r")))]
7554   "TARGET_POPC && TARGET_ARCH32"
7556   if (sparc_check_64 (operands[1], insn) <= 0)
7557     output_asm_insn ("srl\t%1, 0, %1", operands);
7558   return "popc\t%1, %0";
7560   [(set_attr "type" "multi")
7561    (set_attr "length" "2")])
7563 (define_expand "clzdi2"
7564   [(set (match_operand:DI 0 "register_operand" "")
7565         (clz:DI (match_operand:DI 1 "register_operand" "")))]
7566   "TARGET_VIS3"
7568   if (TARGET_ARCH32)
7569     {
7570       emit_insn (gen_clzdi_v8plus (operands[0], operands[1]));
7571       DONE;
7572     }
7575 (define_insn "*clzdi_sp64"
7576   [(set (match_operand:DI 0 "register_operand" "=r")
7577         (clz:DI (match_operand:DI 1 "register_operand" "r")))]
7578   "TARGET_VIS3 && TARGET_ARCH64"
7579   "lzd\t%1, %0"
7580   [(set_attr "type" "lzd")])
7582 (define_insn "clzdi_v8plus"
7583   [(set (match_operand:DI 0 "register_operand" "=r")
7584         (clz:DI (match_operand:DI 1 "register_operand" "r")))
7585    (clobber (match_scratch:SI 2 "=&h"))]
7586   "TARGET_VIS3 && TARGET_ARCH32"
7588   if (sparc_check_64 (operands[1], insn) <= 0)
7589     output_asm_insn ("srl\t%L1, 0, %L1", operands);
7590   return "sllx\t%H1, 32, %2\n\tor\t%L1, %2, %2\n\tlzd\t%2, %L0\n\tclr\t%H0";
7592   [(set_attr "type" "multi")
7593    (set_attr "length" "5")])
7595 (define_expand "clzsi2"
7596   [(set (match_dup 2)
7597         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
7598    (set (match_dup 3)
7599         (truncate:SI (clz:DI (match_dup 2))))
7600    (set (match_operand:SI 0 "register_operand" "")
7601         (minus:SI (match_dup 3) (const_int 32)))]
7602   "TARGET_VIS3"
7604   if (TARGET_ARCH32)
7605     {
7606       emit_insn (gen_clzsi_v8plus (operands[0], operands[1]));
7607       DONE;
7608     }
7609   else
7610     {
7611       operands[2] = gen_reg_rtx (DImode);
7612       operands[3] = gen_reg_rtx (SImode);
7613     }
7616 (define_insn "*clzsi_sp64"
7617   [(set (match_operand:SI 0 "register_operand" "=r")
7618         (truncate:SI
7619           (clz:DI (match_operand:DI 1 "register_operand" "r"))))]
7620   "TARGET_VIS3 && TARGET_ARCH64"
7621   "lzd\t%1, %0"
7622   [(set_attr "type" "lzd")])
7624 (define_insn "clzsi_v8plus"
7625   [(set (match_operand:SI 0 "register_operand" "=r")
7626         (clz:SI (match_operand:SI 1 "register_operand" "r")))]
7627   "TARGET_VIS3 && TARGET_ARCH32"
7629   if (sparc_check_64 (operands[1], insn) <= 0)
7630     output_asm_insn ("srl\t%1, 0, %1", operands);
7631   return "lzd\t%1, %0\n\tsub\t%0, 32, %0";
7633   [(set_attr "type" "multi")
7634    (set_attr "length" "3")])
7637 ;; Peepholes go at the end.
7639 ;; Optimize consecutive loads or stores into ldd and std when possible.
7640 ;; The conditions in which we do this are very restricted and are 
7641 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
7643 (define_peephole2
7644   [(set (match_operand:SI 0 "memory_operand" "")
7645       (const_int 0))
7646    (set (match_operand:SI 1 "memory_operand" "")
7647       (const_int 0))]
7648   "TARGET_V9
7649    && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
7650   [(set (match_dup 0) (const_int 0))]
7652   operands[0] = widen_mem_for_ldd_peep (operands[0], operands[1], DImode);
7655 (define_peephole2
7656   [(set (match_operand:SI 0 "memory_operand" "")
7657       (const_int 0))
7658    (set (match_operand:SI 1 "memory_operand" "")
7659       (const_int 0))]
7660   "TARGET_V9
7661    && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
7662   [(set (match_dup 1) (const_int 0))]
7664   operands[1] = widen_mem_for_ldd_peep (operands[1], operands[0], DImode);
7667 (define_peephole2
7668   [(set (match_operand:SI 0 "register_operand" "")
7669         (match_operand:SI 1 "memory_operand" ""))
7670    (set (match_operand:SI 2 "register_operand" "")
7671         (match_operand:SI 3 "memory_operand" ""))]
7672   "registers_ok_for_ldd_peep (operands[0], operands[2]) 
7673    && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])" 
7674   [(set (match_dup 0) (match_dup 1))]
7676   operands[1] = widen_mem_for_ldd_peep (operands[1], operands[3], DImode);
7677   operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
7680 (define_peephole2
7681   [(set (match_operand:SI 0 "memory_operand" "")
7682         (match_operand:SI 1 "register_operand" ""))
7683    (set (match_operand:SI 2 "memory_operand" "")
7684         (match_operand:SI 3 "register_operand" ""))]
7685   "registers_ok_for_ldd_peep (operands[1], operands[3]) 
7686    && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7687   [(set (match_dup 0) (match_dup 1))]
7689   operands[0] = widen_mem_for_ldd_peep (operands[0], operands[2], DImode);
7690   operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));
7693 (define_peephole2
7694   [(set (match_operand:SF 0 "register_operand" "")
7695         (match_operand:SF 1 "memory_operand" ""))
7696    (set (match_operand:SF 2 "register_operand" "")
7697         (match_operand:SF 3 "memory_operand" ""))]
7698   "registers_ok_for_ldd_peep (operands[0], operands[2]) 
7699    && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
7700   [(set (match_dup 0) (match_dup 1))]
7702   operands[1] = widen_mem_for_ldd_peep (operands[1], operands[3], DFmode);
7703   operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));
7706 (define_peephole2
7707   [(set (match_operand:SF 0 "memory_operand" "")
7708         (match_operand:SF 1 "register_operand" ""))
7709    (set (match_operand:SF 2 "memory_operand" "")
7710         (match_operand:SF 3 "register_operand" ""))]
7711   "registers_ok_for_ldd_peep (operands[1], operands[3]) 
7712   && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7713   [(set (match_dup 0) (match_dup 1))]
7715   operands[0] = widen_mem_for_ldd_peep (operands[0], operands[2], DFmode);
7716   operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));
7719 (define_peephole2
7720   [(set (match_operand:SI 0 "register_operand" "")
7721         (match_operand:SI 1 "memory_operand" ""))
7722    (set (match_operand:SI 2 "register_operand" "")
7723         (match_operand:SI 3 "memory_operand" ""))]
7724   "registers_ok_for_ldd_peep (operands[2], operands[0]) 
7725   && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
7726   [(set (match_dup 2) (match_dup 3))]
7728   operands[3] = widen_mem_for_ldd_peep (operands[3], operands[1], DImode);
7729   operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));
7732 (define_peephole2
7733   [(set (match_operand:SI 0 "memory_operand" "")
7734         (match_operand:SI 1 "register_operand" ""))
7735    (set (match_operand:SI 2 "memory_operand" "")
7736         (match_operand:SI 3 "register_operand" ""))]
7737   "registers_ok_for_ldd_peep (operands[3], operands[1]) 
7738   && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)" 
7739   [(set (match_dup 2) (match_dup 3))]
7741   operands[2] = widen_mem_for_ldd_peep (operands[2],  operands[0], DImode);
7742   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
7745 (define_peephole2
7746   [(set (match_operand:SF 0 "register_operand" "")
7747         (match_operand:SF 1 "memory_operand" ""))
7748    (set (match_operand:SF 2 "register_operand" "")
7749         (match_operand:SF 3 "memory_operand" ""))]
7750   "registers_ok_for_ldd_peep (operands[2], operands[0]) 
7751   && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
7752   [(set (match_dup 2) (match_dup 3))]
7754   operands[3] = widen_mem_for_ldd_peep (operands[3], operands[1], DFmode);
7755   operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));
7758 (define_peephole2
7759   [(set (match_operand:SF 0 "memory_operand" "")
7760         (match_operand:SF 1 "register_operand" ""))
7761    (set (match_operand:SF 2 "memory_operand" "")
7762         (match_operand:SF 3 "register_operand" ""))]
7763   "registers_ok_for_ldd_peep (operands[3], operands[1]) 
7764   && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
7765   [(set (match_dup 2) (match_dup 3))]
7767   operands[2] = widen_mem_for_ldd_peep (operands[2], operands[0], DFmode);
7768   operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));
7771 ;; Optimize the case of following a reg-reg move with a test
7772 ;; of reg just moved.  Don't allow floating point regs for operand 0 or 1.
7773 ;; This can result from a float to fix conversion.
7775 (define_peephole2
7776   [(set (match_operand:SI 0 "register_operand" "")
7777         (match_operand:SI 1 "register_operand" ""))
7778    (set (reg:CC CC_REG)
7779         (compare:CC (match_operand:SI 2 "register_operand" "")
7780                     (const_int 0)))]
7781   "(rtx_equal_p (operands[2], operands[0])
7782     || rtx_equal_p (operands[2], operands[1]))
7783     && !SPARC_FP_REG_P (REGNO (operands[0]))
7784     && !SPARC_FP_REG_P (REGNO (operands[1]))"
7785   [(parallel [(set (match_dup 0) (match_dup 1))
7786               (set (reg:CC CC_REG)
7787                    (compare:CC (match_dup 1) (const_int 0)))])]
7788   "")
7790 (define_peephole2
7791   [(set (match_operand:DI 0 "register_operand" "")
7792         (match_operand:DI 1 "register_operand" ""))
7793    (set (reg:CCX CC_REG)
7794         (compare:CCX (match_operand:DI 2 "register_operand" "")
7795                     (const_int 0)))]
7796   "TARGET_ARCH64
7797    && (rtx_equal_p (operands[2], operands[0])
7798        || rtx_equal_p (operands[2], operands[1]))
7799    && !SPARC_FP_REG_P (REGNO (operands[0]))
7800    && !SPARC_FP_REG_P (REGNO (operands[1]))"
7801   [(parallel [(set (match_dup 0) (match_dup 1))
7802               (set (reg:CCX CC_REG)
7803                    (compare:CCX (match_dup 1) (const_int 0)))])]
7804   "")
7807 ;; Prefetch instructions.
7809 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point
7810 ;; register file, if it hits the prefetch cache, has a chance to dual-issue
7811 ;; with other memory operations.  With DFA we might be able to model this,
7812 ;; but it requires a lot of state.
7813 (define_expand "prefetch"
7814   [(match_operand 0 "address_operand" "")
7815    (match_operand 1 "const_int_operand" "")
7816    (match_operand 2 "const_int_operand" "")]
7817   "TARGET_V9"
7819   if (TARGET_ARCH64)
7820     emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
7821   else
7822     emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
7823   DONE;
7826 (define_insn "prefetch_64"
7827   [(prefetch (match_operand:DI 0 "address_operand" "p")
7828              (match_operand:DI 1 "const_int_operand" "n")
7829              (match_operand:DI 2 "const_int_operand" "n"))]
7830   ""
7832   static const char * const prefetch_instr[2][2] = {
7833     {
7834       "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7835       "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7836     },
7837     {
7838       "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7839       "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7840     }
7841   };
7842   int read_or_write = INTVAL (operands[1]);
7843   int locality = INTVAL (operands[2]);
7845   gcc_assert (read_or_write == 0 || read_or_write == 1);
7846   gcc_assert (locality >= 0 && locality < 4);
7847   return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7849   [(set_attr "type" "load")
7850    (set_attr "subtype" "prefetch")])
7852 (define_insn "prefetch_32"
7853   [(prefetch (match_operand:SI 0 "address_operand" "p")
7854              (match_operand:SI 1 "const_int_operand" "n")
7855              (match_operand:SI 2 "const_int_operand" "n"))]
7856   ""
7858   static const char * const prefetch_instr[2][2] = {
7859     {
7860       "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7861       "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7862     },
7863     {
7864       "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7865       "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7866     }
7867   };
7868   int read_or_write = INTVAL (operands[1]);
7869   int locality = INTVAL (operands[2]);
7871   gcc_assert (read_or_write == 0 || read_or_write == 1);
7872   gcc_assert (locality >= 0 && locality < 4);
7873   return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7875   [(set_attr "type" "load")
7876    (set_attr "subtype" "prefetch")])
7879 ;; Trap instructions.
7881 (define_insn "trap"
7882   [(trap_if (const_int 1) (const_int 5))]
7883   ""
7884   "ta\t5"
7885   [(set_attr "type" "trap")])
7887 (define_expand "ctrapsi4"
7888   [(trap_if (match_operator 0 "comparison_operator"
7889              [(match_operand:SI 1 "compare_operand" "")
7890               (match_operand:SI 2 "arith_operand" "")])
7891             (match_operand 3 "arith_operand"))]
7892   ""
7894   operands[1] = gen_compare_reg (operands[0]);
7895   if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
7896     FAIL;
7897   operands[2] = const0_rtx;
7900 (define_expand "ctrapdi4"
7901   [(trap_if (match_operator 0 "comparison_operator"
7902              [(match_operand:DI 1 "compare_operand" "")
7903               (match_operand:DI 2 "arith_operand" "")])
7904             (match_operand 3 "arith_operand"))]
7905   "TARGET_ARCH64"
7907   operands[1] = gen_compare_reg (operands[0]);
7908   if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
7909     FAIL;
7910   operands[2] = const0_rtx;
7913 (define_insn "*trapsi_insn"
7914   [(trap_if (match_operator 0 "icc_comparison_operator"
7915              [(reg:CC CC_REG) (const_int 0)])
7916             (match_operand:SI 1 "arith_operand" "rM"))]
7917   ""
7919   if (TARGET_V9)
7920     return "t%C0\t%%icc, %1";
7921   else
7922     return "t%C0\t%1";
7924   [(set_attr "type" "trap")])
7926 (define_insn "*trapdi_insn"
7927   [(trap_if (match_operator 0 "icc_comparison_operator"
7928              [(reg:CCX CC_REG) (const_int 0)])
7929             (match_operand:SI 1 "arith_operand" "rM"))]
7930   "TARGET_V9"
7931   "t%C0\t%%xcc, %1"
7932   [(set_attr "type" "trap")])
7935 ;; TLS support instructions.
7937 (define_insn "tgd_hi22"
7938   [(set (match_operand:SI 0 "register_operand" "=r")
7939         (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
7940                             UNSPEC_TLSGD)))]
7941   "TARGET_TLS"
7942   "sethi\\t%%tgd_hi22(%a1), %0")
7944 (define_insn "tgd_lo10"
7945   [(set (match_operand:SI 0 "register_operand" "=r")
7946         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7947                    (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
7948                               UNSPEC_TLSGD)))]
7949   "TARGET_TLS"
7950   "add\\t%1, %%tgd_lo10(%a2), %0")
7952 (define_insn "tgd_add32"
7953   [(set (match_operand:SI 0 "register_operand" "=r")
7954         (plus:SI (match_operand:SI 1 "register_operand" "r")
7955                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7956                              (match_operand 3 "tgd_symbolic_operand" "")]
7957                             UNSPEC_TLSGD)))]
7958   "TARGET_TLS && TARGET_ARCH32"
7959   "add\\t%1, %2, %0, %%tgd_add(%a3)")
7961 (define_insn "tgd_add64"
7962   [(set (match_operand:DI 0 "register_operand" "=r")
7963         (plus:DI (match_operand:DI 1 "register_operand" "r")
7964                  (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7965                              (match_operand 3 "tgd_symbolic_operand" "")]
7966                             UNSPEC_TLSGD)))]
7967   "TARGET_TLS && TARGET_ARCH64"
7968   "add\\t%1, %2, %0, %%tgd_add(%a3)")
7970 (define_insn "tgd_call32"
7971   [(set (match_operand 0 "register_operand" "=r")
7972         (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
7973                                   (match_operand 2 "tgd_symbolic_operand" "")]
7974                                  UNSPEC_TLSGD))
7975               (match_operand 3 "" "")))
7976    (clobber (reg:SI O7_REG))]
7977   "TARGET_TLS && TARGET_ARCH32"
7978   "call\t%a1, %%tgd_call(%a2)%#"
7979   [(set_attr "type" "call")])
7981 (define_insn "tgd_call64"
7982   [(set (match_operand 0 "register_operand" "=r")
7983         (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
7984                                   (match_operand 2 "tgd_symbolic_operand" "")]
7985                                  UNSPEC_TLSGD))
7986               (match_operand 3 "" "")))
7987    (clobber (reg:DI O7_REG))]
7988   "TARGET_TLS && TARGET_ARCH64"
7989   "call\t%a1, %%tgd_call(%a2)%#"
7990   [(set_attr "type" "call")])
7992 (define_insn "tldm_hi22"
7993   [(set (match_operand:SI 0 "register_operand" "=r")
7994         (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7995   "TARGET_TLS"
7996   "sethi\\t%%tldm_hi22(%&), %0")
7998 (define_insn "tldm_lo10"
7999   [(set (match_operand:SI 0 "register_operand" "=r")
8000         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8001                     (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
8002   "TARGET_TLS"
8003   "add\\t%1, %%tldm_lo10(%&), %0")
8005 (define_insn "tldm_add32"
8006   [(set (match_operand:SI 0 "register_operand" "=r")
8007         (plus:SI (match_operand:SI 1 "register_operand" "r")
8008                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
8009                             UNSPEC_TLSLDM)))]
8010   "TARGET_TLS && TARGET_ARCH32"
8011   "add\\t%1, %2, %0, %%tldm_add(%&)")
8013 (define_insn "tldm_add64"
8014   [(set (match_operand:DI 0 "register_operand" "=r")
8015         (plus:DI (match_operand:DI 1 "register_operand" "r")
8016                  (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
8017                             UNSPEC_TLSLDM)))]
8018   "TARGET_TLS && TARGET_ARCH64"
8019   "add\\t%1, %2, %0, %%tldm_add(%&)")
8021 (define_insn "tldm_call32"
8022   [(set (match_operand 0 "register_operand" "=r")
8023         (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
8024                                  UNSPEC_TLSLDM))
8025               (match_operand 2 "" "")))
8026    (clobber (reg:SI O7_REG))]
8027   "TARGET_TLS && TARGET_ARCH32"
8028   "call\t%a1, %%tldm_call(%&)%#"
8029   [(set_attr "type" "call")])
8031 (define_insn "tldm_call64"
8032   [(set (match_operand 0 "register_operand" "=r")
8033         (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
8034                                  UNSPEC_TLSLDM))
8035               (match_operand 2 "" "")))
8036    (clobber (reg:DI O7_REG))]
8037   "TARGET_TLS && TARGET_ARCH64"
8038   "call\t%a1, %%tldm_call(%&)%#"
8039   [(set_attr "type" "call")])
8041 (define_insn "tldo_hix22"
8042   [(set (match_operand:SI 0 "register_operand" "=r")
8043         (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
8044                             UNSPEC_TLSLDO)))]
8045   "TARGET_TLS"
8046   "sethi\\t%%tldo_hix22(%a1), %0")
8048 (define_insn "tldo_lox10"
8049   [(set (match_operand:SI 0 "register_operand" "=r")
8050         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8051                    (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
8052                               UNSPEC_TLSLDO)))]
8053   "TARGET_TLS"
8054   "xor\\t%1, %%tldo_lox10(%a2), %0")
8056 (define_insn "tldo_add32"
8057   [(set (match_operand:SI 0 "register_operand" "=r")
8058         (plus:SI (match_operand:SI 1 "register_operand" "r")
8059                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8060                              (match_operand 3 "tld_symbolic_operand" "")]
8061                             UNSPEC_TLSLDO)))]
8062   "TARGET_TLS && TARGET_ARCH32"
8063   "add\\t%1, %2, %0, %%tldo_add(%a3)")
8065 (define_insn "tldo_add64"
8066   [(set (match_operand:DI 0 "register_operand" "=r")
8067         (plus:DI (match_operand:DI 1 "register_operand" "r")
8068                  (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8069                              (match_operand 3 "tld_symbolic_operand" "")]
8070                             UNSPEC_TLSLDO)))]
8071   "TARGET_TLS && TARGET_ARCH64"
8072   "add\\t%1, %2, %0, %%tldo_add(%a3)")
8074 (define_insn "tie_hi22"
8075   [(set (match_operand:SI 0 "register_operand" "=r")
8076         (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
8077                             UNSPEC_TLSIE)))]
8078   "TARGET_TLS"
8079   "sethi\\t%%tie_hi22(%a1), %0")
8081 (define_insn "tie_lo10"
8082   [(set (match_operand:SI 0 "register_operand" "=r")
8083         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8084                    (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
8085                               UNSPEC_TLSIE)))]
8086   "TARGET_TLS"
8087   "add\\t%1, %%tie_lo10(%a2), %0")
8089 (define_insn "tie_ld32"
8090   [(set (match_operand:SI 0 "register_operand" "=r")
8091         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
8092                     (match_operand:SI 2 "register_operand" "r")
8093                     (match_operand 3 "tie_symbolic_operand" "")]
8094                    UNSPEC_TLSIE))]
8095   "TARGET_TLS && TARGET_ARCH32"
8096   "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
8097   [(set_attr "type" "load")
8098    (set_attr "subtype" "regular")])
8100 (define_insn "tie_ld64"
8101   [(set (match_operand:DI 0 "register_operand" "=r")
8102         (unspec:DI [(match_operand:DI 1 "register_operand" "r")
8103                     (match_operand:SI 2 "register_operand" "r")
8104                     (match_operand 3 "tie_symbolic_operand" "")]
8105                    UNSPEC_TLSIE))]
8106   "TARGET_TLS && TARGET_ARCH64"
8107   "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
8108   [(set_attr "type" "load")
8109    (set_attr "subtype" "regular")])
8111 (define_insn "tie_add32"
8112   [(set (match_operand:SI 0 "register_operand" "=r")
8113         (plus:SI (match_operand:SI 1 "register_operand" "r")
8114                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8115                              (match_operand 3 "tie_symbolic_operand" "")]
8116                             UNSPEC_TLSIE)))]
8117   "TARGET_SUN_TLS && TARGET_ARCH32"
8118   "add\\t%1, %2, %0, %%tie_add(%a3)")
8120 (define_insn "tie_add64"
8121   [(set (match_operand:DI 0 "register_operand" "=r")
8122         (plus:DI (match_operand:DI 1 "register_operand" "r")
8123                  (unspec:DI [(match_operand:DI 2 "register_operand" "r")
8124                              (match_operand 3 "tie_symbolic_operand" "")]
8125                             UNSPEC_TLSIE)))]
8126   "TARGET_SUN_TLS && TARGET_ARCH64"
8127   "add\\t%1, %2, %0, %%tie_add(%a3)")
8129 (define_insn "tle_hix22_sp32"
8130   [(set (match_operand:SI 0 "register_operand" "=r")
8131         (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
8132                             UNSPEC_TLSLE)))]
8133   "TARGET_TLS && TARGET_ARCH32"
8134   "sethi\\t%%tle_hix22(%a1), %0")
8136 (define_insn "tle_lox10_sp32"
8137   [(set (match_operand:SI 0 "register_operand" "=r")
8138         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8139                    (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
8140                               UNSPEC_TLSLE)))]
8141   "TARGET_TLS && TARGET_ARCH32"
8142   "xor\\t%1, %%tle_lox10(%a2), %0")
8144 (define_insn "tle_hix22_sp64"
8145   [(set (match_operand:DI 0 "register_operand" "=r")
8146         (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
8147                             UNSPEC_TLSLE)))]
8148   "TARGET_TLS && TARGET_ARCH64"
8149   "sethi\\t%%tle_hix22(%a1), %0")
8151 (define_insn "tle_lox10_sp64"
8152   [(set (match_operand:DI 0 "register_operand" "=r")
8153         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
8154                    (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
8155                               UNSPEC_TLSLE)))]
8156   "TARGET_TLS && TARGET_ARCH64"
8157   "xor\\t%1, %%tle_lox10(%a2), %0")
8159 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
8160 (define_insn "*tldo_ldub_sp32"
8161   [(set (match_operand:QI 0 "register_operand" "=r")
8162         (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8163                                      (match_operand 3 "tld_symbolic_operand" "")]
8164                                     UNSPEC_TLSLDO)
8165                          (match_operand:SI 1 "register_operand" "r"))))]
8166   "TARGET_TLS && TARGET_ARCH32"
8167   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8168   [(set_attr "type" "load")
8169    (set_attr "subtype" "regular")
8170    (set_attr "us3load_type" "3cycle")])
8172 (define_insn "*tldo_ldub1_sp32"
8173   [(set (match_operand:HI 0 "register_operand" "=r")
8174         (zero_extend:HI
8175           (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8176                                        (match_operand 3 "tld_symbolic_operand" "")]
8177                                       UNSPEC_TLSLDO)
8178                            (match_operand:SI 1 "register_operand" "r")))))]
8179   "TARGET_TLS && TARGET_ARCH32"
8180   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8181   [(set_attr "type" "load")
8182    (set_attr "subtype" "regular")
8183    (set_attr "us3load_type" "3cycle")])
8185 (define_insn "*tldo_ldub2_sp32"
8186   [(set (match_operand:SI 0 "register_operand" "=r")
8187         (zero_extend:SI
8188           (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8189                                        (match_operand 3 "tld_symbolic_operand" "")]
8190                                       UNSPEC_TLSLDO)
8191                            (match_operand:SI 1 "register_operand" "r")))))]
8192   "TARGET_TLS && TARGET_ARCH32"
8193   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8194   [(set_attr "type" "load")
8195    (set_attr "subtype" "regular")
8196    (set_attr "us3load_type" "3cycle")])
8198 (define_insn "*tldo_ldsb1_sp32"
8199   [(set (match_operand:HI 0 "register_operand" "=r")
8200         (sign_extend:HI
8201           (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8202                                        (match_operand 3 "tld_symbolic_operand" "")]
8203                                       UNSPEC_TLSLDO)
8204                            (match_operand:SI 1 "register_operand" "r")))))]
8205   "TARGET_TLS && TARGET_ARCH32"
8206   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8207   [(set_attr "type" "sload")
8208    (set_attr "us3load_type" "3cycle")])
8210 (define_insn "*tldo_ldsb2_sp32"
8211   [(set (match_operand:SI 0 "register_operand" "=r")
8212         (sign_extend:SI
8213           (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8214                                        (match_operand 3 "tld_symbolic_operand" "")]
8215                                       UNSPEC_TLSLDO)
8216                            (match_operand:SI 1 "register_operand" "r")))))]
8217   "TARGET_TLS && TARGET_ARCH32"
8218   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8219   [(set_attr "type" "sload")
8220    (set_attr "us3load_type" "3cycle")])
8222 (define_insn "*tldo_ldub_sp64"
8223   [(set (match_operand:QI 0 "register_operand" "=r")
8224         (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8225                                      (match_operand 3 "tld_symbolic_operand" "")]
8226                                     UNSPEC_TLSLDO)
8227                          (match_operand:DI 1 "register_operand" "r"))))]
8228   "TARGET_TLS && TARGET_ARCH64"
8229   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8230   [(set_attr "type" "load")
8231    (set_attr "subtype" "regular")
8232    (set_attr "us3load_type" "3cycle")])
8234 (define_insn "*tldo_ldub1_sp64"
8235   [(set (match_operand:HI 0 "register_operand" "=r")
8236         (zero_extend:HI
8237           (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8238                                        (match_operand 3 "tld_symbolic_operand" "")]
8239                                       UNSPEC_TLSLDO)
8240                            (match_operand:DI 1 "register_operand" "r")))))]
8241   "TARGET_TLS && TARGET_ARCH64"
8242   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8243   [(set_attr "type" "load")
8244    (set_attr "subtype" "regular")
8245    (set_attr "us3load_type" "3cycle")])
8247 (define_insn "*tldo_ldub2_sp64"
8248   [(set (match_operand:SI 0 "register_operand" "=r")
8249         (zero_extend:SI
8250           (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8251                                        (match_operand 3 "tld_symbolic_operand" "")]
8252                                       UNSPEC_TLSLDO)
8253                            (match_operand:DI 1 "register_operand" "r")))))]
8254   "TARGET_TLS && TARGET_ARCH64"
8255   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8256   [(set_attr "type" "load")
8257    (set_attr "subtype" "regular")
8258    (set_attr "us3load_type" "3cycle")])
8260 (define_insn "*tldo_ldub3_sp64"
8261   [(set (match_operand:DI 0 "register_operand" "=r")
8262         (zero_extend:DI
8263           (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8264                                        (match_operand 3 "tld_symbolic_operand" "")]
8265                                       UNSPEC_TLSLDO)
8266                            (match_operand:DI 1 "register_operand" "r")))))]
8267   "TARGET_TLS && TARGET_ARCH64"
8268   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8269   [(set_attr "type" "load")
8270    (set_attr "subtype" "regular")
8271    (set_attr "us3load_type" "3cycle")])
8273 (define_insn "*tldo_ldsb1_sp64"
8274   [(set (match_operand:HI 0 "register_operand" "=r")
8275         (sign_extend:HI
8276           (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8277                                        (match_operand 3 "tld_symbolic_operand" "")]
8278                                       UNSPEC_TLSLDO)
8279                            (match_operand:DI 1 "register_operand" "r")))))]
8280   "TARGET_TLS && TARGET_ARCH64"
8281   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8282   [(set_attr "type" "sload")
8283    (set_attr "us3load_type" "3cycle")])
8285 (define_insn "*tldo_ldsb2_sp64"
8286   [(set (match_operand:SI 0 "register_operand" "=r")
8287         (sign_extend:SI
8288           (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8289                                        (match_operand 3 "tld_symbolic_operand" "")]
8290                                       UNSPEC_TLSLDO)
8291                            (match_operand:DI 1 "register_operand" "r")))))]
8292   "TARGET_TLS && TARGET_ARCH64"
8293   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8294   [(set_attr "type" "sload")
8295    (set_attr "us3load_type" "3cycle")])
8297 (define_insn "*tldo_ldsb3_sp64"
8298   [(set (match_operand:DI 0 "register_operand" "=r")
8299         (sign_extend:DI
8300           (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8301                                        (match_operand 3 "tld_symbolic_operand" "")]
8302                                       UNSPEC_TLSLDO)
8303                            (match_operand:DI 1 "register_operand" "r")))))]
8304   "TARGET_TLS && TARGET_ARCH64"
8305   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8306   [(set_attr "type" "sload")
8307    (set_attr "us3load_type" "3cycle")])
8309 (define_insn "*tldo_lduh_sp32"
8310   [(set (match_operand:HI 0 "register_operand" "=r")
8311         (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8312                                      (match_operand 3 "tld_symbolic_operand" "")]
8313                                     UNSPEC_TLSLDO)
8314                          (match_operand:SI 1 "register_operand" "r"))))]
8315   "TARGET_TLS && TARGET_ARCH32"
8316   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8317   [(set_attr "type" "load")
8318    (set_attr "subtype" "regular")
8319    (set_attr "us3load_type" "3cycle")])
8321 (define_insn "*tldo_lduh1_sp32"
8322   [(set (match_operand:SI 0 "register_operand" "=r")
8323         (zero_extend:SI
8324           (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8325                                        (match_operand 3 "tld_symbolic_operand" "")]
8326                                       UNSPEC_TLSLDO)
8327                            (match_operand:SI 1 "register_operand" "r")))))]
8328   "TARGET_TLS && TARGET_ARCH32"
8329   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8330   [(set_attr "type" "load")
8331    (set_attr "subtype" "regular")
8332    (set_attr "us3load_type" "3cycle")])
8334 (define_insn "*tldo_ldsh1_sp32"
8335   [(set (match_operand:SI 0 "register_operand" "=r")
8336         (sign_extend:SI
8337           (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8338                                        (match_operand 3 "tld_symbolic_operand" "")]
8339                                       UNSPEC_TLSLDO)
8340                            (match_operand:SI 1 "register_operand" "r")))))]
8341   "TARGET_TLS && TARGET_ARCH32"
8342   "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8343   [(set_attr "type" "sload")
8344    (set_attr "us3load_type" "3cycle")])
8346 (define_insn "*tldo_lduh_sp64"
8347   [(set (match_operand:HI 0 "register_operand" "=r")
8348         (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8349                                      (match_operand 3 "tld_symbolic_operand" "")]
8350                                     UNSPEC_TLSLDO)
8351                          (match_operand:DI 1 "register_operand" "r"))))]
8352   "TARGET_TLS && TARGET_ARCH64"
8353   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8354   [(set_attr "type" "load")
8355    (set_attr "subtype" "regular")
8356    (set_attr "us3load_type" "3cycle")])
8358 (define_insn "*tldo_lduh1_sp64"
8359   [(set (match_operand:SI 0 "register_operand" "=r")
8360         (zero_extend:SI
8361           (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8362                                        (match_operand 3 "tld_symbolic_operand" "")]
8363                                       UNSPEC_TLSLDO)
8364                            (match_operand:DI 1 "register_operand" "r")))))]
8365   "TARGET_TLS && TARGET_ARCH64"
8366   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8367   [(set_attr "type" "load")
8368    (set_attr "subtype" "regular")
8369    (set_attr "us3load_type" "3cycle")])
8371 (define_insn "*tldo_lduh2_sp64"
8372   [(set (match_operand:DI 0 "register_operand" "=r")
8373         (zero_extend:DI
8374           (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8375                                        (match_operand 3 "tld_symbolic_operand" "")]
8376                                       UNSPEC_TLSLDO)
8377                            (match_operand:DI 1 "register_operand" "r")))))]
8378   "TARGET_TLS && TARGET_ARCH64"
8379   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8380   [(set_attr "type" "load")
8381    (set_attr "subtype" "regular")
8382    (set_attr "us3load_type" "3cycle")])
8384 (define_insn "*tldo_ldsh1_sp64"
8385   [(set (match_operand:SI 0 "register_operand" "=r")
8386         (sign_extend:SI
8387           (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8388                                        (match_operand 3 "tld_symbolic_operand" "")]
8389                                       UNSPEC_TLSLDO)
8390                            (match_operand:DI 1 "register_operand" "r")))))]
8391   "TARGET_TLS && TARGET_ARCH64"
8392   "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8393   [(set_attr "type" "sload")
8394    (set_attr "us3load_type" "3cycle")])
8396 (define_insn "*tldo_ldsh2_sp64"
8397   [(set (match_operand:DI 0 "register_operand" "=r")
8398         (sign_extend:DI
8399           (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8400                                        (match_operand 3 "tld_symbolic_operand" "")]
8401                                       UNSPEC_TLSLDO)
8402                            (match_operand:DI 1 "register_operand" "r")))))]
8403   "TARGET_TLS && TARGET_ARCH64"
8404   "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8405   [(set_attr "type" "sload")
8406    (set_attr "us3load_type" "3cycle")])
8408 (define_insn "*tldo_lduw_sp32"
8409   [(set (match_operand:SI 0 "register_operand" "=r")
8410         (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8411                                      (match_operand 3 "tld_symbolic_operand" "")]
8412                                     UNSPEC_TLSLDO)
8413                          (match_operand:SI 1 "register_operand" "r"))))]
8414   "TARGET_TLS && TARGET_ARCH32"
8415   "ld\t[%1 + %2], %0, %%tldo_add(%3)"
8416   [(set_attr "type" "load")
8417    (set_attr "subtype" "regular")])
8419 (define_insn "*tldo_lduw_sp64"
8420   [(set (match_operand:SI 0 "register_operand" "=r")
8421         (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8422                                      (match_operand 3 "tld_symbolic_operand" "")]
8423                                     UNSPEC_TLSLDO)
8424                          (match_operand:DI 1 "register_operand" "r"))))]
8425   "TARGET_TLS && TARGET_ARCH64"
8426   "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8427   [(set_attr "type" "load")
8428    (set_attr "subtype" "regular")])
8430 (define_insn "*tldo_lduw1_sp64"
8431   [(set (match_operand:DI 0 "register_operand" "=r")
8432         (zero_extend:DI
8433           (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8434                                        (match_operand 3 "tld_symbolic_operand" "")]
8435                                       UNSPEC_TLSLDO)
8436                            (match_operand:DI 1 "register_operand" "r")))))]
8437   "TARGET_TLS && TARGET_ARCH64"
8438   "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8439   [(set_attr "type" "load")
8440    (set_attr "subtype" "regular")])
8442 (define_insn "*tldo_ldsw1_sp64"
8443   [(set (match_operand:DI 0 "register_operand" "=r")
8444         (sign_extend:DI
8445           (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8446                                         (match_operand 3 "tld_symbolic_operand" "")]
8447                                       UNSPEC_TLSLDO)
8448                            (match_operand:DI 1 "register_operand" "r")))))]
8449   "TARGET_TLS && TARGET_ARCH64"
8450   "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
8451   [(set_attr "type" "sload")
8452    (set_attr "us3load_type" "3cycle")])
8454 (define_insn "*tldo_ldx_sp64"
8455   [(set (match_operand:DI 0 "register_operand" "=r")
8456         (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8457                                      (match_operand 3 "tld_symbolic_operand" "")]
8458                                     UNSPEC_TLSLDO)
8459                          (match_operand:DI 1 "register_operand" "r"))))]
8460   "TARGET_TLS && TARGET_ARCH64"
8461   "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
8462   [(set_attr "type" "load")
8463    (set_attr "subtype" "regular")])
8465 (define_insn "*tldo_stb_sp32"
8466   [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8467                                      (match_operand 3 "tld_symbolic_operand" "")]
8468                                     UNSPEC_TLSLDO)
8469                          (match_operand:SI 1 "register_operand" "r")))
8470         (match_operand:QI 0 "register_operand" "r"))]
8471   "TARGET_TLS && TARGET_ARCH32"
8472   "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8473   [(set_attr "type" "store")])
8475 (define_insn "*tldo_stb_sp64"
8476   [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8477                                      (match_operand 3 "tld_symbolic_operand" "")]
8478                                     UNSPEC_TLSLDO)
8479                          (match_operand:DI 1 "register_operand" "r")))
8480         (match_operand:QI 0 "register_operand" "r"))]
8481   "TARGET_TLS && TARGET_ARCH64"
8482   "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8483   [(set_attr "type" "store")])
8485 (define_insn "*tldo_sth_sp32"
8486   [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8487                                      (match_operand 3 "tld_symbolic_operand" "")]
8488                                     UNSPEC_TLSLDO)
8489                          (match_operand:SI 1 "register_operand" "r")))
8490         (match_operand:HI 0 "register_operand" "r"))]
8491   "TARGET_TLS && TARGET_ARCH32"
8492   "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8493   [(set_attr "type" "store")])
8495 (define_insn "*tldo_sth_sp64"
8496   [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8497                                      (match_operand 3 "tld_symbolic_operand" "")]
8498                                     UNSPEC_TLSLDO)
8499                          (match_operand:DI 1 "register_operand" "r")))
8500         (match_operand:HI 0 "register_operand" "r"))]
8501   "TARGET_TLS && TARGET_ARCH64"
8502   "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8503   [(set_attr "type" "store")])
8505 (define_insn "*tldo_stw_sp32"
8506   [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8507                                      (match_operand 3 "tld_symbolic_operand" "")]
8508                                     UNSPEC_TLSLDO)
8509                          (match_operand:SI 1 "register_operand" "r")))
8510         (match_operand:SI 0 "register_operand" "r"))]
8511   "TARGET_TLS && TARGET_ARCH32"
8512   "st\t%0, [%1 + %2], %%tldo_add(%3)"
8513   [(set_attr "type" "store")])
8515 (define_insn "*tldo_stw_sp64"
8516   [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8517                                      (match_operand 3 "tld_symbolic_operand" "")]
8518                                     UNSPEC_TLSLDO)
8519                          (match_operand:DI 1 "register_operand" "r")))
8520         (match_operand:SI 0 "register_operand" "r"))]
8521   "TARGET_TLS && TARGET_ARCH64"
8522   "stw\t%0, [%1 + %2], %%tldo_add(%3)"
8523   [(set_attr "type" "store")])
8525 (define_insn "*tldo_stx_sp64"
8526   [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8527                                      (match_operand 3 "tld_symbolic_operand" "")]
8528                                     UNSPEC_TLSLDO)
8529                          (match_operand:DI 1 "register_operand" "r")))
8530         (match_operand:DI 0 "register_operand" "r"))]
8531   "TARGET_TLS && TARGET_ARCH64"
8532   "stx\t%0, [%1 + %2], %%tldo_add(%3)"
8533   [(set_attr "type" "store")])
8536 ;; Stack protector instructions.
8538 (define_expand "stack_protect_set"
8539   [(match_operand 0 "memory_operand" "")
8540    (match_operand 1 "memory_operand" "")]
8541   ""
8543 #ifdef TARGET_THREAD_SSP_OFFSET
8544   rtx tlsreg = gen_rtx_REG (Pmode, 7);
8545   rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
8546   operands[1] = gen_rtx_MEM (Pmode, addr);
8547 #endif
8548   if (TARGET_ARCH64)
8549     emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
8550   else
8551     emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
8552   DONE;
8555 (define_insn "stack_protect_setsi"
8556   [(set (match_operand:SI 0 "memory_operand" "=m")
8557         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
8558    (set (match_scratch:SI 2 "=&r") (const_int 0))]
8559   "TARGET_ARCH32"
8560   "ld\t%1, %2\;st\t%2, %0\;mov\t0, %2"
8561   [(set_attr "type" "multi")
8562    (set_attr "length" "3")])
8564 (define_insn "stack_protect_setdi"
8565   [(set (match_operand:DI 0 "memory_operand" "=m")
8566         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
8567    (set (match_scratch:DI 2 "=&r") (const_int 0))]
8568   "TARGET_ARCH64"
8569   "ldx\t%1, %2\;stx\t%2, %0\;mov\t0, %2"
8570   [(set_attr "type" "multi")
8571    (set_attr "length" "3")])
8573 (define_expand "stack_protect_test"
8574   [(match_operand 0 "memory_operand" "")
8575    (match_operand 1 "memory_operand" "")
8576    (match_operand 2 "" "")]
8577   ""
8579   rtx result, test;
8580 #ifdef TARGET_THREAD_SSP_OFFSET
8581   rtx tlsreg = gen_rtx_REG (Pmode, 7);
8582   rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
8583   operands[1] = gen_rtx_MEM (Pmode, addr);
8584 #endif
8585   if (TARGET_ARCH64)
8586     {
8587       result = gen_reg_rtx (Pmode);
8588       emit_insn (gen_stack_protect_testdi (result, operands[0], operands[1]));
8589       test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
8590       emit_jump_insn (gen_cbranchdi4 (test, result, const0_rtx, operands[2]));
8591     }
8592   else
8593     {
8594       emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
8595       result = gen_rtx_REG (CCmode, SPARC_ICC_REG);
8596       test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
8597       emit_jump_insn (gen_cbranchcc4 (test, result, const0_rtx, operands[2]));
8598     }
8599   DONE;
8602 (define_insn "stack_protect_testsi"
8603   [(set (reg:CC CC_REG)
8604         (unspec:CC [(match_operand:SI 0 "memory_operand" "m")
8605                     (match_operand:SI 1 "memory_operand" "m")]
8606                    UNSPEC_SP_TEST))
8607    (set (match_scratch:SI 3 "=r") (const_int 0))
8608    (clobber (match_scratch:SI 2 "=&r"))]
8609   "TARGET_ARCH32"
8610   "ld\t%0, %2\;ld\t%1, %3\;xorcc\t%2, %3, %2\;mov\t0, %3"
8611   [(set_attr "type" "multi")
8612    (set_attr "length" "4")])
8614 (define_insn "stack_protect_testdi"
8615   [(set (match_operand:DI 0 "register_operand" "=&r")
8616         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
8617                     (match_operand:DI 2 "memory_operand" "m")]
8618                    UNSPEC_SP_TEST))
8619    (set (match_scratch:DI 3 "=r") (const_int 0))]
8620   "TARGET_ARCH64"
8621   "ldx\t%1, %0\;ldx\t%2, %3\;xor\t%0, %3, %0\;mov\t0, %3"
8622   [(set_attr "type" "multi")
8623    (set_attr "length" "4")])
8626 ;; Vector instructions.
8628 (define_mode_iterator VM32 [V1SI V2HI V4QI])
8629 (define_mode_iterator VM64 [V1DI V2SI V4HI V8QI])
8630 (define_mode_iterator VMALL [V1SI V2HI V4QI V1DI V2SI V4HI V8QI])
8632 (define_mode_attr vbits [(V2SI "32") (V4HI "16") (V1SI "32s") (V2HI "16s")
8633                          (V8QI "8")])
8634 (define_mode_attr vconstr [(V1SI "f") (V2HI "f") (V4QI "f")
8635                            (V1DI "e") (V2SI "e") (V4HI "e") (V8QI "e")])
8636 (define_mode_attr vfptype [(V1SI "single") (V2HI "single") (V4QI "single")
8637                            (V1DI "double") (V2SI "double") (V4HI "double")
8638                            (V8QI "double")])
8639 (define_mode_attr veltmode [(V1SI "si") (V2HI "hi") (V4QI "qi") (V1DI "di")
8640                             (V2SI "si") (V4HI "hi") (V8QI "qi")])
8642 (define_expand "mov<VMALL:mode>"
8643   [(set (match_operand:VMALL 0 "nonimmediate_operand" "")
8644         (match_operand:VMALL 1 "general_operand" ""))]
8645   "TARGET_VIS"
8647   if (sparc_expand_move (<VMALL:MODE>mode, operands))
8648     DONE;
8651 (define_insn "*mov<VM32:mode>_insn"
8652   [(set (match_operand:VM32 0 "nonimmediate_operand" "=f,f,f,f,m,m,*r, m,*r,*r, f")
8653         (match_operand:VM32 1 "input_operand"         "Y,Z,f,m,f,Y, m,*r,*r, f,*r"))]
8654   "TARGET_VIS
8655    && (register_operand (operands[0], <VM32:MODE>mode)
8656        || register_or_zero_or_all_ones_operand (operands[1], <VM32:MODE>mode))"
8657   "@
8658   fzeros\t%0
8659   fones\t%0
8660   fsrc2s\t%1, %0
8661   ld\t%1, %0
8662   st\t%1, %0
8663   st\t%r1, %0
8664   ld\t%1, %0
8665   st\t%1, %0
8666   mov\t%1, %0
8667   movstouw\t%1, %0
8668   movwtos\t%1, %0"
8669   [(set_attr "type" "visl,visl,vismv,fpload,fpstore,store,load,store,*,vismv,vismv")
8670    (set_attr "subtype" "single,single,single,*,*,*,regular,*,*,movstouw,single")
8671    (set_attr "cpu_feature" "vis,vis,vis,*,*,*,*,*,*,vis3,vis3")])
8673 (define_insn "*mov<VM64:mode>_insn_sp64"
8674   [(set (match_operand:VM64 0 "nonimmediate_operand" "=e,e,e,e,W,m,*r, m,*r, e,*r")
8675         (match_operand:VM64 1 "input_operand"         "Y,Z,e,W,e,Y, m,*r, e,*r,*r"))]
8676   "TARGET_VIS
8677    && TARGET_ARCH64
8678    && (register_operand (operands[0], <VM64:MODE>mode)
8679        || register_or_zero_or_all_ones_operand (operands[1], <VM64:MODE>mode))"
8680   "@
8681   fzero\t%0
8682   fone\t%0
8683   fsrc2\t%1, %0
8684   ldd\t%1, %0
8685   std\t%1, %0
8686   stx\t%r1, %0
8687   ldx\t%1, %0
8688   stx\t%1, %0
8689   movdtox\t%1, %0
8690   movxtod\t%1, %0
8691   mov\t%1, %0"
8692   [(set_attr "type" "visl,visl,vismv,fpload,fpstore,store,load,store,vismv,vismv,*")
8693    (set_attr "subtype" "double,double,double,*,*,*,regular,*,movdtox,movxtod,*")
8694    (set_attr "cpu_feature" "vis,vis,vis,*,*,*,*,*,vis3,vis3,*")])
8696 (define_insn "*mov<VM64:mode>_insn_sp32"
8697   [(set (match_operand:VM64 0 "nonimmediate_operand"
8698                               "=T,o,e,e,e,*r, f,e,T,U,T,f,o,*r,*r, o")
8699         (match_operand:VM64 1 "input_operand"
8700                               " Y,Y,Y,Z,e, f,*r,T,e,T,U,o,f,*r, o,*r"))]
8701   "TARGET_VIS
8702    && TARGET_ARCH32
8703    && (register_operand (operands[0], <VM64:MODE>mode)
8704        || register_or_zero_or_all_ones_operand (operands[1], <VM64:MODE>mode))"
8705   "@
8706   stx\t%r1, %0
8707   #
8708   fzero\t%0
8709   fone\t%0
8710   fsrc2\t%1, %0
8711   #
8712   #
8713   ldd\t%1, %0
8714   std\t%1, %0
8715   ldd\t%1, %0
8716   std\t%1, %0
8717   #
8718   #
8719   #
8720   ldd\t%1, %0
8721   std\t%1, %0"
8722   [(set_attr "type" "store,*,visl,visl,vismv,*,*,fpload,fpstore,load,store,*,*,*,load,store")
8723    (set_attr "subtype" "*,*,double,double,double,*,*,*,*,regular,*,*,*,*,regular,*")
8724    (set_attr "length" "*,2,*,*,*,2,2,*,*,*,*,2,2,2,*,*")
8725    (set_attr "cpu_feature" "*,*,vis,vis,vis,vis3,vis3,*,*,*,*,*,*,*,*,*")
8726    (set_attr "lra" "*,*,*,*,*,*,*,*,*,disabled,disabled,*,*,*,*,*")])
8728 (define_split
8729   [(set (match_operand:VM64 0 "register_operand" "")
8730         (match_operand:VM64 1 "register_operand" ""))]
8731   "reload_completed
8732    && TARGET_VIS
8733    && TARGET_ARCH32
8734    && sparc_split_reg_reg_legitimate (operands[0], operands[1])"
8735   [(clobber (const_int 0))]
8737   sparc_split_reg_reg (operands[0], operands[1], SImode);
8738   DONE;
8741 (define_split
8742   [(set (match_operand:VM64 0 "register_operand" "")
8743         (match_operand:VM64 1 "memory_operand" ""))]
8744   "reload_completed
8745    && TARGET_VIS
8746    && TARGET_ARCH32
8747    && sparc_split_reg_mem_legitimate (operands[0], operands[1])"
8748   [(clobber (const_int 0))]
8750   sparc_split_reg_mem (operands[0], operands[1], SImode);
8751   DONE;
8754 (define_split
8755   [(set (match_operand:VM64 0 "memory_operand" "")
8756         (match_operand:VM64 1 "register_operand" ""))]
8757   "reload_completed
8758    && TARGET_VIS
8759    && TARGET_ARCH32
8760    && sparc_split_reg_mem_legitimate (operands[1], operands[0])"
8761   [(clobber (const_int 0))]
8763   sparc_split_mem_reg (operands[0], operands[1], SImode);
8764   DONE;
8767 (define_split
8768   [(set (match_operand:VM64 0 "memory_operand" "")
8769         (match_operand:VM64 1 "const_zero_operand" ""))]
8770   "reload_completed
8771    && TARGET_VIS
8772    && TARGET_ARCH32
8773    && !mem_min_alignment (operands[0], 8)
8774    && offsettable_memref_p (operands[0])"
8775   [(clobber (const_int 0))]
8777   emit_move_insn_1 (adjust_address (operands[0], SImode, 0), const0_rtx);
8778   emit_move_insn_1 (adjust_address (operands[0], SImode, 4), const0_rtx);
8779   DONE;
8782 (define_expand "vec_init<VMALL:mode><VMALL:veltmode>"
8783   [(match_operand:VMALL 0 "register_operand" "")
8784    (match_operand:VMALL 1 "" "")]
8785   "TARGET_VIS"
8787   sparc_expand_vector_init (operands[0], operands[1]);
8788   DONE;
8791 (define_code_iterator plusminus [plus minus])
8792 (define_code_attr plusminus_insn [(plus "add") (minus "sub")])
8794 (define_mode_iterator VADDSUB [V1SI V2SI V2HI V4HI])
8796 (define_insn "<plusminus_insn><VADDSUB:mode>3"
8797   [(set (match_operand:VADDSUB 0 "register_operand" "=<vconstr>")
8798         (plusminus:VADDSUB (match_operand:VADDSUB 1 "register_operand" "<vconstr>")
8799                            (match_operand:VADDSUB 2 "register_operand" "<vconstr>")))]
8800   "TARGET_VIS"
8801   "fp<plusminus_insn><vbits>\t%1, %2, %0"
8802   [(set_attr "type" "fga")
8803    (set_attr "subtype" "other")
8804    (set_attr "fptype" "<vfptype>")])
8806 (define_mode_iterator VL [V1SI V2HI V4QI V1DI V2SI V4HI V8QI])
8807 (define_mode_attr vlsuf [(V1SI "s") (V2HI "s") (V4QI "s")
8808                          (V1DI  "") (V2SI  "") (V4HI  "") (V8QI "")])
8809 (define_code_iterator vlop [ior and xor])
8810 (define_code_attr vlinsn [(ior "or") (and "and") (xor "xor")])
8811 (define_code_attr vlninsn [(ior "nor") (and "nand") (xor "xnor")])
8813 (define_insn "<vlop:code><VL:mode>3"
8814   [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8815         (vlop:VL (match_operand:VL 1 "register_operand" "<vconstr>")
8816                  (match_operand:VL 2 "register_operand" "<vconstr>")))]
8817   "TARGET_VIS"
8818   "f<vlinsn><vlsuf>\t%1, %2, %0"
8819   [(set_attr "type" "visl")
8820    (set_attr "fptype" "<vfptype>")])
8822 (define_insn "*not_<vlop:code><VL:mode>3"
8823   [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8824         (not:VL (vlop:VL (match_operand:VL 1 "register_operand" "<vconstr>")
8825                          (match_operand:VL 2 "register_operand" "<vconstr>"))))]
8826   "TARGET_VIS"
8827   "f<vlninsn><vlsuf>\t%1, %2, %0"
8828   [(set_attr "type" "visl")
8829    (set_attr "fptype" "<vfptype>")])
8831 ;; (ior (not (op1)) (not (op2))) is the canonical form of NAND.
8832 (define_insn "*nand<VL:mode>_vis"
8833   [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8834         (ior:VL (not:VL (match_operand:VL 1 "register_operand" "<vconstr>"))
8835                 (not:VL (match_operand:VL 2 "register_operand" "<vconstr>"))))]
8836   "TARGET_VIS"
8837   "fnand<vlsuf>\t%1, %2, %0"
8838   [(set_attr "type" "visl")
8839    (set_attr "fptype" "<vfptype>")])
8841 (define_code_iterator vlnotop [ior and])
8843 (define_insn "*<vlnotop:code>_not1<VL:mode>_vis"
8844   [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8845         (vlnotop:VL (not:VL (match_operand:VL 1 "register_operand" "<vconstr>"))
8846                     (match_operand:VL 2 "register_operand" "<vconstr>")))]
8847   "TARGET_VIS"
8848   "f<vlinsn>not1<vlsuf>\t%1, %2, %0"
8849   [(set_attr "type" "visl")
8850    (set_attr "fptype" "<vfptype>")])
8852 (define_insn "*<vlnotop:code>_not2<VL:mode>_vis"
8853   [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8854         (vlnotop:VL (match_operand:VL 1 "register_operand" "<vconstr>")
8855                     (not:VL (match_operand:VL 2 "register_operand" "<vconstr>"))))]
8856   "TARGET_VIS"
8857   "f<vlinsn>not2<vlsuf>\t%1, %2, %0"
8858   [(set_attr "type" "visl")
8859    (set_attr "fptype" "<vfptype>")])
8861 (define_insn "one_cmpl<VL:mode>2"
8862   [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8863         (not:VL (match_operand:VL 1 "register_operand" "<vconstr>")))]
8864   "TARGET_VIS"
8865   "fnot1<vlsuf>\t%1, %0"
8866   [(set_attr "type" "visl")
8867    (set_attr "fptype" "<vfptype>")])
8869 ;; Hard to generate VIS instructions.  We have builtins for these.
8871 (define_insn "fpack16_vis"
8872   [(set (match_operand:V4QI 0 "register_operand" "=f")
8873         (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e")
8874                       (reg:DI GSR_REG)]
8875                       UNSPEC_FPACK16))]
8876   "TARGET_VIS"
8877   "fpack16\t%1, %0"
8878   [(set_attr "type" "fgm_pack")
8879    (set_attr "fptype" "double")])
8881 (define_insn "fpackfix_vis"
8882   [(set (match_operand:V2HI 0 "register_operand" "=f")
8883         (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e")
8884                       (reg:DI GSR_REG)]
8885                       UNSPEC_FPACKFIX))]
8886   "TARGET_VIS"
8887   "fpackfix\t%1, %0"
8888   [(set_attr "type" "fgm_pack")
8889    (set_attr "fptype" "double")])
8891 (define_insn "fpack32_vis"
8892   [(set (match_operand:V8QI 0 "register_operand" "=e")
8893         (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e")
8894                       (match_operand:V8QI 2 "register_operand" "e")
8895                       (reg:DI GSR_REG)]
8896                      UNSPEC_FPACK32))]
8897   "TARGET_VIS"
8898   "fpack32\t%1, %2, %0"
8899   [(set_attr "type" "fgm_pack")
8900    (set_attr "fptype" "double")])
8902 (define_insn "fexpand_vis"
8903   [(set (match_operand:V4HI 0 "register_operand" "=e")
8904         (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")]
8905          UNSPEC_FEXPAND))]
8906  "TARGET_VIS"
8907  "fexpand\t%1, %0"
8908  [(set_attr "type" "fga")
8909   (set_attr "subtype" "fpu")
8910   (set_attr "fptype" "double")])
8912 (define_insn "fpmerge_vis"
8913   [(set (match_operand:V8QI 0 "register_operand" "=e")
8914         (vec_select:V8QI
8915           (vec_concat:V8QI (match_operand:V4QI 1 "register_operand" "f")
8916                            (match_operand:V4QI 2 "register_operand" "f"))
8917           (parallel [(const_int 0) (const_int 4)
8918                      (const_int 1) (const_int 5)
8919                      (const_int 2) (const_int 6)
8920                      (const_int 3) (const_int 7)])))]
8921  "TARGET_VIS"
8922  "fpmerge\t%1, %2, %0"
8923  [(set_attr "type" "fga")
8924   (set_attr "subtype" "fpu")
8925   (set_attr "fptype" "double")])
8927 ;; Partitioned multiply instructions
8928 (define_insn "fmul8x16_vis"
8929   [(set (match_operand:V4HI 0 "register_operand" "=e")
8930         (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8931                       (match_operand:V4HI 2 "register_operand" "e")]
8932          UNSPEC_MUL8))]
8933   "TARGET_VIS"
8934   "fmul8x16\t%1, %2, %0"
8935   [(set_attr "type" "fgm_mul")
8936    (set_attr "fptype" "double")])
8938 (define_insn "fmul8x16au_vis"
8939   [(set (match_operand:V4HI 0 "register_operand" "=e")
8940         (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8941                       (match_operand:V2HI 2 "register_operand" "f")]
8942          UNSPEC_MUL16AU))]
8943   "TARGET_VIS"
8944   "fmul8x16au\t%1, %2, %0"
8945   [(set_attr "type" "fgm_mul")
8946    (set_attr "fptype" "double")])
8948 (define_insn "fmul8x16al_vis"
8949   [(set (match_operand:V4HI 0 "register_operand" "=e")
8950         (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8951                       (match_operand:V2HI 2 "register_operand" "f")]
8952          UNSPEC_MUL16AL))]
8953   "TARGET_VIS"
8954   "fmul8x16al\t%1, %2, %0"
8955   [(set_attr "type" "fgm_mul")
8956    (set_attr "fptype" "double")])
8958 (define_insn "fmul8sux16_vis"
8959   [(set (match_operand:V4HI 0 "register_operand" "=e")
8960         (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
8961                       (match_operand:V4HI 2 "register_operand" "e")]
8962          UNSPEC_MUL8SU))]
8963   "TARGET_VIS"
8964   "fmul8sux16\t%1, %2, %0"
8965   [(set_attr "type" "fgm_mul")
8966    (set_attr "fptype" "double")])
8968 (define_insn "fmul8ulx16_vis"
8969   [(set (match_operand:V4HI 0 "register_operand" "=e")
8970         (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
8971                       (match_operand:V4HI 2 "register_operand" "e")]
8972          UNSPEC_MUL8UL))]
8973   "TARGET_VIS"
8974   "fmul8ulx16\t%1, %2, %0"
8975   [(set_attr "type" "fgm_mul")
8976    (set_attr "fptype" "double")])
8978 (define_insn "fmuld8sux16_vis"
8979   [(set (match_operand:V2SI 0 "register_operand" "=e")
8980         (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
8981                       (match_operand:V2HI 2 "register_operand" "f")]
8982          UNSPEC_MULDSU))]
8983   "TARGET_VIS"
8984   "fmuld8sux16\t%1, %2, %0"
8985   [(set_attr "type" "fgm_mul")
8986    (set_attr "fptype" "double")])
8988 (define_insn "fmuld8ulx16_vis"
8989   [(set (match_operand:V2SI 0 "register_operand" "=e")
8990         (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
8991                       (match_operand:V2HI 2 "register_operand" "f")]
8992          UNSPEC_MULDUL))]
8993   "TARGET_VIS"
8994   "fmuld8ulx16\t%1, %2, %0"
8995   [(set_attr "type" "fgm_mul")
8996    (set_attr "fptype" "double")])
8998 (define_expand "wrgsr_vis"
8999   [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" ""))]
9000   "TARGET_VIS"
9002   if (TARGET_ARCH32)
9003     {
9004       emit_insn (gen_wrgsr_v8plus (operands[0]));
9005       DONE;
9006     }
9009 (define_insn "*wrgsr_sp64"
9010   [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" "rI"))]
9011   "TARGET_VIS && TARGET_ARCH64"
9012   "wr\t%%g0, %0, %%gsr"
9013   [(set_attr "type" "gsr")
9014    (set_attr "subtype" "reg")])
9016 (define_insn "wrgsr_v8plus"
9017   [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" "I,r"))
9018    (clobber (match_scratch:SI 1 "=X,&h"))]
9019   "TARGET_VIS && TARGET_ARCH32"
9021   if (GET_CODE (operands[0]) == CONST_INT
9022       || sparc_check_64 (operands[0], insn))
9023     return "wr\t%%g0, %0, %%gsr";
9025   output_asm_insn("srl\t%L0, 0, %L0", operands);
9026   return "sllx\t%H0, 32, %1\n\tor\t%L0, %1, %1\n\twr\t%%g0, %1, %%gsr";
9028   [(set_attr "type" "multi")])
9030 (define_expand "rdgsr_vis"
9031   [(set (match_operand:DI 0 "register_operand" "") (reg:DI GSR_REG))]
9032   "TARGET_VIS"
9034   if (TARGET_ARCH32)
9035     {
9036       emit_insn (gen_rdgsr_v8plus (operands[0]));
9037       DONE;
9038     }
9041 (define_insn "*rdgsr_sp64"
9042   [(set (match_operand:DI 0 "register_operand" "=r") (reg:DI GSR_REG))]
9043   "TARGET_VIS && TARGET_ARCH64"
9044   "rd\t%%gsr, %0"
9045   [(set_attr "type" "gsr")
9046    (set_attr "subtype" "reg")])
9048 (define_insn "rdgsr_v8plus"
9049   [(set (match_operand:DI 0 "register_operand" "=r") (reg:DI GSR_REG))
9050    (clobber (match_scratch:SI 1 "=&h"))]
9051   "TARGET_VIS && TARGET_ARCH32"
9053   return "rd\t%%gsr, %1\n\tsrlx\t%1, 32, %H0\n\tmov %1, %L0";
9055   [(set_attr "type" "multi")])
9057 ;; Using faligndata only makes sense after an alignaddr since the choice of
9058 ;; bytes to take out of each operand is dependent on the results of the last
9059 ;; alignaddr.
9060 (define_insn "faligndata<VM64:mode>_vis"
9061   [(set (match_operand:VM64 0 "register_operand" "=e")
9062         (unspec:VM64 [(match_operand:VM64 1 "register_operand" "e")
9063                       (match_operand:VM64 2 "register_operand" "e")
9064                       (reg:DI GSR_REG)]
9065          UNSPEC_ALIGNDATA))]
9066   "TARGET_VIS"
9067   "faligndata\t%1, %2, %0"
9068   [(set_attr "type" "fga")
9069    (set_attr "subtype" "other")
9070    (set_attr "fptype" "double")])
9072 (define_insn "alignaddrsi_vis"
9073   [(set (match_operand:SI 0 "register_operand" "=r")
9074         (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
9075                  (match_operand:SI 2 "register_or_zero_operand" "rJ")))
9076    (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
9077         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
9078   "TARGET_VIS"
9079   "alignaddr\t%r1, %r2, %0"
9080   [(set_attr "type" "gsr")
9081    (set_attr "subtype" "alignaddr")])
9083 (define_insn "alignaddrdi_vis"
9084   [(set (match_operand:DI 0 "register_operand" "=r")
9085         (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
9086                  (match_operand:DI 2 "register_or_zero_operand" "rJ")))
9087    (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
9088         (plus:DI (match_dup 1) (match_dup 2)))]
9089   "TARGET_VIS"
9090   "alignaddr\t%r1, %r2, %0"
9091   [(set_attr "type" "gsr")
9092    (set_attr "subtype" "alignaddr")])
9094 (define_insn "alignaddrlsi_vis"
9095   [(set (match_operand:SI 0 "register_operand" "=r")
9096         (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
9097                  (match_operand:SI 2 "register_or_zero_operand" "rJ")))
9098    (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
9099         (xor:DI (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2)))
9100                 (const_int 7)))]
9101   "TARGET_VIS"
9102   "alignaddrl\t%r1, %r2, %0"
9103   [(set_attr "type" "gsr")
9104    (set_attr "subtype" "alignaddr")])
9106 (define_insn "alignaddrldi_vis"
9107   [(set (match_operand:DI 0 "register_operand" "=r")
9108         (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
9109                  (match_operand:DI 2 "register_or_zero_operand" "rJ")))
9110    (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
9111         (xor:DI (plus:DI (match_dup 1) (match_dup 2))
9112                 (const_int 7)))]
9113   "TARGET_VIS"
9114   "alignaddrl\t%r1, %r2, %0"
9115   [(set_attr "type" "gsr")
9116    (set_attr "subtype" "alignaddr")])
9118 (define_insn "pdist_vis"
9119   [(set (match_operand:DI 0 "register_operand" "=e")
9120         (unspec:DI [(match_operand:V8QI 1 "register_operand" "e")
9121                     (match_operand:V8QI 2 "register_operand" "e")
9122                     (match_operand:DI 3 "register_operand" "0")]
9123          UNSPEC_PDIST))]
9124   "TARGET_VIS"
9125   "pdist\t%1, %2, %0"
9126   [(set_attr "type" "pdist")
9127    (set_attr "fptype" "double")])
9129 ;; Edge instructions produce condition codes equivalent to a 'subcc'
9130 ;; with the same operands.
9131 (define_insn "edge8<P:mode>_vis"
9132   [(set (reg:CCNZ CC_REG)
9133         (compare:CCNZ (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
9134                                (match_operand:P 2 "register_or_zero_operand" "rJ"))
9135                       (const_int 0)))
9136    (set (match_operand:P 0 "register_operand" "=r")
9137         (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8))]
9138   "TARGET_VIS"
9139   "edge8\t%r1, %r2, %0"
9140   [(set_attr "type" "edge")])
9142 (define_insn "edge8l<P:mode>_vis"
9143   [(set (reg:CCNZ CC_REG)
9144         (compare:CCNZ (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
9145                                (match_operand:P 2 "register_or_zero_operand" "rJ"))
9146                       (const_int 0)))
9147    (set (match_operand:P 0 "register_operand" "=r")
9148         (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8L))]
9149   "TARGET_VIS"
9150   "edge8l\t%r1, %r2, %0"
9151   [(set_attr "type" "edge")])
9153 (define_insn "edge16<P:mode>_vis"
9154   [(set (reg:CCNZ CC_REG)
9155         (compare:CCNZ (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
9156                                (match_operand:P 2 "register_or_zero_operand" "rJ"))
9157                       (const_int 0)))
9158    (set (match_operand:P 0 "register_operand" "=r")
9159         (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16))]
9160   "TARGET_VIS"
9161   "edge16\t%r1, %r2, %0"
9162   [(set_attr "type" "edge")])
9164 (define_insn "edge16l<P:mode>_vis"
9165   [(set (reg:CCNZ CC_REG)
9166         (compare:CCNZ (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
9167                                (match_operand:P 2 "register_or_zero_operand" "rJ"))
9168                       (const_int 0)))
9169    (set (match_operand:P 0 "register_operand" "=r")
9170         (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16L))]
9171   "TARGET_VIS"
9172   "edge16l\t%r1, %r2, %0"
9173   [(set_attr "type" "edge")])
9175 (define_insn "edge32<P:mode>_vis"
9176   [(set (reg:CCNZ CC_REG)
9177         (compare:CCNZ (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
9178                                (match_operand:P 2 "register_or_zero_operand" "rJ"))
9179                       (const_int 0)))
9180    (set (match_operand:P 0 "register_operand" "=r")
9181         (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32))]
9182   "TARGET_VIS"
9183   "edge32\t%r1, %r2, %0"
9184   [(set_attr "type" "edge")])
9186 (define_insn "edge32l<P:mode>_vis"
9187   [(set (reg:CCNZ CC_REG)
9188         (compare:CCNZ (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
9189                                (match_operand:P 2 "register_or_zero_operand" "rJ"))
9190                       (const_int 0)))
9191    (set (match_operand:P 0 "register_operand" "=r")
9192         (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32L))]
9193   "TARGET_VIS"
9194   "edge32l\t%r1, %r2, %0"
9195   [(set_attr "type" "edge")])
9197 (define_code_iterator gcond [le ne gt eq])
9198 (define_mode_iterator GCM [V4HI V2SI])
9199 (define_mode_attr gcm_name [(V4HI "16") (V2SI "32")])
9201 (define_insn "fcmp<gcond:code><GCM:gcm_name><P:mode>_vis"
9202   [(set (match_operand:P 0 "register_operand" "=r")
9203         (unspec:P [(gcond:GCM (match_operand:GCM 1 "register_operand" "e")
9204                               (match_operand:GCM 2 "register_operand" "e"))]
9205          UNSPEC_FCMP))]
9206   "TARGET_VIS"
9207   "fcmp<gcond:code><GCM:gcm_name>\t%1, %2, %0"
9208   [(set_attr "type" "viscmp")])
9210 (define_insn "fpcmp<gcond:code>8<P:mode>_vis"
9211   [(set (match_operand:P 0 "register_operand" "=r")
9212         (unspec:P [(gcond:V8QI (match_operand:V8QI 1 "register_operand" "e")
9213                                (match_operand:V8QI 2 "register_operand" "e"))]
9214          UNSPEC_FCMP))]
9215   "TARGET_VIS4"
9216   "fpcmp<gcond:code>8\t%1, %2, %0"
9217   [(set_attr "type" "viscmp")])
9219 (define_expand "vcond<GCM:mode><GCM:mode>"
9220   [(match_operand:GCM 0 "register_operand" "")
9221    (match_operand:GCM 1 "register_operand" "")
9222    (match_operand:GCM 2 "register_operand" "")
9223    (match_operator 3 ""
9224      [(match_operand:GCM 4 "register_operand" "")
9225       (match_operand:GCM 5 "register_operand" "")])]
9226   "TARGET_VIS3"
9228   sparc_expand_vcond (<MODE>mode, operands, UNSPEC_CMASK<gcm_name>, UNSPEC_FCMP);
9229   DONE;
9232 (define_expand "vconduv8qiv8qi"
9233   [(match_operand:V8QI 0 "register_operand" "")
9234    (match_operand:V8QI 1 "register_operand" "")
9235    (match_operand:V8QI 2 "register_operand" "")
9236    (match_operator 3 ""
9237      [(match_operand:V8QI 4 "register_operand" "")
9238       (match_operand:V8QI 5 "register_operand" "")])]
9239   "TARGET_VIS3"
9241   sparc_expand_vcond (V8QImode, operands, UNSPEC_CMASK8, UNSPEC_FUCMP);
9242   DONE;
9245 (define_insn "array8<P:mode>_vis"
9246   [(set (match_operand:P 0 "register_operand" "=r")
9247         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
9248                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
9249                   UNSPEC_ARRAY8))]
9250   "TARGET_VIS"
9251   "array8\t%r1, %r2, %0"
9252   [(set_attr "type" "array")])
9254 (define_insn "array16<P:mode>_vis"
9255   [(set (match_operand:P 0 "register_operand" "=r")
9256         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
9257                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
9258                   UNSPEC_ARRAY16))]
9259   "TARGET_VIS"
9260   "array16\t%r1, %r2, %0"
9261   [(set_attr "type" "array")])
9263 (define_insn "array32<P:mode>_vis"
9264   [(set (match_operand:P 0 "register_operand" "=r")
9265         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
9266                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
9267                   UNSPEC_ARRAY32))]
9268   "TARGET_VIS"
9269   "array32\t%r1, %r2, %0"
9270   [(set_attr "type" "array")])
9272 (define_insn "bmaskdi_vis"
9273   [(set (match_operand:DI 0 "register_operand" "=r")
9274         (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
9275                  (match_operand:DI 2 "register_or_zero_operand" "rJ")))
9276    (set (zero_extract:DI (reg:DI GSR_REG) (const_int 32) (const_int 32))
9277         (plus:DI (match_dup 1) (match_dup 2)))]
9278   "TARGET_VIS2 && TARGET_ARCH64"
9279   "bmask\t%r1, %r2, %0"
9280   [(set_attr "type" "bmask")])
9282 (define_insn "bmasksi_vis"
9283   [(set (match_operand:SI 0 "register_operand" "=r")
9284         (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
9285                  (match_operand:SI 2 "register_or_zero_operand" "rJ")))
9286    (set (zero_extract:DI (reg:DI GSR_REG) (const_int 32) (const_int 32))
9287         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
9288   "TARGET_VIS2"
9289   "bmask\t%r1, %r2, %0"
9290   [(set_attr "type" "bmask")])
9292 (define_insn "bshuffle<VM64:mode>_vis"
9293   [(set (match_operand:VM64 0 "register_operand" "=e")
9294         (unspec:VM64 [(match_operand:VM64 1 "register_operand" "e")
9295                       (match_operand:VM64 2 "register_operand" "e")
9296                       (reg:DI GSR_REG)]
9297                      UNSPEC_BSHUFFLE))]
9298   "TARGET_VIS2"
9299   "bshuffle\t%1, %2, %0"
9300   [(set_attr "type" "fga")
9301    (set_attr "subtype" "other")
9302    (set_attr "fptype" "double")])
9304 ;; The rtl expanders will happily convert constant permutations on other
9305 ;; modes down to V8QI.  Rely on this to avoid the complexity of the byte
9306 ;; order of the permutation.
9307 (define_expand "vec_perm_constv8qi"
9308   [(match_operand:V8QI 0 "register_operand" "")
9309    (match_operand:V8QI 1 "register_operand" "")
9310    (match_operand:V8QI 2 "register_operand" "")
9311    (match_operand:V8QI 3 "" "")]
9312   "TARGET_VIS2"
9314   unsigned int i, mask;
9315   rtx sel = operands[3];
9317   for (i = mask = 0; i < 8; ++i)
9318     mask |= (INTVAL (XVECEXP (sel, 0, i)) & 0xf) << (28 - i*4);
9319   sel = force_reg (SImode, gen_int_mode (mask, SImode));
9321   emit_insn (gen_bmasksi_vis (gen_reg_rtx (SImode), sel, const0_rtx));
9322   emit_insn (gen_bshufflev8qi_vis (operands[0], operands[1], operands[2]));
9323   DONE;
9326 ;; Unlike constant permutation, we can vastly simplify the compression of
9327 ;; the 64-bit selector input to the 32-bit %gsr value by knowing what the
9328 ;; width of the input is.
9329 (define_expand "vec_perm<VM64:mode>"
9330   [(match_operand:VM64 0 "register_operand" "")
9331    (match_operand:VM64 1 "register_operand" "")
9332    (match_operand:VM64 2 "register_operand" "")
9333    (match_operand:VM64 3 "register_operand" "")]
9334   "TARGET_VIS2"
9336   sparc_expand_vec_perm_bmask (<MODE>mode, operands[3]);
9337   emit_insn (gen_bshuffle<VM64:mode>_vis (operands[0], operands[1], operands[2]));
9338   DONE;
9341 ;; VIS 2.0 adds edge variants which do not set the condition codes
9342 (define_insn "edge8n<P:mode>_vis"
9343   [(set (match_operand:P 0 "register_operand" "=r")
9344         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
9345                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
9346                   UNSPEC_EDGE8N))]
9347   "TARGET_VIS2"
9348   "edge8n\t%r1, %r2, %0"
9349   [(set_attr "type" "edgen")])
9351 (define_insn "edge8ln<P:mode>_vis"
9352   [(set (match_operand:P 0 "register_operand" "=r")
9353         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
9354                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
9355                   UNSPEC_EDGE8LN))]
9356   "TARGET_VIS2"
9357   "edge8ln\t%r1, %r2, %0"
9358   [(set_attr "type" "edgen")])
9360 (define_insn "edge16n<P:mode>_vis"
9361   [(set (match_operand:P 0 "register_operand" "=r")
9362         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
9363                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
9364                   UNSPEC_EDGE16N))]
9365   "TARGET_VIS2"
9366   "edge16n\t%r1, %r2, %0"
9367   [(set_attr "type" "edgen")])
9369 (define_insn "edge16ln<P:mode>_vis"
9370   [(set (match_operand:P 0 "register_operand" "=r")
9371         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
9372                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
9373                   UNSPEC_EDGE16LN))]
9374   "TARGET_VIS2"
9375   "edge16ln\t%r1, %r2, %0"
9376   [(set_attr "type" "edgen")])
9378 (define_insn "edge32n<P:mode>_vis"
9379   [(set (match_operand:P 0 "register_operand" "=r")
9380         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
9381                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
9382                   UNSPEC_EDGE32N))]
9383   "TARGET_VIS2"
9384   "edge32n\t%r1, %r2, %0"
9385   [(set_attr "type" "edgen")])
9387 (define_insn "edge32ln<P:mode>_vis"
9388   [(set (match_operand:P 0 "register_operand" "=r")
9389         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
9390                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
9391                   UNSPEC_EDGE32LN))]
9392   "TARGET_VIS2"
9393   "edge32ln\t%r1, %r2, %0"
9394   [(set_attr "type" "edge")])
9396 ;; Conditional moves are possible via fcmpX --> cmaskX -> bshuffle
9397 (define_insn "cmask8<P:mode>_vis"
9398   [(set (reg:DI GSR_REG)
9399         (unspec:DI [(match_operand:P 0 "register_or_zero_operand" "rJ")
9400                     (reg:DI GSR_REG)]
9401                    UNSPEC_CMASK8))]
9402   "TARGET_VIS3"
9403   "cmask8\t%r0"
9404   [(set_attr "type" "fga")
9405    (set_attr "subtype" "cmask")])
9407 (define_insn "cmask16<P:mode>_vis"
9408   [(set (reg:DI GSR_REG)
9409         (unspec:DI [(match_operand:P 0 "register_or_zero_operand" "rJ")
9410                     (reg:DI GSR_REG)]
9411                    UNSPEC_CMASK16))]
9412   "TARGET_VIS3"
9413   "cmask16\t%r0"
9414   [(set_attr "type" "fga")
9415    (set_attr "subtype" "cmask")])
9417 (define_insn "cmask32<P:mode>_vis"
9418   [(set (reg:DI GSR_REG)
9419         (unspec:DI [(match_operand:P 0 "register_or_zero_operand" "rJ")
9420                     (reg:DI GSR_REG)]
9421                    UNSPEC_CMASK32))]
9422   "TARGET_VIS3"
9423   "cmask32\t%r0"
9424   [(set_attr "type" "fga")
9425    (set_attr "subtype" "cmask")])
9427 (define_insn "fchksm16_vis"
9428   [(set (match_operand:V4HI 0 "register_operand" "=e")
9429         (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "e")
9430                       (match_operand:V4HI 2 "register_operand" "e")]
9431                      UNSPEC_FCHKSM16))]
9432   "TARGET_VIS3"
9433   "fchksm16\t%1, %2, %0"
9434   [(set_attr "type" "fga")
9435    (set_attr "subtype" "fpu")])
9437 (define_code_iterator vis3_shift [ashift ss_ashift lshiftrt ashiftrt])
9438 (define_code_attr vis3_shift_insn
9439   [(ashift "fsll") (ss_ashift "fslas") (lshiftrt "fsrl") (ashiftrt "fsra")])
9440 (define_code_attr vis3_shift_patname
9441   [(ashift "ashl") (ss_ashift "ssashl") (lshiftrt "lshr") (ashiftrt "ashr")])
9442    
9443 (define_insn "v<vis3_shift_patname><GCM:mode>3"
9444   [(set (match_operand:GCM 0 "register_operand" "=<vconstr>")
9445         (vis3_shift:GCM (match_operand:GCM 1 "register_operand" "<vconstr>")
9446                         (match_operand:GCM 2 "register_operand" "<vconstr>")))]
9447   "TARGET_VIS3"
9448   "<vis3_shift_insn><vbits>\t%1, %2, %0"
9449   [(set_attr "type" "fga")
9450    (set_attr "subtype" "fpu")])
9452 (define_insn "pdistn<P:mode>_vis"
9453   [(set (match_operand:P 0 "register_operand" "=r")
9454         (unspec:P [(match_operand:V8QI 1 "register_operand" "e")
9455                    (match_operand:V8QI 2 "register_operand" "e")]
9456          UNSPEC_PDISTN))]
9457   "TARGET_VIS3"
9458   "pdistn\t%1, %2, %0"
9459   [(set_attr "type" "pdistn")
9460    (set_attr "fptype" "double")])
9462 (define_insn "fmean16_vis"
9463   [(set (match_operand:V4HI 0 "register_operand" "=e")
9464         (truncate:V4HI
9465           (lshiftrt:V4SI
9466             (plus:V4SI
9467               (plus:V4SI
9468                 (zero_extend:V4SI
9469                   (match_operand:V4HI 1 "register_operand" "e"))
9470                 (zero_extend:V4SI
9471                   (match_operand:V4HI 2 "register_operand" "e")))
9472               (const_vector:V4SI [(const_int 1) (const_int 1)
9473                                   (const_int 1) (const_int 1)]))
9474           (const_int 1))))]
9475   "TARGET_VIS3"
9476   "fmean16\t%1, %2, %0"
9477   [(set_attr "type" "fga")
9478    (set_attr "subtype" "fpu")])
9480 (define_insn "fp<plusminus_insn>64_vis"
9481   [(set (match_operand:V1DI 0 "register_operand" "=e")
9482         (plusminus:V1DI (match_operand:V1DI 1 "register_operand" "e")
9483                         (match_operand:V1DI 2 "register_operand" "e")))]
9484   "TARGET_VIS3"
9485   "fp<plusminus_insn>64\t%1, %2, %0"
9486   [(set_attr "type" "fga")
9487    (set_attr "subtype" "addsub64")])
9489 (define_insn "<plusminus_insn>v8qi3"
9490   [(set (match_operand:V8QI 0 "register_operand" "=e")
9491         (plusminus:V8QI (match_operand:V8QI 1 "register_operand" "e")
9492                         (match_operand:V8QI 2 "register_operand" "e")))]
9493   "TARGET_VIS4"
9494   "fp<plusminus_insn>8\t%1, %2, %0"
9495   [(set_attr "type" "fga")
9496    (set_attr "subtype" "other")])
9498 (define_mode_iterator VASS [V4HI V2SI V2HI V1SI])
9499 (define_code_iterator vis3_addsub_ss [ss_plus ss_minus])
9500 (define_code_attr vis3_addsub_ss_insn
9501   [(ss_plus "fpadds") (ss_minus "fpsubs")])
9502 (define_code_attr vis3_addsub_ss_patname
9503   [(ss_plus "ssadd") (ss_minus "sssub")])
9505 (define_insn "<vis3_addsub_ss_patname><VASS:mode>3"
9506   [(set (match_operand:VASS 0 "register_operand" "=<vconstr>")
9507         (vis3_addsub_ss:VASS (match_operand:VASS 1 "register_operand" "<vconstr>")
9508                              (match_operand:VASS 2 "register_operand" "<vconstr>")))]
9509   "TARGET_VIS3"
9510   "<vis3_addsub_ss_insn><vbits>\t%1, %2, %0"
9511   [(set_attr "type" "fga")
9512    (set_attr "subtype" "other")])
9514 (define_mode_iterator VMMAX [V8QI V4HI V2SI])
9515 (define_code_iterator vis4_minmax [smin smax])
9516 (define_code_attr vis4_minmax_insn
9517   [(smin "fpmin") (smax "fpmax")])
9518 (define_code_attr vis4_minmax_patname
9519   [(smin "min") (smax "max")])
9521 (define_insn "<vis4_minmax_patname><VMMAX:mode>3"
9522   [(set (match_operand:VMMAX 0 "register_operand" "=<vconstr>")
9523         (vis4_minmax:VMMAX (match_operand:VMMAX 1 "register_operand" "<vconstr>")
9524                            (match_operand:VMMAX 2 "register_operand" "<vconstr>")))]
9525   "TARGET_VIS4"
9526   "<vis4_minmax_insn><vbits>\t%1, %2, %0"
9527   [(set_attr "type" "fga")
9528    (set_attr "subtype" "maxmin")])
9530 (define_code_iterator vis4_uminmax [umin umax])
9531 (define_code_attr vis4_uminmax_insn
9532   [(umin "fpminu") (umax "fpmaxu")])
9533 (define_code_attr vis4_uminmax_patname
9534  [(umin "minu") (umax "maxu")])
9536 (define_insn "<vis4_uminmax_patname><VMMAX:mode>3"
9537   [(set (match_operand:VMMAX 0 "register_operand" "=<vconstr>")
9538         (vis4_uminmax:VMMAX (match_operand:VMMAX 1 "register_operand" "<vconstr>")
9539                             (match_operand:VMMAX 2 "register_operand" "<vconstr>")))]
9540   "TARGET_VIS4"
9541   "<vis4_uminmax_insn><vbits>\t%1, %2, %0"
9542   [(set_attr "type" "fga")
9543    (set_attr "subtype" "maxmin")])
9545 ;; The use of vis3_addsub_ss_patname in the VIS4 instruction below is
9546 ;; intended.
9547 (define_insn "<vis3_addsub_ss_patname>v8qi3"
9548   [(set (match_operand:V8QI 0 "register_operand" "=e")
9549         (vis3_addsub_ss:V8QI (match_operand:V8QI 1 "register_operand" "e")
9550                              (match_operand:V8QI 2 "register_operand" "e")))]
9551   "TARGET_VIS4"
9552   "<vis3_addsub_ss_insn>8\t%1, %2, %0"
9553   [(set_attr "type" "fga")
9554    (set_attr "subtype" "other")])
9556 (define_mode_iterator VAUS [V4HI V8QI])
9557 (define_code_iterator vis4_addsub_us [us_plus us_minus])
9558 (define_code_attr vis4_addsub_us_insn
9559   [(us_plus "fpaddus") (us_minus "fpsubus")])
9560 (define_code_attr vis4_addsub_us_patname
9561   [(us_plus "usadd") (us_minus "ussub")])
9563 (define_insn "<vis4_addsub_us_patname><VAUS:mode>3"
9564  [(set (match_operand:VAUS 0 "register_operand" "=<vconstr>")
9565        (vis4_addsub_us:VAUS (match_operand:VAUS 1 "register_operand" "<vconstr>")
9566                             (match_operand:VAUS 2 "register_operand" "<vconstr>")))]
9567  "TARGET_VIS4"
9568  "<vis4_addsub_us_insn><vbits>\t%1, %2, %0"
9569  [(set_attr "type" "fga")
9570   (set_attr "subtype" "other")])
9572 (define_insn "fucmp<gcond:code>8<P:mode>_vis"
9573   [(set (match_operand:P 0 "register_operand" "=r")
9574         (unspec:P [(gcond:V8QI (match_operand:V8QI 1 "register_operand" "e")
9575                                (match_operand:V8QI 2 "register_operand" "e"))]
9576          UNSPEC_FUCMP))]
9577   "TARGET_VIS3"
9578   "fucmp<gcond:code>8\t%1, %2, %0"
9579   [(set_attr "type" "viscmp")])
9581 (define_insn "fpcmpu<gcond:code><GCM:gcm_name><P:mode>_vis"
9582   [(set (match_operand:P 0 "register_operand" "=r")
9583         (unspec:P [(gcond:GCM (match_operand:GCM 1 "register_operand" "e")
9584                               (match_operand:GCM 2 "register_operand" "e"))]
9585          UNSPEC_FUCMP))]
9586   "TARGET_VIS4"
9587   "fpcmpu<gcond:code><GCM:gcm_name>\t%1, %2, %0"
9588   [(set_attr "type" "viscmp")])
9590 (define_insn "*naddsf3"
9591   [(set (match_operand:SF 0 "register_operand" "=f")
9592         (neg:SF (plus:SF (match_operand:SF 1 "register_operand" "f")
9593                          (match_operand:SF 2 "register_operand" "f"))))]
9594   "TARGET_VIS3"
9595   "fnadds\t%1, %2, %0"
9596   [(set_attr "type" "fp")])
9598 (define_insn "*nadddf3"
9599   [(set (match_operand:DF 0 "register_operand" "=e")
9600         (neg:DF (plus:DF (match_operand:DF 1 "register_operand" "e")
9601                          (match_operand:DF 2 "register_operand" "e"))))]
9602   "TARGET_VIS3"
9603   "fnaddd\t%1, %2, %0"
9604   [(set_attr "type" "fp")
9605    (set_attr "fptype" "double")])
9607 (define_insn "*nmulsf3"
9608   [(set (match_operand:SF 0 "register_operand" "=f")
9609         (mult:SF (neg:SF (match_operand:SF 1 "register_operand" "f"))
9610                  (match_operand:SF 2 "register_operand" "f")))]
9611   "TARGET_VIS3"
9612   "fnmuls\t%1, %2, %0"
9613   [(set_attr "type" "fpmul")])
9615 (define_insn "*nmuldf3"
9616   [(set (match_operand:DF 0 "register_operand" "=e")
9617         (mult:DF (neg:DF (match_operand:DF 1 "register_operand" "e"))
9618                  (match_operand:DF 2 "register_operand" "e")))]
9619   "TARGET_VIS3"
9620   "fnmuld\t%1, %2, %0"
9621   [(set_attr "type" "fpmul")
9622    (set_attr "fptype" "double")])
9624 (define_insn "*nmuldf3_extend"
9625   [(set (match_operand:DF 0 "register_operand" "=e")
9626         (mult:DF (neg:DF (float_extend:DF
9627                            (match_operand:SF 1 "register_operand" "f")))
9628                  (float_extend:DF
9629                    (match_operand:SF 2 "register_operand" "f"))))]
9630   "TARGET_VIS3"
9631   "fnsmuld\t%1, %2, %0"
9632   [(set_attr "type" "fpmul")
9633    (set_attr "fptype" "double")])
9635 (define_insn "fhaddsf_vis"
9636   [(set (match_operand:SF 0 "register_operand" "=f")
9637         (unspec:SF [(match_operand:SF 1 "register_operand" "f")
9638                     (match_operand:SF 2 "register_operand" "f")]
9639                    UNSPEC_FHADD))]
9640   "TARGET_VIS3"
9641   "fhadds\t%1, %2, %0"
9642   [(set_attr "type" "fp")])
9644 (define_insn "fhadddf_vis"
9645   [(set (match_operand:DF 0 "register_operand" "=f")
9646         (unspec:DF [(match_operand:DF 1 "register_operand" "f")
9647                     (match_operand:DF 2 "register_operand" "f")]
9648                    UNSPEC_FHADD))]
9649   "TARGET_VIS3"
9650   "fhaddd\t%1, %2, %0"
9651   [(set_attr "type" "fp")
9652    (set_attr "fptype" "double")])
9654 (define_insn "fhsubsf_vis"
9655   [(set (match_operand:SF 0 "register_operand" "=f")
9656         (unspec:SF [(match_operand:SF 1 "register_operand" "f")
9657                     (match_operand:SF 2 "register_operand" "f")]
9658                    UNSPEC_FHSUB))]
9659   "TARGET_VIS3"
9660   "fhsubs\t%1, %2, %0"
9661   [(set_attr "type" "fp")])
9663 (define_insn "fhsubdf_vis"
9664   [(set (match_operand:DF 0 "register_operand" "=f")
9665         (unspec:DF [(match_operand:DF 1 "register_operand" "f")
9666                     (match_operand:DF 2 "register_operand" "f")]
9667                    UNSPEC_FHSUB))]
9668   "TARGET_VIS3"
9669   "fhsubd\t%1, %2, %0"
9670   [(set_attr "type" "fp")
9671    (set_attr "fptype" "double")])
9673 (define_insn "fnhaddsf_vis"
9674   [(set (match_operand:SF 0 "register_operand" "=f")
9675         (neg:SF (unspec:SF [(match_operand:SF 1 "register_operand" "f")
9676                             (match_operand:SF 2 "register_operand" "f")]
9677                            UNSPEC_FHADD)))]
9678   "TARGET_VIS3"
9679   "fnhadds\t%1, %2, %0"
9680   [(set_attr "type" "fp")])
9682 (define_insn "fnhadddf_vis"
9683   [(set (match_operand:DF 0 "register_operand" "=f")
9684         (neg:DF (unspec:DF [(match_operand:DF 1 "register_operand" "f")
9685                             (match_operand:DF 2 "register_operand" "f")]
9686                            UNSPEC_FHADD)))]
9687   "TARGET_VIS3"
9688   "fnhaddd\t%1, %2, %0"
9689   [(set_attr "type" "fp")
9690    (set_attr "fptype" "double")])
9692 ;; VIS4B instructions.
9694 (define_mode_iterator DUMODE [V2SI V4HI V8QI])
9696 (define_insn "dictunpack<DUMODE:vbits>"
9697   [(set (match_operand:DUMODE 0 "register_operand" "=e")
9698         (unspec:DUMODE [(match_operand:DF 1 "register_operand" "e")
9699                         (match_operand:SI 2 "imm5_operand_dictunpack<DUMODE:vbits>" "t")]
9700          UNSPEC_DICTUNPACK))]
9701   "TARGET_VIS4B"
9702   "dictunpack\t%1, %2, %0"
9703   [(set_attr "type" "fga")
9704    (set_attr "subtype" "other")])
9706 (define_mode_iterator FPCSMODE [V2SI V4HI V8QI])
9707 (define_code_iterator fpcscond [le gt eq ne])
9708 (define_code_iterator fpcsucond [le gt])
9710 (define_insn "fpcmp<fpcscond:code><FPCSMODE:vbits><P:mode>shl"
9711   [(set (match_operand:P 0 "register_operand" "=r")
9712         (unspec:P [(fpcscond:FPCSMODE (match_operand:FPCSMODE 1 "register_operand" "e")
9713                                       (match_operand:FPCSMODE 2 "register_operand" "e"))
9714                    (match_operand:SI 3 "imm2_operand" "q")]
9715          UNSPEC_FPCMPSHL))]
9716    "TARGET_VIS4B"
9717    "fpcmp<fpcscond:code><FPCSMODE:vbits>shl\t%1, %2, %3, %0"
9718    [(set_attr "type" "viscmp")])
9720 (define_insn "fpcmpu<fpcsucond:code><FPCSMODE:vbits><P:mode>shl"
9721   [(set (match_operand:P 0 "register_operand" "=r")
9722         (unspec:P [(fpcsucond:FPCSMODE (match_operand:FPCSMODE 1 "register_operand" "e")
9723                                        (match_operand:FPCSMODE 2 "register_operand" "e"))
9724                    (match_operand:SI 3 "imm2_operand" "q")]
9725          UNSPEC_FPUCMPSHL))]
9726    "TARGET_VIS4B"
9727    "fpcmpu<fpcsucond:code><FPCSMODE:vbits>shl\t%1, %2, %3, %0"
9728    [(set_attr "type" "viscmp")])
9730 (define_insn "fpcmpde<FPCSMODE:vbits><P:mode>shl"
9731   [(set (match_operand:P 0 "register_operand" "=r")
9732         (unspec:P [(match_operand:FPCSMODE 1 "register_operand" "e")
9733                    (match_operand:FPCSMODE 2 "register_operand" "e")
9734                    (match_operand:SI 3 "imm2_operand" "q")]
9735          UNSPEC_FPCMPDESHL))]
9736    "TARGET_VIS4B"
9737    "fpcmpde<FPCSMODE:vbits>shl\t%1, %2, %3, %0"
9738    [(set_attr "type" "viscmp")])
9740 (define_insn "fpcmpur<FPCSMODE:vbits><P:mode>shl"
9741   [(set (match_operand:P 0 "register_operand" "=r")
9742         (unspec:P [(match_operand:FPCSMODE 1 "register_operand" "e")
9743                    (match_operand:FPCSMODE 2 "register_operand" "e")
9744                    (match_operand:SI 3 "imm2_operand" "q")]
9745          UNSPEC_FPCMPURSHL))]
9746    "TARGET_VIS4B"
9747    "fpcmpur<FPCSMODE:vbits>shl\t%1, %2, %3, %0"
9748    [(set_attr "type" "viscmp")])
9750 (include "sync.md")