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