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