OSDN Git Service

./:
[pf3gnuchains/gcc-fork.git] / gcc / config / sparc / sparc.md
1 ;; Machine description for SPARC chip for GCC
2 ;;  Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 ;;  1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
4 ;;  Free Software Foundation, Inc.
5 ;;  Contributed by Michael Tiemann (tiemann@cygnus.com)
6 ;;  64-bit SPARC-V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
7 ;;  at Cygnus Support.
8
9 ;; This file is part of GCC.
10
11 ;; GCC is free software; you can redistribute it and/or modify
12 ;; it under the terms of the GNU General Public License as published by
13 ;; the Free Software Foundation; either version 3, or (at your option)
14 ;; any later version.
15
16 ;; GCC is distributed in the hope that it will be useful,
17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 ;; GNU General Public License for more details.
20
21 ;; You should have received a copy of the GNU General Public License
22 ;; along with GCC; see the file COPYING3.  If not see
23 ;; <http://www.gnu.org/licenses/>.
24
25 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
26
27 (define_constants
28   [(UNSPEC_MOVE_PIC             0)
29    (UNSPEC_UPDATE_RETURN        1)
30    (UNSPEC_LOAD_PCREL_SYM       2)
31    (UNSPEC_MOVE_PIC_LABEL       5)
32    (UNSPEC_SETH44               6)
33    (UNSPEC_SETM44               7)
34    (UNSPEC_SETHH                9)
35    (UNSPEC_SETLM                10)
36    (UNSPEC_EMB_HISUM            11)
37    (UNSPEC_EMB_TEXTUHI          13)
38    (UNSPEC_EMB_TEXTHI           14)
39    (UNSPEC_EMB_TEXTULO          15)
40    (UNSPEC_EMB_SETHM            18)
41
42    (UNSPEC_MEMBAR               20)
43
44    (UNSPEC_TLSGD                30)
45    (UNSPEC_TLSLDM               31)
46    (UNSPEC_TLSLDO               32)
47    (UNSPEC_TLSIE                33)
48    (UNSPEC_TLSLE                34)
49    (UNSPEC_TLSLD_BASE           35)
50
51    (UNSPEC_FPACK16              40)
52    (UNSPEC_FPACK32              41)
53    (UNSPEC_FPACKFIX             42)
54    (UNSPEC_FEXPAND              43)
55    (UNSPEC_FPMERGE              44)
56    (UNSPEC_MUL16AL              45)
57    (UNSPEC_MUL8UL               46)
58    (UNSPEC_MULDUL               47)
59    (UNSPEC_ALIGNDATA            48)
60    (UNSPEC_ALIGNADDR            49)
61    (UNSPEC_PDIST                50)
62
63    (UNSPEC_SP_SET               60)
64    (UNSPEC_SP_TEST              61)
65   ])
66
67 (define_constants
68   [(UNSPECV_BLOCKAGE            0)
69    (UNSPECV_FLUSHW              1)
70    (UNSPECV_GOTO                2)
71    (UNSPECV_FLUSH               4)
72    (UNSPECV_SETJMP              5)
73    (UNSPECV_SAVEW               6)
74    (UNSPECV_CAS                 8)
75    (UNSPECV_SWAP                9)
76    (UNSPECV_LDSTUB              10)
77   ])
78
79 ;; The upper 32 fp regs on the v9 can't hold SFmode values.  To deal with this
80 ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip.  The name
81 ;; is a bit of a misnomer as it covers all 64 fp regs.  The corresponding
82 ;; constraint letter is 'e'.  To avoid any confusion, 'e' is used instead of
83 ;; 'f' for all DF/TFmode values, including those that are specific to the v8.
84
85
86 ;; Attribute for cpu type.
87 ;; These must match the values for enum processor_type in sparc.h.
88 (define_attr "cpu"
89   "v7,
90    cypress,
91    v8,
92    supersparc,
93    sparclite,f930,f934,
94    hypersparc,sparclite86x,
95    sparclet,tsc701,
96    v9,
97    ultrasparc,
98    ultrasparc3,
99    niagara,
100    niagara2"
101   (const (symbol_ref "sparc_cpu_attr")))
102
103 ;; Attribute for the instruction set.
104 ;; At present we only need to distinguish v9/!v9, but for clarity we
105 ;; test TARGET_V8 too.
106 (define_attr "isa" "v7,v8,v9,sparclet"
107  (const
108   (cond [(symbol_ref "TARGET_V9") (const_string "v9")
109          (symbol_ref "TARGET_V8") (const_string "v8")
110          (symbol_ref "TARGET_SPARCLET") (const_string "sparclet")]
111         (const_string "v7"))))
112
113 ;; Insn type.
114 (define_attr "type"
115   "ialu,compare,shift,
116    load,sload,store,
117    uncond_branch,branch,call,sibcall,call_no_delay_slot,return,
118    imul,idiv,
119    fpload,fpstore,
120    fp,fpmove,
121    fpcmove,fpcrmove,
122    fpcmp,
123    fpmul,fpdivs,fpdivd,
124    fpsqrts,fpsqrtd,
125    fga,fgm_pack,fgm_mul,fgm_pdist,fgm_cmp,
126    cmove,
127    ialuX,
128    multi,savew,flushw,iflush,trap"
129   (const_string "ialu"))
130
131 ;; True if branch/call has empty delay slot and will emit a nop in it
132 (define_attr "empty_delay_slot" "false,true"
133   (symbol_ref "(empty_delay_slot (insn)
134                 ? EMPTY_DELAY_SLOT_TRUE : EMPTY_DELAY_SLOT_FALSE)"))
135
136 (define_attr "branch_type" "none,icc,fcc,reg"
137   (const_string "none"))
138
139 (define_attr "pic" "false,true"
140   (symbol_ref "(flag_pic != 0 ? PIC_TRUE : PIC_FALSE)"))
141
142 (define_attr "calls_alloca" "false,true"
143   (symbol_ref "(cfun->calls_alloca != 0
144                 ? CALLS_ALLOCA_TRUE : CALLS_ALLOCA_FALSE)"))
145
146 (define_attr "calls_eh_return" "false,true"
147    (symbol_ref "(crtl->calls_eh_return != 0
148                  ? CALLS_EH_RETURN_TRUE : CALLS_EH_RETURN_FALSE)"))
149    
150 (define_attr "leaf_function" "false,true"
151   (symbol_ref "(current_function_uses_only_leaf_regs != 0
152                 ? LEAF_FUNCTION_TRUE : LEAF_FUNCTION_FALSE)"))
153
154 (define_attr "delayed_branch" "false,true"
155   (symbol_ref "(flag_delayed_branch != 0
156                 ? DELAYED_BRANCH_TRUE : DELAYED_BRANCH_FALSE)"))
157
158 ;; Length (in # of insns).
159 ;; Beware that setting a length greater or equal to 3 for conditional branches
160 ;; has a side-effect (see output_cbranch and output_v9branch).
161 (define_attr "length" ""
162   (cond [(eq_attr "type" "uncond_branch,call")
163            (if_then_else (eq_attr "empty_delay_slot" "true")
164              (const_int 2)
165              (const_int 1))
166          (eq_attr "type" "sibcall")
167            (if_then_else (eq_attr "leaf_function" "true")
168              (if_then_else (eq_attr "empty_delay_slot" "true")
169                (const_int 3)
170                (const_int 2))
171              (if_then_else (eq_attr "empty_delay_slot" "true")
172                (const_int 2)
173                (const_int 1)))
174          (eq_attr "branch_type" "icc")
175            (if_then_else (match_operand 0 "noov_compare64_operator" "")
176              (if_then_else (lt (pc) (match_dup 1))
177                (if_then_else (lt (minus (match_dup 1) (pc)) (const_int 260000))
178                  (if_then_else (eq_attr "empty_delay_slot" "true")
179                    (const_int 2)
180                    (const_int 1))
181                  (if_then_else (eq_attr "empty_delay_slot" "true")
182                    (const_int 4)
183                    (const_int 3)))
184                (if_then_else (lt (minus (pc) (match_dup 1)) (const_int 260000))
185                  (if_then_else (eq_attr "empty_delay_slot" "true")
186                    (const_int 2)
187                    (const_int 1))
188                  (if_then_else (eq_attr "empty_delay_slot" "true")
189                    (const_int 4)
190                    (const_int 3))))
191              (if_then_else (eq_attr "empty_delay_slot" "true")
192                (const_int 2)
193                (const_int 1)))
194          (eq_attr "branch_type" "fcc")
195            (if_then_else (match_operand 0 "fcc0_register_operand" "")
196              (if_then_else (eq_attr "empty_delay_slot" "true")
197                (if_then_else (eq (symbol_ref "TARGET_V9") (const_int 0))
198                  (const_int 3)
199                  (const_int 2))
200                (if_then_else (eq (symbol_ref "TARGET_V9") (const_int 0))
201                  (const_int 2)
202                  (const_int 1)))
203              (if_then_else (lt (pc) (match_dup 2))
204                (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 260000))
205                  (if_then_else (eq_attr "empty_delay_slot" "true")
206                    (const_int 2)
207                    (const_int 1))
208                  (if_then_else (eq_attr "empty_delay_slot" "true")
209                    (const_int 4)
210                    (const_int 3)))
211                (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 260000))
212                  (if_then_else (eq_attr "empty_delay_slot" "true")
213                    (const_int 2)
214                    (const_int 1))
215                  (if_then_else (eq_attr "empty_delay_slot" "true")
216                    (const_int 4)
217                    (const_int 3)))))
218          (eq_attr "branch_type" "reg")
219            (if_then_else (lt (pc) (match_dup 2))
220              (if_then_else (lt (minus (match_dup 2) (pc)) (const_int 32000))
221                (if_then_else (eq_attr "empty_delay_slot" "true")
222                  (const_int 2)
223                  (const_int 1))
224                (if_then_else (eq_attr "empty_delay_slot" "true")
225                  (const_int 4)
226                  (const_int 3)))
227              (if_then_else (lt (minus (pc) (match_dup 2)) (const_int 32000))
228                (if_then_else (eq_attr "empty_delay_slot" "true")
229                  (const_int 2)
230                  (const_int 1))
231                (if_then_else (eq_attr "empty_delay_slot" "true")
232                  (const_int 4)
233                  (const_int 3))))
234          ] (const_int 1)))
235
236 ;; FP precision.
237 (define_attr "fptype" "single,double"
238   (const_string "single"))
239
240 ;; UltraSPARC-III integer load type.
241 (define_attr "us3load_type" "2cycle,3cycle"
242   (const_string "2cycle"))
243
244 (define_asm_attributes
245   [(set_attr "length" "2")
246    (set_attr "type" "multi")])
247
248 ;; Attributes for instruction and branch scheduling
249 (define_attr "tls_call_delay" "false,true"
250   (symbol_ref "(tls_call_delay (insn)
251                 ? TLS_CALL_DELAY_TRUE : TLS_CALL_DELAY_FALSE)"))
252
253 (define_attr "in_call_delay" "false,true"
254   (cond [(eq_attr "type" "uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
255                 (const_string "false")
256          (eq_attr "type" "load,fpload,store,fpstore")
257                 (if_then_else (eq_attr "length" "1")
258                               (const_string "true")
259                               (const_string "false"))]
260         (if_then_else (and (eq_attr "length" "1")
261                            (eq_attr "tls_call_delay" "true"))
262                       (const_string "true")
263                       (const_string "false"))))
264
265 (define_attr "eligible_for_sibcall_delay" "false,true"
266   (symbol_ref "(eligible_for_sibcall_delay (insn)
267                 ? ELIGIBLE_FOR_SIBCALL_DELAY_TRUE
268                 : ELIGIBLE_FOR_SIBCALL_DELAY_FALSE)"))
269
270 (define_attr "eligible_for_return_delay" "false,true"
271   (symbol_ref "(eligible_for_return_delay (insn)
272                 ? ELIGIBLE_FOR_RETURN_DELAY_TRUE
273                 : ELIGIBLE_FOR_RETURN_DELAY_FALSE)"))
274
275 ;; ??? !v9: Should implement the notion of predelay slots for floating-point
276 ;; branches.  This would allow us to remove the nop always inserted before
277 ;; a floating point branch.
278
279 ;; ??? It is OK for fill_simple_delay_slots to put load/store instructions
280 ;; in a delay slot, but it is not OK for fill_eager_delay_slots to do so.
281 ;; This is because doing so will add several pipeline stalls to the path
282 ;; that the load/store did not come from.  Unfortunately, there is no way
283 ;; to prevent fill_eager_delay_slots from using load/store without completely
284 ;; disabling them.  For the SPEC benchmark set, this is a serious lose,
285 ;; because it prevents us from moving back the final store of inner loops.
286
287 (define_attr "in_branch_delay" "false,true"
288   (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
289                      (eq_attr "length" "1"))
290                 (const_string "true")
291                 (const_string "false")))
292
293 (define_attr "in_uncond_branch_delay" "false,true"
294   (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
295                      (eq_attr "length" "1"))
296                 (const_string "true")
297                 (const_string "false")))
298
299 (define_attr "in_annul_branch_delay" "false,true"
300   (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,sibcall,call_no_delay_slot,multi")
301                      (eq_attr "length" "1"))
302                 (const_string "true")
303                 (const_string "false")))
304
305 (define_delay (eq_attr "type" "call")
306   [(eq_attr "in_call_delay" "true") (nil) (nil)])
307
308 (define_delay (eq_attr "type" "sibcall")
309   [(eq_attr "eligible_for_sibcall_delay" "true") (nil) (nil)])
310
311 (define_delay (eq_attr "type" "branch")
312   [(eq_attr "in_branch_delay" "true")
313    (nil) (eq_attr "in_annul_branch_delay" "true")])
314
315 (define_delay (eq_attr "type" "uncond_branch")
316   [(eq_attr "in_uncond_branch_delay" "true")
317    (nil) (nil)])
318
319 (define_delay (eq_attr "type" "return")
320   [(eq_attr "eligible_for_return_delay" "true") (nil) (nil)])
321
322
323 ;; Include SPARC DFA schedulers
324
325 (include "cypress.md")
326 (include "supersparc.md")
327 (include "hypersparc.md")
328 (include "sparclet.md")
329 (include "ultra1_2.md")
330 (include "ultra3.md")
331 (include "niagara.md")
332 (include "niagara2.md")
333
334
335 ;; Operand and operator predicates and constraints
336
337 (include "predicates.md")
338 (include "constraints.md")
339
340
341 ;; Compare instructions.
342
343 ;; We generate RTL for comparisons and branches by having the cmpxx 
344 ;; patterns store away the operands.  Then, the scc and bcc patterns
345 ;; emit RTL for both the compare and the branch.
346 ;;
347 ;; We do this because we want to generate different code for an sne and
348 ;; seq insn.  In those cases, if the second operand of the compare is not
349 ;; const0_rtx, we want to compute the xor of the two operands and test
350 ;; it against zero.
351 ;;
352 ;; We start with the DEFINE_EXPANDs, then the DEFINE_INSNs to match
353 ;; the patterns.  Finally, we have the DEFINE_SPLITs for some of the scc
354 ;; insns that actually require more than one machine instruction.
355
356 (define_expand "cmpsi"
357   [(set (reg:CC 100)
358         (compare:CC (match_operand:SI 0 "compare_operand" "")
359                     (match_operand:SI 1 "arith_operand" "")))]
360   ""
361 {
362   if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx)
363     operands[0] = force_reg (SImode, operands[0]);
364
365   sparc_compare_op0 = operands[0];
366   sparc_compare_op1 = operands[1];
367   DONE;
368 })
369
370 (define_expand "cmpdi"
371   [(set (reg:CCX 100)
372         (compare:CCX (match_operand:DI 0 "compare_operand" "")
373                      (match_operand:DI 1 "arith_operand" "")))]
374   "TARGET_ARCH64"
375 {
376   if (GET_CODE (operands[0]) == ZERO_EXTRACT && operands[1] != const0_rtx)
377     operands[0] = force_reg (DImode, operands[0]);
378
379   sparc_compare_op0 = operands[0];
380   sparc_compare_op1 = operands[1];
381   DONE;
382 })
383
384 (define_expand "cmpsf"
385   ;; The 96 here isn't ever used by anyone.
386   [(set (reg:CCFP 96)
387         (compare:CCFP (match_operand:SF 0 "register_operand" "")
388                       (match_operand:SF 1 "register_operand" "")))]
389   "TARGET_FPU"
390 {
391   sparc_compare_op0 = operands[0];
392   sparc_compare_op1 = operands[1];
393   DONE;
394 })
395
396 (define_expand "cmpdf"
397   ;; The 96 here isn't ever used by anyone.
398   [(set (reg:CCFP 96)
399         (compare:CCFP (match_operand:DF 0 "register_operand" "")
400                       (match_operand:DF 1 "register_operand" "")))]
401   "TARGET_FPU"
402 {
403   sparc_compare_op0 = operands[0];
404   sparc_compare_op1 = operands[1];
405   DONE;
406 })
407
408 (define_expand "cmptf"
409   ;; The 96 here isn't ever used by anyone.
410   [(set (reg:CCFP 96)
411         (compare:CCFP (match_operand:TF 0 "register_operand" "")
412                       (match_operand:TF 1 "register_operand" "")))]
413   "TARGET_FPU"
414 {
415   sparc_compare_op0 = operands[0];
416   sparc_compare_op1 = operands[1];
417   DONE;
418 })
419
420 ;; Now the compare DEFINE_INSNs.
421
422 (define_insn "*cmpsi_insn"
423   [(set (reg:CC 100)
424         (compare:CC (match_operand:SI 0 "register_operand" "r")
425                     (match_operand:SI 1 "arith_operand" "rI")))]
426   ""
427   "cmp\t%0, %1"
428   [(set_attr "type" "compare")])
429
430 (define_insn "*cmpdi_sp64"
431   [(set (reg:CCX 100)
432         (compare:CCX (match_operand:DI 0 "register_operand" "r")
433                      (match_operand:DI 1 "arith_operand" "rI")))]
434   "TARGET_ARCH64"
435   "cmp\t%0, %1"
436   [(set_attr "type" "compare")])
437
438 (define_insn "*cmpsf_fpe"
439   [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
440         (compare:CCFPE (match_operand:SF 1 "register_operand" "f")
441                        (match_operand:SF 2 "register_operand" "f")))]
442   "TARGET_FPU"
443 {
444   if (TARGET_V9)
445     return "fcmpes\t%0, %1, %2";
446   return "fcmpes\t%1, %2";
447 }
448   [(set_attr "type" "fpcmp")])
449
450 (define_insn "*cmpdf_fpe"
451   [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
452         (compare:CCFPE (match_operand:DF 1 "register_operand" "e")
453                        (match_operand:DF 2 "register_operand" "e")))]
454   "TARGET_FPU"
455 {
456   if (TARGET_V9)
457     return "fcmped\t%0, %1, %2";
458   return "fcmped\t%1, %2";
459 }
460   [(set_attr "type" "fpcmp")
461    (set_attr "fptype" "double")])
462
463 (define_insn "*cmptf_fpe"
464   [(set (match_operand:CCFPE 0 "fcc_register_operand" "=c")
465         (compare:CCFPE (match_operand:TF 1 "register_operand" "e")
466                        (match_operand:TF 2 "register_operand" "e")))]
467   "TARGET_FPU && TARGET_HARD_QUAD"
468 {
469   if (TARGET_V9)
470     return "fcmpeq\t%0, %1, %2";
471   return "fcmpeq\t%1, %2";
472 }
473   [(set_attr "type" "fpcmp")])
474
475 (define_insn "*cmpsf_fp"
476   [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
477         (compare:CCFP (match_operand:SF 1 "register_operand" "f")
478                       (match_operand:SF 2 "register_operand" "f")))]
479   "TARGET_FPU"
480 {
481   if (TARGET_V9)
482     return "fcmps\t%0, %1, %2";
483   return "fcmps\t%1, %2";
484 }
485   [(set_attr "type" "fpcmp")])
486
487 (define_insn "*cmpdf_fp"
488   [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
489         (compare:CCFP (match_operand:DF 1 "register_operand" "e")
490                       (match_operand:DF 2 "register_operand" "e")))]
491   "TARGET_FPU"
492 {
493   if (TARGET_V9)
494     return "fcmpd\t%0, %1, %2";
495   return "fcmpd\t%1, %2";
496 }
497   [(set_attr "type" "fpcmp")
498    (set_attr "fptype" "double")])
499
500 (define_insn "*cmptf_fp"
501   [(set (match_operand:CCFP 0 "fcc_register_operand" "=c")
502         (compare:CCFP (match_operand:TF 1 "register_operand" "e")
503                       (match_operand:TF 2 "register_operand" "e")))]
504   "TARGET_FPU && TARGET_HARD_QUAD"
505 {
506   if (TARGET_V9)
507     return "fcmpq\t%0, %1, %2";
508   return "fcmpq\t%1, %2";
509 }
510   [(set_attr "type" "fpcmp")])
511 \f
512 ;; Next come the scc insns.  For seq, sne, sgeu, and sltu, we can do this
513 ;; without jumps using the addx/subx instructions.  For seq/sne on v9 we use
514 ;; the same code as v8 (the addx/subx method has more applications).  The
515 ;; exception to this is "reg != 0" which can be done in one instruction on v9
516 ;; (so we do it).  For the rest, on v9 we use conditional moves; on v8, we do
517 ;; branches.
518
519 ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they
520 ;; generate addcc/subcc instructions.
521
522 (define_expand "seqsi_special"
523   [(set (match_dup 3)
524         (xor:SI (match_operand:SI 1 "register_operand" "")
525                 (match_operand:SI 2 "register_operand" "")))
526    (parallel [(set (match_operand:SI 0 "register_operand" "")
527                    (eq:SI (match_dup 3) (const_int 0)))
528               (clobber (reg:CC 100))])]
529   ""
530   { operands[3] = gen_reg_rtx (SImode); })
531
532 (define_expand "seqdi_special"
533   [(set (match_dup 3)
534         (xor:DI (match_operand:DI 1 "register_operand" "")
535                 (match_operand:DI 2 "register_operand" "")))
536    (set (match_operand:DI 0 "register_operand" "")
537         (eq:DI (match_dup 3) (const_int 0)))]
538   "TARGET_ARCH64"
539   { operands[3] = gen_reg_rtx (DImode); })
540
541 (define_expand "snesi_special"
542   [(set (match_dup 3)
543         (xor:SI (match_operand:SI 1 "register_operand" "")
544                 (match_operand:SI 2 "register_operand" "")))
545    (parallel [(set (match_operand:SI 0 "register_operand" "")
546                    (ne:SI (match_dup 3) (const_int 0)))
547               (clobber (reg:CC 100))])]
548   ""
549   { operands[3] = gen_reg_rtx (SImode); })
550
551 (define_expand "snedi_special"
552   [(set (match_dup 3)
553         (xor:DI (match_operand:DI 1 "register_operand" "")
554                 (match_operand:DI 2 "register_operand" "")))
555    (set (match_operand:DI 0 "register_operand" "")
556         (ne:DI (match_dup 3) (const_int 0)))]
557   "TARGET_ARCH64"
558   { operands[3] = gen_reg_rtx (DImode); })
559
560 (define_expand "seqdi_special_trunc"
561   [(set (match_dup 3)
562         (xor:DI (match_operand:DI 1 "register_operand" "")
563                 (match_operand:DI 2 "register_operand" "")))
564    (set (match_operand:SI 0 "register_operand" "")
565         (eq:SI (match_dup 3) (const_int 0)))]
566   "TARGET_ARCH64"
567   { operands[3] = gen_reg_rtx (DImode); })
568
569 (define_expand "snedi_special_trunc"
570   [(set (match_dup 3)
571         (xor:DI (match_operand:DI 1 "register_operand" "")
572                 (match_operand:DI 2 "register_operand" "")))
573    (set (match_operand:SI 0 "register_operand" "")
574         (ne:SI (match_dup 3) (const_int 0)))]
575   "TARGET_ARCH64"
576   { operands[3] = gen_reg_rtx (DImode); })
577
578 (define_expand "seqsi_special_extend"
579   [(set (match_dup 3)
580         (xor:SI (match_operand:SI 1 "register_operand" "")
581                 (match_operand:SI 2 "register_operand" "")))
582    (parallel [(set (match_operand:DI 0 "register_operand" "")
583                    (eq:DI (match_dup 3) (const_int 0)))
584               (clobber (reg:CC 100))])]
585   "TARGET_ARCH64"
586   { operands[3] = gen_reg_rtx (SImode); })
587
588 (define_expand "snesi_special_extend"
589   [(set (match_dup 3)
590         (xor:SI (match_operand:SI 1 "register_operand" "")
591                 (match_operand:SI 2 "register_operand" "")))
592    (parallel [(set (match_operand:DI 0 "register_operand" "")
593                    (ne:DI (match_dup 3) (const_int 0)))
594               (clobber (reg:CC 100))])]
595   "TARGET_ARCH64"
596   { operands[3] = gen_reg_rtx (SImode); })
597
598 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
599 ;; However, the code handles both SImode and DImode.
600 (define_expand "seq"
601   [(set (match_operand:SI 0 "int_register_operand" "")
602         (eq:SI (match_dup 1) (const_int 0)))]
603   ""
604 {
605   if (GET_MODE (sparc_compare_op0) == SImode)
606     {
607       rtx pat;
608
609       if (GET_MODE (operands[0]) == SImode)
610         pat = gen_seqsi_special (operands[0], sparc_compare_op0,
611                                  sparc_compare_op1);
612       else if (! TARGET_ARCH64)
613         FAIL;
614       else
615         pat = gen_seqsi_special_extend (operands[0], sparc_compare_op0,
616                                         sparc_compare_op1);
617       emit_insn (pat);
618       DONE;
619     }
620   else if (GET_MODE (sparc_compare_op0) == DImode)
621     {
622       rtx pat;
623
624       if (! TARGET_ARCH64)
625         FAIL;
626       else if (GET_MODE (operands[0]) == SImode)
627         pat = gen_seqdi_special_trunc (operands[0], sparc_compare_op0,
628                                        sparc_compare_op1);
629       else
630         pat = gen_seqdi_special (operands[0], sparc_compare_op0,
631                                  sparc_compare_op1);
632       emit_insn (pat);
633       DONE;
634     }
635   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
636     {
637       enum rtx_code code
638         = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
639       gcc_assert (code == NE);
640       emit_insn (gen_sne (operands[0]));
641       DONE;
642     }
643   else if (TARGET_V9)
644     {
645       if (gen_v9_scc (EQ, operands))
646         DONE;
647       /* fall through */
648     }
649   FAIL;
650 })
651
652 ;; ??? v9: Operand 0 needs a mode, so SImode was chosen.
653 ;; However, the code handles both SImode and DImode.
654 (define_expand "sne"
655   [(set (match_operand:SI 0 "int_register_operand" "")
656         (ne:SI (match_dup 1) (const_int 0)))]
657   ""
658 {
659   if (GET_MODE (sparc_compare_op0) == SImode)
660     {
661       rtx pat;
662
663       if (GET_MODE (operands[0]) == SImode)
664         pat = gen_snesi_special (operands[0], sparc_compare_op0,
665                                  sparc_compare_op1);
666       else if (! TARGET_ARCH64)
667         FAIL;
668       else
669         pat = gen_snesi_special_extend (operands[0], sparc_compare_op0,
670                                         sparc_compare_op1);
671       emit_insn (pat);
672       DONE;
673     }
674   else if (GET_MODE (sparc_compare_op0) == DImode)
675     {
676       rtx pat;
677
678       if (! TARGET_ARCH64)
679         FAIL;
680       else if (GET_MODE (operands[0]) == SImode)
681         pat = gen_snedi_special_trunc (operands[0], sparc_compare_op0,
682                                        sparc_compare_op1);
683       else
684         pat = gen_snedi_special (operands[0], sparc_compare_op0,
685                                  sparc_compare_op1);
686       emit_insn (pat);
687       DONE;
688     }
689   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
690     {
691       enum rtx_code code
692         = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
693       gcc_assert (code == NE);
694       emit_insn (gen_sne (operands[0]));
695       DONE;
696     }
697   else if (TARGET_V9)
698     {
699       if (gen_v9_scc (NE, operands))
700         DONE;
701       /* fall through */
702     }
703   FAIL;
704 })
705
706 (define_expand "sgt"
707   [(set (match_operand:SI 0 "int_register_operand" "")
708         (gt:SI (match_dup 1) (const_int 0)))]
709   ""
710 {
711   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
712     {
713       enum rtx_code code
714         = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
715       gcc_assert (code == NE);
716       emit_insn (gen_sne (operands[0]));
717       DONE;
718     }
719   else if (TARGET_V9)
720     {
721       if (gen_v9_scc (GT, operands))
722         DONE;
723       /* fall through */
724     }
725   FAIL;
726 })
727
728 (define_expand "slt"
729   [(set (match_operand:SI 0 "int_register_operand" "")
730         (lt:SI (match_dup 1) (const_int 0)))]
731   ""
732 {
733   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
734     {
735       enum rtx_code code
736         = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
737       gcc_assert (code == NE);
738       emit_insn (gen_sne (operands[0]));
739       DONE;
740     }
741   else if (TARGET_V9)
742     {
743       if (gen_v9_scc (LT, operands))
744         DONE;
745       /* fall through */
746     }
747   FAIL;
748 })
749
750 (define_expand "sge"
751   [(set (match_operand:SI 0 "int_register_operand" "")
752         (ge:SI (match_dup 1) (const_int 0)))]
753   ""
754 {
755   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
756     {
757       enum rtx_code code
758         = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
759       gcc_assert (code == NE);
760       emit_insn (gen_sne (operands[0]));
761       DONE;
762     }
763   else if (TARGET_V9)
764     {
765       if (gen_v9_scc (GE, operands))
766         DONE;
767       /* fall through */
768     }
769   FAIL;
770 })
771
772 (define_expand "sle"
773   [(set (match_operand:SI 0 "int_register_operand" "")
774         (le:SI (match_dup 1) (const_int 0)))]
775   ""
776 {
777   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
778     {
779       enum rtx_code code
780         = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
781       gcc_assert (code == NE);
782       emit_insn (gen_sne (operands[0]));
783       DONE;
784     }
785   else if (TARGET_V9)
786     {
787       if (gen_v9_scc (LE, operands))
788         DONE;
789       /* fall through */
790     }
791   FAIL;
792 })
793
794 (define_expand "sgtu"
795   [(set (match_operand:SI 0 "int_register_operand" "")
796         (gtu:SI (match_dup 1) (const_int 0)))]
797   ""
798 {
799   if (! TARGET_V9)
800     {
801       rtx tem, pat;
802
803       /* We can do ltu easily, so if both operands are registers, swap them and
804          do a LTU.  */
805       if ((GET_CODE (sparc_compare_op0) == REG
806            || GET_CODE (sparc_compare_op0) == SUBREG)
807           && (GET_CODE (sparc_compare_op1) == REG
808               || GET_CODE (sparc_compare_op1) == SUBREG))
809         {
810           tem = sparc_compare_op0;
811           sparc_compare_op0 = sparc_compare_op1;
812           sparc_compare_op1 = tem;
813           pat = gen_sltu (operands[0]);
814           if (pat == NULL_RTX)
815             FAIL;
816           emit_insn (pat);
817           DONE;
818         }
819     }
820   else
821     {
822       if (gen_v9_scc (GTU, operands))
823         DONE;
824     }
825   FAIL;
826 })
827
828 (define_expand "sltu"
829   [(set (match_operand:SI 0 "int_register_operand" "")
830         (ltu:SI (match_dup 1) (const_int 0)))]
831   ""
832 {
833   if (TARGET_V9)
834     {
835       if (gen_v9_scc (LTU, operands))
836         DONE;
837     }
838   operands[1] = gen_compare_reg (LTU);
839 })
840
841 (define_expand "sgeu"
842   [(set (match_operand:SI 0 "int_register_operand" "")
843         (geu:SI (match_dup 1) (const_int 0)))]
844   ""
845 {
846   if (TARGET_V9)
847     {
848       if (gen_v9_scc (GEU, operands))
849         DONE;
850     }
851   operands[1] = gen_compare_reg (GEU);
852 })
853
854 (define_expand "sleu"
855   [(set (match_operand:SI 0 "int_register_operand" "")
856         (leu:SI (match_dup 1) (const_int 0)))]
857   ""
858 {
859   if (! TARGET_V9)
860     {
861       rtx tem, pat;
862
863       /* We can do geu easily, so if both operands are registers, swap them and
864          do a GEU.  */
865       if ((GET_CODE (sparc_compare_op0) == REG
866            || GET_CODE (sparc_compare_op0) == SUBREG)
867           && (GET_CODE (sparc_compare_op1) == REG
868               || GET_CODE (sparc_compare_op1) == SUBREG))
869         {
870           tem = sparc_compare_op0;
871           sparc_compare_op0 = sparc_compare_op1;
872           sparc_compare_op1 = tem;
873           pat = gen_sgeu (operands[0]);
874           if (pat == NULL_RTX)
875             FAIL;
876           emit_insn (pat);
877           DONE;
878         }
879     }
880   else
881     {
882       if (gen_v9_scc (LEU, operands))
883         DONE;
884     }
885   FAIL;
886 })
887
888 ;; Now the DEFINE_INSNs for the scc cases.
889
890 ;; The SEQ and SNE patterns are special because they can be done
891 ;; without any branching and do not involve a COMPARE.  We want
892 ;; them to always use the splits below so the results can be
893 ;; scheduled.
894
895 (define_insn_and_split "*snesi_zero"
896   [(set (match_operand:SI 0 "register_operand" "=r")
897         (ne:SI (match_operand:SI 1 "register_operand" "r")
898                (const_int 0)))
899    (clobber (reg:CC 100))]
900   ""
901   "#"
902   ""
903   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
904                                            (const_int 0)))
905    (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))]
906   ""
907   [(set_attr "length" "2")])
908
909 (define_insn_and_split "*neg_snesi_zero"
910   [(set (match_operand:SI 0 "register_operand" "=r")
911         (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
912                        (const_int 0))))
913    (clobber (reg:CC 100))]
914   ""
915   "#"
916   ""
917   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
918                                            (const_int 0)))
919    (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
920   ""
921   [(set_attr "length" "2")])
922
923 (define_insn_and_split "*snesi_zero_extend"
924   [(set (match_operand:DI 0 "register_operand" "=r")
925         (ne:DI (match_operand:SI 1 "register_operand" "r")
926                (const_int 0)))
927    (clobber (reg:CC 100))]
928   "TARGET_ARCH64"
929   "#"
930   "&& 1"
931   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
932                                                      (match_dup 1))
933                                            (const_int 0)))
934    (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0)
935                                                         (const_int 0))
936                                                (ltu:SI (reg:CC_NOOV 100)
937                                                        (const_int 0)))))]
938   ""
939   [(set_attr "length" "2")])
940
941 (define_insn_and_split "*snedi_zero"
942   [(set (match_operand:DI 0 "register_operand" "=&r")
943         (ne:DI (match_operand:DI 1 "register_operand" "r")
944                (const_int 0)))]
945   "TARGET_ARCH64"
946   "#"
947   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
948   [(set (match_dup 0) (const_int 0))
949    (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
950                                               (const_int 0))
951                                        (const_int 1)
952                                        (match_dup 0)))]
953   ""
954   [(set_attr "length" "2")])
955
956 (define_insn_and_split "*neg_snedi_zero"
957   [(set (match_operand:DI 0 "register_operand" "=&r")
958         (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r")
959                        (const_int 0))))]
960   "TARGET_ARCH64"
961   "#"
962   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
963   [(set (match_dup 0) (const_int 0))
964    (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
965                                               (const_int 0))
966                                        (const_int -1)
967                                        (match_dup 0)))]
968   ""
969   [(set_attr "length" "2")])
970
971 (define_insn_and_split "*snedi_zero_trunc"
972   [(set (match_operand:SI 0 "register_operand" "=&r")
973         (ne:SI (match_operand:DI 1 "register_operand" "r")
974                (const_int 0)))]
975   "TARGET_ARCH64"
976   "#"
977   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
978   [(set (match_dup 0) (const_int 0))
979    (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
980                                               (const_int 0))
981                                        (const_int 1)
982                                        (match_dup 0)))]
983   ""
984   [(set_attr "length" "2")])
985
986 (define_insn_and_split "*seqsi_zero"
987   [(set (match_operand:SI 0 "register_operand" "=r")
988         (eq:SI (match_operand:SI 1 "register_operand" "r")
989                (const_int 0)))
990    (clobber (reg:CC 100))]
991   ""
992   "#"
993   ""
994   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
995                                            (const_int 0)))
996    (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))]
997   ""
998   [(set_attr "length" "2")])
999
1000 (define_insn_and_split "*neg_seqsi_zero"
1001   [(set (match_operand:SI 0 "register_operand" "=r")
1002         (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1003                        (const_int 0))))
1004    (clobber (reg:CC 100))]
1005   ""
1006   "#"
1007   ""
1008   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1009                                            (const_int 0)))
1010    (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1011   ""
1012   [(set_attr "length" "2")])
1013
1014 (define_insn_and_split "*seqsi_zero_extend"
1015   [(set (match_operand:DI 0 "register_operand" "=r")
1016         (eq:DI (match_operand:SI 1 "register_operand" "r")
1017                (const_int 0)))
1018    (clobber (reg:CC 100))]
1019   "TARGET_ARCH64"
1020   "#"
1021   "&& 1"
1022   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0)
1023                                                      (match_dup 1))
1024                                            (const_int 0)))
1025    (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0)
1026                                                           (const_int -1))
1027                                                 (ltu:SI (reg:CC_NOOV 100)
1028                                                         (const_int 0)))))]
1029   ""
1030   [(set_attr "length" "2")])
1031
1032 (define_insn_and_split "*seqdi_zero"
1033   [(set (match_operand:DI 0 "register_operand" "=&r")
1034         (eq:DI (match_operand:DI 1 "register_operand" "r")
1035                (const_int 0)))]
1036   "TARGET_ARCH64"
1037   "#"
1038   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1039   [(set (match_dup 0) (const_int 0))
1040    (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1041                                               (const_int 0))
1042                                        (const_int 1)
1043                                        (match_dup 0)))]
1044   ""
1045   [(set_attr "length" "2")])
1046
1047 (define_insn_and_split "*neg_seqdi_zero"
1048   [(set (match_operand:DI 0 "register_operand" "=&r")
1049         (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r")
1050                        (const_int 0))))]
1051   "TARGET_ARCH64"
1052   "#"
1053   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1054   [(set (match_dup 0) (const_int 0))
1055    (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
1056                                               (const_int 0))
1057                                        (const_int -1)
1058                                        (match_dup 0)))]
1059   ""
1060   [(set_attr "length" "2")]) 
1061
1062 (define_insn_and_split "*seqdi_zero_trunc"
1063   [(set (match_operand:SI 0 "register_operand" "=&r")
1064         (eq:SI (match_operand:DI 1 "register_operand" "r")
1065                (const_int 0)))]
1066   "TARGET_ARCH64"
1067   "#"
1068   "&& ! reg_overlap_mentioned_p (operands[1], operands[0])"
1069   [(set (match_dup 0) (const_int 0))
1070    (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
1071                                               (const_int 0))
1072                                        (const_int 1)
1073                                        (match_dup 0)))]
1074   ""
1075   [(set_attr "length" "2")])
1076
1077 ;; We can also do (x + (i == 0)) and related, so put them in.
1078 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1079 ;; versions for v9.
1080
1081 (define_insn_and_split "*x_plus_i_ne_0"
1082   [(set (match_operand:SI 0 "register_operand" "=r")
1083         (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "r")
1084                         (const_int 0))
1085                  (match_operand:SI 2 "register_operand" "r")))
1086    (clobber (reg:CC 100))]
1087   ""
1088   "#"
1089   ""
1090   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1091                                            (const_int 0)))
1092    (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1093                                (match_dup 2)))]
1094   ""
1095   [(set_attr "length" "2")])
1096
1097 (define_insn_and_split "*x_minus_i_ne_0"
1098   [(set (match_operand:SI 0 "register_operand" "=r")
1099         (minus:SI (match_operand:SI 2 "register_operand" "r")
1100                   (ne:SI (match_operand:SI 1 "register_operand" "r")
1101                          (const_int 0))))
1102    (clobber (reg:CC 100))]
1103   ""
1104   "#"
1105   ""
1106   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1107                                            (const_int 0)))
1108    (set (match_dup 0) (minus:SI (match_dup 2)
1109                                 (ltu:SI (reg:CC 100) (const_int 0))))]
1110   ""
1111   [(set_attr "length" "2")])
1112
1113 (define_insn_and_split "*x_plus_i_eq_0"
1114   [(set (match_operand:SI 0 "register_operand" "=r")
1115         (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r")
1116                         (const_int 0))
1117                  (match_operand:SI 2 "register_operand" "r")))
1118    (clobber (reg:CC 100))]
1119   ""
1120   "#"
1121   ""
1122   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1123                                            (const_int 0)))
1124    (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1125                                (match_dup 2)))]
1126   ""
1127   [(set_attr "length" "2")])
1128
1129 (define_insn_and_split "*x_minus_i_eq_0"
1130   [(set (match_operand:SI 0 "register_operand" "=r")
1131         (minus:SI (match_operand:SI 2 "register_operand" "r")
1132                   (eq:SI (match_operand:SI 1 "register_operand" "r")
1133                          (const_int 0))))
1134    (clobber (reg:CC 100))]
1135   ""
1136   "#"
1137   ""
1138   [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1))
1139                                            (const_int 0)))
1140    (set (match_dup 0) (minus:SI (match_dup 2)
1141                                 (geu:SI (reg:CC 100) (const_int 0))))]
1142   ""
1143   [(set_attr "length" "2")])
1144
1145 ;; We can also do GEU and LTU directly, but these operate after a compare.
1146 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1147 ;; versions for v9.
1148
1149 (define_insn "*sltu_insn"
1150   [(set (match_operand:SI 0 "register_operand" "=r")
1151         (ltu:SI (reg:CC 100) (const_int 0)))]
1152   ""
1153   "addx\t%%g0, 0, %0"
1154   [(set_attr "type" "ialuX")])
1155
1156 (define_insn "*neg_sltu_insn"
1157   [(set (match_operand:SI 0 "register_operand" "=r")
1158         (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))]
1159   ""
1160   "subx\t%%g0, 0, %0"
1161   [(set_attr "type" "ialuX")])
1162
1163 ;; ??? Combine should canonicalize these next two to the same pattern.
1164 (define_insn "*neg_sltu_minus_x"
1165   [(set (match_operand:SI 0 "register_operand" "=r")
1166         (minus:SI (neg:SI (ltu:SI (reg:CC 100) (const_int 0)))
1167                   (match_operand:SI 1 "arith_operand" "rI")))]
1168   ""
1169   "subx\t%%g0, %1, %0"
1170   [(set_attr "type" "ialuX")])
1171
1172 (define_insn "*neg_sltu_plus_x"
1173   [(set (match_operand:SI 0 "register_operand" "=r")
1174         (neg:SI (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1175                          (match_operand:SI 1 "arith_operand" "rI"))))]
1176   ""
1177   "subx\t%%g0, %1, %0"
1178   [(set_attr "type" "ialuX")])
1179
1180 (define_insn "*sgeu_insn"
1181   [(set (match_operand:SI 0 "register_operand" "=r")
1182         (geu:SI (reg:CC 100) (const_int 0)))]
1183   ""
1184   "subx\t%%g0, -1, %0"
1185   [(set_attr "type" "ialuX")])
1186
1187 (define_insn "*neg_sgeu_insn"
1188   [(set (match_operand:SI 0 "register_operand" "=r")
1189         (neg:SI (geu:SI (reg:CC 100) (const_int 0))))]
1190   ""
1191   "addx\t%%g0, -1, %0"
1192   [(set_attr "type" "ialuX")])
1193
1194 ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in.
1195 ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode
1196 ;; versions for v9.
1197
1198 (define_insn "*sltu_plus_x"
1199   [(set (match_operand:SI 0 "register_operand" "=r")
1200         (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1201                  (match_operand:SI 1 "arith_operand" "rI")))]
1202   ""
1203   "addx\t%%g0, %1, %0"
1204   [(set_attr "type" "ialuX")])
1205
1206 (define_insn "*sltu_plus_x_plus_y"
1207   [(set (match_operand:SI 0 "register_operand" "=r")
1208         (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1209                  (plus:SI (match_operand:SI 1 "arith_operand" "%r")
1210                           (match_operand:SI 2 "arith_operand" "rI"))))]
1211   ""
1212   "addx\t%1, %2, %0"
1213   [(set_attr "type" "ialuX")])
1214
1215 (define_insn "*x_minus_sltu"
1216   [(set (match_operand:SI 0 "register_operand" "=r")
1217         (minus:SI (match_operand:SI 1 "register_operand" "r")
1218                   (ltu:SI (reg:CC 100) (const_int 0))))]
1219   ""
1220   "subx\t%1, 0, %0"
1221   [(set_attr "type" "ialuX")])
1222
1223 ;; ??? Combine should canonicalize these next two to the same pattern.
1224 (define_insn "*x_minus_y_minus_sltu"
1225   [(set (match_operand:SI 0 "register_operand" "=r")
1226         (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
1227                             (match_operand:SI 2 "arith_operand" "rI"))
1228                   (ltu:SI (reg:CC 100) (const_int 0))))]
1229   ""
1230   "subx\t%r1, %2, %0"
1231   [(set_attr "type" "ialuX")])
1232
1233 (define_insn "*x_minus_sltu_plus_y"
1234   [(set (match_operand:SI 0 "register_operand" "=r")
1235         (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
1236                   (plus:SI (ltu:SI (reg:CC 100) (const_int 0))
1237                            (match_operand:SI 2 "arith_operand" "rI"))))]
1238   ""
1239   "subx\t%r1, %2, %0"
1240   [(set_attr "type" "ialuX")])
1241
1242 (define_insn "*sgeu_plus_x"
1243   [(set (match_operand:SI 0 "register_operand" "=r")
1244         (plus:SI (geu:SI (reg:CC 100) (const_int 0))
1245                  (match_operand:SI 1 "register_operand" "r")))]
1246   ""
1247   "subx\t%1, -1, %0"
1248   [(set_attr "type" "ialuX")])
1249
1250 (define_insn "*x_minus_sgeu"
1251   [(set (match_operand:SI 0 "register_operand" "=r")
1252         (minus:SI (match_operand:SI 1 "register_operand" "r")
1253                   (geu:SI (reg:CC 100) (const_int 0))))]
1254   ""
1255   "addx\t%1, -1, %0"
1256   [(set_attr "type" "ialuX")])
1257
1258 (define_split
1259   [(set (match_operand:SI 0 "register_operand" "")
1260         (match_operator:SI 2 "noov_compare_operator"
1261                            [(match_operand 1 "icc_or_fcc_register_operand" "")
1262                             (const_int 0)]))]
1263   "TARGET_V9
1264    && REGNO (operands[1]) == SPARC_ICC_REG
1265    && (GET_MODE (operands[1]) == CCXmode
1266        /* 32-bit LTU/GEU are better implemented using addx/subx.  */
1267        || (GET_CODE (operands[2]) != LTU && GET_CODE (operands[2]) != GEU))"
1268   [(set (match_dup 0) (const_int 0))
1269    (set (match_dup 0)
1270         (if_then_else:SI (match_op_dup:SI 2 [(match_dup 1) (const_int 0)])
1271                          (const_int 1)
1272                          (match_dup 0)))]
1273   "")
1274
1275 \f
1276 ;; These control RTL generation for conditional jump insns
1277
1278 ;; The quad-word fp compare library routines all return nonzero to indicate
1279 ;; true, which is different from the equivalent libgcc routines, so we must
1280 ;; handle them specially here.
1281
1282 (define_expand "beq"
1283   [(set (pc)
1284         (if_then_else (eq (match_dup 1) (const_int 0))
1285                       (label_ref (match_operand 0 "" ""))
1286                       (pc)))]
1287   ""
1288 {
1289   if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1290       && GET_CODE (sparc_compare_op0) == REG
1291       && GET_MODE (sparc_compare_op0) == DImode)
1292     {
1293       emit_v9_brxx_insn (EQ, sparc_compare_op0, operands[0]);
1294       DONE;
1295     }
1296   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1297     {
1298       enum rtx_code code
1299         = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, EQ);
1300       gcc_assert (code == NE);
1301       emit_jump_insn (gen_bne (operands[0]));
1302       DONE;
1303     }
1304   operands[1] = gen_compare_reg (EQ);
1305 })
1306
1307 (define_expand "bne"
1308   [(set (pc)
1309         (if_then_else (ne (match_dup 1) (const_int 0))
1310                       (label_ref (match_operand 0 "" ""))
1311                       (pc)))]
1312   ""
1313 {
1314   if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1315       && GET_CODE (sparc_compare_op0) == REG
1316       && GET_MODE (sparc_compare_op0) == DImode)
1317     {
1318       emit_v9_brxx_insn (NE, sparc_compare_op0, operands[0]);
1319       DONE;
1320     }
1321   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1322     {
1323       enum rtx_code code
1324         = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, NE);
1325       gcc_assert (code == NE);
1326       emit_jump_insn (gen_bne (operands[0]));
1327       DONE;
1328     }
1329   operands[1] = gen_compare_reg (NE);
1330 })
1331
1332 (define_expand "bgt"
1333   [(set (pc)
1334         (if_then_else (gt (match_dup 1) (const_int 0))
1335                       (label_ref (match_operand 0 "" ""))
1336                       (pc)))]
1337   ""
1338 {
1339   if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1340       && GET_CODE (sparc_compare_op0) == REG
1341       && GET_MODE (sparc_compare_op0) == DImode)
1342     {
1343       emit_v9_brxx_insn (GT, sparc_compare_op0, operands[0]);
1344       DONE;
1345     }
1346   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1347     {
1348       enum rtx_code code
1349         = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GT);
1350       gcc_assert (code == NE);
1351       emit_jump_insn (gen_bne (operands[0]));
1352       DONE;
1353     }
1354   operands[1] = gen_compare_reg (GT);
1355 })
1356
1357 (define_expand "bgtu"
1358   [(set (pc)
1359         (if_then_else (gtu (match_dup 1) (const_int 0))
1360                       (label_ref (match_operand 0 "" ""))
1361                       (pc)))]
1362   ""
1363 {
1364   operands[1] = gen_compare_reg (GTU);
1365 })
1366
1367 (define_expand "blt"
1368   [(set (pc)
1369         (if_then_else (lt (match_dup 1) (const_int 0))
1370                       (label_ref (match_operand 0 "" ""))
1371                       (pc)))]
1372   ""
1373 {
1374   if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1375       && GET_CODE (sparc_compare_op0) == REG
1376       && GET_MODE (sparc_compare_op0) == DImode)
1377     {
1378       emit_v9_brxx_insn (LT, sparc_compare_op0, operands[0]);
1379       DONE;
1380     }
1381   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1382     {
1383       enum rtx_code code
1384         = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LT);
1385       gcc_assert (code == NE);
1386       emit_jump_insn (gen_bne (operands[0]));
1387       DONE;
1388     }
1389   operands[1] = gen_compare_reg (LT);
1390 })
1391
1392 (define_expand "bltu"
1393   [(set (pc)
1394         (if_then_else (ltu (match_dup 1) (const_int 0))
1395                       (label_ref (match_operand 0 "" ""))
1396                       (pc)))]
1397   ""
1398 {
1399   operands[1] = gen_compare_reg (LTU);
1400 })
1401
1402 (define_expand "bge"
1403   [(set (pc)
1404         (if_then_else (ge (match_dup 1) (const_int 0))
1405                       (label_ref (match_operand 0 "" ""))
1406                       (pc)))]
1407   ""
1408 {
1409   if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1410       && GET_CODE (sparc_compare_op0) == REG
1411       && GET_MODE (sparc_compare_op0) == DImode)
1412     {
1413       emit_v9_brxx_insn (GE, sparc_compare_op0, operands[0]);
1414       DONE;
1415     }
1416   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1417     {
1418       enum rtx_code code
1419         = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, GE);
1420       gcc_assert (code == NE);
1421       emit_jump_insn (gen_bne (operands[0]));
1422       DONE;
1423     }
1424   operands[1] = gen_compare_reg (GE);
1425 })
1426
1427 (define_expand "bgeu"
1428   [(set (pc)
1429         (if_then_else (geu (match_dup 1) (const_int 0))
1430                       (label_ref (match_operand 0 "" ""))
1431                       (pc)))]
1432   ""
1433 {
1434   operands[1] = gen_compare_reg (GEU);
1435 })
1436
1437 (define_expand "ble"
1438   [(set (pc)
1439         (if_then_else (le (match_dup 1) (const_int 0))
1440                       (label_ref (match_operand 0 "" ""))
1441                       (pc)))]
1442   ""
1443 {
1444   if (TARGET_ARCH64 && sparc_compare_op1 == const0_rtx
1445       && GET_CODE (sparc_compare_op0) == REG
1446       && GET_MODE (sparc_compare_op0) == DImode)
1447     {
1448       emit_v9_brxx_insn (LE, sparc_compare_op0, operands[0]);
1449       DONE;
1450     }
1451   else if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1452     {
1453       enum rtx_code code
1454         = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LE);
1455       gcc_assert (code == NE);
1456       emit_jump_insn (gen_bne (operands[0]));
1457       DONE;
1458     }
1459   operands[1] = gen_compare_reg (LE);
1460 })
1461
1462 (define_expand "bleu"
1463   [(set (pc)
1464         (if_then_else (leu (match_dup 1) (const_int 0))
1465                       (label_ref (match_operand 0 "" ""))
1466                       (pc)))]
1467   ""
1468 {
1469   operands[1] = gen_compare_reg (LEU);
1470 })
1471
1472 (define_expand "bunordered"
1473   [(set (pc)
1474         (if_then_else (unordered (match_dup 1) (const_int 0))
1475                       (label_ref (match_operand 0 "" ""))
1476                       (pc)))]
1477   ""
1478 {
1479   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1480     {
1481       enum rtx_code code
1482         = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNORDERED);
1483       gcc_assert (code == EQ);
1484       emit_jump_insn (gen_beq (operands[0]));
1485       DONE;
1486     }
1487   operands[1] = gen_compare_reg (UNORDERED);
1488 })
1489
1490 (define_expand "bordered"
1491   [(set (pc)
1492         (if_then_else (ordered (match_dup 1) (const_int 0))
1493                       (label_ref (match_operand 0 "" ""))
1494                       (pc)))]
1495   ""
1496 {
1497   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1498     {
1499       enum rtx_code code
1500         = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, ORDERED);
1501       gcc_assert (code == NE);
1502       emit_jump_insn (gen_bne (operands[0]));
1503       DONE;
1504     }
1505   operands[1] = gen_compare_reg (ORDERED);
1506 })
1507
1508 (define_expand "bungt"
1509   [(set (pc)
1510         (if_then_else (ungt (match_dup 1) (const_int 0))
1511                       (label_ref (match_operand 0 "" ""))
1512                       (pc)))]
1513   ""
1514 {
1515   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1516     {
1517       enum rtx_code code
1518         = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGT);
1519       gcc_assert (code == GT);
1520       emit_jump_insn (gen_bgt (operands[0]));
1521       DONE;
1522     }
1523   operands[1] = gen_compare_reg (UNGT);
1524 })
1525
1526 (define_expand "bunlt"
1527   [(set (pc)
1528         (if_then_else (unlt (match_dup 1) (const_int 0))
1529                       (label_ref (match_operand 0 "" ""))
1530                       (pc)))]
1531   ""
1532 {
1533   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1534     {
1535       enum rtx_code code
1536         = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLT);
1537       gcc_assert (code == NE);
1538       emit_jump_insn (gen_bne (operands[0]));
1539       DONE;
1540     }
1541   operands[1] = gen_compare_reg (UNLT);
1542 })
1543
1544 (define_expand "buneq"
1545   [(set (pc)
1546         (if_then_else (uneq (match_dup 1) (const_int 0))
1547                       (label_ref (match_operand 0 "" ""))
1548                       (pc)))]
1549   ""
1550 {
1551   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1552     {
1553       enum rtx_code code
1554         = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNEQ);
1555       gcc_assert (code == EQ);
1556       emit_jump_insn (gen_beq (operands[0]));
1557       DONE;
1558     }
1559   operands[1] = gen_compare_reg (UNEQ);
1560 })
1561
1562 (define_expand "bunge"
1563   [(set (pc)
1564         (if_then_else (unge (match_dup 1) (const_int 0))
1565                       (label_ref (match_operand 0 "" ""))
1566                       (pc)))]
1567   ""
1568 {
1569   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1570     {
1571       enum rtx_code code
1572         = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNGE);
1573       gcc_assert (code == NE);
1574       emit_jump_insn (gen_bne (operands[0]));
1575       DONE;
1576     }
1577   operands[1] = gen_compare_reg (UNGE);
1578 })
1579
1580 (define_expand "bunle"
1581   [(set (pc)
1582         (if_then_else (unle (match_dup 1) (const_int 0))
1583                       (label_ref (match_operand 0 "" ""))
1584                       (pc)))]
1585   ""
1586 {
1587   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1588     {
1589       enum rtx_code code
1590         = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, UNLE);
1591       gcc_assert (code == NE);
1592       emit_jump_insn (gen_bne (operands[0]));
1593       DONE;
1594     }
1595   operands[1] = gen_compare_reg (UNLE);
1596 })
1597
1598 (define_expand "bltgt"
1599   [(set (pc)
1600         (if_then_else (ltgt (match_dup 1) (const_int 0))
1601                       (label_ref (match_operand 0 "" ""))
1602                       (pc)))]
1603   ""
1604 {
1605   if (GET_MODE (sparc_compare_op0) == TFmode && ! TARGET_HARD_QUAD)
1606     {
1607       enum rtx_code code
1608         = sparc_emit_float_lib_cmp (sparc_compare_op0, sparc_compare_op1, LTGT);
1609       gcc_assert (code == NE);
1610       emit_jump_insn (gen_bne (operands[0]));
1611       DONE;
1612     }
1613   operands[1] = gen_compare_reg (LTGT);
1614 })
1615 \f
1616 ;; Now match both normal and inverted jump.
1617
1618 ;; XXX fpcmp nop braindamage
1619 (define_insn "*normal_branch"
1620   [(set (pc)
1621         (if_then_else (match_operator 0 "noov_compare_operator"
1622                                       [(reg 100) (const_int 0)])
1623                       (label_ref (match_operand 1 "" ""))
1624                       (pc)))]
1625   ""
1626 {
1627   return output_cbranch (operands[0], operands[1], 1, 0,
1628                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1629                          insn);
1630 }
1631   [(set_attr "type" "branch")
1632    (set_attr "branch_type" "icc")])
1633
1634 ;; XXX fpcmp nop braindamage
1635 (define_insn "*inverted_branch"
1636   [(set (pc)
1637         (if_then_else (match_operator 0 "noov_compare_operator"
1638                                       [(reg 100) (const_int 0)])
1639                       (pc)
1640                       (label_ref (match_operand 1 "" ""))))]
1641   ""
1642 {
1643   return output_cbranch (operands[0], operands[1], 1, 1,
1644                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1645                          insn);
1646 }
1647   [(set_attr "type" "branch")
1648    (set_attr "branch_type" "icc")])
1649
1650 ;; XXX fpcmp nop braindamage
1651 (define_insn "*normal_fp_branch"
1652   [(set (pc)
1653         (if_then_else (match_operator 1 "comparison_operator"
1654                                       [(match_operand:CCFP 0 "fcc_register_operand" "c")
1655                                        (const_int 0)])
1656                       (label_ref (match_operand 2 "" ""))
1657                       (pc)))]
1658   ""
1659 {
1660   return output_cbranch (operands[1], operands[2], 2, 0,
1661                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1662                          insn);
1663 }
1664   [(set_attr "type" "branch")
1665    (set_attr "branch_type" "fcc")])
1666
1667 ;; XXX fpcmp nop braindamage
1668 (define_insn "*inverted_fp_branch"
1669   [(set (pc)
1670         (if_then_else (match_operator 1 "comparison_operator"
1671                                       [(match_operand:CCFP 0 "fcc_register_operand" "c")
1672                                        (const_int 0)])
1673                       (pc)
1674                       (label_ref (match_operand 2 "" ""))))]
1675   ""
1676 {
1677   return output_cbranch (operands[1], operands[2], 2, 1,
1678                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1679                          insn);
1680 }
1681   [(set_attr "type" "branch")
1682    (set_attr "branch_type" "fcc")])
1683
1684 ;; XXX fpcmp nop braindamage
1685 (define_insn "*normal_fpe_branch"
1686   [(set (pc)
1687         (if_then_else (match_operator 1 "comparison_operator"
1688                                       [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1689                                        (const_int 0)])
1690                       (label_ref (match_operand 2 "" ""))
1691                       (pc)))]
1692   ""
1693 {
1694   return output_cbranch (operands[1], operands[2], 2, 0,
1695                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1696                          insn);
1697 }
1698   [(set_attr "type" "branch")
1699    (set_attr "branch_type" "fcc")])
1700
1701 ;; XXX fpcmp nop braindamage
1702 (define_insn "*inverted_fpe_branch"
1703   [(set (pc)
1704         (if_then_else (match_operator 1 "comparison_operator"
1705                                       [(match_operand:CCFPE 0 "fcc_register_operand" "c")
1706                                        (const_int 0)])
1707                       (pc)
1708                       (label_ref (match_operand 2 "" ""))))]
1709   ""
1710 {
1711   return output_cbranch (operands[1], operands[2], 2, 1,
1712                          final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1713                          insn);
1714 }
1715   [(set_attr "type" "branch")
1716    (set_attr "branch_type" "fcc")])
1717
1718 ;; SPARC V9-specific jump insns.  None of these are guaranteed to be
1719 ;; in the architecture.
1720
1721 ;; There are no 32 bit brreg insns.
1722
1723 ;; XXX
1724 (define_insn "*normal_int_branch_sp64"
1725   [(set (pc)
1726         (if_then_else (match_operator 0 "v9_register_compare_operator"
1727                                       [(match_operand:DI 1 "register_operand" "r")
1728                                        (const_int 0)])
1729                       (label_ref (match_operand 2 "" ""))
1730                       (pc)))]
1731   "TARGET_ARCH64"
1732 {
1733   return output_v9branch (operands[0], operands[2], 1, 2, 0,
1734                           final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1735                           insn);
1736 }
1737   [(set_attr "type" "branch")
1738    (set_attr "branch_type" "reg")])
1739
1740 ;; XXX
1741 (define_insn "*inverted_int_branch_sp64"
1742   [(set (pc)
1743         (if_then_else (match_operator 0 "v9_register_compare_operator"
1744                                       [(match_operand:DI 1 "register_operand" "r")
1745                                        (const_int 0)])
1746                       (pc)
1747                       (label_ref (match_operand 2 "" ""))))]
1748   "TARGET_ARCH64"
1749 {
1750   return output_v9branch (operands[0], operands[2], 1, 2, 1,
1751                           final_sequence && INSN_ANNULLED_BRANCH_P (insn),
1752                           insn);
1753 }
1754   [(set_attr "type" "branch")
1755    (set_attr "branch_type" "reg")])
1756
1757
1758 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1759
1760 ;; Load in operand 0 the (absolute) address of operand 1, which is a symbolic
1761 ;; value subject to a PC-relative relocation.  Operand 2 is a helper function
1762 ;; that adds the PC value at the call point to operand 0.
1763
1764 (define_insn "load_pcrel_sym<P:mode>"
1765   [(set (match_operand:P 0 "register_operand" "=r")
1766         (unspec:P [(match_operand:P 1 "symbolic_operand" "")
1767                    (match_operand:P 2 "call_address_operand" "")] UNSPEC_LOAD_PCREL_SYM))
1768    (clobber (reg:P 15))]
1769   ""
1770 {
1771   if (flag_delayed_branch)
1772     return "sethi\t%%hi(%a1-4), %0\n\tcall\t%a2\n\t add\t%0, %%lo(%a1+4), %0";
1773   else
1774     return "sethi\t%%hi(%a1-8), %0\n\tadd\t%0, %%lo(%a1-4), %0\n\tcall\t%a2\n\t nop";
1775 }
1776   [(set (attr "type") (const_string "multi"))
1777    (set (attr "length")
1778         (if_then_else (eq_attr "delayed_branch" "true")
1779                       (const_int 3)
1780                       (const_int 4)))])
1781
1782
1783 ;; Integer move instructions
1784
1785 (define_expand "movqi"
1786   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1787         (match_operand:QI 1 "general_operand" ""))]
1788   ""
1789 {
1790   if (sparc_expand_move (QImode, operands))
1791     DONE;
1792 })
1793
1794 (define_insn "*movqi_insn"
1795   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m")
1796         (match_operand:QI 1 "input_operand"   "rI,m,rJ"))]
1797   "(register_operand (operands[0], QImode)
1798     || register_or_zero_operand (operands[1], QImode))"
1799   "@
1800    mov\t%1, %0
1801    ldub\t%1, %0
1802    stb\t%r1, %0"
1803   [(set_attr "type" "*,load,store")
1804    (set_attr "us3load_type" "*,3cycle,*")])
1805
1806 (define_expand "movhi"
1807   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1808         (match_operand:HI 1 "general_operand" ""))]
1809   ""
1810 {
1811   if (sparc_expand_move (HImode, operands))
1812     DONE;
1813 })
1814
1815 (define_insn "*movhi_insn"
1816   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1817         (match_operand:HI 1 "input_operand"   "rI,K,m,rJ"))]
1818   "(register_operand (operands[0], HImode)
1819     || register_or_zero_operand (operands[1], HImode))"
1820   "@
1821    mov\t%1, %0
1822    sethi\t%%hi(%a1), %0
1823    lduh\t%1, %0
1824    sth\t%r1, %0"
1825   [(set_attr "type" "*,*,load,store")
1826    (set_attr "us3load_type" "*,*,3cycle,*")])
1827
1828 ;; We always work with constants here.
1829 (define_insn "*movhi_lo_sum"
1830   [(set (match_operand:HI 0 "register_operand" "=r")
1831         (ior:HI (match_operand:HI 1 "register_operand" "%r")
1832                 (match_operand:HI 2 "small_int_operand" "I")))]
1833   ""
1834   "or\t%1, %2, %0")
1835
1836 (define_expand "movsi"
1837   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1838         (match_operand:SI 1 "general_operand" ""))]
1839   ""
1840 {
1841   if (sparc_expand_move (SImode, operands))
1842     DONE;
1843 })
1844
1845 (define_insn "*movsi_insn"
1846   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m,!f,!f,!m,d")
1847         (match_operand:SI 1 "input_operand"   "rI,K,m,rJ,f,m,f,J"))]
1848   "(register_operand (operands[0], SImode)
1849     || register_or_zero_operand (operands[1], SImode))"
1850   "@
1851    mov\t%1, %0
1852    sethi\t%%hi(%a1), %0
1853    ld\t%1, %0
1854    st\t%r1, %0
1855    fmovs\t%1, %0
1856    ld\t%1, %0
1857    st\t%1, %0
1858    fzeros\t%0"
1859   [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga")])
1860
1861 (define_insn "*movsi_lo_sum"
1862   [(set (match_operand:SI 0 "register_operand" "=r")
1863         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1864                    (match_operand:SI 2 "immediate_operand" "in")))]
1865   ""
1866   "or\t%1, %%lo(%a2), %0")
1867
1868 (define_insn "*movsi_high"
1869   [(set (match_operand:SI 0 "register_operand" "=r")
1870         (high:SI (match_operand:SI 1 "immediate_operand" "in")))]
1871   ""
1872   "sethi\t%%hi(%a1), %0")
1873
1874 ;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC
1875 ;; so that CSE won't optimize the address computation away.
1876 (define_insn "movsi_lo_sum_pic"
1877   [(set (match_operand:SI 0 "register_operand" "=r")
1878         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1879                    (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
1880   "flag_pic"
1881   "or\t%1, %%lo(%a2), %0")
1882
1883 (define_insn "movsi_high_pic"
1884   [(set (match_operand:SI 0 "register_operand" "=r")
1885         (high:SI (unspec:SI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
1886   "flag_pic && check_pic (1)"
1887   "sethi\t%%hi(%a1), %0")
1888
1889 (define_expand "movsi_pic_label_ref"
1890   [(set (match_dup 3) (high:SI
1891      (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1892                  (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1893    (set (match_dup 4) (lo_sum:SI (match_dup 3)
1894      (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
1895    (set (match_operand:SI 0 "register_operand" "=r")
1896         (minus:SI (match_dup 5) (match_dup 4)))]
1897   "flag_pic"
1898 {
1899   crtl->uses_pic_offset_table = 1;
1900   operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
1901   if (!can_create_pseudo_p ())
1902     {
1903       operands[3] = operands[0];
1904       operands[4] = operands[0];
1905     }
1906   else
1907     {
1908       operands[3] = gen_reg_rtx (SImode);
1909       operands[4] = gen_reg_rtx (SImode);
1910     }
1911   operands[5] = pic_offset_table_rtx;
1912 })
1913
1914 (define_insn "*movsi_high_pic_label_ref"
1915   [(set (match_operand:SI 0 "register_operand" "=r")
1916       (high:SI
1917         (unspec:SI [(match_operand:SI 1 "label_ref_operand" "")
1918                     (match_operand:SI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1919   "flag_pic"
1920   "sethi\t%%hi(%a2-(%a1-.)), %0")
1921
1922 (define_insn "*movsi_lo_sum_pic_label_ref"
1923   [(set (match_operand:SI 0 "register_operand" "=r")
1924       (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
1925         (unspec:SI [(match_operand:SI 2 "label_ref_operand" "")
1926                     (match_operand:SI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
1927   "flag_pic"
1928   "or\t%1, %%lo(%a3-(%a2-.)), %0")
1929
1930 ;; Set up the PIC register for VxWorks.
1931
1932 (define_expand "vxworks_load_got"
1933   [(set (match_dup 0)
1934         (high:SI (match_dup 1)))
1935    (set (match_dup 0)
1936         (mem:SI (lo_sum:SI (match_dup 0) (match_dup 1))))
1937    (set (match_dup 0)
1938         (mem:SI (lo_sum:SI (match_dup 0) (match_dup 2))))]
1939   "TARGET_VXWORKS_RTP"
1940 {
1941   operands[0] = pic_offset_table_rtx;
1942   operands[1] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_BASE);
1943   operands[2] = gen_rtx_SYMBOL_REF (SImode, VXWORKS_GOTT_INDEX);
1944 })
1945
1946 (define_expand "movdi"
1947   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1948         (match_operand:DI 1 "general_operand" ""))]
1949   ""
1950 {
1951   if (sparc_expand_move (DImode, operands))
1952     DONE;
1953 })
1954
1955 ;; Be careful, fmovd does not exist when !v9.
1956 ;; We match MEM moves directly when we have correct even
1957 ;; numbered registers, but fall into splits otherwise.
1958 ;; The constraint ordering here is really important to
1959 ;; avoid insane problems in reload, especially for patterns
1960 ;; of the form:
1961 ;;
1962 ;; (set (mem:DI (plus:SI (reg:SI 30 %fp)
1963 ;;                       (const_int -5016)))
1964 ;;      (reg:DI 2 %g2))
1965 ;;
1966
1967 (define_insn "*movdi_insn_sp32"
1968   [(set (match_operand:DI 0 "nonimmediate_operand"
1969                                 "=o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
1970         (match_operand:DI 1 "input_operand"
1971                                 " J,U,T,r,o,i,r, f, T, o, f, f"))]
1972   "! TARGET_V9
1973    && (register_operand (operands[0], DImode)
1974        || register_or_zero_operand (operands[1], DImode))"
1975   "@
1976    #
1977    std\t%1, %0
1978    ldd\t%1, %0
1979    #
1980    #
1981    #
1982    #
1983    std\t%1, %0
1984    ldd\t%1, %0
1985    #
1986    #
1987    #"
1988   [(set_attr "type" "store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
1989    (set_attr "length" "2,*,*,2,2,2,2,*,*,2,2,2")])
1990
1991 (define_insn "*movdi_insn_sp32_v9"
1992   [(set (match_operand:DI 0 "nonimmediate_operand"
1993                                         "=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?e,?e,?W")
1994         (match_operand:DI 1 "input_operand"
1995                                         " J,J,U,T,r,o,i,r, f, T, o, f, e, W, e"))]
1996   "! TARGET_ARCH64
1997    && TARGET_V9
1998    && (register_operand (operands[0], DImode)
1999        || register_or_zero_operand (operands[1], DImode))"
2000   "@
2001    stx\t%%g0, %0
2002    #
2003    std\t%1, %0
2004    ldd\t%1, %0
2005    #
2006    #
2007    #
2008    #
2009    std\t%1, %0
2010    ldd\t%1, %0
2011    #
2012    #
2013    fmovd\\t%1, %0
2014    ldd\\t%1, %0
2015    std\\t%1, %0"
2016   [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,fpmove,fpload,fpstore")
2017    (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,*,*,*")
2018    (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])
2019
2020 (define_insn "*movdi_insn_sp64"
2021   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,m,?e,?e,?W,b")
2022         (match_operand:DI 1 "input_operand"   "rI,N,m,rJ,e,W,e,J"))]
2023   "TARGET_ARCH64
2024    && (register_operand (operands[0], DImode)
2025        || register_or_zero_operand (operands[1], DImode))"
2026   "@
2027    mov\t%1, %0
2028    sethi\t%%hi(%a1), %0
2029    ldx\t%1, %0
2030    stx\t%r1, %0
2031    fmovd\t%1, %0
2032    ldd\t%1, %0
2033    std\t%1, %0
2034    fzero\t%0"
2035   [(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga")
2036    (set_attr "fptype" "*,*,*,*,double,*,*,double")])
2037
2038 (define_expand "movdi_pic_label_ref"
2039   [(set (match_dup 3) (high:DI
2040      (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2041                  (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2042    (set (match_dup 4) (lo_sum:DI (match_dup 3)
2043      (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_MOVE_PIC_LABEL)))
2044    (set (match_operand:DI 0 "register_operand" "=r")
2045         (minus:DI (match_dup 5) (match_dup 4)))]
2046   "TARGET_ARCH64 && flag_pic"
2047 {
2048   crtl->uses_pic_offset_table = 1;
2049   operands[2] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
2050   if (!can_create_pseudo_p ())
2051     {
2052       operands[3] = operands[0];
2053       operands[4] = operands[0];
2054     }
2055   else
2056     {
2057       operands[3] = gen_reg_rtx (DImode);
2058       operands[4] = gen_reg_rtx (DImode);
2059     }
2060   operands[5] = pic_offset_table_rtx;
2061 })
2062
2063 (define_insn "*movdi_high_pic_label_ref"
2064   [(set (match_operand:DI 0 "register_operand" "=r")
2065         (high:DI
2066           (unspec:DI [(match_operand:DI 1 "label_ref_operand" "")
2067                       (match_operand:DI 2 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2068   "TARGET_ARCH64 && flag_pic"
2069   "sethi\t%%hi(%a2-(%a1-.)), %0")
2070
2071 (define_insn "*movdi_lo_sum_pic_label_ref"
2072   [(set (match_operand:DI 0 "register_operand" "=r")
2073       (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2074         (unspec:DI [(match_operand:DI 2 "label_ref_operand" "")
2075                     (match_operand:DI 3 "" "")] UNSPEC_MOVE_PIC_LABEL)))]
2076   "TARGET_ARCH64 && flag_pic"
2077   "or\t%1, %%lo(%a3-(%a2-.)), %0")
2078
2079 ;; SPARC-v9 code model support insns.  See sparc_emit_set_symbolic_const64
2080 ;; in sparc.c to see what is going on here... PIC stuff comes first.
2081
2082 (define_insn "movdi_lo_sum_pic"
2083   [(set (match_operand:DI 0 "register_operand" "=r")
2084         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2085                    (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] UNSPEC_MOVE_PIC)))]
2086   "TARGET_ARCH64 && flag_pic"
2087   "or\t%1, %%lo(%a2), %0")
2088
2089 (define_insn "movdi_high_pic"
2090   [(set (match_operand:DI 0 "register_operand" "=r")
2091         (high:DI (unspec:DI [(match_operand 1 "" "")] UNSPEC_MOVE_PIC)))]
2092   "TARGET_ARCH64 && flag_pic && check_pic (1)"
2093   "sethi\t%%hi(%a1), %0")
2094
2095 (define_insn "*sethi_di_medlow_embmedany_pic"
2096   [(set (match_operand:DI 0 "register_operand" "=r")
2097         (high:DI (match_operand:DI 1 "medium_pic_operand" "")))]
2098   "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)"
2099   "sethi\t%%hi(%a1), %0")
2100
2101 (define_insn "*sethi_di_medlow"
2102   [(set (match_operand:DI 0 "register_operand" "=r")
2103         (high:DI (match_operand:DI 1 "symbolic_operand" "")))]
2104   "TARGET_CM_MEDLOW && check_pic (1)"
2105   "sethi\t%%hi(%a1), %0")
2106
2107 (define_insn "*losum_di_medlow"
2108   [(set (match_operand:DI 0 "register_operand" "=r")
2109         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2110                    (match_operand:DI 2 "symbolic_operand" "")))]
2111   "TARGET_CM_MEDLOW"
2112   "or\t%1, %%lo(%a2), %0")
2113
2114 (define_insn "seth44"
2115   [(set (match_operand:DI 0 "register_operand" "=r")
2116         (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETH44)))]
2117   "TARGET_CM_MEDMID"
2118   "sethi\t%%h44(%a1), %0")
2119
2120 (define_insn "setm44"
2121   [(set (match_operand:DI 0 "register_operand" "=r")
2122         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2123                    (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_SETM44)))]
2124   "TARGET_CM_MEDMID"
2125   "or\t%1, %%m44(%a2), %0")
2126
2127 (define_insn "setl44"
2128   [(set (match_operand:DI 0 "register_operand" "=r")
2129         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2130                    (match_operand:DI 2 "symbolic_operand" "")))]
2131   "TARGET_CM_MEDMID"
2132   "or\t%1, %%l44(%a2), %0")
2133
2134 (define_insn "sethh"
2135   [(set (match_operand:DI 0 "register_operand" "=r")
2136         (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETHH)))]
2137   "TARGET_CM_MEDANY"
2138   "sethi\t%%hh(%a1), %0")
2139
2140 (define_insn "setlm"
2141   [(set (match_operand:DI 0 "register_operand" "=r")
2142         (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] UNSPEC_SETLM)))]
2143   "TARGET_CM_MEDANY"
2144   "sethi\t%%lm(%a1), %0")
2145
2146 (define_insn "sethm"
2147   [(set (match_operand:DI 0 "register_operand" "=r")
2148         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2149                    (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] UNSPEC_EMB_SETHM)))]
2150   "TARGET_CM_MEDANY"
2151   "or\t%1, %%hm(%a2), %0")
2152
2153 (define_insn "setlo"
2154   [(set (match_operand:DI 0 "register_operand" "=r")
2155         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2156                    (match_operand:DI 2 "symbolic_operand" "")))]
2157   "TARGET_CM_MEDANY"
2158   "or\t%1, %%lo(%a2), %0")
2159
2160 (define_insn "embmedany_sethi"
2161   [(set (match_operand:DI 0 "register_operand" "=r")
2162         (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] UNSPEC_EMB_HISUM)))]
2163   "TARGET_CM_EMBMEDANY && check_pic (1)"
2164   "sethi\t%%hi(%a1), %0")
2165
2166 (define_insn "embmedany_losum"
2167   [(set (match_operand:DI 0 "register_operand" "=r")
2168         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2169                    (match_operand:DI 2 "data_segment_operand" "")))]
2170   "TARGET_CM_EMBMEDANY"
2171   "add\t%1, %%lo(%a2), %0")
2172
2173 (define_insn "embmedany_brsum"
2174   [(set (match_operand:DI 0 "register_operand" "=r")
2175         (unspec:DI [(match_operand:DI 1 "register_operand" "r")] UNSPEC_EMB_HISUM))]
2176   "TARGET_CM_EMBMEDANY"
2177   "add\t%1, %_, %0")
2178
2179 (define_insn "embmedany_textuhi"
2180   [(set (match_operand:DI 0 "register_operand" "=r")
2181         (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTUHI)))]
2182   "TARGET_CM_EMBMEDANY && check_pic (1)"
2183   "sethi\t%%uhi(%a1), %0")
2184
2185 (define_insn "embmedany_texthi"
2186   [(set (match_operand:DI 0 "register_operand" "=r")
2187         (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] UNSPEC_EMB_TEXTHI)))]
2188   "TARGET_CM_EMBMEDANY && check_pic (1)"
2189   "sethi\t%%hi(%a1), %0")
2190
2191 (define_insn "embmedany_textulo"
2192   [(set (match_operand:DI 0 "register_operand" "=r")
2193         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2194                    (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] UNSPEC_EMB_TEXTULO)))]
2195   "TARGET_CM_EMBMEDANY"
2196   "or\t%1, %%ulo(%a2), %0")
2197
2198 (define_insn "embmedany_textlo"
2199   [(set (match_operand:DI 0 "register_operand" "=r")
2200         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
2201                    (match_operand:DI 2 "text_segment_operand" "")))]
2202   "TARGET_CM_EMBMEDANY"
2203   "or\t%1, %%lo(%a2), %0")
2204
2205 ;; Now some patterns to help reload out a bit.
2206 (define_expand "reload_indi"
2207   [(parallel [(match_operand:DI 0 "register_operand" "=r")
2208               (match_operand:DI 1 "immediate_operand" "")
2209               (match_operand:TI 2 "register_operand" "=&r")])]
2210   "(TARGET_CM_MEDANY
2211     || TARGET_CM_EMBMEDANY)
2212    && ! flag_pic"
2213 {
2214   sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2215   DONE;
2216 })
2217
2218 (define_expand "reload_outdi"
2219   [(parallel [(match_operand:DI 0 "register_operand" "=r")
2220               (match_operand:DI 1 "immediate_operand" "")
2221               (match_operand:TI 2 "register_operand" "=&r")])]
2222   "(TARGET_CM_MEDANY
2223     || TARGET_CM_EMBMEDANY)
2224    && ! flag_pic"
2225 {
2226   sparc_emit_set_symbolic_const64 (operands[0], operands[1], operands[2]);
2227   DONE;
2228 })
2229
2230 ;; Split up putting CONSTs and REGs into DI regs when !arch64
2231 (define_split
2232   [(set (match_operand:DI 0 "register_operand" "")
2233         (match_operand:DI 1 "const_int_operand" ""))]
2234   "! TARGET_ARCH64 && reload_completed"
2235   [(clobber (const_int 0))]
2236 {
2237 #if HOST_BITS_PER_WIDE_INT == 32
2238   emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2239                         (INTVAL (operands[1]) < 0) ?
2240                         constm1_rtx :
2241                         const0_rtx));
2242   emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2243                         operands[1]));
2244 #else
2245   unsigned int low, high;
2246
2247   low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
2248   high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
2249   emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
2250
2251   /* Slick... but this trick loses if this subreg constant part
2252      can be done in one insn.  */
2253   if (low == high
2254       && ! SPARC_SETHI32_P (high)
2255       && ! SPARC_SIMM13_P (high))
2256     emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2257                           gen_highpart (SImode, operands[0])));
2258   else
2259     emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low)));
2260 #endif
2261   DONE;
2262 })
2263
2264 (define_split
2265   [(set (match_operand:DI 0 "register_operand" "")
2266         (match_operand:DI 1 "const_double_operand" ""))]
2267   "reload_completed
2268    && (! TARGET_V9
2269        || (! TARGET_ARCH64
2270            && ((GET_CODE (operands[0]) == REG
2271                 && REGNO (operands[0]) < 32)
2272                || (GET_CODE (operands[0]) == SUBREG
2273                    && GET_CODE (SUBREG_REG (operands[0])) == REG
2274                    && REGNO (SUBREG_REG (operands[0])) < 32))))"
2275   [(clobber (const_int 0))]
2276 {
2277   emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
2278                         GEN_INT (CONST_DOUBLE_HIGH (operands[1]))));
2279
2280   /* Slick... but this trick loses if this subreg constant part
2281      can be done in one insn.  */
2282   if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1])
2283       && ! SPARC_SETHI32_P (CONST_DOUBLE_HIGH (operands[1]))
2284       && ! SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1])))
2285     {
2286       emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2287                             gen_highpart (SImode, operands[0])));
2288     }
2289   else
2290     {
2291       emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2292                             GEN_INT (CONST_DOUBLE_LOW (operands[1]))));
2293     }
2294   DONE;
2295 })
2296
2297 (define_split
2298   [(set (match_operand:DI 0 "register_operand" "")
2299         (match_operand:DI 1 "register_operand" ""))]
2300   "reload_completed
2301    && (! TARGET_V9
2302        || (! TARGET_ARCH64
2303            && ((GET_CODE (operands[0]) == REG
2304                 && REGNO (operands[0]) < 32)
2305                || (GET_CODE (operands[0]) == SUBREG
2306                    && GET_CODE (SUBREG_REG (operands[0])) == REG
2307                    && REGNO (SUBREG_REG (operands[0])) < 32))))"
2308   [(clobber (const_int 0))]
2309 {
2310   rtx set_dest = operands[0];
2311   rtx set_src = operands[1];
2312   rtx dest1, dest2;
2313   rtx src1, src2;
2314
2315   dest1 = gen_highpart (SImode, set_dest);
2316   dest2 = gen_lowpart (SImode, set_dest);
2317   src1 = gen_highpart (SImode, set_src);
2318   src2 = gen_lowpart (SImode, set_src);
2319
2320   /* Now emit using the real source and destination we found, swapping
2321      the order if we detect overlap.  */
2322   if (reg_overlap_mentioned_p (dest1, src2))
2323     {
2324       emit_insn (gen_movsi (dest2, src2));
2325       emit_insn (gen_movsi (dest1, src1));
2326     }
2327   else
2328     {
2329       emit_insn (gen_movsi (dest1, src1));
2330       emit_insn (gen_movsi (dest2, src2));
2331     }
2332   DONE;
2333 })
2334
2335 ;; Now handle the cases of memory moves from/to non-even
2336 ;; DI mode register pairs.
2337 (define_split
2338   [(set (match_operand:DI 0 "register_operand" "")
2339         (match_operand:DI 1 "memory_operand" ""))]
2340   "(! TARGET_ARCH64
2341     && reload_completed
2342     && sparc_splitdi_legitimate (operands[0], operands[1]))"
2343   [(clobber (const_int 0))]
2344 {
2345   rtx word0 = adjust_address (operands[1], SImode, 0);
2346   rtx word1 = adjust_address (operands[1], SImode, 4);
2347   rtx high_part = gen_highpart (SImode, operands[0]);
2348   rtx low_part = gen_lowpart (SImode, operands[0]);
2349
2350   if (reg_overlap_mentioned_p (high_part, word1))
2351     {
2352       emit_insn (gen_movsi (low_part, word1));
2353       emit_insn (gen_movsi (high_part, word0));
2354     }
2355   else
2356     {
2357       emit_insn (gen_movsi (high_part, word0));
2358       emit_insn (gen_movsi (low_part, word1));
2359     }
2360   DONE;
2361 })
2362
2363 (define_split
2364   [(set (match_operand:DI 0 "memory_operand" "")
2365         (match_operand:DI 1 "register_operand" ""))]
2366   "(! TARGET_ARCH64
2367     && reload_completed
2368     && sparc_splitdi_legitimate (operands[1], operands[0]))"
2369   [(clobber (const_int 0))]
2370 {
2371   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0),
2372                         gen_highpart (SImode, operands[1])));
2373   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
2374                         gen_lowpart (SImode, operands[1])));
2375   DONE;
2376 })
2377
2378 (define_split
2379   [(set (match_operand:DI 0 "memory_operand" "")
2380         (match_operand:DI 1 "const_zero_operand" ""))]
2381   "reload_completed
2382    && (! TARGET_V9
2383        || (! TARGET_ARCH64
2384            && ! mem_min_alignment (operands[0], 8)))
2385    && offsettable_memref_p (operands[0])"
2386   [(clobber (const_int 0))]
2387 {
2388   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx));
2389   emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx));
2390   DONE;
2391 })
2392
2393
2394 ;; Floating point and vector move instructions
2395
2396 ;; We don't define V1SI because SI should work just fine.
2397 (define_mode_iterator V32 [SF V2HI V4QI])
2398
2399 ;; Yes, you guessed it right, the former movsf expander.
2400 (define_expand "mov<V32:mode>"
2401   [(set (match_operand:V32 0 "nonimmediate_operand" "")
2402         (match_operand:V32 1 "general_operand" ""))]
2403   "<V32:MODE>mode == SFmode || TARGET_VIS"
2404 {
2405   if (sparc_expand_move (<V32:MODE>mode, operands))
2406     DONE;
2407 })
2408
2409 (define_insn "*movsf_insn"
2410   [(set (match_operand:V32 0 "nonimmediate_operand" "=d,f,*r,*r,*r,f,*r,m,m")
2411         (match_operand:V32 1 "input_operand"        "GY,f,*rRY,Q,S,m,m,f,*rGY"))]
2412   "TARGET_FPU
2413    && (register_operand (operands[0], <V32:MODE>mode)
2414        || register_or_zero_operand (operands[1], <V32:MODE>mode))"
2415 {
2416   if (GET_CODE (operands[1]) == CONST_DOUBLE
2417       && (which_alternative == 2
2418           || which_alternative == 3
2419           || which_alternative == 4))
2420     {
2421       REAL_VALUE_TYPE r;
2422       long i;
2423
2424       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2425       REAL_VALUE_TO_TARGET_SINGLE (r, i);
2426       operands[1] = GEN_INT (i);
2427     }
2428
2429   switch (which_alternative)
2430     {
2431     case 0:
2432       return "fzeros\t%0";
2433     case 1:
2434       return "fmovs\t%1, %0";
2435     case 2:
2436       return "mov\t%1, %0";
2437     case 3:
2438       return "sethi\t%%hi(%a1), %0";
2439     case 4:
2440       return "#";
2441     case 5:
2442     case 6:
2443       return "ld\t%1, %0";
2444     case 7:
2445     case 8:
2446       return "st\t%r1, %0";
2447     default:
2448       gcc_unreachable ();
2449     }
2450 }
2451   [(set_attr "type" "fga,fpmove,*,*,*,fpload,load,fpstore,store")])
2452
2453 ;; Exactly the same as above, except that all `f' cases are deleted.
2454 ;; This is necessary to prevent reload from ever trying to use a `f' reg
2455 ;; when -mno-fpu.
2456
2457 (define_insn "*movsf_insn_no_fpu"
2458   [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,m")
2459         (match_operand:SF 1 "input_operand"    "rR,Q,S,m,rG"))]
2460   "! TARGET_FPU
2461    && (register_operand (operands[0], SFmode)
2462        || register_or_zero_operand (operands[1], SFmode))"
2463 {
2464   if (GET_CODE (operands[1]) == CONST_DOUBLE
2465       && (which_alternative == 0
2466           || which_alternative == 1
2467           || which_alternative == 2))
2468     {
2469       REAL_VALUE_TYPE r;
2470       long i;
2471
2472       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2473       REAL_VALUE_TO_TARGET_SINGLE (r, i);
2474       operands[1] = GEN_INT (i);
2475     }
2476
2477   switch (which_alternative)
2478     {
2479     case 0:
2480       return "mov\t%1, %0";
2481     case 1:
2482       return "sethi\t%%hi(%a1), %0";
2483     case 2:
2484       return "#";
2485     case 3:
2486       return "ld\t%1, %0";
2487     case 4:
2488       return "st\t%r1, %0";
2489     default:
2490       gcc_unreachable ();
2491     }
2492 }
2493   [(set_attr "type" "*,*,*,load,store")])
2494
2495 ;; The following 3 patterns build SFmode constants in integer registers.
2496
2497 (define_insn "*movsf_lo_sum"
2498   [(set (match_operand:SF 0 "register_operand" "=r")
2499         (lo_sum:SF (match_operand:SF 1 "register_operand" "r")
2500                    (match_operand:SF 2 "fp_const_high_losum_operand" "S")))]
2501   ""
2502 {
2503   REAL_VALUE_TYPE r;
2504   long i;
2505
2506   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]);
2507   REAL_VALUE_TO_TARGET_SINGLE (r, i);
2508   operands[2] = GEN_INT (i);
2509   return "or\t%1, %%lo(%a2), %0";
2510 })
2511
2512 (define_insn "*movsf_high"
2513   [(set (match_operand:SF 0 "register_operand" "=r")
2514         (high:SF (match_operand:SF 1 "fp_const_high_losum_operand" "S")))]
2515   ""
2516 {
2517   REAL_VALUE_TYPE r;
2518   long i;
2519
2520   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2521   REAL_VALUE_TO_TARGET_SINGLE (r, i);
2522   operands[1] = GEN_INT (i);
2523   return "sethi\t%%hi(%1), %0";
2524 })
2525
2526 (define_split
2527   [(set (match_operand:SF 0 "register_operand" "")
2528         (match_operand:SF 1 "fp_const_high_losum_operand" ""))]
2529   "REG_P (operands[0]) && REGNO (operands[0]) < 32"
2530   [(set (match_dup 0) (high:SF (match_dup 1)))
2531    (set (match_dup 0) (lo_sum:SF (match_dup 0) (match_dup 1)))])
2532
2533 (define_mode_iterator V64 [DF V2SI V4HI V8QI])
2534
2535 ;; Yes, you again guessed it right, the former movdf expander.
2536 (define_expand "mov<V64:mode>"
2537   [(set (match_operand:V64 0 "nonimmediate_operand" "")
2538         (match_operand:V64 1 "general_operand" ""))]
2539   "<V64:MODE>mode == DFmode || TARGET_VIS"
2540 {
2541   if (sparc_expand_move (<V64:MODE>mode, operands))
2542     DONE;
2543 })
2544
2545 ;; Be careful, fmovd does not exist when !v9.
2546 (define_insn "*movdf_insn_sp32"
2547   [(set (match_operand:DF 0 "nonimmediate_operand" "=e,W,U,T,o,e,*r,o,e,o")
2548         (match_operand:DF 1 "input_operand"    "W#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
2549   "TARGET_FPU
2550    && ! TARGET_V9
2551    && (register_operand (operands[0], DFmode)
2552        || register_or_zero_operand (operands[1], DFmode))"
2553   "@
2554   ldd\t%1, %0
2555   std\t%1, %0
2556   ldd\t%1, %0
2557   std\t%1, %0
2558   #
2559   #
2560   #
2561   #
2562   #
2563   #"
2564  [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*")
2565   (set_attr "length" "*,*,*,*,2,2,2,2,2,2")])
2566
2567 (define_insn "*movdf_insn_sp32_no_fpu"
2568   [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
2569         (match_operand:DF 1 "input_operand"    "T,U,G,ro,r"))]
2570   "! TARGET_FPU
2571    && ! TARGET_V9
2572    && (register_operand (operands[0], DFmode)
2573        || register_or_zero_operand (operands[1], DFmode))"
2574   "@
2575   ldd\t%1, %0
2576   std\t%1, %0
2577   #
2578   #
2579   #"
2580   [(set_attr "type" "load,store,*,*,*")
2581    (set_attr "length" "*,*,2,2,2")])
2582
2583 ;; We have available v9 double floats but not 64-bit integer registers.
2584 (define_insn "*movdf_insn_sp32_v9"
2585   [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,T,W,U,T,f,*r,o")
2586         (match_operand:V64 1 "input_operand" "GY,e,W#F,GY,e,T,U,o#F,*roGYDF,*rGYf"))]
2587   "TARGET_FPU
2588    && TARGET_V9
2589    && ! TARGET_ARCH64
2590    && (register_operand (operands[0], <V64:MODE>mode)
2591        || register_or_zero_operand (operands[1], <V64:MODE>mode))"
2592   "@
2593   fzero\t%0
2594   fmovd\t%1, %0
2595   ldd\t%1, %0
2596   stx\t%r1, %0
2597   std\t%1, %0
2598   ldd\t%1, %0
2599   std\t%1, %0
2600   #
2601   #
2602   #"
2603   [(set_attr "type" "fga,fpmove,load,store,store,load,store,*,*,*")
2604    (set_attr "length" "*,*,*,*,*,*,*,2,2,2")
2605    (set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
2606
2607 (define_insn "*movdf_insn_sp32_v9_no_fpu"
2608   [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
2609         (match_operand:DF 1 "input_operand"    "T,U,G,ro,rG"))]
2610   "! TARGET_FPU
2611    && TARGET_V9
2612    && ! TARGET_ARCH64
2613    && (register_operand (operands[0], DFmode)
2614        || register_or_zero_operand (operands[1], DFmode))"
2615   "@
2616   ldd\t%1, %0
2617   std\t%1, %0
2618   stx\t%r1, %0
2619   #
2620   #"
2621   [(set_attr "type" "load,store,store,*,*")
2622    (set_attr "length" "*,*,*,2,2")])
2623
2624 ;; We have available both v9 double floats and 64-bit integer registers.
2625 (define_insn "*movdf_insn_sp64"
2626   [(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,W,*r,*r,m,*r")
2627         (match_operand:V64 1 "input_operand"    "GY,e,W#F,e,*rGY,m,*rGY,DF"))]
2628   "TARGET_FPU
2629    && TARGET_ARCH64
2630    && (register_operand (operands[0], <V64:MODE>mode)
2631        || register_or_zero_operand (operands[1], <V64:MODE>mode))"
2632   "@
2633   fzero\t%0
2634   fmovd\t%1, %0
2635   ldd\t%1, %0
2636   std\t%1, %0
2637   mov\t%r1, %0
2638   ldx\t%1, %0
2639   stx\t%r1, %0
2640   #"
2641   [(set_attr "type" "fga,fpmove,load,store,*,load,store,*")
2642    (set_attr "length" "*,*,*,*,*,*,*,2")
2643    (set_attr "fptype" "double,double,*,*,*,*,*,*")])
2644
2645 (define_insn "*movdf_insn_sp64_no_fpu"
2646   [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
2647         (match_operand:DF 1 "input_operand"    "r,m,rG"))]
2648   "! TARGET_FPU
2649    && TARGET_ARCH64
2650    && (register_operand (operands[0], DFmode)
2651        || register_or_zero_operand (operands[1], DFmode))"
2652   "@
2653   mov\t%1, %0
2654   ldx\t%1, %0
2655   stx\t%r1, %0"
2656   [(set_attr "type" "*,load,store")])
2657
2658 ;; This pattern builds V64mode constants in integer registers.
2659 (define_split
2660   [(set (match_operand:V64 0 "register_operand" "")
2661         (match_operand:V64 1 "const_double_or_vector_operand" ""))]
2662   "TARGET_FPU
2663    && (GET_CODE (operands[0]) == REG
2664        && REGNO (operands[0]) < 32)
2665    && ! const_zero_operand (operands[1], GET_MODE (operands[0]))
2666    && reload_completed"
2667   [(clobber (const_int 0))]
2668 {
2669   operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
2670
2671   if (TARGET_ARCH64)
2672     {
2673 #if HOST_BITS_PER_WIDE_INT == 32
2674       gcc_unreachable ();
2675 #else
2676       enum machine_mode mode = GET_MODE (operands[1]);
2677       rtx tem = simplify_subreg (DImode, operands[1], mode, 0);
2678       emit_insn (gen_movdi (operands[0], tem));
2679 #endif
2680     }
2681   else
2682     {
2683       enum machine_mode mode = GET_MODE (operands[1]);
2684       rtx hi = simplify_subreg (SImode, operands[1], mode, 0);
2685       rtx lo = simplify_subreg (SImode, operands[1], mode, 4);
2686
2687       gcc_assert (GET_CODE (hi) == CONST_INT);
2688       gcc_assert (GET_CODE (lo) == CONST_INT);
2689
2690       emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), hi));
2691
2692       /* Slick... but this trick loses if this subreg constant part
2693          can be done in one insn.  */
2694       if (lo == hi
2695           && ! SPARC_SETHI32_P (INTVAL (hi))
2696           && ! SPARC_SIMM13_P (INTVAL (hi)))
2697         {
2698           emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
2699                                 gen_highpart (SImode, operands[0])));
2700         }
2701       else
2702         {
2703           emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), lo));
2704         }
2705     }
2706   DONE;
2707 })
2708
2709 ;; Ok, now the splits to handle all the multi insn and
2710 ;; mis-aligned memory address cases.
2711 ;; In these splits please take note that we must be
2712 ;; careful when V9 but not ARCH64 because the integer
2713 ;; register DFmode cases must be handled.
2714 (define_split
2715   [(set (match_operand:V64 0 "register_operand" "")
2716         (match_operand:V64 1 "register_operand" ""))]
2717   "(! TARGET_V9
2718     || (! TARGET_ARCH64
2719         && ((GET_CODE (operands[0]) == REG
2720              && REGNO (operands[0]) < 32)
2721             || (GET_CODE (operands[0]) == SUBREG
2722                 && GET_CODE (SUBREG_REG (operands[0])) == REG
2723                 && REGNO (SUBREG_REG (operands[0])) < 32))))
2724    && reload_completed"
2725   [(clobber (const_int 0))]
2726 {
2727   rtx set_dest = operands[0];
2728   rtx set_src = operands[1];
2729   rtx dest1, dest2;
2730   rtx src1, src2;
2731   enum machine_mode half_mode;
2732
2733   /* We can be expanded for DFmode or integral vector modes.  */
2734   if (<V64:MODE>mode == DFmode)
2735     half_mode = SFmode;
2736   else
2737     half_mode = SImode;
2738   
2739   dest1 = gen_highpart (half_mode, set_dest);
2740   dest2 = gen_lowpart (half_mode, set_dest);
2741   src1 = gen_highpart (half_mode, set_src);
2742   src2 = gen_lowpart (half_mode, set_src);
2743
2744   /* Now emit using the real source and destination we found, swapping
2745      the order if we detect overlap.  */
2746   if (reg_overlap_mentioned_p (dest1, src2))
2747     {
2748       emit_move_insn_1 (dest2, src2);
2749       emit_move_insn_1 (dest1, src1);
2750     }
2751   else
2752     {
2753       emit_move_insn_1 (dest1, src1);
2754       emit_move_insn_1 (dest2, src2);
2755     }
2756   DONE;
2757 })
2758
2759 (define_split
2760   [(set (match_operand:V64 0 "register_operand" "")
2761         (match_operand:V64 1 "memory_operand" ""))]
2762   "reload_completed
2763    && ! TARGET_ARCH64
2764    && (((REGNO (operands[0]) % 2) != 0)
2765        || ! mem_min_alignment (operands[1], 8))
2766    && offsettable_memref_p (operands[1])"
2767   [(clobber (const_int 0))]
2768 {
2769   enum machine_mode half_mode;
2770   rtx word0, word1;
2771
2772   /* We can be expanded for DFmode or integral vector modes.  */
2773   if (<V64:MODE>mode == DFmode)
2774     half_mode = SFmode;
2775   else
2776     half_mode = SImode;
2777
2778   word0 = adjust_address (operands[1], half_mode, 0);
2779   word1 = adjust_address (operands[1], half_mode, 4);
2780
2781   if (reg_overlap_mentioned_p (gen_highpart (half_mode, operands[0]), word1))
2782     {
2783       emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2784       emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2785     }
2786   else
2787     {
2788       emit_move_insn_1 (gen_highpart (half_mode, operands[0]), word0);
2789       emit_move_insn_1 (gen_lowpart (half_mode, operands[0]), word1);
2790     }
2791   DONE;
2792 })
2793
2794 (define_split
2795   [(set (match_operand:V64 0 "memory_operand" "")
2796         (match_operand:V64 1 "register_operand" ""))]
2797   "reload_completed
2798    && ! TARGET_ARCH64
2799    && (((REGNO (operands[1]) % 2) != 0)
2800        || ! mem_min_alignment (operands[0], 8))
2801    && offsettable_memref_p (operands[0])"
2802   [(clobber (const_int 0))]
2803 {
2804   enum machine_mode half_mode;
2805   rtx word0, word1;
2806
2807   /* We can be expanded for DFmode or integral vector modes.  */
2808   if (<V64:MODE>mode == DFmode)
2809     half_mode = SFmode;
2810   else
2811     half_mode = SImode;
2812
2813   word0 = adjust_address (operands[0], half_mode, 0);
2814   word1 = adjust_address (operands[0], half_mode, 4);
2815
2816   emit_move_insn_1 (word0, gen_highpart (half_mode, operands[1]));
2817   emit_move_insn_1 (word1, gen_lowpart (half_mode, operands[1]));
2818   DONE;
2819 })
2820
2821 (define_split
2822   [(set (match_operand:V64 0 "memory_operand" "")
2823         (match_operand:V64 1 "const_zero_operand" ""))]
2824   "reload_completed
2825    && (! TARGET_V9
2826        || (! TARGET_ARCH64
2827            && ! mem_min_alignment (operands[0], 8)))
2828    && offsettable_memref_p (operands[0])"
2829   [(clobber (const_int 0))]
2830 {
2831   enum machine_mode half_mode;
2832   rtx dest1, dest2;
2833
2834   /* We can be expanded for DFmode or integral vector modes.  */
2835   if (<V64:MODE>mode == DFmode)
2836     half_mode = SFmode;
2837   else
2838     half_mode = SImode;
2839
2840   dest1 = adjust_address (operands[0], half_mode, 0);
2841   dest2 = adjust_address (operands[0], half_mode, 4);
2842
2843   emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2844   emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2845   DONE;
2846 })
2847
2848 (define_split
2849   [(set (match_operand:V64 0 "register_operand" "")
2850         (match_operand:V64 1 "const_zero_operand" ""))]
2851   "reload_completed
2852    && ! TARGET_ARCH64
2853    && ((GET_CODE (operands[0]) == REG
2854         && REGNO (operands[0]) < 32)
2855        || (GET_CODE (operands[0]) == SUBREG
2856            && GET_CODE (SUBREG_REG (operands[0])) == REG
2857            && REGNO (SUBREG_REG (operands[0])) < 32))"
2858   [(clobber (const_int 0))]
2859 {
2860   enum machine_mode half_mode;
2861   rtx set_dest = operands[0];
2862   rtx dest1, dest2;
2863
2864   /* We can be expanded for DFmode or integral vector modes.  */
2865   if (<V64:MODE>mode == DFmode)
2866     half_mode = SFmode;
2867   else
2868     half_mode = SImode;
2869
2870   dest1 = gen_highpart (half_mode, set_dest);
2871   dest2 = gen_lowpart (half_mode, set_dest);
2872   emit_move_insn_1 (dest1, CONST0_RTX (half_mode));
2873   emit_move_insn_1 (dest2, CONST0_RTX (half_mode));
2874   DONE;
2875 })
2876
2877 (define_expand "movtf"
2878   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2879         (match_operand:TF 1 "general_operand" ""))]
2880   ""
2881 {
2882   if (sparc_expand_move (TFmode, operands))
2883     DONE;
2884 })
2885
2886 (define_insn "*movtf_insn_sp32"
2887   [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,U,r")
2888         (match_operand:TF 1 "input_operand"    "G,oe,GeUr,o,roG"))]
2889   "TARGET_FPU
2890    && ! TARGET_ARCH64
2891    && (register_operand (operands[0], TFmode)
2892        || register_or_zero_operand (operands[1], TFmode))"
2893   "#"
2894   [(set_attr "length" "4")])
2895
2896 ;; Exactly the same as above, except that all `e' cases are deleted.
2897 ;; This is necessary to prevent reload from ever trying to use a `e' reg
2898 ;; when -mno-fpu.
2899
2900 (define_insn "*movtf_insn_sp32_no_fpu"
2901   [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
2902         (match_operand:TF 1 "input_operand"    "G,o,U,roG,r"))]
2903   "! TARGET_FPU
2904    && ! TARGET_ARCH64
2905    && (register_operand (operands[0], TFmode)
2906        || register_or_zero_operand (operands[1], TFmode))"
2907   "#"
2908   [(set_attr "length" "4")])
2909
2910 (define_insn "*movtf_insn_sp64"
2911   [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,o,r")
2912         (match_operand:TF 1 "input_operand"    "G,oe,Ger,roG"))]
2913   "TARGET_FPU
2914    && TARGET_ARCH64
2915    && ! TARGET_HARD_QUAD
2916    && (register_operand (operands[0], TFmode)
2917        || register_or_zero_operand (operands[1], TFmode))"
2918   "#"
2919   [(set_attr "length" "2")])
2920
2921 (define_insn "*movtf_insn_sp64_hq"
2922   [(set (match_operand:TF 0 "nonimmediate_operand" "=b,e,e,m,o,r")
2923         (match_operand:TF 1 "input_operand"    "G,e,m,e,rG,roG"))]
2924   "TARGET_FPU
2925    && TARGET_ARCH64
2926    && TARGET_HARD_QUAD
2927    && (register_operand (operands[0], TFmode)
2928        || register_or_zero_operand (operands[1], TFmode))"
2929   "@
2930   #
2931   fmovq\t%1, %0
2932   ldq\t%1, %0
2933   stq\t%1, %0
2934   #
2935   #"
2936   [(set_attr "type" "*,fpmove,fpload,fpstore,*,*")
2937    (set_attr "length" "2,*,*,*,2,2")])
2938
2939 (define_insn "*movtf_insn_sp64_no_fpu"
2940   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
2941         (match_operand:TF 1 "input_operand"    "orG,rG"))]
2942   "! TARGET_FPU
2943    && TARGET_ARCH64
2944    && (register_operand (operands[0], TFmode)
2945        || register_or_zero_operand (operands[1], TFmode))"
2946   "#"
2947   [(set_attr "length" "2")])
2948
2949 ;; Now all the splits to handle multi-insn TF mode moves.
2950 (define_split
2951   [(set (match_operand:TF 0 "register_operand" "")
2952         (match_operand:TF 1 "register_operand" ""))]
2953   "reload_completed
2954    && (! TARGET_ARCH64
2955        || (TARGET_FPU
2956            && ! TARGET_HARD_QUAD)
2957        || ! fp_register_operand (operands[0], TFmode))"
2958   [(clobber (const_int 0))]
2959 {
2960   rtx set_dest = operands[0];
2961   rtx set_src = operands[1];
2962   rtx dest1, dest2;
2963   rtx src1, src2;
2964
2965   dest1 = gen_df_reg (set_dest, 0);
2966   dest2 = gen_df_reg (set_dest, 1);
2967   src1 = gen_df_reg (set_src, 0);
2968   src2 = gen_df_reg (set_src, 1);
2969
2970   /* Now emit using the real source and destination we found, swapping
2971      the order if we detect overlap.  */
2972   if (reg_overlap_mentioned_p (dest1, src2))
2973     {
2974       emit_insn (gen_movdf (dest2, src2));
2975       emit_insn (gen_movdf (dest1, src1));
2976     }
2977   else
2978     {
2979       emit_insn (gen_movdf (dest1, src1));
2980       emit_insn (gen_movdf (dest2, src2));
2981     }
2982   DONE;
2983 })
2984
2985 (define_split
2986   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2987         (match_operand:TF 1 "const_zero_operand" ""))]
2988   "reload_completed"
2989   [(clobber (const_int 0))]
2990 {
2991   rtx set_dest = operands[0];
2992   rtx dest1, dest2;
2993
2994   switch (GET_CODE (set_dest))
2995     {
2996     case REG:
2997       dest1 = gen_df_reg (set_dest, 0);
2998       dest2 = gen_df_reg (set_dest, 1);
2999       break;
3000     case MEM:
3001       dest1 = adjust_address (set_dest, DFmode, 0);
3002       dest2 = adjust_address (set_dest, DFmode, 8);
3003       break;
3004     default:
3005       gcc_unreachable ();      
3006     }
3007
3008   emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
3009   emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
3010   DONE;
3011 })
3012
3013 (define_split
3014   [(set (match_operand:TF 0 "register_operand" "")
3015         (match_operand:TF 1 "memory_operand" ""))]
3016   "(reload_completed
3017     && offsettable_memref_p (operands[1])
3018     && (! TARGET_ARCH64
3019         || ! TARGET_HARD_QUAD
3020         || ! fp_register_operand (operands[0], TFmode)))"
3021   [(clobber (const_int 0))]
3022 {
3023   rtx word0 = adjust_address (operands[1], DFmode, 0);
3024   rtx word1 = adjust_address (operands[1], DFmode, 8);
3025   rtx set_dest, dest1, dest2;
3026
3027   set_dest = operands[0];
3028
3029   dest1 = gen_df_reg (set_dest, 0);
3030   dest2 = gen_df_reg (set_dest, 1);
3031
3032   /* Now output, ordering such that we don't clobber any registers
3033      mentioned in the address.  */
3034   if (reg_overlap_mentioned_p (dest1, word1))
3035
3036     {
3037       emit_insn (gen_movdf (dest2, word1));
3038       emit_insn (gen_movdf (dest1, word0));
3039     }
3040   else
3041    {
3042       emit_insn (gen_movdf (dest1, word0));
3043       emit_insn (gen_movdf (dest2, word1));
3044    }
3045   DONE;
3046 })
3047
3048 (define_split
3049   [(set (match_operand:TF 0 "memory_operand" "")
3050         (match_operand:TF 1 "register_operand" ""))]
3051   "(reload_completed
3052     && offsettable_memref_p (operands[0])
3053     && (! TARGET_ARCH64
3054         || ! TARGET_HARD_QUAD
3055         || ! fp_register_operand (operands[1], TFmode)))"
3056   [(clobber (const_int 0))]
3057 {
3058   rtx set_src = operands[1];
3059
3060   emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 0),
3061                         gen_df_reg (set_src, 0)));
3062   emit_insn (gen_movdf (adjust_address (operands[0], DFmode, 8),
3063                         gen_df_reg (set_src, 1)));
3064   DONE;
3065 })
3066
3067
3068 ;; SPARC-V9 conditional move instructions
3069
3070 ;; We can handle larger constants here for some flavors, but for now we keep
3071 ;; it simple and only allow those constants supported by all flavors.
3072 ;; Note that emit_conditional_move canonicalizes operands 2,3 so that operand
3073 ;; 3 contains the constant if one is present, but we handle either for
3074 ;; generality (sparc.c puts a constant in operand 2).
3075
3076 (define_mode_iterator I [QI HI SI DI])
3077
3078 (define_expand "mov<I:mode>cc"
3079   [(set (match_operand:I 0 "register_operand" "")
3080         (if_then_else:I (match_operand 1 "comparison_operator" "")
3081                         (match_operand:I 2 "arith10_operand" "")
3082                         (match_operand:I 3 "arith10_operand" "")))]
3083   "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
3084 {
3085   enum rtx_code code = GET_CODE (operands[1]);
3086
3087   if (GET_MODE (sparc_compare_op0) == DImode
3088       && ! TARGET_ARCH64)
3089     FAIL;
3090
3091   if (sparc_compare_op1 == const0_rtx
3092       && GET_CODE (sparc_compare_op0) == REG
3093       && GET_MODE (sparc_compare_op0) == DImode
3094       && v9_regcmp_p (code))
3095     operands[1] = gen_rtx_fmt_ee (code, DImode, sparc_compare_op0, const0_rtx);
3096   else
3097     operands[1] = gen_compare_operator (code);
3098 })
3099
3100 (define_mode_iterator F [SF DF TF])
3101
3102 (define_expand "mov<F:mode>cc"
3103   [(set (match_operand:F 0 "register_operand" "")
3104         (if_then_else:F (match_operand 1 "comparison_operator" "")
3105                         (match_operand:F 2 "register_operand" "")
3106                         (match_operand:F 3 "register_operand" "")))]
3107   "TARGET_V9 && TARGET_FPU"
3108 {
3109   enum rtx_code code = GET_CODE (operands[1]);
3110
3111   if (GET_MODE (sparc_compare_op0) == DImode
3112       && ! TARGET_ARCH64)
3113     FAIL;
3114
3115   if (sparc_compare_op1 == const0_rtx
3116       && GET_CODE (sparc_compare_op0) == REG
3117       && GET_MODE (sparc_compare_op0) == DImode
3118       && v9_regcmp_p (code))
3119     operands[1] = gen_rtx_fmt_ee (code, DImode, sparc_compare_op0, const0_rtx);
3120   else
3121     operands[1] = gen_compare_operator (code);
3122 })
3123
3124 ;; Conditional move define_insns
3125
3126 (define_insn "*mov<I:mode>_cc_v9"
3127   [(set (match_operand:I 0 "register_operand" "=r,r")
3128         (if_then_else:I (match_operator 1 "comparison_operator"
3129                                [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3130                                 (const_int 0)])
3131                         (match_operand:I 3 "arith11_operand" "rL,0")
3132                         (match_operand:I 4 "arith11_operand" "0,rL")))]
3133   "TARGET_V9 && !(<I:MODE>mode == DImode && TARGET_ARCH32)"
3134   "@
3135    mov%C1\t%x2, %3, %0
3136    mov%c1\t%x2, %4, %0"
3137   [(set_attr "type" "cmove")])
3138
3139 (define_insn "*mov<I:mode>_cc_reg_sp64"
3140   [(set (match_operand:I 0 "register_operand" "=r,r")
3141         (if_then_else:I (match_operator 1 "v9_register_compare_operator"
3142                                 [(match_operand:DI 2 "register_operand" "r,r")
3143                                  (const_int 0)])
3144                         (match_operand:I 3 "arith10_operand" "rM,0")
3145                         (match_operand:I 4 "arith10_operand" "0,rM")))]
3146   "TARGET_ARCH64"
3147   "@
3148    movr%D1\t%2, %r3, %0
3149    movr%d1\t%2, %r4, %0"
3150   [(set_attr "type" "cmove")])
3151
3152 (define_insn "*movsf_cc_v9"
3153   [(set (match_operand:SF 0 "register_operand" "=f,f")
3154         (if_then_else:SF (match_operator 1 "comparison_operator"
3155                                 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3156                                  (const_int 0)])
3157                          (match_operand:SF 3 "register_operand" "f,0")
3158                          (match_operand:SF 4 "register_operand" "0,f")))]
3159   "TARGET_V9 && TARGET_FPU"
3160   "@
3161    fmovs%C1\t%x2, %3, %0
3162    fmovs%c1\t%x2, %4, %0"
3163   [(set_attr "type" "fpcmove")])
3164
3165 (define_insn "*movsf_cc_reg_sp64"
3166   [(set (match_operand:SF 0 "register_operand" "=f,f")
3167         (if_then_else:SF (match_operator 1 "v9_register_compare_operator"
3168                                 [(match_operand:DI 2 "register_operand" "r,r")
3169                                  (const_int 0)])
3170                          (match_operand:SF 3 "register_operand" "f,0")
3171                          (match_operand:SF 4 "register_operand" "0,f")))]
3172   "TARGET_ARCH64 && TARGET_FPU"
3173   "@
3174    fmovrs%D1\t%2, %3, %0
3175    fmovrs%d1\t%2, %4, %0"
3176   [(set_attr "type" "fpcrmove")])
3177
3178 ;; Named because invoked by movtf_cc_v9
3179 (define_insn "movdf_cc_v9"
3180   [(set (match_operand:DF 0 "register_operand" "=e,e")
3181         (if_then_else:DF (match_operator 1 "comparison_operator"
3182                                 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3183                                  (const_int 0)])
3184                          (match_operand:DF 3 "register_operand" "e,0")
3185                          (match_operand:DF 4 "register_operand" "0,e")))]
3186   "TARGET_V9 && TARGET_FPU"
3187   "@
3188    fmovd%C1\t%x2, %3, %0
3189    fmovd%c1\t%x2, %4, %0"
3190   [(set_attr "type" "fpcmove")
3191    (set_attr "fptype" "double")])
3192
3193 ;; Named because invoked by movtf_cc_reg_sp64
3194 (define_insn "movdf_cc_reg_sp64"
3195   [(set (match_operand:DF 0 "register_operand" "=e,e")
3196         (if_then_else:DF (match_operator 1 "v9_register_compare_operator"
3197                                 [(match_operand:DI 2 "register_operand" "r,r")
3198                                  (const_int 0)])
3199                          (match_operand:DF 3 "register_operand" "e,0")
3200                          (match_operand:DF 4 "register_operand" "0,e")))]
3201   "TARGET_ARCH64 && TARGET_FPU"
3202   "@
3203    fmovrd%D1\t%2, %3, %0
3204    fmovrd%d1\t%2, %4, %0"
3205   [(set_attr "type" "fpcrmove")
3206    (set_attr "fptype" "double")])
3207
3208 (define_insn "*movtf_cc_hq_v9"
3209   [(set (match_operand:TF 0 "register_operand" "=e,e")
3210         (if_then_else:TF (match_operator 1 "comparison_operator"
3211                                 [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3212                                  (const_int 0)])
3213                          (match_operand:TF 3 "register_operand" "e,0")
3214                          (match_operand:TF 4 "register_operand" "0,e")))]
3215   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3216   "@
3217    fmovq%C1\t%x2, %3, %0
3218    fmovq%c1\t%x2, %4, %0"
3219   [(set_attr "type" "fpcmove")])
3220
3221 (define_insn "*movtf_cc_reg_hq_sp64"
3222   [(set (match_operand:TF 0 "register_operand" "=e,e")
3223         (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
3224                                 [(match_operand:DI 2 "register_operand" "r,r")
3225                                  (const_int 0)])
3226                          (match_operand:TF 3 "register_operand" "e,0")
3227                          (match_operand:TF 4 "register_operand" "0,e")))]
3228   "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD"
3229   "@
3230    fmovrq%D1\t%2, %3, %0
3231    fmovrq%d1\t%2, %4, %0"
3232   [(set_attr "type" "fpcrmove")])
3233
3234 (define_insn_and_split "*movtf_cc_v9"
3235   [(set (match_operand:TF 0 "register_operand" "=e,e")
3236         (if_then_else:TF (match_operator 1 "comparison_operator"
3237                             [(match_operand 2 "icc_or_fcc_register_operand" "X,X")
3238                              (const_int 0)])
3239                          (match_operand:TF 3 "register_operand" "e,0")
3240                          (match_operand:TF 4 "register_operand" "0,e")))]
3241   "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD"
3242   "#"
3243   "&& reload_completed"
3244   [(clobber (const_int 0))]
3245 {
3246   rtx set_dest = operands[0];
3247   rtx set_srca = operands[3];
3248   rtx set_srcb = operands[4];
3249   int third = rtx_equal_p (set_dest, set_srca);
3250   rtx dest1, dest2;
3251   rtx srca1, srca2, srcb1, srcb2;
3252
3253   dest1 = gen_df_reg (set_dest, 0);
3254   dest2 = gen_df_reg (set_dest, 1);
3255   srca1 = gen_df_reg (set_srca, 0);
3256   srca2 = gen_df_reg (set_srca, 1);
3257   srcb1 = gen_df_reg (set_srcb, 0);
3258   srcb2 = gen_df_reg (set_srcb, 1);
3259
3260   /* Now emit using the real source and destination we found, swapping
3261      the order if we detect overlap.  */
3262   if ((third && reg_overlap_mentioned_p (dest1, srcb2))
3263       || (!third && reg_overlap_mentioned_p (dest1, srca2)))
3264     {
3265       emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, srcb2));
3266       emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, srcb1));
3267     }
3268   else
3269     {
3270       emit_insn (gen_movdf_cc_v9 (dest1, operands[1], operands[2], srca1, srcb1));
3271       emit_insn (gen_movdf_cc_v9 (dest2, operands[1], operands[2], srca2, srcb2));
3272     }
3273   DONE;
3274 }
3275   [(set_attr "length" "2")])
3276
3277 (define_insn_and_split "*movtf_cc_reg_sp64"
3278   [(set (match_operand:TF 0 "register_operand" "=e,e")
3279         (if_then_else:TF (match_operator 1 "v9_register_compare_operator"
3280                                 [(match_operand:DI 2 "register_operand" "r,r")
3281                                  (const_int 0)])
3282                          (match_operand:TF 3 "register_operand" "e,0")
3283                          (match_operand:TF 4 "register_operand" "0,e")))]
3284   "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD"
3285   "#"
3286   "&& reload_completed"
3287   [(clobber (const_int 0))]
3288 {
3289   rtx set_dest = operands[0];
3290   rtx set_srca = operands[3];
3291   rtx set_srcb = operands[4];
3292   int third = rtx_equal_p (set_dest, set_srca);
3293   rtx dest1, dest2;
3294   rtx srca1, srca2, srcb1, srcb2;
3295
3296   dest1 = gen_df_reg (set_dest, 0);
3297   dest2 = gen_df_reg (set_dest, 1);
3298   srca1 = gen_df_reg (set_srca, 0);
3299   srca2 = gen_df_reg (set_srca, 1);
3300   srcb1 = gen_df_reg (set_srcb, 0);
3301   srcb2 = gen_df_reg (set_srcb, 1);
3302
3303   /* Now emit using the real source and destination we found, swapping
3304      the order if we detect overlap.  */
3305   if ((third && reg_overlap_mentioned_p (dest1, srcb2))
3306       || (!third && reg_overlap_mentioned_p (dest1, srca2)))
3307     {
3308       emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3309       emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3310     }
3311   else
3312     {
3313       emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1));
3314       emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2));
3315     }
3316   DONE;
3317 }
3318   [(set_attr "length" "2")])
3319
3320 \f
3321 ;; Zero-extension instructions
3322
3323 ;; These patterns originally accepted general_operands, however, slightly
3324 ;; better code is generated by only accepting register_operands, and then
3325 ;; letting combine generate the ldu[hb] insns.
3326
3327 (define_expand "zero_extendhisi2"
3328   [(set (match_operand:SI 0 "register_operand" "")
3329         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
3330   ""
3331 {
3332   rtx temp = gen_reg_rtx (SImode);
3333   rtx shift_16 = GEN_INT (16);
3334   int op1_subbyte = 0;
3335
3336   if (GET_CODE (operand1) == SUBREG)
3337     {
3338       op1_subbyte = SUBREG_BYTE (operand1);
3339       op1_subbyte /= GET_MODE_SIZE (SImode);
3340       op1_subbyte *= GET_MODE_SIZE (SImode);
3341       operand1 = XEXP (operand1, 0);
3342     }
3343
3344   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3345                           shift_16));
3346   emit_insn (gen_lshrsi3 (operand0, temp, shift_16));
3347   DONE;
3348 })
3349
3350 (define_insn "*zero_extendhisi2_insn"
3351   [(set (match_operand:SI 0 "register_operand" "=r")
3352         (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3353   ""
3354   "lduh\t%1, %0"
3355   [(set_attr "type" "load")
3356    (set_attr "us3load_type" "3cycle")])
3357
3358 (define_expand "zero_extendqihi2"
3359   [(set (match_operand:HI 0 "register_operand" "")
3360         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
3361   ""
3362   "")
3363
3364 (define_insn "*zero_extendqihi2_insn"
3365   [(set (match_operand:HI 0 "register_operand" "=r,r")
3366         (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))]
3367   "GET_CODE (operands[1]) != CONST_INT"
3368   "@
3369    and\t%1, 0xff, %0
3370    ldub\t%1, %0"
3371   [(set_attr "type" "*,load")
3372    (set_attr "us3load_type" "*,3cycle")])
3373
3374 (define_expand "zero_extendqisi2"
3375   [(set (match_operand:SI 0 "register_operand" "")
3376         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
3377   ""
3378   "")
3379
3380 (define_insn "*zero_extendqisi2_insn"
3381   [(set (match_operand:SI 0 "register_operand" "=r,r")
3382         (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))]
3383   "GET_CODE (operands[1]) != CONST_INT"
3384   "@
3385    and\t%1, 0xff, %0
3386    ldub\t%1, %0"
3387   [(set_attr "type" "*,load")
3388    (set_attr "us3load_type" "*,3cycle")])
3389
3390 (define_expand "zero_extendqidi2"
3391   [(set (match_operand:DI 0 "register_operand" "")
3392         (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
3393   "TARGET_ARCH64"
3394   "")
3395
3396 (define_insn "*zero_extendqidi2_insn"
3397   [(set (match_operand:DI 0 "register_operand" "=r,r")
3398         (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))]
3399   "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
3400   "@
3401    and\t%1, 0xff, %0
3402    ldub\t%1, %0"
3403   [(set_attr "type" "*,load")
3404    (set_attr "us3load_type" "*,3cycle")])
3405
3406 (define_expand "zero_extendhidi2"
3407   [(set (match_operand:DI 0 "register_operand" "")
3408         (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
3409   "TARGET_ARCH64"
3410 {
3411   rtx temp = gen_reg_rtx (DImode);
3412   rtx shift_48 = GEN_INT (48);
3413   int op1_subbyte = 0;
3414
3415   if (GET_CODE (operand1) == SUBREG)
3416     {
3417       op1_subbyte = SUBREG_BYTE (operand1);
3418       op1_subbyte /= GET_MODE_SIZE (DImode);
3419       op1_subbyte *= GET_MODE_SIZE (DImode);
3420       operand1 = XEXP (operand1, 0);
3421     }
3422
3423   emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3424                           shift_48));
3425   emit_insn (gen_lshrdi3 (operand0, temp, shift_48));
3426   DONE;
3427 })
3428
3429 (define_insn "*zero_extendhidi2_insn"
3430   [(set (match_operand:DI 0 "register_operand" "=r")
3431         (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3432   "TARGET_ARCH64"
3433   "lduh\t%1, %0"
3434   [(set_attr "type" "load")
3435    (set_attr "us3load_type" "3cycle")])
3436
3437 ;; ??? Write truncdisi pattern using sra?
3438
3439 (define_expand "zero_extendsidi2"
3440   [(set (match_operand:DI 0 "register_operand" "")
3441         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
3442   ""
3443   "")
3444
3445 (define_insn "*zero_extendsidi2_insn_sp64"
3446   [(set (match_operand:DI 0 "register_operand" "=r,r")
3447         (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
3448   "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT"
3449   "@
3450    srl\t%1, 0, %0
3451    lduw\t%1, %0"
3452   [(set_attr "type" "shift,load")])
3453
3454 (define_insn_and_split "*zero_extendsidi2_insn_sp32"
3455   [(set (match_operand:DI 0 "register_operand" "=r")
3456         (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
3457   "! TARGET_ARCH64"
3458   "#"
3459   "&& reload_completed"
3460   [(set (match_dup 2) (match_dup 3))
3461    (set (match_dup 4) (match_dup 5))]
3462 {
3463   rtx dest1, dest2;
3464
3465   dest1 = gen_highpart (SImode, operands[0]);
3466   dest2 = gen_lowpart (SImode, operands[0]);
3467
3468   /* Swap the order in case of overlap.  */
3469   if (REGNO (dest1) == REGNO (operands[1]))
3470     {
3471       operands[2] = dest2;
3472       operands[3] = operands[1];
3473       operands[4] = dest1;
3474       operands[5] = const0_rtx;
3475     }
3476   else
3477     {
3478       operands[2] = dest1;
3479       operands[3] = const0_rtx;
3480       operands[4] = dest2;
3481       operands[5] = operands[1];
3482     }
3483 }
3484   [(set_attr "length" "2")])
3485
3486 ;; Simplify comparisons of extended values.
3487
3488 (define_insn "*cmp_zero_extendqisi2"
3489   [(set (reg:CC 100)
3490         (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r"))
3491                     (const_int 0)))]
3492   ""
3493   "andcc\t%0, 0xff, %%g0"
3494   [(set_attr "type" "compare")])
3495
3496 (define_insn "*cmp_zero_qi"
3497   [(set (reg:CC 100)
3498         (compare:CC (match_operand:QI 0 "register_operand" "r")
3499                     (const_int 0)))]
3500   ""
3501   "andcc\t%0, 0xff, %%g0"
3502   [(set_attr "type" "compare")])
3503
3504 (define_insn "*cmp_zero_extendqisi2_set"
3505   [(set (reg:CC 100)
3506         (compare:CC (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))
3507                     (const_int 0)))
3508    (set (match_operand:SI 0 "register_operand" "=r")
3509         (zero_extend:SI (match_dup 1)))]
3510   ""
3511   "andcc\t%1, 0xff, %0"
3512   [(set_attr "type" "compare")])
3513
3514 (define_insn "*cmp_zero_extendqisi2_andcc_set"
3515   [(set (reg:CC 100)
3516         (compare:CC (and:SI (match_operand:SI 1 "register_operand" "r")
3517                             (const_int 255))
3518                     (const_int 0)))
3519    (set (match_operand:SI 0 "register_operand" "=r")
3520         (zero_extend:SI (subreg:QI (match_dup 1) 0)))]
3521   ""
3522   "andcc\t%1, 0xff, %0"
3523   [(set_attr "type" "compare")])
3524
3525 (define_insn "*cmp_zero_extendqidi2"
3526   [(set (reg:CCX 100)
3527         (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r"))
3528                      (const_int 0)))]
3529   "TARGET_ARCH64"
3530   "andcc\t%0, 0xff, %%g0"
3531   [(set_attr "type" "compare")])
3532
3533 (define_insn "*cmp_zero_qi_sp64"
3534   [(set (reg:CCX 100)
3535         (compare:CCX (match_operand:QI 0 "register_operand" "r")
3536                      (const_int 0)))]
3537   "TARGET_ARCH64"
3538   "andcc\t%0, 0xff, %%g0"
3539   [(set_attr "type" "compare")])
3540
3541 (define_insn "*cmp_zero_extendqidi2_set"
3542   [(set (reg:CCX 100)
3543         (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
3544                      (const_int 0)))
3545    (set (match_operand:DI 0 "register_operand" "=r")
3546         (zero_extend:DI (match_dup 1)))]
3547   "TARGET_ARCH64"
3548   "andcc\t%1, 0xff, %0"
3549   [(set_attr "type" "compare")])
3550
3551 (define_insn "*cmp_zero_extendqidi2_andcc_set"
3552   [(set (reg:CCX 100)
3553         (compare:CCX (and:DI (match_operand:DI 1 "register_operand" "r")
3554                              (const_int 255))
3555                      (const_int 0)))
3556    (set (match_operand:DI 0 "register_operand" "=r")
3557         (zero_extend:DI (subreg:QI (match_dup 1) 0)))]
3558   "TARGET_ARCH64"
3559   "andcc\t%1, 0xff, %0"
3560   [(set_attr "type" "compare")])
3561
3562 ;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare.
3563
3564 (define_insn "*cmp_siqi_trunc"
3565   [(set (reg:CC 100)
3566         (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 3)
3567                     (const_int 0)))]
3568   ""
3569   "andcc\t%0, 0xff, %%g0"
3570   [(set_attr "type" "compare")])
3571
3572 (define_insn "*cmp_siqi_trunc_set"
3573   [(set (reg:CC 100)
3574         (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 3)
3575                     (const_int 0)))
3576    (set (match_operand:QI 0 "register_operand" "=r")
3577         (subreg:QI (match_dup 1) 3))]
3578   ""
3579   "andcc\t%1, 0xff, %0"
3580   [(set_attr "type" "compare")])
3581
3582 (define_insn "*cmp_diqi_trunc"
3583   [(set (reg:CC 100)
3584         (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 7)
3585                     (const_int 0)))]
3586   "TARGET_ARCH64"
3587   "andcc\t%0, 0xff, %%g0"
3588   [(set_attr "type" "compare")])
3589
3590 (define_insn "*cmp_diqi_trunc_set"
3591   [(set (reg:CC 100)
3592         (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 7)
3593                     (const_int 0)))
3594    (set (match_operand:QI 0 "register_operand" "=r")
3595         (subreg:QI (match_dup 1) 7))]
3596   "TARGET_ARCH64"
3597   "andcc\t%1, 0xff, %0"
3598   [(set_attr "type" "compare")])
3599 \f
3600
3601 ;; Sign-extension instructions
3602
3603 ;; These patterns originally accepted general_operands, however, slightly
3604 ;; better code is generated by only accepting register_operands, and then
3605 ;; letting combine generate the lds[hb] insns.
3606
3607 (define_expand "extendhisi2"
3608   [(set (match_operand:SI 0 "register_operand" "")
3609         (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
3610   ""
3611 {
3612   rtx temp = gen_reg_rtx (SImode);
3613   rtx shift_16 = GEN_INT (16);
3614   int op1_subbyte = 0;
3615
3616   if (GET_CODE (operand1) == SUBREG)
3617     {
3618       op1_subbyte = SUBREG_BYTE (operand1);
3619       op1_subbyte /= GET_MODE_SIZE (SImode);
3620       op1_subbyte *= GET_MODE_SIZE (SImode);
3621       operand1 = XEXP (operand1, 0);
3622     }
3623
3624   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3625                           shift_16));
3626   emit_insn (gen_ashrsi3 (operand0, temp, shift_16));
3627   DONE;
3628 })
3629
3630 (define_insn "*sign_extendhisi2_insn"
3631   [(set (match_operand:SI 0 "register_operand" "=r")
3632         (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
3633   ""
3634   "ldsh\t%1, %0"
3635   [(set_attr "type" "sload")
3636    (set_attr "us3load_type" "3cycle")])
3637
3638 (define_expand "extendqihi2"
3639   [(set (match_operand:HI 0 "register_operand" "")
3640         (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
3641   ""
3642 {
3643   rtx temp = gen_reg_rtx (SImode);
3644   rtx shift_24 = GEN_INT (24);
3645   int op1_subbyte = 0;
3646   int op0_subbyte = 0;
3647
3648   if (GET_CODE (operand1) == SUBREG)
3649     {
3650       op1_subbyte = SUBREG_BYTE (operand1);
3651       op1_subbyte /= GET_MODE_SIZE (SImode);
3652       op1_subbyte *= GET_MODE_SIZE (SImode);
3653       operand1 = XEXP (operand1, 0);
3654     }
3655   if (GET_CODE (operand0) == SUBREG)
3656     {
3657       op0_subbyte = SUBREG_BYTE (operand0);
3658       op0_subbyte /= GET_MODE_SIZE (SImode);
3659       op0_subbyte *= GET_MODE_SIZE (SImode);
3660       operand0 = XEXP (operand0, 0);
3661     }
3662   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3663                           shift_24));
3664   if (GET_MODE (operand0) != SImode)
3665     operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subbyte);
3666   emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3667   DONE;
3668 })
3669
3670 (define_insn "*sign_extendqihi2_insn"
3671   [(set (match_operand:HI 0 "register_operand" "=r")
3672         (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3673   ""
3674   "ldsb\t%1, %0"
3675   [(set_attr "type" "sload")
3676    (set_attr "us3load_type" "3cycle")])
3677
3678 (define_expand "extendqisi2"
3679   [(set (match_operand:SI 0 "register_operand" "")
3680         (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
3681   ""
3682 {
3683   rtx temp = gen_reg_rtx (SImode);
3684   rtx shift_24 = GEN_INT (24);
3685   int op1_subbyte = 0;
3686
3687   if (GET_CODE (operand1) == SUBREG)
3688     {
3689       op1_subbyte = SUBREG_BYTE (operand1);
3690       op1_subbyte /= GET_MODE_SIZE (SImode);
3691       op1_subbyte *= GET_MODE_SIZE (SImode);
3692       operand1 = XEXP (operand1, 0);
3693     }
3694
3695   emit_insn (gen_ashlsi3 (temp, gen_rtx_SUBREG (SImode, operand1, op1_subbyte),
3696                           shift_24));
3697   emit_insn (gen_ashrsi3 (operand0, temp, shift_24));
3698   DONE;
3699 })
3700
3701 (define_insn "*sign_extendqisi2_insn"
3702   [(set (match_operand:SI 0 "register_operand" "=r")
3703         (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3704   ""
3705   "ldsb\t%1, %0"
3706   [(set_attr "type" "sload")
3707    (set_attr "us3load_type" "3cycle")])
3708
3709 (define_expand "extendqidi2"
3710   [(set (match_operand:DI 0 "register_operand" "")
3711         (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
3712   "TARGET_ARCH64"
3713 {
3714   rtx temp = gen_reg_rtx (DImode);
3715   rtx shift_56 = GEN_INT (56);
3716   int op1_subbyte = 0;
3717
3718   if (GET_CODE (operand1) == SUBREG)
3719     {
3720       op1_subbyte = SUBREG_BYTE (operand1);
3721       op1_subbyte /= GET_MODE_SIZE (DImode);
3722       op1_subbyte *= GET_MODE_SIZE (DImode);
3723       operand1 = XEXP (operand1, 0);
3724     }
3725
3726   emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3727                           shift_56));
3728   emit_insn (gen_ashrdi3 (operand0, temp, shift_56));
3729   DONE;
3730 })
3731
3732 (define_insn "*sign_extendqidi2_insn"
3733   [(set (match_operand:DI 0 "register_operand" "=r")
3734         (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
3735   "TARGET_ARCH64"
3736   "ldsb\t%1, %0"
3737   [(set_attr "type" "sload")
3738    (set_attr "us3load_type" "3cycle")])
3739
3740 (define_expand "extendhidi2"
3741   [(set (match_operand:DI 0 "register_operand" "")
3742         (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
3743   "TARGET_ARCH64"
3744 {
3745   rtx temp = gen_reg_rtx (DImode);
3746   rtx shift_48 = GEN_INT (48);
3747   int op1_subbyte = 0;
3748
3749   if (GET_CODE (operand1) == SUBREG)
3750     {
3751       op1_subbyte = SUBREG_BYTE (operand1);
3752       op1_subbyte /= GET_MODE_SIZE (DImode);
3753       op1_subbyte *= GET_MODE_SIZE (DImode);
3754       operand1 = XEXP (operand1, 0);
3755     }
3756
3757   emit_insn (gen_ashldi3 (temp, gen_rtx_SUBREG (DImode, operand1, op1_subbyte),
3758                           shift_48));
3759   emit_insn (gen_ashrdi3 (operand0, temp, shift_48));
3760   DONE;
3761 })
3762
3763 (define_insn "*sign_extendhidi2_insn"
3764   [(set (match_operand:DI 0 "register_operand" "=r")
3765         (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
3766   "TARGET_ARCH64"
3767   "ldsh\t%1, %0"
3768   [(set_attr "type" "sload")
3769    (set_attr "us3load_type" "3cycle")])
3770
3771 (define_expand "extendsidi2"
3772   [(set (match_operand:DI 0 "register_operand" "")
3773         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3774   "TARGET_ARCH64"
3775   "")
3776
3777 (define_insn "*sign_extendsidi2_insn"
3778   [(set (match_operand:DI 0 "register_operand" "=r,r")
3779         (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))]
3780   "TARGET_ARCH64"
3781   "@
3782   sra\t%1, 0, %0
3783   ldsw\t%1, %0"
3784   [(set_attr "type" "shift,sload")
3785    (set_attr "us3load_type" "*,3cycle")])
3786
3787
3788 ;; Special pattern for optimizing bit-field compares.  This is needed
3789 ;; because combine uses this as a canonical form.
3790
3791 (define_insn "*cmp_zero_extract"
3792   [(set (reg:CC 100)
3793         (compare:CC
3794          (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
3795                           (match_operand:SI 1 "small_int_operand" "I")
3796                           (match_operand:SI 2 "small_int_operand" "I"))
3797          (const_int 0)))]
3798   "INTVAL (operands[2]) > 19"
3799 {
3800   int len = INTVAL (operands[1]);
3801   int pos = 32 - INTVAL (operands[2]) - len;
3802   HOST_WIDE_INT mask = ((1 << len) - 1) << pos;
3803   operands[1] = GEN_INT (mask);
3804   return "andcc\t%0, %1, %%g0";
3805 }
3806   [(set_attr "type" "compare")])
3807
3808 (define_insn "*cmp_zero_extract_sp64"
3809   [(set (reg:CCX 100)
3810         (compare:CCX
3811          (zero_extract:DI (match_operand:DI 0 "register_operand" "r")
3812                           (match_operand:SI 1 "small_int_operand" "I")
3813                           (match_operand:SI 2 "small_int_operand" "I"))
3814          (const_int 0)))]
3815   "TARGET_ARCH64 && INTVAL (operands[2]) > 51"
3816 {
3817   int len = INTVAL (operands[1]);
3818   int pos = 64 - INTVAL (operands[2]) - len;
3819   HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos;
3820   operands[1] = GEN_INT (mask);
3821   return "andcc\t%0, %1, %%g0";
3822 }
3823   [(set_attr "type" "compare")])
3824
3825
3826 ;; Conversions between float, double and long double.
3827
3828 (define_insn "extendsfdf2"
3829   [(set (match_operand:DF 0 "register_operand" "=e")
3830         (float_extend:DF
3831          (match_operand:SF 1 "register_operand" "f")))]
3832   "TARGET_FPU"
3833   "fstod\t%1, %0"
3834   [(set_attr "type" "fp")
3835    (set_attr "fptype" "double")])
3836
3837 (define_expand "extendsftf2"
3838   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3839         (float_extend:TF
3840          (match_operand:SF 1 "register_operand" "")))]
3841   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3842   "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3843
3844 (define_insn "*extendsftf2_hq"
3845   [(set (match_operand:TF 0 "register_operand" "=e")
3846         (float_extend:TF
3847          (match_operand:SF 1 "register_operand" "f")))]
3848   "TARGET_FPU && TARGET_HARD_QUAD"
3849   "fstoq\t%1, %0"
3850   [(set_attr "type" "fp")])
3851
3852 (define_expand "extenddftf2"
3853   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3854         (float_extend:TF
3855          (match_operand:DF 1 "register_operand" "")))]
3856   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3857   "emit_tfmode_cvt (FLOAT_EXTEND, operands); DONE;")
3858
3859 (define_insn "*extenddftf2_hq"
3860   [(set (match_operand:TF 0 "register_operand" "=e")
3861         (float_extend:TF
3862          (match_operand:DF 1 "register_operand" "e")))]
3863   "TARGET_FPU && TARGET_HARD_QUAD"
3864   "fdtoq\t%1, %0"
3865   [(set_attr "type" "fp")])
3866
3867 (define_insn "truncdfsf2"
3868   [(set (match_operand:SF 0 "register_operand" "=f")
3869         (float_truncate:SF
3870          (match_operand:DF 1 "register_operand" "e")))]
3871   "TARGET_FPU"
3872   "fdtos\t%1, %0"
3873   [(set_attr "type" "fp")
3874    (set_attr "fptype" "double")])
3875
3876 (define_expand "trunctfsf2"
3877   [(set (match_operand:SF 0 "register_operand" "")
3878         (float_truncate:SF
3879          (match_operand:TF 1 "general_operand" "")))]
3880   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3881   "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3882
3883 (define_insn "*trunctfsf2_hq"
3884   [(set (match_operand:SF 0 "register_operand" "=f")
3885         (float_truncate:SF
3886          (match_operand:TF 1 "register_operand" "e")))]
3887   "TARGET_FPU && TARGET_HARD_QUAD"
3888   "fqtos\t%1, %0"
3889   [(set_attr "type" "fp")])
3890
3891 (define_expand "trunctfdf2"
3892   [(set (match_operand:DF 0 "register_operand" "")
3893         (float_truncate:DF
3894          (match_operand:TF 1 "general_operand" "")))]
3895   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3896   "emit_tfmode_cvt (FLOAT_TRUNCATE, operands); DONE;")
3897
3898 (define_insn "*trunctfdf2_hq"
3899   [(set (match_operand:DF 0 "register_operand" "=e")
3900         (float_truncate:DF
3901          (match_operand:TF 1 "register_operand" "e")))]
3902   "TARGET_FPU && TARGET_HARD_QUAD"
3903   "fqtod\t%1, %0"
3904   [(set_attr "type" "fp")])
3905
3906
3907 ;; Conversion between fixed point and floating point.
3908
3909 (define_insn "floatsisf2"
3910   [(set (match_operand:SF 0 "register_operand" "=f")
3911         (float:SF (match_operand:SI 1 "register_operand" "f")))]
3912   "TARGET_FPU"
3913   "fitos\t%1, %0"
3914   [(set_attr "type" "fp")
3915    (set_attr "fptype" "double")])
3916
3917 (define_insn "floatsidf2"
3918   [(set (match_operand:DF 0 "register_operand" "=e")
3919         (float:DF (match_operand:SI 1 "register_operand" "f")))]
3920   "TARGET_FPU"
3921   "fitod\t%1, %0"
3922   [(set_attr "type" "fp")
3923    (set_attr "fptype" "double")])
3924
3925 (define_expand "floatsitf2"
3926   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3927         (float:TF (match_operand:SI 1 "register_operand" "")))]
3928   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3929   "emit_tfmode_cvt (FLOAT, operands); DONE;")
3930
3931 (define_insn "*floatsitf2_hq"
3932   [(set (match_operand:TF 0 "register_operand" "=e")
3933         (float:TF (match_operand:SI 1 "register_operand" "f")))]
3934   "TARGET_FPU && TARGET_HARD_QUAD"
3935   "fitoq\t%1, %0"
3936   [(set_attr "type" "fp")])
3937
3938 (define_expand "floatunssitf2"
3939   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3940         (unsigned_float:TF (match_operand:SI 1 "register_operand" "")))]
3941   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3942   "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3943
3944 ;; Now the same for 64 bit sources.
3945
3946 (define_insn "floatdisf2"
3947   [(set (match_operand:SF 0 "register_operand" "=f")
3948         (float:SF (match_operand:DI 1 "register_operand" "e")))]
3949   "TARGET_V9 && TARGET_FPU"
3950   "fxtos\t%1, %0"
3951   [(set_attr "type" "fp")
3952    (set_attr "fptype" "double")])
3953
3954 (define_expand "floatunsdisf2"
3955   [(use (match_operand:SF 0 "register_operand" ""))
3956    (use (match_operand:DI 1 "general_operand" ""))]
3957   "TARGET_ARCH64 && TARGET_FPU"
3958   "sparc_emit_floatunsdi (operands, SFmode); DONE;")
3959
3960 (define_insn "floatdidf2"
3961   [(set (match_operand:DF 0 "register_operand" "=e")
3962         (float:DF (match_operand:DI 1 "register_operand" "e")))]
3963   "TARGET_V9 && TARGET_FPU"
3964   "fxtod\t%1, %0"
3965   [(set_attr "type" "fp")
3966    (set_attr "fptype" "double")])
3967
3968 (define_expand "floatunsdidf2"
3969   [(use (match_operand:DF 0 "register_operand" ""))
3970    (use (match_operand:DI 1 "general_operand" ""))]
3971   "TARGET_ARCH64 && TARGET_FPU"
3972   "sparc_emit_floatunsdi (operands, DFmode); DONE;")
3973
3974 (define_expand "floatditf2"
3975   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3976         (float:TF (match_operand:DI 1 "register_operand" "")))]
3977   "TARGET_FPU && TARGET_V9 && (TARGET_HARD_QUAD || TARGET_ARCH64)"
3978   "emit_tfmode_cvt (FLOAT, operands); DONE;")
3979
3980 (define_insn "*floatditf2_hq"
3981   [(set (match_operand:TF 0 "register_operand" "=e")
3982         (float:TF (match_operand:DI 1 "register_operand" "e")))]
3983   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
3984   "fxtoq\t%1, %0"
3985   [(set_attr "type" "fp")])
3986
3987 (define_expand "floatunsditf2"
3988   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3989         (unsigned_float:TF (match_operand:DI 1 "register_operand" "")))]
3990   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
3991   "emit_tfmode_cvt (UNSIGNED_FLOAT, operands); DONE;")
3992
3993 ;; Convert a float to an actual integer.
3994 ;; Truncation is performed as part of the conversion.
3995
3996 (define_insn "fix_truncsfsi2"
3997   [(set (match_operand:SI 0 "register_operand" "=f")
3998         (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
3999   "TARGET_FPU"
4000   "fstoi\t%1, %0"
4001   [(set_attr "type" "fp")
4002    (set_attr "fptype" "double")])
4003
4004 (define_insn "fix_truncdfsi2"
4005   [(set (match_operand:SI 0 "register_operand" "=f")
4006         (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4007   "TARGET_FPU"
4008   "fdtoi\t%1, %0"
4009   [(set_attr "type" "fp")
4010    (set_attr "fptype" "double")])
4011
4012 (define_expand "fix_trunctfsi2"
4013   [(set (match_operand:SI 0 "register_operand" "")
4014         (fix:SI (match_operand:TF 1 "general_operand" "")))]
4015   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4016   "emit_tfmode_cvt (FIX, operands); DONE;")
4017
4018 (define_insn "*fix_trunctfsi2_hq"
4019   [(set (match_operand:SI 0 "register_operand" "=f")
4020         (fix:SI (match_operand:TF 1 "register_operand" "e")))]
4021   "TARGET_FPU && TARGET_HARD_QUAD"
4022   "fqtoi\t%1, %0"
4023   [(set_attr "type" "fp")])
4024
4025 (define_expand "fixuns_trunctfsi2"
4026   [(set (match_operand:SI 0 "register_operand" "")
4027         (unsigned_fix:SI (match_operand:TF 1 "general_operand" "")))]
4028   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4029   "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4030
4031 ;; Now the same, for V9 targets
4032
4033 (define_insn "fix_truncsfdi2"
4034   [(set (match_operand:DI 0 "register_operand" "=e")
4035         (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
4036   "TARGET_V9 && TARGET_FPU"
4037   "fstox\t%1, %0"
4038   [(set_attr "type" "fp")
4039    (set_attr "fptype" "double")])
4040
4041 (define_expand "fixuns_truncsfdi2"
4042   [(use (match_operand:DI 0 "register_operand" ""))
4043    (use (match_operand:SF 1 "general_operand" ""))]
4044   "TARGET_ARCH64 && TARGET_FPU"
4045   "sparc_emit_fixunsdi (operands, SFmode); DONE;")
4046
4047 (define_insn "fix_truncdfdi2"
4048   [(set (match_operand:DI 0 "register_operand" "=e")
4049         (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))]
4050   "TARGET_V9 && TARGET_FPU"
4051   "fdtox\t%1, %0"
4052   [(set_attr "type" "fp")
4053    (set_attr "fptype" "double")])
4054
4055 (define_expand "fixuns_truncdfdi2"
4056   [(use (match_operand:DI 0 "register_operand" ""))
4057    (use (match_operand:DF 1 "general_operand" ""))]
4058   "TARGET_ARCH64 && TARGET_FPU"
4059   "sparc_emit_fixunsdi (operands, DFmode); DONE;")
4060
4061 (define_expand "fix_trunctfdi2"
4062   [(set (match_operand:DI 0 "register_operand" "")
4063         (fix:DI (match_operand:TF 1 "general_operand" "")))]
4064   "TARGET_V9 && TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
4065   "emit_tfmode_cvt (FIX, operands); DONE;")
4066
4067 (define_insn "*fix_trunctfdi2_hq"
4068   [(set (match_operand:DI 0 "register_operand" "=e")
4069         (fix:DI (match_operand:TF 1 "register_operand" "e")))]
4070   "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD"
4071   "fqtox\t%1, %0"
4072   [(set_attr "type" "fp")])
4073
4074 (define_expand "fixuns_trunctfdi2"
4075   [(set (match_operand:DI 0 "register_operand" "")
4076         (unsigned_fix:DI (match_operand:TF 1 "general_operand" "")))]
4077   "TARGET_FPU && TARGET_ARCH64 && ! TARGET_HARD_QUAD"
4078   "emit_tfmode_cvt (UNSIGNED_FIX, operands); DONE;")
4079
4080
4081 ;; Integer addition/subtraction instructions.
4082
4083 (define_expand "adddi3"
4084   [(set (match_operand:DI 0 "register_operand" "")
4085         (plus:DI (match_operand:DI 1 "register_operand" "")
4086                  (match_operand:DI 2 "arith_double_add_operand" "")))]
4087   ""
4088 {
4089   if (! TARGET_ARCH64)
4090     {
4091       emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4092                           gen_rtx_SET (VOIDmode, operands[0],
4093                                    gen_rtx_PLUS (DImode, operands[1],
4094                                                  operands[2])),
4095                           gen_rtx_CLOBBER (VOIDmode,
4096                                    gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4097       DONE;
4098     }
4099 })
4100
4101 (define_insn_and_split "adddi3_insn_sp32"
4102   [(set (match_operand:DI 0 "register_operand" "=r")
4103         (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
4104                  (match_operand:DI 2 "arith_double_operand" "rHI")))
4105    (clobber (reg:CC 100))]
4106   "! TARGET_ARCH64"
4107   "#"
4108   "&& reload_completed"
4109   [(parallel [(set (reg:CC_NOOV 100)
4110                    (compare:CC_NOOV (plus:SI (match_dup 4)
4111                                              (match_dup 5))
4112                                     (const_int 0)))
4113               (set (match_dup 3)
4114                    (plus:SI (match_dup 4) (match_dup 5)))])
4115    (set (match_dup 6)
4116         (plus:SI (plus:SI (match_dup 7)
4117                           (match_dup 8))
4118                  (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4119 {
4120   operands[3] = gen_lowpart (SImode, operands[0]);
4121   operands[4] = gen_lowpart (SImode, operands[1]);
4122   operands[5] = gen_lowpart (SImode, operands[2]);
4123   operands[6] = gen_highpart (SImode, operands[0]);
4124   operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
4125 #if HOST_BITS_PER_WIDE_INT == 32
4126   if (GET_CODE (operands[2]) == CONST_INT)
4127     {
4128       if (INTVAL (operands[2]) < 0)
4129         operands[8] = constm1_rtx;
4130       else
4131         operands[8] = const0_rtx;
4132     }
4133   else
4134 #endif
4135     operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4136 }
4137   [(set_attr "length" "2")])
4138
4139 ;; LTU here means "carry set"
4140 (define_insn "addx"
4141   [(set (match_operand:SI 0 "register_operand" "=r")
4142         (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4143                           (match_operand:SI 2 "arith_operand" "rI"))
4144                  (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4145   ""
4146   "addx\t%1, %2, %0"
4147   [(set_attr "type" "ialuX")])
4148
4149 (define_insn_and_split "*addx_extend_sp32"
4150   [(set (match_operand:DI 0 "register_operand" "=r")
4151         (zero_extend:DI (plus:SI (plus:SI
4152                                   (match_operand:SI 1 "register_or_zero_operand" "%rJ")
4153                                   (match_operand:SI 2 "arith_operand" "rI"))
4154                                  (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4155   "! TARGET_ARCH64"
4156   "#"
4157   "&& reload_completed"
4158   [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2))
4159                                (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4160    (set (match_dup 4) (const_int 0))]
4161   "operands[3] = gen_lowpart (SImode, operands[0]);
4162    operands[4] = gen_highpart_mode (SImode, DImode, operands[1]);"
4163   [(set_attr "length" "2")])
4164
4165 (define_insn "*addx_extend_sp64"
4166   [(set (match_operand:DI 0 "register_operand" "=r")
4167         (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
4168                                           (match_operand:SI 2 "arith_operand" "rI"))
4169                                  (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4170   "TARGET_ARCH64"
4171   "addx\t%r1, %2, %0"
4172   [(set_attr "type" "ialuX")])
4173
4174 (define_insn_and_split ""
4175   [(set (match_operand:DI 0 "register_operand" "=r")
4176         (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4177                  (match_operand:DI 2 "register_operand" "r")))
4178    (clobber (reg:CC 100))]
4179   "! TARGET_ARCH64"
4180   "#"
4181   "&& reload_completed"
4182   [(parallel [(set (reg:CC_NOOV 100)
4183                    (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1))
4184                                     (const_int 0)))
4185               (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))])
4186    (set (match_dup 6)
4187         (plus:SI (plus:SI (match_dup 4) (const_int 0))
4188                  (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4189   "operands[3] = gen_lowpart (SImode, operands[2]);
4190    operands[4] = gen_highpart (SImode, operands[2]);
4191    operands[5] = gen_lowpart (SImode, operands[0]);
4192    operands[6] = gen_highpart (SImode, operands[0]);"
4193   [(set_attr "length" "2")])
4194
4195 (define_insn "*adddi3_sp64"
4196   [(set (match_operand:DI 0 "register_operand" "=r,r")
4197         (plus:DI (match_operand:DI 1 "register_operand" "%r,r")
4198                  (match_operand:DI 2 "arith_add_operand" "rI,O")))]
4199   "TARGET_ARCH64"
4200   "@
4201    add\t%1, %2, %0
4202    sub\t%1, -%2, %0")
4203
4204 (define_insn "addsi3"
4205   [(set (match_operand:SI 0 "register_operand" "=r,r,d")
4206         (plus:SI (match_operand:SI 1 "register_operand" "%r,r,d")
4207                  (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
4208   ""
4209   "@
4210    add\t%1, %2, %0
4211    sub\t%1, -%2, %0
4212    fpadd32s\t%1, %2, %0"
4213   [(set_attr "type" "*,*,fga")
4214    (set_attr "fptype" "*,*,single")])
4215
4216 (define_insn "*cmp_cc_plus"
4217   [(set (reg:CC_NOOV 100)
4218         (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r")
4219                                   (match_operand:SI 1 "arith_operand" "rI"))
4220                          (const_int 0)))]
4221   ""
4222   "addcc\t%0, %1, %%g0"
4223   [(set_attr "type" "compare")])
4224
4225 (define_insn "*cmp_ccx_plus"
4226   [(set (reg:CCX_NOOV 100)
4227         (compare:CCX_NOOV (plus:DI (match_operand:DI 0 "arith_operand" "%r")
4228                                    (match_operand:DI 1 "arith_operand" "rI"))
4229                           (const_int 0)))]
4230   "TARGET_ARCH64"
4231   "addcc\t%0, %1, %%g0"
4232   [(set_attr "type" "compare")])
4233
4234 (define_insn "*cmp_cc_plus_set"
4235   [(set (reg:CC_NOOV 100)
4236         (compare:CC_NOOV (plus:SI (match_operand:SI 1 "arith_operand" "%r")
4237                                   (match_operand:SI 2 "arith_operand" "rI"))
4238                          (const_int 0)))
4239    (set (match_operand:SI 0 "register_operand" "=r")
4240         (plus:SI (match_dup 1) (match_dup 2)))]
4241   ""
4242   "addcc\t%1, %2, %0"
4243   [(set_attr "type" "compare")])
4244
4245 (define_insn "*cmp_ccx_plus_set"
4246   [(set (reg:CCX_NOOV 100)
4247         (compare:CCX_NOOV (plus:DI (match_operand:DI 1 "arith_operand" "%r")
4248                                    (match_operand:DI 2 "arith_operand" "rI"))
4249                           (const_int 0)))
4250    (set (match_operand:DI 0 "register_operand" "=r")
4251         (plus:DI (match_dup 1) (match_dup 2)))]
4252   "TARGET_ARCH64"
4253   "addcc\t%1, %2, %0"
4254   [(set_attr "type" "compare")])
4255
4256 (define_expand "subdi3"
4257   [(set (match_operand:DI 0 "register_operand" "")
4258         (minus:DI (match_operand:DI 1 "register_operand" "")
4259                   (match_operand:DI 2 "arith_double_add_operand" "")))]
4260   ""
4261 {
4262   if (! TARGET_ARCH64)
4263     {
4264       emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2,
4265                           gen_rtx_SET (VOIDmode, operands[0],
4266                                    gen_rtx_MINUS (DImode, operands[1],
4267                                                   operands[2])),
4268                           gen_rtx_CLOBBER (VOIDmode,
4269                                    gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
4270       DONE;
4271     }
4272 })
4273
4274 (define_insn_and_split "subdi3_insn_sp32"
4275   [(set (match_operand:DI 0 "register_operand" "=r")
4276         (minus:DI (match_operand:DI 1 "register_operand" "r")
4277                   (match_operand:DI 2 "arith_double_operand" "rHI")))
4278    (clobber (reg:CC 100))]
4279   "! TARGET_ARCH64"
4280   "#"
4281   "&& reload_completed"
4282   [(parallel [(set (reg:CC_NOOV 100)
4283                    (compare:CC_NOOV (minus:SI (match_dup 4)
4284                                               (match_dup 5))
4285                                     (const_int 0)))
4286               (set (match_dup 3)
4287                    (minus:SI (match_dup 4) (match_dup 5)))])
4288    (set (match_dup 6)
4289         (minus:SI (minus:SI (match_dup 7)
4290                             (match_dup 8))
4291                   (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4292 {
4293   operands[3] = gen_lowpart (SImode, operands[0]);
4294   operands[4] = gen_lowpart (SImode, operands[1]);
4295   operands[5] = gen_lowpart (SImode, operands[2]);
4296   operands[6] = gen_highpart (SImode, operands[0]);
4297   operands[7] = gen_highpart (SImode, operands[1]);
4298 #if HOST_BITS_PER_WIDE_INT == 32
4299   if (GET_CODE (operands[2]) == CONST_INT)
4300     {
4301       if (INTVAL (operands[2]) < 0)
4302         operands[8] = constm1_rtx;
4303       else
4304         operands[8] = const0_rtx;
4305     }
4306   else
4307 #endif
4308     operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
4309 }
4310   [(set_attr "length" "2")])
4311
4312 ;; LTU here means "carry set"
4313 (define_insn "subx"
4314   [(set (match_operand:SI 0 "register_operand" "=r")
4315         (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4316                             (match_operand:SI 2 "arith_operand" "rI"))
4317                   (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4318   ""
4319   "subx\t%r1, %2, %0"
4320   [(set_attr "type" "ialuX")])
4321
4322 (define_insn "*subx_extend_sp64"
4323   [(set (match_operand:DI 0 "register_operand" "=r")
4324         (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4325                                             (match_operand:SI 2 "arith_operand" "rI"))
4326                                   (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4327   "TARGET_ARCH64"
4328   "subx\t%r1, %2, %0"
4329   [(set_attr "type" "ialuX")])
4330
4331 (define_insn_and_split "*subx_extend"
4332   [(set (match_operand:DI 0 "register_operand" "=r")
4333         (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4334                                             (match_operand:SI 2 "arith_operand" "rI"))
4335                                   (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))]
4336   "! TARGET_ARCH64"
4337   "#"
4338   "&& reload_completed"
4339   [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2))
4340                                 (ltu:SI (reg:CC_NOOV 100) (const_int 0))))
4341    (set (match_dup 4) (const_int 0))]
4342   "operands[3] = gen_lowpart (SImode, operands[0]);
4343    operands[4] = gen_highpart (SImode, operands[0]);"
4344   [(set_attr "length" "2")])
4345
4346 (define_insn_and_split ""
4347   [(set (match_operand:DI 0 "register_operand" "=r")
4348       (minus:DI (match_operand:DI 1 "register_operand" "r")
4349                 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))
4350    (clobber (reg:CC 100))]
4351   "! TARGET_ARCH64"
4352   "#"
4353   "&& reload_completed"
4354   [(parallel [(set (reg:CC_NOOV 100)
4355                    (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2))
4356                                     (const_int 0)))
4357               (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))])
4358    (set (match_dup 6)
4359         (minus:SI (minus:SI (match_dup 4) (const_int 0))
4360                   (ltu:SI (reg:CC_NOOV 100) (const_int 0))))]
4361   "operands[3] = gen_lowpart (SImode, operands[1]);
4362    operands[4] = gen_highpart (SImode, operands[1]);
4363    operands[5] = gen_lowpart (SImode, operands[0]);
4364    operands[6] = gen_highpart (SImode, operands[0]);"
4365   [(set_attr "length" "2")])
4366
4367 (define_insn "*subdi3_sp64"
4368   [(set (match_operand:DI 0 "register_operand" "=r,r")
4369         (minus:DI (match_operand:DI 1 "register_operand" "r,r")
4370                   (match_operand:DI 2 "arith_add_operand" "rI,O")))]
4371   "TARGET_ARCH64"
4372   "@
4373    sub\t%1, %2, %0
4374    add\t%1, -%2, %0")
4375
4376 (define_insn "subsi3"
4377   [(set (match_operand:SI 0 "register_operand" "=r,r,d")
4378         (minus:SI (match_operand:SI 1 "register_operand" "r,r,d")
4379                   (match_operand:SI 2 "arith_add_operand" "rI,O,d")))]
4380   ""
4381   "@
4382    sub\t%1, %2, %0
4383    add\t%1, -%2, %0
4384    fpsub32s\t%1, %2, %0"
4385   [(set_attr "type" "*,*,fga")
4386    (set_attr "fptype" "*,*,single")])
4387
4388 (define_insn "*cmp_minus_cc"
4389   [(set (reg:CC_NOOV 100)
4390         (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
4391                                    (match_operand:SI 1 "arith_operand" "rI"))
4392                          (const_int 0)))]
4393   ""
4394   "subcc\t%r0, %1, %%g0"
4395   [(set_attr "type" "compare")])
4396
4397 (define_insn "*cmp_minus_ccx"
4398   [(set (reg:CCX_NOOV 100)
4399         (compare:CCX_NOOV (minus:DI (match_operand:DI 0 "register_operand" "r")
4400                                     (match_operand:DI 1 "arith_operand" "rI"))
4401                           (const_int 0)))]
4402   "TARGET_ARCH64"
4403   "subcc\t%0, %1, %%g0"
4404   [(set_attr "type" "compare")])
4405
4406 (define_insn "cmp_minus_cc_set"
4407   [(set (reg:CC_NOOV 100)
4408         (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
4409                                    (match_operand:SI 2 "arith_operand" "rI"))
4410                          (const_int 0)))
4411    (set (match_operand:SI 0 "register_operand" "=r")
4412         (minus:SI (match_dup 1) (match_dup 2)))]
4413   ""
4414   "subcc\t%r1, %2, %0"
4415   [(set_attr "type" "compare")])
4416
4417 (define_insn "*cmp_minus_ccx_set"
4418   [(set (reg:CCX_NOOV 100)
4419         (compare:CCX_NOOV (minus:DI (match_operand:DI 1 "register_operand" "r")
4420                                     (match_operand:DI 2 "arith_operand" "rI"))
4421                           (const_int 0)))
4422    (set (match_operand:DI 0 "register_operand" "=r")
4423         (minus:DI (match_dup 1) (match_dup 2)))]
4424   "TARGET_ARCH64"
4425   "subcc\t%1, %2, %0"
4426   [(set_attr "type" "compare")])
4427
4428
4429 ;; Integer multiply/divide instructions.
4430
4431 ;; The 32-bit multiply/divide instructions are deprecated on v9, but at
4432 ;; least in UltraSPARC I, II and IIi it is a win tick-wise.
4433
4434 (define_insn "mulsi3"
4435   [(set (match_operand:SI 0 "register_operand" "=r")
4436         (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4437                  (match_operand:SI 2 "arith_operand" "rI")))]
4438   "TARGET_HARD_MUL"
4439   "smul\t%1, %2, %0"
4440   [(set_attr "type" "imul")])
4441
4442 (define_expand "muldi3"
4443   [(set (match_operand:DI 0 "register_operand" "")
4444         (mult:DI (match_operand:DI 1 "arith_operand" "")
4445                  (match_operand:DI 2 "arith_operand" "")))]
4446   "TARGET_ARCH64 || TARGET_V8PLUS"
4447 {
4448   if (TARGET_V8PLUS)
4449     {
4450       emit_insn (gen_muldi3_v8plus (operands[0], operands[1], operands[2]));
4451       DONE;
4452     }
4453 })
4454
4455 (define_insn "*muldi3_sp64"
4456   [(set (match_operand:DI 0 "register_operand" "=r")
4457         (mult:DI (match_operand:DI 1 "arith_operand" "%r")
4458                  (match_operand:DI 2 "arith_operand" "rI")))]
4459   "TARGET_ARCH64"
4460   "mulx\t%1, %2, %0"
4461   [(set_attr "type" "imul")])
4462
4463 ;; V8plus wide multiply.
4464 ;; XXX
4465 (define_insn "muldi3_v8plus"
4466   [(set (match_operand:DI 0 "register_operand" "=r,h")
4467         (mult:DI (match_operand:DI 1 "arith_operand" "%r,0")
4468                  (match_operand:DI 2 "arith_operand" "rI,rI")))
4469    (clobber (match_scratch:SI 3 "=&h,X"))
4470    (clobber (match_scratch:SI 4 "=&h,X"))]
4471   "TARGET_V8PLUS"
4472 {
4473   if (sparc_check_64 (operands[1], insn) <= 0)
4474     output_asm_insn ("srl\t%L1, 0, %L1", operands);
4475   if (which_alternative == 1)
4476     output_asm_insn ("sllx\t%H1, 32, %H1", operands);
4477   if (GET_CODE (operands[2]) == CONST_INT)
4478     {
4479       if (which_alternative == 1)
4480         return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %2, %L0\;srlx\t%L0, 32, %H0";
4481       else
4482         return "sllx\t%H1, 32, %3\n\tor\t%L1, %3, %3\n\tmulx\t%3, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0";
4483     }
4484   else if (rtx_equal_p (operands[1], operands[2]))
4485     {
4486       if (which_alternative == 1)
4487         return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %H1, %L0\;srlx\t%L0, 32, %H0";
4488       else
4489         return "sllx\t%H1, 32, %3\n\tor\t%L1, %3, %3\n\tmulx\t%3, %3, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0";
4490     }
4491   if (sparc_check_64 (operands[2], insn) <= 0)
4492     output_asm_insn ("srl\t%L2, 0, %L2", operands);
4493   if (which_alternative == 1)
4494     return "or\t%L1, %H1, %H1\n\tsllx\t%H2, 32, %L1\n\tor\t%L2, %L1, %L1\n\tmulx\t%H1, %L1, %L0\;srlx\t%L0, 32, %H0";
4495   else
4496     return "sllx\t%H1, 32, %3\n\tsllx\t%H2, 32, %4\n\tor\t%L1, %3, %3\n\tor\t%L2, %4, %4\n\tmulx\t%3, %4, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0";
4497 }
4498   [(set_attr "type" "multi")
4499    (set_attr "length" "9,8")])
4500
4501 (define_insn "*cmp_mul_set"
4502   [(set (reg:CC 100)
4503         (compare:CC (mult:SI (match_operand:SI 1 "arith_operand" "%r")
4504                     (match_operand:SI 2 "arith_operand" "rI"))
4505                     (const_int 0)))
4506    (set (match_operand:SI 0 "register_operand" "=r")
4507         (mult:SI (match_dup 1) (match_dup 2)))]
4508   "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS"
4509   "smulcc\t%1, %2, %0"
4510   [(set_attr "type" "imul")])
4511
4512 (define_expand "mulsidi3"
4513   [(set (match_operand:DI 0 "register_operand" "")
4514         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4515                  (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
4516   "TARGET_HARD_MUL"
4517 {
4518   if (CONSTANT_P (operands[2]))
4519     {
4520       if (TARGET_V8PLUS)
4521         emit_insn (gen_const_mulsidi3_v8plus (operands[0], operands[1],
4522                                               operands[2]));
4523       else if (TARGET_ARCH32)
4524         emit_insn (gen_const_mulsidi3_sp32 (operands[0], operands[1],
4525                                             operands[2]));
4526       else 
4527         emit_insn (gen_const_mulsidi3_sp64 (operands[0], operands[1],
4528                                             operands[2]));
4529       DONE;
4530     }
4531   if (TARGET_V8PLUS)
4532     {
4533       emit_insn (gen_mulsidi3_v8plus (operands[0], operands[1], operands[2]));
4534       DONE;
4535     }
4536 })
4537
4538 ;; V9 puts the 64-bit product in a 64-bit register.  Only out or global
4539 ;; registers can hold 64-bit values in the V8plus environment.
4540 ;; XXX
4541 (define_insn "mulsidi3_v8plus"
4542   [(set (match_operand:DI 0 "register_operand" "=h,r")
4543         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4544                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4545    (clobber (match_scratch:SI 3 "=X,&h"))]
4546   "TARGET_V8PLUS"
4547   "@
4548    smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4549    smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4550   [(set_attr "type" "multi")
4551    (set_attr "length" "2,3")])
4552
4553 ;; XXX
4554 (define_insn "const_mulsidi3_v8plus"
4555   [(set (match_operand:DI 0 "register_operand" "=h,r")
4556         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4557                  (match_operand:DI 2 "small_int_operand" "I,I")))
4558    (clobber (match_scratch:SI 3 "=X,&h"))]
4559   "TARGET_V8PLUS"
4560   "@
4561    smul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4562    smul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4563   [(set_attr "type" "multi")
4564    (set_attr "length" "2,3")])
4565
4566 ;; XXX
4567 (define_insn "*mulsidi3_sp32"
4568   [(set (match_operand:DI 0 "register_operand" "=r")
4569         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4570                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4571   "TARGET_HARD_MUL32"
4572 {
4573   return TARGET_SPARCLET
4574          ? "smuld\t%1, %2, %L0"
4575          : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4576 }
4577   [(set (attr "type")
4578         (if_then_else (eq_attr "isa" "sparclet")
4579                       (const_string "imul") (const_string "multi")))
4580    (set (attr "length")
4581         (if_then_else (eq_attr "isa" "sparclet")
4582                       (const_int 1) (const_int 2)))])
4583
4584 (define_insn "*mulsidi3_sp64"
4585   [(set (match_operand:DI 0 "register_operand" "=r")
4586         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4587                  (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4588   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4589   "smul\t%1, %2, %0"
4590   [(set_attr "type" "imul")])
4591
4592 ;; Extra pattern, because sign_extend of a constant isn't valid.
4593
4594 ;; XXX
4595 (define_insn "const_mulsidi3_sp32"
4596   [(set (match_operand:DI 0 "register_operand" "=r")
4597         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4598                  (match_operand:DI 2 "small_int_operand" "I")))]
4599   "TARGET_HARD_MUL32"
4600 {
4601   return TARGET_SPARCLET
4602          ? "smuld\t%1, %2, %L0"
4603          : "smul\t%1, %2, %L0\n\trd\t%%y, %H0";
4604 }
4605   [(set (attr "type")
4606         (if_then_else (eq_attr "isa" "sparclet")
4607                       (const_string "imul") (const_string "multi")))
4608    (set (attr "length")
4609         (if_then_else (eq_attr "isa" "sparclet")
4610                       (const_int 1) (const_int 2)))])
4611
4612 (define_insn "const_mulsidi3_sp64"
4613   [(set (match_operand:DI 0 "register_operand" "=r")
4614         (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4615                  (match_operand:DI 2 "small_int_operand" "I")))]
4616   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4617   "smul\t%1, %2, %0"
4618   [(set_attr "type" "imul")])
4619
4620 (define_expand "smulsi3_highpart"
4621   [(set (match_operand:SI 0 "register_operand" "")
4622         (truncate:SI
4623          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
4624                                (sign_extend:DI (match_operand:SI 2 "arith_operand" "")))
4625                       (const_int 32))))]
4626   "TARGET_HARD_MUL && TARGET_ARCH32"
4627 {
4628   if (CONSTANT_P (operands[2]))
4629     {
4630       if (TARGET_V8PLUS)
4631         {
4632           emit_insn (gen_const_smulsi3_highpart_v8plus (operands[0],
4633                                                         operands[1],
4634                                                         operands[2],
4635                                                         GEN_INT (32)));
4636           DONE;
4637         }
4638       emit_insn (gen_const_smulsi3_highpart (operands[0], operands[1], operands[2]));
4639       DONE;
4640     }
4641   if (TARGET_V8PLUS)
4642     {
4643       emit_insn (gen_smulsi3_highpart_v8plus (operands[0], operands[1],
4644                                               operands[2], GEN_INT (32)));
4645       DONE;
4646     }
4647 })
4648
4649 ;; XXX
4650 (define_insn "smulsi3_highpart_v8plus"
4651   [(set (match_operand:SI 0 "register_operand" "=h,r")
4652         (truncate:SI
4653          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4654                                (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4655                       (match_operand:SI 3 "small_int_operand" "I,I"))))
4656    (clobber (match_scratch:SI 4 "=X,&h"))]
4657   "TARGET_V8PLUS"
4658   "@
4659    smul\t%1, %2, %0\;srlx\t%0, %3, %0
4660    smul\t%1, %2, %4\;srlx\t%4, %3, %0"
4661   [(set_attr "type" "multi")
4662    (set_attr "length" "2")])
4663
4664 ;; The combiner changes TRUNCATE in the previous pattern to SUBREG.
4665 ;; XXX
4666 (define_insn ""
4667   [(set (match_operand:SI 0 "register_operand" "=h,r")
4668         (subreg:SI
4669          (lshiftrt:DI
4670           (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4671                    (sign_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4672           (match_operand:SI 3 "small_int_operand" "I,I"))
4673          4))
4674    (clobber (match_scratch:SI 4 "=X,&h"))]
4675   "TARGET_V8PLUS"
4676   "@
4677    smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4678    smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4679   [(set_attr "type" "multi")
4680    (set_attr "length" "2")])
4681
4682 ;; XXX
4683 (define_insn "const_smulsi3_highpart_v8plus"
4684   [(set (match_operand:SI 0 "register_operand" "=h,r")
4685         (truncate:SI
4686          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4687                                (match_operand:DI 2 "small_int_operand" "I,I"))
4688                       (match_operand:SI 3 "small_int_operand" "I,I"))))
4689    (clobber (match_scratch:SI 4 "=X,&h"))]
4690   "TARGET_V8PLUS"
4691   "@
4692    smul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4693    smul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4694   [(set_attr "type" "multi")
4695    (set_attr "length" "2")])
4696
4697 ;; XXX
4698 (define_insn "*smulsi3_highpart_sp32"
4699   [(set (match_operand:SI 0 "register_operand" "=r")
4700         (truncate:SI
4701          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4702                                (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
4703                       (const_int 32))))]
4704   "TARGET_HARD_MUL32"
4705   "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4706   [(set_attr "type" "multi")
4707    (set_attr "length" "2")])
4708
4709 ;; XXX
4710 (define_insn "const_smulsi3_highpart"
4711   [(set (match_operand:SI 0 "register_operand" "=r")
4712         (truncate:SI
4713          (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
4714                                (match_operand:DI 2 "small_int_operand" "i"))
4715                       (const_int 32))))]
4716   "TARGET_HARD_MUL32"
4717   "smul\t%1, %2, %%g0\n\trd\t%%y, %0"
4718   [(set_attr "type" "multi")
4719    (set_attr "length" "2")])
4720
4721 (define_expand "umulsidi3"
4722   [(set (match_operand:DI 0 "register_operand" "")
4723         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4724                  (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" ""))))]
4725   "TARGET_HARD_MUL"
4726 {
4727   if (CONSTANT_P (operands[2]))
4728     {
4729       if (TARGET_V8PLUS)
4730         emit_insn (gen_const_umulsidi3_v8plus (operands[0], operands[1],
4731                                                operands[2]));
4732       else if (TARGET_ARCH32)
4733         emit_insn (gen_const_umulsidi3_sp32 (operands[0], operands[1],
4734                                              operands[2]));
4735       else 
4736         emit_insn (gen_const_umulsidi3_sp64 (operands[0], operands[1],
4737                                              operands[2]));
4738       DONE;
4739     }
4740   if (TARGET_V8PLUS)
4741     {
4742       emit_insn (gen_umulsidi3_v8plus (operands[0], operands[1], operands[2]));
4743       DONE;
4744     }
4745 })
4746
4747 ;; XXX
4748 (define_insn "umulsidi3_v8plus"
4749   [(set (match_operand:DI 0 "register_operand" "=h,r")
4750         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4751                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r"))))
4752    (clobber (match_scratch:SI 3 "=X,&h"))]
4753   "TARGET_V8PLUS"
4754   "@
4755    umul\t%1, %2, %L0\n\tsrlx\t%L0, 32, %H0
4756    umul\t%1, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4757   [(set_attr "type" "multi")
4758    (set_attr "length" "2,3")])
4759
4760 ;; XXX
4761 (define_insn "*umulsidi3_sp32"
4762   [(set (match_operand:DI 0 "register_operand" "=r")
4763         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4764                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4765   "TARGET_HARD_MUL32"
4766 {
4767   return TARGET_SPARCLET
4768          ? "umuld\t%1, %2, %L0"
4769          : "umul\t%1, %2, %L0\n\trd\t%%y, %H0";
4770 }
4771   [(set (attr "type")
4772         (if_then_else (eq_attr "isa" "sparclet")
4773                       (const_string "imul") (const_string "multi")))
4774    (set (attr "length")
4775         (if_then_else (eq_attr "isa" "sparclet")
4776                       (const_int 1) (const_int 2)))])
4777
4778 (define_insn "*umulsidi3_sp64"
4779   [(set (match_operand:DI 0 "register_operand" "=r")
4780         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4781                  (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
4782   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4783   "umul\t%1, %2, %0"
4784   [(set_attr "type" "imul")])
4785
4786 ;; Extra pattern, because sign_extend of a constant isn't valid.
4787
4788 ;; XXX
4789 (define_insn "const_umulsidi3_sp32"
4790   [(set (match_operand:DI 0 "register_operand" "=r")
4791         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4792                  (match_operand:DI 2 "uns_small_int_operand" "")))]
4793   "TARGET_HARD_MUL32"
4794 {
4795   return TARGET_SPARCLET
4796          ? "umuld\t%1, %s2, %L0"
4797          : "umul\t%1, %s2, %L0\n\trd\t%%y, %H0";
4798 }
4799   [(set (attr "type")
4800         (if_then_else (eq_attr "isa" "sparclet")
4801                       (const_string "imul") (const_string "multi")))
4802    (set (attr "length")
4803         (if_then_else (eq_attr "isa" "sparclet")
4804                       (const_int 1) (const_int 2)))])
4805
4806 (define_insn "const_umulsidi3_sp64"
4807   [(set (match_operand:DI 0 "register_operand" "=r")
4808         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4809                  (match_operand:DI 2 "uns_small_int_operand" "")))]
4810   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4811   "umul\t%1, %s2, %0"
4812   [(set_attr "type" "imul")])
4813
4814 ;; XXX
4815 (define_insn "const_umulsidi3_v8plus"
4816   [(set (match_operand:DI 0 "register_operand" "=h,r")
4817         (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4818                  (match_operand:DI 2 "uns_small_int_operand" "")))
4819    (clobber (match_scratch:SI 3 "=X,h"))]
4820   "TARGET_V8PLUS"
4821   "@
4822    umul\t%1, %s2, %L0\n\tsrlx\t%L0, 32, %H0
4823    umul\t%1, %s2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"
4824   [(set_attr "type" "multi")
4825    (set_attr "length" "2,3")])
4826
4827 (define_expand "umulsi3_highpart"
4828   [(set (match_operand:SI 0 "register_operand" "")
4829         (truncate:SI
4830          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
4831                                (zero_extend:DI (match_operand:SI 2 "uns_arith_operand" "")))
4832                       (const_int 32))))]
4833   "TARGET_HARD_MUL && TARGET_ARCH32"
4834 {
4835   if (CONSTANT_P (operands[2]))
4836     {
4837       if (TARGET_V8PLUS)
4838         {
4839           emit_insn (gen_const_umulsi3_highpart_v8plus (operands[0],
4840                                                         operands[1],
4841                                                         operands[2],
4842                                                         GEN_INT (32)));
4843           DONE;
4844         }
4845       emit_insn (gen_const_umulsi3_highpart (operands[0], operands[1], operands[2]));
4846       DONE;
4847     }
4848   if (TARGET_V8PLUS)
4849     {
4850       emit_insn (gen_umulsi3_highpart_v8plus (operands[0], operands[1],
4851                                               operands[2], GEN_INT (32)));
4852       DONE;
4853     }
4854 })
4855
4856 ;; XXX
4857 (define_insn "umulsi3_highpart_v8plus"
4858   [(set (match_operand:SI 0 "register_operand" "=h,r")
4859         (truncate:SI
4860          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4861                                (zero_extend:DI (match_operand:SI 2 "register_operand" "r,r")))
4862                       (match_operand:SI 3 "small_int_operand" "I,I"))))
4863    (clobber (match_scratch:SI 4 "=X,h"))]
4864   "TARGET_V8PLUS"
4865   "@
4866    umul\t%1, %2, %0\n\tsrlx\t%0, %3, %0
4867    umul\t%1, %2, %4\n\tsrlx\t%4, %3, %0"
4868   [(set_attr "type" "multi")
4869    (set_attr "length" "2")])
4870
4871 ;; XXX
4872 (define_insn "const_umulsi3_highpart_v8plus"
4873   [(set (match_operand:SI 0 "register_operand" "=h,r")
4874         (truncate:SI
4875          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r"))
4876                                (match_operand:DI 2 "uns_small_int_operand" ""))
4877                       (match_operand:SI 3 "small_int_operand" "I,I"))))
4878    (clobber (match_scratch:SI 4 "=X,h"))]
4879   "TARGET_V8PLUS"
4880   "@
4881    umul\t%1, %s2, %0\n\tsrlx\t%0, %3, %0
4882    umul\t%1, %s2, %4\n\tsrlx\t%4, %3, %0"
4883   [(set_attr "type" "multi")
4884    (set_attr "length" "2")])
4885
4886 ;; XXX
4887 (define_insn "*umulsi3_highpart_sp32"
4888   [(set (match_operand:SI 0 "register_operand" "=r")
4889         (truncate:SI
4890          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4891                                (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
4892                       (const_int 32))))]
4893   "TARGET_HARD_MUL32"
4894   "umul\t%1, %2, %%g0\n\trd\t%%y, %0"
4895   [(set_attr "type" "multi")
4896    (set_attr "length" "2")])
4897
4898 ;; XXX
4899 (define_insn "const_umulsi3_highpart"
4900   [(set (match_operand:SI 0 "register_operand" "=r")
4901         (truncate:SI
4902          (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
4903                                (match_operand:DI 2 "uns_small_int_operand" ""))
4904                       (const_int 32))))]
4905   "TARGET_HARD_MUL32"
4906   "umul\t%1, %s2, %%g0\n\trd\t%%y, %0"
4907   [(set_attr "type" "multi")
4908    (set_attr "length" "2")])
4909
4910 (define_expand "divsi3"
4911   [(parallel [(set (match_operand:SI 0 "register_operand" "")
4912                    (div:SI (match_operand:SI 1 "register_operand" "")
4913                            (match_operand:SI 2 "input_operand" "")))
4914               (clobber (match_scratch:SI 3 ""))])]
4915   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4916 {
4917   if (TARGET_ARCH64)
4918     {
4919       operands[3] = gen_reg_rtx(SImode);
4920       emit_insn (gen_ashrsi3 (operands[3], operands[1], GEN_INT (31)));
4921       emit_insn (gen_divsi3_sp64 (operands[0], operands[1], operands[2],
4922                                   operands[3]));
4923       DONE;
4924     }
4925 })
4926
4927 ;; The V8 architecture specifies that there must be at least 3 instructions
4928 ;; between a write to the Y register and a use of it for correct results.
4929 ;; We try to fill one of them with a simple constant or a memory load.
4930
4931 (define_insn "divsi3_sp32"
4932   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
4933         (div:SI (match_operand:SI 1 "register_operand" "r,r,r")
4934                 (match_operand:SI 2 "input_operand" "rI,K,m")))
4935    (clobber (match_scratch:SI 3 "=&r,&r,&r"))]
4936   "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
4937 {
4938   output_asm_insn ("sra\t%1, 31, %3", operands);
4939   output_asm_insn ("wr\t%3, 0, %%y", operands);
4940
4941   switch (which_alternative)
4942     {
4943     case 0:
4944       if (TARGET_V9)
4945         return "sdiv\t%1, %2, %0";
4946       else
4947         return "nop\n\tnop\n\tnop\n\tsdiv\t%1, %2, %0";
4948     case 1:
4949       if (TARGET_V9)
4950         return "sethi\t%%hi(%a2), %3\n\tsdiv\t%1, %3, %0";
4951       else
4952         return "sethi\t%%hi(%a2), %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4953     case 2:
4954       if (TARGET_V9)
4955         return "ld\t%2, %3\n\tsdiv\t%1, %3, %0";
4956       else
4957         return "ld\t%2, %3\n\tnop\n\tnop\n\tsdiv\t%1, %3, %0";
4958     default:
4959       gcc_unreachable ();
4960     }
4961 }
4962   [(set_attr "type" "multi")
4963    (set (attr "length")
4964         (if_then_else (eq_attr "isa" "v9")
4965                       (const_int 4) (const_int 6)))])
4966
4967 (define_insn "divsi3_sp64"
4968   [(set (match_operand:SI 0 "register_operand" "=r")
4969         (div:SI (match_operand:SI 1 "register_operand" "r")
4970                 (match_operand:SI 2 "input_operand" "rI")))
4971    (use (match_operand:SI 3 "register_operand" "r"))]
4972   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
4973   "wr\t%%g0, %3, %%y\n\tsdiv\t%1, %2, %0"
4974   [(set_attr "type" "multi")
4975    (set_attr "length" "2")])
4976
4977 (define_insn "divdi3"
4978   [(set (match_operand:DI 0 "register_operand" "=r")
4979         (div:DI (match_operand:DI 1 "register_operand" "r")
4980                 (match_operand:DI 2 "arith_operand" "rI")))]
4981   "TARGET_ARCH64"
4982   "sdivx\t%1, %2, %0"
4983   [(set_attr "type" "idiv")])
4984
4985 (define_insn "*cmp_sdiv_cc_set"
4986   [(set (reg:CC 100)
4987         (compare:CC (div:SI (match_operand:SI 1 "register_operand" "r")
4988                             (match_operand:SI 2 "arith_operand" "rI"))
4989                     (const_int 0)))
4990    (set (match_operand:SI 0 "register_operand" "=r")
4991         (div:SI (match_dup 1) (match_dup 2)))
4992    (clobber (match_scratch:SI 3 "=&r"))]
4993   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
4994 {
4995   output_asm_insn ("sra\t%1, 31, %3", operands);
4996   output_asm_insn ("wr\t%3, 0, %%y", operands);
4997
4998   if (TARGET_V9)
4999     return "sdivcc\t%1, %2, %0";
5000   else
5001     return "nop\n\tnop\n\tnop\n\tsdivcc\t%1, %2, %0";
5002 }
5003   [(set_attr "type" "multi")
5004    (set (attr "length")
5005         (if_then_else (eq_attr "isa" "v9")
5006                       (const_int 3) (const_int 6)))])
5007
5008 ;; XXX
5009 (define_expand "udivsi3"
5010   [(set (match_operand:SI 0 "register_operand" "")
5011         (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "")
5012                  (match_operand:SI 2 "input_operand" "")))]
5013   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5014   "")
5015
5016 ;; The V8 architecture specifies that there must be at least 3 instructions
5017 ;; between a write to the Y register and a use of it for correct results.
5018 ;; We try to fill one of them with a simple constant or a memory load.
5019
5020 (define_insn "udivsi3_sp32"
5021   [(set (match_operand:SI 0 "register_operand" "=r,&r,&r,&r")
5022         (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r,r,r,m")
5023                  (match_operand:SI 2 "input_operand" "rI,K,m,r")))]
5024   "(TARGET_V8 || TARGET_DEPRECATED_V8_INSNS) && TARGET_ARCH32"
5025 {
5026   output_asm_insn ("wr\t%%g0, 0, %%y", operands);
5027
5028   switch (which_alternative)
5029     {
5030     case 0:
5031       if (TARGET_V9)
5032         return "udiv\t%1, %2, %0";
5033       else
5034         return "nop\n\tnop\n\tnop\n\tudiv\t%1, %2, %0";
5035     case 1:
5036       if (TARGET_V9)
5037         return "sethi\t%%hi(%a2), %0\n\tudiv\t%1, %0, %0";
5038       else
5039         return "sethi\t%%hi(%a2), %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
5040     case 2:
5041       if (TARGET_V9)
5042         return "ld\t%2, %0\n\tudiv\t%1, %0, %0";
5043       else
5044         return "ld\t%2, %0\n\tnop\n\tnop\n\tudiv\t%1, %0, %0";
5045     case 3:
5046       if (TARGET_V9)
5047         return "ld\t%1, %0\n\tudiv\t%0, %2, %0";
5048       else
5049         return "ld\t%1, %0\n\tnop\n\tnop\n\tudiv\t%0, %2, %0";
5050     default:
5051       gcc_unreachable ();
5052     }
5053 }
5054   [(set_attr "type" "multi")
5055    (set (attr "length")
5056         (if_then_else (eq_attr "isa" "v9")
5057                       (const_int 3) (const_int 5)))])
5058
5059 (define_insn "udivsi3_sp64"
5060   [(set (match_operand:SI 0 "register_operand" "=r")
5061         (udiv:SI (match_operand:SI 1 "nonimmediate_operand" "r")
5062                  (match_operand:SI 2 "input_operand" "rI")))]
5063   "TARGET_DEPRECATED_V8_INSNS && TARGET_ARCH64"
5064   "wr\t%%g0, 0, %%y\n\tudiv\t%1, %2, %0"
5065   [(set_attr "type" "multi")
5066    (set_attr "length" "2")])
5067
5068 (define_insn "udivdi3"
5069   [(set (match_operand:DI 0 "register_operand" "=r")
5070         (udiv:DI (match_operand:DI 1 "register_operand" "r")
5071                  (match_operand:DI 2 "arith_operand" "rI")))]
5072   "TARGET_ARCH64"
5073   "udivx\t%1, %2, %0"
5074   [(set_attr "type" "idiv")])
5075
5076 (define_insn "*cmp_udiv_cc_set"
5077   [(set (reg:CC 100)
5078         (compare:CC (udiv:SI (match_operand:SI 1 "register_operand" "r")
5079                              (match_operand:SI 2 "arith_operand" "rI"))
5080                     (const_int 0)))
5081    (set (match_operand:SI 0 "register_operand" "=r")
5082         (udiv:SI (match_dup 1) (match_dup 2)))]
5083   "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS"
5084 {
5085   output_asm_insn ("wr\t%%g0, 0, %%y", operands);
5086
5087   if (TARGET_V9)
5088     return "udivcc\t%1, %2, %0";
5089   else
5090     return "nop\n\tnop\n\tnop\n\tudivcc\t%1, %2, %0";
5091 }
5092   [(set_attr "type" "multi")
5093    (set (attr "length")
5094         (if_then_else (eq_attr "isa" "v9")
5095                       (const_int 2) (const_int 5)))])
5096
5097 ; sparclet multiply/accumulate insns
5098
5099 (define_insn "*smacsi"
5100   [(set (match_operand:SI 0 "register_operand" "=r")
5101         (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
5102                           (match_operand:SI 2 "arith_operand" "rI"))
5103                  (match_operand:SI 3 "register_operand" "0")))]
5104   "TARGET_SPARCLET"
5105   "smac\t%1, %2, %0"
5106   [(set_attr "type" "imul")])
5107
5108 (define_insn "*smacdi"
5109   [(set (match_operand:DI 0 "register_operand" "=r")
5110         (plus:DI (mult:DI (sign_extend:DI
5111                            (match_operand:SI 1 "register_operand" "%r"))
5112                           (sign_extend:DI
5113                            (match_operand:SI 2 "register_operand" "r")))
5114                  (match_operand:DI 3 "register_operand" "0")))]
5115   "TARGET_SPARCLET"
5116   "smacd\t%1, %2, %L0"
5117   [(set_attr "type" "imul")])
5118
5119 (define_insn "*umacdi"
5120   [(set (match_operand:DI 0 "register_operand" "=r")
5121         (plus:DI (mult:DI (zero_extend:DI
5122                            (match_operand:SI 1 "register_operand" "%r"))
5123                           (zero_extend:DI
5124                            (match_operand:SI 2 "register_operand" "r")))
5125                  (match_operand:DI 3 "register_operand" "0")))]
5126   "TARGET_SPARCLET"
5127   "umacd\t%1, %2, %L0"
5128   [(set_attr "type" "imul")])
5129
5130
5131 ;; Boolean instructions.
5132
5133 ;; We define DImode `and' so with DImode `not' we can get
5134 ;; DImode `andn'.  Other combinations are possible.
5135
5136 (define_mode_iterator V64I [DI V2SI V4HI V8QI])
5137 (define_mode_iterator V32I [SI V2HI V4QI])
5138
5139 (define_expand "and<V64I:mode>3"
5140   [(set (match_operand:V64I 0 "register_operand" "")
5141         (and:V64I (match_operand:V64I 1 "arith_double_operand" "")
5142                   (match_operand:V64I 2 "arith_double_operand" "")))]
5143   ""
5144   "")
5145
5146 (define_insn "*and<V64I:mode>3_sp32"
5147   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5148         (and:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5149                   (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5150   "! TARGET_ARCH64"
5151   "@
5152   #
5153   fand\t%1, %2, %0"
5154   [(set_attr "type" "*,fga")
5155    (set_attr "length" "2,*")
5156    (set_attr "fptype" "*,double")])
5157
5158 (define_insn "*and<V64I:mode>3_sp64"
5159   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5160         (and:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
5161                   (match_operand:V64I 2 "arith_operand" "rI,b")))]
5162   "TARGET_ARCH64"
5163   "@
5164    and\t%1, %2, %0
5165    fand\t%1, %2, %0"
5166   [(set_attr "type" "*,fga")
5167    (set_attr "fptype" "*,double")])
5168
5169 (define_insn "and<V32I:mode>3"
5170   [(set (match_operand:V32I 0 "register_operand" "=r,d")
5171         (and:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
5172                   (match_operand:V32I 2 "arith_operand" "rI,d")))]
5173   ""
5174   "@
5175    and\t%1, %2, %0
5176    fands\t%1, %2, %0"
5177   [(set_attr "type" "*,fga")
5178    (set_attr "fptype" "*,single")])
5179
5180 (define_split
5181   [(set (match_operand:SI 0 "register_operand" "")
5182         (and:SI (match_operand:SI 1 "register_operand" "")
5183                 (match_operand:SI 2 "const_compl_high_operand" "")))
5184    (clobber (match_operand:SI 3 "register_operand" ""))]
5185   ""
5186   [(set (match_dup 3) (match_dup 4))
5187    (set (match_dup 0) (and:SI (not:SI (match_dup 3)) (match_dup 1)))]
5188 {
5189   operands[4] = GEN_INT (~INTVAL (operands[2]));
5190 })
5191
5192 (define_insn_and_split "*and_not_<V64I:mode>_sp32"
5193   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5194         (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
5195                   (match_operand:V64I 2 "register_operand" "r,b")))]
5196   "! TARGET_ARCH64"
5197   "@
5198    #
5199    fandnot1\t%1, %2, %0"
5200   "&& reload_completed
5201    && ((GET_CODE (operands[0]) == REG
5202         && REGNO (operands[0]) < 32)
5203        || (GET_CODE (operands[0]) == SUBREG
5204            && GET_CODE (SUBREG_REG (operands[0])) == REG
5205            && REGNO (SUBREG_REG (operands[0])) < 32))"
5206   [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))
5207    (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))]
5208   "operands[3] = gen_highpart (SImode, operands[0]);
5209    operands[4] = gen_highpart (SImode, operands[1]);
5210    operands[5] = gen_highpart (SImode, operands[2]);
5211    operands[6] = gen_lowpart (SImode, operands[0]);
5212    operands[7] = gen_lowpart (SImode, operands[1]);
5213    operands[8] = gen_lowpart (SImode, operands[2]);"
5214   [(set_attr "type" "*,fga")
5215    (set_attr "length" "2,*")
5216    (set_attr "fptype" "*,double")])
5217
5218 (define_insn "*and_not_<V64I:mode>_sp64"
5219   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5220         (and:V64I (not:V64I (match_operand:V64I 1 "register_operand" "%r,b"))
5221                   (match_operand:V64I 2 "register_operand" "r,b")))]
5222   "TARGET_ARCH64"
5223   "@
5224    andn\t%2, %1, %0
5225    fandnot1\t%1, %2, %0"
5226   [(set_attr "type" "*,fga")
5227    (set_attr "fptype" "*,double")])
5228
5229 (define_insn "*and_not_<V32I:mode>"
5230   [(set (match_operand:V32I 0 "register_operand" "=r,d")
5231         (and:V32I (not:V32I (match_operand:V32I 1 "register_operand" "%r,d"))
5232                   (match_operand:V32I 2 "register_operand" "r,d")))]
5233   ""
5234   "@
5235    andn\t%2, %1, %0
5236    fandnot1s\t%1, %2, %0"
5237   [(set_attr "type" "*,fga")
5238    (set_attr "fptype" "*,single")])
5239
5240 (define_expand "ior<V64I:mode>3"
5241   [(set (match_operand:V64I 0 "register_operand" "")
5242         (ior:V64I (match_operand:V64I 1 "arith_double_operand" "")
5243                   (match_operand:V64I 2 "arith_double_operand" "")))]
5244   ""
5245   "")
5246
5247 (define_insn "*ior<V64I:mode>3_sp32"
5248   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5249         (ior:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5250                   (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5251   "! TARGET_ARCH64"
5252   "@
5253   #
5254   for\t%1, %2, %0"
5255   [(set_attr "type" "*,fga")
5256    (set_attr "length" "2,*")
5257    (set_attr "fptype" "*,double")])
5258
5259 (define_insn "*ior<V64I:mode>3_sp64"
5260   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5261         (ior:V64I (match_operand:V64I 1 "arith_operand" "%r,b")
5262                   (match_operand:V64I 2 "arith_operand" "rI,b")))]
5263   "TARGET_ARCH64"
5264   "@
5265   or\t%1, %2, %0
5266   for\t%1, %2, %0"
5267   [(set_attr "type" "*,fga")
5268    (set_attr "fptype" "*,double")])
5269
5270 (define_insn "ior<V32I:mode>3"
5271   [(set (match_operand:V32I 0 "register_operand" "=r,d")
5272         (ior:V32I (match_operand:V32I 1 "arith_operand" "%r,d")
5273                   (match_operand:V32I 2 "arith_operand" "rI,d")))]
5274   ""
5275   "@
5276    or\t%1, %2, %0
5277    fors\t%1, %2, %0"
5278   [(set_attr "type" "*,fga")
5279    (set_attr "fptype" "*,single")])
5280
5281 (define_split
5282   [(set (match_operand:SI 0 "register_operand" "")
5283         (ior:SI (match_operand:SI 1 "register_operand" "")
5284                 (match_operand:SI 2 "const_compl_high_operand" "")))
5285    (clobber (match_operand:SI 3 "register_operand" ""))]
5286   ""
5287   [(set (match_dup 3) (match_dup 4))
5288    (set (match_dup 0) (ior:SI (not:SI (match_dup 3)) (match_dup 1)))]
5289 {
5290   operands[4] = GEN_INT (~INTVAL (operands[2]));
5291 })
5292
5293 (define_insn_and_split "*or_not_<V64I:mode>_sp32"
5294   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5295         (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
5296                   (match_operand:V64I 2 "register_operand" "r,b")))]
5297   "! TARGET_ARCH64"
5298   "@
5299    #
5300    fornot1\t%1, %2, %0"
5301   "&& reload_completed
5302    && ((GET_CODE (operands[0]) == REG
5303         && REGNO (operands[0]) < 32)
5304        || (GET_CODE (operands[0]) == SUBREG
5305            && GET_CODE (SUBREG_REG (operands[0])) == REG
5306            && REGNO (SUBREG_REG (operands[0])) < 32))"
5307   [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))
5308    (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))]
5309   "operands[3] = gen_highpart (SImode, operands[0]);
5310    operands[4] = gen_highpart (SImode, operands[1]);
5311    operands[5] = gen_highpart (SImode, operands[2]);
5312    operands[6] = gen_lowpart (SImode, operands[0]);
5313    operands[7] = gen_lowpart (SImode, operands[1]);
5314    operands[8] = gen_lowpart (SImode, operands[2]);"
5315   [(set_attr "type" "*,fga")
5316    (set_attr "length" "2,*")
5317    (set_attr "fptype" "*,double")])
5318
5319 (define_insn "*or_not_<V64I:mode>_sp64"
5320   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5321         (ior:V64I (not:V64I (match_operand:V64I 1 "register_operand" "r,b"))
5322                   (match_operand:V64I 2 "register_operand" "r,b")))]
5323   "TARGET_ARCH64"
5324   "@
5325   orn\t%2, %1, %0
5326   fornot1\t%1, %2, %0"
5327   [(set_attr "type" "*,fga")
5328    (set_attr "fptype" "*,double")])
5329
5330 (define_insn "*or_not_<V32I:mode>"
5331   [(set (match_operand:V32I 0 "register_operand" "=r,d")
5332         (ior:V32I (not:V32I (match_operand:V32I 1 "register_operand" "r,d"))
5333                   (match_operand:V32I 2 "register_operand" "r,d")))]
5334   ""
5335   "@
5336    orn\t%2, %1, %0
5337    fornot1s\t%1, %2, %0"
5338   [(set_attr "type" "*,fga")
5339    (set_attr "fptype" "*,single")])
5340
5341 (define_expand "xor<V64I:mode>3"
5342   [(set (match_operand:V64I 0 "register_operand" "")
5343         (xor:V64I (match_operand:V64I 1 "arith_double_operand" "")
5344                   (match_operand:V64I 2 "arith_double_operand" "")))]
5345   ""
5346   "")
5347
5348 (define_insn "*xor<V64I:mode>3_sp32"
5349   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5350         (xor:V64I (match_operand:V64I 1 "arith_double_operand" "%r,b")
5351                   (match_operand:V64I 2 "arith_double_operand" "rHI,b")))]
5352   "! TARGET_ARCH64"
5353   "@
5354   #
5355   fxor\t%1, %2, %0"
5356   [(set_attr "type" "*,fga")
5357    (set_attr "length" "2,*")
5358    (set_attr "fptype" "*,double")])
5359
5360 (define_insn "*xor<V64I:mode>3_sp64"
5361   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5362         (xor:V64I (match_operand:V64I 1 "arith_operand" "%rJ,b")
5363                   (match_operand:V64I 2 "arith_operand" "rI,b")))]
5364   "TARGET_ARCH64"
5365   "@
5366   xor\t%r1, %2, %0
5367   fxor\t%1, %2, %0"
5368   [(set_attr "type" "*,fga")
5369    (set_attr "fptype" "*,double")])
5370
5371 (define_insn "xor<V32I:mode>3"
5372   [(set (match_operand:V32I 0 "register_operand" "=r,d")
5373         (xor:V32I (match_operand:V32I 1 "arith_operand" "%rJ,d")
5374                   (match_operand:V32I 2 "arith_operand" "rI,d")))]
5375   ""
5376   "@
5377    xor\t%r1, %2, %0
5378    fxors\t%1, %2, %0"
5379   [(set_attr "type" "*,fga")
5380    (set_attr "fptype" "*,single")])
5381
5382 (define_split
5383   [(set (match_operand:SI 0 "register_operand" "")
5384         (xor:SI (match_operand:SI 1 "register_operand" "")
5385                 (match_operand:SI 2 "const_compl_high_operand" "")))
5386    (clobber (match_operand:SI 3 "register_operand" ""))]
5387    ""
5388   [(set (match_dup 3) (match_dup 4))
5389    (set (match_dup 0) (not:SI (xor:SI (match_dup 3) (match_dup 1))))]
5390 {
5391   operands[4] = GEN_INT (~INTVAL (operands[2]));
5392 })
5393
5394 (define_split
5395   [(set (match_operand:SI 0 "register_operand" "")
5396         (not:SI (xor:SI (match_operand:SI 1 "register_operand" "")
5397                         (match_operand:SI 2 "const_compl_high_operand" ""))))
5398    (clobber (match_operand:SI 3 "register_operand" ""))]
5399   ""
5400   [(set (match_dup 3) (match_dup 4))
5401    (set (match_dup 0) (xor:SI (match_dup 3) (match_dup 1)))]
5402 {
5403   operands[4] = GEN_INT (~INTVAL (operands[2]));
5404 })
5405
5406 ;; Split DImode logical operations requiring two instructions.
5407 (define_split
5408   [(set (match_operand:V64I 0 "register_operand" "")
5409         (match_operator:V64I 1 "cc_arith_operator"      ; AND, IOR, XOR
5410                            [(match_operand:V64I 2 "register_operand" "")
5411                             (match_operand:V64I 3 "arith_double_operand" "")]))]
5412   "! TARGET_ARCH64
5413    && reload_completed
5414    && ((GET_CODE (operands[0]) == REG
5415         && REGNO (operands[0]) < 32)
5416        || (GET_CODE (operands[0]) == SUBREG
5417            && GET_CODE (SUBREG_REG (operands[0])) == REG
5418            && REGNO (SUBREG_REG (operands[0])) < 32))"
5419   [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)]))
5420    (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))]
5421 {
5422   operands[4] = gen_highpart (SImode, operands[0]);
5423   operands[5] = gen_lowpart (SImode, operands[0]);
5424   operands[6] = gen_highpart (SImode, operands[2]);
5425   operands[7] = gen_lowpart (SImode, operands[2]);
5426 #if HOST_BITS_PER_WIDE_INT == 32
5427   if (GET_CODE (operands[3]) == CONST_INT && <V64I:MODE>mode == DImode)
5428     {
5429       if (INTVAL (operands[3]) < 0)
5430         operands[8] = constm1_rtx;
5431       else
5432         operands[8] = const0_rtx;
5433     }
5434   else
5435 #endif
5436     operands[8] = gen_highpart_mode (SImode, <V64I:MODE>mode, operands[3]);
5437   operands[9] = gen_lowpart (SImode, operands[3]);
5438 })
5439
5440 ;; xnor patterns.  Note that (a ^ ~b) == (~a ^ b) == ~(a ^ b).
5441 ;; Combine now canonicalizes to the rightmost expression.
5442 (define_insn_and_split "*xor_not_<V64I:mode>_sp32"
5443   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5444         (not:V64I (xor:V64I (match_operand:V64I 1 "register_operand" "r,b")
5445                             (match_operand:V64I 2 "register_operand" "r,b"))))]
5446   "! TARGET_ARCH64"
5447   "@
5448    #
5449    fxnor\t%1, %2, %0"
5450   "&& reload_completed
5451    && ((GET_CODE (operands[0]) == REG
5452         && REGNO (operands[0]) < 32)
5453        || (GET_CODE (operands[0]) == SUBREG
5454            && GET_CODE (SUBREG_REG (operands[0])) == REG
5455            && REGNO (SUBREG_REG (operands[0])) < 32))"
5456   [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5))))
5457    (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))]
5458   "operands[3] = gen_highpart (SImode, operands[0]);
5459    operands[4] = gen_highpart (SImode, operands[1]);
5460    operands[5] = gen_highpart (SImode, operands[2]);
5461    operands[6] = gen_lowpart (SImode, operands[0]);
5462    operands[7] = gen_lowpart (SImode, operands[1]);
5463    operands[8] = gen_lowpart (SImode, operands[2]);"
5464   [(set_attr "type" "*,fga")
5465    (set_attr "length" "2,*")
5466    (set_attr "fptype" "*,double")])
5467
5468 (define_insn "*xor_not_<V64I:mode>_sp64"
5469   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5470         (not:V64I (xor:V64I (match_operand:V64I 1 "register_or_zero_operand" "rJ,b")
5471                             (match_operand:V64I 2 "arith_operand" "rI,b"))))]
5472   "TARGET_ARCH64"
5473   "@
5474   xnor\t%r1, %2, %0
5475   fxnor\t%1, %2, %0"
5476   [(set_attr "type" "*,fga")
5477    (set_attr "fptype" "*,double")])
5478
5479 (define_insn "*xor_not_<V32I:mode>"
5480   [(set (match_operand:V32I 0 "register_operand" "=r,d")
5481         (not:V32I (xor:V32I (match_operand:V32I 1 "register_or_zero_operand" "rJ,d")
5482                             (match_operand:V32I 2 "arith_operand" "rI,d"))))]
5483   ""
5484   "@
5485    xnor\t%r1, %2, %0
5486    fxnors\t%1, %2, %0"
5487   [(set_attr "type" "*,fga")
5488    (set_attr "fptype" "*,single")])
5489
5490 ;; These correspond to the above in the case where we also (or only)
5491 ;; want to set the condition code.  
5492
5493 (define_insn "*cmp_cc_arith_op"
5494   [(set (reg:CC 100)
5495         (compare:CC
5496          (match_operator:SI 2 "cc_arith_operator"
5497                             [(match_operand:SI 0 "arith_operand" "%r")
5498                              (match_operand:SI 1 "arith_operand" "rI")])
5499          (const_int 0)))]
5500   ""
5501   "%A2cc\t%0, %1, %%g0"
5502   [(set_attr "type" "compare")])
5503
5504 (define_insn "*cmp_ccx_arith_op"
5505   [(set (reg:CCX 100)
5506         (compare:CCX
5507          (match_operator:DI 2 "cc_arith_operator"
5508                             [(match_operand:DI 0 "arith_operand" "%r")
5509                              (match_operand:DI 1 "arith_operand" "rI")])
5510          (const_int 0)))]
5511   "TARGET_ARCH64"
5512   "%A2cc\t%0, %1, %%g0"
5513   [(set_attr "type" "compare")])
5514
5515 (define_insn "*cmp_cc_arith_op_set"
5516   [(set (reg:CC 100)
5517         (compare:CC
5518          (match_operator:SI 3 "cc_arith_operator"
5519                             [(match_operand:SI 1 "arith_operand" "%r")
5520                              (match_operand:SI 2 "arith_operand" "rI")])
5521          (const_int 0)))
5522    (set (match_operand:SI 0 "register_operand" "=r")
5523         (match_operator:SI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5524   "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5525   "%A3cc\t%1, %2, %0"
5526   [(set_attr "type" "compare")])
5527
5528 (define_insn "*cmp_ccx_arith_op_set"
5529   [(set (reg:CCX 100)
5530         (compare:CCX
5531          (match_operator:DI 3 "cc_arith_operator"
5532                             [(match_operand:DI 1 "arith_operand" "%r")
5533                              (match_operand:DI 2 "arith_operand" "rI")])
5534          (const_int 0)))
5535    (set (match_operand:DI 0 "register_operand" "=r")
5536         (match_operator:DI 4 "cc_arith_operator" [(match_dup 1) (match_dup 2)]))]
5537   "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5538   "%A3cc\t%1, %2, %0"
5539   [(set_attr "type" "compare")])
5540
5541 (define_insn "*cmp_cc_xor_not"
5542   [(set (reg:CC 100)
5543         (compare:CC
5544          (not:SI (xor:SI (match_operand:SI 0 "register_or_zero_operand" "%rJ")
5545                          (match_operand:SI 1 "arith_operand" "rI")))
5546          (const_int 0)))]
5547   ""
5548   "xnorcc\t%r0, %1, %%g0"
5549   [(set_attr "type" "compare")])
5550
5551 (define_insn "*cmp_ccx_xor_not"
5552   [(set (reg:CCX 100)
5553         (compare:CCX
5554          (not:DI (xor:DI (match_operand:DI 0 "register_or_zero_operand" "%rJ")
5555                          (match_operand:DI 1 "arith_operand" "rI")))
5556          (const_int 0)))]
5557   "TARGET_ARCH64"
5558   "xnorcc\t%r0, %1, %%g0"
5559   [(set_attr "type" "compare")])
5560
5561 (define_insn "*cmp_cc_xor_not_set"
5562   [(set (reg:CC 100)
5563         (compare:CC
5564          (not:SI (xor:SI (match_operand:SI 1 "register_or_zero_operand" "%rJ")
5565                          (match_operand:SI 2 "arith_operand" "rI")))
5566          (const_int 0)))
5567    (set (match_operand:SI 0 "register_operand" "=r")
5568         (not:SI (xor:SI (match_dup 1) (match_dup 2))))]
5569   ""
5570   "xnorcc\t%r1, %2, %0"
5571   [(set_attr "type" "compare")])
5572
5573 (define_insn "*cmp_ccx_xor_not_set"
5574   [(set (reg:CCX 100)
5575         (compare:CCX
5576          (not:DI (xor:DI (match_operand:DI 1 "register_or_zero_operand" "%rJ")
5577                          (match_operand:DI 2 "arith_operand" "rI")))
5578          (const_int 0)))
5579    (set (match_operand:DI 0 "register_operand" "=r")
5580         (not:DI (xor:DI (match_dup 1) (match_dup 2))))]
5581   "TARGET_ARCH64"
5582   "xnorcc\t%r1, %2, %0"
5583   [(set_attr "type" "compare")])
5584
5585 (define_insn "*cmp_cc_arith_op_not"
5586   [(set (reg:CC 100)
5587         (compare:CC
5588          (match_operator:SI 2 "cc_arith_not_operator"
5589                             [(not:SI (match_operand:SI 0 "arith_operand" "rI"))
5590                              (match_operand:SI 1 "register_or_zero_operand" "rJ")])
5591          (const_int 0)))]
5592   ""
5593   "%B2cc\t%r1, %0, %%g0"
5594   [(set_attr "type" "compare")])
5595
5596 (define_insn "*cmp_ccx_arith_op_not"
5597   [(set (reg:CCX 100)
5598         (compare:CCX
5599          (match_operator:DI 2 "cc_arith_not_operator"
5600                             [(not:DI (match_operand:DI 0 "arith_operand" "rI"))
5601                              (match_operand:DI 1 "register_or_zero_operand" "rJ")])
5602          (const_int 0)))]
5603   "TARGET_ARCH64"
5604   "%B2cc\t%r1, %0, %%g0"
5605   [(set_attr "type" "compare")])
5606
5607 (define_insn "*cmp_cc_arith_op_not_set"
5608   [(set (reg:CC 100)
5609         (compare:CC
5610          (match_operator:SI 3 "cc_arith_not_operator"
5611                             [(not:SI (match_operand:SI 1 "arith_operand" "rI"))
5612                              (match_operand:SI 2 "register_or_zero_operand" "rJ")])
5613          (const_int 0)))
5614    (set (match_operand:SI 0 "register_operand" "=r")
5615         (match_operator:SI 4 "cc_arith_not_operator"
5616                             [(not:SI (match_dup 1)) (match_dup 2)]))]
5617   "GET_CODE (operands[3]) == GET_CODE (operands[4])"
5618   "%B3cc\t%r2, %1, %0"
5619   [(set_attr "type" "compare")])
5620
5621 (define_insn "*cmp_ccx_arith_op_not_set"
5622   [(set (reg:CCX 100)
5623         (compare:CCX
5624          (match_operator:DI 3 "cc_arith_not_operator"
5625                             [(not:DI (match_operand:DI 1 "arith_operand" "rI"))
5626                              (match_operand:DI 2 "register_or_zero_operand" "rJ")])
5627          (const_int 0)))
5628    (set (match_operand:DI 0 "register_operand" "=r")
5629         (match_operator:DI 4 "cc_arith_not_operator"
5630                             [(not:DI (match_dup 1)) (match_dup 2)]))]
5631   "TARGET_ARCH64 && GET_CODE (operands[3]) == GET_CODE (operands[4])"
5632   "%B3cc\t%r2, %1, %0"
5633   [(set_attr "type" "compare")])
5634
5635 ;; We cannot use the "neg" pseudo insn because the Sun assembler
5636 ;; does not know how to make it work for constants.
5637
5638 (define_expand "negdi2"
5639   [(set (match_operand:DI 0 "register_operand" "=r")
5640         (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5641   ""
5642 {
5643   if (! TARGET_ARCH64)
5644     {
5645       emit_insn (gen_rtx_PARALLEL
5646                  (VOIDmode,
5647                   gen_rtvec (2,
5648                              gen_rtx_SET (VOIDmode, operand0,
5649                                           gen_rtx_NEG (DImode, operand1)),
5650                              gen_rtx_CLOBBER (VOIDmode,
5651                                               gen_rtx_REG (CCmode,
5652                                                            SPARC_ICC_REG)))));
5653       DONE;
5654     }
5655 })
5656
5657 (define_insn_and_split "*negdi2_sp32"
5658   [(set (match_operand:DI 0 "register_operand" "=r")
5659         (neg:DI (match_operand:DI 1 "register_operand" "r")))
5660    (clobber (reg:CC 100))]
5661   "TARGET_ARCH32"
5662   "#"
5663   "&& reload_completed"
5664   [(parallel [(set (reg:CC_NOOV 100)
5665                    (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5))
5666                                     (const_int 0)))
5667               (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))])
5668    (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3))
5669                                 (ltu:SI (reg:CC 100) (const_int 0))))]
5670   "operands[2] = gen_highpart (SImode, operands[0]);
5671    operands[3] = gen_highpart (SImode, operands[1]);
5672    operands[4] = gen_lowpart (SImode, operands[0]);
5673    operands[5] = gen_lowpart (SImode, operands[1]);"
5674   [(set_attr "length" "2")])
5675
5676 (define_insn "*negdi2_sp64"
5677   [(set (match_operand:DI 0 "register_operand" "=r")
5678         (neg:DI (match_operand:DI 1 "register_operand" "r")))]
5679   "TARGET_ARCH64"
5680   "sub\t%%g0, %1, %0")
5681
5682 (define_insn "negsi2"
5683   [(set (match_operand:SI 0 "register_operand" "=r")
5684         (neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
5685   ""
5686   "sub\t%%g0, %1, %0")
5687
5688 (define_insn "*cmp_cc_neg"
5689   [(set (reg:CC_NOOV 100)
5690         (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
5691                          (const_int 0)))]
5692   ""
5693   "subcc\t%%g0, %0, %%g0"
5694   [(set_attr "type" "compare")])
5695
5696 (define_insn "*cmp_ccx_neg"
5697   [(set (reg:CCX_NOOV 100)
5698         (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_operand" "rI"))
5699                           (const_int 0)))]
5700   "TARGET_ARCH64"
5701   "subcc\t%%g0, %0, %%g0"
5702   [(set_attr "type" "compare")])
5703
5704 (define_insn "*cmp_cc_set_neg"
5705   [(set (reg:CC_NOOV 100)
5706         (compare:CC_NOOV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
5707                          (const_int 0)))
5708    (set (match_operand:SI 0 "register_operand" "=r")
5709         (neg:SI (match_dup 1)))]
5710   ""
5711   "subcc\t%%g0, %1, %0"
5712   [(set_attr "type" "compare")])
5713
5714 (define_insn "*cmp_ccx_set_neg"
5715   [(set (reg:CCX_NOOV 100)
5716         (compare:CCX_NOOV (neg:DI (match_operand:DI 1 "arith_operand" "rI"))
5717                           (const_int 0)))
5718    (set (match_operand:DI 0 "register_operand" "=r")
5719         (neg:DI (match_dup 1)))]
5720   "TARGET_ARCH64"
5721   "subcc\t%%g0, %1, %0"
5722   [(set_attr "type" "compare")])
5723
5724 ;; We cannot use the "not" pseudo insn because the Sun assembler
5725 ;; does not know how to make it work for constants.
5726 (define_expand "one_cmpl<V64I:mode>2"
5727   [(set (match_operand:V64I 0 "register_operand" "")
5728         (not:V64I (match_operand:V64I 1 "register_operand" "")))]
5729   ""
5730   "")
5731
5732 (define_insn_and_split "*one_cmpl<V64I:mode>2_sp32"
5733   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5734         (not:V64I (match_operand:V64I 1 "register_operand" "r,b")))]
5735   "! TARGET_ARCH64"
5736   "@
5737    #
5738    fnot1\t%1, %0"
5739   "&& reload_completed
5740    && ((GET_CODE (operands[0]) == REG
5741         && REGNO (operands[0]) < 32)
5742        || (GET_CODE (operands[0]) == SUBREG
5743            && GET_CODE (SUBREG_REG (operands[0])) == REG
5744            && REGNO (SUBREG_REG (operands[0])) < 32))"
5745   [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0))))
5746    (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))]
5747   "operands[2] = gen_highpart (SImode, operands[0]);
5748    operands[3] = gen_highpart (SImode, operands[1]);
5749    operands[4] = gen_lowpart (SImode, operands[0]);
5750    operands[5] = gen_lowpart (SImode, operands[1]);"
5751   [(set_attr "type" "*,fga")
5752    (set_attr "length" "2,*")
5753    (set_attr "fptype" "*,double")])
5754
5755 (define_insn "*one_cmpl<V64I:mode>2_sp64"
5756   [(set (match_operand:V64I 0 "register_operand" "=r,b")
5757         (not:V64I (match_operand:V64I 1 "arith_operand" "rI,b")))]
5758   "TARGET_ARCH64"
5759   "@
5760    xnor\t%%g0, %1, %0
5761    fnot1\t%1, %0"
5762   [(set_attr "type" "*,fga")
5763    (set_attr "fptype" "*,double")])
5764
5765 (define_insn "one_cmpl<V32I:mode>2"
5766   [(set (match_operand:V32I 0 "register_operand" "=r,d")
5767         (not:V32I (match_operand:V32I 1 "arith_operand" "rI,d")))]
5768   ""
5769   "@
5770   xnor\t%%g0, %1, %0
5771   fnot1s\t%1, %0"
5772   [(set_attr "type" "*,fga")
5773    (set_attr "fptype" "*,single")])
5774
5775 (define_insn "*cmp_cc_not"
5776   [(set (reg:CC 100)
5777         (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI"))
5778                     (const_int 0)))]
5779   ""
5780   "xnorcc\t%%g0, %0, %%g0"
5781   [(set_attr "type" "compare")])
5782
5783 (define_insn "*cmp_ccx_not"
5784   [(set (reg:CCX 100)
5785         (compare:CCX (not:DI (match_operand:DI 0 "arith_operand" "rI"))
5786                      (const_int 0)))]
5787   "TARGET_ARCH64"
5788   "xnorcc\t%%g0, %0, %%g0"
5789   [(set_attr "type" "compare")])
5790
5791 (define_insn "*cmp_cc_set_not"
5792   [(set (reg:CC 100)
5793         (compare:CC (not:SI (match_operand:SI 1 "arith_operand" "rI"))
5794                     (const_int 0)))
5795    (set (match_operand:SI 0 "register_operand" "=r")
5796         (not:SI (match_dup 1)))]
5797   ""
5798   "xnorcc\t%%g0, %1, %0"
5799   [(set_attr "type" "compare")])
5800
5801 (define_insn "*cmp_ccx_set_not"
5802   [(set (reg:CCX 100)
5803         (compare:CCX (not:DI (match_operand:DI 1 "arith_operand" "rI"))
5804                     (const_int 0)))
5805    (set (match_operand:DI 0 "register_operand" "=r")
5806         (not:DI (match_dup 1)))]
5807   "TARGET_ARCH64"
5808   "xnorcc\t%%g0, %1, %0"
5809   [(set_attr "type" "compare")])
5810
5811 (define_insn "*cmp_cc_set"
5812   [(set (match_operand:SI 0 "register_operand" "=r")
5813         (match_operand:SI 1 "register_operand" "r"))
5814    (set (reg:CC 100)
5815         (compare:CC (match_dup 1)
5816                     (const_int 0)))]
5817   ""
5818   "orcc\t%1, 0, %0"
5819   [(set_attr "type" "compare")])
5820
5821 (define_insn "*cmp_ccx_set64"
5822   [(set (match_operand:DI 0 "register_operand" "=r")
5823         (match_operand:DI 1 "register_operand" "r"))
5824    (set (reg:CCX 100)
5825         (compare:CCX (match_dup 1)
5826                      (const_int 0)))]
5827   "TARGET_ARCH64"
5828   "orcc\t%1, 0, %0"
5829    [(set_attr "type" "compare")])
5830
5831
5832 ;; Floating point arithmetic instructions.
5833
5834 (define_expand "addtf3"
5835   [(set (match_operand:TF 0 "nonimmediate_operand" "")
5836         (plus:TF (match_operand:TF 1 "general_operand" "")
5837                  (match_operand:TF 2 "general_operand" "")))]
5838   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5839   "emit_tfmode_binop (PLUS, operands); DONE;")
5840
5841 (define_insn "*addtf3_hq"
5842   [(set (match_operand:TF 0 "register_operand" "=e")
5843         (plus:TF (match_operand:TF 1 "register_operand" "e")
5844                  (match_operand:TF 2 "register_operand" "e")))]
5845   "TARGET_FPU && TARGET_HARD_QUAD"
5846   "faddq\t%1, %2, %0"
5847   [(set_attr "type" "fp")])
5848
5849 (define_insn "adddf3"
5850   [(set (match_operand:DF 0 "register_operand" "=e")
5851         (plus:DF (match_operand:DF 1 "register_operand" "e")
5852                  (match_operand:DF 2 "register_operand" "e")))]
5853   "TARGET_FPU"
5854   "faddd\t%1, %2, %0"
5855   [(set_attr "type" "fp")
5856    (set_attr "fptype" "double")])
5857
5858 (define_insn "addsf3"
5859   [(set (match_operand:SF 0 "register_operand" "=f")
5860         (plus:SF (match_operand:SF 1 "register_operand" "f")
5861                  (match_operand:SF 2 "register_operand" "f")))]
5862   "TARGET_FPU"
5863   "fadds\t%1, %2, %0"
5864   [(set_attr "type" "fp")])
5865
5866 (define_expand "subtf3"
5867   [(set (match_operand:TF 0 "nonimmediate_operand" "")
5868         (minus:TF (match_operand:TF 1 "general_operand" "")
5869                   (match_operand:TF 2 "general_operand" "")))]
5870   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5871   "emit_tfmode_binop (MINUS, operands); DONE;")
5872
5873 (define_insn "*subtf3_hq"
5874   [(set (match_operand:TF 0 "register_operand" "=e")
5875         (minus:TF (match_operand:TF 1 "register_operand" "e")
5876                   (match_operand:TF 2 "register_operand" "e")))]
5877   "TARGET_FPU && TARGET_HARD_QUAD"
5878   "fsubq\t%1, %2, %0"
5879   [(set_attr "type" "fp")])
5880
5881 (define_insn "subdf3"
5882   [(set (match_operand:DF 0 "register_operand" "=e")
5883         (minus:DF (match_operand:DF 1 "register_operand" "e")
5884                   (match_operand:DF 2 "register_operand" "e")))]
5885   "TARGET_FPU"
5886   "fsubd\t%1, %2, %0"
5887   [(set_attr "type" "fp")
5888    (set_attr "fptype" "double")])
5889
5890 (define_insn "subsf3"
5891   [(set (match_operand:SF 0 "register_operand" "=f")
5892         (minus:SF (match_operand:SF 1 "register_operand" "f")
5893                   (match_operand:SF 2 "register_operand" "f")))]
5894   "TARGET_FPU"
5895   "fsubs\t%1, %2, %0"
5896   [(set_attr "type" "fp")])
5897
5898 (define_expand "multf3"
5899   [(set (match_operand:TF 0 "nonimmediate_operand" "")
5900         (mult:TF (match_operand:TF 1 "general_operand" "")
5901                  (match_operand:TF 2 "general_operand" "")))]
5902   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5903   "emit_tfmode_binop (MULT, operands); DONE;")
5904
5905 (define_insn "*multf3_hq"
5906   [(set (match_operand:TF 0 "register_operand" "=e")
5907         (mult:TF (match_operand:TF 1 "register_operand" "e")
5908                  (match_operand:TF 2 "register_operand" "e")))]
5909   "TARGET_FPU && TARGET_HARD_QUAD"
5910   "fmulq\t%1, %2, %0"
5911   [(set_attr "type" "fpmul")])
5912
5913 (define_insn "muldf3"
5914   [(set (match_operand:DF 0 "register_operand" "=e")
5915         (mult:DF (match_operand:DF 1 "register_operand" "e")
5916                  (match_operand:DF 2 "register_operand" "e")))]
5917   "TARGET_FPU"
5918   "fmuld\t%1, %2, %0"
5919   [(set_attr "type" "fpmul")
5920    (set_attr "fptype" "double")])
5921
5922 (define_insn "mulsf3"
5923   [(set (match_operand:SF 0 "register_operand" "=f")
5924         (mult:SF (match_operand:SF 1 "register_operand" "f")
5925                  (match_operand:SF 2 "register_operand" "f")))]
5926   "TARGET_FPU"
5927   "fmuls\t%1, %2, %0"
5928   [(set_attr "type" "fpmul")])
5929
5930 (define_insn "*muldf3_extend"
5931   [(set (match_operand:DF 0 "register_operand" "=e")
5932         (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f"))
5933                  (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))]
5934   "(TARGET_V8 || TARGET_V9) && TARGET_FPU"
5935   "fsmuld\t%1, %2, %0"
5936   [(set_attr "type" "fpmul")
5937    (set_attr "fptype" "double")])
5938
5939 (define_insn "*multf3_extend"
5940   [(set (match_operand:TF 0 "register_operand" "=e")
5941         (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e"))
5942                  (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))]
5943   "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD"
5944   "fdmulq\t%1, %2, %0"
5945   [(set_attr "type" "fpmul")])
5946
5947 (define_expand "divtf3"
5948   [(set (match_operand:TF 0 "nonimmediate_operand" "")
5949         (div:TF (match_operand:TF 1 "general_operand" "")
5950                 (match_operand:TF 2 "general_operand" "")))]
5951   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
5952   "emit_tfmode_binop (DIV, operands); DONE;")
5953
5954 ;; don't have timing for quad-prec. divide.
5955 (define_insn "*divtf3_hq"
5956   [(set (match_operand:TF 0 "register_operand" "=e")
5957         (div:TF (match_operand:TF 1 "register_operand" "e")
5958                 (match_operand:TF 2 "register_operand" "e")))]
5959   "TARGET_FPU && TARGET_HARD_QUAD"
5960   "fdivq\t%1, %2, %0"
5961   [(set_attr "type" "fpdivd")])
5962
5963 (define_insn "divdf3"
5964   [(set (match_operand:DF 0 "register_operand" "=e")
5965         (div:DF (match_operand:DF 1 "register_operand" "e")
5966                 (match_operand:DF 2 "register_operand" "e")))]
5967   "TARGET_FPU"
5968   "fdivd\t%1, %2, %0"
5969   [(set_attr "type" "fpdivd")
5970    (set_attr "fptype" "double")])
5971
5972 (define_insn "divsf3"
5973   [(set (match_operand:SF 0 "register_operand" "=f")
5974         (div:SF (match_operand:SF 1 "register_operand" "f")
5975                 (match_operand:SF 2 "register_operand" "f")))]
5976   "TARGET_FPU"
5977   "fdivs\t%1, %2, %0"
5978   [(set_attr "type" "fpdivs")])
5979
5980 (define_expand "negtf2"
5981   [(set (match_operand:TF 0 "register_operand" "=e,e")
5982         (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5983   "TARGET_FPU"
5984   "")
5985
5986 (define_insn_and_split "*negtf2_notv9"
5987   [(set (match_operand:TF 0 "register_operand" "=e,e")
5988         (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
5989   ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
5990   "TARGET_FPU
5991    && ! TARGET_V9"
5992   "@
5993   fnegs\t%0, %0
5994   #"
5995   "&& reload_completed
5996    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
5997   [(set (match_dup 2) (neg:SF (match_dup 3)))
5998    (set (match_dup 4) (match_dup 5))
5999    (set (match_dup 6) (match_dup 7))]
6000   "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6001    operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6002    operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6003    operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6004    operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6005    operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6006   [(set_attr "type" "fpmove,*")
6007    (set_attr "length" "*,2")])
6008
6009 (define_insn_and_split "*negtf2_v9"
6010   [(set (match_operand:TF 0 "register_operand" "=e,e")
6011         (neg:TF (match_operand:TF 1 "register_operand" "0,e")))]
6012   ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6013   "TARGET_FPU && TARGET_V9"
6014   "@
6015   fnegd\t%0, %0
6016   #"
6017   "&& reload_completed
6018    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6019   [(set (match_dup 2) (neg:DF (match_dup 3)))
6020    (set (match_dup 4) (match_dup 5))]
6021   "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6022    operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6023    operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6024    operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6025   [(set_attr "type" "fpmove,*")
6026    (set_attr "length" "*,2")
6027    (set_attr "fptype" "double")])
6028
6029 (define_expand "negdf2"
6030   [(set (match_operand:DF 0 "register_operand" "")
6031         (neg:DF (match_operand:DF 1 "register_operand" "")))]
6032   "TARGET_FPU"
6033   "")
6034
6035 (define_insn_and_split "*negdf2_notv9"
6036   [(set (match_operand:DF 0 "register_operand" "=e,e")
6037         (neg:DF (match_operand:DF 1 "register_operand" "0,e")))]
6038   "TARGET_FPU && ! TARGET_V9"
6039   "@
6040   fnegs\t%0, %0
6041   #"
6042   "&& reload_completed
6043    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6044   [(set (match_dup 2) (neg:SF (match_dup 3)))
6045    (set (match_dup 4) (match_dup 5))]
6046   "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6047    operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6048    operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6049    operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6050   [(set_attr "type" "fpmove,*")
6051    (set_attr "length" "*,2")])
6052
6053 (define_insn "*negdf2_v9"
6054   [(set (match_operand:DF 0 "register_operand" "=e")
6055         (neg:DF (match_operand:DF 1 "register_operand" "e")))]
6056   "TARGET_FPU && TARGET_V9"
6057   "fnegd\t%1, %0"
6058   [(set_attr "type" "fpmove")
6059    (set_attr "fptype" "double")])
6060
6061 (define_insn "negsf2"
6062   [(set (match_operand:SF 0 "register_operand" "=f")
6063         (neg:SF (match_operand:SF 1 "register_operand" "f")))]
6064   "TARGET_FPU"
6065   "fnegs\t%1, %0"
6066   [(set_attr "type" "fpmove")])
6067
6068 (define_expand "abstf2"
6069   [(set (match_operand:TF 0 "register_operand" "")
6070         (abs:TF (match_operand:TF 1 "register_operand" "")))]
6071   "TARGET_FPU"
6072   "")
6073
6074 (define_insn_and_split "*abstf2_notv9"
6075   [(set (match_operand:TF 0 "register_operand" "=e,e")
6076         (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6077   ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD.
6078   "TARGET_FPU && ! TARGET_V9"
6079   "@
6080   fabss\t%0, %0
6081   #"
6082   "&& reload_completed
6083    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6084   [(set (match_dup 2) (abs:SF (match_dup 3)))
6085    (set (match_dup 4) (match_dup 5))
6086    (set (match_dup 6) (match_dup 7))]
6087   "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6088    operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6089    operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6090    operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);
6091    operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6092    operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6093   [(set_attr "type" "fpmove,*")
6094    (set_attr "length" "*,2")])
6095
6096 (define_insn "*abstf2_hq_v9"
6097   [(set (match_operand:TF 0 "register_operand" "=e,e")
6098         (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6099   "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD"
6100   "@
6101   fabsd\t%0, %0
6102   fabsq\t%1, %0"
6103   [(set_attr "type" "fpmove")
6104    (set_attr "fptype" "double,*")])
6105
6106 (define_insn_and_split "*abstf2_v9"
6107   [(set (match_operand:TF 0 "register_operand" "=e,e")
6108         (abs:TF (match_operand:TF 1 "register_operand" "0,e")))]
6109   "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD"
6110   "@
6111   fabsd\t%0, %0
6112   #"
6113   "&& reload_completed
6114    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6115   [(set (match_dup 2) (abs:DF (match_dup 3)))
6116    (set (match_dup 4) (match_dup 5))]
6117   "operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]));
6118    operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]));
6119    operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2);
6120    operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);"
6121   [(set_attr "type" "fpmove,*")
6122    (set_attr "length" "*,2")
6123    (set_attr "fptype" "double,*")])
6124
6125 (define_expand "absdf2"
6126   [(set (match_operand:DF 0 "register_operand" "")
6127         (abs:DF (match_operand:DF 1 "register_operand" "")))]
6128   "TARGET_FPU"
6129   "")
6130
6131 (define_insn_and_split "*absdf2_notv9"
6132   [(set (match_operand:DF 0 "register_operand" "=e,e")
6133         (abs:DF (match_operand:DF 1 "register_operand" "0,e")))]
6134   "TARGET_FPU && ! TARGET_V9"
6135   "@
6136   fabss\t%0, %0
6137   #"
6138   "&& reload_completed
6139    && sparc_absnegfloat_split_legitimate (operands[0], operands[1])"
6140   [(set (match_dup 2) (abs:SF (match_dup 3)))
6141    (set (match_dup 4) (match_dup 5))]
6142   "operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]));
6143    operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]));
6144    operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1);
6145    operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);"
6146   [(set_attr "type" "fpmove,*")
6147    (set_attr "length" "*,2")])
6148
6149 (define_insn "*absdf2_v9"
6150   [(set (match_operand:DF 0 "register_operand" "=e")
6151         (abs:DF (match_operand:DF 1 "register_operand" "e")))]
6152   "TARGET_FPU && TARGET_V9"
6153   "fabsd\t%1, %0"
6154   [(set_attr "type" "fpmove")
6155    (set_attr "fptype" "double")])
6156
6157 (define_insn "abssf2"
6158   [(set (match_operand:SF 0 "register_operand" "=f")
6159         (abs:SF (match_operand:SF 1 "register_operand" "f")))]
6160   "TARGET_FPU"
6161   "fabss\t%1, %0"
6162   [(set_attr "type" "fpmove")])
6163
6164 (define_expand "sqrttf2"
6165   [(set (match_operand:TF 0 "nonimmediate_operand" "")
6166         (sqrt:TF (match_operand:TF 1 "general_operand" "")))]
6167   "TARGET_FPU && (TARGET_HARD_QUAD || TARGET_ARCH64)"
6168   "emit_tfmode_unop (SQRT, operands); DONE;")
6169
6170 (define_insn "*sqrttf2_hq"
6171   [(set (match_operand:TF 0 "register_operand" "=e")
6172         (sqrt:TF (match_operand:TF 1 "register_operand" "e")))]
6173   "TARGET_FPU && TARGET_HARD_QUAD"
6174   "fsqrtq\t%1, %0"
6175   [(set_attr "type" "fpsqrtd")])
6176
6177 (define_insn "sqrtdf2"
6178   [(set (match_operand:DF 0 "register_operand" "=e")
6179         (sqrt:DF (match_operand:DF 1 "register_operand" "e")))]
6180   "TARGET_FPU"
6181   "fsqrtd\t%1, %0"
6182   [(set_attr "type" "fpsqrtd")
6183    (set_attr "fptype" "double")])
6184
6185 (define_insn "sqrtsf2"
6186   [(set (match_operand:SF 0 "register_operand" "=f")
6187         (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
6188   "TARGET_FPU"
6189   "fsqrts\t%1, %0"
6190   [(set_attr "type" "fpsqrts")])
6191
6192
6193 ;; Arithmetic shift instructions.
6194
6195 (define_insn "ashlsi3"
6196   [(set (match_operand:SI 0 "register_operand" "=r")
6197         (ashift:SI (match_operand:SI 1 "register_operand" "r")
6198                    (match_operand:SI 2 "arith_operand" "rI")))]
6199   ""
6200 {
6201   if (GET_CODE (operands[2]) == CONST_INT)
6202     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6203   return "sll\t%1, %2, %0";
6204 }
6205   [(set (attr "type")
6206         (if_then_else (match_operand 2 "const_one_operand" "")
6207                       (const_string "ialu") (const_string "shift")))])
6208
6209 (define_expand "ashldi3"
6210   [(set (match_operand:DI 0 "register_operand" "=r")
6211         (ashift:DI (match_operand:DI 1 "register_operand" "r")
6212                    (match_operand:SI 2 "arith_operand" "rI")))]
6213   "TARGET_ARCH64 || TARGET_V8PLUS"
6214 {
6215   if (! TARGET_ARCH64)
6216     {
6217       if (GET_CODE (operands[2]) == CONST_INT)
6218         FAIL;
6219       emit_insn (gen_ashldi3_v8plus (operands[0], operands[1], operands[2]));
6220       DONE;
6221     }
6222 })
6223
6224 (define_insn "*ashldi3_sp64"
6225   [(set (match_operand:DI 0 "register_operand" "=r")
6226         (ashift:DI (match_operand:DI 1 "register_operand" "r")
6227                    (match_operand:SI 2 "arith_operand" "rI")))]
6228   "TARGET_ARCH64"
6229 {
6230   if (GET_CODE (operands[2]) == CONST_INT)
6231     operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6232   return "sllx\t%1, %2, %0";
6233 }
6234   [(set (attr "type")
6235         (if_then_else (match_operand 2 "const_one_operand" "")
6236                       (const_string "ialu") (const_string "shift")))])
6237
6238 ;; XXX UGH!
6239 (define_insn "ashldi3_v8plus"
6240   [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6241         (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6242                    (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6243    (clobber (match_scratch:SI 3 "=X,X,&h"))]
6244   "TARGET_V8PLUS"
6245   "* return output_v8plus_shift (operands, insn, \"sllx\");"
6246   [(set_attr "type" "multi")
6247    (set_attr "length" "5,5,6")])
6248
6249 ;; Optimize (1LL<<x)-1
6250 ;; XXX this also needs to be fixed to handle equal subregs
6251 ;; XXX first before we could re-enable it.
6252 ;(define_insn ""
6253 ;  [(set (match_operand:DI 0 "register_operand" "=h")
6254 ;       (plus:DI (ashift:DI (const_int 1)
6255 ;                           (match_operand:SI 1 "arith_operand" "rI"))
6256 ;                (const_int -1)))]
6257 ;  "0 && TARGET_V8PLUS"
6258 ;{
6259 ;  if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == REGNO (operands[0]))
6260 ;    return "mov\t1, %L0\;sllx\t%L0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
6261 ;  return "mov\t1, %H0\;sllx\t%H0, %1, %L0\;sub\t%L0, 1, %L0\;srlx\t%L0, 32, %H0";
6262 ;}
6263 ;  [(set_attr "type" "multi")
6264 ;   (set_attr "length" "4")])
6265
6266 (define_insn "*cmp_cc_ashift_1"
6267   [(set (reg:CC_NOOV 100)
6268         (compare:CC_NOOV (ashift:SI (match_operand:SI 0 "register_operand" "r")
6269                                     (const_int 1))
6270                          (const_int 0)))]
6271   ""
6272   "addcc\t%0, %0, %%g0"
6273   [(set_attr "type" "compare")])
6274
6275 (define_insn "*cmp_cc_set_ashift_1"
6276   [(set (reg:CC_NOOV 100)
6277         (compare:CC_NOOV (ashift:SI (match_operand:SI 1 "register_operand" "r")
6278                                     (const_int 1))
6279                          (const_int 0)))
6280    (set (match_operand:SI 0 "register_operand" "=r")
6281         (ashift:SI (match_dup 1) (const_int 1)))]
6282   ""
6283   "addcc\t%1, %1, %0"
6284   [(set_attr "type" "compare")])
6285
6286 (define_insn "ashrsi3"
6287   [(set (match_operand:SI 0 "register_operand" "=r")
6288         (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
6289                      (match_operand:SI 2 "arith_operand" "rI")))]
6290   ""
6291   {
6292      if (GET_CODE (operands[2]) == CONST_INT)
6293        operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6294      return "sra\t%1, %2, %0";
6295   }
6296   [(set_attr "type" "shift")])
6297
6298 (define_insn "*ashrsi3_extend"
6299   [(set (match_operand:DI 0 "register_operand" "=r")
6300         (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
6301                                      (match_operand:SI 2 "arith_operand" "r"))))]
6302   "TARGET_ARCH64"
6303   "sra\t%1, %2, %0"
6304   [(set_attr "type" "shift")])
6305
6306 ;; This handles the case as above, but with constant shift instead of
6307 ;; register. Combiner "simplifies" it for us a little bit though.
6308 (define_insn "*ashrsi3_extend2"
6309   [(set (match_operand:DI 0 "register_operand" "=r")
6310         (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
6311                                 (const_int 32))
6312                      (match_operand:SI 2 "small_int_operand" "I")))]
6313   "TARGET_ARCH64 && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64"
6314 {
6315   operands[2] = GEN_INT (INTVAL (operands[2]) - 32);
6316   return "sra\t%1, %2, %0";
6317 }
6318   [(set_attr "type" "shift")])
6319
6320 (define_expand "ashrdi3"
6321   [(set (match_operand:DI 0 "register_operand" "=r")
6322         (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6323                      (match_operand:SI 2 "arith_operand" "rI")))]
6324   "TARGET_ARCH64 || TARGET_V8PLUS"
6325 {
6326   if (! TARGET_ARCH64)
6327     {
6328       if (GET_CODE (operands[2]) == CONST_INT)
6329         FAIL;   /* prefer generic code in this case */
6330       emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2]));
6331       DONE;
6332     }
6333 })
6334
6335 (define_insn "*ashrdi3_sp64"
6336   [(set (match_operand:DI 0 "register_operand" "=r")
6337         (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6338                      (match_operand:SI 2 "arith_operand" "rI")))]
6339   "TARGET_ARCH64"
6340   
6341   {
6342     if (GET_CODE (operands[2]) == CONST_INT)
6343       operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6344     return "srax\t%1, %2, %0";
6345   }
6346   [(set_attr "type" "shift")])
6347
6348 ;; XXX
6349 (define_insn "ashrdi3_v8plus"
6350   [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6351         (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6352                      (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6353    (clobber (match_scratch:SI 3 "=X,X,&h"))]
6354   "TARGET_V8PLUS"
6355   "* return output_v8plus_shift (operands, insn, \"srax\");"
6356   [(set_attr "type" "multi")
6357    (set_attr "length" "5,5,6")])
6358
6359 (define_insn "lshrsi3"
6360   [(set (match_operand:SI 0 "register_operand" "=r")
6361         (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
6362                      (match_operand:SI 2 "arith_operand" "rI")))]
6363   ""
6364   {
6365     if (GET_CODE (operands[2]) == CONST_INT)
6366       operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
6367     return "srl\t%1, %2, %0";
6368   }
6369   [(set_attr "type" "shift")])
6370
6371 ;; This handles the case where
6372 ;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))),
6373 ;; but combiner "simplifies" it for us.
6374 (define_insn "*lshrsi3_extend"
6375   [(set (match_operand:DI 0 "register_operand" "=r")
6376         (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
6377                            (match_operand:SI 2 "arith_operand" "r")) 0)
6378                 (match_operand 3 "const_int_operand" "")))]
6379   "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff"
6380   "srl\t%1, %2, %0"
6381   [(set_attr "type" "shift")])
6382
6383 ;; This handles the case where
6384 ;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32))
6385 ;; but combiner "simplifies" it for us.
6386 (define_insn "*lshrsi3_extend2"
6387   [(set (match_operand:DI 0 "register_operand" "=r")
6388         (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0)
6389                          (match_operand 2 "small_int_operand" "I")
6390                          (const_int 32)))]
6391   "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6392 {
6393   operands[2] = GEN_INT (32 - INTVAL (operands[2]));
6394   return "srl\t%1, %2, %0";
6395 }
6396   [(set_attr "type" "shift")])
6397
6398 (define_expand "lshrdi3"
6399   [(set (match_operand:DI 0 "register_operand" "=r")
6400         (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6401                      (match_operand:SI 2 "arith_operand" "rI")))]
6402   "TARGET_ARCH64 || TARGET_V8PLUS"
6403 {
6404   if (! TARGET_ARCH64)
6405     {
6406       if (GET_CODE (operands[2]) == CONST_INT)
6407         FAIL;
6408       emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2]));
6409       DONE;
6410     }
6411 })
6412
6413 (define_insn "*lshrdi3_sp64"
6414   [(set (match_operand:DI 0 "register_operand" "=r")
6415         (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6416                      (match_operand:SI 2 "arith_operand" "rI")))]
6417   "TARGET_ARCH64"
6418   {
6419     if (GET_CODE (operands[2]) == CONST_INT)
6420       operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f);
6421     return "srlx\t%1, %2, %0";
6422   }
6423   [(set_attr "type" "shift")])
6424
6425 ;; XXX
6426 (define_insn "lshrdi3_v8plus"
6427   [(set (match_operand:DI 0 "register_operand" "=&h,&h,r")
6428         (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI")
6429                      (match_operand:SI 2 "arith_operand" "rI,rI,rI")))
6430    (clobber (match_scratch:SI 3 "=X,X,&h"))]
6431   "TARGET_V8PLUS"
6432   "* return output_v8plus_shift (operands, insn, \"srlx\");"
6433   [(set_attr "type" "multi")
6434    (set_attr "length" "5,5,6")])
6435
6436 (define_insn ""
6437   [(set (match_operand:SI 0 "register_operand" "=r")
6438         (ashiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6439                                              (const_int 32)) 4)
6440                      (match_operand:SI 2 "small_int_operand" "I")))]
6441   "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6442 {
6443   operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6444   return "srax\t%1, %2, %0";
6445 }
6446   [(set_attr "type" "shift")])
6447
6448 (define_insn ""
6449   [(set (match_operand:SI 0 "register_operand" "=r")
6450         (lshiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6451                                              (const_int 32)) 4)
6452                      (match_operand:SI 2 "small_int_operand" "I")))]
6453   "TARGET_ARCH64 && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32"
6454 {
6455   operands[2] = GEN_INT (INTVAL (operands[2]) + 32);
6456   return "srlx\t%1, %2, %0";
6457 }
6458   [(set_attr "type" "shift")])
6459
6460 (define_insn ""
6461   [(set (match_operand:SI 0 "register_operand" "=r")
6462         (ashiftrt:SI (subreg:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "r")
6463                                              (match_operand:SI 2 "small_int_operand" "I")) 4)
6464                      (match_operand:SI 3 "small_int_operand" "I")))]
6465   "TARGET_ARCH64
6466    && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6467    && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6468    && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6469 {
6470   operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6471
6472   return "srax\t%1, %2, %0";
6473 }
6474   [(set_attr "type" "shift")])
6475
6476 (define_insn ""
6477   [(set (match_operand:SI 0 "register_operand" "=r")
6478         (lshiftrt:SI (subreg:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
6479                                              (match_operand:SI 2 "small_int_operand" "I")) 4)
6480                      (match_operand:SI 3 "small_int_operand" "I")))]
6481   "TARGET_ARCH64
6482    && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 32
6483    && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) < 32
6484    && (unsigned HOST_WIDE_INT) (INTVAL (operands[2]) + INTVAL (operands[3])) < 64"
6485 {
6486   operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
6487
6488   return "srlx\t%1, %2, %0";
6489 }
6490   [(set_attr "type" "shift")])
6491
6492
6493 ;; Unconditional and other jump instructions.
6494
6495 (define_insn "jump"
6496   [(set (pc) (label_ref (match_operand 0 "" "")))]
6497   ""
6498   "* return output_ubranch (operands[0], 0, insn);"
6499   [(set_attr "type" "uncond_branch")])
6500
6501 (define_expand "tablejump"
6502   [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
6503               (use (label_ref (match_operand 1 "" "")))])]
6504   ""
6505 {
6506   gcc_assert (GET_MODE (operands[0]) == CASE_VECTOR_MODE);
6507
6508   /* In pic mode, our address differences are against the base of the
6509      table.  Add that base value back in; CSE ought to be able to combine
6510      the two address loads.  */
6511   if (flag_pic)
6512     {
6513       rtx tmp, tmp2;
6514       tmp = gen_rtx_LABEL_REF (Pmode, operands[1]);
6515       tmp2 = operands[0];
6516       if (CASE_VECTOR_MODE != Pmode)
6517         tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2);
6518       tmp = gen_rtx_PLUS (Pmode, tmp2, tmp);
6519       operands[0] = memory_address (Pmode, tmp);
6520     }
6521 })
6522
6523 (define_insn "*tablejump_sp32"
6524   [(set (pc) (match_operand:SI 0 "address_operand" "p"))
6525    (use (label_ref (match_operand 1 "" "")))]
6526   "! TARGET_ARCH64"
6527   "jmp\t%a0%#"
6528   [(set_attr "type" "uncond_branch")])
6529
6530 (define_insn "*tablejump_sp64"
6531   [(set (pc) (match_operand:DI 0 "address_operand" "p"))
6532    (use (label_ref (match_operand 1 "" "")))]
6533   "TARGET_ARCH64"
6534   "jmp\t%a0%#"
6535   [(set_attr "type" "uncond_branch")])
6536
6537
6538 ;; Jump to subroutine instructions.
6539
6540 (define_expand "call"
6541   ;; Note that this expression is not used for generating RTL.
6542   ;; All the RTL is generated explicitly below.
6543   [(call (match_operand 0 "call_operand" "")
6544          (match_operand 3 "" "i"))]
6545   ;; operands[2] is next_arg_register
6546   ;; operands[3] is struct_value_size_rtx.
6547   ""
6548 {
6549   rtx fn_rtx;
6550
6551   gcc_assert (MEM_P (operands[0]) && GET_MODE (operands[0]) == FUNCTION_MODE);
6552
6553   gcc_assert (GET_CODE (operands[3]) == CONST_INT);
6554
6555   if (GET_CODE (XEXP (operands[0], 0)) == LABEL_REF)
6556     {
6557       /* This is really a PIC sequence.  We want to represent
6558          it as a funny jump so its delay slots can be filled. 
6559
6560          ??? But if this really *is* a CALL, will not it clobber the
6561          call-clobbered registers?  We lose this if it is a JUMP_INSN.
6562          Why cannot we have delay slots filled if it were a CALL?  */
6563
6564       /* We accept negative sizes for untyped calls.  */
6565       if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6566         emit_jump_insn
6567           (gen_rtx_PARALLEL
6568            (VOIDmode,
6569             gen_rtvec (3,
6570                        gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6571                        operands[3],
6572                        gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6573       else
6574         emit_jump_insn
6575           (gen_rtx_PARALLEL
6576            (VOIDmode,
6577             gen_rtvec (2,
6578                        gen_rtx_SET (VOIDmode, pc_rtx, XEXP (operands[0], 0)),
6579                        gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))));
6580       goto finish_call;
6581     }
6582
6583   fn_rtx = operands[0];
6584
6585   /* We accept negative sizes for untyped calls.  */
6586   if (! TARGET_ARCH64 && INTVAL (operands[3]) != 0)
6587     sparc_emit_call_insn
6588       (gen_rtx_PARALLEL
6589        (VOIDmode,
6590         gen_rtvec (3, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6591                    operands[3],
6592                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6593        XEXP (fn_rtx, 0));
6594   else
6595     sparc_emit_call_insn
6596       (gen_rtx_PARALLEL
6597        (VOIDmode,
6598         gen_rtvec (2, gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx),
6599                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)))),
6600        XEXP (fn_rtx, 0));
6601
6602  finish_call:
6603
6604   DONE;
6605 })
6606
6607 ;; We can't use the same pattern for these two insns, because then registers
6608 ;; in the address may not be properly reloaded.
6609
6610 (define_insn "*call_address_sp32"
6611   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6612          (match_operand 1 "" ""))
6613    (clobber (reg:SI 15))]
6614   ;;- Do not use operand 1 for most machines.
6615   "! TARGET_ARCH64"
6616   "call\t%a0, %1%#"
6617   [(set_attr "type" "call")])
6618
6619 (define_insn "*call_symbolic_sp32"
6620   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6621          (match_operand 1 "" ""))
6622    (clobber (reg:SI 15))]
6623   ;;- Do not use operand 1 for most machines.
6624   "! TARGET_ARCH64"
6625   "call\t%a0, %1%#"
6626   [(set_attr "type" "call")])
6627
6628 (define_insn "*call_address_sp64"
6629   [(call (mem:DI (match_operand:DI 0 "address_operand" "p"))
6630          (match_operand 1 "" ""))
6631    (clobber (reg:DI 15))]
6632   ;;- Do not use operand 1 for most machines.
6633   "TARGET_ARCH64"
6634   "call\t%a0, %1%#"
6635   [(set_attr "type" "call")])
6636
6637 (define_insn "*call_symbolic_sp64"
6638   [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6639          (match_operand 1 "" ""))
6640    (clobber (reg:DI 15))]
6641   ;;- Do not use operand 1 for most machines.
6642   "TARGET_ARCH64"
6643   "call\t%a0, %1%#"
6644   [(set_attr "type" "call")])
6645
6646 ;; This is a call that wants a structure value.
6647 ;; There is no such critter for v9 (??? we may need one anyway).
6648 (define_insn "*call_address_struct_value_sp32"
6649   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6650          (match_operand 1 "" ""))
6651    (match_operand 2 "immediate_operand" "")
6652    (clobber (reg:SI 15))]
6653   ;;- Do not use operand 1 for most machines.
6654   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6655 {
6656   operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6657   return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6658 }
6659   [(set_attr "type" "call_no_delay_slot")
6660    (set_attr "length" "3")])
6661
6662 ;; This is a call that wants a structure value.
6663 ;; There is no such critter for v9 (??? we may need one anyway).
6664 (define_insn "*call_symbolic_struct_value_sp32"
6665   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6666          (match_operand 1 "" ""))
6667    (match_operand 2 "immediate_operand" "")
6668    (clobber (reg:SI 15))]
6669   ;;- Do not use operand 1 for most machines.
6670   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) > 0"
6671 {
6672   operands[2] = GEN_INT (INTVAL (operands[2]) & 0xfff);
6673   return "call\t%a0, %1\n\t nop\n\tunimp\t%2";
6674 }
6675   [(set_attr "type" "call_no_delay_slot")
6676    (set_attr "length" "3")])
6677
6678 ;; This is a call that may want a structure value.  This is used for
6679 ;; untyped_calls.
6680 (define_insn "*call_address_untyped_struct_value_sp32"
6681   [(call (mem:SI (match_operand:SI 0 "address_operand" "p"))
6682          (match_operand 1 "" ""))
6683    (match_operand 2 "immediate_operand" "")
6684    (clobber (reg:SI 15))]
6685   ;;- Do not use operand 1 for most machines.
6686   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6687   "call\t%a0, %1\n\t nop\n\tnop"
6688   [(set_attr "type" "call_no_delay_slot")
6689    (set_attr "length" "3")])
6690
6691 ;; This is a call that may want a structure value.  This is used for
6692 ;; untyped_calls.
6693 (define_insn "*call_symbolic_untyped_struct_value_sp32"
6694   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6695          (match_operand 1 "" ""))
6696    (match_operand 2 "immediate_operand" "")
6697    (clobber (reg:SI 15))]
6698   ;;- Do not use operand 1 for most machines.
6699   "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0"
6700   "call\t%a0, %1\n\t nop\n\tnop"
6701   [(set_attr "type" "call_no_delay_slot")
6702    (set_attr "length" "3")])
6703
6704 (define_expand "call_value"
6705   ;; Note that this expression is not used for generating RTL.
6706   ;; All the RTL is generated explicitly below.
6707   [(set (match_operand 0 "register_operand" "=rf")
6708         (call (match_operand 1 "" "")
6709               (match_operand 4 "" "")))]
6710   ;; operand 2 is stack_size_rtx
6711   ;; operand 3 is next_arg_register
6712   ""
6713 {
6714   rtx fn_rtx;
6715   rtvec vec;
6716
6717   gcc_assert (MEM_P (operands[1]) && GET_MODE (operands[1]) == FUNCTION_MODE);
6718
6719   fn_rtx = operands[1];
6720
6721   vec = gen_rtvec (2,
6722                    gen_rtx_SET (VOIDmode, operands[0],
6723                                 gen_rtx_CALL (VOIDmode, fn_rtx, const0_rtx)),
6724                    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 15)));
6725
6726   sparc_emit_call_insn (gen_rtx_PARALLEL (VOIDmode, vec), XEXP (fn_rtx, 0));
6727
6728   DONE;
6729 })
6730
6731 (define_insn "*call_value_address_sp32"
6732   [(set (match_operand 0 "" "=rf")
6733         (call (mem:SI (match_operand:SI 1 "address_operand" "p"))
6734               (match_operand 2 "" "")))
6735    (clobber (reg:SI 15))]
6736   ;;- Do not use operand 2 for most machines.
6737   "! TARGET_ARCH64"
6738   "call\t%a1, %2%#"
6739   [(set_attr "type" "call")])
6740
6741 (define_insn "*call_value_symbolic_sp32"
6742   [(set (match_operand 0 "" "=rf")
6743         (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6744               (match_operand 2 "" "")))
6745    (clobber (reg:SI 15))]
6746   ;;- Do not use operand 2 for most machines.
6747   "! TARGET_ARCH64"
6748   "call\t%a1, %2%#"
6749   [(set_attr "type" "call")])
6750
6751 (define_insn "*call_value_address_sp64"
6752   [(set (match_operand 0 "" "")
6753         (call (mem:DI (match_operand:DI 1 "address_operand" "p"))
6754               (match_operand 2 "" "")))
6755    (clobber (reg:DI 15))]
6756   ;;- Do not use operand 2 for most machines.
6757   "TARGET_ARCH64"
6758   "call\t%a1, %2%#"
6759   [(set_attr "type" "call")])
6760
6761 (define_insn "*call_value_symbolic_sp64"
6762   [(set (match_operand 0 "" "")
6763         (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6764               (match_operand 2 "" "")))
6765    (clobber (reg:DI 15))]
6766   ;;- Do not use operand 2 for most machines.
6767   "TARGET_ARCH64"
6768   "call\t%a1, %2%#"
6769   [(set_attr "type" "call")])
6770
6771 (define_expand "untyped_call"
6772   [(parallel [(call (match_operand 0 "" "")
6773                     (const_int 0))
6774               (match_operand:BLK 1 "memory_operand" "")
6775               (match_operand 2 "" "")])]
6776   ""
6777 {
6778   rtx valreg1 = gen_rtx_REG (DImode, 8);
6779   rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6780   rtx result = operands[1];
6781
6782   /* Pass constm1 to indicate that it may expect a structure value, but
6783      we don't know what size it is.  */
6784   emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));
6785
6786   /* Save the function value registers.  */
6787   emit_move_insn (adjust_address (result, DImode, 0), valreg1);
6788   emit_move_insn (adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8),
6789                                   valreg2);
6790
6791   /* The optimizer does not know that the call sets the function value
6792      registers we stored in the result block.  We avoid problems by
6793      claiming that all hard registers are used and clobbered at this
6794      point.  */
6795   emit_insn (gen_blockage ());
6796
6797   DONE;
6798 })
6799
6800 ;;  Tail call instructions.
6801
6802 (define_expand "sibcall"
6803   [(parallel [(call (match_operand 0 "call_operand" "") (const_int 0))
6804               (return)])]
6805   ""
6806   "")
6807
6808 (define_insn "*sibcall_symbolic_sp32"
6809   [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "s"))
6810          (match_operand 1 "" ""))
6811    (return)]
6812   "! TARGET_ARCH64"
6813   "* return output_sibcall(insn, operands[0]);"
6814   [(set_attr "type" "sibcall")])
6815
6816 (define_insn "*sibcall_symbolic_sp64"
6817   [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "s"))
6818          (match_operand 1 "" ""))
6819    (return)]
6820   "TARGET_ARCH64"
6821   "* return output_sibcall(insn, operands[0]);"
6822   [(set_attr "type" "sibcall")])
6823
6824 (define_expand "sibcall_value"
6825   [(parallel [(set (match_operand 0 "register_operand" "=rf")
6826                 (call (match_operand 1 "" "") (const_int 0)))
6827               (return)])]
6828   ""
6829   "")
6830
6831 (define_insn "*sibcall_value_symbolic_sp32"
6832   [(set (match_operand 0 "" "=rf")
6833         (call (mem:SI (match_operand:SI 1 "symbolic_operand" "s"))
6834               (match_operand 2 "" "")))
6835    (return)]
6836   "! TARGET_ARCH64"
6837   "* return output_sibcall(insn, operands[1]);"
6838   [(set_attr "type" "sibcall")])
6839
6840 (define_insn "*sibcall_value_symbolic_sp64"
6841   [(set (match_operand 0 "" "")
6842         (call (mem:DI (match_operand:DI 1 "symbolic_operand" "s"))
6843               (match_operand 2 "" "")))
6844    (return)]
6845   "TARGET_ARCH64"
6846   "* return output_sibcall(insn, operands[1]);"
6847   [(set_attr "type" "sibcall")])
6848
6849
6850 ;; Special instructions.
6851
6852 (define_expand "prologue"
6853   [(const_int 0)]
6854   ""
6855 {
6856   sparc_expand_prologue ();
6857   DONE;
6858 })
6859
6860 ;; The "save register window" insn is modelled as follows so that the DWARF-2
6861 ;; backend automatically emits the required call frame debugging information
6862 ;; while it is parsing it.  Therefore, the pattern should not be modified
6863 ;; without first studying the impact of the changes on the debug info.
6864 ;; [(set (%fp) (%sp))
6865 ;;  (set (%sp) (unspec_volatile [(%sp) (-frame_size)] UNSPECV_SAVEW))
6866 ;;  (set (%i7) (%o7))]
6867
6868 (define_insn "save_register_window<P:mode>"
6869   [(set (reg:P 30) (reg:P 14))
6870    (set (reg:P 14) (unspec_volatile:P [(reg:P 14)
6871                                        (match_operand:P 0 "arith_operand" "rI")] UNSPECV_SAVEW))
6872    (set (reg:P 31) (reg:P 15))]
6873   ""
6874   "save\t%%sp, %0, %%sp"
6875   [(set_attr "type" "savew")])
6876
6877 (define_expand "epilogue"
6878   [(return)]
6879   ""
6880 {
6881   sparc_expand_epilogue ();
6882 })
6883
6884 (define_expand "sibcall_epilogue"
6885   [(return)]
6886   ""
6887 {
6888   sparc_expand_epilogue ();
6889   DONE;
6890 })
6891
6892 (define_expand "return"
6893   [(return)]
6894   "sparc_can_use_return_insn_p ()"
6895   "")
6896
6897 (define_insn "*return_internal"
6898   [(return)]
6899   ""
6900   "* return output_return (insn);"
6901   [(set_attr "type" "return")
6902    (set (attr "length")
6903         (cond [(eq_attr "leaf_function" "true")
6904                  (if_then_else (eq_attr "empty_delay_slot" "true")
6905                                (const_int 2)
6906                                (const_int 1))
6907                (eq_attr "calls_eh_return" "true")
6908                  (if_then_else (eq_attr "delayed_branch" "true")
6909                                (if_then_else (eq_attr "isa" "v9")
6910                                              (const_int 2)
6911                                              (const_int 3))
6912                                (if_then_else (eq_attr "isa" "v9")
6913                                              (const_int 3)
6914                                              (const_int 4)))
6915                (eq_attr "empty_delay_slot" "true")
6916                  (if_then_else (eq_attr "delayed_branch" "true")
6917                                (const_int 2)
6918                                (const_int 3))
6919               ] (const_int 1)))])
6920
6921 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
6922 ;; all of memory.  This blocks insns from being moved across this point.
6923
6924 (define_insn "blockage"
6925   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
6926   ""
6927   ""
6928   [(set_attr "length" "0")])
6929
6930 ;; Prepare to return any type including a structure value.
6931
6932 (define_expand "untyped_return"
6933   [(match_operand:BLK 0 "memory_operand" "")
6934    (match_operand 1 "" "")]
6935   ""
6936 {
6937   rtx valreg1 = gen_rtx_REG (DImode, 24);
6938   rtx valreg2 = gen_rtx_REG (TARGET_ARCH64 ? TFmode : DFmode, 32);
6939   rtx result = operands[0];
6940
6941   if (! TARGET_ARCH64)
6942     {
6943       rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs
6944                                          ? 15 : 31));
6945       rtx value = gen_reg_rtx (SImode);
6946
6947       /* Fetch the instruction where we will return to and see if it's an unimp
6948          instruction (the most significant 10 bits will be zero).  If so,
6949          update the return address to skip the unimp instruction.  */
6950       emit_move_insn (value,
6951                       gen_rtx_MEM (SImode, plus_constant (rtnreg, 8)));
6952       emit_insn (gen_lshrsi3 (value, value, GEN_INT (22)));
6953       emit_insn (gen_update_return (rtnreg, value));
6954     }
6955
6956   /* Reload the function value registers.  */
6957   emit_move_insn (valreg1, adjust_address (result, DImode, 0));
6958   emit_move_insn (valreg2,
6959                   adjust_address (result, TARGET_ARCH64 ? TFmode : DFmode, 8));
6960
6961   /* Put USE insns before the return.  */
6962   emit_use (valreg1);
6963   emit_use (valreg2);
6964
6965   /* Construct the return.  */
6966   expand_naked_return ();
6967
6968   DONE;
6969 })
6970
6971 ;; Adjust the return address conditionally. If the value of op1 is equal
6972 ;; to all zero then adjust the return address i.e. op0 = op0 + 4.
6973 ;; This is technically *half* the check required by the 32-bit SPARC
6974 ;; psABI. This check only ensures that an "unimp" insn was written by
6975 ;; the caller, but doesn't check to see if the expected size matches
6976 ;; (this is encoded in the 12 lower bits). This check is obsolete and
6977 ;; only used by the above code "untyped_return".
6978
6979 (define_insn "update_return"
6980   [(unspec:SI [(match_operand:SI 0 "register_operand" "r")
6981                (match_operand:SI 1 "register_operand" "r")] UNSPEC_UPDATE_RETURN)]
6982   "! TARGET_ARCH64"
6983 {
6984   if (flag_delayed_branch)
6985     return "cmp\t%1, 0\n\tbe,a\t.+8\n\t add\t%0, 4, %0";
6986   else
6987     return "cmp\t%1, 0\n\tbne\t.+12\n\t nop\n\tadd\t%0, 4, %0";
6988 }
6989   [(set (attr "type") (const_string "multi"))
6990    (set (attr "length")
6991         (if_then_else (eq_attr "delayed_branch" "true")
6992                       (const_int 3)
6993                       (const_int 4)))])
6994 \f
6995 (define_insn "nop"
6996   [(const_int 0)]
6997   ""
6998   "nop")
6999
7000 (define_expand "indirect_jump"
7001   [(set (pc) (match_operand 0 "address_operand" "p"))]
7002   ""
7003   "")
7004
7005 (define_insn "*branch_sp32"
7006   [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
7007   "! TARGET_ARCH64"
7008  "jmp\t%a0%#"
7009  [(set_attr "type" "uncond_branch")])
7010  
7011 (define_insn "*branch_sp64"
7012   [(set (pc) (match_operand:DI 0 "address_operand" "p"))]
7013   "TARGET_ARCH64"
7014   "jmp\t%a0%#"
7015   [(set_attr "type" "uncond_branch")])
7016
7017 (define_expand "nonlocal_goto"
7018   [(match_operand:SI 0 "general_operand" "")
7019    (match_operand:SI 1 "general_operand" "")
7020    (match_operand:SI 2 "general_operand" "")
7021    (match_operand:SI 3 "" "")]
7022   ""
7023 {
7024   rtx lab = operands[1];
7025   rtx stack = operands[2];
7026   rtx fp = operands[3];
7027   rtx labreg;
7028
7029   /* Trap instruction to flush all the register windows.  */
7030   emit_insn (gen_flush_register_windows ());
7031
7032   /* Load the fp value for the containing fn into %fp.  This is needed
7033      because STACK refers to %fp.  Note that virtual register instantiation
7034      fails if the virtual %fp isn't set from a register.  */
7035   if (GET_CODE (fp) != REG)
7036     fp = force_reg (Pmode, fp);
7037   emit_move_insn (virtual_stack_vars_rtx, fp);
7038
7039   /* Find the containing function's current nonlocal goto handler,
7040      which will do any cleanups and then jump to the label.  */
7041   labreg = gen_rtx_REG (Pmode, 8);
7042   emit_move_insn (labreg, lab);
7043
7044   /* Restore %fp from stack pointer value for containing function.
7045      The restore insn that follows will move this to %sp,
7046      and reload the appropriate value into %fp.  */
7047   emit_move_insn (hard_frame_pointer_rtx, stack);
7048
7049   emit_use (stack_pointer_rtx);
7050   emit_use (static_chain_rtx);
7051
7052   /* ??? The V9-specific version was disabled in rev 1.65.  */
7053   emit_jump_insn (gen_goto_handler_and_restore (labreg));
7054   emit_barrier ();
7055   DONE;
7056 })
7057
7058 ;; Special trap insn to flush register windows.
7059 (define_insn "flush_register_windows"
7060   [(unspec_volatile [(const_int 0)] UNSPECV_FLUSHW)]
7061   ""
7062   { return TARGET_V9 ? "flushw" : "ta\t3"; }
7063   [(set_attr "type" "flushw")])
7064
7065 (define_insn "goto_handler_and_restore"
7066   [(unspec_volatile [(match_operand 0 "register_operand" "=r")] UNSPECV_GOTO)]
7067   "GET_MODE (operands[0]) == Pmode"
7068 {
7069   if (flag_delayed_branch)
7070     return "jmp\t%0\n\t restore";
7071   else
7072     return "mov\t%0,%%g1\n\trestore\n\tjmp\t%%g1\n\t nop";
7073 }
7074   [(set (attr "type") (const_string "multi"))
7075    (set (attr "length")
7076         (if_then_else (eq_attr "delayed_branch" "true")
7077                       (const_int 2)
7078                       (const_int 4)))])
7079
7080 ;; For __builtin_setjmp we need to flush register windows iff the function
7081 ;; calls alloca as well, because otherwise the register window might be
7082 ;; saved after %sp adjustment and thus setjmp would crash
7083 (define_expand "builtin_setjmp_setup"
7084   [(match_operand 0 "register_operand" "r")]
7085   ""
7086 {
7087   emit_insn (gen_do_builtin_setjmp_setup ());
7088   DONE;
7089 })
7090
7091 (define_insn "do_builtin_setjmp_setup"
7092   [(unspec_volatile [(const_int 0)] UNSPECV_SETJMP)]
7093   ""
7094 {
7095   if (!cfun->calls_alloca)
7096     return "";
7097   if (!TARGET_V9)
7098     return "ta\t3";
7099   fputs ("\tflushw\n", asm_out_file);
7100   if (flag_pic)
7101     fprintf (asm_out_file, "\tst%c\t%%l7, [%%sp+%d]\n",
7102              TARGET_ARCH64 ? 'x' : 'w',
7103              SPARC_STACK_BIAS + 7 * UNITS_PER_WORD);
7104   fprintf (asm_out_file, "\tst%c\t%%fp, [%%sp+%d]\n",
7105            TARGET_ARCH64 ? 'x' : 'w',
7106            SPARC_STACK_BIAS + 14 * UNITS_PER_WORD);
7107   fprintf (asm_out_file, "\tst%c\t%%i7, [%%sp+%d]\n",
7108            TARGET_ARCH64 ? 'x' : 'w',
7109            SPARC_STACK_BIAS + 15 * UNITS_PER_WORD);
7110   return "";
7111 }
7112   [(set_attr "type" "multi")
7113    (set (attr "length")
7114         (cond [(eq_attr "calls_alloca" "false")
7115                  (const_int 0)
7116                (eq_attr "isa" "!v9")
7117                  (const_int 1)
7118                (eq_attr "pic" "true")
7119                  (const_int 4)] (const_int 3)))])
7120
7121 ;; Pattern for use after a setjmp to store FP and the return register
7122 ;; into the stack area.
7123
7124 (define_expand "setjmp"
7125   [(const_int 0)]
7126   ""
7127 {
7128   rtx mem;
7129   
7130   mem = gen_rtx_MEM (Pmode,
7131                      plus_constant (stack_pointer_rtx,
7132                                     SPARC_STACK_BIAS + 14 * UNITS_PER_WORD));
7133   emit_insn (gen_rtx_SET (VOIDmode, mem, frame_pointer_rtx));
7134
7135   mem = gen_rtx_MEM (Pmode,
7136                      plus_constant (stack_pointer_rtx,
7137                                     SPARC_STACK_BIAS + 15 * UNITS_PER_WORD));
7138   emit_insn (gen_rtx_SET (VOIDmode, mem, gen_rtx_REG (Pmode, 31)));
7139   DONE;
7140 })
7141
7142 ;; Special pattern for the FLUSH instruction.
7143
7144 ; We do SImode and DImode versions of this to quiet down genrecog's complaints
7145 ; of the define_insn otherwise missing a mode.  We make "flush", aka
7146 ; gen_flush, the default one since sparc_initialize_trampoline uses
7147 ; it on SImode mem values.
7148
7149 (define_insn "flush"
7150   [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7151   ""
7152   { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7153   [(set_attr "type" "iflush")])
7154
7155 (define_insn "flushdi"
7156   [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_FLUSH)]
7157   ""
7158   { return TARGET_V9 ? "flush\t%f0" : "iflush\t%f0"; }
7159   [(set_attr "type" "iflush")])
7160
7161
7162 ;; Find first set instructions.
7163
7164 ;; The scan instruction searches from the most significant bit while ffs
7165 ;; searches from the least significant bit.  The bit index and treatment of
7166 ;; zero also differ.  It takes at least 7 instructions to get the proper
7167 ;; result.  Here is an obvious 8 instruction sequence.
7168
7169 ;; XXX
7170 (define_insn "ffssi2"
7171   [(set (match_operand:SI 0 "register_operand" "=&r")
7172         (ffs:SI (match_operand:SI 1 "register_operand" "r")))
7173    (clobber (match_scratch:SI 2 "=&r"))]
7174   "TARGET_SPARCLITE || TARGET_SPARCLET"
7175 {
7176   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";
7177 }
7178   [(set_attr "type" "multi")
7179    (set_attr "length" "8")])
7180
7181 ;; ??? This should be a define expand, so that the extra instruction have
7182 ;; a chance of being optimized away.
7183
7184 ;; Disabled because none of the UltraSPARCs implement popc.  The HAL R1
7185 ;; does, but no one uses that and we don't have a switch for it.
7186 ;
7187 ;(define_insn "ffsdi2"
7188 ;  [(set (match_operand:DI 0 "register_operand" "=&r")
7189 ;       (ffs:DI (match_operand:DI 1 "register_operand" "r")))
7190 ;   (clobber (match_scratch:DI 2 "=&r"))]
7191 ;  "TARGET_ARCH64"
7192 ;  "neg\t%1, %2\;xnor\t%1, %2, %2\;popc\t%2, %0\;movzr\t%1, 0, %0"
7193 ;  [(set_attr "type" "multi")
7194 ;   (set_attr "length" "4")])
7195
7196
7197 \f
7198 ;; Peepholes go at the end.
7199
7200 ;; Optimize consecutive loads or stores into ldd and std when possible.
7201 ;; The conditions in which we do this are very restricted and are 
7202 ;; explained in the code for {registers,memory}_ok_for_ldd functions.
7203
7204 (define_peephole2
7205   [(set (match_operand:SI 0 "memory_operand" "")
7206       (const_int 0))
7207    (set (match_operand:SI 1 "memory_operand" "")
7208       (const_int 0))]
7209   "TARGET_V9
7210    && mems_ok_for_ldd_peep (operands[0], operands[1], NULL_RTX)"
7211   [(set (match_dup 0)
7212        (const_int 0))]
7213   "operands[0] = widen_memory_access (operands[0], DImode, 0);")
7214
7215 (define_peephole2
7216   [(set (match_operand:SI 0 "memory_operand" "")
7217       (const_int 0))
7218    (set (match_operand:SI 1 "memory_operand" "")
7219       (const_int 0))]
7220   "TARGET_V9
7221    && mems_ok_for_ldd_peep (operands[1], operands[0], NULL_RTX)"
7222   [(set (match_dup 1)
7223        (const_int 0))]
7224   "operands[1] = widen_memory_access (operands[1], DImode, 0);")
7225
7226 (define_peephole2
7227   [(set (match_operand:SI 0 "register_operand" "")
7228         (match_operand:SI 1 "memory_operand" ""))
7229    (set (match_operand:SI 2 "register_operand" "")
7230         (match_operand:SI 3 "memory_operand" ""))]
7231   "registers_ok_for_ldd_peep (operands[0], operands[2]) 
7232    && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])" 
7233   [(set (match_dup 0)
7234         (match_dup 1))]
7235   "operands[1] = widen_memory_access (operands[1], DImode, 0);
7236    operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));")
7237
7238 (define_peephole2
7239   [(set (match_operand:SI 0 "memory_operand" "")
7240         (match_operand:SI 1 "register_operand" ""))
7241    (set (match_operand:SI 2 "memory_operand" "")
7242         (match_operand:SI 3 "register_operand" ""))]
7243   "registers_ok_for_ldd_peep (operands[1], operands[3]) 
7244    && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7245   [(set (match_dup 0)
7246         (match_dup 1))]
7247   "operands[0] = widen_memory_access (operands[0], DImode, 0);
7248    operands[1] = gen_rtx_REG (DImode, REGNO (operands[1]));")
7249
7250 (define_peephole2
7251   [(set (match_operand:SF 0 "register_operand" "")
7252         (match_operand:SF 1 "memory_operand" ""))
7253    (set (match_operand:SF 2 "register_operand" "")
7254         (match_operand:SF 3 "memory_operand" ""))]
7255   "registers_ok_for_ldd_peep (operands[0], operands[2]) 
7256    && mems_ok_for_ldd_peep (operands[1], operands[3], operands[0])"
7257   [(set (match_dup 0)
7258         (match_dup 1))]
7259   "operands[1] = widen_memory_access (operands[1], DFmode, 0);
7260    operands[0] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
7261
7262 (define_peephole2
7263   [(set (match_operand:SF 0 "memory_operand" "")
7264         (match_operand:SF 1 "register_operand" ""))
7265    (set (match_operand:SF 2 "memory_operand" "")
7266         (match_operand:SF 3 "register_operand" ""))]
7267   "registers_ok_for_ldd_peep (operands[1], operands[3]) 
7268   && mems_ok_for_ldd_peep (operands[0], operands[2], NULL_RTX)"
7269   [(set (match_dup 0)
7270         (match_dup 1))]
7271   "operands[0] = widen_memory_access (operands[0], DFmode, 0);
7272    operands[1] = gen_rtx_REG (DFmode, REGNO (operands[1]));")
7273
7274 (define_peephole2
7275   [(set (match_operand:SI 0 "register_operand" "")
7276         (match_operand:SI 1 "memory_operand" ""))
7277    (set (match_operand:SI 2 "register_operand" "")
7278         (match_operand:SI 3 "memory_operand" ""))]
7279   "registers_ok_for_ldd_peep (operands[2], operands[0]) 
7280   && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
7281   [(set (match_dup 2)
7282         (match_dup 3))]
7283    "operands[3] = widen_memory_access (operands[3], DImode, 0);
7284     operands[2] = gen_rtx_REG (DImode, REGNO (operands[2]));")
7285
7286 (define_peephole2
7287   [(set (match_operand:SI 0 "memory_operand" "")
7288         (match_operand:SI 1 "register_operand" ""))
7289    (set (match_operand:SI 2 "memory_operand" "")
7290         (match_operand:SI 3 "register_operand" ""))]
7291   "registers_ok_for_ldd_peep (operands[3], operands[1]) 
7292   && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)" 
7293   [(set (match_dup 2)
7294         (match_dup 3))]
7295   "operands[2] = widen_memory_access (operands[2], DImode, 0);
7296    operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
7297    ")
7298  
7299 (define_peephole2
7300   [(set (match_operand:SF 0 "register_operand" "")
7301         (match_operand:SF 1 "memory_operand" ""))
7302    (set (match_operand:SF 2 "register_operand" "")
7303         (match_operand:SF 3 "memory_operand" ""))]
7304   "registers_ok_for_ldd_peep (operands[2], operands[0]) 
7305   && mems_ok_for_ldd_peep (operands[3], operands[1], operands[0])"
7306   [(set (match_dup 2)
7307         (match_dup 3))]
7308   "operands[3] = widen_memory_access (operands[3], DFmode, 0);
7309    operands[2] = gen_rtx_REG (DFmode, REGNO (operands[2]));")
7310
7311 (define_peephole2
7312   [(set (match_operand:SF 0 "memory_operand" "")
7313         (match_operand:SF 1 "register_operand" ""))
7314    (set (match_operand:SF 2 "memory_operand" "")
7315         (match_operand:SF 3 "register_operand" ""))]
7316   "registers_ok_for_ldd_peep (operands[3], operands[1]) 
7317   && mems_ok_for_ldd_peep (operands[2], operands[0], NULL_RTX)"
7318   [(set (match_dup 2)
7319         (match_dup 3))]
7320   "operands[2] = widen_memory_access (operands[2], DFmode, 0);
7321    operands[3] = gen_rtx_REG (DFmode, REGNO (operands[3]));")
7322  
7323 ;; Optimize the case of following a reg-reg move with a test
7324 ;; of reg just moved.  Don't allow floating point regs for operand 0 or 1.
7325 ;; This can result from a float to fix conversion.
7326
7327 (define_peephole2
7328   [(set (match_operand:SI 0 "register_operand" "")
7329         (match_operand:SI 1 "register_operand" ""))
7330    (set (reg:CC 100)
7331         (compare:CC (match_operand:SI 2 "register_operand" "")
7332                     (const_int 0)))]
7333   "(rtx_equal_p (operands[2], operands[0])
7334     || rtx_equal_p (operands[2], operands[1]))
7335     && ! SPARC_FP_REG_P (REGNO (operands[0]))
7336     && ! SPARC_FP_REG_P (REGNO (operands[1]))"
7337   [(parallel [(set (match_dup 0) (match_dup 1))
7338               (set (reg:CC 100)
7339                    (compare:CC (match_dup 1) (const_int 0)))])]
7340   "")
7341
7342 (define_peephole2
7343   [(set (match_operand:DI 0 "register_operand" "")
7344         (match_operand:DI 1 "register_operand" ""))
7345    (set (reg:CCX 100)
7346         (compare:CCX (match_operand:DI 2 "register_operand" "")
7347                     (const_int 0)))]
7348   "TARGET_ARCH64
7349    && (rtx_equal_p (operands[2], operands[0])
7350        || rtx_equal_p (operands[2], operands[1]))
7351    && ! SPARC_FP_REG_P (REGNO (operands[0]))
7352    && ! SPARC_FP_REG_P (REGNO (operands[1]))"
7353   [(parallel [(set (match_dup 0) (match_dup 1))
7354               (set (reg:CCX 100)
7355                    (compare:CCX (match_dup 1) (const_int 0)))])]
7356   "")
7357
7358
7359 ;; Prefetch instructions.
7360
7361 ;; ??? UltraSPARC-III note: A memory operation loading into the floating point register
7362 ;; ??? file, if it hits the prefetch cache, has a chance to dual-issue with other memory
7363 ;; ??? operations.  With DFA we might be able to model this, but it requires a lot of
7364 ;; ??? state.
7365 (define_expand "prefetch"
7366   [(match_operand 0 "address_operand" "")
7367    (match_operand 1 "const_int_operand" "")
7368    (match_operand 2 "const_int_operand" "")]
7369   "TARGET_V9"
7370 {
7371   if (TARGET_ARCH64)
7372     emit_insn (gen_prefetch_64 (operands[0], operands[1], operands[2]));
7373   else
7374     emit_insn (gen_prefetch_32 (operands[0], operands[1], operands[2]));
7375   DONE;
7376 })
7377
7378 (define_insn "prefetch_64"
7379   [(prefetch (match_operand:DI 0 "address_operand" "p")
7380              (match_operand:DI 1 "const_int_operand" "n")
7381              (match_operand:DI 2 "const_int_operand" "n"))]
7382   ""
7383 {
7384   static const char * const prefetch_instr[2][2] = {
7385     {
7386       "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7387       "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7388     },
7389     {
7390       "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7391       "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7392     }
7393   };
7394   int read_or_write = INTVAL (operands[1]);
7395   int locality = INTVAL (operands[2]);
7396
7397   gcc_assert (read_or_write == 0 || read_or_write == 1);
7398   gcc_assert (locality >= 0 && locality < 4);
7399   return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7400 }
7401   [(set_attr "type" "load")])
7402
7403 (define_insn "prefetch_32"
7404   [(prefetch (match_operand:SI 0 "address_operand" "p")
7405              (match_operand:SI 1 "const_int_operand" "n")
7406              (match_operand:SI 2 "const_int_operand" "n"))]
7407   ""
7408 {
7409   static const char * const prefetch_instr[2][2] = {
7410     {
7411       "prefetch\t[%a0], 1", /* no locality: prefetch for one read */
7412       "prefetch\t[%a0], 0", /* medium to high locality: prefetch for several reads */
7413     },
7414     {
7415       "prefetch\t[%a0], 3", /* no locality: prefetch for one write */
7416       "prefetch\t[%a0], 2", /* medium to high locality: prefetch for several writes */
7417     }
7418   };
7419   int read_or_write = INTVAL (operands[1]);
7420   int locality = INTVAL (operands[2]);
7421
7422   gcc_assert (read_or_write == 0 || read_or_write == 1);
7423   gcc_assert (locality >= 0 && locality < 4);
7424   return prefetch_instr [read_or_write][locality == 0 ? 0 : 1];
7425 }
7426   [(set_attr "type" "load")])
7427
7428
7429 ;; Trap instructions.
7430
7431 (define_insn "trap"
7432   [(trap_if (const_int 1) (const_int 5))]
7433   ""
7434   "ta\t5"
7435   [(set_attr "type" "trap")])
7436
7437 (define_expand "conditional_trap"
7438   [(trap_if (match_operator 0 "noov_compare_operator" [(match_dup 2) (match_dup 3)])
7439             (match_operand:SI 1 "arith_operand" ""))]
7440   ""
7441   "operands[2] = gen_compare_reg (GET_CODE (operands[0]));
7442    if (GET_MODE (operands[2]) != CCmode && GET_MODE (operands[2]) != CCXmode)
7443      FAIL;
7444    operands[3] = const0_rtx;")
7445
7446 (define_insn ""
7447   [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CC 100) (const_int 0)])
7448             (match_operand:SI 1 "arith_operand" "rM"))]
7449   ""
7450 {
7451   if (TARGET_V9)
7452     return "t%C0\t%%icc, %1";
7453   else
7454     return "t%C0\t%1";
7455 }
7456   [(set_attr "type" "trap")])
7457
7458 (define_insn ""
7459   [(trap_if (match_operator 0 "noov_compare_operator" [(reg:CCX 100) (const_int 0)])
7460             (match_operand:SI 1 "arith_operand" "rM"))]
7461   "TARGET_V9"
7462   "t%C0\t%%xcc, %1"
7463   [(set_attr "type" "trap")])
7464
7465
7466 ;; TLS support instructions.
7467
7468 (define_insn "tgd_hi22"
7469   [(set (match_operand:SI 0 "register_operand" "=r")
7470         (high:SI (unspec:SI [(match_operand 1 "tgd_symbolic_operand" "")]
7471                             UNSPEC_TLSGD)))]
7472   "TARGET_TLS"
7473   "sethi\\t%%tgd_hi22(%a1), %0")
7474
7475 (define_insn "tgd_lo10"
7476   [(set (match_operand:SI 0 "register_operand" "=r")
7477         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7478                    (unspec:SI [(match_operand 2 "tgd_symbolic_operand" "")]
7479                               UNSPEC_TLSGD)))]
7480   "TARGET_TLS"
7481   "add\\t%1, %%tgd_lo10(%a2), %0")
7482
7483 (define_insn "tgd_add32"
7484   [(set (match_operand:SI 0 "register_operand" "=r")
7485         (plus:SI (match_operand:SI 1 "register_operand" "r")
7486                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7487                              (match_operand 3 "tgd_symbolic_operand" "")]
7488                             UNSPEC_TLSGD)))]
7489   "TARGET_TLS && TARGET_ARCH32"
7490   "add\\t%1, %2, %0, %%tgd_add(%a3)")
7491
7492 (define_insn "tgd_add64"
7493   [(set (match_operand:DI 0 "register_operand" "=r")
7494         (plus:DI (match_operand:DI 1 "register_operand" "r")
7495                  (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7496                              (match_operand 3 "tgd_symbolic_operand" "")]
7497                             UNSPEC_TLSGD)))]
7498   "TARGET_TLS && TARGET_ARCH64"
7499   "add\\t%1, %2, %0, %%tgd_add(%a3)")
7500
7501 (define_insn "tgd_call32"
7502   [(set (match_operand 0 "register_operand" "=r")
7503         (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")
7504                                   (match_operand 2 "tgd_symbolic_operand" "")]
7505                                  UNSPEC_TLSGD))
7506               (match_operand 3 "" "")))
7507    (clobber (reg:SI 15))]
7508   "TARGET_TLS && TARGET_ARCH32"
7509   "call\t%a1, %%tgd_call(%a2)%#"
7510   [(set_attr "type" "call")])
7511
7512 (define_insn "tgd_call64"
7513   [(set (match_operand 0 "register_operand" "=r")
7514         (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")
7515                                   (match_operand 2 "tgd_symbolic_operand" "")]
7516                                  UNSPEC_TLSGD))
7517               (match_operand 3 "" "")))
7518    (clobber (reg:DI 15))]
7519   "TARGET_TLS && TARGET_ARCH64"
7520   "call\t%a1, %%tgd_call(%a2)%#"
7521   [(set_attr "type" "call")])
7522
7523 (define_insn "tldm_hi22"
7524   [(set (match_operand:SI 0 "register_operand" "=r")
7525         (high:SI (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7526   "TARGET_TLS"
7527   "sethi\\t%%tldm_hi22(%&), %0")
7528
7529 (define_insn "tldm_lo10"
7530   [(set (match_operand:SI 0 "register_operand" "=r")
7531         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7532                     (unspec:SI [(const_int 0)] UNSPEC_TLSLDM)))]
7533   "TARGET_TLS"
7534   "add\\t%1, %%tldm_lo10(%&), %0")
7535
7536 (define_insn "tldm_add32"
7537   [(set (match_operand:SI 0 "register_operand" "=r")
7538         (plus:SI (match_operand:SI 1 "register_operand" "r")
7539                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")]
7540                             UNSPEC_TLSLDM)))]
7541   "TARGET_TLS && TARGET_ARCH32"
7542   "add\\t%1, %2, %0, %%tldm_add(%&)")
7543
7544 (define_insn "tldm_add64"
7545   [(set (match_operand:DI 0 "register_operand" "=r")
7546         (plus:DI (match_operand:DI 1 "register_operand" "r")
7547                  (unspec:DI [(match_operand:SI 2 "register_operand" "r")]
7548                             UNSPEC_TLSLDM)))]
7549   "TARGET_TLS && TARGET_ARCH64"
7550   "add\\t%1, %2, %0, %%tldm_add(%&)")
7551
7552 (define_insn "tldm_call32"
7553   [(set (match_operand 0 "register_operand" "=r")
7554         (call (mem:SI (unspec:SI [(match_operand:SI 1 "symbolic_operand" "s")]
7555                                  UNSPEC_TLSLDM))
7556               (match_operand 2 "" "")))
7557    (clobber (reg:SI 15))]
7558   "TARGET_TLS && TARGET_ARCH32"
7559   "call\t%a1, %%tldm_call(%&)%#"
7560   [(set_attr "type" "call")])
7561
7562 (define_insn "tldm_call64"
7563   [(set (match_operand 0 "register_operand" "=r")
7564         (call (mem:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "s")]
7565                                  UNSPEC_TLSLDM))
7566               (match_operand 2 "" "")))
7567    (clobber (reg:DI 15))]
7568   "TARGET_TLS && TARGET_ARCH64"
7569   "call\t%a1, %%tldm_call(%&)%#"
7570   [(set_attr "type" "call")])
7571
7572 (define_insn "tldo_hix22"
7573   [(set (match_operand:SI 0 "register_operand" "=r")
7574         (high:SI (unspec:SI [(match_operand 1 "tld_symbolic_operand" "")]
7575                             UNSPEC_TLSLDO)))]
7576   "TARGET_TLS"
7577   "sethi\\t%%tldo_hix22(%a1), %0")
7578
7579 (define_insn "tldo_lox10"
7580   [(set (match_operand:SI 0 "register_operand" "=r")
7581         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7582                    (unspec:SI [(match_operand 2 "tld_symbolic_operand" "")]
7583                               UNSPEC_TLSLDO)))]
7584   "TARGET_TLS"
7585   "xor\\t%1, %%tldo_lox10(%a2), %0")
7586
7587 (define_insn "tldo_add32"
7588   [(set (match_operand:SI 0 "register_operand" "=r")
7589         (plus:SI (match_operand:SI 1 "register_operand" "r")
7590                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7591                              (match_operand 3 "tld_symbolic_operand" "")]
7592                             UNSPEC_TLSLDO)))]
7593   "TARGET_TLS && TARGET_ARCH32"
7594   "add\\t%1, %2, %0, %%tldo_add(%a3)")
7595
7596 (define_insn "tldo_add64"
7597   [(set (match_operand:DI 0 "register_operand" "=r")
7598         (plus:DI (match_operand:DI 1 "register_operand" "r")
7599                  (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7600                              (match_operand 3 "tld_symbolic_operand" "")]
7601                             UNSPEC_TLSLDO)))]
7602   "TARGET_TLS && TARGET_ARCH64"
7603   "add\\t%1, %2, %0, %%tldo_add(%a3)")
7604
7605 (define_insn "tie_hi22"
7606   [(set (match_operand:SI 0 "register_operand" "=r")
7607         (high:SI (unspec:SI [(match_operand 1 "tie_symbolic_operand" "")]
7608                             UNSPEC_TLSIE)))]
7609   "TARGET_TLS"
7610   "sethi\\t%%tie_hi22(%a1), %0")
7611
7612 (define_insn "tie_lo10"
7613   [(set (match_operand:SI 0 "register_operand" "=r")
7614         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7615                    (unspec:SI [(match_operand 2 "tie_symbolic_operand" "")]
7616                               UNSPEC_TLSIE)))]
7617   "TARGET_TLS"
7618   "add\\t%1, %%tie_lo10(%a2), %0")
7619
7620 (define_insn "tie_ld32"
7621   [(set (match_operand:SI 0 "register_operand" "=r")
7622         (unspec:SI [(match_operand:SI 1 "register_operand" "r")
7623                     (match_operand:SI 2 "register_operand" "r")
7624                     (match_operand 3 "tie_symbolic_operand" "")]
7625                    UNSPEC_TLSIE))]
7626   "TARGET_TLS && TARGET_ARCH32"
7627   "ld\\t[%1 + %2], %0, %%tie_ld(%a3)"
7628   [(set_attr "type" "load")])
7629
7630 (define_insn "tie_ld64"
7631   [(set (match_operand:DI 0 "register_operand" "=r")
7632         (unspec:DI [(match_operand:DI 1 "register_operand" "r")
7633                     (match_operand:SI 2 "register_operand" "r")
7634                     (match_operand 3 "tie_symbolic_operand" "")]
7635                    UNSPEC_TLSIE))]
7636   "TARGET_TLS && TARGET_ARCH64"
7637   "ldx\\t[%1 + %2], %0, %%tie_ldx(%a3)"
7638   [(set_attr "type" "load")])
7639
7640 (define_insn "tie_add32"
7641   [(set (match_operand:SI 0 "register_operand" "=r")
7642         (plus:SI (match_operand:SI 1 "register_operand" "r")
7643                  (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7644                              (match_operand 3 "tie_symbolic_operand" "")]
7645                             UNSPEC_TLSIE)))]
7646   "TARGET_SUN_TLS && TARGET_ARCH32"
7647   "add\\t%1, %2, %0, %%tie_add(%a3)")
7648
7649 (define_insn "tie_add64"
7650   [(set (match_operand:DI 0 "register_operand" "=r")
7651         (plus:DI (match_operand:DI 1 "register_operand" "r")
7652                  (unspec:DI [(match_operand:DI 2 "register_operand" "r")
7653                              (match_operand 3 "tie_symbolic_operand" "")]
7654                             UNSPEC_TLSIE)))]
7655   "TARGET_SUN_TLS && TARGET_ARCH64"
7656   "add\\t%1, %2, %0, %%tie_add(%a3)")
7657
7658 (define_insn "tle_hix22_sp32"
7659   [(set (match_operand:SI 0 "register_operand" "=r")
7660         (high:SI (unspec:SI [(match_operand 1 "tle_symbolic_operand" "")]
7661                             UNSPEC_TLSLE)))]
7662   "TARGET_TLS && TARGET_ARCH32"
7663   "sethi\\t%%tle_hix22(%a1), %0")
7664
7665 (define_insn "tle_lox10_sp32"
7666   [(set (match_operand:SI 0 "register_operand" "=r")
7667         (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
7668                    (unspec:SI [(match_operand 2 "tle_symbolic_operand" "")]
7669                               UNSPEC_TLSLE)))]
7670   "TARGET_TLS && TARGET_ARCH32"
7671   "xor\\t%1, %%tle_lox10(%a2), %0")
7672
7673 (define_insn "tle_hix22_sp64"
7674   [(set (match_operand:DI 0 "register_operand" "=r")
7675         (high:DI (unspec:DI [(match_operand 1 "tle_symbolic_operand" "")]
7676                             UNSPEC_TLSLE)))]
7677   "TARGET_TLS && TARGET_ARCH64"
7678   "sethi\\t%%tle_hix22(%a1), %0")
7679
7680 (define_insn "tle_lox10_sp64"
7681   [(set (match_operand:DI 0 "register_operand" "=r")
7682         (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
7683                    (unspec:DI [(match_operand 2 "tle_symbolic_operand" "")]
7684                               UNSPEC_TLSLE)))]
7685   "TARGET_TLS && TARGET_ARCH64"
7686   "xor\\t%1, %%tle_lox10(%a2), %0")
7687
7688 ;; Now patterns combining tldo_add{32,64} with some integer loads or stores
7689 (define_insn "*tldo_ldub_sp32"
7690   [(set (match_operand:QI 0 "register_operand" "=r")
7691         (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7692                                      (match_operand 3 "tld_symbolic_operand" "")]
7693                                     UNSPEC_TLSLDO)
7694                          (match_operand:SI 1 "register_operand" "r"))))]
7695   "TARGET_TLS && TARGET_ARCH32"
7696   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7697   [(set_attr "type" "load")
7698    (set_attr "us3load_type" "3cycle")])
7699
7700 (define_insn "*tldo_ldub1_sp32"
7701   [(set (match_operand:HI 0 "register_operand" "=r")
7702         (zero_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7703                                                      (match_operand 3 "tld_symbolic_operand" "")]
7704                                                     UNSPEC_TLSLDO)
7705                                          (match_operand:SI 1 "register_operand" "r")))))]
7706   "TARGET_TLS && TARGET_ARCH32"
7707   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7708   [(set_attr "type" "load")
7709    (set_attr "us3load_type" "3cycle")])
7710
7711 (define_insn "*tldo_ldub2_sp32"
7712   [(set (match_operand:SI 0 "register_operand" "=r")
7713         (zero_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7714                                                      (match_operand 3 "tld_symbolic_operand" "")]
7715                                                     UNSPEC_TLSLDO)
7716                                          (match_operand:SI 1 "register_operand" "r")))))]
7717   "TARGET_TLS && TARGET_ARCH32"
7718   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7719   [(set_attr "type" "load")
7720    (set_attr "us3load_type" "3cycle")])
7721
7722 (define_insn "*tldo_ldsb1_sp32"
7723   [(set (match_operand:HI 0 "register_operand" "=r")
7724         (sign_extend:HI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7725                                                      (match_operand 3 "tld_symbolic_operand" "")]
7726                                                     UNSPEC_TLSLDO)
7727                                          (match_operand:SI 1 "register_operand" "r")))))]
7728   "TARGET_TLS && TARGET_ARCH32"
7729   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7730   [(set_attr "type" "sload")
7731    (set_attr "us3load_type" "3cycle")])
7732
7733 (define_insn "*tldo_ldsb2_sp32"
7734   [(set (match_operand:SI 0 "register_operand" "=r")
7735         (sign_extend:SI (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7736                                                      (match_operand 3 "tld_symbolic_operand" "")]
7737                                                     UNSPEC_TLSLDO)
7738                                          (match_operand:SI 1 "register_operand" "r")))))]
7739   "TARGET_TLS && TARGET_ARCH32"
7740   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7741   [(set_attr "type" "sload")
7742    (set_attr "us3load_type" "3cycle")])
7743
7744 (define_insn "*tldo_ldub_sp64"
7745   [(set (match_operand:QI 0 "register_operand" "=r")
7746         (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7747                                      (match_operand 3 "tld_symbolic_operand" "")]
7748                                     UNSPEC_TLSLDO)
7749                          (match_operand:DI 1 "register_operand" "r"))))]
7750   "TARGET_TLS && TARGET_ARCH64"
7751   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7752   [(set_attr "type" "load")
7753    (set_attr "us3load_type" "3cycle")])
7754
7755 (define_insn "*tldo_ldub1_sp64"
7756   [(set (match_operand:HI 0 "register_operand" "=r")
7757         (zero_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7758                                                      (match_operand 3 "tld_symbolic_operand" "")]
7759                                                     UNSPEC_TLSLDO)
7760                                          (match_operand:DI 1 "register_operand" "r")))))]
7761   "TARGET_TLS && TARGET_ARCH64"
7762   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7763   [(set_attr "type" "load")
7764    (set_attr "us3load_type" "3cycle")])
7765
7766 (define_insn "*tldo_ldub2_sp64"
7767   [(set (match_operand:SI 0 "register_operand" "=r")
7768         (zero_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7769                                                      (match_operand 3 "tld_symbolic_operand" "")]
7770                                                     UNSPEC_TLSLDO)
7771                                          (match_operand:DI 1 "register_operand" "r")))))]
7772   "TARGET_TLS && TARGET_ARCH64"
7773   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7774   [(set_attr "type" "load")
7775    (set_attr "us3load_type" "3cycle")])
7776
7777 (define_insn "*tldo_ldub3_sp64"
7778   [(set (match_operand:DI 0 "register_operand" "=r")
7779         (zero_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7780                                                      (match_operand 3 "tld_symbolic_operand" "")]
7781                                                     UNSPEC_TLSLDO)
7782                                          (match_operand:DI 1 "register_operand" "r")))))]
7783   "TARGET_TLS && TARGET_ARCH64"
7784   "ldub\t[%1 + %2], %0, %%tldo_add(%3)"
7785   [(set_attr "type" "load")
7786    (set_attr "us3load_type" "3cycle")])
7787
7788 (define_insn "*tldo_ldsb1_sp64"
7789   [(set (match_operand:HI 0 "register_operand" "=r")
7790         (sign_extend:HI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7791                                                      (match_operand 3 "tld_symbolic_operand" "")]
7792                                                     UNSPEC_TLSLDO)
7793                                          (match_operand:DI 1 "register_operand" "r")))))]
7794   "TARGET_TLS && TARGET_ARCH64"
7795   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7796   [(set_attr "type" "sload")
7797    (set_attr "us3load_type" "3cycle")])
7798
7799 (define_insn "*tldo_ldsb2_sp64"
7800   [(set (match_operand:SI 0 "register_operand" "=r")
7801         (sign_extend:SI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7802                                                      (match_operand 3 "tld_symbolic_operand" "")]
7803                                                     UNSPEC_TLSLDO)
7804                                          (match_operand:DI 1 "register_operand" "r")))))]
7805   "TARGET_TLS && TARGET_ARCH64"
7806   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7807   [(set_attr "type" "sload")
7808    (set_attr "us3load_type" "3cycle")])
7809
7810 (define_insn "*tldo_ldsb3_sp64"
7811   [(set (match_operand:DI 0 "register_operand" "=r")
7812         (sign_extend:DI (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7813                                                      (match_operand 3 "tld_symbolic_operand" "")]
7814                                                     UNSPEC_TLSLDO)
7815                                          (match_operand:DI 1 "register_operand" "r")))))]
7816   "TARGET_TLS && TARGET_ARCH64"
7817   "ldsb\t[%1 + %2], %0, %%tldo_add(%3)"
7818   [(set_attr "type" "sload")
7819    (set_attr "us3load_type" "3cycle")])
7820
7821 (define_insn "*tldo_lduh_sp32"
7822   [(set (match_operand:HI 0 "register_operand" "=r")
7823         (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7824                                      (match_operand 3 "tld_symbolic_operand" "")]
7825                                     UNSPEC_TLSLDO)
7826                          (match_operand:SI 1 "register_operand" "r"))))]
7827   "TARGET_TLS && TARGET_ARCH32"
7828   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7829   [(set_attr "type" "load")
7830    (set_attr "us3load_type" "3cycle")])
7831
7832 (define_insn "*tldo_lduh1_sp32"
7833   [(set (match_operand:SI 0 "register_operand" "=r")
7834         (zero_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7835                                                      (match_operand 3 "tld_symbolic_operand" "")]
7836                                                     UNSPEC_TLSLDO)
7837                                          (match_operand:SI 1 "register_operand" "r")))))]
7838   "TARGET_TLS && TARGET_ARCH32"
7839   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7840   [(set_attr "type" "load")
7841    (set_attr "us3load_type" "3cycle")])
7842
7843 (define_insn "*tldo_ldsh1_sp32"
7844   [(set (match_operand:SI 0 "register_operand" "=r")
7845         (sign_extend:SI (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7846                                                      (match_operand 3 "tld_symbolic_operand" "")]
7847                                                     UNSPEC_TLSLDO)
7848                                          (match_operand:SI 1 "register_operand" "r")))))]
7849   "TARGET_TLS && TARGET_ARCH32"
7850   "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7851   [(set_attr "type" "sload")
7852    (set_attr "us3load_type" "3cycle")])
7853
7854 (define_insn "*tldo_lduh_sp64"
7855   [(set (match_operand:HI 0 "register_operand" "=r")
7856         (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7857                                      (match_operand 3 "tld_symbolic_operand" "")]
7858                                     UNSPEC_TLSLDO)
7859                          (match_operand:DI 1 "register_operand" "r"))))]
7860   "TARGET_TLS && TARGET_ARCH64"
7861   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7862   [(set_attr "type" "load")
7863    (set_attr "us3load_type" "3cycle")])
7864
7865 (define_insn "*tldo_lduh1_sp64"
7866   [(set (match_operand:SI 0 "register_operand" "=r")
7867         (zero_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7868                                                      (match_operand 3 "tld_symbolic_operand" "")]
7869                                                     UNSPEC_TLSLDO)
7870                                          (match_operand:DI 1 "register_operand" "r")))))]
7871   "TARGET_TLS && TARGET_ARCH64"
7872   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7873   [(set_attr "type" "load")
7874    (set_attr "us3load_type" "3cycle")])
7875
7876 (define_insn "*tldo_lduh2_sp64"
7877   [(set (match_operand:DI 0 "register_operand" "=r")
7878         (zero_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7879                                                      (match_operand 3 "tld_symbolic_operand" "")]
7880                                                     UNSPEC_TLSLDO)
7881                                          (match_operand:DI 1 "register_operand" "r")))))]
7882   "TARGET_TLS && TARGET_ARCH64"
7883   "lduh\t[%1 + %2], %0, %%tldo_add(%3)"
7884   [(set_attr "type" "load")
7885    (set_attr "us3load_type" "3cycle")])
7886
7887 (define_insn "*tldo_ldsh1_sp64"
7888   [(set (match_operand:SI 0 "register_operand" "=r")
7889         (sign_extend:SI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7890                                                      (match_operand 3 "tld_symbolic_operand" "")]
7891                                                     UNSPEC_TLSLDO)
7892                                          (match_operand:DI 1 "register_operand" "r")))))]
7893   "TARGET_TLS && TARGET_ARCH64"
7894   "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7895   [(set_attr "type" "sload")
7896    (set_attr "us3load_type" "3cycle")])
7897
7898 (define_insn "*tldo_ldsh2_sp64"
7899   [(set (match_operand:DI 0 "register_operand" "=r")
7900         (sign_extend:DI (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7901                                                      (match_operand 3 "tld_symbolic_operand" "")]
7902                                                     UNSPEC_TLSLDO)
7903                                          (match_operand:DI 1 "register_operand" "r")))))]
7904   "TARGET_TLS && TARGET_ARCH64"
7905   "ldsh\t[%1 + %2], %0, %%tldo_add(%3)"
7906   [(set_attr "type" "sload")
7907    (set_attr "us3load_type" "3cycle")])
7908
7909 (define_insn "*tldo_lduw_sp32"
7910   [(set (match_operand:SI 0 "register_operand" "=r")
7911         (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7912                                      (match_operand 3 "tld_symbolic_operand" "")]
7913                                     UNSPEC_TLSLDO)
7914                          (match_operand:SI 1 "register_operand" "r"))))]
7915   "TARGET_TLS && TARGET_ARCH32"
7916   "ld\t[%1 + %2], %0, %%tldo_add(%3)"
7917   [(set_attr "type" "load")])
7918
7919 (define_insn "*tldo_lduw_sp64"
7920   [(set (match_operand:SI 0 "register_operand" "=r")
7921         (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7922                                      (match_operand 3 "tld_symbolic_operand" "")]
7923                                     UNSPEC_TLSLDO)
7924                          (match_operand:DI 1 "register_operand" "r"))))]
7925   "TARGET_TLS && TARGET_ARCH64"
7926   "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7927   [(set_attr "type" "load")])
7928
7929 (define_insn "*tldo_lduw1_sp64"
7930   [(set (match_operand:DI 0 "register_operand" "=r")
7931         (zero_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7932                                                      (match_operand 3 "tld_symbolic_operand" "")]
7933                                                     UNSPEC_TLSLDO)
7934                                          (match_operand:DI 1 "register_operand" "r")))))]
7935   "TARGET_TLS && TARGET_ARCH64"
7936   "lduw\t[%1 + %2], %0, %%tldo_add(%3)"
7937   [(set_attr "type" "load")])
7938
7939 (define_insn "*tldo_ldsw1_sp64"
7940   [(set (match_operand:DI 0 "register_operand" "=r")
7941         (sign_extend:DI (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7942                                                      (match_operand 3 "tld_symbolic_operand" "")]
7943                                                     UNSPEC_TLSLDO)
7944                                          (match_operand:DI 1 "register_operand" "r")))))]
7945   "TARGET_TLS && TARGET_ARCH64"
7946   "ldsw\t[%1 + %2], %0, %%tldo_add(%3)"
7947   [(set_attr "type" "sload")
7948    (set_attr "us3load_type" "3cycle")])
7949
7950 (define_insn "*tldo_ldx_sp64"
7951   [(set (match_operand:DI 0 "register_operand" "=r")
7952         (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7953                                      (match_operand 3 "tld_symbolic_operand" "")]
7954                                     UNSPEC_TLSLDO)
7955                          (match_operand:DI 1 "register_operand" "r"))))]
7956   "TARGET_TLS && TARGET_ARCH64"
7957   "ldx\t[%1 + %2], %0, %%tldo_add(%3)"
7958   [(set_attr "type" "load")])
7959
7960 (define_insn "*tldo_stb_sp32"
7961   [(set (mem:QI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7962                                      (match_operand 3 "tld_symbolic_operand" "")]
7963                                     UNSPEC_TLSLDO)
7964                          (match_operand:SI 1 "register_operand" "r")))
7965         (match_operand:QI 0 "register_operand" "=r"))]
7966   "TARGET_TLS && TARGET_ARCH32"
7967   "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7968   [(set_attr "type" "store")])
7969
7970 (define_insn "*tldo_stb_sp64"
7971   [(set (mem:QI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7972                                      (match_operand 3 "tld_symbolic_operand" "")]
7973                                     UNSPEC_TLSLDO)
7974                          (match_operand:DI 1 "register_operand" "r")))
7975         (match_operand:QI 0 "register_operand" "=r"))]
7976   "TARGET_TLS && TARGET_ARCH64"
7977   "stb\t%0, [%1 + %2], %%tldo_add(%3)"
7978   [(set_attr "type" "store")])
7979
7980 (define_insn "*tldo_sth_sp32"
7981   [(set (mem:HI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
7982                                      (match_operand 3 "tld_symbolic_operand" "")]
7983                                     UNSPEC_TLSLDO)
7984                          (match_operand:SI 1 "register_operand" "r")))
7985         (match_operand:HI 0 "register_operand" "=r"))]
7986   "TARGET_TLS && TARGET_ARCH32"
7987   "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7988   [(set_attr "type" "store")])
7989
7990 (define_insn "*tldo_sth_sp64"
7991   [(set (mem:HI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
7992                                      (match_operand 3 "tld_symbolic_operand" "")]
7993                                     UNSPEC_TLSLDO)
7994                          (match_operand:DI 1 "register_operand" "r")))
7995         (match_operand:HI 0 "register_operand" "=r"))]
7996   "TARGET_TLS && TARGET_ARCH64"
7997   "sth\t%0, [%1 + %2], %%tldo_add(%3)"
7998   [(set_attr "type" "store")])
7999
8000 (define_insn "*tldo_stw_sp32"
8001   [(set (mem:SI (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "r")
8002                                      (match_operand 3 "tld_symbolic_operand" "")]
8003                                     UNSPEC_TLSLDO)
8004                          (match_operand:SI 1 "register_operand" "r")))
8005         (match_operand:SI 0 "register_operand" "=r"))]
8006   "TARGET_TLS && TARGET_ARCH32"
8007   "st\t%0, [%1 + %2], %%tldo_add(%3)"
8008   [(set_attr "type" "store")])
8009
8010 (define_insn "*tldo_stw_sp64"
8011   [(set (mem:SI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8012                                      (match_operand 3 "tld_symbolic_operand" "")]
8013                                     UNSPEC_TLSLDO)
8014                          (match_operand:DI 1 "register_operand" "r")))
8015         (match_operand:SI 0 "register_operand" "=r"))]
8016   "TARGET_TLS && TARGET_ARCH64"
8017   "stw\t%0, [%1 + %2], %%tldo_add(%3)"
8018   [(set_attr "type" "store")])
8019
8020 (define_insn "*tldo_stx_sp64"
8021   [(set (mem:DI (plus:DI (unspec:DI [(match_operand:SI 2 "register_operand" "r")
8022                                      (match_operand 3 "tld_symbolic_operand" "")]
8023                                     UNSPEC_TLSLDO)
8024                          (match_operand:DI 1 "register_operand" "r")))
8025         (match_operand:DI 0 "register_operand" "=r"))]
8026   "TARGET_TLS && TARGET_ARCH64"
8027   "stx\t%0, [%1 + %2], %%tldo_add(%3)"
8028   [(set_attr "type" "store")])
8029
8030
8031 ;; Stack protector instructions.
8032
8033 (define_expand "stack_protect_set"
8034   [(match_operand 0 "memory_operand" "")
8035    (match_operand 1 "memory_operand" "")]
8036   ""
8037 {
8038 #ifdef TARGET_THREAD_SSP_OFFSET
8039   rtx tlsreg = gen_rtx_REG (Pmode, 7);
8040   rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
8041   operands[1] = gen_rtx_MEM (Pmode, addr);
8042 #endif
8043   if (TARGET_ARCH64)
8044     emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
8045   else
8046     emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
8047   DONE;
8048 })
8049
8050 (define_insn "stack_protect_setsi"
8051   [(set (match_operand:SI 0 "memory_operand" "=m")
8052         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
8053    (set (match_scratch:SI 2 "=&r") (const_int 0))]
8054   "TARGET_ARCH32"
8055   "ld\t%1, %2\;st\t%2, %0\;mov\t0, %2"
8056   [(set_attr "type" "multi")
8057    (set_attr "length" "3")])
8058
8059 (define_insn "stack_protect_setdi"
8060   [(set (match_operand:DI 0 "memory_operand" "=m")
8061         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
8062    (set (match_scratch:DI 2 "=&r") (const_int 0))]
8063   "TARGET_ARCH64"
8064   "ldx\t%1, %2\;stx\t%2, %0\;mov\t0, %2"
8065   [(set_attr "type" "multi")
8066    (set_attr "length" "3")])
8067
8068 (define_expand "stack_protect_test"
8069   [(match_operand 0 "memory_operand" "")
8070    (match_operand 1 "memory_operand" "")
8071    (match_operand 2 "" "")]
8072   ""
8073 {
8074 #ifdef TARGET_THREAD_SSP_OFFSET
8075   rtx tlsreg = gen_rtx_REG (Pmode, 7);
8076   rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
8077   operands[1] = gen_rtx_MEM (Pmode, addr);
8078 #endif
8079   if (TARGET_ARCH64)
8080     {
8081       rtx temp = gen_reg_rtx (Pmode);
8082       emit_insn (gen_stack_protect_testdi (temp, operands[0], operands[1]));
8083       sparc_compare_op0 = temp;
8084       sparc_compare_op1 = const0_rtx;
8085     }
8086   else
8087     {
8088       emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
8089       sparc_compare_op0 = gen_rtx_REG (CCmode, SPARC_ICC_REG);
8090       sparc_compare_op1 = const0_rtx;
8091     }
8092   emit_jump_insn (gen_beq (operands[2]));
8093   DONE;
8094 })
8095
8096 (define_insn "stack_protect_testsi"
8097   [(set (reg:CC 100)
8098         (unspec:CC [(match_operand:SI 0 "memory_operand" "m")
8099                     (match_operand:SI 1 "memory_operand" "m")]
8100                    UNSPEC_SP_TEST))
8101    (set (match_scratch:SI 3 "=r") (const_int 0))
8102    (clobber (match_scratch:SI 2 "=&r"))]
8103   "TARGET_ARCH32"
8104   "ld\t%0, %2\;ld\t%1, %3\;xorcc\t%2, %3, %2\;mov\t0, %3"
8105   [(set_attr "type" "multi")
8106    (set_attr "length" "4")])
8107
8108 (define_insn "stack_protect_testdi"
8109   [(set (match_operand:DI 0 "register_operand" "=&r")
8110         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
8111                     (match_operand:DI 2 "memory_operand" "m")]
8112                    UNSPEC_SP_TEST))
8113    (set (match_scratch:DI 3 "=r") (const_int 0))]
8114   "TARGET_ARCH64"
8115   "ldx\t%1, %0\;ldx\t%2, %3\;xor\t%0, %3, %0\;mov\t0, %3"
8116   [(set_attr "type" "multi")
8117    (set_attr "length" "4")])
8118
8119
8120 ;; Vector instructions.
8121
8122 (define_insn "addv2si3"
8123   [(set (match_operand:V2SI 0 "register_operand" "=e")
8124         (plus:V2SI (match_operand:V2SI 1 "register_operand" "e")
8125                    (match_operand:V2SI 2 "register_operand" "e")))]
8126   "TARGET_VIS"
8127   "fpadd32\t%1, %2, %0"
8128   [(set_attr "type" "fga")
8129    (set_attr "fptype" "double")])
8130
8131 (define_insn "addv4hi3"
8132   [(set (match_operand:V4HI 0 "register_operand" "=e")
8133          (plus:V4HI (match_operand:V4HI 1 "register_operand" "e")
8134                     (match_operand:V4HI 2 "register_operand" "e")))]
8135   "TARGET_VIS"
8136   "fpadd16\t%1, %2, %0"
8137   [(set_attr "type" "fga")
8138    (set_attr "fptype" "double")])
8139
8140 ;; fpadd32s is emitted by the addsi3 pattern.
8141
8142 (define_insn "addv2hi3"
8143   [(set (match_operand:V2HI 0 "register_operand" "=f")
8144         (plus:V2HI (match_operand:V2HI 1 "register_operand" "f")
8145                    (match_operand:V2HI 2 "register_operand" "f")))]
8146   "TARGET_VIS"
8147   "fpadd16s\t%1, %2, %0"
8148   [(set_attr "type" "fga")
8149    (set_attr "fptype" "single")])
8150
8151 (define_insn "subv2si3"
8152   [(set (match_operand:V2SI 0 "register_operand" "=e")
8153         (minus:V2SI (match_operand:V2SI 1 "register_operand" "e")
8154                     (match_operand:V2SI 2 "register_operand" "e")))]
8155   "TARGET_VIS"
8156   "fpsub32\t%1, %2, %0"
8157   [(set_attr "type" "fga")
8158    (set_attr "fptype" "double")])
8159
8160 (define_insn "subv4hi3"
8161   [(set (match_operand:V4HI 0 "register_operand" "=e")
8162         (minus:V4HI (match_operand:V4HI 1 "register_operand" "e")
8163                     (match_operand:V4HI 2 "register_operand" "e")))]
8164   "TARGET_VIS"
8165   "fpsub16\t%1, %2, %0"
8166   [(set_attr "type" "fga")
8167    (set_attr "fptype" "double")])
8168
8169 ;; fpsub32s is emitted by the subsi3 pattern.
8170
8171 (define_insn "subv2hi3"
8172   [(set (match_operand:V2HI 0 "register_operand" "=f")
8173         (minus:V2HI (match_operand:V2HI 1 "register_operand" "f")
8174                     (match_operand:V2HI 2 "register_operand" "f")))]
8175   "TARGET_VIS"
8176   "fpsub16s\t%1, %2, %0"
8177   [(set_attr "type" "fga")
8178    (set_attr "fptype" "single")])
8179
8180 ;; All other logical instructions have integer equivalents so they
8181 ;; are defined together.
8182
8183 ;; (ior (not (op1)) (not (op2))) is the canonical form of NAND.
8184
8185 (define_insn "*nand<V64:mode>_vis"
8186   [(set (match_operand:V64 0 "register_operand" "=e")
8187         (ior:V64 (not:V64 (match_operand:V64 1 "register_operand" "e"))
8188                  (not:V64 (match_operand:V64 2 "register_operand" "e"))))]
8189   "TARGET_VIS"
8190   "fnand\t%1, %2, %0"
8191   [(set_attr "type" "fga")
8192    (set_attr "fptype" "double")])
8193
8194 (define_insn "*nand<V32:mode>_vis"
8195   [(set (match_operand:V32 0 "register_operand" "=f")
8196          (ior:V32 (not:V32 (match_operand:V32 1 "register_operand" "f"))
8197                   (not:V32 (match_operand:V32 2 "register_operand" "f"))))]
8198   "TARGET_VIS"
8199   "fnands\t%1, %2, %0"
8200   [(set_attr "type" "fga")
8201    (set_attr "fptype" "single")])
8202
8203 ;; Hard to generate VIS instructions.  We have builtins for these.
8204
8205 (define_insn "fpack16_vis"
8206   [(set (match_operand:V4QI 0 "register_operand" "=f")
8207         (unspec:V4QI [(match_operand:V4HI 1 "register_operand" "e")]
8208                       UNSPEC_FPACK16))]
8209   "TARGET_VIS"
8210   "fpack16\t%1, %0"
8211   [(set_attr "type" "fga")
8212    (set_attr "fptype" "double")])
8213
8214 (define_insn "fpackfix_vis"
8215   [(set (match_operand:V2HI 0 "register_operand" "=f")
8216         (unspec:V2HI [(match_operand:V2SI 1 "register_operand" "e")]
8217                       UNSPEC_FPACKFIX))]
8218   "TARGET_VIS"
8219   "fpackfix\t%1, %0"
8220   [(set_attr "type" "fga")
8221    (set_attr "fptype" "double")])
8222
8223 (define_insn "fpack32_vis"
8224   [(set (match_operand:V8QI 0 "register_operand" "=e")
8225         (unspec:V8QI [(match_operand:V2SI 1 "register_operand" "e")
8226                       (match_operand:V8QI 2 "register_operand" "e")]
8227                      UNSPEC_FPACK32))]
8228   "TARGET_VIS"
8229   "fpack32\t%1, %2, %0"
8230   [(set_attr "type" "fga")
8231    (set_attr "fptype" "double")])
8232
8233 (define_insn "fexpand_vis"
8234   [(set (match_operand:V4HI 0 "register_operand" "=e")
8235         (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")]
8236          UNSPEC_FEXPAND))]
8237  "TARGET_VIS"
8238  "fexpand\t%1, %0"
8239  [(set_attr "type" "fga")
8240   (set_attr "fptype" "double")])
8241
8242 ;; It may be possible to describe this operation as (1 indexed):
8243 ;; (vec_select (vec_duplicate (vec_duplicate (vec_concat 1 2)))
8244 ;;  1,5,10,14,19,23,28,32)
8245 ;; Note that (vec_merge:V8QI [(V4QI) (V4QI)] (10101010 = 170) doesn't work
8246 ;; because vec_merge expects all the operands to be of the same type.
8247 (define_insn "fpmerge_vis"
8248   [(set (match_operand:V8QI 0 "register_operand" "=e")
8249         (unspec:V8QI [(match_operand:V4QI 1 "register_operand" "f")
8250                       (match_operand:V4QI 2 "register_operand" "f")]
8251          UNSPEC_FPMERGE))]
8252  "TARGET_VIS"
8253  "fpmerge\t%1, %2, %0"
8254  [(set_attr "type" "fga")
8255   (set_attr "fptype" "double")])
8256
8257 ;; Partitioned multiply instructions
8258 (define_insn "fmul8x16_vis"
8259   [(set (match_operand:V4HI 0 "register_operand" "=e")
8260         (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
8261                    (match_operand:V4HI 2 "register_operand" "e")))]
8262   "TARGET_VIS"
8263   "fmul8x16\t%1, %2, %0"
8264   [(set_attr "type" "fpmul")
8265    (set_attr "fptype" "double")])
8266
8267 ;; Only one of the following two insns can be a multiply.
8268 (define_insn "fmul8x16au_vis"
8269   [(set (match_operand:V4HI 0 "register_operand" "=e")
8270         (mult:V4HI (match_operand:V4QI 1 "register_operand" "f")
8271                    (match_operand:V2HI 2 "register_operand" "f")))]
8272   "TARGET_VIS"
8273   "fmul8x16au\t%1, %2, %0"
8274   [(set_attr "type" "fpmul")
8275    (set_attr "fptype" "double")])
8276
8277 (define_insn "fmul8x16al_vis"
8278   [(set (match_operand:V4HI 0 "register_operand" "=e")
8279         (unspec:V4HI [(match_operand:V4QI 1 "register_operand" "f")
8280                       (match_operand:V2HI 2 "register_operand" "f")]
8281          UNSPEC_MUL16AL))]
8282   "TARGET_VIS"
8283   "fmul8x16al\t%1, %2, %0"
8284   [(set_attr "type" "fpmul")
8285    (set_attr "fptype" "double")])
8286
8287 ;; Only one of the following two insns can be a multiply.
8288 (define_insn "fmul8sux16_vis"
8289   [(set (match_operand:V4HI 0 "register_operand" "=e")
8290         (mult:V4HI (match_operand:V8QI 1 "register_operand" "e")
8291                    (match_operand:V4HI 2 "register_operand" "e")))]
8292   "TARGET_VIS"
8293   "fmul8sux16\t%1, %2, %0"
8294   [(set_attr "type" "fpmul")
8295    (set_attr "fptype" "double")])
8296
8297 (define_insn "fmul8ulx16_vis"
8298   [(set (match_operand:V4HI 0 "register_operand" "=e")
8299         (unspec:V4HI [(match_operand:V8QI 1 "register_operand" "e")
8300                       (match_operand:V4HI 2 "register_operand" "e")]
8301          UNSPEC_MUL8UL))]
8302   "TARGET_VIS"
8303   "fmul8ulx16\t%1, %2, %0"
8304   [(set_attr "type" "fpmul")
8305    (set_attr "fptype" "double")])
8306
8307 ;; Only one of the following two insns can be a multiply.
8308 (define_insn "fmuld8sux16_vis"
8309   [(set (match_operand:V2SI 0 "register_operand" "=e")
8310         (mult:V2SI (match_operand:V4QI 1 "register_operand" "f")
8311                    (match_operand:V2HI 2 "register_operand" "f")))]
8312   "TARGET_VIS"
8313   "fmuld8sux16\t%1, %2, %0"
8314   [(set_attr "type" "fpmul")
8315    (set_attr "fptype" "double")])
8316
8317 (define_insn "fmuld8ulx16_vis"
8318   [(set (match_operand:V2SI 0 "register_operand" "=e")
8319         (unspec:V2SI [(match_operand:V4QI 1 "register_operand" "f")
8320                       (match_operand:V2HI 2 "register_operand" "f")]
8321          UNSPEC_MULDUL))]
8322   "TARGET_VIS"
8323   "fmuld8ulx16\t%1, %2, %0"
8324   [(set_attr "type" "fpmul")
8325    (set_attr "fptype" "double")])
8326
8327 ;; Using faligndata only makes sense after an alignaddr since the choice of
8328 ;; bytes to take out of each operand is dependent on the results of the last
8329 ;; alignaddr.
8330 (define_insn "faligndata<V64I:mode>_vis"
8331   [(set (match_operand:V64I 0 "register_operand" "=e")
8332         (unspec:V64I [(match_operand:V64I 1 "register_operand" "e")
8333                       (match_operand:V64I 2 "register_operand" "e")]
8334          UNSPEC_ALIGNDATA))]
8335   "TARGET_VIS"
8336   "faligndata\t%1, %2, %0"
8337   [(set_attr "type" "fga")
8338    (set_attr "fptype" "double")])
8339
8340 (define_insn "alignaddr<P:mode>_vis"
8341   [(set (match_operand:P 0 "register_operand" "=r")
8342         (unspec:P [(match_operand:P 1 "register_or_zero_operand" "rJ")
8343                    (match_operand:P 2 "register_or_zero_operand" "rJ")]
8344          UNSPEC_ALIGNADDR))]
8345   "TARGET_VIS"
8346   "alignaddr\t%r1, %r2, %0")
8347
8348 (define_insn "pdist_vis"
8349   [(set (match_operand:DI 0 "register_operand" "=e")
8350         (unspec:DI [(match_operand:V8QI 1 "register_operand" "e")
8351                     (match_operand:V8QI 2 "register_operand" "e")
8352                     (match_operand:DI 3 "register_operand" "0")]
8353          UNSPEC_PDIST))]
8354   "TARGET_VIS"
8355   "pdist\t%1, %2, %0"
8356   [(set_attr "type" "fga")
8357    (set_attr "fptype" "double")])
8358
8359 (include "sync.md")