* gimplify.c (nonlocal_vlas): Delete.
[official-gcc.git] / gcc / config / sparc / sparc.md
blobdf769405190388ca4e684fff9e2dc5a3bee653e5
1 ;; Machine description for SPARC.
2 ;; Copyright (C) 1987-2018 Free Software Foundation, Inc.
3 ;; Contributed by Michael Tiemann (tiemann@cygnus.com)
4 ;; 64-bit SPARC-V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
5 ;; at Cygnus Support.
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 (define_attr "fix_lost_divsqrt" "false,true"
434    (symbol_ref "(sparc_fix_lost_divsqrt != 0
435                  ? FIX_LOST_DIVSQRT_TRUE : FIX_LOST_DIVSQRT_FALSE)"))
437 (define_attr "fix_gr712rc" "false,true"
438    (symbol_ref "(sparc_fix_gr712rc != 0
439                  ? FIX_GR712RC_TRUE : FIX_GR712RC_FALSE)"))
441 ;; Length (in # of insns).
442 ;; Beware that setting a length greater or equal to 3 for conditional branches
443 ;; has a side-effect (see output_cbranch and output_v9branch).
444 (define_attr "length" ""
445   (cond [(eq_attr "type" "uncond_branch,call")
446            (if_then_else (eq_attr "empty_delay_slot" "true")
447              (const_int 2)
448              (const_int 1))
449          (eq_attr "type" "sibcall")
450            (if_then_else (ior (eq_attr "leaf_function" "true")
451                               (eq_attr "flat" "true"))
452              (if_then_else (eq_attr "empty_delay_slot" "true")
453                (const_int 3)
454                (const_int 2))
455              (if_then_else (eq_attr "empty_delay_slot" "true")
456                (const_int 2)
457                (const_int 1)))
458          (eq_attr "branch_type" "icc")
459            (if_then_else (match_operand 0 "v9_comparison_operator" "")
460              (if_then_else (lt (pc) (match_dup 1))
461                (if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000))
462                  (if_then_else (eq_attr "empty_delay_slot" "true")
463                    (const_int 2)
464                    (const_int 1))
465                  (if_then_else (eq_attr "empty_delay_slot" "true")
466                    (const_int 4)
467                    (const_int 3)))
468                (if_then_else (lt (minus (pc) (match_dup 1)) (const_int 260000))
469                  (if_then_else (eq_attr "empty_delay_slot" "true")
470                    (const_int 2)
471                    (const_int 1))
472                  (if_then_else (eq_attr "empty_delay_slot" "true")
473                    (const_int 4)
474                    (const_int 3))))
475              (if_then_else (eq_attr "empty_delay_slot" "true")
476                (const_int 2)
477                (const_int 1)))
478          (eq_attr "branch_type" "fcc")
479            (if_then_else (match_operand 0 "fcc0_register_operand" "")
480              (if_then_else (eq_attr "empty_delay_slot" "true")
481                (if_then_else (not (match_test "TARGET_V9"))
482                  (const_int 3)
483                  (const_int 2))
484                (if_then_else (not (match_test "TARGET_V9"))
485                  (const_int 2)
486                  (const_int 1)))
487              (if_then_else (lt (pc) (match_dup 2))
488                (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000))
489                  (if_then_else (eq_attr "empty_delay_slot" "true")
490                    (const_int 2)
491                    (const_int 1))
492                  (if_then_else (eq_attr "empty_delay_slot" "true")
493                    (const_int 4)
494                    (const_int 3)))
495                (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000))
496                  (if_then_else (eq_attr "empty_delay_slot" "true")
497                    (const_int 2)
498                    (const_int 1))
499                  (if_then_else (eq_attr "empty_delay_slot" "true")
500                    (const_int 4)
501                    (const_int 3)))))
502          (eq_attr "branch_type" "reg")
503            (if_then_else (lt (pc) (match_dup 2))
504              (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000))
505                (if_then_else (eq_attr "empty_delay_slot" "true")
506                  (const_int 2)
507                  (const_int 1))
508                (if_then_else (eq_attr "empty_delay_slot" "true")
509                  (const_int 4)
510                  (const_int 3)))
511              (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000))
512                (if_then_else (eq_attr "empty_delay_slot" "true")
513                  (const_int 2)
514                  (const_int 1))
515                (if_then_else (eq_attr "empty_delay_slot" "true")
516                  (const_int 4)
517                  (const_int 3))))
518          (eq_attr "type" "cbcond")
519            (if_then_else (lt (pc) (match_dup 3))
520              (if_then_else (lt (minus (match_dup 3) (pc)) (const_int 500))
521                (if_then_else (eq_attr "emit_cbcond_nop" "true")
522                  (const_int 2)
523                  (const_int 1))
524                (const_int 4))
525              (if_then_else (lt (minus (pc) (match_dup 3)) (const_int 500))
526                (if_then_else (eq_attr "emit_cbcond_nop" "true")
527                  (const_int 2)
528                  (const_int 1))
529                (const_int 4)))
530          (eq_attr "type" "uncond_cbcond")
531            (if_then_else (lt (pc) (match_dup 0))
532              (if_then_else (lt (minus (match_dup 0) (pc)) (const_int 500))
533                (if_then_else (eq_attr "emit_cbcond_nop" "true")
534                  (const_int 2)
535                  (const_int 1))
536                (const_int 1))
537              (if_then_else (lt (minus (pc) (match_dup 0)) (const_int 500))
538                (if_then_else (eq_attr "emit_cbcond_nop" "true")
539                  (const_int 2)
540                  (const_int 1))
541                (const_int 1)))
542          ] (const_int 1)))
544 ;; FP precision.
545 (define_attr "fptype" "single,double"
546   (const_string "single"))
548 ;; FP precision specific to the UT699.
549 (define_attr "fptype_ut699" "none,single"
550   (const_string "none"))
552 ;; UltraSPARC-III integer load type.
553 (define_attr "us3load_type" "2cycle,3cycle"
554   (const_string "2cycle"))
556 (define_asm_attributes
557   [(set_attr "length" "2")
558    (set_attr "type" "multi")])
560 ;; Attributes for branch scheduling
561 (define_attr "in_call_delay" "false,true"
562   (symbol_ref "(eligible_for_call_delay (insn)
563                 ? IN_CALL_DELAY_TRUE : IN_CALL_DELAY_FALSE)"))
565 (define_attr "in_sibcall_delay" "false,true"
566   (symbol_ref "(eligible_for_sibcall_delay (insn)
567                 ? IN_SIBCALL_DELAY_TRUE : IN_SIBCALL_DELAY_FALSE)"))
569 (define_attr "in_return_delay" "false,true"
570   (symbol_ref "(eligible_for_return_delay (insn)
571                 ? IN_RETURN_DELAY_TRUE : IN_RETURN_DELAY_FALSE)"))
573 ;; ??? !v9: Should implement the notion of predelay slots for floating-point
574 ;; branches.  This would allow us to remove the nop always inserted before
575 ;; a floating point branch.
577 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
578 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
579 ;; This is because doing so will add several pipeline stalls to the path
580 ;; that the load/store did not come from.  Unfortunately, there is no way
581 ;; to prevent fill_eager_delay_slots from using load/store without completely
582 ;; disabling them.  For the SPEC benchmark set, this is a serious lose,
583 ;; because it prevents us from moving back the final store of inner loops.
585 (define_attr "in_branch_delay" "false,true"
586   (cond [(eq_attr "type" "uncond_branch,branch,cbcond,uncond_cbcond,call,sibcall,call_no_delay_slot,multi")
587            (const_string "false")
588          (and (eq_attr "fix_lost_divsqrt" "true")
589               (eq_attr "type" "fpdivs,fpsqrts,fpdivd,fpsqrtd"))
590            (const_string "false")
591          (and (eq_attr "fix_b2bst" "true") (eq_attr "type" "store,fpstore"))
592            (const_string "false")
593          (and (eq_attr "fix_ut699" "true") (eq_attr "type" "load,sload"))
594            (const_string "false")
595          (and (eq_attr "fix_ut699" "true")
596               (and (eq_attr "type" "fpload,fp,fpmove,fpmul,fpdivs,fpsqrts")
597                    (ior (eq_attr "fptype" "single")
598                         (eq_attr "fptype_ut699" "single"))))
599            (const_string "false")
600          (eq_attr "length" "1")
601            (const_string "true")
602         ] (const_string "false")))
604 (define_attr "in_integer_branch_annul_delay" "false,true"
605   (cond [(and (eq_attr "fix_gr712rc" "true")
606               (eq_attr "type" "fp,fpcmp,fpmove,fpcmove,fpmul,
607                                fpdivs,fpsqrts,fpdivd,fpsqrtd"))
608            (const_string "false")
609          (eq_attr "in_branch_delay" "true")
610            (const_string "true")
611         ] (const_string "false")))
613 (define_delay (eq_attr "type" "call")
614   [(eq_attr "in_call_delay" "true") (nil) (nil)])
616 (define_delay (eq_attr "type" "sibcall")
617   [(eq_attr "in_sibcall_delay" "true") (nil) (nil)])
619 (define_delay (eq_attr "type" "return")
620   [(eq_attr "in_return_delay" "true") (nil) (nil)])
622 (define_delay (and (eq_attr "type" "branch")
623               (not (eq_attr "branch_type" "icc")))
624   [(eq_attr "in_branch_delay" "true") (nil) (eq_attr "in_branch_delay" "true")])
626 (define_delay (and (eq_attr "type" "branch")
627               (eq_attr "branch_type" "icc"))
628   [(eq_attr "in_branch_delay" "true") (nil)
629   (eq_attr "in_integer_branch_annul_delay" "true")])
631 (define_delay (eq_attr "type" "uncond_branch")
632   [(eq_attr "in_branch_delay" "true") (nil) (nil)])
635 ;; Include SPARC DFA schedulers
637 (include "cypress.md")
638 (include "supersparc.md")
639 (include "hypersparc.md")
640 (include "leon.md")
641 (include "sparclet.md")
642 (include "ultra1_2.md")
643 (include "ultra3.md")
644 (include "niagara.md")
645 (include "niagara2.md")
646 (include "niagara4.md")
647 (include "niagara7.md")
648 (include "m8.md")
651 ;; Operand and operator predicates and constraints
653 (include "predicates.md")
654 (include "constraints.md")
657 ;; Compare instructions.
659 ;; These are just the DEFINE_INSNs to match the patterns and the
660 ;; DEFINE_SPLITs for some of the scc insns that actually require
661 ;; more than one machine instruction.  DEFINE_EXPANDs are further down.
663 (define_insn "*cmpsi_insn"
664   [(set (reg:CC CC_REG)
665         (compare:CC (match_operand:SI 0 "register_operand" "r")
666                     (match_operand:SI 1 "arith_operand" "rI")))]
667   ""
668   "cmp\t%0, %1"
669   [(set_attr "type" "compare")])
671 (define_insn "*cmpdi_sp64"
672   [(set (reg:CCX CC_REG)
673         (compare:CCX (match_operand:DI 0 "register_operand" "r")
674                      (match_operand:DI 1 "arith_operand" "rI")))]
675   "TARGET_ARCH64"
676   "cmp\t%0, %1"
677   [(set_attr "type" "compare")])
679 (define_insn "*cmpsi_sne"
680   [(set (reg:CCC CC_REG)
681         (compare:CCC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
682                      (const_int -1)))]
683   ""
684   "cmp\t%%g0, %0"
685   [(set_attr "type" "compare")])
687 (define_insn "*cmpdi_sne"
688   [(set (reg:CCXC CC_REG)
689         (compare:CCXC (not:DI (match_operand:DI 0 "arith_operand" "rI"))
690                       (const_int -1)))]
691   "TARGET_ARCH64"
692   "cmp\t%%g0, %0"
693   [(set_attr "type" "compare")])
695 (define_insn "*cmpsf_fpe"
696   [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
697         (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
698                        (match_operand:SF 2 "register_operand" "f")))]
699   "TARGET_FPU"
701   if (TARGET_V9)
702     return "fcmpes\t%0, %1, %2";
703   return "fcmpes\t%1, %2";
705   [(set_attr "type" "fpcmp")])
707 (define_insn "*cmpdf_fpe"
708   [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
709         (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
710                        (match_operand:DF 2 "register_operand" "e")))]
711   "TARGET_FPU"
713   if (TARGET_V9)
714     return "fcmped\t%0, %1, %2";
715   return "fcmped\t%1, %2";
717   [(set_attr "type" "fpcmp")
718    (set_attr "fptype" "double")])
720 (define_insn "*cmptf_fpe"
721   [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
722         (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
723                        (match_operand:TF 2 "register_operand" "e")))]
724   "TARGET_FPU && TARGET_HARD_QUAD"
726   if (TARGET_V9)
727     return "fcmpeq\t%0, %1, %2";
728   return "fcmpeq\t%1, %2";
730   [(set_attr "type" "fpcmp")])
732 (define_insn "*cmpsf_fp"
733   [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
734         (compare:CCFP (match_operand:SF 1 "register_operand" "f")
735                       (match_operand:SF 2 "register_operand" "f")))]
736   "TARGET_FPU"
738   if (TARGET_V9)
739     return "fcmps\t%0, %1, %2";
740   return "fcmps\t%1, %2";
742   [(set_attr "type" "fpcmp")])
744 (define_insn "*cmpdf_fp"
745   [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
746         (compare:CCFP (match_operand:DF 1 "register_operand" "e")
747                       (match_operand:DF 2 "register_operand" "e")))]
748   "TARGET_FPU"
750   if (TARGET_V9)
751     return "fcmpd\t%0, %1, %2";
752   return "fcmpd\t%1, %2";
754   [(set_attr "type" "fpcmp")
755    (set_attr "fptype" "double")])
757 (define_insn "*cmptf_fp"
758   [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
759         (compare:CCFP (match_operand:TF 1 "register_operand" "e")
760                       (match_operand:TF 2 "register_operand" "e")))]
761   "TARGET_FPU && TARGET_HARD_QUAD"
763   if (TARGET_V9)
764     return "fcmpq\t%0, %1, %2";
765   return "fcmpq\t%1, %2";
767   [(set_attr "type" "fpcmp")])
769 ;; Next come the scc insns.
771 ;; Note that the boolean result (operand 0) takes on DImode
772 ;; (not SImode) when TARGET_ARCH64.
774 (define_expand "cstoresi4"
775   [(use (match_operator 1 "comparison_operator"
776          [(match_operand:SI 2 "compare_operand" "")
777           (match_operand:SI 3 "arith_operand" "")]))
778    (clobber (match_operand:SI 0 "cstore_result_operand"))]
779   ""
781   if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
782     operands[2] = force_reg (SImode, operands[2]);
783   if (emit_scc_insn (operands)) DONE; else FAIL;
786 (define_expand "cstoredi4"
787   [(use (match_operator 1 "comparison_operator"
788          [(match_operand:DI 2 "compare_operand" "")
789           (match_operand:DI 3 "arith_operand" "")]))
790    (clobber (match_operand:SI 0 "cstore_result_operand"))]
791   "TARGET_ARCH64"
793   if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
794     operands[2] = force_reg (DImode, operands[2]);
795   if (emit_scc_insn (operands)) DONE; else FAIL;
798 (define_expand "cstore<F:mode>4"
799   [(use (match_operator 1 "comparison_operator"
800          [(match_operand:F 2 "register_operand" "")
801           (match_operand:F 3 "register_operand" "")]))
802    (clobber (match_operand:SI 0 "cstore_result_operand"))]
803   "TARGET_FPU"
805   if (emit_scc_insn (operands)) DONE; else FAIL;
808 ;; The SNE and SEQ patterns are special because they can be done
809 ;; without any branching and do not involve a COMPARE.
811 (define_insn_and_split "*snesi<W:mode>_zero"
812   [(set (match_operand:W 0 "register_operand" "=r")
813         (ne:W (match_operand:SI 1 "register_operand" "r")
814               (const_int 0)))
815    (clobber (reg:CC CC_REG))]
816   ""
817   "#"
818   ""
819   [(set (reg:CCC CC_REG) (compare:CCC (not:SI (match_dup 1)) (const_int -1)))
820    (set (match_dup 0) (ltu:W (reg:CCC CC_REG) (const_int 0)))]
821   ""
822   [(set_attr "length" "2")])
824 (define_insn_and_split "*neg_snesi<W:mode>_zero"
825   [(set (match_operand:W 0 "register_operand" "=r")
826         (neg:W (ne:W (match_operand:SI 1 "register_operand" "r")
827                      (const_int 0))))
828    (clobber (reg:CC CC_REG))]
829   ""
830   "#"
831   ""
832   [(set (reg:CCC CC_REG) (compare:CCC (not:SI (match_dup 1)) (const_int -1)))
833    (set (match_dup 0) (neg:W (ltu:W (reg:CCC CC_REG) (const_int 0))))]
834   ""
835   [(set_attr "length" "2")])
837 (define_insn_and_split "*snedi<W:mode>_zero"
838   [(set (match_operand:W 0 "register_operand" "=&r")
839         (ne:W (match_operand:DI 1 "register_operand" "r")
840               (const_int 0)))]
841   "TARGET_ARCH64 && !TARGET_VIS3"
842   "#"
843   "&& !reg_overlap_mentioned_p (operands[1], operands[0])"
844   [(set (match_dup 0) (const_int 0))
845    (set (match_dup 0) (if_then_else:W (ne:DI (match_dup 1) (const_int 0))
846                                       (const_int 1)
847                                       (match_dup 0)))]
848   ""
849   [(set_attr "length" "2")])
851 (define_insn_and_split "*snedi<W:mode>_zero_vis3"
852   [(set (match_operand:W 0 "register_operand" "=r")
853         (ne:W (match_operand:DI 1 "register_operand" "r")
854               (const_int 0)))
855    (clobber (reg:CCX CC_REG))]
856   "TARGET_ARCH64 && TARGET_VIS3"
857   "#"
858   ""
859   [(set (reg:CCXC CC_REG) (compare:CCXC (not:DI (match_dup 1)) (const_int -1)))
860    (set (match_dup 0) (ltu:W (reg:CCXC CC_REG) (const_int 0)))]
861   ""
862   [(set_attr "length" "2")])
864 (define_insn_and_split "*neg_snedi<W:mode>_zero"
865   [(set (match_operand:W 0 "register_operand" "=&r")
866         (neg:W (ne:W (match_operand:DI 1 "register_operand" "r")
867                      (const_int 0))))]
868   "TARGET_ARCH64 && !TARGET_SUBXC"
869   "#"
870   "&& !reg_overlap_mentioned_p (operands[1], operands[0])"
871   [(set (match_dup 0) (const_int 0))
872    (set (match_dup 0) (if_then_else:W (ne:DI (match_dup 1) (const_int 0))
873                                       (const_int -1)
874                                       (match_dup 0)))]
875   ""
876   [(set_attr "length" "2")])
878 (define_insn_and_split "*neg_snedi<W:mode>_zero_subxc"
879   [(set (match_operand:W 0 "register_operand" "=&r")
880         (neg:W (ne:W (match_operand:DI 1 "register_operand" "r")
881                      (const_int 0))))
882    (clobber (reg:CCX CC_REG))]
883   "TARGET_ARCH64 && TARGET_SUBXC"
884   "#"
885   ""
886   [(set (reg:CCXC CC_REG) (compare:CCXC (not:DI (match_dup 1)) (const_int -1)))
887    (set (match_dup 0) (neg:W (ltu:W (reg:CCXC CC_REG) (const_int 0))))]
888   ""
889   [(set_attr "length" "2")])
891 (define_insn_and_split "*seqsi<W:mode>_zero"
892   [(set (match_operand:W 0 "register_operand" "=r")
893         (eq:W (match_operand:SI 1 "register_operand" "r")
894               (const_int 0)))
895    (clobber (reg:CC CC_REG))]
896   ""
897   "#"
898   ""
899   [(set (reg:CCC CC_REG) (compare:CCC (not:SI (match_dup 1)) (const_int -1)))
900    (set (match_dup 0) (geu:W (reg:CCC CC_REG) (const_int 0)))]
901   ""
902   [(set_attr "length" "2")])
904 (define_insn_and_split "*neg_seqsi<W:mode>_zero"
905   [(set (match_operand:W 0 "register_operand" "=r")
906         (neg:W (eq:W (match_operand:SI 1 "register_operand" "r")
907                      (const_int 0))))
908    (clobber (reg:CC CC_REG))]
909   ""
910   "#"
911   ""
912   [(set (reg:CCC CC_REG) (compare:CCC (not:SI (match_dup 1)) (const_int -1)))
913    (set (match_dup 0) (neg:W (geu:W (reg:CCC CC_REG) (const_int 0))))]
914   ""
915   [(set_attr "length" "2")])
917 (define_insn_and_split "*seqdi<W:mode>_zero"
918   [(set (match_operand:W 0 "register_operand" "=&r")
919         (eq:W (match_operand:DI 1 "register_operand" "r")
920               (const_int 0)))]
921   "TARGET_ARCH64"
922   "#"
923   "&& !reg_overlap_mentioned_p (operands[1], operands[0])"
924   [(set (match_dup 0) (const_int 0))
925    (set (match_dup 0) (if_then_else:W (eq:DI (match_dup 1) (const_int 0))
926                                       (const_int 1)
927                                       (match_dup 0)))]
928   ""
929   [(set_attr "length" "2")])
931 (define_insn_and_split "*neg_seqdi<W:mode>_zero"
932   [(set (match_operand:W 0 "register_operand" "=&r")
933         (neg:W (eq:W (match_operand:DI 1 "register_operand" "r")
934                      (const_int 0))))]
935   "TARGET_ARCH64"
936   "#"
937   "&& !reg_overlap_mentioned_p (operands[1], operands[0])"
938   [(set (match_dup 0) (const_int 0))
939    (set (match_dup 0) (if_then_else:W (eq:DI (match_dup 1) (const_int 0))
940                                       (const_int -1)
941                                       (match_dup 0)))]
942   ""
943   [(set_attr "length" "2")]) 
945 ;; We can also do (x + (i == 0)) and related, so put them in.
947 (define_insn_and_split "*plus_snesi<W:mode>_zero"
948   [(set (match_operand:W 0 "register_operand" "=r")
949         (plus:W (ne:W (match_operand:SI 1 "register_operand" "r")
950                       (const_int 0))
951                 (match_operand:W 2 "register_operand" "r")))
952    (clobber (reg:CC CC_REG))]
953   ""
954   "#"
955   ""
956   [(set (reg:CCC CC_REG) (compare:CCC (not:SI (match_dup 1)) (const_int -1)))
957    (set (match_dup 0) (plus:W (ltu:W (reg:CCC CC_REG) (const_int 0))
958                               (match_dup 2)))]
959   ""
960   [(set_attr "length" "2")])
962 (define_insn_and_split "*plus_plus_snesi<W:mode>_zero"
963   [(set (match_operand:W 0 "register_operand" "=r")
964         (plus:W (plus:W (ne:W (match_operand:SI 1 "register_operand" "r")
965                               (const_int 0))
966                         (match_operand:W 2 "register_operand" "r"))
967                  (match_operand:W 3 "register_operand" "r")))
968    (clobber (reg:CC CC_REG))]
969   ""
970   "#"
971   ""
972   [(set (reg:CCC CC_REG) (compare:CCC (not:SI (match_dup 1)) (const_int -1)))
973    (set (match_dup 0) (plus:W (plus:W (ltu:W (reg:CCC CC_REG) (const_int 0))
974                                       (match_dup 2))
975                       (match_dup 3)))]
976   ""
977   [(set_attr "length" "2")])
979 (define_insn_and_split "*plus_snedi<W:mode>_zero"
980   [(set (match_operand:W 0 "register_operand" "=r")
981         (plus:W (ne:W (match_operand:DI 1 "register_operand" "r")
982                       (const_int 0))
983                 (match_operand:W 2 "register_operand" "r")))
984    (clobber (reg:CCX CC_REG))]
985   "TARGET_ARCH64 && TARGET_VIS3"
986   "#"
987   ""
988   [(set (reg:CCXC CC_REG) (compare:CCXC (not:DI (match_dup 1)) (const_int -1)))
989    (set (match_dup 0) (plus:W (ltu:W (reg:CCXC CC_REG) (const_int 0))
990                               (match_dup 2)))]
991   ""
992   [(set_attr "length" "2")])
994 (define_insn_and_split "*plus_plus_snedi<W:mode>_zero"
995   [(set (match_operand:W 0 "register_operand" "=r")
996         (plus:W (plus:W (ne:W (match_operand:DI 1 "register_operand" "r")
997                               (const_int 0))
998                         (match_operand:W 2 "register_operand" "r"))
999                  (match_operand:W 3 "register_operand" "r")))
1000    (clobber (reg:CCX CC_REG))]
1001   "TARGET_ARCH64 && TARGET_VIS3"
1002   "#"
1003   ""
1004   [(set (reg:CCXC CC_REG) (compare:CCXC (not:DI (match_dup 1)) (const_int -1)))
1005    (set (match_dup 0) (plus:W (plus:W (ltu:W (reg:CCXC CC_REG) (const_int 0))
1006                                       (match_dup 2))
1007                       (match_dup 3)))]
1008   ""
1009   [(set_attr "length" "2")])
1011 (define_insn_and_split "*minus_snesi<W:mode>_zero"
1012   [(set (match_operand:W 0 "register_operand" "=r")
1013         (minus:W (match_operand:W 2 "register_operand" "r")
1014                   (ne:W (match_operand:SI 1 "register_operand" "r")
1015                         (const_int 0))))
1016    (clobber (reg:CC CC_REG))]
1017   ""
1018   "#"
1019   ""
1020   [(set (reg:CCC CC_REG) (compare:CCC (not:SI (match_dup 1)) (const_int -1)))
1021    (set (match_dup 0) (minus:W (match_dup 2)
1022                                (ltu:W (reg:CCC CC_REG) (const_int 0))))]
1023   ""
1024   [(set_attr "length" "2")])
1026 (define_insn_and_split "*minus_minus_snesi<W:mode>_zero"
1027   [(set (match_operand:W 0 "register_operand" "=r")
1028         (minus:W (minus:W (match_operand:W 2 "register_operand" "r")
1029                           (ne:W (match_operand:SI 1 "register_operand" "r")
1030                                 (const_int 0)))
1031                  (match_operand:W 3 "register_operand" "r")))
1032    (clobber (reg:CC CC_REG))]
1033   ""
1034   "#"
1035   ""
1036   [(set (reg:CCC CC_REG) (compare:CCC (not:SI (match_dup 1)) (const_int -1)))
1037    (set (match_dup 0) (minus:W (minus:W (match_dup 2)
1038                                         (ltu:W (reg:CCC CC_REG) (const_int 0)))
1039                                (match_dup 3)))]
1040   ""
1041   [(set_attr "length" "2")])
1043 (define_insn_and_split "*minus_snedi<W:mode>_zero"
1044   [(set (match_operand:W 0 "register_operand" "=r")
1045         (minus:W (match_operand:W 2 "register_operand" "r")
1046                  (ne:W (match_operand:DI 1 "register_operand" "r")
1047                        (const_int 0))))
1048    (clobber (reg:CCX CC_REG))]
1049   "TARGET_ARCH64 && TARGET_SUBXC"
1050   "#"
1051   ""
1052   [(set (reg:CCXC CC_REG) (compare:CCXC (not:DI (match_dup 1)) (const_int -1)))
1053    (set (match_dup 0) (minus:W (match_dup 2)
1054                                (ltu:W (reg:CCXC CC_REG) (const_int 0))))]
1055   ""
1056   [(set_attr "length" "2")])
1058 (define_insn_and_split "*minus_minus_snedi<W:mode>_zero"
1059   [(set (match_operand:W 0 "register_operand" "=r")
1060         (minus:W (minus:W (match_operand:W 2 "register_operand" "r")
1061                           (ne:W (match_operand:DI 1 "register_operand" "r")
1062                                 (const_int 0)))
1063                  (match_operand:W 3 "register_operand" "r")))
1064    (clobber (reg:CCX CC_REG))]
1065   "TARGET_ARCH64 && TARGET_SUBXC"
1066   "#"
1067   ""
1068   [(set (reg:CCXC CC_REG) (compare:CCXC (not:DI (match_dup 1)) (const_int -1)))
1069    (set (match_dup 0) (minus:W (minus:W (match_dup 2)
1070                                         (ltu:W (reg:CCXC CC_REG) (const_int 0)))
1071                                (match_dup 3)))]
1072   ""
1073   [(set_attr "length" "2")])
1075 (define_insn_and_split "*plus_seqsi<W:mode>_zero"
1076   [(set (match_operand:W 0 "register_operand" "=r")
1077         (plus:W (eq:W (match_operand:SI 1 "register_operand" "r")
1078                       (const_int 0))
1079                 (match_operand:W 2 "register_operand" "r")))
1080    (clobber (reg:CC CC_REG))]
1081   ""
1082   "#"
1083   ""
1084   [(set (reg:CCC CC_REG) (compare:CCC (not:SI (match_dup 1)) (const_int -1)))
1085    (set (match_dup 0) (plus:W (geu:W (reg:CCC CC_REG) (const_int 0))
1086                               (match_dup 2)))]
1087   ""
1088   [(set_attr "length" "2")])
1090 (define_insn_and_split "*minus_seqsi<W:mode>_zero"
1091   [(set (match_operand:W 0 "register_operand" "=r")
1092         (minus:W (match_operand:W 2 "register_operand" "r")
1093                  (eq:W (match_operand:SI 1 "register_operand" "r")
1094                        (const_int 0))))
1095    (clobber (reg:CC CC_REG))]
1096   ""
1097   "#"
1098   ""
1099   [(set (reg:CCC CC_REG) (compare:CCC (not:SI (match_dup 1)) (const_int -1)))
1100    (set (match_dup 0) (minus:W (match_dup 2)
1101                                (geu:W (reg:CCC CC_REG) (const_int 0))))]
1102   ""
1103   [(set_attr "length" "2")])
1105 ;; We can also do GEU and LTU directly, but these operate after a compare.
1107 (define_insn "*sltu<W:mode>_insn"
1108   [(set (match_operand:W 0 "register_operand" "=r")
1109         (ltu:W (match_operand 1 "icc_register_operand" "X") (const_int 0)))]
1110   "GET_MODE (operands[1]) == CCmode || GET_MODE (operands[1]) == CCCmode"
1111   "addx\t%%g0, 0, %0"
1112   [(set_attr "type" "ialuX")])
1114 (define_insn "*plus_sltu<W:mode>"
1115   [(set (match_operand:W 0 "register_operand" "=r")
1116         (plus:W (ltu:W (match_operand 2 "icc_register_operand" "X")
1117                        (const_int 0))
1118                 (match_operand:W 1 "arith_operand" "rI")))]
1119   "GET_MODE (operands[2]) == CCmode || GET_MODE (operands[2]) == CCCmode"
1120   "addx\t%%g0, %1, %0"
1121   [(set_attr "type" "ialuX")])
1123 (define_insn "*plus_plus_sltu<W:mode>"
1124   [(set (match_operand:W 0 "register_operand" "=r")
1125         (plus:W (plus:W (ltu:W (match_operand 3 "icc_register_operand" "X")
1126                                (const_int 0))
1127                         (match_operand:W 1 "register_operand" "%r"))
1128                 (match_operand:W 2 "arith_operand" "rI")))]
1129   "GET_MODE (operands[3]) == CCmode || GET_MODE (operands[3]) == CCCmode"
1130   "addx\t%1, %2, %0"
1131   [(set_attr "type" "ialuX")])
1133 (define_insn "*neg_sgeu<W:mode>"
1134   [(set (match_operand:W 0 "register_operand" "=r")
1135         (neg:W (geu:W (match_operand 1 "icc_register_operand" "X")
1136                       (const_int 0))))]
1137   "GET_MODE (operands[1]) == CCmode || GET_MODE (operands[1]) == CCCmode"
1138   "addx\t%%g0, -1, %0"
1139   [(set_attr "type" "ialuX")])
1141 (define_insn "*neg_sgeusidi"
1142   [(set (match_operand:DI 0 "register_operand" "=r")
1143         (sign_extend:DI (neg:SI (geu:SI (match_operand 1 "icc_register_operand" "X")
1144                                         (const_int 0)))))]
1145   "TARGET_ARCH64
1146    && (GET_MODE (operands[1]) == CCmode || GET_MODE (operands[1]) == CCCmode)"
1147   "addx\t%%g0, -1, %0"
1148   [(set_attr "type" "ialuX")])
1150 (define_insn "*minus_sgeu<W:mode>"
1151   [(set (match_operand:W 0 "register_operand" "=r")
1152         (minus:W (match_operand:W 1 "register_operand" "r")
1153                  (geu:W (match_operand 2 "icc_register_operand" "X")
1154                         (const_int 0))))]
1155   "GET_MODE (operands[2]) == CCmode || GET_MODE (operands[2]) == CCCmode"
1156   "addx\t%1, -1, %0"
1157   [(set_attr "type" "ialuX")])
1159 (define_insn "*addx<W:mode>"
1160   [(set (match_operand:W 0 "register_operand" "=r")
1161         (plus:W (plus:W (match_operand:W 1 "register_operand" "%r")
1162                         (match_operand:W 2 "arith_operand" "rI"))
1163                 (ltu:W (match_operand 3 "icc_register_operand" "X")
1164                        (const_int 0))))]
1165   "GET_MODE (operands[3]) == CCmode || GET_MODE (operands[3]) == CCCmode"
1166   "addx\t%1, %2, %0"
1167   [(set_attr "type" "ialuX")])
1169 (define_insn "*sltu<W:mode>_insn_vis3"
1170   [(set (match_operand:W 0 "register_operand" "=r")
1171         (ltu:W (match_operand 1 "icc_register_operand" "X") (const_int 0)))]
1172   "TARGET_ARCH64 && TARGET_VIS3
1173    && (GET_MODE (operands[1]) == CCXmode || GET_MODE (operands[1]) == CCXCmode)"
1174   "addxc\t%%g0, %%g0, %0"
1175   [(set_attr "type" "ialuX")])
1177 (define_insn "*plus_sltu<W:mode>_vis3"
1178   [(set (match_operand:W 0 "register_operand" "=r")
1179         (plus:W (ltu:W (match_operand 2 "icc_register_operand" "X")
1180                        (const_int 0))
1181                 (match_operand:W 1 "register_operand" "r")))]
1182   "TARGET_ARCH64 && TARGET_VIS3
1183    && (GET_MODE (operands[2]) == CCXmode || GET_MODE (operands[2]) == CCXCmode)"
1184   "addxc\t%%g0, %1, %0"
1185   [(set_attr "type" "ialuX")])
1187 (define_insn "*plus_plus_sltu<W:mode>_vis3"
1188   [(set (match_operand:W 0 "register_operand" "=r")
1189         (plus:W (plus:W (ltu:W (match_operand 3 "icc_register_operand" "X")
1190                                (const_int 0))
1191                         (match_operand:W 1 "register_operand" "%r"))
1192                 (match_operand:W 2 "register_operand" "r")))]
1193   "TARGET_ARCH64 && TARGET_VIS3
1194    && (GET_MODE (operands[3]) == CCXmode || GET_MODE (operands[3]) == CCXCmode)"
1195   "addxc\t%1, %2, %0"
1196   [(set_attr "type" "ialuX")])
1198 (define_insn "*addxc<W:mode>"
1199   [(set (match_operand:W 0 "register_operand" "=r")
1200         (plus:W (plus:W (match_operand:W 1 "register_operand" "%r")
1201                         (match_operand:W 2 "register_operand" "r"))
1202                 (ltu:W (match_operand 3 "icc_register_operand" "X")
1203                        (const_int 0))))]
1204   "TARGET_ARCH64 && TARGET_VIS3
1205    && (GET_MODE (operands[3]) == CCXmode || GET_MODE (operands[3]) == CCXCmode)"
1206   "addxc\t%1, %2, %0"
1207   [(set_attr "type" "ialuX")])
1209 (define_insn "*neg_sltu<W:mode>"
1210   [(set (match_operand:W 0 "register_operand" "=r")
1211         (neg:W (ltu:W (match_operand 1 "icc_register_operand" "X")
1212                       (const_int 0))))]
1213   "GET_MODE (operands[1]) == CCmode || GET_MODE (operands[1]) == CCCmode"
1214   "subx\t%%g0, 0, %0"
1215   [(set_attr "type" "ialuX")])
1217 (define_insn "*neg_sltusidi"
1218   [(set (match_operand:DI 0 "register_operand" "=r")
1219         (sign_extend:DI (neg:SI (ltu:SI (match_operand 1 "icc_register_operand" "X")
1220                                         (const_int 0)))))]
1221   "TARGET_ARCH64
1222    && (GET_MODE (operands[1]) == CCmode || GET_MODE (operands[1]) == CCCmode)"
1223   "subx\t%%g0, 0, %0"
1224   [(set_attr "type" "ialuX")])
1226 (define_insn "*minus_neg_sltu<W:mode>"
1227   [(set (match_operand:W 0 "register_operand" "=r")
1228         (minus:W (neg:W (ltu:W (match_operand 2 "icc_register_operand" "X")
1229                                (const_int 0)))
1230                  (match_operand:W 1 "arith_operand" "rI")))]
1231   "GET_MODE (operands[2]) == CCmode || GET_MODE (operands[2]) == CCCmode"
1232   "subx\t%%g0, %1, %0"
1233   [(set_attr "type" "ialuX")])
1235 (define_insn "*neg_plus_sltu<W:mode>"
1236   [(set (match_operand:W 0 "register_operand" "=r")
1237         (neg:W (plus:W (ltu:W (match_operand 2 "icc_register_operand" "X")
1238                               (const_int 0))
1239                        (match_operand:W 1 "arith_operand" "rI"))))]
1240   "GET_MODE (operands[2]) == CCmode || GET_MODE (operands[2]) == CCCmode"
1241   "subx\t%%g0, %1, %0"
1242   [(set_attr "type" "ialuX")])
1244 (define_insn "*minus_sltu<W:mode>"
1245   [(set (match_operand:W 0 "register_operand" "=r")
1246         (minus:W (match_operand:W 1 "register_operand" "r")
1247                  (ltu:W (match_operand 2 "icc_register_operand" "X")
1248                         (const_int 0))))]
1249   "GET_MODE (operands[2]) == CCmode || GET_MODE (operands[2]) == CCCmode"
1250   "subx\t%1, 0, %0"
1251   [(set_attr "type" "ialuX")])
1253 (define_insn "*minus_minus_sltu<W:mode>"
1254   [(set (match_operand:W 0 "register_operand" "=r")
1255         (minus:W (minus:W (match_operand:W 1 "register_or_zero_operand" "rJ")
1256                           (ltu:W (match_operand 3 "icc_register_operand" "X")
1257                                  (const_int 0)))
1258                  (match_operand:W 2 "arith_operand" "rI")))]
1259   "GET_MODE (operands[3]) == CCmode || GET_MODE (operands[3]) == CCCmode"
1260   "subx\t%r1, %2, %0"
1261   [(set_attr "type" "ialuX")])
1263 (define_insn "*sgeu<W:mode>_insn"
1264   [(set (match_operand:W 0 "register_operand" "=r")
1265         (geu:W (match_operand 1 "icc_register_operand" "X") (const_int 0)))]
1266   "GET_MODE (operands[1]) == CCmode || GET_MODE (operands[1]) == CCCmode"
1267   "subx\t%%g0, -1, %0"
1268   [(set_attr "type" "ialuX")])
1270 (define_insn "*plus_sgeu<W:mode>"
1271   [(set (match_operand:W 0 "register_operand" "=r")
1272         (plus:W (geu:W (match_operand 2 "icc_register_operand" "X")
1273                        (const_int 0))
1274                 (match_operand:W 1 "register_operand" "r")))]
1275   "GET_MODE (operands[2]) == CCmode || GET_MODE (operands[2]) == CCCmode"
1276   "subx\t%1, -1, %0"
1277   [(set_attr "type" "ialuX")])
1279 (define_insn "*subx<W:mode>"
1280   [(set (match_operand:W 0 "register_operand" "=r")
1281         (minus:W (minus:W (match_operand:W 1 "register_or_zero_operand" "rJ")
1282                           (match_operand:W 2 "arith_operand" "rI"))
1283                  (ltu:W (match_operand 3 "icc_register_operand" "X")
1284                         (const_int 0))))]
1285   "GET_MODE (operands[3]) == CCmode || GET_MODE (operands[3]) == CCCmode"
1286   "subx\t%r1, %2, %0"
1287   [(set_attr "type" "ialuX")])
1289 (define_insn "*neg_sltu<W:mode>_subxc"
1290   [(set (match_operand:W 0 "register_operand" "=r")
1291         (neg:W (ltu:W (match_operand 1 "icc_register_operand" "X")
1292                       (const_int 0))))]
1293   "TARGET_ARCH64 && TARGET_SUBXC
1294    && (GET_MODE (operands[1]) == CCXmode || GET_MODE (operands[1]) == CCXCmode)"
1295   "subxc\t%%g0, %%g0, %0"
1296   [(set_attr "type" "ialuX")])
1298 (define_insn "*minus_neg_sltu<W:mode>_subxc"
1299   [(set (match_operand:W 0 "register_operand" "=r")
1300         (minus:W (neg:W (ltu:W (match_operand 2 "icc_register_operand" "X")
1301                                (const_int 0)))
1302                  (match_operand:W 1 "register_operand" "r")))]
1303   "TARGET_ARCH64 && TARGET_SUBXC
1304    && (GET_MODE (operands[2]) == CCXmode || GET_MODE (operands[2]) == CCXCmode)"
1305   "subxc\t%%g0, %1, %0"
1306   [(set_attr "type" "ialuX")])
1308 (define_insn "*neg_plus_sltu<W:mode>_subxc"
1309   [(set (match_operand:W 0 "register_operand" "=r")
1310         (neg:W (plus:W (ltu:W (match_operand 2 "icc_register_operand" "X")
1311                               (const_int 0))
1312                        (match_operand:W 1 "register_operand" "r"))))]
1313   "TARGET_ARCH64 && TARGET_SUBXC
1314    && (GET_MODE (operands[2]) == CCXmode || GET_MODE (operands[2]) == CCXCmode)"
1315   "subxc\t%%g0, %1, %0"
1316   [(set_attr "type" "ialuX")])
1318 (define_insn "*minus_sltu<W:mode>_subxc"
1319   [(set (match_operand:W 0 "register_operand" "=r")
1320         (minus:W (match_operand:W 1 "register_operand" "r")
1321                  (ltu:W (match_operand 2 "icc_register_operand" "X")
1322                         (const_int 0))))]
1323   "TARGET_ARCH64 && TARGET_SUBXC
1324    && (GET_MODE (operands[2]) == CCXmode || GET_MODE (operands[2]) == CCXCmode)"
1325   "subxc\t%1, %%g0, %0"
1326   [(set_attr "type" "ialuX")])
1328 (define_insn "*minus_minus_sltu<W:mode>_subxc"
1329   [(set (match_operand:W 0 "register_operand" "=r")
1330         (minus:W (minus:W (match_operand:W 1 "register_or_zero_operand" "rJ")
1331                           (ltu:W (match_operand 3 "icc_register_operand" "X")
1332                                  (const_int 0)))
1333                  (match_operand:W 2 "register_operand" "r")))]
1334   "TARGET_ARCH64 && TARGET_SUBXC
1335    && (GET_MODE (operands[3]) == CCXmode || GET_MODE (operands[3]) == CCXCmode)"
1336   "subxc\t%r1, %2, %0"
1337   [(set_attr "type" "ialuX")])
1339 (define_insn "*subxc<W:mode>"
1340   [(set (match_operand:W 0 "register_operand" "=r")
1341         (minus:W (minus:W (match_operand:W 1 "register_or_zero_operand" "rJ")
1342                           (match_operand:W 2 "register_operand" "r"))
1343                  (ltu:W (match_operand 3 "icc_register_operand" "X")
1344                         (const_int 0))))]
1345   "TARGET_ARCH64 && TARGET_SUBXC
1346    && (GET_MODE (operands[3]) == CCXmode || GET_MODE (operands[3]) == CCXCmode)"
1347   "subxc\t%r1, %2, %0"
1348   [(set_attr "type" "ialuX")])
1350 (define_split
1351   [(set (match_operand:W 0 "register_operand" "")
1352         (match_operator:W 1 "icc_comparison_operator"
1353          [(match_operand 2 "icc_register_operand" "") (const_int 0)]))]
1354   "TARGET_V9
1355    /* 64-bit LTU is better implemented using addxc with VIS3.  */
1356    && !(GET_CODE (operands[1]) == LTU
1357         && (GET_MODE (operands[2]) == CCXmode
1358             || GET_MODE (operands[2]) == CCXCmode)
1359         && TARGET_VIS3)
1360    /* 32-bit LTU/GEU are better implemented using addx/subx.  */
1361    && !((GET_CODE (operands[1]) == LTU || GET_CODE (operands[1]) == GEU)
1362         && (GET_MODE (operands[2]) == CCmode
1363             || GET_MODE (operands[2]) == CCCmode))"
1364   [(set (match_dup 0) (const_int 0))
1365    (set (match_dup 0)
1366         (if_then_else:SI (match_op_dup:W 1 [(match_dup 2) (const_int 0)])
1367                          (const_int 1)
1368                          (match_dup 0)))]
1369   "")
1371 ;; These control RTL generation for conditional jump insns
1373 (define_expand "cbranchcc4"
1374   [(set (pc)
1375         (if_then_else (match_operator 0 "comparison_operator"
1376                        [(match_operand 1 "compare_operand" "")
1377                         (match_operand 2 "const_zero_operand" "")])
1378                       (label_ref (match_operand 3 "" ""))
1379                       (pc)))]
1380   ""
1381   "")
1383 (define_expand "cbranchsi4"
1384   [(use (match_operator 0 "comparison_operator"
1385          [(match_operand:SI 1 "compare_operand" "")
1386           (match_operand:SI 2 "arith_operand" "")]))
1387    (use (match_operand 3 ""))]
1388   ""
1390   if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
1391     operands[1] = force_reg (SImode, operands[1]);
1392   emit_conditional_branch_insn (operands);
1393   DONE;
1396 (define_expand "cbranchdi4"
1397   [(use (match_operator 0 "comparison_operator"
1398          [(match_operand:DI 1 "compare_operand" "")
1399           (match_operand:DI 2 "arith_operand" "")]))
1400    (use (match_operand 3 ""))]
1401   "TARGET_ARCH64"
1403   if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
1404     operands[1] = force_reg (DImode, operands[1]);
1405   emit_conditional_branch_insn (operands);
1406   DONE;
1409 (define_expand "cbranch<F:mode>4"
1410   [(use (match_operator 0 "comparison_operator"
1411          [(match_operand:F 1 "register_operand" "")
1412           (match_operand:F 2 "register_operand" "")]))
1413    (use (match_operand 3 ""))]
1414   "TARGET_FPU"
1416   emit_conditional_branch_insn (operands);
1417   DONE;
1421 ;; Now match both normal and inverted jump.
1423 ;; XXX fpcmp nop braindamage
1424 (define_insn "*normal_branch"
1425   [(set (pc)
1426         (if_then_else (match_operator 0 "icc_comparison_operator"
1427                        [(reg CC_REG) (const_int 0)])
1428                       (label_ref (match_operand 1 "" ""))
1429                       (pc)))]
1430   ""
1432   return output_cbranch (operands[0], operands[1], 1, 0,
1433                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1434                          insn);
1436   [(set_attr "type" "branch")
1437    (set_attr "branch_type" "icc")])
1439 ;; XXX fpcmp nop braindamage
1440 (define_insn "*inverted_branch"
1441   [(set (pc)
1442         (if_then_else (match_operator 0 "icc_comparison_operator"
1443                        [(reg CC_REG) (const_int 0)])
1444                       (pc)
1445                       (label_ref (match_operand 1 "" ""))))]
1446   ""
1448   return output_cbranch (operands[0], operands[1], 1, 1,
1449                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1450                          insn);
1452   [(set_attr "type" "branch")
1453    (set_attr "branch_type" "icc")])
1455 ;; XXX fpcmp nop braindamage
1456 (define_insn "*normal_fp_branch"
1457   [(set (pc)
1458         (if_then_else (match_operator 1 "comparison_operator"
1459                        [(match_operand:CCFP 0 "fcc_register_operand" "c")
1460                         (const_int 0)])
1461                       (label_ref (match_operand 2 "" ""))
1462                       (pc)))]
1463   ""
1465   return output_cbranch (operands[1], operands[2], 2, 0,
1466                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1467                          insn);
1469   [(set_attr "type" "branch")
1470    (set_attr "branch_type" "fcc")])
1472 ;; XXX fpcmp nop braindamage
1473 (define_insn "*inverted_fp_branch"
1474   [(set (pc)
1475         (if_then_else (match_operator 1 "comparison_operator"
1476                        [(match_operand:CCFP 0 "fcc_register_operand" "c")
1477                         (const_int 0)])
1478                       (pc)
1479                       (label_ref (match_operand 2 "" ""))))]
1480   ""
1482   return output_cbranch (operands[1], operands[2], 2, 1,
1483                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1484                          insn);
1486   [(set_attr "type" "branch")
1487    (set_attr "branch_type" "fcc")])
1489 ;; XXX fpcmp nop braindamage
1490 (define_insn "*normal_fpe_branch"
1491   [(set (pc)
1492         (if_then_else (match_operator 1 "comparison_operator"
1493                        [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1494                         (const_int 0)])
1495                       (label_ref (match_operand 2 "" ""))
1496                       (pc)))]
1497   ""
1499   return output_cbranch (operands[1], operands[2], 2, 0,
1500                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1501                          insn);
1503   [(set_attr "type" "branch")
1504    (set_attr "branch_type" "fcc")])
1506 ;; XXX fpcmp nop braindamage
1507 (define_insn "*inverted_fpe_branch"
1508   [(set (pc)
1509         (if_then_else (match_operator 1 "comparison_operator"
1510                        [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1511                         (const_int 0)])
1512                       (pc)
1513                       (label_ref (match_operand 2 "" ""))))]
1514   ""
1516   return output_cbranch (operands[1], operands[2], 2, 1,
1517                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1518                          insn);
1520   [(set_attr "type" "branch")
1521    (set_attr "branch_type" "fcc")])
1523 ;; SPARC V9-specific jump insns.  None of these are guaranteed to be
1524 ;; in the architecture.
1526 (define_insn "*cbcond_sp32"
1527   [(set (pc)
1528         (if_then_else (match_operator 0 "comparison_operator"
1529                        [(match_operand:SI 1 "register_operand" "r")
1530                         (match_operand:SI 2 "arith5_operand" "rA")])
1531                       (label_ref (match_operand 3 "" ""))
1532                       (pc)))]
1533   "TARGET_CBCOND"
1535   return output_cbcond (operands[0], operands[3], insn);
1537   [(set_attr "type" "cbcond")])
1539 (define_insn "*cbcond_sp64"
1540   [(set (pc)
1541         (if_then_else (match_operator 0 "comparison_operator"
1542                        [(match_operand:DI 1 "register_operand" "r")
1543                         (match_operand:DI 2 "arith5_operand" "rA")])
1544                       (label_ref (match_operand 3 "" ""))
1545                       (pc)))]
1546   "TARGET_ARCH64 && TARGET_CBCOND"
1548   return output_cbcond (operands[0], operands[3], insn);
1550   [(set_attr "type" "cbcond")])
1552 ;; There are no 32-bit brreg insns.
1554 (define_insn "*normal_int_branch_sp64"
1555   [(set (pc)
1556         (if_then_else (match_operator 0 "v9_register_comparison_operator"
1557                        [(match_operand:DI 1 "register_operand" "r")
1558                         (const_int 0)])
1559                       (label_ref (match_operand 2 "" ""))
1560                       (pc)))]
1561   "TARGET_ARCH64"
1563   return output_v9branch (operands[0], operands[2], 1, 2, 0,
1564                           final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1565                           insn);
1567   [(set_attr "type" "branch")
1568    (set_attr "branch_type" "reg")])
1570 (define_insn "*inverted_int_branch_sp64"
1571   [(set (pc)
1572         (if_then_else (match_operator 0 "v9_register_comparison_operator"
1573                        [(match_operand:DI 1 "register_operand" "r")
1574                         (const_int 0)])
1575                       (pc)
1576                       (label_ref (match_operand 2 "" ""))))]
1577   "TARGET_ARCH64"
1579   return output_v9branch (operands[0], operands[2], 1, 2, 1,
1580                           final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1581                           insn);
1583   [(set_attr "type" "branch")
1584    (set_attr "branch_type" "reg")])
1587 ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic
1588 ;; value subject to a PC-relative relocation.  Operand 2 is a helper function
1589 ;; that adds the PC value at the call point to register #(operand 3).
1591 ;; Even on V9 we use this call sequence with a stub, instead of "rd %pc, ..."
1592 ;; because the RDPC instruction is extremely expensive and incurs a complete
1593 ;; instruction pipeline flush.
1595 (define_insn "load_pcrel_sym<P:mode>"
1596   [(set (match_operand:P 0 "register_operand" "=r")
1597         (unspec:P [(match_operand:P 1 "symbolic_operand" "")
1598                    (match_operand:P 2 "call_address_operand" "")
1599                    (match_operand:P 3 "const_int_operand" "")]
1600                   UNSPEC_LOAD_PCREL_SYM))
1601    (clobber (reg:P O7_REG))]
1602   "REGNO (operands[0]) == INTVAL (operands[3])"
1604   if (flag_delayed_branch)
1605     return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0";
1606   else
1607     return "sethi\t%%hi(%a1-8), %0\n\tadd\t%0, %%lo(%a1-4), %0\n\tcall\t%a2\n\t nop";
1609   [(set (attr "type") (const_string "multi"))
1610    (set (attr "length")
1611         (if_then_else (eq_attr "delayed_branch" "true")
1612                       (const_int 3)
1613                       (const_int 4)))])
1616 ;; Integer move instructions
1618 (define_expand "movqi"
1619   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1620         (match_operand:QI 1 "general_operand" ""))]
1621   ""
1623   if (sparc_expand_move (QImode, operands))
1624     DONE;
1627 (define_insn "*movqi_insn"
1628   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1629         (match_operand:QI 1 "input_operand"   "rI,m,rJ"))]
1630   "(register_operand (operands[0], QImode)
1631     || register_or_zero_operand (operands[1], QImode))"
1632   "@
1633    mov\t%1, %0
1634    ldub\t%1, %0
1635    stb\t%r1, %0"
1636   [(set_attr "type" "*,load,store")
1637    (set_attr "subtype" "*,regular,*")
1638    (set_attr "us3load_type" "*,3cycle,*")])
1640 (define_expand "movhi"
1641   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1642         (match_operand:HI 1 "general_operand" ""))]
1643   ""
1645   if (sparc_expand_move (HImode, operands))
1646     DONE;
1649 (define_insn "*movhi_insn"
1650   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1651         (match_operand:HI 1 "input_operand"   "rI,K,m,rJ"))]
1652   "(register_operand (operands[0], HImode)
1653     || register_or_zero_operand (operands[1], HImode))"
1654   "@
1655    mov\t%1, %0
1656    sethi\t%%hi(%a1), %0
1657    lduh\t%1, %0
1658    sth\t%r1, %0"
1659   [(set_attr "type" "*,*,load,store")
1660    (set_attr "subtype" "*,*,regular,*")
1661    (set_attr "us3load_type" "*,*,3cycle,*")])
1663 ;; We always work with constants here.
1664 (define_insn "*movhi_lo_sum"
1665   [(set (match_operand:HI 0 "register_operand" "=r")
1666         (ior:HI (match_operand:HI 1 "register_operand" "%r")
1667                 (match_operand:HI 2 "small_int_operand" "I")))]
1668   ""
1669   "or\t%1, %2, %0")
1671 (define_expand "movsi"
1672   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1673         (match_operand:SI 1 "general_operand" ""))]
1674   ""
1676   if (sparc_expand_move (SImode, operands))
1677     DONE;
1680 (define_insn "*movsi_insn"
1681   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r, m, r,*f,*f,*f, m,d,d")
1682         (match_operand:SI 1 "input_operand"        "rI,K,m,rJ,*f, r, f, m,*f,J,P"))]
1683   "register_operand (operands[0], SImode)
1684    || register_or_zero_or_all_ones_operand (operands[1], SImode)"
1685   "@
1686    mov\t%1, %0
1687    sethi\t%%hi(%a1), %0
1688    ld\t%1, %0
1689    st\t%r1, %0
1690    movstouw\t%1, %0
1691    movwtos\t%1, %0
1692    fmovs\t%1, %0
1693    ld\t%1, %0
1694    st\t%1, %0
1695    fzeros\t%0
1696    fones\t%0"
1697   [(set_attr "type" "*,*,load,store,vismv,vismv,fpmove,fpload,fpstore,visl,visl")
1698    (set_attr "subtype" "*,*,regular,*,movstouw,single,*,*,*,single,single")
1699    (set_attr "cpu_feature" "*,*,*,*,vis3,vis3,*,*,*,vis,vis")])
1701 (define_insn "*movsi_lo_sum"
1702   [(set (match_operand:SI 0 "register_operand" "=r")
1703         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1704                    (match_operand:SI 2 "immediate_operand" "in")))]
1705   "!flag_pic"
1706   "or\t%1, %%lo(%a2), %0")
1708 (define_insn "*movsi_high"
1709   [(set (match_operand:SI 0 "register_operand" "=r")
1710         (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1711   "!flag_pic"
1712   "sethi\t%%hi(%a1), %0")
1714 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1715 ;; so that CSE won't optimize the address computation away.
1716 (define_insn "movsi_lo_sum_pic"
1717   [(set (match_operand:SI 0 "register_operand" "=r")
1718         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1719                    (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")]
1720                               UNSPEC_MOVE_PIC)))]
1721   "flag_pic"
1723 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1724   return "xor\t%1, %%gdop_lox10(%a2), %0";
1725 #else
1726   return "or\t%1, %%lo(%a2), %0";
1727 #endif
1730 (define_insn "movsi_high_pic"
1731   [(set (match_operand:SI 0 "register_operand" "=r")
1732         (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1733   "flag_pic && check_pic (1)"
1735 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1736   return "sethi\t%%gdop_hix22(%a1), %0";
1737 #else
1738   return "sethi\t%%hi(%a1), %0";
1739 #endif
1742 (define_insn "movsi_pic_gotdata_op"
1743   [(set (match_operand:SI 0 "register_operand" "=r")
1744         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
1745                     (match_operand:SI 2 "register_operand" "r")
1746                     (match_operand 3 "symbolic_operand" "")]
1747                    UNSPEC_MOVE_GOTDATA))]
1748   "flag_pic && check_pic (1)"
1750 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1751   return "ld\t[%1 + %2], %0, %%gdop(%a3)";
1752 #else
1753   return "ld\t[%1 + %2], %0";
1754 #endif
1756   [(set_attr "type" "load")
1757    (set_attr "subtype" "regular")])
1759 (define_expand "movsi_pic_label_ref"
1760   [(set (match_dup 3) (high:SI
1761      (unspec:SI [(match_operand:SI 1 "symbolic_operand" "")
1762                  (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1763    (set (match_dup 4) (lo_sum:SI (match_dup 3)
1764      (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1765    (set (match_operand:SI 0 "register_operand" "=r")
1766         (minus:SI (match_dup 5) (match_dup 4)))]
1767   "flag_pic"
1769   crtl->uses_pic_offset_table = 1;
1770   operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1771   if (!can_create_pseudo_p ())
1772     {
1773       operands[3] = operands[0];
1774       operands[4] = operands[0];
1775     }
1776   else
1777     {
1778       operands[3] = gen_reg_rtx (SImode);
1779       operands[4] = gen_reg_rtx (SImode);
1780     }
1781   operands[5] = pic_offset_table_rtx;
1784 (define_insn "*movsi_high_pic_label_ref"
1785   [(set (match_operand:SI 0 "register_operand" "=r")
1786       (high:SI
1787         (unspec:SI [(match_operand:SI 1 "symbolic_operand" "")
1788                     (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1789   "flag_pic"
1790   "sethi\t%%hi(%a2-(%a1-.)), %0")
1792 (define_insn "*movsi_lo_sum_pic_label_ref"
1793   [(set (match_operand:SI 0 "register_operand" "=r")
1794       (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1795         (unspec:SI [(match_operand:SI 2 "symbolic_operand" "")
1796                     (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1797   "flag_pic"
1798   "or\t%1, %%lo(%a3-(%a2-.)), %0")
1800 ;; Set up the PIC register for VxWorks.
1802 (define_expand "vxworks_load_got"
1803   [(set (match_dup 0)
1804         (high:SI (match_dup 1)))
1805    (set (match_dup 0)
1806         (mem:SI (lo_sum:SI (match_dup 0) (match_dup 1))))
1807    (set (match_dup 0)
1808         (mem:SI (lo_sum:SI (match_dup 0) (match_dup 2))))]
1809   "TARGET_VXWORKS_RTP"
1811   operands[0] = pic_offset_table_rtx;
1812   operands[1] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_BASE);
1813   operands[2] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_INDEX);
1816 (define_expand "movdi"
1817   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1818         (match_operand:DI 1 "general_operand" ""))]
1819   ""
1821   if (sparc_expand_move (DImode, operands))
1822     DONE;
1825 ;; Be careful, fmovd does not exist when !v9.
1826 ;; We match MEM moves directly when we have correct even
1827 ;; numbered registers, but fall into splits otherwise.
1828 ;; The constraint ordering here is really important to
1829 ;; avoid insane problems in reload, especially for patterns
1830 ;; of the form:
1832 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
1833 ;;                       (const_int -5016)))
1834 ;;      (reg:DI 2 %g2))
1837 (define_insn "*movdi_insn_sp32"
1838   [(set (match_operand:DI 0 "nonimmediate_operand"
1839                             "=T,o,U,T,r,o,r,r,?*f,?T,?*f,?o,?*e,?*e,  r,?*f,?*e,?T,*b,*b")
1840         (match_operand:DI 1 "input_operand"
1841                             " J,J,T,U,o,r,i,r,  T,*f,  o,*f, *e, *e,?*f,  r,  T,*e, J, P"))]
1842   "TARGET_ARCH32
1843    && (register_operand (operands[0], DImode)
1844        || register_or_zero_operand (operands[1], DImode))"
1845   "@
1846    stx\t%r1, %0
1847    #
1848    ldd\t%1, %0
1849    std\t%1, %0
1850    ldd\t%1, %0
1851    std\t%1, %0
1852    #
1853    #
1854    ldd\t%1, %0
1855    std\t%1, %0
1856    #
1857    #
1858    fmovd\t%1, %0
1859    #
1860    #
1861    #
1862    ldd\t%1, %0
1863    std\t%1, %0
1864    fzero\t%0
1865    fone\t%0"
1866   [(set_attr "type" "store,*,load,store,load,store,*,*,fpload,fpstore,*,*,fpmove,*,*,*,fpload,fpstore,visl,
1867 visl")
1868    (set_attr "subtype" "*,*,regular,*,regular,*,*,*,*,*,*,*,*,*,*,*,*,*,double,double")
1869    (set_attr "length" "*,2,*,*,*,*,2,2,*,*,2,2,*,2,2,2,*,*,*,*")
1870    (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*,*,*,*,double,double")
1871    (set_attr "cpu_feature" "v9,*,*,*,*,*,*,*,fpu,fpu,fpu,fpu,v9,fpunotv9,vis3,vis3,fpu,fpu,vis,vis")
1872    (set_attr "lra" "*,*,disabled,disabled,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
1874 (define_insn "*movdi_insn_sp64"
1875   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r, m, r,*e,?*e,?*e,?W,b,b")
1876         (match_operand:DI 1 "input_operand"        "rI,N,m,rJ,*e, r, *e,  W,*e,J,P"))]
1877   "TARGET_ARCH64
1878    && (register_operand (operands[0], DImode)
1879        || register_or_zero_or_all_ones_operand (operands[1], DImode))"
1880   "@
1881    mov\t%1, %0
1882    sethi\t%%hi(%a1), %0
1883    ldx\t%1, %0
1884    stx\t%r1, %0
1885    movdtox\t%1, %0
1886    movxtod\t%1, %0
1887    fmovd\t%1, %0
1888    ldd\t%1, %0
1889    std\t%1, %0
1890    fzero\t%0
1891    fone\t%0"
1892   [(set_attr "type" "*,*,load,store,vismv,vismv,fpmove,fpload,fpstore,visl,visl")
1893    (set_attr "subtype" "*,*,regular,*,movdtox,movxtod,*,*,*,double,double")
1894    (set_attr "fptype" "*,*,*,*,*,*,double,*,*,double,double")
1895    (set_attr "cpu_feature" "*,*,*,*,vis3,vis3,*,*,*,vis,vis")])
1897 (define_expand "movdi_pic_label_ref"
1898   [(set (match_dup 3) (high:DI
1899      (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")
1900                  (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1901    (set (match_dup 4) (lo_sum:DI (match_dup 3)
1902      (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1903    (set (match_operand:DI 0 "register_operand" "=r")
1904         (minus:DI (match_dup 5) (match_dup 4)))]
1905   "TARGET_ARCH64 && flag_pic"
1907   crtl->uses_pic_offset_table = 1;
1908   operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1909   if (!can_create_pseudo_p ())
1910     {
1911       operands[3] = operands[0];
1912       operands[4] = operands[0];
1913     }
1914   else
1915     {
1916       operands[3] = gen_reg_rtx (DImode);
1917       operands[4] = gen_reg_rtx (DImode);
1918     }
1919   operands[5] = pic_offset_table_rtx;
1922 (define_insn "*movdi_high_pic_label_ref"
1923   [(set (match_operand:DI 0 "register_operand" "=r")
1924         (high:DI
1925           (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")
1926                       (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1927   "TARGET_ARCH64 && flag_pic"
1928   "sethi\t%%hi(%a2-(%a1-.)), %0")
1930 (define_insn "*movdi_lo_sum_pic_label_ref"
1931   [(set (match_operand:DI 0 "register_operand" "=r")
1932       (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1933         (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")
1934                     (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1935   "TARGET_ARCH64 && flag_pic"
1936   "or\t%1, %%lo(%a3-(%a2-.)), %0")
1938 ;; SPARC-v9 code model support insns.  See sparc_emit_set_symbolic_const64
1939 ;; in sparc.c to see what is going on here... PIC stuff comes first.
1941 (define_insn "movdi_lo_sum_pic"
1942   [(set (match_operand:DI 0 "register_operand" "=r")
1943         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1944                    (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")]
1945                               UNSPEC_MOVE_PIC)))]
1946   "TARGET_ARCH64 && flag_pic"
1948 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1949   return "xor\t%1, %%gdop_lox10(%a2), %0";
1950 #else
1951   return "or\t%1, %%lo(%a2), %0";
1952 #endif
1955 (define_insn "movdi_high_pic"
1956   [(set (match_operand:DI 0 "register_operand" "=r")
1957         (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1958   "TARGET_ARCH64 && flag_pic && check_pic (1)"
1960 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1961   return "sethi\t%%gdop_hix22(%a1), %0";
1962 #else
1963   return "sethi\t%%hi(%a1), %0";
1964 #endif
1967 (define_insn "movdi_pic_gotdata_op"
1968   [(set (match_operand:DI 0 "register_operand" "=r")
1969         (unspec:DI [(match_operand:DI 1 "register_operand" "r")
1970                     (match_operand:DI 2 "register_operand" "r")
1971                     (match_operand 3 "symbolic_operand" "")]
1972                    UNSPEC_MOVE_GOTDATA))]
1973   "TARGET_ARCH64 && flag_pic && check_pic (1)"
1975 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1976   return "ldx\t[%1 + %2], %0, %%gdop(%a3)";
1977 #else
1978   return "ldx\t[%1 + %2], %0";
1979 #endif
1981   [(set_attr "type" "load")
1982    (set_attr "subtype" "regular")])
1984 (define_insn "*sethi_di_medlow_embmedany_pic"
1985   [(set (match_operand:DI 0 "register_operand" "=r")
1986         (high:DI (match_operand:DI 1 "medium_pic_operand" "")))]
1987   "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && flag_pic && check_pic (1)"
1988   "sethi\t%%hi(%a1), %0")
1990 (define_insn "*sethi_di_medlow"
1991   [(set (match_operand:DI 0 "register_operand" "=r")
1992         (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
1993   "TARGET_CM_MEDLOW && !flag_pic"
1994   "sethi\t%%hi(%a1), %0")
1996 (define_insn "*losum_di_medlow"
1997   [(set (match_operand:DI 0 "register_operand" "=r")
1998         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1999                    (match_operand:DI 2 "symbolic_operand" "")))]
2000   "TARGET_CM_MEDLOW && !flag_pic"
2001   "or\t%1, %%lo(%a2), %0")
2003 (define_insn "seth44"
2004   [(set (match_operand:DI 0 "register_operand" "=r")
2005         (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
2006                             UNSPEC_SETH44)))]
2007   "TARGET_CM_MEDMID && !flag_pic"
2008   "sethi\t%%h44(%a1), %0")
2010 (define_insn "setm44"
2011   [(set (match_operand:DI 0 "register_operand" "=r")
2012         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2013                    (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
2014                               UNSPEC_SETM44)))]
2015   "TARGET_CM_MEDMID && !flag_pic"
2016   "or\t%1, %%m44(%a2), %0")
2018 (define_insn "setl44"
2019   [(set (match_operand:DI 0 "register_operand" "=r")
2020         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2021                    (match_operand:DI 2 "symbolic_operand" "")))]
2022   "TARGET_CM_MEDMID && !flag_pic"
2023   "or\t%1, %%l44(%a2), %0")
2025 (define_insn "sethh"
2026   [(set (match_operand:DI 0 "register_operand" "=r")
2027         (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
2028                             UNSPEC_SETHH)))]
2029   "TARGET_CM_MEDANY && !flag_pic"
2030   "sethi\t%%hh(%a1), %0")
2032 (define_insn "setlm"
2033   [(set (match_operand:DI 0 "register_operand" "=r")
2034         (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
2035                             UNSPEC_SETLM)))]
2036   "TARGET_CM_MEDANY && !flag_pic"
2037   "sethi\t%%lm(%a1), %0")
2039 (define_insn "sethm"
2040   [(set (match_operand:DI 0 "register_operand" "=r")
2041         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2042                    (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
2043                               UNSPEC_EMB_SETHM)))]
2044   "TARGET_CM_MEDANY && !flag_pic"
2045   "or\t%1, %%hm(%a2), %0")
2047 (define_insn "setlo"
2048   [(set (match_operand:DI 0 "register_operand" "=r")
2049         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2050                    (match_operand:DI 2 "symbolic_operand" "")))]
2051   "TARGET_CM_MEDANY && !flag_pic"
2052   "or\t%1, %%lo(%a2), %0")
2054 (define_insn "embmedany_sethi"
2055   [(set (match_operand:DI 0 "register_operand" "=r")
2056         (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")]
2057                             UNSPEC_EMB_HISUM)))]
2058   "TARGET_CM_EMBMEDANY && !flag_pic"
2059   "sethi\t%%hi(%a1), %0")
2061 (define_insn "embmedany_losum"
2062   [(set (match_operand:DI 0 "register_operand" "=r")
2063         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2064                    (match_operand:DI 2 "data_segment_operand" "")))]
2065   "TARGET_CM_EMBMEDANY && !flag_pic"
2066   "add\t%1, %%lo(%a2), %0")
2068 (define_insn "embmedany_brsum"
2069   [(set (match_operand:DI 0 "register_operand" "=r")
2070         (unspec:DI [(match_operand:DI 1 "register_operand" "r")]
2071                    UNSPEC_EMB_HISUM))]
2072   "TARGET_CM_EMBMEDANY && !flag_pic"
2073   "add\t%1, %_, %0")
2075 (define_insn "embmedany_textuhi"
2076   [(set (match_operand:DI 0 "register_operand" "=r")
2077         (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")]
2078                             UNSPEC_EMB_TEXTUHI)))]
2079   "TARGET_CM_EMBMEDANY && !flag_pic"
2080   "sethi\t%%uhi(%a1), %0")
2082 (define_insn "embmedany_texthi"
2083   [(set (match_operand:DI 0 "register_operand" "=r")
2084         (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")]
2085                             UNSPEC_EMB_TEXTHI)))]
2086   "TARGET_CM_EMBMEDANY && !flag_pic"
2087   "sethi\t%%hi(%a1), %0")
2089 (define_insn "embmedany_textulo"
2090   [(set (match_operand:DI 0 "register_operand" "=r")
2091         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2092                    (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")]
2093                               UNSPEC_EMB_TEXTULO)))]
2094   "TARGET_CM_EMBMEDANY && !flag_pic"
2095   "or\t%1, %%ulo(%a2), %0")
2097 (define_insn "embmedany_textlo"
2098   [(set (match_operand:DI 0 "register_operand" "=r")
2099         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2100                    (match_operand:DI 2 "text_segment_operand" "")))]
2101   "TARGET_CM_EMBMEDANY && !flag_pic"
2102   "or\t%1, %%lo(%a2), %0")
2104 ;; Now some patterns to help reload out a bit.
2105 (define_expand "reload_indi"
2106   [(parallel [(match_operand:DI 0 "register_operand" "=r")
2107               (match_operand:DI 1 "immediate_operand" "")
2108               (match_operand:TI 2 "register_operand" "=&r")])]
2109   "(TARGET_CM_MEDANY || TARGET_CM_EMBMEDANY) && !flag_pic"
2111   sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2112   DONE;
2115 (define_expand "reload_outdi"
2116   [(parallel [(match_operand:DI 0 "register_operand" "=r")
2117               (match_operand:DI 1 "immediate_operand" "")
2118               (match_operand:TI 2 "register_operand" "=&r")])]
2119   "(TARGET_CM_MEDANY || TARGET_CM_EMBMEDANY) && !flag_pic"
2121   sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2122   DONE;
2125 ;; Split up putting CONSTs and REGs into DI regs when !arch64
2126 (define_split
2127   [(set (match_operand:DI 0 "register_operand" "")
2128         (match_operand:DI 1 "const_int_operand" ""))]
2129   "reload_completed
2130    && TARGET_ARCH32
2131    && ((GET_CODE (operands[0]) == REG
2132         && SPARC_INT_REG_P (REGNO (operands[0])))
2133        || (GET_CODE (operands[0]) == SUBREG
2134            && GET_CODE (SUBREG_REG (operands[0])) == REG
2135            && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
2136   [(clobber (const_int 0))]
2138   HOST_WIDE_INT low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
2139   HOST_WIDE_INT high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
2140   rtx high_part = gen_highpart (SImode, operands[0]);
2141   rtx low_part = gen_lowpart (SImode, operands[0]);
2143   emit_move_insn_1 (high_part, GEN_INT (high));
2145   /* Slick... but this loses if the constant can be done in one insn.  */
2146   if (low == high && !SPARC_SETHI32_P (high) && !SPARC_SIMM13_P (high))
2147     emit_move_insn_1 (low_part, high_part);
2148   else
2149     emit_move_insn_1 (low_part, GEN_INT (low));
2151   DONE;
2154 (define_split
2155   [(set (match_operand:DI 0 "register_operand" "")
2156         (match_operand:DI 1 "register_operand" ""))]
2157   "reload_completed
2158    && (!TARGET_V9
2159        || (TARGET_ARCH32
2160            && sparc_split_reg_reg_legitimate (operands[0], operands[1])))"
2161   [(clobber (const_int 0))]
2163   sparc_split_reg_reg (operands[0], operands[1], SImode);
2164   DONE;
2167 ;; Now handle the cases of memory moves from/to non-even
2168 ;; DI mode register pairs.
2169 (define_split
2170   [(set (match_operand:DI 0 "register_operand" "")
2171         (match_operand:DI 1 "memory_operand" ""))]
2172   "reload_completed
2173    && TARGET_ARCH32
2174    && sparc_split_reg_mem_legitimate (operands[0], operands[1])"
2175   [(clobber (const_int 0))]
2177   sparc_split_reg_mem (operands[0], operands[1], SImode);
2178   DONE;
2181 (define_split
2182   [(set (match_operand:DI 0 "memory_operand" "")
2183         (match_operand:DI 1 "register_operand" ""))]
2184   "reload_completed
2185    && TARGET_ARCH32
2186    && sparc_split_reg_mem_legitimate (operands[1], operands[0])"
2187   [(clobber (const_int 0))]
2189   sparc_split_mem_reg (operands[0], operands[1], SImode);
2190   DONE;
2193 (define_split
2194   [(set (match_operand:DI 0 "memory_operand" "")
2195         (match_operand:DI 1 "const_zero_operand" ""))]
2196   "reload_completed
2197    && (!TARGET_V9
2198        || (TARGET_ARCH32
2199            && !mem_min_alignment (operands[0], 8)))
2200    && offsettable_memref_p (operands[0])"
2201   [(clobber (const_int 0))]
2203   emit_move_insn_1 (adjust_address (operands[0], SImode, 0), const0_rtx);
2204   emit_move_insn_1 (adjust_address (operands[0], SImode, 4), const0_rtx);
2205   DONE;
2208 (define_expand "movti"
2209   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2210         (match_operand:TI 1 "general_operand" ""))]
2211   "TARGET_ARCH64"
2213   if (sparc_expand_move (TImode, operands))
2214     DONE;
2217 ;; We need to prevent reload from splitting TImode moves, because it
2218 ;; might decide to overwrite a pointer with the value it points to.
2219 ;; In that case we have to do the loads in the appropriate order so
2220 ;; that the pointer is not destroyed too early.
2222 (define_insn "*movti_insn_sp64"
2223   [(set (match_operand:TI 0 "nonimmediate_operand" "=r , o,?*e,?o,b")
2224         (match_operand:TI 1 "input_operand"        "roJ,rJ, eo, e,J"))]
2225   "TARGET_ARCH64
2226    && !TARGET_HARD_QUAD
2227    && (register_operand (operands[0], TImode)
2228        || register_or_zero_operand (operands[1], TImode))"
2229   "#"
2230   [(set_attr "length" "2,2,2,2,2")
2231    (set_attr "cpu_feature" "*,*,fpu,fpu,vis")])
2233 (define_insn "*movti_insn_sp64_hq"
2234   [(set (match_operand:TI 0 "nonimmediate_operand" "=r , o,?*e,?*e,?m,b")
2235         (match_operand:TI 1 "input_operand"        "roJ,rJ,  e,  m, e,J"))]
2236   "TARGET_ARCH64
2237    && TARGET_HARD_QUAD
2238    && (register_operand (operands[0], TImode)
2239        || register_or_zero_operand (operands[1], TImode))"
2240   "@
2241   #
2242   #
2243   fmovq\t%1, %0
2244   ldq\t%1, %0
2245   stq\t%1, %0
2246   #"
2247   [(set_attr "type" "*,*,fpmove,fpload,fpstore,*")
2248    (set_attr "length" "2,2,*,*,*,2")])
2250 ;; Now all the splits to handle multi-insn TI mode moves.
2251 (define_split
2252   [(set (match_operand:TI 0 "register_operand" "")
2253         (match_operand:TI 1 "register_operand" ""))]
2254   "reload_completed
2255    && ((TARGET_FPU
2256         && !TARGET_HARD_QUAD)
2257        || (!fp_register_operand (operands[0], TImode)
2258            && !fp_register_operand (operands[1], TImode)))"
2259   [(clobber (const_int 0))]
2261   rtx set_dest = operands[0];
2262   rtx set_src = operands[1];
2263   rtx dest1, dest2;
2264   rtx src1, src2;
2266   dest1 = gen_highpart (DImode, set_dest);
2267   dest2 = gen_lowpart (DImode, set_dest);
2268   src1 = gen_highpart (DImode, set_src);
2269   src2 = gen_lowpart (DImode, set_src);
2271   /* Now emit using the real source and destination we found, swapping
2272      the order if we detect overlap.  */
2273   if (reg_overlap_mentioned_p (dest1, src2))
2274     {
2275       emit_insn (gen_movdi (dest2, src2));
2276       emit_insn (gen_movdi (dest1, src1));
2277     }
2278   else
2279     {
2280       emit_insn (gen_movdi (dest1, src1));
2281       emit_insn (gen_movdi (dest2, src2));
2282     }
2283   DONE;
2286 (define_split
2287   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2288         (match_operand:TI 1 "const_zero_operand" ""))]
2289   "reload_completed"
2290   [(clobber (const_int 0))]
2292   rtx set_dest = operands[0];
2293   rtx dest1, dest2;
2295   switch (GET_CODE (set_dest))
2296     {
2297     case REG:
2298       dest1 = gen_highpart (DImode, set_dest);
2299       dest2 = gen_lowpart (DImode, set_dest);
2300       break;
2301     case MEM:
2302       dest1 = adjust_address (set_dest, DImode, 0);
2303       dest2 = adjust_address (set_dest, DImode, 8);
2304       break;
2305     default:
2306       gcc_unreachable ();
2307     }
2309   emit_insn (gen_movdi (dest1, const0_rtx));
2310   emit_insn (gen_movdi (dest2, const0_rtx));
2311   DONE;
2314 (define_split
2315   [(set (match_operand:TI 0 "register_operand" "")
2316         (match_operand:TI 1 "memory_operand" ""))]
2317   "reload_completed
2318    && offsettable_memref_p (operands[1])
2319    && (!TARGET_HARD_QUAD
2320        || !fp_register_operand (operands[0], TImode))"
2321   [(clobber (const_int 0))]
2323   rtx word0 = adjust_address (operands[1], DImode, 0);
2324   rtx word1 = adjust_address (operands[1], DImode, 8);
2325   rtx set_dest, dest1, dest2;
2327   set_dest = operands[0];
2329   dest1 = gen_highpart (DImode, set_dest);
2330   dest2 = gen_lowpart (DImode, set_dest);
2332   /* Now output, ordering such that we don't clobber any registers
2333      mentioned in the address.  */
2334   if (reg_overlap_mentioned_p (dest1, word1))
2336     {
2337       emit_insn (gen_movdi (dest2, word1));
2338       emit_insn (gen_movdi (dest1, word0));
2339     }
2340   else
2341    {
2342       emit_insn (gen_movdi (dest1, word0));
2343       emit_insn (gen_movdi (dest2, word1));
2344    }
2345   DONE;
2348 (define_split
2349   [(set (match_operand:TI 0 "memory_operand" "")
2350         (match_operand:TI 1 "register_operand" ""))]
2351   "reload_completed
2352    && offsettable_memref_p (operands[0])
2353    && (!TARGET_HARD_QUAD
2354        || !fp_register_operand (operands[1], TImode))"
2355   [(clobber (const_int 0))]
2357   rtx set_src = operands[1];
2359   emit_insn (gen_movdi (adjust_address (operands[0], DImode, 0),
2360                         gen_highpart (DImode, set_src)));
2361   emit_insn (gen_movdi (adjust_address (operands[0], DImode, 8),
2362                         gen_lowpart (DImode, set_src)));
2363   DONE;
2367 ;; Floating point move instructions
2369 (define_expand "movsf"
2370   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2371         (match_operand:SF 1 "general_operand" ""))]
2372   ""
2374   if (sparc_expand_move (SFmode, operands))
2375     DONE;
2378 (define_insn "*movsf_insn"
2379   [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,f, *r,*r,*r,*r, f,f,*r,m,  m")
2380         (match_operand:SF 1 "input_operand"         "G,C,f,*rR, Q, S, f,*r,m, m,f,*rG"))]
2381   "(register_operand (operands[0], SFmode)
2382     || register_or_zero_or_all_ones_operand (operands[1], SFmode))"
2384   if (GET_CODE (operands[1]) == CONST_DOUBLE
2385       && (which_alternative == 3
2386           || which_alternative == 4
2387           || which_alternative == 5))
2388     {
2389       long i;
2391       REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (operands[1]), i);
2392       operands[1] = GEN_INT (i);
2393     }
2395   switch (which_alternative)
2396     {
2397     case 0:
2398       return "fzeros\t%0";
2399     case 1:
2400       return "fones\t%0";
2401     case 2:
2402       return "fmovs\t%1, %0";
2403     case 3:
2404       return "mov\t%1, %0";
2405     case 4:
2406       return "sethi\t%%hi(%a1), %0";
2407     case 5:
2408       return "#";
2409     case 6:
2410       return "movstouw\t%1, %0";
2411     case 7:
2412       return "movwtos\t%1, %0";
2413     case 8:
2414     case 9:
2415       return "ld\t%1, %0";
2416     case 10:
2417     case 11:
2418       return "st\t%r1, %0";
2419     default:
2420       gcc_unreachable ();
2421     }
2423   [(set_attr "type" "visl,visl,fpmove,*,*,*,vismv,vismv,fpload,load,fpstore,store")
2424    (set_attr "subtype" "single,single,*,*,*,*,movstouw,single,*,regular,*,*")
2425    (set_attr "cpu_feature" "vis,vis,fpu,*,*,*,vis3,vis3,fpu,*,fpu,*")])
2427 ;; The following 3 patterns build SFmode constants in integer registers.
2429 (define_insn "*movsf_lo_sum"
2430   [(set (match_operand:SF 0 "register_operand" "=r")
2431         (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
2432                    (match_operand:SF 2 "fp_const_high_losum_operand" "S")))]
2433   ""
2435   long i;
2437   REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (operands[2]), i);
2438   operands[2] = GEN_INT (i);
2439   return "or\t%1, %%lo(%a2), %0";
2442 (define_insn "*movsf_high"
2443   [(set (match_operand:SF 0 "register_operand" "=r")
2444         (high:SF (match_operand:SF 1 "fp_const_high_losum_operand" "S")))]
2445   ""
2447   long i;
2449   REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (operands[1]), i);
2450   operands[1] = GEN_INT (i);
2451   return "sethi\t%%hi(%1), %0";
2454 (define_split
2455   [(set (match_operand:SF 0 "register_operand" "")
2456         (match_operand:SF 1 "fp_const_high_losum_operand" ""))]
2457   "REG_P (operands[0]) && SPARC_INT_REG_P (REGNO (operands[0]))"
2458   [(set (match_dup 0) (high:SF (match_dup 1)))
2459    (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
2461 (define_expand "movdf"
2462   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2463         (match_operand:DF 1 "general_operand" ""))]
2464   ""
2466   if (sparc_expand_move (DFmode, operands))
2467     DONE;
2470 (define_insn "*movdf_insn_sp32"
2471   [(set (match_operand:DF 0 "nonimmediate_operand"
2472                             "=T,o,b,b,e,e,*r, f,  e,T,U,T,  f,o, *r,*r, o")
2473         (match_operand:DF 1 "input_operand"
2474                             " G,G,G,C,e,e, f,*r,T#F,e,T,U,o#F,f,*rF, o,*r"))]
2475   "TARGET_ARCH32
2476    && (register_operand (operands[0], DFmode)
2477        || register_or_zero_or_all_ones_operand (operands[1], DFmode))"
2478   "@
2479   stx\t%r1, %0
2480   #
2481   fzero\t%0
2482   fone\t%0
2483   fmovd\t%1, %0
2484   #
2485   #
2486   #
2487   ldd\t%1, %0
2488   std\t%1, %0
2489   ldd\t%1, %0
2490   std\t%1, %0
2491   #
2492   #
2493   #
2494   ldd\t%1, %0
2495   std\t%1, %0"
2496   [(set_attr "type" "store,*,visl,visl,fpmove,*,*,*,fpload,fpstore,load,store,*,*,*,load,store")
2497    (set_attr "subtype" "*,*,double,double,*,*,*,*,*,*,regular,*,*,*,*,regular,*")
2498    (set_attr "length" "*,2,*,*,*,2,2,2,*,*,*,*,2,2,2,*,*")
2499    (set_attr "fptype" "*,*,double,double,double,*,*,*,*,*,*,*,*,*,*,*,*")
2500    (set_attr "cpu_feature" "v9,*,vis,vis,v9,fpunotv9,vis3,vis3,fpu,fpu,*,*,fpu,fpu,*,*,*")
2501    (set_attr "lra" "*,*,*,*,*,*,*,*,*,*,disabled,disabled,*,*,*,*,*")])
2503 (define_insn "*movdf_insn_sp64"
2504   [(set (match_operand:DF 0 "nonimmediate_operand" "=b,b,e,*r, e,  e,W, *r,*r,  m,*r")
2505         (match_operand:DF 1 "input_operand"         "G,C,e, e,*r,W#F,e,*rG, m,*rG, F"))]
2506   "TARGET_ARCH64
2507    && (register_operand (operands[0], DFmode)
2508        || register_or_zero_or_all_ones_operand (operands[1], DFmode))"
2509   "@
2510   fzero\t%0
2511   fone\t%0
2512   fmovd\t%1, %0
2513   movdtox\t%1, %0
2514   movxtod\t%1, %0
2515   ldd\t%1, %0
2516   std\t%1, %0
2517   mov\t%r1, %0
2518   ldx\t%1, %0
2519   stx\t%r1, %0
2520   #"
2521   [(set_attr "type" "visl,visl,fpmove,vismv,vismv,load,store,*,load,store,*")
2522    (set_attr "subtype" "double,double,*,movdtox,movxtod,regular,*,*,regular,*,*")
2523    (set_attr "length" "*,*,*,*,*,*,*,*,*,*,2")
2524    (set_attr "fptype" "double,double,double,double,double,*,*,*,*,*,*")
2525    (set_attr "cpu_feature" "vis,vis,fpu,vis3,vis3,fpu,fpu,*,*,*,*")])
2527 ;; This pattern builds DFmode constants in integer registers.
2528 (define_split
2529   [(set (match_operand:DF 0 "register_operand" "")
2530         (match_operand:DF 1 "const_double_operand" ""))]
2531   "reload_completed
2532    && REG_P (operands[0])
2533    && SPARC_INT_REG_P (REGNO (operands[0]))
2534    && !const_zero_operand (operands[1], GET_MODE (operands[0]))"
2535   [(clobber (const_int 0))]
2537   operands[0] = gen_raw_REG (DImode, REGNO (operands[0]));
2539   if (TARGET_ARCH64)
2540     {
2541       rtx tem = simplify_subreg (DImode, operands[1], DFmode, 0);
2542       emit_insn (gen_movdi (operands[0], tem));
2543     }
2544   else
2545     {
2546       rtx hi = simplify_subreg (SImode, operands[1], DFmode, 0);
2547       rtx lo = simplify_subreg (SImode, operands[1], DFmode, 4);
2548       rtx high_part = gen_highpart (SImode, operands[0]);
2549       rtx low_part = gen_lowpart (SImode, operands[0]);
2551       gcc_assert (GET_CODE (hi) == CONST_INT);
2552       gcc_assert (GET_CODE (lo) == CONST_INT);
2554       emit_move_insn_1 (high_part, hi);
2556       /* Slick... but this loses if the constant can be done in one insn.  */
2557       if (lo == hi
2558           && !SPARC_SETHI32_P (INTVAL (hi))
2559           && !SPARC_SIMM13_P (INTVAL (hi)))
2560         emit_move_insn_1 (low_part, high_part);
2561       else
2562         emit_move_insn_1 (low_part, lo);
2563     }
2564   DONE;
2567 ;; Ok, now the splits to handle all the multi insn and
2568 ;; mis-aligned memory address cases.
2569 ;; In these splits please take note that we must be
2570 ;; careful when V9 but not ARCH64 because the integer
2571 ;; register DFmode cases must be handled.
2572 (define_split
2573   [(set (match_operand:DF 0 "register_operand" "")
2574         (match_operand:DF 1 "const_zero_operand" ""))]
2575   "reload_completed
2576    && TARGET_ARCH32
2577    && ((GET_CODE (operands[0]) == REG
2578         && SPARC_INT_REG_P (REGNO (operands[0])))
2579        || (GET_CODE (operands[0]) == SUBREG
2580            && GET_CODE (SUBREG_REG (operands[0])) == REG
2581            && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
2582   [(clobber (const_int 0))]
2584   emit_move_insn_1 (gen_highpart (SFmode, operands[0]), CONST0_RTX (SFmode));
2585   emit_move_insn_1 (gen_lowpart (SFmode, operands[0]), CONST0_RTX (SFmode));
2586   DONE;
2589 (define_split
2590   [(set (match_operand:DF 0 "register_operand" "")
2591         (match_operand:DF 1 "register_operand" ""))]
2592   "reload_completed
2593    && (!TARGET_V9
2594        || (TARGET_ARCH32
2595            && sparc_split_reg_reg_legitimate (operands[0], operands[1])))"
2596   [(clobber (const_int 0))]
2598   sparc_split_reg_reg (operands[0], operands[1], SFmode);
2599   DONE;
2602 (define_split
2603   [(set (match_operand:DF 0 "register_operand" "")
2604         (match_operand:DF 1 "memory_operand" ""))]
2605   "reload_completed
2606    && TARGET_ARCH32
2607    && sparc_split_reg_mem_legitimate (operands[0], operands[1])"
2608   [(clobber (const_int 0))]
2610   sparc_split_reg_mem (operands[0], operands[1], SFmode);
2611   DONE;
2614 (define_split
2615   [(set (match_operand:DF 0 "memory_operand" "")
2616         (match_operand:DF 1 "register_operand" ""))]
2617   "reload_completed
2618    && TARGET_ARCH32
2619    && sparc_split_reg_mem_legitimate (operands[1], operands[0])"
2620   [(clobber (const_int 0))]
2622   sparc_split_mem_reg (operands[0], operands[1], SFmode);
2623   DONE;
2626 (define_split
2627   [(set (match_operand:DF 0 "memory_operand" "")
2628         (match_operand:DF 1 "const_zero_operand" ""))]
2629   "reload_completed
2630    && (!TARGET_V9
2631        || (TARGET_ARCH32
2632            && !mem_min_alignment (operands[0], 8)))
2633    && offsettable_memref_p (operands[0])"
2634   [(clobber (const_int 0))]
2636   emit_move_insn_1 (adjust_address (operands[0], SFmode, 0), CONST0_RTX (SFmode));
2637   emit_move_insn_1 (adjust_address (operands[0], SFmode, 4), CONST0_RTX (SFmode));
2638   DONE;
2641 (define_expand "movtf"
2642   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2643         (match_operand:TF 1 "general_operand" ""))]
2644   ""
2646   if (sparc_expand_move (TFmode, operands))
2647     DONE;
2650 (define_insn "*movtf_insn_sp32"
2651   [(set (match_operand:TF 0 "nonimmediate_operand" "=b, e,o, o,  r")
2652         (match_operand:TF 1 "input_operand"        " G,oe,e,rG,roG"))]
2653   "TARGET_ARCH32
2654    && (register_operand (operands[0], TFmode)
2655        || register_or_zero_operand (operands[1], TFmode))"
2656   "#"
2657   [(set_attr "length" "4,4,4,4,4")
2658    (set_attr "cpu_feature" "fpu,fpu,fpu,*,*")])
2660 (define_insn "*movtf_insn_sp64"
2661   [(set (match_operand:TF 0 "nonimmediate_operand" "=b, e,o, o,  r")
2662         (match_operand:TF 1 "input_operand"         "G,oe,e,rG,roG"))]
2663   "TARGET_ARCH64
2664    && !TARGET_HARD_QUAD
2665    && (register_operand (operands[0], TFmode)
2666        || register_or_zero_operand (operands[1], TFmode))"
2667   "#"
2668   [(set_attr "length" "2,2,2,2,2")
2669    (set_attr "cpu_feature" "fpu,fpu,fpu,*,*")])
2671 (define_insn "*movtf_insn_sp64_hq"
2672   [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,e,m, o,  r")
2673         (match_operand:TF 1 "input_operand"         "G,e,m,e,rG,roG"))]
2674   "TARGET_ARCH64
2675    && TARGET_HARD_QUAD
2676    && (register_operand (operands[0], TFmode)
2677        || register_or_zero_operand (operands[1], TFmode))"
2678   "@
2679   #
2680   fmovq\t%1, %0
2681   ldq\t%1, %0
2682   stq\t%1, %0
2683   #
2684   #"
2685   [(set_attr "type" "*,fpmove,fpload,fpstore,*,*")
2686    (set_attr "length" "2,*,*,*,2,2")])
2688 ;; Now all the splits to handle multi-insn TF mode moves.
2689 (define_split
2690   [(set (match_operand:TF 0 "register_operand" "")
2691         (match_operand:TF 1 "register_operand" ""))]
2692   "reload_completed
2693    && (TARGET_ARCH32
2694        || (TARGET_FPU
2695            && !TARGET_HARD_QUAD)
2696        || (!fp_register_operand (operands[0], TFmode)
2697            && !fp_register_operand (operands[1], TFmode)))"
2698   [(clobber (const_int 0))]
2700   rtx set_dest = operands[0];
2701   rtx set_src = operands[1];
2702   rtx dest1, dest2;
2703   rtx src1, src2;
2705   dest1 = gen_df_reg (set_dest, 0);
2706   dest2 = gen_df_reg (set_dest, 1);
2707   src1 = gen_df_reg (set_src, 0);
2708   src2 = gen_df_reg (set_src, 1);
2710   /* Now emit using the real source and destination we found, swapping
2711      the order if we detect overlap.  */
2712   if (reg_overlap_mentioned_p (dest1, src2))
2713     {
2714       emit_insn (gen_movdf (dest2, src2));
2715       emit_insn (gen_movdf (dest1, src1));
2716     }
2717   else
2718     {
2719       emit_insn (gen_movdf (dest1, src1));
2720       emit_insn (gen_movdf (dest2, src2));
2721     }
2722   DONE;
2725 (define_split
2726   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2727         (match_operand:TF 1 "const_zero_operand" ""))]
2728   "reload_completed"
2729   [(clobber (const_int 0))]
2731   rtx set_dest = operands[0];
2732   rtx dest1, dest2;
2734   switch (GET_CODE (set_dest))
2735     {
2736     case REG:
2737       dest1 = gen_df_reg (set_dest, 0);
2738       dest2 = gen_df_reg (set_dest, 1);
2739       break;
2740     case MEM:
2741       dest1 = adjust_address (set_dest, DFmode, 0);
2742       dest2 = adjust_address (set_dest, DFmode, 8);
2743       break;
2744     default:
2745       gcc_unreachable ();
2746     }
2748   emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
2749   emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
2750   DONE;
2753 (define_split
2754   [(set (match_operand:TF 0 "register_operand" "")
2755         (match_operand:TF 1 "memory_operand" ""))]
2756   "(reload_completed
2757     && offsettable_memref_p (operands[1])
2758     && (TARGET_ARCH32
2759         || !TARGET_HARD_QUAD
2760         || !fp_register_operand (operands[0], TFmode)))"
2761   [(clobber (const_int 0))]
2763   rtx word0 = adjust_address (operands[1], DFmode, 0);
2764   rtx word1 = adjust_address (operands[1], DFmode, 8);
2765   rtx set_dest, dest1, dest2;
2767   set_dest = operands[0];
2769   dest1 = gen_df_reg (set_dest, 0);
2770   dest2 = gen_df_reg (set_dest, 1);
2772   /* Now output, ordering such that we don't clobber any registers
2773      mentioned in the address.  */
2774   if (reg_overlap_mentioned_p (dest1, word1))
2776     {
2777       emit_insn (gen_movdf (dest2, word1));
2778       emit_insn (gen_movdf (dest1, word0));
2779     }
2780   else
2781    {
2782       emit_insn (gen_movdf (dest1, word0));
2783       emit_insn (gen_movdf (dest2, word1));
2784    }
2785   DONE;
2788 (define_split
2789   [(set (match_operand:TF 0 "memory_operand" "")
2790         (match_operand:TF 1 "register_operand" ""))]
2791   "(reload_completed
2792     && offsettable_memref_p (operands[0])
2793     && (TARGET_ARCH32
2794         || !TARGET_HARD_QUAD
2795         || !fp_register_operand (operands[1], TFmode)))"
2796   [(clobber (const_int 0))]
2798   rtx set_src = operands[1];
2800   emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
2801                         gen_df_reg (set_src, 0)));
2802   emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
2803                         gen_df_reg (set_src, 1)));
2804   DONE;
2808 ;; SPARC-V9 conditional move instructions
2810 ;; We can handle larger constants here for some flavors, but for now we keep
2811 ;; it simple and only allow those constants supported by all flavors.
2812 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
2813 ;; 3 contains the constant if one is present, but we handle either for
2814 ;; generality (sparc.c puts a constant in operand 2).
2816 ;; Our instruction patterns, on the other hand, canonicalize such that
2817 ;; operand 3 must be the set destination.
2819 (define_expand "mov<I:mode>cc"
2820   [(set (match_operand:I 0 "register_operand" "")
2821         (if_then_else:I (match_operand 1 "comparison_operator" "")
2822                         (match_operand:I 2 "arith10_operand" "")
2823                         (match_operand:I 3 "arith10_operand" "")))]
2824   "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2826   if (!sparc_expand_conditional_move (<I:MODE>mode, operands))
2827     FAIL;
2828   DONE;
2831 (define_expand "mov<F:mode>cc"
2832   [(set (match_operand:F 0 "register_operand" "")
2833         (if_then_else:F (match_operand 1 "comparison_operator" "")
2834                         (match_operand:F 2 "register_operand" "")
2835                         (match_operand:F 3 "register_operand" "")))]
2836   "TARGET_V9 && TARGET_FPU"
2838   if (!sparc_expand_conditional_move (<F:MODE>mode, operands))
2839     FAIL;
2840   DONE;
2843 (define_insn "*mov<I:mode>_cc_v9"
2844   [(set (match_operand:I 0 "register_operand" "=r")
2845         (if_then_else:I (match_operator 1 "icc_or_fcc_comparison_operator"
2846                          [(match_operand 2 "icc_or_fcc_register_operand" "X")
2847                           (const_int 0)])
2848                         (match_operand:I 3 "arith11_operand" "rL")
2849                         (match_operand:I 4 "register_operand" "0")))]
2850   "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2851   "mov%C1\t%x2, %3, %0"
2852   [(set_attr "type" "cmove")])
2854 (define_insn "*mov<I:mode>_cc_reg_sp64"
2855   [(set (match_operand:I 0 "register_operand" "=r")
2856         (if_then_else:I (match_operator 1 "v9_register_comparison_operator"
2857                          [(match_operand:DI 2 "register_operand" "r")
2858                           (const_int 0)])
2859                         (match_operand:I 3 "arith10_operand" "rM")
2860                         (match_operand:I 4 "register_operand" "0")))]
2861   "TARGET_ARCH64"
2862   "movr%D1\t%2, %r3, %0"
2863   [(set_attr "type" "cmove")])
2865 (define_insn "*movsf_cc_v9"
2866   [(set (match_operand:SF 0 "register_operand" "=f")
2867         (if_then_else:SF (match_operator 1 "icc_or_fcc_comparison_operator"
2868                           [(match_operand 2 "icc_or_fcc_register_operand" "X")
2869                            (const_int 0)])
2870                          (match_operand:SF 3 "register_operand" "f")
2871                          (match_operand:SF 4 "register_operand" "0")))]
2872   "TARGET_V9 && TARGET_FPU"
2873   "fmovs%C1\t%x2, %3, %0"
2874   [(set_attr "type" "fpcmove")])
2876 (define_insn "*movsf_cc_reg_sp64"
2877   [(set (match_operand:SF 0 "register_operand" "=f")
2878         (if_then_else:SF (match_operator 1 "v9_register_comparison_operator"
2879                           [(match_operand:DI 2 "register_operand" "r")
2880                            (const_int 0)])
2881                          (match_operand:SF 3 "register_operand" "f")
2882                          (match_operand:SF 4 "register_operand" "0")))]
2883   "TARGET_ARCH64 && TARGET_FPU"
2884   "fmovrs%D1\t%2, %3, %0"
2885   [(set_attr "type" "fpcrmove")])
2887 ;; Named because invoked by movtf_cc_v9
2888 (define_insn "movdf_cc_v9"
2889   [(set (match_operand:DF 0 "register_operand" "=e")
2890         (if_then_else:DF (match_operator 1 "icc_or_fcc_comparison_operator"
2891                           [(match_operand 2 "icc_or_fcc_register_operand" "X")
2892                            (const_int 0)])
2893                          (match_operand:DF 3 "register_operand" "e")
2894                          (match_operand:DF 4 "register_operand" "0")))]
2895   "TARGET_V9 && TARGET_FPU"
2896   "fmovd%C1\t%x2, %3, %0"
2897   [(set_attr "type" "fpcmove")
2898    (set_attr "fptype" "double")])
2900 ;; Named because invoked by movtf_cc_reg_sp64
2901 (define_insn "movdf_cc_reg_sp64"
2902   [(set (match_operand:DF 0 "register_operand" "=e")
2903         (if_then_else:DF (match_operator 1 "v9_register_comparison_operator"
2904                           [(match_operand:DI 2 "register_operand" "r")
2905                            (const_int 0)])
2906                          (match_operand:DF 3 "register_operand" "e")
2907                          (match_operand:DF 4 "register_operand" "0")))]
2908   "TARGET_ARCH64 && TARGET_FPU"
2909   "fmovrd%D1\t%2, %3, %0"
2910   [(set_attr "type" "fpcrmove")
2911    (set_attr "fptype" "double")])
2913 (define_insn "*movtf_cc_hq_v9"
2914   [(set (match_operand:TF 0 "register_operand" "=e")
2915         (if_then_else:TF (match_operator 1 "icc_or_fcc_comparison_operator"
2916                           [(match_operand 2 "icc_or_fcc_register_operand" "X")
2917                            (const_int 0)])
2918                          (match_operand:TF 3 "register_operand" "e")
2919                          (match_operand:TF 4 "register_operand" "0")))]
2920   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
2921   "fmovq%C1\t%x2, %3, %0"
2922   [(set_attr "type" "fpcmove")])
2924 (define_insn "*movtf_cc_reg_hq_sp64"
2925   [(set (match_operand:TF 0 "register_operand" "=e")
2926         (if_then_else:TF (match_operator 1 "v9_register_comparison_operator"
2927                           [(match_operand:DI 2 "register_operand" "r")
2928                            (const_int 0)])
2929                          (match_operand:TF 3 "register_operand" "e")
2930                          (match_operand:TF 4 "register_operand" "0")))]
2931   "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
2932   "fmovrq%D1\t%2, %3, %0"
2933   [(set_attr "type" "fpcrmove")])
2935 (define_insn_and_split "*movtf_cc_v9"
2936   [(set (match_operand:TF 0 "register_operand" "=e")
2937         (if_then_else:TF (match_operator 1 "icc_or_fcc_comparison_operator"
2938                           [(match_operand 2 "icc_or_fcc_register_operand" "X")
2939                            (const_int 0)])
2940                          (match_operand:TF 3 "register_operand" "e")
2941                          (match_operand:TF 4 "register_operand" "0")))]
2942   "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
2943   "#"
2944   "&& reload_completed"
2945   [(clobber (const_int 0))]
2947   rtx set_dest = operands[0];
2948   rtx set_srca = operands[3];
2949   rtx dest1, dest2;
2950   rtx srca1, srca2;
2952   dest1 = gen_df_reg (set_dest, 0);
2953   dest2 = gen_df_reg (set_dest, 1);
2954   srca1 = gen_df_reg (set_srca, 0);
2955   srca2 = gen_df_reg (set_srca, 1);
2957   if (reg_overlap_mentioned_p (dest1, srca2))
2958     {
2959       emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2],
2960                                   srca2, dest2));
2961       emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2],
2962                                   srca1, dest1));
2963     }
2964   else
2965     {
2966       emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2],
2967                                   srca1, dest1));
2968       emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2],
2969                                   srca2, dest2));
2970     }
2971   DONE;
2973   [(set_attr "length" "2")])
2975 (define_insn_and_split "*movtf_cc_reg_sp64"
2976   [(set (match_operand:TF 0 "register_operand" "=e")
2977         (if_then_else:TF (match_operator 1 "v9_register_comparison_operator"
2978                           [(match_operand:DI 2 "register_operand" "r")
2979                            (const_int 0)])
2980                          (match_operand:TF 3 "register_operand" "e")
2981                          (match_operand:TF 4 "register_operand" "0")))]
2982   "TARGET_ARCH64 && TARGET_FPU && !TARGET_HARD_QUAD"
2983   "#"
2984   "&& reload_completed"
2985   [(clobber (const_int 0))]
2987   rtx set_dest = operands[0];
2988   rtx set_srca = operands[3];
2989   rtx dest1, dest2;
2990   rtx srca1, srca2;
2992   dest1 = gen_df_reg (set_dest, 0);
2993   dest2 = gen_df_reg (set_dest, 1);
2994   srca1 = gen_df_reg (set_srca, 0);
2995   srca2 = gen_df_reg (set_srca, 1);
2997   if (reg_overlap_mentioned_p (dest1, srca2))
2998     {
2999       emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2],
3000                                         srca2, dest2));
3001       emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2],
3002                                         srca1, dest1));
3003     }
3004   else
3005     {
3006       emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2],
3007                                         srca1, dest1));
3008       emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2],
3009                                         srca2, dest2));
3010     }
3011   DONE;
3013   [(set_attr "length" "2")])
3016 ;; Zero-extension instructions
3018 ;; These patterns originally accepted general_operands, however, slightly
3019 ;; better code is generated by only accepting register_operands, and then
3020 ;; letting combine generate the ldu[hb] insns.
3022 (define_expand "zero_extendhisi2"
3023   [(set (match_operand:SI 0 "register_operand" "")
3024         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
3025   ""
3027   rtx temp = gen_reg_rtx (SImode);
3028   rtx shift_16 = GEN_INT (16);
3029   int op1_subbyte = 0;
3031   if (GET_CODE (operand1) == SUBREG)
3032     {
3033       op1_subbyte = SUBREG_BYTE (operand1);
3034       op1_subbyte /= GET_MODE_SIZE (SImode);
3035       op1_subbyte *= GET_MODE_SIZE (SImode);
3036       operand1 = XEXP (operand1, 0);
3037     }
3039   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3040                           shift_16));
3041   emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
3042   DONE;
3045 (define_insn "*zero_extendhisi2_insn"
3046   [(set (match_operand:SI 0 "register_operand" "=r")
3047         (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3048   ""
3049   "lduh\t%1, %0"
3050   [(set_attr "type" "load")
3051    (set_attr "subtype" "regular")
3052    (set_attr "us3load_type" "3cycle")])
3054 (define_expand "zero_extendqihi2"
3055   [(set (match_operand:HI 0 "register_operand" "")
3056         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
3057   ""
3058   "")
3060 (define_insn "*zero_extendqihi2_insn"
3061   [(set (match_operand:HI 0 "register_operand" "=r,r")
3062         (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
3063   "GET_CODE (operands[1]) != CONST_INT"
3064   "@
3065    and\t%1, 0xff, %0
3066    ldub\t%1, %0"
3067   [(set_attr "type" "*,load")
3068    (set_attr "subtype" "*,regular")
3069    (set_attr "us3load_type" "*,3cycle")])
3071 (define_expand "zero_extendqisi2"
3072   [(set (match_operand:SI 0 "register_operand" "")
3073         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
3074   ""
3075   "")
3077 (define_insn "*zero_extendqisi2_insn"
3078   [(set (match_operand:SI 0 "register_operand" "=r,r")
3079         (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
3080   "GET_CODE (operands[1]) != CONST_INT"
3081   "@
3082    and\t%1, 0xff, %0
3083    ldub\t%1, %0"
3084   [(set_attr "type" "*,load")
3085    (set_attr "subtype" "*,regular")
3086    (set_attr "us3load_type" "*,3cycle")])
3088 (define_expand "zero_extendqidi2"
3089   [(set (match_operand:DI 0 "register_operand" "")
3090         (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
3091   "TARGET_ARCH64"
3092   "")
3094 (define_insn "*zero_extendqidi2_insn"
3095   [(set (match_operand:DI 0 "register_operand" "=r,r")
3096         (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
3097   "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
3098   "@
3099    and\t%1, 0xff, %0
3100    ldub\t%1, %0"
3101   [(set_attr "type" "*,load")
3102    (set_attr "subtype" "*,regular")
3103    (set_attr "us3load_type" "*,3cycle")])
3105 (define_expand "zero_extendhidi2"
3106   [(set (match_operand:DI 0 "register_operand" "")
3107         (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
3108   "TARGET_ARCH64"
3110   rtx temp = gen_reg_rtx (DImode);
3111   rtx shift_48 = GEN_INT (48);
3112   int op1_subbyte = 0;
3114   if (GET_CODE (operand1) == SUBREG)
3115     {
3116       op1_subbyte = SUBREG_BYTE (operand1);
3117       op1_subbyte /= GET_MODE_SIZE (DImode);
3118       op1_subbyte *= GET_MODE_SIZE (DImode);
3119       operand1 = XEXP (operand1, 0);
3120     }
3122   emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3123                           shift_48));
3124   emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
3125   DONE;
3128 (define_insn "*zero_extendhidi2_insn"
3129   [(set (match_operand:DI 0 "register_operand" "=r")
3130         (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3131   "TARGET_ARCH64"
3132   "lduh\t%1, %0"
3133   [(set_attr "type" "load")
3134    (set_attr "subtype" "regular")
3135    (set_attr "us3load_type" "3cycle")])
3137 ;; ??? Write truncdisi pattern using sra?
3139 (define_expand "zero_extendsidi2"
3140   [(set (match_operand:DI 0 "register_operand" "")
3141         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
3142   ""
3143   "")
3145 (define_insn "*zero_extendsidi2_insn_sp64"
3146   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
3147         (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m,*f")))]
3148   "TARGET_ARCH64
3149    && GET_CODE (operands[1]) != CONST_INT"
3150   "@
3151    srl\t%1, 0, %0
3152    lduw\t%1, %0
3153    movstouw\t%1, %0"
3154   [(set_attr "type" "shift,load,vismv")
3155    (set_attr "subtype" "*,regular,movstouw")
3156    (set_attr "cpu_feature" "*,*,vis3")])
3158 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
3159   [(set (match_operand:DI 0 "register_operand" "=r")
3160         (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
3161   "TARGET_ARCH32"
3162   "#"
3163   "&& reload_completed"
3164   [(set (match_dup 2) (match_dup 1))
3165    (set (match_dup 3) (const_int 0))]
3166   "operands[2] = gen_lowpart (SImode, operands[0]);
3167    operands[3] = gen_highpart (SImode, operands[0]);"
3168   [(set_attr "length" "2")])
3170 ;; Simplify comparisons of extended values.
3172 (define_insn "*cmp_zero_extendqisi2"
3173   [(set (reg:CC CC_REG)
3174         (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
3175                     (const_int 0)))]
3176   ""
3177   "andcc\t%0, 0xff, %%g0"
3178   [(set_attr "type" "compare")])
3180 (define_insn "*cmp_zero_qi"
3181   [(set (reg:CC CC_REG)
3182         (compare:CC (match_operand:QI 0 "register_operand" "r")
3183                     (const_int 0)))]
3184   ""
3185   "andcc\t%0, 0xff, %%g0"
3186   [(set_attr "type" "compare")])
3188 (define_insn "*cmp_zero_extendqisi2_set"
3189   [(set (reg:CC CC_REG)
3190         (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
3191                     (const_int 0)))
3192    (set (match_operand:SI 0 "register_operand" "=r")
3193         (zero_extend:SI (match_dup 1)))]
3194   ""
3195   "andcc\t%1, 0xff, %0"
3196   [(set_attr "type" "compare")])
3198 (define_insn "*cmp_zero_extendqisi2_andcc_set"
3199   [(set (reg:CC CC_REG)
3200         (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
3201                             (const_int 255))
3202                     (const_int 0)))
3203    (set (match_operand:SI 0 "register_operand" "=r")
3204         (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
3205   ""
3206   "andcc\t%1, 0xff, %0"
3207   [(set_attr "type" "compare")])
3209 (define_insn "*cmp_zero_extendqidi2"
3210   [(set (reg:CCX CC_REG)
3211         (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
3212                      (const_int 0)))]
3213   "TARGET_ARCH64"
3214   "andcc\t%0, 0xff, %%g0"
3215   [(set_attr "type" "compare")])
3217 (define_insn "*cmp_zero_qi_sp64"
3218   [(set (reg:CCX CC_REG)
3219         (compare:CCX (match_operand:QI 0 "register_operand" "r")
3220                      (const_int 0)))]
3221   "TARGET_ARCH64"
3222   "andcc\t%0, 0xff, %%g0"
3223   [(set_attr "type" "compare")])
3225 (define_insn "*cmp_zero_extendqidi2_set"
3226   [(set (reg:CCX CC_REG)
3227         (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
3228                      (const_int 0)))
3229    (set (match_operand:DI 0 "register_operand" "=r")
3230         (zero_extend:DI (match_dup 1)))]
3231   "TARGET_ARCH64"
3232   "andcc\t%1, 0xff, %0"
3233   [(set_attr "type" "compare")])
3235 (define_insn "*cmp_zero_extendqidi2_andcc_set"
3236   [(set (reg:CCX CC_REG)
3237         (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
3238                              (const_int 255))
3239                      (const_int 0)))
3240    (set (match_operand:DI 0 "register_operand" "=r")
3241         (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
3242   "TARGET_ARCH64"
3243   "andcc\t%1, 0xff, %0"
3244   [(set_attr "type" "compare")])
3246 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
3248 (define_insn "*cmp_siqi_trunc"
3249   [(set (reg:CC CC_REG)
3250         (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
3251                     (const_int 0)))]
3252   ""
3253   "andcc\t%0, 0xff, %%g0"
3254   [(set_attr "type" "compare")])
3256 (define_insn "*cmp_siqi_trunc_set"
3257   [(set (reg:CC CC_REG)
3258         (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
3259                     (const_int 0)))
3260    (set (match_operand:QI 0 "register_operand" "=r")
3261         (subreg:QI (match_dup 1) 3))]
3262   ""
3263   "andcc\t%1, 0xff, %0"
3264   [(set_attr "type" "compare")])
3266 (define_insn "*cmp_diqi_trunc"
3267   [(set (reg:CC CC_REG)
3268         (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
3269                     (const_int 0)))]
3270   "TARGET_ARCH64"
3271   "andcc\t%0, 0xff, %%g0"
3272   [(set_attr "type" "compare")])
3274 (define_insn "*cmp_diqi_trunc_set"
3275   [(set (reg:CC CC_REG)
3276         (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
3277                     (const_int 0)))
3278    (set (match_operand:QI 0 "register_operand" "=r")
3279         (subreg:QI (match_dup 1) 7))]
3280   "TARGET_ARCH64"
3281   "andcc\t%1, 0xff, %0"
3282   [(set_attr "type" "compare")])
3285 ;; Sign-extension instructions
3287 ;; These patterns originally accepted general_operands, however, slightly
3288 ;; better code is generated by only accepting register_operands, and then
3289 ;; letting combine generate the lds[hb] insns.
3291 (define_expand "extendhisi2"
3292   [(set (match_operand:SI 0 "register_operand" "")
3293         (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
3294   ""
3296   rtx temp = gen_reg_rtx (SImode);
3297   rtx shift_16 = GEN_INT (16);
3298   int op1_subbyte = 0;
3300   if (GET_CODE (operand1) == SUBREG)
3301     {
3302       op1_subbyte = SUBREG_BYTE (operand1);
3303       op1_subbyte /= GET_MODE_SIZE (SImode);
3304       op1_subbyte *= GET_MODE_SIZE (SImode);
3305       operand1 = XEXP (operand1, 0);
3306     }
3308   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3309                           shift_16));
3310   emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
3311   DONE;
3314 (define_insn "*sign_extendhisi2_insn"
3315   [(set (match_operand:SI 0 "register_operand" "=r")
3316         (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3317   ""
3318   "ldsh\t%1, %0"
3319   [(set_attr "type" "sload")
3320    (set_attr "us3load_type" "3cycle")])
3322 (define_expand "extendqihi2"
3323   [(set (match_operand:HI 0 "register_operand" "")
3324         (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
3325   ""
3327   rtx temp = gen_reg_rtx (SImode);
3328   rtx shift_24 = GEN_INT (24);
3329   int op1_subbyte = 0;
3330   int op0_subbyte = 0;
3332   if (GET_CODE (operand1) == SUBREG)
3333     {
3334       op1_subbyte = SUBREG_BYTE (operand1);
3335       op1_subbyte /= GET_MODE_SIZE (SImode);
3336       op1_subbyte *= GET_MODE_SIZE (SImode);
3337       operand1 = XEXP (operand1, 0);
3338     }
3339   if (GET_CODE (operand0) == SUBREG)
3340     {
3341       op0_subbyte = SUBREG_BYTE (operand0);
3342       op0_subbyte /= GET_MODE_SIZE (SImode);
3343       op0_subbyte *= GET_MODE_SIZE (SImode);
3344       operand0 = XEXP (operand0, 0);
3345     }
3346   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3347                           shift_24));
3348   if (GET_MODE (operand0) != SImode)
3349     operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
3350   emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3351   DONE;
3354 (define_insn "*sign_extendqihi2_insn"
3355   [(set (match_operand:HI 0 "register_operand" "=r")
3356         (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3357   ""
3358   "ldsb\t%1, %0"
3359   [(set_attr "type" "sload")
3360    (set_attr "us3load_type" "3cycle")])
3362 (define_expand "extendqisi2"
3363   [(set (match_operand:SI 0 "register_operand" "")
3364         (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
3365   ""
3367   rtx temp = gen_reg_rtx (SImode);
3368   rtx shift_24 = GEN_INT (24);
3369   int op1_subbyte = 0;
3371   if (GET_CODE (operand1) == SUBREG)
3372     {
3373       op1_subbyte = SUBREG_BYTE (operand1);
3374       op1_subbyte /= GET_MODE_SIZE (SImode);
3375       op1_subbyte *= GET_MODE_SIZE (SImode);
3376       operand1 = XEXP (operand1, 0);
3377     }
3379   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3380                           shift_24));
3381   emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3382   DONE;
3385 (define_insn "*sign_extendqisi2_insn"
3386   [(set (match_operand:SI 0 "register_operand" "=r")
3387         (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3388   ""
3389   "ldsb\t%1, %0"
3390   [(set_attr "type" "sload")
3391    (set_attr "us3load_type" "3cycle")])
3393 (define_expand "extendqidi2"
3394   [(set (match_operand:DI 0 "register_operand" "")
3395         (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
3396   "TARGET_ARCH64"
3398   rtx temp = gen_reg_rtx (DImode);
3399   rtx shift_56 = GEN_INT (56);
3400   int op1_subbyte = 0;
3402   if (GET_CODE (operand1) == SUBREG)
3403     {
3404       op1_subbyte = SUBREG_BYTE (operand1);
3405       op1_subbyte /= GET_MODE_SIZE (DImode);
3406       op1_subbyte *= GET_MODE_SIZE (DImode);
3407       operand1 = XEXP (operand1, 0);
3408     }
3410   emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3411                           shift_56));
3412   emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
3413   DONE;
3416 (define_insn "*sign_extendqidi2_insn"
3417   [(set (match_operand:DI 0 "register_operand" "=r")
3418         (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3419   "TARGET_ARCH64"
3420   "ldsb\t%1, %0"
3421   [(set_attr "type" "sload")
3422    (set_attr "us3load_type" "3cycle")])
3424 (define_expand "extendhidi2"
3425   [(set (match_operand:DI 0 "register_operand" "")
3426         (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
3427   "TARGET_ARCH64"
3429   rtx temp = gen_reg_rtx (DImode);
3430   rtx shift_48 = GEN_INT (48);
3431   int op1_subbyte = 0;
3433   if (GET_CODE (operand1) == SUBREG)
3434     {
3435       op1_subbyte = SUBREG_BYTE (operand1);
3436       op1_subbyte /= GET_MODE_SIZE (DImode);
3437       op1_subbyte *= GET_MODE_SIZE (DImode);
3438       operand1 = XEXP (operand1, 0);
3439     }
3441   emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3442                           shift_48));
3443   emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
3444   DONE;
3447 (define_insn "*sign_extendhidi2_insn"
3448   [(set (match_operand:DI 0 "register_operand" "=r")
3449         (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3450   "TARGET_ARCH64"
3451   "ldsh\t%1, %0"
3452   [(set_attr "type" "sload")
3453    (set_attr "us3load_type" "3cycle")])
3455 (define_expand "extendsidi2"
3456   [(set (match_operand:DI 0 "register_operand" "")
3457         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3458   "TARGET_ARCH64"
3459   "")
3461 (define_insn "*sign_extendsidi2_insn"
3462   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
3463         (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m,*f")))]
3464   "TARGET_ARCH64"
3465   "@
3466   sra\t%1, 0, %0
3467   ldsw\t%1, %0
3468   movstosw\t%1, %0"
3469   [(set_attr "type" "shift,sload,vismv")
3470    (set_attr "us3load_type" "*,3cycle,*")
3471    (set_attr "cpu_feature" "*,*,vis3")])
3474 ;; Special pattern for optimizing bit-field compares.  This is needed
3475 ;; because combine uses this as a canonical form.
3477 (define_insn "*cmp_zero_extract"
3478   [(set (reg:CC CC_REG)
3479         (compare:CC
3480          (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
3481                           (match_operand:SI 1 "small_int_operand" "I")
3482                           (match_operand:SI 2 "small_int_operand" "I"))
3483          (const_int 0)))]
3484   "INTVAL (operands[2]) > 19"
3486   int len = INTVAL (operands[1]);
3487   int pos = 32 - INTVAL (operands[2]) - len;
3488   HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
3489   operands[1] = GEN_INT (mask);
3490   return "andcc\t%0, %1, %%g0";
3492   [(set_attr "type" "compare")])
3494 (define_insn "*cmp_zero_extract_sp64"
3495   [(set (reg:CCX CC_REG)
3496         (compare:CCX
3497          (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
3498                           (match_operand:SI 1 "small_int_operand" "I")
3499                           (match_operand:SI 2 "small_int_operand" "I"))
3500          (const_int 0)))]
3501   "TARGET_ARCH64 && INTVAL (operands[2]) > 51"
3503   int len = INTVAL (operands[1]);
3504   int pos = 64 - INTVAL (operands[2]) - len;
3505   HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
3506   operands[1] = GEN_INT (mask);
3507   return "andcc\t%0, %1, %%g0";
3509   [(set_attr "type" "compare")])
3512 ;; Conversions between float, double and long double.
3514 (define_insn "extendsfdf2"
3515   [(set (match_operand:DF 0 "register_operand" "=e")
3516         (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
3517   "TARGET_FPU"
3518   "fstod\t%1, %0"
3519   [(set_attr "type" "fp")
3520    (set_attr "fptype" "double")])
3522 (define_expand "extendsftf2"
3523   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3524         (float_extend:TF (match_operand:SF 1 "register_operand" "")))]
3525   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3526   "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3528 (define_insn "*extendsftf2_hq"
3529   [(set (match_operand:TF 0 "register_operand" "=e")
3530         (float_extend:TF (match_operand:SF 1 "register_operand" "f")))]
3531   "TARGET_FPU && TARGET_HARD_QUAD"
3532   "fstoq\t%1, %0"
3533   [(set_attr "type" "fp")])
3535 (define_expand "extenddftf2"
3536   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3537         (float_extend:TF (match_operand:DF 1 "register_operand" "")))]
3538   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3539   "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3541 (define_insn "*extenddftf2_hq"
3542   [(set (match_operand:TF 0 "register_operand" "=e")
3543         (float_extend:TF (match_operand:DF 1 "register_operand" "e")))]
3544   "TARGET_FPU && TARGET_HARD_QUAD"
3545   "fdtoq\t%1, %0"
3546   [(set_attr "type" "fp")])
3548 (define_insn "truncdfsf2"
3549   [(set (match_operand:SF 0 "register_operand" "=f")
3550         (float_truncate:SF (match_operand:DF 1 "register_operand" "e")))]
3551   "TARGET_FPU"
3552   "fdtos\t%1, %0"
3553   [(set_attr "type" "fp")
3554    (set_attr "fptype" "double")
3555    (set_attr "fptype_ut699" "single")])
3557 (define_expand "trunctfsf2"
3558   [(set (match_operand:SF 0 "register_operand" "")
3559         (float_truncate:SF (match_operand:TF 1 "general_operand" "")))]
3560   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3561   "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3563 (define_insn "*trunctfsf2_hq"
3564   [(set (match_operand:SF 0 "register_operand" "=f")
3565         (float_truncate:SF (match_operand:TF 1 "register_operand" "e")))]
3566   "TARGET_FPU && TARGET_HARD_QUAD"
3567   "fqtos\t%1, %0"
3568   [(set_attr "type" "fp")])
3570 (define_expand "trunctfdf2"
3571   [(set (match_operand:DF 0 "register_operand" "")
3572         (float_truncate:DF (match_operand:TF 1 "general_operand" "")))]
3573   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3574   "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3576 (define_insn "*trunctfdf2_hq"
3577   [(set (match_operand:DF 0 "register_operand" "=e")
3578         (float_truncate:DF (match_operand:TF 1 "register_operand" "e")))]
3579   "TARGET_FPU && TARGET_HARD_QUAD"
3580   "fqtod\t%1, %0"
3581   [(set_attr "type" "fp")])
3584 ;; Conversion between fixed point and floating point.
3586 (define_insn "floatsisf2"
3587   [(set (match_operand:SF 0 "register_operand" "=f")
3588         (float:SF (match_operand:SI 1 "register_operand" "f")))]
3589   "TARGET_FPU"
3590   "fitos\t%1, %0"
3591   [(set_attr "type" "fp")
3592    (set_attr "fptype" "single")])
3594 (define_insn "floatsidf2"
3595   [(set (match_operand:DF 0 "register_operand" "=e")
3596         (float:DF (match_operand:SI 1 "register_operand" "f")))]
3597   "TARGET_FPU"
3598   "fitod\t%1, %0"
3599   [(set_attr "type" "fp")
3600    (set_attr "fptype" "double")])
3602 (define_expand "floatsitf2"
3603   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3604         (float:TF (match_operand:SI 1 "register_operand" "")))]
3605   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3606   "emit_tfmode_cvt (FLOAT, operands); DONE;")
3608 (define_insn "*floatsitf2_hq"
3609   [(set (match_operand:TF 0 "register_operand" "=e")
3610         (float:TF (match_operand:SI 1 "register_operand" "f")))]
3611   "TARGET_FPU && TARGET_HARD_QUAD"
3612   "fitoq\t%1, %0"
3613   [(set_attr "type" "fp")])
3615 (define_expand "floatunssitf2"
3616   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3617         (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
3618   "TARGET_FPU && TARGET_ARCH64 && !TARGET_HARD_QUAD"
3619   "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3621 ;; Now the same for 64 bit sources.
3623 (define_insn "floatdisf2"
3624   [(set (match_operand:SF 0 "register_operand" "=f")
3625         (float:SF (match_operand:DI 1 "register_operand" "e")))]
3626   "TARGET_V9 && TARGET_FPU"
3627   "fxtos\t%1, %0"
3628   [(set_attr "type" "fp")
3629    (set_attr "fptype" "double")])
3631 (define_expand "floatunsdisf2"
3632   [(use (match_operand:SF 0 "register_operand" ""))
3633    (use (match_operand:DI 1 "general_operand" ""))]
3634   "TARGET_ARCH64 && TARGET_FPU"
3635   "sparc_emit_floatunsdi (operands, SFmode); DONE;")
3637 (define_insn "floatdidf2"
3638   [(set (match_operand:DF 0 "register_operand" "=e")
3639         (float:DF (match_operand:DI 1 "register_operand" "e")))]
3640   "TARGET_V9 && TARGET_FPU"
3641   "fxtod\t%1, %0"
3642   [(set_attr "type" "fp")
3643    (set_attr "fptype" "double")])
3645 (define_expand "floatunsdidf2"
3646   [(use (match_operand:DF 0 "register_operand" ""))
3647    (use (match_operand:DI 1 "general_operand" ""))]
3648   "TARGET_ARCH64 && TARGET_FPU"
3649   "sparc_emit_floatunsdi (operands, DFmode); DONE;")
3651 (define_expand "floatditf2"
3652   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3653         (float:TF (match_operand:DI 1 "register_operand" "")))]
3654   "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3655   "emit_tfmode_cvt (FLOAT, operands); DONE;")
3657 (define_insn "*floatditf2_hq"
3658   [(set (match_operand:TF 0 "register_operand" "=e")
3659         (float:TF (match_operand:DI 1 "register_operand" "e")))]
3660   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3661   "fxtoq\t%1, %0"
3662   [(set_attr "type" "fp")])
3664 (define_expand "floatunsditf2"
3665   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3666         (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
3667   "TARGET_FPU && TARGET_ARCH64 && !TARGET_HARD_QUAD"
3668   "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3670 ;; Convert a float to an actual integer.
3671 ;; Truncation is performed as part of the conversion.
3673 (define_insn "fix_truncsfsi2"
3674   [(set (match_operand:SI 0 "register_operand" "=f")
3675         (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3676   "TARGET_FPU"
3677   "fstoi\t%1, %0"
3678   [(set_attr "type" "fp")
3679    (set_attr "fptype" "single")])
3681 (define_insn "fix_truncdfsi2"
3682   [(set (match_operand:SI 0 "register_operand" "=f")
3683         (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3684   "TARGET_FPU"
3685   "fdtoi\t%1, %0"
3686   [(set_attr "type" "fp")
3687    (set_attr "fptype" "double")
3688    (set_attr "fptype_ut699" "single")])
3690 (define_expand "fix_trunctfsi2"
3691   [(set (match_operand:SI 0 "register_operand" "")
3692         (fix:SI (match_operand:TF 1 "general_operand" "")))]
3693   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3694   "emit_tfmode_cvt (FIX, operands); DONE;")
3696 (define_insn "*fix_trunctfsi2_hq"
3697   [(set (match_operand:SI 0 "register_operand" "=f")
3698         (fix:SI (match_operand:TF 1 "register_operand" "e")))]
3699   "TARGET_FPU && TARGET_HARD_QUAD"
3700   "fqtoi\t%1, %0"
3701   [(set_attr "type" "fp")])
3703 (define_expand "fixuns_trunctfsi2"
3704   [(set (match_operand:SI 0 "register_operand" "")
3705         (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
3706   "TARGET_FPU && TARGET_ARCH64 && !TARGET_HARD_QUAD"
3707   "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3709 ;; Now the same, for V9 targets
3711 (define_insn "fix_truncsfdi2"
3712   [(set (match_operand:DI 0 "register_operand" "=e")
3713         (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3714   "TARGET_V9 && TARGET_FPU"
3715   "fstox\t%1, %0"
3716   [(set_attr "type" "fp")
3717    (set_attr "fptype" "double")])
3719 (define_expand "fixuns_truncsfdi2"
3720   [(use (match_operand:DI 0 "register_operand" ""))
3721    (use (match_operand:SF 1 "general_operand" ""))]
3722   "TARGET_ARCH64 && TARGET_FPU"
3723   "sparc_emit_fixunsdi (operands, SFmode); DONE;")
3725 (define_insn "fix_truncdfdi2"
3726   [(set (match_operand:DI 0 "register_operand" "=e")
3727         (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3728   "TARGET_V9 && TARGET_FPU"
3729   "fdtox\t%1, %0"
3730   [(set_attr "type" "fp")
3731    (set_attr "fptype" "double")])
3733 (define_expand "fixuns_truncdfdi2"
3734   [(use (match_operand:DI 0 "register_operand" ""))
3735    (use (match_operand:DF 1 "general_operand" ""))]
3736   "TARGET_ARCH64 && TARGET_FPU"
3737   "sparc_emit_fixunsdi (operands, DFmode); DONE;")
3739 (define_expand "fix_trunctfdi2"
3740   [(set (match_operand:DI 0 "register_operand" "")
3741         (fix:DI (match_operand:TF 1 "general_operand" "")))]
3742   "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3743   "emit_tfmode_cvt (FIX, operands); DONE;")
3745 (define_insn "*fix_trunctfdi2_hq"
3746   [(set (match_operand:DI 0 "register_operand" "=e")
3747         (fix:DI (match_operand:TF 1 "register_operand" "e")))]
3748   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3749   "fqtox\t%1, %0"
3750   [(set_attr "type" "fp")])
3752 (define_expand "fixuns_trunctfdi2"
3753   [(set (match_operand:DI 0 "register_operand" "")
3754         (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
3755   "TARGET_FPU && TARGET_ARCH64 && !TARGET_HARD_QUAD"
3756   "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3759 ;; Integer addition/subtraction instructions.
3761 (define_expand "adddi3"
3762   [(set (match_operand:DI 0 "register_operand" "")
3763         (plus:DI (match_operand:DI 1 "register_operand" "")
3764                  (match_operand:DI 2 "arith_double_add_operand" "")))]
3765   ""
3767   if (TARGET_ARCH32)
3768     {
3769       emit_insn (gen_adddi3_sp32 (operands[0], operands[1], operands[2]));
3770       DONE;
3771     }
3774 (define_expand "uaddvdi4"
3775   [(parallel [(set (reg:CCXC CC_REG)
3776                    (compare:CCXC (plus:DI (match_operand:DI 1 "register_operand")
3777                                           (match_operand:DI 2 "arith_add_operand"))
3778                                  (match_dup 1)))
3779               (set (match_operand:DI 0 "register_operand")
3780                    (plus:DI (match_dup 1) (match_dup 2)))])
3781    (set (pc) (if_then_else (ltu (reg:CCXC CC_REG) (const_int 0))
3782                            (label_ref (match_operand 3))
3783                            (pc)))]
3784  ""
3786   if (TARGET_ARCH32)
3787     {
3788       emit_insn (gen_uaddvdi4_sp32 (operands[0], operands[1], operands[2]));
3789       rtx x = gen_rtx_LTU (VOIDmode, gen_rtx_REG (CCCmode, SPARC_ICC_REG),
3790                                      const0_rtx);
3791       emit_jump_insn (gen_cbranchcc4 (x, XEXP (x, 0), XEXP (x, 1), operands[3]));
3792       DONE;
3793     }
3796 (define_expand "addvdi4"
3797   [(parallel [(set (reg:CCXV CC_REG)
3798                    (compare:CCXV (plus:DI (match_operand:DI 1 "register_operand")
3799                                           (match_operand:DI 2 "arith_add_operand"))
3800                                  (unspec:DI [(match_dup 1) (match_dup 2)]
3801                                             UNSPEC_ADDV)))
3802               (set (match_operand:DI 0 "register_operand")
3803                    (plus:DI (match_dup 1) (match_dup 2)))])
3804    (set (pc) (if_then_else (ne (reg:CCXV CC_REG) (const_int 0))
3805                            (label_ref (match_operand 3))
3806                            (pc)))]
3807  ""
3809   if (TARGET_ARCH32)
3810     {
3811       emit_insn (gen_addvdi4_sp32 (operands[0], operands[1], operands[2]));
3812       rtx x = gen_rtx_NE (VOIDmode, gen_rtx_REG (CCVmode, SPARC_ICC_REG),
3813                                     const0_rtx);
3814       emit_jump_insn (gen_cbranchcc4 (x, XEXP (x, 0), XEXP (x, 1), operands[3]));
3815       DONE;
3816     }
3819 (define_insn_and_split "adddi3_sp32"
3820   [(set (match_operand:DI 0 "register_operand" "=&r")
3821         (plus:DI (match_operand:DI 1 "register_operand" "%r")
3822                  (match_operand:DI 2 "arith_double_operand" "rHI")))
3823    (clobber (reg:CC CC_REG))]
3824   "TARGET_ARCH32"
3825   "#"
3826   "&& reload_completed"
3827   [(parallel [(set (reg:CCC CC_REG)
3828                    (compare:CCC (plus:SI (match_dup 4) (match_dup 5))
3829                                 (match_dup 4)))
3830               (set (match_dup 3)
3831                    (plus:SI (match_dup 4) (match_dup 5)))])
3832    (set (match_dup 6)
3833         (plus:SI (plus:SI (match_dup 7) (match_dup 8))
3834                  (ltu:SI (reg:CCC CC_REG) (const_int 0))))]
3836   operands[3] = gen_lowpart (SImode, operands[0]);
3837   operands[4] = gen_lowpart (SImode, operands[1]);
3838   operands[5] = gen_lowpart (SImode, operands[2]);
3839   operands[6] = gen_highpart (SImode, operands[0]);
3840   operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
3841   operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3843   [(set_attr "length" "2")])
3845 (define_insn_and_split "uaddvdi4_sp32"
3846   [(set (reg:CCC CC_REG)
3847         (compare:CCC (plus:DI (match_operand:DI 1 "register_operand" "%r")
3848                               (match_operand:DI 2 "arith_double_operand" "rHI"))
3849                      (match_dup 1)))
3850    (set (match_operand:DI 0 "register_operand" "=&r")
3851         (plus:DI (match_dup 1) (match_dup 2)))]
3852   "TARGET_ARCH32"
3853   "#"
3854   "&& reload_completed"
3855   [(parallel [(set (reg:CCC CC_REG)
3856                    (compare:CCC (plus:SI (match_dup 4) (match_dup 5))
3857                                 (match_dup 4)))
3858               (set (match_dup 3)
3859                    (plus:SI (match_dup 4) (match_dup 5)))])
3860    (parallel [(set (reg:CCC CC_REG)
3861                    (compare:CCC (zero_extend:DI
3862                                   (plus:SI (plus:SI (match_dup 7) (match_dup 8))
3863                                            (ltu:SI (reg:CCC CC_REG)
3864                                                    (const_int 0))))
3865                                 (plus:DI (plus:DI (zero_extend:DI (match_dup 7))
3866                                                   (zero_extend:DI (match_dup 8)))
3867                                          (ltu:DI (reg:CCC CC_REG)
3868                                                  (const_int 0)))))
3869               (set (match_dup 6)
3870                    (plus:SI (plus:SI (match_dup 7) (match_dup 8))
3871                             (ltu:SI (reg:CCC CC_REG)
3872                                     (const_int 0))))])]
3874   operands[3] = gen_lowpart (SImode, operands[0]);
3875   operands[4] = gen_lowpart (SImode, operands[1]);
3876   operands[5] = gen_lowpart (SImode, operands[2]);
3877   operands[6] = gen_highpart (SImode, operands[0]);
3878   operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
3879   operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3881   [(set_attr "length" "2")])
3883 (define_insn_and_split "addvdi4_sp32"
3884   [(set (reg:CCV CC_REG)
3885         (compare:CCV (plus:DI (match_operand:DI 1 "register_operand" "%r")
3886                               (match_operand:DI 2 "arith_double_operand" "rHI"))
3887                      (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_ADDV)))
3888    (set (match_operand:DI 0 "register_operand" "=&r")
3889         (plus:DI (match_dup 1) (match_dup 2)))]
3890   "TARGET_ARCH32"
3891   "#"
3892   "&& reload_completed"
3893   [(parallel [(set (reg:CCC CC_REG)
3894                    (compare:CCC (plus:SI (match_dup 4) (match_dup 5))
3895                                 (match_dup 4)))
3896               (set (match_dup 3)
3897                    (plus:SI (match_dup 4) (match_dup 5)))])
3898    (parallel [(set (reg:CCV CC_REG)
3899                    (compare:CCV (plus:SI (plus:SI (match_dup 7) (match_dup 8))
3900                                          (ltu:SI (reg:CCC CC_REG)
3901                                                  (const_int 0)))
3902                                 (unspec:SI [(plus:SI (match_dup 7) (match_dup 8))
3903                                             (ltu:SI (reg:CCC CC_REG)
3904                                                      (const_int 0))]
3905                                            UNSPEC_ADDV)))
3906               (set (match_dup 6)
3907                    (plus:SI (plus:SI (match_dup 7) (match_dup 8))
3908                             (ltu:SI (reg:CCC CC_REG) (const_int 0))))])]
3910   operands[3] = gen_lowpart (SImode, operands[0]);
3911   operands[4] = gen_lowpart (SImode, operands[1]);
3912   operands[5] = gen_lowpart (SImode, operands[2]);
3913   operands[6] = gen_highpart (SImode, operands[0]);
3914   operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
3915   operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3917   [(set_attr "length" "2")])
3919 (define_insn_and_split "*addx_extend_sp32"
3920   [(set (match_operand:DI 0 "register_operand" "=r")
3921         (zero_extend:DI (plus:SI (plus:SI
3922                                    (match_operand:SI 1 "register_operand" "%r")
3923                                    (match_operand:SI 2 "arith_operand" "rI"))
3924                                  (ltu:SI (reg:CCC CC_REG) (const_int 0)))))]
3925   "TARGET_ARCH32"
3926   "#"
3927   "&& reload_completed"
3928   [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
3929                                (ltu:SI (reg:CCC CC_REG) (const_int 0))))
3930    (set (match_dup 4) (const_int 0))]
3931   "operands[3] = gen_lowpart (SImode, operands[0]);
3932    operands[4] = gen_highpart (SImode, operands[0]);"
3933   [(set_attr "length" "2")])
3935 (define_insn_and_split "*adddi3_extend_sp32"
3936   [(set (match_operand:DI 0 "register_operand" "=&r")
3937         (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
3938                  (match_operand:DI 2 "register_operand" "r")))
3939    (clobber (reg:CC CC_REG))]
3940   "TARGET_ARCH32"
3941   "#"
3942   "&& reload_completed"
3943   [(parallel [(set (reg:CCC CC_REG)
3944                    (compare:CCC (plus:SI (match_dup 3) (match_dup 1))
3945                                 (match_dup 3)))
3946               (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
3947    (set (match_dup 6)
3948         (plus:SI (plus:SI (match_dup 4) (const_int 0))
3949                  (ltu:SI (reg:CCC CC_REG) (const_int 0))))]
3950   "operands[3] = gen_lowpart (SImode, operands[2]);
3951    operands[4] = gen_highpart (SImode, operands[2]);
3952    operands[5] = gen_lowpart (SImode, operands[0]);
3953    operands[6] = gen_highpart (SImode, operands[0]);"
3954   [(set_attr "length" "2")])
3956 (define_insn "*adddi3_sp64"
3957   [(set (match_operand:DI 0 "register_operand" "=r,r")
3958         (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
3959                  (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3960   "TARGET_ARCH64"
3961   "@
3962    add\t%1, %2, %0
3963    sub\t%1, -%2, %0")
3965 (define_insn "addsi3"
3966   [(set (match_operand:SI 0 "register_operand" "=r,r")
3967         (plus:SI (match_operand:SI 1 "register_operand" "%r,r")
3968                  (match_operand:SI 2 "arith_add_operand" "rI,O")))]
3969   ""
3970   "@
3971    add\t%1, %2, %0
3972    sub\t%1, -%2, %0"
3973   [(set_attr "type" "*,*")
3974    (set_attr "fptype" "*,*")])
3976 (define_expand "uaddvsi4"
3977   [(parallel [(set (reg:CCC CC_REG)
3978                    (compare:CCC (plus:SI (match_operand:SI 1 "register_operand")
3979                                          (match_operand:SI 2 "arith_operand"))
3980                                 (match_dup 1)))
3981               (set (match_operand:SI 0 "register_operand")
3982                    (plus:SI (match_dup 1) (match_dup 2)))])
3983    (set (pc) (if_then_else (ltu (reg:CCC CC_REG) (const_int 0))
3984                            (label_ref (match_operand 3))
3985                            (pc)))]
3986  "")
3988 (define_expand "addvsi4"
3989   [(parallel [(set (reg:CCV CC_REG)
3990                    (compare:CCV (plus:SI (match_operand:SI 1 "register_operand")
3991                                          (match_operand:SI 2 "arith_operand"))
3992                                 (unspec:SI [(match_dup 1) (match_dup 2)]
3993                                            UNSPEC_ADDV)))
3994               (set (match_operand:SI 0 "register_operand")
3995                    (plus:SI (match_dup 1) (match_dup 2)))])
3996    (set (pc) (if_then_else (ne (reg:CCV CC_REG) (const_int 0))
3997                            (label_ref (match_operand 3))
3998                            (pc)))]
3999  "")
4001 (define_insn "*cmp_ccnz_plus"
4002   [(set (reg:CCNZ CC_REG)
4003         (compare:CCNZ (plus:SI (match_operand:SI 0 "register_operand" "%r")
4004                                (match_operand:SI 1 "arith_operand" "rI"))
4005                       (const_int 0)))]
4006   ""
4007   "addcc\t%0, %1, %%g0"
4008   [(set_attr "type" "compare")])
4010 (define_insn "*cmp_ccxnz_plus"
4011   [(set (reg:CCXNZ CC_REG)
4012         (compare:CCXNZ (plus:DI (match_operand:DI 0 "register_operand" "%r")
4013                                 (match_operand:DI 1 "arith_operand" "rI"))
4014                        (const_int 0)))]
4015   "TARGET_ARCH64"
4016   "addcc\t%0, %1, %%g0"
4017   [(set_attr "type" "compare")])
4019 (define_insn "*cmp_ccnz_plus_set"
4020   [(set (reg:CCNZ CC_REG)
4021         (compare:CCNZ (plus:SI (match_operand:SI 1 "register_operand" "%r")
4022                                (match_operand:SI 2 "arith_operand" "rI"))
4023                       (const_int 0)))
4024    (set (match_operand:SI 0 "register_operand" "=r")
4025         (plus:SI (match_dup 1) (match_dup 2)))]
4026   ""
4027   "addcc\t%1, %2, %0"
4028   [(set_attr "type" "compare")])
4030 (define_insn "*cmp_ccxnz_plus_set"
4031   [(set (reg:CCXNZ CC_REG)
4032         (compare:CCXNZ (plus:DI (match_operand:DI 1 "register_operand" "%r")
4033                                 (match_operand:DI 2 "arith_operand" "rI"))
4034                        (const_int 0)))
4035    (set (match_operand:DI 0 "register_operand" "=r")
4036         (plus:DI (match_dup 1) (match_dup 2)))]
4037   "TARGET_ARCH64"
4038   "addcc\t%1, %2, %0"
4039   [(set_attr "type" "compare")])
4041 (define_insn "*cmp_ccc_plus"
4042   [(set (reg:CCC CC_REG)
4043         (compare:CCC (plus:SI (match_operand:SI 0 "register_operand" "%r")
4044                               (match_operand:SI 1 "arith_operand" "rI"))
4045                      (match_dup 0)))]
4046   ""
4047   "addcc\t%0, %1, %%g0"
4048   [(set_attr "type" "compare")])
4050 (define_insn "*cmp_ccxc_plus"
4051   [(set (reg:CCXC CC_REG)
4052         (compare:CCXC (plus:DI (match_operand:DI 0 "register_operand" "%r")
4053                                (match_operand:DI 1 "arith_operand" "rI"))
4054                       (match_dup 0)))]
4055   "TARGET_ARCH64"
4056   "addcc\t%0, %1, %%g0"
4057   [(set_attr "type" "compare")])
4059 (define_insn "*cmp_ccc_plus_set"
4060   [(set (reg:CCC CC_REG)
4061         (compare:CCC (plus:SI (match_operand:SI 1 "register_operand" "%r")
4062                               (match_operand:SI 2 "arith_operand" "rI"))
4063                      (match_dup 1)))
4064    (set (match_operand:SI 0 "register_operand" "=r")
4065         (plus:SI (match_dup 1) (match_dup 2)))]
4066   ""
4067   "addcc\t%1, %2, %0"
4068   [(set_attr "type" "compare")])
4070 (define_insn "*cmp_ccxc_plus_set"
4071   [(set (reg:CCXC CC_REG)
4072         (compare:CCXC (plus:DI (match_operand:DI 1 "register_operand" "%r")
4073                                (match_operand:DI 2 "arith_operand" "rI"))
4074                       (match_dup 1)))
4075    (set (match_operand:DI 0 "register_operand" "=r")
4076         (plus:DI (match_dup 1) (match_dup 2)))]
4077   "TARGET_ARCH64"
4078   "addcc\t%1, %2, %0"
4079   [(set_attr "type" "compare")])
4081 (define_insn "*cmp_ccc_plus_sltu_set"
4082   [(set (reg:CCC CC_REG)
4083         (compare:CCC (zero_extend:DI
4084                        (plus:SI
4085                          (plus:SI (match_operand:SI 1 "register_operand" "%r")
4086                                   (match_operand:SI 2 "arith_operand" "rI"))
4087                        (ltu:SI (reg:CCC CC_REG) (const_int 0))))
4088                      (plus:DI (plus:DI (zero_extend:DI (match_dup 1))
4089                                        (zero_extend:DI (match_dup 2)))
4090                               (ltu:DI (reg:CCC CC_REG) (const_int 0)))))
4091    (set (match_operand:SI 0 "register_operand" "=r")
4092         (plus:SI (plus:SI (match_dup 1) (match_dup 2))
4093                  (ltu:SI (reg:CCC CC_REG) (const_int 0))))]
4094   ""
4095   "addxcc\t%1, %2, %0"
4096   [(set_attr "type" "compare")])
4098 (define_insn "*cmp_ccv_plus"
4099   [(set (reg:CCV CC_REG)
4100         (compare:CCV (plus:SI (match_operand:SI 0 "register_operand" "%r")
4101                               (match_operand:SI 1 "arith_operand" "rI"))
4102                      (unspec:SI [(match_dup 0) (match_dup 1)] UNSPEC_ADDV)))]
4103   ""
4104   "addcc\t%0, %1, %%g0"
4105   [(set_attr "type" "compare")])
4107 (define_insn "*cmp_ccxv_plus"
4108   [(set (reg:CCXV CC_REG)
4109         (compare:CCXV (plus:DI (match_operand:DI 0 "register_operand" "%r")
4110                                (match_operand:DI 1 "arith_operand" "rI"))
4111                       (unspec:DI [(match_dup 0) (match_dup 1)] UNSPEC_ADDV)))]
4112   "TARGET_ARCH64"
4113   "addcc\t%0, %1, %%g0"
4114   [(set_attr "type" "compare")])
4116 (define_insn "*cmp_ccv_plus_set"
4117   [(set (reg:CCV CC_REG)
4118         (compare:CCV (plus:SI (match_operand:SI 1 "register_operand" "%r")
4119                               (match_operand:SI 2 "arith_operand" "rI"))
4120                      (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_ADDV)))
4121    (set (match_operand:SI 0 "register_operand" "=r")
4122         (plus:SI (match_dup 1) (match_dup 2)))]
4123   ""
4124   "addcc\t%1, %2, %0"
4125   [(set_attr "type" "compare")])
4127 (define_insn "*cmp_ccxv_plus_set"
4128   [(set (reg:CCXV CC_REG)
4129         (compare:CCXV (plus:DI (match_operand:DI 1 "register_operand" "%r")
4130                                (match_operand:DI 2 "arith_operand" "rI"))
4131                       (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_ADDV)))
4132    (set (match_operand:DI 0 "register_operand" "=r")
4133         (plus:DI (match_dup 1) (match_dup 2)))]
4134   "TARGET_ARCH64"
4135   "addcc\t%1, %2, %0"
4136   [(set_attr "type" "compare")])
4138 (define_insn "*cmp_ccv_plus_sltu_set"
4139   [(set (reg:CCV CC_REG)
4140         (compare:CCV (plus:SI (plus:SI (match_operand:SI 1 "register_operand" "%r")
4141                                        (match_operand:SI 2 "arith_operand" "rI"))
4142                               (ltu:SI (reg:CCC CC_REG) (const_int 0)))
4143                      (unspec:SI [(plus:SI (match_dup 1) (match_dup 2))
4144                                  (ltu:SI (reg:CCC CC_REG) (const_int 0))]
4145                                 UNSPEC_ADDV)))
4146    (set (match_operand:SI 0 "register_operand" "=r")
4147         (plus:SI (plus:SI (match_dup 1) (match_dup 2))
4148                  (ltu:SI (reg:CCC CC_REG) (const_int 0))))]
4149   ""
4150   "addxcc\t%1, %2, %0"
4151   [(set_attr "type" "compare")])
4154 (define_expand "subdi3"
4155   [(set (match_operand:DI 0 "register_operand" "")
4156         (minus:DI (match_operand:DI 1 "register_operand" "")
4157                   (match_operand:DI 2 "arith_double_add_operand" "")))]
4158   ""
4160   if (TARGET_ARCH32)
4161     {
4162       emit_insn (gen_subdi3_sp32 (operands[0], operands[1], operands[2]));
4163       DONE;
4164     }
4167 (define_expand "usubvdi4"
4168   [(parallel [(set (reg:CCX CC_REG)
4169                    (compare:CCX (match_operand:DI 1 "register_or_zero_operand")
4170                                 (match_operand:DI 2 "arith_add_operand")))
4171               (set (match_operand:DI 0 "register_operand")
4172                    (minus:DI (match_dup 1) (match_dup 2)))])
4173    (set (pc) (if_then_else (ltu (reg:CCX CC_REG) (const_int 0))
4174                            (label_ref (match_operand 3))
4175                            (pc)))]
4176  ""
4178   if (operands[1] == const0_rtx)
4179     {
4180       emit_insn (gen_unegvdi3 (operands[0], operands[2], operands[3]));
4181       DONE;
4182     }
4184   if (TARGET_ARCH32)
4185     {
4186       emit_insn (gen_usubvdi4_sp32 (operands[0], operands[1], operands[2]));
4187       rtx x = gen_rtx_LTU (VOIDmode, gen_rtx_REG (CCCmode, SPARC_ICC_REG),
4188                                      const0_rtx);
4189       emit_jump_insn (gen_cbranchcc4 (x, XEXP (x, 0), XEXP (x, 1), operands[3]));
4190       DONE;
4191     }
4194 (define_expand "subvdi4"
4195   [(parallel [(set (reg:CCXV CC_REG)
4196                    (compare:CCXV (minus:DI (match_operand:DI 1 "register_operand")
4197                                            (match_operand:DI 2 "arith_add_operand"))
4198                                  (unspec:DI [(match_dup 1) (match_dup 2)]
4199                                             UNSPEC_SUBV)))
4200               (set (match_operand:DI 0 "register_operand")
4201                    (minus:DI (match_dup 1) (match_dup 2)))])
4202    (set (pc) (if_then_else (ne (reg:CCXV CC_REG) (const_int 0))
4203                            (label_ref (match_operand 3))
4204                            (pc)))]
4205  ""
4207   if (TARGET_ARCH32)
4208     {
4209       emit_insn (gen_subvdi4_sp32 (operands[0], operands[1], operands[2]));
4210       rtx x = gen_rtx_NE (VOIDmode, gen_rtx_REG (CCVmode, SPARC_ICC_REG),
4211                                     const0_rtx);
4212       emit_jump_insn (gen_cbranchcc4 (x, XEXP (x, 0), XEXP (x, 1), operands[3]));
4213       DONE;
4214     }
4217 (define_insn_and_split "subdi3_sp32"
4218   [(set (match_operand:DI 0 "register_operand" "=&r")
4219         (minus:DI (match_operand:DI 1 "register_operand" "r")
4220                   (match_operand:DI 2 "arith_double_operand" "rHI")))
4221    (clobber (reg:CC CC_REG))]
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    (set (match_dup 6)
4230         (minus:SI (minus:SI (match_dup 7) (match_dup 8))
4231                   (ltu:SI (reg:CC CC_REG) (const_int 0))))]
4233   operands[3] = gen_lowpart (SImode, operands[0]);
4234   operands[4] = gen_lowpart (SImode, operands[1]);
4235   operands[5] = gen_lowpart (SImode, operands[2]);
4236   operands[6] = gen_highpart (SImode, operands[0]);
4237   operands[7] = gen_highpart (SImode, operands[1]);
4238   operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4240   [(set_attr "length" "2")])
4242 (define_insn_and_split "usubvdi4_sp32"
4243   [(set (reg:CCC CC_REG)
4244         (compare:CCC (match_operand:DI 1 "register_operand" "r")
4245                      (match_operand:DI 2 "arith_double_operand" "rHI")))
4246    (set (match_operand:DI 0 "register_operand" "=&r")
4247         (minus:DI (match_dup 1) (match_dup 2)))]
4248   "TARGET_ARCH32"
4249   "#"
4250   "&& reload_completed"
4251   [(parallel [(set (reg:CC CC_REG)
4252                    (compare:CC (match_dup 4) (match_dup 5)))
4253               (set (match_dup 3)
4254                    (minus:SI (match_dup 4) (match_dup 5)))])
4255    (parallel [(set (reg:CCC CC_REG)
4256                    (compare:CCC (zero_extend:DI
4257                                   (minus:SI (minus:SI (match_dup 7)
4258                                                       (ltu:SI (reg:CC CC_REG)
4259                                                               (const_int 0)))
4260                                             (match_dup 8)))
4261                                 (minus:DI
4262                                   (minus:DI (zero_extend:DI (match_dup 7))
4263                                             (ltu:DI (reg:CC CC_REG)
4264                                                     (const_int 0)))
4265                                   (zero_extend:DI (match_dup 8)))))
4266               (set (match_dup 6)
4267                    (minus:SI (minus:SI (match_dup 7)
4268                                        (ltu:SI (reg:CC CC_REG)
4269                                                (const_int 0)))
4270                              (match_dup 8)))])]
4272   operands[3] = gen_lowpart (SImode, operands[0]);
4273   operands[4] = gen_lowpart (SImode, operands[1]);
4274   operands[5] = gen_lowpart (SImode, operands[2]);
4275   operands[6] = gen_highpart (SImode, operands[0]);
4276   operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
4277   operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4279   [(set_attr "length" "2")])
4281 (define_insn_and_split "subvdi4_sp32"
4282   [(set (reg:CCV CC_REG)
4283         (compare:CCV (minus:DI (match_operand:DI 1 "register_operand" "%r")
4284                                (match_operand:DI 2 "arith_double_operand" "rHI"))
4285                      (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_SUBV)))
4286    (set (match_operand:DI 0 "register_operand" "=&r")
4287         (minus:DI (match_dup 1) (match_dup 2)))]
4288   "TARGET_ARCH32"
4289   "#"
4290   "&& reload_completed"
4291   [(parallel [(set (reg:CC CC_REG)
4292                    (compare:CC (match_dup 4) (match_dup 5)))
4293               (set (match_dup 3)
4294                    (minus:SI (match_dup 4) (match_dup 5)))])
4295    (parallel [(set (reg:CCV CC_REG)
4296                    (compare:CCV (minus:SI (minus:SI (match_dup 7) (match_dup 8))
4297                                           (ltu:SI (reg:CC CC_REG)
4298                                                   (const_int 0)))
4299                                 (unspec:SI [(minus:SI (match_dup 7) (match_dup 8))
4300                                             (ltu:SI (reg:CC CC_REG)
4301                                                     (const_int 0))]
4302                                            UNSPEC_SUBV)))
4303               (set (match_dup 6)
4304                    (minus:SI (minus:SI (match_dup 7) (match_dup 8))
4305                              (ltu:SI (reg:CC CC_REG) (const_int 0))))])]
4307   operands[3] = gen_lowpart (SImode, operands[0]);
4308   operands[4] = gen_lowpart (SImode, operands[1]);
4309   operands[5] = gen_lowpart (SImode, operands[2]);
4310   operands[6] = gen_highpart (SImode, operands[0]);
4311   operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
4312   operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4314   [(set_attr "length" "2")])
4316 (define_insn_and_split "*subx_extend_sp32"
4317   [(set (match_operand:DI 0 "register_operand" "=r")
4318         (zero_extend:DI (minus:SI (minus:SI
4319                                     (match_operand:SI 1 "register_or_zero_operand" "rJ")
4320                                     (match_operand:SI 2 "arith_operand" "rI"))
4321                                   (ltu:SI (reg:CCC CC_REG) (const_int 0)))))]
4322   "TARGET_ARCH32"
4323   "#"
4324   "&& reload_completed"
4325   [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
4326                                 (ltu:SI (reg:CCC CC_REG) (const_int 0))))
4327    (set (match_dup 4) (const_int 0))]
4328   "operands[3] = gen_lowpart (SImode, operands[0]);
4329    operands[4] = gen_highpart (SImode, operands[0]);"
4330   [(set_attr "length" "2")])
4332 (define_insn_and_split "*subdi3_extend_sp32"
4333   [(set (match_operand:DI 0 "register_operand" "=&r")
4334       (minus:DI (match_operand:DI 1 "register_operand" "r")
4335                 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
4336    (clobber (reg:CC CC_REG))]
4337   "TARGET_ARCH32"
4338   "#"
4339   "&& reload_completed"
4340   [(parallel [(set (reg:CC CC_REG)
4341                    (compare:CC (match_dup 3) (match_dup 2)))
4342               (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
4343    (set (match_dup 6)
4344         (minus:SI (minus:SI (match_dup 4) (const_int 0))
4345                   (ltu:SI (reg:CC CC_REG) (const_int 0))))]
4346   "operands[3] = gen_lowpart (SImode, operands[1]);
4347    operands[4] = gen_highpart (SImode, operands[1]);
4348    operands[5] = gen_lowpart (SImode, operands[0]);
4349    operands[6] = gen_highpart (SImode, operands[0]);"
4350   [(set_attr "length" "2")])
4352 (define_insn "*subdi3_sp64"
4353   [(set (match_operand:DI 0 "register_operand" "=r,r")
4354         (minus:DI (match_operand:DI 1 "register_operand" "r,r")
4355                   (match_operand:DI 2 "arith_add_operand" "rI,O")))]
4356   "TARGET_ARCH64"
4357   "@
4358    sub\t%1, %2, %0
4359    add\t%1, -%2, %0")
4361 (define_insn "subsi3"
4362   [(set (match_operand:SI 0 "register_operand" "=r,r")
4363         (minus:SI (match_operand:SI 1 "register_operand" "r,r")
4364                   (match_operand:SI 2 "arith_add_operand" "rI,O")))]
4365   ""
4366   "@
4367    sub\t%1, %2, %0
4368    add\t%1, -%2, %0"
4369   [(set_attr "type" "*,*")
4370    (set_attr "fptype" "*,*")])
4372 (define_expand "usubvsi4"
4373   [(parallel [(set (reg:CC CC_REG)
4374                    (compare:CC (match_operand:SI 1 "register_or_zero_operand")
4375                                (match_operand:SI 2 "arith_operand")))
4376               (set (match_operand:SI 0 "register_operand")
4377                    (minus:SI (match_dup 1) (match_dup 2)))])
4378    (set (pc) (if_then_else (ltu (reg:CC CC_REG) (const_int 0))
4379                            (label_ref (match_operand 3))
4380                            (pc)))]
4381  ""
4383   if (operands[1] == const0_rtx)
4384     {
4385       emit_insn (gen_unegvsi3 (operands[0], operands[2], operands[3]));
4386       DONE;
4387     }
4390 (define_expand "subvsi4"
4391   [(parallel [(set (reg:CCV CC_REG)
4392                    (compare:CCV (minus:SI (match_operand:SI 1 "register_operand")
4393                                           (match_operand:SI 2 "arith_operand"))
4394                                 (unspec:SI [(match_dup 1) (match_dup 2)]
4395                                            UNSPEC_SUBV)))
4396               (set (match_operand:SI 0 "register_operand")
4397                    (minus:SI (match_dup 1) (match_dup 2)))])
4398    (set (pc) (if_then_else (ne (reg:CCV CC_REG) (const_int 0))
4399                            (label_ref (match_operand 3))
4400                            (pc)))]
4401  "")
4403 (define_insn "*cmp_ccnz_minus"
4404   [(set (reg:CCNZ CC_REG)
4405         (compare:CCNZ (minus:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
4406                                 (match_operand:SI 1 "arith_operand" "rI"))
4407                       (const_int 0)))]
4408   ""
4409   "subcc\t%r0, %1, %%g0"
4410   [(set_attr "type" "compare")])
4412 (define_insn "*cmp_ccxnz_minus"
4413   [(set (reg:CCXNZ CC_REG)
4414         (compare:CCXNZ (minus:DI (match_operand:DI 0 "register_or_zero_operand" "rJ")
4415                                  (match_operand:DI 1 "arith_operand" "rI"))
4416                        (const_int 0)))]
4417   "TARGET_ARCH64"
4418   "subcc\t%r0, %1, %%g0"
4419   [(set_attr "type" "compare")])
4421 (define_insn "*cmp_ccnz_minus_set"
4422   [(set (reg:CCNZ CC_REG)
4423         (compare:CCNZ (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4424                                 (match_operand:SI 2 "arith_operand" "rI"))
4425                       (const_int 0)))
4426    (set (match_operand:SI 0 "register_operand" "=r")
4427         (minus:SI (match_dup 1) (match_dup 2)))]
4428   ""
4429   "subcc\t%r1, %2, %0"
4430   [(set_attr "type" "compare")])
4432 (define_insn "*cmp_ccxnz_minus_set"
4433   [(set (reg:CCXNZ CC_REG)
4434         (compare:CCXNZ (minus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
4435                                  (match_operand:DI 2 "arith_operand" "rI"))
4436                        (const_int 0)))
4437    (set (match_operand:DI 0 "register_operand" "=r")
4438         (minus:DI (match_dup 1) (match_dup 2)))]
4439   "TARGET_ARCH64"
4440   "subcc\t%r1, %2, %0"
4441   [(set_attr "type" "compare")])
4443 (define_insn "*cmpsi_set"
4444   [(set (reg:CC CC_REG)
4445         (compare:CC (match_operand:SI 1 "register_or_zero_operand" "rJ")
4446                     (match_operand:SI 2 "arith_operand" "rI")))
4447    (set (match_operand:SI 0 "register_operand" "=r")
4448         (minus:SI (match_dup 1) (match_dup 2)))]
4449   ""
4450   "subcc\t%r1, %2, %0"
4451   [(set_attr "type" "compare")])
4453 (define_insn "*cmpdi_set"
4454   [(set (reg:CCX CC_REG)
4455         (compare:CCX (match_operand:DI 1 "register_or_zero_operand" "rJ")
4456                      (match_operand:DI 2 "arith_operand" "rI")))
4457    (set (match_operand:DI 0 "register_operand" "=r")
4458         (minus:DI (match_dup 1) (match_dup 2)))]
4459   "TARGET_ARCH64"
4460   "subcc\t%r1, %2, %0"
4461   [(set_attr "type" "compare")])
4463 (define_insn "*cmp_ccc_minus_sltu_set"
4464   [(set (reg:CCC CC_REG)
4465         (compare:CCC (zero_extend:DI
4466                        (minus:SI
4467                          (minus:SI
4468                            (match_operand:SI 1 "register_or_zero_operand" "rJ")
4469                            (ltu:SI (reg:CC CC_REG) (const_int 0)))
4470                          (match_operand:SI 2 "arith_operand" "rI")))
4471                      (minus:DI
4472                        (minus:DI
4473                          (zero_extend:DI (match_dup 1))
4474                          (ltu:DI (reg:CC CC_REG) (const_int 0)))
4475                        (zero_extend:DI (match_dup 2)))))
4476    (set (match_operand:SI 0 "register_operand" "=r")
4477         (minus:SI (minus:SI (match_dup 1)
4478                             (ltu:SI (reg:CC CC_REG) (const_int 0)))
4479                   (match_dup 2)))]
4480   ""
4481   "subxcc\t%r1, %2, %0"
4482   [(set_attr "type" "compare")])
4484 (define_insn "*cmp_ccv_minus"
4485   [(set (reg:CCV CC_REG)
4486         (compare:CCV (minus:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
4487                                (match_operand:SI 1 "arith_operand" "rI"))
4488                      (unspec:SI [(match_dup 0) (match_dup 1)] UNSPEC_SUBV)))]
4489   ""
4490   "subcc\t%r0, %1, %%g0"
4491   [(set_attr "type" "compare")])
4493 (define_insn "*cmp_ccxv_minus"
4494   [(set (reg:CCXV CC_REG)
4495         (compare:CCXV (minus:DI (match_operand:DI 0 "register_or_zero_operand" "rJ")
4496                                 (match_operand:DI 1 "arith_operand" "rI"))
4497                       (unspec:DI [(match_dup 0) (match_dup 1)] UNSPEC_SUBV)))]
4498   "TARGET_ARCH64"
4499   "subcc\t%r0, %1, %%g0"
4500   [(set_attr "type" "compare")])
4502 (define_insn "*cmp_ccv_minus_set"
4503   [(set (reg:CCV CC_REG)
4504         (compare:CCV (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4505                                (match_operand:SI 2 "arith_operand" "rI"))
4506                      (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_SUBV)))
4507    (set (match_operand:SI 0 "register_operand" "=r")
4508         (minus:SI (match_dup 1) (match_dup 2)))]
4509   ""
4510   "subcc\t%r1, %2, %0"
4511   [(set_attr "type" "compare")])
4513 (define_insn "*cmp_ccxv_minus_set"
4514   [(set (reg:CCXV CC_REG)
4515         (compare:CCXV (minus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
4516                                 (match_operand:DI 2 "arith_operand" "rI"))
4517                       (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_SUBV)))
4518    (set (match_operand:DI 0 "register_operand" "=r")
4519         (minus:DI (match_dup 1) (match_dup 2)))]
4520   "TARGET_ARCH64"
4521   "subcc\t%r1, %2, %0"
4522   [(set_attr "type" "compare")])
4524 (define_insn "*cmp_ccv_minus_sltu_set"
4525   [(set (reg:CCV CC_REG)
4526         (compare:CCV
4527           (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4528                               (match_operand:SI 2 "arith_operand" "rI"))
4529                     (ltu:SI (reg:CC CC_REG) (const_int 0)))
4530           (unspec:SI [(minus:SI (match_dup 1) (match_dup 2))
4531                       (ltu:SI (reg:CC CC_REG) (const_int 0))]
4532                      UNSPEC_SUBV)))
4533    (set (match_operand:SI 0 "register_operand" "=r")
4534         (minus:SI (minus:SI (match_dup 1) (match_dup 2))
4535                   (ltu:SI (reg:CC CC_REG) (const_int 0))))]
4536   ""
4537   "subxcc\t%1, %2, %0"
4538   [(set_attr "type" "compare")])
4541 ;; Integer multiply/divide instructions.
4543 ;; The 32-bit multiply/divide instructions are deprecated on v9, but at
4544 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
4546 (define_expand "mulsi3"
4547   [(set (match_operand:SI 0 "register_operand" "")
4548         (mult:SI (match_operand:SI 1 "arith_operand" "")
4549                  (match_operand:SI 2 "arith_operand" "")))]
4550   "TARGET_HARD_MUL || TARGET_ARCH64"
4551   "")
4553 (define_insn "*mulsi3_sp32"
4554   [(set (match_operand:SI 0 "register_operand" "=r")
4555         (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4556                  (match_operand:SI 2 "arith_operand" "rI")))]
4557   "TARGET_HARD_MUL"
4558   "smul\t%1, %2, %0"
4559   [(set_attr "type" "imul")])
4561 (define_insn "*mulsi3_sp64"
4562   [(set (match_operand:SI 0 "register_operand" "=r")
4563         (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4564                  (match_operand:SI 2 "arith_operand" "rI")))]
4565   "TARGET_ARCH64"
4566   "mulx\t%1, %2, %0"
4567   [(set_attr "type" "imul")])
4569 (define_expand "muldi3"
4570   [(set (match_operand:DI 0 "register_operand" "")
4571         (mult:DI (match_operand:DI 1 "arith_operand" "")
4572                  (match_operand:DI 2 "arith_operand" "")))]
4573   "TARGET_ARCH64 || TARGET_V8PLUS"
4575   if (TARGET_V8PLUS)
4576     {
4577       emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
4578       DONE;
4579     }
4582 (define_insn "*muldi3_sp64"
4583   [(set (match_operand:DI 0 "register_operand" "=r")
4584         (mult:DI (match_operand:DI 1 "arith_operand" "%r")
4585                  (match_operand:DI 2 "arith_operand" "rI")))]
4586   "TARGET_ARCH64"
4587   "mulx\t%1, %2, %0"
4588   [(set_attr "type" "imul")])
4590 ;; V8plus wide multiply.
4591 (define_insn "muldi3_v8plus"
4592   [(set (match_operand:DI 0 "register_operand" "=r,h")
4593         (mult:DI (match_operand:DI 1 "arith_operand" "%r,0")
4594                  (match_operand:DI 2 "arith_operand" "rI,rI")))
4595    (clobber (match_scratch:SI 3 "=&h,X"))
4596    (clobber (match_scratch:SI 4 "=&h,X"))]
4597   "TARGET_V8PLUS"
4599   return output_v8plus_mult (insn, operands, \"mulx\");
4601   [(set_attr "type" "multi")
4602    (set_attr "length" "9,8")])
4604 (define_insn "*cmp_mul_set"
4605   [(set (reg:CC CC_REG)
4606         (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4607                     (match_operand:SI 2 "arith_operand" "rI"))
4608                     (const_int 0)))
4609    (set (match_operand:SI 0 "register_operand" "=r")
4610         (mult:SI (match_dup 1) (match_dup 2)))]
4611   "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
4612   "smulcc\t%1, %2, %0"
4613   [(set_attr "type" "imul")])
4615 (define_expand "mulsidi3"
4616   [(set (match_operand:DI 0 "register_operand" "")
4617         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4618                  (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
4619   "TARGET_HARD_MUL"
4621   if (CONSTANT_P (operands[2]))
4622     {
4623       if (TARGET_V8PLUS)
4624         emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
4625                                               operands[2]));
4626       else if (TARGET_ARCH32)
4627         emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
4628                                             operands[2]));
4629       else 
4630         emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
4631                                             operands[2]));
4632       DONE;
4633     }
4634   if (TARGET_V8PLUS)
4635     {
4636       emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
4637       DONE;
4638     }
4641 ;; V9 puts the 64-bit product in a 64-bit register.  Only out or global
4642 ;; registers can hold 64-bit values in the V8plus environment.
4643 (define_insn "mulsidi3_v8plus"
4644   [(set (match_operand:DI 0 "register_operand" "=h,r")
4645         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4646                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4647    (clobber (match_scratch:SI 3 "=X,&h"))]
4648   "TARGET_V8PLUS"
4649   "@
4650    smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4651    smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4652   [(set_attr "type" "multi")
4653    (set_attr "length" "2,3")])
4655 (define_insn "const_mulsidi3_v8plus"
4656   [(set (match_operand:DI 0 "register_operand" "=h,r")
4657         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4658                  (match_operand:DI 2 "small_int_operand" "I,I")))
4659    (clobber (match_scratch:SI 3 "=X,&h"))]
4660   "TARGET_V8PLUS"
4661   "@
4662    smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4663    smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4664   [(set_attr "type" "multi")
4665    (set_attr "length" "2,3")])
4667 (define_insn "*mulsidi3_sp32"
4668   [(set (match_operand:DI 0 "register_operand" "=r")
4669         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4670                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4671   "TARGET_HARD_MUL32"
4673   return TARGET_SPARCLET
4674          ? "smuld\t%1, %2, %L0"
4675          : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4677   [(set (attr "type")
4678         (if_then_else (eq_attr "isa" "sparclet")
4679                       (const_string "imul") (const_string "multi")))
4680    (set (attr "length")
4681         (if_then_else (eq_attr "isa" "sparclet")
4682                       (const_int 1) (const_int 2)))])
4684 (define_insn "*mulsidi3_sp64"
4685   [(set (match_operand:DI 0 "register_operand" "=r")
4686         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4687                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4688   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4689   "smul\t%1, %2, %0"
4690   [(set_attr "type" "imul")])
4692 ;; Extra pattern, because sign_extend of a constant isn't valid.
4694 (define_insn "const_mulsidi3_sp32"
4695   [(set (match_operand:DI 0 "register_operand" "=r")
4696         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4697                  (match_operand:DI 2 "small_int_operand" "I")))]
4698   "TARGET_HARD_MUL32"
4700   return TARGET_SPARCLET
4701          ? "smuld\t%1, %2, %L0"
4702          : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4704   [(set (attr "type")
4705         (if_then_else (eq_attr "isa" "sparclet")
4706                       (const_string "imul") (const_string "multi")))
4707    (set (attr "length")
4708         (if_then_else (eq_attr "isa" "sparclet")
4709                       (const_int 1) (const_int 2)))])
4711 (define_insn "const_mulsidi3_sp64"
4712   [(set (match_operand:DI 0 "register_operand" "=r")
4713         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4714                  (match_operand:DI 2 "small_int_operand" "I")))]
4715   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4716   "smul\t%1, %2, %0"
4717   [(set_attr "type" "imul")])
4719 (define_expand "smulsi3_highpart"
4720   [(set (match_operand:SI 0 "register_operand" "")
4721         (truncate:SI
4722           (lshiftrt:DI
4723             (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4724                      (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
4725             (const_int 32))))]
4726   "TARGET_HARD_MUL && TARGET_ARCH32"
4728   if (CONSTANT_P (operands[2]))
4729     {
4730       if (TARGET_V8PLUS)
4731         {
4732           emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
4733                                                         operands[1],
4734                                                         operands[2],
4735                                                         GEN_INT (32)));
4736           DONE;
4737         }
4738       emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
4739       DONE;
4740     }
4741   if (TARGET_V8PLUS)
4742     {
4743       emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
4744                                               operands[2], GEN_INT (32)));
4745       DONE;
4746     }
4749 (define_insn "smulsi3_highpart_v8plus"
4750   [(set (match_operand:SI 0 "register_operand" "=h,r")
4751         (truncate:SI
4752           (lshiftrt:DI
4753             (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4754                      (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4755             (match_operand:SI 3 "small_int_operand" "I,I"))))
4756    (clobber (match_scratch:SI 4 "=X,&h"))]
4757   "TARGET_V8PLUS"
4758   "@
4759    smul\t%1, %2, %0\;srlx\t%0, %3, %0
4760    smul\t%1, %2, %4\;srlx\t%4, %3, %0"
4761   [(set_attr "type" "multi")
4762    (set_attr "length" "2")])
4764 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
4765 (define_insn ""
4766   [(set (match_operand:SI 0 "register_operand" "=h,r")
4767         (subreg:SI
4768           (lshiftrt:DI
4769             (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4770                      (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4771             (match_operand:SI 3 "small_int_operand" "I,I")) 4))
4772    (clobber (match_scratch:SI 4 "=X,&h"))]
4773   "TARGET_V8PLUS"
4774   "@
4775    smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4776    smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4777   [(set_attr "type" "multi")
4778    (set_attr "length" "2")])
4780 (define_insn "const_smulsi3_highpart_v8plus"
4781   [(set (match_operand:SI 0 "register_operand" "=h,r")
4782         (truncate:SI
4783           (lshiftrt:DI
4784             (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4785                      (match_operand:DI 2 "small_int_operand" "I,I"))
4786           (match_operand:SI 3 "small_int_operand" "I,I"))))
4787    (clobber (match_scratch:SI 4 "=X,&h"))]
4788   "TARGET_V8PLUS"
4789   "@
4790    smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4791    smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4792   [(set_attr "type" "multi")
4793    (set_attr "length" "2")])
4795 (define_insn "*smulsi3_highpart_sp32"
4796   [(set (match_operand:SI 0 "register_operand" "=r")
4797         (truncate:SI
4798           (lshiftrt:DI
4799             (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4800                      (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
4801           (const_int 32))))]
4802   "TARGET_HARD_MUL32"
4803   "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4804   [(set_attr "type" "multi")
4805    (set_attr "length" "2")])
4807 (define_insn "const_smulsi3_highpart"
4808   [(set (match_operand:SI 0 "register_operand" "=r")
4809         (truncate:SI
4810           (lshiftrt:DI
4811             (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4812                      (match_operand:DI 2 "small_int_operand" "i"))
4813             (const_int 32))))]
4814   "TARGET_HARD_MUL32"
4815   "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4816   [(set_attr "type" "multi")
4817    (set_attr "length" "2")])
4819 (define_expand "umulsidi3"
4820   [(set (match_operand:DI 0 "register_operand" "")
4821         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4822                  (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
4823   "TARGET_HARD_MUL"
4825   if (CONSTANT_P (operands[2]))
4826     {
4827       if (TARGET_V8PLUS)
4828         emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
4829                                                operands[2]));
4830       else if (TARGET_ARCH32)
4831         emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
4832                                              operands[2]));
4833       else 
4834         emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
4835                                              operands[2]));
4836       DONE;
4837     }
4838   if (TARGET_V8PLUS)
4839     {
4840       emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
4841       DONE;
4842     }
4845 (define_insn "umulsidi3_v8plus"
4846   [(set (match_operand:DI 0 "register_operand" "=h,r")
4847         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4848                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4849    (clobber (match_scratch:SI 3 "=X,&h"))]
4850   "TARGET_V8PLUS"
4851   "@
4852    umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4853    umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4854   [(set_attr "type" "multi")
4855    (set_attr "length" "2,3")])
4857 (define_insn "*umulsidi3_sp32"
4858   [(set (match_operand:DI 0 "register_operand" "=r")
4859         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4860                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4861   "TARGET_HARD_MUL32"
4863   return TARGET_SPARCLET
4864          ? "umuld\t%1, %2, %L0"
4865          : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
4867   [(set (attr "type")
4868         (if_then_else (eq_attr "isa" "sparclet")
4869                       (const_string "imul") (const_string "multi")))
4870    (set (attr "length")
4871         (if_then_else (eq_attr "isa" "sparclet")
4872                       (const_int 1) (const_int 2)))])
4874 (define_insn "*umulsidi3_sp64"
4875   [(set (match_operand:DI 0 "register_operand" "=r")
4876         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4877                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4878   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4879   "umul\t%1, %2, %0"
4880   [(set_attr "type" "imul")])
4882 ;; Extra pattern, because sign_extend of a constant isn't valid.
4884 (define_insn "const_umulsidi3_sp32"
4885   [(set (match_operand:DI 0 "register_operand" "=r")
4886         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4887                  (match_operand:DI 2 "uns_small_int_operand" "")))]
4888   "TARGET_HARD_MUL32"
4890   return TARGET_SPARCLET
4891          ? "umuld\t%1, %s2, %L0"
4892          : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
4894   [(set (attr "type")
4895         (if_then_else (eq_attr "isa" "sparclet")
4896                       (const_string "imul") (const_string "multi")))
4897    (set (attr "length")
4898         (if_then_else (eq_attr "isa" "sparclet")
4899                       (const_int 1) (const_int 2)))])
4901 (define_insn "const_umulsidi3_sp64"
4902   [(set (match_operand:DI 0 "register_operand" "=r")
4903         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4904                  (match_operand:DI 2 "uns_small_int_operand" "")))]
4905   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4906   "umul\t%1, %s2, %0"
4907   [(set_attr "type" "imul")])
4909 (define_insn "const_umulsidi3_v8plus"
4910   [(set (match_operand:DI 0 "register_operand" "=h,r")
4911         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4912                  (match_operand:DI 2 "uns_small_int_operand" "")))
4913    (clobber (match_scratch:SI 3 "=X,h"))]
4914   "TARGET_V8PLUS"
4915   "@
4916    umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
4917    umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4918   [(set_attr "type" "multi")
4919    (set_attr "length" "2,3")])
4921 (define_expand "umulsi3_highpart"
4922   [(set (match_operand:SI 0 "register_operand" "")
4923         (truncate:SI
4924           (lshiftrt:DI
4925             (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4926                      (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
4927           (const_int 32))))]
4928   "TARGET_HARD_MUL && TARGET_ARCH32"
4930   if (CONSTANT_P (operands[2]))
4931     {
4932       if (TARGET_V8PLUS)
4933         {
4934           emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
4935                                                         operands[1],
4936                                                         operands[2],
4937                                                         GEN_INT (32)));
4938           DONE;
4939         }
4940       emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
4941       DONE;
4942     }
4943   if (TARGET_V8PLUS)
4944     {
4945       emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
4946                                               operands[2], GEN_INT (32)));
4947       DONE;
4948     }
4951 (define_insn "umulsi3_highpart_v8plus"
4952   [(set (match_operand:SI 0 "register_operand" "=h,r")
4953         (truncate:SI
4954           (lshiftrt:DI
4955             (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4956                      (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4957             (match_operand:SI 3 "small_int_operand" "I,I"))))
4958    (clobber (match_scratch:SI 4 "=X,h"))]
4959   "TARGET_V8PLUS"
4960   "@
4961    umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4962    umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4963   [(set_attr "type" "multi")
4964    (set_attr "length" "2")])
4966 (define_insn "const_umulsi3_highpart_v8plus"
4967   [(set (match_operand:SI 0 "register_operand" "=h,r")
4968         (truncate:SI
4969           (lshiftrt:DI
4970             (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4971                      (match_operand:DI 2 "uns_small_int_operand" ""))
4972             (match_operand:SI 3 "small_int_operand" "I,I"))))
4973    (clobber (match_scratch:SI 4 "=X,h"))]
4974   "TARGET_V8PLUS"
4975   "@
4976    umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
4977    umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
4978   [(set_attr "type" "multi")
4979    (set_attr "length" "2")])
4981 (define_insn "*umulsi3_highpart_sp32"
4982   [(set (match_operand:SI 0 "register_operand" "=r")
4983         (truncate:SI
4984           (lshiftrt:DI
4985             (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4986                      (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
4987             (const_int 32))))]
4988   "TARGET_HARD_MUL32"
4989   "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
4990   [(set_attr "type" "multi")
4991    (set_attr "length" "2")])
4993 (define_insn "const_umulsi3_highpart"
4994   [(set (match_operand:SI 0 "register_operand" "=r")
4995         (truncate:SI
4996           (lshiftrt:DI
4997             (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4998                      (match_operand:DI 2 "uns_small_int_operand" ""))
4999             (const_int 32))))]
5000   "TARGET_HARD_MUL32"
5001   "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
5002   [(set_attr "type" "multi")
5003    (set_attr "length" "2")])
5006 (define_expand "umulxhi_vis"
5007   [(set (match_operand:DI 0 "register_operand" "")
5008         (truncate:DI
5009           (lshiftrt:TI
5010             (mult:TI (zero_extend:TI (match_operand:DI 1 "arith_operand" ""))
5011                      (zero_extend:TI (match_operand:DI 2 "arith_operand" "")))
5012           (const_int 64))))]
5013  "TARGET_VIS3"
5015   if (TARGET_ARCH32)
5016     {
5017       emit_insn (gen_umulxhi_v8plus (operands[0], operands[1], operands[2]));
5018       DONE;
5019     }
5022 (define_insn "*umulxhi_sp64"
5023   [(set (match_operand:DI 0 "register_operand" "=r")
5024         (truncate:DI
5025           (lshiftrt:TI
5026             (mult:TI (zero_extend:TI (match_operand:DI 1 "arith_operand" "%r"))
5027                      (zero_extend:TI (match_operand:DI 2 "arith_operand" "rI")))
5028           (const_int 64))))]
5029   "TARGET_VIS3 && TARGET_ARCH64"
5030   "umulxhi\t%1, %2, %0"
5031   [(set_attr "type" "imul")])
5033 (define_insn "umulxhi_v8plus"
5034   [(set (match_operand:DI 0 "register_operand" "=r,h")
5035         (truncate:DI
5036           (lshiftrt:TI
5037             (mult:TI (zero_extend:TI (match_operand:DI 1 "arith_operand" "%r,0"))
5038                      (zero_extend:TI (match_operand:DI 2 "arith_operand" "rI,rI")))
5039           (const_int 64))))
5040    (clobber (match_scratch:SI 3 "=&h,X"))
5041    (clobber (match_scratch:SI 4 "=&h,X"))]
5042   "TARGET_VIS3 && TARGET_ARCH32"
5044   return output_v8plus_mult (insn, operands, \"umulxhi\");
5046   [(set_attr "type" "imul")
5047    (set_attr "length" "9,8")])
5049 (define_expand "xmulx_vis"
5050   [(set (match_operand:DI 0 "register_operand" "")
5051         (truncate:DI
5052           (unspec:TI [(zero_extend:TI (match_operand:DI 1 "arith_operand" ""))
5053                       (zero_extend:TI (match_operand:DI 2 "arith_operand" ""))]
5054                      UNSPEC_XMUL)))]
5055   "TARGET_VIS3"
5057   if (TARGET_ARCH32)
5058     {
5059       emit_insn (gen_xmulx_v8plus (operands[0], operands[1], operands[2]));
5060       DONE;
5061     }
5064 (define_insn "*xmulx_sp64"
5065   [(set (match_operand:DI 0 "register_operand" "=r")
5066         (truncate:DI
5067           (unspec:TI [(zero_extend:TI (match_operand:DI 1 "arith_operand" "%r"))
5068                       (zero_extend:TI (match_operand:DI 2 "arith_operand" "rI"))]
5069                      UNSPEC_XMUL)))]
5070   "TARGET_VIS3 && TARGET_ARCH64"
5071   "xmulx\t%1, %2, %0"
5072   [(set_attr "type" "imul")])
5074 (define_insn "xmulx_v8plus"
5075   [(set (match_operand:DI 0 "register_operand" "=r,h")
5076         (truncate:DI
5077           (unspec:TI [(zero_extend:TI (match_operand:DI 1 "arith_operand" "%r,0"))
5078                       (zero_extend:TI (match_operand:DI 2 "arith_operand" "rI,rI"))]
5079                      UNSPEC_XMUL)))
5080    (clobber (match_scratch:SI 3 "=&h,X"))
5081    (clobber (match_scratch:SI 4 "=&h,X"))]
5082   "TARGET_VIS3 && TARGET_ARCH32"
5084   return output_v8plus_mult (insn, operands, \"xmulx\");
5086   [(set_attr "type" "imul")
5087    (set_attr "length" "9,8")])
5089 (define_expand "xmulxhi_vis"
5090   [(set (match_operand:DI 0 "register_operand" "")
5091         (truncate:DI
5092           (lshiftrt:TI
5093              (unspec:TI [(zero_extend:TI (match_operand:DI 1 "arith_operand" ""))
5094                          (zero_extend:TI (match_operand:DI 2 "arith_operand" ""))]
5095                         UNSPEC_XMUL)
5096           (const_int 64))))]
5097   "TARGET_VIS3"
5099   if (TARGET_ARCH32)
5100     {
5101       emit_insn (gen_xmulxhi_v8plus (operands[0], operands[1], operands[2]));
5102       DONE;
5103     }
5106 (define_insn "*xmulxhi_sp64"
5107   [(set (match_operand:DI 0 "register_operand" "=r")
5108         (truncate:DI
5109           (lshiftrt:TI
5110             (unspec:TI [(zero_extend:TI (match_operand:DI 1 "arith_operand" "%r"))
5111                         (zero_extend:TI (match_operand:DI 2 "arith_operand" "rI"))]
5112                        UNSPEC_XMUL)
5113             (const_int 64))))]
5114   "TARGET_VIS3 && TARGET_ARCH64"
5115   "xmulxhi\t%1, %2, %0"
5116   [(set_attr "type" "imul")])
5118 (define_insn "xmulxhi_v8plus"
5119   [(set (match_operand:DI 0 "register_operand" "=r,h")
5120         (truncate:DI
5121           (lshiftrt:TI
5122             (unspec:TI [(zero_extend:TI (match_operand:DI 1 "arith_operand" "%r,0"))
5123                         (zero_extend:TI (match_operand:DI 2 "arith_operand" "rI,rI"))]
5124                        UNSPEC_XMUL)
5125           (const_int 64))))
5126    (clobber (match_scratch:SI 3 "=&h,X"))
5127    (clobber (match_scratch:SI 4 "=&h,X"))]
5128   "TARGET_VIS3 && TARGET_ARCH32"
5130   return output_v8plus_mult (insn, operands, \"xmulxhi\");
5132   [(set_attr "type" "imul")
5133    (set_attr "length" "9,8")])
5135 (define_expand "divsi3"
5136   [(parallel [(set (match_operand:SI 0 "register_operand" "")
5137                    (div:SI (match_operand:SI 1 "register_operand" "")
5138                            (match_operand:SI 2 "input_operand" "")))
5139               (clobber (match_scratch:SI 3 ""))])]
5140   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5142   if (TARGET_ARCH64)
5143     {
5144       operands[3] = gen_reg_rtx(SImode);
5145       emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
5146       emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
5147                                   operands[3]));
5148       DONE;
5149     }
5152 ;; The V8 architecture specifies that there must be at least 3 instructions
5153 ;; between a write to the Y register and a use of it for correct results.
5154 ;; We try to fill one of them with a simple constant or a memory load.
5156 (define_insn "divsi3_sp32"
5157   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
5158         (div:SI (match_operand:SI 1 "register_operand" "r,r,r")
5159                 (match_operand:SI 2 "input_operand" "rI,K,m")))
5160    (clobber (match_scratch:SI 3 "=&r,&r,&r"))]
5161   "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
5163   output_asm_insn ("sra\t%1, 31, %3", operands);
5164   output_asm_insn ("wr\t%3, 0, %%y", operands);
5166   switch (which_alternative)
5167     {
5168     case 0:
5169       if (TARGET_V9)
5170         return "sdiv\t%1, %2, %0";
5171       else
5172         return "nop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
5173     case 1:
5174       if (TARGET_V9)
5175         return "sethi\t%%hi(%a2), %3\n\tsdiv\t%1, %3, %0";
5176       else
5177         return "sethi\t%%hi(%a2), %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
5178     case 2:
5179       if (TARGET_V9)
5180         return "ld\t%2, %3\n\tsdiv\t%1, %3, %0";
5181       else
5182         return "ld\t%2, %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
5183     default:
5184       gcc_unreachable ();
5185     }
5187   [(set_attr "type" "multi")
5188    (set (attr "length")
5189         (if_then_else (eq_attr "isa" "v9")
5190                       (const_int 4) (const_int 6)))])
5192 (define_insn "divsi3_sp64"
5193   [(set (match_operand:SI 0 "register_operand" "=r")
5194         (div:SI (match_operand:SI 1 "register_operand" "r")
5195                 (match_operand:SI 2 "input_operand" "rI")))
5196    (use (match_operand:SI 3 "register_operand" "r"))]
5197   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5198   "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
5199   [(set_attr "type" "multi")
5200    (set_attr "length" "2")])
5202 (define_insn "divdi3"
5203   [(set (match_operand:DI 0 "register_operand" "=r")
5204         (div:DI (match_operand:DI 1 "register_operand" "r")
5205                 (match_operand:DI 2 "arith_operand" "rI")))]
5206   "TARGET_ARCH64"
5207   "sdivx\t%1, %2, %0"
5208   [(set_attr "type" "idiv")])
5210 (define_insn "*cmp_sdiv_cc_set"
5211   [(set (reg:CC CC_REG)
5212         (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
5213                             (match_operand:SI 2 "arith_operand" "rI"))
5214                     (const_int 0)))
5215    (set (match_operand:SI 0 "register_operand" "=r")
5216         (div:SI (match_dup 1) (match_dup 2)))
5217    (clobber (match_scratch:SI 3 "=&r"))]
5218   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5220   output_asm_insn ("sra\t%1, 31, %3", operands);
5221   output_asm_insn ("wr\t%3, 0, %%y", operands);
5223   if (TARGET_V9)
5224     return "sdivcc\t%1, %2, %0";
5225   else
5226     return "nop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
5228   [(set_attr "type" "multi")
5229    (set (attr "length")
5230         (if_then_else (eq_attr "isa" "v9")
5231                       (const_int 3) (const_int 6)))])
5233 (define_expand "udivsi3"
5234   [(set (match_operand:SI 0 "register_operand" "")
5235         (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "")
5236                  (match_operand:SI 2 "input_operand" "")))]
5237   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5238   "")
5240 ;; The V8 architecture specifies that there must be at least 3 instructions
5241 ;; between a write to the Y register and a use of it for correct results.
5242 ;; We try to fill one of them with a simple constant or a memory load.
5244 (define_insn "udivsi3_sp32"
5245   [(set (match_operand:SI 0 "register_operand" "=r,&r,&r,&r")
5246         (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r,r,r,m")
5247                  (match_operand:SI 2 "input_operand" "rI,K,m,r")))]
5248   "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
5250   output_asm_insn ("wr\t%%g0, 0, %%y", operands);
5252   switch (which_alternative)
5253     {
5254     case 0:
5255       if (TARGET_V9)
5256         return "udiv\t%1, %2, %0";
5257       else
5258         return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
5259     case 1:
5260       if (TARGET_V9)
5261         return "sethi\t%%hi(%a2), %0\n\tudiv\t%1, %0, %0";
5262       else
5263         return "sethi\t%%hi(%a2), %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
5264     case 2:
5265       if (TARGET_V9)
5266         return "ld\t%2, %0\n\tudiv\t%1, %0, %0";
5267       else
5268         return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
5269     case 3:
5270       if (TARGET_V9)
5271         return "ld\t%1, %0\n\tudiv\t%0, %2, %0";
5272       else
5273         return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
5274     default:
5275       gcc_unreachable ();
5276     }
5278   [(set_attr "type" "multi")
5279    (set (attr "length")
5280         (if_then_else (eq_attr "isa" "v9")
5281                       (const_int 3) (const_int 5)))])
5283 (define_insn "udivsi3_sp64"
5284   [(set (match_operand:SI 0 "register_operand" "=r")
5285         (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r")
5286                  (match_operand:SI 2 "input_operand" "rI")))]
5287   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5288   "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
5289   [(set_attr "type" "multi")
5290    (set_attr "length" "2")])
5292 (define_insn "udivdi3"
5293   [(set (match_operand:DI 0 "register_operand" "=r")
5294         (udiv:DI (match_operand:DI 1 "register_operand" "r")
5295                  (match_operand:DI 2 "arith_operand" "rI")))]
5296   "TARGET_ARCH64"
5297   "udivx\t%1, %2, %0"
5298   [(set_attr "type" "idiv")])
5300 (define_insn "*cmp_udiv_cc_set"
5301   [(set (reg:CC CC_REG)
5302         (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
5303                              (match_operand:SI 2 "arith_operand" "rI"))
5304                     (const_int 0)))
5305    (set (match_operand:SI 0 "register_operand" "=r")
5306         (udiv:SI (match_dup 1) (match_dup 2)))]
5307   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5309   output_asm_insn ("wr\t%%g0, 0, %%y", operands);
5311   if (TARGET_V9)
5312     return "udivcc\t%1, %2, %0";
5313   else
5314     return "nop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
5316   [(set_attr "type" "multi")
5317    (set (attr "length")
5318         (if_then_else (eq_attr "isa" "v9")
5319                       (const_int 2) (const_int 5)))])
5322 ;; SPARClet multiply/accumulate insns
5324 (define_insn "*smacsi"
5325   [(set (match_operand:SI 0 "register_operand" "=r")
5326         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
5327                           (match_operand:SI 2 "arith_operand" "rI"))
5328                  (match_operand:SI 3 "register_operand" "0")))]
5329   "TARGET_SPARCLET"
5330   "smac\t%1, %2, %0"
5331   [(set_attr "type" "imul")])
5333 (define_insn "*smacdi"
5334   [(set (match_operand:DI 0 "register_operand" "=r")
5335         (plus:DI (mult:DI (sign_extend:DI
5336                            (match_operand:SI 1 "register_operand" "%r"))
5337                           (sign_extend:DI
5338                            (match_operand:SI 2 "register_operand" "r")))
5339                  (match_operand:DI 3 "register_operand" "0")))]
5340   "TARGET_SPARCLET"
5341   "smacd\t%1, %2, %L0"
5342   [(set_attr "type" "imul")])
5344 (define_insn "*umacdi"
5345   [(set (match_operand:DI 0 "register_operand" "=r")
5346         (plus:DI (mult:DI (zero_extend:DI
5347                            (match_operand:SI 1 "register_operand" "%r"))
5348                           (zero_extend:DI
5349                            (match_operand:SI 2 "register_operand" "r")))
5350                  (match_operand:DI 3 "register_operand" "0")))]
5351   "TARGET_SPARCLET"
5352   "umacd\t%1, %2, %L0"
5353   [(set_attr "type" "imul")])
5356 ;; Boolean instructions.
5358 (define_insn "anddi3"
5359   [(set (match_operand:DI 0 "register_operand" "=r")
5360         (and:DI (match_operand:DI 1 "arith_operand" "%r")
5361                 (match_operand:DI 2 "arith_operand" "rI")))]
5362   "TARGET_ARCH64"
5363   "and\t%1, %2, %0")
5365 (define_insn "andsi3"
5366   [(set (match_operand:SI 0 "register_operand" "=r")
5367         (and:SI (match_operand:SI 1 "arith_operand" "%r")
5368                 (match_operand:SI 2 "arith_operand" "rI")))]
5369   ""
5370   "and\t%1, %2, %0")
5372 (define_split
5373   [(set (match_operand:SI 0 "register_operand" "")
5374         (and:SI (match_operand:SI 1 "register_operand" "")
5375                 (match_operand:SI 2 "const_compl_high_operand" "")))
5376    (clobber (match_operand:SI 3 "register_operand" ""))]
5377   ""
5378   [(set (match_dup 3) (match_dup 4))
5379    (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
5381   operands[4] = GEN_INT (~INTVAL (operands[2]));
5384 (define_insn "*and_not_di_sp64"
5385   [(set (match_operand:DI 0 "register_operand" "=r")
5386         (and:DI (not:DI (match_operand:DI 1 "register_operand" "%r"))
5387                 (match_operand:DI 2 "register_operand" "r")))]
5388   "TARGET_ARCH64"
5389   "andn\t%2, %1, %0")
5391 (define_insn "*and_not_si"
5392   [(set (match_operand:SI 0 "register_operand" "=r")
5393         (and:SI (not:SI (match_operand:SI 1 "register_operand" "%r"))
5394                 (match_operand:SI 2 "register_operand" "r")))]
5395   ""
5396   "andn\t%2, %1, %0")
5398 (define_insn "iordi3"
5399   [(set (match_operand:DI 0 "register_operand" "=r")
5400         (ior:DI (match_operand:DI 1 "arith_operand" "%r")
5401                 (match_operand:DI 2 "arith_operand" "rI")))]
5402   "TARGET_ARCH64"
5403   "or\t%1, %2, %0")
5405 (define_insn "iorsi3"
5406   [(set (match_operand:SI 0 "register_operand" "=r")
5407         (ior:SI (match_operand:SI 1 "arith_operand" "%r")
5408                 (match_operand:SI 2 "arith_operand" "rI")))]
5409   ""
5410   "or\t%1, %2, %0")
5412 (define_split
5413   [(set (match_operand:SI 0 "register_operand" "")
5414         (ior:SI (match_operand:SI 1 "register_operand" "")
5415                 (match_operand:SI 2 "const_compl_high_operand" "")))
5416    (clobber (match_operand:SI 3 "register_operand" ""))]
5417   ""
5418   [(set (match_dup 3) (match_dup 4))
5419    (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
5421   operands[4] = gen_int_mode (~INTVAL (operands[2]), SImode);
5424 (define_insn "*or_not_di_sp64"
5425   [(set (match_operand:DI 0 "register_operand" "=r")
5426         (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
5427                 (match_operand:DI 2 "register_operand" "r")))]
5428   "TARGET_ARCH64"
5429   "orn\t%2, %1, %0")
5431 (define_insn "*or_not_si"
5432   [(set (match_operand:SI 0 "register_operand" "=r")
5433         (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
5434                 (match_operand:SI 2 "register_operand" "r")))]
5435   ""
5436   "orn\t%2, %1, %0")
5438 (define_insn "xordi3"
5439   [(set (match_operand:DI 0 "register_operand" "=r")
5440         (xor:DI (match_operand:DI 1 "arith_operand" "%rJ")
5441                 (match_operand:DI 2 "arith_operand" "rI")))]
5442   "TARGET_ARCH64"
5443   "xor\t%r1, %2, %0")
5445 (define_insn "xorsi3"
5446   [(set (match_operand:SI 0 "register_operand" "=r")
5447         (xor:SI (match_operand:SI 1 "arith_operand" "%rJ")
5448                   (match_operand:SI 2 "arith_operand" "rI")))]
5449   ""
5450   "xor\t%r1, %2, %0")
5452 (define_split
5453   [(set (match_operand:SI 0 "register_operand" "")
5454         (xor:SI (match_operand:SI 1 "register_operand" "")
5455                 (match_operand:SI 2 "const_compl_high_operand" "")))
5456    (clobber (match_operand:SI 3 "register_operand" ""))]
5457    ""
5458   [(set (match_dup 3) (match_dup 4))
5459    (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
5461   operands[4] = gen_int_mode (~INTVAL (operands[2]), SImode);
5464 (define_split
5465   [(set (match_operand:SI 0 "register_operand" "")
5466         (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
5467                         (match_operand:SI 2 "const_compl_high_operand" ""))))
5468    (clobber (match_operand:SI 3 "register_operand" ""))]
5469   ""
5470   [(set (match_dup 3) (match_dup 4))
5471    (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
5473   operands[4] = gen_int_mode (~INTVAL (operands[2]), SImode);
5476 (define_insn "*xor_not_di_sp64"
5477   [(set (match_operand:DI 0 "register_operand" "=r")
5478         (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
5479                         (match_operand:DI 2 "arith_operand" "rI"))))]
5480   "TARGET_ARCH64"
5481   "xnor\t%r1, %2, %0")
5483 (define_insn "*xor_not_si"
5484   [(set (match_operand:SI 0 "register_operand" "=r")
5485         (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
5486                         (match_operand:SI 2 "arith_operand" "rI"))))]
5487   ""
5488   "xnor\t%r1, %2, %0")
5490 ;; These correspond to the above in the case where we also (or only)
5491 ;; want to set the condition code.  
5493 (define_insn "*cmp_cc_arith_op"
5494   [(set (reg:CC CC_REG)
5495         (compare:CC (match_operator:SI 2 "cc_arith_operator"
5496                      [(match_operand:SI 0 "arith_operand" "%r")
5497                       (match_operand:SI 1 "arith_operand" "rI")])
5498          (const_int 0)))]
5499   ""
5500   "%A2cc\t%0, %1, %%g0"
5501   [(set_attr "type" "compare")])
5503 (define_insn "*cmp_ccx_arith_op"
5504   [(set (reg:CCX CC_REG)
5505         (compare:CCX (match_operator:DI 2 "cc_arith_operator"
5506                       [(match_operand:DI 0 "arith_operand" "%r")
5507                        (match_operand:DI 1 "arith_operand" "rI")])
5508          (const_int 0)))]
5509   "TARGET_ARCH64"
5510   "%A2cc\t%0, %1, %%g0"
5511   [(set_attr "type" "compare")])
5513 (define_insn "*cmp_cc_arith_op_set"
5514   [(set (reg:CC CC_REG)
5515         (compare:CC (match_operator:SI 3 "cc_arith_operator"
5516                      [(match_operand:SI 1 "arith_operand" "%r")
5517                       (match_operand:SI 2 "arith_operand" "rI")])
5518          (const_int 0)))
5519    (set (match_operand:SI 0 "register_operand" "=r")
5520         (match_operator:SI 4 "cc_arith_operator"
5521          [(match_dup 1) (match_dup 2)]))]
5522   "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5523   "%A3cc\t%1, %2, %0"
5524   [(set_attr "type" "compare")])
5526 (define_insn "*cmp_ccx_arith_op_set"
5527   [(set (reg:CCX CC_REG)
5528         (compare:CCX (match_operator:DI 3 "cc_arith_operator"
5529                       [(match_operand:DI 1 "arith_operand" "%r")
5530                        (match_operand:DI 2 "arith_operand" "rI")])
5531          (const_int 0)))
5532    (set (match_operand:DI 0 "register_operand" "=r")
5533         (match_operator:DI 4 "cc_arith_operator"
5534          [(match_dup 1) (match_dup 2)]))]
5535   "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5536   "%A3cc\t%1, %2, %0"
5537   [(set_attr "type" "compare")])
5539 (define_insn "*cmp_cc_xor_not"
5540   [(set (reg:CC CC_REG)
5541         (compare:CC
5542          (not:SI (xor:SI (match_operand:SI 0 "register_or_zero_operand" "%rJ")
5543                          (match_operand:SI 1 "arith_operand" "rI")))
5544          (const_int 0)))]
5545   ""
5546   "xnorcc\t%r0, %1, %%g0"
5547   [(set_attr "type" "compare")])
5549 (define_insn "*cmp_ccx_xor_not"
5550   [(set (reg:CCX CC_REG)
5551         (compare:CCX
5552          (not:DI (xor:DI (match_operand:DI 0 "register_or_zero_operand" "%rJ")
5553                          (match_operand:DI 1 "arith_operand" "rI")))
5554          (const_int 0)))]
5555   "TARGET_ARCH64"
5556   "xnorcc\t%r0, %1, %%g0"
5557   [(set_attr "type" "compare")])
5559 (define_insn "*cmp_cc_xor_not_set"
5560   [(set (reg:CC CC_REG)
5561         (compare:CC
5562          (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
5563                          (match_operand:SI 2 "arith_operand" "rI")))
5564          (const_int 0)))
5565    (set (match_operand:SI 0 "register_operand" "=r")
5566         (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
5567   ""
5568   "xnorcc\t%r1, %2, %0"
5569   [(set_attr "type" "compare")])
5571 (define_insn "*cmp_ccx_xor_not_set"
5572   [(set (reg:CCX CC_REG)
5573         (compare:CCX
5574          (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
5575                          (match_operand:DI 2 "arith_operand" "rI")))
5576          (const_int 0)))
5577    (set (match_operand:DI 0 "register_operand" "=r")
5578         (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
5579   "TARGET_ARCH64"
5580   "xnorcc\t%r1, %2, %0"
5581   [(set_attr "type" "compare")])
5583 (define_insn "*cmp_cc_arith_op_not"
5584   [(set (reg:CC CC_REG)
5585         (compare:CC (match_operator:SI 2 "cc_arith_not_operator"
5586                      [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
5587                       (match_operand:SI 1 "register_or_zero_operand" "rJ")])
5588          (const_int 0)))]
5589   ""
5590   "%B2cc\t%r1, %0, %%g0"
5591   [(set_attr "type" "compare")])
5593 (define_insn "*cmp_ccx_arith_op_not"
5594   [(set (reg:CCX CC_REG)
5595         (compare:CCX (match_operator:DI 2 "cc_arith_not_operator"
5596                       [(not:DI (match_operand:DI 0 "arith_operand" "rI"))
5597                        (match_operand:DI 1 "register_or_zero_operand" "rJ")])
5598          (const_int 0)))]
5599   "TARGET_ARCH64"
5600   "%B2cc\t%r1, %0, %%g0"
5601   [(set_attr "type" "compare")])
5603 (define_insn "*cmp_cc_arith_op_not_set"
5604   [(set (reg:CC CC_REG)
5605         (compare:CC (match_operator:SI 3 "cc_arith_not_operator"
5606                      [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
5607                       (match_operand:SI 2 "register_or_zero_operand" "rJ")])
5608          (const_int 0)))
5609    (set (match_operand:SI 0 "register_operand" "=r")
5610         (match_operator:SI 4 "cc_arith_not_operator"
5611          [(not:SI (match_dup 1)) (match_dup 2)]))]
5612   "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5613   "%B3cc\t%r2, %1, %0"
5614   [(set_attr "type" "compare")])
5616 (define_insn "*cmp_ccx_arith_op_not_set"
5617   [(set (reg:CCX CC_REG)
5618         (compare:CCX (match_operator:DI 3 "cc_arith_not_operator"
5619                       [(not:DI (match_operand:DI 1 "arith_operand" "rI"))
5620                        (match_operand:DI 2 "register_or_zero_operand" "rJ")])
5621          (const_int 0)))
5622    (set (match_operand:DI 0 "register_operand" "=r")
5623         (match_operator:DI 4 "cc_arith_not_operator"
5624          [(not:DI (match_dup 1)) (match_dup 2)]))]
5625   "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5626   "%B3cc\t%r2, %1, %0"
5627   [(set_attr "type" "compare")])
5629 ;; We cannot use the "neg" pseudo insn because the Sun assembler
5630 ;; does not know how to make it work for constants.
5632 (define_expand "negdi2"
5633   [(set (match_operand:DI 0 "register_operand" "=r")
5634         (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5635   ""
5637   if (TARGET_ARCH32)
5638     {
5639       emit_insn (gen_negdi2_sp32 (operands[0], operands[1]));
5640       DONE;
5641     }
5644 (define_expand "unegvdi3"
5645   [(parallel [(set (reg:CCXC CC_REG)
5646                    (compare:CCXC (not:DI (match_operand:DI 1 "register_operand" ""))
5647                                  (const_int -1)))
5648               (set (match_operand:DI 0 "register_operand" "")
5649                    (neg:DI (match_dup 1)))])
5650    (set (pc)
5651         (if_then_else (ltu (reg:CCXC CC_REG) (const_int 0))
5652                       (label_ref (match_operand 2 ""))
5653                       (pc)))]
5654   ""
5656   if (TARGET_ARCH32)
5657     {
5658       emit_insn (gen_unegvdi3_sp32 (operands[0], operands[1]));
5659       rtx x = gen_rtx_LTU (VOIDmode, gen_rtx_REG (CCCmode, SPARC_ICC_REG),
5660                                      const0_rtx);
5661       emit_jump_insn (gen_cbranchcc4 (x, XEXP (x, 0), XEXP (x, 1), operands[2]));
5662       DONE;
5663     }
5666 (define_expand "negvdi3"
5667   [(parallel [(set (reg:CCXV CC_REG)
5668                    (compare:CCXV (neg:DI (match_operand:DI 1 "register_operand" ""))
5669                                  (unspec:DI [(match_dup 1)] UNSPEC_NEGV)))
5670               (set (match_operand:DI 0 "register_operand" "")
5671                    (neg:DI (match_dup 1)))])
5672    (set (pc)
5673         (if_then_else (ne (reg:CCXV CC_REG) (const_int 0))
5674                       (label_ref (match_operand 2 ""))
5675                       (pc)))]
5676   ""
5678   if (TARGET_ARCH32)
5679     {
5680       emit_insn (gen_negvdi3_sp32 (operands[0], operands[1]));
5681       rtx x = gen_rtx_NE (VOIDmode, gen_rtx_REG (CCVmode, SPARC_ICC_REG),
5682                                     const0_rtx);
5683       emit_jump_insn (gen_cbranchcc4 (x, XEXP (x, 0), XEXP (x, 1), operands[2]));
5684       DONE;
5685     }
5688 (define_insn_and_split "negdi2_sp32"
5689   [(set (match_operand:DI 0 "register_operand" "=&r")
5690         (neg:DI (match_operand:DI 1 "register_operand" "r")))
5691    (clobber (reg:CC CC_REG))]
5692   "TARGET_ARCH32"
5693   "#"
5694   "&& reload_completed"
5695   [(parallel [(set (reg:CCC CC_REG)
5696                    (compare:CCC (not:SI (match_dup 5)) (const_int -1)))
5697               (set (match_dup 4) (neg:SI (match_dup 5)))])
5698    (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
5699                                 (ltu:SI (reg:CCC CC_REG) (const_int 0))))]
5700   "operands[2] = gen_highpart (SImode, operands[0]);
5701    operands[3] = gen_highpart (SImode, operands[1]);
5702    operands[4] = gen_lowpart (SImode, operands[0]);
5703    operands[5] = gen_lowpart (SImode, operands[1]);"
5704   [(set_attr "length" "2")])
5706 (define_insn_and_split "unegvdi3_sp32"
5707   [(set (reg:CCC CC_REG)
5708         (compare:CCC (not:DI (match_operand:DI 1 "register_operand" "r"))
5709                      (const_int -1)))
5710    (set (match_operand:DI 0 "register_operand" "=&r")
5711         (neg:DI (match_dup 1)))]
5712   "TARGET_ARCH32"
5713   "#"
5714   "&& reload_completed"
5715   [(parallel [(set (reg:CCC CC_REG)
5716                    (compare:CCC (not:SI (match_dup 5)) (const_int -1)))
5717               (set (match_dup 4) (neg:SI (match_dup 5)))])
5718    (parallel [(set (reg:CCC CC_REG)
5719                    (compare:CCC (zero_extend:DI
5720                                   (neg:SI (plus:SI (match_dup 3)
5721                                                    (ltu:SI (reg:CCC CC_REG)
5722                                                            (const_int 0)))))
5723                                 (neg:DI (plus:DI (zero_extend:DI (match_dup 3))
5724                                                  (ltu:DI (reg:CCC CC_REG)
5725                                                          (const_int 0))))))
5726               (set (match_dup 2) (neg:SI (plus:SI (match_dup 3)
5727                                                   (ltu:SI (reg:CCC CC_REG)
5728                                                           (const_int 0)))))])]
5729   "operands[2] = gen_highpart (SImode, operands[0]);
5730    operands[3] = gen_highpart (SImode, operands[1]);
5731    operands[4] = gen_lowpart (SImode, operands[0]);
5732    operands[5] = gen_lowpart (SImode, operands[1]);"
5733   [(set_attr "length" "2")])
5735 (define_insn_and_split "negvdi3_sp32"
5736   [(set (reg:CCV CC_REG)
5737         (compare:CCV (neg:DI (match_operand:DI 1 "register_operand" "r"))
5738                      (unspec:DI [(match_dup 1)] UNSPEC_NEGV)))
5739    (set (match_operand:DI 0 "register_operand" "=&r")
5740         (neg:DI (match_dup 1)))]
5741   "TARGET_ARCH32"
5742   "#"
5743   "&& reload_completed"
5744   [(parallel [(set (reg:CCC CC_REG)
5745                    (compare:CCC (not:SI (match_dup 5)) (const_int -1)))
5746               (set (match_dup 4) (neg:SI (match_dup 5)))])
5747    (parallel [(set (reg:CCV CC_REG)
5748                    (compare:CCV (neg:SI (plus:SI (match_dup 3)
5749                                                  (ltu:SI (reg:CCC CC_REG)
5750                                                          (const_int 0))))
5751                                 (unspec:SI [(plus:SI (match_dup 3)
5752                                                      (ltu:SI (reg:CCC CC_REG)
5753                                                              (const_int 0)))]
5754                                            UNSPEC_NEGV)))
5755               (set (match_dup 2) (neg:SI (plus:SI (match_dup 3)
5756                                                   (ltu:SI (reg:CCC CC_REG)
5757                                                           (const_int 0)))))])]
5758   "operands[2] = gen_highpart (SImode, operands[0]);
5759    operands[3] = gen_highpart (SImode, operands[1]);
5760    operands[4] = gen_lowpart (SImode, operands[0]);
5761    operands[5] = gen_lowpart (SImode, operands[1]);"
5762   [(set_attr "length" "2")])
5764 (define_insn "*negdi2_sp64"
5765   [(set (match_operand:DI 0 "register_operand" "=r")
5766         (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5767   "TARGET_ARCH64"
5768   "sub\t%%g0, %1, %0")
5770 (define_insn "negsi2"
5771   [(set (match_operand:SI 0 "register_operand" "=r")
5772         (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
5773   ""
5774   "sub\t%%g0, %1, %0")
5776 (define_expand "unegvsi3"
5777   [(parallel [(set (reg:CCC CC_REG)
5778                    (compare:CCC (not:SI (match_operand:SI 1 "arith_operand" ""))
5779                                 (const_int -1)))
5780               (set (match_operand:SI 0 "register_operand" "")
5781                    (neg:SI (match_dup 1)))])
5782    (set (pc)
5783         (if_then_else (ltu (reg:CCC CC_REG) (const_int 0))
5784                       (label_ref (match_operand 2 ""))
5785                       (pc)))]
5786   "")
5788 (define_expand "negvsi3"
5789   [(parallel [(set (reg:CCV CC_REG)
5790                    (compare:CCV (neg:SI (match_operand:SI 1 "arith_operand" ""))
5791                                 (unspec:SI [(match_dup 1)] UNSPEC_NEGV)))
5792               (set (match_operand:SI 0 "register_operand" "")
5793                    (neg:SI (match_dup 1)))])
5794    (set (pc)
5795         (if_then_else (ne (reg:CCV CC_REG) (const_int 0))
5796                       (label_ref (match_operand 2 ""))
5797                       (pc)))]
5800 (define_insn "*cmp_ccnz_neg"
5801   [(set (reg:CCNZ CC_REG)
5802         (compare:CCNZ (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
5803                       (const_int 0)))]
5804   ""
5805   "subcc\t%%g0, %0, %%g0"
5806   [(set_attr "type" "compare")])
5808 (define_insn "*cmp_ccxnz_neg"
5809   [(set (reg:CCXNZ CC_REG)
5810         (compare:CCXNZ (neg:DI (match_operand:DI 0 "arith_operand" "rI"))
5811                        (const_int 0)))]
5812   "TARGET_ARCH64"
5813   "subcc\t%%g0, %0, %%g0"
5814   [(set_attr "type" "compare")])
5816 (define_insn "*cmp_ccnz_neg_set"
5817   [(set (reg:CCNZ CC_REG)
5818         (compare:CCNZ (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
5819                       (const_int 0)))
5820    (set (match_operand:SI 0 "register_operand" "=r")
5821         (neg:SI (match_dup 1)))]
5822   ""
5823   "subcc\t%%g0, %1, %0"
5824   [(set_attr "type" "compare")])
5826 (define_insn "*cmp_ccxnz_neg_set"
5827   [(set (reg:CCXNZ CC_REG)
5828         (compare:CCXNZ (neg:DI (match_operand:DI 1 "arith_operand" "rI"))
5829                        (const_int 0)))
5830    (set (match_operand:DI 0 "register_operand" "=r")
5831         (neg:DI (match_dup 1)))]
5832   "TARGET_ARCH64"
5833   "subcc\t%%g0, %1, %0"
5834   [(set_attr "type" "compare")])
5836 (define_insn "*cmp_ccc_neg_set"
5837   [(set (reg:CCC CC_REG)
5838         (compare:CCC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
5839                      (const_int -1)))
5840    (set (match_operand:SI 0 "register_operand" "=r")
5841         (neg:SI (match_dup 1)))]
5842   ""
5843   "subcc\t%%g0, %1, %0"
5844   [(set_attr "type" "compare")])
5846 (define_insn "*cmp_ccxc_neg_set"
5847   [(set (reg:CCXC CC_REG)
5848         (compare:CCXC (not:DI (match_operand:DI 1 "arith_operand" "rI"))
5849                       (const_int -1)))
5850    (set (match_operand:DI 0 "register_operand" "=r")
5851         (neg:DI (match_dup 1)))]
5852   "TARGET_ARCH64"
5853   "subcc\t%%g0, %1, %0"
5854   [(set_attr "type" "compare")])
5856 (define_insn "*cmp_ccc_neg_sltu_set"
5857   [(set (reg:CCC CC_REG)
5858         (compare:CCC (zero_extend:DI
5859                        (neg:SI (plus:SI (match_operand:SI 1 "arith_operand" "rI")
5860                                         (ltu:SI (reg:CCC CC_REG)
5861                                                 (const_int 0)))))
5862                      (neg:DI (plus:DI (zero_extend:DI (match_dup 1))
5863                                       (ltu:DI (reg:CCC CC_REG)
5864                                               (const_int 0))))))
5865    (set (match_operand:SI 0 "register_operand" "=r")
5866         (neg:SI (plus:SI (match_dup 1)
5867                          (ltu:SI (reg:CCC CC_REG) (const_int 0)))))]
5868   ""
5869   "subxcc\t%%g0, %1, %0"
5870   [(set_attr "type" "compare")])
5872 (define_insn "*cmp_ccv_neg"
5873   [(set (reg:CCV CC_REG)
5874         (compare:CCV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
5875                      (unspec:SI [(match_dup 0)] UNSPEC_NEGV)))]
5876   ""
5877   "subcc\t%%g0, %0, %%g0"
5878   [(set_attr "type" "compare")])
5880 (define_insn "*cmp_ccxv_neg"
5881   [(set (reg:CCXV CC_REG)
5882         (compare:CCXV (neg:DI (match_operand:DI 0 "arith_operand" "rI"))
5883                       (unspec:DI [(match_dup 0)] UNSPEC_NEGV)))]
5884   "TARGET_ARCH64"
5885   "subcc\t%%g0, %0, %%g0"
5886   [(set_attr "type" "compare")])
5888 (define_insn "*cmp_ccv_neg_set"
5889   [(set (reg:CCV CC_REG)
5890         (compare:CCV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
5891                      (unspec:SI [(match_dup 1)] UNSPEC_NEGV)))
5892    (set (match_operand:SI 0 "register_operand" "=r")
5893         (neg:SI (match_dup 1)))]
5894   ""
5895   "subcc\t%%g0, %1, %0"
5896   [(set_attr "type" "compare")])
5898 (define_insn "*cmp_ccxv_neg_set"
5899   [(set (reg:CCXV CC_REG)
5900         (compare:CCXV (neg:DI (match_operand:DI 1 "arith_operand" "rI"))
5901                       (unspec:DI [(match_dup 1)] UNSPEC_NEGV)))
5902    (set (match_operand:DI 0 "register_operand" "=r")
5903         (neg:DI (match_dup 1)))]
5904   "TARGET_ARCH64"
5905   "subcc\t%%g0, %1, %0"
5906   [(set_attr "type" "compare")])
5908 (define_insn "*cmp_ccv_neg_sltu_set"
5909   [(set (reg:CCV CC_REG)
5910         (compare:CCV (neg:SI (plus:SI (match_operand:SI 1 "arith_operand" "rI")
5911                                       (ltu:SI (reg:CCC CC_REG) (const_int 0))))
5912                      (unspec:SI [(plus:SI (match_dup 1)
5913                                           (ltu:SI (reg:CCC CC_REG)
5914                                                   (const_int 0)))]
5915                                 UNSPEC_NEGV)))
5916    (set (match_operand:SI 0 "register_operand" "=r")
5917         (neg:SI (plus:SI (match_dup 1)
5918                          (ltu:SI (reg:CCC CC_REG) (const_int 0)))))]
5919   ""
5920   "subxcc\t%%g0, %1, %0"
5921   [(set_attr "type" "compare")])
5924 (define_insn "one_cmpldi2"
5925   [(set (match_operand:DI 0 "register_operand" "=r")
5926         (not:DI (match_operand:DI 1 "arith_operand" "rI")))]
5927   "TARGET_ARCH64"
5928   "xnor\t%%g0, %1, %0")
5930 (define_insn "one_cmplsi2"
5931   [(set (match_operand:SI 0 "register_operand" "=r")
5932         (not:SI (match_operand:SI 1 "arith_operand" "rI")))]
5933   ""
5934   "xnor\t%%g0, %1, %0")
5936 (define_insn "*cmp_cc_not"
5937   [(set (reg:CC CC_REG)
5938         (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
5939                     (const_int 0)))]
5940   ""
5941   "xnorcc\t%%g0, %0, %%g0"
5942   [(set_attr "type" "compare")])
5944 (define_insn "*cmp_ccx_not"
5945   [(set (reg:CCX CC_REG)
5946         (compare:CCX (not:DI (match_operand:DI 0 "arith_operand" "rI"))
5947                      (const_int 0)))]
5948   "TARGET_ARCH64"
5949   "xnorcc\t%%g0, %0, %%g0"
5950   [(set_attr "type" "compare")])
5952 (define_insn "*cmp_cc_set_not"
5953   [(set (reg:CC CC_REG)
5954         (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
5955                     (const_int 0)))
5956    (set (match_operand:SI 0 "register_operand" "=r")
5957         (not:SI (match_dup 1)))]
5958   ""
5959   "xnorcc\t%%g0, %1, %0"
5960   [(set_attr "type" "compare")])
5962 (define_insn "*cmp_ccx_set_not"
5963   [(set (reg:CCX CC_REG)
5964         (compare:CCX (not:DI (match_operand:DI 1 "arith_operand" "rI"))
5965                     (const_int 0)))
5966    (set (match_operand:DI 0 "register_operand" "=r")
5967         (not:DI (match_dup 1)))]
5968   "TARGET_ARCH64"
5969   "xnorcc\t%%g0, %1, %0"
5970   [(set_attr "type" "compare")])
5972 (define_insn "*cmp_cc_set"
5973   [(set (match_operand:SI 0 "register_operand" "=r")
5974         (match_operand:SI 1 "register_operand" "r"))
5975    (set (reg:CC CC_REG)
5976         (compare:CC (match_dup 1) (const_int 0)))]
5977   ""
5978   "orcc\t%1, 0, %0"
5979   [(set_attr "type" "compare")])
5981 (define_insn "*cmp_ccx_set64"
5982   [(set (match_operand:DI 0 "register_operand" "=r")
5983         (match_operand:DI 1 "register_operand" "r"))
5984    (set (reg:CCX CC_REG)
5985         (compare:CCX (match_dup 1) (const_int 0)))]
5986   "TARGET_ARCH64"
5987   "orcc\t%1, 0, %0"
5988    [(set_attr "type" "compare")])
5991 ;; Floating point arithmetic instructions.
5993 (define_expand "addtf3"
5994   [(set (match_operand:TF 0 "nonimmediate_operand" "")
5995         (plus:TF (match_operand:TF 1 "general_operand" "")
5996                  (match_operand:TF 2 "general_operand" "")))]
5997   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5998   "emit_tfmode_binop (PLUS, operands); DONE;")
6000 (define_insn "*addtf3_hq"
6001   [(set (match_operand:TF 0 "register_operand" "=e")
6002         (plus:TF (match_operand:TF 1 "register_operand" "e")
6003                  (match_operand:TF 2 "register_operand" "e")))]
6004   "TARGET_FPU && TARGET_HARD_QUAD"
6005   "faddq\t%1, %2, %0"
6006   [(set_attr "type" "fp")])
6008 (define_insn "adddf3"
6009   [(set (match_operand:DF 0 "register_operand" "=e")
6010         (plus:DF (match_operand:DF 1 "register_operand" "e")
6011                  (match_operand:DF 2 "register_operand" "e")))]
6012   "TARGET_FPU"
6013   "faddd\t%1, %2, %0"
6014   [(set_attr "type" "fp")
6015    (set_attr "fptype" "double")])
6017 (define_insn "addsf3"
6018   [(set (match_operand:SF 0 "register_operand" "=f")
6019         (plus:SF (match_operand:SF 1 "register_operand" "f")
6020                  (match_operand:SF 2 "register_operand" "f")))]
6021   "TARGET_FPU"
6022   "fadds\t%1, %2, %0"
6023   [(set_attr "type" "fp")])
6025 (define_expand "subtf3"
6026   [(set (match_operand:TF 0 "nonimmediate_operand" "")
6027         (minus:TF (match_operand:TF 1 "general_operand" "")
6028                   (match_operand:TF 2 "general_operand" "")))]
6029   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6030   "emit_tfmode_binop (MINUS, operands); DONE;")
6032 (define_insn "*subtf3_hq"
6033   [(set (match_operand:TF 0 "register_operand" "=e")
6034         (minus:TF (match_operand:TF 1 "register_operand" "e")
6035                   (match_operand:TF 2 "register_operand" "e")))]
6036   "TARGET_FPU && TARGET_HARD_QUAD"
6037   "fsubq\t%1, %2, %0"
6038   [(set_attr "type" "fp")])
6040 (define_insn "subdf3"
6041   [(set (match_operand:DF 0 "register_operand" "=e")
6042         (minus:DF (match_operand:DF 1 "register_operand" "e")
6043                   (match_operand:DF 2 "register_operand" "e")))]
6044   "TARGET_FPU"
6045   "fsubd\t%1, %2, %0"
6046   [(set_attr "type" "fp")
6047    (set_attr "fptype" "double")])
6049 (define_insn "subsf3"
6050   [(set (match_operand:SF 0 "register_operand" "=f")
6051         (minus:SF (match_operand:SF 1 "register_operand" "f")
6052                   (match_operand:SF 2 "register_operand" "f")))]
6053   "TARGET_FPU"
6054   "fsubs\t%1, %2, %0"
6055   [(set_attr "type" "fp")])
6057 (define_expand "multf3"
6058   [(set (match_operand:TF 0 "nonimmediate_operand" "")
6059         (mult:TF (match_operand:TF 1 "general_operand" "")
6060                  (match_operand:TF 2 "general_operand" "")))]
6061   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6062   "emit_tfmode_binop (MULT, operands); DONE;")
6064 (define_insn "*multf3_hq"
6065   [(set (match_operand:TF 0 "register_operand" "=e")
6066         (mult:TF (match_operand:TF 1 "register_operand" "e")
6067                  (match_operand:TF 2 "register_operand" "e")))]
6068   "TARGET_FPU && TARGET_HARD_QUAD"
6069   "fmulq\t%1, %2, %0"
6070   [(set_attr "type" "fpmul")])
6072 (define_insn "muldf3"
6073   [(set (match_operand:DF 0 "register_operand" "=e")
6074         (mult:DF (match_operand:DF 1 "register_operand" "e")
6075                  (match_operand:DF 2 "register_operand" "e")))]
6076   "TARGET_FPU"
6077   "fmuld\t%1, %2, %0"
6078   [(set_attr "type" "fpmul")
6079    (set_attr "fptype" "double")])
6081 (define_insn "mulsf3"
6082   [(set (match_operand:SF 0 "register_operand" "=f")
6083         (mult:SF (match_operand:SF 1 "register_operand" "f")
6084                  (match_operand:SF 2 "register_operand" "f")))]
6085   "TARGET_FPU"
6086   "fmuls\t%1, %2, %0"
6087   [(set_attr "type" "fpmul")])
6089 (define_insn "fmadf4"
6090   [(set (match_operand:DF 0 "register_operand" "=e")
6091         (fma:DF (match_operand:DF 1 "register_operand" "e")
6092                 (match_operand:DF 2 "register_operand" "e")
6093                 (match_operand:DF 3 "register_operand" "e")))]
6094   "TARGET_FMAF"
6095   "fmaddd\t%1, %2, %3, %0"
6096   [(set_attr "type" "fpmul")])
6098 (define_insn "fmsdf4"
6099   [(set (match_operand:DF 0 "register_operand" "=e")
6100         (fma:DF (match_operand:DF 1 "register_operand" "e")
6101                 (match_operand:DF 2 "register_operand" "e")
6102                 (neg:DF (match_operand:DF 3 "register_operand" "e"))))]
6103   "TARGET_FMAF"
6104   "fmsubd\t%1, %2, %3, %0"
6105   [(set_attr "type" "fpmul")])
6107 (define_insn "*nfmadf4"
6108   [(set (match_operand:DF 0 "register_operand" "=e")
6109         (neg:DF (fma:DF (match_operand:DF 1 "register_operand" "e")
6110                         (match_operand:DF 2 "register_operand" "e")
6111                         (match_operand:DF 3 "register_operand" "e"))))]
6112   "TARGET_FMAF"
6113   "fnmaddd\t%1, %2, %3, %0"
6114   [(set_attr "type" "fpmul")])
6116 (define_insn "*nfmsdf4"
6117   [(set (match_operand:DF 0 "register_operand" "=e")
6118         (neg:DF (fma:DF (match_operand:DF 1 "register_operand" "e")
6119                         (match_operand:DF 2 "register_operand" "e")
6120                         (neg:DF (match_operand:DF 3 "register_operand" "e")))))]
6121   "TARGET_FMAF"
6122   "fnmsubd\t%1, %2, %3, %0"
6123   [(set_attr "type" "fpmul")])
6125 (define_insn "fmasf4"
6126   [(set (match_operand:SF 0 "register_operand" "=f")
6127         (fma:SF (match_operand:SF 1 "register_operand" "f")
6128                 (match_operand:SF 2 "register_operand" "f")
6129                 (match_operand:SF 3 "register_operand" "f")))]
6130   "TARGET_FMAF"
6131   "fmadds\t%1, %2, %3, %0"
6132   [(set_attr "type" "fpmul")])
6134 (define_insn "fmssf4"
6135   [(set (match_operand:SF 0 "register_operand" "=f")
6136         (fma:SF (match_operand:SF 1 "register_operand" "f")
6137                 (match_operand:SF 2 "register_operand" "f")
6138                 (neg:SF (match_operand:SF 3 "register_operand" "f"))))]
6139   "TARGET_FMAF"
6140   "fmsubs\t%1, %2, %3, %0"
6141   [(set_attr "type" "fpmul")])
6143 (define_insn "*nfmasf4"
6144   [(set (match_operand:SF 0 "register_operand" "=f")
6145         (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "f")
6146                         (match_operand:SF 2 "register_operand" "f")
6147                         (match_operand:SF 3 "register_operand" "f"))))]
6148   "TARGET_FMAF"
6149   "fnmadds\t%1, %2, %3, %0"
6150   [(set_attr "type" "fpmul")])
6152 (define_insn "*nfmssf4"
6153   [(set (match_operand:SF 0 "register_operand" "=f")
6154         (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "f")
6155                         (match_operand:SF 2 "register_operand" "f")
6156                         (neg:SF (match_operand:SF 3 "register_operand" "f")))))]
6157   "TARGET_FMAF"
6158   "fnmsubs\t%1, %2, %3, %0"
6159   [(set_attr "type" "fpmul")])
6161 (define_insn "*muldf3_extend"
6162   [(set (match_operand:DF 0 "register_operand" "=e")
6163         (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
6164                  (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
6165   "TARGET_FSMULD"
6166   "fsmuld\t%1, %2, %0"
6167   [(set_attr "type" "fpmul")
6168    (set_attr "fptype" "double")])
6170 (define_insn "*multf3_extend"
6171   [(set (match_operand:TF 0 "register_operand" "=e")
6172         (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
6173                  (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
6174   "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
6175   "fdmulq\t%1, %2, %0"
6176   [(set_attr "type" "fpmul")])
6178 (define_expand "divtf3"
6179   [(set (match_operand:TF 0 "nonimmediate_operand" "")
6180         (div:TF (match_operand:TF 1 "general_operand" "")
6181                 (match_operand:TF 2 "general_operand" "")))]
6182   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6183   "emit_tfmode_binop (DIV, operands); DONE;")
6185 ;; don't have timing for quad-prec. divide.
6186 (define_insn "*divtf3_hq"
6187   [(set (match_operand:TF 0 "register_operand" "=e")
6188         (div:TF (match_operand:TF 1 "register_operand" "e")
6189                 (match_operand:TF 2 "register_operand" "e")))]
6190   "TARGET_FPU && TARGET_HARD_QUAD"
6191   "fdivq\t%1, %2, %0"
6192   [(set_attr "type" "fpdivs")])
6194 (define_expand "divdf3"
6195   [(set (match_operand:DF 0 "register_operand" "=e")
6196         (div:DF (match_operand:DF 1 "register_operand" "e")
6197                 (match_operand:DF 2 "register_operand" "e")))]
6198   "TARGET_FPU"
6199   "")
6201 (define_insn "*divdf3_nofix"
6202   [(set (match_operand:DF 0 "register_operand" "=e")
6203         (div:DF (match_operand:DF 1 "register_operand" "e")
6204                 (match_operand:DF 2 "register_operand" "e")))]
6205   "TARGET_FPU && !sparc_fix_ut699"
6206   "fdivd\t%1, %2, %0"
6207   [(set_attr "type" "fpdivd")
6208    (set_attr "fptype" "double")])
6210 (define_insn "*divdf3_fix"
6211   [(set (match_operand:DF 0 "register_operand" "=e")
6212         (div:DF (match_operand:DF 1 "register_operand" "e")
6213                 (match_operand:DF 2 "register_operand" "e")))]
6214   "TARGET_FPU && sparc_fix_ut699"
6215   "fdivd\t%1, %2, %0\n\tstd\t%0, [%%sp-8]\n\tnop"
6216   [(set_attr "type" "fpdivd")
6217    (set_attr "fptype" "double")
6218    (set_attr "length" "3")])
6220 (define_insn "divsf3"
6221   [(set (match_operand:SF 0 "register_operand" "=f")
6222         (div:SF (match_operand:SF 1 "register_operand" "f")
6223                 (match_operand:SF 2 "register_operand" "f")))]
6224   "TARGET_FPU && !sparc_fix_ut699"
6225   "fdivs\t%1, %2, %0"
6226   [(set_attr "type" "fpdivs")])
6228 (define_expand "negtf2"
6229   [(set (match_operand:TF 0 "register_operand" "")
6230         (neg:TF (match_operand:TF 1 "register_operand" "")))]
6231   "TARGET_FPU"
6232   "")
6234 (define_insn "*negtf2_hq"
6235   [(set (match_operand:TF 0 "register_operand" "=e")
6236         (neg:TF (match_operand:TF 1 "register_operand" "e")))]
6237   "TARGET_FPU && TARGET_HARD_QUAD"
6238   "fnegq\t%1, %0"
6239   [(set_attr "type" "fpmove")])
6241 (define_insn_and_split "*negtf2"
6242   [(set (match_operand:TF 0 "register_operand" "=e")
6243         (neg:TF (match_operand:TF 1 "register_operand" "e")))]
6244   "TARGET_FPU && !TARGET_HARD_QUAD"
6245   "#"
6246   "&& reload_completed"
6247   [(clobber (const_int 0))]
6249   rtx set_dest = operands[0];
6250   rtx set_src = operands[1];
6251   rtx dest1, dest2;
6252   rtx src1, src2;
6254   dest1 = gen_df_reg (set_dest, 0);
6255   dest2 = gen_df_reg (set_dest, 1);
6256   src1 = gen_df_reg (set_src, 0);
6257   src2 = gen_df_reg (set_src, 1);
6259   /* Now emit using the real source and destination we found, swapping
6260      the order if we detect overlap.  */
6261   if (reg_overlap_mentioned_p (dest1, src2))
6262     {
6263       emit_insn (gen_movdf (dest2, src2));
6264       emit_insn (gen_negdf2 (dest1, src1));
6265     }
6266   else
6267     {
6268       emit_insn (gen_negdf2 (dest1, src1));
6269       if (REGNO (dest2) != REGNO (src2))
6270         emit_insn (gen_movdf (dest2, src2));
6271     }
6272   DONE;
6274   [(set_attr "length" "2")])
6276 (define_expand "negdf2"
6277   [(set (match_operand:DF 0 "register_operand" "")
6278         (neg:DF (match_operand:DF 1 "register_operand" "")))]
6279   "TARGET_FPU"
6280   "")
6282 (define_insn_and_split "*negdf2_notv9"
6283   [(set (match_operand:DF 0 "register_operand" "=e")
6284         (neg:DF (match_operand:DF 1 "register_operand" "e")))]
6285   "TARGET_FPU && !TARGET_V9"
6286   "#"
6287   "&& reload_completed"
6288   [(clobber (const_int 0))]
6290   rtx set_dest = operands[0];
6291   rtx set_src = operands[1];
6292   rtx dest1, dest2;
6293   rtx src1, src2;
6295   dest1 = gen_highpart (SFmode, set_dest);
6296   dest2 = gen_lowpart (SFmode, set_dest);
6297   src1 = gen_highpart (SFmode, set_src);
6298   src2 = gen_lowpart (SFmode, set_src);
6300   /* Now emit using the real source and destination we found, swapping
6301      the order if we detect overlap.  */
6302   if (reg_overlap_mentioned_p (dest1, src2))
6303     {
6304       emit_insn (gen_movsf (dest2, src2));
6305       emit_insn (gen_negsf2 (dest1, src1));
6306     }
6307   else
6308     {
6309       emit_insn (gen_negsf2 (dest1, src1));
6310       if (REGNO (dest2) != REGNO (src2))
6311         emit_insn (gen_movsf (dest2, src2));
6312     }
6313   DONE;
6315   [(set_attr "length" "2")])
6317 (define_insn "*negdf2_v9"
6318   [(set (match_operand:DF 0 "register_operand" "=e")
6319         (neg:DF (match_operand:DF 1 "register_operand" "e")))]
6320   "TARGET_FPU && TARGET_V9"
6321   "fnegd\t%1, %0"
6322   [(set_attr "type" "fpmove")
6323    (set_attr "fptype" "double")])
6325 (define_insn "negsf2"
6326   [(set (match_operand:SF 0 "register_operand" "=f")
6327         (neg:SF (match_operand:SF 1 "register_operand" "f")))]
6328   "TARGET_FPU"
6329   "fnegs\t%1, %0"
6330   [(set_attr "type" "fpmove")])
6332 (define_expand "abstf2"
6333   [(set (match_operand:TF 0 "register_operand" "")
6334         (abs:TF (match_operand:TF 1 "register_operand" "")))]
6335   "TARGET_FPU"
6336   "")
6338 (define_insn "*abstf2_hq"
6339   [(set (match_operand:TF 0 "register_operand" "=e")
6340         (abs:TF (match_operand:TF 1 "register_operand" "e")))]
6341   "TARGET_FPU && TARGET_HARD_QUAD"
6342   "fabsq\t%1, %0"
6343   [(set_attr "type" "fpmove")])
6345 (define_insn_and_split "*abstf2"
6346   [(set (match_operand:TF 0 "register_operand" "=e")
6347         (abs:TF (match_operand:TF 1 "register_operand" "e")))]
6348   "TARGET_FPU && !TARGET_HARD_QUAD"
6349   "#"
6350   "&& reload_completed"
6351   [(clobber (const_int 0))]
6353   rtx set_dest = operands[0];
6354   rtx set_src = operands[1];
6355   rtx dest1, dest2;
6356   rtx src1, src2;
6358   dest1 = gen_df_reg (set_dest, 0);
6359   dest2 = gen_df_reg (set_dest, 1);
6360   src1 = gen_df_reg (set_src, 0);
6361   src2 = gen_df_reg (set_src, 1);
6363   /* Now emit using the real source and destination we found, swapping
6364      the order if we detect overlap.  */
6365   if (reg_overlap_mentioned_p (dest1, src2))
6366     {
6367       emit_insn (gen_movdf (dest2, src2));
6368       emit_insn (gen_absdf2 (dest1, src1));
6369     }
6370   else
6371     {
6372       emit_insn (gen_absdf2 (dest1, src1));
6373       if (REGNO (dest2) != REGNO (src2))
6374         emit_insn (gen_movdf (dest2, src2));
6375     }
6376   DONE;
6378   [(set_attr "length" "2")])
6380 (define_expand "absdf2"
6381   [(set (match_operand:DF 0 "register_operand" "")
6382         (abs:DF (match_operand:DF 1 "register_operand" "")))]
6383   "TARGET_FPU"
6384   "")
6386 (define_insn_and_split "*absdf2_notv9"
6387   [(set (match_operand:DF 0 "register_operand" "=e")
6388         (abs:DF (match_operand:DF 1 "register_operand" "e")))]
6389   "TARGET_FPU && !TARGET_V9"
6390   "#"
6391   "&& reload_completed"
6392   [(clobber (const_int 0))]
6394   rtx set_dest = operands[0];
6395   rtx set_src = operands[1];
6396   rtx dest1, dest2;
6397   rtx src1, src2;
6399   dest1 = gen_highpart (SFmode, set_dest);
6400   dest2 = gen_lowpart (SFmode, set_dest);
6401   src1 = gen_highpart (SFmode, set_src);
6402   src2 = gen_lowpart (SFmode, set_src);
6404   /* Now emit using the real source and destination we found, swapping
6405      the order if we detect overlap.  */
6406   if (reg_overlap_mentioned_p (dest1, src2))
6407     {
6408       emit_insn (gen_movsf (dest2, src2));
6409       emit_insn (gen_abssf2 (dest1, src1));
6410     }
6411   else
6412     {
6413       emit_insn (gen_abssf2 (dest1, src1));
6414       if (REGNO (dest2) != REGNO (src2))
6415         emit_insn (gen_movsf (dest2, src2));
6416     }
6417   DONE;
6419   [(set_attr "length" "2")])
6421 (define_insn "*absdf2_v9"
6422   [(set (match_operand:DF 0 "register_operand" "=e")
6423         (abs:DF (match_operand:DF 1 "register_operand" "e")))]
6424   "TARGET_FPU && TARGET_V9"
6425   "fabsd\t%1, %0"
6426   [(set_attr "type" "fpmove")
6427    (set_attr "fptype" "double")])
6429 (define_insn "abssf2"
6430   [(set (match_operand:SF 0 "register_operand" "=f")
6431         (abs:SF (match_operand:SF 1 "register_operand" "f")))]
6432   "TARGET_FPU"
6433   "fabss\t%1, %0"
6434   [(set_attr "type" "fpmove")])
6436 (define_expand "sqrttf2"
6437   [(set (match_operand:TF 0 "nonimmediate_operand" "")
6438         (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
6439   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6440   "emit_tfmode_unop (SQRT, operands); DONE;")
6442 (define_insn "*sqrttf2_hq"
6443   [(set (match_operand:TF 0 "register_operand" "=e")
6444         (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
6445   "TARGET_FPU && TARGET_HARD_QUAD"
6446   "fsqrtq\t%1, %0"
6447   [(set_attr "type" "fpsqrts")])
6449 (define_expand "sqrtdf2"
6450   [(set (match_operand:DF 0 "register_operand" "=e")
6451         (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
6452   "TARGET_FPU"
6453   "")
6455 (define_insn "*sqrtdf2_nofix"
6456   [(set (match_operand:DF 0 "register_operand" "=e")
6457         (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
6458   "TARGET_FPU && !sparc_fix_ut699"
6459   "fsqrtd\t%1, %0"
6460   [(set_attr "type" "fpsqrtd")
6461    (set_attr "fptype" "double")])
6463 (define_insn "*sqrtdf2_fix"
6464   [(set (match_operand:DF 0 "register_operand" "=e")
6465         (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
6466   "TARGET_FPU && sparc_fix_ut699"
6467   "fsqrtd\t%1, %0\n\tstd\t%0, [%%sp-8]\n\tnop"
6468   [(set_attr "type" "fpsqrtd")
6469    (set_attr "fptype" "double")
6470    (set_attr "length" "3")])
6472 (define_insn "sqrtsf2"
6473   [(set (match_operand:SF 0 "register_operand" "=f")
6474         (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
6475   "TARGET_FPU && !sparc_fix_ut699"
6476   "fsqrts\t%1, %0"
6477   [(set_attr "type" "fpsqrts")])
6480 ;; Arithmetic shift instructions.
6482 (define_insn "ashlsi3"
6483   [(set (match_operand:SI 0 "register_operand" "=r")
6484         (ashift:SI (match_operand:SI 1 "register_operand" "r")
6485                    (match_operand:SI 2 "arith_operand" "rI")))]
6486   ""
6488   if (GET_CODE (operands[2]) == CONST_INT)
6489     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6490   return "sll\t%1, %2, %0";
6492   [(set_attr "type" "shift")])
6494 (define_expand "ashldi3"
6495   [(set (match_operand:DI 0 "register_operand" "=r")
6496         (ashift:DI (match_operand:DI 1 "register_operand" "r")
6497                    (match_operand:SI 2 "arith_operand" "rI")))]
6498   "TARGET_ARCH64 || TARGET_V8PLUS"
6500   if (TARGET_ARCH32)
6501     {
6502       if (GET_CODE (operands[2]) == CONST_INT)
6503         FAIL;
6504       emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
6505       DONE;
6506     }
6509 (define_insn "*ashldi3_sp64"
6510   [(set (match_operand:DI 0 "register_operand" "=r")
6511         (ashift:DI (match_operand:DI 1 "register_operand" "r")
6512                    (match_operand:SI 2 "arith_operand" "rI")))]
6513   "TARGET_ARCH64"
6515   if (GET_CODE (operands[2]) == CONST_INT)
6516     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6517   return "sllx\t%1, %2, %0";
6519   [(set_attr "type" "shift")])
6521 (define_insn "ashldi3_v8plus"
6522   [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6523         (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6524                    (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6525    (clobber (match_scratch:SI 3 "=X,X,&h"))]
6526   "TARGET_V8PLUS"
6528   return output_v8plus_shift (insn ,operands, \"sllx\");
6530   [(set_attr "type" "multi")
6531    (set_attr "length" "5,5,6")])
6533 (define_insn "*cmp_ccnz_ashift_1"
6534   [(set (reg:CCNZ CC_REG)
6535         (compare:CCNZ (ashift:SI (match_operand:SI 0 "register_operand" "r")
6536                                  (const_int 1))
6537                       (const_int 0)))]
6538   ""
6539   "addcc\t%0, %0, %%g0"
6540   [(set_attr "type" "compare")])
6542 (define_insn "*cmp_ccnz_set_ashift_1"
6543   [(set (reg:CCNZ CC_REG)
6544         (compare:CCNZ (ashift:SI (match_operand:SI 1 "register_operand" "r")
6545                                  (const_int 1))
6546                       (const_int 0)))
6547    (set (match_operand:SI 0 "register_operand" "=r")
6548         (ashift:SI (match_dup 1) (const_int 1)))]
6549   ""
6550   "addcc\t%1, %1, %0"
6551   [(set_attr "type" "compare")])
6553 (define_insn "ashrsi3"
6554   [(set (match_operand:SI 0 "register_operand" "=r")
6555         (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
6556                      (match_operand:SI 2 "arith_operand" "rI")))]
6557   ""
6559   if (GET_CODE (operands[2]) == CONST_INT)
6560    operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6561   return "sra\t%1, %2, %0";
6563   [(set_attr "type" "shift")])
6565 (define_insn "*ashrsi3_extend0"
6566   [(set (match_operand:DI 0 "register_operand" "=r")
6567         (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
6568                                      (match_operand:SI 2 "arith_operand" "rI"))))]
6569   "TARGET_ARCH64"
6571   if (GET_CODE (operands[2]) == CONST_INT)
6572    operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6573   return "sra\t%1, %2, %0";
6575   [(set_attr "type" "shift")])
6577 ;; This handles the case where
6578 ;; (sign_extend:DI (ashiftrt:SI (match_operand:SI) (match_operand:SI)))
6579 ;; but combiner "simplifies" it for us.
6580 (define_insn "*ashrsi3_extend1"
6581   [(set (match_operand:DI 0 "register_operand" "=r")
6582         (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
6583                                 (const_int 32))
6584                      (match_operand:SI 2 "small_int_operand" "I")))]
6585   "TARGET_ARCH64 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64"
6587   operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
6588   return "sra\t%1, %2, %0";
6590   [(set_attr "type" "shift")])
6592 ;; This handles the case where
6593 ;; (ashiftrt:DI (sign_extend:DI (match_operand:SI)) (const_int))
6594 ;; but combiner "simplifies" it for us.
6595 (define_insn "*ashrsi3_extend2"
6596   [(set (match_operand:DI 0 "register_operand" "=r")
6597         (sign_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
6598                          (match_operand 2 "small_int_operand" "I")
6599                          (const_int 32)))]
6600   "TARGET_ARCH64 && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 32"
6602   operands[2] = GEN_INT (32 - INTVAL (operands[2]));
6603   return "sra\t%1, %2, %0";
6605   [(set_attr "type" "shift")])
6607 (define_expand "ashrdi3"
6608   [(set (match_operand:DI 0 "register_operand" "=r")
6609         (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6610                      (match_operand:SI 2 "arith_operand" "rI")))]
6611   "TARGET_ARCH64 || TARGET_V8PLUS"
6613   if (TARGET_ARCH32)
6614     {
6615       if (GET_CODE (operands[2]) == CONST_INT)
6616         FAIL;   /* prefer generic code in this case */
6617       emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
6618       DONE;
6619     }
6622 (define_insn "*ashrdi3_sp64"
6623   [(set (match_operand:DI 0 "register_operand" "=r")
6624         (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6625                      (match_operand:SI 2 "arith_operand" "rI")))]
6626   "TARGET_ARCH64"
6628   if (GET_CODE (operands[2]) == CONST_INT)
6629     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6630   return "srax\t%1, %2, %0";
6632   [(set_attr "type" "shift")])
6634 (define_insn "ashrdi3_v8plus"
6635   [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6636         (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6637                      (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6638    (clobber (match_scratch:SI 3 "=X,X,&h"))]
6639   "TARGET_V8PLUS"
6641   return output_v8plus_shift (insn, operands, \"srax\");
6643   [(set_attr "type" "multi")
6644    (set_attr "length" "5,5,6")])
6646 (define_insn "lshrsi3"
6647   [(set (match_operand:SI 0 "register_operand" "=r")
6648         (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
6649                      (match_operand:SI 2 "arith_operand" "rI")))]
6650   ""
6652   if (GET_CODE (operands[2]) == CONST_INT)
6653     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6654   return "srl\t%1, %2, %0";
6656   [(set_attr "type" "shift")])
6658 (define_insn "*lshrsi3_extend0"
6659   [(set (match_operand:DI 0 "register_operand" "=r")
6660         (zero_extend:DI
6661           (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
6662                        (match_operand:SI 2 "arith_operand" "rI"))))]
6663   "TARGET_ARCH64"
6665   if (GET_CODE (operands[2]) == CONST_INT)
6666     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6667   return "srl\t%1, %2, %0";
6669   [(set_attr "type" "shift")])
6671 ;; This handles the case where
6672 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI)))
6673 ;; but combiner "simplifies" it for us.
6674 (define_insn "*lshrsi3_extend1"
6675   [(set (match_operand:DI 0 "register_operand" "=r")
6676         (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
6677                                         (match_operand:SI 2 "arith_operand" "rI")) 0)
6678                 (match_operand 3 "const_int_operand" "")))]
6679   "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff"
6681   if (GET_CODE (operands[2]) == CONST_INT)
6682     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6683   return "srl\t%1, %2, %0";
6685   [(set_attr "type" "shift")])
6687 ;; This handles the case where
6688 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int))
6689 ;; but combiner "simplifies" it for us.
6690 (define_insn "*lshrsi3_extend2"
6691   [(set (match_operand:DI 0 "register_operand" "=r")
6692         (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
6693                          (match_operand 2 "small_int_operand" "I")
6694                          (const_int 32)))]
6695   "TARGET_ARCH64 && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 32"
6697   operands[2] = GEN_INT (32 - INTVAL (operands[2]));
6698   return "srl\t%1, %2, %0";
6700   [(set_attr "type" "shift")])
6702 (define_expand "lshrdi3"
6703   [(set (match_operand:DI 0 "register_operand" "=r")
6704         (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6705                      (match_operand:SI 2 "arith_operand" "rI")))]
6706   "TARGET_ARCH64 || TARGET_V8PLUS"
6708   if (TARGET_ARCH32)
6709     {
6710       if (GET_CODE (operands[2]) == CONST_INT)
6711         FAIL;
6712       emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
6713       DONE;
6714     }
6717 (define_insn "*lshrdi3_sp64"
6718   [(set (match_operand:DI 0 "register_operand" "=r")
6719         (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6720                      (match_operand:SI 2 "arith_operand" "rI")))]
6721   "TARGET_ARCH64"
6723   if (GET_CODE (operands[2]) == CONST_INT)
6724     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6725   return "srlx\t%1, %2, %0";
6727   [(set_attr "type" "shift")])
6729 (define_insn "lshrdi3_v8plus"
6730   [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6731         (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6732                      (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6733    (clobber (match_scratch:SI 3 "=X,X,&h"))]
6734   "TARGET_V8PLUS"
6736   return output_v8plus_shift (insn, operands, \"srlx\");
6738   [(set_attr "type" "multi")
6739    (set_attr "length" "5,5,6")])
6741 (define_insn ""
6742   [(set (match_operand:SI 0 "register_operand" "=r")
6743         (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6744                                              (const_int 32)) 4)
6745                      (match_operand:SI 2 "small_int_operand" "I")))]
6746   "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6748   operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6749   return "srax\t%1, %2, %0";
6751   [(set_attr "type" "shift")])
6753 (define_insn ""
6754   [(set (match_operand:SI 0 "register_operand" "=r")
6755         (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6756                                              (const_int 32)) 4)
6757                      (match_operand:SI 2 "small_int_operand" "I")))]
6758   "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6760   operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6761   return "srlx\t%1, %2, %0";
6763   [(set_attr "type" "shift")])
6765 (define_insn ""
6766   [(set (match_operand:SI 0 "register_operand" "=r")
6767         (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6768                                              (match_operand:SI 2 "small_int_operand" "I")) 4)
6769                      (match_operand:SI 3 "small_int_operand" "I")))]
6770   "TARGET_ARCH64
6771    && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6772    && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6773    && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6775   operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6777   return "srax\t%1, %2, %0";
6779   [(set_attr "type" "shift")])
6781 (define_insn ""
6782   [(set (match_operand:SI 0 "register_operand" "=r")
6783         (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6784                                              (match_operand:SI 2 "small_int_operand" "I")) 4)
6785                      (match_operand:SI 3 "small_int_operand" "I")))]
6786   "TARGET_ARCH64
6787    && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6788    && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6789    && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6791   operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6793   return "srlx\t%1, %2, %0";
6795   [(set_attr "type" "shift")])
6798 ;; Unconditional and other jump instructions.
6800 (define_expand "jump"
6801   [(set (pc) (label_ref (match_operand 0 "" "")))]
6802   "")
6804 (define_insn "*jump_ubranch"
6805   [(set (pc) (label_ref (match_operand 0 "" "")))]
6806   "!TARGET_CBCOND"
6808   return output_ubranch (operands[0], insn);
6810   [(set_attr "type" "uncond_branch")])
6812 (define_insn "*jump_cbcond"
6813   [(set (pc) (label_ref (match_operand 0 "" "")))]
6814   "TARGET_CBCOND"
6816   return output_ubranch (operands[0], insn);
6818   [(set_attr "type" "uncond_cbcond")])
6820 (define_expand "tablejump"
6821   [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
6822               (use (label_ref (match_operand 1 "" "")))])]
6823   ""
6825   gcc_assert (GET_MODE (operands[0]) == CASE_VECTOR_MODE);
6827   /* In pic mode, our address differences are against the base of the
6828      table.  Add that base value back in; CSE ought to be able to combine
6829      the two address loads.  */
6830   if (flag_pic)
6831     {
6832       rtx tmp, tmp2;
6833       tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
6834       tmp2 = operands[0];
6835       if (CASE_VECTOR_MODE != Pmode)
6836         tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
6837       tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
6838       operands[0] = memory_address (Pmode, tmp);
6839     }
6842 (define_insn "*tablejump_sp32"
6843   [(set (pc) (match_operand:SI 0 "address_operand" "p"))
6844    (use (label_ref (match_operand 1 "" "")))]
6845   "TARGET_ARCH32"
6846   "jmp\t%a0%#"
6847   [(set_attr "type" "uncond_branch")])
6849 (define_insn "*tablejump_sp64"
6850   [(set (pc) (match_operand:DI 0 "address_operand" "p"))
6851    (use (label_ref (match_operand 1 "" "")))]
6852   "TARGET_ARCH64"
6853   "jmp\t%a0%#"
6854   [(set_attr "type" "uncond_branch")])
6857 ;; Jump to subroutine instructions.
6859 (define_expand "call"
6860   ;; Note that this expression is not used for generating RTL.
6861   ;; All the RTL is generated explicitly below.
6862   [(call (match_operand 0 "call_operand" "")
6863          (match_operand 3 "" "i"))]
6864   ;; operands[2] is next_arg_register
6865   ;; operands[3] is struct_value_size_rtx.
6866   ""
6868   rtx fn_rtx;
6870   gcc_assert (MEM_P (operands[0]) && GET_MODE (operands[0]) == FUNCTION_MODE);
6872   gcc_assert (GET_CODE (operands[3]) == CONST_INT);
6874   if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
6875     {
6876       /* This is really a PIC sequence.  We want to represent
6877          it as a funny jump so its delay slots can be filled. 
6879          ??? But if this really *is* a CALL, will not it clobber the
6880          call-clobbered registers?  We lose this if it is a JUMP_INSN.
6881          Why cannot we have delay slots filled if it were a CALL?  */
6883       /* We accept negative sizes for untyped calls.  */
6884       if (TARGET_ARCH32 && INTVAL (operands[3]) != 0)
6885         emit_jump_insn
6886           (gen_rtx_PARALLEL
6887            (VOIDmode,
6888             gen_rtvec (3,
6889                        gen_rtx_SET (pc_rtx, XEXP (operands[0], 0)),
6890                        operands[3],
6891                        gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6892       else
6893         emit_jump_insn
6894           (gen_rtx_PARALLEL
6895            (VOIDmode,
6896             gen_rtvec (2,
6897                        gen_rtx_SET (pc_rtx, XEXP (operands[0], 0)),
6898                        gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6899       goto finish_call;
6900     }
6902   fn_rtx = operands[0];
6904   /* We accept negative sizes for untyped calls.  */
6905   if (TARGET_ARCH32 && INTVAL (operands[3]) != 0)
6906     sparc_emit_call_insn
6907       (gen_rtx_PARALLEL
6908        (VOIDmode,
6909         gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6910                    operands[3],
6911                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6912        XEXP (fn_rtx, 0));
6913   else
6914     sparc_emit_call_insn
6915       (gen_rtx_PARALLEL
6916        (VOIDmode,
6917         gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6918                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6919        XEXP (fn_rtx, 0));
6921  finish_call:
6923   DONE;
6926 ;; We can't use the same pattern for these two insns, because then registers
6927 ;; in the address may not be properly reloaded.
6929 (define_insn "*call_address_sp32"
6930   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6931          (match_operand 1 "" ""))
6932    (clobber (reg:SI O7_REG))]
6933   ;;- Do not use operand 1 for most machines.
6934   "TARGET_ARCH32"
6935   "call\t%a0, %1%#"
6936   [(set_attr "type" "call")])
6938 (define_insn "*call_symbolic_sp32"
6939   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6940          (match_operand 1 "" ""))
6941    (clobber (reg:SI O7_REG))]
6942   ;;- Do not use operand 1 for most machines.
6943   "TARGET_ARCH32"
6944   "call\t%a0, %1%#"
6945   [(set_attr "type" "call")])
6947 (define_insn "*call_address_sp64"
6948   [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
6949          (match_operand 1 "" ""))
6950    (clobber (reg:DI O7_REG))]
6951   ;;- Do not use operand 1 for most machines.
6952   "TARGET_ARCH64"
6953   "call\t%a0, %1%#"
6954   [(set_attr "type" "call")])
6956 (define_insn "*call_symbolic_sp64"
6957   [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6958          (match_operand 1 "" ""))
6959    (clobber (reg:DI O7_REG))]
6960   ;;- Do not use operand 1 for most machines.
6961   "TARGET_ARCH64"
6962   "call\t%a0, %1%#"
6963   [(set_attr "type" "call")])
6965 ;; This is a call that wants a structure value.
6966 ;; There is no such critter for v9 (??? we may need one anyway).
6967 (define_insn "*call_address_struct_value_sp32"
6968   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6969          (match_operand 1 "" ""))
6970    (match_operand 2 "immediate_operand" "")
6971    (clobber (reg:SI O7_REG))]
6972   ;;- Do not use operand 1 for most machines.
6973   "TARGET_ARCH32 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6975   operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6976   return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6978   [(set_attr "type" "call_no_delay_slot")
6979    (set_attr "length" "3")])
6981 ;; This is a call that wants a structure value.
6982 ;; There is no such critter for v9 (??? we may need one anyway).
6983 (define_insn "*call_symbolic_struct_value_sp32"
6984   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6985          (match_operand 1 "" ""))
6986    (match_operand 2 "immediate_operand" "")
6987    (clobber (reg:SI O7_REG))]
6988   ;;- Do not use operand 1 for most machines.
6989   "TARGET_ARCH32 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6991   operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6992   return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6994   [(set_attr "type" "call_no_delay_slot")
6995    (set_attr "length" "3")])
6997 ;; This is a call that may want a structure value.  This is used for
6998 ;; untyped_calls.
6999 (define_insn "*call_address_untyped_struct_value_sp32"
7000   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
7001          (match_operand 1 "" ""))
7002    (match_operand 2 "immediate_operand" "")
7003    (clobber (reg:SI O7_REG))]
7004   ;;- Do not use operand 1 for most machines.
7005   "TARGET_ARCH32 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7006   "call\t%a0, %1\n\t nop\n\tnop"
7007   [(set_attr "type" "call_no_delay_slot")
7008    (set_attr "length" "3")])
7010 ;; This is a call that may want a structure value.  This is used for
7011 ;; untyped_calls.
7012 (define_insn "*call_symbolic_untyped_struct_value_sp32"
7013   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7014          (match_operand 1 "" ""))
7015    (match_operand 2 "immediate_operand" "")
7016    (clobber (reg:SI O7_REG))]
7017   ;;- Do not use operand 1 for most machines.
7018   "TARGET_ARCH32 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
7019   "call\t%a0, %1\n\t nop\n\tnop"
7020   [(set_attr "type" "call_no_delay_slot")
7021    (set_attr "length" "3")])
7023 (define_expand "call_value"
7024   ;; Note that this expression is not used for generating RTL.
7025   ;; All the RTL is generated explicitly below.
7026   [(set (match_operand 0 "register_operand" "=rf")
7027         (call (match_operand 1 "" "")
7028               (match_operand 4 "" "")))]
7029   ;; operand 2 is stack_size_rtx
7030   ;; operand 3 is next_arg_register
7031   ""
7033   rtx fn_rtx;
7034   rtvec vec;
7036   gcc_assert (MEM_P (operands[1]) && GET_MODE (operands[1]) == FUNCTION_MODE);
7038   fn_rtx = operands[1];
7040   vec = gen_rtvec (2,
7041                    gen_rtx_SET (operands[0],
7042                                 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
7043                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
7045   sparc_emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec), XEXP (fn_rtx, 0));
7047   DONE;
7050 (define_insn "*call_value_address_sp32"
7051   [(set (match_operand 0 "" "=rf")
7052         (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
7053               (match_operand 2 "" "")))
7054    (clobber (reg:SI O7_REG))]
7055   ;;- Do not use operand 2 for most machines.
7056   "TARGET_ARCH32"
7057   "call\t%a1, %2%#"
7058   [(set_attr "type" "call")])
7060 (define_insn "*call_value_symbolic_sp32"
7061   [(set (match_operand 0 "" "=rf")
7062         (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7063               (match_operand 2 "" "")))
7064    (clobber (reg:SI O7_REG))]
7065   ;;- Do not use operand 2 for most machines.
7066   "TARGET_ARCH32"
7067   "call\t%a1, %2%#"
7068   [(set_attr "type" "call")])
7070 (define_insn "*call_value_address_sp64"
7071   [(set (match_operand 0 "" "")
7072         (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
7073               (match_operand 2 "" "")))
7074    (clobber (reg:DI O7_REG))]
7075   ;;- Do not use operand 2 for most machines.
7076   "TARGET_ARCH64"
7077   "call\t%a1, %2%#"
7078   [(set_attr "type" "call")])
7080 (define_insn "*call_value_symbolic_sp64"
7081   [(set (match_operand 0 "" "")
7082         (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
7083               (match_operand 2 "" "")))
7084    (clobber (reg:DI O7_REG))]
7085   ;;- Do not use operand 2 for most machines.
7086   "TARGET_ARCH64"
7087   "call\t%a1, %2%#"
7088   [(set_attr "type" "call")])
7090 (define_expand "untyped_call"
7091   [(parallel [(call (match_operand 0 "" "")
7092                     (const_int 0))
7093               (match_operand:BLK 1 "memory_operand" "")
7094               (match_operand 2 "" "")])]
7095   ""
7097   rtx valreg1 = gen_rtx_REG (DImode, 8);
7098   rtx result = operands[1];
7100   /* Pass constm1 to indicate that it may expect a structure value, but
7101      we don't know what size it is.  */
7102   emit_call_insn (gen_call (operands[0], const0_rtx, NULL, constm1_rtx));
7104   /* Save the function value registers.  */
7105   emit_move_insn (adjust_address (result, DImode, 0), valreg1);
7106   if (TARGET_FPU)
7107     {
7108       rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
7109       emit_move_insn (adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8),
7110                       valreg2);
7111     }
7113   /* The optimizer does not know that the call sets the function value
7114      registers we stored in the result block.  We avoid problems by
7115      claiming that all hard registers are used and clobbered at this
7116      point.  */
7117   emit_insn (gen_blockage ());
7119   DONE;
7123 ;;  Tail call instructions.
7125 (define_expand "sibcall"
7126   [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
7127               (return)])]
7128   ""
7129   "")
7131 (define_insn "*sibcall_symbolic_sp32"
7132   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
7133          (match_operand 1 "" ""))
7134    (return)]
7135   "TARGET_ARCH32"
7137   return output_sibcall(insn, operands[0]);
7139   [(set_attr "type" "sibcall")])
7141 (define_insn "*sibcall_symbolic_sp64"
7142   [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
7143          (match_operand 1 "" ""))
7144    (return)]
7145   "TARGET_ARCH64"
7147   return output_sibcall(insn, operands[0]);
7149   [(set_attr "type" "sibcall")])
7151 (define_expand "sibcall_value"
7152   [(parallel [(set (match_operand 0 "register_operand" "=rf")
7153                 (call (match_operand 1 "" "") (const_int 0)))
7154               (return)])]
7155   ""
7156   "")
7158 (define_insn "*sibcall_value_symbolic_sp32"
7159   [(set (match_operand 0 "" "=rf")
7160         (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
7161               (match_operand 2 "" "")))
7162    (return)]
7163   "TARGET_ARCH32"
7165   return output_sibcall(insn, operands[1]);
7167   [(set_attr "type" "sibcall")])
7169 (define_insn "*sibcall_value_symbolic_sp64"
7170   [(set (match_operand 0 "" "")
7171         (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
7172               (match_operand 2 "" "")))
7173    (return)]
7174   "TARGET_ARCH64"
7176   return output_sibcall(insn, operands[1]);
7178   [(set_attr "type" "sibcall")])
7181 ;; Special instructions.
7183 (define_expand "prologue"
7184   [(const_int 0)]
7185   ""
7187   if (TARGET_FLAT)
7188     sparc_flat_expand_prologue ();
7189   else
7190     sparc_expand_prologue ();
7191   DONE;
7194 ;; The "register window save" insn is modelled as follows.  The dwarf2
7195 ;; information is manually added in emit_window_save.
7197 (define_insn "window_save"
7198   [(unspec_volatile
7199         [(match_operand 0 "arith_operand" "rI")]
7200         UNSPECV_SAVEW)]
7201   "!TARGET_FLAT"
7202   "save\t%%sp, %0, %%sp"
7203   [(set_attr "type" "savew")])
7205 (define_expand "epilogue"
7206   [(return)]
7207   ""
7209   if (TARGET_FLAT)
7210     sparc_flat_expand_epilogue (false);
7211   else
7212     sparc_expand_epilogue (false);
7215 (define_expand "sibcall_epilogue"
7216   [(return)]
7217   ""
7219   if (TARGET_FLAT)
7220     sparc_flat_expand_epilogue (false);
7221   else
7222     sparc_expand_epilogue (false);
7223   DONE;
7226 (define_expand "eh_return"
7227   [(use (match_operand 0 "general_operand" ""))]
7228   ""
7230   emit_move_insn (gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM), operands[0]);
7231   emit_jump_insn (gen_eh_return_internal ());
7232   emit_barrier ();
7233   DONE;
7236 (define_insn_and_split "eh_return_internal"
7237   [(eh_return)]
7238   ""
7239   "#"
7240   "epilogue_completed"
7241   [(return)]
7243   if (TARGET_FLAT)
7244     sparc_flat_expand_epilogue (true);
7245   else
7246     sparc_expand_epilogue (true);
7249 (define_expand "return"
7250   [(return)]
7251   "sparc_can_use_return_insn_p ()"
7253   if (cfun->calls_alloca)
7254     emit_insn (gen_frame_blockage ());
7257 (define_insn "*return_internal"
7258   [(return)]
7259   ""
7261   return output_return (insn);
7263   [(set_attr "type" "return")
7264    (set (attr "length")
7265         (cond [(eq_attr "calls_eh_return" "true")
7266                  (if_then_else (eq_attr "delayed_branch" "true")
7267                                 (if_then_else (ior (eq_attr "isa" "v9")
7268                                                    (eq_attr "flat" "true"))
7269                                         (const_int 2)
7270                                         (const_int 3))
7271                                 (if_then_else (eq_attr "flat" "true")
7272                                         (const_int 3)
7273                                         (const_int 4)))
7274                (ior (eq_attr "leaf_function" "true") (eq_attr "flat" "true"))
7275                  (if_then_else (eq_attr "empty_delay_slot" "true")
7276                                (const_int 2)
7277                                (const_int 1))
7278                (eq_attr "empty_delay_slot" "true")
7279                  (if_then_else (eq_attr "delayed_branch" "true")
7280                                (const_int 2)
7281                                (const_int 3))
7282               ] (const_int 1)))])
7284 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
7285 ;; all of memory.  This blocks insns from being moved across this point.
7287 (define_insn "blockage"
7288   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7289   ""
7290   ""
7291   [(set_attr "length" "0")])
7293 ;; Do not schedule instructions accessing memory before this point.
7295 (define_expand "frame_blockage"
7296   [(set (match_dup 0)
7297         (unspec:BLK [(match_dup 1)] UNSPEC_FRAME_BLOCKAGE))]
7298   ""
7300   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
7301   MEM_VOLATILE_P (operands[0]) = 1;
7302   operands[1] = stack_pointer_rtx;
7305 (define_insn "*frame_blockage<P:mode>"
7306   [(set (match_operand:BLK 0 "" "")
7307         (unspec:BLK [(match_operand:P 1 "" "")] UNSPEC_FRAME_BLOCKAGE))]
7308   ""
7309   ""
7310   [(set_attr "length" "0")])
7312 (define_expand "probe_stack"
7313   [(set (match_operand 0 "memory_operand" "") (const_int 0))]
7314   ""
7316   operands[0]
7317     = adjust_address (operands[0], GET_MODE (operands[0]), SPARC_STACK_BIAS);
7320 (define_insn "probe_stack_range<P:mode>"
7321   [(set (match_operand:P 0 "register_operand" "=r")
7322         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
7323                             (match_operand:P 2 "register_operand" "r")]
7324                             UNSPECV_PROBE_STACK_RANGE))]
7325   ""
7327   return output_probe_stack_range (operands[0], operands[2]);
7329   [(set_attr "type" "multi")])
7331 ;; Prepare to return any type including a structure value.
7333 (define_expand "untyped_return"
7334   [(match_operand:BLK 0 "memory_operand" "")
7335    (match_operand 1 "" "")]
7336   ""
7338   rtx valreg1 = gen_rtx_REG (DImode, 24);
7339   rtx result = operands[0];
7341   if (TARGET_ARCH32)
7342     {
7343       rtx rtnreg = gen_rtx_REG (SImode, RETURN_ADDR_REGNUM);
7344       rtx value = gen_reg_rtx (SImode);
7346       /* Fetch the instruction where we will return to and see if it's an unimp
7347          instruction (the most significant 10 bits will be zero).  If so,
7348          update the return address to skip the unimp instruction.  */
7349       emit_move_insn (value,
7350                       gen_rtx_MEM (SImode, plus_constant (SImode, rtnreg, 8)));
7351       emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
7352       emit_insn (gen_update_return (rtnreg, value));
7353     }
7355   /* Reload the function value registers.
7356      Put USE insns before the return.  */
7357   emit_move_insn (valreg1, adjust_address (result, DImode, 0));
7358   emit_use (valreg1);
7360   if (TARGET_FPU)
7361     {
7362       rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
7363       emit_move_insn (valreg2,
7364                       adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
7365       emit_use (valreg2);
7366     }
7368   /* Construct the return.  */
7369   expand_naked_return ();
7371   DONE;
7374 ;; Adjust the return address conditionally. If the value of op1 is equal
7375 ;; to all zero then adjust the return address i.e. op0 = op0 + 4.
7376 ;; This is technically *half* the check required by the 32-bit SPARC
7377 ;; psABI. This check only ensures that an "unimp" insn was written by
7378 ;; the caller, but doesn't check to see if the expected size matches
7379 ;; (this is encoded in the 12 lower bits). This check is obsolete and
7380 ;; only used by the above code "untyped_return".
7382 (define_insn "update_return"
7383   [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
7384                (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
7385   "TARGET_ARCH32"
7387   if (flag_delayed_branch)
7388     return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
7389   else
7390     return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
7392   [(set (attr "type") (const_string "multi"))
7393    (set (attr "length")
7394         (if_then_else (eq_attr "delayed_branch" "true")
7395                       (const_int 3)
7396                       (const_int 4)))])
7398 (define_insn "nop"
7399   [(const_int 0)]
7400   ""
7401   "nop")
7403 (define_expand "indirect_jump"
7404   [(set (pc) (match_operand 0 "address_operand" "p"))]
7405   ""
7406   "")
7408 (define_insn "*branch_sp32"
7409   [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
7410   "TARGET_ARCH32"
7411  "jmp\t%a0%#"
7412  [(set_attr "type" "uncond_branch")])
7414 (define_insn "*branch_sp64"
7415   [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
7416   "TARGET_ARCH64"
7417   "jmp\t%a0%#"
7418   [(set_attr "type" "uncond_branch")])
7420 (define_expand "save_stack_nonlocal"
7421   [(set (match_operand 0 "memory_operand" "")
7422         (match_operand 1 "register_operand" ""))
7423    (set (match_dup 2) (match_dup 3))]
7424   ""
7426   operands[0] = adjust_address (operands[0], Pmode, 0);
7427   operands[2] = adjust_address (operands[0], Pmode, GET_MODE_SIZE (Pmode));
7428   operands[3] = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
7431 (define_expand "restore_stack_nonlocal"
7432   [(set (match_operand 0 "register_operand" "")
7433         (match_operand 1 "memory_operand" ""))]
7434   ""
7436   operands[1] = adjust_address (operands[1], Pmode, 0);
7439 (define_expand "nonlocal_goto"
7440   [(match_operand 0 "general_operand" "")
7441    (match_operand 1 "general_operand" "")
7442    (match_operand 2 "memory_operand" "")
7443    (match_operand 3 "memory_operand" "")]
7444   ""
7446   rtx i7 = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
7447   rtx r_label = copy_to_reg (operands[1]);
7448   rtx r_sp = adjust_address (operands[2], Pmode, 0);
7449   rtx r_fp = operands[3];
7450   rtx r_i7 = adjust_address (operands[2], Pmode, GET_MODE_SIZE (Pmode));
7452   /* We need to flush all the register windows so that their contents will
7453      be re-synchronized by the restore insn of the target function.  */
7454   if (!TARGET_FLAT)
7455     emit_insn (gen_flush_register_windows ());
7457   emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
7458   emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
7460   /* Restore frame pointer for containing function.  */
7461   emit_move_insn (hard_frame_pointer_rtx, r_fp);
7462   emit_stack_restore (SAVE_NONLOCAL, r_sp);
7463   emit_move_insn (i7, r_i7);
7465   /* USE of hard_frame_pointer_rtx added for consistency;
7466      not clear if really needed.  */
7467   emit_use (hard_frame_pointer_rtx);
7468   emit_use (stack_pointer_rtx);
7469   emit_use (i7);
7471   emit_jump_insn (gen_indirect_jump (r_label));
7472   emit_barrier ();
7473   DONE;
7476 (define_expand "builtin_setjmp_receiver"
7477   [(label_ref (match_operand 0 "" ""))]
7478   "TARGET_VXWORKS_RTP && flag_pic"
7480   load_got_register ();
7481   DONE;
7484 ;; Special insn to flush register windows.
7486 (define_insn "flush_register_windows"
7487   [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
7488   ""
7490   return TARGET_V9 ? "flushw" : "ta\t3";
7492   [(set_attr "type" "flushw")])
7494 ;; Special pattern for the FLUSH instruction.
7496 (define_insn "flush<P:mode>"
7497   [(unspec_volatile [(match_operand:P 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7498   ""
7500   return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0";
7502   [(set_attr "type" "iflush")])
7504 ;; Special insns to load and store the 32-bit FP Status Register.
7506 (define_insn "ldfsr"
7507   [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_LDFSR)]
7508   "TARGET_FPU"
7509   "ld\t%0, %%fsr"
7510   [(set_attr "type" "load")
7511    (set_attr "subtype" "regular")])
7513 (define_insn "stfsr"
7514   [(set (match_operand:SI 0 "memory_operand" "=m")
7515         (unspec_volatile:SI [(const_int 0)] UNSPECV_STFSR))]
7516   "TARGET_FPU"
7517   "st\t%%fsr, %0"
7518   [(set_attr "type" "store")])
7521 ;; Find first set instructions.
7523 (define_expand "popcountdi2"
7524   [(set (match_operand:DI 0 "register_operand" "")
7525         (popcount:DI (match_operand:DI 1 "register_operand" "")))]
7526   "TARGET_POPC"
7528   if (TARGET_ARCH32)
7529     {
7530       emit_insn (gen_popcountdi_v8plus (operands[0], operands[1]));
7531       DONE;
7532     }
7535 (define_insn "*popcountdi_sp64"
7536   [(set (match_operand:DI 0 "register_operand" "=r")
7537         (popcount:DI (match_operand:DI 1 "register_operand" "r")))]
7538   "TARGET_POPC && TARGET_ARCH64"
7539   "popc\t%1, %0")
7541 (define_insn "popcountdi_v8plus"
7542   [(set (match_operand:DI 0 "register_operand" "=r")
7543         (popcount:DI (match_operand:DI 1 "register_operand" "r")))
7544    (clobber (match_scratch:SI 2 "=&h"))]
7545   "TARGET_POPC && TARGET_ARCH32"
7547   if (sparc_check_64 (operands[1], insn) <= 0)
7548     output_asm_insn ("srl\t%L1, 0, %L1", operands);
7549   return "sllx\t%H1, 32, %2\n\tor\t%L1, %2, %2\n\tpopc\t%2, %L0\n\tclr\t%H0";
7551   [(set_attr "type" "multi")
7552    (set_attr "length" "5")])
7554 (define_expand "popcountsi2"
7555   [(set (match_dup 2)
7556         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
7557    (set (match_operand:SI 0 "register_operand" "")
7558         (truncate:SI (popcount:DI (match_dup 2))))]
7559   "TARGET_POPC"
7561   if (TARGET_ARCH32)
7562     {
7563       emit_insn (gen_popcountsi_v8plus (operands[0], operands[1]));
7564       DONE;
7565     }
7566   else
7567     operands[2] = gen_reg_rtx (DImode);
7570 (define_insn "*popcountsi_sp64"
7571   [(set (match_operand:SI 0 "register_operand" "=r")
7572         (truncate:SI
7573           (popcount:DI (match_operand:DI 1 "register_operand" "r"))))]
7574   "TARGET_POPC && TARGET_ARCH64"
7575   "popc\t%1, %0")
7577 (define_insn "popcountsi_v8plus"
7578   [(set (match_operand:SI 0 "register_operand" "=r")
7579         (popcount:SI (match_operand:SI 1 "register_operand" "r")))]
7580   "TARGET_POPC && TARGET_ARCH32"
7582   if (sparc_check_64 (operands[1], insn) <= 0)
7583     output_asm_insn ("srl\t%1, 0, %1", operands);
7584   return "popc\t%1, %0";
7586   [(set_attr "type" "multi")
7587    (set_attr "length" "2")])
7589 (define_expand "clzdi2"
7590   [(set (match_operand:DI 0 "register_operand" "")
7591         (clz:DI (match_operand:DI 1 "register_operand" "")))]
7592   "TARGET_VIS3"
7594   if (TARGET_ARCH32)
7595     {
7596       emit_insn (gen_clzdi_v8plus (operands[0], operands[1]));
7597       DONE;
7598     }
7601 (define_insn "*clzdi_sp64"
7602   [(set (match_operand:DI 0 "register_operand" "=r")
7603         (clz:DI (match_operand:DI 1 "register_operand" "r")))]
7604   "TARGET_VIS3 && TARGET_ARCH64"
7605   "lzd\t%1, %0"
7606   [(set_attr "type" "lzd")])
7608 (define_insn "clzdi_v8plus"
7609   [(set (match_operand:DI 0 "register_operand" "=r")
7610         (clz:DI (match_operand:DI 1 "register_operand" "r")))
7611    (clobber (match_scratch:SI 2 "=&h"))]
7612   "TARGET_VIS3 && TARGET_ARCH32"
7614   if (sparc_check_64 (operands[1], insn) <= 0)
7615     output_asm_insn ("srl\t%L1, 0, %L1", operands);
7616   return "sllx\t%H1, 32, %2\n\tor\t%L1, %2, %2\n\tlzd\t%2, %L0\n\tclr\t%H0";
7618   [(set_attr "type" "multi")
7619    (set_attr "length" "5")])
7621 (define_expand "clzsi2"
7622   [(set (match_dup 2)
7623         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
7624    (set (match_dup 3)
7625         (truncate:SI (clz:DI (match_dup 2))))
7626    (set (match_operand:SI 0 "register_operand" "")
7627         (minus:SI (match_dup 3) (const_int 32)))]
7628   "TARGET_VIS3"
7630   if (TARGET_ARCH32)
7631     {
7632       emit_insn (gen_clzsi_v8plus (operands[0], operands[1]));
7633       DONE;
7634     }
7635   else
7636     {
7637       operands[2] = gen_reg_rtx (DImode);
7638       operands[3] = gen_reg_rtx (SImode);
7639     }
7642 (define_insn "*clzsi_sp64"
7643   [(set (match_operand:SI 0 "register_operand" "=r")
7644         (truncate:SI
7645           (clz:DI (match_operand:DI 1 "register_operand" "r"))))]
7646   "TARGET_VIS3 && TARGET_ARCH64"
7647   "lzd\t%1, %0"
7648   [(set_attr "type" "lzd")])
7650 (define_insn "clzsi_v8plus"
7651   [(set (match_operand:SI 0 "register_operand" "=r")
7652         (clz:SI (match_operand:SI 1 "register_operand" "r")))]
7653   "TARGET_VIS3 && TARGET_ARCH32"
7655   if (sparc_check_64 (operands[1], insn) <= 0)
7656     output_asm_insn ("srl\t%1, 0, %1", operands);
7657   return "lzd\t%1, %0\n\tsub\t%0, 32, %0";
7659   [(set_attr "type" "multi")
7660    (set_attr "length" "3")])
7663 ;; Peepholes go at the end.
7665 ;; Optimize consecutive loads or stores into ldd and std when possible.
7666 ;; The conditions in which we do this are very restricted and are 
7667 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
7669 (define_peephole2
7670   [(set (match_operand:SI 0 "memory_operand" "")
7671       (const_int 0))
7672    (set (match_operand:SI 1 "memory_operand" "")
7673       (const_int 0))]
7674   "TARGET_V9
7675    && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
7676   [(set (match_dup 0) (const_int 0))]
7678   operands[0] = widen_mem_for_ldd_peep (operands[0], operands[1], DImode);
7681 (define_peephole2
7682   [(set (match_operand:SI 0 "memory_operand" "")
7683       (const_int 0))
7684    (set (match_operand:SI 1 "memory_operand" "")
7685       (const_int 0))]
7686   "TARGET_V9
7687    && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
7688   [(set (match_dup 1) (const_int 0))]
7690   operands[1] = widen_mem_for_ldd_peep (operands[1], operands[0], DImode);
7693 (define_peephole2
7694   [(set (match_operand:SI 0 "register_operand" "")
7695         (match_operand:SI 1 "memory_operand" ""))
7696    (set (match_operand:SI 2 "register_operand" "")
7697         (match_operand:SI 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], DImode);
7703   operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
7706 (define_peephole2
7707   [(set (match_operand:SI 0 "memory_operand" "")
7708         (match_operand:SI 1 "register_operand" ""))
7709    (set (match_operand:SI 2 "memory_operand" "")
7710         (match_operand:SI 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], DImode);
7716   operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));
7719 (define_peephole2
7720   [(set (match_operand:SF 0 "register_operand" "")
7721         (match_operand:SF 1 "memory_operand" ""))
7722    (set (match_operand:SF 2 "register_operand" "")
7723         (match_operand:SF 3 "memory_operand" ""))]
7724   "registers_ok_for_ldd_peep (operands[0], operands[2]) 
7725    && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
7726   [(set (match_dup 0) (match_dup 1))]
7728   operands[1] = widen_mem_for_ldd_peep (operands[1], operands[3], DFmode);
7729   operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));
7732 (define_peephole2
7733   [(set (match_operand:SF 0 "memory_operand" "")
7734         (match_operand:SF 1 "register_operand" ""))
7735    (set (match_operand:SF 2 "memory_operand" "")
7736         (match_operand:SF 3 "register_operand" ""))]
7737   "registers_ok_for_ldd_peep (operands[1], operands[3]) 
7738   && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7739   [(set (match_dup 0) (match_dup 1))]
7741   operands[0] = widen_mem_for_ldd_peep (operands[0], operands[2], DFmode);
7742   operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));
7745 (define_peephole2
7746   [(set (match_operand:SI 0 "register_operand" "")
7747         (match_operand:SI 1 "memory_operand" ""))
7748    (set (match_operand:SI 2 "register_operand" "")
7749         (match_operand:SI 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], DImode);
7755   operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));
7758 (define_peephole2
7759   [(set (match_operand:SI 0 "memory_operand" "")
7760         (match_operand:SI 1 "register_operand" ""))
7761    (set (match_operand:SI 2 "memory_operand" "")
7762         (match_operand:SI 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], DImode);
7768   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
7771 (define_peephole2
7772   [(set (match_operand:SF 0 "register_operand" "")
7773         (match_operand:SF 1 "memory_operand" ""))
7774    (set (match_operand:SF 2 "register_operand" "")
7775         (match_operand:SF 3 "memory_operand" ""))]
7776   "registers_ok_for_ldd_peep (operands[2], operands[0]) 
7777   && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
7778   [(set (match_dup 2) (match_dup 3))]
7780   operands[3] = widen_mem_for_ldd_peep (operands[3], operands[1], DFmode);
7781   operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));
7784 (define_peephole2
7785   [(set (match_operand:SF 0 "memory_operand" "")
7786         (match_operand:SF 1 "register_operand" ""))
7787    (set (match_operand:SF 2 "memory_operand" "")
7788         (match_operand:SF 3 "register_operand" ""))]
7789   "registers_ok_for_ldd_peep (operands[3], operands[1]) 
7790   && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
7791   [(set (match_dup 2) (match_dup 3))]
7793   operands[2] = widen_mem_for_ldd_peep (operands[2], operands[0], DFmode);
7794   operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));
7797 ;; Optimize the case of following a reg-reg move with a test
7798 ;; of reg just moved.  Don't allow floating point regs for operand 0 or 1.
7799 ;; This can result from a float to fix conversion.
7801 (define_peephole2
7802   [(set (match_operand:SI 0 "register_operand" "")
7803         (match_operand:SI 1 "register_operand" ""))
7804    (set (reg:CC CC_REG)
7805         (compare:CC (match_operand:SI 2 "register_operand" "")
7806                     (const_int 0)))]
7807   "(rtx_equal_p (operands[2], operands[0])
7808     || rtx_equal_p (operands[2], operands[1]))
7809     && !SPARC_FP_REG_P (REGNO (operands[0]))
7810     && !SPARC_FP_REG_P (REGNO (operands[1]))"
7811   [(parallel [(set (match_dup 0) (match_dup 1))
7812               (set (reg:CC CC_REG)
7813                    (compare:CC (match_dup 1) (const_int 0)))])]
7814   "")
7816 (define_peephole2
7817   [(set (match_operand:DI 0 "register_operand" "")
7818         (match_operand:DI 1 "register_operand" ""))
7819    (set (reg:CCX CC_REG)
7820         (compare:CCX (match_operand:DI 2 "register_operand" "")
7821                     (const_int 0)))]
7822   "TARGET_ARCH64
7823    && (rtx_equal_p (operands[2], operands[0])
7824        || rtx_equal_p (operands[2], operands[1]))
7825    && !SPARC_FP_REG_P (REGNO (operands[0]))
7826    && !SPARC_FP_REG_P (REGNO (operands[1]))"
7827   [(parallel [(set (match_dup 0) (match_dup 1))
7828               (set (reg:CCX CC_REG)
7829                    (compare:CCX (match_dup 1) (const_int 0)))])]
7830   "")
7833 ;; Prefetch instructions.
7835 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point
7836 ;; register file, if it hits the prefetch cache, has a chance to dual-issue
7837 ;; with other memory operations.  With DFA we might be able to model this,
7838 ;; but it requires a lot of state.
7839 (define_expand "prefetch"
7840   [(match_operand 0 "address_operand" "")
7841    (match_operand 1 "const_int_operand" "")
7842    (match_operand 2 "const_int_operand" "")]
7843   "TARGET_V9"
7845   if (TARGET_ARCH64)
7846     emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
7847   else
7848     emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
7849   DONE;
7852 (define_insn "prefetch_64"
7853   [(prefetch (match_operand:DI 0 "address_operand" "p")
7854              (match_operand:DI 1 "const_int_operand" "n")
7855              (match_operand:DI 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")])
7878 (define_insn "prefetch_32"
7879   [(prefetch (match_operand:SI 0 "address_operand" "p")
7880              (match_operand:SI 1 "const_int_operand" "n")
7881              (match_operand:SI 2 "const_int_operand" "n"))]
7882   ""
7884   static const char * const prefetch_instr[2][2] = {
7885     {
7886       "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7887       "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7888     },
7889     {
7890       "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7891       "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7892     }
7893   };
7894   int read_or_write = INTVAL (operands[1]);
7895   int locality = INTVAL (operands[2]);
7897   gcc_assert (read_or_write == 0 || read_or_write == 1);
7898   gcc_assert (locality >= 0 && locality < 4);
7899   return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7901   [(set_attr "type" "load")
7902    (set_attr "subtype" "prefetch")])
7905 ;; Trap instructions.
7907 (define_insn "trap"
7908   [(trap_if (const_int 1) (const_int 5))]
7909   ""
7910   "ta\t5"
7911   [(set_attr "type" "trap")])
7913 (define_expand "ctrapsi4"
7914   [(trap_if (match_operator 0 "comparison_operator"
7915              [(match_operand:SI 1 "compare_operand" "")
7916               (match_operand:SI 2 "arith_operand" "")])
7917             (match_operand 3 "arith_operand"))]
7918   ""
7920   operands[1] = gen_compare_reg (operands[0]);
7921   if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
7922     FAIL;
7923   operands[2] = const0_rtx;
7926 (define_expand "ctrapdi4"
7927   [(trap_if (match_operator 0 "comparison_operator"
7928              [(match_operand:DI 1 "compare_operand" "")
7929               (match_operand:DI 2 "arith_operand" "")])
7930             (match_operand 3 "arith_operand"))]
7931   "TARGET_ARCH64"
7933   operands[1] = gen_compare_reg (operands[0]);
7934   if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
7935     FAIL;
7936   operands[2] = const0_rtx;
7939 (define_insn "*trapsi_insn"
7940   [(trap_if (match_operator 0 "icc_comparison_operator"
7941              [(reg:CC CC_REG) (const_int 0)])
7942             (match_operand:SI 1 "arith_operand" "rM"))]
7943   ""
7945   if (TARGET_V9)
7946     return "t%C0\t%%icc, %1";
7947   else
7948     return "t%C0\t%1";
7950   [(set_attr "type" "trap")])
7952 (define_insn "*trapdi_insn"
7953   [(trap_if (match_operator 0 "icc_comparison_operator"
7954              [(reg:CCX CC_REG) (const_int 0)])
7955             (match_operand:SI 1 "arith_operand" "rM"))]
7956   "TARGET_V9"
7957   "t%C0\t%%xcc, %1"
7958   [(set_attr "type" "trap")])
7961 ;; TLS support instructions.
7963 (define_insn "tgd_hi22"
7964   [(set (match_operand:SI 0 "register_operand" "=r")
7965         (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
7966                             UNSPEC_TLSGD)))]
7967   "TARGET_TLS"
7968   "sethi\\t%%tgd_hi22(%a1), %0")
7970 (define_insn "tgd_lo10"
7971   [(set (match_operand:SI 0 "register_operand" "=r")
7972         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7973                    (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
7974                               UNSPEC_TLSGD)))]
7975   "TARGET_TLS"
7976   "add\\t%1, %%tgd_lo10(%a2), %0")
7978 (define_insn "tgd_add32"
7979   [(set (match_operand:SI 0 "register_operand" "=r")
7980         (plus:SI (match_operand:SI 1 "register_operand" "r")
7981                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7982                              (match_operand 3 "tgd_symbolic_operand" "")]
7983                             UNSPEC_TLSGD)))]
7984   "TARGET_TLS && TARGET_ARCH32"
7985   "add\\t%1, %2, %0, %%tgd_add(%a3)")
7987 (define_insn "tgd_add64"
7988   [(set (match_operand:DI 0 "register_operand" "=r")
7989         (plus:DI (match_operand:DI 1 "register_operand" "r")
7990                  (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7991                              (match_operand 3 "tgd_symbolic_operand" "")]
7992                             UNSPEC_TLSGD)))]
7993   "TARGET_TLS && TARGET_ARCH64"
7994   "add\\t%1, %2, %0, %%tgd_add(%a3)")
7996 (define_insn "tgd_call32"
7997   [(set (match_operand 0 "register_operand" "=r")
7998         (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
7999                                   (match_operand 2 "tgd_symbolic_operand" "")]
8000                                  UNSPEC_TLSGD))
8001               (match_operand 3 "" "")))
8002    (clobber (reg:SI O7_REG))]
8003   "TARGET_TLS && TARGET_ARCH32"
8004   "call\t%a1, %%tgd_call(%a2)%#"
8005   [(set_attr "type" "call")])
8007 (define_insn "tgd_call64"
8008   [(set (match_operand 0 "register_operand" "=r")
8009         (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
8010                                   (match_operand 2 "tgd_symbolic_operand" "")]
8011                                  UNSPEC_TLSGD))
8012               (match_operand 3 "" "")))
8013    (clobber (reg:DI O7_REG))]
8014   "TARGET_TLS && TARGET_ARCH64"
8015   "call\t%a1, %%tgd_call(%a2)%#"
8016   [(set_attr "type" "call")])
8018 (define_insn "tldm_hi22"
8019   [(set (match_operand:SI 0 "register_operand" "=r")
8020         (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
8021   "TARGET_TLS"
8022   "sethi\\t%%tldm_hi22(%&), %0")
8024 (define_insn "tldm_lo10"
8025   [(set (match_operand:SI 0 "register_operand" "=r")
8026         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8027                     (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
8028   "TARGET_TLS"
8029   "add\\t%1, %%tldm_lo10(%&), %0")
8031 (define_insn "tldm_add32"
8032   [(set (match_operand:SI 0 "register_operand" "=r")
8033         (plus:SI (match_operand:SI 1 "register_operand" "r")
8034                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
8035                             UNSPEC_TLSLDM)))]
8036   "TARGET_TLS && TARGET_ARCH32"
8037   "add\\t%1, %2, %0, %%tldm_add(%&)")
8039 (define_insn "tldm_add64"
8040   [(set (match_operand:DI 0 "register_operand" "=r")
8041         (plus:DI (match_operand:DI 1 "register_operand" "r")
8042                  (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
8043                             UNSPEC_TLSLDM)))]
8044   "TARGET_TLS && TARGET_ARCH64"
8045   "add\\t%1, %2, %0, %%tldm_add(%&)")
8047 (define_insn "tldm_call32"
8048   [(set (match_operand 0 "register_operand" "=r")
8049         (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
8050                                  UNSPEC_TLSLDM))
8051               (match_operand 2 "" "")))
8052    (clobber (reg:SI O7_REG))]
8053   "TARGET_TLS && TARGET_ARCH32"
8054   "call\t%a1, %%tldm_call(%&)%#"
8055   [(set_attr "type" "call")])
8057 (define_insn "tldm_call64"
8058   [(set (match_operand 0 "register_operand" "=r")
8059         (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
8060                                  UNSPEC_TLSLDM))
8061               (match_operand 2 "" "")))
8062    (clobber (reg:DI O7_REG))]
8063   "TARGET_TLS && TARGET_ARCH64"
8064   "call\t%a1, %%tldm_call(%&)%#"
8065   [(set_attr "type" "call")])
8067 (define_insn "tldo_hix22"
8068   [(set (match_operand:SI 0 "register_operand" "=r")
8069         (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
8070                             UNSPEC_TLSLDO)))]
8071   "TARGET_TLS"
8072   "sethi\\t%%tldo_hix22(%a1), %0")
8074 (define_insn "tldo_lox10"
8075   [(set (match_operand:SI 0 "register_operand" "=r")
8076         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8077                    (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
8078                               UNSPEC_TLSLDO)))]
8079   "TARGET_TLS"
8080   "xor\\t%1, %%tldo_lox10(%a2), %0")
8082 (define_insn "tldo_add32"
8083   [(set (match_operand:SI 0 "register_operand" "=r")
8084         (plus:SI (match_operand:SI 1 "register_operand" "r")
8085                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8086                              (match_operand 3 "tld_symbolic_operand" "")]
8087                             UNSPEC_TLSLDO)))]
8088   "TARGET_TLS && TARGET_ARCH32"
8089   "add\\t%1, %2, %0, %%tldo_add(%a3)")
8091 (define_insn "tldo_add64"
8092   [(set (match_operand:DI 0 "register_operand" "=r")
8093         (plus:DI (match_operand:DI 1 "register_operand" "r")
8094                  (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8095                              (match_operand 3 "tld_symbolic_operand" "")]
8096                             UNSPEC_TLSLDO)))]
8097   "TARGET_TLS && TARGET_ARCH64"
8098   "add\\t%1, %2, %0, %%tldo_add(%a3)")
8100 (define_insn "tie_hi22"
8101   [(set (match_operand:SI 0 "register_operand" "=r")
8102         (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
8103                             UNSPEC_TLSIE)))]
8104   "TARGET_TLS"
8105   "sethi\\t%%tie_hi22(%a1), %0")
8107 (define_insn "tie_lo10"
8108   [(set (match_operand:SI 0 "register_operand" "=r")
8109         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8110                    (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
8111                               UNSPEC_TLSIE)))]
8112   "TARGET_TLS"
8113   "add\\t%1, %%tie_lo10(%a2), %0")
8115 (define_insn "tie_ld32"
8116   [(set (match_operand:SI 0 "register_operand" "=r")
8117         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
8118                     (match_operand:SI 2 "register_operand" "r")
8119                     (match_operand 3 "tie_symbolic_operand" "")]
8120                    UNSPEC_TLSIE))]
8121   "TARGET_TLS && TARGET_ARCH32"
8122   "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
8123   [(set_attr "type" "load")
8124    (set_attr "subtype" "regular")])
8126 (define_insn "tie_ld64"
8127   [(set (match_operand:DI 0 "register_operand" "=r")
8128         (unspec:DI [(match_operand:DI 1 "register_operand" "r")
8129                     (match_operand:SI 2 "register_operand" "r")
8130                     (match_operand 3 "tie_symbolic_operand" "")]
8131                    UNSPEC_TLSIE))]
8132   "TARGET_TLS && TARGET_ARCH64"
8133   "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
8134   [(set_attr "type" "load")
8135    (set_attr "subtype" "regular")])
8137 (define_insn "tie_add32"
8138   [(set (match_operand:SI 0 "register_operand" "=r")
8139         (plus:SI (match_operand:SI 1 "register_operand" "r")
8140                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8141                              (match_operand 3 "tie_symbolic_operand" "")]
8142                             UNSPEC_TLSIE)))]
8143   "TARGET_SUN_TLS && TARGET_ARCH32"
8144   "add\\t%1, %2, %0, %%tie_add(%a3)")
8146 (define_insn "tie_add64"
8147   [(set (match_operand:DI 0 "register_operand" "=r")
8148         (plus:DI (match_operand:DI 1 "register_operand" "r")
8149                  (unspec:DI [(match_operand:DI 2 "register_operand" "r")
8150                              (match_operand 3 "tie_symbolic_operand" "")]
8151                             UNSPEC_TLSIE)))]
8152   "TARGET_SUN_TLS && TARGET_ARCH64"
8153   "add\\t%1, %2, %0, %%tie_add(%a3)")
8155 (define_insn "tle_hix22_sp32"
8156   [(set (match_operand:SI 0 "register_operand" "=r")
8157         (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
8158                             UNSPEC_TLSLE)))]
8159   "TARGET_TLS && TARGET_ARCH32"
8160   "sethi\\t%%tle_hix22(%a1), %0")
8162 (define_insn "tle_lox10_sp32"
8163   [(set (match_operand:SI 0 "register_operand" "=r")
8164         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
8165                    (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
8166                               UNSPEC_TLSLE)))]
8167   "TARGET_TLS && TARGET_ARCH32"
8168   "xor\\t%1, %%tle_lox10(%a2), %0")
8170 (define_insn "tle_hix22_sp64"
8171   [(set (match_operand:DI 0 "register_operand" "=r")
8172         (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
8173                             UNSPEC_TLSLE)))]
8174   "TARGET_TLS && TARGET_ARCH64"
8175   "sethi\\t%%tle_hix22(%a1), %0")
8177 (define_insn "tle_lox10_sp64"
8178   [(set (match_operand:DI 0 "register_operand" "=r")
8179         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
8180                    (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
8181                               UNSPEC_TLSLE)))]
8182   "TARGET_TLS && TARGET_ARCH64"
8183   "xor\\t%1, %%tle_lox10(%a2), %0")
8185 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
8186 (define_insn "*tldo_ldub_sp32"
8187   [(set (match_operand:QI 0 "register_operand" "=r")
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_ldub1_sp32"
8199   [(set (match_operand:HI 0 "register_operand" "=r")
8200         (zero_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   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8207   [(set_attr "type" "load")
8208    (set_attr "subtype" "regular")
8209    (set_attr "us3load_type" "3cycle")])
8211 (define_insn "*tldo_ldub2_sp32"
8212   [(set (match_operand:SI 0 "register_operand" "=r")
8213         (zero_extend:SI
8214           (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8215                                        (match_operand 3 "tld_symbolic_operand" "")]
8216                                       UNSPEC_TLSLDO)
8217                            (match_operand:SI 1 "register_operand" "r")))))]
8218   "TARGET_TLS && TARGET_ARCH32"
8219   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8220   [(set_attr "type" "load")
8221    (set_attr "subtype" "regular")
8222    (set_attr "us3load_type" "3cycle")])
8224 (define_insn "*tldo_ldsb1_sp32"
8225   [(set (match_operand:HI 0 "register_operand" "=r")
8226         (sign_extend:HI
8227           (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8228                                        (match_operand 3 "tld_symbolic_operand" "")]
8229                                       UNSPEC_TLSLDO)
8230                            (match_operand:SI 1 "register_operand" "r")))))]
8231   "TARGET_TLS && TARGET_ARCH32"
8232   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8233   [(set_attr "type" "sload")
8234    (set_attr "us3load_type" "3cycle")])
8236 (define_insn "*tldo_ldsb2_sp32"
8237   [(set (match_operand:SI 0 "register_operand" "=r")
8238         (sign_extend:SI
8239           (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8240                                        (match_operand 3 "tld_symbolic_operand" "")]
8241                                       UNSPEC_TLSLDO)
8242                            (match_operand:SI 1 "register_operand" "r")))))]
8243   "TARGET_TLS && TARGET_ARCH32"
8244   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8245   [(set_attr "type" "sload")
8246    (set_attr "us3load_type" "3cycle")])
8248 (define_insn "*tldo_ldub_sp64"
8249   [(set (match_operand:QI 0 "register_operand" "=r")
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_ldub1_sp64"
8261   [(set (match_operand:HI 0 "register_operand" "=r")
8262         (zero_extend:HI
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_ldub2_sp64"
8274   [(set (match_operand:SI 0 "register_operand" "=r")
8275         (zero_extend:SI
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   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8282   [(set_attr "type" "load")
8283    (set_attr "subtype" "regular")
8284    (set_attr "us3load_type" "3cycle")])
8286 (define_insn "*tldo_ldub3_sp64"
8287   [(set (match_operand:DI 0 "register_operand" "=r")
8288         (zero_extend:DI
8289           (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8290                                        (match_operand 3 "tld_symbolic_operand" "")]
8291                                       UNSPEC_TLSLDO)
8292                            (match_operand:DI 1 "register_operand" "r")))))]
8293   "TARGET_TLS && TARGET_ARCH64"
8294   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
8295   [(set_attr "type" "load")
8296    (set_attr "subtype" "regular")
8297    (set_attr "us3load_type" "3cycle")])
8299 (define_insn "*tldo_ldsb1_sp64"
8300   [(set (match_operand:HI 0 "register_operand" "=r")
8301         (sign_extend:HI
8302           (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8303                                        (match_operand 3 "tld_symbolic_operand" "")]
8304                                       UNSPEC_TLSLDO)
8305                            (match_operand:DI 1 "register_operand" "r")))))]
8306   "TARGET_TLS && TARGET_ARCH64"
8307   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8308   [(set_attr "type" "sload")
8309    (set_attr "us3load_type" "3cycle")])
8311 (define_insn "*tldo_ldsb2_sp64"
8312   [(set (match_operand:SI 0 "register_operand" "=r")
8313         (sign_extend:SI
8314           (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8315                                        (match_operand 3 "tld_symbolic_operand" "")]
8316                                       UNSPEC_TLSLDO)
8317                            (match_operand:DI 1 "register_operand" "r")))))]
8318   "TARGET_TLS && TARGET_ARCH64"
8319   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8320   [(set_attr "type" "sload")
8321    (set_attr "us3load_type" "3cycle")])
8323 (define_insn "*tldo_ldsb3_sp64"
8324   [(set (match_operand:DI 0 "register_operand" "=r")
8325         (sign_extend:DI
8326           (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8327                                        (match_operand 3 "tld_symbolic_operand" "")]
8328                                       UNSPEC_TLSLDO)
8329                            (match_operand:DI 1 "register_operand" "r")))))]
8330   "TARGET_TLS && TARGET_ARCH64"
8331   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
8332   [(set_attr "type" "sload")
8333    (set_attr "us3load_type" "3cycle")])
8335 (define_insn "*tldo_lduh_sp32"
8336   [(set (match_operand:HI 0 "register_operand" "=r")
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   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8343   [(set_attr "type" "load")
8344    (set_attr "subtype" "regular")
8345    (set_attr "us3load_type" "3cycle")])
8347 (define_insn "*tldo_lduh1_sp32"
8348   [(set (match_operand:SI 0 "register_operand" "=r")
8349         (zero_extend:SI
8350           (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8351                                        (match_operand 3 "tld_symbolic_operand" "")]
8352                                       UNSPEC_TLSLDO)
8353                            (match_operand:SI 1 "register_operand" "r")))))]
8354   "TARGET_TLS && TARGET_ARCH32"
8355   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8356   [(set_attr "type" "load")
8357    (set_attr "subtype" "regular")
8358    (set_attr "us3load_type" "3cycle")])
8360 (define_insn "*tldo_ldsh1_sp32"
8361   [(set (match_operand:SI 0 "register_operand" "=r")
8362         (sign_extend:SI
8363           (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8364                                        (match_operand 3 "tld_symbolic_operand" "")]
8365                                       UNSPEC_TLSLDO)
8366                            (match_operand:SI 1 "register_operand" "r")))))]
8367   "TARGET_TLS && TARGET_ARCH32"
8368   "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8369   [(set_attr "type" "sload")
8370    (set_attr "us3load_type" "3cycle")])
8372 (define_insn "*tldo_lduh_sp64"
8373   [(set (match_operand:HI 0 "register_operand" "=r")
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_lduh1_sp64"
8385   [(set (match_operand:SI 0 "register_operand" "=r")
8386         (zero_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   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8393   [(set_attr "type" "load")
8394    (set_attr "subtype" "regular")
8395    (set_attr "us3load_type" "3cycle")])
8397 (define_insn "*tldo_lduh2_sp64"
8398   [(set (match_operand:DI 0 "register_operand" "=r")
8399         (zero_extend:DI
8400           (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8401                                        (match_operand 3 "tld_symbolic_operand" "")]
8402                                       UNSPEC_TLSLDO)
8403                            (match_operand:DI 1 "register_operand" "r")))))]
8404   "TARGET_TLS && TARGET_ARCH64"
8405   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
8406   [(set_attr "type" "load")
8407    (set_attr "subtype" "regular")
8408    (set_attr "us3load_type" "3cycle")])
8410 (define_insn "*tldo_ldsh1_sp64"
8411   [(set (match_operand:SI 0 "register_operand" "=r")
8412         (sign_extend:SI
8413           (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8414                                        (match_operand 3 "tld_symbolic_operand" "")]
8415                                       UNSPEC_TLSLDO)
8416                            (match_operand:DI 1 "register_operand" "r")))))]
8417   "TARGET_TLS && TARGET_ARCH64"
8418   "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8419   [(set_attr "type" "sload")
8420    (set_attr "us3load_type" "3cycle")])
8422 (define_insn "*tldo_ldsh2_sp64"
8423   [(set (match_operand:DI 0 "register_operand" "=r")
8424         (sign_extend:DI
8425           (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8426                                        (match_operand 3 "tld_symbolic_operand" "")]
8427                                       UNSPEC_TLSLDO)
8428                            (match_operand:DI 1 "register_operand" "r")))))]
8429   "TARGET_TLS && TARGET_ARCH64"
8430   "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
8431   [(set_attr "type" "sload")
8432    (set_attr "us3load_type" "3cycle")])
8434 (define_insn "*tldo_lduw_sp32"
8435   [(set (match_operand:SI 0 "register_operand" "=r")
8436         (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8437                                      (match_operand 3 "tld_symbolic_operand" "")]
8438                                     UNSPEC_TLSLDO)
8439                          (match_operand:SI 1 "register_operand" "r"))))]
8440   "TARGET_TLS && TARGET_ARCH32"
8441   "ld\t[%1 + %2], %0, %%tldo_add(%3)"
8442   [(set_attr "type" "load")
8443    (set_attr "subtype" "regular")])
8445 (define_insn "*tldo_lduw_sp64"
8446   [(set (match_operand:SI 0 "register_operand" "=r")
8447         (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8448                                      (match_operand 3 "tld_symbolic_operand" "")]
8449                                     UNSPEC_TLSLDO)
8450                          (match_operand:DI 1 "register_operand" "r"))))]
8451   "TARGET_TLS && TARGET_ARCH64"
8452   "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8453   [(set_attr "type" "load")
8454    (set_attr "subtype" "regular")])
8456 (define_insn "*tldo_lduw1_sp64"
8457   [(set (match_operand:DI 0 "register_operand" "=r")
8458         (zero_extend:DI
8459           (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8460                                        (match_operand 3 "tld_symbolic_operand" "")]
8461                                       UNSPEC_TLSLDO)
8462                            (match_operand:DI 1 "register_operand" "r")))))]
8463   "TARGET_TLS && TARGET_ARCH64"
8464   "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
8465   [(set_attr "type" "load")
8466    (set_attr "subtype" "regular")])
8468 (define_insn "*tldo_ldsw1_sp64"
8469   [(set (match_operand:DI 0 "register_operand" "=r")
8470         (sign_extend:DI
8471           (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8472                                         (match_operand 3 "tld_symbolic_operand" "")]
8473                                       UNSPEC_TLSLDO)
8474                            (match_operand:DI 1 "register_operand" "r")))))]
8475   "TARGET_TLS && TARGET_ARCH64"
8476   "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
8477   [(set_attr "type" "sload")
8478    (set_attr "us3load_type" "3cycle")])
8480 (define_insn "*tldo_ldx_sp64"
8481   [(set (match_operand:DI 0 "register_operand" "=r")
8482         (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8483                                      (match_operand 3 "tld_symbolic_operand" "")]
8484                                     UNSPEC_TLSLDO)
8485                          (match_operand:DI 1 "register_operand" "r"))))]
8486   "TARGET_TLS && TARGET_ARCH64"
8487   "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
8488   [(set_attr "type" "load")
8489    (set_attr "subtype" "regular")])
8491 (define_insn "*tldo_stb_sp32"
8492   [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8493                                      (match_operand 3 "tld_symbolic_operand" "")]
8494                                     UNSPEC_TLSLDO)
8495                          (match_operand:SI 1 "register_operand" "r")))
8496         (match_operand:QI 0 "register_operand" "r"))]
8497   "TARGET_TLS && TARGET_ARCH32"
8498   "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8499   [(set_attr "type" "store")])
8501 (define_insn "*tldo_stb_sp64"
8502   [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8503                                      (match_operand 3 "tld_symbolic_operand" "")]
8504                                     UNSPEC_TLSLDO)
8505                          (match_operand:DI 1 "register_operand" "r")))
8506         (match_operand:QI 0 "register_operand" "r"))]
8507   "TARGET_TLS && TARGET_ARCH64"
8508   "stb\t%0, [%1 + %2], %%tldo_add(%3)"
8509   [(set_attr "type" "store")])
8511 (define_insn "*tldo_sth_sp32"
8512   [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8513                                      (match_operand 3 "tld_symbolic_operand" "")]
8514                                     UNSPEC_TLSLDO)
8515                          (match_operand:SI 1 "register_operand" "r")))
8516         (match_operand:HI 0 "register_operand" "r"))]
8517   "TARGET_TLS && TARGET_ARCH32"
8518   "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8519   [(set_attr "type" "store")])
8521 (define_insn "*tldo_sth_sp64"
8522   [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8523                                      (match_operand 3 "tld_symbolic_operand" "")]
8524                                     UNSPEC_TLSLDO)
8525                          (match_operand:DI 1 "register_operand" "r")))
8526         (match_operand:HI 0 "register_operand" "r"))]
8527   "TARGET_TLS && TARGET_ARCH64"
8528   "sth\t%0, [%1 + %2], %%tldo_add(%3)"
8529   [(set_attr "type" "store")])
8531 (define_insn "*tldo_stw_sp32"
8532   [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8533                                      (match_operand 3 "tld_symbolic_operand" "")]
8534                                     UNSPEC_TLSLDO)
8535                          (match_operand:SI 1 "register_operand" "r")))
8536         (match_operand:SI 0 "register_operand" "r"))]
8537   "TARGET_TLS && TARGET_ARCH32"
8538   "st\t%0, [%1 + %2], %%tldo_add(%3)"
8539   [(set_attr "type" "store")])
8541 (define_insn "*tldo_stw_sp64"
8542   [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8543                                      (match_operand 3 "tld_symbolic_operand" "")]
8544                                     UNSPEC_TLSLDO)
8545                          (match_operand:DI 1 "register_operand" "r")))
8546         (match_operand:SI 0 "register_operand" "r"))]
8547   "TARGET_TLS && TARGET_ARCH64"
8548   "stw\t%0, [%1 + %2], %%tldo_add(%3)"
8549   [(set_attr "type" "store")])
8551 (define_insn "*tldo_stx_sp64"
8552   [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8553                                      (match_operand 3 "tld_symbolic_operand" "")]
8554                                     UNSPEC_TLSLDO)
8555                          (match_operand:DI 1 "register_operand" "r")))
8556         (match_operand:DI 0 "register_operand" "r"))]
8557   "TARGET_TLS && TARGET_ARCH64"
8558   "stx\t%0, [%1 + %2], %%tldo_add(%3)"
8559   [(set_attr "type" "store")])
8562 ;; Stack protector instructions.
8564 (define_expand "stack_protect_set"
8565   [(match_operand 0 "memory_operand" "")
8566    (match_operand 1 "memory_operand" "")]
8567   ""
8569 #ifdef TARGET_THREAD_SSP_OFFSET
8570   rtx tlsreg = gen_rtx_REG (Pmode, 7);
8571   rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
8572   operands[1] = gen_rtx_MEM (Pmode, addr);
8573 #endif
8574   if (TARGET_ARCH64)
8575     emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
8576   else
8577     emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
8578   DONE;
8581 (define_insn "stack_protect_setsi"
8582   [(set (match_operand:SI 0 "memory_operand" "=m")
8583         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
8584    (set (match_scratch:SI 2 "=&r") (const_int 0))]
8585   "TARGET_ARCH32"
8586   "ld\t%1, %2\;st\t%2, %0\;mov\t0, %2"
8587   [(set_attr "type" "multi")
8588    (set_attr "length" "3")])
8590 (define_insn "stack_protect_setdi"
8591   [(set (match_operand:DI 0 "memory_operand" "=m")
8592         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
8593    (set (match_scratch:DI 2 "=&r") (const_int 0))]
8594   "TARGET_ARCH64"
8595   "ldx\t%1, %2\;stx\t%2, %0\;mov\t0, %2"
8596   [(set_attr "type" "multi")
8597    (set_attr "length" "3")])
8599 (define_expand "stack_protect_test"
8600   [(match_operand 0 "memory_operand" "")
8601    (match_operand 1 "memory_operand" "")
8602    (match_operand 2 "" "")]
8603   ""
8605   rtx result, test;
8606 #ifdef TARGET_THREAD_SSP_OFFSET
8607   rtx tlsreg = gen_rtx_REG (Pmode, 7);
8608   rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
8609   operands[1] = gen_rtx_MEM (Pmode, addr);
8610 #endif
8611   if (TARGET_ARCH64)
8612     {
8613       result = gen_reg_rtx (Pmode);
8614       emit_insn (gen_stack_protect_testdi (result, operands[0], operands[1]));
8615       test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
8616       emit_jump_insn (gen_cbranchdi4 (test, result, const0_rtx, operands[2]));
8617     }
8618   else
8619     {
8620       emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
8621       result = gen_rtx_REG (CCmode, SPARC_ICC_REG);
8622       test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
8623       emit_jump_insn (gen_cbranchcc4 (test, result, const0_rtx, operands[2]));
8624     }
8625   DONE;
8628 (define_insn "stack_protect_testsi"
8629   [(set (reg:CC CC_REG)
8630         (unspec:CC [(match_operand:SI 0 "memory_operand" "m")
8631                     (match_operand:SI 1 "memory_operand" "m")]
8632                    UNSPEC_SP_TEST))
8633    (set (match_scratch:SI 3 "=r") (const_int 0))
8634    (clobber (match_scratch:SI 2 "=&r"))]
8635   "TARGET_ARCH32"
8636   "ld\t%0, %2\;ld\t%1, %3\;xorcc\t%2, %3, %2\;mov\t0, %3"
8637   [(set_attr "type" "multi")
8638    (set_attr "length" "4")])
8640 (define_insn "stack_protect_testdi"
8641   [(set (match_operand:DI 0 "register_operand" "=&r")
8642         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
8643                     (match_operand:DI 2 "memory_operand" "m")]
8644                    UNSPEC_SP_TEST))
8645    (set (match_scratch:DI 3 "=r") (const_int 0))]
8646   "TARGET_ARCH64"
8647   "ldx\t%1, %0\;ldx\t%2, %3\;xor\t%0, %3, %0\;mov\t0, %3"
8648   [(set_attr "type" "multi")
8649    (set_attr "length" "4")])
8652 ;; Vector instructions.
8654 (define_mode_iterator VM32 [V1SI V2HI V4QI])
8655 (define_mode_iterator VM64 [V1DI V2SI V4HI V8QI])
8656 (define_mode_iterator VMALL [V1SI V2HI V4QI V1DI V2SI V4HI V8QI])
8658 (define_mode_attr vbits [(V2SI "32") (V4HI "16") (V1SI "32s") (V2HI "16s")
8659                          (V8QI "8")])
8660 (define_mode_attr vconstr [(V1SI "f") (V2HI "f") (V4QI "f")
8661                            (V1DI "e") (V2SI "e") (V4HI "e") (V8QI "e")])
8662 (define_mode_attr vfptype [(V1SI "single") (V2HI "single") (V4QI "single")
8663                            (V1DI "double") (V2SI "double") (V4HI "double")
8664                            (V8QI "double")])
8665 (define_mode_attr veltmode [(V1SI "si") (V2HI "hi") (V4QI "qi") (V1DI "di")
8666                             (V2SI "si") (V4HI "hi") (V8QI "qi")])
8668 (define_expand "mov<VMALL:mode>"
8669   [(set (match_operand:VMALL 0 "nonimmediate_operand" "")
8670         (match_operand:VMALL 1 "general_operand" ""))]
8671   "TARGET_VIS"
8673   if (sparc_expand_move (<VMALL:MODE>mode, operands))
8674     DONE;
8677 (define_insn "*mov<VM32:mode>_insn"
8678   [(set (match_operand:VM32 0 "nonimmediate_operand" "=f,f,f,f,m,m,*r, m,*r,*r, f")
8679         (match_operand:VM32 1 "input_operand"         "Y,Z,f,m,f,Y, m,*r,*r, f,*r"))]
8680   "TARGET_VIS
8681    && (register_operand (operands[0], <VM32:MODE>mode)
8682        || register_or_zero_or_all_ones_operand (operands[1], <VM32:MODE>mode))"
8683   "@
8684   fzeros\t%0
8685   fones\t%0
8686   fsrc2s\t%1, %0
8687   ld\t%1, %0
8688   st\t%1, %0
8689   st\t%r1, %0
8690   ld\t%1, %0
8691   st\t%1, %0
8692   mov\t%1, %0
8693   movstouw\t%1, %0
8694   movwtos\t%1, %0"
8695   [(set_attr "type" "visl,visl,vismv,fpload,fpstore,store,load,store,*,vismv,vismv")
8696    (set_attr "subtype" "single,single,single,*,*,*,regular,*,*,movstouw,single")
8697    (set_attr "cpu_feature" "vis,vis,vis,*,*,*,*,*,*,vis3,vis3")])
8699 (define_insn "*mov<VM64:mode>_insn_sp64"
8700   [(set (match_operand:VM64 0 "nonimmediate_operand" "=e,e,e,e,W,m,*r, m,*r, e,*r")
8701         (match_operand:VM64 1 "input_operand"         "Y,Z,e,W,e,Y, m,*r, e,*r,*r"))]
8702   "TARGET_VIS
8703    && TARGET_ARCH64
8704    && (register_operand (operands[0], <VM64:MODE>mode)
8705        || register_or_zero_or_all_ones_operand (operands[1], <VM64:MODE>mode))"
8706   "@
8707   fzero\t%0
8708   fone\t%0
8709   fsrc2\t%1, %0
8710   ldd\t%1, %0
8711   std\t%1, %0
8712   stx\t%r1, %0
8713   ldx\t%1, %0
8714   stx\t%1, %0
8715   movdtox\t%1, %0
8716   movxtod\t%1, %0
8717   mov\t%1, %0"
8718   [(set_attr "type" "visl,visl,vismv,fpload,fpstore,store,load,store,vismv,vismv,*")
8719    (set_attr "subtype" "double,double,double,*,*,*,regular,*,movdtox,movxtod,*")
8720    (set_attr "cpu_feature" "vis,vis,vis,*,*,*,*,*,vis3,vis3,*")])
8722 (define_insn "*mov<VM64:mode>_insn_sp32"
8723   [(set (match_operand:VM64 0 "nonimmediate_operand"
8724                               "=T,o,e,e,e,*r, f,e,T,U,T,f,o,*r,*r, o")
8725         (match_operand:VM64 1 "input_operand"
8726                               " Y,Y,Y,Z,e, f,*r,T,e,T,U,o,f,*r, o,*r"))]
8727   "TARGET_VIS
8728    && TARGET_ARCH32
8729    && (register_operand (operands[0], <VM64:MODE>mode)
8730        || register_or_zero_or_all_ones_operand (operands[1], <VM64:MODE>mode))"
8731   "@
8732   stx\t%r1, %0
8733   #
8734   fzero\t%0
8735   fone\t%0
8736   fsrc2\t%1, %0
8737   #
8738   #
8739   ldd\t%1, %0
8740   std\t%1, %0
8741   ldd\t%1, %0
8742   std\t%1, %0
8743   #
8744   #
8745   #
8746   ldd\t%1, %0
8747   std\t%1, %0"
8748   [(set_attr "type" "store,*,visl,visl,vismv,*,*,fpload,fpstore,load,store,*,*,*,load,store")
8749    (set_attr "subtype" "*,*,double,double,double,*,*,*,*,regular,*,*,*,*,regular,*")
8750    (set_attr "length" "*,2,*,*,*,2,2,*,*,*,*,2,2,2,*,*")
8751    (set_attr "cpu_feature" "*,*,vis,vis,vis,vis3,vis3,*,*,*,*,*,*,*,*,*")
8752    (set_attr "lra" "*,*,*,*,*,*,*,*,*,disabled,disabled,*,*,*,*,*")])
8754 (define_split
8755   [(set (match_operand:VM64 0 "register_operand" "")
8756         (match_operand:VM64 1 "register_operand" ""))]
8757   "reload_completed
8758    && TARGET_VIS
8759    && TARGET_ARCH32
8760    && sparc_split_reg_reg_legitimate (operands[0], operands[1])"
8761   [(clobber (const_int 0))]
8763   sparc_split_reg_reg (operands[0], operands[1], SImode);
8764   DONE;
8767 (define_split
8768   [(set (match_operand:VM64 0 "register_operand" "")
8769         (match_operand:VM64 1 "memory_operand" ""))]
8770   "reload_completed
8771    && TARGET_VIS
8772    && TARGET_ARCH32
8773    && sparc_split_reg_mem_legitimate (operands[0], operands[1])"
8774   [(clobber (const_int 0))]
8776   sparc_split_reg_mem (operands[0], operands[1], SImode);
8777   DONE;
8780 (define_split
8781   [(set (match_operand:VM64 0 "memory_operand" "")
8782         (match_operand:VM64 1 "register_operand" ""))]
8783   "reload_completed
8784    && TARGET_VIS
8785    && TARGET_ARCH32
8786    && sparc_split_reg_mem_legitimate (operands[1], operands[0])"
8787   [(clobber (const_int 0))]
8789   sparc_split_mem_reg (operands[0], operands[1], SImode);
8790   DONE;
8793 (define_split
8794   [(set (match_operand:VM64 0 "memory_operand" "")
8795         (match_operand:VM64 1 "const_zero_operand" ""))]
8796   "reload_completed
8797    && TARGET_VIS
8798    && TARGET_ARCH32
8799    && !mem_min_alignment (operands[0], 8)
8800    && offsettable_memref_p (operands[0])"
8801   [(clobber (const_int 0))]
8803   emit_move_insn_1 (adjust_address (operands[0], SImode, 0), const0_rtx);
8804   emit_move_insn_1 (adjust_address (operands[0], SImode, 4), const0_rtx);
8805   DONE;
8808 (define_expand "vec_init<VMALL:mode><VMALL:veltmode>"
8809   [(match_operand:VMALL 0 "register_operand" "")
8810    (match_operand:VMALL 1 "" "")]
8811   "TARGET_VIS"
8813   sparc_expand_vector_init (operands[0], operands[1]);
8814   DONE;
8817 (define_code_iterator plusminus [plus minus])
8818 (define_code_attr plusminus_insn [(plus "add") (minus "sub")])
8820 (define_mode_iterator VADDSUB [V1SI V2SI V2HI V4HI])
8822 (define_insn "<plusminus_insn><VADDSUB:mode>3"
8823   [(set (match_operand:VADDSUB 0 "register_operand" "=<vconstr>")
8824         (plusminus:VADDSUB (match_operand:VADDSUB 1 "register_operand" "<vconstr>")
8825                            (match_operand:VADDSUB 2 "register_operand" "<vconstr>")))]
8826   "TARGET_VIS"
8827   "fp<plusminus_insn><vbits>\t%1, %2, %0"
8828   [(set_attr "type" "fga")
8829    (set_attr "subtype" "other")
8830    (set_attr "fptype" "<vfptype>")])
8832 (define_mode_iterator VL [V1SI V2HI V4QI V1DI V2SI V4HI V8QI])
8833 (define_mode_attr vlsuf [(V1SI "s") (V2HI "s") (V4QI "s")
8834                          (V1DI  "") (V2SI  "") (V4HI  "") (V8QI "")])
8835 (define_code_iterator vlop [ior and xor])
8836 (define_code_attr vlinsn [(ior "or") (and "and") (xor "xor")])
8837 (define_code_attr vlninsn [(ior "nor") (and "nand") (xor "xnor")])
8839 (define_insn "<vlop:code><VL:mode>3"
8840   [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8841         (vlop:VL (match_operand:VL 1 "register_operand" "<vconstr>")
8842                  (match_operand:VL 2 "register_operand" "<vconstr>")))]
8843   "TARGET_VIS"
8844   "f<vlinsn><vlsuf>\t%1, %2, %0"
8845   [(set_attr "type" "visl")
8846    (set_attr "fptype" "<vfptype>")])
8848 (define_insn "*not_<vlop:code><VL:mode>3"
8849   [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8850         (not:VL (vlop:VL (match_operand:VL 1 "register_operand" "<vconstr>")
8851                          (match_operand:VL 2 "register_operand" "<vconstr>"))))]
8852   "TARGET_VIS"
8853   "f<vlninsn><vlsuf>\t%1, %2, %0"
8854   [(set_attr "type" "visl")
8855    (set_attr "fptype" "<vfptype>")])
8857 ;; (ior (not (op1)) (not (op2))) is the canonical form of NAND.
8858 (define_insn "*nand<VL:mode>_vis"
8859   [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8860         (ior:VL (not:VL (match_operand:VL 1 "register_operand" "<vconstr>"))
8861                 (not:VL (match_operand:VL 2 "register_operand" "<vconstr>"))))]
8862   "TARGET_VIS"
8863   "fnand<vlsuf>\t%1, %2, %0"
8864   [(set_attr "type" "visl")
8865    (set_attr "fptype" "<vfptype>")])
8867 (define_code_iterator vlnotop [ior and])
8869 (define_insn "*<vlnotop:code>_not1<VL:mode>_vis"
8870   [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8871         (vlnotop:VL (not:VL (match_operand:VL 1 "register_operand" "<vconstr>"))
8872                     (match_operand:VL 2 "register_operand" "<vconstr>")))]
8873   "TARGET_VIS"
8874   "f<vlinsn>not1<vlsuf>\t%1, %2, %0"
8875   [(set_attr "type" "visl")
8876    (set_attr "fptype" "<vfptype>")])
8878 (define_insn "*<vlnotop:code>_not2<VL:mode>_vis"
8879   [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8880         (vlnotop:VL (match_operand:VL 1 "register_operand" "<vconstr>")
8881                     (not:VL (match_operand:VL 2 "register_operand" "<vconstr>"))))]
8882   "TARGET_VIS"
8883   "f<vlinsn>not2<vlsuf>\t%1, %2, %0"
8884   [(set_attr "type" "visl")
8885    (set_attr "fptype" "<vfptype>")])
8887 (define_insn "one_cmpl<VL:mode>2"
8888   [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8889         (not:VL (match_operand:VL 1 "register_operand" "<vconstr>")))]
8890   "TARGET_VIS"
8891   "fnot1<vlsuf>\t%1, %0"
8892   [(set_attr "type" "visl")
8893    (set_attr "fptype" "<vfptype>")])
8895 ;; Hard to generate VIS instructions.  We have builtins for these.
8897 (define_insn "fpack16_vis"
8898   [(set (match_operand:V4QI 0 "register_operand" "=f")
8899         (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e")
8900                       (reg:DI GSR_REG)]
8901                       UNSPEC_FPACK16))]
8902   "TARGET_VIS"
8903   "fpack16\t%1, %0"
8904   [(set_attr "type" "fgm_pack")
8905    (set_attr "fptype" "double")])
8907 (define_insn "fpackfix_vis"
8908   [(set (match_operand:V2HI 0 "register_operand" "=f")
8909         (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e")
8910                       (reg:DI GSR_REG)]
8911                       UNSPEC_FPACKFIX))]
8912   "TARGET_VIS"
8913   "fpackfix\t%1, %0"
8914   [(set_attr "type" "fgm_pack")
8915    (set_attr "fptype" "double")])
8917 (define_insn "fpack32_vis"
8918   [(set (match_operand:V8QI 0 "register_operand" "=e")
8919         (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e")
8920                       (match_operand:V8QI 2 "register_operand" "e")
8921                       (reg:DI GSR_REG)]
8922                      UNSPEC_FPACK32))]
8923   "TARGET_VIS"
8924   "fpack32\t%1, %2, %0"
8925   [(set_attr "type" "fgm_pack")
8926    (set_attr "fptype" "double")])
8928 (define_insn "fexpand_vis"
8929   [(set (match_operand:V4HI 0 "register_operand" "=e")
8930         (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")]
8931          UNSPEC_FEXPAND))]
8932  "TARGET_VIS"
8933  "fexpand\t%1, %0"
8934  [(set_attr "type" "fga")
8935   (set_attr "subtype" "fpu")
8936   (set_attr "fptype" "double")])
8938 (define_insn "fpmerge_vis"
8939   [(set (match_operand:V8QI 0 "register_operand" "=e")
8940         (vec_select:V8QI
8941           (vec_concat:V8QI (match_operand:V4QI 1 "register_operand" "f")
8942                            (match_operand:V4QI 2 "register_operand" "f"))
8943           (parallel [(const_int 0) (const_int 4)
8944                      (const_int 1) (const_int 5)
8945                      (const_int 2) (const_int 6)
8946                      (const_int 3) (const_int 7)])))]
8947  "TARGET_VIS"
8948  "fpmerge\t%1, %2, %0"
8949  [(set_attr "type" "fga")
8950   (set_attr "subtype" "fpu")
8951   (set_attr "fptype" "double")])
8953 ;; Partitioned multiply instructions
8954 (define_insn "fmul8x16_vis"
8955   [(set (match_operand:V4HI 0 "register_operand" "=e")
8956         (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8957                       (match_operand:V4HI 2 "register_operand" "e")]
8958          UNSPEC_MUL8))]
8959   "TARGET_VIS"
8960   "fmul8x16\t%1, %2, %0"
8961   [(set_attr "type" "fgm_mul")
8962    (set_attr "fptype" "double")])
8964 (define_insn "fmul8x16au_vis"
8965   [(set (match_operand:V4HI 0 "register_operand" "=e")
8966         (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8967                       (match_operand:V2HI 2 "register_operand" "f")]
8968          UNSPEC_MUL16AU))]
8969   "TARGET_VIS"
8970   "fmul8x16au\t%1, %2, %0"
8971   [(set_attr "type" "fgm_mul")
8972    (set_attr "fptype" "double")])
8974 (define_insn "fmul8x16al_vis"
8975   [(set (match_operand:V4HI 0 "register_operand" "=e")
8976         (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8977                       (match_operand:V2HI 2 "register_operand" "f")]
8978          UNSPEC_MUL16AL))]
8979   "TARGET_VIS"
8980   "fmul8x16al\t%1, %2, %0"
8981   [(set_attr "type" "fgm_mul")
8982    (set_attr "fptype" "double")])
8984 (define_insn "fmul8sux16_vis"
8985   [(set (match_operand:V4HI 0 "register_operand" "=e")
8986         (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
8987                       (match_operand:V4HI 2 "register_operand" "e")]
8988          UNSPEC_MUL8SU))]
8989   "TARGET_VIS"
8990   "fmul8sux16\t%1, %2, %0"
8991   [(set_attr "type" "fgm_mul")
8992    (set_attr "fptype" "double")])
8994 (define_insn "fmul8ulx16_vis"
8995   [(set (match_operand:V4HI 0 "register_operand" "=e")
8996         (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
8997                       (match_operand:V4HI 2 "register_operand" "e")]
8998          UNSPEC_MUL8UL))]
8999   "TARGET_VIS"
9000   "fmul8ulx16\t%1, %2, %0"
9001   [(set_attr "type" "fgm_mul")
9002    (set_attr "fptype" "double")])
9004 (define_insn "fmuld8sux16_vis"
9005   [(set (match_operand:V2SI 0 "register_operand" "=e")
9006         (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
9007                       (match_operand:V2HI 2 "register_operand" "f")]
9008          UNSPEC_MULDSU))]
9009   "TARGET_VIS"
9010   "fmuld8sux16\t%1, %2, %0"
9011   [(set_attr "type" "fgm_mul")
9012    (set_attr "fptype" "double")])
9014 (define_insn "fmuld8ulx16_vis"
9015   [(set (match_operand:V2SI 0 "register_operand" "=e")
9016         (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
9017                       (match_operand:V2HI 2 "register_operand" "f")]
9018          UNSPEC_MULDUL))]
9019   "TARGET_VIS"
9020   "fmuld8ulx16\t%1, %2, %0"
9021   [(set_attr "type" "fgm_mul")
9022    (set_attr "fptype" "double")])
9024 (define_expand "wrgsr_vis"
9025   [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" ""))]
9026   "TARGET_VIS"
9028   if (TARGET_ARCH32)
9029     {
9030       emit_insn (gen_wrgsr_v8plus (operands[0]));
9031       DONE;
9032     }
9035 (define_insn "*wrgsr_sp64"
9036   [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" "rI"))]
9037   "TARGET_VIS && TARGET_ARCH64"
9038   "wr\t%%g0, %0, %%gsr"
9039   [(set_attr "type" "gsr")
9040    (set_attr "subtype" "reg")])
9042 (define_insn "wrgsr_v8plus"
9043   [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" "I,r"))
9044    (clobber (match_scratch:SI 1 "=X,&h"))]
9045   "TARGET_VIS && TARGET_ARCH32"
9047   if (GET_CODE (operands[0]) == CONST_INT
9048       || sparc_check_64 (operands[0], insn))
9049     return "wr\t%%g0, %0, %%gsr";
9051   output_asm_insn("srl\t%L0, 0, %L0", operands);
9052   return "sllx\t%H0, 32, %1\n\tor\t%L0, %1, %1\n\twr\t%%g0, %1, %%gsr";
9054   [(set_attr "type" "multi")])
9056 (define_expand "rdgsr_vis"
9057   [(set (match_operand:DI 0 "register_operand" "") (reg:DI GSR_REG))]
9058   "TARGET_VIS"
9060   if (TARGET_ARCH32)
9061     {
9062       emit_insn (gen_rdgsr_v8plus (operands[0]));
9063       DONE;
9064     }
9067 (define_insn "*rdgsr_sp64"
9068   [(set (match_operand:DI 0 "register_operand" "=r") (reg:DI GSR_REG))]
9069   "TARGET_VIS && TARGET_ARCH64"
9070   "rd\t%%gsr, %0"
9071   [(set_attr "type" "gsr")
9072    (set_attr "subtype" "reg")])
9074 (define_insn "rdgsr_v8plus"
9075   [(set (match_operand:DI 0 "register_operand" "=r") (reg:DI GSR_REG))
9076    (clobber (match_scratch:SI 1 "=&h"))]
9077   "TARGET_VIS && TARGET_ARCH32"
9079   return "rd\t%%gsr, %1\n\tsrlx\t%1, 32, %H0\n\tmov %1, %L0";
9081   [(set_attr "type" "multi")])
9083 ;; Using faligndata only makes sense after an alignaddr since the choice of
9084 ;; bytes to take out of each operand is dependent on the results of the last
9085 ;; alignaddr.
9086 (define_insn "faligndata<VM64:mode>_vis"
9087   [(set (match_operand:VM64 0 "register_operand" "=e")
9088         (unspec:VM64 [(match_operand:VM64 1 "register_operand" "e")
9089                       (match_operand:VM64 2 "register_operand" "e")
9090                       (reg:DI GSR_REG)]
9091          UNSPEC_ALIGNDATA))]
9092   "TARGET_VIS"
9093   "faligndata\t%1, %2, %0"
9094   [(set_attr "type" "fga")
9095    (set_attr "subtype" "other")
9096    (set_attr "fptype" "double")])
9098 (define_insn "alignaddrsi_vis"
9099   [(set (match_operand:SI 0 "register_operand" "=r")
9100         (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
9101                  (match_operand:SI 2 "register_or_zero_operand" "rJ")))
9102    (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
9103         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
9104   "TARGET_VIS"
9105   "alignaddr\t%r1, %r2, %0"
9106   [(set_attr "type" "gsr")
9107    (set_attr "subtype" "alignaddr")])
9109 (define_insn "alignaddrdi_vis"
9110   [(set (match_operand:DI 0 "register_operand" "=r")
9111         (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
9112                  (match_operand:DI 2 "register_or_zero_operand" "rJ")))
9113    (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
9114         (plus:DI (match_dup 1) (match_dup 2)))]
9115   "TARGET_VIS"
9116   "alignaddr\t%r1, %r2, %0"
9117   [(set_attr "type" "gsr")
9118    (set_attr "subtype" "alignaddr")])
9120 (define_insn "alignaddrlsi_vis"
9121   [(set (match_operand:SI 0 "register_operand" "=r")
9122         (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
9123                  (match_operand:SI 2 "register_or_zero_operand" "rJ")))
9124    (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
9125         (xor:DI (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2)))
9126                 (const_int 7)))]
9127   "TARGET_VIS"
9128   "alignaddrl\t%r1, %r2, %0"
9129   [(set_attr "type" "gsr")
9130    (set_attr "subtype" "alignaddr")])
9132 (define_insn "alignaddrldi_vis"
9133   [(set (match_operand:DI 0 "register_operand" "=r")
9134         (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
9135                  (match_operand:DI 2 "register_or_zero_operand" "rJ")))
9136    (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
9137         (xor:DI (plus:DI (match_dup 1) (match_dup 2))
9138                 (const_int 7)))]
9139   "TARGET_VIS"
9140   "alignaddrl\t%r1, %r2, %0"
9141   [(set_attr "type" "gsr")
9142    (set_attr "subtype" "alignaddr")])
9144 (define_insn "pdist_vis"
9145   [(set (match_operand:DI 0 "register_operand" "=e")
9146         (unspec:DI [(match_operand:V8QI 1 "register_operand" "e")
9147                     (match_operand:V8QI 2 "register_operand" "e")
9148                     (match_operand:DI 3 "register_operand" "0")]
9149          UNSPEC_PDIST))]
9150   "TARGET_VIS"
9151   "pdist\t%1, %2, %0"
9152   [(set_attr "type" "pdist")
9153    (set_attr "fptype" "double")])
9155 ;; Edge instructions produce condition codes equivalent to a 'subcc'
9156 ;; with the same operands.
9157 (define_insn "edge8<P:mode>_vis"
9158   [(set (reg:CCNZ CC_REG)
9159         (compare:CCNZ (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
9160                                (match_operand:P 2 "register_or_zero_operand" "rJ"))
9161                       (const_int 0)))
9162    (set (match_operand:P 0 "register_operand" "=r")
9163         (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8))]
9164   "TARGET_VIS"
9165   "edge8\t%r1, %r2, %0"
9166   [(set_attr "type" "edge")])
9168 (define_insn "edge8l<P:mode>_vis"
9169   [(set (reg:CCNZ CC_REG)
9170         (compare:CCNZ (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
9171                                (match_operand:P 2 "register_or_zero_operand" "rJ"))
9172                       (const_int 0)))
9173    (set (match_operand:P 0 "register_operand" "=r")
9174         (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8L))]
9175   "TARGET_VIS"
9176   "edge8l\t%r1, %r2, %0"
9177   [(set_attr "type" "edge")])
9179 (define_insn "edge16<P:mode>_vis"
9180   [(set (reg:CCNZ CC_REG)
9181         (compare:CCNZ (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
9182                                (match_operand:P 2 "register_or_zero_operand" "rJ"))
9183                       (const_int 0)))
9184    (set (match_operand:P 0 "register_operand" "=r")
9185         (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16))]
9186   "TARGET_VIS"
9187   "edge16\t%r1, %r2, %0"
9188   [(set_attr "type" "edge")])
9190 (define_insn "edge16l<P:mode>_vis"
9191   [(set (reg:CCNZ CC_REG)
9192         (compare:CCNZ (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
9193                                (match_operand:P 2 "register_or_zero_operand" "rJ"))
9194                       (const_int 0)))
9195    (set (match_operand:P 0 "register_operand" "=r")
9196         (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16L))]
9197   "TARGET_VIS"
9198   "edge16l\t%r1, %r2, %0"
9199   [(set_attr "type" "edge")])
9201 (define_insn "edge32<P:mode>_vis"
9202   [(set (reg:CCNZ CC_REG)
9203         (compare:CCNZ (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
9204                                (match_operand:P 2 "register_or_zero_operand" "rJ"))
9205                       (const_int 0)))
9206    (set (match_operand:P 0 "register_operand" "=r")
9207         (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32))]
9208   "TARGET_VIS"
9209   "edge32\t%r1, %r2, %0"
9210   [(set_attr "type" "edge")])
9212 (define_insn "edge32l<P:mode>_vis"
9213   [(set (reg:CCNZ CC_REG)
9214         (compare:CCNZ (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
9215                                (match_operand:P 2 "register_or_zero_operand" "rJ"))
9216                       (const_int 0)))
9217    (set (match_operand:P 0 "register_operand" "=r")
9218         (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32L))]
9219   "TARGET_VIS"
9220   "edge32l\t%r1, %r2, %0"
9221   [(set_attr "type" "edge")])
9223 (define_code_iterator gcond [le ne gt eq])
9224 (define_mode_iterator GCM [V4HI V2SI])
9225 (define_mode_attr gcm_name [(V4HI "16") (V2SI "32")])
9227 (define_insn "fcmp<gcond:code><GCM:gcm_name><P:mode>_vis"
9228   [(set (match_operand:P 0 "register_operand" "=r")
9229         (unspec:P [(gcond:GCM (match_operand:GCM 1 "register_operand" "e")
9230                               (match_operand:GCM 2 "register_operand" "e"))]
9231          UNSPEC_FCMP))]
9232   "TARGET_VIS"
9233   "fcmp<gcond:code><GCM:gcm_name>\t%1, %2, %0"
9234   [(set_attr "type" "viscmp")])
9236 (define_insn "fpcmp<gcond:code>8<P:mode>_vis"
9237   [(set (match_operand:P 0 "register_operand" "=r")
9238         (unspec:P [(gcond:V8QI (match_operand:V8QI 1 "register_operand" "e")
9239                                (match_operand:V8QI 2 "register_operand" "e"))]
9240          UNSPEC_FCMP))]
9241   "TARGET_VIS4"
9242   "fpcmp<gcond:code>8\t%1, %2, %0"
9243   [(set_attr "type" "viscmp")])
9245 (define_expand "vcond<GCM:mode><GCM:mode>"
9246   [(match_operand:GCM 0 "register_operand" "")
9247    (match_operand:GCM 1 "register_operand" "")
9248    (match_operand:GCM 2 "register_operand" "")
9249    (match_operator 3 ""
9250      [(match_operand:GCM 4 "register_operand" "")
9251       (match_operand:GCM 5 "register_operand" "")])]
9252   "TARGET_VIS3"
9254   sparc_expand_vcond (<MODE>mode, operands, UNSPEC_CMASK<gcm_name>, UNSPEC_FCMP);
9255   DONE;
9258 (define_expand "vconduv8qiv8qi"
9259   [(match_operand:V8QI 0 "register_operand" "")
9260    (match_operand:V8QI 1 "register_operand" "")
9261    (match_operand:V8QI 2 "register_operand" "")
9262    (match_operator 3 ""
9263      [(match_operand:V8QI 4 "register_operand" "")
9264       (match_operand:V8QI 5 "register_operand" "")])]
9265   "TARGET_VIS3"
9267   sparc_expand_vcond (V8QImode, operands, UNSPEC_CMASK8, UNSPEC_FUCMP);
9268   DONE;
9271 (define_insn "array8<P:mode>_vis"
9272   [(set (match_operand:P 0 "register_operand" "=r")
9273         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
9274                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
9275                   UNSPEC_ARRAY8))]
9276   "TARGET_VIS"
9277   "array8\t%r1, %r2, %0"
9278   [(set_attr "type" "array")])
9280 (define_insn "array16<P:mode>_vis"
9281   [(set (match_operand:P 0 "register_operand" "=r")
9282         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
9283                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
9284                   UNSPEC_ARRAY16))]
9285   "TARGET_VIS"
9286   "array16\t%r1, %r2, %0"
9287   [(set_attr "type" "array")])
9289 (define_insn "array32<P:mode>_vis"
9290   [(set (match_operand:P 0 "register_operand" "=r")
9291         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
9292                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
9293                   UNSPEC_ARRAY32))]
9294   "TARGET_VIS"
9295   "array32\t%r1, %r2, %0"
9296   [(set_attr "type" "array")])
9298 (define_insn "bmaskdi_vis"
9299   [(set (match_operand:DI 0 "register_operand" "=r")
9300         (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
9301                  (match_operand:DI 2 "register_or_zero_operand" "rJ")))
9302    (set (zero_extract:DI (reg:DI GSR_REG) (const_int 32) (const_int 32))
9303         (plus:DI (match_dup 1) (match_dup 2)))]
9304   "TARGET_VIS2 && TARGET_ARCH64"
9305   "bmask\t%r1, %r2, %0"
9306   [(set_attr "type" "bmask")])
9308 (define_insn "bmasksi_vis"
9309   [(set (match_operand:SI 0 "register_operand" "=r")
9310         (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
9311                  (match_operand:SI 2 "register_or_zero_operand" "rJ")))
9312    (set (zero_extract:DI (reg:DI GSR_REG) (const_int 32) (const_int 32))
9313         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
9314   "TARGET_VIS2"
9315   "bmask\t%r1, %r2, %0"
9316   [(set_attr "type" "bmask")])
9318 (define_insn "bshuffle<VM64:mode>_vis"
9319   [(set (match_operand:VM64 0 "register_operand" "=e")
9320         (unspec:VM64 [(match_operand:VM64 1 "register_operand" "e")
9321                       (match_operand:VM64 2 "register_operand" "e")
9322                       (reg:DI GSR_REG)]
9323                      UNSPEC_BSHUFFLE))]
9324   "TARGET_VIS2"
9325   "bshuffle\t%1, %2, %0"
9326   [(set_attr "type" "fga")
9327    (set_attr "subtype" "other")
9328    (set_attr "fptype" "double")])
9330 ;; Unlike constant permutation, we can vastly simplify the compression of
9331 ;; the 64-bit selector input to the 32-bit %gsr value by knowing what the
9332 ;; width of the input is.
9333 (define_expand "vec_perm<VM64:mode>"
9334   [(match_operand:VM64 0 "register_operand" "")
9335    (match_operand:VM64 1 "register_operand" "")
9336    (match_operand:VM64 2 "register_operand" "")
9337    (match_operand:VM64 3 "register_operand" "")]
9338   "TARGET_VIS2"
9340   sparc_expand_vec_perm_bmask (<MODE>mode, operands[3]);
9341   emit_insn (gen_bshuffle<VM64:mode>_vis (operands[0], operands[1], operands[2]));
9342   DONE;
9345 ;; VIS 2.0 adds edge variants which do not set the condition codes
9346 (define_insn "edge8n<P:mode>_vis"
9347   [(set (match_operand:P 0 "register_operand" "=r")
9348         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
9349                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
9350                   UNSPEC_EDGE8N))]
9351   "TARGET_VIS2"
9352   "edge8n\t%r1, %r2, %0"
9353   [(set_attr "type" "edgen")])
9355 (define_insn "edge8ln<P:mode>_vis"
9356   [(set (match_operand:P 0 "register_operand" "=r")
9357         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
9358                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
9359                   UNSPEC_EDGE8LN))]
9360   "TARGET_VIS2"
9361   "edge8ln\t%r1, %r2, %0"
9362   [(set_attr "type" "edgen")])
9364 (define_insn "edge16n<P:mode>_vis"
9365   [(set (match_operand:P 0 "register_operand" "=r")
9366         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
9367                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
9368                   UNSPEC_EDGE16N))]
9369   "TARGET_VIS2"
9370   "edge16n\t%r1, %r2, %0"
9371   [(set_attr "type" "edgen")])
9373 (define_insn "edge16ln<P:mode>_vis"
9374   [(set (match_operand:P 0 "register_operand" "=r")
9375         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
9376                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
9377                   UNSPEC_EDGE16LN))]
9378   "TARGET_VIS2"
9379   "edge16ln\t%r1, %r2, %0"
9380   [(set_attr "type" "edgen")])
9382 (define_insn "edge32n<P:mode>_vis"
9383   [(set (match_operand:P 0 "register_operand" "=r")
9384         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
9385                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
9386                   UNSPEC_EDGE32N))]
9387   "TARGET_VIS2"
9388   "edge32n\t%r1, %r2, %0"
9389   [(set_attr "type" "edgen")])
9391 (define_insn "edge32ln<P:mode>_vis"
9392   [(set (match_operand:P 0 "register_operand" "=r")
9393         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
9394                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
9395                   UNSPEC_EDGE32LN))]
9396   "TARGET_VIS2"
9397   "edge32ln\t%r1, %r2, %0"
9398   [(set_attr "type" "edge")])
9400 ;; Conditional moves are possible via fcmpX --> cmaskX -> bshuffle
9401 (define_insn "cmask8<P:mode>_vis"
9402   [(set (reg:DI GSR_REG)
9403         (unspec:DI [(match_operand:P 0 "register_or_zero_operand" "rJ")
9404                     (reg:DI GSR_REG)]
9405                    UNSPEC_CMASK8))]
9406   "TARGET_VIS3"
9407   "cmask8\t%r0"
9408   [(set_attr "type" "fga")
9409    (set_attr "subtype" "cmask")])
9411 (define_insn "cmask16<P:mode>_vis"
9412   [(set (reg:DI GSR_REG)
9413         (unspec:DI [(match_operand:P 0 "register_or_zero_operand" "rJ")
9414                     (reg:DI GSR_REG)]
9415                    UNSPEC_CMASK16))]
9416   "TARGET_VIS3"
9417   "cmask16\t%r0"
9418   [(set_attr "type" "fga")
9419    (set_attr "subtype" "cmask")])
9421 (define_insn "cmask32<P:mode>_vis"
9422   [(set (reg:DI GSR_REG)
9423         (unspec:DI [(match_operand:P 0 "register_or_zero_operand" "rJ")
9424                     (reg:DI GSR_REG)]
9425                    UNSPEC_CMASK32))]
9426   "TARGET_VIS3"
9427   "cmask32\t%r0"
9428   [(set_attr "type" "fga")
9429    (set_attr "subtype" "cmask")])
9431 (define_insn "fchksm16_vis"
9432   [(set (match_operand:V4HI 0 "register_operand" "=e")
9433         (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "e")
9434                       (match_operand:V4HI 2 "register_operand" "e")]
9435                      UNSPEC_FCHKSM16))]
9436   "TARGET_VIS3"
9437   "fchksm16\t%1, %2, %0"
9438   [(set_attr "type" "fga")
9439    (set_attr "subtype" "fpu")])
9441 (define_code_iterator vis3_shift [ashift ss_ashift lshiftrt ashiftrt])
9442 (define_code_attr vis3_shift_insn
9443   [(ashift "fsll") (ss_ashift "fslas") (lshiftrt "fsrl") (ashiftrt "fsra")])
9444 (define_code_attr vis3_shift_patname
9445   [(ashift "ashl") (ss_ashift "ssashl") (lshiftrt "lshr") (ashiftrt "ashr")])
9446    
9447 (define_insn "v<vis3_shift_patname><GCM:mode>3"
9448   [(set (match_operand:GCM 0 "register_operand" "=<vconstr>")
9449         (vis3_shift:GCM (match_operand:GCM 1 "register_operand" "<vconstr>")
9450                         (match_operand:GCM 2 "register_operand" "<vconstr>")))]
9451   "TARGET_VIS3"
9452   "<vis3_shift_insn><vbits>\t%1, %2, %0"
9453   [(set_attr "type" "fga")
9454    (set_attr "subtype" "fpu")])
9456 (define_insn "pdistn<P:mode>_vis"
9457   [(set (match_operand:P 0 "register_operand" "=r")
9458         (unspec:P [(match_operand:V8QI 1 "register_operand" "e")
9459                    (match_operand:V8QI 2 "register_operand" "e")]
9460          UNSPEC_PDISTN))]
9461   "TARGET_VIS3"
9462   "pdistn\t%1, %2, %0"
9463   [(set_attr "type" "pdistn")
9464    (set_attr "fptype" "double")])
9466 (define_insn "fmean16_vis"
9467   [(set (match_operand:V4HI 0 "register_operand" "=e")
9468         (truncate:V4HI
9469           (lshiftrt:V4SI
9470             (plus:V4SI
9471               (plus:V4SI
9472                 (zero_extend:V4SI
9473                   (match_operand:V4HI 1 "register_operand" "e"))
9474                 (zero_extend:V4SI
9475                   (match_operand:V4HI 2 "register_operand" "e")))
9476               (const_vector:V4SI [(const_int 1) (const_int 1)
9477                                   (const_int 1) (const_int 1)]))
9478           (const_int 1))))]
9479   "TARGET_VIS3"
9480   "fmean16\t%1, %2, %0"
9481   [(set_attr "type" "fga")
9482    (set_attr "subtype" "fpu")])
9484 (define_insn "fp<plusminus_insn>64_vis"
9485   [(set (match_operand:V1DI 0 "register_operand" "=e")
9486         (plusminus:V1DI (match_operand:V1DI 1 "register_operand" "e")
9487                         (match_operand:V1DI 2 "register_operand" "e")))]
9488   "TARGET_VIS3"
9489   "fp<plusminus_insn>64\t%1, %2, %0"
9490   [(set_attr "type" "fga")
9491    (set_attr "subtype" "addsub64")])
9493 (define_insn "<plusminus_insn>v8qi3"
9494   [(set (match_operand:V8QI 0 "register_operand" "=e")
9495         (plusminus:V8QI (match_operand:V8QI 1 "register_operand" "e")
9496                         (match_operand:V8QI 2 "register_operand" "e")))]
9497   "TARGET_VIS4"
9498   "fp<plusminus_insn>8\t%1, %2, %0"
9499   [(set_attr "type" "fga")
9500    (set_attr "subtype" "other")])
9502 (define_mode_iterator VASS [V4HI V2SI V2HI V1SI])
9503 (define_code_iterator vis3_addsub_ss [ss_plus ss_minus])
9504 (define_code_attr vis3_addsub_ss_insn
9505   [(ss_plus "fpadds") (ss_minus "fpsubs")])
9506 (define_code_attr vis3_addsub_ss_patname
9507   [(ss_plus "ssadd") (ss_minus "sssub")])
9509 (define_insn "<vis3_addsub_ss_patname><VASS:mode>3"
9510   [(set (match_operand:VASS 0 "register_operand" "=<vconstr>")
9511         (vis3_addsub_ss:VASS (match_operand:VASS 1 "register_operand" "<vconstr>")
9512                              (match_operand:VASS 2 "register_operand" "<vconstr>")))]
9513   "TARGET_VIS3"
9514   "<vis3_addsub_ss_insn><vbits>\t%1, %2, %0"
9515   [(set_attr "type" "fga")
9516    (set_attr "subtype" "other")])
9518 (define_mode_iterator VMMAX [V8QI V4HI V2SI])
9519 (define_code_iterator vis4_minmax [smin smax])
9520 (define_code_attr vis4_minmax_insn
9521   [(smin "fpmin") (smax "fpmax")])
9522 (define_code_attr vis4_minmax_patname
9523   [(smin "min") (smax "max")])
9525 (define_insn "<vis4_minmax_patname><VMMAX:mode>3"
9526   [(set (match_operand:VMMAX 0 "register_operand" "=<vconstr>")
9527         (vis4_minmax:VMMAX (match_operand:VMMAX 1 "register_operand" "<vconstr>")
9528                            (match_operand:VMMAX 2 "register_operand" "<vconstr>")))]
9529   "TARGET_VIS4"
9530   "<vis4_minmax_insn><vbits>\t%1, %2, %0"
9531   [(set_attr "type" "fga")
9532    (set_attr "subtype" "maxmin")])
9534 (define_code_iterator vis4_uminmax [umin umax])
9535 (define_code_attr vis4_uminmax_insn
9536   [(umin "fpminu") (umax "fpmaxu")])
9537 (define_code_attr vis4_uminmax_patname
9538  [(umin "minu") (umax "maxu")])
9540 (define_insn "<vis4_uminmax_patname><VMMAX:mode>3"
9541   [(set (match_operand:VMMAX 0 "register_operand" "=<vconstr>")
9542         (vis4_uminmax:VMMAX (match_operand:VMMAX 1 "register_operand" "<vconstr>")
9543                             (match_operand:VMMAX 2 "register_operand" "<vconstr>")))]
9544   "TARGET_VIS4"
9545   "<vis4_uminmax_insn><vbits>\t%1, %2, %0"
9546   [(set_attr "type" "fga")
9547    (set_attr "subtype" "maxmin")])
9549 ;; The use of vis3_addsub_ss_patname in the VIS4 instruction below is
9550 ;; intended.
9551 (define_insn "<vis3_addsub_ss_patname>v8qi3"
9552   [(set (match_operand:V8QI 0 "register_operand" "=e")
9553         (vis3_addsub_ss:V8QI (match_operand:V8QI 1 "register_operand" "e")
9554                              (match_operand:V8QI 2 "register_operand" "e")))]
9555   "TARGET_VIS4"
9556   "<vis3_addsub_ss_insn>8\t%1, %2, %0"
9557   [(set_attr "type" "fga")
9558    (set_attr "subtype" "other")])
9560 (define_mode_iterator VAUS [V4HI V8QI])
9561 (define_code_iterator vis4_addsub_us [us_plus us_minus])
9562 (define_code_attr vis4_addsub_us_insn
9563   [(us_plus "fpaddus") (us_minus "fpsubus")])
9564 (define_code_attr vis4_addsub_us_patname
9565   [(us_plus "usadd") (us_minus "ussub")])
9567 (define_insn "<vis4_addsub_us_patname><VAUS:mode>3"
9568  [(set (match_operand:VAUS 0 "register_operand" "=<vconstr>")
9569        (vis4_addsub_us:VAUS (match_operand:VAUS 1 "register_operand" "<vconstr>")
9570                             (match_operand:VAUS 2 "register_operand" "<vconstr>")))]
9571  "TARGET_VIS4"
9572  "<vis4_addsub_us_insn><vbits>\t%1, %2, %0"
9573  [(set_attr "type" "fga")
9574   (set_attr "subtype" "other")])
9576 (define_insn "fucmp<gcond:code>8<P:mode>_vis"
9577   [(set (match_operand:P 0 "register_operand" "=r")
9578         (unspec:P [(gcond:V8QI (match_operand:V8QI 1 "register_operand" "e")
9579                                (match_operand:V8QI 2 "register_operand" "e"))]
9580          UNSPEC_FUCMP))]
9581   "TARGET_VIS3"
9582   "fucmp<gcond:code>8\t%1, %2, %0"
9583   [(set_attr "type" "viscmp")])
9585 (define_insn "fpcmpu<gcond:code><GCM:gcm_name><P:mode>_vis"
9586   [(set (match_operand:P 0 "register_operand" "=r")
9587         (unspec:P [(gcond:GCM (match_operand:GCM 1 "register_operand" "e")
9588                               (match_operand:GCM 2 "register_operand" "e"))]
9589          UNSPEC_FUCMP))]
9590   "TARGET_VIS4"
9591   "fpcmpu<gcond:code><GCM:gcm_name>\t%1, %2, %0"
9592   [(set_attr "type" "viscmp")])
9594 (define_insn "*naddsf3"
9595   [(set (match_operand:SF 0 "register_operand" "=f")
9596         (neg:SF (plus:SF (match_operand:SF 1 "register_operand" "f")
9597                          (match_operand:SF 2 "register_operand" "f"))))]
9598   "TARGET_VIS3"
9599   "fnadds\t%1, %2, %0"
9600   [(set_attr "type" "fp")])
9602 (define_insn "*nadddf3"
9603   [(set (match_operand:DF 0 "register_operand" "=e")
9604         (neg:DF (plus:DF (match_operand:DF 1 "register_operand" "e")
9605                          (match_operand:DF 2 "register_operand" "e"))))]
9606   "TARGET_VIS3"
9607   "fnaddd\t%1, %2, %0"
9608   [(set_attr "type" "fp")
9609    (set_attr "fptype" "double")])
9611 (define_insn "*nmulsf3"
9612   [(set (match_operand:SF 0 "register_operand" "=f")
9613         (mult:SF (neg:SF (match_operand:SF 1 "register_operand" "f"))
9614                  (match_operand:SF 2 "register_operand" "f")))]
9615   "TARGET_VIS3"
9616   "fnmuls\t%1, %2, %0"
9617   [(set_attr "type" "fpmul")])
9619 (define_insn "*nmuldf3"
9620   [(set (match_operand:DF 0 "register_operand" "=e")
9621         (mult:DF (neg:DF (match_operand:DF 1 "register_operand" "e"))
9622                  (match_operand:DF 2 "register_operand" "e")))]
9623   "TARGET_VIS3"
9624   "fnmuld\t%1, %2, %0"
9625   [(set_attr "type" "fpmul")
9626    (set_attr "fptype" "double")])
9628 (define_insn "*nmuldf3_extend"
9629   [(set (match_operand:DF 0 "register_operand" "=e")
9630         (mult:DF (neg:DF (float_extend:DF
9631                            (match_operand:SF 1 "register_operand" "f")))
9632                  (float_extend:DF
9633                    (match_operand:SF 2 "register_operand" "f"))))]
9634   "TARGET_VIS3"
9635   "fnsmuld\t%1, %2, %0"
9636   [(set_attr "type" "fpmul")
9637    (set_attr "fptype" "double")])
9639 (define_insn "fhaddsf_vis"
9640   [(set (match_operand:SF 0 "register_operand" "=f")
9641         (unspec:SF [(match_operand:SF 1 "register_operand" "f")
9642                     (match_operand:SF 2 "register_operand" "f")]
9643                    UNSPEC_FHADD))]
9644   "TARGET_VIS3"
9645   "fhadds\t%1, %2, %0"
9646   [(set_attr "type" "fp")])
9648 (define_insn "fhadddf_vis"
9649   [(set (match_operand:DF 0 "register_operand" "=f")
9650         (unspec:DF [(match_operand:DF 1 "register_operand" "f")
9651                     (match_operand:DF 2 "register_operand" "f")]
9652                    UNSPEC_FHADD))]
9653   "TARGET_VIS3"
9654   "fhaddd\t%1, %2, %0"
9655   [(set_attr "type" "fp")
9656    (set_attr "fptype" "double")])
9658 (define_insn "fhsubsf_vis"
9659   [(set (match_operand:SF 0 "register_operand" "=f")
9660         (unspec:SF [(match_operand:SF 1 "register_operand" "f")
9661                     (match_operand:SF 2 "register_operand" "f")]
9662                    UNSPEC_FHSUB))]
9663   "TARGET_VIS3"
9664   "fhsubs\t%1, %2, %0"
9665   [(set_attr "type" "fp")])
9667 (define_insn "fhsubdf_vis"
9668   [(set (match_operand:DF 0 "register_operand" "=f")
9669         (unspec:DF [(match_operand:DF 1 "register_operand" "f")
9670                     (match_operand:DF 2 "register_operand" "f")]
9671                    UNSPEC_FHSUB))]
9672   "TARGET_VIS3"
9673   "fhsubd\t%1, %2, %0"
9674   [(set_attr "type" "fp")
9675    (set_attr "fptype" "double")])
9677 (define_insn "fnhaddsf_vis"
9678   [(set (match_operand:SF 0 "register_operand" "=f")
9679         (neg:SF (unspec:SF [(match_operand:SF 1 "register_operand" "f")
9680                             (match_operand:SF 2 "register_operand" "f")]
9681                            UNSPEC_FHADD)))]
9682   "TARGET_VIS3"
9683   "fnhadds\t%1, %2, %0"
9684   [(set_attr "type" "fp")])
9686 (define_insn "fnhadddf_vis"
9687   [(set (match_operand:DF 0 "register_operand" "=f")
9688         (neg:DF (unspec:DF [(match_operand:DF 1 "register_operand" "f")
9689                             (match_operand:DF 2 "register_operand" "f")]
9690                            UNSPEC_FHADD)))]
9691   "TARGET_VIS3"
9692   "fnhaddd\t%1, %2, %0"
9693   [(set_attr "type" "fp")
9694    (set_attr "fptype" "double")])
9696 ;; VIS4B instructions.
9698 (define_mode_iterator DUMODE [V2SI V4HI V8QI])
9700 (define_insn "dictunpack<DUMODE:vbits>"
9701   [(set (match_operand:DUMODE 0 "register_operand" "=e")
9702         (unspec:DUMODE [(match_operand:DF 1 "register_operand" "e")
9703                         (match_operand:SI 2 "imm5_operand_dictunpack<DUMODE:vbits>" "t")]
9704          UNSPEC_DICTUNPACK))]
9705   "TARGET_VIS4B"
9706   "dictunpack\t%1, %2, %0"
9707   [(set_attr "type" "fga")
9708    (set_attr "subtype" "other")])
9710 (define_mode_iterator FPCSMODE [V2SI V4HI V8QI])
9711 (define_code_iterator fpcscond [le gt eq ne])
9712 (define_code_iterator fpcsucond [le gt])
9714 (define_insn "fpcmp<fpcscond:code><FPCSMODE:vbits><P:mode>shl"
9715   [(set (match_operand:P 0 "register_operand" "=r")
9716         (unspec:P [(fpcscond:FPCSMODE (match_operand:FPCSMODE 1 "register_operand" "e")
9717                                       (match_operand:FPCSMODE 2 "register_operand" "e"))
9718                    (match_operand:SI 3 "imm2_operand" "q")]
9719          UNSPEC_FPCMPSHL))]
9720    "TARGET_VIS4B"
9721    "fpcmp<fpcscond:code><FPCSMODE:vbits>shl\t%1, %2, %3, %0"
9722    [(set_attr "type" "viscmp")])
9724 (define_insn "fpcmpu<fpcsucond:code><FPCSMODE:vbits><P:mode>shl"
9725   [(set (match_operand:P 0 "register_operand" "=r")
9726         (unspec:P [(fpcsucond:FPCSMODE (match_operand:FPCSMODE 1 "register_operand" "e")
9727                                        (match_operand:FPCSMODE 2 "register_operand" "e"))
9728                    (match_operand:SI 3 "imm2_operand" "q")]
9729          UNSPEC_FPUCMPSHL))]
9730    "TARGET_VIS4B"
9731    "fpcmpu<fpcsucond:code><FPCSMODE:vbits>shl\t%1, %2, %3, %0"
9732    [(set_attr "type" "viscmp")])
9734 (define_insn "fpcmpde<FPCSMODE:vbits><P:mode>shl"
9735   [(set (match_operand:P 0 "register_operand" "=r")
9736         (unspec:P [(match_operand:FPCSMODE 1 "register_operand" "e")
9737                    (match_operand:FPCSMODE 2 "register_operand" "e")
9738                    (match_operand:SI 3 "imm2_operand" "q")]
9739          UNSPEC_FPCMPDESHL))]
9740    "TARGET_VIS4B"
9741    "fpcmpde<FPCSMODE:vbits>shl\t%1, %2, %3, %0"
9742    [(set_attr "type" "viscmp")])
9744 (define_insn "fpcmpur<FPCSMODE:vbits><P:mode>shl"
9745   [(set (match_operand:P 0 "register_operand" "=r")
9746         (unspec:P [(match_operand:FPCSMODE 1 "register_operand" "e")
9747                    (match_operand:FPCSMODE 2 "register_operand" "e")
9748                    (match_operand:SI 3 "imm2_operand" "q")]
9749          UNSPEC_FPCMPURSHL))]
9750    "TARGET_VIS4B"
9751    "fpcmpur<FPCSMODE:vbits>shl\t%1, %2, %3, %0"
9752    [(set_attr "type" "viscmp")])
9754 (include "sync.md")