PR target/60941
[official-gcc.git] / gcc / config / sparc / sparc.md
blobe2a4669e05d297d568f71618c6611bcf85361ebc
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 ;; UltraSPARC-III integer load type.
428 (define_attr "us3load_type" "2cycle,3cycle"
429   (const_string "2cycle"))
431 (define_asm_attributes
432   [(set_attr "length" "2")
433    (set_attr "type" "multi")])
435 ;; Attributes for branch scheduling
436 (define_attr "in_call_delay" "false,true"
437   (symbol_ref "(eligible_for_call_delay (insn)
438                 ? IN_CALL_DELAY_TRUE : IN_CALL_DELAY_FALSE)"))
440 (define_attr "in_sibcall_delay" "false,true"
441   (symbol_ref "(eligible_for_sibcall_delay (insn)
442                 ? IN_SIBCALL_DELAY_TRUE : IN_SIBCALL_DELAY_FALSE)"))
444 (define_attr "in_return_delay" "false,true"
445   (symbol_ref "(eligible_for_return_delay (insn)
446                 ? IN_RETURN_DELAY_TRUE : IN_RETURN_DELAY_FALSE)"))
448 ;; ??? !v9: Should implement the notion of predelay slots for floating-point
449 ;; branches.  This would allow us to remove the nop always inserted before
450 ;; a floating point branch.
452 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
453 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
454 ;; This is because doing so will add several pipeline stalls to the path
455 ;; that the load/store did not come from.  Unfortunately, there is no way
456 ;; to prevent fill_eager_delay_slots from using load/store without completely
457 ;; disabling them.  For the SPEC benchmark set, this is a serious lose,
458 ;; because it prevents us from moving back the final store of inner loops.
460 (define_attr "in_branch_delay" "false,true"
461   (cond [(eq_attr "type" "uncond_branch,branch,cbcond,uncond_cbcond,call,sibcall,call_no_delay_slot,multi")
462            (const_string "false")
463          (and (eq_attr "fix_ut699" "true") (eq_attr "type" "load,sload"))
464            (const_string "false")
465          (and (eq_attr "fix_ut699" "true")
466               (and (eq_attr "type" "fpload,fp,fpmove,fpmul,fpdivs,fpsqrts")
467                    (eq_attr "fptype" "single")))
468            (const_string "false")
469          (eq_attr "length" "1")
470            (const_string "true")
471         ] (const_string "false")))
473 (define_delay (eq_attr "type" "call")
474   [(eq_attr "in_call_delay" "true") (nil) (nil)])
476 (define_delay (eq_attr "type" "sibcall")
477   [(eq_attr "in_sibcall_delay" "true") (nil) (nil)])
479 (define_delay (eq_attr "type" "return")
480   [(eq_attr "in_return_delay" "true") (nil) (nil)])
482 (define_delay (eq_attr "type" "branch")
483   [(eq_attr "in_branch_delay" "true") (nil) (eq_attr "in_branch_delay" "true")])
485 (define_delay (eq_attr "type" "uncond_branch")
486   [(eq_attr "in_branch_delay" "true") (nil) (nil)])
489 ;; Include SPARC DFA schedulers
491 (include "cypress.md")
492 (include "supersparc.md")
493 (include "hypersparc.md")
494 (include "leon.md")
495 (include "sparclet.md")
496 (include "ultra1_2.md")
497 (include "ultra3.md")
498 (include "niagara.md")
499 (include "niagara2.md")
500 (include "niagara4.md")
503 ;; Operand and operator predicates and constraints
505 (include "predicates.md")
506 (include "constraints.md")
509 ;; Compare instructions.
511 ;; These are just the DEFINE_INSNs to match the patterns and the
512 ;; DEFINE_SPLITs for some of the scc insns that actually require
513 ;; more than one machine instruction.  DEFINE_EXPANDs are further down.
515 ;; The compare DEFINE_INSNs.
517 (define_insn "*cmpsi_insn"
518   [(set (reg:CC CC_REG)
519         (compare:CC (match_operand:SI 0 "register_operand" "r")
520                     (match_operand:SI 1 "arith_operand" "rI")))]
521   ""
522   "cmp\t%0, %1"
523   [(set_attr "type" "compare")])
525 (define_insn "*cmpdi_sp64"
526   [(set (reg:CCX CC_REG)
527         (compare:CCX (match_operand:DI 0 "register_operand" "r")
528                      (match_operand:DI 1 "arith_operand" "rI")))]
529   "TARGET_ARCH64"
530   "cmp\t%0, %1"
531   [(set_attr "type" "compare")])
533 (define_insn "*cmpsf_fpe"
534   [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
535         (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
536                        (match_operand:SF 2 "register_operand" "f")))]
537   "TARGET_FPU"
539   if (TARGET_V9)
540     return "fcmpes\t%0, %1, %2";
541   return "fcmpes\t%1, %2";
543   [(set_attr "type" "fpcmp")])
545 (define_insn "*cmpdf_fpe"
546   [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
547         (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
548                        (match_operand:DF 2 "register_operand" "e")))]
549   "TARGET_FPU"
551   if (TARGET_V9)
552     return "fcmped\t%0, %1, %2";
553   return "fcmped\t%1, %2";
555   [(set_attr "type" "fpcmp")
556    (set_attr "fptype" "double")])
558 (define_insn "*cmptf_fpe"
559   [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
560         (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
561                        (match_operand:TF 2 "register_operand" "e")))]
562   "TARGET_FPU && TARGET_HARD_QUAD"
564   if (TARGET_V9)
565     return "fcmpeq\t%0, %1, %2";
566   return "fcmpeq\t%1, %2";
568   [(set_attr "type" "fpcmp")])
570 (define_insn "*cmpsf_fp"
571   [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
572         (compare:CCFP (match_operand:SF 1 "register_operand" "f")
573                       (match_operand:SF 2 "register_operand" "f")))]
574   "TARGET_FPU"
576   if (TARGET_V9)
577     return "fcmps\t%0, %1, %2";
578   return "fcmps\t%1, %2";
580   [(set_attr "type" "fpcmp")])
582 (define_insn "*cmpdf_fp"
583   [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
584         (compare:CCFP (match_operand:DF 1 "register_operand" "e")
585                       (match_operand:DF 2 "register_operand" "e")))]
586   "TARGET_FPU"
588   if (TARGET_V9)
589     return "fcmpd\t%0, %1, %2";
590   return "fcmpd\t%1, %2";
592   [(set_attr "type" "fpcmp")
593    (set_attr "fptype" "double")])
595 (define_insn "*cmptf_fp"
596   [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
597         (compare:CCFP (match_operand:TF 1 "register_operand" "e")
598                       (match_operand:TF 2 "register_operand" "e")))]
599   "TARGET_FPU && TARGET_HARD_QUAD"
601   if (TARGET_V9)
602     return "fcmpq\t%0, %1, %2";
603   return "fcmpq\t%1, %2";
605   [(set_attr "type" "fpcmp")])
607 ;; Next come the scc insns.
609 ;; Note that the boolean result (operand 0) takes on DImode
610 ;; (not SImode) when TARGET_ARCH64.
612 (define_expand "cstoresi4"
613   [(use (match_operator 1 "comparison_operator"
614          [(match_operand:SI 2 "compare_operand" "")
615           (match_operand:SI 3 "arith_operand" "")]))
616    (clobber (match_operand:SI 0 "cstore_result_operand"))]
617   ""
619   if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
620     operands[2] = force_reg (SImode, operands[2]);
621   if (emit_scc_insn (operands)) DONE; else FAIL;
624 (define_expand "cstoredi4"
625   [(use (match_operator 1 "comparison_operator"
626          [(match_operand:DI 2 "compare_operand" "")
627           (match_operand:DI 3 "arith_operand" "")]))
628    (clobber (match_operand:SI 0 "cstore_result_operand"))]
629   "TARGET_ARCH64"
631   if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
632     operands[2] = force_reg (DImode, operands[2]);
633   if (emit_scc_insn (operands)) DONE; else FAIL;
636 (define_expand "cstore<F:mode>4"
637   [(use (match_operator 1 "comparison_operator"
638          [(match_operand:F 2 "register_operand" "")
639           (match_operand:F 3 "register_operand" "")]))
640    (clobber (match_operand:SI 0 "cstore_result_operand"))]
641   "TARGET_FPU"
642   { if (emit_scc_insn (operands)) DONE; else FAIL; })
646 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
647 ;; generate addcc/subcc instructions.
649 (define_expand "seqsi<P:mode>_special"
650   [(set (match_dup 3)
651         (xor:SI (match_operand:SI 1 "register_operand" "")
652                 (match_operand:SI 2 "register_operand" "")))
653    (parallel [(set (match_operand:P 0 "register_operand" "")
654                    (eq:P (match_dup 3) (const_int 0)))
655               (clobber (reg:CC CC_REG))])]
656   ""
657   { operands[3] = gen_reg_rtx (SImode); })
659 (define_expand "seqdi_special"
660   [(set (match_dup 3)
661         (xor:DI (match_operand:DI 1 "register_operand" "")
662                 (match_operand:DI 2 "register_operand" "")))
663    (set (match_operand:DI 0 "register_operand" "")
664         (eq:DI (match_dup 3) (const_int 0)))]
665   "TARGET_ARCH64"
666   { operands[3] = gen_reg_rtx (DImode); })
668 (define_expand "snesi<P:mode>_special"
669   [(set (match_dup 3)
670         (xor:SI (match_operand:SI 1 "register_operand" "")
671                 (match_operand:SI 2 "register_operand" "")))
672    (parallel [(set (match_operand:P 0 "register_operand" "")
673                    (ne:P (match_dup 3) (const_int 0)))
674               (clobber (reg:CC CC_REG))])]
675   ""
676   { operands[3] = gen_reg_rtx (SImode); })
678 (define_expand "snedi_special"
679   [(set (match_dup 3)
680         (xor:DI (match_operand:DI 1 "register_operand" "")
681                 (match_operand:DI 2 "register_operand" "")))
682    (set (match_operand:DI 0 "register_operand" "")
683         (ne:DI (match_dup 3) (const_int 0)))]
684   "TARGET_ARCH64 && ! TARGET_VIS3"
685   { operands[3] = gen_reg_rtx (DImode); })
687 (define_expand "snedi_special_vis3"
688   [(set (match_dup 3)
689         (xor:DI (match_operand:DI 1 "register_operand" "")
690                 (match_operand:DI 2 "register_operand" "")))
691    (parallel [(set (match_operand:DI 0 "register_operand" "")
692                    (ne:DI (match_dup 3) (const_int 0)))
693               (clobber (reg:CCX CC_REG))])]
694   "TARGET_ARCH64 && TARGET_VIS3"
695   { operands[3] = gen_reg_rtx (DImode); })
698 ;; Now the DEFINE_INSNs for the scc cases.
700 ;; The SEQ and SNE patterns are special because they can be done
701 ;; without any branching and do not involve a COMPARE.  We want
702 ;; them to always use the splits below so the results can be
703 ;; scheduled.
705 (define_insn_and_split "*snesi<P:mode>_zero"
706   [(set (match_operand:P 0 "register_operand" "=r")
707         (ne:P (match_operand:SI 1 "register_operand" "r")
708                (const_int 0)))
709    (clobber (reg:CC CC_REG))]
710   ""
711   "#"
712   ""
713   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
714                                            (const_int 0)))
715    (set (match_dup 0) (ltu:P (reg:CC CC_REG) (const_int 0)))]
716   ""
717   [(set_attr "length" "2")])
719 (define_insn_and_split "*neg_snesisi_zero"
720   [(set (match_operand:SI 0 "register_operand" "=r")
721         (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
722                        (const_int 0))))
723    (clobber (reg:CC CC_REG))]
724   ""
725   "#"
726   ""
727   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
728                                            (const_int 0)))
729    (set (match_dup 0) (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0))))]
730   ""
731   [(set_attr "length" "2")])
733 (define_insn_and_split "*neg_snesidi_zero"
734   [(set (match_operand:DI 0 "register_operand" "=r")
735         (neg:DI (ne:DI (match_operand:SI 1 "register_operand" "r")
736                        (const_int 0))))
737    (clobber (reg:CC CC_REG))]
738   "TARGET_ARCH64"
739   "#"
740   ""
741   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
742                                            (const_int 0)))
743    (set (match_dup 0) (sign_extend:DI (neg:SI (ltu:SI (reg:CC CC_REG)
744                                                       (const_int 0)))))]
745   ""
746   [(set_attr "length" "2")])
748 (define_insn_and_split "*snedi_zero"
749   [(set (match_operand:DI 0 "register_operand" "=&r")
750         (ne:DI (match_operand:DI 1 "register_operand" "r")
751                (const_int 0)))]
752   "TARGET_ARCH64 && ! TARGET_VIS3"
753   "#"
754   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
755   [(set (match_dup 0) (const_int 0))
756    (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
757                                               (const_int 0))
758                                        (const_int 1)
759                                        (match_dup 0)))]
760   ""
761   [(set_attr "length" "2")])
763 (define_insn_and_split "*snedi_zero_vis3"
764   [(set (match_operand:DI 0 "register_operand" "=r")
765         (ne:DI (match_operand:DI 1 "register_operand" "r")
766                (const_int 0)))
767    (clobber (reg:CCX CC_REG))]
768   "TARGET_ARCH64 && TARGET_VIS3"
769   "#"
770   ""
771   [(set (reg:CCX_NOOV CC_REG) (compare:CCX_NOOV (neg:DI (match_dup 1))
772                                                 (const_int 0)))
773    (set (match_dup 0) (ltu:DI (reg:CCX CC_REG) (const_int 0)))]
774   ""
775   [(set_attr "length" "2")])
777 (define_insn_and_split "*neg_snedi_zero"
778   [(set (match_operand:DI 0 "register_operand" "=&r")
779         (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
780                        (const_int 0))))]
781   "TARGET_ARCH64"
782   "#"
783   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
784   [(set (match_dup 0) (const_int 0))
785    (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
786                                               (const_int 0))
787                                        (const_int -1)
788                                        (match_dup 0)))]
789   ""
790   [(set_attr "length" "2")])
792 (define_insn_and_split "*snedi_zero_trunc"
793   [(set (match_operand:SI 0 "register_operand" "=&r")
794         (ne:SI (match_operand:DI 1 "register_operand" "r")
795                (const_int 0)))]
796   "TARGET_ARCH64 && ! TARGET_VIS3"
797   "#"
798   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
799   [(set (match_dup 0) (const_int 0))
800    (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
801                                               (const_int 0))
802                                        (const_int 1)
803                                        (match_dup 0)))]
804   ""
805   [(set_attr "length" "2")])
807 (define_insn_and_split "*snedi_zero_trunc_vis3"
808   [(set (match_operand:SI 0 "register_operand" "=r")
809         (ne:SI (match_operand:DI 1 "register_operand" "r")
810                (const_int 0)))
811    (clobber (reg:CCX CC_REG))]
812   "TARGET_ARCH64 && TARGET_VIS3"
813   "#"
814   ""
815   [(set (reg:CCX_NOOV CC_REG) (compare:CCX_NOOV (neg:DI (match_dup 1))
816                                                 (const_int 0)))
817    (set (match_dup 0) (ltu:SI (reg:CCX CC_REG) (const_int 0)))]
818   ""
819   [(set_attr "length" "2")])
821 (define_insn_and_split "*seqsi<P:mode>_zero"
822   [(set (match_operand:P 0 "register_operand" "=r")
823         (eq:P (match_operand:SI 1 "register_operand" "r")
824                (const_int 0)))
825    (clobber (reg:CC CC_REG))]
826   ""
827   "#"
828   ""
829   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
830                                            (const_int 0)))
831    (set (match_dup 0) (geu:P (reg:CC CC_REG) (const_int 0)))]
832   ""
833   [(set_attr "length" "2")])
835 (define_insn_and_split "*neg_seqsisi_zero"
836   [(set (match_operand:SI 0 "register_operand" "=r")
837         (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
838                        (const_int 0))))
839    (clobber (reg:CC CC_REG))]
840   ""
841   "#"
842   ""
843   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
844                                            (const_int 0)))
845    (set (match_dup 0) (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0))))]
846   ""
847   [(set_attr "length" "2")])
849 (define_insn_and_split "*neg_seqsidi_zero"
850   [(set (match_operand:DI 0 "register_operand" "=r")
851         (neg:DI (eq:DI (match_operand:SI 1 "register_operand" "r")
852                        (const_int 0))))
853    (clobber (reg:CC CC_REG))]
854   "TARGET_ARCH64"
855   "#"
856   "&& 1"
857   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
858                                            (const_int 0)))
859    (set (match_dup 0) (sign_extend:DI (neg:SI (geu:SI (reg:CC CC_REG)
860                                                       (const_int 0)))))]
861   ""
862   [(set_attr "length" "2")])
864 (define_insn_and_split "*seqdi_zero"
865   [(set (match_operand:DI 0 "register_operand" "=&r")
866         (eq:DI (match_operand:DI 1 "register_operand" "r")
867                (const_int 0)))]
868   "TARGET_ARCH64"
869   "#"
870   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
871   [(set (match_dup 0) (const_int 0))
872    (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
873                                               (const_int 0))
874                                        (const_int 1)
875                                        (match_dup 0)))]
876   ""
877   [(set_attr "length" "2")])
879 (define_insn_and_split "*neg_seqdi_zero"
880   [(set (match_operand:DI 0 "register_operand" "=&r")
881         (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
882                        (const_int 0))))]
883   "TARGET_ARCH64"
884   "#"
885   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
886   [(set (match_dup 0) (const_int 0))
887    (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
888                                               (const_int 0))
889                                        (const_int -1)
890                                        (match_dup 0)))]
891   ""
892   [(set_attr "length" "2")]) 
894 (define_insn_and_split "*seqdi_zero_trunc"
895   [(set (match_operand:SI 0 "register_operand" "=&r")
896         (eq:SI (match_operand:DI 1 "register_operand" "r")
897                (const_int 0)))]
898   "TARGET_ARCH64"
899   "#"
900   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
901   [(set (match_dup 0) (const_int 0))
902    (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
903                                               (const_int 0))
904                                        (const_int 1)
905                                        (match_dup 0)))]
906   ""
907   [(set_attr "length" "2")])
909 ;; We can also do (x + (i == 0)) and related, so put them in.
910 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
911 ;; versions for v9.
913 (define_insn_and_split "*x_plus_i_ne_0"
914   [(set (match_operand:SI 0 "register_operand" "=r")
915         (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
916                         (const_int 0))
917                  (match_operand:SI 2 "register_operand" "r")))
918    (clobber (reg:CC CC_REG))]
919   ""
920   "#"
921   ""
922   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
923                                            (const_int 0)))
924    (set (match_dup 0) (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
925                                (match_dup 2)))]
926   ""
927   [(set_attr "length" "2")])
929 (define_insn_and_split "*x_minus_i_ne_0"
930   [(set (match_operand:SI 0 "register_operand" "=r")
931         (minus:SI (match_operand:SI 2 "register_operand" "r")
932                   (ne:SI (match_operand:SI 1 "register_operand" "r")
933                          (const_int 0))))
934    (clobber (reg:CC CC_REG))]
935   ""
936   "#"
937   ""
938   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
939                                            (const_int 0)))
940    (set (match_dup 0) (minus:SI (match_dup 2)
941                                 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
942   ""
943   [(set_attr "length" "2")])
945 (define_insn_and_split "*x_plus_i_eq_0"
946   [(set (match_operand:SI 0 "register_operand" "=r")
947         (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
948                         (const_int 0))
949                  (match_operand:SI 2 "register_operand" "r")))
950    (clobber (reg:CC CC_REG))]
951   ""
952   "#"
953   ""
954   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
955                                            (const_int 0)))
956    (set (match_dup 0) (plus:SI (geu:SI (reg:CC CC_REG) (const_int 0))
957                                (match_dup 2)))]
958   ""
959   [(set_attr "length" "2")])
961 (define_insn_and_split "*x_minus_i_eq_0"
962   [(set (match_operand:SI 0 "register_operand" "=r")
963         (minus:SI (match_operand:SI 2 "register_operand" "r")
964                   (eq:SI (match_operand:SI 1 "register_operand" "r")
965                          (const_int 0))))
966    (clobber (reg:CC CC_REG))]
967   ""
968   "#"
969   ""
970   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
971                                            (const_int 0)))
972    (set (match_dup 0) (minus:SI (match_dup 2)
973                                 (geu:SI (reg:CC CC_REG) (const_int 0))))]
974   ""
975   [(set_attr "length" "2")])
977 ;; We can also do GEU and LTU directly, but these operate after a compare.
978 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
979 ;; versions for v9.
981 (define_insn "*sltu<P:mode>_insn"
982   [(set (match_operand:P 0 "register_operand" "=r")
983         (ltu:P (reg:CC CC_REG) (const_int 0)))]
984   ""
985   "addx\t%%g0, 0, %0"
986   [(set_attr "type" "ialuX")])
988 (define_insn "*sltu_insn_vis3"
989   [(set (match_operand:DI 0 "register_operand" "=r")
990         (ltu:DI (reg:CCX CC_REG) (const_int 0)))]
991   "TARGET_ARCH64 && TARGET_VIS3"
992   "addxc\t%%g0, %%g0, %0"
993   [(set_attr "type" "ialuX")])
995 (define_insn "*sltu_insn_vis3_trunc"
996   [(set (match_operand:SI 0 "register_operand" "=r")
997         (ltu:SI (reg:CCX CC_REG) (const_int 0)))]
998   "TARGET_ARCH64 && TARGET_VIS3"
999   "addxc\t%%g0, %%g0, %0"
1000   [(set_attr "type" "ialuX")])
1002 (define_insn "*neg_sltusi_insn"
1003   [(set (match_operand:SI 0 "register_operand" "=r")
1004         (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0))))]
1005   ""
1006   "subx\t%%g0, 0, %0"
1007   [(set_attr "type" "ialuX")])
1009 (define_insn "*neg_sltudi_insn"
1010   [(set (match_operand:DI 0 "register_operand" "=r")
1011         (sign_extend:DI (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0)))))]
1012   "TARGET_ARCH64"
1013   "subx\t%%g0, 0, %0"
1014   [(set_attr "type" "ialuX")])
1016 (define_insn "*neg_sltu_minus_x"
1017   [(set (match_operand:SI 0 "register_operand" "=r")
1018         (minus:SI (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0)))
1019                   (match_operand:SI 1 "arith_operand" "rI")))]
1020   ""
1021   "subx\t%%g0, %1, %0"
1022   [(set_attr "type" "ialuX")])
1024 (define_insn "*neg_sltu_plus_x"
1025   [(set (match_operand:SI 0 "register_operand" "=r")
1026         (neg:SI (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
1027                          (match_operand:SI 1 "arith_operand" "rI"))))]
1028   ""
1029   "subx\t%%g0, %1, %0"
1030   [(set_attr "type" "ialuX")])
1032 (define_insn "*sgeu<P:mode>_insn"
1033   [(set (match_operand:P 0 "register_operand" "=r")
1034         (geu:P (reg:CC CC_REG) (const_int 0)))]
1035   ""
1036   "subx\t%%g0, -1, %0"
1037   [(set_attr "type" "ialuX")])
1039 (define_insn "*neg_sgeusi_insn"
1040   [(set (match_operand:SI 0 "register_operand" "=r")
1041         (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0))))]
1042   ""
1043   "addx\t%%g0, -1, %0"
1044   [(set_attr "type" "ialuX")])
1046 (define_insn "*neg_sgeudi_insn"
1047   [(set (match_operand:DI 0 "register_operand" "=r")
1048         (sign_extend:DI (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0)))))]
1049   "TARGET_ARCH64"
1050   "addx\t%%g0, -1, %0"
1051   [(set_attr "type" "ialuX")])
1053 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
1054 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1055 ;; versions for v9.
1057 (define_insn "*sltu_plus_x"
1058   [(set (match_operand:SI 0 "register_operand" "=r")
1059         (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
1060                  (match_operand:SI 1 "arith_operand" "rI")))]
1061   ""
1062   "addx\t%%g0, %1, %0"
1063   [(set_attr "type" "ialuX")])
1065 (define_insn "*sltu_plus_x_plus_y"
1066   [(set (match_operand:SI 0 "register_operand" "=r")
1067         (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
1068                  (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1069                           (match_operand:SI 2 "arith_operand" "rI"))))]
1070   ""
1071   "addx\t%1, %2, %0"
1072   [(set_attr "type" "ialuX")])
1074 (define_insn "*x_minus_sltu"
1075   [(set (match_operand:SI 0 "register_operand" "=r")
1076         (minus:SI (match_operand:SI 1 "register_operand" "r")
1077                   (ltu:SI (reg:CC CC_REG) (const_int 0))))]
1078   ""
1079   "subx\t%1, 0, %0"
1080   [(set_attr "type" "ialuX")])
1082 ;; ??? Combine should canonicalize these next two to the same pattern.
1083 (define_insn "*x_minus_y_minus_sltu"
1084   [(set (match_operand:SI 0 "register_operand" "=r")
1085         (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
1086                             (match_operand:SI 2 "arith_operand" "rI"))
1087                   (ltu:SI (reg:CC CC_REG) (const_int 0))))]
1088   ""
1089   "subx\t%r1, %2, %0"
1090   [(set_attr "type" "ialuX")])
1092 (define_insn "*x_minus_sltu_plus_y"
1093   [(set (match_operand:SI 0 "register_operand" "=r")
1094         (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
1095                   (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
1096                            (match_operand:SI 2 "arith_operand" "rI"))))]
1097   ""
1098   "subx\t%r1, %2, %0"
1099   [(set_attr "type" "ialuX")])
1101 (define_insn "*sgeu_plus_x"
1102   [(set (match_operand:SI 0 "register_operand" "=r")
1103         (plus:SI (geu:SI (reg:CC CC_REG) (const_int 0))
1104                  (match_operand:SI 1 "register_operand" "r")))]
1105   ""
1106   "subx\t%1, -1, %0"
1107   [(set_attr "type" "ialuX")])
1109 (define_insn "*x_minus_sgeu"
1110   [(set (match_operand:SI 0 "register_operand" "=r")
1111         (minus:SI (match_operand:SI 1 "register_operand" "r")
1112                   (geu:SI (reg:CC CC_REG) (const_int 0))))]
1113   ""
1114   "addx\t%1, -1, %0"
1115   [(set_attr "type" "ialuX")])
1117 (define_split
1118   [(set (match_operand:SI 0 "register_operand" "")
1119         (match_operator:SI 2 "noov_compare_operator"
1120                            [(match_operand 1 "icc_or_fcc_register_operand" "")
1121                             (const_int 0)]))]
1122   "TARGET_V9
1123    && REGNO (operands[1]) == SPARC_ICC_REG
1124    && (GET_MODE (operands[1]) == CCXmode
1125        /* 32-bit LTU/GEU are better implemented using addx/subx.  */
1126        || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1127   [(set (match_dup 0) (const_int 0))
1128    (set (match_dup 0)
1129         (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1130                          (const_int 1)
1131                          (match_dup 0)))]
1132   "")
1135 ;; These control RTL generation for conditional jump insns
1137 (define_expand "cbranchcc4"
1138   [(set (pc)
1139         (if_then_else (match_operator 0 "comparison_operator"
1140                           [(match_operand 1 "compare_operand" "")
1141                            (match_operand 2 "const_zero_operand" "")])
1142                       (label_ref (match_operand 3 "" ""))
1143                       (pc)))]
1144   ""
1145   "")
1147 (define_expand "cbranchsi4"
1148   [(use (match_operator 0 "comparison_operator"
1149          [(match_operand:SI 1 "compare_operand" "")
1150           (match_operand:SI 2 "arith_operand" "")]))
1151    (use (match_operand 3 ""))]
1152   ""
1154   if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
1155     operands[1] = force_reg (SImode, operands[1]);
1156   emit_conditional_branch_insn (operands);
1157   DONE;
1160 (define_expand "cbranchdi4"
1161   [(use (match_operator 0 "comparison_operator"
1162          [(match_operand:DI 1 "compare_operand" "")
1163           (match_operand:DI 2 "arith_operand" "")]))
1164    (use (match_operand 3 ""))]
1165   "TARGET_ARCH64"
1167   if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
1168     operands[1] = force_reg (DImode, operands[1]);
1169   emit_conditional_branch_insn (operands);
1170   DONE;
1173 (define_expand "cbranch<F:mode>4"
1174   [(use (match_operator 0 "comparison_operator"
1175          [(match_operand:F 1 "register_operand" "")
1176           (match_operand:F 2 "register_operand" "")]))
1177    (use (match_operand 3 ""))]
1178   "TARGET_FPU"
1179   { emit_conditional_branch_insn (operands); DONE; })
1182 ;; Now match both normal and inverted jump.
1184 ;; XXX fpcmp nop braindamage
1185 (define_insn "*normal_branch"
1186   [(set (pc)
1187         (if_then_else (match_operator 0 "noov_compare_operator"
1188                                       [(reg CC_REG) (const_int 0)])
1189                       (label_ref (match_operand 1 "" ""))
1190                       (pc)))]
1191   ""
1193   return output_cbranch (operands[0], operands[1], 1, 0,
1194                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1195                          insn);
1197   [(set_attr "type" "branch")
1198    (set_attr "branch_type" "icc")])
1200 ;; XXX fpcmp nop braindamage
1201 (define_insn "*inverted_branch"
1202   [(set (pc)
1203         (if_then_else (match_operator 0 "noov_compare_operator"
1204                                       [(reg CC_REG) (const_int 0)])
1205                       (pc)
1206                       (label_ref (match_operand 1 "" ""))))]
1207   ""
1209   return output_cbranch (operands[0], operands[1], 1, 1,
1210                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1211                          insn);
1213   [(set_attr "type" "branch")
1214    (set_attr "branch_type" "icc")])
1216 ;; XXX fpcmp nop braindamage
1217 (define_insn "*normal_fp_branch"
1218   [(set (pc)
1219         (if_then_else (match_operator 1 "comparison_operator"
1220                                       [(match_operand:CCFP 0 "fcc_register_operand" "c")
1221                                        (const_int 0)])
1222                       (label_ref (match_operand 2 "" ""))
1223                       (pc)))]
1224   ""
1226   return output_cbranch (operands[1], operands[2], 2, 0,
1227                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1228                          insn);
1230   [(set_attr "type" "branch")
1231    (set_attr "branch_type" "fcc")])
1233 ;; XXX fpcmp nop braindamage
1234 (define_insn "*inverted_fp_branch"
1235   [(set (pc)
1236         (if_then_else (match_operator 1 "comparison_operator"
1237                                       [(match_operand:CCFP 0 "fcc_register_operand" "c")
1238                                        (const_int 0)])
1239                       (pc)
1240                       (label_ref (match_operand 2 "" ""))))]
1241   ""
1243   return output_cbranch (operands[1], operands[2], 2, 1,
1244                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1245                          insn);
1247   [(set_attr "type" "branch")
1248    (set_attr "branch_type" "fcc")])
1250 ;; XXX fpcmp nop braindamage
1251 (define_insn "*normal_fpe_branch"
1252   [(set (pc)
1253         (if_then_else (match_operator 1 "comparison_operator"
1254                                       [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1255                                        (const_int 0)])
1256                       (label_ref (match_operand 2 "" ""))
1257                       (pc)))]
1258   ""
1260   return output_cbranch (operands[1], operands[2], 2, 0,
1261                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1262                          insn);
1264   [(set_attr "type" "branch")
1265    (set_attr "branch_type" "fcc")])
1267 ;; XXX fpcmp nop braindamage
1268 (define_insn "*inverted_fpe_branch"
1269   [(set (pc)
1270         (if_then_else (match_operator 1 "comparison_operator"
1271                                       [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1272                                        (const_int 0)])
1273                       (pc)
1274                       (label_ref (match_operand 2 "" ""))))]
1275   ""
1277   return output_cbranch (operands[1], operands[2], 2, 1,
1278                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1279                          insn);
1281   [(set_attr "type" "branch")
1282    (set_attr "branch_type" "fcc")])
1284 ;; SPARC V9-specific jump insns.  None of these are guaranteed to be
1285 ;; in the architecture.
1287 (define_insn "*cbcond_sp32"
1288   [(set (pc)
1289         (if_then_else (match_operator 0 "noov_compare_operator"
1290                        [(match_operand:SI 1 "register_operand" "r")
1291                         (match_operand:SI 2 "arith5_operand" "rA")])
1292                       (label_ref (match_operand 3 "" ""))
1293                       (pc)))]
1294   "TARGET_CBCOND"
1296   return output_cbcond (operands[0], operands[3], insn);
1298   [(set_attr "type" "cbcond")])
1300 (define_insn "*cbcond_sp64"
1301   [(set (pc)
1302         (if_then_else (match_operator 0 "noov_compare_operator"
1303                        [(match_operand:DI 1 "register_operand" "r")
1304                         (match_operand:DI 2 "arith5_operand" "rA")])
1305                       (label_ref (match_operand 3 "" ""))
1306                       (pc)))]
1307   "TARGET_ARCH64 && TARGET_CBCOND"
1309   return output_cbcond (operands[0], operands[3], insn);
1311   [(set_attr "type" "cbcond")])
1313 ;; There are no 32 bit brreg insns.
1315 ;; XXX
1316 (define_insn "*normal_int_branch_sp64"
1317   [(set (pc)
1318         (if_then_else (match_operator 0 "v9_register_compare_operator"
1319                                       [(match_operand:DI 1 "register_operand" "r")
1320                                        (const_int 0)])
1321                       (label_ref (match_operand 2 "" ""))
1322                       (pc)))]
1323   "TARGET_ARCH64"
1325   return output_v9branch (operands[0], operands[2], 1, 2, 0,
1326                           final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1327                           insn);
1329   [(set_attr "type" "branch")
1330    (set_attr "branch_type" "reg")])
1332 ;; XXX
1333 (define_insn "*inverted_int_branch_sp64"
1334   [(set (pc)
1335         (if_then_else (match_operator 0 "v9_register_compare_operator"
1336                                       [(match_operand:DI 1 "register_operand" "r")
1337                                        (const_int 0)])
1338                       (pc)
1339                       (label_ref (match_operand 2 "" ""))))]
1340   "TARGET_ARCH64"
1342   return output_v9branch (operands[0], operands[2], 1, 2, 1,
1343                           final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1344                           insn);
1346   [(set_attr "type" "branch")
1347    (set_attr "branch_type" "reg")])
1350 ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic
1351 ;; value subject to a PC-relative relocation.  Operand 2 is a helper function
1352 ;; that adds the PC value at the call point to register #(operand 3).
1354 ;; Even on V9 we use this call sequence with a stub, instead of "rd %pc, ..."
1355 ;; because the RDPC instruction is extremely expensive and incurs a complete
1356 ;; instruction pipeline flush.
1358 (define_insn "load_pcrel_sym<P:mode>"
1359   [(set (match_operand:P 0 "register_operand" "=r")
1360         (unspec:P [(match_operand:P 1 "symbolic_operand" "")
1361                    (match_operand:P 2 "call_address_operand" "")
1362                    (match_operand:P 3 "const_int_operand" "")] UNSPEC_LOAD_PCREL_SYM))
1363    (clobber (reg:P O7_REG))]
1364   "REGNO (operands[0]) == INTVAL (operands[3])"
1366   if (flag_delayed_branch)
1367     return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0";
1368   else
1369     return "sethi\t%%hi(%a1-8), %0\n\tadd\t%0, %%lo(%a1-4), %0\n\tcall\t%a2\n\t nop";
1371   [(set (attr "type") (const_string "multi"))
1372    (set (attr "length")
1373         (if_then_else (eq_attr "delayed_branch" "true")
1374                       (const_int 3)
1375                       (const_int 4)))])
1378 ;; Integer move instructions
1380 (define_expand "movqi"
1381   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1382         (match_operand:QI 1 "general_operand" ""))]
1383   ""
1385   if (sparc_expand_move (QImode, operands))
1386     DONE;
1389 (define_insn "*movqi_insn"
1390   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1391         (match_operand:QI 1 "input_operand"   "rI,m,rJ"))]
1392   "(register_operand (operands[0], QImode)
1393     || register_or_zero_operand (operands[1], QImode))"
1394   "@
1395    mov\t%1, %0
1396    ldub\t%1, %0
1397    stb\t%r1, %0"
1398   [(set_attr "type" "*,load,store")
1399    (set_attr "us3load_type" "*,3cycle,*")])
1401 (define_expand "movhi"
1402   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1403         (match_operand:HI 1 "general_operand" ""))]
1404   ""
1406   if (sparc_expand_move (HImode, operands))
1407     DONE;
1410 (define_insn "*movhi_insn"
1411   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1412         (match_operand:HI 1 "input_operand"   "rI,K,m,rJ"))]
1413   "(register_operand (operands[0], HImode)
1414     || register_or_zero_operand (operands[1], HImode))"
1415   "@
1416    mov\t%1, %0
1417    sethi\t%%hi(%a1), %0
1418    lduh\t%1, %0
1419    sth\t%r1, %0"
1420   [(set_attr "type" "*,*,load,store")
1421    (set_attr "us3load_type" "*,*,3cycle,*")])
1423 ;; We always work with constants here.
1424 (define_insn "*movhi_lo_sum"
1425   [(set (match_operand:HI 0 "register_operand" "=r")
1426         (ior:HI (match_operand:HI 1 "register_operand" "%r")
1427                 (match_operand:HI 2 "small_int_operand" "I")))]
1428   ""
1429   "or\t%1, %2, %0")
1431 (define_expand "movsi"
1432   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1433         (match_operand:SI 1 "general_operand" ""))]
1434   ""
1436   if (sparc_expand_move (SImode, operands))
1437     DONE;
1440 (define_insn "*movsi_insn"
1441   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r, m, r,*f,*f,*f, m,d,d")
1442         (match_operand:SI 1 "input_operand"        "rI,K,m,rJ,*f, r, f, m,*f,J,P"))]
1443   "register_operand (operands[0], SImode)
1444    || register_or_zero_or_all_ones_operand (operands[1], SImode)"
1445   "@
1446    mov\t%1, %0
1447    sethi\t%%hi(%a1), %0
1448    ld\t%1, %0
1449    st\t%r1, %0
1450    movstouw\t%1, %0
1451    movwtos\t%1, %0
1452    fmovs\t%1, %0
1453    ld\t%1, %0
1454    st\t%1, %0
1455    fzeros\t%0
1456    fones\t%0"
1457   [(set_attr "type" "*,*,load,store,vismv,vismv,fpmove,fpload,fpstore,visl,visl")
1458    (set_attr "cpu_feature" "*,*,*,*,vis3,vis3,*,*,*,vis,vis")])
1460 (define_insn "*movsi_lo_sum"
1461   [(set (match_operand:SI 0 "register_operand" "=r")
1462         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1463                    (match_operand:SI 2 "immediate_operand" "in")))]
1464   ""
1465   "or\t%1, %%lo(%a2), %0")
1467 (define_insn "*movsi_high"
1468   [(set (match_operand:SI 0 "register_operand" "=r")
1469         (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1470   ""
1471   "sethi\t%%hi(%a1), %0")
1473 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1474 ;; so that CSE won't optimize the address computation away.
1475 (define_insn "movsi_lo_sum_pic"
1476   [(set (match_operand:SI 0 "register_operand" "=r")
1477         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1478                    (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1479   "flag_pic"
1481 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1482   return "xor\t%1, %%gdop_lox10(%a2), %0";
1483 #else
1484   return "or\t%1, %%lo(%a2), %0";
1485 #endif
1488 (define_insn "movsi_high_pic"
1489   [(set (match_operand:SI 0 "register_operand" "=r")
1490         (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1491   "flag_pic && check_pic (1)"
1493 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1494   return "sethi\t%%gdop_hix22(%a1), %0";
1495 #else
1496   return "sethi\t%%hi(%a1), %0";
1497 #endif
1500 (define_insn "movsi_pic_gotdata_op"
1501   [(set (match_operand:SI 0 "register_operand" "=r")
1502         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
1503                     (match_operand:SI 2 "register_operand" "r")
1504                     (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
1505   "flag_pic && check_pic (1)"
1507 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1508   return "ld\t[%1 + %2], %0, %%gdop(%a3)";
1509 #else
1510   return "ld\t[%1 + %2], %0";
1511 #endif
1513   [(set_attr "type" "load")])
1515 (define_expand "movsi_pic_label_ref"
1516   [(set (match_dup 3) (high:SI
1517      (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1518                  (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1519    (set (match_dup 4) (lo_sum:SI (match_dup 3)
1520      (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1521    (set (match_operand:SI 0 "register_operand" "=r")
1522         (minus:SI (match_dup 5) (match_dup 4)))]
1523   "flag_pic"
1525   crtl->uses_pic_offset_table = 1;
1526   operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1527   if (!can_create_pseudo_p ())
1528     {
1529       operands[3] = operands[0];
1530       operands[4] = operands[0];
1531     }
1532   else
1533     {
1534       operands[3] = gen_reg_rtx (SImode);
1535       operands[4] = gen_reg_rtx (SImode);
1536     }
1537   operands[5] = pic_offset_table_rtx;
1540 (define_insn "*movsi_high_pic_label_ref"
1541   [(set (match_operand:SI 0 "register_operand" "=r")
1542       (high:SI
1543         (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1544                     (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1545   "flag_pic"
1546   "sethi\t%%hi(%a2-(%a1-.)), %0")
1548 (define_insn "*movsi_lo_sum_pic_label_ref"
1549   [(set (match_operand:SI 0 "register_operand" "=r")
1550       (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1551         (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
1552                     (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1553   "flag_pic"
1554   "or\t%1, %%lo(%a3-(%a2-.)), %0")
1556 ;; Set up the PIC register for VxWorks.
1558 (define_expand "vxworks_load_got"
1559   [(set (match_dup 0)
1560         (high:SI (match_dup 1)))
1561    (set (match_dup 0)
1562         (mem:SI (lo_sum:SI (match_dup 0) (match_dup 1))))
1563    (set (match_dup 0)
1564         (mem:SI (lo_sum:SI (match_dup 0) (match_dup 2))))]
1565   "TARGET_VXWORKS_RTP"
1567   operands[0] = pic_offset_table_rtx;
1568   operands[1] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_BASE);
1569   operands[2] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_INDEX);
1572 (define_expand "movdi"
1573   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1574         (match_operand:DI 1 "general_operand" ""))]
1575   ""
1577   if (sparc_expand_move (DImode, operands))
1578     DONE;
1581 ;; Be careful, fmovd does not exist when !v9.
1582 ;; We match MEM moves directly when we have correct even
1583 ;; numbered registers, but fall into splits otherwise.
1584 ;; The constraint ordering here is really important to
1585 ;; avoid insane problems in reload, especially for patterns
1586 ;; of the form:
1588 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
1589 ;;                       (const_int -5016)))
1590 ;;      (reg:DI 2 %g2))
1593 (define_insn "*movdi_insn_sp32"
1594   [(set (match_operand:DI 0 "nonimmediate_operand"
1595                                         "=T,o,T,U,o,r,r,r,?T,?*f,?*f,?o,?*e,?*e,  r,?*f,?*e,?W,b,b")
1596         (match_operand:DI 1 "input_operand"
1597                                         " J,J,U,T,r,o,i,r,*f,  T,  o,*f, *e, *e,?*f,  r,  W,*e,J,P"))]
1598   "! TARGET_ARCH64
1599    && (register_operand (operands[0], DImode)
1600        || register_or_zero_operand (operands[1], DImode))"
1601   "@
1602    stx\t%%g0, %0
1603    #
1604    std\t%1, %0
1605    ldd\t%1, %0
1606    #
1607    #
1608    #
1609    #
1610    std\t%1, %0
1611    ldd\t%1, %0
1612    #
1613    #
1614    fmovd\t%1, %0
1615    #
1616    #
1617    #
1618    ldd\t%1, %0
1619    std\t%1, %0
1620    fzero\t%0
1621    fone\t%0"
1622   [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,*,*,*,fpload,fpstore,visl,visl")
1623    (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,2,2,2,*,*,*,*")
1624    (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*,*,*,*,double,double")
1625    (set_attr "cpu_feature" "v9,*,*,*,*,*,*,*,fpu,fpu,fpu,fpu,v9,fpunotv9,vis3,vis3,fpu,fpu,vis,vis")])
1627 (define_insn "*movdi_insn_sp64"
1628   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r, m, r,*e,?*e,?*e,?W,b,b")
1629         (match_operand:DI 1 "input_operand"        "rI,N,m,rJ,*e, r, *e,  W,*e,J,P"))]
1630   "TARGET_ARCH64
1631    && (register_operand (operands[0], DImode)
1632        || register_or_zero_or_all_ones_operand (operands[1], DImode))"
1633   "@
1634    mov\t%1, %0
1635    sethi\t%%hi(%a1), %0
1636    ldx\t%1, %0
1637    stx\t%r1, %0
1638    movdtox\t%1, %0
1639    movxtod\t%1, %0
1640    fmovd\t%1, %0
1641    ldd\t%1, %0
1642    std\t%1, %0
1643    fzero\t%0
1644    fone\t%0"
1645   [(set_attr "type" "*,*,load,store,vismv,vismv,fpmove,fpload,fpstore,visl,visl")
1646    (set_attr "fptype" "*,*,*,*,*,*,double,*,*,double,double")
1647    (set_attr "cpu_feature" "*,*,*,*,vis3,vis3,*,*,*,vis,vis")])
1649 (define_expand "movdi_pic_label_ref"
1650   [(set (match_dup 3) (high:DI
1651      (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1652                  (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1653    (set (match_dup 4) (lo_sum:DI (match_dup 3)
1654      (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1655    (set (match_operand:DI 0 "register_operand" "=r")
1656         (minus:DI (match_dup 5) (match_dup 4)))]
1657   "TARGET_ARCH64 && flag_pic"
1659   crtl->uses_pic_offset_table = 1;
1660   operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1661   if (!can_create_pseudo_p ())
1662     {
1663       operands[3] = operands[0];
1664       operands[4] = operands[0];
1665     }
1666   else
1667     {
1668       operands[3] = gen_reg_rtx (DImode);
1669       operands[4] = gen_reg_rtx (DImode);
1670     }
1671   operands[5] = pic_offset_table_rtx;
1674 (define_insn "*movdi_high_pic_label_ref"
1675   [(set (match_operand:DI 0 "register_operand" "=r")
1676         (high:DI
1677           (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1678                       (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1679   "TARGET_ARCH64 && flag_pic"
1680   "sethi\t%%hi(%a2-(%a1-.)), %0")
1682 (define_insn "*movdi_lo_sum_pic_label_ref"
1683   [(set (match_operand:DI 0 "register_operand" "=r")
1684       (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1685         (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
1686                     (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1687   "TARGET_ARCH64 && flag_pic"
1688   "or\t%1, %%lo(%a3-(%a2-.)), %0")
1690 ;; SPARC-v9 code model support insns.  See sparc_emit_set_symbolic_const64
1691 ;; in sparc.c to see what is going on here... PIC stuff comes first.
1693 (define_insn "movdi_lo_sum_pic"
1694   [(set (match_operand:DI 0 "register_operand" "=r")
1695         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1696                    (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1697   "TARGET_ARCH64 && flag_pic"
1699 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1700   return "xor\t%1, %%gdop_lox10(%a2), %0";
1701 #else
1702   return "or\t%1, %%lo(%a2), %0";
1703 #endif
1706 (define_insn "movdi_high_pic"
1707   [(set (match_operand:DI 0 "register_operand" "=r")
1708         (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1709   "TARGET_ARCH64 && flag_pic && check_pic (1)"
1711 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1712   return "sethi\t%%gdop_hix22(%a1), %0";
1713 #else
1714   return "sethi\t%%hi(%a1), %0";
1715 #endif
1718 (define_insn "movdi_pic_gotdata_op"
1719   [(set (match_operand:DI 0 "register_operand" "=r")
1720         (unspec:DI [(match_operand:DI 1 "register_operand" "r")
1721                     (match_operand:DI 2 "register_operand" "r")
1722                     (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
1723   "TARGET_ARCH64 && flag_pic && check_pic (1)"
1725 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1726   return "ldx\t[%1 + %2], %0, %%gdop(%a3)";
1727 #else
1728   return "ldx\t[%1 + %2], %0";
1729 #endif
1731   [(set_attr "type" "load")])
1733 (define_insn "*sethi_di_medlow_embmedany_pic"
1734   [(set (match_operand:DI 0 "register_operand" "=r")
1735         (high:DI (match_operand:DI 1 "medium_pic_operand" "")))]
1736   "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
1737   "sethi\t%%hi(%a1), %0")
1739 (define_insn "*sethi_di_medlow"
1740   [(set (match_operand:DI 0 "register_operand" "=r")
1741         (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
1742   "TARGET_CM_MEDLOW && check_pic (1)"
1743   "sethi\t%%hi(%a1), %0")
1745 (define_insn "*losum_di_medlow"
1746   [(set (match_operand:DI 0 "register_operand" "=r")
1747         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1748                    (match_operand:DI 2 "symbolic_operand" "")))]
1749   "TARGET_CM_MEDLOW"
1750   "or\t%1, %%lo(%a2), %0")
1752 (define_insn "seth44"
1753   [(set (match_operand:DI 0 "register_operand" "=r")
1754         (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
1755   "TARGET_CM_MEDMID"
1756   "sethi\t%%h44(%a1), %0")
1758 (define_insn "setm44"
1759   [(set (match_operand:DI 0 "register_operand" "=r")
1760         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1761                    (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
1762   "TARGET_CM_MEDMID"
1763   "or\t%1, %%m44(%a2), %0")
1765 (define_insn "setl44"
1766   [(set (match_operand:DI 0 "register_operand" "=r")
1767         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1768                    (match_operand:DI 2 "symbolic_operand" "")))]
1769   "TARGET_CM_MEDMID"
1770   "or\t%1, %%l44(%a2), %0")
1772 (define_insn "sethh"
1773   [(set (match_operand:DI 0 "register_operand" "=r")
1774         (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
1775   "TARGET_CM_MEDANY"
1776   "sethi\t%%hh(%a1), %0")
1778 (define_insn "setlm"
1779   [(set (match_operand:DI 0 "register_operand" "=r")
1780         (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
1781   "TARGET_CM_MEDANY"
1782   "sethi\t%%lm(%a1), %0")
1784 (define_insn "sethm"
1785   [(set (match_operand:DI 0 "register_operand" "=r")
1786         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1787                    (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
1788   "TARGET_CM_MEDANY"
1789   "or\t%1, %%hm(%a2), %0")
1791 (define_insn "setlo"
1792   [(set (match_operand:DI 0 "register_operand" "=r")
1793         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1794                    (match_operand:DI 2 "symbolic_operand" "")))]
1795   "TARGET_CM_MEDANY"
1796   "or\t%1, %%lo(%a2), %0")
1798 (define_insn "embmedany_sethi"
1799   [(set (match_operand:DI 0 "register_operand" "=r")
1800         (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
1801   "TARGET_CM_EMBMEDANY && check_pic (1)"
1802   "sethi\t%%hi(%a1), %0")
1804 (define_insn "embmedany_losum"
1805   [(set (match_operand:DI 0 "register_operand" "=r")
1806         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1807                    (match_operand:DI 2 "data_segment_operand" "")))]
1808   "TARGET_CM_EMBMEDANY"
1809   "add\t%1, %%lo(%a2), %0")
1811 (define_insn "embmedany_brsum"
1812   [(set (match_operand:DI 0 "register_operand" "=r")
1813         (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
1814   "TARGET_CM_EMBMEDANY"
1815   "add\t%1, %_, %0")
1817 (define_insn "embmedany_textuhi"
1818   [(set (match_operand:DI 0 "register_operand" "=r")
1819         (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
1820   "TARGET_CM_EMBMEDANY && check_pic (1)"
1821   "sethi\t%%uhi(%a1), %0")
1823 (define_insn "embmedany_texthi"
1824   [(set (match_operand:DI 0 "register_operand" "=r")
1825         (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
1826   "TARGET_CM_EMBMEDANY && check_pic (1)"
1827   "sethi\t%%hi(%a1), %0")
1829 (define_insn "embmedany_textulo"
1830   [(set (match_operand:DI 0 "register_operand" "=r")
1831         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1832                    (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
1833   "TARGET_CM_EMBMEDANY"
1834   "or\t%1, %%ulo(%a2), %0")
1836 (define_insn "embmedany_textlo"
1837   [(set (match_operand:DI 0 "register_operand" "=r")
1838         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1839                    (match_operand:DI 2 "text_segment_operand" "")))]
1840   "TARGET_CM_EMBMEDANY"
1841   "or\t%1, %%lo(%a2), %0")
1843 ;; Now some patterns to help reload out a bit.
1844 (define_expand "reload_indi"
1845   [(parallel [(match_operand:DI 0 "register_operand" "=r")
1846               (match_operand:DI 1 "immediate_operand" "")
1847               (match_operand:TI 2 "register_operand" "=&r")])]
1848   "(TARGET_CM_MEDANY
1849     || TARGET_CM_EMBMEDANY)
1850    && ! flag_pic"
1852   sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1853   DONE;
1856 (define_expand "reload_outdi"
1857   [(parallel [(match_operand:DI 0 "register_operand" "=r")
1858               (match_operand:DI 1 "immediate_operand" "")
1859               (match_operand:TI 2 "register_operand" "=&r")])]
1860   "(TARGET_CM_MEDANY
1861     || TARGET_CM_EMBMEDANY)
1862    && ! flag_pic"
1864   sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1865   DONE;
1868 ;; Split up putting CONSTs and REGs into DI regs when !arch64
1869 (define_split
1870   [(set (match_operand:DI 0 "register_operand" "")
1871         (match_operand:DI 1 "const_int_operand" ""))]
1872   "! TARGET_ARCH64
1873    && ((GET_CODE (operands[0]) == REG
1874         && SPARC_INT_REG_P (REGNO (operands[0])))
1875        || (GET_CODE (operands[0]) == SUBREG
1876            && GET_CODE (SUBREG_REG (operands[0])) == REG
1877            && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))
1878    && reload_completed"
1879   [(clobber (const_int 0))]
1881 #if HOST_BITS_PER_WIDE_INT == 32
1882   emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1883                         (INTVAL (operands[1]) < 0) ?
1884                         constm1_rtx :
1885                         const0_rtx));
1886   emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1887                         operands[1]));
1888 #else
1889   unsigned int low, high;
1891   low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
1892   high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
1893   emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
1895   /* Slick... but this trick loses if this subreg constant part
1896      can be done in one insn.  */
1897   if (low == high
1898       && ! SPARC_SETHI32_P (high)
1899       && ! SPARC_SIMM13_P (high))
1900     emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1901                           gen_highpart (SImode, operands[0])));
1902   else
1903     emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
1904 #endif
1905   DONE;
1908 (define_split
1909   [(set (match_operand:DI 0 "register_operand" "")
1910         (match_operand:DI 1 "const_double_operand" ""))]
1911   "reload_completed
1912    && (! TARGET_V9
1913        || (! TARGET_ARCH64
1914            && ((GET_CODE (operands[0]) == REG
1915                 && SPARC_INT_REG_P (REGNO (operands[0])))
1916                || (GET_CODE (operands[0]) == SUBREG
1917                    && GET_CODE (SUBREG_REG (operands[0])) == REG
1918                    && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))))"
1919   [(clobber (const_int 0))]
1921   emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1922                         GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
1924   /* Slick... but this trick loses if this subreg constant part
1925      can be done in one insn.  */
1926   if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
1927       && ! SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
1928       && ! SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1])))
1929     {
1930       emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1931                             gen_highpart (SImode, operands[0])));
1932     }
1933   else
1934     {
1935       emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1936                             GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
1937     }
1938   DONE;
1941 (define_split
1942   [(set (match_operand:DI 0 "register_operand" "")
1943         (match_operand:DI 1 "register_operand" ""))]
1944   "reload_completed
1945    && (! TARGET_V9
1946        || (! TARGET_ARCH64
1947            && sparc_split_regreg_legitimate (operands[0],
1948                                              operands[1])))"
1949   [(clobber (const_int 0))]
1951   rtx set_dest = operands[0];
1952   rtx set_src = operands[1];
1953   rtx dest1, dest2;
1954   rtx src1, src2;
1956   dest1 = gen_highpart (SImode, set_dest);
1957   dest2 = gen_lowpart (SImode, set_dest);
1958   src1 = gen_highpart (SImode, set_src);
1959   src2 = gen_lowpart (SImode, set_src);
1961   /* Now emit using the real source and destination we found, swapping
1962      the order if we detect overlap.  */
1963   if (reg_overlap_mentioned_p (dest1, src2))
1964     {
1965       emit_insn (gen_movsi (dest2, src2));
1966       emit_insn (gen_movsi (dest1, src1));
1967     }
1968   else
1969     {
1970       emit_insn (gen_movsi (dest1, src1));
1971       emit_insn (gen_movsi (dest2, src2));
1972     }
1973   DONE;
1976 ;; Now handle the cases of memory moves from/to non-even
1977 ;; DI mode register pairs.
1978 (define_split
1979   [(set (match_operand:DI 0 "register_operand" "")
1980         (match_operand:DI 1 "memory_operand" ""))]
1981   "(! TARGET_ARCH64
1982     && reload_completed
1983     && sparc_splitdi_legitimate (operands[0], operands[1]))"
1984   [(clobber (const_int 0))]
1986   rtx word0 = adjust_address (operands[1], SImode, 0);
1987   rtx word1 = adjust_address (operands[1], SImode, 4);
1988   rtx high_part = gen_highpart (SImode, operands[0]);
1989   rtx low_part = gen_lowpart (SImode, operands[0]);
1991   if (reg_overlap_mentioned_p (high_part, word1))
1992     {
1993       emit_insn (gen_movsi (low_part, word1));
1994       emit_insn (gen_movsi (high_part, word0));
1995     }
1996   else
1997     {
1998       emit_insn (gen_movsi (high_part, word0));
1999       emit_insn (gen_movsi (low_part, word1));
2000     }
2001   DONE;
2004 (define_split
2005   [(set (match_operand:DI 0 "memory_operand" "")
2006         (match_operand:DI 1 "register_operand" ""))]
2007   "(! TARGET_ARCH64
2008     && reload_completed
2009     && sparc_splitdi_legitimate (operands[1], operands[0]))"
2010   [(clobber (const_int 0))]
2012   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
2013                         gen_highpart (SImode, operands[1])));
2014   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
2015                         gen_lowpart (SImode, operands[1])));
2016   DONE;
2019 (define_split
2020   [(set (match_operand:DI 0 "memory_operand" "")
2021         (match_operand:DI 1 "const_zero_operand" ""))]
2022   "reload_completed
2023    && (! TARGET_V9
2024        || (! TARGET_ARCH64
2025            && ! mem_min_alignment (operands[0], 8)))
2026    && offsettable_memref_p (operands[0])"
2027   [(clobber (const_int 0))]
2029   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
2030   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
2031   DONE;
2034 (define_expand "movti"
2035   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2036         (match_operand:TI 1 "general_operand" ""))]
2037   "TARGET_ARCH64"
2039   if (sparc_expand_move (TImode, operands))
2040     DONE;
2043 ;; We need to prevent reload from splitting TImode moves, because it
2044 ;; might decide to overwrite a pointer with the value it points to.
2045 ;; In that case we have to do the loads in the appropriate order so
2046 ;; that the pointer is not destroyed too early.
2048 (define_insn "*movti_insn_sp64"
2049   [(set (match_operand:TI 0 "nonimmediate_operand" "=r , o,?*e,?o,b")
2050         (match_operand:TI 1 "input_operand"        "roJ,rJ, eo, e,J"))]
2051   "TARGET_ARCH64
2052    && ! TARGET_HARD_QUAD
2053    && (register_operand (operands[0], TImode)
2054        || register_or_zero_operand (operands[1], TImode))"
2055   "#"
2056   [(set_attr "length" "2,2,2,2,2")
2057    (set_attr "cpu_feature" "*,*,fpu,fpu,vis")])
2059 (define_insn "*movti_insn_sp64_hq"
2060   [(set (match_operand:TI 0 "nonimmediate_operand" "=r , o,?*e,?*e,?m,b")
2061         (match_operand:TI 1 "input_operand"        "roJ,rJ,  e,  m, e,J"))]
2062   "TARGET_ARCH64
2063    && TARGET_HARD_QUAD
2064    && (register_operand (operands[0], TImode)
2065        || register_or_zero_operand (operands[1], TImode))"
2066   "@
2067   #
2068   #
2069   fmovq\t%1, %0
2070   ldq\t%1, %0
2071   stq\t%1, %0
2072   #"
2073   [(set_attr "type" "*,*,fpmove,fpload,fpstore,*")
2074    (set_attr "length" "2,2,*,*,*,2")])
2076 ;; Now all the splits to handle multi-insn TI mode moves.
2077 (define_split
2078   [(set (match_operand:TI 0 "register_operand" "")
2079         (match_operand:TI 1 "register_operand" ""))]
2080   "reload_completed
2081    && ((TARGET_FPU
2082         && ! TARGET_HARD_QUAD)
2083        || (! fp_register_operand (operands[0], TImode)
2084            && ! fp_register_operand (operands[1], TImode)))"
2085   [(clobber (const_int 0))]
2087   rtx set_dest = operands[0];
2088   rtx set_src = operands[1];
2089   rtx dest1, dest2;
2090   rtx src1, src2;
2092   dest1 = gen_highpart (DImode, set_dest);
2093   dest2 = gen_lowpart (DImode, set_dest);
2094   src1 = gen_highpart (DImode, set_src);
2095   src2 = gen_lowpart (DImode, set_src);
2097   /* Now emit using the real source and destination we found, swapping
2098      the order if we detect overlap.  */
2099   if (reg_overlap_mentioned_p (dest1, src2))
2100     {
2101       emit_insn (gen_movdi (dest2, src2));
2102       emit_insn (gen_movdi (dest1, src1));
2103     }
2104   else
2105     {
2106       emit_insn (gen_movdi (dest1, src1));
2107       emit_insn (gen_movdi (dest2, src2));
2108     }
2109   DONE;
2112 (define_split
2113   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2114         (match_operand:TI 1 "const_zero_operand" ""))]
2115   "reload_completed"
2116   [(clobber (const_int 0))]
2118   rtx set_dest = operands[0];
2119   rtx dest1, dest2;
2121   switch (GET_CODE (set_dest))
2122     {
2123     case REG:
2124       dest1 = gen_highpart (DImode, set_dest);
2125       dest2 = gen_lowpart (DImode, set_dest);
2126       break;
2127     case MEM:
2128       dest1 = adjust_address (set_dest, DImode, 0);
2129       dest2 = adjust_address (set_dest, DImode, 8);
2130       break;
2131     default:
2132       gcc_unreachable ();
2133     }
2135   emit_insn (gen_movdi (dest1, const0_rtx));
2136   emit_insn (gen_movdi (dest2, const0_rtx));
2137   DONE;
2140 (define_split
2141   [(set (match_operand:TI 0 "register_operand" "")
2142         (match_operand:TI 1 "memory_operand" ""))]
2143   "reload_completed
2144    && offsettable_memref_p (operands[1])
2145    && (! TARGET_HARD_QUAD
2146        || ! fp_register_operand (operands[0], TImode))"
2147   [(clobber (const_int 0))]
2149   rtx word0 = adjust_address (operands[1], DImode, 0);
2150   rtx word1 = adjust_address (operands[1], DImode, 8);
2151   rtx set_dest, dest1, dest2;
2153   set_dest = operands[0];
2155   dest1 = gen_highpart (DImode, set_dest);
2156   dest2 = gen_lowpart (DImode, set_dest);
2158   /* Now output, ordering such that we don't clobber any registers
2159      mentioned in the address.  */
2160   if (reg_overlap_mentioned_p (dest1, word1))
2162     {
2163       emit_insn (gen_movdi (dest2, word1));
2164       emit_insn (gen_movdi (dest1, word0));
2165     }
2166   else
2167    {
2168       emit_insn (gen_movdi (dest1, word0));
2169       emit_insn (gen_movdi (dest2, word1));
2170    }
2171   DONE;
2174 (define_split
2175   [(set (match_operand:TI 0 "memory_operand" "")
2176         (match_operand:TI 1 "register_operand" ""))]
2177   "reload_completed
2178    && offsettable_memref_p (operands[0])
2179    && (! TARGET_HARD_QUAD
2180        || ! fp_register_operand (operands[1], TImode))"
2181   [(clobber (const_int 0))]
2183   rtx set_src = operands[1];
2185   emit_insn (gen_movdi (adjust_address (operands[0], DImode, 0),
2186                         gen_highpart (DImode, set_src)));
2187   emit_insn (gen_movdi (adjust_address (operands[0], DImode, 8),
2188                         gen_lowpart (DImode, set_src)));
2189   DONE;
2193 ;; Floating point move instructions
2195 (define_expand "movsf"
2196   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2197         (match_operand:SF 1 "general_operand" ""))]
2198   ""
2200   if (sparc_expand_move (SFmode, operands))
2201     DONE;
2204 (define_insn "*movsf_insn"
2205   [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,f, *r,*r,*r,*r, f,f,*r,m,  m")
2206         (match_operand:SF 1 "input_operand"         "G,C,f,*rR, Q, S, f,*r,m, m,f,*rG"))]
2207   "(register_operand (operands[0], SFmode)
2208     || register_or_zero_or_all_ones_operand (operands[1], SFmode))"
2210   if (GET_CODE (operands[1]) == CONST_DOUBLE
2211       && (which_alternative == 3
2212           || which_alternative == 4
2213           || which_alternative == 5))
2214     {
2215       REAL_VALUE_TYPE r;
2216       long i;
2218       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2219       REAL_VALUE_TO_TARGET_SINGLE (r, i);
2220       operands[1] = GEN_INT (i);
2221     }
2223   switch (which_alternative)
2224     {
2225     case 0:
2226       return "fzeros\t%0";
2227     case 1:
2228       return "fones\t%0";
2229     case 2:
2230       return "fmovs\t%1, %0";
2231     case 3:
2232       return "mov\t%1, %0";
2233     case 4:
2234       return "sethi\t%%hi(%a1), %0";
2235     case 5:
2236       return "#";
2237     case 6:
2238       return "movstouw\t%1, %0";
2239     case 7:
2240       return "movwtos\t%1, %0";
2241     case 8:
2242     case 9:
2243       return "ld\t%1, %0";
2244     case 10:
2245     case 11:
2246       return "st\t%r1, %0";
2247     default:
2248       gcc_unreachable ();
2249     }
2251   [(set_attr "type" "visl,visl,fpmove,*,*,*,vismv,vismv,fpload,load,fpstore,store")
2252    (set_attr "cpu_feature" "vis,vis,fpu,*,*,*,vis3,vis3,fpu,*,fpu,*")])
2254 ;; The following 3 patterns build SFmode constants in integer registers.
2256 (define_insn "*movsf_lo_sum"
2257   [(set (match_operand:SF 0 "register_operand" "=r")
2258         (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
2259                    (match_operand:SF 2 "fp_const_high_losum_operand" "S")))]
2260   ""
2262   REAL_VALUE_TYPE r;
2263   long i;
2265   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
2266   REAL_VALUE_TO_TARGET_SINGLE (r, i);
2267   operands[2] = GEN_INT (i);
2268   return "or\t%1, %%lo(%a2), %0";
2271 (define_insn "*movsf_high"
2272   [(set (match_operand:SF 0 "register_operand" "=r")
2273         (high:SF (match_operand:SF 1 "fp_const_high_losum_operand" "S")))]
2274   ""
2276   REAL_VALUE_TYPE r;
2277   long i;
2279   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2280   REAL_VALUE_TO_TARGET_SINGLE (r, i);
2281   operands[1] = GEN_INT (i);
2282   return "sethi\t%%hi(%1), %0";
2285 (define_split
2286   [(set (match_operand:SF 0 "register_operand" "")
2287         (match_operand:SF 1 "fp_const_high_losum_operand" ""))]
2288   "REG_P (operands[0]) && SPARC_INT_REG_P (REGNO (operands[0]))"
2289   [(set (match_dup 0) (high:SF (match_dup 1)))
2290    (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
2292 (define_expand "movdf"
2293   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2294         (match_operand:DF 1 "general_operand" ""))]
2295   ""
2297   if (sparc_expand_move (DFmode, operands))
2298     DONE;
2301 (define_insn "*movdf_insn_sp32"
2302   [(set (match_operand:DF 0 "nonimmediate_operand" "=b,b,e,e,*r, f,  e,T,W,U,T,  f,  *r,  o,o")
2303         (match_operand:DF 1 "input_operand"         "G,C,e,e, f,*r,W#F,G,e,T,U,o#F,*roF,*rG,f"))]
2304   "! TARGET_ARCH64
2305    && (register_operand (operands[0], DFmode)
2306        || register_or_zero_or_all_ones_operand (operands[1], DFmode))"
2307   "@
2308   fzero\t%0
2309   fone\t%0
2310   fmovd\t%1, %0
2311   #
2312   #
2313   #
2314   ldd\t%1, %0
2315   stx\t%r1, %0
2316   std\t%1, %0
2317   ldd\t%1, %0
2318   std\t%1, %0
2319   #
2320   #
2321   #
2322   #"
2323   [(set_attr "type" "visl,visl,fpmove,*,*,*,fpload,store,fpstore,load,store,*,*,*,*")
2324    (set_attr "length" "*,*,*,2,2,2,*,*,*,*,*,2,2,2,2")
2325    (set_attr "fptype" "double,double,double,*,*,*,*,*,*,*,*,*,*,*,*")
2326    (set_attr "cpu_feature" "vis,vis,v9,fpunotv9,vis3,vis3,fpu,v9,fpu,*,*,fpu,*,*,fpu")])
2328 (define_insn "*movdf_insn_sp64"
2329   [(set (match_operand:DF 0 "nonimmediate_operand" "=b,b,e,*r, e,  e,W, *r,*r,  m,*r")
2330         (match_operand:DF 1 "input_operand"         "G,C,e, e,*r,W#F,e,*rG, m,*rG, F"))]
2331   "TARGET_ARCH64
2332    && (register_operand (operands[0], DFmode)
2333        || register_or_zero_or_all_ones_operand (operands[1], DFmode))"
2334   "@
2335   fzero\t%0
2336   fone\t%0
2337   fmovd\t%1, %0
2338   movdtox\t%1, %0
2339   movxtod\t%1, %0
2340   ldd\t%1, %0
2341   std\t%1, %0
2342   mov\t%r1, %0
2343   ldx\t%1, %0
2344   stx\t%r1, %0
2345   #"
2346   [(set_attr "type" "visl,visl,fpmove,vismv,vismv,load,store,*,load,store,*")
2347    (set_attr "length" "*,*,*,*,*,*,*,*,*,*,2")
2348    (set_attr "fptype" "double,double,double,double,double,*,*,*,*,*,*")
2349    (set_attr "cpu_feature" "vis,vis,fpu,vis3,vis3,fpu,fpu,*,*,*,*")])
2351 ;; This pattern builds DFmode constants in integer registers.
2352 (define_split
2353   [(set (match_operand:DF 0 "register_operand" "")
2354         (match_operand:DF 1 "const_double_operand" ""))]
2355   "REG_P (operands[0])
2356    && SPARC_INT_REG_P (REGNO (operands[0]))
2357    && ! const_zero_operand (operands[1], GET_MODE (operands[0]))
2358    && reload_completed"
2359   [(clobber (const_int 0))]
2361   operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
2363   if (TARGET_ARCH64)
2364     {
2365 #if HOST_BITS_PER_WIDE_INT == 32
2366       gcc_unreachable ();
2367 #else
2368       enum machine_mode mode = GET_MODE (operands[1]);
2369       rtx tem = simplify_subreg (DImode, operands[1], mode, 0);
2370       emit_insn (gen_movdi (operands[0], tem));
2371 #endif
2372     }
2373   else
2374     {
2375       enum machine_mode mode = GET_MODE (operands[1]);
2376       rtx hi = simplify_subreg (SImode, operands[1], mode, 0);
2377       rtx lo = simplify_subreg (SImode, operands[1], mode, 4);
2379       gcc_assert (GET_CODE (hi) == CONST_INT);
2380       gcc_assert (GET_CODE (lo) == CONST_INT);
2382       emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), hi));
2384       /* Slick... but this trick loses if this subreg constant part
2385          can be done in one insn.  */
2386       if (lo == hi
2387           && ! SPARC_SETHI32_P (INTVAL (hi))
2388           && ! SPARC_SIMM13_P (INTVAL (hi)))
2389         {
2390           emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2391                                 gen_highpart (SImode, operands[0])));
2392         }
2393       else
2394         {
2395           emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), lo));
2396         }
2397     }
2398   DONE;
2401 ;; Ok, now the splits to handle all the multi insn and
2402 ;; mis-aligned memory address cases.
2403 ;; In these splits please take note that we must be
2404 ;; careful when V9 but not ARCH64 because the integer
2405 ;; register DFmode cases must be handled.
2406 (define_split
2407   [(set (match_operand:DF 0 "register_operand" "")
2408         (match_operand:DF 1 "register_operand" ""))]
2409   "(! TARGET_V9
2410     || (! TARGET_ARCH64
2411         && sparc_split_regreg_legitimate (operands[0],
2412                                           operands[1])))
2413    && reload_completed"
2414   [(clobber (const_int 0))]
2416   rtx set_dest = operands[0];
2417   rtx set_src = operands[1];
2418   rtx dest1, dest2;
2419   rtx src1, src2;
2421   dest1 = gen_highpart (SFmode, set_dest);
2422   dest2 = gen_lowpart (SFmode, set_dest);
2423   src1 = gen_highpart (SFmode, set_src);
2424   src2 = gen_lowpart (SFmode, set_src);
2426   /* Now emit using the real source and destination we found, swapping
2427      the order if we detect overlap.  */
2428   if (reg_overlap_mentioned_p (dest1, src2))
2429     {
2430       emit_move_insn_1 (dest2, src2);
2431       emit_move_insn_1 (dest1, src1);
2432     }
2433   else
2434     {
2435       emit_move_insn_1 (dest1, src1);
2436       emit_move_insn_1 (dest2, src2);
2437     }
2438   DONE;
2441 (define_split
2442   [(set (match_operand:DF 0 "register_operand" "")
2443         (match_operand:DF 1 "memory_operand" ""))]
2444   "reload_completed
2445    && ! TARGET_ARCH64
2446    && (((REGNO (operands[0]) % 2) != 0)
2447        || ! mem_min_alignment (operands[1], 8))
2448    && offsettable_memref_p (operands[1])"
2449   [(clobber (const_int 0))]
2451   rtx word0, word1;
2453   word0 = adjust_address (operands[1], SFmode, 0);
2454   word1 = adjust_address (operands[1], SFmode, 4);
2456   if (reg_overlap_mentioned_p (gen_highpart (SFmode, operands[0]), word1))
2457     {
2458       emit_move_insn_1 (gen_lowpart (SFmode, operands[0]), word1);
2459       emit_move_insn_1 (gen_highpart (SFmode, operands[0]), word0);
2460     }
2461   else
2462     {
2463       emit_move_insn_1 (gen_highpart (SFmode, operands[0]), word0);
2464       emit_move_insn_1 (gen_lowpart (SFmode, operands[0]), word1);
2465     }
2466   DONE;
2469 (define_split
2470   [(set (match_operand:DF 0 "memory_operand" "")
2471         (match_operand:DF 1 "register_operand" ""))]
2472   "reload_completed
2473    && ! TARGET_ARCH64
2474    && (((REGNO (operands[1]) % 2) != 0)
2475        || ! mem_min_alignment (operands[0], 8))
2476    && offsettable_memref_p (operands[0])"
2477   [(clobber (const_int 0))]
2479   rtx word0, word1;
2481   word0 = adjust_address (operands[0], SFmode, 0);
2482   word1 = adjust_address (operands[0], SFmode, 4);
2484   emit_move_insn_1 (word0, gen_highpart (SFmode, operands[1]));
2485   emit_move_insn_1 (word1, gen_lowpart (SFmode, operands[1]));
2486   DONE;
2489 (define_split
2490   [(set (match_operand:DF 0 "memory_operand" "")
2491         (match_operand:DF 1 "const_zero_operand" ""))]
2492   "reload_completed
2493    && (! TARGET_V9
2494        || (! TARGET_ARCH64
2495            && ! mem_min_alignment (operands[0], 8)))
2496    && offsettable_memref_p (operands[0])"
2497   [(clobber (const_int 0))]
2499   rtx dest1, dest2;
2501   dest1 = adjust_address (operands[0], SFmode, 0);
2502   dest2 = adjust_address (operands[0], SFmode, 4);
2504   emit_move_insn_1 (dest1, CONST0_RTX (SFmode));
2505   emit_move_insn_1 (dest2, CONST0_RTX (SFmode));
2506   DONE;
2509 (define_split
2510   [(set (match_operand:DF 0 "register_operand" "")
2511         (match_operand:DF 1 "const_zero_operand" ""))]
2512   "reload_completed
2513    && ! TARGET_ARCH64
2514    && ((GET_CODE (operands[0]) == REG
2515         && SPARC_INT_REG_P (REGNO (operands[0])))
2516        || (GET_CODE (operands[0]) == SUBREG
2517            && GET_CODE (SUBREG_REG (operands[0])) == REG
2518            && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
2519   [(clobber (const_int 0))]
2521   rtx set_dest = operands[0];
2522   rtx dest1, dest2;
2524   dest1 = gen_highpart (SFmode, set_dest);
2525   dest2 = gen_lowpart (SFmode, set_dest);
2526   emit_move_insn_1 (dest1, CONST0_RTX (SFmode));
2527   emit_move_insn_1 (dest2, CONST0_RTX (SFmode));
2528   DONE;
2531 (define_expand "movtf"
2532   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2533         (match_operand:TF 1 "general_operand" ""))]
2534   ""
2536   if (sparc_expand_move (TFmode, operands))
2537     DONE;
2540 (define_insn "*movtf_insn_sp32"
2541   [(set (match_operand:TF 0 "nonimmediate_operand" "=b, e,o,  o,U,  r")
2542         (match_operand:TF 1 "input_operand"        " G,oe,e,rGU,o,roG"))]
2543   "! TARGET_ARCH64
2544    && (register_operand (operands[0], TFmode)
2545        || register_or_zero_operand (operands[1], TFmode))"
2546   "#"
2547   [(set_attr "length" "4,4,4,4,4,4")
2548    (set_attr "cpu_feature" "fpu,fpu,fpu,*,*,*")])
2550 (define_insn "*movtf_insn_sp64"
2551   [(set (match_operand:TF 0 "nonimmediate_operand" "=b, e,o, o,  r")
2552         (match_operand:TF 1 "input_operand"         "G,oe,e,rG,roG"))]
2553   "TARGET_ARCH64
2554    && ! TARGET_HARD_QUAD
2555    && (register_operand (operands[0], TFmode)
2556        || register_or_zero_operand (operands[1], TFmode))"
2557   "#"
2558   [(set_attr "length" "2,2,2,2,2")
2559    (set_attr "cpu_feature" "fpu,fpu,fpu,*,*")])
2561 (define_insn "*movtf_insn_sp64_hq"
2562   [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,e,m, o,  r")
2563         (match_operand:TF 1 "input_operand"         "G,e,m,e,rG,roG"))]
2564   "TARGET_ARCH64
2565    && TARGET_HARD_QUAD
2566    && (register_operand (operands[0], TFmode)
2567        || register_or_zero_operand (operands[1], TFmode))"
2568   "@
2569   #
2570   fmovq\t%1, %0
2571   ldq\t%1, %0
2572   stq\t%1, %0
2573   #
2574   #"
2575   [(set_attr "type" "*,fpmove,fpload,fpstore,*,*")
2576    (set_attr "length" "2,*,*,*,2,2")])
2578 ;; Now all the splits to handle multi-insn TF mode moves.
2579 (define_split
2580   [(set (match_operand:TF 0 "register_operand" "")
2581         (match_operand:TF 1 "register_operand" ""))]
2582   "reload_completed
2583    && (! TARGET_ARCH64
2584        || (TARGET_FPU
2585            && ! TARGET_HARD_QUAD)
2586        || (! fp_register_operand (operands[0], TFmode)
2587            && ! fp_register_operand (operands[1], TFmode)))"
2588   [(clobber (const_int 0))]
2590   rtx set_dest = operands[0];
2591   rtx set_src = operands[1];
2592   rtx dest1, dest2;
2593   rtx src1, src2;
2595   dest1 = gen_df_reg (set_dest, 0);
2596   dest2 = gen_df_reg (set_dest, 1);
2597   src1 = gen_df_reg (set_src, 0);
2598   src2 = gen_df_reg (set_src, 1);
2600   /* Now emit using the real source and destination we found, swapping
2601      the order if we detect overlap.  */
2602   if (reg_overlap_mentioned_p (dest1, src2))
2603     {
2604       emit_insn (gen_movdf (dest2, src2));
2605       emit_insn (gen_movdf (dest1, src1));
2606     }
2607   else
2608     {
2609       emit_insn (gen_movdf (dest1, src1));
2610       emit_insn (gen_movdf (dest2, src2));
2611     }
2612   DONE;
2615 (define_split
2616   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2617         (match_operand:TF 1 "const_zero_operand" ""))]
2618   "reload_completed"
2619   [(clobber (const_int 0))]
2621   rtx set_dest = operands[0];
2622   rtx dest1, dest2;
2624   switch (GET_CODE (set_dest))
2625     {
2626     case REG:
2627       dest1 = gen_df_reg (set_dest, 0);
2628       dest2 = gen_df_reg (set_dest, 1);
2629       break;
2630     case MEM:
2631       dest1 = adjust_address (set_dest, DFmode, 0);
2632       dest2 = adjust_address (set_dest, DFmode, 8);
2633       break;
2634     default:
2635       gcc_unreachable ();
2636     }
2638   emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
2639   emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
2640   DONE;
2643 (define_split
2644   [(set (match_operand:TF 0 "register_operand" "")
2645         (match_operand:TF 1 "memory_operand" ""))]
2646   "(reload_completed
2647     && offsettable_memref_p (operands[1])
2648     && (! TARGET_ARCH64
2649         || ! TARGET_HARD_QUAD
2650         || ! fp_register_operand (operands[0], TFmode)))"
2651   [(clobber (const_int 0))]
2653   rtx word0 = adjust_address (operands[1], DFmode, 0);
2654   rtx word1 = adjust_address (operands[1], DFmode, 8);
2655   rtx set_dest, dest1, dest2;
2657   set_dest = operands[0];
2659   dest1 = gen_df_reg (set_dest, 0);
2660   dest2 = gen_df_reg (set_dest, 1);
2662   /* Now output, ordering such that we don't clobber any registers
2663      mentioned in the address.  */
2664   if (reg_overlap_mentioned_p (dest1, word1))
2666     {
2667       emit_insn (gen_movdf (dest2, word1));
2668       emit_insn (gen_movdf (dest1, word0));
2669     }
2670   else
2671    {
2672       emit_insn (gen_movdf (dest1, word0));
2673       emit_insn (gen_movdf (dest2, word1));
2674    }
2675   DONE;
2678 (define_split
2679   [(set (match_operand:TF 0 "memory_operand" "")
2680         (match_operand:TF 1 "register_operand" ""))]
2681   "(reload_completed
2682     && offsettable_memref_p (operands[0])
2683     && (! TARGET_ARCH64
2684         || ! TARGET_HARD_QUAD
2685         || ! fp_register_operand (operands[1], TFmode)))"
2686   [(clobber (const_int 0))]
2688   rtx set_src = operands[1];
2690   emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
2691                         gen_df_reg (set_src, 0)));
2692   emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
2693                         gen_df_reg (set_src, 1)));
2694   DONE;
2698 ;; SPARC-V9 conditional move instructions
2700 ;; We can handle larger constants here for some flavors, but for now we keep
2701 ;; it simple and only allow those constants supported by all flavors.
2702 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
2703 ;; 3 contains the constant if one is present, but we handle either for
2704 ;; generality (sparc.c puts a constant in operand 2).
2706 ;; Our instruction patterns, on the other hand, canonicalize such that
2707 ;; operand 3 must be the set destination.
2709 (define_expand "mov<I:mode>cc"
2710   [(set (match_operand:I 0 "register_operand" "")
2711         (if_then_else:I (match_operand 1 "comparison_operator" "")
2712                         (match_operand:I 2 "arith10_operand" "")
2713                         (match_operand:I 3 "arith10_operand" "")))]
2714   "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2716   if (! sparc_expand_conditional_move (<I:MODE>mode, operands))
2717     FAIL;
2718   DONE;
2721 (define_expand "mov<F:mode>cc"
2722   [(set (match_operand:F 0 "register_operand" "")
2723         (if_then_else:F (match_operand 1 "comparison_operator" "")
2724                         (match_operand:F 2 "register_operand" "")
2725                         (match_operand:F 3 "register_operand" "")))]
2726   "TARGET_V9 && TARGET_FPU"
2728   if (! sparc_expand_conditional_move (<F:MODE>mode, operands))
2729     FAIL;
2730   DONE;
2733 ;; Conditional move define_insns
2735 (define_insn "*mov<I:mode>_cc_v9"
2736   [(set (match_operand:I 0 "register_operand" "=r")
2737         (if_then_else:I (match_operator 1 "comparison_operator"
2738                                [(match_operand 2 "icc_or_fcc_register_operand" "X")
2739                                 (const_int 0)])
2740                         (match_operand:I 3 "arith11_operand" "rL")
2741                         (match_operand:I 4 "register_operand" "0")))]
2742   "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2743   "mov%C1\t%x2, %3, %0"
2744   [(set_attr "type" "cmove")])
2746 (define_insn "*mov<I:mode>_cc_reg_sp64"
2747   [(set (match_operand:I 0 "register_operand" "=r")
2748         (if_then_else:I (match_operator 1 "v9_register_compare_operator"
2749                                 [(match_operand:DI 2 "register_operand" "r")
2750                                  (const_int 0)])
2751                         (match_operand:I 3 "arith10_operand" "rM")
2752                         (match_operand:I 4 "register_operand" "0")))]
2753   "TARGET_ARCH64"
2754   "movr%D1\t%2, %r3, %0"
2755   [(set_attr "type" "cmove")])
2757 (define_insn "*movsf_cc_v9"
2758   [(set (match_operand:SF 0 "register_operand" "=f")
2759         (if_then_else:SF (match_operator 1 "comparison_operator"
2760                                 [(match_operand 2 "icc_or_fcc_register_operand" "X")
2761                                  (const_int 0)])
2762                          (match_operand:SF 3 "register_operand" "f")
2763                          (match_operand:SF 4 "register_operand" "0")))]
2764   "TARGET_V9 && TARGET_FPU"
2765   "fmovs%C1\t%x2, %3, %0"
2766   [(set_attr "type" "fpcmove")])
2768 (define_insn "*movsf_cc_reg_sp64"
2769   [(set (match_operand:SF 0 "register_operand" "=f")
2770         (if_then_else:SF (match_operator 1 "v9_register_compare_operator"
2771                                 [(match_operand:DI 2 "register_operand" "r")
2772                                  (const_int 0)])
2773                          (match_operand:SF 3 "register_operand" "f")
2774                          (match_operand:SF 4 "register_operand" "0")))]
2775   "TARGET_ARCH64 && TARGET_FPU"
2776   "fmovrs%D1\t%2, %3, %0"
2777   [(set_attr "type" "fpcrmove")])
2779 ;; Named because invoked by movtf_cc_v9
2780 (define_insn "movdf_cc_v9"
2781   [(set (match_operand:DF 0 "register_operand" "=e")
2782         (if_then_else:DF (match_operator 1 "comparison_operator"
2783                                 [(match_operand 2 "icc_or_fcc_register_operand" "X")
2784                                  (const_int 0)])
2785                          (match_operand:DF 3 "register_operand" "e")
2786                          (match_operand:DF 4 "register_operand" "0")))]
2787   "TARGET_V9 && TARGET_FPU"
2788   "fmovd%C1\t%x2, %3, %0"
2789   [(set_attr "type" "fpcmove")
2790    (set_attr "fptype" "double")])
2792 ;; Named because invoked by movtf_cc_reg_sp64
2793 (define_insn "movdf_cc_reg_sp64"
2794   [(set (match_operand:DF 0 "register_operand" "=e")
2795         (if_then_else:DF (match_operator 1 "v9_register_compare_operator"
2796                                 [(match_operand:DI 2 "register_operand" "r")
2797                                  (const_int 0)])
2798                          (match_operand:DF 3 "register_operand" "e")
2799                          (match_operand:DF 4 "register_operand" "0")))]
2800   "TARGET_ARCH64 && TARGET_FPU"
2801   "fmovrd%D1\t%2, %3, %0"
2802   [(set_attr "type" "fpcrmove")
2803    (set_attr "fptype" "double")])
2805 (define_insn "*movtf_cc_hq_v9"
2806   [(set (match_operand:TF 0 "register_operand" "=e")
2807         (if_then_else:TF (match_operator 1 "comparison_operator"
2808                                 [(match_operand 2 "icc_or_fcc_register_operand" "X")
2809                                  (const_int 0)])
2810                          (match_operand:TF 3 "register_operand" "e")
2811                          (match_operand:TF 4 "register_operand" "0")))]
2812   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
2813   "fmovq%C1\t%x2, %3, %0"
2814   [(set_attr "type" "fpcmove")])
2816 (define_insn "*movtf_cc_reg_hq_sp64"
2817   [(set (match_operand:TF 0 "register_operand" "=e")
2818         (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2819                                 [(match_operand:DI 2 "register_operand" "r")
2820                                  (const_int 0)])
2821                          (match_operand:TF 3 "register_operand" "e")
2822                          (match_operand:TF 4 "register_operand" "0")))]
2823   "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
2824   "fmovrq%D1\t%2, %3, %0"
2825   [(set_attr "type" "fpcrmove")])
2827 (define_insn_and_split "*movtf_cc_v9"
2828   [(set (match_operand:TF 0 "register_operand" "=e")
2829         (if_then_else:TF (match_operator 1 "comparison_operator"
2830                             [(match_operand 2 "icc_or_fcc_register_operand" "X")
2831                              (const_int 0)])
2832                          (match_operand:TF 3 "register_operand" "e")
2833                          (match_operand:TF 4 "register_operand" "0")))]
2834   "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
2835   "#"
2836   "&& reload_completed"
2837   [(clobber (const_int 0))]
2839   rtx set_dest = operands[0];
2840   rtx set_srca = operands[3];
2841   rtx dest1, dest2;
2842   rtx srca1, srca2;
2844   dest1 = gen_df_reg (set_dest, 0);
2845   dest2 = gen_df_reg (set_dest, 1);
2846   srca1 = gen_df_reg (set_srca, 0);
2847   srca2 = gen_df_reg (set_srca, 1);
2849   if (reg_overlap_mentioned_p (dest1, srca2))
2850     {
2851       emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, dest2));
2852       emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, dest1));
2853     }
2854   else
2855     {
2856       emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, dest1));
2857       emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, dest2));
2858     }
2859   DONE;
2861   [(set_attr "length" "2")])
2863 (define_insn_and_split "*movtf_cc_reg_sp64"
2864   [(set (match_operand:TF 0 "register_operand" "=e")
2865         (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2866                                 [(match_operand:DI 2 "register_operand" "r")
2867                                  (const_int 0)])
2868                          (match_operand:TF 3 "register_operand" "e")
2869                          (match_operand:TF 4 "register_operand" "0")))]
2870   "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
2871   "#"
2872   "&& reload_completed"
2873   [(clobber (const_int 0))]
2875   rtx set_dest = operands[0];
2876   rtx set_srca = operands[3];
2877   rtx dest1, dest2;
2878   rtx srca1, srca2;
2880   dest1 = gen_df_reg (set_dest, 0);
2881   dest2 = gen_df_reg (set_dest, 1);
2882   srca1 = gen_df_reg (set_srca, 0);
2883   srca2 = gen_df_reg (set_srca, 1);
2885   if (reg_overlap_mentioned_p (dest1, srca2))
2886     {
2887       emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, dest2));
2888       emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, dest1));
2889     }
2890   else
2891     {
2892       emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, dest1));
2893       emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, dest2));
2894     }
2895   DONE;
2897   [(set_attr "length" "2")])
2900 ;; Zero-extension instructions
2902 ;; These patterns originally accepted general_operands, however, slightly
2903 ;; better code is generated by only accepting register_operands, and then
2904 ;; letting combine generate the ldu[hb] insns.
2906 (define_expand "zero_extendhisi2"
2907   [(set (match_operand:SI 0 "register_operand" "")
2908         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
2909   ""
2911   rtx temp = gen_reg_rtx (SImode);
2912   rtx shift_16 = GEN_INT (16);
2913   int op1_subbyte = 0;
2915   if (GET_CODE (operand1) == SUBREG)
2916     {
2917       op1_subbyte = SUBREG_BYTE (operand1);
2918       op1_subbyte /= GET_MODE_SIZE (SImode);
2919       op1_subbyte *= GET_MODE_SIZE (SImode);
2920       operand1 = XEXP (operand1, 0);
2921     }
2923   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
2924                           shift_16));
2925   emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
2926   DONE;
2929 (define_insn "*zero_extendhisi2_insn"
2930   [(set (match_operand:SI 0 "register_operand" "=r")
2931         (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2932   ""
2933   "lduh\t%1, %0"
2934   [(set_attr "type" "load")
2935    (set_attr "us3load_type" "3cycle")])
2937 (define_expand "zero_extendqihi2"
2938   [(set (match_operand:HI 0 "register_operand" "")
2939         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
2940   ""
2941   "")
2943 (define_insn "*zero_extendqihi2_insn"
2944   [(set (match_operand:HI 0 "register_operand" "=r,r")
2945         (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
2946   "GET_CODE (operands[1]) != CONST_INT"
2947   "@
2948    and\t%1, 0xff, %0
2949    ldub\t%1, %0"
2950   [(set_attr "type" "*,load")
2951    (set_attr "us3load_type" "*,3cycle")])
2953 (define_expand "zero_extendqisi2"
2954   [(set (match_operand:SI 0 "register_operand" "")
2955         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
2956   ""
2957   "")
2959 (define_insn "*zero_extendqisi2_insn"
2960   [(set (match_operand:SI 0 "register_operand" "=r,r")
2961         (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
2962   "GET_CODE (operands[1]) != CONST_INT"
2963   "@
2964    and\t%1, 0xff, %0
2965    ldub\t%1, %0"
2966   [(set_attr "type" "*,load")
2967    (set_attr "us3load_type" "*,3cycle")])
2969 (define_expand "zero_extendqidi2"
2970   [(set (match_operand:DI 0 "register_operand" "")
2971         (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
2972   "TARGET_ARCH64"
2973   "")
2975 (define_insn "*zero_extendqidi2_insn"
2976   [(set (match_operand:DI 0 "register_operand" "=r,r")
2977         (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
2978   "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
2979   "@
2980    and\t%1, 0xff, %0
2981    ldub\t%1, %0"
2982   [(set_attr "type" "*,load")
2983    (set_attr "us3load_type" "*,3cycle")])
2985 (define_expand "zero_extendhidi2"
2986   [(set (match_operand:DI 0 "register_operand" "")
2987         (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
2988   "TARGET_ARCH64"
2990   rtx temp = gen_reg_rtx (DImode);
2991   rtx shift_48 = GEN_INT (48);
2992   int op1_subbyte = 0;
2994   if (GET_CODE (operand1) == SUBREG)
2995     {
2996       op1_subbyte = SUBREG_BYTE (operand1);
2997       op1_subbyte /= GET_MODE_SIZE (DImode);
2998       op1_subbyte *= GET_MODE_SIZE (DImode);
2999       operand1 = XEXP (operand1, 0);
3000     }
3002   emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3003                           shift_48));
3004   emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
3005   DONE;
3008 (define_insn "*zero_extendhidi2_insn"
3009   [(set (match_operand:DI 0 "register_operand" "=r")
3010         (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3011   "TARGET_ARCH64"
3012   "lduh\t%1, %0"
3013   [(set_attr "type" "load")
3014    (set_attr "us3load_type" "3cycle")])
3016 ;; ??? Write truncdisi pattern using sra?
3018 (define_expand "zero_extendsidi2"
3019   [(set (match_operand:DI 0 "register_operand" "")
3020         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
3021   ""
3022   "")
3024 (define_insn "*zero_extendsidi2_insn_sp64"
3025   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
3026         (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m,*f")))]
3027   "TARGET_ARCH64
3028    && GET_CODE (operands[1]) != CONST_INT"
3029   "@
3030    srl\t%1, 0, %0
3031    lduw\t%1, %0
3032    movstouw\t%1, %0"
3033   [(set_attr "type" "shift,load,*")
3034    (set_attr "cpu_feature" "*,*,vis3")])
3036 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
3037   [(set (match_operand:DI 0 "register_operand" "=r")
3038         (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
3039   "! TARGET_ARCH64"
3040   "#"
3041   "&& reload_completed"
3042   [(set (match_dup 2) (match_dup 3))
3043    (set (match_dup 4) (match_dup 5))]
3045   rtx dest1, dest2;
3047   dest1 = gen_highpart (SImode, operands[0]);
3048   dest2 = gen_lowpart (SImode, operands[0]);
3050   /* Swap the order in case of overlap.  */
3051   if (REGNO (dest1) == REGNO (operands[1]))
3052     {
3053       operands[2] = dest2;
3054       operands[3] = operands[1];
3055       operands[4] = dest1;
3056       operands[5] = const0_rtx;
3057     }
3058   else
3059     {
3060       operands[2] = dest1;
3061       operands[3] = const0_rtx;
3062       operands[4] = dest2;
3063       operands[5] = operands[1];
3064     }
3066   [(set_attr "length" "2")])
3068 ;; Simplify comparisons of extended values.
3070 (define_insn "*cmp_zero_extendqisi2"
3071   [(set (reg:CC CC_REG)
3072         (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
3073                     (const_int 0)))]
3074   ""
3075   "andcc\t%0, 0xff, %%g0"
3076   [(set_attr "type" "compare")])
3078 (define_insn "*cmp_zero_qi"
3079   [(set (reg:CC CC_REG)
3080         (compare:CC (match_operand:QI 0 "register_operand" "r")
3081                     (const_int 0)))]
3082   ""
3083   "andcc\t%0, 0xff, %%g0"
3084   [(set_attr "type" "compare")])
3086 (define_insn "*cmp_zero_extendqisi2_set"
3087   [(set (reg:CC CC_REG)
3088         (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
3089                     (const_int 0)))
3090    (set (match_operand:SI 0 "register_operand" "=r")
3091         (zero_extend:SI (match_dup 1)))]
3092   ""
3093   "andcc\t%1, 0xff, %0"
3094   [(set_attr "type" "compare")])
3096 (define_insn "*cmp_zero_extendqisi2_andcc_set"
3097   [(set (reg:CC CC_REG)
3098         (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
3099                             (const_int 255))
3100                     (const_int 0)))
3101    (set (match_operand:SI 0 "register_operand" "=r")
3102         (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
3103   ""
3104   "andcc\t%1, 0xff, %0"
3105   [(set_attr "type" "compare")])
3107 (define_insn "*cmp_zero_extendqidi2"
3108   [(set (reg:CCX CC_REG)
3109         (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
3110                      (const_int 0)))]
3111   "TARGET_ARCH64"
3112   "andcc\t%0, 0xff, %%g0"
3113   [(set_attr "type" "compare")])
3115 (define_insn "*cmp_zero_qi_sp64"
3116   [(set (reg:CCX CC_REG)
3117         (compare:CCX (match_operand:QI 0 "register_operand" "r")
3118                      (const_int 0)))]
3119   "TARGET_ARCH64"
3120   "andcc\t%0, 0xff, %%g0"
3121   [(set_attr "type" "compare")])
3123 (define_insn "*cmp_zero_extendqidi2_set"
3124   [(set (reg:CCX CC_REG)
3125         (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
3126                      (const_int 0)))
3127    (set (match_operand:DI 0 "register_operand" "=r")
3128         (zero_extend:DI (match_dup 1)))]
3129   "TARGET_ARCH64"
3130   "andcc\t%1, 0xff, %0"
3131   [(set_attr "type" "compare")])
3133 (define_insn "*cmp_zero_extendqidi2_andcc_set"
3134   [(set (reg:CCX CC_REG)
3135         (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
3136                              (const_int 255))
3137                      (const_int 0)))
3138    (set (match_operand:DI 0 "register_operand" "=r")
3139         (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
3140   "TARGET_ARCH64"
3141   "andcc\t%1, 0xff, %0"
3142   [(set_attr "type" "compare")])
3144 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
3146 (define_insn "*cmp_siqi_trunc"
3147   [(set (reg:CC CC_REG)
3148         (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
3149                     (const_int 0)))]
3150   ""
3151   "andcc\t%0, 0xff, %%g0"
3152   [(set_attr "type" "compare")])
3154 (define_insn "*cmp_siqi_trunc_set"
3155   [(set (reg:CC CC_REG)
3156         (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
3157                     (const_int 0)))
3158    (set (match_operand:QI 0 "register_operand" "=r")
3159         (subreg:QI (match_dup 1) 3))]
3160   ""
3161   "andcc\t%1, 0xff, %0"
3162   [(set_attr "type" "compare")])
3164 (define_insn "*cmp_diqi_trunc"
3165   [(set (reg:CC CC_REG)
3166         (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
3167                     (const_int 0)))]
3168   "TARGET_ARCH64"
3169   "andcc\t%0, 0xff, %%g0"
3170   [(set_attr "type" "compare")])
3172 (define_insn "*cmp_diqi_trunc_set"
3173   [(set (reg:CC CC_REG)
3174         (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
3175                     (const_int 0)))
3176    (set (match_operand:QI 0 "register_operand" "=r")
3177         (subreg:QI (match_dup 1) 7))]
3178   "TARGET_ARCH64"
3179   "andcc\t%1, 0xff, %0"
3180   [(set_attr "type" "compare")])
3183 ;; Sign-extension instructions
3185 ;; These patterns originally accepted general_operands, however, slightly
3186 ;; better code is generated by only accepting register_operands, and then
3187 ;; letting combine generate the lds[hb] insns.
3189 (define_expand "extendhisi2"
3190   [(set (match_operand:SI 0 "register_operand" "")
3191         (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
3192   ""
3194   rtx temp = gen_reg_rtx (SImode);
3195   rtx shift_16 = GEN_INT (16);
3196   int op1_subbyte = 0;
3198   if (GET_CODE (operand1) == SUBREG)
3199     {
3200       op1_subbyte = SUBREG_BYTE (operand1);
3201       op1_subbyte /= GET_MODE_SIZE (SImode);
3202       op1_subbyte *= GET_MODE_SIZE (SImode);
3203       operand1 = XEXP (operand1, 0);
3204     }
3206   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3207                           shift_16));
3208   emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
3209   DONE;
3212 (define_insn "*sign_extendhisi2_insn"
3213   [(set (match_operand:SI 0 "register_operand" "=r")
3214         (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3215   ""
3216   "ldsh\t%1, %0"
3217   [(set_attr "type" "sload")
3218    (set_attr "us3load_type" "3cycle")])
3220 (define_expand "extendqihi2"
3221   [(set (match_operand:HI 0 "register_operand" "")
3222         (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
3223   ""
3225   rtx temp = gen_reg_rtx (SImode);
3226   rtx shift_24 = GEN_INT (24);
3227   int op1_subbyte = 0;
3228   int op0_subbyte = 0;
3230   if (GET_CODE (operand1) == SUBREG)
3231     {
3232       op1_subbyte = SUBREG_BYTE (operand1);
3233       op1_subbyte /= GET_MODE_SIZE (SImode);
3234       op1_subbyte *= GET_MODE_SIZE (SImode);
3235       operand1 = XEXP (operand1, 0);
3236     }
3237   if (GET_CODE (operand0) == SUBREG)
3238     {
3239       op0_subbyte = SUBREG_BYTE (operand0);
3240       op0_subbyte /= GET_MODE_SIZE (SImode);
3241       op0_subbyte *= GET_MODE_SIZE (SImode);
3242       operand0 = XEXP (operand0, 0);
3243     }
3244   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3245                           shift_24));
3246   if (GET_MODE (operand0) != SImode)
3247     operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
3248   emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3249   DONE;
3252 (define_insn "*sign_extendqihi2_insn"
3253   [(set (match_operand:HI 0 "register_operand" "=r")
3254         (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3255   ""
3256   "ldsb\t%1, %0"
3257   [(set_attr "type" "sload")
3258    (set_attr "us3load_type" "3cycle")])
3260 (define_expand "extendqisi2"
3261   [(set (match_operand:SI 0 "register_operand" "")
3262         (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
3263   ""
3265   rtx temp = gen_reg_rtx (SImode);
3266   rtx shift_24 = GEN_INT (24);
3267   int op1_subbyte = 0;
3269   if (GET_CODE (operand1) == SUBREG)
3270     {
3271       op1_subbyte = SUBREG_BYTE (operand1);
3272       op1_subbyte /= GET_MODE_SIZE (SImode);
3273       op1_subbyte *= GET_MODE_SIZE (SImode);
3274       operand1 = XEXP (operand1, 0);
3275     }
3277   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3278                           shift_24));
3279   emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3280   DONE;
3283 (define_insn "*sign_extendqisi2_insn"
3284   [(set (match_operand:SI 0 "register_operand" "=r")
3285         (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3286   ""
3287   "ldsb\t%1, %0"
3288   [(set_attr "type" "sload")
3289    (set_attr "us3load_type" "3cycle")])
3291 (define_expand "extendqidi2"
3292   [(set (match_operand:DI 0 "register_operand" "")
3293         (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
3294   "TARGET_ARCH64"
3296   rtx temp = gen_reg_rtx (DImode);
3297   rtx shift_56 = GEN_INT (56);
3298   int op1_subbyte = 0;
3300   if (GET_CODE (operand1) == SUBREG)
3301     {
3302       op1_subbyte = SUBREG_BYTE (operand1);
3303       op1_subbyte /= GET_MODE_SIZE (DImode);
3304       op1_subbyte *= GET_MODE_SIZE (DImode);
3305       operand1 = XEXP (operand1, 0);
3306     }
3308   emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3309                           shift_56));
3310   emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
3311   DONE;
3314 (define_insn "*sign_extendqidi2_insn"
3315   [(set (match_operand:DI 0 "register_operand" "=r")
3316         (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3317   "TARGET_ARCH64"
3318   "ldsb\t%1, %0"
3319   [(set_attr "type" "sload")
3320    (set_attr "us3load_type" "3cycle")])
3322 (define_expand "extendhidi2"
3323   [(set (match_operand:DI 0 "register_operand" "")
3324         (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
3325   "TARGET_ARCH64"
3327   rtx temp = gen_reg_rtx (DImode);
3328   rtx shift_48 = GEN_INT (48);
3329   int op1_subbyte = 0;
3331   if (GET_CODE (operand1) == SUBREG)
3332     {
3333       op1_subbyte = SUBREG_BYTE (operand1);
3334       op1_subbyte /= GET_MODE_SIZE (DImode);
3335       op1_subbyte *= GET_MODE_SIZE (DImode);
3336       operand1 = XEXP (operand1, 0);
3337     }
3339   emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3340                           shift_48));
3341   emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
3342   DONE;
3345 (define_insn "*sign_extendhidi2_insn"
3346   [(set (match_operand:DI 0 "register_operand" "=r")
3347         (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3348   "TARGET_ARCH64"
3349   "ldsh\t%1, %0"
3350   [(set_attr "type" "sload")
3351    (set_attr "us3load_type" "3cycle")])
3353 (define_expand "extendsidi2"
3354   [(set (match_operand:DI 0 "register_operand" "")
3355         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3356   "TARGET_ARCH64"
3357   "")
3359 (define_insn "*sign_extendsidi2_insn"
3360   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
3361         (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m,*f")))]
3362   "TARGET_ARCH64"
3363   "@
3364   sra\t%1, 0, %0
3365   ldsw\t%1, %0
3366   movstosw\t%1, %0"
3367   [(set_attr "type" "shift,sload,*")
3368    (set_attr "us3load_type" "*,3cycle,*")
3369    (set_attr "cpu_feature" "*,*,vis3")])
3372 ;; Special pattern for optimizing bit-field compares.  This is needed
3373 ;; because combine uses this as a canonical form.
3375 (define_insn "*cmp_zero_extract"
3376   [(set (reg:CC CC_REG)
3377         (compare:CC
3378          (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
3379                           (match_operand:SI 1 "small_int_operand" "I")
3380                           (match_operand:SI 2 "small_int_operand" "I"))
3381          (const_int 0)))]
3382   "INTVAL (operands[2]) > 19"
3384   int len = INTVAL (operands[1]);
3385   int pos = 32 - INTVAL (operands[2]) - len;
3386   HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
3387   operands[1] = GEN_INT (mask);
3388   return "andcc\t%0, %1, %%g0";
3390   [(set_attr "type" "compare")])
3392 (define_insn "*cmp_zero_extract_sp64"
3393   [(set (reg:CCX CC_REG)
3394         (compare:CCX
3395          (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
3396                           (match_operand:SI 1 "small_int_operand" "I")
3397                           (match_operand:SI 2 "small_int_operand" "I"))
3398          (const_int 0)))]
3399   "TARGET_ARCH64 && INTVAL (operands[2]) > 51"
3401   int len = INTVAL (operands[1]);
3402   int pos = 64 - INTVAL (operands[2]) - len;
3403   HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
3404   operands[1] = GEN_INT (mask);
3405   return "andcc\t%0, %1, %%g0";
3407   [(set_attr "type" "compare")])
3410 ;; Conversions between float, double and long double.
3412 (define_insn "extendsfdf2"
3413   [(set (match_operand:DF 0 "register_operand" "=e")
3414         (float_extend:DF
3415          (match_operand:SF 1 "register_operand" "f")))]
3416   "TARGET_FPU"
3417   "fstod\t%1, %0"
3418   [(set_attr "type" "fp")
3419    (set_attr "fptype" "double")])
3421 (define_expand "extendsftf2"
3422   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3423         (float_extend:TF
3424          (match_operand:SF 1 "register_operand" "")))]
3425   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3426   "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3428 (define_insn "*extendsftf2_hq"
3429   [(set (match_operand:TF 0 "register_operand" "=e")
3430         (float_extend:TF
3431          (match_operand:SF 1 "register_operand" "f")))]
3432   "TARGET_FPU && TARGET_HARD_QUAD"
3433   "fstoq\t%1, %0"
3434   [(set_attr "type" "fp")])
3436 (define_expand "extenddftf2"
3437   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3438         (float_extend:TF
3439          (match_operand:DF 1 "register_operand" "")))]
3440   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3441   "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3443 (define_insn "*extenddftf2_hq"
3444   [(set (match_operand:TF 0 "register_operand" "=e")
3445         (float_extend:TF
3446          (match_operand:DF 1 "register_operand" "e")))]
3447   "TARGET_FPU && TARGET_HARD_QUAD"
3448   "fdtoq\t%1, %0"
3449   [(set_attr "type" "fp")])
3451 (define_insn "truncdfsf2"
3452   [(set (match_operand:SF 0 "register_operand" "=f")
3453         (float_truncate:SF
3454          (match_operand:DF 1 "register_operand" "e")))]
3455   "TARGET_FPU"
3456   "fdtos\t%1, %0"
3457   [(set_attr "type" "fp")
3458    (set_attr "fptype" "double")])
3460 (define_expand "trunctfsf2"
3461   [(set (match_operand:SF 0 "register_operand" "")
3462         (float_truncate:SF
3463          (match_operand:TF 1 "general_operand" "")))]
3464   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3465   "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3467 (define_insn "*trunctfsf2_hq"
3468   [(set (match_operand:SF 0 "register_operand" "=f")
3469         (float_truncate:SF
3470          (match_operand:TF 1 "register_operand" "e")))]
3471   "TARGET_FPU && TARGET_HARD_QUAD"
3472   "fqtos\t%1, %0"
3473   [(set_attr "type" "fp")])
3475 (define_expand "trunctfdf2"
3476   [(set (match_operand:DF 0 "register_operand" "")
3477         (float_truncate:DF
3478          (match_operand:TF 1 "general_operand" "")))]
3479   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3480   "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3482 (define_insn "*trunctfdf2_hq"
3483   [(set (match_operand:DF 0 "register_operand" "=e")
3484         (float_truncate:DF
3485          (match_operand:TF 1 "register_operand" "e")))]
3486   "TARGET_FPU && TARGET_HARD_QUAD"
3487   "fqtod\t%1, %0"
3488   [(set_attr "type" "fp")])
3491 ;; Conversion between fixed point and floating point.
3493 (define_insn "floatsisf2"
3494   [(set (match_operand:SF 0 "register_operand" "=f")
3495         (float:SF (match_operand:SI 1 "register_operand" "f")))]
3496   "TARGET_FPU"
3497   "fitos\t%1, %0"
3498   [(set_attr "type" "fp")
3499    (set_attr "fptype" "double")])
3501 (define_insn "floatsidf2"
3502   [(set (match_operand:DF 0 "register_operand" "=e")
3503         (float:DF (match_operand:SI 1 "register_operand" "f")))]
3504   "TARGET_FPU"
3505   "fitod\t%1, %0"
3506   [(set_attr "type" "fp")
3507    (set_attr "fptype" "double")])
3509 (define_expand "floatsitf2"
3510   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3511         (float:TF (match_operand:SI 1 "register_operand" "")))]
3512   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3513   "emit_tfmode_cvt (FLOAT, operands); DONE;")
3515 (define_insn "*floatsitf2_hq"
3516   [(set (match_operand:TF 0 "register_operand" "=e")
3517         (float:TF (match_operand:SI 1 "register_operand" "f")))]
3518   "TARGET_FPU && TARGET_HARD_QUAD"
3519   "fitoq\t%1, %0"
3520   [(set_attr "type" "fp")])
3522 (define_expand "floatunssitf2"
3523   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3524         (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
3525   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3526   "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3528 ;; Now the same for 64 bit sources.
3530 (define_insn "floatdisf2"
3531   [(set (match_operand:SF 0 "register_operand" "=f")
3532         (float:SF (match_operand:DI 1 "register_operand" "e")))]
3533   "TARGET_V9 && TARGET_FPU"
3534   "fxtos\t%1, %0"
3535   [(set_attr "type" "fp")
3536    (set_attr "fptype" "double")])
3538 (define_expand "floatunsdisf2"
3539   [(use (match_operand:SF 0 "register_operand" ""))
3540    (use (match_operand:DI 1 "general_operand" ""))]
3541   "TARGET_ARCH64 && TARGET_FPU"
3542   "sparc_emit_floatunsdi (operands, SFmode); DONE;")
3544 (define_insn "floatdidf2"
3545   [(set (match_operand:DF 0 "register_operand" "=e")
3546         (float:DF (match_operand:DI 1 "register_operand" "e")))]
3547   "TARGET_V9 && TARGET_FPU"
3548   "fxtod\t%1, %0"
3549   [(set_attr "type" "fp")
3550    (set_attr "fptype" "double")])
3552 (define_expand "floatunsdidf2"
3553   [(use (match_operand:DF 0 "register_operand" ""))
3554    (use (match_operand:DI 1 "general_operand" ""))]
3555   "TARGET_ARCH64 && TARGET_FPU"
3556   "sparc_emit_floatunsdi (operands, DFmode); DONE;")
3558 (define_expand "floatditf2"
3559   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3560         (float:TF (match_operand:DI 1 "register_operand" "")))]
3561   "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3562   "emit_tfmode_cvt (FLOAT, operands); DONE;")
3564 (define_insn "*floatditf2_hq"
3565   [(set (match_operand:TF 0 "register_operand" "=e")
3566         (float:TF (match_operand:DI 1 "register_operand" "e")))]
3567   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3568   "fxtoq\t%1, %0"
3569   [(set_attr "type" "fp")])
3571 (define_expand "floatunsditf2"
3572   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3573         (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
3574   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3575   "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3577 ;; Convert a float to an actual integer.
3578 ;; Truncation is performed as part of the conversion.
3580 (define_insn "fix_truncsfsi2"
3581   [(set (match_operand:SI 0 "register_operand" "=f")
3582         (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3583   "TARGET_FPU"
3584   "fstoi\t%1, %0"
3585   [(set_attr "type" "fp")
3586    (set_attr "fptype" "double")])
3588 (define_insn "fix_truncdfsi2"
3589   [(set (match_operand:SI 0 "register_operand" "=f")
3590         (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3591   "TARGET_FPU"
3592   "fdtoi\t%1, %0"
3593   [(set_attr "type" "fp")
3594    (set_attr "fptype" "double")])
3596 (define_expand "fix_trunctfsi2"
3597   [(set (match_operand:SI 0 "register_operand" "")
3598         (fix:SI (match_operand:TF 1 "general_operand" "")))]
3599   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3600   "emit_tfmode_cvt (FIX, operands); DONE;")
3602 (define_insn "*fix_trunctfsi2_hq"
3603   [(set (match_operand:SI 0 "register_operand" "=f")
3604         (fix:SI (match_operand:TF 1 "register_operand" "e")))]
3605   "TARGET_FPU && TARGET_HARD_QUAD"
3606   "fqtoi\t%1, %0"
3607   [(set_attr "type" "fp")])
3609 (define_expand "fixuns_trunctfsi2"
3610   [(set (match_operand:SI 0 "register_operand" "")
3611         (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
3612   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3613   "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3615 ;; Now the same, for V9 targets
3617 (define_insn "fix_truncsfdi2"
3618   [(set (match_operand:DI 0 "register_operand" "=e")
3619         (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3620   "TARGET_V9 && TARGET_FPU"
3621   "fstox\t%1, %0"
3622   [(set_attr "type" "fp")
3623    (set_attr "fptype" "double")])
3625 (define_expand "fixuns_truncsfdi2"
3626   [(use (match_operand:DI 0 "register_operand" ""))
3627    (use (match_operand:SF 1 "general_operand" ""))]
3628   "TARGET_ARCH64 && TARGET_FPU"
3629   "sparc_emit_fixunsdi (operands, SFmode); DONE;")
3631 (define_insn "fix_truncdfdi2"
3632   [(set (match_operand:DI 0 "register_operand" "=e")
3633         (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3634   "TARGET_V9 && TARGET_FPU"
3635   "fdtox\t%1, %0"
3636   [(set_attr "type" "fp")
3637    (set_attr "fptype" "double")])
3639 (define_expand "fixuns_truncdfdi2"
3640   [(use (match_operand:DI 0 "register_operand" ""))
3641    (use (match_operand:DF 1 "general_operand" ""))]
3642   "TARGET_ARCH64 && TARGET_FPU"
3643   "sparc_emit_fixunsdi (operands, DFmode); DONE;")
3645 (define_expand "fix_trunctfdi2"
3646   [(set (match_operand:DI 0 "register_operand" "")
3647         (fix:DI (match_operand:TF 1 "general_operand" "")))]
3648   "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3649   "emit_tfmode_cvt (FIX, operands); DONE;")
3651 (define_insn "*fix_trunctfdi2_hq"
3652   [(set (match_operand:DI 0 "register_operand" "=e")
3653         (fix:DI (match_operand:TF 1 "register_operand" "e")))]
3654   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3655   "fqtox\t%1, %0"
3656   [(set_attr "type" "fp")])
3658 (define_expand "fixuns_trunctfdi2"
3659   [(set (match_operand:DI 0 "register_operand" "")
3660         (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
3661   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3662   "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3665 ;; Integer addition/subtraction instructions.
3667 (define_expand "adddi3"
3668   [(set (match_operand:DI 0 "register_operand" "")
3669         (plus:DI (match_operand:DI 1 "register_operand" "")
3670                  (match_operand:DI 2 "arith_double_add_operand" "")))]
3671   ""
3673   if (! TARGET_ARCH64)
3674     {
3675       emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3676                           gen_rtx_SET (VOIDmode, operands[0],
3677                                    gen_rtx_PLUS (DImode, operands[1],
3678                                                  operands[2])),
3679                           gen_rtx_CLOBBER (VOIDmode,
3680                                    gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3681       DONE;
3682     }
3685 (define_insn_and_split "*adddi3_insn_sp32"
3686   [(set (match_operand:DI 0 "register_operand" "=&r")
3687         (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
3688                  (match_operand:DI 2 "arith_double_operand" "rHI")))
3689    (clobber (reg:CC CC_REG))]
3690   "! TARGET_ARCH64"
3691   "#"
3692   "&& reload_completed"
3693   [(parallel [(set (reg:CC_NOOV CC_REG)
3694                    (compare:CC_NOOV (plus:SI (match_dup 4)
3695                                              (match_dup 5))
3696                                     (const_int 0)))
3697               (set (match_dup 3)
3698                    (plus:SI (match_dup 4) (match_dup 5)))])
3699    (set (match_dup 6)
3700         (plus:SI (plus:SI (match_dup 7)
3701                           (match_dup 8))
3702                  (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3704   operands[3] = gen_lowpart (SImode, operands[0]);
3705   operands[4] = gen_lowpart (SImode, operands[1]);
3706   operands[5] = gen_lowpart (SImode, operands[2]);
3707   operands[6] = gen_highpart (SImode, operands[0]);
3708   operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
3709 #if HOST_BITS_PER_WIDE_INT == 32
3710   if (GET_CODE (operands[2]) == CONST_INT)
3711     {
3712       if (INTVAL (operands[2]) < 0)
3713         operands[8] = constm1_rtx;
3714       else
3715         operands[8] = const0_rtx;
3716     }
3717   else
3718 #endif
3719     operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3721   [(set_attr "length" "2")])
3723 ;; LTU here means "carry set"
3724 (define_insn "addx"
3725   [(set (match_operand:SI 0 "register_operand" "=r")
3726         (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3727                           (match_operand:SI 2 "arith_operand" "rI"))
3728                  (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3729   ""
3730   "addx\t%1, %2, %0"
3731   [(set_attr "type" "ialuX")])
3733 (define_insn "addxc"
3734   [(set (match_operand:DI 0 "register_operand" "=r")
3735         (plus:DI (plus:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
3736                           (match_operand:DI 2 "register_or_zero_operand" "rJ"))
3737                  (ltu:DI (reg:CCX_NOOV CC_REG) (const_int 0))))]
3738   "TARGET_ARCH64 && TARGET_VIS3"
3739   "addxc\t%r1, %r2, %0"
3740   [(set_attr "type" "ialuX")])
3742 (define_insn_and_split "*addx_extend_sp32"
3743   [(set (match_operand:DI 0 "register_operand" "=r")
3744         (zero_extend:DI (plus:SI (plus:SI
3745                                   (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3746                                   (match_operand:SI 2 "arith_operand" "rI"))
3747                                  (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3748   "! TARGET_ARCH64"
3749   "#"
3750   "&& reload_completed"
3751   [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
3752                                (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))
3753    (set (match_dup 4) (const_int 0))]
3754   "operands[3] = gen_lowpart (SImode, operands[0]);
3755    operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
3756   [(set_attr "length" "2")])
3758 (define_insn "*addx_extend_sp64"
3759   [(set (match_operand:DI 0 "register_operand" "=r")
3760         (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3761                                           (match_operand:SI 2 "register_or_zero_operand" "rJ"))
3762                                  (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3763   "TARGET_ARCH64"
3764   "addx\t%r1, %r2, %0"
3765   [(set_attr "type" "ialuX")])
3767 (define_insn "*addxc_trunc_sp64_vis3"
3768   [(set (match_operand:SI 0 "register_operand" "=r")
3769         (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3770                           (match_operand:SI 2 "register_or_zero_operand" "rJ"))
3771                  (ltu:SI (reg:CCX_NOOV CC_REG) (const_int 0))))]
3772   "TARGET_ARCH64 && TARGET_VIS3"
3773   "addxc\t%r1, %r2, %0"
3774   [(set_attr "type" "ialuX")])
3776 (define_insn_and_split "*adddi3_extend_sp32"
3777   [(set (match_operand:DI 0 "register_operand" "=r")
3778         (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
3779                  (match_operand:DI 2 "register_operand" "r")))
3780    (clobber (reg:CC CC_REG))]
3781   "! TARGET_ARCH64"
3782   "#"
3783   "&& reload_completed"
3784   [(parallel [(set (reg:CC_NOOV CC_REG)
3785                    (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
3786                                     (const_int 0)))
3787               (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
3788    (set (match_dup 6)
3789         (plus:SI (plus:SI (match_dup 4) (const_int 0))
3790                  (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3791   "operands[3] = gen_lowpart (SImode, operands[2]);
3792    operands[4] = gen_highpart (SImode, operands[2]);
3793    operands[5] = gen_lowpart (SImode, operands[0]);
3794    operands[6] = gen_highpart (SImode, operands[0]);"
3795   [(set_attr "length" "2")])
3797 (define_insn "*adddi3_sp64"
3798   [(set (match_operand:DI 0 "register_operand" "=r,r")
3799         (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
3800                  (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3801   "TARGET_ARCH64"
3802   "@
3803    add\t%1, %2, %0
3804    sub\t%1, -%2, %0")
3806 (define_insn "addsi3"
3807   [(set (match_operand:SI 0 "register_operand" "=r,r")
3808         (plus:SI (match_operand:SI 1 "register_operand" "%r,r")
3809                  (match_operand:SI 2 "arith_add_operand" "rI,O")))]
3810   ""
3811   "@
3812    add\t%1, %2, %0
3813    sub\t%1, -%2, %0"
3814   [(set_attr "type" "*,*")
3815    (set_attr "fptype" "*,*")])
3817 (define_insn "*cmp_cc_plus"
3818   [(set (reg:CC_NOOV CC_REG)
3819         (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
3820                                   (match_operand:SI 1 "arith_operand" "rI"))
3821                          (const_int 0)))]
3822   ""
3823   "addcc\t%0, %1, %%g0"
3824   [(set_attr "type" "compare")])
3826 (define_insn "*cmp_ccx_plus"
3827   [(set (reg:CCX_NOOV CC_REG)
3828         (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_operand" "%r")
3829                                    (match_operand:DI 1 "arith_operand" "rI"))
3830                           (const_int 0)))]
3831   "TARGET_ARCH64"
3832   "addcc\t%0, %1, %%g0"
3833   [(set_attr "type" "compare")])
3835 (define_insn "*cmp_cc_plus_set"
3836   [(set (reg:CC_NOOV CC_REG)
3837         (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3838                                   (match_operand:SI 2 "arith_operand" "rI"))
3839                          (const_int 0)))
3840    (set (match_operand:SI 0 "register_operand" "=r")
3841         (plus:SI (match_dup 1) (match_dup 2)))]
3842   ""
3843   "addcc\t%1, %2, %0"
3844   [(set_attr "type" "compare")])
3846 (define_insn "*cmp_ccx_plus_set"
3847   [(set (reg:CCX_NOOV CC_REG)
3848         (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_operand" "%r")
3849                                    (match_operand:DI 2 "arith_operand" "rI"))
3850                           (const_int 0)))
3851    (set (match_operand:DI 0 "register_operand" "=r")
3852         (plus:DI (match_dup 1) (match_dup 2)))]
3853   "TARGET_ARCH64"
3854   "addcc\t%1, %2, %0"
3855   [(set_attr "type" "compare")])
3857 (define_expand "subdi3"
3858   [(set (match_operand:DI 0 "register_operand" "")
3859         (minus:DI (match_operand:DI 1 "register_operand" "")
3860                   (match_operand:DI 2 "arith_double_add_operand" "")))]
3861   ""
3863   if (! TARGET_ARCH64)
3864     {
3865       emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3866                           gen_rtx_SET (VOIDmode, operands[0],
3867                                    gen_rtx_MINUS (DImode, operands[1],
3868                                                   operands[2])),
3869                           gen_rtx_CLOBBER (VOIDmode,
3870                                    gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3871       DONE;
3872     }
3875 (define_insn_and_split "*subdi3_insn_sp32"
3876   [(set (match_operand:DI 0 "register_operand" "=r")
3877         (minus:DI (match_operand:DI 1 "register_operand" "r")
3878                   (match_operand:DI 2 "arith_double_operand" "rHI")))
3879    (clobber (reg:CC CC_REG))]
3880   "! TARGET_ARCH64"
3881   "#"
3882   "&& reload_completed"
3883   [(parallel [(set (reg:CC_NOOV CC_REG)
3884                    (compare:CC_NOOV (minus:SI (match_dup 4)
3885                                               (match_dup 5))
3886                                     (const_int 0)))
3887               (set (match_dup 3)
3888                    (minus:SI (match_dup 4) (match_dup 5)))])
3889    (set (match_dup 6)
3890         (minus:SI (minus:SI (match_dup 7)
3891                             (match_dup 8))
3892                   (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3894   operands[3] = gen_lowpart (SImode, operands[0]);
3895   operands[4] = gen_lowpart (SImode, operands[1]);
3896   operands[5] = gen_lowpart (SImode, operands[2]);
3897   operands[6] = gen_highpart (SImode, operands[0]);
3898   operands[7] = gen_highpart (SImode, operands[1]);
3899 #if HOST_BITS_PER_WIDE_INT == 32
3900   if (GET_CODE (operands[2]) == CONST_INT)
3901     {
3902       if (INTVAL (operands[2]) < 0)
3903         operands[8] = constm1_rtx;
3904       else
3905         operands[8] = const0_rtx;
3906     }
3907   else
3908 #endif
3909     operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3911   [(set_attr "length" "2")])
3913 ;; LTU here means "carry set"
3914 (define_insn "subx"
3915   [(set (match_operand:SI 0 "register_operand" "=r")
3916         (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3917                             (match_operand:SI 2 "arith_operand" "rI"))
3918                   (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3919   ""
3920   "subx\t%r1, %2, %0"
3921   [(set_attr "type" "ialuX")])
3923 (define_insn "*subx_extend_sp64"
3924   [(set (match_operand:DI 0 "register_operand" "=r")
3925         (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3926                                             (match_operand:SI 2 "arith_operand" "rI"))
3927                                   (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3928   "TARGET_ARCH64"
3929   "subx\t%r1, %2, %0"
3930   [(set_attr "type" "ialuX")])
3932 (define_insn_and_split "*subx_extend"
3933   [(set (match_operand:DI 0 "register_operand" "=r")
3934         (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3935                                             (match_operand:SI 2 "arith_operand" "rI"))
3936                                   (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3937   "! TARGET_ARCH64"
3938   "#"
3939   "&& reload_completed"
3940   [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
3941                                 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))
3942    (set (match_dup 4) (const_int 0))]
3943   "operands[3] = gen_lowpart (SImode, operands[0]);
3944    operands[4] = gen_highpart (SImode, operands[0]);"
3945   [(set_attr "length" "2")])
3947 (define_insn_and_split "*subdi3_extend_sp32"
3948   [(set (match_operand:DI 0 "register_operand" "=r")
3949       (minus:DI (match_operand:DI 1 "register_operand" "r")
3950                 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
3951    (clobber (reg:CC CC_REG))]
3952   "! TARGET_ARCH64"
3953   "#"
3954   "&& reload_completed"
3955   [(parallel [(set (reg:CC_NOOV CC_REG)
3956                    (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
3957                                     (const_int 0)))
3958               (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
3959    (set (match_dup 6)
3960         (minus:SI (minus:SI (match_dup 4) (const_int 0))
3961                   (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3962   "operands[3] = gen_lowpart (SImode, operands[1]);
3963    operands[4] = gen_highpart (SImode, operands[1]);
3964    operands[5] = gen_lowpart (SImode, operands[0]);
3965    operands[6] = gen_highpart (SImode, operands[0]);"
3966   [(set_attr "length" "2")])
3968 (define_insn "*subdi3_sp64"
3969   [(set (match_operand:DI 0 "register_operand" "=r,r")
3970         (minus:DI (match_operand:DI 1 "register_operand" "r,r")
3971                   (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3972   "TARGET_ARCH64"
3973   "@
3974    sub\t%1, %2, %0
3975    add\t%1, -%2, %0")
3977 (define_insn "subsi3"
3978   [(set (match_operand:SI 0 "register_operand" "=r,r")
3979         (minus:SI (match_operand:SI 1 "register_operand" "r,r")
3980                   (match_operand:SI 2 "arith_add_operand" "rI,O")))]
3981   ""
3982   "@
3983    sub\t%1, %2, %0
3984    add\t%1, -%2, %0"
3985   [(set_attr "type" "*,*")
3986    (set_attr "fptype" "*,*")])
3988 (define_insn "*cmp_minus_cc"
3989   [(set (reg:CC_NOOV CC_REG)
3990         (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
3991                                    (match_operand:SI 1 "arith_operand" "rI"))
3992                          (const_int 0)))]
3993   ""
3994   "subcc\t%r0, %1, %%g0"
3995   [(set_attr "type" "compare")])
3997 (define_insn "*cmp_minus_ccx"
3998   [(set (reg:CCX_NOOV CC_REG)
3999         (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
4000                                     (match_operand:DI 1 "arith_operand" "rI"))
4001                           (const_int 0)))]
4002   "TARGET_ARCH64"
4003   "subcc\t%0, %1, %%g0"
4004   [(set_attr "type" "compare")])
4006 (define_insn "cmp_minus_cc_set"
4007   [(set (reg:CC_NOOV CC_REG)
4008         (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4009                                    (match_operand:SI 2 "arith_operand" "rI"))
4010                          (const_int 0)))
4011    (set (match_operand:SI 0 "register_operand" "=r")
4012         (minus:SI (match_dup 1) (match_dup 2)))]
4013   ""
4014   "subcc\t%r1, %2, %0"
4015   [(set_attr "type" "compare")])
4017 (define_insn "*cmp_minus_ccx_set"
4018   [(set (reg:CCX_NOOV CC_REG)
4019         (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
4020                                     (match_operand:DI 2 "arith_operand" "rI"))
4021                           (const_int 0)))
4022    (set (match_operand:DI 0 "register_operand" "=r")
4023         (minus:DI (match_dup 1) (match_dup 2)))]
4024   "TARGET_ARCH64"
4025   "subcc\t%1, %2, %0"
4026   [(set_attr "type" "compare")])
4029 ;; Integer multiply/divide instructions.
4031 ;; The 32-bit multiply/divide instructions are deprecated on v9, but at
4032 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
4034 (define_insn "mulsi3"
4035   [(set (match_operand:SI 0 "register_operand" "=r")
4036         (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4037                  (match_operand:SI 2 "arith_operand" "rI")))]
4038   "TARGET_HARD_MUL"
4039   "smul\t%1, %2, %0"
4040   [(set_attr "type" "imul")])
4042 (define_expand "muldi3"
4043   [(set (match_operand:DI 0 "register_operand" "")
4044         (mult:DI (match_operand:DI 1 "arith_operand" "")
4045                  (match_operand:DI 2 "arith_operand" "")))]
4046   "TARGET_ARCH64 || TARGET_V8PLUS"
4048   if (TARGET_V8PLUS)
4049     {
4050       emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
4051       DONE;
4052     }
4055 (define_insn "*muldi3_sp64"
4056   [(set (match_operand:DI 0 "register_operand" "=r")
4057         (mult:DI (match_operand:DI 1 "arith_operand" "%r")
4058                  (match_operand:DI 2 "arith_operand" "rI")))]
4059   "TARGET_ARCH64"
4060   "mulx\t%1, %2, %0"
4061   [(set_attr "type" "imul")])
4063 ;; V8plus wide multiply.
4064 ;; XXX
4065 (define_insn "muldi3_v8plus"
4066   [(set (match_operand:DI 0 "register_operand" "=r,h")
4067         (mult:DI (match_operand:DI 1 "arith_operand" "%r,0")
4068                  (match_operand:DI 2 "arith_operand" "rI,rI")))
4069    (clobber (match_scratch:SI 3 "=&h,X"))
4070    (clobber (match_scratch:SI 4 "=&h,X"))]
4071   "TARGET_V8PLUS"
4072   "* return output_v8plus_mult (insn, operands, \"mulx\");"
4073   [(set_attr "type" "multi")
4074    (set_attr "length" "9,8")])
4076 (define_insn "*cmp_mul_set"
4077   [(set (reg:CC CC_REG)
4078         (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4079                     (match_operand:SI 2 "arith_operand" "rI"))
4080                     (const_int 0)))
4081    (set (match_operand:SI 0 "register_operand" "=r")
4082         (mult:SI (match_dup 1) (match_dup 2)))]
4083   "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
4084   "smulcc\t%1, %2, %0"
4085   [(set_attr "type" "imul")])
4087 (define_expand "mulsidi3"
4088   [(set (match_operand:DI 0 "register_operand" "")
4089         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4090                  (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
4091   "TARGET_HARD_MUL"
4093   if (CONSTANT_P (operands[2]))
4094     {
4095       if (TARGET_V8PLUS)
4096         emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
4097                                               operands[2]));
4098       else if (TARGET_ARCH32)
4099         emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
4100                                             operands[2]));
4101       else 
4102         emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
4103                                             operands[2]));
4104       DONE;
4105     }
4106   if (TARGET_V8PLUS)
4107     {
4108       emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
4109       DONE;
4110     }
4113 ;; V9 puts the 64-bit product in a 64-bit register.  Only out or global
4114 ;; registers can hold 64-bit values in the V8plus environment.
4115 ;; XXX
4116 (define_insn "mulsidi3_v8plus"
4117   [(set (match_operand:DI 0 "register_operand" "=h,r")
4118         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4119                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4120    (clobber (match_scratch:SI 3 "=X,&h"))]
4121   "TARGET_V8PLUS"
4122   "@
4123    smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4124    smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4125   [(set_attr "type" "multi")
4126    (set_attr "length" "2,3")])
4128 ;; XXX
4129 (define_insn "const_mulsidi3_v8plus"
4130   [(set (match_operand:DI 0 "register_operand" "=h,r")
4131         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4132                  (match_operand:DI 2 "small_int_operand" "I,I")))
4133    (clobber (match_scratch:SI 3 "=X,&h"))]
4134   "TARGET_V8PLUS"
4135   "@
4136    smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4137    smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4138   [(set_attr "type" "multi")
4139    (set_attr "length" "2,3")])
4141 ;; XXX
4142 (define_insn "*mulsidi3_sp32"
4143   [(set (match_operand:DI 0 "register_operand" "=r")
4144         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4145                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4146   "TARGET_HARD_MUL32"
4148   return TARGET_SPARCLET
4149          ? "smuld\t%1, %2, %L0"
4150          : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4152   [(set (attr "type")
4153         (if_then_else (eq_attr "isa" "sparclet")
4154                       (const_string "imul") (const_string "multi")))
4155    (set (attr "length")
4156         (if_then_else (eq_attr "isa" "sparclet")
4157                       (const_int 1) (const_int 2)))])
4159 (define_insn "*mulsidi3_sp64"
4160   [(set (match_operand:DI 0 "register_operand" "=r")
4161         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4162                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4163   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4164   "smul\t%1, %2, %0"
4165   [(set_attr "type" "imul")])
4167 ;; Extra pattern, because sign_extend of a constant isn't valid.
4169 ;; XXX
4170 (define_insn "const_mulsidi3_sp32"
4171   [(set (match_operand:DI 0 "register_operand" "=r")
4172         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4173                  (match_operand:DI 2 "small_int_operand" "I")))]
4174   "TARGET_HARD_MUL32"
4176   return TARGET_SPARCLET
4177          ? "smuld\t%1, %2, %L0"
4178          : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4180   [(set (attr "type")
4181         (if_then_else (eq_attr "isa" "sparclet")
4182                       (const_string "imul") (const_string "multi")))
4183    (set (attr "length")
4184         (if_then_else (eq_attr "isa" "sparclet")
4185                       (const_int 1) (const_int 2)))])
4187 (define_insn "const_mulsidi3_sp64"
4188   [(set (match_operand:DI 0 "register_operand" "=r")
4189         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4190                  (match_operand:DI 2 "small_int_operand" "I")))]
4191   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4192   "smul\t%1, %2, %0"
4193   [(set_attr "type" "imul")])
4195 (define_expand "smulsi3_highpart"
4196   [(set (match_operand:SI 0 "register_operand" "")
4197         (truncate:SI
4198          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4199                                (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
4200                       (const_int 32))))]
4201   "TARGET_HARD_MUL && TARGET_ARCH32"
4203   if (CONSTANT_P (operands[2]))
4204     {
4205       if (TARGET_V8PLUS)
4206         {
4207           emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
4208                                                         operands[1],
4209                                                         operands[2],
4210                                                         GEN_INT (32)));
4211           DONE;
4212         }
4213       emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
4214       DONE;
4215     }
4216   if (TARGET_V8PLUS)
4217     {
4218       emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
4219                                               operands[2], GEN_INT (32)));
4220       DONE;
4221     }
4224 ;; XXX
4225 (define_insn "smulsi3_highpart_v8plus"
4226   [(set (match_operand:SI 0 "register_operand" "=h,r")
4227         (truncate:SI
4228          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4229                                (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4230                       (match_operand:SI 3 "small_int_operand" "I,I"))))
4231    (clobber (match_scratch:SI 4 "=X,&h"))]
4232   "TARGET_V8PLUS"
4233   "@
4234    smul\t%1, %2, %0\;srlx\t%0, %3, %0
4235    smul\t%1, %2, %4\;srlx\t%4, %3, %0"
4236   [(set_attr "type" "multi")
4237    (set_attr "length" "2")])
4239 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
4240 ;; XXX
4241 (define_insn ""
4242   [(set (match_operand:SI 0 "register_operand" "=h,r")
4243         (subreg:SI
4244          (lshiftrt:DI
4245           (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4246                    (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4247           (match_operand:SI 3 "small_int_operand" "I,I"))
4248          4))
4249    (clobber (match_scratch:SI 4 "=X,&h"))]
4250   "TARGET_V8PLUS"
4251   "@
4252    smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4253    smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4254   [(set_attr "type" "multi")
4255    (set_attr "length" "2")])
4257 ;; XXX
4258 (define_insn "const_smulsi3_highpart_v8plus"
4259   [(set (match_operand:SI 0 "register_operand" "=h,r")
4260         (truncate:SI
4261          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4262                                (match_operand:DI 2 "small_int_operand" "I,I"))
4263                       (match_operand:SI 3 "small_int_operand" "I,I"))))
4264    (clobber (match_scratch:SI 4 "=X,&h"))]
4265   "TARGET_V8PLUS"
4266   "@
4267    smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4268    smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4269   [(set_attr "type" "multi")
4270    (set_attr "length" "2")])
4272 ;; XXX
4273 (define_insn "*smulsi3_highpart_sp32"
4274   [(set (match_operand:SI 0 "register_operand" "=r")
4275         (truncate:SI
4276          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4277                                (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
4278                       (const_int 32))))]
4279   "TARGET_HARD_MUL32"
4280   "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4281   [(set_attr "type" "multi")
4282    (set_attr "length" "2")])
4284 ;; XXX
4285 (define_insn "const_smulsi3_highpart"
4286   [(set (match_operand:SI 0 "register_operand" "=r")
4287         (truncate:SI
4288          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4289                                (match_operand:DI 2 "small_int_operand" "i"))
4290                       (const_int 32))))]
4291   "TARGET_HARD_MUL32"
4292   "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4293   [(set_attr "type" "multi")
4294    (set_attr "length" "2")])
4296 (define_expand "umulsidi3"
4297   [(set (match_operand:DI 0 "register_operand" "")
4298         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4299                  (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
4300   "TARGET_HARD_MUL"
4302   if (CONSTANT_P (operands[2]))
4303     {
4304       if (TARGET_V8PLUS)
4305         emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
4306                                                operands[2]));
4307       else if (TARGET_ARCH32)
4308         emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
4309                                              operands[2]));
4310       else 
4311         emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
4312                                              operands[2]));
4313       DONE;
4314     }
4315   if (TARGET_V8PLUS)
4316     {
4317       emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
4318       DONE;
4319     }
4322 ;; XXX
4323 (define_insn "umulsidi3_v8plus"
4324   [(set (match_operand:DI 0 "register_operand" "=h,r")
4325         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4326                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4327    (clobber (match_scratch:SI 3 "=X,&h"))]
4328   "TARGET_V8PLUS"
4329   "@
4330    umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4331    umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4332   [(set_attr "type" "multi")
4333    (set_attr "length" "2,3")])
4335 ;; XXX
4336 (define_insn "*umulsidi3_sp32"
4337   [(set (match_operand:DI 0 "register_operand" "=r")
4338         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4339                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4340   "TARGET_HARD_MUL32"
4342   return TARGET_SPARCLET
4343          ? "umuld\t%1, %2, %L0"
4344          : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
4346   [(set (attr "type")
4347         (if_then_else (eq_attr "isa" "sparclet")
4348                       (const_string "imul") (const_string "multi")))
4349    (set (attr "length")
4350         (if_then_else (eq_attr "isa" "sparclet")
4351                       (const_int 1) (const_int 2)))])
4353 (define_insn "*umulsidi3_sp64"
4354   [(set (match_operand:DI 0 "register_operand" "=r")
4355         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4356                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4357   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4358   "umul\t%1, %2, %0"
4359   [(set_attr "type" "imul")])
4361 ;; Extra pattern, because sign_extend of a constant isn't valid.
4363 ;; XXX
4364 (define_insn "const_umulsidi3_sp32"
4365   [(set (match_operand:DI 0 "register_operand" "=r")
4366         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4367                  (match_operand:DI 2 "uns_small_int_operand" "")))]
4368   "TARGET_HARD_MUL32"
4370   return TARGET_SPARCLET
4371          ? "umuld\t%1, %s2, %L0"
4372          : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
4374   [(set (attr "type")
4375         (if_then_else (eq_attr "isa" "sparclet")
4376                       (const_string "imul") (const_string "multi")))
4377    (set (attr "length")
4378         (if_then_else (eq_attr "isa" "sparclet")
4379                       (const_int 1) (const_int 2)))])
4381 (define_insn "const_umulsidi3_sp64"
4382   [(set (match_operand:DI 0 "register_operand" "=r")
4383         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4384                  (match_operand:DI 2 "uns_small_int_operand" "")))]
4385   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4386   "umul\t%1, %s2, %0"
4387   [(set_attr "type" "imul")])
4389 ;; XXX
4390 (define_insn "const_umulsidi3_v8plus"
4391   [(set (match_operand:DI 0 "register_operand" "=h,r")
4392         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4393                  (match_operand:DI 2 "uns_small_int_operand" "")))
4394    (clobber (match_scratch:SI 3 "=X,h"))]
4395   "TARGET_V8PLUS"
4396   "@
4397    umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
4398    umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4399   [(set_attr "type" "multi")
4400    (set_attr "length" "2,3")])
4402 (define_expand "umulsi3_highpart"
4403   [(set (match_operand:SI 0 "register_operand" "")
4404         (truncate:SI
4405          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4406                                (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
4407                       (const_int 32))))]
4408   "TARGET_HARD_MUL && TARGET_ARCH32"
4410   if (CONSTANT_P (operands[2]))
4411     {
4412       if (TARGET_V8PLUS)
4413         {
4414           emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
4415                                                         operands[1],
4416                                                         operands[2],
4417                                                         GEN_INT (32)));
4418           DONE;
4419         }
4420       emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
4421       DONE;
4422     }
4423   if (TARGET_V8PLUS)
4424     {
4425       emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
4426                                               operands[2], GEN_INT (32)));
4427       DONE;
4428     }
4431 ;; XXX
4432 (define_insn "umulsi3_highpart_v8plus"
4433   [(set (match_operand:SI 0 "register_operand" "=h,r")
4434         (truncate:SI
4435          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4436                                (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4437                       (match_operand:SI 3 "small_int_operand" "I,I"))))
4438    (clobber (match_scratch:SI 4 "=X,h"))]
4439   "TARGET_V8PLUS"
4440   "@
4441    umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4442    umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4443   [(set_attr "type" "multi")
4444    (set_attr "length" "2")])
4446 ;; XXX
4447 (define_insn "const_umulsi3_highpart_v8plus"
4448   [(set (match_operand:SI 0 "register_operand" "=h,r")
4449         (truncate:SI
4450          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4451                                (match_operand:DI 2 "uns_small_int_operand" ""))
4452                       (match_operand:SI 3 "small_int_operand" "I,I"))))
4453    (clobber (match_scratch:SI 4 "=X,h"))]
4454   "TARGET_V8PLUS"
4455   "@
4456    umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
4457    umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
4458   [(set_attr "type" "multi")
4459    (set_attr "length" "2")])
4461 ;; XXX
4462 (define_insn "*umulsi3_highpart_sp32"
4463   [(set (match_operand:SI 0 "register_operand" "=r")
4464         (truncate:SI
4465          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4466                                (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
4467                       (const_int 32))))]
4468   "TARGET_HARD_MUL32"
4469   "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
4470   [(set_attr "type" "multi")
4471    (set_attr "length" "2")])
4473 ;; XXX
4474 (define_insn "const_umulsi3_highpart"
4475   [(set (match_operand:SI 0 "register_operand" "=r")
4476         (truncate:SI
4477          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4478                                (match_operand:DI 2 "uns_small_int_operand" ""))
4479                       (const_int 32))))]
4480   "TARGET_HARD_MUL32"
4481   "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
4482   [(set_attr "type" "multi")
4483    (set_attr "length" "2")])
4485 (define_expand "divsi3"
4486   [(parallel [(set (match_operand:SI 0 "register_operand" "")
4487                    (div:SI (match_operand:SI 1 "register_operand" "")
4488                            (match_operand:SI 2 "input_operand" "")))
4489               (clobber (match_scratch:SI 3 ""))])]
4490   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4492   if (TARGET_ARCH64)
4493     {
4494       operands[3] = gen_reg_rtx(SImode);
4495       emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
4496       emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
4497                                   operands[3]));
4498       DONE;
4499     }
4502 ;; The V8 architecture specifies that there must be at least 3 instructions
4503 ;; between a write to the Y register and a use of it for correct results.
4504 ;; We try to fill one of them with a simple constant or a memory load.
4506 (define_insn "divsi3_sp32"
4507   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
4508         (div:SI (match_operand:SI 1 "register_operand" "r,r,r")
4509                 (match_operand:SI 2 "input_operand" "rI,K,m")))
4510    (clobber (match_scratch:SI 3 "=&r,&r,&r"))]
4511   "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4513   output_asm_insn ("sra\t%1, 31, %3", operands);
4514   output_asm_insn ("wr\t%3, 0, %%y", operands);
4516   switch (which_alternative)
4517     {
4518     case 0:
4519       if (TARGET_V9)
4520         return "sdiv\t%1, %2, %0";
4521       else
4522         return "nop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
4523     case 1:
4524       if (TARGET_V9)
4525         return "sethi\t%%hi(%a2), %3\n\tsdiv\t%1, %3, %0";
4526       else
4527         return "sethi\t%%hi(%a2), %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4528     case 2:
4529       if (TARGET_V9)
4530         return "ld\t%2, %3\n\tsdiv\t%1, %3, %0";
4531       else
4532         return "ld\t%2, %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4533     default:
4534       gcc_unreachable ();
4535     }
4537   [(set_attr "type" "multi")
4538    (set (attr "length")
4539         (if_then_else (eq_attr "isa" "v9")
4540                       (const_int 4) (const_int 6)))])
4542 (define_insn "divsi3_sp64"
4543   [(set (match_operand:SI 0 "register_operand" "=r")
4544         (div:SI (match_operand:SI 1 "register_operand" "r")
4545                 (match_operand:SI 2 "input_operand" "rI")))
4546    (use (match_operand:SI 3 "register_operand" "r"))]
4547   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4548   "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
4549   [(set_attr "type" "multi")
4550    (set_attr "length" "2")])
4552 (define_insn "divdi3"
4553   [(set (match_operand:DI 0 "register_operand" "=r")
4554         (div:DI (match_operand:DI 1 "register_operand" "r")
4555                 (match_operand:DI 2 "arith_operand" "rI")))]
4556   "TARGET_ARCH64"
4557   "sdivx\t%1, %2, %0"
4558   [(set_attr "type" "idiv")])
4560 (define_insn "*cmp_sdiv_cc_set"
4561   [(set (reg:CC CC_REG)
4562         (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
4563                             (match_operand:SI 2 "arith_operand" "rI"))
4564                     (const_int 0)))
4565    (set (match_operand:SI 0 "register_operand" "=r")
4566         (div:SI (match_dup 1) (match_dup 2)))
4567    (clobber (match_scratch:SI 3 "=&r"))]
4568   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4570   output_asm_insn ("sra\t%1, 31, %3", operands);
4571   output_asm_insn ("wr\t%3, 0, %%y", operands);
4573   if (TARGET_V9)
4574     return "sdivcc\t%1, %2, %0";
4575   else
4576     return "nop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
4578   [(set_attr "type" "multi")
4579    (set (attr "length")
4580         (if_then_else (eq_attr "isa" "v9")
4581                       (const_int 3) (const_int 6)))])
4583 ;; XXX
4584 (define_expand "udivsi3"
4585   [(set (match_operand:SI 0 "register_operand" "")
4586         (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "")
4587                  (match_operand:SI 2 "input_operand" "")))]
4588   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4589   "")
4591 ;; The V8 architecture specifies that there must be at least 3 instructions
4592 ;; between a write to the Y register and a use of it for correct results.
4593 ;; We try to fill one of them with a simple constant or a memory load.
4595 (define_insn "udivsi3_sp32"
4596   [(set (match_operand:SI 0 "register_operand" "=r,&r,&r,&r")
4597         (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r,r,r,m")
4598                  (match_operand:SI 2 "input_operand" "rI,K,m,r")))]
4599   "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4601   output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4603   switch (which_alternative)
4604     {
4605     case 0:
4606       if (TARGET_V9)
4607         return "udiv\t%1, %2, %0";
4608       else
4609         return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
4610     case 1:
4611       if (TARGET_V9)
4612         return "sethi\t%%hi(%a2), %0\n\tudiv\t%1, %0, %0";
4613       else
4614         return "sethi\t%%hi(%a2), %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4615     case 2:
4616       if (TARGET_V9)
4617         return "ld\t%2, %0\n\tudiv\t%1, %0, %0";
4618       else
4619         return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4620     case 3:
4621       if (TARGET_V9)
4622         return "ld\t%1, %0\n\tudiv\t%0, %2, %0";
4623       else
4624         return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
4625     default:
4626       gcc_unreachable ();
4627     }
4629   [(set_attr "type" "multi")
4630    (set (attr "length")
4631         (if_then_else (eq_attr "isa" "v9")
4632                       (const_int 3) (const_int 5)))])
4634 (define_insn "udivsi3_sp64"
4635   [(set (match_operand:SI 0 "register_operand" "=r")
4636         (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r")
4637                  (match_operand:SI 2 "input_operand" "rI")))]
4638   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4639   "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
4640   [(set_attr "type" "multi")
4641    (set_attr "length" "2")])
4643 (define_insn "udivdi3"
4644   [(set (match_operand:DI 0 "register_operand" "=r")
4645         (udiv:DI (match_operand:DI 1 "register_operand" "r")
4646                  (match_operand:DI 2 "arith_operand" "rI")))]
4647   "TARGET_ARCH64"
4648   "udivx\t%1, %2, %0"
4649   [(set_attr "type" "idiv")])
4651 (define_insn "*cmp_udiv_cc_set"
4652   [(set (reg:CC CC_REG)
4653         (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
4654                              (match_operand:SI 2 "arith_operand" "rI"))
4655                     (const_int 0)))
4656    (set (match_operand:SI 0 "register_operand" "=r")
4657         (udiv:SI (match_dup 1) (match_dup 2)))]
4658   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4660   output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4662   if (TARGET_V9)
4663     return "udivcc\t%1, %2, %0";
4664   else
4665     return "nop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
4667   [(set_attr "type" "multi")
4668    (set (attr "length")
4669         (if_then_else (eq_attr "isa" "v9")
4670                       (const_int 2) (const_int 5)))])
4672 ; sparclet multiply/accumulate insns
4674 (define_insn "*smacsi"
4675   [(set (match_operand:SI 0 "register_operand" "=r")
4676         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
4677                           (match_operand:SI 2 "arith_operand" "rI"))
4678                  (match_operand:SI 3 "register_operand" "0")))]
4679   "TARGET_SPARCLET"
4680   "smac\t%1, %2, %0"
4681   [(set_attr "type" "imul")])
4683 (define_insn "*smacdi"
4684   [(set (match_operand:DI 0 "register_operand" "=r")
4685         (plus:DI (mult:DI (sign_extend:DI
4686                            (match_operand:SI 1 "register_operand" "%r"))
4687                           (sign_extend:DI
4688                            (match_operand:SI 2 "register_operand" "r")))
4689                  (match_operand:DI 3 "register_operand" "0")))]
4690   "TARGET_SPARCLET"
4691   "smacd\t%1, %2, %L0"
4692   [(set_attr "type" "imul")])
4694 (define_insn "*umacdi"
4695   [(set (match_operand:DI 0 "register_operand" "=r")
4696         (plus:DI (mult:DI (zero_extend:DI
4697                            (match_operand:SI 1 "register_operand" "%r"))
4698                           (zero_extend:DI
4699                            (match_operand:SI 2 "register_operand" "r")))
4700                  (match_operand:DI 3 "register_operand" "0")))]
4701   "TARGET_SPARCLET"
4702   "umacd\t%1, %2, %L0"
4703   [(set_attr "type" "imul")])
4706 ;; Boolean instructions.
4708 ;; We define DImode `and' so with DImode `not' we can get
4709 ;; DImode `andn'.  Other combinations are possible.
4711 (define_expand "anddi3"
4712   [(set (match_operand:DI 0 "register_operand" "")
4713         (and:DI (match_operand:DI 1 "arith_double_operand" "")
4714                 (match_operand:DI 2 "arith_double_operand" "")))]
4715   ""
4716   "")
4718 (define_insn "*anddi3_sp32"
4719   [(set (match_operand:DI 0 "register_operand" "=r")
4720         (and:DI (match_operand:DI 1 "arith_double_operand" "%r")
4721                 (match_operand:DI 2 "arith_double_operand" "rHI")))]
4722   "! TARGET_ARCH64"
4723   "#")
4725 (define_insn "*anddi3_sp64"
4726   [(set (match_operand:DI 0 "register_operand" "=r")
4727         (and:DI (match_operand:DI 1 "arith_operand" "%r")
4728                 (match_operand:DI 2 "arith_operand" "rI")))]
4729   "TARGET_ARCH64"
4730   "and\t%1, %2, %0")
4732 (define_insn "andsi3"
4733   [(set (match_operand:SI 0 "register_operand" "=r")
4734         (and:SI (match_operand:SI 1 "arith_operand" "%r")
4735                 (match_operand:SI 2 "arith_operand" "rI")))]
4736   ""
4737   "and\t%1, %2, %0")
4739 (define_split
4740   [(set (match_operand:SI 0 "register_operand" "")
4741         (and:SI (match_operand:SI 1 "register_operand" "")
4742                 (match_operand:SI 2 "const_compl_high_operand" "")))
4743    (clobber (match_operand:SI 3 "register_operand" ""))]
4744   ""
4745   [(set (match_dup 3) (match_dup 4))
4746    (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
4748   operands[4] = GEN_INT (~INTVAL (operands[2]));
4751 (define_insn_and_split "*and_not_di_sp32"
4752   [(set (match_operand:DI 0 "register_operand" "=r")
4753         (and:DI (not:DI (match_operand:DI 1 "register_operand" "%r"))
4754                 (match_operand:DI 2 "register_operand" "r")))]
4755   "! TARGET_ARCH64"
4756   "#"
4757   "&& reload_completed
4758    && ((GET_CODE (operands[0]) == REG
4759         && SPARC_INT_REG_P (REGNO (operands[0])))
4760        || (GET_CODE (operands[0]) == SUBREG
4761            && GET_CODE (SUBREG_REG (operands[0])) == REG
4762            && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
4763   [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
4764    (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
4765   "operands[3] = gen_highpart (SImode, operands[0]);
4766    operands[4] = gen_highpart (SImode, operands[1]);
4767    operands[5] = gen_highpart (SImode, operands[2]);
4768    operands[6] = gen_lowpart (SImode, operands[0]);
4769    operands[7] = gen_lowpart (SImode, operands[1]);
4770    operands[8] = gen_lowpart (SImode, operands[2]);"
4771   [(set_attr "length" "2")])
4773 (define_insn "*and_not_di_sp64"
4774   [(set (match_operand:DI 0 "register_operand" "=r")
4775         (and:DI (not:DI (match_operand:DI 1 "register_operand" "%r"))
4776                 (match_operand:DI 2 "register_operand" "r")))]
4777   "TARGET_ARCH64"
4778   "andn\t%2, %1, %0")
4780 (define_insn "*and_not_si"
4781   [(set (match_operand:SI 0 "register_operand" "=r")
4782         (and:SI (not:SI (match_operand:SI 1 "register_operand" "%r"))
4783                 (match_operand:SI 2 "register_operand" "r")))]
4784   ""
4785   "andn\t%2, %1, %0")
4787 (define_expand "iordi3"
4788   [(set (match_operand:DI 0 "register_operand" "")
4789         (ior:DI (match_operand:DI 1 "arith_double_operand" "")
4790                 (match_operand:DI 2 "arith_double_operand" "")))]
4791   ""
4792   "")
4794 (define_insn "*iordi3_sp32"
4795   [(set (match_operand:DI 0 "register_operand" "=r")
4796         (ior:DI (match_operand:DI 1 "arith_double_operand" "%r")
4797                 (match_operand:DI 2 "arith_double_operand" "rHI")))]
4798   "! TARGET_ARCH64"
4799   "#"
4800   [(set_attr "length" "2")])
4802 (define_insn "*iordi3_sp64"
4803   [(set (match_operand:DI 0 "register_operand" "=r")
4804         (ior:DI (match_operand:DI 1 "arith_operand" "%r")
4805                 (match_operand:DI 2 "arith_operand" "rI")))]
4806   "TARGET_ARCH64"
4807   "or\t%1, %2, %0")
4809 (define_insn "iorsi3"
4810   [(set (match_operand:SI 0 "register_operand" "=r")
4811         (ior:SI (match_operand:SI 1 "arith_operand" "%r")
4812                 (match_operand:SI 2 "arith_operand" "rI")))]
4813   ""
4814   "or\t%1, %2, %0")
4816 (define_split
4817   [(set (match_operand:SI 0 "register_operand" "")
4818         (ior:SI (match_operand:SI 1 "register_operand" "")
4819                 (match_operand:SI 2 "const_compl_high_operand" "")))
4820    (clobber (match_operand:SI 3 "register_operand" ""))]
4821   ""
4822   [(set (match_dup 3) (match_dup 4))
4823    (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
4825   operands[4] = GEN_INT (~INTVAL (operands[2]));
4828 (define_insn_and_split "*or_not_di_sp32"
4829   [(set (match_operand:DI 0 "register_operand" "=r")
4830         (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
4831                 (match_operand:DI 2 "register_operand" "r")))]
4832   "! TARGET_ARCH64"
4833   "#"
4834   "&& reload_completed
4835    && ((GET_CODE (operands[0]) == REG
4836         && SPARC_INT_REG_P (REGNO (operands[0])))
4837        || (GET_CODE (operands[0]) == SUBREG
4838            && GET_CODE (SUBREG_REG (operands[0])) == REG
4839            && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
4840   [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
4841    (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
4842   "operands[3] = gen_highpart (SImode, operands[0]);
4843    operands[4] = gen_highpart (SImode, operands[1]);
4844    operands[5] = gen_highpart (SImode, operands[2]);
4845    operands[6] = gen_lowpart (SImode, operands[0]);
4846    operands[7] = gen_lowpart (SImode, operands[1]);
4847    operands[8] = gen_lowpart (SImode, operands[2]);"
4848   [(set_attr "length" "2")])
4850 (define_insn "*or_not_di_sp64"
4851   [(set (match_operand:DI 0 "register_operand" "=r")
4852         (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
4853                 (match_operand:DI 2 "register_operand" "r")))]
4854   "TARGET_ARCH64"
4855   "orn\t%2, %1, %0")
4857 (define_insn "*or_not_si"
4858   [(set (match_operand:SI 0 "register_operand" "=r")
4859         (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
4860                 (match_operand:SI 2 "register_operand" "r")))]
4861   ""
4862   "orn\t%2, %1, %0")
4864 (define_expand "xordi3"
4865   [(set (match_operand:DI 0 "register_operand" "")
4866         (xor:DI (match_operand:DI 1 "arith_double_operand" "")
4867                 (match_operand:DI 2 "arith_double_operand" "")))]
4868   ""
4869   "")
4871 (define_insn "*xordi3_sp32"
4872   [(set (match_operand:DI 0 "register_operand" "=r")
4873         (xor:DI (match_operand:DI 1 "arith_double_operand" "%r")
4874                 (match_operand:DI 2 "arith_double_operand" "rHI")))]
4875   "! TARGET_ARCH64"
4876   "#"
4877   [(set_attr "length" "2")])
4879 (define_insn "*xordi3_sp64"
4880   [(set (match_operand:DI 0 "register_operand" "=r")
4881         (xor:DI (match_operand:DI 1 "arith_operand" "%rJ")
4882                 (match_operand:DI 2 "arith_operand" "rI")))]
4883   "TARGET_ARCH64"
4884   "xor\t%r1, %2, %0")
4886 (define_insn "xorsi3"
4887   [(set (match_operand:SI 0 "register_operand" "=r")
4888         (xor:SI (match_operand:SI 1 "arith_operand" "%rJ")
4889                   (match_operand:SI 2 "arith_operand" "rI")))]
4890   ""
4891   "xor\t%r1, %2, %0")
4893 (define_split
4894   [(set (match_operand:SI 0 "register_operand" "")
4895         (xor:SI (match_operand:SI 1 "register_operand" "")
4896                 (match_operand:SI 2 "const_compl_high_operand" "")))
4897    (clobber (match_operand:SI 3 "register_operand" ""))]
4898    ""
4899   [(set (match_dup 3) (match_dup 4))
4900    (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
4902   operands[4] = GEN_INT (~INTVAL (operands[2]));
4905 (define_split
4906   [(set (match_operand:SI 0 "register_operand" "")
4907         (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
4908                         (match_operand:SI 2 "const_compl_high_operand" ""))))
4909    (clobber (match_operand:SI 3 "register_operand" ""))]
4910   ""
4911   [(set (match_dup 3) (match_dup 4))
4912    (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
4914   operands[4] = GEN_INT (~INTVAL (operands[2]));
4917 ;; Split DImode logical operations requiring two instructions.
4918 (define_split
4919   [(set (match_operand:DI 0 "register_operand" "")
4920         (match_operator:DI 1 "cc_arith_operator"        ; AND, IOR, XOR
4921                            [(match_operand:DI 2 "register_operand" "")
4922                             (match_operand:DI 3 "arith_double_operand" "")]))]
4923   "! TARGET_ARCH64
4924    && reload_completed
4925    && ((GET_CODE (operands[0]) == REG
4926         && SPARC_INT_REG_P (REGNO (operands[0])))
4927        || (GET_CODE (operands[0]) == SUBREG
4928            && GET_CODE (SUBREG_REG (operands[0])) == REG
4929            && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
4930   [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
4931    (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
4933   operands[4] = gen_highpart (SImode, operands[0]);
4934   operands[5] = gen_lowpart (SImode, operands[0]);
4935   operands[6] = gen_highpart (SImode, operands[2]);
4936   operands[7] = gen_lowpart (SImode, operands[2]);
4937 #if HOST_BITS_PER_WIDE_INT == 32
4938   if (GET_CODE (operands[3]) == CONST_INT)
4939     {
4940       if (INTVAL (operands[3]) < 0)
4941         operands[8] = constm1_rtx;
4942       else
4943         operands[8] = const0_rtx;
4944     }
4945   else
4946 #endif
4947     operands[8] = gen_highpart_mode (SImode, DImode, operands[3]);
4948   operands[9] = gen_lowpart (SImode, operands[3]);
4951 ;; xnor patterns.  Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
4952 ;; Combine now canonicalizes to the rightmost expression.
4953 (define_insn_and_split "*xor_not_di_sp32"
4954   [(set (match_operand:DI 0 "register_operand" "=r")
4955         (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r")
4956                         (match_operand:DI 2 "register_operand" "r"))))]
4957   "! TARGET_ARCH64"
4958   "#"
4959   "&& reload_completed
4960    && ((GET_CODE (operands[0]) == REG
4961         && SPARC_INT_REG_P (REGNO (operands[0])))
4962        || (GET_CODE (operands[0]) == SUBREG
4963            && GET_CODE (SUBREG_REG (operands[0])) == REG
4964            && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
4965   [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
4966    (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
4967   "operands[3] = gen_highpart (SImode, operands[0]);
4968    operands[4] = gen_highpart (SImode, operands[1]);
4969    operands[5] = gen_highpart (SImode, operands[2]);
4970    operands[6] = gen_lowpart (SImode, operands[0]);
4971    operands[7] = gen_lowpart (SImode, operands[1]);
4972    operands[8] = gen_lowpart (SImode, operands[2]);"
4973   [(set_attr "length" "2")])
4975 (define_insn "*xor_not_di_sp64"
4976   [(set (match_operand:DI 0 "register_operand" "=r")
4977         (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
4978                         (match_operand:DI 2 "arith_operand" "rI"))))]
4979   "TARGET_ARCH64"
4980   "xnor\t%r1, %2, %0")
4982 (define_insn "*xor_not_si"
4983   [(set (match_operand:SI 0 "register_operand" "=r")
4984         (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4985                         (match_operand:SI 2 "arith_operand" "rI"))))]
4986   ""
4987   "xnor\t%r1, %2, %0")
4989 ;; These correspond to the above in the case where we also (or only)
4990 ;; want to set the condition code.  
4992 (define_insn "*cmp_cc_arith_op"
4993   [(set (reg:CC CC_REG)
4994         (compare:CC
4995          (match_operator:SI 2 "cc_arith_operator"
4996                             [(match_operand:SI 0 "arith_operand" "%r")
4997                              (match_operand:SI 1 "arith_operand" "rI")])
4998          (const_int 0)))]
4999   ""
5000   "%A2cc\t%0, %1, %%g0"
5001   [(set_attr "type" "compare")])
5003 (define_insn "*cmp_ccx_arith_op"
5004   [(set (reg:CCX CC_REG)
5005         (compare:CCX
5006          (match_operator:DI 2 "cc_arith_operator"
5007                             [(match_operand:DI 0 "arith_operand" "%r")
5008                              (match_operand:DI 1 "arith_operand" "rI")])
5009          (const_int 0)))]
5010   "TARGET_ARCH64"
5011   "%A2cc\t%0, %1, %%g0"
5012   [(set_attr "type" "compare")])
5014 (define_insn "*cmp_cc_arith_op_set"
5015   [(set (reg:CC CC_REG)
5016         (compare:CC
5017          (match_operator:SI 3 "cc_arith_operator"
5018                             [(match_operand:SI 1 "arith_operand" "%r")
5019                              (match_operand:SI 2 "arith_operand" "rI")])
5020          (const_int 0)))
5021    (set (match_operand:SI 0 "register_operand" "=r")
5022         (match_operator:SI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5023   "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5024   "%A3cc\t%1, %2, %0"
5025   [(set_attr "type" "compare")])
5027 (define_insn "*cmp_ccx_arith_op_set"
5028   [(set (reg:CCX CC_REG)
5029         (compare:CCX
5030          (match_operator:DI 3 "cc_arith_operator"
5031                             [(match_operand:DI 1 "arith_operand" "%r")
5032                              (match_operand:DI 2 "arith_operand" "rI")])
5033          (const_int 0)))
5034    (set (match_operand:DI 0 "register_operand" "=r")
5035         (match_operator:DI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5036   "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5037   "%A3cc\t%1, %2, %0"
5038   [(set_attr "type" "compare")])
5040 (define_insn "*cmp_cc_xor_not"
5041   [(set (reg:CC CC_REG)
5042         (compare:CC
5043          (not:SI (xor:SI (match_operand:SI 0 "register_or_zero_operand" "%rJ")
5044                          (match_operand:SI 1 "arith_operand" "rI")))
5045          (const_int 0)))]
5046   ""
5047   "xnorcc\t%r0, %1, %%g0"
5048   [(set_attr "type" "compare")])
5050 (define_insn "*cmp_ccx_xor_not"
5051   [(set (reg:CCX CC_REG)
5052         (compare:CCX
5053          (not:DI (xor:DI (match_operand:DI 0 "register_or_zero_operand" "%rJ")
5054                          (match_operand:DI 1 "arith_operand" "rI")))
5055          (const_int 0)))]
5056   "TARGET_ARCH64"
5057   "xnorcc\t%r0, %1, %%g0"
5058   [(set_attr "type" "compare")])
5060 (define_insn "*cmp_cc_xor_not_set"
5061   [(set (reg:CC CC_REG)
5062         (compare:CC
5063          (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
5064                          (match_operand:SI 2 "arith_operand" "rI")))
5065          (const_int 0)))
5066    (set (match_operand:SI 0 "register_operand" "=r")
5067         (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
5068   ""
5069   "xnorcc\t%r1, %2, %0"
5070   [(set_attr "type" "compare")])
5072 (define_insn "*cmp_ccx_xor_not_set"
5073   [(set (reg:CCX CC_REG)
5074         (compare:CCX
5075          (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
5076                          (match_operand:DI 2 "arith_operand" "rI")))
5077          (const_int 0)))
5078    (set (match_operand:DI 0 "register_operand" "=r")
5079         (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
5080   "TARGET_ARCH64"
5081   "xnorcc\t%r1, %2, %0"
5082   [(set_attr "type" "compare")])
5084 (define_insn "*cmp_cc_arith_op_not"
5085   [(set (reg:CC CC_REG)
5086         (compare:CC
5087          (match_operator:SI 2 "cc_arith_not_operator"
5088                             [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
5089                              (match_operand:SI 1 "register_or_zero_operand" "rJ")])
5090          (const_int 0)))]
5091   ""
5092   "%B2cc\t%r1, %0, %%g0"
5093   [(set_attr "type" "compare")])
5095 (define_insn "*cmp_ccx_arith_op_not"
5096   [(set (reg:CCX CC_REG)
5097         (compare:CCX
5098          (match_operator:DI 2 "cc_arith_not_operator"
5099                             [(not:DI (match_operand:DI 0 "arith_operand" "rI"))
5100                              (match_operand:DI 1 "register_or_zero_operand" "rJ")])
5101          (const_int 0)))]
5102   "TARGET_ARCH64"
5103   "%B2cc\t%r1, %0, %%g0"
5104   [(set_attr "type" "compare")])
5106 (define_insn "*cmp_cc_arith_op_not_set"
5107   [(set (reg:CC CC_REG)
5108         (compare:CC
5109          (match_operator:SI 3 "cc_arith_not_operator"
5110                             [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
5111                              (match_operand:SI 2 "register_or_zero_operand" "rJ")])
5112          (const_int 0)))
5113    (set (match_operand:SI 0 "register_operand" "=r")
5114         (match_operator:SI 4 "cc_arith_not_operator"
5115                             [(not:SI (match_dup 1)) (match_dup 2)]))]
5116   "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5117   "%B3cc\t%r2, %1, %0"
5118   [(set_attr "type" "compare")])
5120 (define_insn "*cmp_ccx_arith_op_not_set"
5121   [(set (reg:CCX CC_REG)
5122         (compare:CCX
5123          (match_operator:DI 3 "cc_arith_not_operator"
5124                             [(not:DI (match_operand:DI 1 "arith_operand" "rI"))
5125                              (match_operand:DI 2 "register_or_zero_operand" "rJ")])
5126          (const_int 0)))
5127    (set (match_operand:DI 0 "register_operand" "=r")
5128         (match_operator:DI 4 "cc_arith_not_operator"
5129                             [(not:DI (match_dup 1)) (match_dup 2)]))]
5130   "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5131   "%B3cc\t%r2, %1, %0"
5132   [(set_attr "type" "compare")])
5134 ;; We cannot use the "neg" pseudo insn because the Sun assembler
5135 ;; does not know how to make it work for constants.
5137 (define_expand "negdi2"
5138   [(set (match_operand:DI 0 "register_operand" "=r")
5139         (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5140   ""
5142   if (! TARGET_ARCH64)
5143     {
5144       emit_insn (gen_rtx_PARALLEL
5145                  (VOIDmode,
5146                   gen_rtvec (2,
5147                              gen_rtx_SET (VOIDmode, operand0,
5148                                           gen_rtx_NEG (DImode, operand1)),
5149                              gen_rtx_CLOBBER (VOIDmode,
5150                                               gen_rtx_REG (CCmode,
5151                                                            SPARC_ICC_REG)))));
5152       DONE;
5153     }
5156 (define_insn_and_split "*negdi2_sp32"
5157   [(set (match_operand:DI 0 "register_operand" "=r")
5158         (neg:DI (match_operand:DI 1 "register_operand" "r")))
5159    (clobber (reg:CC CC_REG))]
5160   "! TARGET_ARCH64"
5161   "#"
5162   "&& reload_completed"
5163   [(parallel [(set (reg:CC_NOOV CC_REG)
5164                    (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
5165                                     (const_int 0)))
5166               (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
5167    (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
5168                                 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
5169   "operands[2] = gen_highpart (SImode, operands[0]);
5170    operands[3] = gen_highpart (SImode, operands[1]);
5171    operands[4] = gen_lowpart (SImode, operands[0]);
5172    operands[5] = gen_lowpart (SImode, operands[1]);"
5173   [(set_attr "length" "2")])
5175 (define_insn "*negdi2_sp64"
5176   [(set (match_operand:DI 0 "register_operand" "=r")
5177         (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5178   "TARGET_ARCH64"
5179   "sub\t%%g0, %1, %0")
5181 (define_insn "negsi2"
5182   [(set (match_operand:SI 0 "register_operand" "=r")
5183         (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
5184   ""
5185   "sub\t%%g0, %1, %0")
5187 (define_insn "*cmp_cc_neg"
5188   [(set (reg:CC_NOOV CC_REG)
5189         (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
5190                          (const_int 0)))]
5191   ""
5192   "subcc\t%%g0, %0, %%g0"
5193   [(set_attr "type" "compare")])
5195 (define_insn "*cmp_ccx_neg"
5196   [(set (reg:CCX_NOOV CC_REG)
5197         (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_operand" "rI"))
5198                           (const_int 0)))]
5199   "TARGET_ARCH64"
5200   "subcc\t%%g0, %0, %%g0"
5201   [(set_attr "type" "compare")])
5203 (define_insn "*cmp_cc_set_neg"
5204   [(set (reg:CC_NOOV CC_REG)
5205         (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
5206                          (const_int 0)))
5207    (set (match_operand:SI 0 "register_operand" "=r")
5208         (neg:SI (match_dup 1)))]
5209   ""
5210   "subcc\t%%g0, %1, %0"
5211   [(set_attr "type" "compare")])
5213 (define_insn "*cmp_ccx_set_neg"
5214   [(set (reg:CCX_NOOV CC_REG)
5215         (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_operand" "rI"))
5216                           (const_int 0)))
5217    (set (match_operand:DI 0 "register_operand" "=r")
5218         (neg:DI (match_dup 1)))]
5219   "TARGET_ARCH64"
5220   "subcc\t%%g0, %1, %0"
5221   [(set_attr "type" "compare")])
5223 ;; We cannot use the "not" pseudo insn because the Sun assembler
5224 ;; does not know how to make it work for constants.
5225 (define_expand "one_cmpldi2"
5226   [(set (match_operand:DI 0 "register_operand" "")
5227         (not:DI (match_operand:DI 1 "register_operand" "")))]
5228   ""
5229   "")
5231 (define_insn_and_split "*one_cmpldi2_sp32"
5232   [(set (match_operand:DI 0 "register_operand" "=r")
5233         (not:DI (match_operand:DI 1 "register_operand" "r")))]
5234   "! TARGET_ARCH64"
5235   "#"
5236   "&& reload_completed
5237    && ((GET_CODE (operands[0]) == REG
5238         && SPARC_INT_REG_P (REGNO (operands[0])))
5239        || (GET_CODE (operands[0]) == SUBREG
5240            && GET_CODE (SUBREG_REG (operands[0])) == REG
5241            && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
5242   [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
5243    (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
5244   "operands[2] = gen_highpart (SImode, operands[0]);
5245    operands[3] = gen_highpart (SImode, operands[1]);
5246    operands[4] = gen_lowpart (SImode, operands[0]);
5247    operands[5] = gen_lowpart (SImode, operands[1]);"
5248   [(set_attr "length" "2")])
5250 (define_insn "*one_cmpldi2_sp64"
5251   [(set (match_operand:DI 0 "register_operand" "=r")
5252         (not:DI (match_operand:DI 1 "arith_operand" "rI")))]
5253   "TARGET_ARCH64"
5254   "xnor\t%%g0, %1, %0")
5256 (define_insn "one_cmplsi2"
5257   [(set (match_operand:SI 0 "register_operand" "=r")
5258         (not:SI (match_operand:SI 1 "arith_operand" "rI")))]
5259   ""
5260   "xnor\t%%g0, %1, %0")
5262 (define_insn "*cmp_cc_not"
5263   [(set (reg:CC CC_REG)
5264         (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
5265                     (const_int 0)))]
5266   ""
5267   "xnorcc\t%%g0, %0, %%g0"
5268   [(set_attr "type" "compare")])
5270 (define_insn "*cmp_ccx_not"
5271   [(set (reg:CCX CC_REG)
5272         (compare:CCX (not:DI (match_operand:DI 0 "arith_operand" "rI"))
5273                      (const_int 0)))]
5274   "TARGET_ARCH64"
5275   "xnorcc\t%%g0, %0, %%g0"
5276   [(set_attr "type" "compare")])
5278 (define_insn "*cmp_cc_set_not"
5279   [(set (reg:CC CC_REG)
5280         (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
5281                     (const_int 0)))
5282    (set (match_operand:SI 0 "register_operand" "=r")
5283         (not:SI (match_dup 1)))]
5284   ""
5285   "xnorcc\t%%g0, %1, %0"
5286   [(set_attr "type" "compare")])
5288 (define_insn "*cmp_ccx_set_not"
5289   [(set (reg:CCX CC_REG)
5290         (compare:CCX (not:DI (match_operand:DI 1 "arith_operand" "rI"))
5291                     (const_int 0)))
5292    (set (match_operand:DI 0 "register_operand" "=r")
5293         (not:DI (match_dup 1)))]
5294   "TARGET_ARCH64"
5295   "xnorcc\t%%g0, %1, %0"
5296   [(set_attr "type" "compare")])
5298 (define_insn "*cmp_cc_set"
5299   [(set (match_operand:SI 0 "register_operand" "=r")
5300         (match_operand:SI 1 "register_operand" "r"))
5301    (set (reg:CC CC_REG)
5302         (compare:CC (match_dup 1)
5303                     (const_int 0)))]
5304   ""
5305   "orcc\t%1, 0, %0"
5306   [(set_attr "type" "compare")])
5308 (define_insn "*cmp_ccx_set64"
5309   [(set (match_operand:DI 0 "register_operand" "=r")
5310         (match_operand:DI 1 "register_operand" "r"))
5311    (set (reg:CCX CC_REG)
5312         (compare:CCX (match_dup 1)
5313                      (const_int 0)))]
5314   "TARGET_ARCH64"
5315   "orcc\t%1, 0, %0"
5316    [(set_attr "type" "compare")])
5319 ;; Floating point arithmetic instructions.
5321 (define_expand "addtf3"
5322   [(set (match_operand:TF 0 "nonimmediate_operand" "")
5323         (plus:TF (match_operand:TF 1 "general_operand" "")
5324                  (match_operand:TF 2 "general_operand" "")))]
5325   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5326   "emit_tfmode_binop (PLUS, operands); DONE;")
5328 (define_insn "*addtf3_hq"
5329   [(set (match_operand:TF 0 "register_operand" "=e")
5330         (plus:TF (match_operand:TF 1 "register_operand" "e")
5331                  (match_operand:TF 2 "register_operand" "e")))]
5332   "TARGET_FPU && TARGET_HARD_QUAD"
5333   "faddq\t%1, %2, %0"
5334   [(set_attr "type" "fp")])
5336 (define_insn "adddf3"
5337   [(set (match_operand:DF 0 "register_operand" "=e")
5338         (plus:DF (match_operand:DF 1 "register_operand" "e")
5339                  (match_operand:DF 2 "register_operand" "e")))]
5340   "TARGET_FPU"
5341   "faddd\t%1, %2, %0"
5342   [(set_attr "type" "fp")
5343    (set_attr "fptype" "double")])
5345 (define_insn "addsf3"
5346   [(set (match_operand:SF 0 "register_operand" "=f")
5347         (plus:SF (match_operand:SF 1 "register_operand" "f")
5348                  (match_operand:SF 2 "register_operand" "f")))]
5349   "TARGET_FPU"
5350   "fadds\t%1, %2, %0"
5351   [(set_attr "type" "fp")])
5353 (define_expand "subtf3"
5354   [(set (match_operand:TF 0 "nonimmediate_operand" "")
5355         (minus:TF (match_operand:TF 1 "general_operand" "")
5356                   (match_operand:TF 2 "general_operand" "")))]
5357   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5358   "emit_tfmode_binop (MINUS, operands); DONE;")
5360 (define_insn "*subtf3_hq"
5361   [(set (match_operand:TF 0 "register_operand" "=e")
5362         (minus:TF (match_operand:TF 1 "register_operand" "e")
5363                   (match_operand:TF 2 "register_operand" "e")))]
5364   "TARGET_FPU && TARGET_HARD_QUAD"
5365   "fsubq\t%1, %2, %0"
5366   [(set_attr "type" "fp")])
5368 (define_insn "subdf3"
5369   [(set (match_operand:DF 0 "register_operand" "=e")
5370         (minus:DF (match_operand:DF 1 "register_operand" "e")
5371                   (match_operand:DF 2 "register_operand" "e")))]
5372   "TARGET_FPU"
5373   "fsubd\t%1, %2, %0"
5374   [(set_attr "type" "fp")
5375    (set_attr "fptype" "double")])
5377 (define_insn "subsf3"
5378   [(set (match_operand:SF 0 "register_operand" "=f")
5379         (minus:SF (match_operand:SF 1 "register_operand" "f")
5380                   (match_operand:SF 2 "register_operand" "f")))]
5381   "TARGET_FPU"
5382   "fsubs\t%1, %2, %0"
5383   [(set_attr "type" "fp")])
5385 (define_expand "multf3"
5386   [(set (match_operand:TF 0 "nonimmediate_operand" "")
5387         (mult:TF (match_operand:TF 1 "general_operand" "")
5388                  (match_operand:TF 2 "general_operand" "")))]
5389   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5390   "emit_tfmode_binop (MULT, operands); DONE;")
5392 (define_insn "*multf3_hq"
5393   [(set (match_operand:TF 0 "register_operand" "=e")
5394         (mult:TF (match_operand:TF 1 "register_operand" "e")
5395                  (match_operand:TF 2 "register_operand" "e")))]
5396   "TARGET_FPU && TARGET_HARD_QUAD"
5397   "fmulq\t%1, %2, %0"
5398   [(set_attr "type" "fpmul")])
5400 (define_insn "muldf3"
5401   [(set (match_operand:DF 0 "register_operand" "=e")
5402         (mult:DF (match_operand:DF 1 "register_operand" "e")
5403                  (match_operand:DF 2 "register_operand" "e")))]
5404   "TARGET_FPU"
5405   "fmuld\t%1, %2, %0"
5406   [(set_attr "type" "fpmul")
5407    (set_attr "fptype" "double")])
5409 (define_insn "mulsf3"
5410   [(set (match_operand:SF 0 "register_operand" "=f")
5411         (mult:SF (match_operand:SF 1 "register_operand" "f")
5412                  (match_operand:SF 2 "register_operand" "f")))]
5413   "TARGET_FPU"
5414   "fmuls\t%1, %2, %0"
5415   [(set_attr "type" "fpmul")])
5417 (define_insn "fmadf4"
5418   [(set (match_operand:DF 0 "register_operand" "=e")
5419         (fma:DF (match_operand:DF 1 "register_operand" "e")
5420                 (match_operand:DF 2 "register_operand" "e")
5421                 (match_operand:DF 3 "register_operand" "e")))]
5422   "TARGET_FMAF"
5423   "fmaddd\t%1, %2, %3, %0"
5424   [(set_attr "type" "fpmul")])
5426 (define_insn "fmsdf4"
5427   [(set (match_operand:DF 0 "register_operand" "=e")
5428         (fma:DF (match_operand:DF 1 "register_operand" "e")
5429                 (match_operand:DF 2 "register_operand" "e")
5430                 (neg:DF (match_operand:DF 3 "register_operand" "e"))))]
5431   "TARGET_FMAF"
5432   "fmsubd\t%1, %2, %3, %0"
5433   [(set_attr "type" "fpmul")])
5435 (define_insn "*nfmadf4"
5436   [(set (match_operand:DF 0 "register_operand" "=e")
5437         (neg:DF (fma:DF (match_operand:DF 1 "register_operand" "e")
5438                         (match_operand:DF 2 "register_operand" "e")
5439                         (match_operand:DF 3 "register_operand" "e"))))]
5440   "TARGET_FMAF"
5441   "fnmaddd\t%1, %2, %3, %0"
5442   [(set_attr "type" "fpmul")])
5444 (define_insn "*nfmsdf4"
5445   [(set (match_operand:DF 0 "register_operand" "=e")
5446         (neg:DF (fma:DF (match_operand:DF 1 "register_operand" "e")
5447                         (match_operand:DF 2 "register_operand" "e")
5448                         (neg:DF (match_operand:DF 3 "register_operand" "e")))))]
5449   "TARGET_FMAF"
5450   "fnmsubd\t%1, %2, %3, %0"
5451   [(set_attr "type" "fpmul")])
5453 (define_insn "fmasf4"
5454   [(set (match_operand:SF 0 "register_operand" "=f")
5455         (fma:SF (match_operand:SF 1 "register_operand" "f")
5456                 (match_operand:SF 2 "register_operand" "f")
5457                 (match_operand:SF 3 "register_operand" "f")))]
5458   "TARGET_FMAF"
5459   "fmadds\t%1, %2, %3, %0"
5460   [(set_attr "type" "fpmul")])
5462 (define_insn "fmssf4"
5463   [(set (match_operand:SF 0 "register_operand" "=f")
5464         (fma:SF (match_operand:SF 1 "register_operand" "f")
5465                 (match_operand:SF 2 "register_operand" "f")
5466                 (neg:SF (match_operand:SF 3 "register_operand" "f"))))]
5467   "TARGET_FMAF"
5468   "fmsubs\t%1, %2, %3, %0"
5469   [(set_attr "type" "fpmul")])
5471 (define_insn "*nfmasf4"
5472   [(set (match_operand:SF 0 "register_operand" "=f")
5473         (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "f")
5474                         (match_operand:SF 2 "register_operand" "f")
5475                         (match_operand:SF 3 "register_operand" "f"))))]
5476   "TARGET_FMAF"
5477   "fnmadds\t%1, %2, %3, %0"
5478   [(set_attr "type" "fpmul")])
5480 (define_insn "*nfmssf4"
5481   [(set (match_operand:SF 0 "register_operand" "=f")
5482         (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "f")
5483                         (match_operand:SF 2 "register_operand" "f")
5484                         (neg:SF (match_operand:SF 3 "register_operand" "f")))))]
5485   "TARGET_FMAF"
5486   "fnmsubs\t%1, %2, %3, %0"
5487   [(set_attr "type" "fpmul")])
5489 (define_insn "*muldf3_extend"
5490   [(set (match_operand:DF 0 "register_operand" "=e")
5491         (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
5492                  (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
5493   "(TARGET_V8 || TARGET_V9) && TARGET_FPU && !sparc_fix_ut699"
5494   "fsmuld\t%1, %2, %0"
5495   [(set_attr "type" "fpmul")
5496    (set_attr "fptype" "double")])
5498 (define_insn "*multf3_extend"
5499   [(set (match_operand:TF 0 "register_operand" "=e")
5500         (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
5501                  (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
5502   "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
5503   "fdmulq\t%1, %2, %0"
5504   [(set_attr "type" "fpmul")])
5506 (define_expand "divtf3"
5507   [(set (match_operand:TF 0 "nonimmediate_operand" "")
5508         (div:TF (match_operand:TF 1 "general_operand" "")
5509                 (match_operand:TF 2 "general_operand" "")))]
5510   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5511   "emit_tfmode_binop (DIV, operands); DONE;")
5513 ;; don't have timing for quad-prec. divide.
5514 (define_insn "*divtf3_hq"
5515   [(set (match_operand:TF 0 "register_operand" "=e")
5516         (div:TF (match_operand:TF 1 "register_operand" "e")
5517                 (match_operand:TF 2 "register_operand" "e")))]
5518   "TARGET_FPU && TARGET_HARD_QUAD"
5519   "fdivq\t%1, %2, %0"
5520   [(set_attr "type" "fpdivs")])
5522 (define_expand "divdf3"
5523   [(set (match_operand:DF 0 "register_operand" "=e")
5524         (div:DF (match_operand:DF 1 "register_operand" "e")
5525                 (match_operand:DF 2 "register_operand" "e")))]
5526   "TARGET_FPU"
5527   "")
5529 (define_insn "*divdf3_nofix"
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 && !sparc_fix_ut699"
5534   "fdivd\t%1, %2, %0"
5535   [(set_attr "type" "fpdivd")
5536    (set_attr "fptype" "double")])
5538 (define_insn "*divdf3_fix"
5539   [(set (match_operand:DF 0 "register_operand" "=e")
5540         (div:DF (match_operand:DF 1 "register_operand" "e")
5541                 (match_operand:DF 2 "register_operand" "e")))]
5542   "TARGET_FPU && sparc_fix_ut699"
5543   "fdivd\t%1, %2, %0\n\tstd\t%0, [%%sp-8]"
5544   [(set_attr "type" "fpdivd")
5545    (set_attr "fptype" "double")
5546    (set_attr "length" "2")])
5548 (define_insn "divsf3"
5549   [(set (match_operand:SF 0 "register_operand" "=f")
5550         (div:SF (match_operand:SF 1 "register_operand" "f")
5551                 (match_operand:SF 2 "register_operand" "f")))]
5552   "TARGET_FPU && !sparc_fix_ut699"
5553   "fdivs\t%1, %2, %0"
5554   [(set_attr "type" "fpdivs")])
5556 (define_expand "negtf2"
5557   [(set (match_operand:TF 0 "register_operand" "=e,e")
5558         (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5559   "TARGET_FPU"
5560   "")
5562 (define_insn_and_split "*negtf2_notv9"
5563   [(set (match_operand:TF 0 "register_operand" "=e,e")
5564         (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5565   ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5566   "TARGET_FPU
5567    && ! TARGET_V9"
5568   "@
5569   fnegs\t%0, %0
5570   #"
5571   "&& reload_completed
5572    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5573   [(set (match_dup 2) (neg:SF (match_dup 3)))
5574    (set (match_dup 4) (match_dup 5))
5575    (set (match_dup 6) (match_dup 7))]
5576   "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5577    operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5578    operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5579    operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
5580    operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5581    operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5582   [(set_attr "type" "fpmove,*")
5583    (set_attr "length" "*,2")])
5585 (define_insn_and_split "*negtf2_v9"
5586   [(set (match_operand:TF 0 "register_operand" "=e,e")
5587         (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5588   ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5589   "TARGET_FPU && TARGET_V9"
5590   "@
5591   fnegd\t%0, %0
5592   #"
5593   "&& reload_completed
5594    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5595   [(set (match_dup 2) (neg:DF (match_dup 3)))
5596    (set (match_dup 4) (match_dup 5))]
5597   "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
5598    operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
5599    operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5600    operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5601   [(set_attr "type" "fpmove,*")
5602    (set_attr "length" "*,2")
5603    (set_attr "fptype" "double")])
5605 (define_expand "negdf2"
5606   [(set (match_operand:DF 0 "register_operand" "")
5607         (neg:DF (match_operand:DF 1 "register_operand" "")))]
5608   "TARGET_FPU"
5609   "")
5611 (define_insn_and_split "*negdf2_notv9"
5612   [(set (match_operand:DF 0 "register_operand" "=e,e")
5613         (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
5614   "TARGET_FPU && ! TARGET_V9"
5615   "@
5616   fnegs\t%0, %0
5617   #"
5618   "&& reload_completed
5619    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5620   [(set (match_dup 2) (neg:SF (match_dup 3)))
5621    (set (match_dup 4) (match_dup 5))]
5622   "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5623    operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5624    operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5625    operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
5626   [(set_attr "type" "fpmove,*")
5627    (set_attr "length" "*,2")])
5629 (define_insn "*negdf2_v9"
5630   [(set (match_operand:DF 0 "register_operand" "=e")
5631         (neg:DF (match_operand:DF 1 "register_operand" "e")))]
5632   "TARGET_FPU && TARGET_V9"
5633   "fnegd\t%1, %0"
5634   [(set_attr "type" "fpmove")
5635    (set_attr "fptype" "double")])
5637 (define_insn "negsf2"
5638   [(set (match_operand:SF 0 "register_operand" "=f")
5639         (neg:SF (match_operand:SF 1 "register_operand" "f")))]
5640   "TARGET_FPU"
5641   "fnegs\t%1, %0"
5642   [(set_attr "type" "fpmove")])
5644 (define_expand "abstf2"
5645   [(set (match_operand:TF 0 "register_operand" "")
5646         (abs:TF (match_operand:TF 1 "register_operand" "")))]
5647   "TARGET_FPU"
5648   "")
5650 (define_insn_and_split "*abstf2_notv9"
5651   [(set (match_operand:TF 0 "register_operand" "=e,e")
5652         (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5653   ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5654   "TARGET_FPU && ! TARGET_V9"
5655   "@
5656   fabss\t%0, %0
5657   #"
5658   "&& reload_completed
5659    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5660   [(set (match_dup 2) (abs:SF (match_dup 3)))
5661    (set (match_dup 4) (match_dup 5))
5662    (set (match_dup 6) (match_dup 7))]
5663   "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5664    operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5665    operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5666    operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
5667    operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5668    operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5669   [(set_attr "type" "fpmove,*")
5670    (set_attr "length" "*,2")])
5672 (define_insn "*abstf2_hq_v9"
5673   [(set (match_operand:TF 0 "register_operand" "=e,e")
5674         (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5675   "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
5676   "@
5677   fabsd\t%0, %0
5678   fabsq\t%1, %0"
5679   [(set_attr "type" "fpmove")
5680    (set_attr "fptype" "double,*")])
5682 (define_insn_and_split "*abstf2_v9"
5683   [(set (match_operand:TF 0 "register_operand" "=e,e")
5684         (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5685   "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
5686   "@
5687   fabsd\t%0, %0
5688   #"
5689   "&& reload_completed
5690    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5691   [(set (match_dup 2) (abs:DF (match_dup 3)))
5692    (set (match_dup 4) (match_dup 5))]
5693   "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
5694    operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
5695    operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5696    operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5697   [(set_attr "type" "fpmove,*")
5698    (set_attr "length" "*,2")
5699    (set_attr "fptype" "double,*")])
5701 (define_expand "absdf2"
5702   [(set (match_operand:DF 0 "register_operand" "")
5703         (abs:DF (match_operand:DF 1 "register_operand" "")))]
5704   "TARGET_FPU"
5705   "")
5707 (define_insn_and_split "*absdf2_notv9"
5708   [(set (match_operand:DF 0 "register_operand" "=e,e")
5709         (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
5710   "TARGET_FPU && ! TARGET_V9"
5711   "@
5712   fabss\t%0, %0
5713   #"
5714   "&& reload_completed
5715    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5716   [(set (match_dup 2) (abs:SF (match_dup 3)))
5717    (set (match_dup 4) (match_dup 5))]
5718   "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5719    operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5720    operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5721    operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
5722   [(set_attr "type" "fpmove,*")
5723    (set_attr "length" "*,2")])
5725 (define_insn "*absdf2_v9"
5726   [(set (match_operand:DF 0 "register_operand" "=e")
5727         (abs:DF (match_operand:DF 1 "register_operand" "e")))]
5728   "TARGET_FPU && TARGET_V9"
5729   "fabsd\t%1, %0"
5730   [(set_attr "type" "fpmove")
5731    (set_attr "fptype" "double")])
5733 (define_insn "abssf2"
5734   [(set (match_operand:SF 0 "register_operand" "=f")
5735         (abs:SF (match_operand:SF 1 "register_operand" "f")))]
5736   "TARGET_FPU"
5737   "fabss\t%1, %0"
5738   [(set_attr "type" "fpmove")])
5740 (define_expand "sqrttf2"
5741   [(set (match_operand:TF 0 "nonimmediate_operand" "")
5742         (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
5743   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5744   "emit_tfmode_unop (SQRT, operands); DONE;")
5746 (define_insn "*sqrttf2_hq"
5747   [(set (match_operand:TF 0 "register_operand" "=e")
5748         (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
5749   "TARGET_FPU && TARGET_HARD_QUAD"
5750   "fsqrtq\t%1, %0"
5751   [(set_attr "type" "fpsqrts")])
5753 (define_expand "sqrtdf2"
5754   [(set (match_operand:DF 0 "register_operand" "=e")
5755         (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
5756   "TARGET_FPU"
5757   "")
5759 (define_insn "*sqrtdf2_nofix"
5760   [(set (match_operand:DF 0 "register_operand" "=e")
5761         (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
5762   "TARGET_FPU && !sparc_fix_ut699"
5763   "fsqrtd\t%1, %0"
5764   [(set_attr "type" "fpsqrtd")
5765    (set_attr "fptype" "double")])
5767 (define_insn "*sqrtdf2_fix"
5768   [(set (match_operand:DF 0 "register_operand" "=e")
5769         (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
5770   "TARGET_FPU && sparc_fix_ut699"
5771   "fsqrtd\t%1, %0\n\tstd\t%0, [%%sp-8]"
5772   [(set_attr "type" "fpsqrtd")
5773    (set_attr "fptype" "double")
5774    (set_attr "length" "2")])
5776 (define_insn "sqrtsf2"
5777   [(set (match_operand:SF 0 "register_operand" "=f")
5778         (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
5779   "TARGET_FPU && !sparc_fix_ut699"
5780   "fsqrts\t%1, %0"
5781   [(set_attr "type" "fpsqrts")])
5784 ;; Arithmetic shift instructions.
5786 (define_insn "ashlsi3"
5787   [(set (match_operand:SI 0 "register_operand" "=r")
5788         (ashift:SI (match_operand:SI 1 "register_operand" "r")
5789                    (match_operand:SI 2 "arith_operand" "rI")))]
5790   ""
5792   if (GET_CODE (operands[2]) == CONST_INT)
5793     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5794   return "sll\t%1, %2, %0";
5796   [(set_attr "type" "shift")])
5798 (define_expand "ashldi3"
5799   [(set (match_operand:DI 0 "register_operand" "=r")
5800         (ashift:DI (match_operand:DI 1 "register_operand" "r")
5801                    (match_operand:SI 2 "arith_operand" "rI")))]
5802   "TARGET_ARCH64 || TARGET_V8PLUS"
5804   if (! TARGET_ARCH64)
5805     {
5806       if (GET_CODE (operands[2]) == CONST_INT)
5807         FAIL;
5808       emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
5809       DONE;
5810     }
5813 (define_insn "*ashldi3_sp64"
5814   [(set (match_operand:DI 0 "register_operand" "=r")
5815         (ashift:DI (match_operand:DI 1 "register_operand" "r")
5816                    (match_operand:SI 2 "arith_operand" "rI")))]
5817   "TARGET_ARCH64"
5819   if (GET_CODE (operands[2]) == CONST_INT)
5820     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5821   return "sllx\t%1, %2, %0";
5823   [(set_attr "type" "shift")])
5825 ;; XXX UGH!
5826 (define_insn "ashldi3_v8plus"
5827   [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5828         (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5829                    (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5830    (clobber (match_scratch:SI 3 "=X,X,&h"))]
5831   "TARGET_V8PLUS"
5832   "* return output_v8plus_shift (insn ,operands, \"sllx\");"
5833   [(set_attr "type" "multi")
5834    (set_attr "length" "5,5,6")])
5836 ;; Optimize (1LL<<x)-1
5837 ;; XXX this also needs to be fixed to handle equal subregs
5838 ;; XXX first before we could re-enable it.
5839 ;(define_insn ""
5840 ;  [(set (match_operand:DI 0 "register_operand" "=h")
5841 ;       (plus:DI (ashift:DI (const_int 1)
5842 ;                           (match_operand:SI 1 "arith_operand" "rI"))
5843 ;                (const_int -1)))]
5844 ;  "0 && TARGET_V8PLUS"
5846 ;  if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
5847 ;    return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5848 ;  return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5850 ;  [(set_attr "type" "multi")
5851 ;   (set_attr "length" "4")])
5853 (define_insn "*cmp_cc_ashift_1"
5854   [(set (reg:CC_NOOV CC_REG)
5855         (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
5856                                     (const_int 1))
5857                          (const_int 0)))]
5858   ""
5859   "addcc\t%0, %0, %%g0"
5860   [(set_attr "type" "compare")])
5862 (define_insn "*cmp_cc_set_ashift_1"
5863   [(set (reg:CC_NOOV CC_REG)
5864         (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
5865                                     (const_int 1))
5866                          (const_int 0)))
5867    (set (match_operand:SI 0 "register_operand" "=r")
5868         (ashift:SI (match_dup 1) (const_int 1)))]
5869   ""
5870   "addcc\t%1, %1, %0"
5871   [(set_attr "type" "compare")])
5873 (define_insn "ashrsi3"
5874   [(set (match_operand:SI 0 "register_operand" "=r")
5875         (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5876                      (match_operand:SI 2 "arith_operand" "rI")))]
5877   ""
5878   {
5879      if (GET_CODE (operands[2]) == CONST_INT)
5880        operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5881      return "sra\t%1, %2, %0";
5882   }
5883   [(set_attr "type" "shift")])
5885 (define_insn "*ashrsi3_extend"
5886   [(set (match_operand:DI 0 "register_operand" "=r")
5887         (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5888                                      (match_operand:SI 2 "arith_operand" "r"))))]
5889   "TARGET_ARCH64"
5890   "sra\t%1, %2, %0"
5891   [(set_attr "type" "shift")])
5893 ;; This handles the case as above, but with constant shift instead of
5894 ;; register. Combiner "simplifies" it for us a little bit though.
5895 (define_insn "*ashrsi3_extend2"
5896   [(set (match_operand:DI 0 "register_operand" "=r")
5897         (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
5898                                 (const_int 32))
5899                      (match_operand:SI 2 "small_int_operand" "I")))]
5900   "TARGET_ARCH64 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64"
5902   operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
5903   return "sra\t%1, %2, %0";
5905   [(set_attr "type" "shift")])
5907 (define_expand "ashrdi3"
5908   [(set (match_operand:DI 0 "register_operand" "=r")
5909         (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5910                      (match_operand:SI 2 "arith_operand" "rI")))]
5911   "TARGET_ARCH64 || TARGET_V8PLUS"
5913   if (! TARGET_ARCH64)
5914     {
5915       if (GET_CODE (operands[2]) == CONST_INT)
5916         FAIL;   /* prefer generic code in this case */
5917       emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
5918       DONE;
5919     }
5922 (define_insn "*ashrdi3_sp64"
5923   [(set (match_operand:DI 0 "register_operand" "=r")
5924         (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5925                      (match_operand:SI 2 "arith_operand" "rI")))]
5926   "TARGET_ARCH64"
5927   
5928   {
5929     if (GET_CODE (operands[2]) == CONST_INT)
5930       operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5931     return "srax\t%1, %2, %0";
5932   }
5933   [(set_attr "type" "shift")])
5935 ;; XXX
5936 (define_insn "ashrdi3_v8plus"
5937   [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5938         (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5939                      (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5940    (clobber (match_scratch:SI 3 "=X,X,&h"))]
5941   "TARGET_V8PLUS"
5942   "* return output_v8plus_shift (insn, operands, \"srax\");"
5943   [(set_attr "type" "multi")
5944    (set_attr "length" "5,5,6")])
5946 (define_insn "lshrsi3"
5947   [(set (match_operand:SI 0 "register_operand" "=r")
5948         (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5949                      (match_operand:SI 2 "arith_operand" "rI")))]
5950   ""
5951   {
5952     if (GET_CODE (operands[2]) == CONST_INT)
5953       operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5954     return "srl\t%1, %2, %0";
5955   }
5956   [(set_attr "type" "shift")])
5958 (define_insn "*lshrsi3_extend0"
5959   [(set (match_operand:DI 0 "register_operand" "=r")
5960         (zero_extend:DI
5961           (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5962                        (match_operand:SI 2 "arith_operand" "rI"))))]
5963   "TARGET_ARCH64"
5964   {
5965     if (GET_CODE (operands[2]) == CONST_INT)
5966       operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5967     return "srl\t%1, %2, %0";
5968   }
5969   [(set_attr "type" "shift")])
5971 ;; This handles the case where
5972 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
5973 ;; but combiner "simplifies" it for us.
5974 (define_insn "*lshrsi3_extend1"
5975   [(set (match_operand:DI 0 "register_operand" "=r")
5976         (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5977                            (match_operand:SI 2 "arith_operand" "r")) 0)
5978                 (match_operand 3 "const_int_operand" "")))]
5979   "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff"
5980   "srl\t%1, %2, %0"
5981   [(set_attr "type" "shift")])
5983 ;; This handles the case where
5984 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
5985 ;; but combiner "simplifies" it for us.
5986 (define_insn "*lshrsi3_extend2"
5987   [(set (match_operand:DI 0 "register_operand" "=r")
5988         (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
5989                          (match_operand 2 "small_int_operand" "I")
5990                          (const_int 32)))]
5991   "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
5993   operands[2] = GEN_INT (32 - INTVAL (operands[2]));
5994   return "srl\t%1, %2, %0";
5996   [(set_attr "type" "shift")])
5998 (define_expand "lshrdi3"
5999   [(set (match_operand:DI 0 "register_operand" "=r")
6000         (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6001                      (match_operand:SI 2 "arith_operand" "rI")))]
6002   "TARGET_ARCH64 || TARGET_V8PLUS"
6004   if (! TARGET_ARCH64)
6005     {
6006       if (GET_CODE (operands[2]) == CONST_INT)
6007         FAIL;
6008       emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
6009       DONE;
6010     }
6013 (define_insn "*lshrdi3_sp64"
6014   [(set (match_operand:DI 0 "register_operand" "=r")
6015         (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6016                      (match_operand:SI 2 "arith_operand" "rI")))]
6017   "TARGET_ARCH64"
6018   {
6019     if (GET_CODE (operands[2]) == CONST_INT)
6020       operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6021     return "srlx\t%1, %2, %0";
6022   }
6023   [(set_attr "type" "shift")])
6025 ;; XXX
6026 (define_insn "lshrdi3_v8plus"
6027   [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6028         (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6029                      (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6030    (clobber (match_scratch:SI 3 "=X,X,&h"))]
6031   "TARGET_V8PLUS"
6032   "* return output_v8plus_shift (insn, operands, \"srlx\");"
6033   [(set_attr "type" "multi")
6034    (set_attr "length" "5,5,6")])
6036 (define_insn ""
6037   [(set (match_operand:SI 0 "register_operand" "=r")
6038         (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6039                                              (const_int 32)) 4)
6040                      (match_operand:SI 2 "small_int_operand" "I")))]
6041   "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6043   operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6044   return "srax\t%1, %2, %0";
6046   [(set_attr "type" "shift")])
6048 (define_insn ""
6049   [(set (match_operand:SI 0 "register_operand" "=r")
6050         (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6051                                              (const_int 32)) 4)
6052                      (match_operand:SI 2 "small_int_operand" "I")))]
6053   "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6055   operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6056   return "srlx\t%1, %2, %0";
6058   [(set_attr "type" "shift")])
6060 (define_insn ""
6061   [(set (match_operand:SI 0 "register_operand" "=r")
6062         (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6063                                              (match_operand:SI 2 "small_int_operand" "I")) 4)
6064                      (match_operand:SI 3 "small_int_operand" "I")))]
6065   "TARGET_ARCH64
6066    && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6067    && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6068    && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6070   operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6072   return "srax\t%1, %2, %0";
6074   [(set_attr "type" "shift")])
6076 (define_insn ""
6077   [(set (match_operand:SI 0 "register_operand" "=r")
6078         (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6079                                              (match_operand:SI 2 "small_int_operand" "I")) 4)
6080                      (match_operand:SI 3 "small_int_operand" "I")))]
6081   "TARGET_ARCH64
6082    && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6083    && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6084    && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6086   operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6088   return "srlx\t%1, %2, %0";
6090   [(set_attr "type" "shift")])
6093 ;; Unconditional and other jump instructions.
6095 (define_expand "jump"
6096   [(set (pc) (label_ref (match_operand 0 "" "")))]
6097   "")
6099 (define_insn "*jump_ubranch"
6100   [(set (pc) (label_ref (match_operand 0 "" "")))]
6101   "! TARGET_CBCOND"
6102   "* return output_ubranch (operands[0], insn);"
6103   [(set_attr "type" "uncond_branch")])
6105 (define_insn "*jump_cbcond"
6106   [(set (pc) (label_ref (match_operand 0 "" "")))]
6107   "TARGET_CBCOND"
6108   "* return output_ubranch (operands[0], insn);"
6109   [(set_attr "type" "uncond_cbcond")])
6111 (define_expand "tablejump"
6112   [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
6113               (use (label_ref (match_operand 1 "" "")))])]
6114   ""
6116   gcc_assert (GET_MODE (operands[0]) == CASE_VECTOR_MODE);
6118   /* In pic mode, our address differences are against the base of the
6119      table.  Add that base value back in; CSE ought to be able to combine
6120      the two address loads.  */
6121   if (flag_pic)
6122     {
6123       rtx tmp, tmp2;
6124       tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
6125       tmp2 = operands[0];
6126       if (CASE_VECTOR_MODE != Pmode)
6127         tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
6128       tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
6129       operands[0] = memory_address (Pmode, tmp);
6130     }
6133 (define_insn "*tablejump_sp32"
6134   [(set (pc) (match_operand:SI 0 "address_operand" "p"))
6135    (use (label_ref (match_operand 1 "" "")))]
6136   "! TARGET_ARCH64"
6137   "jmp\t%a0%#"
6138   [(set_attr "type" "uncond_branch")])
6140 (define_insn "*tablejump_sp64"
6141   [(set (pc) (match_operand:DI 0 "address_operand" "p"))
6142    (use (label_ref (match_operand 1 "" "")))]
6143   "TARGET_ARCH64"
6144   "jmp\t%a0%#"
6145   [(set_attr "type" "uncond_branch")])
6148 ;; Jump to subroutine instructions.
6150 (define_expand "call"
6151   ;; Note that this expression is not used for generating RTL.
6152   ;; All the RTL is generated explicitly below.
6153   [(call (match_operand 0 "call_operand" "")
6154          (match_operand 3 "" "i"))]
6155   ;; operands[2] is next_arg_register
6156   ;; operands[3] is struct_value_size_rtx.
6157   ""
6159   rtx fn_rtx;
6161   gcc_assert (MEM_P (operands[0]) && GET_MODE (operands[0]) == FUNCTION_MODE);
6163   gcc_assert (GET_CODE (operands[3]) == CONST_INT);
6165   if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
6166     {
6167       /* This is really a PIC sequence.  We want to represent
6168          it as a funny jump so its delay slots can be filled. 
6170          ??? But if this really *is* a CALL, will not it clobber the
6171          call-clobbered registers?  We lose this if it is a JUMP_INSN.
6172          Why cannot we have delay slots filled if it were a CALL?  */
6174       /* We accept negative sizes for untyped calls.  */
6175       if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6176         emit_jump_insn
6177           (gen_rtx_PARALLEL
6178            (VOIDmode,
6179             gen_rtvec (3,
6180                        gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6181                        operands[3],
6182                        gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6183       else
6184         emit_jump_insn
6185           (gen_rtx_PARALLEL
6186            (VOIDmode,
6187             gen_rtvec (2,
6188                        gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6189                        gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6190       goto finish_call;
6191     }
6193   fn_rtx = operands[0];
6195   /* We accept negative sizes for untyped calls.  */
6196   if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6197     sparc_emit_call_insn
6198       (gen_rtx_PARALLEL
6199        (VOIDmode,
6200         gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6201                    operands[3],
6202                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6203        XEXP (fn_rtx, 0));
6204   else
6205     sparc_emit_call_insn
6206       (gen_rtx_PARALLEL
6207        (VOIDmode,
6208         gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6209                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6210        XEXP (fn_rtx, 0));
6212  finish_call:
6214   DONE;
6217 ;; We can't use the same pattern for these two insns, because then registers
6218 ;; in the address may not be properly reloaded.
6220 (define_insn "*call_address_sp32"
6221   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6222          (match_operand 1 "" ""))
6223    (clobber (reg:SI O7_REG))]
6224   ;;- Do not use operand 1 for most machines.
6225   "! TARGET_ARCH64"
6226   "call\t%a0, %1%#"
6227   [(set_attr "type" "call")])
6229 (define_insn "*call_symbolic_sp32"
6230   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6231          (match_operand 1 "" ""))
6232    (clobber (reg:SI O7_REG))]
6233   ;;- Do not use operand 1 for most machines.
6234   "! TARGET_ARCH64"
6235   "call\t%a0, %1%#"
6236   [(set_attr "type" "call")])
6238 (define_insn "*call_address_sp64"
6239   [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
6240          (match_operand 1 "" ""))
6241    (clobber (reg:DI O7_REG))]
6242   ;;- Do not use operand 1 for most machines.
6243   "TARGET_ARCH64"
6244   "call\t%a0, %1%#"
6245   [(set_attr "type" "call")])
6247 (define_insn "*call_symbolic_sp64"
6248   [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6249          (match_operand 1 "" ""))
6250    (clobber (reg:DI O7_REG))]
6251   ;;- Do not use operand 1 for most machines.
6252   "TARGET_ARCH64"
6253   "call\t%a0, %1%#"
6254   [(set_attr "type" "call")])
6256 ;; This is a call that wants a structure value.
6257 ;; There is no such critter for v9 (??? we may need one anyway).
6258 (define_insn "*call_address_struct_value_sp32"
6259   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6260          (match_operand 1 "" ""))
6261    (match_operand 2 "immediate_operand" "")
6262    (clobber (reg:SI O7_REG))]
6263   ;;- Do not use operand 1 for most machines.
6264   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6266   operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6267   return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6269   [(set_attr "type" "call_no_delay_slot")
6270    (set_attr "length" "3")])
6272 ;; This is a call that wants a structure value.
6273 ;; There is no such critter for v9 (??? we may need one anyway).
6274 (define_insn "*call_symbolic_struct_value_sp32"
6275   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6276          (match_operand 1 "" ""))
6277    (match_operand 2 "immediate_operand" "")
6278    (clobber (reg:SI O7_REG))]
6279   ;;- Do not use operand 1 for most machines.
6280   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6282   operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6283   return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6285   [(set_attr "type" "call_no_delay_slot")
6286    (set_attr "length" "3")])
6288 ;; This is a call that may want a structure value.  This is used for
6289 ;; untyped_calls.
6290 (define_insn "*call_address_untyped_struct_value_sp32"
6291   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6292          (match_operand 1 "" ""))
6293    (match_operand 2 "immediate_operand" "")
6294    (clobber (reg:SI O7_REG))]
6295   ;;- Do not use operand 1 for most machines.
6296   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6297   "call\t%a0, %1\n\t nop\n\tnop"
6298   [(set_attr "type" "call_no_delay_slot")
6299    (set_attr "length" "3")])
6301 ;; This is a call that may want a structure value.  This is used for
6302 ;; untyped_calls.
6303 (define_insn "*call_symbolic_untyped_struct_value_sp32"
6304   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6305          (match_operand 1 "" ""))
6306    (match_operand 2 "immediate_operand" "")
6307    (clobber (reg:SI O7_REG))]
6308   ;;- Do not use operand 1 for most machines.
6309   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6310   "call\t%a0, %1\n\t nop\n\tnop"
6311   [(set_attr "type" "call_no_delay_slot")
6312    (set_attr "length" "3")])
6314 (define_expand "call_value"
6315   ;; Note that this expression is not used for generating RTL.
6316   ;; All the RTL is generated explicitly below.
6317   [(set (match_operand 0 "register_operand" "=rf")
6318         (call (match_operand 1 "" "")
6319               (match_operand 4 "" "")))]
6320   ;; operand 2 is stack_size_rtx
6321   ;; operand 3 is next_arg_register
6322   ""
6324   rtx fn_rtx;
6325   rtvec vec;
6327   gcc_assert (MEM_P (operands[1]) && GET_MODE (operands[1]) == FUNCTION_MODE);
6329   fn_rtx = operands[1];
6331   vec = gen_rtvec (2,
6332                    gen_rtx_SET (VOIDmode, operands[0],
6333                                 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
6334                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
6336   sparc_emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec), XEXP (fn_rtx, 0));
6338   DONE;
6341 (define_insn "*call_value_address_sp32"
6342   [(set (match_operand 0 "" "=rf")
6343         (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
6344               (match_operand 2 "" "")))
6345    (clobber (reg:SI O7_REG))]
6346   ;;- Do not use operand 2 for most machines.
6347   "! TARGET_ARCH64"
6348   "call\t%a1, %2%#"
6349   [(set_attr "type" "call")])
6351 (define_insn "*call_value_symbolic_sp32"
6352   [(set (match_operand 0 "" "=rf")
6353         (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6354               (match_operand 2 "" "")))
6355    (clobber (reg:SI O7_REG))]
6356   ;;- Do not use operand 2 for most machines.
6357   "! TARGET_ARCH64"
6358   "call\t%a1, %2%#"
6359   [(set_attr "type" "call")])
6361 (define_insn "*call_value_address_sp64"
6362   [(set (match_operand 0 "" "")
6363         (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
6364               (match_operand 2 "" "")))
6365    (clobber (reg:DI O7_REG))]
6366   ;;- Do not use operand 2 for most machines.
6367   "TARGET_ARCH64"
6368   "call\t%a1, %2%#"
6369   [(set_attr "type" "call")])
6371 (define_insn "*call_value_symbolic_sp64"
6372   [(set (match_operand 0 "" "")
6373         (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6374               (match_operand 2 "" "")))
6375    (clobber (reg:DI O7_REG))]
6376   ;;- Do not use operand 2 for most machines.
6377   "TARGET_ARCH64"
6378   "call\t%a1, %2%#"
6379   [(set_attr "type" "call")])
6381 (define_expand "untyped_call"
6382   [(parallel [(call (match_operand 0 "" "")
6383                     (const_int 0))
6384               (match_operand:BLK 1 "memory_operand" "")
6385               (match_operand 2 "" "")])]
6386   ""
6388   rtx valreg1 = gen_rtx_REG (DImode, 8);
6389   rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6390   rtx result = operands[1];
6392   /* Pass constm1 to indicate that it may expect a structure value, but
6393      we don't know what size it is.  */
6394   emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
6396   /* Save the function value registers.  */
6397   emit_move_insn (adjust_address (result, DImode, 0), valreg1);
6398   emit_move_insn (adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8),
6399                                   valreg2);
6401   /* The optimizer does not know that the call sets the function value
6402      registers we stored in the result block.  We avoid problems by
6403      claiming that all hard registers are used and clobbered at this
6404      point.  */
6405   emit_insn (gen_blockage ());
6407   DONE;
6410 ;;  Tail call instructions.
6412 (define_expand "sibcall"
6413   [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
6414               (return)])]
6415   ""
6416   "")
6418 (define_insn "*sibcall_symbolic_sp32"
6419   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6420          (match_operand 1 "" ""))
6421    (return)]
6422   "! TARGET_ARCH64"
6423   "* return output_sibcall(insn, operands[0]);"
6424   [(set_attr "type" "sibcall")])
6426 (define_insn "*sibcall_symbolic_sp64"
6427   [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6428          (match_operand 1 "" ""))
6429    (return)]
6430   "TARGET_ARCH64"
6431   "* return output_sibcall(insn, operands[0]);"
6432   [(set_attr "type" "sibcall")])
6434 (define_expand "sibcall_value"
6435   [(parallel [(set (match_operand 0 "register_operand" "=rf")
6436                 (call (match_operand 1 "" "") (const_int 0)))
6437               (return)])]
6438   ""
6439   "")
6441 (define_insn "*sibcall_value_symbolic_sp32"
6442   [(set (match_operand 0 "" "=rf")
6443         (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6444               (match_operand 2 "" "")))
6445    (return)]
6446   "! TARGET_ARCH64"
6447   "* return output_sibcall(insn, operands[1]);"
6448   [(set_attr "type" "sibcall")])
6450 (define_insn "*sibcall_value_symbolic_sp64"
6451   [(set (match_operand 0 "" "")
6452         (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6453               (match_operand 2 "" "")))
6454    (return)]
6455   "TARGET_ARCH64"
6456   "* return output_sibcall(insn, operands[1]);"
6457   [(set_attr "type" "sibcall")])
6460 ;; Special instructions.
6462 (define_expand "prologue"
6463   [(const_int 0)]
6464   ""
6466   if (TARGET_FLAT)
6467     sparc_flat_expand_prologue ();
6468   else
6469     sparc_expand_prologue ();
6470   DONE;
6473 ;; The "register window save" insn is modelled as follows.  The dwarf2
6474 ;; information is manually added in emit_window_save.
6476 (define_insn "window_save"
6477   [(unspec_volatile
6478         [(match_operand 0 "arith_operand" "rI")]
6479         UNSPECV_SAVEW)]
6480   "!TARGET_FLAT"
6481   "save\t%%sp, %0, %%sp"
6482   [(set_attr "type" "savew")])
6484 (define_expand "epilogue"
6485   [(return)]
6486   ""
6488   if (TARGET_FLAT)
6489     sparc_flat_expand_epilogue (false);
6490   else
6491     sparc_expand_epilogue (false);
6494 (define_expand "sibcall_epilogue"
6495   [(return)]
6496   ""
6498   if (TARGET_FLAT)
6499     sparc_flat_expand_epilogue (false);
6500   else
6501     sparc_expand_epilogue (false);
6502   DONE;
6505 (define_expand "eh_return"
6506   [(use (match_operand 0 "general_operand" ""))]
6507   ""
6509   emit_move_insn (gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM), operands[0]);
6510   emit_jump_insn (gen_eh_return_internal ());
6511   emit_barrier ();
6512   DONE;
6515 (define_insn_and_split "eh_return_internal"
6516   [(eh_return)]
6517   ""
6518   "#"
6519   "epilogue_completed"
6520   [(return)]
6522   if (TARGET_FLAT)
6523     sparc_flat_expand_epilogue (true);
6524   else
6525     sparc_expand_epilogue (true);
6528 (define_expand "return"
6529   [(return)]
6530   "sparc_can_use_return_insn_p ()"
6531   "")
6533 (define_insn "*return_internal"
6534   [(return)]
6535   ""
6536   "* return output_return (insn);"
6537   [(set_attr "type" "return")
6538    (set (attr "length")
6539         (cond [(eq_attr "calls_eh_return" "true")
6540                  (if_then_else (eq_attr "delayed_branch" "true")
6541                                 (if_then_else (ior (eq_attr "isa" "v9")
6542                                                    (eq_attr "flat" "true"))
6543                                         (const_int 2)
6544                                         (const_int 3))
6545                                 (if_then_else (eq_attr "flat" "true")
6546                                         (const_int 3)
6547                                         (const_int 4)))
6548                (ior (eq_attr "leaf_function" "true") (eq_attr "flat" "true"))
6549                  (if_then_else (eq_attr "empty_delay_slot" "true")
6550                                (const_int 2)
6551                                (const_int 1))
6552                (eq_attr "empty_delay_slot" "true")
6553                  (if_then_else (eq_attr "delayed_branch" "true")
6554                                (const_int 2)
6555                                (const_int 3))
6556               ] (const_int 1)))])
6558 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
6559 ;; all of memory.  This blocks insns from being moved across this point.
6561 (define_insn "blockage"
6562   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
6563   ""
6564   ""
6565   [(set_attr "length" "0")])
6567 ;; Do not schedule instructions accessing memory before this point.
6569 (define_expand "frame_blockage"
6570   [(set (match_dup 0)
6571         (unspec:BLK [(match_dup 1)] UNSPEC_FRAME_BLOCKAGE))]
6572   ""
6574   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
6575   MEM_VOLATILE_P (operands[0]) = 1;
6576   operands[1] = stack_pointer_rtx;
6579 (define_insn "*frame_blockage<P:mode>"
6580   [(set (match_operand:BLK 0 "" "")
6581         (unspec:BLK [(match_operand:P 1 "" "")] UNSPEC_FRAME_BLOCKAGE))]
6582   ""
6583   ""
6584   [(set_attr "length" "0")])
6586 (define_expand "probe_stack"
6587   [(set (match_operand 0 "memory_operand" "") (const_int 0))]
6588   ""
6590   operands[0]
6591     = adjust_address (operands[0], GET_MODE (operands[0]), SPARC_STACK_BIAS);
6594 (define_insn "probe_stack_range<P:mode>"
6595   [(set (match_operand:P 0 "register_operand" "=r")
6596         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
6597                             (match_operand:P 2 "register_operand" "r")]
6598                             UNSPECV_PROBE_STACK_RANGE))]
6599   ""
6600   "* return output_probe_stack_range (operands[0], operands[2]);"
6601   [(set_attr "type" "multi")])
6603 ;; Prepare to return any type including a structure value.
6605 (define_expand "untyped_return"
6606   [(match_operand:BLK 0 "memory_operand" "")
6607    (match_operand 1 "" "")]
6608   ""
6610   rtx valreg1 = gen_rtx_REG (DImode, 24);
6611   rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6612   rtx result = operands[0];
6614   if (! TARGET_ARCH64)
6615     {
6616       rtx rtnreg = gen_rtx_REG (SImode, RETURN_ADDR_REGNUM);
6617       rtx value = gen_reg_rtx (SImode);
6619       /* Fetch the instruction where we will return to and see if it's an unimp
6620          instruction (the most significant 10 bits will be zero).  If so,
6621          update the return address to skip the unimp instruction.  */
6622       emit_move_insn (value,
6623                       gen_rtx_MEM (SImode, plus_constant (SImode, rtnreg, 8)));
6624       emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
6625       emit_insn (gen_update_return (rtnreg, value));
6626     }
6628   /* Reload the function value registers.  */
6629   emit_move_insn (valreg1, adjust_address (result, DImode, 0));
6630   emit_move_insn (valreg2,
6631                   adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
6633   /* Put USE insns before the return.  */
6634   emit_use (valreg1);
6635   emit_use (valreg2);
6637   /* Construct the return.  */
6638   expand_naked_return ();
6640   DONE;
6643 ;; Adjust the return address conditionally. If the value of op1 is equal
6644 ;; to all zero then adjust the return address i.e. op0 = op0 + 4.
6645 ;; This is technically *half* the check required by the 32-bit SPARC
6646 ;; psABI. This check only ensures that an "unimp" insn was written by
6647 ;; the caller, but doesn't check to see if the expected size matches
6648 ;; (this is encoded in the 12 lower bits). This check is obsolete and
6649 ;; only used by the above code "untyped_return".
6651 (define_insn "update_return"
6652   [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
6653                (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
6654   "! TARGET_ARCH64"
6656   if (flag_delayed_branch)
6657     return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
6658   else
6659     return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
6661   [(set (attr "type") (const_string "multi"))
6662    (set (attr "length")
6663         (if_then_else (eq_attr "delayed_branch" "true")
6664                       (const_int 3)
6665                       (const_int 4)))])
6667 (define_insn "nop"
6668   [(const_int 0)]
6669   ""
6670   "nop")
6672 (define_expand "indirect_jump"
6673   [(set (pc) (match_operand 0 "address_operand" "p"))]
6674   ""
6675   "")
6677 (define_insn "*branch_sp32"
6678   [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
6679   "! TARGET_ARCH64"
6680  "jmp\t%a0%#"
6681  [(set_attr "type" "uncond_branch")])
6683 (define_insn "*branch_sp64"
6684   [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
6685   "TARGET_ARCH64"
6686   "jmp\t%a0%#"
6687   [(set_attr "type" "uncond_branch")])
6689 (define_expand "save_stack_nonlocal"
6690   [(set (match_operand 0 "memory_operand" "")
6691         (match_operand 1 "register_operand" ""))
6692    (set (match_dup 2) (match_dup 3))]
6693   ""
6695   operands[0] = adjust_address_nv (operands[0], Pmode, 0);
6696   operands[2] = adjust_address_nv (operands[0], Pmode, GET_MODE_SIZE (Pmode));
6697   operands[3] = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
6700 (define_expand "restore_stack_nonlocal"
6701   [(set (match_operand 0 "register_operand" "")
6702         (match_operand 1 "memory_operand" ""))]
6703   ""
6705   operands[1] = adjust_address_nv (operands[1], Pmode, 0);
6708 (define_expand "nonlocal_goto"
6709   [(match_operand 0 "general_operand" "")
6710    (match_operand 1 "general_operand" "")
6711    (match_operand 2 "memory_operand" "")
6712    (match_operand 3 "memory_operand" "")]
6713   ""
6715   rtx i7 = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
6716   rtx r_label = copy_to_reg (operands[1]);
6717   rtx r_sp = adjust_address_nv (operands[2], Pmode, 0);
6718   rtx r_fp = operands[3];
6719   rtx r_i7 = adjust_address_nv (operands[2], Pmode, GET_MODE_SIZE (Pmode));
6721   /* We need to flush all the register windows so that their contents will
6722      be re-synchronized by the restore insn of the target function.  */
6723   if (!TARGET_FLAT)
6724     emit_insn (gen_flush_register_windows ());
6726   emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
6727   emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
6729   /* Restore frame pointer for containing function.  */
6730   emit_move_insn (hard_frame_pointer_rtx, r_fp);
6731   emit_stack_restore (SAVE_NONLOCAL, r_sp);
6732   emit_move_insn (i7, r_i7);
6734   /* USE of hard_frame_pointer_rtx added for consistency;
6735      not clear if really needed.  */
6736   emit_use (hard_frame_pointer_rtx);
6737   emit_use (stack_pointer_rtx);
6738   emit_use (i7);
6740   emit_jump_insn (gen_indirect_jump (r_label));
6741   emit_barrier ();
6742   DONE;
6745 (define_expand "builtin_setjmp_receiver"
6746   [(label_ref (match_operand 0 "" ""))]
6747   "flag_pic"
6749   load_got_register ();
6750   DONE;
6753 ;; Special insn to flush register windows.
6755 (define_insn "flush_register_windows"
6756   [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
6757   ""
6758   { return TARGET_V9 ? "flushw" : "ta\t3"; }
6759   [(set_attr "type" "flushw")])
6761 ;; Special pattern for the FLUSH instruction.
6763 (define_insn "flush<P:mode>"
6764   [(unspec_volatile [(match_operand:P 0 "memory_operand" "m")] UNSPECV_FLUSH)]
6765   ""
6766   { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
6767   [(set_attr "type" "iflush")])
6769 ;; Special insns to load and store the 32-bit FP Status Register.
6771 (define_insn "ldfsr"
6772   [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_LDFSR)]
6773   "TARGET_FPU"
6774   "ld\t%0, %%fsr"
6775   [(set_attr "type" "load")])
6777 (define_insn "stfsr"
6778   [(set (match_operand:SI 0 "memory_operand" "=m")
6779         (unspec_volatile:SI [(const_int 0)] UNSPECV_STFSR))]
6780   "TARGET_FPU"
6781   "st\t%%fsr, %0"
6782   [(set_attr "type" "store")])
6785 ;; Find first set instructions.
6787 ;; The scan instruction searches from the most significant bit while ffs
6788 ;; searches from the least significant bit.  The bit index and treatment of
6789 ;; zero also differ.  It takes at least 7 instructions to get the proper
6790 ;; result.  Here is an obvious 8 instruction sequence.
6792 ;; XXX
6793 (define_insn "ffssi2"
6794   [(set (match_operand:SI 0 "register_operand" "=&r")
6795         (ffs:SI (match_operand:SI 1 "register_operand" "r")))
6796    (clobber (match_scratch:SI 2 "=&r"))]
6797   "TARGET_SPARCLITE || TARGET_SPARCLET"
6799   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";
6801   [(set_attr "type" "multi")
6802    (set_attr "length" "8")])
6804 (define_expand "popcountdi2"
6805   [(set (match_operand:DI 0 "register_operand" "")
6806         (popcount:DI (match_operand:DI 1 "register_operand" "")))]
6807   "TARGET_POPC"
6809   if (! TARGET_ARCH64)
6810     {
6811       emit_insn (gen_popcountdi_v8plus (operands[0], operands[1]));
6812       DONE;
6813     }
6816 (define_insn "*popcountdi_sp64"
6817   [(set (match_operand:DI 0 "register_operand" "=r")
6818         (popcount:DI (match_operand:DI 1 "register_operand" "r")))]
6819   "TARGET_POPC && TARGET_ARCH64"
6820   "popc\t%1, %0")
6822 (define_insn "popcountdi_v8plus"
6823   [(set (match_operand:DI 0 "register_operand" "=r")
6824         (popcount:DI (match_operand:DI 1 "register_operand" "r")))
6825    (clobber (match_scratch:SI 2 "=&h"))]
6826   "TARGET_POPC && ! TARGET_ARCH64"
6828   if (sparc_check_64 (operands[1], insn) <= 0)
6829     output_asm_insn ("srl\t%L1, 0, %L1", operands);
6830   return "sllx\t%H1, 32, %2\n\tor\t%L1, %2, %2\n\tpopc\t%2, %L0\n\tclr\t%H0";
6832   [(set_attr "type" "multi")
6833    (set_attr "length" "5")])
6835 (define_expand "popcountsi2"
6836   [(set (match_dup 2)
6837         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
6838    (set (match_operand:SI 0 "register_operand" "")
6839         (truncate:SI (popcount:DI (match_dup 2))))]
6840   "TARGET_POPC"
6842   if (! TARGET_ARCH64)
6843     {
6844       emit_insn (gen_popcountsi_v8plus (operands[0], operands[1]));
6845       DONE;
6846     }
6847   else
6848     operands[2] = gen_reg_rtx (DImode);
6851 (define_insn "*popcountsi_sp64"
6852   [(set (match_operand:SI 0 "register_operand" "=r")
6853         (truncate:SI
6854           (popcount:DI (match_operand:DI 1 "register_operand" "r"))))]
6855   "TARGET_POPC && TARGET_ARCH64"
6856   "popc\t%1, %0")
6858 (define_insn "popcountsi_v8plus"
6859   [(set (match_operand:SI 0 "register_operand" "=r")
6860         (popcount:SI (match_operand:SI 1 "register_operand" "r")))]
6861   "TARGET_POPC && ! TARGET_ARCH64"
6863   if (sparc_check_64 (operands[1], insn) <= 0)
6864     output_asm_insn ("srl\t%1, 0, %1", operands);
6865   return "popc\t%1, %0";
6867   [(set_attr "type" "multi")
6868    (set_attr "length" "2")])
6870 (define_expand "clzdi2"
6871   [(set (match_operand:DI 0 "register_operand" "")
6872         (clz:DI (match_operand:DI 1 "register_operand" "")))]
6873   "TARGET_VIS3"
6875   if (! TARGET_ARCH64)
6876     {
6877       emit_insn (gen_clzdi_v8plus (operands[0], operands[1]));
6878       DONE;
6879     }
6882 (define_insn "*clzdi_sp64"
6883   [(set (match_operand:DI 0 "register_operand" "=r")
6884         (clz:DI (match_operand:DI 1 "register_operand" "r")))]
6885   "TARGET_VIS3 && TARGET_ARCH64"
6886   "lzd\t%1, %0")
6888 (define_insn "clzdi_v8plus"
6889   [(set (match_operand:DI 0 "register_operand" "=r")
6890         (clz:DI (match_operand:DI 1 "register_operand" "r")))
6891    (clobber (match_scratch:SI 2 "=&h"))]
6892   "TARGET_VIS3 && ! TARGET_ARCH64"
6894   if (sparc_check_64 (operands[1], insn) <= 0)
6895     output_asm_insn ("srl\t%L1, 0, %L1", operands);
6896   return "sllx\t%H1, 32, %2\n\tor\t%L1, %2, %2\n\tlzd\t%2, %L0\n\tclr\t%H0";
6898   [(set_attr "type" "multi")
6899    (set_attr "length" "5")])
6901 (define_expand "clzsi2"
6902   [(set (match_dup 2)
6903         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
6904    (set (match_dup 3)
6905         (truncate:SI (clz:DI (match_dup 2))))
6906    (set (match_operand:SI 0 "register_operand" "")
6907         (minus:SI (match_dup 3) (const_int 32)))]
6908   "TARGET_VIS3"
6910   if (! TARGET_ARCH64)
6911     {
6912       emit_insn (gen_clzsi_v8plus (operands[0], operands[1]));
6913       DONE;
6914     }
6915   else
6916     {
6917       operands[2] = gen_reg_rtx (DImode);
6918       operands[3] = gen_reg_rtx (SImode);
6919     }
6922 (define_insn "*clzsi_sp64"
6923   [(set (match_operand:SI 0 "register_operand" "=r")
6924         (truncate:SI
6925           (clz:DI (match_operand:DI 1 "register_operand" "r"))))]
6926   "TARGET_VIS3 && TARGET_ARCH64"
6927   "lzd\t%1, %0")
6929 (define_insn "clzsi_v8plus"
6930   [(set (match_operand:SI 0 "register_operand" "=r")
6931         (clz:SI (match_operand:SI 1 "register_operand" "r")))]
6932   "TARGET_VIS3 && ! TARGET_ARCH64"
6934   if (sparc_check_64 (operands[1], insn) <= 0)
6935     output_asm_insn ("srl\t%1, 0, %1", operands);
6936   return "lzd\t%1, %0\n\tsub\t%0, 32, %0";
6938   [(set_attr "type" "multi")
6939    (set_attr "length" "3")])
6942 ;; Peepholes go at the end.
6944 ;; Optimize consecutive loads or stores into ldd and std when possible.
6945 ;; The conditions in which we do this are very restricted and are 
6946 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
6948 (define_peephole2
6949   [(set (match_operand:SI 0 "memory_operand" "")
6950       (const_int 0))
6951    (set (match_operand:SI 1 "memory_operand" "")
6952       (const_int 0))]
6953   "TARGET_V9
6954    && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
6955   [(set (match_dup 0) (const_int 0))]
6957   operands[0] = widen_mem_for_ldd_peep (operands[0], operands[1], DImode);
6960 (define_peephole2
6961   [(set (match_operand:SI 0 "memory_operand" "")
6962       (const_int 0))
6963    (set (match_operand:SI 1 "memory_operand" "")
6964       (const_int 0))]
6965   "TARGET_V9
6966    && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
6967   [(set (match_dup 1) (const_int 0))]
6969   operands[1] = widen_mem_for_ldd_peep (operands[1], operands[0], DImode);
6972 (define_peephole2
6973   [(set (match_operand:SI 0 "register_operand" "")
6974         (match_operand:SI 1 "memory_operand" ""))
6975    (set (match_operand:SI 2 "register_operand" "")
6976         (match_operand:SI 3 "memory_operand" ""))]
6977   "registers_ok_for_ldd_peep (operands[0], operands[2]) 
6978    && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])" 
6979   [(set (match_dup 0) (match_dup 1))]
6981   operands[1] = widen_mem_for_ldd_peep (operands[1], operands[3], DImode);
6982   operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
6985 (define_peephole2
6986   [(set (match_operand:SI 0 "memory_operand" "")
6987         (match_operand:SI 1 "register_operand" ""))
6988    (set (match_operand:SI 2 "memory_operand" "")
6989         (match_operand:SI 3 "register_operand" ""))]
6990   "registers_ok_for_ldd_peep (operands[1], operands[3]) 
6991    && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
6992   [(set (match_dup 0) (match_dup 1))]
6994   operands[0] = widen_mem_for_ldd_peep (operands[0], operands[2], DImode);
6995   operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));
6998 (define_peephole2
6999   [(set (match_operand:SF 0 "register_operand" "")
7000         (match_operand:SF 1 "memory_operand" ""))
7001    (set (match_operand:SF 2 "register_operand" "")
7002         (match_operand:SF 3 "memory_operand" ""))]
7003   "registers_ok_for_ldd_peep (operands[0], operands[2]) 
7004    && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
7005   [(set (match_dup 0) (match_dup 1))]
7007   operands[1] = widen_mem_for_ldd_peep (operands[1], operands[3], DFmode);
7008   operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));
7011 (define_peephole2
7012   [(set (match_operand:SF 0 "memory_operand" "")
7013         (match_operand:SF 1 "register_operand" ""))
7014    (set (match_operand:SF 2 "memory_operand" "")
7015         (match_operand:SF 3 "register_operand" ""))]
7016   "registers_ok_for_ldd_peep (operands[1], operands[3]) 
7017   && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7018   [(set (match_dup 0) (match_dup 1))]
7020   operands[0] = widen_mem_for_ldd_peep (operands[0], operands[2], DFmode);
7021   operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));
7024 (define_peephole2
7025   [(set (match_operand:SI 0 "register_operand" "")
7026         (match_operand:SI 1 "memory_operand" ""))
7027    (set (match_operand:SI 2 "register_operand" "")
7028         (match_operand:SI 3 "memory_operand" ""))]
7029   "registers_ok_for_ldd_peep (operands[2], operands[0]) 
7030   && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
7031   [(set (match_dup 2) (match_dup 3))]
7033   operands[3] = widen_mem_for_ldd_peep (operands[3], operands[1], DImode);
7034   operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));
7037 (define_peephole2
7038   [(set (match_operand:SI 0 "memory_operand" "")
7039         (match_operand:SI 1 "register_operand" ""))
7040    (set (match_operand:SI 2 "memory_operand" "")
7041         (match_operand:SI 3 "register_operand" ""))]
7042   "registers_ok_for_ldd_peep (operands[3], operands[1]) 
7043   && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)" 
7044   [(set (match_dup 2) (match_dup 3))]
7046   operands[2] = widen_mem_for_ldd_peep (operands[2],  operands[0], DImode);
7047   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
7050 (define_peephole2
7051   [(set (match_operand:SF 0 "register_operand" "")
7052         (match_operand:SF 1 "memory_operand" ""))
7053    (set (match_operand:SF 2 "register_operand" "")
7054         (match_operand:SF 3 "memory_operand" ""))]
7055   "registers_ok_for_ldd_peep (operands[2], operands[0]) 
7056   && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
7057   [(set (match_dup 2) (match_dup 3))]
7059   operands[3] = widen_mem_for_ldd_peep (operands[3], operands[1], DFmode);
7060   operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));
7063 (define_peephole2
7064   [(set (match_operand:SF 0 "memory_operand" "")
7065         (match_operand:SF 1 "register_operand" ""))
7066    (set (match_operand:SF 2 "memory_operand" "")
7067         (match_operand:SF 3 "register_operand" ""))]
7068   "registers_ok_for_ldd_peep (operands[3], operands[1]) 
7069   && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
7070   [(set (match_dup 2) (match_dup 3))]
7072   operands[2] = widen_mem_for_ldd_peep (operands[2], operands[0], DFmode);
7073   operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));
7076 ;; Optimize the case of following a reg-reg move with a test
7077 ;; of reg just moved.  Don't allow floating point regs for operand 0 or 1.
7078 ;; This can result from a float to fix conversion.
7080 (define_peephole2
7081   [(set (match_operand:SI 0 "register_operand" "")
7082         (match_operand:SI 1 "register_operand" ""))
7083    (set (reg:CC CC_REG)
7084         (compare:CC (match_operand:SI 2 "register_operand" "")
7085                     (const_int 0)))]
7086   "(rtx_equal_p (operands[2], operands[0])
7087     || rtx_equal_p (operands[2], operands[1]))
7088     && ! SPARC_FP_REG_P (REGNO (operands[0]))
7089     && ! SPARC_FP_REG_P (REGNO (operands[1]))"
7090   [(parallel [(set (match_dup 0) (match_dup 1))
7091               (set (reg:CC CC_REG)
7092                    (compare:CC (match_dup 1) (const_int 0)))])]
7093   "")
7095 (define_peephole2
7096   [(set (match_operand:DI 0 "register_operand" "")
7097         (match_operand:DI 1 "register_operand" ""))
7098    (set (reg:CCX CC_REG)
7099         (compare:CCX (match_operand:DI 2 "register_operand" "")
7100                     (const_int 0)))]
7101   "TARGET_ARCH64
7102    && (rtx_equal_p (operands[2], operands[0])
7103        || rtx_equal_p (operands[2], operands[1]))
7104    && ! SPARC_FP_REG_P (REGNO (operands[0]))
7105    && ! SPARC_FP_REG_P (REGNO (operands[1]))"
7106   [(parallel [(set (match_dup 0) (match_dup 1))
7107               (set (reg:CCX CC_REG)
7108                    (compare:CCX (match_dup 1) (const_int 0)))])]
7109   "")
7112 ;; Prefetch instructions.
7114 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
7115 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
7116 ;; ??? operations.  With DFA we might be able to model this, but it requires a lot of
7117 ;; ??? state.
7118 (define_expand "prefetch"
7119   [(match_operand 0 "address_operand" "")
7120    (match_operand 1 "const_int_operand" "")
7121    (match_operand 2 "const_int_operand" "")]
7122   "TARGET_V9"
7124   if (TARGET_ARCH64)
7125     emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
7126   else
7127     emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
7128   DONE;
7131 (define_insn "prefetch_64"
7132   [(prefetch (match_operand:DI 0 "address_operand" "p")
7133              (match_operand:DI 1 "const_int_operand" "n")
7134              (match_operand:DI 2 "const_int_operand" "n"))]
7135   ""
7137   static const char * const prefetch_instr[2][2] = {
7138     {
7139       "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7140       "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7141     },
7142     {
7143       "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7144       "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7145     }
7146   };
7147   int read_or_write = INTVAL (operands[1]);
7148   int locality = INTVAL (operands[2]);
7150   gcc_assert (read_or_write == 0 || read_or_write == 1);
7151   gcc_assert (locality >= 0 && locality < 4);
7152   return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7154   [(set_attr "type" "load")])
7156 (define_insn "prefetch_32"
7157   [(prefetch (match_operand:SI 0 "address_operand" "p")
7158              (match_operand:SI 1 "const_int_operand" "n")
7159              (match_operand:SI 2 "const_int_operand" "n"))]
7160   ""
7162   static const char * const prefetch_instr[2][2] = {
7163     {
7164       "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7165       "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7166     },
7167     {
7168       "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7169       "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7170     }
7171   };
7172   int read_or_write = INTVAL (operands[1]);
7173   int locality = INTVAL (operands[2]);
7175   gcc_assert (read_or_write == 0 || read_or_write == 1);
7176   gcc_assert (locality >= 0 && locality < 4);
7177   return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7179   [(set_attr "type" "load")])
7182 ;; Trap instructions.
7184 (define_insn "trap"
7185   [(trap_if (const_int 1) (const_int 5))]
7186   ""
7187   "ta\t5"
7188   [(set_attr "type" "trap")])
7190 (define_expand "ctrapsi4"
7191   [(trap_if (match_operator 0 "noov_compare_operator"
7192              [(match_operand:SI 1 "compare_operand" "")
7193               (match_operand:SI 2 "arith_operand" "")])
7194            (match_operand 3 "arith_operand"))]
7195   ""
7196   "operands[1] = gen_compare_reg (operands[0]);
7197    if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
7198      FAIL;
7199    operands[2] = const0_rtx;")
7201 (define_expand "ctrapdi4"
7202   [(trap_if (match_operator 0 "noov_compare_operator"
7203              [(match_operand:DI 1 "compare_operand" "")
7204               (match_operand:DI 2 "arith_operand" "")])
7205            (match_operand 3 "arith_operand"))]
7206   "TARGET_ARCH64"
7207   "operands[1] = gen_compare_reg (operands[0]);
7208    if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
7209      FAIL;
7210    operands[2] = const0_rtx;")
7213 (define_insn ""
7214   [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CC CC_REG) (const_int 0)])
7215             (match_operand:SI 1 "arith_operand" "rM"))]
7216   ""
7218   if (TARGET_V9)
7219     return "t%C0\t%%icc, %1";
7220   else
7221     return "t%C0\t%1";
7223   [(set_attr "type" "trap")])
7225 (define_insn ""
7226   [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CCX CC_REG) (const_int 0)])
7227             (match_operand:SI 1 "arith_operand" "rM"))]
7228   "TARGET_V9"
7229   "t%C0\t%%xcc, %1"
7230   [(set_attr "type" "trap")])
7233 ;; TLS support instructions.
7235 (define_insn "tgd_hi22"
7236   [(set (match_operand:SI 0 "register_operand" "=r")
7237         (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
7238                             UNSPEC_TLSGD)))]
7239   "TARGET_TLS"
7240   "sethi\\t%%tgd_hi22(%a1), %0")
7242 (define_insn "tgd_lo10"
7243   [(set (match_operand:SI 0 "register_operand" "=r")
7244         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7245                    (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
7246                               UNSPEC_TLSGD)))]
7247   "TARGET_TLS"
7248   "add\\t%1, %%tgd_lo10(%a2), %0")
7250 (define_insn "tgd_add32"
7251   [(set (match_operand:SI 0 "register_operand" "=r")
7252         (plus:SI (match_operand:SI 1 "register_operand" "r")
7253                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7254                              (match_operand 3 "tgd_symbolic_operand" "")]
7255                             UNSPEC_TLSGD)))]
7256   "TARGET_TLS && TARGET_ARCH32"
7257   "add\\t%1, %2, %0, %%tgd_add(%a3)")
7259 (define_insn "tgd_add64"
7260   [(set (match_operand:DI 0 "register_operand" "=r")
7261         (plus:DI (match_operand:DI 1 "register_operand" "r")
7262                  (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7263                              (match_operand 3 "tgd_symbolic_operand" "")]
7264                             UNSPEC_TLSGD)))]
7265   "TARGET_TLS && TARGET_ARCH64"
7266   "add\\t%1, %2, %0, %%tgd_add(%a3)")
7268 (define_insn "tgd_call32"
7269   [(set (match_operand 0 "register_operand" "=r")
7270         (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
7271                                   (match_operand 2 "tgd_symbolic_operand" "")]
7272                                  UNSPEC_TLSGD))
7273               (match_operand 3 "" "")))
7274    (clobber (reg:SI O7_REG))]
7275   "TARGET_TLS && TARGET_ARCH32"
7276   "call\t%a1, %%tgd_call(%a2)%#"
7277   [(set_attr "type" "call")])
7279 (define_insn "tgd_call64"
7280   [(set (match_operand 0 "register_operand" "=r")
7281         (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
7282                                   (match_operand 2 "tgd_symbolic_operand" "")]
7283                                  UNSPEC_TLSGD))
7284               (match_operand 3 "" "")))
7285    (clobber (reg:DI O7_REG))]
7286   "TARGET_TLS && TARGET_ARCH64"
7287   "call\t%a1, %%tgd_call(%a2)%#"
7288   [(set_attr "type" "call")])
7290 (define_insn "tldm_hi22"
7291   [(set (match_operand:SI 0 "register_operand" "=r")
7292         (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7293   "TARGET_TLS"
7294   "sethi\\t%%tldm_hi22(%&), %0")
7296 (define_insn "tldm_lo10"
7297   [(set (match_operand:SI 0 "register_operand" "=r")
7298         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7299                     (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7300   "TARGET_TLS"
7301   "add\\t%1, %%tldm_lo10(%&), %0")
7303 (define_insn "tldm_add32"
7304   [(set (match_operand:SI 0 "register_operand" "=r")
7305         (plus:SI (match_operand:SI 1 "register_operand" "r")
7306                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
7307                             UNSPEC_TLSLDM)))]
7308   "TARGET_TLS && TARGET_ARCH32"
7309   "add\\t%1, %2, %0, %%tldm_add(%&)")
7311 (define_insn "tldm_add64"
7312   [(set (match_operand:DI 0 "register_operand" "=r")
7313         (plus:DI (match_operand:DI 1 "register_operand" "r")
7314                  (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
7315                             UNSPEC_TLSLDM)))]
7316   "TARGET_TLS && TARGET_ARCH64"
7317   "add\\t%1, %2, %0, %%tldm_add(%&)")
7319 (define_insn "tldm_call32"
7320   [(set (match_operand 0 "register_operand" "=r")
7321         (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
7322                                  UNSPEC_TLSLDM))
7323               (match_operand 2 "" "")))
7324    (clobber (reg:SI O7_REG))]
7325   "TARGET_TLS && TARGET_ARCH32"
7326   "call\t%a1, %%tldm_call(%&)%#"
7327   [(set_attr "type" "call")])
7329 (define_insn "tldm_call64"
7330   [(set (match_operand 0 "register_operand" "=r")
7331         (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
7332                                  UNSPEC_TLSLDM))
7333               (match_operand 2 "" "")))
7334    (clobber (reg:DI O7_REG))]
7335   "TARGET_TLS && TARGET_ARCH64"
7336   "call\t%a1, %%tldm_call(%&)%#"
7337   [(set_attr "type" "call")])
7339 (define_insn "tldo_hix22"
7340   [(set (match_operand:SI 0 "register_operand" "=r")
7341         (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
7342                             UNSPEC_TLSLDO)))]
7343   "TARGET_TLS"
7344   "sethi\\t%%tldo_hix22(%a1), %0")
7346 (define_insn "tldo_lox10"
7347   [(set (match_operand:SI 0 "register_operand" "=r")
7348         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7349                    (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
7350                               UNSPEC_TLSLDO)))]
7351   "TARGET_TLS"
7352   "xor\\t%1, %%tldo_lox10(%a2), %0")
7354 (define_insn "tldo_add32"
7355   [(set (match_operand:SI 0 "register_operand" "=r")
7356         (plus:SI (match_operand:SI 1 "register_operand" "r")
7357                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7358                              (match_operand 3 "tld_symbolic_operand" "")]
7359                             UNSPEC_TLSLDO)))]
7360   "TARGET_TLS && TARGET_ARCH32"
7361   "add\\t%1, %2, %0, %%tldo_add(%a3)")
7363 (define_insn "tldo_add64"
7364   [(set (match_operand:DI 0 "register_operand" "=r")
7365         (plus:DI (match_operand:DI 1 "register_operand" "r")
7366                  (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7367                              (match_operand 3 "tld_symbolic_operand" "")]
7368                             UNSPEC_TLSLDO)))]
7369   "TARGET_TLS && TARGET_ARCH64"
7370   "add\\t%1, %2, %0, %%tldo_add(%a3)")
7372 (define_insn "tie_hi22"
7373   [(set (match_operand:SI 0 "register_operand" "=r")
7374         (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
7375                             UNSPEC_TLSIE)))]
7376   "TARGET_TLS"
7377   "sethi\\t%%tie_hi22(%a1), %0")
7379 (define_insn "tie_lo10"
7380   [(set (match_operand:SI 0 "register_operand" "=r")
7381         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7382                    (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
7383                               UNSPEC_TLSIE)))]
7384   "TARGET_TLS"
7385   "add\\t%1, %%tie_lo10(%a2), %0")
7387 (define_insn "tie_ld32"
7388   [(set (match_operand:SI 0 "register_operand" "=r")
7389         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
7390                     (match_operand:SI 2 "register_operand" "r")
7391                     (match_operand 3 "tie_symbolic_operand" "")]
7392                    UNSPEC_TLSIE))]
7393   "TARGET_TLS && TARGET_ARCH32"
7394   "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
7395   [(set_attr "type" "load")])
7397 (define_insn "tie_ld64"
7398   [(set (match_operand:DI 0 "register_operand" "=r")
7399         (unspec:DI [(match_operand:DI 1 "register_operand" "r")
7400                     (match_operand:SI 2 "register_operand" "r")
7401                     (match_operand 3 "tie_symbolic_operand" "")]
7402                    UNSPEC_TLSIE))]
7403   "TARGET_TLS && TARGET_ARCH64"
7404   "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
7405   [(set_attr "type" "load")])
7407 (define_insn "tie_add32"
7408   [(set (match_operand:SI 0 "register_operand" "=r")
7409         (plus:SI (match_operand:SI 1 "register_operand" "r")
7410                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7411                              (match_operand 3 "tie_symbolic_operand" "")]
7412                             UNSPEC_TLSIE)))]
7413   "TARGET_SUN_TLS && TARGET_ARCH32"
7414   "add\\t%1, %2, %0, %%tie_add(%a3)")
7416 (define_insn "tie_add64"
7417   [(set (match_operand:DI 0 "register_operand" "=r")
7418         (plus:DI (match_operand:DI 1 "register_operand" "r")
7419                  (unspec:DI [(match_operand:DI 2 "register_operand" "r")
7420                              (match_operand 3 "tie_symbolic_operand" "")]
7421                             UNSPEC_TLSIE)))]
7422   "TARGET_SUN_TLS && TARGET_ARCH64"
7423   "add\\t%1, %2, %0, %%tie_add(%a3)")
7425 (define_insn "tle_hix22_sp32"
7426   [(set (match_operand:SI 0 "register_operand" "=r")
7427         (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
7428                             UNSPEC_TLSLE)))]
7429   "TARGET_TLS && TARGET_ARCH32"
7430   "sethi\\t%%tle_hix22(%a1), %0")
7432 (define_insn "tle_lox10_sp32"
7433   [(set (match_operand:SI 0 "register_operand" "=r")
7434         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7435                    (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
7436                               UNSPEC_TLSLE)))]
7437   "TARGET_TLS && TARGET_ARCH32"
7438   "xor\\t%1, %%tle_lox10(%a2), %0")
7440 (define_insn "tle_hix22_sp64"
7441   [(set (match_operand:DI 0 "register_operand" "=r")
7442         (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
7443                             UNSPEC_TLSLE)))]
7444   "TARGET_TLS && TARGET_ARCH64"
7445   "sethi\\t%%tle_hix22(%a1), %0")
7447 (define_insn "tle_lox10_sp64"
7448   [(set (match_operand:DI 0 "register_operand" "=r")
7449         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
7450                    (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
7451                               UNSPEC_TLSLE)))]
7452   "TARGET_TLS && TARGET_ARCH64"
7453   "xor\\t%1, %%tle_lox10(%a2), %0")
7455 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
7456 (define_insn "*tldo_ldub_sp32"
7457   [(set (match_operand:QI 0 "register_operand" "=r")
7458         (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7459                                      (match_operand 3 "tld_symbolic_operand" "")]
7460                                     UNSPEC_TLSLDO)
7461                          (match_operand:SI 1 "register_operand" "r"))))]
7462   "TARGET_TLS && TARGET_ARCH32"
7463   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7464   [(set_attr "type" "load")
7465    (set_attr "us3load_type" "3cycle")])
7467 (define_insn "*tldo_ldub1_sp32"
7468   [(set (match_operand:HI 0 "register_operand" "=r")
7469         (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7470                                                      (match_operand 3 "tld_symbolic_operand" "")]
7471                                                     UNSPEC_TLSLDO)
7472                                          (match_operand:SI 1 "register_operand" "r")))))]
7473   "TARGET_TLS && TARGET_ARCH32"
7474   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7475   [(set_attr "type" "load")
7476    (set_attr "us3load_type" "3cycle")])
7478 (define_insn "*tldo_ldub2_sp32"
7479   [(set (match_operand:SI 0 "register_operand" "=r")
7480         (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7481                                                      (match_operand 3 "tld_symbolic_operand" "")]
7482                                                     UNSPEC_TLSLDO)
7483                                          (match_operand:SI 1 "register_operand" "r")))))]
7484   "TARGET_TLS && TARGET_ARCH32"
7485   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7486   [(set_attr "type" "load")
7487    (set_attr "us3load_type" "3cycle")])
7489 (define_insn "*tldo_ldsb1_sp32"
7490   [(set (match_operand:HI 0 "register_operand" "=r")
7491         (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7492                                                      (match_operand 3 "tld_symbolic_operand" "")]
7493                                                     UNSPEC_TLSLDO)
7494                                          (match_operand:SI 1 "register_operand" "r")))))]
7495   "TARGET_TLS && TARGET_ARCH32"
7496   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7497   [(set_attr "type" "sload")
7498    (set_attr "us3load_type" "3cycle")])
7500 (define_insn "*tldo_ldsb2_sp32"
7501   [(set (match_operand:SI 0 "register_operand" "=r")
7502         (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7503                                                      (match_operand 3 "tld_symbolic_operand" "")]
7504                                                     UNSPEC_TLSLDO)
7505                                          (match_operand:SI 1 "register_operand" "r")))))]
7506   "TARGET_TLS && TARGET_ARCH32"
7507   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7508   [(set_attr "type" "sload")
7509    (set_attr "us3load_type" "3cycle")])
7511 (define_insn "*tldo_ldub_sp64"
7512   [(set (match_operand:QI 0 "register_operand" "=r")
7513         (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7514                                      (match_operand 3 "tld_symbolic_operand" "")]
7515                                     UNSPEC_TLSLDO)
7516                          (match_operand:DI 1 "register_operand" "r"))))]
7517   "TARGET_TLS && TARGET_ARCH64"
7518   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7519   [(set_attr "type" "load")
7520    (set_attr "us3load_type" "3cycle")])
7522 (define_insn "*tldo_ldub1_sp64"
7523   [(set (match_operand:HI 0 "register_operand" "=r")
7524         (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7525                                                      (match_operand 3 "tld_symbolic_operand" "")]
7526                                                     UNSPEC_TLSLDO)
7527                                          (match_operand:DI 1 "register_operand" "r")))))]
7528   "TARGET_TLS && TARGET_ARCH64"
7529   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7530   [(set_attr "type" "load")
7531    (set_attr "us3load_type" "3cycle")])
7533 (define_insn "*tldo_ldub2_sp64"
7534   [(set (match_operand:SI 0 "register_operand" "=r")
7535         (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7536                                                      (match_operand 3 "tld_symbolic_operand" "")]
7537                                                     UNSPEC_TLSLDO)
7538                                          (match_operand:DI 1 "register_operand" "r")))))]
7539   "TARGET_TLS && TARGET_ARCH64"
7540   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7541   [(set_attr "type" "load")
7542    (set_attr "us3load_type" "3cycle")])
7544 (define_insn "*tldo_ldub3_sp64"
7545   [(set (match_operand:DI 0 "register_operand" "=r")
7546         (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7547                                                      (match_operand 3 "tld_symbolic_operand" "")]
7548                                                     UNSPEC_TLSLDO)
7549                                          (match_operand:DI 1 "register_operand" "r")))))]
7550   "TARGET_TLS && TARGET_ARCH64"
7551   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7552   [(set_attr "type" "load")
7553    (set_attr "us3load_type" "3cycle")])
7555 (define_insn "*tldo_ldsb1_sp64"
7556   [(set (match_operand:HI 0 "register_operand" "=r")
7557         (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7558                                                      (match_operand 3 "tld_symbolic_operand" "")]
7559                                                     UNSPEC_TLSLDO)
7560                                          (match_operand:DI 1 "register_operand" "r")))))]
7561   "TARGET_TLS && TARGET_ARCH64"
7562   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7563   [(set_attr "type" "sload")
7564    (set_attr "us3load_type" "3cycle")])
7566 (define_insn "*tldo_ldsb2_sp64"
7567   [(set (match_operand:SI 0 "register_operand" "=r")
7568         (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7569                                                      (match_operand 3 "tld_symbolic_operand" "")]
7570                                                     UNSPEC_TLSLDO)
7571                                          (match_operand:DI 1 "register_operand" "r")))))]
7572   "TARGET_TLS && TARGET_ARCH64"
7573   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7574   [(set_attr "type" "sload")
7575    (set_attr "us3load_type" "3cycle")])
7577 (define_insn "*tldo_ldsb3_sp64"
7578   [(set (match_operand:DI 0 "register_operand" "=r")
7579         (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7580                                                      (match_operand 3 "tld_symbolic_operand" "")]
7581                                                     UNSPEC_TLSLDO)
7582                                          (match_operand:DI 1 "register_operand" "r")))))]
7583   "TARGET_TLS && TARGET_ARCH64"
7584   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7585   [(set_attr "type" "sload")
7586    (set_attr "us3load_type" "3cycle")])
7588 (define_insn "*tldo_lduh_sp32"
7589   [(set (match_operand:HI 0 "register_operand" "=r")
7590         (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7591                                      (match_operand 3 "tld_symbolic_operand" "")]
7592                                     UNSPEC_TLSLDO)
7593                          (match_operand:SI 1 "register_operand" "r"))))]
7594   "TARGET_TLS && TARGET_ARCH32"
7595   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7596   [(set_attr "type" "load")
7597    (set_attr "us3load_type" "3cycle")])
7599 (define_insn "*tldo_lduh1_sp32"
7600   [(set (match_operand:SI 0 "register_operand" "=r")
7601         (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7602                                                      (match_operand 3 "tld_symbolic_operand" "")]
7603                                                     UNSPEC_TLSLDO)
7604                                          (match_operand:SI 1 "register_operand" "r")))))]
7605   "TARGET_TLS && TARGET_ARCH32"
7606   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7607   [(set_attr "type" "load")
7608    (set_attr "us3load_type" "3cycle")])
7610 (define_insn "*tldo_ldsh1_sp32"
7611   [(set (match_operand:SI 0 "register_operand" "=r")
7612         (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7613                                                      (match_operand 3 "tld_symbolic_operand" "")]
7614                                                     UNSPEC_TLSLDO)
7615                                          (match_operand:SI 1 "register_operand" "r")))))]
7616   "TARGET_TLS && TARGET_ARCH32"
7617   "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7618   [(set_attr "type" "sload")
7619    (set_attr "us3load_type" "3cycle")])
7621 (define_insn "*tldo_lduh_sp64"
7622   [(set (match_operand:HI 0 "register_operand" "=r")
7623         (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7624                                      (match_operand 3 "tld_symbolic_operand" "")]
7625                                     UNSPEC_TLSLDO)
7626                          (match_operand:DI 1 "register_operand" "r"))))]
7627   "TARGET_TLS && TARGET_ARCH64"
7628   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7629   [(set_attr "type" "load")
7630    (set_attr "us3load_type" "3cycle")])
7632 (define_insn "*tldo_lduh1_sp64"
7633   [(set (match_operand:SI 0 "register_operand" "=r")
7634         (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7635                                                      (match_operand 3 "tld_symbolic_operand" "")]
7636                                                     UNSPEC_TLSLDO)
7637                                          (match_operand:DI 1 "register_operand" "r")))))]
7638   "TARGET_TLS && TARGET_ARCH64"
7639   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7640   [(set_attr "type" "load")
7641    (set_attr "us3load_type" "3cycle")])
7643 (define_insn "*tldo_lduh2_sp64"
7644   [(set (match_operand:DI 0 "register_operand" "=r")
7645         (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7646                                                      (match_operand 3 "tld_symbolic_operand" "")]
7647                                                     UNSPEC_TLSLDO)
7648                                          (match_operand:DI 1 "register_operand" "r")))))]
7649   "TARGET_TLS && TARGET_ARCH64"
7650   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7651   [(set_attr "type" "load")
7652    (set_attr "us3load_type" "3cycle")])
7654 (define_insn "*tldo_ldsh1_sp64"
7655   [(set (match_operand:SI 0 "register_operand" "=r")
7656         (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7657                                                      (match_operand 3 "tld_symbolic_operand" "")]
7658                                                     UNSPEC_TLSLDO)
7659                                          (match_operand:DI 1 "register_operand" "r")))))]
7660   "TARGET_TLS && TARGET_ARCH64"
7661   "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7662   [(set_attr "type" "sload")
7663    (set_attr "us3load_type" "3cycle")])
7665 (define_insn "*tldo_ldsh2_sp64"
7666   [(set (match_operand:DI 0 "register_operand" "=r")
7667         (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7668                                                      (match_operand 3 "tld_symbolic_operand" "")]
7669                                                     UNSPEC_TLSLDO)
7670                                          (match_operand:DI 1 "register_operand" "r")))))]
7671   "TARGET_TLS && TARGET_ARCH64"
7672   "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7673   [(set_attr "type" "sload")
7674    (set_attr "us3load_type" "3cycle")])
7676 (define_insn "*tldo_lduw_sp32"
7677   [(set (match_operand:SI 0 "register_operand" "=r")
7678         (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7679                                      (match_operand 3 "tld_symbolic_operand" "")]
7680                                     UNSPEC_TLSLDO)
7681                          (match_operand:SI 1 "register_operand" "r"))))]
7682   "TARGET_TLS && TARGET_ARCH32"
7683   "ld\t[%1 + %2], %0, %%tldo_add(%3)"
7684   [(set_attr "type" "load")])
7686 (define_insn "*tldo_lduw_sp64"
7687   [(set (match_operand:SI 0 "register_operand" "=r")
7688         (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7689                                      (match_operand 3 "tld_symbolic_operand" "")]
7690                                     UNSPEC_TLSLDO)
7691                          (match_operand:DI 1 "register_operand" "r"))))]
7692   "TARGET_TLS && TARGET_ARCH64"
7693   "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7694   [(set_attr "type" "load")])
7696 (define_insn "*tldo_lduw1_sp64"
7697   [(set (match_operand:DI 0 "register_operand" "=r")
7698         (zero_extend:DI (mem:SI (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   "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7704   [(set_attr "type" "load")])
7706 (define_insn "*tldo_ldsw1_sp64"
7707   [(set (match_operand:DI 0 "register_operand" "=r")
7708         (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7709                                                      (match_operand 3 "tld_symbolic_operand" "")]
7710                                                     UNSPEC_TLSLDO)
7711                                          (match_operand:DI 1 "register_operand" "r")))))]
7712   "TARGET_TLS && TARGET_ARCH64"
7713   "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
7714   [(set_attr "type" "sload")
7715    (set_attr "us3load_type" "3cycle")])
7717 (define_insn "*tldo_ldx_sp64"
7718   [(set (match_operand:DI 0 "register_operand" "=r")
7719         (mem:DI (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   "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
7725   [(set_attr "type" "load")])
7727 (define_insn "*tldo_stb_sp32"
7728   [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7729                                      (match_operand 3 "tld_symbolic_operand" "")]
7730                                     UNSPEC_TLSLDO)
7731                          (match_operand:SI 1 "register_operand" "r")))
7732         (match_operand:QI 0 "register_operand" "r"))]
7733   "TARGET_TLS && TARGET_ARCH32"
7734   "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7735   [(set_attr "type" "store")])
7737 (define_insn "*tldo_stb_sp64"
7738   [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7739                                      (match_operand 3 "tld_symbolic_operand" "")]
7740                                     UNSPEC_TLSLDO)
7741                          (match_operand:DI 1 "register_operand" "r")))
7742         (match_operand:QI 0 "register_operand" "r"))]
7743   "TARGET_TLS && TARGET_ARCH64"
7744   "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7745   [(set_attr "type" "store")])
7747 (define_insn "*tldo_sth_sp32"
7748   [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7749                                      (match_operand 3 "tld_symbolic_operand" "")]
7750                                     UNSPEC_TLSLDO)
7751                          (match_operand:SI 1 "register_operand" "r")))
7752         (match_operand:HI 0 "register_operand" "r"))]
7753   "TARGET_TLS && TARGET_ARCH32"
7754   "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7755   [(set_attr "type" "store")])
7757 (define_insn "*tldo_sth_sp64"
7758   [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7759                                      (match_operand 3 "tld_symbolic_operand" "")]
7760                                     UNSPEC_TLSLDO)
7761                          (match_operand:DI 1 "register_operand" "r")))
7762         (match_operand:HI 0 "register_operand" "r"))]
7763   "TARGET_TLS && TARGET_ARCH64"
7764   "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7765   [(set_attr "type" "store")])
7767 (define_insn "*tldo_stw_sp32"
7768   [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7769                                      (match_operand 3 "tld_symbolic_operand" "")]
7770                                     UNSPEC_TLSLDO)
7771                          (match_operand:SI 1 "register_operand" "r")))
7772         (match_operand:SI 0 "register_operand" "r"))]
7773   "TARGET_TLS && TARGET_ARCH32"
7774   "st\t%0, [%1 + %2], %%tldo_add(%3)"
7775   [(set_attr "type" "store")])
7777 (define_insn "*tldo_stw_sp64"
7778   [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7779                                      (match_operand 3 "tld_symbolic_operand" "")]
7780                                     UNSPEC_TLSLDO)
7781                          (match_operand:DI 1 "register_operand" "r")))
7782         (match_operand:SI 0 "register_operand" "r"))]
7783   "TARGET_TLS && TARGET_ARCH64"
7784   "stw\t%0, [%1 + %2], %%tldo_add(%3)"
7785   [(set_attr "type" "store")])
7787 (define_insn "*tldo_stx_sp64"
7788   [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7789                                      (match_operand 3 "tld_symbolic_operand" "")]
7790                                     UNSPEC_TLSLDO)
7791                          (match_operand:DI 1 "register_operand" "r")))
7792         (match_operand:DI 0 "register_operand" "r"))]
7793   "TARGET_TLS && TARGET_ARCH64"
7794   "stx\t%0, [%1 + %2], %%tldo_add(%3)"
7795   [(set_attr "type" "store")])
7798 ;; Stack protector instructions.
7800 (define_expand "stack_protect_set"
7801   [(match_operand 0 "memory_operand" "")
7802    (match_operand 1 "memory_operand" "")]
7803   ""
7805 #ifdef TARGET_THREAD_SSP_OFFSET
7806   rtx tlsreg = gen_rtx_REG (Pmode, 7);
7807   rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7808   operands[1] = gen_rtx_MEM (Pmode, addr);
7809 #endif
7810   if (TARGET_ARCH64)
7811     emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
7812   else
7813     emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
7814   DONE;
7817 (define_insn "stack_protect_setsi"
7818   [(set (match_operand:SI 0 "memory_operand" "=m")
7819         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7820    (set (match_scratch:SI 2 "=&r") (const_int 0))]
7821   "TARGET_ARCH32"
7822   "ld\t%1, %2\;st\t%2, %0\;mov\t0, %2"
7823   [(set_attr "type" "multi")
7824    (set_attr "length" "3")])
7826 (define_insn "stack_protect_setdi"
7827   [(set (match_operand:DI 0 "memory_operand" "=m")
7828         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7829    (set (match_scratch:DI 2 "=&r") (const_int 0))]
7830   "TARGET_ARCH64"
7831   "ldx\t%1, %2\;stx\t%2, %0\;mov\t0, %2"
7832   [(set_attr "type" "multi")
7833    (set_attr "length" "3")])
7835 (define_expand "stack_protect_test"
7836   [(match_operand 0 "memory_operand" "")
7837    (match_operand 1 "memory_operand" "")
7838    (match_operand 2 "" "")]
7839   ""
7841   rtx result, test;
7842 #ifdef TARGET_THREAD_SSP_OFFSET
7843   rtx tlsreg = gen_rtx_REG (Pmode, 7);
7844   rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7845   operands[1] = gen_rtx_MEM (Pmode, addr);
7846 #endif
7847   if (TARGET_ARCH64)
7848     {
7849       result = gen_reg_rtx (Pmode);
7850       emit_insn (gen_stack_protect_testdi (result, operands[0], operands[1]));
7851       test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7852       emit_jump_insn (gen_cbranchdi4 (test, result, const0_rtx, operands[2]));
7853     }
7854   else
7855     {
7856       emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
7857       result = gen_rtx_REG (CCmode, SPARC_ICC_REG);
7858       test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7859       emit_jump_insn (gen_cbranchcc4 (test, result, const0_rtx, operands[2]));
7860     }
7861   DONE;
7864 (define_insn "stack_protect_testsi"
7865   [(set (reg:CC CC_REG)
7866         (unspec:CC [(match_operand:SI 0 "memory_operand" "m")
7867                     (match_operand:SI 1 "memory_operand" "m")]
7868                    UNSPEC_SP_TEST))
7869    (set (match_scratch:SI 3 "=r") (const_int 0))
7870    (clobber (match_scratch:SI 2 "=&r"))]
7871   "TARGET_ARCH32"
7872   "ld\t%0, %2\;ld\t%1, %3\;xorcc\t%2, %3, %2\;mov\t0, %3"
7873   [(set_attr "type" "multi")
7874    (set_attr "length" "4")])
7876 (define_insn "stack_protect_testdi"
7877   [(set (match_operand:DI 0 "register_operand" "=&r")
7878         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
7879                     (match_operand:DI 2 "memory_operand" "m")]
7880                    UNSPEC_SP_TEST))
7881    (set (match_scratch:DI 3 "=r") (const_int 0))]
7882   "TARGET_ARCH64"
7883   "ldx\t%1, %0\;ldx\t%2, %3\;xor\t%0, %3, %0\;mov\t0, %3"
7884   [(set_attr "type" "multi")
7885    (set_attr "length" "4")])
7887 ;; Vector instructions.
7889 (define_mode_iterator VM32 [V1SI V2HI V4QI])
7890 (define_mode_iterator VM64 [V1DI V2SI V4HI V8QI])
7891 (define_mode_iterator VMALL [V1SI V2HI V4QI V1DI V2SI V4HI V8QI])
7893 (define_mode_attr vbits [(V2SI "32") (V4HI "16") (V1SI "32s") (V2HI "16s")])
7894 (define_mode_attr vconstr [(V1SI "f") (V2HI "f") (V4QI "f")
7895                            (V1DI "e") (V2SI "e") (V4HI "e") (V8QI "e")])
7896 (define_mode_attr vfptype [(V1SI "single") (V2HI "single") (V4QI "single")
7897                            (V1DI "double") (V2SI "double") (V4HI "double")
7898                            (V8QI "double")])
7900 (define_expand "mov<VMALL:mode>"
7901   [(set (match_operand:VMALL 0 "nonimmediate_operand" "")
7902         (match_operand:VMALL 1 "general_operand" ""))]
7903   "TARGET_VIS"
7905   if (sparc_expand_move (<VMALL:MODE>mode, operands))
7906     DONE;
7909 (define_insn "*mov<VM32:mode>_insn"
7910   [(set (match_operand:VM32 0 "nonimmediate_operand" "=f,f,f,f,m,m,*r, m,*r,*r, f")
7911         (match_operand:VM32 1 "input_operand"         "Y,Z,f,m,f,Y, m,*r,*r, f,*r"))]
7912   "TARGET_VIS
7913    && (register_operand (operands[0], <VM32:MODE>mode)
7914        || register_or_zero_or_all_ones_operand (operands[1], <VM32:MODE>mode))"
7915   "@
7916   fzeros\t%0
7917   fones\t%0
7918   fsrc2s\t%1, %0
7919   ld\t%1, %0
7920   st\t%1, %0
7921   st\t%r1, %0
7922   ld\t%1, %0
7923   st\t%1, %0
7924   mov\t%1, %0
7925   movstouw\t%1, %0
7926   movwtos\t%1, %0"
7927   [(set_attr "type" "visl,visl,vismv,fpload,fpstore,store,load,store,*,vismv,vismv")
7928    (set_attr "cpu_feature" "vis,vis,vis,*,*,*,*,*,*,vis3,vis3")])
7930 (define_insn "*mov<VM64:mode>_insn_sp64"
7931   [(set (match_operand:VM64 0 "nonimmediate_operand" "=e,e,e,e,m,m,*r, m,*r, e,*r")
7932         (match_operand:VM64 1 "input_operand"         "Y,C,e,m,e,Y, m,*r, e,*r,*r"))]
7933   "TARGET_VIS
7934    && TARGET_ARCH64
7935    && (register_operand (operands[0], <VM64:MODE>mode)
7936        || register_or_zero_or_all_ones_operand (operands[1], <VM64:MODE>mode))"
7937   "@
7938   fzero\t%0
7939   fone\t%0
7940   fsrc2\t%1, %0
7941   ldd\t%1, %0
7942   std\t%1, %0
7943   stx\t%r1, %0
7944   ldx\t%1, %0
7945   stx\t%1, %0
7946   movdtox\t%1, %0
7947   movxtod\t%1, %0
7948   mov\t%1, %0"
7949   [(set_attr "type" "visl,visl,vismv,fpload,fpstore,store,load,store,vismv,vismv,*")
7950    (set_attr "cpu_feature" "vis,vis,vis,*,*,*,*,*,vis3,vis3,*")])
7952 (define_insn "*mov<VM64:mode>_insn_sp32"
7953   [(set (match_operand:VM64 0 "nonimmediate_operand" "=e,e,e,*r, f,e,m,m,U,T, o,*r")
7954         (match_operand:VM64 1 "input_operand"         "Y,C,e, f,*r,m,e,Y,T,U,*r,*r"))]
7955   "TARGET_VIS
7956    && ! TARGET_ARCH64
7957    && (register_operand (operands[0], <VM64:MODE>mode)
7958        || register_or_zero_or_all_ones_operand (operands[1], <VM64:MODE>mode))"
7959   "@
7960   fzero\t%0
7961   fone\t%0
7962   fsrc2\t%1, %0
7963   #
7964   #
7965   ldd\t%1, %0
7966   std\t%1, %0
7967   stx\t%r1, %0
7968   ldd\t%1, %0
7969   std\t%1, %0
7970   #
7971   #"
7972   [(set_attr "type" "visl,visl,vismv,*,*,fpload,fpstore,store,load,store,*,*")
7973    (set_attr "length" "*,*,*,2,2,*,*,*,*,*,2,2")
7974    (set_attr "cpu_feature" "vis,vis,vis,vis3,vis3,*,*,*,*,*,*,*")])
7976 (define_split
7977   [(set (match_operand:VM64 0 "memory_operand" "")
7978         (match_operand:VM64 1 "register_operand" ""))]
7979   "reload_completed
7980    && TARGET_VIS
7981    && ! TARGET_ARCH64
7982    && (((REGNO (operands[1]) % 2) != 0)
7983        || ! mem_min_alignment (operands[0], 8))
7984    && offsettable_memref_p (operands[0])"
7985   [(clobber (const_int 0))]
7987   rtx word0, word1;
7989   word0 = adjust_address (operands[0], SImode, 0);
7990   word1 = adjust_address (operands[0], SImode, 4);
7992   emit_move_insn_1 (word0, gen_highpart (SImode, operands[1]));
7993   emit_move_insn_1 (word1, gen_lowpart (SImode, operands[1]));
7994   DONE;
7997 (define_split
7998   [(set (match_operand:VM64 0 "register_operand" "")
7999         (match_operand:VM64 1 "register_operand" ""))]
8000   "reload_completed
8001    && TARGET_VIS
8002    && ! TARGET_ARCH64
8003    && sparc_split_regreg_legitimate (operands[0], operands[1])"
8004   [(clobber (const_int 0))]
8006   rtx set_dest = operands[0];
8007   rtx set_src = operands[1];
8008   rtx dest1, dest2;
8009   rtx src1, src2;
8011   dest1 = gen_highpart (SImode, set_dest);
8012   dest2 = gen_lowpart (SImode, set_dest);
8013   src1 = gen_highpart (SImode, set_src);
8014   src2 = gen_lowpart (SImode, set_src);
8016   /* Now emit using the real source and destination we found, swapping
8017      the order if we detect overlap.  */
8018   if (reg_overlap_mentioned_p (dest1, src2))
8019     {
8020       emit_insn (gen_movsi (dest2, src2));
8021       emit_insn (gen_movsi (dest1, src1));
8022     }
8023   else
8024     {
8025       emit_insn (gen_movsi (dest1, src1));
8026       emit_insn (gen_movsi (dest2, src2));
8027     }
8028   DONE;
8031 (define_expand "vec_init<mode>"
8032   [(match_operand:VMALL 0 "register_operand" "")
8033    (match_operand:VMALL 1 "" "")]
8034   "TARGET_VIS"
8036   sparc_expand_vector_init (operands[0], operands[1]);
8037   DONE;
8040 (define_code_iterator plusminus [plus minus])
8041 (define_code_attr plusminus_insn [(plus "add") (minus "sub")])
8043 (define_mode_iterator VADDSUB [V1SI V2SI V2HI V4HI])
8045 (define_insn "<plusminus_insn><mode>3"
8046   [(set (match_operand:VADDSUB 0 "register_operand" "=<vconstr>")
8047         (plusminus:VADDSUB (match_operand:VADDSUB 1 "register_operand" "<vconstr>")
8048                            (match_operand:VADDSUB 2 "register_operand" "<vconstr>")))]
8049   "TARGET_VIS"
8050   "fp<plusminus_insn><vbits>\t%1, %2, %0"
8051   [(set_attr "type" "fga")
8052    (set_attr "fptype" "<vfptype>")])
8054 (define_mode_iterator VL [V1SI V2HI V4QI V1DI V2SI V4HI V8QI])
8055 (define_mode_attr vlsuf [(V1SI "s") (V2HI "s") (V4QI "s")
8056                          (V1DI  "") (V2SI  "") (V4HI  "") (V8QI "")])
8057 (define_code_iterator vlop [ior and xor])
8058 (define_code_attr vlinsn [(ior "or") (and "and") (xor "xor")])
8059 (define_code_attr vlninsn [(ior "nor") (and "nand") (xor "xnor")])
8061 (define_insn "<code><mode>3"
8062   [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8063         (vlop:VL (match_operand:VL 1 "register_operand" "<vconstr>")
8064                  (match_operand:VL 2 "register_operand" "<vconstr>")))]
8065   "TARGET_VIS"
8066   "f<vlinsn><vlsuf>\t%1, %2, %0"
8067   [(set_attr "type" "visl")
8068    (set_attr "fptype" "<vfptype>")])
8070 (define_insn "*not_<code><mode>3"
8071   [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8072         (not:VL (vlop:VL (match_operand:VL 1 "register_operand" "<vconstr>")
8073                          (match_operand:VL 2 "register_operand" "<vconstr>"))))]
8074   "TARGET_VIS"
8075   "f<vlninsn><vlsuf>\t%1, %2, %0"
8076   [(set_attr "type" "visl")
8077    (set_attr "fptype" "<vfptype>")])
8079 ;; (ior (not (op1)) (not (op2))) is the canonical form of NAND.
8080 (define_insn "*nand<mode>_vis"
8081   [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8082         (ior:VL (not:VL (match_operand:VL 1 "register_operand" "<vconstr>"))
8083                 (not:VL (match_operand:VL 2 "register_operand" "<vconstr>"))))]
8084   "TARGET_VIS"
8085   "fnand<vlsuf>\t%1, %2, %0"
8086   [(set_attr "type" "visl")
8087    (set_attr "fptype" "<vfptype>")])
8089 (define_code_iterator vlnotop [ior and])
8091 (define_insn "*<code>_not1<mode>_vis"
8092   [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8093         (vlnotop:VL (not:VL (match_operand:VL 1 "register_operand" "<vconstr>"))
8094                     (match_operand:VL 2 "register_operand" "<vconstr>")))]
8095   "TARGET_VIS"
8096   "f<vlinsn>not1<vlsuf>\t%1, %2, %0"
8097   [(set_attr "type" "visl")
8098    (set_attr "fptype" "<vfptype>")])
8100 (define_insn "*<code>_not2<mode>_vis"
8101   [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8102         (vlnotop:VL (match_operand:VL 1 "register_operand" "<vconstr>")
8103                     (not:VL (match_operand:VL 2 "register_operand" "<vconstr>"))))]
8104   "TARGET_VIS"
8105   "f<vlinsn>not2<vlsuf>\t%1, %2, %0"
8106   [(set_attr "type" "visl")
8107    (set_attr "fptype" "<vfptype>")])
8109 (define_insn "one_cmpl<mode>2"
8110   [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8111         (not:VL (match_operand:VL 1 "register_operand" "<vconstr>")))]
8112   "TARGET_VIS"
8113   "fnot1<vlsuf>\t%1, %0"
8114   [(set_attr "type" "visl")
8115    (set_attr "fptype" "<vfptype>")])
8117 ;; Hard to generate VIS instructions.  We have builtins for these.
8119 (define_insn "fpack16_vis"
8120   [(set (match_operand:V4QI 0 "register_operand" "=f")
8121         (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e")
8122                       (reg:DI GSR_REG)]
8123                       UNSPEC_FPACK16))]
8124   "TARGET_VIS"
8125   "fpack16\t%1, %0"
8126   [(set_attr "type" "fgm_pack")
8127    (set_attr "fptype" "double")])
8129 (define_insn "fpackfix_vis"
8130   [(set (match_operand:V2HI 0 "register_operand" "=f")
8131         (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e")
8132                       (reg:DI GSR_REG)]
8133                       UNSPEC_FPACKFIX))]
8134   "TARGET_VIS"
8135   "fpackfix\t%1, %0"
8136   [(set_attr "type" "fgm_pack")
8137    (set_attr "fptype" "double")])
8139 (define_insn "fpack32_vis"
8140   [(set (match_operand:V8QI 0 "register_operand" "=e")
8141         (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e")
8142                       (match_operand:V8QI 2 "register_operand" "e")
8143                       (reg:DI GSR_REG)]
8144                      UNSPEC_FPACK32))]
8145   "TARGET_VIS"
8146   "fpack32\t%1, %2, %0"
8147   [(set_attr "type" "fgm_pack")
8148    (set_attr "fptype" "double")])
8150 (define_insn "fexpand_vis"
8151   [(set (match_operand:V4HI 0 "register_operand" "=e")
8152         (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")]
8153          UNSPEC_FEXPAND))]
8154  "TARGET_VIS"
8155  "fexpand\t%1, %0"
8156  [(set_attr "type" "fga")
8157   (set_attr "fptype" "double")])
8159 (define_insn "fpmerge_vis"
8160   [(set (match_operand:V8QI 0 "register_operand" "=e")
8161         (vec_select:V8QI
8162           (vec_concat:V8QI (match_operand:V4QI 1 "register_operand" "f")
8163                            (match_operand:V4QI 2 "register_operand" "f"))
8164           (parallel [(const_int 0) (const_int 4)
8165                      (const_int 1) (const_int 5)
8166                      (const_int 2) (const_int 6)
8167                      (const_int 3) (const_int 7)])))]
8168  "TARGET_VIS"
8169  "fpmerge\t%1, %2, %0"
8170  [(set_attr "type" "fga")
8171   (set_attr "fptype" "double")])
8173 (define_insn "vec_interleave_lowv8qi"
8174   [(set (match_operand:V8QI 0 "register_operand" "=e")
8175         (vec_select:V8QI
8176           (vec_concat:V16QI (match_operand:V8QI 1 "register_operand" "f")
8177                             (match_operand:V8QI 2 "register_operand" "f"))
8178           (parallel [(const_int 0) (const_int 8)
8179                      (const_int 1) (const_int 9)
8180                      (const_int 2) (const_int 10)
8181                      (const_int 3) (const_int 11)])))]
8182  "TARGET_VIS"
8183  "fpmerge\t%L1, %L2, %0"
8184  [(set_attr "type" "fga")
8185   (set_attr "fptype" "double")])
8187 (define_insn "vec_interleave_highv8qi"
8188   [(set (match_operand:V8QI 0 "register_operand" "=e")
8189         (vec_select:V8QI
8190           (vec_concat:V16QI (match_operand:V8QI 1 "register_operand" "f")
8191                             (match_operand:V8QI 2 "register_operand" "f"))
8192           (parallel [(const_int 4) (const_int 12)
8193                      (const_int 5) (const_int 13)
8194                      (const_int 6) (const_int 14)
8195                      (const_int 7) (const_int 15)])))]
8196  "TARGET_VIS"
8197  "fpmerge\t%H1, %H2, %0"
8198  [(set_attr "type" "fga")
8199   (set_attr "fptype" "double")])
8201 ;; Partitioned multiply instructions
8202 (define_insn "fmul8x16_vis"
8203   [(set (match_operand:V4HI 0 "register_operand" "=e")
8204         (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8205                       (match_operand:V4HI 2 "register_operand" "e")]
8206          UNSPEC_MUL8))]
8207   "TARGET_VIS"
8208   "fmul8x16\t%1, %2, %0"
8209   [(set_attr "type" "fgm_mul")
8210    (set_attr "fptype" "double")])
8212 (define_insn "fmul8x16au_vis"
8213   [(set (match_operand:V4HI 0 "register_operand" "=e")
8214         (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8215                       (match_operand:V2HI 2 "register_operand" "f")]
8216          UNSPEC_MUL16AU))]
8217   "TARGET_VIS"
8218   "fmul8x16au\t%1, %2, %0"
8219   [(set_attr "type" "fgm_mul")
8220    (set_attr "fptype" "double")])
8222 (define_insn "fmul8x16al_vis"
8223   [(set (match_operand:V4HI 0 "register_operand" "=e")
8224         (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8225                       (match_operand:V2HI 2 "register_operand" "f")]
8226          UNSPEC_MUL16AL))]
8227   "TARGET_VIS"
8228   "fmul8x16al\t%1, %2, %0"
8229   [(set_attr "type" "fgm_mul")
8230    (set_attr "fptype" "double")])
8232 (define_insn "fmul8sux16_vis"
8233   [(set (match_operand:V4HI 0 "register_operand" "=e")
8234         (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
8235                       (match_operand:V4HI 2 "register_operand" "e")]
8236          UNSPEC_MUL8SU))]
8237   "TARGET_VIS"
8238   "fmul8sux16\t%1, %2, %0"
8239   [(set_attr "type" "fgm_mul")
8240    (set_attr "fptype" "double")])
8242 (define_insn "fmul8ulx16_vis"
8243   [(set (match_operand:V4HI 0 "register_operand" "=e")
8244         (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
8245                       (match_operand:V4HI 2 "register_operand" "e")]
8246          UNSPEC_MUL8UL))]
8247   "TARGET_VIS"
8248   "fmul8ulx16\t%1, %2, %0"
8249   [(set_attr "type" "fgm_mul")
8250    (set_attr "fptype" "double")])
8252 (define_insn "fmuld8sux16_vis"
8253   [(set (match_operand:V2SI 0 "register_operand" "=e")
8254         (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
8255                       (match_operand:V2HI 2 "register_operand" "f")]
8256          UNSPEC_MULDSU))]
8257   "TARGET_VIS"
8258   "fmuld8sux16\t%1, %2, %0"
8259   [(set_attr "type" "fgm_mul")
8260    (set_attr "fptype" "double")])
8262 (define_insn "fmuld8ulx16_vis"
8263   [(set (match_operand:V2SI 0 "register_operand" "=e")
8264         (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
8265                       (match_operand:V2HI 2 "register_operand" "f")]
8266          UNSPEC_MULDUL))]
8267   "TARGET_VIS"
8268   "fmuld8ulx16\t%1, %2, %0"
8269   [(set_attr "type" "fgm_mul")
8270    (set_attr "fptype" "double")])
8272 (define_expand "wrgsr_vis"
8273   [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" ""))]
8274   "TARGET_VIS"
8276   if (! TARGET_ARCH64)
8277     {
8278       emit_insn (gen_wrgsr_v8plus (operands[0]));
8279       DONE;
8280     }
8283 (define_insn "*wrgsr_sp64"
8284   [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" "rI"))]
8285   "TARGET_VIS && TARGET_ARCH64"
8286   "wr\t%%g0, %0, %%gsr"
8287   [(set_attr "type" "gsr")])
8289 (define_insn "wrgsr_v8plus"
8290   [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" "I,r"))
8291    (clobber (match_scratch:SI 1 "=X,&h"))]
8292   "TARGET_VIS && ! TARGET_ARCH64"
8294   if (GET_CODE (operands[0]) == CONST_INT
8295       || sparc_check_64 (operands[0], insn))
8296     return "wr\t%%g0, %0, %%gsr";
8298   output_asm_insn("srl\t%L0, 0, %L0", operands);
8299   return "sllx\t%H0, 32, %1\n\tor\t%L0, %1, %1\n\twr\t%%g0, %1, %%gsr";
8301   [(set_attr "type" "multi")])
8303 (define_expand "rdgsr_vis"
8304   [(set (match_operand:DI 0 "register_operand" "") (reg:DI GSR_REG))]
8305   "TARGET_VIS"
8307   if (! TARGET_ARCH64)
8308     {
8309       emit_insn (gen_rdgsr_v8plus (operands[0]));
8310       DONE;
8311     }
8314 (define_insn "*rdgsr_sp64"
8315   [(set (match_operand:DI 0 "register_operand" "=r") (reg:DI GSR_REG))]
8316   "TARGET_VIS && TARGET_ARCH64"
8317   "rd\t%%gsr, %0"
8318   [(set_attr "type" "gsr")])
8320 (define_insn "rdgsr_v8plus"
8321   [(set (match_operand:DI 0 "register_operand" "=r") (reg:DI GSR_REG))
8322    (clobber (match_scratch:SI 1 "=&h"))]
8323   "TARGET_VIS && ! TARGET_ARCH64"
8325   return "rd\t%%gsr, %1\n\tsrlx\t%1, 32, %H0\n\tmov %1, %L0";
8327   [(set_attr "type" "multi")])
8329 ;; Using faligndata only makes sense after an alignaddr since the choice of
8330 ;; bytes to take out of each operand is dependent on the results of the last
8331 ;; alignaddr.
8332 (define_insn "faligndata<VM64:mode>_vis"
8333   [(set (match_operand:VM64 0 "register_operand" "=e")
8334         (unspec:VM64 [(match_operand:VM64 1 "register_operand" "e")
8335                       (match_operand:VM64 2 "register_operand" "e")
8336                       (reg:DI GSR_REG)]
8337          UNSPEC_ALIGNDATA))]
8338   "TARGET_VIS"
8339   "faligndata\t%1, %2, %0"
8340   [(set_attr "type" "fga")
8341    (set_attr "fptype" "double")])
8343 (define_insn "alignaddrsi_vis"
8344   [(set (match_operand:SI 0 "register_operand" "=r")
8345         (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
8346                  (match_operand:SI 2 "register_or_zero_operand" "rJ")))
8347    (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8348         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
8349   "TARGET_VIS"
8350   "alignaddr\t%r1, %r2, %0"
8351   [(set_attr "type" "gsr")])
8353 (define_insn "alignaddrdi_vis"
8354   [(set (match_operand:DI 0 "register_operand" "=r")
8355         (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
8356                  (match_operand:DI 2 "register_or_zero_operand" "rJ")))
8357    (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8358         (plus:DI (match_dup 1) (match_dup 2)))]
8359   "TARGET_VIS"
8360   "alignaddr\t%r1, %r2, %0"
8361   [(set_attr "type" "gsr")])
8363 (define_insn "alignaddrlsi_vis"
8364   [(set (match_operand:SI 0 "register_operand" "=r")
8365         (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
8366                  (match_operand:SI 2 "register_or_zero_operand" "rJ")))
8367    (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8368         (xor:DI (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2)))
8369                 (const_int 7)))]
8370   "TARGET_VIS"
8371   "alignaddrl\t%r1, %r2, %0"
8372   [(set_attr "type" "gsr")])
8374 (define_insn "alignaddrldi_vis"
8375   [(set (match_operand:DI 0 "register_operand" "=r")
8376         (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
8377                  (match_operand:DI 2 "register_or_zero_operand" "rJ")))
8378    (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8379         (xor:DI (plus:DI (match_dup 1) (match_dup 2))
8380                 (const_int 7)))]
8381   "TARGET_VIS"
8382   "alignaddrl\t%r1, %r2, %0"
8383   [(set_attr "type" "gsr")])
8385 (define_insn "pdist_vis"
8386   [(set (match_operand:DI 0 "register_operand" "=e")
8387         (unspec:DI [(match_operand:V8QI 1 "register_operand" "e")
8388                     (match_operand:V8QI 2 "register_operand" "e")
8389                     (match_operand:DI 3 "register_operand" "0")]
8390          UNSPEC_PDIST))]
8391   "TARGET_VIS"
8392   "pdist\t%1, %2, %0"
8393   [(set_attr "type" "pdist")
8394    (set_attr "fptype" "double")])
8396 ;; Edge instructions produce condition codes equivalent to a 'subcc'
8397 ;; with the same operands.
8398 (define_insn "edge8<P:mode>_vis"
8399   [(set (reg:CC_NOOV CC_REG)
8400         (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8401                                   (match_operand:P 2 "register_or_zero_operand" "rJ"))
8402                          (const_int 0)))
8403    (set (match_operand:P 0 "register_operand" "=r")
8404         (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8))]
8405   "TARGET_VIS"
8406   "edge8\t%r1, %r2, %0"
8407   [(set_attr "type" "edge")])
8409 (define_insn "edge8l<P:mode>_vis"
8410   [(set (reg:CC_NOOV CC_REG)
8411         (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8412                                   (match_operand:P 2 "register_or_zero_operand" "rJ"))
8413                          (const_int 0)))
8414    (set (match_operand:P 0 "register_operand" "=r")
8415         (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8L))]
8416   "TARGET_VIS"
8417   "edge8l\t%r1, %r2, %0"
8418   [(set_attr "type" "edge")])
8420 (define_insn "edge16<P:mode>_vis"
8421   [(set (reg:CC_NOOV CC_REG)
8422         (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8423                                   (match_operand:P 2 "register_or_zero_operand" "rJ"))
8424                          (const_int 0)))
8425    (set (match_operand:P 0 "register_operand" "=r")
8426         (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16))]
8427   "TARGET_VIS"
8428   "edge16\t%r1, %r2, %0"
8429   [(set_attr "type" "edge")])
8431 (define_insn "edge16l<P:mode>_vis"
8432   [(set (reg:CC_NOOV CC_REG)
8433         (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8434                                   (match_operand:P 2 "register_or_zero_operand" "rJ"))
8435                          (const_int 0)))
8436    (set (match_operand:P 0 "register_operand" "=r")
8437         (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16L))]
8438   "TARGET_VIS"
8439   "edge16l\t%r1, %r2, %0"
8440   [(set_attr "type" "edge")])
8442 (define_insn "edge32<P:mode>_vis"
8443   [(set (reg:CC_NOOV CC_REG)
8444         (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8445                                   (match_operand:P 2 "register_or_zero_operand" "rJ"))
8446                          (const_int 0)))
8447    (set (match_operand:P 0 "register_operand" "=r")
8448         (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32))]
8449   "TARGET_VIS"
8450   "edge32\t%r1, %r2, %0"
8451   [(set_attr "type" "edge")])
8453 (define_insn "edge32l<P:mode>_vis"
8454   [(set (reg:CC_NOOV CC_REG)
8455         (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8456                                   (match_operand:P 2 "register_or_zero_operand" "rJ"))
8457                          (const_int 0)))
8458    (set (match_operand:P 0 "register_operand" "=r")
8459         (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32L))]
8460   "TARGET_VIS"
8461   "edge32l\t%r1, %r2, %0"
8462   [(set_attr "type" "edge")])
8464 (define_code_iterator gcond [le ne gt eq])
8465 (define_mode_iterator GCM [V4HI V2SI])
8466 (define_mode_attr gcm_name [(V4HI "16") (V2SI "32")])
8468 (define_insn "fcmp<code><GCM:gcm_name><P:mode>_vis"
8469   [(set (match_operand:P 0 "register_operand" "=r")
8470         (unspec:P [(gcond:GCM (match_operand:GCM 1 "register_operand" "e")
8471                               (match_operand:GCM 2 "register_operand" "e"))]
8472          UNSPEC_FCMP))]
8473   "TARGET_VIS"
8474   "fcmp<code><GCM:gcm_name>\t%1, %2, %0"
8475   [(set_attr "type" "visl")
8476    (set_attr "fptype" "double")])
8478 (define_expand "vcond<mode><mode>"
8479   [(match_operand:GCM 0 "register_operand" "")
8480    (match_operand:GCM 1 "register_operand" "")
8481    (match_operand:GCM 2 "register_operand" "")
8482    (match_operator 3 ""
8483      [(match_operand:GCM 4 "register_operand" "")
8484       (match_operand:GCM 5 "register_operand" "")])]
8485   "TARGET_VIS3"
8487   sparc_expand_vcond (<MODE>mode, operands,
8488                       UNSPEC_CMASK<gcm_name>,
8489                       UNSPEC_FCMP);
8490   DONE;
8493 (define_expand "vconduv8qiv8qi"
8494   [(match_operand:V8QI 0 "register_operand" "")
8495    (match_operand:V8QI 1 "register_operand" "")
8496    (match_operand:V8QI 2 "register_operand" "")
8497    (match_operator 3 ""
8498      [(match_operand:V8QI 4 "register_operand" "")
8499       (match_operand:V8QI 5 "register_operand" "")])]
8500   "TARGET_VIS3"
8502   sparc_expand_vcond (V8QImode, operands,
8503                       UNSPEC_CMASK8,
8504                       UNSPEC_FUCMP);
8505   DONE;
8508 (define_insn "array8<P:mode>_vis"
8509   [(set (match_operand:P 0 "register_operand" "=r")
8510         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8511                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
8512                   UNSPEC_ARRAY8))]
8513   "TARGET_VIS"
8514   "array8\t%r1, %r2, %0"
8515   [(set_attr "type" "array")])
8517 (define_insn "array16<P:mode>_vis"
8518   [(set (match_operand:P 0 "register_operand" "=r")
8519         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8520                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
8521                   UNSPEC_ARRAY16))]
8522   "TARGET_VIS"
8523   "array16\t%r1, %r2, %0"
8524   [(set_attr "type" "array")])
8526 (define_insn "array32<P:mode>_vis"
8527   [(set (match_operand:P 0 "register_operand" "=r")
8528         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8529                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
8530                   UNSPEC_ARRAY32))]
8531   "TARGET_VIS"
8532   "array32\t%r1, %r2, %0"
8533   [(set_attr "type" "array")])
8535 (define_insn "bmaskdi_vis"
8536   [(set (match_operand:DI 0 "register_operand" "=r")
8537         (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
8538                  (match_operand:DI 2 "register_or_zero_operand" "rJ")))
8539    (set (zero_extract:DI (reg:DI GSR_REG) (const_int 32) (const_int 32))
8540         (plus:DI (match_dup 1) (match_dup 2)))]
8541   "TARGET_VIS2"
8542   "bmask\t%r1, %r2, %0"
8543   [(set_attr "type" "array")])
8545 (define_insn "bmasksi_vis"
8546   [(set (match_operand:SI 0 "register_operand" "=r")
8547         (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
8548                  (match_operand:SI 2 "register_or_zero_operand" "rJ")))
8549    (set (zero_extract:DI (reg:DI GSR_REG) (const_int 32) (const_int 32))
8550         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
8551   "TARGET_VIS2"
8552   "bmask\t%r1, %r2, %0"
8553   [(set_attr "type" "array")])
8555 (define_insn "bshuffle<VM64:mode>_vis"
8556   [(set (match_operand:VM64 0 "register_operand" "=e")
8557         (unspec:VM64 [(match_operand:VM64 1 "register_operand" "e")
8558                       (match_operand:VM64 2 "register_operand" "e")
8559                       (reg:DI GSR_REG)]
8560                      UNSPEC_BSHUFFLE))]
8561   "TARGET_VIS2"
8562   "bshuffle\t%1, %2, %0"
8563   [(set_attr "type" "fga")
8564    (set_attr "fptype" "double")])
8566 ;; The rtl expanders will happily convert constant permutations on other
8567 ;; modes down to V8QI.  Rely on this to avoid the complexity of the byte
8568 ;; order of the permutation.
8569 (define_expand "vec_perm_constv8qi"
8570   [(match_operand:V8QI 0 "register_operand" "")
8571    (match_operand:V8QI 1 "register_operand" "")
8572    (match_operand:V8QI 2 "register_operand" "")
8573    (match_operand:V8QI 3 "" "")]
8574   "TARGET_VIS2"
8576   unsigned int i, mask;
8577   rtx sel = operands[3];
8579   for (i = mask = 0; i < 8; ++i)
8580     mask |= (INTVAL (XVECEXP (sel, 0, i)) & 0xf) << (28 - i*4);
8581   sel = force_reg (SImode, gen_int_mode (mask, SImode));
8583   emit_insn (gen_bmasksi_vis (gen_rtx_REG (SImode, 0), sel, const0_rtx));
8584   emit_insn (gen_bshufflev8qi_vis (operands[0], operands[1], operands[2]));
8585   DONE;
8588 ;; Unlike constant permutation, we can vastly simplify the compression of
8589 ;; the 64-bit selector input to the 32-bit %gsr value by knowing what the
8590 ;; width of the input is.
8591 (define_expand "vec_perm<mode>"
8592   [(match_operand:VM64 0 "register_operand" "")
8593    (match_operand:VM64 1 "register_operand" "")
8594    (match_operand:VM64 2 "register_operand" "")
8595    (match_operand:VM64 3 "register_operand" "")]
8596   "TARGET_VIS2"
8598   sparc_expand_vec_perm_bmask (<MODE>mode, operands[3]);
8599   emit_insn (gen_bshuffle<mode>_vis (operands[0], operands[1], operands[2]));
8600   DONE;
8603 ;; VIS 2.0 adds edge variants which do not set the condition codes
8604 (define_insn "edge8n<P:mode>_vis"
8605   [(set (match_operand:P 0 "register_operand" "=r")
8606         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8607                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
8608                   UNSPEC_EDGE8N))]
8609   "TARGET_VIS2"
8610   "edge8n\t%r1, %r2, %0"
8611   [(set_attr "type" "edgen")])
8613 (define_insn "edge8ln<P:mode>_vis"
8614   [(set (match_operand:P 0 "register_operand" "=r")
8615         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8616                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
8617                   UNSPEC_EDGE8LN))]
8618   "TARGET_VIS2"
8619   "edge8ln\t%r1, %r2, %0"
8620   [(set_attr "type" "edgen")])
8622 (define_insn "edge16n<P:mode>_vis"
8623   [(set (match_operand:P 0 "register_operand" "=r")
8624         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8625                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
8626                   UNSPEC_EDGE16N))]
8627   "TARGET_VIS2"
8628   "edge16n\t%r1, %r2, %0"
8629   [(set_attr "type" "edgen")])
8631 (define_insn "edge16ln<P:mode>_vis"
8632   [(set (match_operand:P 0 "register_operand" "=r")
8633         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8634                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
8635                   UNSPEC_EDGE16LN))]
8636   "TARGET_VIS2"
8637   "edge16ln\t%r1, %r2, %0"
8638   [(set_attr "type" "edgen")])
8640 (define_insn "edge32n<P:mode>_vis"
8641   [(set (match_operand:P 0 "register_operand" "=r")
8642         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8643                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
8644                   UNSPEC_EDGE32N))]
8645   "TARGET_VIS2"
8646   "edge32n\t%r1, %r2, %0"
8647   [(set_attr "type" "edgen")])
8649 (define_insn "edge32ln<P:mode>_vis"
8650   [(set (match_operand:P 0 "register_operand" "=r")
8651         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8652                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
8653                   UNSPEC_EDGE32LN))]
8654   "TARGET_VIS2"
8655   "edge32ln\t%r1, %r2, %0"
8656   [(set_attr "type" "edge")])
8658 ;; Conditional moves are possible via fcmpX --> cmaskX -> bshuffle
8659 (define_insn "cmask8<P:mode>_vis"
8660   [(set (reg:DI GSR_REG)
8661         (unspec:DI [(match_operand:P 0 "register_or_zero_operand" "rJ")
8662                     (reg:DI GSR_REG)]
8663                    UNSPEC_CMASK8))]
8664   "TARGET_VIS3"
8665   "cmask8\t%r0"
8666   [(set_attr "type" "fga")])
8668 (define_insn "cmask16<P:mode>_vis"
8669   [(set (reg:DI GSR_REG)
8670         (unspec:DI [(match_operand:P 0 "register_or_zero_operand" "rJ")
8671                     (reg:DI GSR_REG)]
8672                    UNSPEC_CMASK16))]
8673   "TARGET_VIS3"
8674   "cmask16\t%r0"
8675   [(set_attr "type" "fga")])
8677 (define_insn "cmask32<P:mode>_vis"
8678   [(set (reg:DI GSR_REG)
8679         (unspec:DI [(match_operand:P 0 "register_or_zero_operand" "rJ")
8680                     (reg:DI GSR_REG)]
8681                    UNSPEC_CMASK32))]
8682   "TARGET_VIS3"
8683   "cmask32\t%r0"
8684   [(set_attr "type" "fga")])
8686 (define_insn "fchksm16_vis"
8687   [(set (match_operand:V4HI 0 "register_operand" "=e")
8688         (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "e")
8689                       (match_operand:V4HI 2 "register_operand" "e")]
8690                      UNSPEC_FCHKSM16))]
8691   "TARGET_VIS3"
8692   "fchksm16\t%1, %2, %0"
8693   [(set_attr "type" "fga")])
8695 (define_code_iterator vis3_shift [ashift ss_ashift lshiftrt ashiftrt])
8696 (define_code_attr vis3_shift_insn
8697   [(ashift "fsll") (ss_ashift "fslas") (lshiftrt "fsrl") (ashiftrt "fsra")])
8698 (define_code_attr vis3_shift_patname
8699   [(ashift "ashl") (ss_ashift "ssashl") (lshiftrt "lshr") (ashiftrt "ashr")])
8700    
8701 (define_insn "v<vis3_shift_patname><mode>3"
8702   [(set (match_operand:GCM 0 "register_operand" "=<vconstr>")
8703         (vis3_shift:GCM (match_operand:GCM 1 "register_operand" "<vconstr>")
8704                         (match_operand:GCM 2 "register_operand" "<vconstr>")))]
8705   "TARGET_VIS3"
8706   "<vis3_shift_insn><vbits>\t%1, %2, %0"
8707   [(set_attr "type" "fga")])
8709 (define_insn "pdistn<mode>_vis"
8710   [(set (match_operand:P 0 "register_operand" "=r")
8711         (unspec:P [(match_operand:V8QI 1 "register_operand" "e")
8712                    (match_operand:V8QI 2 "register_operand" "e")]
8713          UNSPEC_PDISTN))]
8714   "TARGET_VIS3"
8715   "pdistn\t%1, %2, %0"
8716   [(set_attr "type" "pdistn")
8717    (set_attr "fptype" "double")])
8719 (define_insn "fmean16_vis"
8720   [(set (match_operand:V4HI 0 "register_operand" "=e")
8721         (truncate:V4HI
8722           (lshiftrt:V4SI
8723             (plus:V4SI
8724               (plus:V4SI
8725                 (zero_extend:V4SI
8726                   (match_operand:V4HI 1 "register_operand" "e"))
8727                 (zero_extend:V4SI
8728                   (match_operand:V4HI 2 "register_operand" "e")))
8729               (const_vector:V4SI [(const_int 1) (const_int 1)
8730                                   (const_int 1) (const_int 1)]))
8731           (const_int 1))))]
8732   "TARGET_VIS3"
8733   "fmean16\t%1, %2, %0"
8734   [(set_attr "type" "fga")])
8736 (define_insn "fp<plusminus_insn>64_vis"
8737   [(set (match_operand:V1DI 0 "register_operand" "=e")
8738         (plusminus:V1DI (match_operand:V1DI 1 "register_operand" "e")
8739                         (match_operand:V1DI 2 "register_operand" "e")))]
8740   "TARGET_VIS3"
8741   "fp<plusminus_insn>64\t%1, %2, %0"
8742   [(set_attr "type" "fga")])
8744 (define_mode_iterator VASS [V4HI V2SI V2HI V1SI])
8745 (define_code_iterator vis3_addsub_ss [ss_plus ss_minus])
8746 (define_code_attr vis3_addsub_ss_insn
8747   [(ss_plus "fpadds") (ss_minus "fpsubs")])
8748 (define_code_attr vis3_addsub_ss_patname
8749   [(ss_plus "ssadd") (ss_minus "sssub")])
8751 (define_insn "<vis3_addsub_ss_patname><mode>3"
8752   [(set (match_operand:VASS 0 "register_operand" "=<vconstr>")
8753         (vis3_addsub_ss:VASS (match_operand:VASS 1 "register_operand" "<vconstr>")
8754                              (match_operand:VASS 2 "register_operand" "<vconstr>")))]
8755   "TARGET_VIS3"
8756   "<vis3_addsub_ss_insn><vbits>\t%1, %2, %0"
8757   [(set_attr "type" "fga")])
8759 (define_insn "fucmp<code>8<P:mode>_vis"
8760   [(set (match_operand:P 0 "register_operand" "=r")
8761         (unspec:P [(gcond:V8QI (match_operand:V8QI 1 "register_operand" "e")
8762                                (match_operand:V8QI 2 "register_operand" "e"))]
8763          UNSPEC_FUCMP))]
8764   "TARGET_VIS3"
8765   "fucmp<code>8\t%1, %2, %0"
8766   [(set_attr "type" "visl")])
8768 (define_insn "*naddsf3"
8769   [(set (match_operand:SF 0 "register_operand" "=f")
8770         (neg:SF (plus:SF (match_operand:SF 1 "register_operand" "f")
8771                          (match_operand:SF 2 "register_operand" "f"))))]
8772   "TARGET_VIS3"
8773   "fnadds\t%1, %2, %0"
8774   [(set_attr "type" "fp")])
8776 (define_insn "*nadddf3"
8777   [(set (match_operand:DF 0 "register_operand" "=e")
8778         (neg:DF (plus:DF (match_operand:DF 1 "register_operand" "e")
8779                          (match_operand:DF 2 "register_operand" "e"))))]
8780   "TARGET_VIS3"
8781   "fnaddd\t%1, %2, %0"
8782   [(set_attr "type" "fp")
8783    (set_attr "fptype" "double")])
8785 (define_insn "*nmulsf3"
8786   [(set (match_operand:SF 0 "register_operand" "=f")
8787         (mult:SF (neg:SF (match_operand:SF 1 "register_operand" "f"))
8788                  (match_operand:SF 2 "register_operand" "f")))]
8789   "TARGET_VIS3"
8790   "fnmuls\t%1, %2, %0"
8791   [(set_attr "type" "fpmul")])
8793 (define_insn "*nmuldf3"
8794   [(set (match_operand:DF 0 "register_operand" "=e")
8795         (mult:DF (neg:DF (match_operand:DF 1 "register_operand" "e"))
8796                  (match_operand:DF 2 "register_operand" "e")))]
8797   "TARGET_VIS3"
8798   "fnmuld\t%1, %2, %0"
8799   [(set_attr "type" "fpmul")
8800    (set_attr "fptype" "double")])
8802 (define_insn "*nmuldf3_extend"
8803   [(set (match_operand:DF 0 "register_operand" "=e")
8804         (mult:DF (neg:DF (float_extend:DF
8805                            (match_operand:SF 1 "register_operand" "f")))
8806                  (float_extend:DF
8807                    (match_operand:SF 2 "register_operand" "f"))))]
8808   "TARGET_VIS3"
8809   "fnsmuld\t%1, %2, %0"
8810   [(set_attr "type" "fpmul")
8811    (set_attr "fptype" "double")])
8813 (define_insn "fhaddsf_vis"
8814   [(set (match_operand:SF 0 "register_operand" "=f")
8815         (unspec:SF [(match_operand:SF 1 "register_operand" "f")
8816                     (match_operand:SF 2 "register_operand" "f")]
8817                    UNSPEC_FHADD))]
8818   "TARGET_VIS3"
8819   "fhadds\t%1, %2, %0"
8820   [(set_attr "type" "fp")])
8822 (define_insn "fhadddf_vis"
8823   [(set (match_operand:DF 0 "register_operand" "=f")
8824         (unspec:DF [(match_operand:DF 1 "register_operand" "f")
8825                     (match_operand:DF 2 "register_operand" "f")]
8826                    UNSPEC_FHADD))]
8827   "TARGET_VIS3"
8828   "fhaddd\t%1, %2, %0"
8829   [(set_attr "type" "fp")
8830    (set_attr "fptype" "double")])
8832 (define_insn "fhsubsf_vis"
8833   [(set (match_operand:SF 0 "register_operand" "=f")
8834         (unspec:SF [(match_operand:SF 1 "register_operand" "f")
8835                     (match_operand:SF 2 "register_operand" "f")]
8836                    UNSPEC_FHSUB))]
8837   "TARGET_VIS3"
8838   "fhsubs\t%1, %2, %0"
8839   [(set_attr "type" "fp")])
8841 (define_insn "fhsubdf_vis"
8842   [(set (match_operand:DF 0 "register_operand" "=f")
8843         (unspec:DF [(match_operand:DF 1 "register_operand" "f")
8844                     (match_operand:DF 2 "register_operand" "f")]
8845                    UNSPEC_FHSUB))]
8846   "TARGET_VIS3"
8847   "fhsubd\t%1, %2, %0"
8848   [(set_attr "type" "fp")
8849    (set_attr "fptype" "double")])
8851 (define_insn "fnhaddsf_vis"
8852   [(set (match_operand:SF 0 "register_operand" "=f")
8853         (neg:SF (unspec:SF [(match_operand:SF 1 "register_operand" "f")
8854                             (match_operand:SF 2 "register_operand" "f")]
8855                            UNSPEC_FHADD)))]
8856   "TARGET_VIS3"
8857   "fnhadds\t%1, %2, %0"
8858   [(set_attr "type" "fp")])
8860 (define_insn "fnhadddf_vis"
8861   [(set (match_operand:DF 0 "register_operand" "=f")
8862         (neg:DF (unspec:DF [(match_operand:DF 1 "register_operand" "f")
8863                             (match_operand:DF 2 "register_operand" "f")]
8864                            UNSPEC_FHADD)))]
8865   "TARGET_VIS3"
8866   "fnhaddd\t%1, %2, %0"
8867   [(set_attr "type" "fp")
8868    (set_attr "fptype" "double")])
8870 (define_expand "umulxhi_vis"
8871   [(set (match_operand:DI 0 "register_operand" "")
8872         (truncate:DI
8873           (lshiftrt:TI
8874             (mult:TI (zero_extend:TI
8875                        (match_operand:DI 1 "arith_operand" ""))
8876                      (zero_extend:TI
8877                        (match_operand:DI 2 "arith_operand" "")))
8878            (const_int 64))))]
8879  "TARGET_VIS3"
8881   if (! TARGET_ARCH64)
8882     {
8883       emit_insn (gen_umulxhi_v8plus (operands[0], operands[1], operands[2]));
8884       DONE;
8885     }
8888 (define_insn "*umulxhi_sp64"
8889   [(set (match_operand:DI 0 "register_operand" "=r")
8890         (truncate:DI
8891           (lshiftrt:TI
8892             (mult:TI (zero_extend:TI
8893                        (match_operand:DI 1 "arith_operand" "%r"))
8894                      (zero_extend:TI
8895                        (match_operand:DI 2 "arith_operand" "rI")))
8896            (const_int 64))))]
8897   "TARGET_VIS3 && TARGET_ARCH64"
8898   "umulxhi\t%1, %2, %0"
8899   [(set_attr "type" "imul")])
8901 (define_insn "umulxhi_v8plus"
8902   [(set (match_operand:DI 0 "register_operand" "=r,h")
8903         (truncate:DI
8904           (lshiftrt:TI
8905             (mult:TI (zero_extend:TI
8906                        (match_operand:DI 1 "arith_operand" "%r,0"))
8907                      (zero_extend:TI
8908                        (match_operand:DI 2 "arith_operand" "rI,rI")))
8909            (const_int 64))))
8910    (clobber (match_scratch:SI 3 "=&h,X"))
8911    (clobber (match_scratch:SI 4 "=&h,X"))]
8912   "TARGET_VIS3 && ! TARGET_ARCH64"
8913   "* return output_v8plus_mult (insn, operands, \"umulxhi\");"
8914   [(set_attr "type" "imul")
8915    (set_attr "length" "9,8")])
8917 (define_expand "xmulx_vis"
8918   [(set (match_operand:DI 0 "register_operand" "")
8919         (truncate:DI
8920           (unspec:TI [(zero_extend:TI
8921                         (match_operand:DI 1 "arith_operand" ""))
8922                       (zero_extend:TI
8923                         (match_operand:DI 2 "arith_operand" ""))]
8924            UNSPEC_XMUL)))]
8925   "TARGET_VIS3"
8927   if (! TARGET_ARCH64)
8928     {
8929       emit_insn (gen_xmulx_v8plus (operands[0], operands[1], operands[2]));
8930       DONE;
8931     }
8934 (define_insn "*xmulx_sp64"
8935   [(set (match_operand:DI 0 "register_operand" "=r")
8936         (truncate:DI
8937           (unspec:TI [(zero_extend:TI
8938                         (match_operand:DI 1 "arith_operand" "%r"))
8939                       (zero_extend:TI
8940                         (match_operand:DI 2 "arith_operand" "rI"))]
8941            UNSPEC_XMUL)))]
8942   "TARGET_VIS3 && TARGET_ARCH64"
8943   "xmulx\t%1, %2, %0"
8944   [(set_attr "type" "imul")])
8946 (define_insn "xmulx_v8plus"
8947   [(set (match_operand:DI 0 "register_operand" "=r,h")
8948         (truncate:DI
8949           (unspec:TI [(zero_extend:TI
8950                         (match_operand:DI 1 "arith_operand" "%r,0"))
8951                       (zero_extend:TI
8952                         (match_operand:DI 2 "arith_operand" "rI,rI"))]
8953            UNSPEC_XMUL)))
8954    (clobber (match_scratch:SI 3 "=&h,X"))
8955    (clobber (match_scratch:SI 4 "=&h,X"))]
8956   "TARGET_VIS3 && ! TARGET_ARCH64"
8957   "* return output_v8plus_mult (insn, operands, \"xmulx\");"
8958   [(set_attr "type" "imul")
8959    (set_attr "length" "9,8")])
8961 (define_expand "xmulxhi_vis"
8962   [(set (match_operand:DI 0 "register_operand" "")
8963         (truncate:DI
8964           (lshiftrt:TI
8965             (unspec:TI [(zero_extend:TI
8966                           (match_operand:DI 1 "arith_operand" ""))
8967                         (zero_extend:TI
8968                           (match_operand:DI 2 "arith_operand" ""))]
8969              UNSPEC_XMUL)
8970            (const_int 64))))]
8971   "TARGET_VIS3"
8973   if (! TARGET_ARCH64)
8974     {
8975       emit_insn (gen_xmulxhi_v8plus (operands[0], operands[1], operands[2]));
8976       DONE;
8977     }
8980 (define_insn "*xmulxhi_sp64"
8981   [(set (match_operand:DI 0 "register_operand" "=r")
8982         (truncate:DI
8983           (lshiftrt:TI
8984             (unspec:TI [(zero_extend:TI
8985                           (match_operand:DI 1 "arith_operand" "%r"))
8986                         (zero_extend:TI
8987                           (match_operand:DI 2 "arith_operand" "rI"))]
8988              UNSPEC_XMUL)
8989            (const_int 64))))]
8990   "TARGET_VIS3 && TARGET_ARCH64"
8991   "xmulxhi\t%1, %2, %0"
8992   [(set_attr "type" "imul")])
8994 (define_insn "xmulxhi_v8plus"
8995   [(set (match_operand:DI 0 "register_operand" "=r,h")
8996         (truncate:DI
8997           (lshiftrt:TI
8998             (unspec:TI [(zero_extend:TI
8999                           (match_operand:DI 1 "arith_operand" "%r,0"))
9000                         (zero_extend:TI
9001                           (match_operand:DI 2 "arith_operand" "rI,rI"))]
9002              UNSPEC_XMUL)
9003            (const_int 64))))
9004    (clobber (match_scratch:SI 3 "=&h,X"))
9005    (clobber (match_scratch:SI 4 "=&h,X"))]
9006   "TARGET_VIS3 && !TARGET_ARCH64"
9007   "* return output_v8plus_mult (insn, operands, \"xmulxhi\");"
9008   [(set_attr "type" "imul")
9009    (set_attr "length" "9,8")])
9011 (include "sync.md")