2015-05-05 Yvan Roux <yvan.roux@linaro.org>
[official-gcc.git] / gcc / config / sparc / sparc.md
blob5ec0bf1777da388cf2b6be9fe8c5ba84167a49b1
1 ;; Machine description for SPARC chip for GCC
2 ;;  Copyright (C) 1987-2015 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    leon3v7,
225    sparclite,
226    f930,
227    f934,
228    sparclite86x,
229    sparclet,
230    tsc701,
231    v9,
232    ultrasparc,
233    ultrasparc3,
234    niagara,
235    niagara2,
236    niagara3,
237    niagara4"
238   (const (symbol_ref "sparc_cpu_attr")))
240 ;; Attribute for the instruction set.
241 ;; At present we only need to distinguish v9/!v9, but for clarity we
242 ;; test TARGET_V8 too.
243 (define_attr "isa" "v7,v8,v9,sparclet"
244  (const
245   (cond [(symbol_ref "TARGET_V9") (const_string "v9")
246          (symbol_ref "TARGET_V8") (const_string "v8")
247          (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
248         (const_string "v7"))))
250 (define_attr "cpu_feature" "none,fpu,fpunotv9,v9,vis,vis3" (const_string "none"))
252 (define_attr "enabled" ""
253   (cond [(eq_attr "cpu_feature" "none") (const_int 1)
254          (eq_attr "cpu_feature" "fpu") (symbol_ref "TARGET_FPU")
255          (eq_attr "cpu_feature" "fpunotv9") (symbol_ref "TARGET_FPU && ! TARGET_V9")
256          (eq_attr "cpu_feature" "v9") (symbol_ref "TARGET_V9")
257          (eq_attr "cpu_feature" "vis") (symbol_ref "TARGET_VIS")
258          (eq_attr "cpu_feature" "vis3") (symbol_ref "TARGET_VIS3")]
259         (const_int 0)))
261 ;; Insn type.
262 (define_attr "type"
263   "ialu,compare,shift,
264    load,sload,store,
265    uncond_branch,branch,call,sibcall,call_no_delay_slot,return,
266    cbcond,uncond_cbcond,
267    imul,idiv,
268    fpload,fpstore,
269    fp,fpmove,
270    fpcmove,fpcrmove,
271    fpcmp,
272    fpmul,fpdivs,fpdivd,
273    fpsqrts,fpsqrtd,
274    fga,visl,vismv,fgm_pack,fgm_mul,pdist,pdistn,edge,edgen,gsr,array,
275    cmove,
276    ialuX,
277    multi,savew,flushw,iflush,trap"
278   (const_string "ialu"))
280 ;; True if branch/call has empty delay slot and will emit a nop in it
281 (define_attr "empty_delay_slot" "false,true"
282   (symbol_ref "(empty_delay_slot (insn)
283                 ? EMPTY_DELAY_SLOT_TRUE : EMPTY_DELAY_SLOT_FALSE)"))
285 ;; True if we are making use of compare-and-branch instructions.
286 ;; True if we should emit a nop after a cbcond instruction
287 (define_attr "emit_cbcond_nop" "false,true"
288   (symbol_ref "(emit_cbcond_nop (insn)
289                 ? EMIT_CBCOND_NOP_TRUE : EMIT_CBCOND_NOP_FALSE)"))
291 (define_attr "branch_type" "none,icc,fcc,reg"
292   (const_string "none"))
294 (define_attr "pic" "false,true"
295   (symbol_ref "(flag_pic != 0
296                 ? PIC_TRUE : PIC_FALSE)"))
298 (define_attr "calls_alloca" "false,true"
299   (symbol_ref "(cfun->calls_alloca != 0
300                 ? CALLS_ALLOCA_TRUE : CALLS_ALLOCA_FALSE)"))
302 (define_attr "calls_eh_return" "false,true"
303    (symbol_ref "(crtl->calls_eh_return != 0
304                  ? CALLS_EH_RETURN_TRUE : CALLS_EH_RETURN_FALSE)"))
306 (define_attr "leaf_function" "false,true"
307   (symbol_ref "(crtl->uses_only_leaf_regs != 0
308                 ? LEAF_FUNCTION_TRUE : LEAF_FUNCTION_FALSE)"))
310 (define_attr "delayed_branch" "false,true"
311   (symbol_ref "(flag_delayed_branch != 0
312                 ? DELAYED_BRANCH_TRUE : DELAYED_BRANCH_FALSE)"))
314 (define_attr "flat" "false,true"
315   (symbol_ref "(TARGET_FLAT != 0
316                 ? FLAT_TRUE : FLAT_FALSE)"))
318 (define_attr "fix_ut699" "false,true"
319    (symbol_ref "(sparc_fix_ut699 != 0
320                  ? FIX_UT699_TRUE : FIX_UT699_FALSE)"))
322 ;; Length (in # of insns).
323 ;; Beware that setting a length greater or equal to 3 for conditional branches
324 ;; has a side-effect (see output_cbranch and output_v9branch).
325 (define_attr "length" ""
326   (cond [(eq_attr "type" "uncond_branch,call")
327            (if_then_else (eq_attr "empty_delay_slot" "true")
328              (const_int 2)
329              (const_int 1))
330          (eq_attr "type" "sibcall")
331            (if_then_else (eq_attr "leaf_function" "true")
332              (if_then_else (eq_attr "empty_delay_slot" "true")
333                (const_int 3)
334                (const_int 2))
335              (if_then_else (eq_attr "empty_delay_slot" "true")
336                (const_int 2)
337                (const_int 1)))
338          (eq_attr "branch_type" "icc")
339            (if_then_else (match_operand 0 "noov_compare64_operator" "")
340              (if_then_else (lt (pc) (match_dup 1))
341                (if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000))
342                  (if_then_else (eq_attr "empty_delay_slot" "true")
343                    (const_int 2)
344                    (const_int 1))
345                  (if_then_else (eq_attr "empty_delay_slot" "true")
346                    (const_int 4)
347                    (const_int 3)))
348                (if_then_else (lt (minus (pc) (match_dup 1)) (const_int 260000))
349                  (if_then_else (eq_attr "empty_delay_slot" "true")
350                    (const_int 2)
351                    (const_int 1))
352                  (if_then_else (eq_attr "empty_delay_slot" "true")
353                    (const_int 4)
354                    (const_int 3))))
355              (if_then_else (eq_attr "empty_delay_slot" "true")
356                (const_int 2)
357                (const_int 1)))
358          (eq_attr "branch_type" "fcc")
359            (if_then_else (match_operand 0 "fcc0_register_operand" "")
360              (if_then_else (eq_attr "empty_delay_slot" "true")
361                (if_then_else (not (match_test "TARGET_V9"))
362                  (const_int 3)
363                  (const_int 2))
364                (if_then_else (not (match_test "TARGET_V9"))
365                  (const_int 2)
366                  (const_int 1)))
367              (if_then_else (lt (pc) (match_dup 2))
368                (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000))
369                  (if_then_else (eq_attr "empty_delay_slot" "true")
370                    (const_int 2)
371                    (const_int 1))
372                  (if_then_else (eq_attr "empty_delay_slot" "true")
373                    (const_int 4)
374                    (const_int 3)))
375                (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000))
376                  (if_then_else (eq_attr "empty_delay_slot" "true")
377                    (const_int 2)
378                    (const_int 1))
379                  (if_then_else (eq_attr "empty_delay_slot" "true")
380                    (const_int 4)
381                    (const_int 3)))))
382          (eq_attr "branch_type" "reg")
383            (if_then_else (lt (pc) (match_dup 2))
384              (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000))
385                (if_then_else (eq_attr "empty_delay_slot" "true")
386                  (const_int 2)
387                  (const_int 1))
388                (if_then_else (eq_attr "empty_delay_slot" "true")
389                  (const_int 4)
390                  (const_int 3)))
391              (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000))
392                (if_then_else (eq_attr "empty_delay_slot" "true")
393                  (const_int 2)
394                  (const_int 1))
395                (if_then_else (eq_attr "empty_delay_slot" "true")
396                  (const_int 4)
397                  (const_int 3))))
398          (eq_attr "type" "cbcond")
399            (if_then_else (lt (pc) (match_dup 3))
400              (if_then_else (lt (minus (match_dup 3) (pc)) (const_int 500))
401                (if_then_else (eq_attr "emit_cbcond_nop" "true")
402                  (const_int 2)
403                  (const_int 1))
404                (const_int 4))
405              (if_then_else (lt (minus (pc) (match_dup 3)) (const_int 500))
406                (if_then_else (eq_attr "emit_cbcond_nop" "true")
407                  (const_int 2)
408                  (const_int 1))
409                (const_int 4)))
410          (eq_attr "type" "uncond_cbcond")
411            (if_then_else (lt (pc) (match_dup 0))
412              (if_then_else (lt (minus (match_dup 0) (pc)) (const_int 500))
413                (if_then_else (eq_attr "emit_cbcond_nop" "true")
414                  (const_int 2)
415                  (const_int 1))
416                (const_int 1))
417              (if_then_else (lt (minus (pc) (match_dup 0)) (const_int 500))
418                (if_then_else (eq_attr "emit_cbcond_nop" "true")
419                  (const_int 2)
420                  (const_int 1))
421                (const_int 1)))
422          ] (const_int 1)))
424 ;; FP precision.
425 (define_attr "fptype" "single,double"
426   (const_string "single"))
428 ;; FP precision specific to the UT699.
429 (define_attr "fptype_ut699" "none,single"
430   (const_string "none"))
432 ;; UltraSPARC-III integer load type.
433 (define_attr "us3load_type" "2cycle,3cycle"
434   (const_string "2cycle"))
436 (define_asm_attributes
437   [(set_attr "length" "2")
438    (set_attr "type" "multi")])
440 ;; Attributes for branch scheduling
441 (define_attr "in_call_delay" "false,true"
442   (symbol_ref "(eligible_for_call_delay (insn)
443                 ? IN_CALL_DELAY_TRUE : IN_CALL_DELAY_FALSE)"))
445 (define_attr "in_sibcall_delay" "false,true"
446   (symbol_ref "(eligible_for_sibcall_delay (insn)
447                 ? IN_SIBCALL_DELAY_TRUE : IN_SIBCALL_DELAY_FALSE)"))
449 (define_attr "in_return_delay" "false,true"
450   (symbol_ref "(eligible_for_return_delay (insn)
451                 ? IN_RETURN_DELAY_TRUE : IN_RETURN_DELAY_FALSE)"))
453 ;; ??? !v9: Should implement the notion of predelay slots for floating-point
454 ;; branches.  This would allow us to remove the nop always inserted before
455 ;; a floating point branch.
457 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
458 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
459 ;; This is because doing so will add several pipeline stalls to the path
460 ;; that the load/store did not come from.  Unfortunately, there is no way
461 ;; to prevent fill_eager_delay_slots from using load/store without completely
462 ;; disabling them.  For the SPEC benchmark set, this is a serious lose,
463 ;; because it prevents us from moving back the final store of inner loops.
465 (define_attr "in_branch_delay" "false,true"
466   (cond [(eq_attr "type" "uncond_branch,branch,cbcond,uncond_cbcond,call,sibcall,call_no_delay_slot,multi")
467            (const_string "false")
468          (and (eq_attr "fix_ut699" "true") (eq_attr "type" "load,sload"))
469            (const_string "false")
470          (and (eq_attr "fix_ut699" "true")
471               (and (eq_attr "type" "fpload,fp,fpmove,fpmul,fpdivs,fpsqrts")
472                    (ior (eq_attr "fptype" "single")
473                         (eq_attr "fptype_ut699" "single"))))
474            (const_string "false")
475          (eq_attr "length" "1")
476            (const_string "true")
477         ] (const_string "false")))
479 (define_delay (eq_attr "type" "call")
480   [(eq_attr "in_call_delay" "true") (nil) (nil)])
482 (define_delay (eq_attr "type" "sibcall")
483   [(eq_attr "in_sibcall_delay" "true") (nil) (nil)])
485 (define_delay (eq_attr "type" "return")
486   [(eq_attr "in_return_delay" "true") (nil) (nil)])
488 (define_delay (eq_attr "type" "branch")
489   [(eq_attr "in_branch_delay" "true") (nil) (eq_attr "in_branch_delay" "true")])
491 (define_delay (eq_attr "type" "uncond_branch")
492   [(eq_attr "in_branch_delay" "true") (nil) (nil)])
495 ;; Include SPARC DFA schedulers
497 (include "cypress.md")
498 (include "supersparc.md")
499 (include "hypersparc.md")
500 (include "leon.md")
501 (include "sparclet.md")
502 (include "ultra1_2.md")
503 (include "ultra3.md")
504 (include "niagara.md")
505 (include "niagara2.md")
506 (include "niagara4.md")
509 ;; Operand and operator predicates and constraints
511 (include "predicates.md")
512 (include "constraints.md")
515 ;; Compare instructions.
517 ;; These are just the DEFINE_INSNs to match the patterns and the
518 ;; DEFINE_SPLITs for some of the scc insns that actually require
519 ;; more than one machine instruction.  DEFINE_EXPANDs are further down.
521 ;; The compare DEFINE_INSNs.
523 (define_insn "*cmpsi_insn"
524   [(set (reg:CC CC_REG)
525         (compare:CC (match_operand:SI 0 "register_operand" "r")
526                     (match_operand:SI 1 "arith_operand" "rI")))]
527   ""
528   "cmp\t%0, %1"
529   [(set_attr "type" "compare")])
531 (define_insn "*cmpdi_sp64"
532   [(set (reg:CCX CC_REG)
533         (compare:CCX (match_operand:DI 0 "register_operand" "r")
534                      (match_operand:DI 1 "arith_operand" "rI")))]
535   "TARGET_ARCH64"
536   "cmp\t%0, %1"
537   [(set_attr "type" "compare")])
539 (define_insn "*cmpsf_fpe"
540   [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
541         (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
542                        (match_operand:SF 2 "register_operand" "f")))]
543   "TARGET_FPU"
545   if (TARGET_V9)
546     return "fcmpes\t%0, %1, %2";
547   return "fcmpes\t%1, %2";
549   [(set_attr "type" "fpcmp")])
551 (define_insn "*cmpdf_fpe"
552   [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
553         (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
554                        (match_operand:DF 2 "register_operand" "e")))]
555   "TARGET_FPU"
557   if (TARGET_V9)
558     return "fcmped\t%0, %1, %2";
559   return "fcmped\t%1, %2";
561   [(set_attr "type" "fpcmp")
562    (set_attr "fptype" "double")])
564 (define_insn "*cmptf_fpe"
565   [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
566         (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
567                        (match_operand:TF 2 "register_operand" "e")))]
568   "TARGET_FPU && TARGET_HARD_QUAD"
570   if (TARGET_V9)
571     return "fcmpeq\t%0, %1, %2";
572   return "fcmpeq\t%1, %2";
574   [(set_attr "type" "fpcmp")])
576 (define_insn "*cmpsf_fp"
577   [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
578         (compare:CCFP (match_operand:SF 1 "register_operand" "f")
579                       (match_operand:SF 2 "register_operand" "f")))]
580   "TARGET_FPU"
582   if (TARGET_V9)
583     return "fcmps\t%0, %1, %2";
584   return "fcmps\t%1, %2";
586   [(set_attr "type" "fpcmp")])
588 (define_insn "*cmpdf_fp"
589   [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
590         (compare:CCFP (match_operand:DF 1 "register_operand" "e")
591                       (match_operand:DF 2 "register_operand" "e")))]
592   "TARGET_FPU"
594   if (TARGET_V9)
595     return "fcmpd\t%0, %1, %2";
596   return "fcmpd\t%1, %2";
598   [(set_attr "type" "fpcmp")
599    (set_attr "fptype" "double")])
601 (define_insn "*cmptf_fp"
602   [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
603         (compare:CCFP (match_operand:TF 1 "register_operand" "e")
604                       (match_operand:TF 2 "register_operand" "e")))]
605   "TARGET_FPU && TARGET_HARD_QUAD"
607   if (TARGET_V9)
608     return "fcmpq\t%0, %1, %2";
609   return "fcmpq\t%1, %2";
611   [(set_attr "type" "fpcmp")])
613 ;; Next come the scc insns.
615 ;; Note that the boolean result (operand 0) takes on DImode
616 ;; (not SImode) when TARGET_ARCH64.
618 (define_expand "cstoresi4"
619   [(use (match_operator 1 "comparison_operator"
620          [(match_operand:SI 2 "compare_operand" "")
621           (match_operand:SI 3 "arith_operand" "")]))
622    (clobber (match_operand:SI 0 "cstore_result_operand"))]
623   ""
625   if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
626     operands[2] = force_reg (SImode, operands[2]);
627   if (emit_scc_insn (operands)) DONE; else FAIL;
630 (define_expand "cstoredi4"
631   [(use (match_operator 1 "comparison_operator"
632          [(match_operand:DI 2 "compare_operand" "")
633           (match_operand:DI 3 "arith_operand" "")]))
634    (clobber (match_operand:SI 0 "cstore_result_operand"))]
635   "TARGET_ARCH64"
637   if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
638     operands[2] = force_reg (DImode, operands[2]);
639   if (emit_scc_insn (operands)) DONE; else FAIL;
642 (define_expand "cstore<F:mode>4"
643   [(use (match_operator 1 "comparison_operator"
644          [(match_operand:F 2 "register_operand" "")
645           (match_operand:F 3 "register_operand" "")]))
646    (clobber (match_operand:SI 0 "cstore_result_operand"))]
647   "TARGET_FPU"
648   { if (emit_scc_insn (operands)) DONE; else FAIL; })
652 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
653 ;; generate addcc/subcc instructions.
655 (define_expand "seqsi<P:mode>_special"
656   [(set (match_dup 3)
657         (xor:SI (match_operand:SI 1 "register_operand" "")
658                 (match_operand:SI 2 "register_operand" "")))
659    (parallel [(set (match_operand:P 0 "register_operand" "")
660                    (eq:P (match_dup 3) (const_int 0)))
661               (clobber (reg:CC CC_REG))])]
662   ""
663   { operands[3] = gen_reg_rtx (SImode); })
665 (define_expand "seqdi_special"
666   [(set (match_dup 3)
667         (xor:DI (match_operand:DI 1 "register_operand" "")
668                 (match_operand:DI 2 "register_operand" "")))
669    (set (match_operand:DI 0 "register_operand" "")
670         (eq:DI (match_dup 3) (const_int 0)))]
671   "TARGET_ARCH64"
672   { operands[3] = gen_reg_rtx (DImode); })
674 (define_expand "snesi<P:mode>_special"
675   [(set (match_dup 3)
676         (xor:SI (match_operand:SI 1 "register_operand" "")
677                 (match_operand:SI 2 "register_operand" "")))
678    (parallel [(set (match_operand:P 0 "register_operand" "")
679                    (ne:P (match_dup 3) (const_int 0)))
680               (clobber (reg:CC CC_REG))])]
681   ""
682   { operands[3] = gen_reg_rtx (SImode); })
684 (define_expand "snedi_special"
685   [(set (match_dup 3)
686         (xor:DI (match_operand:DI 1 "register_operand" "")
687                 (match_operand:DI 2 "register_operand" "")))
688    (set (match_operand:DI 0 "register_operand" "")
689         (ne:DI (match_dup 3) (const_int 0)))]
690   "TARGET_ARCH64 && ! TARGET_VIS3"
691   { operands[3] = gen_reg_rtx (DImode); })
693 (define_expand "snedi_special_vis3"
694   [(set (match_dup 3)
695         (xor:DI (match_operand:DI 1 "register_operand" "")
696                 (match_operand:DI 2 "register_operand" "")))
697    (parallel [(set (match_operand:DI 0 "register_operand" "")
698                    (ne:DI (match_dup 3) (const_int 0)))
699               (clobber (reg:CCX CC_REG))])]
700   "TARGET_ARCH64 && TARGET_VIS3"
701   { operands[3] = gen_reg_rtx (DImode); })
704 ;; Now the DEFINE_INSNs for the scc cases.
706 ;; The SEQ and SNE patterns are special because they can be done
707 ;; without any branching and do not involve a COMPARE.  We want
708 ;; them to always use the splits below so the results can be
709 ;; scheduled.
711 (define_insn_and_split "*snesi<P:mode>_zero"
712   [(set (match_operand:P 0 "register_operand" "=r")
713         (ne:P (match_operand:SI 1 "register_operand" "r")
714                (const_int 0)))
715    (clobber (reg:CC CC_REG))]
716   ""
717   "#"
718   ""
719   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
720                                            (const_int 0)))
721    (set (match_dup 0) (ltu:P (reg:CC CC_REG) (const_int 0)))]
722   ""
723   [(set_attr "length" "2")])
725 (define_insn_and_split "*neg_snesisi_zero"
726   [(set (match_operand:SI 0 "register_operand" "=r")
727         (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
728                        (const_int 0))))
729    (clobber (reg:CC CC_REG))]
730   ""
731   "#"
732   ""
733   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
734                                            (const_int 0)))
735    (set (match_dup 0) (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0))))]
736   ""
737   [(set_attr "length" "2")])
739 (define_insn_and_split "*neg_snesidi_zero"
740   [(set (match_operand:DI 0 "register_operand" "=r")
741         (neg:DI (ne:DI (match_operand:SI 1 "register_operand" "r")
742                        (const_int 0))))
743    (clobber (reg:CC CC_REG))]
744   "TARGET_ARCH64"
745   "#"
746   ""
747   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
748                                            (const_int 0)))
749    (set (match_dup 0) (sign_extend:DI (neg:SI (ltu:SI (reg:CC CC_REG)
750                                                       (const_int 0)))))]
751   ""
752   [(set_attr "length" "2")])
754 (define_insn_and_split "*snedi_zero"
755   [(set (match_operand:DI 0 "register_operand" "=&r")
756         (ne:DI (match_operand:DI 1 "register_operand" "r")
757                (const_int 0)))]
758   "TARGET_ARCH64 && ! TARGET_VIS3"
759   "#"
760   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
761   [(set (match_dup 0) (const_int 0))
762    (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
763                                               (const_int 0))
764                                        (const_int 1)
765                                        (match_dup 0)))]
766   ""
767   [(set_attr "length" "2")])
769 (define_insn_and_split "*snedi_zero_vis3"
770   [(set (match_operand:DI 0 "register_operand" "=r")
771         (ne:DI (match_operand:DI 1 "register_operand" "r")
772                (const_int 0)))
773    (clobber (reg:CCX CC_REG))]
774   "TARGET_ARCH64 && TARGET_VIS3"
775   "#"
776   ""
777   [(set (reg:CCX_NOOV CC_REG) (compare:CCX_NOOV (neg:DI (match_dup 1))
778                                                 (const_int 0)))
779    (set (match_dup 0) (ltu:DI (reg:CCX CC_REG) (const_int 0)))]
780   ""
781   [(set_attr "length" "2")])
783 (define_insn_and_split "*neg_snedi_zero"
784   [(set (match_operand:DI 0 "register_operand" "=&r")
785         (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
786                        (const_int 0))))]
787   "TARGET_ARCH64"
788   "#"
789   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
790   [(set (match_dup 0) (const_int 0))
791    (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
792                                               (const_int 0))
793                                        (const_int -1)
794                                        (match_dup 0)))]
795   ""
796   [(set_attr "length" "2")])
798 (define_insn_and_split "*snedi_zero_trunc"
799   [(set (match_operand:SI 0 "register_operand" "=&r")
800         (ne:SI (match_operand:DI 1 "register_operand" "r")
801                (const_int 0)))]
802   "TARGET_ARCH64 && ! TARGET_VIS3"
803   "#"
804   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
805   [(set (match_dup 0) (const_int 0))
806    (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
807                                               (const_int 0))
808                                        (const_int 1)
809                                        (match_dup 0)))]
810   ""
811   [(set_attr "length" "2")])
813 (define_insn_and_split "*snedi_zero_trunc_vis3"
814   [(set (match_operand:SI 0 "register_operand" "=r")
815         (ne:SI (match_operand:DI 1 "register_operand" "r")
816                (const_int 0)))
817    (clobber (reg:CCX CC_REG))]
818   "TARGET_ARCH64 && TARGET_VIS3"
819   "#"
820   ""
821   [(set (reg:CCX_NOOV CC_REG) (compare:CCX_NOOV (neg:DI (match_dup 1))
822                                                 (const_int 0)))
823    (set (match_dup 0) (ltu:SI (reg:CCX CC_REG) (const_int 0)))]
824   ""
825   [(set_attr "length" "2")])
827 (define_insn_and_split "*seqsi<P:mode>_zero"
828   [(set (match_operand:P 0 "register_operand" "=r")
829         (eq:P (match_operand:SI 1 "register_operand" "r")
830                (const_int 0)))
831    (clobber (reg:CC CC_REG))]
832   ""
833   "#"
834   ""
835   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
836                                            (const_int 0)))
837    (set (match_dup 0) (geu:P (reg:CC CC_REG) (const_int 0)))]
838   ""
839   [(set_attr "length" "2")])
841 (define_insn_and_split "*neg_seqsisi_zero"
842   [(set (match_operand:SI 0 "register_operand" "=r")
843         (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
844                        (const_int 0))))
845    (clobber (reg:CC CC_REG))]
846   ""
847   "#"
848   ""
849   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
850                                            (const_int 0)))
851    (set (match_dup 0) (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0))))]
852   ""
853   [(set_attr "length" "2")])
855 (define_insn_and_split "*neg_seqsidi_zero"
856   [(set (match_operand:DI 0 "register_operand" "=r")
857         (neg:DI (eq:DI (match_operand:SI 1 "register_operand" "r")
858                        (const_int 0))))
859    (clobber (reg:CC CC_REG))]
860   "TARGET_ARCH64"
861   "#"
862   "&& 1"
863   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
864                                            (const_int 0)))
865    (set (match_dup 0) (sign_extend:DI (neg:SI (geu:SI (reg:CC CC_REG)
866                                                       (const_int 0)))))]
867   ""
868   [(set_attr "length" "2")])
870 (define_insn_and_split "*seqdi_zero"
871   [(set (match_operand:DI 0 "register_operand" "=&r")
872         (eq:DI (match_operand:DI 1 "register_operand" "r")
873                (const_int 0)))]
874   "TARGET_ARCH64"
875   "#"
876   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
877   [(set (match_dup 0) (const_int 0))
878    (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
879                                               (const_int 0))
880                                        (const_int 1)
881                                        (match_dup 0)))]
882   ""
883   [(set_attr "length" "2")])
885 (define_insn_and_split "*neg_seqdi_zero"
886   [(set (match_operand:DI 0 "register_operand" "=&r")
887         (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
888                        (const_int 0))))]
889   "TARGET_ARCH64"
890   "#"
891   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
892   [(set (match_dup 0) (const_int 0))
893    (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
894                                               (const_int 0))
895                                        (const_int -1)
896                                        (match_dup 0)))]
897   ""
898   [(set_attr "length" "2")]) 
900 (define_insn_and_split "*seqdi_zero_trunc"
901   [(set (match_operand:SI 0 "register_operand" "=&r")
902         (eq:SI (match_operand:DI 1 "register_operand" "r")
903                (const_int 0)))]
904   "TARGET_ARCH64"
905   "#"
906   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
907   [(set (match_dup 0) (const_int 0))
908    (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
909                                               (const_int 0))
910                                        (const_int 1)
911                                        (match_dup 0)))]
912   ""
913   [(set_attr "length" "2")])
915 ;; We can also do (x + (i == 0)) and related, so put them in.
916 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
917 ;; versions for v9.
919 (define_insn_and_split "*x_plus_i_ne_0"
920   [(set (match_operand:SI 0 "register_operand" "=r")
921         (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
922                         (const_int 0))
923                  (match_operand:SI 2 "register_operand" "r")))
924    (clobber (reg:CC CC_REG))]
925   ""
926   "#"
927   ""
928   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
929                                            (const_int 0)))
930    (set (match_dup 0) (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
931                                (match_dup 2)))]
932   ""
933   [(set_attr "length" "2")])
935 (define_insn_and_split "*x_minus_i_ne_0"
936   [(set (match_operand:SI 0 "register_operand" "=r")
937         (minus:SI (match_operand:SI 2 "register_operand" "r")
938                   (ne:SI (match_operand:SI 1 "register_operand" "r")
939                          (const_int 0))))
940    (clobber (reg:CC CC_REG))]
941   ""
942   "#"
943   ""
944   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
945                                            (const_int 0)))
946    (set (match_dup 0) (minus:SI (match_dup 2)
947                                 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
948   ""
949   [(set_attr "length" "2")])
951 (define_insn_and_split "*x_plus_i_eq_0"
952   [(set (match_operand:SI 0 "register_operand" "=r")
953         (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
954                         (const_int 0))
955                  (match_operand:SI 2 "register_operand" "r")))
956    (clobber (reg:CC CC_REG))]
957   ""
958   "#"
959   ""
960   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
961                                            (const_int 0)))
962    (set (match_dup 0) (plus:SI (geu:SI (reg:CC CC_REG) (const_int 0))
963                                (match_dup 2)))]
964   ""
965   [(set_attr "length" "2")])
967 (define_insn_and_split "*x_minus_i_eq_0"
968   [(set (match_operand:SI 0 "register_operand" "=r")
969         (minus:SI (match_operand:SI 2 "register_operand" "r")
970                   (eq:SI (match_operand:SI 1 "register_operand" "r")
971                          (const_int 0))))
972    (clobber (reg:CC CC_REG))]
973   ""
974   "#"
975   ""
976   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
977                                            (const_int 0)))
978    (set (match_dup 0) (minus:SI (match_dup 2)
979                                 (geu:SI (reg:CC CC_REG) (const_int 0))))]
980   ""
981   [(set_attr "length" "2")])
983 ;; We can also do GEU and LTU directly, but these operate after a compare.
984 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
985 ;; versions for v9.
987 (define_insn "*sltu<P:mode>_insn"
988   [(set (match_operand:P 0 "register_operand" "=r")
989         (ltu:P (reg:CC CC_REG) (const_int 0)))]
990   ""
991   "addx\t%%g0, 0, %0"
992   [(set_attr "type" "ialuX")])
994 (define_insn "*sltu_insn_vis3"
995   [(set (match_operand:DI 0 "register_operand" "=r")
996         (ltu:DI (reg:CCX CC_REG) (const_int 0)))]
997   "TARGET_ARCH64 && TARGET_VIS3"
998   "addxc\t%%g0, %%g0, %0"
999   [(set_attr "type" "ialuX")])
1001 (define_insn "*sltu_insn_vis3_trunc"
1002   [(set (match_operand:SI 0 "register_operand" "=r")
1003         (ltu:SI (reg:CCX CC_REG) (const_int 0)))]
1004   "TARGET_ARCH64 && TARGET_VIS3"
1005   "addxc\t%%g0, %%g0, %0"
1006   [(set_attr "type" "ialuX")])
1008 (define_insn "*neg_sltusi_insn"
1009   [(set (match_operand:SI 0 "register_operand" "=r")
1010         (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0))))]
1011   ""
1012   "subx\t%%g0, 0, %0"
1013   [(set_attr "type" "ialuX")])
1015 (define_insn "*neg_sltudi_insn"
1016   [(set (match_operand:DI 0 "register_operand" "=r")
1017         (sign_extend:DI (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0)))))]
1018   "TARGET_ARCH64"
1019   "subx\t%%g0, 0, %0"
1020   [(set_attr "type" "ialuX")])
1022 (define_insn "*neg_sltu_minus_x"
1023   [(set (match_operand:SI 0 "register_operand" "=r")
1024         (minus:SI (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0)))
1025                   (match_operand:SI 1 "arith_operand" "rI")))]
1026   ""
1027   "subx\t%%g0, %1, %0"
1028   [(set_attr "type" "ialuX")])
1030 (define_insn "*neg_sltu_plus_x"
1031   [(set (match_operand:SI 0 "register_operand" "=r")
1032         (neg:SI (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
1033                          (match_operand:SI 1 "arith_operand" "rI"))))]
1034   ""
1035   "subx\t%%g0, %1, %0"
1036   [(set_attr "type" "ialuX")])
1038 (define_insn "*sgeu<P:mode>_insn"
1039   [(set (match_operand:P 0 "register_operand" "=r")
1040         (geu:P (reg:CC CC_REG) (const_int 0)))]
1041   ""
1042   "subx\t%%g0, -1, %0"
1043   [(set_attr "type" "ialuX")])
1045 (define_insn "*neg_sgeusi_insn"
1046   [(set (match_operand:SI 0 "register_operand" "=r")
1047         (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0))))]
1048   ""
1049   "addx\t%%g0, -1, %0"
1050   [(set_attr "type" "ialuX")])
1052 (define_insn "*neg_sgeudi_insn"
1053   [(set (match_operand:DI 0 "register_operand" "=r")
1054         (sign_extend:DI (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0)))))]
1055   "TARGET_ARCH64"
1056   "addx\t%%g0, -1, %0"
1057   [(set_attr "type" "ialuX")])
1059 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
1060 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1061 ;; versions for v9.
1063 (define_insn "*sltu_plus_x"
1064   [(set (match_operand:SI 0 "register_operand" "=r")
1065         (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
1066                  (match_operand:SI 1 "arith_operand" "rI")))]
1067   ""
1068   "addx\t%%g0, %1, %0"
1069   [(set_attr "type" "ialuX")])
1071 (define_insn "*sltu_plus_x_plus_y"
1072   [(set (match_operand:SI 0 "register_operand" "=r")
1073         (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
1074                  (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1075                           (match_operand:SI 2 "arith_operand" "rI"))))]
1076   ""
1077   "addx\t%1, %2, %0"
1078   [(set_attr "type" "ialuX")])
1080 (define_insn "*x_minus_sltu"
1081   [(set (match_operand:SI 0 "register_operand" "=r")
1082         (minus:SI (match_operand:SI 1 "register_operand" "r")
1083                   (ltu:SI (reg:CC CC_REG) (const_int 0))))]
1084   ""
1085   "subx\t%1, 0, %0"
1086   [(set_attr "type" "ialuX")])
1088 ;; ??? Combine should canonicalize these next two to the same pattern.
1089 (define_insn "*x_minus_y_minus_sltu"
1090   [(set (match_operand:SI 0 "register_operand" "=r")
1091         (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
1092                             (match_operand:SI 2 "arith_operand" "rI"))
1093                   (ltu:SI (reg:CC CC_REG) (const_int 0))))]
1094   ""
1095   "subx\t%r1, %2, %0"
1096   [(set_attr "type" "ialuX")])
1098 (define_insn "*x_minus_sltu_plus_y"
1099   [(set (match_operand:SI 0 "register_operand" "=r")
1100         (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
1101                   (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
1102                            (match_operand:SI 2 "arith_operand" "rI"))))]
1103   ""
1104   "subx\t%r1, %2, %0"
1105   [(set_attr "type" "ialuX")])
1107 (define_insn "*sgeu_plus_x"
1108   [(set (match_operand:SI 0 "register_operand" "=r")
1109         (plus:SI (geu:SI (reg:CC CC_REG) (const_int 0))
1110                  (match_operand:SI 1 "register_operand" "r")))]
1111   ""
1112   "subx\t%1, -1, %0"
1113   [(set_attr "type" "ialuX")])
1115 (define_insn "*x_minus_sgeu"
1116   [(set (match_operand:SI 0 "register_operand" "=r")
1117         (minus:SI (match_operand:SI 1 "register_operand" "r")
1118                   (geu:SI (reg:CC CC_REG) (const_int 0))))]
1119   ""
1120   "addx\t%1, -1, %0"
1121   [(set_attr "type" "ialuX")])
1123 (define_split
1124   [(set (match_operand:SI 0 "register_operand" "")
1125         (match_operator:SI 2 "noov_compare_operator"
1126                            [(match_operand 1 "icc_or_fcc_register_operand" "")
1127                             (const_int 0)]))]
1128   "TARGET_V9
1129    && REGNO (operands[1]) == SPARC_ICC_REG
1130    && (GET_MODE (operands[1]) == CCXmode
1131        /* 32-bit LTU/GEU are better implemented using addx/subx.  */
1132        || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1133   [(set (match_dup 0) (const_int 0))
1134    (set (match_dup 0)
1135         (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1136                          (const_int 1)
1137                          (match_dup 0)))]
1138   "")
1141 ;; These control RTL generation for conditional jump insns
1143 (define_expand "cbranchcc4"
1144   [(set (pc)
1145         (if_then_else (match_operator 0 "comparison_operator"
1146                           [(match_operand 1 "compare_operand" "")
1147                            (match_operand 2 "const_zero_operand" "")])
1148                       (label_ref (match_operand 3 "" ""))
1149                       (pc)))]
1150   ""
1151   "")
1153 (define_expand "cbranchsi4"
1154   [(use (match_operator 0 "comparison_operator"
1155          [(match_operand:SI 1 "compare_operand" "")
1156           (match_operand:SI 2 "arith_operand" "")]))
1157    (use (match_operand 3 ""))]
1158   ""
1160   if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
1161     operands[1] = force_reg (SImode, operands[1]);
1162   emit_conditional_branch_insn (operands);
1163   DONE;
1166 (define_expand "cbranchdi4"
1167   [(use (match_operator 0 "comparison_operator"
1168          [(match_operand:DI 1 "compare_operand" "")
1169           (match_operand:DI 2 "arith_operand" "")]))
1170    (use (match_operand 3 ""))]
1171   "TARGET_ARCH64"
1173   if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
1174     operands[1] = force_reg (DImode, operands[1]);
1175   emit_conditional_branch_insn (operands);
1176   DONE;
1179 (define_expand "cbranch<F:mode>4"
1180   [(use (match_operator 0 "comparison_operator"
1181          [(match_operand:F 1 "register_operand" "")
1182           (match_operand:F 2 "register_operand" "")]))
1183    (use (match_operand 3 ""))]
1184   "TARGET_FPU"
1185   { emit_conditional_branch_insn (operands); DONE; })
1188 ;; Now match both normal and inverted jump.
1190 ;; XXX fpcmp nop braindamage
1191 (define_insn "*normal_branch"
1192   [(set (pc)
1193         (if_then_else (match_operator 0 "noov_compare_operator"
1194                                       [(reg CC_REG) (const_int 0)])
1195                       (label_ref (match_operand 1 "" ""))
1196                       (pc)))]
1197   ""
1199   return output_cbranch (operands[0], operands[1], 1, 0,
1200                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1201                          insn);
1203   [(set_attr "type" "branch")
1204    (set_attr "branch_type" "icc")])
1206 ;; XXX fpcmp nop braindamage
1207 (define_insn "*inverted_branch"
1208   [(set (pc)
1209         (if_then_else (match_operator 0 "noov_compare_operator"
1210                                       [(reg CC_REG) (const_int 0)])
1211                       (pc)
1212                       (label_ref (match_operand 1 "" ""))))]
1213   ""
1215   return output_cbranch (operands[0], operands[1], 1, 1,
1216                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1217                          insn);
1219   [(set_attr "type" "branch")
1220    (set_attr "branch_type" "icc")])
1222 ;; XXX fpcmp nop braindamage
1223 (define_insn "*normal_fp_branch"
1224   [(set (pc)
1225         (if_then_else (match_operator 1 "comparison_operator"
1226                                       [(match_operand:CCFP 0 "fcc_register_operand" "c")
1227                                        (const_int 0)])
1228                       (label_ref (match_operand 2 "" ""))
1229                       (pc)))]
1230   ""
1232   return output_cbranch (operands[1], operands[2], 2, 0,
1233                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1234                          insn);
1236   [(set_attr "type" "branch")
1237    (set_attr "branch_type" "fcc")])
1239 ;; XXX fpcmp nop braindamage
1240 (define_insn "*inverted_fp_branch"
1241   [(set (pc)
1242         (if_then_else (match_operator 1 "comparison_operator"
1243                                       [(match_operand:CCFP 0 "fcc_register_operand" "c")
1244                                        (const_int 0)])
1245                       (pc)
1246                       (label_ref (match_operand 2 "" ""))))]
1247   ""
1249   return output_cbranch (operands[1], operands[2], 2, 1,
1250                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1251                          insn);
1253   [(set_attr "type" "branch")
1254    (set_attr "branch_type" "fcc")])
1256 ;; XXX fpcmp nop braindamage
1257 (define_insn "*normal_fpe_branch"
1258   [(set (pc)
1259         (if_then_else (match_operator 1 "comparison_operator"
1260                                       [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1261                                        (const_int 0)])
1262                       (label_ref (match_operand 2 "" ""))
1263                       (pc)))]
1264   ""
1266   return output_cbranch (operands[1], operands[2], 2, 0,
1267                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1268                          insn);
1270   [(set_attr "type" "branch")
1271    (set_attr "branch_type" "fcc")])
1273 ;; XXX fpcmp nop braindamage
1274 (define_insn "*inverted_fpe_branch"
1275   [(set (pc)
1276         (if_then_else (match_operator 1 "comparison_operator"
1277                                       [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1278                                        (const_int 0)])
1279                       (pc)
1280                       (label_ref (match_operand 2 "" ""))))]
1281   ""
1283   return output_cbranch (operands[1], operands[2], 2, 1,
1284                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1285                          insn);
1287   [(set_attr "type" "branch")
1288    (set_attr "branch_type" "fcc")])
1290 ;; SPARC V9-specific jump insns.  None of these are guaranteed to be
1291 ;; in the architecture.
1293 (define_insn "*cbcond_sp32"
1294   [(set (pc)
1295         (if_then_else (match_operator 0 "noov_compare_operator"
1296                        [(match_operand:SI 1 "register_operand" "r")
1297                         (match_operand:SI 2 "arith5_operand" "rA")])
1298                       (label_ref (match_operand 3 "" ""))
1299                       (pc)))]
1300   "TARGET_CBCOND"
1302   return output_cbcond (operands[0], operands[3], insn);
1304   [(set_attr "type" "cbcond")])
1306 (define_insn "*cbcond_sp64"
1307   [(set (pc)
1308         (if_then_else (match_operator 0 "noov_compare_operator"
1309                        [(match_operand:DI 1 "register_operand" "r")
1310                         (match_operand:DI 2 "arith5_operand" "rA")])
1311                       (label_ref (match_operand 3 "" ""))
1312                       (pc)))]
1313   "TARGET_ARCH64 && TARGET_CBCOND"
1315   return output_cbcond (operands[0], operands[3], insn);
1317   [(set_attr "type" "cbcond")])
1319 ;; There are no 32 bit brreg insns.
1321 ;; XXX
1322 (define_insn "*normal_int_branch_sp64"
1323   [(set (pc)
1324         (if_then_else (match_operator 0 "v9_register_compare_operator"
1325                                       [(match_operand:DI 1 "register_operand" "r")
1326                                        (const_int 0)])
1327                       (label_ref (match_operand 2 "" ""))
1328                       (pc)))]
1329   "TARGET_ARCH64"
1331   return output_v9branch (operands[0], operands[2], 1, 2, 0,
1332                           final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1333                           insn);
1335   [(set_attr "type" "branch")
1336    (set_attr "branch_type" "reg")])
1338 ;; XXX
1339 (define_insn "*inverted_int_branch_sp64"
1340   [(set (pc)
1341         (if_then_else (match_operator 0 "v9_register_compare_operator"
1342                                       [(match_operand:DI 1 "register_operand" "r")
1343                                        (const_int 0)])
1344                       (pc)
1345                       (label_ref (match_operand 2 "" ""))))]
1346   "TARGET_ARCH64"
1348   return output_v9branch (operands[0], operands[2], 1, 2, 1,
1349                           final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1350                           insn);
1352   [(set_attr "type" "branch")
1353    (set_attr "branch_type" "reg")])
1356 ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic
1357 ;; value subject to a PC-relative relocation.  Operand 2 is a helper function
1358 ;; that adds the PC value at the call point to register #(operand 3).
1360 ;; Even on V9 we use this call sequence with a stub, instead of "rd %pc, ..."
1361 ;; because the RDPC instruction is extremely expensive and incurs a complete
1362 ;; instruction pipeline flush.
1364 (define_insn "load_pcrel_sym<P:mode>"
1365   [(set (match_operand:P 0 "register_operand" "=r")
1366         (unspec:P [(match_operand:P 1 "symbolic_operand" "")
1367                    (match_operand:P 2 "call_address_operand" "")
1368                    (match_operand:P 3 "const_int_operand" "")] UNSPEC_LOAD_PCREL_SYM))
1369    (clobber (reg:P O7_REG))]
1370   "REGNO (operands[0]) == INTVAL (operands[3])"
1372   if (flag_delayed_branch)
1373     return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0";
1374   else
1375     return "sethi\t%%hi(%a1-8), %0\n\tadd\t%0, %%lo(%a1-4), %0\n\tcall\t%a2\n\t nop";
1377   [(set (attr "type") (const_string "multi"))
1378    (set (attr "length")
1379         (if_then_else (eq_attr "delayed_branch" "true")
1380                       (const_int 3)
1381                       (const_int 4)))])
1384 ;; Integer move instructions
1386 (define_expand "movqi"
1387   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1388         (match_operand:QI 1 "general_operand" ""))]
1389   ""
1391   if (sparc_expand_move (QImode, operands))
1392     DONE;
1395 (define_insn "*movqi_insn"
1396   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1397         (match_operand:QI 1 "input_operand"   "rI,m,rJ"))]
1398   "(register_operand (operands[0], QImode)
1399     || register_or_zero_operand (operands[1], QImode))"
1400   "@
1401    mov\t%1, %0
1402    ldub\t%1, %0
1403    stb\t%r1, %0"
1404   [(set_attr "type" "*,load,store")
1405    (set_attr "us3load_type" "*,3cycle,*")])
1407 (define_expand "movhi"
1408   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1409         (match_operand:HI 1 "general_operand" ""))]
1410   ""
1412   if (sparc_expand_move (HImode, operands))
1413     DONE;
1416 (define_insn "*movhi_insn"
1417   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1418         (match_operand:HI 1 "input_operand"   "rI,K,m,rJ"))]
1419   "(register_operand (operands[0], HImode)
1420     || register_or_zero_operand (operands[1], HImode))"
1421   "@
1422    mov\t%1, %0
1423    sethi\t%%hi(%a1), %0
1424    lduh\t%1, %0
1425    sth\t%r1, %0"
1426   [(set_attr "type" "*,*,load,store")
1427    (set_attr "us3load_type" "*,*,3cycle,*")])
1429 ;; We always work with constants here.
1430 (define_insn "*movhi_lo_sum"
1431   [(set (match_operand:HI 0 "register_operand" "=r")
1432         (ior:HI (match_operand:HI 1 "register_operand" "%r")
1433                 (match_operand:HI 2 "small_int_operand" "I")))]
1434   ""
1435   "or\t%1, %2, %0")
1437 (define_expand "movsi"
1438   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1439         (match_operand:SI 1 "general_operand" ""))]
1440   ""
1442   if (sparc_expand_move (SImode, operands))
1443     DONE;
1446 (define_insn "*movsi_insn"
1447   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r, m, r,*f,*f,*f, m,d,d")
1448         (match_operand:SI 1 "input_operand"        "rI,K,m,rJ,*f, r, f, m,*f,J,P"))]
1449   "register_operand (operands[0], SImode)
1450    || register_or_zero_or_all_ones_operand (operands[1], SImode)"
1451   "@
1452    mov\t%1, %0
1453    sethi\t%%hi(%a1), %0
1454    ld\t%1, %0
1455    st\t%r1, %0
1456    movstouw\t%1, %0
1457    movwtos\t%1, %0
1458    fmovs\t%1, %0
1459    ld\t%1, %0
1460    st\t%1, %0
1461    fzeros\t%0
1462    fones\t%0"
1463   [(set_attr "type" "*,*,load,store,vismv,vismv,fpmove,fpload,fpstore,visl,visl")
1464    (set_attr "cpu_feature" "*,*,*,*,vis3,vis3,*,*,*,vis,vis")])
1466 (define_insn "*movsi_lo_sum"
1467   [(set (match_operand:SI 0 "register_operand" "=r")
1468         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1469                    (match_operand:SI 2 "immediate_operand" "in")))]
1470   ""
1471   "or\t%1, %%lo(%a2), %0")
1473 (define_insn "*movsi_high"
1474   [(set (match_operand:SI 0 "register_operand" "=r")
1475         (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1476   ""
1477   "sethi\t%%hi(%a1), %0")
1479 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1480 ;; so that CSE won't optimize the address computation away.
1481 (define_insn "movsi_lo_sum_pic"
1482   [(set (match_operand:SI 0 "register_operand" "=r")
1483         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1484                    (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1485   "flag_pic"
1487 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1488   return "xor\t%1, %%gdop_lox10(%a2), %0";
1489 #else
1490   return "or\t%1, %%lo(%a2), %0";
1491 #endif
1494 (define_insn "movsi_high_pic"
1495   [(set (match_operand:SI 0 "register_operand" "=r")
1496         (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1497   "flag_pic && check_pic (1)"
1499 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1500   return "sethi\t%%gdop_hix22(%a1), %0";
1501 #else
1502   return "sethi\t%%hi(%a1), %0";
1503 #endif
1506 (define_insn "movsi_pic_gotdata_op"
1507   [(set (match_operand:SI 0 "register_operand" "=r")
1508         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
1509                     (match_operand:SI 2 "register_operand" "r")
1510                     (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
1511   "flag_pic && check_pic (1)"
1513 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1514   return "ld\t[%1 + %2], %0, %%gdop(%a3)";
1515 #else
1516   return "ld\t[%1 + %2], %0";
1517 #endif
1519   [(set_attr "type" "load")])
1521 (define_expand "movsi_pic_label_ref"
1522   [(set (match_dup 3) (high:SI
1523      (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1524                  (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1525    (set (match_dup 4) (lo_sum:SI (match_dup 3)
1526      (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1527    (set (match_operand:SI 0 "register_operand" "=r")
1528         (minus:SI (match_dup 5) (match_dup 4)))]
1529   "flag_pic"
1531   crtl->uses_pic_offset_table = 1;
1532   operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1533   if (!can_create_pseudo_p ())
1534     {
1535       operands[3] = operands[0];
1536       operands[4] = operands[0];
1537     }
1538   else
1539     {
1540       operands[3] = gen_reg_rtx (SImode);
1541       operands[4] = gen_reg_rtx (SImode);
1542     }
1543   operands[5] = pic_offset_table_rtx;
1546 (define_insn "*movsi_high_pic_label_ref"
1547   [(set (match_operand:SI 0 "register_operand" "=r")
1548       (high:SI
1549         (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1550                     (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1551   "flag_pic"
1552   "sethi\t%%hi(%a2-(%a1-.)), %0")
1554 (define_insn "*movsi_lo_sum_pic_label_ref"
1555   [(set (match_operand:SI 0 "register_operand" "=r")
1556       (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1557         (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
1558                     (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1559   "flag_pic"
1560   "or\t%1, %%lo(%a3-(%a2-.)), %0")
1562 ;; Set up the PIC register for VxWorks.
1564 (define_expand "vxworks_load_got"
1565   [(set (match_dup 0)
1566         (high:SI (match_dup 1)))
1567    (set (match_dup 0)
1568         (mem:SI (lo_sum:SI (match_dup 0) (match_dup 1))))
1569    (set (match_dup 0)
1570         (mem:SI (lo_sum:SI (match_dup 0) (match_dup 2))))]
1571   "TARGET_VXWORKS_RTP"
1573   operands[0] = pic_offset_table_rtx;
1574   operands[1] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_BASE);
1575   operands[2] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_INDEX);
1578 (define_expand "movdi"
1579   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1580         (match_operand:DI 1 "general_operand" ""))]
1581   ""
1583   if (sparc_expand_move (DImode, operands))
1584     DONE;
1587 ;; Be careful, fmovd does not exist when !v9.
1588 ;; We match MEM moves directly when we have correct even
1589 ;; numbered registers, but fall into splits otherwise.
1590 ;; The constraint ordering here is really important to
1591 ;; avoid insane problems in reload, especially for patterns
1592 ;; of the form:
1594 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
1595 ;;                       (const_int -5016)))
1596 ;;      (reg:DI 2 %g2))
1599 (define_insn "*movdi_insn_sp32"
1600   [(set (match_operand:DI 0 "nonimmediate_operand"
1601                                         "=T,o,T,U,o,r,r,r,?T,?*f,?*f,?o,?*e,?*e,  r,?*f,?*e,?W,b,b")
1602         (match_operand:DI 1 "input_operand"
1603                                         " J,J,U,T,r,o,i,r,*f,  T,  o,*f, *e, *e,?*f,  r,  W,*e,J,P"))]
1604   "! TARGET_ARCH64
1605    && (register_operand (operands[0], DImode)
1606        || register_or_zero_operand (operands[1], DImode))"
1607   "@
1608    stx\t%%g0, %0
1609    #
1610    std\t%1, %0
1611    ldd\t%1, %0
1612    #
1613    #
1614    #
1615    #
1616    std\t%1, %0
1617    ldd\t%1, %0
1618    #
1619    #
1620    fmovd\t%1, %0
1621    #
1622    #
1623    #
1624    ldd\t%1, %0
1625    std\t%1, %0
1626    fzero\t%0
1627    fone\t%0"
1628   [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,*,*,*,fpload,fpstore,visl,visl")
1629    (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,2,2,2,*,*,*,*")
1630    (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*,*,*,*,double,double")
1631    (set_attr "cpu_feature" "v9,*,*,*,*,*,*,*,fpu,fpu,fpu,fpu,v9,fpunotv9,vis3,vis3,fpu,fpu,vis,vis")])
1633 (define_insn "*movdi_insn_sp64"
1634   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r, m, r,*e,?*e,?*e,?W,b,b")
1635         (match_operand:DI 1 "input_operand"        "rI,N,m,rJ,*e, r, *e,  W,*e,J,P"))]
1636   "TARGET_ARCH64
1637    && (register_operand (operands[0], DImode)
1638        || register_or_zero_or_all_ones_operand (operands[1], DImode))"
1639   "@
1640    mov\t%1, %0
1641    sethi\t%%hi(%a1), %0
1642    ldx\t%1, %0
1643    stx\t%r1, %0
1644    movdtox\t%1, %0
1645    movxtod\t%1, %0
1646    fmovd\t%1, %0
1647    ldd\t%1, %0
1648    std\t%1, %0
1649    fzero\t%0
1650    fone\t%0"
1651   [(set_attr "type" "*,*,load,store,vismv,vismv,fpmove,fpload,fpstore,visl,visl")
1652    (set_attr "fptype" "*,*,*,*,*,*,double,*,*,double,double")
1653    (set_attr "cpu_feature" "*,*,*,*,vis3,vis3,*,*,*,vis,vis")])
1655 (define_expand "movdi_pic_label_ref"
1656   [(set (match_dup 3) (high:DI
1657      (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1658                  (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1659    (set (match_dup 4) (lo_sum:DI (match_dup 3)
1660      (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1661    (set (match_operand:DI 0 "register_operand" "=r")
1662         (minus:DI (match_dup 5) (match_dup 4)))]
1663   "TARGET_ARCH64 && flag_pic"
1665   crtl->uses_pic_offset_table = 1;
1666   operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1667   if (!can_create_pseudo_p ())
1668     {
1669       operands[3] = operands[0];
1670       operands[4] = operands[0];
1671     }
1672   else
1673     {
1674       operands[3] = gen_reg_rtx (DImode);
1675       operands[4] = gen_reg_rtx (DImode);
1676     }
1677   operands[5] = pic_offset_table_rtx;
1680 (define_insn "*movdi_high_pic_label_ref"
1681   [(set (match_operand:DI 0 "register_operand" "=r")
1682         (high:DI
1683           (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1684                       (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1685   "TARGET_ARCH64 && flag_pic"
1686   "sethi\t%%hi(%a2-(%a1-.)), %0")
1688 (define_insn "*movdi_lo_sum_pic_label_ref"
1689   [(set (match_operand:DI 0 "register_operand" "=r")
1690       (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1691         (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
1692                     (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1693   "TARGET_ARCH64 && flag_pic"
1694   "or\t%1, %%lo(%a3-(%a2-.)), %0")
1696 ;; SPARC-v9 code model support insns.  See sparc_emit_set_symbolic_const64
1697 ;; in sparc.c to see what is going on here... PIC stuff comes first.
1699 (define_insn "movdi_lo_sum_pic"
1700   [(set (match_operand:DI 0 "register_operand" "=r")
1701         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1702                    (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1703   "TARGET_ARCH64 && flag_pic"
1705 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1706   return "xor\t%1, %%gdop_lox10(%a2), %0";
1707 #else
1708   return "or\t%1, %%lo(%a2), %0";
1709 #endif
1712 (define_insn "movdi_high_pic"
1713   [(set (match_operand:DI 0 "register_operand" "=r")
1714         (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1715   "TARGET_ARCH64 && flag_pic && check_pic (1)"
1717 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1718   return "sethi\t%%gdop_hix22(%a1), %0";
1719 #else
1720   return "sethi\t%%hi(%a1), %0";
1721 #endif
1724 (define_insn "movdi_pic_gotdata_op"
1725   [(set (match_operand:DI 0 "register_operand" "=r")
1726         (unspec:DI [(match_operand:DI 1 "register_operand" "r")
1727                     (match_operand:DI 2 "register_operand" "r")
1728                     (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
1729   "TARGET_ARCH64 && flag_pic && check_pic (1)"
1731 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1732   return "ldx\t[%1 + %2], %0, %%gdop(%a3)";
1733 #else
1734   return "ldx\t[%1 + %2], %0";
1735 #endif
1737   [(set_attr "type" "load")])
1739 (define_insn "*sethi_di_medlow_embmedany_pic"
1740   [(set (match_operand:DI 0 "register_operand" "=r")
1741         (high:DI (match_operand:DI 1 "medium_pic_operand" "")))]
1742   "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
1743   "sethi\t%%hi(%a1), %0")
1745 (define_insn "*sethi_di_medlow"
1746   [(set (match_operand:DI 0 "register_operand" "=r")
1747         (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
1748   "TARGET_CM_MEDLOW && check_pic (1)"
1749   "sethi\t%%hi(%a1), %0")
1751 (define_insn "*losum_di_medlow"
1752   [(set (match_operand:DI 0 "register_operand" "=r")
1753         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1754                    (match_operand:DI 2 "symbolic_operand" "")))]
1755   "TARGET_CM_MEDLOW"
1756   "or\t%1, %%lo(%a2), %0")
1758 (define_insn "seth44"
1759   [(set (match_operand:DI 0 "register_operand" "=r")
1760         (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
1761   "TARGET_CM_MEDMID"
1762   "sethi\t%%h44(%a1), %0")
1764 (define_insn "setm44"
1765   [(set (match_operand:DI 0 "register_operand" "=r")
1766         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1767                    (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
1768   "TARGET_CM_MEDMID"
1769   "or\t%1, %%m44(%a2), %0")
1771 (define_insn "setl44"
1772   [(set (match_operand:DI 0 "register_operand" "=r")
1773         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1774                    (match_operand:DI 2 "symbolic_operand" "")))]
1775   "TARGET_CM_MEDMID"
1776   "or\t%1, %%l44(%a2), %0")
1778 (define_insn "sethh"
1779   [(set (match_operand:DI 0 "register_operand" "=r")
1780         (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
1781   "TARGET_CM_MEDANY"
1782   "sethi\t%%hh(%a1), %0")
1784 (define_insn "setlm"
1785   [(set (match_operand:DI 0 "register_operand" "=r")
1786         (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
1787   "TARGET_CM_MEDANY"
1788   "sethi\t%%lm(%a1), %0")
1790 (define_insn "sethm"
1791   [(set (match_operand:DI 0 "register_operand" "=r")
1792         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1793                    (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
1794   "TARGET_CM_MEDANY"
1795   "or\t%1, %%hm(%a2), %0")
1797 (define_insn "setlo"
1798   [(set (match_operand:DI 0 "register_operand" "=r")
1799         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1800                    (match_operand:DI 2 "symbolic_operand" "")))]
1801   "TARGET_CM_MEDANY"
1802   "or\t%1, %%lo(%a2), %0")
1804 (define_insn "embmedany_sethi"
1805   [(set (match_operand:DI 0 "register_operand" "=r")
1806         (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
1807   "TARGET_CM_EMBMEDANY && check_pic (1)"
1808   "sethi\t%%hi(%a1), %0")
1810 (define_insn "embmedany_losum"
1811   [(set (match_operand:DI 0 "register_operand" "=r")
1812         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1813                    (match_operand:DI 2 "data_segment_operand" "")))]
1814   "TARGET_CM_EMBMEDANY"
1815   "add\t%1, %%lo(%a2), %0")
1817 (define_insn "embmedany_brsum"
1818   [(set (match_operand:DI 0 "register_operand" "=r")
1819         (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
1820   "TARGET_CM_EMBMEDANY"
1821   "add\t%1, %_, %0")
1823 (define_insn "embmedany_textuhi"
1824   [(set (match_operand:DI 0 "register_operand" "=r")
1825         (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
1826   "TARGET_CM_EMBMEDANY && check_pic (1)"
1827   "sethi\t%%uhi(%a1), %0")
1829 (define_insn "embmedany_texthi"
1830   [(set (match_operand:DI 0 "register_operand" "=r")
1831         (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
1832   "TARGET_CM_EMBMEDANY && check_pic (1)"
1833   "sethi\t%%hi(%a1), %0")
1835 (define_insn "embmedany_textulo"
1836   [(set (match_operand:DI 0 "register_operand" "=r")
1837         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1838                    (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
1839   "TARGET_CM_EMBMEDANY"
1840   "or\t%1, %%ulo(%a2), %0")
1842 (define_insn "embmedany_textlo"
1843   [(set (match_operand:DI 0 "register_operand" "=r")
1844         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1845                    (match_operand:DI 2 "text_segment_operand" "")))]
1846   "TARGET_CM_EMBMEDANY"
1847   "or\t%1, %%lo(%a2), %0")
1849 ;; Now some patterns to help reload out a bit.
1850 (define_expand "reload_indi"
1851   [(parallel [(match_operand:DI 0 "register_operand" "=r")
1852               (match_operand:DI 1 "immediate_operand" "")
1853               (match_operand:TI 2 "register_operand" "=&r")])]
1854   "(TARGET_CM_MEDANY
1855     || TARGET_CM_EMBMEDANY)
1856    && ! flag_pic"
1858   sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1859   DONE;
1862 (define_expand "reload_outdi"
1863   [(parallel [(match_operand:DI 0 "register_operand" "=r")
1864               (match_operand:DI 1 "immediate_operand" "")
1865               (match_operand:TI 2 "register_operand" "=&r")])]
1866   "(TARGET_CM_MEDANY
1867     || TARGET_CM_EMBMEDANY)
1868    && ! flag_pic"
1870   sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1871   DONE;
1874 ;; Split up putting CONSTs and REGs into DI regs when !arch64
1875 (define_split
1876   [(set (match_operand:DI 0 "register_operand" "")
1877         (match_operand:DI 1 "const_int_operand" ""))]
1878   "! TARGET_ARCH64
1879    && ((GET_CODE (operands[0]) == REG
1880         && SPARC_INT_REG_P (REGNO (operands[0])))
1881        || (GET_CODE (operands[0]) == SUBREG
1882            && GET_CODE (SUBREG_REG (operands[0])) == REG
1883            && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))
1884    && reload_completed"
1885   [(clobber (const_int 0))]
1887 #if HOST_BITS_PER_WIDE_INT == 32
1888   emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1889                         (INTVAL (operands[1]) < 0) ?
1890                         constm1_rtx :
1891                         const0_rtx));
1892   emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1893                         operands[1]));
1894 #else
1895   HOST_WIDE_INT low, high;
1897   low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
1898   high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
1899   emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
1901   /* Slick... but this trick loses if this subreg constant part
1902      can be done in one insn.  */
1903   if (low == high
1904       && ! SPARC_SETHI32_P (high)
1905       && ! SPARC_SIMM13_P (high))
1906     emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1907                           gen_highpart (SImode, operands[0])));
1908   else
1909     emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
1910 #endif
1911   DONE;
1914 (define_split
1915   [(set (match_operand:DI 0 "register_operand" "")
1916         (match_operand:DI 1 "const_double_operand" ""))]
1917   "reload_completed
1918    && (! TARGET_V9
1919        || (! TARGET_ARCH64
1920            && ((GET_CODE (operands[0]) == REG
1921                 && SPARC_INT_REG_P (REGNO (operands[0])))
1922                || (GET_CODE (operands[0]) == SUBREG
1923                    && GET_CODE (SUBREG_REG (operands[0])) == REG
1924                    && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))))"
1925   [(clobber (const_int 0))]
1927   emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1928                         GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
1930   /* Slick... but this trick loses if this subreg constant part
1931      can be done in one insn.  */
1932   if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
1933       && ! SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
1934       && ! SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1])))
1935     {
1936       emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1937                             gen_highpart (SImode, operands[0])));
1938     }
1939   else
1940     {
1941       emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1942                             GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
1943     }
1944   DONE;
1947 (define_split
1948   [(set (match_operand:DI 0 "register_operand" "")
1949         (match_operand:DI 1 "register_operand" ""))]
1950   "reload_completed
1951    && (! TARGET_V9
1952        || (! TARGET_ARCH64
1953            && sparc_split_regreg_legitimate (operands[0],
1954                                              operands[1])))"
1955   [(clobber (const_int 0))]
1957   rtx set_dest = operands[0];
1958   rtx set_src = operands[1];
1959   rtx dest1, dest2;
1960   rtx src1, src2;
1962   dest1 = gen_highpart (SImode, set_dest);
1963   dest2 = gen_lowpart (SImode, set_dest);
1964   src1 = gen_highpart (SImode, set_src);
1965   src2 = gen_lowpart (SImode, set_src);
1967   /* Now emit using the real source and destination we found, swapping
1968      the order if we detect overlap.  */
1969   if (reg_overlap_mentioned_p (dest1, src2))
1970     {
1971       emit_insn (gen_movsi (dest2, src2));
1972       emit_insn (gen_movsi (dest1, src1));
1973     }
1974   else
1975     {
1976       emit_insn (gen_movsi (dest1, src1));
1977       emit_insn (gen_movsi (dest2, src2));
1978     }
1979   DONE;
1982 ;; Now handle the cases of memory moves from/to non-even
1983 ;; DI mode register pairs.
1984 (define_split
1985   [(set (match_operand:DI 0 "register_operand" "")
1986         (match_operand:DI 1 "memory_operand" ""))]
1987   "(! TARGET_ARCH64
1988     && reload_completed
1989     && sparc_splitdi_legitimate (operands[0], operands[1]))"
1990   [(clobber (const_int 0))]
1992   rtx word0 = adjust_address (operands[1], SImode, 0);
1993   rtx word1 = adjust_address (operands[1], SImode, 4);
1994   rtx high_part = gen_highpart (SImode, operands[0]);
1995   rtx low_part = gen_lowpart (SImode, operands[0]);
1997   if (reg_overlap_mentioned_p (high_part, word1))
1998     {
1999       emit_insn (gen_movsi (low_part, word1));
2000       emit_insn (gen_movsi (high_part, word0));
2001     }
2002   else
2003     {
2004       emit_insn (gen_movsi (high_part, word0));
2005       emit_insn (gen_movsi (low_part, word1));
2006     }
2007   DONE;
2010 (define_split
2011   [(set (match_operand:DI 0 "memory_operand" "")
2012         (match_operand:DI 1 "register_operand" ""))]
2013   "(! TARGET_ARCH64
2014     && reload_completed
2015     && sparc_splitdi_legitimate (operands[1], operands[0]))"
2016   [(clobber (const_int 0))]
2018   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
2019                         gen_highpart (SImode, operands[1])));
2020   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
2021                         gen_lowpart (SImode, operands[1])));
2022   DONE;
2025 (define_split
2026   [(set (match_operand:DI 0 "memory_operand" "")
2027         (match_operand:DI 1 "const_zero_operand" ""))]
2028   "reload_completed
2029    && (! TARGET_V9
2030        || (! TARGET_ARCH64
2031            && ! mem_min_alignment (operands[0], 8)))
2032    && offsettable_memref_p (operands[0])"
2033   [(clobber (const_int 0))]
2035   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
2036   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
2037   DONE;
2040 (define_expand "movti"
2041   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2042         (match_operand:TI 1 "general_operand" ""))]
2043   "TARGET_ARCH64"
2045   if (sparc_expand_move (TImode, operands))
2046     DONE;
2049 ;; We need to prevent reload from splitting TImode moves, because it
2050 ;; might decide to overwrite a pointer with the value it points to.
2051 ;; In that case we have to do the loads in the appropriate order so
2052 ;; that the pointer is not destroyed too early.
2054 (define_insn "*movti_insn_sp64"
2055   [(set (match_operand:TI 0 "nonimmediate_operand" "=r , o,?*e,?o,b")
2056         (match_operand:TI 1 "input_operand"        "roJ,rJ, eo, e,J"))]
2057   "TARGET_ARCH64
2058    && ! TARGET_HARD_QUAD
2059    && (register_operand (operands[0], TImode)
2060        || register_or_zero_operand (operands[1], TImode))"
2061   "#"
2062   [(set_attr "length" "2,2,2,2,2")
2063    (set_attr "cpu_feature" "*,*,fpu,fpu,vis")])
2065 (define_insn "*movti_insn_sp64_hq"
2066   [(set (match_operand:TI 0 "nonimmediate_operand" "=r , o,?*e,?*e,?m,b")
2067         (match_operand:TI 1 "input_operand"        "roJ,rJ,  e,  m, e,J"))]
2068   "TARGET_ARCH64
2069    && TARGET_HARD_QUAD
2070    && (register_operand (operands[0], TImode)
2071        || register_or_zero_operand (operands[1], TImode))"
2072   "@
2073   #
2074   #
2075   fmovq\t%1, %0
2076   ldq\t%1, %0
2077   stq\t%1, %0
2078   #"
2079   [(set_attr "type" "*,*,fpmove,fpload,fpstore,*")
2080    (set_attr "length" "2,2,*,*,*,2")])
2082 ;; Now all the splits to handle multi-insn TI mode moves.
2083 (define_split
2084   [(set (match_operand:TI 0 "register_operand" "")
2085         (match_operand:TI 1 "register_operand" ""))]
2086   "reload_completed
2087    && ((TARGET_FPU
2088         && ! TARGET_HARD_QUAD)
2089        || (! fp_register_operand (operands[0], TImode)
2090            && ! fp_register_operand (operands[1], TImode)))"
2091   [(clobber (const_int 0))]
2093   rtx set_dest = operands[0];
2094   rtx set_src = operands[1];
2095   rtx dest1, dest2;
2096   rtx src1, src2;
2098   dest1 = gen_highpart (DImode, set_dest);
2099   dest2 = gen_lowpart (DImode, set_dest);
2100   src1 = gen_highpart (DImode, set_src);
2101   src2 = gen_lowpart (DImode, set_src);
2103   /* Now emit using the real source and destination we found, swapping
2104      the order if we detect overlap.  */
2105   if (reg_overlap_mentioned_p (dest1, src2))
2106     {
2107       emit_insn (gen_movdi (dest2, src2));
2108       emit_insn (gen_movdi (dest1, src1));
2109     }
2110   else
2111     {
2112       emit_insn (gen_movdi (dest1, src1));
2113       emit_insn (gen_movdi (dest2, src2));
2114     }
2115   DONE;
2118 (define_split
2119   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2120         (match_operand:TI 1 "const_zero_operand" ""))]
2121   "reload_completed"
2122   [(clobber (const_int 0))]
2124   rtx set_dest = operands[0];
2125   rtx dest1, dest2;
2127   switch (GET_CODE (set_dest))
2128     {
2129     case REG:
2130       dest1 = gen_highpart (DImode, set_dest);
2131       dest2 = gen_lowpart (DImode, set_dest);
2132       break;
2133     case MEM:
2134       dest1 = adjust_address (set_dest, DImode, 0);
2135       dest2 = adjust_address (set_dest, DImode, 8);
2136       break;
2137     default:
2138       gcc_unreachable ();
2139     }
2141   emit_insn (gen_movdi (dest1, const0_rtx));
2142   emit_insn (gen_movdi (dest2, const0_rtx));
2143   DONE;
2146 (define_split
2147   [(set (match_operand:TI 0 "register_operand" "")
2148         (match_operand:TI 1 "memory_operand" ""))]
2149   "reload_completed
2150    && offsettable_memref_p (operands[1])
2151    && (! TARGET_HARD_QUAD
2152        || ! fp_register_operand (operands[0], TImode))"
2153   [(clobber (const_int 0))]
2155   rtx word0 = adjust_address (operands[1], DImode, 0);
2156   rtx word1 = adjust_address (operands[1], DImode, 8);
2157   rtx set_dest, dest1, dest2;
2159   set_dest = operands[0];
2161   dest1 = gen_highpart (DImode, set_dest);
2162   dest2 = gen_lowpart (DImode, set_dest);
2164   /* Now output, ordering such that we don't clobber any registers
2165      mentioned in the address.  */
2166   if (reg_overlap_mentioned_p (dest1, word1))
2168     {
2169       emit_insn (gen_movdi (dest2, word1));
2170       emit_insn (gen_movdi (dest1, word0));
2171     }
2172   else
2173    {
2174       emit_insn (gen_movdi (dest1, word0));
2175       emit_insn (gen_movdi (dest2, word1));
2176    }
2177   DONE;
2180 (define_split
2181   [(set (match_operand:TI 0 "memory_operand" "")
2182         (match_operand:TI 1 "register_operand" ""))]
2183   "reload_completed
2184    && offsettable_memref_p (operands[0])
2185    && (! TARGET_HARD_QUAD
2186        || ! fp_register_operand (operands[1], TImode))"
2187   [(clobber (const_int 0))]
2189   rtx set_src = operands[1];
2191   emit_insn (gen_movdi (adjust_address (operands[0], DImode, 0),
2192                         gen_highpart (DImode, set_src)));
2193   emit_insn (gen_movdi (adjust_address (operands[0], DImode, 8),
2194                         gen_lowpart (DImode, set_src)));
2195   DONE;
2199 ;; Floating point move instructions
2201 (define_expand "movsf"
2202   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2203         (match_operand:SF 1 "general_operand" ""))]
2204   ""
2206   if (sparc_expand_move (SFmode, operands))
2207     DONE;
2210 (define_insn "*movsf_insn"
2211   [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,f, *r,*r,*r,*r, f,f,*r,m,  m")
2212         (match_operand:SF 1 "input_operand"         "G,C,f,*rR, Q, S, f,*r,m, m,f,*rG"))]
2213   "(register_operand (operands[0], SFmode)
2214     || register_or_zero_or_all_ones_operand (operands[1], SFmode))"
2216   if (GET_CODE (operands[1]) == CONST_DOUBLE
2217       && (which_alternative == 3
2218           || which_alternative == 4
2219           || which_alternative == 5))
2220     {
2221       REAL_VALUE_TYPE r;
2222       long i;
2224       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2225       REAL_VALUE_TO_TARGET_SINGLE (r, i);
2226       operands[1] = GEN_INT (i);
2227     }
2229   switch (which_alternative)
2230     {
2231     case 0:
2232       return "fzeros\t%0";
2233     case 1:
2234       return "fones\t%0";
2235     case 2:
2236       return "fmovs\t%1, %0";
2237     case 3:
2238       return "mov\t%1, %0";
2239     case 4:
2240       return "sethi\t%%hi(%a1), %0";
2241     case 5:
2242       return "#";
2243     case 6:
2244       return "movstouw\t%1, %0";
2245     case 7:
2246       return "movwtos\t%1, %0";
2247     case 8:
2248     case 9:
2249       return "ld\t%1, %0";
2250     case 10:
2251     case 11:
2252       return "st\t%r1, %0";
2253     default:
2254       gcc_unreachable ();
2255     }
2257   [(set_attr "type" "visl,visl,fpmove,*,*,*,vismv,vismv,fpload,load,fpstore,store")
2258    (set_attr "cpu_feature" "vis,vis,fpu,*,*,*,vis3,vis3,fpu,*,fpu,*")])
2260 ;; The following 3 patterns build SFmode constants in integer registers.
2262 (define_insn "*movsf_lo_sum"
2263   [(set (match_operand:SF 0 "register_operand" "=r")
2264         (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
2265                    (match_operand:SF 2 "fp_const_high_losum_operand" "S")))]
2266   ""
2268   REAL_VALUE_TYPE r;
2269   long i;
2271   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
2272   REAL_VALUE_TO_TARGET_SINGLE (r, i);
2273   operands[2] = GEN_INT (i);
2274   return "or\t%1, %%lo(%a2), %0";
2277 (define_insn "*movsf_high"
2278   [(set (match_operand:SF 0 "register_operand" "=r")
2279         (high:SF (match_operand:SF 1 "fp_const_high_losum_operand" "S")))]
2280   ""
2282   REAL_VALUE_TYPE r;
2283   long i;
2285   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2286   REAL_VALUE_TO_TARGET_SINGLE (r, i);
2287   operands[1] = GEN_INT (i);
2288   return "sethi\t%%hi(%1), %0";
2291 (define_split
2292   [(set (match_operand:SF 0 "register_operand" "")
2293         (match_operand:SF 1 "fp_const_high_losum_operand" ""))]
2294   "REG_P (operands[0]) && SPARC_INT_REG_P (REGNO (operands[0]))"
2295   [(set (match_dup 0) (high:SF (match_dup 1)))
2296    (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
2298 (define_expand "movdf"
2299   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2300         (match_operand:DF 1 "general_operand" ""))]
2301   ""
2303   if (sparc_expand_move (DFmode, operands))
2304     DONE;
2307 (define_insn "*movdf_insn_sp32"
2308   [(set (match_operand:DF 0 "nonimmediate_operand" "=b,b,e,e,*r, f,  e,T,W,U,T,  f,  *r,  o,o")
2309         (match_operand:DF 1 "input_operand"         "G,C,e,e, f,*r,W#F,G,e,T,U,o#F,*roF,*rG,f"))]
2310   "! TARGET_ARCH64
2311    && (register_operand (operands[0], DFmode)
2312        || register_or_zero_or_all_ones_operand (operands[1], DFmode))"
2313   "@
2314   fzero\t%0
2315   fone\t%0
2316   fmovd\t%1, %0
2317   #
2318   #
2319   #
2320   ldd\t%1, %0
2321   stx\t%r1, %0
2322   std\t%1, %0
2323   ldd\t%1, %0
2324   std\t%1, %0
2325   #
2326   #
2327   #
2328   #"
2329   [(set_attr "type" "visl,visl,fpmove,*,*,*,fpload,store,fpstore,load,store,*,*,*,*")
2330    (set_attr "length" "*,*,*,2,2,2,*,*,*,*,*,2,2,2,2")
2331    (set_attr "fptype" "double,double,double,*,*,*,*,*,*,*,*,*,*,*,*")
2332    (set_attr "cpu_feature" "vis,vis,v9,fpunotv9,vis3,vis3,fpu,v9,fpu,*,*,fpu,*,*,fpu")])
2334 (define_insn "*movdf_insn_sp64"
2335   [(set (match_operand:DF 0 "nonimmediate_operand" "=b,b,e,*r, e,  e,W, *r,*r,  m,*r")
2336         (match_operand:DF 1 "input_operand"         "G,C,e, e,*r,W#F,e,*rG, m,*rG, F"))]
2337   "TARGET_ARCH64
2338    && (register_operand (operands[0], DFmode)
2339        || register_or_zero_or_all_ones_operand (operands[1], DFmode))"
2340   "@
2341   fzero\t%0
2342   fone\t%0
2343   fmovd\t%1, %0
2344   movdtox\t%1, %0
2345   movxtod\t%1, %0
2346   ldd\t%1, %0
2347   std\t%1, %0
2348   mov\t%r1, %0
2349   ldx\t%1, %0
2350   stx\t%r1, %0
2351   #"
2352   [(set_attr "type" "visl,visl,fpmove,vismv,vismv,load,store,*,load,store,*")
2353    (set_attr "length" "*,*,*,*,*,*,*,*,*,*,2")
2354    (set_attr "fptype" "double,double,double,double,double,*,*,*,*,*,*")
2355    (set_attr "cpu_feature" "vis,vis,fpu,vis3,vis3,fpu,fpu,*,*,*,*")])
2357 ;; This pattern builds DFmode constants in integer registers.
2358 (define_split
2359   [(set (match_operand:DF 0 "register_operand" "")
2360         (match_operand:DF 1 "const_double_operand" ""))]
2361   "REG_P (operands[0])
2362    && SPARC_INT_REG_P (REGNO (operands[0]))
2363    && ! const_zero_operand (operands[1], GET_MODE (operands[0]))
2364    && reload_completed"
2365   [(clobber (const_int 0))]
2367   operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
2369   if (TARGET_ARCH64)
2370     {
2371 #if HOST_BITS_PER_WIDE_INT == 32
2372       gcc_unreachable ();
2373 #else
2374       machine_mode mode = GET_MODE (operands[1]);
2375       rtx tem = simplify_subreg (DImode, operands[1], mode, 0);
2376       emit_insn (gen_movdi (operands[0], tem));
2377 #endif
2378     }
2379   else
2380     {
2381       machine_mode mode = GET_MODE (operands[1]);
2382       rtx hi = simplify_subreg (SImode, operands[1], mode, 0);
2383       rtx lo = simplify_subreg (SImode, operands[1], mode, 4);
2385       gcc_assert (GET_CODE (hi) == CONST_INT);
2386       gcc_assert (GET_CODE (lo) == CONST_INT);
2388       emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), hi));
2390       /* Slick... but this trick loses if this subreg constant part
2391          can be done in one insn.  */
2392       if (lo == hi
2393           && ! SPARC_SETHI32_P (INTVAL (hi))
2394           && ! SPARC_SIMM13_P (INTVAL (hi)))
2395         {
2396           emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2397                                 gen_highpart (SImode, operands[0])));
2398         }
2399       else
2400         {
2401           emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), lo));
2402         }
2403     }
2404   DONE;
2407 ;; Ok, now the splits to handle all the multi insn and
2408 ;; mis-aligned memory address cases.
2409 ;; In these splits please take note that we must be
2410 ;; careful when V9 but not ARCH64 because the integer
2411 ;; register DFmode cases must be handled.
2412 (define_split
2413   [(set (match_operand:DF 0 "register_operand" "")
2414         (match_operand:DF 1 "register_operand" ""))]
2415   "(! TARGET_V9
2416     || (! TARGET_ARCH64
2417         && sparc_split_regreg_legitimate (operands[0],
2418                                           operands[1])))
2419    && reload_completed"
2420   [(clobber (const_int 0))]
2422   rtx set_dest = operands[0];
2423   rtx set_src = operands[1];
2424   rtx dest1, dest2;
2425   rtx src1, src2;
2427   dest1 = gen_highpart (SFmode, set_dest);
2428   dest2 = gen_lowpart (SFmode, set_dest);
2429   src1 = gen_highpart (SFmode, set_src);
2430   src2 = gen_lowpart (SFmode, set_src);
2432   /* Now emit using the real source and destination we found, swapping
2433      the order if we detect overlap.  */
2434   if (reg_overlap_mentioned_p (dest1, src2))
2435     {
2436       emit_move_insn_1 (dest2, src2);
2437       emit_move_insn_1 (dest1, src1);
2438     }
2439   else
2440     {
2441       emit_move_insn_1 (dest1, src1);
2442       emit_move_insn_1 (dest2, src2);
2443     }
2444   DONE;
2447 (define_split
2448   [(set (match_operand:DF 0 "register_operand" "")
2449         (match_operand:DF 1 "memory_operand" ""))]
2450   "reload_completed
2451    && ! TARGET_ARCH64
2452    && (((REGNO (operands[0]) % 2) != 0)
2453        || ! mem_min_alignment (operands[1], 8))
2454    && offsettable_memref_p (operands[1])"
2455   [(clobber (const_int 0))]
2457   rtx word0, word1;
2459   word0 = adjust_address (operands[1], SFmode, 0);
2460   word1 = adjust_address (operands[1], SFmode, 4);
2462   if (reg_overlap_mentioned_p (gen_highpart (SFmode, operands[0]), word1))
2463     {
2464       emit_move_insn_1 (gen_lowpart (SFmode, operands[0]), word1);
2465       emit_move_insn_1 (gen_highpart (SFmode, operands[0]), word0);
2466     }
2467   else
2468     {
2469       emit_move_insn_1 (gen_highpart (SFmode, operands[0]), word0);
2470       emit_move_insn_1 (gen_lowpart (SFmode, operands[0]), word1);
2471     }
2472   DONE;
2475 (define_split
2476   [(set (match_operand:DF 0 "memory_operand" "")
2477         (match_operand:DF 1 "register_operand" ""))]
2478   "reload_completed
2479    && ! TARGET_ARCH64
2480    && (((REGNO (operands[1]) % 2) != 0)
2481        || ! mem_min_alignment (operands[0], 8))
2482    && offsettable_memref_p (operands[0])"
2483   [(clobber (const_int 0))]
2485   rtx word0, word1;
2487   word0 = adjust_address (operands[0], SFmode, 0);
2488   word1 = adjust_address (operands[0], SFmode, 4);
2490   emit_move_insn_1 (word0, gen_highpart (SFmode, operands[1]));
2491   emit_move_insn_1 (word1, gen_lowpart (SFmode, operands[1]));
2492   DONE;
2495 (define_split
2496   [(set (match_operand:DF 0 "memory_operand" "")
2497         (match_operand:DF 1 "const_zero_operand" ""))]
2498   "reload_completed
2499    && (! TARGET_V9
2500        || (! TARGET_ARCH64
2501            && ! mem_min_alignment (operands[0], 8)))
2502    && offsettable_memref_p (operands[0])"
2503   [(clobber (const_int 0))]
2505   rtx dest1, dest2;
2507   dest1 = adjust_address (operands[0], SFmode, 0);
2508   dest2 = adjust_address (operands[0], SFmode, 4);
2510   emit_move_insn_1 (dest1, CONST0_RTX (SFmode));
2511   emit_move_insn_1 (dest2, CONST0_RTX (SFmode));
2512   DONE;
2515 (define_split
2516   [(set (match_operand:DF 0 "register_operand" "")
2517         (match_operand:DF 1 "const_zero_operand" ""))]
2518   "reload_completed
2519    && ! TARGET_ARCH64
2520    && ((GET_CODE (operands[0]) == REG
2521         && SPARC_INT_REG_P (REGNO (operands[0])))
2522        || (GET_CODE (operands[0]) == SUBREG
2523            && GET_CODE (SUBREG_REG (operands[0])) == REG
2524            && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
2525   [(clobber (const_int 0))]
2527   rtx set_dest = operands[0];
2528   rtx dest1, dest2;
2530   dest1 = gen_highpart (SFmode, set_dest);
2531   dest2 = gen_lowpart (SFmode, set_dest);
2532   emit_move_insn_1 (dest1, CONST0_RTX (SFmode));
2533   emit_move_insn_1 (dest2, CONST0_RTX (SFmode));
2534   DONE;
2537 (define_expand "movtf"
2538   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2539         (match_operand:TF 1 "general_operand" ""))]
2540   ""
2542   if (sparc_expand_move (TFmode, operands))
2543     DONE;
2546 (define_insn "*movtf_insn_sp32"
2547   [(set (match_operand:TF 0 "nonimmediate_operand" "=b, e,o,  o,U,  r")
2548         (match_operand:TF 1 "input_operand"        " G,oe,e,rGU,o,roG"))]
2549   "! TARGET_ARCH64
2550    && (register_operand (operands[0], TFmode)
2551        || register_or_zero_operand (operands[1], TFmode))"
2552   "#"
2553   [(set_attr "length" "4,4,4,4,4,4")
2554    (set_attr "cpu_feature" "fpu,fpu,fpu,*,*,*")])
2556 (define_insn "*movtf_insn_sp64"
2557   [(set (match_operand:TF 0 "nonimmediate_operand" "=b, e,o, o,  r")
2558         (match_operand:TF 1 "input_operand"         "G,oe,e,rG,roG"))]
2559   "TARGET_ARCH64
2560    && ! TARGET_HARD_QUAD
2561    && (register_operand (operands[0], TFmode)
2562        || register_or_zero_operand (operands[1], TFmode))"
2563   "#"
2564   [(set_attr "length" "2,2,2,2,2")
2565    (set_attr "cpu_feature" "fpu,fpu,fpu,*,*")])
2567 (define_insn "*movtf_insn_sp64_hq"
2568   [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,e,m, o,  r")
2569         (match_operand:TF 1 "input_operand"         "G,e,m,e,rG,roG"))]
2570   "TARGET_ARCH64
2571    && TARGET_HARD_QUAD
2572    && (register_operand (operands[0], TFmode)
2573        || register_or_zero_operand (operands[1], TFmode))"
2574   "@
2575   #
2576   fmovq\t%1, %0
2577   ldq\t%1, %0
2578   stq\t%1, %0
2579   #
2580   #"
2581   [(set_attr "type" "*,fpmove,fpload,fpstore,*,*")
2582    (set_attr "length" "2,*,*,*,2,2")])
2584 ;; Now all the splits to handle multi-insn TF mode moves.
2585 (define_split
2586   [(set (match_operand:TF 0 "register_operand" "")
2587         (match_operand:TF 1 "register_operand" ""))]
2588   "reload_completed
2589    && (! TARGET_ARCH64
2590        || (TARGET_FPU
2591            && ! TARGET_HARD_QUAD)
2592        || (! fp_register_operand (operands[0], TFmode)
2593            && ! fp_register_operand (operands[1], TFmode)))"
2594   [(clobber (const_int 0))]
2596   rtx set_dest = operands[0];
2597   rtx set_src = operands[1];
2598   rtx dest1, dest2;
2599   rtx src1, src2;
2601   dest1 = gen_df_reg (set_dest, 0);
2602   dest2 = gen_df_reg (set_dest, 1);
2603   src1 = gen_df_reg (set_src, 0);
2604   src2 = gen_df_reg (set_src, 1);
2606   /* Now emit using the real source and destination we found, swapping
2607      the order if we detect overlap.  */
2608   if (reg_overlap_mentioned_p (dest1, src2))
2609     {
2610       emit_insn (gen_movdf (dest2, src2));
2611       emit_insn (gen_movdf (dest1, src1));
2612     }
2613   else
2614     {
2615       emit_insn (gen_movdf (dest1, src1));
2616       emit_insn (gen_movdf (dest2, src2));
2617     }
2618   DONE;
2621 (define_split
2622   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2623         (match_operand:TF 1 "const_zero_operand" ""))]
2624   "reload_completed"
2625   [(clobber (const_int 0))]
2627   rtx set_dest = operands[0];
2628   rtx dest1, dest2;
2630   switch (GET_CODE (set_dest))
2631     {
2632     case REG:
2633       dest1 = gen_df_reg (set_dest, 0);
2634       dest2 = gen_df_reg (set_dest, 1);
2635       break;
2636     case MEM:
2637       dest1 = adjust_address (set_dest, DFmode, 0);
2638       dest2 = adjust_address (set_dest, DFmode, 8);
2639       break;
2640     default:
2641       gcc_unreachable ();
2642     }
2644   emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
2645   emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
2646   DONE;
2649 (define_split
2650   [(set (match_operand:TF 0 "register_operand" "")
2651         (match_operand:TF 1 "memory_operand" ""))]
2652   "(reload_completed
2653     && offsettable_memref_p (operands[1])
2654     && (! TARGET_ARCH64
2655         || ! TARGET_HARD_QUAD
2656         || ! fp_register_operand (operands[0], TFmode)))"
2657   [(clobber (const_int 0))]
2659   rtx word0 = adjust_address (operands[1], DFmode, 0);
2660   rtx word1 = adjust_address (operands[1], DFmode, 8);
2661   rtx set_dest, dest1, dest2;
2663   set_dest = operands[0];
2665   dest1 = gen_df_reg (set_dest, 0);
2666   dest2 = gen_df_reg (set_dest, 1);
2668   /* Now output, ordering such that we don't clobber any registers
2669      mentioned in the address.  */
2670   if (reg_overlap_mentioned_p (dest1, word1))
2672     {
2673       emit_insn (gen_movdf (dest2, word1));
2674       emit_insn (gen_movdf (dest1, word0));
2675     }
2676   else
2677    {
2678       emit_insn (gen_movdf (dest1, word0));
2679       emit_insn (gen_movdf (dest2, word1));
2680    }
2681   DONE;
2684 (define_split
2685   [(set (match_operand:TF 0 "memory_operand" "")
2686         (match_operand:TF 1 "register_operand" ""))]
2687   "(reload_completed
2688     && offsettable_memref_p (operands[0])
2689     && (! TARGET_ARCH64
2690         || ! TARGET_HARD_QUAD
2691         || ! fp_register_operand (operands[1], TFmode)))"
2692   [(clobber (const_int 0))]
2694   rtx set_src = operands[1];
2696   emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
2697                         gen_df_reg (set_src, 0)));
2698   emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
2699                         gen_df_reg (set_src, 1)));
2700   DONE;
2704 ;; SPARC-V9 conditional move instructions
2706 ;; We can handle larger constants here for some flavors, but for now we keep
2707 ;; it simple and only allow those constants supported by all flavors.
2708 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
2709 ;; 3 contains the constant if one is present, but we handle either for
2710 ;; generality (sparc.c puts a constant in operand 2).
2712 ;; Our instruction patterns, on the other hand, canonicalize such that
2713 ;; operand 3 must be the set destination.
2715 (define_expand "mov<I:mode>cc"
2716   [(set (match_operand:I 0 "register_operand" "")
2717         (if_then_else:I (match_operand 1 "comparison_operator" "")
2718                         (match_operand:I 2 "arith10_operand" "")
2719                         (match_operand:I 3 "arith10_operand" "")))]
2720   "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2722   if (! sparc_expand_conditional_move (<I:MODE>mode, operands))
2723     FAIL;
2724   DONE;
2727 (define_expand "mov<F:mode>cc"
2728   [(set (match_operand:F 0 "register_operand" "")
2729         (if_then_else:F (match_operand 1 "comparison_operator" "")
2730                         (match_operand:F 2 "register_operand" "")
2731                         (match_operand:F 3 "register_operand" "")))]
2732   "TARGET_V9 && TARGET_FPU"
2734   if (! sparc_expand_conditional_move (<F:MODE>mode, operands))
2735     FAIL;
2736   DONE;
2739 ;; Conditional move define_insns
2741 (define_insn "*mov<I:mode>_cc_v9"
2742   [(set (match_operand:I 0 "register_operand" "=r")
2743         (if_then_else:I (match_operator 1 "comparison_operator"
2744                                [(match_operand 2 "icc_or_fcc_register_operand" "X")
2745                                 (const_int 0)])
2746                         (match_operand:I 3 "arith11_operand" "rL")
2747                         (match_operand:I 4 "register_operand" "0")))]
2748   "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2749   "mov%C1\t%x2, %3, %0"
2750   [(set_attr "type" "cmove")])
2752 (define_insn "*mov<I:mode>_cc_reg_sp64"
2753   [(set (match_operand:I 0 "register_operand" "=r")
2754         (if_then_else:I (match_operator 1 "v9_register_compare_operator"
2755                                 [(match_operand:DI 2 "register_operand" "r")
2756                                  (const_int 0)])
2757                         (match_operand:I 3 "arith10_operand" "rM")
2758                         (match_operand:I 4 "register_operand" "0")))]
2759   "TARGET_ARCH64"
2760   "movr%D1\t%2, %r3, %0"
2761   [(set_attr "type" "cmove")])
2763 (define_insn "*movsf_cc_v9"
2764   [(set (match_operand:SF 0 "register_operand" "=f")
2765         (if_then_else:SF (match_operator 1 "comparison_operator"
2766                                 [(match_operand 2 "icc_or_fcc_register_operand" "X")
2767                                  (const_int 0)])
2768                          (match_operand:SF 3 "register_operand" "f")
2769                          (match_operand:SF 4 "register_operand" "0")))]
2770   "TARGET_V9 && TARGET_FPU"
2771   "fmovs%C1\t%x2, %3, %0"
2772   [(set_attr "type" "fpcmove")])
2774 (define_insn "*movsf_cc_reg_sp64"
2775   [(set (match_operand:SF 0 "register_operand" "=f")
2776         (if_then_else:SF (match_operator 1 "v9_register_compare_operator"
2777                                 [(match_operand:DI 2 "register_operand" "r")
2778                                  (const_int 0)])
2779                          (match_operand:SF 3 "register_operand" "f")
2780                          (match_operand:SF 4 "register_operand" "0")))]
2781   "TARGET_ARCH64 && TARGET_FPU"
2782   "fmovrs%D1\t%2, %3, %0"
2783   [(set_attr "type" "fpcrmove")])
2785 ;; Named because invoked by movtf_cc_v9
2786 (define_insn "movdf_cc_v9"
2787   [(set (match_operand:DF 0 "register_operand" "=e")
2788         (if_then_else:DF (match_operator 1 "comparison_operator"
2789                                 [(match_operand 2 "icc_or_fcc_register_operand" "X")
2790                                  (const_int 0)])
2791                          (match_operand:DF 3 "register_operand" "e")
2792                          (match_operand:DF 4 "register_operand" "0")))]
2793   "TARGET_V9 && TARGET_FPU"
2794   "fmovd%C1\t%x2, %3, %0"
2795   [(set_attr "type" "fpcmove")
2796    (set_attr "fptype" "double")])
2798 ;; Named because invoked by movtf_cc_reg_sp64
2799 (define_insn "movdf_cc_reg_sp64"
2800   [(set (match_operand:DF 0 "register_operand" "=e")
2801         (if_then_else:DF (match_operator 1 "v9_register_compare_operator"
2802                                 [(match_operand:DI 2 "register_operand" "r")
2803                                  (const_int 0)])
2804                          (match_operand:DF 3 "register_operand" "e")
2805                          (match_operand:DF 4 "register_operand" "0")))]
2806   "TARGET_ARCH64 && TARGET_FPU"
2807   "fmovrd%D1\t%2, %3, %0"
2808   [(set_attr "type" "fpcrmove")
2809    (set_attr "fptype" "double")])
2811 (define_insn "*movtf_cc_hq_v9"
2812   [(set (match_operand:TF 0 "register_operand" "=e")
2813         (if_then_else:TF (match_operator 1 "comparison_operator"
2814                                 [(match_operand 2 "icc_or_fcc_register_operand" "X")
2815                                  (const_int 0)])
2816                          (match_operand:TF 3 "register_operand" "e")
2817                          (match_operand:TF 4 "register_operand" "0")))]
2818   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
2819   "fmovq%C1\t%x2, %3, %0"
2820   [(set_attr "type" "fpcmove")])
2822 (define_insn "*movtf_cc_reg_hq_sp64"
2823   [(set (match_operand:TF 0 "register_operand" "=e")
2824         (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2825                                 [(match_operand:DI 2 "register_operand" "r")
2826                                  (const_int 0)])
2827                          (match_operand:TF 3 "register_operand" "e")
2828                          (match_operand:TF 4 "register_operand" "0")))]
2829   "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
2830   "fmovrq%D1\t%2, %3, %0"
2831   [(set_attr "type" "fpcrmove")])
2833 (define_insn_and_split "*movtf_cc_v9"
2834   [(set (match_operand:TF 0 "register_operand" "=e")
2835         (if_then_else:TF (match_operator 1 "comparison_operator"
2836                             [(match_operand 2 "icc_or_fcc_register_operand" "X")
2837                              (const_int 0)])
2838                          (match_operand:TF 3 "register_operand" "e")
2839                          (match_operand:TF 4 "register_operand" "0")))]
2840   "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
2841   "#"
2842   "&& reload_completed"
2843   [(clobber (const_int 0))]
2845   rtx set_dest = operands[0];
2846   rtx set_srca = operands[3];
2847   rtx dest1, dest2;
2848   rtx srca1, srca2;
2850   dest1 = gen_df_reg (set_dest, 0);
2851   dest2 = gen_df_reg (set_dest, 1);
2852   srca1 = gen_df_reg (set_srca, 0);
2853   srca2 = gen_df_reg (set_srca, 1);
2855   if (reg_overlap_mentioned_p (dest1, srca2))
2856     {
2857       emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, dest2));
2858       emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, dest1));
2859     }
2860   else
2861     {
2862       emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, dest1));
2863       emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, dest2));
2864     }
2865   DONE;
2867   [(set_attr "length" "2")])
2869 (define_insn_and_split "*movtf_cc_reg_sp64"
2870   [(set (match_operand:TF 0 "register_operand" "=e")
2871         (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2872                                 [(match_operand:DI 2 "register_operand" "r")
2873                                  (const_int 0)])
2874                          (match_operand:TF 3 "register_operand" "e")
2875                          (match_operand:TF 4 "register_operand" "0")))]
2876   "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
2877   "#"
2878   "&& reload_completed"
2879   [(clobber (const_int 0))]
2881   rtx set_dest = operands[0];
2882   rtx set_srca = operands[3];
2883   rtx dest1, dest2;
2884   rtx srca1, srca2;
2886   dest1 = gen_df_reg (set_dest, 0);
2887   dest2 = gen_df_reg (set_dest, 1);
2888   srca1 = gen_df_reg (set_srca, 0);
2889   srca2 = gen_df_reg (set_srca, 1);
2891   if (reg_overlap_mentioned_p (dest1, srca2))
2892     {
2893       emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, dest2));
2894       emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, dest1));
2895     }
2896   else
2897     {
2898       emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, dest1));
2899       emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, dest2));
2900     }
2901   DONE;
2903   [(set_attr "length" "2")])
2906 ;; Zero-extension instructions
2908 ;; These patterns originally accepted general_operands, however, slightly
2909 ;; better code is generated by only accepting register_operands, and then
2910 ;; letting combine generate the ldu[hb] insns.
2912 (define_expand "zero_extendhisi2"
2913   [(set (match_operand:SI 0 "register_operand" "")
2914         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
2915   ""
2917   rtx temp = gen_reg_rtx (SImode);
2918   rtx shift_16 = GEN_INT (16);
2919   int op1_subbyte = 0;
2921   if (GET_CODE (operand1) == SUBREG)
2922     {
2923       op1_subbyte = SUBREG_BYTE (operand1);
2924       op1_subbyte /= GET_MODE_SIZE (SImode);
2925       op1_subbyte *= GET_MODE_SIZE (SImode);
2926       operand1 = XEXP (operand1, 0);
2927     }
2929   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
2930                           shift_16));
2931   emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
2932   DONE;
2935 (define_insn "*zero_extendhisi2_insn"
2936   [(set (match_operand:SI 0 "register_operand" "=r")
2937         (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2938   ""
2939   "lduh\t%1, %0"
2940   [(set_attr "type" "load")
2941    (set_attr "us3load_type" "3cycle")])
2943 (define_expand "zero_extendqihi2"
2944   [(set (match_operand:HI 0 "register_operand" "")
2945         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
2946   ""
2947   "")
2949 (define_insn "*zero_extendqihi2_insn"
2950   [(set (match_operand:HI 0 "register_operand" "=r,r")
2951         (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
2952   "GET_CODE (operands[1]) != CONST_INT"
2953   "@
2954    and\t%1, 0xff, %0
2955    ldub\t%1, %0"
2956   [(set_attr "type" "*,load")
2957    (set_attr "us3load_type" "*,3cycle")])
2959 (define_expand "zero_extendqisi2"
2960   [(set (match_operand:SI 0 "register_operand" "")
2961         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
2962   ""
2963   "")
2965 (define_insn "*zero_extendqisi2_insn"
2966   [(set (match_operand:SI 0 "register_operand" "=r,r")
2967         (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
2968   "GET_CODE (operands[1]) != CONST_INT"
2969   "@
2970    and\t%1, 0xff, %0
2971    ldub\t%1, %0"
2972   [(set_attr "type" "*,load")
2973    (set_attr "us3load_type" "*,3cycle")])
2975 (define_expand "zero_extendqidi2"
2976   [(set (match_operand:DI 0 "register_operand" "")
2977         (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
2978   "TARGET_ARCH64"
2979   "")
2981 (define_insn "*zero_extendqidi2_insn"
2982   [(set (match_operand:DI 0 "register_operand" "=r,r")
2983         (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
2984   "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
2985   "@
2986    and\t%1, 0xff, %0
2987    ldub\t%1, %0"
2988   [(set_attr "type" "*,load")
2989    (set_attr "us3load_type" "*,3cycle")])
2991 (define_expand "zero_extendhidi2"
2992   [(set (match_operand:DI 0 "register_operand" "")
2993         (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
2994   "TARGET_ARCH64"
2996   rtx temp = gen_reg_rtx (DImode);
2997   rtx shift_48 = GEN_INT (48);
2998   int op1_subbyte = 0;
3000   if (GET_CODE (operand1) == SUBREG)
3001     {
3002       op1_subbyte = SUBREG_BYTE (operand1);
3003       op1_subbyte /= GET_MODE_SIZE (DImode);
3004       op1_subbyte *= GET_MODE_SIZE (DImode);
3005       operand1 = XEXP (operand1, 0);
3006     }
3008   emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3009                           shift_48));
3010   emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
3011   DONE;
3014 (define_insn "*zero_extendhidi2_insn"
3015   [(set (match_operand:DI 0 "register_operand" "=r")
3016         (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3017   "TARGET_ARCH64"
3018   "lduh\t%1, %0"
3019   [(set_attr "type" "load")
3020    (set_attr "us3load_type" "3cycle")])
3022 ;; ??? Write truncdisi pattern using sra?
3024 (define_expand "zero_extendsidi2"
3025   [(set (match_operand:DI 0 "register_operand" "")
3026         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
3027   ""
3028   "")
3030 (define_insn "*zero_extendsidi2_insn_sp64"
3031   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
3032         (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m,*f")))]
3033   "TARGET_ARCH64
3034    && GET_CODE (operands[1]) != CONST_INT"
3035   "@
3036    srl\t%1, 0, %0
3037    lduw\t%1, %0
3038    movstouw\t%1, %0"
3039   [(set_attr "type" "shift,load,*")
3040    (set_attr "cpu_feature" "*,*,vis3")])
3042 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
3043   [(set (match_operand:DI 0 "register_operand" "=r")
3044         (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
3045   "! TARGET_ARCH64"
3046   "#"
3047   "&& reload_completed"
3048   [(set (match_dup 2) (match_dup 3))
3049    (set (match_dup 4) (match_dup 5))]
3051   rtx dest1, dest2;
3053   dest1 = gen_highpart (SImode, operands[0]);
3054   dest2 = gen_lowpart (SImode, operands[0]);
3056   /* Swap the order in case of overlap.  */
3057   if (REGNO (dest1) == REGNO (operands[1]))
3058     {
3059       operands[2] = dest2;
3060       operands[3] = operands[1];
3061       operands[4] = dest1;
3062       operands[5] = const0_rtx;
3063     }
3064   else
3065     {
3066       operands[2] = dest1;
3067       operands[3] = const0_rtx;
3068       operands[4] = dest2;
3069       operands[5] = operands[1];
3070     }
3072   [(set_attr "length" "2")])
3074 ;; Simplify comparisons of extended values.
3076 (define_insn "*cmp_zero_extendqisi2"
3077   [(set (reg:CC CC_REG)
3078         (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
3079                     (const_int 0)))]
3080   ""
3081   "andcc\t%0, 0xff, %%g0"
3082   [(set_attr "type" "compare")])
3084 (define_insn "*cmp_zero_qi"
3085   [(set (reg:CC CC_REG)
3086         (compare:CC (match_operand:QI 0 "register_operand" "r")
3087                     (const_int 0)))]
3088   ""
3089   "andcc\t%0, 0xff, %%g0"
3090   [(set_attr "type" "compare")])
3092 (define_insn "*cmp_zero_extendqisi2_set"
3093   [(set (reg:CC CC_REG)
3094         (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
3095                     (const_int 0)))
3096    (set (match_operand:SI 0 "register_operand" "=r")
3097         (zero_extend:SI (match_dup 1)))]
3098   ""
3099   "andcc\t%1, 0xff, %0"
3100   [(set_attr "type" "compare")])
3102 (define_insn "*cmp_zero_extendqisi2_andcc_set"
3103   [(set (reg:CC CC_REG)
3104         (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
3105                             (const_int 255))
3106                     (const_int 0)))
3107    (set (match_operand:SI 0 "register_operand" "=r")
3108         (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
3109   ""
3110   "andcc\t%1, 0xff, %0"
3111   [(set_attr "type" "compare")])
3113 (define_insn "*cmp_zero_extendqidi2"
3114   [(set (reg:CCX CC_REG)
3115         (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
3116                      (const_int 0)))]
3117   "TARGET_ARCH64"
3118   "andcc\t%0, 0xff, %%g0"
3119   [(set_attr "type" "compare")])
3121 (define_insn "*cmp_zero_qi_sp64"
3122   [(set (reg:CCX CC_REG)
3123         (compare:CCX (match_operand:QI 0 "register_operand" "r")
3124                      (const_int 0)))]
3125   "TARGET_ARCH64"
3126   "andcc\t%0, 0xff, %%g0"
3127   [(set_attr "type" "compare")])
3129 (define_insn "*cmp_zero_extendqidi2_set"
3130   [(set (reg:CCX CC_REG)
3131         (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
3132                      (const_int 0)))
3133    (set (match_operand:DI 0 "register_operand" "=r")
3134         (zero_extend:DI (match_dup 1)))]
3135   "TARGET_ARCH64"
3136   "andcc\t%1, 0xff, %0"
3137   [(set_attr "type" "compare")])
3139 (define_insn "*cmp_zero_extendqidi2_andcc_set"
3140   [(set (reg:CCX CC_REG)
3141         (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
3142                              (const_int 255))
3143                      (const_int 0)))
3144    (set (match_operand:DI 0 "register_operand" "=r")
3145         (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
3146   "TARGET_ARCH64"
3147   "andcc\t%1, 0xff, %0"
3148   [(set_attr "type" "compare")])
3150 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
3152 (define_insn "*cmp_siqi_trunc"
3153   [(set (reg:CC CC_REG)
3154         (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
3155                     (const_int 0)))]
3156   ""
3157   "andcc\t%0, 0xff, %%g0"
3158   [(set_attr "type" "compare")])
3160 (define_insn "*cmp_siqi_trunc_set"
3161   [(set (reg:CC CC_REG)
3162         (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
3163                     (const_int 0)))
3164    (set (match_operand:QI 0 "register_operand" "=r")
3165         (subreg:QI (match_dup 1) 3))]
3166   ""
3167   "andcc\t%1, 0xff, %0"
3168   [(set_attr "type" "compare")])
3170 (define_insn "*cmp_diqi_trunc"
3171   [(set (reg:CC CC_REG)
3172         (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
3173                     (const_int 0)))]
3174   "TARGET_ARCH64"
3175   "andcc\t%0, 0xff, %%g0"
3176   [(set_attr "type" "compare")])
3178 (define_insn "*cmp_diqi_trunc_set"
3179   [(set (reg:CC CC_REG)
3180         (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
3181                     (const_int 0)))
3182    (set (match_operand:QI 0 "register_operand" "=r")
3183         (subreg:QI (match_dup 1) 7))]
3184   "TARGET_ARCH64"
3185   "andcc\t%1, 0xff, %0"
3186   [(set_attr "type" "compare")])
3189 ;; Sign-extension instructions
3191 ;; These patterns originally accepted general_operands, however, slightly
3192 ;; better code is generated by only accepting register_operands, and then
3193 ;; letting combine generate the lds[hb] insns.
3195 (define_expand "extendhisi2"
3196   [(set (match_operand:SI 0 "register_operand" "")
3197         (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
3198   ""
3200   rtx temp = gen_reg_rtx (SImode);
3201   rtx shift_16 = GEN_INT (16);
3202   int op1_subbyte = 0;
3204   if (GET_CODE (operand1) == SUBREG)
3205     {
3206       op1_subbyte = SUBREG_BYTE (operand1);
3207       op1_subbyte /= GET_MODE_SIZE (SImode);
3208       op1_subbyte *= GET_MODE_SIZE (SImode);
3209       operand1 = XEXP (operand1, 0);
3210     }
3212   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3213                           shift_16));
3214   emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
3215   DONE;
3218 (define_insn "*sign_extendhisi2_insn"
3219   [(set (match_operand:SI 0 "register_operand" "=r")
3220         (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3221   ""
3222   "ldsh\t%1, %0"
3223   [(set_attr "type" "sload")
3224    (set_attr "us3load_type" "3cycle")])
3226 (define_expand "extendqihi2"
3227   [(set (match_operand:HI 0 "register_operand" "")
3228         (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
3229   ""
3231   rtx temp = gen_reg_rtx (SImode);
3232   rtx shift_24 = GEN_INT (24);
3233   int op1_subbyte = 0;
3234   int op0_subbyte = 0;
3236   if (GET_CODE (operand1) == SUBREG)
3237     {
3238       op1_subbyte = SUBREG_BYTE (operand1);
3239       op1_subbyte /= GET_MODE_SIZE (SImode);
3240       op1_subbyte *= GET_MODE_SIZE (SImode);
3241       operand1 = XEXP (operand1, 0);
3242     }
3243   if (GET_CODE (operand0) == SUBREG)
3244     {
3245       op0_subbyte = SUBREG_BYTE (operand0);
3246       op0_subbyte /= GET_MODE_SIZE (SImode);
3247       op0_subbyte *= GET_MODE_SIZE (SImode);
3248       operand0 = XEXP (operand0, 0);
3249     }
3250   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3251                           shift_24));
3252   if (GET_MODE (operand0) != SImode)
3253     operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
3254   emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3255   DONE;
3258 (define_insn "*sign_extendqihi2_insn"
3259   [(set (match_operand:HI 0 "register_operand" "=r")
3260         (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3261   ""
3262   "ldsb\t%1, %0"
3263   [(set_attr "type" "sload")
3264    (set_attr "us3load_type" "3cycle")])
3266 (define_expand "extendqisi2"
3267   [(set (match_operand:SI 0 "register_operand" "")
3268         (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
3269   ""
3271   rtx temp = gen_reg_rtx (SImode);
3272   rtx shift_24 = GEN_INT (24);
3273   int op1_subbyte = 0;
3275   if (GET_CODE (operand1) == SUBREG)
3276     {
3277       op1_subbyte = SUBREG_BYTE (operand1);
3278       op1_subbyte /= GET_MODE_SIZE (SImode);
3279       op1_subbyte *= GET_MODE_SIZE (SImode);
3280       operand1 = XEXP (operand1, 0);
3281     }
3283   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3284                           shift_24));
3285   emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3286   DONE;
3289 (define_insn "*sign_extendqisi2_insn"
3290   [(set (match_operand:SI 0 "register_operand" "=r")
3291         (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3292   ""
3293   "ldsb\t%1, %0"
3294   [(set_attr "type" "sload")
3295    (set_attr "us3load_type" "3cycle")])
3297 (define_expand "extendqidi2"
3298   [(set (match_operand:DI 0 "register_operand" "")
3299         (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
3300   "TARGET_ARCH64"
3302   rtx temp = gen_reg_rtx (DImode);
3303   rtx shift_56 = GEN_INT (56);
3304   int op1_subbyte = 0;
3306   if (GET_CODE (operand1) == SUBREG)
3307     {
3308       op1_subbyte = SUBREG_BYTE (operand1);
3309       op1_subbyte /= GET_MODE_SIZE (DImode);
3310       op1_subbyte *= GET_MODE_SIZE (DImode);
3311       operand1 = XEXP (operand1, 0);
3312     }
3314   emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3315                           shift_56));
3316   emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
3317   DONE;
3320 (define_insn "*sign_extendqidi2_insn"
3321   [(set (match_operand:DI 0 "register_operand" "=r")
3322         (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3323   "TARGET_ARCH64"
3324   "ldsb\t%1, %0"
3325   [(set_attr "type" "sload")
3326    (set_attr "us3load_type" "3cycle")])
3328 (define_expand "extendhidi2"
3329   [(set (match_operand:DI 0 "register_operand" "")
3330         (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
3331   "TARGET_ARCH64"
3333   rtx temp = gen_reg_rtx (DImode);
3334   rtx shift_48 = GEN_INT (48);
3335   int op1_subbyte = 0;
3337   if (GET_CODE (operand1) == SUBREG)
3338     {
3339       op1_subbyte = SUBREG_BYTE (operand1);
3340       op1_subbyte /= GET_MODE_SIZE (DImode);
3341       op1_subbyte *= GET_MODE_SIZE (DImode);
3342       operand1 = XEXP (operand1, 0);
3343     }
3345   emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3346                           shift_48));
3347   emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
3348   DONE;
3351 (define_insn "*sign_extendhidi2_insn"
3352   [(set (match_operand:DI 0 "register_operand" "=r")
3353         (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3354   "TARGET_ARCH64"
3355   "ldsh\t%1, %0"
3356   [(set_attr "type" "sload")
3357    (set_attr "us3load_type" "3cycle")])
3359 (define_expand "extendsidi2"
3360   [(set (match_operand:DI 0 "register_operand" "")
3361         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3362   "TARGET_ARCH64"
3363   "")
3365 (define_insn "*sign_extendsidi2_insn"
3366   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
3367         (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m,*f")))]
3368   "TARGET_ARCH64"
3369   "@
3370   sra\t%1, 0, %0
3371   ldsw\t%1, %0
3372   movstosw\t%1, %0"
3373   [(set_attr "type" "shift,sload,*")
3374    (set_attr "us3load_type" "*,3cycle,*")
3375    (set_attr "cpu_feature" "*,*,vis3")])
3378 ;; Special pattern for optimizing bit-field compares.  This is needed
3379 ;; because combine uses this as a canonical form.
3381 (define_insn "*cmp_zero_extract"
3382   [(set (reg:CC CC_REG)
3383         (compare:CC
3384          (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
3385                           (match_operand:SI 1 "small_int_operand" "I")
3386                           (match_operand:SI 2 "small_int_operand" "I"))
3387          (const_int 0)))]
3388   "INTVAL (operands[2]) > 19"
3390   int len = INTVAL (operands[1]);
3391   int pos = 32 - INTVAL (operands[2]) - len;
3392   HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
3393   operands[1] = GEN_INT (mask);
3394   return "andcc\t%0, %1, %%g0";
3396   [(set_attr "type" "compare")])
3398 (define_insn "*cmp_zero_extract_sp64"
3399   [(set (reg:CCX CC_REG)
3400         (compare:CCX
3401          (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
3402                           (match_operand:SI 1 "small_int_operand" "I")
3403                           (match_operand:SI 2 "small_int_operand" "I"))
3404          (const_int 0)))]
3405   "TARGET_ARCH64 && INTVAL (operands[2]) > 51"
3407   int len = INTVAL (operands[1]);
3408   int pos = 64 - INTVAL (operands[2]) - len;
3409   HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
3410   operands[1] = GEN_INT (mask);
3411   return "andcc\t%0, %1, %%g0";
3413   [(set_attr "type" "compare")])
3416 ;; Conversions between float, double and long double.
3418 (define_insn "extendsfdf2"
3419   [(set (match_operand:DF 0 "register_operand" "=e")
3420         (float_extend:DF
3421          (match_operand:SF 1 "register_operand" "f")))]
3422   "TARGET_FPU"
3423   "fstod\t%1, %0"
3424   [(set_attr "type" "fp")
3425    (set_attr "fptype" "double")])
3427 (define_expand "extendsftf2"
3428   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3429         (float_extend:TF
3430          (match_operand:SF 1 "register_operand" "")))]
3431   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3432   "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3434 (define_insn "*extendsftf2_hq"
3435   [(set (match_operand:TF 0 "register_operand" "=e")
3436         (float_extend:TF
3437          (match_operand:SF 1 "register_operand" "f")))]
3438   "TARGET_FPU && TARGET_HARD_QUAD"
3439   "fstoq\t%1, %0"
3440   [(set_attr "type" "fp")])
3442 (define_expand "extenddftf2"
3443   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3444         (float_extend:TF
3445          (match_operand:DF 1 "register_operand" "")))]
3446   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3447   "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3449 (define_insn "*extenddftf2_hq"
3450   [(set (match_operand:TF 0 "register_operand" "=e")
3451         (float_extend:TF
3452          (match_operand:DF 1 "register_operand" "e")))]
3453   "TARGET_FPU && TARGET_HARD_QUAD"
3454   "fdtoq\t%1, %0"
3455   [(set_attr "type" "fp")])
3457 (define_insn "truncdfsf2"
3458   [(set (match_operand:SF 0 "register_operand" "=f")
3459         (float_truncate:SF
3460          (match_operand:DF 1 "register_operand" "e")))]
3461   "TARGET_FPU"
3462   "fdtos\t%1, %0"
3463   [(set_attr "type" "fp")
3464    (set_attr "fptype" "double")
3465    (set_attr "fptype_ut699" "single")])
3467 (define_expand "trunctfsf2"
3468   [(set (match_operand:SF 0 "register_operand" "")
3469         (float_truncate:SF
3470          (match_operand:TF 1 "general_operand" "")))]
3471   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3472   "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3474 (define_insn "*trunctfsf2_hq"
3475   [(set (match_operand:SF 0 "register_operand" "=f")
3476         (float_truncate:SF
3477          (match_operand:TF 1 "register_operand" "e")))]
3478   "TARGET_FPU && TARGET_HARD_QUAD"
3479   "fqtos\t%1, %0"
3480   [(set_attr "type" "fp")])
3482 (define_expand "trunctfdf2"
3483   [(set (match_operand:DF 0 "register_operand" "")
3484         (float_truncate:DF
3485          (match_operand:TF 1 "general_operand" "")))]
3486   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3487   "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3489 (define_insn "*trunctfdf2_hq"
3490   [(set (match_operand:DF 0 "register_operand" "=e")
3491         (float_truncate:DF
3492          (match_operand:TF 1 "register_operand" "e")))]
3493   "TARGET_FPU && TARGET_HARD_QUAD"
3494   "fqtod\t%1, %0"
3495   [(set_attr "type" "fp")])
3498 ;; Conversion between fixed point and floating point.
3500 (define_insn "floatsisf2"
3501   [(set (match_operand:SF 0 "register_operand" "=f")
3502         (float:SF (match_operand:SI 1 "register_operand" "f")))]
3503   "TARGET_FPU"
3504   "fitos\t%1, %0"
3505   [(set_attr "type" "fp")
3506    (set_attr "fptype" "single")])
3508 (define_insn "floatsidf2"
3509   [(set (match_operand:DF 0 "register_operand" "=e")
3510         (float:DF (match_operand:SI 1 "register_operand" "f")))]
3511   "TARGET_FPU"
3512   "fitod\t%1, %0"
3513   [(set_attr "type" "fp")
3514    (set_attr "fptype" "double")])
3516 (define_expand "floatsitf2"
3517   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3518         (float:TF (match_operand:SI 1 "register_operand" "")))]
3519   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3520   "emit_tfmode_cvt (FLOAT, operands); DONE;")
3522 (define_insn "*floatsitf2_hq"
3523   [(set (match_operand:TF 0 "register_operand" "=e")
3524         (float:TF (match_operand:SI 1 "register_operand" "f")))]
3525   "TARGET_FPU && TARGET_HARD_QUAD"
3526   "fitoq\t%1, %0"
3527   [(set_attr "type" "fp")])
3529 (define_expand "floatunssitf2"
3530   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3531         (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
3532   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3533   "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3535 ;; Now the same for 64 bit sources.
3537 (define_insn "floatdisf2"
3538   [(set (match_operand:SF 0 "register_operand" "=f")
3539         (float:SF (match_operand:DI 1 "register_operand" "e")))]
3540   "TARGET_V9 && TARGET_FPU"
3541   "fxtos\t%1, %0"
3542   [(set_attr "type" "fp")
3543    (set_attr "fptype" "double")])
3545 (define_expand "floatunsdisf2"
3546   [(use (match_operand:SF 0 "register_operand" ""))
3547    (use (match_operand:DI 1 "general_operand" ""))]
3548   "TARGET_ARCH64 && TARGET_FPU"
3549   "sparc_emit_floatunsdi (operands, SFmode); DONE;")
3551 (define_insn "floatdidf2"
3552   [(set (match_operand:DF 0 "register_operand" "=e")
3553         (float:DF (match_operand:DI 1 "register_operand" "e")))]
3554   "TARGET_V9 && TARGET_FPU"
3555   "fxtod\t%1, %0"
3556   [(set_attr "type" "fp")
3557    (set_attr "fptype" "double")])
3559 (define_expand "floatunsdidf2"
3560   [(use (match_operand:DF 0 "register_operand" ""))
3561    (use (match_operand:DI 1 "general_operand" ""))]
3562   "TARGET_ARCH64 && TARGET_FPU"
3563   "sparc_emit_floatunsdi (operands, DFmode); DONE;")
3565 (define_expand "floatditf2"
3566   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3567         (float:TF (match_operand:DI 1 "register_operand" "")))]
3568   "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3569   "emit_tfmode_cvt (FLOAT, operands); DONE;")
3571 (define_insn "*floatditf2_hq"
3572   [(set (match_operand:TF 0 "register_operand" "=e")
3573         (float:TF (match_operand:DI 1 "register_operand" "e")))]
3574   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3575   "fxtoq\t%1, %0"
3576   [(set_attr "type" "fp")])
3578 (define_expand "floatunsditf2"
3579   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3580         (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
3581   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3582   "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3584 ;; Convert a float to an actual integer.
3585 ;; Truncation is performed as part of the conversion.
3587 (define_insn "fix_truncsfsi2"
3588   [(set (match_operand:SI 0 "register_operand" "=f")
3589         (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3590   "TARGET_FPU"
3591   "fstoi\t%1, %0"
3592   [(set_attr "type" "fp")
3593    (set_attr "fptype" "single")])
3595 (define_insn "fix_truncdfsi2"
3596   [(set (match_operand:SI 0 "register_operand" "=f")
3597         (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3598   "TARGET_FPU"
3599   "fdtoi\t%1, %0"
3600   [(set_attr "type" "fp")
3601    (set_attr "fptype" "double")
3602    (set_attr "fptype_ut699" "single")])
3604 (define_expand "fix_trunctfsi2"
3605   [(set (match_operand:SI 0 "register_operand" "")
3606         (fix:SI (match_operand:TF 1 "general_operand" "")))]
3607   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3608   "emit_tfmode_cvt (FIX, operands); DONE;")
3610 (define_insn "*fix_trunctfsi2_hq"
3611   [(set (match_operand:SI 0 "register_operand" "=f")
3612         (fix:SI (match_operand:TF 1 "register_operand" "e")))]
3613   "TARGET_FPU && TARGET_HARD_QUAD"
3614   "fqtoi\t%1, %0"
3615   [(set_attr "type" "fp")])
3617 (define_expand "fixuns_trunctfsi2"
3618   [(set (match_operand:SI 0 "register_operand" "")
3619         (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
3620   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3621   "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3623 ;; Now the same, for V9 targets
3625 (define_insn "fix_truncsfdi2"
3626   [(set (match_operand:DI 0 "register_operand" "=e")
3627         (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3628   "TARGET_V9 && TARGET_FPU"
3629   "fstox\t%1, %0"
3630   [(set_attr "type" "fp")
3631    (set_attr "fptype" "double")])
3633 (define_expand "fixuns_truncsfdi2"
3634   [(use (match_operand:DI 0 "register_operand" ""))
3635    (use (match_operand:SF 1 "general_operand" ""))]
3636   "TARGET_ARCH64 && TARGET_FPU"
3637   "sparc_emit_fixunsdi (operands, SFmode); DONE;")
3639 (define_insn "fix_truncdfdi2"
3640   [(set (match_operand:DI 0 "register_operand" "=e")
3641         (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3642   "TARGET_V9 && TARGET_FPU"
3643   "fdtox\t%1, %0"
3644   [(set_attr "type" "fp")
3645    (set_attr "fptype" "double")])
3647 (define_expand "fixuns_truncdfdi2"
3648   [(use (match_operand:DI 0 "register_operand" ""))
3649    (use (match_operand:DF 1 "general_operand" ""))]
3650   "TARGET_ARCH64 && TARGET_FPU"
3651   "sparc_emit_fixunsdi (operands, DFmode); DONE;")
3653 (define_expand "fix_trunctfdi2"
3654   [(set (match_operand:DI 0 "register_operand" "")
3655         (fix:DI (match_operand:TF 1 "general_operand" "")))]
3656   "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3657   "emit_tfmode_cvt (FIX, operands); DONE;")
3659 (define_insn "*fix_trunctfdi2_hq"
3660   [(set (match_operand:DI 0 "register_operand" "=e")
3661         (fix:DI (match_operand:TF 1 "register_operand" "e")))]
3662   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3663   "fqtox\t%1, %0"
3664   [(set_attr "type" "fp")])
3666 (define_expand "fixuns_trunctfdi2"
3667   [(set (match_operand:DI 0 "register_operand" "")
3668         (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
3669   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3670   "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3673 ;; Integer addition/subtraction instructions.
3675 (define_expand "adddi3"
3676   [(set (match_operand:DI 0 "register_operand" "")
3677         (plus:DI (match_operand:DI 1 "register_operand" "")
3678                  (match_operand:DI 2 "arith_double_add_operand" "")))]
3679   ""
3681   if (! TARGET_ARCH64)
3682     {
3683       emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3684                           gen_rtx_SET (VOIDmode, operands[0],
3685                                    gen_rtx_PLUS (DImode, operands[1],
3686                                                  operands[2])),
3687                           gen_rtx_CLOBBER (VOIDmode,
3688                                    gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3689       DONE;
3690     }
3693 (define_insn_and_split "*adddi3_insn_sp32"
3694   [(set (match_operand:DI 0 "register_operand" "=&r")
3695         (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
3696                  (match_operand:DI 2 "arith_double_operand" "rHI")))
3697    (clobber (reg:CC CC_REG))]
3698   "! TARGET_ARCH64"
3699   "#"
3700   "&& reload_completed"
3701   [(parallel [(set (reg:CC_NOOV CC_REG)
3702                    (compare:CC_NOOV (plus:SI (match_dup 4)
3703                                              (match_dup 5))
3704                                     (const_int 0)))
3705               (set (match_dup 3)
3706                    (plus:SI (match_dup 4) (match_dup 5)))])
3707    (set (match_dup 6)
3708         (plus:SI (plus:SI (match_dup 7)
3709                           (match_dup 8))
3710                  (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3712   operands[3] = gen_lowpart (SImode, operands[0]);
3713   operands[4] = gen_lowpart (SImode, operands[1]);
3714   operands[5] = gen_lowpart (SImode, operands[2]);
3715   operands[6] = gen_highpart (SImode, operands[0]);
3716   operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
3717 #if HOST_BITS_PER_WIDE_INT == 32
3718   if (GET_CODE (operands[2]) == CONST_INT)
3719     {
3720       if (INTVAL (operands[2]) < 0)
3721         operands[8] = constm1_rtx;
3722       else
3723         operands[8] = const0_rtx;
3724     }
3725   else
3726 #endif
3727     operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3729   [(set_attr "length" "2")])
3731 ;; LTU here means "carry set"
3732 (define_insn "addx"
3733   [(set (match_operand:SI 0 "register_operand" "=r")
3734         (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3735                           (match_operand:SI 2 "arith_operand" "rI"))
3736                  (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3737   ""
3738   "addx\t%1, %2, %0"
3739   [(set_attr "type" "ialuX")])
3741 (define_insn "addxc"
3742   [(set (match_operand:DI 0 "register_operand" "=r")
3743         (plus:DI (plus:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
3744                           (match_operand:DI 2 "register_or_zero_operand" "rJ"))
3745                  (ltu:DI (reg:CCX_NOOV CC_REG) (const_int 0))))]
3746   "TARGET_ARCH64 && TARGET_VIS3"
3747   "addxc\t%r1, %r2, %0"
3748   [(set_attr "type" "ialuX")])
3750 (define_insn_and_split "*addx_extend_sp32"
3751   [(set (match_operand:DI 0 "register_operand" "=r")
3752         (zero_extend:DI (plus:SI (plus:SI
3753                                   (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3754                                   (match_operand:SI 2 "arith_operand" "rI"))
3755                                  (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3756   "! TARGET_ARCH64"
3757   "#"
3758   "&& reload_completed"
3759   [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
3760                                (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))
3761    (set (match_dup 4) (const_int 0))]
3762   "operands[3] = gen_lowpart (SImode, operands[0]);
3763    operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
3764   [(set_attr "length" "2")])
3766 (define_insn "*addx_extend_sp64"
3767   [(set (match_operand:DI 0 "register_operand" "=r")
3768         (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3769                                           (match_operand:SI 2 "register_or_zero_operand" "rJ"))
3770                                  (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3771   "TARGET_ARCH64"
3772   "addx\t%r1, %r2, %0"
3773   [(set_attr "type" "ialuX")])
3775 (define_insn "*addxc_trunc_sp64_vis3"
3776   [(set (match_operand:SI 0 "register_operand" "=r")
3777         (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3778                           (match_operand:SI 2 "register_or_zero_operand" "rJ"))
3779                  (ltu:SI (reg:CCX_NOOV CC_REG) (const_int 0))))]
3780   "TARGET_ARCH64 && TARGET_VIS3"
3781   "addxc\t%r1, %r2, %0"
3782   [(set_attr "type" "ialuX")])
3784 (define_insn_and_split "*adddi3_extend_sp32"
3785   [(set (match_operand:DI 0 "register_operand" "=r")
3786         (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
3787                  (match_operand:DI 2 "register_operand" "r")))
3788    (clobber (reg:CC CC_REG))]
3789   "! TARGET_ARCH64"
3790   "#"
3791   "&& reload_completed"
3792   [(parallel [(set (reg:CC_NOOV CC_REG)
3793                    (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
3794                                     (const_int 0)))
3795               (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
3796    (set (match_dup 6)
3797         (plus:SI (plus:SI (match_dup 4) (const_int 0))
3798                  (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3799   "operands[3] = gen_lowpart (SImode, operands[2]);
3800    operands[4] = gen_highpart (SImode, operands[2]);
3801    operands[5] = gen_lowpart (SImode, operands[0]);
3802    operands[6] = gen_highpart (SImode, operands[0]);"
3803   [(set_attr "length" "2")])
3805 (define_insn "*adddi3_sp64"
3806   [(set (match_operand:DI 0 "register_operand" "=r,r")
3807         (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
3808                  (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3809   "TARGET_ARCH64"
3810   "@
3811    add\t%1, %2, %0
3812    sub\t%1, -%2, %0")
3814 (define_insn "addsi3"
3815   [(set (match_operand:SI 0 "register_operand" "=r,r")
3816         (plus:SI (match_operand:SI 1 "register_operand" "%r,r")
3817                  (match_operand:SI 2 "arith_add_operand" "rI,O")))]
3818   ""
3819   "@
3820    add\t%1, %2, %0
3821    sub\t%1, -%2, %0"
3822   [(set_attr "type" "*,*")
3823    (set_attr "fptype" "*,*")])
3825 (define_insn "*cmp_cc_plus"
3826   [(set (reg:CC_NOOV CC_REG)
3827         (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
3828                                   (match_operand:SI 1 "arith_operand" "rI"))
3829                          (const_int 0)))]
3830   ""
3831   "addcc\t%0, %1, %%g0"
3832   [(set_attr "type" "compare")])
3834 (define_insn "*cmp_ccx_plus"
3835   [(set (reg:CCX_NOOV CC_REG)
3836         (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_operand" "%r")
3837                                    (match_operand:DI 1 "arith_operand" "rI"))
3838                           (const_int 0)))]
3839   "TARGET_ARCH64"
3840   "addcc\t%0, %1, %%g0"
3841   [(set_attr "type" "compare")])
3843 (define_insn "*cmp_cc_plus_set"
3844   [(set (reg:CC_NOOV CC_REG)
3845         (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3846                                   (match_operand:SI 2 "arith_operand" "rI"))
3847                          (const_int 0)))
3848    (set (match_operand:SI 0 "register_operand" "=r")
3849         (plus:SI (match_dup 1) (match_dup 2)))]
3850   ""
3851   "addcc\t%1, %2, %0"
3852   [(set_attr "type" "compare")])
3854 (define_insn "*cmp_ccx_plus_set"
3855   [(set (reg:CCX_NOOV CC_REG)
3856         (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_operand" "%r")
3857                                    (match_operand:DI 2 "arith_operand" "rI"))
3858                           (const_int 0)))
3859    (set (match_operand:DI 0 "register_operand" "=r")
3860         (plus:DI (match_dup 1) (match_dup 2)))]
3861   "TARGET_ARCH64"
3862   "addcc\t%1, %2, %0"
3863   [(set_attr "type" "compare")])
3865 (define_expand "subdi3"
3866   [(set (match_operand:DI 0 "register_operand" "")
3867         (minus:DI (match_operand:DI 1 "register_operand" "")
3868                   (match_operand:DI 2 "arith_double_add_operand" "")))]
3869   ""
3871   if (! TARGET_ARCH64)
3872     {
3873       emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3874                           gen_rtx_SET (VOIDmode, operands[0],
3875                                    gen_rtx_MINUS (DImode, operands[1],
3876                                                   operands[2])),
3877                           gen_rtx_CLOBBER (VOIDmode,
3878                                    gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3879       DONE;
3880     }
3883 (define_insn_and_split "*subdi3_insn_sp32"
3884   [(set (match_operand:DI 0 "register_operand" "=r")
3885         (minus:DI (match_operand:DI 1 "register_operand" "r")
3886                   (match_operand:DI 2 "arith_double_operand" "rHI")))
3887    (clobber (reg:CC CC_REG))]
3888   "! TARGET_ARCH64"
3889   "#"
3890   "&& reload_completed"
3891   [(parallel [(set (reg:CC_NOOV CC_REG)
3892                    (compare:CC_NOOV (minus:SI (match_dup 4)
3893                                               (match_dup 5))
3894                                     (const_int 0)))
3895               (set (match_dup 3)
3896                    (minus:SI (match_dup 4) (match_dup 5)))])
3897    (set (match_dup 6)
3898         (minus:SI (minus:SI (match_dup 7)
3899                             (match_dup 8))
3900                   (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3902   operands[3] = gen_lowpart (SImode, operands[0]);
3903   operands[4] = gen_lowpart (SImode, operands[1]);
3904   operands[5] = gen_lowpart (SImode, operands[2]);
3905   operands[6] = gen_highpart (SImode, operands[0]);
3906   operands[7] = gen_highpart (SImode, operands[1]);
3907 #if HOST_BITS_PER_WIDE_INT == 32
3908   if (GET_CODE (operands[2]) == CONST_INT)
3909     {
3910       if (INTVAL (operands[2]) < 0)
3911         operands[8] = constm1_rtx;
3912       else
3913         operands[8] = const0_rtx;
3914     }
3915   else
3916 #endif
3917     operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3919   [(set_attr "length" "2")])
3921 ;; LTU here means "carry set"
3922 (define_insn "subx"
3923   [(set (match_operand:SI 0 "register_operand" "=r")
3924         (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3925                             (match_operand:SI 2 "arith_operand" "rI"))
3926                   (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3927   ""
3928   "subx\t%r1, %2, %0"
3929   [(set_attr "type" "ialuX")])
3931 (define_insn "*subx_extend_sp64"
3932   [(set (match_operand:DI 0 "register_operand" "=r")
3933         (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3934                                             (match_operand:SI 2 "arith_operand" "rI"))
3935                                   (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3936   "TARGET_ARCH64"
3937   "subx\t%r1, %2, %0"
3938   [(set_attr "type" "ialuX")])
3940 (define_insn_and_split "*subx_extend"
3941   [(set (match_operand:DI 0 "register_operand" "=r")
3942         (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3943                                             (match_operand:SI 2 "arith_operand" "rI"))
3944                                   (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3945   "! TARGET_ARCH64"
3946   "#"
3947   "&& reload_completed"
3948   [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
3949                                 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))
3950    (set (match_dup 4) (const_int 0))]
3951   "operands[3] = gen_lowpart (SImode, operands[0]);
3952    operands[4] = gen_highpart (SImode, operands[0]);"
3953   [(set_attr "length" "2")])
3955 (define_insn_and_split "*subdi3_extend_sp32"
3956   [(set (match_operand:DI 0 "register_operand" "=r")
3957       (minus:DI (match_operand:DI 1 "register_operand" "r")
3958                 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
3959    (clobber (reg:CC CC_REG))]
3960   "! TARGET_ARCH64"
3961   "#"
3962   "&& reload_completed"
3963   [(parallel [(set (reg:CC_NOOV CC_REG)
3964                    (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
3965                                     (const_int 0)))
3966               (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
3967    (set (match_dup 6)
3968         (minus:SI (minus:SI (match_dup 4) (const_int 0))
3969                   (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3970   "operands[3] = gen_lowpart (SImode, operands[1]);
3971    operands[4] = gen_highpart (SImode, operands[1]);
3972    operands[5] = gen_lowpart (SImode, operands[0]);
3973    operands[6] = gen_highpart (SImode, operands[0]);"
3974   [(set_attr "length" "2")])
3976 (define_insn "*subdi3_sp64"
3977   [(set (match_operand:DI 0 "register_operand" "=r,r")
3978         (minus:DI (match_operand:DI 1 "register_operand" "r,r")
3979                   (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3980   "TARGET_ARCH64"
3981   "@
3982    sub\t%1, %2, %0
3983    add\t%1, -%2, %0")
3985 (define_insn "subsi3"
3986   [(set (match_operand:SI 0 "register_operand" "=r,r")
3987         (minus:SI (match_operand:SI 1 "register_operand" "r,r")
3988                   (match_operand:SI 2 "arith_add_operand" "rI,O")))]
3989   ""
3990   "@
3991    sub\t%1, %2, %0
3992    add\t%1, -%2, %0"
3993   [(set_attr "type" "*,*")
3994    (set_attr "fptype" "*,*")])
3996 (define_insn "*cmp_minus_cc"
3997   [(set (reg:CC_NOOV CC_REG)
3998         (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
3999                                    (match_operand:SI 1 "arith_operand" "rI"))
4000                          (const_int 0)))]
4001   ""
4002   "subcc\t%r0, %1, %%g0"
4003   [(set_attr "type" "compare")])
4005 (define_insn "*cmp_minus_ccx"
4006   [(set (reg:CCX_NOOV CC_REG)
4007         (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
4008                                     (match_operand:DI 1 "arith_operand" "rI"))
4009                           (const_int 0)))]
4010   "TARGET_ARCH64"
4011   "subcc\t%0, %1, %%g0"
4012   [(set_attr "type" "compare")])
4014 (define_insn "cmp_minus_cc_set"
4015   [(set (reg:CC_NOOV CC_REG)
4016         (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4017                                    (match_operand:SI 2 "arith_operand" "rI"))
4018                          (const_int 0)))
4019    (set (match_operand:SI 0 "register_operand" "=r")
4020         (minus:SI (match_dup 1) (match_dup 2)))]
4021   ""
4022   "subcc\t%r1, %2, %0"
4023   [(set_attr "type" "compare")])
4025 (define_insn "*cmp_minus_ccx_set"
4026   [(set (reg:CCX_NOOV CC_REG)
4027         (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
4028                                     (match_operand:DI 2 "arith_operand" "rI"))
4029                           (const_int 0)))
4030    (set (match_operand:DI 0 "register_operand" "=r")
4031         (minus:DI (match_dup 1) (match_dup 2)))]
4032   "TARGET_ARCH64"
4033   "subcc\t%1, %2, %0"
4034   [(set_attr "type" "compare")])
4037 ;; Integer multiply/divide instructions.
4039 ;; The 32-bit multiply/divide instructions are deprecated on v9, but at
4040 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
4042 (define_insn "mulsi3"
4043   [(set (match_operand:SI 0 "register_operand" "=r")
4044         (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4045                  (match_operand:SI 2 "arith_operand" "rI")))]
4046   "TARGET_HARD_MUL"
4047   "smul\t%1, %2, %0"
4048   [(set_attr "type" "imul")])
4050 (define_expand "muldi3"
4051   [(set (match_operand:DI 0 "register_operand" "")
4052         (mult:DI (match_operand:DI 1 "arith_operand" "")
4053                  (match_operand:DI 2 "arith_operand" "")))]
4054   "TARGET_ARCH64 || TARGET_V8PLUS"
4056   if (TARGET_V8PLUS)
4057     {
4058       emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
4059       DONE;
4060     }
4063 (define_insn "*muldi3_sp64"
4064   [(set (match_operand:DI 0 "register_operand" "=r")
4065         (mult:DI (match_operand:DI 1 "arith_operand" "%r")
4066                  (match_operand:DI 2 "arith_operand" "rI")))]
4067   "TARGET_ARCH64"
4068   "mulx\t%1, %2, %0"
4069   [(set_attr "type" "imul")])
4071 ;; V8plus wide multiply.
4072 ;; XXX
4073 (define_insn "muldi3_v8plus"
4074   [(set (match_operand:DI 0 "register_operand" "=r,h")
4075         (mult:DI (match_operand:DI 1 "arith_operand" "%r,0")
4076                  (match_operand:DI 2 "arith_operand" "rI,rI")))
4077    (clobber (match_scratch:SI 3 "=&h,X"))
4078    (clobber (match_scratch:SI 4 "=&h,X"))]
4079   "TARGET_V8PLUS"
4080   "* return output_v8plus_mult (insn, operands, \"mulx\");"
4081   [(set_attr "type" "multi")
4082    (set_attr "length" "9,8")])
4084 (define_insn "*cmp_mul_set"
4085   [(set (reg:CC CC_REG)
4086         (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4087                     (match_operand:SI 2 "arith_operand" "rI"))
4088                     (const_int 0)))
4089    (set (match_operand:SI 0 "register_operand" "=r")
4090         (mult:SI (match_dup 1) (match_dup 2)))]
4091   "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
4092   "smulcc\t%1, %2, %0"
4093   [(set_attr "type" "imul")])
4095 (define_expand "mulsidi3"
4096   [(set (match_operand:DI 0 "register_operand" "")
4097         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4098                  (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
4099   "TARGET_HARD_MUL"
4101   if (CONSTANT_P (operands[2]))
4102     {
4103       if (TARGET_V8PLUS)
4104         emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
4105                                               operands[2]));
4106       else if (TARGET_ARCH32)
4107         emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
4108                                             operands[2]));
4109       else 
4110         emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
4111                                             operands[2]));
4112       DONE;
4113     }
4114   if (TARGET_V8PLUS)
4115     {
4116       emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
4117       DONE;
4118     }
4121 ;; V9 puts the 64-bit product in a 64-bit register.  Only out or global
4122 ;; registers can hold 64-bit values in the V8plus environment.
4123 ;; XXX
4124 (define_insn "mulsidi3_v8plus"
4125   [(set (match_operand:DI 0 "register_operand" "=h,r")
4126         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4127                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4128    (clobber (match_scratch:SI 3 "=X,&h"))]
4129   "TARGET_V8PLUS"
4130   "@
4131    smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4132    smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4133   [(set_attr "type" "multi")
4134    (set_attr "length" "2,3")])
4136 ;; XXX
4137 (define_insn "const_mulsidi3_v8plus"
4138   [(set (match_operand:DI 0 "register_operand" "=h,r")
4139         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4140                  (match_operand:DI 2 "small_int_operand" "I,I")))
4141    (clobber (match_scratch:SI 3 "=X,&h"))]
4142   "TARGET_V8PLUS"
4143   "@
4144    smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4145    smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4146   [(set_attr "type" "multi")
4147    (set_attr "length" "2,3")])
4149 ;; XXX
4150 (define_insn "*mulsidi3_sp32"
4151   [(set (match_operand:DI 0 "register_operand" "=r")
4152         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4153                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4154   "TARGET_HARD_MUL32"
4156   return TARGET_SPARCLET
4157          ? "smuld\t%1, %2, %L0"
4158          : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4160   [(set (attr "type")
4161         (if_then_else (eq_attr "isa" "sparclet")
4162                       (const_string "imul") (const_string "multi")))
4163    (set (attr "length")
4164         (if_then_else (eq_attr "isa" "sparclet")
4165                       (const_int 1) (const_int 2)))])
4167 (define_insn "*mulsidi3_sp64"
4168   [(set (match_operand:DI 0 "register_operand" "=r")
4169         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4170                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4171   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4172   "smul\t%1, %2, %0"
4173   [(set_attr "type" "imul")])
4175 ;; Extra pattern, because sign_extend of a constant isn't valid.
4177 ;; XXX
4178 (define_insn "const_mulsidi3_sp32"
4179   [(set (match_operand:DI 0 "register_operand" "=r")
4180         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4181                  (match_operand:DI 2 "small_int_operand" "I")))]
4182   "TARGET_HARD_MUL32"
4184   return TARGET_SPARCLET
4185          ? "smuld\t%1, %2, %L0"
4186          : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4188   [(set (attr "type")
4189         (if_then_else (eq_attr "isa" "sparclet")
4190                       (const_string "imul") (const_string "multi")))
4191    (set (attr "length")
4192         (if_then_else (eq_attr "isa" "sparclet")
4193                       (const_int 1) (const_int 2)))])
4195 (define_insn "const_mulsidi3_sp64"
4196   [(set (match_operand:DI 0 "register_operand" "=r")
4197         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4198                  (match_operand:DI 2 "small_int_operand" "I")))]
4199   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4200   "smul\t%1, %2, %0"
4201   [(set_attr "type" "imul")])
4203 (define_expand "smulsi3_highpart"
4204   [(set (match_operand:SI 0 "register_operand" "")
4205         (truncate:SI
4206          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4207                                (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
4208                       (const_int 32))))]
4209   "TARGET_HARD_MUL && TARGET_ARCH32"
4211   if (CONSTANT_P (operands[2]))
4212     {
4213       if (TARGET_V8PLUS)
4214         {
4215           emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
4216                                                         operands[1],
4217                                                         operands[2],
4218                                                         GEN_INT (32)));
4219           DONE;
4220         }
4221       emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
4222       DONE;
4223     }
4224   if (TARGET_V8PLUS)
4225     {
4226       emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
4227                                               operands[2], GEN_INT (32)));
4228       DONE;
4229     }
4232 ;; XXX
4233 (define_insn "smulsi3_highpart_v8plus"
4234   [(set (match_operand:SI 0 "register_operand" "=h,r")
4235         (truncate:SI
4236          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4237                                (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4238                       (match_operand:SI 3 "small_int_operand" "I,I"))))
4239    (clobber (match_scratch:SI 4 "=X,&h"))]
4240   "TARGET_V8PLUS"
4241   "@
4242    smul\t%1, %2, %0\;srlx\t%0, %3, %0
4243    smul\t%1, %2, %4\;srlx\t%4, %3, %0"
4244   [(set_attr "type" "multi")
4245    (set_attr "length" "2")])
4247 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
4248 ;; XXX
4249 (define_insn ""
4250   [(set (match_operand:SI 0 "register_operand" "=h,r")
4251         (subreg:SI
4252          (lshiftrt:DI
4253           (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4254                    (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4255           (match_operand:SI 3 "small_int_operand" "I,I"))
4256          4))
4257    (clobber (match_scratch:SI 4 "=X,&h"))]
4258   "TARGET_V8PLUS"
4259   "@
4260    smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4261    smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4262   [(set_attr "type" "multi")
4263    (set_attr "length" "2")])
4265 ;; XXX
4266 (define_insn "const_smulsi3_highpart_v8plus"
4267   [(set (match_operand:SI 0 "register_operand" "=h,r")
4268         (truncate:SI
4269          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4270                                (match_operand:DI 2 "small_int_operand" "I,I"))
4271                       (match_operand:SI 3 "small_int_operand" "I,I"))))
4272    (clobber (match_scratch:SI 4 "=X,&h"))]
4273   "TARGET_V8PLUS"
4274   "@
4275    smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4276    smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4277   [(set_attr "type" "multi")
4278    (set_attr "length" "2")])
4280 ;; XXX
4281 (define_insn "*smulsi3_highpart_sp32"
4282   [(set (match_operand:SI 0 "register_operand" "=r")
4283         (truncate:SI
4284          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4285                                (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
4286                       (const_int 32))))]
4287   "TARGET_HARD_MUL32"
4288   "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4289   [(set_attr "type" "multi")
4290    (set_attr "length" "2")])
4292 ;; XXX
4293 (define_insn "const_smulsi3_highpart"
4294   [(set (match_operand:SI 0 "register_operand" "=r")
4295         (truncate:SI
4296          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4297                                (match_operand:DI 2 "small_int_operand" "i"))
4298                       (const_int 32))))]
4299   "TARGET_HARD_MUL32"
4300   "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4301   [(set_attr "type" "multi")
4302    (set_attr "length" "2")])
4304 (define_expand "umulsidi3"
4305   [(set (match_operand:DI 0 "register_operand" "")
4306         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4307                  (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
4308   "TARGET_HARD_MUL"
4310   if (CONSTANT_P (operands[2]))
4311     {
4312       if (TARGET_V8PLUS)
4313         emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
4314                                                operands[2]));
4315       else if (TARGET_ARCH32)
4316         emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
4317                                              operands[2]));
4318       else 
4319         emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
4320                                              operands[2]));
4321       DONE;
4322     }
4323   if (TARGET_V8PLUS)
4324     {
4325       emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
4326       DONE;
4327     }
4330 ;; XXX
4331 (define_insn "umulsidi3_v8plus"
4332   [(set (match_operand:DI 0 "register_operand" "=h,r")
4333         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4334                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4335    (clobber (match_scratch:SI 3 "=X,&h"))]
4336   "TARGET_V8PLUS"
4337   "@
4338    umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4339    umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4340   [(set_attr "type" "multi")
4341    (set_attr "length" "2,3")])
4343 ;; XXX
4344 (define_insn "*umulsidi3_sp32"
4345   [(set (match_operand:DI 0 "register_operand" "=r")
4346         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4347                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4348   "TARGET_HARD_MUL32"
4350   return TARGET_SPARCLET
4351          ? "umuld\t%1, %2, %L0"
4352          : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
4354   [(set (attr "type")
4355         (if_then_else (eq_attr "isa" "sparclet")
4356                       (const_string "imul") (const_string "multi")))
4357    (set (attr "length")
4358         (if_then_else (eq_attr "isa" "sparclet")
4359                       (const_int 1) (const_int 2)))])
4361 (define_insn "*umulsidi3_sp64"
4362   [(set (match_operand:DI 0 "register_operand" "=r")
4363         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4364                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4365   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4366   "umul\t%1, %2, %0"
4367   [(set_attr "type" "imul")])
4369 ;; Extra pattern, because sign_extend of a constant isn't valid.
4371 ;; XXX
4372 (define_insn "const_umulsidi3_sp32"
4373   [(set (match_operand:DI 0 "register_operand" "=r")
4374         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4375                  (match_operand:DI 2 "uns_small_int_operand" "")))]
4376   "TARGET_HARD_MUL32"
4378   return TARGET_SPARCLET
4379          ? "umuld\t%1, %s2, %L0"
4380          : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
4382   [(set (attr "type")
4383         (if_then_else (eq_attr "isa" "sparclet")
4384                       (const_string "imul") (const_string "multi")))
4385    (set (attr "length")
4386         (if_then_else (eq_attr "isa" "sparclet")
4387                       (const_int 1) (const_int 2)))])
4389 (define_insn "const_umulsidi3_sp64"
4390   [(set (match_operand:DI 0 "register_operand" "=r")
4391         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4392                  (match_operand:DI 2 "uns_small_int_operand" "")))]
4393   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4394   "umul\t%1, %s2, %0"
4395   [(set_attr "type" "imul")])
4397 ;; XXX
4398 (define_insn "const_umulsidi3_v8plus"
4399   [(set (match_operand:DI 0 "register_operand" "=h,r")
4400         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4401                  (match_operand:DI 2 "uns_small_int_operand" "")))
4402    (clobber (match_scratch:SI 3 "=X,h"))]
4403   "TARGET_V8PLUS"
4404   "@
4405    umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
4406    umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4407   [(set_attr "type" "multi")
4408    (set_attr "length" "2,3")])
4410 (define_expand "umulsi3_highpart"
4411   [(set (match_operand:SI 0 "register_operand" "")
4412         (truncate:SI
4413          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4414                                (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
4415                       (const_int 32))))]
4416   "TARGET_HARD_MUL && TARGET_ARCH32"
4418   if (CONSTANT_P (operands[2]))
4419     {
4420       if (TARGET_V8PLUS)
4421         {
4422           emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
4423                                                         operands[1],
4424                                                         operands[2],
4425                                                         GEN_INT (32)));
4426           DONE;
4427         }
4428       emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
4429       DONE;
4430     }
4431   if (TARGET_V8PLUS)
4432     {
4433       emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
4434                                               operands[2], GEN_INT (32)));
4435       DONE;
4436     }
4439 ;; XXX
4440 (define_insn "umulsi3_highpart_v8plus"
4441   [(set (match_operand:SI 0 "register_operand" "=h,r")
4442         (truncate:SI
4443          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4444                                (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4445                       (match_operand:SI 3 "small_int_operand" "I,I"))))
4446    (clobber (match_scratch:SI 4 "=X,h"))]
4447   "TARGET_V8PLUS"
4448   "@
4449    umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4450    umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4451   [(set_attr "type" "multi")
4452    (set_attr "length" "2")])
4454 ;; XXX
4455 (define_insn "const_umulsi3_highpart_v8plus"
4456   [(set (match_operand:SI 0 "register_operand" "=h,r")
4457         (truncate:SI
4458          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4459                                (match_operand:DI 2 "uns_small_int_operand" ""))
4460                       (match_operand:SI 3 "small_int_operand" "I,I"))))
4461    (clobber (match_scratch:SI 4 "=X,h"))]
4462   "TARGET_V8PLUS"
4463   "@
4464    umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
4465    umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
4466   [(set_attr "type" "multi")
4467    (set_attr "length" "2")])
4469 ;; XXX
4470 (define_insn "*umulsi3_highpart_sp32"
4471   [(set (match_operand:SI 0 "register_operand" "=r")
4472         (truncate:SI
4473          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4474                                (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
4475                       (const_int 32))))]
4476   "TARGET_HARD_MUL32"
4477   "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
4478   [(set_attr "type" "multi")
4479    (set_attr "length" "2")])
4481 ;; XXX
4482 (define_insn "const_umulsi3_highpart"
4483   [(set (match_operand:SI 0 "register_operand" "=r")
4484         (truncate:SI
4485          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4486                                (match_operand:DI 2 "uns_small_int_operand" ""))
4487                       (const_int 32))))]
4488   "TARGET_HARD_MUL32"
4489   "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
4490   [(set_attr "type" "multi")
4491    (set_attr "length" "2")])
4493 (define_expand "divsi3"
4494   [(parallel [(set (match_operand:SI 0 "register_operand" "")
4495                    (div:SI (match_operand:SI 1 "register_operand" "")
4496                            (match_operand:SI 2 "input_operand" "")))
4497               (clobber (match_scratch:SI 3 ""))])]
4498   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4500   if (TARGET_ARCH64)
4501     {
4502       operands[3] = gen_reg_rtx(SImode);
4503       emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
4504       emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
4505                                   operands[3]));
4506       DONE;
4507     }
4510 ;; The V8 architecture specifies that there must be at least 3 instructions
4511 ;; between a write to the Y register and a use of it for correct results.
4512 ;; We try to fill one of them with a simple constant or a memory load.
4514 (define_insn "divsi3_sp32"
4515   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
4516         (div:SI (match_operand:SI 1 "register_operand" "r,r,r")
4517                 (match_operand:SI 2 "input_operand" "rI,K,m")))
4518    (clobber (match_scratch:SI 3 "=&r,&r,&r"))]
4519   "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4521   output_asm_insn ("sra\t%1, 31, %3", operands);
4522   output_asm_insn ("wr\t%3, 0, %%y", operands);
4524   switch (which_alternative)
4525     {
4526     case 0:
4527       if (TARGET_V9)
4528         return "sdiv\t%1, %2, %0";
4529       else
4530         return "nop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
4531     case 1:
4532       if (TARGET_V9)
4533         return "sethi\t%%hi(%a2), %3\n\tsdiv\t%1, %3, %0";
4534       else
4535         return "sethi\t%%hi(%a2), %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4536     case 2:
4537       if (TARGET_V9)
4538         return "ld\t%2, %3\n\tsdiv\t%1, %3, %0";
4539       else
4540         return "ld\t%2, %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4541     default:
4542       gcc_unreachable ();
4543     }
4545   [(set_attr "type" "multi")
4546    (set (attr "length")
4547         (if_then_else (eq_attr "isa" "v9")
4548                       (const_int 4) (const_int 6)))])
4550 (define_insn "divsi3_sp64"
4551   [(set (match_operand:SI 0 "register_operand" "=r")
4552         (div:SI (match_operand:SI 1 "register_operand" "r")
4553                 (match_operand:SI 2 "input_operand" "rI")))
4554    (use (match_operand:SI 3 "register_operand" "r"))]
4555   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4556   "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
4557   [(set_attr "type" "multi")
4558    (set_attr "length" "2")])
4560 (define_insn "divdi3"
4561   [(set (match_operand:DI 0 "register_operand" "=r")
4562         (div:DI (match_operand:DI 1 "register_operand" "r")
4563                 (match_operand:DI 2 "arith_operand" "rI")))]
4564   "TARGET_ARCH64"
4565   "sdivx\t%1, %2, %0"
4566   [(set_attr "type" "idiv")])
4568 (define_insn "*cmp_sdiv_cc_set"
4569   [(set (reg:CC CC_REG)
4570         (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
4571                             (match_operand:SI 2 "arith_operand" "rI"))
4572                     (const_int 0)))
4573    (set (match_operand:SI 0 "register_operand" "=r")
4574         (div:SI (match_dup 1) (match_dup 2)))
4575    (clobber (match_scratch:SI 3 "=&r"))]
4576   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4578   output_asm_insn ("sra\t%1, 31, %3", operands);
4579   output_asm_insn ("wr\t%3, 0, %%y", operands);
4581   if (TARGET_V9)
4582     return "sdivcc\t%1, %2, %0";
4583   else
4584     return "nop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
4586   [(set_attr "type" "multi")
4587    (set (attr "length")
4588         (if_then_else (eq_attr "isa" "v9")
4589                       (const_int 3) (const_int 6)))])
4591 ;; XXX
4592 (define_expand "udivsi3"
4593   [(set (match_operand:SI 0 "register_operand" "")
4594         (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "")
4595                  (match_operand:SI 2 "input_operand" "")))]
4596   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4597   "")
4599 ;; The V8 architecture specifies that there must be at least 3 instructions
4600 ;; between a write to the Y register and a use of it for correct results.
4601 ;; We try to fill one of them with a simple constant or a memory load.
4603 (define_insn "udivsi3_sp32"
4604   [(set (match_operand:SI 0 "register_operand" "=r,&r,&r,&r")
4605         (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r,r,r,m")
4606                  (match_operand:SI 2 "input_operand" "rI,K,m,r")))]
4607   "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4609   output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4611   switch (which_alternative)
4612     {
4613     case 0:
4614       if (TARGET_V9)
4615         return "udiv\t%1, %2, %0";
4616       else
4617         return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
4618     case 1:
4619       if (TARGET_V9)
4620         return "sethi\t%%hi(%a2), %0\n\tudiv\t%1, %0, %0";
4621       else
4622         return "sethi\t%%hi(%a2), %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4623     case 2:
4624       if (TARGET_V9)
4625         return "ld\t%2, %0\n\tudiv\t%1, %0, %0";
4626       else
4627         return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4628     case 3:
4629       if (TARGET_V9)
4630         return "ld\t%1, %0\n\tudiv\t%0, %2, %0";
4631       else
4632         return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
4633     default:
4634       gcc_unreachable ();
4635     }
4637   [(set_attr "type" "multi")
4638    (set (attr "length")
4639         (if_then_else (eq_attr "isa" "v9")
4640                       (const_int 3) (const_int 5)))])
4642 (define_insn "udivsi3_sp64"
4643   [(set (match_operand:SI 0 "register_operand" "=r")
4644         (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r")
4645                  (match_operand:SI 2 "input_operand" "rI")))]
4646   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4647   "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
4648   [(set_attr "type" "multi")
4649    (set_attr "length" "2")])
4651 (define_insn "udivdi3"
4652   [(set (match_operand:DI 0 "register_operand" "=r")
4653         (udiv:DI (match_operand:DI 1 "register_operand" "r")
4654                  (match_operand:DI 2 "arith_operand" "rI")))]
4655   "TARGET_ARCH64"
4656   "udivx\t%1, %2, %0"
4657   [(set_attr "type" "idiv")])
4659 (define_insn "*cmp_udiv_cc_set"
4660   [(set (reg:CC CC_REG)
4661         (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
4662                              (match_operand:SI 2 "arith_operand" "rI"))
4663                     (const_int 0)))
4664    (set (match_operand:SI 0 "register_operand" "=r")
4665         (udiv:SI (match_dup 1) (match_dup 2)))]
4666   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4668   output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4670   if (TARGET_V9)
4671     return "udivcc\t%1, %2, %0";
4672   else
4673     return "nop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
4675   [(set_attr "type" "multi")
4676    (set (attr "length")
4677         (if_then_else (eq_attr "isa" "v9")
4678                       (const_int 2) (const_int 5)))])
4680 ; sparclet multiply/accumulate insns
4682 (define_insn "*smacsi"
4683   [(set (match_operand:SI 0 "register_operand" "=r")
4684         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
4685                           (match_operand:SI 2 "arith_operand" "rI"))
4686                  (match_operand:SI 3 "register_operand" "0")))]
4687   "TARGET_SPARCLET"
4688   "smac\t%1, %2, %0"
4689   [(set_attr "type" "imul")])
4691 (define_insn "*smacdi"
4692   [(set (match_operand:DI 0 "register_operand" "=r")
4693         (plus:DI (mult:DI (sign_extend:DI
4694                            (match_operand:SI 1 "register_operand" "%r"))
4695                           (sign_extend:DI
4696                            (match_operand:SI 2 "register_operand" "r")))
4697                  (match_operand:DI 3 "register_operand" "0")))]
4698   "TARGET_SPARCLET"
4699   "smacd\t%1, %2, %L0"
4700   [(set_attr "type" "imul")])
4702 (define_insn "*umacdi"
4703   [(set (match_operand:DI 0 "register_operand" "=r")
4704         (plus:DI (mult:DI (zero_extend:DI
4705                            (match_operand:SI 1 "register_operand" "%r"))
4706                           (zero_extend:DI
4707                            (match_operand:SI 2 "register_operand" "r")))
4708                  (match_operand:DI 3 "register_operand" "0")))]
4709   "TARGET_SPARCLET"
4710   "umacd\t%1, %2, %L0"
4711   [(set_attr "type" "imul")])
4714 ;; Boolean instructions.
4716 ;; We define DImode `and' so with DImode `not' we can get
4717 ;; DImode `andn'.  Other combinations are possible.
4719 (define_expand "anddi3"
4720   [(set (match_operand:DI 0 "register_operand" "")
4721         (and:DI (match_operand:DI 1 "arith_double_operand" "")
4722                 (match_operand:DI 2 "arith_double_operand" "")))]
4723   ""
4724   "")
4726 (define_insn "*anddi3_sp32"
4727   [(set (match_operand:DI 0 "register_operand" "=r")
4728         (and:DI (match_operand:DI 1 "arith_double_operand" "%r")
4729                 (match_operand:DI 2 "arith_double_operand" "rHI")))]
4730   "! TARGET_ARCH64"
4731   "#")
4733 (define_insn "*anddi3_sp64"
4734   [(set (match_operand:DI 0 "register_operand" "=r")
4735         (and:DI (match_operand:DI 1 "arith_operand" "%r")
4736                 (match_operand:DI 2 "arith_operand" "rI")))]
4737   "TARGET_ARCH64"
4738   "and\t%1, %2, %0")
4740 (define_insn "andsi3"
4741   [(set (match_operand:SI 0 "register_operand" "=r")
4742         (and:SI (match_operand:SI 1 "arith_operand" "%r")
4743                 (match_operand:SI 2 "arith_operand" "rI")))]
4744   ""
4745   "and\t%1, %2, %0")
4747 (define_split
4748   [(set (match_operand:SI 0 "register_operand" "")
4749         (and:SI (match_operand:SI 1 "register_operand" "")
4750                 (match_operand:SI 2 "const_compl_high_operand" "")))
4751    (clobber (match_operand:SI 3 "register_operand" ""))]
4752   ""
4753   [(set (match_dup 3) (match_dup 4))
4754    (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
4756   operands[4] = GEN_INT (~INTVAL (operands[2]));
4759 (define_insn_and_split "*and_not_di_sp32"
4760   [(set (match_operand:DI 0 "register_operand" "=r")
4761         (and:DI (not:DI (match_operand:DI 1 "register_operand" "%r"))
4762                 (match_operand:DI 2 "register_operand" "r")))]
4763   "! TARGET_ARCH64"
4764   "#"
4765   "&& reload_completed
4766    && ((GET_CODE (operands[0]) == REG
4767         && SPARC_INT_REG_P (REGNO (operands[0])))
4768        || (GET_CODE (operands[0]) == SUBREG
4769            && GET_CODE (SUBREG_REG (operands[0])) == REG
4770            && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
4771   [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
4772    (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
4773   "operands[3] = gen_highpart (SImode, operands[0]);
4774    operands[4] = gen_highpart (SImode, operands[1]);
4775    operands[5] = gen_highpart (SImode, operands[2]);
4776    operands[6] = gen_lowpart (SImode, operands[0]);
4777    operands[7] = gen_lowpart (SImode, operands[1]);
4778    operands[8] = gen_lowpart (SImode, operands[2]);"
4779   [(set_attr "length" "2")])
4781 (define_insn "*and_not_di_sp64"
4782   [(set (match_operand:DI 0 "register_operand" "=r")
4783         (and:DI (not:DI (match_operand:DI 1 "register_operand" "%r"))
4784                 (match_operand:DI 2 "register_operand" "r")))]
4785   "TARGET_ARCH64"
4786   "andn\t%2, %1, %0")
4788 (define_insn "*and_not_si"
4789   [(set (match_operand:SI 0 "register_operand" "=r")
4790         (and:SI (not:SI (match_operand:SI 1 "register_operand" "%r"))
4791                 (match_operand:SI 2 "register_operand" "r")))]
4792   ""
4793   "andn\t%2, %1, %0")
4795 (define_expand "iordi3"
4796   [(set (match_operand:DI 0 "register_operand" "")
4797         (ior:DI (match_operand:DI 1 "arith_double_operand" "")
4798                 (match_operand:DI 2 "arith_double_operand" "")))]
4799   ""
4800   "")
4802 (define_insn "*iordi3_sp32"
4803   [(set (match_operand:DI 0 "register_operand" "=r")
4804         (ior:DI (match_operand:DI 1 "arith_double_operand" "%r")
4805                 (match_operand:DI 2 "arith_double_operand" "rHI")))]
4806   "! TARGET_ARCH64"
4807   "#"
4808   [(set_attr "length" "2")])
4810 (define_insn "*iordi3_sp64"
4811   [(set (match_operand:DI 0 "register_operand" "=r")
4812         (ior:DI (match_operand:DI 1 "arith_operand" "%r")
4813                 (match_operand:DI 2 "arith_operand" "rI")))]
4814   "TARGET_ARCH64"
4815   "or\t%1, %2, %0")
4817 (define_insn "iorsi3"
4818   [(set (match_operand:SI 0 "register_operand" "=r")
4819         (ior:SI (match_operand:SI 1 "arith_operand" "%r")
4820                 (match_operand:SI 2 "arith_operand" "rI")))]
4821   ""
4822   "or\t%1, %2, %0")
4824 (define_split
4825   [(set (match_operand:SI 0 "register_operand" "")
4826         (ior:SI (match_operand:SI 1 "register_operand" "")
4827                 (match_operand:SI 2 "const_compl_high_operand" "")))
4828    (clobber (match_operand:SI 3 "register_operand" ""))]
4829   ""
4830   [(set (match_dup 3) (match_dup 4))
4831    (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
4833   operands[4] = gen_int_mode (~INTVAL (operands[2]), SImode);
4836 (define_insn_and_split "*or_not_di_sp32"
4837   [(set (match_operand:DI 0 "register_operand" "=r")
4838         (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
4839                 (match_operand:DI 2 "register_operand" "r")))]
4840   "! TARGET_ARCH64"
4841   "#"
4842   "&& reload_completed
4843    && ((GET_CODE (operands[0]) == REG
4844         && SPARC_INT_REG_P (REGNO (operands[0])))
4845        || (GET_CODE (operands[0]) == SUBREG
4846            && GET_CODE (SUBREG_REG (operands[0])) == REG
4847            && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
4848   [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
4849    (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
4850   "operands[3] = gen_highpart (SImode, operands[0]);
4851    operands[4] = gen_highpart (SImode, operands[1]);
4852    operands[5] = gen_highpart (SImode, operands[2]);
4853    operands[6] = gen_lowpart (SImode, operands[0]);
4854    operands[7] = gen_lowpart (SImode, operands[1]);
4855    operands[8] = gen_lowpart (SImode, operands[2]);"
4856   [(set_attr "length" "2")])
4858 (define_insn "*or_not_di_sp64"
4859   [(set (match_operand:DI 0 "register_operand" "=r")
4860         (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
4861                 (match_operand:DI 2 "register_operand" "r")))]
4862   "TARGET_ARCH64"
4863   "orn\t%2, %1, %0")
4865 (define_insn "*or_not_si"
4866   [(set (match_operand:SI 0 "register_operand" "=r")
4867         (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
4868                 (match_operand:SI 2 "register_operand" "r")))]
4869   ""
4870   "orn\t%2, %1, %0")
4872 (define_expand "xordi3"
4873   [(set (match_operand:DI 0 "register_operand" "")
4874         (xor:DI (match_operand:DI 1 "arith_double_operand" "")
4875                 (match_operand:DI 2 "arith_double_operand" "")))]
4876   ""
4877   "")
4879 (define_insn "*xordi3_sp32"
4880   [(set (match_operand:DI 0 "register_operand" "=r")
4881         (xor:DI (match_operand:DI 1 "arith_double_operand" "%r")
4882                 (match_operand:DI 2 "arith_double_operand" "rHI")))]
4883   "! TARGET_ARCH64"
4884   "#"
4885   [(set_attr "length" "2")])
4887 (define_insn "*xordi3_sp64"
4888   [(set (match_operand:DI 0 "register_operand" "=r")
4889         (xor:DI (match_operand:DI 1 "arith_operand" "%rJ")
4890                 (match_operand:DI 2 "arith_operand" "rI")))]
4891   "TARGET_ARCH64"
4892   "xor\t%r1, %2, %0")
4894 (define_insn "xorsi3"
4895   [(set (match_operand:SI 0 "register_operand" "=r")
4896         (xor:SI (match_operand:SI 1 "arith_operand" "%rJ")
4897                   (match_operand:SI 2 "arith_operand" "rI")))]
4898   ""
4899   "xor\t%r1, %2, %0")
4901 (define_split
4902   [(set (match_operand:SI 0 "register_operand" "")
4903         (xor:SI (match_operand:SI 1 "register_operand" "")
4904                 (match_operand:SI 2 "const_compl_high_operand" "")))
4905    (clobber (match_operand:SI 3 "register_operand" ""))]
4906    ""
4907   [(set (match_dup 3) (match_dup 4))
4908    (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
4910   operands[4] = gen_int_mode (~INTVAL (operands[2]), SImode);
4913 (define_split
4914   [(set (match_operand:SI 0 "register_operand" "")
4915         (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
4916                         (match_operand:SI 2 "const_compl_high_operand" ""))))
4917    (clobber (match_operand:SI 3 "register_operand" ""))]
4918   ""
4919   [(set (match_dup 3) (match_dup 4))
4920    (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
4922   operands[4] = gen_int_mode (~INTVAL (operands[2]), SImode);
4925 ;; Split DImode logical operations requiring two instructions.
4926 (define_split
4927   [(set (match_operand:DI 0 "register_operand" "")
4928         (match_operator:DI 1 "cc_arith_operator"        ; AND, IOR, XOR
4929                            [(match_operand:DI 2 "register_operand" "")
4930                             (match_operand:DI 3 "arith_double_operand" "")]))]
4931   "! TARGET_ARCH64
4932    && reload_completed
4933    && ((GET_CODE (operands[0]) == REG
4934         && SPARC_INT_REG_P (REGNO (operands[0])))
4935        || (GET_CODE (operands[0]) == SUBREG
4936            && GET_CODE (SUBREG_REG (operands[0])) == REG
4937            && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
4938   [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
4939    (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
4941   operands[4] = gen_highpart (SImode, operands[0]);
4942   operands[5] = gen_lowpart (SImode, operands[0]);
4943   operands[6] = gen_highpart (SImode, operands[2]);
4944   operands[7] = gen_lowpart (SImode, operands[2]);
4945 #if HOST_BITS_PER_WIDE_INT == 32
4946   if (GET_CODE (operands[3]) == CONST_INT)
4947     {
4948       if (INTVAL (operands[3]) < 0)
4949         operands[8] = constm1_rtx;
4950       else
4951         operands[8] = const0_rtx;
4952     }
4953   else
4954 #endif
4955     operands[8] = gen_highpart_mode (SImode, DImode, operands[3]);
4956   operands[9] = gen_lowpart (SImode, operands[3]);
4959 ;; xnor patterns.  Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
4960 ;; Combine now canonicalizes to the rightmost expression.
4961 (define_insn_and_split "*xor_not_di_sp32"
4962   [(set (match_operand:DI 0 "register_operand" "=r")
4963         (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r")
4964                         (match_operand:DI 2 "register_operand" "r"))))]
4965   "! TARGET_ARCH64"
4966   "#"
4967   "&& reload_completed
4968    && ((GET_CODE (operands[0]) == REG
4969         && SPARC_INT_REG_P (REGNO (operands[0])))
4970        || (GET_CODE (operands[0]) == SUBREG
4971            && GET_CODE (SUBREG_REG (operands[0])) == REG
4972            && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
4973   [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
4974    (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
4975   "operands[3] = gen_highpart (SImode, operands[0]);
4976    operands[4] = gen_highpart (SImode, operands[1]);
4977    operands[5] = gen_highpart (SImode, operands[2]);
4978    operands[6] = gen_lowpart (SImode, operands[0]);
4979    operands[7] = gen_lowpart (SImode, operands[1]);
4980    operands[8] = gen_lowpart (SImode, operands[2]);"
4981   [(set_attr "length" "2")])
4983 (define_insn "*xor_not_di_sp64"
4984   [(set (match_operand:DI 0 "register_operand" "=r")
4985         (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
4986                         (match_operand:DI 2 "arith_operand" "rI"))))]
4987   "TARGET_ARCH64"
4988   "xnor\t%r1, %2, %0")
4990 (define_insn "*xor_not_si"
4991   [(set (match_operand:SI 0 "register_operand" "=r")
4992         (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4993                         (match_operand:SI 2 "arith_operand" "rI"))))]
4994   ""
4995   "xnor\t%r1, %2, %0")
4997 ;; These correspond to the above in the case where we also (or only)
4998 ;; want to set the condition code.  
5000 (define_insn "*cmp_cc_arith_op"
5001   [(set (reg:CC CC_REG)
5002         (compare:CC
5003          (match_operator:SI 2 "cc_arith_operator"
5004                             [(match_operand:SI 0 "arith_operand" "%r")
5005                              (match_operand:SI 1 "arith_operand" "rI")])
5006          (const_int 0)))]
5007   ""
5008   "%A2cc\t%0, %1, %%g0"
5009   [(set_attr "type" "compare")])
5011 (define_insn "*cmp_ccx_arith_op"
5012   [(set (reg:CCX CC_REG)
5013         (compare:CCX
5014          (match_operator:DI 2 "cc_arith_operator"
5015                             [(match_operand:DI 0 "arith_operand" "%r")
5016                              (match_operand:DI 1 "arith_operand" "rI")])
5017          (const_int 0)))]
5018   "TARGET_ARCH64"
5019   "%A2cc\t%0, %1, %%g0"
5020   [(set_attr "type" "compare")])
5022 (define_insn "*cmp_cc_arith_op_set"
5023   [(set (reg:CC CC_REG)
5024         (compare:CC
5025          (match_operator:SI 3 "cc_arith_operator"
5026                             [(match_operand:SI 1 "arith_operand" "%r")
5027                              (match_operand:SI 2 "arith_operand" "rI")])
5028          (const_int 0)))
5029    (set (match_operand:SI 0 "register_operand" "=r")
5030         (match_operator:SI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5031   "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5032   "%A3cc\t%1, %2, %0"
5033   [(set_attr "type" "compare")])
5035 (define_insn "*cmp_ccx_arith_op_set"
5036   [(set (reg:CCX CC_REG)
5037         (compare:CCX
5038          (match_operator:DI 3 "cc_arith_operator"
5039                             [(match_operand:DI 1 "arith_operand" "%r")
5040                              (match_operand:DI 2 "arith_operand" "rI")])
5041          (const_int 0)))
5042    (set (match_operand:DI 0 "register_operand" "=r")
5043         (match_operator:DI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5044   "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5045   "%A3cc\t%1, %2, %0"
5046   [(set_attr "type" "compare")])
5048 (define_insn "*cmp_cc_xor_not"
5049   [(set (reg:CC CC_REG)
5050         (compare:CC
5051          (not:SI (xor:SI (match_operand:SI 0 "register_or_zero_operand" "%rJ")
5052                          (match_operand:SI 1 "arith_operand" "rI")))
5053          (const_int 0)))]
5054   ""
5055   "xnorcc\t%r0, %1, %%g0"
5056   [(set_attr "type" "compare")])
5058 (define_insn "*cmp_ccx_xor_not"
5059   [(set (reg:CCX CC_REG)
5060         (compare:CCX
5061          (not:DI (xor:DI (match_operand:DI 0 "register_or_zero_operand" "%rJ")
5062                          (match_operand:DI 1 "arith_operand" "rI")))
5063          (const_int 0)))]
5064   "TARGET_ARCH64"
5065   "xnorcc\t%r0, %1, %%g0"
5066   [(set_attr "type" "compare")])
5068 (define_insn "*cmp_cc_xor_not_set"
5069   [(set (reg:CC CC_REG)
5070         (compare:CC
5071          (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
5072                          (match_operand:SI 2 "arith_operand" "rI")))
5073          (const_int 0)))
5074    (set (match_operand:SI 0 "register_operand" "=r")
5075         (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
5076   ""
5077   "xnorcc\t%r1, %2, %0"
5078   [(set_attr "type" "compare")])
5080 (define_insn "*cmp_ccx_xor_not_set"
5081   [(set (reg:CCX CC_REG)
5082         (compare:CCX
5083          (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
5084                          (match_operand:DI 2 "arith_operand" "rI")))
5085          (const_int 0)))
5086    (set (match_operand:DI 0 "register_operand" "=r")
5087         (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
5088   "TARGET_ARCH64"
5089   "xnorcc\t%r1, %2, %0"
5090   [(set_attr "type" "compare")])
5092 (define_insn "*cmp_cc_arith_op_not"
5093   [(set (reg:CC CC_REG)
5094         (compare:CC
5095          (match_operator:SI 2 "cc_arith_not_operator"
5096                             [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
5097                              (match_operand:SI 1 "register_or_zero_operand" "rJ")])
5098          (const_int 0)))]
5099   ""
5100   "%B2cc\t%r1, %0, %%g0"
5101   [(set_attr "type" "compare")])
5103 (define_insn "*cmp_ccx_arith_op_not"
5104   [(set (reg:CCX CC_REG)
5105         (compare:CCX
5106          (match_operator:DI 2 "cc_arith_not_operator"
5107                             [(not:DI (match_operand:DI 0 "arith_operand" "rI"))
5108                              (match_operand:DI 1 "register_or_zero_operand" "rJ")])
5109          (const_int 0)))]
5110   "TARGET_ARCH64"
5111   "%B2cc\t%r1, %0, %%g0"
5112   [(set_attr "type" "compare")])
5114 (define_insn "*cmp_cc_arith_op_not_set"
5115   [(set (reg:CC CC_REG)
5116         (compare:CC
5117          (match_operator:SI 3 "cc_arith_not_operator"
5118                             [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
5119                              (match_operand:SI 2 "register_or_zero_operand" "rJ")])
5120          (const_int 0)))
5121    (set (match_operand:SI 0 "register_operand" "=r")
5122         (match_operator:SI 4 "cc_arith_not_operator"
5123                             [(not:SI (match_dup 1)) (match_dup 2)]))]
5124   "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5125   "%B3cc\t%r2, %1, %0"
5126   [(set_attr "type" "compare")])
5128 (define_insn "*cmp_ccx_arith_op_not_set"
5129   [(set (reg:CCX CC_REG)
5130         (compare:CCX
5131          (match_operator:DI 3 "cc_arith_not_operator"
5132                             [(not:DI (match_operand:DI 1 "arith_operand" "rI"))
5133                              (match_operand:DI 2 "register_or_zero_operand" "rJ")])
5134          (const_int 0)))
5135    (set (match_operand:DI 0 "register_operand" "=r")
5136         (match_operator:DI 4 "cc_arith_not_operator"
5137                             [(not:DI (match_dup 1)) (match_dup 2)]))]
5138   "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5139   "%B3cc\t%r2, %1, %0"
5140   [(set_attr "type" "compare")])
5142 ;; We cannot use the "neg" pseudo insn because the Sun assembler
5143 ;; does not know how to make it work for constants.
5145 (define_expand "negdi2"
5146   [(set (match_operand:DI 0 "register_operand" "=r")
5147         (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5148   ""
5150   if (! TARGET_ARCH64)
5151     {
5152       emit_insn (gen_rtx_PARALLEL
5153                  (VOIDmode,
5154                   gen_rtvec (2,
5155                              gen_rtx_SET (VOIDmode, operand0,
5156                                           gen_rtx_NEG (DImode, operand1)),
5157                              gen_rtx_CLOBBER (VOIDmode,
5158                                               gen_rtx_REG (CCmode,
5159                                                            SPARC_ICC_REG)))));
5160       DONE;
5161     }
5164 (define_insn_and_split "*negdi2_sp32"
5165   [(set (match_operand:DI 0 "register_operand" "=r")
5166         (neg:DI (match_operand:DI 1 "register_operand" "r")))
5167    (clobber (reg:CC CC_REG))]
5168   "! TARGET_ARCH64"
5169   "#"
5170   "&& reload_completed"
5171   [(parallel [(set (reg:CC_NOOV CC_REG)
5172                    (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
5173                                     (const_int 0)))
5174               (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
5175    (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
5176                                 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
5177   "operands[2] = gen_highpart (SImode, operands[0]);
5178    operands[3] = gen_highpart (SImode, operands[1]);
5179    operands[4] = gen_lowpart (SImode, operands[0]);
5180    operands[5] = gen_lowpart (SImode, operands[1]);"
5181   [(set_attr "length" "2")])
5183 (define_insn "*negdi2_sp64"
5184   [(set (match_operand:DI 0 "register_operand" "=r")
5185         (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5186   "TARGET_ARCH64"
5187   "sub\t%%g0, %1, %0")
5189 (define_insn "negsi2"
5190   [(set (match_operand:SI 0 "register_operand" "=r")
5191         (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
5192   ""
5193   "sub\t%%g0, %1, %0")
5195 (define_insn "*cmp_cc_neg"
5196   [(set (reg:CC_NOOV CC_REG)
5197         (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
5198                          (const_int 0)))]
5199   ""
5200   "subcc\t%%g0, %0, %%g0"
5201   [(set_attr "type" "compare")])
5203 (define_insn "*cmp_ccx_neg"
5204   [(set (reg:CCX_NOOV CC_REG)
5205         (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_operand" "rI"))
5206                           (const_int 0)))]
5207   "TARGET_ARCH64"
5208   "subcc\t%%g0, %0, %%g0"
5209   [(set_attr "type" "compare")])
5211 (define_insn "*cmp_cc_set_neg"
5212   [(set (reg:CC_NOOV CC_REG)
5213         (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
5214                          (const_int 0)))
5215    (set (match_operand:SI 0 "register_operand" "=r")
5216         (neg:SI (match_dup 1)))]
5217   ""
5218   "subcc\t%%g0, %1, %0"
5219   [(set_attr "type" "compare")])
5221 (define_insn "*cmp_ccx_set_neg"
5222   [(set (reg:CCX_NOOV CC_REG)
5223         (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_operand" "rI"))
5224                           (const_int 0)))
5225    (set (match_operand:DI 0 "register_operand" "=r")
5226         (neg:DI (match_dup 1)))]
5227   "TARGET_ARCH64"
5228   "subcc\t%%g0, %1, %0"
5229   [(set_attr "type" "compare")])
5231 ;; We cannot use the "not" pseudo insn because the Sun assembler
5232 ;; does not know how to make it work for constants.
5233 (define_expand "one_cmpldi2"
5234   [(set (match_operand:DI 0 "register_operand" "")
5235         (not:DI (match_operand:DI 1 "register_operand" "")))]
5236   ""
5237   "")
5239 (define_insn_and_split "*one_cmpldi2_sp32"
5240   [(set (match_operand:DI 0 "register_operand" "=r")
5241         (not:DI (match_operand:DI 1 "register_operand" "r")))]
5242   "! TARGET_ARCH64"
5243   "#"
5244   "&& reload_completed
5245    && ((GET_CODE (operands[0]) == REG
5246         && SPARC_INT_REG_P (REGNO (operands[0])))
5247        || (GET_CODE (operands[0]) == SUBREG
5248            && GET_CODE (SUBREG_REG (operands[0])) == REG
5249            && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
5250   [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
5251    (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
5252   "operands[2] = gen_highpart (SImode, operands[0]);
5253    operands[3] = gen_highpart (SImode, operands[1]);
5254    operands[4] = gen_lowpart (SImode, operands[0]);
5255    operands[5] = gen_lowpart (SImode, operands[1]);"
5256   [(set_attr "length" "2")])
5258 (define_insn "*one_cmpldi2_sp64"
5259   [(set (match_operand:DI 0 "register_operand" "=r")
5260         (not:DI (match_operand:DI 1 "arith_operand" "rI")))]
5261   "TARGET_ARCH64"
5262   "xnor\t%%g0, %1, %0")
5264 (define_insn "one_cmplsi2"
5265   [(set (match_operand:SI 0 "register_operand" "=r")
5266         (not:SI (match_operand:SI 1 "arith_operand" "rI")))]
5267   ""
5268   "xnor\t%%g0, %1, %0")
5270 (define_insn "*cmp_cc_not"
5271   [(set (reg:CC CC_REG)
5272         (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
5273                     (const_int 0)))]
5274   ""
5275   "xnorcc\t%%g0, %0, %%g0"
5276   [(set_attr "type" "compare")])
5278 (define_insn "*cmp_ccx_not"
5279   [(set (reg:CCX CC_REG)
5280         (compare:CCX (not:DI (match_operand:DI 0 "arith_operand" "rI"))
5281                      (const_int 0)))]
5282   "TARGET_ARCH64"
5283   "xnorcc\t%%g0, %0, %%g0"
5284   [(set_attr "type" "compare")])
5286 (define_insn "*cmp_cc_set_not"
5287   [(set (reg:CC CC_REG)
5288         (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
5289                     (const_int 0)))
5290    (set (match_operand:SI 0 "register_operand" "=r")
5291         (not:SI (match_dup 1)))]
5292   ""
5293   "xnorcc\t%%g0, %1, %0"
5294   [(set_attr "type" "compare")])
5296 (define_insn "*cmp_ccx_set_not"
5297   [(set (reg:CCX CC_REG)
5298         (compare:CCX (not:DI (match_operand:DI 1 "arith_operand" "rI"))
5299                     (const_int 0)))
5300    (set (match_operand:DI 0 "register_operand" "=r")
5301         (not:DI (match_dup 1)))]
5302   "TARGET_ARCH64"
5303   "xnorcc\t%%g0, %1, %0"
5304   [(set_attr "type" "compare")])
5306 (define_insn "*cmp_cc_set"
5307   [(set (match_operand:SI 0 "register_operand" "=r")
5308         (match_operand:SI 1 "register_operand" "r"))
5309    (set (reg:CC CC_REG)
5310         (compare:CC (match_dup 1)
5311                     (const_int 0)))]
5312   ""
5313   "orcc\t%1, 0, %0"
5314   [(set_attr "type" "compare")])
5316 (define_insn "*cmp_ccx_set64"
5317   [(set (match_operand:DI 0 "register_operand" "=r")
5318         (match_operand:DI 1 "register_operand" "r"))
5319    (set (reg:CCX CC_REG)
5320         (compare:CCX (match_dup 1)
5321                      (const_int 0)))]
5322   "TARGET_ARCH64"
5323   "orcc\t%1, 0, %0"
5324    [(set_attr "type" "compare")])
5327 ;; Floating point arithmetic instructions.
5329 (define_expand "addtf3"
5330   [(set (match_operand:TF 0 "nonimmediate_operand" "")
5331         (plus:TF (match_operand:TF 1 "general_operand" "")
5332                  (match_operand:TF 2 "general_operand" "")))]
5333   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5334   "emit_tfmode_binop (PLUS, operands); DONE;")
5336 (define_insn "*addtf3_hq"
5337   [(set (match_operand:TF 0 "register_operand" "=e")
5338         (plus:TF (match_operand:TF 1 "register_operand" "e")
5339                  (match_operand:TF 2 "register_operand" "e")))]
5340   "TARGET_FPU && TARGET_HARD_QUAD"
5341   "faddq\t%1, %2, %0"
5342   [(set_attr "type" "fp")])
5344 (define_insn "adddf3"
5345   [(set (match_operand:DF 0 "register_operand" "=e")
5346         (plus:DF (match_operand:DF 1 "register_operand" "e")
5347                  (match_operand:DF 2 "register_operand" "e")))]
5348   "TARGET_FPU"
5349   "faddd\t%1, %2, %0"
5350   [(set_attr "type" "fp")
5351    (set_attr "fptype" "double")])
5353 (define_insn "addsf3"
5354   [(set (match_operand:SF 0 "register_operand" "=f")
5355         (plus:SF (match_operand:SF 1 "register_operand" "f")
5356                  (match_operand:SF 2 "register_operand" "f")))]
5357   "TARGET_FPU"
5358   "fadds\t%1, %2, %0"
5359   [(set_attr "type" "fp")])
5361 (define_expand "subtf3"
5362   [(set (match_operand:TF 0 "nonimmediate_operand" "")
5363         (minus:TF (match_operand:TF 1 "general_operand" "")
5364                   (match_operand:TF 2 "general_operand" "")))]
5365   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5366   "emit_tfmode_binop (MINUS, operands); DONE;")
5368 (define_insn "*subtf3_hq"
5369   [(set (match_operand:TF 0 "register_operand" "=e")
5370         (minus:TF (match_operand:TF 1 "register_operand" "e")
5371                   (match_operand:TF 2 "register_operand" "e")))]
5372   "TARGET_FPU && TARGET_HARD_QUAD"
5373   "fsubq\t%1, %2, %0"
5374   [(set_attr "type" "fp")])
5376 (define_insn "subdf3"
5377   [(set (match_operand:DF 0 "register_operand" "=e")
5378         (minus:DF (match_operand:DF 1 "register_operand" "e")
5379                   (match_operand:DF 2 "register_operand" "e")))]
5380   "TARGET_FPU"
5381   "fsubd\t%1, %2, %0"
5382   [(set_attr "type" "fp")
5383    (set_attr "fptype" "double")])
5385 (define_insn "subsf3"
5386   [(set (match_operand:SF 0 "register_operand" "=f")
5387         (minus:SF (match_operand:SF 1 "register_operand" "f")
5388                   (match_operand:SF 2 "register_operand" "f")))]
5389   "TARGET_FPU"
5390   "fsubs\t%1, %2, %0"
5391   [(set_attr "type" "fp")])
5393 (define_expand "multf3"
5394   [(set (match_operand:TF 0 "nonimmediate_operand" "")
5395         (mult:TF (match_operand:TF 1 "general_operand" "")
5396                  (match_operand:TF 2 "general_operand" "")))]
5397   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5398   "emit_tfmode_binop (MULT, operands); DONE;")
5400 (define_insn "*multf3_hq"
5401   [(set (match_operand:TF 0 "register_operand" "=e")
5402         (mult:TF (match_operand:TF 1 "register_operand" "e")
5403                  (match_operand:TF 2 "register_operand" "e")))]
5404   "TARGET_FPU && TARGET_HARD_QUAD"
5405   "fmulq\t%1, %2, %0"
5406   [(set_attr "type" "fpmul")])
5408 (define_insn "muldf3"
5409   [(set (match_operand:DF 0 "register_operand" "=e")
5410         (mult:DF (match_operand:DF 1 "register_operand" "e")
5411                  (match_operand:DF 2 "register_operand" "e")))]
5412   "TARGET_FPU"
5413   "fmuld\t%1, %2, %0"
5414   [(set_attr "type" "fpmul")
5415    (set_attr "fptype" "double")])
5417 (define_insn "mulsf3"
5418   [(set (match_operand:SF 0 "register_operand" "=f")
5419         (mult:SF (match_operand:SF 1 "register_operand" "f")
5420                  (match_operand:SF 2 "register_operand" "f")))]
5421   "TARGET_FPU"
5422   "fmuls\t%1, %2, %0"
5423   [(set_attr "type" "fpmul")])
5425 (define_insn "fmadf4"
5426   [(set (match_operand:DF 0 "register_operand" "=e")
5427         (fma:DF (match_operand:DF 1 "register_operand" "e")
5428                 (match_operand:DF 2 "register_operand" "e")
5429                 (match_operand:DF 3 "register_operand" "e")))]
5430   "TARGET_FMAF"
5431   "fmaddd\t%1, %2, %3, %0"
5432   [(set_attr "type" "fpmul")])
5434 (define_insn "fmsdf4"
5435   [(set (match_operand:DF 0 "register_operand" "=e")
5436         (fma:DF (match_operand:DF 1 "register_operand" "e")
5437                 (match_operand:DF 2 "register_operand" "e")
5438                 (neg:DF (match_operand:DF 3 "register_operand" "e"))))]
5439   "TARGET_FMAF"
5440   "fmsubd\t%1, %2, %3, %0"
5441   [(set_attr "type" "fpmul")])
5443 (define_insn "*nfmadf4"
5444   [(set (match_operand:DF 0 "register_operand" "=e")
5445         (neg:DF (fma:DF (match_operand:DF 1 "register_operand" "e")
5446                         (match_operand:DF 2 "register_operand" "e")
5447                         (match_operand:DF 3 "register_operand" "e"))))]
5448   "TARGET_FMAF"
5449   "fnmaddd\t%1, %2, %3, %0"
5450   [(set_attr "type" "fpmul")])
5452 (define_insn "*nfmsdf4"
5453   [(set (match_operand:DF 0 "register_operand" "=e")
5454         (neg:DF (fma:DF (match_operand:DF 1 "register_operand" "e")
5455                         (match_operand:DF 2 "register_operand" "e")
5456                         (neg:DF (match_operand:DF 3 "register_operand" "e")))))]
5457   "TARGET_FMAF"
5458   "fnmsubd\t%1, %2, %3, %0"
5459   [(set_attr "type" "fpmul")])
5461 (define_insn "fmasf4"
5462   [(set (match_operand:SF 0 "register_operand" "=f")
5463         (fma:SF (match_operand:SF 1 "register_operand" "f")
5464                 (match_operand:SF 2 "register_operand" "f")
5465                 (match_operand:SF 3 "register_operand" "f")))]
5466   "TARGET_FMAF"
5467   "fmadds\t%1, %2, %3, %0"
5468   [(set_attr "type" "fpmul")])
5470 (define_insn "fmssf4"
5471   [(set (match_operand:SF 0 "register_operand" "=f")
5472         (fma:SF (match_operand:SF 1 "register_operand" "f")
5473                 (match_operand:SF 2 "register_operand" "f")
5474                 (neg:SF (match_operand:SF 3 "register_operand" "f"))))]
5475   "TARGET_FMAF"
5476   "fmsubs\t%1, %2, %3, %0"
5477   [(set_attr "type" "fpmul")])
5479 (define_insn "*nfmasf4"
5480   [(set (match_operand:SF 0 "register_operand" "=f")
5481         (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "f")
5482                         (match_operand:SF 2 "register_operand" "f")
5483                         (match_operand:SF 3 "register_operand" "f"))))]
5484   "TARGET_FMAF"
5485   "fnmadds\t%1, %2, %3, %0"
5486   [(set_attr "type" "fpmul")])
5488 (define_insn "*nfmssf4"
5489   [(set (match_operand:SF 0 "register_operand" "=f")
5490         (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "f")
5491                         (match_operand:SF 2 "register_operand" "f")
5492                         (neg:SF (match_operand:SF 3 "register_operand" "f")))))]
5493   "TARGET_FMAF"
5494   "fnmsubs\t%1, %2, %3, %0"
5495   [(set_attr "type" "fpmul")])
5497 (define_insn "*muldf3_extend"
5498   [(set (match_operand:DF 0 "register_operand" "=e")
5499         (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
5500                  (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
5501   "(TARGET_V8 || TARGET_V9) && TARGET_FPU && !sparc_fix_ut699"
5502   "fsmuld\t%1, %2, %0"
5503   [(set_attr "type" "fpmul")
5504    (set_attr "fptype" "double")])
5506 (define_insn "*multf3_extend"
5507   [(set (match_operand:TF 0 "register_operand" "=e")
5508         (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
5509                  (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
5510   "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
5511   "fdmulq\t%1, %2, %0"
5512   [(set_attr "type" "fpmul")])
5514 (define_expand "divtf3"
5515   [(set (match_operand:TF 0 "nonimmediate_operand" "")
5516         (div:TF (match_operand:TF 1 "general_operand" "")
5517                 (match_operand:TF 2 "general_operand" "")))]
5518   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5519   "emit_tfmode_binop (DIV, operands); DONE;")
5521 ;; don't have timing for quad-prec. divide.
5522 (define_insn "*divtf3_hq"
5523   [(set (match_operand:TF 0 "register_operand" "=e")
5524         (div:TF (match_operand:TF 1 "register_operand" "e")
5525                 (match_operand:TF 2 "register_operand" "e")))]
5526   "TARGET_FPU && TARGET_HARD_QUAD"
5527   "fdivq\t%1, %2, %0"
5528   [(set_attr "type" "fpdivs")])
5530 (define_expand "divdf3"
5531   [(set (match_operand:DF 0 "register_operand" "=e")
5532         (div:DF (match_operand:DF 1 "register_operand" "e")
5533                 (match_operand:DF 2 "register_operand" "e")))]
5534   "TARGET_FPU"
5535   "")
5537 (define_insn "*divdf3_nofix"
5538   [(set (match_operand:DF 0 "register_operand" "=e")
5539         (div:DF (match_operand:DF 1 "register_operand" "e")
5540                 (match_operand:DF 2 "register_operand" "e")))]
5541   "TARGET_FPU && !sparc_fix_ut699"
5542   "fdivd\t%1, %2, %0"
5543   [(set_attr "type" "fpdivd")
5544    (set_attr "fptype" "double")])
5546 (define_insn "*divdf3_fix"
5547   [(set (match_operand:DF 0 "register_operand" "=e")
5548         (div:DF (match_operand:DF 1 "register_operand" "e")
5549                 (match_operand:DF 2 "register_operand" "e")))]
5550   "TARGET_FPU && sparc_fix_ut699"
5551   "fdivd\t%1, %2, %0\n\tstd\t%0, [%%sp-8]"
5552   [(set_attr "type" "fpdivd")
5553    (set_attr "fptype" "double")
5554    (set_attr "length" "2")])
5556 (define_insn "divsf3"
5557   [(set (match_operand:SF 0 "register_operand" "=f")
5558         (div:SF (match_operand:SF 1 "register_operand" "f")
5559                 (match_operand:SF 2 "register_operand" "f")))]
5560   "TARGET_FPU && !sparc_fix_ut699"
5561   "fdivs\t%1, %2, %0"
5562   [(set_attr "type" "fpdivs")])
5564 (define_expand "negtf2"
5565   [(set (match_operand:TF 0 "register_operand" "")
5566         (neg:TF (match_operand:TF 1 "register_operand" "")))]
5567   "TARGET_FPU"
5568   "")
5570 (define_insn "*negtf2_hq"
5571   [(set (match_operand:TF 0 "register_operand" "=e")
5572         (neg:TF (match_operand:TF 1 "register_operand" "e")))]
5573   "TARGET_FPU && TARGET_HARD_QUAD"
5574   "fnegq\t%1, %0"
5575   [(set_attr "type" "fpmove")])
5577 (define_insn_and_split "*negtf2"
5578   [(set (match_operand:TF 0 "register_operand" "=e")
5579         (neg:TF (match_operand:TF 1 "register_operand" "e")))]
5580   "TARGET_FPU && !TARGET_HARD_QUAD"
5581   "#"
5582   "&& reload_completed"
5583   [(clobber (const_int 0))]
5585   rtx set_dest = operands[0];
5586   rtx set_src = operands[1];
5587   rtx dest1, dest2;
5588   rtx src1, src2;
5590   dest1 = gen_df_reg (set_dest, 0);
5591   dest2 = gen_df_reg (set_dest, 1);
5592   src1 = gen_df_reg (set_src, 0);
5593   src2 = gen_df_reg (set_src, 1);
5595   /* Now emit using the real source and destination we found, swapping
5596      the order if we detect overlap.  */
5597   if (reg_overlap_mentioned_p (dest1, src2))
5598     {
5599       emit_insn (gen_movdf (dest2, src2));
5600       emit_insn (gen_negdf2 (dest1, src1));
5601     }
5602   else
5603     {
5604       emit_insn (gen_negdf2 (dest1, src1));
5605       if (REGNO (dest2) != REGNO (src2))
5606         emit_insn (gen_movdf (dest2, src2));
5607     }
5608   DONE;
5610   [(set_attr "length" "2")])
5612 (define_expand "negdf2"
5613   [(set (match_operand:DF 0 "register_operand" "")
5614         (neg:DF (match_operand:DF 1 "register_operand" "")))]
5615   "TARGET_FPU"
5616   "")
5618 (define_insn_and_split "*negdf2_notv9"
5619   [(set (match_operand:DF 0 "register_operand" "=e")
5620         (neg:DF (match_operand:DF 1 "register_operand" "e")))]
5621   "TARGET_FPU && !TARGET_V9"
5622   "#"
5623   "&& reload_completed"
5624   [(clobber (const_int 0))]
5626   rtx set_dest = operands[0];
5627   rtx set_src = operands[1];
5628   rtx dest1, dest2;
5629   rtx src1, src2;
5631   dest1 = gen_highpart (SFmode, set_dest);
5632   dest2 = gen_lowpart (SFmode, set_dest);
5633   src1 = gen_highpart (SFmode, set_src);
5634   src2 = gen_lowpart (SFmode, set_src);
5636   /* Now emit using the real source and destination we found, swapping
5637      the order if we detect overlap.  */
5638   if (reg_overlap_mentioned_p (dest1, src2))
5639     {
5640       emit_insn (gen_movsf (dest2, src2));
5641       emit_insn (gen_negsf2 (dest1, src1));
5642     }
5643   else
5644     {
5645       emit_insn (gen_negsf2 (dest1, src1));
5646       if (REGNO (dest2) != REGNO (src2))
5647         emit_insn (gen_movsf (dest2, src2));
5648     }
5649   DONE;
5651   [(set_attr "length" "2")])
5653 (define_insn "*negdf2_v9"
5654   [(set (match_operand:DF 0 "register_operand" "=e")
5655         (neg:DF (match_operand:DF 1 "register_operand" "e")))]
5656   "TARGET_FPU && TARGET_V9"
5657   "fnegd\t%1, %0"
5658   [(set_attr "type" "fpmove")
5659    (set_attr "fptype" "double")])
5661 (define_insn "negsf2"
5662   [(set (match_operand:SF 0 "register_operand" "=f")
5663         (neg:SF (match_operand:SF 1 "register_operand" "f")))]
5664   "TARGET_FPU"
5665   "fnegs\t%1, %0"
5666   [(set_attr "type" "fpmove")])
5668 (define_expand "abstf2"
5669   [(set (match_operand:TF 0 "register_operand" "")
5670         (abs:TF (match_operand:TF 1 "register_operand" "")))]
5671   "TARGET_FPU"
5672   "")
5674 (define_insn "*abstf2_hq"
5675   [(set (match_operand:TF 0 "register_operand" "=e")
5676         (abs:TF (match_operand:TF 1 "register_operand" "e")))]
5677   "TARGET_FPU && TARGET_HARD_QUAD"
5678   "fabsq\t%1, %0"
5679   [(set_attr "type" "fpmove")])
5681 (define_insn_and_split "*abstf2"
5682   [(set (match_operand:TF 0 "register_operand" "=e")
5683         (abs:TF (match_operand:TF 1 "register_operand" "e")))]
5684   "TARGET_FPU && !TARGET_HARD_QUAD"
5685   "#"
5686   "&& reload_completed"
5687   [(clobber (const_int 0))]
5689   rtx set_dest = operands[0];
5690   rtx set_src = operands[1];
5691   rtx dest1, dest2;
5692   rtx src1, src2;
5694   dest1 = gen_df_reg (set_dest, 0);
5695   dest2 = gen_df_reg (set_dest, 1);
5696   src1 = gen_df_reg (set_src, 0);
5697   src2 = gen_df_reg (set_src, 1);
5699   /* Now emit using the real source and destination we found, swapping
5700      the order if we detect overlap.  */
5701   if (reg_overlap_mentioned_p (dest1, src2))
5702     {
5703       emit_insn (gen_movdf (dest2, src2));
5704       emit_insn (gen_absdf2 (dest1, src1));
5705     }
5706   else
5707     {
5708       emit_insn (gen_absdf2 (dest1, src1));
5709       if (REGNO (dest2) != REGNO (src2))
5710         emit_insn (gen_movdf (dest2, src2));
5711     }
5712   DONE;
5714   [(set_attr "length" "2")])
5716 (define_expand "absdf2"
5717   [(set (match_operand:DF 0 "register_operand" "")
5718         (abs:DF (match_operand:DF 1 "register_operand" "")))]
5719   "TARGET_FPU"
5720   "")
5722 (define_insn_and_split "*absdf2_notv9"
5723   [(set (match_operand:DF 0 "register_operand" "=e")
5724         (abs:DF (match_operand:DF 1 "register_operand" "e")))]
5725   "TARGET_FPU && !TARGET_V9"
5726   "#"
5727   "&& reload_completed"
5728   [(clobber (const_int 0))]
5730   rtx set_dest = operands[0];
5731   rtx set_src = operands[1];
5732   rtx dest1, dest2;
5733   rtx src1, src2;
5735   dest1 = gen_highpart (SFmode, set_dest);
5736   dest2 = gen_lowpart (SFmode, set_dest);
5737   src1 = gen_highpart (SFmode, set_src);
5738   src2 = gen_lowpart (SFmode, set_src);
5740   /* Now emit using the real source and destination we found, swapping
5741      the order if we detect overlap.  */
5742   if (reg_overlap_mentioned_p (dest1, src2))
5743     {
5744       emit_insn (gen_movsf (dest2, src2));
5745       emit_insn (gen_abssf2 (dest1, src1));
5746     }
5747   else
5748     {
5749       emit_insn (gen_abssf2 (dest1, src1));
5750       if (REGNO (dest2) != REGNO (src2))
5751         emit_insn (gen_movsf (dest2, src2));
5752     }
5753   DONE;
5755   [(set_attr "length" "2")])
5757 (define_insn "*absdf2_v9"
5758   [(set (match_operand:DF 0 "register_operand" "=e")
5759         (abs:DF (match_operand:DF 1 "register_operand" "e")))]
5760   "TARGET_FPU && TARGET_V9"
5761   "fabsd\t%1, %0"
5762   [(set_attr "type" "fpmove")
5763    (set_attr "fptype" "double")])
5765 (define_insn "abssf2"
5766   [(set (match_operand:SF 0 "register_operand" "=f")
5767         (abs:SF (match_operand:SF 1 "register_operand" "f")))]
5768   "TARGET_FPU"
5769   "fabss\t%1, %0"
5770   [(set_attr "type" "fpmove")])
5772 (define_expand "sqrttf2"
5773   [(set (match_operand:TF 0 "nonimmediate_operand" "")
5774         (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
5775   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5776   "emit_tfmode_unop (SQRT, operands); DONE;")
5778 (define_insn "*sqrttf2_hq"
5779   [(set (match_operand:TF 0 "register_operand" "=e")
5780         (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
5781   "TARGET_FPU && TARGET_HARD_QUAD"
5782   "fsqrtq\t%1, %0"
5783   [(set_attr "type" "fpsqrts")])
5785 (define_expand "sqrtdf2"
5786   [(set (match_operand:DF 0 "register_operand" "=e")
5787         (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
5788   "TARGET_FPU"
5789   "")
5791 (define_insn "*sqrtdf2_nofix"
5792   [(set (match_operand:DF 0 "register_operand" "=e")
5793         (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
5794   "TARGET_FPU && !sparc_fix_ut699"
5795   "fsqrtd\t%1, %0"
5796   [(set_attr "type" "fpsqrtd")
5797    (set_attr "fptype" "double")])
5799 (define_insn "*sqrtdf2_fix"
5800   [(set (match_operand:DF 0 "register_operand" "=e")
5801         (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
5802   "TARGET_FPU && sparc_fix_ut699"
5803   "fsqrtd\t%1, %0\n\tstd\t%0, [%%sp-8]"
5804   [(set_attr "type" "fpsqrtd")
5805    (set_attr "fptype" "double")
5806    (set_attr "length" "2")])
5808 (define_insn "sqrtsf2"
5809   [(set (match_operand:SF 0 "register_operand" "=f")
5810         (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
5811   "TARGET_FPU && !sparc_fix_ut699"
5812   "fsqrts\t%1, %0"
5813   [(set_attr "type" "fpsqrts")])
5816 ;; Arithmetic shift instructions.
5818 (define_insn "ashlsi3"
5819   [(set (match_operand:SI 0 "register_operand" "=r")
5820         (ashift:SI (match_operand:SI 1 "register_operand" "r")
5821                    (match_operand:SI 2 "arith_operand" "rI")))]
5822   ""
5824   if (GET_CODE (operands[2]) == CONST_INT)
5825     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5826   return "sll\t%1, %2, %0";
5828   [(set_attr "type" "shift")])
5830 (define_expand "ashldi3"
5831   [(set (match_operand:DI 0 "register_operand" "=r")
5832         (ashift:DI (match_operand:DI 1 "register_operand" "r")
5833                    (match_operand:SI 2 "arith_operand" "rI")))]
5834   "TARGET_ARCH64 || TARGET_V8PLUS"
5836   if (! TARGET_ARCH64)
5837     {
5838       if (GET_CODE (operands[2]) == CONST_INT)
5839         FAIL;
5840       emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
5841       DONE;
5842     }
5845 (define_insn "*ashldi3_sp64"
5846   [(set (match_operand:DI 0 "register_operand" "=r")
5847         (ashift:DI (match_operand:DI 1 "register_operand" "r")
5848                    (match_operand:SI 2 "arith_operand" "rI")))]
5849   "TARGET_ARCH64"
5851   if (GET_CODE (operands[2]) == CONST_INT)
5852     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5853   return "sllx\t%1, %2, %0";
5855   [(set_attr "type" "shift")])
5857 ;; XXX UGH!
5858 (define_insn "ashldi3_v8plus"
5859   [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5860         (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5861                    (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5862    (clobber (match_scratch:SI 3 "=X,X,&h"))]
5863   "TARGET_V8PLUS"
5864   "* return output_v8plus_shift (insn ,operands, \"sllx\");"
5865   [(set_attr "type" "multi")
5866    (set_attr "length" "5,5,6")])
5868 ;; Optimize (1LL<<x)-1
5869 ;; XXX this also needs to be fixed to handle equal subregs
5870 ;; XXX first before we could re-enable it.
5871 ;(define_insn ""
5872 ;  [(set (match_operand:DI 0 "register_operand" "=h")
5873 ;       (plus:DI (ashift:DI (const_int 1)
5874 ;                           (match_operand:SI 1 "arith_operand" "rI"))
5875 ;                (const_int -1)))]
5876 ;  "0 && TARGET_V8PLUS"
5878 ;  if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
5879 ;    return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5880 ;  return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5882 ;  [(set_attr "type" "multi")
5883 ;   (set_attr "length" "4")])
5885 (define_insn "*cmp_cc_ashift_1"
5886   [(set (reg:CC_NOOV CC_REG)
5887         (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
5888                                     (const_int 1))
5889                          (const_int 0)))]
5890   ""
5891   "addcc\t%0, %0, %%g0"
5892   [(set_attr "type" "compare")])
5894 (define_insn "*cmp_cc_set_ashift_1"
5895   [(set (reg:CC_NOOV CC_REG)
5896         (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
5897                                     (const_int 1))
5898                          (const_int 0)))
5899    (set (match_operand:SI 0 "register_operand" "=r")
5900         (ashift:SI (match_dup 1) (const_int 1)))]
5901   ""
5902   "addcc\t%1, %1, %0"
5903   [(set_attr "type" "compare")])
5905 (define_insn "ashrsi3"
5906   [(set (match_operand:SI 0 "register_operand" "=r")
5907         (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5908                      (match_operand:SI 2 "arith_operand" "rI")))]
5909   ""
5910   {
5911      if (GET_CODE (operands[2]) == CONST_INT)
5912        operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5913      return "sra\t%1, %2, %0";
5914   }
5915   [(set_attr "type" "shift")])
5917 (define_insn "*ashrsi3_extend"
5918   [(set (match_operand:DI 0 "register_operand" "=r")
5919         (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5920                                      (match_operand:SI 2 "arith_operand" "r"))))]
5921   "TARGET_ARCH64"
5922   "sra\t%1, %2, %0"
5923   [(set_attr "type" "shift")])
5925 ;; This handles the case as above, but with constant shift instead of
5926 ;; register. Combiner "simplifies" it for us a little bit though.
5927 (define_insn "*ashrsi3_extend2"
5928   [(set (match_operand:DI 0 "register_operand" "=r")
5929         (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
5930                                 (const_int 32))
5931                      (match_operand:SI 2 "small_int_operand" "I")))]
5932   "TARGET_ARCH64 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64"
5934   operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
5935   return "sra\t%1, %2, %0";
5937   [(set_attr "type" "shift")])
5939 (define_expand "ashrdi3"
5940   [(set (match_operand:DI 0 "register_operand" "=r")
5941         (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5942                      (match_operand:SI 2 "arith_operand" "rI")))]
5943   "TARGET_ARCH64 || TARGET_V8PLUS"
5945   if (! TARGET_ARCH64)
5946     {
5947       if (GET_CODE (operands[2]) == CONST_INT)
5948         FAIL;   /* prefer generic code in this case */
5949       emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
5950       DONE;
5951     }
5954 (define_insn "*ashrdi3_sp64"
5955   [(set (match_operand:DI 0 "register_operand" "=r")
5956         (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5957                      (match_operand:SI 2 "arith_operand" "rI")))]
5958   "TARGET_ARCH64"
5959   
5960   {
5961     if (GET_CODE (operands[2]) == CONST_INT)
5962       operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5963     return "srax\t%1, %2, %0";
5964   }
5965   [(set_attr "type" "shift")])
5967 ;; XXX
5968 (define_insn "ashrdi3_v8plus"
5969   [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5970         (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5971                      (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5972    (clobber (match_scratch:SI 3 "=X,X,&h"))]
5973   "TARGET_V8PLUS"
5974   "* return output_v8plus_shift (insn, operands, \"srax\");"
5975   [(set_attr "type" "multi")
5976    (set_attr "length" "5,5,6")])
5978 (define_insn "lshrsi3"
5979   [(set (match_operand:SI 0 "register_operand" "=r")
5980         (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5981                      (match_operand:SI 2 "arith_operand" "rI")))]
5982   ""
5983   {
5984     if (GET_CODE (operands[2]) == CONST_INT)
5985       operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5986     return "srl\t%1, %2, %0";
5987   }
5988   [(set_attr "type" "shift")])
5990 (define_insn "*lshrsi3_extend0"
5991   [(set (match_operand:DI 0 "register_operand" "=r")
5992         (zero_extend:DI
5993           (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5994                        (match_operand:SI 2 "arith_operand" "rI"))))]
5995   "TARGET_ARCH64"
5996   {
5997     if (GET_CODE (operands[2]) == CONST_INT)
5998       operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5999     return "srl\t%1, %2, %0";
6000   }
6001   [(set_attr "type" "shift")])
6003 ;; This handles the case where
6004 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
6005 ;; but combiner "simplifies" it for us.
6006 (define_insn "*lshrsi3_extend1"
6007   [(set (match_operand:DI 0 "register_operand" "=r")
6008         (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
6009                            (match_operand:SI 2 "arith_operand" "r")) 0)
6010                 (match_operand 3 "const_int_operand" "")))]
6011   "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff"
6012   "srl\t%1, %2, %0"
6013   [(set_attr "type" "shift")])
6015 ;; This handles the case where
6016 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
6017 ;; but combiner "simplifies" it for us.
6018 (define_insn "*lshrsi3_extend2"
6019   [(set (match_operand:DI 0 "register_operand" "=r")
6020         (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
6021                          (match_operand 2 "small_int_operand" "I")
6022                          (const_int 32)))]
6023   "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6025   operands[2] = GEN_INT (32 - INTVAL (operands[2]));
6026   return "srl\t%1, %2, %0";
6028   [(set_attr "type" "shift")])
6030 (define_expand "lshrdi3"
6031   [(set (match_operand:DI 0 "register_operand" "=r")
6032         (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6033                      (match_operand:SI 2 "arith_operand" "rI")))]
6034   "TARGET_ARCH64 || TARGET_V8PLUS"
6036   if (! TARGET_ARCH64)
6037     {
6038       if (GET_CODE (operands[2]) == CONST_INT)
6039         FAIL;
6040       emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
6041       DONE;
6042     }
6045 (define_insn "*lshrdi3_sp64"
6046   [(set (match_operand:DI 0 "register_operand" "=r")
6047         (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6048                      (match_operand:SI 2 "arith_operand" "rI")))]
6049   "TARGET_ARCH64"
6050   {
6051     if (GET_CODE (operands[2]) == CONST_INT)
6052       operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6053     return "srlx\t%1, %2, %0";
6054   }
6055   [(set_attr "type" "shift")])
6057 ;; XXX
6058 (define_insn "lshrdi3_v8plus"
6059   [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6060         (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6061                      (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6062    (clobber (match_scratch:SI 3 "=X,X,&h"))]
6063   "TARGET_V8PLUS"
6064   "* return output_v8plus_shift (insn, operands, \"srlx\");"
6065   [(set_attr "type" "multi")
6066    (set_attr "length" "5,5,6")])
6068 (define_insn ""
6069   [(set (match_operand:SI 0 "register_operand" "=r")
6070         (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6071                                              (const_int 32)) 4)
6072                      (match_operand:SI 2 "small_int_operand" "I")))]
6073   "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6075   operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6076   return "srax\t%1, %2, %0";
6078   [(set_attr "type" "shift")])
6080 (define_insn ""
6081   [(set (match_operand:SI 0 "register_operand" "=r")
6082         (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6083                                              (const_int 32)) 4)
6084                      (match_operand:SI 2 "small_int_operand" "I")))]
6085   "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6087   operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6088   return "srlx\t%1, %2, %0";
6090   [(set_attr "type" "shift")])
6092 (define_insn ""
6093   [(set (match_operand:SI 0 "register_operand" "=r")
6094         (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6095                                              (match_operand:SI 2 "small_int_operand" "I")) 4)
6096                      (match_operand:SI 3 "small_int_operand" "I")))]
6097   "TARGET_ARCH64
6098    && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6099    && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6100    && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6102   operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6104   return "srax\t%1, %2, %0";
6106   [(set_attr "type" "shift")])
6108 (define_insn ""
6109   [(set (match_operand:SI 0 "register_operand" "=r")
6110         (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6111                                              (match_operand:SI 2 "small_int_operand" "I")) 4)
6112                      (match_operand:SI 3 "small_int_operand" "I")))]
6113   "TARGET_ARCH64
6114    && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6115    && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6116    && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6118   operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6120   return "srlx\t%1, %2, %0";
6122   [(set_attr "type" "shift")])
6125 ;; Unconditional and other jump instructions.
6127 (define_expand "jump"
6128   [(set (pc) (label_ref (match_operand 0 "" "")))]
6129   "")
6131 (define_insn "*jump_ubranch"
6132   [(set (pc) (label_ref (match_operand 0 "" "")))]
6133   "! TARGET_CBCOND"
6134   "* return output_ubranch (operands[0], insn);"
6135   [(set_attr "type" "uncond_branch")])
6137 (define_insn "*jump_cbcond"
6138   [(set (pc) (label_ref (match_operand 0 "" "")))]
6139   "TARGET_CBCOND"
6140   "* return output_ubranch (operands[0], insn);"
6141   [(set_attr "type" "uncond_cbcond")])
6143 (define_expand "tablejump"
6144   [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
6145               (use (label_ref (match_operand 1 "" "")))])]
6146   ""
6148   gcc_assert (GET_MODE (operands[0]) == CASE_VECTOR_MODE);
6150   /* In pic mode, our address differences are against the base of the
6151      table.  Add that base value back in; CSE ought to be able to combine
6152      the two address loads.  */
6153   if (flag_pic)
6154     {
6155       rtx tmp, tmp2;
6156       tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
6157       tmp2 = operands[0];
6158       if (CASE_VECTOR_MODE != Pmode)
6159         tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
6160       tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
6161       operands[0] = memory_address (Pmode, tmp);
6162     }
6165 (define_insn "*tablejump_sp32"
6166   [(set (pc) (match_operand:SI 0 "address_operand" "p"))
6167    (use (label_ref (match_operand 1 "" "")))]
6168   "! TARGET_ARCH64"
6169   "jmp\t%a0%#"
6170   [(set_attr "type" "uncond_branch")])
6172 (define_insn "*tablejump_sp64"
6173   [(set (pc) (match_operand:DI 0 "address_operand" "p"))
6174    (use (label_ref (match_operand 1 "" "")))]
6175   "TARGET_ARCH64"
6176   "jmp\t%a0%#"
6177   [(set_attr "type" "uncond_branch")])
6180 ;; Jump to subroutine instructions.
6182 (define_expand "call"
6183   ;; Note that this expression is not used for generating RTL.
6184   ;; All the RTL is generated explicitly below.
6185   [(call (match_operand 0 "call_operand" "")
6186          (match_operand 3 "" "i"))]
6187   ;; operands[2] is next_arg_register
6188   ;; operands[3] is struct_value_size_rtx.
6189   ""
6191   rtx fn_rtx;
6193   gcc_assert (MEM_P (operands[0]) && GET_MODE (operands[0]) == FUNCTION_MODE);
6195   gcc_assert (GET_CODE (operands[3]) == CONST_INT);
6197   if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
6198     {
6199       /* This is really a PIC sequence.  We want to represent
6200          it as a funny jump so its delay slots can be filled. 
6202          ??? But if this really *is* a CALL, will not it clobber the
6203          call-clobbered registers?  We lose this if it is a JUMP_INSN.
6204          Why cannot we have delay slots filled if it were a CALL?  */
6206       /* We accept negative sizes for untyped calls.  */
6207       if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6208         emit_jump_insn
6209           (gen_rtx_PARALLEL
6210            (VOIDmode,
6211             gen_rtvec (3,
6212                        gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6213                        operands[3],
6214                        gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6215       else
6216         emit_jump_insn
6217           (gen_rtx_PARALLEL
6218            (VOIDmode,
6219             gen_rtvec (2,
6220                        gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6221                        gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6222       goto finish_call;
6223     }
6225   fn_rtx = operands[0];
6227   /* We accept negative sizes for untyped calls.  */
6228   if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6229     sparc_emit_call_insn
6230       (gen_rtx_PARALLEL
6231        (VOIDmode,
6232         gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6233                    operands[3],
6234                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6235        XEXP (fn_rtx, 0));
6236   else
6237     sparc_emit_call_insn
6238       (gen_rtx_PARALLEL
6239        (VOIDmode,
6240         gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6241                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6242        XEXP (fn_rtx, 0));
6244  finish_call:
6246   DONE;
6249 ;; We can't use the same pattern for these two insns, because then registers
6250 ;; in the address may not be properly reloaded.
6252 (define_insn "*call_address_sp32"
6253   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6254          (match_operand 1 "" ""))
6255    (clobber (reg:SI O7_REG))]
6256   ;;- Do not use operand 1 for most machines.
6257   "! TARGET_ARCH64"
6258   "call\t%a0, %1%#"
6259   [(set_attr "type" "call")])
6261 (define_insn "*call_symbolic_sp32"
6262   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6263          (match_operand 1 "" ""))
6264    (clobber (reg:SI O7_REG))]
6265   ;;- Do not use operand 1 for most machines.
6266   "! TARGET_ARCH64"
6267   "call\t%a0, %1%#"
6268   [(set_attr "type" "call")])
6270 (define_insn "*call_address_sp64"
6271   [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
6272          (match_operand 1 "" ""))
6273    (clobber (reg:DI O7_REG))]
6274   ;;- Do not use operand 1 for most machines.
6275   "TARGET_ARCH64"
6276   "call\t%a0, %1%#"
6277   [(set_attr "type" "call")])
6279 (define_insn "*call_symbolic_sp64"
6280   [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6281          (match_operand 1 "" ""))
6282    (clobber (reg:DI O7_REG))]
6283   ;;- Do not use operand 1 for most machines.
6284   "TARGET_ARCH64"
6285   "call\t%a0, %1%#"
6286   [(set_attr "type" "call")])
6288 ;; This is a call that wants a structure value.
6289 ;; There is no such critter for v9 (??? we may need one anyway).
6290 (define_insn "*call_address_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"
6298   operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6299   return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6301   [(set_attr "type" "call_no_delay_slot")
6302    (set_attr "length" "3")])
6304 ;; This is a call that wants a structure value.
6305 ;; There is no such critter for v9 (??? we may need one anyway).
6306 (define_insn "*call_symbolic_struct_value_sp32"
6307   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6308          (match_operand 1 "" ""))
6309    (match_operand 2 "immediate_operand" "")
6310    (clobber (reg:SI O7_REG))]
6311   ;;- Do not use operand 1 for most machines.
6312   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6314   operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6315   return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6317   [(set_attr "type" "call_no_delay_slot")
6318    (set_attr "length" "3")])
6320 ;; This is a call that may want a structure value.  This is used for
6321 ;; untyped_calls.
6322 (define_insn "*call_address_untyped_struct_value_sp32"
6323   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6324          (match_operand 1 "" ""))
6325    (match_operand 2 "immediate_operand" "")
6326    (clobber (reg:SI O7_REG))]
6327   ;;- Do not use operand 1 for most machines.
6328   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6329   "call\t%a0, %1\n\t nop\n\tnop"
6330   [(set_attr "type" "call_no_delay_slot")
6331    (set_attr "length" "3")])
6333 ;; This is a call that may want a structure value.  This is used for
6334 ;; untyped_calls.
6335 (define_insn "*call_symbolic_untyped_struct_value_sp32"
6336   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6337          (match_operand 1 "" ""))
6338    (match_operand 2 "immediate_operand" "")
6339    (clobber (reg:SI O7_REG))]
6340   ;;- Do not use operand 1 for most machines.
6341   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6342   "call\t%a0, %1\n\t nop\n\tnop"
6343   [(set_attr "type" "call_no_delay_slot")
6344    (set_attr "length" "3")])
6346 (define_expand "call_value"
6347   ;; Note that this expression is not used for generating RTL.
6348   ;; All the RTL is generated explicitly below.
6349   [(set (match_operand 0 "register_operand" "=rf")
6350         (call (match_operand 1 "" "")
6351               (match_operand 4 "" "")))]
6352   ;; operand 2 is stack_size_rtx
6353   ;; operand 3 is next_arg_register
6354   ""
6356   rtx fn_rtx;
6357   rtvec vec;
6359   gcc_assert (MEM_P (operands[1]) && GET_MODE (operands[1]) == FUNCTION_MODE);
6361   fn_rtx = operands[1];
6363   vec = gen_rtvec (2,
6364                    gen_rtx_SET (VOIDmode, operands[0],
6365                                 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
6366                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
6368   sparc_emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec), XEXP (fn_rtx, 0));
6370   DONE;
6373 (define_insn "*call_value_address_sp32"
6374   [(set (match_operand 0 "" "=rf")
6375         (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
6376               (match_operand 2 "" "")))
6377    (clobber (reg:SI O7_REG))]
6378   ;;- Do not use operand 2 for most machines.
6379   "! TARGET_ARCH64"
6380   "call\t%a1, %2%#"
6381   [(set_attr "type" "call")])
6383 (define_insn "*call_value_symbolic_sp32"
6384   [(set (match_operand 0 "" "=rf")
6385         (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6386               (match_operand 2 "" "")))
6387    (clobber (reg:SI O7_REG))]
6388   ;;- Do not use operand 2 for most machines.
6389   "! TARGET_ARCH64"
6390   "call\t%a1, %2%#"
6391   [(set_attr "type" "call")])
6393 (define_insn "*call_value_address_sp64"
6394   [(set (match_operand 0 "" "")
6395         (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
6396               (match_operand 2 "" "")))
6397    (clobber (reg:DI O7_REG))]
6398   ;;- Do not use operand 2 for most machines.
6399   "TARGET_ARCH64"
6400   "call\t%a1, %2%#"
6401   [(set_attr "type" "call")])
6403 (define_insn "*call_value_symbolic_sp64"
6404   [(set (match_operand 0 "" "")
6405         (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6406               (match_operand 2 "" "")))
6407    (clobber (reg:DI O7_REG))]
6408   ;;- Do not use operand 2 for most machines.
6409   "TARGET_ARCH64"
6410   "call\t%a1, %2%#"
6411   [(set_attr "type" "call")])
6413 (define_expand "untyped_call"
6414   [(parallel [(call (match_operand 0 "" "")
6415                     (const_int 0))
6416               (match_operand:BLK 1 "memory_operand" "")
6417               (match_operand 2 "" "")])]
6418   ""
6420   rtx valreg1 = gen_rtx_REG (DImode, 8);
6421   rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6422   rtx result = operands[1];
6424   /* Pass constm1 to indicate that it may expect a structure value, but
6425      we don't know what size it is.  */
6426   emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
6428   /* Save the function value registers.  */
6429   emit_move_insn (adjust_address (result, DImode, 0), valreg1);
6430   emit_move_insn (adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8),
6431                                   valreg2);
6433   /* The optimizer does not know that the call sets the function value
6434      registers we stored in the result block.  We avoid problems by
6435      claiming that all hard registers are used and clobbered at this
6436      point.  */
6437   emit_insn (gen_blockage ());
6439   DONE;
6442 ;;  Tail call instructions.
6444 (define_expand "sibcall"
6445   [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
6446               (return)])]
6447   ""
6448   "")
6450 (define_insn "*sibcall_symbolic_sp32"
6451   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6452          (match_operand 1 "" ""))
6453    (return)]
6454   "! TARGET_ARCH64"
6455   "* return output_sibcall(insn, operands[0]);"
6456   [(set_attr "type" "sibcall")])
6458 (define_insn "*sibcall_symbolic_sp64"
6459   [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6460          (match_operand 1 "" ""))
6461    (return)]
6462   "TARGET_ARCH64"
6463   "* return output_sibcall(insn, operands[0]);"
6464   [(set_attr "type" "sibcall")])
6466 (define_expand "sibcall_value"
6467   [(parallel [(set (match_operand 0 "register_operand" "=rf")
6468                 (call (match_operand 1 "" "") (const_int 0)))
6469               (return)])]
6470   ""
6471   "")
6473 (define_insn "*sibcall_value_symbolic_sp32"
6474   [(set (match_operand 0 "" "=rf")
6475         (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6476               (match_operand 2 "" "")))
6477    (return)]
6478   "! TARGET_ARCH64"
6479   "* return output_sibcall(insn, operands[1]);"
6480   [(set_attr "type" "sibcall")])
6482 (define_insn "*sibcall_value_symbolic_sp64"
6483   [(set (match_operand 0 "" "")
6484         (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6485               (match_operand 2 "" "")))
6486    (return)]
6487   "TARGET_ARCH64"
6488   "* return output_sibcall(insn, operands[1]);"
6489   [(set_attr "type" "sibcall")])
6492 ;; Special instructions.
6494 (define_expand "prologue"
6495   [(const_int 0)]
6496   ""
6498   if (TARGET_FLAT)
6499     sparc_flat_expand_prologue ();
6500   else
6501     sparc_expand_prologue ();
6502   DONE;
6505 ;; The "register window save" insn is modelled as follows.  The dwarf2
6506 ;; information is manually added in emit_window_save.
6508 (define_insn "window_save"
6509   [(unspec_volatile
6510         [(match_operand 0 "arith_operand" "rI")]
6511         UNSPECV_SAVEW)]
6512   "!TARGET_FLAT"
6513   "save\t%%sp, %0, %%sp"
6514   [(set_attr "type" "savew")])
6516 (define_expand "epilogue"
6517   [(return)]
6518   ""
6520   if (TARGET_FLAT)
6521     sparc_flat_expand_epilogue (false);
6522   else
6523     sparc_expand_epilogue (false);
6526 (define_expand "sibcall_epilogue"
6527   [(return)]
6528   ""
6530   if (TARGET_FLAT)
6531     sparc_flat_expand_epilogue (false);
6532   else
6533     sparc_expand_epilogue (false);
6534   DONE;
6537 (define_expand "eh_return"
6538   [(use (match_operand 0 "general_operand" ""))]
6539   ""
6541   emit_move_insn (gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM), operands[0]);
6542   emit_jump_insn (gen_eh_return_internal ());
6543   emit_barrier ();
6544   DONE;
6547 (define_insn_and_split "eh_return_internal"
6548   [(eh_return)]
6549   ""
6550   "#"
6551   "epilogue_completed"
6552   [(return)]
6554   if (TARGET_FLAT)
6555     sparc_flat_expand_epilogue (true);
6556   else
6557     sparc_expand_epilogue (true);
6560 (define_expand "return"
6561   [(return)]
6562   "sparc_can_use_return_insn_p ()"
6563   "")
6565 (define_insn "*return_internal"
6566   [(return)]
6567   ""
6568   "* return output_return (insn);"
6569   [(set_attr "type" "return")
6570    (set (attr "length")
6571         (cond [(eq_attr "calls_eh_return" "true")
6572                  (if_then_else (eq_attr "delayed_branch" "true")
6573                                 (if_then_else (ior (eq_attr "isa" "v9")
6574                                                    (eq_attr "flat" "true"))
6575                                         (const_int 2)
6576                                         (const_int 3))
6577                                 (if_then_else (eq_attr "flat" "true")
6578                                         (const_int 3)
6579                                         (const_int 4)))
6580                (ior (eq_attr "leaf_function" "true") (eq_attr "flat" "true"))
6581                  (if_then_else (eq_attr "empty_delay_slot" "true")
6582                                (const_int 2)
6583                                (const_int 1))
6584                (eq_attr "empty_delay_slot" "true")
6585                  (if_then_else (eq_attr "delayed_branch" "true")
6586                                (const_int 2)
6587                                (const_int 3))
6588               ] (const_int 1)))])
6590 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
6591 ;; all of memory.  This blocks insns from being moved across this point.
6593 (define_insn "blockage"
6594   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
6595   ""
6596   ""
6597   [(set_attr "length" "0")])
6599 ;; Do not schedule instructions accessing memory before this point.
6601 (define_expand "frame_blockage"
6602   [(set (match_dup 0)
6603         (unspec:BLK [(match_dup 1)] UNSPEC_FRAME_BLOCKAGE))]
6604   ""
6606   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
6607   MEM_VOLATILE_P (operands[0]) = 1;
6608   operands[1] = stack_pointer_rtx;
6611 (define_insn "*frame_blockage<P:mode>"
6612   [(set (match_operand:BLK 0 "" "")
6613         (unspec:BLK [(match_operand:P 1 "" "")] UNSPEC_FRAME_BLOCKAGE))]
6614   ""
6615   ""
6616   [(set_attr "length" "0")])
6618 (define_expand "probe_stack"
6619   [(set (match_operand 0 "memory_operand" "") (const_int 0))]
6620   ""
6622   operands[0]
6623     = adjust_address (operands[0], GET_MODE (operands[0]), SPARC_STACK_BIAS);
6626 (define_insn "probe_stack_range<P:mode>"
6627   [(set (match_operand:P 0 "register_operand" "=r")
6628         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
6629                             (match_operand:P 2 "register_operand" "r")]
6630                             UNSPECV_PROBE_STACK_RANGE))]
6631   ""
6632   "* return output_probe_stack_range (operands[0], operands[2]);"
6633   [(set_attr "type" "multi")])
6635 ;; Prepare to return any type including a structure value.
6637 (define_expand "untyped_return"
6638   [(match_operand:BLK 0 "memory_operand" "")
6639    (match_operand 1 "" "")]
6640   ""
6642   rtx valreg1 = gen_rtx_REG (DImode, 24);
6643   rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6644   rtx result = operands[0];
6646   if (! TARGET_ARCH64)
6647     {
6648       rtx rtnreg = gen_rtx_REG (SImode, RETURN_ADDR_REGNUM);
6649       rtx value = gen_reg_rtx (SImode);
6651       /* Fetch the instruction where we will return to and see if it's an unimp
6652          instruction (the most significant 10 bits will be zero).  If so,
6653          update the return address to skip the unimp instruction.  */
6654       emit_move_insn (value,
6655                       gen_rtx_MEM (SImode, plus_constant (SImode, rtnreg, 8)));
6656       emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
6657       emit_insn (gen_update_return (rtnreg, value));
6658     }
6660   /* Reload the function value registers.  */
6661   emit_move_insn (valreg1, adjust_address (result, DImode, 0));
6662   emit_move_insn (valreg2,
6663                   adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
6665   /* Put USE insns before the return.  */
6666   emit_use (valreg1);
6667   emit_use (valreg2);
6669   /* Construct the return.  */
6670   expand_naked_return ();
6672   DONE;
6675 ;; Adjust the return address conditionally. If the value of op1 is equal
6676 ;; to all zero then adjust the return address i.e. op0 = op0 + 4.
6677 ;; This is technically *half* the check required by the 32-bit SPARC
6678 ;; psABI. This check only ensures that an "unimp" insn was written by
6679 ;; the caller, but doesn't check to see if the expected size matches
6680 ;; (this is encoded in the 12 lower bits). This check is obsolete and
6681 ;; only used by the above code "untyped_return".
6683 (define_insn "update_return"
6684   [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
6685                (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
6686   "! TARGET_ARCH64"
6688   if (flag_delayed_branch)
6689     return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
6690   else
6691     return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
6693   [(set (attr "type") (const_string "multi"))
6694    (set (attr "length")
6695         (if_then_else (eq_attr "delayed_branch" "true")
6696                       (const_int 3)
6697                       (const_int 4)))])
6699 (define_insn "nop"
6700   [(const_int 0)]
6701   ""
6702   "nop")
6704 (define_expand "indirect_jump"
6705   [(set (pc) (match_operand 0 "address_operand" "p"))]
6706   ""
6707   "")
6709 (define_insn "*branch_sp32"
6710   [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
6711   "! TARGET_ARCH64"
6712  "jmp\t%a0%#"
6713  [(set_attr "type" "uncond_branch")])
6715 (define_insn "*branch_sp64"
6716   [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
6717   "TARGET_ARCH64"
6718   "jmp\t%a0%#"
6719   [(set_attr "type" "uncond_branch")])
6721 (define_expand "save_stack_nonlocal"
6722   [(set (match_operand 0 "memory_operand" "")
6723         (match_operand 1 "register_operand" ""))
6724    (set (match_dup 2) (match_dup 3))]
6725   ""
6727   operands[0] = adjust_address_nv (operands[0], Pmode, 0);
6728   operands[2] = adjust_address_nv (operands[0], Pmode, GET_MODE_SIZE (Pmode));
6729   operands[3] = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
6732 (define_expand "restore_stack_nonlocal"
6733   [(set (match_operand 0 "register_operand" "")
6734         (match_operand 1 "memory_operand" ""))]
6735   ""
6737   operands[1] = adjust_address_nv (operands[1], Pmode, 0);
6740 (define_expand "nonlocal_goto"
6741   [(match_operand 0 "general_operand" "")
6742    (match_operand 1 "general_operand" "")
6743    (match_operand 2 "memory_operand" "")
6744    (match_operand 3 "memory_operand" "")]
6745   ""
6747   rtx i7 = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
6748   rtx r_label = copy_to_reg (operands[1]);
6749   rtx r_sp = adjust_address_nv (operands[2], Pmode, 0);
6750   rtx r_fp = operands[3];
6751   rtx r_i7 = adjust_address_nv (operands[2], Pmode, GET_MODE_SIZE (Pmode));
6753   /* We need to flush all the register windows so that their contents will
6754      be re-synchronized by the restore insn of the target function.  */
6755   if (!TARGET_FLAT)
6756     emit_insn (gen_flush_register_windows ());
6758   emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
6759   emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
6761   /* Restore frame pointer for containing function.  */
6762   emit_move_insn (hard_frame_pointer_rtx, r_fp);
6763   emit_stack_restore (SAVE_NONLOCAL, r_sp);
6764   emit_move_insn (i7, r_i7);
6766   /* USE of hard_frame_pointer_rtx added for consistency;
6767      not clear if really needed.  */
6768   emit_use (hard_frame_pointer_rtx);
6769   emit_use (stack_pointer_rtx);
6770   emit_use (i7);
6772   emit_jump_insn (gen_indirect_jump (r_label));
6773   emit_barrier ();
6774   DONE;
6777 (define_expand "builtin_setjmp_receiver"
6778   [(label_ref (match_operand 0 "" ""))]
6779   "flag_pic"
6781   load_got_register ();
6782   DONE;
6785 ;; Special insn to flush register windows.
6787 (define_insn "flush_register_windows"
6788   [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
6789   ""
6790   { return TARGET_V9 ? "flushw" : "ta\t3"; }
6791   [(set_attr "type" "flushw")])
6793 ;; Special pattern for the FLUSH instruction.
6795 (define_insn "flush<P:mode>"
6796   [(unspec_volatile [(match_operand:P 0 "memory_operand" "m")] UNSPECV_FLUSH)]
6797   ""
6798   { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
6799   [(set_attr "type" "iflush")])
6801 ;; Special insns to load and store the 32-bit FP Status Register.
6803 (define_insn "ldfsr"
6804   [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_LDFSR)]
6805   "TARGET_FPU"
6806   "ld\t%0, %%fsr"
6807   [(set_attr "type" "load")])
6809 (define_insn "stfsr"
6810   [(set (match_operand:SI 0 "memory_operand" "=m")
6811         (unspec_volatile:SI [(const_int 0)] UNSPECV_STFSR))]
6812   "TARGET_FPU"
6813   "st\t%%fsr, %0"
6814   [(set_attr "type" "store")])
6817 ;; Find first set instructions.
6819 ;; The scan instruction searches from the most significant bit while ffs
6820 ;; searches from the least significant bit.  The bit index and treatment of
6821 ;; zero also differ.  It takes at least 7 instructions to get the proper
6822 ;; result.  Here is an obvious 8 instruction sequence.
6824 ;; XXX
6825 (define_insn "ffssi2"
6826   [(set (match_operand:SI 0 "register_operand" "=&r")
6827         (ffs:SI (match_operand:SI 1 "register_operand" "r")))
6828    (clobber (match_scratch:SI 2 "=&r"))]
6829   "TARGET_SPARCLITE || TARGET_SPARCLET"
6831   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";
6833   [(set_attr "type" "multi")
6834    (set_attr "length" "8")])
6836 (define_expand "popcountdi2"
6837   [(set (match_operand:DI 0 "register_operand" "")
6838         (popcount:DI (match_operand:DI 1 "register_operand" "")))]
6839   "TARGET_POPC"
6841   if (! TARGET_ARCH64)
6842     {
6843       emit_insn (gen_popcountdi_v8plus (operands[0], operands[1]));
6844       DONE;
6845     }
6848 (define_insn "*popcountdi_sp64"
6849   [(set (match_operand:DI 0 "register_operand" "=r")
6850         (popcount:DI (match_operand:DI 1 "register_operand" "r")))]
6851   "TARGET_POPC && TARGET_ARCH64"
6852   "popc\t%1, %0")
6854 (define_insn "popcountdi_v8plus"
6855   [(set (match_operand:DI 0 "register_operand" "=r")
6856         (popcount:DI (match_operand:DI 1 "register_operand" "r")))
6857    (clobber (match_scratch:SI 2 "=&h"))]
6858   "TARGET_POPC && ! TARGET_ARCH64"
6860   if (sparc_check_64 (operands[1], insn) <= 0)
6861     output_asm_insn ("srl\t%L1, 0, %L1", operands);
6862   return "sllx\t%H1, 32, %2\n\tor\t%L1, %2, %2\n\tpopc\t%2, %L0\n\tclr\t%H0";
6864   [(set_attr "type" "multi")
6865    (set_attr "length" "5")])
6867 (define_expand "popcountsi2"
6868   [(set (match_dup 2)
6869         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
6870    (set (match_operand:SI 0 "register_operand" "")
6871         (truncate:SI (popcount:DI (match_dup 2))))]
6872   "TARGET_POPC"
6874   if (! TARGET_ARCH64)
6875     {
6876       emit_insn (gen_popcountsi_v8plus (operands[0], operands[1]));
6877       DONE;
6878     }
6879   else
6880     operands[2] = gen_reg_rtx (DImode);
6883 (define_insn "*popcountsi_sp64"
6884   [(set (match_operand:SI 0 "register_operand" "=r")
6885         (truncate:SI
6886           (popcount:DI (match_operand:DI 1 "register_operand" "r"))))]
6887   "TARGET_POPC && TARGET_ARCH64"
6888   "popc\t%1, %0")
6890 (define_insn "popcountsi_v8plus"
6891   [(set (match_operand:SI 0 "register_operand" "=r")
6892         (popcount:SI (match_operand:SI 1 "register_operand" "r")))]
6893   "TARGET_POPC && ! TARGET_ARCH64"
6895   if (sparc_check_64 (operands[1], insn) <= 0)
6896     output_asm_insn ("srl\t%1, 0, %1", operands);
6897   return "popc\t%1, %0";
6899   [(set_attr "type" "multi")
6900    (set_attr "length" "2")])
6902 (define_expand "clzdi2"
6903   [(set (match_operand:DI 0 "register_operand" "")
6904         (clz:DI (match_operand:DI 1 "register_operand" "")))]
6905   "TARGET_VIS3"
6907   if (! TARGET_ARCH64)
6908     {
6909       emit_insn (gen_clzdi_v8plus (operands[0], operands[1]));
6910       DONE;
6911     }
6914 (define_insn "*clzdi_sp64"
6915   [(set (match_operand:DI 0 "register_operand" "=r")
6916         (clz:DI (match_operand:DI 1 "register_operand" "r")))]
6917   "TARGET_VIS3 && TARGET_ARCH64"
6918   "lzd\t%1, %0")
6920 (define_insn "clzdi_v8plus"
6921   [(set (match_operand:DI 0 "register_operand" "=r")
6922         (clz:DI (match_operand:DI 1 "register_operand" "r")))
6923    (clobber (match_scratch:SI 2 "=&h"))]
6924   "TARGET_VIS3 && ! TARGET_ARCH64"
6926   if (sparc_check_64 (operands[1], insn) <= 0)
6927     output_asm_insn ("srl\t%L1, 0, %L1", operands);
6928   return "sllx\t%H1, 32, %2\n\tor\t%L1, %2, %2\n\tlzd\t%2, %L0\n\tclr\t%H0";
6930   [(set_attr "type" "multi")
6931    (set_attr "length" "5")])
6933 (define_expand "clzsi2"
6934   [(set (match_dup 2)
6935         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
6936    (set (match_dup 3)
6937         (truncate:SI (clz:DI (match_dup 2))))
6938    (set (match_operand:SI 0 "register_operand" "")
6939         (minus:SI (match_dup 3) (const_int 32)))]
6940   "TARGET_VIS3"
6942   if (! TARGET_ARCH64)
6943     {
6944       emit_insn (gen_clzsi_v8plus (operands[0], operands[1]));
6945       DONE;
6946     }
6947   else
6948     {
6949       operands[2] = gen_reg_rtx (DImode);
6950       operands[3] = gen_reg_rtx (SImode);
6951     }
6954 (define_insn "*clzsi_sp64"
6955   [(set (match_operand:SI 0 "register_operand" "=r")
6956         (truncate:SI
6957           (clz:DI (match_operand:DI 1 "register_operand" "r"))))]
6958   "TARGET_VIS3 && TARGET_ARCH64"
6959   "lzd\t%1, %0")
6961 (define_insn "clzsi_v8plus"
6962   [(set (match_operand:SI 0 "register_operand" "=r")
6963         (clz:SI (match_operand:SI 1 "register_operand" "r")))]
6964   "TARGET_VIS3 && ! TARGET_ARCH64"
6966   if (sparc_check_64 (operands[1], insn) <= 0)
6967     output_asm_insn ("srl\t%1, 0, %1", operands);
6968   return "lzd\t%1, %0\n\tsub\t%0, 32, %0";
6970   [(set_attr "type" "multi")
6971    (set_attr "length" "3")])
6974 ;; Peepholes go at the end.
6976 ;; Optimize consecutive loads or stores into ldd and std when possible.
6977 ;; The conditions in which we do this are very restricted and are 
6978 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
6980 (define_peephole2
6981   [(set (match_operand:SI 0 "memory_operand" "")
6982       (const_int 0))
6983    (set (match_operand:SI 1 "memory_operand" "")
6984       (const_int 0))]
6985   "TARGET_V9
6986    && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
6987   [(set (match_dup 0) (const_int 0))]
6989   operands[0] = widen_mem_for_ldd_peep (operands[0], operands[1], DImode);
6992 (define_peephole2
6993   [(set (match_operand:SI 0 "memory_operand" "")
6994       (const_int 0))
6995    (set (match_operand:SI 1 "memory_operand" "")
6996       (const_int 0))]
6997   "TARGET_V9
6998    && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
6999   [(set (match_dup 1) (const_int 0))]
7001   operands[1] = widen_mem_for_ldd_peep (operands[1], operands[0], DImode);
7004 (define_peephole2
7005   [(set (match_operand:SI 0 "register_operand" "")
7006         (match_operand:SI 1 "memory_operand" ""))
7007    (set (match_operand:SI 2 "register_operand" "")
7008         (match_operand:SI 3 "memory_operand" ""))]
7009   "registers_ok_for_ldd_peep (operands[0], operands[2]) 
7010    && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])" 
7011   [(set (match_dup 0) (match_dup 1))]
7013   operands[1] = widen_mem_for_ldd_peep (operands[1], operands[3], DImode);
7014   operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
7017 (define_peephole2
7018   [(set (match_operand:SI 0 "memory_operand" "")
7019         (match_operand:SI 1 "register_operand" ""))
7020    (set (match_operand:SI 2 "memory_operand" "")
7021         (match_operand:SI 3 "register_operand" ""))]
7022   "registers_ok_for_ldd_peep (operands[1], operands[3]) 
7023    && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7024   [(set (match_dup 0) (match_dup 1))]
7026   operands[0] = widen_mem_for_ldd_peep (operands[0], operands[2], DImode);
7027   operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));
7030 (define_peephole2
7031   [(set (match_operand:SF 0 "register_operand" "")
7032         (match_operand:SF 1 "memory_operand" ""))
7033    (set (match_operand:SF 2 "register_operand" "")
7034         (match_operand:SF 3 "memory_operand" ""))]
7035   "registers_ok_for_ldd_peep (operands[0], operands[2]) 
7036    && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
7037   [(set (match_dup 0) (match_dup 1))]
7039   operands[1] = widen_mem_for_ldd_peep (operands[1], operands[3], DFmode);
7040   operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));
7043 (define_peephole2
7044   [(set (match_operand:SF 0 "memory_operand" "")
7045         (match_operand:SF 1 "register_operand" ""))
7046    (set (match_operand:SF 2 "memory_operand" "")
7047         (match_operand:SF 3 "register_operand" ""))]
7048   "registers_ok_for_ldd_peep (operands[1], operands[3]) 
7049   && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7050   [(set (match_dup 0) (match_dup 1))]
7052   operands[0] = widen_mem_for_ldd_peep (operands[0], operands[2], DFmode);
7053   operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));
7056 (define_peephole2
7057   [(set (match_operand:SI 0 "register_operand" "")
7058         (match_operand:SI 1 "memory_operand" ""))
7059    (set (match_operand:SI 2 "register_operand" "")
7060         (match_operand:SI 3 "memory_operand" ""))]
7061   "registers_ok_for_ldd_peep (operands[2], operands[0]) 
7062   && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
7063   [(set (match_dup 2) (match_dup 3))]
7065   operands[3] = widen_mem_for_ldd_peep (operands[3], operands[1], DImode);
7066   operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));
7069 (define_peephole2
7070   [(set (match_operand:SI 0 "memory_operand" "")
7071         (match_operand:SI 1 "register_operand" ""))
7072    (set (match_operand:SI 2 "memory_operand" "")
7073         (match_operand:SI 3 "register_operand" ""))]
7074   "registers_ok_for_ldd_peep (operands[3], operands[1]) 
7075   && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)" 
7076   [(set (match_dup 2) (match_dup 3))]
7078   operands[2] = widen_mem_for_ldd_peep (operands[2],  operands[0], DImode);
7079   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
7082 (define_peephole2
7083   [(set (match_operand:SF 0 "register_operand" "")
7084         (match_operand:SF 1 "memory_operand" ""))
7085    (set (match_operand:SF 2 "register_operand" "")
7086         (match_operand:SF 3 "memory_operand" ""))]
7087   "registers_ok_for_ldd_peep (operands[2], operands[0]) 
7088   && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
7089   [(set (match_dup 2) (match_dup 3))]
7091   operands[3] = widen_mem_for_ldd_peep (operands[3], operands[1], DFmode);
7092   operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));
7095 (define_peephole2
7096   [(set (match_operand:SF 0 "memory_operand" "")
7097         (match_operand:SF 1 "register_operand" ""))
7098    (set (match_operand:SF 2 "memory_operand" "")
7099         (match_operand:SF 3 "register_operand" ""))]
7100   "registers_ok_for_ldd_peep (operands[3], operands[1]) 
7101   && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
7102   [(set (match_dup 2) (match_dup 3))]
7104   operands[2] = widen_mem_for_ldd_peep (operands[2], operands[0], DFmode);
7105   operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));
7108 ;; Optimize the case of following a reg-reg move with a test
7109 ;; of reg just moved.  Don't allow floating point regs for operand 0 or 1.
7110 ;; This can result from a float to fix conversion.
7112 (define_peephole2
7113   [(set (match_operand:SI 0 "register_operand" "")
7114         (match_operand:SI 1 "register_operand" ""))
7115    (set (reg:CC CC_REG)
7116         (compare:CC (match_operand:SI 2 "register_operand" "")
7117                     (const_int 0)))]
7118   "(rtx_equal_p (operands[2], operands[0])
7119     || rtx_equal_p (operands[2], operands[1]))
7120     && ! SPARC_FP_REG_P (REGNO (operands[0]))
7121     && ! SPARC_FP_REG_P (REGNO (operands[1]))"
7122   [(parallel [(set (match_dup 0) (match_dup 1))
7123               (set (reg:CC CC_REG)
7124                    (compare:CC (match_dup 1) (const_int 0)))])]
7125   "")
7127 (define_peephole2
7128   [(set (match_operand:DI 0 "register_operand" "")
7129         (match_operand:DI 1 "register_operand" ""))
7130    (set (reg:CCX CC_REG)
7131         (compare:CCX (match_operand:DI 2 "register_operand" "")
7132                     (const_int 0)))]
7133   "TARGET_ARCH64
7134    && (rtx_equal_p (operands[2], operands[0])
7135        || rtx_equal_p (operands[2], operands[1]))
7136    && ! SPARC_FP_REG_P (REGNO (operands[0]))
7137    && ! SPARC_FP_REG_P (REGNO (operands[1]))"
7138   [(parallel [(set (match_dup 0) (match_dup 1))
7139               (set (reg:CCX CC_REG)
7140                    (compare:CCX (match_dup 1) (const_int 0)))])]
7141   "")
7144 ;; Prefetch instructions.
7146 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
7147 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
7148 ;; ??? operations.  With DFA we might be able to model this, but it requires a lot of
7149 ;; ??? state.
7150 (define_expand "prefetch"
7151   [(match_operand 0 "address_operand" "")
7152    (match_operand 1 "const_int_operand" "")
7153    (match_operand 2 "const_int_operand" "")]
7154   "TARGET_V9"
7156   if (TARGET_ARCH64)
7157     emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
7158   else
7159     emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
7160   DONE;
7163 (define_insn "prefetch_64"
7164   [(prefetch (match_operand:DI 0 "address_operand" "p")
7165              (match_operand:DI 1 "const_int_operand" "n")
7166              (match_operand:DI 2 "const_int_operand" "n"))]
7167   ""
7169   static const char * const prefetch_instr[2][2] = {
7170     {
7171       "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7172       "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7173     },
7174     {
7175       "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7176       "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7177     }
7178   };
7179   int read_or_write = INTVAL (operands[1]);
7180   int locality = INTVAL (operands[2]);
7182   gcc_assert (read_or_write == 0 || read_or_write == 1);
7183   gcc_assert (locality >= 0 && locality < 4);
7184   return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7186   [(set_attr "type" "load")])
7188 (define_insn "prefetch_32"
7189   [(prefetch (match_operand:SI 0 "address_operand" "p")
7190              (match_operand:SI 1 "const_int_operand" "n")
7191              (match_operand:SI 2 "const_int_operand" "n"))]
7192   ""
7194   static const char * const prefetch_instr[2][2] = {
7195     {
7196       "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7197       "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7198     },
7199     {
7200       "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7201       "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7202     }
7203   };
7204   int read_or_write = INTVAL (operands[1]);
7205   int locality = INTVAL (operands[2]);
7207   gcc_assert (read_or_write == 0 || read_or_write == 1);
7208   gcc_assert (locality >= 0 && locality < 4);
7209   return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7211   [(set_attr "type" "load")])
7214 ;; Trap instructions.
7216 (define_insn "trap"
7217   [(trap_if (const_int 1) (const_int 5))]
7218   ""
7219   "ta\t5"
7220   [(set_attr "type" "trap")])
7222 (define_expand "ctrapsi4"
7223   [(trap_if (match_operator 0 "noov_compare_operator"
7224              [(match_operand:SI 1 "compare_operand" "")
7225               (match_operand:SI 2 "arith_operand" "")])
7226            (match_operand 3 "arith_operand"))]
7227   ""
7228   "operands[1] = gen_compare_reg (operands[0]);
7229    if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
7230      FAIL;
7231    operands[2] = const0_rtx;")
7233 (define_expand "ctrapdi4"
7234   [(trap_if (match_operator 0 "noov_compare_operator"
7235              [(match_operand:DI 1 "compare_operand" "")
7236               (match_operand:DI 2 "arith_operand" "")])
7237            (match_operand 3 "arith_operand"))]
7238   "TARGET_ARCH64"
7239   "operands[1] = gen_compare_reg (operands[0]);
7240    if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
7241      FAIL;
7242    operands[2] = const0_rtx;")
7245 (define_insn ""
7246   [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CC CC_REG) (const_int 0)])
7247             (match_operand:SI 1 "arith_operand" "rM"))]
7248   ""
7250   if (TARGET_V9)
7251     return "t%C0\t%%icc, %1";
7252   else
7253     return "t%C0\t%1";
7255   [(set_attr "type" "trap")])
7257 (define_insn ""
7258   [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CCX CC_REG) (const_int 0)])
7259             (match_operand:SI 1 "arith_operand" "rM"))]
7260   "TARGET_V9"
7261   "t%C0\t%%xcc, %1"
7262   [(set_attr "type" "trap")])
7265 ;; TLS support instructions.
7267 (define_insn "tgd_hi22"
7268   [(set (match_operand:SI 0 "register_operand" "=r")
7269         (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
7270                             UNSPEC_TLSGD)))]
7271   "TARGET_TLS"
7272   "sethi\\t%%tgd_hi22(%a1), %0")
7274 (define_insn "tgd_lo10"
7275   [(set (match_operand:SI 0 "register_operand" "=r")
7276         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7277                    (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
7278                               UNSPEC_TLSGD)))]
7279   "TARGET_TLS"
7280   "add\\t%1, %%tgd_lo10(%a2), %0")
7282 (define_insn "tgd_add32"
7283   [(set (match_operand:SI 0 "register_operand" "=r")
7284         (plus:SI (match_operand:SI 1 "register_operand" "r")
7285                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7286                              (match_operand 3 "tgd_symbolic_operand" "")]
7287                             UNSPEC_TLSGD)))]
7288   "TARGET_TLS && TARGET_ARCH32"
7289   "add\\t%1, %2, %0, %%tgd_add(%a3)")
7291 (define_insn "tgd_add64"
7292   [(set (match_operand:DI 0 "register_operand" "=r")
7293         (plus:DI (match_operand:DI 1 "register_operand" "r")
7294                  (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7295                              (match_operand 3 "tgd_symbolic_operand" "")]
7296                             UNSPEC_TLSGD)))]
7297   "TARGET_TLS && TARGET_ARCH64"
7298   "add\\t%1, %2, %0, %%tgd_add(%a3)")
7300 (define_insn "tgd_call32"
7301   [(set (match_operand 0 "register_operand" "=r")
7302         (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
7303                                   (match_operand 2 "tgd_symbolic_operand" "")]
7304                                  UNSPEC_TLSGD))
7305               (match_operand 3 "" "")))
7306    (clobber (reg:SI O7_REG))]
7307   "TARGET_TLS && TARGET_ARCH32"
7308   "call\t%a1, %%tgd_call(%a2)%#"
7309   [(set_attr "type" "call")])
7311 (define_insn "tgd_call64"
7312   [(set (match_operand 0 "register_operand" "=r")
7313         (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
7314                                   (match_operand 2 "tgd_symbolic_operand" "")]
7315                                  UNSPEC_TLSGD))
7316               (match_operand 3 "" "")))
7317    (clobber (reg:DI O7_REG))]
7318   "TARGET_TLS && TARGET_ARCH64"
7319   "call\t%a1, %%tgd_call(%a2)%#"
7320   [(set_attr "type" "call")])
7322 (define_insn "tldm_hi22"
7323   [(set (match_operand:SI 0 "register_operand" "=r")
7324         (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7325   "TARGET_TLS"
7326   "sethi\\t%%tldm_hi22(%&), %0")
7328 (define_insn "tldm_lo10"
7329   [(set (match_operand:SI 0 "register_operand" "=r")
7330         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7331                     (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7332   "TARGET_TLS"
7333   "add\\t%1, %%tldm_lo10(%&), %0")
7335 (define_insn "tldm_add32"
7336   [(set (match_operand:SI 0 "register_operand" "=r")
7337         (plus:SI (match_operand:SI 1 "register_operand" "r")
7338                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
7339                             UNSPEC_TLSLDM)))]
7340   "TARGET_TLS && TARGET_ARCH32"
7341   "add\\t%1, %2, %0, %%tldm_add(%&)")
7343 (define_insn "tldm_add64"
7344   [(set (match_operand:DI 0 "register_operand" "=r")
7345         (plus:DI (match_operand:DI 1 "register_operand" "r")
7346                  (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
7347                             UNSPEC_TLSLDM)))]
7348   "TARGET_TLS && TARGET_ARCH64"
7349   "add\\t%1, %2, %0, %%tldm_add(%&)")
7351 (define_insn "tldm_call32"
7352   [(set (match_operand 0 "register_operand" "=r")
7353         (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
7354                                  UNSPEC_TLSLDM))
7355               (match_operand 2 "" "")))
7356    (clobber (reg:SI O7_REG))]
7357   "TARGET_TLS && TARGET_ARCH32"
7358   "call\t%a1, %%tldm_call(%&)%#"
7359   [(set_attr "type" "call")])
7361 (define_insn "tldm_call64"
7362   [(set (match_operand 0 "register_operand" "=r")
7363         (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
7364                                  UNSPEC_TLSLDM))
7365               (match_operand 2 "" "")))
7366    (clobber (reg:DI O7_REG))]
7367   "TARGET_TLS && TARGET_ARCH64"
7368   "call\t%a1, %%tldm_call(%&)%#"
7369   [(set_attr "type" "call")])
7371 (define_insn "tldo_hix22"
7372   [(set (match_operand:SI 0 "register_operand" "=r")
7373         (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
7374                             UNSPEC_TLSLDO)))]
7375   "TARGET_TLS"
7376   "sethi\\t%%tldo_hix22(%a1), %0")
7378 (define_insn "tldo_lox10"
7379   [(set (match_operand:SI 0 "register_operand" "=r")
7380         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7381                    (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
7382                               UNSPEC_TLSLDO)))]
7383   "TARGET_TLS"
7384   "xor\\t%1, %%tldo_lox10(%a2), %0")
7386 (define_insn "tldo_add32"
7387   [(set (match_operand:SI 0 "register_operand" "=r")
7388         (plus:SI (match_operand:SI 1 "register_operand" "r")
7389                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7390                              (match_operand 3 "tld_symbolic_operand" "")]
7391                             UNSPEC_TLSLDO)))]
7392   "TARGET_TLS && TARGET_ARCH32"
7393   "add\\t%1, %2, %0, %%tldo_add(%a3)")
7395 (define_insn "tldo_add64"
7396   [(set (match_operand:DI 0 "register_operand" "=r")
7397         (plus:DI (match_operand:DI 1 "register_operand" "r")
7398                  (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7399                              (match_operand 3 "tld_symbolic_operand" "")]
7400                             UNSPEC_TLSLDO)))]
7401   "TARGET_TLS && TARGET_ARCH64"
7402   "add\\t%1, %2, %0, %%tldo_add(%a3)")
7404 (define_insn "tie_hi22"
7405   [(set (match_operand:SI 0 "register_operand" "=r")
7406         (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
7407                             UNSPEC_TLSIE)))]
7408   "TARGET_TLS"
7409   "sethi\\t%%tie_hi22(%a1), %0")
7411 (define_insn "tie_lo10"
7412   [(set (match_operand:SI 0 "register_operand" "=r")
7413         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7414                    (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
7415                               UNSPEC_TLSIE)))]
7416   "TARGET_TLS"
7417   "add\\t%1, %%tie_lo10(%a2), %0")
7419 (define_insn "tie_ld32"
7420   [(set (match_operand:SI 0 "register_operand" "=r")
7421         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
7422                     (match_operand:SI 2 "register_operand" "r")
7423                     (match_operand 3 "tie_symbolic_operand" "")]
7424                    UNSPEC_TLSIE))]
7425   "TARGET_TLS && TARGET_ARCH32"
7426   "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
7427   [(set_attr "type" "load")])
7429 (define_insn "tie_ld64"
7430   [(set (match_operand:DI 0 "register_operand" "=r")
7431         (unspec:DI [(match_operand:DI 1 "register_operand" "r")
7432                     (match_operand:SI 2 "register_operand" "r")
7433                     (match_operand 3 "tie_symbolic_operand" "")]
7434                    UNSPEC_TLSIE))]
7435   "TARGET_TLS && TARGET_ARCH64"
7436   "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
7437   [(set_attr "type" "load")])
7439 (define_insn "tie_add32"
7440   [(set (match_operand:SI 0 "register_operand" "=r")
7441         (plus:SI (match_operand:SI 1 "register_operand" "r")
7442                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7443                              (match_operand 3 "tie_symbolic_operand" "")]
7444                             UNSPEC_TLSIE)))]
7445   "TARGET_SUN_TLS && TARGET_ARCH32"
7446   "add\\t%1, %2, %0, %%tie_add(%a3)")
7448 (define_insn "tie_add64"
7449   [(set (match_operand:DI 0 "register_operand" "=r")
7450         (plus:DI (match_operand:DI 1 "register_operand" "r")
7451                  (unspec:DI [(match_operand:DI 2 "register_operand" "r")
7452                              (match_operand 3 "tie_symbolic_operand" "")]
7453                             UNSPEC_TLSIE)))]
7454   "TARGET_SUN_TLS && TARGET_ARCH64"
7455   "add\\t%1, %2, %0, %%tie_add(%a3)")
7457 (define_insn "tle_hix22_sp32"
7458   [(set (match_operand:SI 0 "register_operand" "=r")
7459         (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
7460                             UNSPEC_TLSLE)))]
7461   "TARGET_TLS && TARGET_ARCH32"
7462   "sethi\\t%%tle_hix22(%a1), %0")
7464 (define_insn "tle_lox10_sp32"
7465   [(set (match_operand:SI 0 "register_operand" "=r")
7466         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7467                    (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
7468                               UNSPEC_TLSLE)))]
7469   "TARGET_TLS && TARGET_ARCH32"
7470   "xor\\t%1, %%tle_lox10(%a2), %0")
7472 (define_insn "tle_hix22_sp64"
7473   [(set (match_operand:DI 0 "register_operand" "=r")
7474         (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
7475                             UNSPEC_TLSLE)))]
7476   "TARGET_TLS && TARGET_ARCH64"
7477   "sethi\\t%%tle_hix22(%a1), %0")
7479 (define_insn "tle_lox10_sp64"
7480   [(set (match_operand:DI 0 "register_operand" "=r")
7481         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
7482                    (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
7483                               UNSPEC_TLSLE)))]
7484   "TARGET_TLS && TARGET_ARCH64"
7485   "xor\\t%1, %%tle_lox10(%a2), %0")
7487 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
7488 (define_insn "*tldo_ldub_sp32"
7489   [(set (match_operand:QI 0 "register_operand" "=r")
7490         (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7491                                      (match_operand 3 "tld_symbolic_operand" "")]
7492                                     UNSPEC_TLSLDO)
7493                          (match_operand:SI 1 "register_operand" "r"))))]
7494   "TARGET_TLS && TARGET_ARCH32"
7495   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7496   [(set_attr "type" "load")
7497    (set_attr "us3load_type" "3cycle")])
7499 (define_insn "*tldo_ldub1_sp32"
7500   [(set (match_operand:HI 0 "register_operand" "=r")
7501         (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7502                                                      (match_operand 3 "tld_symbolic_operand" "")]
7503                                                     UNSPEC_TLSLDO)
7504                                          (match_operand:SI 1 "register_operand" "r")))))]
7505   "TARGET_TLS && TARGET_ARCH32"
7506   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7507   [(set_attr "type" "load")
7508    (set_attr "us3load_type" "3cycle")])
7510 (define_insn "*tldo_ldub2_sp32"
7511   [(set (match_operand:SI 0 "register_operand" "=r")
7512         (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7513                                                      (match_operand 3 "tld_symbolic_operand" "")]
7514                                                     UNSPEC_TLSLDO)
7515                                          (match_operand:SI 1 "register_operand" "r")))))]
7516   "TARGET_TLS && TARGET_ARCH32"
7517   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7518   [(set_attr "type" "load")
7519    (set_attr "us3load_type" "3cycle")])
7521 (define_insn "*tldo_ldsb1_sp32"
7522   [(set (match_operand:HI 0 "register_operand" "=r")
7523         (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7524                                                      (match_operand 3 "tld_symbolic_operand" "")]
7525                                                     UNSPEC_TLSLDO)
7526                                          (match_operand:SI 1 "register_operand" "r")))))]
7527   "TARGET_TLS && TARGET_ARCH32"
7528   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7529   [(set_attr "type" "sload")
7530    (set_attr "us3load_type" "3cycle")])
7532 (define_insn "*tldo_ldsb2_sp32"
7533   [(set (match_operand:SI 0 "register_operand" "=r")
7534         (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7535                                                      (match_operand 3 "tld_symbolic_operand" "")]
7536                                                     UNSPEC_TLSLDO)
7537                                          (match_operand:SI 1 "register_operand" "r")))))]
7538   "TARGET_TLS && TARGET_ARCH32"
7539   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7540   [(set_attr "type" "sload")
7541    (set_attr "us3load_type" "3cycle")])
7543 (define_insn "*tldo_ldub_sp64"
7544   [(set (match_operand:QI 0 "register_operand" "=r")
7545         (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7546                                      (match_operand 3 "tld_symbolic_operand" "")]
7547                                     UNSPEC_TLSLDO)
7548                          (match_operand:DI 1 "register_operand" "r"))))]
7549   "TARGET_TLS && TARGET_ARCH64"
7550   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7551   [(set_attr "type" "load")
7552    (set_attr "us3load_type" "3cycle")])
7554 (define_insn "*tldo_ldub1_sp64"
7555   [(set (match_operand:HI 0 "register_operand" "=r")
7556         (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7557                                                      (match_operand 3 "tld_symbolic_operand" "")]
7558                                                     UNSPEC_TLSLDO)
7559                                          (match_operand:DI 1 "register_operand" "r")))))]
7560   "TARGET_TLS && TARGET_ARCH64"
7561   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7562   [(set_attr "type" "load")
7563    (set_attr "us3load_type" "3cycle")])
7565 (define_insn "*tldo_ldub2_sp64"
7566   [(set (match_operand:SI 0 "register_operand" "=r")
7567         (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7568                                                      (match_operand 3 "tld_symbolic_operand" "")]
7569                                                     UNSPEC_TLSLDO)
7570                                          (match_operand:DI 1 "register_operand" "r")))))]
7571   "TARGET_TLS && TARGET_ARCH64"
7572   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7573   [(set_attr "type" "load")
7574    (set_attr "us3load_type" "3cycle")])
7576 (define_insn "*tldo_ldub3_sp64"
7577   [(set (match_operand:DI 0 "register_operand" "=r")
7578         (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7579                                                      (match_operand 3 "tld_symbolic_operand" "")]
7580                                                     UNSPEC_TLSLDO)
7581                                          (match_operand:DI 1 "register_operand" "r")))))]
7582   "TARGET_TLS && TARGET_ARCH64"
7583   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7584   [(set_attr "type" "load")
7585    (set_attr "us3load_type" "3cycle")])
7587 (define_insn "*tldo_ldsb1_sp64"
7588   [(set (match_operand:HI 0 "register_operand" "=r")
7589         (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7590                                                      (match_operand 3 "tld_symbolic_operand" "")]
7591                                                     UNSPEC_TLSLDO)
7592                                          (match_operand:DI 1 "register_operand" "r")))))]
7593   "TARGET_TLS && TARGET_ARCH64"
7594   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7595   [(set_attr "type" "sload")
7596    (set_attr "us3load_type" "3cycle")])
7598 (define_insn "*tldo_ldsb2_sp64"
7599   [(set (match_operand:SI 0 "register_operand" "=r")
7600         (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7601                                                      (match_operand 3 "tld_symbolic_operand" "")]
7602                                                     UNSPEC_TLSLDO)
7603                                          (match_operand:DI 1 "register_operand" "r")))))]
7604   "TARGET_TLS && TARGET_ARCH64"
7605   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7606   [(set_attr "type" "sload")
7607    (set_attr "us3load_type" "3cycle")])
7609 (define_insn "*tldo_ldsb3_sp64"
7610   [(set (match_operand:DI 0 "register_operand" "=r")
7611         (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7612                                                      (match_operand 3 "tld_symbolic_operand" "")]
7613                                                     UNSPEC_TLSLDO)
7614                                          (match_operand:DI 1 "register_operand" "r")))))]
7615   "TARGET_TLS && TARGET_ARCH64"
7616   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7617   [(set_attr "type" "sload")
7618    (set_attr "us3load_type" "3cycle")])
7620 (define_insn "*tldo_lduh_sp32"
7621   [(set (match_operand:HI 0 "register_operand" "=r")
7622         (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7623                                      (match_operand 3 "tld_symbolic_operand" "")]
7624                                     UNSPEC_TLSLDO)
7625                          (match_operand:SI 1 "register_operand" "r"))))]
7626   "TARGET_TLS && TARGET_ARCH32"
7627   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7628   [(set_attr "type" "load")
7629    (set_attr "us3load_type" "3cycle")])
7631 (define_insn "*tldo_lduh1_sp32"
7632   [(set (match_operand:SI 0 "register_operand" "=r")
7633         (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7634                                                      (match_operand 3 "tld_symbolic_operand" "")]
7635                                                     UNSPEC_TLSLDO)
7636                                          (match_operand:SI 1 "register_operand" "r")))))]
7637   "TARGET_TLS && TARGET_ARCH32"
7638   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7639   [(set_attr "type" "load")
7640    (set_attr "us3load_type" "3cycle")])
7642 (define_insn "*tldo_ldsh1_sp32"
7643   [(set (match_operand:SI 0 "register_operand" "=r")
7644         (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7645                                                      (match_operand 3 "tld_symbolic_operand" "")]
7646                                                     UNSPEC_TLSLDO)
7647                                          (match_operand:SI 1 "register_operand" "r")))))]
7648   "TARGET_TLS && TARGET_ARCH32"
7649   "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7650   [(set_attr "type" "sload")
7651    (set_attr "us3load_type" "3cycle")])
7653 (define_insn "*tldo_lduh_sp64"
7654   [(set (match_operand:HI 0 "register_operand" "=r")
7655         (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7656                                      (match_operand 3 "tld_symbolic_operand" "")]
7657                                     UNSPEC_TLSLDO)
7658                          (match_operand:DI 1 "register_operand" "r"))))]
7659   "TARGET_TLS && TARGET_ARCH64"
7660   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7661   [(set_attr "type" "load")
7662    (set_attr "us3load_type" "3cycle")])
7664 (define_insn "*tldo_lduh1_sp64"
7665   [(set (match_operand:SI 0 "register_operand" "=r")
7666         (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7667                                                      (match_operand 3 "tld_symbolic_operand" "")]
7668                                                     UNSPEC_TLSLDO)
7669                                          (match_operand:DI 1 "register_operand" "r")))))]
7670   "TARGET_TLS && TARGET_ARCH64"
7671   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7672   [(set_attr "type" "load")
7673    (set_attr "us3load_type" "3cycle")])
7675 (define_insn "*tldo_lduh2_sp64"
7676   [(set (match_operand:DI 0 "register_operand" "=r")
7677         (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7678                                                      (match_operand 3 "tld_symbolic_operand" "")]
7679                                                     UNSPEC_TLSLDO)
7680                                          (match_operand:DI 1 "register_operand" "r")))))]
7681   "TARGET_TLS && TARGET_ARCH64"
7682   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7683   [(set_attr "type" "load")
7684    (set_attr "us3load_type" "3cycle")])
7686 (define_insn "*tldo_ldsh1_sp64"
7687   [(set (match_operand:SI 0 "register_operand" "=r")
7688         (sign_extend:SI (mem:HI (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   "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7694   [(set_attr "type" "sload")
7695    (set_attr "us3load_type" "3cycle")])
7697 (define_insn "*tldo_ldsh2_sp64"
7698   [(set (match_operand:DI 0 "register_operand" "=r")
7699         (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7700                                                      (match_operand 3 "tld_symbolic_operand" "")]
7701                                                     UNSPEC_TLSLDO)
7702                                          (match_operand:DI 1 "register_operand" "r")))))]
7703   "TARGET_TLS && TARGET_ARCH64"
7704   "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7705   [(set_attr "type" "sload")
7706    (set_attr "us3load_type" "3cycle")])
7708 (define_insn "*tldo_lduw_sp32"
7709   [(set (match_operand:SI 0 "register_operand" "=r")
7710         (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7711                                      (match_operand 3 "tld_symbolic_operand" "")]
7712                                     UNSPEC_TLSLDO)
7713                          (match_operand:SI 1 "register_operand" "r"))))]
7714   "TARGET_TLS && TARGET_ARCH32"
7715   "ld\t[%1 + %2], %0, %%tldo_add(%3)"
7716   [(set_attr "type" "load")])
7718 (define_insn "*tldo_lduw_sp64"
7719   [(set (match_operand:SI 0 "register_operand" "=r")
7720         (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7721                                      (match_operand 3 "tld_symbolic_operand" "")]
7722                                     UNSPEC_TLSLDO)
7723                          (match_operand:DI 1 "register_operand" "r"))))]
7724   "TARGET_TLS && TARGET_ARCH64"
7725   "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7726   [(set_attr "type" "load")])
7728 (define_insn "*tldo_lduw1_sp64"
7729   [(set (match_operand:DI 0 "register_operand" "=r")
7730         (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7731                                                      (match_operand 3 "tld_symbolic_operand" "")]
7732                                                     UNSPEC_TLSLDO)
7733                                          (match_operand:DI 1 "register_operand" "r")))))]
7734   "TARGET_TLS && TARGET_ARCH64"
7735   "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7736   [(set_attr "type" "load")])
7738 (define_insn "*tldo_ldsw1_sp64"
7739   [(set (match_operand:DI 0 "register_operand" "=r")
7740         (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7741                                                      (match_operand 3 "tld_symbolic_operand" "")]
7742                                                     UNSPEC_TLSLDO)
7743                                          (match_operand:DI 1 "register_operand" "r")))))]
7744   "TARGET_TLS && TARGET_ARCH64"
7745   "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
7746   [(set_attr "type" "sload")
7747    (set_attr "us3load_type" "3cycle")])
7749 (define_insn "*tldo_ldx_sp64"
7750   [(set (match_operand:DI 0 "register_operand" "=r")
7751         (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7752                                      (match_operand 3 "tld_symbolic_operand" "")]
7753                                     UNSPEC_TLSLDO)
7754                          (match_operand:DI 1 "register_operand" "r"))))]
7755   "TARGET_TLS && TARGET_ARCH64"
7756   "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
7757   [(set_attr "type" "load")])
7759 (define_insn "*tldo_stb_sp32"
7760   [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7761                                      (match_operand 3 "tld_symbolic_operand" "")]
7762                                     UNSPEC_TLSLDO)
7763                          (match_operand:SI 1 "register_operand" "r")))
7764         (match_operand:QI 0 "register_operand" "r"))]
7765   "TARGET_TLS && TARGET_ARCH32"
7766   "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7767   [(set_attr "type" "store")])
7769 (define_insn "*tldo_stb_sp64"
7770   [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7771                                      (match_operand 3 "tld_symbolic_operand" "")]
7772                                     UNSPEC_TLSLDO)
7773                          (match_operand:DI 1 "register_operand" "r")))
7774         (match_operand:QI 0 "register_operand" "r"))]
7775   "TARGET_TLS && TARGET_ARCH64"
7776   "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7777   [(set_attr "type" "store")])
7779 (define_insn "*tldo_sth_sp32"
7780   [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7781                                      (match_operand 3 "tld_symbolic_operand" "")]
7782                                     UNSPEC_TLSLDO)
7783                          (match_operand:SI 1 "register_operand" "r")))
7784         (match_operand:HI 0 "register_operand" "r"))]
7785   "TARGET_TLS && TARGET_ARCH32"
7786   "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7787   [(set_attr "type" "store")])
7789 (define_insn "*tldo_sth_sp64"
7790   [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7791                                      (match_operand 3 "tld_symbolic_operand" "")]
7792                                     UNSPEC_TLSLDO)
7793                          (match_operand:DI 1 "register_operand" "r")))
7794         (match_operand:HI 0 "register_operand" "r"))]
7795   "TARGET_TLS && TARGET_ARCH64"
7796   "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7797   [(set_attr "type" "store")])
7799 (define_insn "*tldo_stw_sp32"
7800   [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7801                                      (match_operand 3 "tld_symbolic_operand" "")]
7802                                     UNSPEC_TLSLDO)
7803                          (match_operand:SI 1 "register_operand" "r")))
7804         (match_operand:SI 0 "register_operand" "r"))]
7805   "TARGET_TLS && TARGET_ARCH32"
7806   "st\t%0, [%1 + %2], %%tldo_add(%3)"
7807   [(set_attr "type" "store")])
7809 (define_insn "*tldo_stw_sp64"
7810   [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7811                                      (match_operand 3 "tld_symbolic_operand" "")]
7812                                     UNSPEC_TLSLDO)
7813                          (match_operand:DI 1 "register_operand" "r")))
7814         (match_operand:SI 0 "register_operand" "r"))]
7815   "TARGET_TLS && TARGET_ARCH64"
7816   "stw\t%0, [%1 + %2], %%tldo_add(%3)"
7817   [(set_attr "type" "store")])
7819 (define_insn "*tldo_stx_sp64"
7820   [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7821                                      (match_operand 3 "tld_symbolic_operand" "")]
7822                                     UNSPEC_TLSLDO)
7823                          (match_operand:DI 1 "register_operand" "r")))
7824         (match_operand:DI 0 "register_operand" "r"))]
7825   "TARGET_TLS && TARGET_ARCH64"
7826   "stx\t%0, [%1 + %2], %%tldo_add(%3)"
7827   [(set_attr "type" "store")])
7830 ;; Stack protector instructions.
7832 (define_expand "stack_protect_set"
7833   [(match_operand 0 "memory_operand" "")
7834    (match_operand 1 "memory_operand" "")]
7835   ""
7837 #ifdef TARGET_THREAD_SSP_OFFSET
7838   rtx tlsreg = gen_rtx_REG (Pmode, 7);
7839   rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7840   operands[1] = gen_rtx_MEM (Pmode, addr);
7841 #endif
7842   if (TARGET_ARCH64)
7843     emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
7844   else
7845     emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
7846   DONE;
7849 (define_insn "stack_protect_setsi"
7850   [(set (match_operand:SI 0 "memory_operand" "=m")
7851         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7852    (set (match_scratch:SI 2 "=&r") (const_int 0))]
7853   "TARGET_ARCH32"
7854   "ld\t%1, %2\;st\t%2, %0\;mov\t0, %2"
7855   [(set_attr "type" "multi")
7856    (set_attr "length" "3")])
7858 (define_insn "stack_protect_setdi"
7859   [(set (match_operand:DI 0 "memory_operand" "=m")
7860         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7861    (set (match_scratch:DI 2 "=&r") (const_int 0))]
7862   "TARGET_ARCH64"
7863   "ldx\t%1, %2\;stx\t%2, %0\;mov\t0, %2"
7864   [(set_attr "type" "multi")
7865    (set_attr "length" "3")])
7867 (define_expand "stack_protect_test"
7868   [(match_operand 0 "memory_operand" "")
7869    (match_operand 1 "memory_operand" "")
7870    (match_operand 2 "" "")]
7871   ""
7873   rtx result, test;
7874 #ifdef TARGET_THREAD_SSP_OFFSET
7875   rtx tlsreg = gen_rtx_REG (Pmode, 7);
7876   rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7877   operands[1] = gen_rtx_MEM (Pmode, addr);
7878 #endif
7879   if (TARGET_ARCH64)
7880     {
7881       result = gen_reg_rtx (Pmode);
7882       emit_insn (gen_stack_protect_testdi (result, operands[0], operands[1]));
7883       test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7884       emit_jump_insn (gen_cbranchdi4 (test, result, const0_rtx, operands[2]));
7885     }
7886   else
7887     {
7888       emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
7889       result = gen_rtx_REG (CCmode, SPARC_ICC_REG);
7890       test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7891       emit_jump_insn (gen_cbranchcc4 (test, result, const0_rtx, operands[2]));
7892     }
7893   DONE;
7896 (define_insn "stack_protect_testsi"
7897   [(set (reg:CC CC_REG)
7898         (unspec:CC [(match_operand:SI 0 "memory_operand" "m")
7899                     (match_operand:SI 1 "memory_operand" "m")]
7900                    UNSPEC_SP_TEST))
7901    (set (match_scratch:SI 3 "=r") (const_int 0))
7902    (clobber (match_scratch:SI 2 "=&r"))]
7903   "TARGET_ARCH32"
7904   "ld\t%0, %2\;ld\t%1, %3\;xorcc\t%2, %3, %2\;mov\t0, %3"
7905   [(set_attr "type" "multi")
7906    (set_attr "length" "4")])
7908 (define_insn "stack_protect_testdi"
7909   [(set (match_operand:DI 0 "register_operand" "=&r")
7910         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
7911                     (match_operand:DI 2 "memory_operand" "m")]
7912                    UNSPEC_SP_TEST))
7913    (set (match_scratch:DI 3 "=r") (const_int 0))]
7914   "TARGET_ARCH64"
7915   "ldx\t%1, %0\;ldx\t%2, %3\;xor\t%0, %3, %0\;mov\t0, %3"
7916   [(set_attr "type" "multi")
7917    (set_attr "length" "4")])
7919 ;; Vector instructions.
7921 (define_mode_iterator VM32 [V1SI V2HI V4QI])
7922 (define_mode_iterator VM64 [V1DI V2SI V4HI V8QI])
7923 (define_mode_iterator VMALL [V1SI V2HI V4QI V1DI V2SI V4HI V8QI])
7925 (define_mode_attr vbits [(V2SI "32") (V4HI "16") (V1SI "32s") (V2HI "16s")])
7926 (define_mode_attr vconstr [(V1SI "f") (V2HI "f") (V4QI "f")
7927                            (V1DI "e") (V2SI "e") (V4HI "e") (V8QI "e")])
7928 (define_mode_attr vfptype [(V1SI "single") (V2HI "single") (V4QI "single")
7929                            (V1DI "double") (V2SI "double") (V4HI "double")
7930                            (V8QI "double")])
7932 (define_expand "mov<VMALL:mode>"
7933   [(set (match_operand:VMALL 0 "nonimmediate_operand" "")
7934         (match_operand:VMALL 1 "general_operand" ""))]
7935   "TARGET_VIS"
7937   if (sparc_expand_move (<VMALL:MODE>mode, operands))
7938     DONE;
7941 (define_insn "*mov<VM32:mode>_insn"
7942   [(set (match_operand:VM32 0 "nonimmediate_operand" "=f,f,f,f,m,m,*r, m,*r,*r, f")
7943         (match_operand:VM32 1 "input_operand"         "Y,Z,f,m,f,Y, m,*r,*r, f,*r"))]
7944   "TARGET_VIS
7945    && (register_operand (operands[0], <VM32:MODE>mode)
7946        || register_or_zero_or_all_ones_operand (operands[1], <VM32:MODE>mode))"
7947   "@
7948   fzeros\t%0
7949   fones\t%0
7950   fsrc2s\t%1, %0
7951   ld\t%1, %0
7952   st\t%1, %0
7953   st\t%r1, %0
7954   ld\t%1, %0
7955   st\t%1, %0
7956   mov\t%1, %0
7957   movstouw\t%1, %0
7958   movwtos\t%1, %0"
7959   [(set_attr "type" "visl,visl,vismv,fpload,fpstore,store,load,store,*,vismv,vismv")
7960    (set_attr "cpu_feature" "vis,vis,vis,*,*,*,*,*,*,vis3,vis3")])
7962 (define_insn "*mov<VM64:mode>_insn_sp64"
7963   [(set (match_operand:VM64 0 "nonimmediate_operand" "=e,e,e,e,m,m,*r, m,*r, e,*r")
7964         (match_operand:VM64 1 "input_operand"         "Y,C,e,m,e,Y, m,*r, e,*r,*r"))]
7965   "TARGET_VIS
7966    && TARGET_ARCH64
7967    && (register_operand (operands[0], <VM64:MODE>mode)
7968        || register_or_zero_or_all_ones_operand (operands[1], <VM64:MODE>mode))"
7969   "@
7970   fzero\t%0
7971   fone\t%0
7972   fsrc2\t%1, %0
7973   ldd\t%1, %0
7974   std\t%1, %0
7975   stx\t%r1, %0
7976   ldx\t%1, %0
7977   stx\t%1, %0
7978   movdtox\t%1, %0
7979   movxtod\t%1, %0
7980   mov\t%1, %0"
7981   [(set_attr "type" "visl,visl,vismv,fpload,fpstore,store,load,store,vismv,vismv,*")
7982    (set_attr "cpu_feature" "vis,vis,vis,*,*,*,*,*,vis3,vis3,*")])
7984 (define_insn "*mov<VM64:mode>_insn_sp32"
7985   [(set (match_operand:VM64 0 "nonimmediate_operand" "=e,e,e,*r, f,e,m,m,U,T, o,*r")
7986         (match_operand:VM64 1 "input_operand"         "Y,C,e, f,*r,m,e,Y,T,U,*r,*r"))]
7987   "TARGET_VIS
7988    && ! TARGET_ARCH64
7989    && (register_operand (operands[0], <VM64:MODE>mode)
7990        || register_or_zero_or_all_ones_operand (operands[1], <VM64:MODE>mode))"
7991   "@
7992   fzero\t%0
7993   fone\t%0
7994   fsrc2\t%1, %0
7995   #
7996   #
7997   ldd\t%1, %0
7998   std\t%1, %0
7999   stx\t%r1, %0
8000   ldd\t%1, %0
8001   std\t%1, %0
8002   #
8003   #"
8004   [(set_attr "type" "visl,visl,vismv,*,*,fpload,fpstore,store,load,store,*,*")
8005    (set_attr "length" "*,*,*,2,2,*,*,*,*,*,2,2")
8006    (set_attr "cpu_feature" "vis,vis,vis,vis3,vis3,*,*,*,*,*,*,*")])
8008 (define_split
8009   [(set (match_operand:VM64 0 "memory_operand" "")
8010         (match_operand:VM64 1 "register_operand" ""))]
8011   "reload_completed
8012    && TARGET_VIS
8013    && ! TARGET_ARCH64
8014    && (((REGNO (operands[1]) % 2) != 0)
8015        || ! mem_min_alignment (operands[0], 8))
8016    && offsettable_memref_p (operands[0])"
8017   [(clobber (const_int 0))]
8019   rtx word0, word1;
8021   word0 = adjust_address (operands[0], SImode, 0);
8022   word1 = adjust_address (operands[0], SImode, 4);
8024   emit_move_insn_1 (word0, gen_highpart (SImode, operands[1]));
8025   emit_move_insn_1 (word1, gen_lowpart (SImode, operands[1]));
8026   DONE;
8029 (define_split
8030   [(set (match_operand:VM64 0 "register_operand" "")
8031         (match_operand:VM64 1 "register_operand" ""))]
8032   "reload_completed
8033    && TARGET_VIS
8034    && ! TARGET_ARCH64
8035    && sparc_split_regreg_legitimate (operands[0], operands[1])"
8036   [(clobber (const_int 0))]
8038   rtx set_dest = operands[0];
8039   rtx set_src = operands[1];
8040   rtx dest1, dest2;
8041   rtx src1, src2;
8043   dest1 = gen_highpart (SImode, set_dest);
8044   dest2 = gen_lowpart (SImode, set_dest);
8045   src1 = gen_highpart (SImode, set_src);
8046   src2 = gen_lowpart (SImode, set_src);
8048   /* Now emit using the real source and destination we found, swapping
8049      the order if we detect overlap.  */
8050   if (reg_overlap_mentioned_p (dest1, src2))
8051     {
8052       emit_insn (gen_movsi (dest2, src2));
8053       emit_insn (gen_movsi (dest1, src1));
8054     }
8055   else
8056     {
8057       emit_insn (gen_movsi (dest1, src1));
8058       emit_insn (gen_movsi (dest2, src2));
8059     }
8060   DONE;
8063 (define_expand "vec_init<mode>"
8064   [(match_operand:VMALL 0 "register_operand" "")
8065    (match_operand:VMALL 1 "" "")]
8066   "TARGET_VIS"
8068   sparc_expand_vector_init (operands[0], operands[1]);
8069   DONE;
8072 (define_code_iterator plusminus [plus minus])
8073 (define_code_attr plusminus_insn [(plus "add") (minus "sub")])
8075 (define_mode_iterator VADDSUB [V1SI V2SI V2HI V4HI])
8077 (define_insn "<plusminus_insn><mode>3"
8078   [(set (match_operand:VADDSUB 0 "register_operand" "=<vconstr>")
8079         (plusminus:VADDSUB (match_operand:VADDSUB 1 "register_operand" "<vconstr>")
8080                            (match_operand:VADDSUB 2 "register_operand" "<vconstr>")))]
8081   "TARGET_VIS"
8082   "fp<plusminus_insn><vbits>\t%1, %2, %0"
8083   [(set_attr "type" "fga")
8084    (set_attr "fptype" "<vfptype>")])
8086 (define_mode_iterator VL [V1SI V2HI V4QI V1DI V2SI V4HI V8QI])
8087 (define_mode_attr vlsuf [(V1SI "s") (V2HI "s") (V4QI "s")
8088                          (V1DI  "") (V2SI  "") (V4HI  "") (V8QI "")])
8089 (define_code_iterator vlop [ior and xor])
8090 (define_code_attr vlinsn [(ior "or") (and "and") (xor "xor")])
8091 (define_code_attr vlninsn [(ior "nor") (and "nand") (xor "xnor")])
8093 (define_insn "<code><mode>3"
8094   [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8095         (vlop:VL (match_operand:VL 1 "register_operand" "<vconstr>")
8096                  (match_operand:VL 2 "register_operand" "<vconstr>")))]
8097   "TARGET_VIS"
8098   "f<vlinsn><vlsuf>\t%1, %2, %0"
8099   [(set_attr "type" "visl")
8100    (set_attr "fptype" "<vfptype>")])
8102 (define_insn "*not_<code><mode>3"
8103   [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8104         (not:VL (vlop:VL (match_operand:VL 1 "register_operand" "<vconstr>")
8105                          (match_operand:VL 2 "register_operand" "<vconstr>"))))]
8106   "TARGET_VIS"
8107   "f<vlninsn><vlsuf>\t%1, %2, %0"
8108   [(set_attr "type" "visl")
8109    (set_attr "fptype" "<vfptype>")])
8111 ;; (ior (not (op1)) (not (op2))) is the canonical form of NAND.
8112 (define_insn "*nand<mode>_vis"
8113   [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8114         (ior:VL (not:VL (match_operand:VL 1 "register_operand" "<vconstr>"))
8115                 (not:VL (match_operand:VL 2 "register_operand" "<vconstr>"))))]
8116   "TARGET_VIS"
8117   "fnand<vlsuf>\t%1, %2, %0"
8118   [(set_attr "type" "visl")
8119    (set_attr "fptype" "<vfptype>")])
8121 (define_code_iterator vlnotop [ior and])
8123 (define_insn "*<code>_not1<mode>_vis"
8124   [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8125         (vlnotop:VL (not:VL (match_operand:VL 1 "register_operand" "<vconstr>"))
8126                     (match_operand:VL 2 "register_operand" "<vconstr>")))]
8127   "TARGET_VIS"
8128   "f<vlinsn>not1<vlsuf>\t%1, %2, %0"
8129   [(set_attr "type" "visl")
8130    (set_attr "fptype" "<vfptype>")])
8132 (define_insn "*<code>_not2<mode>_vis"
8133   [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8134         (vlnotop:VL (match_operand:VL 1 "register_operand" "<vconstr>")
8135                     (not:VL (match_operand:VL 2 "register_operand" "<vconstr>"))))]
8136   "TARGET_VIS"
8137   "f<vlinsn>not2<vlsuf>\t%1, %2, %0"
8138   [(set_attr "type" "visl")
8139    (set_attr "fptype" "<vfptype>")])
8141 (define_insn "one_cmpl<mode>2"
8142   [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8143         (not:VL (match_operand:VL 1 "register_operand" "<vconstr>")))]
8144   "TARGET_VIS"
8145   "fnot1<vlsuf>\t%1, %0"
8146   [(set_attr "type" "visl")
8147    (set_attr "fptype" "<vfptype>")])
8149 ;; Hard to generate VIS instructions.  We have builtins for these.
8151 (define_insn "fpack16_vis"
8152   [(set (match_operand:V4QI 0 "register_operand" "=f")
8153         (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e")
8154                       (reg:DI GSR_REG)]
8155                       UNSPEC_FPACK16))]
8156   "TARGET_VIS"
8157   "fpack16\t%1, %0"
8158   [(set_attr "type" "fgm_pack")
8159    (set_attr "fptype" "double")])
8161 (define_insn "fpackfix_vis"
8162   [(set (match_operand:V2HI 0 "register_operand" "=f")
8163         (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e")
8164                       (reg:DI GSR_REG)]
8165                       UNSPEC_FPACKFIX))]
8166   "TARGET_VIS"
8167   "fpackfix\t%1, %0"
8168   [(set_attr "type" "fgm_pack")
8169    (set_attr "fptype" "double")])
8171 (define_insn "fpack32_vis"
8172   [(set (match_operand:V8QI 0 "register_operand" "=e")
8173         (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e")
8174                       (match_operand:V8QI 2 "register_operand" "e")
8175                       (reg:DI GSR_REG)]
8176                      UNSPEC_FPACK32))]
8177   "TARGET_VIS"
8178   "fpack32\t%1, %2, %0"
8179   [(set_attr "type" "fgm_pack")
8180    (set_attr "fptype" "double")])
8182 (define_insn "fexpand_vis"
8183   [(set (match_operand:V4HI 0 "register_operand" "=e")
8184         (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")]
8185          UNSPEC_FEXPAND))]
8186  "TARGET_VIS"
8187  "fexpand\t%1, %0"
8188  [(set_attr "type" "fga")
8189   (set_attr "fptype" "double")])
8191 (define_insn "fpmerge_vis"
8192   [(set (match_operand:V8QI 0 "register_operand" "=e")
8193         (vec_select:V8QI
8194           (vec_concat:V8QI (match_operand:V4QI 1 "register_operand" "f")
8195                            (match_operand:V4QI 2 "register_operand" "f"))
8196           (parallel [(const_int 0) (const_int 4)
8197                      (const_int 1) (const_int 5)
8198                      (const_int 2) (const_int 6)
8199                      (const_int 3) (const_int 7)])))]
8200  "TARGET_VIS"
8201  "fpmerge\t%1, %2, %0"
8202  [(set_attr "type" "fga")
8203   (set_attr "fptype" "double")])
8205 (define_insn "vec_interleave_lowv8qi"
8206   [(set (match_operand:V8QI 0 "register_operand" "=e")
8207         (vec_select:V8QI
8208           (vec_concat:V16QI (match_operand:V8QI 1 "register_operand" "f")
8209                             (match_operand:V8QI 2 "register_operand" "f"))
8210           (parallel [(const_int 0) (const_int 8)
8211                      (const_int 1) (const_int 9)
8212                      (const_int 2) (const_int 10)
8213                      (const_int 3) (const_int 11)])))]
8214  "TARGET_VIS"
8215  "fpmerge\t%L1, %L2, %0"
8216  [(set_attr "type" "fga")
8217   (set_attr "fptype" "double")])
8219 (define_insn "vec_interleave_highv8qi"
8220   [(set (match_operand:V8QI 0 "register_operand" "=e")
8221         (vec_select:V8QI
8222           (vec_concat:V16QI (match_operand:V8QI 1 "register_operand" "f")
8223                             (match_operand:V8QI 2 "register_operand" "f"))
8224           (parallel [(const_int 4) (const_int 12)
8225                      (const_int 5) (const_int 13)
8226                      (const_int 6) (const_int 14)
8227                      (const_int 7) (const_int 15)])))]
8228  "TARGET_VIS"
8229  "fpmerge\t%H1, %H2, %0"
8230  [(set_attr "type" "fga")
8231   (set_attr "fptype" "double")])
8233 ;; Partitioned multiply instructions
8234 (define_insn "fmul8x16_vis"
8235   [(set (match_operand:V4HI 0 "register_operand" "=e")
8236         (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8237                       (match_operand:V4HI 2 "register_operand" "e")]
8238          UNSPEC_MUL8))]
8239   "TARGET_VIS"
8240   "fmul8x16\t%1, %2, %0"
8241   [(set_attr "type" "fgm_mul")
8242    (set_attr "fptype" "double")])
8244 (define_insn "fmul8x16au_vis"
8245   [(set (match_operand:V4HI 0 "register_operand" "=e")
8246         (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8247                       (match_operand:V2HI 2 "register_operand" "f")]
8248          UNSPEC_MUL16AU))]
8249   "TARGET_VIS"
8250   "fmul8x16au\t%1, %2, %0"
8251   [(set_attr "type" "fgm_mul")
8252    (set_attr "fptype" "double")])
8254 (define_insn "fmul8x16al_vis"
8255   [(set (match_operand:V4HI 0 "register_operand" "=e")
8256         (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8257                       (match_operand:V2HI 2 "register_operand" "f")]
8258          UNSPEC_MUL16AL))]
8259   "TARGET_VIS"
8260   "fmul8x16al\t%1, %2, %0"
8261   [(set_attr "type" "fgm_mul")
8262    (set_attr "fptype" "double")])
8264 (define_insn "fmul8sux16_vis"
8265   [(set (match_operand:V4HI 0 "register_operand" "=e")
8266         (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
8267                       (match_operand:V4HI 2 "register_operand" "e")]
8268          UNSPEC_MUL8SU))]
8269   "TARGET_VIS"
8270   "fmul8sux16\t%1, %2, %0"
8271   [(set_attr "type" "fgm_mul")
8272    (set_attr "fptype" "double")])
8274 (define_insn "fmul8ulx16_vis"
8275   [(set (match_operand:V4HI 0 "register_operand" "=e")
8276         (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
8277                       (match_operand:V4HI 2 "register_operand" "e")]
8278          UNSPEC_MUL8UL))]
8279   "TARGET_VIS"
8280   "fmul8ulx16\t%1, %2, %0"
8281   [(set_attr "type" "fgm_mul")
8282    (set_attr "fptype" "double")])
8284 (define_insn "fmuld8sux16_vis"
8285   [(set (match_operand:V2SI 0 "register_operand" "=e")
8286         (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
8287                       (match_operand:V2HI 2 "register_operand" "f")]
8288          UNSPEC_MULDSU))]
8289   "TARGET_VIS"
8290   "fmuld8sux16\t%1, %2, %0"
8291   [(set_attr "type" "fgm_mul")
8292    (set_attr "fptype" "double")])
8294 (define_insn "fmuld8ulx16_vis"
8295   [(set (match_operand:V2SI 0 "register_operand" "=e")
8296         (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
8297                       (match_operand:V2HI 2 "register_operand" "f")]
8298          UNSPEC_MULDUL))]
8299   "TARGET_VIS"
8300   "fmuld8ulx16\t%1, %2, %0"
8301   [(set_attr "type" "fgm_mul")
8302    (set_attr "fptype" "double")])
8304 (define_expand "wrgsr_vis"
8305   [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" ""))]
8306   "TARGET_VIS"
8308   if (! TARGET_ARCH64)
8309     {
8310       emit_insn (gen_wrgsr_v8plus (operands[0]));
8311       DONE;
8312     }
8315 (define_insn "*wrgsr_sp64"
8316   [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" "rI"))]
8317   "TARGET_VIS && TARGET_ARCH64"
8318   "wr\t%%g0, %0, %%gsr"
8319   [(set_attr "type" "gsr")])
8321 (define_insn "wrgsr_v8plus"
8322   [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" "I,r"))
8323    (clobber (match_scratch:SI 1 "=X,&h"))]
8324   "TARGET_VIS && ! TARGET_ARCH64"
8326   if (GET_CODE (operands[0]) == CONST_INT
8327       || sparc_check_64 (operands[0], insn))
8328     return "wr\t%%g0, %0, %%gsr";
8330   output_asm_insn("srl\t%L0, 0, %L0", operands);
8331   return "sllx\t%H0, 32, %1\n\tor\t%L0, %1, %1\n\twr\t%%g0, %1, %%gsr";
8333   [(set_attr "type" "multi")])
8335 (define_expand "rdgsr_vis"
8336   [(set (match_operand:DI 0 "register_operand" "") (reg:DI GSR_REG))]
8337   "TARGET_VIS"
8339   if (! TARGET_ARCH64)
8340     {
8341       emit_insn (gen_rdgsr_v8plus (operands[0]));
8342       DONE;
8343     }
8346 (define_insn "*rdgsr_sp64"
8347   [(set (match_operand:DI 0 "register_operand" "=r") (reg:DI GSR_REG))]
8348   "TARGET_VIS && TARGET_ARCH64"
8349   "rd\t%%gsr, %0"
8350   [(set_attr "type" "gsr")])
8352 (define_insn "rdgsr_v8plus"
8353   [(set (match_operand:DI 0 "register_operand" "=r") (reg:DI GSR_REG))
8354    (clobber (match_scratch:SI 1 "=&h"))]
8355   "TARGET_VIS && ! TARGET_ARCH64"
8357   return "rd\t%%gsr, %1\n\tsrlx\t%1, 32, %H0\n\tmov %1, %L0";
8359   [(set_attr "type" "multi")])
8361 ;; Using faligndata only makes sense after an alignaddr since the choice of
8362 ;; bytes to take out of each operand is dependent on the results of the last
8363 ;; alignaddr.
8364 (define_insn "faligndata<VM64:mode>_vis"
8365   [(set (match_operand:VM64 0 "register_operand" "=e")
8366         (unspec:VM64 [(match_operand:VM64 1 "register_operand" "e")
8367                       (match_operand:VM64 2 "register_operand" "e")
8368                       (reg:DI GSR_REG)]
8369          UNSPEC_ALIGNDATA))]
8370   "TARGET_VIS"
8371   "faligndata\t%1, %2, %0"
8372   [(set_attr "type" "fga")
8373    (set_attr "fptype" "double")])
8375 (define_insn "alignaddrsi_vis"
8376   [(set (match_operand:SI 0 "register_operand" "=r")
8377         (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
8378                  (match_operand:SI 2 "register_or_zero_operand" "rJ")))
8379    (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8380         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
8381   "TARGET_VIS"
8382   "alignaddr\t%r1, %r2, %0"
8383   [(set_attr "type" "gsr")])
8385 (define_insn "alignaddrdi_vis"
8386   [(set (match_operand:DI 0 "register_operand" "=r")
8387         (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
8388                  (match_operand:DI 2 "register_or_zero_operand" "rJ")))
8389    (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8390         (plus:DI (match_dup 1) (match_dup 2)))]
8391   "TARGET_VIS"
8392   "alignaddr\t%r1, %r2, %0"
8393   [(set_attr "type" "gsr")])
8395 (define_insn "alignaddrlsi_vis"
8396   [(set (match_operand:SI 0 "register_operand" "=r")
8397         (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
8398                  (match_operand:SI 2 "register_or_zero_operand" "rJ")))
8399    (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8400         (xor:DI (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2)))
8401                 (const_int 7)))]
8402   "TARGET_VIS"
8403   "alignaddrl\t%r1, %r2, %0"
8404   [(set_attr "type" "gsr")])
8406 (define_insn "alignaddrldi_vis"
8407   [(set (match_operand:DI 0 "register_operand" "=r")
8408         (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
8409                  (match_operand:DI 2 "register_or_zero_operand" "rJ")))
8410    (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8411         (xor:DI (plus:DI (match_dup 1) (match_dup 2))
8412                 (const_int 7)))]
8413   "TARGET_VIS"
8414   "alignaddrl\t%r1, %r2, %0"
8415   [(set_attr "type" "gsr")])
8417 (define_insn "pdist_vis"
8418   [(set (match_operand:DI 0 "register_operand" "=e")
8419         (unspec:DI [(match_operand:V8QI 1 "register_operand" "e")
8420                     (match_operand:V8QI 2 "register_operand" "e")
8421                     (match_operand:DI 3 "register_operand" "0")]
8422          UNSPEC_PDIST))]
8423   "TARGET_VIS"
8424   "pdist\t%1, %2, %0"
8425   [(set_attr "type" "pdist")
8426    (set_attr "fptype" "double")])
8428 ;; Edge instructions produce condition codes equivalent to a 'subcc'
8429 ;; with the same operands.
8430 (define_insn "edge8<P:mode>_vis"
8431   [(set (reg:CC_NOOV CC_REG)
8432         (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8433                                   (match_operand:P 2 "register_or_zero_operand" "rJ"))
8434                          (const_int 0)))
8435    (set (match_operand:P 0 "register_operand" "=r")
8436         (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8))]
8437   "TARGET_VIS"
8438   "edge8\t%r1, %r2, %0"
8439   [(set_attr "type" "edge")])
8441 (define_insn "edge8l<P:mode>_vis"
8442   [(set (reg:CC_NOOV CC_REG)
8443         (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8444                                   (match_operand:P 2 "register_or_zero_operand" "rJ"))
8445                          (const_int 0)))
8446    (set (match_operand:P 0 "register_operand" "=r")
8447         (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8L))]
8448   "TARGET_VIS"
8449   "edge8l\t%r1, %r2, %0"
8450   [(set_attr "type" "edge")])
8452 (define_insn "edge16<P:mode>_vis"
8453   [(set (reg:CC_NOOV CC_REG)
8454         (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8455                                   (match_operand:P 2 "register_or_zero_operand" "rJ"))
8456                          (const_int 0)))
8457    (set (match_operand:P 0 "register_operand" "=r")
8458         (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16))]
8459   "TARGET_VIS"
8460   "edge16\t%r1, %r2, %0"
8461   [(set_attr "type" "edge")])
8463 (define_insn "edge16l<P:mode>_vis"
8464   [(set (reg:CC_NOOV CC_REG)
8465         (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8466                                   (match_operand:P 2 "register_or_zero_operand" "rJ"))
8467                          (const_int 0)))
8468    (set (match_operand:P 0 "register_operand" "=r")
8469         (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16L))]
8470   "TARGET_VIS"
8471   "edge16l\t%r1, %r2, %0"
8472   [(set_attr "type" "edge")])
8474 (define_insn "edge32<P:mode>_vis"
8475   [(set (reg:CC_NOOV CC_REG)
8476         (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8477                                   (match_operand:P 2 "register_or_zero_operand" "rJ"))
8478                          (const_int 0)))
8479    (set (match_operand:P 0 "register_operand" "=r")
8480         (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32))]
8481   "TARGET_VIS"
8482   "edge32\t%r1, %r2, %0"
8483   [(set_attr "type" "edge")])
8485 (define_insn "edge32l<P:mode>_vis"
8486   [(set (reg:CC_NOOV CC_REG)
8487         (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8488                                   (match_operand:P 2 "register_or_zero_operand" "rJ"))
8489                          (const_int 0)))
8490    (set (match_operand:P 0 "register_operand" "=r")
8491         (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32L))]
8492   "TARGET_VIS"
8493   "edge32l\t%r1, %r2, %0"
8494   [(set_attr "type" "edge")])
8496 (define_code_iterator gcond [le ne gt eq])
8497 (define_mode_iterator GCM [V4HI V2SI])
8498 (define_mode_attr gcm_name [(V4HI "16") (V2SI "32")])
8500 (define_insn "fcmp<code><GCM:gcm_name><P:mode>_vis"
8501   [(set (match_operand:P 0 "register_operand" "=r")
8502         (unspec:P [(gcond:GCM (match_operand:GCM 1 "register_operand" "e")
8503                               (match_operand:GCM 2 "register_operand" "e"))]
8504          UNSPEC_FCMP))]
8505   "TARGET_VIS"
8506   "fcmp<code><GCM:gcm_name>\t%1, %2, %0"
8507   [(set_attr "type" "visl")
8508    (set_attr "fptype" "double")])
8510 (define_expand "vcond<mode><mode>"
8511   [(match_operand:GCM 0 "register_operand" "")
8512    (match_operand:GCM 1 "register_operand" "")
8513    (match_operand:GCM 2 "register_operand" "")
8514    (match_operator 3 ""
8515      [(match_operand:GCM 4 "register_operand" "")
8516       (match_operand:GCM 5 "register_operand" "")])]
8517   "TARGET_VIS3"
8519   sparc_expand_vcond (<MODE>mode, operands,
8520                       UNSPEC_CMASK<gcm_name>,
8521                       UNSPEC_FCMP);
8522   DONE;
8525 (define_expand "vconduv8qiv8qi"
8526   [(match_operand:V8QI 0 "register_operand" "")
8527    (match_operand:V8QI 1 "register_operand" "")
8528    (match_operand:V8QI 2 "register_operand" "")
8529    (match_operator 3 ""
8530      [(match_operand:V8QI 4 "register_operand" "")
8531       (match_operand:V8QI 5 "register_operand" "")])]
8532   "TARGET_VIS3"
8534   sparc_expand_vcond (V8QImode, operands,
8535                       UNSPEC_CMASK8,
8536                       UNSPEC_FUCMP);
8537   DONE;
8540 (define_insn "array8<P:mode>_vis"
8541   [(set (match_operand:P 0 "register_operand" "=r")
8542         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8543                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
8544                   UNSPEC_ARRAY8))]
8545   "TARGET_VIS"
8546   "array8\t%r1, %r2, %0"
8547   [(set_attr "type" "array")])
8549 (define_insn "array16<P:mode>_vis"
8550   [(set (match_operand:P 0 "register_operand" "=r")
8551         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8552                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
8553                   UNSPEC_ARRAY16))]
8554   "TARGET_VIS"
8555   "array16\t%r1, %r2, %0"
8556   [(set_attr "type" "array")])
8558 (define_insn "array32<P:mode>_vis"
8559   [(set (match_operand:P 0 "register_operand" "=r")
8560         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8561                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
8562                   UNSPEC_ARRAY32))]
8563   "TARGET_VIS"
8564   "array32\t%r1, %r2, %0"
8565   [(set_attr "type" "array")])
8567 (define_insn "bmaskdi_vis"
8568   [(set (match_operand:DI 0 "register_operand" "=r")
8569         (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
8570                  (match_operand:DI 2 "register_or_zero_operand" "rJ")))
8571    (set (zero_extract:DI (reg:DI GSR_REG) (const_int 32) (const_int 32))
8572         (plus:DI (match_dup 1) (match_dup 2)))]
8573   "TARGET_VIS2"
8574   "bmask\t%r1, %r2, %0"
8575   [(set_attr "type" "array")])
8577 (define_insn "bmasksi_vis"
8578   [(set (match_operand:SI 0 "register_operand" "=r")
8579         (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
8580                  (match_operand:SI 2 "register_or_zero_operand" "rJ")))
8581    (set (zero_extract:DI (reg:DI GSR_REG) (const_int 32) (const_int 32))
8582         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
8583   "TARGET_VIS2"
8584   "bmask\t%r1, %r2, %0"
8585   [(set_attr "type" "array")])
8587 (define_insn "bshuffle<VM64:mode>_vis"
8588   [(set (match_operand:VM64 0 "register_operand" "=e")
8589         (unspec:VM64 [(match_operand:VM64 1 "register_operand" "e")
8590                       (match_operand:VM64 2 "register_operand" "e")
8591                       (reg:DI GSR_REG)]
8592                      UNSPEC_BSHUFFLE))]
8593   "TARGET_VIS2"
8594   "bshuffle\t%1, %2, %0"
8595   [(set_attr "type" "fga")
8596    (set_attr "fptype" "double")])
8598 ;; The rtl expanders will happily convert constant permutations on other
8599 ;; modes down to V8QI.  Rely on this to avoid the complexity of the byte
8600 ;; order of the permutation.
8601 (define_expand "vec_perm_constv8qi"
8602   [(match_operand:V8QI 0 "register_operand" "")
8603    (match_operand:V8QI 1 "register_operand" "")
8604    (match_operand:V8QI 2 "register_operand" "")
8605    (match_operand:V8QI 3 "" "")]
8606   "TARGET_VIS2"
8608   unsigned int i, mask;
8609   rtx sel = operands[3];
8611   for (i = mask = 0; i < 8; ++i)
8612     mask |= (INTVAL (XVECEXP (sel, 0, i)) & 0xf) << (28 - i*4);
8613   sel = force_reg (SImode, gen_int_mode (mask, SImode));
8615   emit_insn (gen_bmasksi_vis (gen_rtx_REG (SImode, 0), sel, const0_rtx));
8616   emit_insn (gen_bshufflev8qi_vis (operands[0], operands[1], operands[2]));
8617   DONE;
8620 ;; Unlike constant permutation, we can vastly simplify the compression of
8621 ;; the 64-bit selector input to the 32-bit %gsr value by knowing what the
8622 ;; width of the input is.
8623 (define_expand "vec_perm<mode>"
8624   [(match_operand:VM64 0 "register_operand" "")
8625    (match_operand:VM64 1 "register_operand" "")
8626    (match_operand:VM64 2 "register_operand" "")
8627    (match_operand:VM64 3 "register_operand" "")]
8628   "TARGET_VIS2"
8630   sparc_expand_vec_perm_bmask (<MODE>mode, operands[3]);
8631   emit_insn (gen_bshuffle<mode>_vis (operands[0], operands[1], operands[2]));
8632   DONE;
8635 ;; VIS 2.0 adds edge variants which do not set the condition codes
8636 (define_insn "edge8n<P:mode>_vis"
8637   [(set (match_operand:P 0 "register_operand" "=r")
8638         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8639                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
8640                   UNSPEC_EDGE8N))]
8641   "TARGET_VIS2"
8642   "edge8n\t%r1, %r2, %0"
8643   [(set_attr "type" "edgen")])
8645 (define_insn "edge8ln<P:mode>_vis"
8646   [(set (match_operand:P 0 "register_operand" "=r")
8647         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8648                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
8649                   UNSPEC_EDGE8LN))]
8650   "TARGET_VIS2"
8651   "edge8ln\t%r1, %r2, %0"
8652   [(set_attr "type" "edgen")])
8654 (define_insn "edge16n<P:mode>_vis"
8655   [(set (match_operand:P 0 "register_operand" "=r")
8656         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8657                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
8658                   UNSPEC_EDGE16N))]
8659   "TARGET_VIS2"
8660   "edge16n\t%r1, %r2, %0"
8661   [(set_attr "type" "edgen")])
8663 (define_insn "edge16ln<P:mode>_vis"
8664   [(set (match_operand:P 0 "register_operand" "=r")
8665         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8666                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
8667                   UNSPEC_EDGE16LN))]
8668   "TARGET_VIS2"
8669   "edge16ln\t%r1, %r2, %0"
8670   [(set_attr "type" "edgen")])
8672 (define_insn "edge32n<P:mode>_vis"
8673   [(set (match_operand:P 0 "register_operand" "=r")
8674         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8675                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
8676                   UNSPEC_EDGE32N))]
8677   "TARGET_VIS2"
8678   "edge32n\t%r1, %r2, %0"
8679   [(set_attr "type" "edgen")])
8681 (define_insn "edge32ln<P:mode>_vis"
8682   [(set (match_operand:P 0 "register_operand" "=r")
8683         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8684                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
8685                   UNSPEC_EDGE32LN))]
8686   "TARGET_VIS2"
8687   "edge32ln\t%r1, %r2, %0"
8688   [(set_attr "type" "edge")])
8690 ;; Conditional moves are possible via fcmpX --> cmaskX -> bshuffle
8691 (define_insn "cmask8<P:mode>_vis"
8692   [(set (reg:DI GSR_REG)
8693         (unspec:DI [(match_operand:P 0 "register_or_zero_operand" "rJ")
8694                     (reg:DI GSR_REG)]
8695                    UNSPEC_CMASK8))]
8696   "TARGET_VIS3"
8697   "cmask8\t%r0"
8698   [(set_attr "type" "fga")])
8700 (define_insn "cmask16<P:mode>_vis"
8701   [(set (reg:DI GSR_REG)
8702         (unspec:DI [(match_operand:P 0 "register_or_zero_operand" "rJ")
8703                     (reg:DI GSR_REG)]
8704                    UNSPEC_CMASK16))]
8705   "TARGET_VIS3"
8706   "cmask16\t%r0"
8707   [(set_attr "type" "fga")])
8709 (define_insn "cmask32<P:mode>_vis"
8710   [(set (reg:DI GSR_REG)
8711         (unspec:DI [(match_operand:P 0 "register_or_zero_operand" "rJ")
8712                     (reg:DI GSR_REG)]
8713                    UNSPEC_CMASK32))]
8714   "TARGET_VIS3"
8715   "cmask32\t%r0"
8716   [(set_attr "type" "fga")])
8718 (define_insn "fchksm16_vis"
8719   [(set (match_operand:V4HI 0 "register_operand" "=e")
8720         (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "e")
8721                       (match_operand:V4HI 2 "register_operand" "e")]
8722                      UNSPEC_FCHKSM16))]
8723   "TARGET_VIS3"
8724   "fchksm16\t%1, %2, %0"
8725   [(set_attr "type" "fga")])
8727 (define_code_iterator vis3_shift [ashift ss_ashift lshiftrt ashiftrt])
8728 (define_code_attr vis3_shift_insn
8729   [(ashift "fsll") (ss_ashift "fslas") (lshiftrt "fsrl") (ashiftrt "fsra")])
8730 (define_code_attr vis3_shift_patname
8731   [(ashift "ashl") (ss_ashift "ssashl") (lshiftrt "lshr") (ashiftrt "ashr")])
8732    
8733 (define_insn "v<vis3_shift_patname><mode>3"
8734   [(set (match_operand:GCM 0 "register_operand" "=<vconstr>")
8735         (vis3_shift:GCM (match_operand:GCM 1 "register_operand" "<vconstr>")
8736                         (match_operand:GCM 2 "register_operand" "<vconstr>")))]
8737   "TARGET_VIS3"
8738   "<vis3_shift_insn><vbits>\t%1, %2, %0"
8739   [(set_attr "type" "fga")])
8741 (define_insn "pdistn<mode>_vis"
8742   [(set (match_operand:P 0 "register_operand" "=r")
8743         (unspec:P [(match_operand:V8QI 1 "register_operand" "e")
8744                    (match_operand:V8QI 2 "register_operand" "e")]
8745          UNSPEC_PDISTN))]
8746   "TARGET_VIS3"
8747   "pdistn\t%1, %2, %0"
8748   [(set_attr "type" "pdistn")
8749    (set_attr "fptype" "double")])
8751 (define_insn "fmean16_vis"
8752   [(set (match_operand:V4HI 0 "register_operand" "=e")
8753         (truncate:V4HI
8754           (lshiftrt:V4SI
8755             (plus:V4SI
8756               (plus:V4SI
8757                 (zero_extend:V4SI
8758                   (match_operand:V4HI 1 "register_operand" "e"))
8759                 (zero_extend:V4SI
8760                   (match_operand:V4HI 2 "register_operand" "e")))
8761               (const_vector:V4SI [(const_int 1) (const_int 1)
8762                                   (const_int 1) (const_int 1)]))
8763           (const_int 1))))]
8764   "TARGET_VIS3"
8765   "fmean16\t%1, %2, %0"
8766   [(set_attr "type" "fga")])
8768 (define_insn "fp<plusminus_insn>64_vis"
8769   [(set (match_operand:V1DI 0 "register_operand" "=e")
8770         (plusminus:V1DI (match_operand:V1DI 1 "register_operand" "e")
8771                         (match_operand:V1DI 2 "register_operand" "e")))]
8772   "TARGET_VIS3"
8773   "fp<plusminus_insn>64\t%1, %2, %0"
8774   [(set_attr "type" "fga")])
8776 (define_mode_iterator VASS [V4HI V2SI V2HI V1SI])
8777 (define_code_iterator vis3_addsub_ss [ss_plus ss_minus])
8778 (define_code_attr vis3_addsub_ss_insn
8779   [(ss_plus "fpadds") (ss_minus "fpsubs")])
8780 (define_code_attr vis3_addsub_ss_patname
8781   [(ss_plus "ssadd") (ss_minus "sssub")])
8783 (define_insn "<vis3_addsub_ss_patname><mode>3"
8784   [(set (match_operand:VASS 0 "register_operand" "=<vconstr>")
8785         (vis3_addsub_ss:VASS (match_operand:VASS 1 "register_operand" "<vconstr>")
8786                              (match_operand:VASS 2 "register_operand" "<vconstr>")))]
8787   "TARGET_VIS3"
8788   "<vis3_addsub_ss_insn><vbits>\t%1, %2, %0"
8789   [(set_attr "type" "fga")])
8791 (define_insn "fucmp<code>8<P:mode>_vis"
8792   [(set (match_operand:P 0 "register_operand" "=r")
8793         (unspec:P [(gcond:V8QI (match_operand:V8QI 1 "register_operand" "e")
8794                                (match_operand:V8QI 2 "register_operand" "e"))]
8795          UNSPEC_FUCMP))]
8796   "TARGET_VIS3"
8797   "fucmp<code>8\t%1, %2, %0"
8798   [(set_attr "type" "visl")])
8800 (define_insn "*naddsf3"
8801   [(set (match_operand:SF 0 "register_operand" "=f")
8802         (neg:SF (plus:SF (match_operand:SF 1 "register_operand" "f")
8803                          (match_operand:SF 2 "register_operand" "f"))))]
8804   "TARGET_VIS3"
8805   "fnadds\t%1, %2, %0"
8806   [(set_attr "type" "fp")])
8808 (define_insn "*nadddf3"
8809   [(set (match_operand:DF 0 "register_operand" "=e")
8810         (neg:DF (plus:DF (match_operand:DF 1 "register_operand" "e")
8811                          (match_operand:DF 2 "register_operand" "e"))))]
8812   "TARGET_VIS3"
8813   "fnaddd\t%1, %2, %0"
8814   [(set_attr "type" "fp")
8815    (set_attr "fptype" "double")])
8817 (define_insn "*nmulsf3"
8818   [(set (match_operand:SF 0 "register_operand" "=f")
8819         (mult:SF (neg:SF (match_operand:SF 1 "register_operand" "f"))
8820                  (match_operand:SF 2 "register_operand" "f")))]
8821   "TARGET_VIS3"
8822   "fnmuls\t%1, %2, %0"
8823   [(set_attr "type" "fpmul")])
8825 (define_insn "*nmuldf3"
8826   [(set (match_operand:DF 0 "register_operand" "=e")
8827         (mult:DF (neg:DF (match_operand:DF 1 "register_operand" "e"))
8828                  (match_operand:DF 2 "register_operand" "e")))]
8829   "TARGET_VIS3"
8830   "fnmuld\t%1, %2, %0"
8831   [(set_attr "type" "fpmul")
8832    (set_attr "fptype" "double")])
8834 (define_insn "*nmuldf3_extend"
8835   [(set (match_operand:DF 0 "register_operand" "=e")
8836         (mult:DF (neg:DF (float_extend:DF
8837                            (match_operand:SF 1 "register_operand" "f")))
8838                  (float_extend:DF
8839                    (match_operand:SF 2 "register_operand" "f"))))]
8840   "TARGET_VIS3"
8841   "fnsmuld\t%1, %2, %0"
8842   [(set_attr "type" "fpmul")
8843    (set_attr "fptype" "double")])
8845 (define_insn "fhaddsf_vis"
8846   [(set (match_operand:SF 0 "register_operand" "=f")
8847         (unspec:SF [(match_operand:SF 1 "register_operand" "f")
8848                     (match_operand:SF 2 "register_operand" "f")]
8849                    UNSPEC_FHADD))]
8850   "TARGET_VIS3"
8851   "fhadds\t%1, %2, %0"
8852   [(set_attr "type" "fp")])
8854 (define_insn "fhadddf_vis"
8855   [(set (match_operand:DF 0 "register_operand" "=f")
8856         (unspec:DF [(match_operand:DF 1 "register_operand" "f")
8857                     (match_operand:DF 2 "register_operand" "f")]
8858                    UNSPEC_FHADD))]
8859   "TARGET_VIS3"
8860   "fhaddd\t%1, %2, %0"
8861   [(set_attr "type" "fp")
8862    (set_attr "fptype" "double")])
8864 (define_insn "fhsubsf_vis"
8865   [(set (match_operand:SF 0 "register_operand" "=f")
8866         (unspec:SF [(match_operand:SF 1 "register_operand" "f")
8867                     (match_operand:SF 2 "register_operand" "f")]
8868                    UNSPEC_FHSUB))]
8869   "TARGET_VIS3"
8870   "fhsubs\t%1, %2, %0"
8871   [(set_attr "type" "fp")])
8873 (define_insn "fhsubdf_vis"
8874   [(set (match_operand:DF 0 "register_operand" "=f")
8875         (unspec:DF [(match_operand:DF 1 "register_operand" "f")
8876                     (match_operand:DF 2 "register_operand" "f")]
8877                    UNSPEC_FHSUB))]
8878   "TARGET_VIS3"
8879   "fhsubd\t%1, %2, %0"
8880   [(set_attr "type" "fp")
8881    (set_attr "fptype" "double")])
8883 (define_insn "fnhaddsf_vis"
8884   [(set (match_operand:SF 0 "register_operand" "=f")
8885         (neg:SF (unspec:SF [(match_operand:SF 1 "register_operand" "f")
8886                             (match_operand:SF 2 "register_operand" "f")]
8887                            UNSPEC_FHADD)))]
8888   "TARGET_VIS3"
8889   "fnhadds\t%1, %2, %0"
8890   [(set_attr "type" "fp")])
8892 (define_insn "fnhadddf_vis"
8893   [(set (match_operand:DF 0 "register_operand" "=f")
8894         (neg:DF (unspec:DF [(match_operand:DF 1 "register_operand" "f")
8895                             (match_operand:DF 2 "register_operand" "f")]
8896                            UNSPEC_FHADD)))]
8897   "TARGET_VIS3"
8898   "fnhaddd\t%1, %2, %0"
8899   [(set_attr "type" "fp")
8900    (set_attr "fptype" "double")])
8902 (define_expand "umulxhi_vis"
8903   [(set (match_operand:DI 0 "register_operand" "")
8904         (truncate:DI
8905           (lshiftrt:TI
8906             (mult:TI (zero_extend:TI
8907                        (match_operand:DI 1 "arith_operand" ""))
8908                      (zero_extend:TI
8909                        (match_operand:DI 2 "arith_operand" "")))
8910            (const_int 64))))]
8911  "TARGET_VIS3"
8913   if (! TARGET_ARCH64)
8914     {
8915       emit_insn (gen_umulxhi_v8plus (operands[0], operands[1], operands[2]));
8916       DONE;
8917     }
8920 (define_insn "*umulxhi_sp64"
8921   [(set (match_operand:DI 0 "register_operand" "=r")
8922         (truncate:DI
8923           (lshiftrt:TI
8924             (mult:TI (zero_extend:TI
8925                        (match_operand:DI 1 "arith_operand" "%r"))
8926                      (zero_extend:TI
8927                        (match_operand:DI 2 "arith_operand" "rI")))
8928            (const_int 64))))]
8929   "TARGET_VIS3 && TARGET_ARCH64"
8930   "umulxhi\t%1, %2, %0"
8931   [(set_attr "type" "imul")])
8933 (define_insn "umulxhi_v8plus"
8934   [(set (match_operand:DI 0 "register_operand" "=r,h")
8935         (truncate:DI
8936           (lshiftrt:TI
8937             (mult:TI (zero_extend:TI
8938                        (match_operand:DI 1 "arith_operand" "%r,0"))
8939                      (zero_extend:TI
8940                        (match_operand:DI 2 "arith_operand" "rI,rI")))
8941            (const_int 64))))
8942    (clobber (match_scratch:SI 3 "=&h,X"))
8943    (clobber (match_scratch:SI 4 "=&h,X"))]
8944   "TARGET_VIS3 && ! TARGET_ARCH64"
8945   "* return output_v8plus_mult (insn, operands, \"umulxhi\");"
8946   [(set_attr "type" "imul")
8947    (set_attr "length" "9,8")])
8949 (define_expand "xmulx_vis"
8950   [(set (match_operand:DI 0 "register_operand" "")
8951         (truncate:DI
8952           (unspec:TI [(zero_extend:TI
8953                         (match_operand:DI 1 "arith_operand" ""))
8954                       (zero_extend:TI
8955                         (match_operand:DI 2 "arith_operand" ""))]
8956            UNSPEC_XMUL)))]
8957   "TARGET_VIS3"
8959   if (! TARGET_ARCH64)
8960     {
8961       emit_insn (gen_xmulx_v8plus (operands[0], operands[1], operands[2]));
8962       DONE;
8963     }
8966 (define_insn "*xmulx_sp64"
8967   [(set (match_operand:DI 0 "register_operand" "=r")
8968         (truncate:DI
8969           (unspec:TI [(zero_extend:TI
8970                         (match_operand:DI 1 "arith_operand" "%r"))
8971                       (zero_extend:TI
8972                         (match_operand:DI 2 "arith_operand" "rI"))]
8973            UNSPEC_XMUL)))]
8974   "TARGET_VIS3 && TARGET_ARCH64"
8975   "xmulx\t%1, %2, %0"
8976   [(set_attr "type" "imul")])
8978 (define_insn "xmulx_v8plus"
8979   [(set (match_operand:DI 0 "register_operand" "=r,h")
8980         (truncate:DI
8981           (unspec:TI [(zero_extend:TI
8982                         (match_operand:DI 1 "arith_operand" "%r,0"))
8983                       (zero_extend:TI
8984                         (match_operand:DI 2 "arith_operand" "rI,rI"))]
8985            UNSPEC_XMUL)))
8986    (clobber (match_scratch:SI 3 "=&h,X"))
8987    (clobber (match_scratch:SI 4 "=&h,X"))]
8988   "TARGET_VIS3 && ! TARGET_ARCH64"
8989   "* return output_v8plus_mult (insn, operands, \"xmulx\");"
8990   [(set_attr "type" "imul")
8991    (set_attr "length" "9,8")])
8993 (define_expand "xmulxhi_vis"
8994   [(set (match_operand:DI 0 "register_operand" "")
8995         (truncate:DI
8996           (lshiftrt:TI
8997             (unspec:TI [(zero_extend:TI
8998                           (match_operand:DI 1 "arith_operand" ""))
8999                         (zero_extend:TI
9000                           (match_operand:DI 2 "arith_operand" ""))]
9001              UNSPEC_XMUL)
9002            (const_int 64))))]
9003   "TARGET_VIS3"
9005   if (! TARGET_ARCH64)
9006     {
9007       emit_insn (gen_xmulxhi_v8plus (operands[0], operands[1], operands[2]));
9008       DONE;
9009     }
9012 (define_insn "*xmulxhi_sp64"
9013   [(set (match_operand:DI 0 "register_operand" "=r")
9014         (truncate:DI
9015           (lshiftrt:TI
9016             (unspec:TI [(zero_extend:TI
9017                           (match_operand:DI 1 "arith_operand" "%r"))
9018                         (zero_extend:TI
9019                           (match_operand:DI 2 "arith_operand" "rI"))]
9020              UNSPEC_XMUL)
9021            (const_int 64))))]
9022   "TARGET_VIS3 && TARGET_ARCH64"
9023   "xmulxhi\t%1, %2, %0"
9024   [(set_attr "type" "imul")])
9026 (define_insn "xmulxhi_v8plus"
9027   [(set (match_operand:DI 0 "register_operand" "=r,h")
9028         (truncate:DI
9029           (lshiftrt:TI
9030             (unspec:TI [(zero_extend:TI
9031                           (match_operand:DI 1 "arith_operand" "%r,0"))
9032                         (zero_extend:TI
9033                           (match_operand:DI 2 "arith_operand" "rI,rI"))]
9034              UNSPEC_XMUL)
9035            (const_int 64))))
9036    (clobber (match_scratch:SI 3 "=&h,X"))
9037    (clobber (match_scratch:SI 4 "=&h,X"))]
9038   "TARGET_VIS3 && !TARGET_ARCH64"
9039   "* return output_v8plus_mult (insn, operands, \"xmulxhi\");"
9040   [(set_attr "type" "imul")
9041    (set_attr "length" "9,8")])
9043 (include "sync.md")