gcc/
[official-gcc.git] / gcc / config / sparc / sparc.md
blob29e4966fccb738dc55a6d3e4f5d3c0074e3f2a72
1 ;; Machine description for SPARC chip for GCC
2 ;;  Copyright (C) 1987-2016 Free Software Foundation, Inc.
3 ;;  Contributed by Michael Tiemann (tiemann@cygnus.com)
4 ;;  64-bit SPARC-V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
5 ;;  at Cygnus Support.
7 ;; This file is part of GCC.
9 ;; GCC is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 3, or (at your option)
12 ;; any later version.
14 ;; GCC is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 ;; GNU General Public License for more details.
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GCC; see the file COPYING3.  If not see
21 ;; <http://www.gnu.org/licenses/>.
23 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
25 (define_c_enum "unspec" [
26   UNSPEC_MOVE_PIC
27   UNSPEC_UPDATE_RETURN
28   UNSPEC_LOAD_PCREL_SYM
29   UNSPEC_FRAME_BLOCKAGE
30   UNSPEC_MOVE_PIC_LABEL
31   UNSPEC_SETH44
32   UNSPEC_SETM44
33   UNSPEC_SETHH
34   UNSPEC_SETLM
35   UNSPEC_EMB_HISUM
36   UNSPEC_EMB_TEXTUHI
37   UNSPEC_EMB_TEXTHI
38   UNSPEC_EMB_TEXTULO
39   UNSPEC_EMB_SETHM
40   UNSPEC_MOVE_GOTDATA
42   UNSPEC_MEMBAR
43   UNSPEC_ATOMIC
45   UNSPEC_TLSGD
46   UNSPEC_TLSLDM
47   UNSPEC_TLSLDO
48   UNSPEC_TLSIE
49   UNSPEC_TLSLE
50   UNSPEC_TLSLD_BASE
52   UNSPEC_FPACK16
53   UNSPEC_FPACK32
54   UNSPEC_FPACKFIX
55   UNSPEC_FEXPAND
56   UNSPEC_MUL16AU
57   UNSPEC_MUL16AL
58   UNSPEC_MUL8UL
59   UNSPEC_MULDUL
60   UNSPEC_ALIGNDATA
61   UNSPEC_FCMP
62   UNSPEC_PDIST
63   UNSPEC_EDGE8
64   UNSPEC_EDGE8L
65   UNSPEC_EDGE16
66   UNSPEC_EDGE16L
67   UNSPEC_EDGE32
68   UNSPEC_EDGE32L
69   UNSPEC_ARRAY8
70   UNSPEC_ARRAY16
71   UNSPEC_ARRAY32
73   UNSPEC_SP_SET
74   UNSPEC_SP_TEST
76   UNSPEC_EDGE8N
77   UNSPEC_EDGE8LN
78   UNSPEC_EDGE16N
79   UNSPEC_EDGE16LN
80   UNSPEC_EDGE32N
81   UNSPEC_EDGE32LN
82   UNSPEC_BSHUFFLE
83   UNSPEC_CMASK8
84   UNSPEC_CMASK16
85   UNSPEC_CMASK32
86   UNSPEC_FCHKSM16
87   UNSPEC_PDISTN
88   UNSPEC_FUCMP
89   UNSPEC_FHADD
90   UNSPEC_FHSUB
91   UNSPEC_XMUL
92   UNSPEC_MUL8
93   UNSPEC_MUL8SU
94   UNSPEC_MULDSU
97 (define_c_enum "unspecv" [
98   UNSPECV_BLOCKAGE
99   UNSPECV_PROBE_STACK_RANGE
101   UNSPECV_FLUSHW
102   UNSPECV_SAVEW
104   UNSPECV_FLUSH
106   UNSPECV_LDSTUB
107   UNSPECV_SWAP
108   UNSPECV_CAS
110   UNSPECV_LDFSR
111   UNSPECV_STFSR
114 (define_constants
115  [(G0_REG                       0)
116   (G1_REG                       1)
117   (G2_REG                       2)
118   (G3_REG                       3)
119   (G4_REG                       4)
120   (G5_REG                       5)
121   (G6_REG                       6)
122   (G7_REG                       7)
123   (O0_REG                       8)
124   (O1_REG                       9)
125   (O2_REG                       10)
126   (O3_REG                       11)
127   (O4_REG                       12)
128   (O5_REG                       13)
129   (O6_REG                       14)
130   (O7_REG                       15)
131   (L0_REG                       16)
132   (L1_REG                       17)
133   (L2_REG                       18)
134   (L3_REG                       19)
135   (L4_REG                       20)
136   (L5_REG                       21)
137   (L6_REG                       22)
138   (L7_REG                       23)
139   (I0_REG                       24)
140   (I1_REG                       25)
141   (I2_REG                       26)
142   (I3_REG                       27)
143   (I4_REG                       28)
144   (I5_REG                       29)
145   (I6_REG                       30)
146   (I7_REG                       31)
147   (F0_REG                       32)
148   (F1_REG                       33)
149   (F2_REG                       34)
150   (F3_REG                       35)
151   (F4_REG                       36)
152   (F5_REG                       37)
153   (F6_REG                       38)
154   (F7_REG                       39)
155   (F8_REG                       40)
156   (F9_REG                       41)
157   (F10_REG                      42)
158   (F11_REG                      43)
159   (F12_REG                      44)
160   (F13_REG                      45)
161   (F14_REG                      46)
162   (F15_REG                      47)
163   (F16_REG                      48)
164   (F17_REG                      49)
165   (F18_REG                      50)
166   (F19_REG                      51)
167   (F20_REG                      52)
168   (F21_REG                      53)
169   (F22_REG                      54)
170   (F23_REG                      55)
171   (F24_REG                      56)
172   (F25_REG                      57)
173   (F26_REG                      58)
174   (F27_REG                      59)
175   (F28_REG                      60)
176   (F29_REG                      61)
177   (F30_REG                      62)
178   (F31_REG                      63)
179   (F32_REG                      64)
180   (F34_REG                      66)
181   (F36_REG                      68)
182   (F38_REG                      70)
183   (F40_REG                      72)
184   (F42_REG                      74)
185   (F44_REG                      76)
186   (F46_REG                      78)
187   (F48_REG                      80)
188   (F50_REG                      82)
189   (F52_REG                      84)
190   (F54_REG                      86)
191   (F56_REG                      88)
192   (F58_REG                      90)
193   (F60_REG                      92)
194   (F62_REG                      94)
195   (FCC0_REG                     96)
196   (FCC1_REG                     97)
197   (FCC2_REG                     98)
198   (FCC3_REG                     99)
199   (CC_REG                       100)
200   (SFP_REG                      101)
201   (GSR_REG                      102)
202  ])
204 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
205 (define_mode_iterator I [QI HI SI DI])
206 (define_mode_iterator F [SF DF TF])
208 ;; The upper 32 fp regs on the v9 can't hold SFmode values.  To deal with this
209 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip.  The name
210 ;; is a bit of a misnomer as it covers all 64 fp regs.  The corresponding
211 ;; constraint letter is 'e'.  To avoid any confusion, 'e' is used instead of
212 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
214 ;; Attribute for cpu type.
215 ;; These must match the values of the enum processor_type in sparc-opts.h.
216 (define_attr "cpu"
217   "v7,
218    cypress,
219    v8,
220    supersparc,
221    hypersparc,
222    leon,
223    leon3,
224    leon3v7,
225    sparclite,
226    f930,
227    f934,
228    sparclite86x,
229    sparclet,
230    tsc701,
231    v9,
232    ultrasparc,
233    ultrasparc3,
234    niagara,
235    niagara2,
236    niagara3,
237    niagara4,
238    niagara7"
239   (const (symbol_ref "sparc_cpu_attr")))
241 ;; Attribute for the instruction set.
242 ;; At present we only need to distinguish v9/!v9, but for clarity we
243 ;; test TARGET_V8 too.
244 (define_attr "isa" "v7,v8,v9,sparclet"
245  (const
246   (cond [(symbol_ref "TARGET_V9") (const_string "v9")
247          (symbol_ref "TARGET_V8") (const_string "v8")
248          (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
249         (const_string "v7"))))
251 (define_attr "cpu_feature" "none,fpu,fpunotv9,v9,vis,vis3,vis4" (const_string "none"))
253 (define_attr "enabled" ""
254   (cond [(eq_attr "cpu_feature" "none") (const_int 1)
255          (eq_attr "cpu_feature" "fpu") (symbol_ref "TARGET_FPU")
256          (eq_attr "cpu_feature" "fpunotv9") (symbol_ref "TARGET_FPU && ! TARGET_V9")
257          (eq_attr "cpu_feature" "v9") (symbol_ref "TARGET_V9")
258          (eq_attr "cpu_feature" "vis") (symbol_ref "TARGET_VIS")
259          (eq_attr "cpu_feature" "vis3") (symbol_ref "TARGET_VIS3")
260          (eq_attr "cpu_feature" "vis4") (symbol_ref "TARGET_VIS4")]
261         (const_int 0)))
263 ;; Insn type.
264 (define_attr "type"
265   "ialu,compare,shift,
266    load,sload,store,
267    uncond_branch,branch,call,sibcall,call_no_delay_slot,return,
268    cbcond,uncond_cbcond,
269    imul,idiv,
270    fpload,fpstore,
271    fp,fpmove,
272    fpcmove,fpcrmove,
273    fpcmp,
274    fpmul,fpdivs,fpdivd,
275    fpsqrts,fpsqrtd,
276    fga,visl,vismv,fgm_pack,fgm_mul,pdist,pdistn,edge,edgen,gsr,array,
277    cmove,
278    ialuX,
279    multi,savew,flushw,iflush,trap,lzd"
280   (const_string "ialu"))
282 ;; True if branch/call has empty delay slot and will emit a nop in it
283 (define_attr "empty_delay_slot" "false,true"
284   (symbol_ref "(empty_delay_slot (insn)
285                 ? EMPTY_DELAY_SLOT_TRUE : EMPTY_DELAY_SLOT_FALSE)"))
287 ;; True if we are making use of compare-and-branch instructions.
288 ;; True if we should emit a nop after a cbcond instruction
289 (define_attr "emit_cbcond_nop" "false,true"
290   (symbol_ref "(emit_cbcond_nop (insn)
291                 ? EMIT_CBCOND_NOP_TRUE : EMIT_CBCOND_NOP_FALSE)"))
293 (define_attr "branch_type" "none,icc,fcc,reg"
294   (const_string "none"))
296 (define_attr "pic" "false,true"
297   (symbol_ref "(flag_pic != 0
298                 ? PIC_TRUE : PIC_FALSE)"))
300 (define_attr "calls_alloca" "false,true"
301   (symbol_ref "(cfun->calls_alloca != 0
302                 ? CALLS_ALLOCA_TRUE : CALLS_ALLOCA_FALSE)"))
304 (define_attr "calls_eh_return" "false,true"
305    (symbol_ref "(crtl->calls_eh_return != 0
306                  ? CALLS_EH_RETURN_TRUE : CALLS_EH_RETURN_FALSE)"))
308 (define_attr "leaf_function" "false,true"
309   (symbol_ref "(crtl->uses_only_leaf_regs != 0
310                 ? LEAF_FUNCTION_TRUE : LEAF_FUNCTION_FALSE)"))
312 (define_attr "delayed_branch" "false,true"
313   (symbol_ref "(flag_delayed_branch != 0
314                 ? DELAYED_BRANCH_TRUE : DELAYED_BRANCH_FALSE)"))
316 (define_attr "flat" "false,true"
317   (symbol_ref "(TARGET_FLAT != 0
318                 ? FLAT_TRUE : FLAT_FALSE)"))
320 (define_attr "fix_ut699" "false,true"
321    (symbol_ref "(sparc_fix_ut699 != 0
322                  ? FIX_UT699_TRUE : FIX_UT699_FALSE)"))
324 ;; Length (in # of insns).
325 ;; Beware that setting a length greater or equal to 3 for conditional branches
326 ;; has a side-effect (see output_cbranch and output_v9branch).
327 (define_attr "length" ""
328   (cond [(eq_attr "type" "uncond_branch,call")
329            (if_then_else (eq_attr "empty_delay_slot" "true")
330              (const_int 2)
331              (const_int 1))
332          (eq_attr "type" "sibcall")
333            (if_then_else (eq_attr "leaf_function" "true")
334              (if_then_else (eq_attr "empty_delay_slot" "true")
335                (const_int 3)
336                (const_int 2))
337              (if_then_else (eq_attr "empty_delay_slot" "true")
338                (const_int 2)
339                (const_int 1)))
340          (eq_attr "branch_type" "icc")
341            (if_then_else (match_operand 0 "noov_compare64_operator" "")
342              (if_then_else (lt (pc) (match_dup 1))
343                (if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000))
344                  (if_then_else (eq_attr "empty_delay_slot" "true")
345                    (const_int 2)
346                    (const_int 1))
347                  (if_then_else (eq_attr "empty_delay_slot" "true")
348                    (const_int 4)
349                    (const_int 3)))
350                (if_then_else (lt (minus (pc) (match_dup 1)) (const_int 260000))
351                  (if_then_else (eq_attr "empty_delay_slot" "true")
352                    (const_int 2)
353                    (const_int 1))
354                  (if_then_else (eq_attr "empty_delay_slot" "true")
355                    (const_int 4)
356                    (const_int 3))))
357              (if_then_else (eq_attr "empty_delay_slot" "true")
358                (const_int 2)
359                (const_int 1)))
360          (eq_attr "branch_type" "fcc")
361            (if_then_else (match_operand 0 "fcc0_register_operand" "")
362              (if_then_else (eq_attr "empty_delay_slot" "true")
363                (if_then_else (not (match_test "TARGET_V9"))
364                  (const_int 3)
365                  (const_int 2))
366                (if_then_else (not (match_test "TARGET_V9"))
367                  (const_int 2)
368                  (const_int 1)))
369              (if_then_else (lt (pc) (match_dup 2))
370                (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000))
371                  (if_then_else (eq_attr "empty_delay_slot" "true")
372                    (const_int 2)
373                    (const_int 1))
374                  (if_then_else (eq_attr "empty_delay_slot" "true")
375                    (const_int 4)
376                    (const_int 3)))
377                (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000))
378                  (if_then_else (eq_attr "empty_delay_slot" "true")
379                    (const_int 2)
380                    (const_int 1))
381                  (if_then_else (eq_attr "empty_delay_slot" "true")
382                    (const_int 4)
383                    (const_int 3)))))
384          (eq_attr "branch_type" "reg")
385            (if_then_else (lt (pc) (match_dup 2))
386              (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000))
387                (if_then_else (eq_attr "empty_delay_slot" "true")
388                  (const_int 2)
389                  (const_int 1))
390                (if_then_else (eq_attr "empty_delay_slot" "true")
391                  (const_int 4)
392                  (const_int 3)))
393              (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000))
394                (if_then_else (eq_attr "empty_delay_slot" "true")
395                  (const_int 2)
396                  (const_int 1))
397                (if_then_else (eq_attr "empty_delay_slot" "true")
398                  (const_int 4)
399                  (const_int 3))))
400          (eq_attr "type" "cbcond")
401            (if_then_else (lt (pc) (match_dup 3))
402              (if_then_else (lt (minus (match_dup 3) (pc)) (const_int 500))
403                (if_then_else (eq_attr "emit_cbcond_nop" "true")
404                  (const_int 2)
405                  (const_int 1))
406                (const_int 4))
407              (if_then_else (lt (minus (pc) (match_dup 3)) (const_int 500))
408                (if_then_else (eq_attr "emit_cbcond_nop" "true")
409                  (const_int 2)
410                  (const_int 1))
411                (const_int 4)))
412          (eq_attr "type" "uncond_cbcond")
413            (if_then_else (lt (pc) (match_dup 0))
414              (if_then_else (lt (minus (match_dup 0) (pc)) (const_int 500))
415                (if_then_else (eq_attr "emit_cbcond_nop" "true")
416                  (const_int 2)
417                  (const_int 1))
418                (const_int 1))
419              (if_then_else (lt (minus (pc) (match_dup 0)) (const_int 500))
420                (if_then_else (eq_attr "emit_cbcond_nop" "true")
421                  (const_int 2)
422                  (const_int 1))
423                (const_int 1)))
424          ] (const_int 1)))
426 ;; FP precision.
427 (define_attr "fptype" "single,double"
428   (const_string "single"))
430 ;; FP precision specific to the UT699.
431 (define_attr "fptype_ut699" "none,single"
432   (const_string "none"))
434 ;; UltraSPARC-III integer load type.
435 (define_attr "us3load_type" "2cycle,3cycle"
436   (const_string "2cycle"))
438 (define_asm_attributes
439   [(set_attr "length" "2")
440    (set_attr "type" "multi")])
442 ;; Attributes for branch scheduling
443 (define_attr "in_call_delay" "false,true"
444   (symbol_ref "(eligible_for_call_delay (insn)
445                 ? IN_CALL_DELAY_TRUE : IN_CALL_DELAY_FALSE)"))
447 (define_attr "in_sibcall_delay" "false,true"
448   (symbol_ref "(eligible_for_sibcall_delay (insn)
449                 ? IN_SIBCALL_DELAY_TRUE : IN_SIBCALL_DELAY_FALSE)"))
451 (define_attr "in_return_delay" "false,true"
452   (symbol_ref "(eligible_for_return_delay (insn)
453                 ? IN_RETURN_DELAY_TRUE : IN_RETURN_DELAY_FALSE)"))
455 ;; ??? !v9: Should implement the notion of predelay slots for floating-point
456 ;; branches.  This would allow us to remove the nop always inserted before
457 ;; a floating point branch.
459 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
460 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
461 ;; This is because doing so will add several pipeline stalls to the path
462 ;; that the load/store did not come from.  Unfortunately, there is no way
463 ;; to prevent fill_eager_delay_slots from using load/store without completely
464 ;; disabling them.  For the SPEC benchmark set, this is a serious lose,
465 ;; because it prevents us from moving back the final store of inner loops.
467 (define_attr "in_branch_delay" "false,true"
468   (cond [(eq_attr "type" "uncond_branch,branch,cbcond,uncond_cbcond,call,sibcall,call_no_delay_slot,multi")
469            (const_string "false")
470          (and (eq_attr "fix_ut699" "true") (eq_attr "type" "load,sload"))
471            (const_string "false")
472          (and (eq_attr "fix_ut699" "true")
473               (and (eq_attr "type" "fpload,fp,fpmove,fpmul,fpdivs,fpsqrts")
474                    (ior (eq_attr "fptype" "single")
475                         (eq_attr "fptype_ut699" "single"))))
476            (const_string "false")
477          (eq_attr "length" "1")
478            (const_string "true")
479         ] (const_string "false")))
481 ;; True if the instruction executes in the V3 pipeline, in M7 and
482 ;; later processors.
483 (define_attr "v3pipe" "false,true" (const_string "false"))
485 (define_delay (eq_attr "type" "call")
486   [(eq_attr "in_call_delay" "true") (nil) (nil)])
488 (define_delay (eq_attr "type" "sibcall")
489   [(eq_attr "in_sibcall_delay" "true") (nil) (nil)])
491 (define_delay (eq_attr "type" "return")
492   [(eq_attr "in_return_delay" "true") (nil) (nil)])
494 (define_delay (eq_attr "type" "branch")
495   [(eq_attr "in_branch_delay" "true") (nil) (eq_attr "in_branch_delay" "true")])
497 (define_delay (eq_attr "type" "uncond_branch")
498   [(eq_attr "in_branch_delay" "true") (nil) (nil)])
501 ;; Include SPARC DFA schedulers
503 (include "cypress.md")
504 (include "supersparc.md")
505 (include "hypersparc.md")
506 (include "leon.md")
507 (include "sparclet.md")
508 (include "ultra1_2.md")
509 (include "ultra3.md")
510 (include "niagara.md")
511 (include "niagara2.md")
512 (include "niagara4.md")
513 (include "niagara7.md")
516 ;; Operand and operator predicates and constraints
518 (include "predicates.md")
519 (include "constraints.md")
522 ;; Compare instructions.
524 ;; These are just the DEFINE_INSNs to match the patterns and the
525 ;; DEFINE_SPLITs for some of the scc insns that actually require
526 ;; more than one machine instruction.  DEFINE_EXPANDs are further down.
528 ;; The compare DEFINE_INSNs.
530 (define_insn "*cmpsi_insn"
531   [(set (reg:CC CC_REG)
532         (compare:CC (match_operand:SI 0 "register_operand" "r")
533                     (match_operand:SI 1 "arith_operand" "rI")))]
534   ""
535   "cmp\t%0, %1"
536   [(set_attr "type" "compare")])
538 (define_insn "*cmpdi_sp64"
539   [(set (reg:CCX CC_REG)
540         (compare:CCX (match_operand:DI 0 "register_operand" "r")
541                      (match_operand:DI 1 "arith_operand" "rI")))]
542   "TARGET_ARCH64"
543   "cmp\t%0, %1"
544   [(set_attr "type" "compare")])
546 (define_insn "*cmpsf_fpe"
547   [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
548         (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
549                        (match_operand:SF 2 "register_operand" "f")))]
550   "TARGET_FPU"
552   if (TARGET_V9)
553     return "fcmpes\t%0, %1, %2";
554   return "fcmpes\t%1, %2";
556   [(set_attr "type" "fpcmp")])
558 (define_insn "*cmpdf_fpe"
559   [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
560         (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
561                        (match_operand:DF 2 "register_operand" "e")))]
562   "TARGET_FPU"
564   if (TARGET_V9)
565     return "fcmped\t%0, %1, %2";
566   return "fcmped\t%1, %2";
568   [(set_attr "type" "fpcmp")
569    (set_attr "fptype" "double")])
571 (define_insn "*cmptf_fpe"
572   [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
573         (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
574                        (match_operand:TF 2 "register_operand" "e")))]
575   "TARGET_FPU && TARGET_HARD_QUAD"
577   if (TARGET_V9)
578     return "fcmpeq\t%0, %1, %2";
579   return "fcmpeq\t%1, %2";
581   [(set_attr "type" "fpcmp")])
583 (define_insn "*cmpsf_fp"
584   [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
585         (compare:CCFP (match_operand:SF 1 "register_operand" "f")
586                       (match_operand:SF 2 "register_operand" "f")))]
587   "TARGET_FPU"
589   if (TARGET_V9)
590     return "fcmps\t%0, %1, %2";
591   return "fcmps\t%1, %2";
593   [(set_attr "type" "fpcmp")])
595 (define_insn "*cmpdf_fp"
596   [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
597         (compare:CCFP (match_operand:DF 1 "register_operand" "e")
598                       (match_operand:DF 2 "register_operand" "e")))]
599   "TARGET_FPU"
601   if (TARGET_V9)
602     return "fcmpd\t%0, %1, %2";
603   return "fcmpd\t%1, %2";
605   [(set_attr "type" "fpcmp")
606    (set_attr "fptype" "double")])
608 (define_insn "*cmptf_fp"
609   [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
610         (compare:CCFP (match_operand:TF 1 "register_operand" "e")
611                       (match_operand:TF 2 "register_operand" "e")))]
612   "TARGET_FPU && TARGET_HARD_QUAD"
614   if (TARGET_V9)
615     return "fcmpq\t%0, %1, %2";
616   return "fcmpq\t%1, %2";
618   [(set_attr "type" "fpcmp")])
620 ;; Next come the scc insns.
622 ;; Note that the boolean result (operand 0) takes on DImode
623 ;; (not SImode) when TARGET_ARCH64.
625 (define_expand "cstoresi4"
626   [(use (match_operator 1 "comparison_operator"
627          [(match_operand:SI 2 "compare_operand" "")
628           (match_operand:SI 3 "arith_operand" "")]))
629    (clobber (match_operand:SI 0 "cstore_result_operand"))]
630   ""
632   if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
633     operands[2] = force_reg (SImode, operands[2]);
634   if (emit_scc_insn (operands)) DONE; else FAIL;
637 (define_expand "cstoredi4"
638   [(use (match_operator 1 "comparison_operator"
639          [(match_operand:DI 2 "compare_operand" "")
640           (match_operand:DI 3 "arith_operand" "")]))
641    (clobber (match_operand:SI 0 "cstore_result_operand"))]
642   "TARGET_ARCH64"
644   if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx)
645     operands[2] = force_reg (DImode, operands[2]);
646   if (emit_scc_insn (operands)) DONE; else FAIL;
649 (define_expand "cstore<F:mode>4"
650   [(use (match_operator 1 "comparison_operator"
651          [(match_operand:F 2 "register_operand" "")
652           (match_operand:F 3 "register_operand" "")]))
653    (clobber (match_operand:SI 0 "cstore_result_operand"))]
654   "TARGET_FPU"
655   { if (emit_scc_insn (operands)) DONE; else FAIL; })
657 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
658 ;; generate addcc/subcc instructions.
660 (define_expand "seqsi<P:mode>_special"
661   [(set (match_dup 3)
662         (xor:SI (match_operand:SI 1 "register_operand" "")
663                 (match_operand:SI 2 "register_operand" "")))
664    (parallel [(set (match_operand:P 0 "register_operand" "")
665                    (eq:P (match_dup 3) (const_int 0)))
666               (clobber (reg:CC CC_REG))])]
667   ""
668   { operands[3] = gen_reg_rtx (SImode); })
670 (define_expand "seqdi_special"
671   [(set (match_dup 3)
672         (xor:DI (match_operand:DI 1 "register_operand" "")
673                 (match_operand:DI 2 "register_operand" "")))
674    (set (match_operand:DI 0 "register_operand" "")
675         (eq:DI (match_dup 3) (const_int 0)))]
676   "TARGET_ARCH64"
677   { operands[3] = gen_reg_rtx (DImode); })
679 (define_expand "snesi<P:mode>_special"
680   [(set (match_dup 3)
681         (xor:SI (match_operand:SI 1 "register_operand" "")
682                 (match_operand:SI 2 "register_operand" "")))
683    (parallel [(set (match_operand:P 0 "register_operand" "")
684                    (ne:P (match_dup 3) (const_int 0)))
685               (clobber (reg:CC CC_REG))])]
686   ""
687   { operands[3] = gen_reg_rtx (SImode); })
689 (define_expand "snedi_special"
690   [(set (match_dup 3)
691         (xor:DI (match_operand:DI 1 "register_operand" "")
692                 (match_operand:DI 2 "register_operand" "")))
693    (set (match_operand:DI 0 "register_operand" "")
694         (ne:DI (match_dup 3) (const_int 0)))]
695   "TARGET_ARCH64 && ! TARGET_VIS3"
696   { operands[3] = gen_reg_rtx (DImode); })
698 (define_expand "snedi_special_vis3"
699   [(set (match_dup 3)
700         (xor:DI (match_operand:DI 1 "register_operand" "")
701                 (match_operand:DI 2 "register_operand" "")))
702    (parallel [(set (match_operand:DI 0 "register_operand" "")
703                    (ne:DI (match_dup 3) (const_int 0)))
704               (clobber (reg:CCX CC_REG))])]
705   "TARGET_ARCH64 && TARGET_VIS3"
706   { operands[3] = gen_reg_rtx (DImode); })
709 ;; Now the DEFINE_INSNs for the scc cases.
711 ;; The SEQ and SNE patterns are special because they can be done
712 ;; without any branching and do not involve a COMPARE.  We want
713 ;; them to always use the splits below so the results can be
714 ;; scheduled.
716 (define_insn_and_split "*snesi<P:mode>_zero"
717   [(set (match_operand:P 0 "register_operand" "=r")
718         (ne:P (match_operand:SI 1 "register_operand" "r")
719                (const_int 0)))
720    (clobber (reg:CC CC_REG))]
721   ""
722   "#"
723   ""
724   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
725                                            (const_int 0)))
726    (set (match_dup 0) (ltu:P (reg:CC CC_REG) (const_int 0)))]
727   ""
728   [(set_attr "length" "2")])
730 (define_insn_and_split "*neg_snesisi_zero"
731   [(set (match_operand:SI 0 "register_operand" "=r")
732         (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
733                        (const_int 0))))
734    (clobber (reg:CC CC_REG))]
735   ""
736   "#"
737   ""
738   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
739                                            (const_int 0)))
740    (set (match_dup 0) (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0))))]
741   ""
742   [(set_attr "length" "2")])
744 (define_insn_and_split "*neg_snesidi_zero"
745   [(set (match_operand:DI 0 "register_operand" "=r")
746         (neg:DI (ne:DI (match_operand:SI 1 "register_operand" "r")
747                        (const_int 0))))
748    (clobber (reg:CC CC_REG))]
749   "TARGET_ARCH64"
750   "#"
751   ""
752   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
753                                            (const_int 0)))
754    (set (match_dup 0) (sign_extend:DI (neg:SI (ltu:SI (reg:CC CC_REG)
755                                                       (const_int 0)))))]
756   ""
757   [(set_attr "length" "2")])
759 (define_insn_and_split "*snedi_zero"
760   [(set (match_operand:DI 0 "register_operand" "=&r")
761         (ne:DI (match_operand:DI 1 "register_operand" "r")
762                (const_int 0)))]
763   "TARGET_ARCH64 && ! TARGET_VIS3"
764   "#"
765   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
766   [(set (match_dup 0) (const_int 0))
767    (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
768                                               (const_int 0))
769                                        (const_int 1)
770                                        (match_dup 0)))]
771   ""
772   [(set_attr "length" "2")])
774 (define_insn_and_split "*snedi_zero_vis3"
775   [(set (match_operand:DI 0 "register_operand" "=r")
776         (ne:DI (match_operand:DI 1 "register_operand" "r")
777                (const_int 0)))
778    (clobber (reg:CCX CC_REG))]
779   "TARGET_ARCH64 && TARGET_VIS3"
780   "#"
781   ""
782   [(set (reg:CCX_NOOV CC_REG) (compare:CCX_NOOV (neg:DI (match_dup 1))
783                                                 (const_int 0)))
784    (set (match_dup 0) (ltu:DI (reg:CCX CC_REG) (const_int 0)))]
785   ""
786   [(set_attr "length" "2")])
788 (define_insn_and_split "*neg_snedi_zero"
789   [(set (match_operand:DI 0 "register_operand" "=&r")
790         (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
791                        (const_int 0))))]
792   "TARGET_ARCH64"
793   "#"
794   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
795   [(set (match_dup 0) (const_int 0))
796    (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
797                                               (const_int 0))
798                                        (const_int -1)
799                                        (match_dup 0)))]
800   ""
801   [(set_attr "length" "2")])
803 (define_insn_and_split "*snedi_zero_trunc"
804   [(set (match_operand:SI 0 "register_operand" "=&r")
805         (ne:SI (match_operand:DI 1 "register_operand" "r")
806                (const_int 0)))]
807   "TARGET_ARCH64 && ! TARGET_VIS3"
808   "#"
809   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
810   [(set (match_dup 0) (const_int 0))
811    (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
812                                               (const_int 0))
813                                        (const_int 1)
814                                        (match_dup 0)))]
815   ""
816   [(set_attr "length" "2")])
818 (define_insn_and_split "*snedi_zero_trunc_vis3"
819   [(set (match_operand:SI 0 "register_operand" "=r")
820         (ne:SI (match_operand:DI 1 "register_operand" "r")
821                (const_int 0)))
822    (clobber (reg:CCX CC_REG))]
823   "TARGET_ARCH64 && TARGET_VIS3"
824   "#"
825   ""
826   [(set (reg:CCX_NOOV CC_REG) (compare:CCX_NOOV (neg:DI (match_dup 1))
827                                                 (const_int 0)))
828    (set (match_dup 0) (ltu:SI (reg:CCX CC_REG) (const_int 0)))]
829   ""
830   [(set_attr "length" "2")])
832 (define_insn_and_split "*seqsi<P:mode>_zero"
833   [(set (match_operand:P 0 "register_operand" "=r")
834         (eq:P (match_operand:SI 1 "register_operand" "r")
835                (const_int 0)))
836    (clobber (reg:CC CC_REG))]
837   ""
838   "#"
839   ""
840   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
841                                            (const_int 0)))
842    (set (match_dup 0) (geu:P (reg:CC CC_REG) (const_int 0)))]
843   ""
844   [(set_attr "length" "2")])
846 (define_insn_and_split "*neg_seqsisi_zero"
847   [(set (match_operand:SI 0 "register_operand" "=r")
848         (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
849                        (const_int 0))))
850    (clobber (reg:CC CC_REG))]
851   ""
852   "#"
853   ""
854   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
855                                            (const_int 0)))
856    (set (match_dup 0) (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0))))]
857   ""
858   [(set_attr "length" "2")])
860 (define_insn_and_split "*neg_seqsidi_zero"
861   [(set (match_operand:DI 0 "register_operand" "=r")
862         (neg:DI (eq:DI (match_operand:SI 1 "register_operand" "r")
863                        (const_int 0))))
864    (clobber (reg:CC CC_REG))]
865   "TARGET_ARCH64"
866   "#"
867   "&& 1"
868   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
869                                            (const_int 0)))
870    (set (match_dup 0) (sign_extend:DI (neg:SI (geu:SI (reg:CC CC_REG)
871                                                       (const_int 0)))))]
872   ""
873   [(set_attr "length" "2")])
875 (define_insn_and_split "*seqdi_zero"
876   [(set (match_operand:DI 0 "register_operand" "=&r")
877         (eq:DI (match_operand:DI 1 "register_operand" "r")
878                (const_int 0)))]
879   "TARGET_ARCH64"
880   "#"
881   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
882   [(set (match_dup 0) (const_int 0))
883    (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
884                                               (const_int 0))
885                                        (const_int 1)
886                                        (match_dup 0)))]
887   ""
888   [(set_attr "length" "2")])
890 (define_insn_and_split "*neg_seqdi_zero"
891   [(set (match_operand:DI 0 "register_operand" "=&r")
892         (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
893                        (const_int 0))))]
894   "TARGET_ARCH64"
895   "#"
896   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
897   [(set (match_dup 0) (const_int 0))
898    (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
899                                               (const_int 0))
900                                        (const_int -1)
901                                        (match_dup 0)))]
902   ""
903   [(set_attr "length" "2")]) 
905 (define_insn_and_split "*seqdi_zero_trunc"
906   [(set (match_operand:SI 0 "register_operand" "=&r")
907         (eq:SI (match_operand:DI 1 "register_operand" "r")
908                (const_int 0)))]
909   "TARGET_ARCH64"
910   "#"
911   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
912   [(set (match_dup 0) (const_int 0))
913    (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
914                                               (const_int 0))
915                                        (const_int 1)
916                                        (match_dup 0)))]
917   ""
918   [(set_attr "length" "2")])
920 ;; We can also do (x + (i == 0)) and related, so put them in.
921 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
922 ;; versions for v9.
924 (define_insn_and_split "*x_plus_i_ne_0"
925   [(set (match_operand:SI 0 "register_operand" "=r")
926         (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
927                         (const_int 0))
928                  (match_operand:SI 2 "register_operand" "r")))
929    (clobber (reg:CC CC_REG))]
930   ""
931   "#"
932   ""
933   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
934                                            (const_int 0)))
935    (set (match_dup 0) (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
936                                (match_dup 2)))]
937   ""
938   [(set_attr "length" "2")])
940 (define_insn_and_split "*x_minus_i_ne_0"
941   [(set (match_operand:SI 0 "register_operand" "=r")
942         (minus:SI (match_operand:SI 2 "register_operand" "r")
943                   (ne:SI (match_operand:SI 1 "register_operand" "r")
944                          (const_int 0))))
945    (clobber (reg:CC CC_REG))]
946   ""
947   "#"
948   ""
949   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
950                                            (const_int 0)))
951    (set (match_dup 0) (minus:SI (match_dup 2)
952                                 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
953   ""
954   [(set_attr "length" "2")])
956 (define_insn_and_split "*x_plus_i_eq_0"
957   [(set (match_operand:SI 0 "register_operand" "=r")
958         (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
959                         (const_int 0))
960                  (match_operand:SI 2 "register_operand" "r")))
961    (clobber (reg:CC CC_REG))]
962   ""
963   "#"
964   ""
965   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
966                                            (const_int 0)))
967    (set (match_dup 0) (plus:SI (geu:SI (reg:CC CC_REG) (const_int 0))
968                                (match_dup 2)))]
969   ""
970   [(set_attr "length" "2")])
972 (define_insn_and_split "*x_minus_i_eq_0"
973   [(set (match_operand:SI 0 "register_operand" "=r")
974         (minus:SI (match_operand:SI 2 "register_operand" "r")
975                   (eq:SI (match_operand:SI 1 "register_operand" "r")
976                          (const_int 0))))
977    (clobber (reg:CC CC_REG))]
978   ""
979   "#"
980   ""
981   [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1))
982                                            (const_int 0)))
983    (set (match_dup 0) (minus:SI (match_dup 2)
984                                 (geu:SI (reg:CC CC_REG) (const_int 0))))]
985   ""
986   [(set_attr "length" "2")])
988 ;; We can also do GEU and LTU directly, but these operate after a compare.
989 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
990 ;; versions for v9.
992 (define_insn "*sltu<P:mode>_insn"
993   [(set (match_operand:P 0 "register_operand" "=r")
994         (ltu:P (reg:CC CC_REG) (const_int 0)))]
995   ""
996   "addx\t%%g0, 0, %0"
997   [(set_attr "type" "ialuX")])
999 (define_insn "*sltu_insn_vis3"
1000   [(set (match_operand:DI 0 "register_operand" "=r")
1001         (ltu:DI (reg:CCX CC_REG) (const_int 0)))]
1002   "TARGET_ARCH64 && TARGET_VIS3"
1003   "addxc\t%%g0, %%g0, %0"
1004   [(set_attr "type" "ialuX")])
1006 (define_insn "*sltu_insn_vis3_trunc"
1007   [(set (match_operand:SI 0 "register_operand" "=r")
1008         (ltu:SI (reg:CCX CC_REG) (const_int 0)))]
1009   "TARGET_ARCH64 && TARGET_VIS3"
1010   "addxc\t%%g0, %%g0, %0"
1011   [(set_attr "type" "ialuX")])
1013 (define_insn "*neg_sltusi_insn"
1014   [(set (match_operand:SI 0 "register_operand" "=r")
1015         (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0))))]
1016   ""
1017   "subx\t%%g0, 0, %0"
1018   [(set_attr "type" "ialuX")])
1020 (define_insn "*neg_sltudi_insn"
1021   [(set (match_operand:DI 0 "register_operand" "=r")
1022         (sign_extend:DI (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0)))))]
1023   "TARGET_ARCH64"
1024   "subx\t%%g0, 0, %0"
1025   [(set_attr "type" "ialuX")])
1027 (define_insn "*neg_sltu_minus_x"
1028   [(set (match_operand:SI 0 "register_operand" "=r")
1029         (minus:SI (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0)))
1030                   (match_operand:SI 1 "arith_operand" "rI")))]
1031   ""
1032   "subx\t%%g0, %1, %0"
1033   [(set_attr "type" "ialuX")])
1035 (define_insn "*neg_sltu_plus_x"
1036   [(set (match_operand:SI 0 "register_operand" "=r")
1037         (neg:SI (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
1038                          (match_operand:SI 1 "arith_operand" "rI"))))]
1039   ""
1040   "subx\t%%g0, %1, %0"
1041   [(set_attr "type" "ialuX")])
1043 (define_insn "*sgeu<P:mode>_insn"
1044   [(set (match_operand:P 0 "register_operand" "=r")
1045         (geu:P (reg:CC CC_REG) (const_int 0)))]
1046   ""
1047   "subx\t%%g0, -1, %0"
1048   [(set_attr "type" "ialuX")])
1050 (define_insn "*neg_sgeusi_insn"
1051   [(set (match_operand:SI 0 "register_operand" "=r")
1052         (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0))))]
1053   ""
1054   "addx\t%%g0, -1, %0"
1055   [(set_attr "type" "ialuX")])
1057 (define_insn "*neg_sgeudi_insn"
1058   [(set (match_operand:DI 0 "register_operand" "=r")
1059         (sign_extend:DI (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0)))))]
1060   "TARGET_ARCH64"
1061   "addx\t%%g0, -1, %0"
1062   [(set_attr "type" "ialuX")])
1064 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
1065 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1066 ;; versions for v9.
1068 (define_insn "*sltu_plus_x"
1069   [(set (match_operand:SI 0 "register_operand" "=r")
1070         (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
1071                  (match_operand:SI 1 "arith_operand" "rI")))]
1072   ""
1073   "addx\t%%g0, %1, %0"
1074   [(set_attr "type" "ialuX")])
1076 (define_insn "*sltu_plus_x_plus_y"
1077   [(set (match_operand:SI 0 "register_operand" "=r")
1078         (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
1079                  (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1080                           (match_operand:SI 2 "arith_operand" "rI"))))]
1081   ""
1082   "addx\t%1, %2, %0"
1083   [(set_attr "type" "ialuX")])
1085 (define_insn "*x_minus_sltu"
1086   [(set (match_operand:SI 0 "register_operand" "=r")
1087         (minus:SI (match_operand:SI 1 "register_operand" "r")
1088                   (ltu:SI (reg:CC CC_REG) (const_int 0))))]
1089   ""
1090   "subx\t%1, 0, %0"
1091   [(set_attr "type" "ialuX")])
1093 ;; ??? Combine should canonicalize these next two to the same pattern.
1094 (define_insn "*x_minus_y_minus_sltu"
1095   [(set (match_operand:SI 0 "register_operand" "=r")
1096         (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
1097                             (match_operand:SI 2 "arith_operand" "rI"))
1098                   (ltu:SI (reg:CC CC_REG) (const_int 0))))]
1099   ""
1100   "subx\t%r1, %2, %0"
1101   [(set_attr "type" "ialuX")])
1103 (define_insn "*x_minus_sltu_plus_y"
1104   [(set (match_operand:SI 0 "register_operand" "=r")
1105         (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
1106                   (plus:SI (ltu:SI (reg:CC CC_REG) (const_int 0))
1107                            (match_operand:SI 2 "arith_operand" "rI"))))]
1108   ""
1109   "subx\t%r1, %2, %0"
1110   [(set_attr "type" "ialuX")])
1112 (define_insn "*sgeu_plus_x"
1113   [(set (match_operand:SI 0 "register_operand" "=r")
1114         (plus:SI (geu:SI (reg:CC CC_REG) (const_int 0))
1115                  (match_operand:SI 1 "register_operand" "r")))]
1116   ""
1117   "subx\t%1, -1, %0"
1118   [(set_attr "type" "ialuX")])
1120 (define_insn "*x_minus_sgeu"
1121   [(set (match_operand:SI 0 "register_operand" "=r")
1122         (minus:SI (match_operand:SI 1 "register_operand" "r")
1123                   (geu:SI (reg:CC CC_REG) (const_int 0))))]
1124   ""
1125   "addx\t%1, -1, %0"
1126   [(set_attr "type" "ialuX")])
1128 (define_split
1129   [(set (match_operand:SI 0 "register_operand" "")
1130         (match_operator:SI 2 "noov_compare_operator"
1131                            [(match_operand 1 "icc_or_fcc_register_operand" "")
1132                             (const_int 0)]))]
1133   "TARGET_V9
1134    && REGNO (operands[1]) == SPARC_ICC_REG
1135    && (GET_MODE (operands[1]) == CCXmode
1136        /* 32-bit LTU/GEU are better implemented using addx/subx.  */
1137        || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1138   [(set (match_dup 0) (const_int 0))
1139    (set (match_dup 0)
1140         (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1141                          (const_int 1)
1142                          (match_dup 0)))]
1143   "")
1146 ;; These control RTL generation for conditional jump insns
1148 (define_expand "cbranchcc4"
1149   [(set (pc)
1150         (if_then_else (match_operator 0 "comparison_operator"
1151                           [(match_operand 1 "compare_operand" "")
1152                            (match_operand 2 "const_zero_operand" "")])
1153                       (label_ref (match_operand 3 "" ""))
1154                       (pc)))]
1155   ""
1156   "")
1158 (define_expand "cbranchsi4"
1159   [(use (match_operator 0 "comparison_operator"
1160          [(match_operand:SI 1 "compare_operand" "")
1161           (match_operand:SI 2 "arith_operand" "")]))
1162    (use (match_operand 3 ""))]
1163   ""
1165   if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
1166     operands[1] = force_reg (SImode, operands[1]);
1167   emit_conditional_branch_insn (operands);
1168   DONE;
1171 (define_expand "cbranchdi4"
1172   [(use (match_operator 0 "comparison_operator"
1173          [(match_operand:DI 1 "compare_operand" "")
1174           (match_operand:DI 2 "arith_operand" "")]))
1175    (use (match_operand 3 ""))]
1176   "TARGET_ARCH64"
1178   if (GET_CODE (operands[1]) == ZERO_EXTRACT && operands[2] != const0_rtx)
1179     operands[1] = force_reg (DImode, operands[1]);
1180   emit_conditional_branch_insn (operands);
1181   DONE;
1184 (define_expand "cbranch<F:mode>4"
1185   [(use (match_operator 0 "comparison_operator"
1186          [(match_operand:F 1 "register_operand" "")
1187           (match_operand:F 2 "register_operand" "")]))
1188    (use (match_operand 3 ""))]
1189   "TARGET_FPU"
1190   { emit_conditional_branch_insn (operands); DONE; })
1193 ;; Now match both normal and inverted jump.
1195 ;; XXX fpcmp nop braindamage
1196 (define_insn "*normal_branch"
1197   [(set (pc)
1198         (if_then_else (match_operator 0 "noov_compare_operator"
1199                                       [(reg CC_REG) (const_int 0)])
1200                       (label_ref (match_operand 1 "" ""))
1201                       (pc)))]
1202   ""
1204   return output_cbranch (operands[0], operands[1], 1, 0,
1205                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1206                          insn);
1208   [(set_attr "type" "branch")
1209    (set_attr "branch_type" "icc")])
1211 ;; XXX fpcmp nop braindamage
1212 (define_insn "*inverted_branch"
1213   [(set (pc)
1214         (if_then_else (match_operator 0 "noov_compare_operator"
1215                                       [(reg CC_REG) (const_int 0)])
1216                       (pc)
1217                       (label_ref (match_operand 1 "" ""))))]
1218   ""
1220   return output_cbranch (operands[0], operands[1], 1, 1,
1221                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1222                          insn);
1224   [(set_attr "type" "branch")
1225    (set_attr "branch_type" "icc")])
1227 ;; XXX fpcmp nop braindamage
1228 (define_insn "*normal_fp_branch"
1229   [(set (pc)
1230         (if_then_else (match_operator 1 "comparison_operator"
1231                                       [(match_operand:CCFP 0 "fcc_register_operand" "c")
1232                                        (const_int 0)])
1233                       (label_ref (match_operand 2 "" ""))
1234                       (pc)))]
1235   ""
1237   return output_cbranch (operands[1], operands[2], 2, 0,
1238                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1239                          insn);
1241   [(set_attr "type" "branch")
1242    (set_attr "branch_type" "fcc")])
1244 ;; XXX fpcmp nop braindamage
1245 (define_insn "*inverted_fp_branch"
1246   [(set (pc)
1247         (if_then_else (match_operator 1 "comparison_operator"
1248                                       [(match_operand:CCFP 0 "fcc_register_operand" "c")
1249                                        (const_int 0)])
1250                       (pc)
1251                       (label_ref (match_operand 2 "" ""))))]
1252   ""
1254   return output_cbranch (operands[1], operands[2], 2, 1,
1255                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1256                          insn);
1258   [(set_attr "type" "branch")
1259    (set_attr "branch_type" "fcc")])
1261 ;; XXX fpcmp nop braindamage
1262 (define_insn "*normal_fpe_branch"
1263   [(set (pc)
1264         (if_then_else (match_operator 1 "comparison_operator"
1265                                       [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1266                                        (const_int 0)])
1267                       (label_ref (match_operand 2 "" ""))
1268                       (pc)))]
1269   ""
1271   return output_cbranch (operands[1], operands[2], 2, 0,
1272                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1273                          insn);
1275   [(set_attr "type" "branch")
1276    (set_attr "branch_type" "fcc")])
1278 ;; XXX fpcmp nop braindamage
1279 (define_insn "*inverted_fpe_branch"
1280   [(set (pc)
1281         (if_then_else (match_operator 1 "comparison_operator"
1282                                       [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1283                                        (const_int 0)])
1284                       (pc)
1285                       (label_ref (match_operand 2 "" ""))))]
1286   ""
1288   return output_cbranch (operands[1], operands[2], 2, 1,
1289                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1290                          insn);
1292   [(set_attr "type" "branch")
1293    (set_attr "branch_type" "fcc")])
1295 ;; SPARC V9-specific jump insns.  None of these are guaranteed to be
1296 ;; in the architecture.
1298 (define_insn "*cbcond_sp32"
1299   [(set (pc)
1300         (if_then_else (match_operator 0 "noov_compare_operator"
1301                        [(match_operand:SI 1 "register_operand" "r")
1302                         (match_operand:SI 2 "arith5_operand" "rA")])
1303                       (label_ref (match_operand 3 "" ""))
1304                       (pc)))]
1305   "TARGET_CBCOND"
1307   return output_cbcond (operands[0], operands[3], insn);
1309   [(set_attr "type" "cbcond")])
1311 (define_insn "*cbcond_sp64"
1312   [(set (pc)
1313         (if_then_else (match_operator 0 "noov_compare_operator"
1314                        [(match_operand:DI 1 "register_operand" "r")
1315                         (match_operand:DI 2 "arith5_operand" "rA")])
1316                       (label_ref (match_operand 3 "" ""))
1317                       (pc)))]
1318   "TARGET_ARCH64 && TARGET_CBCOND"
1320   return output_cbcond (operands[0], operands[3], insn);
1322   [(set_attr "type" "cbcond")])
1324 ;; There are no 32 bit brreg insns.
1326 (define_insn "*normal_int_branch_sp64"
1327   [(set (pc)
1328         (if_then_else (match_operator 0 "v9_register_compare_operator"
1329                                       [(match_operand:DI 1 "register_operand" "r")
1330                                        (const_int 0)])
1331                       (label_ref (match_operand 2 "" ""))
1332                       (pc)))]
1333   "TARGET_ARCH64"
1335   return output_v9branch (operands[0], operands[2], 1, 2, 0,
1336                           final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1337                           insn);
1339   [(set_attr "type" "branch")
1340    (set_attr "branch_type" "reg")])
1342 (define_insn "*inverted_int_branch_sp64"
1343   [(set (pc)
1344         (if_then_else (match_operator 0 "v9_register_compare_operator"
1345                                       [(match_operand:DI 1 "register_operand" "r")
1346                                        (const_int 0)])
1347                       (pc)
1348                       (label_ref (match_operand 2 "" ""))))]
1349   "TARGET_ARCH64"
1351   return output_v9branch (operands[0], operands[2], 1, 2, 1,
1352                           final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1353                           insn);
1355   [(set_attr "type" "branch")
1356    (set_attr "branch_type" "reg")])
1359 ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic
1360 ;; value subject to a PC-relative relocation.  Operand 2 is a helper function
1361 ;; that adds the PC value at the call point to register #(operand 3).
1363 ;; Even on V9 we use this call sequence with a stub, instead of "rd %pc, ..."
1364 ;; because the RDPC instruction is extremely expensive and incurs a complete
1365 ;; instruction pipeline flush.
1367 (define_insn "load_pcrel_sym<P:mode>"
1368   [(set (match_operand:P 0 "register_operand" "=r")
1369         (unspec:P [(match_operand:P 1 "symbolic_operand" "")
1370                    (match_operand:P 2 "call_address_operand" "")
1371                    (match_operand:P 3 "const_int_operand" "")] UNSPEC_LOAD_PCREL_SYM))
1372    (clobber (reg:P O7_REG))]
1373   "REGNO (operands[0]) == INTVAL (operands[3])"
1375   if (flag_delayed_branch)
1376     return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0";
1377   else
1378     return "sethi\t%%hi(%a1-8), %0\n\tadd\t%0, %%lo(%a1-4), %0\n\tcall\t%a2\n\t nop";
1380   [(set (attr "type") (const_string "multi"))
1381    (set (attr "length")
1382         (if_then_else (eq_attr "delayed_branch" "true")
1383                       (const_int 3)
1384                       (const_int 4)))])
1387 ;; Integer move instructions
1389 (define_expand "movqi"
1390   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1391         (match_operand:QI 1 "general_operand" ""))]
1392   ""
1394   if (sparc_expand_move (QImode, operands))
1395     DONE;
1398 (define_insn "*movqi_insn"
1399   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1400         (match_operand:QI 1 "input_operand"   "rI,m,rJ"))]
1401   "(register_operand (operands[0], QImode)
1402     || register_or_zero_operand (operands[1], QImode))"
1403   "@
1404    mov\t%1, %0
1405    ldub\t%1, %0
1406    stb\t%r1, %0"
1407   [(set_attr "type" "*,load,store")
1408    (set_attr "us3load_type" "*,3cycle,*")])
1410 (define_expand "movhi"
1411   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1412         (match_operand:HI 1 "general_operand" ""))]
1413   ""
1415   if (sparc_expand_move (HImode, operands))
1416     DONE;
1419 (define_insn "*movhi_insn"
1420   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1421         (match_operand:HI 1 "input_operand"   "rI,K,m,rJ"))]
1422   "(register_operand (operands[0], HImode)
1423     || register_or_zero_operand (operands[1], HImode))"
1424   "@
1425    mov\t%1, %0
1426    sethi\t%%hi(%a1), %0
1427    lduh\t%1, %0
1428    sth\t%r1, %0"
1429   [(set_attr "type" "*,*,load,store")
1430    (set_attr "us3load_type" "*,*,3cycle,*")])
1432 ;; We always work with constants here.
1433 (define_insn "*movhi_lo_sum"
1434   [(set (match_operand:HI 0 "register_operand" "=r")
1435         (ior:HI (match_operand:HI 1 "register_operand" "%r")
1436                 (match_operand:HI 2 "small_int_operand" "I")))]
1437   ""
1438   "or\t%1, %2, %0")
1440 (define_expand "movsi"
1441   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1442         (match_operand:SI 1 "general_operand" ""))]
1443   ""
1445   if (sparc_expand_move (SImode, operands))
1446     DONE;
1449 (define_insn "*movsi_insn"
1450   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r, m, r,*f,*f,*f, m,d,d")
1451         (match_operand:SI 1 "input_operand"        "rI,K,m,rJ,*f, r, f, m,*f,J,P"))]
1452   "register_operand (operands[0], SImode)
1453    || register_or_zero_or_all_ones_operand (operands[1], SImode)"
1454   "@
1455    mov\t%1, %0
1456    sethi\t%%hi(%a1), %0
1457    ld\t%1, %0
1458    st\t%r1, %0
1459    movstouw\t%1, %0
1460    movwtos\t%1, %0
1461    fmovs\t%1, %0
1462    ld\t%1, %0
1463    st\t%1, %0
1464    fzeros\t%0
1465    fones\t%0"
1466   [(set_attr "type" "*,*,load,store,vismv,vismv,fpmove,fpload,fpstore,visl,visl")
1467    (set_attr "v3pipe" "*,*,*,*,true,true,*,*,*,true,true")
1468    (set_attr "cpu_feature" "*,*,*,*,vis3,vis3,*,*,*,vis,vis")])
1470 (define_insn "*movsi_lo_sum"
1471   [(set (match_operand:SI 0 "register_operand" "=r")
1472         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1473                    (match_operand:SI 2 "immediate_operand" "in")))]
1474   ""
1475   "or\t%1, %%lo(%a2), %0")
1477 (define_insn "*movsi_high"
1478   [(set (match_operand:SI 0 "register_operand" "=r")
1479         (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1480   ""
1481   "sethi\t%%hi(%a1), %0")
1483 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1484 ;; so that CSE won't optimize the address computation away.
1485 (define_insn "movsi_lo_sum_pic"
1486   [(set (match_operand:SI 0 "register_operand" "=r")
1487         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1488                    (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1489   "flag_pic"
1491 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1492   return "xor\t%1, %%gdop_lox10(%a2), %0";
1493 #else
1494   return "or\t%1, %%lo(%a2), %0";
1495 #endif
1498 (define_insn "movsi_high_pic"
1499   [(set (match_operand:SI 0 "register_operand" "=r")
1500         (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1501   "flag_pic && check_pic (1)"
1503 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1504   return "sethi\t%%gdop_hix22(%a1), %0";
1505 #else
1506   return "sethi\t%%hi(%a1), %0";
1507 #endif
1510 (define_insn "movsi_pic_gotdata_op"
1511   [(set (match_operand:SI 0 "register_operand" "=r")
1512         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
1513                     (match_operand:SI 2 "register_operand" "r")
1514                     (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
1515   "flag_pic && check_pic (1)"
1517 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1518   return "ld\t[%1 + %2], %0, %%gdop(%a3)";
1519 #else
1520   return "ld\t[%1 + %2], %0";
1521 #endif
1523   [(set_attr "type" "load")])
1525 (define_expand "movsi_pic_label_ref"
1526   [(set (match_dup 3) (high:SI
1527      (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1528                  (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1529    (set (match_dup 4) (lo_sum:SI (match_dup 3)
1530      (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1531    (set (match_operand:SI 0 "register_operand" "=r")
1532         (minus:SI (match_dup 5) (match_dup 4)))]
1533   "flag_pic"
1535   crtl->uses_pic_offset_table = 1;
1536   operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1537   if (!can_create_pseudo_p ())
1538     {
1539       operands[3] = operands[0];
1540       operands[4] = operands[0];
1541     }
1542   else
1543     {
1544       operands[3] = gen_reg_rtx (SImode);
1545       operands[4] = gen_reg_rtx (SImode);
1546     }
1547   operands[5] = pic_offset_table_rtx;
1550 (define_insn "*movsi_high_pic_label_ref"
1551   [(set (match_operand:SI 0 "register_operand" "=r")
1552       (high:SI
1553         (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1554                     (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1555   "flag_pic"
1556   "sethi\t%%hi(%a2-(%a1-.)), %0")
1558 (define_insn "*movsi_lo_sum_pic_label_ref"
1559   [(set (match_operand:SI 0 "register_operand" "=r")
1560       (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1561         (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
1562                     (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1563   "flag_pic"
1564   "or\t%1, %%lo(%a3-(%a2-.)), %0")
1566 ;; Set up the PIC register for VxWorks.
1568 (define_expand "vxworks_load_got"
1569   [(set (match_dup 0)
1570         (high:SI (match_dup 1)))
1571    (set (match_dup 0)
1572         (mem:SI (lo_sum:SI (match_dup 0) (match_dup 1))))
1573    (set (match_dup 0)
1574         (mem:SI (lo_sum:SI (match_dup 0) (match_dup 2))))]
1575   "TARGET_VXWORKS_RTP"
1577   operands[0] = pic_offset_table_rtx;
1578   operands[1] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_BASE);
1579   operands[2] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_INDEX);
1582 (define_expand "movdi"
1583   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1584         (match_operand:DI 1 "general_operand" ""))]
1585   ""
1587   if (sparc_expand_move (DImode, operands))
1588     DONE;
1591 ;; Be careful, fmovd does not exist when !v9.
1592 ;; We match MEM moves directly when we have correct even
1593 ;; numbered registers, but fall into splits otherwise.
1594 ;; The constraint ordering here is really important to
1595 ;; avoid insane problems in reload, especially for patterns
1596 ;; of the form:
1598 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
1599 ;;                       (const_int -5016)))
1600 ;;      (reg:DI 2 %g2))
1603 (define_insn "*movdi_insn_sp32"
1604   [(set (match_operand:DI 0 "nonimmediate_operand"
1605                                         "=T,o,T,U,o,r,r,r,?T,?*f,?*f,?o,?*e,?*e,  r,?*f,?*e,?W,b,b")
1606         (match_operand:DI 1 "input_operand"
1607                                         " J,J,U,T,r,o,i,r,*f,  T,  o,*f, *e, *e,?*f,  r,  W,*e,J,P"))]
1608   "! TARGET_ARCH64
1609    && (register_operand (operands[0], DImode)
1610        || register_or_zero_operand (operands[1], DImode))"
1611   "@
1612    stx\t%%g0, %0
1613    #
1614    std\t%1, %0
1615    ldd\t%1, %0
1616    #
1617    #
1618    #
1619    #
1620    std\t%1, %0
1621    ldd\t%1, %0
1622    #
1623    #
1624    fmovd\t%1, %0
1625    #
1626    #
1627    #
1628    ldd\t%1, %0
1629    std\t%1, %0
1630    fzero\t%0
1631    fone\t%0"
1632   [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,*,*,*,fpload,fpstore,visl,visl")
1633    (set_attr "v3pipe" "false, false, false, false,false,false,false,false,false,false,false,false,false,false,false,false,false,false, true, true")
1634    (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,2,2,2,*,*,*,*")
1635    (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*,*,*,*,double,double")
1636    (set_attr "cpu_feature" "v9,*,*,*,*,*,*,*,fpu,fpu,fpu,fpu,v9,fpunotv9,vis3,vis3,fpu,fpu,vis,vis")])
1638 (define_insn "*movdi_insn_sp64"
1639   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r, m, r,*e,?*e,?*e,?W,b,b")
1640         (match_operand:DI 1 "input_operand"        "rI,N,m,rJ,*e, r, *e,  W,*e,J,P"))]
1641   "TARGET_ARCH64
1642    && (register_operand (operands[0], DImode)
1643        || register_or_zero_or_all_ones_operand (operands[1], DImode))"
1644   "@
1645    mov\t%1, %0
1646    sethi\t%%hi(%a1), %0
1647    ldx\t%1, %0
1648    stx\t%r1, %0
1649    movdtox\t%1, %0
1650    movxtod\t%1, %0
1651    fmovd\t%1, %0
1652    ldd\t%1, %0
1653    std\t%1, %0
1654    fzero\t%0
1655    fone\t%0"
1656   [(set_attr "type" "*,*,load,store,vismv,vismv,fpmove,fpload,fpstore,visl,visl")
1657    (set_attr "v3pipe" "*, *, *, *, *, *, *, *, *, true, true")
1658    (set_attr "fptype" "*,*,*,*,*,*,double,*,*,double,double")
1659    (set_attr "cpu_feature" "*,*,*,*,vis3,vis3,*,*,*,vis,vis")])
1661 (define_expand "movdi_pic_label_ref"
1662   [(set (match_dup 3) (high:DI
1663      (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1664                  (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1665    (set (match_dup 4) (lo_sum:DI (match_dup 3)
1666      (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1667    (set (match_operand:DI 0 "register_operand" "=r")
1668         (minus:DI (match_dup 5) (match_dup 4)))]
1669   "TARGET_ARCH64 && flag_pic"
1671   crtl->uses_pic_offset_table = 1;
1672   operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1673   if (!can_create_pseudo_p ())
1674     {
1675       operands[3] = operands[0];
1676       operands[4] = operands[0];
1677     }
1678   else
1679     {
1680       operands[3] = gen_reg_rtx (DImode);
1681       operands[4] = gen_reg_rtx (DImode);
1682     }
1683   operands[5] = pic_offset_table_rtx;
1686 (define_insn "*movdi_high_pic_label_ref"
1687   [(set (match_operand:DI 0 "register_operand" "=r")
1688         (high:DI
1689           (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
1690                       (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1691   "TARGET_ARCH64 && flag_pic"
1692   "sethi\t%%hi(%a2-(%a1-.)), %0")
1694 (define_insn "*movdi_lo_sum_pic_label_ref"
1695   [(set (match_operand:DI 0 "register_operand" "=r")
1696       (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1697         (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
1698                     (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1699   "TARGET_ARCH64 && flag_pic"
1700   "or\t%1, %%lo(%a3-(%a2-.)), %0")
1702 ;; SPARC-v9 code model support insns.  See sparc_emit_set_symbolic_const64
1703 ;; in sparc.c to see what is going on here... PIC stuff comes first.
1705 (define_insn "movdi_lo_sum_pic"
1706   [(set (match_operand:DI 0 "register_operand" "=r")
1707         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1708                    (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1709   "TARGET_ARCH64 && flag_pic"
1711 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1712   return "xor\t%1, %%gdop_lox10(%a2), %0";
1713 #else
1714   return "or\t%1, %%lo(%a2), %0";
1715 #endif
1718 (define_insn "movdi_high_pic"
1719   [(set (match_operand:DI 0 "register_operand" "=r")
1720         (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1721   "TARGET_ARCH64 && flag_pic && check_pic (1)"
1723 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1724   return "sethi\t%%gdop_hix22(%a1), %0";
1725 #else
1726   return "sethi\t%%hi(%a1), %0";
1727 #endif
1730 (define_insn "movdi_pic_gotdata_op"
1731   [(set (match_operand:DI 0 "register_operand" "=r")
1732         (unspec:DI [(match_operand:DI 1 "register_operand" "r")
1733                     (match_operand:DI 2 "register_operand" "r")
1734                     (match_operand 3 "symbolic_operand" "")] UNSPEC_MOVE_GOTDATA))]
1735   "TARGET_ARCH64 && flag_pic && check_pic (1)"
1737 #ifdef HAVE_AS_SPARC_GOTDATA_OP
1738   return "ldx\t[%1 + %2], %0, %%gdop(%a3)";
1739 #else
1740   return "ldx\t[%1 + %2], %0";
1741 #endif
1743   [(set_attr "type" "load")])
1745 (define_insn "*sethi_di_medlow_embmedany_pic"
1746   [(set (match_operand:DI 0 "register_operand" "=r")
1747         (high:DI (match_operand:DI 1 "medium_pic_operand" "")))]
1748   "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
1749   "sethi\t%%hi(%a1), %0")
1751 (define_insn "*sethi_di_medlow"
1752   [(set (match_operand:DI 0 "register_operand" "=r")
1753         (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
1754   "TARGET_CM_MEDLOW && check_pic (1)"
1755   "sethi\t%%hi(%a1), %0")
1757 (define_insn "*losum_di_medlow"
1758   [(set (match_operand:DI 0 "register_operand" "=r")
1759         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1760                    (match_operand:DI 2 "symbolic_operand" "")))]
1761   "TARGET_CM_MEDLOW"
1762   "or\t%1, %%lo(%a2), %0")
1764 (define_insn "seth44"
1765   [(set (match_operand:DI 0 "register_operand" "=r")
1766         (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
1767   "TARGET_CM_MEDMID"
1768   "sethi\t%%h44(%a1), %0")
1770 (define_insn "setm44"
1771   [(set (match_operand:DI 0 "register_operand" "=r")
1772         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1773                    (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
1774   "TARGET_CM_MEDMID"
1775   "or\t%1, %%m44(%a2), %0")
1777 (define_insn "setl44"
1778   [(set (match_operand:DI 0 "register_operand" "=r")
1779         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1780                    (match_operand:DI 2 "symbolic_operand" "")))]
1781   "TARGET_CM_MEDMID"
1782   "or\t%1, %%l44(%a2), %0")
1784 (define_insn "sethh"
1785   [(set (match_operand:DI 0 "register_operand" "=r")
1786         (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
1787   "TARGET_CM_MEDANY"
1788   "sethi\t%%hh(%a1), %0")
1790 (define_insn "setlm"
1791   [(set (match_operand:DI 0 "register_operand" "=r")
1792         (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
1793   "TARGET_CM_MEDANY"
1794   "sethi\t%%lm(%a1), %0")
1796 (define_insn "sethm"
1797   [(set (match_operand:DI 0 "register_operand" "=r")
1798         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1799                    (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
1800   "TARGET_CM_MEDANY"
1801   "or\t%1, %%hm(%a2), %0")
1803 (define_insn "setlo"
1804   [(set (match_operand:DI 0 "register_operand" "=r")
1805         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1806                    (match_operand:DI 2 "symbolic_operand" "")))]
1807   "TARGET_CM_MEDANY"
1808   "or\t%1, %%lo(%a2), %0")
1810 (define_insn "embmedany_sethi"
1811   [(set (match_operand:DI 0 "register_operand" "=r")
1812         (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
1813   "TARGET_CM_EMBMEDANY && check_pic (1)"
1814   "sethi\t%%hi(%a1), %0")
1816 (define_insn "embmedany_losum"
1817   [(set (match_operand:DI 0 "register_operand" "=r")
1818         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1819                    (match_operand:DI 2 "data_segment_operand" "")))]
1820   "TARGET_CM_EMBMEDANY"
1821   "add\t%1, %%lo(%a2), %0")
1823 (define_insn "embmedany_brsum"
1824   [(set (match_operand:DI 0 "register_operand" "=r")
1825         (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
1826   "TARGET_CM_EMBMEDANY"
1827   "add\t%1, %_, %0")
1829 (define_insn "embmedany_textuhi"
1830   [(set (match_operand:DI 0 "register_operand" "=r")
1831         (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
1832   "TARGET_CM_EMBMEDANY && check_pic (1)"
1833   "sethi\t%%uhi(%a1), %0")
1835 (define_insn "embmedany_texthi"
1836   [(set (match_operand:DI 0 "register_operand" "=r")
1837         (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
1838   "TARGET_CM_EMBMEDANY && check_pic (1)"
1839   "sethi\t%%hi(%a1), %0")
1841 (define_insn "embmedany_textulo"
1842   [(set (match_operand:DI 0 "register_operand" "=r")
1843         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1844                    (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
1845   "TARGET_CM_EMBMEDANY"
1846   "or\t%1, %%ulo(%a2), %0")
1848 (define_insn "embmedany_textlo"
1849   [(set (match_operand:DI 0 "register_operand" "=r")
1850         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
1851                    (match_operand:DI 2 "text_segment_operand" "")))]
1852   "TARGET_CM_EMBMEDANY"
1853   "or\t%1, %%lo(%a2), %0")
1855 ;; Now some patterns to help reload out a bit.
1856 (define_expand "reload_indi"
1857   [(parallel [(match_operand:DI 0 "register_operand" "=r")
1858               (match_operand:DI 1 "immediate_operand" "")
1859               (match_operand:TI 2 "register_operand" "=&r")])]
1860   "(TARGET_CM_MEDANY
1861     || TARGET_CM_EMBMEDANY)
1862    && ! flag_pic"
1864   sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1865   DONE;
1868 (define_expand "reload_outdi"
1869   [(parallel [(match_operand:DI 0 "register_operand" "=r")
1870               (match_operand:DI 1 "immediate_operand" "")
1871               (match_operand:TI 2 "register_operand" "=&r")])]
1872   "(TARGET_CM_MEDANY
1873     || TARGET_CM_EMBMEDANY)
1874    && ! flag_pic"
1876   sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
1877   DONE;
1880 ;; Split up putting CONSTs and REGs into DI regs when !arch64
1881 (define_split
1882   [(set (match_operand:DI 0 "register_operand" "")
1883         (match_operand:DI 1 "const_int_operand" ""))]
1884   "! TARGET_ARCH64
1885    && ((GET_CODE (operands[0]) == REG
1886         && SPARC_INT_REG_P (REGNO (operands[0])))
1887        || (GET_CODE (operands[0]) == SUBREG
1888            && GET_CODE (SUBREG_REG (operands[0])) == REG
1889            && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))
1890    && reload_completed"
1891   [(clobber (const_int 0))]
1893   HOST_WIDE_INT low, high;
1895   low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
1896   high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
1897   emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
1899   /* Slick... but this trick loses if this subreg constant part
1900      can be done in one insn.  */
1901   if (low == high
1902       && ! SPARC_SETHI32_P (high)
1903       && ! SPARC_SIMM13_P (high))
1904     emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
1905                           gen_highpart (SImode, operands[0])));
1906   else
1907     emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
1909   DONE;
1912 (define_split
1913   [(set (match_operand:DI 0 "register_operand" "")
1914         (match_operand:DI 1 "register_operand" ""))]
1915   "reload_completed
1916    && (! TARGET_V9
1917        || (! TARGET_ARCH64
1918            && sparc_split_regreg_legitimate (operands[0],
1919                                              operands[1])))"
1920   [(clobber (const_int 0))]
1922   rtx set_dest = operands[0];
1923   rtx set_src = operands[1];
1924   rtx dest1, dest2;
1925   rtx src1, src2;
1927   dest1 = gen_highpart (SImode, set_dest);
1928   dest2 = gen_lowpart (SImode, set_dest);
1929   src1 = gen_highpart (SImode, set_src);
1930   src2 = gen_lowpart (SImode, set_src);
1932   /* Now emit using the real source and destination we found, swapping
1933      the order if we detect overlap.  */
1934   if (reg_overlap_mentioned_p (dest1, src2))
1935     {
1936       emit_insn (gen_movsi (dest2, src2));
1937       emit_insn (gen_movsi (dest1, src1));
1938     }
1939   else
1940     {
1941       emit_insn (gen_movsi (dest1, src1));
1942       emit_insn (gen_movsi (dest2, src2));
1943     }
1944   DONE;
1947 ;; Now handle the cases of memory moves from/to non-even
1948 ;; DI mode register pairs.
1949 (define_split
1950   [(set (match_operand:DI 0 "register_operand" "")
1951         (match_operand:DI 1 "memory_operand" ""))]
1952   "(! TARGET_ARCH64
1953     && reload_completed
1954     && sparc_splitdi_legitimate (operands[0], operands[1]))"
1955   [(clobber (const_int 0))]
1957   rtx word0 = adjust_address (operands[1], SImode, 0);
1958   rtx word1 = adjust_address (operands[1], SImode, 4);
1959   rtx high_part = gen_highpart (SImode, operands[0]);
1960   rtx low_part = gen_lowpart (SImode, operands[0]);
1962   if (reg_overlap_mentioned_p (high_part, word1))
1963     {
1964       emit_insn (gen_movsi (low_part, word1));
1965       emit_insn (gen_movsi (high_part, word0));
1966     }
1967   else
1968     {
1969       emit_insn (gen_movsi (high_part, word0));
1970       emit_insn (gen_movsi (low_part, word1));
1971     }
1972   DONE;
1975 (define_split
1976   [(set (match_operand:DI 0 "memory_operand" "")
1977         (match_operand:DI 1 "register_operand" ""))]
1978   "(! TARGET_ARCH64
1979     && reload_completed
1980     && sparc_splitdi_legitimate (operands[1], operands[0]))"
1981   [(clobber (const_int 0))]
1983   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
1984                         gen_highpart (SImode, operands[1])));
1985   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
1986                         gen_lowpart (SImode, operands[1])));
1987   DONE;
1990 (define_split
1991   [(set (match_operand:DI 0 "memory_operand" "")
1992         (match_operand:DI 1 "const_zero_operand" ""))]
1993   "reload_completed
1994    && (! TARGET_V9
1995        || (! TARGET_ARCH64
1996            && ! mem_min_alignment (operands[0], 8)))
1997    && offsettable_memref_p (operands[0])"
1998   [(clobber (const_int 0))]
2000   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
2001   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
2002   DONE;
2005 (define_expand "movti"
2006   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2007         (match_operand:TI 1 "general_operand" ""))]
2008   "TARGET_ARCH64"
2010   if (sparc_expand_move (TImode, operands))
2011     DONE;
2014 ;; We need to prevent reload from splitting TImode moves, because it
2015 ;; might decide to overwrite a pointer with the value it points to.
2016 ;; In that case we have to do the loads in the appropriate order so
2017 ;; that the pointer is not destroyed too early.
2019 (define_insn "*movti_insn_sp64"
2020   [(set (match_operand:TI 0 "nonimmediate_operand" "=r , o,?*e,?o,b")
2021         (match_operand:TI 1 "input_operand"        "roJ,rJ, eo, e,J"))]
2022   "TARGET_ARCH64
2023    && ! TARGET_HARD_QUAD
2024    && (register_operand (operands[0], TImode)
2025        || register_or_zero_operand (operands[1], TImode))"
2026   "#"
2027   [(set_attr "length" "2,2,2,2,2")
2028    (set_attr "cpu_feature" "*,*,fpu,fpu,vis")])
2030 (define_insn "*movti_insn_sp64_hq"
2031   [(set (match_operand:TI 0 "nonimmediate_operand" "=r , o,?*e,?*e,?m,b")
2032         (match_operand:TI 1 "input_operand"        "roJ,rJ,  e,  m, e,J"))]
2033   "TARGET_ARCH64
2034    && TARGET_HARD_QUAD
2035    && (register_operand (operands[0], TImode)
2036        || register_or_zero_operand (operands[1], TImode))"
2037   "@
2038   #
2039   #
2040   fmovq\t%1, %0
2041   ldq\t%1, %0
2042   stq\t%1, %0
2043   #"
2044   [(set_attr "type" "*,*,fpmove,fpload,fpstore,*")
2045    (set_attr "length" "2,2,*,*,*,2")])
2047 ;; Now all the splits to handle multi-insn TI mode moves.
2048 (define_split
2049   [(set (match_operand:TI 0 "register_operand" "")
2050         (match_operand:TI 1 "register_operand" ""))]
2051   "reload_completed
2052    && ((TARGET_FPU
2053         && ! TARGET_HARD_QUAD)
2054        || (! fp_register_operand (operands[0], TImode)
2055            && ! fp_register_operand (operands[1], TImode)))"
2056   [(clobber (const_int 0))]
2058   rtx set_dest = operands[0];
2059   rtx set_src = operands[1];
2060   rtx dest1, dest2;
2061   rtx src1, src2;
2063   dest1 = gen_highpart (DImode, set_dest);
2064   dest2 = gen_lowpart (DImode, set_dest);
2065   src1 = gen_highpart (DImode, set_src);
2066   src2 = gen_lowpart (DImode, set_src);
2068   /* Now emit using the real source and destination we found, swapping
2069      the order if we detect overlap.  */
2070   if (reg_overlap_mentioned_p (dest1, src2))
2071     {
2072       emit_insn (gen_movdi (dest2, src2));
2073       emit_insn (gen_movdi (dest1, src1));
2074     }
2075   else
2076     {
2077       emit_insn (gen_movdi (dest1, src1));
2078       emit_insn (gen_movdi (dest2, src2));
2079     }
2080   DONE;
2083 (define_split
2084   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2085         (match_operand:TI 1 "const_zero_operand" ""))]
2086   "reload_completed"
2087   [(clobber (const_int 0))]
2089   rtx set_dest = operands[0];
2090   rtx dest1, dest2;
2092   switch (GET_CODE (set_dest))
2093     {
2094     case REG:
2095       dest1 = gen_highpart (DImode, set_dest);
2096       dest2 = gen_lowpart (DImode, set_dest);
2097       break;
2098     case MEM:
2099       dest1 = adjust_address (set_dest, DImode, 0);
2100       dest2 = adjust_address (set_dest, DImode, 8);
2101       break;
2102     default:
2103       gcc_unreachable ();
2104     }
2106   emit_insn (gen_movdi (dest1, const0_rtx));
2107   emit_insn (gen_movdi (dest2, const0_rtx));
2108   DONE;
2111 (define_split
2112   [(set (match_operand:TI 0 "register_operand" "")
2113         (match_operand:TI 1 "memory_operand" ""))]
2114   "reload_completed
2115    && offsettable_memref_p (operands[1])
2116    && (! TARGET_HARD_QUAD
2117        || ! fp_register_operand (operands[0], TImode))"
2118   [(clobber (const_int 0))]
2120   rtx word0 = adjust_address (operands[1], DImode, 0);
2121   rtx word1 = adjust_address (operands[1], DImode, 8);
2122   rtx set_dest, dest1, dest2;
2124   set_dest = operands[0];
2126   dest1 = gen_highpart (DImode, set_dest);
2127   dest2 = gen_lowpart (DImode, set_dest);
2129   /* Now output, ordering such that we don't clobber any registers
2130      mentioned in the address.  */
2131   if (reg_overlap_mentioned_p (dest1, word1))
2133     {
2134       emit_insn (gen_movdi (dest2, word1));
2135       emit_insn (gen_movdi (dest1, word0));
2136     }
2137   else
2138    {
2139       emit_insn (gen_movdi (dest1, word0));
2140       emit_insn (gen_movdi (dest2, word1));
2141    }
2142   DONE;
2145 (define_split
2146   [(set (match_operand:TI 0 "memory_operand" "")
2147         (match_operand:TI 1 "register_operand" ""))]
2148   "reload_completed
2149    && offsettable_memref_p (operands[0])
2150    && (! TARGET_HARD_QUAD
2151        || ! fp_register_operand (operands[1], TImode))"
2152   [(clobber (const_int 0))]
2154   rtx set_src = operands[1];
2156   emit_insn (gen_movdi (adjust_address (operands[0], DImode, 0),
2157                         gen_highpart (DImode, set_src)));
2158   emit_insn (gen_movdi (adjust_address (operands[0], DImode, 8),
2159                         gen_lowpart (DImode, set_src)));
2160   DONE;
2164 ;; Floating point move instructions
2166 (define_expand "movsf"
2167   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2168         (match_operand:SF 1 "general_operand" ""))]
2169   ""
2171   if (sparc_expand_move (SFmode, operands))
2172     DONE;
2175 (define_insn "*movsf_insn"
2176   [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,f, *r,*r,*r,*r, f,f,*r,m,  m")
2177         (match_operand:SF 1 "input_operand"         "G,C,f,*rR, Q, S, f,*r,m, m,f,*rG"))]
2178   "(register_operand (operands[0], SFmode)
2179     || register_or_zero_or_all_ones_operand (operands[1], SFmode))"
2181   if (GET_CODE (operands[1]) == CONST_DOUBLE
2182       && (which_alternative == 3
2183           || which_alternative == 4
2184           || which_alternative == 5))
2185     {
2186       long i;
2188       REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (operands[1]), i);
2189       operands[1] = GEN_INT (i);
2190     }
2192   switch (which_alternative)
2193     {
2194     case 0:
2195       return "fzeros\t%0";
2196     case 1:
2197       return "fones\t%0";
2198     case 2:
2199       return "fmovs\t%1, %0";
2200     case 3:
2201       return "mov\t%1, %0";
2202     case 4:
2203       return "sethi\t%%hi(%a1), %0";
2204     case 5:
2205       return "#";
2206     case 6:
2207       return "movstouw\t%1, %0";
2208     case 7:
2209       return "movwtos\t%1, %0";
2210     case 8:
2211     case 9:
2212       return "ld\t%1, %0";
2213     case 10:
2214     case 11:
2215       return "st\t%r1, %0";
2216     default:
2217       gcc_unreachable ();
2218     }
2220   [(set_attr "type" "visl,visl,fpmove,*,*,*,vismv,vismv,fpload,load,fpstore,store")
2221    (set_attr "v3pipe" "true, true, *, *, *, *, true, true, *, *, *, *")
2222    (set_attr "cpu_feature" "vis,vis,fpu,*,*,*,vis3,vis3,fpu,*,fpu,*")])
2224 ;; The following 3 patterns build SFmode constants in integer registers.
2226 (define_insn "*movsf_lo_sum"
2227   [(set (match_operand:SF 0 "register_operand" "=r")
2228         (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
2229                    (match_operand:SF 2 "fp_const_high_losum_operand" "S")))]
2230   ""
2232   long i;
2234   REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (operands[2]), i);
2235   operands[2] = GEN_INT (i);
2236   return "or\t%1, %%lo(%a2), %0";
2239 (define_insn "*movsf_high"
2240   [(set (match_operand:SF 0 "register_operand" "=r")
2241         (high:SF (match_operand:SF 1 "fp_const_high_losum_operand" "S")))]
2242   ""
2244   long i;
2246   REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (operands[1]), i);
2247   operands[1] = GEN_INT (i);
2248   return "sethi\t%%hi(%1), %0";
2251 (define_split
2252   [(set (match_operand:SF 0 "register_operand" "")
2253         (match_operand:SF 1 "fp_const_high_losum_operand" ""))]
2254   "REG_P (operands[0]) && SPARC_INT_REG_P (REGNO (operands[0]))"
2255   [(set (match_dup 0) (high:SF (match_dup 1)))
2256    (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
2258 (define_expand "movdf"
2259   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2260         (match_operand:DF 1 "general_operand" ""))]
2261   ""
2263   if (sparc_expand_move (DFmode, operands))
2264     DONE;
2267 (define_insn "*movdf_insn_sp32"
2268   [(set (match_operand:DF 0 "nonimmediate_operand" "=b,b,e,e,*r, f,  e,T,W,U,T,  f,  *r,  o,o")
2269         (match_operand:DF 1 "input_operand"         "G,C,e,e, f,*r,W#F,G,e,T,U,o#F,*roF,*rG,f"))]
2270   "! TARGET_ARCH64
2271    && (register_operand (operands[0], DFmode)
2272        || register_or_zero_or_all_ones_operand (operands[1], DFmode))"
2273   "@
2274   fzero\t%0
2275   fone\t%0
2276   fmovd\t%1, %0
2277   #
2278   #
2279   #
2280   ldd\t%1, %0
2281   stx\t%r1, %0
2282   std\t%1, %0
2283   ldd\t%1, %0
2284   std\t%1, %0
2285   #
2286   #
2287   #
2288   #"
2289   [(set_attr "type" "visl,visl,fpmove,*,*,*,fpload,store,fpstore,load,store,*,*,*,*")
2290    (set_attr "v3pipe" "true, true, *, *, *, *, *, *, *, *, *, *, *, *, *")
2291    (set_attr "length" "*,*,*,2,2,2,*,*,*,*,*,2,2,2,2")
2292    (set_attr "fptype" "double,double,double,*,*,*,*,*,*,*,*,*,*,*,*")
2293    (set_attr "cpu_feature" "vis,vis,v9,fpunotv9,vis3,vis3,fpu,v9,fpu,*,*,fpu,*,*,fpu")])
2295 (define_insn "*movdf_insn_sp64"
2296   [(set (match_operand:DF 0 "nonimmediate_operand" "=b,b,e,*r, e,  e,W, *r,*r,  m,*r")
2297         (match_operand:DF 1 "input_operand"         "G,C,e, e,*r,W#F,e,*rG, m,*rG, F"))]
2298   "TARGET_ARCH64
2299    && (register_operand (operands[0], DFmode)
2300        || register_or_zero_or_all_ones_operand (operands[1], DFmode))"
2301   "@
2302   fzero\t%0
2303   fone\t%0
2304   fmovd\t%1, %0
2305   movdtox\t%1, %0
2306   movxtod\t%1, %0
2307   ldd\t%1, %0
2308   std\t%1, %0
2309   mov\t%r1, %0
2310   ldx\t%1, %0
2311   stx\t%r1, %0
2312   #"
2313   [(set_attr "type" "visl,visl,fpmove,vismv,vismv,load,store,*,load,store,*")
2314    (set_attr "v3pipe" "true, true, *, *, *, *, *, *, *, *, *")
2315    (set_attr "length" "*,*,*,*,*,*,*,*,*,*,2")
2316    (set_attr "fptype" "double,double,double,double,double,*,*,*,*,*,*")
2317    (set_attr "cpu_feature" "vis,vis,fpu,vis3,vis3,fpu,fpu,*,*,*,*")])
2319 ;; This pattern builds DFmode constants in integer registers.
2320 (define_split
2321   [(set (match_operand:DF 0 "register_operand" "")
2322         (match_operand:DF 1 "const_double_operand" ""))]
2323   "REG_P (operands[0])
2324    && SPARC_INT_REG_P (REGNO (operands[0]))
2325    && ! const_zero_operand (operands[1], GET_MODE (operands[0]))
2326    && reload_completed"
2327   [(clobber (const_int 0))]
2329   operands[0] = gen_raw_REG (DImode, REGNO (operands[0]));
2331   if (TARGET_ARCH64)
2332     {
2333       machine_mode mode = GET_MODE (operands[1]);
2334       rtx tem = simplify_subreg (DImode, operands[1], mode, 0);
2335       emit_insn (gen_movdi (operands[0], tem));
2336     }
2337   else
2338     {
2339       machine_mode mode = GET_MODE (operands[1]);
2340       rtx hi = simplify_subreg (SImode, operands[1], mode, 0);
2341       rtx lo = simplify_subreg (SImode, operands[1], mode, 4);
2343       gcc_assert (GET_CODE (hi) == CONST_INT);
2344       gcc_assert (GET_CODE (lo) == CONST_INT);
2346       emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), hi));
2348       /* Slick... but this trick loses if this subreg constant part
2349          can be done in one insn.  */
2350       if (lo == hi
2351           && ! SPARC_SETHI32_P (INTVAL (hi))
2352           && ! SPARC_SIMM13_P (INTVAL (hi)))
2353         {
2354           emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2355                                 gen_highpart (SImode, operands[0])));
2356         }
2357       else
2358         {
2359           emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), lo));
2360         }
2361     }
2362   DONE;
2365 ;; Ok, now the splits to handle all the multi insn and
2366 ;; mis-aligned memory address cases.
2367 ;; In these splits please take note that we must be
2368 ;; careful when V9 but not ARCH64 because the integer
2369 ;; register DFmode cases must be handled.
2370 (define_split
2371   [(set (match_operand:DF 0 "register_operand" "")
2372         (match_operand:DF 1 "register_operand" ""))]
2373   "(! TARGET_V9
2374     || (! TARGET_ARCH64
2375         && sparc_split_regreg_legitimate (operands[0],
2376                                           operands[1])))
2377    && reload_completed"
2378   [(clobber (const_int 0))]
2380   rtx set_dest = operands[0];
2381   rtx set_src = operands[1];
2382   rtx dest1, dest2;
2383   rtx src1, src2;
2385   dest1 = gen_highpart (SFmode, set_dest);
2386   dest2 = gen_lowpart (SFmode, set_dest);
2387   src1 = gen_highpart (SFmode, set_src);
2388   src2 = gen_lowpart (SFmode, set_src);
2390   /* Now emit using the real source and destination we found, swapping
2391      the order if we detect overlap.  */
2392   if (reg_overlap_mentioned_p (dest1, src2))
2393     {
2394       emit_move_insn_1 (dest2, src2);
2395       emit_move_insn_1 (dest1, src1);
2396     }
2397   else
2398     {
2399       emit_move_insn_1 (dest1, src1);
2400       emit_move_insn_1 (dest2, src2);
2401     }
2402   DONE;
2405 (define_split
2406   [(set (match_operand:DF 0 "register_operand" "")
2407         (match_operand:DF 1 "memory_operand" ""))]
2408   "reload_completed
2409    && ! TARGET_ARCH64
2410    && (((REGNO (operands[0]) % 2) != 0)
2411        || ! mem_min_alignment (operands[1], 8))
2412    && offsettable_memref_p (operands[1])"
2413   [(clobber (const_int 0))]
2415   rtx word0, word1;
2417   word0 = adjust_address (operands[1], SFmode, 0);
2418   word1 = adjust_address (operands[1], SFmode, 4);
2420   if (reg_overlap_mentioned_p (gen_highpart (SFmode, operands[0]), word1))
2421     {
2422       emit_move_insn_1 (gen_lowpart (SFmode, operands[0]), word1);
2423       emit_move_insn_1 (gen_highpart (SFmode, operands[0]), word0);
2424     }
2425   else
2426     {
2427       emit_move_insn_1 (gen_highpart (SFmode, operands[0]), word0);
2428       emit_move_insn_1 (gen_lowpart (SFmode, operands[0]), word1);
2429     }
2430   DONE;
2433 (define_split
2434   [(set (match_operand:DF 0 "memory_operand" "")
2435         (match_operand:DF 1 "register_operand" ""))]
2436   "reload_completed
2437    && ! TARGET_ARCH64
2438    && (((REGNO (operands[1]) % 2) != 0)
2439        || ! mem_min_alignment (operands[0], 8))
2440    && offsettable_memref_p (operands[0])"
2441   [(clobber (const_int 0))]
2443   rtx word0, word1;
2445   word0 = adjust_address (operands[0], SFmode, 0);
2446   word1 = adjust_address (operands[0], SFmode, 4);
2448   emit_move_insn_1 (word0, gen_highpart (SFmode, operands[1]));
2449   emit_move_insn_1 (word1, gen_lowpart (SFmode, operands[1]));
2450   DONE;
2453 (define_split
2454   [(set (match_operand:DF 0 "memory_operand" "")
2455         (match_operand:DF 1 "const_zero_operand" ""))]
2456   "reload_completed
2457    && (! TARGET_V9
2458        || (! TARGET_ARCH64
2459            && ! mem_min_alignment (operands[0], 8)))
2460    && offsettable_memref_p (operands[0])"
2461   [(clobber (const_int 0))]
2463   rtx dest1, dest2;
2465   dest1 = adjust_address (operands[0], SFmode, 0);
2466   dest2 = adjust_address (operands[0], SFmode, 4);
2468   emit_move_insn_1 (dest1, CONST0_RTX (SFmode));
2469   emit_move_insn_1 (dest2, CONST0_RTX (SFmode));
2470   DONE;
2473 (define_split
2474   [(set (match_operand:DF 0 "register_operand" "")
2475         (match_operand:DF 1 "const_zero_operand" ""))]
2476   "reload_completed
2477    && ! TARGET_ARCH64
2478    && ((GET_CODE (operands[0]) == REG
2479         && SPARC_INT_REG_P (REGNO (operands[0])))
2480        || (GET_CODE (operands[0]) == SUBREG
2481            && GET_CODE (SUBREG_REG (operands[0])) == REG
2482            && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
2483   [(clobber (const_int 0))]
2485   rtx set_dest = operands[0];
2486   rtx dest1, dest2;
2488   dest1 = gen_highpart (SFmode, set_dest);
2489   dest2 = gen_lowpart (SFmode, set_dest);
2490   emit_move_insn_1 (dest1, CONST0_RTX (SFmode));
2491   emit_move_insn_1 (dest2, CONST0_RTX (SFmode));
2492   DONE;
2495 (define_expand "movtf"
2496   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2497         (match_operand:TF 1 "general_operand" ""))]
2498   ""
2500   if (sparc_expand_move (TFmode, operands))
2501     DONE;
2504 (define_insn "*movtf_insn_sp32"
2505   [(set (match_operand:TF 0 "nonimmediate_operand" "=b, e,o,  o,U,  r")
2506         (match_operand:TF 1 "input_operand"        " G,oe,e,rGU,o,roG"))]
2507   "! TARGET_ARCH64
2508    && (register_operand (operands[0], TFmode)
2509        || register_or_zero_operand (operands[1], TFmode))"
2510   "#"
2511   [(set_attr "length" "4,4,4,4,4,4")
2512    (set_attr "cpu_feature" "fpu,fpu,fpu,*,*,*")])
2514 (define_insn "*movtf_insn_sp64"
2515   [(set (match_operand:TF 0 "nonimmediate_operand" "=b, e,o, o,  r")
2516         (match_operand:TF 1 "input_operand"         "G,oe,e,rG,roG"))]
2517   "TARGET_ARCH64
2518    && ! TARGET_HARD_QUAD
2519    && (register_operand (operands[0], TFmode)
2520        || register_or_zero_operand (operands[1], TFmode))"
2521   "#"
2522   [(set_attr "length" "2,2,2,2,2")
2523    (set_attr "cpu_feature" "fpu,fpu,fpu,*,*")])
2525 (define_insn "*movtf_insn_sp64_hq"
2526   [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,e,m, o,  r")
2527         (match_operand:TF 1 "input_operand"         "G,e,m,e,rG,roG"))]
2528   "TARGET_ARCH64
2529    && TARGET_HARD_QUAD
2530    && (register_operand (operands[0], TFmode)
2531        || register_or_zero_operand (operands[1], TFmode))"
2532   "@
2533   #
2534   fmovq\t%1, %0
2535   ldq\t%1, %0
2536   stq\t%1, %0
2537   #
2538   #"
2539   [(set_attr "type" "*,fpmove,fpload,fpstore,*,*")
2540    (set_attr "length" "2,*,*,*,2,2")])
2542 ;; Now all the splits to handle multi-insn TF mode moves.
2543 (define_split
2544   [(set (match_operand:TF 0 "register_operand" "")
2545         (match_operand:TF 1 "register_operand" ""))]
2546   "reload_completed
2547    && (! TARGET_ARCH64
2548        || (TARGET_FPU
2549            && ! TARGET_HARD_QUAD)
2550        || (! fp_register_operand (operands[0], TFmode)
2551            && ! fp_register_operand (operands[1], TFmode)))"
2552   [(clobber (const_int 0))]
2554   rtx set_dest = operands[0];
2555   rtx set_src = operands[1];
2556   rtx dest1, dest2;
2557   rtx src1, src2;
2559   dest1 = gen_df_reg (set_dest, 0);
2560   dest2 = gen_df_reg (set_dest, 1);
2561   src1 = gen_df_reg (set_src, 0);
2562   src2 = gen_df_reg (set_src, 1);
2564   /* Now emit using the real source and destination we found, swapping
2565      the order if we detect overlap.  */
2566   if (reg_overlap_mentioned_p (dest1, src2))
2567     {
2568       emit_insn (gen_movdf (dest2, src2));
2569       emit_insn (gen_movdf (dest1, src1));
2570     }
2571   else
2572     {
2573       emit_insn (gen_movdf (dest1, src1));
2574       emit_insn (gen_movdf (dest2, src2));
2575     }
2576   DONE;
2579 (define_split
2580   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2581         (match_operand:TF 1 "const_zero_operand" ""))]
2582   "reload_completed"
2583   [(clobber (const_int 0))]
2585   rtx set_dest = operands[0];
2586   rtx dest1, dest2;
2588   switch (GET_CODE (set_dest))
2589     {
2590     case REG:
2591       dest1 = gen_df_reg (set_dest, 0);
2592       dest2 = gen_df_reg (set_dest, 1);
2593       break;
2594     case MEM:
2595       dest1 = adjust_address (set_dest, DFmode, 0);
2596       dest2 = adjust_address (set_dest, DFmode, 8);
2597       break;
2598     default:
2599       gcc_unreachable ();
2600     }
2602   emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
2603   emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
2604   DONE;
2607 (define_split
2608   [(set (match_operand:TF 0 "register_operand" "")
2609         (match_operand:TF 1 "memory_operand" ""))]
2610   "(reload_completed
2611     && offsettable_memref_p (operands[1])
2612     && (! TARGET_ARCH64
2613         || ! TARGET_HARD_QUAD
2614         || ! fp_register_operand (operands[0], TFmode)))"
2615   [(clobber (const_int 0))]
2617   rtx word0 = adjust_address (operands[1], DFmode, 0);
2618   rtx word1 = adjust_address (operands[1], DFmode, 8);
2619   rtx set_dest, dest1, dest2;
2621   set_dest = operands[0];
2623   dest1 = gen_df_reg (set_dest, 0);
2624   dest2 = gen_df_reg (set_dest, 1);
2626   /* Now output, ordering such that we don't clobber any registers
2627      mentioned in the address.  */
2628   if (reg_overlap_mentioned_p (dest1, word1))
2630     {
2631       emit_insn (gen_movdf (dest2, word1));
2632       emit_insn (gen_movdf (dest1, word0));
2633     }
2634   else
2635    {
2636       emit_insn (gen_movdf (dest1, word0));
2637       emit_insn (gen_movdf (dest2, word1));
2638    }
2639   DONE;
2642 (define_split
2643   [(set (match_operand:TF 0 "memory_operand" "")
2644         (match_operand:TF 1 "register_operand" ""))]
2645   "(reload_completed
2646     && offsettable_memref_p (operands[0])
2647     && (! TARGET_ARCH64
2648         || ! TARGET_HARD_QUAD
2649         || ! fp_register_operand (operands[1], TFmode)))"
2650   [(clobber (const_int 0))]
2652   rtx set_src = operands[1];
2654   emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
2655                         gen_df_reg (set_src, 0)));
2656   emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
2657                         gen_df_reg (set_src, 1)));
2658   DONE;
2662 ;; SPARC-V9 conditional move instructions
2664 ;; We can handle larger constants here for some flavors, but for now we keep
2665 ;; it simple and only allow those constants supported by all flavors.
2666 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
2667 ;; 3 contains the constant if one is present, but we handle either for
2668 ;; generality (sparc.c puts a constant in operand 2).
2670 ;; Our instruction patterns, on the other hand, canonicalize such that
2671 ;; operand 3 must be the set destination.
2673 (define_expand "mov<I:mode>cc"
2674   [(set (match_operand:I 0 "register_operand" "")
2675         (if_then_else:I (match_operand 1 "comparison_operator" "")
2676                         (match_operand:I 2 "arith10_operand" "")
2677                         (match_operand:I 3 "arith10_operand" "")))]
2678   "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2680   if (! sparc_expand_conditional_move (<I:MODE>mode, operands))
2681     FAIL;
2682   DONE;
2685 (define_expand "mov<F:mode>cc"
2686   [(set (match_operand:F 0 "register_operand" "")
2687         (if_then_else:F (match_operand 1 "comparison_operator" "")
2688                         (match_operand:F 2 "register_operand" "")
2689                         (match_operand:F 3 "register_operand" "")))]
2690   "TARGET_V9 && TARGET_FPU"
2692   if (! sparc_expand_conditional_move (<F:MODE>mode, operands))
2693     FAIL;
2694   DONE;
2697 (define_insn "*mov<I:mode>_cc_v9"
2698   [(set (match_operand:I 0 "register_operand" "=r")
2699         (if_then_else:I (match_operator 1 "comparison_operator"
2700                                [(match_operand 2 "icc_or_fcc_register_operand" "X")
2701                                 (const_int 0)])
2702                         (match_operand:I 3 "arith11_operand" "rL")
2703                         (match_operand:I 4 "register_operand" "0")))]
2704   "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
2705   "mov%C1\t%x2, %3, %0"
2706   [(set_attr "type" "cmove")])
2708 (define_insn "*mov<I:mode>_cc_reg_sp64"
2709   [(set (match_operand:I 0 "register_operand" "=r")
2710         (if_then_else:I (match_operator 1 "v9_register_compare_operator"
2711                                 [(match_operand:DI 2 "register_operand" "r")
2712                                  (const_int 0)])
2713                         (match_operand:I 3 "arith10_operand" "rM")
2714                         (match_operand:I 4 "register_operand" "0")))]
2715   "TARGET_ARCH64"
2716   "movr%D1\t%2, %r3, %0"
2717   [(set_attr "type" "cmove")])
2719 (define_insn "*movsf_cc_v9"
2720   [(set (match_operand:SF 0 "register_operand" "=f")
2721         (if_then_else:SF (match_operator 1 "comparison_operator"
2722                                 [(match_operand 2 "icc_or_fcc_register_operand" "X")
2723                                  (const_int 0)])
2724                          (match_operand:SF 3 "register_operand" "f")
2725                          (match_operand:SF 4 "register_operand" "0")))]
2726   "TARGET_V9 && TARGET_FPU"
2727   "fmovs%C1\t%x2, %3, %0"
2728   [(set_attr "type" "fpcmove")])
2730 (define_insn "*movsf_cc_reg_sp64"
2731   [(set (match_operand:SF 0 "register_operand" "=f")
2732         (if_then_else:SF (match_operator 1 "v9_register_compare_operator"
2733                                 [(match_operand:DI 2 "register_operand" "r")
2734                                  (const_int 0)])
2735                          (match_operand:SF 3 "register_operand" "f")
2736                          (match_operand:SF 4 "register_operand" "0")))]
2737   "TARGET_ARCH64 && TARGET_FPU"
2738   "fmovrs%D1\t%2, %3, %0"
2739   [(set_attr "type" "fpcrmove")])
2741 ;; Named because invoked by movtf_cc_v9
2742 (define_insn "movdf_cc_v9"
2743   [(set (match_operand:DF 0 "register_operand" "=e")
2744         (if_then_else:DF (match_operator 1 "comparison_operator"
2745                                 [(match_operand 2 "icc_or_fcc_register_operand" "X")
2746                                  (const_int 0)])
2747                          (match_operand:DF 3 "register_operand" "e")
2748                          (match_operand:DF 4 "register_operand" "0")))]
2749   "TARGET_V9 && TARGET_FPU"
2750   "fmovd%C1\t%x2, %3, %0"
2751   [(set_attr "type" "fpcmove")
2752    (set_attr "fptype" "double")])
2754 ;; Named because invoked by movtf_cc_reg_sp64
2755 (define_insn "movdf_cc_reg_sp64"
2756   [(set (match_operand:DF 0 "register_operand" "=e")
2757         (if_then_else:DF (match_operator 1 "v9_register_compare_operator"
2758                                 [(match_operand:DI 2 "register_operand" "r")
2759                                  (const_int 0)])
2760                          (match_operand:DF 3 "register_operand" "e")
2761                          (match_operand:DF 4 "register_operand" "0")))]
2762   "TARGET_ARCH64 && TARGET_FPU"
2763   "fmovrd%D1\t%2, %3, %0"
2764   [(set_attr "type" "fpcrmove")
2765    (set_attr "fptype" "double")])
2767 (define_insn "*movtf_cc_hq_v9"
2768   [(set (match_operand:TF 0 "register_operand" "=e")
2769         (if_then_else:TF (match_operator 1 "comparison_operator"
2770                                 [(match_operand 2 "icc_or_fcc_register_operand" "X")
2771                                  (const_int 0)])
2772                          (match_operand:TF 3 "register_operand" "e")
2773                          (match_operand:TF 4 "register_operand" "0")))]
2774   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
2775   "fmovq%C1\t%x2, %3, %0"
2776   [(set_attr "type" "fpcmove")])
2778 (define_insn "*movtf_cc_reg_hq_sp64"
2779   [(set (match_operand:TF 0 "register_operand" "=e")
2780         (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2781                                 [(match_operand:DI 2 "register_operand" "r")
2782                                  (const_int 0)])
2783                          (match_operand:TF 3 "register_operand" "e")
2784                          (match_operand:TF 4 "register_operand" "0")))]
2785   "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
2786   "fmovrq%D1\t%2, %3, %0"
2787   [(set_attr "type" "fpcrmove")])
2789 (define_insn_and_split "*movtf_cc_v9"
2790   [(set (match_operand:TF 0 "register_operand" "=e")
2791         (if_then_else:TF (match_operator 1 "comparison_operator"
2792                             [(match_operand 2 "icc_or_fcc_register_operand" "X")
2793                              (const_int 0)])
2794                          (match_operand:TF 3 "register_operand" "e")
2795                          (match_operand:TF 4 "register_operand" "0")))]
2796   "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
2797   "#"
2798   "&& reload_completed"
2799   [(clobber (const_int 0))]
2801   rtx set_dest = operands[0];
2802   rtx set_srca = operands[3];
2803   rtx dest1, dest2;
2804   rtx srca1, srca2;
2806   dest1 = gen_df_reg (set_dest, 0);
2807   dest2 = gen_df_reg (set_dest, 1);
2808   srca1 = gen_df_reg (set_srca, 0);
2809   srca2 = gen_df_reg (set_srca, 1);
2811   if (reg_overlap_mentioned_p (dest1, srca2))
2812     {
2813       emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, dest2));
2814       emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, dest1));
2815     }
2816   else
2817     {
2818       emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, dest1));
2819       emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, dest2));
2820     }
2821   DONE;
2823   [(set_attr "length" "2")])
2825 (define_insn_and_split "*movtf_cc_reg_sp64"
2826   [(set (match_operand:TF 0 "register_operand" "=e")
2827         (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
2828                                 [(match_operand:DI 2 "register_operand" "r")
2829                                  (const_int 0)])
2830                          (match_operand:TF 3 "register_operand" "e")
2831                          (match_operand:TF 4 "register_operand" "0")))]
2832   "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
2833   "#"
2834   "&& reload_completed"
2835   [(clobber (const_int 0))]
2837   rtx set_dest = operands[0];
2838   rtx set_srca = operands[3];
2839   rtx dest1, dest2;
2840   rtx srca1, srca2;
2842   dest1 = gen_df_reg (set_dest, 0);
2843   dest2 = gen_df_reg (set_dest, 1);
2844   srca1 = gen_df_reg (set_srca, 0);
2845   srca2 = gen_df_reg (set_srca, 1);
2847   if (reg_overlap_mentioned_p (dest1, srca2))
2848     {
2849       emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, dest2));
2850       emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, dest1));
2851     }
2852   else
2853     {
2854       emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, dest1));
2855       emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, dest2));
2856     }
2857   DONE;
2859   [(set_attr "length" "2")])
2862 ;; Zero-extension instructions
2864 ;; These patterns originally accepted general_operands, however, slightly
2865 ;; better code is generated by only accepting register_operands, and then
2866 ;; letting combine generate the ldu[hb] insns.
2868 (define_expand "zero_extendhisi2"
2869   [(set (match_operand:SI 0 "register_operand" "")
2870         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
2871   ""
2873   rtx temp = gen_reg_rtx (SImode);
2874   rtx shift_16 = GEN_INT (16);
2875   int op1_subbyte = 0;
2877   if (GET_CODE (operand1) == SUBREG)
2878     {
2879       op1_subbyte = SUBREG_BYTE (operand1);
2880       op1_subbyte /= GET_MODE_SIZE (SImode);
2881       op1_subbyte *= GET_MODE_SIZE (SImode);
2882       operand1 = XEXP (operand1, 0);
2883     }
2885   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
2886                           shift_16));
2887   emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
2888   DONE;
2891 (define_insn "*zero_extendhisi2_insn"
2892   [(set (match_operand:SI 0 "register_operand" "=r")
2893         (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2894   ""
2895   "lduh\t%1, %0"
2896   [(set_attr "type" "load")
2897    (set_attr "us3load_type" "3cycle")])
2899 (define_expand "zero_extendqihi2"
2900   [(set (match_operand:HI 0 "register_operand" "")
2901         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
2902   ""
2903   "")
2905 (define_insn "*zero_extendqihi2_insn"
2906   [(set (match_operand:HI 0 "register_operand" "=r,r")
2907         (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
2908   "GET_CODE (operands[1]) != CONST_INT"
2909   "@
2910    and\t%1, 0xff, %0
2911    ldub\t%1, %0"
2912   [(set_attr "type" "*,load")
2913    (set_attr "us3load_type" "*,3cycle")])
2915 (define_expand "zero_extendqisi2"
2916   [(set (match_operand:SI 0 "register_operand" "")
2917         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
2918   ""
2919   "")
2921 (define_insn "*zero_extendqisi2_insn"
2922   [(set (match_operand:SI 0 "register_operand" "=r,r")
2923         (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
2924   "GET_CODE (operands[1]) != CONST_INT"
2925   "@
2926    and\t%1, 0xff, %0
2927    ldub\t%1, %0"
2928   [(set_attr "type" "*,load")
2929    (set_attr "us3load_type" "*,3cycle")])
2931 (define_expand "zero_extendqidi2"
2932   [(set (match_operand:DI 0 "register_operand" "")
2933         (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
2934   "TARGET_ARCH64"
2935   "")
2937 (define_insn "*zero_extendqidi2_insn"
2938   [(set (match_operand:DI 0 "register_operand" "=r,r")
2939         (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
2940   "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
2941   "@
2942    and\t%1, 0xff, %0
2943    ldub\t%1, %0"
2944   [(set_attr "type" "*,load")
2945    (set_attr "us3load_type" "*,3cycle")])
2947 (define_expand "zero_extendhidi2"
2948   [(set (match_operand:DI 0 "register_operand" "")
2949         (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
2950   "TARGET_ARCH64"
2952   rtx temp = gen_reg_rtx (DImode);
2953   rtx shift_48 = GEN_INT (48);
2954   int op1_subbyte = 0;
2956   if (GET_CODE (operand1) == SUBREG)
2957     {
2958       op1_subbyte = SUBREG_BYTE (operand1);
2959       op1_subbyte /= GET_MODE_SIZE (DImode);
2960       op1_subbyte *= GET_MODE_SIZE (DImode);
2961       operand1 = XEXP (operand1, 0);
2962     }
2964   emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
2965                           shift_48));
2966   emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
2967   DONE;
2970 (define_insn "*zero_extendhidi2_insn"
2971   [(set (match_operand:DI 0 "register_operand" "=r")
2972         (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
2973   "TARGET_ARCH64"
2974   "lduh\t%1, %0"
2975   [(set_attr "type" "load")
2976    (set_attr "us3load_type" "3cycle")])
2978 ;; ??? Write truncdisi pattern using sra?
2980 (define_expand "zero_extendsidi2"
2981   [(set (match_operand:DI 0 "register_operand" "")
2982         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
2983   ""
2984   "")
2986 (define_insn "*zero_extendsidi2_insn_sp64"
2987   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
2988         (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m,*f")))]
2989   "TARGET_ARCH64
2990    && GET_CODE (operands[1]) != CONST_INT"
2991   "@
2992    srl\t%1, 0, %0
2993    lduw\t%1, %0
2994    movstouw\t%1, %0"
2995   [(set_attr "type" "shift,load,*")
2996    (set_attr "v3pipe" "*,*,true")
2997    (set_attr "cpu_feature" "*,*,vis3")])
2999 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
3000   [(set (match_operand:DI 0 "register_operand" "=r")
3001         (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
3002   "! TARGET_ARCH64"
3003   "#"
3004   "&& reload_completed"
3005   [(set (match_dup 2) (match_dup 1))
3006    (set (match_dup 3) (const_int 0))]
3007   "operands[2] = gen_lowpart (SImode, operands[0]);
3008    operands[3] = gen_highpart (SImode, operands[0]);"
3009   [(set_attr "length" "2")])
3011 ;; Simplify comparisons of extended values.
3013 (define_insn "*cmp_zero_extendqisi2"
3014   [(set (reg:CC CC_REG)
3015         (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
3016                     (const_int 0)))]
3017   ""
3018   "andcc\t%0, 0xff, %%g0"
3019   [(set_attr "type" "compare")])
3021 (define_insn "*cmp_zero_qi"
3022   [(set (reg:CC CC_REG)
3023         (compare:CC (match_operand:QI 0 "register_operand" "r")
3024                     (const_int 0)))]
3025   ""
3026   "andcc\t%0, 0xff, %%g0"
3027   [(set_attr "type" "compare")])
3029 (define_insn "*cmp_zero_extendqisi2_set"
3030   [(set (reg:CC CC_REG)
3031         (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
3032                     (const_int 0)))
3033    (set (match_operand:SI 0 "register_operand" "=r")
3034         (zero_extend:SI (match_dup 1)))]
3035   ""
3036   "andcc\t%1, 0xff, %0"
3037   [(set_attr "type" "compare")])
3039 (define_insn "*cmp_zero_extendqisi2_andcc_set"
3040   [(set (reg:CC CC_REG)
3041         (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
3042                             (const_int 255))
3043                     (const_int 0)))
3044    (set (match_operand:SI 0 "register_operand" "=r")
3045         (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
3046   ""
3047   "andcc\t%1, 0xff, %0"
3048   [(set_attr "type" "compare")])
3050 (define_insn "*cmp_zero_extendqidi2"
3051   [(set (reg:CCX CC_REG)
3052         (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
3053                      (const_int 0)))]
3054   "TARGET_ARCH64"
3055   "andcc\t%0, 0xff, %%g0"
3056   [(set_attr "type" "compare")])
3058 (define_insn "*cmp_zero_qi_sp64"
3059   [(set (reg:CCX CC_REG)
3060         (compare:CCX (match_operand:QI 0 "register_operand" "r")
3061                      (const_int 0)))]
3062   "TARGET_ARCH64"
3063   "andcc\t%0, 0xff, %%g0"
3064   [(set_attr "type" "compare")])
3066 (define_insn "*cmp_zero_extendqidi2_set"
3067   [(set (reg:CCX CC_REG)
3068         (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
3069                      (const_int 0)))
3070    (set (match_operand:DI 0 "register_operand" "=r")
3071         (zero_extend:DI (match_dup 1)))]
3072   "TARGET_ARCH64"
3073   "andcc\t%1, 0xff, %0"
3074   [(set_attr "type" "compare")])
3076 (define_insn "*cmp_zero_extendqidi2_andcc_set"
3077   [(set (reg:CCX CC_REG)
3078         (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
3079                              (const_int 255))
3080                      (const_int 0)))
3081    (set (match_operand:DI 0 "register_operand" "=r")
3082         (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
3083   "TARGET_ARCH64"
3084   "andcc\t%1, 0xff, %0"
3085   [(set_attr "type" "compare")])
3087 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
3089 (define_insn "*cmp_siqi_trunc"
3090   [(set (reg:CC CC_REG)
3091         (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
3092                     (const_int 0)))]
3093   ""
3094   "andcc\t%0, 0xff, %%g0"
3095   [(set_attr "type" "compare")])
3097 (define_insn "*cmp_siqi_trunc_set"
3098   [(set (reg:CC CC_REG)
3099         (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
3100                     (const_int 0)))
3101    (set (match_operand:QI 0 "register_operand" "=r")
3102         (subreg:QI (match_dup 1) 3))]
3103   ""
3104   "andcc\t%1, 0xff, %0"
3105   [(set_attr "type" "compare")])
3107 (define_insn "*cmp_diqi_trunc"
3108   [(set (reg:CC CC_REG)
3109         (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
3110                     (const_int 0)))]
3111   "TARGET_ARCH64"
3112   "andcc\t%0, 0xff, %%g0"
3113   [(set_attr "type" "compare")])
3115 (define_insn "*cmp_diqi_trunc_set"
3116   [(set (reg:CC CC_REG)
3117         (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
3118                     (const_int 0)))
3119    (set (match_operand:QI 0 "register_operand" "=r")
3120         (subreg:QI (match_dup 1) 7))]
3121   "TARGET_ARCH64"
3122   "andcc\t%1, 0xff, %0"
3123   [(set_attr "type" "compare")])
3126 ;; Sign-extension instructions
3128 ;; These patterns originally accepted general_operands, however, slightly
3129 ;; better code is generated by only accepting register_operands, and then
3130 ;; letting combine generate the lds[hb] insns.
3132 (define_expand "extendhisi2"
3133   [(set (match_operand:SI 0 "register_operand" "")
3134         (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
3135   ""
3137   rtx temp = gen_reg_rtx (SImode);
3138   rtx shift_16 = GEN_INT (16);
3139   int op1_subbyte = 0;
3141   if (GET_CODE (operand1) == SUBREG)
3142     {
3143       op1_subbyte = SUBREG_BYTE (operand1);
3144       op1_subbyte /= GET_MODE_SIZE (SImode);
3145       op1_subbyte *= GET_MODE_SIZE (SImode);
3146       operand1 = XEXP (operand1, 0);
3147     }
3149   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3150                           shift_16));
3151   emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
3152   DONE;
3155 (define_insn "*sign_extendhisi2_insn"
3156   [(set (match_operand:SI 0 "register_operand" "=r")
3157         (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3158   ""
3159   "ldsh\t%1, %0"
3160   [(set_attr "type" "sload")
3161    (set_attr "us3load_type" "3cycle")])
3163 (define_expand "extendqihi2"
3164   [(set (match_operand:HI 0 "register_operand" "")
3165         (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
3166   ""
3168   rtx temp = gen_reg_rtx (SImode);
3169   rtx shift_24 = GEN_INT (24);
3170   int op1_subbyte = 0;
3171   int op0_subbyte = 0;
3173   if (GET_CODE (operand1) == SUBREG)
3174     {
3175       op1_subbyte = SUBREG_BYTE (operand1);
3176       op1_subbyte /= GET_MODE_SIZE (SImode);
3177       op1_subbyte *= GET_MODE_SIZE (SImode);
3178       operand1 = XEXP (operand1, 0);
3179     }
3180   if (GET_CODE (operand0) == SUBREG)
3181     {
3182       op0_subbyte = SUBREG_BYTE (operand0);
3183       op0_subbyte /= GET_MODE_SIZE (SImode);
3184       op0_subbyte *= GET_MODE_SIZE (SImode);
3185       operand0 = XEXP (operand0, 0);
3186     }
3187   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3188                           shift_24));
3189   if (GET_MODE (operand0) != SImode)
3190     operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
3191   emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3192   DONE;
3195 (define_insn "*sign_extendqihi2_insn"
3196   [(set (match_operand:HI 0 "register_operand" "=r")
3197         (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3198   ""
3199   "ldsb\t%1, %0"
3200   [(set_attr "type" "sload")
3201    (set_attr "us3load_type" "3cycle")])
3203 (define_expand "extendqisi2"
3204   [(set (match_operand:SI 0 "register_operand" "")
3205         (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
3206   ""
3208   rtx temp = gen_reg_rtx (SImode);
3209   rtx shift_24 = GEN_INT (24);
3210   int op1_subbyte = 0;
3212   if (GET_CODE (operand1) == SUBREG)
3213     {
3214       op1_subbyte = SUBREG_BYTE (operand1);
3215       op1_subbyte /= GET_MODE_SIZE (SImode);
3216       op1_subbyte *= GET_MODE_SIZE (SImode);
3217       operand1 = XEXP (operand1, 0);
3218     }
3220   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3221                           shift_24));
3222   emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3223   DONE;
3226 (define_insn "*sign_extendqisi2_insn"
3227   [(set (match_operand:SI 0 "register_operand" "=r")
3228         (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3229   ""
3230   "ldsb\t%1, %0"
3231   [(set_attr "type" "sload")
3232    (set_attr "us3load_type" "3cycle")])
3234 (define_expand "extendqidi2"
3235   [(set (match_operand:DI 0 "register_operand" "")
3236         (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
3237   "TARGET_ARCH64"
3239   rtx temp = gen_reg_rtx (DImode);
3240   rtx shift_56 = GEN_INT (56);
3241   int op1_subbyte = 0;
3243   if (GET_CODE (operand1) == SUBREG)
3244     {
3245       op1_subbyte = SUBREG_BYTE (operand1);
3246       op1_subbyte /= GET_MODE_SIZE (DImode);
3247       op1_subbyte *= GET_MODE_SIZE (DImode);
3248       operand1 = XEXP (operand1, 0);
3249     }
3251   emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3252                           shift_56));
3253   emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
3254   DONE;
3257 (define_insn "*sign_extendqidi2_insn"
3258   [(set (match_operand:DI 0 "register_operand" "=r")
3259         (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3260   "TARGET_ARCH64"
3261   "ldsb\t%1, %0"
3262   [(set_attr "type" "sload")
3263    (set_attr "us3load_type" "3cycle")])
3265 (define_expand "extendhidi2"
3266   [(set (match_operand:DI 0 "register_operand" "")
3267         (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
3268   "TARGET_ARCH64"
3270   rtx temp = gen_reg_rtx (DImode);
3271   rtx shift_48 = GEN_INT (48);
3272   int op1_subbyte = 0;
3274   if (GET_CODE (operand1) == SUBREG)
3275     {
3276       op1_subbyte = SUBREG_BYTE (operand1);
3277       op1_subbyte /= GET_MODE_SIZE (DImode);
3278       op1_subbyte *= GET_MODE_SIZE (DImode);
3279       operand1 = XEXP (operand1, 0);
3280     }
3282   emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3283                           shift_48));
3284   emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
3285   DONE;
3288 (define_insn "*sign_extendhidi2_insn"
3289   [(set (match_operand:DI 0 "register_operand" "=r")
3290         (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3291   "TARGET_ARCH64"
3292   "ldsh\t%1, %0"
3293   [(set_attr "type" "sload")
3294    (set_attr "us3load_type" "3cycle")])
3296 (define_expand "extendsidi2"
3297   [(set (match_operand:DI 0 "register_operand" "")
3298         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3299   "TARGET_ARCH64"
3300   "")
3302 (define_insn "*sign_extendsidi2_insn"
3303   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
3304         (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m,*f")))]
3305   "TARGET_ARCH64"
3306   "@
3307   sra\t%1, 0, %0
3308   ldsw\t%1, %0
3309   movstosw\t%1, %0"
3310   [(set_attr "type" "shift,sload,*")
3311    (set_attr "v3pipe" "*,*,true")
3312    (set_attr "us3load_type" "*,3cycle,*")
3313    (set_attr "cpu_feature" "*,*,vis3")])
3316 ;; Special pattern for optimizing bit-field compares.  This is needed
3317 ;; because combine uses this as a canonical form.
3319 (define_insn "*cmp_zero_extract"
3320   [(set (reg:CC CC_REG)
3321         (compare:CC
3322          (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
3323                           (match_operand:SI 1 "small_int_operand" "I")
3324                           (match_operand:SI 2 "small_int_operand" "I"))
3325          (const_int 0)))]
3326   "INTVAL (operands[2]) > 19"
3328   int len = INTVAL (operands[1]);
3329   int pos = 32 - INTVAL (operands[2]) - len;
3330   HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
3331   operands[1] = GEN_INT (mask);
3332   return "andcc\t%0, %1, %%g0";
3334   [(set_attr "type" "compare")])
3336 (define_insn "*cmp_zero_extract_sp64"
3337   [(set (reg:CCX CC_REG)
3338         (compare:CCX
3339          (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
3340                           (match_operand:SI 1 "small_int_operand" "I")
3341                           (match_operand:SI 2 "small_int_operand" "I"))
3342          (const_int 0)))]
3343   "TARGET_ARCH64 && INTVAL (operands[2]) > 51"
3345   int len = INTVAL (operands[1]);
3346   int pos = 64 - INTVAL (operands[2]) - len;
3347   HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
3348   operands[1] = GEN_INT (mask);
3349   return "andcc\t%0, %1, %%g0";
3351   [(set_attr "type" "compare")])
3354 ;; Conversions between float, double and long double.
3356 (define_insn "extendsfdf2"
3357   [(set (match_operand:DF 0 "register_operand" "=e")
3358         (float_extend:DF
3359          (match_operand:SF 1 "register_operand" "f")))]
3360   "TARGET_FPU"
3361   "fstod\t%1, %0"
3362   [(set_attr "type" "fp")
3363    (set_attr "fptype" "double")])
3365 (define_expand "extendsftf2"
3366   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3367         (float_extend:TF
3368          (match_operand:SF 1 "register_operand" "")))]
3369   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3370   "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3372 (define_insn "*extendsftf2_hq"
3373   [(set (match_operand:TF 0 "register_operand" "=e")
3374         (float_extend:TF
3375          (match_operand:SF 1 "register_operand" "f")))]
3376   "TARGET_FPU && TARGET_HARD_QUAD"
3377   "fstoq\t%1, %0"
3378   [(set_attr "type" "fp")])
3380 (define_expand "extenddftf2"
3381   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3382         (float_extend:TF
3383          (match_operand:DF 1 "register_operand" "")))]
3384   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3385   "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3387 (define_insn "*extenddftf2_hq"
3388   [(set (match_operand:TF 0 "register_operand" "=e")
3389         (float_extend:TF
3390          (match_operand:DF 1 "register_operand" "e")))]
3391   "TARGET_FPU && TARGET_HARD_QUAD"
3392   "fdtoq\t%1, %0"
3393   [(set_attr "type" "fp")])
3395 (define_insn "truncdfsf2"
3396   [(set (match_operand:SF 0 "register_operand" "=f")
3397         (float_truncate:SF
3398          (match_operand:DF 1 "register_operand" "e")))]
3399   "TARGET_FPU"
3400   "fdtos\t%1, %0"
3401   [(set_attr "type" "fp")
3402    (set_attr "fptype" "double")
3403    (set_attr "fptype_ut699" "single")])
3405 (define_expand "trunctfsf2"
3406   [(set (match_operand:SF 0 "register_operand" "")
3407         (float_truncate:SF
3408          (match_operand:TF 1 "general_operand" "")))]
3409   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3410   "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3412 (define_insn "*trunctfsf2_hq"
3413   [(set (match_operand:SF 0 "register_operand" "=f")
3414         (float_truncate:SF
3415          (match_operand:TF 1 "register_operand" "e")))]
3416   "TARGET_FPU && TARGET_HARD_QUAD"
3417   "fqtos\t%1, %0"
3418   [(set_attr "type" "fp")])
3420 (define_expand "trunctfdf2"
3421   [(set (match_operand:DF 0 "register_operand" "")
3422         (float_truncate:DF
3423          (match_operand:TF 1 "general_operand" "")))]
3424   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3425   "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3427 (define_insn "*trunctfdf2_hq"
3428   [(set (match_operand:DF 0 "register_operand" "=e")
3429         (float_truncate:DF
3430          (match_operand:TF 1 "register_operand" "e")))]
3431   "TARGET_FPU && TARGET_HARD_QUAD"
3432   "fqtod\t%1, %0"
3433   [(set_attr "type" "fp")])
3436 ;; Conversion between fixed point and floating point.
3438 (define_insn "floatsisf2"
3439   [(set (match_operand:SF 0 "register_operand" "=f")
3440         (float:SF (match_operand:SI 1 "register_operand" "f")))]
3441   "TARGET_FPU"
3442   "fitos\t%1, %0"
3443   [(set_attr "type" "fp")
3444    (set_attr "fptype" "single")])
3446 (define_insn "floatsidf2"
3447   [(set (match_operand:DF 0 "register_operand" "=e")
3448         (float:DF (match_operand:SI 1 "register_operand" "f")))]
3449   "TARGET_FPU"
3450   "fitod\t%1, %0"
3451   [(set_attr "type" "fp")
3452    (set_attr "fptype" "double")])
3454 (define_expand "floatsitf2"
3455   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3456         (float:TF (match_operand:SI 1 "register_operand" "")))]
3457   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3458   "emit_tfmode_cvt (FLOAT, operands); DONE;")
3460 (define_insn "*floatsitf2_hq"
3461   [(set (match_operand:TF 0 "register_operand" "=e")
3462         (float:TF (match_operand:SI 1 "register_operand" "f")))]
3463   "TARGET_FPU && TARGET_HARD_QUAD"
3464   "fitoq\t%1, %0"
3465   [(set_attr "type" "fp")])
3467 (define_expand "floatunssitf2"
3468   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3469         (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
3470   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3471   "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3473 ;; Now the same for 64 bit sources.
3475 (define_insn "floatdisf2"
3476   [(set (match_operand:SF 0 "register_operand" "=f")
3477         (float:SF (match_operand:DI 1 "register_operand" "e")))]
3478   "TARGET_V9 && TARGET_FPU"
3479   "fxtos\t%1, %0"
3480   [(set_attr "type" "fp")
3481    (set_attr "fptype" "double")])
3483 (define_expand "floatunsdisf2"
3484   [(use (match_operand:SF 0 "register_operand" ""))
3485    (use (match_operand:DI 1 "general_operand" ""))]
3486   "TARGET_ARCH64 && TARGET_FPU"
3487   "sparc_emit_floatunsdi (operands, SFmode); DONE;")
3489 (define_insn "floatdidf2"
3490   [(set (match_operand:DF 0 "register_operand" "=e")
3491         (float:DF (match_operand:DI 1 "register_operand" "e")))]
3492   "TARGET_V9 && TARGET_FPU"
3493   "fxtod\t%1, %0"
3494   [(set_attr "type" "fp")
3495    (set_attr "fptype" "double")])
3497 (define_expand "floatunsdidf2"
3498   [(use (match_operand:DF 0 "register_operand" ""))
3499    (use (match_operand:DI 1 "general_operand" ""))]
3500   "TARGET_ARCH64 && TARGET_FPU"
3501   "sparc_emit_floatunsdi (operands, DFmode); DONE;")
3503 (define_expand "floatditf2"
3504   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3505         (float:TF (match_operand:DI 1 "register_operand" "")))]
3506   "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3507   "emit_tfmode_cvt (FLOAT, operands); DONE;")
3509 (define_insn "*floatditf2_hq"
3510   [(set (match_operand:TF 0 "register_operand" "=e")
3511         (float:TF (match_operand:DI 1 "register_operand" "e")))]
3512   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3513   "fxtoq\t%1, %0"
3514   [(set_attr "type" "fp")])
3516 (define_expand "floatunsditf2"
3517   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3518         (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
3519   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3520   "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3522 ;; Convert a float to an actual integer.
3523 ;; Truncation is performed as part of the conversion.
3525 (define_insn "fix_truncsfsi2"
3526   [(set (match_operand:SI 0 "register_operand" "=f")
3527         (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3528   "TARGET_FPU"
3529   "fstoi\t%1, %0"
3530   [(set_attr "type" "fp")
3531    (set_attr "fptype" "single")])
3533 (define_insn "fix_truncdfsi2"
3534   [(set (match_operand:SI 0 "register_operand" "=f")
3535         (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3536   "TARGET_FPU"
3537   "fdtoi\t%1, %0"
3538   [(set_attr "type" "fp")
3539    (set_attr "fptype" "double")
3540    (set_attr "fptype_ut699" "single")])
3542 (define_expand "fix_trunctfsi2"
3543   [(set (match_operand:SI 0 "register_operand" "")
3544         (fix:SI (match_operand:TF 1 "general_operand" "")))]
3545   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3546   "emit_tfmode_cvt (FIX, operands); DONE;")
3548 (define_insn "*fix_trunctfsi2_hq"
3549   [(set (match_operand:SI 0 "register_operand" "=f")
3550         (fix:SI (match_operand:TF 1 "register_operand" "e")))]
3551   "TARGET_FPU && TARGET_HARD_QUAD"
3552   "fqtoi\t%1, %0"
3553   [(set_attr "type" "fp")])
3555 (define_expand "fixuns_trunctfsi2"
3556   [(set (match_operand:SI 0 "register_operand" "")
3557         (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
3558   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3559   "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3561 ;; Now the same, for V9 targets
3563 (define_insn "fix_truncsfdi2"
3564   [(set (match_operand:DI 0 "register_operand" "=e")
3565         (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3566   "TARGET_V9 && TARGET_FPU"
3567   "fstox\t%1, %0"
3568   [(set_attr "type" "fp")
3569    (set_attr "fptype" "double")])
3571 (define_expand "fixuns_truncsfdi2"
3572   [(use (match_operand:DI 0 "register_operand" ""))
3573    (use (match_operand:SF 1 "general_operand" ""))]
3574   "TARGET_ARCH64 && TARGET_FPU"
3575   "sparc_emit_fixunsdi (operands, SFmode); DONE;")
3577 (define_insn "fix_truncdfdi2"
3578   [(set (match_operand:DI 0 "register_operand" "=e")
3579         (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
3580   "TARGET_V9 && TARGET_FPU"
3581   "fdtox\t%1, %0"
3582   [(set_attr "type" "fp")
3583    (set_attr "fptype" "double")])
3585 (define_expand "fixuns_truncdfdi2"
3586   [(use (match_operand:DI 0 "register_operand" ""))
3587    (use (match_operand:DF 1 "general_operand" ""))]
3588   "TARGET_ARCH64 && TARGET_FPU"
3589   "sparc_emit_fixunsdi (operands, DFmode); DONE;")
3591 (define_expand "fix_trunctfdi2"
3592   [(set (match_operand:DI 0 "register_operand" "")
3593         (fix:DI (match_operand:TF 1 "general_operand" "")))]
3594   "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3595   "emit_tfmode_cvt (FIX, operands); DONE;")
3597 (define_insn "*fix_trunctfdi2_hq"
3598   [(set (match_operand:DI 0 "register_operand" "=e")
3599         (fix:DI (match_operand:TF 1 "register_operand" "e")))]
3600   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3601   "fqtox\t%1, %0"
3602   [(set_attr "type" "fp")])
3604 (define_expand "fixuns_trunctfdi2"
3605   [(set (match_operand:DI 0 "register_operand" "")
3606         (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
3607   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3608   "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
3611 ;; Integer addition/subtraction instructions.
3613 (define_expand "adddi3"
3614   [(set (match_operand:DI 0 "register_operand" "")
3615         (plus:DI (match_operand:DI 1 "register_operand" "")
3616                  (match_operand:DI 2 "arith_double_add_operand" "")))]
3617   ""
3619   if (! TARGET_ARCH64)
3620     {
3621       emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3622                           gen_rtx_SET (operands[0],
3623                                    gen_rtx_PLUS (DImode, operands[1],
3624                                                  operands[2])),
3625                           gen_rtx_CLOBBER (VOIDmode,
3626                                    gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3627       DONE;
3628     }
3631 (define_insn_and_split "*adddi3_insn_sp32"
3632   [(set (match_operand:DI 0 "register_operand" "=&r")
3633         (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
3634                  (match_operand:DI 2 "arith_double_operand" "rHI")))
3635    (clobber (reg:CC CC_REG))]
3636   "! TARGET_ARCH64"
3637   "#"
3638   "&& reload_completed"
3639   [(parallel [(set (reg:CC_NOOV CC_REG)
3640                    (compare:CC_NOOV (plus:SI (match_dup 4)
3641                                              (match_dup 5))
3642                                     (const_int 0)))
3643               (set (match_dup 3)
3644                    (plus:SI (match_dup 4) (match_dup 5)))])
3645    (set (match_dup 6)
3646         (plus:SI (plus:SI (match_dup 7)
3647                           (match_dup 8))
3648                  (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3650   operands[3] = gen_lowpart (SImode, operands[0]);
3651   operands[4] = gen_lowpart (SImode, operands[1]);
3652   operands[5] = gen_lowpart (SImode, operands[2]);
3653   operands[6] = gen_highpart (SImode, operands[0]);
3654   operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
3655   operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3657   [(set_attr "length" "2")])
3659 ;; LTU here means "carry set"
3660 (define_insn "addx"
3661   [(set (match_operand:SI 0 "register_operand" "=r")
3662         (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3663                           (match_operand:SI 2 "arith_operand" "rI"))
3664                  (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3665   ""
3666   "addx\t%1, %2, %0"
3667   [(set_attr "type" "ialuX")])
3669 (define_insn "addxc"
3670   [(set (match_operand:DI 0 "register_operand" "=r")
3671         (plus:DI (plus:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
3672                           (match_operand:DI 2 "register_or_zero_operand" "rJ"))
3673                  (ltu:DI (reg:CCX_NOOV CC_REG) (const_int 0))))]
3674   "TARGET_ARCH64 && TARGET_VIS3"
3675   "addxc\t%r1, %r2, %0"
3676   [(set_attr "type" "ialuX")])
3678 (define_insn_and_split "*addx_extend_sp32"
3679   [(set (match_operand:DI 0 "register_operand" "=r")
3680         (zero_extend:DI (plus:SI (plus:SI
3681                                   (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3682                                   (match_operand:SI 2 "arith_operand" "rI"))
3683                                  (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3684   "! TARGET_ARCH64"
3685   "#"
3686   "&& reload_completed"
3687   [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
3688                                (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))
3689    (set (match_dup 4) (const_int 0))]
3690   "operands[3] = gen_lowpart (SImode, operands[0]);
3691    operands[4] = gen_highpart (SImode, operands[0]);"
3692   [(set_attr "length" "2")])
3694 (define_insn "*addx_extend_sp64"
3695   [(set (match_operand:DI 0 "register_operand" "=r")
3696         (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3697                                           (match_operand:SI 2 "register_or_zero_operand" "rJ"))
3698                                  (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3699   "TARGET_ARCH64"
3700   "addx\t%r1, %r2, %0"
3701   [(set_attr "type" "ialuX")])
3703 (define_insn "*addxc_trunc_sp64_vis3"
3704   [(set (match_operand:SI 0 "register_operand" "=r")
3705         (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
3706                           (match_operand:SI 2 "register_or_zero_operand" "rJ"))
3707                  (ltu:SI (reg:CCX_NOOV CC_REG) (const_int 0))))]
3708   "TARGET_ARCH64 && TARGET_VIS3"
3709   "addxc\t%r1, %r2, %0"
3710   [(set_attr "type" "ialuX")])
3712 (define_insn_and_split "*adddi3_extend_sp32"
3713   [(set (match_operand:DI 0 "register_operand" "=&r")
3714         (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
3715                  (match_operand:DI 2 "register_operand" "r")))
3716    (clobber (reg:CC CC_REG))]
3717   "! TARGET_ARCH64"
3718   "#"
3719   "&& reload_completed"
3720   [(parallel [(set (reg:CC_NOOV CC_REG)
3721                    (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
3722                                     (const_int 0)))
3723               (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
3724    (set (match_dup 6)
3725         (plus:SI (plus:SI (match_dup 4) (const_int 0))
3726                  (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3727   "operands[3] = gen_lowpart (SImode, operands[2]);
3728    operands[4] = gen_highpart (SImode, operands[2]);
3729    operands[5] = gen_lowpart (SImode, operands[0]);
3730    operands[6] = gen_highpart (SImode, operands[0]);"
3731   [(set_attr "length" "2")])
3733 (define_insn "*adddi3_sp64"
3734   [(set (match_operand:DI 0 "register_operand" "=r,r")
3735         (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
3736                  (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3737   "TARGET_ARCH64"
3738   "@
3739    add\t%1, %2, %0
3740    sub\t%1, -%2, %0")
3742 (define_insn "addsi3"
3743   [(set (match_operand:SI 0 "register_operand" "=r,r")
3744         (plus:SI (match_operand:SI 1 "register_operand" "%r,r")
3745                  (match_operand:SI 2 "arith_add_operand" "rI,O")))]
3746   ""
3747   "@
3748    add\t%1, %2, %0
3749    sub\t%1, -%2, %0"
3750   [(set_attr "type" "*,*")
3751    (set_attr "fptype" "*,*")])
3753 (define_insn "*cmp_cc_plus"
3754   [(set (reg:CC_NOOV CC_REG)
3755         (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
3756                                   (match_operand:SI 1 "arith_operand" "rI"))
3757                          (const_int 0)))]
3758   ""
3759   "addcc\t%0, %1, %%g0"
3760   [(set_attr "type" "compare")])
3762 (define_insn "*cmp_ccx_plus"
3763   [(set (reg:CCX_NOOV CC_REG)
3764         (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_operand" "%r")
3765                                    (match_operand:DI 1 "arith_operand" "rI"))
3766                           (const_int 0)))]
3767   "TARGET_ARCH64"
3768   "addcc\t%0, %1, %%g0"
3769   [(set_attr "type" "compare")])
3771 (define_insn "*cmp_cc_plus_set"
3772   [(set (reg:CC_NOOV CC_REG)
3773         (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
3774                                   (match_operand:SI 2 "arith_operand" "rI"))
3775                          (const_int 0)))
3776    (set (match_operand:SI 0 "register_operand" "=r")
3777         (plus:SI (match_dup 1) (match_dup 2)))]
3778   ""
3779   "addcc\t%1, %2, %0"
3780   [(set_attr "type" "compare")])
3782 (define_insn "*cmp_ccx_plus_set"
3783   [(set (reg:CCX_NOOV CC_REG)
3784         (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_operand" "%r")
3785                                    (match_operand:DI 2 "arith_operand" "rI"))
3786                           (const_int 0)))
3787    (set (match_operand:DI 0 "register_operand" "=r")
3788         (plus:DI (match_dup 1) (match_dup 2)))]
3789   "TARGET_ARCH64"
3790   "addcc\t%1, %2, %0"
3791   [(set_attr "type" "compare")])
3793 (define_expand "subdi3"
3794   [(set (match_operand:DI 0 "register_operand" "")
3795         (minus:DI (match_operand:DI 1 "register_operand" "")
3796                   (match_operand:DI 2 "arith_double_add_operand" "")))]
3797   ""
3799   if (! TARGET_ARCH64)
3800     {
3801       emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
3802                           gen_rtx_SET (operands[0],
3803                                    gen_rtx_MINUS (DImode, operands[1],
3804                                                   operands[2])),
3805                           gen_rtx_CLOBBER (VOIDmode,
3806                                    gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
3807       DONE;
3808     }
3811 (define_insn_and_split "*subdi3_insn_sp32"
3812   [(set (match_operand:DI 0 "register_operand" "=&r")
3813         (minus:DI (match_operand:DI 1 "register_operand" "r")
3814                   (match_operand:DI 2 "arith_double_operand" "rHI")))
3815    (clobber (reg:CC CC_REG))]
3816   "! TARGET_ARCH64"
3817   "#"
3818   "&& reload_completed"
3819   [(parallel [(set (reg:CC_NOOV CC_REG)
3820                    (compare:CC_NOOV (minus:SI (match_dup 4)
3821                                               (match_dup 5))
3822                                     (const_int 0)))
3823               (set (match_dup 3)
3824                    (minus:SI (match_dup 4) (match_dup 5)))])
3825    (set (match_dup 6)
3826         (minus:SI (minus:SI (match_dup 7)
3827                             (match_dup 8))
3828                   (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3830   operands[3] = gen_lowpart (SImode, operands[0]);
3831   operands[4] = gen_lowpart (SImode, operands[1]);
3832   operands[5] = gen_lowpart (SImode, operands[2]);
3833   operands[6] = gen_highpart (SImode, operands[0]);
3834   operands[7] = gen_highpart (SImode, operands[1]);
3835   operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
3837   [(set_attr "length" "2")])
3839 ;; LTU here means "carry set"
3840 (define_insn "subx"
3841   [(set (match_operand:SI 0 "register_operand" "=r")
3842         (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3843                             (match_operand:SI 2 "arith_operand" "rI"))
3844                   (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3845   ""
3846   "subx\t%r1, %2, %0"
3847   [(set_attr "type" "ialuX")])
3849 (define_insn "*subx_extend_sp64"
3850   [(set (match_operand:DI 0 "register_operand" "=r")
3851         (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3852                                             (match_operand:SI 2 "arith_operand" "rI"))
3853                                   (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3854   "TARGET_ARCH64"
3855   "subx\t%r1, %2, %0"
3856   [(set_attr "type" "ialuX")])
3858 (define_insn_and_split "*subx_extend_sp32"
3859   [(set (match_operand:DI 0 "register_operand" "=r")
3860         (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3861                                             (match_operand:SI 2 "arith_operand" "rI"))
3862                                   (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0)))))]
3863   "! TARGET_ARCH64"
3864   "#"
3865   "&& reload_completed"
3866   [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
3867                                 (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))
3868    (set (match_dup 4) (const_int 0))]
3869   "operands[3] = gen_lowpart (SImode, operands[0]);
3870    operands[4] = gen_highpart (SImode, operands[0]);"
3871   [(set_attr "length" "2")])
3873 (define_insn_and_split "*subdi3_extend_sp32"
3874   [(set (match_operand:DI 0 "register_operand" "=&r")
3875       (minus:DI (match_operand:DI 1 "register_operand" "r")
3876                 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
3877    (clobber (reg:CC CC_REG))]
3878   "! TARGET_ARCH64"
3879   "#"
3880   "&& reload_completed"
3881   [(parallel [(set (reg:CC_NOOV CC_REG)
3882                    (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
3883                                     (const_int 0)))
3884               (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
3885    (set (match_dup 6)
3886         (minus:SI (minus:SI (match_dup 4) (const_int 0))
3887                   (ltu:SI (reg:CC_NOOV CC_REG) (const_int 0))))]
3888   "operands[3] = gen_lowpart (SImode, operands[1]);
3889    operands[4] = gen_highpart (SImode, operands[1]);
3890    operands[5] = gen_lowpart (SImode, operands[0]);
3891    operands[6] = gen_highpart (SImode, operands[0]);"
3892   [(set_attr "length" "2")])
3894 (define_insn "*subdi3_sp64"
3895   [(set (match_operand:DI 0 "register_operand" "=r,r")
3896         (minus:DI (match_operand:DI 1 "register_operand" "r,r")
3897                   (match_operand:DI 2 "arith_add_operand" "rI,O")))]
3898   "TARGET_ARCH64"
3899   "@
3900    sub\t%1, %2, %0
3901    add\t%1, -%2, %0")
3903 (define_insn "subsi3"
3904   [(set (match_operand:SI 0 "register_operand" "=r,r")
3905         (minus:SI (match_operand:SI 1 "register_operand" "r,r")
3906                   (match_operand:SI 2 "arith_add_operand" "rI,O")))]
3907   ""
3908   "@
3909    sub\t%1, %2, %0
3910    add\t%1, -%2, %0"
3911   [(set_attr "type" "*,*")
3912    (set_attr "fptype" "*,*")])
3914 (define_insn "*cmp_minus_cc"
3915   [(set (reg:CC_NOOV CC_REG)
3916         (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
3917                                    (match_operand:SI 1 "arith_operand" "rI"))
3918                          (const_int 0)))]
3919   ""
3920   "subcc\t%r0, %1, %%g0"
3921   [(set_attr "type" "compare")])
3923 (define_insn "*cmp_minus_ccx"
3924   [(set (reg:CCX_NOOV CC_REG)
3925         (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
3926                                     (match_operand:DI 1 "arith_operand" "rI"))
3927                           (const_int 0)))]
3928   "TARGET_ARCH64"
3929   "subcc\t%0, %1, %%g0"
3930   [(set_attr "type" "compare")])
3932 (define_insn "cmp_minus_cc_set"
3933   [(set (reg:CC_NOOV CC_REG)
3934         (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
3935                                    (match_operand:SI 2 "arith_operand" "rI"))
3936                          (const_int 0)))
3937    (set (match_operand:SI 0 "register_operand" "=r")
3938         (minus:SI (match_dup 1) (match_dup 2)))]
3939   ""
3940   "subcc\t%r1, %2, %0"
3941   [(set_attr "type" "compare")])
3943 (define_insn "*cmp_minus_ccx_set"
3944   [(set (reg:CCX_NOOV CC_REG)
3945         (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
3946                                     (match_operand:DI 2 "arith_operand" "rI"))
3947                           (const_int 0)))
3948    (set (match_operand:DI 0 "register_operand" "=r")
3949         (minus:DI (match_dup 1) (match_dup 2)))]
3950   "TARGET_ARCH64"
3951   "subcc\t%1, %2, %0"
3952   [(set_attr "type" "compare")])
3955 ;; Integer multiply/divide instructions.
3957 ;; The 32-bit multiply/divide instructions are deprecated on v9, but at
3958 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
3960 (define_insn "mulsi3"
3961   [(set (match_operand:SI 0 "register_operand" "=r")
3962         (mult:SI (match_operand:SI 1 "arith_operand" "%r")
3963                  (match_operand:SI 2 "arith_operand" "rI")))]
3964   "TARGET_HARD_MUL"
3965   "smul\t%1, %2, %0"
3966   [(set_attr "type" "imul")])
3968 (define_expand "muldi3"
3969   [(set (match_operand:DI 0 "register_operand" "")
3970         (mult:DI (match_operand:DI 1 "arith_operand" "")
3971                  (match_operand:DI 2 "arith_operand" "")))]
3972   "TARGET_ARCH64 || TARGET_V8PLUS"
3974   if (TARGET_V8PLUS)
3975     {
3976       emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
3977       DONE;
3978     }
3981 (define_insn "*muldi3_sp64"
3982   [(set (match_operand:DI 0 "register_operand" "=r")
3983         (mult:DI (match_operand:DI 1 "arith_operand" "%r")
3984                  (match_operand:DI 2 "arith_operand" "rI")))]
3985   "TARGET_ARCH64"
3986   "mulx\t%1, %2, %0"
3987   [(set_attr "type" "imul")])
3989 ;; V8plus wide multiply.
3990 (define_insn "muldi3_v8plus"
3991   [(set (match_operand:DI 0 "register_operand" "=r,h")
3992         (mult:DI (match_operand:DI 1 "arith_operand" "%r,0")
3993                  (match_operand:DI 2 "arith_operand" "rI,rI")))
3994    (clobber (match_scratch:SI 3 "=&h,X"))
3995    (clobber (match_scratch:SI 4 "=&h,X"))]
3996   "TARGET_V8PLUS"
3997   "* return output_v8plus_mult (insn, operands, \"mulx\");"
3998   [(set_attr "type" "multi")
3999    (set_attr "length" "9,8")])
4001 (define_insn "*cmp_mul_set"
4002   [(set (reg:CC CC_REG)
4003         (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4004                     (match_operand:SI 2 "arith_operand" "rI"))
4005                     (const_int 0)))
4006    (set (match_operand:SI 0 "register_operand" "=r")
4007         (mult:SI (match_dup 1) (match_dup 2)))]
4008   "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
4009   "smulcc\t%1, %2, %0"
4010   [(set_attr "type" "imul")])
4012 (define_expand "mulsidi3"
4013   [(set (match_operand:DI 0 "register_operand" "")
4014         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4015                  (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
4016   "TARGET_HARD_MUL"
4018   if (CONSTANT_P (operands[2]))
4019     {
4020       if (TARGET_V8PLUS)
4021         emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
4022                                               operands[2]));
4023       else if (TARGET_ARCH32)
4024         emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
4025                                             operands[2]));
4026       else 
4027         emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
4028                                             operands[2]));
4029       DONE;
4030     }
4031   if (TARGET_V8PLUS)
4032     {
4033       emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
4034       DONE;
4035     }
4038 ;; V9 puts the 64-bit product in a 64-bit register.  Only out or global
4039 ;; registers can hold 64-bit values in the V8plus environment.
4040 (define_insn "mulsidi3_v8plus"
4041   [(set (match_operand:DI 0 "register_operand" "=h,r")
4042         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4043                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4044    (clobber (match_scratch:SI 3 "=X,&h"))]
4045   "TARGET_V8PLUS"
4046   "@
4047    smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4048    smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4049   [(set_attr "type" "multi")
4050    (set_attr "length" "2,3")])
4052 (define_insn "const_mulsidi3_v8plus"
4053   [(set (match_operand:DI 0 "register_operand" "=h,r")
4054         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4055                  (match_operand:DI 2 "small_int_operand" "I,I")))
4056    (clobber (match_scratch:SI 3 "=X,&h"))]
4057   "TARGET_V8PLUS"
4058   "@
4059    smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4060    smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4061   [(set_attr "type" "multi")
4062    (set_attr "length" "2,3")])
4064 (define_insn "*mulsidi3_sp32"
4065   [(set (match_operand:DI 0 "register_operand" "=r")
4066         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4067                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4068   "TARGET_HARD_MUL32"
4070   return TARGET_SPARCLET
4071          ? "smuld\t%1, %2, %L0"
4072          : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4074   [(set (attr "type")
4075         (if_then_else (eq_attr "isa" "sparclet")
4076                       (const_string "imul") (const_string "multi")))
4077    (set (attr "length")
4078         (if_then_else (eq_attr "isa" "sparclet")
4079                       (const_int 1) (const_int 2)))])
4081 (define_insn "*mulsidi3_sp64"
4082   [(set (match_operand:DI 0 "register_operand" "=r")
4083         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4084                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4085   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4086   "smul\t%1, %2, %0"
4087   [(set_attr "type" "imul")])
4089 ;; Extra pattern, because sign_extend of a constant isn't valid.
4091 (define_insn "const_mulsidi3_sp32"
4092   [(set (match_operand:DI 0 "register_operand" "=r")
4093         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4094                  (match_operand:DI 2 "small_int_operand" "I")))]
4095   "TARGET_HARD_MUL32"
4097   return TARGET_SPARCLET
4098          ? "smuld\t%1, %2, %L0"
4099          : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4101   [(set (attr "type")
4102         (if_then_else (eq_attr "isa" "sparclet")
4103                       (const_string "imul") (const_string "multi")))
4104    (set (attr "length")
4105         (if_then_else (eq_attr "isa" "sparclet")
4106                       (const_int 1) (const_int 2)))])
4108 (define_insn "const_mulsidi3_sp64"
4109   [(set (match_operand:DI 0 "register_operand" "=r")
4110         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4111                  (match_operand:DI 2 "small_int_operand" "I")))]
4112   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4113   "smul\t%1, %2, %0"
4114   [(set_attr "type" "imul")])
4116 (define_expand "smulsi3_highpart"
4117   [(set (match_operand:SI 0 "register_operand" "")
4118         (truncate:SI
4119          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4120                                (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
4121                       (const_int 32))))]
4122   "TARGET_HARD_MUL && TARGET_ARCH32"
4124   if (CONSTANT_P (operands[2]))
4125     {
4126       if (TARGET_V8PLUS)
4127         {
4128           emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
4129                                                         operands[1],
4130                                                         operands[2],
4131                                                         GEN_INT (32)));
4132           DONE;
4133         }
4134       emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
4135       DONE;
4136     }
4137   if (TARGET_V8PLUS)
4138     {
4139       emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
4140                                               operands[2], GEN_INT (32)));
4141       DONE;
4142     }
4145 (define_insn "smulsi3_highpart_v8plus"
4146   [(set (match_operand:SI 0 "register_operand" "=h,r")
4147         (truncate:SI
4148          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4149                                (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4150                       (match_operand:SI 3 "small_int_operand" "I,I"))))
4151    (clobber (match_scratch:SI 4 "=X,&h"))]
4152   "TARGET_V8PLUS"
4153   "@
4154    smul\t%1, %2, %0\;srlx\t%0, %3, %0
4155    smul\t%1, %2, %4\;srlx\t%4, %3, %0"
4156   [(set_attr "type" "multi")
4157    (set_attr "length" "2")])
4159 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
4160 (define_insn ""
4161   [(set (match_operand:SI 0 "register_operand" "=h,r")
4162         (subreg:SI
4163          (lshiftrt:DI
4164           (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4165                    (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4166           (match_operand:SI 3 "small_int_operand" "I,I"))
4167          4))
4168    (clobber (match_scratch:SI 4 "=X,&h"))]
4169   "TARGET_V8PLUS"
4170   "@
4171    smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4172    smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4173   [(set_attr "type" "multi")
4174    (set_attr "length" "2")])
4176 (define_insn "const_smulsi3_highpart_v8plus"
4177   [(set (match_operand:SI 0 "register_operand" "=h,r")
4178         (truncate:SI
4179          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4180                                (match_operand:DI 2 "small_int_operand" "I,I"))
4181                       (match_operand:SI 3 "small_int_operand" "I,I"))))
4182    (clobber (match_scratch:SI 4 "=X,&h"))]
4183   "TARGET_V8PLUS"
4184   "@
4185    smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4186    smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4187   [(set_attr "type" "multi")
4188    (set_attr "length" "2")])
4190 (define_insn "*smulsi3_highpart_sp32"
4191   [(set (match_operand:SI 0 "register_operand" "=r")
4192         (truncate:SI
4193          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4194                                (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
4195                       (const_int 32))))]
4196   "TARGET_HARD_MUL32"
4197   "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4198   [(set_attr "type" "multi")
4199    (set_attr "length" "2")])
4201 (define_insn "const_smulsi3_highpart"
4202   [(set (match_operand:SI 0 "register_operand" "=r")
4203         (truncate:SI
4204          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4205                                (match_operand:DI 2 "small_int_operand" "i"))
4206                       (const_int 32))))]
4207   "TARGET_HARD_MUL32"
4208   "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4209   [(set_attr "type" "multi")
4210    (set_attr "length" "2")])
4212 (define_expand "umulsidi3"
4213   [(set (match_operand:DI 0 "register_operand" "")
4214         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4215                  (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
4216   "TARGET_HARD_MUL"
4218   if (CONSTANT_P (operands[2]))
4219     {
4220       if (TARGET_V8PLUS)
4221         emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
4222                                                operands[2]));
4223       else if (TARGET_ARCH32)
4224         emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
4225                                              operands[2]));
4226       else 
4227         emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
4228                                              operands[2]));
4229       DONE;
4230     }
4231   if (TARGET_V8PLUS)
4232     {
4233       emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
4234       DONE;
4235     }
4238 (define_insn "umulsidi3_v8plus"
4239   [(set (match_operand:DI 0 "register_operand" "=h,r")
4240         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4241                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4242    (clobber (match_scratch:SI 3 "=X,&h"))]
4243   "TARGET_V8PLUS"
4244   "@
4245    umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4246    umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4247   [(set_attr "type" "multi")
4248    (set_attr "length" "2,3")])
4250 (define_insn "*umulsidi3_sp32"
4251   [(set (match_operand:DI 0 "register_operand" "=r")
4252         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4253                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4254   "TARGET_HARD_MUL32"
4256   return TARGET_SPARCLET
4257          ? "umuld\t%1, %2, %L0"
4258          : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
4260   [(set (attr "type")
4261         (if_then_else (eq_attr "isa" "sparclet")
4262                       (const_string "imul") (const_string "multi")))
4263    (set (attr "length")
4264         (if_then_else (eq_attr "isa" "sparclet")
4265                       (const_int 1) (const_int 2)))])
4267 (define_insn "*umulsidi3_sp64"
4268   [(set (match_operand:DI 0 "register_operand" "=r")
4269         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4270                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4271   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4272   "umul\t%1, %2, %0"
4273   [(set_attr "type" "imul")])
4275 ;; Extra pattern, because sign_extend of a constant isn't valid.
4277 (define_insn "const_umulsidi3_sp32"
4278   [(set (match_operand:DI 0 "register_operand" "=r")
4279         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4280                  (match_operand:DI 2 "uns_small_int_operand" "")))]
4281   "TARGET_HARD_MUL32"
4283   return TARGET_SPARCLET
4284          ? "umuld\t%1, %s2, %L0"
4285          : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
4287   [(set (attr "type")
4288         (if_then_else (eq_attr "isa" "sparclet")
4289                       (const_string "imul") (const_string "multi")))
4290    (set (attr "length")
4291         (if_then_else (eq_attr "isa" "sparclet")
4292                       (const_int 1) (const_int 2)))])
4294 (define_insn "const_umulsidi3_sp64"
4295   [(set (match_operand:DI 0 "register_operand" "=r")
4296         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4297                  (match_operand:DI 2 "uns_small_int_operand" "")))]
4298   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4299   "umul\t%1, %s2, %0"
4300   [(set_attr "type" "imul")])
4302 (define_insn "const_umulsidi3_v8plus"
4303   [(set (match_operand:DI 0 "register_operand" "=h,r")
4304         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4305                  (match_operand:DI 2 "uns_small_int_operand" "")))
4306    (clobber (match_scratch:SI 3 "=X,h"))]
4307   "TARGET_V8PLUS"
4308   "@
4309    umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
4310    umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4311   [(set_attr "type" "multi")
4312    (set_attr "length" "2,3")])
4314 (define_expand "umulsi3_highpart"
4315   [(set (match_operand:SI 0 "register_operand" "")
4316         (truncate:SI
4317          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4318                                (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
4319                       (const_int 32))))]
4320   "TARGET_HARD_MUL && TARGET_ARCH32"
4322   if (CONSTANT_P (operands[2]))
4323     {
4324       if (TARGET_V8PLUS)
4325         {
4326           emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
4327                                                         operands[1],
4328                                                         operands[2],
4329                                                         GEN_INT (32)));
4330           DONE;
4331         }
4332       emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
4333       DONE;
4334     }
4335   if (TARGET_V8PLUS)
4336     {
4337       emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
4338                                               operands[2], GEN_INT (32)));
4339       DONE;
4340     }
4343 (define_insn "umulsi3_highpart_v8plus"
4344   [(set (match_operand:SI 0 "register_operand" "=h,r")
4345         (truncate:SI
4346          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4347                                (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4348                       (match_operand:SI 3 "small_int_operand" "I,I"))))
4349    (clobber (match_scratch:SI 4 "=X,h"))]
4350   "TARGET_V8PLUS"
4351   "@
4352    umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4353    umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4354   [(set_attr "type" "multi")
4355    (set_attr "length" "2")])
4357 (define_insn "const_umulsi3_highpart_v8plus"
4358   [(set (match_operand:SI 0 "register_operand" "=h,r")
4359         (truncate:SI
4360          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4361                                (match_operand:DI 2 "uns_small_int_operand" ""))
4362                       (match_operand:SI 3 "small_int_operand" "I,I"))))
4363    (clobber (match_scratch:SI 4 "=X,h"))]
4364   "TARGET_V8PLUS"
4365   "@
4366    umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
4367    umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
4368   [(set_attr "type" "multi")
4369    (set_attr "length" "2")])
4371 (define_insn "*umulsi3_highpart_sp32"
4372   [(set (match_operand:SI 0 "register_operand" "=r")
4373         (truncate:SI
4374          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4375                                (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
4376                       (const_int 32))))]
4377   "TARGET_HARD_MUL32"
4378   "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
4379   [(set_attr "type" "multi")
4380    (set_attr "length" "2")])
4382 (define_insn "const_umulsi3_highpart"
4383   [(set (match_operand:SI 0 "register_operand" "=r")
4384         (truncate:SI
4385          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4386                                (match_operand:DI 2 "uns_small_int_operand" ""))
4387                       (const_int 32))))]
4388   "TARGET_HARD_MUL32"
4389   "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
4390   [(set_attr "type" "multi")
4391    (set_attr "length" "2")])
4394 (define_expand "umulxhi_vis"
4395   [(set (match_operand:DI 0 "register_operand" "")
4396         (truncate:DI
4397           (lshiftrt:TI
4398             (mult:TI (zero_extend:TI
4399                        (match_operand:DI 1 "arith_operand" ""))
4400                      (zero_extend:TI
4401                        (match_operand:DI 2 "arith_operand" "")))
4402            (const_int 64))))]
4403  "TARGET_VIS3"
4405   if (! TARGET_ARCH64)
4406     {
4407       emit_insn (gen_umulxhi_v8plus (operands[0], operands[1], operands[2]));
4408       DONE;
4409     }
4412 (define_insn "*umulxhi_sp64"
4413   [(set (match_operand:DI 0 "register_operand" "=r")
4414         (truncate:DI
4415           (lshiftrt:TI
4416             (mult:TI (zero_extend:TI
4417                        (match_operand:DI 1 "arith_operand" "%r"))
4418                      (zero_extend:TI
4419                        (match_operand:DI 2 "arith_operand" "rI")))
4420            (const_int 64))))]
4421   "TARGET_VIS3 && TARGET_ARCH64"
4422   "umulxhi\t%1, %2, %0"
4423   [(set_attr "type" "imul")])
4425 (define_insn "umulxhi_v8plus"
4426   [(set (match_operand:DI 0 "register_operand" "=r,h")
4427         (truncate:DI
4428           (lshiftrt:TI
4429             (mult:TI (zero_extend:TI
4430                        (match_operand:DI 1 "arith_operand" "%r,0"))
4431                      (zero_extend:TI
4432                        (match_operand:DI 2 "arith_operand" "rI,rI")))
4433            (const_int 64))))
4434    (clobber (match_scratch:SI 3 "=&h,X"))
4435    (clobber (match_scratch:SI 4 "=&h,X"))]
4436   "TARGET_VIS3 && ! TARGET_ARCH64"
4437   "* return output_v8plus_mult (insn, operands, \"umulxhi\");"
4438   [(set_attr "type" "imul")
4439    (set_attr "length" "9,8")])
4441 (define_expand "xmulx_vis"
4442   [(set (match_operand:DI 0 "register_operand" "")
4443         (truncate:DI
4444           (unspec:TI [(zero_extend:TI
4445                         (match_operand:DI 1 "arith_operand" ""))
4446                       (zero_extend:TI
4447                         (match_operand:DI 2 "arith_operand" ""))]
4448            UNSPEC_XMUL)))]
4449   "TARGET_VIS3"
4451   if (! TARGET_ARCH64)
4452     {
4453       emit_insn (gen_xmulx_v8plus (operands[0], operands[1], operands[2]));
4454       DONE;
4455     }
4458 (define_insn "*xmulx_sp64"
4459   [(set (match_operand:DI 0 "register_operand" "=r")
4460         (truncate:DI
4461           (unspec:TI [(zero_extend:TI
4462                         (match_operand:DI 1 "arith_operand" "%r"))
4463                       (zero_extend:TI
4464                         (match_operand:DI 2 "arith_operand" "rI"))]
4465            UNSPEC_XMUL)))]
4466   "TARGET_VIS3 && TARGET_ARCH64"
4467   "xmulx\t%1, %2, %0"
4468   [(set_attr "type" "imul")])
4470 (define_insn "xmulx_v8plus"
4471   [(set (match_operand:DI 0 "register_operand" "=r,h")
4472         (truncate:DI
4473           (unspec:TI [(zero_extend:TI
4474                         (match_operand:DI 1 "arith_operand" "%r,0"))
4475                       (zero_extend:TI
4476                         (match_operand:DI 2 "arith_operand" "rI,rI"))]
4477            UNSPEC_XMUL)))
4478    (clobber (match_scratch:SI 3 "=&h,X"))
4479    (clobber (match_scratch:SI 4 "=&h,X"))]
4480   "TARGET_VIS3 && ! TARGET_ARCH64"
4481   "* return output_v8plus_mult (insn, operands, \"xmulx\");"
4482   [(set_attr "type" "imul")
4483    (set_attr "length" "9,8")])
4485 (define_expand "xmulxhi_vis"
4486   [(set (match_operand:DI 0 "register_operand" "")
4487         (truncate:DI
4488           (lshiftrt:TI
4489             (unspec:TI [(zero_extend:TI
4490                           (match_operand:DI 1 "arith_operand" ""))
4491                         (zero_extend:TI
4492                           (match_operand:DI 2 "arith_operand" ""))]
4493              UNSPEC_XMUL)
4494            (const_int 64))))]
4495   "TARGET_VIS3"
4497   if (! TARGET_ARCH64)
4498     {
4499       emit_insn (gen_xmulxhi_v8plus (operands[0], operands[1], operands[2]));
4500       DONE;
4501     }
4504 (define_insn "*xmulxhi_sp64"
4505   [(set (match_operand:DI 0 "register_operand" "=r")
4506         (truncate:DI
4507           (lshiftrt:TI
4508             (unspec:TI [(zero_extend:TI
4509                           (match_operand:DI 1 "arith_operand" "%r"))
4510                         (zero_extend:TI
4511                           (match_operand:DI 2 "arith_operand" "rI"))]
4512              UNSPEC_XMUL)
4513            (const_int 64))))]
4514   "TARGET_VIS3 && TARGET_ARCH64"
4515   "xmulxhi\t%1, %2, %0"
4516   [(set_attr "type" "imul")])
4518 (define_insn "xmulxhi_v8plus"
4519   [(set (match_operand:DI 0 "register_operand" "=r,h")
4520         (truncate:DI
4521           (lshiftrt:TI
4522             (unspec:TI [(zero_extend:TI
4523                           (match_operand:DI 1 "arith_operand" "%r,0"))
4524                         (zero_extend:TI
4525                           (match_operand:DI 2 "arith_operand" "rI,rI"))]
4526              UNSPEC_XMUL)
4527            (const_int 64))))
4528    (clobber (match_scratch:SI 3 "=&h,X"))
4529    (clobber (match_scratch:SI 4 "=&h,X"))]
4530   "TARGET_VIS3 && !TARGET_ARCH64"
4531   "* return output_v8plus_mult (insn, operands, \"xmulxhi\");"
4532   [(set_attr "type" "imul")
4533    (set_attr "length" "9,8")])
4535 (define_expand "divsi3"
4536   [(parallel [(set (match_operand:SI 0 "register_operand" "")
4537                    (div:SI (match_operand:SI 1 "register_operand" "")
4538                            (match_operand:SI 2 "input_operand" "")))
4539               (clobber (match_scratch:SI 3 ""))])]
4540   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4542   if (TARGET_ARCH64)
4543     {
4544       operands[3] = gen_reg_rtx(SImode);
4545       emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
4546       emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
4547                                   operands[3]));
4548       DONE;
4549     }
4552 ;; The V8 architecture specifies that there must be at least 3 instructions
4553 ;; between a write to the Y register and a use of it for correct results.
4554 ;; We try to fill one of them with a simple constant or a memory load.
4556 (define_insn "divsi3_sp32"
4557   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
4558         (div:SI (match_operand:SI 1 "register_operand" "r,r,r")
4559                 (match_operand:SI 2 "input_operand" "rI,K,m")))
4560    (clobber (match_scratch:SI 3 "=&r,&r,&r"))]
4561   "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4563   output_asm_insn ("sra\t%1, 31, %3", operands);
4564   output_asm_insn ("wr\t%3, 0, %%y", operands);
4566   switch (which_alternative)
4567     {
4568     case 0:
4569       if (TARGET_V9)
4570         return "sdiv\t%1, %2, %0";
4571       else
4572         return "nop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
4573     case 1:
4574       if (TARGET_V9)
4575         return "sethi\t%%hi(%a2), %3\n\tsdiv\t%1, %3, %0";
4576       else
4577         return "sethi\t%%hi(%a2), %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4578     case 2:
4579       if (TARGET_V9)
4580         return "ld\t%2, %3\n\tsdiv\t%1, %3, %0";
4581       else
4582         return "ld\t%2, %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4583     default:
4584       gcc_unreachable ();
4585     }
4587   [(set_attr "type" "multi")
4588    (set (attr "length")
4589         (if_then_else (eq_attr "isa" "v9")
4590                       (const_int 4) (const_int 6)))])
4592 (define_insn "divsi3_sp64"
4593   [(set (match_operand:SI 0 "register_operand" "=r")
4594         (div:SI (match_operand:SI 1 "register_operand" "r")
4595                 (match_operand:SI 2 "input_operand" "rI")))
4596    (use (match_operand:SI 3 "register_operand" "r"))]
4597   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4598   "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
4599   [(set_attr "type" "multi")
4600    (set_attr "length" "2")])
4602 (define_insn "divdi3"
4603   [(set (match_operand:DI 0 "register_operand" "=r")
4604         (div:DI (match_operand:DI 1 "register_operand" "r")
4605                 (match_operand:DI 2 "arith_operand" "rI")))]
4606   "TARGET_ARCH64"
4607   "sdivx\t%1, %2, %0"
4608   [(set_attr "type" "idiv")])
4610 (define_insn "*cmp_sdiv_cc_set"
4611   [(set (reg:CC CC_REG)
4612         (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
4613                             (match_operand:SI 2 "arith_operand" "rI"))
4614                     (const_int 0)))
4615    (set (match_operand:SI 0 "register_operand" "=r")
4616         (div:SI (match_dup 1) (match_dup 2)))
4617    (clobber (match_scratch:SI 3 "=&r"))]
4618   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4620   output_asm_insn ("sra\t%1, 31, %3", operands);
4621   output_asm_insn ("wr\t%3, 0, %%y", operands);
4623   if (TARGET_V9)
4624     return "sdivcc\t%1, %2, %0";
4625   else
4626     return "nop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
4628   [(set_attr "type" "multi")
4629    (set (attr "length")
4630         (if_then_else (eq_attr "isa" "v9")
4631                       (const_int 3) (const_int 6)))])
4633 (define_expand "udivsi3"
4634   [(set (match_operand:SI 0 "register_operand" "")
4635         (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "")
4636                  (match_operand:SI 2 "input_operand" "")))]
4637   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4638   "")
4640 ;; The V8 architecture specifies that there must be at least 3 instructions
4641 ;; between a write to the Y register and a use of it for correct results.
4642 ;; We try to fill one of them with a simple constant or a memory load.
4644 (define_insn "udivsi3_sp32"
4645   [(set (match_operand:SI 0 "register_operand" "=r,&r,&r,&r")
4646         (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r,r,r,m")
4647                  (match_operand:SI 2 "input_operand" "rI,K,m,r")))]
4648   "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4650   output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4652   switch (which_alternative)
4653     {
4654     case 0:
4655       if (TARGET_V9)
4656         return "udiv\t%1, %2, %0";
4657       else
4658         return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
4659     case 1:
4660       if (TARGET_V9)
4661         return "sethi\t%%hi(%a2), %0\n\tudiv\t%1, %0, %0";
4662       else
4663         return "sethi\t%%hi(%a2), %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4664     case 2:
4665       if (TARGET_V9)
4666         return "ld\t%2, %0\n\tudiv\t%1, %0, %0";
4667       else
4668         return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
4669     case 3:
4670       if (TARGET_V9)
4671         return "ld\t%1, %0\n\tudiv\t%0, %2, %0";
4672       else
4673         return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
4674     default:
4675       gcc_unreachable ();
4676     }
4678   [(set_attr "type" "multi")
4679    (set (attr "length")
4680         (if_then_else (eq_attr "isa" "v9")
4681                       (const_int 3) (const_int 5)))])
4683 (define_insn "udivsi3_sp64"
4684   [(set (match_operand:SI 0 "register_operand" "=r")
4685         (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r")
4686                  (match_operand:SI 2 "input_operand" "rI")))]
4687   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4688   "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
4689   [(set_attr "type" "multi")
4690    (set_attr "length" "2")])
4692 (define_insn "udivdi3"
4693   [(set (match_operand:DI 0 "register_operand" "=r")
4694         (udiv:DI (match_operand:DI 1 "register_operand" "r")
4695                  (match_operand:DI 2 "arith_operand" "rI")))]
4696   "TARGET_ARCH64"
4697   "udivx\t%1, %2, %0"
4698   [(set_attr "type" "idiv")])
4700 (define_insn "*cmp_udiv_cc_set"
4701   [(set (reg:CC CC_REG)
4702         (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
4703                              (match_operand:SI 2 "arith_operand" "rI"))
4704                     (const_int 0)))
4705    (set (match_operand:SI 0 "register_operand" "=r")
4706         (udiv:SI (match_dup 1) (match_dup 2)))]
4707   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4709   output_asm_insn ("wr\t%%g0, 0, %%y", operands);
4711   if (TARGET_V9)
4712     return "udivcc\t%1, %2, %0";
4713   else
4714     return "nop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
4716   [(set_attr "type" "multi")
4717    (set (attr "length")
4718         (if_then_else (eq_attr "isa" "v9")
4719                       (const_int 2) (const_int 5)))])
4722 ;; SPARClet multiply/accumulate insns
4724 (define_insn "*smacsi"
4725   [(set (match_operand:SI 0 "register_operand" "=r")
4726         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
4727                           (match_operand:SI 2 "arith_operand" "rI"))
4728                  (match_operand:SI 3 "register_operand" "0")))]
4729   "TARGET_SPARCLET"
4730   "smac\t%1, %2, %0"
4731   [(set_attr "type" "imul")])
4733 (define_insn "*smacdi"
4734   [(set (match_operand:DI 0 "register_operand" "=r")
4735         (plus:DI (mult:DI (sign_extend:DI
4736                            (match_operand:SI 1 "register_operand" "%r"))
4737                           (sign_extend:DI
4738                            (match_operand:SI 2 "register_operand" "r")))
4739                  (match_operand:DI 3 "register_operand" "0")))]
4740   "TARGET_SPARCLET"
4741   "smacd\t%1, %2, %L0"
4742   [(set_attr "type" "imul")])
4744 (define_insn "*umacdi"
4745   [(set (match_operand:DI 0 "register_operand" "=r")
4746         (plus:DI (mult:DI (zero_extend:DI
4747                            (match_operand:SI 1 "register_operand" "%r"))
4748                           (zero_extend:DI
4749                            (match_operand:SI 2 "register_operand" "r")))
4750                  (match_operand:DI 3 "register_operand" "0")))]
4751   "TARGET_SPARCLET"
4752   "umacd\t%1, %2, %L0"
4753   [(set_attr "type" "imul")])
4756 ;; Boolean instructions.
4758 (define_insn "anddi3"
4759   [(set (match_operand:DI 0 "register_operand" "=r")
4760         (and:DI (match_operand:DI 1 "arith_operand" "%r")
4761                 (match_operand:DI 2 "arith_operand" "rI")))]
4762   "TARGET_ARCH64"
4763   "and\t%1, %2, %0")
4765 (define_insn "andsi3"
4766   [(set (match_operand:SI 0 "register_operand" "=r")
4767         (and:SI (match_operand:SI 1 "arith_operand" "%r")
4768                 (match_operand:SI 2 "arith_operand" "rI")))]
4769   ""
4770   "and\t%1, %2, %0")
4772 (define_split
4773   [(set (match_operand:SI 0 "register_operand" "")
4774         (and:SI (match_operand:SI 1 "register_operand" "")
4775                 (match_operand:SI 2 "const_compl_high_operand" "")))
4776    (clobber (match_operand:SI 3 "register_operand" ""))]
4777   ""
4778   [(set (match_dup 3) (match_dup 4))
4779    (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
4781   operands[4] = GEN_INT (~INTVAL (operands[2]));
4784 (define_insn "*and_not_di_sp64"
4785   [(set (match_operand:DI 0 "register_operand" "=r")
4786         (and:DI (not:DI (match_operand:DI 1 "register_operand" "%r"))
4787                 (match_operand:DI 2 "register_operand" "r")))]
4788   "TARGET_ARCH64"
4789   "andn\t%2, %1, %0")
4791 (define_insn "*and_not_si"
4792   [(set (match_operand:SI 0 "register_operand" "=r")
4793         (and:SI (not:SI (match_operand:SI 1 "register_operand" "%r"))
4794                 (match_operand:SI 2 "register_operand" "r")))]
4795   ""
4796   "andn\t%2, %1, %0")
4798 (define_insn "iordi3"
4799   [(set (match_operand:DI 0 "register_operand" "=r")
4800         (ior:DI (match_operand:DI 1 "arith_operand" "%r")
4801                 (match_operand:DI 2 "arith_operand" "rI")))]
4802   "TARGET_ARCH64"
4803   "or\t%1, %2, %0")
4805 (define_insn "iorsi3"
4806   [(set (match_operand:SI 0 "register_operand" "=r")
4807         (ior:SI (match_operand:SI 1 "arith_operand" "%r")
4808                 (match_operand:SI 2 "arith_operand" "rI")))]
4809   ""
4810   "or\t%1, %2, %0")
4812 (define_split
4813   [(set (match_operand:SI 0 "register_operand" "")
4814         (ior:SI (match_operand:SI 1 "register_operand" "")
4815                 (match_operand:SI 2 "const_compl_high_operand" "")))
4816    (clobber (match_operand:SI 3 "register_operand" ""))]
4817   ""
4818   [(set (match_dup 3) (match_dup 4))
4819    (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
4821   operands[4] = gen_int_mode (~INTVAL (operands[2]), SImode);
4824 (define_insn "*or_not_di_sp64"
4825   [(set (match_operand:DI 0 "register_operand" "=r")
4826         (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
4827                 (match_operand:DI 2 "register_operand" "r")))]
4828   "TARGET_ARCH64"
4829   "orn\t%2, %1, %0")
4831 (define_insn "*or_not_si"
4832   [(set (match_operand:SI 0 "register_operand" "=r")
4833         (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
4834                 (match_operand:SI 2 "register_operand" "r")))]
4835   ""
4836   "orn\t%2, %1, %0")
4838 (define_insn "xordi3"
4839   [(set (match_operand:DI 0 "register_operand" "=r")
4840         (xor:DI (match_operand:DI 1 "arith_operand" "%rJ")
4841                 (match_operand:DI 2 "arith_operand" "rI")))]
4842   "TARGET_ARCH64"
4843   "xor\t%r1, %2, %0")
4845 (define_insn "xorsi3"
4846   [(set (match_operand:SI 0 "register_operand" "=r")
4847         (xor:SI (match_operand:SI 1 "arith_operand" "%rJ")
4848                   (match_operand:SI 2 "arith_operand" "rI")))]
4849   ""
4850   "xor\t%r1, %2, %0")
4852 (define_split
4853   [(set (match_operand:SI 0 "register_operand" "")
4854         (xor:SI (match_operand:SI 1 "register_operand" "")
4855                 (match_operand:SI 2 "const_compl_high_operand" "")))
4856    (clobber (match_operand:SI 3 "register_operand" ""))]
4857    ""
4858   [(set (match_dup 3) (match_dup 4))
4859    (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
4861   operands[4] = gen_int_mode (~INTVAL (operands[2]), SImode);
4864 (define_split
4865   [(set (match_operand:SI 0 "register_operand" "")
4866         (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
4867                         (match_operand:SI 2 "const_compl_high_operand" ""))))
4868    (clobber (match_operand:SI 3 "register_operand" ""))]
4869   ""
4870   [(set (match_dup 3) (match_dup 4))
4871    (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
4873   operands[4] = gen_int_mode (~INTVAL (operands[2]), SImode);
4876 (define_insn "*xor_not_di_sp64"
4877   [(set (match_operand:DI 0 "register_operand" "=r")
4878         (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
4879                         (match_operand:DI 2 "arith_operand" "rI"))))]
4880   "TARGET_ARCH64"
4881   "xnor\t%r1, %2, %0")
4883 (define_insn "*xor_not_si"
4884   [(set (match_operand:SI 0 "register_operand" "=r")
4885         (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4886                         (match_operand:SI 2 "arith_operand" "rI"))))]
4887   ""
4888   "xnor\t%r1, %2, %0")
4890 ;; These correspond to the above in the case where we also (or only)
4891 ;; want to set the condition code.  
4893 (define_insn "*cmp_cc_arith_op"
4894   [(set (reg:CC CC_REG)
4895         (compare:CC
4896          (match_operator:SI 2 "cc_arith_operator"
4897                             [(match_operand:SI 0 "arith_operand" "%r")
4898                              (match_operand:SI 1 "arith_operand" "rI")])
4899          (const_int 0)))]
4900   ""
4901   "%A2cc\t%0, %1, %%g0"
4902   [(set_attr "type" "compare")])
4904 (define_insn "*cmp_ccx_arith_op"
4905   [(set (reg:CCX CC_REG)
4906         (compare:CCX
4907          (match_operator:DI 2 "cc_arith_operator"
4908                             [(match_operand:DI 0 "arith_operand" "%r")
4909                              (match_operand:DI 1 "arith_operand" "rI")])
4910          (const_int 0)))]
4911   "TARGET_ARCH64"
4912   "%A2cc\t%0, %1, %%g0"
4913   [(set_attr "type" "compare")])
4915 (define_insn "*cmp_cc_arith_op_set"
4916   [(set (reg:CC CC_REG)
4917         (compare:CC
4918          (match_operator:SI 3 "cc_arith_operator"
4919                             [(match_operand:SI 1 "arith_operand" "%r")
4920                              (match_operand:SI 2 "arith_operand" "rI")])
4921          (const_int 0)))
4922    (set (match_operand:SI 0 "register_operand" "=r")
4923         (match_operator:SI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
4924   "GET_CODE (operands[3]) == GET_CODE (operands[4])"
4925   "%A3cc\t%1, %2, %0"
4926   [(set_attr "type" "compare")])
4928 (define_insn "*cmp_ccx_arith_op_set"
4929   [(set (reg:CCX CC_REG)
4930         (compare:CCX
4931          (match_operator:DI 3 "cc_arith_operator"
4932                             [(match_operand:DI 1 "arith_operand" "%r")
4933                              (match_operand:DI 2 "arith_operand" "rI")])
4934          (const_int 0)))
4935    (set (match_operand:DI 0 "register_operand" "=r")
4936         (match_operator:DI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
4937   "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
4938   "%A3cc\t%1, %2, %0"
4939   [(set_attr "type" "compare")])
4941 (define_insn "*cmp_cc_xor_not"
4942   [(set (reg:CC CC_REG)
4943         (compare:CC
4944          (not:SI (xor:SI (match_operand:SI 0 "register_or_zero_operand" "%rJ")
4945                          (match_operand:SI 1 "arith_operand" "rI")))
4946          (const_int 0)))]
4947   ""
4948   "xnorcc\t%r0, %1, %%g0"
4949   [(set_attr "type" "compare")])
4951 (define_insn "*cmp_ccx_xor_not"
4952   [(set (reg:CCX CC_REG)
4953         (compare:CCX
4954          (not:DI (xor:DI (match_operand:DI 0 "register_or_zero_operand" "%rJ")
4955                          (match_operand:DI 1 "arith_operand" "rI")))
4956          (const_int 0)))]
4957   "TARGET_ARCH64"
4958   "xnorcc\t%r0, %1, %%g0"
4959   [(set_attr "type" "compare")])
4961 (define_insn "*cmp_cc_xor_not_set"
4962   [(set (reg:CC CC_REG)
4963         (compare:CC
4964          (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
4965                          (match_operand:SI 2 "arith_operand" "rI")))
4966          (const_int 0)))
4967    (set (match_operand:SI 0 "register_operand" "=r")
4968         (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
4969   ""
4970   "xnorcc\t%r1, %2, %0"
4971   [(set_attr "type" "compare")])
4973 (define_insn "*cmp_ccx_xor_not_set"
4974   [(set (reg:CCX CC_REG)
4975         (compare:CCX
4976          (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
4977                          (match_operand:DI 2 "arith_operand" "rI")))
4978          (const_int 0)))
4979    (set (match_operand:DI 0 "register_operand" "=r")
4980         (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
4981   "TARGET_ARCH64"
4982   "xnorcc\t%r1, %2, %0"
4983   [(set_attr "type" "compare")])
4985 (define_insn "*cmp_cc_arith_op_not"
4986   [(set (reg:CC CC_REG)
4987         (compare:CC
4988          (match_operator:SI 2 "cc_arith_not_operator"
4989                             [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
4990                              (match_operand:SI 1 "register_or_zero_operand" "rJ")])
4991          (const_int 0)))]
4992   ""
4993   "%B2cc\t%r1, %0, %%g0"
4994   [(set_attr "type" "compare")])
4996 (define_insn "*cmp_ccx_arith_op_not"
4997   [(set (reg:CCX CC_REG)
4998         (compare:CCX
4999          (match_operator:DI 2 "cc_arith_not_operator"
5000                             [(not:DI (match_operand:DI 0 "arith_operand" "rI"))
5001                              (match_operand:DI 1 "register_or_zero_operand" "rJ")])
5002          (const_int 0)))]
5003   "TARGET_ARCH64"
5004   "%B2cc\t%r1, %0, %%g0"
5005   [(set_attr "type" "compare")])
5007 (define_insn "*cmp_cc_arith_op_not_set"
5008   [(set (reg:CC CC_REG)
5009         (compare:CC
5010          (match_operator:SI 3 "cc_arith_not_operator"
5011                             [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
5012                              (match_operand:SI 2 "register_or_zero_operand" "rJ")])
5013          (const_int 0)))
5014    (set (match_operand:SI 0 "register_operand" "=r")
5015         (match_operator:SI 4 "cc_arith_not_operator"
5016                             [(not:SI (match_dup 1)) (match_dup 2)]))]
5017   "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5018   "%B3cc\t%r2, %1, %0"
5019   [(set_attr "type" "compare")])
5021 (define_insn "*cmp_ccx_arith_op_not_set"
5022   [(set (reg:CCX CC_REG)
5023         (compare:CCX
5024          (match_operator:DI 3 "cc_arith_not_operator"
5025                             [(not:DI (match_operand:DI 1 "arith_operand" "rI"))
5026                              (match_operand:DI 2 "register_or_zero_operand" "rJ")])
5027          (const_int 0)))
5028    (set (match_operand:DI 0 "register_operand" "=r")
5029         (match_operator:DI 4 "cc_arith_not_operator"
5030                             [(not:DI (match_dup 1)) (match_dup 2)]))]
5031   "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5032   "%B3cc\t%r2, %1, %0"
5033   [(set_attr "type" "compare")])
5035 ;; We cannot use the "neg" pseudo insn because the Sun assembler
5036 ;; does not know how to make it work for constants.
5038 (define_expand "negdi2"
5039   [(set (match_operand:DI 0 "register_operand" "=r")
5040         (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5041   ""
5043   if (! TARGET_ARCH64)
5044     {
5045       emit_insn (gen_rtx_PARALLEL
5046                  (VOIDmode,
5047                   gen_rtvec (2,
5048                              gen_rtx_SET (operand0,
5049                                           gen_rtx_NEG (DImode, operand1)),
5050                              gen_rtx_CLOBBER (VOIDmode,
5051                                               gen_rtx_REG (CCmode,
5052                                                            SPARC_ICC_REG)))));
5053       DONE;
5054     }
5057 (define_insn_and_split "*negdi2_sp32"
5058   [(set (match_operand:DI 0 "register_operand" "=&r")
5059         (neg:DI (match_operand:DI 1 "register_operand" "r")))
5060    (clobber (reg:CC CC_REG))]
5061   "! TARGET_ARCH64"
5062   "#"
5063   "&& reload_completed"
5064   [(parallel [(set (reg:CC_NOOV CC_REG)
5065                    (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
5066                                     (const_int 0)))
5067               (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
5068    (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
5069                                 (ltu:SI (reg:CC CC_REG) (const_int 0))))]
5070   "operands[2] = gen_highpart (SImode, operands[0]);
5071    operands[3] = gen_highpart (SImode, operands[1]);
5072    operands[4] = gen_lowpart (SImode, operands[0]);
5073    operands[5] = gen_lowpart (SImode, operands[1]);"
5074   [(set_attr "length" "2")])
5076 (define_insn "*negdi2_sp64"
5077   [(set (match_operand:DI 0 "register_operand" "=r")
5078         (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5079   "TARGET_ARCH64"
5080   "sub\t%%g0, %1, %0")
5082 (define_insn "negsi2"
5083   [(set (match_operand:SI 0 "register_operand" "=r")
5084         (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
5085   ""
5086   "sub\t%%g0, %1, %0")
5088 (define_insn "*cmp_cc_neg"
5089   [(set (reg:CC_NOOV CC_REG)
5090         (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
5091                          (const_int 0)))]
5092   ""
5093   "subcc\t%%g0, %0, %%g0"
5094   [(set_attr "type" "compare")])
5096 (define_insn "*cmp_ccx_neg"
5097   [(set (reg:CCX_NOOV CC_REG)
5098         (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_operand" "rI"))
5099                           (const_int 0)))]
5100   "TARGET_ARCH64"
5101   "subcc\t%%g0, %0, %%g0"
5102   [(set_attr "type" "compare")])
5104 (define_insn "*cmp_cc_set_neg"
5105   [(set (reg:CC_NOOV CC_REG)
5106         (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
5107                          (const_int 0)))
5108    (set (match_operand:SI 0 "register_operand" "=r")
5109         (neg:SI (match_dup 1)))]
5110   ""
5111   "subcc\t%%g0, %1, %0"
5112   [(set_attr "type" "compare")])
5114 (define_insn "*cmp_ccx_set_neg"
5115   [(set (reg:CCX_NOOV CC_REG)
5116         (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_operand" "rI"))
5117                           (const_int 0)))
5118    (set (match_operand:DI 0 "register_operand" "=r")
5119         (neg:DI (match_dup 1)))]
5120   "TARGET_ARCH64"
5121   "subcc\t%%g0, %1, %0"
5122   [(set_attr "type" "compare")])
5124 (define_insn "one_cmpldi2"
5125   [(set (match_operand:DI 0 "register_operand" "=r")
5126         (not:DI (match_operand:DI 1 "arith_operand" "rI")))]
5127   "TARGET_ARCH64"
5128   "xnor\t%%g0, %1, %0")
5130 (define_insn "one_cmplsi2"
5131   [(set (match_operand:SI 0 "register_operand" "=r")
5132         (not:SI (match_operand:SI 1 "arith_operand" "rI")))]
5133   ""
5134   "xnor\t%%g0, %1, %0")
5136 (define_insn "*cmp_cc_not"
5137   [(set (reg:CC CC_REG)
5138         (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
5139                     (const_int 0)))]
5140   ""
5141   "xnorcc\t%%g0, %0, %%g0"
5142   [(set_attr "type" "compare")])
5144 (define_insn "*cmp_ccx_not"
5145   [(set (reg:CCX CC_REG)
5146         (compare:CCX (not:DI (match_operand:DI 0 "arith_operand" "rI"))
5147                      (const_int 0)))]
5148   "TARGET_ARCH64"
5149   "xnorcc\t%%g0, %0, %%g0"
5150   [(set_attr "type" "compare")])
5152 (define_insn "*cmp_cc_set_not"
5153   [(set (reg:CC CC_REG)
5154         (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
5155                     (const_int 0)))
5156    (set (match_operand:SI 0 "register_operand" "=r")
5157         (not:SI (match_dup 1)))]
5158   ""
5159   "xnorcc\t%%g0, %1, %0"
5160   [(set_attr "type" "compare")])
5162 (define_insn "*cmp_ccx_set_not"
5163   [(set (reg:CCX CC_REG)
5164         (compare:CCX (not:DI (match_operand:DI 1 "arith_operand" "rI"))
5165                     (const_int 0)))
5166    (set (match_operand:DI 0 "register_operand" "=r")
5167         (not:DI (match_dup 1)))]
5168   "TARGET_ARCH64"
5169   "xnorcc\t%%g0, %1, %0"
5170   [(set_attr "type" "compare")])
5172 (define_insn "*cmp_cc_set"
5173   [(set (match_operand:SI 0 "register_operand" "=r")
5174         (match_operand:SI 1 "register_operand" "r"))
5175    (set (reg:CC CC_REG)
5176         (compare:CC (match_dup 1)
5177                     (const_int 0)))]
5178   ""
5179   "orcc\t%1, 0, %0"
5180   [(set_attr "type" "compare")])
5182 (define_insn "*cmp_ccx_set64"
5183   [(set (match_operand:DI 0 "register_operand" "=r")
5184         (match_operand:DI 1 "register_operand" "r"))
5185    (set (reg:CCX CC_REG)
5186         (compare:CCX (match_dup 1)
5187                      (const_int 0)))]
5188   "TARGET_ARCH64"
5189   "orcc\t%1, 0, %0"
5190    [(set_attr "type" "compare")])
5193 ;; Floating point arithmetic instructions.
5195 (define_expand "addtf3"
5196   [(set (match_operand:TF 0 "nonimmediate_operand" "")
5197         (plus:TF (match_operand:TF 1 "general_operand" "")
5198                  (match_operand:TF 2 "general_operand" "")))]
5199   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5200   "emit_tfmode_binop (PLUS, operands); DONE;")
5202 (define_insn "*addtf3_hq"
5203   [(set (match_operand:TF 0 "register_operand" "=e")
5204         (plus:TF (match_operand:TF 1 "register_operand" "e")
5205                  (match_operand:TF 2 "register_operand" "e")))]
5206   "TARGET_FPU && TARGET_HARD_QUAD"
5207   "faddq\t%1, %2, %0"
5208   [(set_attr "type" "fp")])
5210 (define_insn "adddf3"
5211   [(set (match_operand:DF 0 "register_operand" "=e")
5212         (plus:DF (match_operand:DF 1 "register_operand" "e")
5213                  (match_operand:DF 2 "register_operand" "e")))]
5214   "TARGET_FPU"
5215   "faddd\t%1, %2, %0"
5216   [(set_attr "type" "fp")
5217    (set_attr "fptype" "double")])
5219 (define_insn "addsf3"
5220   [(set (match_operand:SF 0 "register_operand" "=f")
5221         (plus:SF (match_operand:SF 1 "register_operand" "f")
5222                  (match_operand:SF 2 "register_operand" "f")))]
5223   "TARGET_FPU"
5224   "fadds\t%1, %2, %0"
5225   [(set_attr "type" "fp")])
5227 (define_expand "subtf3"
5228   [(set (match_operand:TF 0 "nonimmediate_operand" "")
5229         (minus:TF (match_operand:TF 1 "general_operand" "")
5230                   (match_operand:TF 2 "general_operand" "")))]
5231   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5232   "emit_tfmode_binop (MINUS, operands); DONE;")
5234 (define_insn "*subtf3_hq"
5235   [(set (match_operand:TF 0 "register_operand" "=e")
5236         (minus:TF (match_operand:TF 1 "register_operand" "e")
5237                   (match_operand:TF 2 "register_operand" "e")))]
5238   "TARGET_FPU && TARGET_HARD_QUAD"
5239   "fsubq\t%1, %2, %0"
5240   [(set_attr "type" "fp")])
5242 (define_insn "subdf3"
5243   [(set (match_operand:DF 0 "register_operand" "=e")
5244         (minus:DF (match_operand:DF 1 "register_operand" "e")
5245                   (match_operand:DF 2 "register_operand" "e")))]
5246   "TARGET_FPU"
5247   "fsubd\t%1, %2, %0"
5248   [(set_attr "type" "fp")
5249    (set_attr "fptype" "double")])
5251 (define_insn "subsf3"
5252   [(set (match_operand:SF 0 "register_operand" "=f")
5253         (minus:SF (match_operand:SF 1 "register_operand" "f")
5254                   (match_operand:SF 2 "register_operand" "f")))]
5255   "TARGET_FPU"
5256   "fsubs\t%1, %2, %0"
5257   [(set_attr "type" "fp")])
5259 (define_expand "multf3"
5260   [(set (match_operand:TF 0 "nonimmediate_operand" "")
5261         (mult:TF (match_operand:TF 1 "general_operand" "")
5262                  (match_operand:TF 2 "general_operand" "")))]
5263   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5264   "emit_tfmode_binop (MULT, operands); DONE;")
5266 (define_insn "*multf3_hq"
5267   [(set (match_operand:TF 0 "register_operand" "=e")
5268         (mult:TF (match_operand:TF 1 "register_operand" "e")
5269                  (match_operand:TF 2 "register_operand" "e")))]
5270   "TARGET_FPU && TARGET_HARD_QUAD"
5271   "fmulq\t%1, %2, %0"
5272   [(set_attr "type" "fpmul")])
5274 (define_insn "muldf3"
5275   [(set (match_operand:DF 0 "register_operand" "=e")
5276         (mult:DF (match_operand:DF 1 "register_operand" "e")
5277                  (match_operand:DF 2 "register_operand" "e")))]
5278   "TARGET_FPU"
5279   "fmuld\t%1, %2, %0"
5280   [(set_attr "type" "fpmul")
5281    (set_attr "fptype" "double")])
5283 (define_insn "mulsf3"
5284   [(set (match_operand:SF 0 "register_operand" "=f")
5285         (mult:SF (match_operand:SF 1 "register_operand" "f")
5286                  (match_operand:SF 2 "register_operand" "f")))]
5287   "TARGET_FPU"
5288   "fmuls\t%1, %2, %0"
5289   [(set_attr "type" "fpmul")])
5291 (define_insn "fmadf4"
5292   [(set (match_operand:DF 0 "register_operand" "=e")
5293         (fma:DF (match_operand:DF 1 "register_operand" "e")
5294                 (match_operand:DF 2 "register_operand" "e")
5295                 (match_operand:DF 3 "register_operand" "e")))]
5296   "TARGET_FMAF"
5297   "fmaddd\t%1, %2, %3, %0"
5298   [(set_attr "type" "fpmul")])
5300 (define_insn "fmsdf4"
5301   [(set (match_operand:DF 0 "register_operand" "=e")
5302         (fma:DF (match_operand:DF 1 "register_operand" "e")
5303                 (match_operand:DF 2 "register_operand" "e")
5304                 (neg:DF (match_operand:DF 3 "register_operand" "e"))))]
5305   "TARGET_FMAF"
5306   "fmsubd\t%1, %2, %3, %0"
5307   [(set_attr "type" "fpmul")])
5309 (define_insn "*nfmadf4"
5310   [(set (match_operand:DF 0 "register_operand" "=e")
5311         (neg:DF (fma:DF (match_operand:DF 1 "register_operand" "e")
5312                         (match_operand:DF 2 "register_operand" "e")
5313                         (match_operand:DF 3 "register_operand" "e"))))]
5314   "TARGET_FMAF"
5315   "fnmaddd\t%1, %2, %3, %0"
5316   [(set_attr "type" "fpmul")])
5318 (define_insn "*nfmsdf4"
5319   [(set (match_operand:DF 0 "register_operand" "=e")
5320         (neg:DF (fma:DF (match_operand:DF 1 "register_operand" "e")
5321                         (match_operand:DF 2 "register_operand" "e")
5322                         (neg:DF (match_operand:DF 3 "register_operand" "e")))))]
5323   "TARGET_FMAF"
5324   "fnmsubd\t%1, %2, %3, %0"
5325   [(set_attr "type" "fpmul")])
5327 (define_insn "fmasf4"
5328   [(set (match_operand:SF 0 "register_operand" "=f")
5329         (fma:SF (match_operand:SF 1 "register_operand" "f")
5330                 (match_operand:SF 2 "register_operand" "f")
5331                 (match_operand:SF 3 "register_operand" "f")))]
5332   "TARGET_FMAF"
5333   "fmadds\t%1, %2, %3, %0"
5334   [(set_attr "type" "fpmul")])
5336 (define_insn "fmssf4"
5337   [(set (match_operand:SF 0 "register_operand" "=f")
5338         (fma:SF (match_operand:SF 1 "register_operand" "f")
5339                 (match_operand:SF 2 "register_operand" "f")
5340                 (neg:SF (match_operand:SF 3 "register_operand" "f"))))]
5341   "TARGET_FMAF"
5342   "fmsubs\t%1, %2, %3, %0"
5343   [(set_attr "type" "fpmul")])
5345 (define_insn "*nfmasf4"
5346   [(set (match_operand:SF 0 "register_operand" "=f")
5347         (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "f")
5348                         (match_operand:SF 2 "register_operand" "f")
5349                         (match_operand:SF 3 "register_operand" "f"))))]
5350   "TARGET_FMAF"
5351   "fnmadds\t%1, %2, %3, %0"
5352   [(set_attr "type" "fpmul")])
5354 (define_insn "*nfmssf4"
5355   [(set (match_operand:SF 0 "register_operand" "=f")
5356         (neg:SF (fma:SF (match_operand:SF 1 "register_operand" "f")
5357                         (match_operand:SF 2 "register_operand" "f")
5358                         (neg:SF (match_operand:SF 3 "register_operand" "f")))))]
5359   "TARGET_FMAF"
5360   "fnmsubs\t%1, %2, %3, %0"
5361   [(set_attr "type" "fpmul")])
5363 (define_insn "*muldf3_extend"
5364   [(set (match_operand:DF 0 "register_operand" "=e")
5365         (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
5366                  (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
5367   "(TARGET_V8 || TARGET_V9) && TARGET_FPU && !sparc_fix_ut699"
5368   "fsmuld\t%1, %2, %0"
5369   [(set_attr "type" "fpmul")
5370    (set_attr "fptype" "double")])
5372 (define_insn "*multf3_extend"
5373   [(set (match_operand:TF 0 "register_operand" "=e")
5374         (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
5375                  (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
5376   "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
5377   "fdmulq\t%1, %2, %0"
5378   [(set_attr "type" "fpmul")])
5380 (define_expand "divtf3"
5381   [(set (match_operand:TF 0 "nonimmediate_operand" "")
5382         (div:TF (match_operand:TF 1 "general_operand" "")
5383                 (match_operand:TF 2 "general_operand" "")))]
5384   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5385   "emit_tfmode_binop (DIV, operands); DONE;")
5387 ;; don't have timing for quad-prec. divide.
5388 (define_insn "*divtf3_hq"
5389   [(set (match_operand:TF 0 "register_operand" "=e")
5390         (div:TF (match_operand:TF 1 "register_operand" "e")
5391                 (match_operand:TF 2 "register_operand" "e")))]
5392   "TARGET_FPU && TARGET_HARD_QUAD"
5393   "fdivq\t%1, %2, %0"
5394   [(set_attr "type" "fpdivs")])
5396 (define_expand "divdf3"
5397   [(set (match_operand:DF 0 "register_operand" "=e")
5398         (div:DF (match_operand:DF 1 "register_operand" "e")
5399                 (match_operand:DF 2 "register_operand" "e")))]
5400   "TARGET_FPU"
5401   "")
5403 (define_insn "*divdf3_nofix"
5404   [(set (match_operand:DF 0 "register_operand" "=e")
5405         (div:DF (match_operand:DF 1 "register_operand" "e")
5406                 (match_operand:DF 2 "register_operand" "e")))]
5407   "TARGET_FPU && !sparc_fix_ut699"
5408   "fdivd\t%1, %2, %0"
5409   [(set_attr "type" "fpdivd")
5410    (set_attr "fptype" "double")])
5412 (define_insn "*divdf3_fix"
5413   [(set (match_operand:DF 0 "register_operand" "=e")
5414         (div:DF (match_operand:DF 1 "register_operand" "e")
5415                 (match_operand:DF 2 "register_operand" "e")))]
5416   "TARGET_FPU && sparc_fix_ut699"
5417   "fdivd\t%1, %2, %0\n\tstd\t%0, [%%sp-8]"
5418   [(set_attr "type" "fpdivd")
5419    (set_attr "fptype" "double")
5420    (set_attr "length" "2")])
5422 (define_insn "divsf3"
5423   [(set (match_operand:SF 0 "register_operand" "=f")
5424         (div:SF (match_operand:SF 1 "register_operand" "f")
5425                 (match_operand:SF 2 "register_operand" "f")))]
5426   "TARGET_FPU && !sparc_fix_ut699"
5427   "fdivs\t%1, %2, %0"
5428   [(set_attr "type" "fpdivs")])
5430 (define_expand "negtf2"
5431   [(set (match_operand:TF 0 "register_operand" "")
5432         (neg:TF (match_operand:TF 1 "register_operand" "")))]
5433   "TARGET_FPU"
5434   "")
5436 (define_insn "*negtf2_hq"
5437   [(set (match_operand:TF 0 "register_operand" "=e")
5438         (neg:TF (match_operand:TF 1 "register_operand" "e")))]
5439   "TARGET_FPU && TARGET_HARD_QUAD"
5440   "fnegq\t%1, %0"
5441   [(set_attr "type" "fpmove")])
5443 (define_insn_and_split "*negtf2"
5444   [(set (match_operand:TF 0 "register_operand" "=e")
5445         (neg:TF (match_operand:TF 1 "register_operand" "e")))]
5446   "TARGET_FPU && !TARGET_HARD_QUAD"
5447   "#"
5448   "&& reload_completed"
5449   [(clobber (const_int 0))]
5451   rtx set_dest = operands[0];
5452   rtx set_src = operands[1];
5453   rtx dest1, dest2;
5454   rtx src1, src2;
5456   dest1 = gen_df_reg (set_dest, 0);
5457   dest2 = gen_df_reg (set_dest, 1);
5458   src1 = gen_df_reg (set_src, 0);
5459   src2 = gen_df_reg (set_src, 1);
5461   /* Now emit using the real source and destination we found, swapping
5462      the order if we detect overlap.  */
5463   if (reg_overlap_mentioned_p (dest1, src2))
5464     {
5465       emit_insn (gen_movdf (dest2, src2));
5466       emit_insn (gen_negdf2 (dest1, src1));
5467     }
5468   else
5469     {
5470       emit_insn (gen_negdf2 (dest1, src1));
5471       if (REGNO (dest2) != REGNO (src2))
5472         emit_insn (gen_movdf (dest2, src2));
5473     }
5474   DONE;
5476   [(set_attr "length" "2")])
5478 (define_expand "negdf2"
5479   [(set (match_operand:DF 0 "register_operand" "")
5480         (neg:DF (match_operand:DF 1 "register_operand" "")))]
5481   "TARGET_FPU"
5482   "")
5484 (define_insn_and_split "*negdf2_notv9"
5485   [(set (match_operand:DF 0 "register_operand" "=e")
5486         (neg:DF (match_operand:DF 1 "register_operand" "e")))]
5487   "TARGET_FPU && !TARGET_V9"
5488   "#"
5489   "&& reload_completed"
5490   [(clobber (const_int 0))]
5492   rtx set_dest = operands[0];
5493   rtx set_src = operands[1];
5494   rtx dest1, dest2;
5495   rtx src1, src2;
5497   dest1 = gen_highpart (SFmode, set_dest);
5498   dest2 = gen_lowpart (SFmode, set_dest);
5499   src1 = gen_highpart (SFmode, set_src);
5500   src2 = gen_lowpart (SFmode, set_src);
5502   /* Now emit using the real source and destination we found, swapping
5503      the order if we detect overlap.  */
5504   if (reg_overlap_mentioned_p (dest1, src2))
5505     {
5506       emit_insn (gen_movsf (dest2, src2));
5507       emit_insn (gen_negsf2 (dest1, src1));
5508     }
5509   else
5510     {
5511       emit_insn (gen_negsf2 (dest1, src1));
5512       if (REGNO (dest2) != REGNO (src2))
5513         emit_insn (gen_movsf (dest2, src2));
5514     }
5515   DONE;
5517   [(set_attr "length" "2")])
5519 (define_insn "*negdf2_v9"
5520   [(set (match_operand:DF 0 "register_operand" "=e")
5521         (neg:DF (match_operand:DF 1 "register_operand" "e")))]
5522   "TARGET_FPU && TARGET_V9"
5523   "fnegd\t%1, %0"
5524   [(set_attr "type" "fpmove")
5525    (set_attr "fptype" "double")])
5527 (define_insn "negsf2"
5528   [(set (match_operand:SF 0 "register_operand" "=f")
5529         (neg:SF (match_operand:SF 1 "register_operand" "f")))]
5530   "TARGET_FPU"
5531   "fnegs\t%1, %0"
5532   [(set_attr "type" "fpmove")])
5534 (define_expand "abstf2"
5535   [(set (match_operand:TF 0 "register_operand" "")
5536         (abs:TF (match_operand:TF 1 "register_operand" "")))]
5537   "TARGET_FPU"
5538   "")
5540 (define_insn "*abstf2_hq"
5541   [(set (match_operand:TF 0 "register_operand" "=e")
5542         (abs:TF (match_operand:TF 1 "register_operand" "e")))]
5543   "TARGET_FPU && TARGET_HARD_QUAD"
5544   "fabsq\t%1, %0"
5545   [(set_attr "type" "fpmove")])
5547 (define_insn_and_split "*abstf2"
5548   [(set (match_operand:TF 0 "register_operand" "=e")
5549         (abs:TF (match_operand:TF 1 "register_operand" "e")))]
5550   "TARGET_FPU && !TARGET_HARD_QUAD"
5551   "#"
5552   "&& reload_completed"
5553   [(clobber (const_int 0))]
5555   rtx set_dest = operands[0];
5556   rtx set_src = operands[1];
5557   rtx dest1, dest2;
5558   rtx src1, src2;
5560   dest1 = gen_df_reg (set_dest, 0);
5561   dest2 = gen_df_reg (set_dest, 1);
5562   src1 = gen_df_reg (set_src, 0);
5563   src2 = gen_df_reg (set_src, 1);
5565   /* Now emit using the real source and destination we found, swapping
5566      the order if we detect overlap.  */
5567   if (reg_overlap_mentioned_p (dest1, src2))
5568     {
5569       emit_insn (gen_movdf (dest2, src2));
5570       emit_insn (gen_absdf2 (dest1, src1));
5571     }
5572   else
5573     {
5574       emit_insn (gen_absdf2 (dest1, src1));
5575       if (REGNO (dest2) != REGNO (src2))
5576         emit_insn (gen_movdf (dest2, src2));
5577     }
5578   DONE;
5580   [(set_attr "length" "2")])
5582 (define_expand "absdf2"
5583   [(set (match_operand:DF 0 "register_operand" "")
5584         (abs:DF (match_operand:DF 1 "register_operand" "")))]
5585   "TARGET_FPU"
5586   "")
5588 (define_insn_and_split "*absdf2_notv9"
5589   [(set (match_operand:DF 0 "register_operand" "=e")
5590         (abs:DF (match_operand:DF 1 "register_operand" "e")))]
5591   "TARGET_FPU && !TARGET_V9"
5592   "#"
5593   "&& reload_completed"
5594   [(clobber (const_int 0))]
5596   rtx set_dest = operands[0];
5597   rtx set_src = operands[1];
5598   rtx dest1, dest2;
5599   rtx src1, src2;
5601   dest1 = gen_highpart (SFmode, set_dest);
5602   dest2 = gen_lowpart (SFmode, set_dest);
5603   src1 = gen_highpart (SFmode, set_src);
5604   src2 = gen_lowpart (SFmode, set_src);
5606   /* Now emit using the real source and destination we found, swapping
5607      the order if we detect overlap.  */
5608   if (reg_overlap_mentioned_p (dest1, src2))
5609     {
5610       emit_insn (gen_movsf (dest2, src2));
5611       emit_insn (gen_abssf2 (dest1, src1));
5612     }
5613   else
5614     {
5615       emit_insn (gen_abssf2 (dest1, src1));
5616       if (REGNO (dest2) != REGNO (src2))
5617         emit_insn (gen_movsf (dest2, src2));
5618     }
5619   DONE;
5621   [(set_attr "length" "2")])
5623 (define_insn "*absdf2_v9"
5624   [(set (match_operand:DF 0 "register_operand" "=e")
5625         (abs:DF (match_operand:DF 1 "register_operand" "e")))]
5626   "TARGET_FPU && TARGET_V9"
5627   "fabsd\t%1, %0"
5628   [(set_attr "type" "fpmove")
5629    (set_attr "fptype" "double")])
5631 (define_insn "abssf2"
5632   [(set (match_operand:SF 0 "register_operand" "=f")
5633         (abs:SF (match_operand:SF 1 "register_operand" "f")))]
5634   "TARGET_FPU"
5635   "fabss\t%1, %0"
5636   [(set_attr "type" "fpmove")])
5638 (define_expand "sqrttf2"
5639   [(set (match_operand:TF 0 "nonimmediate_operand" "")
5640         (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
5641   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5642   "emit_tfmode_unop (SQRT, operands); DONE;")
5644 (define_insn "*sqrttf2_hq"
5645   [(set (match_operand:TF 0 "register_operand" "=e")
5646         (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
5647   "TARGET_FPU && TARGET_HARD_QUAD"
5648   "fsqrtq\t%1, %0"
5649   [(set_attr "type" "fpsqrts")])
5651 (define_expand "sqrtdf2"
5652   [(set (match_operand:DF 0 "register_operand" "=e")
5653         (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
5654   "TARGET_FPU"
5655   "")
5657 (define_insn "*sqrtdf2_nofix"
5658   [(set (match_operand:DF 0 "register_operand" "=e")
5659         (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
5660   "TARGET_FPU && !sparc_fix_ut699"
5661   "fsqrtd\t%1, %0"
5662   [(set_attr "type" "fpsqrtd")
5663    (set_attr "fptype" "double")])
5665 (define_insn "*sqrtdf2_fix"
5666   [(set (match_operand:DF 0 "register_operand" "=e")
5667         (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
5668   "TARGET_FPU && sparc_fix_ut699"
5669   "fsqrtd\t%1, %0\n\tstd\t%0, [%%sp-8]"
5670   [(set_attr "type" "fpsqrtd")
5671    (set_attr "fptype" "double")
5672    (set_attr "length" "2")])
5674 (define_insn "sqrtsf2"
5675   [(set (match_operand:SF 0 "register_operand" "=f")
5676         (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
5677   "TARGET_FPU && !sparc_fix_ut699"
5678   "fsqrts\t%1, %0"
5679   [(set_attr "type" "fpsqrts")])
5682 ;; Arithmetic shift instructions.
5684 (define_insn "ashlsi3"
5685   [(set (match_operand:SI 0 "register_operand" "=r")
5686         (ashift:SI (match_operand:SI 1 "register_operand" "r")
5687                    (match_operand:SI 2 "arith_operand" "rI")))]
5688   ""
5690   if (GET_CODE (operands[2]) == CONST_INT)
5691     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5692   return "sll\t%1, %2, %0";
5694   [(set_attr "type" "shift")])
5696 (define_expand "ashldi3"
5697   [(set (match_operand:DI 0 "register_operand" "=r")
5698         (ashift:DI (match_operand:DI 1 "register_operand" "r")
5699                    (match_operand:SI 2 "arith_operand" "rI")))]
5700   "TARGET_ARCH64 || TARGET_V8PLUS"
5702   if (! TARGET_ARCH64)
5703     {
5704       if (GET_CODE (operands[2]) == CONST_INT)
5705         FAIL;
5706       emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
5707       DONE;
5708     }
5711 (define_insn "*ashldi3_sp64"
5712   [(set (match_operand:DI 0 "register_operand" "=r")
5713         (ashift:DI (match_operand:DI 1 "register_operand" "r")
5714                    (match_operand:SI 2 "arith_operand" "rI")))]
5715   "TARGET_ARCH64"
5717   if (GET_CODE (operands[2]) == CONST_INT)
5718     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5719   return "sllx\t%1, %2, %0";
5721   [(set_attr "type" "shift")])
5723 (define_insn "ashldi3_v8plus"
5724   [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5725         (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5726                    (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5727    (clobber (match_scratch:SI 3 "=X,X,&h"))]
5728   "TARGET_V8PLUS"
5729   "* return output_v8plus_shift (insn ,operands, \"sllx\");"
5730   [(set_attr "type" "multi")
5731    (set_attr "length" "5,5,6")])
5733 ;; Optimize (1LL<<x)-1
5734 ;; XXX this also needs to be fixed to handle equal subregs
5735 ;; XXX first before we could re-enable it.
5736 ;(define_insn ""
5737 ;  [(set (match_operand:DI 0 "register_operand" "=h")
5738 ;       (plus:DI (ashift:DI (const_int 1)
5739 ;                           (match_operand:SI 1 "arith_operand" "rI"))
5740 ;                (const_int -1)))]
5741 ;  "0 && TARGET_V8PLUS"
5743 ;  if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
5744 ;    return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5745 ;  return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
5747 ;  [(set_attr "type" "multi")
5748 ;   (set_attr "length" "4")])
5750 (define_insn "*cmp_cc_ashift_1"
5751   [(set (reg:CC_NOOV CC_REG)
5752         (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
5753                                     (const_int 1))
5754                          (const_int 0)))]
5755   ""
5756   "addcc\t%0, %0, %%g0"
5757   [(set_attr "type" "compare")])
5759 (define_insn "*cmp_cc_set_ashift_1"
5760   [(set (reg:CC_NOOV CC_REG)
5761         (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
5762                                     (const_int 1))
5763                          (const_int 0)))
5764    (set (match_operand:SI 0 "register_operand" "=r")
5765         (ashift:SI (match_dup 1) (const_int 1)))]
5766   ""
5767   "addcc\t%1, %1, %0"
5768   [(set_attr "type" "compare")])
5770 (define_insn "ashrsi3"
5771   [(set (match_operand:SI 0 "register_operand" "=r")
5772         (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5773                      (match_operand:SI 2 "arith_operand" "rI")))]
5774   ""
5775   {
5776      if (GET_CODE (operands[2]) == CONST_INT)
5777        operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5778      return "sra\t%1, %2, %0";
5779   }
5780   [(set_attr "type" "shift")])
5782 (define_insn "*ashrsi3_extend"
5783   [(set (match_operand:DI 0 "register_operand" "=r")
5784         (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
5785                                      (match_operand:SI 2 "arith_operand" "r"))))]
5786   "TARGET_ARCH64"
5787   "sra\t%1, %2, %0"
5788   [(set_attr "type" "shift")])
5790 ;; This handles the case as above, but with constant shift instead of
5791 ;; register. Combiner "simplifies" it for us a little bit though.
5792 (define_insn "*ashrsi3_extend2"
5793   [(set (match_operand:DI 0 "register_operand" "=r")
5794         (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
5795                                 (const_int 32))
5796                      (match_operand:SI 2 "small_int_operand" "I")))]
5797   "TARGET_ARCH64 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64"
5799   operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
5800   return "sra\t%1, %2, %0";
5802   [(set_attr "type" "shift")])
5804 (define_expand "ashrdi3"
5805   [(set (match_operand:DI 0 "register_operand" "=r")
5806         (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5807                      (match_operand:SI 2 "arith_operand" "rI")))]
5808   "TARGET_ARCH64 || TARGET_V8PLUS"
5810   if (! TARGET_ARCH64)
5811     {
5812       if (GET_CODE (operands[2]) == CONST_INT)
5813         FAIL;   /* prefer generic code in this case */
5814       emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
5815       DONE;
5816     }
5819 (define_insn "*ashrdi3_sp64"
5820   [(set (match_operand:DI 0 "register_operand" "=r")
5821         (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5822                      (match_operand:SI 2 "arith_operand" "rI")))]
5823   "TARGET_ARCH64"
5824   
5825   {
5826     if (GET_CODE (operands[2]) == CONST_INT)
5827       operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5828     return "srax\t%1, %2, %0";
5829   }
5830   [(set_attr "type" "shift")])
5832 (define_insn "ashrdi3_v8plus"
5833   [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5834         (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5835                      (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5836    (clobber (match_scratch:SI 3 "=X,X,&h"))]
5837   "TARGET_V8PLUS"
5838   "* return output_v8plus_shift (insn, operands, \"srax\");"
5839   [(set_attr "type" "multi")
5840    (set_attr "length" "5,5,6")])
5842 (define_insn "lshrsi3"
5843   [(set (match_operand:SI 0 "register_operand" "=r")
5844         (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5845                      (match_operand:SI 2 "arith_operand" "rI")))]
5846   ""
5847   {
5848     if (GET_CODE (operands[2]) == CONST_INT)
5849       operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5850     return "srl\t%1, %2, %0";
5851   }
5852   [(set_attr "type" "shift")])
5854 (define_insn "*lshrsi3_extend0"
5855   [(set (match_operand:DI 0 "register_operand" "=r")
5856         (zero_extend:DI
5857           (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5858                        (match_operand:SI 2 "arith_operand" "rI"))))]
5859   "TARGET_ARCH64"
5860   {
5861     if (GET_CODE (operands[2]) == CONST_INT)
5862       operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
5863     return "srl\t%1, %2, %0";
5864   }
5865   [(set_attr "type" "shift")])
5867 ;; This handles the case where
5868 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
5869 ;; but combiner "simplifies" it for us.
5870 (define_insn "*lshrsi3_extend1"
5871   [(set (match_operand:DI 0 "register_operand" "=r")
5872         (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
5873                            (match_operand:SI 2 "arith_operand" "r")) 0)
5874                 (match_operand 3 "const_int_operand" "")))]
5875   "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff"
5876   "srl\t%1, %2, %0"
5877   [(set_attr "type" "shift")])
5879 ;; This handles the case where
5880 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
5881 ;; but combiner "simplifies" it for us.
5882 (define_insn "*lshrsi3_extend2"
5883   [(set (match_operand:DI 0 "register_operand" "=r")
5884         (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
5885                          (match_operand 2 "small_int_operand" "I")
5886                          (const_int 32)))]
5887   "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
5889   operands[2] = GEN_INT (32 - INTVAL (operands[2]));
5890   return "srl\t%1, %2, %0";
5892   [(set_attr "type" "shift")])
5894 (define_expand "lshrdi3"
5895   [(set (match_operand:DI 0 "register_operand" "=r")
5896         (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5897                      (match_operand:SI 2 "arith_operand" "rI")))]
5898   "TARGET_ARCH64 || TARGET_V8PLUS"
5900   if (! TARGET_ARCH64)
5901     {
5902       if (GET_CODE (operands[2]) == CONST_INT)
5903         FAIL;
5904       emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
5905       DONE;
5906     }
5909 (define_insn "*lshrdi3_sp64"
5910   [(set (match_operand:DI 0 "register_operand" "=r")
5911         (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5912                      (match_operand:SI 2 "arith_operand" "rI")))]
5913   "TARGET_ARCH64"
5914   {
5915     if (GET_CODE (operands[2]) == CONST_INT)
5916       operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
5917     return "srlx\t%1, %2, %0";
5918   }
5919   [(set_attr "type" "shift")])
5921 (define_insn "lshrdi3_v8plus"
5922   [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
5923         (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
5924                      (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
5925    (clobber (match_scratch:SI 3 "=X,X,&h"))]
5926   "TARGET_V8PLUS"
5927   "* return output_v8plus_shift (insn, operands, \"srlx\");"
5928   [(set_attr "type" "multi")
5929    (set_attr "length" "5,5,6")])
5931 (define_insn ""
5932   [(set (match_operand:SI 0 "register_operand" "=r")
5933         (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5934                                              (const_int 32)) 4)
5935                      (match_operand:SI 2 "small_int_operand" "I")))]
5936   "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
5938   operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
5939   return "srax\t%1, %2, %0";
5941   [(set_attr "type" "shift")])
5943 (define_insn ""
5944   [(set (match_operand:SI 0 "register_operand" "=r")
5945         (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5946                                              (const_int 32)) 4)
5947                      (match_operand:SI 2 "small_int_operand" "I")))]
5948   "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
5950   operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
5951   return "srlx\t%1, %2, %0";
5953   [(set_attr "type" "shift")])
5955 (define_insn ""
5956   [(set (match_operand:SI 0 "register_operand" "=r")
5957         (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
5958                                              (match_operand:SI 2 "small_int_operand" "I")) 4)
5959                      (match_operand:SI 3 "small_int_operand" "I")))]
5960   "TARGET_ARCH64
5961    && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
5962    && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
5963    && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
5965   operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
5967   return "srax\t%1, %2, %0";
5969   [(set_attr "type" "shift")])
5971 (define_insn ""
5972   [(set (match_operand:SI 0 "register_operand" "=r")
5973         (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
5974                                              (match_operand:SI 2 "small_int_operand" "I")) 4)
5975                      (match_operand:SI 3 "small_int_operand" "I")))]
5976   "TARGET_ARCH64
5977    && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
5978    && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
5979    && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
5981   operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
5983   return "srlx\t%1, %2, %0";
5985   [(set_attr "type" "shift")])
5988 ;; Unconditional and other jump instructions.
5990 (define_expand "jump"
5991   [(set (pc) (label_ref (match_operand 0 "" "")))]
5992   "")
5994 (define_insn "*jump_ubranch"
5995   [(set (pc) (label_ref (match_operand 0 "" "")))]
5996   "! TARGET_CBCOND"
5997   "* return output_ubranch (operands[0], insn);"
5998   [(set_attr "type" "uncond_branch")])
6000 (define_insn "*jump_cbcond"
6001   [(set (pc) (label_ref (match_operand 0 "" "")))]
6002   "TARGET_CBCOND"
6003   "* return output_ubranch (operands[0], insn);"
6004   [(set_attr "type" "uncond_cbcond")])
6006 (define_expand "tablejump"
6007   [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
6008               (use (label_ref (match_operand 1 "" "")))])]
6009   ""
6011   gcc_assert (GET_MODE (operands[0]) == CASE_VECTOR_MODE);
6013   /* In pic mode, our address differences are against the base of the
6014      table.  Add that base value back in; CSE ought to be able to combine
6015      the two address loads.  */
6016   if (flag_pic)
6017     {
6018       rtx tmp, tmp2;
6019       tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
6020       tmp2 = operands[0];
6021       if (CASE_VECTOR_MODE != Pmode)
6022         tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
6023       tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
6024       operands[0] = memory_address (Pmode, tmp);
6025     }
6028 (define_insn "*tablejump_sp32"
6029   [(set (pc) (match_operand:SI 0 "address_operand" "p"))
6030    (use (label_ref (match_operand 1 "" "")))]
6031   "! TARGET_ARCH64"
6032   "jmp\t%a0%#"
6033   [(set_attr "type" "uncond_branch")])
6035 (define_insn "*tablejump_sp64"
6036   [(set (pc) (match_operand:DI 0 "address_operand" "p"))
6037    (use (label_ref (match_operand 1 "" "")))]
6038   "TARGET_ARCH64"
6039   "jmp\t%a0%#"
6040   [(set_attr "type" "uncond_branch")])
6043 ;; Jump to subroutine instructions.
6045 (define_expand "call"
6046   ;; Note that this expression is not used for generating RTL.
6047   ;; All the RTL is generated explicitly below.
6048   [(call (match_operand 0 "call_operand" "")
6049          (match_operand 3 "" "i"))]
6050   ;; operands[2] is next_arg_register
6051   ;; operands[3] is struct_value_size_rtx.
6052   ""
6054   rtx fn_rtx;
6056   gcc_assert (MEM_P (operands[0]) && GET_MODE (operands[0]) == FUNCTION_MODE);
6058   gcc_assert (GET_CODE (operands[3]) == CONST_INT);
6060   if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
6061     {
6062       /* This is really a PIC sequence.  We want to represent
6063          it as a funny jump so its delay slots can be filled. 
6065          ??? But if this really *is* a CALL, will not it clobber the
6066          call-clobbered registers?  We lose this if it is a JUMP_INSN.
6067          Why cannot we have delay slots filled if it were a CALL?  */
6069       /* We accept negative sizes for untyped calls.  */
6070       if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6071         emit_jump_insn
6072           (gen_rtx_PARALLEL
6073            (VOIDmode,
6074             gen_rtvec (3,
6075                        gen_rtx_SET (pc_rtx, XEXP (operands[0], 0)),
6076                        operands[3],
6077                        gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6078       else
6079         emit_jump_insn
6080           (gen_rtx_PARALLEL
6081            (VOIDmode,
6082             gen_rtvec (2,
6083                        gen_rtx_SET (pc_rtx, XEXP (operands[0], 0)),
6084                        gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6085       goto finish_call;
6086     }
6088   fn_rtx = operands[0];
6090   /* We accept negative sizes for untyped calls.  */
6091   if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6092     sparc_emit_call_insn
6093       (gen_rtx_PARALLEL
6094        (VOIDmode,
6095         gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6096                    operands[3],
6097                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6098        XEXP (fn_rtx, 0));
6099   else
6100     sparc_emit_call_insn
6101       (gen_rtx_PARALLEL
6102        (VOIDmode,
6103         gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6104                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6105        XEXP (fn_rtx, 0));
6107  finish_call:
6109   DONE;
6112 ;; We can't use the same pattern for these two insns, because then registers
6113 ;; in the address may not be properly reloaded.
6115 (define_insn "*call_address_sp32"
6116   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6117          (match_operand 1 "" ""))
6118    (clobber (reg:SI O7_REG))]
6119   ;;- Do not use operand 1 for most machines.
6120   "! TARGET_ARCH64"
6121   "call\t%a0, %1%#"
6122   [(set_attr "type" "call")])
6124 (define_insn "*call_symbolic_sp32"
6125   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6126          (match_operand 1 "" ""))
6127    (clobber (reg:SI O7_REG))]
6128   ;;- Do not use operand 1 for most machines.
6129   "! TARGET_ARCH64"
6130   "call\t%a0, %1%#"
6131   [(set_attr "type" "call")])
6133 (define_insn "*call_address_sp64"
6134   [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
6135          (match_operand 1 "" ""))
6136    (clobber (reg:DI O7_REG))]
6137   ;;- Do not use operand 1 for most machines.
6138   "TARGET_ARCH64"
6139   "call\t%a0, %1%#"
6140   [(set_attr "type" "call")])
6142 (define_insn "*call_symbolic_sp64"
6143   [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6144          (match_operand 1 "" ""))
6145    (clobber (reg:DI O7_REG))]
6146   ;;- Do not use operand 1 for most machines.
6147   "TARGET_ARCH64"
6148   "call\t%a0, %1%#"
6149   [(set_attr "type" "call")])
6151 ;; This is a call that wants a structure value.
6152 ;; There is no such critter for v9 (??? we may need one anyway).
6153 (define_insn "*call_address_struct_value_sp32"
6154   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6155          (match_operand 1 "" ""))
6156    (match_operand 2 "immediate_operand" "")
6157    (clobber (reg:SI O7_REG))]
6158   ;;- Do not use operand 1 for most machines.
6159   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6161   operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6162   return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6164   [(set_attr "type" "call_no_delay_slot")
6165    (set_attr "length" "3")])
6167 ;; This is a call that wants a structure value.
6168 ;; There is no such critter for v9 (??? we may need one anyway).
6169 (define_insn "*call_symbolic_struct_value_sp32"
6170   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6171          (match_operand 1 "" ""))
6172    (match_operand 2 "immediate_operand" "")
6173    (clobber (reg:SI O7_REG))]
6174   ;;- Do not use operand 1 for most machines.
6175   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6177   operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6178   return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6180   [(set_attr "type" "call_no_delay_slot")
6181    (set_attr "length" "3")])
6183 ;; This is a call that may want a structure value.  This is used for
6184 ;; untyped_calls.
6185 (define_insn "*call_address_untyped_struct_value_sp32"
6186   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6187          (match_operand 1 "" ""))
6188    (match_operand 2 "immediate_operand" "")
6189    (clobber (reg:SI O7_REG))]
6190   ;;- Do not use operand 1 for most machines.
6191   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6192   "call\t%a0, %1\n\t nop\n\tnop"
6193   [(set_attr "type" "call_no_delay_slot")
6194    (set_attr "length" "3")])
6196 ;; This is a call that may want a structure value.  This is used for
6197 ;; untyped_calls.
6198 (define_insn "*call_symbolic_untyped_struct_value_sp32"
6199   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6200          (match_operand 1 "" ""))
6201    (match_operand 2 "immediate_operand" "")
6202    (clobber (reg:SI O7_REG))]
6203   ;;- Do not use operand 1 for most machines.
6204   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6205   "call\t%a0, %1\n\t nop\n\tnop"
6206   [(set_attr "type" "call_no_delay_slot")
6207    (set_attr "length" "3")])
6209 (define_expand "call_value"
6210   ;; Note that this expression is not used for generating RTL.
6211   ;; All the RTL is generated explicitly below.
6212   [(set (match_operand 0 "register_operand" "=rf")
6213         (call (match_operand 1 "" "")
6214               (match_operand 4 "" "")))]
6215   ;; operand 2 is stack_size_rtx
6216   ;; operand 3 is next_arg_register
6217   ""
6219   rtx fn_rtx;
6220   rtvec vec;
6222   gcc_assert (MEM_P (operands[1]) && GET_MODE (operands[1]) == FUNCTION_MODE);
6224   fn_rtx = operands[1];
6226   vec = gen_rtvec (2,
6227                    gen_rtx_SET (operands[0],
6228                                 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
6229                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
6231   sparc_emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec), XEXP (fn_rtx, 0));
6233   DONE;
6236 (define_insn "*call_value_address_sp32"
6237   [(set (match_operand 0 "" "=rf")
6238         (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
6239               (match_operand 2 "" "")))
6240    (clobber (reg:SI O7_REG))]
6241   ;;- Do not use operand 2 for most machines.
6242   "! TARGET_ARCH64"
6243   "call\t%a1, %2%#"
6244   [(set_attr "type" "call")])
6246 (define_insn "*call_value_symbolic_sp32"
6247   [(set (match_operand 0 "" "=rf")
6248         (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6249               (match_operand 2 "" "")))
6250    (clobber (reg:SI O7_REG))]
6251   ;;- Do not use operand 2 for most machines.
6252   "! TARGET_ARCH64"
6253   "call\t%a1, %2%#"
6254   [(set_attr "type" "call")])
6256 (define_insn "*call_value_address_sp64"
6257   [(set (match_operand 0 "" "")
6258         (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
6259               (match_operand 2 "" "")))
6260    (clobber (reg:DI O7_REG))]
6261   ;;- Do not use operand 2 for most machines.
6262   "TARGET_ARCH64"
6263   "call\t%a1, %2%#"
6264   [(set_attr "type" "call")])
6266 (define_insn "*call_value_symbolic_sp64"
6267   [(set (match_operand 0 "" "")
6268         (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6269               (match_operand 2 "" "")))
6270    (clobber (reg:DI O7_REG))]
6271   ;;- Do not use operand 2 for most machines.
6272   "TARGET_ARCH64"
6273   "call\t%a1, %2%#"
6274   [(set_attr "type" "call")])
6276 (define_expand "untyped_call"
6277   [(parallel [(call (match_operand 0 "" "")
6278                     (const_int 0))
6279               (match_operand:BLK 1 "memory_operand" "")
6280               (match_operand 2 "" "")])]
6281   ""
6283   rtx valreg1 = gen_rtx_REG (DImode, 8);
6284   rtx result = operands[1];
6286   /* Pass constm1 to indicate that it may expect a structure value, but
6287      we don't know what size it is.  */
6288   emit_call_insn (gen_call (operands[0], const0_rtx, NULL, constm1_rtx));
6290   /* Save the function value registers.  */
6291   emit_move_insn (adjust_address (result, DImode, 0), valreg1);
6292   if (TARGET_FPU)
6293     {
6294       rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6295       emit_move_insn (adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8),
6296                       valreg2);
6297     }
6299   /* The optimizer does not know that the call sets the function value
6300      registers we stored in the result block.  We avoid problems by
6301      claiming that all hard registers are used and clobbered at this
6302      point.  */
6303   emit_insn (gen_blockage ());
6305   DONE;
6309 ;;  Tail call instructions.
6311 (define_expand "sibcall"
6312   [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
6313               (return)])]
6314   ""
6315   "")
6317 (define_insn "*sibcall_symbolic_sp32"
6318   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6319          (match_operand 1 "" ""))
6320    (return)]
6321   "! TARGET_ARCH64"
6322   "* return output_sibcall(insn, operands[0]);"
6323   [(set_attr "type" "sibcall")])
6325 (define_insn "*sibcall_symbolic_sp64"
6326   [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6327          (match_operand 1 "" ""))
6328    (return)]
6329   "TARGET_ARCH64"
6330   "* return output_sibcall(insn, operands[0]);"
6331   [(set_attr "type" "sibcall")])
6333 (define_expand "sibcall_value"
6334   [(parallel [(set (match_operand 0 "register_operand" "=rf")
6335                 (call (match_operand 1 "" "") (const_int 0)))
6336               (return)])]
6337   ""
6338   "")
6340 (define_insn "*sibcall_value_symbolic_sp32"
6341   [(set (match_operand 0 "" "=rf")
6342         (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6343               (match_operand 2 "" "")))
6344    (return)]
6345   "! TARGET_ARCH64"
6346   "* return output_sibcall(insn, operands[1]);"
6347   [(set_attr "type" "sibcall")])
6349 (define_insn "*sibcall_value_symbolic_sp64"
6350   [(set (match_operand 0 "" "")
6351         (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6352               (match_operand 2 "" "")))
6353    (return)]
6354   "TARGET_ARCH64"
6355   "* return output_sibcall(insn, operands[1]);"
6356   [(set_attr "type" "sibcall")])
6359 ;; Special instructions.
6361 (define_expand "prologue"
6362   [(const_int 0)]
6363   ""
6365   if (TARGET_FLAT)
6366     sparc_flat_expand_prologue ();
6367   else
6368     sparc_expand_prologue ();
6369   DONE;
6372 ;; The "register window save" insn is modelled as follows.  The dwarf2
6373 ;; information is manually added in emit_window_save.
6375 (define_insn "window_save"
6376   [(unspec_volatile
6377         [(match_operand 0 "arith_operand" "rI")]
6378         UNSPECV_SAVEW)]
6379   "!TARGET_FLAT"
6380   "save\t%%sp, %0, %%sp"
6381   [(set_attr "type" "savew")])
6383 (define_expand "epilogue"
6384   [(return)]
6385   ""
6387   if (TARGET_FLAT)
6388     sparc_flat_expand_epilogue (false);
6389   else
6390     sparc_expand_epilogue (false);
6393 (define_expand "sibcall_epilogue"
6394   [(return)]
6395   ""
6397   if (TARGET_FLAT)
6398     sparc_flat_expand_epilogue (false);
6399   else
6400     sparc_expand_epilogue (false);
6401   DONE;
6404 (define_expand "eh_return"
6405   [(use (match_operand 0 "general_operand" ""))]
6406   ""
6408   emit_move_insn (gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM), operands[0]);
6409   emit_jump_insn (gen_eh_return_internal ());
6410   emit_barrier ();
6411   DONE;
6414 (define_insn_and_split "eh_return_internal"
6415   [(eh_return)]
6416   ""
6417   "#"
6418   "epilogue_completed"
6419   [(return)]
6421   if (TARGET_FLAT)
6422     sparc_flat_expand_epilogue (true);
6423   else
6424     sparc_expand_epilogue (true);
6427 (define_expand "return"
6428   [(return)]
6429   "sparc_can_use_return_insn_p ()"
6430   "")
6432 (define_insn "*return_internal"
6433   [(return)]
6434   ""
6435   "* return output_return (insn);"
6436   [(set_attr "type" "return")
6437    (set (attr "length")
6438         (cond [(eq_attr "calls_eh_return" "true")
6439                  (if_then_else (eq_attr "delayed_branch" "true")
6440                                 (if_then_else (ior (eq_attr "isa" "v9")
6441                                                    (eq_attr "flat" "true"))
6442                                         (const_int 2)
6443                                         (const_int 3))
6444                                 (if_then_else (eq_attr "flat" "true")
6445                                         (const_int 3)
6446                                         (const_int 4)))
6447                (ior (eq_attr "leaf_function" "true") (eq_attr "flat" "true"))
6448                  (if_then_else (eq_attr "empty_delay_slot" "true")
6449                                (const_int 2)
6450                                (const_int 1))
6451                (eq_attr "empty_delay_slot" "true")
6452                  (if_then_else (eq_attr "delayed_branch" "true")
6453                                (const_int 2)
6454                                (const_int 3))
6455               ] (const_int 1)))])
6457 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
6458 ;; all of memory.  This blocks insns from being moved across this point.
6460 (define_insn "blockage"
6461   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
6462   ""
6463   ""
6464   [(set_attr "length" "0")])
6466 ;; Do not schedule instructions accessing memory before this point.
6468 (define_expand "frame_blockage"
6469   [(set (match_dup 0)
6470         (unspec:BLK [(match_dup 1)] UNSPEC_FRAME_BLOCKAGE))]
6471   ""
6473   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
6474   MEM_VOLATILE_P (operands[0]) = 1;
6475   operands[1] = stack_pointer_rtx;
6478 (define_insn "*frame_blockage<P:mode>"
6479   [(set (match_operand:BLK 0 "" "")
6480         (unspec:BLK [(match_operand:P 1 "" "")] UNSPEC_FRAME_BLOCKAGE))]
6481   ""
6482   ""
6483   [(set_attr "length" "0")])
6485 (define_expand "probe_stack"
6486   [(set (match_operand 0 "memory_operand" "") (const_int 0))]
6487   ""
6489   operands[0]
6490     = adjust_address (operands[0], GET_MODE (operands[0]), SPARC_STACK_BIAS);
6493 (define_insn "probe_stack_range<P:mode>"
6494   [(set (match_operand:P 0 "register_operand" "=r")
6495         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
6496                             (match_operand:P 2 "register_operand" "r")]
6497                             UNSPECV_PROBE_STACK_RANGE))]
6498   ""
6499   "* return output_probe_stack_range (operands[0], operands[2]);"
6500   [(set_attr "type" "multi")])
6502 ;; Prepare to return any type including a structure value.
6504 (define_expand "untyped_return"
6505   [(match_operand:BLK 0 "memory_operand" "")
6506    (match_operand 1 "" "")]
6507   ""
6509   rtx valreg1 = gen_rtx_REG (DImode, 24);
6510   rtx result = operands[0];
6512   if (! TARGET_ARCH64)
6513     {
6514       rtx rtnreg = gen_rtx_REG (SImode, RETURN_ADDR_REGNUM);
6515       rtx value = gen_reg_rtx (SImode);
6517       /* Fetch the instruction where we will return to and see if it's an unimp
6518          instruction (the most significant 10 bits will be zero).  If so,
6519          update the return address to skip the unimp instruction.  */
6520       emit_move_insn (value,
6521                       gen_rtx_MEM (SImode, plus_constant (SImode, rtnreg, 8)));
6522       emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
6523       emit_insn (gen_update_return (rtnreg, value));
6524     }
6526   /* Reload the function value registers.
6527      Put USE insns before the return.  */
6528   emit_move_insn (valreg1, adjust_address (result, DImode, 0));
6529   emit_use (valreg1);
6531   if (TARGET_FPU)
6532     {
6533       rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6534       emit_move_insn (valreg2,
6535                       adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
6536       emit_use (valreg2);
6537     }
6539   /* Construct the return.  */
6540   expand_naked_return ();
6542   DONE;
6545 ;; Adjust the return address conditionally. If the value of op1 is equal
6546 ;; to all zero then adjust the return address i.e. op0 = op0 + 4.
6547 ;; This is technically *half* the check required by the 32-bit SPARC
6548 ;; psABI. This check only ensures that an "unimp" insn was written by
6549 ;; the caller, but doesn't check to see if the expected size matches
6550 ;; (this is encoded in the 12 lower bits). This check is obsolete and
6551 ;; only used by the above code "untyped_return".
6553 (define_insn "update_return"
6554   [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
6555                (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
6556   "! TARGET_ARCH64"
6558   if (flag_delayed_branch)
6559     return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
6560   else
6561     return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
6563   [(set (attr "type") (const_string "multi"))
6564    (set (attr "length")
6565         (if_then_else (eq_attr "delayed_branch" "true")
6566                       (const_int 3)
6567                       (const_int 4)))])
6569 (define_insn "nop"
6570   [(const_int 0)]
6571   ""
6572   "nop")
6574 (define_expand "indirect_jump"
6575   [(set (pc) (match_operand 0 "address_operand" "p"))]
6576   ""
6577   "")
6579 (define_insn "*branch_sp32"
6580   [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
6581   "! TARGET_ARCH64"
6582  "jmp\t%a0%#"
6583  [(set_attr "type" "uncond_branch")])
6585 (define_insn "*branch_sp64"
6586   [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
6587   "TARGET_ARCH64"
6588   "jmp\t%a0%#"
6589   [(set_attr "type" "uncond_branch")])
6591 (define_expand "save_stack_nonlocal"
6592   [(set (match_operand 0 "memory_operand" "")
6593         (match_operand 1 "register_operand" ""))
6594    (set (match_dup 2) (match_dup 3))]
6595   ""
6597   operands[0] = adjust_address (operands[0], Pmode, 0);
6598   operands[2] = adjust_address (operands[0], Pmode, GET_MODE_SIZE (Pmode));
6599   operands[3] = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
6602 (define_expand "restore_stack_nonlocal"
6603   [(set (match_operand 0 "register_operand" "")
6604         (match_operand 1 "memory_operand" ""))]
6605   ""
6607   operands[1] = adjust_address (operands[1], Pmode, 0);
6610 (define_expand "nonlocal_goto"
6611   [(match_operand 0 "general_operand" "")
6612    (match_operand 1 "general_operand" "")
6613    (match_operand 2 "memory_operand" "")
6614    (match_operand 3 "memory_operand" "")]
6615   ""
6617   rtx i7 = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
6618   rtx r_label = copy_to_reg (operands[1]);
6619   rtx r_sp = adjust_address (operands[2], Pmode, 0);
6620   rtx r_fp = operands[3];
6621   rtx r_i7 = adjust_address (operands[2], Pmode, GET_MODE_SIZE (Pmode));
6623   /* We need to flush all the register windows so that their contents will
6624      be re-synchronized by the restore insn of the target function.  */
6625   if (!TARGET_FLAT)
6626     emit_insn (gen_flush_register_windows ());
6628   emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
6629   emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
6631   /* Restore frame pointer for containing function.  */
6632   emit_move_insn (hard_frame_pointer_rtx, r_fp);
6633   emit_stack_restore (SAVE_NONLOCAL, r_sp);
6634   emit_move_insn (i7, r_i7);
6636   /* USE of hard_frame_pointer_rtx added for consistency;
6637      not clear if really needed.  */
6638   emit_use (hard_frame_pointer_rtx);
6639   emit_use (stack_pointer_rtx);
6640   emit_use (i7);
6642   emit_jump_insn (gen_indirect_jump (r_label));
6643   emit_barrier ();
6644   DONE;
6647 (define_expand "builtin_setjmp_receiver"
6648   [(label_ref (match_operand 0 "" ""))]
6649   "flag_pic"
6651   load_got_register ();
6652   DONE;
6655 ;; Special insn to flush register windows.
6657 (define_insn "flush_register_windows"
6658   [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
6659   ""
6660   { return TARGET_V9 ? "flushw" : "ta\t3"; }
6661   [(set_attr "type" "flushw")])
6663 ;; Special pattern for the FLUSH instruction.
6665 (define_insn "flush<P:mode>"
6666   [(unspec_volatile [(match_operand:P 0 "memory_operand" "m")] UNSPECV_FLUSH)]
6667   ""
6668   { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
6669   [(set_attr "type" "iflush")])
6671 ;; Special insns to load and store the 32-bit FP Status Register.
6673 (define_insn "ldfsr"
6674   [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_LDFSR)]
6675   "TARGET_FPU"
6676   "ld\t%0, %%fsr"
6677   [(set_attr "type" "load")])
6679 (define_insn "stfsr"
6680   [(set (match_operand:SI 0 "memory_operand" "=m")
6681         (unspec_volatile:SI [(const_int 0)] UNSPECV_STFSR))]
6682   "TARGET_FPU"
6683   "st\t%%fsr, %0"
6684   [(set_attr "type" "store")])
6687 ;; Find first set instructions.
6689 ;; The scan instruction searches from the most significant bit while ffs
6690 ;; searches from the least significant bit.  The bit index and treatment of
6691 ;; zero also differ.  It takes at least 7 instructions to get the proper
6692 ;; result.  Here is an obvious 8 instruction sequence.
6694 ;; XXX
6695 (define_insn "ffssi2"
6696   [(set (match_operand:SI 0 "register_operand" "=&r")
6697         (ffs:SI (match_operand:SI 1 "register_operand" "r")))
6698    (clobber (match_scratch:SI 2 "=&r"))]
6699   "TARGET_SPARCLITE || TARGET_SPARCLET"
6701   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";
6703   [(set_attr "type" "multi")
6704    (set_attr "length" "8")])
6706 (define_expand "popcountdi2"
6707   [(set (match_operand:DI 0 "register_operand" "")
6708         (popcount:DI (match_operand:DI 1 "register_operand" "")))]
6709   "TARGET_POPC"
6711   if (! TARGET_ARCH64)
6712     {
6713       emit_insn (gen_popcountdi_v8plus (operands[0], operands[1]));
6714       DONE;
6715     }
6718 (define_insn "*popcountdi_sp64"
6719   [(set (match_operand:DI 0 "register_operand" "=r")
6720         (popcount:DI (match_operand:DI 1 "register_operand" "r")))]
6721   "TARGET_POPC && TARGET_ARCH64"
6722   "popc\t%1, %0")
6724 (define_insn "popcountdi_v8plus"
6725   [(set (match_operand:DI 0 "register_operand" "=r")
6726         (popcount:DI (match_operand:DI 1 "register_operand" "r")))
6727    (clobber (match_scratch:SI 2 "=&h"))]
6728   "TARGET_POPC && ! TARGET_ARCH64"
6730   if (sparc_check_64 (operands[1], insn) <= 0)
6731     output_asm_insn ("srl\t%L1, 0, %L1", operands);
6732   return "sllx\t%H1, 32, %2\n\tor\t%L1, %2, %2\n\tpopc\t%2, %L0\n\tclr\t%H0";
6734   [(set_attr "type" "multi")
6735    (set_attr "length" "5")])
6737 (define_expand "popcountsi2"
6738   [(set (match_dup 2)
6739         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
6740    (set (match_operand:SI 0 "register_operand" "")
6741         (truncate:SI (popcount:DI (match_dup 2))))]
6742   "TARGET_POPC"
6744   if (! TARGET_ARCH64)
6745     {
6746       emit_insn (gen_popcountsi_v8plus (operands[0], operands[1]));
6747       DONE;
6748     }
6749   else
6750     operands[2] = gen_reg_rtx (DImode);
6753 (define_insn "*popcountsi_sp64"
6754   [(set (match_operand:SI 0 "register_operand" "=r")
6755         (truncate:SI
6756           (popcount:DI (match_operand:DI 1 "register_operand" "r"))))]
6757   "TARGET_POPC && TARGET_ARCH64"
6758   "popc\t%1, %0")
6760 (define_insn "popcountsi_v8plus"
6761   [(set (match_operand:SI 0 "register_operand" "=r")
6762         (popcount:SI (match_operand:SI 1 "register_operand" "r")))]
6763   "TARGET_POPC && ! TARGET_ARCH64"
6765   if (sparc_check_64 (operands[1], insn) <= 0)
6766     output_asm_insn ("srl\t%1, 0, %1", operands);
6767   return "popc\t%1, %0";
6769   [(set_attr "type" "multi")
6770    (set_attr "length" "2")])
6772 (define_expand "clzdi2"
6773   [(set (match_operand:DI 0 "register_operand" "")
6774         (clz:DI (match_operand:DI 1 "register_operand" "")))]
6775   "TARGET_VIS3"
6777   if (! TARGET_ARCH64)
6778     {
6779       emit_insn (gen_clzdi_v8plus (operands[0], operands[1]));
6780       DONE;
6781     }
6784 (define_insn "*clzdi_sp64"
6785   [(set (match_operand:DI 0 "register_operand" "=r")
6786         (clz:DI (match_operand:DI 1 "register_operand" "r")))]
6787   "TARGET_VIS3 && TARGET_ARCH64"
6788   "lzd\t%1, %0"
6789   [(set_attr "type" "lzd")])
6791 (define_insn "clzdi_v8plus"
6792   [(set (match_operand:DI 0 "register_operand" "=r")
6793         (clz:DI (match_operand:DI 1 "register_operand" "r")))
6794    (clobber (match_scratch:SI 2 "=&h"))]
6795   "TARGET_VIS3 && ! TARGET_ARCH64"
6797   if (sparc_check_64 (operands[1], insn) <= 0)
6798     output_asm_insn ("srl\t%L1, 0, %L1", operands);
6799   return "sllx\t%H1, 32, %2\n\tor\t%L1, %2, %2\n\tlzd\t%2, %L0\n\tclr\t%H0";
6801   [(set_attr "type" "multi")
6802    (set_attr "length" "5")])
6804 (define_expand "clzsi2"
6805   [(set (match_dup 2)
6806         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
6807    (set (match_dup 3)
6808         (truncate:SI (clz:DI (match_dup 2))))
6809    (set (match_operand:SI 0 "register_operand" "")
6810         (minus:SI (match_dup 3) (const_int 32)))]
6811   "TARGET_VIS3"
6813   if (! TARGET_ARCH64)
6814     {
6815       emit_insn (gen_clzsi_v8plus (operands[0], operands[1]));
6816       DONE;
6817     }
6818   else
6819     {
6820       operands[2] = gen_reg_rtx (DImode);
6821       operands[3] = gen_reg_rtx (SImode);
6822     }
6825 (define_insn "*clzsi_sp64"
6826   [(set (match_operand:SI 0 "register_operand" "=r")
6827         (truncate:SI
6828           (clz:DI (match_operand:DI 1 "register_operand" "r"))))]
6829   "TARGET_VIS3 && TARGET_ARCH64"
6830   "lzd\t%1, %0"
6831   [(set_attr "type" "lzd")])
6833 (define_insn "clzsi_v8plus"
6834   [(set (match_operand:SI 0 "register_operand" "=r")
6835         (clz:SI (match_operand:SI 1 "register_operand" "r")))]
6836   "TARGET_VIS3 && ! TARGET_ARCH64"
6838   if (sparc_check_64 (operands[1], insn) <= 0)
6839     output_asm_insn ("srl\t%1, 0, %1", operands);
6840   return "lzd\t%1, %0\n\tsub\t%0, 32, %0";
6842   [(set_attr "type" "multi")
6843    (set_attr "length" "3")])
6846 ;; Peepholes go at the end.
6848 ;; Optimize consecutive loads or stores into ldd and std when possible.
6849 ;; The conditions in which we do this are very restricted and are 
6850 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
6852 (define_peephole2
6853   [(set (match_operand:SI 0 "memory_operand" "")
6854       (const_int 0))
6855    (set (match_operand:SI 1 "memory_operand" "")
6856       (const_int 0))]
6857   "TARGET_V9
6858    && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
6859   [(set (match_dup 0) (const_int 0))]
6861   operands[0] = widen_mem_for_ldd_peep (operands[0], operands[1], DImode);
6864 (define_peephole2
6865   [(set (match_operand:SI 0 "memory_operand" "")
6866       (const_int 0))
6867    (set (match_operand:SI 1 "memory_operand" "")
6868       (const_int 0))]
6869   "TARGET_V9
6870    && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
6871   [(set (match_dup 1) (const_int 0))]
6873   operands[1] = widen_mem_for_ldd_peep (operands[1], operands[0], DImode);
6876 (define_peephole2
6877   [(set (match_operand:SI 0 "register_operand" "")
6878         (match_operand:SI 1 "memory_operand" ""))
6879    (set (match_operand:SI 2 "register_operand" "")
6880         (match_operand:SI 3 "memory_operand" ""))]
6881   "registers_ok_for_ldd_peep (operands[0], operands[2]) 
6882    && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])" 
6883   [(set (match_dup 0) (match_dup 1))]
6885   operands[1] = widen_mem_for_ldd_peep (operands[1], operands[3], DImode);
6886   operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
6889 (define_peephole2
6890   [(set (match_operand:SI 0 "memory_operand" "")
6891         (match_operand:SI 1 "register_operand" ""))
6892    (set (match_operand:SI 2 "memory_operand" "")
6893         (match_operand:SI 3 "register_operand" ""))]
6894   "registers_ok_for_ldd_peep (operands[1], operands[3]) 
6895    && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
6896   [(set (match_dup 0) (match_dup 1))]
6898   operands[0] = widen_mem_for_ldd_peep (operands[0], operands[2], DImode);
6899   operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));
6902 (define_peephole2
6903   [(set (match_operand:SF 0 "register_operand" "")
6904         (match_operand:SF 1 "memory_operand" ""))
6905    (set (match_operand:SF 2 "register_operand" "")
6906         (match_operand:SF 3 "memory_operand" ""))]
6907   "registers_ok_for_ldd_peep (operands[0], operands[2]) 
6908    && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
6909   [(set (match_dup 0) (match_dup 1))]
6911   operands[1] = widen_mem_for_ldd_peep (operands[1], operands[3], DFmode);
6912   operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));
6915 (define_peephole2
6916   [(set (match_operand:SF 0 "memory_operand" "")
6917         (match_operand:SF 1 "register_operand" ""))
6918    (set (match_operand:SF 2 "memory_operand" "")
6919         (match_operand:SF 3 "register_operand" ""))]
6920   "registers_ok_for_ldd_peep (operands[1], operands[3]) 
6921   && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
6922   [(set (match_dup 0) (match_dup 1))]
6924   operands[0] = widen_mem_for_ldd_peep (operands[0], operands[2], DFmode);
6925   operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));
6928 (define_peephole2
6929   [(set (match_operand:SI 0 "register_operand" "")
6930         (match_operand:SI 1 "memory_operand" ""))
6931    (set (match_operand:SI 2 "register_operand" "")
6932         (match_operand:SI 3 "memory_operand" ""))]
6933   "registers_ok_for_ldd_peep (operands[2], operands[0]) 
6934   && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
6935   [(set (match_dup 2) (match_dup 3))]
6937   operands[3] = widen_mem_for_ldd_peep (operands[3], operands[1], DImode);
6938   operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));
6941 (define_peephole2
6942   [(set (match_operand:SI 0 "memory_operand" "")
6943         (match_operand:SI 1 "register_operand" ""))
6944    (set (match_operand:SI 2 "memory_operand" "")
6945         (match_operand:SI 3 "register_operand" ""))]
6946   "registers_ok_for_ldd_peep (operands[3], operands[1]) 
6947   && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)" 
6948   [(set (match_dup 2) (match_dup 3))]
6950   operands[2] = widen_mem_for_ldd_peep (operands[2],  operands[0], DImode);
6951   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
6954 (define_peephole2
6955   [(set (match_operand:SF 0 "register_operand" "")
6956         (match_operand:SF 1 "memory_operand" ""))
6957    (set (match_operand:SF 2 "register_operand" "")
6958         (match_operand:SF 3 "memory_operand" ""))]
6959   "registers_ok_for_ldd_peep (operands[2], operands[0]) 
6960   && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
6961   [(set (match_dup 2) (match_dup 3))]
6963   operands[3] = widen_mem_for_ldd_peep (operands[3], operands[1], DFmode);
6964   operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));
6967 (define_peephole2
6968   [(set (match_operand:SF 0 "memory_operand" "")
6969         (match_operand:SF 1 "register_operand" ""))
6970    (set (match_operand:SF 2 "memory_operand" "")
6971         (match_operand:SF 3 "register_operand" ""))]
6972   "registers_ok_for_ldd_peep (operands[3], operands[1]) 
6973   && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
6974   [(set (match_dup 2) (match_dup 3))]
6976   operands[2] = widen_mem_for_ldd_peep (operands[2], operands[0], DFmode);
6977   operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));
6980 ;; Optimize the case of following a reg-reg move with a test
6981 ;; of reg just moved.  Don't allow floating point regs for operand 0 or 1.
6982 ;; This can result from a float to fix conversion.
6984 (define_peephole2
6985   [(set (match_operand:SI 0 "register_operand" "")
6986         (match_operand:SI 1 "register_operand" ""))
6987    (set (reg:CC CC_REG)
6988         (compare:CC (match_operand:SI 2 "register_operand" "")
6989                     (const_int 0)))]
6990   "(rtx_equal_p (operands[2], operands[0])
6991     || rtx_equal_p (operands[2], operands[1]))
6992     && ! SPARC_FP_REG_P (REGNO (operands[0]))
6993     && ! SPARC_FP_REG_P (REGNO (operands[1]))"
6994   [(parallel [(set (match_dup 0) (match_dup 1))
6995               (set (reg:CC CC_REG)
6996                    (compare:CC (match_dup 1) (const_int 0)))])]
6997   "")
6999 (define_peephole2
7000   [(set (match_operand:DI 0 "register_operand" "")
7001         (match_operand:DI 1 "register_operand" ""))
7002    (set (reg:CCX CC_REG)
7003         (compare:CCX (match_operand:DI 2 "register_operand" "")
7004                     (const_int 0)))]
7005   "TARGET_ARCH64
7006    && (rtx_equal_p (operands[2], operands[0])
7007        || rtx_equal_p (operands[2], operands[1]))
7008    && ! SPARC_FP_REG_P (REGNO (operands[0]))
7009    && ! SPARC_FP_REG_P (REGNO (operands[1]))"
7010   [(parallel [(set (match_dup 0) (match_dup 1))
7011               (set (reg:CCX CC_REG)
7012                    (compare:CCX (match_dup 1) (const_int 0)))])]
7013   "")
7016 ;; Prefetch instructions.
7018 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
7019 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
7020 ;; ??? operations.  With DFA we might be able to model this, but it requires a lot of
7021 ;; ??? state.
7022 (define_expand "prefetch"
7023   [(match_operand 0 "address_operand" "")
7024    (match_operand 1 "const_int_operand" "")
7025    (match_operand 2 "const_int_operand" "")]
7026   "TARGET_V9"
7028   if (TARGET_ARCH64)
7029     emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
7030   else
7031     emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
7032   DONE;
7035 (define_insn "prefetch_64"
7036   [(prefetch (match_operand:DI 0 "address_operand" "p")
7037              (match_operand:DI 1 "const_int_operand" "n")
7038              (match_operand:DI 2 "const_int_operand" "n"))]
7039   ""
7041   static const char * const prefetch_instr[2][2] = {
7042     {
7043       "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7044       "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7045     },
7046     {
7047       "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7048       "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7049     }
7050   };
7051   int read_or_write = INTVAL (operands[1]);
7052   int locality = INTVAL (operands[2]);
7054   gcc_assert (read_or_write == 0 || read_or_write == 1);
7055   gcc_assert (locality >= 0 && locality < 4);
7056   return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7058   [(set_attr "type" "load")])
7060 (define_insn "prefetch_32"
7061   [(prefetch (match_operand:SI 0 "address_operand" "p")
7062              (match_operand:SI 1 "const_int_operand" "n")
7063              (match_operand:SI 2 "const_int_operand" "n"))]
7064   ""
7066   static const char * const prefetch_instr[2][2] = {
7067     {
7068       "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7069       "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7070     },
7071     {
7072       "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7073       "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7074     }
7075   };
7076   int read_or_write = INTVAL (operands[1]);
7077   int locality = INTVAL (operands[2]);
7079   gcc_assert (read_or_write == 0 || read_or_write == 1);
7080   gcc_assert (locality >= 0 && locality < 4);
7081   return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7083   [(set_attr "type" "load")])
7086 ;; Trap instructions.
7088 (define_insn "trap"
7089   [(trap_if (const_int 1) (const_int 5))]
7090   ""
7091   "ta\t5"
7092   [(set_attr "type" "trap")])
7094 (define_expand "ctrapsi4"
7095   [(trap_if (match_operator 0 "noov_compare_operator"
7096              [(match_operand:SI 1 "compare_operand" "")
7097               (match_operand:SI 2 "arith_operand" "")])
7098            (match_operand 3 "arith_operand"))]
7099   ""
7100   "operands[1] = gen_compare_reg (operands[0]);
7101    if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
7102      FAIL;
7103    operands[2] = const0_rtx;")
7105 (define_expand "ctrapdi4"
7106   [(trap_if (match_operator 0 "noov_compare_operator"
7107              [(match_operand:DI 1 "compare_operand" "")
7108               (match_operand:DI 2 "arith_operand" "")])
7109            (match_operand 3 "arith_operand"))]
7110   "TARGET_ARCH64"
7111   "operands[1] = gen_compare_reg (operands[0]);
7112    if (GET_MODE (operands[1]) != CCmode && GET_MODE (operands[1]) != CCXmode)
7113      FAIL;
7114    operands[2] = const0_rtx;")
7116 (define_insn ""
7117   [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CC CC_REG) (const_int 0)])
7118             (match_operand:SI 1 "arith_operand" "rM"))]
7119   ""
7121   if (TARGET_V9)
7122     return "t%C0\t%%icc, %1";
7123   else
7124     return "t%C0\t%1";
7126   [(set_attr "type" "trap")])
7128 (define_insn ""
7129   [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CCX CC_REG) (const_int 0)])
7130             (match_operand:SI 1 "arith_operand" "rM"))]
7131   "TARGET_V9"
7132   "t%C0\t%%xcc, %1"
7133   [(set_attr "type" "trap")])
7136 ;; TLS support instructions.
7138 (define_insn "tgd_hi22"
7139   [(set (match_operand:SI 0 "register_operand" "=r")
7140         (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
7141                             UNSPEC_TLSGD)))]
7142   "TARGET_TLS"
7143   "sethi\\t%%tgd_hi22(%a1), %0")
7145 (define_insn "tgd_lo10"
7146   [(set (match_operand:SI 0 "register_operand" "=r")
7147         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7148                    (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
7149                               UNSPEC_TLSGD)))]
7150   "TARGET_TLS"
7151   "add\\t%1, %%tgd_lo10(%a2), %0")
7153 (define_insn "tgd_add32"
7154   [(set (match_operand:SI 0 "register_operand" "=r")
7155         (plus:SI (match_operand:SI 1 "register_operand" "r")
7156                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7157                              (match_operand 3 "tgd_symbolic_operand" "")]
7158                             UNSPEC_TLSGD)))]
7159   "TARGET_TLS && TARGET_ARCH32"
7160   "add\\t%1, %2, %0, %%tgd_add(%a3)")
7162 (define_insn "tgd_add64"
7163   [(set (match_operand:DI 0 "register_operand" "=r")
7164         (plus:DI (match_operand:DI 1 "register_operand" "r")
7165                  (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7166                              (match_operand 3 "tgd_symbolic_operand" "")]
7167                             UNSPEC_TLSGD)))]
7168   "TARGET_TLS && TARGET_ARCH64"
7169   "add\\t%1, %2, %0, %%tgd_add(%a3)")
7171 (define_insn "tgd_call32"
7172   [(set (match_operand 0 "register_operand" "=r")
7173         (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
7174                                   (match_operand 2 "tgd_symbolic_operand" "")]
7175                                  UNSPEC_TLSGD))
7176               (match_operand 3 "" "")))
7177    (clobber (reg:SI O7_REG))]
7178   "TARGET_TLS && TARGET_ARCH32"
7179   "call\t%a1, %%tgd_call(%a2)%#"
7180   [(set_attr "type" "call")])
7182 (define_insn "tgd_call64"
7183   [(set (match_operand 0 "register_operand" "=r")
7184         (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
7185                                   (match_operand 2 "tgd_symbolic_operand" "")]
7186                                  UNSPEC_TLSGD))
7187               (match_operand 3 "" "")))
7188    (clobber (reg:DI O7_REG))]
7189   "TARGET_TLS && TARGET_ARCH64"
7190   "call\t%a1, %%tgd_call(%a2)%#"
7191   [(set_attr "type" "call")])
7193 (define_insn "tldm_hi22"
7194   [(set (match_operand:SI 0 "register_operand" "=r")
7195         (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7196   "TARGET_TLS"
7197   "sethi\\t%%tldm_hi22(%&), %0")
7199 (define_insn "tldm_lo10"
7200   [(set (match_operand:SI 0 "register_operand" "=r")
7201         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7202                     (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7203   "TARGET_TLS"
7204   "add\\t%1, %%tldm_lo10(%&), %0")
7206 (define_insn "tldm_add32"
7207   [(set (match_operand:SI 0 "register_operand" "=r")
7208         (plus:SI (match_operand:SI 1 "register_operand" "r")
7209                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
7210                             UNSPEC_TLSLDM)))]
7211   "TARGET_TLS && TARGET_ARCH32"
7212   "add\\t%1, %2, %0, %%tldm_add(%&)")
7214 (define_insn "tldm_add64"
7215   [(set (match_operand:DI 0 "register_operand" "=r")
7216         (plus:DI (match_operand:DI 1 "register_operand" "r")
7217                  (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
7218                             UNSPEC_TLSLDM)))]
7219   "TARGET_TLS && TARGET_ARCH64"
7220   "add\\t%1, %2, %0, %%tldm_add(%&)")
7222 (define_insn "tldm_call32"
7223   [(set (match_operand 0 "register_operand" "=r")
7224         (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
7225                                  UNSPEC_TLSLDM))
7226               (match_operand 2 "" "")))
7227    (clobber (reg:SI O7_REG))]
7228   "TARGET_TLS && TARGET_ARCH32"
7229   "call\t%a1, %%tldm_call(%&)%#"
7230   [(set_attr "type" "call")])
7232 (define_insn "tldm_call64"
7233   [(set (match_operand 0 "register_operand" "=r")
7234         (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
7235                                  UNSPEC_TLSLDM))
7236               (match_operand 2 "" "")))
7237    (clobber (reg:DI O7_REG))]
7238   "TARGET_TLS && TARGET_ARCH64"
7239   "call\t%a1, %%tldm_call(%&)%#"
7240   [(set_attr "type" "call")])
7242 (define_insn "tldo_hix22"
7243   [(set (match_operand:SI 0 "register_operand" "=r")
7244         (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
7245                             UNSPEC_TLSLDO)))]
7246   "TARGET_TLS"
7247   "sethi\\t%%tldo_hix22(%a1), %0")
7249 (define_insn "tldo_lox10"
7250   [(set (match_operand:SI 0 "register_operand" "=r")
7251         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7252                    (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
7253                               UNSPEC_TLSLDO)))]
7254   "TARGET_TLS"
7255   "xor\\t%1, %%tldo_lox10(%a2), %0")
7257 (define_insn "tldo_add32"
7258   [(set (match_operand:SI 0 "register_operand" "=r")
7259         (plus:SI (match_operand:SI 1 "register_operand" "r")
7260                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7261                              (match_operand 3 "tld_symbolic_operand" "")]
7262                             UNSPEC_TLSLDO)))]
7263   "TARGET_TLS && TARGET_ARCH32"
7264   "add\\t%1, %2, %0, %%tldo_add(%a3)")
7266 (define_insn "tldo_add64"
7267   [(set (match_operand:DI 0 "register_operand" "=r")
7268         (plus:DI (match_operand:DI 1 "register_operand" "r")
7269                  (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7270                              (match_operand 3 "tld_symbolic_operand" "")]
7271                             UNSPEC_TLSLDO)))]
7272   "TARGET_TLS && TARGET_ARCH64"
7273   "add\\t%1, %2, %0, %%tldo_add(%a3)")
7275 (define_insn "tie_hi22"
7276   [(set (match_operand:SI 0 "register_operand" "=r")
7277         (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
7278                             UNSPEC_TLSIE)))]
7279   "TARGET_TLS"
7280   "sethi\\t%%tie_hi22(%a1), %0")
7282 (define_insn "tie_lo10"
7283   [(set (match_operand:SI 0 "register_operand" "=r")
7284         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7285                    (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
7286                               UNSPEC_TLSIE)))]
7287   "TARGET_TLS"
7288   "add\\t%1, %%tie_lo10(%a2), %0")
7290 (define_insn "tie_ld32"
7291   [(set (match_operand:SI 0 "register_operand" "=r")
7292         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
7293                     (match_operand:SI 2 "register_operand" "r")
7294                     (match_operand 3 "tie_symbolic_operand" "")]
7295                    UNSPEC_TLSIE))]
7296   "TARGET_TLS && TARGET_ARCH32"
7297   "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
7298   [(set_attr "type" "load")])
7300 (define_insn "tie_ld64"
7301   [(set (match_operand:DI 0 "register_operand" "=r")
7302         (unspec:DI [(match_operand:DI 1 "register_operand" "r")
7303                     (match_operand:SI 2 "register_operand" "r")
7304                     (match_operand 3 "tie_symbolic_operand" "")]
7305                    UNSPEC_TLSIE))]
7306   "TARGET_TLS && TARGET_ARCH64"
7307   "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
7308   [(set_attr "type" "load")])
7310 (define_insn "tie_add32"
7311   [(set (match_operand:SI 0 "register_operand" "=r")
7312         (plus:SI (match_operand:SI 1 "register_operand" "r")
7313                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7314                              (match_operand 3 "tie_symbolic_operand" "")]
7315                             UNSPEC_TLSIE)))]
7316   "TARGET_SUN_TLS && TARGET_ARCH32"
7317   "add\\t%1, %2, %0, %%tie_add(%a3)")
7319 (define_insn "tie_add64"
7320   [(set (match_operand:DI 0 "register_operand" "=r")
7321         (plus:DI (match_operand:DI 1 "register_operand" "r")
7322                  (unspec:DI [(match_operand:DI 2 "register_operand" "r")
7323                              (match_operand 3 "tie_symbolic_operand" "")]
7324                             UNSPEC_TLSIE)))]
7325   "TARGET_SUN_TLS && TARGET_ARCH64"
7326   "add\\t%1, %2, %0, %%tie_add(%a3)")
7328 (define_insn "tle_hix22_sp32"
7329   [(set (match_operand:SI 0 "register_operand" "=r")
7330         (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
7331                             UNSPEC_TLSLE)))]
7332   "TARGET_TLS && TARGET_ARCH32"
7333   "sethi\\t%%tle_hix22(%a1), %0")
7335 (define_insn "tle_lox10_sp32"
7336   [(set (match_operand:SI 0 "register_operand" "=r")
7337         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7338                    (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
7339                               UNSPEC_TLSLE)))]
7340   "TARGET_TLS && TARGET_ARCH32"
7341   "xor\\t%1, %%tle_lox10(%a2), %0")
7343 (define_insn "tle_hix22_sp64"
7344   [(set (match_operand:DI 0 "register_operand" "=r")
7345         (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
7346                             UNSPEC_TLSLE)))]
7347   "TARGET_TLS && TARGET_ARCH64"
7348   "sethi\\t%%tle_hix22(%a1), %0")
7350 (define_insn "tle_lox10_sp64"
7351   [(set (match_operand:DI 0 "register_operand" "=r")
7352         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
7353                    (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
7354                               UNSPEC_TLSLE)))]
7355   "TARGET_TLS && TARGET_ARCH64"
7356   "xor\\t%1, %%tle_lox10(%a2), %0")
7358 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
7359 (define_insn "*tldo_ldub_sp32"
7360   [(set (match_operand:QI 0 "register_operand" "=r")
7361         (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7362                                      (match_operand 3 "tld_symbolic_operand" "")]
7363                                     UNSPEC_TLSLDO)
7364                          (match_operand:SI 1 "register_operand" "r"))))]
7365   "TARGET_TLS && TARGET_ARCH32"
7366   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7367   [(set_attr "type" "load")
7368    (set_attr "us3load_type" "3cycle")])
7370 (define_insn "*tldo_ldub1_sp32"
7371   [(set (match_operand:HI 0 "register_operand" "=r")
7372         (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7373                                                      (match_operand 3 "tld_symbolic_operand" "")]
7374                                                     UNSPEC_TLSLDO)
7375                                          (match_operand:SI 1 "register_operand" "r")))))]
7376   "TARGET_TLS && TARGET_ARCH32"
7377   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7378   [(set_attr "type" "load")
7379    (set_attr "us3load_type" "3cycle")])
7381 (define_insn "*tldo_ldub2_sp32"
7382   [(set (match_operand:SI 0 "register_operand" "=r")
7383         (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7384                                                      (match_operand 3 "tld_symbolic_operand" "")]
7385                                                     UNSPEC_TLSLDO)
7386                                          (match_operand:SI 1 "register_operand" "r")))))]
7387   "TARGET_TLS && TARGET_ARCH32"
7388   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7389   [(set_attr "type" "load")
7390    (set_attr "us3load_type" "3cycle")])
7392 (define_insn "*tldo_ldsb1_sp32"
7393   [(set (match_operand:HI 0 "register_operand" "=r")
7394         (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7395                                                      (match_operand 3 "tld_symbolic_operand" "")]
7396                                                     UNSPEC_TLSLDO)
7397                                          (match_operand:SI 1 "register_operand" "r")))))]
7398   "TARGET_TLS && TARGET_ARCH32"
7399   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7400   [(set_attr "type" "sload")
7401    (set_attr "us3load_type" "3cycle")])
7403 (define_insn "*tldo_ldsb2_sp32"
7404   [(set (match_operand:SI 0 "register_operand" "=r")
7405         (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7406                                                      (match_operand 3 "tld_symbolic_operand" "")]
7407                                                     UNSPEC_TLSLDO)
7408                                          (match_operand:SI 1 "register_operand" "r")))))]
7409   "TARGET_TLS && TARGET_ARCH32"
7410   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7411   [(set_attr "type" "sload")
7412    (set_attr "us3load_type" "3cycle")])
7414 (define_insn "*tldo_ldub_sp64"
7415   [(set (match_operand:QI 0 "register_operand" "=r")
7416         (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7417                                      (match_operand 3 "tld_symbolic_operand" "")]
7418                                     UNSPEC_TLSLDO)
7419                          (match_operand:DI 1 "register_operand" "r"))))]
7420   "TARGET_TLS && TARGET_ARCH64"
7421   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7422   [(set_attr "type" "load")
7423    (set_attr "us3load_type" "3cycle")])
7425 (define_insn "*tldo_ldub1_sp64"
7426   [(set (match_operand:HI 0 "register_operand" "=r")
7427         (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7428                                                      (match_operand 3 "tld_symbolic_operand" "")]
7429                                                     UNSPEC_TLSLDO)
7430                                          (match_operand:DI 1 "register_operand" "r")))))]
7431   "TARGET_TLS && TARGET_ARCH64"
7432   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7433   [(set_attr "type" "load")
7434    (set_attr "us3load_type" "3cycle")])
7436 (define_insn "*tldo_ldub2_sp64"
7437   [(set (match_operand:SI 0 "register_operand" "=r")
7438         (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7439                                                      (match_operand 3 "tld_symbolic_operand" "")]
7440                                                     UNSPEC_TLSLDO)
7441                                          (match_operand:DI 1 "register_operand" "r")))))]
7442   "TARGET_TLS && TARGET_ARCH64"
7443   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7444   [(set_attr "type" "load")
7445    (set_attr "us3load_type" "3cycle")])
7447 (define_insn "*tldo_ldub3_sp64"
7448   [(set (match_operand:DI 0 "register_operand" "=r")
7449         (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7450                                                      (match_operand 3 "tld_symbolic_operand" "")]
7451                                                     UNSPEC_TLSLDO)
7452                                          (match_operand:DI 1 "register_operand" "r")))))]
7453   "TARGET_TLS && TARGET_ARCH64"
7454   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7455   [(set_attr "type" "load")
7456    (set_attr "us3load_type" "3cycle")])
7458 (define_insn "*tldo_ldsb1_sp64"
7459   [(set (match_operand:HI 0 "register_operand" "=r")
7460         (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7461                                                      (match_operand 3 "tld_symbolic_operand" "")]
7462                                                     UNSPEC_TLSLDO)
7463                                          (match_operand:DI 1 "register_operand" "r")))))]
7464   "TARGET_TLS && TARGET_ARCH64"
7465   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7466   [(set_attr "type" "sload")
7467    (set_attr "us3load_type" "3cycle")])
7469 (define_insn "*tldo_ldsb2_sp64"
7470   [(set (match_operand:SI 0 "register_operand" "=r")
7471         (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7472                                                      (match_operand 3 "tld_symbolic_operand" "")]
7473                                                     UNSPEC_TLSLDO)
7474                                          (match_operand:DI 1 "register_operand" "r")))))]
7475   "TARGET_TLS && TARGET_ARCH64"
7476   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7477   [(set_attr "type" "sload")
7478    (set_attr "us3load_type" "3cycle")])
7480 (define_insn "*tldo_ldsb3_sp64"
7481   [(set (match_operand:DI 0 "register_operand" "=r")
7482         (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7483                                                      (match_operand 3 "tld_symbolic_operand" "")]
7484                                                     UNSPEC_TLSLDO)
7485                                          (match_operand:DI 1 "register_operand" "r")))))]
7486   "TARGET_TLS && TARGET_ARCH64"
7487   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7488   [(set_attr "type" "sload")
7489    (set_attr "us3load_type" "3cycle")])
7491 (define_insn "*tldo_lduh_sp32"
7492   [(set (match_operand:HI 0 "register_operand" "=r")
7493         (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7494                                      (match_operand 3 "tld_symbolic_operand" "")]
7495                                     UNSPEC_TLSLDO)
7496                          (match_operand:SI 1 "register_operand" "r"))))]
7497   "TARGET_TLS && TARGET_ARCH32"
7498   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7499   [(set_attr "type" "load")
7500    (set_attr "us3load_type" "3cycle")])
7502 (define_insn "*tldo_lduh1_sp32"
7503   [(set (match_operand:SI 0 "register_operand" "=r")
7504         (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7505                                                      (match_operand 3 "tld_symbolic_operand" "")]
7506                                                     UNSPEC_TLSLDO)
7507                                          (match_operand:SI 1 "register_operand" "r")))))]
7508   "TARGET_TLS && TARGET_ARCH32"
7509   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7510   [(set_attr "type" "load")
7511    (set_attr "us3load_type" "3cycle")])
7513 (define_insn "*tldo_ldsh1_sp32"
7514   [(set (match_operand:SI 0 "register_operand" "=r")
7515         (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7516                                                      (match_operand 3 "tld_symbolic_operand" "")]
7517                                                     UNSPEC_TLSLDO)
7518                                          (match_operand:SI 1 "register_operand" "r")))))]
7519   "TARGET_TLS && TARGET_ARCH32"
7520   "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7521   [(set_attr "type" "sload")
7522    (set_attr "us3load_type" "3cycle")])
7524 (define_insn "*tldo_lduh_sp64"
7525   [(set (match_operand:HI 0 "register_operand" "=r")
7526         (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7527                                      (match_operand 3 "tld_symbolic_operand" "")]
7528                                     UNSPEC_TLSLDO)
7529                          (match_operand:DI 1 "register_operand" "r"))))]
7530   "TARGET_TLS && TARGET_ARCH64"
7531   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7532   [(set_attr "type" "load")
7533    (set_attr "us3load_type" "3cycle")])
7535 (define_insn "*tldo_lduh1_sp64"
7536   [(set (match_operand:SI 0 "register_operand" "=r")
7537         (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7538                                                      (match_operand 3 "tld_symbolic_operand" "")]
7539                                                     UNSPEC_TLSLDO)
7540                                          (match_operand:DI 1 "register_operand" "r")))))]
7541   "TARGET_TLS && TARGET_ARCH64"
7542   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7543   [(set_attr "type" "load")
7544    (set_attr "us3load_type" "3cycle")])
7546 (define_insn "*tldo_lduh2_sp64"
7547   [(set (match_operand:DI 0 "register_operand" "=r")
7548         (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7549                                                      (match_operand 3 "tld_symbolic_operand" "")]
7550                                                     UNSPEC_TLSLDO)
7551                                          (match_operand:DI 1 "register_operand" "r")))))]
7552   "TARGET_TLS && TARGET_ARCH64"
7553   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7554   [(set_attr "type" "load")
7555    (set_attr "us3load_type" "3cycle")])
7557 (define_insn "*tldo_ldsh1_sp64"
7558   [(set (match_operand:SI 0 "register_operand" "=r")
7559         (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7560                                                      (match_operand 3 "tld_symbolic_operand" "")]
7561                                                     UNSPEC_TLSLDO)
7562                                          (match_operand:DI 1 "register_operand" "r")))))]
7563   "TARGET_TLS && TARGET_ARCH64"
7564   "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7565   [(set_attr "type" "sload")
7566    (set_attr "us3load_type" "3cycle")])
7568 (define_insn "*tldo_ldsh2_sp64"
7569   [(set (match_operand:DI 0 "register_operand" "=r")
7570         (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7571                                                      (match_operand 3 "tld_symbolic_operand" "")]
7572                                                     UNSPEC_TLSLDO)
7573                                          (match_operand:DI 1 "register_operand" "r")))))]
7574   "TARGET_TLS && TARGET_ARCH64"
7575   "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7576   [(set_attr "type" "sload")
7577    (set_attr "us3load_type" "3cycle")])
7579 (define_insn "*tldo_lduw_sp32"
7580   [(set (match_operand:SI 0 "register_operand" "=r")
7581         (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7582                                      (match_operand 3 "tld_symbolic_operand" "")]
7583                                     UNSPEC_TLSLDO)
7584                          (match_operand:SI 1 "register_operand" "r"))))]
7585   "TARGET_TLS && TARGET_ARCH32"
7586   "ld\t[%1 + %2], %0, %%tldo_add(%3)"
7587   [(set_attr "type" "load")])
7589 (define_insn "*tldo_lduw_sp64"
7590   [(set (match_operand:SI 0 "register_operand" "=r")
7591         (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7592                                      (match_operand 3 "tld_symbolic_operand" "")]
7593                                     UNSPEC_TLSLDO)
7594                          (match_operand:DI 1 "register_operand" "r"))))]
7595   "TARGET_TLS && TARGET_ARCH64"
7596   "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7597   [(set_attr "type" "load")])
7599 (define_insn "*tldo_lduw1_sp64"
7600   [(set (match_operand:DI 0 "register_operand" "=r")
7601         (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7602                                                      (match_operand 3 "tld_symbolic_operand" "")]
7603                                                     UNSPEC_TLSLDO)
7604                                          (match_operand:DI 1 "register_operand" "r")))))]
7605   "TARGET_TLS && TARGET_ARCH64"
7606   "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7607   [(set_attr "type" "load")])
7609 (define_insn "*tldo_ldsw1_sp64"
7610   [(set (match_operand:DI 0 "register_operand" "=r")
7611         (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7612                                                      (match_operand 3 "tld_symbolic_operand" "")]
7613                                                     UNSPEC_TLSLDO)
7614                                          (match_operand:DI 1 "register_operand" "r")))))]
7615   "TARGET_TLS && TARGET_ARCH64"
7616   "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
7617   [(set_attr "type" "sload")
7618    (set_attr "us3load_type" "3cycle")])
7620 (define_insn "*tldo_ldx_sp64"
7621   [(set (match_operand:DI 0 "register_operand" "=r")
7622         (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7623                                      (match_operand 3 "tld_symbolic_operand" "")]
7624                                     UNSPEC_TLSLDO)
7625                          (match_operand:DI 1 "register_operand" "r"))))]
7626   "TARGET_TLS && TARGET_ARCH64"
7627   "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
7628   [(set_attr "type" "load")])
7630 (define_insn "*tldo_stb_sp32"
7631   [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7632                                      (match_operand 3 "tld_symbolic_operand" "")]
7633                                     UNSPEC_TLSLDO)
7634                          (match_operand:SI 1 "register_operand" "r")))
7635         (match_operand:QI 0 "register_operand" "r"))]
7636   "TARGET_TLS && TARGET_ARCH32"
7637   "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7638   [(set_attr "type" "store")])
7640 (define_insn "*tldo_stb_sp64"
7641   [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7642                                      (match_operand 3 "tld_symbolic_operand" "")]
7643                                     UNSPEC_TLSLDO)
7644                          (match_operand:DI 1 "register_operand" "r")))
7645         (match_operand:QI 0 "register_operand" "r"))]
7646   "TARGET_TLS && TARGET_ARCH64"
7647   "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7648   [(set_attr "type" "store")])
7650 (define_insn "*tldo_sth_sp32"
7651   [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7652                                      (match_operand 3 "tld_symbolic_operand" "")]
7653                                     UNSPEC_TLSLDO)
7654                          (match_operand:SI 1 "register_operand" "r")))
7655         (match_operand:HI 0 "register_operand" "r"))]
7656   "TARGET_TLS && TARGET_ARCH32"
7657   "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7658   [(set_attr "type" "store")])
7660 (define_insn "*tldo_sth_sp64"
7661   [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7662                                      (match_operand 3 "tld_symbolic_operand" "")]
7663                                     UNSPEC_TLSLDO)
7664                          (match_operand:DI 1 "register_operand" "r")))
7665         (match_operand:HI 0 "register_operand" "r"))]
7666   "TARGET_TLS && TARGET_ARCH64"
7667   "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7668   [(set_attr "type" "store")])
7670 (define_insn "*tldo_stw_sp32"
7671   [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7672                                      (match_operand 3 "tld_symbolic_operand" "")]
7673                                     UNSPEC_TLSLDO)
7674                          (match_operand:SI 1 "register_operand" "r")))
7675         (match_operand:SI 0 "register_operand" "r"))]
7676   "TARGET_TLS && TARGET_ARCH32"
7677   "st\t%0, [%1 + %2], %%tldo_add(%3)"
7678   [(set_attr "type" "store")])
7680 (define_insn "*tldo_stw_sp64"
7681   [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7682                                      (match_operand 3 "tld_symbolic_operand" "")]
7683                                     UNSPEC_TLSLDO)
7684                          (match_operand:DI 1 "register_operand" "r")))
7685         (match_operand:SI 0 "register_operand" "r"))]
7686   "TARGET_TLS && TARGET_ARCH64"
7687   "stw\t%0, [%1 + %2], %%tldo_add(%3)"
7688   [(set_attr "type" "store")])
7690 (define_insn "*tldo_stx_sp64"
7691   [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7692                                      (match_operand 3 "tld_symbolic_operand" "")]
7693                                     UNSPEC_TLSLDO)
7694                          (match_operand:DI 1 "register_operand" "r")))
7695         (match_operand:DI 0 "register_operand" "r"))]
7696   "TARGET_TLS && TARGET_ARCH64"
7697   "stx\t%0, [%1 + %2], %%tldo_add(%3)"
7698   [(set_attr "type" "store")])
7701 ;; Stack protector instructions.
7703 (define_expand "stack_protect_set"
7704   [(match_operand 0 "memory_operand" "")
7705    (match_operand 1 "memory_operand" "")]
7706   ""
7708 #ifdef TARGET_THREAD_SSP_OFFSET
7709   rtx tlsreg = gen_rtx_REG (Pmode, 7);
7710   rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7711   operands[1] = gen_rtx_MEM (Pmode, addr);
7712 #endif
7713   if (TARGET_ARCH64)
7714     emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
7715   else
7716     emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
7717   DONE;
7720 (define_insn "stack_protect_setsi"
7721   [(set (match_operand:SI 0 "memory_operand" "=m")
7722         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7723    (set (match_scratch:SI 2 "=&r") (const_int 0))]
7724   "TARGET_ARCH32"
7725   "ld\t%1, %2\;st\t%2, %0\;mov\t0, %2"
7726   [(set_attr "type" "multi")
7727    (set_attr "length" "3")])
7729 (define_insn "stack_protect_setdi"
7730   [(set (match_operand:DI 0 "memory_operand" "=m")
7731         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
7732    (set (match_scratch:DI 2 "=&r") (const_int 0))]
7733   "TARGET_ARCH64"
7734   "ldx\t%1, %2\;stx\t%2, %0\;mov\t0, %2"
7735   [(set_attr "type" "multi")
7736    (set_attr "length" "3")])
7738 (define_expand "stack_protect_test"
7739   [(match_operand 0 "memory_operand" "")
7740    (match_operand 1 "memory_operand" "")
7741    (match_operand 2 "" "")]
7742   ""
7744   rtx result, test;
7745 #ifdef TARGET_THREAD_SSP_OFFSET
7746   rtx tlsreg = gen_rtx_REG (Pmode, 7);
7747   rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
7748   operands[1] = gen_rtx_MEM (Pmode, addr);
7749 #endif
7750   if (TARGET_ARCH64)
7751     {
7752       result = gen_reg_rtx (Pmode);
7753       emit_insn (gen_stack_protect_testdi (result, operands[0], operands[1]));
7754       test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7755       emit_jump_insn (gen_cbranchdi4 (test, result, const0_rtx, operands[2]));
7756     }
7757   else
7758     {
7759       emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
7760       result = gen_rtx_REG (CCmode, SPARC_ICC_REG);
7761       test = gen_rtx_EQ (VOIDmode, result, const0_rtx);
7762       emit_jump_insn (gen_cbranchcc4 (test, result, const0_rtx, operands[2]));
7763     }
7764   DONE;
7767 (define_insn "stack_protect_testsi"
7768   [(set (reg:CC CC_REG)
7769         (unspec:CC [(match_operand:SI 0 "memory_operand" "m")
7770                     (match_operand:SI 1 "memory_operand" "m")]
7771                    UNSPEC_SP_TEST))
7772    (set (match_scratch:SI 3 "=r") (const_int 0))
7773    (clobber (match_scratch:SI 2 "=&r"))]
7774   "TARGET_ARCH32"
7775   "ld\t%0, %2\;ld\t%1, %3\;xorcc\t%2, %3, %2\;mov\t0, %3"
7776   [(set_attr "type" "multi")
7777    (set_attr "length" "4")])
7779 (define_insn "stack_protect_testdi"
7780   [(set (match_operand:DI 0 "register_operand" "=&r")
7781         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
7782                     (match_operand:DI 2 "memory_operand" "m")]
7783                    UNSPEC_SP_TEST))
7784    (set (match_scratch:DI 3 "=r") (const_int 0))]
7785   "TARGET_ARCH64"
7786   "ldx\t%1, %0\;ldx\t%2, %3\;xor\t%0, %3, %0\;mov\t0, %3"
7787   [(set_attr "type" "multi")
7788    (set_attr "length" "4")])
7791 ;; Vector instructions.
7793 (define_mode_iterator VM32 [V1SI V2HI V4QI])
7794 (define_mode_iterator VM64 [V1DI V2SI V4HI V8QI])
7795 (define_mode_iterator VMALL [V1SI V2HI V4QI V1DI V2SI V4HI V8QI])
7797 (define_mode_attr vbits [(V2SI "32") (V4HI "16") (V1SI "32s") (V2HI "16s") (V8QI "8")])
7798 (define_mode_attr vconstr [(V1SI "f") (V2HI "f") (V4QI "f")
7799                            (V1DI "e") (V2SI "e") (V4HI "e") (V8QI "e")])
7800 (define_mode_attr vfptype [(V1SI "single") (V2HI "single") (V4QI "single")
7801                            (V1DI "double") (V2SI "double") (V4HI "double")
7802                            (V8QI "double")])
7804 (define_expand "mov<VMALL:mode>"
7805   [(set (match_operand:VMALL 0 "nonimmediate_operand" "")
7806         (match_operand:VMALL 1 "general_operand" ""))]
7807   "TARGET_VIS"
7809   if (sparc_expand_move (<VMALL:MODE>mode, operands))
7810     DONE;
7813 (define_insn "*mov<VM32:mode>_insn"
7814   [(set (match_operand:VM32 0 "nonimmediate_operand" "=f,f,f,f,m,m,*r, m,*r,*r, f")
7815         (match_operand:VM32 1 "input_operand"         "Y,Z,f,m,f,Y, m,*r,*r, f,*r"))]
7816   "TARGET_VIS
7817    && (register_operand (operands[0], <VM32:MODE>mode)
7818        || register_or_zero_or_all_ones_operand (operands[1], <VM32:MODE>mode))"
7819   "@
7820   fzeros\t%0
7821   fones\t%0
7822   fsrc2s\t%1, %0
7823   ld\t%1, %0
7824   st\t%1, %0
7825   st\t%r1, %0
7826   ld\t%1, %0
7827   st\t%1, %0
7828   mov\t%1, %0
7829   movstouw\t%1, %0
7830   movwtos\t%1, %0"
7831   [(set_attr "type" "visl,visl,vismv,fpload,fpstore,store,load,store,*,vismv,vismv")
7832    (set_attr "v3pipe" "true,true,true,false,false,false,false,false,false,true,true")
7833    (set_attr "cpu_feature" "vis,vis,vis,*,*,*,*,*,*,vis3,vis3")])
7835 (define_insn "*mov<VM64:mode>_insn_sp64"
7836   [(set (match_operand:VM64 0 "nonimmediate_operand" "=e,e,e,e,m,m,*r, m,*r, e,*r")
7837         (match_operand:VM64 1 "input_operand"         "Y,C,e,m,e,Y, m,*r, e,*r,*r"))]
7838   "TARGET_VIS
7839    && TARGET_ARCH64
7840    && (register_operand (operands[0], <VM64:MODE>mode)
7841        || register_or_zero_or_all_ones_operand (operands[1], <VM64:MODE>mode))"
7842   "@
7843   fzero\t%0
7844   fone\t%0
7845   fsrc2\t%1, %0
7846   ldd\t%1, %0
7847   std\t%1, %0
7848   stx\t%r1, %0
7849   ldx\t%1, %0
7850   stx\t%1, %0
7851   movdtox\t%1, %0
7852   movxtod\t%1, %0
7853   mov\t%1, %0"
7854   [(set_attr "type" "visl,visl,vismv,fpload,fpstore,store,load,store,vismv,vismv,*")
7855    (set_attr "v3pipe" "true, true, true, false, false, false, false, false, false, false, false")
7856    (set_attr "cpu_feature" "vis,vis,vis,*,*,*,*,*,vis3,vis3,*")])
7858 (define_insn "*mov<VM64:mode>_insn_sp32"
7859   [(set (match_operand:VM64 0 "nonimmediate_operand" "=e,e,e,*r, f,e,m,m,U,T, o,*r")
7860         (match_operand:VM64 1 "input_operand"         "Y,C,e, f,*r,m,e,Y,T,U,*r,*r"))]
7861   "TARGET_VIS
7862    && ! TARGET_ARCH64
7863    && (register_operand (operands[0], <VM64:MODE>mode)
7864        || register_or_zero_or_all_ones_operand (operands[1], <VM64:MODE>mode))"
7865   "@
7866   fzero\t%0
7867   fone\t%0
7868   fsrc2\t%1, %0
7869   #
7870   #
7871   ldd\t%1, %0
7872   std\t%1, %0
7873   stx\t%r1, %0
7874   ldd\t%1, %0
7875   std\t%1, %0
7876   #
7877   #"
7878   [(set_attr "type" "visl,visl,vismv,*,*,fpload,fpstore,store,load,store,*,*")
7879    (set_attr "v3pipe" "true, true, true, false, false, false, false, false, false, false, false, false")
7880    (set_attr "length" "*,*,*,2,2,*,*,*,*,*,2,2")
7881    (set_attr "cpu_feature" "vis,vis,vis,vis3,vis3,*,*,*,*,*,*,*")])
7883 (define_split
7884   [(set (match_operand:VM64 0 "memory_operand" "")
7885         (match_operand:VM64 1 "register_operand" ""))]
7886   "reload_completed
7887    && TARGET_VIS
7888    && ! TARGET_ARCH64
7889    && (((REGNO (operands[1]) % 2) != 0)
7890        || ! mem_min_alignment (operands[0], 8))
7891    && offsettable_memref_p (operands[0])"
7892   [(clobber (const_int 0))]
7894   rtx word0, word1;
7896   word0 = adjust_address (operands[0], SImode, 0);
7897   word1 = adjust_address (operands[0], SImode, 4);
7899   emit_move_insn_1 (word0, gen_highpart (SImode, operands[1]));
7900   emit_move_insn_1 (word1, gen_lowpart (SImode, operands[1]));
7901   DONE;
7904 (define_split
7905   [(set (match_operand:VM64 0 "register_operand" "")
7906         (match_operand:VM64 1 "register_operand" ""))]
7907   "reload_completed
7908    && TARGET_VIS
7909    && ! TARGET_ARCH64
7910    && sparc_split_regreg_legitimate (operands[0], operands[1])"
7911   [(clobber (const_int 0))]
7913   rtx set_dest = operands[0];
7914   rtx set_src = operands[1];
7915   rtx dest1, dest2;
7916   rtx src1, src2;
7918   dest1 = gen_highpart (SImode, set_dest);
7919   dest2 = gen_lowpart (SImode, set_dest);
7920   src1 = gen_highpart (SImode, set_src);
7921   src2 = gen_lowpart (SImode, set_src);
7923   /* Now emit using the real source and destination we found, swapping
7924      the order if we detect overlap.  */
7925   if (reg_overlap_mentioned_p (dest1, src2))
7926     {
7927       emit_insn (gen_movsi (dest2, src2));
7928       emit_insn (gen_movsi (dest1, src1));
7929     }
7930   else
7931     {
7932       emit_insn (gen_movsi (dest1, src1));
7933       emit_insn (gen_movsi (dest2, src2));
7934     }
7935   DONE;
7938 (define_expand "vec_init<mode>"
7939   [(match_operand:VMALL 0 "register_operand" "")
7940    (match_operand:VMALL 1 "" "")]
7941   "TARGET_VIS"
7943   sparc_expand_vector_init (operands[0], operands[1]);
7944   DONE;
7947 (define_code_iterator plusminus [plus minus])
7948 (define_code_attr plusminus_insn [(plus "add") (minus "sub")])
7950 (define_mode_iterator VADDSUB [V1SI V2SI V2HI V4HI])
7952 (define_insn "<plusminus_insn><mode>3"
7953   [(set (match_operand:VADDSUB 0 "register_operand" "=<vconstr>")
7954         (plusminus:VADDSUB (match_operand:VADDSUB 1 "register_operand" "<vconstr>")
7955                            (match_operand:VADDSUB 2 "register_operand" "<vconstr>")))]
7956   "TARGET_VIS"
7957   "fp<plusminus_insn><vbits>\t%1, %2, %0"
7958   [(set_attr "type" "fga")
7959    (set_attr "fptype" "<vfptype>")
7960    (set_attr "v3pipe" "true")])
7962 (define_mode_iterator VL [V1SI V2HI V4QI V1DI V2SI V4HI V8QI])
7963 (define_mode_attr vlsuf [(V1SI "s") (V2HI "s") (V4QI "s")
7964                          (V1DI  "") (V2SI  "") (V4HI  "") (V8QI "")])
7965 (define_code_iterator vlop [ior and xor])
7966 (define_code_attr vlinsn [(ior "or") (and "and") (xor "xor")])
7967 (define_code_attr vlninsn [(ior "nor") (and "nand") (xor "xnor")])
7969 (define_insn "<code><mode>3"
7970   [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
7971         (vlop:VL (match_operand:VL 1 "register_operand" "<vconstr>")
7972                  (match_operand:VL 2 "register_operand" "<vconstr>")))]
7973   "TARGET_VIS"
7974   "f<vlinsn><vlsuf>\t%1, %2, %0"
7975   [(set_attr "type" "visl")
7976    (set_attr "v3pipe" "true")
7977    (set_attr "fptype" "<vfptype>")])
7979 (define_insn "*not_<code><mode>3"
7980   [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
7981         (not:VL (vlop:VL (match_operand:VL 1 "register_operand" "<vconstr>")
7982                          (match_operand:VL 2 "register_operand" "<vconstr>"))))]
7983   "TARGET_VIS"
7984   "f<vlninsn><vlsuf>\t%1, %2, %0"
7985   [(set_attr "type" "visl")
7986    (set_attr "v3pipe" "true")
7987    (set_attr "fptype" "<vfptype>")])
7989 ;; (ior (not (op1)) (not (op2))) is the canonical form of NAND.
7990 (define_insn "*nand<mode>_vis"
7991   [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
7992         (ior:VL (not:VL (match_operand:VL 1 "register_operand" "<vconstr>"))
7993                 (not:VL (match_operand:VL 2 "register_operand" "<vconstr>"))))]
7994   "TARGET_VIS"
7995   "fnand<vlsuf>\t%1, %2, %0"
7996   [(set_attr "type" "visl")
7997    (set_attr "v3pipe" "true")
7998    (set_attr "fptype" "<vfptype>")])
8000 (define_code_iterator vlnotop [ior and])
8002 (define_insn "*<code>_not1<mode>_vis"
8003   [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8004         (vlnotop:VL (not:VL (match_operand:VL 1 "register_operand" "<vconstr>"))
8005                     (match_operand:VL 2 "register_operand" "<vconstr>")))]
8006   "TARGET_VIS"
8007   "f<vlinsn>not1<vlsuf>\t%1, %2, %0"
8008   [(set_attr "type" "visl")
8009    (set_attr "v3pipe" "true")
8010    (set_attr "fptype" "<vfptype>")])
8012 (define_insn "*<code>_not2<mode>_vis"
8013   [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8014         (vlnotop:VL (match_operand:VL 1 "register_operand" "<vconstr>")
8015                     (not:VL (match_operand:VL 2 "register_operand" "<vconstr>"))))]
8016   "TARGET_VIS"
8017   "f<vlinsn>not2<vlsuf>\t%1, %2, %0"
8018   [(set_attr "type" "visl")
8019    (set_attr "v3pipe" "true")
8020    (set_attr "fptype" "<vfptype>")])
8022 (define_insn "one_cmpl<mode>2"
8023   [(set (match_operand:VL 0 "register_operand" "=<vconstr>")
8024         (not:VL (match_operand:VL 1 "register_operand" "<vconstr>")))]
8025   "TARGET_VIS"
8026   "fnot1<vlsuf>\t%1, %0"
8027   [(set_attr "type" "visl")
8028    (set_attr "v3pipe" "true")
8029    (set_attr "fptype" "<vfptype>")])
8031 ;; Hard to generate VIS instructions.  We have builtins for these.
8033 (define_insn "fpack16_vis"
8034   [(set (match_operand:V4QI 0 "register_operand" "=f")
8035         (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e")
8036                       (reg:DI GSR_REG)]
8037                       UNSPEC_FPACK16))]
8038   "TARGET_VIS"
8039   "fpack16\t%1, %0"
8040   [(set_attr "type" "fgm_pack")
8041    (set_attr "fptype" "double")])
8043 (define_insn "fpackfix_vis"
8044   [(set (match_operand:V2HI 0 "register_operand" "=f")
8045         (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e")
8046                       (reg:DI GSR_REG)]
8047                       UNSPEC_FPACKFIX))]
8048   "TARGET_VIS"
8049   "fpackfix\t%1, %0"
8050   [(set_attr "type" "fgm_pack")
8051    (set_attr "fptype" "double")])
8053 (define_insn "fpack32_vis"
8054   [(set (match_operand:V8QI 0 "register_operand" "=e")
8055         (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e")
8056                       (match_operand:V8QI 2 "register_operand" "e")
8057                       (reg:DI GSR_REG)]
8058                      UNSPEC_FPACK32))]
8059   "TARGET_VIS"
8060   "fpack32\t%1, %2, %0"
8061   [(set_attr "type" "fgm_pack")
8062    (set_attr "fptype" "double")])
8064 (define_insn "fexpand_vis"
8065   [(set (match_operand:V4HI 0 "register_operand" "=e")
8066         (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")]
8067          UNSPEC_FEXPAND))]
8068  "TARGET_VIS"
8069  "fexpand\t%1, %0"
8070  [(set_attr "type" "fga")
8071   (set_attr "fptype" "double")])
8073 (define_insn "fpmerge_vis"
8074   [(set (match_operand:V8QI 0 "register_operand" "=e")
8075         (vec_select:V8QI
8076           (vec_concat:V8QI (match_operand:V4QI 1 "register_operand" "f")
8077                            (match_operand:V4QI 2 "register_operand" "f"))
8078           (parallel [(const_int 0) (const_int 4)
8079                      (const_int 1) (const_int 5)
8080                      (const_int 2) (const_int 6)
8081                      (const_int 3) (const_int 7)])))]
8082  "TARGET_VIS"
8083  "fpmerge\t%1, %2, %0"
8084  [(set_attr "type" "fga")
8085   (set_attr "fptype" "double")])
8087 (define_insn "vec_interleave_lowv8qi"
8088   [(set (match_operand:V8QI 0 "register_operand" "=e")
8089         (vec_select:V8QI
8090           (vec_concat:V16QI (match_operand:V8QI 1 "register_operand" "f")
8091                             (match_operand:V8QI 2 "register_operand" "f"))
8092           (parallel [(const_int 0) (const_int 8)
8093                      (const_int 1) (const_int 9)
8094                      (const_int 2) (const_int 10)
8095                      (const_int 3) (const_int 11)])))]
8096  "TARGET_VIS"
8097  "fpmerge\t%L1, %L2, %0"
8098  [(set_attr "type" "fga")
8099   (set_attr "fptype" "double")])
8101 (define_insn "vec_interleave_highv8qi"
8102   [(set (match_operand:V8QI 0 "register_operand" "=e")
8103         (vec_select:V8QI
8104           (vec_concat:V16QI (match_operand:V8QI 1 "register_operand" "f")
8105                             (match_operand:V8QI 2 "register_operand" "f"))
8106           (parallel [(const_int 4) (const_int 12)
8107                      (const_int 5) (const_int 13)
8108                      (const_int 6) (const_int 14)
8109                      (const_int 7) (const_int 15)])))]
8110  "TARGET_VIS"
8111  "fpmerge\t%H1, %H2, %0"
8112  [(set_attr "type" "fga")
8113   (set_attr "fptype" "double")])
8115 ;; Partitioned multiply instructions
8116 (define_insn "fmul8x16_vis"
8117   [(set (match_operand:V4HI 0 "register_operand" "=e")
8118         (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8119                       (match_operand:V4HI 2 "register_operand" "e")]
8120          UNSPEC_MUL8))]
8121   "TARGET_VIS"
8122   "fmul8x16\t%1, %2, %0"
8123   [(set_attr "type" "fgm_mul")
8124    (set_attr "fptype" "double")])
8126 (define_insn "fmul8x16au_vis"
8127   [(set (match_operand:V4HI 0 "register_operand" "=e")
8128         (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8129                       (match_operand:V2HI 2 "register_operand" "f")]
8130          UNSPEC_MUL16AU))]
8131   "TARGET_VIS"
8132   "fmul8x16au\t%1, %2, %0"
8133   [(set_attr "type" "fgm_mul")
8134    (set_attr "fptype" "double")])
8136 (define_insn "fmul8x16al_vis"
8137   [(set (match_operand:V4HI 0 "register_operand" "=e")
8138         (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8139                       (match_operand:V2HI 2 "register_operand" "f")]
8140          UNSPEC_MUL16AL))]
8141   "TARGET_VIS"
8142   "fmul8x16al\t%1, %2, %0"
8143   [(set_attr "type" "fgm_mul")
8144    (set_attr "fptype" "double")])
8146 (define_insn "fmul8sux16_vis"
8147   [(set (match_operand:V4HI 0 "register_operand" "=e")
8148         (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
8149                       (match_operand:V4HI 2 "register_operand" "e")]
8150          UNSPEC_MUL8SU))]
8151   "TARGET_VIS"
8152   "fmul8sux16\t%1, %2, %0"
8153   [(set_attr "type" "fgm_mul")
8154    (set_attr "fptype" "double")])
8156 (define_insn "fmul8ulx16_vis"
8157   [(set (match_operand:V4HI 0 "register_operand" "=e")
8158         (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
8159                       (match_operand:V4HI 2 "register_operand" "e")]
8160          UNSPEC_MUL8UL))]
8161   "TARGET_VIS"
8162   "fmul8ulx16\t%1, %2, %0"
8163   [(set_attr "type" "fgm_mul")
8164    (set_attr "fptype" "double")])
8166 (define_insn "fmuld8sux16_vis"
8167   [(set (match_operand:V2SI 0 "register_operand" "=e")
8168         (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
8169                       (match_operand:V2HI 2 "register_operand" "f")]
8170          UNSPEC_MULDSU))]
8171   "TARGET_VIS"
8172   "fmuld8sux16\t%1, %2, %0"
8173   [(set_attr "type" "fgm_mul")
8174    (set_attr "fptype" "double")])
8176 (define_insn "fmuld8ulx16_vis"
8177   [(set (match_operand:V2SI 0 "register_operand" "=e")
8178         (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
8179                       (match_operand:V2HI 2 "register_operand" "f")]
8180          UNSPEC_MULDUL))]
8181   "TARGET_VIS"
8182   "fmuld8ulx16\t%1, %2, %0"
8183   [(set_attr "type" "fgm_mul")
8184    (set_attr "fptype" "double")])
8186 (define_expand "wrgsr_vis"
8187   [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" ""))]
8188   "TARGET_VIS"
8190   if (! TARGET_ARCH64)
8191     {
8192       emit_insn (gen_wrgsr_v8plus (operands[0]));
8193       DONE;
8194     }
8197 (define_insn "*wrgsr_sp64"
8198   [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" "rI"))]
8199   "TARGET_VIS && TARGET_ARCH64"
8200   "wr\t%%g0, %0, %%gsr"
8201   [(set_attr "type" "gsr")])
8203 (define_insn "wrgsr_v8plus"
8204   [(set (reg:DI GSR_REG) (match_operand:DI 0 "arith_operand" "I,r"))
8205    (clobber (match_scratch:SI 1 "=X,&h"))]
8206   "TARGET_VIS && ! TARGET_ARCH64"
8208   if (GET_CODE (operands[0]) == CONST_INT
8209       || sparc_check_64 (operands[0], insn))
8210     return "wr\t%%g0, %0, %%gsr";
8212   output_asm_insn("srl\t%L0, 0, %L0", operands);
8213   return "sllx\t%H0, 32, %1\n\tor\t%L0, %1, %1\n\twr\t%%g0, %1, %%gsr";
8215   [(set_attr "type" "multi")])
8217 (define_expand "rdgsr_vis"
8218   [(set (match_operand:DI 0 "register_operand" "") (reg:DI GSR_REG))]
8219   "TARGET_VIS"
8221   if (! TARGET_ARCH64)
8222     {
8223       emit_insn (gen_rdgsr_v8plus (operands[0]));
8224       DONE;
8225     }
8228 (define_insn "*rdgsr_sp64"
8229   [(set (match_operand:DI 0 "register_operand" "=r") (reg:DI GSR_REG))]
8230   "TARGET_VIS && TARGET_ARCH64"
8231   "rd\t%%gsr, %0"
8232   [(set_attr "type" "gsr")])
8234 (define_insn "rdgsr_v8plus"
8235   [(set (match_operand:DI 0 "register_operand" "=r") (reg:DI GSR_REG))
8236    (clobber (match_scratch:SI 1 "=&h"))]
8237   "TARGET_VIS && ! TARGET_ARCH64"
8239   return "rd\t%%gsr, %1\n\tsrlx\t%1, 32, %H0\n\tmov %1, %L0";
8241   [(set_attr "type" "multi")])
8243 ;; Using faligndata only makes sense after an alignaddr since the choice of
8244 ;; bytes to take out of each operand is dependent on the results of the last
8245 ;; alignaddr.
8246 (define_insn "faligndata<VM64:mode>_vis"
8247   [(set (match_operand:VM64 0 "register_operand" "=e")
8248         (unspec:VM64 [(match_operand:VM64 1 "register_operand" "e")
8249                       (match_operand:VM64 2 "register_operand" "e")
8250                       (reg:DI GSR_REG)]
8251          UNSPEC_ALIGNDATA))]
8252   "TARGET_VIS"
8253   "faligndata\t%1, %2, %0"
8254   [(set_attr "type" "fga")
8255    (set_attr "fptype" "double")
8256    (set_attr "v3pipe" "true")])
8258 (define_insn "alignaddrsi_vis"
8259   [(set (match_operand:SI 0 "register_operand" "=r")
8260         (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
8261                  (match_operand:SI 2 "register_or_zero_operand" "rJ")))
8262    (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8263         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
8264   "TARGET_VIS"
8265   "alignaddr\t%r1, %r2, %0"
8266   [(set_attr "type" "gsr")
8267    (set_attr "v3pipe" "true")])
8269 (define_insn "alignaddrdi_vis"
8270   [(set (match_operand:DI 0 "register_operand" "=r")
8271         (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
8272                  (match_operand:DI 2 "register_or_zero_operand" "rJ")))
8273    (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8274         (plus:DI (match_dup 1) (match_dup 2)))]
8275   "TARGET_VIS"
8276   "alignaddr\t%r1, %r2, %0"
8277   [(set_attr "type" "gsr")
8278    (set_attr "v3pipe" "true")])
8280 (define_insn "alignaddrlsi_vis"
8281   [(set (match_operand:SI 0 "register_operand" "=r")
8282         (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
8283                  (match_operand:SI 2 "register_or_zero_operand" "rJ")))
8284    (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8285         (xor:DI (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2)))
8286                 (const_int 7)))]
8287   "TARGET_VIS"
8288   "alignaddrl\t%r1, %r2, %0"
8289   [(set_attr "type" "gsr")
8290    (set_attr "v3pipe" "true")])
8292 (define_insn "alignaddrldi_vis"
8293   [(set (match_operand:DI 0 "register_operand" "=r")
8294         (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
8295                  (match_operand:DI 2 "register_or_zero_operand" "rJ")))
8296    (set (zero_extract:DI (reg:DI GSR_REG) (const_int 3) (const_int 0))
8297         (xor:DI (plus:DI (match_dup 1) (match_dup 2))
8298                 (const_int 7)))]
8299   "TARGET_VIS"
8300   "alignaddrl\t%r1, %r2, %0"
8301   [(set_attr "type" "gsr")
8302    (set_attr "v3pipe" "true")])
8304 (define_insn "pdist_vis"
8305   [(set (match_operand:DI 0 "register_operand" "=e")
8306         (unspec:DI [(match_operand:V8QI 1 "register_operand" "e")
8307                     (match_operand:V8QI 2 "register_operand" "e")
8308                     (match_operand:DI 3 "register_operand" "0")]
8309          UNSPEC_PDIST))]
8310   "TARGET_VIS"
8311   "pdist\t%1, %2, %0"
8312   [(set_attr "type" "pdist")
8313    (set_attr "fptype" "double")])
8315 ;; Edge instructions produce condition codes equivalent to a 'subcc'
8316 ;; with the same operands.
8317 (define_insn "edge8<P:mode>_vis"
8318   [(set (reg:CC_NOOV CC_REG)
8319         (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8320                                   (match_operand:P 2 "register_or_zero_operand" "rJ"))
8321                          (const_int 0)))
8322    (set (match_operand:P 0 "register_operand" "=r")
8323         (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8))]
8324   "TARGET_VIS"
8325   "edge8\t%r1, %r2, %0"
8326   [(set_attr "type" "edge")])
8328 (define_insn "edge8l<P:mode>_vis"
8329   [(set (reg:CC_NOOV CC_REG)
8330         (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8331                                   (match_operand:P 2 "register_or_zero_operand" "rJ"))
8332                          (const_int 0)))
8333    (set (match_operand:P 0 "register_operand" "=r")
8334         (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE8L))]
8335   "TARGET_VIS"
8336   "edge8l\t%r1, %r2, %0"
8337   [(set_attr "type" "edge")])
8339 (define_insn "edge16<P:mode>_vis"
8340   [(set (reg:CC_NOOV CC_REG)
8341         (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8342                                   (match_operand:P 2 "register_or_zero_operand" "rJ"))
8343                          (const_int 0)))
8344    (set (match_operand:P 0 "register_operand" "=r")
8345         (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16))]
8346   "TARGET_VIS"
8347   "edge16\t%r1, %r2, %0"
8348   [(set_attr "type" "edge")])
8350 (define_insn "edge16l<P:mode>_vis"
8351   [(set (reg:CC_NOOV CC_REG)
8352         (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8353                                   (match_operand:P 2 "register_or_zero_operand" "rJ"))
8354                          (const_int 0)))
8355    (set (match_operand:P 0 "register_operand" "=r")
8356         (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE16L))]
8357   "TARGET_VIS"
8358   "edge16l\t%r1, %r2, %0"
8359   [(set_attr "type" "edge")])
8361 (define_insn "edge32<P:mode>_vis"
8362   [(set (reg:CC_NOOV CC_REG)
8363         (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8364                                   (match_operand:P 2 "register_or_zero_operand" "rJ"))
8365                          (const_int 0)))
8366    (set (match_operand:P 0 "register_operand" "=r")
8367         (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32))]
8368   "TARGET_VIS"
8369   "edge32\t%r1, %r2, %0"
8370   [(set_attr "type" "edge")])
8372 (define_insn "edge32l<P:mode>_vis"
8373   [(set (reg:CC_NOOV CC_REG)
8374         (compare:CC_NOOV (minus:P (match_operand:P 1 "register_or_zero_operand" "rJ")
8375                                   (match_operand:P 2 "register_or_zero_operand" "rJ"))
8376                          (const_int 0)))
8377    (set (match_operand:P 0 "register_operand" "=r")
8378         (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_EDGE32L))]
8379   "TARGET_VIS"
8380   "edge32l\t%r1, %r2, %0"
8381   [(set_attr "type" "edge")])
8383 (define_code_iterator gcond [le ne gt eq])
8384 (define_mode_iterator GCM [V4HI V2SI])
8385 (define_mode_attr gcm_name [(V4HI "16") (V2SI "32")])
8387 (define_insn "fcmp<code><GCM:gcm_name><P:mode>_vis"
8388   [(set (match_operand:P 0 "register_operand" "=r")
8389         (unspec:P [(gcond:GCM (match_operand:GCM 1 "register_operand" "e")
8390                               (match_operand:GCM 2 "register_operand" "e"))]
8391          UNSPEC_FCMP))]
8392   "TARGET_VIS"
8393   "fcmp<code><GCM:gcm_name>\t%1, %2, %0"
8394   [(set_attr "type" "visl")
8395    (set_attr "v3pipe" "true")
8396    (set_attr "fptype" "double")])
8398 (define_insn "fpcmp<code>8<P:mode>_vis"
8399   [(set (match_operand:P 0 "register_operand" "=r")
8400         (unspec:P [(gcond:V8QI (match_operand:V8QI 1 "register_operand" "e")
8401                                (match_operand:V8QI 2 "register_operand" "e"))]
8402          UNSPEC_FCMP))]
8403   "TARGET_VIS4"
8404   "fpcmp<code>8\t%1, %2, %0"
8405   [(set_attr "type" "visl")
8406    (set_attr "fptype" "double")])
8408 (define_expand "vcond<mode><mode>"
8409   [(match_operand:GCM 0 "register_operand" "")
8410    (match_operand:GCM 1 "register_operand" "")
8411    (match_operand:GCM 2 "register_operand" "")
8412    (match_operator 3 ""
8413      [(match_operand:GCM 4 "register_operand" "")
8414       (match_operand:GCM 5 "register_operand" "")])]
8415   "TARGET_VIS3"
8417   sparc_expand_vcond (<MODE>mode, operands,
8418                       UNSPEC_CMASK<gcm_name>,
8419                       UNSPEC_FCMP);
8420   DONE;
8423 (define_expand "vconduv8qiv8qi"
8424   [(match_operand:V8QI 0 "register_operand" "")
8425    (match_operand:V8QI 1 "register_operand" "")
8426    (match_operand:V8QI 2 "register_operand" "")
8427    (match_operator 3 ""
8428      [(match_operand:V8QI 4 "register_operand" "")
8429       (match_operand:V8QI 5 "register_operand" "")])]
8430   "TARGET_VIS3"
8432   sparc_expand_vcond (V8QImode, operands,
8433                       UNSPEC_CMASK8,
8434                       UNSPEC_FUCMP);
8435   DONE;
8438 (define_insn "array8<P:mode>_vis"
8439   [(set (match_operand:P 0 "register_operand" "=r")
8440         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8441                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
8442                   UNSPEC_ARRAY8))]
8443   "TARGET_VIS"
8444   "array8\t%r1, %r2, %0"
8445   [(set_attr "type" "array")])
8447 (define_insn "array16<P:mode>_vis"
8448   [(set (match_operand:P 0 "register_operand" "=r")
8449         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8450                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
8451                   UNSPEC_ARRAY16))]
8452   "TARGET_VIS"
8453   "array16\t%r1, %r2, %0"
8454   [(set_attr "type" "array")])
8456 (define_insn "array32<P:mode>_vis"
8457   [(set (match_operand:P 0 "register_operand" "=r")
8458         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8459                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
8460                   UNSPEC_ARRAY32))]
8461   "TARGET_VIS"
8462   "array32\t%r1, %r2, %0"
8463   [(set_attr "type" "array")])
8465 (define_insn "bmaskdi_vis"
8466   [(set (match_operand:DI 0 "register_operand" "=r")
8467         (plus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
8468                  (match_operand:DI 2 "register_or_zero_operand" "rJ")))
8469    (set (zero_extract:DI (reg:DI GSR_REG) (const_int 32) (const_int 32))
8470         (plus:DI (match_dup 1) (match_dup 2)))]
8471   "TARGET_VIS2"
8472   "bmask\t%r1, %r2, %0"
8473   [(set_attr "type" "array")
8474    (set_attr "v3pipe" "true")])
8476 (define_insn "bmasksi_vis"
8477   [(set (match_operand:SI 0 "register_operand" "=r")
8478         (plus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
8479                  (match_operand:SI 2 "register_or_zero_operand" "rJ")))
8480    (set (zero_extract:DI (reg:DI GSR_REG) (const_int 32) (const_int 32))
8481         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
8482   "TARGET_VIS2"
8483   "bmask\t%r1, %r2, %0"
8484   [(set_attr "type" "array")
8485    (set_attr "v3pipe" "true")])
8487 (define_insn "bshuffle<VM64:mode>_vis"
8488   [(set (match_operand:VM64 0 "register_operand" "=e")
8489         (unspec:VM64 [(match_operand:VM64 1 "register_operand" "e")
8490                       (match_operand:VM64 2 "register_operand" "e")
8491                       (reg:DI GSR_REG)]
8492                      UNSPEC_BSHUFFLE))]
8493   "TARGET_VIS2"
8494   "bshuffle\t%1, %2, %0"
8495   [(set_attr "type" "fga")
8496    (set_attr "fptype" "double")
8497    (set_attr "v3pipe" "true")])
8499 ;; The rtl expanders will happily convert constant permutations on other
8500 ;; modes down to V8QI.  Rely on this to avoid the complexity of the byte
8501 ;; order of the permutation.
8502 (define_expand "vec_perm_constv8qi"
8503   [(match_operand:V8QI 0 "register_operand" "")
8504    (match_operand:V8QI 1 "register_operand" "")
8505    (match_operand:V8QI 2 "register_operand" "")
8506    (match_operand:V8QI 3 "" "")]
8507   "TARGET_VIS2"
8509   unsigned int i, mask;
8510   rtx sel = operands[3];
8512   for (i = mask = 0; i < 8; ++i)
8513     mask |= (INTVAL (XVECEXP (sel, 0, i)) & 0xf) << (28 - i*4);
8514   sel = force_reg (SImode, gen_int_mode (mask, SImode));
8516   emit_insn (gen_bmasksi_vis (gen_rtx_REG (SImode, 0), sel, const0_rtx));
8517   emit_insn (gen_bshufflev8qi_vis (operands[0], operands[1], operands[2]));
8518   DONE;
8521 ;; Unlike constant permutation, we can vastly simplify the compression of
8522 ;; the 64-bit selector input to the 32-bit %gsr value by knowing what the
8523 ;; width of the input is.
8524 (define_expand "vec_perm<mode>"
8525   [(match_operand:VM64 0 "register_operand" "")
8526    (match_operand:VM64 1 "register_operand" "")
8527    (match_operand:VM64 2 "register_operand" "")
8528    (match_operand:VM64 3 "register_operand" "")]
8529   "TARGET_VIS2"
8531   sparc_expand_vec_perm_bmask (<MODE>mode, operands[3]);
8532   emit_insn (gen_bshuffle<mode>_vis (operands[0], operands[1], operands[2]));
8533   DONE;
8536 ;; VIS 2.0 adds edge variants which do not set the condition codes
8537 (define_insn "edge8n<P:mode>_vis"
8538   [(set (match_operand:P 0 "register_operand" "=r")
8539         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8540                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
8541                   UNSPEC_EDGE8N))]
8542   "TARGET_VIS2"
8543   "edge8n\t%r1, %r2, %0"
8544   [(set_attr "type" "edgen")])
8546 (define_insn "edge8ln<P:mode>_vis"
8547   [(set (match_operand:P 0 "register_operand" "=r")
8548         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8549                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
8550                   UNSPEC_EDGE8LN))]
8551   "TARGET_VIS2"
8552   "edge8ln\t%r1, %r2, %0"
8553   [(set_attr "type" "edgen")])
8555 (define_insn "edge16n<P:mode>_vis"
8556   [(set (match_operand:P 0 "register_operand" "=r")
8557         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8558                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
8559                   UNSPEC_EDGE16N))]
8560   "TARGET_VIS2"
8561   "edge16n\t%r1, %r2, %0"
8562   [(set_attr "type" "edgen")])
8564 (define_insn "edge16ln<P:mode>_vis"
8565   [(set (match_operand:P 0 "register_operand" "=r")
8566         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8567                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
8568                   UNSPEC_EDGE16LN))]
8569   "TARGET_VIS2"
8570   "edge16ln\t%r1, %r2, %0"
8571   [(set_attr "type" "edgen")])
8573 (define_insn "edge32n<P:mode>_vis"
8574   [(set (match_operand:P 0 "register_operand" "=r")
8575         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8576                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
8577                   UNSPEC_EDGE32N))]
8578   "TARGET_VIS2"
8579   "edge32n\t%r1, %r2, %0"
8580   [(set_attr "type" "edgen")])
8582 (define_insn "edge32ln<P:mode>_vis"
8583   [(set (match_operand:P 0 "register_operand" "=r")
8584         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8585                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
8586                   UNSPEC_EDGE32LN))]
8587   "TARGET_VIS2"
8588   "edge32ln\t%r1, %r2, %0"
8589   [(set_attr "type" "edge")])
8591 ;; Conditional moves are possible via fcmpX --> cmaskX -> bshuffle
8592 (define_insn "cmask8<P:mode>_vis"
8593   [(set (reg:DI GSR_REG)
8594         (unspec:DI [(match_operand:P 0 "register_or_zero_operand" "rJ")
8595                     (reg:DI GSR_REG)]
8596                    UNSPEC_CMASK8))]
8597   "TARGET_VIS3"
8598   "cmask8\t%r0"
8599   [(set_attr "type" "fga")
8600    (set_attr "v3pipe" "true")])
8602 (define_insn "cmask16<P:mode>_vis"
8603   [(set (reg:DI GSR_REG)
8604         (unspec:DI [(match_operand:P 0 "register_or_zero_operand" "rJ")
8605                     (reg:DI GSR_REG)]
8606                    UNSPEC_CMASK16))]
8607   "TARGET_VIS3"
8608   "cmask16\t%r0"
8609   [(set_attr "type" "fga")
8610    (set_attr "v3pipe" "true")])
8612 (define_insn "cmask32<P:mode>_vis"
8613   [(set (reg:DI GSR_REG)
8614         (unspec:DI [(match_operand:P 0 "register_or_zero_operand" "rJ")
8615                     (reg:DI GSR_REG)]
8616                    UNSPEC_CMASK32))]
8617   "TARGET_VIS3"
8618   "cmask32\t%r0"
8619   [(set_attr "type" "fga")
8620    (set_attr "v3pipe" "true")])
8622 (define_insn "fchksm16_vis"
8623   [(set (match_operand:V4HI 0 "register_operand" "=e")
8624         (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "e")
8625                       (match_operand:V4HI 2 "register_operand" "e")]
8626                      UNSPEC_FCHKSM16))]
8627   "TARGET_VIS3"
8628   "fchksm16\t%1, %2, %0"
8629   [(set_attr "type" "fga")])
8631 (define_code_iterator vis3_shift [ashift ss_ashift lshiftrt ashiftrt])
8632 (define_code_attr vis3_shift_insn
8633   [(ashift "fsll") (ss_ashift "fslas") (lshiftrt "fsrl") (ashiftrt "fsra")])
8634 (define_code_attr vis3_shift_patname
8635   [(ashift "ashl") (ss_ashift "ssashl") (lshiftrt "lshr") (ashiftrt "ashr")])
8636    
8637 (define_insn "v<vis3_shift_patname><mode>3"
8638   [(set (match_operand:GCM 0 "register_operand" "=<vconstr>")
8639         (vis3_shift:GCM (match_operand:GCM 1 "register_operand" "<vconstr>")
8640                         (match_operand:GCM 2 "register_operand" "<vconstr>")))]
8641   "TARGET_VIS3"
8642   "<vis3_shift_insn><vbits>\t%1, %2, %0"
8643   [(set_attr "type" "fga")])
8645 (define_insn "pdistn<mode>_vis"
8646   [(set (match_operand:P 0 "register_operand" "=r")
8647         (unspec:P [(match_operand:V8QI 1 "register_operand" "e")
8648                    (match_operand:V8QI 2 "register_operand" "e")]
8649          UNSPEC_PDISTN))]
8650   "TARGET_VIS3"
8651   "pdistn\t%1, %2, %0"
8652   [(set_attr "type" "pdistn")
8653    (set_attr "v3pipe" "true")
8654    (set_attr "fptype" "double")])
8656 (define_insn "fmean16_vis"
8657   [(set (match_operand:V4HI 0 "register_operand" "=e")
8658         (truncate:V4HI
8659           (lshiftrt:V4SI
8660             (plus:V4SI
8661               (plus:V4SI
8662                 (zero_extend:V4SI
8663                   (match_operand:V4HI 1 "register_operand" "e"))
8664                 (zero_extend:V4SI
8665                   (match_operand:V4HI 2 "register_operand" "e")))
8666               (const_vector:V4SI [(const_int 1) (const_int 1)
8667                                   (const_int 1) (const_int 1)]))
8668           (const_int 1))))]
8669   "TARGET_VIS3"
8670   "fmean16\t%1, %2, %0"
8671   [(set_attr "type" "fga")])
8673 (define_insn "fp<plusminus_insn>64_vis"
8674   [(set (match_operand:V1DI 0 "register_operand" "=e")
8675         (plusminus:V1DI (match_operand:V1DI 1 "register_operand" "e")
8676                         (match_operand:V1DI 2 "register_operand" "e")))]
8677   "TARGET_VIS3"
8678   "fp<plusminus_insn>64\t%1, %2, %0"
8679   [(set_attr "type" "fga")])
8681 (define_insn "<plusminus_insn>v8qi3"
8682   [(set (match_operand:V8QI 0 "register_operand" "=e")
8683         (plusminus:V8QI (match_operand:V8QI 1 "register_operand" "e")
8684                         (match_operand:V8QI 2 "register_operand" "e")))]
8685   "TARGET_VIS4"
8686   "fp<plusminus_insn>8\t%1, %2, %0"
8687   [(set_attr "type" "fga")])
8689 (define_mode_iterator VASS [V4HI V2SI V2HI V1SI])
8690 (define_code_iterator vis3_addsub_ss [ss_plus ss_minus])
8691 (define_code_attr vis3_addsub_ss_insn
8692   [(ss_plus "fpadds") (ss_minus "fpsubs")])
8693 (define_code_attr vis3_addsub_ss_patname
8694   [(ss_plus "ssadd") (ss_minus "sssub")])
8696 (define_insn "<vis3_addsub_ss_patname><mode>3"
8697   [(set (match_operand:VASS 0 "register_operand" "=<vconstr>")
8698         (vis3_addsub_ss:VASS (match_operand:VASS 1 "register_operand" "<vconstr>")
8699                              (match_operand:VASS 2 "register_operand" "<vconstr>")))]
8700   "TARGET_VIS3"
8701   "<vis3_addsub_ss_insn><vbits>\t%1, %2, %0"
8702   [(set_attr "type" "fga")
8703    (set_attr "v3pipe" "true")])
8705 (define_mode_iterator VMMAX [V8QI V4HI V2SI])
8706 (define_code_iterator vis4_minmax [smin smax])
8707 (define_code_attr vis4_minmax_insn
8708   [(smin "fpmin") (smax "fpmax")])
8709 (define_code_attr vis4_minmax_patname
8710   [(smin "min") (smax "max")])
8712 (define_insn "<vis4_minmax_patname><mode>3"
8713   [(set (match_operand:VMMAX 0 "register_operand" "=<vconstr>")
8714         (vis4_minmax:VMMAX (match_operand:VMMAX 1 "register_operand" "<vconstr>")
8715                            (match_operand:VMMAX 2 "register_operand" "<vconstr>")))]
8716   "TARGET_VIS4"
8717   "<vis4_minmax_insn><vbits>\t%1, %2, %0"
8718   [(set_attr "type" "fga")])
8720 (define_code_iterator vis4_uminmax [umin umax])
8721 (define_code_attr vis4_uminmax_insn
8722   [(umin "fpminu") (umax "fpmaxu")])
8723 (define_code_attr vis4_uminmax_patname
8724  [(umin "minu") (umax "maxu")])
8726 (define_insn "<vis4_uminmax_patname><mode>3"
8727   [(set (match_operand:VMMAX 0 "register_operand" "=<vconstr>")
8728         (vis4_uminmax:VMMAX (match_operand:VMMAX 1 "register_operand" "<vconstr>")
8729                             (match_operand:VMMAX 2 "register_operand" "<vconstr>")))]
8730   "TARGET_VIS4"
8731   "<vis4_uminmax_insn><vbits>\t%1, %2, %0"
8732   [(set_attr "type" "fga")])
8734 ;; The use of vis3_addsub_ss_patname in the VIS4 instruction below is
8735 ;; intended.
8736 (define_insn "<vis3_addsub_ss_patname>v8qi3"
8737   [(set (match_operand:V8QI 0 "register_operand" "=e")
8738         (vis3_addsub_ss:V8QI (match_operand:V8QI 1 "register_operand" "e")
8739                              (match_operand:V8QI 2 "register_operand" "e")))]
8740   "TARGET_VIS4"
8741   "<vis3_addsub_ss_insn>8\t%1, %2, %0"
8742   [(set_attr "type" "fga")])
8744 (define_mode_iterator VAUS [V4HI V8QI])
8745 (define_code_iterator vis4_addsub_us [us_plus us_minus])
8746 (define_code_attr vis4_addsub_us_insn
8747   [(us_plus "fpaddus") (us_minus "fpsubus")])
8748 (define_code_attr vis4_addsub_us_patname
8749   [(us_plus "usadd") (us_minus "ussub")])
8751 (define_insn "<vis4_addsub_us_patname><mode>3"
8752  [(set (match_operand:VAUS 0 "register_operand" "=<vconstr>")
8753        (vis4_addsub_us:VAUS (match_operand:VAUS 1 "register_operand" "<vconstr>")
8754                             (match_operand:VAUS 2 "register_operand" "<vconstr>")))]
8755  "TARGET_VIS4"
8756  "<vis4_addsub_us_insn><vbits>\t%1, %2, %0"
8757  [(set_attr "type" "fga")])
8759 (define_insn "fucmp<code>8<P:mode>_vis"
8760   [(set (match_operand:P 0 "register_operand" "=r")
8761         (unspec:P [(gcond:V8QI (match_operand:V8QI 1 "register_operand" "e")
8762                                (match_operand:V8QI 2 "register_operand" "e"))]
8763          UNSPEC_FUCMP))]
8764   "TARGET_VIS3"
8765   "fucmp<code>8\t%1, %2, %0"
8766   [(set_attr "type" "visl")
8767    (set_attr "v3pipe" "true")])
8769 (define_insn "fpcmpu<code><GCM:gcm_name><P:mode>_vis"
8770   [(set (match_operand:P 0 "register_operand" "=r")
8771         (unspec:P [(gcond:GCM (match_operand:GCM 1 "register_operand" "e")
8772                               (match_operand:GCM 2 "register_operand" "e"))]
8773          UNSPEC_FUCMP))]
8774   "TARGET_VIS4"
8775   "fpcmpu<code><GCM:gcm_name>\t%1, %2, %0"
8776   [(set_attr "type" "visl")
8777    (set_attr "fptype" "double")])
8779 (define_insn "*naddsf3"
8780   [(set (match_operand:SF 0 "register_operand" "=f")
8781         (neg:SF (plus:SF (match_operand:SF 1 "register_operand" "f")
8782                          (match_operand:SF 2 "register_operand" "f"))))]
8783   "TARGET_VIS3"
8784   "fnadds\t%1, %2, %0"
8785   [(set_attr "type" "fp")])
8787 (define_insn "*nadddf3"
8788   [(set (match_operand:DF 0 "register_operand" "=e")
8789         (neg:DF (plus:DF (match_operand:DF 1 "register_operand" "e")
8790                          (match_operand:DF 2 "register_operand" "e"))))]
8791   "TARGET_VIS3"
8792   "fnaddd\t%1, %2, %0"
8793   [(set_attr "type" "fp")
8794    (set_attr "fptype" "double")])
8796 (define_insn "*nmulsf3"
8797   [(set (match_operand:SF 0 "register_operand" "=f")
8798         (mult:SF (neg:SF (match_operand:SF 1 "register_operand" "f"))
8799                  (match_operand:SF 2 "register_operand" "f")))]
8800   "TARGET_VIS3"
8801   "fnmuls\t%1, %2, %0"
8802   [(set_attr "type" "fpmul")])
8804 (define_insn "*nmuldf3"
8805   [(set (match_operand:DF 0 "register_operand" "=e")
8806         (mult:DF (neg:DF (match_operand:DF 1 "register_operand" "e"))
8807                  (match_operand:DF 2 "register_operand" "e")))]
8808   "TARGET_VIS3"
8809   "fnmuld\t%1, %2, %0"
8810   [(set_attr "type" "fpmul")
8811    (set_attr "fptype" "double")])
8813 (define_insn "*nmuldf3_extend"
8814   [(set (match_operand:DF 0 "register_operand" "=e")
8815         (mult:DF (neg:DF (float_extend:DF
8816                            (match_operand:SF 1 "register_operand" "f")))
8817                  (float_extend:DF
8818                    (match_operand:SF 2 "register_operand" "f"))))]
8819   "TARGET_VIS3"
8820   "fnsmuld\t%1, %2, %0"
8821   [(set_attr "type" "fpmul")
8822    (set_attr "fptype" "double")])
8824 (define_insn "fhaddsf_vis"
8825   [(set (match_operand:SF 0 "register_operand" "=f")
8826         (unspec:SF [(match_operand:SF 1 "register_operand" "f")
8827                     (match_operand:SF 2 "register_operand" "f")]
8828                    UNSPEC_FHADD))]
8829   "TARGET_VIS3"
8830   "fhadds\t%1, %2, %0"
8831   [(set_attr "type" "fp")])
8833 (define_insn "fhadddf_vis"
8834   [(set (match_operand:DF 0 "register_operand" "=f")
8835         (unspec:DF [(match_operand:DF 1 "register_operand" "f")
8836                     (match_operand:DF 2 "register_operand" "f")]
8837                    UNSPEC_FHADD))]
8838   "TARGET_VIS3"
8839   "fhaddd\t%1, %2, %0"
8840   [(set_attr "type" "fp")
8841    (set_attr "fptype" "double")])
8843 (define_insn "fhsubsf_vis"
8844   [(set (match_operand:SF 0 "register_operand" "=f")
8845         (unspec:SF [(match_operand:SF 1 "register_operand" "f")
8846                     (match_operand:SF 2 "register_operand" "f")]
8847                    UNSPEC_FHSUB))]
8848   "TARGET_VIS3"
8849   "fhsubs\t%1, %2, %0"
8850   [(set_attr "type" "fp")])
8852 (define_insn "fhsubdf_vis"
8853   [(set (match_operand:DF 0 "register_operand" "=f")
8854         (unspec:DF [(match_operand:DF 1 "register_operand" "f")
8855                     (match_operand:DF 2 "register_operand" "f")]
8856                    UNSPEC_FHSUB))]
8857   "TARGET_VIS3"
8858   "fhsubd\t%1, %2, %0"
8859   [(set_attr "type" "fp")
8860    (set_attr "fptype" "double")])
8862 (define_insn "fnhaddsf_vis"
8863   [(set (match_operand:SF 0 "register_operand" "=f")
8864         (neg:SF (unspec:SF [(match_operand:SF 1 "register_operand" "f")
8865                             (match_operand:SF 2 "register_operand" "f")]
8866                            UNSPEC_FHADD)))]
8867   "TARGET_VIS3"
8868   "fnhadds\t%1, %2, %0"
8869   [(set_attr "type" "fp")])
8871 (define_insn "fnhadddf_vis"
8872   [(set (match_operand:DF 0 "register_operand" "=f")
8873         (neg:DF (unspec:DF [(match_operand:DF 1 "register_operand" "f")
8874                             (match_operand:DF 2 "register_operand" "f")]
8875                            UNSPEC_FHADD)))]
8876   "TARGET_VIS3"
8877   "fnhaddd\t%1, %2, %0"
8878   [(set_attr "type" "fp")
8879    (set_attr "fptype" "double")])
8881 (include "sync.md")