2013-01-08 Paul Thomas <pault@gcc.gnu.org>
[official-gcc.git] / gcc / config / sparc / sparc.md
blob7ec6302eeca62cb1955f4f3f4412553d79840855
1 ;; Machine description for SPARC chip for GCC
2 ;;  Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 ;;  1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
4 ;;  2011 Free Software Foundation, Inc.
5 ;;  Contributed by Michael Tiemann (tiemann@cygnus.com)
6 ;;  64-bit SPARC-V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
7 ;;  at Cygnus Support.
9 ;; This file is part of GCC.
11 ;; GCC is free software; you can redistribute it and/or modify
12 ;; it under the terms of the GNU General Public License as published by
13 ;; the Free Software Foundation; either version 3, or (at your option)
14 ;; any later version.
16 ;; GCC is distributed in the hope that it will be useful,
17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 ;; GNU General Public License for more details.
21 ;; You should have received a copy of the GNU General Public License
22 ;; along with GCC; see the file COPYING3.  If not see
23 ;; <http://www.gnu.org/licenses/>.
25 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
27 (define_constants
28   [(UNSPEC_MOVE_PIC             0)
29    (UNSPEC_UPDATE_RETURN        1)
30    (UNSPEC_LOAD_PCREL_SYM       2)
31    (UNSPEC_FRAME_BLOCKAGE      3)
32    (UNSPEC_MOVE_PIC_LABEL       5)
33    (UNSPEC_SETH44               6)
34    (UNSPEC_SETM44               7)
35    (UNSPEC_SETHH                9)
36    (UNSPEC_SETLM                10)
37    (UNSPEC_EMB_HISUM            11)
38    (UNSPEC_EMB_TEXTUHI          13)
39    (UNSPEC_EMB_TEXTHI           14)
40    (UNSPEC_EMB_TEXTULO          15)
41    (UNSPEC_EMB_SETHM            18)
42    (UNSPEC_MOVE_GOTDATA         19)
44    (UNSPEC_MEMBAR               20)
45    (UNSPEC_ATOMIC               21)
47    (UNSPEC_TLSGD                30)
48    (UNSPEC_TLSLDM               31)
49    (UNSPEC_TLSLDO               32)
50    (UNSPEC_TLSIE                33)
51    (UNSPEC_TLSLE                34)
52    (UNSPEC_TLSLD_BASE           35)
54    (UNSPEC_FPACK16              40)
55    (UNSPEC_FPACK32              41)
56    (UNSPEC_FPACKFIX             42)
57    (UNSPEC_FEXPAND              43)
58    (UNSPEC_MUL16AU              44)
59    (UNSPEC_MUL16AL              45)
60    (UNSPEC_MUL8UL               46)
61    (UNSPEC_MULDUL               47)
62    (UNSPEC_ALIGNDATA            48)
63    (UNSPEC_FCMP                 49)
64    (UNSPEC_PDIST                50)
65    (UNSPEC_EDGE8                51)
66    (UNSPEC_EDGE8L               52)
67    (UNSPEC_EDGE16               53)
68    (UNSPEC_EDGE16L              54)
69    (UNSPEC_EDGE32               55)
70    (UNSPEC_EDGE32L              56)
71    (UNSPEC_ARRAY8               57)
72    (UNSPEC_ARRAY16              58)
73    (UNSPEC_ARRAY32              59)
75    (UNSPEC_SP_SET               60)
76    (UNSPEC_SP_TEST              61)
78    (UNSPEC_EDGE8N               70)
79    (UNSPEC_EDGE8LN              71)
80    (UNSPEC_EDGE16N              72)
81    (UNSPEC_EDGE16LN             73)
82    (UNSPEC_EDGE32N              74)
83    (UNSPEC_EDGE32LN             75)
84    (UNSPEC_BSHUFFLE             76)
85    (UNSPEC_CMASK8               77)
86    (UNSPEC_CMASK16              78)
87    (UNSPEC_CMASK32              79)
88    (UNSPEC_FCHKSM16             80)
89    (UNSPEC_PDISTN               81)
90    (UNSPEC_FUCMP                82)
91    (UNSPEC_FHADD                83)
92    (UNSPEC_FHSUB                84)
93    (UNSPEC_XMUL                 85)
94    (UNSPEC_MUL8                 86)
95    (UNSPEC_MUL8SU               87)
96    (UNSPEC_MULDSU               88)
97   ])
99 (define_constants
100   [(UNSPECV_BLOCKAGE            0)
101    (UNSPECV_FLUSHW              1)
102    (UNSPECV_FLUSH               4)
103    (UNSPECV_SAVEW               6)
104    (UNSPECV_CAS                 8)
105    (UNSPECV_SWAP                9)
106    (UNSPECV_LDSTUB              10)
107    (UNSPECV_PROBE_STACK_RANGE   11)
108   ])
110 (define_constants
111  [(G0_REG                       0)
112   (G1_REG                       1)
113   (G2_REG                       2)
114   (G3_REG                       3)
115   (G4_REG                       4)
116   (G5_REG                       5)
117   (G6_REG                       6)
118   (G7_REG                       7)
119   (O0_REG                       8)
120   (O1_REG                       9)
121   (O2_REG                       10)
122   (O3_REG                       11)
123   (O4_REG                       12)
124   (O5_REG                       13)
125   (O6_REG                       14)
126   (O7_REG                       15)
127   (L0_REG                       16)
128   (L1_REG                       17)
129   (L2_REG                       18)
130   (L3_REG                       19)
131   (L4_REG                       20)
132   (L5_REG                       21)
133   (L6_REG                       22)
134   (L7_REG                       23)
135   (I0_REG                       24)
136   (I1_REG                       25)
137   (I2_REG                       26)
138   (I3_REG                       27)
139   (I4_REG                       28)
140   (I5_REG                       29)
141   (I6_REG                       30)
142   (I7_REG                       31)
143   (F0_REG                       32)
144   (F1_REG                       33)
145   (F2_REG                       34)
146   (F3_REG                       35)
147   (F4_REG                       36)
148   (F5_REG                       37)
149   (F6_REG                       38)
150   (F7_REG                       39)
151   (F8_REG                       40)
152   (F9_REG                       41)
153   (F10_REG                      42)
154   (F11_REG                      43)
155   (F12_REG                      44)
156   (F13_REG                      45)
157   (F14_REG                      46)
158   (F15_REG                      47)
159   (F16_REG                      48)
160   (F17_REG                      49)
161   (F18_REG                      50)
162   (F19_REG                      51)
163   (F20_REG                      52)
164   (F21_REG                      53)
165   (F22_REG                      54)
166   (F23_REG                      55)
167   (F24_REG                      56)
168   (F25_REG                      57)
169   (F26_REG                      58)
170   (F27_REG                      59)
171   (F28_REG                      60)
172   (F29_REG                      61)
173   (F30_REG                      62)
174   (F31_REG                      63)
175   (F32_REG                      64)
176   (F34_REG                      66)
177   (F36_REG                      68)
178   (F38_REG                      70)
179   (F40_REG                      72)
180   (F42_REG                      74)
181   (F44_REG                      76)
182   (F46_REG                      78)
183   (F48_REG                      80)
184   (F50_REG                      82)
185   (F52_REG                      84)
186   (F54_REG                      86)
187   (F56_REG                      88)
188   (F58_REG                      90)
189   (F60_REG                      92)
190   (F62_REG                      94)
191   (FCC0_REG                     96)
192   (FCC1_REG                     97)
193   (FCC2_REG                     98)
194   (FCC3_REG                     99)
195   (CC_REG                       100)
196   (SFP_REG                      101)
197   (GSR_REG                      102)
198  ])
200 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
201 (define_mode_iterator I [QI HI SI DI])
202 (define_mode_iterator F [SF DF TF])
204 ;; The upper 32 fp regs on the v9 can't hold SFmode values.  To deal with this
205 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip.  The name
206 ;; is a bit of a misnomer as it covers all 64 fp regs.  The corresponding
207 ;; constraint letter is 'e'.  To avoid any confusion, 'e' is used instead of
208 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
210 ;; Attribute for cpu type.
211 ;; These must match the values for enum processor_type in sparc.h.
212 (define_attr "cpu"
213   "v7,
214    cypress,
215    v8,
216    supersparc,
217    hypersparc,
218    leon,
219    sparclite,
220    f930,
221    f934,
222    sparclite86x,
223    sparclet,
224    tsc701,
225    v9,
226    ultrasparc,
227    ultrasparc3,
228    niagara,
229    niagara2,
230    niagara3,
231    niagara4"
232   (const (symbol_ref "sparc_cpu_attr")))
234 ;; Attribute for the instruction set.
235 ;; At present we only need to distinguish v9/!v9, but for clarity we
236 ;; test TARGET_V8 too.
237 (define_attr "isa" "v7,v8,v9,sparclet"
238  (const
239   (cond [(symbol_ref "TARGET_V9") (const_string "v9")
240          (symbol_ref "TARGET_V8") (const_string "v8")
241          (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
242         (const_string "v7"))))
244 (define_attr "cpu_feature" "none,fpu,fpunotv9,v9,vis,vis3" (const_string "none"))
246 (define_attr "enabled" ""
247   (cond [(eq_attr "cpu_feature" "none") (const_int 1)
248          (eq_attr "cpu_feature" "fpu") (symbol_ref "TARGET_FPU")
249          (eq_attr "cpu_feature" "fpunotv9") (symbol_ref "TARGET_FPU && ! TARGET_V9")
250          (eq_attr "cpu_feature" "v9") (symbol_ref "TARGET_V9")
251          (eq_attr "cpu_feature" "vis") (symbol_ref "TARGET_VIS")
252          (eq_attr "cpu_feature" "vis3") (symbol_ref "TARGET_VIS3")]
253         (const_int 0)))
255 ;; Insn type.
256 (define_attr "type"
257   "ialu,compare,shift,
258    load,sload,store,
259    uncond_branch,branch,call,sibcall,call_no_delay_slot,return,
260    cbcond,uncond_cbcond,
261    imul,idiv,
262    fpload,fpstore,
263    fp,fpmove,
264    fpcmove,fpcrmove,
265    fpcmp,
266    fpmul,fpdivs,fpdivd,
267    fpsqrts,fpsqrtd,
268    fga,visl,vismv,fgm_pack,fgm_mul,pdist,pdistn,edge,edgen,gsr,array,
269    cmove,
270    ialuX,
271    multi,savew,flushw,iflush,trap"
272   (const_string "ialu"))
274 ;; True if branch/call has empty delay slot and will emit a nop in it
275 (define_attr "empty_delay_slot" "false,true"
276   (symbol_ref "(empty_delay_slot (insn)
277                 ? EMPTY_DELAY_SLOT_TRUE : EMPTY_DELAY_SLOT_FALSE)"))
279 ;; True if we are making use of compare-and-branch instructions.
280 ;; True if we should emit a nop after a cbcond instruction
281 (define_attr "emit_cbcond_nop" "false,true"
282   (symbol_ref "(emit_cbcond_nop (insn)
283                 ? EMIT_CBCOND_NOP_TRUE : EMIT_CBCOND_NOP_FALSE)"))
285 (define_attr "branch_type" "none,icc,fcc,reg"
286   (const_string "none"))
288 (define_attr "pic" "false,true"
289   (symbol_ref "(flag_pic != 0 ? PIC_TRUE : PIC_FALSE)"))
291 (define_attr "calls_alloca" "false,true"
292   (symbol_ref "(cfun->calls_alloca != 0
293                 ? CALLS_ALLOCA_TRUE : CALLS_ALLOCA_FALSE)"))
295 (define_attr "calls_eh_return" "false,true"
296    (symbol_ref "(crtl->calls_eh_return != 0
297                  ? CALLS_EH_RETURN_TRUE : CALLS_EH_RETURN_FALSE)"))
299 (define_attr "leaf_function" "false,true"
300   (symbol_ref "(crtl->uses_only_leaf_regs != 0
301                 ? LEAF_FUNCTION_TRUE : LEAF_FUNCTION_FALSE)"))
303 (define_attr "delayed_branch" "false,true"
304   (symbol_ref "(flag_delayed_branch != 0
305                 ? DELAYED_BRANCH_TRUE : DELAYED_BRANCH_FALSE)"))
307 (define_attr "flat" "false,true"
308   (symbol_ref "(TARGET_FLAT != 0
309                 ? FLAT_TRUE : FLAT_FALSE)"))
311 ;; Length (in # of insns).
312 ;; Beware that setting a length greater or equal to 3 for conditional branches
313 ;; has a side-effect (see output_cbranch and output_v9branch).
314 (define_attr "length" ""
315   (cond [(eq_attr "type" "uncond_branch,call")
316            (if_then_else (eq_attr "empty_delay_slot" "true")
317              (const_int 2)
318              (const_int 1))
319          (eq_attr "type" "sibcall")
320            (if_then_else (eq_attr "leaf_function" "true")
321              (if_then_else (eq_attr "empty_delay_slot" "true")
322                (const_int 3)
323                (const_int 2))
324              (if_then_else (eq_attr "empty_delay_slot" "true")
325                (const_int 2)
326                (const_int 1)))
327          (eq_attr "branch_type" "icc")
328            (if_then_else (match_operand 0 "noov_compare64_operator" "")
329              (if_then_else (lt (pc) (match_dup 1))
330                (if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000))
331                  (if_then_else (eq_attr "empty_delay_slot" "true")
332                    (const_int 2)
333                    (const_int 1))
334                  (if_then_else (eq_attr "empty_delay_slot" "true")
335                    (const_int 4)
336                    (const_int 3)))
337                (if_then_else (lt (minus (pc) (match_dup 1)) (const_int 260000))
338                  (if_then_else (eq_attr "empty_delay_slot" "true")
339                    (const_int 2)
340                    (const_int 1))
341                  (if_then_else (eq_attr "empty_delay_slot" "true")
342                    (const_int 4)
343                    (const_int 3))))
344              (if_then_else (eq_attr "empty_delay_slot" "true")
345                (const_int 2)
346                (const_int 1)))
347          (eq_attr "branch_type" "fcc")
348            (if_then_else (match_operand 0 "fcc0_register_operand" "")
349              (if_then_else (eq_attr "empty_delay_slot" "true")
350                (if_then_else (not (match_test "TARGET_V9"))
351                  (const_int 3)
352                  (const_int 2))
353                (if_then_else (not (match_test "TARGET_V9"))
354                  (const_int 2)
355                  (const_int 1)))
356              (if_then_else (lt (pc) (match_dup 2))
357                (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000))
358                  (if_then_else (eq_attr "empty_delay_slot" "true")
359                    (const_int 2)
360                    (const_int 1))
361                  (if_then_else (eq_attr "empty_delay_slot" "true")
362                    (const_int 4)
363                    (const_int 3)))
364                (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000))
365                  (if_then_else (eq_attr "empty_delay_slot" "true")
366                    (const_int 2)
367                    (const_int 1))
368                  (if_then_else (eq_attr "empty_delay_slot" "true")
369                    (const_int 4)
370                    (const_int 3)))))
371          (eq_attr "branch_type" "reg")
372            (if_then_else (lt (pc) (match_dup 2))
373              (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000))
374                (if_then_else (eq_attr "empty_delay_slot" "true")
375                  (const_int 2)
376                  (const_int 1))
377                (if_then_else (eq_attr "empty_delay_slot" "true")
378                  (const_int 4)
379                  (const_int 3)))
380              (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000))
381                (if_then_else (eq_attr "empty_delay_slot" "true")
382                  (const_int 2)
383                  (const_int 1))
384                (if_then_else (eq_attr "empty_delay_slot" "true")
385                  (const_int 4)
386                  (const_int 3))))
387          (eq_attr "type" "cbcond")
388            (if_then_else (lt (pc) (match_dup 3))
389              (if_then_else (lt (minus (match_dup 3) (pc)) (const_int 500))
390                (if_then_else (eq_attr "emit_cbcond_nop" "true")
391                  (const_int 2)
392                  (const_int 1))
393                (const_int 4))
394              (if_then_else (lt (minus (pc) (match_dup 3)) (const_int 500))
395                (if_then_else (eq_attr "emit_cbcond_nop" "true")
396                  (const_int 2)
397                  (const_int 1))
398                (const_int 4)))
399          (eq_attr "type" "uncond_cbcond")
400            (if_then_else (lt (pc) (match_dup 0))
401              (if_then_else (lt (minus (match_dup 0) (pc)) (const_int 500))
402                (if_then_else (eq_attr "emit_cbcond_nop" "true")
403                  (const_int 2)
404                  (const_int 1))
405                (const_int 1))
406              (if_then_else (lt (minus (pc) (match_dup 0)) (const_int 500))
407                (if_then_else (eq_attr "emit_cbcond_nop" "true")
408                  (const_int 2)
409                  (const_int 1))
410                (const_int 1)))
411          ] (const_int 1)))
413 ;; FP precision.
414 (define_attr "fptype" "single,double"
415   (const_string "single"))
417 ;; UltraSPARC-III integer load type.
418 (define_attr "us3load_type" "2cycle,3cycle"
419   (const_string "2cycle"))
421 (define_asm_attributes
422   [(set_attr "length" "2")
423    (set_attr "type" "multi")])
425 ;; Attributes for instruction and branch scheduling
426 (define_attr "tls_call_delay" "false,true"
427   (symbol_ref "(tls_call_delay (insn)
428                 ? TLS_CALL_DELAY_TRUE : TLS_CALL_DELAY_FALSE)"))
430 (define_attr "in_call_delay" "false,true"
431   (cond [(eq_attr "type" "uncond_branch,branch,cbcond,uncond_cbcond,call,sibcall,call_no_delay_slot,multi")
432                 (const_string "false")
433          (eq_attr "type" "load,fpload,store,fpstore")
434                 (if_then_else (eq_attr "length" "1")
435                               (const_string "true")
436                               (const_string "false"))]
437          (if_then_else (and (eq_attr "length" "1")
438                             (eq_attr "tls_call_delay" "true"))
439                        (const_string "true")
440                        (const_string "false"))))
442 (define_attr "eligible_for_sibcall_delay" "false,true"
443   (symbol_ref "(eligible_for_sibcall_delay (insn)
444                 ? ELIGIBLE_FOR_SIBCALL_DELAY_TRUE
445                 : ELIGIBLE_FOR_SIBCALL_DELAY_FALSE)"))
447 (define_attr "eligible_for_return_delay" "false,true"
448   (symbol_ref "(eligible_for_return_delay (insn)
449                 ? ELIGIBLE_FOR_RETURN_DELAY_TRUE
450                 : ELIGIBLE_FOR_RETURN_DELAY_FALSE)"))
452 ;; ??? !v9: Should implement the notion of predelay slots for floating-point
453 ;; branches.  This would allow us to remove the nop always inserted before
454 ;; a floating point branch.
456 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
457 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
458 ;; This is because doing so will add several pipeline stalls to the path
459 ;; that the load/store did not come from.  Unfortunately, there is no way
460 ;; to prevent fill_eager_delay_slots from using load/store without completely
461 ;; disabling them.  For the SPEC benchmark set, this is a serious lose,
462 ;; because it prevents us from moving back the final store of inner loops.
464 (define_attr "in_branch_delay" "false,true"
465   (if_then_else (and (eq_attr "type" "!uncond_branch,branch,cbcond,uncond_cbcond,call,sibcall,call_no_delay_slot,multi")
466                      (eq_attr "length" "1"))
467                 (const_string "true")
468                 (const_string "false")))
470 (define_attr "in_uncond_branch_delay" "false,true"
471   (if_then_else (and (eq_attr "type" "!uncond_branch,branch,cbcond,uncond_cbcond,call,sibcall,call_no_delay_slot,multi")
472                      (eq_attr "length" "1"))
473                 (const_string "true")
474                 (const_string "false")))
476 (define_attr "in_annul_branch_delay" "false,true"
477   (if_then_else (and (eq_attr "type" "!uncond_branch,branch,cbcond,uncond_cbcond,call,sibcall,call_no_delay_slot,multi")
478                      (eq_attr "length" "1"))
479                 (const_string "true")
480                 (const_string "false")))
482 (define_delay (eq_attr "type" "call")
483   [(eq_attr "in_call_delay" "true") (nil) (nil)])
485 (define_delay (eq_attr "type" "sibcall")
486   [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
488 (define_delay (eq_attr "type" "branch")
489   [(eq_attr "in_branch_delay" "true")
490    (nil) (eq_attr "in_annul_branch_delay" "true")])
492 (define_delay (eq_attr "type" "uncond_branch")
493   [(eq_attr "in_uncond_branch_delay" "true")
494    (nil) (nil)])
496 (define_delay (eq_attr "type" "return")
497   [(eq_attr "eligible_for_return_delay" "true") (nil) (nil)])
500 ;; Include SPARC DFA schedulers
502 (include "cypress.md")
503 (include "supersparc.md")
504 (include "hypersparc.md")
505 (include "leon.md")
506 (include "sparclet.md")
507 (include "ultra1_2.md")
508 (include "ultra3.md")
509 (include "niagara.md")
510 (include "niagara2.md")
511 (include "niagara4.md")
514 ;; Operand and operator predicates and constraints
516 (include "predicates.md")
517 (include "constraints.md")
520 ;; Compare instructions.
522 ;; These are just the DEFINE_INSNs to match the patterns and the
523 ;; DEFINE_SPLITs for some of the scc insns that actually require
524 ;; more than one machine instruction.  DEFINE_EXPANDs are further down.
526 ;; The compare DEFINE_INSNs.
528 (define_insn "*cmpsi_insn"
529   [(set (reg:CC CC_REG)
530         (compare:CC (match_operand:SI 0 "register_operand" "r")
531                     (match_operand:SI 1 "arith_operand" "rI")))]
532   ""
533   "cmp\t%0, %1"
534   [(set_attr "type" "compare")])
536 (define_insn "*cmpdi_sp64"
537   [(set (reg:CCX CC_REG)
538         (compare:CCX (match_operand:DI 0 "register_operand" "r")
539                      (match_operand:DI 1 "arith_operand" "rI")))]
540   "TARGET_ARCH64"
541   "cmp\t%0, %1"
542   [(set_attr "type" "compare")])
544 (define_insn "*cmpsf_fpe"
545   [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
546         (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
547                        (match_operand:SF 2 "register_operand" "f")))]
548   "TARGET_FPU"
550   if (TARGET_V9)
551     return "fcmpes\t%0, %1, %2";
552   return "fcmpes\t%1, %2";
554   [(set_attr "type" "fpcmp")])
556 (define_insn "*cmpdf_fpe"
557   [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
558         (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
559                        (match_operand:DF 2 "register_operand" "e")))]
560   "TARGET_FPU"
562   if (TARGET_V9)
563     return "fcmped\t%0, %1, %2";
564   return "fcmped\t%1, %2";
566   [(set_attr "type" "fpcmp")
567    (set_attr "fptype" "double")])
569 (define_insn "*cmptf_fpe"
570   [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
571         (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
572                        (match_operand:TF 2 "register_operand" "e")))]
573   "TARGET_FPU && TARGET_HARD_QUAD"
575   if (TARGET_V9)
576     return "fcmpeq\t%0, %1, %2";
577   return "fcmpeq\t%1, %2";
579   [(set_attr "type" "fpcmp")])
581 (define_insn "*cmpsf_fp"
582   [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
583         (compare:CCFP (match_operand:SF 1 "register_operand" "f")
584                       (match_operand:SF 2 "register_operand" "f")))]
585   "TARGET_FPU"
587   if (TARGET_V9)
588     return "fcmps\t%0, %1, %2";
589   return "fcmps\t%1, %2";
591   [(set_attr "type" "fpcmp")])
593 (define_insn "*cmpdf_fp"
594   [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
595         (compare:CCFP (match_operand:DF 1 "register_operand" "e")
596                       (match_operand:DF 2 "register_operand" "e")))]
597   "TARGET_FPU"
599   if (TARGET_V9)
600     return "fcmpd\t%0, %1, %2";
601   return "fcmpd\t%1, %2";
603   [(set_attr "type" "fpcmp")
604    (set_attr "fptype" "double")])
606 (define_insn "*cmptf_fp"
607   [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
608         (compare:CCFP (match_operand:TF 1 "register_operand" "e")
609                       (match_operand:TF 2 "register_operand" "e")))]
610   "TARGET_FPU && TARGET_HARD_QUAD"
612   if (TARGET_V9)
613     return "fcmpq\t%0, %1, %2";
614   return "fcmpq\t%1, %2";
616   [(set_attr "type" "fpcmp")])
618 ;; Next come the scc insns.
620 (define_expand "cstoresi4"
621   [(use (match_operator 1 "comparison_operator"
622          [(match_operand:SI 2 "compare_operand" "")
623           (match_operand:SI 3 "arith_operand" "")]))
624    (clobber (match_operand:SI 0 "register_operand"))]
625   ""
627   if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
628     operands[2] = force_reg (SImode, operands[2]);
629   if (emit_scc_insn (operands)) DONE; else FAIL;
632 (define_expand "cstoredi4"
633   [(use (match_operator 1 "comparison_operator"
634          [(match_operand:DI 2 "compare_operand" "")
635           (match_operand:DI 3 "arith_operand" "")]))
636    (clobber (match_operand:SI 0 "register_operand"))]
637   "TARGET_ARCH64"
639   if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
640     operands[2] = force_reg (DImode, operands[2]);
641   if (emit_scc_insn (operands)) DONE; else FAIL;
644 (define_expand "cstore<F:mode>4"
645   [(use (match_operator 1 "comparison_operator"
646          [(match_operand:F 2 "register_operand" "")
647           (match_operand:F 3 "register_operand" "")]))
648    (clobber (match_operand:SI 0 "register_operand"))]
649   "TARGET_FPU"
650   { if (emit_scc_insn (operands)) DONE; else FAIL; })
654 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
655 ;; generate addcc/subcc instructions.
657 (define_expand "seqsi_special"
658   [(set (match_dup 3)
659         (xor:SI (match_operand:SI 1 "register_operand" "")
660                 (match_operand:SI 2 "register_operand" "")))
661    (parallel [(set (match_operand:SI 0 "register_operand" "")
662                    (eq:SI (match_dup 3) (const_int 0)))
663               (clobber (reg:CC CC_REG))])]
664   ""
665   { operands[3] = gen_reg_rtx (SImode); })
667 (define_expand "seqdi_special"
668   [(set (match_dup 3)
669         (xor:DI (match_operand:DI 1 "register_operand" "")
670                 (match_operand:DI 2 "register_operand" "")))
671    (set (match_operand:SI 0 "register_operand" "")
672         (eq:SI (match_dup 3) (const_int 0)))]
673   "TARGET_ARCH64"
674   { operands[3] = gen_reg_rtx (DImode); })
676 (define_expand "snesi_special"
677   [(set (match_dup 3)
678         (xor:SI (match_operand:SI 1 "register_operand" "")
679                 (match_operand:SI 2 "register_operand" "")))
680    (parallel [(set (match_operand:SI 0 "register_operand" "")
681                    (ne:SI (match_dup 3) (const_int 0)))
682               (clobber (reg:CC CC_REG))])]
683   ""
684   { operands[3] = gen_reg_rtx (SImode); })
686 (define_expand "snedi_special"
687   [(set (match_dup 3)
688         (xor:DI (match_operand:DI 1 "register_operand" "")
689                 (match_operand:DI 2 "register_operand" "")))
690    (set (match_operand:SI 0 "register_operand" "")
691         (ne:SI (match_dup 3) (const_int 0)))]
692   "TARGET_ARCH64 && ! TARGET_VIS3"
693   { operands[3] = gen_reg_rtx (DImode); })
695 (define_expand "snedi_special_vis3"
696   [(set (match_dup 3)
697         (xor:DI (match_operand:DI 1 "register_operand" "")
698                 (match_operand:DI 2 "register_operand" "")))
699    (parallel [(set (match_operand:SI 0 "register_operand" "")
700                    (ne:SI (match_dup 3) (const_int 0)))
701               (clobber (reg:CCX CC_REG))])]
702   "TARGET_ARCH64 && TARGET_VIS3"
703   { operands[3] = gen_reg_rtx (DImode); })
706 ;; Now the DEFINE_INSNs for the scc cases.
708 ;; The SEQ and SNE patterns are special because they can be done
709 ;; without any branching and do not involve a COMPARE.  We want
710 ;; them to always use the splits below so the results can be
711 ;; scheduled.
713 (define_insn_and_split "*snesi_zero"
714   [(set (match_operand:SI 0 "register_operand" "=r")
715         (ne:SI (match_operand:SI 1 "register_operand" "r")
716                (const_int 0)))
717    (clobber (reg:CC CC_REG))]
718   ""
719   "#"
720   ""
721   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
722                                            (const_int 0)))
723    (set (match_dup 0) (ltu:SI (reg:CC CC_REG) (const_int 0)))]
724   ""
725   [(set_attr "length" "2")])
727 (define_insn_and_split "*neg_snesi_zero"
728   [(set (match_operand:SI 0 "register_operand" "=r")
729         (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
730                        (const_int 0))))
731    (clobber (reg:CC CC_REG))]
732   ""
733   "#"
734   ""
735   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
736                                            (const_int 0)))
737    (set (match_dup 0) (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0))))]
738   ""
739   [(set_attr "length" "2")])
741 (define_insn_and_split "*snesi_zero_extend"
742   [(set (match_operand:DI 0 "register_operand" "=r")
743         (ne:DI (match_operand:SI 1 "register_operand" "r")
744                (const_int 0)))
745    (clobber (reg:CC CC_REG))]
746   "TARGET_ARCH64"
747   "#"
748   "&& 1"
749   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (minus:SI (const_int 0)
750                                                      (match_dup 1))
751                                            (const_int 0)))
752    (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
753                                                         (const_int 0))
754                                                (ltu:SI (reg:CC_NOOV CC_REG)
755                                                        (const_int 0)))))]
756   ""
757   [(set_attr "length" "2")])
759 (define_insn_and_split "*neg_snesi_sign_extend"
760   [(set (match_operand:DI 0 "register_operand" "=r")
761         (neg:DI (ne:DI (match_operand:SI 1 "register_operand" "r")
762                       (const_int 0))))
763    (clobber (reg:CC CC_REG))]
764   "TARGET_ARCH64"
765   "#"
766   "&& 1"
767   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (minus:SI (const_int 0)
768                                                      (match_dup 1))
769                                            (const_int 0)))
770    (set (match_dup 0) (sign_extend:DI (neg:SI (ltu:SI (reg:CC CC_REG)
771                                                       (const_int 0)))))]
772   ""
773   [(set_attr "length" "2")])
775 (define_insn_and_split "*snedi_zero"
776   [(set (match_operand:DI 0 "register_operand" "=&r")
777         (ne:DI (match_operand:DI 1 "register_operand" "r")
778                (const_int 0)))]
779   "TARGET_ARCH64 && ! TARGET_VIS3"
780   "#"
781   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
782   [(set (match_dup 0) (const_int 0))
783    (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
784                                               (const_int 0))
785                                        (const_int 1)
786                                        (match_dup 0)))]
787   ""
788   [(set_attr "length" "2")])
790 (define_insn_and_split "*snedi_zero_vis3"
791   [(set (match_operand:DI 0 "register_operand" "=r")
792         (ne:DI (match_operand:DI 1 "register_operand" "r")
793                (const_int 0)))
794    (clobber (reg:CCX CC_REG))]
795   "TARGET_ARCH64 && TARGET_VIS3"
796   "#"
797   ""
798   [(set (reg:CCX_NOOV CC_REG) (compare:CCX_NOOV (neg:DI (match_dup 1))
799                                                 (const_int 0)))
800    (set (match_dup 0) (ltu:DI (reg:CCX CC_REG) (const_int 0)))]
801   ""
802   [(set_attr "length" "2")])
804 (define_insn_and_split "*neg_snedi_zero"
805   [(set (match_operand:DI 0 "register_operand" "=&r")
806         (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
807                        (const_int 0))))]
808   "TARGET_ARCH64"
809   "#"
810   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
811   [(set (match_dup 0) (const_int 0))
812    (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
813                                               (const_int 0))
814                                        (const_int -1)
815                                        (match_dup 0)))]
816   ""
817   [(set_attr "length" "2")])
819 (define_insn_and_split "*snedi_zero_trunc"
820   [(set (match_operand:SI 0 "register_operand" "=&r")
821         (ne:SI (match_operand:DI 1 "register_operand" "r")
822                (const_int 0)))]
823   "TARGET_ARCH64 && ! TARGET_VIS3"
824   "#"
825   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
826   [(set (match_dup 0) (const_int 0))
827    (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
828                                               (const_int 0))
829                                        (const_int 1)
830                                        (match_dup 0)))]
831   ""
832   [(set_attr "length" "2")])
834 (define_insn_and_split "*snedi_zero_trunc_vis3"
835   [(set (match_operand:SI 0 "register_operand" "=r")
836         (ne:SI (match_operand:DI 1 "register_operand" "r")
837                (const_int 0)))
838    (clobber (reg:CCX CC_REG))]
839   "TARGET_ARCH64 && TARGET_VIS3"
840   "#"
841   ""
842   [(set (reg:CCX_NOOV CC_REG) (compare:CCX_NOOV (neg:DI (match_dup 1))
843                                                 (const_int 0)))
844    (set (match_dup 0) (ltu:SI (reg:CCX CC_REG) (const_int 0)))]
845   ""
846   [(set_attr "length" "2")])
848 (define_insn_and_split "*seqsi_zero"
849   [(set (match_operand:SI 0 "register_operand" "=r")
850         (eq:SI (match_operand:SI 1 "register_operand" "r")
851                (const_int 0)))
852    (clobber (reg:CC CC_REG))]
853   ""
854   "#"
855   ""
856   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
857                                            (const_int 0)))
858    (set (match_dup 0) (geu:SI (reg:CC CC_REG) (const_int 0)))]
859   ""
860   [(set_attr "length" "2")])
862 (define_insn_and_split "*neg_seqsi_zero"
863   [(set (match_operand:SI 0 "register_operand" "=r")
864         (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
865                        (const_int 0))))
866    (clobber (reg:CC CC_REG))]
867   ""
868   "#"
869   ""
870   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
871                                            (const_int 0)))
872    (set (match_dup 0) (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0))))]
873   ""
874   [(set_attr "length" "2")])
876 (define_insn_and_split "*seqsi_zero_extend"
877   [(set (match_operand:DI 0 "register_operand" "=r")
878         (eq:DI (match_operand:SI 1 "register_operand" "r")
879                (const_int 0)))
880    (clobber (reg:CC CC_REG))]
881   "TARGET_ARCH64"
882   "#"
883   "&& 1"
884   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (minus:SI (const_int 0)
885                                                      (match_dup 1))
886                                            (const_int 0)))
887    (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
888                                                           (const_int -1))
889                                                 (ltu:SI (reg:CC_NOOV CC_REG)
890                                                         (const_int 0)))))]
891   ""
892   [(set_attr "length" "2")])
894 (define_insn_and_split "*neg_seqsi_sign_extend"
895   [(set (match_operand:DI 0 "register_operand" "=r")
896         (neg:DI (eq:DI (match_operand:SI 1 "register_operand" "r")
897                        (const_int 0))))
898    (clobber (reg:CC CC_REG))]
899   "TARGET_ARCH64"
900   "#"
901   "&& 1"
902   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
903                                            (const_int 0)))
904    (set (match_dup 0) (sign_extend:DI (neg:SI (geu:SI (reg:CC CC_REG)
905                                                       (const_int 0)))))]
906   ""
907   [(set_attr "length" "2")])
909 (define_insn_and_split "*seqdi_zero"
910   [(set (match_operand:DI 0 "register_operand" "=&r")
911         (eq:DI (match_operand:DI 1 "register_operand" "r")
912                (const_int 0)))]
913   "TARGET_ARCH64"
914   "#"
915   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
916   [(set (match_dup 0) (const_int 0))
917    (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
918                                               (const_int 0))
919                                        (const_int 1)
920                                        (match_dup 0)))]
921   ""
922   [(set_attr "length" "2")])
924 (define_insn_and_split "*neg_seqdi_zero"
925   [(set (match_operand:DI 0 "register_operand" "=&r")
926         (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
927                        (const_int 0))))]
928   "TARGET_ARCH64"
929   "#"
930   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
931   [(set (match_dup 0) (const_int 0))
932    (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
933                                               (const_int 0))
934                                        (const_int -1)
935                                        (match_dup 0)))]
936   ""
937   [(set_attr "length" "2")]) 
939 (define_insn_and_split "*seqdi_zero_trunc"
940   [(set (match_operand:SI 0 "register_operand" "=&r")
941         (eq:SI (match_operand:DI 1 "register_operand" "r")
942                (const_int 0)))]
943   "TARGET_ARCH64"
944   "#"
945   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
946   [(set (match_dup 0) (const_int 0))
947    (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
948                                               (const_int 0))
949                                        (const_int 1)
950                                        (match_dup 0)))]
951   ""
952   [(set_attr "length" "2")])
954 ;; We can also do (x + (i == 0)) and related, so put them in.
955 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
956 ;; versions for v9.
958 (define_insn_and_split "*x_plus_i_ne_0"
959   [(set (match_operand:SI 0 "register_operand" "=r")
960         (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
961                         (const_int 0))
962                  (match_operand:SI 2 "register_operand" "r")))
963    (clobber (reg:CC CC_REG))]
964   ""
965   "#"
966   ""
967   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
968                                            (const_int 0)))
969    (set (match_dup 0) (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
970                                (match_dup 2)))]
971   ""
972   [(set_attr "length" "2")])
974 (define_insn_and_split "*x_minus_i_ne_0"
975   [(set (match_operand:SI 0 "register_operand" "=r")
976         (minus:SI (match_operand:SI 2 "register_operand" "r")
977                   (ne:SI (match_operand:SI 1 "register_operand" "r")
978                          (const_int 0))))
979    (clobber (reg:CC CC_REG))]
980   ""
981   "#"
982   ""
983   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
984                                            (const_int 0)))
985    (set (match_dup 0) (minus:SI (match_dup 2)
986                                 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
987   ""
988   [(set_attr "length" "2")])
990 (define_insn_and_split "*x_plus_i_eq_0"
991   [(set (match_operand:SI 0 "register_operand" "=r")
992         (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
993                         (const_int 0))
994                  (match_operand:SI 2 "register_operand" "r")))
995    (clobber (reg:CC CC_REG))]
996   ""
997   "#"
998   ""
999   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
1000                                            (const_int 0)))
1001    (set (match_dup 0) (plus:SI (geu:SI (reg:CC CC_REG) (const_int 0))
1002                                (match_dup 2)))]
1003   ""
1004   [(set_attr "length" "2")])
1006 (define_insn_and_split "*x_minus_i_eq_0"
1007   [(set (match_operand:SI 0 "register_operand" "=r")
1008         (minus:SI (match_operand:SI 2 "register_operand" "r")
1009                   (eq:SI (match_operand:SI 1 "register_operand" "r")
1010                          (const_int 0))))
1011    (clobber (reg:CC CC_REG))]
1012   ""
1013   "#"
1014   ""
1015   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
1016                                            (const_int 0)))
1017    (set (match_dup 0) (minus:SI (match_dup 2)
1018                                 (geu:SI (reg:CC CC_REG) (const_int 0))))]
1019   ""
1020   [(set_attr "length" "2")])
1022 ;; We can also do GEU and LTU directly, but these operate after a compare.
1023 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1024 ;; versions for v9.
1026 (define_insn "*sltu_insn"
1027   [(set (match_operand:SI 0 "register_operand" "=r")
1028         (ltu:SI (reg:CC CC_REG) (const_int 0)))]
1029   ""
1030   "addx\t%%g0, 0, %0"
1031   [(set_attr "type" "ialuX")])
1033 (define_insn "*sltu_insn_vis3"
1034   [(set (match_operand:DI 0 "register_operand" "=r")
1035         (ltu:DI (reg:CCX CC_REG) (const_int 0)))]
1036   "TARGET_ARCH64 && TARGET_VIS3"
1037   "addxc\t%%g0, %%g0, %0"
1038   [(set_attr "type" "ialuX")])
1040 (define_insn "*sltu_insn_vis3_trunc"
1041   [(set (match_operand:SI 0 "register_operand" "=r")
1042         (ltu:SI (reg:CCX CC_REG) (const_int 0)))]
1043   "TARGET_ARCH64 && TARGET_VIS3"
1044   "addxc\t%%g0, %%g0, %0"
1045   [(set_attr "type" "ialuX")])
1047 (define_insn "*sltu_extend_sp64"
1048   [(set (match_operand:DI 0 "register_operand" "=r")
1049         (ltu:DI (reg:CC CC_REG) (const_int 0)))]
1050   "TARGET_ARCH64"
1051   "addx\t%%g0, 0, %0"
1052   [(set_attr "type" "ialuX")])
1054 (define_insn "*neg_sltu_insn"
1055   [(set (match_operand:SI 0 "register_operand" "=r")
1056         (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0))))]
1057   ""
1058   "subx\t%%g0, 0, %0"
1059   [(set_attr "type" "ialuX")])
1061 (define_insn "*neg_sltu_extend_sp64"
1062   [(set (match_operand:DI 0 "register_operand" "=r")
1063         (sign_extend:DI (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0)))))]
1064   "TARGET_ARCH64"
1065   "subx\t%%g0, 0, %0"
1066   [(set_attr "type" "ialuX")])
1068 ;; ??? Combine should canonicalize these next two to the same pattern.
1069 (define_insn "*neg_sltu_minus_x"
1070   [(set (match_operand:SI 0 "register_operand" "=r")
1071         (minus:SI (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0)))
1072                   (match_operand:SI 1 "arith_operand" "rI")))]
1073   ""
1074   "subx\t%%g0, %1, %0"
1075   [(set_attr "type" "ialuX")])
1077 (define_insn "*neg_sltu_plus_x"
1078   [(set (match_operand:SI 0 "register_operand" "=r")
1079         (neg:SI (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
1080                          (match_operand:SI 1 "arith_operand" "rI"))))]
1081   ""
1082   "subx\t%%g0, %1, %0"
1083   [(set_attr "type" "ialuX")])
1085 (define_insn "*sgeu_insn"
1086   [(set (match_operand:SI 0 "register_operand" "=r")
1087         (geu:SI (reg:CC CC_REG) (const_int 0)))]
1088   ""
1089   "subx\t%%g0, -1, %0"
1090   [(set_attr "type" "ialuX")])
1092 (define_insn "*sgeu_extend_sp64"
1093   [(set (match_operand:DI 0 "register_operand" "=r")
1094         (geu:DI (reg:CC CC_REG) (const_int 0)))]
1095   "TARGET_ARCH64"
1096   "subx\t%%g0, -1, %0"
1097   [(set_attr "type" "ialuX")])
1099 (define_insn "*neg_sgeu_insn"
1100   [(set (match_operand:SI 0 "register_operand" "=r")
1101         (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0))))]
1102   ""
1103   "addx\t%%g0, -1, %0"
1104   [(set_attr "type" "ialuX")])
1106 (define_insn "*neg_sgeu_extend_sp64"
1107   [(set (match_operand:DI 0 "register_operand" "=r")
1108         (sign_extend:DI (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0)))))]
1109   "TARGET_ARCH64"
1110   "addx\t%%g0, -1, %0"
1111   [(set_attr "type" "ialuX")])
1113 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
1114 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1115 ;; versions for v9.
1117 (define_insn "*sltu_plus_x"
1118   [(set (match_operand:SI 0 "register_operand" "=r")
1119         (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
1120                  (match_operand:SI 1 "arith_operand" "rI")))]
1121   ""
1122   "addx\t%%g0, %1, %0"
1123   [(set_attr "type" "ialuX")])
1125 (define_insn "*sltu_plus_x_plus_y"
1126   [(set (match_operand:SI 0 "register_operand" "=r")
1127         (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
1128                  (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1129                           (match_operand:SI 2 "arith_operand" "rI"))))]
1130   ""
1131   "addx\t%1, %2, %0"
1132   [(set_attr "type" "ialuX")])
1134 (define_insn "*x_minus_sltu"
1135   [(set (match_operand:SI 0 "register_operand" "=r")
1136         (minus:SI (match_operand:SI 1 "register_operand" "r")
1137                   (ltu:SI (reg:CC CC_REG) (const_int 0))))]
1138   ""
1139   "subx\t%1, 0, %0"
1140   [(set_attr "type" "ialuX")])
1142 ;; ??? Combine should canonicalize these next two to the same pattern.
1143 (define_insn "*x_minus_y_minus_sltu"
1144   [(set (match_operand:SI 0 "register_operand" "=r")
1145         (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
1146                             (match_operand:SI 2 "arith_operand" "rI"))
1147                   (ltu:SI (reg:CC CC_REG) (const_int 0))))]
1148   ""
1149   "subx\t%r1, %2, %0"
1150   [(set_attr "type" "ialuX")])
1152 (define_insn "*x_minus_sltu_plus_y"
1153   [(set (match_operand:SI 0 "register_operand" "=r")
1154         (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
1155                   (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
1156                            (match_operand:SI 2 "arith_operand" "rI"))))]
1157   ""
1158   "subx\t%r1, %2, %0"
1159   [(set_attr "type" "ialuX")])
1161 (define_insn "*sgeu_plus_x"
1162   [(set (match_operand:SI 0 "register_operand" "=r")
1163         (plus:SI (geu:SI (reg:CC CC_REG) (const_int 0))
1164                  (match_operand:SI 1 "register_operand" "r")))]
1165   ""
1166   "subx\t%1, -1, %0"
1167   [(set_attr "type" "ialuX")])
1169 (define_insn "*x_minus_sgeu"
1170   [(set (match_operand:SI 0 "register_operand" "=r")
1171         (minus:SI (match_operand:SI 1 "register_operand" "r")
1172                   (geu:SI (reg:CC CC_REG) (const_int 0))))]
1173   ""
1174   "addx\t%1, -1, %0"
1175   [(set_attr "type" "ialuX")])
1177 (define_split
1178   [(set (match_operand:SI 0 "register_operand" "")
1179         (match_operator:SI 2 "noov_compare_operator"
1180                            [(match_operand 1 "icc_or_fcc_register_operand" "")
1181                             (const_int 0)]))]
1182   "TARGET_V9
1183    && REGNO (operands[1]) == SPARC_ICC_REG
1184    && (GET_MODE (operands[1]) == CCXmode
1185        /* 32-bit LTU/GEU are better implemented using addx/subx.  */
1186        || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1187   [(set (match_dup 0) (const_int 0))
1188    (set (match_dup 0)
1189         (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1190                          (const_int 1)
1191                          (match_dup 0)))]
1192   "")
1195 ;; These control RTL generation for conditional jump insns
1197 (define_expand "cbranchcc4"
1198   [(set (pc)
1199         (if_then_else (match_operator 0 "comparison_operator"
1200                           [(match_operand 1 "compare_operand" "")
1201                            (match_operand 2 "const_zero_operand" "")])
1202                       (label_ref (match_operand 3 "" ""))
1203                       (pc)))]
1204   ""
1205   "")
1207 (define_expand "cbranchsi4"
1208   [(use (match_operator 0 "comparison_operator"
1209          [(match_operand:SI 1 "compare_operand" "")
1210           (match_operand:SI 2 "arith_operand" "")]))
1211    (use (match_operand 3 ""))]
1212   ""
1214   if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
1215     operands[1] = force_reg (SImode, operands[1]);
1216   emit_conditional_branch_insn (operands);
1217   DONE;
1220 (define_expand "cbranchdi4"
1221   [(use (match_operator 0 "comparison_operator"
1222          [(match_operand:DI 1 "compare_operand" "")
1223           (match_operand:DI 2 "arith_operand" "")]))
1224    (use (match_operand 3 ""))]
1225   "TARGET_ARCH64"
1227   if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
1228     operands[1] = force_reg (DImode, operands[1]);
1229   emit_conditional_branch_insn (operands);
1230   DONE;
1233 (define_expand "cbranch<F:mode>4"
1234   [(use (match_operator 0 "comparison_operator"
1235          [(match_operand:F 1 "register_operand" "")
1236           (match_operand:F 2 "register_operand" "")]))
1237    (use (match_operand 3 ""))]
1238   "TARGET_FPU"
1239   { emit_conditional_branch_insn (operands); DONE; })
1242 ;; Now match both normal and inverted jump.
1244 ;; XXX fpcmp nop braindamage
1245 (define_insn "*normal_branch"
1246   [(set (pc)
1247         (if_then_else (match_operator 0 "noov_compare_operator"
1248                                       [(reg CC_REG) (const_int 0)])
1249                       (label_ref (match_operand 1 "" ""))
1250                       (pc)))]
1251   ""
1253   return output_cbranch (operands[0], operands[1], 1, 0,
1254                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1255                          insn);
1257   [(set_attr "type" "branch")
1258    (set_attr "branch_type" "icc")])
1260 ;; XXX fpcmp nop braindamage
1261 (define_insn "*inverted_branch"
1262   [(set (pc)
1263         (if_then_else (match_operator 0 "noov_compare_operator"
1264                                       [(reg CC_REG) (const_int 0)])
1265                       (pc)
1266                       (label_ref (match_operand 1 "" ""))))]
1267   ""
1269   return output_cbranch (operands[0], operands[1], 1, 1,
1270                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1271                          insn);
1273   [(set_attr "type" "branch")
1274    (set_attr "branch_type" "icc")])
1276 ;; XXX fpcmp nop braindamage
1277 (define_insn "*normal_fp_branch"
1278   [(set (pc)
1279         (if_then_else (match_operator 1 "comparison_operator"
1280                                       [(match_operand:CCFP 0 "fcc_register_operand" "c")
1281                                        (const_int 0)])
1282                       (label_ref (match_operand 2 "" ""))
1283                       (pc)))]
1284   ""
1286   return output_cbranch (operands[1], operands[2], 2, 0,
1287                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1288                          insn);
1290   [(set_attr "type" "branch")
1291    (set_attr "branch_type" "fcc")])
1293 ;; XXX fpcmp nop braindamage
1294 (define_insn "*inverted_fp_branch"
1295   [(set (pc)
1296         (if_then_else (match_operator 1 "comparison_operator"
1297                                       [(match_operand:CCFP 0 "fcc_register_operand" "c")
1298                                        (const_int 0)])
1299                       (pc)
1300                       (label_ref (match_operand 2 "" ""))))]
1301   ""
1303   return output_cbranch (operands[1], operands[2], 2, 1,
1304                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1305                          insn);
1307   [(set_attr "type" "branch")
1308    (set_attr "branch_type" "fcc")])
1310 ;; XXX fpcmp nop braindamage
1311 (define_insn "*normal_fpe_branch"
1312   [(set (pc)
1313         (if_then_else (match_operator 1 "comparison_operator"
1314                                       [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1315                                        (const_int 0)])
1316                       (label_ref (match_operand 2 "" ""))
1317                       (pc)))]
1318   ""
1320   return output_cbranch (operands[1], operands[2], 2, 0,
1321                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1322                          insn);
1324   [(set_attr "type" "branch")
1325    (set_attr "branch_type" "fcc")])
1327 ;; XXX fpcmp nop braindamage
1328 (define_insn "*inverted_fpe_branch"
1329   [(set (pc)
1330         (if_then_else (match_operator 1 "comparison_operator"
1331                                       [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1332                                        (const_int 0)])
1333                       (pc)
1334                       (label_ref (match_operand 2 "" ""))))]
1335   ""
1337   return output_cbranch (operands[1], operands[2], 2, 1,
1338                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1339                          insn);
1341   [(set_attr "type" "branch")
1342    (set_attr "branch_type" "fcc")])
1344 ;; SPARC V9-specific jump insns.  None of these are guaranteed to be
1345 ;; in the architecture.
1347 (define_insn "*cbcond_sp32"
1348   [(set (pc)
1349         (if_then_else (match_operator 0 "noov_compare_operator"
1350                        [(match_operand:SI 1 "register_operand" "r")
1351                         (match_operand:SI 2 "arith5_operand" "rA")])
1352                       (label_ref (match_operand 3 "" ""))
1353                       (pc)))]
1354   "TARGET_CBCOND"
1356   return output_cbcond (operands[0], operands[3], insn);
1358   [(set_attr "type" "cbcond")])
1360 (define_insn "*cbcond_sp64"
1361   [(set (pc)
1362         (if_then_else (match_operator 0 "noov_compare_operator"
1363                        [(match_operand:DI 1 "register_operand" "r")
1364                         (match_operand:DI 2 "arith5_operand" "rA")])
1365                       (label_ref (match_operand 3 "" ""))
1366                       (pc)))]
1367   "TARGET_ARCH64 && TARGET_CBCOND"
1369   return output_cbcond (operands[0], operands[3], insn);
1371   [(set_attr "type" "cbcond")])
1373 ;; There are no 32 bit brreg insns.
1375 ;; XXX
1376 (define_insn "*normal_int_branch_sp64"
1377   [(set (pc)
1378         (if_then_else (match_operator 0 "v9_register_compare_operator"
1379                                       [(match_operand:DI 1 "register_operand" "r")
1380                                        (const_int 0)])
1381                       (label_ref (match_operand 2 "" ""))
1382                       (pc)))]
1383   "TARGET_ARCH64"
1385   return output_v9branch (operands[0], operands[2], 1, 2, 0,
1386                           final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1387                           insn);
1389   [(set_attr "type" "branch")
1390    (set_attr "branch_type" "reg")])
1392 ;; XXX
1393 (define_insn "*inverted_int_branch_sp64"
1394   [(set (pc)
1395         (if_then_else (match_operator 0 "v9_register_compare_operator"
1396                                       [(match_operand:DI 1 "register_operand" "r")
1397                                        (const_int 0)])
1398                       (pc)
1399                       (label_ref (match_operand 2 "" ""))))]
1400   "TARGET_ARCH64"
1402   return output_v9branch (operands[0], operands[2], 1, 2, 1,
1403                           final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1404                           insn);
1406   [(set_attr "type" "branch")
1407    (set_attr "branch_type" "reg")])
1410 ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic
1411 ;; value subject to a PC-relative relocation.  Operand 2 is a helper function
1412 ;; that adds the PC value at the call point to register #(operand 3).
1414 ;; Even on V9 we use this call sequence with a stub, instead of "rd %pc, ..."
1415 ;; because the RDPC instruction is extremely expensive and incurs a complete
1416 ;; instruction pipeline flush.
1418 (define_insn "load_pcrel_sym<P:mode>"
1419   [(set (match_operand:P 0 "register_operand" "=r")
1420         (unspec:P [(match_operand:P 1 "symbolic_operand" "")
1421                    (match_operand:P 2 "call_address_operand" "")
1422                    (match_operand:P 3 "const_int_operand" "")] UNSPEC_LOAD_PCREL_SYM))
1423    (clobber (reg:P O7_REG))]
1424   "REGNO (operands[0]) == INTVAL (operands[3])"
1426   if (flag_delayed_branch)
1427     return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0";
1428   else
1429     return "sethi\t%%hi(%a1-8), %0\n\tadd\t%0, %%lo(%a1-4), %0\n\tcall\t%a2\n\t nop";
1431   [(set (attr "type") (const_string "multi"))
1432    (set (attr "length")
1433         (if_then_else (eq_attr "delayed_branch" "true")
1434                       (const_int 3)
1435                       (const_int 4)))])
1438 ;; Integer move instructions
1440 (define_expand "movqi"
1441   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1442         (match_operand:QI 1 "general_operand" ""))]
1443   ""
1445   if (sparc_expand_move (QImode, operands))
1446     DONE;
1449 (define_insn "*movqi_insn"
1450   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1451         (match_operand:QI 1 "input_operand"   "rI,m,rJ"))]
1452   "(register_operand (operands[0], QImode)
1453     || register_or_zero_operand (operands[1], QImode))"
1454   "@
1455    mov\t%1, %0
1456    ldub\t%1, %0
1457    stb\t%r1, %0"
1458   [(set_attr "type" "*,load,store")
1459    (set_attr "us3load_type" "*,3cycle,*")])
1461 (define_expand "movhi"
1462   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1463         (match_operand:HI 1 "general_operand" ""))]
1464   ""
1466   if (sparc_expand_move (HImode, operands))
1467     DONE;
1470 (define_insn "*movhi_insn"
1471   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1472         (match_operand:HI 1 "input_operand"   "rI,K,m,rJ"))]
1473   "(register_operand (operands[0], HImode)
1474     || register_or_zero_operand (operands[1], HImode))"
1475   "@
1476    mov\t%1, %0
1477    sethi\t%%hi(%a1), %0
1478    lduh\t%1, %0
1479    sth\t%r1, %0"
1480   [(set_attr "type" "*,*,load,store")
1481    (set_attr "us3load_type" "*,*,3cycle,*")])
1483 ;; We always work with constants here.
1484 (define_insn "*movhi_lo_sum"
1485   [(set (match_operand:HI 0 "register_operand" "=r")
1486         (ior:HI (match_operand:HI 1 "register_operand" "%r")
1487                 (match_operand:HI 2 "small_int_operand" "I")))]
1488   ""
1489   "or\t%1, %2, %0")
1491 (define_expand "movsi"
1492   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1493         (match_operand:SI 1 "general_operand" ""))]
1494   ""
1496   if (sparc_expand_move (SImode, operands))
1497     DONE;
1500 (define_insn "*movsi_insn"
1501   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r, m, r,*f,*f,*f, m,d,d")
1502         (match_operand:SI 1 "input_operand"        "rI,K,m,rJ,*f, r, f, m,*f,J,P"))]
1503   "register_operand (operands[0], SImode)
1504    || register_or_zero_or_all_ones_operand (operands[1], SImode)"
1505   "@
1506    mov\t%1, %0
1507    sethi\t%%hi(%a1), %0
1508    ld\t%1, %0
1509    st\t%r1, %0
1510    movstouw\t%1, %0
1511    movwtos\t%1, %0
1512    fmovs\t%1, %0
1513    ld\t%1, %0
1514    st\t%1, %0
1515    fzeros\t%0
1516    fones\t%0"
1517   [(set_attr "type" "*,*,load,store,vismv,vismv,fpmove,fpload,fpstore,visl,visl")
1518    (set_attr "cpu_feature" "*,*,*,*,vis3,vis3,*,*,*,vis,vis")])
1520 (define_insn "*movsi_lo_sum"
1521   [(set (match_operand:SI 0 "register_operand" "=r")
1522         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1523                    (match_operand:SI 2 "immediate_operand" "in")))]
1524   ""
1525   "or\t%1, %%lo(%a2), %0")
1527 (define_insn "*movsi_high"
1528   [(set (match_operand:SI 0 "register_operand" "=r")
1529         (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1530   ""
1531   "sethi\t%%hi(%a1), %0")
1533 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1534 ;; so that CSE won't optimize the address computation away.
1535 (define_insn "movsi_lo_sum_pic"
1536   [(set (match_operand:SI 0 "register_operand" "=r")
1537         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1538                    (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1539   "flag_pic"
1541 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1542   return "xor\t%1, %%gdop_lox10(%a2), %0";
1543 #else
1544   return "or\t%1, %%lo(%a2), %0";
1545 #endif
1548 (define_insn "movsi_high_pic"
1549   [(set (match_operand:SI 0 "register_operand" "=r")
1550         (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1551   "flag_pic && check_pic (1)"
1553 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1554   return "sethi\t%%gdop_hix22(%a1), %0";
1555 #else
1556   return "sethi\t%%hi(%a1), %0";
1557 #endif
1560 (define_insn "movsi_pic_gotdata_op"
1561   [(set (match_operand:SI 0 "register_operand" "=r")
1562         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
1563                     (match_operand:SI 2 "register_operand" "r")
1564                     (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
1565   "flag_pic && check_pic (1)"
1567 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1568   return "ld\t[%1 + %2], %0, %%gdop(%a3)";
1569 #else
1570   return "ld\t[%1 + %2], %0";
1571 #endif
1573   [(set_attr "type" "load")])
1575 (define_expand "movsi_pic_label_ref"
1576   [(set (match_dup 3) (high:SI
1577      (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1578                  (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1579    (set (match_dup 4) (lo_sum:SI (match_dup 3)
1580      (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1581    (set (match_operand:SI 0 "register_operand" "=r")
1582         (minus:SI (match_dup 5) (match_dup 4)))]
1583   "flag_pic"
1585   crtl->uses_pic_offset_table = 1;
1586   operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1587   if (!can_create_pseudo_p ())
1588     {
1589       operands[3] = operands[0];
1590       operands[4] = operands[0];
1591     }
1592   else
1593     {
1594       operands[3] = gen_reg_rtx (SImode);
1595       operands[4] = gen_reg_rtx (SImode);
1596     }
1597   operands[5] = pic_offset_table_rtx;
1600 (define_insn "*movsi_high_pic_label_ref"
1601   [(set (match_operand:SI 0 "register_operand" "=r")
1602       (high:SI
1603         (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1604                     (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1605   "flag_pic"
1606   "sethi\t%%hi(%a2-(%a1-.)), %0")
1608 (define_insn "*movsi_lo_sum_pic_label_ref"
1609   [(set (match_operand:SI 0 "register_operand" "=r")
1610       (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1611         (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
1612                     (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1613   "flag_pic"
1614   "or\t%1, %%lo(%a3-(%a2-.)), %0")
1616 ;; Set up the PIC register for VxWorks.
1618 (define_expand "vxworks_load_got"
1619   [(set (match_dup 0)
1620         (high:SI (match_dup 1)))
1621    (set (match_dup 0)
1622         (mem:SI (lo_sum:SI (match_dup 0) (match_dup 1))))
1623    (set (match_dup 0)
1624         (mem:SI (lo_sum:SI (match_dup 0) (match_dup 2))))]
1625   "TARGET_VXWORKS_RTP"
1627   operands[0] = pic_offset_table_rtx;
1628   operands[1] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_BASE);
1629   operands[2] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_INDEX);
1632 (define_expand "movdi"
1633   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1634         (match_operand:DI 1 "general_operand" ""))]
1635   ""
1637   if (sparc_expand_move (DImode, operands))
1638     DONE;
1641 ;; Be careful, fmovd does not exist when !v9.
1642 ;; We match MEM moves directly when we have correct even
1643 ;; numbered registers, but fall into splits otherwise.
1644 ;; The constraint ordering here is really important to
1645 ;; avoid insane problems in reload, especially for patterns
1646 ;; of the form:
1648 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
1649 ;;                       (const_int -5016)))
1650 ;;      (reg:DI 2 %g2))
1653 (define_insn "*movdi_insn_sp32"
1654   [(set (match_operand:DI 0 "nonimmediate_operand"
1655                                         "=T,o,T,U,o,r,r,r,?T,?*f,?*f,?o,?*e,?*e,  r,?*f,?*e,?W,b,b")
1656         (match_operand:DI 1 "input_operand"
1657                                         " J,J,U,T,r,o,i,r,*f,  T,  o,*f, *e, *e,?*f,  r,  W,*e,J,P"))]
1658   "! TARGET_ARCH64
1659    && (register_operand (operands[0], DImode)
1660        || register_or_zero_operand (operands[1], DImode))"
1661   "@
1662    stx\t%%g0, %0
1663    #
1664    std\t%1, %0
1665    ldd\t%1, %0
1666    #
1667    #
1668    #
1669    #
1670    std\t%1, %0
1671    ldd\t%1, %0
1672    #
1673    #
1674    fmovd\t%1, %0
1675    #
1676    #
1677    #
1678    ldd\t%1, %0
1679    std\t%1, %0
1680    fzero\t%0
1681    fone\t%0"
1682   [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,*,*,*,fpload,fpstore,visl,visl")
1683    (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,2,2,2,*,*,*,*")
1684    (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*,*,*,*,double,double")
1685    (set_attr "cpu_feature" "v9,*,*,*,*,*,*,*,fpu,fpu,fpu,fpu,v9,fpunotv9,vis3,vis3,fpu,fpu,vis,vis")])
1687 (define_insn "*movdi_insn_sp64"
1688   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r, m, r,*e,?*e,?*e,?W,b,b")
1689         (match_operand:DI 1 "input_operand"        "rI,N,m,rJ,*e, r, *e,  W,*e,J,P"))]
1690   "TARGET_ARCH64
1691    && (register_operand (operands[0], DImode)
1692        || register_or_zero_or_all_ones_operand (operands[1], DImode))"
1693   "@
1694    mov\t%1, %0
1695    sethi\t%%hi(%a1), %0
1696    ldx\t%1, %0
1697    stx\t%r1, %0
1698    movdtox\t%1, %0
1699    movxtod\t%1, %0
1700    fmovd\t%1, %0
1701    ldd\t%1, %0
1702    std\t%1, %0
1703    fzero\t%0
1704    fone\t%0"
1705   [(set_attr "type" "*,*,load,store,vismv,vismv,fpmove,fpload,fpstore,visl,visl")
1706    (set_attr "fptype" "*,*,*,*,*,*,double,*,*,double,double")
1707    (set_attr "cpu_feature" "*,*,*,*,vis3,vis3,*,*,*,vis,vis")])
1709 (define_expand "movdi_pic_label_ref"
1710   [(set (match_dup 3) (high:DI
1711      (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1712                  (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1713    (set (match_dup 4) (lo_sum:DI (match_dup 3)
1714      (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1715    (set (match_operand:DI 0 "register_operand" "=r")
1716         (minus:DI (match_dup 5) (match_dup 4)))]
1717   "TARGET_ARCH64 && flag_pic"
1719   crtl->uses_pic_offset_table = 1;
1720   operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1721   if (!can_create_pseudo_p ())
1722     {
1723       operands[3] = operands[0];
1724       operands[4] = operands[0];
1725     }
1726   else
1727     {
1728       operands[3] = gen_reg_rtx (DImode);
1729       operands[4] = gen_reg_rtx (DImode);
1730     }
1731   operands[5] = pic_offset_table_rtx;
1734 (define_insn "*movdi_high_pic_label_ref"
1735   [(set (match_operand:DI 0 "register_operand" "=r")
1736         (high:DI
1737           (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1738                       (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1739   "TARGET_ARCH64 && flag_pic"
1740   "sethi\t%%hi(%a2-(%a1-.)), %0")
1742 (define_insn "*movdi_lo_sum_pic_label_ref"
1743   [(set (match_operand:DI 0 "register_operand" "=r")
1744       (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1745         (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
1746                     (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1747   "TARGET_ARCH64 && flag_pic"
1748   "or\t%1, %%lo(%a3-(%a2-.)), %0")
1750 ;; SPARC-v9 code model support insns.  See sparc_emit_set_symbolic_const64
1751 ;; in sparc.c to see what is going on here... PIC stuff comes first.
1753 (define_insn "movdi_lo_sum_pic"
1754   [(set (match_operand:DI 0 "register_operand" "=r")
1755         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1756                    (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1757   "TARGET_ARCH64 && flag_pic"
1759 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1760   return "xor\t%1, %%gdop_lox10(%a2), %0";
1761 #else
1762   return "or\t%1, %%lo(%a2), %0";
1763 #endif
1766 (define_insn "movdi_high_pic"
1767   [(set (match_operand:DI 0 "register_operand" "=r")
1768         (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1769   "TARGET_ARCH64 && flag_pic && check_pic (1)"
1771 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1772   return "sethi\t%%gdop_hix22(%a1), %0";
1773 #else
1774   return "sethi\t%%hi(%a1), %0";
1775 #endif
1778 (define_insn "movdi_pic_gotdata_op"
1779   [(set (match_operand:DI 0 "register_operand" "=r")
1780         (unspec:DI [(match_operand:DI 1 "register_operand" "r")
1781                     (match_operand:DI 2 "register_operand" "r")
1782                     (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
1783   "TARGET_ARCH64 && flag_pic && check_pic (1)"
1785 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1786   return "ldx\t[%1 + %2], %0, %%gdop(%a3)";
1787 #else
1788   return "ldx\t[%1 + %2], %0";
1789 #endif
1791   [(set_attr "type" "load")])
1793 (define_insn "*sethi_di_medlow_embmedany_pic"
1794   [(set (match_operand:DI 0 "register_operand" "=r")
1795         (high:DI (match_operand:DI 1 "medium_pic_operand" "")))]
1796   "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
1797   "sethi\t%%hi(%a1), %0")
1799 (define_insn "*sethi_di_medlow"
1800   [(set (match_operand:DI 0 "register_operand" "=r")
1801         (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
1802   "TARGET_CM_MEDLOW && check_pic (1)"
1803   "sethi\t%%hi(%a1), %0")
1805 (define_insn "*losum_di_medlow"
1806   [(set (match_operand:DI 0 "register_operand" "=r")
1807         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1808                    (match_operand:DI 2 "symbolic_operand" "")))]
1809   "TARGET_CM_MEDLOW"
1810   "or\t%1, %%lo(%a2), %0")
1812 (define_insn "seth44"
1813   [(set (match_operand:DI 0 "register_operand" "=r")
1814         (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
1815   "TARGET_CM_MEDMID"
1816   "sethi\t%%h44(%a1), %0")
1818 (define_insn "setm44"
1819   [(set (match_operand:DI 0 "register_operand" "=r")
1820         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1821                    (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
1822   "TARGET_CM_MEDMID"
1823   "or\t%1, %%m44(%a2), %0")
1825 (define_insn "setl44"
1826   [(set (match_operand:DI 0 "register_operand" "=r")
1827         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1828                    (match_operand:DI 2 "symbolic_operand" "")))]
1829   "TARGET_CM_MEDMID"
1830   "or\t%1, %%l44(%a2), %0")
1832 (define_insn "sethh"
1833   [(set (match_operand:DI 0 "register_operand" "=r")
1834         (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
1835   "TARGET_CM_MEDANY"
1836   "sethi\t%%hh(%a1), %0")
1838 (define_insn "setlm"
1839   [(set (match_operand:DI 0 "register_operand" "=r")
1840         (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
1841   "TARGET_CM_MEDANY"
1842   "sethi\t%%lm(%a1), %0")
1844 (define_insn "sethm"
1845   [(set (match_operand:DI 0 "register_operand" "=r")
1846         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1847                    (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
1848   "TARGET_CM_MEDANY"
1849   "or\t%1, %%hm(%a2), %0")
1851 (define_insn "setlo"
1852   [(set (match_operand:DI 0 "register_operand" "=r")
1853         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1854                    (match_operand:DI 2 "symbolic_operand" "")))]
1855   "TARGET_CM_MEDANY"
1856   "or\t%1, %%lo(%a2), %0")
1858 (define_insn "embmedany_sethi"
1859   [(set (match_operand:DI 0 "register_operand" "=r")
1860         (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
1861   "TARGET_CM_EMBMEDANY && check_pic (1)"
1862   "sethi\t%%hi(%a1), %0")
1864 (define_insn "embmedany_losum"
1865   [(set (match_operand:DI 0 "register_operand" "=r")
1866         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1867                    (match_operand:DI 2 "data_segment_operand" "")))]
1868   "TARGET_CM_EMBMEDANY"
1869   "add\t%1, %%lo(%a2), %0")
1871 (define_insn "embmedany_brsum"
1872   [(set (match_operand:DI 0 "register_operand" "=r")
1873         (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
1874   "TARGET_CM_EMBMEDANY"
1875   "add\t%1, %_, %0")
1877 (define_insn "embmedany_textuhi"
1878   [(set (match_operand:DI 0 "register_operand" "=r")
1879         (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
1880   "TARGET_CM_EMBMEDANY && check_pic (1)"
1881   "sethi\t%%uhi(%a1), %0")
1883 (define_insn "embmedany_texthi"
1884   [(set (match_operand:DI 0 "register_operand" "=r")
1885         (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
1886   "TARGET_CM_EMBMEDANY && check_pic (1)"
1887   "sethi\t%%hi(%a1), %0")
1889 (define_insn "embmedany_textulo"
1890   [(set (match_operand:DI 0 "register_operand" "=r")
1891         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1892                    (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
1893   "TARGET_CM_EMBMEDANY"
1894   "or\t%1, %%ulo(%a2), %0")
1896 (define_insn "embmedany_textlo"
1897   [(set (match_operand:DI 0 "register_operand" "=r")
1898         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1899                    (match_operand:DI 2 "text_segment_operand" "")))]
1900   "TARGET_CM_EMBMEDANY"
1901   "or\t%1, %%lo(%a2), %0")
1903 ;; Now some patterns to help reload out a bit.
1904 (define_expand "reload_indi"
1905   [(parallel [(match_operand:DI 0 "register_operand" "=r")
1906               (match_operand:DI 1 "immediate_operand" "")
1907               (match_operand:TI 2 "register_operand" "=&r")])]
1908   "(TARGET_CM_MEDANY
1909     || TARGET_CM_EMBMEDANY)
1910    && ! flag_pic"
1912   sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1913   DONE;
1916 (define_expand "reload_outdi"
1917   [(parallel [(match_operand:DI 0 "register_operand" "=r")
1918               (match_operand:DI 1 "immediate_operand" "")
1919               (match_operand:TI 2 "register_operand" "=&r")])]
1920   "(TARGET_CM_MEDANY
1921     || TARGET_CM_EMBMEDANY)
1922    && ! flag_pic"
1924   sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1925   DONE;
1928 ;; Split up putting CONSTs and REGs into DI regs when !arch64
1929 (define_split
1930   [(set (match_operand:DI 0 "register_operand" "")
1931         (match_operand:DI 1 "const_int_operand" ""))]
1932   "! TARGET_ARCH64
1933    && ((GET_CODE (operands[0]) == REG
1934         && SPARC_INT_REG_P (REGNO (operands[0])))
1935        || (GET_CODE (operands[0]) == SUBREG
1936            && GET_CODE (SUBREG_REG (operands[0])) == REG
1937            && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))
1938    && reload_completed"
1939   [(clobber (const_int 0))]
1941 #if HOST_BITS_PER_WIDE_INT == 32
1942   emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1943                         (INTVAL (operands[1]) < 0) ?
1944                         constm1_rtx :
1945                         const0_rtx));
1946   emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1947                         operands[1]));
1948 #else
1949   unsigned int low, high;
1951   low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
1952   high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
1953   emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
1955   /* Slick... but this trick loses if this subreg constant part
1956      can be done in one insn.  */
1957   if (low == high
1958       && ! SPARC_SETHI32_P (high)
1959       && ! SPARC_SIMM13_P (high))
1960     emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1961                           gen_highpart (SImode, operands[0])));
1962   else
1963     emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
1964 #endif
1965   DONE;
1968 (define_split
1969   [(set (match_operand:DI 0 "register_operand" "")
1970         (match_operand:DI 1 "const_double_operand" ""))]
1971   "reload_completed
1972    && (! TARGET_V9
1973        || (! TARGET_ARCH64
1974            && ((GET_CODE (operands[0]) == REG
1975                 && SPARC_INT_REG_P (REGNO (operands[0])))
1976                || (GET_CODE (operands[0]) == SUBREG
1977                    && GET_CODE (SUBREG_REG (operands[0])) == REG
1978                    && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))))"
1979   [(clobber (const_int 0))]
1981   emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
1982                         GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
1984   /* Slick... but this trick loses if this subreg constant part
1985      can be done in one insn.  */
1986   if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
1987       && ! SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
1988       && ! SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1])))
1989     {
1990       emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1991                             gen_highpart (SImode, operands[0])));
1992     }
1993   else
1994     {
1995       emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1996                             GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
1997     }
1998   DONE;
2001 (define_split
2002   [(set (match_operand:DI 0 "register_operand" "")
2003         (match_operand:DI 1 "register_operand" ""))]
2004   "reload_completed
2005    && (! TARGET_V9
2006        || (! TARGET_ARCH64
2007            && sparc_split_regreg_legitimate (operands[0],
2008                                              operands[1])))"
2009   [(clobber (const_int 0))]
2011   rtx set_dest = operands[0];
2012   rtx set_src = operands[1];
2013   rtx dest1, dest2;
2014   rtx src1, src2;
2016   dest1 = gen_highpart (SImode, set_dest);
2017   dest2 = gen_lowpart (SImode, set_dest);
2018   src1 = gen_highpart (SImode, set_src);
2019   src2 = gen_lowpart (SImode, set_src);
2021   /* Now emit using the real source and destination we found, swapping
2022      the order if we detect overlap.  */
2023   if (reg_overlap_mentioned_p (dest1, src2))
2024     {
2025       emit_insn (gen_movsi (dest2, src2));
2026       emit_insn (gen_movsi (dest1, src1));
2027     }
2028   else
2029     {
2030       emit_insn (gen_movsi (dest1, src1));
2031       emit_insn (gen_movsi (dest2, src2));
2032     }
2033   DONE;
2036 ;; Now handle the cases of memory moves from/to non-even
2037 ;; DI mode register pairs.
2038 (define_split
2039   [(set (match_operand:DI 0 "register_operand" "")
2040         (match_operand:DI 1 "memory_operand" ""))]
2041   "(! TARGET_ARCH64
2042     && reload_completed
2043     && sparc_splitdi_legitimate (operands[0], operands[1]))"
2044   [(clobber (const_int 0))]
2046   rtx word0 = adjust_address (operands[1], SImode, 0);
2047   rtx word1 = adjust_address (operands[1], SImode, 4);
2048   rtx high_part = gen_highpart (SImode, operands[0]);
2049   rtx low_part = gen_lowpart (SImode, operands[0]);
2051   if (reg_overlap_mentioned_p (high_part, word1))
2052     {
2053       emit_insn (gen_movsi (low_part, word1));
2054       emit_insn (gen_movsi (high_part, word0));
2055     }
2056   else
2057     {
2058       emit_insn (gen_movsi (high_part, word0));
2059       emit_insn (gen_movsi (low_part, word1));
2060     }
2061   DONE;
2064 (define_split
2065   [(set (match_operand:DI 0 "memory_operand" "")
2066         (match_operand:DI 1 "register_operand" ""))]
2067   "(! TARGET_ARCH64
2068     && reload_completed
2069     && sparc_splitdi_legitimate (operands[1], operands[0]))"
2070   [(clobber (const_int 0))]
2072   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
2073                         gen_highpart (SImode, operands[1])));
2074   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
2075                         gen_lowpart (SImode, operands[1])));
2076   DONE;
2079 (define_split
2080   [(set (match_operand:DI 0 "memory_operand" "")
2081         (match_operand:DI 1 "const_zero_operand" ""))]
2082   "reload_completed
2083    && (! TARGET_V9
2084        || (! TARGET_ARCH64
2085            && ! mem_min_alignment (operands[0], 8)))
2086    && offsettable_memref_p (operands[0])"
2087   [(clobber (const_int 0))]
2089   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
2090   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
2091   DONE;
2094 (define_expand "movti"
2095   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2096         (match_operand:TI 1 "general_operand" ""))]
2097   "TARGET_ARCH64"
2099   if (sparc_expand_move (TImode, operands))
2100     DONE;
2103 ;; We need to prevent reload from splitting TImode moves, because it
2104 ;; might decide to overwrite a pointer with the value it points to.
2105 ;; In that case we have to do the loads in the appropriate order so
2106 ;; that the pointer is not destroyed too early.
2108 (define_insn "*movti_insn_sp64"
2109   [(set (match_operand:TI 0 "nonimmediate_operand" "=r , o,?*e,?o,b")
2110         (match_operand:TI 1 "input_operand"        "roJ,rJ, eo, e,J"))]
2111   "TARGET_ARCH64
2112    && ! TARGET_HARD_QUAD
2113    && (register_operand (operands[0], TImode)
2114        || register_or_zero_operand (operands[1], TImode))"
2115   "#"
2116   [(set_attr "length" "2,2,2,2,2")
2117    (set_attr "cpu_feature" "*,*,fpu,fpu,vis")])
2119 (define_insn "*movti_insn_sp64_hq"
2120   [(set (match_operand:TI 0 "nonimmediate_operand" "=r , o,?*e,?*e,?m,b")
2121         (match_operand:TI 1 "input_operand"        "roJ,rJ,  e,  m, e,J"))]
2122   "TARGET_ARCH64
2123    && TARGET_HARD_QUAD
2124    && (register_operand (operands[0], TImode)
2125        || register_or_zero_operand (operands[1], TImode))"
2126   "@
2127   #
2128   #
2129   fmovq\t%1, %0
2130   ldq\t%1, %0
2131   stq\t%1, %0
2132   #"
2133   [(set_attr "type" "*,*,fpmove,fpload,fpstore,*")
2134    (set_attr "length" "2,2,*,*,*,2")])
2136 ;; Now all the splits to handle multi-insn TI mode moves.
2137 (define_split
2138   [(set (match_operand:TI 0 "register_operand" "")
2139         (match_operand:TI 1 "register_operand" ""))]
2140   "reload_completed
2141    && ((TARGET_FPU
2142         && ! TARGET_HARD_QUAD)
2143        || (! fp_register_operand (operands[0], TImode)
2144            && ! fp_register_operand (operands[1], TImode)))"
2145   [(clobber (const_int 0))]
2147   rtx set_dest = operands[0];
2148   rtx set_src = operands[1];
2149   rtx dest1, dest2;
2150   rtx src1, src2;
2152   dest1 = gen_highpart (DImode, set_dest);
2153   dest2 = gen_lowpart (DImode, set_dest);
2154   src1 = gen_highpart (DImode, set_src);
2155   src2 = gen_lowpart (DImode, set_src);
2157   /* Now emit using the real source and destination we found, swapping
2158      the order if we detect overlap.  */
2159   if (reg_overlap_mentioned_p (dest1, src2))
2160     {
2161       emit_insn (gen_movdi (dest2, src2));
2162       emit_insn (gen_movdi (dest1, src1));
2163     }
2164   else
2165     {
2166       emit_insn (gen_movdi (dest1, src1));
2167       emit_insn (gen_movdi (dest2, src2));
2168     }
2169   DONE;
2172 (define_split
2173   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2174         (match_operand:TI 1 "const_zero_operand" ""))]
2175   "reload_completed"
2176   [(clobber (const_int 0))]
2178   rtx set_dest = operands[0];
2179   rtx dest1, dest2;
2181   switch (GET_CODE (set_dest))
2182     {
2183     case REG:
2184       dest1 = gen_highpart (DImode, set_dest);
2185       dest2 = gen_lowpart (DImode, set_dest);
2186       break;
2187     case MEM:
2188       dest1 = adjust_address (set_dest, DImode, 0);
2189       dest2 = adjust_address (set_dest, DImode, 8);
2190       break;
2191     default:
2192       gcc_unreachable ();
2193     }
2195   emit_insn (gen_movdi (dest1, const0_rtx));
2196   emit_insn (gen_movdi (dest2, const0_rtx));
2197   DONE;
2200 (define_split
2201   [(set (match_operand:TI 0 "register_operand" "")
2202         (match_operand:TI 1 "memory_operand" ""))]
2203   "reload_completed
2204    && offsettable_memref_p (operands[1])
2205    && (! TARGET_HARD_QUAD
2206        || ! fp_register_operand (operands[0], TImode))"
2207   [(clobber (const_int 0))]
2209   rtx word0 = adjust_address (operands[1], DImode, 0);
2210   rtx word1 = adjust_address (operands[1], DImode, 8);
2211   rtx set_dest, dest1, dest2;
2213   set_dest = operands[0];
2215   dest1 = gen_highpart (DImode, set_dest);
2216   dest2 = gen_lowpart (DImode, set_dest);
2218   /* Now output, ordering such that we don't clobber any registers
2219      mentioned in the address.  */
2220   if (reg_overlap_mentioned_p (dest1, word1))
2222     {
2223       emit_insn (gen_movdi (dest2, word1));
2224       emit_insn (gen_movdi (dest1, word0));
2225     }
2226   else
2227    {
2228       emit_insn (gen_movdi (dest1, word0));
2229       emit_insn (gen_movdi (dest2, word1));
2230    }
2231   DONE;
2234 (define_split
2235   [(set (match_operand:TI 0 "memory_operand" "")
2236         (match_operand:TI 1 "register_operand" ""))]
2237   "reload_completed
2238    && offsettable_memref_p (operands[0])
2239    && (! TARGET_HARD_QUAD
2240        || ! fp_register_operand (operands[1], TImode))"
2241   [(clobber (const_int 0))]
2243   rtx set_src = operands[1];
2245   emit_insn (gen_movdi (adjust_address (operands[0], DImode, 0),
2246                         gen_highpart (DImode, set_src)));
2247   emit_insn (gen_movdi (adjust_address (operands[0], DImode, 8),
2248                         gen_lowpart (DImode, set_src)));
2249   DONE;
2253 ;; Floating point move instructions
2255 (define_expand "movsf"
2256   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2257         (match_operand:SF 1 "general_operand" ""))]
2258   ""
2260   if (sparc_expand_move (SFmode, operands))
2261     DONE;
2264 (define_insn "*movsf_insn"
2265   [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,f, *r,*r,*r,*r, f,f,*r,m,  m")
2266         (match_operand:SF 1 "input_operand"         "G,C,f,*rR, Q, S, f,*r,m, m,f,*rG"))]
2267   "(register_operand (operands[0], SFmode)
2268     || register_or_zero_or_all_ones_operand (operands[1], SFmode))"
2270   if (GET_CODE (operands[1]) == CONST_DOUBLE
2271       && (which_alternative == 3
2272           || which_alternative == 4
2273           || which_alternative == 5))
2274     {
2275       REAL_VALUE_TYPE r;
2276       long i;
2278       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2279       REAL_VALUE_TO_TARGET_SINGLE (r, i);
2280       operands[1] = GEN_INT (i);
2281     }
2283   switch (which_alternative)
2284     {
2285     case 0:
2286       return "fzeros\t%0";
2287     case 1:
2288       return "fones\t%0";
2289     case 2:
2290       return "fmovs\t%1, %0";
2291     case 3:
2292       return "mov\t%1, %0";
2293     case 4:
2294       return "sethi\t%%hi(%a1), %0";
2295     case 5:
2296       return "#";
2297     case 6:
2298       return "movstouw\t%1, %0";
2299     case 7:
2300       return "movwtos\t%1, %0";
2301     case 8:
2302     case 9:
2303       return "ld\t%1, %0";
2304     case 10:
2305     case 11:
2306       return "st\t%r1, %0";
2307     default:
2308       gcc_unreachable ();
2309     }
2311   [(set_attr "type" "visl,visl,fpmove,*,*,*,vismv,vismv,fpload,load,fpstore,store")
2312    (set_attr "cpu_feature" "vis,vis,fpu,*,*,*,vis3,vis3,fpu,*,fpu,*")])
2314 ;; The following 3 patterns build SFmode constants in integer registers.
2316 (define_insn "*movsf_lo_sum"
2317   [(set (match_operand:SF 0 "register_operand" "=r")
2318         (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
2319                    (match_operand:SF 2 "fp_const_high_losum_operand" "S")))]
2320   ""
2322   REAL_VALUE_TYPE r;
2323   long i;
2325   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
2326   REAL_VALUE_TO_TARGET_SINGLE (r, i);
2327   operands[2] = GEN_INT (i);
2328   return "or\t%1, %%lo(%a2), %0";
2331 (define_insn "*movsf_high"
2332   [(set (match_operand:SF 0 "register_operand" "=r")
2333         (high:SF (match_operand:SF 1 "fp_const_high_losum_operand" "S")))]
2334   ""
2336   REAL_VALUE_TYPE r;
2337   long i;
2339   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2340   REAL_VALUE_TO_TARGET_SINGLE (r, i);
2341   operands[1] = GEN_INT (i);
2342   return "sethi\t%%hi(%1), %0";
2345 (define_split
2346   [(set (match_operand:SF 0 "register_operand" "")
2347         (match_operand:SF 1 "fp_const_high_losum_operand" ""))]
2348   "REG_P (operands[0]) && SPARC_INT_REG_P (REGNO (operands[0]))"
2349   [(set (match_dup 0) (high:SF (match_dup 1)))
2350    (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
2352 (define_expand "movdf"
2353   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2354         (match_operand:DF 1 "general_operand" ""))]
2355   ""
2357   if (sparc_expand_move (DFmode, operands))
2358     DONE;
2361 (define_insn "*movdf_insn_sp32"
2362   [(set (match_operand:DF 0 "nonimmediate_operand" "=b,b,e,e,*r, f,  e,T,W,U,T,  f,  *r,  o,o")
2363         (match_operand:DF 1 "input_operand"         "G,C,e,e, f,*r,W#F,G,e,T,U,o#F,*roF,*rG,f"))]
2364   "! TARGET_ARCH64
2365    && (register_operand (operands[0], DFmode)
2366        || register_or_zero_or_all_ones_operand (operands[1], DFmode))"
2367   "@
2368   fzero\t%0
2369   fone\t%0
2370   fmovd\t%1, %0
2371   #
2372   #
2373   #
2374   ldd\t%1, %0
2375   stx\t%r1, %0
2376   std\t%1, %0
2377   ldd\t%1, %0
2378   std\t%1, %0
2379   #
2380   #
2381   #
2382   #"
2383   [(set_attr "type" "visl,visl,fpmove,*,*,*,fpload,store,fpstore,load,store,*,*,*,*")
2384    (set_attr "length" "*,*,*,2,2,2,*,*,*,*,*,2,2,2,2")
2385    (set_attr "fptype" "double,double,double,*,*,*,*,*,*,*,*,*,*,*,*")
2386    (set_attr "cpu_feature" "vis,vis,v9,fpunotv9,vis3,vis3,fpu,v9,fpu,*,*,fpu,*,*,fpu")])
2388 (define_insn "*movdf_insn_sp64"
2389   [(set (match_operand:DF 0 "nonimmediate_operand" "=b,b,e,*r, e,  e,W, *r,*r,  m,*r")
2390         (match_operand:DF 1 "input_operand"         "G,C,e, e,*r,W#F,e,*rG, m,*rG, F"))]
2391   "TARGET_ARCH64
2392    && (register_operand (operands[0], DFmode)
2393        || register_or_zero_or_all_ones_operand (operands[1], DFmode))"
2394   "@
2395   fzero\t%0
2396   fone\t%0
2397   fmovd\t%1, %0
2398   movdtox\t%1, %0
2399   movxtod\t%1, %0
2400   ldd\t%1, %0
2401   std\t%1, %0
2402   mov\t%r1, %0
2403   ldx\t%1, %0
2404   stx\t%r1, %0
2405   #"
2406   [(set_attr "type" "visl,visl,fpmove,vismv,vismv,load,store,*,load,store,*")
2407    (set_attr "length" "*,*,*,*,*,*,*,*,*,*,2")
2408    (set_attr "fptype" "double,double,double,double,double,*,*,*,*,*,*")
2409    (set_attr "cpu_feature" "vis,vis,fpu,vis3,vis3,fpu,fpu,*,*,*,*")])
2411 ;; This pattern builds DFmode constants in integer registers.
2412 (define_split
2413   [(set (match_operand:DF 0 "register_operand" "")
2414         (match_operand:DF 1 "const_double_operand" ""))]
2415   "REG_P (operands[0])
2416    && SPARC_INT_REG_P (REGNO (operands[0]))
2417    && ! const_zero_operand (operands[1], GET_MODE (operands[0]))
2418    && reload_completed"
2419   [(clobber (const_int 0))]
2421   operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
2423   if (TARGET_ARCH64)
2424     {
2425 #if HOST_BITS_PER_WIDE_INT == 32
2426       gcc_unreachable ();
2427 #else
2428       enum machine_mode mode = GET_MODE (operands[1]);
2429       rtx tem = simplify_subreg (DImode, operands[1], mode, 0);
2430       emit_insn (gen_movdi (operands[0], tem));
2431 #endif
2432     }
2433   else
2434     {
2435       enum machine_mode mode = GET_MODE (operands[1]);
2436       rtx hi = simplify_subreg (SImode, operands[1], mode, 0);
2437       rtx lo = simplify_subreg (SImode, operands[1], mode, 4);
2439       gcc_assert (GET_CODE (hi) == CONST_INT);
2440       gcc_assert (GET_CODE (lo) == CONST_INT);
2442       emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), hi));
2444       /* Slick... but this trick loses if this subreg constant part
2445          can be done in one insn.  */
2446       if (lo == hi
2447           && ! SPARC_SETHI32_P (INTVAL (hi))
2448           && ! SPARC_SIMM13_P (INTVAL (hi)))
2449         {
2450           emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2451                                 gen_highpart (SImode, operands[0])));
2452         }
2453       else
2454         {
2455           emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), lo));
2456         }
2457     }
2458   DONE;
2461 ;; Ok, now the splits to handle all the multi insn and
2462 ;; mis-aligned memory address cases.
2463 ;; In these splits please take note that we must be
2464 ;; careful when V9 but not ARCH64 because the integer
2465 ;; register DFmode cases must be handled.
2466 (define_split
2467   [(set (match_operand:DF 0 "register_operand" "")
2468         (match_operand:DF 1 "register_operand" ""))]
2469   "(! TARGET_V9
2470     || (! TARGET_ARCH64
2471         && sparc_split_regreg_legitimate (operands[0],
2472                                           operands[1])))
2473    && reload_completed"
2474   [(clobber (const_int 0))]
2476   rtx set_dest = operands[0];
2477   rtx set_src = operands[1];
2478   rtx dest1, dest2;
2479   rtx src1, src2;
2481   dest1 = gen_highpart (SFmode, set_dest);
2482   dest2 = gen_lowpart (SFmode, set_dest);
2483   src1 = gen_highpart (SFmode, set_src);
2484   src2 = gen_lowpart (SFmode, set_src);
2486   /* Now emit using the real source and destination we found, swapping
2487      the order if we detect overlap.  */
2488   if (reg_overlap_mentioned_p (dest1, src2))
2489     {
2490       emit_move_insn_1 (dest2, src2);
2491       emit_move_insn_1 (dest1, src1);
2492     }
2493   else
2494     {
2495       emit_move_insn_1 (dest1, src1);
2496       emit_move_insn_1 (dest2, src2);
2497     }
2498   DONE;
2501 (define_split
2502   [(set (match_operand:DF 0 "register_operand" "")
2503         (match_operand:DF 1 "memory_operand" ""))]
2504   "reload_completed
2505    && ! TARGET_ARCH64
2506    && (((REGNO (operands[0]) % 2) != 0)
2507        || ! mem_min_alignment (operands[1], 8))
2508    && offsettable_memref_p (operands[1])"
2509   [(clobber (const_int 0))]
2511   rtx word0, word1;
2513   word0 = adjust_address (operands[1], SFmode, 0);
2514   word1 = adjust_address (operands[1], SFmode, 4);
2516   if (reg_overlap_mentioned_p (gen_highpart (SFmode, operands[0]), word1))
2517     {
2518       emit_move_insn_1 (gen_lowpart (SFmode, operands[0]), word1);
2519       emit_move_insn_1 (gen_highpart (SFmode, operands[0]), word0);
2520     }
2521   else
2522     {
2523       emit_move_insn_1 (gen_highpart (SFmode, operands[0]), word0);
2524       emit_move_insn_1 (gen_lowpart (SFmode, operands[0]), word1);
2525     }
2526   DONE;
2529 (define_split
2530   [(set (match_operand:DF 0 "memory_operand" "")
2531         (match_operand:DF 1 "register_operand" ""))]
2532   "reload_completed
2533    && ! TARGET_ARCH64
2534    && (((REGNO (operands[1]) % 2) != 0)
2535        || ! mem_min_alignment (operands[0], 8))
2536    && offsettable_memref_p (operands[0])"
2537   [(clobber (const_int 0))]
2539   rtx word0, word1;
2541   word0 = adjust_address (operands[0], SFmode, 0);
2542   word1 = adjust_address (operands[0], SFmode, 4);
2544   emit_move_insn_1 (word0, gen_highpart (SFmode, operands[1]));
2545   emit_move_insn_1 (word1, gen_lowpart (SFmode, operands[1]));
2546   DONE;
2549 (define_split
2550   [(set (match_operand:DF 0 "memory_operand" "")
2551         (match_operand:DF 1 "const_zero_operand" ""))]
2552   "reload_completed
2553    && (! TARGET_V9
2554        || (! TARGET_ARCH64
2555            && ! mem_min_alignment (operands[0], 8)))
2556    && offsettable_memref_p (operands[0])"
2557   [(clobber (const_int 0))]
2559   rtx dest1, dest2;
2561   dest1 = adjust_address (operands[0], SFmode, 0);
2562   dest2 = adjust_address (operands[0], SFmode, 4);
2564   emit_move_insn_1 (dest1, CONST0_RTX (SFmode));
2565   emit_move_insn_1 (dest2, CONST0_RTX (SFmode));
2566   DONE;
2569 (define_split
2570   [(set (match_operand:DF 0 "register_operand" "")
2571         (match_operand:DF 1 "const_zero_operand" ""))]
2572   "reload_completed
2573    && ! TARGET_ARCH64
2574    && ((GET_CODE (operands[0]) == REG
2575         && SPARC_INT_REG_P (REGNO (operands[0])))
2576        || (GET_CODE (operands[0]) == SUBREG
2577            && GET_CODE (SUBREG_REG (operands[0])) == REG
2578            && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
2579   [(clobber (const_int 0))]
2581   rtx set_dest = operands[0];
2582   rtx dest1, dest2;
2584   dest1 = gen_highpart (SFmode, set_dest);
2585   dest2 = gen_lowpart (SFmode, set_dest);
2586   emit_move_insn_1 (dest1, CONST0_RTX (SFmode));
2587   emit_move_insn_1 (dest2, CONST0_RTX (SFmode));
2588   DONE;
2591 (define_expand "movtf"
2592   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2593         (match_operand:TF 1 "general_operand" ""))]
2594   ""
2596   if (sparc_expand_move (TFmode, operands))
2597     DONE;
2600 (define_insn "*movtf_insn_sp32"
2601   [(set (match_operand:TF 0 "nonimmediate_operand" "=b, e,o,  o,U,  r")
2602         (match_operand:TF 1 "input_operand"        " G,oe,e,rGU,o,roG"))]
2603   "! TARGET_ARCH64
2604    && (register_operand (operands[0], TFmode)
2605        || register_or_zero_operand (operands[1], TFmode))"
2606   "#"
2607   [(set_attr "length" "4,4,4,4,4,4")
2608    (set_attr "cpu_feature" "fpu,fpu,fpu,*,*,*")])
2610 (define_insn "*movtf_insn_sp64"
2611   [(set (match_operand:TF 0 "nonimmediate_operand" "=b, e,o, o,  r")
2612         (match_operand:TF 1 "input_operand"         "G,oe,e,rG,roG"))]
2613   "TARGET_ARCH64
2614    && ! TARGET_HARD_QUAD
2615    && (register_operand (operands[0], TFmode)
2616        || register_or_zero_operand (operands[1], TFmode))"
2617   "#"
2618   [(set_attr "length" "2,2,2,2,2")
2619    (set_attr "cpu_feature" "fpu,fpu,fpu,*,*")])
2621 (define_insn "*movtf_insn_sp64_hq"
2622   [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,e,m, o,  r")
2623         (match_operand:TF 1 "input_operand"         "G,e,m,e,rG,roG"))]
2624   "TARGET_ARCH64
2625    && TARGET_HARD_QUAD
2626    && (register_operand (operands[0], TFmode)
2627        || register_or_zero_operand (operands[1], TFmode))"
2628   "@
2629   #
2630   fmovq\t%1, %0
2631   ldq\t%1, %0
2632   stq\t%1, %0
2633   #
2634   #"
2635   [(set_attr "type" "*,fpmove,fpload,fpstore,*,*")
2636    (set_attr "length" "2,*,*,*,2,2")])
2638 ;; Now all the splits to handle multi-insn TF mode moves.
2639 (define_split
2640   [(set (match_operand:TF 0 "register_operand" "")
2641         (match_operand:TF 1 "register_operand" ""))]
2642   "reload_completed
2643    && (! TARGET_ARCH64
2644        || (TARGET_FPU
2645            && ! TARGET_HARD_QUAD)
2646        || (! fp_register_operand (operands[0], TFmode)
2647            && ! fp_register_operand (operands[1], TFmode)))"
2648   [(clobber (const_int 0))]
2650   rtx set_dest = operands[0];
2651   rtx set_src = operands[1];
2652   rtx dest1, dest2;
2653   rtx src1, src2;
2655   dest1 = gen_df_reg (set_dest, 0);
2656   dest2 = gen_df_reg (set_dest, 1);
2657   src1 = gen_df_reg (set_src, 0);
2658   src2 = gen_df_reg (set_src, 1);
2660   /* Now emit using the real source and destination we found, swapping
2661      the order if we detect overlap.  */
2662   if (reg_overlap_mentioned_p (dest1, src2))
2663     {
2664       emit_insn (gen_movdf (dest2, src2));
2665       emit_insn (gen_movdf (dest1, src1));
2666     }
2667   else
2668     {
2669       emit_insn (gen_movdf (dest1, src1));
2670       emit_insn (gen_movdf (dest2, src2));
2671     }
2672   DONE;
2675 (define_split
2676   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2677         (match_operand:TF 1 "const_zero_operand" ""))]
2678   "reload_completed"
2679   [(clobber (const_int 0))]
2681   rtx set_dest = operands[0];
2682   rtx dest1, dest2;
2684   switch (GET_CODE (set_dest))
2685     {
2686     case REG:
2687       dest1 = gen_df_reg (set_dest, 0);
2688       dest2 = gen_df_reg (set_dest, 1);
2689       break;
2690     case MEM:
2691       dest1 = adjust_address (set_dest, DFmode, 0);
2692       dest2 = adjust_address (set_dest, DFmode, 8);
2693       break;
2694     default:
2695       gcc_unreachable ();
2696     }
2698   emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
2699   emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
2700   DONE;
2703 (define_split
2704   [(set (match_operand:TF 0 "register_operand" "")
2705         (match_operand:TF 1 "memory_operand" ""))]
2706   "(reload_completed
2707     && offsettable_memref_p (operands[1])
2708     && (! TARGET_ARCH64
2709         || ! TARGET_HARD_QUAD
2710         || ! fp_register_operand (operands[0], TFmode)))"
2711   [(clobber (const_int 0))]
2713   rtx word0 = adjust_address (operands[1], DFmode, 0);
2714   rtx word1 = adjust_address (operands[1], DFmode, 8);
2715   rtx set_dest, dest1, dest2;
2717   set_dest = operands[0];
2719   dest1 = gen_df_reg (set_dest, 0);
2720   dest2 = gen_df_reg (set_dest, 1);
2722   /* Now output, ordering such that we don't clobber any registers
2723      mentioned in the address.  */
2724   if (reg_overlap_mentioned_p (dest1, word1))
2726     {
2727       emit_insn (gen_movdf (dest2, word1));
2728       emit_insn (gen_movdf (dest1, word0));
2729     }
2730   else
2731    {
2732       emit_insn (gen_movdf (dest1, word0));
2733       emit_insn (gen_movdf (dest2, word1));
2734    }
2735   DONE;
2738 (define_split
2739   [(set (match_operand:TF 0 "memory_operand" "")
2740         (match_operand:TF 1 "register_operand" ""))]
2741   "(reload_completed
2742     && offsettable_memref_p (operands[0])
2743     && (! TARGET_ARCH64
2744         || ! TARGET_HARD_QUAD
2745         || ! fp_register_operand (operands[1], TFmode)))"
2746   [(clobber (const_int 0))]
2748   rtx set_src = operands[1];
2750   emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
2751                         gen_df_reg (set_src, 0)));
2752   emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
2753                         gen_df_reg (set_src, 1)));
2754   DONE;
2758 ;; SPARC-V9 conditional move instructions
2760 ;; We can handle larger constants here for some flavors, but for now we keep
2761 ;; it simple and only allow those constants supported by all flavors.
2762 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
2763 ;; 3 contains the constant if one is present, but we handle either for
2764 ;; generality (sparc.c puts a constant in operand 2).
2766 ;; Our instruction patterns, on the other hand, canonicalize such that
2767 ;; operand 3 must be the set destination.
2769 (define_expand "mov<I:mode>cc"
2770   [(set (match_operand:I 0 "register_operand" "")
2771         (if_then_else:I (match_operand 1 "comparison_operator" "")
2772                         (match_operand:I 2 "arith10_operand" "")
2773                         (match_operand:I 3 "arith10_operand" "")))]
2774   "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2776   if (! sparc_expand_conditional_move (<I:MODE>mode, operands))
2777     FAIL;
2778   DONE;
2781 (define_expand "mov<F:mode>cc"
2782   [(set (match_operand:F 0 "register_operand" "")
2783         (if_then_else:F (match_operand 1 "comparison_operator" "")
2784                         (match_operand:F 2 "register_operand" "")
2785                         (match_operand:F 3 "register_operand" "")))]
2786   "TARGET_V9 && TARGET_FPU"
2788   if (! sparc_expand_conditional_move (<F:MODE>mode, operands))
2789     FAIL;
2790   DONE;
2793 ;; Conditional move define_insns
2795 (define_insn "*mov<I:mode>_cc_v9"
2796   [(set (match_operand:I 0 "register_operand" "=r")
2797         (if_then_else:I (match_operator 1 "comparison_operator"
2798                                [(match_operand 2 "icc_or_fcc_register_operand" "X")
2799                                 (const_int 0)])
2800                         (match_operand:I 3 "arith11_operand" "rL")
2801                         (match_operand:I 4 "register_operand" "0")))]
2802   "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2803   "mov%C1\t%x2, %3, %0"
2804   [(set_attr "type" "cmove")])
2806 (define_insn "*mov<I:mode>_cc_reg_sp64"
2807   [(set (match_operand:I 0 "register_operand" "=r")
2808         (if_then_else:I (match_operator 1 "v9_register_compare_operator"
2809                                 [(match_operand:DI 2 "register_operand" "r")
2810                                  (const_int 0)])
2811                         (match_operand:I 3 "arith10_operand" "rM")
2812                         (match_operand:I 4 "register_operand" "0")))]
2813   "TARGET_ARCH64"
2814   "movr%D1\t%2, %r3, %0"
2815   [(set_attr "type" "cmove")])
2817 (define_insn "*movsf_cc_v9"
2818   [(set (match_operand:SF 0 "register_operand" "=f")
2819         (if_then_else:SF (match_operator 1 "comparison_operator"
2820                                 [(match_operand 2 "icc_or_fcc_register_operand" "X")
2821                                  (const_int 0)])
2822                          (match_operand:SF 3 "register_operand" "f")
2823                          (match_operand:SF 4 "register_operand" "0")))]
2824   "TARGET_V9 && TARGET_FPU"
2825   "fmovs%C1\t%x2, %3, %0"
2826   [(set_attr "type" "fpcmove")])
2828 (define_insn "*movsf_cc_reg_sp64"
2829   [(set (match_operand:SF 0 "register_operand" "=f")
2830         (if_then_else:SF (match_operator 1 "v9_register_compare_operator"
2831                                 [(match_operand:DI 2 "register_operand" "r")
2832                                  (const_int 0)])
2833                          (match_operand:SF 3 "register_operand" "f")
2834                          (match_operand:SF 4 "register_operand" "0")))]
2835   "TARGET_ARCH64 && TARGET_FPU"
2836   "fmovrs%D1\t%2, %3, %0"
2837   [(set_attr "type" "fpcrmove")])
2839 ;; Named because invoked by movtf_cc_v9
2840 (define_insn "movdf_cc_v9"
2841   [(set (match_operand:DF 0 "register_operand" "=e")
2842         (if_then_else:DF (match_operator 1 "comparison_operator"
2843                                 [(match_operand 2 "icc_or_fcc_register_operand" "X")
2844                                  (const_int 0)])
2845                          (match_operand:DF 3 "register_operand" "e")
2846                          (match_operand:DF 4 "register_operand" "0")))]
2847   "TARGET_V9 && TARGET_FPU"
2848   "fmovd%C1\t%x2, %3, %0"
2849   [(set_attr "type" "fpcmove")
2850    (set_attr "fptype" "double")])
2852 ;; Named because invoked by movtf_cc_reg_sp64
2853 (define_insn "movdf_cc_reg_sp64"
2854   [(set (match_operand:DF 0 "register_operand" "=e")
2855         (if_then_else:DF (match_operator 1 "v9_register_compare_operator"
2856                                 [(match_operand:DI 2 "register_operand" "r")
2857                                  (const_int 0)])
2858                          (match_operand:DF 3 "register_operand" "e")
2859                          (match_operand:DF 4 "register_operand" "0")))]
2860   "TARGET_ARCH64 && TARGET_FPU"
2861   "fmovrd%D1\t%2, %3, %0"
2862   [(set_attr "type" "fpcrmove")
2863    (set_attr "fptype" "double")])
2865 (define_insn "*movtf_cc_hq_v9"
2866   [(set (match_operand:TF 0 "register_operand" "=e")
2867         (if_then_else:TF (match_operator 1 "comparison_operator"
2868                                 [(match_operand 2 "icc_or_fcc_register_operand" "X")
2869                                  (const_int 0)])
2870                          (match_operand:TF 3 "register_operand" "e")
2871                          (match_operand:TF 4 "register_operand" "0")))]
2872   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
2873   "fmovq%C1\t%x2, %3, %0"
2874   [(set_attr "type" "fpcmove")])
2876 (define_insn "*movtf_cc_reg_hq_sp64"
2877   [(set (match_operand:TF 0 "register_operand" "=e")
2878         (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2879                                 [(match_operand:DI 2 "register_operand" "r")
2880                                  (const_int 0)])
2881                          (match_operand:TF 3 "register_operand" "e")
2882                          (match_operand:TF 4 "register_operand" "0")))]
2883   "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
2884   "fmovrq%D1\t%2, %3, %0"
2885   [(set_attr "type" "fpcrmove")])
2887 (define_insn_and_split "*movtf_cc_v9"
2888   [(set (match_operand:TF 0 "register_operand" "=e")
2889         (if_then_else:TF (match_operator 1 "comparison_operator"
2890                             [(match_operand 2 "icc_or_fcc_register_operand" "X")
2891                              (const_int 0)])
2892                          (match_operand:TF 3 "register_operand" "e")
2893                          (match_operand:TF 4 "register_operand" "0")))]
2894   "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
2895   "#"
2896   "&& reload_completed"
2897   [(clobber (const_int 0))]
2899   rtx set_dest = operands[0];
2900   rtx set_srca = operands[3];
2901   rtx dest1, dest2;
2902   rtx srca1, srca2;
2904   dest1 = gen_df_reg (set_dest, 0);
2905   dest2 = gen_df_reg (set_dest, 1);
2906   srca1 = gen_df_reg (set_srca, 0);
2907   srca2 = gen_df_reg (set_srca, 1);
2909   if (reg_overlap_mentioned_p (dest1, srca2))
2910     {
2911       emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, dest2));
2912       emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, dest1));
2913     }
2914   else
2915     {
2916       emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, dest1));
2917       emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, dest2));
2918     }
2919   DONE;
2921   [(set_attr "length" "2")])
2923 (define_insn_and_split "*movtf_cc_reg_sp64"
2924   [(set (match_operand:TF 0 "register_operand" "=e")
2925         (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2926                                 [(match_operand:DI 2 "register_operand" "r")
2927                                  (const_int 0)])
2928                          (match_operand:TF 3 "register_operand" "e")
2929                          (match_operand:TF 4 "register_operand" "0")))]
2930   "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
2931   "#"
2932   "&& reload_completed"
2933   [(clobber (const_int 0))]
2935   rtx set_dest = operands[0];
2936   rtx set_srca = operands[3];
2937   rtx dest1, dest2;
2938   rtx srca1, srca2;
2940   dest1 = gen_df_reg (set_dest, 0);
2941   dest2 = gen_df_reg (set_dest, 1);
2942   srca1 = gen_df_reg (set_srca, 0);
2943   srca2 = gen_df_reg (set_srca, 1);
2945   if (reg_overlap_mentioned_p (dest1, srca2))
2946     {
2947       emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, dest2));
2948       emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, dest1));
2949     }
2950   else
2951     {
2952       emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, dest1));
2953       emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, dest2));
2954     }
2955   DONE;
2957   [(set_attr "length" "2")])
2960 ;; Zero-extension instructions
2962 ;; These patterns originally accepted general_operands, however, slightly
2963 ;; better code is generated by only accepting register_operands, and then
2964 ;; letting combine generate the ldu[hb] insns.
2966 (define_expand "zero_extendhisi2"
2967   [(set (match_operand:SI 0 "register_operand" "")
2968         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
2969   ""
2971   rtx temp = gen_reg_rtx (SImode);
2972   rtx shift_16 = GEN_INT (16);
2973   int op1_subbyte = 0;
2975   if (GET_CODE (operand1) == SUBREG)
2976     {
2977       op1_subbyte = SUBREG_BYTE (operand1);
2978       op1_subbyte /= GET_MODE_SIZE (SImode);
2979       op1_subbyte *= GET_MODE_SIZE (SImode);
2980       operand1 = XEXP (operand1, 0);
2981     }
2983   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
2984                           shift_16));
2985   emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
2986   DONE;
2989 (define_insn "*zero_extendhisi2_insn"
2990   [(set (match_operand:SI 0 "register_operand" "=r")
2991         (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2992   ""
2993   "lduh\t%1, %0"
2994   [(set_attr "type" "load")
2995    (set_attr "us3load_type" "3cycle")])
2997 (define_expand "zero_extendqihi2"
2998   [(set (match_operand:HI 0 "register_operand" "")
2999         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
3000   ""
3001   "")
3003 (define_insn "*zero_extendqihi2_insn"
3004   [(set (match_operand:HI 0 "register_operand" "=r,r")
3005         (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
3006   "GET_CODE (operands[1]) != CONST_INT"
3007   "@
3008    and\t%1, 0xff, %0
3009    ldub\t%1, %0"
3010   [(set_attr "type" "*,load")
3011    (set_attr "us3load_type" "*,3cycle")])
3013 (define_expand "zero_extendqisi2"
3014   [(set (match_operand:SI 0 "register_operand" "")
3015         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
3016   ""
3017   "")
3019 (define_insn "*zero_extendqisi2_insn"
3020   [(set (match_operand:SI 0 "register_operand" "=r,r")
3021         (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
3022   "GET_CODE (operands[1]) != CONST_INT"
3023   "@
3024    and\t%1, 0xff, %0
3025    ldub\t%1, %0"
3026   [(set_attr "type" "*,load")
3027    (set_attr "us3load_type" "*,3cycle")])
3029 (define_expand "zero_extendqidi2"
3030   [(set (match_operand:DI 0 "register_operand" "")
3031         (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
3032   "TARGET_ARCH64"
3033   "")
3035 (define_insn "*zero_extendqidi2_insn"
3036   [(set (match_operand:DI 0 "register_operand" "=r,r")
3037         (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
3038   "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
3039   "@
3040    and\t%1, 0xff, %0
3041    ldub\t%1, %0"
3042   [(set_attr "type" "*,load")
3043    (set_attr "us3load_type" "*,3cycle")])
3045 (define_expand "zero_extendhidi2"
3046   [(set (match_operand:DI 0 "register_operand" "")
3047         (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
3048   "TARGET_ARCH64"
3050   rtx temp = gen_reg_rtx (DImode);
3051   rtx shift_48 = GEN_INT (48);
3052   int op1_subbyte = 0;
3054   if (GET_CODE (operand1) == SUBREG)
3055     {
3056       op1_subbyte = SUBREG_BYTE (operand1);
3057       op1_subbyte /= GET_MODE_SIZE (DImode);
3058       op1_subbyte *= GET_MODE_SIZE (DImode);
3059       operand1 = XEXP (operand1, 0);
3060     }
3062   emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3063                           shift_48));
3064   emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
3065   DONE;
3068 (define_insn "*zero_extendhidi2_insn"
3069   [(set (match_operand:DI 0 "register_operand" "=r")
3070         (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3071   "TARGET_ARCH64"
3072   "lduh\t%1, %0"
3073   [(set_attr "type" "load")
3074    (set_attr "us3load_type" "3cycle")])
3076 ;; ??? Write truncdisi pattern using sra?
3078 (define_expand "zero_extendsidi2"
3079   [(set (match_operand:DI 0 "register_operand" "")
3080         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
3081   ""
3082   "")
3084 (define_insn "*zero_extendsidi2_insn_sp64"
3085   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
3086         (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m,*f")))]
3087   "TARGET_ARCH64
3088    && GET_CODE (operands[1]) != CONST_INT"
3089   "@
3090    srl\t%1, 0, %0
3091    lduw\t%1, %0
3092    movstouw\t%1, %0"
3093   [(set_attr "type" "shift,load,*")
3094    (set_attr "cpu_feature" "*,*,vis3")])
3096 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
3097   [(set (match_operand:DI 0 "register_operand" "=r")
3098         (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
3099   "! TARGET_ARCH64"
3100   "#"
3101   "&& reload_completed"
3102   [(set (match_dup 2) (match_dup 3))
3103    (set (match_dup 4) (match_dup 5))]
3105   rtx dest1, dest2;
3107   dest1 = gen_highpart (SImode, operands[0]);
3108   dest2 = gen_lowpart (SImode, operands[0]);
3110   /* Swap the order in case of overlap.  */
3111   if (REGNO (dest1) == REGNO (operands[1]))
3112     {
3113       operands[2] = dest2;
3114       operands[3] = operands[1];
3115       operands[4] = dest1;
3116       operands[5] = const0_rtx;
3117     }
3118   else
3119     {
3120       operands[2] = dest1;
3121       operands[3] = const0_rtx;
3122       operands[4] = dest2;
3123       operands[5] = operands[1];
3124     }
3126   [(set_attr "length" "2")])
3128 ;; Simplify comparisons of extended values.
3130 (define_insn "*cmp_zero_extendqisi2"
3131   [(set (reg:CC CC_REG)
3132         (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
3133                     (const_int 0)))]
3134   ""
3135   "andcc\t%0, 0xff, %%g0"
3136   [(set_attr "type" "compare")])
3138 (define_insn "*cmp_zero_qi"
3139   [(set (reg:CC CC_REG)
3140         (compare:CC (match_operand:QI 0 "register_operand" "r")
3141                     (const_int 0)))]
3142   ""
3143   "andcc\t%0, 0xff, %%g0"
3144   [(set_attr "type" "compare")])
3146 (define_insn "*cmp_zero_extendqisi2_set"
3147   [(set (reg:CC CC_REG)
3148         (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
3149                     (const_int 0)))
3150    (set (match_operand:SI 0 "register_operand" "=r")
3151         (zero_extend:SI (match_dup 1)))]
3152   ""
3153   "andcc\t%1, 0xff, %0"
3154   [(set_attr "type" "compare")])
3156 (define_insn "*cmp_zero_extendqisi2_andcc_set"
3157   [(set (reg:CC CC_REG)
3158         (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
3159                             (const_int 255))
3160                     (const_int 0)))
3161    (set (match_operand:SI 0 "register_operand" "=r")
3162         (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
3163   ""
3164   "andcc\t%1, 0xff, %0"
3165   [(set_attr "type" "compare")])
3167 (define_insn "*cmp_zero_extendqidi2"
3168   [(set (reg:CCX CC_REG)
3169         (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
3170                      (const_int 0)))]
3171   "TARGET_ARCH64"
3172   "andcc\t%0, 0xff, %%g0"
3173   [(set_attr "type" "compare")])
3175 (define_insn "*cmp_zero_qi_sp64"
3176   [(set (reg:CCX CC_REG)
3177         (compare:CCX (match_operand:QI 0 "register_operand" "r")
3178                      (const_int 0)))]
3179   "TARGET_ARCH64"
3180   "andcc\t%0, 0xff, %%g0"
3181   [(set_attr "type" "compare")])
3183 (define_insn "*cmp_zero_extendqidi2_set"
3184   [(set (reg:CCX CC_REG)
3185         (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
3186                      (const_int 0)))
3187    (set (match_operand:DI 0 "register_operand" "=r")
3188         (zero_extend:DI (match_dup 1)))]
3189   "TARGET_ARCH64"
3190   "andcc\t%1, 0xff, %0"
3191   [(set_attr "type" "compare")])
3193 (define_insn "*cmp_zero_extendqidi2_andcc_set"
3194   [(set (reg:CCX CC_REG)
3195         (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
3196                              (const_int 255))
3197                      (const_int 0)))
3198    (set (match_operand:DI 0 "register_operand" "=r")
3199         (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
3200   "TARGET_ARCH64"
3201   "andcc\t%1, 0xff, %0"
3202   [(set_attr "type" "compare")])
3204 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
3206 (define_insn "*cmp_siqi_trunc"
3207   [(set (reg:CC CC_REG)
3208         (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
3209                     (const_int 0)))]
3210   ""
3211   "andcc\t%0, 0xff, %%g0"
3212   [(set_attr "type" "compare")])
3214 (define_insn "*cmp_siqi_trunc_set"
3215   [(set (reg:CC CC_REG)
3216         (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
3217                     (const_int 0)))
3218    (set (match_operand:QI 0 "register_operand" "=r")
3219         (subreg:QI (match_dup 1) 3))]
3220   ""
3221   "andcc\t%1, 0xff, %0"
3222   [(set_attr "type" "compare")])
3224 (define_insn "*cmp_diqi_trunc"
3225   [(set (reg:CC CC_REG)
3226         (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
3227                     (const_int 0)))]
3228   "TARGET_ARCH64"
3229   "andcc\t%0, 0xff, %%g0"
3230   [(set_attr "type" "compare")])
3232 (define_insn "*cmp_diqi_trunc_set"
3233   [(set (reg:CC CC_REG)
3234         (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
3235                     (const_int 0)))
3236    (set (match_operand:QI 0 "register_operand" "=r")
3237         (subreg:QI (match_dup 1) 7))]
3238   "TARGET_ARCH64"
3239   "andcc\t%1, 0xff, %0"
3240   [(set_attr "type" "compare")])
3243 ;; Sign-extension instructions
3245 ;; These patterns originally accepted general_operands, however, slightly
3246 ;; better code is generated by only accepting register_operands, and then
3247 ;; letting combine generate the lds[hb] insns.
3249 (define_expand "extendhisi2"
3250   [(set (match_operand:SI 0 "register_operand" "")
3251         (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
3252   ""
3254   rtx temp = gen_reg_rtx (SImode);
3255   rtx shift_16 = GEN_INT (16);
3256   int op1_subbyte = 0;
3258   if (GET_CODE (operand1) == SUBREG)
3259     {
3260       op1_subbyte = SUBREG_BYTE (operand1);
3261       op1_subbyte /= GET_MODE_SIZE (SImode);
3262       op1_subbyte *= GET_MODE_SIZE (SImode);
3263       operand1 = XEXP (operand1, 0);
3264     }
3266   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3267                           shift_16));
3268   emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
3269   DONE;
3272 (define_insn "*sign_extendhisi2_insn"
3273   [(set (match_operand:SI 0 "register_operand" "=r")
3274         (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3275   ""
3276   "ldsh\t%1, %0"
3277   [(set_attr "type" "sload")
3278    (set_attr "us3load_type" "3cycle")])
3280 (define_expand "extendqihi2"
3281   [(set (match_operand:HI 0 "register_operand" "")
3282         (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
3283   ""
3285   rtx temp = gen_reg_rtx (SImode);
3286   rtx shift_24 = GEN_INT (24);
3287   int op1_subbyte = 0;
3288   int op0_subbyte = 0;
3290   if (GET_CODE (operand1) == SUBREG)
3291     {
3292       op1_subbyte = SUBREG_BYTE (operand1);
3293       op1_subbyte /= GET_MODE_SIZE (SImode);
3294       op1_subbyte *= GET_MODE_SIZE (SImode);
3295       operand1 = XEXP (operand1, 0);
3296     }
3297   if (GET_CODE (operand0) == SUBREG)
3298     {
3299       op0_subbyte = SUBREG_BYTE (operand0);
3300       op0_subbyte /= GET_MODE_SIZE (SImode);
3301       op0_subbyte *= GET_MODE_SIZE (SImode);
3302       operand0 = XEXP (operand0, 0);
3303     }
3304   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3305                           shift_24));
3306   if (GET_MODE (operand0) != SImode)
3307     operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
3308   emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3309   DONE;
3312 (define_insn "*sign_extendqihi2_insn"
3313   [(set (match_operand:HI 0 "register_operand" "=r")
3314         (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3315   ""
3316   "ldsb\t%1, %0"
3317   [(set_attr "type" "sload")
3318    (set_attr "us3load_type" "3cycle")])
3320 (define_expand "extendqisi2"
3321   [(set (match_operand:SI 0 "register_operand" "")
3322         (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
3323   ""
3325   rtx temp = gen_reg_rtx (SImode);
3326   rtx shift_24 = GEN_INT (24);
3327   int op1_subbyte = 0;
3329   if (GET_CODE (operand1) == SUBREG)
3330     {
3331       op1_subbyte = SUBREG_BYTE (operand1);
3332       op1_subbyte /= GET_MODE_SIZE (SImode);
3333       op1_subbyte *= GET_MODE_SIZE (SImode);
3334       operand1 = XEXP (operand1, 0);
3335     }
3337   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3338                           shift_24));
3339   emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3340   DONE;
3343 (define_insn "*sign_extendqisi2_insn"
3344   [(set (match_operand:SI 0 "register_operand" "=r")
3345         (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3346   ""
3347   "ldsb\t%1, %0"
3348   [(set_attr "type" "sload")
3349    (set_attr "us3load_type" "3cycle")])
3351 (define_expand "extendqidi2"
3352   [(set (match_operand:DI 0 "register_operand" "")
3353         (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
3354   "TARGET_ARCH64"
3356   rtx temp = gen_reg_rtx (DImode);
3357   rtx shift_56 = GEN_INT (56);
3358   int op1_subbyte = 0;
3360   if (GET_CODE (operand1) == SUBREG)
3361     {
3362       op1_subbyte = SUBREG_BYTE (operand1);
3363       op1_subbyte /= GET_MODE_SIZE (DImode);
3364       op1_subbyte *= GET_MODE_SIZE (DImode);
3365       operand1 = XEXP (operand1, 0);
3366     }
3368   emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3369                           shift_56));
3370   emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
3371   DONE;
3374 (define_insn "*sign_extendqidi2_insn"
3375   [(set (match_operand:DI 0 "register_operand" "=r")
3376         (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3377   "TARGET_ARCH64"
3378   "ldsb\t%1, %0"
3379   [(set_attr "type" "sload")
3380    (set_attr "us3load_type" "3cycle")])
3382 (define_expand "extendhidi2"
3383   [(set (match_operand:DI 0 "register_operand" "")
3384         (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
3385   "TARGET_ARCH64"
3387   rtx temp = gen_reg_rtx (DImode);
3388   rtx shift_48 = GEN_INT (48);
3389   int op1_subbyte = 0;
3391   if (GET_CODE (operand1) == SUBREG)
3392     {
3393       op1_subbyte = SUBREG_BYTE (operand1);
3394       op1_subbyte /= GET_MODE_SIZE (DImode);
3395       op1_subbyte *= GET_MODE_SIZE (DImode);
3396       operand1 = XEXP (operand1, 0);
3397     }
3399   emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3400                           shift_48));
3401   emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
3402   DONE;
3405 (define_insn "*sign_extendhidi2_insn"
3406   [(set (match_operand:DI 0 "register_operand" "=r")
3407         (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3408   "TARGET_ARCH64"
3409   "ldsh\t%1, %0"
3410   [(set_attr "type" "sload")
3411    (set_attr "us3load_type" "3cycle")])
3413 (define_expand "extendsidi2"
3414   [(set (match_operand:DI 0 "register_operand" "")
3415         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3416   "TARGET_ARCH64"
3417   "")
3419 (define_insn "*sign_extendsidi2_insn"
3420   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
3421         (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m,*f")))]
3422   "TARGET_ARCH64"
3423   "@
3424   sra\t%1, 0, %0
3425   ldsw\t%1, %0
3426   movstosw\t%1, %0"
3427   [(set_attr "type" "shift,sload,*")
3428    (set_attr "us3load_type" "*,3cycle,*")
3429    (set_attr "cpu_feature" "*,*,vis3")])
3432 ;; Special pattern for optimizing bit-field compares.  This is needed
3433 ;; because combine uses this as a canonical form.
3435 (define_insn "*cmp_zero_extract"
3436   [(set (reg:CC CC_REG)
3437         (compare:CC
3438          (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
3439                           (match_operand:SI 1 "small_int_operand" "I")
3440                           (match_operand:SI 2 "small_int_operand" "I"))
3441          (const_int 0)))]
3442   "INTVAL (operands[2]) > 19"
3444   int len = INTVAL (operands[1]);
3445   int pos = 32 - INTVAL (operands[2]) - len;
3446   HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
3447   operands[1] = GEN_INT (mask);
3448   return "andcc\t%0, %1, %%g0";
3450   [(set_attr "type" "compare")])
3452 (define_insn "*cmp_zero_extract_sp64"
3453   [(set (reg:CCX CC_REG)
3454         (compare:CCX
3455          (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
3456                           (match_operand:SI 1 "small_int_operand" "I")
3457                           (match_operand:SI 2 "small_int_operand" "I"))
3458          (const_int 0)))]
3459   "TARGET_ARCH64 && INTVAL (operands[2]) > 51"
3461   int len = INTVAL (operands[1]);
3462   int pos = 64 - INTVAL (operands[2]) - len;
3463   HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
3464   operands[1] = GEN_INT (mask);
3465   return "andcc\t%0, %1, %%g0";
3467   [(set_attr "type" "compare")])
3470 ;; Conversions between float, double and long double.
3472 (define_insn "extendsfdf2"
3473   [(set (match_operand:DF 0 "register_operand" "=e")
3474         (float_extend:DF
3475          (match_operand:SF 1 "register_operand" "f")))]
3476   "TARGET_FPU"
3477   "fstod\t%1, %0"
3478   [(set_attr "type" "fp")
3479    (set_attr "fptype" "double")])
3481 (define_expand "extendsftf2"
3482   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3483         (float_extend:TF
3484          (match_operand:SF 1 "register_operand" "")))]
3485   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3486   "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3488 (define_insn "*extendsftf2_hq"
3489   [(set (match_operand:TF 0 "register_operand" "=e")
3490         (float_extend:TF
3491          (match_operand:SF 1 "register_operand" "f")))]
3492   "TARGET_FPU && TARGET_HARD_QUAD"
3493   "fstoq\t%1, %0"
3494   [(set_attr "type" "fp")])
3496 (define_expand "extenddftf2"
3497   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3498         (float_extend:TF
3499          (match_operand:DF 1 "register_operand" "")))]
3500   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3501   "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3503 (define_insn "*extenddftf2_hq"
3504   [(set (match_operand:TF 0 "register_operand" "=e")
3505         (float_extend:TF
3506          (match_operand:DF 1 "register_operand" "e")))]
3507   "TARGET_FPU && TARGET_HARD_QUAD"
3508   "fdtoq\t%1, %0"
3509   [(set_attr "type" "fp")])
3511 (define_insn "truncdfsf2"
3512   [(set (match_operand:SF 0 "register_operand" "=f")
3513         (float_truncate:SF
3514          (match_operand:DF 1 "register_operand" "e")))]
3515   "TARGET_FPU"
3516   "fdtos\t%1, %0"
3517   [(set_attr "type" "fp")
3518    (set_attr "fptype" "double")])
3520 (define_expand "trunctfsf2"
3521   [(set (match_operand:SF 0 "register_operand" "")
3522         (float_truncate:SF
3523          (match_operand:TF 1 "general_operand" "")))]
3524   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3525   "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3527 (define_insn "*trunctfsf2_hq"
3528   [(set (match_operand:SF 0 "register_operand" "=f")
3529         (float_truncate:SF
3530          (match_operand:TF 1 "register_operand" "e")))]
3531   "TARGET_FPU && TARGET_HARD_QUAD"
3532   "fqtos\t%1, %0"
3533   [(set_attr "type" "fp")])
3535 (define_expand "trunctfdf2"
3536   [(set (match_operand:DF 0 "register_operand" "")
3537         (float_truncate:DF
3538          (match_operand:TF 1 "general_operand" "")))]
3539   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3540   "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3542 (define_insn "*trunctfdf2_hq"
3543   [(set (match_operand:DF 0 "register_operand" "=e")
3544         (float_truncate:DF
3545          (match_operand:TF 1 "register_operand" "e")))]
3546   "TARGET_FPU && TARGET_HARD_QUAD"
3547   "fqtod\t%1, %0"
3548   [(set_attr "type" "fp")])
3551 ;; Conversion between fixed point and floating point.
3553 (define_insn "floatsisf2"
3554   [(set (match_operand:SF 0 "register_operand" "=f")
3555         (float:SF (match_operand:SI 1 "register_operand" "f")))]
3556   "TARGET_FPU"
3557   "fitos\t%1, %0"
3558   [(set_attr "type" "fp")
3559    (set_attr "fptype" "double")])
3561 (define_insn "floatsidf2"
3562   [(set (match_operand:DF 0 "register_operand" "=e")
3563         (float:DF (match_operand:SI 1 "register_operand" "f")))]
3564   "TARGET_FPU"
3565   "fitod\t%1, %0"
3566   [(set_attr "type" "fp")
3567    (set_attr "fptype" "double")])
3569 (define_expand "floatsitf2"
3570   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3571         (float:TF (match_operand:SI 1 "register_operand" "")))]
3572   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3573   "emit_tfmode_cvt (FLOAT, operands); DONE;")
3575 (define_insn "*floatsitf2_hq"
3576   [(set (match_operand:TF 0 "register_operand" "=e")
3577         (float:TF (match_operand:SI 1 "register_operand" "f")))]
3578   "TARGET_FPU && TARGET_HARD_QUAD"
3579   "fitoq\t%1, %0"
3580   [(set_attr "type" "fp")])
3582 (define_expand "floatunssitf2"
3583   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3584         (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
3585   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3586   "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3588 ;; Now the same for 64 bit sources.
3590 (define_insn "floatdisf2"
3591   [(set (match_operand:SF 0 "register_operand" "=f")
3592         (float:SF (match_operand:DI 1 "register_operand" "e")))]
3593   "TARGET_V9 && TARGET_FPU"
3594   "fxtos\t%1, %0"
3595   [(set_attr "type" "fp")
3596    (set_attr "fptype" "double")])
3598 (define_expand "floatunsdisf2"
3599   [(use (match_operand:SF 0 "register_operand" ""))
3600    (use (match_operand:DI 1 "general_operand" ""))]
3601   "TARGET_ARCH64 && TARGET_FPU"
3602   "sparc_emit_floatunsdi (operands, SFmode); DONE;")
3604 (define_insn "floatdidf2"
3605   [(set (match_operand:DF 0 "register_operand" "=e")
3606         (float:DF (match_operand:DI 1 "register_operand" "e")))]
3607   "TARGET_V9 && TARGET_FPU"
3608   "fxtod\t%1, %0"
3609   [(set_attr "type" "fp")
3610    (set_attr "fptype" "double")])
3612 (define_expand "floatunsdidf2"
3613   [(use (match_operand:DF 0 "register_operand" ""))
3614    (use (match_operand:DI 1 "general_operand" ""))]
3615   "TARGET_ARCH64 && TARGET_FPU"
3616   "sparc_emit_floatunsdi (operands, DFmode); DONE;")
3618 (define_expand "floatditf2"
3619   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3620         (float:TF (match_operand:DI 1 "register_operand" "")))]
3621   "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3622   "emit_tfmode_cvt (FLOAT, operands); DONE;")
3624 (define_insn "*floatditf2_hq"
3625   [(set (match_operand:TF 0 "register_operand" "=e")
3626         (float:TF (match_operand:DI 1 "register_operand" "e")))]
3627   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3628   "fxtoq\t%1, %0"
3629   [(set_attr "type" "fp")])
3631 (define_expand "floatunsditf2"
3632   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3633         (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
3634   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3635   "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3637 ;; Convert a float to an actual integer.
3638 ;; Truncation is performed as part of the conversion.
3640 (define_insn "fix_truncsfsi2"
3641   [(set (match_operand:SI 0 "register_operand" "=f")
3642         (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3643   "TARGET_FPU"
3644   "fstoi\t%1, %0"
3645   [(set_attr "type" "fp")
3646    (set_attr "fptype" "double")])
3648 (define_insn "fix_truncdfsi2"
3649   [(set (match_operand:SI 0 "register_operand" "=f")
3650         (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3651   "TARGET_FPU"
3652   "fdtoi\t%1, %0"
3653   [(set_attr "type" "fp")
3654    (set_attr "fptype" "double")])
3656 (define_expand "fix_trunctfsi2"
3657   [(set (match_operand:SI 0 "register_operand" "")
3658         (fix:SI (match_operand:TF 1 "general_operand" "")))]
3659   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3660   "emit_tfmode_cvt (FIX, operands); DONE;")
3662 (define_insn "*fix_trunctfsi2_hq"
3663   [(set (match_operand:SI 0 "register_operand" "=f")
3664         (fix:SI (match_operand:TF 1 "register_operand" "e")))]
3665   "TARGET_FPU && TARGET_HARD_QUAD"
3666   "fqtoi\t%1, %0"
3667   [(set_attr "type" "fp")])
3669 (define_expand "fixuns_trunctfsi2"
3670   [(set (match_operand:SI 0 "register_operand" "")
3671         (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
3672   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3673   "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3675 ;; Now the same, for V9 targets
3677 (define_insn "fix_truncsfdi2"
3678   [(set (match_operand:DI 0 "register_operand" "=e")
3679         (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3680   "TARGET_V9 && TARGET_FPU"
3681   "fstox\t%1, %0"
3682   [(set_attr "type" "fp")
3683    (set_attr "fptype" "double")])
3685 (define_expand "fixuns_truncsfdi2"
3686   [(use (match_operand:DI 0 "register_operand" ""))
3687    (use (match_operand:SF 1 "general_operand" ""))]
3688   "TARGET_ARCH64 && TARGET_FPU"
3689   "sparc_emit_fixunsdi (operands, SFmode); DONE;")
3691 (define_insn "fix_truncdfdi2"
3692   [(set (match_operand:DI 0 "register_operand" "=e")
3693         (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3694   "TARGET_V9 && TARGET_FPU"
3695   "fdtox\t%1, %0"
3696   [(set_attr "type" "fp")
3697    (set_attr "fptype" "double")])
3699 (define_expand "fixuns_truncdfdi2"
3700   [(use (match_operand:DI 0 "register_operand" ""))
3701    (use (match_operand:DF 1 "general_operand" ""))]
3702   "TARGET_ARCH64 && TARGET_FPU"
3703   "sparc_emit_fixunsdi (operands, DFmode); DONE;")
3705 (define_expand "fix_trunctfdi2"
3706   [(set (match_operand:DI 0 "register_operand" "")
3707         (fix:DI (match_operand:TF 1 "general_operand" "")))]
3708   "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3709   "emit_tfmode_cvt (FIX, operands); DONE;")
3711 (define_insn "*fix_trunctfdi2_hq"
3712   [(set (match_operand:DI 0 "register_operand" "=e")
3713         (fix:DI (match_operand:TF 1 "register_operand" "e")))]
3714   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3715   "fqtox\t%1, %0"
3716   [(set_attr "type" "fp")])
3718 (define_expand "fixuns_trunctfdi2"
3719   [(set (match_operand:DI 0 "register_operand" "")
3720         (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
3721   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3722   "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3725 ;; Integer addition/subtraction instructions.
3727 (define_expand "adddi3"
3728   [(set (match_operand:DI 0 "register_operand" "")
3729         (plus:DI (match_operand:DI 1 "register_operand" "")
3730                  (match_operand:DI 2 "arith_double_add_operand" "")))]
3731   ""
3733   if (! TARGET_ARCH64)
3734     {
3735       emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3736                           gen_rtx_SET (VOIDmode, operands[0],
3737                                    gen_rtx_PLUS (DImode, operands[1],
3738                                                  operands[2])),
3739                           gen_rtx_CLOBBER (VOIDmode,
3740                                    gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3741       DONE;
3742     }
3745 (define_insn_and_split "*adddi3_insn_sp32"
3746   [(set (match_operand:DI 0 "register_operand" "=&r")
3747         (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
3748                  (match_operand:DI 2 "arith_double_operand" "rHI")))
3749    (clobber (reg:CC CC_REG))]
3750   "! TARGET_ARCH64"
3751   "#"
3752   "&& reload_completed"
3753   [(parallel [(set (reg:CC_NOOV CC_REG)
3754                    (compare:CC_NOOV (plus:SI (match_dup 4)
3755                                              (match_dup 5))
3756                                     (const_int 0)))
3757               (set (match_dup 3)
3758                    (plus:SI (match_dup 4) (match_dup 5)))])
3759    (set (match_dup 6)
3760         (plus:SI (plus:SI (match_dup 7)
3761                           (match_dup 8))
3762                  (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3764   operands[3] = gen_lowpart (SImode, operands[0]);
3765   operands[4] = gen_lowpart (SImode, operands[1]);
3766   operands[5] = gen_lowpart (SImode, operands[2]);
3767   operands[6] = gen_highpart (SImode, operands[0]);
3768   operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
3769 #if HOST_BITS_PER_WIDE_INT == 32
3770   if (GET_CODE (operands[2]) == CONST_INT)
3771     {
3772       if (INTVAL (operands[2]) < 0)
3773         operands[8] = constm1_rtx;
3774       else
3775         operands[8] = const0_rtx;
3776     }
3777   else
3778 #endif
3779     operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3781   [(set_attr "length" "2")])
3783 ;; LTU here means "carry set"
3784 (define_insn "addx"
3785   [(set (match_operand:SI 0 "register_operand" "=r")
3786         (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3787                           (match_operand:SI 2 "arith_operand" "rI"))
3788                  (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3789   ""
3790   "addx\t%1, %2, %0"
3791   [(set_attr "type" "ialuX")])
3793 (define_insn "addxc"
3794   [(set (match_operand:DI 0 "register_operand" "=r")
3795         (plus:DI (plus:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
3796                           (match_operand:DI 2 "register_or_zero_operand" "rJ"))
3797                  (ltu:DI (reg:CCX_NOOV CC_REG) (const_int 0))))]
3798   "TARGET_ARCH64 && TARGET_VIS3"
3799   "addxc\t%r1, %r2, %0"
3800   [(set_attr "type" "ialuX")])
3802 (define_insn_and_split "*addx_extend_sp32"
3803   [(set (match_operand:DI 0 "register_operand" "=r")
3804         (zero_extend:DI (plus:SI (plus:SI
3805                                   (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3806                                   (match_operand:SI 2 "arith_operand" "rI"))
3807                                  (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3808   "! TARGET_ARCH64"
3809   "#"
3810   "&& reload_completed"
3811   [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
3812                                (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))
3813    (set (match_dup 4) (const_int 0))]
3814   "operands[3] = gen_lowpart (SImode, operands[0]);
3815    operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
3816   [(set_attr "length" "2")])
3818 (define_insn "*addx_extend_sp64"
3819   [(set (match_operand:DI 0 "register_operand" "=r")
3820         (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3821                                           (match_operand:SI 2 "register_or_zero_operand" "rJ"))
3822                                  (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3823   "TARGET_ARCH64"
3824   "addx\t%r1, %r2, %0"
3825   [(set_attr "type" "ialuX")])
3827 (define_insn "*addxc_trunc_sp64_vis3"
3828   [(set (match_operand:SI 0 "register_operand" "=r")
3829         (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3830                           (match_operand:SI 2 "register_or_zero_operand" "rJ"))
3831                  (ltu:SI (reg:CCX_NOOV CC_REG) (const_int 0))))]
3832   "TARGET_ARCH64 && TARGET_VIS3"
3833   "addxc\t%r1, %r2, %0"
3834   [(set_attr "type" "ialuX")])
3836 (define_insn_and_split "*adddi3_extend_sp32"
3837   [(set (match_operand:DI 0 "register_operand" "=r")
3838         (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
3839                  (match_operand:DI 2 "register_operand" "r")))
3840    (clobber (reg:CC CC_REG))]
3841   "! TARGET_ARCH64"
3842   "#"
3843   "&& reload_completed"
3844   [(parallel [(set (reg:CC_NOOV CC_REG)
3845                    (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
3846                                     (const_int 0)))
3847               (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
3848    (set (match_dup 6)
3849         (plus:SI (plus:SI (match_dup 4) (const_int 0))
3850                  (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3851   "operands[3] = gen_lowpart (SImode, operands[2]);
3852    operands[4] = gen_highpart (SImode, operands[2]);
3853    operands[5] = gen_lowpart (SImode, operands[0]);
3854    operands[6] = gen_highpart (SImode, operands[0]);"
3855   [(set_attr "length" "2")])
3857 (define_insn "*adddi3_sp64"
3858   [(set (match_operand:DI 0 "register_operand" "=r,r")
3859         (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
3860                  (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3861   "TARGET_ARCH64"
3862   "@
3863    add\t%1, %2, %0
3864    sub\t%1, -%2, %0")
3866 (define_insn "addsi3"
3867   [(set (match_operand:SI 0 "register_operand" "=r,r")
3868         (plus:SI (match_operand:SI 1 "register_operand" "%r,r")
3869                  (match_operand:SI 2 "arith_add_operand" "rI,O")))]
3870   ""
3871   "@
3872    add\t%1, %2, %0
3873    sub\t%1, -%2, %0"
3874   [(set_attr "type" "*,*")
3875    (set_attr "fptype" "*,*")])
3877 (define_insn "*cmp_cc_plus"
3878   [(set (reg:CC_NOOV CC_REG)
3879         (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
3880                                   (match_operand:SI 1 "arith_operand" "rI"))
3881                          (const_int 0)))]
3882   ""
3883   "addcc\t%0, %1, %%g0"
3884   [(set_attr "type" "compare")])
3886 (define_insn "*cmp_ccx_plus"
3887   [(set (reg:CCX_NOOV CC_REG)
3888         (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_operand" "%r")
3889                                    (match_operand:DI 1 "arith_operand" "rI"))
3890                           (const_int 0)))]
3891   "TARGET_ARCH64"
3892   "addcc\t%0, %1, %%g0"
3893   [(set_attr "type" "compare")])
3895 (define_insn "*cmp_cc_plus_set"
3896   [(set (reg:CC_NOOV CC_REG)
3897         (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3898                                   (match_operand:SI 2 "arith_operand" "rI"))
3899                          (const_int 0)))
3900    (set (match_operand:SI 0 "register_operand" "=r")
3901         (plus:SI (match_dup 1) (match_dup 2)))]
3902   ""
3903   "addcc\t%1, %2, %0"
3904   [(set_attr "type" "compare")])
3906 (define_insn "*cmp_ccx_plus_set"
3907   [(set (reg:CCX_NOOV CC_REG)
3908         (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_operand" "%r")
3909                                    (match_operand:DI 2 "arith_operand" "rI"))
3910                           (const_int 0)))
3911    (set (match_operand:DI 0 "register_operand" "=r")
3912         (plus:DI (match_dup 1) (match_dup 2)))]
3913   "TARGET_ARCH64"
3914   "addcc\t%1, %2, %0"
3915   [(set_attr "type" "compare")])
3917 (define_expand "subdi3"
3918   [(set (match_operand:DI 0 "register_operand" "")
3919         (minus:DI (match_operand:DI 1 "register_operand" "")
3920                   (match_operand:DI 2 "arith_double_add_operand" "")))]
3921   ""
3923   if (! TARGET_ARCH64)
3924     {
3925       emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3926                           gen_rtx_SET (VOIDmode, operands[0],
3927                                    gen_rtx_MINUS (DImode, operands[1],
3928                                                   operands[2])),
3929                           gen_rtx_CLOBBER (VOIDmode,
3930                                    gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3931       DONE;
3932     }
3935 (define_insn_and_split "*subdi3_insn_sp32"
3936   [(set (match_operand:DI 0 "register_operand" "=r")
3937         (minus:DI (match_operand:DI 1 "register_operand" "r")
3938                   (match_operand:DI 2 "arith_double_operand" "rHI")))
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 4)
3945                                               (match_dup 5))
3946                                     (const_int 0)))
3947               (set (match_dup 3)
3948                    (minus:SI (match_dup 4) (match_dup 5)))])
3949    (set (match_dup 6)
3950         (minus:SI (minus:SI (match_dup 7)
3951                             (match_dup 8))
3952                   (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3954   operands[3] = gen_lowpart (SImode, operands[0]);
3955   operands[4] = gen_lowpart (SImode, operands[1]);
3956   operands[5] = gen_lowpart (SImode, operands[2]);
3957   operands[6] = gen_highpart (SImode, operands[0]);
3958   operands[7] = gen_highpart (SImode, operands[1]);
3959 #if HOST_BITS_PER_WIDE_INT == 32
3960   if (GET_CODE (operands[2]) == CONST_INT)
3961     {
3962       if (INTVAL (operands[2]) < 0)
3963         operands[8] = constm1_rtx;
3964       else
3965         operands[8] = const0_rtx;
3966     }
3967   else
3968 #endif
3969     operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3971   [(set_attr "length" "2")])
3973 ;; LTU here means "carry set"
3974 (define_insn "subx"
3975   [(set (match_operand:SI 0 "register_operand" "=r")
3976         (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3977                             (match_operand:SI 2 "arith_operand" "rI"))
3978                   (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3979   ""
3980   "subx\t%r1, %2, %0"
3981   [(set_attr "type" "ialuX")])
3983 (define_insn "*subx_extend_sp64"
3984   [(set (match_operand:DI 0 "register_operand" "=r")
3985         (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3986                                             (match_operand:SI 2 "arith_operand" "rI"))
3987                                   (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3988   "TARGET_ARCH64"
3989   "subx\t%r1, %2, %0"
3990   [(set_attr "type" "ialuX")])
3992 (define_insn_and_split "*subx_extend"
3993   [(set (match_operand:DI 0 "register_operand" "=r")
3994         (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3995                                             (match_operand:SI 2 "arith_operand" "rI"))
3996                                   (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3997   "! TARGET_ARCH64"
3998   "#"
3999   "&& reload_completed"
4000   [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
4001                                 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))
4002    (set (match_dup 4) (const_int 0))]
4003   "operands[3] = gen_lowpart (SImode, operands[0]);
4004    operands[4] = gen_highpart (SImode, operands[0]);"
4005   [(set_attr "length" "2")])
4007 (define_insn_and_split "*subdi3_extend_sp32"
4008   [(set (match_operand:DI 0 "register_operand" "=r")
4009       (minus:DI (match_operand:DI 1 "register_operand" "r")
4010                 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
4011    (clobber (reg:CC CC_REG))]
4012   "! TARGET_ARCH64"
4013   "#"
4014   "&& reload_completed"
4015   [(parallel [(set (reg:CC_NOOV CC_REG)
4016                    (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
4017                                     (const_int 0)))
4018               (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
4019    (set (match_dup 6)
4020         (minus:SI (minus:SI (match_dup 4) (const_int 0))
4021                   (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
4022   "operands[3] = gen_lowpart (SImode, operands[1]);
4023    operands[4] = gen_highpart (SImode, operands[1]);
4024    operands[5] = gen_lowpart (SImode, operands[0]);
4025    operands[6] = gen_highpart (SImode, operands[0]);"
4026   [(set_attr "length" "2")])
4028 (define_insn "*subdi3_sp64"
4029   [(set (match_operand:DI 0 "register_operand" "=r,r")
4030         (minus:DI (match_operand:DI 1 "register_operand" "r,r")
4031                   (match_operand:DI 2 "arith_add_operand" "rI,O")))]
4032   "TARGET_ARCH64"
4033   "@
4034    sub\t%1, %2, %0
4035    add\t%1, -%2, %0")
4037 (define_insn "subsi3"
4038   [(set (match_operand:SI 0 "register_operand" "=r,r")
4039         (minus:SI (match_operand:SI 1 "register_operand" "r,r")
4040                   (match_operand:SI 2 "arith_add_operand" "rI,O")))]
4041   ""
4042   "@
4043    sub\t%1, %2, %0
4044    add\t%1, -%2, %0"
4045   [(set_attr "type" "*,*")
4046    (set_attr "fptype" "*,*")])
4048 (define_insn "*cmp_minus_cc"
4049   [(set (reg:CC_NOOV CC_REG)
4050         (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
4051                                    (match_operand:SI 1 "arith_operand" "rI"))
4052                          (const_int 0)))]
4053   ""
4054   "subcc\t%r0, %1, %%g0"
4055   [(set_attr "type" "compare")])
4057 (define_insn "*cmp_minus_ccx"
4058   [(set (reg:CCX_NOOV CC_REG)
4059         (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
4060                                     (match_operand:DI 1 "arith_operand" "rI"))
4061                           (const_int 0)))]
4062   "TARGET_ARCH64"
4063   "subcc\t%0, %1, %%g0"
4064   [(set_attr "type" "compare")])
4066 (define_insn "cmp_minus_cc_set"
4067   [(set (reg:CC_NOOV CC_REG)
4068         (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4069                                    (match_operand:SI 2 "arith_operand" "rI"))
4070                          (const_int 0)))
4071    (set (match_operand:SI 0 "register_operand" "=r")
4072         (minus:SI (match_dup 1) (match_dup 2)))]
4073   ""
4074   "subcc\t%r1, %2, %0"
4075   [(set_attr "type" "compare")])
4077 (define_insn "*cmp_minus_ccx_set"
4078   [(set (reg:CCX_NOOV CC_REG)
4079         (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
4080                                     (match_operand:DI 2 "arith_operand" "rI"))
4081                           (const_int 0)))
4082    (set (match_operand:DI 0 "register_operand" "=r")
4083         (minus:DI (match_dup 1) (match_dup 2)))]
4084   "TARGET_ARCH64"
4085   "subcc\t%1, %2, %0"
4086   [(set_attr "type" "compare")])
4089 ;; Integer multiply/divide instructions.
4091 ;; The 32-bit multiply/divide instructions are deprecated on v9, but at
4092 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
4094 (define_insn "mulsi3"
4095   [(set (match_operand:SI 0 "register_operand" "=r")
4096         (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4097                  (match_operand:SI 2 "arith_operand" "rI")))]
4098   "TARGET_HARD_MUL"
4099   "smul\t%1, %2, %0"
4100   [(set_attr "type" "imul")])
4102 (define_expand "muldi3"
4103   [(set (match_operand:DI 0 "register_operand" "")
4104         (mult:DI (match_operand:DI 1 "arith_operand" "")
4105                  (match_operand:DI 2 "arith_operand" "")))]
4106   "TARGET_ARCH64 || TARGET_V8PLUS"
4108   if (TARGET_V8PLUS)
4109     {
4110       emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
4111       DONE;
4112     }
4115 (define_insn "*muldi3_sp64"
4116   [(set (match_operand:DI 0 "register_operand" "=r")
4117         (mult:DI (match_operand:DI 1 "arith_operand" "%r")
4118                  (match_operand:DI 2 "arith_operand" "rI")))]
4119   "TARGET_ARCH64"
4120   "mulx\t%1, %2, %0"
4121   [(set_attr "type" "imul")])
4123 ;; V8plus wide multiply.
4124 ;; XXX
4125 (define_insn "muldi3_v8plus"
4126   [(set (match_operand:DI 0 "register_operand" "=r,h")
4127         (mult:DI (match_operand:DI 1 "arith_operand" "%r,0")
4128                  (match_operand:DI 2 "arith_operand" "rI,rI")))
4129    (clobber (match_scratch:SI 3 "=&h,X"))
4130    (clobber (match_scratch:SI 4 "=&h,X"))]
4131   "TARGET_V8PLUS"
4132   "* return output_v8plus_mult (insn, operands, \"mulx\");"
4133   [(set_attr "type" "multi")
4134    (set_attr "length" "9,8")])
4136 (define_insn "*cmp_mul_set"
4137   [(set (reg:CC CC_REG)
4138         (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4139                     (match_operand:SI 2 "arith_operand" "rI"))
4140                     (const_int 0)))
4141    (set (match_operand:SI 0 "register_operand" "=r")
4142         (mult:SI (match_dup 1) (match_dup 2)))]
4143   "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
4144   "smulcc\t%1, %2, %0"
4145   [(set_attr "type" "imul")])
4147 (define_expand "mulsidi3"
4148   [(set (match_operand:DI 0 "register_operand" "")
4149         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4150                  (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
4151   "TARGET_HARD_MUL"
4153   if (CONSTANT_P (operands[2]))
4154     {
4155       if (TARGET_V8PLUS)
4156         emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
4157                                               operands[2]));
4158       else if (TARGET_ARCH32)
4159         emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
4160                                             operands[2]));
4161       else 
4162         emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
4163                                             operands[2]));
4164       DONE;
4165     }
4166   if (TARGET_V8PLUS)
4167     {
4168       emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
4169       DONE;
4170     }
4173 ;; V9 puts the 64-bit product in a 64-bit register.  Only out or global
4174 ;; registers can hold 64-bit values in the V8plus environment.
4175 ;; XXX
4176 (define_insn "mulsidi3_v8plus"
4177   [(set (match_operand:DI 0 "register_operand" "=h,r")
4178         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4179                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4180    (clobber (match_scratch:SI 3 "=X,&h"))]
4181   "TARGET_V8PLUS"
4182   "@
4183    smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4184    smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4185   [(set_attr "type" "multi")
4186    (set_attr "length" "2,3")])
4188 ;; XXX
4189 (define_insn "const_mulsidi3_v8plus"
4190   [(set (match_operand:DI 0 "register_operand" "=h,r")
4191         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4192                  (match_operand:DI 2 "small_int_operand" "I,I")))
4193    (clobber (match_scratch:SI 3 "=X,&h"))]
4194   "TARGET_V8PLUS"
4195   "@
4196    smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4197    smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4198   [(set_attr "type" "multi")
4199    (set_attr "length" "2,3")])
4201 ;; XXX
4202 (define_insn "*mulsidi3_sp32"
4203   [(set (match_operand:DI 0 "register_operand" "=r")
4204         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4205                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4206   "TARGET_HARD_MUL32"
4208   return TARGET_SPARCLET
4209          ? "smuld\t%1, %2, %L0"
4210          : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4212   [(set (attr "type")
4213         (if_then_else (eq_attr "isa" "sparclet")
4214                       (const_string "imul") (const_string "multi")))
4215    (set (attr "length")
4216         (if_then_else (eq_attr "isa" "sparclet")
4217                       (const_int 1) (const_int 2)))])
4219 (define_insn "*mulsidi3_sp64"
4220   [(set (match_operand:DI 0 "register_operand" "=r")
4221         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4222                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4223   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4224   "smul\t%1, %2, %0"
4225   [(set_attr "type" "imul")])
4227 ;; Extra pattern, because sign_extend of a constant isn't valid.
4229 ;; XXX
4230 (define_insn "const_mulsidi3_sp32"
4231   [(set (match_operand:DI 0 "register_operand" "=r")
4232         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4233                  (match_operand:DI 2 "small_int_operand" "I")))]
4234   "TARGET_HARD_MUL32"
4236   return TARGET_SPARCLET
4237          ? "smuld\t%1, %2, %L0"
4238          : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4240   [(set (attr "type")
4241         (if_then_else (eq_attr "isa" "sparclet")
4242                       (const_string "imul") (const_string "multi")))
4243    (set (attr "length")
4244         (if_then_else (eq_attr "isa" "sparclet")
4245                       (const_int 1) (const_int 2)))])
4247 (define_insn "const_mulsidi3_sp64"
4248   [(set (match_operand:DI 0 "register_operand" "=r")
4249         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4250                  (match_operand:DI 2 "small_int_operand" "I")))]
4251   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4252   "smul\t%1, %2, %0"
4253   [(set_attr "type" "imul")])
4255 (define_expand "smulsi3_highpart"
4256   [(set (match_operand:SI 0 "register_operand" "")
4257         (truncate:SI
4258          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4259                                (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
4260                       (const_int 32))))]
4261   "TARGET_HARD_MUL && TARGET_ARCH32"
4263   if (CONSTANT_P (operands[2]))
4264     {
4265       if (TARGET_V8PLUS)
4266         {
4267           emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
4268                                                         operands[1],
4269                                                         operands[2],
4270                                                         GEN_INT (32)));
4271           DONE;
4272         }
4273       emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
4274       DONE;
4275     }
4276   if (TARGET_V8PLUS)
4277     {
4278       emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
4279                                               operands[2], GEN_INT (32)));
4280       DONE;
4281     }
4284 ;; XXX
4285 (define_insn "smulsi3_highpart_v8plus"
4286   [(set (match_operand:SI 0 "register_operand" "=h,r")
4287         (truncate:SI
4288          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4289                                (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4290                       (match_operand:SI 3 "small_int_operand" "I,I"))))
4291    (clobber (match_scratch:SI 4 "=X,&h"))]
4292   "TARGET_V8PLUS"
4293   "@
4294    smul\t%1, %2, %0\;srlx\t%0, %3, %0
4295    smul\t%1, %2, %4\;srlx\t%4, %3, %0"
4296   [(set_attr "type" "multi")
4297    (set_attr "length" "2")])
4299 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
4300 ;; XXX
4301 (define_insn ""
4302   [(set (match_operand:SI 0 "register_operand" "=h,r")
4303         (subreg:SI
4304          (lshiftrt:DI
4305           (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4306                    (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4307           (match_operand:SI 3 "small_int_operand" "I,I"))
4308          4))
4309    (clobber (match_scratch:SI 4 "=X,&h"))]
4310   "TARGET_V8PLUS"
4311   "@
4312    smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4313    smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4314   [(set_attr "type" "multi")
4315    (set_attr "length" "2")])
4317 ;; XXX
4318 (define_insn "const_smulsi3_highpart_v8plus"
4319   [(set (match_operand:SI 0 "register_operand" "=h,r")
4320         (truncate:SI
4321          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4322                                (match_operand:DI 2 "small_int_operand" "I,I"))
4323                       (match_operand:SI 3 "small_int_operand" "I,I"))))
4324    (clobber (match_scratch:SI 4 "=X,&h"))]
4325   "TARGET_V8PLUS"
4326   "@
4327    smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4328    smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4329   [(set_attr "type" "multi")
4330    (set_attr "length" "2")])
4332 ;; XXX
4333 (define_insn "*smulsi3_highpart_sp32"
4334   [(set (match_operand:SI 0 "register_operand" "=r")
4335         (truncate:SI
4336          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4337                                (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
4338                       (const_int 32))))]
4339   "TARGET_HARD_MUL32"
4340   "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4341   [(set_attr "type" "multi")
4342    (set_attr "length" "2")])
4344 ;; XXX
4345 (define_insn "const_smulsi3_highpart"
4346   [(set (match_operand:SI 0 "register_operand" "=r")
4347         (truncate:SI
4348          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4349                                (match_operand:DI 2 "small_int_operand" "i"))
4350                       (const_int 32))))]
4351   "TARGET_HARD_MUL32"
4352   "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4353   [(set_attr "type" "multi")
4354    (set_attr "length" "2")])
4356 (define_expand "umulsidi3"
4357   [(set (match_operand:DI 0 "register_operand" "")
4358         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4359                  (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
4360   "TARGET_HARD_MUL"
4362   if (CONSTANT_P (operands[2]))
4363     {
4364       if (TARGET_V8PLUS)
4365         emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
4366                                                operands[2]));
4367       else if (TARGET_ARCH32)
4368         emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
4369                                              operands[2]));
4370       else 
4371         emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
4372                                              operands[2]));
4373       DONE;
4374     }
4375   if (TARGET_V8PLUS)
4376     {
4377       emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
4378       DONE;
4379     }
4382 ;; XXX
4383 (define_insn "umulsidi3_v8plus"
4384   [(set (match_operand:DI 0 "register_operand" "=h,r")
4385         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4386                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4387    (clobber (match_scratch:SI 3 "=X,&h"))]
4388   "TARGET_V8PLUS"
4389   "@
4390    umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4391    umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4392   [(set_attr "type" "multi")
4393    (set_attr "length" "2,3")])
4395 ;; XXX
4396 (define_insn "*umulsidi3_sp32"
4397   [(set (match_operand:DI 0 "register_operand" "=r")
4398         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4399                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4400   "TARGET_HARD_MUL32"
4402   return TARGET_SPARCLET
4403          ? "umuld\t%1, %2, %L0"
4404          : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
4406   [(set (attr "type")
4407         (if_then_else (eq_attr "isa" "sparclet")
4408                       (const_string "imul") (const_string "multi")))
4409    (set (attr "length")
4410         (if_then_else (eq_attr "isa" "sparclet")
4411                       (const_int 1) (const_int 2)))])
4413 (define_insn "*umulsidi3_sp64"
4414   [(set (match_operand:DI 0 "register_operand" "=r")
4415         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4416                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4417   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4418   "umul\t%1, %2, %0"
4419   [(set_attr "type" "imul")])
4421 ;; Extra pattern, because sign_extend of a constant isn't valid.
4423 ;; XXX
4424 (define_insn "const_umulsidi3_sp32"
4425   [(set (match_operand:DI 0 "register_operand" "=r")
4426         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4427                  (match_operand:DI 2 "uns_small_int_operand" "")))]
4428   "TARGET_HARD_MUL32"
4430   return TARGET_SPARCLET
4431          ? "umuld\t%1, %s2, %L0"
4432          : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
4434   [(set (attr "type")
4435         (if_then_else (eq_attr "isa" "sparclet")
4436                       (const_string "imul") (const_string "multi")))
4437    (set (attr "length")
4438         (if_then_else (eq_attr "isa" "sparclet")
4439                       (const_int 1) (const_int 2)))])
4441 (define_insn "const_umulsidi3_sp64"
4442   [(set (match_operand:DI 0 "register_operand" "=r")
4443         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4444                  (match_operand:DI 2 "uns_small_int_operand" "")))]
4445   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4446   "umul\t%1, %s2, %0"
4447   [(set_attr "type" "imul")])
4449 ;; XXX
4450 (define_insn "const_umulsidi3_v8plus"
4451   [(set (match_operand:DI 0 "register_operand" "=h,r")
4452         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4453                  (match_operand:DI 2 "uns_small_int_operand" "")))
4454    (clobber (match_scratch:SI 3 "=X,h"))]
4455   "TARGET_V8PLUS"
4456   "@
4457    umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
4458    umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4459   [(set_attr "type" "multi")
4460    (set_attr "length" "2,3")])
4462 (define_expand "umulsi3_highpart"
4463   [(set (match_operand:SI 0 "register_operand" "")
4464         (truncate:SI
4465          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4466                                (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
4467                       (const_int 32))))]
4468   "TARGET_HARD_MUL && TARGET_ARCH32"
4470   if (CONSTANT_P (operands[2]))
4471     {
4472       if (TARGET_V8PLUS)
4473         {
4474           emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
4475                                                         operands[1],
4476                                                         operands[2],
4477                                                         GEN_INT (32)));
4478           DONE;
4479         }
4480       emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
4481       DONE;
4482     }
4483   if (TARGET_V8PLUS)
4484     {
4485       emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
4486                                               operands[2], GEN_INT (32)));
4487       DONE;
4488     }
4491 ;; XXX
4492 (define_insn "umulsi3_highpart_v8plus"
4493   [(set (match_operand:SI 0 "register_operand" "=h,r")
4494         (truncate:SI
4495          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4496                                (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4497                       (match_operand:SI 3 "small_int_operand" "I,I"))))
4498    (clobber (match_scratch:SI 4 "=X,h"))]
4499   "TARGET_V8PLUS"
4500   "@
4501    umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4502    umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4503   [(set_attr "type" "multi")
4504    (set_attr "length" "2")])
4506 ;; XXX
4507 (define_insn "const_umulsi3_highpart_v8plus"
4508   [(set (match_operand:SI 0 "register_operand" "=h,r")
4509         (truncate:SI
4510          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4511                                (match_operand:DI 2 "uns_small_int_operand" ""))
4512                       (match_operand:SI 3 "small_int_operand" "I,I"))))
4513    (clobber (match_scratch:SI 4 "=X,h"))]
4514   "TARGET_V8PLUS"
4515   "@
4516    umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
4517    umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
4518   [(set_attr "type" "multi")
4519    (set_attr "length" "2")])
4521 ;; XXX
4522 (define_insn "*umulsi3_highpart_sp32"
4523   [(set (match_operand:SI 0 "register_operand" "=r")
4524         (truncate:SI
4525          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4526                                (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
4527                       (const_int 32))))]
4528   "TARGET_HARD_MUL32"
4529   "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
4530   [(set_attr "type" "multi")
4531    (set_attr "length" "2")])
4533 ;; XXX
4534 (define_insn "const_umulsi3_highpart"
4535   [(set (match_operand:SI 0 "register_operand" "=r")
4536         (truncate:SI
4537          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4538                                (match_operand:DI 2 "uns_small_int_operand" ""))
4539                       (const_int 32))))]
4540   "TARGET_HARD_MUL32"
4541   "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
4542   [(set_attr "type" "multi")
4543    (set_attr "length" "2")])
4545 (define_expand "divsi3"
4546   [(parallel [(set (match_operand:SI 0 "register_operand" "")
4547                    (div:SI (match_operand:SI 1 "register_operand" "")
4548                            (match_operand:SI 2 "input_operand" "")))
4549               (clobber (match_scratch:SI 3 ""))])]
4550   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4552   if (TARGET_ARCH64)
4553     {
4554       operands[3] = gen_reg_rtx(SImode);
4555       emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
4556       emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
4557                                   operands[3]));
4558       DONE;
4559     }
4562 ;; The V8 architecture specifies that there must be at least 3 instructions
4563 ;; between a write to the Y register and a use of it for correct results.
4564 ;; We try to fill one of them with a simple constant or a memory load.
4566 (define_insn "divsi3_sp32"
4567   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
4568         (div:SI (match_operand:SI 1 "register_operand" "r,r,r")
4569                 (match_operand:SI 2 "input_operand" "rI,K,m")))
4570    (clobber (match_scratch:SI 3 "=&r,&r,&r"))]
4571   "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4573   output_asm_insn ("sra\t%1, 31, %3", operands);
4574   output_asm_insn ("wr\t%3, 0, %%y", operands);
4576   switch (which_alternative)
4577     {
4578     case 0:
4579       if (TARGET_V9)
4580         return "sdiv\t%1, %2, %0";
4581       else
4582         return "nop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
4583     case 1:
4584       if (TARGET_V9)
4585         return "sethi\t%%hi(%a2), %3\n\tsdiv\t%1, %3, %0";
4586       else
4587         return "sethi\t%%hi(%a2), %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4588     case 2:
4589       if (TARGET_V9)
4590         return "ld\t%2, %3\n\tsdiv\t%1, %3, %0";
4591       else
4592         return "ld\t%2, %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4593     default:
4594       gcc_unreachable ();
4595     }
4597   [(set_attr "type" "multi")
4598    (set (attr "length")
4599         (if_then_else (eq_attr "isa" "v9")
4600                       (const_int 4) (const_int 6)))])
4602 (define_insn "divsi3_sp64"
4603   [(set (match_operand:SI 0 "register_operand" "=r")
4604         (div:SI (match_operand:SI 1 "register_operand" "r")
4605                 (match_operand:SI 2 "input_operand" "rI")))
4606    (use (match_operand:SI 3 "register_operand" "r"))]
4607   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4608   "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
4609   [(set_attr "type" "multi")
4610    (set_attr "length" "2")])
4612 (define_insn "divdi3"
4613   [(set (match_operand:DI 0 "register_operand" "=r")
4614         (div:DI (match_operand:DI 1 "register_operand" "r")
4615                 (match_operand:DI 2 "arith_operand" "rI")))]
4616   "TARGET_ARCH64"
4617   "sdivx\t%1, %2, %0"
4618   [(set_attr "type" "idiv")])
4620 (define_insn "*cmp_sdiv_cc_set"
4621   [(set (reg:CC CC_REG)
4622         (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
4623                             (match_operand:SI 2 "arith_operand" "rI"))
4624                     (const_int 0)))
4625    (set (match_operand:SI 0 "register_operand" "=r")
4626         (div:SI (match_dup 1) (match_dup 2)))
4627    (clobber (match_scratch:SI 3 "=&r"))]
4628   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4630   output_asm_insn ("sra\t%1, 31, %3", operands);
4631   output_asm_insn ("wr\t%3, 0, %%y", operands);
4633   if (TARGET_V9)
4634     return "sdivcc\t%1, %2, %0";
4635   else
4636     return "nop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
4638   [(set_attr "type" "multi")
4639    (set (attr "length")
4640         (if_then_else (eq_attr "isa" "v9")
4641                       (const_int 3) (const_int 6)))])
4643 ;; XXX
4644 (define_expand "udivsi3"
4645   [(set (match_operand:SI 0 "register_operand" "")
4646         (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "")
4647                  (match_operand:SI 2 "input_operand" "")))]
4648   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4649   "")
4651 ;; The V8 architecture specifies that there must be at least 3 instructions
4652 ;; between a write to the Y register and a use of it for correct results.
4653 ;; We try to fill one of them with a simple constant or a memory load.
4655 (define_insn "udivsi3_sp32"
4656   [(set (match_operand:SI 0 "register_operand" "=r,&r,&r,&r")
4657         (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r,r,r,m")
4658                  (match_operand:SI 2 "input_operand" "rI,K,m,r")))]
4659   "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4661   output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4663   switch (which_alternative)
4664     {
4665     case 0:
4666       if (TARGET_V9)
4667         return "udiv\t%1, %2, %0";
4668       else
4669         return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
4670     case 1:
4671       if (TARGET_V9)
4672         return "sethi\t%%hi(%a2), %0\n\tudiv\t%1, %0, %0";
4673       else
4674         return "sethi\t%%hi(%a2), %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4675     case 2:
4676       if (TARGET_V9)
4677         return "ld\t%2, %0\n\tudiv\t%1, %0, %0";
4678       else
4679         return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4680     case 3:
4681       if (TARGET_V9)
4682         return "ld\t%1, %0\n\tudiv\t%0, %2, %0";
4683       else
4684         return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
4685     default:
4686       gcc_unreachable ();
4687     }
4689   [(set_attr "type" "multi")
4690    (set (attr "length")
4691         (if_then_else (eq_attr "isa" "v9")
4692                       (const_int 3) (const_int 5)))])
4694 (define_insn "udivsi3_sp64"
4695   [(set (match_operand:SI 0 "register_operand" "=r")
4696         (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r")
4697                  (match_operand:SI 2 "input_operand" "rI")))]
4698   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4699   "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
4700   [(set_attr "type" "multi")
4701    (set_attr "length" "2")])
4703 (define_insn "udivdi3"
4704   [(set (match_operand:DI 0 "register_operand" "=r")
4705         (udiv:DI (match_operand:DI 1 "register_operand" "r")
4706                  (match_operand:DI 2 "arith_operand" "rI")))]
4707   "TARGET_ARCH64"
4708   "udivx\t%1, %2, %0"
4709   [(set_attr "type" "idiv")])
4711 (define_insn "*cmp_udiv_cc_set"
4712   [(set (reg:CC CC_REG)
4713         (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
4714                              (match_operand:SI 2 "arith_operand" "rI"))
4715                     (const_int 0)))
4716    (set (match_operand:SI 0 "register_operand" "=r")
4717         (udiv:SI (match_dup 1) (match_dup 2)))]
4718   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4720   output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4722   if (TARGET_V9)
4723     return "udivcc\t%1, %2, %0";
4724   else
4725     return "nop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
4727   [(set_attr "type" "multi")
4728    (set (attr "length")
4729         (if_then_else (eq_attr "isa" "v9")
4730                       (const_int 2) (const_int 5)))])
4732 ; sparclet multiply/accumulate insns
4734 (define_insn "*smacsi"
4735   [(set (match_operand:SI 0 "register_operand" "=r")
4736         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
4737                           (match_operand:SI 2 "arith_operand" "rI"))
4738                  (match_operand:SI 3 "register_operand" "0")))]
4739   "TARGET_SPARCLET"
4740   "smac\t%1, %2, %0"
4741   [(set_attr "type" "imul")])
4743 (define_insn "*smacdi"
4744   [(set (match_operand:DI 0 "register_operand" "=r")
4745         (plus:DI (mult:DI (sign_extend:DI
4746                            (match_operand:SI 1 "register_operand" "%r"))
4747                           (sign_extend:DI
4748                            (match_operand:SI 2 "register_operand" "r")))
4749                  (match_operand:DI 3 "register_operand" "0")))]
4750   "TARGET_SPARCLET"
4751   "smacd\t%1, %2, %L0"
4752   [(set_attr "type" "imul")])
4754 (define_insn "*umacdi"
4755   [(set (match_operand:DI 0 "register_operand" "=r")
4756         (plus:DI (mult:DI (zero_extend:DI
4757                            (match_operand:SI 1 "register_operand" "%r"))
4758                           (zero_extend:DI
4759                            (match_operand:SI 2 "register_operand" "r")))
4760                  (match_operand:DI 3 "register_operand" "0")))]
4761   "TARGET_SPARCLET"
4762   "umacd\t%1, %2, %L0"
4763   [(set_attr "type" "imul")])
4766 ;; Boolean instructions.
4768 ;; We define DImode `and' so with DImode `not' we can get
4769 ;; DImode `andn'.  Other combinations are possible.
4771 (define_expand "anddi3"
4772   [(set (match_operand:DI 0 "register_operand" "")
4773         (and:DI (match_operand:DI 1 "arith_double_operand" "")
4774                 (match_operand:DI 2 "arith_double_operand" "")))]
4775   ""
4776   "")
4778 (define_insn "*anddi3_sp32"
4779   [(set (match_operand:DI 0 "register_operand" "=r")
4780         (and:DI (match_operand:DI 1 "arith_double_operand" "%r")
4781                 (match_operand:DI 2 "arith_double_operand" "rHI")))]
4782   "! TARGET_ARCH64"
4783   "#")
4785 (define_insn "*anddi3_sp64"
4786   [(set (match_operand:DI 0 "register_operand" "=r")
4787         (and:DI (match_operand:DI 1 "arith_operand" "%r")
4788                 (match_operand:DI 2 "arith_operand" "rI")))]
4789   "TARGET_ARCH64"
4790   "and\t%1, %2, %0")
4792 (define_insn "andsi3"
4793   [(set (match_operand:SI 0 "register_operand" "=r")
4794         (and:SI (match_operand:SI 1 "arith_operand" "%r")
4795                 (match_operand:SI 2 "arith_operand" "rI")))]
4796   ""
4797   "and\t%1, %2, %0")
4799 (define_split
4800   [(set (match_operand:SI 0 "register_operand" "")
4801         (and:SI (match_operand:SI 1 "register_operand" "")
4802                 (match_operand:SI 2 "const_compl_high_operand" "")))
4803    (clobber (match_operand:SI 3 "register_operand" ""))]
4804   ""
4805   [(set (match_dup 3) (match_dup 4))
4806    (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
4808   operands[4] = GEN_INT (~INTVAL (operands[2]));
4811 (define_insn_and_split "*and_not_di_sp32"
4812   [(set (match_operand:DI 0 "register_operand" "=r")
4813         (and:DI (not:DI (match_operand:DI 1 "register_operand" "%r"))
4814                 (match_operand:DI 2 "register_operand" "r")))]
4815   "! TARGET_ARCH64"
4816   "#"
4817   "&& reload_completed
4818    && ((GET_CODE (operands[0]) == REG
4819         && SPARC_INT_REG_P (REGNO (operands[0])))
4820        || (GET_CODE (operands[0]) == SUBREG
4821            && GET_CODE (SUBREG_REG (operands[0])) == REG
4822            && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
4823   [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
4824    (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
4825   "operands[3] = gen_highpart (SImode, operands[0]);
4826    operands[4] = gen_highpart (SImode, operands[1]);
4827    operands[5] = gen_highpart (SImode, operands[2]);
4828    operands[6] = gen_lowpart (SImode, operands[0]);
4829    operands[7] = gen_lowpart (SImode, operands[1]);
4830    operands[8] = gen_lowpart (SImode, operands[2]);"
4831   [(set_attr "length" "2")])
4833 (define_insn "*and_not_di_sp64"
4834   [(set (match_operand:DI 0 "register_operand" "=r")
4835         (and:DI (not:DI (match_operand:DI 1 "register_operand" "%r"))
4836                 (match_operand:DI 2 "register_operand" "r")))]
4837   "TARGET_ARCH64"
4838   "andn\t%2, %1, %0")
4840 (define_insn "*and_not_si"
4841   [(set (match_operand:SI 0 "register_operand" "=r")
4842         (and:SI (not:SI (match_operand:SI 1 "register_operand" "%r"))
4843                 (match_operand:SI 2 "register_operand" "r")))]
4844   ""
4845   "andn\t%2, %1, %0")
4847 (define_expand "iordi3"
4848   [(set (match_operand:DI 0 "register_operand" "")
4849         (ior:DI (match_operand:DI 1 "arith_double_operand" "")
4850                 (match_operand:DI 2 "arith_double_operand" "")))]
4851   ""
4852   "")
4854 (define_insn "*iordi3_sp32"
4855   [(set (match_operand:DI 0 "register_operand" "=r")
4856         (ior:DI (match_operand:DI 1 "arith_double_operand" "%r")
4857                 (match_operand:DI 2 "arith_double_operand" "rHI")))]
4858   "! TARGET_ARCH64"
4859   "#"
4860   [(set_attr "length" "2")])
4862 (define_insn "*iordi3_sp64"
4863   [(set (match_operand:DI 0 "register_operand" "=r")
4864         (ior:DI (match_operand:DI 1 "arith_operand" "%r")
4865                 (match_operand:DI 2 "arith_operand" "rI")))]
4866   "TARGET_ARCH64"
4867   "or\t%1, %2, %0")
4869 (define_insn "iorsi3"
4870   [(set (match_operand:SI 0 "register_operand" "=r")
4871         (ior:SI (match_operand:SI 1 "arith_operand" "%r")
4872                 (match_operand:SI 2 "arith_operand" "rI")))]
4873   ""
4874   "or\t%1, %2, %0")
4876 (define_split
4877   [(set (match_operand:SI 0 "register_operand" "")
4878         (ior:SI (match_operand:SI 1 "register_operand" "")
4879                 (match_operand:SI 2 "const_compl_high_operand" "")))
4880    (clobber (match_operand:SI 3 "register_operand" ""))]
4881   ""
4882   [(set (match_dup 3) (match_dup 4))
4883    (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
4885   operands[4] = GEN_INT (~INTVAL (operands[2]));
4888 (define_insn_and_split "*or_not_di_sp32"
4889   [(set (match_operand:DI 0 "register_operand" "=r")
4890         (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
4891                 (match_operand:DI 2 "register_operand" "r")))]
4892   "! TARGET_ARCH64"
4893   "#"
4894   "&& reload_completed
4895    && ((GET_CODE (operands[0]) == REG
4896         && SPARC_INT_REG_P (REGNO (operands[0])))
4897        || (GET_CODE (operands[0]) == SUBREG
4898            && GET_CODE (SUBREG_REG (operands[0])) == REG
4899            && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
4900   [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
4901    (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
4902   "operands[3] = gen_highpart (SImode, operands[0]);
4903    operands[4] = gen_highpart (SImode, operands[1]);
4904    operands[5] = gen_highpart (SImode, operands[2]);
4905    operands[6] = gen_lowpart (SImode, operands[0]);
4906    operands[7] = gen_lowpart (SImode, operands[1]);
4907    operands[8] = gen_lowpart (SImode, operands[2]);"
4908   [(set_attr "length" "2")])
4910 (define_insn "*or_not_di_sp64"
4911   [(set (match_operand:DI 0 "register_operand" "=r")
4912         (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
4913                 (match_operand:DI 2 "register_operand" "r")))]
4914   "TARGET_ARCH64"
4915   "orn\t%2, %1, %0")
4917 (define_insn "*or_not_si"
4918   [(set (match_operand:SI 0 "register_operand" "=r")
4919         (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
4920                 (match_operand:SI 2 "register_operand" "r")))]
4921   ""
4922   "orn\t%2, %1, %0")
4924 (define_expand "xordi3"
4925   [(set (match_operand:DI 0 "register_operand" "")
4926         (xor:DI (match_operand:DI 1 "arith_double_operand" "")
4927                 (match_operand:DI 2 "arith_double_operand" "")))]
4928   ""
4929   "")
4931 (define_insn "*xordi3_sp32"
4932   [(set (match_operand:DI 0 "register_operand" "=r")
4933         (xor:DI (match_operand:DI 1 "arith_double_operand" "%r")
4934                 (match_operand:DI 2 "arith_double_operand" "rHI")))]
4935   "! TARGET_ARCH64"
4936   "#"
4937   [(set_attr "length" "2")])
4939 (define_insn "*xordi3_sp64"
4940   [(set (match_operand:DI 0 "register_operand" "=r")
4941         (xor:DI (match_operand:DI 1 "arith_operand" "%rJ")
4942                 (match_operand:DI 2 "arith_operand" "rI")))]
4943   "TARGET_ARCH64"
4944   "xor\t%r1, %2, %0")
4946 (define_insn "xorsi3"
4947   [(set (match_operand:SI 0 "register_operand" "=r")
4948         (xor:SI (match_operand:SI 1 "arith_operand" "%rJ")
4949                   (match_operand:SI 2 "arith_operand" "rI")))]
4950   ""
4951   "xor\t%r1, %2, %0")
4953 (define_split
4954   [(set (match_operand:SI 0 "register_operand" "")
4955         (xor:SI (match_operand:SI 1 "register_operand" "")
4956                 (match_operand:SI 2 "const_compl_high_operand" "")))
4957    (clobber (match_operand:SI 3 "register_operand" ""))]
4958    ""
4959   [(set (match_dup 3) (match_dup 4))
4960    (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
4962   operands[4] = GEN_INT (~INTVAL (operands[2]));
4965 (define_split
4966   [(set (match_operand:SI 0 "register_operand" "")
4967         (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
4968                         (match_operand:SI 2 "const_compl_high_operand" ""))))
4969    (clobber (match_operand:SI 3 "register_operand" ""))]
4970   ""
4971   [(set (match_dup 3) (match_dup 4))
4972    (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
4974   operands[4] = GEN_INT (~INTVAL (operands[2]));
4977 ;; Split DImode logical operations requiring two instructions.
4978 (define_split
4979   [(set (match_operand:DI 0 "register_operand" "")
4980         (match_operator:DI 1 "cc_arith_operator"        ; AND, IOR, XOR
4981                            [(match_operand:DI 2 "register_operand" "")
4982                             (match_operand:DI 3 "arith_double_operand" "")]))]
4983   "! TARGET_ARCH64
4984    && reload_completed
4985    && ((GET_CODE (operands[0]) == REG
4986         && SPARC_INT_REG_P (REGNO (operands[0])))
4987        || (GET_CODE (operands[0]) == SUBREG
4988            && GET_CODE (SUBREG_REG (operands[0])) == REG
4989            && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
4990   [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
4991    (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
4993   operands[4] = gen_highpart (SImode, operands[0]);
4994   operands[5] = gen_lowpart (SImode, operands[0]);
4995   operands[6] = gen_highpart (SImode, operands[2]);
4996   operands[7] = gen_lowpart (SImode, operands[2]);
4997 #if HOST_BITS_PER_WIDE_INT == 32
4998   if (GET_CODE (operands[3]) == CONST_INT)
4999     {
5000       if (INTVAL (operands[3]) < 0)
5001         operands[8] = constm1_rtx;
5002       else
5003         operands[8] = const0_rtx;
5004     }
5005   else
5006 #endif
5007     operands[8] = gen_highpart_mode (SImode, DImode, operands[3]);
5008   operands[9] = gen_lowpart (SImode, operands[3]);
5011 ;; xnor patterns.  Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
5012 ;; Combine now canonicalizes to the rightmost expression.
5013 (define_insn_and_split "*xor_not_di_sp32"
5014   [(set (match_operand:DI 0 "register_operand" "=r")
5015         (not:DI (xor:DI (match_operand:DI 1 "register_operand" "r")
5016                         (match_operand:DI 2 "register_operand" "r"))))]
5017   "! TARGET_ARCH64"
5018   "#"
5019   "&& reload_completed
5020    && ((GET_CODE (operands[0]) == REG
5021         && SPARC_INT_REG_P (REGNO (operands[0])))
5022        || (GET_CODE (operands[0]) == SUBREG
5023            && GET_CODE (SUBREG_REG (operands[0])) == REG
5024            && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
5025   [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
5026    (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
5027   "operands[3] = gen_highpart (SImode, operands[0]);
5028    operands[4] = gen_highpart (SImode, operands[1]);
5029    operands[5] = gen_highpart (SImode, operands[2]);
5030    operands[6] = gen_lowpart (SImode, operands[0]);
5031    operands[7] = gen_lowpart (SImode, operands[1]);
5032    operands[8] = gen_lowpart (SImode, operands[2]);"
5033   [(set_attr "length" "2")])
5035 (define_insn "*xor_not_di_sp64"
5036   [(set (match_operand:DI 0 "register_operand" "=r")
5037         (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
5038                         (match_operand:DI 2 "arith_operand" "rI"))))]
5039   "TARGET_ARCH64"
5040   "xnor\t%r1, %2, %0")
5042 (define_insn "*xor_not_si"
5043   [(set (match_operand:SI 0 "register_operand" "=r")
5044         (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
5045                         (match_operand:SI 2 "arith_operand" "rI"))))]
5046   ""
5047   "xnor\t%r1, %2, %0")
5049 ;; These correspond to the above in the case where we also (or only)
5050 ;; want to set the condition code.  
5052 (define_insn "*cmp_cc_arith_op"
5053   [(set (reg:CC CC_REG)
5054         (compare:CC
5055          (match_operator:SI 2 "cc_arith_operator"
5056                             [(match_operand:SI 0 "arith_operand" "%r")
5057                              (match_operand:SI 1 "arith_operand" "rI")])
5058          (const_int 0)))]
5059   ""
5060   "%A2cc\t%0, %1, %%g0"
5061   [(set_attr "type" "compare")])
5063 (define_insn "*cmp_ccx_arith_op"
5064   [(set (reg:CCX CC_REG)
5065         (compare:CCX
5066          (match_operator:DI 2 "cc_arith_operator"
5067                             [(match_operand:DI 0 "arith_operand" "%r")
5068                              (match_operand:DI 1 "arith_operand" "rI")])
5069          (const_int 0)))]
5070   "TARGET_ARCH64"
5071   "%A2cc\t%0, %1, %%g0"
5072   [(set_attr "type" "compare")])
5074 (define_insn "*cmp_cc_arith_op_set"
5075   [(set (reg:CC CC_REG)
5076         (compare:CC
5077          (match_operator:SI 3 "cc_arith_operator"
5078                             [(match_operand:SI 1 "arith_operand" "%r")
5079                              (match_operand:SI 2 "arith_operand" "rI")])
5080          (const_int 0)))
5081    (set (match_operand:SI 0 "register_operand" "=r")
5082         (match_operator:SI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5083   "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5084   "%A3cc\t%1, %2, %0"
5085   [(set_attr "type" "compare")])
5087 (define_insn "*cmp_ccx_arith_op_set"
5088   [(set (reg:CCX CC_REG)
5089         (compare:CCX
5090          (match_operator:DI 3 "cc_arith_operator"
5091                             [(match_operand:DI 1 "arith_operand" "%r")
5092                              (match_operand:DI 2 "arith_operand" "rI")])
5093          (const_int 0)))
5094    (set (match_operand:DI 0 "register_operand" "=r")
5095         (match_operator:DI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5096   "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5097   "%A3cc\t%1, %2, %0"
5098   [(set_attr "type" "compare")])
5100 (define_insn "*cmp_cc_xor_not"
5101   [(set (reg:CC CC_REG)
5102         (compare:CC
5103          (not:SI (xor:SI (match_operand:SI 0 "register_or_zero_operand" "%rJ")
5104                          (match_operand:SI 1 "arith_operand" "rI")))
5105          (const_int 0)))]
5106   ""
5107   "xnorcc\t%r0, %1, %%g0"
5108   [(set_attr "type" "compare")])
5110 (define_insn "*cmp_ccx_xor_not"
5111   [(set (reg:CCX CC_REG)
5112         (compare:CCX
5113          (not:DI (xor:DI (match_operand:DI 0 "register_or_zero_operand" "%rJ")
5114                          (match_operand:DI 1 "arith_operand" "rI")))
5115          (const_int 0)))]
5116   "TARGET_ARCH64"
5117   "xnorcc\t%r0, %1, %%g0"
5118   [(set_attr "type" "compare")])
5120 (define_insn "*cmp_cc_xor_not_set"
5121   [(set (reg:CC CC_REG)
5122         (compare:CC
5123          (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
5124                          (match_operand:SI 2 "arith_operand" "rI")))
5125          (const_int 0)))
5126    (set (match_operand:SI 0 "register_operand" "=r")
5127         (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
5128   ""
5129   "xnorcc\t%r1, %2, %0"
5130   [(set_attr "type" "compare")])
5132 (define_insn "*cmp_ccx_xor_not_set"
5133   [(set (reg:CCX CC_REG)
5134         (compare:CCX
5135          (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
5136                          (match_operand:DI 2 "arith_operand" "rI")))
5137          (const_int 0)))
5138    (set (match_operand:DI 0 "register_operand" "=r")
5139         (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
5140   "TARGET_ARCH64"
5141   "xnorcc\t%r1, %2, %0"
5142   [(set_attr "type" "compare")])
5144 (define_insn "*cmp_cc_arith_op_not"
5145   [(set (reg:CC CC_REG)
5146         (compare:CC
5147          (match_operator:SI 2 "cc_arith_not_operator"
5148                             [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
5149                              (match_operand:SI 1 "register_or_zero_operand" "rJ")])
5150          (const_int 0)))]
5151   ""
5152   "%B2cc\t%r1, %0, %%g0"
5153   [(set_attr "type" "compare")])
5155 (define_insn "*cmp_ccx_arith_op_not"
5156   [(set (reg:CCX CC_REG)
5157         (compare:CCX
5158          (match_operator:DI 2 "cc_arith_not_operator"
5159                             [(not:DI (match_operand:DI 0 "arith_operand" "rI"))
5160                              (match_operand:DI 1 "register_or_zero_operand" "rJ")])
5161          (const_int 0)))]
5162   "TARGET_ARCH64"
5163   "%B2cc\t%r1, %0, %%g0"
5164   [(set_attr "type" "compare")])
5166 (define_insn "*cmp_cc_arith_op_not_set"
5167   [(set (reg:CC CC_REG)
5168         (compare:CC
5169          (match_operator:SI 3 "cc_arith_not_operator"
5170                             [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
5171                              (match_operand:SI 2 "register_or_zero_operand" "rJ")])
5172          (const_int 0)))
5173    (set (match_operand:SI 0 "register_operand" "=r")
5174         (match_operator:SI 4 "cc_arith_not_operator"
5175                             [(not:SI (match_dup 1)) (match_dup 2)]))]
5176   "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5177   "%B3cc\t%r2, %1, %0"
5178   [(set_attr "type" "compare")])
5180 (define_insn "*cmp_ccx_arith_op_not_set"
5181   [(set (reg:CCX CC_REG)
5182         (compare:CCX
5183          (match_operator:DI 3 "cc_arith_not_operator"
5184                             [(not:DI (match_operand:DI 1 "arith_operand" "rI"))
5185                              (match_operand:DI 2 "register_or_zero_operand" "rJ")])
5186          (const_int 0)))
5187    (set (match_operand:DI 0 "register_operand" "=r")
5188         (match_operator:DI 4 "cc_arith_not_operator"
5189                             [(not:DI (match_dup 1)) (match_dup 2)]))]
5190   "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5191   "%B3cc\t%r2, %1, %0"
5192   [(set_attr "type" "compare")])
5194 ;; We cannot use the "neg" pseudo insn because the Sun assembler
5195 ;; does not know how to make it work for constants.
5197 (define_expand "negdi2"
5198   [(set (match_operand:DI 0 "register_operand" "=r")
5199         (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5200   ""
5202   if (! TARGET_ARCH64)
5203     {
5204       emit_insn (gen_rtx_PARALLEL
5205                  (VOIDmode,
5206                   gen_rtvec (2,
5207                              gen_rtx_SET (VOIDmode, operand0,
5208                                           gen_rtx_NEG (DImode, operand1)),
5209                              gen_rtx_CLOBBER (VOIDmode,
5210                                               gen_rtx_REG (CCmode,
5211                                                            SPARC_ICC_REG)))));
5212       DONE;
5213     }
5216 (define_insn_and_split "*negdi2_sp32"
5217   [(set (match_operand:DI 0 "register_operand" "=r")
5218         (neg:DI (match_operand:DI 1 "register_operand" "r")))
5219    (clobber (reg:CC CC_REG))]
5220   "! TARGET_ARCH64"
5221   "#"
5222   "&& reload_completed"
5223   [(parallel [(set (reg:CC_NOOV CC_REG)
5224                    (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
5225                                     (const_int 0)))
5226               (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
5227    (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
5228                                 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
5229   "operands[2] = gen_highpart (SImode, operands[0]);
5230    operands[3] = gen_highpart (SImode, operands[1]);
5231    operands[4] = gen_lowpart (SImode, operands[0]);
5232    operands[5] = gen_lowpart (SImode, operands[1]);"
5233   [(set_attr "length" "2")])
5235 (define_insn "*negdi2_sp64"
5236   [(set (match_operand:DI 0 "register_operand" "=r")
5237         (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5238   "TARGET_ARCH64"
5239   "sub\t%%g0, %1, %0")
5241 (define_insn "negsi2"
5242   [(set (match_operand:SI 0 "register_operand" "=r")
5243         (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
5244   ""
5245   "sub\t%%g0, %1, %0")
5247 (define_insn "*cmp_cc_neg"
5248   [(set (reg:CC_NOOV CC_REG)
5249         (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
5250                          (const_int 0)))]
5251   ""
5252   "subcc\t%%g0, %0, %%g0"
5253   [(set_attr "type" "compare")])
5255 (define_insn "*cmp_ccx_neg"
5256   [(set (reg:CCX_NOOV CC_REG)
5257         (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_operand" "rI"))
5258                           (const_int 0)))]
5259   "TARGET_ARCH64"
5260   "subcc\t%%g0, %0, %%g0"
5261   [(set_attr "type" "compare")])
5263 (define_insn "*cmp_cc_set_neg"
5264   [(set (reg:CC_NOOV CC_REG)
5265         (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
5266                          (const_int 0)))
5267    (set (match_operand:SI 0 "register_operand" "=r")
5268         (neg:SI (match_dup 1)))]
5269   ""
5270   "subcc\t%%g0, %1, %0"
5271   [(set_attr "type" "compare")])
5273 (define_insn "*cmp_ccx_set_neg"
5274   [(set (reg:CCX_NOOV CC_REG)
5275         (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_operand" "rI"))
5276                           (const_int 0)))
5277    (set (match_operand:DI 0 "register_operand" "=r")
5278         (neg:DI (match_dup 1)))]
5279   "TARGET_ARCH64"
5280   "subcc\t%%g0, %1, %0"
5281   [(set_attr "type" "compare")])
5283 ;; We cannot use the "not" pseudo insn because the Sun assembler
5284 ;; does not know how to make it work for constants.
5285 (define_expand "one_cmpldi2"
5286   [(set (match_operand:DI 0 "register_operand" "")
5287         (not:DI (match_operand:DI 1 "register_operand" "")))]
5288   ""
5289   "")
5291 (define_insn_and_split "*one_cmpldi2_sp32"
5292   [(set (match_operand:DI 0 "register_operand" "=r")
5293         (not:DI (match_operand:DI 1 "register_operand" "r")))]
5294   "! TARGET_ARCH64"
5295   "#"
5296   "&& reload_completed
5297    && ((GET_CODE (operands[0]) == REG
5298         && SPARC_INT_REG_P (REGNO (operands[0])))
5299        || (GET_CODE (operands[0]) == SUBREG
5300            && GET_CODE (SUBREG_REG (operands[0])) == REG
5301            && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
5302   [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
5303    (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
5304   "operands[2] = gen_highpart (SImode, operands[0]);
5305    operands[3] = gen_highpart (SImode, operands[1]);
5306    operands[4] = gen_lowpart (SImode, operands[0]);
5307    operands[5] = gen_lowpart (SImode, operands[1]);"
5308   [(set_attr "length" "2")])
5310 (define_insn "*one_cmpldi2_sp64"
5311   [(set (match_operand:DI 0 "register_operand" "=r")
5312         (not:DI (match_operand:DI 1 "arith_operand" "rI")))]
5313   "TARGET_ARCH64"
5314   "xnor\t%%g0, %1, %0")
5316 (define_insn "one_cmplsi2"
5317   [(set (match_operand:SI 0 "register_operand" "=r")
5318         (not:SI (match_operand:SI 1 "arith_operand" "rI")))]
5319   ""
5320   "xnor\t%%g0, %1, %0")
5322 (define_insn "*cmp_cc_not"
5323   [(set (reg:CC CC_REG)
5324         (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
5325                     (const_int 0)))]
5326   ""
5327   "xnorcc\t%%g0, %0, %%g0"
5328   [(set_attr "type" "compare")])
5330 (define_insn "*cmp_ccx_not"
5331   [(set (reg:CCX CC_REG)
5332         (compare:CCX (not:DI (match_operand:DI 0 "arith_operand" "rI"))
5333                      (const_int 0)))]
5334   "TARGET_ARCH64"
5335   "xnorcc\t%%g0, %0, %%g0"
5336   [(set_attr "type" "compare")])
5338 (define_insn "*cmp_cc_set_not"
5339   [(set (reg:CC CC_REG)
5340         (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
5341                     (const_int 0)))
5342    (set (match_operand:SI 0 "register_operand" "=r")
5343         (not:SI (match_dup 1)))]
5344   ""
5345   "xnorcc\t%%g0, %1, %0"
5346   [(set_attr "type" "compare")])
5348 (define_insn "*cmp_ccx_set_not"
5349   [(set (reg:CCX CC_REG)
5350         (compare:CCX (not:DI (match_operand:DI 1 "arith_operand" "rI"))
5351                     (const_int 0)))
5352    (set (match_operand:DI 0 "register_operand" "=r")
5353         (not:DI (match_dup 1)))]
5354   "TARGET_ARCH64"
5355   "xnorcc\t%%g0, %1, %0"
5356   [(set_attr "type" "compare")])
5358 (define_insn "*cmp_cc_set"
5359   [(set (match_operand:SI 0 "register_operand" "=r")
5360         (match_operand:SI 1 "register_operand" "r"))
5361    (set (reg:CC CC_REG)
5362         (compare:CC (match_dup 1)
5363                     (const_int 0)))]
5364   ""
5365   "orcc\t%1, 0, %0"
5366   [(set_attr "type" "compare")])
5368 (define_insn "*cmp_ccx_set64"
5369   [(set (match_operand:DI 0 "register_operand" "=r")
5370         (match_operand:DI 1 "register_operand" "r"))
5371    (set (reg:CCX CC_REG)
5372         (compare:CCX (match_dup 1)
5373                      (const_int 0)))]
5374   "TARGET_ARCH64"
5375   "orcc\t%1, 0, %0"
5376    [(set_attr "type" "compare")])
5379 ;; Floating point arithmetic instructions.
5381 (define_expand "addtf3"
5382   [(set (match_operand:TF 0 "nonimmediate_operand" "")
5383         (plus:TF (match_operand:TF 1 "general_operand" "")
5384                  (match_operand:TF 2 "general_operand" "")))]
5385   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5386   "emit_tfmode_binop (PLUS, operands); DONE;")
5388 (define_insn "*addtf3_hq"
5389   [(set (match_operand:TF 0 "register_operand" "=e")
5390         (plus:TF (match_operand:TF 1 "register_operand" "e")
5391                  (match_operand:TF 2 "register_operand" "e")))]
5392   "TARGET_FPU && TARGET_HARD_QUAD"
5393   "faddq\t%1, %2, %0"
5394   [(set_attr "type" "fp")])
5396 (define_insn "adddf3"
5397   [(set (match_operand:DF 0 "register_operand" "=e")
5398         (plus:DF (match_operand:DF 1 "register_operand" "e")
5399                  (match_operand:DF 2 "register_operand" "e")))]
5400   "TARGET_FPU"
5401   "faddd\t%1, %2, %0"
5402   [(set_attr "type" "fp")
5403    (set_attr "fptype" "double")])
5405 (define_insn "addsf3"
5406   [(set (match_operand:SF 0 "register_operand" "=f")
5407         (plus:SF (match_operand:SF 1 "register_operand" "f")
5408                  (match_operand:SF 2 "register_operand" "f")))]
5409   "TARGET_FPU"
5410   "fadds\t%1, %2, %0"
5411   [(set_attr "type" "fp")])
5413 (define_expand "subtf3"
5414   [(set (match_operand:TF 0 "nonimmediate_operand" "")
5415         (minus:TF (match_operand:TF 1 "general_operand" "")
5416                   (match_operand:TF 2 "general_operand" "")))]
5417   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5418   "emit_tfmode_binop (MINUS, operands); DONE;")
5420 (define_insn "*subtf3_hq"
5421   [(set (match_operand:TF 0 "register_operand" "=e")
5422         (minus:TF (match_operand:TF 1 "register_operand" "e")
5423                   (match_operand:TF 2 "register_operand" "e")))]
5424   "TARGET_FPU && TARGET_HARD_QUAD"
5425   "fsubq\t%1, %2, %0"
5426   [(set_attr "type" "fp")])
5428 (define_insn "subdf3"
5429   [(set (match_operand:DF 0 "register_operand" "=e")
5430         (minus:DF (match_operand:DF 1 "register_operand" "e")
5431                   (match_operand:DF 2 "register_operand" "e")))]
5432   "TARGET_FPU"
5433   "fsubd\t%1, %2, %0"
5434   [(set_attr "type" "fp")
5435    (set_attr "fptype" "double")])
5437 (define_insn "subsf3"
5438   [(set (match_operand:SF 0 "register_operand" "=f")
5439         (minus:SF (match_operand:SF 1 "register_operand" "f")
5440                   (match_operand:SF 2 "register_operand" "f")))]
5441   "TARGET_FPU"
5442   "fsubs\t%1, %2, %0"
5443   [(set_attr "type" "fp")])
5445 (define_expand "multf3"
5446   [(set (match_operand:TF 0 "nonimmediate_operand" "")
5447         (mult:TF (match_operand:TF 1 "general_operand" "")
5448                  (match_operand:TF 2 "general_operand" "")))]
5449   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5450   "emit_tfmode_binop (MULT, operands); DONE;")
5452 (define_insn "*multf3_hq"
5453   [(set (match_operand:TF 0 "register_operand" "=e")
5454         (mult:TF (match_operand:TF 1 "register_operand" "e")
5455                  (match_operand:TF 2 "register_operand" "e")))]
5456   "TARGET_FPU && TARGET_HARD_QUAD"
5457   "fmulq\t%1, %2, %0"
5458   [(set_attr "type" "fpmul")])
5460 (define_insn "muldf3"
5461   [(set (match_operand:DF 0 "register_operand" "=e")
5462         (mult:DF (match_operand:DF 1 "register_operand" "e")
5463                  (match_operand:DF 2 "register_operand" "e")))]
5464   "TARGET_FPU"
5465   "fmuld\t%1, %2, %0"
5466   [(set_attr "type" "fpmul")
5467    (set_attr "fptype" "double")])
5469 (define_insn "mulsf3"
5470   [(set (match_operand:SF 0 "register_operand" "=f")
5471         (mult:SF (match_operand:SF 1 "register_operand" "f")
5472                  (match_operand:SF 2 "register_operand" "f")))]
5473   "TARGET_FPU"
5474   "fmuls\t%1, %2, %0"
5475   [(set_attr "type" "fpmul")])
5477 (define_insn "fmadf4"
5478   [(set (match_operand:DF 0 "register_operand" "=e")
5479         (fma:DF (match_operand:DF 1 "register_operand" "e")
5480                 (match_operand:DF 2 "register_operand" "e")
5481                 (match_operand:DF 3 "register_operand" "e")))]
5482   "TARGET_FMAF"
5483   "fmaddd\t%1, %2, %3, %0"
5484   [(set_attr "type" "fpmul")])
5486 (define_insn "fmsdf4"
5487   [(set (match_operand:DF 0 "register_operand" "=e")
5488         (fma:DF (match_operand:DF 1 "register_operand" "e")
5489                 (match_operand:DF 2 "register_operand" "e")
5490                 (neg:DF (match_operand:DF 3 "register_operand" "e"))))]
5491   "TARGET_FMAF"
5492   "fmsubd\t%1, %2, %3, %0"
5493   [(set_attr "type" "fpmul")])
5495 (define_insn "*nfmadf4"
5496   [(set (match_operand:DF 0 "register_operand" "=e")
5497         (neg:DF (fma:DF (match_operand:DF 1 "register_operand" "e")
5498                         (match_operand:DF 2 "register_operand" "e")
5499                         (match_operand:DF 3 "register_operand" "e"))))]
5500   "TARGET_FMAF"
5501   "fnmaddd\t%1, %2, %3, %0"
5502   [(set_attr "type" "fpmul")])
5504 (define_insn "*nfmsdf4"
5505   [(set (match_operand:DF 0 "register_operand" "=e")
5506         (neg:DF (fma:DF (match_operand:DF 1 "register_operand" "e")
5507                         (match_operand:DF 2 "register_operand" "e")
5508                         (neg:DF (match_operand:DF 3 "register_operand" "e")))))]
5509   "TARGET_FMAF"
5510   "fnmsubd\t%1, %2, %3, %0"
5511   [(set_attr "type" "fpmul")])
5513 (define_insn "fmasf4"
5514   [(set (match_operand:SF 0 "register_operand" "=f")
5515         (fma:SF (match_operand:SF 1 "register_operand" "f")
5516                 (match_operand:SF 2 "register_operand" "f")
5517                 (match_operand:SF 3 "register_operand" "f")))]
5518   "TARGET_FMAF"
5519   "fmadds\t%1, %2, %3, %0"
5520   [(set_attr "type" "fpmul")])
5522 (define_insn "fmssf4"
5523   [(set (match_operand:SF 0 "register_operand" "=f")
5524         (fma:SF (match_operand:SF 1 "register_operand" "f")
5525                 (match_operand:SF 2 "register_operand" "f")
5526                 (neg:SF (match_operand:SF 3 "register_operand" "f"))))]
5527   "TARGET_FMAF"
5528   "fmsubs\t%1, %2, %3, %0"
5529   [(set_attr "type" "fpmul")])
5531 (define_insn "*nfmasf4"
5532   [(set (match_operand:SF 0 "register_operand" "=f")
5533         (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "f")
5534                         (match_operand:SF 2 "register_operand" "f")
5535                         (match_operand:SF 3 "register_operand" "f"))))]
5536   "TARGET_FMAF"
5537   "fnmadds\t%1, %2, %3, %0"
5538   [(set_attr "type" "fpmul")])
5540 (define_insn "*nfmssf4"
5541   [(set (match_operand:SF 0 "register_operand" "=f")
5542         (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "f")
5543                         (match_operand:SF 2 "register_operand" "f")
5544                         (neg:SF (match_operand:SF 3 "register_operand" "f")))))]
5545   "TARGET_FMAF"
5546   "fnmsubs\t%1, %2, %3, %0"
5547   [(set_attr "type" "fpmul")])
5549 (define_insn "*muldf3_extend"
5550   [(set (match_operand:DF 0 "register_operand" "=e")
5551         (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
5552                  (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
5553   "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
5554   "fsmuld\t%1, %2, %0"
5555   [(set_attr "type" "fpmul")
5556    (set_attr "fptype" "double")])
5558 (define_insn "*multf3_extend"
5559   [(set (match_operand:TF 0 "register_operand" "=e")
5560         (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
5561                  (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
5562   "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
5563   "fdmulq\t%1, %2, %0"
5564   [(set_attr "type" "fpmul")])
5566 (define_expand "divtf3"
5567   [(set (match_operand:TF 0 "nonimmediate_operand" "")
5568         (div:TF (match_operand:TF 1 "general_operand" "")
5569                 (match_operand:TF 2 "general_operand" "")))]
5570   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5571   "emit_tfmode_binop (DIV, operands); DONE;")
5573 ;; don't have timing for quad-prec. divide.
5574 (define_insn "*divtf3_hq"
5575   [(set (match_operand:TF 0 "register_operand" "=e")
5576         (div:TF (match_operand:TF 1 "register_operand" "e")
5577                 (match_operand:TF 2 "register_operand" "e")))]
5578   "TARGET_FPU && TARGET_HARD_QUAD"
5579   "fdivq\t%1, %2, %0"
5580   [(set_attr "type" "fpdivd")])
5582 (define_insn "divdf3"
5583   [(set (match_operand:DF 0 "register_operand" "=e")
5584         (div:DF (match_operand:DF 1 "register_operand" "e")
5585                 (match_operand:DF 2 "register_operand" "e")))]
5586   "TARGET_FPU"
5587   "fdivd\t%1, %2, %0"
5588   [(set_attr "type" "fpdivd")
5589    (set_attr "fptype" "double")])
5591 (define_insn "divsf3"
5592   [(set (match_operand:SF 0 "register_operand" "=f")
5593         (div:SF (match_operand:SF 1 "register_operand" "f")
5594                 (match_operand:SF 2 "register_operand" "f")))]
5595   "TARGET_FPU"
5596   "fdivs\t%1, %2, %0"
5597   [(set_attr "type" "fpdivs")])
5599 (define_expand "negtf2"
5600   [(set (match_operand:TF 0 "register_operand" "=e,e")
5601         (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5602   "TARGET_FPU"
5603   "")
5605 (define_insn_and_split "*negtf2_notv9"
5606   [(set (match_operand:TF 0 "register_operand" "=e,e")
5607         (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5608   ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5609   "TARGET_FPU
5610    && ! TARGET_V9"
5611   "@
5612   fnegs\t%0, %0
5613   #"
5614   "&& reload_completed
5615    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5616   [(set (match_dup 2) (neg:SF (match_dup 3)))
5617    (set (match_dup 4) (match_dup 5))
5618    (set (match_dup 6) (match_dup 7))]
5619   "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5620    operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5621    operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5622    operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
5623    operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5624    operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5625   [(set_attr "type" "fpmove,*")
5626    (set_attr "length" "*,2")])
5628 (define_insn_and_split "*negtf2_v9"
5629   [(set (match_operand:TF 0 "register_operand" "=e,e")
5630         (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5631   ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5632   "TARGET_FPU && TARGET_V9"
5633   "@
5634   fnegd\t%0, %0
5635   #"
5636   "&& reload_completed
5637    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5638   [(set (match_dup 2) (neg:DF (match_dup 3)))
5639    (set (match_dup 4) (match_dup 5))]
5640   "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
5641    operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
5642    operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5643    operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5644   [(set_attr "type" "fpmove,*")
5645    (set_attr "length" "*,2")
5646    (set_attr "fptype" "double")])
5648 (define_expand "negdf2"
5649   [(set (match_operand:DF 0 "register_operand" "")
5650         (neg:DF (match_operand:DF 1 "register_operand" "")))]
5651   "TARGET_FPU"
5652   "")
5654 (define_insn_and_split "*negdf2_notv9"
5655   [(set (match_operand:DF 0 "register_operand" "=e,e")
5656         (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
5657   "TARGET_FPU && ! TARGET_V9"
5658   "@
5659   fnegs\t%0, %0
5660   #"
5661   "&& reload_completed
5662    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5663   [(set (match_dup 2) (neg:SF (match_dup 3)))
5664    (set (match_dup 4) (match_dup 5))]
5665   "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5666    operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5667    operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5668    operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
5669   [(set_attr "type" "fpmove,*")
5670    (set_attr "length" "*,2")])
5672 (define_insn "*negdf2_v9"
5673   [(set (match_operand:DF 0 "register_operand" "=e")
5674         (neg:DF (match_operand:DF 1 "register_operand" "e")))]
5675   "TARGET_FPU && TARGET_V9"
5676   "fnegd\t%1, %0"
5677   [(set_attr "type" "fpmove")
5678    (set_attr "fptype" "double")])
5680 (define_insn "negsf2"
5681   [(set (match_operand:SF 0 "register_operand" "=f")
5682         (neg:SF (match_operand:SF 1 "register_operand" "f")))]
5683   "TARGET_FPU"
5684   "fnegs\t%1, %0"
5685   [(set_attr "type" "fpmove")])
5687 (define_expand "abstf2"
5688   [(set (match_operand:TF 0 "register_operand" "")
5689         (abs:TF (match_operand:TF 1 "register_operand" "")))]
5690   "TARGET_FPU"
5691   "")
5693 (define_insn_and_split "*abstf2_notv9"
5694   [(set (match_operand:TF 0 "register_operand" "=e,e")
5695         (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5696   ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5697   "TARGET_FPU && ! TARGET_V9"
5698   "@
5699   fabss\t%0, %0
5700   #"
5701   "&& reload_completed
5702    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5703   [(set (match_dup 2) (abs:SF (match_dup 3)))
5704    (set (match_dup 4) (match_dup 5))
5705    (set (match_dup 6) (match_dup 7))]
5706   "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5707    operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5708    operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5709    operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
5710    operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5711    operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5712   [(set_attr "type" "fpmove,*")
5713    (set_attr "length" "*,2")])
5715 (define_insn "*abstf2_hq_v9"
5716   [(set (match_operand:TF 0 "register_operand" "=e,e")
5717         (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5718   "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
5719   "@
5720   fabsd\t%0, %0
5721   fabsq\t%1, %0"
5722   [(set_attr "type" "fpmove")
5723    (set_attr "fptype" "double,*")])
5725 (define_insn_and_split "*abstf2_v9"
5726   [(set (match_operand:TF 0 "register_operand" "=e,e")
5727         (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
5728   "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
5729   "@
5730   fabsd\t%0, %0
5731   #"
5732   "&& reload_completed
5733    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5734   [(set (match_dup 2) (abs:DF (match_dup 3)))
5735    (set (match_dup 4) (match_dup 5))]
5736   "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
5737    operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
5738    operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
5739    operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
5740   [(set_attr "type" "fpmove,*")
5741    (set_attr "length" "*,2")
5742    (set_attr "fptype" "double,*")])
5744 (define_expand "absdf2"
5745   [(set (match_operand:DF 0 "register_operand" "")
5746         (abs:DF (match_operand:DF 1 "register_operand" "")))]
5747   "TARGET_FPU"
5748   "")
5750 (define_insn_and_split "*absdf2_notv9"
5751   [(set (match_operand:DF 0 "register_operand" "=e,e")
5752         (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
5753   "TARGET_FPU && ! TARGET_V9"
5754   "@
5755   fabss\t%0, %0
5756   #"
5757   "&& reload_completed
5758    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5759   [(set (match_dup 2) (abs:SF (match_dup 3)))
5760    (set (match_dup 4) (match_dup 5))]
5761   "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
5762    operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
5763    operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
5764    operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
5765   [(set_attr "type" "fpmove,*")
5766    (set_attr "length" "*,2")])
5768 (define_insn "*absdf2_v9"
5769   [(set (match_operand:DF 0 "register_operand" "=e")
5770         (abs:DF (match_operand:DF 1 "register_operand" "e")))]
5771   "TARGET_FPU && TARGET_V9"
5772   "fabsd\t%1, %0"
5773   [(set_attr "type" "fpmove")
5774    (set_attr "fptype" "double")])
5776 (define_insn "abssf2"
5777   [(set (match_operand:SF 0 "register_operand" "=f")
5778         (abs:SF (match_operand:SF 1 "register_operand" "f")))]
5779   "TARGET_FPU"
5780   "fabss\t%1, %0"
5781   [(set_attr "type" "fpmove")])
5783 (define_expand "sqrttf2"
5784   [(set (match_operand:TF 0 "nonimmediate_operand" "")
5785         (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
5786   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5787   "emit_tfmode_unop (SQRT, operands); DONE;")
5789 (define_insn "*sqrttf2_hq"
5790   [(set (match_operand:TF 0 "register_operand" "=e")
5791         (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
5792   "TARGET_FPU && TARGET_HARD_QUAD"
5793   "fsqrtq\t%1, %0"
5794   [(set_attr "type" "fpsqrtd")])
5796 (define_insn "sqrtdf2"
5797   [(set (match_operand:DF 0 "register_operand" "=e")
5798         (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
5799   "TARGET_FPU"
5800   "fsqrtd\t%1, %0"
5801   [(set_attr "type" "fpsqrtd")
5802    (set_attr "fptype" "double")])
5804 (define_insn "sqrtsf2"
5805   [(set (match_operand:SF 0 "register_operand" "=f")
5806         (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
5807   "TARGET_FPU"
5808   "fsqrts\t%1, %0"
5809   [(set_attr "type" "fpsqrts")])
5812 ;; Arithmetic shift instructions.
5814 (define_insn "ashlsi3"
5815   [(set (match_operand:SI 0 "register_operand" "=r")
5816         (ashift:SI (match_operand:SI 1 "register_operand" "r")
5817                    (match_operand:SI 2 "arith_operand" "rI")))]
5818   ""
5820   if (GET_CODE (operands[2]) == CONST_INT)
5821     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5822   return "sll\t%1, %2, %0";
5824   [(set_attr "type" "shift")])
5826 (define_insn "*ashlsi3_extend"
5827   [(set (match_operand:DI 0 "register_operand" "=r")
5828         (zero_extend:DI
5829           (ashift:SI (match_operand:SI 1 "register_operand" "r")
5830                      (match_operand:SI 2 "arith_operand" "rI"))))]
5831   "TARGET_ARCH64"
5833   if (GET_CODE (operands[2]) == CONST_INT)
5834     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5835   return "sll\t%1, %2, %0";
5837   [(set_attr "type" "shift")])
5839 (define_expand "ashldi3"
5840   [(set (match_operand:DI 0 "register_operand" "=r")
5841         (ashift:DI (match_operand:DI 1 "register_operand" "r")
5842                    (match_operand:SI 2 "arith_operand" "rI")))]
5843   "TARGET_ARCH64 || TARGET_V8PLUS"
5845   if (! TARGET_ARCH64)
5846     {
5847       if (GET_CODE (operands[2]) == CONST_INT)
5848         FAIL;
5849       emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
5850       DONE;
5851     }
5854 (define_insn "*ashldi3_sp64"
5855   [(set (match_operand:DI 0 "register_operand" "=r")
5856         (ashift:DI (match_operand:DI 1 "register_operand" "r")
5857                    (match_operand:SI 2 "arith_operand" "rI")))]
5858   "TARGET_ARCH64"
5860   if (GET_CODE (operands[2]) == CONST_INT)
5861     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5862   return "sllx\t%1, %2, %0";
5864   [(set_attr "type" "shift")])
5866 ;; XXX UGH!
5867 (define_insn "ashldi3_v8plus"
5868   [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5869         (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5870                    (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5871    (clobber (match_scratch:SI 3 "=X,X,&h"))]
5872   "TARGET_V8PLUS"
5873   "* return output_v8plus_shift (insn ,operands, \"sllx\");"
5874   [(set_attr "type" "multi")
5875    (set_attr "length" "5,5,6")])
5877 ;; Optimize (1LL<<x)-1
5878 ;; XXX this also needs to be fixed to handle equal subregs
5879 ;; XXX first before we could re-enable it.
5880 ;(define_insn ""
5881 ;  [(set (match_operand:DI 0 "register_operand" "=h")
5882 ;       (plus:DI (ashift:DI (const_int 1)
5883 ;                           (match_operand:SI 1 "arith_operand" "rI"))
5884 ;                (const_int -1)))]
5885 ;  "0 && TARGET_V8PLUS"
5887 ;  if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
5888 ;    return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5889 ;  return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5891 ;  [(set_attr "type" "multi")
5892 ;   (set_attr "length" "4")])
5894 (define_insn "*cmp_cc_ashift_1"
5895   [(set (reg:CC_NOOV CC_REG)
5896         (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
5897                                     (const_int 1))
5898                          (const_int 0)))]
5899   ""
5900   "addcc\t%0, %0, %%g0"
5901   [(set_attr "type" "compare")])
5903 (define_insn "*cmp_cc_set_ashift_1"
5904   [(set (reg:CC_NOOV CC_REG)
5905         (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
5906                                     (const_int 1))
5907                          (const_int 0)))
5908    (set (match_operand:SI 0 "register_operand" "=r")
5909         (ashift:SI (match_dup 1) (const_int 1)))]
5910   ""
5911   "addcc\t%1, %1, %0"
5912   [(set_attr "type" "compare")])
5914 (define_insn "ashrsi3"
5915   [(set (match_operand:SI 0 "register_operand" "=r")
5916         (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5917                      (match_operand:SI 2 "arith_operand" "rI")))]
5918   ""
5919   {
5920      if (GET_CODE (operands[2]) == CONST_INT)
5921        operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5922      return "sra\t%1, %2, %0";
5923   }
5924   [(set_attr "type" "shift")])
5926 (define_insn "*ashrsi3_extend"
5927   [(set (match_operand:DI 0 "register_operand" "=r")
5928         (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5929                                      (match_operand:SI 2 "arith_operand" "r"))))]
5930   "TARGET_ARCH64"
5931   "sra\t%1, %2, %0"
5932   [(set_attr "type" "shift")])
5934 ;; This handles the case as above, but with constant shift instead of
5935 ;; register. Combiner "simplifies" it for us a little bit though.
5936 (define_insn "*ashrsi3_extend2"
5937   [(set (match_operand:DI 0 "register_operand" "=r")
5938         (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
5939                                 (const_int 32))
5940                      (match_operand:SI 2 "small_int_operand" "I")))]
5941   "TARGET_ARCH64 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64"
5943   operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
5944   return "sra\t%1, %2, %0";
5946   [(set_attr "type" "shift")])
5948 (define_expand "ashrdi3"
5949   [(set (match_operand:DI 0 "register_operand" "=r")
5950         (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5951                      (match_operand:SI 2 "arith_operand" "rI")))]
5952   "TARGET_ARCH64 || TARGET_V8PLUS"
5954   if (! TARGET_ARCH64)
5955     {
5956       if (GET_CODE (operands[2]) == CONST_INT)
5957         FAIL;   /* prefer generic code in this case */
5958       emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
5959       DONE;
5960     }
5963 (define_insn "*ashrdi3_sp64"
5964   [(set (match_operand:DI 0 "register_operand" "=r")
5965         (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5966                      (match_operand:SI 2 "arith_operand" "rI")))]
5967   "TARGET_ARCH64"
5968   
5969   {
5970     if (GET_CODE (operands[2]) == CONST_INT)
5971       operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5972     return "srax\t%1, %2, %0";
5973   }
5974   [(set_attr "type" "shift")])
5976 ;; XXX
5977 (define_insn "ashrdi3_v8plus"
5978   [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5979         (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5980                      (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5981    (clobber (match_scratch:SI 3 "=X,X,&h"))]
5982   "TARGET_V8PLUS"
5983   "* return output_v8plus_shift (insn, operands, \"srax\");"
5984   [(set_attr "type" "multi")
5985    (set_attr "length" "5,5,6")])
5987 (define_insn "lshrsi3"
5988   [(set (match_operand:SI 0 "register_operand" "=r")
5989         (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5990                      (match_operand:SI 2 "arith_operand" "rI")))]
5991   ""
5992   {
5993     if (GET_CODE (operands[2]) == CONST_INT)
5994       operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5995     return "srl\t%1, %2, %0";
5996   }
5997   [(set_attr "type" "shift")])
5999 (define_insn "*lshrsi3_extend0"
6000   [(set (match_operand:DI 0 "register_operand" "=r")
6001         (zero_extend:DI
6002           (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
6003                        (match_operand:SI 2 "arith_operand" "rI"))))]
6004   "TARGET_ARCH64"
6005   {
6006     if (GET_CODE (operands[2]) == CONST_INT)
6007       operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6008     return "srl\t%1, %2, %0";
6009   }
6010   [(set_attr "type" "shift")])
6012 ;; This handles the case where
6013 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
6014 ;; but combiner "simplifies" it for us.
6015 (define_insn "*lshrsi3_extend1"
6016   [(set (match_operand:DI 0 "register_operand" "=r")
6017         (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
6018                            (match_operand:SI 2 "arith_operand" "r")) 0)
6019                 (match_operand 3 "const_int_operand" "")))]
6020   "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff"
6021   "srl\t%1, %2, %0"
6022   [(set_attr "type" "shift")])
6024 ;; This handles the case where
6025 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
6026 ;; but combiner "simplifies" it for us.
6027 (define_insn "*lshrsi3_extend2"
6028   [(set (match_operand:DI 0 "register_operand" "=r")
6029         (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
6030                          (match_operand 2 "small_int_operand" "I")
6031                          (const_int 32)))]
6032   "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6034   operands[2] = GEN_INT (32 - INTVAL (operands[2]));
6035   return "srl\t%1, %2, %0";
6037   [(set_attr "type" "shift")])
6039 (define_expand "lshrdi3"
6040   [(set (match_operand:DI 0 "register_operand" "=r")
6041         (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6042                      (match_operand:SI 2 "arith_operand" "rI")))]
6043   "TARGET_ARCH64 || TARGET_V8PLUS"
6045   if (! TARGET_ARCH64)
6046     {
6047       if (GET_CODE (operands[2]) == CONST_INT)
6048         FAIL;
6049       emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
6050       DONE;
6051     }
6054 (define_insn "*lshrdi3_sp64"
6055   [(set (match_operand:DI 0 "register_operand" "=r")
6056         (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6057                      (match_operand:SI 2 "arith_operand" "rI")))]
6058   "TARGET_ARCH64"
6059   {
6060     if (GET_CODE (operands[2]) == CONST_INT)
6061       operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6062     return "srlx\t%1, %2, %0";
6063   }
6064   [(set_attr "type" "shift")])
6066 ;; XXX
6067 (define_insn "lshrdi3_v8plus"
6068   [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6069         (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6070                      (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6071    (clobber (match_scratch:SI 3 "=X,X,&h"))]
6072   "TARGET_V8PLUS"
6073   "* return output_v8plus_shift (insn, operands, \"srlx\");"
6074   [(set_attr "type" "multi")
6075    (set_attr "length" "5,5,6")])
6077 (define_insn ""
6078   [(set (match_operand:SI 0 "register_operand" "=r")
6079         (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6080                                              (const_int 32)) 4)
6081                      (match_operand:SI 2 "small_int_operand" "I")))]
6082   "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6084   operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6085   return "srax\t%1, %2, %0";
6087   [(set_attr "type" "shift")])
6089 (define_insn ""
6090   [(set (match_operand:SI 0 "register_operand" "=r")
6091         (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6092                                              (const_int 32)) 4)
6093                      (match_operand:SI 2 "small_int_operand" "I")))]
6094   "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6096   operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6097   return "srlx\t%1, %2, %0";
6099   [(set_attr "type" "shift")])
6101 (define_insn ""
6102   [(set (match_operand:SI 0 "register_operand" "=r")
6103         (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6104                                              (match_operand:SI 2 "small_int_operand" "I")) 4)
6105                      (match_operand:SI 3 "small_int_operand" "I")))]
6106   "TARGET_ARCH64
6107    && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6108    && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6109    && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6111   operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6113   return "srax\t%1, %2, %0";
6115   [(set_attr "type" "shift")])
6117 (define_insn ""
6118   [(set (match_operand:SI 0 "register_operand" "=r")
6119         (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6120                                              (match_operand:SI 2 "small_int_operand" "I")) 4)
6121                      (match_operand:SI 3 "small_int_operand" "I")))]
6122   "TARGET_ARCH64
6123    && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6124    && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6125    && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6127   operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6129   return "srlx\t%1, %2, %0";
6131   [(set_attr "type" "shift")])
6134 ;; Unconditional and other jump instructions.
6136 (define_expand "jump"
6137   [(set (pc) (label_ref (match_operand 0 "" "")))]
6138   "")
6140 (define_insn "*jump_ubranch"
6141   [(set (pc) (label_ref (match_operand 0 "" "")))]
6142   "! TARGET_CBCOND"
6143   "* return output_ubranch (operands[0], insn);"
6144   [(set_attr "type" "uncond_branch")])
6146 (define_insn "*jump_cbcond"
6147   [(set (pc) (label_ref (match_operand 0 "" "")))]
6148   "TARGET_CBCOND"
6149   "* return output_ubranch (operands[0], insn);"
6150   [(set_attr "type" "uncond_cbcond")])
6152 (define_expand "tablejump"
6153   [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
6154               (use (label_ref (match_operand 1 "" "")))])]
6155   ""
6157   gcc_assert (GET_MODE (operands[0]) == CASE_VECTOR_MODE);
6159   /* In pic mode, our address differences are against the base of the
6160      table.  Add that base value back in; CSE ought to be able to combine
6161      the two address loads.  */
6162   if (flag_pic)
6163     {
6164       rtx tmp, tmp2;
6165       tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
6166       tmp2 = operands[0];
6167       if (CASE_VECTOR_MODE != Pmode)
6168         tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
6169       tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
6170       operands[0] = memory_address (Pmode, tmp);
6171     }
6174 (define_insn "*tablejump_sp32"
6175   [(set (pc) (match_operand:SI 0 "address_operand" "p"))
6176    (use (label_ref (match_operand 1 "" "")))]
6177   "! TARGET_ARCH64"
6178   "jmp\t%a0%#"
6179   [(set_attr "type" "uncond_branch")])
6181 (define_insn "*tablejump_sp64"
6182   [(set (pc) (match_operand:DI 0 "address_operand" "p"))
6183    (use (label_ref (match_operand 1 "" "")))]
6184   "TARGET_ARCH64"
6185   "jmp\t%a0%#"
6186   [(set_attr "type" "uncond_branch")])
6189 ;; Jump to subroutine instructions.
6191 (define_expand "call"
6192   ;; Note that this expression is not used for generating RTL.
6193   ;; All the RTL is generated explicitly below.
6194   [(call (match_operand 0 "call_operand" "")
6195          (match_operand 3 "" "i"))]
6196   ;; operands[2] is next_arg_register
6197   ;; operands[3] is struct_value_size_rtx.
6198   ""
6200   rtx fn_rtx;
6202   gcc_assert (MEM_P (operands[0]) && GET_MODE (operands[0]) == FUNCTION_MODE);
6204   gcc_assert (GET_CODE (operands[3]) == CONST_INT);
6206   if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
6207     {
6208       /* This is really a PIC sequence.  We want to represent
6209          it as a funny jump so its delay slots can be filled. 
6211          ??? But if this really *is* a CALL, will not it clobber the
6212          call-clobbered registers?  We lose this if it is a JUMP_INSN.
6213          Why cannot we have delay slots filled if it were a CALL?  */
6215       /* We accept negative sizes for untyped calls.  */
6216       if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6217         emit_jump_insn
6218           (gen_rtx_PARALLEL
6219            (VOIDmode,
6220             gen_rtvec (3,
6221                        gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6222                        operands[3],
6223                        gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6224       else
6225         emit_jump_insn
6226           (gen_rtx_PARALLEL
6227            (VOIDmode,
6228             gen_rtvec (2,
6229                        gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6230                        gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6231       goto finish_call;
6232     }
6234   fn_rtx = operands[0];
6236   /* We accept negative sizes for untyped calls.  */
6237   if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6238     sparc_emit_call_insn
6239       (gen_rtx_PARALLEL
6240        (VOIDmode,
6241         gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6242                    operands[3],
6243                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6244        XEXP (fn_rtx, 0));
6245   else
6246     sparc_emit_call_insn
6247       (gen_rtx_PARALLEL
6248        (VOIDmode,
6249         gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6250                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6251        XEXP (fn_rtx, 0));
6253  finish_call:
6255   DONE;
6258 ;; We can't use the same pattern for these two insns, because then registers
6259 ;; in the address may not be properly reloaded.
6261 (define_insn "*call_address_sp32"
6262   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6263          (match_operand 1 "" ""))
6264    (clobber (reg:SI O7_REG))]
6265   ;;- Do not use operand 1 for most machines.
6266   "! TARGET_ARCH64"
6267   "call\t%a0, %1%#"
6268   [(set_attr "type" "call")])
6270 (define_insn "*call_symbolic_sp32"
6271   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6272          (match_operand 1 "" ""))
6273    (clobber (reg:SI O7_REG))]
6274   ;;- Do not use operand 1 for most machines.
6275   "! TARGET_ARCH64"
6276   "call\t%a0, %1%#"
6277   [(set_attr "type" "call")])
6279 (define_insn "*call_address_sp64"
6280   [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
6281          (match_operand 1 "" ""))
6282    (clobber (reg:DI O7_REG))]
6283   ;;- Do not use operand 1 for most machines.
6284   "TARGET_ARCH64"
6285   "call\t%a0, %1%#"
6286   [(set_attr "type" "call")])
6288 (define_insn "*call_symbolic_sp64"
6289   [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6290          (match_operand 1 "" ""))
6291    (clobber (reg:DI O7_REG))]
6292   ;;- Do not use operand 1 for most machines.
6293   "TARGET_ARCH64"
6294   "call\t%a0, %1%#"
6295   [(set_attr "type" "call")])
6297 ;; This is a call that wants a structure value.
6298 ;; There is no such critter for v9 (??? we may need one anyway).
6299 (define_insn "*call_address_struct_value_sp32"
6300   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6301          (match_operand 1 "" ""))
6302    (match_operand 2 "immediate_operand" "")
6303    (clobber (reg:SI O7_REG))]
6304   ;;- Do not use operand 1 for most machines.
6305   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6307   operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6308   return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6310   [(set_attr "type" "call_no_delay_slot")
6311    (set_attr "length" "3")])
6313 ;; This is a call that wants a structure value.
6314 ;; There is no such critter for v9 (??? we may need one anyway).
6315 (define_insn "*call_symbolic_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"
6323   operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6324   return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6326   [(set_attr "type" "call_no_delay_slot")
6327    (set_attr "length" "3")])
6329 ;; This is a call that may want a structure value.  This is used for
6330 ;; untyped_calls.
6331 (define_insn "*call_address_untyped_struct_value_sp32"
6332   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6333          (match_operand 1 "" ""))
6334    (match_operand 2 "immediate_operand" "")
6335    (clobber (reg:SI O7_REG))]
6336   ;;- Do not use operand 1 for most machines.
6337   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6338   "call\t%a0, %1\n\t nop\n\tnop"
6339   [(set_attr "type" "call_no_delay_slot")
6340    (set_attr "length" "3")])
6342 ;; This is a call that may want a structure value.  This is used for
6343 ;; untyped_calls.
6344 (define_insn "*call_symbolic_untyped_struct_value_sp32"
6345   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6346          (match_operand 1 "" ""))
6347    (match_operand 2 "immediate_operand" "")
6348    (clobber (reg:SI O7_REG))]
6349   ;;- Do not use operand 1 for most machines.
6350   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6351   "call\t%a0, %1\n\t nop\n\tnop"
6352   [(set_attr "type" "call_no_delay_slot")
6353    (set_attr "length" "3")])
6355 (define_expand "call_value"
6356   ;; Note that this expression is not used for generating RTL.
6357   ;; All the RTL is generated explicitly below.
6358   [(set (match_operand 0 "register_operand" "=rf")
6359         (call (match_operand 1 "" "")
6360               (match_operand 4 "" "")))]
6361   ;; operand 2 is stack_size_rtx
6362   ;; operand 3 is next_arg_register
6363   ""
6365   rtx fn_rtx;
6366   rtvec vec;
6368   gcc_assert (MEM_P (operands[1]) && GET_MODE (operands[1]) == FUNCTION_MODE);
6370   fn_rtx = operands[1];
6372   vec = gen_rtvec (2,
6373                    gen_rtx_SET (VOIDmode, operands[0],
6374                                 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
6375                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
6377   sparc_emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec), XEXP (fn_rtx, 0));
6379   DONE;
6382 (define_insn "*call_value_address_sp32"
6383   [(set (match_operand 0 "" "=rf")
6384         (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
6385               (match_operand 2 "" "")))
6386    (clobber (reg:SI O7_REG))]
6387   ;;- Do not use operand 2 for most machines.
6388   "! TARGET_ARCH64"
6389   "call\t%a1, %2%#"
6390   [(set_attr "type" "call")])
6392 (define_insn "*call_value_symbolic_sp32"
6393   [(set (match_operand 0 "" "=rf")
6394         (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6395               (match_operand 2 "" "")))
6396    (clobber (reg:SI O7_REG))]
6397   ;;- Do not use operand 2 for most machines.
6398   "! TARGET_ARCH64"
6399   "call\t%a1, %2%#"
6400   [(set_attr "type" "call")])
6402 (define_insn "*call_value_address_sp64"
6403   [(set (match_operand 0 "" "")
6404         (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
6405               (match_operand 2 "" "")))
6406    (clobber (reg:DI O7_REG))]
6407   ;;- Do not use operand 2 for most machines.
6408   "TARGET_ARCH64"
6409   "call\t%a1, %2%#"
6410   [(set_attr "type" "call")])
6412 (define_insn "*call_value_symbolic_sp64"
6413   [(set (match_operand 0 "" "")
6414         (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6415               (match_operand 2 "" "")))
6416    (clobber (reg:DI O7_REG))]
6417   ;;- Do not use operand 2 for most machines.
6418   "TARGET_ARCH64"
6419   "call\t%a1, %2%#"
6420   [(set_attr "type" "call")])
6422 (define_expand "untyped_call"
6423   [(parallel [(call (match_operand 0 "" "")
6424                     (const_int 0))
6425               (match_operand:BLK 1 "memory_operand" "")
6426               (match_operand 2 "" "")])]
6427   ""
6429   rtx valreg1 = gen_rtx_REG (DImode, 8);
6430   rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6431   rtx result = operands[1];
6433   /* Pass constm1 to indicate that it may expect a structure value, but
6434      we don't know what size it is.  */
6435   emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
6437   /* Save the function value registers.  */
6438   emit_move_insn (adjust_address (result, DImode, 0), valreg1);
6439   emit_move_insn (adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8),
6440                                   valreg2);
6442   /* The optimizer does not know that the call sets the function value
6443      registers we stored in the result block.  We avoid problems by
6444      claiming that all hard registers are used and clobbered at this
6445      point.  */
6446   emit_insn (gen_blockage ());
6448   DONE;
6451 ;;  Tail call instructions.
6453 (define_expand "sibcall"
6454   [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
6455               (return)])]
6456   ""
6457   "")
6459 (define_insn "*sibcall_symbolic_sp32"
6460   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6461          (match_operand 1 "" ""))
6462    (return)]
6463   "! TARGET_ARCH64"
6464   "* return output_sibcall(insn, operands[0]);"
6465   [(set_attr "type" "sibcall")])
6467 (define_insn "*sibcall_symbolic_sp64"
6468   [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6469          (match_operand 1 "" ""))
6470    (return)]
6471   "TARGET_ARCH64"
6472   "* return output_sibcall(insn, operands[0]);"
6473   [(set_attr "type" "sibcall")])
6475 (define_expand "sibcall_value"
6476   [(parallel [(set (match_operand 0 "register_operand" "=rf")
6477                 (call (match_operand 1 "" "") (const_int 0)))
6478               (return)])]
6479   ""
6480   "")
6482 (define_insn "*sibcall_value_symbolic_sp32"
6483   [(set (match_operand 0 "" "=rf")
6484         (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6485               (match_operand 2 "" "")))
6486    (return)]
6487   "! TARGET_ARCH64"
6488   "* return output_sibcall(insn, operands[1]);"
6489   [(set_attr "type" "sibcall")])
6491 (define_insn "*sibcall_value_symbolic_sp64"
6492   [(set (match_operand 0 "" "")
6493         (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6494               (match_operand 2 "" "")))
6495    (return)]
6496   "TARGET_ARCH64"
6497   "* return output_sibcall(insn, operands[1]);"
6498   [(set_attr "type" "sibcall")])
6501 ;; Special instructions.
6503 (define_expand "prologue"
6504   [(const_int 0)]
6505   ""
6507   if (TARGET_FLAT)
6508     sparc_flat_expand_prologue ();
6509   else
6510     sparc_expand_prologue ();
6511   DONE;
6514 ;; The "register window save" insn is modelled as follows.  The dwarf2
6515 ;; information is manually added in emit_window_save.
6517 (define_insn "window_save"
6518   [(unspec_volatile
6519         [(match_operand 0 "arith_operand" "rI")]
6520         UNSPECV_SAVEW)]
6521   "!TARGET_FLAT"
6522   "save\t%%sp, %0, %%sp"
6523   [(set_attr "type" "savew")])
6525 (define_expand "epilogue"
6526   [(return)]
6527   ""
6529   if (TARGET_FLAT)
6530     sparc_flat_expand_epilogue (false);
6531   else
6532     sparc_expand_epilogue (false);
6535 (define_expand "sibcall_epilogue"
6536   [(return)]
6537   ""
6539   if (TARGET_FLAT)
6540     sparc_flat_expand_epilogue (false);
6541   else
6542     sparc_expand_epilogue (false);
6543   DONE;
6546 (define_expand "eh_return"
6547   [(use (match_operand 0 "general_operand" ""))]
6548   ""
6550   emit_move_insn (gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM), operands[0]);
6551   emit_jump_insn (gen_eh_return_internal ());
6552   emit_barrier ();
6553   DONE;
6556 (define_insn_and_split "eh_return_internal"
6557   [(eh_return)]
6558   ""
6559   "#"
6560   "epilogue_completed"
6561   [(return)]
6563   if (TARGET_FLAT)
6564     sparc_flat_expand_epilogue (true);
6565   else
6566     sparc_expand_epilogue (true);
6569 (define_expand "return"
6570   [(return)]
6571   "sparc_can_use_return_insn_p ()"
6572   "")
6574 (define_insn "*return_internal"
6575   [(return)]
6576   ""
6577   "* return output_return (insn);"
6578   [(set_attr "type" "return")
6579    (set (attr "length")
6580         (cond [(eq_attr "calls_eh_return" "true")
6581                  (if_then_else (eq_attr "delayed_branch" "true")
6582                                 (if_then_else (ior (eq_attr "isa" "v9")
6583                                                    (eq_attr "flat" "true"))
6584                                         (const_int 2)
6585                                         (const_int 3))
6586                                 (if_then_else (eq_attr "flat" "true")
6587                                         (const_int 3)
6588                                         (const_int 4)))
6589                (ior (eq_attr "leaf_function" "true") (eq_attr "flat" "true"))
6590                  (if_then_else (eq_attr "empty_delay_slot" "true")
6591                                (const_int 2)
6592                                (const_int 1))
6593                (eq_attr "empty_delay_slot" "true")
6594                  (if_then_else (eq_attr "delayed_branch" "true")
6595                                (const_int 2)
6596                                (const_int 3))
6597               ] (const_int 1)))])
6599 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
6600 ;; all of memory.  This blocks insns from being moved across this point.
6602 (define_insn "blockage"
6603   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
6604   ""
6605   ""
6606   [(set_attr "length" "0")])
6608 ;; Do not schedule instructions accessing memory before this point.
6610 (define_expand "frame_blockage"
6611   [(set (match_dup 0)
6612         (unspec:BLK [(match_dup 1)] UNSPEC_FRAME_BLOCKAGE))]
6613   ""
6615   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
6616   MEM_VOLATILE_P (operands[0]) = 1;
6617   operands[1] = stack_pointer_rtx;
6620 (define_insn "*frame_blockage<P:mode>"
6621   [(set (match_operand:BLK 0 "" "")
6622         (unspec:BLK [(match_operand:P 1 "" "")] UNSPEC_FRAME_BLOCKAGE))]
6623   ""
6624   ""
6625   [(set_attr "length" "0")])
6627 (define_expand "probe_stack"
6628   [(set (match_operand 0 "memory_operand" "") (const_int 0))]
6629   ""
6631   operands[0]
6632     = adjust_address (operands[0], GET_MODE (operands[0]), SPARC_STACK_BIAS);
6635 (define_insn "probe_stack_range<P:mode>"
6636   [(set (match_operand:P 0 "register_operand" "=r")
6637         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
6638                             (match_operand:P 2 "register_operand" "r")]
6639                             UNSPECV_PROBE_STACK_RANGE))]
6640   ""
6641   "* return output_probe_stack_range (operands[0], operands[2]);"
6642   [(set_attr "type" "multi")])
6644 ;; Prepare to return any type including a structure value.
6646 (define_expand "untyped_return"
6647   [(match_operand:BLK 0 "memory_operand" "")
6648    (match_operand 1 "" "")]
6649   ""
6651   rtx valreg1 = gen_rtx_REG (DImode, 24);
6652   rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6653   rtx result = operands[0];
6655   if (! TARGET_ARCH64)
6656     {
6657       rtx rtnreg = gen_rtx_REG (SImode, RETURN_ADDR_REGNUM);
6658       rtx value = gen_reg_rtx (SImode);
6660       /* Fetch the instruction where we will return to and see if it's an unimp
6661          instruction (the most significant 10 bits will be zero).  If so,
6662          update the return address to skip the unimp instruction.  */
6663       emit_move_insn (value,
6664                       gen_rtx_MEM (SImode, plus_constant (SImode, rtnreg, 8)));
6665       emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
6666       emit_insn (gen_update_return (rtnreg, value));
6667     }
6669   /* Reload the function value registers.  */
6670   emit_move_insn (valreg1, adjust_address (result, DImode, 0));
6671   emit_move_insn (valreg2,
6672                   adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
6674   /* Put USE insns before the return.  */
6675   emit_use (valreg1);
6676   emit_use (valreg2);
6678   /* Construct the return.  */
6679   expand_naked_return ();
6681   DONE;
6684 ;; Adjust the return address conditionally. If the value of op1 is equal
6685 ;; to all zero then adjust the return address i.e. op0 = op0 + 4.
6686 ;; This is technically *half* the check required by the 32-bit SPARC
6687 ;; psABI. This check only ensures that an "unimp" insn was written by
6688 ;; the caller, but doesn't check to see if the expected size matches
6689 ;; (this is encoded in the 12 lower bits). This check is obsolete and
6690 ;; only used by the above code "untyped_return".
6692 (define_insn "update_return"
6693   [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
6694                (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
6695   "! TARGET_ARCH64"
6697   if (flag_delayed_branch)
6698     return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
6699   else
6700     return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
6702   [(set (attr "type") (const_string "multi"))
6703    (set (attr "length")
6704         (if_then_else (eq_attr "delayed_branch" "true")
6705                       (const_int 3)
6706                       (const_int 4)))])
6708 (define_insn "nop"
6709   [(const_int 0)]
6710   ""
6711   "nop")
6713 (define_expand "indirect_jump"
6714   [(set (pc) (match_operand 0 "address_operand" "p"))]
6715   ""
6716   "")
6718 (define_insn "*branch_sp32"
6719   [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
6720   "! TARGET_ARCH64"
6721  "jmp\t%a0%#"
6722  [(set_attr "type" "uncond_branch")])
6724 (define_insn "*branch_sp64"
6725   [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
6726   "TARGET_ARCH64"
6727   "jmp\t%a0%#"
6728   [(set_attr "type" "uncond_branch")])
6730 (define_expand "save_stack_nonlocal"
6731   [(set (match_operand 0 "memory_operand" "")
6732         (match_operand 1 "register_operand" ""))
6733    (set (match_dup 2) (match_dup 3))]
6734   ""
6736   operands[0] = adjust_address_nv (operands[0], Pmode, 0);
6737   operands[2] = adjust_address_nv (operands[0], Pmode, GET_MODE_SIZE (Pmode));
6738   operands[3] = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
6741 (define_expand "restore_stack_nonlocal"
6742   [(set (match_operand 0 "register_operand" "")
6743         (match_operand 1 "memory_operand" ""))]
6744   ""
6746   operands[1] = adjust_address_nv (operands[1], Pmode, 0);
6749 (define_expand "nonlocal_goto"
6750   [(match_operand 0 "general_operand" "")
6751    (match_operand 1 "general_operand" "")
6752    (match_operand 2 "memory_operand" "")
6753    (match_operand 3 "memory_operand" "")]
6754   ""
6756   rtx i7 = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
6757   rtx r_label = copy_to_reg (operands[1]);
6758   rtx r_sp = adjust_address_nv (operands[2], Pmode, 0);
6759   rtx r_fp = operands[3];
6760   rtx r_i7 = adjust_address_nv (operands[2], Pmode, GET_MODE_SIZE (Pmode));
6762   /* We need to flush all the register windows so that their contents will
6763      be re-synchronized by the restore insn of the target function.  */
6764   if (!TARGET_FLAT)
6765     emit_insn (gen_flush_register_windows ());
6767   emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
6768   emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
6770   /* Restore frame pointer for containing function.  */
6771   emit_move_insn (hard_frame_pointer_rtx, r_fp);
6772   emit_stack_restore (SAVE_NONLOCAL, r_sp);
6773   emit_move_insn (i7, r_i7);
6775   /* USE of hard_frame_pointer_rtx added for consistency;
6776      not clear if really needed.  */
6777   emit_use (hard_frame_pointer_rtx);
6778   emit_use (stack_pointer_rtx);
6779   emit_use (i7);
6781   emit_jump_insn (gen_indirect_jump (r_label));
6782   emit_barrier ();
6783   DONE;
6786 (define_expand "builtin_setjmp_receiver"
6787   [(label_ref (match_operand 0 "" ""))]
6788   "flag_pic"
6790   load_got_register ();
6791   DONE;
6794 ;; Special insn to flush register windows.
6796 (define_insn "flush_register_windows"
6797   [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
6798   ""
6799   { return TARGET_V9 ? "flushw" : "ta\t3"; }
6800   [(set_attr "type" "flushw")])
6802 ;; Special pattern for the FLUSH instruction.
6804 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
6805 ; of the define_insn otherwise missing a mode.  We make "flush", aka
6806 ; gen_flush, the default one since sparc_initialize_trampoline uses
6807 ; it on SImode mem values.
6809 (define_insn "flush"
6810   [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
6811   ""
6812   { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
6813   [(set_attr "type" "iflush")])
6815 (define_insn "flushdi"
6816   [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
6817   ""
6818   { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
6819   [(set_attr "type" "iflush")])
6822 ;; Find first set instructions.
6824 ;; The scan instruction searches from the most significant bit while ffs
6825 ;; searches from the least significant bit.  The bit index and treatment of
6826 ;; zero also differ.  It takes at least 7 instructions to get the proper
6827 ;; result.  Here is an obvious 8 instruction sequence.
6829 ;; XXX
6830 (define_insn "ffssi2"
6831   [(set (match_operand:SI 0 "register_operand" "=&r")
6832         (ffs:SI (match_operand:SI 1 "register_operand" "r")))
6833    (clobber (match_scratch:SI 2 "=&r"))]
6834   "TARGET_SPARCLITE || TARGET_SPARCLET"
6836   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";
6838   [(set_attr "type" "multi")
6839    (set_attr "length" "8")])
6841 (define_expand "popcountdi2"
6842   [(set (match_operand:DI 0 "register_operand" "")
6843         (popcount:DI (match_operand:DI 1 "register_operand" "")))]
6844   "TARGET_POPC"
6846   if (! TARGET_ARCH64)
6847     {
6848       emit_insn (gen_popcountdi_v8plus (operands[0], operands[1]));
6849       DONE;
6850     }
6853 (define_insn "*popcountdi_sp64"
6854   [(set (match_operand:DI 0 "register_operand" "=r")
6855         (popcount:DI (match_operand:DI 1 "register_operand" "r")))]
6856   "TARGET_POPC && TARGET_ARCH64"
6857   "popc\t%1, %0")
6859 (define_insn "popcountdi_v8plus"
6860   [(set (match_operand:DI 0 "register_operand" "=r")
6861         (popcount:DI (match_operand:DI 1 "register_operand" "r")))
6862    (clobber (match_scratch:SI 2 "=&h"))]
6863   "TARGET_POPC && ! TARGET_ARCH64"
6865   if (sparc_check_64 (operands[1], insn) <= 0)
6866     output_asm_insn ("srl\t%L1, 0, %L1", operands);
6867   return "sllx\t%H1, 32, %2\n\tor\t%L1, %2, %2\n\tpopc\t%2, %L0\n\tclr\t%H0";
6869   [(set_attr "type" "multi")
6870    (set_attr "length" "5")])
6872 (define_expand "popcountsi2"
6873   [(set (match_dup 2)
6874         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
6875    (set (match_operand:SI 0 "register_operand" "")
6876         (truncate:SI (popcount:DI (match_dup 2))))]
6877   "TARGET_POPC"
6879   if (! TARGET_ARCH64)
6880     {
6881       emit_insn (gen_popcountsi_v8plus (operands[0], operands[1]));
6882       DONE;
6883     }
6884   else
6885     operands[2] = gen_reg_rtx (DImode);
6888 (define_insn "*popcountsi_sp64"
6889   [(set (match_operand:SI 0 "register_operand" "=r")
6890         (truncate:SI
6891           (popcount:DI (match_operand:DI 1 "register_operand" "r"))))]
6892   "TARGET_POPC && TARGET_ARCH64"
6893   "popc\t%1, %0")
6895 (define_insn "popcountsi_v8plus"
6896   [(set (match_operand:SI 0 "register_operand" "=r")
6897         (popcount:SI (match_operand:SI 1 "register_operand" "r")))]
6898   "TARGET_POPC && ! TARGET_ARCH64"
6900   if (sparc_check_64 (operands[1], insn) <= 0)
6901     output_asm_insn ("srl\t%1, 0, %1", operands);
6902   return "popc\t%1, %0";
6904   [(set_attr "type" "multi")
6905    (set_attr "length" "2")])
6907 (define_expand "clzdi2"
6908   [(set (match_operand:DI 0 "register_operand" "")
6909         (clz:DI (match_operand:DI 1 "register_operand" "")))]
6910   "TARGET_VIS3"
6912   if (! TARGET_ARCH64)
6913     {
6914       emit_insn (gen_clzdi_v8plus (operands[0], operands[1]));
6915       DONE;
6916     }
6919 (define_insn "*clzdi_sp64"
6920   [(set (match_operand:DI 0 "register_operand" "=r")
6921         (clz:DI (match_operand:DI 1 "register_operand" "r")))]
6922   "TARGET_VIS3 && TARGET_ARCH64"
6923   "lzd\t%1, %0")
6925 (define_insn "clzdi_v8plus"
6926   [(set (match_operand:DI 0 "register_operand" "=r")
6927         (clz:DI (match_operand:DI 1 "register_operand" "r")))
6928    (clobber (match_scratch:SI 2 "=&h"))]
6929   "TARGET_VIS3 && ! TARGET_ARCH64"
6931   if (sparc_check_64 (operands[1], insn) <= 0)
6932     output_asm_insn ("srl\t%L1, 0, %L1", operands);
6933   return "sllx\t%H1, 32, %2\n\tor\t%L1, %2, %2\n\tlzd\t%2, %L0\n\tclr\t%H0";
6935   [(set_attr "type" "multi")
6936    (set_attr "length" "5")])
6938 (define_expand "clzsi2"
6939   [(set (match_dup 2)
6940         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
6941    (set (match_dup 3)
6942         (truncate:SI (clz:DI (match_dup 2))))
6943    (set (match_operand:SI 0 "register_operand" "")
6944         (minus:SI (match_dup 3) (const_int 32)))]
6945   "TARGET_VIS3"
6947   if (! TARGET_ARCH64)
6948     {
6949       emit_insn (gen_clzsi_v8plus (operands[0], operands[1]));
6950       DONE;
6951     }
6952   else
6953     {
6954       operands[2] = gen_reg_rtx (DImode);
6955       operands[3] = gen_reg_rtx (SImode);
6956     }
6959 (define_insn "*clzsi_sp64"
6960   [(set (match_operand:SI 0 "register_operand" "=r")
6961         (truncate:SI
6962           (clz:DI (match_operand:DI 1 "register_operand" "r"))))]
6963   "TARGET_VIS3 && TARGET_ARCH64"
6964   "lzd\t%1, %0")
6966 (define_insn "clzsi_v8plus"
6967   [(set (match_operand:SI 0 "register_operand" "=r")
6968         (clz:SI (match_operand:SI 1 "register_operand" "r")))]
6969   "TARGET_VIS3 && ! TARGET_ARCH64"
6971   if (sparc_check_64 (operands[1], insn) <= 0)
6972     output_asm_insn ("srl\t%1, 0, %1", operands);
6973   return "lzd\t%1, %0\n\tsub\t%0, 32, %0";
6975   [(set_attr "type" "multi")
6976    (set_attr "length" "3")])
6979 ;; Peepholes go at the end.
6981 ;; Optimize consecutive loads or stores into ldd and std when possible.
6982 ;; The conditions in which we do this are very restricted and are 
6983 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
6985 (define_peephole2
6986   [(set (match_operand:SI 0 "memory_operand" "")
6987       (const_int 0))
6988    (set (match_operand:SI 1 "memory_operand" "")
6989       (const_int 0))]
6990   "TARGET_V9
6991    && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
6992   [(set (match_dup 0)
6993        (const_int 0))]
6994   "operands[0] = widen_memory_access (operands[0], DImode, 0);")
6996 (define_peephole2
6997   [(set (match_operand:SI 0 "memory_operand" "")
6998       (const_int 0))
6999    (set (match_operand:SI 1 "memory_operand" "")
7000       (const_int 0))]
7001   "TARGET_V9
7002    && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
7003   [(set (match_dup 1)
7004        (const_int 0))]
7005   "operands[1] = widen_memory_access (operands[1], DImode, 0);")
7007 (define_peephole2
7008   [(set (match_operand:SI 0 "register_operand" "")
7009         (match_operand:SI 1 "memory_operand" ""))
7010    (set (match_operand:SI 2 "register_operand" "")
7011         (match_operand:SI 3 "memory_operand" ""))]
7012   "registers_ok_for_ldd_peep (operands[0], operands[2]) 
7013    && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])" 
7014   [(set (match_dup 0)
7015         (match_dup 1))]
7016   "operands[1] = widen_memory_access (operands[1], DImode, 0);
7017    operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
7019 (define_peephole2
7020   [(set (match_operand:SI 0 "memory_operand" "")
7021         (match_operand:SI 1 "register_operand" ""))
7022    (set (match_operand:SI 2 "memory_operand" "")
7023         (match_operand:SI 3 "register_operand" ""))]
7024   "registers_ok_for_ldd_peep (operands[1], operands[3]) 
7025    && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7026   [(set (match_dup 0)
7027         (match_dup 1))]
7028   "operands[0] = widen_memory_access (operands[0], DImode, 0);
7029    operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
7031 (define_peephole2
7032   [(set (match_operand:SF 0 "register_operand" "")
7033         (match_operand:SF 1 "memory_operand" ""))
7034    (set (match_operand:SF 2 "register_operand" "")
7035         (match_operand:SF 3 "memory_operand" ""))]
7036   "registers_ok_for_ldd_peep (operands[0], operands[2]) 
7037    && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
7038   [(set (match_dup 0)
7039         (match_dup 1))]
7040   "operands[1] = widen_memory_access (operands[1], DFmode, 0);
7041    operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
7043 (define_peephole2
7044   [(set (match_operand:SF 0 "memory_operand" "")
7045         (match_operand:SF 1 "register_operand" ""))
7046    (set (match_operand:SF 2 "memory_operand" "")
7047         (match_operand:SF 3 "register_operand" ""))]
7048   "registers_ok_for_ldd_peep (operands[1], operands[3]) 
7049   && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7050   [(set (match_dup 0)
7051         (match_dup 1))]
7052   "operands[0] = widen_memory_access (operands[0], DFmode, 0);
7053    operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
7055 (define_peephole2
7056   [(set (match_operand:SI 0 "register_operand" "")
7057         (match_operand:SI 1 "memory_operand" ""))
7058    (set (match_operand:SI 2 "register_operand" "")
7059         (match_operand:SI 3 "memory_operand" ""))]
7060   "registers_ok_for_ldd_peep (operands[2], operands[0]) 
7061   && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
7062   [(set (match_dup 2)
7063         (match_dup 3))]
7064    "operands[3] = widen_memory_access (operands[3], DImode, 0);
7065     operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
7067 (define_peephole2
7068   [(set (match_operand:SI 0 "memory_operand" "")
7069         (match_operand:SI 1 "register_operand" ""))
7070    (set (match_operand:SI 2 "memory_operand" "")
7071         (match_operand:SI 3 "register_operand" ""))]
7072   "registers_ok_for_ldd_peep (operands[3], operands[1]) 
7073   && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)" 
7074   [(set (match_dup 2)
7075         (match_dup 3))]
7076   "operands[2] = widen_memory_access (operands[2], DImode, 0);
7077    operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
7078    ")
7080 (define_peephole2
7081   [(set (match_operand:SF 0 "register_operand" "")
7082         (match_operand:SF 1 "memory_operand" ""))
7083    (set (match_operand:SF 2 "register_operand" "")
7084         (match_operand:SF 3 "memory_operand" ""))]
7085   "registers_ok_for_ldd_peep (operands[2], operands[0]) 
7086   && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
7087   [(set (match_dup 2)
7088         (match_dup 3))]
7089   "operands[3] = widen_memory_access (operands[3], DFmode, 0);
7090    operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
7092 (define_peephole2
7093   [(set (match_operand:SF 0 "memory_operand" "")
7094         (match_operand:SF 1 "register_operand" ""))
7095    (set (match_operand:SF 2 "memory_operand" "")
7096         (match_operand:SF 3 "register_operand" ""))]
7097   "registers_ok_for_ldd_peep (operands[3], operands[1]) 
7098   && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
7099   [(set (match_dup 2)
7100         (match_dup 3))]
7101   "operands[2] = widen_memory_access (operands[2], DFmode, 0);
7102    operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
7104 ;; Optimize the case of following a reg-reg move with a test
7105 ;; of reg just moved.  Don't allow floating point regs for operand 0 or 1.
7106 ;; This can result from a float to fix conversion.
7108 (define_peephole2
7109   [(set (match_operand:SI 0 "register_operand" "")
7110         (match_operand:SI 1 "register_operand" ""))
7111    (set (reg:CC CC_REG)
7112         (compare:CC (match_operand:SI 2 "register_operand" "")
7113                     (const_int 0)))]
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:CC CC_REG)
7120                    (compare:CC (match_dup 1) (const_int 0)))])]
7121   "")
7123 (define_peephole2
7124   [(set (match_operand:DI 0 "register_operand" "")
7125         (match_operand:DI 1 "register_operand" ""))
7126    (set (reg:CCX CC_REG)
7127         (compare:CCX (match_operand:DI 2 "register_operand" "")
7128                     (const_int 0)))]
7129   "TARGET_ARCH64
7130    && (rtx_equal_p (operands[2], operands[0])
7131        || rtx_equal_p (operands[2], operands[1]))
7132    && ! SPARC_FP_REG_P (REGNO (operands[0]))
7133    && ! SPARC_FP_REG_P (REGNO (operands[1]))"
7134   [(parallel [(set (match_dup 0) (match_dup 1))
7135               (set (reg:CCX CC_REG)
7136                    (compare:CCX (match_dup 1) (const_int 0)))])]
7137   "")
7140 ;; Prefetch instructions.
7142 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
7143 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
7144 ;; ??? operations.  With DFA we might be able to model this, but it requires a lot of
7145 ;; ??? state.
7146 (define_expand "prefetch"
7147   [(match_operand 0 "address_operand" "")
7148    (match_operand 1 "const_int_operand" "")
7149    (match_operand 2 "const_int_operand" "")]
7150   "TARGET_V9"
7152   if (TARGET_ARCH64)
7153     emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
7154   else
7155     emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
7156   DONE;
7159 (define_insn "prefetch_64"
7160   [(prefetch (match_operand:DI 0 "address_operand" "p")
7161              (match_operand:DI 1 "const_int_operand" "n")
7162              (match_operand:DI 2 "const_int_operand" "n"))]
7163   ""
7165   static const char * const prefetch_instr[2][2] = {
7166     {
7167       "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7168       "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7169     },
7170     {
7171       "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7172       "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7173     }
7174   };
7175   int read_or_write = INTVAL (operands[1]);
7176   int locality = INTVAL (operands[2]);
7178   gcc_assert (read_or_write == 0 || read_or_write == 1);
7179   gcc_assert (locality >= 0 && locality < 4);
7180   return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7182   [(set_attr "type" "load")])
7184 (define_insn "prefetch_32"
7185   [(prefetch (match_operand:SI 0 "address_operand" "p")
7186              (match_operand:SI 1 "const_int_operand" "n")
7187              (match_operand:SI 2 "const_int_operand" "n"))]
7188   ""
7190   static const char * const prefetch_instr[2][2] = {
7191     {
7192       "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7193       "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7194     },
7195     {
7196       "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7197       "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7198     }
7199   };
7200   int read_or_write = INTVAL (operands[1]);
7201   int locality = INTVAL (operands[2]);
7203   gcc_assert (read_or_write == 0 || read_or_write == 1);
7204   gcc_assert (locality >= 0 && locality < 4);
7205   return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7207   [(set_attr "type" "load")])
7210 ;; Trap instructions.
7212 (define_insn "trap"
7213   [(trap_if (const_int 1) (const_int 5))]
7214   ""
7215   "ta\t5"
7216   [(set_attr "type" "trap")])
7218 (define_expand "ctrapsi4"
7219   [(trap_if (match_operator 0 "noov_compare_operator"
7220              [(match_operand:SI 1 "compare_operand" "")
7221               (match_operand:SI 2 "arith_operand" "")])
7222            (match_operand 3 ""))]
7223   ""
7224   "operands[1] = gen_compare_reg (operands[0]);
7225    if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
7226      FAIL;
7227    operands[2] = const0_rtx;")
7229 (define_expand "ctrapdi4"
7230   [(trap_if (match_operator 0 "noov_compare_operator"
7231              [(match_operand:DI 1 "compare_operand" "")
7232               (match_operand:DI 2 "arith_operand" "")])
7233            (match_operand 3 ""))]
7234   "TARGET_ARCH64"
7235   "operands[1] = gen_compare_reg (operands[0]);
7236    if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
7237      FAIL;
7238    operands[2] = const0_rtx;")
7241 (define_insn ""
7242   [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CC CC_REG) (const_int 0)])
7243             (match_operand:SI 1 "arith_operand" "rM"))]
7244   ""
7246   if (TARGET_V9)
7247     return "t%C0\t%%icc, %1";
7248   else
7249     return "t%C0\t%1";
7251   [(set_attr "type" "trap")])
7253 (define_insn ""
7254   [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CCX CC_REG) (const_int 0)])
7255             (match_operand:SI 1 "arith_operand" "rM"))]
7256   "TARGET_V9"
7257   "t%C0\t%%xcc, %1"
7258   [(set_attr "type" "trap")])
7261 ;; TLS support instructions.
7263 (define_insn "tgd_hi22"
7264   [(set (match_operand:SI 0 "register_operand" "=r")
7265         (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
7266                             UNSPEC_TLSGD)))]
7267   "TARGET_TLS"
7268   "sethi\\t%%tgd_hi22(%a1), %0")
7270 (define_insn "tgd_lo10"
7271   [(set (match_operand:SI 0 "register_operand" "=r")
7272         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7273                    (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
7274                               UNSPEC_TLSGD)))]
7275   "TARGET_TLS"
7276   "add\\t%1, %%tgd_lo10(%a2), %0")
7278 (define_insn "tgd_add32"
7279   [(set (match_operand:SI 0 "register_operand" "=r")
7280         (plus:SI (match_operand:SI 1 "register_operand" "r")
7281                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7282                              (match_operand 3 "tgd_symbolic_operand" "")]
7283                             UNSPEC_TLSGD)))]
7284   "TARGET_TLS && TARGET_ARCH32"
7285   "add\\t%1, %2, %0, %%tgd_add(%a3)")
7287 (define_insn "tgd_add64"
7288   [(set (match_operand:DI 0 "register_operand" "=r")
7289         (plus:DI (match_operand:DI 1 "register_operand" "r")
7290                  (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7291                              (match_operand 3 "tgd_symbolic_operand" "")]
7292                             UNSPEC_TLSGD)))]
7293   "TARGET_TLS && TARGET_ARCH64"
7294   "add\\t%1, %2, %0, %%tgd_add(%a3)")
7296 (define_insn "tgd_call32"
7297   [(set (match_operand 0 "register_operand" "=r")
7298         (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
7299                                   (match_operand 2 "tgd_symbolic_operand" "")]
7300                                  UNSPEC_TLSGD))
7301               (match_operand 3 "" "")))
7302    (clobber (reg:SI O7_REG))]
7303   "TARGET_TLS && TARGET_ARCH32"
7304   "call\t%a1, %%tgd_call(%a2)%#"
7305   [(set_attr "type" "call")])
7307 (define_insn "tgd_call64"
7308   [(set (match_operand 0 "register_operand" "=r")
7309         (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
7310                                   (match_operand 2 "tgd_symbolic_operand" "")]
7311                                  UNSPEC_TLSGD))
7312               (match_operand 3 "" "")))
7313    (clobber (reg:DI O7_REG))]
7314   "TARGET_TLS && TARGET_ARCH64"
7315   "call\t%a1, %%tgd_call(%a2)%#"
7316   [(set_attr "type" "call")])
7318 (define_insn "tldm_hi22"
7319   [(set (match_operand:SI 0 "register_operand" "=r")
7320         (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7321   "TARGET_TLS"
7322   "sethi\\t%%tldm_hi22(%&), %0")
7324 (define_insn "tldm_lo10"
7325   [(set (match_operand:SI 0 "register_operand" "=r")
7326         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7327                     (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7328   "TARGET_TLS"
7329   "add\\t%1, %%tldm_lo10(%&), %0")
7331 (define_insn "tldm_add32"
7332   [(set (match_operand:SI 0 "register_operand" "=r")
7333         (plus:SI (match_operand:SI 1 "register_operand" "r")
7334                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
7335                             UNSPEC_TLSLDM)))]
7336   "TARGET_TLS && TARGET_ARCH32"
7337   "add\\t%1, %2, %0, %%tldm_add(%&)")
7339 (define_insn "tldm_add64"
7340   [(set (match_operand:DI 0 "register_operand" "=r")
7341         (plus:DI (match_operand:DI 1 "register_operand" "r")
7342                  (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
7343                             UNSPEC_TLSLDM)))]
7344   "TARGET_TLS && TARGET_ARCH64"
7345   "add\\t%1, %2, %0, %%tldm_add(%&)")
7347 (define_insn "tldm_call32"
7348   [(set (match_operand 0 "register_operand" "=r")
7349         (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
7350                                  UNSPEC_TLSLDM))
7351               (match_operand 2 "" "")))
7352    (clobber (reg:SI O7_REG))]
7353   "TARGET_TLS && TARGET_ARCH32"
7354   "call\t%a1, %%tldm_call(%&)%#"
7355   [(set_attr "type" "call")])
7357 (define_insn "tldm_call64"
7358   [(set (match_operand 0 "register_operand" "=r")
7359         (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
7360                                  UNSPEC_TLSLDM))
7361               (match_operand 2 "" "")))
7362    (clobber (reg:DI O7_REG))]
7363   "TARGET_TLS && TARGET_ARCH64"
7364   "call\t%a1, %%tldm_call(%&)%#"
7365   [(set_attr "type" "call")])
7367 (define_insn "tldo_hix22"
7368   [(set (match_operand:SI 0 "register_operand" "=r")
7369         (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
7370                             UNSPEC_TLSLDO)))]
7371   "TARGET_TLS"
7372   "sethi\\t%%tldo_hix22(%a1), %0")
7374 (define_insn "tldo_lox10"
7375   [(set (match_operand:SI 0 "register_operand" "=r")
7376         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7377                    (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
7378                               UNSPEC_TLSLDO)))]
7379   "TARGET_TLS"
7380   "xor\\t%1, %%tldo_lox10(%a2), %0")
7382 (define_insn "tldo_add32"
7383   [(set (match_operand:SI 0 "register_operand" "=r")
7384         (plus:SI (match_operand:SI 1 "register_operand" "r")
7385                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7386                              (match_operand 3 "tld_symbolic_operand" "")]
7387                             UNSPEC_TLSLDO)))]
7388   "TARGET_TLS && TARGET_ARCH32"
7389   "add\\t%1, %2, %0, %%tldo_add(%a3)")
7391 (define_insn "tldo_add64"
7392   [(set (match_operand:DI 0 "register_operand" "=r")
7393         (plus:DI (match_operand:DI 1 "register_operand" "r")
7394                  (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7395                              (match_operand 3 "tld_symbolic_operand" "")]
7396                             UNSPEC_TLSLDO)))]
7397   "TARGET_TLS && TARGET_ARCH64"
7398   "add\\t%1, %2, %0, %%tldo_add(%a3)")
7400 (define_insn "tie_hi22"
7401   [(set (match_operand:SI 0 "register_operand" "=r")
7402         (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
7403                             UNSPEC_TLSIE)))]
7404   "TARGET_TLS"
7405   "sethi\\t%%tie_hi22(%a1), %0")
7407 (define_insn "tie_lo10"
7408   [(set (match_operand:SI 0 "register_operand" "=r")
7409         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7410                    (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
7411                               UNSPEC_TLSIE)))]
7412   "TARGET_TLS"
7413   "add\\t%1, %%tie_lo10(%a2), %0")
7415 (define_insn "tie_ld32"
7416   [(set (match_operand:SI 0 "register_operand" "=r")
7417         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
7418                     (match_operand:SI 2 "register_operand" "r")
7419                     (match_operand 3 "tie_symbolic_operand" "")]
7420                    UNSPEC_TLSIE))]
7421   "TARGET_TLS && TARGET_ARCH32"
7422   "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
7423   [(set_attr "type" "load")])
7425 (define_insn "tie_ld64"
7426   [(set (match_operand:DI 0 "register_operand" "=r")
7427         (unspec:DI [(match_operand:DI 1 "register_operand" "r")
7428                     (match_operand:SI 2 "register_operand" "r")
7429                     (match_operand 3 "tie_symbolic_operand" "")]
7430                    UNSPEC_TLSIE))]
7431   "TARGET_TLS && TARGET_ARCH64"
7432   "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
7433   [(set_attr "type" "load")])
7435 (define_insn "tie_add32"
7436   [(set (match_operand:SI 0 "register_operand" "=r")
7437         (plus:SI (match_operand:SI 1 "register_operand" "r")
7438                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7439                              (match_operand 3 "tie_symbolic_operand" "")]
7440                             UNSPEC_TLSIE)))]
7441   "TARGET_SUN_TLS && TARGET_ARCH32"
7442   "add\\t%1, %2, %0, %%tie_add(%a3)")
7444 (define_insn "tie_add64"
7445   [(set (match_operand:DI 0 "register_operand" "=r")
7446         (plus:DI (match_operand:DI 1 "register_operand" "r")
7447                  (unspec:DI [(match_operand:DI 2 "register_operand" "r")
7448                              (match_operand 3 "tie_symbolic_operand" "")]
7449                             UNSPEC_TLSIE)))]
7450   "TARGET_SUN_TLS && TARGET_ARCH64"
7451   "add\\t%1, %2, %0, %%tie_add(%a3)")
7453 (define_insn "tle_hix22_sp32"
7454   [(set (match_operand:SI 0 "register_operand" "=r")
7455         (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
7456                             UNSPEC_TLSLE)))]
7457   "TARGET_TLS && TARGET_ARCH32"
7458   "sethi\\t%%tle_hix22(%a1), %0")
7460 (define_insn "tle_lox10_sp32"
7461   [(set (match_operand:SI 0 "register_operand" "=r")
7462         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7463                    (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
7464                               UNSPEC_TLSLE)))]
7465   "TARGET_TLS && TARGET_ARCH32"
7466   "xor\\t%1, %%tle_lox10(%a2), %0")
7468 (define_insn "tle_hix22_sp64"
7469   [(set (match_operand:DI 0 "register_operand" "=r")
7470         (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
7471                             UNSPEC_TLSLE)))]
7472   "TARGET_TLS && TARGET_ARCH64"
7473   "sethi\\t%%tle_hix22(%a1), %0")
7475 (define_insn "tle_lox10_sp64"
7476   [(set (match_operand:DI 0 "register_operand" "=r")
7477         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
7478                    (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
7479                               UNSPEC_TLSLE)))]
7480   "TARGET_TLS && TARGET_ARCH64"
7481   "xor\\t%1, %%tle_lox10(%a2), %0")
7483 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
7484 (define_insn "*tldo_ldub_sp32"
7485   [(set (match_operand:QI 0 "register_operand" "=r")
7486         (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7487                                      (match_operand 3 "tld_symbolic_operand" "")]
7488                                     UNSPEC_TLSLDO)
7489                          (match_operand:SI 1 "register_operand" "r"))))]
7490   "TARGET_TLS && TARGET_ARCH32"
7491   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7492   [(set_attr "type" "load")
7493    (set_attr "us3load_type" "3cycle")])
7495 (define_insn "*tldo_ldub1_sp32"
7496   [(set (match_operand:HI 0 "register_operand" "=r")
7497         (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7498                                                      (match_operand 3 "tld_symbolic_operand" "")]
7499                                                     UNSPEC_TLSLDO)
7500                                          (match_operand:SI 1 "register_operand" "r")))))]
7501   "TARGET_TLS && TARGET_ARCH32"
7502   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7503   [(set_attr "type" "load")
7504    (set_attr "us3load_type" "3cycle")])
7506 (define_insn "*tldo_ldub2_sp32"
7507   [(set (match_operand:SI 0 "register_operand" "=r")
7508         (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7509                                                      (match_operand 3 "tld_symbolic_operand" "")]
7510                                                     UNSPEC_TLSLDO)
7511                                          (match_operand:SI 1 "register_operand" "r")))))]
7512   "TARGET_TLS && TARGET_ARCH32"
7513   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7514   [(set_attr "type" "load")
7515    (set_attr "us3load_type" "3cycle")])
7517 (define_insn "*tldo_ldsb1_sp32"
7518   [(set (match_operand:HI 0 "register_operand" "=r")
7519         (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7520                                                      (match_operand 3 "tld_symbolic_operand" "")]
7521                                                     UNSPEC_TLSLDO)
7522                                          (match_operand:SI 1 "register_operand" "r")))))]
7523   "TARGET_TLS && TARGET_ARCH32"
7524   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7525   [(set_attr "type" "sload")
7526    (set_attr "us3load_type" "3cycle")])
7528 (define_insn "*tldo_ldsb2_sp32"
7529   [(set (match_operand:SI 0 "register_operand" "=r")
7530         (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7531                                                      (match_operand 3 "tld_symbolic_operand" "")]
7532                                                     UNSPEC_TLSLDO)
7533                                          (match_operand:SI 1 "register_operand" "r")))))]
7534   "TARGET_TLS && TARGET_ARCH32"
7535   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7536   [(set_attr "type" "sload")
7537    (set_attr "us3load_type" "3cycle")])
7539 (define_insn "*tldo_ldub_sp64"
7540   [(set (match_operand:QI 0 "register_operand" "=r")
7541         (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7542                                      (match_operand 3 "tld_symbolic_operand" "")]
7543                                     UNSPEC_TLSLDO)
7544                          (match_operand:DI 1 "register_operand" "r"))))]
7545   "TARGET_TLS && TARGET_ARCH64"
7546   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7547   [(set_attr "type" "load")
7548    (set_attr "us3load_type" "3cycle")])
7550 (define_insn "*tldo_ldub1_sp64"
7551   [(set (match_operand:HI 0 "register_operand" "=r")
7552         (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7553                                                      (match_operand 3 "tld_symbolic_operand" "")]
7554                                                     UNSPEC_TLSLDO)
7555                                          (match_operand:DI 1 "register_operand" "r")))))]
7556   "TARGET_TLS && TARGET_ARCH64"
7557   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7558   [(set_attr "type" "load")
7559    (set_attr "us3load_type" "3cycle")])
7561 (define_insn "*tldo_ldub2_sp64"
7562   [(set (match_operand:SI 0 "register_operand" "=r")
7563         (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7564                                                      (match_operand 3 "tld_symbolic_operand" "")]
7565                                                     UNSPEC_TLSLDO)
7566                                          (match_operand:DI 1 "register_operand" "r")))))]
7567   "TARGET_TLS && TARGET_ARCH64"
7568   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7569   [(set_attr "type" "load")
7570    (set_attr "us3load_type" "3cycle")])
7572 (define_insn "*tldo_ldub3_sp64"
7573   [(set (match_operand:DI 0 "register_operand" "=r")
7574         (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7575                                                      (match_operand 3 "tld_symbolic_operand" "")]
7576                                                     UNSPEC_TLSLDO)
7577                                          (match_operand:DI 1 "register_operand" "r")))))]
7578   "TARGET_TLS && TARGET_ARCH64"
7579   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7580   [(set_attr "type" "load")
7581    (set_attr "us3load_type" "3cycle")])
7583 (define_insn "*tldo_ldsb1_sp64"
7584   [(set (match_operand:HI 0 "register_operand" "=r")
7585         (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7586                                                      (match_operand 3 "tld_symbolic_operand" "")]
7587                                                     UNSPEC_TLSLDO)
7588                                          (match_operand:DI 1 "register_operand" "r")))))]
7589   "TARGET_TLS && TARGET_ARCH64"
7590   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7591   [(set_attr "type" "sload")
7592    (set_attr "us3load_type" "3cycle")])
7594 (define_insn "*tldo_ldsb2_sp64"
7595   [(set (match_operand:SI 0 "register_operand" "=r")
7596         (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7597                                                      (match_operand 3 "tld_symbolic_operand" "")]
7598                                                     UNSPEC_TLSLDO)
7599                                          (match_operand:DI 1 "register_operand" "r")))))]
7600   "TARGET_TLS && TARGET_ARCH64"
7601   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7602   [(set_attr "type" "sload")
7603    (set_attr "us3load_type" "3cycle")])
7605 (define_insn "*tldo_ldsb3_sp64"
7606   [(set (match_operand:DI 0 "register_operand" "=r")
7607         (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7608                                                      (match_operand 3 "tld_symbolic_operand" "")]
7609                                                     UNSPEC_TLSLDO)
7610                                          (match_operand:DI 1 "register_operand" "r")))))]
7611   "TARGET_TLS && TARGET_ARCH64"
7612   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7613   [(set_attr "type" "sload")
7614    (set_attr "us3load_type" "3cycle")])
7616 (define_insn "*tldo_lduh_sp32"
7617   [(set (match_operand:HI 0 "register_operand" "=r")
7618         (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7619                                      (match_operand 3 "tld_symbolic_operand" "")]
7620                                     UNSPEC_TLSLDO)
7621                          (match_operand:SI 1 "register_operand" "r"))))]
7622   "TARGET_TLS && TARGET_ARCH32"
7623   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7624   [(set_attr "type" "load")
7625    (set_attr "us3load_type" "3cycle")])
7627 (define_insn "*tldo_lduh1_sp32"
7628   [(set (match_operand:SI 0 "register_operand" "=r")
7629         (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7630                                                      (match_operand 3 "tld_symbolic_operand" "")]
7631                                                     UNSPEC_TLSLDO)
7632                                          (match_operand:SI 1 "register_operand" "r")))))]
7633   "TARGET_TLS && TARGET_ARCH32"
7634   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7635   [(set_attr "type" "load")
7636    (set_attr "us3load_type" "3cycle")])
7638 (define_insn "*tldo_ldsh1_sp32"
7639   [(set (match_operand:SI 0 "register_operand" "=r")
7640         (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7641                                                      (match_operand 3 "tld_symbolic_operand" "")]
7642                                                     UNSPEC_TLSLDO)
7643                                          (match_operand:SI 1 "register_operand" "r")))))]
7644   "TARGET_TLS && TARGET_ARCH32"
7645   "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7646   [(set_attr "type" "sload")
7647    (set_attr "us3load_type" "3cycle")])
7649 (define_insn "*tldo_lduh_sp64"
7650   [(set (match_operand:HI 0 "register_operand" "=r")
7651         (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7652                                      (match_operand 3 "tld_symbolic_operand" "")]
7653                                     UNSPEC_TLSLDO)
7654                          (match_operand:DI 1 "register_operand" "r"))))]
7655   "TARGET_TLS && TARGET_ARCH64"
7656   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7657   [(set_attr "type" "load")
7658    (set_attr "us3load_type" "3cycle")])
7660 (define_insn "*tldo_lduh1_sp64"
7661   [(set (match_operand:SI 0 "register_operand" "=r")
7662         (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7663                                                      (match_operand 3 "tld_symbolic_operand" "")]
7664                                                     UNSPEC_TLSLDO)
7665                                          (match_operand:DI 1 "register_operand" "r")))))]
7666   "TARGET_TLS && TARGET_ARCH64"
7667   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7668   [(set_attr "type" "load")
7669    (set_attr "us3load_type" "3cycle")])
7671 (define_insn "*tldo_lduh2_sp64"
7672   [(set (match_operand:DI 0 "register_operand" "=r")
7673         (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7674                                                      (match_operand 3 "tld_symbolic_operand" "")]
7675                                                     UNSPEC_TLSLDO)
7676                                          (match_operand:DI 1 "register_operand" "r")))))]
7677   "TARGET_TLS && TARGET_ARCH64"
7678   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7679   [(set_attr "type" "load")
7680    (set_attr "us3load_type" "3cycle")])
7682 (define_insn "*tldo_ldsh1_sp64"
7683   [(set (match_operand:SI 0 "register_operand" "=r")
7684         (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7685                                                      (match_operand 3 "tld_symbolic_operand" "")]
7686                                                     UNSPEC_TLSLDO)
7687                                          (match_operand:DI 1 "register_operand" "r")))))]
7688   "TARGET_TLS && TARGET_ARCH64"
7689   "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7690   [(set_attr "type" "sload")
7691    (set_attr "us3load_type" "3cycle")])
7693 (define_insn "*tldo_ldsh2_sp64"
7694   [(set (match_operand:DI 0 "register_operand" "=r")
7695         (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7696                                                      (match_operand 3 "tld_symbolic_operand" "")]
7697                                                     UNSPEC_TLSLDO)
7698                                          (match_operand:DI 1 "register_operand" "r")))))]
7699   "TARGET_TLS && TARGET_ARCH64"
7700   "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7701   [(set_attr "type" "sload")
7702    (set_attr "us3load_type" "3cycle")])
7704 (define_insn "*tldo_lduw_sp32"
7705   [(set (match_operand:SI 0 "register_operand" "=r")
7706         (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7707                                      (match_operand 3 "tld_symbolic_operand" "")]
7708                                     UNSPEC_TLSLDO)
7709                          (match_operand:SI 1 "register_operand" "r"))))]
7710   "TARGET_TLS && TARGET_ARCH32"
7711   "ld\t[%1 + %2], %0, %%tldo_add(%3)"
7712   [(set_attr "type" "load")])
7714 (define_insn "*tldo_lduw_sp64"
7715   [(set (match_operand:SI 0 "register_operand" "=r")
7716         (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7717                                      (match_operand 3 "tld_symbolic_operand" "")]
7718                                     UNSPEC_TLSLDO)
7719                          (match_operand:DI 1 "register_operand" "r"))))]
7720   "TARGET_TLS && TARGET_ARCH64"
7721   "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7722   [(set_attr "type" "load")])
7724 (define_insn "*tldo_lduw1_sp64"
7725   [(set (match_operand:DI 0 "register_operand" "=r")
7726         (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7727                                                      (match_operand 3 "tld_symbolic_operand" "")]
7728                                                     UNSPEC_TLSLDO)
7729                                          (match_operand:DI 1 "register_operand" "r")))))]
7730   "TARGET_TLS && TARGET_ARCH64"
7731   "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7732   [(set_attr "type" "load")])
7734 (define_insn "*tldo_ldsw1_sp64"
7735   [(set (match_operand:DI 0 "register_operand" "=r")
7736         (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7737                                                      (match_operand 3 "tld_symbolic_operand" "")]
7738                                                     UNSPEC_TLSLDO)
7739                                          (match_operand:DI 1 "register_operand" "r")))))]
7740   "TARGET_TLS && TARGET_ARCH64"
7741   "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
7742   [(set_attr "type" "sload")
7743    (set_attr "us3load_type" "3cycle")])
7745 (define_insn "*tldo_ldx_sp64"
7746   [(set (match_operand:DI 0 "register_operand" "=r")
7747         (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7748                                      (match_operand 3 "tld_symbolic_operand" "")]
7749                                     UNSPEC_TLSLDO)
7750                          (match_operand:DI 1 "register_operand" "r"))))]
7751   "TARGET_TLS && TARGET_ARCH64"
7752   "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
7753   [(set_attr "type" "load")])
7755 (define_insn "*tldo_stb_sp32"
7756   [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7757                                      (match_operand 3 "tld_symbolic_operand" "")]
7758                                     UNSPEC_TLSLDO)
7759                          (match_operand:SI 1 "register_operand" "r")))
7760         (match_operand:QI 0 "register_operand" "r"))]
7761   "TARGET_TLS && TARGET_ARCH32"
7762   "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7763   [(set_attr "type" "store")])
7765 (define_insn "*tldo_stb_sp64"
7766   [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7767                                      (match_operand 3 "tld_symbolic_operand" "")]
7768                                     UNSPEC_TLSLDO)
7769                          (match_operand:DI 1 "register_operand" "r")))
7770         (match_operand:QI 0 "register_operand" "r"))]
7771   "TARGET_TLS && TARGET_ARCH64"
7772   "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7773   [(set_attr "type" "store")])
7775 (define_insn "*tldo_sth_sp32"
7776   [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7777                                      (match_operand 3 "tld_symbolic_operand" "")]
7778                                     UNSPEC_TLSLDO)
7779                          (match_operand:SI 1 "register_operand" "r")))
7780         (match_operand:HI 0 "register_operand" "r"))]
7781   "TARGET_TLS && TARGET_ARCH32"
7782   "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7783   [(set_attr "type" "store")])
7785 (define_insn "*tldo_sth_sp64"
7786   [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7787                                      (match_operand 3 "tld_symbolic_operand" "")]
7788                                     UNSPEC_TLSLDO)
7789                          (match_operand:DI 1 "register_operand" "r")))
7790         (match_operand:HI 0 "register_operand" "r"))]
7791   "TARGET_TLS && TARGET_ARCH64"
7792   "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7793   [(set_attr "type" "store")])
7795 (define_insn "*tldo_stw_sp32"
7796   [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7797                                      (match_operand 3 "tld_symbolic_operand" "")]
7798                                     UNSPEC_TLSLDO)
7799                          (match_operand:SI 1 "register_operand" "r")))
7800         (match_operand:SI 0 "register_operand" "r"))]
7801   "TARGET_TLS && TARGET_ARCH32"
7802   "st\t%0, [%1 + %2], %%tldo_add(%3)"
7803   [(set_attr "type" "store")])
7805 (define_insn "*tldo_stw_sp64"
7806   [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7807                                      (match_operand 3 "tld_symbolic_operand" "")]
7808                                     UNSPEC_TLSLDO)
7809                          (match_operand:DI 1 "register_operand" "r")))
7810         (match_operand:SI 0 "register_operand" "r"))]
7811   "TARGET_TLS && TARGET_ARCH64"
7812   "stw\t%0, [%1 + %2], %%tldo_add(%3)"
7813   [(set_attr "type" "store")])
7815 (define_insn "*tldo_stx_sp64"
7816   [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7817                                      (match_operand 3 "tld_symbolic_operand" "")]
7818                                     UNSPEC_TLSLDO)
7819                          (match_operand:DI 1 "register_operand" "r")))
7820         (match_operand:DI 0 "register_operand" "r"))]
7821   "TARGET_TLS && TARGET_ARCH64"
7822   "stx\t%0, [%1 + %2], %%tldo_add(%3)"
7823   [(set_attr "type" "store")])
7826 ;; Stack protector instructions.
7828 (define_expand "stack_protect_set"
7829   [(match_operand 0 "memory_operand" "")
7830    (match_operand 1 "memory_operand" "")]
7831   ""
7833 #ifdef TARGET_THREAD_SSP_OFFSET
7834   rtx tlsreg = gen_rtx_REG (Pmode, 7);
7835   rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7836   operands[1] = gen_rtx_MEM (Pmode, addr);
7837 #endif
7838   if (TARGET_ARCH64)
7839     emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
7840   else
7841     emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
7842   DONE;
7845 (define_insn "stack_protect_setsi"
7846   [(set (match_operand:SI 0 "memory_operand" "=m")
7847         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7848    (set (match_scratch:SI 2 "=&r") (const_int 0))]
7849   "TARGET_ARCH32"
7850   "ld\t%1, %2\;st\t%2, %0\;mov\t0, %2"
7851   [(set_attr "type" "multi")
7852    (set_attr "length" "3")])
7854 (define_insn "stack_protect_setdi"
7855   [(set (match_operand:DI 0 "memory_operand" "=m")
7856         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7857    (set (match_scratch:DI 2 "=&r") (const_int 0))]
7858   "TARGET_ARCH64"
7859   "ldx\t%1, %2\;stx\t%2, %0\;mov\t0, %2"
7860   [(set_attr "type" "multi")
7861    (set_attr "length" "3")])
7863 (define_expand "stack_protect_test"
7864   [(match_operand 0 "memory_operand" "")
7865    (match_operand 1 "memory_operand" "")
7866    (match_operand 2 "" "")]
7867   ""
7869   rtx result, test;
7870 #ifdef TARGET_THREAD_SSP_OFFSET
7871   rtx tlsreg = gen_rtx_REG (Pmode, 7);
7872   rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7873   operands[1] = gen_rtx_MEM (Pmode, addr);
7874 #endif
7875   if (TARGET_ARCH64)
7876     {
7877       result = gen_reg_rtx (Pmode);
7878       emit_insn (gen_stack_protect_testdi (result, operands[0], operands[1]));
7879       test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7880       emit_jump_insn (gen_cbranchdi4 (test, result, const0_rtx, operands[2]));
7881     }
7882   else
7883     {
7884       emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
7885       result = gen_rtx_REG (CCmode, SPARC_ICC_REG);
7886       test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7887       emit_jump_insn (gen_cbranchcc4 (test, result, const0_rtx, operands[2]));
7888     }
7889   DONE;
7892 (define_insn "stack_protect_testsi"
7893   [(set (reg:CC CC_REG)
7894         (unspec:CC [(match_operand:SI 0 "memory_operand" "m")
7895                     (match_operand:SI 1 "memory_operand" "m")]
7896                    UNSPEC_SP_TEST))
7897    (set (match_scratch:SI 3 "=r") (const_int 0))
7898    (clobber (match_scratch:SI 2 "=&r"))]
7899   "TARGET_ARCH32"
7900   "ld\t%0, %2\;ld\t%1, %3\;xorcc\t%2, %3, %2\;mov\t0, %3"
7901   [(set_attr "type" "multi")
7902    (set_attr "length" "4")])
7904 (define_insn "stack_protect_testdi"
7905   [(set (match_operand:DI 0 "register_operand" "=&r")
7906         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
7907                     (match_operand:DI 2 "memory_operand" "m")]
7908                    UNSPEC_SP_TEST))
7909    (set (match_scratch:DI 3 "=r") (const_int 0))]
7910   "TARGET_ARCH64"
7911   "ldx\t%1, %0\;ldx\t%2, %3\;xor\t%0, %3, %0\;mov\t0, %3"
7912   [(set_attr "type" "multi")
7913    (set_attr "length" "4")])
7915 ;; Vector instructions.
7917 (define_mode_iterator VM32 [V1SI V2HI V4QI])
7918 (define_mode_iterator VM64 [V1DI V2SI V4HI V8QI])
7919 (define_mode_iterator VMALL [V1SI V2HI V4QI V1DI V2SI V4HI V8QI])
7921 (define_mode_attr vbits [(V2SI "32") (V4HI "16") (V1SI "32s") (V2HI "16s")])
7922 (define_mode_attr vconstr [(V1SI "f") (V2HI "f") (V4QI "f")
7923                            (V1DI "e") (V2SI "e") (V4HI "e") (V8QI "e")])
7924 (define_mode_attr vfptype [(V1SI "single") (V2HI "single") (V4QI "single")
7925                            (V1DI "double") (V2SI "double") (V4HI "double")
7926                            (V8QI "double")])
7928 (define_expand "mov<VMALL:mode>"
7929   [(set (match_operand:VMALL 0 "nonimmediate_operand" "")
7930         (match_operand:VMALL 1 "general_operand" ""))]
7931   "TARGET_VIS"
7933   if (sparc_expand_move (<VMALL:MODE>mode, operands))
7934     DONE;
7937 (define_insn "*mov<VM32:mode>_insn"
7938   [(set (match_operand:VM32 0 "nonimmediate_operand" "=f,f,f,f,m,m,*r, m,*r,*r, f")
7939         (match_operand:VM32 1 "input_operand"         "Y,Z,f,m,f,Y, m,*r,*r, f,*r"))]
7940   "TARGET_VIS
7941    && (register_operand (operands[0], <VM32:MODE>mode)
7942        || register_or_zero_or_all_ones_operand (operands[1], <VM32:MODE>mode))"
7943   "@
7944   fzeros\t%0
7945   fones\t%0
7946   fsrc2s\t%1, %0
7947   ld\t%1, %0
7948   st\t%1, %0
7949   st\t%r1, %0
7950   ld\t%1, %0
7951   st\t%1, %0
7952   mov\t%1, %0
7953   movstouw\t%1, %0
7954   movwtos\t%1, %0"
7955   [(set_attr "type" "visl,visl,vismv,fpload,fpstore,store,load,store,*,vismv,vismv")
7956    (set_attr "cpu_feature" "vis,vis,vis,*,*,*,*,*,*,vis3,vis3")])
7958 (define_insn "*mov<VM64:mode>_insn_sp64"
7959   [(set (match_operand:VM64 0 "nonimmediate_operand" "=e,e,e,e,m,m,*r, m,*r, e,*r")
7960         (match_operand:VM64 1 "input_operand"         "Y,C,e,m,e,Y, m,*r, e,*r,*r"))]
7961   "TARGET_VIS
7962    && TARGET_ARCH64
7963    && (register_operand (operands[0], <VM64:MODE>mode)
7964        || register_or_zero_or_all_ones_operand (operands[1], <VM64:MODE>mode))"
7965   "@
7966   fzero\t%0
7967   fone\t%0
7968   fsrc2\t%1, %0
7969   ldd\t%1, %0
7970   std\t%1, %0
7971   stx\t%r1, %0
7972   ldx\t%1, %0
7973   stx\t%1, %0
7974   movdtox\t%1, %0
7975   movxtod\t%1, %0
7976   mov\t%1, %0"
7977   [(set_attr "type" "visl,visl,vismv,fpload,fpstore,store,load,store,vismv,vismv,*")
7978    (set_attr "cpu_feature" "vis,vis,vis,*,*,*,*,*,vis3,vis3,*")])
7980 (define_insn "*mov<VM64:mode>_insn_sp32"
7981   [(set (match_operand:VM64 0 "nonimmediate_operand" "=e,e,e,*r, f,e,m,m,U,T, o,*r")
7982         (match_operand:VM64 1 "input_operand"         "Y,C,e, f,*r,m,e,Y,T,U,*r,*r"))]
7983   "TARGET_VIS
7984    && ! TARGET_ARCH64
7985    && (register_operand (operands[0], <VM64:MODE>mode)
7986        || register_or_zero_or_all_ones_operand (operands[1], <VM64:MODE>mode))"
7987   "@
7988   fzero\t%0
7989   fone\t%0
7990   fsrc2\t%1, %0
7991   #
7992   #
7993   ldd\t%1, %0
7994   std\t%1, %0
7995   stx\t%r1, %0
7996   ldd\t%1, %0
7997   std\t%1, %0
7998   #
7999   #"
8000   [(set_attr "type" "visl,visl,vismv,*,*,fpload,fpstore,store,load,store,*,*")
8001    (set_attr "length" "*,*,*,2,2,*,*,*,*,*,2,2")
8002    (set_attr "cpu_feature" "vis,vis,vis,vis3,vis3,*,*,*,*,*,*,*")])
8004 (define_split
8005   [(set (match_operand:VM64 0 "memory_operand" "")
8006         (match_operand:VM64 1 "register_operand" ""))]
8007   "reload_completed
8008    && TARGET_VIS
8009    && ! TARGET_ARCH64
8010    && (((REGNO (operands[1]) % 2) != 0)
8011        || ! mem_min_alignment (operands[0], 8))
8012    && offsettable_memref_p (operands[0])"
8013   [(clobber (const_int 0))]
8015   rtx word0, word1;
8017   word0 = adjust_address (operands[0], SImode, 0);
8018   word1 = adjust_address (operands[0], SImode, 4);
8020   emit_move_insn_1 (word0, gen_highpart (SImode, operands[1]));
8021   emit_move_insn_1 (word1, gen_lowpart (SImode, operands[1]));
8022   DONE;
8025 (define_split
8026   [(set (match_operand:VM64 0 "register_operand" "")
8027         (match_operand:VM64 1 "register_operand" ""))]
8028   "reload_completed
8029    && TARGET_VIS
8030    && ! TARGET_ARCH64
8031    && sparc_split_regreg_legitimate (operands[0], operands[1])"
8032   [(clobber (const_int 0))]
8034   rtx set_dest = operands[0];
8035   rtx set_src = operands[1];
8036   rtx dest1, dest2;
8037   rtx src1, src2;
8039   dest1 = gen_highpart (SImode, set_dest);
8040   dest2 = gen_lowpart (SImode, set_dest);
8041   src1 = gen_highpart (SImode, set_src);
8042   src2 = gen_lowpart (SImode, set_src);
8044   /* Now emit using the real source and destination we found, swapping
8045      the order if we detect overlap.  */
8046   if (reg_overlap_mentioned_p (dest1, src2))
8047     {
8048       emit_insn (gen_movsi (dest2, src2));
8049       emit_insn (gen_movsi (dest1, src1));
8050     }
8051   else
8052     {
8053       emit_insn (gen_movsi (dest1, src1));
8054       emit_insn (gen_movsi (dest2, src2));
8055     }
8056   DONE;
8059 (define_expand "vec_init<mode>"
8060   [(match_operand:VMALL 0 "register_operand" "")
8061    (match_operand:VMALL 1 "" "")]
8062   "TARGET_VIS"
8064   sparc_expand_vector_init (operands[0], operands[1]);
8065   DONE;
8068 (define_code_iterator plusminus [plus minus])
8069 (define_code_attr plusminus_insn [(plus "add") (minus "sub")])
8071 (define_mode_iterator VADDSUB [V1SI V2SI V2HI V4HI])
8073 (define_insn "<plusminus_insn><mode>3"
8074   [(set (match_operand:VADDSUB 0 "register_operand" "=<vconstr>")
8075         (plusminus:VADDSUB (match_operand:VADDSUB 1 "register_operand" "<vconstr>")
8076                            (match_operand:VADDSUB 2 "register_operand" "<vconstr>")))]
8077   "TARGET_VIS"
8078   "fp<plusminus_insn><vbits>\t%1, %2, %0"
8079   [(set_attr "type" "fga")
8080    (set_attr "fptype" "<vfptype>")])
8082 (define_mode_iterator VL [V1SI V2HI V4QI V1DI V2SI V4HI V8QI])
8083 (define_mode_attr vlsuf [(V1SI "s") (V2HI "s") (V4QI "s")
8084                          (V1DI  "") (V2SI  "") (V4HI  "") (V8QI "")])
8085 (define_code_iterator vlop [ior and xor])
8086 (define_code_attr vlinsn [(ior "or") (and "and") (xor "xor")])
8087 (define_code_attr vlninsn [(ior "nor") (and "nand") (xor "xnor")])
8089 (define_insn "<code><mode>3"
8090   [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8091         (vlop:VL (match_operand:VL 1 "register_operand" "<vconstr>")
8092                  (match_operand:VL 2 "register_operand" "<vconstr>")))]
8093   "TARGET_VIS"
8094   "f<vlinsn><vlsuf>\t%1, %2, %0"
8095   [(set_attr "type" "visl")
8096    (set_attr "fptype" "<vfptype>")])
8098 (define_insn "*not_<code><mode>3"
8099   [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8100         (not:VL (vlop:VL (match_operand:VL 1 "register_operand" "<vconstr>")
8101                          (match_operand:VL 2 "register_operand" "<vconstr>"))))]
8102   "TARGET_VIS"
8103   "f<vlninsn><vlsuf>\t%1, %2, %0"
8104   [(set_attr "type" "visl")
8105    (set_attr "fptype" "<vfptype>")])
8107 ;; (ior (not (op1)) (not (op2))) is the canonical form of NAND.
8108 (define_insn "*nand<mode>_vis"
8109   [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8110         (ior:VL (not:VL (match_operand:VL 1 "register_operand" "<vconstr>"))
8111                 (not:VL (match_operand:VL 2 "register_operand" "<vconstr>"))))]
8112   "TARGET_VIS"
8113   "fnand<vlsuf>\t%1, %2, %0"
8114   [(set_attr "type" "visl")
8115    (set_attr "fptype" "<vfptype>")])
8117 (define_code_iterator vlnotop [ior and])
8119 (define_insn "*<code>_not1<mode>_vis"
8120   [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8121         (vlnotop:VL (not:VL (match_operand:VL 1 "register_operand" "<vconstr>"))
8122                     (match_operand:VL 2 "register_operand" "<vconstr>")))]
8123   "TARGET_VIS"
8124   "f<vlinsn>not1<vlsuf>\t%1, %2, %0"
8125   [(set_attr "type" "visl")
8126    (set_attr "fptype" "<vfptype>")])
8128 (define_insn "*<code>_not2<mode>_vis"
8129   [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8130         (vlnotop:VL (match_operand:VL 1 "register_operand" "<vconstr>")
8131                     (not:VL (match_operand:VL 2 "register_operand" "<vconstr>"))))]
8132   "TARGET_VIS"
8133   "f<vlinsn>not2<vlsuf>\t%1, %2, %0"
8134   [(set_attr "type" "visl")
8135    (set_attr "fptype" "<vfptype>")])
8137 (define_insn "one_cmpl<mode>2"
8138   [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8139         (not:VL (match_operand:VL 1 "register_operand" "<vconstr>")))]
8140   "TARGET_VIS"
8141   "fnot1<vlsuf>\t%1, %0"
8142   [(set_attr "type" "visl")
8143    (set_attr "fptype" "<vfptype>")])
8145 ;; Hard to generate VIS instructions.  We have builtins for these.
8147 (define_insn "fpack16_vis"
8148   [(set (match_operand:V4QI 0 "register_operand" "=f")
8149         (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e")
8150                       (reg:DI GSR_REG)]
8151                       UNSPEC_FPACK16))]
8152   "TARGET_VIS"
8153   "fpack16\t%1, %0"
8154   [(set_attr "type" "fgm_pack")
8155    (set_attr "fptype" "double")])
8157 (define_insn "fpackfix_vis"
8158   [(set (match_operand:V2HI 0 "register_operand" "=f")
8159         (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e")
8160                       (reg:DI GSR_REG)]
8161                       UNSPEC_FPACKFIX))]
8162   "TARGET_VIS"
8163   "fpackfix\t%1, %0"
8164   [(set_attr "type" "fgm_pack")
8165    (set_attr "fptype" "double")])
8167 (define_insn "fpack32_vis"
8168   [(set (match_operand:V8QI 0 "register_operand" "=e")
8169         (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e")
8170                       (match_operand:V8QI 2 "register_operand" "e")
8171                       (reg:DI GSR_REG)]
8172                      UNSPEC_FPACK32))]
8173   "TARGET_VIS"
8174   "fpack32\t%1, %2, %0"
8175   [(set_attr "type" "fgm_pack")
8176    (set_attr "fptype" "double")])
8178 (define_insn "fexpand_vis"
8179   [(set (match_operand:V4HI 0 "register_operand" "=e")
8180         (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")]
8181          UNSPEC_FEXPAND))]
8182  "TARGET_VIS"
8183  "fexpand\t%1, %0"
8184  [(set_attr "type" "fga")
8185   (set_attr "fptype" "double")])
8187 (define_insn "fpmerge_vis"
8188   [(set (match_operand:V8QI 0 "register_operand" "=e")
8189         (vec_select:V8QI
8190           (vec_concat:V8QI (match_operand:V4QI 1 "register_operand" "f")
8191                            (match_operand:V4QI 2 "register_operand" "f"))
8192           (parallel [(const_int 0) (const_int 4)
8193                      (const_int 1) (const_int 5)
8194                      (const_int 2) (const_int 6)
8195                      (const_int 3) (const_int 7)])))]
8196  "TARGET_VIS"
8197  "fpmerge\t%1, %2, %0"
8198  [(set_attr "type" "fga")
8199   (set_attr "fptype" "double")])
8201 (define_insn "vec_interleave_lowv8qi"
8202   [(set (match_operand:V8QI 0 "register_operand" "=e")
8203         (vec_select:V8QI
8204           (vec_concat:V16QI (match_operand:V8QI 1 "register_operand" "f")
8205                             (match_operand:V8QI 2 "register_operand" "f"))
8206           (parallel [(const_int 0) (const_int 8)
8207                      (const_int 1) (const_int 9)
8208                      (const_int 2) (const_int 10)
8209                      (const_int 3) (const_int 11)])))]
8210  "TARGET_VIS"
8211  "fpmerge\t%L1, %L2, %0"
8212  [(set_attr "type" "fga")
8213   (set_attr "fptype" "double")])
8215 (define_insn "vec_interleave_highv8qi"
8216   [(set (match_operand:V8QI 0 "register_operand" "=e")
8217         (vec_select:V8QI
8218           (vec_concat:V16QI (match_operand:V8QI 1 "register_operand" "f")
8219                             (match_operand:V8QI 2 "register_operand" "f"))
8220           (parallel [(const_int 4) (const_int 12)
8221                      (const_int 5) (const_int 13)
8222                      (const_int 6) (const_int 14)
8223                      (const_int 7) (const_int 15)])))]
8224  "TARGET_VIS"
8225  "fpmerge\t%H1, %H2, %0"
8226  [(set_attr "type" "fga")
8227   (set_attr "fptype" "double")])
8229 ;; Partitioned multiply instructions
8230 (define_insn "fmul8x16_vis"
8231   [(set (match_operand:V4HI 0 "register_operand" "=e")
8232         (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8233                       (match_operand:V4HI 2 "register_operand" "e")]
8234          UNSPEC_MUL8))]
8235   "TARGET_VIS"
8236   "fmul8x16\t%1, %2, %0"
8237   [(set_attr "type" "fgm_mul")
8238    (set_attr "fptype" "double")])
8240 (define_insn "fmul8x16au_vis"
8241   [(set (match_operand:V4HI 0 "register_operand" "=e")
8242         (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8243                       (match_operand:V2HI 2 "register_operand" "f")]
8244          UNSPEC_MUL16AU))]
8245   "TARGET_VIS"
8246   "fmul8x16au\t%1, %2, %0"
8247   [(set_attr "type" "fgm_mul")
8248    (set_attr "fptype" "double")])
8250 (define_insn "fmul8x16al_vis"
8251   [(set (match_operand:V4HI 0 "register_operand" "=e")
8252         (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8253                       (match_operand:V2HI 2 "register_operand" "f")]
8254          UNSPEC_MUL16AL))]
8255   "TARGET_VIS"
8256   "fmul8x16al\t%1, %2, %0"
8257   [(set_attr "type" "fgm_mul")
8258    (set_attr "fptype" "double")])
8260 (define_insn "fmul8sux16_vis"
8261   [(set (match_operand:V4HI 0 "register_operand" "=e")
8262         (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
8263                       (match_operand:V4HI 2 "register_operand" "e")]
8264          UNSPEC_MUL8SU))]
8265   "TARGET_VIS"
8266   "fmul8sux16\t%1, %2, %0"
8267   [(set_attr "type" "fgm_mul")
8268    (set_attr "fptype" "double")])
8270 (define_insn "fmul8ulx16_vis"
8271   [(set (match_operand:V4HI 0 "register_operand" "=e")
8272         (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
8273                       (match_operand:V4HI 2 "register_operand" "e")]
8274          UNSPEC_MUL8UL))]
8275   "TARGET_VIS"
8276   "fmul8ulx16\t%1, %2, %0"
8277   [(set_attr "type" "fgm_mul")
8278    (set_attr "fptype" "double")])
8280 (define_insn "fmuld8sux16_vis"
8281   [(set (match_operand:V2SI 0 "register_operand" "=e")
8282         (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
8283                       (match_operand:V2HI 2 "register_operand" "f")]
8284          UNSPEC_MULDSU))]
8285   "TARGET_VIS"
8286   "fmuld8sux16\t%1, %2, %0"
8287   [(set_attr "type" "fgm_mul")
8288    (set_attr "fptype" "double")])
8290 (define_insn "fmuld8ulx16_vis"
8291   [(set (match_operand:V2SI 0 "register_operand" "=e")
8292         (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
8293                       (match_operand:V2HI 2 "register_operand" "f")]
8294          UNSPEC_MULDUL))]
8295   "TARGET_VIS"
8296   "fmuld8ulx16\t%1, %2, %0"
8297   [(set_attr "type" "fgm_mul")
8298    (set_attr "fptype" "double")])
8300 (define_expand "wrgsr_vis"
8301   [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" ""))]
8302   "TARGET_VIS"
8304   if (! TARGET_ARCH64)
8305     {
8306       emit_insn (gen_wrgsr_v8plus (operands[0]));
8307       DONE;
8308     }
8311 (define_insn "*wrgsr_sp64"
8312   [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" "rI"))]
8313   "TARGET_VIS && TARGET_ARCH64"
8314   "wr\t%%g0, %0, %%gsr"
8315   [(set_attr "type" "gsr")])
8317 (define_insn "wrgsr_v8plus"
8318   [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" "I,r"))
8319    (clobber (match_scratch:SI 1 "=X,&h"))]
8320   "TARGET_VIS && ! TARGET_ARCH64"
8322   if (GET_CODE (operands[0]) == CONST_INT
8323       || sparc_check_64 (operands[0], insn))
8324     return "wr\t%%g0, %0, %%gsr";
8326   output_asm_insn("srl\t%L0, 0, %L0", operands);
8327   return "sllx\t%H0, 32, %1\n\tor\t%L0, %1, %1\n\twr\t%%g0, %1, %%gsr";
8329   [(set_attr "type" "multi")])
8331 (define_expand "rdgsr_vis"
8332   [(set (match_operand:DI 0 "register_operand" "") (reg:DI GSR_REG))]
8333   "TARGET_VIS"
8335   if (! TARGET_ARCH64)
8336     {
8337       emit_insn (gen_rdgsr_v8plus (operands[0]));
8338       DONE;
8339     }
8342 (define_insn "*rdgsr_sp64"
8343   [(set (match_operand:DI 0 "register_operand" "=r") (reg:DI GSR_REG))]
8344   "TARGET_VIS && TARGET_ARCH64"
8345   "rd\t%%gsr, %0"
8346   [(set_attr "type" "gsr")])
8348 (define_insn "rdgsr_v8plus"
8349   [(set (match_operand:DI 0 "register_operand" "=r") (reg:DI GSR_REG))
8350    (clobber (match_scratch:SI 1 "=&h"))]
8351   "TARGET_VIS && ! TARGET_ARCH64"
8353   return "rd\t%%gsr, %1\n\tsrlx\t%1, 32, %H0\n\tmov %1, %L0";
8355   [(set_attr "type" "multi")])
8357 ;; Using faligndata only makes sense after an alignaddr since the choice of
8358 ;; bytes to take out of each operand is dependent on the results of the last
8359 ;; alignaddr.
8360 (define_insn "faligndata<VM64:mode>_vis"
8361   [(set (match_operand:VM64 0 "register_operand" "=e")
8362         (unspec:VM64 [(match_operand:VM64 1 "register_operand" "e")
8363                       (match_operand:VM64 2 "register_operand" "e")
8364                       (reg:DI GSR_REG)]
8365          UNSPEC_ALIGNDATA))]
8366   "TARGET_VIS"
8367   "faligndata\t%1, %2, %0"
8368   [(set_attr "type" "fga")
8369    (set_attr "fptype" "double")])
8371 (define_insn "alignaddrsi_vis"
8372   [(set (match_operand:SI 0 "register_operand" "=r")
8373         (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
8374                  (match_operand:SI 2 "register_or_zero_operand" "rJ")))
8375    (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8376         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
8377   "TARGET_VIS"
8378   "alignaddr\t%r1, %r2, %0"
8379   [(set_attr "type" "gsr")])
8381 (define_insn "alignaddrdi_vis"
8382   [(set (match_operand:DI 0 "register_operand" "=r")
8383         (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
8384                  (match_operand:DI 2 "register_or_zero_operand" "rJ")))
8385    (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8386         (plus:DI (match_dup 1) (match_dup 2)))]
8387   "TARGET_VIS"
8388   "alignaddr\t%r1, %r2, %0"
8389   [(set_attr "type" "gsr")])
8391 (define_insn "alignaddrlsi_vis"
8392   [(set (match_operand:SI 0 "register_operand" "=r")
8393         (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
8394                  (match_operand:SI 2 "register_or_zero_operand" "rJ")))
8395    (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8396         (xor:DI (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2)))
8397                 (const_int 7)))]
8398   "TARGET_VIS"
8399   "alignaddrl\t%r1, %r2, %0"
8400   [(set_attr "type" "gsr")])
8402 (define_insn "alignaddrldi_vis"
8403   [(set (match_operand:DI 0 "register_operand" "=r")
8404         (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
8405                  (match_operand:DI 2 "register_or_zero_operand" "rJ")))
8406    (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8407         (xor:DI (plus:DI (match_dup 1) (match_dup 2))
8408                 (const_int 7)))]
8409   "TARGET_VIS"
8410   "alignaddrl\t%r1, %r2, %0"
8411   [(set_attr "type" "gsr")])
8413 (define_insn "pdist_vis"
8414   [(set (match_operand:DI 0 "register_operand" "=e")
8415         (unspec:DI [(match_operand:V8QI 1 "register_operand" "e")
8416                     (match_operand:V8QI 2 "register_operand" "e")
8417                     (match_operand:DI 3 "register_operand" "0")]
8418          UNSPEC_PDIST))]
8419   "TARGET_VIS"
8420   "pdist\t%1, %2, %0"
8421   [(set_attr "type" "pdist")
8422    (set_attr "fptype" "double")])
8424 ;; Edge instructions produce condition codes equivalent to a 'subcc'
8425 ;; with the same operands.
8426 (define_insn "edge8<P:mode>_vis"
8427   [(set (reg:CC_NOOV CC_REG)
8428         (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8429                                   (match_operand:P 2 "register_or_zero_operand" "rJ"))
8430                          (const_int 0)))
8431    (set (match_operand:P 0 "register_operand" "=r")
8432         (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8))]
8433   "TARGET_VIS"
8434   "edge8\t%r1, %r2, %0"
8435   [(set_attr "type" "edge")])
8437 (define_insn "edge8l<P:mode>_vis"
8438   [(set (reg:CC_NOOV CC_REG)
8439         (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8440                                   (match_operand:P 2 "register_or_zero_operand" "rJ"))
8441                          (const_int 0)))
8442    (set (match_operand:P 0 "register_operand" "=r")
8443         (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8L))]
8444   "TARGET_VIS"
8445   "edge8l\t%r1, %r2, %0"
8446   [(set_attr "type" "edge")])
8448 (define_insn "edge16<P:mode>_vis"
8449   [(set (reg:CC_NOOV CC_REG)
8450         (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8451                                   (match_operand:P 2 "register_or_zero_operand" "rJ"))
8452                          (const_int 0)))
8453    (set (match_operand:P 0 "register_operand" "=r")
8454         (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16))]
8455   "TARGET_VIS"
8456   "edge16\t%r1, %r2, %0"
8457   [(set_attr "type" "edge")])
8459 (define_insn "edge16l<P:mode>_vis"
8460   [(set (reg:CC_NOOV CC_REG)
8461         (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8462                                   (match_operand:P 2 "register_or_zero_operand" "rJ"))
8463                          (const_int 0)))
8464    (set (match_operand:P 0 "register_operand" "=r")
8465         (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16L))]
8466   "TARGET_VIS"
8467   "edge16l\t%r1, %r2, %0"
8468   [(set_attr "type" "edge")])
8470 (define_insn "edge32<P:mode>_vis"
8471   [(set (reg:CC_NOOV CC_REG)
8472         (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8473                                   (match_operand:P 2 "register_or_zero_operand" "rJ"))
8474                          (const_int 0)))
8475    (set (match_operand:P 0 "register_operand" "=r")
8476         (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32))]
8477   "TARGET_VIS"
8478   "edge32\t%r1, %r2, %0"
8479   [(set_attr "type" "edge")])
8481 (define_insn "edge32l<P:mode>_vis"
8482   [(set (reg:CC_NOOV CC_REG)
8483         (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8484                                   (match_operand:P 2 "register_or_zero_operand" "rJ"))
8485                          (const_int 0)))
8486    (set (match_operand:P 0 "register_operand" "=r")
8487         (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32L))]
8488   "TARGET_VIS"
8489   "edge32l\t%r1, %r2, %0"
8490   [(set_attr "type" "edge")])
8492 (define_code_iterator gcond [le ne gt eq])
8493 (define_mode_iterator GCM [V4HI V2SI])
8494 (define_mode_attr gcm_name [(V4HI "16") (V2SI "32")])
8496 (define_insn "fcmp<code><GCM:gcm_name><P:mode>_vis"
8497   [(set (match_operand:P 0 "register_operand" "=r")
8498         (unspec:P [(gcond:GCM (match_operand:GCM 1 "register_operand" "e")
8499                               (match_operand:GCM 2 "register_operand" "e"))]
8500          UNSPEC_FCMP))]
8501   "TARGET_VIS"
8502   "fcmp<code><GCM:gcm_name>\t%1, %2, %0"
8503   [(set_attr "type" "visl")
8504    (set_attr "fptype" "double")])
8506 (define_expand "vcond<mode><mode>"
8507   [(match_operand:GCM 0 "register_operand" "")
8508    (match_operand:GCM 1 "register_operand" "")
8509    (match_operand:GCM 2 "register_operand" "")
8510    (match_operator 3 ""
8511      [(match_operand:GCM 4 "register_operand" "")
8512       (match_operand:GCM 5 "register_operand" "")])]
8513   "TARGET_VIS3"
8515   sparc_expand_vcond (<MODE>mode, operands,
8516                       UNSPEC_CMASK<gcm_name>,
8517                       UNSPEC_FCMP);
8518   DONE;
8521 (define_expand "vconduv8qiv8qi"
8522   [(match_operand:V8QI 0 "register_operand" "")
8523    (match_operand:V8QI 1 "register_operand" "")
8524    (match_operand:V8QI 2 "register_operand" "")
8525    (match_operator 3 ""
8526      [(match_operand:V8QI 4 "register_operand" "")
8527       (match_operand:V8QI 5 "register_operand" "")])]
8528   "TARGET_VIS3"
8530   sparc_expand_vcond (V8QImode, operands,
8531                       UNSPEC_CMASK8,
8532                       UNSPEC_FUCMP);
8533   DONE;
8536 (define_insn "array8<P:mode>_vis"
8537   [(set (match_operand:P 0 "register_operand" "=r")
8538         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8539                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
8540                   UNSPEC_ARRAY8))]
8541   "TARGET_VIS"
8542   "array8\t%r1, %r2, %0"
8543   [(set_attr "type" "array")])
8545 (define_insn "array16<P:mode>_vis"
8546   [(set (match_operand:P 0 "register_operand" "=r")
8547         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8548                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
8549                   UNSPEC_ARRAY16))]
8550   "TARGET_VIS"
8551   "array16\t%r1, %r2, %0"
8552   [(set_attr "type" "array")])
8554 (define_insn "array32<P:mode>_vis"
8555   [(set (match_operand:P 0 "register_operand" "=r")
8556         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8557                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
8558                   UNSPEC_ARRAY32))]
8559   "TARGET_VIS"
8560   "array32\t%r1, %r2, %0"
8561   [(set_attr "type" "array")])
8563 (define_insn "bmaskdi_vis"
8564   [(set (match_operand:DI 0 "register_operand" "=r")
8565         (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
8566                  (match_operand:DI 2 "register_or_zero_operand" "rJ")))
8567    (set (zero_extract:DI (reg:DI GSR_REG) (const_int 32) (const_int 32))
8568         (plus:DI (match_dup 1) (match_dup 2)))]
8569   "TARGET_VIS2"
8570   "bmask\t%r1, %r2, %0"
8571   [(set_attr "type" "array")])
8573 (define_insn "bmasksi_vis"
8574   [(set (match_operand:SI 0 "register_operand" "=r")
8575         (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
8576                  (match_operand:SI 2 "register_or_zero_operand" "rJ")))
8577    (set (zero_extract:DI (reg:DI GSR_REG) (const_int 32) (const_int 32))
8578         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
8579   "TARGET_VIS2"
8580   "bmask\t%r1, %r2, %0"
8581   [(set_attr "type" "array")])
8583 (define_insn "bshuffle<VM64:mode>_vis"
8584   [(set (match_operand:VM64 0 "register_operand" "=e")
8585         (unspec:VM64 [(match_operand:VM64 1 "register_operand" "e")
8586                       (match_operand:VM64 2 "register_operand" "e")
8587                       (reg:DI GSR_REG)]
8588                      UNSPEC_BSHUFFLE))]
8589   "TARGET_VIS2"
8590   "bshuffle\t%1, %2, %0"
8591   [(set_attr "type" "fga")
8592    (set_attr "fptype" "double")])
8594 ;; The rtl expanders will happily convert constant permutations on other
8595 ;; modes down to V8QI.  Rely on this to avoid the complexity of the byte
8596 ;; order of the permutation.
8597 (define_expand "vec_perm_constv8qi"
8598   [(match_operand:V8QI 0 "register_operand" "")
8599    (match_operand:V8QI 1 "register_operand" "")
8600    (match_operand:V8QI 2 "register_operand" "")
8601    (match_operand:V8QI 3 "" "")]
8602   "TARGET_VIS2"
8604   unsigned int i, mask;
8605   rtx sel = operands[3];
8607   for (i = mask = 0; i < 8; ++i)
8608     mask |= (INTVAL (XVECEXP (sel, 0, i)) & 0xf) << (28 - i*4);
8609   sel = force_reg (SImode, gen_int_mode (mask, SImode));
8611   emit_insn (gen_bmasksi_vis (gen_reg_rtx (SImode), sel, const0_rtx));
8612   emit_insn (gen_bshufflev8qi_vis (operands[0], operands[1], operands[2]));
8613   DONE;
8616 ;; Unlike constant permutation, we can vastly simplify the compression of
8617 ;; the 64-bit selector input to the 32-bit %gsr value by knowing what the
8618 ;; width of the input is.
8619 (define_expand "vec_perm<mode>"
8620   [(match_operand:VM64 0 "register_operand" "")
8621    (match_operand:VM64 1 "register_operand" "")
8622    (match_operand:VM64 2 "register_operand" "")
8623    (match_operand:VM64 3 "register_operand" "")]
8624   "TARGET_VIS2"
8626   sparc_expand_vec_perm_bmask (<MODE>mode, operands[3]);
8627   emit_insn (gen_bshuffle<mode>_vis (operands[0], operands[1], operands[2]));
8628   DONE;
8631 ;; VIS 2.0 adds edge variants which do not set the condition codes
8632 (define_insn "edge8n<P:mode>_vis"
8633   [(set (match_operand:P 0 "register_operand" "=r")
8634         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8635                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
8636                   UNSPEC_EDGE8N))]
8637   "TARGET_VIS2"
8638   "edge8n\t%r1, %r2, %0"
8639   [(set_attr "type" "edgen")])
8641 (define_insn "edge8ln<P:mode>_vis"
8642   [(set (match_operand:P 0 "register_operand" "=r")
8643         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8644                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
8645                   UNSPEC_EDGE8LN))]
8646   "TARGET_VIS2"
8647   "edge8ln\t%r1, %r2, %0"
8648   [(set_attr "type" "edgen")])
8650 (define_insn "edge16n<P:mode>_vis"
8651   [(set (match_operand:P 0 "register_operand" "=r")
8652         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8653                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
8654                   UNSPEC_EDGE16N))]
8655   "TARGET_VIS2"
8656   "edge16n\t%r1, %r2, %0"
8657   [(set_attr "type" "edgen")])
8659 (define_insn "edge16ln<P:mode>_vis"
8660   [(set (match_operand:P 0 "register_operand" "=r")
8661         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8662                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
8663                   UNSPEC_EDGE16LN))]
8664   "TARGET_VIS2"
8665   "edge16ln\t%r1, %r2, %0"
8666   [(set_attr "type" "edgen")])
8668 (define_insn "edge32n<P:mode>_vis"
8669   [(set (match_operand:P 0 "register_operand" "=r")
8670         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8671                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
8672                   UNSPEC_EDGE32N))]
8673   "TARGET_VIS2"
8674   "edge32n\t%r1, %r2, %0"
8675   [(set_attr "type" "edgen")])
8677 (define_insn "edge32ln<P:mode>_vis"
8678   [(set (match_operand:P 0 "register_operand" "=r")
8679         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8680                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
8681                   UNSPEC_EDGE32LN))]
8682   "TARGET_VIS2"
8683   "edge32ln\t%r1, %r2, %0"
8684   [(set_attr "type" "edge")])
8686 ;; Conditional moves are possible via fcmpX --> cmaskX -> bshuffle
8687 (define_insn "cmask8<P:mode>_vis"
8688   [(set (reg:DI GSR_REG)
8689         (unspec:DI [(match_operand:P 0 "register_or_zero_operand" "rJ")
8690                     (reg:DI GSR_REG)]
8691                    UNSPEC_CMASK8))]
8692   "TARGET_VIS3"
8693   "cmask8\t%r0"
8694   [(set_attr "type" "fga")])
8696 (define_insn "cmask16<P:mode>_vis"
8697   [(set (reg:DI GSR_REG)
8698         (unspec:DI [(match_operand:P 0 "register_or_zero_operand" "rJ")
8699                     (reg:DI GSR_REG)]
8700                    UNSPEC_CMASK16))]
8701   "TARGET_VIS3"
8702   "cmask16\t%r0"
8703   [(set_attr "type" "fga")])
8705 (define_insn "cmask32<P:mode>_vis"
8706   [(set (reg:DI GSR_REG)
8707         (unspec:DI [(match_operand:P 0 "register_or_zero_operand" "rJ")
8708                     (reg:DI GSR_REG)]
8709                    UNSPEC_CMASK32))]
8710   "TARGET_VIS3"
8711   "cmask32\t%r0"
8712   [(set_attr "type" "fga")])
8714 (define_insn "fchksm16_vis"
8715   [(set (match_operand:V4HI 0 "register_operand" "=e")
8716         (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "e")
8717                       (match_operand:V4HI 2 "register_operand" "e")]
8718                      UNSPEC_FCHKSM16))]
8719   "TARGET_VIS3"
8720   "fchksm16\t%1, %2, %0"
8721   [(set_attr "type" "fga")])
8723 (define_code_iterator vis3_shift [ashift ss_ashift lshiftrt ashiftrt])
8724 (define_code_attr vis3_shift_insn
8725   [(ashift "fsll") (ss_ashift "fslas") (lshiftrt "fsrl") (ashiftrt "fsra")])
8726 (define_code_attr vis3_shift_patname
8727   [(ashift "ashl") (ss_ashift "ssashl") (lshiftrt "lshr") (ashiftrt "ashr")])
8728    
8729 (define_insn "v<vis3_shift_patname><mode>3"
8730   [(set (match_operand:GCM 0 "register_operand" "=<vconstr>")
8731         (vis3_shift:GCM (match_operand:GCM 1 "register_operand" "<vconstr>")
8732                         (match_operand:GCM 2 "register_operand" "<vconstr>")))]
8733   "TARGET_VIS3"
8734   "<vis3_shift_insn><vbits>\t%1, %2, %0"
8735   [(set_attr "type" "fga")])
8737 (define_insn "pdistn<mode>_vis"
8738   [(set (match_operand:P 0 "register_operand" "=r")
8739         (unspec:P [(match_operand:V8QI 1 "register_operand" "e")
8740                    (match_operand:V8QI 2 "register_operand" "e")]
8741          UNSPEC_PDISTN))]
8742   "TARGET_VIS3"
8743   "pdistn\t%1, %2, %0"
8744   [(set_attr "type" "pdistn")
8745    (set_attr "fptype" "double")])
8747 (define_insn "fmean16_vis"
8748   [(set (match_operand:V4HI 0 "register_operand" "=e")
8749         (truncate:V4HI
8750           (lshiftrt:V4SI
8751             (plus:V4SI
8752               (plus:V4SI
8753                 (zero_extend:V4SI
8754                   (match_operand:V4HI 1 "register_operand" "e"))
8755                 (zero_extend:V4SI
8756                   (match_operand:V4HI 2 "register_operand" "e")))
8757               (const_vector:V4SI [(const_int 1) (const_int 1)
8758                                   (const_int 1) (const_int 1)]))
8759           (const_int 1))))]
8760   "TARGET_VIS3"
8761   "fmean16\t%1, %2, %0"
8762   [(set_attr "type" "fga")])
8764 (define_insn "fp<plusminus_insn>64_vis"
8765   [(set (match_operand:V1DI 0 "register_operand" "=e")
8766         (plusminus:V1DI (match_operand:V1DI 1 "register_operand" "e")
8767                         (match_operand:V1DI 2 "register_operand" "e")))]
8768   "TARGET_VIS3"
8769   "fp<plusminus_insn>64\t%1, %2, %0"
8770   [(set_attr "type" "fga")])
8772 (define_mode_iterator VASS [V4HI V2SI V2HI V1SI])
8773 (define_code_iterator vis3_addsub_ss [ss_plus ss_minus])
8774 (define_code_attr vis3_addsub_ss_insn
8775   [(ss_plus "fpadds") (ss_minus "fpsubs")])
8776 (define_code_attr vis3_addsub_ss_patname
8777   [(ss_plus "ssadd") (ss_minus "sssub")])
8779 (define_insn "<vis3_addsub_ss_patname><mode>3"
8780   [(set (match_operand:VASS 0 "register_operand" "=<vconstr>")
8781         (vis3_addsub_ss:VASS (match_operand:VASS 1 "register_operand" "<vconstr>")
8782                              (match_operand:VASS 2 "register_operand" "<vconstr>")))]
8783   "TARGET_VIS3"
8784   "<vis3_addsub_ss_insn><vbits>\t%1, %2, %0"
8785   [(set_attr "type" "fga")])
8787 (define_insn "fucmp<code>8<P:mode>_vis"
8788   [(set (match_operand:P 0 "register_operand" "=r")
8789         (unspec:P [(gcond:V8QI (match_operand:V8QI 1 "register_operand" "e")
8790                                (match_operand:V8QI 2 "register_operand" "e"))]
8791          UNSPEC_FUCMP))]
8792   "TARGET_VIS3"
8793   "fucmp<code>8\t%1, %2, %0"
8794   [(set_attr "type" "visl")])
8796 (define_insn "*naddsf3"
8797   [(set (match_operand:SF 0 "register_operand" "=f")
8798         (neg:SF (plus:SF (match_operand:SF 1 "register_operand" "f")
8799                          (match_operand:SF 2 "register_operand" "f"))))]
8800   "TARGET_VIS3"
8801   "fnadds\t%1, %2, %0"
8802   [(set_attr "type" "fp")])
8804 (define_insn "*nadddf3"
8805   [(set (match_operand:DF 0 "register_operand" "=e")
8806         (neg:DF (plus:DF (match_operand:DF 1 "register_operand" "e")
8807                          (match_operand:DF 2 "register_operand" "e"))))]
8808   "TARGET_VIS3"
8809   "fnaddd\t%1, %2, %0"
8810   [(set_attr "type" "fp")
8811    (set_attr "fptype" "double")])
8813 (define_insn "*nmulsf3"
8814   [(set (match_operand:SF 0 "register_operand" "=f")
8815         (mult:SF (neg:SF (match_operand:SF 1 "register_operand" "f"))
8816                  (match_operand:SF 2 "register_operand" "f")))]
8817   "TARGET_VIS3"
8818   "fnmuls\t%1, %2, %0"
8819   [(set_attr "type" "fpmul")])
8821 (define_insn "*nmuldf3"
8822   [(set (match_operand:DF 0 "register_operand" "=e")
8823         (mult:DF (neg:DF (match_operand:DF 1 "register_operand" "e"))
8824                  (match_operand:DF 2 "register_operand" "e")))]
8825   "TARGET_VIS3"
8826   "fnmuld\t%1, %2, %0"
8827   [(set_attr "type" "fpmul")
8828    (set_attr "fptype" "double")])
8830 (define_insn "*nmuldf3_extend"
8831   [(set (match_operand:DF 0 "register_operand" "=e")
8832         (mult:DF (neg:DF (float_extend:DF
8833                            (match_operand:SF 1 "register_operand" "f")))
8834                  (float_extend:DF
8835                    (match_operand:SF 2 "register_operand" "f"))))]
8836   "TARGET_VIS3"
8837   "fnsmuld\t%1, %2, %0"
8838   [(set_attr "type" "fpmul")
8839    (set_attr "fptype" "double")])
8841 (define_insn "fhaddsf_vis"
8842   [(set (match_operand:SF 0 "register_operand" "=f")
8843         (unspec:SF [(match_operand:SF 1 "register_operand" "f")
8844                     (match_operand:SF 2 "register_operand" "f")]
8845                    UNSPEC_FHADD))]
8846   "TARGET_VIS3"
8847   "fhadds\t%1, %2, %0"
8848   [(set_attr "type" "fp")])
8850 (define_insn "fhadddf_vis"
8851   [(set (match_operand:DF 0 "register_operand" "=f")
8852         (unspec:DF [(match_operand:DF 1 "register_operand" "f")
8853                     (match_operand:DF 2 "register_operand" "f")]
8854                    UNSPEC_FHADD))]
8855   "TARGET_VIS3"
8856   "fhaddd\t%1, %2, %0"
8857   [(set_attr "type" "fp")
8858    (set_attr "fptype" "double")])
8860 (define_insn "fhsubsf_vis"
8861   [(set (match_operand:SF 0 "register_operand" "=f")
8862         (unspec:SF [(match_operand:SF 1 "register_operand" "f")
8863                     (match_operand:SF 2 "register_operand" "f")]
8864                    UNSPEC_FHSUB))]
8865   "TARGET_VIS3"
8866   "fhsubs\t%1, %2, %0"
8867   [(set_attr "type" "fp")])
8869 (define_insn "fhsubdf_vis"
8870   [(set (match_operand:DF 0 "register_operand" "=f")
8871         (unspec:DF [(match_operand:DF 1 "register_operand" "f")
8872                     (match_operand:DF 2 "register_operand" "f")]
8873                    UNSPEC_FHSUB))]
8874   "TARGET_VIS3"
8875   "fhsubd\t%1, %2, %0"
8876   [(set_attr "type" "fp")
8877    (set_attr "fptype" "double")])
8879 (define_insn "fnhaddsf_vis"
8880   [(set (match_operand:SF 0 "register_operand" "=f")
8881         (neg:SF (unspec:SF [(match_operand:SF 1 "register_operand" "f")
8882                             (match_operand:SF 2 "register_operand" "f")]
8883                            UNSPEC_FHADD)))]
8884   "TARGET_VIS3"
8885   "fnhadds\t%1, %2, %0"
8886   [(set_attr "type" "fp")])
8888 (define_insn "fnhadddf_vis"
8889   [(set (match_operand:DF 0 "register_operand" "=f")
8890         (neg:DF (unspec:DF [(match_operand:DF 1 "register_operand" "f")
8891                             (match_operand:DF 2 "register_operand" "f")]
8892                            UNSPEC_FHADD)))]
8893   "TARGET_VIS3"
8894   "fnhaddd\t%1, %2, %0"
8895   [(set_attr "type" "fp")
8896    (set_attr "fptype" "double")])
8898 (define_expand "umulxhi_vis"
8899   [(set (match_operand:DI 0 "register_operand" "")
8900         (truncate:DI
8901           (lshiftrt:TI
8902             (mult:TI (zero_extend:TI
8903                        (match_operand:DI 1 "arith_operand" ""))
8904                      (zero_extend:TI
8905                        (match_operand:DI 2 "arith_operand" "")))
8906            (const_int 64))))]
8907  "TARGET_VIS3"
8909   if (! TARGET_ARCH64)
8910     {
8911       emit_insn (gen_umulxhi_v8plus (operands[0], operands[1], operands[2]));
8912       DONE;
8913     }
8916 (define_insn "*umulxhi_sp64"
8917   [(set (match_operand:DI 0 "register_operand" "=r")
8918         (truncate:DI
8919           (lshiftrt:TI
8920             (mult:TI (zero_extend:TI
8921                        (match_operand:DI 1 "arith_operand" "%r"))
8922                      (zero_extend:TI
8923                        (match_operand:DI 2 "arith_operand" "rI")))
8924            (const_int 64))))]
8925   "TARGET_VIS3 && TARGET_ARCH64"
8926   "umulxhi\t%1, %2, %0"
8927   [(set_attr "type" "imul")])
8929 (define_insn "umulxhi_v8plus"
8930   [(set (match_operand:DI 0 "register_operand" "=r,h")
8931         (truncate:DI
8932           (lshiftrt:TI
8933             (mult:TI (zero_extend:TI
8934                        (match_operand:DI 1 "arith_operand" "%r,0"))
8935                      (zero_extend:TI
8936                        (match_operand:DI 2 "arith_operand" "rI,rI")))
8937            (const_int 64))))
8938    (clobber (match_scratch:SI 3 "=&h,X"))
8939    (clobber (match_scratch:SI 4 "=&h,X"))]
8940   "TARGET_VIS3 && ! TARGET_ARCH64"
8941   "* return output_v8plus_mult (insn, operands, \"umulxhi\");"
8942   [(set_attr "type" "imul")
8943    (set_attr "length" "9,8")])
8945 (define_expand "xmulx_vis"
8946   [(set (match_operand:DI 0 "register_operand" "")
8947         (truncate:DI
8948           (unspec:TI [(zero_extend:TI
8949                         (match_operand:DI 1 "arith_operand" ""))
8950                       (zero_extend:TI
8951                         (match_operand:DI 2 "arith_operand" ""))]
8952            UNSPEC_XMUL)))]
8953   "TARGET_VIS3"
8955   if (! TARGET_ARCH64)
8956     {
8957       emit_insn (gen_xmulx_v8plus (operands[0], operands[1], operands[2]));
8958       DONE;
8959     }
8962 (define_insn "*xmulx_sp64"
8963   [(set (match_operand:DI 0 "register_operand" "=r")
8964         (truncate:DI
8965           (unspec:TI [(zero_extend:TI
8966                         (match_operand:DI 1 "arith_operand" "%r"))
8967                       (zero_extend:TI
8968                         (match_operand:DI 2 "arith_operand" "rI"))]
8969            UNSPEC_XMUL)))]
8970   "TARGET_VIS3 && TARGET_ARCH64"
8971   "xmulx\t%1, %2, %0"
8972   [(set_attr "type" "imul")])
8974 (define_insn "xmulx_v8plus"
8975   [(set (match_operand:DI 0 "register_operand" "=r,h")
8976         (truncate:DI
8977           (unspec:TI [(zero_extend:TI
8978                         (match_operand:DI 1 "arith_operand" "%r,0"))
8979                       (zero_extend:TI
8980                         (match_operand:DI 2 "arith_operand" "rI,rI"))]
8981            UNSPEC_XMUL)))
8982    (clobber (match_scratch:SI 3 "=&h,X"))
8983    (clobber (match_scratch:SI 4 "=&h,X"))]
8984   "TARGET_VIS3 && ! TARGET_ARCH64"
8985   "* return output_v8plus_mult (insn, operands, \"xmulx\");"
8986   [(set_attr "type" "imul")
8987    (set_attr "length" "9,8")])
8989 (define_expand "xmulxhi_vis"
8990   [(set (match_operand:DI 0 "register_operand" "")
8991         (truncate:DI
8992           (lshiftrt:TI
8993             (unspec:TI [(zero_extend:TI
8994                           (match_operand:DI 1 "arith_operand" ""))
8995                         (zero_extend:TI
8996                           (match_operand:DI 2 "arith_operand" ""))]
8997              UNSPEC_XMUL)
8998            (const_int 64))))]
8999   "TARGET_VIS3"
9001   if (! TARGET_ARCH64)
9002     {
9003       emit_insn (gen_xmulxhi_v8plus (operands[0], operands[1], operands[2]));
9004       DONE;
9005     }
9008 (define_insn "*xmulxhi_sp64"
9009   [(set (match_operand:DI 0 "register_operand" "=r")
9010         (truncate:DI
9011           (lshiftrt:TI
9012             (unspec:TI [(zero_extend:TI
9013                           (match_operand:DI 1 "arith_operand" "%r"))
9014                         (zero_extend:TI
9015                           (match_operand:DI 2 "arith_operand" "rI"))]
9016              UNSPEC_XMUL)
9017            (const_int 64))))]
9018   "TARGET_VIS3 && TARGET_ARCH64"
9019   "xmulxhi\t%1, %2, %0"
9020   [(set_attr "type" "imul")])
9022 (define_insn "xmulxhi_v8plus"
9023   [(set (match_operand:DI 0 "register_operand" "=r,h")
9024         (truncate:DI
9025           (lshiftrt:TI
9026             (unspec:TI [(zero_extend:TI
9027                           (match_operand:DI 1 "arith_operand" "%r,0"))
9028                         (zero_extend:TI
9029                           (match_operand:DI 2 "arith_operand" "rI,rI"))]
9030              UNSPEC_XMUL)
9031            (const_int 64))))
9032    (clobber (match_scratch:SI 3 "=&h,X"))
9033    (clobber (match_scratch:SI 4 "=&h,X"))]
9034   "TARGET_VIS3 && !TARGET_ARCH64"
9035   "* return output_v8plus_mult (insn, operands, \"xmulxhi\");"
9036   [(set_attr "type" "imul")
9037    (set_attr "length" "9,8")])
9039 (include "sync.md")