[Obvious] Remove unused aarch64_types_cmtst_qualifiers, was breaking bootstrap.
[official-gcc.git] / gcc / config / sparc / sparc.md
blobb6cd7f026855981f2517340d727a4114dffa1202
1 ;; Machine description for SPARC chip for GCC
2 ;;  Copyright (C) 1987-2014 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 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
25 (define_c_enum "unspec" [
26   UNSPEC_MOVE_PIC
27   UNSPEC_UPDATE_RETURN
28   UNSPEC_LOAD_PCREL_SYM
29   UNSPEC_FRAME_BLOCKAGE
30   UNSPEC_MOVE_PIC_LABEL
31   UNSPEC_SETH44
32   UNSPEC_SETM44
33   UNSPEC_SETHH
34   UNSPEC_SETLM
35   UNSPEC_EMB_HISUM
36   UNSPEC_EMB_TEXTUHI
37   UNSPEC_EMB_TEXTHI
38   UNSPEC_EMB_TEXTULO
39   UNSPEC_EMB_SETHM
40   UNSPEC_MOVE_GOTDATA
42   UNSPEC_MEMBAR
43   UNSPEC_ATOMIC
45   UNSPEC_TLSGD
46   UNSPEC_TLSLDM
47   UNSPEC_TLSLDO
48   UNSPEC_TLSIE
49   UNSPEC_TLSLE
50   UNSPEC_TLSLD_BASE
52   UNSPEC_FPACK16
53   UNSPEC_FPACK32
54   UNSPEC_FPACKFIX
55   UNSPEC_FEXPAND
56   UNSPEC_MUL16AU
57   UNSPEC_MUL16AL
58   UNSPEC_MUL8UL
59   UNSPEC_MULDUL
60   UNSPEC_ALIGNDATA
61   UNSPEC_FCMP
62   UNSPEC_PDIST
63   UNSPEC_EDGE8
64   UNSPEC_EDGE8L
65   UNSPEC_EDGE16
66   UNSPEC_EDGE16L
67   UNSPEC_EDGE32
68   UNSPEC_EDGE32L
69   UNSPEC_ARRAY8
70   UNSPEC_ARRAY16
71   UNSPEC_ARRAY32
73   UNSPEC_SP_SET
74   UNSPEC_SP_TEST
76   UNSPEC_EDGE8N
77   UNSPEC_EDGE8LN
78   UNSPEC_EDGE16N
79   UNSPEC_EDGE16LN
80   UNSPEC_EDGE32N
81   UNSPEC_EDGE32LN
82   UNSPEC_BSHUFFLE
83   UNSPEC_CMASK8
84   UNSPEC_CMASK16
85   UNSPEC_CMASK32
86   UNSPEC_FCHKSM16
87   UNSPEC_PDISTN
88   UNSPEC_FUCMP
89   UNSPEC_FHADD
90   UNSPEC_FHSUB
91   UNSPEC_XMUL
92   UNSPEC_MUL8
93   UNSPEC_MUL8SU
94   UNSPEC_MULDSU
97 (define_c_enum "unspecv" [
98   UNSPECV_BLOCKAGE
99   UNSPECV_PROBE_STACK_RANGE
101   UNSPECV_FLUSHW
102   UNSPECV_SAVEW
104   UNSPECV_FLUSH
106   UNSPECV_LDSTUB
107   UNSPECV_SWAP
108   UNSPECV_CAS
110   UNSPECV_LDFSR
111   UNSPECV_STFSR
114 (define_constants
115  [(G0_REG                       0)
116   (G1_REG                       1)
117   (G2_REG                       2)
118   (G3_REG                       3)
119   (G4_REG                       4)
120   (G5_REG                       5)
121   (G6_REG                       6)
122   (G7_REG                       7)
123   (O0_REG                       8)
124   (O1_REG                       9)
125   (O2_REG                       10)
126   (O3_REG                       11)
127   (O4_REG                       12)
128   (O5_REG                       13)
129   (O6_REG                       14)
130   (O7_REG                       15)
131   (L0_REG                       16)
132   (L1_REG                       17)
133   (L2_REG                       18)
134   (L3_REG                       19)
135   (L4_REG                       20)
136   (L5_REG                       21)
137   (L6_REG                       22)
138   (L7_REG                       23)
139   (I0_REG                       24)
140   (I1_REG                       25)
141   (I2_REG                       26)
142   (I3_REG                       27)
143   (I4_REG                       28)
144   (I5_REG                       29)
145   (I6_REG                       30)
146   (I7_REG                       31)
147   (F0_REG                       32)
148   (F1_REG                       33)
149   (F2_REG                       34)
150   (F3_REG                       35)
151   (F4_REG                       36)
152   (F5_REG                       37)
153   (F6_REG                       38)
154   (F7_REG                       39)
155   (F8_REG                       40)
156   (F9_REG                       41)
157   (F10_REG                      42)
158   (F11_REG                      43)
159   (F12_REG                      44)
160   (F13_REG                      45)
161   (F14_REG                      46)
162   (F15_REG                      47)
163   (F16_REG                      48)
164   (F17_REG                      49)
165   (F18_REG                      50)
166   (F19_REG                      51)
167   (F20_REG                      52)
168   (F21_REG                      53)
169   (F22_REG                      54)
170   (F23_REG                      55)
171   (F24_REG                      56)
172   (F25_REG                      57)
173   (F26_REG                      58)
174   (F27_REG                      59)
175   (F28_REG                      60)
176   (F29_REG                      61)
177   (F30_REG                      62)
178   (F31_REG                      63)
179   (F32_REG                      64)
180   (F34_REG                      66)
181   (F36_REG                      68)
182   (F38_REG                      70)
183   (F40_REG                      72)
184   (F42_REG                      74)
185   (F44_REG                      76)
186   (F46_REG                      78)
187   (F48_REG                      80)
188   (F50_REG                      82)
189   (F52_REG                      84)
190   (F54_REG                      86)
191   (F56_REG                      88)
192   (F58_REG                      90)
193   (F60_REG                      92)
194   (F62_REG                      94)
195   (FCC0_REG                     96)
196   (FCC1_REG                     97)
197   (FCC2_REG                     98)
198   (FCC3_REG                     99)
199   (CC_REG                       100)
200   (SFP_REG                      101)
201   (GSR_REG                      102)
202  ])
204 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
205 (define_mode_iterator I [QI HI SI DI])
206 (define_mode_iterator F [SF DF TF])
208 ;; The upper 32 fp regs on the v9 can't hold SFmode values.  To deal with this
209 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip.  The name
210 ;; is a bit of a misnomer as it covers all 64 fp regs.  The corresponding
211 ;; constraint letter is 'e'.  To avoid any confusion, 'e' is used instead of
212 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
214 ;; Attribute for cpu type.
215 ;; These must match the values of the enum processor_type in sparc-opts.h.
216 (define_attr "cpu"
217   "v7,
218    cypress,
219    v8,
220    supersparc,
221    hypersparc,
222    leon,
223    leon3,
224    sparclite,
225    f930,
226    f934,
227    sparclite86x,
228    sparclet,
229    tsc701,
230    v9,
231    ultrasparc,
232    ultrasparc3,
233    niagara,
234    niagara2,
235    niagara3,
236    niagara4"
237   (const (symbol_ref "sparc_cpu_attr")))
239 ;; Attribute for the instruction set.
240 ;; At present we only need to distinguish v9/!v9, but for clarity we
241 ;; test TARGET_V8 too.
242 (define_attr "isa" "v7,v8,v9,sparclet"
243  (const
244   (cond [(symbol_ref "TARGET_V9") (const_string "v9")
245          (symbol_ref "TARGET_V8") (const_string "v8")
246          (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
247         (const_string "v7"))))
249 (define_attr "cpu_feature" "none,fpu,fpunotv9,v9,vis,vis3" (const_string "none"))
251 (define_attr "enabled" ""
252   (cond [(eq_attr "cpu_feature" "none") (const_int 1)
253          (eq_attr "cpu_feature" "fpu") (symbol_ref "TARGET_FPU")
254          (eq_attr "cpu_feature" "fpunotv9") (symbol_ref "TARGET_FPU && ! TARGET_V9")
255          (eq_attr "cpu_feature" "v9") (symbol_ref "TARGET_V9")
256          (eq_attr "cpu_feature" "vis") (symbol_ref "TARGET_VIS")
257          (eq_attr "cpu_feature" "vis3") (symbol_ref "TARGET_VIS3")]
258         (const_int 0)))
260 ;; Insn type.
261 (define_attr "type"
262   "ialu,compare,shift,
263    load,sload,store,
264    uncond_branch,branch,call,sibcall,call_no_delay_slot,return,
265    cbcond,uncond_cbcond,
266    imul,idiv,
267    fpload,fpstore,
268    fp,fpmove,
269    fpcmove,fpcrmove,
270    fpcmp,
271    fpmul,fpdivs,fpdivd,
272    fpsqrts,fpsqrtd,
273    fga,visl,vismv,fgm_pack,fgm_mul,pdist,pdistn,edge,edgen,gsr,array,
274    cmove,
275    ialuX,
276    multi,savew,flushw,iflush,trap"
277   (const_string "ialu"))
279 ;; True if branch/call has empty delay slot and will emit a nop in it
280 (define_attr "empty_delay_slot" "false,true"
281   (symbol_ref "(empty_delay_slot (insn)
282                 ? EMPTY_DELAY_SLOT_TRUE : EMPTY_DELAY_SLOT_FALSE)"))
284 ;; True if we are making use of compare-and-branch instructions.
285 ;; True if we should emit a nop after a cbcond instruction
286 (define_attr "emit_cbcond_nop" "false,true"
287   (symbol_ref "(emit_cbcond_nop (insn)
288                 ? EMIT_CBCOND_NOP_TRUE : EMIT_CBCOND_NOP_FALSE)"))
290 (define_attr "branch_type" "none,icc,fcc,reg"
291   (const_string "none"))
293 (define_attr "pic" "false,true"
294   (symbol_ref "(flag_pic != 0
295                 ? PIC_TRUE : PIC_FALSE)"))
297 (define_attr "calls_alloca" "false,true"
298   (symbol_ref "(cfun->calls_alloca != 0
299                 ? CALLS_ALLOCA_TRUE : CALLS_ALLOCA_FALSE)"))
301 (define_attr "calls_eh_return" "false,true"
302    (symbol_ref "(crtl->calls_eh_return != 0
303                  ? CALLS_EH_RETURN_TRUE : CALLS_EH_RETURN_FALSE)"))
305 (define_attr "leaf_function" "false,true"
306   (symbol_ref "(crtl->uses_only_leaf_regs != 0
307                 ? LEAF_FUNCTION_TRUE : LEAF_FUNCTION_FALSE)"))
309 (define_attr "delayed_branch" "false,true"
310   (symbol_ref "(flag_delayed_branch != 0
311                 ? DELAYED_BRANCH_TRUE : DELAYED_BRANCH_FALSE)"))
313 (define_attr "flat" "false,true"
314   (symbol_ref "(TARGET_FLAT != 0
315                 ? FLAT_TRUE : FLAT_FALSE)"))
317 (define_attr "fix_ut699" "false,true"
318    (symbol_ref "(sparc_fix_ut699 != 0
319                  ? FIX_UT699_TRUE : FIX_UT699_FALSE)"))
321 ;; Length (in # of insns).
322 ;; Beware that setting a length greater or equal to 3 for conditional branches
323 ;; has a side-effect (see output_cbranch and output_v9branch).
324 (define_attr "length" ""
325   (cond [(eq_attr "type" "uncond_branch,call")
326            (if_then_else (eq_attr "empty_delay_slot" "true")
327              (const_int 2)
328              (const_int 1))
329          (eq_attr "type" "sibcall")
330            (if_then_else (eq_attr "leaf_function" "true")
331              (if_then_else (eq_attr "empty_delay_slot" "true")
332                (const_int 3)
333                (const_int 2))
334              (if_then_else (eq_attr "empty_delay_slot" "true")
335                (const_int 2)
336                (const_int 1)))
337          (eq_attr "branch_type" "icc")
338            (if_then_else (match_operand 0 "noov_compare64_operator" "")
339              (if_then_else (lt (pc) (match_dup 1))
340                (if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000))
341                  (if_then_else (eq_attr "empty_delay_slot" "true")
342                    (const_int 2)
343                    (const_int 1))
344                  (if_then_else (eq_attr "empty_delay_slot" "true")
345                    (const_int 4)
346                    (const_int 3)))
347                (if_then_else (lt (minus (pc) (match_dup 1)) (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 (eq_attr "empty_delay_slot" "true")
355                (const_int 2)
356                (const_int 1)))
357          (eq_attr "branch_type" "fcc")
358            (if_then_else (match_operand 0 "fcc0_register_operand" "")
359              (if_then_else (eq_attr "empty_delay_slot" "true")
360                (if_then_else (not (match_test "TARGET_V9"))
361                  (const_int 3)
362                  (const_int 2))
363                (if_then_else (not (match_test "TARGET_V9"))
364                  (const_int 2)
365                  (const_int 1)))
366              (if_then_else (lt (pc) (match_dup 2))
367                (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000))
368                  (if_then_else (eq_attr "empty_delay_slot" "true")
369                    (const_int 2)
370                    (const_int 1))
371                  (if_then_else (eq_attr "empty_delay_slot" "true")
372                    (const_int 4)
373                    (const_int 3)))
374                (if_then_else (lt (minus (pc) (match_dup 2)) (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          (eq_attr "branch_type" "reg")
382            (if_then_else (lt (pc) (match_dup 2))
383              (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000))
384                (if_then_else (eq_attr "empty_delay_slot" "true")
385                  (const_int 2)
386                  (const_int 1))
387                (if_then_else (eq_attr "empty_delay_slot" "true")
388                  (const_int 4)
389                  (const_int 3)))
390              (if_then_else (lt (minus (pc) (match_dup 2)) (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          (eq_attr "type" "cbcond")
398            (if_then_else (lt (pc) (match_dup 3))
399              (if_then_else (lt (minus (match_dup 3) (pc)) (const_int 500))
400                (if_then_else (eq_attr "emit_cbcond_nop" "true")
401                  (const_int 2)
402                  (const_int 1))
403                (const_int 4))
404              (if_then_else (lt (minus (pc) (match_dup 3)) (const_int 500))
405                (if_then_else (eq_attr "emit_cbcond_nop" "true")
406                  (const_int 2)
407                  (const_int 1))
408                (const_int 4)))
409          (eq_attr "type" "uncond_cbcond")
410            (if_then_else (lt (pc) (match_dup 0))
411              (if_then_else (lt (minus (match_dup 0) (pc)) (const_int 500))
412                (if_then_else (eq_attr "emit_cbcond_nop" "true")
413                  (const_int 2)
414                  (const_int 1))
415                (const_int 1))
416              (if_then_else (lt (minus (pc) (match_dup 0)) (const_int 500))
417                (if_then_else (eq_attr "emit_cbcond_nop" "true")
418                  (const_int 2)
419                  (const_int 1))
420                (const_int 1)))
421          ] (const_int 1)))
423 ;; FP precision.
424 (define_attr "fptype" "single,double"
425   (const_string "single"))
427 ;; FP precision specific to the UT699.
428 (define_attr "fptype_ut699" "none,single"
429   (const_string "none"))
431 ;; UltraSPARC-III integer load type.
432 (define_attr "us3load_type" "2cycle,3cycle"
433   (const_string "2cycle"))
435 (define_asm_attributes
436   [(set_attr "length" "2")
437    (set_attr "type" "multi")])
439 ;; Attributes for branch scheduling
440 (define_attr "in_call_delay" "false,true"
441   (symbol_ref "(eligible_for_call_delay (insn)
442                 ? IN_CALL_DELAY_TRUE : IN_CALL_DELAY_FALSE)"))
444 (define_attr "in_sibcall_delay" "false,true"
445   (symbol_ref "(eligible_for_sibcall_delay (insn)
446                 ? IN_SIBCALL_DELAY_TRUE : IN_SIBCALL_DELAY_FALSE)"))
448 (define_attr "in_return_delay" "false,true"
449   (symbol_ref "(eligible_for_return_delay (insn)
450                 ? IN_RETURN_DELAY_TRUE : IN_RETURN_DELAY_FALSE)"))
452 ;; ??? !v9: Should implement the notion of predelay slots for floating-point
453 ;; branches.  This would allow us to remove the nop always inserted before
454 ;; a floating point branch.
456 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
457 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
458 ;; This is because doing so will add several pipeline stalls to the path
459 ;; that the load/store did not come from.  Unfortunately, there is no way
460 ;; to prevent fill_eager_delay_slots from using load/store without completely
461 ;; disabling them.  For the SPEC benchmark set, this is a serious lose,
462 ;; because it prevents us from moving back the final store of inner loops.
464 (define_attr "in_branch_delay" "false,true"
465   (cond [(eq_attr "type" "uncond_branch,branch,cbcond,uncond_cbcond,call,sibcall,call_no_delay_slot,multi")
466            (const_string "false")
467          (and (eq_attr "fix_ut699" "true") (eq_attr "type" "load,sload"))
468            (const_string "false")
469          (and (eq_attr "fix_ut699" "true")
470               (and (eq_attr "type" "fpload,fp,fpmove,fpmul,fpdivs,fpsqrts")
471                    (ior (eq_attr "fptype" "single")
472                         (eq_attr "fptype_ut699" "single"))))
473            (const_string "false")
474          (eq_attr "length" "1")
475            (const_string "true")
476         ] (const_string "false")))
478 (define_delay (eq_attr "type" "call")
479   [(eq_attr "in_call_delay" "true") (nil) (nil)])
481 (define_delay (eq_attr "type" "sibcall")
482   [(eq_attr "in_sibcall_delay" "true") (nil) (nil)])
484 (define_delay (eq_attr "type" "return")
485   [(eq_attr "in_return_delay" "true") (nil) (nil)])
487 (define_delay (eq_attr "type" "branch")
488   [(eq_attr "in_branch_delay" "true") (nil) (eq_attr "in_branch_delay" "true")])
490 (define_delay (eq_attr "type" "uncond_branch")
491   [(eq_attr "in_branch_delay" "true") (nil) (nil)])
494 ;; Include SPARC DFA schedulers
496 (include "cypress.md")
497 (include "supersparc.md")
498 (include "hypersparc.md")
499 (include "leon.md")
500 (include "sparclet.md")
501 (include "ultra1_2.md")
502 (include "ultra3.md")
503 (include "niagara.md")
504 (include "niagara2.md")
505 (include "niagara4.md")
508 ;; Operand and operator predicates and constraints
510 (include "predicates.md")
511 (include "constraints.md")
514 ;; Compare instructions.
516 ;; These are just the DEFINE_INSNs to match the patterns and the
517 ;; DEFINE_SPLITs for some of the scc insns that actually require
518 ;; more than one machine instruction.  DEFINE_EXPANDs are further down.
520 ;; The compare DEFINE_INSNs.
522 (define_insn "*cmpsi_insn"
523   [(set (reg:CC CC_REG)
524         (compare:CC (match_operand:SI 0 "register_operand" "r")
525                     (match_operand:SI 1 "arith_operand" "rI")))]
526   ""
527   "cmp\t%0, %1"
528   [(set_attr "type" "compare")])
530 (define_insn "*cmpdi_sp64"
531   [(set (reg:CCX CC_REG)
532         (compare:CCX (match_operand:DI 0 "register_operand" "r")
533                      (match_operand:DI 1 "arith_operand" "rI")))]
534   "TARGET_ARCH64"
535   "cmp\t%0, %1"
536   [(set_attr "type" "compare")])
538 (define_insn "*cmpsf_fpe"
539   [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
540         (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
541                        (match_operand:SF 2 "register_operand" "f")))]
542   "TARGET_FPU"
544   if (TARGET_V9)
545     return "fcmpes\t%0, %1, %2";
546   return "fcmpes\t%1, %2";
548   [(set_attr "type" "fpcmp")])
550 (define_insn "*cmpdf_fpe"
551   [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
552         (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
553                        (match_operand:DF 2 "register_operand" "e")))]
554   "TARGET_FPU"
556   if (TARGET_V9)
557     return "fcmped\t%0, %1, %2";
558   return "fcmped\t%1, %2";
560   [(set_attr "type" "fpcmp")
561    (set_attr "fptype" "double")])
563 (define_insn "*cmptf_fpe"
564   [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
565         (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
566                        (match_operand:TF 2 "register_operand" "e")))]
567   "TARGET_FPU && TARGET_HARD_QUAD"
569   if (TARGET_V9)
570     return "fcmpeq\t%0, %1, %2";
571   return "fcmpeq\t%1, %2";
573   [(set_attr "type" "fpcmp")])
575 (define_insn "*cmpsf_fp"
576   [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
577         (compare:CCFP (match_operand:SF 1 "register_operand" "f")
578                       (match_operand:SF 2 "register_operand" "f")))]
579   "TARGET_FPU"
581   if (TARGET_V9)
582     return "fcmps\t%0, %1, %2";
583   return "fcmps\t%1, %2";
585   [(set_attr "type" "fpcmp")])
587 (define_insn "*cmpdf_fp"
588   [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
589         (compare:CCFP (match_operand:DF 1 "register_operand" "e")
590                       (match_operand:DF 2 "register_operand" "e")))]
591   "TARGET_FPU"
593   if (TARGET_V9)
594     return "fcmpd\t%0, %1, %2";
595   return "fcmpd\t%1, %2";
597   [(set_attr "type" "fpcmp")
598    (set_attr "fptype" "double")])
600 (define_insn "*cmptf_fp"
601   [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
602         (compare:CCFP (match_operand:TF 1 "register_operand" "e")
603                       (match_operand:TF 2 "register_operand" "e")))]
604   "TARGET_FPU && TARGET_HARD_QUAD"
606   if (TARGET_V9)
607     return "fcmpq\t%0, %1, %2";
608   return "fcmpq\t%1, %2";
610   [(set_attr "type" "fpcmp")])
612 ;; Next come the scc insns.
614 ;; Note that the boolean result (operand 0) takes on DImode
615 ;; (not SImode) when TARGET_ARCH64.
617 (define_expand "cstoresi4"
618   [(use (match_operator 1 "comparison_operator"
619          [(match_operand:SI 2 "compare_operand" "")
620           (match_operand:SI 3 "arith_operand" "")]))
621    (clobber (match_operand:SI 0 "cstore_result_operand"))]
622   ""
624   if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
625     operands[2] = force_reg (SImode, operands[2]);
626   if (emit_scc_insn (operands)) DONE; else FAIL;
629 (define_expand "cstoredi4"
630   [(use (match_operator 1 "comparison_operator"
631          [(match_operand:DI 2 "compare_operand" "")
632           (match_operand:DI 3 "arith_operand" "")]))
633    (clobber (match_operand:SI 0 "cstore_result_operand"))]
634   "TARGET_ARCH64"
636   if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
637     operands[2] = force_reg (DImode, operands[2]);
638   if (emit_scc_insn (operands)) DONE; else FAIL;
641 (define_expand "cstore<F:mode>4"
642   [(use (match_operator 1 "comparison_operator"
643          [(match_operand:F 2 "register_operand" "")
644           (match_operand:F 3 "register_operand" "")]))
645    (clobber (match_operand:SI 0 "cstore_result_operand"))]
646   "TARGET_FPU"
647   { if (emit_scc_insn (operands)) DONE; else FAIL; })
651 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
652 ;; generate addcc/subcc instructions.
654 (define_expand "seqsi<P:mode>_special"
655   [(set (match_dup 3)
656         (xor:SI (match_operand:SI 1 "register_operand" "")
657                 (match_operand:SI 2 "register_operand" "")))
658    (parallel [(set (match_operand:P 0 "register_operand" "")
659                    (eq:P (match_dup 3) (const_int 0)))
660               (clobber (reg:CC CC_REG))])]
661   ""
662   { operands[3] = gen_reg_rtx (SImode); })
664 (define_expand "seqdi_special"
665   [(set (match_dup 3)
666         (xor:DI (match_operand:DI 1 "register_operand" "")
667                 (match_operand:DI 2 "register_operand" "")))
668    (set (match_operand:DI 0 "register_operand" "")
669         (eq:DI (match_dup 3) (const_int 0)))]
670   "TARGET_ARCH64"
671   { operands[3] = gen_reg_rtx (DImode); })
673 (define_expand "snesi<P:mode>_special"
674   [(set (match_dup 3)
675         (xor:SI (match_operand:SI 1 "register_operand" "")
676                 (match_operand:SI 2 "register_operand" "")))
677    (parallel [(set (match_operand:P 0 "register_operand" "")
678                    (ne:P (match_dup 3) (const_int 0)))
679               (clobber (reg:CC CC_REG))])]
680   ""
681   { operands[3] = gen_reg_rtx (SImode); })
683 (define_expand "snedi_special"
684   [(set (match_dup 3)
685         (xor:DI (match_operand:DI 1 "register_operand" "")
686                 (match_operand:DI 2 "register_operand" "")))
687    (set (match_operand:DI 0 "register_operand" "")
688         (ne:DI (match_dup 3) (const_int 0)))]
689   "TARGET_ARCH64 && ! TARGET_VIS3"
690   { operands[3] = gen_reg_rtx (DImode); })
692 (define_expand "snedi_special_vis3"
693   [(set (match_dup 3)
694         (xor:DI (match_operand:DI 1 "register_operand" "")
695                 (match_operand:DI 2 "register_operand" "")))
696    (parallel [(set (match_operand:DI 0 "register_operand" "")
697                    (ne:DI (match_dup 3) (const_int 0)))
698               (clobber (reg:CCX CC_REG))])]
699   "TARGET_ARCH64 && TARGET_VIS3"
700   { operands[3] = gen_reg_rtx (DImode); })
703 ;; Now the DEFINE_INSNs for the scc cases.
705 ;; The SEQ and SNE patterns are special because they can be done
706 ;; without any branching and do not involve a COMPARE.  We want
707 ;; them to always use the splits below so the results can be
708 ;; scheduled.
710 (define_insn_and_split "*snesi<P:mode>_zero"
711   [(set (match_operand:P 0 "register_operand" "=r")
712         (ne:P (match_operand:SI 1 "register_operand" "r")
713                (const_int 0)))
714    (clobber (reg:CC CC_REG))]
715   ""
716   "#"
717   ""
718   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
719                                            (const_int 0)))
720    (set (match_dup 0) (ltu:P (reg:CC CC_REG) (const_int 0)))]
721   ""
722   [(set_attr "length" "2")])
724 (define_insn_and_split "*neg_snesisi_zero"
725   [(set (match_operand:SI 0 "register_operand" "=r")
726         (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
727                        (const_int 0))))
728    (clobber (reg:CC CC_REG))]
729   ""
730   "#"
731   ""
732   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
733                                            (const_int 0)))
734    (set (match_dup 0) (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0))))]
735   ""
736   [(set_attr "length" "2")])
738 (define_insn_and_split "*neg_snesidi_zero"
739   [(set (match_operand:DI 0 "register_operand" "=r")
740         (neg:DI (ne:DI (match_operand:SI 1 "register_operand" "r")
741                        (const_int 0))))
742    (clobber (reg:CC CC_REG))]
743   "TARGET_ARCH64"
744   "#"
745   ""
746   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
747                                            (const_int 0)))
748    (set (match_dup 0) (sign_extend:DI (neg:SI (ltu:SI (reg:CC CC_REG)
749                                                       (const_int 0)))))]
750   ""
751   [(set_attr "length" "2")])
753 (define_insn_and_split "*snedi_zero"
754   [(set (match_operand:DI 0 "register_operand" "=&r")
755         (ne:DI (match_operand:DI 1 "register_operand" "r")
756                (const_int 0)))]
757   "TARGET_ARCH64 && ! TARGET_VIS3"
758   "#"
759   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
760   [(set (match_dup 0) (const_int 0))
761    (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
762                                               (const_int 0))
763                                        (const_int 1)
764                                        (match_dup 0)))]
765   ""
766   [(set_attr "length" "2")])
768 (define_insn_and_split "*snedi_zero_vis3"
769   [(set (match_operand:DI 0 "register_operand" "=r")
770         (ne:DI (match_operand:DI 1 "register_operand" "r")
771                (const_int 0)))
772    (clobber (reg:CCX CC_REG))]
773   "TARGET_ARCH64 && TARGET_VIS3"
774   "#"
775   ""
776   [(set (reg:CCX_NOOV CC_REG) (compare:CCX_NOOV (neg:DI (match_dup 1))
777                                                 (const_int 0)))
778    (set (match_dup 0) (ltu:DI (reg:CCX CC_REG) (const_int 0)))]
779   ""
780   [(set_attr "length" "2")])
782 (define_insn_and_split "*neg_snedi_zero"
783   [(set (match_operand:DI 0 "register_operand" "=&r")
784         (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
785                        (const_int 0))))]
786   "TARGET_ARCH64"
787   "#"
788   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
789   [(set (match_dup 0) (const_int 0))
790    (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
791                                               (const_int 0))
792                                        (const_int -1)
793                                        (match_dup 0)))]
794   ""
795   [(set_attr "length" "2")])
797 (define_insn_and_split "*snedi_zero_trunc"
798   [(set (match_operand:SI 0 "register_operand" "=&r")
799         (ne:SI (match_operand:DI 1 "register_operand" "r")
800                (const_int 0)))]
801   "TARGET_ARCH64 && ! TARGET_VIS3"
802   "#"
803   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
804   [(set (match_dup 0) (const_int 0))
805    (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
806                                               (const_int 0))
807                                        (const_int 1)
808                                        (match_dup 0)))]
809   ""
810   [(set_attr "length" "2")])
812 (define_insn_and_split "*snedi_zero_trunc_vis3"
813   [(set (match_operand:SI 0 "register_operand" "=r")
814         (ne:SI (match_operand:DI 1 "register_operand" "r")
815                (const_int 0)))
816    (clobber (reg:CCX CC_REG))]
817   "TARGET_ARCH64 && TARGET_VIS3"
818   "#"
819   ""
820   [(set (reg:CCX_NOOV CC_REG) (compare:CCX_NOOV (neg:DI (match_dup 1))
821                                                 (const_int 0)))
822    (set (match_dup 0) (ltu:SI (reg:CCX CC_REG) (const_int 0)))]
823   ""
824   [(set_attr "length" "2")])
826 (define_insn_and_split "*seqsi<P:mode>_zero"
827   [(set (match_operand:P 0 "register_operand" "=r")
828         (eq:P (match_operand:SI 1 "register_operand" "r")
829                (const_int 0)))
830    (clobber (reg:CC CC_REG))]
831   ""
832   "#"
833   ""
834   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
835                                            (const_int 0)))
836    (set (match_dup 0) (geu:P (reg:CC CC_REG) (const_int 0)))]
837   ""
838   [(set_attr "length" "2")])
840 (define_insn_and_split "*neg_seqsisi_zero"
841   [(set (match_operand:SI 0 "register_operand" "=r")
842         (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
843                        (const_int 0))))
844    (clobber (reg:CC CC_REG))]
845   ""
846   "#"
847   ""
848   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
849                                            (const_int 0)))
850    (set (match_dup 0) (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0))))]
851   ""
852   [(set_attr "length" "2")])
854 (define_insn_and_split "*neg_seqsidi_zero"
855   [(set (match_operand:DI 0 "register_operand" "=r")
856         (neg:DI (eq:DI (match_operand:SI 1 "register_operand" "r")
857                        (const_int 0))))
858    (clobber (reg:CC CC_REG))]
859   "TARGET_ARCH64"
860   "#"
861   "&& 1"
862   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
863                                            (const_int 0)))
864    (set (match_dup 0) (sign_extend:DI (neg:SI (geu:SI (reg:CC CC_REG)
865                                                       (const_int 0)))))]
866   ""
867   [(set_attr "length" "2")])
869 (define_insn_and_split "*seqdi_zero"
870   [(set (match_operand:DI 0 "register_operand" "=&r")
871         (eq:DI (match_operand:DI 1 "register_operand" "r")
872                (const_int 0)))]
873   "TARGET_ARCH64"
874   "#"
875   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
876   [(set (match_dup 0) (const_int 0))
877    (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
878                                               (const_int 0))
879                                        (const_int 1)
880                                        (match_dup 0)))]
881   ""
882   [(set_attr "length" "2")])
884 (define_insn_and_split "*neg_seqdi_zero"
885   [(set (match_operand:DI 0 "register_operand" "=&r")
886         (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
887                        (const_int 0))))]
888   "TARGET_ARCH64"
889   "#"
890   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
891   [(set (match_dup 0) (const_int 0))
892    (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
893                                               (const_int 0))
894                                        (const_int -1)
895                                        (match_dup 0)))]
896   ""
897   [(set_attr "length" "2")]) 
899 (define_insn_and_split "*seqdi_zero_trunc"
900   [(set (match_operand:SI 0 "register_operand" "=&r")
901         (eq:SI (match_operand:DI 1 "register_operand" "r")
902                (const_int 0)))]
903   "TARGET_ARCH64"
904   "#"
905   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
906   [(set (match_dup 0) (const_int 0))
907    (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
908                                               (const_int 0))
909                                        (const_int 1)
910                                        (match_dup 0)))]
911   ""
912   [(set_attr "length" "2")])
914 ;; We can also do (x + (i == 0)) and related, so put them in.
915 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
916 ;; versions for v9.
918 (define_insn_and_split "*x_plus_i_ne_0"
919   [(set (match_operand:SI 0 "register_operand" "=r")
920         (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
921                         (const_int 0))
922                  (match_operand:SI 2 "register_operand" "r")))
923    (clobber (reg:CC CC_REG))]
924   ""
925   "#"
926   ""
927   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
928                                            (const_int 0)))
929    (set (match_dup 0) (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
930                                (match_dup 2)))]
931   ""
932   [(set_attr "length" "2")])
934 (define_insn_and_split "*x_minus_i_ne_0"
935   [(set (match_operand:SI 0 "register_operand" "=r")
936         (minus:SI (match_operand:SI 2 "register_operand" "r")
937                   (ne:SI (match_operand:SI 1 "register_operand" "r")
938                          (const_int 0))))
939    (clobber (reg:CC CC_REG))]
940   ""
941   "#"
942   ""
943   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
944                                            (const_int 0)))
945    (set (match_dup 0) (minus:SI (match_dup 2)
946                                 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
947   ""
948   [(set_attr "length" "2")])
950 (define_insn_and_split "*x_plus_i_eq_0"
951   [(set (match_operand:SI 0 "register_operand" "=r")
952         (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
953                         (const_int 0))
954                  (match_operand:SI 2 "register_operand" "r")))
955    (clobber (reg:CC CC_REG))]
956   ""
957   "#"
958   ""
959   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
960                                            (const_int 0)))
961    (set (match_dup 0) (plus:SI (geu:SI (reg:CC CC_REG) (const_int 0))
962                                (match_dup 2)))]
963   ""
964   [(set_attr "length" "2")])
966 (define_insn_and_split "*x_minus_i_eq_0"
967   [(set (match_operand:SI 0 "register_operand" "=r")
968         (minus:SI (match_operand:SI 2 "register_operand" "r")
969                   (eq:SI (match_operand:SI 1 "register_operand" "r")
970                          (const_int 0))))
971    (clobber (reg:CC CC_REG))]
972   ""
973   "#"
974   ""
975   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
976                                            (const_int 0)))
977    (set (match_dup 0) (minus:SI (match_dup 2)
978                                 (geu:SI (reg:CC CC_REG) (const_int 0))))]
979   ""
980   [(set_attr "length" "2")])
982 ;; We can also do GEU and LTU directly, but these operate after a compare.
983 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
984 ;; versions for v9.
986 (define_insn "*sltu<P:mode>_insn"
987   [(set (match_operand:P 0 "register_operand" "=r")
988         (ltu:P (reg:CC CC_REG) (const_int 0)))]
989   ""
990   "addx\t%%g0, 0, %0"
991   [(set_attr "type" "ialuX")])
993 (define_insn "*sltu_insn_vis3"
994   [(set (match_operand:DI 0 "register_operand" "=r")
995         (ltu:DI (reg:CCX CC_REG) (const_int 0)))]
996   "TARGET_ARCH64 && TARGET_VIS3"
997   "addxc\t%%g0, %%g0, %0"
998   [(set_attr "type" "ialuX")])
1000 (define_insn "*sltu_insn_vis3_trunc"
1001   [(set (match_operand:SI 0 "register_operand" "=r")
1002         (ltu:SI (reg:CCX CC_REG) (const_int 0)))]
1003   "TARGET_ARCH64 && TARGET_VIS3"
1004   "addxc\t%%g0, %%g0, %0"
1005   [(set_attr "type" "ialuX")])
1007 (define_insn "*neg_sltusi_insn"
1008   [(set (match_operand:SI 0 "register_operand" "=r")
1009         (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0))))]
1010   ""
1011   "subx\t%%g0, 0, %0"
1012   [(set_attr "type" "ialuX")])
1014 (define_insn "*neg_sltudi_insn"
1015   [(set (match_operand:DI 0 "register_operand" "=r")
1016         (sign_extend:DI (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0)))))]
1017   "TARGET_ARCH64"
1018   "subx\t%%g0, 0, %0"
1019   [(set_attr "type" "ialuX")])
1021 (define_insn "*neg_sltu_minus_x"
1022   [(set (match_operand:SI 0 "register_operand" "=r")
1023         (minus:SI (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0)))
1024                   (match_operand:SI 1 "arith_operand" "rI")))]
1025   ""
1026   "subx\t%%g0, %1, %0"
1027   [(set_attr "type" "ialuX")])
1029 (define_insn "*neg_sltu_plus_x"
1030   [(set (match_operand:SI 0 "register_operand" "=r")
1031         (neg:SI (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
1032                          (match_operand:SI 1 "arith_operand" "rI"))))]
1033   ""
1034   "subx\t%%g0, %1, %0"
1035   [(set_attr "type" "ialuX")])
1037 (define_insn "*sgeu<P:mode>_insn"
1038   [(set (match_operand:P 0 "register_operand" "=r")
1039         (geu:P (reg:CC CC_REG) (const_int 0)))]
1040   ""
1041   "subx\t%%g0, -1, %0"
1042   [(set_attr "type" "ialuX")])
1044 (define_insn "*neg_sgeusi_insn"
1045   [(set (match_operand:SI 0 "register_operand" "=r")
1046         (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0))))]
1047   ""
1048   "addx\t%%g0, -1, %0"
1049   [(set_attr "type" "ialuX")])
1051 (define_insn "*neg_sgeudi_insn"
1052   [(set (match_operand:DI 0 "register_operand" "=r")
1053         (sign_extend:DI (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0)))))]
1054   "TARGET_ARCH64"
1055   "addx\t%%g0, -1, %0"
1056   [(set_attr "type" "ialuX")])
1058 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
1059 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1060 ;; versions for v9.
1062 (define_insn "*sltu_plus_x"
1063   [(set (match_operand:SI 0 "register_operand" "=r")
1064         (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
1065                  (match_operand:SI 1 "arith_operand" "rI")))]
1066   ""
1067   "addx\t%%g0, %1, %0"
1068   [(set_attr "type" "ialuX")])
1070 (define_insn "*sltu_plus_x_plus_y"
1071   [(set (match_operand:SI 0 "register_operand" "=r")
1072         (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
1073                  (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1074                           (match_operand:SI 2 "arith_operand" "rI"))))]
1075   ""
1076   "addx\t%1, %2, %0"
1077   [(set_attr "type" "ialuX")])
1079 (define_insn "*x_minus_sltu"
1080   [(set (match_operand:SI 0 "register_operand" "=r")
1081         (minus:SI (match_operand:SI 1 "register_operand" "r")
1082                   (ltu:SI (reg:CC CC_REG) (const_int 0))))]
1083   ""
1084   "subx\t%1, 0, %0"
1085   [(set_attr "type" "ialuX")])
1087 ;; ??? Combine should canonicalize these next two to the same pattern.
1088 (define_insn "*x_minus_y_minus_sltu"
1089   [(set (match_operand:SI 0 "register_operand" "=r")
1090         (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
1091                             (match_operand:SI 2 "arith_operand" "rI"))
1092                   (ltu:SI (reg:CC CC_REG) (const_int 0))))]
1093   ""
1094   "subx\t%r1, %2, %0"
1095   [(set_attr "type" "ialuX")])
1097 (define_insn "*x_minus_sltu_plus_y"
1098   [(set (match_operand:SI 0 "register_operand" "=r")
1099         (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
1100                   (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
1101                            (match_operand:SI 2 "arith_operand" "rI"))))]
1102   ""
1103   "subx\t%r1, %2, %0"
1104   [(set_attr "type" "ialuX")])
1106 (define_insn "*sgeu_plus_x"
1107   [(set (match_operand:SI 0 "register_operand" "=r")
1108         (plus:SI (geu:SI (reg:CC CC_REG) (const_int 0))
1109                  (match_operand:SI 1 "register_operand" "r")))]
1110   ""
1111   "subx\t%1, -1, %0"
1112   [(set_attr "type" "ialuX")])
1114 (define_insn "*x_minus_sgeu"
1115   [(set (match_operand:SI 0 "register_operand" "=r")
1116         (minus:SI (match_operand:SI 1 "register_operand" "r")
1117                   (geu:SI (reg:CC CC_REG) (const_int 0))))]
1118   ""
1119   "addx\t%1, -1, %0"
1120   [(set_attr "type" "ialuX")])
1122 (define_split
1123   [(set (match_operand:SI 0 "register_operand" "")
1124         (match_operator:SI 2 "noov_compare_operator"
1125                            [(match_operand 1 "icc_or_fcc_register_operand" "")
1126                             (const_int 0)]))]
1127   "TARGET_V9
1128    && REGNO (operands[1]) == SPARC_ICC_REG
1129    && (GET_MODE (operands[1]) == CCXmode
1130        /* 32-bit LTU/GEU are better implemented using addx/subx.  */
1131        || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1132   [(set (match_dup 0) (const_int 0))
1133    (set (match_dup 0)
1134         (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1135                          (const_int 1)
1136                          (match_dup 0)))]
1137   "")
1140 ;; These control RTL generation for conditional jump insns
1142 (define_expand "cbranchcc4"
1143   [(set (pc)
1144         (if_then_else (match_operator 0 "comparison_operator"
1145                           [(match_operand 1 "compare_operand" "")
1146                            (match_operand 2 "const_zero_operand" "")])
1147                       (label_ref (match_operand 3 "" ""))
1148                       (pc)))]
1149   ""
1150   "")
1152 (define_expand "cbranchsi4"
1153   [(use (match_operator 0 "comparison_operator"
1154          [(match_operand:SI 1 "compare_operand" "")
1155           (match_operand:SI 2 "arith_operand" "")]))
1156    (use (match_operand 3 ""))]
1157   ""
1159   if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
1160     operands[1] = force_reg (SImode, operands[1]);
1161   emit_conditional_branch_insn (operands);
1162   DONE;
1165 (define_expand "cbranchdi4"
1166   [(use (match_operator 0 "comparison_operator"
1167          [(match_operand:DI 1 "compare_operand" "")
1168           (match_operand:DI 2 "arith_operand" "")]))
1169    (use (match_operand 3 ""))]
1170   "TARGET_ARCH64"
1172   if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
1173     operands[1] = force_reg (DImode, operands[1]);
1174   emit_conditional_branch_insn (operands);
1175   DONE;
1178 (define_expand "cbranch<F:mode>4"
1179   [(use (match_operator 0 "comparison_operator"
1180          [(match_operand:F 1 "register_operand" "")
1181           (match_operand:F 2 "register_operand" "")]))
1182    (use (match_operand 3 ""))]
1183   "TARGET_FPU"
1184   { emit_conditional_branch_insn (operands); DONE; })
1187 ;; Now match both normal and inverted jump.
1189 ;; XXX fpcmp nop braindamage
1190 (define_insn "*normal_branch"
1191   [(set (pc)
1192         (if_then_else (match_operator 0 "noov_compare_operator"
1193                                       [(reg CC_REG) (const_int 0)])
1194                       (label_ref (match_operand 1 "" ""))
1195                       (pc)))]
1196   ""
1198   return output_cbranch (operands[0], operands[1], 1, 0,
1199                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1200                          insn);
1202   [(set_attr "type" "branch")
1203    (set_attr "branch_type" "icc")])
1205 ;; XXX fpcmp nop braindamage
1206 (define_insn "*inverted_branch"
1207   [(set (pc)
1208         (if_then_else (match_operator 0 "noov_compare_operator"
1209                                       [(reg CC_REG) (const_int 0)])
1210                       (pc)
1211                       (label_ref (match_operand 1 "" ""))))]
1212   ""
1214   return output_cbranch (operands[0], operands[1], 1, 1,
1215                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1216                          insn);
1218   [(set_attr "type" "branch")
1219    (set_attr "branch_type" "icc")])
1221 ;; XXX fpcmp nop braindamage
1222 (define_insn "*normal_fp_branch"
1223   [(set (pc)
1224         (if_then_else (match_operator 1 "comparison_operator"
1225                                       [(match_operand:CCFP 0 "fcc_register_operand" "c")
1226                                        (const_int 0)])
1227                       (label_ref (match_operand 2 "" ""))
1228                       (pc)))]
1229   ""
1231   return output_cbranch (operands[1], operands[2], 2, 0,
1232                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1233                          insn);
1235   [(set_attr "type" "branch")
1236    (set_attr "branch_type" "fcc")])
1238 ;; XXX fpcmp nop braindamage
1239 (define_insn "*inverted_fp_branch"
1240   [(set (pc)
1241         (if_then_else (match_operator 1 "comparison_operator"
1242                                       [(match_operand:CCFP 0 "fcc_register_operand" "c")
1243                                        (const_int 0)])
1244                       (pc)
1245                       (label_ref (match_operand 2 "" ""))))]
1246   ""
1248   return output_cbranch (operands[1], operands[2], 2, 1,
1249                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1250                          insn);
1252   [(set_attr "type" "branch")
1253    (set_attr "branch_type" "fcc")])
1255 ;; XXX fpcmp nop braindamage
1256 (define_insn "*normal_fpe_branch"
1257   [(set (pc)
1258         (if_then_else (match_operator 1 "comparison_operator"
1259                                       [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1260                                        (const_int 0)])
1261                       (label_ref (match_operand 2 "" ""))
1262                       (pc)))]
1263   ""
1265   return output_cbranch (operands[1], operands[2], 2, 0,
1266                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1267                          insn);
1269   [(set_attr "type" "branch")
1270    (set_attr "branch_type" "fcc")])
1272 ;; XXX fpcmp nop braindamage
1273 (define_insn "*inverted_fpe_branch"
1274   [(set (pc)
1275         (if_then_else (match_operator 1 "comparison_operator"
1276                                       [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1277                                        (const_int 0)])
1278                       (pc)
1279                       (label_ref (match_operand 2 "" ""))))]
1280   ""
1282   return output_cbranch (operands[1], operands[2], 2, 1,
1283                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1284                          insn);
1286   [(set_attr "type" "branch")
1287    (set_attr "branch_type" "fcc")])
1289 ;; SPARC V9-specific jump insns.  None of these are guaranteed to be
1290 ;; in the architecture.
1292 (define_insn "*cbcond_sp32"
1293   [(set (pc)
1294         (if_then_else (match_operator 0 "noov_compare_operator"
1295                        [(match_operand:SI 1 "register_operand" "r")
1296                         (match_operand:SI 2 "arith5_operand" "rA")])
1297                       (label_ref (match_operand 3 "" ""))
1298                       (pc)))]
1299   "TARGET_CBCOND"
1301   return output_cbcond (operands[0], operands[3], insn);
1303   [(set_attr "type" "cbcond")])
1305 (define_insn "*cbcond_sp64"
1306   [(set (pc)
1307         (if_then_else (match_operator 0 "noov_compare_operator"
1308                        [(match_operand:DI 1 "register_operand" "r")
1309                         (match_operand:DI 2 "arith5_operand" "rA")])
1310                       (label_ref (match_operand 3 "" ""))
1311                       (pc)))]
1312   "TARGET_ARCH64 && TARGET_CBCOND"
1314   return output_cbcond (operands[0], operands[3], insn);
1316   [(set_attr "type" "cbcond")])
1318 ;; There are no 32 bit brreg insns.
1320 ;; XXX
1321 (define_insn "*normal_int_branch_sp64"
1322   [(set (pc)
1323         (if_then_else (match_operator 0 "v9_register_compare_operator"
1324                                       [(match_operand:DI 1 "register_operand" "r")
1325                                        (const_int 0)])
1326                       (label_ref (match_operand 2 "" ""))
1327                       (pc)))]
1328   "TARGET_ARCH64"
1330   return output_v9branch (operands[0], operands[2], 1, 2, 0,
1331                           final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1332                           insn);
1334   [(set_attr "type" "branch")
1335    (set_attr "branch_type" "reg")])
1337 ;; XXX
1338 (define_insn "*inverted_int_branch_sp64"
1339   [(set (pc)
1340         (if_then_else (match_operator 0 "v9_register_compare_operator"
1341                                       [(match_operand:DI 1 "register_operand" "r")
1342                                        (const_int 0)])
1343                       (pc)
1344                       (label_ref (match_operand 2 "" ""))))]
1345   "TARGET_ARCH64"
1347   return output_v9branch (operands[0], operands[2], 1, 2, 1,
1348                           final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1349                           insn);
1351   [(set_attr "type" "branch")
1352    (set_attr "branch_type" "reg")])
1355 ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic
1356 ;; value subject to a PC-relative relocation.  Operand 2 is a helper function
1357 ;; that adds the PC value at the call point to register #(operand 3).
1359 ;; Even on V9 we use this call sequence with a stub, instead of "rd %pc, ..."
1360 ;; because the RDPC instruction is extremely expensive and incurs a complete
1361 ;; instruction pipeline flush.
1363 (define_insn "load_pcrel_sym<P:mode>"
1364   [(set (match_operand:P 0 "register_operand" "=r")
1365         (unspec:P [(match_operand:P 1 "symbolic_operand" "")
1366                    (match_operand:P 2 "call_address_operand" "")
1367                    (match_operand:P 3 "const_int_operand" "")] UNSPEC_LOAD_PCREL_SYM))
1368    (clobber (reg:P O7_REG))]
1369   "REGNO (operands[0]) == INTVAL (operands[3])"
1371   if (flag_delayed_branch)
1372     return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0";
1373   else
1374     return "sethi\t%%hi(%a1-8), %0\n\tadd\t%0, %%lo(%a1-4), %0\n\tcall\t%a2\n\t nop";
1376   [(set (attr "type") (const_string "multi"))
1377    (set (attr "length")
1378         (if_then_else (eq_attr "delayed_branch" "true")
1379                       (const_int 3)
1380                       (const_int 4)))])
1383 ;; Integer move instructions
1385 (define_expand "movqi"
1386   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1387         (match_operand:QI 1 "general_operand" ""))]
1388   ""
1390   if (sparc_expand_move (QImode, operands))
1391     DONE;
1394 (define_insn "*movqi_insn"
1395   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1396         (match_operand:QI 1 "input_operand"   "rI,m,rJ"))]
1397   "(register_operand (operands[0], QImode)
1398     || register_or_zero_operand (operands[1], QImode))"
1399   "@
1400    mov\t%1, %0
1401    ldub\t%1, %0
1402    stb\t%r1, %0"
1403   [(set_attr "type" "*,load,store")
1404    (set_attr "us3load_type" "*,3cycle,*")])
1406 (define_expand "movhi"
1407   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1408         (match_operand:HI 1 "general_operand" ""))]
1409   ""
1411   if (sparc_expand_move (HImode, operands))
1412     DONE;
1415 (define_insn "*movhi_insn"
1416   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1417         (match_operand:HI 1 "input_operand"   "rI,K,m,rJ"))]
1418   "(register_operand (operands[0], HImode)
1419     || register_or_zero_operand (operands[1], HImode))"
1420   "@
1421    mov\t%1, %0
1422    sethi\t%%hi(%a1), %0
1423    lduh\t%1, %0
1424    sth\t%r1, %0"
1425   [(set_attr "type" "*,*,load,store")
1426    (set_attr "us3load_type" "*,*,3cycle,*")])
1428 ;; We always work with constants here.
1429 (define_insn "*movhi_lo_sum"
1430   [(set (match_operand:HI 0 "register_operand" "=r")
1431         (ior:HI (match_operand:HI 1 "register_operand" "%r")
1432                 (match_operand:HI 2 "small_int_operand" "I")))]
1433   ""
1434   "or\t%1, %2, %0")
1436 (define_expand "movsi"
1437   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1438         (match_operand:SI 1 "general_operand" ""))]
1439   ""
1441   if (sparc_expand_move (SImode, operands))
1442     DONE;
1445 (define_insn "*movsi_insn"
1446   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r, m, r,*f,*f,*f, m,d,d")
1447         (match_operand:SI 1 "input_operand"        "rI,K,m,rJ,*f, r, f, m,*f,J,P"))]
1448   "register_operand (operands[0], SImode)
1449    || register_or_zero_or_all_ones_operand (operands[1], SImode)"
1450   "@
1451    mov\t%1, %0
1452    sethi\t%%hi(%a1), %0
1453    ld\t%1, %0
1454    st\t%r1, %0
1455    movstouw\t%1, %0
1456    movwtos\t%1, %0
1457    fmovs\t%1, %0
1458    ld\t%1, %0
1459    st\t%1, %0
1460    fzeros\t%0
1461    fones\t%0"
1462   [(set_attr "type" "*,*,load,store,vismv,vismv,fpmove,fpload,fpstore,visl,visl")
1463    (set_attr "cpu_feature" "*,*,*,*,vis3,vis3,*,*,*,vis,vis")])
1465 (define_insn "*movsi_lo_sum"
1466   [(set (match_operand:SI 0 "register_operand" "=r")
1467         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1468                    (match_operand:SI 2 "immediate_operand" "in")))]
1469   ""
1470   "or\t%1, %%lo(%a2), %0")
1472 (define_insn "*movsi_high"
1473   [(set (match_operand:SI 0 "register_operand" "=r")
1474         (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1475   ""
1476   "sethi\t%%hi(%a1), %0")
1478 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1479 ;; so that CSE won't optimize the address computation away.
1480 (define_insn "movsi_lo_sum_pic"
1481   [(set (match_operand:SI 0 "register_operand" "=r")
1482         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1483                    (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1484   "flag_pic"
1486 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1487   return "xor\t%1, %%gdop_lox10(%a2), %0";
1488 #else
1489   return "or\t%1, %%lo(%a2), %0";
1490 #endif
1493 (define_insn "movsi_high_pic"
1494   [(set (match_operand:SI 0 "register_operand" "=r")
1495         (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1496   "flag_pic && check_pic (1)"
1498 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1499   return "sethi\t%%gdop_hix22(%a1), %0";
1500 #else
1501   return "sethi\t%%hi(%a1), %0";
1502 #endif
1505 (define_insn "movsi_pic_gotdata_op"
1506   [(set (match_operand:SI 0 "register_operand" "=r")
1507         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
1508                     (match_operand:SI 2 "register_operand" "r")
1509                     (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
1510   "flag_pic && check_pic (1)"
1512 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1513   return "ld\t[%1 + %2], %0, %%gdop(%a3)";
1514 #else
1515   return "ld\t[%1 + %2], %0";
1516 #endif
1518   [(set_attr "type" "load")])
1520 (define_expand "movsi_pic_label_ref"
1521   [(set (match_dup 3) (high:SI
1522      (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1523                  (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1524    (set (match_dup 4) (lo_sum:SI (match_dup 3)
1525      (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1526    (set (match_operand:SI 0 "register_operand" "=r")
1527         (minus:SI (match_dup 5) (match_dup 4)))]
1528   "flag_pic"
1530   crtl->uses_pic_offset_table = 1;
1531   operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1532   if (!can_create_pseudo_p ())
1533     {
1534       operands[3] = operands[0];
1535       operands[4] = operands[0];
1536     }
1537   else
1538     {
1539       operands[3] = gen_reg_rtx (SImode);
1540       operands[4] = gen_reg_rtx (SImode);
1541     }
1542   operands[5] = pic_offset_table_rtx;
1545 (define_insn "*movsi_high_pic_label_ref"
1546   [(set (match_operand:SI 0 "register_operand" "=r")
1547       (high:SI
1548         (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1549                     (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1550   "flag_pic"
1551   "sethi\t%%hi(%a2-(%a1-.)), %0")
1553 (define_insn "*movsi_lo_sum_pic_label_ref"
1554   [(set (match_operand:SI 0 "register_operand" "=r")
1555       (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1556         (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
1557                     (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1558   "flag_pic"
1559   "or\t%1, %%lo(%a3-(%a2-.)), %0")
1561 ;; Set up the PIC register for VxWorks.
1563 (define_expand "vxworks_load_got"
1564   [(set (match_dup 0)
1565         (high:SI (match_dup 1)))
1566    (set (match_dup 0)
1567         (mem:SI (lo_sum:SI (match_dup 0) (match_dup 1))))
1568    (set (match_dup 0)
1569         (mem:SI (lo_sum:SI (match_dup 0) (match_dup 2))))]
1570   "TARGET_VXWORKS_RTP"
1572   operands[0] = pic_offset_table_rtx;
1573   operands[1] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_BASE);
1574   operands[2] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_INDEX);
1577 (define_expand "movdi"
1578   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1579         (match_operand:DI 1 "general_operand" ""))]
1580   ""
1582   if (sparc_expand_move (DImode, operands))
1583     DONE;
1586 ;; Be careful, fmovd does not exist when !v9.
1587 ;; We match MEM moves directly when we have correct even
1588 ;; numbered registers, but fall into splits otherwise.
1589 ;; The constraint ordering here is really important to
1590 ;; avoid insane problems in reload, especially for patterns
1591 ;; of the form:
1593 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
1594 ;;                       (const_int -5016)))
1595 ;;      (reg:DI 2 %g2))
1598 (define_insn "*movdi_insn_sp32"
1599   [(set (match_operand:DI 0 "nonimmediate_operand"
1600                                         "=T,o,T,U,o,r,r,r,?T,?*f,?*f,?o,?*e,?*e,  r,?*f,?*e,?W,b,b")
1601         (match_operand:DI 1 "input_operand"
1602                                         " J,J,U,T,r,o,i,r,*f,  T,  o,*f, *e, *e,?*f,  r,  W,*e,J,P"))]
1603   "! TARGET_ARCH64
1604    && (register_operand (operands[0], DImode)
1605        || register_or_zero_operand (operands[1], DImode))"
1606   "@
1607    stx\t%%g0, %0
1608    #
1609    std\t%1, %0
1610    ldd\t%1, %0
1611    #
1612    #
1613    #
1614    #
1615    std\t%1, %0
1616    ldd\t%1, %0
1617    #
1618    #
1619    fmovd\t%1, %0
1620    #
1621    #
1622    #
1623    ldd\t%1, %0
1624    std\t%1, %0
1625    fzero\t%0
1626    fone\t%0"
1627   [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,*,*,*,fpload,fpstore,visl,visl")
1628    (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,2,2,2,*,*,*,*")
1629    (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*,*,*,*,double,double")
1630    (set_attr "cpu_feature" "v9,*,*,*,*,*,*,*,fpu,fpu,fpu,fpu,v9,fpunotv9,vis3,vis3,fpu,fpu,vis,vis")])
1632 (define_insn "*movdi_insn_sp64"
1633   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r, m, r,*e,?*e,?*e,?W,b,b")
1634         (match_operand:DI 1 "input_operand"        "rI,N,m,rJ,*e, r, *e,  W,*e,J,P"))]
1635   "TARGET_ARCH64
1636    && (register_operand (operands[0], DImode)
1637        || register_or_zero_or_all_ones_operand (operands[1], DImode))"
1638   "@
1639    mov\t%1, %0
1640    sethi\t%%hi(%a1), %0
1641    ldx\t%1, %0
1642    stx\t%r1, %0
1643    movdtox\t%1, %0
1644    movxtod\t%1, %0
1645    fmovd\t%1, %0
1646    ldd\t%1, %0
1647    std\t%1, %0
1648    fzero\t%0
1649    fone\t%0"
1650   [(set_attr "type" "*,*,load,store,vismv,vismv,fpmove,fpload,fpstore,visl,visl")
1651    (set_attr "fptype" "*,*,*,*,*,*,double,*,*,double,double")
1652    (set_attr "cpu_feature" "*,*,*,*,vis3,vis3,*,*,*,vis,vis")])
1654 (define_expand "movdi_pic_label_ref"
1655   [(set (match_dup 3) (high:DI
1656      (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1657                  (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1658    (set (match_dup 4) (lo_sum:DI (match_dup 3)
1659      (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1660    (set (match_operand:DI 0 "register_operand" "=r")
1661         (minus:DI (match_dup 5) (match_dup 4)))]
1662   "TARGET_ARCH64 && flag_pic"
1664   crtl->uses_pic_offset_table = 1;
1665   operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1666   if (!can_create_pseudo_p ())
1667     {
1668       operands[3] = operands[0];
1669       operands[4] = operands[0];
1670     }
1671   else
1672     {
1673       operands[3] = gen_reg_rtx (DImode);
1674       operands[4] = gen_reg_rtx (DImode);
1675     }
1676   operands[5] = pic_offset_table_rtx;
1679 (define_insn "*movdi_high_pic_label_ref"
1680   [(set (match_operand:DI 0 "register_operand" "=r")
1681         (high:DI
1682           (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1683                       (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1684   "TARGET_ARCH64 && flag_pic"
1685   "sethi\t%%hi(%a2-(%a1-.)), %0")
1687 (define_insn "*movdi_lo_sum_pic_label_ref"
1688   [(set (match_operand:DI 0 "register_operand" "=r")
1689       (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1690         (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
1691                     (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1692   "TARGET_ARCH64 && flag_pic"
1693   "or\t%1, %%lo(%a3-(%a2-.)), %0")
1695 ;; SPARC-v9 code model support insns.  See sparc_emit_set_symbolic_const64
1696 ;; in sparc.c to see what is going on here... PIC stuff comes first.
1698 (define_insn "movdi_lo_sum_pic"
1699   [(set (match_operand:DI 0 "register_operand" "=r")
1700         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1701                    (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1702   "TARGET_ARCH64 && flag_pic"
1704 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1705   return "xor\t%1, %%gdop_lox10(%a2), %0";
1706 #else
1707   return "or\t%1, %%lo(%a2), %0";
1708 #endif
1711 (define_insn "movdi_high_pic"
1712   [(set (match_operand:DI 0 "register_operand" "=r")
1713         (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1714   "TARGET_ARCH64 && flag_pic && check_pic (1)"
1716 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1717   return "sethi\t%%gdop_hix22(%a1), %0";
1718 #else
1719   return "sethi\t%%hi(%a1), %0";
1720 #endif
1723 (define_insn "movdi_pic_gotdata_op"
1724   [(set (match_operand:DI 0 "register_operand" "=r")
1725         (unspec:DI [(match_operand:DI 1 "register_operand" "r")
1726                     (match_operand:DI 2 "register_operand" "r")
1727                     (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
1728   "TARGET_ARCH64 && flag_pic && check_pic (1)"
1730 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1731   return "ldx\t[%1 + %2], %0, %%gdop(%a3)";
1732 #else
1733   return "ldx\t[%1 + %2], %0";
1734 #endif
1736   [(set_attr "type" "load")])
1738 (define_insn "*sethi_di_medlow_embmedany_pic"
1739   [(set (match_operand:DI 0 "register_operand" "=r")
1740         (high:DI (match_operand:DI 1 "medium_pic_operand" "")))]
1741   "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
1742   "sethi\t%%hi(%a1), %0")
1744 (define_insn "*sethi_di_medlow"
1745   [(set (match_operand:DI 0 "register_operand" "=r")
1746         (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
1747   "TARGET_CM_MEDLOW && check_pic (1)"
1748   "sethi\t%%hi(%a1), %0")
1750 (define_insn "*losum_di_medlow"
1751   [(set (match_operand:DI 0 "register_operand" "=r")
1752         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1753                    (match_operand:DI 2 "symbolic_operand" "")))]
1754   "TARGET_CM_MEDLOW"
1755   "or\t%1, %%lo(%a2), %0")
1757 (define_insn "seth44"
1758   [(set (match_operand:DI 0 "register_operand" "=r")
1759         (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
1760   "TARGET_CM_MEDMID"
1761   "sethi\t%%h44(%a1), %0")
1763 (define_insn "setm44"
1764   [(set (match_operand:DI 0 "register_operand" "=r")
1765         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1766                    (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
1767   "TARGET_CM_MEDMID"
1768   "or\t%1, %%m44(%a2), %0")
1770 (define_insn "setl44"
1771   [(set (match_operand:DI 0 "register_operand" "=r")
1772         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1773                    (match_operand:DI 2 "symbolic_operand" "")))]
1774   "TARGET_CM_MEDMID"
1775   "or\t%1, %%l44(%a2), %0")
1777 (define_insn "sethh"
1778   [(set (match_operand:DI 0 "register_operand" "=r")
1779         (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
1780   "TARGET_CM_MEDANY"
1781   "sethi\t%%hh(%a1), %0")
1783 (define_insn "setlm"
1784   [(set (match_operand:DI 0 "register_operand" "=r")
1785         (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
1786   "TARGET_CM_MEDANY"
1787   "sethi\t%%lm(%a1), %0")
1789 (define_insn "sethm"
1790   [(set (match_operand:DI 0 "register_operand" "=r")
1791         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1792                    (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
1793   "TARGET_CM_MEDANY"
1794   "or\t%1, %%hm(%a2), %0")
1796 (define_insn "setlo"
1797   [(set (match_operand:DI 0 "register_operand" "=r")
1798         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1799                    (match_operand:DI 2 "symbolic_operand" "")))]
1800   "TARGET_CM_MEDANY"
1801   "or\t%1, %%lo(%a2), %0")
1803 (define_insn "embmedany_sethi"
1804   [(set (match_operand:DI 0 "register_operand" "=r")
1805         (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
1806   "TARGET_CM_EMBMEDANY && check_pic (1)"
1807   "sethi\t%%hi(%a1), %0")
1809 (define_insn "embmedany_losum"
1810   [(set (match_operand:DI 0 "register_operand" "=r")
1811         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1812                    (match_operand:DI 2 "data_segment_operand" "")))]
1813   "TARGET_CM_EMBMEDANY"
1814   "add\t%1, %%lo(%a2), %0")
1816 (define_insn "embmedany_brsum"
1817   [(set (match_operand:DI 0 "register_operand" "=r")
1818         (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
1819   "TARGET_CM_EMBMEDANY"
1820   "add\t%1, %_, %0")
1822 (define_insn "embmedany_textuhi"
1823   [(set (match_operand:DI 0 "register_operand" "=r")
1824         (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
1825   "TARGET_CM_EMBMEDANY && check_pic (1)"
1826   "sethi\t%%uhi(%a1), %0")
1828 (define_insn "embmedany_texthi"
1829   [(set (match_operand:DI 0 "register_operand" "=r")
1830         (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
1831   "TARGET_CM_EMBMEDANY && check_pic (1)"
1832   "sethi\t%%hi(%a1), %0")
1834 (define_insn "embmedany_textulo"
1835   [(set (match_operand:DI 0 "register_operand" "=r")
1836         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1837                    (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
1838   "TARGET_CM_EMBMEDANY"
1839   "or\t%1, %%ulo(%a2), %0")
1841 (define_insn "embmedany_textlo"
1842   [(set (match_operand:DI 0 "register_operand" "=r")
1843         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1844                    (match_operand:DI 2 "text_segment_operand" "")))]
1845   "TARGET_CM_EMBMEDANY"
1846   "or\t%1, %%lo(%a2), %0")
1848 ;; Now some patterns to help reload out a bit.
1849 (define_expand "reload_indi"
1850   [(parallel [(match_operand:DI 0 "register_operand" "=r")
1851               (match_operand:DI 1 "immediate_operand" "")
1852               (match_operand:TI 2 "register_operand" "=&r")])]
1853   "(TARGET_CM_MEDANY
1854     || TARGET_CM_EMBMEDANY)
1855    && ! flag_pic"
1857   sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1858   DONE;
1861 (define_expand "reload_outdi"
1862   [(parallel [(match_operand:DI 0 "register_operand" "=r")
1863               (match_operand:DI 1 "immediate_operand" "")
1864               (match_operand:TI 2 "register_operand" "=&r")])]
1865   "(TARGET_CM_MEDANY
1866     || TARGET_CM_EMBMEDANY)
1867    && ! flag_pic"
1869   sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1870   DONE;
1873 ;; Split up putting CONSTs and REGs into DI regs when !arch64
1874 (define_split
1875   [(set (match_operand:DI 0 "register_operand" "")
1876         (match_operand:DI 1 "const_int_operand" ""))]
1877   "! TARGET_ARCH64
1878    && ((GET_CODE (operands[0]) == REG
1879         && SPARC_INT_REG_P (REGNO (operands[0])))
1880        || (GET_CODE (operands[0]) == SUBREG
1881            && GET_CODE (SUBREG_REG (operands[0])) == REG
1882            && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))
1883    && reload_completed"
1884   [(clobber (const_int 0))]
1886 #if HOST_BITS_PER_WIDE_INT == 32
1887   emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1888                         (INTVAL (operands[1]) < 0) ?
1889                         constm1_rtx :
1890                         const0_rtx));
1891   emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1892                         operands[1]));
1893 #else
1894   HOST_WIDE_INT low, high;
1896   low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
1897   high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
1898   emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
1900   /* Slick... but this trick loses if this subreg constant part
1901      can be done in one insn.  */
1902   if (low == high
1903       && ! SPARC_SETHI32_P (high)
1904       && ! SPARC_SIMM13_P (high))
1905     emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1906                           gen_highpart (SImode, operands[0])));
1907   else
1908     emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
1909 #endif
1910   DONE;
1913 (define_split
1914   [(set (match_operand:DI 0 "register_operand" "")
1915         (match_operand:DI 1 "const_double_operand" ""))]
1916   "reload_completed
1917    && (! TARGET_V9
1918        || (! TARGET_ARCH64
1919            && ((GET_CODE (operands[0]) == REG
1920                 && SPARC_INT_REG_P (REGNO (operands[0])))
1921                || (GET_CODE (operands[0]) == SUBREG
1922                    && GET_CODE (SUBREG_REG (operands[0])) == REG
1923                    && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))))"
1924   [(clobber (const_int 0))]
1926   emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1927                         GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
1929   /* Slick... but this trick loses if this subreg constant part
1930      can be done in one insn.  */
1931   if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
1932       && ! SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
1933       && ! SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1])))
1934     {
1935       emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1936                             gen_highpart (SImode, operands[0])));
1937     }
1938   else
1939     {
1940       emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1941                             GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
1942     }
1943   DONE;
1946 (define_split
1947   [(set (match_operand:DI 0 "register_operand" "")
1948         (match_operand:DI 1 "register_operand" ""))]
1949   "reload_completed
1950    && (! TARGET_V9
1951        || (! TARGET_ARCH64
1952            && sparc_split_regreg_legitimate (operands[0],
1953                                              operands[1])))"
1954   [(clobber (const_int 0))]
1956   rtx set_dest = operands[0];
1957   rtx set_src = operands[1];
1958   rtx dest1, dest2;
1959   rtx src1, src2;
1961   dest1 = gen_highpart (SImode, set_dest);
1962   dest2 = gen_lowpart (SImode, set_dest);
1963   src1 = gen_highpart (SImode, set_src);
1964   src2 = gen_lowpart (SImode, set_src);
1966   /* Now emit using the real source and destination we found, swapping
1967      the order if we detect overlap.  */
1968   if (reg_overlap_mentioned_p (dest1, src2))
1969     {
1970       emit_insn (gen_movsi (dest2, src2));
1971       emit_insn (gen_movsi (dest1, src1));
1972     }
1973   else
1974     {
1975       emit_insn (gen_movsi (dest1, src1));
1976       emit_insn (gen_movsi (dest2, src2));
1977     }
1978   DONE;
1981 ;; Now handle the cases of memory moves from/to non-even
1982 ;; DI mode register pairs.
1983 (define_split
1984   [(set (match_operand:DI 0 "register_operand" "")
1985         (match_operand:DI 1 "memory_operand" ""))]
1986   "(! TARGET_ARCH64
1987     && reload_completed
1988     && sparc_splitdi_legitimate (operands[0], operands[1]))"
1989   [(clobber (const_int 0))]
1991   rtx word0 = adjust_address (operands[1], SImode, 0);
1992   rtx word1 = adjust_address (operands[1], SImode, 4);
1993   rtx high_part = gen_highpart (SImode, operands[0]);
1994   rtx low_part = gen_lowpart (SImode, operands[0]);
1996   if (reg_overlap_mentioned_p (high_part, word1))
1997     {
1998       emit_insn (gen_movsi (low_part, word1));
1999       emit_insn (gen_movsi (high_part, word0));
2000     }
2001   else
2002     {
2003       emit_insn (gen_movsi (high_part, word0));
2004       emit_insn (gen_movsi (low_part, word1));
2005     }
2006   DONE;
2009 (define_split
2010   [(set (match_operand:DI 0 "memory_operand" "")
2011         (match_operand:DI 1 "register_operand" ""))]
2012   "(! TARGET_ARCH64
2013     && reload_completed
2014     && sparc_splitdi_legitimate (operands[1], operands[0]))"
2015   [(clobber (const_int 0))]
2017   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
2018                         gen_highpart (SImode, operands[1])));
2019   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
2020                         gen_lowpart (SImode, operands[1])));
2021   DONE;
2024 (define_split
2025   [(set (match_operand:DI 0 "memory_operand" "")
2026         (match_operand:DI 1 "const_zero_operand" ""))]
2027   "reload_completed
2028    && (! TARGET_V9
2029        || (! TARGET_ARCH64
2030            && ! mem_min_alignment (operands[0], 8)))
2031    && offsettable_memref_p (operands[0])"
2032   [(clobber (const_int 0))]
2034   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
2035   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
2036   DONE;
2039 (define_expand "movti"
2040   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2041         (match_operand:TI 1 "general_operand" ""))]
2042   "TARGET_ARCH64"
2044   if (sparc_expand_move (TImode, operands))
2045     DONE;
2048 ;; We need to prevent reload from splitting TImode moves, because it
2049 ;; might decide to overwrite a pointer with the value it points to.
2050 ;; In that case we have to do the loads in the appropriate order so
2051 ;; that the pointer is not destroyed too early.
2053 (define_insn "*movti_insn_sp64"
2054   [(set (match_operand:TI 0 "nonimmediate_operand" "=r , o,?*e,?o,b")
2055         (match_operand:TI 1 "input_operand"        "roJ,rJ, eo, e,J"))]
2056   "TARGET_ARCH64
2057    && ! TARGET_HARD_QUAD
2058    && (register_operand (operands[0], TImode)
2059        || register_or_zero_operand (operands[1], TImode))"
2060   "#"
2061   [(set_attr "length" "2,2,2,2,2")
2062    (set_attr "cpu_feature" "*,*,fpu,fpu,vis")])
2064 (define_insn "*movti_insn_sp64_hq"
2065   [(set (match_operand:TI 0 "nonimmediate_operand" "=r , o,?*e,?*e,?m,b")
2066         (match_operand:TI 1 "input_operand"        "roJ,rJ,  e,  m, e,J"))]
2067   "TARGET_ARCH64
2068    && TARGET_HARD_QUAD
2069    && (register_operand (operands[0], TImode)
2070        || register_or_zero_operand (operands[1], TImode))"
2071   "@
2072   #
2073   #
2074   fmovq\t%1, %0
2075   ldq\t%1, %0
2076   stq\t%1, %0
2077   #"
2078   [(set_attr "type" "*,*,fpmove,fpload,fpstore,*")
2079    (set_attr "length" "2,2,*,*,*,2")])
2081 ;; Now all the splits to handle multi-insn TI mode moves.
2082 (define_split
2083   [(set (match_operand:TI 0 "register_operand" "")
2084         (match_operand:TI 1 "register_operand" ""))]
2085   "reload_completed
2086    && ((TARGET_FPU
2087         && ! TARGET_HARD_QUAD)
2088        || (! fp_register_operand (operands[0], TImode)
2089            && ! fp_register_operand (operands[1], TImode)))"
2090   [(clobber (const_int 0))]
2092   rtx set_dest = operands[0];
2093   rtx set_src = operands[1];
2094   rtx dest1, dest2;
2095   rtx src1, src2;
2097   dest1 = gen_highpart (DImode, set_dest);
2098   dest2 = gen_lowpart (DImode, set_dest);
2099   src1 = gen_highpart (DImode, set_src);
2100   src2 = gen_lowpart (DImode, set_src);
2102   /* Now emit using the real source and destination we found, swapping
2103      the order if we detect overlap.  */
2104   if (reg_overlap_mentioned_p (dest1, src2))
2105     {
2106       emit_insn (gen_movdi (dest2, src2));
2107       emit_insn (gen_movdi (dest1, src1));
2108     }
2109   else
2110     {
2111       emit_insn (gen_movdi (dest1, src1));
2112       emit_insn (gen_movdi (dest2, src2));
2113     }
2114   DONE;
2117 (define_split
2118   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2119         (match_operand:TI 1 "const_zero_operand" ""))]
2120   "reload_completed"
2121   [(clobber (const_int 0))]
2123   rtx set_dest = operands[0];
2124   rtx dest1, dest2;
2126   switch (GET_CODE (set_dest))
2127     {
2128     case REG:
2129       dest1 = gen_highpart (DImode, set_dest);
2130       dest2 = gen_lowpart (DImode, set_dest);
2131       break;
2132     case MEM:
2133       dest1 = adjust_address (set_dest, DImode, 0);
2134       dest2 = adjust_address (set_dest, DImode, 8);
2135       break;
2136     default:
2137       gcc_unreachable ();
2138     }
2140   emit_insn (gen_movdi (dest1, const0_rtx));
2141   emit_insn (gen_movdi (dest2, const0_rtx));
2142   DONE;
2145 (define_split
2146   [(set (match_operand:TI 0 "register_operand" "")
2147         (match_operand:TI 1 "memory_operand" ""))]
2148   "reload_completed
2149    && offsettable_memref_p (operands[1])
2150    && (! TARGET_HARD_QUAD
2151        || ! fp_register_operand (operands[0], TImode))"
2152   [(clobber (const_int 0))]
2154   rtx word0 = adjust_address (operands[1], DImode, 0);
2155   rtx word1 = adjust_address (operands[1], DImode, 8);
2156   rtx set_dest, dest1, dest2;
2158   set_dest = operands[0];
2160   dest1 = gen_highpart (DImode, set_dest);
2161   dest2 = gen_lowpart (DImode, set_dest);
2163   /* Now output, ordering such that we don't clobber any registers
2164      mentioned in the address.  */
2165   if (reg_overlap_mentioned_p (dest1, word1))
2167     {
2168       emit_insn (gen_movdi (dest2, word1));
2169       emit_insn (gen_movdi (dest1, word0));
2170     }
2171   else
2172    {
2173       emit_insn (gen_movdi (dest1, word0));
2174       emit_insn (gen_movdi (dest2, word1));
2175    }
2176   DONE;
2179 (define_split
2180   [(set (match_operand:TI 0 "memory_operand" "")
2181         (match_operand:TI 1 "register_operand" ""))]
2182   "reload_completed
2183    && offsettable_memref_p (operands[0])
2184    && (! TARGET_HARD_QUAD
2185        || ! fp_register_operand (operands[1], TImode))"
2186   [(clobber (const_int 0))]
2188   rtx set_src = operands[1];
2190   emit_insn (gen_movdi (adjust_address (operands[0], DImode, 0),
2191                         gen_highpart (DImode, set_src)));
2192   emit_insn (gen_movdi (adjust_address (operands[0], DImode, 8),
2193                         gen_lowpart (DImode, set_src)));
2194   DONE;
2198 ;; Floating point move instructions
2200 (define_expand "movsf"
2201   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2202         (match_operand:SF 1 "general_operand" ""))]
2203   ""
2205   if (sparc_expand_move (SFmode, operands))
2206     DONE;
2209 (define_insn "*movsf_insn"
2210   [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,f, *r,*r,*r,*r, f,f,*r,m,  m")
2211         (match_operand:SF 1 "input_operand"         "G,C,f,*rR, Q, S, f,*r,m, m,f,*rG"))]
2212   "(register_operand (operands[0], SFmode)
2213     || register_or_zero_or_all_ones_operand (operands[1], SFmode))"
2215   if (GET_CODE (operands[1]) == CONST_DOUBLE
2216       && (which_alternative == 3
2217           || which_alternative == 4
2218           || which_alternative == 5))
2219     {
2220       REAL_VALUE_TYPE r;
2221       long i;
2223       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2224       REAL_VALUE_TO_TARGET_SINGLE (r, i);
2225       operands[1] = GEN_INT (i);
2226     }
2228   switch (which_alternative)
2229     {
2230     case 0:
2231       return "fzeros\t%0";
2232     case 1:
2233       return "fones\t%0";
2234     case 2:
2235       return "fmovs\t%1, %0";
2236     case 3:
2237       return "mov\t%1, %0";
2238     case 4:
2239       return "sethi\t%%hi(%a1), %0";
2240     case 5:
2241       return "#";
2242     case 6:
2243       return "movstouw\t%1, %0";
2244     case 7:
2245       return "movwtos\t%1, %0";
2246     case 8:
2247     case 9:
2248       return "ld\t%1, %0";
2249     case 10:
2250     case 11:
2251       return "st\t%r1, %0";
2252     default:
2253       gcc_unreachable ();
2254     }
2256   [(set_attr "type" "visl,visl,fpmove,*,*,*,vismv,vismv,fpload,load,fpstore,store")
2257    (set_attr "cpu_feature" "vis,vis,fpu,*,*,*,vis3,vis3,fpu,*,fpu,*")])
2259 ;; The following 3 patterns build SFmode constants in integer registers.
2261 (define_insn "*movsf_lo_sum"
2262   [(set (match_operand:SF 0 "register_operand" "=r")
2263         (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
2264                    (match_operand:SF 2 "fp_const_high_losum_operand" "S")))]
2265   ""
2267   REAL_VALUE_TYPE r;
2268   long i;
2270   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
2271   REAL_VALUE_TO_TARGET_SINGLE (r, i);
2272   operands[2] = GEN_INT (i);
2273   return "or\t%1, %%lo(%a2), %0";
2276 (define_insn "*movsf_high"
2277   [(set (match_operand:SF 0 "register_operand" "=r")
2278         (high:SF (match_operand:SF 1 "fp_const_high_losum_operand" "S")))]
2279   ""
2281   REAL_VALUE_TYPE r;
2282   long i;
2284   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2285   REAL_VALUE_TO_TARGET_SINGLE (r, i);
2286   operands[1] = GEN_INT (i);
2287   return "sethi\t%%hi(%1), %0";
2290 (define_split
2291   [(set (match_operand:SF 0 "register_operand" "")
2292         (match_operand:SF 1 "fp_const_high_losum_operand" ""))]
2293   "REG_P (operands[0]) && SPARC_INT_REG_P (REGNO (operands[0]))"
2294   [(set (match_dup 0) (high:SF (match_dup 1)))
2295    (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
2297 (define_expand "movdf"
2298   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2299         (match_operand:DF 1 "general_operand" ""))]
2300   ""
2302   if (sparc_expand_move (DFmode, operands))
2303     DONE;
2306 (define_insn "*movdf_insn_sp32"
2307   [(set (match_operand:DF 0 "nonimmediate_operand" "=b,b,e,e,*r, f,  e,T,W,U,T,  f,  *r,  o,o")
2308         (match_operand:DF 1 "input_operand"         "G,C,e,e, f,*r,W#F,G,e,T,U,o#F,*roF,*rG,f"))]
2309   "! TARGET_ARCH64
2310    && (register_operand (operands[0], DFmode)
2311        || register_or_zero_or_all_ones_operand (operands[1], DFmode))"
2312   "@
2313   fzero\t%0
2314   fone\t%0
2315   fmovd\t%1, %0
2316   #
2317   #
2318   #
2319   ldd\t%1, %0
2320   stx\t%r1, %0
2321   std\t%1, %0
2322   ldd\t%1, %0
2323   std\t%1, %0
2324   #
2325   #
2326   #
2327   #"
2328   [(set_attr "type" "visl,visl,fpmove,*,*,*,fpload,store,fpstore,load,store,*,*,*,*")
2329    (set_attr "length" "*,*,*,2,2,2,*,*,*,*,*,2,2,2,2")
2330    (set_attr "fptype" "double,double,double,*,*,*,*,*,*,*,*,*,*,*,*")
2331    (set_attr "cpu_feature" "vis,vis,v9,fpunotv9,vis3,vis3,fpu,v9,fpu,*,*,fpu,*,*,fpu")])
2333 (define_insn "*movdf_insn_sp64"
2334   [(set (match_operand:DF 0 "nonimmediate_operand" "=b,b,e,*r, e,  e,W, *r,*r,  m,*r")
2335         (match_operand:DF 1 "input_operand"         "G,C,e, e,*r,W#F,e,*rG, m,*rG, F"))]
2336   "TARGET_ARCH64
2337    && (register_operand (operands[0], DFmode)
2338        || register_or_zero_or_all_ones_operand (operands[1], DFmode))"
2339   "@
2340   fzero\t%0
2341   fone\t%0
2342   fmovd\t%1, %0
2343   movdtox\t%1, %0
2344   movxtod\t%1, %0
2345   ldd\t%1, %0
2346   std\t%1, %0
2347   mov\t%r1, %0
2348   ldx\t%1, %0
2349   stx\t%r1, %0
2350   #"
2351   [(set_attr "type" "visl,visl,fpmove,vismv,vismv,load,store,*,load,store,*")
2352    (set_attr "length" "*,*,*,*,*,*,*,*,*,*,2")
2353    (set_attr "fptype" "double,double,double,double,double,*,*,*,*,*,*")
2354    (set_attr "cpu_feature" "vis,vis,fpu,vis3,vis3,fpu,fpu,*,*,*,*")])
2356 ;; This pattern builds DFmode constants in integer registers.
2357 (define_split
2358   [(set (match_operand:DF 0 "register_operand" "")
2359         (match_operand:DF 1 "const_double_operand" ""))]
2360   "REG_P (operands[0])
2361    && SPARC_INT_REG_P (REGNO (operands[0]))
2362    && ! const_zero_operand (operands[1], GET_MODE (operands[0]))
2363    && reload_completed"
2364   [(clobber (const_int 0))]
2366   operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
2368   if (TARGET_ARCH64)
2369     {
2370 #if HOST_BITS_PER_WIDE_INT == 32
2371       gcc_unreachable ();
2372 #else
2373       enum machine_mode mode = GET_MODE (operands[1]);
2374       rtx tem = simplify_subreg (DImode, operands[1], mode, 0);
2375       emit_insn (gen_movdi (operands[0], tem));
2376 #endif
2377     }
2378   else
2379     {
2380       enum machine_mode mode = GET_MODE (operands[1]);
2381       rtx hi = simplify_subreg (SImode, operands[1], mode, 0);
2382       rtx lo = simplify_subreg (SImode, operands[1], mode, 4);
2384       gcc_assert (GET_CODE (hi) == CONST_INT);
2385       gcc_assert (GET_CODE (lo) == CONST_INT);
2387       emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), hi));
2389       /* Slick... but this trick loses if this subreg constant part
2390          can be done in one insn.  */
2391       if (lo == hi
2392           && ! SPARC_SETHI32_P (INTVAL (hi))
2393           && ! SPARC_SIMM13_P (INTVAL (hi)))
2394         {
2395           emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2396                                 gen_highpart (SImode, operands[0])));
2397         }
2398       else
2399         {
2400           emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), lo));
2401         }
2402     }
2403   DONE;
2406 ;; Ok, now the splits to handle all the multi insn and
2407 ;; mis-aligned memory address cases.
2408 ;; In these splits please take note that we must be
2409 ;; careful when V9 but not ARCH64 because the integer
2410 ;; register DFmode cases must be handled.
2411 (define_split
2412   [(set (match_operand:DF 0 "register_operand" "")
2413         (match_operand:DF 1 "register_operand" ""))]
2414   "(! TARGET_V9
2415     || (! TARGET_ARCH64
2416         && sparc_split_regreg_legitimate (operands[0],
2417                                           operands[1])))
2418    && reload_completed"
2419   [(clobber (const_int 0))]
2421   rtx set_dest = operands[0];
2422   rtx set_src = operands[1];
2423   rtx dest1, dest2;
2424   rtx src1, src2;
2426   dest1 = gen_highpart (SFmode, set_dest);
2427   dest2 = gen_lowpart (SFmode, set_dest);
2428   src1 = gen_highpart (SFmode, set_src);
2429   src2 = gen_lowpart (SFmode, set_src);
2431   /* Now emit using the real source and destination we found, swapping
2432      the order if we detect overlap.  */
2433   if (reg_overlap_mentioned_p (dest1, src2))
2434     {
2435       emit_move_insn_1 (dest2, src2);
2436       emit_move_insn_1 (dest1, src1);
2437     }
2438   else
2439     {
2440       emit_move_insn_1 (dest1, src1);
2441       emit_move_insn_1 (dest2, src2);
2442     }
2443   DONE;
2446 (define_split
2447   [(set (match_operand:DF 0 "register_operand" "")
2448         (match_operand:DF 1 "memory_operand" ""))]
2449   "reload_completed
2450    && ! TARGET_ARCH64
2451    && (((REGNO (operands[0]) % 2) != 0)
2452        || ! mem_min_alignment (operands[1], 8))
2453    && offsettable_memref_p (operands[1])"
2454   [(clobber (const_int 0))]
2456   rtx word0, word1;
2458   word0 = adjust_address (operands[1], SFmode, 0);
2459   word1 = adjust_address (operands[1], SFmode, 4);
2461   if (reg_overlap_mentioned_p (gen_highpart (SFmode, operands[0]), word1))
2462     {
2463       emit_move_insn_1 (gen_lowpart (SFmode, operands[0]), word1);
2464       emit_move_insn_1 (gen_highpart (SFmode, operands[0]), word0);
2465     }
2466   else
2467     {
2468       emit_move_insn_1 (gen_highpart (SFmode, operands[0]), word0);
2469       emit_move_insn_1 (gen_lowpart (SFmode, operands[0]), word1);
2470     }
2471   DONE;
2474 (define_split
2475   [(set (match_operand:DF 0 "memory_operand" "")
2476         (match_operand:DF 1 "register_operand" ""))]
2477   "reload_completed
2478    && ! TARGET_ARCH64
2479    && (((REGNO (operands[1]) % 2) != 0)
2480        || ! mem_min_alignment (operands[0], 8))
2481    && offsettable_memref_p (operands[0])"
2482   [(clobber (const_int 0))]
2484   rtx word0, word1;
2486   word0 = adjust_address (operands[0], SFmode, 0);
2487   word1 = adjust_address (operands[0], SFmode, 4);
2489   emit_move_insn_1 (word0, gen_highpart (SFmode, operands[1]));
2490   emit_move_insn_1 (word1, gen_lowpart (SFmode, operands[1]));
2491   DONE;
2494 (define_split
2495   [(set (match_operand:DF 0 "memory_operand" "")
2496         (match_operand:DF 1 "const_zero_operand" ""))]
2497   "reload_completed
2498    && (! TARGET_V9
2499        || (! TARGET_ARCH64
2500            && ! mem_min_alignment (operands[0], 8)))
2501    && offsettable_memref_p (operands[0])"
2502   [(clobber (const_int 0))]
2504   rtx dest1, dest2;
2506   dest1 = adjust_address (operands[0], SFmode, 0);
2507   dest2 = adjust_address (operands[0], SFmode, 4);
2509   emit_move_insn_1 (dest1, CONST0_RTX (SFmode));
2510   emit_move_insn_1 (dest2, CONST0_RTX (SFmode));
2511   DONE;
2514 (define_split
2515   [(set (match_operand:DF 0 "register_operand" "")
2516         (match_operand:DF 1 "const_zero_operand" ""))]
2517   "reload_completed
2518    && ! TARGET_ARCH64
2519    && ((GET_CODE (operands[0]) == REG
2520         && SPARC_INT_REG_P (REGNO (operands[0])))
2521        || (GET_CODE (operands[0]) == SUBREG
2522            && GET_CODE (SUBREG_REG (operands[0])) == REG
2523            && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
2524   [(clobber (const_int 0))]
2526   rtx set_dest = operands[0];
2527   rtx dest1, dest2;
2529   dest1 = gen_highpart (SFmode, set_dest);
2530   dest2 = gen_lowpart (SFmode, set_dest);
2531   emit_move_insn_1 (dest1, CONST0_RTX (SFmode));
2532   emit_move_insn_1 (dest2, CONST0_RTX (SFmode));
2533   DONE;
2536 (define_expand "movtf"
2537   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2538         (match_operand:TF 1 "general_operand" ""))]
2539   ""
2541   if (sparc_expand_move (TFmode, operands))
2542     DONE;
2545 (define_insn "*movtf_insn_sp32"
2546   [(set (match_operand:TF 0 "nonimmediate_operand" "=b, e,o,  o,U,  r")
2547         (match_operand:TF 1 "input_operand"        " G,oe,e,rGU,o,roG"))]
2548   "! TARGET_ARCH64
2549    && (register_operand (operands[0], TFmode)
2550        || register_or_zero_operand (operands[1], TFmode))"
2551   "#"
2552   [(set_attr "length" "4,4,4,4,4,4")
2553    (set_attr "cpu_feature" "fpu,fpu,fpu,*,*,*")])
2555 (define_insn "*movtf_insn_sp64"
2556   [(set (match_operand:TF 0 "nonimmediate_operand" "=b, e,o, o,  r")
2557         (match_operand:TF 1 "input_operand"         "G,oe,e,rG,roG"))]
2558   "TARGET_ARCH64
2559    && ! TARGET_HARD_QUAD
2560    && (register_operand (operands[0], TFmode)
2561        || register_or_zero_operand (operands[1], TFmode))"
2562   "#"
2563   [(set_attr "length" "2,2,2,2,2")
2564    (set_attr "cpu_feature" "fpu,fpu,fpu,*,*")])
2566 (define_insn "*movtf_insn_sp64_hq"
2567   [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,e,m, o,  r")
2568         (match_operand:TF 1 "input_operand"         "G,e,m,e,rG,roG"))]
2569   "TARGET_ARCH64
2570    && TARGET_HARD_QUAD
2571    && (register_operand (operands[0], TFmode)
2572        || register_or_zero_operand (operands[1], TFmode))"
2573   "@
2574   #
2575   fmovq\t%1, %0
2576   ldq\t%1, %0
2577   stq\t%1, %0
2578   #
2579   #"
2580   [(set_attr "type" "*,fpmove,fpload,fpstore,*,*")
2581    (set_attr "length" "2,*,*,*,2,2")])
2583 ;; Now all the splits to handle multi-insn TF mode moves.
2584 (define_split
2585   [(set (match_operand:TF 0 "register_operand" "")
2586         (match_operand:TF 1 "register_operand" ""))]
2587   "reload_completed
2588    && (! TARGET_ARCH64
2589        || (TARGET_FPU
2590            && ! TARGET_HARD_QUAD)
2591        || (! fp_register_operand (operands[0], TFmode)
2592            && ! fp_register_operand (operands[1], TFmode)))"
2593   [(clobber (const_int 0))]
2595   rtx set_dest = operands[0];
2596   rtx set_src = operands[1];
2597   rtx dest1, dest2;
2598   rtx src1, src2;
2600   dest1 = gen_df_reg (set_dest, 0);
2601   dest2 = gen_df_reg (set_dest, 1);
2602   src1 = gen_df_reg (set_src, 0);
2603   src2 = gen_df_reg (set_src, 1);
2605   /* Now emit using the real source and destination we found, swapping
2606      the order if we detect overlap.  */
2607   if (reg_overlap_mentioned_p (dest1, src2))
2608     {
2609       emit_insn (gen_movdf (dest2, src2));
2610       emit_insn (gen_movdf (dest1, src1));
2611     }
2612   else
2613     {
2614       emit_insn (gen_movdf (dest1, src1));
2615       emit_insn (gen_movdf (dest2, src2));
2616     }
2617   DONE;
2620 (define_split
2621   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2622         (match_operand:TF 1 "const_zero_operand" ""))]
2623   "reload_completed"
2624   [(clobber (const_int 0))]
2626   rtx set_dest = operands[0];
2627   rtx dest1, dest2;
2629   switch (GET_CODE (set_dest))
2630     {
2631     case REG:
2632       dest1 = gen_df_reg (set_dest, 0);
2633       dest2 = gen_df_reg (set_dest, 1);
2634       break;
2635     case MEM:
2636       dest1 = adjust_address (set_dest, DFmode, 0);
2637       dest2 = adjust_address (set_dest, DFmode, 8);
2638       break;
2639     default:
2640       gcc_unreachable ();
2641     }
2643   emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
2644   emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
2645   DONE;
2648 (define_split
2649   [(set (match_operand:TF 0 "register_operand" "")
2650         (match_operand:TF 1 "memory_operand" ""))]
2651   "(reload_completed
2652     && offsettable_memref_p (operands[1])
2653     && (! TARGET_ARCH64
2654         || ! TARGET_HARD_QUAD
2655         || ! fp_register_operand (operands[0], TFmode)))"
2656   [(clobber (const_int 0))]
2658   rtx word0 = adjust_address (operands[1], DFmode, 0);
2659   rtx word1 = adjust_address (operands[1], DFmode, 8);
2660   rtx set_dest, dest1, dest2;
2662   set_dest = operands[0];
2664   dest1 = gen_df_reg (set_dest, 0);
2665   dest2 = gen_df_reg (set_dest, 1);
2667   /* Now output, ordering such that we don't clobber any registers
2668      mentioned in the address.  */
2669   if (reg_overlap_mentioned_p (dest1, word1))
2671     {
2672       emit_insn (gen_movdf (dest2, word1));
2673       emit_insn (gen_movdf (dest1, word0));
2674     }
2675   else
2676    {
2677       emit_insn (gen_movdf (dest1, word0));
2678       emit_insn (gen_movdf (dest2, word1));
2679    }
2680   DONE;
2683 (define_split
2684   [(set (match_operand:TF 0 "memory_operand" "")
2685         (match_operand:TF 1 "register_operand" ""))]
2686   "(reload_completed
2687     && offsettable_memref_p (operands[0])
2688     && (! TARGET_ARCH64
2689         || ! TARGET_HARD_QUAD
2690         || ! fp_register_operand (operands[1], TFmode)))"
2691   [(clobber (const_int 0))]
2693   rtx set_src = operands[1];
2695   emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
2696                         gen_df_reg (set_src, 0)));
2697   emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
2698                         gen_df_reg (set_src, 1)));
2699   DONE;
2703 ;; SPARC-V9 conditional move instructions
2705 ;; We can handle larger constants here for some flavors, but for now we keep
2706 ;; it simple and only allow those constants supported by all flavors.
2707 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
2708 ;; 3 contains the constant if one is present, but we handle either for
2709 ;; generality (sparc.c puts a constant in operand 2).
2711 ;; Our instruction patterns, on the other hand, canonicalize such that
2712 ;; operand 3 must be the set destination.
2714 (define_expand "mov<I:mode>cc"
2715   [(set (match_operand:I 0 "register_operand" "")
2716         (if_then_else:I (match_operand 1 "comparison_operator" "")
2717                         (match_operand:I 2 "arith10_operand" "")
2718                         (match_operand:I 3 "arith10_operand" "")))]
2719   "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2721   if (! sparc_expand_conditional_move (<I:MODE>mode, operands))
2722     FAIL;
2723   DONE;
2726 (define_expand "mov<F:mode>cc"
2727   [(set (match_operand:F 0 "register_operand" "")
2728         (if_then_else:F (match_operand 1 "comparison_operator" "")
2729                         (match_operand:F 2 "register_operand" "")
2730                         (match_operand:F 3 "register_operand" "")))]
2731   "TARGET_V9 && TARGET_FPU"
2733   if (! sparc_expand_conditional_move (<F:MODE>mode, operands))
2734     FAIL;
2735   DONE;
2738 ;; Conditional move define_insns
2740 (define_insn "*mov<I:mode>_cc_v9"
2741   [(set (match_operand:I 0 "register_operand" "=r")
2742         (if_then_else:I (match_operator 1 "comparison_operator"
2743                                [(match_operand 2 "icc_or_fcc_register_operand" "X")
2744                                 (const_int 0)])
2745                         (match_operand:I 3 "arith11_operand" "rL")
2746                         (match_operand:I 4 "register_operand" "0")))]
2747   "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2748   "mov%C1\t%x2, %3, %0"
2749   [(set_attr "type" "cmove")])
2751 (define_insn "*mov<I:mode>_cc_reg_sp64"
2752   [(set (match_operand:I 0 "register_operand" "=r")
2753         (if_then_else:I (match_operator 1 "v9_register_compare_operator"
2754                                 [(match_operand:DI 2 "register_operand" "r")
2755                                  (const_int 0)])
2756                         (match_operand:I 3 "arith10_operand" "rM")
2757                         (match_operand:I 4 "register_operand" "0")))]
2758   "TARGET_ARCH64"
2759   "movr%D1\t%2, %r3, %0"
2760   [(set_attr "type" "cmove")])
2762 (define_insn "*movsf_cc_v9"
2763   [(set (match_operand:SF 0 "register_operand" "=f")
2764         (if_then_else:SF (match_operator 1 "comparison_operator"
2765                                 [(match_operand 2 "icc_or_fcc_register_operand" "X")
2766                                  (const_int 0)])
2767                          (match_operand:SF 3 "register_operand" "f")
2768                          (match_operand:SF 4 "register_operand" "0")))]
2769   "TARGET_V9 && TARGET_FPU"
2770   "fmovs%C1\t%x2, %3, %0"
2771   [(set_attr "type" "fpcmove")])
2773 (define_insn "*movsf_cc_reg_sp64"
2774   [(set (match_operand:SF 0 "register_operand" "=f")
2775         (if_then_else:SF (match_operator 1 "v9_register_compare_operator"
2776                                 [(match_operand:DI 2 "register_operand" "r")
2777                                  (const_int 0)])
2778                          (match_operand:SF 3 "register_operand" "f")
2779                          (match_operand:SF 4 "register_operand" "0")))]
2780   "TARGET_ARCH64 && TARGET_FPU"
2781   "fmovrs%D1\t%2, %3, %0"
2782   [(set_attr "type" "fpcrmove")])
2784 ;; Named because invoked by movtf_cc_v9
2785 (define_insn "movdf_cc_v9"
2786   [(set (match_operand:DF 0 "register_operand" "=e")
2787         (if_then_else:DF (match_operator 1 "comparison_operator"
2788                                 [(match_operand 2 "icc_or_fcc_register_operand" "X")
2789                                  (const_int 0)])
2790                          (match_operand:DF 3 "register_operand" "e")
2791                          (match_operand:DF 4 "register_operand" "0")))]
2792   "TARGET_V9 && TARGET_FPU"
2793   "fmovd%C1\t%x2, %3, %0"
2794   [(set_attr "type" "fpcmove")
2795    (set_attr "fptype" "double")])
2797 ;; Named because invoked by movtf_cc_reg_sp64
2798 (define_insn "movdf_cc_reg_sp64"
2799   [(set (match_operand:DF 0 "register_operand" "=e")
2800         (if_then_else:DF (match_operator 1 "v9_register_compare_operator"
2801                                 [(match_operand:DI 2 "register_operand" "r")
2802                                  (const_int 0)])
2803                          (match_operand:DF 3 "register_operand" "e")
2804                          (match_operand:DF 4 "register_operand" "0")))]
2805   "TARGET_ARCH64 && TARGET_FPU"
2806   "fmovrd%D1\t%2, %3, %0"
2807   [(set_attr "type" "fpcrmove")
2808    (set_attr "fptype" "double")])
2810 (define_insn "*movtf_cc_hq_v9"
2811   [(set (match_operand:TF 0 "register_operand" "=e")
2812         (if_then_else:TF (match_operator 1 "comparison_operator"
2813                                 [(match_operand 2 "icc_or_fcc_register_operand" "X")
2814                                  (const_int 0)])
2815                          (match_operand:TF 3 "register_operand" "e")
2816                          (match_operand:TF 4 "register_operand" "0")))]
2817   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
2818   "fmovq%C1\t%x2, %3, %0"
2819   [(set_attr "type" "fpcmove")])
2821 (define_insn "*movtf_cc_reg_hq_sp64"
2822   [(set (match_operand:TF 0 "register_operand" "=e")
2823         (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2824                                 [(match_operand:DI 2 "register_operand" "r")
2825                                  (const_int 0)])
2826                          (match_operand:TF 3 "register_operand" "e")
2827                          (match_operand:TF 4 "register_operand" "0")))]
2828   "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
2829   "fmovrq%D1\t%2, %3, %0"
2830   [(set_attr "type" "fpcrmove")])
2832 (define_insn_and_split "*movtf_cc_v9"
2833   [(set (match_operand:TF 0 "register_operand" "=e")
2834         (if_then_else:TF (match_operator 1 "comparison_operator"
2835                             [(match_operand 2 "icc_or_fcc_register_operand" "X")
2836                              (const_int 0)])
2837                          (match_operand:TF 3 "register_operand" "e")
2838                          (match_operand:TF 4 "register_operand" "0")))]
2839   "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
2840   "#"
2841   "&& reload_completed"
2842   [(clobber (const_int 0))]
2844   rtx set_dest = operands[0];
2845   rtx set_srca = operands[3];
2846   rtx dest1, dest2;
2847   rtx srca1, srca2;
2849   dest1 = gen_df_reg (set_dest, 0);
2850   dest2 = gen_df_reg (set_dest, 1);
2851   srca1 = gen_df_reg (set_srca, 0);
2852   srca2 = gen_df_reg (set_srca, 1);
2854   if (reg_overlap_mentioned_p (dest1, srca2))
2855     {
2856       emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, dest2));
2857       emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, dest1));
2858     }
2859   else
2860     {
2861       emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, dest1));
2862       emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, dest2));
2863     }
2864   DONE;
2866   [(set_attr "length" "2")])
2868 (define_insn_and_split "*movtf_cc_reg_sp64"
2869   [(set (match_operand:TF 0 "register_operand" "=e")
2870         (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2871                                 [(match_operand:DI 2 "register_operand" "r")
2872                                  (const_int 0)])
2873                          (match_operand:TF 3 "register_operand" "e")
2874                          (match_operand:TF 4 "register_operand" "0")))]
2875   "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
2876   "#"
2877   "&& reload_completed"
2878   [(clobber (const_int 0))]
2880   rtx set_dest = operands[0];
2881   rtx set_srca = operands[3];
2882   rtx dest1, dest2;
2883   rtx srca1, srca2;
2885   dest1 = gen_df_reg (set_dest, 0);
2886   dest2 = gen_df_reg (set_dest, 1);
2887   srca1 = gen_df_reg (set_srca, 0);
2888   srca2 = gen_df_reg (set_srca, 1);
2890   if (reg_overlap_mentioned_p (dest1, srca2))
2891     {
2892       emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, dest2));
2893       emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, dest1));
2894     }
2895   else
2896     {
2897       emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, dest1));
2898       emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, dest2));
2899     }
2900   DONE;
2902   [(set_attr "length" "2")])
2905 ;; Zero-extension instructions
2907 ;; These patterns originally accepted general_operands, however, slightly
2908 ;; better code is generated by only accepting register_operands, and then
2909 ;; letting combine generate the ldu[hb] insns.
2911 (define_expand "zero_extendhisi2"
2912   [(set (match_operand:SI 0 "register_operand" "")
2913         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
2914   ""
2916   rtx temp = gen_reg_rtx (SImode);
2917   rtx shift_16 = GEN_INT (16);
2918   int op1_subbyte = 0;
2920   if (GET_CODE (operand1) == SUBREG)
2921     {
2922       op1_subbyte = SUBREG_BYTE (operand1);
2923       op1_subbyte /= GET_MODE_SIZE (SImode);
2924       op1_subbyte *= GET_MODE_SIZE (SImode);
2925       operand1 = XEXP (operand1, 0);
2926     }
2928   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
2929                           shift_16));
2930   emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
2931   DONE;
2934 (define_insn "*zero_extendhisi2_insn"
2935   [(set (match_operand:SI 0 "register_operand" "=r")
2936         (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2937   ""
2938   "lduh\t%1, %0"
2939   [(set_attr "type" "load")
2940    (set_attr "us3load_type" "3cycle")])
2942 (define_expand "zero_extendqihi2"
2943   [(set (match_operand:HI 0 "register_operand" "")
2944         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
2945   ""
2946   "")
2948 (define_insn "*zero_extendqihi2_insn"
2949   [(set (match_operand:HI 0 "register_operand" "=r,r")
2950         (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
2951   "GET_CODE (operands[1]) != CONST_INT"
2952   "@
2953    and\t%1, 0xff, %0
2954    ldub\t%1, %0"
2955   [(set_attr "type" "*,load")
2956    (set_attr "us3load_type" "*,3cycle")])
2958 (define_expand "zero_extendqisi2"
2959   [(set (match_operand:SI 0 "register_operand" "")
2960         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
2961   ""
2962   "")
2964 (define_insn "*zero_extendqisi2_insn"
2965   [(set (match_operand:SI 0 "register_operand" "=r,r")
2966         (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
2967   "GET_CODE (operands[1]) != CONST_INT"
2968   "@
2969    and\t%1, 0xff, %0
2970    ldub\t%1, %0"
2971   [(set_attr "type" "*,load")
2972    (set_attr "us3load_type" "*,3cycle")])
2974 (define_expand "zero_extendqidi2"
2975   [(set (match_operand:DI 0 "register_operand" "")
2976         (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
2977   "TARGET_ARCH64"
2978   "")
2980 (define_insn "*zero_extendqidi2_insn"
2981   [(set (match_operand:DI 0 "register_operand" "=r,r")
2982         (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
2983   "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
2984   "@
2985    and\t%1, 0xff, %0
2986    ldub\t%1, %0"
2987   [(set_attr "type" "*,load")
2988    (set_attr "us3load_type" "*,3cycle")])
2990 (define_expand "zero_extendhidi2"
2991   [(set (match_operand:DI 0 "register_operand" "")
2992         (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
2993   "TARGET_ARCH64"
2995   rtx temp = gen_reg_rtx (DImode);
2996   rtx shift_48 = GEN_INT (48);
2997   int op1_subbyte = 0;
2999   if (GET_CODE (operand1) == SUBREG)
3000     {
3001       op1_subbyte = SUBREG_BYTE (operand1);
3002       op1_subbyte /= GET_MODE_SIZE (DImode);
3003       op1_subbyte *= GET_MODE_SIZE (DImode);
3004       operand1 = XEXP (operand1, 0);
3005     }
3007   emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3008                           shift_48));
3009   emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
3010   DONE;
3013 (define_insn "*zero_extendhidi2_insn"
3014   [(set (match_operand:DI 0 "register_operand" "=r")
3015         (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3016   "TARGET_ARCH64"
3017   "lduh\t%1, %0"
3018   [(set_attr "type" "load")
3019    (set_attr "us3load_type" "3cycle")])
3021 ;; ??? Write truncdisi pattern using sra?
3023 (define_expand "zero_extendsidi2"
3024   [(set (match_operand:DI 0 "register_operand" "")
3025         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
3026   ""
3027   "")
3029 (define_insn "*zero_extendsidi2_insn_sp64"
3030   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
3031         (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m,*f")))]
3032   "TARGET_ARCH64
3033    && GET_CODE (operands[1]) != CONST_INT"
3034   "@
3035    srl\t%1, 0, %0
3036    lduw\t%1, %0
3037    movstouw\t%1, %0"
3038   [(set_attr "type" "shift,load,*")
3039    (set_attr "cpu_feature" "*,*,vis3")])
3041 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
3042   [(set (match_operand:DI 0 "register_operand" "=r")
3043         (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
3044   "! TARGET_ARCH64"
3045   "#"
3046   "&& reload_completed"
3047   [(set (match_dup 2) (match_dup 3))
3048    (set (match_dup 4) (match_dup 5))]
3050   rtx dest1, dest2;
3052   dest1 = gen_highpart (SImode, operands[0]);
3053   dest2 = gen_lowpart (SImode, operands[0]);
3055   /* Swap the order in case of overlap.  */
3056   if (REGNO (dest1) == REGNO (operands[1]))
3057     {
3058       operands[2] = dest2;
3059       operands[3] = operands[1];
3060       operands[4] = dest1;
3061       operands[5] = const0_rtx;
3062     }
3063   else
3064     {
3065       operands[2] = dest1;
3066       operands[3] = const0_rtx;
3067       operands[4] = dest2;
3068       operands[5] = operands[1];
3069     }
3071   [(set_attr "length" "2")])
3073 ;; Simplify comparisons of extended values.
3075 (define_insn "*cmp_zero_extendqisi2"
3076   [(set (reg:CC CC_REG)
3077         (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
3078                     (const_int 0)))]
3079   ""
3080   "andcc\t%0, 0xff, %%g0"
3081   [(set_attr "type" "compare")])
3083 (define_insn "*cmp_zero_qi"
3084   [(set (reg:CC CC_REG)
3085         (compare:CC (match_operand:QI 0 "register_operand" "r")
3086                     (const_int 0)))]
3087   ""
3088   "andcc\t%0, 0xff, %%g0"
3089   [(set_attr "type" "compare")])
3091 (define_insn "*cmp_zero_extendqisi2_set"
3092   [(set (reg:CC CC_REG)
3093         (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
3094                     (const_int 0)))
3095    (set (match_operand:SI 0 "register_operand" "=r")
3096         (zero_extend:SI (match_dup 1)))]
3097   ""
3098   "andcc\t%1, 0xff, %0"
3099   [(set_attr "type" "compare")])
3101 (define_insn "*cmp_zero_extendqisi2_andcc_set"
3102   [(set (reg:CC CC_REG)
3103         (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
3104                             (const_int 255))
3105                     (const_int 0)))
3106    (set (match_operand:SI 0 "register_operand" "=r")
3107         (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
3108   ""
3109   "andcc\t%1, 0xff, %0"
3110   [(set_attr "type" "compare")])
3112 (define_insn "*cmp_zero_extendqidi2"
3113   [(set (reg:CCX CC_REG)
3114         (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
3115                      (const_int 0)))]
3116   "TARGET_ARCH64"
3117   "andcc\t%0, 0xff, %%g0"
3118   [(set_attr "type" "compare")])
3120 (define_insn "*cmp_zero_qi_sp64"
3121   [(set (reg:CCX CC_REG)
3122         (compare:CCX (match_operand:QI 0 "register_operand" "r")
3123                      (const_int 0)))]
3124   "TARGET_ARCH64"
3125   "andcc\t%0, 0xff, %%g0"
3126   [(set_attr "type" "compare")])
3128 (define_insn "*cmp_zero_extendqidi2_set"
3129   [(set (reg:CCX CC_REG)
3130         (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
3131                      (const_int 0)))
3132    (set (match_operand:DI 0 "register_operand" "=r")
3133         (zero_extend:DI (match_dup 1)))]
3134   "TARGET_ARCH64"
3135   "andcc\t%1, 0xff, %0"
3136   [(set_attr "type" "compare")])
3138 (define_insn "*cmp_zero_extendqidi2_andcc_set"
3139   [(set (reg:CCX CC_REG)
3140         (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
3141                              (const_int 255))
3142                      (const_int 0)))
3143    (set (match_operand:DI 0 "register_operand" "=r")
3144         (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
3145   "TARGET_ARCH64"
3146   "andcc\t%1, 0xff, %0"
3147   [(set_attr "type" "compare")])
3149 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
3151 (define_insn "*cmp_siqi_trunc"
3152   [(set (reg:CC CC_REG)
3153         (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
3154                     (const_int 0)))]
3155   ""
3156   "andcc\t%0, 0xff, %%g0"
3157   [(set_attr "type" "compare")])
3159 (define_insn "*cmp_siqi_trunc_set"
3160   [(set (reg:CC CC_REG)
3161         (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
3162                     (const_int 0)))
3163    (set (match_operand:QI 0 "register_operand" "=r")
3164         (subreg:QI (match_dup 1) 3))]
3165   ""
3166   "andcc\t%1, 0xff, %0"
3167   [(set_attr "type" "compare")])
3169 (define_insn "*cmp_diqi_trunc"
3170   [(set (reg:CC CC_REG)
3171         (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
3172                     (const_int 0)))]
3173   "TARGET_ARCH64"
3174   "andcc\t%0, 0xff, %%g0"
3175   [(set_attr "type" "compare")])
3177 (define_insn "*cmp_diqi_trunc_set"
3178   [(set (reg:CC CC_REG)
3179         (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
3180                     (const_int 0)))
3181    (set (match_operand:QI 0 "register_operand" "=r")
3182         (subreg:QI (match_dup 1) 7))]
3183   "TARGET_ARCH64"
3184   "andcc\t%1, 0xff, %0"
3185   [(set_attr "type" "compare")])
3188 ;; Sign-extension instructions
3190 ;; These patterns originally accepted general_operands, however, slightly
3191 ;; better code is generated by only accepting register_operands, and then
3192 ;; letting combine generate the lds[hb] insns.
3194 (define_expand "extendhisi2"
3195   [(set (match_operand:SI 0 "register_operand" "")
3196         (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
3197   ""
3199   rtx temp = gen_reg_rtx (SImode);
3200   rtx shift_16 = GEN_INT (16);
3201   int op1_subbyte = 0;
3203   if (GET_CODE (operand1) == SUBREG)
3204     {
3205       op1_subbyte = SUBREG_BYTE (operand1);
3206       op1_subbyte /= GET_MODE_SIZE (SImode);
3207       op1_subbyte *= GET_MODE_SIZE (SImode);
3208       operand1 = XEXP (operand1, 0);
3209     }
3211   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3212                           shift_16));
3213   emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
3214   DONE;
3217 (define_insn "*sign_extendhisi2_insn"
3218   [(set (match_operand:SI 0 "register_operand" "=r")
3219         (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3220   ""
3221   "ldsh\t%1, %0"
3222   [(set_attr "type" "sload")
3223    (set_attr "us3load_type" "3cycle")])
3225 (define_expand "extendqihi2"
3226   [(set (match_operand:HI 0 "register_operand" "")
3227         (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
3228   ""
3230   rtx temp = gen_reg_rtx (SImode);
3231   rtx shift_24 = GEN_INT (24);
3232   int op1_subbyte = 0;
3233   int op0_subbyte = 0;
3235   if (GET_CODE (operand1) == SUBREG)
3236     {
3237       op1_subbyte = SUBREG_BYTE (operand1);
3238       op1_subbyte /= GET_MODE_SIZE (SImode);
3239       op1_subbyte *= GET_MODE_SIZE (SImode);
3240       operand1 = XEXP (operand1, 0);
3241     }
3242   if (GET_CODE (operand0) == SUBREG)
3243     {
3244       op0_subbyte = SUBREG_BYTE (operand0);
3245       op0_subbyte /= GET_MODE_SIZE (SImode);
3246       op0_subbyte *= GET_MODE_SIZE (SImode);
3247       operand0 = XEXP (operand0, 0);
3248     }
3249   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3250                           shift_24));
3251   if (GET_MODE (operand0) != SImode)
3252     operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
3253   emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3254   DONE;
3257 (define_insn "*sign_extendqihi2_insn"
3258   [(set (match_operand:HI 0 "register_operand" "=r")
3259         (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3260   ""
3261   "ldsb\t%1, %0"
3262   [(set_attr "type" "sload")
3263    (set_attr "us3load_type" "3cycle")])
3265 (define_expand "extendqisi2"
3266   [(set (match_operand:SI 0 "register_operand" "")
3267         (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
3268   ""
3270   rtx temp = gen_reg_rtx (SImode);
3271   rtx shift_24 = GEN_INT (24);
3272   int op1_subbyte = 0;
3274   if (GET_CODE (operand1) == SUBREG)
3275     {
3276       op1_subbyte = SUBREG_BYTE (operand1);
3277       op1_subbyte /= GET_MODE_SIZE (SImode);
3278       op1_subbyte *= GET_MODE_SIZE (SImode);
3279       operand1 = XEXP (operand1, 0);
3280     }
3282   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3283                           shift_24));
3284   emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3285   DONE;
3288 (define_insn "*sign_extendqisi2_insn"
3289   [(set (match_operand:SI 0 "register_operand" "=r")
3290         (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3291   ""
3292   "ldsb\t%1, %0"
3293   [(set_attr "type" "sload")
3294    (set_attr "us3load_type" "3cycle")])
3296 (define_expand "extendqidi2"
3297   [(set (match_operand:DI 0 "register_operand" "")
3298         (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
3299   "TARGET_ARCH64"
3301   rtx temp = gen_reg_rtx (DImode);
3302   rtx shift_56 = GEN_INT (56);
3303   int op1_subbyte = 0;
3305   if (GET_CODE (operand1) == SUBREG)
3306     {
3307       op1_subbyte = SUBREG_BYTE (operand1);
3308       op1_subbyte /= GET_MODE_SIZE (DImode);
3309       op1_subbyte *= GET_MODE_SIZE (DImode);
3310       operand1 = XEXP (operand1, 0);
3311     }
3313   emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3314                           shift_56));
3315   emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
3316   DONE;
3319 (define_insn "*sign_extendqidi2_insn"
3320   [(set (match_operand:DI 0 "register_operand" "=r")
3321         (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3322   "TARGET_ARCH64"
3323   "ldsb\t%1, %0"
3324   [(set_attr "type" "sload")
3325    (set_attr "us3load_type" "3cycle")])
3327 (define_expand "extendhidi2"
3328   [(set (match_operand:DI 0 "register_operand" "")
3329         (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
3330   "TARGET_ARCH64"
3332   rtx temp = gen_reg_rtx (DImode);
3333   rtx shift_48 = GEN_INT (48);
3334   int op1_subbyte = 0;
3336   if (GET_CODE (operand1) == SUBREG)
3337     {
3338       op1_subbyte = SUBREG_BYTE (operand1);
3339       op1_subbyte /= GET_MODE_SIZE (DImode);
3340       op1_subbyte *= GET_MODE_SIZE (DImode);
3341       operand1 = XEXP (operand1, 0);
3342     }
3344   emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3345                           shift_48));
3346   emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
3347   DONE;
3350 (define_insn "*sign_extendhidi2_insn"
3351   [(set (match_operand:DI 0 "register_operand" "=r")
3352         (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3353   "TARGET_ARCH64"
3354   "ldsh\t%1, %0"
3355   [(set_attr "type" "sload")
3356    (set_attr "us3load_type" "3cycle")])
3358 (define_expand "extendsidi2"
3359   [(set (match_operand:DI 0 "register_operand" "")
3360         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3361   "TARGET_ARCH64"
3362   "")
3364 (define_insn "*sign_extendsidi2_insn"
3365   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
3366         (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m,*f")))]
3367   "TARGET_ARCH64"
3368   "@
3369   sra\t%1, 0, %0
3370   ldsw\t%1, %0
3371   movstosw\t%1, %0"
3372   [(set_attr "type" "shift,sload,*")
3373    (set_attr "us3load_type" "*,3cycle,*")
3374    (set_attr "cpu_feature" "*,*,vis3")])
3377 ;; Special pattern for optimizing bit-field compares.  This is needed
3378 ;; because combine uses this as a canonical form.
3380 (define_insn "*cmp_zero_extract"
3381   [(set (reg:CC CC_REG)
3382         (compare:CC
3383          (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
3384                           (match_operand:SI 1 "small_int_operand" "I")
3385                           (match_operand:SI 2 "small_int_operand" "I"))
3386          (const_int 0)))]
3387   "INTVAL (operands[2]) > 19"
3389   int len = INTVAL (operands[1]);
3390   int pos = 32 - INTVAL (operands[2]) - len;
3391   HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
3392   operands[1] = GEN_INT (mask);
3393   return "andcc\t%0, %1, %%g0";
3395   [(set_attr "type" "compare")])
3397 (define_insn "*cmp_zero_extract_sp64"
3398   [(set (reg:CCX CC_REG)
3399         (compare:CCX
3400          (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
3401                           (match_operand:SI 1 "small_int_operand" "I")
3402                           (match_operand:SI 2 "small_int_operand" "I"))
3403          (const_int 0)))]
3404   "TARGET_ARCH64 && INTVAL (operands[2]) > 51"
3406   int len = INTVAL (operands[1]);
3407   int pos = 64 - INTVAL (operands[2]) - len;
3408   HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
3409   operands[1] = GEN_INT (mask);
3410   return "andcc\t%0, %1, %%g0";
3412   [(set_attr "type" "compare")])
3415 ;; Conversions between float, double and long double.
3417 (define_insn "extendsfdf2"
3418   [(set (match_operand:DF 0 "register_operand" "=e")
3419         (float_extend:DF
3420          (match_operand:SF 1 "register_operand" "f")))]
3421   "TARGET_FPU"
3422   "fstod\t%1, %0"
3423   [(set_attr "type" "fp")
3424    (set_attr "fptype" "double")])
3426 (define_expand "extendsftf2"
3427   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3428         (float_extend:TF
3429          (match_operand:SF 1 "register_operand" "")))]
3430   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3431   "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3433 (define_insn "*extendsftf2_hq"
3434   [(set (match_operand:TF 0 "register_operand" "=e")
3435         (float_extend:TF
3436          (match_operand:SF 1 "register_operand" "f")))]
3437   "TARGET_FPU && TARGET_HARD_QUAD"
3438   "fstoq\t%1, %0"
3439   [(set_attr "type" "fp")])
3441 (define_expand "extenddftf2"
3442   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3443         (float_extend:TF
3444          (match_operand:DF 1 "register_operand" "")))]
3445   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3446   "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3448 (define_insn "*extenddftf2_hq"
3449   [(set (match_operand:TF 0 "register_operand" "=e")
3450         (float_extend:TF
3451          (match_operand:DF 1 "register_operand" "e")))]
3452   "TARGET_FPU && TARGET_HARD_QUAD"
3453   "fdtoq\t%1, %0"
3454   [(set_attr "type" "fp")])
3456 (define_insn "truncdfsf2"
3457   [(set (match_operand:SF 0 "register_operand" "=f")
3458         (float_truncate:SF
3459          (match_operand:DF 1 "register_operand" "e")))]
3460   "TARGET_FPU"
3461   "fdtos\t%1, %0"
3462   [(set_attr "type" "fp")
3463    (set_attr "fptype" "double")
3464    (set_attr "fptype_ut699" "single")])
3466 (define_expand "trunctfsf2"
3467   [(set (match_operand:SF 0 "register_operand" "")
3468         (float_truncate:SF
3469          (match_operand:TF 1 "general_operand" "")))]
3470   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3471   "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3473 (define_insn "*trunctfsf2_hq"
3474   [(set (match_operand:SF 0 "register_operand" "=f")
3475         (float_truncate:SF
3476          (match_operand:TF 1 "register_operand" "e")))]
3477   "TARGET_FPU && TARGET_HARD_QUAD"
3478   "fqtos\t%1, %0"
3479   [(set_attr "type" "fp")])
3481 (define_expand "trunctfdf2"
3482   [(set (match_operand:DF 0 "register_operand" "")
3483         (float_truncate:DF
3484          (match_operand:TF 1 "general_operand" "")))]
3485   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3486   "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3488 (define_insn "*trunctfdf2_hq"
3489   [(set (match_operand:DF 0 "register_operand" "=e")
3490         (float_truncate:DF
3491          (match_operand:TF 1 "register_operand" "e")))]
3492   "TARGET_FPU && TARGET_HARD_QUAD"
3493   "fqtod\t%1, %0"
3494   [(set_attr "type" "fp")])
3497 ;; Conversion between fixed point and floating point.
3499 (define_insn "floatsisf2"
3500   [(set (match_operand:SF 0 "register_operand" "=f")
3501         (float:SF (match_operand:SI 1 "register_operand" "f")))]
3502   "TARGET_FPU"
3503   "fitos\t%1, %0"
3504   [(set_attr "type" "fp")
3505    (set_attr "fptype" "single")])
3507 (define_insn "floatsidf2"
3508   [(set (match_operand:DF 0 "register_operand" "=e")
3509         (float:DF (match_operand:SI 1 "register_operand" "f")))]
3510   "TARGET_FPU"
3511   "fitod\t%1, %0"
3512   [(set_attr "type" "fp")
3513    (set_attr "fptype" "double")])
3515 (define_expand "floatsitf2"
3516   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3517         (float:TF (match_operand:SI 1 "register_operand" "")))]
3518   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3519   "emit_tfmode_cvt (FLOAT, operands); DONE;")
3521 (define_insn "*floatsitf2_hq"
3522   [(set (match_operand:TF 0 "register_operand" "=e")
3523         (float:TF (match_operand:SI 1 "register_operand" "f")))]
3524   "TARGET_FPU && TARGET_HARD_QUAD"
3525   "fitoq\t%1, %0"
3526   [(set_attr "type" "fp")])
3528 (define_expand "floatunssitf2"
3529   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3530         (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
3531   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3532   "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3534 ;; Now the same for 64 bit sources.
3536 (define_insn "floatdisf2"
3537   [(set (match_operand:SF 0 "register_operand" "=f")
3538         (float:SF (match_operand:DI 1 "register_operand" "e")))]
3539   "TARGET_V9 && TARGET_FPU"
3540   "fxtos\t%1, %0"
3541   [(set_attr "type" "fp")
3542    (set_attr "fptype" "double")])
3544 (define_expand "floatunsdisf2"
3545   [(use (match_operand:SF 0 "register_operand" ""))
3546    (use (match_operand:DI 1 "general_operand" ""))]
3547   "TARGET_ARCH64 && TARGET_FPU"
3548   "sparc_emit_floatunsdi (operands, SFmode); DONE;")
3550 (define_insn "floatdidf2"
3551   [(set (match_operand:DF 0 "register_operand" "=e")
3552         (float:DF (match_operand:DI 1 "register_operand" "e")))]
3553   "TARGET_V9 && TARGET_FPU"
3554   "fxtod\t%1, %0"
3555   [(set_attr "type" "fp")
3556    (set_attr "fptype" "double")])
3558 (define_expand "floatunsdidf2"
3559   [(use (match_operand:DF 0 "register_operand" ""))
3560    (use (match_operand:DI 1 "general_operand" ""))]
3561   "TARGET_ARCH64 && TARGET_FPU"
3562   "sparc_emit_floatunsdi (operands, DFmode); DONE;")
3564 (define_expand "floatditf2"
3565   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3566         (float:TF (match_operand:DI 1 "register_operand" "")))]
3567   "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3568   "emit_tfmode_cvt (FLOAT, operands); DONE;")
3570 (define_insn "*floatditf2_hq"
3571   [(set (match_operand:TF 0 "register_operand" "=e")
3572         (float:TF (match_operand:DI 1 "register_operand" "e")))]
3573   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3574   "fxtoq\t%1, %0"
3575   [(set_attr "type" "fp")])
3577 (define_expand "floatunsditf2"
3578   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3579         (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
3580   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3581   "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3583 ;; Convert a float to an actual integer.
3584 ;; Truncation is performed as part of the conversion.
3586 (define_insn "fix_truncsfsi2"
3587   [(set (match_operand:SI 0 "register_operand" "=f")
3588         (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3589   "TARGET_FPU"
3590   "fstoi\t%1, %0"
3591   [(set_attr "type" "fp")
3592    (set_attr "fptype" "single")])
3594 (define_insn "fix_truncdfsi2"
3595   [(set (match_operand:SI 0 "register_operand" "=f")
3596         (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3597   "TARGET_FPU"
3598   "fdtoi\t%1, %0"
3599   [(set_attr "type" "fp")
3600    (set_attr "fptype" "double")
3601    (set_attr "fptype_ut699" "single")])
3603 (define_expand "fix_trunctfsi2"
3604   [(set (match_operand:SI 0 "register_operand" "")
3605         (fix:SI (match_operand:TF 1 "general_operand" "")))]
3606   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3607   "emit_tfmode_cvt (FIX, operands); DONE;")
3609 (define_insn "*fix_trunctfsi2_hq"
3610   [(set (match_operand:SI 0 "register_operand" "=f")
3611         (fix:SI (match_operand:TF 1 "register_operand" "e")))]
3612   "TARGET_FPU && TARGET_HARD_QUAD"
3613   "fqtoi\t%1, %0"
3614   [(set_attr "type" "fp")])
3616 (define_expand "fixuns_trunctfsi2"
3617   [(set (match_operand:SI 0 "register_operand" "")
3618         (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
3619   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3620   "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3622 ;; Now the same, for V9 targets
3624 (define_insn "fix_truncsfdi2"
3625   [(set (match_operand:DI 0 "register_operand" "=e")
3626         (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3627   "TARGET_V9 && TARGET_FPU"
3628   "fstox\t%1, %0"
3629   [(set_attr "type" "fp")
3630    (set_attr "fptype" "double")])
3632 (define_expand "fixuns_truncsfdi2"
3633   [(use (match_operand:DI 0 "register_operand" ""))
3634    (use (match_operand:SF 1 "general_operand" ""))]
3635   "TARGET_ARCH64 && TARGET_FPU"
3636   "sparc_emit_fixunsdi (operands, SFmode); DONE;")
3638 (define_insn "fix_truncdfdi2"
3639   [(set (match_operand:DI 0 "register_operand" "=e")
3640         (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3641   "TARGET_V9 && TARGET_FPU"
3642   "fdtox\t%1, %0"
3643   [(set_attr "type" "fp")
3644    (set_attr "fptype" "double")])
3646 (define_expand "fixuns_truncdfdi2"
3647   [(use (match_operand:DI 0 "register_operand" ""))
3648    (use (match_operand:DF 1 "general_operand" ""))]
3649   "TARGET_ARCH64 && TARGET_FPU"
3650   "sparc_emit_fixunsdi (operands, DFmode); DONE;")
3652 (define_expand "fix_trunctfdi2"
3653   [(set (match_operand:DI 0 "register_operand" "")
3654         (fix:DI (match_operand:TF 1 "general_operand" "")))]
3655   "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3656   "emit_tfmode_cvt (FIX, operands); DONE;")
3658 (define_insn "*fix_trunctfdi2_hq"
3659   [(set (match_operand:DI 0 "register_operand" "=e")
3660         (fix:DI (match_operand:TF 1 "register_operand" "e")))]
3661   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3662   "fqtox\t%1, %0"
3663   [(set_attr "type" "fp")])
3665 (define_expand "fixuns_trunctfdi2"
3666   [(set (match_operand:DI 0 "register_operand" "")
3667         (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
3668   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3669   "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3672 ;; Integer addition/subtraction instructions.
3674 (define_expand "adddi3"
3675   [(set (match_operand:DI 0 "register_operand" "")
3676         (plus:DI (match_operand:DI 1 "register_operand" "")
3677                  (match_operand:DI 2 "arith_double_add_operand" "")))]
3678   ""
3680   if (! TARGET_ARCH64)
3681     {
3682       emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3683                           gen_rtx_SET (VOIDmode, operands[0],
3684                                    gen_rtx_PLUS (DImode, operands[1],
3685                                                  operands[2])),
3686                           gen_rtx_CLOBBER (VOIDmode,
3687                                    gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3688       DONE;
3689     }
3692 (define_insn_and_split "*adddi3_insn_sp32"
3693   [(set (match_operand:DI 0 "register_operand" "=&r")
3694         (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
3695                  (match_operand:DI 2 "arith_double_operand" "rHI")))
3696    (clobber (reg:CC CC_REG))]
3697   "! TARGET_ARCH64"
3698   "#"
3699   "&& reload_completed"
3700   [(parallel [(set (reg:CC_NOOV CC_REG)
3701                    (compare:CC_NOOV (plus:SI (match_dup 4)
3702                                              (match_dup 5))
3703                                     (const_int 0)))
3704               (set (match_dup 3)
3705                    (plus:SI (match_dup 4) (match_dup 5)))])
3706    (set (match_dup 6)
3707         (plus:SI (plus:SI (match_dup 7)
3708                           (match_dup 8))
3709                  (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3711   operands[3] = gen_lowpart (SImode, operands[0]);
3712   operands[4] = gen_lowpart (SImode, operands[1]);
3713   operands[5] = gen_lowpart (SImode, operands[2]);
3714   operands[6] = gen_highpart (SImode, operands[0]);
3715   operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
3716 #if HOST_BITS_PER_WIDE_INT == 32
3717   if (GET_CODE (operands[2]) == CONST_INT)
3718     {
3719       if (INTVAL (operands[2]) < 0)
3720         operands[8] = constm1_rtx;
3721       else
3722         operands[8] = const0_rtx;
3723     }
3724   else
3725 #endif
3726     operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3728   [(set_attr "length" "2")])
3730 ;; LTU here means "carry set"
3731 (define_insn "addx"
3732   [(set (match_operand:SI 0 "register_operand" "=r")
3733         (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3734                           (match_operand:SI 2 "arith_operand" "rI"))
3735                  (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3736   ""
3737   "addx\t%1, %2, %0"
3738   [(set_attr "type" "ialuX")])
3740 (define_insn "addxc"
3741   [(set (match_operand:DI 0 "register_operand" "=r")
3742         (plus:DI (plus:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
3743                           (match_operand:DI 2 "register_or_zero_operand" "rJ"))
3744                  (ltu:DI (reg:CCX_NOOV CC_REG) (const_int 0))))]
3745   "TARGET_ARCH64 && TARGET_VIS3"
3746   "addxc\t%r1, %r2, %0"
3747   [(set_attr "type" "ialuX")])
3749 (define_insn_and_split "*addx_extend_sp32"
3750   [(set (match_operand:DI 0 "register_operand" "=r")
3751         (zero_extend:DI (plus:SI (plus:SI
3752                                   (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3753                                   (match_operand:SI 2 "arith_operand" "rI"))
3754                                  (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3755   "! TARGET_ARCH64"
3756   "#"
3757   "&& reload_completed"
3758   [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
3759                                (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))
3760    (set (match_dup 4) (const_int 0))]
3761   "operands[3] = gen_lowpart (SImode, operands[0]);
3762    operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
3763   [(set_attr "length" "2")])
3765 (define_insn "*addx_extend_sp64"
3766   [(set (match_operand:DI 0 "register_operand" "=r")
3767         (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3768                                           (match_operand:SI 2 "register_or_zero_operand" "rJ"))
3769                                  (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3770   "TARGET_ARCH64"
3771   "addx\t%r1, %r2, %0"
3772   [(set_attr "type" "ialuX")])
3774 (define_insn "*addxc_trunc_sp64_vis3"
3775   [(set (match_operand:SI 0 "register_operand" "=r")
3776         (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3777                           (match_operand:SI 2 "register_or_zero_operand" "rJ"))
3778                  (ltu:SI (reg:CCX_NOOV CC_REG) (const_int 0))))]
3779   "TARGET_ARCH64 && TARGET_VIS3"
3780   "addxc\t%r1, %r2, %0"
3781   [(set_attr "type" "ialuX")])
3783 (define_insn_and_split "*adddi3_extend_sp32"
3784   [(set (match_operand:DI 0 "register_operand" "=r")
3785         (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
3786                  (match_operand:DI 2 "register_operand" "r")))
3787    (clobber (reg:CC CC_REG))]
3788   "! TARGET_ARCH64"
3789   "#"
3790   "&& reload_completed"
3791   [(parallel [(set (reg:CC_NOOV CC_REG)
3792                    (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
3793                                     (const_int 0)))
3794               (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
3795    (set (match_dup 6)
3796         (plus:SI (plus:SI (match_dup 4) (const_int 0))
3797                  (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3798   "operands[3] = gen_lowpart (SImode, operands[2]);
3799    operands[4] = gen_highpart (SImode, operands[2]);
3800    operands[5] = gen_lowpart (SImode, operands[0]);
3801    operands[6] = gen_highpart (SImode, operands[0]);"
3802   [(set_attr "length" "2")])
3804 (define_insn "*adddi3_sp64"
3805   [(set (match_operand:DI 0 "register_operand" "=r,r")
3806         (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
3807                  (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3808   "TARGET_ARCH64"
3809   "@
3810    add\t%1, %2, %0
3811    sub\t%1, -%2, %0")
3813 (define_insn "addsi3"
3814   [(set (match_operand:SI 0 "register_operand" "=r,r")
3815         (plus:SI (match_operand:SI 1 "register_operand" "%r,r")
3816                  (match_operand:SI 2 "arith_add_operand" "rI,O")))]
3817   ""
3818   "@
3819    add\t%1, %2, %0
3820    sub\t%1, -%2, %0"
3821   [(set_attr "type" "*,*")
3822    (set_attr "fptype" "*,*")])
3824 (define_insn "*cmp_cc_plus"
3825   [(set (reg:CC_NOOV CC_REG)
3826         (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
3827                                   (match_operand:SI 1 "arith_operand" "rI"))
3828                          (const_int 0)))]
3829   ""
3830   "addcc\t%0, %1, %%g0"
3831   [(set_attr "type" "compare")])
3833 (define_insn "*cmp_ccx_plus"
3834   [(set (reg:CCX_NOOV CC_REG)
3835         (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_operand" "%r")
3836                                    (match_operand:DI 1 "arith_operand" "rI"))
3837                           (const_int 0)))]
3838   "TARGET_ARCH64"
3839   "addcc\t%0, %1, %%g0"
3840   [(set_attr "type" "compare")])
3842 (define_insn "*cmp_cc_plus_set"
3843   [(set (reg:CC_NOOV CC_REG)
3844         (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3845                                   (match_operand:SI 2 "arith_operand" "rI"))
3846                          (const_int 0)))
3847    (set (match_operand:SI 0 "register_operand" "=r")
3848         (plus:SI (match_dup 1) (match_dup 2)))]
3849   ""
3850   "addcc\t%1, %2, %0"
3851   [(set_attr "type" "compare")])
3853 (define_insn "*cmp_ccx_plus_set"
3854   [(set (reg:CCX_NOOV CC_REG)
3855         (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_operand" "%r")
3856                                    (match_operand:DI 2 "arith_operand" "rI"))
3857                           (const_int 0)))
3858    (set (match_operand:DI 0 "register_operand" "=r")
3859         (plus:DI (match_dup 1) (match_dup 2)))]
3860   "TARGET_ARCH64"
3861   "addcc\t%1, %2, %0"
3862   [(set_attr "type" "compare")])
3864 (define_expand "subdi3"
3865   [(set (match_operand:DI 0 "register_operand" "")
3866         (minus:DI (match_operand:DI 1 "register_operand" "")
3867                   (match_operand:DI 2 "arith_double_add_operand" "")))]
3868   ""
3870   if (! TARGET_ARCH64)
3871     {
3872       emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3873                           gen_rtx_SET (VOIDmode, operands[0],
3874                                    gen_rtx_MINUS (DImode, operands[1],
3875                                                   operands[2])),
3876                           gen_rtx_CLOBBER (VOIDmode,
3877                                    gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3878       DONE;
3879     }
3882 (define_insn_and_split "*subdi3_insn_sp32"
3883   [(set (match_operand:DI 0 "register_operand" "=r")
3884         (minus:DI (match_operand:DI 1 "register_operand" "r")
3885                   (match_operand:DI 2 "arith_double_operand" "rHI")))
3886    (clobber (reg:CC CC_REG))]
3887   "! TARGET_ARCH64"
3888   "#"
3889   "&& reload_completed"
3890   [(parallel [(set (reg:CC_NOOV CC_REG)
3891                    (compare:CC_NOOV (minus:SI (match_dup 4)
3892                                               (match_dup 5))
3893                                     (const_int 0)))
3894               (set (match_dup 3)
3895                    (minus:SI (match_dup 4) (match_dup 5)))])
3896    (set (match_dup 6)
3897         (minus:SI (minus:SI (match_dup 7)
3898                             (match_dup 8))
3899                   (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3901   operands[3] = gen_lowpart (SImode, operands[0]);
3902   operands[4] = gen_lowpart (SImode, operands[1]);
3903   operands[5] = gen_lowpart (SImode, operands[2]);
3904   operands[6] = gen_highpart (SImode, operands[0]);
3905   operands[7] = gen_highpart (SImode, operands[1]);
3906 #if HOST_BITS_PER_WIDE_INT == 32
3907   if (GET_CODE (operands[2]) == CONST_INT)
3908     {
3909       if (INTVAL (operands[2]) < 0)
3910         operands[8] = constm1_rtx;
3911       else
3912         operands[8] = const0_rtx;
3913     }
3914   else
3915 #endif
3916     operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3918   [(set_attr "length" "2")])
3920 ;; LTU here means "carry set"
3921 (define_insn "subx"
3922   [(set (match_operand:SI 0 "register_operand" "=r")
3923         (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3924                             (match_operand:SI 2 "arith_operand" "rI"))
3925                   (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3926   ""
3927   "subx\t%r1, %2, %0"
3928   [(set_attr "type" "ialuX")])
3930 (define_insn "*subx_extend_sp64"
3931   [(set (match_operand:DI 0 "register_operand" "=r")
3932         (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3933                                             (match_operand:SI 2 "arith_operand" "rI"))
3934                                   (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3935   "TARGET_ARCH64"
3936   "subx\t%r1, %2, %0"
3937   [(set_attr "type" "ialuX")])
3939 (define_insn_and_split "*subx_extend"
3940   [(set (match_operand:DI 0 "register_operand" "=r")
3941         (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3942                                             (match_operand:SI 2 "arith_operand" "rI"))
3943                                   (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3944   "! TARGET_ARCH64"
3945   "#"
3946   "&& reload_completed"
3947   [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
3948                                 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))
3949    (set (match_dup 4) (const_int 0))]
3950   "operands[3] = gen_lowpart (SImode, operands[0]);
3951    operands[4] = gen_highpart (SImode, operands[0]);"
3952   [(set_attr "length" "2")])
3954 (define_insn_and_split "*subdi3_extend_sp32"
3955   [(set (match_operand:DI 0 "register_operand" "=r")
3956       (minus:DI (match_operand:DI 1 "register_operand" "r")
3957                 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
3958    (clobber (reg:CC CC_REG))]
3959   "! TARGET_ARCH64"
3960   "#"
3961   "&& reload_completed"
3962   [(parallel [(set (reg:CC_NOOV CC_REG)
3963                    (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
3964                                     (const_int 0)))
3965               (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
3966    (set (match_dup 6)
3967         (minus:SI (minus:SI (match_dup 4) (const_int 0))
3968                   (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3969   "operands[3] = gen_lowpart (SImode, operands[1]);
3970    operands[4] = gen_highpart (SImode, operands[1]);
3971    operands[5] = gen_lowpart (SImode, operands[0]);
3972    operands[6] = gen_highpart (SImode, operands[0]);"
3973   [(set_attr "length" "2")])
3975 (define_insn "*subdi3_sp64"
3976   [(set (match_operand:DI 0 "register_operand" "=r,r")
3977         (minus:DI (match_operand:DI 1 "register_operand" "r,r")
3978                   (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3979   "TARGET_ARCH64"
3980   "@
3981    sub\t%1, %2, %0
3982    add\t%1, -%2, %0")
3984 (define_insn "subsi3"
3985   [(set (match_operand:SI 0 "register_operand" "=r,r")
3986         (minus:SI (match_operand:SI 1 "register_operand" "r,r")
3987                   (match_operand:SI 2 "arith_add_operand" "rI,O")))]
3988   ""
3989   "@
3990    sub\t%1, %2, %0
3991    add\t%1, -%2, %0"
3992   [(set_attr "type" "*,*")
3993    (set_attr "fptype" "*,*")])
3995 (define_insn "*cmp_minus_cc"
3996   [(set (reg:CC_NOOV CC_REG)
3997         (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
3998                                    (match_operand:SI 1 "arith_operand" "rI"))
3999                          (const_int 0)))]
4000   ""
4001   "subcc\t%r0, %1, %%g0"
4002   [(set_attr "type" "compare")])
4004 (define_insn "*cmp_minus_ccx"
4005   [(set (reg:CCX_NOOV CC_REG)
4006         (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
4007                                     (match_operand:DI 1 "arith_operand" "rI"))
4008                           (const_int 0)))]
4009   "TARGET_ARCH64"
4010   "subcc\t%0, %1, %%g0"
4011   [(set_attr "type" "compare")])
4013 (define_insn "cmp_minus_cc_set"
4014   [(set (reg:CC_NOOV CC_REG)
4015         (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4016                                    (match_operand:SI 2 "arith_operand" "rI"))
4017                          (const_int 0)))
4018    (set (match_operand:SI 0 "register_operand" "=r")
4019         (minus:SI (match_dup 1) (match_dup 2)))]
4020   ""
4021   "subcc\t%r1, %2, %0"
4022   [(set_attr "type" "compare")])
4024 (define_insn "*cmp_minus_ccx_set"
4025   [(set (reg:CCX_NOOV CC_REG)
4026         (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
4027                                     (match_operand:DI 2 "arith_operand" "rI"))
4028                           (const_int 0)))
4029    (set (match_operand:DI 0 "register_operand" "=r")
4030         (minus:DI (match_dup 1) (match_dup 2)))]
4031   "TARGET_ARCH64"
4032   "subcc\t%1, %2, %0"
4033   [(set_attr "type" "compare")])
4036 ;; Integer multiply/divide instructions.
4038 ;; The 32-bit multiply/divide instructions are deprecated on v9, but at
4039 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
4041 (define_insn "mulsi3"
4042   [(set (match_operand:SI 0 "register_operand" "=r")
4043         (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4044                  (match_operand:SI 2 "arith_operand" "rI")))]
4045   "TARGET_HARD_MUL"
4046   "smul\t%1, %2, %0"
4047   [(set_attr "type" "imul")])
4049 (define_expand "muldi3"
4050   [(set (match_operand:DI 0 "register_operand" "")
4051         (mult:DI (match_operand:DI 1 "arith_operand" "")
4052                  (match_operand:DI 2 "arith_operand" "")))]
4053   "TARGET_ARCH64 || TARGET_V8PLUS"
4055   if (TARGET_V8PLUS)
4056     {
4057       emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
4058       DONE;
4059     }
4062 (define_insn "*muldi3_sp64"
4063   [(set (match_operand:DI 0 "register_operand" "=r")
4064         (mult:DI (match_operand:DI 1 "arith_operand" "%r")
4065                  (match_operand:DI 2 "arith_operand" "rI")))]
4066   "TARGET_ARCH64"
4067   "mulx\t%1, %2, %0"
4068   [(set_attr "type" "imul")])
4070 ;; V8plus wide multiply.
4071 ;; XXX
4072 (define_insn "muldi3_v8plus"
4073   [(set (match_operand:DI 0 "register_operand" "=r,h")
4074         (mult:DI (match_operand:DI 1 "arith_operand" "%r,0")
4075                  (match_operand:DI 2 "arith_operand" "rI,rI")))
4076    (clobber (match_scratch:SI 3 "=&h,X"))
4077    (clobber (match_scratch:SI 4 "=&h,X"))]
4078   "TARGET_V8PLUS"
4079   "* return output_v8plus_mult (insn, operands, \"mulx\");"
4080   [(set_attr "type" "multi")
4081    (set_attr "length" "9,8")])
4083 (define_insn "*cmp_mul_set"
4084   [(set (reg:CC CC_REG)
4085         (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4086                     (match_operand:SI 2 "arith_operand" "rI"))
4087                     (const_int 0)))
4088    (set (match_operand:SI 0 "register_operand" "=r")
4089         (mult:SI (match_dup 1) (match_dup 2)))]
4090   "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
4091   "smulcc\t%1, %2, %0"
4092   [(set_attr "type" "imul")])
4094 (define_expand "mulsidi3"
4095   [(set (match_operand:DI 0 "register_operand" "")
4096         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4097                  (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
4098   "TARGET_HARD_MUL"
4100   if (CONSTANT_P (operands[2]))
4101     {
4102       if (TARGET_V8PLUS)
4103         emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
4104                                               operands[2]));
4105       else if (TARGET_ARCH32)
4106         emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
4107                                             operands[2]));
4108       else 
4109         emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
4110                                             operands[2]));
4111       DONE;
4112     }
4113   if (TARGET_V8PLUS)
4114     {
4115       emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
4116       DONE;
4117     }
4120 ;; V9 puts the 64-bit product in a 64-bit register.  Only out or global
4121 ;; registers can hold 64-bit values in the V8plus environment.
4122 ;; XXX
4123 (define_insn "mulsidi3_v8plus"
4124   [(set (match_operand:DI 0 "register_operand" "=h,r")
4125         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4126                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4127    (clobber (match_scratch:SI 3 "=X,&h"))]
4128   "TARGET_V8PLUS"
4129   "@
4130    smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4131    smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4132   [(set_attr "type" "multi")
4133    (set_attr "length" "2,3")])
4135 ;; XXX
4136 (define_insn "const_mulsidi3_v8plus"
4137   [(set (match_operand:DI 0 "register_operand" "=h,r")
4138         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4139                  (match_operand:DI 2 "small_int_operand" "I,I")))
4140    (clobber (match_scratch:SI 3 "=X,&h"))]
4141   "TARGET_V8PLUS"
4142   "@
4143    smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4144    smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4145   [(set_attr "type" "multi")
4146    (set_attr "length" "2,3")])
4148 ;; XXX
4149 (define_insn "*mulsidi3_sp32"
4150   [(set (match_operand:DI 0 "register_operand" "=r")
4151         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4152                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4153   "TARGET_HARD_MUL32"
4155   return TARGET_SPARCLET
4156          ? "smuld\t%1, %2, %L0"
4157          : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4159   [(set (attr "type")
4160         (if_then_else (eq_attr "isa" "sparclet")
4161                       (const_string "imul") (const_string "multi")))
4162    (set (attr "length")
4163         (if_then_else (eq_attr "isa" "sparclet")
4164                       (const_int 1) (const_int 2)))])
4166 (define_insn "*mulsidi3_sp64"
4167   [(set (match_operand:DI 0 "register_operand" "=r")
4168         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4169                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4170   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4171   "smul\t%1, %2, %0"
4172   [(set_attr "type" "imul")])
4174 ;; Extra pattern, because sign_extend of a constant isn't valid.
4176 ;; XXX
4177 (define_insn "const_mulsidi3_sp32"
4178   [(set (match_operand:DI 0 "register_operand" "=r")
4179         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4180                  (match_operand:DI 2 "small_int_operand" "I")))]
4181   "TARGET_HARD_MUL32"
4183   return TARGET_SPARCLET
4184          ? "smuld\t%1, %2, %L0"
4185          : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4187   [(set (attr "type")
4188         (if_then_else (eq_attr "isa" "sparclet")
4189                       (const_string "imul") (const_string "multi")))
4190    (set (attr "length")
4191         (if_then_else (eq_attr "isa" "sparclet")
4192                       (const_int 1) (const_int 2)))])
4194 (define_insn "const_mulsidi3_sp64"
4195   [(set (match_operand:DI 0 "register_operand" "=r")
4196         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4197                  (match_operand:DI 2 "small_int_operand" "I")))]
4198   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4199   "smul\t%1, %2, %0"
4200   [(set_attr "type" "imul")])
4202 (define_expand "smulsi3_highpart"
4203   [(set (match_operand:SI 0 "register_operand" "")
4204         (truncate:SI
4205          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4206                                (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
4207                       (const_int 32))))]
4208   "TARGET_HARD_MUL && TARGET_ARCH32"
4210   if (CONSTANT_P (operands[2]))
4211     {
4212       if (TARGET_V8PLUS)
4213         {
4214           emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
4215                                                         operands[1],
4216                                                         operands[2],
4217                                                         GEN_INT (32)));
4218           DONE;
4219         }
4220       emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
4221       DONE;
4222     }
4223   if (TARGET_V8PLUS)
4224     {
4225       emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
4226                                               operands[2], GEN_INT (32)));
4227       DONE;
4228     }
4231 ;; XXX
4232 (define_insn "smulsi3_highpart_v8plus"
4233   [(set (match_operand:SI 0 "register_operand" "=h,r")
4234         (truncate:SI
4235          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4236                                (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4237                       (match_operand:SI 3 "small_int_operand" "I,I"))))
4238    (clobber (match_scratch:SI 4 "=X,&h"))]
4239   "TARGET_V8PLUS"
4240   "@
4241    smul\t%1, %2, %0\;srlx\t%0, %3, %0
4242    smul\t%1, %2, %4\;srlx\t%4, %3, %0"
4243   [(set_attr "type" "multi")
4244    (set_attr "length" "2")])
4246 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
4247 ;; XXX
4248 (define_insn ""
4249   [(set (match_operand:SI 0 "register_operand" "=h,r")
4250         (subreg:SI
4251          (lshiftrt:DI
4252           (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4253                    (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4254           (match_operand:SI 3 "small_int_operand" "I,I"))
4255          4))
4256    (clobber (match_scratch:SI 4 "=X,&h"))]
4257   "TARGET_V8PLUS"
4258   "@
4259    smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4260    smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4261   [(set_attr "type" "multi")
4262    (set_attr "length" "2")])
4264 ;; XXX
4265 (define_insn "const_smulsi3_highpart_v8plus"
4266   [(set (match_operand:SI 0 "register_operand" "=h,r")
4267         (truncate:SI
4268          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4269                                (match_operand:DI 2 "small_int_operand" "I,I"))
4270                       (match_operand:SI 3 "small_int_operand" "I,I"))))
4271    (clobber (match_scratch:SI 4 "=X,&h"))]
4272   "TARGET_V8PLUS"
4273   "@
4274    smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4275    smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4276   [(set_attr "type" "multi")
4277    (set_attr "length" "2")])
4279 ;; XXX
4280 (define_insn "*smulsi3_highpart_sp32"
4281   [(set (match_operand:SI 0 "register_operand" "=r")
4282         (truncate:SI
4283          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4284                                (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
4285                       (const_int 32))))]
4286   "TARGET_HARD_MUL32"
4287   "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4288   [(set_attr "type" "multi")
4289    (set_attr "length" "2")])
4291 ;; XXX
4292 (define_insn "const_smulsi3_highpart"
4293   [(set (match_operand:SI 0 "register_operand" "=r")
4294         (truncate:SI
4295          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4296                                (match_operand:DI 2 "small_int_operand" "i"))
4297                       (const_int 32))))]
4298   "TARGET_HARD_MUL32"
4299   "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4300   [(set_attr "type" "multi")
4301    (set_attr "length" "2")])
4303 (define_expand "umulsidi3"
4304   [(set (match_operand:DI 0 "register_operand" "")
4305         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4306                  (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
4307   "TARGET_HARD_MUL"
4309   if (CONSTANT_P (operands[2]))
4310     {
4311       if (TARGET_V8PLUS)
4312         emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
4313                                                operands[2]));
4314       else if (TARGET_ARCH32)
4315         emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
4316                                              operands[2]));
4317       else 
4318         emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
4319                                              operands[2]));
4320       DONE;
4321     }
4322   if (TARGET_V8PLUS)
4323     {
4324       emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
4325       DONE;
4326     }
4329 ;; XXX
4330 (define_insn "umulsidi3_v8plus"
4331   [(set (match_operand:DI 0 "register_operand" "=h,r")
4332         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4333                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4334    (clobber (match_scratch:SI 3 "=X,&h"))]
4335   "TARGET_V8PLUS"
4336   "@
4337    umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4338    umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4339   [(set_attr "type" "multi")
4340    (set_attr "length" "2,3")])
4342 ;; XXX
4343 (define_insn "*umulsidi3_sp32"
4344   [(set (match_operand:DI 0 "register_operand" "=r")
4345         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4346                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4347   "TARGET_HARD_MUL32"
4349   return TARGET_SPARCLET
4350          ? "umuld\t%1, %2, %L0"
4351          : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
4353   [(set (attr "type")
4354         (if_then_else (eq_attr "isa" "sparclet")
4355                       (const_string "imul") (const_string "multi")))
4356    (set (attr "length")
4357         (if_then_else (eq_attr "isa" "sparclet")
4358                       (const_int 1) (const_int 2)))])
4360 (define_insn "*umulsidi3_sp64"
4361   [(set (match_operand:DI 0 "register_operand" "=r")
4362         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4363                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4364   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4365   "umul\t%1, %2, %0"
4366   [(set_attr "type" "imul")])
4368 ;; Extra pattern, because sign_extend of a constant isn't valid.
4370 ;; XXX
4371 (define_insn "const_umulsidi3_sp32"
4372   [(set (match_operand:DI 0 "register_operand" "=r")
4373         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4374                  (match_operand:DI 2 "uns_small_int_operand" "")))]
4375   "TARGET_HARD_MUL32"
4377   return TARGET_SPARCLET
4378          ? "umuld\t%1, %s2, %L0"
4379          : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
4381   [(set (attr "type")
4382         (if_then_else (eq_attr "isa" "sparclet")
4383                       (const_string "imul") (const_string "multi")))
4384    (set (attr "length")
4385         (if_then_else (eq_attr "isa" "sparclet")
4386                       (const_int 1) (const_int 2)))])
4388 (define_insn "const_umulsidi3_sp64"
4389   [(set (match_operand:DI 0 "register_operand" "=r")
4390         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4391                  (match_operand:DI 2 "uns_small_int_operand" "")))]
4392   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4393   "umul\t%1, %s2, %0"
4394   [(set_attr "type" "imul")])
4396 ;; XXX
4397 (define_insn "const_umulsidi3_v8plus"
4398   [(set (match_operand:DI 0 "register_operand" "=h,r")
4399         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4400                  (match_operand:DI 2 "uns_small_int_operand" "")))
4401    (clobber (match_scratch:SI 3 "=X,h"))]
4402   "TARGET_V8PLUS"
4403   "@
4404    umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
4405    umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4406   [(set_attr "type" "multi")
4407    (set_attr "length" "2,3")])
4409 (define_expand "umulsi3_highpart"
4410   [(set (match_operand:SI 0 "register_operand" "")
4411         (truncate:SI
4412          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4413                                (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
4414                       (const_int 32))))]
4415   "TARGET_HARD_MUL && TARGET_ARCH32"
4417   if (CONSTANT_P (operands[2]))
4418     {
4419       if (TARGET_V8PLUS)
4420         {
4421           emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
4422                                                         operands[1],
4423                                                         operands[2],
4424                                                         GEN_INT (32)));
4425           DONE;
4426         }
4427       emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
4428       DONE;
4429     }
4430   if (TARGET_V8PLUS)
4431     {
4432       emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
4433                                               operands[2], GEN_INT (32)));
4434       DONE;
4435     }
4438 ;; XXX
4439 (define_insn "umulsi3_highpart_v8plus"
4440   [(set (match_operand:SI 0 "register_operand" "=h,r")
4441         (truncate:SI
4442          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4443                                (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4444                       (match_operand:SI 3 "small_int_operand" "I,I"))))
4445    (clobber (match_scratch:SI 4 "=X,h"))]
4446   "TARGET_V8PLUS"
4447   "@
4448    umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4449    umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4450   [(set_attr "type" "multi")
4451    (set_attr "length" "2")])
4453 ;; XXX
4454 (define_insn "const_umulsi3_highpart_v8plus"
4455   [(set (match_operand:SI 0 "register_operand" "=h,r")
4456         (truncate:SI
4457          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4458                                (match_operand:DI 2 "uns_small_int_operand" ""))
4459                       (match_operand:SI 3 "small_int_operand" "I,I"))))
4460    (clobber (match_scratch:SI 4 "=X,h"))]
4461   "TARGET_V8PLUS"
4462   "@
4463    umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
4464    umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
4465   [(set_attr "type" "multi")
4466    (set_attr "length" "2")])
4468 ;; XXX
4469 (define_insn "*umulsi3_highpart_sp32"
4470   [(set (match_operand:SI 0 "register_operand" "=r")
4471         (truncate:SI
4472          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4473                                (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
4474                       (const_int 32))))]
4475   "TARGET_HARD_MUL32"
4476   "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
4477   [(set_attr "type" "multi")
4478    (set_attr "length" "2")])
4480 ;; XXX
4481 (define_insn "const_umulsi3_highpart"
4482   [(set (match_operand:SI 0 "register_operand" "=r")
4483         (truncate:SI
4484          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4485                                (match_operand:DI 2 "uns_small_int_operand" ""))
4486                       (const_int 32))))]
4487   "TARGET_HARD_MUL32"
4488   "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
4489   [(set_attr "type" "multi")
4490    (set_attr "length" "2")])
4492 (define_expand "divsi3"
4493   [(parallel [(set (match_operand:SI 0 "register_operand" "")
4494                    (div:SI (match_operand:SI 1 "register_operand" "")
4495                            (match_operand:SI 2 "input_operand" "")))
4496               (clobber (match_scratch:SI 3 ""))])]
4497   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4499   if (TARGET_ARCH64)
4500     {
4501       operands[3] = gen_reg_rtx(SImode);
4502       emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
4503       emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
4504                                   operands[3]));
4505       DONE;
4506     }
4509 ;; The V8 architecture specifies that there must be at least 3 instructions
4510 ;; between a write to the Y register and a use of it for correct results.
4511 ;; We try to fill one of them with a simple constant or a memory load.
4513 (define_insn "divsi3_sp32"
4514   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
4515         (div:SI (match_operand:SI 1 "register_operand" "r,r,r")
4516                 (match_operand:SI 2 "input_operand" "rI,K,m")))
4517    (clobber (match_scratch:SI 3 "=&r,&r,&r"))]
4518   "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4520   output_asm_insn ("sra\t%1, 31, %3", operands);
4521   output_asm_insn ("wr\t%3, 0, %%y", operands);
4523   switch (which_alternative)
4524     {
4525     case 0:
4526       if (TARGET_V9)
4527         return "sdiv\t%1, %2, %0";
4528       else
4529         return "nop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
4530     case 1:
4531       if (TARGET_V9)
4532         return "sethi\t%%hi(%a2), %3\n\tsdiv\t%1, %3, %0";
4533       else
4534         return "sethi\t%%hi(%a2), %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4535     case 2:
4536       if (TARGET_V9)
4537         return "ld\t%2, %3\n\tsdiv\t%1, %3, %0";
4538       else
4539         return "ld\t%2, %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4540     default:
4541       gcc_unreachable ();
4542     }
4544   [(set_attr "type" "multi")
4545    (set (attr "length")
4546         (if_then_else (eq_attr "isa" "v9")
4547                       (const_int 4) (const_int 6)))])
4549 (define_insn "divsi3_sp64"
4550   [(set (match_operand:SI 0 "register_operand" "=r")
4551         (div:SI (match_operand:SI 1 "register_operand" "r")
4552                 (match_operand:SI 2 "input_operand" "rI")))
4553    (use (match_operand:SI 3 "register_operand" "r"))]
4554   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4555   "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
4556   [(set_attr "type" "multi")
4557    (set_attr "length" "2")])
4559 (define_insn "divdi3"
4560   [(set (match_operand:DI 0 "register_operand" "=r")
4561         (div:DI (match_operand:DI 1 "register_operand" "r")
4562                 (match_operand:DI 2 "arith_operand" "rI")))]
4563   "TARGET_ARCH64"
4564   "sdivx\t%1, %2, %0"
4565   [(set_attr "type" "idiv")])
4567 (define_insn "*cmp_sdiv_cc_set"
4568   [(set (reg:CC CC_REG)
4569         (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
4570                             (match_operand:SI 2 "arith_operand" "rI"))
4571                     (const_int 0)))
4572    (set (match_operand:SI 0 "register_operand" "=r")
4573         (div:SI (match_dup 1) (match_dup 2)))
4574    (clobber (match_scratch:SI 3 "=&r"))]
4575   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4577   output_asm_insn ("sra\t%1, 31, %3", operands);
4578   output_asm_insn ("wr\t%3, 0, %%y", operands);
4580   if (TARGET_V9)
4581     return "sdivcc\t%1, %2, %0";
4582   else
4583     return "nop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
4585   [(set_attr "type" "multi")
4586    (set (attr "length")
4587         (if_then_else (eq_attr "isa" "v9")
4588                       (const_int 3) (const_int 6)))])
4590 ;; XXX
4591 (define_expand "udivsi3"
4592   [(set (match_operand:SI 0 "register_operand" "")
4593         (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "")
4594                  (match_operand:SI 2 "input_operand" "")))]
4595   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4596   "")
4598 ;; The V8 architecture specifies that there must be at least 3 instructions
4599 ;; between a write to the Y register and a use of it for correct results.
4600 ;; We try to fill one of them with a simple constant or a memory load.
4602 (define_insn "udivsi3_sp32"
4603   [(set (match_operand:SI 0 "register_operand" "=r,&r,&r,&r")
4604         (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r,r,r,m")
4605                  (match_operand:SI 2 "input_operand" "rI,K,m,r")))]
4606   "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4608   output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4610   switch (which_alternative)
4611     {
4612     case 0:
4613       if (TARGET_V9)
4614         return "udiv\t%1, %2, %0";
4615       else
4616         return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
4617     case 1:
4618       if (TARGET_V9)
4619         return "sethi\t%%hi(%a2), %0\n\tudiv\t%1, %0, %0";
4620       else
4621         return "sethi\t%%hi(%a2), %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4622     case 2:
4623       if (TARGET_V9)
4624         return "ld\t%2, %0\n\tudiv\t%1, %0, %0";
4625       else
4626         return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4627     case 3:
4628       if (TARGET_V9)
4629         return "ld\t%1, %0\n\tudiv\t%0, %2, %0";
4630       else
4631         return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
4632     default:
4633       gcc_unreachable ();
4634     }
4636   [(set_attr "type" "multi")
4637    (set (attr "length")
4638         (if_then_else (eq_attr "isa" "v9")
4639                       (const_int 3) (const_int 5)))])
4641 (define_insn "udivsi3_sp64"
4642   [(set (match_operand:SI 0 "register_operand" "=r")
4643         (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r")
4644                  (match_operand:SI 2 "input_operand" "rI")))]
4645   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4646   "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
4647   [(set_attr "type" "multi")
4648    (set_attr "length" "2")])
4650 (define_insn "udivdi3"
4651   [(set (match_operand:DI 0 "register_operand" "=r")
4652         (udiv:DI (match_operand:DI 1 "register_operand" "r")
4653                  (match_operand:DI 2 "arith_operand" "rI")))]
4654   "TARGET_ARCH64"
4655   "udivx\t%1, %2, %0"
4656   [(set_attr "type" "idiv")])
4658 (define_insn "*cmp_udiv_cc_set"
4659   [(set (reg:CC CC_REG)
4660         (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
4661                              (match_operand:SI 2 "arith_operand" "rI"))
4662                     (const_int 0)))
4663    (set (match_operand:SI 0 "register_operand" "=r")
4664         (udiv:SI (match_dup 1) (match_dup 2)))]
4665   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4667   output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4669   if (TARGET_V9)
4670     return "udivcc\t%1, %2, %0";
4671   else
4672     return "nop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
4674   [(set_attr "type" "multi")
4675    (set (attr "length")
4676         (if_then_else (eq_attr "isa" "v9")
4677                       (const_int 2) (const_int 5)))])
4679 ; sparclet multiply/accumulate insns
4681 (define_insn "*smacsi"
4682   [(set (match_operand:SI 0 "register_operand" "=r")
4683         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
4684                           (match_operand:SI 2 "arith_operand" "rI"))
4685                  (match_operand:SI 3 "register_operand" "0")))]
4686   "TARGET_SPARCLET"
4687   "smac\t%1, %2, %0"
4688   [(set_attr "type" "imul")])
4690 (define_insn "*smacdi"
4691   [(set (match_operand:DI 0 "register_operand" "=r")
4692         (plus:DI (mult:DI (sign_extend:DI
4693                            (match_operand:SI 1 "register_operand" "%r"))
4694                           (sign_extend:DI
4695                            (match_operand:SI 2 "register_operand" "r")))
4696                  (match_operand:DI 3 "register_operand" "0")))]
4697   "TARGET_SPARCLET"
4698   "smacd\t%1, %2, %L0"
4699   [(set_attr "type" "imul")])
4701 (define_insn "*umacdi"
4702   [(set (match_operand:DI 0 "register_operand" "=r")
4703         (plus:DI (mult:DI (zero_extend:DI
4704                            (match_operand:SI 1 "register_operand" "%r"))
4705                           (zero_extend:DI
4706                            (match_operand:SI 2 "register_operand" "r")))
4707                  (match_operand:DI 3 "register_operand" "0")))]
4708   "TARGET_SPARCLET"
4709   "umacd\t%1, %2, %L0"
4710   [(set_attr "type" "imul")])
4713 ;; Boolean instructions.
4715 ;; We define DImode `and' so with DImode `not' we can get
4716 ;; DImode `andn'.  Other combinations are possible.
4718 (define_expand "anddi3"
4719   [(set (match_operand:DI 0 "register_operand" "")
4720         (and:DI (match_operand:DI 1 "arith_double_operand" "")
4721                 (match_operand:DI 2 "arith_double_operand" "")))]
4722   ""
4723   "")
4725 (define_insn "*anddi3_sp32"
4726   [(set (match_operand:DI 0 "register_operand" "=r")
4727         (and:DI (match_operand:DI 1 "arith_double_operand" "%r")
4728                 (match_operand:DI 2 "arith_double_operand" "rHI")))]
4729   "! TARGET_ARCH64"
4730   "#")
4732 (define_insn "*anddi3_sp64"
4733   [(set (match_operand:DI 0 "register_operand" "=r")
4734         (and:DI (match_operand:DI 1 "arith_operand" "%r")
4735                 (match_operand:DI 2 "arith_operand" "rI")))]
4736   "TARGET_ARCH64"
4737   "and\t%1, %2, %0")
4739 (define_insn "andsi3"
4740   [(set (match_operand:SI 0 "register_operand" "=r")
4741         (and:SI (match_operand:SI 1 "arith_operand" "%r")
4742                 (match_operand:SI 2 "arith_operand" "rI")))]
4743   ""
4744   "and\t%1, %2, %0")
4746 (define_split
4747   [(set (match_operand:SI 0 "register_operand" "")
4748         (and:SI (match_operand:SI 1 "register_operand" "")
4749                 (match_operand:SI 2 "const_compl_high_operand" "")))
4750    (clobber (match_operand:SI 3 "register_operand" ""))]
4751   ""
4752   [(set (match_dup 3) (match_dup 4))
4753    (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
4755   operands[4] = GEN_INT (~INTVAL (operands[2]));
4758 (define_insn_and_split "*and_not_di_sp32"
4759   [(set (match_operand:DI 0 "register_operand" "=r")
4760         (and:DI (not:DI (match_operand:DI 1 "register_operand" "%r"))
4761                 (match_operand:DI 2 "register_operand" "r")))]
4762   "! TARGET_ARCH64"
4763   "#"
4764   "&& reload_completed
4765    && ((GET_CODE (operands[0]) == REG
4766         && SPARC_INT_REG_P (REGNO (operands[0])))
4767        || (GET_CODE (operands[0]) == SUBREG
4768            && GET_CODE (SUBREG_REG (operands[0])) == REG
4769            && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
4770   [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
4771    (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
4772   "operands[3] = gen_highpart (SImode, operands[0]);
4773    operands[4] = gen_highpart (SImode, operands[1]);
4774    operands[5] = gen_highpart (SImode, operands[2]);
4775    operands[6] = gen_lowpart (SImode, operands[0]);
4776    operands[7] = gen_lowpart (SImode, operands[1]);
4777    operands[8] = gen_lowpart (SImode, operands[2]);"
4778   [(set_attr "length" "2")])
4780 (define_insn "*and_not_di_sp64"
4781   [(set (match_operand:DI 0 "register_operand" "=r")
4782         (and:DI (not:DI (match_operand:DI 1 "register_operand" "%r"))
4783                 (match_operand:DI 2 "register_operand" "r")))]
4784   "TARGET_ARCH64"
4785   "andn\t%2, %1, %0")
4787 (define_insn "*and_not_si"
4788   [(set (match_operand:SI 0 "register_operand" "=r")
4789         (and:SI (not:SI (match_operand:SI 1 "register_operand" "%r"))
4790                 (match_operand:SI 2 "register_operand" "r")))]
4791   ""
4792   "andn\t%2, %1, %0")
4794 (define_expand "iordi3"
4795   [(set (match_operand:DI 0 "register_operand" "")
4796         (ior:DI (match_operand:DI 1 "arith_double_operand" "")
4797                 (match_operand:DI 2 "arith_double_operand" "")))]
4798   ""
4799   "")
4801 (define_insn "*iordi3_sp32"
4802   [(set (match_operand:DI 0 "register_operand" "=r")
4803         (ior:DI (match_operand:DI 1 "arith_double_operand" "%r")
4804                 (match_operand:DI 2 "arith_double_operand" "rHI")))]
4805   "! TARGET_ARCH64"
4806   "#"
4807   [(set_attr "length" "2")])
4809 (define_insn "*iordi3_sp64"
4810   [(set (match_operand:DI 0 "register_operand" "=r")
4811         (ior:DI (match_operand:DI 1 "arith_operand" "%r")
4812                 (match_operand:DI 2 "arith_operand" "rI")))]
4813   "TARGET_ARCH64"
4814   "or\t%1, %2, %0")
4816 (define_insn "iorsi3"
4817   [(set (match_operand:SI 0 "register_operand" "=r")
4818         (ior:SI (match_operand:SI 1 "arith_operand" "%r")
4819                 (match_operand:SI 2 "arith_operand" "rI")))]
4820   ""
4821   "or\t%1, %2, %0")
4823 (define_split
4824   [(set (match_operand:SI 0 "register_operand" "")
4825         (ior:SI (match_operand:SI 1 "register_operand" "")
4826                 (match_operand:SI 2 "const_compl_high_operand" "")))
4827    (clobber (match_operand:SI 3 "register_operand" ""))]
4828   ""
4829   [(set (match_dup 3) (match_dup 4))
4830    (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
4832   operands[4] = gen_int_mode (~INTVAL (operands[2]), SImode);
4835 (define_insn_and_split "*or_not_di_sp32"
4836   [(set (match_operand:DI 0 "register_operand" "=r")
4837         (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
4838                 (match_operand:DI 2 "register_operand" "r")))]
4839   "! TARGET_ARCH64"
4840   "#"
4841   "&& reload_completed
4842    && ((GET_CODE (operands[0]) == REG
4843         && SPARC_INT_REG_P (REGNO (operands[0])))
4844        || (GET_CODE (operands[0]) == SUBREG
4845            && GET_CODE (SUBREG_REG (operands[0])) == REG
4846            && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
4847   [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
4848    (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
4849   "operands[3] = gen_highpart (SImode, operands[0]);
4850    operands[4] = gen_highpart (SImode, operands[1]);
4851    operands[5] = gen_highpart (SImode, operands[2]);
4852    operands[6] = gen_lowpart (SImode, operands[0]);
4853    operands[7] = gen_lowpart (SImode, operands[1]);
4854    operands[8] = gen_lowpart (SImode, operands[2]);"
4855   [(set_attr "length" "2")])
4857 (define_insn "*or_not_di_sp64"
4858   [(set (match_operand:DI 0 "register_operand" "=r")
4859         (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
4860                 (match_operand:DI 2 "register_operand" "r")))]
4861   "TARGET_ARCH64"
4862   "orn\t%2, %1, %0")
4864 (define_insn "*or_not_si"
4865   [(set (match_operand:SI 0 "register_operand" "=r")
4866         (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
4867                 (match_operand:SI 2 "register_operand" "r")))]
4868   ""
4869   "orn\t%2, %1, %0")
4871 (define_expand "xordi3"
4872   [(set (match_operand:DI 0 "register_operand" "")
4873         (xor:DI (match_operand:DI 1 "arith_double_operand" "")
4874                 (match_operand:DI 2 "arith_double_operand" "")))]
4875   ""
4876   "")
4878 (define_insn "*xordi3_sp32"
4879   [(set (match_operand:DI 0 "register_operand" "=r")
4880         (xor:DI (match_operand:DI 1 "arith_double_operand" "%r")
4881                 (match_operand:DI 2 "arith_double_operand" "rHI")))]
4882   "! TARGET_ARCH64"
4883   "#"
4884   [(set_attr "length" "2")])
4886 (define_insn "*xordi3_sp64"
4887   [(set (match_operand:DI 0 "register_operand" "=r")
4888         (xor:DI (match_operand:DI 1 "arith_operand" "%rJ")
4889                 (match_operand:DI 2 "arith_operand" "rI")))]
4890   "TARGET_ARCH64"
4891   "xor\t%r1, %2, %0")
4893 (define_insn "xorsi3"
4894   [(set (match_operand:SI 0 "register_operand" "=r")
4895         (xor:SI (match_operand:SI 1 "arith_operand" "%rJ")
4896                   (match_operand:SI 2 "arith_operand" "rI")))]
4897   ""
4898   "xor\t%r1, %2, %0")
4900 (define_split
4901   [(set (match_operand:SI 0 "register_operand" "")
4902         (xor:SI (match_operand:SI 1 "register_operand" "")
4903                 (match_operand:SI 2 "const_compl_high_operand" "")))
4904    (clobber (match_operand:SI 3 "register_operand" ""))]
4905    ""
4906   [(set (match_dup 3) (match_dup 4))
4907    (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
4909   operands[4] = gen_int_mode (~INTVAL (operands[2]), SImode);
4912 (define_split
4913   [(set (match_operand:SI 0 "register_operand" "")
4914         (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
4915                         (match_operand:SI 2 "const_compl_high_operand" ""))))
4916    (clobber (match_operand:SI 3 "register_operand" ""))]
4917   ""
4918   [(set (match_dup 3) (match_dup 4))
4919    (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
4921   operands[4] = gen_int_mode (~INTVAL (operands[2]), SImode);
4924 ;; Split DImode logical operations requiring two instructions.
4925 (define_split
4926   [(set (match_operand:DI 0 "register_operand" "")
4927         (match_operator:DI 1 "cc_arith_operator"        ; AND, IOR, XOR
4928                            [(match_operand:DI 2 "register_operand" "")
4929                             (match_operand:DI 3 "arith_double_operand" "")]))]
4930   "! TARGET_ARCH64
4931    && reload_completed
4932    && ((GET_CODE (operands[0]) == REG
4933         && SPARC_INT_REG_P (REGNO (operands[0])))
4934        || (GET_CODE (operands[0]) == SUBREG
4935            && GET_CODE (SUBREG_REG (operands[0])) == REG
4936            && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
4937   [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
4938    (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
4940   operands[4] = gen_highpart (SImode, operands[0]);
4941   operands[5] = gen_lowpart (SImode, operands[0]);
4942   operands[6] = gen_highpart (SImode, operands[2]);
4943   operands[7] = gen_lowpart (SImode, operands[2]);
4944 #if HOST_BITS_PER_WIDE_INT == 32
4945   if (GET_CODE (operands[3]) == CONST_INT)
4946     {
4947       if (INTVAL (operands[3]) < 0)
4948         operands[8] = constm1_rtx;
4949       else
4950         operands[8] = const0_rtx;
4951     }
4952   else
4953 #endif
4954     operands[8] = gen_highpart_mode (SImode, DImode, operands[3]);
4955   operands[9] = gen_lowpart (SImode, operands[3]);
4958 ;; xnor patterns.  Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
4959 ;; Combine now canonicalizes to the rightmost expression.
4960 (define_insn_and_split "*xor_not_di_sp32"
4961   [(set (match_operand:DI 0 "register_operand" "=r")
4962         (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r")
4963                         (match_operand:DI 2 "register_operand" "r"))))]
4964   "! TARGET_ARCH64"
4965   "#"
4966   "&& reload_completed
4967    && ((GET_CODE (operands[0]) == REG
4968         && SPARC_INT_REG_P (REGNO (operands[0])))
4969        || (GET_CODE (operands[0]) == SUBREG
4970            && GET_CODE (SUBREG_REG (operands[0])) == REG
4971            && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
4972   [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
4973    (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
4974   "operands[3] = gen_highpart (SImode, operands[0]);
4975    operands[4] = gen_highpart (SImode, operands[1]);
4976    operands[5] = gen_highpart (SImode, operands[2]);
4977    operands[6] = gen_lowpart (SImode, operands[0]);
4978    operands[7] = gen_lowpart (SImode, operands[1]);
4979    operands[8] = gen_lowpart (SImode, operands[2]);"
4980   [(set_attr "length" "2")])
4982 (define_insn "*xor_not_di_sp64"
4983   [(set (match_operand:DI 0 "register_operand" "=r")
4984         (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
4985                         (match_operand:DI 2 "arith_operand" "rI"))))]
4986   "TARGET_ARCH64"
4987   "xnor\t%r1, %2, %0")
4989 (define_insn "*xor_not_si"
4990   [(set (match_operand:SI 0 "register_operand" "=r")
4991         (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4992                         (match_operand:SI 2 "arith_operand" "rI"))))]
4993   ""
4994   "xnor\t%r1, %2, %0")
4996 ;; These correspond to the above in the case where we also (or only)
4997 ;; want to set the condition code.  
4999 (define_insn "*cmp_cc_arith_op"
5000   [(set (reg:CC CC_REG)
5001         (compare:CC
5002          (match_operator:SI 2 "cc_arith_operator"
5003                             [(match_operand:SI 0 "arith_operand" "%r")
5004                              (match_operand:SI 1 "arith_operand" "rI")])
5005          (const_int 0)))]
5006   ""
5007   "%A2cc\t%0, %1, %%g0"
5008   [(set_attr "type" "compare")])
5010 (define_insn "*cmp_ccx_arith_op"
5011   [(set (reg:CCX CC_REG)
5012         (compare:CCX
5013          (match_operator:DI 2 "cc_arith_operator"
5014                             [(match_operand:DI 0 "arith_operand" "%r")
5015                              (match_operand:DI 1 "arith_operand" "rI")])
5016          (const_int 0)))]
5017   "TARGET_ARCH64"
5018   "%A2cc\t%0, %1, %%g0"
5019   [(set_attr "type" "compare")])
5021 (define_insn "*cmp_cc_arith_op_set"
5022   [(set (reg:CC CC_REG)
5023         (compare:CC
5024          (match_operator:SI 3 "cc_arith_operator"
5025                             [(match_operand:SI 1 "arith_operand" "%r")
5026                              (match_operand:SI 2 "arith_operand" "rI")])
5027          (const_int 0)))
5028    (set (match_operand:SI 0 "register_operand" "=r")
5029         (match_operator:SI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5030   "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5031   "%A3cc\t%1, %2, %0"
5032   [(set_attr "type" "compare")])
5034 (define_insn "*cmp_ccx_arith_op_set"
5035   [(set (reg:CCX CC_REG)
5036         (compare:CCX
5037          (match_operator:DI 3 "cc_arith_operator"
5038                             [(match_operand:DI 1 "arith_operand" "%r")
5039                              (match_operand:DI 2 "arith_operand" "rI")])
5040          (const_int 0)))
5041    (set (match_operand:DI 0 "register_operand" "=r")
5042         (match_operator:DI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5043   "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5044   "%A3cc\t%1, %2, %0"
5045   [(set_attr "type" "compare")])
5047 (define_insn "*cmp_cc_xor_not"
5048   [(set (reg:CC CC_REG)
5049         (compare:CC
5050          (not:SI (xor:SI (match_operand:SI 0 "register_or_zero_operand" "%rJ")
5051                          (match_operand:SI 1 "arith_operand" "rI")))
5052          (const_int 0)))]
5053   ""
5054   "xnorcc\t%r0, %1, %%g0"
5055   [(set_attr "type" "compare")])
5057 (define_insn "*cmp_ccx_xor_not"
5058   [(set (reg:CCX CC_REG)
5059         (compare:CCX
5060          (not:DI (xor:DI (match_operand:DI 0 "register_or_zero_operand" "%rJ")
5061                          (match_operand:DI 1 "arith_operand" "rI")))
5062          (const_int 0)))]
5063   "TARGET_ARCH64"
5064   "xnorcc\t%r0, %1, %%g0"
5065   [(set_attr "type" "compare")])
5067 (define_insn "*cmp_cc_xor_not_set"
5068   [(set (reg:CC CC_REG)
5069         (compare:CC
5070          (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
5071                          (match_operand:SI 2 "arith_operand" "rI")))
5072          (const_int 0)))
5073    (set (match_operand:SI 0 "register_operand" "=r")
5074         (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
5075   ""
5076   "xnorcc\t%r1, %2, %0"
5077   [(set_attr "type" "compare")])
5079 (define_insn "*cmp_ccx_xor_not_set"
5080   [(set (reg:CCX CC_REG)
5081         (compare:CCX
5082          (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
5083                          (match_operand:DI 2 "arith_operand" "rI")))
5084          (const_int 0)))
5085    (set (match_operand:DI 0 "register_operand" "=r")
5086         (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
5087   "TARGET_ARCH64"
5088   "xnorcc\t%r1, %2, %0"
5089   [(set_attr "type" "compare")])
5091 (define_insn "*cmp_cc_arith_op_not"
5092   [(set (reg:CC CC_REG)
5093         (compare:CC
5094          (match_operator:SI 2 "cc_arith_not_operator"
5095                             [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
5096                              (match_operand:SI 1 "register_or_zero_operand" "rJ")])
5097          (const_int 0)))]
5098   ""
5099   "%B2cc\t%r1, %0, %%g0"
5100   [(set_attr "type" "compare")])
5102 (define_insn "*cmp_ccx_arith_op_not"
5103   [(set (reg:CCX CC_REG)
5104         (compare:CCX
5105          (match_operator:DI 2 "cc_arith_not_operator"
5106                             [(not:DI (match_operand:DI 0 "arith_operand" "rI"))
5107                              (match_operand:DI 1 "register_or_zero_operand" "rJ")])
5108          (const_int 0)))]
5109   "TARGET_ARCH64"
5110   "%B2cc\t%r1, %0, %%g0"
5111   [(set_attr "type" "compare")])
5113 (define_insn "*cmp_cc_arith_op_not_set"
5114   [(set (reg:CC CC_REG)
5115         (compare:CC
5116          (match_operator:SI 3 "cc_arith_not_operator"
5117                             [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
5118                              (match_operand:SI 2 "register_or_zero_operand" "rJ")])
5119          (const_int 0)))
5120    (set (match_operand:SI 0 "register_operand" "=r")
5121         (match_operator:SI 4 "cc_arith_not_operator"
5122                             [(not:SI (match_dup 1)) (match_dup 2)]))]
5123   "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5124   "%B3cc\t%r2, %1, %0"
5125   [(set_attr "type" "compare")])
5127 (define_insn "*cmp_ccx_arith_op_not_set"
5128   [(set (reg:CCX CC_REG)
5129         (compare:CCX
5130          (match_operator:DI 3 "cc_arith_not_operator"
5131                             [(not:DI (match_operand:DI 1 "arith_operand" "rI"))
5132                              (match_operand:DI 2 "register_or_zero_operand" "rJ")])
5133          (const_int 0)))
5134    (set (match_operand:DI 0 "register_operand" "=r")
5135         (match_operator:DI 4 "cc_arith_not_operator"
5136                             [(not:DI (match_dup 1)) (match_dup 2)]))]
5137   "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5138   "%B3cc\t%r2, %1, %0"
5139   [(set_attr "type" "compare")])
5141 ;; We cannot use the "neg" pseudo insn because the Sun assembler
5142 ;; does not know how to make it work for constants.
5144 (define_expand "negdi2"
5145   [(set (match_operand:DI 0 "register_operand" "=r")
5146         (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5147   ""
5149   if (! TARGET_ARCH64)
5150     {
5151       emit_insn (gen_rtx_PARALLEL
5152                  (VOIDmode,
5153                   gen_rtvec (2,
5154                              gen_rtx_SET (VOIDmode, operand0,
5155                                           gen_rtx_NEG (DImode, operand1)),
5156                              gen_rtx_CLOBBER (VOIDmode,
5157                                               gen_rtx_REG (CCmode,
5158                                                            SPARC_ICC_REG)))));
5159       DONE;
5160     }
5163 (define_insn_and_split "*negdi2_sp32"
5164   [(set (match_operand:DI 0 "register_operand" "=r")
5165         (neg:DI (match_operand:DI 1 "register_operand" "r")))
5166    (clobber (reg:CC CC_REG))]
5167   "! TARGET_ARCH64"
5168   "#"
5169   "&& reload_completed"
5170   [(parallel [(set (reg:CC_NOOV CC_REG)
5171                    (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
5172                                     (const_int 0)))
5173               (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
5174    (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
5175                                 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
5176   "operands[2] = gen_highpart (SImode, operands[0]);
5177    operands[3] = gen_highpart (SImode, operands[1]);
5178    operands[4] = gen_lowpart (SImode, operands[0]);
5179    operands[5] = gen_lowpart (SImode, operands[1]);"
5180   [(set_attr "length" "2")])
5182 (define_insn "*negdi2_sp64"
5183   [(set (match_operand:DI 0 "register_operand" "=r")
5184         (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5185   "TARGET_ARCH64"
5186   "sub\t%%g0, %1, %0")
5188 (define_insn "negsi2"
5189   [(set (match_operand:SI 0 "register_operand" "=r")
5190         (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
5191   ""
5192   "sub\t%%g0, %1, %0")
5194 (define_insn "*cmp_cc_neg"
5195   [(set (reg:CC_NOOV CC_REG)
5196         (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
5197                          (const_int 0)))]
5198   ""
5199   "subcc\t%%g0, %0, %%g0"
5200   [(set_attr "type" "compare")])
5202 (define_insn "*cmp_ccx_neg"
5203   [(set (reg:CCX_NOOV CC_REG)
5204         (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_operand" "rI"))
5205                           (const_int 0)))]
5206   "TARGET_ARCH64"
5207   "subcc\t%%g0, %0, %%g0"
5208   [(set_attr "type" "compare")])
5210 (define_insn "*cmp_cc_set_neg"
5211   [(set (reg:CC_NOOV CC_REG)
5212         (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
5213                          (const_int 0)))
5214    (set (match_operand:SI 0 "register_operand" "=r")
5215         (neg:SI (match_dup 1)))]
5216   ""
5217   "subcc\t%%g0, %1, %0"
5218   [(set_attr "type" "compare")])
5220 (define_insn "*cmp_ccx_set_neg"
5221   [(set (reg:CCX_NOOV CC_REG)
5222         (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_operand" "rI"))
5223                           (const_int 0)))
5224    (set (match_operand:DI 0 "register_operand" "=r")
5225         (neg:DI (match_dup 1)))]
5226   "TARGET_ARCH64"
5227   "subcc\t%%g0, %1, %0"
5228   [(set_attr "type" "compare")])
5230 ;; We cannot use the "not" pseudo insn because the Sun assembler
5231 ;; does not know how to make it work for constants.
5232 (define_expand "one_cmpldi2"
5233   [(set (match_operand:DI 0 "register_operand" "")
5234         (not:DI (match_operand:DI 1 "register_operand" "")))]
5235   ""
5236   "")
5238 (define_insn_and_split "*one_cmpldi2_sp32"
5239   [(set (match_operand:DI 0 "register_operand" "=r")
5240         (not:DI (match_operand:DI 1 "register_operand" "r")))]
5241   "! TARGET_ARCH64"
5242   "#"
5243   "&& reload_completed
5244    && ((GET_CODE (operands[0]) == REG
5245         && SPARC_INT_REG_P (REGNO (operands[0])))
5246        || (GET_CODE (operands[0]) == SUBREG
5247            && GET_CODE (SUBREG_REG (operands[0])) == REG
5248            && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
5249   [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
5250    (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
5251   "operands[2] = gen_highpart (SImode, operands[0]);
5252    operands[3] = gen_highpart (SImode, operands[1]);
5253    operands[4] = gen_lowpart (SImode, operands[0]);
5254    operands[5] = gen_lowpart (SImode, operands[1]);"
5255   [(set_attr "length" "2")])
5257 (define_insn "*one_cmpldi2_sp64"
5258   [(set (match_operand:DI 0 "register_operand" "=r")
5259         (not:DI (match_operand:DI 1 "arith_operand" "rI")))]
5260   "TARGET_ARCH64"
5261   "xnor\t%%g0, %1, %0")
5263 (define_insn "one_cmplsi2"
5264   [(set (match_operand:SI 0 "register_operand" "=r")
5265         (not:SI (match_operand:SI 1 "arith_operand" "rI")))]
5266   ""
5267   "xnor\t%%g0, %1, %0")
5269 (define_insn "*cmp_cc_not"
5270   [(set (reg:CC CC_REG)
5271         (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
5272                     (const_int 0)))]
5273   ""
5274   "xnorcc\t%%g0, %0, %%g0"
5275   [(set_attr "type" "compare")])
5277 (define_insn "*cmp_ccx_not"
5278   [(set (reg:CCX CC_REG)
5279         (compare:CCX (not:DI (match_operand:DI 0 "arith_operand" "rI"))
5280                      (const_int 0)))]
5281   "TARGET_ARCH64"
5282   "xnorcc\t%%g0, %0, %%g0"
5283   [(set_attr "type" "compare")])
5285 (define_insn "*cmp_cc_set_not"
5286   [(set (reg:CC CC_REG)
5287         (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
5288                     (const_int 0)))
5289    (set (match_operand:SI 0 "register_operand" "=r")
5290         (not:SI (match_dup 1)))]
5291   ""
5292   "xnorcc\t%%g0, %1, %0"
5293   [(set_attr "type" "compare")])
5295 (define_insn "*cmp_ccx_set_not"
5296   [(set (reg:CCX CC_REG)
5297         (compare:CCX (not:DI (match_operand:DI 1 "arith_operand" "rI"))
5298                     (const_int 0)))
5299    (set (match_operand:DI 0 "register_operand" "=r")
5300         (not:DI (match_dup 1)))]
5301   "TARGET_ARCH64"
5302   "xnorcc\t%%g0, %1, %0"
5303   [(set_attr "type" "compare")])
5305 (define_insn "*cmp_cc_set"
5306   [(set (match_operand:SI 0 "register_operand" "=r")
5307         (match_operand:SI 1 "register_operand" "r"))
5308    (set (reg:CC CC_REG)
5309         (compare:CC (match_dup 1)
5310                     (const_int 0)))]
5311   ""
5312   "orcc\t%1, 0, %0"
5313   [(set_attr "type" "compare")])
5315 (define_insn "*cmp_ccx_set64"
5316   [(set (match_operand:DI 0 "register_operand" "=r")
5317         (match_operand:DI 1 "register_operand" "r"))
5318    (set (reg:CCX CC_REG)
5319         (compare:CCX (match_dup 1)
5320                      (const_int 0)))]
5321   "TARGET_ARCH64"
5322   "orcc\t%1, 0, %0"
5323    [(set_attr "type" "compare")])
5326 ;; Floating point arithmetic instructions.
5328 (define_expand "addtf3"
5329   [(set (match_operand:TF 0 "nonimmediate_operand" "")
5330         (plus:TF (match_operand:TF 1 "general_operand" "")
5331                  (match_operand:TF 2 "general_operand" "")))]
5332   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5333   "emit_tfmode_binop (PLUS, operands); DONE;")
5335 (define_insn "*addtf3_hq"
5336   [(set (match_operand:TF 0 "register_operand" "=e")
5337         (plus:TF (match_operand:TF 1 "register_operand" "e")
5338                  (match_operand:TF 2 "register_operand" "e")))]
5339   "TARGET_FPU && TARGET_HARD_QUAD"
5340   "faddq\t%1, %2, %0"
5341   [(set_attr "type" "fp")])
5343 (define_insn "adddf3"
5344   [(set (match_operand:DF 0 "register_operand" "=e")
5345         (plus:DF (match_operand:DF 1 "register_operand" "e")
5346                  (match_operand:DF 2 "register_operand" "e")))]
5347   "TARGET_FPU"
5348   "faddd\t%1, %2, %0"
5349   [(set_attr "type" "fp")
5350    (set_attr "fptype" "double")])
5352 (define_insn "addsf3"
5353   [(set (match_operand:SF 0 "register_operand" "=f")
5354         (plus:SF (match_operand:SF 1 "register_operand" "f")
5355                  (match_operand:SF 2 "register_operand" "f")))]
5356   "TARGET_FPU"
5357   "fadds\t%1, %2, %0"
5358   [(set_attr "type" "fp")])
5360 (define_expand "subtf3"
5361   [(set (match_operand:TF 0 "nonimmediate_operand" "")
5362         (minus:TF (match_operand:TF 1 "general_operand" "")
5363                   (match_operand:TF 2 "general_operand" "")))]
5364   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5365   "emit_tfmode_binop (MINUS, operands); DONE;")
5367 (define_insn "*subtf3_hq"
5368   [(set (match_operand:TF 0 "register_operand" "=e")
5369         (minus:TF (match_operand:TF 1 "register_operand" "e")
5370                   (match_operand:TF 2 "register_operand" "e")))]
5371   "TARGET_FPU && TARGET_HARD_QUAD"
5372   "fsubq\t%1, %2, %0"
5373   [(set_attr "type" "fp")])
5375 (define_insn "subdf3"
5376   [(set (match_operand:DF 0 "register_operand" "=e")
5377         (minus:DF (match_operand:DF 1 "register_operand" "e")
5378                   (match_operand:DF 2 "register_operand" "e")))]
5379   "TARGET_FPU"
5380   "fsubd\t%1, %2, %0"
5381   [(set_attr "type" "fp")
5382    (set_attr "fptype" "double")])
5384 (define_insn "subsf3"
5385   [(set (match_operand:SF 0 "register_operand" "=f")
5386         (minus:SF (match_operand:SF 1 "register_operand" "f")
5387                   (match_operand:SF 2 "register_operand" "f")))]
5388   "TARGET_FPU"
5389   "fsubs\t%1, %2, %0"
5390   [(set_attr "type" "fp")])
5392 (define_expand "multf3"
5393   [(set (match_operand:TF 0 "nonimmediate_operand" "")
5394         (mult:TF (match_operand:TF 1 "general_operand" "")
5395                  (match_operand:TF 2 "general_operand" "")))]
5396   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5397   "emit_tfmode_binop (MULT, operands); DONE;")
5399 (define_insn "*multf3_hq"
5400   [(set (match_operand:TF 0 "register_operand" "=e")
5401         (mult:TF (match_operand:TF 1 "register_operand" "e")
5402                  (match_operand:TF 2 "register_operand" "e")))]
5403   "TARGET_FPU && TARGET_HARD_QUAD"
5404   "fmulq\t%1, %2, %0"
5405   [(set_attr "type" "fpmul")])
5407 (define_insn "muldf3"
5408   [(set (match_operand:DF 0 "register_operand" "=e")
5409         (mult:DF (match_operand:DF 1 "register_operand" "e")
5410                  (match_operand:DF 2 "register_operand" "e")))]
5411   "TARGET_FPU"
5412   "fmuld\t%1, %2, %0"
5413   [(set_attr "type" "fpmul")
5414    (set_attr "fptype" "double")])
5416 (define_insn "mulsf3"
5417   [(set (match_operand:SF 0 "register_operand" "=f")
5418         (mult:SF (match_operand:SF 1 "register_operand" "f")
5419                  (match_operand:SF 2 "register_operand" "f")))]
5420   "TARGET_FPU"
5421   "fmuls\t%1, %2, %0"
5422   [(set_attr "type" "fpmul")])
5424 (define_insn "fmadf4"
5425   [(set (match_operand:DF 0 "register_operand" "=e")
5426         (fma:DF (match_operand:DF 1 "register_operand" "e")
5427                 (match_operand:DF 2 "register_operand" "e")
5428                 (match_operand:DF 3 "register_operand" "e")))]
5429   "TARGET_FMAF"
5430   "fmaddd\t%1, %2, %3, %0"
5431   [(set_attr "type" "fpmul")])
5433 (define_insn "fmsdf4"
5434   [(set (match_operand:DF 0 "register_operand" "=e")
5435         (fma:DF (match_operand:DF 1 "register_operand" "e")
5436                 (match_operand:DF 2 "register_operand" "e")
5437                 (neg:DF (match_operand:DF 3 "register_operand" "e"))))]
5438   "TARGET_FMAF"
5439   "fmsubd\t%1, %2, %3, %0"
5440   [(set_attr "type" "fpmul")])
5442 (define_insn "*nfmadf4"
5443   [(set (match_operand:DF 0 "register_operand" "=e")
5444         (neg:DF (fma:DF (match_operand:DF 1 "register_operand" "e")
5445                         (match_operand:DF 2 "register_operand" "e")
5446                         (match_operand:DF 3 "register_operand" "e"))))]
5447   "TARGET_FMAF"
5448   "fnmaddd\t%1, %2, %3, %0"
5449   [(set_attr "type" "fpmul")])
5451 (define_insn "*nfmsdf4"
5452   [(set (match_operand:DF 0 "register_operand" "=e")
5453         (neg:DF (fma:DF (match_operand:DF 1 "register_operand" "e")
5454                         (match_operand:DF 2 "register_operand" "e")
5455                         (neg:DF (match_operand:DF 3 "register_operand" "e")))))]
5456   "TARGET_FMAF"
5457   "fnmsubd\t%1, %2, %3, %0"
5458   [(set_attr "type" "fpmul")])
5460 (define_insn "fmasf4"
5461   [(set (match_operand:SF 0 "register_operand" "=f")
5462         (fma:SF (match_operand:SF 1 "register_operand" "f")
5463                 (match_operand:SF 2 "register_operand" "f")
5464                 (match_operand:SF 3 "register_operand" "f")))]
5465   "TARGET_FMAF"
5466   "fmadds\t%1, %2, %3, %0"
5467   [(set_attr "type" "fpmul")])
5469 (define_insn "fmssf4"
5470   [(set (match_operand:SF 0 "register_operand" "=f")
5471         (fma:SF (match_operand:SF 1 "register_operand" "f")
5472                 (match_operand:SF 2 "register_operand" "f")
5473                 (neg:SF (match_operand:SF 3 "register_operand" "f"))))]
5474   "TARGET_FMAF"
5475   "fmsubs\t%1, %2, %3, %0"
5476   [(set_attr "type" "fpmul")])
5478 (define_insn "*nfmasf4"
5479   [(set (match_operand:SF 0 "register_operand" "=f")
5480         (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "f")
5481                         (match_operand:SF 2 "register_operand" "f")
5482                         (match_operand:SF 3 "register_operand" "f"))))]
5483   "TARGET_FMAF"
5484   "fnmadds\t%1, %2, %3, %0"
5485   [(set_attr "type" "fpmul")])
5487 (define_insn "*nfmssf4"
5488   [(set (match_operand:SF 0 "register_operand" "=f")
5489         (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "f")
5490                         (match_operand:SF 2 "register_operand" "f")
5491                         (neg:SF (match_operand:SF 3 "register_operand" "f")))))]
5492   "TARGET_FMAF"
5493   "fnmsubs\t%1, %2, %3, %0"
5494   [(set_attr "type" "fpmul")])
5496 (define_insn "*muldf3_extend"
5497   [(set (match_operand:DF 0 "register_operand" "=e")
5498         (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
5499                  (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
5500   "(TARGET_V8 || TARGET_V9) && TARGET_FPU && !sparc_fix_ut699"
5501   "fsmuld\t%1, %2, %0"
5502   [(set_attr "type" "fpmul")
5503    (set_attr "fptype" "double")])
5505 (define_insn "*multf3_extend"
5506   [(set (match_operand:TF 0 "register_operand" "=e")
5507         (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
5508                  (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
5509   "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
5510   "fdmulq\t%1, %2, %0"
5511   [(set_attr "type" "fpmul")])
5513 (define_expand "divtf3"
5514   [(set (match_operand:TF 0 "nonimmediate_operand" "")
5515         (div:TF (match_operand:TF 1 "general_operand" "")
5516                 (match_operand:TF 2 "general_operand" "")))]
5517   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5518   "emit_tfmode_binop (DIV, operands); DONE;")
5520 ;; don't have timing for quad-prec. divide.
5521 (define_insn "*divtf3_hq"
5522   [(set (match_operand:TF 0 "register_operand" "=e")
5523         (div:TF (match_operand:TF 1 "register_operand" "e")
5524                 (match_operand:TF 2 "register_operand" "e")))]
5525   "TARGET_FPU && TARGET_HARD_QUAD"
5526   "fdivq\t%1, %2, %0"
5527   [(set_attr "type" "fpdivs")])
5529 (define_expand "divdf3"
5530   [(set (match_operand:DF 0 "register_operand" "=e")
5531         (div:DF (match_operand:DF 1 "register_operand" "e")
5532                 (match_operand:DF 2 "register_operand" "e")))]
5533   "TARGET_FPU"
5534   "")
5536 (define_insn "*divdf3_nofix"
5537   [(set (match_operand:DF 0 "register_operand" "=e")
5538         (div:DF (match_operand:DF 1 "register_operand" "e")
5539                 (match_operand:DF 2 "register_operand" "e")))]
5540   "TARGET_FPU && !sparc_fix_ut699"
5541   "fdivd\t%1, %2, %0"
5542   [(set_attr "type" "fpdivd")
5543    (set_attr "fptype" "double")])
5545 (define_insn "*divdf3_fix"
5546   [(set (match_operand:DF 0 "register_operand" "=e")
5547         (div:DF (match_operand:DF 1 "register_operand" "e")
5548                 (match_operand:DF 2 "register_operand" "e")))]
5549   "TARGET_FPU && sparc_fix_ut699"
5550   "fdivd\t%1, %2, %0\n\tstd\t%0, [%%sp-8]"
5551   [(set_attr "type" "fpdivd")
5552    (set_attr "fptype" "double")
5553    (set_attr "length" "2")])
5555 (define_insn "divsf3"
5556   [(set (match_operand:SF 0 "register_operand" "=f")
5557         (div:SF (match_operand:SF 1 "register_operand" "f")
5558                 (match_operand:SF 2 "register_operand" "f")))]
5559   "TARGET_FPU && !sparc_fix_ut699"
5560   "fdivs\t%1, %2, %0"
5561   [(set_attr "type" "fpdivs")])
5563 (define_expand "negtf2"
5564   [(set (match_operand:TF 0 "register_operand" "")
5565         (neg:TF (match_operand:TF 1 "register_operand" "")))]
5566   "TARGET_FPU"
5567   "")
5569 (define_insn "*negtf2_hq"
5570   [(set (match_operand:TF 0 "register_operand" "=e")
5571         (neg:TF (match_operand:TF 1 "register_operand" "e")))]
5572   "TARGET_FPU && TARGET_HARD_QUAD"
5573   "fnegq\t%1, %0"
5574   [(set_attr "type" "fpmove")])
5576 (define_insn_and_split "*negtf2"
5577   [(set (match_operand:TF 0 "register_operand" "=e")
5578         (neg:TF (match_operand:TF 1 "register_operand" "e")))]
5579   "TARGET_FPU && !TARGET_HARD_QUAD"
5580   "#"
5581   "&& reload_completed"
5582   [(clobber (const_int 0))]
5584   rtx set_dest = operands[0];
5585   rtx set_src = operands[1];
5586   rtx dest1, dest2;
5587   rtx src1, src2;
5589   dest1 = gen_df_reg (set_dest, 0);
5590   dest2 = gen_df_reg (set_dest, 1);
5591   src1 = gen_df_reg (set_src, 0);
5592   src2 = gen_df_reg (set_src, 1);
5594   /* Now emit using the real source and destination we found, swapping
5595      the order if we detect overlap.  */
5596   if (reg_overlap_mentioned_p (dest1, src2))
5597     {
5598       emit_insn (gen_movdf (dest2, src2));
5599       emit_insn (gen_negdf2 (dest1, src1));
5600     }
5601   else
5602     {
5603       emit_insn (gen_negdf2 (dest1, src1));
5604       if (REGNO (dest2) != REGNO (src2))
5605         emit_insn (gen_movdf (dest2, src2));
5606     }
5607   DONE;
5609   [(set_attr "length" "2")])
5611 (define_expand "negdf2"
5612   [(set (match_operand:DF 0 "register_operand" "")
5613         (neg:DF (match_operand:DF 1 "register_operand" "")))]
5614   "TARGET_FPU"
5615   "")
5617 (define_insn_and_split "*negdf2_notv9"
5618   [(set (match_operand:DF 0 "register_operand" "=e")
5619         (neg:DF (match_operand:DF 1 "register_operand" "e")))]
5620   "TARGET_FPU && !TARGET_V9"
5621   "#"
5622   "&& reload_completed"
5623   [(clobber (const_int 0))]
5625   rtx set_dest = operands[0];
5626   rtx set_src = operands[1];
5627   rtx dest1, dest2;
5628   rtx src1, src2;
5630   dest1 = gen_highpart (SFmode, set_dest);
5631   dest2 = gen_lowpart (SFmode, set_dest);
5632   src1 = gen_highpart (SFmode, set_src);
5633   src2 = gen_lowpart (SFmode, set_src);
5635   /* Now emit using the real source and destination we found, swapping
5636      the order if we detect overlap.  */
5637   if (reg_overlap_mentioned_p (dest1, src2))
5638     {
5639       emit_insn (gen_movsf (dest2, src2));
5640       emit_insn (gen_negsf2 (dest1, src1));
5641     }
5642   else
5643     {
5644       emit_insn (gen_negsf2 (dest1, src1));
5645       if (REGNO (dest2) != REGNO (src2))
5646         emit_insn (gen_movsf (dest2, src2));
5647     }
5648   DONE;
5650   [(set_attr "length" "2")])
5652 (define_insn "*negdf2_v9"
5653   [(set (match_operand:DF 0 "register_operand" "=e")
5654         (neg:DF (match_operand:DF 1 "register_operand" "e")))]
5655   "TARGET_FPU && TARGET_V9"
5656   "fnegd\t%1, %0"
5657   [(set_attr "type" "fpmove")
5658    (set_attr "fptype" "double")])
5660 (define_insn "negsf2"
5661   [(set (match_operand:SF 0 "register_operand" "=f")
5662         (neg:SF (match_operand:SF 1 "register_operand" "f")))]
5663   "TARGET_FPU"
5664   "fnegs\t%1, %0"
5665   [(set_attr "type" "fpmove")])
5667 (define_expand "abstf2"
5668   [(set (match_operand:TF 0 "register_operand" "")
5669         (abs:TF (match_operand:TF 1 "register_operand" "")))]
5670   "TARGET_FPU"
5671   "")
5673 (define_insn "*abstf2_hq"
5674   [(set (match_operand:TF 0 "register_operand" "=e")
5675         (abs:TF (match_operand:TF 1 "register_operand" "e")))]
5676   "TARGET_FPU && TARGET_HARD_QUAD"
5677   "fabsq\t%1, %0"
5678   [(set_attr "type" "fpmove")])
5680 (define_insn_and_split "*abstf2"
5681   [(set (match_operand:TF 0 "register_operand" "=e")
5682         (abs:TF (match_operand:TF 1 "register_operand" "e")))]
5683   "TARGET_FPU && !TARGET_HARD_QUAD"
5684   "#"
5685   "&& reload_completed"
5686   [(clobber (const_int 0))]
5688   rtx set_dest = operands[0];
5689   rtx set_src = operands[1];
5690   rtx dest1, dest2;
5691   rtx src1, src2;
5693   dest1 = gen_df_reg (set_dest, 0);
5694   dest2 = gen_df_reg (set_dest, 1);
5695   src1 = gen_df_reg (set_src, 0);
5696   src2 = gen_df_reg (set_src, 1);
5698   /* Now emit using the real source and destination we found, swapping
5699      the order if we detect overlap.  */
5700   if (reg_overlap_mentioned_p (dest1, src2))
5701     {
5702       emit_insn (gen_movdf (dest2, src2));
5703       emit_insn (gen_absdf2 (dest1, src1));
5704     }
5705   else
5706     {
5707       emit_insn (gen_absdf2 (dest1, src1));
5708       if (REGNO (dest2) != REGNO (src2))
5709         emit_insn (gen_movdf (dest2, src2));
5710     }
5711   DONE;
5713   [(set_attr "length" "2")])
5715 (define_expand "absdf2"
5716   [(set (match_operand:DF 0 "register_operand" "")
5717         (abs:DF (match_operand:DF 1 "register_operand" "")))]
5718   "TARGET_FPU"
5719   "")
5721 (define_insn_and_split "*absdf2_notv9"
5722   [(set (match_operand:DF 0 "register_operand" "=e")
5723         (abs:DF (match_operand:DF 1 "register_operand" "e")))]
5724   "TARGET_FPU && !TARGET_V9"
5725   "#"
5726   "&& reload_completed"
5727   [(clobber (const_int 0))]
5729   rtx set_dest = operands[0];
5730   rtx set_src = operands[1];
5731   rtx dest1, dest2;
5732   rtx src1, src2;
5734   dest1 = gen_highpart (SFmode, set_dest);
5735   dest2 = gen_lowpart (SFmode, set_dest);
5736   src1 = gen_highpart (SFmode, set_src);
5737   src2 = gen_lowpart (SFmode, set_src);
5739   /* Now emit using the real source and destination we found, swapping
5740      the order if we detect overlap.  */
5741   if (reg_overlap_mentioned_p (dest1, src2))
5742     {
5743       emit_insn (gen_movsf (dest2, src2));
5744       emit_insn (gen_abssf2 (dest1, src1));
5745     }
5746   else
5747     {
5748       emit_insn (gen_abssf2 (dest1, src1));
5749       if (REGNO (dest2) != REGNO (src2))
5750         emit_insn (gen_movsf (dest2, src2));
5751     }
5752   DONE;
5754   [(set_attr "length" "2")])
5756 (define_insn "*absdf2_v9"
5757   [(set (match_operand:DF 0 "register_operand" "=e")
5758         (abs:DF (match_operand:DF 1 "register_operand" "e")))]
5759   "TARGET_FPU && TARGET_V9"
5760   "fabsd\t%1, %0"
5761   [(set_attr "type" "fpmove")
5762    (set_attr "fptype" "double")])
5764 (define_insn "abssf2"
5765   [(set (match_operand:SF 0 "register_operand" "=f")
5766         (abs:SF (match_operand:SF 1 "register_operand" "f")))]
5767   "TARGET_FPU"
5768   "fabss\t%1, %0"
5769   [(set_attr "type" "fpmove")])
5771 (define_expand "sqrttf2"
5772   [(set (match_operand:TF 0 "nonimmediate_operand" "")
5773         (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
5774   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5775   "emit_tfmode_unop (SQRT, operands); DONE;")
5777 (define_insn "*sqrttf2_hq"
5778   [(set (match_operand:TF 0 "register_operand" "=e")
5779         (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
5780   "TARGET_FPU && TARGET_HARD_QUAD"
5781   "fsqrtq\t%1, %0"
5782   [(set_attr "type" "fpsqrts")])
5784 (define_expand "sqrtdf2"
5785   [(set (match_operand:DF 0 "register_operand" "=e")
5786         (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
5787   "TARGET_FPU"
5788   "")
5790 (define_insn "*sqrtdf2_nofix"
5791   [(set (match_operand:DF 0 "register_operand" "=e")
5792         (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
5793   "TARGET_FPU && !sparc_fix_ut699"
5794   "fsqrtd\t%1, %0"
5795   [(set_attr "type" "fpsqrtd")
5796    (set_attr "fptype" "double")])
5798 (define_insn "*sqrtdf2_fix"
5799   [(set (match_operand:DF 0 "register_operand" "=e")
5800         (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
5801   "TARGET_FPU && sparc_fix_ut699"
5802   "fsqrtd\t%1, %0\n\tstd\t%0, [%%sp-8]"
5803   [(set_attr "type" "fpsqrtd")
5804    (set_attr "fptype" "double")
5805    (set_attr "length" "2")])
5807 (define_insn "sqrtsf2"
5808   [(set (match_operand:SF 0 "register_operand" "=f")
5809         (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
5810   "TARGET_FPU && !sparc_fix_ut699"
5811   "fsqrts\t%1, %0"
5812   [(set_attr "type" "fpsqrts")])
5815 ;; Arithmetic shift instructions.
5817 (define_insn "ashlsi3"
5818   [(set (match_operand:SI 0 "register_operand" "=r")
5819         (ashift:SI (match_operand:SI 1 "register_operand" "r")
5820                    (match_operand:SI 2 "arith_operand" "rI")))]
5821   ""
5823   if (GET_CODE (operands[2]) == CONST_INT)
5824     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5825   return "sll\t%1, %2, %0";
5827   [(set_attr "type" "shift")])
5829 (define_expand "ashldi3"
5830   [(set (match_operand:DI 0 "register_operand" "=r")
5831         (ashift:DI (match_operand:DI 1 "register_operand" "r")
5832                    (match_operand:SI 2 "arith_operand" "rI")))]
5833   "TARGET_ARCH64 || TARGET_V8PLUS"
5835   if (! TARGET_ARCH64)
5836     {
5837       if (GET_CODE (operands[2]) == CONST_INT)
5838         FAIL;
5839       emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
5840       DONE;
5841     }
5844 (define_insn "*ashldi3_sp64"
5845   [(set (match_operand:DI 0 "register_operand" "=r")
5846         (ashift:DI (match_operand:DI 1 "register_operand" "r")
5847                    (match_operand:SI 2 "arith_operand" "rI")))]
5848   "TARGET_ARCH64"
5850   if (GET_CODE (operands[2]) == CONST_INT)
5851     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5852   return "sllx\t%1, %2, %0";
5854   [(set_attr "type" "shift")])
5856 ;; XXX UGH!
5857 (define_insn "ashldi3_v8plus"
5858   [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5859         (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5860                    (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5861    (clobber (match_scratch:SI 3 "=X,X,&h"))]
5862   "TARGET_V8PLUS"
5863   "* return output_v8plus_shift (insn ,operands, \"sllx\");"
5864   [(set_attr "type" "multi")
5865    (set_attr "length" "5,5,6")])
5867 ;; Optimize (1LL<<x)-1
5868 ;; XXX this also needs to be fixed to handle equal subregs
5869 ;; XXX first before we could re-enable it.
5870 ;(define_insn ""
5871 ;  [(set (match_operand:DI 0 "register_operand" "=h")
5872 ;       (plus:DI (ashift:DI (const_int 1)
5873 ;                           (match_operand:SI 1 "arith_operand" "rI"))
5874 ;                (const_int -1)))]
5875 ;  "0 && TARGET_V8PLUS"
5877 ;  if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
5878 ;    return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5879 ;  return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5881 ;  [(set_attr "type" "multi")
5882 ;   (set_attr "length" "4")])
5884 (define_insn "*cmp_cc_ashift_1"
5885   [(set (reg:CC_NOOV CC_REG)
5886         (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
5887                                     (const_int 1))
5888                          (const_int 0)))]
5889   ""
5890   "addcc\t%0, %0, %%g0"
5891   [(set_attr "type" "compare")])
5893 (define_insn "*cmp_cc_set_ashift_1"
5894   [(set (reg:CC_NOOV CC_REG)
5895         (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
5896                                     (const_int 1))
5897                          (const_int 0)))
5898    (set (match_operand:SI 0 "register_operand" "=r")
5899         (ashift:SI (match_dup 1) (const_int 1)))]
5900   ""
5901   "addcc\t%1, %1, %0"
5902   [(set_attr "type" "compare")])
5904 (define_insn "ashrsi3"
5905   [(set (match_operand:SI 0 "register_operand" "=r")
5906         (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5907                      (match_operand:SI 2 "arith_operand" "rI")))]
5908   ""
5909   {
5910      if (GET_CODE (operands[2]) == CONST_INT)
5911        operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5912      return "sra\t%1, %2, %0";
5913   }
5914   [(set_attr "type" "shift")])
5916 (define_insn "*ashrsi3_extend"
5917   [(set (match_operand:DI 0 "register_operand" "=r")
5918         (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5919                                      (match_operand:SI 2 "arith_operand" "r"))))]
5920   "TARGET_ARCH64"
5921   "sra\t%1, %2, %0"
5922   [(set_attr "type" "shift")])
5924 ;; This handles the case as above, but with constant shift instead of
5925 ;; register. Combiner "simplifies" it for us a little bit though.
5926 (define_insn "*ashrsi3_extend2"
5927   [(set (match_operand:DI 0 "register_operand" "=r")
5928         (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
5929                                 (const_int 32))
5930                      (match_operand:SI 2 "small_int_operand" "I")))]
5931   "TARGET_ARCH64 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64"
5933   operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
5934   return "sra\t%1, %2, %0";
5936   [(set_attr "type" "shift")])
5938 (define_expand "ashrdi3"
5939   [(set (match_operand:DI 0 "register_operand" "=r")
5940         (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5941                      (match_operand:SI 2 "arith_operand" "rI")))]
5942   "TARGET_ARCH64 || TARGET_V8PLUS"
5944   if (! TARGET_ARCH64)
5945     {
5946       if (GET_CODE (operands[2]) == CONST_INT)
5947         FAIL;   /* prefer generic code in this case */
5948       emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
5949       DONE;
5950     }
5953 (define_insn "*ashrdi3_sp64"
5954   [(set (match_operand:DI 0 "register_operand" "=r")
5955         (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5956                      (match_operand:SI 2 "arith_operand" "rI")))]
5957   "TARGET_ARCH64"
5958   
5959   {
5960     if (GET_CODE (operands[2]) == CONST_INT)
5961       operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5962     return "srax\t%1, %2, %0";
5963   }
5964   [(set_attr "type" "shift")])
5966 ;; XXX
5967 (define_insn "ashrdi3_v8plus"
5968   [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5969         (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5970                      (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5971    (clobber (match_scratch:SI 3 "=X,X,&h"))]
5972   "TARGET_V8PLUS"
5973   "* return output_v8plus_shift (insn, operands, \"srax\");"
5974   [(set_attr "type" "multi")
5975    (set_attr "length" "5,5,6")])
5977 (define_insn "lshrsi3"
5978   [(set (match_operand:SI 0 "register_operand" "=r")
5979         (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5980                      (match_operand:SI 2 "arith_operand" "rI")))]
5981   ""
5982   {
5983     if (GET_CODE (operands[2]) == CONST_INT)
5984       operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5985     return "srl\t%1, %2, %0";
5986   }
5987   [(set_attr "type" "shift")])
5989 (define_insn "*lshrsi3_extend0"
5990   [(set (match_operand:DI 0 "register_operand" "=r")
5991         (zero_extend:DI
5992           (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5993                        (match_operand:SI 2 "arith_operand" "rI"))))]
5994   "TARGET_ARCH64"
5995   {
5996     if (GET_CODE (operands[2]) == CONST_INT)
5997       operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5998     return "srl\t%1, %2, %0";
5999   }
6000   [(set_attr "type" "shift")])
6002 ;; This handles the case where
6003 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
6004 ;; but combiner "simplifies" it for us.
6005 (define_insn "*lshrsi3_extend1"
6006   [(set (match_operand:DI 0 "register_operand" "=r")
6007         (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
6008                            (match_operand:SI 2 "arith_operand" "r")) 0)
6009                 (match_operand 3 "const_int_operand" "")))]
6010   "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff"
6011   "srl\t%1, %2, %0"
6012   [(set_attr "type" "shift")])
6014 ;; This handles the case where
6015 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
6016 ;; but combiner "simplifies" it for us.
6017 (define_insn "*lshrsi3_extend2"
6018   [(set (match_operand:DI 0 "register_operand" "=r")
6019         (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
6020                          (match_operand 2 "small_int_operand" "I")
6021                          (const_int 32)))]
6022   "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6024   operands[2] = GEN_INT (32 - INTVAL (operands[2]));
6025   return "srl\t%1, %2, %0";
6027   [(set_attr "type" "shift")])
6029 (define_expand "lshrdi3"
6030   [(set (match_operand:DI 0 "register_operand" "=r")
6031         (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6032                      (match_operand:SI 2 "arith_operand" "rI")))]
6033   "TARGET_ARCH64 || TARGET_V8PLUS"
6035   if (! TARGET_ARCH64)
6036     {
6037       if (GET_CODE (operands[2]) == CONST_INT)
6038         FAIL;
6039       emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
6040       DONE;
6041     }
6044 (define_insn "*lshrdi3_sp64"
6045   [(set (match_operand:DI 0 "register_operand" "=r")
6046         (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6047                      (match_operand:SI 2 "arith_operand" "rI")))]
6048   "TARGET_ARCH64"
6049   {
6050     if (GET_CODE (operands[2]) == CONST_INT)
6051       operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6052     return "srlx\t%1, %2, %0";
6053   }
6054   [(set_attr "type" "shift")])
6056 ;; XXX
6057 (define_insn "lshrdi3_v8plus"
6058   [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6059         (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6060                      (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6061    (clobber (match_scratch:SI 3 "=X,X,&h"))]
6062   "TARGET_V8PLUS"
6063   "* return output_v8plus_shift (insn, operands, \"srlx\");"
6064   [(set_attr "type" "multi")
6065    (set_attr "length" "5,5,6")])
6067 (define_insn ""
6068   [(set (match_operand:SI 0 "register_operand" "=r")
6069         (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6070                                              (const_int 32)) 4)
6071                      (match_operand:SI 2 "small_int_operand" "I")))]
6072   "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6074   operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6075   return "srax\t%1, %2, %0";
6077   [(set_attr "type" "shift")])
6079 (define_insn ""
6080   [(set (match_operand:SI 0 "register_operand" "=r")
6081         (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6082                                              (const_int 32)) 4)
6083                      (match_operand:SI 2 "small_int_operand" "I")))]
6084   "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6086   operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6087   return "srlx\t%1, %2, %0";
6089   [(set_attr "type" "shift")])
6091 (define_insn ""
6092   [(set (match_operand:SI 0 "register_operand" "=r")
6093         (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6094                                              (match_operand:SI 2 "small_int_operand" "I")) 4)
6095                      (match_operand:SI 3 "small_int_operand" "I")))]
6096   "TARGET_ARCH64
6097    && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6098    && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6099    && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6101   operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6103   return "srax\t%1, %2, %0";
6105   [(set_attr "type" "shift")])
6107 (define_insn ""
6108   [(set (match_operand:SI 0 "register_operand" "=r")
6109         (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6110                                              (match_operand:SI 2 "small_int_operand" "I")) 4)
6111                      (match_operand:SI 3 "small_int_operand" "I")))]
6112   "TARGET_ARCH64
6113    && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6114    && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6115    && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6117   operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6119   return "srlx\t%1, %2, %0";
6121   [(set_attr "type" "shift")])
6124 ;; Unconditional and other jump instructions.
6126 (define_expand "jump"
6127   [(set (pc) (label_ref (match_operand 0 "" "")))]
6128   "")
6130 (define_insn "*jump_ubranch"
6131   [(set (pc) (label_ref (match_operand 0 "" "")))]
6132   "! TARGET_CBCOND"
6133   "* return output_ubranch (operands[0], insn);"
6134   [(set_attr "type" "uncond_branch")])
6136 (define_insn "*jump_cbcond"
6137   [(set (pc) (label_ref (match_operand 0 "" "")))]
6138   "TARGET_CBCOND"
6139   "* return output_ubranch (operands[0], insn);"
6140   [(set_attr "type" "uncond_cbcond")])
6142 (define_expand "tablejump"
6143   [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
6144               (use (label_ref (match_operand 1 "" "")))])]
6145   ""
6147   gcc_assert (GET_MODE (operands[0]) == CASE_VECTOR_MODE);
6149   /* In pic mode, our address differences are against the base of the
6150      table.  Add that base value back in; CSE ought to be able to combine
6151      the two address loads.  */
6152   if (flag_pic)
6153     {
6154       rtx tmp, tmp2;
6155       tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
6156       tmp2 = operands[0];
6157       if (CASE_VECTOR_MODE != Pmode)
6158         tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
6159       tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
6160       operands[0] = memory_address (Pmode, tmp);
6161     }
6164 (define_insn "*tablejump_sp32"
6165   [(set (pc) (match_operand:SI 0 "address_operand" "p"))
6166    (use (label_ref (match_operand 1 "" "")))]
6167   "! TARGET_ARCH64"
6168   "jmp\t%a0%#"
6169   [(set_attr "type" "uncond_branch")])
6171 (define_insn "*tablejump_sp64"
6172   [(set (pc) (match_operand:DI 0 "address_operand" "p"))
6173    (use (label_ref (match_operand 1 "" "")))]
6174   "TARGET_ARCH64"
6175   "jmp\t%a0%#"
6176   [(set_attr "type" "uncond_branch")])
6179 ;; Jump to subroutine instructions.
6181 (define_expand "call"
6182   ;; Note that this expression is not used for generating RTL.
6183   ;; All the RTL is generated explicitly below.
6184   [(call (match_operand 0 "call_operand" "")
6185          (match_operand 3 "" "i"))]
6186   ;; operands[2] is next_arg_register
6187   ;; operands[3] is struct_value_size_rtx.
6188   ""
6190   rtx fn_rtx;
6192   gcc_assert (MEM_P (operands[0]) && GET_MODE (operands[0]) == FUNCTION_MODE);
6194   gcc_assert (GET_CODE (operands[3]) == CONST_INT);
6196   if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
6197     {
6198       /* This is really a PIC sequence.  We want to represent
6199          it as a funny jump so its delay slots can be filled. 
6201          ??? But if this really *is* a CALL, will not it clobber the
6202          call-clobbered registers?  We lose this if it is a JUMP_INSN.
6203          Why cannot we have delay slots filled if it were a CALL?  */
6205       /* We accept negative sizes for untyped calls.  */
6206       if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6207         emit_jump_insn
6208           (gen_rtx_PARALLEL
6209            (VOIDmode,
6210             gen_rtvec (3,
6211                        gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6212                        operands[3],
6213                        gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6214       else
6215         emit_jump_insn
6216           (gen_rtx_PARALLEL
6217            (VOIDmode,
6218             gen_rtvec (2,
6219                        gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6220                        gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6221       goto finish_call;
6222     }
6224   fn_rtx = operands[0];
6226   /* We accept negative sizes for untyped calls.  */
6227   if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6228     sparc_emit_call_insn
6229       (gen_rtx_PARALLEL
6230        (VOIDmode,
6231         gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6232                    operands[3],
6233                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6234        XEXP (fn_rtx, 0));
6235   else
6236     sparc_emit_call_insn
6237       (gen_rtx_PARALLEL
6238        (VOIDmode,
6239         gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6240                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6241        XEXP (fn_rtx, 0));
6243  finish_call:
6245   DONE;
6248 ;; We can't use the same pattern for these two insns, because then registers
6249 ;; in the address may not be properly reloaded.
6251 (define_insn "*call_address_sp32"
6252   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6253          (match_operand 1 "" ""))
6254    (clobber (reg:SI O7_REG))]
6255   ;;- Do not use operand 1 for most machines.
6256   "! TARGET_ARCH64"
6257   "call\t%a0, %1%#"
6258   [(set_attr "type" "call")])
6260 (define_insn "*call_symbolic_sp32"
6261   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6262          (match_operand 1 "" ""))
6263    (clobber (reg:SI O7_REG))]
6264   ;;- Do not use operand 1 for most machines.
6265   "! TARGET_ARCH64"
6266   "call\t%a0, %1%#"
6267   [(set_attr "type" "call")])
6269 (define_insn "*call_address_sp64"
6270   [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
6271          (match_operand 1 "" ""))
6272    (clobber (reg:DI O7_REG))]
6273   ;;- Do not use operand 1 for most machines.
6274   "TARGET_ARCH64"
6275   "call\t%a0, %1%#"
6276   [(set_attr "type" "call")])
6278 (define_insn "*call_symbolic_sp64"
6279   [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6280          (match_operand 1 "" ""))
6281    (clobber (reg:DI O7_REG))]
6282   ;;- Do not use operand 1 for most machines.
6283   "TARGET_ARCH64"
6284   "call\t%a0, %1%#"
6285   [(set_attr "type" "call")])
6287 ;; This is a call that wants a structure value.
6288 ;; There is no such critter for v9 (??? we may need one anyway).
6289 (define_insn "*call_address_struct_value_sp32"
6290   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6291          (match_operand 1 "" ""))
6292    (match_operand 2 "immediate_operand" "")
6293    (clobber (reg:SI O7_REG))]
6294   ;;- Do not use operand 1 for most machines.
6295   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6297   operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6298   return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6300   [(set_attr "type" "call_no_delay_slot")
6301    (set_attr "length" "3")])
6303 ;; This is a call that wants a structure value.
6304 ;; There is no such critter for v9 (??? we may need one anyway).
6305 (define_insn "*call_symbolic_struct_value_sp32"
6306   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6307          (match_operand 1 "" ""))
6308    (match_operand 2 "immediate_operand" "")
6309    (clobber (reg:SI O7_REG))]
6310   ;;- Do not use operand 1 for most machines.
6311   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6313   operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6314   return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6316   [(set_attr "type" "call_no_delay_slot")
6317    (set_attr "length" "3")])
6319 ;; This is a call that may want a structure value.  This is used for
6320 ;; untyped_calls.
6321 (define_insn "*call_address_untyped_struct_value_sp32"
6322   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6323          (match_operand 1 "" ""))
6324    (match_operand 2 "immediate_operand" "")
6325    (clobber (reg:SI O7_REG))]
6326   ;;- Do not use operand 1 for most machines.
6327   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6328   "call\t%a0, %1\n\t nop\n\tnop"
6329   [(set_attr "type" "call_no_delay_slot")
6330    (set_attr "length" "3")])
6332 ;; This is a call that may want a structure value.  This is used for
6333 ;; untyped_calls.
6334 (define_insn "*call_symbolic_untyped_struct_value_sp32"
6335   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6336          (match_operand 1 "" ""))
6337    (match_operand 2 "immediate_operand" "")
6338    (clobber (reg:SI O7_REG))]
6339   ;;- Do not use operand 1 for most machines.
6340   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6341   "call\t%a0, %1\n\t nop\n\tnop"
6342   [(set_attr "type" "call_no_delay_slot")
6343    (set_attr "length" "3")])
6345 (define_expand "call_value"
6346   ;; Note that this expression is not used for generating RTL.
6347   ;; All the RTL is generated explicitly below.
6348   [(set (match_operand 0 "register_operand" "=rf")
6349         (call (match_operand 1 "" "")
6350               (match_operand 4 "" "")))]
6351   ;; operand 2 is stack_size_rtx
6352   ;; operand 3 is next_arg_register
6353   ""
6355   rtx fn_rtx;
6356   rtvec vec;
6358   gcc_assert (MEM_P (operands[1]) && GET_MODE (operands[1]) == FUNCTION_MODE);
6360   fn_rtx = operands[1];
6362   vec = gen_rtvec (2,
6363                    gen_rtx_SET (VOIDmode, operands[0],
6364                                 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
6365                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
6367   sparc_emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec), XEXP (fn_rtx, 0));
6369   DONE;
6372 (define_insn "*call_value_address_sp32"
6373   [(set (match_operand 0 "" "=rf")
6374         (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
6375               (match_operand 2 "" "")))
6376    (clobber (reg:SI O7_REG))]
6377   ;;- Do not use operand 2 for most machines.
6378   "! TARGET_ARCH64"
6379   "call\t%a1, %2%#"
6380   [(set_attr "type" "call")])
6382 (define_insn "*call_value_symbolic_sp32"
6383   [(set (match_operand 0 "" "=rf")
6384         (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6385               (match_operand 2 "" "")))
6386    (clobber (reg:SI O7_REG))]
6387   ;;- Do not use operand 2 for most machines.
6388   "! TARGET_ARCH64"
6389   "call\t%a1, %2%#"
6390   [(set_attr "type" "call")])
6392 (define_insn "*call_value_address_sp64"
6393   [(set (match_operand 0 "" "")
6394         (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
6395               (match_operand 2 "" "")))
6396    (clobber (reg:DI O7_REG))]
6397   ;;- Do not use operand 2 for most machines.
6398   "TARGET_ARCH64"
6399   "call\t%a1, %2%#"
6400   [(set_attr "type" "call")])
6402 (define_insn "*call_value_symbolic_sp64"
6403   [(set (match_operand 0 "" "")
6404         (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6405               (match_operand 2 "" "")))
6406    (clobber (reg:DI O7_REG))]
6407   ;;- Do not use operand 2 for most machines.
6408   "TARGET_ARCH64"
6409   "call\t%a1, %2%#"
6410   [(set_attr "type" "call")])
6412 (define_expand "untyped_call"
6413   [(parallel [(call (match_operand 0 "" "")
6414                     (const_int 0))
6415               (match_operand:BLK 1 "memory_operand" "")
6416               (match_operand 2 "" "")])]
6417   ""
6419   rtx valreg1 = gen_rtx_REG (DImode, 8);
6420   rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6421   rtx result = operands[1];
6423   /* Pass constm1 to indicate that it may expect a structure value, but
6424      we don't know what size it is.  */
6425   emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
6427   /* Save the function value registers.  */
6428   emit_move_insn (adjust_address (result, DImode, 0), valreg1);
6429   emit_move_insn (adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8),
6430                                   valreg2);
6432   /* The optimizer does not know that the call sets the function value
6433      registers we stored in the result block.  We avoid problems by
6434      claiming that all hard registers are used and clobbered at this
6435      point.  */
6436   emit_insn (gen_blockage ());
6438   DONE;
6441 ;;  Tail call instructions.
6443 (define_expand "sibcall"
6444   [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
6445               (return)])]
6446   ""
6447   "")
6449 (define_insn "*sibcall_symbolic_sp32"
6450   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6451          (match_operand 1 "" ""))
6452    (return)]
6453   "! TARGET_ARCH64"
6454   "* return output_sibcall(insn, operands[0]);"
6455   [(set_attr "type" "sibcall")])
6457 (define_insn "*sibcall_symbolic_sp64"
6458   [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6459          (match_operand 1 "" ""))
6460    (return)]
6461   "TARGET_ARCH64"
6462   "* return output_sibcall(insn, operands[0]);"
6463   [(set_attr "type" "sibcall")])
6465 (define_expand "sibcall_value"
6466   [(parallel [(set (match_operand 0 "register_operand" "=rf")
6467                 (call (match_operand 1 "" "") (const_int 0)))
6468               (return)])]
6469   ""
6470   "")
6472 (define_insn "*sibcall_value_symbolic_sp32"
6473   [(set (match_operand 0 "" "=rf")
6474         (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6475               (match_operand 2 "" "")))
6476    (return)]
6477   "! TARGET_ARCH64"
6478   "* return output_sibcall(insn, operands[1]);"
6479   [(set_attr "type" "sibcall")])
6481 (define_insn "*sibcall_value_symbolic_sp64"
6482   [(set (match_operand 0 "" "")
6483         (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6484               (match_operand 2 "" "")))
6485    (return)]
6486   "TARGET_ARCH64"
6487   "* return output_sibcall(insn, operands[1]);"
6488   [(set_attr "type" "sibcall")])
6491 ;; Special instructions.
6493 (define_expand "prologue"
6494   [(const_int 0)]
6495   ""
6497   if (TARGET_FLAT)
6498     sparc_flat_expand_prologue ();
6499   else
6500     sparc_expand_prologue ();
6501   DONE;
6504 ;; The "register window save" insn is modelled as follows.  The dwarf2
6505 ;; information is manually added in emit_window_save.
6507 (define_insn "window_save"
6508   [(unspec_volatile
6509         [(match_operand 0 "arith_operand" "rI")]
6510         UNSPECV_SAVEW)]
6511   "!TARGET_FLAT"
6512   "save\t%%sp, %0, %%sp"
6513   [(set_attr "type" "savew")])
6515 (define_expand "epilogue"
6516   [(return)]
6517   ""
6519   if (TARGET_FLAT)
6520     sparc_flat_expand_epilogue (false);
6521   else
6522     sparc_expand_epilogue (false);
6525 (define_expand "sibcall_epilogue"
6526   [(return)]
6527   ""
6529   if (TARGET_FLAT)
6530     sparc_flat_expand_epilogue (false);
6531   else
6532     sparc_expand_epilogue (false);
6533   DONE;
6536 (define_expand "eh_return"
6537   [(use (match_operand 0 "general_operand" ""))]
6538   ""
6540   emit_move_insn (gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM), operands[0]);
6541   emit_jump_insn (gen_eh_return_internal ());
6542   emit_barrier ();
6543   DONE;
6546 (define_insn_and_split "eh_return_internal"
6547   [(eh_return)]
6548   ""
6549   "#"
6550   "epilogue_completed"
6551   [(return)]
6553   if (TARGET_FLAT)
6554     sparc_flat_expand_epilogue (true);
6555   else
6556     sparc_expand_epilogue (true);
6559 (define_expand "return"
6560   [(return)]
6561   "sparc_can_use_return_insn_p ()"
6562   "")
6564 (define_insn "*return_internal"
6565   [(return)]
6566   ""
6567   "* return output_return (insn);"
6568   [(set_attr "type" "return")
6569    (set (attr "length")
6570         (cond [(eq_attr "calls_eh_return" "true")
6571                  (if_then_else (eq_attr "delayed_branch" "true")
6572                                 (if_then_else (ior (eq_attr "isa" "v9")
6573                                                    (eq_attr "flat" "true"))
6574                                         (const_int 2)
6575                                         (const_int 3))
6576                                 (if_then_else (eq_attr "flat" "true")
6577                                         (const_int 3)
6578                                         (const_int 4)))
6579                (ior (eq_attr "leaf_function" "true") (eq_attr "flat" "true"))
6580                  (if_then_else (eq_attr "empty_delay_slot" "true")
6581                                (const_int 2)
6582                                (const_int 1))
6583                (eq_attr "empty_delay_slot" "true")
6584                  (if_then_else (eq_attr "delayed_branch" "true")
6585                                (const_int 2)
6586                                (const_int 3))
6587               ] (const_int 1)))])
6589 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
6590 ;; all of memory.  This blocks insns from being moved across this point.
6592 (define_insn "blockage"
6593   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
6594   ""
6595   ""
6596   [(set_attr "length" "0")])
6598 ;; Do not schedule instructions accessing memory before this point.
6600 (define_expand "frame_blockage"
6601   [(set (match_dup 0)
6602         (unspec:BLK [(match_dup 1)] UNSPEC_FRAME_BLOCKAGE))]
6603   ""
6605   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
6606   MEM_VOLATILE_P (operands[0]) = 1;
6607   operands[1] = stack_pointer_rtx;
6610 (define_insn "*frame_blockage<P:mode>"
6611   [(set (match_operand:BLK 0 "" "")
6612         (unspec:BLK [(match_operand:P 1 "" "")] UNSPEC_FRAME_BLOCKAGE))]
6613   ""
6614   ""
6615   [(set_attr "length" "0")])
6617 (define_expand "probe_stack"
6618   [(set (match_operand 0 "memory_operand" "") (const_int 0))]
6619   ""
6621   operands[0]
6622     = adjust_address (operands[0], GET_MODE (operands[0]), SPARC_STACK_BIAS);
6625 (define_insn "probe_stack_range<P:mode>"
6626   [(set (match_operand:P 0 "register_operand" "=r")
6627         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
6628                             (match_operand:P 2 "register_operand" "r")]
6629                             UNSPECV_PROBE_STACK_RANGE))]
6630   ""
6631   "* return output_probe_stack_range (operands[0], operands[2]);"
6632   [(set_attr "type" "multi")])
6634 ;; Prepare to return any type including a structure value.
6636 (define_expand "untyped_return"
6637   [(match_operand:BLK 0 "memory_operand" "")
6638    (match_operand 1 "" "")]
6639   ""
6641   rtx valreg1 = gen_rtx_REG (DImode, 24);
6642   rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6643   rtx result = operands[0];
6645   if (! TARGET_ARCH64)
6646     {
6647       rtx rtnreg = gen_rtx_REG (SImode, RETURN_ADDR_REGNUM);
6648       rtx value = gen_reg_rtx (SImode);
6650       /* Fetch the instruction where we will return to and see if it's an unimp
6651          instruction (the most significant 10 bits will be zero).  If so,
6652          update the return address to skip the unimp instruction.  */
6653       emit_move_insn (value,
6654                       gen_rtx_MEM (SImode, plus_constant (SImode, rtnreg, 8)));
6655       emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
6656       emit_insn (gen_update_return (rtnreg, value));
6657     }
6659   /* Reload the function value registers.  */
6660   emit_move_insn (valreg1, adjust_address (result, DImode, 0));
6661   emit_move_insn (valreg2,
6662                   adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
6664   /* Put USE insns before the return.  */
6665   emit_use (valreg1);
6666   emit_use (valreg2);
6668   /* Construct the return.  */
6669   expand_naked_return ();
6671   DONE;
6674 ;; Adjust the return address conditionally. If the value of op1 is equal
6675 ;; to all zero then adjust the return address i.e. op0 = op0 + 4.
6676 ;; This is technically *half* the check required by the 32-bit SPARC
6677 ;; psABI. This check only ensures that an "unimp" insn was written by
6678 ;; the caller, but doesn't check to see if the expected size matches
6679 ;; (this is encoded in the 12 lower bits). This check is obsolete and
6680 ;; only used by the above code "untyped_return".
6682 (define_insn "update_return"
6683   [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
6684                (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
6685   "! TARGET_ARCH64"
6687   if (flag_delayed_branch)
6688     return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
6689   else
6690     return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
6692   [(set (attr "type") (const_string "multi"))
6693    (set (attr "length")
6694         (if_then_else (eq_attr "delayed_branch" "true")
6695                       (const_int 3)
6696                       (const_int 4)))])
6698 (define_insn "nop"
6699   [(const_int 0)]
6700   ""
6701   "nop")
6703 (define_expand "indirect_jump"
6704   [(set (pc) (match_operand 0 "address_operand" "p"))]
6705   ""
6706   "")
6708 (define_insn "*branch_sp32"
6709   [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
6710   "! TARGET_ARCH64"
6711  "jmp\t%a0%#"
6712  [(set_attr "type" "uncond_branch")])
6714 (define_insn "*branch_sp64"
6715   [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
6716   "TARGET_ARCH64"
6717   "jmp\t%a0%#"
6718   [(set_attr "type" "uncond_branch")])
6720 (define_expand "save_stack_nonlocal"
6721   [(set (match_operand 0 "memory_operand" "")
6722         (match_operand 1 "register_operand" ""))
6723    (set (match_dup 2) (match_dup 3))]
6724   ""
6726   operands[0] = adjust_address_nv (operands[0], Pmode, 0);
6727   operands[2] = adjust_address_nv (operands[0], Pmode, GET_MODE_SIZE (Pmode));
6728   operands[3] = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
6731 (define_expand "restore_stack_nonlocal"
6732   [(set (match_operand 0 "register_operand" "")
6733         (match_operand 1 "memory_operand" ""))]
6734   ""
6736   operands[1] = adjust_address_nv (operands[1], Pmode, 0);
6739 (define_expand "nonlocal_goto"
6740   [(match_operand 0 "general_operand" "")
6741    (match_operand 1 "general_operand" "")
6742    (match_operand 2 "memory_operand" "")
6743    (match_operand 3 "memory_operand" "")]
6744   ""
6746   rtx i7 = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
6747   rtx r_label = copy_to_reg (operands[1]);
6748   rtx r_sp = adjust_address_nv (operands[2], Pmode, 0);
6749   rtx r_fp = operands[3];
6750   rtx r_i7 = adjust_address_nv (operands[2], Pmode, GET_MODE_SIZE (Pmode));
6752   /* We need to flush all the register windows so that their contents will
6753      be re-synchronized by the restore insn of the target function.  */
6754   if (!TARGET_FLAT)
6755     emit_insn (gen_flush_register_windows ());
6757   emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
6758   emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
6760   /* Restore frame pointer for containing function.  */
6761   emit_move_insn (hard_frame_pointer_rtx, r_fp);
6762   emit_stack_restore (SAVE_NONLOCAL, r_sp);
6763   emit_move_insn (i7, r_i7);
6765   /* USE of hard_frame_pointer_rtx added for consistency;
6766      not clear if really needed.  */
6767   emit_use (hard_frame_pointer_rtx);
6768   emit_use (stack_pointer_rtx);
6769   emit_use (i7);
6771   emit_jump_insn (gen_indirect_jump (r_label));
6772   emit_barrier ();
6773   DONE;
6776 (define_expand "builtin_setjmp_receiver"
6777   [(label_ref (match_operand 0 "" ""))]
6778   "flag_pic"
6780   load_got_register ();
6781   DONE;
6784 ;; Special insn to flush register windows.
6786 (define_insn "flush_register_windows"
6787   [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
6788   ""
6789   { return TARGET_V9 ? "flushw" : "ta\t3"; }
6790   [(set_attr "type" "flushw")])
6792 ;; Special pattern for the FLUSH instruction.
6794 (define_insn "flush<P:mode>"
6795   [(unspec_volatile [(match_operand:P 0 "memory_operand" "m")] UNSPECV_FLUSH)]
6796   ""
6797   { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
6798   [(set_attr "type" "iflush")])
6800 ;; Special insns to load and store the 32-bit FP Status Register.
6802 (define_insn "ldfsr"
6803   [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_LDFSR)]
6804   "TARGET_FPU"
6805   "ld\t%0, %%fsr"
6806   [(set_attr "type" "load")])
6808 (define_insn "stfsr"
6809   [(set (match_operand:SI 0 "memory_operand" "=m")
6810         (unspec_volatile:SI [(const_int 0)] UNSPECV_STFSR))]
6811   "TARGET_FPU"
6812   "st\t%%fsr, %0"
6813   [(set_attr "type" "store")])
6816 ;; Find first set instructions.
6818 ;; The scan instruction searches from the most significant bit while ffs
6819 ;; searches from the least significant bit.  The bit index and treatment of
6820 ;; zero also differ.  It takes at least 7 instructions to get the proper
6821 ;; result.  Here is an obvious 8 instruction sequence.
6823 ;; XXX
6824 (define_insn "ffssi2"
6825   [(set (match_operand:SI 0 "register_operand" "=&r")
6826         (ffs:SI (match_operand:SI 1 "register_operand" "r")))
6827    (clobber (match_scratch:SI 2 "=&r"))]
6828   "TARGET_SPARCLITE || TARGET_SPARCLET"
6830   return "sub\t%%g0, %1, %0\;and\t%0, %1, %0\;scan\t%0, 0, %0\;mov\t32, %2\;sub\t%2, %0, %0\;sra\t%0, 31, %2\;and\t%2, 31, %2\;add\t%2, %0, %0";
6832   [(set_attr "type" "multi")
6833    (set_attr "length" "8")])
6835 (define_expand "popcountdi2"
6836   [(set (match_operand:DI 0 "register_operand" "")
6837         (popcount:DI (match_operand:DI 1 "register_operand" "")))]
6838   "TARGET_POPC"
6840   if (! TARGET_ARCH64)
6841     {
6842       emit_insn (gen_popcountdi_v8plus (operands[0], operands[1]));
6843       DONE;
6844     }
6847 (define_insn "*popcountdi_sp64"
6848   [(set (match_operand:DI 0 "register_operand" "=r")
6849         (popcount:DI (match_operand:DI 1 "register_operand" "r")))]
6850   "TARGET_POPC && TARGET_ARCH64"
6851   "popc\t%1, %0")
6853 (define_insn "popcountdi_v8plus"
6854   [(set (match_operand:DI 0 "register_operand" "=r")
6855         (popcount:DI (match_operand:DI 1 "register_operand" "r")))
6856    (clobber (match_scratch:SI 2 "=&h"))]
6857   "TARGET_POPC && ! TARGET_ARCH64"
6859   if (sparc_check_64 (operands[1], insn) <= 0)
6860     output_asm_insn ("srl\t%L1, 0, %L1", operands);
6861   return "sllx\t%H1, 32, %2\n\tor\t%L1, %2, %2\n\tpopc\t%2, %L0\n\tclr\t%H0";
6863   [(set_attr "type" "multi")
6864    (set_attr "length" "5")])
6866 (define_expand "popcountsi2"
6867   [(set (match_dup 2)
6868         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
6869    (set (match_operand:SI 0 "register_operand" "")
6870         (truncate:SI (popcount:DI (match_dup 2))))]
6871   "TARGET_POPC"
6873   if (! TARGET_ARCH64)
6874     {
6875       emit_insn (gen_popcountsi_v8plus (operands[0], operands[1]));
6876       DONE;
6877     }
6878   else
6879     operands[2] = gen_reg_rtx (DImode);
6882 (define_insn "*popcountsi_sp64"
6883   [(set (match_operand:SI 0 "register_operand" "=r")
6884         (truncate:SI
6885           (popcount:DI (match_operand:DI 1 "register_operand" "r"))))]
6886   "TARGET_POPC && TARGET_ARCH64"
6887   "popc\t%1, %0")
6889 (define_insn "popcountsi_v8plus"
6890   [(set (match_operand:SI 0 "register_operand" "=r")
6891         (popcount:SI (match_operand:SI 1 "register_operand" "r")))]
6892   "TARGET_POPC && ! TARGET_ARCH64"
6894   if (sparc_check_64 (operands[1], insn) <= 0)
6895     output_asm_insn ("srl\t%1, 0, %1", operands);
6896   return "popc\t%1, %0";
6898   [(set_attr "type" "multi")
6899    (set_attr "length" "2")])
6901 (define_expand "clzdi2"
6902   [(set (match_operand:DI 0 "register_operand" "")
6903         (clz:DI (match_operand:DI 1 "register_operand" "")))]
6904   "TARGET_VIS3"
6906   if (! TARGET_ARCH64)
6907     {
6908       emit_insn (gen_clzdi_v8plus (operands[0], operands[1]));
6909       DONE;
6910     }
6913 (define_insn "*clzdi_sp64"
6914   [(set (match_operand:DI 0 "register_operand" "=r")
6915         (clz:DI (match_operand:DI 1 "register_operand" "r")))]
6916   "TARGET_VIS3 && TARGET_ARCH64"
6917   "lzd\t%1, %0")
6919 (define_insn "clzdi_v8plus"
6920   [(set (match_operand:DI 0 "register_operand" "=r")
6921         (clz:DI (match_operand:DI 1 "register_operand" "r")))
6922    (clobber (match_scratch:SI 2 "=&h"))]
6923   "TARGET_VIS3 && ! TARGET_ARCH64"
6925   if (sparc_check_64 (operands[1], insn) <= 0)
6926     output_asm_insn ("srl\t%L1, 0, %L1", operands);
6927   return "sllx\t%H1, 32, %2\n\tor\t%L1, %2, %2\n\tlzd\t%2, %L0\n\tclr\t%H0";
6929   [(set_attr "type" "multi")
6930    (set_attr "length" "5")])
6932 (define_expand "clzsi2"
6933   [(set (match_dup 2)
6934         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
6935    (set (match_dup 3)
6936         (truncate:SI (clz:DI (match_dup 2))))
6937    (set (match_operand:SI 0 "register_operand" "")
6938         (minus:SI (match_dup 3) (const_int 32)))]
6939   "TARGET_VIS3"
6941   if (! TARGET_ARCH64)
6942     {
6943       emit_insn (gen_clzsi_v8plus (operands[0], operands[1]));
6944       DONE;
6945     }
6946   else
6947     {
6948       operands[2] = gen_reg_rtx (DImode);
6949       operands[3] = gen_reg_rtx (SImode);
6950     }
6953 (define_insn "*clzsi_sp64"
6954   [(set (match_operand:SI 0 "register_operand" "=r")
6955         (truncate:SI
6956           (clz:DI (match_operand:DI 1 "register_operand" "r"))))]
6957   "TARGET_VIS3 && TARGET_ARCH64"
6958   "lzd\t%1, %0")
6960 (define_insn "clzsi_v8plus"
6961   [(set (match_operand:SI 0 "register_operand" "=r")
6962         (clz:SI (match_operand:SI 1 "register_operand" "r")))]
6963   "TARGET_VIS3 && ! TARGET_ARCH64"
6965   if (sparc_check_64 (operands[1], insn) <= 0)
6966     output_asm_insn ("srl\t%1, 0, %1", operands);
6967   return "lzd\t%1, %0\n\tsub\t%0, 32, %0";
6969   [(set_attr "type" "multi")
6970    (set_attr "length" "3")])
6973 ;; Peepholes go at the end.
6975 ;; Optimize consecutive loads or stores into ldd and std when possible.
6976 ;; The conditions in which we do this are very restricted and are 
6977 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
6979 (define_peephole2
6980   [(set (match_operand:SI 0 "memory_operand" "")
6981       (const_int 0))
6982    (set (match_operand:SI 1 "memory_operand" "")
6983       (const_int 0))]
6984   "TARGET_V9
6985    && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
6986   [(set (match_dup 0) (const_int 0))]
6988   operands[0] = widen_mem_for_ldd_peep (operands[0], operands[1], DImode);
6991 (define_peephole2
6992   [(set (match_operand:SI 0 "memory_operand" "")
6993       (const_int 0))
6994    (set (match_operand:SI 1 "memory_operand" "")
6995       (const_int 0))]
6996   "TARGET_V9
6997    && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
6998   [(set (match_dup 1) (const_int 0))]
7000   operands[1] = widen_mem_for_ldd_peep (operands[1], operands[0], DImode);
7003 (define_peephole2
7004   [(set (match_operand:SI 0 "register_operand" "")
7005         (match_operand:SI 1 "memory_operand" ""))
7006    (set (match_operand:SI 2 "register_operand" "")
7007         (match_operand:SI 3 "memory_operand" ""))]
7008   "registers_ok_for_ldd_peep (operands[0], operands[2]) 
7009    && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])" 
7010   [(set (match_dup 0) (match_dup 1))]
7012   operands[1] = widen_mem_for_ldd_peep (operands[1], operands[3], DImode);
7013   operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
7016 (define_peephole2
7017   [(set (match_operand:SI 0 "memory_operand" "")
7018         (match_operand:SI 1 "register_operand" ""))
7019    (set (match_operand:SI 2 "memory_operand" "")
7020         (match_operand:SI 3 "register_operand" ""))]
7021   "registers_ok_for_ldd_peep (operands[1], operands[3]) 
7022    && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7023   [(set (match_dup 0) (match_dup 1))]
7025   operands[0] = widen_mem_for_ldd_peep (operands[0], operands[2], DImode);
7026   operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));
7029 (define_peephole2
7030   [(set (match_operand:SF 0 "register_operand" "")
7031         (match_operand:SF 1 "memory_operand" ""))
7032    (set (match_operand:SF 2 "register_operand" "")
7033         (match_operand:SF 3 "memory_operand" ""))]
7034   "registers_ok_for_ldd_peep (operands[0], operands[2]) 
7035    && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
7036   [(set (match_dup 0) (match_dup 1))]
7038   operands[1] = widen_mem_for_ldd_peep (operands[1], operands[3], DFmode);
7039   operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));
7042 (define_peephole2
7043   [(set (match_operand:SF 0 "memory_operand" "")
7044         (match_operand:SF 1 "register_operand" ""))
7045    (set (match_operand:SF 2 "memory_operand" "")
7046         (match_operand:SF 3 "register_operand" ""))]
7047   "registers_ok_for_ldd_peep (operands[1], operands[3]) 
7048   && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7049   [(set (match_dup 0) (match_dup 1))]
7051   operands[0] = widen_mem_for_ldd_peep (operands[0], operands[2], DFmode);
7052   operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));
7055 (define_peephole2
7056   [(set (match_operand:SI 0 "register_operand" "")
7057         (match_operand:SI 1 "memory_operand" ""))
7058    (set (match_operand:SI 2 "register_operand" "")
7059         (match_operand:SI 3 "memory_operand" ""))]
7060   "registers_ok_for_ldd_peep (operands[2], operands[0]) 
7061   && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
7062   [(set (match_dup 2) (match_dup 3))]
7064   operands[3] = widen_mem_for_ldd_peep (operands[3], operands[1], DImode);
7065   operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));
7068 (define_peephole2
7069   [(set (match_operand:SI 0 "memory_operand" "")
7070         (match_operand:SI 1 "register_operand" ""))
7071    (set (match_operand:SI 2 "memory_operand" "")
7072         (match_operand:SI 3 "register_operand" ""))]
7073   "registers_ok_for_ldd_peep (operands[3], operands[1]) 
7074   && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)" 
7075   [(set (match_dup 2) (match_dup 3))]
7077   operands[2] = widen_mem_for_ldd_peep (operands[2],  operands[0], DImode);
7078   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
7081 (define_peephole2
7082   [(set (match_operand:SF 0 "register_operand" "")
7083         (match_operand:SF 1 "memory_operand" ""))
7084    (set (match_operand:SF 2 "register_operand" "")
7085         (match_operand:SF 3 "memory_operand" ""))]
7086   "registers_ok_for_ldd_peep (operands[2], operands[0]) 
7087   && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
7088   [(set (match_dup 2) (match_dup 3))]
7090   operands[3] = widen_mem_for_ldd_peep (operands[3], operands[1], DFmode);
7091   operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));
7094 (define_peephole2
7095   [(set (match_operand:SF 0 "memory_operand" "")
7096         (match_operand:SF 1 "register_operand" ""))
7097    (set (match_operand:SF 2 "memory_operand" "")
7098         (match_operand:SF 3 "register_operand" ""))]
7099   "registers_ok_for_ldd_peep (operands[3], operands[1]) 
7100   && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
7101   [(set (match_dup 2) (match_dup 3))]
7103   operands[2] = widen_mem_for_ldd_peep (operands[2], operands[0], DFmode);
7104   operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));
7107 ;; Optimize the case of following a reg-reg move with a test
7108 ;; of reg just moved.  Don't allow floating point regs for operand 0 or 1.
7109 ;; This can result from a float to fix conversion.
7111 (define_peephole2
7112   [(set (match_operand:SI 0 "register_operand" "")
7113         (match_operand:SI 1 "register_operand" ""))
7114    (set (reg:CC CC_REG)
7115         (compare:CC (match_operand:SI 2 "register_operand" "")
7116                     (const_int 0)))]
7117   "(rtx_equal_p (operands[2], operands[0])
7118     || rtx_equal_p (operands[2], operands[1]))
7119     && ! SPARC_FP_REG_P (REGNO (operands[0]))
7120     && ! SPARC_FP_REG_P (REGNO (operands[1]))"
7121   [(parallel [(set (match_dup 0) (match_dup 1))
7122               (set (reg:CC CC_REG)
7123                    (compare:CC (match_dup 1) (const_int 0)))])]
7124   "")
7126 (define_peephole2
7127   [(set (match_operand:DI 0 "register_operand" "")
7128         (match_operand:DI 1 "register_operand" ""))
7129    (set (reg:CCX CC_REG)
7130         (compare:CCX (match_operand:DI 2 "register_operand" "")
7131                     (const_int 0)))]
7132   "TARGET_ARCH64
7133    && (rtx_equal_p (operands[2], operands[0])
7134        || rtx_equal_p (operands[2], operands[1]))
7135    && ! SPARC_FP_REG_P (REGNO (operands[0]))
7136    && ! SPARC_FP_REG_P (REGNO (operands[1]))"
7137   [(parallel [(set (match_dup 0) (match_dup 1))
7138               (set (reg:CCX CC_REG)
7139                    (compare:CCX (match_dup 1) (const_int 0)))])]
7140   "")
7143 ;; Prefetch instructions.
7145 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
7146 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
7147 ;; ??? operations.  With DFA we might be able to model this, but it requires a lot of
7148 ;; ??? state.
7149 (define_expand "prefetch"
7150   [(match_operand 0 "address_operand" "")
7151    (match_operand 1 "const_int_operand" "")
7152    (match_operand 2 "const_int_operand" "")]
7153   "TARGET_V9"
7155   if (TARGET_ARCH64)
7156     emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
7157   else
7158     emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
7159   DONE;
7162 (define_insn "prefetch_64"
7163   [(prefetch (match_operand:DI 0 "address_operand" "p")
7164              (match_operand:DI 1 "const_int_operand" "n")
7165              (match_operand:DI 2 "const_int_operand" "n"))]
7166   ""
7168   static const char * const prefetch_instr[2][2] = {
7169     {
7170       "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7171       "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7172     },
7173     {
7174       "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7175       "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7176     }
7177   };
7178   int read_or_write = INTVAL (operands[1]);
7179   int locality = INTVAL (operands[2]);
7181   gcc_assert (read_or_write == 0 || read_or_write == 1);
7182   gcc_assert (locality >= 0 && locality < 4);
7183   return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7185   [(set_attr "type" "load")])
7187 (define_insn "prefetch_32"
7188   [(prefetch (match_operand:SI 0 "address_operand" "p")
7189              (match_operand:SI 1 "const_int_operand" "n")
7190              (match_operand:SI 2 "const_int_operand" "n"))]
7191   ""
7193   static const char * const prefetch_instr[2][2] = {
7194     {
7195       "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7196       "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7197     },
7198     {
7199       "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7200       "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7201     }
7202   };
7203   int read_or_write = INTVAL (operands[1]);
7204   int locality = INTVAL (operands[2]);
7206   gcc_assert (read_or_write == 0 || read_or_write == 1);
7207   gcc_assert (locality >= 0 && locality < 4);
7208   return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7210   [(set_attr "type" "load")])
7213 ;; Trap instructions.
7215 (define_insn "trap"
7216   [(trap_if (const_int 1) (const_int 5))]
7217   ""
7218   "ta\t5"
7219   [(set_attr "type" "trap")])
7221 (define_expand "ctrapsi4"
7222   [(trap_if (match_operator 0 "noov_compare_operator"
7223              [(match_operand:SI 1 "compare_operand" "")
7224               (match_operand:SI 2 "arith_operand" "")])
7225            (match_operand 3 "arith_operand"))]
7226   ""
7227   "operands[1] = gen_compare_reg (operands[0]);
7228    if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
7229      FAIL;
7230    operands[2] = const0_rtx;")
7232 (define_expand "ctrapdi4"
7233   [(trap_if (match_operator 0 "noov_compare_operator"
7234              [(match_operand:DI 1 "compare_operand" "")
7235               (match_operand:DI 2 "arith_operand" "")])
7236            (match_operand 3 "arith_operand"))]
7237   "TARGET_ARCH64"
7238   "operands[1] = gen_compare_reg (operands[0]);
7239    if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
7240      FAIL;
7241    operands[2] = const0_rtx;")
7244 (define_insn ""
7245   [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CC CC_REG) (const_int 0)])
7246             (match_operand:SI 1 "arith_operand" "rM"))]
7247   ""
7249   if (TARGET_V9)
7250     return "t%C0\t%%icc, %1";
7251   else
7252     return "t%C0\t%1";
7254   [(set_attr "type" "trap")])
7256 (define_insn ""
7257   [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CCX CC_REG) (const_int 0)])
7258             (match_operand:SI 1 "arith_operand" "rM"))]
7259   "TARGET_V9"
7260   "t%C0\t%%xcc, %1"
7261   [(set_attr "type" "trap")])
7264 ;; TLS support instructions.
7266 (define_insn "tgd_hi22"
7267   [(set (match_operand:SI 0 "register_operand" "=r")
7268         (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
7269                             UNSPEC_TLSGD)))]
7270   "TARGET_TLS"
7271   "sethi\\t%%tgd_hi22(%a1), %0")
7273 (define_insn "tgd_lo10"
7274   [(set (match_operand:SI 0 "register_operand" "=r")
7275         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7276                    (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
7277                               UNSPEC_TLSGD)))]
7278   "TARGET_TLS"
7279   "add\\t%1, %%tgd_lo10(%a2), %0")
7281 (define_insn "tgd_add32"
7282   [(set (match_operand:SI 0 "register_operand" "=r")
7283         (plus:SI (match_operand:SI 1 "register_operand" "r")
7284                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7285                              (match_operand 3 "tgd_symbolic_operand" "")]
7286                             UNSPEC_TLSGD)))]
7287   "TARGET_TLS && TARGET_ARCH32"
7288   "add\\t%1, %2, %0, %%tgd_add(%a3)")
7290 (define_insn "tgd_add64"
7291   [(set (match_operand:DI 0 "register_operand" "=r")
7292         (plus:DI (match_operand:DI 1 "register_operand" "r")
7293                  (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7294                              (match_operand 3 "tgd_symbolic_operand" "")]
7295                             UNSPEC_TLSGD)))]
7296   "TARGET_TLS && TARGET_ARCH64"
7297   "add\\t%1, %2, %0, %%tgd_add(%a3)")
7299 (define_insn "tgd_call32"
7300   [(set (match_operand 0 "register_operand" "=r")
7301         (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
7302                                   (match_operand 2 "tgd_symbolic_operand" "")]
7303                                  UNSPEC_TLSGD))
7304               (match_operand 3 "" "")))
7305    (clobber (reg:SI O7_REG))]
7306   "TARGET_TLS && TARGET_ARCH32"
7307   "call\t%a1, %%tgd_call(%a2)%#"
7308   [(set_attr "type" "call")])
7310 (define_insn "tgd_call64"
7311   [(set (match_operand 0 "register_operand" "=r")
7312         (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
7313                                   (match_operand 2 "tgd_symbolic_operand" "")]
7314                                  UNSPEC_TLSGD))
7315               (match_operand 3 "" "")))
7316    (clobber (reg:DI O7_REG))]
7317   "TARGET_TLS && TARGET_ARCH64"
7318   "call\t%a1, %%tgd_call(%a2)%#"
7319   [(set_attr "type" "call")])
7321 (define_insn "tldm_hi22"
7322   [(set (match_operand:SI 0 "register_operand" "=r")
7323         (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7324   "TARGET_TLS"
7325   "sethi\\t%%tldm_hi22(%&), %0")
7327 (define_insn "tldm_lo10"
7328   [(set (match_operand:SI 0 "register_operand" "=r")
7329         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7330                     (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7331   "TARGET_TLS"
7332   "add\\t%1, %%tldm_lo10(%&), %0")
7334 (define_insn "tldm_add32"
7335   [(set (match_operand:SI 0 "register_operand" "=r")
7336         (plus:SI (match_operand:SI 1 "register_operand" "r")
7337                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
7338                             UNSPEC_TLSLDM)))]
7339   "TARGET_TLS && TARGET_ARCH32"
7340   "add\\t%1, %2, %0, %%tldm_add(%&)")
7342 (define_insn "tldm_add64"
7343   [(set (match_operand:DI 0 "register_operand" "=r")
7344         (plus:DI (match_operand:DI 1 "register_operand" "r")
7345                  (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
7346                             UNSPEC_TLSLDM)))]
7347   "TARGET_TLS && TARGET_ARCH64"
7348   "add\\t%1, %2, %0, %%tldm_add(%&)")
7350 (define_insn "tldm_call32"
7351   [(set (match_operand 0 "register_operand" "=r")
7352         (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
7353                                  UNSPEC_TLSLDM))
7354               (match_operand 2 "" "")))
7355    (clobber (reg:SI O7_REG))]
7356   "TARGET_TLS && TARGET_ARCH32"
7357   "call\t%a1, %%tldm_call(%&)%#"
7358   [(set_attr "type" "call")])
7360 (define_insn "tldm_call64"
7361   [(set (match_operand 0 "register_operand" "=r")
7362         (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
7363                                  UNSPEC_TLSLDM))
7364               (match_operand 2 "" "")))
7365    (clobber (reg:DI O7_REG))]
7366   "TARGET_TLS && TARGET_ARCH64"
7367   "call\t%a1, %%tldm_call(%&)%#"
7368   [(set_attr "type" "call")])
7370 (define_insn "tldo_hix22"
7371   [(set (match_operand:SI 0 "register_operand" "=r")
7372         (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
7373                             UNSPEC_TLSLDO)))]
7374   "TARGET_TLS"
7375   "sethi\\t%%tldo_hix22(%a1), %0")
7377 (define_insn "tldo_lox10"
7378   [(set (match_operand:SI 0 "register_operand" "=r")
7379         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7380                    (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
7381                               UNSPEC_TLSLDO)))]
7382   "TARGET_TLS"
7383   "xor\\t%1, %%tldo_lox10(%a2), %0")
7385 (define_insn "tldo_add32"
7386   [(set (match_operand:SI 0 "register_operand" "=r")
7387         (plus:SI (match_operand:SI 1 "register_operand" "r")
7388                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7389                              (match_operand 3 "tld_symbolic_operand" "")]
7390                             UNSPEC_TLSLDO)))]
7391   "TARGET_TLS && TARGET_ARCH32"
7392   "add\\t%1, %2, %0, %%tldo_add(%a3)")
7394 (define_insn "tldo_add64"
7395   [(set (match_operand:DI 0 "register_operand" "=r")
7396         (plus:DI (match_operand:DI 1 "register_operand" "r")
7397                  (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7398                              (match_operand 3 "tld_symbolic_operand" "")]
7399                             UNSPEC_TLSLDO)))]
7400   "TARGET_TLS && TARGET_ARCH64"
7401   "add\\t%1, %2, %0, %%tldo_add(%a3)")
7403 (define_insn "tie_hi22"
7404   [(set (match_operand:SI 0 "register_operand" "=r")
7405         (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
7406                             UNSPEC_TLSIE)))]
7407   "TARGET_TLS"
7408   "sethi\\t%%tie_hi22(%a1), %0")
7410 (define_insn "tie_lo10"
7411   [(set (match_operand:SI 0 "register_operand" "=r")
7412         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7413                    (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
7414                               UNSPEC_TLSIE)))]
7415   "TARGET_TLS"
7416   "add\\t%1, %%tie_lo10(%a2), %0")
7418 (define_insn "tie_ld32"
7419   [(set (match_operand:SI 0 "register_operand" "=r")
7420         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
7421                     (match_operand:SI 2 "register_operand" "r")
7422                     (match_operand 3 "tie_symbolic_operand" "")]
7423                    UNSPEC_TLSIE))]
7424   "TARGET_TLS && TARGET_ARCH32"
7425   "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
7426   [(set_attr "type" "load")])
7428 (define_insn "tie_ld64"
7429   [(set (match_operand:DI 0 "register_operand" "=r")
7430         (unspec:DI [(match_operand:DI 1 "register_operand" "r")
7431                     (match_operand:SI 2 "register_operand" "r")
7432                     (match_operand 3 "tie_symbolic_operand" "")]
7433                    UNSPEC_TLSIE))]
7434   "TARGET_TLS && TARGET_ARCH64"
7435   "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
7436   [(set_attr "type" "load")])
7438 (define_insn "tie_add32"
7439   [(set (match_operand:SI 0 "register_operand" "=r")
7440         (plus:SI (match_operand:SI 1 "register_operand" "r")
7441                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7442                              (match_operand 3 "tie_symbolic_operand" "")]
7443                             UNSPEC_TLSIE)))]
7444   "TARGET_SUN_TLS && TARGET_ARCH32"
7445   "add\\t%1, %2, %0, %%tie_add(%a3)")
7447 (define_insn "tie_add64"
7448   [(set (match_operand:DI 0 "register_operand" "=r")
7449         (plus:DI (match_operand:DI 1 "register_operand" "r")
7450                  (unspec:DI [(match_operand:DI 2 "register_operand" "r")
7451                              (match_operand 3 "tie_symbolic_operand" "")]
7452                             UNSPEC_TLSIE)))]
7453   "TARGET_SUN_TLS && TARGET_ARCH64"
7454   "add\\t%1, %2, %0, %%tie_add(%a3)")
7456 (define_insn "tle_hix22_sp32"
7457   [(set (match_operand:SI 0 "register_operand" "=r")
7458         (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
7459                             UNSPEC_TLSLE)))]
7460   "TARGET_TLS && TARGET_ARCH32"
7461   "sethi\\t%%tle_hix22(%a1), %0")
7463 (define_insn "tle_lox10_sp32"
7464   [(set (match_operand:SI 0 "register_operand" "=r")
7465         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7466                    (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
7467                               UNSPEC_TLSLE)))]
7468   "TARGET_TLS && TARGET_ARCH32"
7469   "xor\\t%1, %%tle_lox10(%a2), %0")
7471 (define_insn "tle_hix22_sp64"
7472   [(set (match_operand:DI 0 "register_operand" "=r")
7473         (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
7474                             UNSPEC_TLSLE)))]
7475   "TARGET_TLS && TARGET_ARCH64"
7476   "sethi\\t%%tle_hix22(%a1), %0")
7478 (define_insn "tle_lox10_sp64"
7479   [(set (match_operand:DI 0 "register_operand" "=r")
7480         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
7481                    (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
7482                               UNSPEC_TLSLE)))]
7483   "TARGET_TLS && TARGET_ARCH64"
7484   "xor\\t%1, %%tle_lox10(%a2), %0")
7486 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
7487 (define_insn "*tldo_ldub_sp32"
7488   [(set (match_operand:QI 0 "register_operand" "=r")
7489         (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7490                                      (match_operand 3 "tld_symbolic_operand" "")]
7491                                     UNSPEC_TLSLDO)
7492                          (match_operand:SI 1 "register_operand" "r"))))]
7493   "TARGET_TLS && TARGET_ARCH32"
7494   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7495   [(set_attr "type" "load")
7496    (set_attr "us3load_type" "3cycle")])
7498 (define_insn "*tldo_ldub1_sp32"
7499   [(set (match_operand:HI 0 "register_operand" "=r")
7500         (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7501                                                      (match_operand 3 "tld_symbolic_operand" "")]
7502                                                     UNSPEC_TLSLDO)
7503                                          (match_operand:SI 1 "register_operand" "r")))))]
7504   "TARGET_TLS && TARGET_ARCH32"
7505   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7506   [(set_attr "type" "load")
7507    (set_attr "us3load_type" "3cycle")])
7509 (define_insn "*tldo_ldub2_sp32"
7510   [(set (match_operand:SI 0 "register_operand" "=r")
7511         (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7512                                                      (match_operand 3 "tld_symbolic_operand" "")]
7513                                                     UNSPEC_TLSLDO)
7514                                          (match_operand:SI 1 "register_operand" "r")))))]
7515   "TARGET_TLS && TARGET_ARCH32"
7516   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7517   [(set_attr "type" "load")
7518    (set_attr "us3load_type" "3cycle")])
7520 (define_insn "*tldo_ldsb1_sp32"
7521   [(set (match_operand:HI 0 "register_operand" "=r")
7522         (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7523                                                      (match_operand 3 "tld_symbolic_operand" "")]
7524                                                     UNSPEC_TLSLDO)
7525                                          (match_operand:SI 1 "register_operand" "r")))))]
7526   "TARGET_TLS && TARGET_ARCH32"
7527   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7528   [(set_attr "type" "sload")
7529    (set_attr "us3load_type" "3cycle")])
7531 (define_insn "*tldo_ldsb2_sp32"
7532   [(set (match_operand:SI 0 "register_operand" "=r")
7533         (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7534                                                      (match_operand 3 "tld_symbolic_operand" "")]
7535                                                     UNSPEC_TLSLDO)
7536                                          (match_operand:SI 1 "register_operand" "r")))))]
7537   "TARGET_TLS && TARGET_ARCH32"
7538   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7539   [(set_attr "type" "sload")
7540    (set_attr "us3load_type" "3cycle")])
7542 (define_insn "*tldo_ldub_sp64"
7543   [(set (match_operand:QI 0 "register_operand" "=r")
7544         (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7545                                      (match_operand 3 "tld_symbolic_operand" "")]
7546                                     UNSPEC_TLSLDO)
7547                          (match_operand:DI 1 "register_operand" "r"))))]
7548   "TARGET_TLS && TARGET_ARCH64"
7549   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7550   [(set_attr "type" "load")
7551    (set_attr "us3load_type" "3cycle")])
7553 (define_insn "*tldo_ldub1_sp64"
7554   [(set (match_operand:HI 0 "register_operand" "=r")
7555         (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7556                                                      (match_operand 3 "tld_symbolic_operand" "")]
7557                                                     UNSPEC_TLSLDO)
7558                                          (match_operand:DI 1 "register_operand" "r")))))]
7559   "TARGET_TLS && TARGET_ARCH64"
7560   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7561   [(set_attr "type" "load")
7562    (set_attr "us3load_type" "3cycle")])
7564 (define_insn "*tldo_ldub2_sp64"
7565   [(set (match_operand:SI 0 "register_operand" "=r")
7566         (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7567                                                      (match_operand 3 "tld_symbolic_operand" "")]
7568                                                     UNSPEC_TLSLDO)
7569                                          (match_operand:DI 1 "register_operand" "r")))))]
7570   "TARGET_TLS && TARGET_ARCH64"
7571   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7572   [(set_attr "type" "load")
7573    (set_attr "us3load_type" "3cycle")])
7575 (define_insn "*tldo_ldub3_sp64"
7576   [(set (match_operand:DI 0 "register_operand" "=r")
7577         (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7578                                                      (match_operand 3 "tld_symbolic_operand" "")]
7579                                                     UNSPEC_TLSLDO)
7580                                          (match_operand:DI 1 "register_operand" "r")))))]
7581   "TARGET_TLS && TARGET_ARCH64"
7582   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7583   [(set_attr "type" "load")
7584    (set_attr "us3load_type" "3cycle")])
7586 (define_insn "*tldo_ldsb1_sp64"
7587   [(set (match_operand:HI 0 "register_operand" "=r")
7588         (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7589                                                      (match_operand 3 "tld_symbolic_operand" "")]
7590                                                     UNSPEC_TLSLDO)
7591                                          (match_operand:DI 1 "register_operand" "r")))))]
7592   "TARGET_TLS && TARGET_ARCH64"
7593   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7594   [(set_attr "type" "sload")
7595    (set_attr "us3load_type" "3cycle")])
7597 (define_insn "*tldo_ldsb2_sp64"
7598   [(set (match_operand:SI 0 "register_operand" "=r")
7599         (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7600                                                      (match_operand 3 "tld_symbolic_operand" "")]
7601                                                     UNSPEC_TLSLDO)
7602                                          (match_operand:DI 1 "register_operand" "r")))))]
7603   "TARGET_TLS && TARGET_ARCH64"
7604   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7605   [(set_attr "type" "sload")
7606    (set_attr "us3load_type" "3cycle")])
7608 (define_insn "*tldo_ldsb3_sp64"
7609   [(set (match_operand:DI 0 "register_operand" "=r")
7610         (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7611                                                      (match_operand 3 "tld_symbolic_operand" "")]
7612                                                     UNSPEC_TLSLDO)
7613                                          (match_operand:DI 1 "register_operand" "r")))))]
7614   "TARGET_TLS && TARGET_ARCH64"
7615   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7616   [(set_attr "type" "sload")
7617    (set_attr "us3load_type" "3cycle")])
7619 (define_insn "*tldo_lduh_sp32"
7620   [(set (match_operand:HI 0 "register_operand" "=r")
7621         (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7622                                      (match_operand 3 "tld_symbolic_operand" "")]
7623                                     UNSPEC_TLSLDO)
7624                          (match_operand:SI 1 "register_operand" "r"))))]
7625   "TARGET_TLS && TARGET_ARCH32"
7626   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7627   [(set_attr "type" "load")
7628    (set_attr "us3load_type" "3cycle")])
7630 (define_insn "*tldo_lduh1_sp32"
7631   [(set (match_operand:SI 0 "register_operand" "=r")
7632         (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7633                                                      (match_operand 3 "tld_symbolic_operand" "")]
7634                                                     UNSPEC_TLSLDO)
7635                                          (match_operand:SI 1 "register_operand" "r")))))]
7636   "TARGET_TLS && TARGET_ARCH32"
7637   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7638   [(set_attr "type" "load")
7639    (set_attr "us3load_type" "3cycle")])
7641 (define_insn "*tldo_ldsh1_sp32"
7642   [(set (match_operand:SI 0 "register_operand" "=r")
7643         (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7644                                                      (match_operand 3 "tld_symbolic_operand" "")]
7645                                                     UNSPEC_TLSLDO)
7646                                          (match_operand:SI 1 "register_operand" "r")))))]
7647   "TARGET_TLS && TARGET_ARCH32"
7648   "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7649   [(set_attr "type" "sload")
7650    (set_attr "us3load_type" "3cycle")])
7652 (define_insn "*tldo_lduh_sp64"
7653   [(set (match_operand:HI 0 "register_operand" "=r")
7654         (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7655                                      (match_operand 3 "tld_symbolic_operand" "")]
7656                                     UNSPEC_TLSLDO)
7657                          (match_operand:DI 1 "register_operand" "r"))))]
7658   "TARGET_TLS && TARGET_ARCH64"
7659   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7660   [(set_attr "type" "load")
7661    (set_attr "us3load_type" "3cycle")])
7663 (define_insn "*tldo_lduh1_sp64"
7664   [(set (match_operand:SI 0 "register_operand" "=r")
7665         (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7666                                                      (match_operand 3 "tld_symbolic_operand" "")]
7667                                                     UNSPEC_TLSLDO)
7668                                          (match_operand:DI 1 "register_operand" "r")))))]
7669   "TARGET_TLS && TARGET_ARCH64"
7670   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7671   [(set_attr "type" "load")
7672    (set_attr "us3load_type" "3cycle")])
7674 (define_insn "*tldo_lduh2_sp64"
7675   [(set (match_operand:DI 0 "register_operand" "=r")
7676         (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7677                                                      (match_operand 3 "tld_symbolic_operand" "")]
7678                                                     UNSPEC_TLSLDO)
7679                                          (match_operand:DI 1 "register_operand" "r")))))]
7680   "TARGET_TLS && TARGET_ARCH64"
7681   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7682   [(set_attr "type" "load")
7683    (set_attr "us3load_type" "3cycle")])
7685 (define_insn "*tldo_ldsh1_sp64"
7686   [(set (match_operand:SI 0 "register_operand" "=r")
7687         (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7688                                                      (match_operand 3 "tld_symbolic_operand" "")]
7689                                                     UNSPEC_TLSLDO)
7690                                          (match_operand:DI 1 "register_operand" "r")))))]
7691   "TARGET_TLS && TARGET_ARCH64"
7692   "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7693   [(set_attr "type" "sload")
7694    (set_attr "us3load_type" "3cycle")])
7696 (define_insn "*tldo_ldsh2_sp64"
7697   [(set (match_operand:DI 0 "register_operand" "=r")
7698         (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7699                                                      (match_operand 3 "tld_symbolic_operand" "")]
7700                                                     UNSPEC_TLSLDO)
7701                                          (match_operand:DI 1 "register_operand" "r")))))]
7702   "TARGET_TLS && TARGET_ARCH64"
7703   "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7704   [(set_attr "type" "sload")
7705    (set_attr "us3load_type" "3cycle")])
7707 (define_insn "*tldo_lduw_sp32"
7708   [(set (match_operand:SI 0 "register_operand" "=r")
7709         (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7710                                      (match_operand 3 "tld_symbolic_operand" "")]
7711                                     UNSPEC_TLSLDO)
7712                          (match_operand:SI 1 "register_operand" "r"))))]
7713   "TARGET_TLS && TARGET_ARCH32"
7714   "ld\t[%1 + %2], %0, %%tldo_add(%3)"
7715   [(set_attr "type" "load")])
7717 (define_insn "*tldo_lduw_sp64"
7718   [(set (match_operand:SI 0 "register_operand" "=r")
7719         (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7720                                      (match_operand 3 "tld_symbolic_operand" "")]
7721                                     UNSPEC_TLSLDO)
7722                          (match_operand:DI 1 "register_operand" "r"))))]
7723   "TARGET_TLS && TARGET_ARCH64"
7724   "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7725   [(set_attr "type" "load")])
7727 (define_insn "*tldo_lduw1_sp64"
7728   [(set (match_operand:DI 0 "register_operand" "=r")
7729         (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7730                                                      (match_operand 3 "tld_symbolic_operand" "")]
7731                                                     UNSPEC_TLSLDO)
7732                                          (match_operand:DI 1 "register_operand" "r")))))]
7733   "TARGET_TLS && TARGET_ARCH64"
7734   "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7735   [(set_attr "type" "load")])
7737 (define_insn "*tldo_ldsw1_sp64"
7738   [(set (match_operand:DI 0 "register_operand" "=r")
7739         (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7740                                                      (match_operand 3 "tld_symbolic_operand" "")]
7741                                                     UNSPEC_TLSLDO)
7742                                          (match_operand:DI 1 "register_operand" "r")))))]
7743   "TARGET_TLS && TARGET_ARCH64"
7744   "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
7745   [(set_attr "type" "sload")
7746    (set_attr "us3load_type" "3cycle")])
7748 (define_insn "*tldo_ldx_sp64"
7749   [(set (match_operand:DI 0 "register_operand" "=r")
7750         (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7751                                      (match_operand 3 "tld_symbolic_operand" "")]
7752                                     UNSPEC_TLSLDO)
7753                          (match_operand:DI 1 "register_operand" "r"))))]
7754   "TARGET_TLS && TARGET_ARCH64"
7755   "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
7756   [(set_attr "type" "load")])
7758 (define_insn "*tldo_stb_sp32"
7759   [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7760                                      (match_operand 3 "tld_symbolic_operand" "")]
7761                                     UNSPEC_TLSLDO)
7762                          (match_operand:SI 1 "register_operand" "r")))
7763         (match_operand:QI 0 "register_operand" "r"))]
7764   "TARGET_TLS && TARGET_ARCH32"
7765   "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7766   [(set_attr "type" "store")])
7768 (define_insn "*tldo_stb_sp64"
7769   [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7770                                      (match_operand 3 "tld_symbolic_operand" "")]
7771                                     UNSPEC_TLSLDO)
7772                          (match_operand:DI 1 "register_operand" "r")))
7773         (match_operand:QI 0 "register_operand" "r"))]
7774   "TARGET_TLS && TARGET_ARCH64"
7775   "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7776   [(set_attr "type" "store")])
7778 (define_insn "*tldo_sth_sp32"
7779   [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7780                                      (match_operand 3 "tld_symbolic_operand" "")]
7781                                     UNSPEC_TLSLDO)
7782                          (match_operand:SI 1 "register_operand" "r")))
7783         (match_operand:HI 0 "register_operand" "r"))]
7784   "TARGET_TLS && TARGET_ARCH32"
7785   "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7786   [(set_attr "type" "store")])
7788 (define_insn "*tldo_sth_sp64"
7789   [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7790                                      (match_operand 3 "tld_symbolic_operand" "")]
7791                                     UNSPEC_TLSLDO)
7792                          (match_operand:DI 1 "register_operand" "r")))
7793         (match_operand:HI 0 "register_operand" "r"))]
7794   "TARGET_TLS && TARGET_ARCH64"
7795   "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7796   [(set_attr "type" "store")])
7798 (define_insn "*tldo_stw_sp32"
7799   [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7800                                      (match_operand 3 "tld_symbolic_operand" "")]
7801                                     UNSPEC_TLSLDO)
7802                          (match_operand:SI 1 "register_operand" "r")))
7803         (match_operand:SI 0 "register_operand" "r"))]
7804   "TARGET_TLS && TARGET_ARCH32"
7805   "st\t%0, [%1 + %2], %%tldo_add(%3)"
7806   [(set_attr "type" "store")])
7808 (define_insn "*tldo_stw_sp64"
7809   [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7810                                      (match_operand 3 "tld_symbolic_operand" "")]
7811                                     UNSPEC_TLSLDO)
7812                          (match_operand:DI 1 "register_operand" "r")))
7813         (match_operand:SI 0 "register_operand" "r"))]
7814   "TARGET_TLS && TARGET_ARCH64"
7815   "stw\t%0, [%1 + %2], %%tldo_add(%3)"
7816   [(set_attr "type" "store")])
7818 (define_insn "*tldo_stx_sp64"
7819   [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7820                                      (match_operand 3 "tld_symbolic_operand" "")]
7821                                     UNSPEC_TLSLDO)
7822                          (match_operand:DI 1 "register_operand" "r")))
7823         (match_operand:DI 0 "register_operand" "r"))]
7824   "TARGET_TLS && TARGET_ARCH64"
7825   "stx\t%0, [%1 + %2], %%tldo_add(%3)"
7826   [(set_attr "type" "store")])
7829 ;; Stack protector instructions.
7831 (define_expand "stack_protect_set"
7832   [(match_operand 0 "memory_operand" "")
7833    (match_operand 1 "memory_operand" "")]
7834   ""
7836 #ifdef TARGET_THREAD_SSP_OFFSET
7837   rtx tlsreg = gen_rtx_REG (Pmode, 7);
7838   rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7839   operands[1] = gen_rtx_MEM (Pmode, addr);
7840 #endif
7841   if (TARGET_ARCH64)
7842     emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
7843   else
7844     emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
7845   DONE;
7848 (define_insn "stack_protect_setsi"
7849   [(set (match_operand:SI 0 "memory_operand" "=m")
7850         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7851    (set (match_scratch:SI 2 "=&r") (const_int 0))]
7852   "TARGET_ARCH32"
7853   "ld\t%1, %2\;st\t%2, %0\;mov\t0, %2"
7854   [(set_attr "type" "multi")
7855    (set_attr "length" "3")])
7857 (define_insn "stack_protect_setdi"
7858   [(set (match_operand:DI 0 "memory_operand" "=m")
7859         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7860    (set (match_scratch:DI 2 "=&r") (const_int 0))]
7861   "TARGET_ARCH64"
7862   "ldx\t%1, %2\;stx\t%2, %0\;mov\t0, %2"
7863   [(set_attr "type" "multi")
7864    (set_attr "length" "3")])
7866 (define_expand "stack_protect_test"
7867   [(match_operand 0 "memory_operand" "")
7868    (match_operand 1 "memory_operand" "")
7869    (match_operand 2 "" "")]
7870   ""
7872   rtx result, test;
7873 #ifdef TARGET_THREAD_SSP_OFFSET
7874   rtx tlsreg = gen_rtx_REG (Pmode, 7);
7875   rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7876   operands[1] = gen_rtx_MEM (Pmode, addr);
7877 #endif
7878   if (TARGET_ARCH64)
7879     {
7880       result = gen_reg_rtx (Pmode);
7881       emit_insn (gen_stack_protect_testdi (result, operands[0], operands[1]));
7882       test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7883       emit_jump_insn (gen_cbranchdi4 (test, result, const0_rtx, operands[2]));
7884     }
7885   else
7886     {
7887       emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
7888       result = gen_rtx_REG (CCmode, SPARC_ICC_REG);
7889       test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7890       emit_jump_insn (gen_cbranchcc4 (test, result, const0_rtx, operands[2]));
7891     }
7892   DONE;
7895 (define_insn "stack_protect_testsi"
7896   [(set (reg:CC CC_REG)
7897         (unspec:CC [(match_operand:SI 0 "memory_operand" "m")
7898                     (match_operand:SI 1 "memory_operand" "m")]
7899                    UNSPEC_SP_TEST))
7900    (set (match_scratch:SI 3 "=r") (const_int 0))
7901    (clobber (match_scratch:SI 2 "=&r"))]
7902   "TARGET_ARCH32"
7903   "ld\t%0, %2\;ld\t%1, %3\;xorcc\t%2, %3, %2\;mov\t0, %3"
7904   [(set_attr "type" "multi")
7905    (set_attr "length" "4")])
7907 (define_insn "stack_protect_testdi"
7908   [(set (match_operand:DI 0 "register_operand" "=&r")
7909         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
7910                     (match_operand:DI 2 "memory_operand" "m")]
7911                    UNSPEC_SP_TEST))
7912    (set (match_scratch:DI 3 "=r") (const_int 0))]
7913   "TARGET_ARCH64"
7914   "ldx\t%1, %0\;ldx\t%2, %3\;xor\t%0, %3, %0\;mov\t0, %3"
7915   [(set_attr "type" "multi")
7916    (set_attr "length" "4")])
7918 ;; Vector instructions.
7920 (define_mode_iterator VM32 [V1SI V2HI V4QI])
7921 (define_mode_iterator VM64 [V1DI V2SI V4HI V8QI])
7922 (define_mode_iterator VMALL [V1SI V2HI V4QI V1DI V2SI V4HI V8QI])
7924 (define_mode_attr vbits [(V2SI "32") (V4HI "16") (V1SI "32s") (V2HI "16s")])
7925 (define_mode_attr vconstr [(V1SI "f") (V2HI "f") (V4QI "f")
7926                            (V1DI "e") (V2SI "e") (V4HI "e") (V8QI "e")])
7927 (define_mode_attr vfptype [(V1SI "single") (V2HI "single") (V4QI "single")
7928                            (V1DI "double") (V2SI "double") (V4HI "double")
7929                            (V8QI "double")])
7931 (define_expand "mov<VMALL:mode>"
7932   [(set (match_operand:VMALL 0 "nonimmediate_operand" "")
7933         (match_operand:VMALL 1 "general_operand" ""))]
7934   "TARGET_VIS"
7936   if (sparc_expand_move (<VMALL:MODE>mode, operands))
7937     DONE;
7940 (define_insn "*mov<VM32:mode>_insn"
7941   [(set (match_operand:VM32 0 "nonimmediate_operand" "=f,f,f,f,m,m,*r, m,*r,*r, f")
7942         (match_operand:VM32 1 "input_operand"         "Y,Z,f,m,f,Y, m,*r,*r, f,*r"))]
7943   "TARGET_VIS
7944    && (register_operand (operands[0], <VM32:MODE>mode)
7945        || register_or_zero_or_all_ones_operand (operands[1], <VM32:MODE>mode))"
7946   "@
7947   fzeros\t%0
7948   fones\t%0
7949   fsrc2s\t%1, %0
7950   ld\t%1, %0
7951   st\t%1, %0
7952   st\t%r1, %0
7953   ld\t%1, %0
7954   st\t%1, %0
7955   mov\t%1, %0
7956   movstouw\t%1, %0
7957   movwtos\t%1, %0"
7958   [(set_attr "type" "visl,visl,vismv,fpload,fpstore,store,load,store,*,vismv,vismv")
7959    (set_attr "cpu_feature" "vis,vis,vis,*,*,*,*,*,*,vis3,vis3")])
7961 (define_insn "*mov<VM64:mode>_insn_sp64"
7962   [(set (match_operand:VM64 0 "nonimmediate_operand" "=e,e,e,e,m,m,*r, m,*r, e,*r")
7963         (match_operand:VM64 1 "input_operand"         "Y,C,e,m,e,Y, m,*r, e,*r,*r"))]
7964   "TARGET_VIS
7965    && TARGET_ARCH64
7966    && (register_operand (operands[0], <VM64:MODE>mode)
7967        || register_or_zero_or_all_ones_operand (operands[1], <VM64:MODE>mode))"
7968   "@
7969   fzero\t%0
7970   fone\t%0
7971   fsrc2\t%1, %0
7972   ldd\t%1, %0
7973   std\t%1, %0
7974   stx\t%r1, %0
7975   ldx\t%1, %0
7976   stx\t%1, %0
7977   movdtox\t%1, %0
7978   movxtod\t%1, %0
7979   mov\t%1, %0"
7980   [(set_attr "type" "visl,visl,vismv,fpload,fpstore,store,load,store,vismv,vismv,*")
7981    (set_attr "cpu_feature" "vis,vis,vis,*,*,*,*,*,vis3,vis3,*")])
7983 (define_insn "*mov<VM64:mode>_insn_sp32"
7984   [(set (match_operand:VM64 0 "nonimmediate_operand" "=e,e,e,*r, f,e,m,m,U,T, o,*r")
7985         (match_operand:VM64 1 "input_operand"         "Y,C,e, f,*r,m,e,Y,T,U,*r,*r"))]
7986   "TARGET_VIS
7987    && ! TARGET_ARCH64
7988    && (register_operand (operands[0], <VM64:MODE>mode)
7989        || register_or_zero_or_all_ones_operand (operands[1], <VM64:MODE>mode))"
7990   "@
7991   fzero\t%0
7992   fone\t%0
7993   fsrc2\t%1, %0
7994   #
7995   #
7996   ldd\t%1, %0
7997   std\t%1, %0
7998   stx\t%r1, %0
7999   ldd\t%1, %0
8000   std\t%1, %0
8001   #
8002   #"
8003   [(set_attr "type" "visl,visl,vismv,*,*,fpload,fpstore,store,load,store,*,*")
8004    (set_attr "length" "*,*,*,2,2,*,*,*,*,*,2,2")
8005    (set_attr "cpu_feature" "vis,vis,vis,vis3,vis3,*,*,*,*,*,*,*")])
8007 (define_split
8008   [(set (match_operand:VM64 0 "memory_operand" "")
8009         (match_operand:VM64 1 "register_operand" ""))]
8010   "reload_completed
8011    && TARGET_VIS
8012    && ! TARGET_ARCH64
8013    && (((REGNO (operands[1]) % 2) != 0)
8014        || ! mem_min_alignment (operands[0], 8))
8015    && offsettable_memref_p (operands[0])"
8016   [(clobber (const_int 0))]
8018   rtx word0, word1;
8020   word0 = adjust_address (operands[0], SImode, 0);
8021   word1 = adjust_address (operands[0], SImode, 4);
8023   emit_move_insn_1 (word0, gen_highpart (SImode, operands[1]));
8024   emit_move_insn_1 (word1, gen_lowpart (SImode, operands[1]));
8025   DONE;
8028 (define_split
8029   [(set (match_operand:VM64 0 "register_operand" "")
8030         (match_operand:VM64 1 "register_operand" ""))]
8031   "reload_completed
8032    && TARGET_VIS
8033    && ! TARGET_ARCH64
8034    && sparc_split_regreg_legitimate (operands[0], operands[1])"
8035   [(clobber (const_int 0))]
8037   rtx set_dest = operands[0];
8038   rtx set_src = operands[1];
8039   rtx dest1, dest2;
8040   rtx src1, src2;
8042   dest1 = gen_highpart (SImode, set_dest);
8043   dest2 = gen_lowpart (SImode, set_dest);
8044   src1 = gen_highpart (SImode, set_src);
8045   src2 = gen_lowpart (SImode, set_src);
8047   /* Now emit using the real source and destination we found, swapping
8048      the order if we detect overlap.  */
8049   if (reg_overlap_mentioned_p (dest1, src2))
8050     {
8051       emit_insn (gen_movsi (dest2, src2));
8052       emit_insn (gen_movsi (dest1, src1));
8053     }
8054   else
8055     {
8056       emit_insn (gen_movsi (dest1, src1));
8057       emit_insn (gen_movsi (dest2, src2));
8058     }
8059   DONE;
8062 (define_expand "vec_init<mode>"
8063   [(match_operand:VMALL 0 "register_operand" "")
8064    (match_operand:VMALL 1 "" "")]
8065   "TARGET_VIS"
8067   sparc_expand_vector_init (operands[0], operands[1]);
8068   DONE;
8071 (define_code_iterator plusminus [plus minus])
8072 (define_code_attr plusminus_insn [(plus "add") (minus "sub")])
8074 (define_mode_iterator VADDSUB [V1SI V2SI V2HI V4HI])
8076 (define_insn "<plusminus_insn><mode>3"
8077   [(set (match_operand:VADDSUB 0 "register_operand" "=<vconstr>")
8078         (plusminus:VADDSUB (match_operand:VADDSUB 1 "register_operand" "<vconstr>")
8079                            (match_operand:VADDSUB 2 "register_operand" "<vconstr>")))]
8080   "TARGET_VIS"
8081   "fp<plusminus_insn><vbits>\t%1, %2, %0"
8082   [(set_attr "type" "fga")
8083    (set_attr "fptype" "<vfptype>")])
8085 (define_mode_iterator VL [V1SI V2HI V4QI V1DI V2SI V4HI V8QI])
8086 (define_mode_attr vlsuf [(V1SI "s") (V2HI "s") (V4QI "s")
8087                          (V1DI  "") (V2SI  "") (V4HI  "") (V8QI "")])
8088 (define_code_iterator vlop [ior and xor])
8089 (define_code_attr vlinsn [(ior "or") (and "and") (xor "xor")])
8090 (define_code_attr vlninsn [(ior "nor") (and "nand") (xor "xnor")])
8092 (define_insn "<code><mode>3"
8093   [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8094         (vlop:VL (match_operand:VL 1 "register_operand" "<vconstr>")
8095                  (match_operand:VL 2 "register_operand" "<vconstr>")))]
8096   "TARGET_VIS"
8097   "f<vlinsn><vlsuf>\t%1, %2, %0"
8098   [(set_attr "type" "visl")
8099    (set_attr "fptype" "<vfptype>")])
8101 (define_insn "*not_<code><mode>3"
8102   [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8103         (not:VL (vlop:VL (match_operand:VL 1 "register_operand" "<vconstr>")
8104                          (match_operand:VL 2 "register_operand" "<vconstr>"))))]
8105   "TARGET_VIS"
8106   "f<vlninsn><vlsuf>\t%1, %2, %0"
8107   [(set_attr "type" "visl")
8108    (set_attr "fptype" "<vfptype>")])
8110 ;; (ior (not (op1)) (not (op2))) is the canonical form of NAND.
8111 (define_insn "*nand<mode>_vis"
8112   [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8113         (ior:VL (not:VL (match_operand:VL 1 "register_operand" "<vconstr>"))
8114                 (not:VL (match_operand:VL 2 "register_operand" "<vconstr>"))))]
8115   "TARGET_VIS"
8116   "fnand<vlsuf>\t%1, %2, %0"
8117   [(set_attr "type" "visl")
8118    (set_attr "fptype" "<vfptype>")])
8120 (define_code_iterator vlnotop [ior and])
8122 (define_insn "*<code>_not1<mode>_vis"
8123   [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8124         (vlnotop:VL (not:VL (match_operand:VL 1 "register_operand" "<vconstr>"))
8125                     (match_operand:VL 2 "register_operand" "<vconstr>")))]
8126   "TARGET_VIS"
8127   "f<vlinsn>not1<vlsuf>\t%1, %2, %0"
8128   [(set_attr "type" "visl")
8129    (set_attr "fptype" "<vfptype>")])
8131 (define_insn "*<code>_not2<mode>_vis"
8132   [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8133         (vlnotop:VL (match_operand:VL 1 "register_operand" "<vconstr>")
8134                     (not:VL (match_operand:VL 2 "register_operand" "<vconstr>"))))]
8135   "TARGET_VIS"
8136   "f<vlinsn>not2<vlsuf>\t%1, %2, %0"
8137   [(set_attr "type" "visl")
8138    (set_attr "fptype" "<vfptype>")])
8140 (define_insn "one_cmpl<mode>2"
8141   [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8142         (not:VL (match_operand:VL 1 "register_operand" "<vconstr>")))]
8143   "TARGET_VIS"
8144   "fnot1<vlsuf>\t%1, %0"
8145   [(set_attr "type" "visl")
8146    (set_attr "fptype" "<vfptype>")])
8148 ;; Hard to generate VIS instructions.  We have builtins for these.
8150 (define_insn "fpack16_vis"
8151   [(set (match_operand:V4QI 0 "register_operand" "=f")
8152         (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e")
8153                       (reg:DI GSR_REG)]
8154                       UNSPEC_FPACK16))]
8155   "TARGET_VIS"
8156   "fpack16\t%1, %0"
8157   [(set_attr "type" "fgm_pack")
8158    (set_attr "fptype" "double")])
8160 (define_insn "fpackfix_vis"
8161   [(set (match_operand:V2HI 0 "register_operand" "=f")
8162         (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e")
8163                       (reg:DI GSR_REG)]
8164                       UNSPEC_FPACKFIX))]
8165   "TARGET_VIS"
8166   "fpackfix\t%1, %0"
8167   [(set_attr "type" "fgm_pack")
8168    (set_attr "fptype" "double")])
8170 (define_insn "fpack32_vis"
8171   [(set (match_operand:V8QI 0 "register_operand" "=e")
8172         (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e")
8173                       (match_operand:V8QI 2 "register_operand" "e")
8174                       (reg:DI GSR_REG)]
8175                      UNSPEC_FPACK32))]
8176   "TARGET_VIS"
8177   "fpack32\t%1, %2, %0"
8178   [(set_attr "type" "fgm_pack")
8179    (set_attr "fptype" "double")])
8181 (define_insn "fexpand_vis"
8182   [(set (match_operand:V4HI 0 "register_operand" "=e")
8183         (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")]
8184          UNSPEC_FEXPAND))]
8185  "TARGET_VIS"
8186  "fexpand\t%1, %0"
8187  [(set_attr "type" "fga")
8188   (set_attr "fptype" "double")])
8190 (define_insn "fpmerge_vis"
8191   [(set (match_operand:V8QI 0 "register_operand" "=e")
8192         (vec_select:V8QI
8193           (vec_concat:V8QI (match_operand:V4QI 1 "register_operand" "f")
8194                            (match_operand:V4QI 2 "register_operand" "f"))
8195           (parallel [(const_int 0) (const_int 4)
8196                      (const_int 1) (const_int 5)
8197                      (const_int 2) (const_int 6)
8198                      (const_int 3) (const_int 7)])))]
8199  "TARGET_VIS"
8200  "fpmerge\t%1, %2, %0"
8201  [(set_attr "type" "fga")
8202   (set_attr "fptype" "double")])
8204 (define_insn "vec_interleave_lowv8qi"
8205   [(set (match_operand:V8QI 0 "register_operand" "=e")
8206         (vec_select:V8QI
8207           (vec_concat:V16QI (match_operand:V8QI 1 "register_operand" "f")
8208                             (match_operand:V8QI 2 "register_operand" "f"))
8209           (parallel [(const_int 0) (const_int 8)
8210                      (const_int 1) (const_int 9)
8211                      (const_int 2) (const_int 10)
8212                      (const_int 3) (const_int 11)])))]
8213  "TARGET_VIS"
8214  "fpmerge\t%L1, %L2, %0"
8215  [(set_attr "type" "fga")
8216   (set_attr "fptype" "double")])
8218 (define_insn "vec_interleave_highv8qi"
8219   [(set (match_operand:V8QI 0 "register_operand" "=e")
8220         (vec_select:V8QI
8221           (vec_concat:V16QI (match_operand:V8QI 1 "register_operand" "f")
8222                             (match_operand:V8QI 2 "register_operand" "f"))
8223           (parallel [(const_int 4) (const_int 12)
8224                      (const_int 5) (const_int 13)
8225                      (const_int 6) (const_int 14)
8226                      (const_int 7) (const_int 15)])))]
8227  "TARGET_VIS"
8228  "fpmerge\t%H1, %H2, %0"
8229  [(set_attr "type" "fga")
8230   (set_attr "fptype" "double")])
8232 ;; Partitioned multiply instructions
8233 (define_insn "fmul8x16_vis"
8234   [(set (match_operand:V4HI 0 "register_operand" "=e")
8235         (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8236                       (match_operand:V4HI 2 "register_operand" "e")]
8237          UNSPEC_MUL8))]
8238   "TARGET_VIS"
8239   "fmul8x16\t%1, %2, %0"
8240   [(set_attr "type" "fgm_mul")
8241    (set_attr "fptype" "double")])
8243 (define_insn "fmul8x16au_vis"
8244   [(set (match_operand:V4HI 0 "register_operand" "=e")
8245         (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8246                       (match_operand:V2HI 2 "register_operand" "f")]
8247          UNSPEC_MUL16AU))]
8248   "TARGET_VIS"
8249   "fmul8x16au\t%1, %2, %0"
8250   [(set_attr "type" "fgm_mul")
8251    (set_attr "fptype" "double")])
8253 (define_insn "fmul8x16al_vis"
8254   [(set (match_operand:V4HI 0 "register_operand" "=e")
8255         (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8256                       (match_operand:V2HI 2 "register_operand" "f")]
8257          UNSPEC_MUL16AL))]
8258   "TARGET_VIS"
8259   "fmul8x16al\t%1, %2, %0"
8260   [(set_attr "type" "fgm_mul")
8261    (set_attr "fptype" "double")])
8263 (define_insn "fmul8sux16_vis"
8264   [(set (match_operand:V4HI 0 "register_operand" "=e")
8265         (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
8266                       (match_operand:V4HI 2 "register_operand" "e")]
8267          UNSPEC_MUL8SU))]
8268   "TARGET_VIS"
8269   "fmul8sux16\t%1, %2, %0"
8270   [(set_attr "type" "fgm_mul")
8271    (set_attr "fptype" "double")])
8273 (define_insn "fmul8ulx16_vis"
8274   [(set (match_operand:V4HI 0 "register_operand" "=e")
8275         (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
8276                       (match_operand:V4HI 2 "register_operand" "e")]
8277          UNSPEC_MUL8UL))]
8278   "TARGET_VIS"
8279   "fmul8ulx16\t%1, %2, %0"
8280   [(set_attr "type" "fgm_mul")
8281    (set_attr "fptype" "double")])
8283 (define_insn "fmuld8sux16_vis"
8284   [(set (match_operand:V2SI 0 "register_operand" "=e")
8285         (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
8286                       (match_operand:V2HI 2 "register_operand" "f")]
8287          UNSPEC_MULDSU))]
8288   "TARGET_VIS"
8289   "fmuld8sux16\t%1, %2, %0"
8290   [(set_attr "type" "fgm_mul")
8291    (set_attr "fptype" "double")])
8293 (define_insn "fmuld8ulx16_vis"
8294   [(set (match_operand:V2SI 0 "register_operand" "=e")
8295         (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
8296                       (match_operand:V2HI 2 "register_operand" "f")]
8297          UNSPEC_MULDUL))]
8298   "TARGET_VIS"
8299   "fmuld8ulx16\t%1, %2, %0"
8300   [(set_attr "type" "fgm_mul")
8301    (set_attr "fptype" "double")])
8303 (define_expand "wrgsr_vis"
8304   [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" ""))]
8305   "TARGET_VIS"
8307   if (! TARGET_ARCH64)
8308     {
8309       emit_insn (gen_wrgsr_v8plus (operands[0]));
8310       DONE;
8311     }
8314 (define_insn "*wrgsr_sp64"
8315   [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" "rI"))]
8316   "TARGET_VIS && TARGET_ARCH64"
8317   "wr\t%%g0, %0, %%gsr"
8318   [(set_attr "type" "gsr")])
8320 (define_insn "wrgsr_v8plus"
8321   [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" "I,r"))
8322    (clobber (match_scratch:SI 1 "=X,&h"))]
8323   "TARGET_VIS && ! TARGET_ARCH64"
8325   if (GET_CODE (operands[0]) == CONST_INT
8326       || sparc_check_64 (operands[0], insn))
8327     return "wr\t%%g0, %0, %%gsr";
8329   output_asm_insn("srl\t%L0, 0, %L0", operands);
8330   return "sllx\t%H0, 32, %1\n\tor\t%L0, %1, %1\n\twr\t%%g0, %1, %%gsr";
8332   [(set_attr "type" "multi")])
8334 (define_expand "rdgsr_vis"
8335   [(set (match_operand:DI 0 "register_operand" "") (reg:DI GSR_REG))]
8336   "TARGET_VIS"
8338   if (! TARGET_ARCH64)
8339     {
8340       emit_insn (gen_rdgsr_v8plus (operands[0]));
8341       DONE;
8342     }
8345 (define_insn "*rdgsr_sp64"
8346   [(set (match_operand:DI 0 "register_operand" "=r") (reg:DI GSR_REG))]
8347   "TARGET_VIS && TARGET_ARCH64"
8348   "rd\t%%gsr, %0"
8349   [(set_attr "type" "gsr")])
8351 (define_insn "rdgsr_v8plus"
8352   [(set (match_operand:DI 0 "register_operand" "=r") (reg:DI GSR_REG))
8353    (clobber (match_scratch:SI 1 "=&h"))]
8354   "TARGET_VIS && ! TARGET_ARCH64"
8356   return "rd\t%%gsr, %1\n\tsrlx\t%1, 32, %H0\n\tmov %1, %L0";
8358   [(set_attr "type" "multi")])
8360 ;; Using faligndata only makes sense after an alignaddr since the choice of
8361 ;; bytes to take out of each operand is dependent on the results of the last
8362 ;; alignaddr.
8363 (define_insn "faligndata<VM64:mode>_vis"
8364   [(set (match_operand:VM64 0 "register_operand" "=e")
8365         (unspec:VM64 [(match_operand:VM64 1 "register_operand" "e")
8366                       (match_operand:VM64 2 "register_operand" "e")
8367                       (reg:DI GSR_REG)]
8368          UNSPEC_ALIGNDATA))]
8369   "TARGET_VIS"
8370   "faligndata\t%1, %2, %0"
8371   [(set_attr "type" "fga")
8372    (set_attr "fptype" "double")])
8374 (define_insn "alignaddrsi_vis"
8375   [(set (match_operand:SI 0 "register_operand" "=r")
8376         (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
8377                  (match_operand:SI 2 "register_or_zero_operand" "rJ")))
8378    (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8379         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
8380   "TARGET_VIS"
8381   "alignaddr\t%r1, %r2, %0"
8382   [(set_attr "type" "gsr")])
8384 (define_insn "alignaddrdi_vis"
8385   [(set (match_operand:DI 0 "register_operand" "=r")
8386         (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
8387                  (match_operand:DI 2 "register_or_zero_operand" "rJ")))
8388    (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8389         (plus:DI (match_dup 1) (match_dup 2)))]
8390   "TARGET_VIS"
8391   "alignaddr\t%r1, %r2, %0"
8392   [(set_attr "type" "gsr")])
8394 (define_insn "alignaddrlsi_vis"
8395   [(set (match_operand:SI 0 "register_operand" "=r")
8396         (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
8397                  (match_operand:SI 2 "register_or_zero_operand" "rJ")))
8398    (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8399         (xor:DI (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2)))
8400                 (const_int 7)))]
8401   "TARGET_VIS"
8402   "alignaddrl\t%r1, %r2, %0"
8403   [(set_attr "type" "gsr")])
8405 (define_insn "alignaddrldi_vis"
8406   [(set (match_operand:DI 0 "register_operand" "=r")
8407         (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
8408                  (match_operand:DI 2 "register_or_zero_operand" "rJ")))
8409    (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8410         (xor:DI (plus:DI (match_dup 1) (match_dup 2))
8411                 (const_int 7)))]
8412   "TARGET_VIS"
8413   "alignaddrl\t%r1, %r2, %0"
8414   [(set_attr "type" "gsr")])
8416 (define_insn "pdist_vis"
8417   [(set (match_operand:DI 0 "register_operand" "=e")
8418         (unspec:DI [(match_operand:V8QI 1 "register_operand" "e")
8419                     (match_operand:V8QI 2 "register_operand" "e")
8420                     (match_operand:DI 3 "register_operand" "0")]
8421          UNSPEC_PDIST))]
8422   "TARGET_VIS"
8423   "pdist\t%1, %2, %0"
8424   [(set_attr "type" "pdist")
8425    (set_attr "fptype" "double")])
8427 ;; Edge instructions produce condition codes equivalent to a 'subcc'
8428 ;; with the same operands.
8429 (define_insn "edge8<P:mode>_vis"
8430   [(set (reg:CC_NOOV CC_REG)
8431         (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8432                                   (match_operand:P 2 "register_or_zero_operand" "rJ"))
8433                          (const_int 0)))
8434    (set (match_operand:P 0 "register_operand" "=r")
8435         (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8))]
8436   "TARGET_VIS"
8437   "edge8\t%r1, %r2, %0"
8438   [(set_attr "type" "edge")])
8440 (define_insn "edge8l<P:mode>_vis"
8441   [(set (reg:CC_NOOV CC_REG)
8442         (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8443                                   (match_operand:P 2 "register_or_zero_operand" "rJ"))
8444                          (const_int 0)))
8445    (set (match_operand:P 0 "register_operand" "=r")
8446         (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8L))]
8447   "TARGET_VIS"
8448   "edge8l\t%r1, %r2, %0"
8449   [(set_attr "type" "edge")])
8451 (define_insn "edge16<P:mode>_vis"
8452   [(set (reg:CC_NOOV CC_REG)
8453         (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8454                                   (match_operand:P 2 "register_or_zero_operand" "rJ"))
8455                          (const_int 0)))
8456    (set (match_operand:P 0 "register_operand" "=r")
8457         (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16))]
8458   "TARGET_VIS"
8459   "edge16\t%r1, %r2, %0"
8460   [(set_attr "type" "edge")])
8462 (define_insn "edge16l<P:mode>_vis"
8463   [(set (reg:CC_NOOV CC_REG)
8464         (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8465                                   (match_operand:P 2 "register_or_zero_operand" "rJ"))
8466                          (const_int 0)))
8467    (set (match_operand:P 0 "register_operand" "=r")
8468         (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16L))]
8469   "TARGET_VIS"
8470   "edge16l\t%r1, %r2, %0"
8471   [(set_attr "type" "edge")])
8473 (define_insn "edge32<P:mode>_vis"
8474   [(set (reg:CC_NOOV CC_REG)
8475         (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8476                                   (match_operand:P 2 "register_or_zero_operand" "rJ"))
8477                          (const_int 0)))
8478    (set (match_operand:P 0 "register_operand" "=r")
8479         (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32))]
8480   "TARGET_VIS"
8481   "edge32\t%r1, %r2, %0"
8482   [(set_attr "type" "edge")])
8484 (define_insn "edge32l<P:mode>_vis"
8485   [(set (reg:CC_NOOV CC_REG)
8486         (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8487                                   (match_operand:P 2 "register_or_zero_operand" "rJ"))
8488                          (const_int 0)))
8489    (set (match_operand:P 0 "register_operand" "=r")
8490         (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32L))]
8491   "TARGET_VIS"
8492   "edge32l\t%r1, %r2, %0"
8493   [(set_attr "type" "edge")])
8495 (define_code_iterator gcond [le ne gt eq])
8496 (define_mode_iterator GCM [V4HI V2SI])
8497 (define_mode_attr gcm_name [(V4HI "16") (V2SI "32")])
8499 (define_insn "fcmp<code><GCM:gcm_name><P:mode>_vis"
8500   [(set (match_operand:P 0 "register_operand" "=r")
8501         (unspec:P [(gcond:GCM (match_operand:GCM 1 "register_operand" "e")
8502                               (match_operand:GCM 2 "register_operand" "e"))]
8503          UNSPEC_FCMP))]
8504   "TARGET_VIS"
8505   "fcmp<code><GCM:gcm_name>\t%1, %2, %0"
8506   [(set_attr "type" "visl")
8507    (set_attr "fptype" "double")])
8509 (define_expand "vcond<mode><mode>"
8510   [(match_operand:GCM 0 "register_operand" "")
8511    (match_operand:GCM 1 "register_operand" "")
8512    (match_operand:GCM 2 "register_operand" "")
8513    (match_operator 3 ""
8514      [(match_operand:GCM 4 "register_operand" "")
8515       (match_operand:GCM 5 "register_operand" "")])]
8516   "TARGET_VIS3"
8518   sparc_expand_vcond (<MODE>mode, operands,
8519                       UNSPEC_CMASK<gcm_name>,
8520                       UNSPEC_FCMP);
8521   DONE;
8524 (define_expand "vconduv8qiv8qi"
8525   [(match_operand:V8QI 0 "register_operand" "")
8526    (match_operand:V8QI 1 "register_operand" "")
8527    (match_operand:V8QI 2 "register_operand" "")
8528    (match_operator 3 ""
8529      [(match_operand:V8QI 4 "register_operand" "")
8530       (match_operand:V8QI 5 "register_operand" "")])]
8531   "TARGET_VIS3"
8533   sparc_expand_vcond (V8QImode, operands,
8534                       UNSPEC_CMASK8,
8535                       UNSPEC_FUCMP);
8536   DONE;
8539 (define_insn "array8<P:mode>_vis"
8540   [(set (match_operand:P 0 "register_operand" "=r")
8541         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8542                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
8543                   UNSPEC_ARRAY8))]
8544   "TARGET_VIS"
8545   "array8\t%r1, %r2, %0"
8546   [(set_attr "type" "array")])
8548 (define_insn "array16<P:mode>_vis"
8549   [(set (match_operand:P 0 "register_operand" "=r")
8550         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8551                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
8552                   UNSPEC_ARRAY16))]
8553   "TARGET_VIS"
8554   "array16\t%r1, %r2, %0"
8555   [(set_attr "type" "array")])
8557 (define_insn "array32<P:mode>_vis"
8558   [(set (match_operand:P 0 "register_operand" "=r")
8559         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8560                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
8561                   UNSPEC_ARRAY32))]
8562   "TARGET_VIS"
8563   "array32\t%r1, %r2, %0"
8564   [(set_attr "type" "array")])
8566 (define_insn "bmaskdi_vis"
8567   [(set (match_operand:DI 0 "register_operand" "=r")
8568         (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
8569                  (match_operand:DI 2 "register_or_zero_operand" "rJ")))
8570    (set (zero_extract:DI (reg:DI GSR_REG) (const_int 32) (const_int 32))
8571         (plus:DI (match_dup 1) (match_dup 2)))]
8572   "TARGET_VIS2"
8573   "bmask\t%r1, %r2, %0"
8574   [(set_attr "type" "array")])
8576 (define_insn "bmasksi_vis"
8577   [(set (match_operand:SI 0 "register_operand" "=r")
8578         (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
8579                  (match_operand:SI 2 "register_or_zero_operand" "rJ")))
8580    (set (zero_extract:DI (reg:DI GSR_REG) (const_int 32) (const_int 32))
8581         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
8582   "TARGET_VIS2"
8583   "bmask\t%r1, %r2, %0"
8584   [(set_attr "type" "array")])
8586 (define_insn "bshuffle<VM64:mode>_vis"
8587   [(set (match_operand:VM64 0 "register_operand" "=e")
8588         (unspec:VM64 [(match_operand:VM64 1 "register_operand" "e")
8589                       (match_operand:VM64 2 "register_operand" "e")
8590                       (reg:DI GSR_REG)]
8591                      UNSPEC_BSHUFFLE))]
8592   "TARGET_VIS2"
8593   "bshuffle\t%1, %2, %0"
8594   [(set_attr "type" "fga")
8595    (set_attr "fptype" "double")])
8597 ;; The rtl expanders will happily convert constant permutations on other
8598 ;; modes down to V8QI.  Rely on this to avoid the complexity of the byte
8599 ;; order of the permutation.
8600 (define_expand "vec_perm_constv8qi"
8601   [(match_operand:V8QI 0 "register_operand" "")
8602    (match_operand:V8QI 1 "register_operand" "")
8603    (match_operand:V8QI 2 "register_operand" "")
8604    (match_operand:V8QI 3 "" "")]
8605   "TARGET_VIS2"
8607   unsigned int i, mask;
8608   rtx sel = operands[3];
8610   for (i = mask = 0; i < 8; ++i)
8611     mask |= (INTVAL (XVECEXP (sel, 0, i)) & 0xf) << (28 - i*4);
8612   sel = force_reg (SImode, gen_int_mode (mask, SImode));
8614   emit_insn (gen_bmasksi_vis (gen_rtx_REG (SImode, 0), sel, const0_rtx));
8615   emit_insn (gen_bshufflev8qi_vis (operands[0], operands[1], operands[2]));
8616   DONE;
8619 ;; Unlike constant permutation, we can vastly simplify the compression of
8620 ;; the 64-bit selector input to the 32-bit %gsr value by knowing what the
8621 ;; width of the input is.
8622 (define_expand "vec_perm<mode>"
8623   [(match_operand:VM64 0 "register_operand" "")
8624    (match_operand:VM64 1 "register_operand" "")
8625    (match_operand:VM64 2 "register_operand" "")
8626    (match_operand:VM64 3 "register_operand" "")]
8627   "TARGET_VIS2"
8629   sparc_expand_vec_perm_bmask (<MODE>mode, operands[3]);
8630   emit_insn (gen_bshuffle<mode>_vis (operands[0], operands[1], operands[2]));
8631   DONE;
8634 ;; VIS 2.0 adds edge variants which do not set the condition codes
8635 (define_insn "edge8n<P:mode>_vis"
8636   [(set (match_operand:P 0 "register_operand" "=r")
8637         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8638                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
8639                   UNSPEC_EDGE8N))]
8640   "TARGET_VIS2"
8641   "edge8n\t%r1, %r2, %0"
8642   [(set_attr "type" "edgen")])
8644 (define_insn "edge8ln<P:mode>_vis"
8645   [(set (match_operand:P 0 "register_operand" "=r")
8646         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8647                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
8648                   UNSPEC_EDGE8LN))]
8649   "TARGET_VIS2"
8650   "edge8ln\t%r1, %r2, %0"
8651   [(set_attr "type" "edgen")])
8653 (define_insn "edge16n<P:mode>_vis"
8654   [(set (match_operand:P 0 "register_operand" "=r")
8655         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8656                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
8657                   UNSPEC_EDGE16N))]
8658   "TARGET_VIS2"
8659   "edge16n\t%r1, %r2, %0"
8660   [(set_attr "type" "edgen")])
8662 (define_insn "edge16ln<P:mode>_vis"
8663   [(set (match_operand:P 0 "register_operand" "=r")
8664         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8665                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
8666                   UNSPEC_EDGE16LN))]
8667   "TARGET_VIS2"
8668   "edge16ln\t%r1, %r2, %0"
8669   [(set_attr "type" "edgen")])
8671 (define_insn "edge32n<P:mode>_vis"
8672   [(set (match_operand:P 0 "register_operand" "=r")
8673         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8674                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
8675                   UNSPEC_EDGE32N))]
8676   "TARGET_VIS2"
8677   "edge32n\t%r1, %r2, %0"
8678   [(set_attr "type" "edgen")])
8680 (define_insn "edge32ln<P:mode>_vis"
8681   [(set (match_operand:P 0 "register_operand" "=r")
8682         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8683                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
8684                   UNSPEC_EDGE32LN))]
8685   "TARGET_VIS2"
8686   "edge32ln\t%r1, %r2, %0"
8687   [(set_attr "type" "edge")])
8689 ;; Conditional moves are possible via fcmpX --> cmaskX -> bshuffle
8690 (define_insn "cmask8<P:mode>_vis"
8691   [(set (reg:DI GSR_REG)
8692         (unspec:DI [(match_operand:P 0 "register_or_zero_operand" "rJ")
8693                     (reg:DI GSR_REG)]
8694                    UNSPEC_CMASK8))]
8695   "TARGET_VIS3"
8696   "cmask8\t%r0"
8697   [(set_attr "type" "fga")])
8699 (define_insn "cmask16<P:mode>_vis"
8700   [(set (reg:DI GSR_REG)
8701         (unspec:DI [(match_operand:P 0 "register_or_zero_operand" "rJ")
8702                     (reg:DI GSR_REG)]
8703                    UNSPEC_CMASK16))]
8704   "TARGET_VIS3"
8705   "cmask16\t%r0"
8706   [(set_attr "type" "fga")])
8708 (define_insn "cmask32<P:mode>_vis"
8709   [(set (reg:DI GSR_REG)
8710         (unspec:DI [(match_operand:P 0 "register_or_zero_operand" "rJ")
8711                     (reg:DI GSR_REG)]
8712                    UNSPEC_CMASK32))]
8713   "TARGET_VIS3"
8714   "cmask32\t%r0"
8715   [(set_attr "type" "fga")])
8717 (define_insn "fchksm16_vis"
8718   [(set (match_operand:V4HI 0 "register_operand" "=e")
8719         (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "e")
8720                       (match_operand:V4HI 2 "register_operand" "e")]
8721                      UNSPEC_FCHKSM16))]
8722   "TARGET_VIS3"
8723   "fchksm16\t%1, %2, %0"
8724   [(set_attr "type" "fga")])
8726 (define_code_iterator vis3_shift [ashift ss_ashift lshiftrt ashiftrt])
8727 (define_code_attr vis3_shift_insn
8728   [(ashift "fsll") (ss_ashift "fslas") (lshiftrt "fsrl") (ashiftrt "fsra")])
8729 (define_code_attr vis3_shift_patname
8730   [(ashift "ashl") (ss_ashift "ssashl") (lshiftrt "lshr") (ashiftrt "ashr")])
8731    
8732 (define_insn "v<vis3_shift_patname><mode>3"
8733   [(set (match_operand:GCM 0 "register_operand" "=<vconstr>")
8734         (vis3_shift:GCM (match_operand:GCM 1 "register_operand" "<vconstr>")
8735                         (match_operand:GCM 2 "register_operand" "<vconstr>")))]
8736   "TARGET_VIS3"
8737   "<vis3_shift_insn><vbits>\t%1, %2, %0"
8738   [(set_attr "type" "fga")])
8740 (define_insn "pdistn<mode>_vis"
8741   [(set (match_operand:P 0 "register_operand" "=r")
8742         (unspec:P [(match_operand:V8QI 1 "register_operand" "e")
8743                    (match_operand:V8QI 2 "register_operand" "e")]
8744          UNSPEC_PDISTN))]
8745   "TARGET_VIS3"
8746   "pdistn\t%1, %2, %0"
8747   [(set_attr "type" "pdistn")
8748    (set_attr "fptype" "double")])
8750 (define_insn "fmean16_vis"
8751   [(set (match_operand:V4HI 0 "register_operand" "=e")
8752         (truncate:V4HI
8753           (lshiftrt:V4SI
8754             (plus:V4SI
8755               (plus:V4SI
8756                 (zero_extend:V4SI
8757                   (match_operand:V4HI 1 "register_operand" "e"))
8758                 (zero_extend:V4SI
8759                   (match_operand:V4HI 2 "register_operand" "e")))
8760               (const_vector:V4SI [(const_int 1) (const_int 1)
8761                                   (const_int 1) (const_int 1)]))
8762           (const_int 1))))]
8763   "TARGET_VIS3"
8764   "fmean16\t%1, %2, %0"
8765   [(set_attr "type" "fga")])
8767 (define_insn "fp<plusminus_insn>64_vis"
8768   [(set (match_operand:V1DI 0 "register_operand" "=e")
8769         (plusminus:V1DI (match_operand:V1DI 1 "register_operand" "e")
8770                         (match_operand:V1DI 2 "register_operand" "e")))]
8771   "TARGET_VIS3"
8772   "fp<plusminus_insn>64\t%1, %2, %0"
8773   [(set_attr "type" "fga")])
8775 (define_mode_iterator VASS [V4HI V2SI V2HI V1SI])
8776 (define_code_iterator vis3_addsub_ss [ss_plus ss_minus])
8777 (define_code_attr vis3_addsub_ss_insn
8778   [(ss_plus "fpadds") (ss_minus "fpsubs")])
8779 (define_code_attr vis3_addsub_ss_patname
8780   [(ss_plus "ssadd") (ss_minus "sssub")])
8782 (define_insn "<vis3_addsub_ss_patname><mode>3"
8783   [(set (match_operand:VASS 0 "register_operand" "=<vconstr>")
8784         (vis3_addsub_ss:VASS (match_operand:VASS 1 "register_operand" "<vconstr>")
8785                              (match_operand:VASS 2 "register_operand" "<vconstr>")))]
8786   "TARGET_VIS3"
8787   "<vis3_addsub_ss_insn><vbits>\t%1, %2, %0"
8788   [(set_attr "type" "fga")])
8790 (define_insn "fucmp<code>8<P:mode>_vis"
8791   [(set (match_operand:P 0 "register_operand" "=r")
8792         (unspec:P [(gcond:V8QI (match_operand:V8QI 1 "register_operand" "e")
8793                                (match_operand:V8QI 2 "register_operand" "e"))]
8794          UNSPEC_FUCMP))]
8795   "TARGET_VIS3"
8796   "fucmp<code>8\t%1, %2, %0"
8797   [(set_attr "type" "visl")])
8799 (define_insn "*naddsf3"
8800   [(set (match_operand:SF 0 "register_operand" "=f")
8801         (neg:SF (plus:SF (match_operand:SF 1 "register_operand" "f")
8802                          (match_operand:SF 2 "register_operand" "f"))))]
8803   "TARGET_VIS3"
8804   "fnadds\t%1, %2, %0"
8805   [(set_attr "type" "fp")])
8807 (define_insn "*nadddf3"
8808   [(set (match_operand:DF 0 "register_operand" "=e")
8809         (neg:DF (plus:DF (match_operand:DF 1 "register_operand" "e")
8810                          (match_operand:DF 2 "register_operand" "e"))))]
8811   "TARGET_VIS3"
8812   "fnaddd\t%1, %2, %0"
8813   [(set_attr "type" "fp")
8814    (set_attr "fptype" "double")])
8816 (define_insn "*nmulsf3"
8817   [(set (match_operand:SF 0 "register_operand" "=f")
8818         (mult:SF (neg:SF (match_operand:SF 1 "register_operand" "f"))
8819                  (match_operand:SF 2 "register_operand" "f")))]
8820   "TARGET_VIS3"
8821   "fnmuls\t%1, %2, %0"
8822   [(set_attr "type" "fpmul")])
8824 (define_insn "*nmuldf3"
8825   [(set (match_operand:DF 0 "register_operand" "=e")
8826         (mult:DF (neg:DF (match_operand:DF 1 "register_operand" "e"))
8827                  (match_operand:DF 2 "register_operand" "e")))]
8828   "TARGET_VIS3"
8829   "fnmuld\t%1, %2, %0"
8830   [(set_attr "type" "fpmul")
8831    (set_attr "fptype" "double")])
8833 (define_insn "*nmuldf3_extend"
8834   [(set (match_operand:DF 0 "register_operand" "=e")
8835         (mult:DF (neg:DF (float_extend:DF
8836                            (match_operand:SF 1 "register_operand" "f")))
8837                  (float_extend:DF
8838                    (match_operand:SF 2 "register_operand" "f"))))]
8839   "TARGET_VIS3"
8840   "fnsmuld\t%1, %2, %0"
8841   [(set_attr "type" "fpmul")
8842    (set_attr "fptype" "double")])
8844 (define_insn "fhaddsf_vis"
8845   [(set (match_operand:SF 0 "register_operand" "=f")
8846         (unspec:SF [(match_operand:SF 1 "register_operand" "f")
8847                     (match_operand:SF 2 "register_operand" "f")]
8848                    UNSPEC_FHADD))]
8849   "TARGET_VIS3"
8850   "fhadds\t%1, %2, %0"
8851   [(set_attr "type" "fp")])
8853 (define_insn "fhadddf_vis"
8854   [(set (match_operand:DF 0 "register_operand" "=f")
8855         (unspec:DF [(match_operand:DF 1 "register_operand" "f")
8856                     (match_operand:DF 2 "register_operand" "f")]
8857                    UNSPEC_FHADD))]
8858   "TARGET_VIS3"
8859   "fhaddd\t%1, %2, %0"
8860   [(set_attr "type" "fp")
8861    (set_attr "fptype" "double")])
8863 (define_insn "fhsubsf_vis"
8864   [(set (match_operand:SF 0 "register_operand" "=f")
8865         (unspec:SF [(match_operand:SF 1 "register_operand" "f")
8866                     (match_operand:SF 2 "register_operand" "f")]
8867                    UNSPEC_FHSUB))]
8868   "TARGET_VIS3"
8869   "fhsubs\t%1, %2, %0"
8870   [(set_attr "type" "fp")])
8872 (define_insn "fhsubdf_vis"
8873   [(set (match_operand:DF 0 "register_operand" "=f")
8874         (unspec:DF [(match_operand:DF 1 "register_operand" "f")
8875                     (match_operand:DF 2 "register_operand" "f")]
8876                    UNSPEC_FHSUB))]
8877   "TARGET_VIS3"
8878   "fhsubd\t%1, %2, %0"
8879   [(set_attr "type" "fp")
8880    (set_attr "fptype" "double")])
8882 (define_insn "fnhaddsf_vis"
8883   [(set (match_operand:SF 0 "register_operand" "=f")
8884         (neg:SF (unspec:SF [(match_operand:SF 1 "register_operand" "f")
8885                             (match_operand:SF 2 "register_operand" "f")]
8886                            UNSPEC_FHADD)))]
8887   "TARGET_VIS3"
8888   "fnhadds\t%1, %2, %0"
8889   [(set_attr "type" "fp")])
8891 (define_insn "fnhadddf_vis"
8892   [(set (match_operand:DF 0 "register_operand" "=f")
8893         (neg:DF (unspec:DF [(match_operand:DF 1 "register_operand" "f")
8894                             (match_operand:DF 2 "register_operand" "f")]
8895                            UNSPEC_FHADD)))]
8896   "TARGET_VIS3"
8897   "fnhaddd\t%1, %2, %0"
8898   [(set_attr "type" "fp")
8899    (set_attr "fptype" "double")])
8901 (define_expand "umulxhi_vis"
8902   [(set (match_operand:DI 0 "register_operand" "")
8903         (truncate:DI
8904           (lshiftrt:TI
8905             (mult:TI (zero_extend:TI
8906                        (match_operand:DI 1 "arith_operand" ""))
8907                      (zero_extend:TI
8908                        (match_operand:DI 2 "arith_operand" "")))
8909            (const_int 64))))]
8910  "TARGET_VIS3"
8912   if (! TARGET_ARCH64)
8913     {
8914       emit_insn (gen_umulxhi_v8plus (operands[0], operands[1], operands[2]));
8915       DONE;
8916     }
8919 (define_insn "*umulxhi_sp64"
8920   [(set (match_operand:DI 0 "register_operand" "=r")
8921         (truncate:DI
8922           (lshiftrt:TI
8923             (mult:TI (zero_extend:TI
8924                        (match_operand:DI 1 "arith_operand" "%r"))
8925                      (zero_extend:TI
8926                        (match_operand:DI 2 "arith_operand" "rI")))
8927            (const_int 64))))]
8928   "TARGET_VIS3 && TARGET_ARCH64"
8929   "umulxhi\t%1, %2, %0"
8930   [(set_attr "type" "imul")])
8932 (define_insn "umulxhi_v8plus"
8933   [(set (match_operand:DI 0 "register_operand" "=r,h")
8934         (truncate:DI
8935           (lshiftrt:TI
8936             (mult:TI (zero_extend:TI
8937                        (match_operand:DI 1 "arith_operand" "%r,0"))
8938                      (zero_extend:TI
8939                        (match_operand:DI 2 "arith_operand" "rI,rI")))
8940            (const_int 64))))
8941    (clobber (match_scratch:SI 3 "=&h,X"))
8942    (clobber (match_scratch:SI 4 "=&h,X"))]
8943   "TARGET_VIS3 && ! TARGET_ARCH64"
8944   "* return output_v8plus_mult (insn, operands, \"umulxhi\");"
8945   [(set_attr "type" "imul")
8946    (set_attr "length" "9,8")])
8948 (define_expand "xmulx_vis"
8949   [(set (match_operand:DI 0 "register_operand" "")
8950         (truncate:DI
8951           (unspec:TI [(zero_extend:TI
8952                         (match_operand:DI 1 "arith_operand" ""))
8953                       (zero_extend:TI
8954                         (match_operand:DI 2 "arith_operand" ""))]
8955            UNSPEC_XMUL)))]
8956   "TARGET_VIS3"
8958   if (! TARGET_ARCH64)
8959     {
8960       emit_insn (gen_xmulx_v8plus (operands[0], operands[1], operands[2]));
8961       DONE;
8962     }
8965 (define_insn "*xmulx_sp64"
8966   [(set (match_operand:DI 0 "register_operand" "=r")
8967         (truncate:DI
8968           (unspec:TI [(zero_extend:TI
8969                         (match_operand:DI 1 "arith_operand" "%r"))
8970                       (zero_extend:TI
8971                         (match_operand:DI 2 "arith_operand" "rI"))]
8972            UNSPEC_XMUL)))]
8973   "TARGET_VIS3 && TARGET_ARCH64"
8974   "xmulx\t%1, %2, %0"
8975   [(set_attr "type" "imul")])
8977 (define_insn "xmulx_v8plus"
8978   [(set (match_operand:DI 0 "register_operand" "=r,h")
8979         (truncate:DI
8980           (unspec:TI [(zero_extend:TI
8981                         (match_operand:DI 1 "arith_operand" "%r,0"))
8982                       (zero_extend:TI
8983                         (match_operand:DI 2 "arith_operand" "rI,rI"))]
8984            UNSPEC_XMUL)))
8985    (clobber (match_scratch:SI 3 "=&h,X"))
8986    (clobber (match_scratch:SI 4 "=&h,X"))]
8987   "TARGET_VIS3 && ! TARGET_ARCH64"
8988   "* return output_v8plus_mult (insn, operands, \"xmulx\");"
8989   [(set_attr "type" "imul")
8990    (set_attr "length" "9,8")])
8992 (define_expand "xmulxhi_vis"
8993   [(set (match_operand:DI 0 "register_operand" "")
8994         (truncate:DI
8995           (lshiftrt:TI
8996             (unspec:TI [(zero_extend:TI
8997                           (match_operand:DI 1 "arith_operand" ""))
8998                         (zero_extend:TI
8999                           (match_operand:DI 2 "arith_operand" ""))]
9000              UNSPEC_XMUL)
9001            (const_int 64))))]
9002   "TARGET_VIS3"
9004   if (! TARGET_ARCH64)
9005     {
9006       emit_insn (gen_xmulxhi_v8plus (operands[0], operands[1], operands[2]));
9007       DONE;
9008     }
9011 (define_insn "*xmulxhi_sp64"
9012   [(set (match_operand:DI 0 "register_operand" "=r")
9013         (truncate:DI
9014           (lshiftrt:TI
9015             (unspec:TI [(zero_extend:TI
9016                           (match_operand:DI 1 "arith_operand" "%r"))
9017                         (zero_extend:TI
9018                           (match_operand:DI 2 "arith_operand" "rI"))]
9019              UNSPEC_XMUL)
9020            (const_int 64))))]
9021   "TARGET_VIS3 && TARGET_ARCH64"
9022   "xmulxhi\t%1, %2, %0"
9023   [(set_attr "type" "imul")])
9025 (define_insn "xmulxhi_v8plus"
9026   [(set (match_operand:DI 0 "register_operand" "=r,h")
9027         (truncate:DI
9028           (lshiftrt:TI
9029             (unspec:TI [(zero_extend:TI
9030                           (match_operand:DI 1 "arith_operand" "%r,0"))
9031                         (zero_extend:TI
9032                           (match_operand:DI 2 "arith_operand" "rI,rI"))]
9033              UNSPEC_XMUL)
9034            (const_int 64))))
9035    (clobber (match_scratch:SI 3 "=&h,X"))
9036    (clobber (match_scratch:SI 4 "=&h,X"))]
9037   "TARGET_VIS3 && !TARGET_ARCH64"
9038   "* return output_v8plus_mult (insn, operands, \"xmulxhi\");"
9039   [(set_attr "type" "imul")
9040    (set_attr "length" "9,8")])
9042 (include "sync.md")