PR bootstrap/66252
[official-gcc.git] / gcc / config / sparc / sparc.md
bloba561877d72b0932505bc7baa2029e640d1957e44
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_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 1))
3049    (set (match_dup 3) (const_int 0))]
3050   "operands[2] = gen_lowpart (SImode, operands[0]);
3051    operands[3] = gen_highpart (SImode, operands[0]);"
3052   [(set_attr "length" "2")])
3054 ;; Simplify comparisons of extended values.
3056 (define_insn "*cmp_zero_extendqisi2"
3057   [(set (reg:CC CC_REG)
3058         (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
3059                     (const_int 0)))]
3060   ""
3061   "andcc\t%0, 0xff, %%g0"
3062   [(set_attr "type" "compare")])
3064 (define_insn "*cmp_zero_qi"
3065   [(set (reg:CC CC_REG)
3066         (compare:CC (match_operand:QI 0 "register_operand" "r")
3067                     (const_int 0)))]
3068   ""
3069   "andcc\t%0, 0xff, %%g0"
3070   [(set_attr "type" "compare")])
3072 (define_insn "*cmp_zero_extendqisi2_set"
3073   [(set (reg:CC CC_REG)
3074         (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
3075                     (const_int 0)))
3076    (set (match_operand:SI 0 "register_operand" "=r")
3077         (zero_extend:SI (match_dup 1)))]
3078   ""
3079   "andcc\t%1, 0xff, %0"
3080   [(set_attr "type" "compare")])
3082 (define_insn "*cmp_zero_extendqisi2_andcc_set"
3083   [(set (reg:CC CC_REG)
3084         (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
3085                             (const_int 255))
3086                     (const_int 0)))
3087    (set (match_operand:SI 0 "register_operand" "=r")
3088         (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
3089   ""
3090   "andcc\t%1, 0xff, %0"
3091   [(set_attr "type" "compare")])
3093 (define_insn "*cmp_zero_extendqidi2"
3094   [(set (reg:CCX CC_REG)
3095         (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
3096                      (const_int 0)))]
3097   "TARGET_ARCH64"
3098   "andcc\t%0, 0xff, %%g0"
3099   [(set_attr "type" "compare")])
3101 (define_insn "*cmp_zero_qi_sp64"
3102   [(set (reg:CCX CC_REG)
3103         (compare:CCX (match_operand:QI 0 "register_operand" "r")
3104                      (const_int 0)))]
3105   "TARGET_ARCH64"
3106   "andcc\t%0, 0xff, %%g0"
3107   [(set_attr "type" "compare")])
3109 (define_insn "*cmp_zero_extendqidi2_set"
3110   [(set (reg:CCX CC_REG)
3111         (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
3112                      (const_int 0)))
3113    (set (match_operand:DI 0 "register_operand" "=r")
3114         (zero_extend:DI (match_dup 1)))]
3115   "TARGET_ARCH64"
3116   "andcc\t%1, 0xff, %0"
3117   [(set_attr "type" "compare")])
3119 (define_insn "*cmp_zero_extendqidi2_andcc_set"
3120   [(set (reg:CCX CC_REG)
3121         (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
3122                              (const_int 255))
3123                      (const_int 0)))
3124    (set (match_operand:DI 0 "register_operand" "=r")
3125         (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
3126   "TARGET_ARCH64"
3127   "andcc\t%1, 0xff, %0"
3128   [(set_attr "type" "compare")])
3130 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
3132 (define_insn "*cmp_siqi_trunc"
3133   [(set (reg:CC CC_REG)
3134         (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
3135                     (const_int 0)))]
3136   ""
3137   "andcc\t%0, 0xff, %%g0"
3138   [(set_attr "type" "compare")])
3140 (define_insn "*cmp_siqi_trunc_set"
3141   [(set (reg:CC CC_REG)
3142         (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
3143                     (const_int 0)))
3144    (set (match_operand:QI 0 "register_operand" "=r")
3145         (subreg:QI (match_dup 1) 3))]
3146   ""
3147   "andcc\t%1, 0xff, %0"
3148   [(set_attr "type" "compare")])
3150 (define_insn "*cmp_diqi_trunc"
3151   [(set (reg:CC CC_REG)
3152         (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
3153                     (const_int 0)))]
3154   "TARGET_ARCH64"
3155   "andcc\t%0, 0xff, %%g0"
3156   [(set_attr "type" "compare")])
3158 (define_insn "*cmp_diqi_trunc_set"
3159   [(set (reg:CC CC_REG)
3160         (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
3161                     (const_int 0)))
3162    (set (match_operand:QI 0 "register_operand" "=r")
3163         (subreg:QI (match_dup 1) 7))]
3164   "TARGET_ARCH64"
3165   "andcc\t%1, 0xff, %0"
3166   [(set_attr "type" "compare")])
3169 ;; Sign-extension instructions
3171 ;; These patterns originally accepted general_operands, however, slightly
3172 ;; better code is generated by only accepting register_operands, and then
3173 ;; letting combine generate the lds[hb] insns.
3175 (define_expand "extendhisi2"
3176   [(set (match_operand:SI 0 "register_operand" "")
3177         (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
3178   ""
3180   rtx temp = gen_reg_rtx (SImode);
3181   rtx shift_16 = GEN_INT (16);
3182   int op1_subbyte = 0;
3184   if (GET_CODE (operand1) == SUBREG)
3185     {
3186       op1_subbyte = SUBREG_BYTE (operand1);
3187       op1_subbyte /= GET_MODE_SIZE (SImode);
3188       op1_subbyte *= GET_MODE_SIZE (SImode);
3189       operand1 = XEXP (operand1, 0);
3190     }
3192   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3193                           shift_16));
3194   emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
3195   DONE;
3198 (define_insn "*sign_extendhisi2_insn"
3199   [(set (match_operand:SI 0 "register_operand" "=r")
3200         (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3201   ""
3202   "ldsh\t%1, %0"
3203   [(set_attr "type" "sload")
3204    (set_attr "us3load_type" "3cycle")])
3206 (define_expand "extendqihi2"
3207   [(set (match_operand:HI 0 "register_operand" "")
3208         (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
3209   ""
3211   rtx temp = gen_reg_rtx (SImode);
3212   rtx shift_24 = GEN_INT (24);
3213   int op1_subbyte = 0;
3214   int op0_subbyte = 0;
3216   if (GET_CODE (operand1) == SUBREG)
3217     {
3218       op1_subbyte = SUBREG_BYTE (operand1);
3219       op1_subbyte /= GET_MODE_SIZE (SImode);
3220       op1_subbyte *= GET_MODE_SIZE (SImode);
3221       operand1 = XEXP (operand1, 0);
3222     }
3223   if (GET_CODE (operand0) == SUBREG)
3224     {
3225       op0_subbyte = SUBREG_BYTE (operand0);
3226       op0_subbyte /= GET_MODE_SIZE (SImode);
3227       op0_subbyte *= GET_MODE_SIZE (SImode);
3228       operand0 = XEXP (operand0, 0);
3229     }
3230   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3231                           shift_24));
3232   if (GET_MODE (operand0) != SImode)
3233     operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
3234   emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3235   DONE;
3238 (define_insn "*sign_extendqihi2_insn"
3239   [(set (match_operand:HI 0 "register_operand" "=r")
3240         (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3241   ""
3242   "ldsb\t%1, %0"
3243   [(set_attr "type" "sload")
3244    (set_attr "us3load_type" "3cycle")])
3246 (define_expand "extendqisi2"
3247   [(set (match_operand:SI 0 "register_operand" "")
3248         (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
3249   ""
3251   rtx temp = gen_reg_rtx (SImode);
3252   rtx shift_24 = GEN_INT (24);
3253   int op1_subbyte = 0;
3255   if (GET_CODE (operand1) == SUBREG)
3256     {
3257       op1_subbyte = SUBREG_BYTE (operand1);
3258       op1_subbyte /= GET_MODE_SIZE (SImode);
3259       op1_subbyte *= GET_MODE_SIZE (SImode);
3260       operand1 = XEXP (operand1, 0);
3261     }
3263   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3264                           shift_24));
3265   emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3266   DONE;
3269 (define_insn "*sign_extendqisi2_insn"
3270   [(set (match_operand:SI 0 "register_operand" "=r")
3271         (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3272   ""
3273   "ldsb\t%1, %0"
3274   [(set_attr "type" "sload")
3275    (set_attr "us3load_type" "3cycle")])
3277 (define_expand "extendqidi2"
3278   [(set (match_operand:DI 0 "register_operand" "")
3279         (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
3280   "TARGET_ARCH64"
3282   rtx temp = gen_reg_rtx (DImode);
3283   rtx shift_56 = GEN_INT (56);
3284   int op1_subbyte = 0;
3286   if (GET_CODE (operand1) == SUBREG)
3287     {
3288       op1_subbyte = SUBREG_BYTE (operand1);
3289       op1_subbyte /= GET_MODE_SIZE (DImode);
3290       op1_subbyte *= GET_MODE_SIZE (DImode);
3291       operand1 = XEXP (operand1, 0);
3292     }
3294   emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3295                           shift_56));
3296   emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
3297   DONE;
3300 (define_insn "*sign_extendqidi2_insn"
3301   [(set (match_operand:DI 0 "register_operand" "=r")
3302         (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3303   "TARGET_ARCH64"
3304   "ldsb\t%1, %0"
3305   [(set_attr "type" "sload")
3306    (set_attr "us3load_type" "3cycle")])
3308 (define_expand "extendhidi2"
3309   [(set (match_operand:DI 0 "register_operand" "")
3310         (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
3311   "TARGET_ARCH64"
3313   rtx temp = gen_reg_rtx (DImode);
3314   rtx shift_48 = GEN_INT (48);
3315   int op1_subbyte = 0;
3317   if (GET_CODE (operand1) == SUBREG)
3318     {
3319       op1_subbyte = SUBREG_BYTE (operand1);
3320       op1_subbyte /= GET_MODE_SIZE (DImode);
3321       op1_subbyte *= GET_MODE_SIZE (DImode);
3322       operand1 = XEXP (operand1, 0);
3323     }
3325   emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3326                           shift_48));
3327   emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
3328   DONE;
3331 (define_insn "*sign_extendhidi2_insn"
3332   [(set (match_operand:DI 0 "register_operand" "=r")
3333         (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3334   "TARGET_ARCH64"
3335   "ldsh\t%1, %0"
3336   [(set_attr "type" "sload")
3337    (set_attr "us3load_type" "3cycle")])
3339 (define_expand "extendsidi2"
3340   [(set (match_operand:DI 0 "register_operand" "")
3341         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3342   "TARGET_ARCH64"
3343   "")
3345 (define_insn "*sign_extendsidi2_insn"
3346   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
3347         (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m,*f")))]
3348   "TARGET_ARCH64"
3349   "@
3350   sra\t%1, 0, %0
3351   ldsw\t%1, %0
3352   movstosw\t%1, %0"
3353   [(set_attr "type" "shift,sload,*")
3354    (set_attr "us3load_type" "*,3cycle,*")
3355    (set_attr "cpu_feature" "*,*,vis3")])
3358 ;; Special pattern for optimizing bit-field compares.  This is needed
3359 ;; because combine uses this as a canonical form.
3361 (define_insn "*cmp_zero_extract"
3362   [(set (reg:CC CC_REG)
3363         (compare:CC
3364          (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
3365                           (match_operand:SI 1 "small_int_operand" "I")
3366                           (match_operand:SI 2 "small_int_operand" "I"))
3367          (const_int 0)))]
3368   "INTVAL (operands[2]) > 19"
3370   int len = INTVAL (operands[1]);
3371   int pos = 32 - INTVAL (operands[2]) - len;
3372   HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
3373   operands[1] = GEN_INT (mask);
3374   return "andcc\t%0, %1, %%g0";
3376   [(set_attr "type" "compare")])
3378 (define_insn "*cmp_zero_extract_sp64"
3379   [(set (reg:CCX CC_REG)
3380         (compare:CCX
3381          (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
3382                           (match_operand:SI 1 "small_int_operand" "I")
3383                           (match_operand:SI 2 "small_int_operand" "I"))
3384          (const_int 0)))]
3385   "TARGET_ARCH64 && INTVAL (operands[2]) > 51"
3387   int len = INTVAL (operands[1]);
3388   int pos = 64 - INTVAL (operands[2]) - len;
3389   HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
3390   operands[1] = GEN_INT (mask);
3391   return "andcc\t%0, %1, %%g0";
3393   [(set_attr "type" "compare")])
3396 ;; Conversions between float, double and long double.
3398 (define_insn "extendsfdf2"
3399   [(set (match_operand:DF 0 "register_operand" "=e")
3400         (float_extend:DF
3401          (match_operand:SF 1 "register_operand" "f")))]
3402   "TARGET_FPU"
3403   "fstod\t%1, %0"
3404   [(set_attr "type" "fp")
3405    (set_attr "fptype" "double")])
3407 (define_expand "extendsftf2"
3408   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3409         (float_extend:TF
3410          (match_operand:SF 1 "register_operand" "")))]
3411   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3412   "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3414 (define_insn "*extendsftf2_hq"
3415   [(set (match_operand:TF 0 "register_operand" "=e")
3416         (float_extend:TF
3417          (match_operand:SF 1 "register_operand" "f")))]
3418   "TARGET_FPU && TARGET_HARD_QUAD"
3419   "fstoq\t%1, %0"
3420   [(set_attr "type" "fp")])
3422 (define_expand "extenddftf2"
3423   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3424         (float_extend:TF
3425          (match_operand:DF 1 "register_operand" "")))]
3426   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3427   "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3429 (define_insn "*extenddftf2_hq"
3430   [(set (match_operand:TF 0 "register_operand" "=e")
3431         (float_extend:TF
3432          (match_operand:DF 1 "register_operand" "e")))]
3433   "TARGET_FPU && TARGET_HARD_QUAD"
3434   "fdtoq\t%1, %0"
3435   [(set_attr "type" "fp")])
3437 (define_insn "truncdfsf2"
3438   [(set (match_operand:SF 0 "register_operand" "=f")
3439         (float_truncate:SF
3440          (match_operand:DF 1 "register_operand" "e")))]
3441   "TARGET_FPU"
3442   "fdtos\t%1, %0"
3443   [(set_attr "type" "fp")
3444    (set_attr "fptype" "double")
3445    (set_attr "fptype_ut699" "single")])
3447 (define_expand "trunctfsf2"
3448   [(set (match_operand:SF 0 "register_operand" "")
3449         (float_truncate:SF
3450          (match_operand:TF 1 "general_operand" "")))]
3451   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3452   "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3454 (define_insn "*trunctfsf2_hq"
3455   [(set (match_operand:SF 0 "register_operand" "=f")
3456         (float_truncate:SF
3457          (match_operand:TF 1 "register_operand" "e")))]
3458   "TARGET_FPU && TARGET_HARD_QUAD"
3459   "fqtos\t%1, %0"
3460   [(set_attr "type" "fp")])
3462 (define_expand "trunctfdf2"
3463   [(set (match_operand:DF 0 "register_operand" "")
3464         (float_truncate:DF
3465          (match_operand:TF 1 "general_operand" "")))]
3466   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3467   "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3469 (define_insn "*trunctfdf2_hq"
3470   [(set (match_operand:DF 0 "register_operand" "=e")
3471         (float_truncate:DF
3472          (match_operand:TF 1 "register_operand" "e")))]
3473   "TARGET_FPU && TARGET_HARD_QUAD"
3474   "fqtod\t%1, %0"
3475   [(set_attr "type" "fp")])
3478 ;; Conversion between fixed point and floating point.
3480 (define_insn "floatsisf2"
3481   [(set (match_operand:SF 0 "register_operand" "=f")
3482         (float:SF (match_operand:SI 1 "register_operand" "f")))]
3483   "TARGET_FPU"
3484   "fitos\t%1, %0"
3485   [(set_attr "type" "fp")
3486    (set_attr "fptype" "single")])
3488 (define_insn "floatsidf2"
3489   [(set (match_operand:DF 0 "register_operand" "=e")
3490         (float:DF (match_operand:SI 1 "register_operand" "f")))]
3491   "TARGET_FPU"
3492   "fitod\t%1, %0"
3493   [(set_attr "type" "fp")
3494    (set_attr "fptype" "double")])
3496 (define_expand "floatsitf2"
3497   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3498         (float:TF (match_operand:SI 1 "register_operand" "")))]
3499   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3500   "emit_tfmode_cvt (FLOAT, operands); DONE;")
3502 (define_insn "*floatsitf2_hq"
3503   [(set (match_operand:TF 0 "register_operand" "=e")
3504         (float:TF (match_operand:SI 1 "register_operand" "f")))]
3505   "TARGET_FPU && TARGET_HARD_QUAD"
3506   "fitoq\t%1, %0"
3507   [(set_attr "type" "fp")])
3509 (define_expand "floatunssitf2"
3510   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3511         (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
3512   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3513   "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3515 ;; Now the same for 64 bit sources.
3517 (define_insn "floatdisf2"
3518   [(set (match_operand:SF 0 "register_operand" "=f")
3519         (float:SF (match_operand:DI 1 "register_operand" "e")))]
3520   "TARGET_V9 && TARGET_FPU"
3521   "fxtos\t%1, %0"
3522   [(set_attr "type" "fp")
3523    (set_attr "fptype" "double")])
3525 (define_expand "floatunsdisf2"
3526   [(use (match_operand:SF 0 "register_operand" ""))
3527    (use (match_operand:DI 1 "general_operand" ""))]
3528   "TARGET_ARCH64 && TARGET_FPU"
3529   "sparc_emit_floatunsdi (operands, SFmode); DONE;")
3531 (define_insn "floatdidf2"
3532   [(set (match_operand:DF 0 "register_operand" "=e")
3533         (float:DF (match_operand:DI 1 "register_operand" "e")))]
3534   "TARGET_V9 && TARGET_FPU"
3535   "fxtod\t%1, %0"
3536   [(set_attr "type" "fp")
3537    (set_attr "fptype" "double")])
3539 (define_expand "floatunsdidf2"
3540   [(use (match_operand:DF 0 "register_operand" ""))
3541    (use (match_operand:DI 1 "general_operand" ""))]
3542   "TARGET_ARCH64 && TARGET_FPU"
3543   "sparc_emit_floatunsdi (operands, DFmode); DONE;")
3545 (define_expand "floatditf2"
3546   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3547         (float:TF (match_operand:DI 1 "register_operand" "")))]
3548   "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3549   "emit_tfmode_cvt (FLOAT, operands); DONE;")
3551 (define_insn "*floatditf2_hq"
3552   [(set (match_operand:TF 0 "register_operand" "=e")
3553         (float:TF (match_operand:DI 1 "register_operand" "e")))]
3554   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3555   "fxtoq\t%1, %0"
3556   [(set_attr "type" "fp")])
3558 (define_expand "floatunsditf2"
3559   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3560         (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
3561   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3562   "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3564 ;; Convert a float to an actual integer.
3565 ;; Truncation is performed as part of the conversion.
3567 (define_insn "fix_truncsfsi2"
3568   [(set (match_operand:SI 0 "register_operand" "=f")
3569         (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3570   "TARGET_FPU"
3571   "fstoi\t%1, %0"
3572   [(set_attr "type" "fp")
3573    (set_attr "fptype" "single")])
3575 (define_insn "fix_truncdfsi2"
3576   [(set (match_operand:SI 0 "register_operand" "=f")
3577         (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3578   "TARGET_FPU"
3579   "fdtoi\t%1, %0"
3580   [(set_attr "type" "fp")
3581    (set_attr "fptype" "double")
3582    (set_attr "fptype_ut699" "single")])
3584 (define_expand "fix_trunctfsi2"
3585   [(set (match_operand:SI 0 "register_operand" "")
3586         (fix:SI (match_operand:TF 1 "general_operand" "")))]
3587   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3588   "emit_tfmode_cvt (FIX, operands); DONE;")
3590 (define_insn "*fix_trunctfsi2_hq"
3591   [(set (match_operand:SI 0 "register_operand" "=f")
3592         (fix:SI (match_operand:TF 1 "register_operand" "e")))]
3593   "TARGET_FPU && TARGET_HARD_QUAD"
3594   "fqtoi\t%1, %0"
3595   [(set_attr "type" "fp")])
3597 (define_expand "fixuns_trunctfsi2"
3598   [(set (match_operand:SI 0 "register_operand" "")
3599         (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
3600   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3601   "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3603 ;; Now the same, for V9 targets
3605 (define_insn "fix_truncsfdi2"
3606   [(set (match_operand:DI 0 "register_operand" "=e")
3607         (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3608   "TARGET_V9 && TARGET_FPU"
3609   "fstox\t%1, %0"
3610   [(set_attr "type" "fp")
3611    (set_attr "fptype" "double")])
3613 (define_expand "fixuns_truncsfdi2"
3614   [(use (match_operand:DI 0 "register_operand" ""))
3615    (use (match_operand:SF 1 "general_operand" ""))]
3616   "TARGET_ARCH64 && TARGET_FPU"
3617   "sparc_emit_fixunsdi (operands, SFmode); DONE;")
3619 (define_insn "fix_truncdfdi2"
3620   [(set (match_operand:DI 0 "register_operand" "=e")
3621         (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3622   "TARGET_V9 && TARGET_FPU"
3623   "fdtox\t%1, %0"
3624   [(set_attr "type" "fp")
3625    (set_attr "fptype" "double")])
3627 (define_expand "fixuns_truncdfdi2"
3628   [(use (match_operand:DI 0 "register_operand" ""))
3629    (use (match_operand:DF 1 "general_operand" ""))]
3630   "TARGET_ARCH64 && TARGET_FPU"
3631   "sparc_emit_fixunsdi (operands, DFmode); DONE;")
3633 (define_expand "fix_trunctfdi2"
3634   [(set (match_operand:DI 0 "register_operand" "")
3635         (fix:DI (match_operand:TF 1 "general_operand" "")))]
3636   "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3637   "emit_tfmode_cvt (FIX, operands); DONE;")
3639 (define_insn "*fix_trunctfdi2_hq"
3640   [(set (match_operand:DI 0 "register_operand" "=e")
3641         (fix:DI (match_operand:TF 1 "register_operand" "e")))]
3642   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3643   "fqtox\t%1, %0"
3644   [(set_attr "type" "fp")])
3646 (define_expand "fixuns_trunctfdi2"
3647   [(set (match_operand:DI 0 "register_operand" "")
3648         (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
3649   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3650   "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3653 ;; Integer addition/subtraction instructions.
3655 (define_expand "adddi3"
3656   [(set (match_operand:DI 0 "register_operand" "")
3657         (plus:DI (match_operand:DI 1 "register_operand" "")
3658                  (match_operand:DI 2 "arith_double_add_operand" "")))]
3659   ""
3661   if (! TARGET_ARCH64)
3662     {
3663       emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3664                           gen_rtx_SET (operands[0],
3665                                    gen_rtx_PLUS (DImode, operands[1],
3666                                                  operands[2])),
3667                           gen_rtx_CLOBBER (VOIDmode,
3668                                    gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3669       DONE;
3670     }
3673 (define_insn_and_split "*adddi3_insn_sp32"
3674   [(set (match_operand:DI 0 "register_operand" "=&r")
3675         (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
3676                  (match_operand:DI 2 "arith_double_operand" "rHI")))
3677    (clobber (reg:CC CC_REG))]
3678   "! TARGET_ARCH64"
3679   "#"
3680   "&& reload_completed"
3681   [(parallel [(set (reg:CC_NOOV CC_REG)
3682                    (compare:CC_NOOV (plus:SI (match_dup 4)
3683                                              (match_dup 5))
3684                                     (const_int 0)))
3685               (set (match_dup 3)
3686                    (plus:SI (match_dup 4) (match_dup 5)))])
3687    (set (match_dup 6)
3688         (plus:SI (plus:SI (match_dup 7)
3689                           (match_dup 8))
3690                  (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3692   operands[3] = gen_lowpart (SImode, operands[0]);
3693   operands[4] = gen_lowpart (SImode, operands[1]);
3694   operands[5] = gen_lowpart (SImode, operands[2]);
3695   operands[6] = gen_highpart (SImode, operands[0]);
3696   operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
3697 #if HOST_BITS_PER_WIDE_INT == 32
3698   if (GET_CODE (operands[2]) == CONST_INT)
3699     {
3700       if (INTVAL (operands[2]) < 0)
3701         operands[8] = constm1_rtx;
3702       else
3703         operands[8] = const0_rtx;
3704     }
3705   else
3706 #endif
3707     operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3709   [(set_attr "length" "2")])
3711 ;; LTU here means "carry set"
3712 (define_insn "addx"
3713   [(set (match_operand:SI 0 "register_operand" "=r")
3714         (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3715                           (match_operand:SI 2 "arith_operand" "rI"))
3716                  (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3717   ""
3718   "addx\t%1, %2, %0"
3719   [(set_attr "type" "ialuX")])
3721 (define_insn "addxc"
3722   [(set (match_operand:DI 0 "register_operand" "=r")
3723         (plus:DI (plus:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
3724                           (match_operand:DI 2 "register_or_zero_operand" "rJ"))
3725                  (ltu:DI (reg:CCX_NOOV CC_REG) (const_int 0))))]
3726   "TARGET_ARCH64 && TARGET_VIS3"
3727   "addxc\t%r1, %r2, %0"
3728   [(set_attr "type" "ialuX")])
3730 (define_insn_and_split "*addx_extend_sp32"
3731   [(set (match_operand:DI 0 "register_operand" "=r")
3732         (zero_extend:DI (plus:SI (plus:SI
3733                                   (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3734                                   (match_operand:SI 2 "arith_operand" "rI"))
3735                                  (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3736   "! TARGET_ARCH64"
3737   "#"
3738   "&& reload_completed"
3739   [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
3740                                (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))
3741    (set (match_dup 4) (const_int 0))]
3742   "operands[3] = gen_lowpart (SImode, operands[0]);
3743    operands[4] = gen_highpart (SImode, operands[0]);"
3744   [(set_attr "length" "2")])
3746 (define_insn "*addx_extend_sp64"
3747   [(set (match_operand:DI 0 "register_operand" "=r")
3748         (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3749                                           (match_operand:SI 2 "register_or_zero_operand" "rJ"))
3750                                  (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3751   "TARGET_ARCH64"
3752   "addx\t%r1, %r2, %0"
3753   [(set_attr "type" "ialuX")])
3755 (define_insn "*addxc_trunc_sp64_vis3"
3756   [(set (match_operand:SI 0 "register_operand" "=r")
3757         (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3758                           (match_operand:SI 2 "register_or_zero_operand" "rJ"))
3759                  (ltu:SI (reg:CCX_NOOV CC_REG) (const_int 0))))]
3760   "TARGET_ARCH64 && TARGET_VIS3"
3761   "addxc\t%r1, %r2, %0"
3762   [(set_attr "type" "ialuX")])
3764 (define_insn_and_split "*adddi3_extend_sp32"
3765   [(set (match_operand:DI 0 "register_operand" "=&r")
3766         (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
3767                  (match_operand:DI 2 "register_operand" "r")))
3768    (clobber (reg:CC CC_REG))]
3769   "! TARGET_ARCH64"
3770   "#"
3771   "&& reload_completed"
3772   [(parallel [(set (reg:CC_NOOV CC_REG)
3773                    (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
3774                                     (const_int 0)))
3775               (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
3776    (set (match_dup 6)
3777         (plus:SI (plus:SI (match_dup 4) (const_int 0))
3778                  (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3779   "operands[3] = gen_lowpart (SImode, operands[2]);
3780    operands[4] = gen_highpart (SImode, operands[2]);
3781    operands[5] = gen_lowpart (SImode, operands[0]);
3782    operands[6] = gen_highpart (SImode, operands[0]);"
3783   [(set_attr "length" "2")])
3785 (define_insn "*adddi3_sp64"
3786   [(set (match_operand:DI 0 "register_operand" "=r,r")
3787         (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
3788                  (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3789   "TARGET_ARCH64"
3790   "@
3791    add\t%1, %2, %0
3792    sub\t%1, -%2, %0")
3794 (define_insn "addsi3"
3795   [(set (match_operand:SI 0 "register_operand" "=r,r")
3796         (plus:SI (match_operand:SI 1 "register_operand" "%r,r")
3797                  (match_operand:SI 2 "arith_add_operand" "rI,O")))]
3798   ""
3799   "@
3800    add\t%1, %2, %0
3801    sub\t%1, -%2, %0"
3802   [(set_attr "type" "*,*")
3803    (set_attr "fptype" "*,*")])
3805 (define_insn "*cmp_cc_plus"
3806   [(set (reg:CC_NOOV CC_REG)
3807         (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
3808                                   (match_operand:SI 1 "arith_operand" "rI"))
3809                          (const_int 0)))]
3810   ""
3811   "addcc\t%0, %1, %%g0"
3812   [(set_attr "type" "compare")])
3814 (define_insn "*cmp_ccx_plus"
3815   [(set (reg:CCX_NOOV CC_REG)
3816         (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_operand" "%r")
3817                                    (match_operand:DI 1 "arith_operand" "rI"))
3818                           (const_int 0)))]
3819   "TARGET_ARCH64"
3820   "addcc\t%0, %1, %%g0"
3821   [(set_attr "type" "compare")])
3823 (define_insn "*cmp_cc_plus_set"
3824   [(set (reg:CC_NOOV CC_REG)
3825         (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3826                                   (match_operand:SI 2 "arith_operand" "rI"))
3827                          (const_int 0)))
3828    (set (match_operand:SI 0 "register_operand" "=r")
3829         (plus:SI (match_dup 1) (match_dup 2)))]
3830   ""
3831   "addcc\t%1, %2, %0"
3832   [(set_attr "type" "compare")])
3834 (define_insn "*cmp_ccx_plus_set"
3835   [(set (reg:CCX_NOOV CC_REG)
3836         (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_operand" "%r")
3837                                    (match_operand:DI 2 "arith_operand" "rI"))
3838                           (const_int 0)))
3839    (set (match_operand:DI 0 "register_operand" "=r")
3840         (plus:DI (match_dup 1) (match_dup 2)))]
3841   "TARGET_ARCH64"
3842   "addcc\t%1, %2, %0"
3843   [(set_attr "type" "compare")])
3845 (define_expand "subdi3"
3846   [(set (match_operand:DI 0 "register_operand" "")
3847         (minus:DI (match_operand:DI 1 "register_operand" "")
3848                   (match_operand:DI 2 "arith_double_add_operand" "")))]
3849   ""
3851   if (! TARGET_ARCH64)
3852     {
3853       emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3854                           gen_rtx_SET (operands[0],
3855                                    gen_rtx_MINUS (DImode, operands[1],
3856                                                   operands[2])),
3857                           gen_rtx_CLOBBER (VOIDmode,
3858                                    gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3859       DONE;
3860     }
3863 (define_insn_and_split "*subdi3_insn_sp32"
3864   [(set (match_operand:DI 0 "register_operand" "=&r")
3865         (minus:DI (match_operand:DI 1 "register_operand" "r")
3866                   (match_operand:DI 2 "arith_double_operand" "rHI")))
3867    (clobber (reg:CC CC_REG))]
3868   "! TARGET_ARCH64"
3869   "#"
3870   "&& reload_completed"
3871   [(parallel [(set (reg:CC_NOOV CC_REG)
3872                    (compare:CC_NOOV (minus:SI (match_dup 4)
3873                                               (match_dup 5))
3874                                     (const_int 0)))
3875               (set (match_dup 3)
3876                    (minus:SI (match_dup 4) (match_dup 5)))])
3877    (set (match_dup 6)
3878         (minus:SI (minus:SI (match_dup 7)
3879                             (match_dup 8))
3880                   (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3882   operands[3] = gen_lowpart (SImode, operands[0]);
3883   operands[4] = gen_lowpart (SImode, operands[1]);
3884   operands[5] = gen_lowpart (SImode, operands[2]);
3885   operands[6] = gen_highpart (SImode, operands[0]);
3886   operands[7] = gen_highpart (SImode, operands[1]);
3887 #if HOST_BITS_PER_WIDE_INT == 32
3888   if (GET_CODE (operands[2]) == CONST_INT)
3889     {
3890       if (INTVAL (operands[2]) < 0)
3891         operands[8] = constm1_rtx;
3892       else
3893         operands[8] = const0_rtx;
3894     }
3895   else
3896 #endif
3897     operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3899   [(set_attr "length" "2")])
3901 ;; LTU here means "carry set"
3902 (define_insn "subx"
3903   [(set (match_operand:SI 0 "register_operand" "=r")
3904         (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3905                             (match_operand:SI 2 "arith_operand" "rI"))
3906                   (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3907   ""
3908   "subx\t%r1, %2, %0"
3909   [(set_attr "type" "ialuX")])
3911 (define_insn "*subx_extend_sp64"
3912   [(set (match_operand:DI 0 "register_operand" "=r")
3913         (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3914                                             (match_operand:SI 2 "arith_operand" "rI"))
3915                                   (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3916   "TARGET_ARCH64"
3917   "subx\t%r1, %2, %0"
3918   [(set_attr "type" "ialuX")])
3920 (define_insn_and_split "*subx_extend_sp32"
3921   [(set (match_operand:DI 0 "register_operand" "=r")
3922         (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3923                                             (match_operand:SI 2 "arith_operand" "rI"))
3924                                   (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3925   "! TARGET_ARCH64"
3926   "#"
3927   "&& reload_completed"
3928   [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
3929                                 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))
3930    (set (match_dup 4) (const_int 0))]
3931   "operands[3] = gen_lowpart (SImode, operands[0]);
3932    operands[4] = gen_highpart (SImode, operands[0]);"
3933   [(set_attr "length" "2")])
3935 (define_insn_and_split "*subdi3_extend_sp32"
3936   [(set (match_operand:DI 0 "register_operand" "=&r")
3937       (minus:DI (match_operand:DI 1 "register_operand" "r")
3938                 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
3939    (clobber (reg:CC CC_REG))]
3940   "! TARGET_ARCH64"
3941   "#"
3942   "&& reload_completed"
3943   [(parallel [(set (reg:CC_NOOV CC_REG)
3944                    (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
3945                                     (const_int 0)))
3946               (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
3947    (set (match_dup 6)
3948         (minus:SI (minus:SI (match_dup 4) (const_int 0))
3949                   (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3950   "operands[3] = gen_lowpart (SImode, operands[1]);
3951    operands[4] = gen_highpart (SImode, operands[1]);
3952    operands[5] = gen_lowpart (SImode, operands[0]);
3953    operands[6] = gen_highpart (SImode, operands[0]);"
3954   [(set_attr "length" "2")])
3956 (define_insn "*subdi3_sp64"
3957   [(set (match_operand:DI 0 "register_operand" "=r,r")
3958         (minus:DI (match_operand:DI 1 "register_operand" "r,r")
3959                   (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3960   "TARGET_ARCH64"
3961   "@
3962    sub\t%1, %2, %0
3963    add\t%1, -%2, %0")
3965 (define_insn "subsi3"
3966   [(set (match_operand:SI 0 "register_operand" "=r,r")
3967         (minus:SI (match_operand:SI 1 "register_operand" "r,r")
3968                   (match_operand:SI 2 "arith_add_operand" "rI,O")))]
3969   ""
3970   "@
3971    sub\t%1, %2, %0
3972    add\t%1, -%2, %0"
3973   [(set_attr "type" "*,*")
3974    (set_attr "fptype" "*,*")])
3976 (define_insn "*cmp_minus_cc"
3977   [(set (reg:CC_NOOV CC_REG)
3978         (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
3979                                    (match_operand:SI 1 "arith_operand" "rI"))
3980                          (const_int 0)))]
3981   ""
3982   "subcc\t%r0, %1, %%g0"
3983   [(set_attr "type" "compare")])
3985 (define_insn "*cmp_minus_ccx"
3986   [(set (reg:CCX_NOOV CC_REG)
3987         (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
3988                                     (match_operand:DI 1 "arith_operand" "rI"))
3989                           (const_int 0)))]
3990   "TARGET_ARCH64"
3991   "subcc\t%0, %1, %%g0"
3992   [(set_attr "type" "compare")])
3994 (define_insn "cmp_minus_cc_set"
3995   [(set (reg:CC_NOOV CC_REG)
3996         (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3997                                    (match_operand:SI 2 "arith_operand" "rI"))
3998                          (const_int 0)))
3999    (set (match_operand:SI 0 "register_operand" "=r")
4000         (minus:SI (match_dup 1) (match_dup 2)))]
4001   ""
4002   "subcc\t%r1, %2, %0"
4003   [(set_attr "type" "compare")])
4005 (define_insn "*cmp_minus_ccx_set"
4006   [(set (reg:CCX_NOOV CC_REG)
4007         (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
4008                                     (match_operand:DI 2 "arith_operand" "rI"))
4009                           (const_int 0)))
4010    (set (match_operand:DI 0 "register_operand" "=r")
4011         (minus:DI (match_dup 1) (match_dup 2)))]
4012   "TARGET_ARCH64"
4013   "subcc\t%1, %2, %0"
4014   [(set_attr "type" "compare")])
4017 ;; Integer multiply/divide instructions.
4019 ;; The 32-bit multiply/divide instructions are deprecated on v9, but at
4020 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
4022 (define_insn "mulsi3"
4023   [(set (match_operand:SI 0 "register_operand" "=r")
4024         (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4025                  (match_operand:SI 2 "arith_operand" "rI")))]
4026   "TARGET_HARD_MUL"
4027   "smul\t%1, %2, %0"
4028   [(set_attr "type" "imul")])
4030 (define_expand "muldi3"
4031   [(set (match_operand:DI 0 "register_operand" "")
4032         (mult:DI (match_operand:DI 1 "arith_operand" "")
4033                  (match_operand:DI 2 "arith_operand" "")))]
4034   "TARGET_ARCH64 || TARGET_V8PLUS"
4036   if (TARGET_V8PLUS)
4037     {
4038       emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
4039       DONE;
4040     }
4043 (define_insn "*muldi3_sp64"
4044   [(set (match_operand:DI 0 "register_operand" "=r")
4045         (mult:DI (match_operand:DI 1 "arith_operand" "%r")
4046                  (match_operand:DI 2 "arith_operand" "rI")))]
4047   "TARGET_ARCH64"
4048   "mulx\t%1, %2, %0"
4049   [(set_attr "type" "imul")])
4051 ;; V8plus wide multiply.
4052 ;; XXX
4053 (define_insn "muldi3_v8plus"
4054   [(set (match_operand:DI 0 "register_operand" "=r,h")
4055         (mult:DI (match_operand:DI 1 "arith_operand" "%r,0")
4056                  (match_operand:DI 2 "arith_operand" "rI,rI")))
4057    (clobber (match_scratch:SI 3 "=&h,X"))
4058    (clobber (match_scratch:SI 4 "=&h,X"))]
4059   "TARGET_V8PLUS"
4060   "* return output_v8plus_mult (insn, operands, \"mulx\");"
4061   [(set_attr "type" "multi")
4062    (set_attr "length" "9,8")])
4064 (define_insn "*cmp_mul_set"
4065   [(set (reg:CC CC_REG)
4066         (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4067                     (match_operand:SI 2 "arith_operand" "rI"))
4068                     (const_int 0)))
4069    (set (match_operand:SI 0 "register_operand" "=r")
4070         (mult:SI (match_dup 1) (match_dup 2)))]
4071   "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
4072   "smulcc\t%1, %2, %0"
4073   [(set_attr "type" "imul")])
4075 (define_expand "mulsidi3"
4076   [(set (match_operand:DI 0 "register_operand" "")
4077         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4078                  (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
4079   "TARGET_HARD_MUL"
4081   if (CONSTANT_P (operands[2]))
4082     {
4083       if (TARGET_V8PLUS)
4084         emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
4085                                               operands[2]));
4086       else if (TARGET_ARCH32)
4087         emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
4088                                             operands[2]));
4089       else 
4090         emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
4091                                             operands[2]));
4092       DONE;
4093     }
4094   if (TARGET_V8PLUS)
4095     {
4096       emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
4097       DONE;
4098     }
4101 ;; V9 puts the 64-bit product in a 64-bit register.  Only out or global
4102 ;; registers can hold 64-bit values in the V8plus environment.
4103 ;; XXX
4104 (define_insn "mulsidi3_v8plus"
4105   [(set (match_operand:DI 0 "register_operand" "=h,r")
4106         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4107                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4108    (clobber (match_scratch:SI 3 "=X,&h"))]
4109   "TARGET_V8PLUS"
4110   "@
4111    smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4112    smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4113   [(set_attr "type" "multi")
4114    (set_attr "length" "2,3")])
4116 ;; XXX
4117 (define_insn "const_mulsidi3_v8plus"
4118   [(set (match_operand:DI 0 "register_operand" "=h,r")
4119         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4120                  (match_operand:DI 2 "small_int_operand" "I,I")))
4121    (clobber (match_scratch:SI 3 "=X,&h"))]
4122   "TARGET_V8PLUS"
4123   "@
4124    smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4125    smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4126   [(set_attr "type" "multi")
4127    (set_attr "length" "2,3")])
4129 ;; XXX
4130 (define_insn "*mulsidi3_sp32"
4131   [(set (match_operand:DI 0 "register_operand" "=r")
4132         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4133                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4134   "TARGET_HARD_MUL32"
4136   return TARGET_SPARCLET
4137          ? "smuld\t%1, %2, %L0"
4138          : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4140   [(set (attr "type")
4141         (if_then_else (eq_attr "isa" "sparclet")
4142                       (const_string "imul") (const_string "multi")))
4143    (set (attr "length")
4144         (if_then_else (eq_attr "isa" "sparclet")
4145                       (const_int 1) (const_int 2)))])
4147 (define_insn "*mulsidi3_sp64"
4148   [(set (match_operand:DI 0 "register_operand" "=r")
4149         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4150                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4151   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4152   "smul\t%1, %2, %0"
4153   [(set_attr "type" "imul")])
4155 ;; Extra pattern, because sign_extend of a constant isn't valid.
4157 ;; XXX
4158 (define_insn "const_mulsidi3_sp32"
4159   [(set (match_operand:DI 0 "register_operand" "=r")
4160         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4161                  (match_operand:DI 2 "small_int_operand" "I")))]
4162   "TARGET_HARD_MUL32"
4164   return TARGET_SPARCLET
4165          ? "smuld\t%1, %2, %L0"
4166          : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4168   [(set (attr "type")
4169         (if_then_else (eq_attr "isa" "sparclet")
4170                       (const_string "imul") (const_string "multi")))
4171    (set (attr "length")
4172         (if_then_else (eq_attr "isa" "sparclet")
4173                       (const_int 1) (const_int 2)))])
4175 (define_insn "const_mulsidi3_sp64"
4176   [(set (match_operand:DI 0 "register_operand" "=r")
4177         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4178                  (match_operand:DI 2 "small_int_operand" "I")))]
4179   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4180   "smul\t%1, %2, %0"
4181   [(set_attr "type" "imul")])
4183 (define_expand "smulsi3_highpart"
4184   [(set (match_operand:SI 0 "register_operand" "")
4185         (truncate:SI
4186          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4187                                (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
4188                       (const_int 32))))]
4189   "TARGET_HARD_MUL && TARGET_ARCH32"
4191   if (CONSTANT_P (operands[2]))
4192     {
4193       if (TARGET_V8PLUS)
4194         {
4195           emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
4196                                                         operands[1],
4197                                                         operands[2],
4198                                                         GEN_INT (32)));
4199           DONE;
4200         }
4201       emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
4202       DONE;
4203     }
4204   if (TARGET_V8PLUS)
4205     {
4206       emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
4207                                               operands[2], GEN_INT (32)));
4208       DONE;
4209     }
4212 ;; XXX
4213 (define_insn "smulsi3_highpart_v8plus"
4214   [(set (match_operand:SI 0 "register_operand" "=h,r")
4215         (truncate:SI
4216          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4217                                (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4218                       (match_operand:SI 3 "small_int_operand" "I,I"))))
4219    (clobber (match_scratch:SI 4 "=X,&h"))]
4220   "TARGET_V8PLUS"
4221   "@
4222    smul\t%1, %2, %0\;srlx\t%0, %3, %0
4223    smul\t%1, %2, %4\;srlx\t%4, %3, %0"
4224   [(set_attr "type" "multi")
4225    (set_attr "length" "2")])
4227 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
4228 ;; XXX
4229 (define_insn ""
4230   [(set (match_operand:SI 0 "register_operand" "=h,r")
4231         (subreg:SI
4232          (lshiftrt:DI
4233           (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4234                    (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4235           (match_operand:SI 3 "small_int_operand" "I,I"))
4236          4))
4237    (clobber (match_scratch:SI 4 "=X,&h"))]
4238   "TARGET_V8PLUS"
4239   "@
4240    smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4241    smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4242   [(set_attr "type" "multi")
4243    (set_attr "length" "2")])
4245 ;; XXX
4246 (define_insn "const_smulsi3_highpart_v8plus"
4247   [(set (match_operand:SI 0 "register_operand" "=h,r")
4248         (truncate:SI
4249          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4250                                (match_operand:DI 2 "small_int_operand" "I,I"))
4251                       (match_operand:SI 3 "small_int_operand" "I,I"))))
4252    (clobber (match_scratch:SI 4 "=X,&h"))]
4253   "TARGET_V8PLUS"
4254   "@
4255    smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4256    smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4257   [(set_attr "type" "multi")
4258    (set_attr "length" "2")])
4260 ;; XXX
4261 (define_insn "*smulsi3_highpart_sp32"
4262   [(set (match_operand:SI 0 "register_operand" "=r")
4263         (truncate:SI
4264          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4265                                (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
4266                       (const_int 32))))]
4267   "TARGET_HARD_MUL32"
4268   "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4269   [(set_attr "type" "multi")
4270    (set_attr "length" "2")])
4272 ;; XXX
4273 (define_insn "const_smulsi3_highpart"
4274   [(set (match_operand:SI 0 "register_operand" "=r")
4275         (truncate:SI
4276          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4277                                (match_operand:DI 2 "small_int_operand" "i"))
4278                       (const_int 32))))]
4279   "TARGET_HARD_MUL32"
4280   "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4281   [(set_attr "type" "multi")
4282    (set_attr "length" "2")])
4284 (define_expand "umulsidi3"
4285   [(set (match_operand:DI 0 "register_operand" "")
4286         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4287                  (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
4288   "TARGET_HARD_MUL"
4290   if (CONSTANT_P (operands[2]))
4291     {
4292       if (TARGET_V8PLUS)
4293         emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
4294                                                operands[2]));
4295       else if (TARGET_ARCH32)
4296         emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
4297                                              operands[2]));
4298       else 
4299         emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
4300                                              operands[2]));
4301       DONE;
4302     }
4303   if (TARGET_V8PLUS)
4304     {
4305       emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
4306       DONE;
4307     }
4310 ;; XXX
4311 (define_insn "umulsidi3_v8plus"
4312   [(set (match_operand:DI 0 "register_operand" "=h,r")
4313         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4314                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4315    (clobber (match_scratch:SI 3 "=X,&h"))]
4316   "TARGET_V8PLUS"
4317   "@
4318    umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4319    umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4320   [(set_attr "type" "multi")
4321    (set_attr "length" "2,3")])
4323 ;; XXX
4324 (define_insn "*umulsidi3_sp32"
4325   [(set (match_operand:DI 0 "register_operand" "=r")
4326         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4327                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4328   "TARGET_HARD_MUL32"
4330   return TARGET_SPARCLET
4331          ? "umuld\t%1, %2, %L0"
4332          : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
4334   [(set (attr "type")
4335         (if_then_else (eq_attr "isa" "sparclet")
4336                       (const_string "imul") (const_string "multi")))
4337    (set (attr "length")
4338         (if_then_else (eq_attr "isa" "sparclet")
4339                       (const_int 1) (const_int 2)))])
4341 (define_insn "*umulsidi3_sp64"
4342   [(set (match_operand:DI 0 "register_operand" "=r")
4343         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4344                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4345   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4346   "umul\t%1, %2, %0"
4347   [(set_attr "type" "imul")])
4349 ;; Extra pattern, because sign_extend of a constant isn't valid.
4351 ;; XXX
4352 (define_insn "const_umulsidi3_sp32"
4353   [(set (match_operand:DI 0 "register_operand" "=r")
4354         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4355                  (match_operand:DI 2 "uns_small_int_operand" "")))]
4356   "TARGET_HARD_MUL32"
4358   return TARGET_SPARCLET
4359          ? "umuld\t%1, %s2, %L0"
4360          : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
4362   [(set (attr "type")
4363         (if_then_else (eq_attr "isa" "sparclet")
4364                       (const_string "imul") (const_string "multi")))
4365    (set (attr "length")
4366         (if_then_else (eq_attr "isa" "sparclet")
4367                       (const_int 1) (const_int 2)))])
4369 (define_insn "const_umulsidi3_sp64"
4370   [(set (match_operand:DI 0 "register_operand" "=r")
4371         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4372                  (match_operand:DI 2 "uns_small_int_operand" "")))]
4373   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4374   "umul\t%1, %s2, %0"
4375   [(set_attr "type" "imul")])
4377 ;; XXX
4378 (define_insn "const_umulsidi3_v8plus"
4379   [(set (match_operand:DI 0 "register_operand" "=h,r")
4380         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4381                  (match_operand:DI 2 "uns_small_int_operand" "")))
4382    (clobber (match_scratch:SI 3 "=X,h"))]
4383   "TARGET_V8PLUS"
4384   "@
4385    umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
4386    umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4387   [(set_attr "type" "multi")
4388    (set_attr "length" "2,3")])
4390 (define_expand "umulsi3_highpart"
4391   [(set (match_operand:SI 0 "register_operand" "")
4392         (truncate:SI
4393          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4394                                (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
4395                       (const_int 32))))]
4396   "TARGET_HARD_MUL && TARGET_ARCH32"
4398   if (CONSTANT_P (operands[2]))
4399     {
4400       if (TARGET_V8PLUS)
4401         {
4402           emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
4403                                                         operands[1],
4404                                                         operands[2],
4405                                                         GEN_INT (32)));
4406           DONE;
4407         }
4408       emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
4409       DONE;
4410     }
4411   if (TARGET_V8PLUS)
4412     {
4413       emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
4414                                               operands[2], GEN_INT (32)));
4415       DONE;
4416     }
4419 ;; XXX
4420 (define_insn "umulsi3_highpart_v8plus"
4421   [(set (match_operand:SI 0 "register_operand" "=h,r")
4422         (truncate:SI
4423          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4424                                (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4425                       (match_operand:SI 3 "small_int_operand" "I,I"))))
4426    (clobber (match_scratch:SI 4 "=X,h"))]
4427   "TARGET_V8PLUS"
4428   "@
4429    umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4430    umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4431   [(set_attr "type" "multi")
4432    (set_attr "length" "2")])
4434 ;; XXX
4435 (define_insn "const_umulsi3_highpart_v8plus"
4436   [(set (match_operand:SI 0 "register_operand" "=h,r")
4437         (truncate:SI
4438          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4439                                (match_operand:DI 2 "uns_small_int_operand" ""))
4440                       (match_operand:SI 3 "small_int_operand" "I,I"))))
4441    (clobber (match_scratch:SI 4 "=X,h"))]
4442   "TARGET_V8PLUS"
4443   "@
4444    umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
4445    umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
4446   [(set_attr "type" "multi")
4447    (set_attr "length" "2")])
4449 ;; XXX
4450 (define_insn "*umulsi3_highpart_sp32"
4451   [(set (match_operand:SI 0 "register_operand" "=r")
4452         (truncate:SI
4453          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4454                                (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
4455                       (const_int 32))))]
4456   "TARGET_HARD_MUL32"
4457   "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
4458   [(set_attr "type" "multi")
4459    (set_attr "length" "2")])
4461 ;; XXX
4462 (define_insn "const_umulsi3_highpart"
4463   [(set (match_operand:SI 0 "register_operand" "=r")
4464         (truncate:SI
4465          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4466                                (match_operand:DI 2 "uns_small_int_operand" ""))
4467                       (const_int 32))))]
4468   "TARGET_HARD_MUL32"
4469   "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
4470   [(set_attr "type" "multi")
4471    (set_attr "length" "2")])
4473 (define_expand "divsi3"
4474   [(parallel [(set (match_operand:SI 0 "register_operand" "")
4475                    (div:SI (match_operand:SI 1 "register_operand" "")
4476                            (match_operand:SI 2 "input_operand" "")))
4477               (clobber (match_scratch:SI 3 ""))])]
4478   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4480   if (TARGET_ARCH64)
4481     {
4482       operands[3] = gen_reg_rtx(SImode);
4483       emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
4484       emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
4485                                   operands[3]));
4486       DONE;
4487     }
4490 ;; The V8 architecture specifies that there must be at least 3 instructions
4491 ;; between a write to the Y register and a use of it for correct results.
4492 ;; We try to fill one of them with a simple constant or a memory load.
4494 (define_insn "divsi3_sp32"
4495   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
4496         (div:SI (match_operand:SI 1 "register_operand" "r,r,r")
4497                 (match_operand:SI 2 "input_operand" "rI,K,m")))
4498    (clobber (match_scratch:SI 3 "=&r,&r,&r"))]
4499   "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4501   output_asm_insn ("sra\t%1, 31, %3", operands);
4502   output_asm_insn ("wr\t%3, 0, %%y", operands);
4504   switch (which_alternative)
4505     {
4506     case 0:
4507       if (TARGET_V9)
4508         return "sdiv\t%1, %2, %0";
4509       else
4510         return "nop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
4511     case 1:
4512       if (TARGET_V9)
4513         return "sethi\t%%hi(%a2), %3\n\tsdiv\t%1, %3, %0";
4514       else
4515         return "sethi\t%%hi(%a2), %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4516     case 2:
4517       if (TARGET_V9)
4518         return "ld\t%2, %3\n\tsdiv\t%1, %3, %0";
4519       else
4520         return "ld\t%2, %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4521     default:
4522       gcc_unreachable ();
4523     }
4525   [(set_attr "type" "multi")
4526    (set (attr "length")
4527         (if_then_else (eq_attr "isa" "v9")
4528                       (const_int 4) (const_int 6)))])
4530 (define_insn "divsi3_sp64"
4531   [(set (match_operand:SI 0 "register_operand" "=r")
4532         (div:SI (match_operand:SI 1 "register_operand" "r")
4533                 (match_operand:SI 2 "input_operand" "rI")))
4534    (use (match_operand:SI 3 "register_operand" "r"))]
4535   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4536   "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
4537   [(set_attr "type" "multi")
4538    (set_attr "length" "2")])
4540 (define_insn "divdi3"
4541   [(set (match_operand:DI 0 "register_operand" "=r")
4542         (div:DI (match_operand:DI 1 "register_operand" "r")
4543                 (match_operand:DI 2 "arith_operand" "rI")))]
4544   "TARGET_ARCH64"
4545   "sdivx\t%1, %2, %0"
4546   [(set_attr "type" "idiv")])
4548 (define_insn "*cmp_sdiv_cc_set"
4549   [(set (reg:CC CC_REG)
4550         (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
4551                             (match_operand:SI 2 "arith_operand" "rI"))
4552                     (const_int 0)))
4553    (set (match_operand:SI 0 "register_operand" "=r")
4554         (div:SI (match_dup 1) (match_dup 2)))
4555    (clobber (match_scratch:SI 3 "=&r"))]
4556   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4558   output_asm_insn ("sra\t%1, 31, %3", operands);
4559   output_asm_insn ("wr\t%3, 0, %%y", operands);
4561   if (TARGET_V9)
4562     return "sdivcc\t%1, %2, %0";
4563   else
4564     return "nop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
4566   [(set_attr "type" "multi")
4567    (set (attr "length")
4568         (if_then_else (eq_attr "isa" "v9")
4569                       (const_int 3) (const_int 6)))])
4571 ;; XXX
4572 (define_expand "udivsi3"
4573   [(set (match_operand:SI 0 "register_operand" "")
4574         (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "")
4575                  (match_operand:SI 2 "input_operand" "")))]
4576   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4577   "")
4579 ;; The V8 architecture specifies that there must be at least 3 instructions
4580 ;; between a write to the Y register and a use of it for correct results.
4581 ;; We try to fill one of them with a simple constant or a memory load.
4583 (define_insn "udivsi3_sp32"
4584   [(set (match_operand:SI 0 "register_operand" "=r,&r,&r,&r")
4585         (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r,r,r,m")
4586                  (match_operand:SI 2 "input_operand" "rI,K,m,r")))]
4587   "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4589   output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4591   switch (which_alternative)
4592     {
4593     case 0:
4594       if (TARGET_V9)
4595         return "udiv\t%1, %2, %0";
4596       else
4597         return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
4598     case 1:
4599       if (TARGET_V9)
4600         return "sethi\t%%hi(%a2), %0\n\tudiv\t%1, %0, %0";
4601       else
4602         return "sethi\t%%hi(%a2), %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4603     case 2:
4604       if (TARGET_V9)
4605         return "ld\t%2, %0\n\tudiv\t%1, %0, %0";
4606       else
4607         return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4608     case 3:
4609       if (TARGET_V9)
4610         return "ld\t%1, %0\n\tudiv\t%0, %2, %0";
4611       else
4612         return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
4613     default:
4614       gcc_unreachable ();
4615     }
4617   [(set_attr "type" "multi")
4618    (set (attr "length")
4619         (if_then_else (eq_attr "isa" "v9")
4620                       (const_int 3) (const_int 5)))])
4622 (define_insn "udivsi3_sp64"
4623   [(set (match_operand:SI 0 "register_operand" "=r")
4624         (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r")
4625                  (match_operand:SI 2 "input_operand" "rI")))]
4626   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4627   "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
4628   [(set_attr "type" "multi")
4629    (set_attr "length" "2")])
4631 (define_insn "udivdi3"
4632   [(set (match_operand:DI 0 "register_operand" "=r")
4633         (udiv:DI (match_operand:DI 1 "register_operand" "r")
4634                  (match_operand:DI 2 "arith_operand" "rI")))]
4635   "TARGET_ARCH64"
4636   "udivx\t%1, %2, %0"
4637   [(set_attr "type" "idiv")])
4639 (define_insn "*cmp_udiv_cc_set"
4640   [(set (reg:CC CC_REG)
4641         (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
4642                              (match_operand:SI 2 "arith_operand" "rI"))
4643                     (const_int 0)))
4644    (set (match_operand:SI 0 "register_operand" "=r")
4645         (udiv:SI (match_dup 1) (match_dup 2)))]
4646   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4648   output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4650   if (TARGET_V9)
4651     return "udivcc\t%1, %2, %0";
4652   else
4653     return "nop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
4655   [(set_attr "type" "multi")
4656    (set (attr "length")
4657         (if_then_else (eq_attr "isa" "v9")
4658                       (const_int 2) (const_int 5)))])
4660 ; sparclet multiply/accumulate insns
4662 (define_insn "*smacsi"
4663   [(set (match_operand:SI 0 "register_operand" "=r")
4664         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
4665                           (match_operand:SI 2 "arith_operand" "rI"))
4666                  (match_operand:SI 3 "register_operand" "0")))]
4667   "TARGET_SPARCLET"
4668   "smac\t%1, %2, %0"
4669   [(set_attr "type" "imul")])
4671 (define_insn "*smacdi"
4672   [(set (match_operand:DI 0 "register_operand" "=r")
4673         (plus:DI (mult:DI (sign_extend:DI
4674                            (match_operand:SI 1 "register_operand" "%r"))
4675                           (sign_extend:DI
4676                            (match_operand:SI 2 "register_operand" "r")))
4677                  (match_operand:DI 3 "register_operand" "0")))]
4678   "TARGET_SPARCLET"
4679   "smacd\t%1, %2, %L0"
4680   [(set_attr "type" "imul")])
4682 (define_insn "*umacdi"
4683   [(set (match_operand:DI 0 "register_operand" "=r")
4684         (plus:DI (mult:DI (zero_extend:DI
4685                            (match_operand:SI 1 "register_operand" "%r"))
4686                           (zero_extend:DI
4687                            (match_operand:SI 2 "register_operand" "r")))
4688                  (match_operand:DI 3 "register_operand" "0")))]
4689   "TARGET_SPARCLET"
4690   "umacd\t%1, %2, %L0"
4691   [(set_attr "type" "imul")])
4694 ;; Boolean instructions.
4696 ;; We define DImode `and' so with DImode `not' we can get
4697 ;; DImode `andn'.  Other combinations are possible.
4699 (define_expand "anddi3"
4700   [(set (match_operand:DI 0 "register_operand" "")
4701         (and:DI (match_operand:DI 1 "arith_double_operand" "")
4702                 (match_operand:DI 2 "arith_double_operand" "")))]
4703   ""
4704   "")
4706 (define_insn "*anddi3_sp32"
4707   [(set (match_operand:DI 0 "register_operand" "=r")
4708         (and:DI (match_operand:DI 1 "arith_double_operand" "%r")
4709                 (match_operand:DI 2 "arith_double_operand" "rHI")))]
4710   "! TARGET_ARCH64"
4711   "#")
4713 (define_insn "*anddi3_sp64"
4714   [(set (match_operand:DI 0 "register_operand" "=r")
4715         (and:DI (match_operand:DI 1 "arith_operand" "%r")
4716                 (match_operand:DI 2 "arith_operand" "rI")))]
4717   "TARGET_ARCH64"
4718   "and\t%1, %2, %0")
4720 (define_insn "andsi3"
4721   [(set (match_operand:SI 0 "register_operand" "=r")
4722         (and:SI (match_operand:SI 1 "arith_operand" "%r")
4723                 (match_operand:SI 2 "arith_operand" "rI")))]
4724   ""
4725   "and\t%1, %2, %0")
4727 (define_split
4728   [(set (match_operand:SI 0 "register_operand" "")
4729         (and:SI (match_operand:SI 1 "register_operand" "")
4730                 (match_operand:SI 2 "const_compl_high_operand" "")))
4731    (clobber (match_operand:SI 3 "register_operand" ""))]
4732   ""
4733   [(set (match_dup 3) (match_dup 4))
4734    (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
4736   operands[4] = GEN_INT (~INTVAL (operands[2]));
4739 (define_insn_and_split "*and_not_di_sp32"
4740   [(set (match_operand:DI 0 "register_operand" "=&r")
4741         (and:DI (not:DI (match_operand:DI 1 "register_operand" "%r"))
4742                 (match_operand:DI 2 "register_operand" "r")))]
4743   "! TARGET_ARCH64"
4744   "#"
4745   "&& reload_completed
4746    && ((GET_CODE (operands[0]) == REG
4747         && SPARC_INT_REG_P (REGNO (operands[0])))
4748        || (GET_CODE (operands[0]) == SUBREG
4749            && GET_CODE (SUBREG_REG (operands[0])) == REG
4750            && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
4751   [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
4752    (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
4753   "operands[3] = gen_highpart (SImode, operands[0]);
4754    operands[4] = gen_highpart (SImode, operands[1]);
4755    operands[5] = gen_highpart (SImode, operands[2]);
4756    operands[6] = gen_lowpart (SImode, operands[0]);
4757    operands[7] = gen_lowpart (SImode, operands[1]);
4758    operands[8] = gen_lowpart (SImode, operands[2]);"
4759   [(set_attr "length" "2")])
4761 (define_insn "*and_not_di_sp64"
4762   [(set (match_operand:DI 0 "register_operand" "=r")
4763         (and:DI (not:DI (match_operand:DI 1 "register_operand" "%r"))
4764                 (match_operand:DI 2 "register_operand" "r")))]
4765   "TARGET_ARCH64"
4766   "andn\t%2, %1, %0")
4768 (define_insn "*and_not_si"
4769   [(set (match_operand:SI 0 "register_operand" "=r")
4770         (and:SI (not:SI (match_operand:SI 1 "register_operand" "%r"))
4771                 (match_operand:SI 2 "register_operand" "r")))]
4772   ""
4773   "andn\t%2, %1, %0")
4775 (define_expand "iordi3"
4776   [(set (match_operand:DI 0 "register_operand" "")
4777         (ior:DI (match_operand:DI 1 "arith_double_operand" "")
4778                 (match_operand:DI 2 "arith_double_operand" "")))]
4779   ""
4780   "")
4782 (define_insn "*iordi3_sp32"
4783   [(set (match_operand:DI 0 "register_operand" "=r")
4784         (ior:DI (match_operand:DI 1 "arith_double_operand" "%r")
4785                 (match_operand:DI 2 "arith_double_operand" "rHI")))]
4786   "! TARGET_ARCH64"
4787   "#"
4788   [(set_attr "length" "2")])
4790 (define_insn "*iordi3_sp64"
4791   [(set (match_operand:DI 0 "register_operand" "=r")
4792         (ior:DI (match_operand:DI 1 "arith_operand" "%r")
4793                 (match_operand:DI 2 "arith_operand" "rI")))]
4794   "TARGET_ARCH64"
4795   "or\t%1, %2, %0")
4797 (define_insn "iorsi3"
4798   [(set (match_operand:SI 0 "register_operand" "=r")
4799         (ior:SI (match_operand:SI 1 "arith_operand" "%r")
4800                 (match_operand:SI 2 "arith_operand" "rI")))]
4801   ""
4802   "or\t%1, %2, %0")
4804 (define_split
4805   [(set (match_operand:SI 0 "register_operand" "")
4806         (ior:SI (match_operand:SI 1 "register_operand" "")
4807                 (match_operand:SI 2 "const_compl_high_operand" "")))
4808    (clobber (match_operand:SI 3 "register_operand" ""))]
4809   ""
4810   [(set (match_dup 3) (match_dup 4))
4811    (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
4813   operands[4] = gen_int_mode (~INTVAL (operands[2]), SImode);
4816 (define_insn_and_split "*or_not_di_sp32"
4817   [(set (match_operand:DI 0 "register_operand" "=&r")
4818         (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
4819                 (match_operand:DI 2 "register_operand" "r")))]
4820   "! TARGET_ARCH64"
4821   "#"
4822   "&& reload_completed
4823    && ((GET_CODE (operands[0]) == REG
4824         && SPARC_INT_REG_P (REGNO (operands[0])))
4825        || (GET_CODE (operands[0]) == SUBREG
4826            && GET_CODE (SUBREG_REG (operands[0])) == REG
4827            && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
4828   [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
4829    (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
4830   "operands[3] = gen_highpart (SImode, operands[0]);
4831    operands[4] = gen_highpart (SImode, operands[1]);
4832    operands[5] = gen_highpart (SImode, operands[2]);
4833    operands[6] = gen_lowpart (SImode, operands[0]);
4834    operands[7] = gen_lowpart (SImode, operands[1]);
4835    operands[8] = gen_lowpart (SImode, operands[2]);"
4836   [(set_attr "length" "2")])
4838 (define_insn "*or_not_di_sp64"
4839   [(set (match_operand:DI 0 "register_operand" "=r")
4840         (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
4841                 (match_operand:DI 2 "register_operand" "r")))]
4842   "TARGET_ARCH64"
4843   "orn\t%2, %1, %0")
4845 (define_insn "*or_not_si"
4846   [(set (match_operand:SI 0 "register_operand" "=r")
4847         (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
4848                 (match_operand:SI 2 "register_operand" "r")))]
4849   ""
4850   "orn\t%2, %1, %0")
4852 (define_expand "xordi3"
4853   [(set (match_operand:DI 0 "register_operand" "")
4854         (xor:DI (match_operand:DI 1 "arith_double_operand" "")
4855                 (match_operand:DI 2 "arith_double_operand" "")))]
4856   ""
4857   "")
4859 (define_insn "*xordi3_sp32"
4860   [(set (match_operand:DI 0 "register_operand" "=r")
4861         (xor:DI (match_operand:DI 1 "arith_double_operand" "%r")
4862                 (match_operand:DI 2 "arith_double_operand" "rHI")))]
4863   "! TARGET_ARCH64"
4864   "#"
4865   [(set_attr "length" "2")])
4867 (define_insn "*xordi3_sp64"
4868   [(set (match_operand:DI 0 "register_operand" "=r")
4869         (xor:DI (match_operand:DI 1 "arith_operand" "%rJ")
4870                 (match_operand:DI 2 "arith_operand" "rI")))]
4871   "TARGET_ARCH64"
4872   "xor\t%r1, %2, %0")
4874 (define_insn "xorsi3"
4875   [(set (match_operand:SI 0 "register_operand" "=r")
4876         (xor:SI (match_operand:SI 1 "arith_operand" "%rJ")
4877                   (match_operand:SI 2 "arith_operand" "rI")))]
4878   ""
4879   "xor\t%r1, %2, %0")
4881 (define_split
4882   [(set (match_operand:SI 0 "register_operand" "")
4883         (xor:SI (match_operand:SI 1 "register_operand" "")
4884                 (match_operand:SI 2 "const_compl_high_operand" "")))
4885    (clobber (match_operand:SI 3 "register_operand" ""))]
4886    ""
4887   [(set (match_dup 3) (match_dup 4))
4888    (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
4890   operands[4] = gen_int_mode (~INTVAL (operands[2]), SImode);
4893 (define_split
4894   [(set (match_operand:SI 0 "register_operand" "")
4895         (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
4896                         (match_operand:SI 2 "const_compl_high_operand" ""))))
4897    (clobber (match_operand:SI 3 "register_operand" ""))]
4898   ""
4899   [(set (match_dup 3) (match_dup 4))
4900    (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
4902   operands[4] = gen_int_mode (~INTVAL (operands[2]), SImode);
4905 ;; Split DImode logical operations requiring two instructions.
4906 (define_split
4907   [(set (match_operand:DI 0 "register_operand" "")
4908         (match_operator:DI 1 "cc_arith_operator"        ; AND, IOR, XOR
4909                            [(match_operand:DI 2 "register_operand" "")
4910                             (match_operand:DI 3 "arith_double_operand" "")]))]
4911   "! TARGET_ARCH64
4912    && reload_completed
4913    && ((GET_CODE (operands[0]) == REG
4914         && SPARC_INT_REG_P (REGNO (operands[0])))
4915        || (GET_CODE (operands[0]) == SUBREG
4916            && GET_CODE (SUBREG_REG (operands[0])) == REG
4917            && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
4918   [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
4919    (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
4921   operands[4] = gen_highpart (SImode, operands[0]);
4922   operands[5] = gen_lowpart (SImode, operands[0]);
4923   operands[6] = gen_highpart (SImode, operands[2]);
4924   operands[7] = gen_lowpart (SImode, operands[2]);
4925 #if HOST_BITS_PER_WIDE_INT == 32
4926   if (GET_CODE (operands[3]) == CONST_INT)
4927     {
4928       if (INTVAL (operands[3]) < 0)
4929         operands[8] = constm1_rtx;
4930       else
4931         operands[8] = const0_rtx;
4932     }
4933   else
4934 #endif
4935     operands[8] = gen_highpart_mode (SImode, DImode, operands[3]);
4936   operands[9] = gen_lowpart (SImode, operands[3]);
4939 ;; xnor patterns.  Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
4940 ;; Combine now canonicalizes to the rightmost expression.
4941 (define_insn_and_split "*xor_not_di_sp32"
4942   [(set (match_operand:DI 0 "register_operand" "=&r")
4943         (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r")
4944                         (match_operand:DI 2 "register_operand" "r"))))]
4945   "! TARGET_ARCH64"
4946   "#"
4947   "&& reload_completed
4948    && ((GET_CODE (operands[0]) == REG
4949         && SPARC_INT_REG_P (REGNO (operands[0])))
4950        || (GET_CODE (operands[0]) == SUBREG
4951            && GET_CODE (SUBREG_REG (operands[0])) == REG
4952            && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
4953   [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
4954    (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
4955   "operands[3] = gen_highpart (SImode, operands[0]);
4956    operands[4] = gen_highpart (SImode, operands[1]);
4957    operands[5] = gen_highpart (SImode, operands[2]);
4958    operands[6] = gen_lowpart (SImode, operands[0]);
4959    operands[7] = gen_lowpart (SImode, operands[1]);
4960    operands[8] = gen_lowpart (SImode, operands[2]);"
4961   [(set_attr "length" "2")])
4963 (define_insn "*xor_not_di_sp64"
4964   [(set (match_operand:DI 0 "register_operand" "=r")
4965         (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
4966                         (match_operand:DI 2 "arith_operand" "rI"))))]
4967   "TARGET_ARCH64"
4968   "xnor\t%r1, %2, %0")
4970 (define_insn "*xor_not_si"
4971   [(set (match_operand:SI 0 "register_operand" "=r")
4972         (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4973                         (match_operand:SI 2 "arith_operand" "rI"))))]
4974   ""
4975   "xnor\t%r1, %2, %0")
4977 ;; These correspond to the above in the case where we also (or only)
4978 ;; want to set the condition code.  
4980 (define_insn "*cmp_cc_arith_op"
4981   [(set (reg:CC CC_REG)
4982         (compare:CC
4983          (match_operator:SI 2 "cc_arith_operator"
4984                             [(match_operand:SI 0 "arith_operand" "%r")
4985                              (match_operand:SI 1 "arith_operand" "rI")])
4986          (const_int 0)))]
4987   ""
4988   "%A2cc\t%0, %1, %%g0"
4989   [(set_attr "type" "compare")])
4991 (define_insn "*cmp_ccx_arith_op"
4992   [(set (reg:CCX CC_REG)
4993         (compare:CCX
4994          (match_operator:DI 2 "cc_arith_operator"
4995                             [(match_operand:DI 0 "arith_operand" "%r")
4996                              (match_operand:DI 1 "arith_operand" "rI")])
4997          (const_int 0)))]
4998   "TARGET_ARCH64"
4999   "%A2cc\t%0, %1, %%g0"
5000   [(set_attr "type" "compare")])
5002 (define_insn "*cmp_cc_arith_op_set"
5003   [(set (reg:CC CC_REG)
5004         (compare:CC
5005          (match_operator:SI 3 "cc_arith_operator"
5006                             [(match_operand:SI 1 "arith_operand" "%r")
5007                              (match_operand:SI 2 "arith_operand" "rI")])
5008          (const_int 0)))
5009    (set (match_operand:SI 0 "register_operand" "=r")
5010         (match_operator:SI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5011   "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5012   "%A3cc\t%1, %2, %0"
5013   [(set_attr "type" "compare")])
5015 (define_insn "*cmp_ccx_arith_op_set"
5016   [(set (reg:CCX CC_REG)
5017         (compare:CCX
5018          (match_operator:DI 3 "cc_arith_operator"
5019                             [(match_operand:DI 1 "arith_operand" "%r")
5020                              (match_operand:DI 2 "arith_operand" "rI")])
5021          (const_int 0)))
5022    (set (match_operand:DI 0 "register_operand" "=r")
5023         (match_operator:DI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5024   "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5025   "%A3cc\t%1, %2, %0"
5026   [(set_attr "type" "compare")])
5028 (define_insn "*cmp_cc_xor_not"
5029   [(set (reg:CC CC_REG)
5030         (compare:CC
5031          (not:SI (xor:SI (match_operand:SI 0 "register_or_zero_operand" "%rJ")
5032                          (match_operand:SI 1 "arith_operand" "rI")))
5033          (const_int 0)))]
5034   ""
5035   "xnorcc\t%r0, %1, %%g0"
5036   [(set_attr "type" "compare")])
5038 (define_insn "*cmp_ccx_xor_not"
5039   [(set (reg:CCX CC_REG)
5040         (compare:CCX
5041          (not:DI (xor:DI (match_operand:DI 0 "register_or_zero_operand" "%rJ")
5042                          (match_operand:DI 1 "arith_operand" "rI")))
5043          (const_int 0)))]
5044   "TARGET_ARCH64"
5045   "xnorcc\t%r0, %1, %%g0"
5046   [(set_attr "type" "compare")])
5048 (define_insn "*cmp_cc_xor_not_set"
5049   [(set (reg:CC CC_REG)
5050         (compare:CC
5051          (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
5052                          (match_operand:SI 2 "arith_operand" "rI")))
5053          (const_int 0)))
5054    (set (match_operand:SI 0 "register_operand" "=r")
5055         (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
5056   ""
5057   "xnorcc\t%r1, %2, %0"
5058   [(set_attr "type" "compare")])
5060 (define_insn "*cmp_ccx_xor_not_set"
5061   [(set (reg:CCX CC_REG)
5062         (compare:CCX
5063          (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
5064                          (match_operand:DI 2 "arith_operand" "rI")))
5065          (const_int 0)))
5066    (set (match_operand:DI 0 "register_operand" "=r")
5067         (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
5068   "TARGET_ARCH64"
5069   "xnorcc\t%r1, %2, %0"
5070   [(set_attr "type" "compare")])
5072 (define_insn "*cmp_cc_arith_op_not"
5073   [(set (reg:CC CC_REG)
5074         (compare:CC
5075          (match_operator:SI 2 "cc_arith_not_operator"
5076                             [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
5077                              (match_operand:SI 1 "register_or_zero_operand" "rJ")])
5078          (const_int 0)))]
5079   ""
5080   "%B2cc\t%r1, %0, %%g0"
5081   [(set_attr "type" "compare")])
5083 (define_insn "*cmp_ccx_arith_op_not"
5084   [(set (reg:CCX CC_REG)
5085         (compare:CCX
5086          (match_operator:DI 2 "cc_arith_not_operator"
5087                             [(not:DI (match_operand:DI 0 "arith_operand" "rI"))
5088                              (match_operand:DI 1 "register_or_zero_operand" "rJ")])
5089          (const_int 0)))]
5090   "TARGET_ARCH64"
5091   "%B2cc\t%r1, %0, %%g0"
5092   [(set_attr "type" "compare")])
5094 (define_insn "*cmp_cc_arith_op_not_set"
5095   [(set (reg:CC CC_REG)
5096         (compare:CC
5097          (match_operator:SI 3 "cc_arith_not_operator"
5098                             [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
5099                              (match_operand:SI 2 "register_or_zero_operand" "rJ")])
5100          (const_int 0)))
5101    (set (match_operand:SI 0 "register_operand" "=r")
5102         (match_operator:SI 4 "cc_arith_not_operator"
5103                             [(not:SI (match_dup 1)) (match_dup 2)]))]
5104   "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5105   "%B3cc\t%r2, %1, %0"
5106   [(set_attr "type" "compare")])
5108 (define_insn "*cmp_ccx_arith_op_not_set"
5109   [(set (reg:CCX CC_REG)
5110         (compare:CCX
5111          (match_operator:DI 3 "cc_arith_not_operator"
5112                             [(not:DI (match_operand:DI 1 "arith_operand" "rI"))
5113                              (match_operand:DI 2 "register_or_zero_operand" "rJ")])
5114          (const_int 0)))
5115    (set (match_operand:DI 0 "register_operand" "=r")
5116         (match_operator:DI 4 "cc_arith_not_operator"
5117                             [(not:DI (match_dup 1)) (match_dup 2)]))]
5118   "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5119   "%B3cc\t%r2, %1, %0"
5120   [(set_attr "type" "compare")])
5122 ;; We cannot use the "neg" pseudo insn because the Sun assembler
5123 ;; does not know how to make it work for constants.
5125 (define_expand "negdi2"
5126   [(set (match_operand:DI 0 "register_operand" "=r")
5127         (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5128   ""
5130   if (! TARGET_ARCH64)
5131     {
5132       emit_insn (gen_rtx_PARALLEL
5133                  (VOIDmode,
5134                   gen_rtvec (2,
5135                              gen_rtx_SET (operand0,
5136                                           gen_rtx_NEG (DImode, operand1)),
5137                              gen_rtx_CLOBBER (VOIDmode,
5138                                               gen_rtx_REG (CCmode,
5139                                                            SPARC_ICC_REG)))));
5140       DONE;
5141     }
5144 (define_insn_and_split "*negdi2_sp32"
5145   [(set (match_operand:DI 0 "register_operand" "=&r")
5146         (neg:DI (match_operand:DI 1 "register_operand" "r")))
5147    (clobber (reg:CC CC_REG))]
5148   "! TARGET_ARCH64"
5149   "#"
5150   "&& reload_completed"
5151   [(parallel [(set (reg:CC_NOOV CC_REG)
5152                    (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
5153                                     (const_int 0)))
5154               (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
5155    (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
5156                                 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
5157   "operands[2] = gen_highpart (SImode, operands[0]);
5158    operands[3] = gen_highpart (SImode, operands[1]);
5159    operands[4] = gen_lowpart (SImode, operands[0]);
5160    operands[5] = gen_lowpart (SImode, operands[1]);"
5161   [(set_attr "length" "2")])
5163 (define_insn "*negdi2_sp64"
5164   [(set (match_operand:DI 0 "register_operand" "=r")
5165         (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5166   "TARGET_ARCH64"
5167   "sub\t%%g0, %1, %0")
5169 (define_insn "negsi2"
5170   [(set (match_operand:SI 0 "register_operand" "=r")
5171         (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
5172   ""
5173   "sub\t%%g0, %1, %0")
5175 (define_insn "*cmp_cc_neg"
5176   [(set (reg:CC_NOOV CC_REG)
5177         (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
5178                          (const_int 0)))]
5179   ""
5180   "subcc\t%%g0, %0, %%g0"
5181   [(set_attr "type" "compare")])
5183 (define_insn "*cmp_ccx_neg"
5184   [(set (reg:CCX_NOOV CC_REG)
5185         (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_operand" "rI"))
5186                           (const_int 0)))]
5187   "TARGET_ARCH64"
5188   "subcc\t%%g0, %0, %%g0"
5189   [(set_attr "type" "compare")])
5191 (define_insn "*cmp_cc_set_neg"
5192   [(set (reg:CC_NOOV CC_REG)
5193         (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
5194                          (const_int 0)))
5195    (set (match_operand:SI 0 "register_operand" "=r")
5196         (neg:SI (match_dup 1)))]
5197   ""
5198   "subcc\t%%g0, %1, %0"
5199   [(set_attr "type" "compare")])
5201 (define_insn "*cmp_ccx_set_neg"
5202   [(set (reg:CCX_NOOV CC_REG)
5203         (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_operand" "rI"))
5204                           (const_int 0)))
5205    (set (match_operand:DI 0 "register_operand" "=r")
5206         (neg:DI (match_dup 1)))]
5207   "TARGET_ARCH64"
5208   "subcc\t%%g0, %1, %0"
5209   [(set_attr "type" "compare")])
5211 ;; We cannot use the "not" pseudo insn because the Sun assembler
5212 ;; does not know how to make it work for constants.
5213 (define_expand "one_cmpldi2"
5214   [(set (match_operand:DI 0 "register_operand" "")
5215         (not:DI (match_operand:DI 1 "register_operand" "")))]
5216   ""
5217   "")
5219 (define_insn_and_split "*one_cmpldi2_sp32"
5220   [(set (match_operand:DI 0 "register_operand" "=&r")
5221         (not:DI (match_operand:DI 1 "register_operand" "r")))]
5222   "! TARGET_ARCH64"
5223   "#"
5224   "&& reload_completed
5225    && ((GET_CODE (operands[0]) == REG
5226         && SPARC_INT_REG_P (REGNO (operands[0])))
5227        || (GET_CODE (operands[0]) == SUBREG
5228            && GET_CODE (SUBREG_REG (operands[0])) == REG
5229            && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
5230   [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
5231    (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
5232   "operands[2] = gen_highpart (SImode, operands[0]);
5233    operands[3] = gen_highpart (SImode, operands[1]);
5234    operands[4] = gen_lowpart (SImode, operands[0]);
5235    operands[5] = gen_lowpart (SImode, operands[1]);"
5236   [(set_attr "length" "2")])
5238 (define_insn "*one_cmpldi2_sp64"
5239   [(set (match_operand:DI 0 "register_operand" "=r")
5240         (not:DI (match_operand:DI 1 "arith_operand" "rI")))]
5241   "TARGET_ARCH64"
5242   "xnor\t%%g0, %1, %0")
5244 (define_insn "one_cmplsi2"
5245   [(set (match_operand:SI 0 "register_operand" "=r")
5246         (not:SI (match_operand:SI 1 "arith_operand" "rI")))]
5247   ""
5248   "xnor\t%%g0, %1, %0")
5250 (define_insn "*cmp_cc_not"
5251   [(set (reg:CC CC_REG)
5252         (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
5253                     (const_int 0)))]
5254   ""
5255   "xnorcc\t%%g0, %0, %%g0"
5256   [(set_attr "type" "compare")])
5258 (define_insn "*cmp_ccx_not"
5259   [(set (reg:CCX CC_REG)
5260         (compare:CCX (not:DI (match_operand:DI 0 "arith_operand" "rI"))
5261                      (const_int 0)))]
5262   "TARGET_ARCH64"
5263   "xnorcc\t%%g0, %0, %%g0"
5264   [(set_attr "type" "compare")])
5266 (define_insn "*cmp_cc_set_not"
5267   [(set (reg:CC CC_REG)
5268         (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
5269                     (const_int 0)))
5270    (set (match_operand:SI 0 "register_operand" "=r")
5271         (not:SI (match_dup 1)))]
5272   ""
5273   "xnorcc\t%%g0, %1, %0"
5274   [(set_attr "type" "compare")])
5276 (define_insn "*cmp_ccx_set_not"
5277   [(set (reg:CCX CC_REG)
5278         (compare:CCX (not:DI (match_operand:DI 1 "arith_operand" "rI"))
5279                     (const_int 0)))
5280    (set (match_operand:DI 0 "register_operand" "=r")
5281         (not:DI (match_dup 1)))]
5282   "TARGET_ARCH64"
5283   "xnorcc\t%%g0, %1, %0"
5284   [(set_attr "type" "compare")])
5286 (define_insn "*cmp_cc_set"
5287   [(set (match_operand:SI 0 "register_operand" "=r")
5288         (match_operand:SI 1 "register_operand" "r"))
5289    (set (reg:CC CC_REG)
5290         (compare:CC (match_dup 1)
5291                     (const_int 0)))]
5292   ""
5293   "orcc\t%1, 0, %0"
5294   [(set_attr "type" "compare")])
5296 (define_insn "*cmp_ccx_set64"
5297   [(set (match_operand:DI 0 "register_operand" "=r")
5298         (match_operand:DI 1 "register_operand" "r"))
5299    (set (reg:CCX CC_REG)
5300         (compare:CCX (match_dup 1)
5301                      (const_int 0)))]
5302   "TARGET_ARCH64"
5303   "orcc\t%1, 0, %0"
5304    [(set_attr "type" "compare")])
5307 ;; Floating point arithmetic instructions.
5309 (define_expand "addtf3"
5310   [(set (match_operand:TF 0 "nonimmediate_operand" "")
5311         (plus:TF (match_operand:TF 1 "general_operand" "")
5312                  (match_operand:TF 2 "general_operand" "")))]
5313   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5314   "emit_tfmode_binop (PLUS, operands); DONE;")
5316 (define_insn "*addtf3_hq"
5317   [(set (match_operand:TF 0 "register_operand" "=e")
5318         (plus:TF (match_operand:TF 1 "register_operand" "e")
5319                  (match_operand:TF 2 "register_operand" "e")))]
5320   "TARGET_FPU && TARGET_HARD_QUAD"
5321   "faddq\t%1, %2, %0"
5322   [(set_attr "type" "fp")])
5324 (define_insn "adddf3"
5325   [(set (match_operand:DF 0 "register_operand" "=e")
5326         (plus:DF (match_operand:DF 1 "register_operand" "e")
5327                  (match_operand:DF 2 "register_operand" "e")))]
5328   "TARGET_FPU"
5329   "faddd\t%1, %2, %0"
5330   [(set_attr "type" "fp")
5331    (set_attr "fptype" "double")])
5333 (define_insn "addsf3"
5334   [(set (match_operand:SF 0 "register_operand" "=f")
5335         (plus:SF (match_operand:SF 1 "register_operand" "f")
5336                  (match_operand:SF 2 "register_operand" "f")))]
5337   "TARGET_FPU"
5338   "fadds\t%1, %2, %0"
5339   [(set_attr "type" "fp")])
5341 (define_expand "subtf3"
5342   [(set (match_operand:TF 0 "nonimmediate_operand" "")
5343         (minus:TF (match_operand:TF 1 "general_operand" "")
5344                   (match_operand:TF 2 "general_operand" "")))]
5345   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5346   "emit_tfmode_binop (MINUS, operands); DONE;")
5348 (define_insn "*subtf3_hq"
5349   [(set (match_operand:TF 0 "register_operand" "=e")
5350         (minus:TF (match_operand:TF 1 "register_operand" "e")
5351                   (match_operand:TF 2 "register_operand" "e")))]
5352   "TARGET_FPU && TARGET_HARD_QUAD"
5353   "fsubq\t%1, %2, %0"
5354   [(set_attr "type" "fp")])
5356 (define_insn "subdf3"
5357   [(set (match_operand:DF 0 "register_operand" "=e")
5358         (minus:DF (match_operand:DF 1 "register_operand" "e")
5359                   (match_operand:DF 2 "register_operand" "e")))]
5360   "TARGET_FPU"
5361   "fsubd\t%1, %2, %0"
5362   [(set_attr "type" "fp")
5363    (set_attr "fptype" "double")])
5365 (define_insn "subsf3"
5366   [(set (match_operand:SF 0 "register_operand" "=f")
5367         (minus:SF (match_operand:SF 1 "register_operand" "f")
5368                   (match_operand:SF 2 "register_operand" "f")))]
5369   "TARGET_FPU"
5370   "fsubs\t%1, %2, %0"
5371   [(set_attr "type" "fp")])
5373 (define_expand "multf3"
5374   [(set (match_operand:TF 0 "nonimmediate_operand" "")
5375         (mult:TF (match_operand:TF 1 "general_operand" "")
5376                  (match_operand:TF 2 "general_operand" "")))]
5377   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5378   "emit_tfmode_binop (MULT, operands); DONE;")
5380 (define_insn "*multf3_hq"
5381   [(set (match_operand:TF 0 "register_operand" "=e")
5382         (mult:TF (match_operand:TF 1 "register_operand" "e")
5383                  (match_operand:TF 2 "register_operand" "e")))]
5384   "TARGET_FPU && TARGET_HARD_QUAD"
5385   "fmulq\t%1, %2, %0"
5386   [(set_attr "type" "fpmul")])
5388 (define_insn "muldf3"
5389   [(set (match_operand:DF 0 "register_operand" "=e")
5390         (mult:DF (match_operand:DF 1 "register_operand" "e")
5391                  (match_operand:DF 2 "register_operand" "e")))]
5392   "TARGET_FPU"
5393   "fmuld\t%1, %2, %0"
5394   [(set_attr "type" "fpmul")
5395    (set_attr "fptype" "double")])
5397 (define_insn "mulsf3"
5398   [(set (match_operand:SF 0 "register_operand" "=f")
5399         (mult:SF (match_operand:SF 1 "register_operand" "f")
5400                  (match_operand:SF 2 "register_operand" "f")))]
5401   "TARGET_FPU"
5402   "fmuls\t%1, %2, %0"
5403   [(set_attr "type" "fpmul")])
5405 (define_insn "fmadf4"
5406   [(set (match_operand:DF 0 "register_operand" "=e")
5407         (fma:DF (match_operand:DF 1 "register_operand" "e")
5408                 (match_operand:DF 2 "register_operand" "e")
5409                 (match_operand:DF 3 "register_operand" "e")))]
5410   "TARGET_FMAF"
5411   "fmaddd\t%1, %2, %3, %0"
5412   [(set_attr "type" "fpmul")])
5414 (define_insn "fmsdf4"
5415   [(set (match_operand:DF 0 "register_operand" "=e")
5416         (fma:DF (match_operand:DF 1 "register_operand" "e")
5417                 (match_operand:DF 2 "register_operand" "e")
5418                 (neg:DF (match_operand:DF 3 "register_operand" "e"))))]
5419   "TARGET_FMAF"
5420   "fmsubd\t%1, %2, %3, %0"
5421   [(set_attr "type" "fpmul")])
5423 (define_insn "*nfmadf4"
5424   [(set (match_operand:DF 0 "register_operand" "=e")
5425         (neg:DF (fma:DF (match_operand:DF 1 "register_operand" "e")
5426                         (match_operand:DF 2 "register_operand" "e")
5427                         (match_operand:DF 3 "register_operand" "e"))))]
5428   "TARGET_FMAF"
5429   "fnmaddd\t%1, %2, %3, %0"
5430   [(set_attr "type" "fpmul")])
5432 (define_insn "*nfmsdf4"
5433   [(set (match_operand:DF 0 "register_operand" "=e")
5434         (neg:DF (fma:DF (match_operand:DF 1 "register_operand" "e")
5435                         (match_operand:DF 2 "register_operand" "e")
5436                         (neg:DF (match_operand:DF 3 "register_operand" "e")))))]
5437   "TARGET_FMAF"
5438   "fnmsubd\t%1, %2, %3, %0"
5439   [(set_attr "type" "fpmul")])
5441 (define_insn "fmasf4"
5442   [(set (match_operand:SF 0 "register_operand" "=f")
5443         (fma:SF (match_operand:SF 1 "register_operand" "f")
5444                 (match_operand:SF 2 "register_operand" "f")
5445                 (match_operand:SF 3 "register_operand" "f")))]
5446   "TARGET_FMAF"
5447   "fmadds\t%1, %2, %3, %0"
5448   [(set_attr "type" "fpmul")])
5450 (define_insn "fmssf4"
5451   [(set (match_operand:SF 0 "register_operand" "=f")
5452         (fma:SF (match_operand:SF 1 "register_operand" "f")
5453                 (match_operand:SF 2 "register_operand" "f")
5454                 (neg:SF (match_operand:SF 3 "register_operand" "f"))))]
5455   "TARGET_FMAF"
5456   "fmsubs\t%1, %2, %3, %0"
5457   [(set_attr "type" "fpmul")])
5459 (define_insn "*nfmasf4"
5460   [(set (match_operand:SF 0 "register_operand" "=f")
5461         (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "f")
5462                         (match_operand:SF 2 "register_operand" "f")
5463                         (match_operand:SF 3 "register_operand" "f"))))]
5464   "TARGET_FMAF"
5465   "fnmadds\t%1, %2, %3, %0"
5466   [(set_attr "type" "fpmul")])
5468 (define_insn "*nfmssf4"
5469   [(set (match_operand:SF 0 "register_operand" "=f")
5470         (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "f")
5471                         (match_operand:SF 2 "register_operand" "f")
5472                         (neg:SF (match_operand:SF 3 "register_operand" "f")))))]
5473   "TARGET_FMAF"
5474   "fnmsubs\t%1, %2, %3, %0"
5475   [(set_attr "type" "fpmul")])
5477 (define_insn "*muldf3_extend"
5478   [(set (match_operand:DF 0 "register_operand" "=e")
5479         (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
5480                  (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
5481   "(TARGET_V8 || TARGET_V9) && TARGET_FPU && !sparc_fix_ut699"
5482   "fsmuld\t%1, %2, %0"
5483   [(set_attr "type" "fpmul")
5484    (set_attr "fptype" "double")])
5486 (define_insn "*multf3_extend"
5487   [(set (match_operand:TF 0 "register_operand" "=e")
5488         (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
5489                  (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
5490   "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
5491   "fdmulq\t%1, %2, %0"
5492   [(set_attr "type" "fpmul")])
5494 (define_expand "divtf3"
5495   [(set (match_operand:TF 0 "nonimmediate_operand" "")
5496         (div:TF (match_operand:TF 1 "general_operand" "")
5497                 (match_operand:TF 2 "general_operand" "")))]
5498   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5499   "emit_tfmode_binop (DIV, operands); DONE;")
5501 ;; don't have timing for quad-prec. divide.
5502 (define_insn "*divtf3_hq"
5503   [(set (match_operand:TF 0 "register_operand" "=e")
5504         (div:TF (match_operand:TF 1 "register_operand" "e")
5505                 (match_operand:TF 2 "register_operand" "e")))]
5506   "TARGET_FPU && TARGET_HARD_QUAD"
5507   "fdivq\t%1, %2, %0"
5508   [(set_attr "type" "fpdivs")])
5510 (define_expand "divdf3"
5511   [(set (match_operand:DF 0 "register_operand" "=e")
5512         (div:DF (match_operand:DF 1 "register_operand" "e")
5513                 (match_operand:DF 2 "register_operand" "e")))]
5514   "TARGET_FPU"
5515   "")
5517 (define_insn "*divdf3_nofix"
5518   [(set (match_operand:DF 0 "register_operand" "=e")
5519         (div:DF (match_operand:DF 1 "register_operand" "e")
5520                 (match_operand:DF 2 "register_operand" "e")))]
5521   "TARGET_FPU && !sparc_fix_ut699"
5522   "fdivd\t%1, %2, %0"
5523   [(set_attr "type" "fpdivd")
5524    (set_attr "fptype" "double")])
5526 (define_insn "*divdf3_fix"
5527   [(set (match_operand:DF 0 "register_operand" "=e")
5528         (div:DF (match_operand:DF 1 "register_operand" "e")
5529                 (match_operand:DF 2 "register_operand" "e")))]
5530   "TARGET_FPU && sparc_fix_ut699"
5531   "fdivd\t%1, %2, %0\n\tstd\t%0, [%%sp-8]"
5532   [(set_attr "type" "fpdivd")
5533    (set_attr "fptype" "double")
5534    (set_attr "length" "2")])
5536 (define_insn "divsf3"
5537   [(set (match_operand:SF 0 "register_operand" "=f")
5538         (div:SF (match_operand:SF 1 "register_operand" "f")
5539                 (match_operand:SF 2 "register_operand" "f")))]
5540   "TARGET_FPU && !sparc_fix_ut699"
5541   "fdivs\t%1, %2, %0"
5542   [(set_attr "type" "fpdivs")])
5544 (define_expand "negtf2"
5545   [(set (match_operand:TF 0 "register_operand" "")
5546         (neg:TF (match_operand:TF 1 "register_operand" "")))]
5547   "TARGET_FPU"
5548   "")
5550 (define_insn "*negtf2_hq"
5551   [(set (match_operand:TF 0 "register_operand" "=e")
5552         (neg:TF (match_operand:TF 1 "register_operand" "e")))]
5553   "TARGET_FPU && TARGET_HARD_QUAD"
5554   "fnegq\t%1, %0"
5555   [(set_attr "type" "fpmove")])
5557 (define_insn_and_split "*negtf2"
5558   [(set (match_operand:TF 0 "register_operand" "=e")
5559         (neg:TF (match_operand:TF 1 "register_operand" "e")))]
5560   "TARGET_FPU && !TARGET_HARD_QUAD"
5561   "#"
5562   "&& reload_completed"
5563   [(clobber (const_int 0))]
5565   rtx set_dest = operands[0];
5566   rtx set_src = operands[1];
5567   rtx dest1, dest2;
5568   rtx src1, src2;
5570   dest1 = gen_df_reg (set_dest, 0);
5571   dest2 = gen_df_reg (set_dest, 1);
5572   src1 = gen_df_reg (set_src, 0);
5573   src2 = gen_df_reg (set_src, 1);
5575   /* Now emit using the real source and destination we found, swapping
5576      the order if we detect overlap.  */
5577   if (reg_overlap_mentioned_p (dest1, src2))
5578     {
5579       emit_insn (gen_movdf (dest2, src2));
5580       emit_insn (gen_negdf2 (dest1, src1));
5581     }
5582   else
5583     {
5584       emit_insn (gen_negdf2 (dest1, src1));
5585       if (REGNO (dest2) != REGNO (src2))
5586         emit_insn (gen_movdf (dest2, src2));
5587     }
5588   DONE;
5590   [(set_attr "length" "2")])
5592 (define_expand "negdf2"
5593   [(set (match_operand:DF 0 "register_operand" "")
5594         (neg:DF (match_operand:DF 1 "register_operand" "")))]
5595   "TARGET_FPU"
5596   "")
5598 (define_insn_and_split "*negdf2_notv9"
5599   [(set (match_operand:DF 0 "register_operand" "=e")
5600         (neg:DF (match_operand:DF 1 "register_operand" "e")))]
5601   "TARGET_FPU && !TARGET_V9"
5602   "#"
5603   "&& reload_completed"
5604   [(clobber (const_int 0))]
5606   rtx set_dest = operands[0];
5607   rtx set_src = operands[1];
5608   rtx dest1, dest2;
5609   rtx src1, src2;
5611   dest1 = gen_highpart (SFmode, set_dest);
5612   dest2 = gen_lowpart (SFmode, set_dest);
5613   src1 = gen_highpart (SFmode, set_src);
5614   src2 = gen_lowpart (SFmode, set_src);
5616   /* Now emit using the real source and destination we found, swapping
5617      the order if we detect overlap.  */
5618   if (reg_overlap_mentioned_p (dest1, src2))
5619     {
5620       emit_insn (gen_movsf (dest2, src2));
5621       emit_insn (gen_negsf2 (dest1, src1));
5622     }
5623   else
5624     {
5625       emit_insn (gen_negsf2 (dest1, src1));
5626       if (REGNO (dest2) != REGNO (src2))
5627         emit_insn (gen_movsf (dest2, src2));
5628     }
5629   DONE;
5631   [(set_attr "length" "2")])
5633 (define_insn "*negdf2_v9"
5634   [(set (match_operand:DF 0 "register_operand" "=e")
5635         (neg:DF (match_operand:DF 1 "register_operand" "e")))]
5636   "TARGET_FPU && TARGET_V9"
5637   "fnegd\t%1, %0"
5638   [(set_attr "type" "fpmove")
5639    (set_attr "fptype" "double")])
5641 (define_insn "negsf2"
5642   [(set (match_operand:SF 0 "register_operand" "=f")
5643         (neg:SF (match_operand:SF 1 "register_operand" "f")))]
5644   "TARGET_FPU"
5645   "fnegs\t%1, %0"
5646   [(set_attr "type" "fpmove")])
5648 (define_expand "abstf2"
5649   [(set (match_operand:TF 0 "register_operand" "")
5650         (abs:TF (match_operand:TF 1 "register_operand" "")))]
5651   "TARGET_FPU"
5652   "")
5654 (define_insn "*abstf2_hq"
5655   [(set (match_operand:TF 0 "register_operand" "=e")
5656         (abs:TF (match_operand:TF 1 "register_operand" "e")))]
5657   "TARGET_FPU && TARGET_HARD_QUAD"
5658   "fabsq\t%1, %0"
5659   [(set_attr "type" "fpmove")])
5661 (define_insn_and_split "*abstf2"
5662   [(set (match_operand:TF 0 "register_operand" "=e")
5663         (abs:TF (match_operand:TF 1 "register_operand" "e")))]
5664   "TARGET_FPU && !TARGET_HARD_QUAD"
5665   "#"
5666   "&& reload_completed"
5667   [(clobber (const_int 0))]
5669   rtx set_dest = operands[0];
5670   rtx set_src = operands[1];
5671   rtx dest1, dest2;
5672   rtx src1, src2;
5674   dest1 = gen_df_reg (set_dest, 0);
5675   dest2 = gen_df_reg (set_dest, 1);
5676   src1 = gen_df_reg (set_src, 0);
5677   src2 = gen_df_reg (set_src, 1);
5679   /* Now emit using the real source and destination we found, swapping
5680      the order if we detect overlap.  */
5681   if (reg_overlap_mentioned_p (dest1, src2))
5682     {
5683       emit_insn (gen_movdf (dest2, src2));
5684       emit_insn (gen_absdf2 (dest1, src1));
5685     }
5686   else
5687     {
5688       emit_insn (gen_absdf2 (dest1, src1));
5689       if (REGNO (dest2) != REGNO (src2))
5690         emit_insn (gen_movdf (dest2, src2));
5691     }
5692   DONE;
5694   [(set_attr "length" "2")])
5696 (define_expand "absdf2"
5697   [(set (match_operand:DF 0 "register_operand" "")
5698         (abs:DF (match_operand:DF 1 "register_operand" "")))]
5699   "TARGET_FPU"
5700   "")
5702 (define_insn_and_split "*absdf2_notv9"
5703   [(set (match_operand:DF 0 "register_operand" "=e")
5704         (abs:DF (match_operand:DF 1 "register_operand" "e")))]
5705   "TARGET_FPU && !TARGET_V9"
5706   "#"
5707   "&& reload_completed"
5708   [(clobber (const_int 0))]
5710   rtx set_dest = operands[0];
5711   rtx set_src = operands[1];
5712   rtx dest1, dest2;
5713   rtx src1, src2;
5715   dest1 = gen_highpart (SFmode, set_dest);
5716   dest2 = gen_lowpart (SFmode, set_dest);
5717   src1 = gen_highpart (SFmode, set_src);
5718   src2 = gen_lowpart (SFmode, set_src);
5720   /* Now emit using the real source and destination we found, swapping
5721      the order if we detect overlap.  */
5722   if (reg_overlap_mentioned_p (dest1, src2))
5723     {
5724       emit_insn (gen_movsf (dest2, src2));
5725       emit_insn (gen_abssf2 (dest1, src1));
5726     }
5727   else
5728     {
5729       emit_insn (gen_abssf2 (dest1, src1));
5730       if (REGNO (dest2) != REGNO (src2))
5731         emit_insn (gen_movsf (dest2, src2));
5732     }
5733   DONE;
5735   [(set_attr "length" "2")])
5737 (define_insn "*absdf2_v9"
5738   [(set (match_operand:DF 0 "register_operand" "=e")
5739         (abs:DF (match_operand:DF 1 "register_operand" "e")))]
5740   "TARGET_FPU && TARGET_V9"
5741   "fabsd\t%1, %0"
5742   [(set_attr "type" "fpmove")
5743    (set_attr "fptype" "double")])
5745 (define_insn "abssf2"
5746   [(set (match_operand:SF 0 "register_operand" "=f")
5747         (abs:SF (match_operand:SF 1 "register_operand" "f")))]
5748   "TARGET_FPU"
5749   "fabss\t%1, %0"
5750   [(set_attr "type" "fpmove")])
5752 (define_expand "sqrttf2"
5753   [(set (match_operand:TF 0 "nonimmediate_operand" "")
5754         (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
5755   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5756   "emit_tfmode_unop (SQRT, operands); DONE;")
5758 (define_insn "*sqrttf2_hq"
5759   [(set (match_operand:TF 0 "register_operand" "=e")
5760         (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
5761   "TARGET_FPU && TARGET_HARD_QUAD"
5762   "fsqrtq\t%1, %0"
5763   [(set_attr "type" "fpsqrts")])
5765 (define_expand "sqrtdf2"
5766   [(set (match_operand:DF 0 "register_operand" "=e")
5767         (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
5768   "TARGET_FPU"
5769   "")
5771 (define_insn "*sqrtdf2_nofix"
5772   [(set (match_operand:DF 0 "register_operand" "=e")
5773         (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
5774   "TARGET_FPU && !sparc_fix_ut699"
5775   "fsqrtd\t%1, %0"
5776   [(set_attr "type" "fpsqrtd")
5777    (set_attr "fptype" "double")])
5779 (define_insn "*sqrtdf2_fix"
5780   [(set (match_operand:DF 0 "register_operand" "=e")
5781         (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
5782   "TARGET_FPU && sparc_fix_ut699"
5783   "fsqrtd\t%1, %0\n\tstd\t%0, [%%sp-8]"
5784   [(set_attr "type" "fpsqrtd")
5785    (set_attr "fptype" "double")
5786    (set_attr "length" "2")])
5788 (define_insn "sqrtsf2"
5789   [(set (match_operand:SF 0 "register_operand" "=f")
5790         (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
5791   "TARGET_FPU && !sparc_fix_ut699"
5792   "fsqrts\t%1, %0"
5793   [(set_attr "type" "fpsqrts")])
5796 ;; Arithmetic shift instructions.
5798 (define_insn "ashlsi3"
5799   [(set (match_operand:SI 0 "register_operand" "=r")
5800         (ashift:SI (match_operand:SI 1 "register_operand" "r")
5801                    (match_operand:SI 2 "arith_operand" "rI")))]
5802   ""
5804   if (GET_CODE (operands[2]) == CONST_INT)
5805     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5806   return "sll\t%1, %2, %0";
5808   [(set_attr "type" "shift")])
5810 (define_expand "ashldi3"
5811   [(set (match_operand:DI 0 "register_operand" "=r")
5812         (ashift:DI (match_operand:DI 1 "register_operand" "r")
5813                    (match_operand:SI 2 "arith_operand" "rI")))]
5814   "TARGET_ARCH64 || TARGET_V8PLUS"
5816   if (! TARGET_ARCH64)
5817     {
5818       if (GET_CODE (operands[2]) == CONST_INT)
5819         FAIL;
5820       emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
5821       DONE;
5822     }
5825 (define_insn "*ashldi3_sp64"
5826   [(set (match_operand:DI 0 "register_operand" "=r")
5827         (ashift:DI (match_operand:DI 1 "register_operand" "r")
5828                    (match_operand:SI 2 "arith_operand" "rI")))]
5829   "TARGET_ARCH64"
5831   if (GET_CODE (operands[2]) == CONST_INT)
5832     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5833   return "sllx\t%1, %2, %0";
5835   [(set_attr "type" "shift")])
5837 ;; XXX UGH!
5838 (define_insn "ashldi3_v8plus"
5839   [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5840         (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5841                    (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5842    (clobber (match_scratch:SI 3 "=X,X,&h"))]
5843   "TARGET_V8PLUS"
5844   "* return output_v8plus_shift (insn ,operands, \"sllx\");"
5845   [(set_attr "type" "multi")
5846    (set_attr "length" "5,5,6")])
5848 ;; Optimize (1LL<<x)-1
5849 ;; XXX this also needs to be fixed to handle equal subregs
5850 ;; XXX first before we could re-enable it.
5851 ;(define_insn ""
5852 ;  [(set (match_operand:DI 0 "register_operand" "=h")
5853 ;       (plus:DI (ashift:DI (const_int 1)
5854 ;                           (match_operand:SI 1 "arith_operand" "rI"))
5855 ;                (const_int -1)))]
5856 ;  "0 && TARGET_V8PLUS"
5858 ;  if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
5859 ;    return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5860 ;  return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5862 ;  [(set_attr "type" "multi")
5863 ;   (set_attr "length" "4")])
5865 (define_insn "*cmp_cc_ashift_1"
5866   [(set (reg:CC_NOOV CC_REG)
5867         (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
5868                                     (const_int 1))
5869                          (const_int 0)))]
5870   ""
5871   "addcc\t%0, %0, %%g0"
5872   [(set_attr "type" "compare")])
5874 (define_insn "*cmp_cc_set_ashift_1"
5875   [(set (reg:CC_NOOV CC_REG)
5876         (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
5877                                     (const_int 1))
5878                          (const_int 0)))
5879    (set (match_operand:SI 0 "register_operand" "=r")
5880         (ashift:SI (match_dup 1) (const_int 1)))]
5881   ""
5882   "addcc\t%1, %1, %0"
5883   [(set_attr "type" "compare")])
5885 (define_insn "ashrsi3"
5886   [(set (match_operand:SI 0 "register_operand" "=r")
5887         (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5888                      (match_operand:SI 2 "arith_operand" "rI")))]
5889   ""
5890   {
5891      if (GET_CODE (operands[2]) == CONST_INT)
5892        operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5893      return "sra\t%1, %2, %0";
5894   }
5895   [(set_attr "type" "shift")])
5897 (define_insn "*ashrsi3_extend"
5898   [(set (match_operand:DI 0 "register_operand" "=r")
5899         (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5900                                      (match_operand:SI 2 "arith_operand" "r"))))]
5901   "TARGET_ARCH64"
5902   "sra\t%1, %2, %0"
5903   [(set_attr "type" "shift")])
5905 ;; This handles the case as above, but with constant shift instead of
5906 ;; register. Combiner "simplifies" it for us a little bit though.
5907 (define_insn "*ashrsi3_extend2"
5908   [(set (match_operand:DI 0 "register_operand" "=r")
5909         (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
5910                                 (const_int 32))
5911                      (match_operand:SI 2 "small_int_operand" "I")))]
5912   "TARGET_ARCH64 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64"
5914   operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
5915   return "sra\t%1, %2, %0";
5917   [(set_attr "type" "shift")])
5919 (define_expand "ashrdi3"
5920   [(set (match_operand:DI 0 "register_operand" "=r")
5921         (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5922                      (match_operand:SI 2 "arith_operand" "rI")))]
5923   "TARGET_ARCH64 || TARGET_V8PLUS"
5925   if (! TARGET_ARCH64)
5926     {
5927       if (GET_CODE (operands[2]) == CONST_INT)
5928         FAIL;   /* prefer generic code in this case */
5929       emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
5930       DONE;
5931     }
5934 (define_insn "*ashrdi3_sp64"
5935   [(set (match_operand:DI 0 "register_operand" "=r")
5936         (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5937                      (match_operand:SI 2 "arith_operand" "rI")))]
5938   "TARGET_ARCH64"
5939   
5940   {
5941     if (GET_CODE (operands[2]) == CONST_INT)
5942       operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5943     return "srax\t%1, %2, %0";
5944   }
5945   [(set_attr "type" "shift")])
5947 ;; XXX
5948 (define_insn "ashrdi3_v8plus"
5949   [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5950         (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5951                      (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5952    (clobber (match_scratch:SI 3 "=X,X,&h"))]
5953   "TARGET_V8PLUS"
5954   "* return output_v8plus_shift (insn, operands, \"srax\");"
5955   [(set_attr "type" "multi")
5956    (set_attr "length" "5,5,6")])
5958 (define_insn "lshrsi3"
5959   [(set (match_operand:SI 0 "register_operand" "=r")
5960         (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5961                      (match_operand:SI 2 "arith_operand" "rI")))]
5962   ""
5963   {
5964     if (GET_CODE (operands[2]) == CONST_INT)
5965       operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5966     return "srl\t%1, %2, %0";
5967   }
5968   [(set_attr "type" "shift")])
5970 (define_insn "*lshrsi3_extend0"
5971   [(set (match_operand:DI 0 "register_operand" "=r")
5972         (zero_extend:DI
5973           (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5974                        (match_operand:SI 2 "arith_operand" "rI"))))]
5975   "TARGET_ARCH64"
5976   {
5977     if (GET_CODE (operands[2]) == CONST_INT)
5978       operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5979     return "srl\t%1, %2, %0";
5980   }
5981   [(set_attr "type" "shift")])
5983 ;; This handles the case where
5984 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
5985 ;; but combiner "simplifies" it for us.
5986 (define_insn "*lshrsi3_extend1"
5987   [(set (match_operand:DI 0 "register_operand" "=r")
5988         (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5989                            (match_operand:SI 2 "arith_operand" "r")) 0)
5990                 (match_operand 3 "const_int_operand" "")))]
5991   "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff"
5992   "srl\t%1, %2, %0"
5993   [(set_attr "type" "shift")])
5995 ;; This handles the case where
5996 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
5997 ;; but combiner "simplifies" it for us.
5998 (define_insn "*lshrsi3_extend2"
5999   [(set (match_operand:DI 0 "register_operand" "=r")
6000         (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
6001                          (match_operand 2 "small_int_operand" "I")
6002                          (const_int 32)))]
6003   "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6005   operands[2] = GEN_INT (32 - INTVAL (operands[2]));
6006   return "srl\t%1, %2, %0";
6008   [(set_attr "type" "shift")])
6010 (define_expand "lshrdi3"
6011   [(set (match_operand:DI 0 "register_operand" "=r")
6012         (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6013                      (match_operand:SI 2 "arith_operand" "rI")))]
6014   "TARGET_ARCH64 || TARGET_V8PLUS"
6016   if (! TARGET_ARCH64)
6017     {
6018       if (GET_CODE (operands[2]) == CONST_INT)
6019         FAIL;
6020       emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
6021       DONE;
6022     }
6025 (define_insn "*lshrdi3_sp64"
6026   [(set (match_operand:DI 0 "register_operand" "=r")
6027         (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6028                      (match_operand:SI 2 "arith_operand" "rI")))]
6029   "TARGET_ARCH64"
6030   {
6031     if (GET_CODE (operands[2]) == CONST_INT)
6032       operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6033     return "srlx\t%1, %2, %0";
6034   }
6035   [(set_attr "type" "shift")])
6037 ;; XXX
6038 (define_insn "lshrdi3_v8plus"
6039   [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6040         (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6041                      (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6042    (clobber (match_scratch:SI 3 "=X,X,&h"))]
6043   "TARGET_V8PLUS"
6044   "* return output_v8plus_shift (insn, operands, \"srlx\");"
6045   [(set_attr "type" "multi")
6046    (set_attr "length" "5,5,6")])
6048 (define_insn ""
6049   [(set (match_operand:SI 0 "register_operand" "=r")
6050         (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6051                                              (const_int 32)) 4)
6052                      (match_operand:SI 2 "small_int_operand" "I")))]
6053   "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6055   operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6056   return "srax\t%1, %2, %0";
6058   [(set_attr "type" "shift")])
6060 (define_insn ""
6061   [(set (match_operand:SI 0 "register_operand" "=r")
6062         (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6063                                              (const_int 32)) 4)
6064                      (match_operand:SI 2 "small_int_operand" "I")))]
6065   "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6067   operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6068   return "srlx\t%1, %2, %0";
6070   [(set_attr "type" "shift")])
6072 (define_insn ""
6073   [(set (match_operand:SI 0 "register_operand" "=r")
6074         (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6075                                              (match_operand:SI 2 "small_int_operand" "I")) 4)
6076                      (match_operand:SI 3 "small_int_operand" "I")))]
6077   "TARGET_ARCH64
6078    && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6079    && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6080    && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6082   operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6084   return "srax\t%1, %2, %0";
6086   [(set_attr "type" "shift")])
6088 (define_insn ""
6089   [(set (match_operand:SI 0 "register_operand" "=r")
6090         (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6091                                              (match_operand:SI 2 "small_int_operand" "I")) 4)
6092                      (match_operand:SI 3 "small_int_operand" "I")))]
6093   "TARGET_ARCH64
6094    && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6095    && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6096    && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6098   operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6100   return "srlx\t%1, %2, %0";
6102   [(set_attr "type" "shift")])
6105 ;; Unconditional and other jump instructions.
6107 (define_expand "jump"
6108   [(set (pc) (label_ref (match_operand 0 "" "")))]
6109   "")
6111 (define_insn "*jump_ubranch"
6112   [(set (pc) (label_ref (match_operand 0 "" "")))]
6113   "! TARGET_CBCOND"
6114   "* return output_ubranch (operands[0], insn);"
6115   [(set_attr "type" "uncond_branch")])
6117 (define_insn "*jump_cbcond"
6118   [(set (pc) (label_ref (match_operand 0 "" "")))]
6119   "TARGET_CBCOND"
6120   "* return output_ubranch (operands[0], insn);"
6121   [(set_attr "type" "uncond_cbcond")])
6123 (define_expand "tablejump"
6124   [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
6125               (use (label_ref (match_operand 1 "" "")))])]
6126   ""
6128   gcc_assert (GET_MODE (operands[0]) == CASE_VECTOR_MODE);
6130   /* In pic mode, our address differences are against the base of the
6131      table.  Add that base value back in; CSE ought to be able to combine
6132      the two address loads.  */
6133   if (flag_pic)
6134     {
6135       rtx tmp, tmp2;
6136       tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
6137       tmp2 = operands[0];
6138       if (CASE_VECTOR_MODE != Pmode)
6139         tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
6140       tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
6141       operands[0] = memory_address (Pmode, tmp);
6142     }
6145 (define_insn "*tablejump_sp32"
6146   [(set (pc) (match_operand:SI 0 "address_operand" "p"))
6147    (use (label_ref (match_operand 1 "" "")))]
6148   "! TARGET_ARCH64"
6149   "jmp\t%a0%#"
6150   [(set_attr "type" "uncond_branch")])
6152 (define_insn "*tablejump_sp64"
6153   [(set (pc) (match_operand:DI 0 "address_operand" "p"))
6154    (use (label_ref (match_operand 1 "" "")))]
6155   "TARGET_ARCH64"
6156   "jmp\t%a0%#"
6157   [(set_attr "type" "uncond_branch")])
6160 ;; Jump to subroutine instructions.
6162 (define_expand "call"
6163   ;; Note that this expression is not used for generating RTL.
6164   ;; All the RTL is generated explicitly below.
6165   [(call (match_operand 0 "call_operand" "")
6166          (match_operand 3 "" "i"))]
6167   ;; operands[2] is next_arg_register
6168   ;; operands[3] is struct_value_size_rtx.
6169   ""
6171   rtx fn_rtx;
6173   gcc_assert (MEM_P (operands[0]) && GET_MODE (operands[0]) == FUNCTION_MODE);
6175   gcc_assert (GET_CODE (operands[3]) == CONST_INT);
6177   if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
6178     {
6179       /* This is really a PIC sequence.  We want to represent
6180          it as a funny jump so its delay slots can be filled. 
6182          ??? But if this really *is* a CALL, will not it clobber the
6183          call-clobbered registers?  We lose this if it is a JUMP_INSN.
6184          Why cannot we have delay slots filled if it were a CALL?  */
6186       /* We accept negative sizes for untyped calls.  */
6187       if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6188         emit_jump_insn
6189           (gen_rtx_PARALLEL
6190            (VOIDmode,
6191             gen_rtvec (3,
6192                        gen_rtx_SET (pc_rtx, XEXP (operands[0], 0)),
6193                        operands[3],
6194                        gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6195       else
6196         emit_jump_insn
6197           (gen_rtx_PARALLEL
6198            (VOIDmode,
6199             gen_rtvec (2,
6200                        gen_rtx_SET (pc_rtx, XEXP (operands[0], 0)),
6201                        gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6202       goto finish_call;
6203     }
6205   fn_rtx = operands[0];
6207   /* We accept negative sizes for untyped calls.  */
6208   if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6209     sparc_emit_call_insn
6210       (gen_rtx_PARALLEL
6211        (VOIDmode,
6212         gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6213                    operands[3],
6214                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6215        XEXP (fn_rtx, 0));
6216   else
6217     sparc_emit_call_insn
6218       (gen_rtx_PARALLEL
6219        (VOIDmode,
6220         gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6221                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6222        XEXP (fn_rtx, 0));
6224  finish_call:
6226   DONE;
6229 ;; We can't use the same pattern for these two insns, because then registers
6230 ;; in the address may not be properly reloaded.
6232 (define_insn "*call_address_sp32"
6233   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6234          (match_operand 1 "" ""))
6235    (clobber (reg:SI O7_REG))]
6236   ;;- Do not use operand 1 for most machines.
6237   "! TARGET_ARCH64"
6238   "call\t%a0, %1%#"
6239   [(set_attr "type" "call")])
6241 (define_insn "*call_symbolic_sp32"
6242   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6243          (match_operand 1 "" ""))
6244    (clobber (reg:SI O7_REG))]
6245   ;;- Do not use operand 1 for most machines.
6246   "! TARGET_ARCH64"
6247   "call\t%a0, %1%#"
6248   [(set_attr "type" "call")])
6250 (define_insn "*call_address_sp64"
6251   [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
6252          (match_operand 1 "" ""))
6253    (clobber (reg:DI O7_REG))]
6254   ;;- Do not use operand 1 for most machines.
6255   "TARGET_ARCH64"
6256   "call\t%a0, %1%#"
6257   [(set_attr "type" "call")])
6259 (define_insn "*call_symbolic_sp64"
6260   [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6261          (match_operand 1 "" ""))
6262    (clobber (reg:DI O7_REG))]
6263   ;;- Do not use operand 1 for most machines.
6264   "TARGET_ARCH64"
6265   "call\t%a0, %1%#"
6266   [(set_attr "type" "call")])
6268 ;; This is a call that wants a structure value.
6269 ;; There is no such critter for v9 (??? we may need one anyway).
6270 (define_insn "*call_address_struct_value_sp32"
6271   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6272          (match_operand 1 "" ""))
6273    (match_operand 2 "immediate_operand" "")
6274    (clobber (reg:SI O7_REG))]
6275   ;;- Do not use operand 1 for most machines.
6276   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6278   operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6279   return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6281   [(set_attr "type" "call_no_delay_slot")
6282    (set_attr "length" "3")])
6284 ;; This is a call that wants a structure value.
6285 ;; There is no such critter for v9 (??? we may need one anyway).
6286 (define_insn "*call_symbolic_struct_value_sp32"
6287   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6288          (match_operand 1 "" ""))
6289    (match_operand 2 "immediate_operand" "")
6290    (clobber (reg:SI O7_REG))]
6291   ;;- Do not use operand 1 for most machines.
6292   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6294   operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6295   return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6297   [(set_attr "type" "call_no_delay_slot")
6298    (set_attr "length" "3")])
6300 ;; This is a call that may want a structure value.  This is used for
6301 ;; untyped_calls.
6302 (define_insn "*call_address_untyped_struct_value_sp32"
6303   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6304          (match_operand 1 "" ""))
6305    (match_operand 2 "immediate_operand" "")
6306    (clobber (reg:SI O7_REG))]
6307   ;;- Do not use operand 1 for most machines.
6308   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6309   "call\t%a0, %1\n\t nop\n\tnop"
6310   [(set_attr "type" "call_no_delay_slot")
6311    (set_attr "length" "3")])
6313 ;; This is a call that may want a structure value.  This is used for
6314 ;; untyped_calls.
6315 (define_insn "*call_symbolic_untyped_struct_value_sp32"
6316   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6317          (match_operand 1 "" ""))
6318    (match_operand 2 "immediate_operand" "")
6319    (clobber (reg:SI O7_REG))]
6320   ;;- Do not use operand 1 for most machines.
6321   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6322   "call\t%a0, %1\n\t nop\n\tnop"
6323   [(set_attr "type" "call_no_delay_slot")
6324    (set_attr "length" "3")])
6326 (define_expand "call_value"
6327   ;; Note that this expression is not used for generating RTL.
6328   ;; All the RTL is generated explicitly below.
6329   [(set (match_operand 0 "register_operand" "=rf")
6330         (call (match_operand 1 "" "")
6331               (match_operand 4 "" "")))]
6332   ;; operand 2 is stack_size_rtx
6333   ;; operand 3 is next_arg_register
6334   ""
6336   rtx fn_rtx;
6337   rtvec vec;
6339   gcc_assert (MEM_P (operands[1]) && GET_MODE (operands[1]) == FUNCTION_MODE);
6341   fn_rtx = operands[1];
6343   vec = gen_rtvec (2,
6344                    gen_rtx_SET (operands[0],
6345                                 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
6346                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
6348   sparc_emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec), XEXP (fn_rtx, 0));
6350   DONE;
6353 (define_insn "*call_value_address_sp32"
6354   [(set (match_operand 0 "" "=rf")
6355         (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
6356               (match_operand 2 "" "")))
6357    (clobber (reg:SI O7_REG))]
6358   ;;- Do not use operand 2 for most machines.
6359   "! TARGET_ARCH64"
6360   "call\t%a1, %2%#"
6361   [(set_attr "type" "call")])
6363 (define_insn "*call_value_symbolic_sp32"
6364   [(set (match_operand 0 "" "=rf")
6365         (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6366               (match_operand 2 "" "")))
6367    (clobber (reg:SI O7_REG))]
6368   ;;- Do not use operand 2 for most machines.
6369   "! TARGET_ARCH64"
6370   "call\t%a1, %2%#"
6371   [(set_attr "type" "call")])
6373 (define_insn "*call_value_address_sp64"
6374   [(set (match_operand 0 "" "")
6375         (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
6376               (match_operand 2 "" "")))
6377    (clobber (reg:DI 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_sp64"
6384   [(set (match_operand 0 "" "")
6385         (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6386               (match_operand 2 "" "")))
6387    (clobber (reg:DI 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_expand "untyped_call"
6394   [(parallel [(call (match_operand 0 "" "")
6395                     (const_int 0))
6396               (match_operand:BLK 1 "memory_operand" "")
6397               (match_operand 2 "" "")])]
6398   ""
6400   rtx valreg1 = gen_rtx_REG (DImode, 8);
6401   rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6402   rtx result = operands[1];
6404   /* Pass constm1 to indicate that it may expect a structure value, but
6405      we don't know what size it is.  */
6406   emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
6408   /* Save the function value registers.  */
6409   emit_move_insn (adjust_address (result, DImode, 0), valreg1);
6410   emit_move_insn (adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8),
6411                                   valreg2);
6413   /* The optimizer does not know that the call sets the function value
6414      registers we stored in the result block.  We avoid problems by
6415      claiming that all hard registers are used and clobbered at this
6416      point.  */
6417   emit_insn (gen_blockage ());
6419   DONE;
6422 ;;  Tail call instructions.
6424 (define_expand "sibcall"
6425   [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
6426               (return)])]
6427   ""
6428   "")
6430 (define_insn "*sibcall_symbolic_sp32"
6431   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6432          (match_operand 1 "" ""))
6433    (return)]
6434   "! TARGET_ARCH64"
6435   "* return output_sibcall(insn, operands[0]);"
6436   [(set_attr "type" "sibcall")])
6438 (define_insn "*sibcall_symbolic_sp64"
6439   [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6440          (match_operand 1 "" ""))
6441    (return)]
6442   "TARGET_ARCH64"
6443   "* return output_sibcall(insn, operands[0]);"
6444   [(set_attr "type" "sibcall")])
6446 (define_expand "sibcall_value"
6447   [(parallel [(set (match_operand 0 "register_operand" "=rf")
6448                 (call (match_operand 1 "" "") (const_int 0)))
6449               (return)])]
6450   ""
6451   "")
6453 (define_insn "*sibcall_value_symbolic_sp32"
6454   [(set (match_operand 0 "" "=rf")
6455         (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6456               (match_operand 2 "" "")))
6457    (return)]
6458   "! TARGET_ARCH64"
6459   "* return output_sibcall(insn, operands[1]);"
6460   [(set_attr "type" "sibcall")])
6462 (define_insn "*sibcall_value_symbolic_sp64"
6463   [(set (match_operand 0 "" "")
6464         (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6465               (match_operand 2 "" "")))
6466    (return)]
6467   "TARGET_ARCH64"
6468   "* return output_sibcall(insn, operands[1]);"
6469   [(set_attr "type" "sibcall")])
6472 ;; Special instructions.
6474 (define_expand "prologue"
6475   [(const_int 0)]
6476   ""
6478   if (TARGET_FLAT)
6479     sparc_flat_expand_prologue ();
6480   else
6481     sparc_expand_prologue ();
6482   DONE;
6485 ;; The "register window save" insn is modelled as follows.  The dwarf2
6486 ;; information is manually added in emit_window_save.
6488 (define_insn "window_save"
6489   [(unspec_volatile
6490         [(match_operand 0 "arith_operand" "rI")]
6491         UNSPECV_SAVEW)]
6492   "!TARGET_FLAT"
6493   "save\t%%sp, %0, %%sp"
6494   [(set_attr "type" "savew")])
6496 (define_expand "epilogue"
6497   [(return)]
6498   ""
6500   if (TARGET_FLAT)
6501     sparc_flat_expand_epilogue (false);
6502   else
6503     sparc_expand_epilogue (false);
6506 (define_expand "sibcall_epilogue"
6507   [(return)]
6508   ""
6510   if (TARGET_FLAT)
6511     sparc_flat_expand_epilogue (false);
6512   else
6513     sparc_expand_epilogue (false);
6514   DONE;
6517 (define_expand "eh_return"
6518   [(use (match_operand 0 "general_operand" ""))]
6519   ""
6521   emit_move_insn (gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM), operands[0]);
6522   emit_jump_insn (gen_eh_return_internal ());
6523   emit_barrier ();
6524   DONE;
6527 (define_insn_and_split "eh_return_internal"
6528   [(eh_return)]
6529   ""
6530   "#"
6531   "epilogue_completed"
6532   [(return)]
6534   if (TARGET_FLAT)
6535     sparc_flat_expand_epilogue (true);
6536   else
6537     sparc_expand_epilogue (true);
6540 (define_expand "return"
6541   [(return)]
6542   "sparc_can_use_return_insn_p ()"
6543   "")
6545 (define_insn "*return_internal"
6546   [(return)]
6547   ""
6548   "* return output_return (insn);"
6549   [(set_attr "type" "return")
6550    (set (attr "length")
6551         (cond [(eq_attr "calls_eh_return" "true")
6552                  (if_then_else (eq_attr "delayed_branch" "true")
6553                                 (if_then_else (ior (eq_attr "isa" "v9")
6554                                                    (eq_attr "flat" "true"))
6555                                         (const_int 2)
6556                                         (const_int 3))
6557                                 (if_then_else (eq_attr "flat" "true")
6558                                         (const_int 3)
6559                                         (const_int 4)))
6560                (ior (eq_attr "leaf_function" "true") (eq_attr "flat" "true"))
6561                  (if_then_else (eq_attr "empty_delay_slot" "true")
6562                                (const_int 2)
6563                                (const_int 1))
6564                (eq_attr "empty_delay_slot" "true")
6565                  (if_then_else (eq_attr "delayed_branch" "true")
6566                                (const_int 2)
6567                                (const_int 3))
6568               ] (const_int 1)))])
6570 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
6571 ;; all of memory.  This blocks insns from being moved across this point.
6573 (define_insn "blockage"
6574   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
6575   ""
6576   ""
6577   [(set_attr "length" "0")])
6579 ;; Do not schedule instructions accessing memory before this point.
6581 (define_expand "frame_blockage"
6582   [(set (match_dup 0)
6583         (unspec:BLK [(match_dup 1)] UNSPEC_FRAME_BLOCKAGE))]
6584   ""
6586   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
6587   MEM_VOLATILE_P (operands[0]) = 1;
6588   operands[1] = stack_pointer_rtx;
6591 (define_insn "*frame_blockage<P:mode>"
6592   [(set (match_operand:BLK 0 "" "")
6593         (unspec:BLK [(match_operand:P 1 "" "")] UNSPEC_FRAME_BLOCKAGE))]
6594   ""
6595   ""
6596   [(set_attr "length" "0")])
6598 (define_expand "probe_stack"
6599   [(set (match_operand 0 "memory_operand" "") (const_int 0))]
6600   ""
6602   operands[0]
6603     = adjust_address (operands[0], GET_MODE (operands[0]), SPARC_STACK_BIAS);
6606 (define_insn "probe_stack_range<P:mode>"
6607   [(set (match_operand:P 0 "register_operand" "=r")
6608         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
6609                             (match_operand:P 2 "register_operand" "r")]
6610                             UNSPECV_PROBE_STACK_RANGE))]
6611   ""
6612   "* return output_probe_stack_range (operands[0], operands[2]);"
6613   [(set_attr "type" "multi")])
6615 ;; Prepare to return any type including a structure value.
6617 (define_expand "untyped_return"
6618   [(match_operand:BLK 0 "memory_operand" "")
6619    (match_operand 1 "" "")]
6620   ""
6622   rtx valreg1 = gen_rtx_REG (DImode, 24);
6623   rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6624   rtx result = operands[0];
6626   if (! TARGET_ARCH64)
6627     {
6628       rtx rtnreg = gen_rtx_REG (SImode, RETURN_ADDR_REGNUM);
6629       rtx value = gen_reg_rtx (SImode);
6631       /* Fetch the instruction where we will return to and see if it's an unimp
6632          instruction (the most significant 10 bits will be zero).  If so,
6633          update the return address to skip the unimp instruction.  */
6634       emit_move_insn (value,
6635                       gen_rtx_MEM (SImode, plus_constant (SImode, rtnreg, 8)));
6636       emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
6637       emit_insn (gen_update_return (rtnreg, value));
6638     }
6640   /* Reload the function value registers.  */
6641   emit_move_insn (valreg1, adjust_address (result, DImode, 0));
6642   emit_move_insn (valreg2,
6643                   adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
6645   /* Put USE insns before the return.  */
6646   emit_use (valreg1);
6647   emit_use (valreg2);
6649   /* Construct the return.  */
6650   expand_naked_return ();
6652   DONE;
6655 ;; Adjust the return address conditionally. If the value of op1 is equal
6656 ;; to all zero then adjust the return address i.e. op0 = op0 + 4.
6657 ;; This is technically *half* the check required by the 32-bit SPARC
6658 ;; psABI. This check only ensures that an "unimp" insn was written by
6659 ;; the caller, but doesn't check to see if the expected size matches
6660 ;; (this is encoded in the 12 lower bits). This check is obsolete and
6661 ;; only used by the above code "untyped_return".
6663 (define_insn "update_return"
6664   [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
6665                (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
6666   "! TARGET_ARCH64"
6668   if (flag_delayed_branch)
6669     return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
6670   else
6671     return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
6673   [(set (attr "type") (const_string "multi"))
6674    (set (attr "length")
6675         (if_then_else (eq_attr "delayed_branch" "true")
6676                       (const_int 3)
6677                       (const_int 4)))])
6679 (define_insn "nop"
6680   [(const_int 0)]
6681   ""
6682   "nop")
6684 (define_expand "indirect_jump"
6685   [(set (pc) (match_operand 0 "address_operand" "p"))]
6686   ""
6687   "")
6689 (define_insn "*branch_sp32"
6690   [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
6691   "! TARGET_ARCH64"
6692  "jmp\t%a0%#"
6693  [(set_attr "type" "uncond_branch")])
6695 (define_insn "*branch_sp64"
6696   [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
6697   "TARGET_ARCH64"
6698   "jmp\t%a0%#"
6699   [(set_attr "type" "uncond_branch")])
6701 (define_expand "save_stack_nonlocal"
6702   [(set (match_operand 0 "memory_operand" "")
6703         (match_operand 1 "register_operand" ""))
6704    (set (match_dup 2) (match_dup 3))]
6705   ""
6707   operands[0] = adjust_address_nv (operands[0], Pmode, 0);
6708   operands[2] = adjust_address_nv (operands[0], Pmode, GET_MODE_SIZE (Pmode));
6709   operands[3] = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
6712 (define_expand "restore_stack_nonlocal"
6713   [(set (match_operand 0 "register_operand" "")
6714         (match_operand 1 "memory_operand" ""))]
6715   ""
6717   operands[1] = adjust_address_nv (operands[1], Pmode, 0);
6720 (define_expand "nonlocal_goto"
6721   [(match_operand 0 "general_operand" "")
6722    (match_operand 1 "general_operand" "")
6723    (match_operand 2 "memory_operand" "")
6724    (match_operand 3 "memory_operand" "")]
6725   ""
6727   rtx i7 = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
6728   rtx r_label = copy_to_reg (operands[1]);
6729   rtx r_sp = adjust_address_nv (operands[2], Pmode, 0);
6730   rtx r_fp = operands[3];
6731   rtx r_i7 = adjust_address_nv (operands[2], Pmode, GET_MODE_SIZE (Pmode));
6733   /* We need to flush all the register windows so that their contents will
6734      be re-synchronized by the restore insn of the target function.  */
6735   if (!TARGET_FLAT)
6736     emit_insn (gen_flush_register_windows ());
6738   emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
6739   emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
6741   /* Restore frame pointer for containing function.  */
6742   emit_move_insn (hard_frame_pointer_rtx, r_fp);
6743   emit_stack_restore (SAVE_NONLOCAL, r_sp);
6744   emit_move_insn (i7, r_i7);
6746   /* USE of hard_frame_pointer_rtx added for consistency;
6747      not clear if really needed.  */
6748   emit_use (hard_frame_pointer_rtx);
6749   emit_use (stack_pointer_rtx);
6750   emit_use (i7);
6752   emit_jump_insn (gen_indirect_jump (r_label));
6753   emit_barrier ();
6754   DONE;
6757 (define_expand "builtin_setjmp_receiver"
6758   [(label_ref (match_operand 0 "" ""))]
6759   "flag_pic"
6761   load_got_register ();
6762   DONE;
6765 ;; Special insn to flush register windows.
6767 (define_insn "flush_register_windows"
6768   [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
6769   ""
6770   { return TARGET_V9 ? "flushw" : "ta\t3"; }
6771   [(set_attr "type" "flushw")])
6773 ;; Special pattern for the FLUSH instruction.
6775 (define_insn "flush<P:mode>"
6776   [(unspec_volatile [(match_operand:P 0 "memory_operand" "m")] UNSPECV_FLUSH)]
6777   ""
6778   { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
6779   [(set_attr "type" "iflush")])
6781 ;; Special insns to load and store the 32-bit FP Status Register.
6783 (define_insn "ldfsr"
6784   [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_LDFSR)]
6785   "TARGET_FPU"
6786   "ld\t%0, %%fsr"
6787   [(set_attr "type" "load")])
6789 (define_insn "stfsr"
6790   [(set (match_operand:SI 0 "memory_operand" "=m")
6791         (unspec_volatile:SI [(const_int 0)] UNSPECV_STFSR))]
6792   "TARGET_FPU"
6793   "st\t%%fsr, %0"
6794   [(set_attr "type" "store")])
6797 ;; Find first set instructions.
6799 ;; The scan instruction searches from the most significant bit while ffs
6800 ;; searches from the least significant bit.  The bit index and treatment of
6801 ;; zero also differ.  It takes at least 7 instructions to get the proper
6802 ;; result.  Here is an obvious 8 instruction sequence.
6804 ;; XXX
6805 (define_insn "ffssi2"
6806   [(set (match_operand:SI 0 "register_operand" "=&r")
6807         (ffs:SI (match_operand:SI 1 "register_operand" "r")))
6808    (clobber (match_scratch:SI 2 "=&r"))]
6809   "TARGET_SPARCLITE || TARGET_SPARCLET"
6811   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";
6813   [(set_attr "type" "multi")
6814    (set_attr "length" "8")])
6816 (define_expand "popcountdi2"
6817   [(set (match_operand:DI 0 "register_operand" "")
6818         (popcount:DI (match_operand:DI 1 "register_operand" "")))]
6819   "TARGET_POPC"
6821   if (! TARGET_ARCH64)
6822     {
6823       emit_insn (gen_popcountdi_v8plus (operands[0], operands[1]));
6824       DONE;
6825     }
6828 (define_insn "*popcountdi_sp64"
6829   [(set (match_operand:DI 0 "register_operand" "=r")
6830         (popcount:DI (match_operand:DI 1 "register_operand" "r")))]
6831   "TARGET_POPC && TARGET_ARCH64"
6832   "popc\t%1, %0")
6834 (define_insn "popcountdi_v8plus"
6835   [(set (match_operand:DI 0 "register_operand" "=r")
6836         (popcount:DI (match_operand:DI 1 "register_operand" "r")))
6837    (clobber (match_scratch:SI 2 "=&h"))]
6838   "TARGET_POPC && ! TARGET_ARCH64"
6840   if (sparc_check_64 (operands[1], insn) <= 0)
6841     output_asm_insn ("srl\t%L1, 0, %L1", operands);
6842   return "sllx\t%H1, 32, %2\n\tor\t%L1, %2, %2\n\tpopc\t%2, %L0\n\tclr\t%H0";
6844   [(set_attr "type" "multi")
6845    (set_attr "length" "5")])
6847 (define_expand "popcountsi2"
6848   [(set (match_dup 2)
6849         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
6850    (set (match_operand:SI 0 "register_operand" "")
6851         (truncate:SI (popcount:DI (match_dup 2))))]
6852   "TARGET_POPC"
6854   if (! TARGET_ARCH64)
6855     {
6856       emit_insn (gen_popcountsi_v8plus (operands[0], operands[1]));
6857       DONE;
6858     }
6859   else
6860     operands[2] = gen_reg_rtx (DImode);
6863 (define_insn "*popcountsi_sp64"
6864   [(set (match_operand:SI 0 "register_operand" "=r")
6865         (truncate:SI
6866           (popcount:DI (match_operand:DI 1 "register_operand" "r"))))]
6867   "TARGET_POPC && TARGET_ARCH64"
6868   "popc\t%1, %0")
6870 (define_insn "popcountsi_v8plus"
6871   [(set (match_operand:SI 0 "register_operand" "=r")
6872         (popcount:SI (match_operand:SI 1 "register_operand" "r")))]
6873   "TARGET_POPC && ! TARGET_ARCH64"
6875   if (sparc_check_64 (operands[1], insn) <= 0)
6876     output_asm_insn ("srl\t%1, 0, %1", operands);
6877   return "popc\t%1, %0";
6879   [(set_attr "type" "multi")
6880    (set_attr "length" "2")])
6882 (define_expand "clzdi2"
6883   [(set (match_operand:DI 0 "register_operand" "")
6884         (clz:DI (match_operand:DI 1 "register_operand" "")))]
6885   "TARGET_VIS3"
6887   if (! TARGET_ARCH64)
6888     {
6889       emit_insn (gen_clzdi_v8plus (operands[0], operands[1]));
6890       DONE;
6891     }
6894 (define_insn "*clzdi_sp64"
6895   [(set (match_operand:DI 0 "register_operand" "=r")
6896         (clz:DI (match_operand:DI 1 "register_operand" "r")))]
6897   "TARGET_VIS3 && TARGET_ARCH64"
6898   "lzd\t%1, %0")
6900 (define_insn "clzdi_v8plus"
6901   [(set (match_operand:DI 0 "register_operand" "=r")
6902         (clz:DI (match_operand:DI 1 "register_operand" "r")))
6903    (clobber (match_scratch:SI 2 "=&h"))]
6904   "TARGET_VIS3 && ! TARGET_ARCH64"
6906   if (sparc_check_64 (operands[1], insn) <= 0)
6907     output_asm_insn ("srl\t%L1, 0, %L1", operands);
6908   return "sllx\t%H1, 32, %2\n\tor\t%L1, %2, %2\n\tlzd\t%2, %L0\n\tclr\t%H0";
6910   [(set_attr "type" "multi")
6911    (set_attr "length" "5")])
6913 (define_expand "clzsi2"
6914   [(set (match_dup 2)
6915         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
6916    (set (match_dup 3)
6917         (truncate:SI (clz:DI (match_dup 2))))
6918    (set (match_operand:SI 0 "register_operand" "")
6919         (minus:SI (match_dup 3) (const_int 32)))]
6920   "TARGET_VIS3"
6922   if (! TARGET_ARCH64)
6923     {
6924       emit_insn (gen_clzsi_v8plus (operands[0], operands[1]));
6925       DONE;
6926     }
6927   else
6928     {
6929       operands[2] = gen_reg_rtx (DImode);
6930       operands[3] = gen_reg_rtx (SImode);
6931     }
6934 (define_insn "*clzsi_sp64"
6935   [(set (match_operand:SI 0 "register_operand" "=r")
6936         (truncate:SI
6937           (clz:DI (match_operand:DI 1 "register_operand" "r"))))]
6938   "TARGET_VIS3 && TARGET_ARCH64"
6939   "lzd\t%1, %0")
6941 (define_insn "clzsi_v8plus"
6942   [(set (match_operand:SI 0 "register_operand" "=r")
6943         (clz:SI (match_operand:SI 1 "register_operand" "r")))]
6944   "TARGET_VIS3 && ! TARGET_ARCH64"
6946   if (sparc_check_64 (operands[1], insn) <= 0)
6947     output_asm_insn ("srl\t%1, 0, %1", operands);
6948   return "lzd\t%1, %0\n\tsub\t%0, 32, %0";
6950   [(set_attr "type" "multi")
6951    (set_attr "length" "3")])
6954 ;; Peepholes go at the end.
6956 ;; Optimize consecutive loads or stores into ldd and std when possible.
6957 ;; The conditions in which we do this are very restricted and are 
6958 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
6960 (define_peephole2
6961   [(set (match_operand:SI 0 "memory_operand" "")
6962       (const_int 0))
6963    (set (match_operand:SI 1 "memory_operand" "")
6964       (const_int 0))]
6965   "TARGET_V9
6966    && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
6967   [(set (match_dup 0) (const_int 0))]
6969   operands[0] = widen_mem_for_ldd_peep (operands[0], operands[1], DImode);
6972 (define_peephole2
6973   [(set (match_operand:SI 0 "memory_operand" "")
6974       (const_int 0))
6975    (set (match_operand:SI 1 "memory_operand" "")
6976       (const_int 0))]
6977   "TARGET_V9
6978    && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
6979   [(set (match_dup 1) (const_int 0))]
6981   operands[1] = widen_mem_for_ldd_peep (operands[1], operands[0], DImode);
6984 (define_peephole2
6985   [(set (match_operand:SI 0 "register_operand" "")
6986         (match_operand:SI 1 "memory_operand" ""))
6987    (set (match_operand:SI 2 "register_operand" "")
6988         (match_operand:SI 3 "memory_operand" ""))]
6989   "registers_ok_for_ldd_peep (operands[0], operands[2]) 
6990    && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])" 
6991   [(set (match_dup 0) (match_dup 1))]
6993   operands[1] = widen_mem_for_ldd_peep (operands[1], operands[3], DImode);
6994   operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
6997 (define_peephole2
6998   [(set (match_operand:SI 0 "memory_operand" "")
6999         (match_operand:SI 1 "register_operand" ""))
7000    (set (match_operand:SI 2 "memory_operand" "")
7001         (match_operand:SI 3 "register_operand" ""))]
7002   "registers_ok_for_ldd_peep (operands[1], operands[3]) 
7003    && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7004   [(set (match_dup 0) (match_dup 1))]
7006   operands[0] = widen_mem_for_ldd_peep (operands[0], operands[2], DImode);
7007   operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));
7010 (define_peephole2
7011   [(set (match_operand:SF 0 "register_operand" "")
7012         (match_operand:SF 1 "memory_operand" ""))
7013    (set (match_operand:SF 2 "register_operand" "")
7014         (match_operand:SF 3 "memory_operand" ""))]
7015   "registers_ok_for_ldd_peep (operands[0], operands[2]) 
7016    && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
7017   [(set (match_dup 0) (match_dup 1))]
7019   operands[1] = widen_mem_for_ldd_peep (operands[1], operands[3], DFmode);
7020   operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));
7023 (define_peephole2
7024   [(set (match_operand:SF 0 "memory_operand" "")
7025         (match_operand:SF 1 "register_operand" ""))
7026    (set (match_operand:SF 2 "memory_operand" "")
7027         (match_operand:SF 3 "register_operand" ""))]
7028   "registers_ok_for_ldd_peep (operands[1], operands[3]) 
7029   && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7030   [(set (match_dup 0) (match_dup 1))]
7032   operands[0] = widen_mem_for_ldd_peep (operands[0], operands[2], DFmode);
7033   operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));
7036 (define_peephole2
7037   [(set (match_operand:SI 0 "register_operand" "")
7038         (match_operand:SI 1 "memory_operand" ""))
7039    (set (match_operand:SI 2 "register_operand" "")
7040         (match_operand:SI 3 "memory_operand" ""))]
7041   "registers_ok_for_ldd_peep (operands[2], operands[0]) 
7042   && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
7043   [(set (match_dup 2) (match_dup 3))]
7045   operands[3] = widen_mem_for_ldd_peep (operands[3], operands[1], DImode);
7046   operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));
7049 (define_peephole2
7050   [(set (match_operand:SI 0 "memory_operand" "")
7051         (match_operand:SI 1 "register_operand" ""))
7052    (set (match_operand:SI 2 "memory_operand" "")
7053         (match_operand:SI 3 "register_operand" ""))]
7054   "registers_ok_for_ldd_peep (operands[3], operands[1]) 
7055   && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)" 
7056   [(set (match_dup 2) (match_dup 3))]
7058   operands[2] = widen_mem_for_ldd_peep (operands[2],  operands[0], DImode);
7059   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
7062 (define_peephole2
7063   [(set (match_operand:SF 0 "register_operand" "")
7064         (match_operand:SF 1 "memory_operand" ""))
7065    (set (match_operand:SF 2 "register_operand" "")
7066         (match_operand:SF 3 "memory_operand" ""))]
7067   "registers_ok_for_ldd_peep (operands[2], operands[0]) 
7068   && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
7069   [(set (match_dup 2) (match_dup 3))]
7071   operands[3] = widen_mem_for_ldd_peep (operands[3], operands[1], DFmode);
7072   operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));
7075 (define_peephole2
7076   [(set (match_operand:SF 0 "memory_operand" "")
7077         (match_operand:SF 1 "register_operand" ""))
7078    (set (match_operand:SF 2 "memory_operand" "")
7079         (match_operand:SF 3 "register_operand" ""))]
7080   "registers_ok_for_ldd_peep (operands[3], operands[1]) 
7081   && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
7082   [(set (match_dup 2) (match_dup 3))]
7084   operands[2] = widen_mem_for_ldd_peep (operands[2], operands[0], DFmode);
7085   operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));
7088 ;; Optimize the case of following a reg-reg move with a test
7089 ;; of reg just moved.  Don't allow floating point regs for operand 0 or 1.
7090 ;; This can result from a float to fix conversion.
7092 (define_peephole2
7093   [(set (match_operand:SI 0 "register_operand" "")
7094         (match_operand:SI 1 "register_operand" ""))
7095    (set (reg:CC CC_REG)
7096         (compare:CC (match_operand:SI 2 "register_operand" "")
7097                     (const_int 0)))]
7098   "(rtx_equal_p (operands[2], operands[0])
7099     || rtx_equal_p (operands[2], operands[1]))
7100     && ! SPARC_FP_REG_P (REGNO (operands[0]))
7101     && ! SPARC_FP_REG_P (REGNO (operands[1]))"
7102   [(parallel [(set (match_dup 0) (match_dup 1))
7103               (set (reg:CC CC_REG)
7104                    (compare:CC (match_dup 1) (const_int 0)))])]
7105   "")
7107 (define_peephole2
7108   [(set (match_operand:DI 0 "register_operand" "")
7109         (match_operand:DI 1 "register_operand" ""))
7110    (set (reg:CCX CC_REG)
7111         (compare:CCX (match_operand:DI 2 "register_operand" "")
7112                     (const_int 0)))]
7113   "TARGET_ARCH64
7114    && (rtx_equal_p (operands[2], operands[0])
7115        || rtx_equal_p (operands[2], operands[1]))
7116    && ! SPARC_FP_REG_P (REGNO (operands[0]))
7117    && ! SPARC_FP_REG_P (REGNO (operands[1]))"
7118   [(parallel [(set (match_dup 0) (match_dup 1))
7119               (set (reg:CCX CC_REG)
7120                    (compare:CCX (match_dup 1) (const_int 0)))])]
7121   "")
7124 ;; Prefetch instructions.
7126 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
7127 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
7128 ;; ??? operations.  With DFA we might be able to model this, but it requires a lot of
7129 ;; ??? state.
7130 (define_expand "prefetch"
7131   [(match_operand 0 "address_operand" "")
7132    (match_operand 1 "const_int_operand" "")
7133    (match_operand 2 "const_int_operand" "")]
7134   "TARGET_V9"
7136   if (TARGET_ARCH64)
7137     emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
7138   else
7139     emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
7140   DONE;
7143 (define_insn "prefetch_64"
7144   [(prefetch (match_operand:DI 0 "address_operand" "p")
7145              (match_operand:DI 1 "const_int_operand" "n")
7146              (match_operand:DI 2 "const_int_operand" "n"))]
7147   ""
7149   static const char * const prefetch_instr[2][2] = {
7150     {
7151       "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7152       "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7153     },
7154     {
7155       "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7156       "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7157     }
7158   };
7159   int read_or_write = INTVAL (operands[1]);
7160   int locality = INTVAL (operands[2]);
7162   gcc_assert (read_or_write == 0 || read_or_write == 1);
7163   gcc_assert (locality >= 0 && locality < 4);
7164   return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7166   [(set_attr "type" "load")])
7168 (define_insn "prefetch_32"
7169   [(prefetch (match_operand:SI 0 "address_operand" "p")
7170              (match_operand:SI 1 "const_int_operand" "n")
7171              (match_operand:SI 2 "const_int_operand" "n"))]
7172   ""
7174   static const char * const prefetch_instr[2][2] = {
7175     {
7176       "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7177       "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7178     },
7179     {
7180       "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7181       "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7182     }
7183   };
7184   int read_or_write = INTVAL (operands[1]);
7185   int locality = INTVAL (operands[2]);
7187   gcc_assert (read_or_write == 0 || read_or_write == 1);
7188   gcc_assert (locality >= 0 && locality < 4);
7189   return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7191   [(set_attr "type" "load")])
7194 ;; Trap instructions.
7196 (define_insn "trap"
7197   [(trap_if (const_int 1) (const_int 5))]
7198   ""
7199   "ta\t5"
7200   [(set_attr "type" "trap")])
7202 (define_expand "ctrapsi4"
7203   [(trap_if (match_operator 0 "noov_compare_operator"
7204              [(match_operand:SI 1 "compare_operand" "")
7205               (match_operand:SI 2 "arith_operand" "")])
7206            (match_operand 3 "arith_operand"))]
7207   ""
7208   "operands[1] = gen_compare_reg (operands[0]);
7209    if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
7210      FAIL;
7211    operands[2] = const0_rtx;")
7213 (define_expand "ctrapdi4"
7214   [(trap_if (match_operator 0 "noov_compare_operator"
7215              [(match_operand:DI 1 "compare_operand" "")
7216               (match_operand:DI 2 "arith_operand" "")])
7217            (match_operand 3 "arith_operand"))]
7218   "TARGET_ARCH64"
7219   "operands[1] = gen_compare_reg (operands[0]);
7220    if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
7221      FAIL;
7222    operands[2] = const0_rtx;")
7225 (define_insn ""
7226   [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CC CC_REG) (const_int 0)])
7227             (match_operand:SI 1 "arith_operand" "rM"))]
7228   ""
7230   if (TARGET_V9)
7231     return "t%C0\t%%icc, %1";
7232   else
7233     return "t%C0\t%1";
7235   [(set_attr "type" "trap")])
7237 (define_insn ""
7238   [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CCX CC_REG) (const_int 0)])
7239             (match_operand:SI 1 "arith_operand" "rM"))]
7240   "TARGET_V9"
7241   "t%C0\t%%xcc, %1"
7242   [(set_attr "type" "trap")])
7245 ;; TLS support instructions.
7247 (define_insn "tgd_hi22"
7248   [(set (match_operand:SI 0 "register_operand" "=r")
7249         (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
7250                             UNSPEC_TLSGD)))]
7251   "TARGET_TLS"
7252   "sethi\\t%%tgd_hi22(%a1), %0")
7254 (define_insn "tgd_lo10"
7255   [(set (match_operand:SI 0 "register_operand" "=r")
7256         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7257                    (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
7258                               UNSPEC_TLSGD)))]
7259   "TARGET_TLS"
7260   "add\\t%1, %%tgd_lo10(%a2), %0")
7262 (define_insn "tgd_add32"
7263   [(set (match_operand:SI 0 "register_operand" "=r")
7264         (plus:SI (match_operand:SI 1 "register_operand" "r")
7265                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7266                              (match_operand 3 "tgd_symbolic_operand" "")]
7267                             UNSPEC_TLSGD)))]
7268   "TARGET_TLS && TARGET_ARCH32"
7269   "add\\t%1, %2, %0, %%tgd_add(%a3)")
7271 (define_insn "tgd_add64"
7272   [(set (match_operand:DI 0 "register_operand" "=r")
7273         (plus:DI (match_operand:DI 1 "register_operand" "r")
7274                  (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7275                              (match_operand 3 "tgd_symbolic_operand" "")]
7276                             UNSPEC_TLSGD)))]
7277   "TARGET_TLS && TARGET_ARCH64"
7278   "add\\t%1, %2, %0, %%tgd_add(%a3)")
7280 (define_insn "tgd_call32"
7281   [(set (match_operand 0 "register_operand" "=r")
7282         (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
7283                                   (match_operand 2 "tgd_symbolic_operand" "")]
7284                                  UNSPEC_TLSGD))
7285               (match_operand 3 "" "")))
7286    (clobber (reg:SI O7_REG))]
7287   "TARGET_TLS && TARGET_ARCH32"
7288   "call\t%a1, %%tgd_call(%a2)%#"
7289   [(set_attr "type" "call")])
7291 (define_insn "tgd_call64"
7292   [(set (match_operand 0 "register_operand" "=r")
7293         (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
7294                                   (match_operand 2 "tgd_symbolic_operand" "")]
7295                                  UNSPEC_TLSGD))
7296               (match_operand 3 "" "")))
7297    (clobber (reg:DI O7_REG))]
7298   "TARGET_TLS && TARGET_ARCH64"
7299   "call\t%a1, %%tgd_call(%a2)%#"
7300   [(set_attr "type" "call")])
7302 (define_insn "tldm_hi22"
7303   [(set (match_operand:SI 0 "register_operand" "=r")
7304         (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7305   "TARGET_TLS"
7306   "sethi\\t%%tldm_hi22(%&), %0")
7308 (define_insn "tldm_lo10"
7309   [(set (match_operand:SI 0 "register_operand" "=r")
7310         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7311                     (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7312   "TARGET_TLS"
7313   "add\\t%1, %%tldm_lo10(%&), %0")
7315 (define_insn "tldm_add32"
7316   [(set (match_operand:SI 0 "register_operand" "=r")
7317         (plus:SI (match_operand:SI 1 "register_operand" "r")
7318                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
7319                             UNSPEC_TLSLDM)))]
7320   "TARGET_TLS && TARGET_ARCH32"
7321   "add\\t%1, %2, %0, %%tldm_add(%&)")
7323 (define_insn "tldm_add64"
7324   [(set (match_operand:DI 0 "register_operand" "=r")
7325         (plus:DI (match_operand:DI 1 "register_operand" "r")
7326                  (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
7327                             UNSPEC_TLSLDM)))]
7328   "TARGET_TLS && TARGET_ARCH64"
7329   "add\\t%1, %2, %0, %%tldm_add(%&)")
7331 (define_insn "tldm_call32"
7332   [(set (match_operand 0 "register_operand" "=r")
7333         (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
7334                                  UNSPEC_TLSLDM))
7335               (match_operand 2 "" "")))
7336    (clobber (reg:SI O7_REG))]
7337   "TARGET_TLS && TARGET_ARCH32"
7338   "call\t%a1, %%tldm_call(%&)%#"
7339   [(set_attr "type" "call")])
7341 (define_insn "tldm_call64"
7342   [(set (match_operand 0 "register_operand" "=r")
7343         (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
7344                                  UNSPEC_TLSLDM))
7345               (match_operand 2 "" "")))
7346    (clobber (reg:DI O7_REG))]
7347   "TARGET_TLS && TARGET_ARCH64"
7348   "call\t%a1, %%tldm_call(%&)%#"
7349   [(set_attr "type" "call")])
7351 (define_insn "tldo_hix22"
7352   [(set (match_operand:SI 0 "register_operand" "=r")
7353         (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
7354                             UNSPEC_TLSLDO)))]
7355   "TARGET_TLS"
7356   "sethi\\t%%tldo_hix22(%a1), %0")
7358 (define_insn "tldo_lox10"
7359   [(set (match_operand:SI 0 "register_operand" "=r")
7360         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7361                    (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
7362                               UNSPEC_TLSLDO)))]
7363   "TARGET_TLS"
7364   "xor\\t%1, %%tldo_lox10(%a2), %0")
7366 (define_insn "tldo_add32"
7367   [(set (match_operand:SI 0 "register_operand" "=r")
7368         (plus:SI (match_operand:SI 1 "register_operand" "r")
7369                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7370                              (match_operand 3 "tld_symbolic_operand" "")]
7371                             UNSPEC_TLSLDO)))]
7372   "TARGET_TLS && TARGET_ARCH32"
7373   "add\\t%1, %2, %0, %%tldo_add(%a3)")
7375 (define_insn "tldo_add64"
7376   [(set (match_operand:DI 0 "register_operand" "=r")
7377         (plus:DI (match_operand:DI 1 "register_operand" "r")
7378                  (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7379                              (match_operand 3 "tld_symbolic_operand" "")]
7380                             UNSPEC_TLSLDO)))]
7381   "TARGET_TLS && TARGET_ARCH64"
7382   "add\\t%1, %2, %0, %%tldo_add(%a3)")
7384 (define_insn "tie_hi22"
7385   [(set (match_operand:SI 0 "register_operand" "=r")
7386         (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
7387                             UNSPEC_TLSIE)))]
7388   "TARGET_TLS"
7389   "sethi\\t%%tie_hi22(%a1), %0")
7391 (define_insn "tie_lo10"
7392   [(set (match_operand:SI 0 "register_operand" "=r")
7393         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7394                    (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
7395                               UNSPEC_TLSIE)))]
7396   "TARGET_TLS"
7397   "add\\t%1, %%tie_lo10(%a2), %0")
7399 (define_insn "tie_ld32"
7400   [(set (match_operand:SI 0 "register_operand" "=r")
7401         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
7402                     (match_operand:SI 2 "register_operand" "r")
7403                     (match_operand 3 "tie_symbolic_operand" "")]
7404                    UNSPEC_TLSIE))]
7405   "TARGET_TLS && TARGET_ARCH32"
7406   "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
7407   [(set_attr "type" "load")])
7409 (define_insn "tie_ld64"
7410   [(set (match_operand:DI 0 "register_operand" "=r")
7411         (unspec:DI [(match_operand:DI 1 "register_operand" "r")
7412                     (match_operand:SI 2 "register_operand" "r")
7413                     (match_operand 3 "tie_symbolic_operand" "")]
7414                    UNSPEC_TLSIE))]
7415   "TARGET_TLS && TARGET_ARCH64"
7416   "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
7417   [(set_attr "type" "load")])
7419 (define_insn "tie_add32"
7420   [(set (match_operand:SI 0 "register_operand" "=r")
7421         (plus:SI (match_operand:SI 1 "register_operand" "r")
7422                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7423                              (match_operand 3 "tie_symbolic_operand" "")]
7424                             UNSPEC_TLSIE)))]
7425   "TARGET_SUN_TLS && TARGET_ARCH32"
7426   "add\\t%1, %2, %0, %%tie_add(%a3)")
7428 (define_insn "tie_add64"
7429   [(set (match_operand:DI 0 "register_operand" "=r")
7430         (plus:DI (match_operand:DI 1 "register_operand" "r")
7431                  (unspec:DI [(match_operand:DI 2 "register_operand" "r")
7432                              (match_operand 3 "tie_symbolic_operand" "")]
7433                             UNSPEC_TLSIE)))]
7434   "TARGET_SUN_TLS && TARGET_ARCH64"
7435   "add\\t%1, %2, %0, %%tie_add(%a3)")
7437 (define_insn "tle_hix22_sp32"
7438   [(set (match_operand:SI 0 "register_operand" "=r")
7439         (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
7440                             UNSPEC_TLSLE)))]
7441   "TARGET_TLS && TARGET_ARCH32"
7442   "sethi\\t%%tle_hix22(%a1), %0")
7444 (define_insn "tle_lox10_sp32"
7445   [(set (match_operand:SI 0 "register_operand" "=r")
7446         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7447                    (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
7448                               UNSPEC_TLSLE)))]
7449   "TARGET_TLS && TARGET_ARCH32"
7450   "xor\\t%1, %%tle_lox10(%a2), %0")
7452 (define_insn "tle_hix22_sp64"
7453   [(set (match_operand:DI 0 "register_operand" "=r")
7454         (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
7455                             UNSPEC_TLSLE)))]
7456   "TARGET_TLS && TARGET_ARCH64"
7457   "sethi\\t%%tle_hix22(%a1), %0")
7459 (define_insn "tle_lox10_sp64"
7460   [(set (match_operand:DI 0 "register_operand" "=r")
7461         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
7462                    (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
7463                               UNSPEC_TLSLE)))]
7464   "TARGET_TLS && TARGET_ARCH64"
7465   "xor\\t%1, %%tle_lox10(%a2), %0")
7467 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
7468 (define_insn "*tldo_ldub_sp32"
7469   [(set (match_operand:QI 0 "register_operand" "=r")
7470         (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7471                                      (match_operand 3 "tld_symbolic_operand" "")]
7472                                     UNSPEC_TLSLDO)
7473                          (match_operand:SI 1 "register_operand" "r"))))]
7474   "TARGET_TLS && TARGET_ARCH32"
7475   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7476   [(set_attr "type" "load")
7477    (set_attr "us3load_type" "3cycle")])
7479 (define_insn "*tldo_ldub1_sp32"
7480   [(set (match_operand:HI 0 "register_operand" "=r")
7481         (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7482                                                      (match_operand 3 "tld_symbolic_operand" "")]
7483                                                     UNSPEC_TLSLDO)
7484                                          (match_operand:SI 1 "register_operand" "r")))))]
7485   "TARGET_TLS && TARGET_ARCH32"
7486   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7487   [(set_attr "type" "load")
7488    (set_attr "us3load_type" "3cycle")])
7490 (define_insn "*tldo_ldub2_sp32"
7491   [(set (match_operand:SI 0 "register_operand" "=r")
7492         (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7493                                                      (match_operand 3 "tld_symbolic_operand" "")]
7494                                                     UNSPEC_TLSLDO)
7495                                          (match_operand:SI 1 "register_operand" "r")))))]
7496   "TARGET_TLS && TARGET_ARCH32"
7497   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7498   [(set_attr "type" "load")
7499    (set_attr "us3load_type" "3cycle")])
7501 (define_insn "*tldo_ldsb1_sp32"
7502   [(set (match_operand:HI 0 "register_operand" "=r")
7503         (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7504                                                      (match_operand 3 "tld_symbolic_operand" "")]
7505                                                     UNSPEC_TLSLDO)
7506                                          (match_operand:SI 1 "register_operand" "r")))))]
7507   "TARGET_TLS && TARGET_ARCH32"
7508   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7509   [(set_attr "type" "sload")
7510    (set_attr "us3load_type" "3cycle")])
7512 (define_insn "*tldo_ldsb2_sp32"
7513   [(set (match_operand:SI 0 "register_operand" "=r")
7514         (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7515                                                      (match_operand 3 "tld_symbolic_operand" "")]
7516                                                     UNSPEC_TLSLDO)
7517                                          (match_operand:SI 1 "register_operand" "r")))))]
7518   "TARGET_TLS && TARGET_ARCH32"
7519   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7520   [(set_attr "type" "sload")
7521    (set_attr "us3load_type" "3cycle")])
7523 (define_insn "*tldo_ldub_sp64"
7524   [(set (match_operand:QI 0 "register_operand" "=r")
7525         (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7526                                      (match_operand 3 "tld_symbolic_operand" "")]
7527                                     UNSPEC_TLSLDO)
7528                          (match_operand:DI 1 "register_operand" "r"))))]
7529   "TARGET_TLS && TARGET_ARCH64"
7530   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7531   [(set_attr "type" "load")
7532    (set_attr "us3load_type" "3cycle")])
7534 (define_insn "*tldo_ldub1_sp64"
7535   [(set (match_operand:HI 0 "register_operand" "=r")
7536         (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7537                                                      (match_operand 3 "tld_symbolic_operand" "")]
7538                                                     UNSPEC_TLSLDO)
7539                                          (match_operand:DI 1 "register_operand" "r")))))]
7540   "TARGET_TLS && TARGET_ARCH64"
7541   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7542   [(set_attr "type" "load")
7543    (set_attr "us3load_type" "3cycle")])
7545 (define_insn "*tldo_ldub2_sp64"
7546   [(set (match_operand:SI 0 "register_operand" "=r")
7547         (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7548                                                      (match_operand 3 "tld_symbolic_operand" "")]
7549                                                     UNSPEC_TLSLDO)
7550                                          (match_operand:DI 1 "register_operand" "r")))))]
7551   "TARGET_TLS && TARGET_ARCH64"
7552   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7553   [(set_attr "type" "load")
7554    (set_attr "us3load_type" "3cycle")])
7556 (define_insn "*tldo_ldub3_sp64"
7557   [(set (match_operand:DI 0 "register_operand" "=r")
7558         (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7559                                                      (match_operand 3 "tld_symbolic_operand" "")]
7560                                                     UNSPEC_TLSLDO)
7561                                          (match_operand:DI 1 "register_operand" "r")))))]
7562   "TARGET_TLS && TARGET_ARCH64"
7563   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7564   [(set_attr "type" "load")
7565    (set_attr "us3load_type" "3cycle")])
7567 (define_insn "*tldo_ldsb1_sp64"
7568   [(set (match_operand:HI 0 "register_operand" "=r")
7569         (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7570                                                      (match_operand 3 "tld_symbolic_operand" "")]
7571                                                     UNSPEC_TLSLDO)
7572                                          (match_operand:DI 1 "register_operand" "r")))))]
7573   "TARGET_TLS && TARGET_ARCH64"
7574   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7575   [(set_attr "type" "sload")
7576    (set_attr "us3load_type" "3cycle")])
7578 (define_insn "*tldo_ldsb2_sp64"
7579   [(set (match_operand:SI 0 "register_operand" "=r")
7580         (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7581                                                      (match_operand 3 "tld_symbolic_operand" "")]
7582                                                     UNSPEC_TLSLDO)
7583                                          (match_operand:DI 1 "register_operand" "r")))))]
7584   "TARGET_TLS && TARGET_ARCH64"
7585   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7586   [(set_attr "type" "sload")
7587    (set_attr "us3load_type" "3cycle")])
7589 (define_insn "*tldo_ldsb3_sp64"
7590   [(set (match_operand:DI 0 "register_operand" "=r")
7591         (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7592                                                      (match_operand 3 "tld_symbolic_operand" "")]
7593                                                     UNSPEC_TLSLDO)
7594                                          (match_operand:DI 1 "register_operand" "r")))))]
7595   "TARGET_TLS && TARGET_ARCH64"
7596   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7597   [(set_attr "type" "sload")
7598    (set_attr "us3load_type" "3cycle")])
7600 (define_insn "*tldo_lduh_sp32"
7601   [(set (match_operand:HI 0 "register_operand" "=r")
7602         (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7603                                      (match_operand 3 "tld_symbolic_operand" "")]
7604                                     UNSPEC_TLSLDO)
7605                          (match_operand:SI 1 "register_operand" "r"))))]
7606   "TARGET_TLS && TARGET_ARCH32"
7607   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7608   [(set_attr "type" "load")
7609    (set_attr "us3load_type" "3cycle")])
7611 (define_insn "*tldo_lduh1_sp32"
7612   [(set (match_operand:SI 0 "register_operand" "=r")
7613         (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7614                                                      (match_operand 3 "tld_symbolic_operand" "")]
7615                                                     UNSPEC_TLSLDO)
7616                                          (match_operand:SI 1 "register_operand" "r")))))]
7617   "TARGET_TLS && TARGET_ARCH32"
7618   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7619   [(set_attr "type" "load")
7620    (set_attr "us3load_type" "3cycle")])
7622 (define_insn "*tldo_ldsh1_sp32"
7623   [(set (match_operand:SI 0 "register_operand" "=r")
7624         (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7625                                                      (match_operand 3 "tld_symbolic_operand" "")]
7626                                                     UNSPEC_TLSLDO)
7627                                          (match_operand:SI 1 "register_operand" "r")))))]
7628   "TARGET_TLS && TARGET_ARCH32"
7629   "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7630   [(set_attr "type" "sload")
7631    (set_attr "us3load_type" "3cycle")])
7633 (define_insn "*tldo_lduh_sp64"
7634   [(set (match_operand:HI 0 "register_operand" "=r")
7635         (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7636                                      (match_operand 3 "tld_symbolic_operand" "")]
7637                                     UNSPEC_TLSLDO)
7638                          (match_operand:DI 1 "register_operand" "r"))))]
7639   "TARGET_TLS && TARGET_ARCH64"
7640   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7641   [(set_attr "type" "load")
7642    (set_attr "us3load_type" "3cycle")])
7644 (define_insn "*tldo_lduh1_sp64"
7645   [(set (match_operand:SI 0 "register_operand" "=r")
7646         (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7647                                                      (match_operand 3 "tld_symbolic_operand" "")]
7648                                                     UNSPEC_TLSLDO)
7649                                          (match_operand:DI 1 "register_operand" "r")))))]
7650   "TARGET_TLS && TARGET_ARCH64"
7651   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7652   [(set_attr "type" "load")
7653    (set_attr "us3load_type" "3cycle")])
7655 (define_insn "*tldo_lduh2_sp64"
7656   [(set (match_operand:DI 0 "register_operand" "=r")
7657         (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7658                                                      (match_operand 3 "tld_symbolic_operand" "")]
7659                                                     UNSPEC_TLSLDO)
7660                                          (match_operand:DI 1 "register_operand" "r")))))]
7661   "TARGET_TLS && TARGET_ARCH64"
7662   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7663   [(set_attr "type" "load")
7664    (set_attr "us3load_type" "3cycle")])
7666 (define_insn "*tldo_ldsh1_sp64"
7667   [(set (match_operand:SI 0 "register_operand" "=r")
7668         (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7669                                                      (match_operand 3 "tld_symbolic_operand" "")]
7670                                                     UNSPEC_TLSLDO)
7671                                          (match_operand:DI 1 "register_operand" "r")))))]
7672   "TARGET_TLS && TARGET_ARCH64"
7673   "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7674   [(set_attr "type" "sload")
7675    (set_attr "us3load_type" "3cycle")])
7677 (define_insn "*tldo_ldsh2_sp64"
7678   [(set (match_operand:DI 0 "register_operand" "=r")
7679         (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7680                                                      (match_operand 3 "tld_symbolic_operand" "")]
7681                                                     UNSPEC_TLSLDO)
7682                                          (match_operand:DI 1 "register_operand" "r")))))]
7683   "TARGET_TLS && TARGET_ARCH64"
7684   "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7685   [(set_attr "type" "sload")
7686    (set_attr "us3load_type" "3cycle")])
7688 (define_insn "*tldo_lduw_sp32"
7689   [(set (match_operand:SI 0 "register_operand" "=r")
7690         (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7691                                      (match_operand 3 "tld_symbolic_operand" "")]
7692                                     UNSPEC_TLSLDO)
7693                          (match_operand:SI 1 "register_operand" "r"))))]
7694   "TARGET_TLS && TARGET_ARCH32"
7695   "ld\t[%1 + %2], %0, %%tldo_add(%3)"
7696   [(set_attr "type" "load")])
7698 (define_insn "*tldo_lduw_sp64"
7699   [(set (match_operand:SI 0 "register_operand" "=r")
7700         (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7701                                      (match_operand 3 "tld_symbolic_operand" "")]
7702                                     UNSPEC_TLSLDO)
7703                          (match_operand:DI 1 "register_operand" "r"))))]
7704   "TARGET_TLS && TARGET_ARCH64"
7705   "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7706   [(set_attr "type" "load")])
7708 (define_insn "*tldo_lduw1_sp64"
7709   [(set (match_operand:DI 0 "register_operand" "=r")
7710         (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7711                                                      (match_operand 3 "tld_symbolic_operand" "")]
7712                                                     UNSPEC_TLSLDO)
7713                                          (match_operand:DI 1 "register_operand" "r")))))]
7714   "TARGET_TLS && TARGET_ARCH64"
7715   "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7716   [(set_attr "type" "load")])
7718 (define_insn "*tldo_ldsw1_sp64"
7719   [(set (match_operand:DI 0 "register_operand" "=r")
7720         (sign_extend:DI (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   "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
7726   [(set_attr "type" "sload")
7727    (set_attr "us3load_type" "3cycle")])
7729 (define_insn "*tldo_ldx_sp64"
7730   [(set (match_operand:DI 0 "register_operand" "=r")
7731         (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7732                                      (match_operand 3 "tld_symbolic_operand" "")]
7733                                     UNSPEC_TLSLDO)
7734                          (match_operand:DI 1 "register_operand" "r"))))]
7735   "TARGET_TLS && TARGET_ARCH64"
7736   "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
7737   [(set_attr "type" "load")])
7739 (define_insn "*tldo_stb_sp32"
7740   [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7741                                      (match_operand 3 "tld_symbolic_operand" "")]
7742                                     UNSPEC_TLSLDO)
7743                          (match_operand:SI 1 "register_operand" "r")))
7744         (match_operand:QI 0 "register_operand" "r"))]
7745   "TARGET_TLS && TARGET_ARCH32"
7746   "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7747   [(set_attr "type" "store")])
7749 (define_insn "*tldo_stb_sp64"
7750   [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7751                                      (match_operand 3 "tld_symbolic_operand" "")]
7752                                     UNSPEC_TLSLDO)
7753                          (match_operand:DI 1 "register_operand" "r")))
7754         (match_operand:QI 0 "register_operand" "r"))]
7755   "TARGET_TLS && TARGET_ARCH64"
7756   "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7757   [(set_attr "type" "store")])
7759 (define_insn "*tldo_sth_sp32"
7760   [(set (mem:HI (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:HI 0 "register_operand" "r"))]
7765   "TARGET_TLS && TARGET_ARCH32"
7766   "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7767   [(set_attr "type" "store")])
7769 (define_insn "*tldo_sth_sp64"
7770   [(set (mem:HI (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:HI 0 "register_operand" "r"))]
7775   "TARGET_TLS && TARGET_ARCH64"
7776   "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7777   [(set_attr "type" "store")])
7779 (define_insn "*tldo_stw_sp32"
7780   [(set (mem:SI (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:SI 0 "register_operand" "r"))]
7785   "TARGET_TLS && TARGET_ARCH32"
7786   "st\t%0, [%1 + %2], %%tldo_add(%3)"
7787   [(set_attr "type" "store")])
7789 (define_insn "*tldo_stw_sp64"
7790   [(set (mem:SI (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:SI 0 "register_operand" "r"))]
7795   "TARGET_TLS && TARGET_ARCH64"
7796   "stw\t%0, [%1 + %2], %%tldo_add(%3)"
7797   [(set_attr "type" "store")])
7799 (define_insn "*tldo_stx_sp64"
7800   [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7801                                      (match_operand 3 "tld_symbolic_operand" "")]
7802                                     UNSPEC_TLSLDO)
7803                          (match_operand:DI 1 "register_operand" "r")))
7804         (match_operand:DI 0 "register_operand" "r"))]
7805   "TARGET_TLS && TARGET_ARCH64"
7806   "stx\t%0, [%1 + %2], %%tldo_add(%3)"
7807   [(set_attr "type" "store")])
7810 ;; Stack protector instructions.
7812 (define_expand "stack_protect_set"
7813   [(match_operand 0 "memory_operand" "")
7814    (match_operand 1 "memory_operand" "")]
7815   ""
7817 #ifdef TARGET_THREAD_SSP_OFFSET
7818   rtx tlsreg = gen_rtx_REG (Pmode, 7);
7819   rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7820   operands[1] = gen_rtx_MEM (Pmode, addr);
7821 #endif
7822   if (TARGET_ARCH64)
7823     emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
7824   else
7825     emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
7826   DONE;
7829 (define_insn "stack_protect_setsi"
7830   [(set (match_operand:SI 0 "memory_operand" "=m")
7831         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7832    (set (match_scratch:SI 2 "=&r") (const_int 0))]
7833   "TARGET_ARCH32"
7834   "ld\t%1, %2\;st\t%2, %0\;mov\t0, %2"
7835   [(set_attr "type" "multi")
7836    (set_attr "length" "3")])
7838 (define_insn "stack_protect_setdi"
7839   [(set (match_operand:DI 0 "memory_operand" "=m")
7840         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7841    (set (match_scratch:DI 2 "=&r") (const_int 0))]
7842   "TARGET_ARCH64"
7843   "ldx\t%1, %2\;stx\t%2, %0\;mov\t0, %2"
7844   [(set_attr "type" "multi")
7845    (set_attr "length" "3")])
7847 (define_expand "stack_protect_test"
7848   [(match_operand 0 "memory_operand" "")
7849    (match_operand 1 "memory_operand" "")
7850    (match_operand 2 "" "")]
7851   ""
7853   rtx result, test;
7854 #ifdef TARGET_THREAD_SSP_OFFSET
7855   rtx tlsreg = gen_rtx_REG (Pmode, 7);
7856   rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7857   operands[1] = gen_rtx_MEM (Pmode, addr);
7858 #endif
7859   if (TARGET_ARCH64)
7860     {
7861       result = gen_reg_rtx (Pmode);
7862       emit_insn (gen_stack_protect_testdi (result, operands[0], operands[1]));
7863       test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7864       emit_jump_insn (gen_cbranchdi4 (test, result, const0_rtx, operands[2]));
7865     }
7866   else
7867     {
7868       emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
7869       result = gen_rtx_REG (CCmode, SPARC_ICC_REG);
7870       test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7871       emit_jump_insn (gen_cbranchcc4 (test, result, const0_rtx, operands[2]));
7872     }
7873   DONE;
7876 (define_insn "stack_protect_testsi"
7877   [(set (reg:CC CC_REG)
7878         (unspec:CC [(match_operand:SI 0 "memory_operand" "m")
7879                     (match_operand:SI 1 "memory_operand" "m")]
7880                    UNSPEC_SP_TEST))
7881    (set (match_scratch:SI 3 "=r") (const_int 0))
7882    (clobber (match_scratch:SI 2 "=&r"))]
7883   "TARGET_ARCH32"
7884   "ld\t%0, %2\;ld\t%1, %3\;xorcc\t%2, %3, %2\;mov\t0, %3"
7885   [(set_attr "type" "multi")
7886    (set_attr "length" "4")])
7888 (define_insn "stack_protect_testdi"
7889   [(set (match_operand:DI 0 "register_operand" "=&r")
7890         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
7891                     (match_operand:DI 2 "memory_operand" "m")]
7892                    UNSPEC_SP_TEST))
7893    (set (match_scratch:DI 3 "=r") (const_int 0))]
7894   "TARGET_ARCH64"
7895   "ldx\t%1, %0\;ldx\t%2, %3\;xor\t%0, %3, %0\;mov\t0, %3"
7896   [(set_attr "type" "multi")
7897    (set_attr "length" "4")])
7899 ;; Vector instructions.
7901 (define_mode_iterator VM32 [V1SI V2HI V4QI])
7902 (define_mode_iterator VM64 [V1DI V2SI V4HI V8QI])
7903 (define_mode_iterator VMALL [V1SI V2HI V4QI V1DI V2SI V4HI V8QI])
7905 (define_mode_attr vbits [(V2SI "32") (V4HI "16") (V1SI "32s") (V2HI "16s")])
7906 (define_mode_attr vconstr [(V1SI "f") (V2HI "f") (V4QI "f")
7907                            (V1DI "e") (V2SI "e") (V4HI "e") (V8QI "e")])
7908 (define_mode_attr vfptype [(V1SI "single") (V2HI "single") (V4QI "single")
7909                            (V1DI "double") (V2SI "double") (V4HI "double")
7910                            (V8QI "double")])
7912 (define_expand "mov<VMALL:mode>"
7913   [(set (match_operand:VMALL 0 "nonimmediate_operand" "")
7914         (match_operand:VMALL 1 "general_operand" ""))]
7915   "TARGET_VIS"
7917   if (sparc_expand_move (<VMALL:MODE>mode, operands))
7918     DONE;
7921 (define_insn "*mov<VM32:mode>_insn"
7922   [(set (match_operand:VM32 0 "nonimmediate_operand" "=f,f,f,f,m,m,*r, m,*r,*r, f")
7923         (match_operand:VM32 1 "input_operand"         "Y,Z,f,m,f,Y, m,*r,*r, f,*r"))]
7924   "TARGET_VIS
7925    && (register_operand (operands[0], <VM32:MODE>mode)
7926        || register_or_zero_or_all_ones_operand (operands[1], <VM32:MODE>mode))"
7927   "@
7928   fzeros\t%0
7929   fones\t%0
7930   fsrc2s\t%1, %0
7931   ld\t%1, %0
7932   st\t%1, %0
7933   st\t%r1, %0
7934   ld\t%1, %0
7935   st\t%1, %0
7936   mov\t%1, %0
7937   movstouw\t%1, %0
7938   movwtos\t%1, %0"
7939   [(set_attr "type" "visl,visl,vismv,fpload,fpstore,store,load,store,*,vismv,vismv")
7940    (set_attr "cpu_feature" "vis,vis,vis,*,*,*,*,*,*,vis3,vis3")])
7942 (define_insn "*mov<VM64:mode>_insn_sp64"
7943   [(set (match_operand:VM64 0 "nonimmediate_operand" "=e,e,e,e,m,m,*r, m,*r, e,*r")
7944         (match_operand:VM64 1 "input_operand"         "Y,C,e,m,e,Y, m,*r, e,*r,*r"))]
7945   "TARGET_VIS
7946    && TARGET_ARCH64
7947    && (register_operand (operands[0], <VM64:MODE>mode)
7948        || register_or_zero_or_all_ones_operand (operands[1], <VM64:MODE>mode))"
7949   "@
7950   fzero\t%0
7951   fone\t%0
7952   fsrc2\t%1, %0
7953   ldd\t%1, %0
7954   std\t%1, %0
7955   stx\t%r1, %0
7956   ldx\t%1, %0
7957   stx\t%1, %0
7958   movdtox\t%1, %0
7959   movxtod\t%1, %0
7960   mov\t%1, %0"
7961   [(set_attr "type" "visl,visl,vismv,fpload,fpstore,store,load,store,vismv,vismv,*")
7962    (set_attr "cpu_feature" "vis,vis,vis,*,*,*,*,*,vis3,vis3,*")])
7964 (define_insn "*mov<VM64:mode>_insn_sp32"
7965   [(set (match_operand:VM64 0 "nonimmediate_operand" "=e,e,e,*r, f,e,m,m,U,T, o,*r")
7966         (match_operand:VM64 1 "input_operand"         "Y,C,e, f,*r,m,e,Y,T,U,*r,*r"))]
7967   "TARGET_VIS
7968    && ! TARGET_ARCH64
7969    && (register_operand (operands[0], <VM64:MODE>mode)
7970        || register_or_zero_or_all_ones_operand (operands[1], <VM64:MODE>mode))"
7971   "@
7972   fzero\t%0
7973   fone\t%0
7974   fsrc2\t%1, %0
7975   #
7976   #
7977   ldd\t%1, %0
7978   std\t%1, %0
7979   stx\t%r1, %0
7980   ldd\t%1, %0
7981   std\t%1, %0
7982   #
7983   #"
7984   [(set_attr "type" "visl,visl,vismv,*,*,fpload,fpstore,store,load,store,*,*")
7985    (set_attr "length" "*,*,*,2,2,*,*,*,*,*,2,2")
7986    (set_attr "cpu_feature" "vis,vis,vis,vis3,vis3,*,*,*,*,*,*,*")])
7988 (define_split
7989   [(set (match_operand:VM64 0 "memory_operand" "")
7990         (match_operand:VM64 1 "register_operand" ""))]
7991   "reload_completed
7992    && TARGET_VIS
7993    && ! TARGET_ARCH64
7994    && (((REGNO (operands[1]) % 2) != 0)
7995        || ! mem_min_alignment (operands[0], 8))
7996    && offsettable_memref_p (operands[0])"
7997   [(clobber (const_int 0))]
7999   rtx word0, word1;
8001   word0 = adjust_address (operands[0], SImode, 0);
8002   word1 = adjust_address (operands[0], SImode, 4);
8004   emit_move_insn_1 (word0, gen_highpart (SImode, operands[1]));
8005   emit_move_insn_1 (word1, gen_lowpart (SImode, operands[1]));
8006   DONE;
8009 (define_split
8010   [(set (match_operand:VM64 0 "register_operand" "")
8011         (match_operand:VM64 1 "register_operand" ""))]
8012   "reload_completed
8013    && TARGET_VIS
8014    && ! TARGET_ARCH64
8015    && sparc_split_regreg_legitimate (operands[0], operands[1])"
8016   [(clobber (const_int 0))]
8018   rtx set_dest = operands[0];
8019   rtx set_src = operands[1];
8020   rtx dest1, dest2;
8021   rtx src1, src2;
8023   dest1 = gen_highpart (SImode, set_dest);
8024   dest2 = gen_lowpart (SImode, set_dest);
8025   src1 = gen_highpart (SImode, set_src);
8026   src2 = gen_lowpart (SImode, set_src);
8028   /* Now emit using the real source and destination we found, swapping
8029      the order if we detect overlap.  */
8030   if (reg_overlap_mentioned_p (dest1, src2))
8031     {
8032       emit_insn (gen_movsi (dest2, src2));
8033       emit_insn (gen_movsi (dest1, src1));
8034     }
8035   else
8036     {
8037       emit_insn (gen_movsi (dest1, src1));
8038       emit_insn (gen_movsi (dest2, src2));
8039     }
8040   DONE;
8043 (define_expand "vec_init<mode>"
8044   [(match_operand:VMALL 0 "register_operand" "")
8045    (match_operand:VMALL 1 "" "")]
8046   "TARGET_VIS"
8048   sparc_expand_vector_init (operands[0], operands[1]);
8049   DONE;
8052 (define_code_iterator plusminus [plus minus])
8053 (define_code_attr plusminus_insn [(plus "add") (minus "sub")])
8055 (define_mode_iterator VADDSUB [V1SI V2SI V2HI V4HI])
8057 (define_insn "<plusminus_insn><mode>3"
8058   [(set (match_operand:VADDSUB 0 "register_operand" "=<vconstr>")
8059         (plusminus:VADDSUB (match_operand:VADDSUB 1 "register_operand" "<vconstr>")
8060                            (match_operand:VADDSUB 2 "register_operand" "<vconstr>")))]
8061   "TARGET_VIS"
8062   "fp<plusminus_insn><vbits>\t%1, %2, %0"
8063   [(set_attr "type" "fga")
8064    (set_attr "fptype" "<vfptype>")])
8066 (define_mode_iterator VL [V1SI V2HI V4QI V1DI V2SI V4HI V8QI])
8067 (define_mode_attr vlsuf [(V1SI "s") (V2HI "s") (V4QI "s")
8068                          (V1DI  "") (V2SI  "") (V4HI  "") (V8QI "")])
8069 (define_code_iterator vlop [ior and xor])
8070 (define_code_attr vlinsn [(ior "or") (and "and") (xor "xor")])
8071 (define_code_attr vlninsn [(ior "nor") (and "nand") (xor "xnor")])
8073 (define_insn "<code><mode>3"
8074   [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8075         (vlop:VL (match_operand:VL 1 "register_operand" "<vconstr>")
8076                  (match_operand:VL 2 "register_operand" "<vconstr>")))]
8077   "TARGET_VIS"
8078   "f<vlinsn><vlsuf>\t%1, %2, %0"
8079   [(set_attr "type" "visl")
8080    (set_attr "fptype" "<vfptype>")])
8082 (define_insn "*not_<code><mode>3"
8083   [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8084         (not:VL (vlop:VL (match_operand:VL 1 "register_operand" "<vconstr>")
8085                          (match_operand:VL 2 "register_operand" "<vconstr>"))))]
8086   "TARGET_VIS"
8087   "f<vlninsn><vlsuf>\t%1, %2, %0"
8088   [(set_attr "type" "visl")
8089    (set_attr "fptype" "<vfptype>")])
8091 ;; (ior (not (op1)) (not (op2))) is the canonical form of NAND.
8092 (define_insn "*nand<mode>_vis"
8093   [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8094         (ior:VL (not:VL (match_operand:VL 1 "register_operand" "<vconstr>"))
8095                 (not:VL (match_operand:VL 2 "register_operand" "<vconstr>"))))]
8096   "TARGET_VIS"
8097   "fnand<vlsuf>\t%1, %2, %0"
8098   [(set_attr "type" "visl")
8099    (set_attr "fptype" "<vfptype>")])
8101 (define_code_iterator vlnotop [ior and])
8103 (define_insn "*<code>_not1<mode>_vis"
8104   [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8105         (vlnotop:VL (not:VL (match_operand:VL 1 "register_operand" "<vconstr>"))
8106                     (match_operand:VL 2 "register_operand" "<vconstr>")))]
8107   "TARGET_VIS"
8108   "f<vlinsn>not1<vlsuf>\t%1, %2, %0"
8109   [(set_attr "type" "visl")
8110    (set_attr "fptype" "<vfptype>")])
8112 (define_insn "*<code>_not2<mode>_vis"
8113   [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8114         (vlnotop:VL (match_operand:VL 1 "register_operand" "<vconstr>")
8115                     (not:VL (match_operand:VL 2 "register_operand" "<vconstr>"))))]
8116   "TARGET_VIS"
8117   "f<vlinsn>not2<vlsuf>\t%1, %2, %0"
8118   [(set_attr "type" "visl")
8119    (set_attr "fptype" "<vfptype>")])
8121 (define_insn "one_cmpl<mode>2"
8122   [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8123         (not:VL (match_operand:VL 1 "register_operand" "<vconstr>")))]
8124   "TARGET_VIS"
8125   "fnot1<vlsuf>\t%1, %0"
8126   [(set_attr "type" "visl")
8127    (set_attr "fptype" "<vfptype>")])
8129 ;; Hard to generate VIS instructions.  We have builtins for these.
8131 (define_insn "fpack16_vis"
8132   [(set (match_operand:V4QI 0 "register_operand" "=f")
8133         (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e")
8134                       (reg:DI GSR_REG)]
8135                       UNSPEC_FPACK16))]
8136   "TARGET_VIS"
8137   "fpack16\t%1, %0"
8138   [(set_attr "type" "fgm_pack")
8139    (set_attr "fptype" "double")])
8141 (define_insn "fpackfix_vis"
8142   [(set (match_operand:V2HI 0 "register_operand" "=f")
8143         (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e")
8144                       (reg:DI GSR_REG)]
8145                       UNSPEC_FPACKFIX))]
8146   "TARGET_VIS"
8147   "fpackfix\t%1, %0"
8148   [(set_attr "type" "fgm_pack")
8149    (set_attr "fptype" "double")])
8151 (define_insn "fpack32_vis"
8152   [(set (match_operand:V8QI 0 "register_operand" "=e")
8153         (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e")
8154                       (match_operand:V8QI 2 "register_operand" "e")
8155                       (reg:DI GSR_REG)]
8156                      UNSPEC_FPACK32))]
8157   "TARGET_VIS"
8158   "fpack32\t%1, %2, %0"
8159   [(set_attr "type" "fgm_pack")
8160    (set_attr "fptype" "double")])
8162 (define_insn "fexpand_vis"
8163   [(set (match_operand:V4HI 0 "register_operand" "=e")
8164         (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")]
8165          UNSPEC_FEXPAND))]
8166  "TARGET_VIS"
8167  "fexpand\t%1, %0"
8168  [(set_attr "type" "fga")
8169   (set_attr "fptype" "double")])
8171 (define_insn "fpmerge_vis"
8172   [(set (match_operand:V8QI 0 "register_operand" "=e")
8173         (vec_select:V8QI
8174           (vec_concat:V8QI (match_operand:V4QI 1 "register_operand" "f")
8175                            (match_operand:V4QI 2 "register_operand" "f"))
8176           (parallel [(const_int 0) (const_int 4)
8177                      (const_int 1) (const_int 5)
8178                      (const_int 2) (const_int 6)
8179                      (const_int 3) (const_int 7)])))]
8180  "TARGET_VIS"
8181  "fpmerge\t%1, %2, %0"
8182  [(set_attr "type" "fga")
8183   (set_attr "fptype" "double")])
8185 (define_insn "vec_interleave_lowv8qi"
8186   [(set (match_operand:V8QI 0 "register_operand" "=e")
8187         (vec_select:V8QI
8188           (vec_concat:V16QI (match_operand:V8QI 1 "register_operand" "f")
8189                             (match_operand:V8QI 2 "register_operand" "f"))
8190           (parallel [(const_int 0) (const_int 8)
8191                      (const_int 1) (const_int 9)
8192                      (const_int 2) (const_int 10)
8193                      (const_int 3) (const_int 11)])))]
8194  "TARGET_VIS"
8195  "fpmerge\t%L1, %L2, %0"
8196  [(set_attr "type" "fga")
8197   (set_attr "fptype" "double")])
8199 (define_insn "vec_interleave_highv8qi"
8200   [(set (match_operand:V8QI 0 "register_operand" "=e")
8201         (vec_select:V8QI
8202           (vec_concat:V16QI (match_operand:V8QI 1 "register_operand" "f")
8203                             (match_operand:V8QI 2 "register_operand" "f"))
8204           (parallel [(const_int 4) (const_int 12)
8205                      (const_int 5) (const_int 13)
8206                      (const_int 6) (const_int 14)
8207                      (const_int 7) (const_int 15)])))]
8208  "TARGET_VIS"
8209  "fpmerge\t%H1, %H2, %0"
8210  [(set_attr "type" "fga")
8211   (set_attr "fptype" "double")])
8213 ;; Partitioned multiply instructions
8214 (define_insn "fmul8x16_vis"
8215   [(set (match_operand:V4HI 0 "register_operand" "=e")
8216         (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8217                       (match_operand:V4HI 2 "register_operand" "e")]
8218          UNSPEC_MUL8))]
8219   "TARGET_VIS"
8220   "fmul8x16\t%1, %2, %0"
8221   [(set_attr "type" "fgm_mul")
8222    (set_attr "fptype" "double")])
8224 (define_insn "fmul8x16au_vis"
8225   [(set (match_operand:V4HI 0 "register_operand" "=e")
8226         (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8227                       (match_operand:V2HI 2 "register_operand" "f")]
8228          UNSPEC_MUL16AU))]
8229   "TARGET_VIS"
8230   "fmul8x16au\t%1, %2, %0"
8231   [(set_attr "type" "fgm_mul")
8232    (set_attr "fptype" "double")])
8234 (define_insn "fmul8x16al_vis"
8235   [(set (match_operand:V4HI 0 "register_operand" "=e")
8236         (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8237                       (match_operand:V2HI 2 "register_operand" "f")]
8238          UNSPEC_MUL16AL))]
8239   "TARGET_VIS"
8240   "fmul8x16al\t%1, %2, %0"
8241   [(set_attr "type" "fgm_mul")
8242    (set_attr "fptype" "double")])
8244 (define_insn "fmul8sux16_vis"
8245   [(set (match_operand:V4HI 0 "register_operand" "=e")
8246         (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
8247                       (match_operand:V4HI 2 "register_operand" "e")]
8248          UNSPEC_MUL8SU))]
8249   "TARGET_VIS"
8250   "fmul8sux16\t%1, %2, %0"
8251   [(set_attr "type" "fgm_mul")
8252    (set_attr "fptype" "double")])
8254 (define_insn "fmul8ulx16_vis"
8255   [(set (match_operand:V4HI 0 "register_operand" "=e")
8256         (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
8257                       (match_operand:V4HI 2 "register_operand" "e")]
8258          UNSPEC_MUL8UL))]
8259   "TARGET_VIS"
8260   "fmul8ulx16\t%1, %2, %0"
8261   [(set_attr "type" "fgm_mul")
8262    (set_attr "fptype" "double")])
8264 (define_insn "fmuld8sux16_vis"
8265   [(set (match_operand:V2SI 0 "register_operand" "=e")
8266         (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
8267                       (match_operand:V2HI 2 "register_operand" "f")]
8268          UNSPEC_MULDSU))]
8269   "TARGET_VIS"
8270   "fmuld8sux16\t%1, %2, %0"
8271   [(set_attr "type" "fgm_mul")
8272    (set_attr "fptype" "double")])
8274 (define_insn "fmuld8ulx16_vis"
8275   [(set (match_operand:V2SI 0 "register_operand" "=e")
8276         (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
8277                       (match_operand:V2HI 2 "register_operand" "f")]
8278          UNSPEC_MULDUL))]
8279   "TARGET_VIS"
8280   "fmuld8ulx16\t%1, %2, %0"
8281   [(set_attr "type" "fgm_mul")
8282    (set_attr "fptype" "double")])
8284 (define_expand "wrgsr_vis"
8285   [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" ""))]
8286   "TARGET_VIS"
8288   if (! TARGET_ARCH64)
8289     {
8290       emit_insn (gen_wrgsr_v8plus (operands[0]));
8291       DONE;
8292     }
8295 (define_insn "*wrgsr_sp64"
8296   [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" "rI"))]
8297   "TARGET_VIS && TARGET_ARCH64"
8298   "wr\t%%g0, %0, %%gsr"
8299   [(set_attr "type" "gsr")])
8301 (define_insn "wrgsr_v8plus"
8302   [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" "I,r"))
8303    (clobber (match_scratch:SI 1 "=X,&h"))]
8304   "TARGET_VIS && ! TARGET_ARCH64"
8306   if (GET_CODE (operands[0]) == CONST_INT
8307       || sparc_check_64 (operands[0], insn))
8308     return "wr\t%%g0, %0, %%gsr";
8310   output_asm_insn("srl\t%L0, 0, %L0", operands);
8311   return "sllx\t%H0, 32, %1\n\tor\t%L0, %1, %1\n\twr\t%%g0, %1, %%gsr";
8313   [(set_attr "type" "multi")])
8315 (define_expand "rdgsr_vis"
8316   [(set (match_operand:DI 0 "register_operand" "") (reg:DI GSR_REG))]
8317   "TARGET_VIS"
8319   if (! TARGET_ARCH64)
8320     {
8321       emit_insn (gen_rdgsr_v8plus (operands[0]));
8322       DONE;
8323     }
8326 (define_insn "*rdgsr_sp64"
8327   [(set (match_operand:DI 0 "register_operand" "=r") (reg:DI GSR_REG))]
8328   "TARGET_VIS && TARGET_ARCH64"
8329   "rd\t%%gsr, %0"
8330   [(set_attr "type" "gsr")])
8332 (define_insn "rdgsr_v8plus"
8333   [(set (match_operand:DI 0 "register_operand" "=r") (reg:DI GSR_REG))
8334    (clobber (match_scratch:SI 1 "=&h"))]
8335   "TARGET_VIS && ! TARGET_ARCH64"
8337   return "rd\t%%gsr, %1\n\tsrlx\t%1, 32, %H0\n\tmov %1, %L0";
8339   [(set_attr "type" "multi")])
8341 ;; Using faligndata only makes sense after an alignaddr since the choice of
8342 ;; bytes to take out of each operand is dependent on the results of the last
8343 ;; alignaddr.
8344 (define_insn "faligndata<VM64:mode>_vis"
8345   [(set (match_operand:VM64 0 "register_operand" "=e")
8346         (unspec:VM64 [(match_operand:VM64 1 "register_operand" "e")
8347                       (match_operand:VM64 2 "register_operand" "e")
8348                       (reg:DI GSR_REG)]
8349          UNSPEC_ALIGNDATA))]
8350   "TARGET_VIS"
8351   "faligndata\t%1, %2, %0"
8352   [(set_attr "type" "fga")
8353    (set_attr "fptype" "double")])
8355 (define_insn "alignaddrsi_vis"
8356   [(set (match_operand:SI 0 "register_operand" "=r")
8357         (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
8358                  (match_operand:SI 2 "register_or_zero_operand" "rJ")))
8359    (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8360         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
8361   "TARGET_VIS"
8362   "alignaddr\t%r1, %r2, %0"
8363   [(set_attr "type" "gsr")])
8365 (define_insn "alignaddrdi_vis"
8366   [(set (match_operand:DI 0 "register_operand" "=r")
8367         (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
8368                  (match_operand:DI 2 "register_or_zero_operand" "rJ")))
8369    (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8370         (plus:DI (match_dup 1) (match_dup 2)))]
8371   "TARGET_VIS"
8372   "alignaddr\t%r1, %r2, %0"
8373   [(set_attr "type" "gsr")])
8375 (define_insn "alignaddrlsi_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         (xor:DI (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2)))
8381                 (const_int 7)))]
8382   "TARGET_VIS"
8383   "alignaddrl\t%r1, %r2, %0"
8384   [(set_attr "type" "gsr")])
8386 (define_insn "alignaddrldi_vis"
8387   [(set (match_operand:DI 0 "register_operand" "=r")
8388         (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
8389                  (match_operand:DI 2 "register_or_zero_operand" "rJ")))
8390    (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8391         (xor:DI (plus:DI (match_dup 1) (match_dup 2))
8392                 (const_int 7)))]
8393   "TARGET_VIS"
8394   "alignaddrl\t%r1, %r2, %0"
8395   [(set_attr "type" "gsr")])
8397 (define_insn "pdist_vis"
8398   [(set (match_operand:DI 0 "register_operand" "=e")
8399         (unspec:DI [(match_operand:V8QI 1 "register_operand" "e")
8400                     (match_operand:V8QI 2 "register_operand" "e")
8401                     (match_operand:DI 3 "register_operand" "0")]
8402          UNSPEC_PDIST))]
8403   "TARGET_VIS"
8404   "pdist\t%1, %2, %0"
8405   [(set_attr "type" "pdist")
8406    (set_attr "fptype" "double")])
8408 ;; Edge instructions produce condition codes equivalent to a 'subcc'
8409 ;; with the same operands.
8410 (define_insn "edge8<P:mode>_vis"
8411   [(set (reg:CC_NOOV CC_REG)
8412         (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8413                                   (match_operand:P 2 "register_or_zero_operand" "rJ"))
8414                          (const_int 0)))
8415    (set (match_operand:P 0 "register_operand" "=r")
8416         (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8))]
8417   "TARGET_VIS"
8418   "edge8\t%r1, %r2, %0"
8419   [(set_attr "type" "edge")])
8421 (define_insn "edge8l<P:mode>_vis"
8422   [(set (reg:CC_NOOV CC_REG)
8423         (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8424                                   (match_operand:P 2 "register_or_zero_operand" "rJ"))
8425                          (const_int 0)))
8426    (set (match_operand:P 0 "register_operand" "=r")
8427         (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8L))]
8428   "TARGET_VIS"
8429   "edge8l\t%r1, %r2, %0"
8430   [(set_attr "type" "edge")])
8432 (define_insn "edge16<P:mode>_vis"
8433   [(set (reg:CC_NOOV CC_REG)
8434         (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8435                                   (match_operand:P 2 "register_or_zero_operand" "rJ"))
8436                          (const_int 0)))
8437    (set (match_operand:P 0 "register_operand" "=r")
8438         (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16))]
8439   "TARGET_VIS"
8440   "edge16\t%r1, %r2, %0"
8441   [(set_attr "type" "edge")])
8443 (define_insn "edge16l<P:mode>_vis"
8444   [(set (reg:CC_NOOV CC_REG)
8445         (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8446                                   (match_operand:P 2 "register_or_zero_operand" "rJ"))
8447                          (const_int 0)))
8448    (set (match_operand:P 0 "register_operand" "=r")
8449         (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16L))]
8450   "TARGET_VIS"
8451   "edge16l\t%r1, %r2, %0"
8452   [(set_attr "type" "edge")])
8454 (define_insn "edge32<P:mode>_vis"
8455   [(set (reg:CC_NOOV CC_REG)
8456         (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8457                                   (match_operand:P 2 "register_or_zero_operand" "rJ"))
8458                          (const_int 0)))
8459    (set (match_operand:P 0 "register_operand" "=r")
8460         (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32))]
8461   "TARGET_VIS"
8462   "edge32\t%r1, %r2, %0"
8463   [(set_attr "type" "edge")])
8465 (define_insn "edge32l<P:mode>_vis"
8466   [(set (reg:CC_NOOV CC_REG)
8467         (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8468                                   (match_operand:P 2 "register_or_zero_operand" "rJ"))
8469                          (const_int 0)))
8470    (set (match_operand:P 0 "register_operand" "=r")
8471         (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32L))]
8472   "TARGET_VIS"
8473   "edge32l\t%r1, %r2, %0"
8474   [(set_attr "type" "edge")])
8476 (define_code_iterator gcond [le ne gt eq])
8477 (define_mode_iterator GCM [V4HI V2SI])
8478 (define_mode_attr gcm_name [(V4HI "16") (V2SI "32")])
8480 (define_insn "fcmp<code><GCM:gcm_name><P:mode>_vis"
8481   [(set (match_operand:P 0 "register_operand" "=r")
8482         (unspec:P [(gcond:GCM (match_operand:GCM 1 "register_operand" "e")
8483                               (match_operand:GCM 2 "register_operand" "e"))]
8484          UNSPEC_FCMP))]
8485   "TARGET_VIS"
8486   "fcmp<code><GCM:gcm_name>\t%1, %2, %0"
8487   [(set_attr "type" "visl")
8488    (set_attr "fptype" "double")])
8490 (define_expand "vcond<mode><mode>"
8491   [(match_operand:GCM 0 "register_operand" "")
8492    (match_operand:GCM 1 "register_operand" "")
8493    (match_operand:GCM 2 "register_operand" "")
8494    (match_operator 3 ""
8495      [(match_operand:GCM 4 "register_operand" "")
8496       (match_operand:GCM 5 "register_operand" "")])]
8497   "TARGET_VIS3"
8499   sparc_expand_vcond (<MODE>mode, operands,
8500                       UNSPEC_CMASK<gcm_name>,
8501                       UNSPEC_FCMP);
8502   DONE;
8505 (define_expand "vconduv8qiv8qi"
8506   [(match_operand:V8QI 0 "register_operand" "")
8507    (match_operand:V8QI 1 "register_operand" "")
8508    (match_operand:V8QI 2 "register_operand" "")
8509    (match_operator 3 ""
8510      [(match_operand:V8QI 4 "register_operand" "")
8511       (match_operand:V8QI 5 "register_operand" "")])]
8512   "TARGET_VIS3"
8514   sparc_expand_vcond (V8QImode, operands,
8515                       UNSPEC_CMASK8,
8516                       UNSPEC_FUCMP);
8517   DONE;
8520 (define_insn "array8<P:mode>_vis"
8521   [(set (match_operand:P 0 "register_operand" "=r")
8522         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8523                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
8524                   UNSPEC_ARRAY8))]
8525   "TARGET_VIS"
8526   "array8\t%r1, %r2, %0"
8527   [(set_attr "type" "array")])
8529 (define_insn "array16<P:mode>_vis"
8530   [(set (match_operand:P 0 "register_operand" "=r")
8531         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8532                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
8533                   UNSPEC_ARRAY16))]
8534   "TARGET_VIS"
8535   "array16\t%r1, %r2, %0"
8536   [(set_attr "type" "array")])
8538 (define_insn "array32<P:mode>_vis"
8539   [(set (match_operand:P 0 "register_operand" "=r")
8540         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8541                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
8542                   UNSPEC_ARRAY32))]
8543   "TARGET_VIS"
8544   "array32\t%r1, %r2, %0"
8545   [(set_attr "type" "array")])
8547 (define_insn "bmaskdi_vis"
8548   [(set (match_operand:DI 0 "register_operand" "=r")
8549         (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
8550                  (match_operand:DI 2 "register_or_zero_operand" "rJ")))
8551    (set (zero_extract:DI (reg:DI GSR_REG) (const_int 32) (const_int 32))
8552         (plus:DI (match_dup 1) (match_dup 2)))]
8553   "TARGET_VIS2"
8554   "bmask\t%r1, %r2, %0"
8555   [(set_attr "type" "array")])
8557 (define_insn "bmasksi_vis"
8558   [(set (match_operand:SI 0 "register_operand" "=r")
8559         (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
8560                  (match_operand:SI 2 "register_or_zero_operand" "rJ")))
8561    (set (zero_extract:DI (reg:DI GSR_REG) (const_int 32) (const_int 32))
8562         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
8563   "TARGET_VIS2"
8564   "bmask\t%r1, %r2, %0"
8565   [(set_attr "type" "array")])
8567 (define_insn "bshuffle<VM64:mode>_vis"
8568   [(set (match_operand:VM64 0 "register_operand" "=e")
8569         (unspec:VM64 [(match_operand:VM64 1 "register_operand" "e")
8570                       (match_operand:VM64 2 "register_operand" "e")
8571                       (reg:DI GSR_REG)]
8572                      UNSPEC_BSHUFFLE))]
8573   "TARGET_VIS2"
8574   "bshuffle\t%1, %2, %0"
8575   [(set_attr "type" "fga")
8576    (set_attr "fptype" "double")])
8578 ;; The rtl expanders will happily convert constant permutations on other
8579 ;; modes down to V8QI.  Rely on this to avoid the complexity of the byte
8580 ;; order of the permutation.
8581 (define_expand "vec_perm_constv8qi"
8582   [(match_operand:V8QI 0 "register_operand" "")
8583    (match_operand:V8QI 1 "register_operand" "")
8584    (match_operand:V8QI 2 "register_operand" "")
8585    (match_operand:V8QI 3 "" "")]
8586   "TARGET_VIS2"
8588   unsigned int i, mask;
8589   rtx sel = operands[3];
8591   for (i = mask = 0; i < 8; ++i)
8592     mask |= (INTVAL (XVECEXP (sel, 0, i)) & 0xf) << (28 - i*4);
8593   sel = force_reg (SImode, gen_int_mode (mask, SImode));
8595   emit_insn (gen_bmasksi_vis (gen_rtx_REG (SImode, 0), sel, const0_rtx));
8596   emit_insn (gen_bshufflev8qi_vis (operands[0], operands[1], operands[2]));
8597   DONE;
8600 ;; Unlike constant permutation, we can vastly simplify the compression of
8601 ;; the 64-bit selector input to the 32-bit %gsr value by knowing what the
8602 ;; width of the input is.
8603 (define_expand "vec_perm<mode>"
8604   [(match_operand:VM64 0 "register_operand" "")
8605    (match_operand:VM64 1 "register_operand" "")
8606    (match_operand:VM64 2 "register_operand" "")
8607    (match_operand:VM64 3 "register_operand" "")]
8608   "TARGET_VIS2"
8610   sparc_expand_vec_perm_bmask (<MODE>mode, operands[3]);
8611   emit_insn (gen_bshuffle<mode>_vis (operands[0], operands[1], operands[2]));
8612   DONE;
8615 ;; VIS 2.0 adds edge variants which do not set the condition codes
8616 (define_insn "edge8n<P:mode>_vis"
8617   [(set (match_operand:P 0 "register_operand" "=r")
8618         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8619                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
8620                   UNSPEC_EDGE8N))]
8621   "TARGET_VIS2"
8622   "edge8n\t%r1, %r2, %0"
8623   [(set_attr "type" "edgen")])
8625 (define_insn "edge8ln<P:mode>_vis"
8626   [(set (match_operand:P 0 "register_operand" "=r")
8627         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8628                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
8629                   UNSPEC_EDGE8LN))]
8630   "TARGET_VIS2"
8631   "edge8ln\t%r1, %r2, %0"
8632   [(set_attr "type" "edgen")])
8634 (define_insn "edge16n<P:mode>_vis"
8635   [(set (match_operand:P 0 "register_operand" "=r")
8636         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8637                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
8638                   UNSPEC_EDGE16N))]
8639   "TARGET_VIS2"
8640   "edge16n\t%r1, %r2, %0"
8641   [(set_attr "type" "edgen")])
8643 (define_insn "edge16ln<P:mode>_vis"
8644   [(set (match_operand:P 0 "register_operand" "=r")
8645         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8646                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
8647                   UNSPEC_EDGE16LN))]
8648   "TARGET_VIS2"
8649   "edge16ln\t%r1, %r2, %0"
8650   [(set_attr "type" "edgen")])
8652 (define_insn "edge32n<P:mode>_vis"
8653   [(set (match_operand:P 0 "register_operand" "=r")
8654         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8655                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
8656                   UNSPEC_EDGE32N))]
8657   "TARGET_VIS2"
8658   "edge32n\t%r1, %r2, %0"
8659   [(set_attr "type" "edgen")])
8661 (define_insn "edge32ln<P:mode>_vis"
8662   [(set (match_operand:P 0 "register_operand" "=r")
8663         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8664                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
8665                   UNSPEC_EDGE32LN))]
8666   "TARGET_VIS2"
8667   "edge32ln\t%r1, %r2, %0"
8668   [(set_attr "type" "edge")])
8670 ;; Conditional moves are possible via fcmpX --> cmaskX -> bshuffle
8671 (define_insn "cmask8<P:mode>_vis"
8672   [(set (reg:DI GSR_REG)
8673         (unspec:DI [(match_operand:P 0 "register_or_zero_operand" "rJ")
8674                     (reg:DI GSR_REG)]
8675                    UNSPEC_CMASK8))]
8676   "TARGET_VIS3"
8677   "cmask8\t%r0"
8678   [(set_attr "type" "fga")])
8680 (define_insn "cmask16<P:mode>_vis"
8681   [(set (reg:DI GSR_REG)
8682         (unspec:DI [(match_operand:P 0 "register_or_zero_operand" "rJ")
8683                     (reg:DI GSR_REG)]
8684                    UNSPEC_CMASK16))]
8685   "TARGET_VIS3"
8686   "cmask16\t%r0"
8687   [(set_attr "type" "fga")])
8689 (define_insn "cmask32<P:mode>_vis"
8690   [(set (reg:DI GSR_REG)
8691         (unspec:DI [(match_operand:P 0 "register_or_zero_operand" "rJ")
8692                     (reg:DI GSR_REG)]
8693                    UNSPEC_CMASK32))]
8694   "TARGET_VIS3"
8695   "cmask32\t%r0"
8696   [(set_attr "type" "fga")])
8698 (define_insn "fchksm16_vis"
8699   [(set (match_operand:V4HI 0 "register_operand" "=e")
8700         (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "e")
8701                       (match_operand:V4HI 2 "register_operand" "e")]
8702                      UNSPEC_FCHKSM16))]
8703   "TARGET_VIS3"
8704   "fchksm16\t%1, %2, %0"
8705   [(set_attr "type" "fga")])
8707 (define_code_iterator vis3_shift [ashift ss_ashift lshiftrt ashiftrt])
8708 (define_code_attr vis3_shift_insn
8709   [(ashift "fsll") (ss_ashift "fslas") (lshiftrt "fsrl") (ashiftrt "fsra")])
8710 (define_code_attr vis3_shift_patname
8711   [(ashift "ashl") (ss_ashift "ssashl") (lshiftrt "lshr") (ashiftrt "ashr")])
8712    
8713 (define_insn "v<vis3_shift_patname><mode>3"
8714   [(set (match_operand:GCM 0 "register_operand" "=<vconstr>")
8715         (vis3_shift:GCM (match_operand:GCM 1 "register_operand" "<vconstr>")
8716                         (match_operand:GCM 2 "register_operand" "<vconstr>")))]
8717   "TARGET_VIS3"
8718   "<vis3_shift_insn><vbits>\t%1, %2, %0"
8719   [(set_attr "type" "fga")])
8721 (define_insn "pdistn<mode>_vis"
8722   [(set (match_operand:P 0 "register_operand" "=r")
8723         (unspec:P [(match_operand:V8QI 1 "register_operand" "e")
8724                    (match_operand:V8QI 2 "register_operand" "e")]
8725          UNSPEC_PDISTN))]
8726   "TARGET_VIS3"
8727   "pdistn\t%1, %2, %0"
8728   [(set_attr "type" "pdistn")
8729    (set_attr "fptype" "double")])
8731 (define_insn "fmean16_vis"
8732   [(set (match_operand:V4HI 0 "register_operand" "=e")
8733         (truncate:V4HI
8734           (lshiftrt:V4SI
8735             (plus:V4SI
8736               (plus:V4SI
8737                 (zero_extend:V4SI
8738                   (match_operand:V4HI 1 "register_operand" "e"))
8739                 (zero_extend:V4SI
8740                   (match_operand:V4HI 2 "register_operand" "e")))
8741               (const_vector:V4SI [(const_int 1) (const_int 1)
8742                                   (const_int 1) (const_int 1)]))
8743           (const_int 1))))]
8744   "TARGET_VIS3"
8745   "fmean16\t%1, %2, %0"
8746   [(set_attr "type" "fga")])
8748 (define_insn "fp<plusminus_insn>64_vis"
8749   [(set (match_operand:V1DI 0 "register_operand" "=e")
8750         (plusminus:V1DI (match_operand:V1DI 1 "register_operand" "e")
8751                         (match_operand:V1DI 2 "register_operand" "e")))]
8752   "TARGET_VIS3"
8753   "fp<plusminus_insn>64\t%1, %2, %0"
8754   [(set_attr "type" "fga")])
8756 (define_mode_iterator VASS [V4HI V2SI V2HI V1SI])
8757 (define_code_iterator vis3_addsub_ss [ss_plus ss_minus])
8758 (define_code_attr vis3_addsub_ss_insn
8759   [(ss_plus "fpadds") (ss_minus "fpsubs")])
8760 (define_code_attr vis3_addsub_ss_patname
8761   [(ss_plus "ssadd") (ss_minus "sssub")])
8763 (define_insn "<vis3_addsub_ss_patname><mode>3"
8764   [(set (match_operand:VASS 0 "register_operand" "=<vconstr>")
8765         (vis3_addsub_ss:VASS (match_operand:VASS 1 "register_operand" "<vconstr>")
8766                              (match_operand:VASS 2 "register_operand" "<vconstr>")))]
8767   "TARGET_VIS3"
8768   "<vis3_addsub_ss_insn><vbits>\t%1, %2, %0"
8769   [(set_attr "type" "fga")])
8771 (define_insn "fucmp<code>8<P:mode>_vis"
8772   [(set (match_operand:P 0 "register_operand" "=r")
8773         (unspec:P [(gcond:V8QI (match_operand:V8QI 1 "register_operand" "e")
8774                                (match_operand:V8QI 2 "register_operand" "e"))]
8775          UNSPEC_FUCMP))]
8776   "TARGET_VIS3"
8777   "fucmp<code>8\t%1, %2, %0"
8778   [(set_attr "type" "visl")])
8780 (define_insn "*naddsf3"
8781   [(set (match_operand:SF 0 "register_operand" "=f")
8782         (neg:SF (plus:SF (match_operand:SF 1 "register_operand" "f")
8783                          (match_operand:SF 2 "register_operand" "f"))))]
8784   "TARGET_VIS3"
8785   "fnadds\t%1, %2, %0"
8786   [(set_attr "type" "fp")])
8788 (define_insn "*nadddf3"
8789   [(set (match_operand:DF 0 "register_operand" "=e")
8790         (neg:DF (plus:DF (match_operand:DF 1 "register_operand" "e")
8791                          (match_operand:DF 2 "register_operand" "e"))))]
8792   "TARGET_VIS3"
8793   "fnaddd\t%1, %2, %0"
8794   [(set_attr "type" "fp")
8795    (set_attr "fptype" "double")])
8797 (define_insn "*nmulsf3"
8798   [(set (match_operand:SF 0 "register_operand" "=f")
8799         (mult:SF (neg:SF (match_operand:SF 1 "register_operand" "f"))
8800                  (match_operand:SF 2 "register_operand" "f")))]
8801   "TARGET_VIS3"
8802   "fnmuls\t%1, %2, %0"
8803   [(set_attr "type" "fpmul")])
8805 (define_insn "*nmuldf3"
8806   [(set (match_operand:DF 0 "register_operand" "=e")
8807         (mult:DF (neg:DF (match_operand:DF 1 "register_operand" "e"))
8808                  (match_operand:DF 2 "register_operand" "e")))]
8809   "TARGET_VIS3"
8810   "fnmuld\t%1, %2, %0"
8811   [(set_attr "type" "fpmul")
8812    (set_attr "fptype" "double")])
8814 (define_insn "*nmuldf3_extend"
8815   [(set (match_operand:DF 0 "register_operand" "=e")
8816         (mult:DF (neg:DF (float_extend:DF
8817                            (match_operand:SF 1 "register_operand" "f")))
8818                  (float_extend:DF
8819                    (match_operand:SF 2 "register_operand" "f"))))]
8820   "TARGET_VIS3"
8821   "fnsmuld\t%1, %2, %0"
8822   [(set_attr "type" "fpmul")
8823    (set_attr "fptype" "double")])
8825 (define_insn "fhaddsf_vis"
8826   [(set (match_operand:SF 0 "register_operand" "=f")
8827         (unspec:SF [(match_operand:SF 1 "register_operand" "f")
8828                     (match_operand:SF 2 "register_operand" "f")]
8829                    UNSPEC_FHADD))]
8830   "TARGET_VIS3"
8831   "fhadds\t%1, %2, %0"
8832   [(set_attr "type" "fp")])
8834 (define_insn "fhadddf_vis"
8835   [(set (match_operand:DF 0 "register_operand" "=f")
8836         (unspec:DF [(match_operand:DF 1 "register_operand" "f")
8837                     (match_operand:DF 2 "register_operand" "f")]
8838                    UNSPEC_FHADD))]
8839   "TARGET_VIS3"
8840   "fhaddd\t%1, %2, %0"
8841   [(set_attr "type" "fp")
8842    (set_attr "fptype" "double")])
8844 (define_insn "fhsubsf_vis"
8845   [(set (match_operand:SF 0 "register_operand" "=f")
8846         (unspec:SF [(match_operand:SF 1 "register_operand" "f")
8847                     (match_operand:SF 2 "register_operand" "f")]
8848                    UNSPEC_FHSUB))]
8849   "TARGET_VIS3"
8850   "fhsubs\t%1, %2, %0"
8851   [(set_attr "type" "fp")])
8853 (define_insn "fhsubdf_vis"
8854   [(set (match_operand:DF 0 "register_operand" "=f")
8855         (unspec:DF [(match_operand:DF 1 "register_operand" "f")
8856                     (match_operand:DF 2 "register_operand" "f")]
8857                    UNSPEC_FHSUB))]
8858   "TARGET_VIS3"
8859   "fhsubd\t%1, %2, %0"
8860   [(set_attr "type" "fp")
8861    (set_attr "fptype" "double")])
8863 (define_insn "fnhaddsf_vis"
8864   [(set (match_operand:SF 0 "register_operand" "=f")
8865         (neg:SF (unspec:SF [(match_operand:SF 1 "register_operand" "f")
8866                             (match_operand:SF 2 "register_operand" "f")]
8867                            UNSPEC_FHADD)))]
8868   "TARGET_VIS3"
8869   "fnhadds\t%1, %2, %0"
8870   [(set_attr "type" "fp")])
8872 (define_insn "fnhadddf_vis"
8873   [(set (match_operand:DF 0 "register_operand" "=f")
8874         (neg:DF (unspec:DF [(match_operand:DF 1 "register_operand" "f")
8875                             (match_operand:DF 2 "register_operand" "f")]
8876                            UNSPEC_FHADD)))]
8877   "TARGET_VIS3"
8878   "fnhaddd\t%1, %2, %0"
8879   [(set_attr "type" "fp")
8880    (set_attr "fptype" "double")])
8882 (define_expand "umulxhi_vis"
8883   [(set (match_operand:DI 0 "register_operand" "")
8884         (truncate:DI
8885           (lshiftrt:TI
8886             (mult:TI (zero_extend:TI
8887                        (match_operand:DI 1 "arith_operand" ""))
8888                      (zero_extend:TI
8889                        (match_operand:DI 2 "arith_operand" "")))
8890            (const_int 64))))]
8891  "TARGET_VIS3"
8893   if (! TARGET_ARCH64)
8894     {
8895       emit_insn (gen_umulxhi_v8plus (operands[0], operands[1], operands[2]));
8896       DONE;
8897     }
8900 (define_insn "*umulxhi_sp64"
8901   [(set (match_operand:DI 0 "register_operand" "=r")
8902         (truncate:DI
8903           (lshiftrt:TI
8904             (mult:TI (zero_extend:TI
8905                        (match_operand:DI 1 "arith_operand" "%r"))
8906                      (zero_extend:TI
8907                        (match_operand:DI 2 "arith_operand" "rI")))
8908            (const_int 64))))]
8909   "TARGET_VIS3 && TARGET_ARCH64"
8910   "umulxhi\t%1, %2, %0"
8911   [(set_attr "type" "imul")])
8913 (define_insn "umulxhi_v8plus"
8914   [(set (match_operand:DI 0 "register_operand" "=r,h")
8915         (truncate:DI
8916           (lshiftrt:TI
8917             (mult:TI (zero_extend:TI
8918                        (match_operand:DI 1 "arith_operand" "%r,0"))
8919                      (zero_extend:TI
8920                        (match_operand:DI 2 "arith_operand" "rI,rI")))
8921            (const_int 64))))
8922    (clobber (match_scratch:SI 3 "=&h,X"))
8923    (clobber (match_scratch:SI 4 "=&h,X"))]
8924   "TARGET_VIS3 && ! TARGET_ARCH64"
8925   "* return output_v8plus_mult (insn, operands, \"umulxhi\");"
8926   [(set_attr "type" "imul")
8927    (set_attr "length" "9,8")])
8929 (define_expand "xmulx_vis"
8930   [(set (match_operand:DI 0 "register_operand" "")
8931         (truncate:DI
8932           (unspec:TI [(zero_extend:TI
8933                         (match_operand:DI 1 "arith_operand" ""))
8934                       (zero_extend:TI
8935                         (match_operand:DI 2 "arith_operand" ""))]
8936            UNSPEC_XMUL)))]
8937   "TARGET_VIS3"
8939   if (! TARGET_ARCH64)
8940     {
8941       emit_insn (gen_xmulx_v8plus (operands[0], operands[1], operands[2]));
8942       DONE;
8943     }
8946 (define_insn "*xmulx_sp64"
8947   [(set (match_operand:DI 0 "register_operand" "=r")
8948         (truncate:DI
8949           (unspec:TI [(zero_extend:TI
8950                         (match_operand:DI 1 "arith_operand" "%r"))
8951                       (zero_extend:TI
8952                         (match_operand:DI 2 "arith_operand" "rI"))]
8953            UNSPEC_XMUL)))]
8954   "TARGET_VIS3 && TARGET_ARCH64"
8955   "xmulx\t%1, %2, %0"
8956   [(set_attr "type" "imul")])
8958 (define_insn "xmulx_v8plus"
8959   [(set (match_operand:DI 0 "register_operand" "=r,h")
8960         (truncate:DI
8961           (unspec:TI [(zero_extend:TI
8962                         (match_operand:DI 1 "arith_operand" "%r,0"))
8963                       (zero_extend:TI
8964                         (match_operand:DI 2 "arith_operand" "rI,rI"))]
8965            UNSPEC_XMUL)))
8966    (clobber (match_scratch:SI 3 "=&h,X"))
8967    (clobber (match_scratch:SI 4 "=&h,X"))]
8968   "TARGET_VIS3 && ! TARGET_ARCH64"
8969   "* return output_v8plus_mult (insn, operands, \"xmulx\");"
8970   [(set_attr "type" "imul")
8971    (set_attr "length" "9,8")])
8973 (define_expand "xmulxhi_vis"
8974   [(set (match_operand:DI 0 "register_operand" "")
8975         (truncate:DI
8976           (lshiftrt:TI
8977             (unspec:TI [(zero_extend:TI
8978                           (match_operand:DI 1 "arith_operand" ""))
8979                         (zero_extend:TI
8980                           (match_operand:DI 2 "arith_operand" ""))]
8981              UNSPEC_XMUL)
8982            (const_int 64))))]
8983   "TARGET_VIS3"
8985   if (! TARGET_ARCH64)
8986     {
8987       emit_insn (gen_xmulxhi_v8plus (operands[0], operands[1], operands[2]));
8988       DONE;
8989     }
8992 (define_insn "*xmulxhi_sp64"
8993   [(set (match_operand:DI 0 "register_operand" "=r")
8994         (truncate:DI
8995           (lshiftrt:TI
8996             (unspec:TI [(zero_extend:TI
8997                           (match_operand:DI 1 "arith_operand" "%r"))
8998                         (zero_extend:TI
8999                           (match_operand:DI 2 "arith_operand" "rI"))]
9000              UNSPEC_XMUL)
9001            (const_int 64))))]
9002   "TARGET_VIS3 && TARGET_ARCH64"
9003   "xmulxhi\t%1, %2, %0"
9004   [(set_attr "type" "imul")])
9006 (define_insn "xmulxhi_v8plus"
9007   [(set (match_operand:DI 0 "register_operand" "=r,h")
9008         (truncate:DI
9009           (lshiftrt:TI
9010             (unspec:TI [(zero_extend:TI
9011                           (match_operand:DI 1 "arith_operand" "%r,0"))
9012                         (zero_extend:TI
9013                           (match_operand:DI 2 "arith_operand" "rI,rI"))]
9014              UNSPEC_XMUL)
9015            (const_int 64))))
9016    (clobber (match_scratch:SI 3 "=&h,X"))
9017    (clobber (match_scratch:SI 4 "=&h,X"))]
9018   "TARGET_VIS3 && !TARGET_ARCH64"
9019   "* return output_v8plus_mult (insn, operands, \"xmulxhi\");"
9020   [(set_attr "type" "imul")
9021    (set_attr "length" "9,8")])
9023 (include "sync.md")