190075Sobrien;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler
2132718Skan;; Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3169689Skan;; 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
4169689Skan;; Free Software Foundation, Inc.
590075Sobrien;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
690075Sobrien
7132718Skan;; This file is part of GCC.
890075Sobrien
9132718Skan;; GCC is free software; you can redistribute it and/or modify it
10132718Skan;; under the terms of the GNU General Public License as published
11132718Skan;; by the Free Software Foundation; either version 2, or (at your
12132718Skan;; option) any later version.
1390075Sobrien
14132718Skan;; GCC is distributed in the hope that it will be useful, but WITHOUT
15132718Skan;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16132718Skan;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
17132718Skan;; License for more details.
1890075Sobrien
1990075Sobrien;; You should have received a copy of the GNU General Public License
20132718Skan;; along with GCC; see the file COPYING.  If not, write to the
21169689Skan;; Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
22169689Skan;; MA 02110-1301, USA.
2390075Sobrien
2490075Sobrien;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
2590075Sobrien
26132718Skan;;
27132718Skan;; UNSPEC usage
28132718Skan;;
29132718Skan
30132718Skan(define_constants
31132718Skan  [(UNSPEC_FRSP			0)	; frsp for POWER machines
32132718Skan   (UNSPEC_TIE			5)	; tie stack contents and stack pointer
33132718Skan   (UNSPEC_TOCPTR		6)	; address of a word pointing to the TOC
34132718Skan   (UNSPEC_TOC			7)	; address of the TOC (more-or-less)
35132718Skan   (UNSPEC_MOVSI_GOT		8)
36132718Skan   (UNSPEC_MV_CR_OV		9)	; move_from_CR_ov_bit
37132718Skan   (UNSPEC_FCTIWZ		10)
38169689Skan   (UNSPEC_FRIM			11)
39169689Skan   (UNSPEC_FRIN			12)
40169689Skan   (UNSPEC_FRIP			13)
41169689Skan   (UNSPEC_FRIZ			14)
42132718Skan   (UNSPEC_LD_MPIC		15)	; load_macho_picbase
43132718Skan   (UNSPEC_MPIC_CORRECT		16)	; macho_correct_pic
44132718Skan   (UNSPEC_TLSGD		17)
45132718Skan   (UNSPEC_TLSLD		18)
46132718Skan   (UNSPEC_MOVESI_FROM_CR	19)
47132718Skan   (UNSPEC_MOVESI_TO_CR		20)
48132718Skan   (UNSPEC_TLSDTPREL		21)
49132718Skan   (UNSPEC_TLSDTPRELHA		22)
50132718Skan   (UNSPEC_TLSDTPRELLO		23)
51132718Skan   (UNSPEC_TLSGOTDTPREL		24)
52132718Skan   (UNSPEC_TLSTPREL		25)
53132718Skan   (UNSPEC_TLSTPRELHA		26)
54132718Skan   (UNSPEC_TLSTPRELLO		27)
55132718Skan   (UNSPEC_TLSGOTTPREL		28)
56132718Skan   (UNSPEC_TLSTLS		29)
57132718Skan   (UNSPEC_FIX_TRUNC_TF		30)	; fadd, rounding towards zero
58169689Skan   (UNSPEC_MV_CR_GT		31)	; move_from_CR_gt_bit
59169689Skan   (UNSPEC_STFIWX		32)
60169689Skan   (UNSPEC_POPCNTB		33)
61169689Skan   (UNSPEC_FRES			34)
62169689Skan   (UNSPEC_SP_SET		35)
63169689Skan   (UNSPEC_SP_TEST		36)
64169689Skan   (UNSPEC_SYNC			37)
65169689Skan   (UNSPEC_LWSYNC		38)
66169689Skan   (UNSPEC_ISYNC		39)
67169689Skan   (UNSPEC_SYNC_OP		40)
68169689Skan   (UNSPEC_ATOMIC		41)
69169689Skan   (UNSPEC_CMPXCHG		42)
70169689Skan   (UNSPEC_XCHG			43)
71169689Skan   (UNSPEC_AND			44)
72169689Skan   (UNSPEC_DLMZB		45)
73169689Skan   (UNSPEC_DLMZB_CR		46)
74169689Skan   (UNSPEC_DLMZB_STRLEN		47)
75132718Skan  ])
76132718Skan
77132718Skan;;
78132718Skan;; UNSPEC_VOLATILE usage
79132718Skan;;
80132718Skan
81132718Skan(define_constants
82132718Skan  [(UNSPECV_BLOCK		0)
83169689Skan   (UNSPECV_LL			1)	; load-locked
84169689Skan   (UNSPECV_SC			2)	; store-conditional
85132718Skan   (UNSPECV_EH_RR		9)	; eh_reg_restore
86132718Skan  ])
8790075Sobrien
8890075Sobrien;; Define an insn type attribute.  This is used in function unit delay
8990075Sobrien;; computations.
90169689Skan(define_attr "type" "integer,two,three,load,load_ext,load_ext_u,load_ext_ux,load_ux,load_u,store,store_ux,store_u,fpload,fpload_ux,fpload_u,fpstore,fpstore_ux,fpstore_u,vecload,vecstore,imul,imul2,imul3,lmul,idiv,ldiv,insert_word,branch,cmp,fast_compare,compare,delayed_compare,imul_compare,lmul_compare,fpcompare,cr_logical,delayed_cr,mfcr,mfcrf,mtcr,mfjmpr,mtjmpr,fp,fpsimple,dmul,sdiv,ddiv,ssqrt,dsqrt,jmpreg,brinc,vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,vecfloat,vecfdiv,isync,sync,load_l,store_c"
9190075Sobrien  (const_string "integer"))
9290075Sobrien
9390075Sobrien;; Length (in bytes).
94169689Skan; '(pc)' in the following doesn't include the instruction itself; it is
9590075Sobrien; calculated as if the instruction had zero size.
9690075Sobrien(define_attr "length" ""
9790075Sobrien  (if_then_else (eq_attr "type" "branch")
9890075Sobrien		(if_then_else (and (ge (minus (match_dup 0) (pc))
9990075Sobrien				       (const_int -32768))
10090075Sobrien				   (lt (minus (match_dup 0) (pc))
10190075Sobrien				       (const_int 32764)))
10290075Sobrien			      (const_int 4)
10390075Sobrien			      (const_int 8))
10490075Sobrien		(const_int 4)))
10590075Sobrien
10690075Sobrien;; Processor type -- this attribute must exactly match the processor_type
10790075Sobrien;; enumeration in rs6000.h.
10890075Sobrien
109132718Skan(define_attr "cpu" "rios1,rios2,rs64a,mpccore,ppc403,ppc405,ppc440,ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,ppc750,ppc7400,ppc7450,ppc8540,power4,power5"
11090075Sobrien  (const (symbol_ref "rs6000_cpu_attr")))
11190075Sobrien
112132718Skan(automata_option "ndfa")
11390075Sobrien
114132718Skan(include "rios1.md")
115132718Skan(include "rios2.md")
116132718Skan(include "rs64.md")
117132718Skan(include "mpc.md")
118132718Skan(include "40x.md")
119132718Skan(include "440.md")
120132718Skan(include "603.md")
121132718Skan(include "6xx.md")
122132718Skan(include "7xx.md")
123132718Skan(include "7450.md")
124132718Skan(include "8540.md")
125132718Skan(include "power4.md")
126132718Skan(include "power5.md")
12790075Sobrien
128169689Skan(include "predicates.md")
129169689Skan(include "constraints.md")
130169689Skan
131169689Skan(include "darwin.md")
132169689Skan
13390075Sobrien
134169689Skan;; Mode macros
135169689Skan
136169689Skan; This mode macro allows :GPR to be used to indicate the allowable size
137169689Skan; of whole values in GPRs.
138169689Skan(define_mode_macro GPR [SI (DI "TARGET_POWERPC64")])
139169689Skan
140169689Skan; Any supported integer mode.
141169689Skan(define_mode_macro INT [QI HI SI DI TI])
142169689Skan
143169689Skan; Any supported integer mode that fits in one register.
144169689Skan(define_mode_macro INT1 [QI HI SI (DI "TARGET_POWERPC64")])
145169689Skan
146169689Skan; extend modes for DImode
147169689Skan(define_mode_macro QHSI [QI HI SI])
148169689Skan
149169689Skan; SImode or DImode, even if DImode doesn't fit in GPRs.
150169689Skan(define_mode_macro SDI [SI DI])
151169689Skan
152169689Skan; The size of a pointer.  Also, the size of the value that a record-condition
153169689Skan; (one with a '.') will compare.
154169689Skan(define_mode_macro P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
155169689Skan
156169689Skan; Any hardware-supported floating-point mode
157169689Skan(define_mode_macro FP [(SF "TARGET_HARD_FLOAT")
158169689Skan  (DF "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)")
159169689Skan  (TF "!TARGET_IEEEQUAD
160169689Skan   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128")])
161169689Skan
162169689Skan; Various instructions that come in SI and DI forms.
163169689Skan; A generic w/d attribute, for things like cmpw/cmpd.
164169689Skan(define_mode_attr wd [(QI "b") (HI "h") (SI "w") (DI "d")])
165169689Skan
166169689Skan; DImode bits
167169689Skan(define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
168169689Skan
169169689Skan
17090075Sobrien;; Start with fixed-point load and store insns.  Here we put only the more
17190075Sobrien;; complex forms.  Basic data transfer is done later.
17290075Sobrien
173169689Skan(define_expand "zero_extend<mode>di2"
17490075Sobrien  [(set (match_operand:DI 0 "gpc_reg_operand" "")
175169689Skan	(zero_extend:DI (match_operand:QHSI 1 "gpc_reg_operand" "")))]
17690075Sobrien  "TARGET_POWERPC64"
17790075Sobrien  "")
17890075Sobrien
179169689Skan(define_insn "*zero_extend<mode>di2_internal1"
18090075Sobrien  [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
181169689Skan	(zero_extend:DI (match_operand:QHSI 1 "reg_or_mem_operand" "m,r")))]
18290075Sobrien  "TARGET_POWERPC64"
18390075Sobrien  "@
184169689Skan   l<wd>z%U1%X1 %0,%1
185169689Skan   rldicl %0,%1,0,<dbits>"
18690075Sobrien  [(set_attr "type" "load,*")])
18790075Sobrien
188169689Skan(define_insn "*zero_extend<mode>di2_internal2"
18990075Sobrien  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
190169689Skan	(compare:CC (zero_extend:DI (match_operand:QHSI 1 "gpc_reg_operand" "r,r"))
19190075Sobrien		    (const_int 0)))
19290075Sobrien   (clobber (match_scratch:DI 2 "=r,r"))]
193132718Skan  "TARGET_64BIT"
19490075Sobrien  "@
195169689Skan   rldicl. %2,%1,0,<dbits>
19690075Sobrien   #"
19790075Sobrien  [(set_attr "type" "compare")
19890075Sobrien   (set_attr "length" "4,8")])
19990075Sobrien
20090075Sobrien(define_split
20190075Sobrien  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
202169689Skan	(compare:CC (zero_extend:DI (match_operand:QHSI 1 "gpc_reg_operand" ""))
20390075Sobrien		    (const_int 0)))
20490075Sobrien   (clobber (match_scratch:DI 2 ""))]
20590075Sobrien  "TARGET_POWERPC64 && reload_completed"
20690075Sobrien  [(set (match_dup 2)
20790075Sobrien	(zero_extend:DI (match_dup 1)))
20890075Sobrien   (set (match_dup 0)
20990075Sobrien	(compare:CC (match_dup 2)
21090075Sobrien		    (const_int 0)))]
21190075Sobrien  "")
21290075Sobrien
213169689Skan(define_insn "*zero_extend<mode>di2_internal3"
21490075Sobrien  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
215169689Skan	(compare:CC (zero_extend:DI (match_operand:QHSI 1 "gpc_reg_operand" "r,r"))
21690075Sobrien		    (const_int 0)))
21790075Sobrien   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
21890075Sobrien	(zero_extend:DI (match_dup 1)))]
219132718Skan  "TARGET_64BIT"
22090075Sobrien  "@
221169689Skan   rldicl. %0,%1,0,<dbits>
22290075Sobrien   #"
22390075Sobrien  [(set_attr "type" "compare")
22490075Sobrien   (set_attr "length" "4,8")])
22590075Sobrien
22690075Sobrien(define_split
22790075Sobrien  [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "")
228169689Skan	(compare:CC (zero_extend:DI (match_operand:QHSI 1 "gpc_reg_operand" ""))
22990075Sobrien		    (const_int 0)))
23090075Sobrien   (set (match_operand:DI 0 "gpc_reg_operand" "")
23190075Sobrien	(zero_extend:DI (match_dup 1)))]
23290075Sobrien  "TARGET_POWERPC64 && reload_completed"
23390075Sobrien  [(set (match_dup 0)
23490075Sobrien	(zero_extend:DI (match_dup 1)))
23590075Sobrien   (set (match_dup 2)
23690075Sobrien	(compare:CC (match_dup 0)
23790075Sobrien		    (const_int 0)))]
23890075Sobrien  "")
23990075Sobrien
24090075Sobrien(define_insn "extendqidi2"
24190075Sobrien  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
24290075Sobrien	(sign_extend:DI (match_operand:QI 1 "gpc_reg_operand" "r")))]
24390075Sobrien  "TARGET_POWERPC64"
24490075Sobrien  "extsb %0,%1")
24590075Sobrien
24690075Sobrien(define_insn ""
24790075Sobrien  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
24890075Sobrien	(compare:CC (sign_extend:DI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
24990075Sobrien		    (const_int 0)))
25090075Sobrien   (clobber (match_scratch:DI 2 "=r,r"))]
251132718Skan  "TARGET_64BIT"
25290075Sobrien  "@
25390075Sobrien   extsb. %2,%1
25490075Sobrien   #"
25590075Sobrien  [(set_attr "type" "compare")
25690075Sobrien   (set_attr "length" "4,8")])
25790075Sobrien
25890075Sobrien(define_split
25990075Sobrien  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
26090075Sobrien	(compare:CC (sign_extend:DI (match_operand:QI 1 "gpc_reg_operand" ""))
26190075Sobrien		    (const_int 0)))
26290075Sobrien   (clobber (match_scratch:DI 2 ""))]
26390075Sobrien  "TARGET_POWERPC64 && reload_completed"
26490075Sobrien  [(set (match_dup 2)
26590075Sobrien	(sign_extend:DI (match_dup 1)))
26690075Sobrien   (set (match_dup 0)
26790075Sobrien	(compare:CC (match_dup 2)
26890075Sobrien		    (const_int 0)))]
26990075Sobrien  "")
27090075Sobrien
27190075Sobrien(define_insn ""
27290075Sobrien  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
27390075Sobrien	(compare:CC (sign_extend:DI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
27490075Sobrien		    (const_int 0)))
27590075Sobrien   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
27690075Sobrien	(sign_extend:DI (match_dup 1)))]
277132718Skan  "TARGET_64BIT"
27890075Sobrien  "@
27990075Sobrien   extsb. %0,%1
28090075Sobrien   #"
28190075Sobrien  [(set_attr "type" "compare")
28290075Sobrien   (set_attr "length" "4,8")])
28390075Sobrien
28490075Sobrien(define_split
28590075Sobrien  [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "")
28690075Sobrien	(compare:CC (sign_extend:DI (match_operand:QI 1 "gpc_reg_operand" ""))
28790075Sobrien		    (const_int 0)))
28890075Sobrien   (set (match_operand:DI 0 "gpc_reg_operand" "")
28990075Sobrien	(sign_extend:DI (match_dup 1)))]
29090075Sobrien  "TARGET_POWERPC64 && reload_completed"
29190075Sobrien  [(set (match_dup 0)
29290075Sobrien	(sign_extend:DI (match_dup 1)))
29390075Sobrien   (set (match_dup 2)
29490075Sobrien	(compare:CC (match_dup 0)
29590075Sobrien		    (const_int 0)))]
29690075Sobrien  "")
29790075Sobrien
29890075Sobrien(define_expand "extendhidi2"
29990075Sobrien  [(set (match_operand:DI 0 "gpc_reg_operand" "")
30090075Sobrien	(sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" "")))]
30190075Sobrien  "TARGET_POWERPC64"
30290075Sobrien  "")
30390075Sobrien
30490075Sobrien(define_insn ""
30590075Sobrien  [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
30690075Sobrien	(sign_extend:DI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
30790075Sobrien  "TARGET_POWERPC64"
30890075Sobrien  "@
30990075Sobrien   lha%U1%X1 %0,%1
31090075Sobrien   extsh %0,%1"
311132718Skan  [(set_attr "type" "load_ext,*")])
31290075Sobrien
31390075Sobrien(define_insn ""
31490075Sobrien  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
31590075Sobrien	(compare:CC (sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
31690075Sobrien		    (const_int 0)))
31790075Sobrien   (clobber (match_scratch:DI 2 "=r,r"))]
318132718Skan  "TARGET_64BIT"
31990075Sobrien  "@
32090075Sobrien   extsh. %2,%1
32190075Sobrien   #"
32290075Sobrien  [(set_attr "type" "compare")
32390075Sobrien   (set_attr "length" "4,8")])
32490075Sobrien
32590075Sobrien(define_split
32690075Sobrien  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
32790075Sobrien	(compare:CC (sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" ""))
32890075Sobrien		    (const_int 0)))
32990075Sobrien   (clobber (match_scratch:DI 2 ""))]
33090075Sobrien  "TARGET_POWERPC64 && reload_completed"
33190075Sobrien  [(set (match_dup 2)
33290075Sobrien	(sign_extend:DI (match_dup 1)))
33390075Sobrien   (set (match_dup 0)
33490075Sobrien	(compare:CC (match_dup 2)
33590075Sobrien		    (const_int 0)))]
33690075Sobrien  "")
33790075Sobrien
33890075Sobrien(define_insn ""
33990075Sobrien  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
34090075Sobrien	(compare:CC (sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
34190075Sobrien		    (const_int 0)))
34290075Sobrien   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
34390075Sobrien	(sign_extend:DI (match_dup 1)))]
344132718Skan  "TARGET_64BIT"
34590075Sobrien  "@
34690075Sobrien   extsh. %0,%1
34790075Sobrien   #"
34890075Sobrien  [(set_attr "type" "compare")
34990075Sobrien   (set_attr "length" "4,8")])
35090075Sobrien
35190075Sobrien(define_split
35290075Sobrien  [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "")
35390075Sobrien	(compare:CC (sign_extend:DI (match_operand:HI 1 "gpc_reg_operand" ""))
35490075Sobrien		    (const_int 0)))
35590075Sobrien   (set (match_operand:DI 0 "gpc_reg_operand" "")
35690075Sobrien	(sign_extend:DI (match_dup 1)))]
35790075Sobrien  "TARGET_POWERPC64 && reload_completed"
35890075Sobrien  [(set (match_dup 0)
35990075Sobrien	(sign_extend:DI (match_dup 1)))
36090075Sobrien   (set (match_dup 2)
36190075Sobrien	(compare:CC (match_dup 0)
36290075Sobrien		    (const_int 0)))]
36390075Sobrien  "")
36490075Sobrien
36590075Sobrien(define_expand "extendsidi2"
36690075Sobrien  [(set (match_operand:DI 0 "gpc_reg_operand" "")
36790075Sobrien	(sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "")))]
36890075Sobrien  "TARGET_POWERPC64"
36990075Sobrien  "")
37090075Sobrien
37190075Sobrien(define_insn ""
37290075Sobrien  [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
37390075Sobrien	(sign_extend:DI (match_operand:SI 1 "lwa_operand" "m,r")))]
37490075Sobrien  "TARGET_POWERPC64"
37590075Sobrien  "@
37690075Sobrien   lwa%U1%X1 %0,%1
37790075Sobrien   extsw %0,%1"
378132718Skan  [(set_attr "type" "load_ext,*")])
37990075Sobrien
38090075Sobrien(define_insn ""
38190075Sobrien  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
38290075Sobrien	(compare:CC (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
38390075Sobrien		    (const_int 0)))
38490075Sobrien   (clobber (match_scratch:DI 2 "=r,r"))]
385132718Skan  "TARGET_64BIT"
38690075Sobrien  "@
38790075Sobrien   extsw. %2,%1
38890075Sobrien   #"
38990075Sobrien  [(set_attr "type" "compare")
39090075Sobrien   (set_attr "length" "4,8")])
39190075Sobrien
39290075Sobrien(define_split
39390075Sobrien  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
39490075Sobrien	(compare:CC (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" ""))
39590075Sobrien		    (const_int 0)))
39690075Sobrien   (clobber (match_scratch:DI 2 ""))]
39790075Sobrien  "TARGET_POWERPC64 && reload_completed"
39890075Sobrien  [(set (match_dup 2)
39990075Sobrien	(sign_extend:DI (match_dup 1)))
40090075Sobrien   (set (match_dup 0)
40190075Sobrien	(compare:CC (match_dup 2)
40290075Sobrien		    (const_int 0)))]
40390075Sobrien  "")
40490075Sobrien
40590075Sobrien(define_insn ""
40690075Sobrien  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
40790075Sobrien	(compare:CC (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
40890075Sobrien		    (const_int 0)))
40990075Sobrien   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
41090075Sobrien	(sign_extend:DI (match_dup 1)))]
411132718Skan  "TARGET_64BIT"
41290075Sobrien  "@
41390075Sobrien   extsw. %0,%1
41490075Sobrien   #"
41590075Sobrien  [(set_attr "type" "compare")
41690075Sobrien   (set_attr "length" "4,8")])
41790075Sobrien
41890075Sobrien(define_split
41990075Sobrien  [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "")
42090075Sobrien	(compare:CC (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" ""))
42190075Sobrien		    (const_int 0)))
42290075Sobrien   (set (match_operand:DI 0 "gpc_reg_operand" "")
42390075Sobrien	(sign_extend:DI (match_dup 1)))]
42490075Sobrien  "TARGET_POWERPC64 && reload_completed"
42590075Sobrien  [(set (match_dup 0)
42690075Sobrien	(sign_extend:DI (match_dup 1)))
42790075Sobrien   (set (match_dup 2)
42890075Sobrien	(compare:CC (match_dup 0)
42990075Sobrien		    (const_int 0)))]
43090075Sobrien  "")
43190075Sobrien
43290075Sobrien(define_expand "zero_extendqisi2"
43390075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "")
43490075Sobrien	(zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" "")))]
43590075Sobrien  ""
43690075Sobrien  "")
43790075Sobrien
43890075Sobrien(define_insn ""
43990075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
44090075Sobrien	(zero_extend:SI (match_operand:QI 1 "reg_or_mem_operand" "m,r")))]
44190075Sobrien  ""
44290075Sobrien  "@
44390075Sobrien   lbz%U1%X1 %0,%1
44490075Sobrien   {rlinm|rlwinm} %0,%1,0,0xff"
44590075Sobrien  [(set_attr "type" "load,*")])
44690075Sobrien
44790075Sobrien(define_insn ""
44890075Sobrien  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
44990075Sobrien	(compare:CC (zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
45090075Sobrien		    (const_int 0)))
45190075Sobrien   (clobber (match_scratch:SI 2 "=r,r"))]
45290075Sobrien  ""
45390075Sobrien  "@
45490075Sobrien   {andil.|andi.} %2,%1,0xff
45590075Sobrien   #"
45690075Sobrien  [(set_attr "type" "compare")
45790075Sobrien   (set_attr "length" "4,8")])
45890075Sobrien
45990075Sobrien(define_split
46090075Sobrien  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
46190075Sobrien	(compare:CC (zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" ""))
46290075Sobrien		    (const_int 0)))
46390075Sobrien   (clobber (match_scratch:SI 2 ""))]
46490075Sobrien  "reload_completed"
46590075Sobrien  [(set (match_dup 2)
46690075Sobrien	(zero_extend:SI (match_dup 1)))
46790075Sobrien   (set (match_dup 0)
46890075Sobrien	(compare:CC (match_dup 2)
46990075Sobrien		    (const_int 0)))]
47090075Sobrien  "")
47190075Sobrien
47290075Sobrien(define_insn ""
47390075Sobrien  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
47490075Sobrien	(compare:CC (zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
47590075Sobrien		    (const_int 0)))
47690075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
47790075Sobrien	(zero_extend:SI (match_dup 1)))]
47890075Sobrien  ""
47990075Sobrien  "@
48090075Sobrien   {andil.|andi.} %0,%1,0xff
48190075Sobrien   #"
48290075Sobrien  [(set_attr "type" "compare")
48390075Sobrien   (set_attr "length" "4,8")])
48490075Sobrien
48590075Sobrien(define_split
48690075Sobrien  [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "")
48790075Sobrien	(compare:CC (zero_extend:SI (match_operand:QI 1 "gpc_reg_operand" ""))
48890075Sobrien		    (const_int 0)))
48990075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "")
49090075Sobrien	(zero_extend:SI (match_dup 1)))]
49190075Sobrien  "reload_completed"
49290075Sobrien  [(set (match_dup 0)
49390075Sobrien	(zero_extend:SI (match_dup 1)))
49490075Sobrien   (set (match_dup 2)
49590075Sobrien	(compare:CC (match_dup 0)
49690075Sobrien		    (const_int 0)))]
49790075Sobrien  "")
49890075Sobrien
49990075Sobrien(define_expand "extendqisi2"
50090075Sobrien  [(use (match_operand:SI 0 "gpc_reg_operand" ""))
50190075Sobrien   (use (match_operand:QI 1 "gpc_reg_operand" ""))]
50290075Sobrien  ""
50390075Sobrien  "
50490075Sobrien{
50590075Sobrien  if (TARGET_POWERPC)
50690075Sobrien    emit_insn (gen_extendqisi2_ppc (operands[0], operands[1]));
50790075Sobrien  else if (TARGET_POWER)
50890075Sobrien    emit_insn (gen_extendqisi2_power (operands[0], operands[1]));
50990075Sobrien  else
51090075Sobrien    emit_insn (gen_extendqisi2_no_power (operands[0], operands[1]));
51190075Sobrien  DONE;
51290075Sobrien}")
51390075Sobrien
51490075Sobrien(define_insn "extendqisi2_ppc"
51590075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
51690075Sobrien	(sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r")))]
51790075Sobrien  "TARGET_POWERPC"
51890075Sobrien  "extsb %0,%1")
51990075Sobrien
52090075Sobrien(define_insn ""
52190075Sobrien  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
52290075Sobrien	(compare:CC (sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
52390075Sobrien		    (const_int 0)))
52490075Sobrien   (clobber (match_scratch:SI 2 "=r,r"))]
52590075Sobrien  "TARGET_POWERPC"
52690075Sobrien  "@
52790075Sobrien   extsb. %2,%1
52890075Sobrien   #"
52990075Sobrien  [(set_attr "type" "compare")
53090075Sobrien   (set_attr "length" "4,8")])
53190075Sobrien
53290075Sobrien(define_split
53390075Sobrien  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
53490075Sobrien	(compare:CC (sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" ""))
53590075Sobrien		    (const_int 0)))
53690075Sobrien   (clobber (match_scratch:SI 2 ""))]
53790075Sobrien  "TARGET_POWERPC && reload_completed"
53890075Sobrien  [(set (match_dup 2)
53990075Sobrien	(sign_extend:SI (match_dup 1)))
54090075Sobrien   (set (match_dup 0)
54190075Sobrien	(compare:CC (match_dup 2)
54290075Sobrien		    (const_int 0)))]
54390075Sobrien  "")
54490075Sobrien
54590075Sobrien(define_insn ""
54690075Sobrien  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
54790075Sobrien	(compare:CC (sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
54890075Sobrien		    (const_int 0)))
54990075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
55090075Sobrien	(sign_extend:SI (match_dup 1)))]
55190075Sobrien  "TARGET_POWERPC"
55290075Sobrien  "@
55390075Sobrien   extsb. %0,%1
55490075Sobrien   #"
55590075Sobrien  [(set_attr "type" "compare")
55690075Sobrien   (set_attr "length" "4,8")])
55790075Sobrien
55890075Sobrien(define_split
55990075Sobrien  [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "")
56090075Sobrien	(compare:CC (sign_extend:SI (match_operand:QI 1 "gpc_reg_operand" ""))
56190075Sobrien		    (const_int 0)))
56290075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "")
56390075Sobrien	(sign_extend:SI (match_dup 1)))]
56490075Sobrien  "TARGET_POWERPC && reload_completed"
56590075Sobrien  [(set (match_dup 0)
56690075Sobrien	(sign_extend:SI (match_dup 1)))
56790075Sobrien   (set (match_dup 2)
56890075Sobrien	(compare:CC (match_dup 0)
56990075Sobrien		    (const_int 0)))]
57090075Sobrien  "")
57190075Sobrien
57290075Sobrien(define_expand "extendqisi2_power"
57390075Sobrien  [(parallel [(set (match_dup 2)
57490075Sobrien		   (ashift:SI (match_operand:QI 1 "gpc_reg_operand" "")
57590075Sobrien			      (const_int 24)))
57690075Sobrien	      (clobber (scratch:SI))])
57790075Sobrien   (parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
57890075Sobrien		   (ashiftrt:SI (match_dup 2)
57990075Sobrien				(const_int 24)))
58090075Sobrien	      (clobber (scratch:SI))])]
58190075Sobrien  "TARGET_POWER"
58290075Sobrien  "
58390075Sobrien{ operands[1] = gen_lowpart (SImode, operands[1]);
58490075Sobrien  operands[2] = gen_reg_rtx (SImode); }")
58590075Sobrien
58690075Sobrien(define_expand "extendqisi2_no_power"
58790075Sobrien  [(set (match_dup 2)
58890075Sobrien	(ashift:SI (match_operand:QI 1 "gpc_reg_operand" "")
58990075Sobrien		   (const_int 24)))
59090075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "")
59190075Sobrien	(ashiftrt:SI (match_dup 2)
59290075Sobrien		     (const_int 24)))]
59390075Sobrien  "! TARGET_POWER && ! TARGET_POWERPC"
59490075Sobrien  "
59590075Sobrien{ operands[1] = gen_lowpart (SImode, operands[1]);
59690075Sobrien  operands[2] = gen_reg_rtx (SImode); }")
59790075Sobrien
59890075Sobrien(define_expand "zero_extendqihi2"
59990075Sobrien  [(set (match_operand:HI 0 "gpc_reg_operand" "")
60090075Sobrien	(zero_extend:HI (match_operand:QI 1 "gpc_reg_operand" "")))]
60190075Sobrien  ""
60290075Sobrien  "")
60390075Sobrien
60490075Sobrien(define_insn ""
60590075Sobrien  [(set (match_operand:HI 0 "gpc_reg_operand" "=r,r")
60690075Sobrien	(zero_extend:HI (match_operand:QI 1 "reg_or_mem_operand" "m,r")))]
60790075Sobrien  ""
60890075Sobrien  "@
60990075Sobrien   lbz%U1%X1 %0,%1
61090075Sobrien   {rlinm|rlwinm} %0,%1,0,0xff"
61190075Sobrien  [(set_attr "type" "load,*")])
61290075Sobrien
61390075Sobrien(define_insn ""
61490075Sobrien  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
61590075Sobrien	(compare:CC (zero_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
61690075Sobrien		    (const_int 0)))
61790075Sobrien   (clobber (match_scratch:HI 2 "=r,r"))]
61890075Sobrien  ""
61990075Sobrien  "@
62090075Sobrien   {andil.|andi.} %2,%1,0xff
62190075Sobrien   #"
62290075Sobrien  [(set_attr "type" "compare")
62390075Sobrien   (set_attr "length" "4,8")])
62490075Sobrien
62590075Sobrien(define_split
62690075Sobrien  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
62790075Sobrien	(compare:CC (zero_extend:HI (match_operand:QI 1 "gpc_reg_operand" ""))
62890075Sobrien		    (const_int 0)))
62990075Sobrien   (clobber (match_scratch:HI 2 ""))]
63090075Sobrien  "reload_completed"
63190075Sobrien  [(set (match_dup 2)
63290075Sobrien	(zero_extend:HI (match_dup 1)))
63390075Sobrien   (set (match_dup 0)
63490075Sobrien	(compare:CC (match_dup 2)
63590075Sobrien		    (const_int 0)))]
63690075Sobrien  "")
63790075Sobrien
63890075Sobrien(define_insn ""
63990075Sobrien  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
64090075Sobrien	(compare:CC (zero_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
64190075Sobrien		    (const_int 0)))
64290075Sobrien   (set (match_operand:HI 0 "gpc_reg_operand" "=r,r")
64390075Sobrien	(zero_extend:HI (match_dup 1)))]
64490075Sobrien  ""
64590075Sobrien  "@
64690075Sobrien   {andil.|andi.} %0,%1,0xff
64790075Sobrien   #"
64890075Sobrien  [(set_attr "type" "compare")
64990075Sobrien   (set_attr "length" "4,8")])
65090075Sobrien
65190075Sobrien(define_split
65290075Sobrien  [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "")
65390075Sobrien	(compare:CC (zero_extend:HI (match_operand:QI 1 "gpc_reg_operand" ""))
65490075Sobrien		    (const_int 0)))
65590075Sobrien   (set (match_operand:HI 0 "gpc_reg_operand" "")
65690075Sobrien	(zero_extend:HI (match_dup 1)))]
65790075Sobrien  "reload_completed"
65890075Sobrien  [(set (match_dup 0)
65990075Sobrien	(zero_extend:HI (match_dup 1)))
66090075Sobrien   (set (match_dup 2)
66190075Sobrien	(compare:CC (match_dup 0)
66290075Sobrien		    (const_int 0)))]
66390075Sobrien  "")
66490075Sobrien
66590075Sobrien(define_expand "extendqihi2"
66690075Sobrien  [(use (match_operand:HI 0 "gpc_reg_operand" ""))
66790075Sobrien   (use (match_operand:QI 1 "gpc_reg_operand" ""))]
66890075Sobrien  ""
66990075Sobrien  "
67090075Sobrien{
67190075Sobrien  if (TARGET_POWERPC)
67290075Sobrien    emit_insn (gen_extendqihi2_ppc (operands[0], operands[1]));
67390075Sobrien  else if (TARGET_POWER)
67490075Sobrien    emit_insn (gen_extendqihi2_power (operands[0], operands[1]));
67590075Sobrien  else
67690075Sobrien    emit_insn (gen_extendqihi2_no_power (operands[0], operands[1]));
67790075Sobrien  DONE;
67890075Sobrien}")
67990075Sobrien
68090075Sobrien(define_insn "extendqihi2_ppc"
68190075Sobrien  [(set (match_operand:HI 0 "gpc_reg_operand" "=r")
68290075Sobrien	(sign_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r")))]
68390075Sobrien  "TARGET_POWERPC"
68490075Sobrien  "extsb %0,%1")
68590075Sobrien
68690075Sobrien(define_insn ""
68790075Sobrien  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
68890075Sobrien	(compare:CC (sign_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
68990075Sobrien		    (const_int 0)))
69090075Sobrien   (clobber (match_scratch:HI 2 "=r,r"))]
69190075Sobrien  "TARGET_POWERPC"
69290075Sobrien  "@
69390075Sobrien   extsb. %2,%1
69490075Sobrien   #"
69590075Sobrien  [(set_attr "type" "compare")
69690075Sobrien   (set_attr "length" "4,8")])
69790075Sobrien
69890075Sobrien(define_split
69990075Sobrien  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
70090075Sobrien	(compare:CC (sign_extend:HI (match_operand:QI 1 "gpc_reg_operand" ""))
70190075Sobrien		    (const_int 0)))
70290075Sobrien   (clobber (match_scratch:HI 2 ""))]
70390075Sobrien  "TARGET_POWERPC && reload_completed"
70490075Sobrien  [(set (match_dup 2)
70590075Sobrien	(sign_extend:HI (match_dup 1)))
70690075Sobrien   (set (match_dup 0)
70790075Sobrien	(compare:CC (match_dup 2)
70890075Sobrien		    (const_int 0)))]
70990075Sobrien  "")
71090075Sobrien
71190075Sobrien(define_insn ""
71290075Sobrien  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
71390075Sobrien	(compare:CC (sign_extend:HI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
71490075Sobrien		    (const_int 0)))
71590075Sobrien   (set (match_operand:HI 0 "gpc_reg_operand" "=r,r")
71690075Sobrien	(sign_extend:HI (match_dup 1)))]
71790075Sobrien  "TARGET_POWERPC"
71890075Sobrien  "@
71990075Sobrien   extsb. %0,%1
72090075Sobrien   #"
72190075Sobrien  [(set_attr "type" "compare")
72290075Sobrien   (set_attr "length" "4,8")])
72390075Sobrien
72490075Sobrien(define_split
72590075Sobrien  [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "")
72690075Sobrien	(compare:CC (sign_extend:HI (match_operand:QI 1 "gpc_reg_operand" ""))
72790075Sobrien		    (const_int 0)))
72890075Sobrien   (set (match_operand:HI 0 "gpc_reg_operand" "")
72990075Sobrien	(sign_extend:HI (match_dup 1)))]
73090075Sobrien  "TARGET_POWERPC && reload_completed"
73190075Sobrien  [(set (match_dup 0)
73290075Sobrien	(sign_extend:HI (match_dup 1)))
73390075Sobrien   (set (match_dup 2)
73490075Sobrien	(compare:CC (match_dup 0)
73590075Sobrien		    (const_int 0)))]
73690075Sobrien  "")
73790075Sobrien
73890075Sobrien(define_expand "extendqihi2_power"
73990075Sobrien  [(parallel [(set (match_dup 2)
74090075Sobrien		   (ashift:SI (match_operand:QI 1 "gpc_reg_operand" "")
74190075Sobrien			      (const_int 24)))
74290075Sobrien	      (clobber (scratch:SI))])
74390075Sobrien   (parallel [(set (match_operand:HI 0 "gpc_reg_operand" "")
74490075Sobrien		   (ashiftrt:SI (match_dup 2)
74590075Sobrien				(const_int 24)))
74690075Sobrien	      (clobber (scratch:SI))])]
74790075Sobrien  "TARGET_POWER"
74890075Sobrien  "
74990075Sobrien{ operands[0] = gen_lowpart (SImode, operands[0]);
75090075Sobrien  operands[1] = gen_lowpart (SImode, operands[1]);
75190075Sobrien  operands[2] = gen_reg_rtx (SImode); }")
75290075Sobrien
75390075Sobrien(define_expand "extendqihi2_no_power"
75490075Sobrien  [(set (match_dup 2)
75590075Sobrien	(ashift:SI (match_operand:QI 1 "gpc_reg_operand" "")
75690075Sobrien		   (const_int 24)))
75790075Sobrien   (set (match_operand:HI 0 "gpc_reg_operand" "")
75890075Sobrien	(ashiftrt:SI (match_dup 2)
75990075Sobrien		     (const_int 24)))]
76090075Sobrien  "! TARGET_POWER && ! TARGET_POWERPC"
76190075Sobrien  "
76290075Sobrien{ operands[0] = gen_lowpart (SImode, operands[0]);
76390075Sobrien  operands[1] = gen_lowpart (SImode, operands[1]);
76490075Sobrien  operands[2] = gen_reg_rtx (SImode); }")
76590075Sobrien
76690075Sobrien(define_expand "zero_extendhisi2"
76790075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "")
76890075Sobrien	(zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" "")))]
76990075Sobrien  ""
77090075Sobrien  "")
77190075Sobrien
77290075Sobrien(define_insn ""
77390075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
77490075Sobrien	(zero_extend:SI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
77590075Sobrien  ""
77690075Sobrien  "@
77790075Sobrien   lhz%U1%X1 %0,%1
77890075Sobrien   {rlinm|rlwinm} %0,%1,0,0xffff"
77990075Sobrien  [(set_attr "type" "load,*")])
78090075Sobrien
78190075Sobrien(define_insn ""
78290075Sobrien  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
78390075Sobrien	(compare:CC (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
78490075Sobrien		    (const_int 0)))
78590075Sobrien   (clobber (match_scratch:SI 2 "=r,r"))]
78690075Sobrien  ""
78790075Sobrien  "@
78890075Sobrien   {andil.|andi.} %2,%1,0xffff
78990075Sobrien   #"
79090075Sobrien  [(set_attr "type" "compare")
79190075Sobrien   (set_attr "length" "4,8")])
79290075Sobrien
79390075Sobrien(define_split
79490075Sobrien  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
79590075Sobrien	(compare:CC (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" ""))
79690075Sobrien		    (const_int 0)))
79790075Sobrien   (clobber (match_scratch:SI 2 ""))]
79890075Sobrien  "reload_completed"
79990075Sobrien  [(set (match_dup 2)
80090075Sobrien	(zero_extend:SI (match_dup 1)))
80190075Sobrien   (set (match_dup 0)
80290075Sobrien	(compare:CC (match_dup 2)
80390075Sobrien		    (const_int 0)))]
80490075Sobrien  "")
80590075Sobrien
80690075Sobrien(define_insn ""
80790075Sobrien  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
80890075Sobrien	(compare:CC (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
80990075Sobrien		    (const_int 0)))
81090075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
81190075Sobrien	(zero_extend:SI (match_dup 1)))]
81290075Sobrien  ""
81390075Sobrien  "@
81490075Sobrien   {andil.|andi.} %0,%1,0xffff
81590075Sobrien   #"
81690075Sobrien  [(set_attr "type" "compare")
81790075Sobrien   (set_attr "length" "4,8")])
81890075Sobrien
81990075Sobrien(define_split
82090075Sobrien  [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "")
82190075Sobrien	(compare:CC (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" ""))
82290075Sobrien		    (const_int 0)))
82390075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "")
82490075Sobrien	(zero_extend:SI (match_dup 1)))]
82590075Sobrien  "reload_completed"
82690075Sobrien  [(set (match_dup 0)
82790075Sobrien	(zero_extend:SI (match_dup 1)))
82890075Sobrien   (set (match_dup 2)
82990075Sobrien	(compare:CC (match_dup 0)
83090075Sobrien		    (const_int 0)))]
83190075Sobrien  "")
83290075Sobrien
83390075Sobrien(define_expand "extendhisi2"
83490075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "")
83590075Sobrien	(sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" "")))]
83690075Sobrien  ""
83790075Sobrien  "")
83890075Sobrien
83990075Sobrien(define_insn ""
84090075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
84190075Sobrien	(sign_extend:SI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))]
84290075Sobrien  ""
84390075Sobrien  "@
84490075Sobrien   lha%U1%X1 %0,%1
84590075Sobrien   {exts|extsh} %0,%1"
846132718Skan  [(set_attr "type" "load_ext,*")])
84790075Sobrien
84890075Sobrien(define_insn ""
84990075Sobrien  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
85090075Sobrien	(compare:CC (sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
85190075Sobrien		    (const_int 0)))
85290075Sobrien   (clobber (match_scratch:SI 2 "=r,r"))]
85390075Sobrien  ""
85490075Sobrien  "@
85590075Sobrien   {exts.|extsh.} %2,%1
85690075Sobrien   #"
85790075Sobrien  [(set_attr "type" "compare")
85890075Sobrien   (set_attr "length" "4,8")])
85990075Sobrien
86090075Sobrien(define_split
86190075Sobrien  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
86290075Sobrien	(compare:CC (sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" ""))
86390075Sobrien		    (const_int 0)))
86490075Sobrien   (clobber (match_scratch:SI 2 ""))]
86590075Sobrien  "reload_completed"
86690075Sobrien  [(set (match_dup 2)
86790075Sobrien	(sign_extend:SI (match_dup 1)))
86890075Sobrien   (set (match_dup 0)
86990075Sobrien	(compare:CC (match_dup 2)
87090075Sobrien		    (const_int 0)))]
87190075Sobrien  "")
87290075Sobrien
87390075Sobrien(define_insn ""
87490075Sobrien  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
87590075Sobrien	(compare:CC (sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
87690075Sobrien		    (const_int 0)))
87790075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
87890075Sobrien	(sign_extend:SI (match_dup 1)))]
87990075Sobrien  ""
88090075Sobrien  "@
88190075Sobrien   {exts.|extsh.} %0,%1
88290075Sobrien   #"
88390075Sobrien  [(set_attr "type" "compare")
88490075Sobrien   (set_attr "length" "4,8")])
88590075Sobrien
886169689Skan;; IBM 405 and 440 half-word multiplication operations.
887169689Skan
888169689Skan(define_insn "*macchwc"
889169689Skan  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
890169689Skan        (compare:CC (plus:SI (mult:SI (ashiftrt:SI
891169689Skan                                       (match_operand:SI 2 "gpc_reg_operand" "r")
892169689Skan                                       (const_int 16))
893169689Skan                                      (sign_extend:SI
894169689Skan                                       (match_operand:HI 1 "gpc_reg_operand" "r")))
895169689Skan                             (match_operand:SI 4 "gpc_reg_operand" "0"))
896169689Skan                    (const_int 0)))
897169689Skan   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
898169689Skan        (plus:SI (mult:SI (ashiftrt:SI
899169689Skan                           (match_dup 2)
900169689Skan                           (const_int 16))
901169689Skan                          (sign_extend:SI
902169689Skan                           (match_dup 1)))
903169689Skan                 (match_dup 4)))]
904169689Skan  "TARGET_MULHW"
905169689Skan  "macchw. %0, %1, %2"
906169689Skan  [(set_attr "type" "imul3")])
907169689Skan
908169689Skan(define_insn "*macchw"
909169689Skan  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
910169689Skan        (plus:SI (mult:SI (ashiftrt:SI
911169689Skan                           (match_operand:SI 2 "gpc_reg_operand" "r")
912169689Skan                           (const_int 16))
913169689Skan                          (sign_extend:SI
914169689Skan                           (match_operand:HI 1 "gpc_reg_operand" "r")))
915169689Skan                 (match_operand:SI 3 "gpc_reg_operand" "0")))]
916169689Skan  "TARGET_MULHW"
917169689Skan  "macchw %0, %1, %2"
918169689Skan  [(set_attr "type" "imul3")])
919169689Skan
920169689Skan(define_insn "*macchwuc"
921169689Skan  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
922169689Skan        (compare:CC (plus:SI (mult:SI (lshiftrt:SI
923169689Skan                                       (match_operand:SI 2 "gpc_reg_operand" "r")
924169689Skan                                       (const_int 16))
925169689Skan                                      (zero_extend:SI
926169689Skan                                       (match_operand:HI 1 "gpc_reg_operand" "r")))
927169689Skan                             (match_operand:SI 4 "gpc_reg_operand" "0"))
928169689Skan                    (const_int 0)))
929169689Skan   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
930169689Skan        (plus:SI (mult:SI (lshiftrt:SI
931169689Skan                           (match_dup 2)
932169689Skan                           (const_int 16))
933169689Skan                          (zero_extend:SI
934169689Skan                           (match_dup 1)))
935169689Skan                 (match_dup 4)))]
936169689Skan  "TARGET_MULHW"
937169689Skan  "macchwu. %0, %1, %2"
938169689Skan  [(set_attr "type" "imul3")])
939169689Skan
940169689Skan(define_insn "*macchwu"
941169689Skan  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
942169689Skan        (plus:SI (mult:SI (lshiftrt:SI
943169689Skan                           (match_operand:SI 2 "gpc_reg_operand" "r")
944169689Skan                           (const_int 16))
945169689Skan                          (zero_extend:SI
946169689Skan                           (match_operand:HI 1 "gpc_reg_operand" "r")))
947169689Skan                 (match_operand:SI 3 "gpc_reg_operand" "0")))]
948169689Skan  "TARGET_MULHW"
949169689Skan  "macchwu %0, %1, %2"
950169689Skan  [(set_attr "type" "imul3")])
951169689Skan
952169689Skan(define_insn "*machhwc"
953169689Skan  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
954169689Skan        (compare:CC (plus:SI (mult:SI (ashiftrt:SI
955169689Skan                                       (match_operand:SI 1 "gpc_reg_operand" "%r")
956169689Skan                                       (const_int 16))
957169689Skan                                      (ashiftrt:SI
958169689Skan                                       (match_operand:SI 2 "gpc_reg_operand" "r")
959169689Skan                                       (const_int 16)))
960169689Skan                             (match_operand:SI 4 "gpc_reg_operand" "0"))
961169689Skan                    (const_int 0)))
962169689Skan   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
963169689Skan        (plus:SI (mult:SI (ashiftrt:SI
964169689Skan                           (match_dup 1)
965169689Skan                           (const_int 16))
966169689Skan                          (ashiftrt:SI
967169689Skan                           (match_dup 2)
968169689Skan                           (const_int 16)))
969169689Skan                 (match_dup 4)))]
970169689Skan  "TARGET_MULHW"
971169689Skan  "machhw. %0, %1, %2"
972169689Skan  [(set_attr "type" "imul3")])
973169689Skan
974169689Skan(define_insn "*machhw"
975169689Skan  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
976169689Skan        (plus:SI (mult:SI (ashiftrt:SI
977169689Skan                           (match_operand:SI 1 "gpc_reg_operand" "%r")
978169689Skan                           (const_int 16))
979169689Skan                          (ashiftrt:SI
980169689Skan                           (match_operand:SI 2 "gpc_reg_operand" "r")
981169689Skan                           (const_int 16)))
982169689Skan                 (match_operand:SI 3 "gpc_reg_operand" "0")))]
983169689Skan  "TARGET_MULHW"
984169689Skan  "machhw %0, %1, %2"
985169689Skan  [(set_attr "type" "imul3")])
986169689Skan
987169689Skan(define_insn "*machhwuc"
988169689Skan  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
989169689Skan        (compare:CC (plus:SI (mult:SI (lshiftrt:SI
990169689Skan                                       (match_operand:SI 1 "gpc_reg_operand" "%r")
991169689Skan                                       (const_int 16))
992169689Skan                                      (lshiftrt:SI
993169689Skan                                       (match_operand:SI 2 "gpc_reg_operand" "r")
994169689Skan                                       (const_int 16)))
995169689Skan                             (match_operand:SI 4 "gpc_reg_operand" "0"))
996169689Skan                    (const_int 0)))
997169689Skan   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
998169689Skan        (plus:SI (mult:SI (lshiftrt:SI
999169689Skan                           (match_dup 1)
1000169689Skan                           (const_int 16))
1001169689Skan                          (lshiftrt:SI
1002169689Skan                           (match_dup 2)
1003169689Skan                           (const_int 16)))
1004169689Skan                 (match_dup 4)))]
1005169689Skan  "TARGET_MULHW"
1006169689Skan  "machhwu. %0, %1, %2"
1007169689Skan  [(set_attr "type" "imul3")])
1008169689Skan
1009169689Skan(define_insn "*machhwu"
1010169689Skan  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1011169689Skan        (plus:SI (mult:SI (lshiftrt:SI
1012169689Skan                           (match_operand:SI 1 "gpc_reg_operand" "%r")
1013169689Skan                           (const_int 16))
1014169689Skan                          (lshiftrt:SI
1015169689Skan                           (match_operand:SI 2 "gpc_reg_operand" "r")
1016169689Skan                           (const_int 16)))
1017169689Skan                 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1018169689Skan  "TARGET_MULHW"
1019169689Skan  "machhwu %0, %1, %2"
1020169689Skan  [(set_attr "type" "imul3")])
1021169689Skan
1022169689Skan(define_insn "*maclhwc"
1023169689Skan  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1024169689Skan        (compare:CC (plus:SI (mult:SI (sign_extend:SI
1025169689Skan                                       (match_operand:HI 1 "gpc_reg_operand" "%r"))
1026169689Skan                                      (sign_extend:SI
1027169689Skan                                       (match_operand:HI 2 "gpc_reg_operand" "r")))
1028169689Skan                             (match_operand:SI 4 "gpc_reg_operand" "0"))
1029169689Skan                    (const_int 0)))
1030169689Skan   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1031169689Skan        (plus:SI (mult:SI (sign_extend:SI
1032169689Skan                           (match_dup 1))
1033169689Skan                          (sign_extend:SI
1034169689Skan                           (match_dup 2)))
1035169689Skan                 (match_dup 4)))]
1036169689Skan  "TARGET_MULHW"
1037169689Skan  "maclhw. %0, %1, %2"
1038169689Skan  [(set_attr "type" "imul3")])
1039169689Skan
1040169689Skan(define_insn "*maclhw"
1041169689Skan  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1042169689Skan        (plus:SI (mult:SI (sign_extend:SI
1043169689Skan                           (match_operand:HI 1 "gpc_reg_operand" "%r"))
1044169689Skan                          (sign_extend:SI
1045169689Skan                           (match_operand:HI 2 "gpc_reg_operand" "r")))
1046169689Skan                 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1047169689Skan  "TARGET_MULHW"
1048169689Skan  "maclhw %0, %1, %2"
1049169689Skan  [(set_attr "type" "imul3")])
1050169689Skan
1051169689Skan(define_insn "*maclhwuc"
1052169689Skan  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1053169689Skan        (compare:CC (plus:SI (mult:SI (zero_extend:SI
1054169689Skan                                       (match_operand:HI 1 "gpc_reg_operand" "%r"))
1055169689Skan                                      (zero_extend:SI
1056169689Skan                                       (match_operand:HI 2 "gpc_reg_operand" "r")))
1057169689Skan                             (match_operand:SI 4 "gpc_reg_operand" "0"))
1058169689Skan                    (const_int 0)))
1059169689Skan   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1060169689Skan        (plus:SI (mult:SI (zero_extend:SI
1061169689Skan                           (match_dup 1))
1062169689Skan                          (zero_extend:SI
1063169689Skan                           (match_dup 2)))
1064169689Skan                 (match_dup 4)))]
1065169689Skan  "TARGET_MULHW"
1066169689Skan  "maclhwu. %0, %1, %2"
1067169689Skan  [(set_attr "type" "imul3")])
1068169689Skan
1069169689Skan(define_insn "*maclhwu"
1070169689Skan  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1071169689Skan        (plus:SI (mult:SI (zero_extend:SI
1072169689Skan                           (match_operand:HI 1 "gpc_reg_operand" "%r"))
1073169689Skan                          (zero_extend:SI
1074169689Skan                           (match_operand:HI 2 "gpc_reg_operand" "r")))
1075169689Skan                 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1076169689Skan  "TARGET_MULHW"
1077169689Skan  "maclhwu %0, %1, %2"
1078169689Skan  [(set_attr "type" "imul3")])
1079169689Skan
1080169689Skan(define_insn "*nmacchwc"
1081169689Skan  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1082169689Skan        (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1083169689Skan                              (mult:SI (ashiftrt:SI
1084169689Skan                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1085169689Skan                                        (const_int 16))
1086169689Skan                                       (sign_extend:SI
1087169689Skan                                        (match_operand:HI 1 "gpc_reg_operand" "r"))))
1088169689Skan                    (const_int 0)))
1089169689Skan   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1090169689Skan        (minus:SI (match_dup 4)
1091169689Skan                  (mult:SI (ashiftrt:SI
1092169689Skan                            (match_dup 2)
1093169689Skan                            (const_int 16))
1094169689Skan                           (sign_extend:SI
1095169689Skan                            (match_dup 1)))))]
1096169689Skan  "TARGET_MULHW"
1097169689Skan  "nmacchw. %0, %1, %2"
1098169689Skan  [(set_attr "type" "imul3")])
1099169689Skan
1100169689Skan(define_insn "*nmacchw"
1101169689Skan  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1102169689Skan        (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1103169689Skan                  (mult:SI (ashiftrt:SI
1104169689Skan                            (match_operand:SI 2 "gpc_reg_operand" "r")
1105169689Skan                            (const_int 16))
1106169689Skan                           (sign_extend:SI
1107169689Skan                            (match_operand:HI 1 "gpc_reg_operand" "r")))))]
1108169689Skan  "TARGET_MULHW"
1109169689Skan  "nmacchw %0, %1, %2"
1110169689Skan  [(set_attr "type" "imul3")])
1111169689Skan
1112169689Skan(define_insn "*nmachhwc"
1113169689Skan  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1114169689Skan        (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1115169689Skan                              (mult:SI (ashiftrt:SI
1116169689Skan                                        (match_operand:SI 1 "gpc_reg_operand" "%r")
1117169689Skan                                        (const_int 16))
1118169689Skan                                       (ashiftrt:SI
1119169689Skan                                        (match_operand:SI 2 "gpc_reg_operand" "r")
1120169689Skan                                        (const_int 16))))
1121169689Skan                    (const_int 0)))
1122169689Skan   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1123169689Skan        (minus:SI (match_dup 4)
1124169689Skan                  (mult:SI (ashiftrt:SI
1125169689Skan                            (match_dup 1)
1126169689Skan                            (const_int 16))
1127169689Skan                           (ashiftrt:SI
1128169689Skan                            (match_dup 2)
1129169689Skan                            (const_int 16)))))]
1130169689Skan  "TARGET_MULHW"
1131169689Skan  "nmachhw. %0, %1, %2"
1132169689Skan  [(set_attr "type" "imul3")])
1133169689Skan
1134169689Skan(define_insn "*nmachhw"
1135169689Skan  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1136169689Skan        (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1137169689Skan                  (mult:SI (ashiftrt:SI
1138169689Skan                            (match_operand:SI 1 "gpc_reg_operand" "%r")
1139169689Skan                            (const_int 16))
1140169689Skan                           (ashiftrt:SI
1141169689Skan                            (match_operand:SI 2 "gpc_reg_operand" "r")
1142169689Skan                            (const_int 16)))))]
1143169689Skan  "TARGET_MULHW"
1144169689Skan  "nmachhw %0, %1, %2"
1145169689Skan  [(set_attr "type" "imul3")])
1146169689Skan
1147169689Skan(define_insn "*nmaclhwc"
1148169689Skan  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1149169689Skan        (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1150169689Skan                              (mult:SI (sign_extend:SI
1151169689Skan                                        (match_operand:HI 1 "gpc_reg_operand" "%r"))
1152169689Skan                                       (sign_extend:SI
1153169689Skan                                        (match_operand:HI 2 "gpc_reg_operand" "r"))))
1154169689Skan                    (const_int 0)))
1155169689Skan   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1156169689Skan        (minus:SI (match_dup 4)
1157169689Skan                  (mult:SI (sign_extend:SI
1158169689Skan                            (match_dup 1))
1159169689Skan                           (sign_extend:SI
1160169689Skan                            (match_dup 2)))))]
1161169689Skan  "TARGET_MULHW"
1162169689Skan  "nmaclhw. %0, %1, %2"
1163169689Skan  [(set_attr "type" "imul3")])
1164169689Skan
1165169689Skan(define_insn "*nmaclhw"
1166169689Skan  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1167169689Skan        (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1168169689Skan                  (mult:SI (sign_extend:SI
1169169689Skan                            (match_operand:HI 1 "gpc_reg_operand" "%r"))
1170169689Skan                           (sign_extend:SI
1171169689Skan                            (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1172169689Skan  "TARGET_MULHW"
1173169689Skan  "nmaclhw %0, %1, %2"
1174169689Skan  [(set_attr "type" "imul3")])
1175169689Skan
1176169689Skan(define_insn "*mulchwc"
1177169689Skan  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1178169689Skan        (compare:CC (mult:SI (ashiftrt:SI
1179169689Skan                              (match_operand:SI 2 "gpc_reg_operand" "r")
1180169689Skan                              (const_int 16))
1181169689Skan                             (sign_extend:SI
1182169689Skan                              (match_operand:HI 1 "gpc_reg_operand" "r")))
1183169689Skan                    (const_int 0)))
1184169689Skan   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1185169689Skan        (mult:SI (ashiftrt:SI
1186169689Skan                  (match_dup 2)
1187169689Skan                  (const_int 16))
1188169689Skan                 (sign_extend:SI
1189169689Skan                  (match_dup 1))))]
1190169689Skan  "TARGET_MULHW"
1191169689Skan  "mulchw. %0, %1, %2"
1192169689Skan  [(set_attr "type" "imul3")])
1193169689Skan
1194169689Skan(define_insn "*mulchw"
1195169689Skan  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1196169689Skan        (mult:SI (ashiftrt:SI
1197169689Skan                  (match_operand:SI 2 "gpc_reg_operand" "r")
1198169689Skan                  (const_int 16))
1199169689Skan                 (sign_extend:SI
1200169689Skan                  (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1201169689Skan  "TARGET_MULHW"
1202169689Skan  "mulchw %0, %1, %2"
1203169689Skan  [(set_attr "type" "imul3")])
1204169689Skan
1205169689Skan(define_insn "*mulchwuc"
1206169689Skan  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1207169689Skan        (compare:CC (mult:SI (lshiftrt:SI
1208169689Skan                              (match_operand:SI 2 "gpc_reg_operand" "r")
1209169689Skan                              (const_int 16))
1210169689Skan                             (zero_extend:SI
1211169689Skan                              (match_operand:HI 1 "gpc_reg_operand" "r")))
1212169689Skan                    (const_int 0)))
1213169689Skan   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1214169689Skan        (mult:SI (lshiftrt:SI
1215169689Skan                  (match_dup 2)
1216169689Skan                  (const_int 16))
1217169689Skan                 (zero_extend:SI
1218169689Skan                  (match_dup 1))))]
1219169689Skan  "TARGET_MULHW"
1220169689Skan  "mulchwu. %0, %1, %2"
1221169689Skan  [(set_attr "type" "imul3")])
1222169689Skan
1223169689Skan(define_insn "*mulchwu"
1224169689Skan  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1225169689Skan        (mult:SI (lshiftrt:SI
1226169689Skan                  (match_operand:SI 2 "gpc_reg_operand" "r")
1227169689Skan                  (const_int 16))
1228169689Skan                 (zero_extend:SI
1229169689Skan                  (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1230169689Skan  "TARGET_MULHW"
1231169689Skan  "mulchwu %0, %1, %2"
1232169689Skan  [(set_attr "type" "imul3")])
1233169689Skan
1234169689Skan(define_insn "*mulhhwc"
1235169689Skan  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1236169689Skan        (compare:CC (mult:SI (ashiftrt:SI
1237169689Skan                              (match_operand:SI 1 "gpc_reg_operand" "%r")
1238169689Skan                              (const_int 16))
1239169689Skan                             (ashiftrt:SI
1240169689Skan                              (match_operand:SI 2 "gpc_reg_operand" "r")
1241169689Skan                              (const_int 16)))
1242169689Skan                    (const_int 0)))
1243169689Skan   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1244169689Skan        (mult:SI (ashiftrt:SI
1245169689Skan                  (match_dup 1)
1246169689Skan                  (const_int 16))
1247169689Skan                 (ashiftrt:SI
1248169689Skan                  (match_dup 2)
1249169689Skan                  (const_int 16))))]
1250169689Skan  "TARGET_MULHW"
1251169689Skan  "mulhhw. %0, %1, %2"
1252169689Skan  [(set_attr "type" "imul3")])
1253169689Skan
1254169689Skan(define_insn "*mulhhw"
1255169689Skan  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1256169689Skan        (mult:SI (ashiftrt:SI
1257169689Skan                  (match_operand:SI 1 "gpc_reg_operand" "%r")
1258169689Skan                  (const_int 16))
1259169689Skan                 (ashiftrt:SI
1260169689Skan                  (match_operand:SI 2 "gpc_reg_operand" "r")
1261169689Skan                  (const_int 16))))]
1262169689Skan  "TARGET_MULHW"
1263169689Skan  "mulhhw %0, %1, %2"
1264169689Skan  [(set_attr "type" "imul3")])
1265169689Skan
1266169689Skan(define_insn "*mulhhwuc"
1267169689Skan  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1268169689Skan        (compare:CC (mult:SI (lshiftrt:SI
1269169689Skan                              (match_operand:SI 1 "gpc_reg_operand" "%r")
1270169689Skan                              (const_int 16))
1271169689Skan                             (lshiftrt:SI
1272169689Skan                              (match_operand:SI 2 "gpc_reg_operand" "r")
1273169689Skan                              (const_int 16)))
1274169689Skan                    (const_int 0)))
1275169689Skan   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1276169689Skan        (mult:SI (lshiftrt:SI
1277169689Skan                  (match_dup 1)
1278169689Skan                  (const_int 16))
1279169689Skan                 (lshiftrt:SI
1280169689Skan                  (match_dup 2)
1281169689Skan                  (const_int 16))))]
1282169689Skan  "TARGET_MULHW"
1283169689Skan  "mulhhwu. %0, %1, %2"
1284169689Skan  [(set_attr "type" "imul3")])
1285169689Skan
1286169689Skan(define_insn "*mulhhwu"
1287169689Skan  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1288169689Skan        (mult:SI (lshiftrt:SI
1289169689Skan                  (match_operand:SI 1 "gpc_reg_operand" "%r")
1290169689Skan                  (const_int 16))
1291169689Skan                 (lshiftrt:SI
1292169689Skan                  (match_operand:SI 2 "gpc_reg_operand" "r")
1293169689Skan                  (const_int 16))))]
1294169689Skan  "TARGET_MULHW"
1295169689Skan  "mulhhwu %0, %1, %2"
1296169689Skan  [(set_attr "type" "imul3")])
1297169689Skan
1298169689Skan(define_insn "*mullhwc"
1299169689Skan  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1300169689Skan        (compare:CC (mult:SI (sign_extend:SI
1301169689Skan                              (match_operand:HI 1 "gpc_reg_operand" "%r"))
1302169689Skan                             (sign_extend:SI
1303169689Skan                              (match_operand:HI 2 "gpc_reg_operand" "r")))
1304169689Skan                    (const_int 0)))
1305169689Skan   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1306169689Skan        (mult:SI (sign_extend:SI
1307169689Skan                  (match_dup 1))
1308169689Skan                 (sign_extend:SI
1309169689Skan                  (match_dup 2))))]
1310169689Skan  "TARGET_MULHW"
1311169689Skan  "mullhw. %0, %1, %2"
1312169689Skan  [(set_attr "type" "imul3")])
1313169689Skan
1314169689Skan(define_insn "*mullhw"
1315169689Skan  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1316169689Skan        (mult:SI (sign_extend:SI
1317169689Skan                  (match_operand:HI 1 "gpc_reg_operand" "%r"))
1318169689Skan                 (sign_extend:SI
1319169689Skan                  (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1320169689Skan  "TARGET_MULHW"
1321169689Skan  "mullhw %0, %1, %2"
1322169689Skan  [(set_attr "type" "imul3")])
1323169689Skan
1324169689Skan(define_insn "*mullhwuc"
1325169689Skan  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1326169689Skan        (compare:CC (mult:SI (zero_extend:SI
1327169689Skan                              (match_operand:HI 1 "gpc_reg_operand" "%r"))
1328169689Skan                             (zero_extend:SI
1329169689Skan                              (match_operand:HI 2 "gpc_reg_operand" "r")))
1330169689Skan                    (const_int 0)))
1331169689Skan   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1332169689Skan        (mult:SI (zero_extend:SI
1333169689Skan                  (match_dup 1))
1334169689Skan                 (zero_extend:SI
1335169689Skan                  (match_dup 2))))]
1336169689Skan  "TARGET_MULHW"
1337169689Skan  "mullhwu. %0, %1, %2"
1338169689Skan  [(set_attr "type" "imul3")])
1339169689Skan
1340169689Skan(define_insn "*mullhwu"
1341169689Skan  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1342169689Skan        (mult:SI (zero_extend:SI
1343169689Skan                  (match_operand:HI 1 "gpc_reg_operand" "%r"))
1344169689Skan                 (zero_extend:SI
1345169689Skan                  (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1346169689Skan  "TARGET_MULHW"
1347169689Skan  "mullhwu %0, %1, %2"
1348169689Skan  [(set_attr "type" "imul3")])
1349169689Skan
1350169689Skan;; IBM 405 and 440 string-search dlmzb instruction support.
1351169689Skan(define_insn "dlmzb"
1352169689Skan  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1353169689Skan        (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1354169689Skan                    (match_operand:SI 2 "gpc_reg_operand" "r")]
1355169689Skan                   UNSPEC_DLMZB_CR))
1356169689Skan   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1357169689Skan        (unspec:SI [(match_dup 1)
1358169689Skan                    (match_dup 2)]
1359169689Skan                   UNSPEC_DLMZB))]
1360169689Skan  "TARGET_DLMZB"
1361169689Skan  "dlmzb. %0, %1, %2")
1362169689Skan
1363169689Skan(define_expand "strlensi"
1364169689Skan  [(set (match_operand:SI 0 "gpc_reg_operand" "")
1365169689Skan        (unspec:SI [(match_operand:BLK 1 "general_operand" "")
1366169689Skan                    (match_operand:QI 2 "const_int_operand" "")
1367169689Skan                    (match_operand 3 "const_int_operand" "")]
1368169689Skan                   UNSPEC_DLMZB_STRLEN))
1369169689Skan   (clobber (match_scratch:CC 4 "=x"))]
1370169689Skan  "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1371169689Skan{
1372169689Skan  rtx result = operands[0];
1373169689Skan  rtx src = operands[1];
1374169689Skan  rtx search_char = operands[2];
1375169689Skan  rtx align = operands[3];
1376169689Skan  rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1377169689Skan  rtx loop_label, end_label, mem, cr0, cond;
1378169689Skan  if (search_char != const0_rtx
1379169689Skan      || GET_CODE (align) != CONST_INT
1380169689Skan      || INTVAL (align) < 8)
1381169689Skan        FAIL;
1382169689Skan  word1 = gen_reg_rtx (SImode);
1383169689Skan  word2 = gen_reg_rtx (SImode);
1384169689Skan  scratch_dlmzb = gen_reg_rtx (SImode);
1385169689Skan  scratch_string = gen_reg_rtx (Pmode);
1386169689Skan  loop_label = gen_label_rtx ();
1387169689Skan  end_label = gen_label_rtx ();
1388169689Skan  addr = force_reg (Pmode, XEXP (src, 0));
1389169689Skan  emit_move_insn (scratch_string, addr);
1390169689Skan  emit_label (loop_label);
1391169689Skan  mem = change_address (src, SImode, scratch_string);
1392169689Skan  emit_move_insn (word1, mem);
1393169689Skan  emit_move_insn (word2, adjust_address (mem, SImode, 4));
1394169689Skan  cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1395169689Skan  emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1396169689Skan  cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1397169689Skan  emit_jump_insn (gen_rtx_SET (VOIDmode,
1398169689Skan                               pc_rtx,
1399169689Skan                               gen_rtx_IF_THEN_ELSE (VOIDmode,
1400169689Skan                                                     cond,
1401169689Skan                                                     gen_rtx_LABEL_REF
1402169689Skan                                                       (VOIDmode,
1403169689Skan                                                        end_label),
1404169689Skan                                                     pc_rtx)));
1405169689Skan  emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1406169689Skan  emit_jump_insn (gen_rtx_SET (VOIDmode,
1407169689Skan                               pc_rtx,
1408169689Skan                               gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1409169689Skan  emit_barrier ();
1410169689Skan  emit_label (end_label);
1411169689Skan  emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1412169689Skan  emit_insn (gen_subsi3 (result, scratch_string, addr));
1413169689Skan  emit_insn (gen_subsi3 (result, result, const1_rtx));
1414169689Skan  DONE;
1415169689Skan})
1416169689Skan
141790075Sobrien(define_split
141890075Sobrien  [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "")
141990075Sobrien	(compare:CC (sign_extend:SI (match_operand:HI 1 "gpc_reg_operand" ""))
142090075Sobrien		    (const_int 0)))
142190075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "")
142290075Sobrien	(sign_extend:SI (match_dup 1)))]
142390075Sobrien  "reload_completed"
142490075Sobrien  [(set (match_dup 0)
142590075Sobrien	(sign_extend:SI (match_dup 1)))
142690075Sobrien   (set (match_dup 2)
142790075Sobrien	(compare:CC (match_dup 0)
142890075Sobrien		    (const_int 0)))]
142990075Sobrien  "")
143090075Sobrien
143190075Sobrien;; Fixed-point arithmetic insns.
143290075Sobrien
1433169689Skan(define_expand "add<mode>3"
1434169689Skan  [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1435169689Skan	(plus:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
1436169689Skan		  (match_operand:SDI 2 "reg_or_add_cint_operand" "")))]
143790075Sobrien  ""
143890075Sobrien{
1439169689Skan  if (<MODE>mode == DImode && ! TARGET_POWERPC64)
144090075Sobrien    {
1441169689Skan      if (non_short_cint_operand (operands[2], DImode))
1442169689Skan	FAIL;
1443169689Skan    }
1444169689Skan  else if (GET_CODE (operands[2]) == CONST_INT
1445169689Skan	   && ! add_operand (operands[2], <MODE>mode))
1446169689Skan    {
144790075Sobrien      rtx tmp = ((no_new_pseudos || rtx_equal_p (operands[0], operands[1]))
1448169689Skan		 ? operands[0] : gen_reg_rtx (<MODE>mode));
144990075Sobrien
145090075Sobrien      HOST_WIDE_INT val = INTVAL (operands[2]);
1451117395Skan      HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1452169689Skan      HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
145390075Sobrien
1454169689Skan      if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1455169689Skan	FAIL;
1456169689Skan
145790075Sobrien      /* The ordering here is important for the prolog expander.
145890075Sobrien	 When space is allocated from the stack, adding 'low' first may
145990075Sobrien	 produce a temporary deallocation (which would be bad).  */
1460169689Skan      emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1461169689Skan      emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
146290075Sobrien      DONE;
146390075Sobrien    }
1464169689Skan})
146590075Sobrien
1466169689Skan;; Discourage ai/addic because of carry but provide it in an alternative
1467169689Skan;; allowing register zero as source.
1468169689Skan(define_insn "*add<mode>3_internal1"
1469169689Skan  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,?r,r")
1470169689Skan	(plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,r,b")
1471169689Skan		  (match_operand:GPR 2 "add_operand" "r,I,I,L")))]
147290075Sobrien  ""
147390075Sobrien  "@
147490075Sobrien   {cax|add} %0,%1,%2
147590075Sobrien   {cal %0,%2(%1)|addi %0,%1,%2}
147690075Sobrien   {ai|addic} %0,%1,%2
147790075Sobrien   {cau|addis} %0,%1,%v2"
147890075Sobrien  [(set_attr "length" "4,4,4,4")])
147990075Sobrien
148090075Sobrien(define_insn "addsi3_high"
148190075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
148290075Sobrien        (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
148390075Sobrien                 (high:SI (match_operand 2 "" ""))))]
148490075Sobrien  "TARGET_MACHO && !TARGET_64BIT"
148590075Sobrien  "{cau|addis} %0,%1,ha16(%2)"
148690075Sobrien  [(set_attr "length" "4")])
148790075Sobrien
1488169689Skan(define_insn "*add<mode>3_internal2"
148990075Sobrien  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
1490169689Skan	(compare:CC (plus:P (match_operand:P 1 "gpc_reg_operand" "%r,r,r,r")
1491169689Skan			    (match_operand:P 2 "reg_or_short_operand" "r,I,r,I"))
149290075Sobrien		    (const_int 0)))
1493169689Skan   (clobber (match_scratch:P 3 "=r,r,r,r"))]
1494169689Skan  ""
149590075Sobrien  "@
149690075Sobrien   {cax.|add.} %3,%1,%2
149790075Sobrien   {ai.|addic.} %3,%1,%2
149890075Sobrien   #
149990075Sobrien   #"
1500132718Skan  [(set_attr "type" "fast_compare,compare,compare,compare")
150190075Sobrien   (set_attr "length" "4,4,8,8")])
150290075Sobrien
150390075Sobrien(define_split
150490075Sobrien  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
1505169689Skan	(compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
1506169689Skan			      (match_operand:GPR 2 "reg_or_short_operand" ""))
150790075Sobrien		    (const_int 0)))
1508169689Skan   (clobber (match_scratch:GPR 3 ""))]
1509169689Skan  "reload_completed"
151090075Sobrien  [(set (match_dup 3)
1511169689Skan	(plus:GPR (match_dup 1)
151290075Sobrien		 (match_dup 2)))
151390075Sobrien   (set (match_dup 0)
151490075Sobrien	(compare:CC (match_dup 3)
151590075Sobrien		    (const_int 0)))]
151690075Sobrien  "")
151790075Sobrien
1518169689Skan(define_insn "*add<mode>3_internal3"
151990075Sobrien  [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
1520169689Skan	(compare:CC (plus:P (match_operand:P 1 "gpc_reg_operand" "%r,r,r,r")
1521169689Skan			    (match_operand:P 2 "reg_or_short_operand" "r,I,r,I"))
152290075Sobrien		    (const_int 0)))
1523169689Skan   (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r,r")
1524169689Skan	(plus:P (match_dup 1)
1525169689Skan		(match_dup 2)))]
1526169689Skan  ""
152790075Sobrien  "@
152890075Sobrien   {cax.|add.} %0,%1,%2
152990075Sobrien   {ai.|addic.} %0,%1,%2
153090075Sobrien   #
153190075Sobrien   #"
1532132718Skan  [(set_attr "type" "fast_compare,compare,compare,compare")
153390075Sobrien   (set_attr "length" "4,4,8,8")])
153490075Sobrien
153590075Sobrien(define_split
153690075Sobrien  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
1537169689Skan	(compare:CC (plus:P (match_operand:P 1 "gpc_reg_operand" "")
1538169689Skan			    (match_operand:P 2 "reg_or_short_operand" ""))
153990075Sobrien		    (const_int 0)))
1540169689Skan   (set (match_operand:P 0 "gpc_reg_operand" "")
1541169689Skan	(plus:P (match_dup 1) (match_dup 2)))]
1542169689Skan  "reload_completed"
154390075Sobrien  [(set (match_dup 0)
1544169689Skan	(plus:P (match_dup 1)
1545169689Skan		(match_dup 2)))
154690075Sobrien   (set (match_dup 3)
154790075Sobrien	(compare:CC (match_dup 0)
154890075Sobrien		    (const_int 0)))]
154990075Sobrien  "")
155090075Sobrien
155190075Sobrien;; Split an add that we can't do in one insn into two insns, each of which
155290075Sobrien;; does one 16-bit part.  This is used by combine.  Note that the low-order
155390075Sobrien;; add should be last in case the result gets used in an address.
155490075Sobrien
155590075Sobrien(define_split
1556169689Skan  [(set (match_operand:GPR 0 "gpc_reg_operand" "")
1557169689Skan	(plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
1558169689Skan		  (match_operand:GPR 2 "non_add_cint_operand" "")))]
155990075Sobrien  ""
1560169689Skan  [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1561169689Skan   (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
156290075Sobrien{
156390075Sobrien  HOST_WIDE_INT val = INTVAL (operands[2]);
1564117395Skan  HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1565169689Skan  HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
156690075Sobrien
156790075Sobrien  operands[4] = GEN_INT (low);
1568169689Skan  if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1569169689Skan    operands[3] = GEN_INT (rest);
1570169689Skan  else if (! no_new_pseudos)
1571169689Skan    {
1572169689Skan      operands[3] = gen_reg_rtx (DImode);
1573169689Skan      emit_move_insn (operands[3], operands[2]);
1574169689Skan      emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1575169689Skan      DONE;
1576169689Skan    }
1577169689Skan  else
1578169689Skan    FAIL;
1579169689Skan})
158090075Sobrien
1581169689Skan(define_insn "one_cmpl<mode>2"
1582169689Skan  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1583169689Skan	(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
158490075Sobrien  ""
158590075Sobrien  "nor %0,%1,%1")
158690075Sobrien
158790075Sobrien(define_insn ""
158890075Sobrien  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
1589169689Skan	(compare:CC (not:P (match_operand:P 1 "gpc_reg_operand" "r,r"))
159090075Sobrien		    (const_int 0)))
1591169689Skan   (clobber (match_scratch:P 2 "=r,r"))]
1592169689Skan  ""
159390075Sobrien  "@
159490075Sobrien   nor. %2,%1,%1
159590075Sobrien   #"
159690075Sobrien  [(set_attr "type" "compare")
159790075Sobrien   (set_attr "length" "4,8")])
159890075Sobrien
159990075Sobrien(define_split
160090075Sobrien  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
1601169689Skan	(compare:CC (not:P (match_operand:P 1 "gpc_reg_operand" ""))
160290075Sobrien		    (const_int 0)))
1603169689Skan   (clobber (match_scratch:P 2 ""))]
1604169689Skan  "reload_completed"
160590075Sobrien  [(set (match_dup 2)
1606169689Skan	(not:P (match_dup 1)))
160790075Sobrien   (set (match_dup 0)
160890075Sobrien	(compare:CC (match_dup 2)
160990075Sobrien		    (const_int 0)))]
161090075Sobrien  "")
161190075Sobrien
161290075Sobrien(define_insn ""
161390075Sobrien  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1614169689Skan	(compare:CC (not:P (match_operand:P 1 "gpc_reg_operand" "r,r"))
161590075Sobrien		    (const_int 0)))
1616169689Skan   (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
1617169689Skan	(not:P (match_dup 1)))]
1618169689Skan  ""
161990075Sobrien  "@
162090075Sobrien   nor. %0,%1,%1
162190075Sobrien   #"
162290075Sobrien  [(set_attr "type" "compare")
162390075Sobrien   (set_attr "length" "4,8")])
162490075Sobrien
162590075Sobrien(define_split
162690075Sobrien  [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "")
1627169689Skan	(compare:CC (not:P (match_operand:P 1 "gpc_reg_operand" ""))
162890075Sobrien		    (const_int 0)))
1629169689Skan   (set (match_operand:P 0 "gpc_reg_operand" "")
1630169689Skan	(not:P (match_dup 1)))]
1631169689Skan  "reload_completed"
163290075Sobrien  [(set (match_dup 0)
1633169689Skan	(not:P (match_dup 1)))
163490075Sobrien   (set (match_dup 2)
163590075Sobrien	(compare:CC (match_dup 0)
163690075Sobrien		    (const_int 0)))]
163790075Sobrien  "")
163890075Sobrien
163990075Sobrien(define_insn ""
164090075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
164190075Sobrien	(minus:SI (match_operand:SI 1 "reg_or_short_operand" "rI")
164290075Sobrien		  (match_operand:SI 2 "gpc_reg_operand" "r")))]
164390075Sobrien  "! TARGET_POWERPC"
164490075Sobrien  "{sf%I1|subf%I1c} %0,%2,%1")
164590075Sobrien
164690075Sobrien(define_insn ""
1647169689Skan  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1648169689Skan	(minus:GPR (match_operand:GPR 1 "reg_or_short_operand" "r,I")
1649169689Skan		   (match_operand:GPR 2 "gpc_reg_operand" "r,r")))]
165090075Sobrien  "TARGET_POWERPC"
165190075Sobrien  "@
165290075Sobrien   subf %0,%2,%1
165390075Sobrien   subfic %0,%2,%1")
165490075Sobrien
165590075Sobrien(define_insn ""
165690075Sobrien  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
165790075Sobrien	(compare:CC (minus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
165890075Sobrien			      (match_operand:SI 2 "gpc_reg_operand" "r,r"))
165990075Sobrien		    (const_int 0)))
166090075Sobrien   (clobber (match_scratch:SI 3 "=r,r"))]
166190075Sobrien  "! TARGET_POWERPC"
166290075Sobrien  "@
166390075Sobrien   {sf.|subfc.} %3,%2,%1
166490075Sobrien   #"
166590075Sobrien  [(set_attr "type" "compare")
166690075Sobrien   (set_attr "length" "4,8")])
166790075Sobrien
166890075Sobrien(define_insn ""
166990075Sobrien  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
1670169689Skan	(compare:CC (minus:P (match_operand:P 1 "gpc_reg_operand" "r,r")
1671169689Skan			     (match_operand:P 2 "gpc_reg_operand" "r,r"))
167290075Sobrien		    (const_int 0)))
1673169689Skan   (clobber (match_scratch:P 3 "=r,r"))]
1674169689Skan  "TARGET_POWERPC"
167590075Sobrien  "@
167690075Sobrien   subf. %3,%2,%1
167790075Sobrien   #"
1678132718Skan  [(set_attr "type" "fast_compare")
167990075Sobrien   (set_attr "length" "4,8")])
168090075Sobrien
168190075Sobrien(define_split
168290075Sobrien  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
1683169689Skan	(compare:CC (minus:P (match_operand:P 1 "gpc_reg_operand" "")
1684169689Skan			     (match_operand:P 2 "gpc_reg_operand" ""))
168590075Sobrien		    (const_int 0)))
1686169689Skan   (clobber (match_scratch:P 3 ""))]
1687169689Skan  "reload_completed"
168890075Sobrien  [(set (match_dup 3)
1689169689Skan	(minus:P (match_dup 1)
169090075Sobrien		  (match_dup 2)))
169190075Sobrien   (set (match_dup 0)
169290075Sobrien	(compare:CC (match_dup 3)
169390075Sobrien		    (const_int 0)))]
169490075Sobrien  "")
169590075Sobrien
169690075Sobrien(define_insn ""
169790075Sobrien  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
169890075Sobrien	(compare:CC (minus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
169990075Sobrien			      (match_operand:SI 2 "gpc_reg_operand" "r,r"))
170090075Sobrien		    (const_int 0)))
170190075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
170290075Sobrien	(minus:SI (match_dup 1) (match_dup 2)))]
170390075Sobrien  "! TARGET_POWERPC"
170490075Sobrien  "@
170590075Sobrien   {sf.|subfc.} %0,%2,%1
170690075Sobrien   #"
170790075Sobrien  [(set_attr "type" "compare")
170890075Sobrien   (set_attr "length" "4,8")])
170990075Sobrien
171090075Sobrien(define_insn ""
171190075Sobrien  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1712169689Skan	(compare:CC (minus:P (match_operand:P 1 "gpc_reg_operand" "r,r")
1713169689Skan			     (match_operand:P 2 "gpc_reg_operand" "r,r"))
171490075Sobrien		    (const_int 0)))
1715169689Skan   (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
1716169689Skan	(minus:P (match_dup 1)
171790075Sobrien		  (match_dup 2)))]
1718169689Skan  "TARGET_POWERPC"
171990075Sobrien  "@
172090075Sobrien   subf. %0,%2,%1
172190075Sobrien   #"
1722132718Skan  [(set_attr "type" "fast_compare")
172390075Sobrien   (set_attr "length" "4,8")])
172490075Sobrien
172590075Sobrien(define_split
172690075Sobrien  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
1727169689Skan	(compare:CC (minus:P (match_operand:P 1 "gpc_reg_operand" "")
1728169689Skan			     (match_operand:P 2 "gpc_reg_operand" ""))
172990075Sobrien		    (const_int 0)))
1730169689Skan   (set (match_operand:P 0 "gpc_reg_operand" "")
1731169689Skan	(minus:P (match_dup 1)
173290075Sobrien		  (match_dup 2)))]
1733169689Skan  "reload_completed"
173490075Sobrien  [(set (match_dup 0)
1735169689Skan	(minus:P (match_dup 1)
173690075Sobrien		  (match_dup 2)))
173790075Sobrien   (set (match_dup 3)
173890075Sobrien	(compare:CC (match_dup 0)
173990075Sobrien		    (const_int 0)))]
174090075Sobrien  "")
174190075Sobrien
1742169689Skan(define_expand "sub<mode>3"
1743169689Skan  [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1744169689Skan	(minus:SDI (match_operand:SDI 1 "reg_or_short_operand" "")
1745169689Skan		   (match_operand:SDI 2 "reg_or_sub_cint_operand" "")))]
174690075Sobrien  ""
174790075Sobrien  "
174890075Sobrien{
174990075Sobrien  if (GET_CODE (operands[2]) == CONST_INT)
175090075Sobrien    {
1751169689Skan      emit_insn (gen_add<mode>3 (operands[0], operands[1],
1752169689Skan				 negate_rtx (<MODE>mode, operands[2])));
175390075Sobrien      DONE;
175490075Sobrien    }
175590075Sobrien}")
175690075Sobrien
175790075Sobrien;; For SMIN, SMAX, UMIN, and UMAX, we use DEFINE_EXPAND's that involve a doz[i]
175890075Sobrien;; instruction and some auxiliary computations.  Then we just have a single
175990075Sobrien;; DEFINE_INSN for doz[i] and the define_splits to make them if made by
176090075Sobrien;; combine.
176190075Sobrien
176290075Sobrien(define_expand "sminsi3"
176390075Sobrien  [(set (match_dup 3)
176490075Sobrien	(if_then_else:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "")
176590075Sobrien				(match_operand:SI 2 "reg_or_short_operand" ""))
176690075Sobrien			 (const_int 0)
176790075Sobrien			 (minus:SI (match_dup 2) (match_dup 1))))
176890075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "")
176990075Sobrien	(minus:SI (match_dup 2) (match_dup 3)))]
1770117395Skan  "TARGET_POWER || TARGET_ISEL"
177190075Sobrien  "
1772117395Skan{
1773117395Skan  if (TARGET_ISEL)
1774117395Skan    {
1775117395Skan      operands[2] = force_reg (SImode, operands[2]);
1776117395Skan      rs6000_emit_minmax (operands[0], SMIN, operands[1], operands[2]);
1777117395Skan      DONE;
1778117395Skan    }
177990075Sobrien
1780117395Skan  operands[3] = gen_reg_rtx (SImode);
1781117395Skan}")
1782117395Skan
178390075Sobrien(define_split
178490075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "")
178590075Sobrien	(smin:SI (match_operand:SI 1 "gpc_reg_operand" "")
178690075Sobrien		 (match_operand:SI 2 "reg_or_short_operand" "")))
178790075Sobrien   (clobber (match_operand:SI 3 "gpc_reg_operand" ""))]
178890075Sobrien  "TARGET_POWER"
178990075Sobrien  [(set (match_dup 3)
179090075Sobrien	(if_then_else:SI (gt:SI (match_dup 1) (match_dup 2))
179190075Sobrien			 (const_int 0)
179290075Sobrien			 (minus:SI (match_dup 2) (match_dup 1))))
179390075Sobrien   (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 3)))]
179490075Sobrien  "")
179590075Sobrien
179690075Sobrien(define_expand "smaxsi3"
179790075Sobrien  [(set (match_dup 3)
179890075Sobrien	(if_then_else:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "")
179990075Sobrien				(match_operand:SI 2 "reg_or_short_operand" ""))
180090075Sobrien			 (const_int 0)
180190075Sobrien			 (minus:SI (match_dup 2) (match_dup 1))))
180290075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "")
180390075Sobrien	(plus:SI (match_dup 3) (match_dup 1)))]
1804117395Skan  "TARGET_POWER || TARGET_ISEL"
180590075Sobrien  "
1806117395Skan{
1807117395Skan  if (TARGET_ISEL)
1808117395Skan    {
1809117395Skan      operands[2] = force_reg (SImode, operands[2]);
1810117395Skan      rs6000_emit_minmax (operands[0], SMAX, operands[1], operands[2]);
1811117395Skan      DONE;
1812117395Skan    }
1813117395Skan  operands[3] = gen_reg_rtx (SImode);
1814117395Skan}")
181590075Sobrien
181690075Sobrien(define_split
181790075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "")
181890075Sobrien	(smax:SI (match_operand:SI 1 "gpc_reg_operand" "")
181990075Sobrien		 (match_operand:SI 2 "reg_or_short_operand" "")))
182090075Sobrien   (clobber (match_operand:SI 3 "gpc_reg_operand" ""))]
182190075Sobrien  "TARGET_POWER"
182290075Sobrien  [(set (match_dup 3)
182390075Sobrien	(if_then_else:SI (gt:SI (match_dup 1) (match_dup 2))
182490075Sobrien			 (const_int 0)
182590075Sobrien			 (minus:SI (match_dup 2) (match_dup 1))))
182690075Sobrien   (set (match_dup 0) (plus:SI (match_dup 3) (match_dup 1)))]
182790075Sobrien  "")
182890075Sobrien
182990075Sobrien(define_expand "uminsi3"
183090075Sobrien  [(set (match_dup 3) (xor:SI (match_operand:SI 1 "gpc_reg_operand" "")
183190075Sobrien			      (match_dup 5)))
183290075Sobrien   (set (match_dup 4) (xor:SI (match_operand:SI 2 "gpc_reg_operand" "")
183390075Sobrien			      (match_dup 5)))
183490075Sobrien   (set (match_dup 3) (if_then_else:SI (gt (match_dup 3) (match_dup 4))
183590075Sobrien				       (const_int 0)
183690075Sobrien				       (minus:SI (match_dup 4) (match_dup 3))))
183790075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "")
183890075Sobrien	(minus:SI (match_dup 2) (match_dup 3)))]
1839117395Skan  "TARGET_POWER || TARGET_ISEL"
184090075Sobrien  "
184190075Sobrien{
1842117395Skan  if (TARGET_ISEL)
1843117395Skan    {
1844117395Skan      rs6000_emit_minmax (operands[0], UMIN, operands[1], operands[2]);
1845117395Skan      DONE;
1846117395Skan    }
184790075Sobrien  operands[3] = gen_reg_rtx (SImode);
184890075Sobrien  operands[4] = gen_reg_rtx (SImode);
184990075Sobrien  operands[5] = GEN_INT (-2147483647 - 1);
185090075Sobrien}")
185190075Sobrien
185290075Sobrien(define_expand "umaxsi3"
185390075Sobrien  [(set (match_dup 3) (xor:SI (match_operand:SI 1 "gpc_reg_operand" "")
185490075Sobrien			      (match_dup 5)))
185590075Sobrien   (set (match_dup 4) (xor:SI (match_operand:SI 2 "gpc_reg_operand" "")
185690075Sobrien			      (match_dup 5)))
185790075Sobrien   (set (match_dup 3) (if_then_else:SI (gt (match_dup 3) (match_dup 4))
185890075Sobrien				       (const_int 0)
185990075Sobrien				       (minus:SI (match_dup 4) (match_dup 3))))
186090075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "")
186190075Sobrien	(plus:SI (match_dup 3) (match_dup 1)))]
1862117395Skan  "TARGET_POWER || TARGET_ISEL"
186390075Sobrien  "
186490075Sobrien{
1865117395Skan  if (TARGET_ISEL)
1866117395Skan    {
1867117395Skan      rs6000_emit_minmax (operands[0], UMAX, operands[1], operands[2]);
1868117395Skan      DONE;
1869117395Skan    }
187090075Sobrien  operands[3] = gen_reg_rtx (SImode);
187190075Sobrien  operands[4] = gen_reg_rtx (SImode);
187290075Sobrien  operands[5] = GEN_INT (-2147483647 - 1);
187390075Sobrien}")
187490075Sobrien
187590075Sobrien(define_insn ""
187690075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
187790075Sobrien	(if_then_else:SI (gt (match_operand:SI 1 "gpc_reg_operand" "r")
187890075Sobrien			     (match_operand:SI 2 "reg_or_short_operand" "rI"))
187990075Sobrien			 (const_int 0)
188090075Sobrien			 (minus:SI (match_dup 2) (match_dup 1))))]
188190075Sobrien  "TARGET_POWER"
188290075Sobrien  "doz%I2 %0,%1,%2")
188390075Sobrien
188490075Sobrien(define_insn ""
188590075Sobrien  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
188690075Sobrien	(compare:CC
188790075Sobrien	 (if_then_else:SI (gt (match_operand:SI 1 "gpc_reg_operand" "r,r")
188890075Sobrien			      (match_operand:SI 2 "reg_or_short_operand" "rI,rI"))
188990075Sobrien			  (const_int 0)
189090075Sobrien			  (minus:SI (match_dup 2) (match_dup 1)))
189190075Sobrien	 (const_int 0)))
189290075Sobrien   (clobber (match_scratch:SI 3 "=r,r"))]
189390075Sobrien  "TARGET_POWER"
189490075Sobrien  "@
189590075Sobrien   doz%I2. %3,%1,%2
189690075Sobrien   #"
189790075Sobrien  [(set_attr "type" "delayed_compare")
189890075Sobrien   (set_attr "length" "4,8")])
189990075Sobrien
190090075Sobrien(define_split
190190075Sobrien  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
190290075Sobrien	(compare:CC
190390075Sobrien	 (if_then_else:SI (gt (match_operand:SI 1 "gpc_reg_operand" "")
190490075Sobrien			      (match_operand:SI 2 "reg_or_short_operand" ""))
190590075Sobrien			  (const_int 0)
190690075Sobrien			  (minus:SI (match_dup 2) (match_dup 1)))
190790075Sobrien	 (const_int 0)))
190890075Sobrien   (clobber (match_scratch:SI 3 ""))]
190990075Sobrien  "TARGET_POWER && reload_completed"
191090075Sobrien  [(set (match_dup 3)
191190075Sobrien	(if_then_else:SI (gt (match_dup 1) (match_dup 2))
191290075Sobrien			  (const_int 0)
191390075Sobrien			  (minus:SI (match_dup 2) (match_dup 1))))
191490075Sobrien   (set (match_dup 0)
191590075Sobrien	(compare:CC (match_dup 3)
191690075Sobrien		    (const_int 0)))]
191790075Sobrien  "")
191890075Sobrien
191990075Sobrien(define_insn ""
192090075Sobrien  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
192190075Sobrien	(compare:CC
192290075Sobrien	 (if_then_else:SI (gt (match_operand:SI 1 "gpc_reg_operand" "r,r")
192390075Sobrien			      (match_operand:SI 2 "reg_or_short_operand" "rI,rI"))
192490075Sobrien			  (const_int 0)
192590075Sobrien			  (minus:SI (match_dup 2) (match_dup 1)))
192690075Sobrien	 (const_int 0)))
192790075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
192890075Sobrien	(if_then_else:SI (gt (match_dup 1) (match_dup 2))
192990075Sobrien			 (const_int 0)
193090075Sobrien			 (minus:SI (match_dup 2) (match_dup 1))))]
193190075Sobrien  "TARGET_POWER"
193290075Sobrien  "@
193390075Sobrien   doz%I2. %0,%1,%2
193490075Sobrien   #"
193590075Sobrien  [(set_attr "type" "delayed_compare")
193690075Sobrien   (set_attr "length" "4,8")])
193790075Sobrien
193890075Sobrien(define_split
193990075Sobrien  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
194090075Sobrien	(compare:CC
194190075Sobrien	 (if_then_else:SI (gt (match_operand:SI 1 "gpc_reg_operand" "")
194290075Sobrien			      (match_operand:SI 2 "reg_or_short_operand" ""))
194390075Sobrien			  (const_int 0)
194490075Sobrien			  (minus:SI (match_dup 2) (match_dup 1)))
194590075Sobrien	 (const_int 0)))
194690075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "")
194790075Sobrien	(if_then_else:SI (gt (match_dup 1) (match_dup 2))
194890075Sobrien			 (const_int 0)
194990075Sobrien			 (minus:SI (match_dup 2) (match_dup 1))))]
195090075Sobrien  "TARGET_POWER && reload_completed"
195190075Sobrien  [(set (match_dup 0)
195290075Sobrien	(if_then_else:SI (gt (match_dup 1) (match_dup 2))
195390075Sobrien			 (const_int 0)
195490075Sobrien			 (minus:SI (match_dup 2) (match_dup 1))))
195590075Sobrien   (set (match_dup 3)
195690075Sobrien	(compare:CC (match_dup 0)
195790075Sobrien		    (const_int 0)))]
195890075Sobrien  "")
195990075Sobrien
196090075Sobrien;; We don't need abs with condition code because such comparisons should
196190075Sobrien;; never be done.
196290075Sobrien(define_expand "abssi2"
196390075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "")
196490075Sobrien	(abs:SI (match_operand:SI 1 "gpc_reg_operand" "")))]
196590075Sobrien  ""
196690075Sobrien  "
196790075Sobrien{
1968117395Skan  if (TARGET_ISEL)
196990075Sobrien    {
1970117395Skan      emit_insn (gen_abssi2_isel (operands[0], operands[1]));
1971117395Skan      DONE;
1972117395Skan    }
1973117395Skan  else if (! TARGET_POWER)
1974117395Skan    {
197590075Sobrien      emit_insn (gen_abssi2_nopower (operands[0], operands[1]));
197690075Sobrien      DONE;
197790075Sobrien    }
197890075Sobrien}")
197990075Sobrien
1980117395Skan(define_insn "*abssi2_power"
198190075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
198290075Sobrien	(abs:SI (match_operand:SI 1 "gpc_reg_operand" "r")))]
198390075Sobrien  "TARGET_POWER"
198490075Sobrien  "abs %0,%1")
198590075Sobrien
1986117395Skan(define_insn_and_split "abssi2_isel"
1987117395Skan  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1988117395Skan        (abs:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
1989132718Skan   (clobber (match_scratch:SI 2 "=&b"))
1990117395Skan   (clobber (match_scratch:CC 3 "=y"))]
1991117395Skan  "TARGET_ISEL"
1992117395Skan  "#"
1993117395Skan  "&& reload_completed"
1994117395Skan  [(set (match_dup 2) (neg:SI (match_dup 1)))
1995117395Skan   (set (match_dup 3)
1996117395Skan	(compare:CC (match_dup 1)
1997117395Skan		    (const_int 0)))
1998117395Skan   (set (match_dup 0)
1999117395Skan	(if_then_else:SI (ge (match_dup 3)
2000117395Skan			     (const_int 0))
2001117395Skan			 (match_dup 1)
2002117395Skan			 (match_dup 2)))]
2003117395Skan  "")
2004117395Skan
2005117395Skan(define_insn_and_split "abssi2_nopower"
200690075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,r")
2007117395Skan        (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r,0")))
200890075Sobrien   (clobber (match_scratch:SI 2 "=&r,&r"))]
2009117395Skan  "! TARGET_POWER && ! TARGET_ISEL"
2010117395Skan  "#"
2011117395Skan  "&& reload_completed"
201290075Sobrien  [(set (match_dup 2) (ashiftrt:SI (match_dup 1) (const_int 31)))
201390075Sobrien   (set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1)))
201490075Sobrien   (set (match_dup 0) (minus:SI (match_dup 0) (match_dup 2)))]
201590075Sobrien  "")
201690075Sobrien
201790075Sobrien(define_insn "*nabs_power"
201890075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
201990075Sobrien	(neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r"))))]
202090075Sobrien  "TARGET_POWER"
202190075Sobrien  "nabs %0,%1")
202290075Sobrien
2023117395Skan(define_insn_and_split "*nabs_nopower"
202490075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,r")
2025117395Skan        (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r,0"))))
202690075Sobrien   (clobber (match_scratch:SI 2 "=&r,&r"))]
202790075Sobrien  "! TARGET_POWER"
2028117395Skan  "#"
2029117395Skan  "&& reload_completed"
203090075Sobrien  [(set (match_dup 2) (ashiftrt:SI (match_dup 1) (const_int 31)))
203190075Sobrien   (set (match_dup 0) (xor:SI (match_dup 2) (match_dup 1)))
203290075Sobrien   (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 0)))]
203390075Sobrien  "")
203490075Sobrien
2035169689Skan(define_expand "neg<mode>2"
2036169689Skan  [(set (match_operand:SDI 0 "gpc_reg_operand" "")
2037169689Skan	(neg:SDI (match_operand:SDI 1 "gpc_reg_operand" "")))]
203890075Sobrien  ""
2039169689Skan  "")
2040169689Skan
2041169689Skan(define_insn "*neg<mode>2_internal"
2042169689Skan  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2043169689Skan	(neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2044169689Skan  ""
204590075Sobrien  "neg %0,%1")
204690075Sobrien
204790075Sobrien(define_insn ""
204890075Sobrien  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
2049169689Skan	(compare:CC (neg:P (match_operand:P 1 "gpc_reg_operand" "r,r"))
205090075Sobrien		    (const_int 0)))
2051169689Skan   (clobber (match_scratch:P 2 "=r,r"))]
2052169689Skan  ""
205390075Sobrien  "@
205490075Sobrien   neg. %2,%1
205590075Sobrien   #"
2056132718Skan  [(set_attr "type" "fast_compare")
205790075Sobrien   (set_attr "length" "4,8")])
205890075Sobrien
205990075Sobrien(define_split
206090075Sobrien  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
2061169689Skan	(compare:CC (neg:P (match_operand:P 1 "gpc_reg_operand" ""))
206290075Sobrien		    (const_int 0)))
2063169689Skan   (clobber (match_scratch:P 2 ""))]
2064169689Skan  "reload_completed"
206590075Sobrien  [(set (match_dup 2)
2066169689Skan	(neg:P (match_dup 1)))
206790075Sobrien   (set (match_dup 0)
206890075Sobrien	(compare:CC (match_dup 2)
206990075Sobrien		    (const_int 0)))]
207090075Sobrien  "")
207190075Sobrien
207290075Sobrien(define_insn ""
207390075Sobrien  [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2074169689Skan	(compare:CC (neg:P (match_operand:P 1 "gpc_reg_operand" "r,r"))
207590075Sobrien		    (const_int 0)))
2076169689Skan   (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
2077169689Skan	(neg:P (match_dup 1)))]
2078169689Skan  ""
207990075Sobrien  "@
208090075Sobrien   neg. %0,%1
208190075Sobrien   #"
2082132718Skan  [(set_attr "type" "fast_compare")
208390075Sobrien   (set_attr "length" "4,8")])
208490075Sobrien
208590075Sobrien(define_split
208690075Sobrien  [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "")
2087169689Skan	(compare:CC (neg:P (match_operand:P 1 "gpc_reg_operand" ""))
208890075Sobrien		    (const_int 0)))
2089169689Skan   (set (match_operand:P 0 "gpc_reg_operand" "")
2090169689Skan	(neg:P (match_dup 1)))]
2091169689Skan  "reload_completed"
209290075Sobrien  [(set (match_dup 0)
2093169689Skan	(neg:P (match_dup 1)))
209490075Sobrien   (set (match_dup 2)
209590075Sobrien	(compare:CC (match_dup 0)
209690075Sobrien		    (const_int 0)))]
209790075Sobrien  "")
209890075Sobrien
2099169689Skan(define_insn "clz<mode>2"
2100169689Skan  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2101169689Skan	(clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
210290075Sobrien  ""
2103169689Skan  "{cntlz|cntlz<wd>} %0,%1")
210490075Sobrien
2105169689Skan(define_expand "ctz<mode>2"
2106132718Skan  [(set (match_dup 2)
2107169689Skan	(neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))
2108169689Skan   (parallel [(set (match_dup 3) (and:GPR (match_dup 1)
2109169689Skan					  (match_dup 2)))
2110132718Skan	      (clobber (scratch:CC))])
2111169689Skan   (set (match_dup 4) (clz:GPR (match_dup 3)))
2112169689Skan   (set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2113169689Skan	(minus:GPR (match_dup 5) (match_dup 4)))]
2114132718Skan  ""
2115132718Skan  {
2116169689Skan     operands[2] = gen_reg_rtx (<MODE>mode);
2117169689Skan     operands[3] = gen_reg_rtx (<MODE>mode);
2118169689Skan     operands[4] = gen_reg_rtx (<MODE>mode);
2119169689Skan     operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
2120132718Skan  })
2121169689Skan
2122169689Skan(define_expand "ffs<mode>2"
2123132718Skan  [(set (match_dup 2)
2124169689Skan	(neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))
2125169689Skan   (parallel [(set (match_dup 3) (and:GPR (match_dup 1)
2126169689Skan					  (match_dup 2)))
2127132718Skan	      (clobber (scratch:CC))])
2128169689Skan   (set (match_dup 4) (clz:GPR (match_dup 3)))
2129169689Skan   (set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2130169689Skan	(minus:GPR (match_dup 5) (match_dup 4)))]
2131132718Skan  ""
2132132718Skan  {
2133169689Skan     operands[2] = gen_reg_rtx (<MODE>mode);
2134169689Skan     operands[3] = gen_reg_rtx (<MODE>mode);
2135169689Skan     operands[4] = gen_reg_rtx (<MODE>mode);
2136169689Skan     operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
2137132718Skan  })
2138169689Skan
2139169689Skan(define_expand "popcount<mode>2"
2140169689Skan  [(set (match_dup 2)
2141169689Skan	(unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2142169689Skan		     UNSPEC_POPCNTB))
2143169689Skan   (set (match_dup 3)
2144169689Skan	(mult:GPR (match_dup 2) (match_dup 4)))
2145169689Skan   (set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2146169689Skan	(lshiftrt:GPR (match_dup 3) (match_dup 5)))]
2147169689Skan  "TARGET_POPCNTB"
2148169689Skan  {
2149169689Skan    operands[2] = gen_reg_rtx (<MODE>mode);
2150169689Skan    operands[3] = gen_reg_rtx (<MODE>mode);
2151169689Skan    operands[4] = force_reg (<MODE>mode,
2152169689Skan			     <MODE>mode == SImode
2153169689Skan			     ? GEN_INT (0x01010101)
2154169689Skan			     : GEN_INT ((HOST_WIDE_INT)
2155169689Skan					0x01010101 << 32 | 0x01010101));
2156169689Skan    operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 8);
2157169689Skan  })
2158169689Skan
2159169689Skan(define_insn "popcntb<mode>2"
2160169689Skan  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2161169689Skan        (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2162169689Skan                     UNSPEC_POPCNTB))]
2163169689Skan  "TARGET_POPCNTB"
2164169689Skan  "popcntb %0,%1")
2165169689Skan
216690075Sobrien(define_expand "mulsi3"
216790075Sobrien  [(use (match_operand:SI 0 "gpc_reg_operand" ""))
216890075Sobrien   (use (match_operand:SI 1 "gpc_reg_operand" ""))
216990075Sobrien   (use (match_operand:SI 2 "reg_or_short_operand" ""))]
217090075Sobrien  ""
217190075Sobrien  "
217290075Sobrien{
217390075Sobrien  if (TARGET_POWER)
217490075Sobrien    emit_insn (gen_mulsi3_mq (operands[0], operands[1], operands[2]));
217590075Sobrien  else
217690075Sobrien    emit_insn (gen_mulsi3_no_mq (operands[0], operands[1], operands[2]));
217790075Sobrien  DONE;
217890075Sobrien}")
217990075Sobrien
218090075Sobrien(define_insn "mulsi3_mq"
218190075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
218290075Sobrien	(mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
218390075Sobrien		 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
218490075Sobrien   (clobber (match_scratch:SI 3 "=q,q"))]
218590075Sobrien  "TARGET_POWER"
218690075Sobrien  "@
218790075Sobrien   {muls|mullw} %0,%1,%2
218890075Sobrien   {muli|mulli} %0,%1,%2"
2189169689Skan   [(set (attr "type")
219090075Sobrien      (cond [(match_operand:SI 2 "s8bit_cint_operand" "")
219190075Sobrien		(const_string "imul3")
2192169689Skan             (match_operand:SI 2 "short_cint_operand" "")
219390075Sobrien		(const_string "imul2")]
219490075Sobrien	(const_string "imul")))])
219590075Sobrien
219690075Sobrien(define_insn "mulsi3_no_mq"
219790075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
219890075Sobrien	(mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
219990075Sobrien		 (match_operand:SI 2 "reg_or_short_operand" "r,I")))]
220090075Sobrien  "! TARGET_POWER"
220190075Sobrien  "@
220290075Sobrien   {muls|mullw} %0,%1,%2
220390075Sobrien   {muli|mulli} %0,%1,%2"
2204169689Skan   [(set (attr "type")
220590075Sobrien      (cond [(match_operand:SI 2 "s8bit_cint_operand" "")
220690075Sobrien		(const_string "imul3")
2207169689Skan             (match_operand:SI 2 "short_cint_operand" "")
220890075Sobrien		(const_string "imul2")]
220990075Sobrien	(const_string "imul")))])
221090075Sobrien
2211132718Skan(define_insn "*mulsi3_mq_internal1"
221290075Sobrien  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
221390075Sobrien	(compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
221490075Sobrien			     (match_operand:SI 2 "gpc_reg_operand" "r,r"))
221590075Sobrien		    (const_int 0)))
221690075Sobrien   (clobber (match_scratch:SI 3 "=r,r"))
221790075Sobrien   (clobber (match_scratch:SI 4 "=q,q"))]
221890075Sobrien  "TARGET_POWER"
221990075Sobrien  "@
222090075Sobrien   {muls.|mullw.} %3,%1,%2
222190075Sobrien   #"
2222132718Skan  [(set_attr "type" "imul_compare")
222390075Sobrien   (set_attr "length" "4,8")])
222490075Sobrien
222590075Sobrien(define_split
222690075Sobrien  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
222790075Sobrien	(compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "")
222890075Sobrien			     (match_operand:SI 2 "gpc_reg_operand" ""))
222990075Sobrien		    (const_int 0)))
223090075Sobrien   (clobber (match_scratch:SI 3 ""))
223190075Sobrien   (clobber (match_scratch:SI 4 ""))]
223290075Sobrien  "TARGET_POWER && reload_completed"
223390075Sobrien  [(parallel [(set (match_dup 3)
223490075Sobrien	(mult:SI (match_dup 1) (match_dup 2)))
223590075Sobrien   (clobber (match_dup 4))])
223690075Sobrien   (set (match_dup 0)
223790075Sobrien	(compare:CC (match_dup 3)
223890075Sobrien		    (const_int 0)))]
223990075Sobrien  "")
224090075Sobrien
2241132718Skan(define_insn "*mulsi3_no_mq_internal1"
224290075Sobrien  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
224390075Sobrien	(compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
224490075Sobrien			     (match_operand:SI 2 "gpc_reg_operand" "r,r"))
224590075Sobrien		    (const_int 0)))
224690075Sobrien   (clobber (match_scratch:SI 3 "=r,r"))]
224790075Sobrien  "! TARGET_POWER"
224890075Sobrien  "@
224990075Sobrien   {muls.|mullw.} %3,%1,%2
225090075Sobrien   #"
2251132718Skan  [(set_attr "type" "imul_compare")
225290075Sobrien   (set_attr "length" "4,8")])
225390075Sobrien
225490075Sobrien(define_split
225590075Sobrien  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
225690075Sobrien	(compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "")
225790075Sobrien			     (match_operand:SI 2 "gpc_reg_operand" ""))
225890075Sobrien		    (const_int 0)))
225990075Sobrien   (clobber (match_scratch:SI 3 ""))]
226090075Sobrien  "! TARGET_POWER && reload_completed"
226190075Sobrien  [(set (match_dup 3)
226290075Sobrien	(mult:SI (match_dup 1) (match_dup 2)))
226390075Sobrien   (set (match_dup 0)
226490075Sobrien	(compare:CC (match_dup 3)
226590075Sobrien		    (const_int 0)))]
226690075Sobrien  "")
226790075Sobrien
2268132718Skan(define_insn "*mulsi3_mq_internal2"
226990075Sobrien  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
227090075Sobrien	(compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
227190075Sobrien			     (match_operand:SI 2 "gpc_reg_operand" "r,r"))
227290075Sobrien		    (const_int 0)))
227390075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
227490075Sobrien	(mult:SI (match_dup 1) (match_dup 2)))
227590075Sobrien   (clobber (match_scratch:SI 4 "=q,q"))]
227690075Sobrien  "TARGET_POWER"
227790075Sobrien  "@
227890075Sobrien   {muls.|mullw.} %0,%1,%2
227990075Sobrien   #"
2280132718Skan  [(set_attr "type" "imul_compare")
228190075Sobrien   (set_attr "length" "4,8")])
228290075Sobrien
228390075Sobrien(define_split
228490075Sobrien  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
228590075Sobrien	(compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "")
228690075Sobrien			     (match_operand:SI 2 "gpc_reg_operand" ""))
228790075Sobrien		    (const_int 0)))
228890075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "")
228990075Sobrien	(mult:SI (match_dup 1) (match_dup 2)))
229090075Sobrien   (clobber (match_scratch:SI 4 ""))]
229190075Sobrien  "TARGET_POWER && reload_completed"
229290075Sobrien  [(parallel [(set (match_dup 0)
229390075Sobrien	(mult:SI (match_dup 1) (match_dup 2)))
229490075Sobrien   (clobber (match_dup 4))])
229590075Sobrien   (set (match_dup 3)
229690075Sobrien	(compare:CC (match_dup 0)
229790075Sobrien		    (const_int 0)))]
229890075Sobrien  "")
229990075Sobrien
2300132718Skan(define_insn "*mulsi3_no_mq_internal2"
230190075Sobrien  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
230290075Sobrien	(compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r")
230390075Sobrien			     (match_operand:SI 2 "gpc_reg_operand" "r,r"))
230490075Sobrien		    (const_int 0)))
230590075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
230690075Sobrien	(mult:SI (match_dup 1) (match_dup 2)))]
230790075Sobrien  "! TARGET_POWER"
230890075Sobrien  "@
230990075Sobrien   {muls.|mullw.} %0,%1,%2
231090075Sobrien   #"
2311132718Skan  [(set_attr "type" "imul_compare")
231290075Sobrien   (set_attr "length" "4,8")])
231390075Sobrien
231490075Sobrien(define_split
231590075Sobrien  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
231690075Sobrien	(compare:CC (mult:SI (match_operand:SI 1 "gpc_reg_operand" "")
231790075Sobrien			     (match_operand:SI 2 "gpc_reg_operand" ""))
231890075Sobrien		    (const_int 0)))
231990075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "")
232090075Sobrien	(mult:SI (match_dup 1) (match_dup 2)))]
232190075Sobrien  "! TARGET_POWER && reload_completed"
232290075Sobrien  [(set (match_dup 0)
232390075Sobrien	(mult:SI (match_dup 1) (match_dup 2)))
232490075Sobrien   (set (match_dup 3)
232590075Sobrien	(compare:CC (match_dup 0)
232690075Sobrien		    (const_int 0)))]
232790075Sobrien  "")
232890075Sobrien
232990075Sobrien;; Operand 1 is divided by operand 2; quotient goes to operand
233090075Sobrien;; 0 and remainder to operand 3.
233190075Sobrien;; ??? At some point, see what, if anything, we can do about if (x % y == 0).
233290075Sobrien
233390075Sobrien(define_expand "divmodsi4"
233490075Sobrien  [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
233590075Sobrien		   (div:SI (match_operand:SI 1 "gpc_reg_operand" "")
233690075Sobrien			   (match_operand:SI 2 "gpc_reg_operand" "")))
2337132718Skan	      (set (match_operand:SI 3 "register_operand" "")
233890075Sobrien		   (mod:SI (match_dup 1) (match_dup 2)))])]
233990075Sobrien  "TARGET_POWER || (! TARGET_POWER && ! TARGET_POWERPC)"
234090075Sobrien  "
234190075Sobrien{
234290075Sobrien  if (! TARGET_POWER && ! TARGET_POWERPC)
234390075Sobrien    {
234490075Sobrien      emit_move_insn (gen_rtx_REG (SImode, 3), operands[1]);
234590075Sobrien      emit_move_insn (gen_rtx_REG (SImode, 4), operands[2]);
234690075Sobrien      emit_insn (gen_divss_call ());
234790075Sobrien      emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
234890075Sobrien      emit_move_insn (operands[3], gen_rtx_REG (SImode, 4));
234990075Sobrien      DONE;
235090075Sobrien    }
235190075Sobrien}")
235290075Sobrien
2353132718Skan(define_insn "*divmodsi4_internal"
235490075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
235590075Sobrien	(div:SI (match_operand:SI 1 "gpc_reg_operand" "r")
235690075Sobrien		(match_operand:SI 2 "gpc_reg_operand" "r")))
2357132718Skan   (set (match_operand:SI 3 "register_operand" "=q")
235890075Sobrien	(mod:SI (match_dup 1) (match_dup 2)))]
235990075Sobrien  "TARGET_POWER"
236090075Sobrien  "divs %0,%1,%2"
236190075Sobrien  [(set_attr "type" "idiv")])
236290075Sobrien
2363169689Skan(define_expand "udiv<mode>3"
2364169689Skan  [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2365169689Skan        (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
2366169689Skan		  (match_operand:GPR 2 "gpc_reg_operand" "")))]
236790075Sobrien  "TARGET_POWERPC || (! TARGET_POWER && ! TARGET_POWERPC)"
236890075Sobrien  "
236990075Sobrien{
237090075Sobrien  if (! TARGET_POWER && ! TARGET_POWERPC)
237190075Sobrien    {
237290075Sobrien      emit_move_insn (gen_rtx_REG (SImode, 3), operands[1]);
237390075Sobrien      emit_move_insn (gen_rtx_REG (SImode, 4), operands[2]);
237490075Sobrien      emit_insn (gen_quous_call ());
237590075Sobrien      emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
237690075Sobrien      DONE;
237790075Sobrien    }
237890075Sobrien  else if (TARGET_POWER)
237990075Sobrien    {
238090075Sobrien      emit_insn (gen_udivsi3_mq (operands[0], operands[1], operands[2]));
238190075Sobrien      DONE;
238290075Sobrien    }
238390075Sobrien}")
238490075Sobrien
238590075Sobrien(define_insn "udivsi3_mq"
238690075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
238790075Sobrien        (udiv:SI (match_operand:SI 1 "gpc_reg_operand" "r")
238890075Sobrien                 (match_operand:SI 2 "gpc_reg_operand" "r")))
238990075Sobrien   (clobber (match_scratch:SI 3 "=q"))]
239090075Sobrien  "TARGET_POWERPC && TARGET_POWER"
239190075Sobrien  "divwu %0,%1,%2"
239290075Sobrien  [(set_attr "type" "idiv")])
239390075Sobrien
239490075Sobrien(define_insn "*udivsi3_no_mq"
2395169689Skan  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2396169689Skan        (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2397169689Skan		  (match_operand:GPR 2 "gpc_reg_operand" "r")))]
239890075Sobrien  "TARGET_POWERPC && ! TARGET_POWER"
2399169689Skan  "div<wd>u %0,%1,%2"
240090075Sobrien  [(set_attr "type" "idiv")])
240190075Sobrien
240290075Sobrien;; For powers of two we can do srai/aze for divide and then adjust for
240390075Sobrien;; modulus.  If it isn't a power of two, FAIL on POWER so divmodsi4 will be
240490075Sobrien;; used; for PowerPC, force operands into register and do a normal divide;
240590075Sobrien;; for AIX common-mode, use quoss call on register operands.
2406169689Skan(define_expand "div<mode>3"
2407169689Skan  [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2408169689Skan	(div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
2409169689Skan		 (match_operand:GPR 2 "reg_or_cint_operand" "")))]
241090075Sobrien  ""
241190075Sobrien  "
241290075Sobrien{
241390075Sobrien  if (GET_CODE (operands[2]) == CONST_INT
241490075Sobrien      && INTVAL (operands[2]) > 0
241590075Sobrien      && exact_log2 (INTVAL (operands[2])) >= 0)
241690075Sobrien    ;
241790075Sobrien  else if (TARGET_POWERPC)
241890075Sobrien    {
2419169689Skan      operands[2] = force_reg (<MODE>mode, operands[2]);
242090075Sobrien      if (TARGET_POWER)
242190075Sobrien	{
242290075Sobrien	  emit_insn (gen_divsi3_mq (operands[0], operands[1], operands[2]));
242390075Sobrien	  DONE;
242490075Sobrien	}
242590075Sobrien    }
242690075Sobrien  else if (TARGET_POWER)
242790075Sobrien    FAIL;
242890075Sobrien  else
242990075Sobrien    {
243090075Sobrien      emit_move_insn (gen_rtx_REG (SImode, 3), operands[1]);
243190075Sobrien      emit_move_insn (gen_rtx_REG (SImode, 4), operands[2]);
243290075Sobrien      emit_insn (gen_quoss_call ());
243390075Sobrien      emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
243490075Sobrien      DONE;
243590075Sobrien    }
243690075Sobrien}")
243790075Sobrien
243890075Sobrien(define_insn "divsi3_mq"
243990075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
244090075Sobrien        (div:SI (match_operand:SI 1 "gpc_reg_operand" "r")
244190075Sobrien                (match_operand:SI 2 "gpc_reg_operand" "r")))
244290075Sobrien   (clobber (match_scratch:SI 3 "=q"))]
244390075Sobrien  "TARGET_POWERPC && TARGET_POWER"
244490075Sobrien  "divw %0,%1,%2"
244590075Sobrien  [(set_attr "type" "idiv")])
244690075Sobrien
2447169689Skan(define_insn "*div<mode>3_no_mq"
2448169689Skan  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2449169689Skan        (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2450169689Skan		 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
245190075Sobrien  "TARGET_POWERPC && ! TARGET_POWER"
2452169689Skan  "div<wd> %0,%1,%2"
245390075Sobrien  [(set_attr "type" "idiv")])
245490075Sobrien
2455169689Skan(define_expand "mod<mode>3"
2456169689Skan  [(use (match_operand:GPR 0 "gpc_reg_operand" ""))
2457169689Skan   (use (match_operand:GPR 1 "gpc_reg_operand" ""))
2458169689Skan   (use (match_operand:GPR 2 "reg_or_cint_operand" ""))]
245990075Sobrien  ""
246090075Sobrien  "
246190075Sobrien{
246290075Sobrien  int i;
246390075Sobrien  rtx temp1;
246490075Sobrien  rtx temp2;
246590075Sobrien
246690075Sobrien  if (GET_CODE (operands[2]) != CONST_INT
2467117395Skan      || INTVAL (operands[2]) <= 0
246890075Sobrien      || (i = exact_log2 (INTVAL (operands[2]))) < 0)
246990075Sobrien    FAIL;
247090075Sobrien
2471169689Skan  temp1 = gen_reg_rtx (<MODE>mode);
2472169689Skan  temp2 = gen_reg_rtx (<MODE>mode);
247390075Sobrien
2474169689Skan  emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
2475169689Skan  emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
2476169689Skan  emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
247790075Sobrien  DONE;
247890075Sobrien}")
247990075Sobrien
248090075Sobrien(define_insn ""
2481169689Skan  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2482169689Skan	(div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2483169689Skan		 (match_operand:GPR 2 "exact_log2_cint_operand" "N")))]
248490075Sobrien  ""
2485169689Skan  "{srai|sra<wd>i} %0,%1,%p2\;{aze|addze} %0,%0"
2486169689Skan  [(set_attr "type" "two")
2487169689Skan   (set_attr "length" "8")])
248890075Sobrien
248990075Sobrien(define_insn ""
249090075Sobrien  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
2491169689Skan	(compare:CC (div:P (match_operand:P 1 "gpc_reg_operand" "r,r")
2492169689Skan			   (match_operand:P 2 "exact_log2_cint_operand" "N,N"))
249390075Sobrien		    (const_int 0)))
2494169689Skan   (clobber (match_scratch:P 3 "=r,r"))]
249590075Sobrien  ""
249690075Sobrien  "@
2497169689Skan   {srai|sra<wd>i} %3,%1,%p2\;{aze.|addze.} %3,%3
249890075Sobrien   #"
249990075Sobrien  [(set_attr "type" "compare")
250090075Sobrien   (set_attr "length" "8,12")])
250190075Sobrien
250290075Sobrien(define_split
250390075Sobrien  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
2504169689Skan	(compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
2505169689Skan			     (match_operand:GPR 2 "exact_log2_cint_operand"
2506169689Skan			      ""))
250790075Sobrien		    (const_int 0)))
2508169689Skan   (clobber (match_scratch:GPR 3 ""))]
250990075Sobrien  "reload_completed"
251090075Sobrien  [(set (match_dup 3)
2511169689Skan	(div:<MODE> (match_dup 1) (match_dup 2)))
251290075Sobrien   (set (match_dup 0)
251390075Sobrien	(compare:CC (match_dup 3)
251490075Sobrien		    (const_int 0)))]
251590075Sobrien  "")
251690075Sobrien
251790075Sobrien(define_insn ""
251890075Sobrien  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2519169689Skan	(compare:CC (div:P (match_operand:P 1 "gpc_reg_operand" "r,r")
2520169689Skan			   (match_operand:P 2 "exact_log2_cint_operand" "N,N"))
252190075Sobrien		    (const_int 0)))
2522169689Skan   (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
2523169689Skan	(div:P (match_dup 1) (match_dup 2)))]
252490075Sobrien  ""
252590075Sobrien  "@
2526169689Skan   {srai|sra<wd>i} %0,%1,%p2\;{aze.|addze.} %0,%0
252790075Sobrien   #"
252890075Sobrien  [(set_attr "type" "compare")
252990075Sobrien   (set_attr "length" "8,12")])
253090075Sobrien
253190075Sobrien(define_split
253290075Sobrien  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
2533169689Skan	(compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
2534169689Skan			     (match_operand:GPR 2 "exact_log2_cint_operand"
2535169689Skan			      ""))
253690075Sobrien		    (const_int 0)))
2537169689Skan   (set (match_operand:GPR 0 "gpc_reg_operand" "")
2538169689Skan	(div:GPR (match_dup 1) (match_dup 2)))]
253990075Sobrien  "reload_completed"
254090075Sobrien  [(set (match_dup 0)
2541169689Skan	(div:<MODE> (match_dup 1) (match_dup 2)))
254290075Sobrien   (set (match_dup 3)
254390075Sobrien	(compare:CC (match_dup 0)
254490075Sobrien		    (const_int 0)))]
254590075Sobrien  "")
254690075Sobrien
254790075Sobrien(define_insn ""
254890075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
254990075Sobrien	(udiv:SI
255090075Sobrien	 (plus:DI (ashift:DI
255190075Sobrien		   (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r"))
255290075Sobrien		   (const_int 32))
255390075Sobrien		  (zero_extend:DI (match_operand:SI 4 "register_operand" "2")))
255490075Sobrien	 (match_operand:SI 3 "gpc_reg_operand" "r")))
255590075Sobrien   (set (match_operand:SI 2 "register_operand" "=*q")
255690075Sobrien	(umod:SI
255790075Sobrien	 (plus:DI (ashift:DI
255890075Sobrien		   (zero_extend:DI (match_dup 1)) (const_int 32))
255990075Sobrien		  (zero_extend:DI (match_dup 4)))
256090075Sobrien	 (match_dup 3)))]
256190075Sobrien  "TARGET_POWER"
256290075Sobrien  "div %0,%1,%3"
256390075Sobrien  [(set_attr "type" "idiv")])
256490075Sobrien
256590075Sobrien;; To do unsigned divide we handle the cases of the divisor looking like a
256690075Sobrien;; negative number.  If it is a constant that is less than 2**31, we don't
256790075Sobrien;; have to worry about the branches.  So make a few subroutines here.
256890075Sobrien;;
256990075Sobrien;; First comes the normal case.
257090075Sobrien(define_expand "udivmodsi4_normal"
257190075Sobrien  [(set (match_dup 4) (const_int 0))
257290075Sobrien   (parallel [(set (match_operand:SI 0 "" "")
257390075Sobrien		   (udiv:SI (plus:DI (ashift:DI (zero_extend:DI (match_dup 4))
257490075Sobrien						(const_int 32))
257590075Sobrien				     (zero_extend:DI (match_operand:SI 1 "" "")))
257690075Sobrien			    (match_operand:SI 2 "" "")))
257790075Sobrien	      (set (match_operand:SI 3 "" "")
257890075Sobrien		   (umod:SI (plus:DI (ashift:DI (zero_extend:DI (match_dup 4))
257990075Sobrien						(const_int 32))
258090075Sobrien				     (zero_extend:DI (match_dup 1)))
258190075Sobrien			    (match_dup 2)))])]
258290075Sobrien  "TARGET_POWER"
258390075Sobrien  "
258490075Sobrien{ operands[4] = gen_reg_rtx (SImode); }")
258590075Sobrien
258690075Sobrien;; This handles the branches.
258790075Sobrien(define_expand "udivmodsi4_tests"
258890075Sobrien  [(set (match_operand:SI 0 "" "") (const_int 0))
258990075Sobrien   (set (match_operand:SI 3 "" "") (match_operand:SI 1 "" ""))
259090075Sobrien   (set (match_dup 5) (compare:CCUNS (match_dup 1) (match_operand:SI 2 "" "")))
259190075Sobrien   (set (pc) (if_then_else (ltu (match_dup 5) (const_int 0))
259290075Sobrien			   (label_ref (match_operand:SI 4 "" "")) (pc)))
259390075Sobrien   (set (match_dup 0) (const_int 1))
259490075Sobrien   (set (match_dup 3) (minus:SI (match_dup 1) (match_dup 2)))
259590075Sobrien   (set (match_dup 6) (compare:CC (match_dup 2) (const_int 0)))
259690075Sobrien   (set (pc) (if_then_else (lt (match_dup 6) (const_int 0))
259790075Sobrien			   (label_ref (match_dup 4)) (pc)))]
259890075Sobrien  "TARGET_POWER"
259990075Sobrien  "
260090075Sobrien{ operands[5] = gen_reg_rtx (CCUNSmode);
260190075Sobrien  operands[6] = gen_reg_rtx (CCmode);
260290075Sobrien}")
260390075Sobrien
260490075Sobrien(define_expand "udivmodsi4"
260590075Sobrien  [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
260690075Sobrien		   (udiv:SI (match_operand:SI 1 "gpc_reg_operand" "")
260790075Sobrien			    (match_operand:SI 2 "reg_or_cint_operand" "")))
260890075Sobrien	      (set (match_operand:SI 3 "gpc_reg_operand" "")
260990075Sobrien		   (umod:SI (match_dup 1) (match_dup 2)))])]
261090075Sobrien  ""
261190075Sobrien  "
261290075Sobrien{
261390075Sobrien  rtx label = 0;
261490075Sobrien
261590075Sobrien  if (! TARGET_POWER)
261690075Sobrien    {
261790075Sobrien      if (! TARGET_POWERPC)
261890075Sobrien        {
261990075Sobrien	  emit_move_insn (gen_rtx_REG (SImode, 3), operands[1]);
262090075Sobrien	  emit_move_insn (gen_rtx_REG (SImode, 4), operands[2]);
262190075Sobrien	  emit_insn (gen_divus_call ());
262290075Sobrien	  emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
262390075Sobrien	  emit_move_insn (operands[3], gen_rtx_REG (SImode, 4));
262490075Sobrien	  DONE;
262590075Sobrien        }
262690075Sobrien      else
262790075Sobrien        FAIL;
262890075Sobrien    }
262990075Sobrien
263090075Sobrien  if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) < 0)
263190075Sobrien    {
263290075Sobrien      operands[2] = force_reg (SImode, operands[2]);
263390075Sobrien      label = gen_label_rtx ();
263490075Sobrien      emit (gen_udivmodsi4_tests (operands[0], operands[1], operands[2],
263590075Sobrien				  operands[3], label));
263690075Sobrien    }
263790075Sobrien  else
263890075Sobrien    operands[2] = force_reg (SImode, operands[2]);
263990075Sobrien
264090075Sobrien  emit (gen_udivmodsi4_normal (operands[0], operands[1], operands[2],
264190075Sobrien			       operands[3]));
264290075Sobrien  if (label)
264390075Sobrien    emit_label (label);
264490075Sobrien
264590075Sobrien  DONE;
264690075Sobrien}")
264790075Sobrien
264890075Sobrien;; AIX architecture-independent common-mode multiply (DImode),
264990075Sobrien;; divide/modulus, and quotient subroutine calls.  Input operands in R3 and
265090075Sobrien;; R4; results in R3 and sometimes R4; link register always clobbered by bla
265190075Sobrien;; instruction; R0 sometimes clobbered; also, MQ sometimes clobbered but
265290075Sobrien;; assumed unused if generating common-mode, so ignore.
265390075Sobrien(define_insn "mulh_call"
265490075Sobrien  [(set (reg:SI 3)
265590075Sobrien	(truncate:SI
265690075Sobrien	 (lshiftrt:DI (mult:DI (sign_extend:DI (reg:SI 3))
265790075Sobrien			       (sign_extend:DI (reg:SI 4)))
265890075Sobrien		      (const_int 32))))
265990075Sobrien   (clobber (match_scratch:SI 0 "=l"))]
266090075Sobrien  "! TARGET_POWER && ! TARGET_POWERPC"
266190075Sobrien  "bla __mulh"
266290075Sobrien  [(set_attr "type" "imul")])
266390075Sobrien
266490075Sobrien(define_insn "mull_call"
266590075Sobrien  [(set (reg:DI 3)
266690075Sobrien	(mult:DI (sign_extend:DI (reg:SI 3))
266790075Sobrien		 (sign_extend:DI (reg:SI 4))))
266890075Sobrien   (clobber (match_scratch:SI 0 "=l"))
266990075Sobrien   (clobber (reg:SI 0))]
267090075Sobrien  "! TARGET_POWER && ! TARGET_POWERPC"
267190075Sobrien  "bla __mull"
267290075Sobrien  [(set_attr "type" "imul")])
267390075Sobrien
267490075Sobrien(define_insn "divss_call"
267590075Sobrien  [(set (reg:SI 3)
267690075Sobrien	(div:SI (reg:SI 3) (reg:SI 4)))
267790075Sobrien   (set (reg:SI 4)
267890075Sobrien	(mod:SI (reg:SI 3) (reg:SI 4)))
267990075Sobrien   (clobber (match_scratch:SI 0 "=l"))
268090075Sobrien   (clobber (reg:SI 0))]
268190075Sobrien  "! TARGET_POWER && ! TARGET_POWERPC"
268290075Sobrien  "bla __divss"
268390075Sobrien  [(set_attr "type" "idiv")])
268490075Sobrien
268590075Sobrien(define_insn "divus_call"
268690075Sobrien  [(set (reg:SI 3)
268790075Sobrien	(udiv:SI (reg:SI 3) (reg:SI 4)))
268890075Sobrien   (set (reg:SI 4)
268990075Sobrien	(umod:SI (reg:SI 3) (reg:SI 4)))
269090075Sobrien   (clobber (match_scratch:SI 0 "=l"))
269190075Sobrien   (clobber (reg:SI 0))
269290075Sobrien   (clobber (match_scratch:CC 1 "=x"))
269390075Sobrien   (clobber (reg:CC 69))]
269490075Sobrien  "! TARGET_POWER && ! TARGET_POWERPC"
269590075Sobrien  "bla __divus"
269690075Sobrien  [(set_attr "type" "idiv")])
269790075Sobrien
269890075Sobrien(define_insn "quoss_call"
269990075Sobrien  [(set (reg:SI 3)
270090075Sobrien	(div:SI (reg:SI 3) (reg:SI 4)))
270190075Sobrien   (clobber (match_scratch:SI 0 "=l"))]
270290075Sobrien  "! TARGET_POWER && ! TARGET_POWERPC"
270390075Sobrien  "bla __quoss"
270490075Sobrien  [(set_attr "type" "idiv")])
270590075Sobrien
270690075Sobrien(define_insn "quous_call"
270790075Sobrien  [(set (reg:SI 3)
270890075Sobrien	(udiv:SI (reg:SI 3) (reg:SI 4)))
270990075Sobrien   (clobber (match_scratch:SI 0 "=l"))
271090075Sobrien   (clobber (reg:SI 0))
271190075Sobrien   (clobber (match_scratch:CC 1 "=x"))
271290075Sobrien   (clobber (reg:CC 69))]
271390075Sobrien  "! TARGET_POWER && ! TARGET_POWERPC"
271490075Sobrien  "bla __quous"
271590075Sobrien  [(set_attr "type" "idiv")])
271690075Sobrien
271790075Sobrien;; Logical instructions
271890075Sobrien;; The logical instructions are mostly combined by using match_operator,
271990075Sobrien;; but the plain AND insns are somewhat different because there is no
272090075Sobrien;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
272190075Sobrien;; those rotate-and-mask operations.  Thus, the AND insns come first.
272290075Sobrien
272390075Sobrien(define_insn "andsi3"
272490075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
272590075Sobrien	(and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r")
272690075Sobrien		(match_operand:SI 2 "and_operand" "?r,T,K,L")))
272790075Sobrien   (clobber (match_scratch:CC 3 "=X,X,x,x"))]
272890075Sobrien  ""
272990075Sobrien  "@
273090075Sobrien   and %0,%1,%2
273190075Sobrien   {rlinm|rlwinm} %0,%1,0,%m2,%M2
273290075Sobrien   {andil.|andi.} %0,%1,%b2
2733169689Skan   {andiu.|andis.} %0,%1,%u2"
2734169689Skan  [(set_attr "type" "*,*,compare,compare")])
273590075Sobrien
273690075Sobrien;; Note to set cr's other than cr0 we do the and immediate and then
2737117395Skan;; the test again -- this avoids a mfcr which on the higher end
273890075Sobrien;; machines causes an execution serialization
273990075Sobrien
274090075Sobrien(define_insn "*andsi3_internal2"
274190075Sobrien  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,x,?y,??y,??y,?y")
274290075Sobrien	(compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r")
274390075Sobrien			    (match_operand:SI 2 "and_operand" "r,K,L,T,r,K,L,T"))
274490075Sobrien		    (const_int 0)))
274590075Sobrien   (clobber (match_scratch:SI 3 "=r,r,r,r,r,r,r,r"))
274690075Sobrien   (clobber (match_scratch:CC 4 "=X,X,X,X,X,x,x,X"))]
2747132718Skan  "TARGET_32BIT"
274890075Sobrien  "@
274990075Sobrien   and. %3,%1,%2
275090075Sobrien   {andil.|andi.} %3,%1,%b2
275190075Sobrien   {andiu.|andis.} %3,%1,%u2
275290075Sobrien   {rlinm.|rlwinm.} %3,%1,0,%m2,%M2
275390075Sobrien   #
275490075Sobrien   #
275590075Sobrien   #
275690075Sobrien   #"
275790075Sobrien  [(set_attr "type" "compare,compare,compare,delayed_compare,compare,compare,compare,compare")
275890075Sobrien   (set_attr "length" "4,4,4,4,8,8,8,8")])
275990075Sobrien
2760117395Skan(define_insn "*andsi3_internal3"
2761117395Skan  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,x,?y,??y,??y,?y")
2762117395Skan	(compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r")
2763117395Skan			    (match_operand:SI 2 "and_operand" "r,K,L,T,r,K,L,T"))
2764117395Skan		    (const_int 0)))
2765117395Skan   (clobber (match_scratch:SI 3 "=r,r,r,r,r,r,r,r"))
2766117395Skan   (clobber (match_scratch:CC 4 "=X,X,X,X,X,x,x,X"))]
2767132718Skan  "TARGET_64BIT"
2768117395Skan  "@
2769117395Skan   #
2770117395Skan   {andil.|andi.} %3,%1,%b2
2771117395Skan   {andiu.|andis.} %3,%1,%u2
2772117395Skan   {rlinm.|rlwinm.} %3,%1,0,%m2,%M2
2773117395Skan   #
2774117395Skan   #
2775117395Skan   #
2776117395Skan   #"
2777117395Skan  [(set_attr "type" "compare,compare,compare,delayed_compare,compare,compare,compare,compare")
2778117395Skan   (set_attr "length" "8,4,4,4,8,8,8,8")])
2779117395Skan
278090075Sobrien(define_split
278190075Sobrien  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
2782169689Skan	(compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
2783169689Skan			     (match_operand:GPR 2 "and_operand" ""))
278490075Sobrien		    (const_int 0)))
2785169689Skan   (clobber (match_scratch:GPR 3 ""))
278690075Sobrien   (clobber (match_scratch:CC 4 ""))]
2787117395Skan  "reload_completed"
278890075Sobrien  [(parallel [(set (match_dup 3)
2789169689Skan		   (and:<MODE> (match_dup 1)
2790169689Skan			       (match_dup 2)))
279190075Sobrien	      (clobber (match_dup 4))])
279290075Sobrien   (set (match_dup 0)
279390075Sobrien	(compare:CC (match_dup 3)
279490075Sobrien		    (const_int 0)))]
279590075Sobrien  "")
279690075Sobrien
2797117395Skan;; We don't have a 32 bit "and. rt,ra,rb" for ppc64.  cr is set from the
2798117395Skan;; whole 64 bit reg, and we don't know what is in the high 32 bits.
2799117395Skan
2800117395Skan(define_split
2801117395Skan  [(set (match_operand:CC 0 "cc_reg_operand" "")
2802117395Skan	(compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "")
2803117395Skan			    (match_operand:SI 2 "gpc_reg_operand" ""))
2804117395Skan		    (const_int 0)))
2805117395Skan   (clobber (match_scratch:SI 3 ""))
2806117395Skan   (clobber (match_scratch:CC 4 ""))]
2807117395Skan  "TARGET_POWERPC64 && reload_completed"
2808117395Skan  [(parallel [(set (match_dup 3)
2809117395Skan		   (and:SI (match_dup 1)
2810117395Skan			   (match_dup 2)))
2811117395Skan	      (clobber (match_dup 4))])
2812117395Skan   (set (match_dup 0)
2813117395Skan	(compare:CC (match_dup 3)
2814117395Skan		    (const_int 0)))]
2815117395Skan  "")
2816117395Skan
2817117395Skan(define_insn "*andsi3_internal4"
281890075Sobrien  [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,x,x,?y,??y,??y,?y")
281990075Sobrien	(compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r")
282090075Sobrien			    (match_operand:SI 2 "and_operand" "r,K,L,T,r,K,L,T"))
282190075Sobrien		    (const_int 0)))
282290075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r,r,r,r")
282390075Sobrien	(and:SI (match_dup 1)
282490075Sobrien		(match_dup 2)))
282590075Sobrien   (clobber (match_scratch:CC 4 "=X,X,X,X,X,x,x,X"))]
2826132718Skan  "TARGET_32BIT"
282790075Sobrien  "@
282890075Sobrien   and. %0,%1,%2
282990075Sobrien   {andil.|andi.} %0,%1,%b2
283090075Sobrien   {andiu.|andis.} %0,%1,%u2
283190075Sobrien   {rlinm.|rlwinm.} %0,%1,0,%m2,%M2
283290075Sobrien   #
283390075Sobrien   #
283490075Sobrien   #
283590075Sobrien   #"
283690075Sobrien  [(set_attr "type" "compare,compare,compare,delayed_compare,compare,compare,compare,compare")
283790075Sobrien   (set_attr "length" "4,4,4,4,8,8,8,8")])
283890075Sobrien
2839117395Skan(define_insn "*andsi3_internal5"
2840117395Skan  [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,x,x,?y,??y,??y,?y")
2841117395Skan	(compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r")
2842117395Skan			    (match_operand:SI 2 "and_operand" "r,K,L,T,r,K,L,T"))
2843117395Skan		    (const_int 0)))
2844117395Skan   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r,r,r,r")
2845117395Skan	(and:SI (match_dup 1)
2846117395Skan		(match_dup 2)))
2847117395Skan   (clobber (match_scratch:CC 4 "=X,X,X,X,X,x,x,X"))]
2848132718Skan  "TARGET_64BIT"
2849117395Skan  "@
2850117395Skan   #
2851117395Skan   {andil.|andi.} %0,%1,%b2
2852117395Skan   {andiu.|andis.} %0,%1,%u2
2853117395Skan   {rlinm.|rlwinm.} %0,%1,0,%m2,%M2
2854117395Skan   #
2855117395Skan   #
2856117395Skan   #
2857117395Skan   #"
2858117395Skan  [(set_attr "type" "compare,compare,compare,delayed_compare,compare,compare,compare,compare")
2859117395Skan   (set_attr "length" "8,4,4,4,8,8,8,8")])
2860117395Skan
286190075Sobrien(define_split
286290075Sobrien  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
286390075Sobrien	(compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "")
286490075Sobrien			    (match_operand:SI 2 "and_operand" ""))
286590075Sobrien		    (const_int 0)))
286690075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "")
286790075Sobrien	(and:SI (match_dup 1)
286890075Sobrien		(match_dup 2)))
286990075Sobrien   (clobber (match_scratch:CC 4 ""))]
2870117395Skan  "reload_completed"
287190075Sobrien  [(parallel [(set (match_dup 0)
287290075Sobrien		   (and:SI (match_dup 1)
287390075Sobrien			   (match_dup 2)))
287490075Sobrien	      (clobber (match_dup 4))])
287590075Sobrien   (set (match_dup 3)
287690075Sobrien	(compare:CC (match_dup 0)
287790075Sobrien		    (const_int 0)))]
287890075Sobrien  "")
287990075Sobrien
2880117395Skan(define_split
2881117395Skan  [(set (match_operand:CC 3 "cc_reg_operand" "")
2882117395Skan	(compare:CC (and:SI (match_operand:SI 1 "gpc_reg_operand" "")
2883117395Skan			    (match_operand:SI 2 "gpc_reg_operand" ""))
2884117395Skan		    (const_int 0)))
2885117395Skan   (set (match_operand:SI 0 "gpc_reg_operand" "")
2886117395Skan	(and:SI (match_dup 1)
2887117395Skan		(match_dup 2)))
2888117395Skan   (clobber (match_scratch:CC 4 ""))]
2889117395Skan  "TARGET_POWERPC64 && reload_completed"
2890117395Skan  [(parallel [(set (match_dup 0)
2891117395Skan		   (and:SI (match_dup 1)
2892117395Skan			   (match_dup 2)))
2893117395Skan	      (clobber (match_dup 4))])
2894117395Skan   (set (match_dup 3)
2895117395Skan	(compare:CC (match_dup 0)
2896117395Skan		    (const_int 0)))]
2897117395Skan  "")
2898117395Skan
2899117395Skan;; Handle the PowerPC64 rlwinm corner case
2900117395Skan
2901117395Skan(define_insn_and_split "*andsi3_internal6"
2902117395Skan  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2903117395Skan	(and:SI (match_operand:SI 1 "gpc_reg_operand" "r")
2904117395Skan		(match_operand:SI 2 "mask_operand_wrap" "i")))]
2905117395Skan  "TARGET_POWERPC64"
2906117395Skan  "#"
2907117395Skan  "TARGET_POWERPC64"
2908117395Skan  [(set (match_dup 0)
2909117395Skan	(and:SI (rotate:SI (match_dup 1) (match_dup 3))
2910117395Skan		(match_dup 4)))
2911117395Skan   (set (match_dup 0)
2912117395Skan	(rotate:SI (match_dup 0) (match_dup 5)))]
2913117395Skan  "
2914117395Skan{
2915117395Skan  int mb = extract_MB (operands[2]);
2916117395Skan  int me = extract_ME (operands[2]);
2917117395Skan  operands[3] = GEN_INT (me + 1);
2918117395Skan  operands[5] = GEN_INT (32 - (me + 1));
2919117395Skan  operands[4] = GEN_INT (~((HOST_WIDE_INT) -1 << (33 + me - mb)));
2920117395Skan}"
2921117395Skan  [(set_attr "length" "8")])
2922117395Skan
292390075Sobrien(define_expand "iorsi3"
292490075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "")
292590075Sobrien	(ior:SI (match_operand:SI 1 "gpc_reg_operand" "")
292690075Sobrien		(match_operand:SI 2 "reg_or_logical_cint_operand" "")))]
292790075Sobrien  ""
292890075Sobrien  "
292990075Sobrien{
293090075Sobrien  if (GET_CODE (operands[2]) == CONST_INT
293190075Sobrien      && ! logical_operand (operands[2], SImode))
293290075Sobrien    {
293390075Sobrien      HOST_WIDE_INT value = INTVAL (operands[2]);
293490075Sobrien      rtx tmp = ((no_new_pseudos || rtx_equal_p (operands[0], operands[1]))
293590075Sobrien		 ? operands[0] : gen_reg_rtx (SImode));
293690075Sobrien
293790075Sobrien      emit_insn (gen_iorsi3 (tmp, operands[1],
293890075Sobrien			     GEN_INT (value & (~ (HOST_WIDE_INT) 0xffff))));
293990075Sobrien      emit_insn (gen_iorsi3 (operands[0], tmp, GEN_INT (value & 0xffff)));
294090075Sobrien      DONE;
294190075Sobrien    }
294290075Sobrien}")
294390075Sobrien
294490075Sobrien(define_expand "xorsi3"
294590075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "")
294690075Sobrien	(xor:SI (match_operand:SI 1 "gpc_reg_operand" "")
294790075Sobrien		(match_operand:SI 2 "reg_or_logical_cint_operand" "")))]
294890075Sobrien  ""
294990075Sobrien  "
295090075Sobrien{
295190075Sobrien  if (GET_CODE (operands[2]) == CONST_INT
295290075Sobrien      && ! logical_operand (operands[2], SImode))
295390075Sobrien    {
295490075Sobrien      HOST_WIDE_INT value = INTVAL (operands[2]);
295590075Sobrien      rtx tmp = ((no_new_pseudos || rtx_equal_p (operands[0], operands[1]))
295690075Sobrien		 ? operands[0] : gen_reg_rtx (SImode));
295790075Sobrien
295890075Sobrien      emit_insn (gen_xorsi3 (tmp, operands[1],
295990075Sobrien			     GEN_INT (value & (~ (HOST_WIDE_INT) 0xffff))));
296090075Sobrien      emit_insn (gen_xorsi3 (operands[0], tmp, GEN_INT (value & 0xffff)));
296190075Sobrien      DONE;
296290075Sobrien    }
296390075Sobrien}")
296490075Sobrien
296590075Sobrien(define_insn "*boolsi3_internal1"
296690075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
296790075Sobrien	(match_operator:SI 3 "boolean_or_operator"
296890075Sobrien	 [(match_operand:SI 1 "gpc_reg_operand" "%r,r,r")
296990075Sobrien	  (match_operand:SI 2 "logical_operand" "r,K,L")]))]
297090075Sobrien  ""
297190075Sobrien  "@
297290075Sobrien   %q3 %0,%1,%2
297390075Sobrien   {%q3il|%q3i} %0,%1,%b2
297490075Sobrien   {%q3iu|%q3is} %0,%1,%u2")
297590075Sobrien
297690075Sobrien(define_insn "*boolsi3_internal2"
297790075Sobrien  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
297890075Sobrien	(compare:CC (match_operator:SI 4 "boolean_or_operator"
297990075Sobrien	 [(match_operand:SI 1 "gpc_reg_operand" "%r,r")
298090075Sobrien	  (match_operand:SI 2 "gpc_reg_operand" "r,r")])
298190075Sobrien	 (const_int 0)))
298290075Sobrien   (clobber (match_scratch:SI 3 "=r,r"))]
2983132718Skan  "TARGET_32BIT"
298490075Sobrien  "@
298590075Sobrien   %q4. %3,%1,%2
298690075Sobrien   #"
298790075Sobrien  [(set_attr "type" "compare")
298890075Sobrien   (set_attr "length" "4,8")])
298990075Sobrien
299090075Sobrien(define_split
299190075Sobrien  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
299290075Sobrien	(compare:CC (match_operator:SI 4 "boolean_operator"
299390075Sobrien	 [(match_operand:SI 1 "gpc_reg_operand" "")
299490075Sobrien	  (match_operand:SI 2 "gpc_reg_operand" "")])
299590075Sobrien	 (const_int 0)))
299690075Sobrien   (clobber (match_scratch:SI 3 ""))]
2997132718Skan  "TARGET_32BIT && reload_completed"
299890075Sobrien  [(set (match_dup 3) (match_dup 4))
299990075Sobrien   (set (match_dup 0)
300090075Sobrien	(compare:CC (match_dup 3)
300190075Sobrien		    (const_int 0)))]
300290075Sobrien  "")
300390075Sobrien
300490075Sobrien(define_insn "*boolsi3_internal3"
300590075Sobrien  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
300690075Sobrien	(compare:CC (match_operator:SI 4 "boolean_operator"
300790075Sobrien	 [(match_operand:SI 1 "gpc_reg_operand" "%r,r")
300890075Sobrien	  (match_operand:SI 2 "gpc_reg_operand" "r,r")])
300990075Sobrien	 (const_int 0)))
301090075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
301190075Sobrien	(match_dup 4))]
3012132718Skan  "TARGET_32BIT"
301390075Sobrien  "@
301490075Sobrien   %q4. %0,%1,%2
301590075Sobrien   #"
301690075Sobrien  [(set_attr "type" "compare")
301790075Sobrien   (set_attr "length" "4,8")])
301890075Sobrien
301990075Sobrien(define_split
302096263Sobrien  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
302190075Sobrien	(compare:CC (match_operator:SI 4 "boolean_operator"
302290075Sobrien	 [(match_operand:SI 1 "gpc_reg_operand" "")
302390075Sobrien	  (match_operand:SI 2 "gpc_reg_operand" "")])
302490075Sobrien	 (const_int 0)))
302590075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "")
302690075Sobrien	(match_dup 4))]
3027132718Skan  "TARGET_32BIT && reload_completed"
302890075Sobrien  [(set (match_dup 0) (match_dup 4))
302990075Sobrien   (set (match_dup 3)
303090075Sobrien	(compare:CC (match_dup 0)
303190075Sobrien		    (const_int 0)))]
303290075Sobrien  "")
303390075Sobrien
3034169689Skan;; Split a logical operation that we can't do in one insn into two insns,
303590075Sobrien;; each of which does one 16-bit part.  This is used by combine.
303690075Sobrien
303790075Sobrien(define_split
303890075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "")
303990075Sobrien	(match_operator:SI 3 "boolean_or_operator"
304090075Sobrien	 [(match_operand:SI 1 "gpc_reg_operand" "")
304190075Sobrien	  (match_operand:SI 2 "non_logical_cint_operand" "")]))]
304290075Sobrien  ""
304390075Sobrien  [(set (match_dup 0) (match_dup 4))
304490075Sobrien   (set (match_dup 0) (match_dup 5))]
304590075Sobrien"
304690075Sobrien{
304790075Sobrien  rtx i;
304890075Sobrien  i = GEN_INT (INTVAL (operands[2]) & (~ (HOST_WIDE_INT) 0xffff));
3049169689Skan  operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
3050169689Skan				operands[1], i);
305190075Sobrien  i = GEN_INT (INTVAL (operands[2]) & 0xffff);
3052169689Skan  operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
3053169689Skan				operands[0], i);
305490075Sobrien}")
305590075Sobrien
305690075Sobrien(define_insn "*boolcsi3_internal1"
305790075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
305890075Sobrien	(match_operator:SI 3 "boolean_operator"
305990075Sobrien	 [(not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
306090075Sobrien	  (match_operand:SI 2 "gpc_reg_operand" "r")]))]
306190075Sobrien  ""
306290075Sobrien  "%q3 %0,%2,%1")
306390075Sobrien
306490075Sobrien(define_insn "*boolcsi3_internal2"
306590075Sobrien  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
306690075Sobrien	(compare:CC (match_operator:SI 4 "boolean_operator"
306790075Sobrien	 [(not:SI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
306890075Sobrien	  (match_operand:SI 2 "gpc_reg_operand" "r,r")])
306990075Sobrien	 (const_int 0)))
307090075Sobrien   (clobber (match_scratch:SI 3 "=r,r"))]
3071132718Skan  "TARGET_32BIT"
307290075Sobrien  "@
307390075Sobrien   %q4. %3,%2,%1
307490075Sobrien   #"
307590075Sobrien  [(set_attr "type" "compare")
307690075Sobrien   (set_attr "length" "4,8")])
307790075Sobrien
307890075Sobrien(define_split
307990075Sobrien  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
308090075Sobrien	(compare:CC (match_operator:SI 4 "boolean_operator"
308190075Sobrien	 [(not:SI (match_operand:SI 1 "gpc_reg_operand" ""))
308290075Sobrien	  (match_operand:SI 2 "gpc_reg_operand" "")])
308390075Sobrien	 (const_int 0)))
308490075Sobrien   (clobber (match_scratch:SI 3 ""))]
3085132718Skan  "TARGET_32BIT && reload_completed"
308690075Sobrien  [(set (match_dup 3) (match_dup 4))
308790075Sobrien   (set (match_dup 0)
308890075Sobrien	(compare:CC (match_dup 3)
308990075Sobrien		    (const_int 0)))]
309090075Sobrien  "")
309190075Sobrien
309290075Sobrien(define_insn "*boolcsi3_internal3"
309390075Sobrien  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
309490075Sobrien	(compare:CC (match_operator:SI 4 "boolean_operator"
309590075Sobrien	 [(not:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r"))
309690075Sobrien	  (match_operand:SI 2 "gpc_reg_operand" "r,r")])
309790075Sobrien	 (const_int 0)))
309890075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
309990075Sobrien	(match_dup 4))]
3100132718Skan  "TARGET_32BIT"
310190075Sobrien  "@
310290075Sobrien   %q4. %0,%2,%1
310390075Sobrien   #"
310490075Sobrien  [(set_attr "type" "compare")
310590075Sobrien   (set_attr "length" "4,8")])
310690075Sobrien
310790075Sobrien(define_split
310896263Sobrien  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
310990075Sobrien	(compare:CC (match_operator:SI 4 "boolean_operator"
311090075Sobrien	 [(not:SI (match_operand:SI 1 "gpc_reg_operand" ""))
311190075Sobrien	  (match_operand:SI 2 "gpc_reg_operand" "")])
311290075Sobrien	 (const_int 0)))
311390075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "")
311490075Sobrien	(match_dup 4))]
3115132718Skan  "TARGET_32BIT && reload_completed"
311690075Sobrien  [(set (match_dup 0) (match_dup 4))
311790075Sobrien   (set (match_dup 3)
311890075Sobrien	(compare:CC (match_dup 0)
311990075Sobrien		    (const_int 0)))]
312090075Sobrien  "")
312190075Sobrien
312290075Sobrien(define_insn "*boolccsi3_internal1"
312390075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
312490075Sobrien	(match_operator:SI 3 "boolean_operator"
312590075Sobrien	 [(not:SI (match_operand:SI 1 "gpc_reg_operand" "r"))
312690075Sobrien	  (not:SI (match_operand:SI 2 "gpc_reg_operand" "r"))]))]
312790075Sobrien  ""
312890075Sobrien  "%q3 %0,%1,%2")
312990075Sobrien
313090075Sobrien(define_insn "*boolccsi3_internal2"
313190075Sobrien  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
313290075Sobrien	(compare:CC (match_operator:SI 4 "boolean_operator"
313390075Sobrien	 [(not:SI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
313490075Sobrien	  (not:SI (match_operand:SI 2 "gpc_reg_operand" "r,r"))])
313590075Sobrien	 (const_int 0)))
313690075Sobrien   (clobber (match_scratch:SI 3 "=r,r"))]
3137132718Skan  "TARGET_32BIT"
313890075Sobrien  "@
313990075Sobrien   %q4. %3,%1,%2
314090075Sobrien   #"
314190075Sobrien  [(set_attr "type" "compare")
314290075Sobrien   (set_attr "length" "4,8")])
314390075Sobrien
314490075Sobrien(define_split
314590075Sobrien  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
314690075Sobrien	(compare:CC (match_operator:SI 4 "boolean_operator"
314790075Sobrien	 [(not:SI (match_operand:SI 1 "gpc_reg_operand" ""))
314890075Sobrien	  (not:SI (match_operand:SI 2 "gpc_reg_operand" ""))])
314990075Sobrien	 (const_int 0)))
315090075Sobrien   (clobber (match_scratch:SI 3 ""))]
3151132718Skan  "TARGET_32BIT && reload_completed"
315290075Sobrien  [(set (match_dup 3) (match_dup 4))
315390075Sobrien   (set (match_dup 0)
315490075Sobrien	(compare:CC (match_dup 3)
315590075Sobrien		    (const_int 0)))]
315690075Sobrien  "")
315790075Sobrien
315890075Sobrien(define_insn "*boolccsi3_internal3"
315990075Sobrien  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
316090075Sobrien	(compare:CC (match_operator:SI 4 "boolean_operator"
316190075Sobrien	 [(not:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r"))
316290075Sobrien	  (not:SI (match_operand:SI 2 "gpc_reg_operand" "r,r"))])
316390075Sobrien	 (const_int 0)))
316490075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
316590075Sobrien	(match_dup 4))]
3166132718Skan  "TARGET_32BIT"
316790075Sobrien  "@
316890075Sobrien   %q4. %0,%1,%2
316990075Sobrien   #"
317090075Sobrien  [(set_attr "type" "compare")
317190075Sobrien   (set_attr "length" "4,8")])
317290075Sobrien
317390075Sobrien(define_split
317496263Sobrien  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
317590075Sobrien	(compare:CC (match_operator:SI 4 "boolean_operator"
317690075Sobrien	 [(not:SI (match_operand:SI 1 "gpc_reg_operand" ""))
317790075Sobrien	  (not:SI (match_operand:SI 2 "gpc_reg_operand" ""))])
317890075Sobrien	 (const_int 0)))
317990075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "")
318090075Sobrien	(match_dup 4))]
3181132718Skan  "TARGET_32BIT && reload_completed"
318290075Sobrien  [(set (match_dup 0) (match_dup 4))
318390075Sobrien   (set (match_dup 3)
318490075Sobrien	(compare:CC (match_dup 0)
318590075Sobrien		    (const_int 0)))]
318690075Sobrien  "")
318790075Sobrien
318890075Sobrien;; maskir insn.  We need four forms because things might be in arbitrary
318990075Sobrien;; orders.  Don't define forms that only set CR fields because these
319090075Sobrien;; would modify an input register.
319190075Sobrien
319290075Sobrien(define_insn "*maskir_internal1"
319390075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
319490075Sobrien	(ior:SI (and:SI (not:SI (match_operand:SI 2 "gpc_reg_operand" "r"))
319590075Sobrien			(match_operand:SI 1 "gpc_reg_operand" "0"))
319690075Sobrien		(and:SI (match_dup 2)
319790075Sobrien			(match_operand:SI 3 "gpc_reg_operand" "r"))))]
319890075Sobrien  "TARGET_POWER"
319990075Sobrien  "maskir %0,%3,%2")
320090075Sobrien
320190075Sobrien(define_insn "*maskir_internal2"
320290075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
320390075Sobrien	(ior:SI (and:SI (not:SI (match_operand:SI 2 "gpc_reg_operand" "r"))
320490075Sobrien			(match_operand:SI 1 "gpc_reg_operand" "0"))
320590075Sobrien		(and:SI (match_operand:SI 3 "gpc_reg_operand" "r")
320690075Sobrien			(match_dup 2))))]
320790075Sobrien  "TARGET_POWER"
320890075Sobrien  "maskir %0,%3,%2")
320990075Sobrien
321090075Sobrien(define_insn "*maskir_internal3"
321190075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
321290075Sobrien	(ior:SI (and:SI (match_operand:SI 2 "gpc_reg_operand" "r")
321390075Sobrien			(match_operand:SI 3 "gpc_reg_operand" "r"))
321490075Sobrien		(and:SI (not:SI (match_dup 2))
321590075Sobrien			(match_operand:SI 1 "gpc_reg_operand" "0"))))]
321690075Sobrien  "TARGET_POWER"
321790075Sobrien  "maskir %0,%3,%2")
321890075Sobrien
321990075Sobrien(define_insn "*maskir_internal4"
322090075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
322190075Sobrien	(ior:SI (and:SI (match_operand:SI 3 "gpc_reg_operand" "r")
322290075Sobrien			(match_operand:SI 2 "gpc_reg_operand" "r"))
322390075Sobrien		(and:SI (not:SI (match_dup 2))
322490075Sobrien			(match_operand:SI 1 "gpc_reg_operand" "0"))))]
322590075Sobrien  "TARGET_POWER"
322690075Sobrien  "maskir %0,%3,%2")
322790075Sobrien
322890075Sobrien(define_insn "*maskir_internal5"
322990075Sobrien  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
323090075Sobrien	(compare:CC
323190075Sobrien	 (ior:SI (and:SI (not:SI (match_operand:SI 2 "gpc_reg_operand" "r,r"))
323290075Sobrien			 (match_operand:SI 1 "gpc_reg_operand" "0,0"))
323390075Sobrien		 (and:SI (match_dup 2)
323490075Sobrien			 (match_operand:SI 3 "gpc_reg_operand" "r,r")))
323590075Sobrien	 (const_int 0)))
323690075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
323790075Sobrien	(ior:SI (and:SI (not:SI (match_dup 2)) (match_dup 1))
323890075Sobrien		(and:SI (match_dup 2) (match_dup 3))))]
323990075Sobrien  "TARGET_POWER"
324090075Sobrien  "@
324190075Sobrien   maskir. %0,%3,%2
324290075Sobrien   #"
324390075Sobrien  [(set_attr "type" "compare")
324490075Sobrien   (set_attr "length" "4,8")])
324590075Sobrien
324690075Sobrien(define_split
324790075Sobrien  [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
324890075Sobrien	(compare:CC
324990075Sobrien	 (ior:SI (and:SI (not:SI (match_operand:SI 2 "gpc_reg_operand" ""))
325090075Sobrien			 (match_operand:SI 1 "gpc_reg_operand" ""))
325190075Sobrien		 (and:SI (match_dup 2)
325290075Sobrien			 (match_operand:SI 3 "gpc_reg_operand" "")))
325390075Sobrien	 (const_int 0)))
325490075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "")
325590075Sobrien	(ior:SI (and:SI (not:SI (match_dup 2)) (match_dup 1))
325690075Sobrien		(and:SI (match_dup 2) (match_dup 3))))]
325790075Sobrien  "TARGET_POWER && reload_completed"
325890075Sobrien  [(set (match_dup 0)
325990075Sobrien	(ior:SI (and:SI (not:SI (match_dup 2)) (match_dup 1))
326090075Sobrien		(and:SI (match_dup 2) (match_dup 3))))
326190075Sobrien   (set (match_dup 4)
326290075Sobrien	(compare:CC (match_dup 0)
326390075Sobrien		    (const_int 0)))]
326490075Sobrien  "")
326590075Sobrien
326690075Sobrien(define_insn "*maskir_internal6"
326790075Sobrien  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
326890075Sobrien	(compare:CC
326990075Sobrien	 (ior:SI (and:SI (not:SI (match_operand:SI 2 "gpc_reg_operand" "r,r"))
327090075Sobrien			 (match_operand:SI 1 "gpc_reg_operand" "0,0"))
327190075Sobrien		 (and:SI (match_operand:SI 3 "gpc_reg_operand" "r,r")
327290075Sobrien			 (match_dup 2)))
327390075Sobrien	 (const_int 0)))
327490075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
327590075Sobrien	(ior:SI (and:SI (not:SI (match_dup 2)) (match_dup 1))
327690075Sobrien		(and:SI (match_dup 3) (match_dup 2))))]
327790075Sobrien  "TARGET_POWER"
327890075Sobrien  "@
327990075Sobrien   maskir. %0,%3,%2
328090075Sobrien   #"
328190075Sobrien  [(set_attr "type" "compare")
328290075Sobrien   (set_attr "length" "4,8")])
328390075Sobrien
328490075Sobrien(define_split
328590075Sobrien  [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
328690075Sobrien	(compare:CC
328790075Sobrien	 (ior:SI (and:SI (not:SI (match_operand:SI 2 "gpc_reg_operand" ""))
328890075Sobrien			 (match_operand:SI 1 "gpc_reg_operand" ""))
328990075Sobrien		 (and:SI (match_operand:SI 3 "gpc_reg_operand" "")
329090075Sobrien			 (match_dup 2)))
329190075Sobrien	 (const_int 0)))
329290075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "")
329390075Sobrien	(ior:SI (and:SI (not:SI (match_dup 2)) (match_dup 1))
329490075Sobrien		(and:SI (match_dup 3) (match_dup 2))))]
329590075Sobrien  "TARGET_POWER && reload_completed"
329690075Sobrien  [(set (match_dup 0)
329790075Sobrien	(ior:SI (and:SI (not:SI (match_dup 2)) (match_dup 1))
329890075Sobrien		(and:SI (match_dup 3) (match_dup 2))))
329990075Sobrien   (set (match_dup 4)
330090075Sobrien	(compare:CC (match_dup 0)
330190075Sobrien		    (const_int 0)))]
330290075Sobrien  "")
330390075Sobrien
330490075Sobrien(define_insn "*maskir_internal7"
330590075Sobrien  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
330690075Sobrien	(compare:CC
330790075Sobrien	 (ior:SI (and:SI (match_operand:SI 2 "gpc_reg_operand" "r,r")
330890075Sobrien			 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
330990075Sobrien		 (and:SI (not:SI (match_dup 2))
331090075Sobrien			 (match_operand:SI 1 "gpc_reg_operand" "0,0")))
331190075Sobrien	 (const_int 0)))
331290075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
331390075Sobrien	(ior:SI (and:SI (match_dup 2) (match_dup 3))
331490075Sobrien		(and:SI (not:SI (match_dup 2)) (match_dup 1))))]
331590075Sobrien  "TARGET_POWER"
331690075Sobrien  "@
331790075Sobrien   maskir. %0,%3,%2
331890075Sobrien   #"
331990075Sobrien  [(set_attr "type" "compare")
332090075Sobrien   (set_attr "length" "4,8")])
332190075Sobrien
332290075Sobrien(define_split
332390075Sobrien  [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
332490075Sobrien	(compare:CC
332590075Sobrien	 (ior:SI (and:SI (match_operand:SI 2 "gpc_reg_operand" "")
332690075Sobrien			 (match_operand:SI 3 "gpc_reg_operand" ""))
332790075Sobrien		 (and:SI (not:SI (match_dup 2))
332890075Sobrien			 (match_operand:SI 1 "gpc_reg_operand" "")))
332990075Sobrien	 (const_int 0)))
333090075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "")
333190075Sobrien	(ior:SI (and:SI (match_dup 2) (match_dup 3))
333290075Sobrien		(and:SI (not:SI (match_dup 2)) (match_dup 1))))]
333390075Sobrien  "TARGET_POWER && reload_completed"
333490075Sobrien  [(set (match_dup 0)
333590075Sobrien	(ior:SI (and:SI (match_dup 2) (match_dup 3))
333690075Sobrien		(and:SI (not:SI (match_dup 2)) (match_dup 1))))
333790075Sobrien   (set (match_dup 4)
333890075Sobrien	(compare:CC (match_dup 0)
333990075Sobrien		    (const_int 0)))]
334090075Sobrien  "")
334190075Sobrien
334290075Sobrien(define_insn "*maskir_internal8"
334390075Sobrien  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
334490075Sobrien	(compare:CC
334590075Sobrien	 (ior:SI (and:SI (match_operand:SI 3 "gpc_reg_operand" "r,r")
334690075Sobrien			 (match_operand:SI 2 "gpc_reg_operand" "r,r"))
334790075Sobrien		 (and:SI (not:SI (match_dup 2))
334890075Sobrien			 (match_operand:SI 1 "gpc_reg_operand" "0,0")))
334990075Sobrien	 (const_int 0)))
335090075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
335190075Sobrien	(ior:SI (and:SI (match_dup 3) (match_dup 2))
335290075Sobrien		(and:SI (not:SI (match_dup 2)) (match_dup 1))))]
335390075Sobrien  "TARGET_POWER"
335490075Sobrien  "@
335590075Sobrien   maskir. %0,%3,%2
335690075Sobrien   #"
335790075Sobrien  [(set_attr "type" "compare")
335890075Sobrien   (set_attr "length" "4,8")])
3359117395Skan
336090075Sobrien(define_split
336190075Sobrien  [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
336290075Sobrien	(compare:CC
336390075Sobrien	 (ior:SI (and:SI (match_operand:SI 3 "gpc_reg_operand" "")
336490075Sobrien			 (match_operand:SI 2 "gpc_reg_operand" ""))
336590075Sobrien		 (and:SI (not:SI (match_dup 2))
336690075Sobrien			 (match_operand:SI 1 "gpc_reg_operand" "")))
336790075Sobrien	 (const_int 0)))
336890075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "")
336990075Sobrien	(ior:SI (and:SI (match_dup 3) (match_dup 2))
337090075Sobrien		(and:SI (not:SI (match_dup 2)) (match_dup 1))))]
337190075Sobrien  "TARGET_POWER && reload_completed"
337290075Sobrien  [(set (match_dup 0)
337390075Sobrien	(ior:SI (and:SI (match_dup 3) (match_dup 2))
337490075Sobrien		(and:SI (not:SI (match_dup 2)) (match_dup 1))))
337590075Sobrien   (set (match_dup 4)
337690075Sobrien	(compare:CC (match_dup 0)
337790075Sobrien		    (const_int 0)))]
337890075Sobrien  "")
3379117395Skan
338090075Sobrien;; Rotate and shift insns, in all their variants.  These support shifts,
338190075Sobrien;; field inserts and extracts, and various combinations thereof.
338290075Sobrien(define_expand "insv"
338390075Sobrien  [(set (zero_extract (match_operand 0 "gpc_reg_operand" "")
338490075Sobrien		       (match_operand:SI 1 "const_int_operand" "")
338590075Sobrien		       (match_operand:SI 2 "const_int_operand" ""))
338690075Sobrien	(match_operand 3 "gpc_reg_operand" ""))]
338790075Sobrien  ""
338890075Sobrien  "
338990075Sobrien{
339090075Sobrien  /* Do not handle 16/8 bit structures that fit in HI/QI modes directly, since
339190075Sobrien     the (SUBREG:SI (REG:HI xxx)) that is otherwise generated can confuse the
3392169689Skan     compiler if the address of the structure is taken later.  Likewise, do
3393169689Skan     not handle invalid E500 subregs.  */
339490075Sobrien  if (GET_CODE (operands[0]) == SUBREG
3395169689Skan      && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (operands[0]))) < UNITS_PER_WORD
3396169689Skan	  || ((TARGET_E500_DOUBLE || TARGET_SPE)
3397169689Skan	      && invalid_e500_subreg (operands[0], GET_MODE (operands[0])))))
339890075Sobrien    FAIL;
339990075Sobrien
340090075Sobrien  if (TARGET_POWERPC64 && GET_MODE (operands[0]) == DImode)
340190075Sobrien    emit_insn (gen_insvdi (operands[0], operands[1], operands[2], operands[3]));
340290075Sobrien  else
340390075Sobrien    emit_insn (gen_insvsi (operands[0], operands[1], operands[2], operands[3]));
340490075Sobrien  DONE;
340590075Sobrien}")
340690075Sobrien
340790075Sobrien(define_insn "insvsi"
340890075Sobrien  [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
340990075Sobrien			 (match_operand:SI 1 "const_int_operand" "i")
341090075Sobrien			 (match_operand:SI 2 "const_int_operand" "i"))
341190075Sobrien	(match_operand:SI 3 "gpc_reg_operand" "r"))]
341290075Sobrien  ""
341390075Sobrien  "*
341490075Sobrien{
341590075Sobrien  int start = INTVAL (operands[2]) & 31;
341690075Sobrien  int size = INTVAL (operands[1]) & 31;
341790075Sobrien
341890075Sobrien  operands[4] = GEN_INT (32 - start - size);
341990075Sobrien  operands[1] = GEN_INT (start + size - 1);
342090075Sobrien  return \"{rlimi|rlwimi} %0,%3,%h4,%h2,%h1\";
3421132718Skan}"
3422132718Skan  [(set_attr "type" "insert_word")])
342390075Sobrien
342490075Sobrien(define_insn "*insvsi_internal1"
342590075Sobrien  [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
342690075Sobrien			 (match_operand:SI 1 "const_int_operand" "i")
342790075Sobrien			 (match_operand:SI 2 "const_int_operand" "i"))
3428169689Skan	(rotate:SI (match_operand:SI 3 "gpc_reg_operand" "r")
342990075Sobrien		   (match_operand:SI 4 "const_int_operand" "i")))]
343090075Sobrien  "(32 - (INTVAL (operands[4]) & 31)) >= INTVAL (operands[1])"
343190075Sobrien  "*
343290075Sobrien{
343390075Sobrien  int shift = INTVAL (operands[4]) & 31;
343490075Sobrien  int start = INTVAL (operands[2]) & 31;
343590075Sobrien  int size = INTVAL (operands[1]) & 31;
343690075Sobrien
343790075Sobrien  operands[4] = GEN_INT (shift - start - size);
343890075Sobrien  operands[1] = GEN_INT (start + size - 1);
343990075Sobrien  return \"{rlimi|rlwimi} %0,%3,%h4,%h2,%h1\";
3440132718Skan}"
3441132718Skan  [(set_attr "type" "insert_word")])
344290075Sobrien
344390075Sobrien(define_insn "*insvsi_internal2"
344490075Sobrien  [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
344590075Sobrien			 (match_operand:SI 1 "const_int_operand" "i")
344690075Sobrien			 (match_operand:SI 2 "const_int_operand" "i"))
344790075Sobrien	(ashiftrt:SI (match_operand:SI 3 "gpc_reg_operand" "r")
344890075Sobrien		     (match_operand:SI 4 "const_int_operand" "i")))]
344990075Sobrien  "(32 - (INTVAL (operands[4]) & 31)) >= INTVAL (operands[1])"
345090075Sobrien  "*
345190075Sobrien{
345290075Sobrien  int shift = INTVAL (operands[4]) & 31;
345390075Sobrien  int start = INTVAL (operands[2]) & 31;
345490075Sobrien  int size = INTVAL (operands[1]) & 31;
345590075Sobrien
345690075Sobrien  operands[4] = GEN_INT (32 - shift - start - size);
345790075Sobrien  operands[1] = GEN_INT (start + size - 1);
345890075Sobrien  return \"{rlimi|rlwimi} %0,%3,%h4,%h2,%h1\";
3459132718Skan}"
3460132718Skan  [(set_attr "type" "insert_word")])
346190075Sobrien
346290075Sobrien(define_insn "*insvsi_internal3"
346390075Sobrien  [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
346490075Sobrien			 (match_operand:SI 1 "const_int_operand" "i")
346590075Sobrien			 (match_operand:SI 2 "const_int_operand" "i"))
346690075Sobrien	(lshiftrt:SI (match_operand:SI 3 "gpc_reg_operand" "r")
346790075Sobrien		     (match_operand:SI 4 "const_int_operand" "i")))]
346890075Sobrien  "(32 - (INTVAL (operands[4]) & 31)) >= INTVAL (operands[1])"
346990075Sobrien  "*
347090075Sobrien{
347190075Sobrien  int shift = INTVAL (operands[4]) & 31;
347290075Sobrien  int start = INTVAL (operands[2]) & 31;
347390075Sobrien  int size = INTVAL (operands[1]) & 31;
347490075Sobrien
347590075Sobrien  operands[4] = GEN_INT (32 - shift - start - size);
347690075Sobrien  operands[1] = GEN_INT (start + size - 1);
347790075Sobrien  return \"{rlimi|rlwimi} %0,%3,%h4,%h2,%h1\";
3478132718Skan}"
3479132718Skan  [(set_attr "type" "insert_word")])
348090075Sobrien
348190075Sobrien(define_insn "*insvsi_internal4"
348290075Sobrien  [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
348390075Sobrien			 (match_operand:SI 1 "const_int_operand" "i")
348490075Sobrien			 (match_operand:SI 2 "const_int_operand" "i"))
348590075Sobrien	(zero_extract:SI (match_operand:SI 3 "gpc_reg_operand" "r")
348690075Sobrien			 (match_operand:SI 4 "const_int_operand" "i")
348790075Sobrien			 (match_operand:SI 5 "const_int_operand" "i")))]
348890075Sobrien  "INTVAL (operands[4]) >= INTVAL (operands[1])"
348990075Sobrien  "*
349090075Sobrien{
349190075Sobrien  int extract_start = INTVAL (operands[5]) & 31;
349290075Sobrien  int extract_size = INTVAL (operands[4]) & 31;
349390075Sobrien  int insert_start = INTVAL (operands[2]) & 31;
349490075Sobrien  int insert_size = INTVAL (operands[1]) & 31;
349590075Sobrien
349690075Sobrien/* Align extract field with insert field */
349790075Sobrien  operands[5] = GEN_INT (extract_start + extract_size - insert_start - insert_size);
349890075Sobrien  operands[1] = GEN_INT (insert_start + insert_size - 1);
349990075Sobrien  return \"{rlimi|rlwimi} %0,%3,%h5,%h2,%h1\";
3500132718Skan}"
3501132718Skan  [(set_attr "type" "insert_word")])
350290075Sobrien
3503169689Skan;; combine patterns for rlwimi
3504169689Skan(define_insn "*insvsi_internal5"
3505169689Skan  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3506169689Skan        (ior:SI (and:SI (match_operand:SI 4 "gpc_reg_operand" "0")
3507169689Skan                        (match_operand:SI 1 "mask_operand" "i"))
3508169689Skan                (and:SI (lshiftrt:SI (match_operand:SI 3 "gpc_reg_operand" "r")
3509169689Skan                                     (match_operand:SI 2 "const_int_operand" "i"))
3510169689Skan                        (match_operand:SI 5 "mask_operand" "i"))))]
3511169689Skan  "TARGET_POWERPC && INTVAL(operands[1]) == ~INTVAL(operands[5])"
3512169689Skan  "*
3513169689Skan{
3514169689Skan int me = extract_ME(operands[5]);
3515169689Skan int mb = extract_MB(operands[5]);
3516169689Skan operands[4] = GEN_INT(32 - INTVAL(operands[2]));
3517169689Skan operands[2] = GEN_INT(mb);
3518169689Skan operands[1] = GEN_INT(me);
3519169689Skan return \"{rlimi|rlwimi} %0,%3,%h4,%h2,%h1\";
3520169689Skan}"
3521169689Skan  [(set_attr "type" "insert_word")])
3522169689Skan
3523169689Skan(define_insn "*insvsi_internal6"
3524169689Skan  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3525169689Skan        (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 3 "gpc_reg_operand" "r")
3526169689Skan                                     (match_operand:SI 2 "const_int_operand" "i"))
3527169689Skan                        (match_operand:SI 5 "mask_operand" "i"))
3528169689Skan                (and:SI (match_operand:SI 4 "gpc_reg_operand" "0")
3529169689Skan                        (match_operand:SI 1 "mask_operand" "i"))))]
3530169689Skan  "TARGET_POWERPC && INTVAL(operands[1]) == ~INTVAL(operands[5])"
3531169689Skan  "*
3532169689Skan{
3533169689Skan int me = extract_ME(operands[5]);
3534169689Skan int mb = extract_MB(operands[5]);
3535169689Skan operands[4] = GEN_INT(32 - INTVAL(operands[2]));
3536169689Skan operands[2] = GEN_INT(mb);
3537169689Skan operands[1] = GEN_INT(me);
3538169689Skan return \"{rlimi|rlwimi} %0,%3,%h4,%h2,%h1\";
3539169689Skan}"
3540169689Skan  [(set_attr "type" "insert_word")])
3541169689Skan
354290075Sobrien(define_insn "insvdi"
354390075Sobrien  [(set (zero_extract:DI (match_operand:DI 0 "gpc_reg_operand" "+r")
354490075Sobrien			 (match_operand:SI 1 "const_int_operand" "i")
354590075Sobrien			 (match_operand:SI 2 "const_int_operand" "i"))
354690075Sobrien	(match_operand:DI 3 "gpc_reg_operand" "r"))]
354790075Sobrien  "TARGET_POWERPC64"
354890075Sobrien  "*
354990075Sobrien{
355090075Sobrien  int start = INTVAL (operands[2]) & 63;
355190075Sobrien  int size = INTVAL (operands[1]) & 63;
355290075Sobrien
355390075Sobrien  operands[1] = GEN_INT (64 - start - size);
355490075Sobrien  return \"rldimi %0,%3,%H1,%H2\";
355590075Sobrien}")
355690075Sobrien
3557169689Skan(define_insn "*insvdi_internal2"
3558169689Skan  [(set (zero_extract:DI (match_operand:DI 0 "gpc_reg_operand" "+r")
3559169689Skan			 (match_operand:SI 1 "const_int_operand" "i")
3560169689Skan			 (match_operand:SI 2 "const_int_operand" "i"))
3561169689Skan	(ashiftrt:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3562169689Skan		     (match_operand:SI 4 "const_int_operand" "i")))]
3563169689Skan  "TARGET_POWERPC64
3564169689Skan   && insvdi_rshift_rlwimi_p (operands[1], operands[2], operands[4])"
3565169689Skan  "*
3566169689Skan{
3567169689Skan  int shift = INTVAL (operands[4]) & 63;
3568169689Skan  int start = (INTVAL (operands[2]) & 63) - 32;
3569169689Skan  int size = INTVAL (operands[1]) & 63;
3570169689Skan
3571169689Skan  operands[4] = GEN_INT (64 - shift - start - size);
3572169689Skan  operands[2] = GEN_INT (start);
3573169689Skan  operands[1] = GEN_INT (start + size - 1);
3574169689Skan  return \"rlwimi %0,%3,%h4,%h2,%h1\";
3575169689Skan}")
3576169689Skan
3577169689Skan(define_insn "*insvdi_internal3"
3578169689Skan  [(set (zero_extract:DI (match_operand:DI 0 "gpc_reg_operand" "+r")
3579169689Skan			 (match_operand:SI 1 "const_int_operand" "i")
3580169689Skan			 (match_operand:SI 2 "const_int_operand" "i"))
3581169689Skan	(lshiftrt:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3582169689Skan		     (match_operand:SI 4 "const_int_operand" "i")))]
3583169689Skan  "TARGET_POWERPC64
3584169689Skan   && insvdi_rshift_rlwimi_p (operands[1], operands[2], operands[4])"
3585169689Skan  "*
3586169689Skan{
3587169689Skan  int shift = INTVAL (operands[4]) & 63;
3588169689Skan  int start = (INTVAL (operands[2]) & 63) - 32;
3589169689Skan  int size = INTVAL (operands[1]) & 63;
3590169689Skan
3591169689Skan  operands[4] = GEN_INT (64 - shift - start - size);
3592169689Skan  operands[2] = GEN_INT (start);
3593169689Skan  operands[1] = GEN_INT (start + size - 1);
3594169689Skan  return \"rlwimi %0,%3,%h4,%h2,%h1\";
3595169689Skan}")
3596169689Skan
359790075Sobrien(define_expand "extzv"
359890075Sobrien  [(set (match_operand 0 "gpc_reg_operand" "")
359990075Sobrien	(zero_extract (match_operand 1 "gpc_reg_operand" "")
360090075Sobrien		       (match_operand:SI 2 "const_int_operand" "")
360190075Sobrien		       (match_operand:SI 3 "const_int_operand" "")))]
360290075Sobrien  ""
360390075Sobrien  "
360490075Sobrien{
360590075Sobrien  /* Do not handle 16/8 bit structures that fit in HI/QI modes directly, since
360690075Sobrien     the (SUBREG:SI (REG:HI xxx)) that is otherwise generated can confuse the
360790075Sobrien     compiler if the address of the structure is taken later.  */
360890075Sobrien  if (GET_CODE (operands[0]) == SUBREG
360990075Sobrien      && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (operands[0]))) < UNITS_PER_WORD))
361090075Sobrien    FAIL;
361190075Sobrien
361290075Sobrien  if (TARGET_POWERPC64 && GET_MODE (operands[1]) == DImode)
361390075Sobrien    emit_insn (gen_extzvdi (operands[0], operands[1], operands[2], operands[3]));
361490075Sobrien  else
361590075Sobrien    emit_insn (gen_extzvsi (operands[0], operands[1], operands[2], operands[3]));
361690075Sobrien  DONE;
361790075Sobrien}")
361890075Sobrien
361990075Sobrien(define_insn "extzvsi"
362090075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
362190075Sobrien	(zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r")
362290075Sobrien			 (match_operand:SI 2 "const_int_operand" "i")
362390075Sobrien			 (match_operand:SI 3 "const_int_operand" "i")))]
362490075Sobrien  ""
362590075Sobrien  "*
362690075Sobrien{
362790075Sobrien  int start = INTVAL (operands[3]) & 31;
362890075Sobrien  int size = INTVAL (operands[2]) & 31;
362990075Sobrien
363090075Sobrien  if (start + size >= 32)
363190075Sobrien    operands[3] = const0_rtx;
363290075Sobrien  else
363390075Sobrien    operands[3] = GEN_INT (start + size);
363490075Sobrien  return \"{rlinm|rlwinm} %0,%1,%3,%s2,31\";
363590075Sobrien}")
363690075Sobrien
363790075Sobrien(define_insn "*extzvsi_internal1"
363890075Sobrien  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
363990075Sobrien	(compare:CC (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
364090075Sobrien			 (match_operand:SI 2 "const_int_operand" "i,i")
364190075Sobrien			 (match_operand:SI 3 "const_int_operand" "i,i"))
364290075Sobrien		    (const_int 0)))
364390075Sobrien   (clobber (match_scratch:SI 4 "=r,r"))]
3644117395Skan  ""
364590075Sobrien  "*
364690075Sobrien{
364790075Sobrien  int start = INTVAL (operands[3]) & 31;
364890075Sobrien  int size = INTVAL (operands[2]) & 31;
364990075Sobrien
365090075Sobrien  /* Force split for non-cc0 compare.  */
365190075Sobrien  if (which_alternative == 1)
365290075Sobrien     return \"#\";
365390075Sobrien
3654117395Skan  /* If the bit-field being tested fits in the upper or lower half of a
365590075Sobrien     word, it is possible to use andiu. or andil. to test it.  This is
365690075Sobrien     useful because the condition register set-use delay is smaller for
365790075Sobrien     andi[ul]. than for rlinm.  This doesn't work when the starting bit
365890075Sobrien     position is 0 because the LT and GT bits may be set wrong.  */
365990075Sobrien
366090075Sobrien  if ((start > 0 && start + size <= 16) || start >= 16)
366190075Sobrien    {
366290075Sobrien      operands[3] = GEN_INT (((1 << (16 - (start & 15)))
366390075Sobrien			      - (1 << (16 - (start & 15) - size))));
366490075Sobrien      if (start < 16)
366590075Sobrien	return \"{andiu.|andis.} %4,%1,%3\";
366690075Sobrien      else
366790075Sobrien	return \"{andil.|andi.} %4,%1,%3\";
366890075Sobrien    }
366990075Sobrien
367090075Sobrien  if (start + size >= 32)
367190075Sobrien    operands[3] = const0_rtx;
367290075Sobrien  else
367390075Sobrien    operands[3] = GEN_INT (start + size);
367490075Sobrien  return \"{rlinm.|rlwinm.} %4,%1,%3,%s2,31\";
367590075Sobrien}"
367690075Sobrien  [(set_attr "type" "compare")
367790075Sobrien   (set_attr "length" "4,8")])
367890075Sobrien
367990075Sobrien(define_split
368090075Sobrien  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
368190075Sobrien	(compare:CC (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "")
368290075Sobrien			 (match_operand:SI 2 "const_int_operand" "")
368390075Sobrien			 (match_operand:SI 3 "const_int_operand" ""))
368490075Sobrien		    (const_int 0)))
368590075Sobrien   (clobber (match_scratch:SI 4 ""))]
3686117395Skan  "reload_completed"
368790075Sobrien  [(set (match_dup 4)
368890075Sobrien	(zero_extract:SI (match_dup 1) (match_dup 2)
368990075Sobrien			 (match_dup 3)))
369090075Sobrien   (set (match_dup 0)
369190075Sobrien	(compare:CC (match_dup 4)
369290075Sobrien		    (const_int 0)))]
369390075Sobrien  "")
369490075Sobrien
369590075Sobrien(define_insn "*extzvsi_internal2"
369690075Sobrien  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
369790075Sobrien	(compare:CC (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
369890075Sobrien			 (match_operand:SI 2 "const_int_operand" "i,i")
369990075Sobrien			 (match_operand:SI 3 "const_int_operand" "i,i"))
370090075Sobrien		    (const_int 0)))
370190075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
370290075Sobrien	(zero_extract:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
3703117395Skan  ""
370490075Sobrien  "*
370590075Sobrien{
370690075Sobrien  int start = INTVAL (operands[3]) & 31;
370790075Sobrien  int size = INTVAL (operands[2]) & 31;
370890075Sobrien
370990075Sobrien  /* Force split for non-cc0 compare.  */
371090075Sobrien  if (which_alternative == 1)
371190075Sobrien     return \"#\";
371290075Sobrien
3713117395Skan  /* Since we are using the output value, we can't ignore any need for
3714117395Skan     a shift.  The bit-field must end at the LSB.  */
371590075Sobrien  if (start >= 16 && start + size == 32)
371690075Sobrien    {
3717117395Skan      operands[3] = GEN_INT ((1 << size) - 1);
371890075Sobrien      return \"{andil.|andi.} %0,%1,%3\";
371990075Sobrien    }
372090075Sobrien
372190075Sobrien  if (start + size >= 32)
372290075Sobrien    operands[3] = const0_rtx;
372390075Sobrien  else
372490075Sobrien    operands[3] = GEN_INT (start + size);
372590075Sobrien  return \"{rlinm.|rlwinm.} %0,%1,%3,%s2,31\";
372690075Sobrien}"
3727117395Skan  [(set_attr "type" "compare")
372890075Sobrien   (set_attr "length" "4,8")])
372990075Sobrien
373090075Sobrien(define_split
373190075Sobrien  [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
373290075Sobrien	(compare:CC (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "")
373390075Sobrien			 (match_operand:SI 2 "const_int_operand" "")
373490075Sobrien			 (match_operand:SI 3 "const_int_operand" ""))
373590075Sobrien		    (const_int 0)))
373690075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "")
373790075Sobrien	(zero_extract:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
3738117395Skan  "reload_completed"
373990075Sobrien  [(set (match_dup 0)
374090075Sobrien	(zero_extract:SI (match_dup 1) (match_dup 2) (match_dup 3)))
374190075Sobrien   (set (match_dup 4)
374290075Sobrien	(compare:CC (match_dup 0)
374390075Sobrien		    (const_int 0)))]
374490075Sobrien  "")
374590075Sobrien
374690075Sobrien(define_insn "extzvdi"
374790075Sobrien  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
374890075Sobrien	(zero_extract:DI (match_operand:DI 1 "gpc_reg_operand" "r")
374990075Sobrien			 (match_operand:SI 2 "const_int_operand" "i")
375090075Sobrien			 (match_operand:SI 3 "const_int_operand" "i")))]
375190075Sobrien  "TARGET_POWERPC64"
375290075Sobrien  "*
375390075Sobrien{
375490075Sobrien  int start = INTVAL (operands[3]) & 63;
375590075Sobrien  int size = INTVAL (operands[2]) & 63;
375690075Sobrien
375790075Sobrien  if (start + size >= 64)
375890075Sobrien    operands[3] = const0_rtx;
375990075Sobrien  else
376090075Sobrien    operands[3] = GEN_INT (start + size);
376190075Sobrien  operands[2] = GEN_INT (64 - size);
376290075Sobrien  return \"rldicl %0,%1,%3,%2\";
376390075Sobrien}")
376490075Sobrien
376590075Sobrien(define_insn "*extzvdi_internal1"
376690075Sobrien  [(set (match_operand:CC 0 "gpc_reg_operand" "=x")
376790075Sobrien	(compare:CC (zero_extract:DI (match_operand:DI 1 "gpc_reg_operand" "r")
376890075Sobrien			 (match_operand:SI 2 "const_int_operand" "i")
376990075Sobrien			 (match_operand:SI 3 "const_int_operand" "i"))
377090075Sobrien		    (const_int 0)))
377190075Sobrien   (clobber (match_scratch:DI 4 "=r"))]
3772132718Skan  "TARGET_64BIT"
377390075Sobrien  "*
377490075Sobrien{
377590075Sobrien  int start = INTVAL (operands[3]) & 63;
377690075Sobrien  int size = INTVAL (operands[2]) & 63;
377790075Sobrien
377890075Sobrien  if (start + size >= 64)
377990075Sobrien    operands[3] = const0_rtx;
378090075Sobrien  else
378190075Sobrien    operands[3] = GEN_INT (start + size);
378290075Sobrien  operands[2] = GEN_INT (64 - size);
378390075Sobrien  return \"rldicl. %4,%1,%3,%2\";
3784169689Skan}"
3785169689Skan  [(set_attr "type" "compare")])
378690075Sobrien
378790075Sobrien(define_insn "*extzvdi_internal2"
378890075Sobrien  [(set (match_operand:CC 4 "gpc_reg_operand" "=x")
378990075Sobrien	(compare:CC (zero_extract:DI (match_operand:DI 1 "gpc_reg_operand" "r")
379090075Sobrien			 (match_operand:SI 2 "const_int_operand" "i")
379190075Sobrien			 (match_operand:SI 3 "const_int_operand" "i"))
379290075Sobrien		    (const_int 0)))
379390075Sobrien   (set (match_operand:DI 0 "gpc_reg_operand" "=r")
379490075Sobrien	(zero_extract:DI (match_dup 1) (match_dup 2) (match_dup 3)))]
3795132718Skan  "TARGET_64BIT"
379690075Sobrien  "*
379790075Sobrien{
379890075Sobrien  int start = INTVAL (operands[3]) & 63;
379990075Sobrien  int size = INTVAL (operands[2]) & 63;
380090075Sobrien
380190075Sobrien  if (start + size >= 64)
380290075Sobrien    operands[3] = const0_rtx;
380390075Sobrien  else
380490075Sobrien    operands[3] = GEN_INT (start + size);
380590075Sobrien  operands[2] = GEN_INT (64 - size);
380690075Sobrien  return \"rldicl. %0,%1,%3,%2\";
3807169689Skan}"
3808169689Skan  [(set_attr "type" "compare")])
380990075Sobrien
381090075Sobrien(define_insn "rotlsi3"
381190075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
381290075Sobrien	(rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
381390075Sobrien		   (match_operand:SI 2 "reg_or_cint_operand" "ri")))]
381490075Sobrien  ""
381590075Sobrien  "{rl%I2nm|rlw%I2nm} %0,%1,%h2,0xffffffff")
381690075Sobrien
381790075Sobrien(define_insn "*rotlsi3_internal2"
381890075Sobrien  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
381990075Sobrien	(compare:CC (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
382090075Sobrien			       (match_operand:SI 2 "reg_or_cint_operand" "ri,ri"))
382190075Sobrien		    (const_int 0)))
382290075Sobrien   (clobber (match_scratch:SI 3 "=r,r"))]
3823117395Skan  ""
382490075Sobrien  "@
382590075Sobrien   {rl%I2nm.|rlw%I2nm.} %3,%1,%h2,0xffffffff
382690075Sobrien   #"
382790075Sobrien  [(set_attr "type" "delayed_compare")
382890075Sobrien   (set_attr "length" "4,8")])
382990075Sobrien
383090075Sobrien(define_split
383190075Sobrien  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
383290075Sobrien	(compare:CC (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
383390075Sobrien			       (match_operand:SI 2 "reg_or_cint_operand" ""))
383490075Sobrien		    (const_int 0)))
383590075Sobrien   (clobber (match_scratch:SI 3 ""))]
3836117395Skan  "reload_completed"
383790075Sobrien  [(set (match_dup 3)
383890075Sobrien	(rotate:SI (match_dup 1) (match_dup 2)))
383990075Sobrien   (set (match_dup 0)
384090075Sobrien	(compare:CC (match_dup 3)
384190075Sobrien		    (const_int 0)))]
384290075Sobrien  "")
384390075Sobrien
384490075Sobrien(define_insn "*rotlsi3_internal3"
384590075Sobrien  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
384690075Sobrien	(compare:CC (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
384790075Sobrien			       (match_operand:SI 2 "reg_or_cint_operand" "ri,ri"))
384890075Sobrien		    (const_int 0)))
384990075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
385090075Sobrien	(rotate:SI (match_dup 1) (match_dup 2)))]
3851117395Skan  ""
385290075Sobrien  "@
385390075Sobrien   {rl%I2nm.|rlw%I2nm.} %0,%1,%h2,0xffffffff
385490075Sobrien   #"
385590075Sobrien  [(set_attr "type" "delayed_compare")
385690075Sobrien   (set_attr "length" "4,8")])
385790075Sobrien
385890075Sobrien(define_split
385990075Sobrien  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
386090075Sobrien	(compare:CC (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
386190075Sobrien			       (match_operand:SI 2 "reg_or_cint_operand" ""))
386290075Sobrien		    (const_int 0)))
386390075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "")
386490075Sobrien	(rotate:SI (match_dup 1) (match_dup 2)))]
3865117395Skan  "reload_completed"
386690075Sobrien  [(set (match_dup 0)
386790075Sobrien	(rotate:SI (match_dup 1) (match_dup 2)))
386890075Sobrien   (set (match_dup 3)
386990075Sobrien	(compare:CC (match_dup 0)
387090075Sobrien		    (const_int 0)))]
387190075Sobrien  "")
387290075Sobrien
387390075Sobrien(define_insn "*rotlsi3_internal4"
387490075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
387590075Sobrien	(and:SI (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
387690075Sobrien			   (match_operand:SI 2 "reg_or_cint_operand" "ri"))
3877117395Skan		(match_operand:SI 3 "mask_operand" "n")))]
387890075Sobrien  ""
387990075Sobrien  "{rl%I2nm|rlw%I2nm} %0,%1,%h2,%m3,%M3")
388090075Sobrien
388190075Sobrien(define_insn "*rotlsi3_internal5"
388290075Sobrien  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
388390075Sobrien	(compare:CC (and:SI
388490075Sobrien		     (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
388590075Sobrien				(match_operand:SI 2 "reg_or_cint_operand" "ri,ri"))
3886117395Skan		     (match_operand:SI 3 "mask_operand" "n,n"))
388790075Sobrien		    (const_int 0)))
388890075Sobrien   (clobber (match_scratch:SI 4 "=r,r"))]
3889117395Skan  ""
389090075Sobrien  "@
389190075Sobrien   {rl%I2nm.|rlw%I2nm.} %4,%1,%h2,%m3,%M3
389290075Sobrien   #"
389390075Sobrien  [(set_attr "type" "delayed_compare")
389490075Sobrien   (set_attr "length" "4,8")])
389590075Sobrien
389690075Sobrien(define_split
389790075Sobrien  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
389890075Sobrien	(compare:CC (and:SI
389990075Sobrien		     (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
390090075Sobrien				(match_operand:SI 2 "reg_or_cint_operand" ""))
390190075Sobrien		     (match_operand:SI 3 "mask_operand" ""))
390290075Sobrien		    (const_int 0)))
390390075Sobrien   (clobber (match_scratch:SI 4 ""))]
3904117395Skan  "reload_completed"
390590075Sobrien  [(set (match_dup 4)
390690075Sobrien	(and:SI (rotate:SI (match_dup 1)
390790075Sobrien				(match_dup 2))
390890075Sobrien		     (match_dup 3)))
390990075Sobrien   (set (match_dup 0)
391090075Sobrien	(compare:CC (match_dup 4)
391190075Sobrien		    (const_int 0)))]
391290075Sobrien  "")
391390075Sobrien
391490075Sobrien(define_insn "*rotlsi3_internal6"
391590075Sobrien  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
391690075Sobrien	(compare:CC (and:SI
391790075Sobrien		     (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
391890075Sobrien				(match_operand:SI 2 "reg_or_cint_operand" "ri,ri"))
3919117395Skan		     (match_operand:SI 3 "mask_operand" "n,n"))
392090075Sobrien		    (const_int 0)))
392190075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
392290075Sobrien	(and:SI (rotate:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
3923117395Skan  ""
392490075Sobrien  "@
392590075Sobrien   {rl%I2nm.|rlw%I2nm.} %0,%1,%h2,%m3,%M3
392690075Sobrien   #"
392790075Sobrien  [(set_attr "type" "delayed_compare")
392890075Sobrien   (set_attr "length" "4,8")])
392990075Sobrien
393090075Sobrien(define_split
393190075Sobrien  [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
393290075Sobrien	(compare:CC (and:SI
393390075Sobrien		     (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
393490075Sobrien				(match_operand:SI 2 "reg_or_cint_operand" ""))
393590075Sobrien		     (match_operand:SI 3 "mask_operand" ""))
393690075Sobrien		    (const_int 0)))
393790075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "")
393890075Sobrien	(and:SI (rotate:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
3939117395Skan  "reload_completed"
394090075Sobrien  [(set (match_dup 0)
394190075Sobrien	(and:SI (rotate:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
394290075Sobrien   (set (match_dup 4)
394390075Sobrien	(compare:CC (match_dup 0)
394490075Sobrien		    (const_int 0)))]
394590075Sobrien  "")
394690075Sobrien
394790075Sobrien(define_insn "*rotlsi3_internal7"
394890075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
394990075Sobrien	(zero_extend:SI
395090075Sobrien	 (subreg:QI
395190075Sobrien	  (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
395290075Sobrien		     (match_operand:SI 2 "reg_or_cint_operand" "ri")) 0)))]
395390075Sobrien  ""
395490075Sobrien  "{rl%I2nm|rlw%I2nm} %0,%1,%h2,0xff")
395590075Sobrien
395690075Sobrien(define_insn "*rotlsi3_internal8"
395790075Sobrien  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
395890075Sobrien	(compare:CC (zero_extend:SI
395990075Sobrien		     (subreg:QI
396090075Sobrien		      (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
396190075Sobrien				 (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) 0))
396290075Sobrien		    (const_int 0)))
396390075Sobrien   (clobber (match_scratch:SI 3 "=r,r"))]
396490075Sobrien  ""
396590075Sobrien  "@
396690075Sobrien   {rl%I2nm.|rlw%I2nm.} %3,%1,%h2,0xff
396790075Sobrien   #"
396890075Sobrien  [(set_attr "type" "delayed_compare")
396990075Sobrien   (set_attr "length" "4,8")])
397090075Sobrien
397190075Sobrien(define_split
397290075Sobrien  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
397390075Sobrien	(compare:CC (zero_extend:SI
397490075Sobrien		     (subreg:QI
397590075Sobrien		      (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
397690075Sobrien				 (match_operand:SI 2 "reg_or_cint_operand" "")) 0))
397790075Sobrien		    (const_int 0)))
397890075Sobrien   (clobber (match_scratch:SI 3 ""))]
397990075Sobrien  "reload_completed"
398090075Sobrien  [(set (match_dup 3)
398190075Sobrien	(zero_extend:SI (subreg:QI
398290075Sobrien		      (rotate:SI (match_dup 1)
398390075Sobrien				 (match_dup 2)) 0)))
398490075Sobrien   (set (match_dup 0)
398590075Sobrien	(compare:CC (match_dup 3)
398690075Sobrien		    (const_int 0)))]
398790075Sobrien  "")
398890075Sobrien
398990075Sobrien(define_insn "*rotlsi3_internal9"
399090075Sobrien  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
399190075Sobrien	(compare:CC (zero_extend:SI
399290075Sobrien		     (subreg:QI
399390075Sobrien		      (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
399490075Sobrien				 (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) 0))
399590075Sobrien		    (const_int 0)))
399690075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
399790075Sobrien	(zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 0)))]
399890075Sobrien  ""
399990075Sobrien  "@
400090075Sobrien   {rl%I2nm.|rlw%I2nm.} %0,%1,%h2,0xff
400190075Sobrien   #"
400290075Sobrien  [(set_attr "type" "delayed_compare")
400390075Sobrien   (set_attr "length" "4,8")])
400490075Sobrien
400590075Sobrien(define_split
400690075Sobrien  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
400790075Sobrien	(compare:CC (zero_extend:SI
400890075Sobrien		     (subreg:QI
400990075Sobrien		      (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
401090075Sobrien				 (match_operand:SI 2 "reg_or_cint_operand" "")) 0))
401190075Sobrien		    (const_int 0)))
401290075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "")
401390075Sobrien	(zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 0)))]
401490075Sobrien  "reload_completed"
401590075Sobrien  [(set (match_dup 0)
401690075Sobrien	(zero_extend:SI (subreg:QI (rotate:SI (match_dup 1) (match_dup 2)) 0)))
401790075Sobrien   (set (match_dup 3)
401890075Sobrien	(compare:CC (match_dup 0)
401990075Sobrien		    (const_int 0)))]
402090075Sobrien  "")
402190075Sobrien
402290075Sobrien(define_insn "*rotlsi3_internal10"
402390075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
402490075Sobrien	(zero_extend:SI
402590075Sobrien	 (subreg:HI
402690075Sobrien	  (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
402790075Sobrien		     (match_operand:SI 2 "reg_or_cint_operand" "ri")) 0)))]
402890075Sobrien  ""
402990075Sobrien  "{rl%I2nm|rlw%I2nm} %0,%1,%h2,0xffff")
403090075Sobrien
403190075Sobrien(define_insn "*rotlsi3_internal11"
403290075Sobrien  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
403390075Sobrien	(compare:CC (zero_extend:SI
403490075Sobrien		     (subreg:HI
403590075Sobrien		      (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
403690075Sobrien				 (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) 0))
403790075Sobrien		    (const_int 0)))
403890075Sobrien   (clobber (match_scratch:SI 3 "=r,r"))]
403990075Sobrien  ""
404090075Sobrien  "@
404190075Sobrien   {rl%I2nm.|rlw%I2nm.} %3,%1,%h2,0xffff
404290075Sobrien   #"
404390075Sobrien  [(set_attr "type" "delayed_compare")
404490075Sobrien   (set_attr "length" "4,8")])
404590075Sobrien
404690075Sobrien(define_split
404790075Sobrien  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
404890075Sobrien	(compare:CC (zero_extend:SI
404990075Sobrien		     (subreg:HI
405090075Sobrien		      (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
405190075Sobrien				 (match_operand:SI 2 "reg_or_cint_operand" "")) 0))
405290075Sobrien		    (const_int 0)))
405390075Sobrien   (clobber (match_scratch:SI 3 ""))]
405490075Sobrien  "reload_completed"
405590075Sobrien  [(set (match_dup 3)
405690075Sobrien	(zero_extend:SI (subreg:HI
405790075Sobrien		      (rotate:SI (match_dup 1)
405890075Sobrien				 (match_dup 2)) 0)))
405990075Sobrien   (set (match_dup 0)
406090075Sobrien	(compare:CC (match_dup 3)
406190075Sobrien		    (const_int 0)))]
406290075Sobrien  "")
406390075Sobrien
406490075Sobrien(define_insn "*rotlsi3_internal12"
406590075Sobrien  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
406690075Sobrien	(compare:CC (zero_extend:SI
406790075Sobrien		     (subreg:HI
406890075Sobrien		      (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
406990075Sobrien				 (match_operand:SI 2 "reg_or_cint_operand" "ri,ri")) 0))
407090075Sobrien		    (const_int 0)))
407190075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
407290075Sobrien	(zero_extend:SI (subreg:HI (rotate:SI (match_dup 1) (match_dup 2)) 0)))]
407390075Sobrien  ""
407490075Sobrien  "@
407590075Sobrien   {rl%I2nm.|rlw%I2nm.} %0,%1,%h2,0xffff
407690075Sobrien   #"
407790075Sobrien  [(set_attr "type" "delayed_compare")
407890075Sobrien   (set_attr "length" "4,8")])
407990075Sobrien
408090075Sobrien(define_split
408190075Sobrien  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
408290075Sobrien	(compare:CC (zero_extend:SI
408390075Sobrien		     (subreg:HI
408490075Sobrien		      (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "")
408590075Sobrien				 (match_operand:SI 2 "reg_or_cint_operand" "")) 0))
408690075Sobrien		    (const_int 0)))
408790075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "")
408890075Sobrien	(zero_extend:SI (subreg:HI (rotate:SI (match_dup 1) (match_dup 2)) 0)))]
408990075Sobrien  "reload_completed"
409090075Sobrien  [(set (match_dup 0)
409190075Sobrien	(zero_extend:SI (subreg:HI (rotate:SI (match_dup 1) (match_dup 2)) 0)))
409290075Sobrien   (set (match_dup 3)
409390075Sobrien	(compare:CC (match_dup 0)
409490075Sobrien		    (const_int 0)))]
409590075Sobrien  "")
409690075Sobrien
409790075Sobrien;; Note that we use "sle." instead of "sl." so that we can set
409890075Sobrien;; SHIFT_COUNT_TRUNCATED.
409990075Sobrien
410090075Sobrien(define_expand "ashlsi3"
410190075Sobrien  [(use (match_operand:SI 0 "gpc_reg_operand" ""))
410290075Sobrien   (use (match_operand:SI 1 "gpc_reg_operand" ""))
410390075Sobrien   (use (match_operand:SI 2 "reg_or_cint_operand" ""))]
410490075Sobrien  ""
410590075Sobrien  "
410690075Sobrien{
410790075Sobrien  if (TARGET_POWER)
410890075Sobrien    emit_insn (gen_ashlsi3_power (operands[0], operands[1], operands[2]));
410990075Sobrien  else
411090075Sobrien    emit_insn (gen_ashlsi3_no_power (operands[0], operands[1], operands[2]));
411190075Sobrien  DONE;
411290075Sobrien}")
411390075Sobrien
411490075Sobrien(define_insn "ashlsi3_power"
411590075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
411690075Sobrien	(ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
411790075Sobrien		   (match_operand:SI 2 "reg_or_cint_operand" "r,i")))
411890075Sobrien   (clobber (match_scratch:SI 3 "=q,X"))]
411990075Sobrien  "TARGET_POWER"
412090075Sobrien  "@
412190075Sobrien   sle %0,%1,%2
412290075Sobrien   {sli|slwi} %0,%1,%h2")
412390075Sobrien
412490075Sobrien(define_insn "ashlsi3_no_power"
412590075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
412690075Sobrien	(ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
412790075Sobrien		   (match_operand:SI 2 "reg_or_cint_operand" "ri")))]
412890075Sobrien  "! TARGET_POWER"
412990075Sobrien  "{sl|slw}%I2 %0,%1,%h2")
413090075Sobrien
413190075Sobrien(define_insn ""
413290075Sobrien  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
413390075Sobrien	(compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
413490075Sobrien			       (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i"))
413590075Sobrien		    (const_int 0)))
413690075Sobrien   (clobber (match_scratch:SI 3 "=r,r,r,r"))
413790075Sobrien   (clobber (match_scratch:SI 4 "=q,X,q,X"))]
413890075Sobrien  "TARGET_POWER"
413990075Sobrien  "@
414090075Sobrien   sle. %3,%1,%2
414190075Sobrien   {sli.|slwi.} %3,%1,%h2
414290075Sobrien   #
414390075Sobrien   #"
414490075Sobrien  [(set_attr "type" "delayed_compare")
414590075Sobrien   (set_attr "length" "4,4,8,8")])
414690075Sobrien
414790075Sobrien(define_split
414890075Sobrien  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
414990075Sobrien	(compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "")
415090075Sobrien			       (match_operand:SI 2 "reg_or_cint_operand" ""))
415190075Sobrien		    (const_int 0)))
415290075Sobrien   (clobber (match_scratch:SI 3 ""))
415390075Sobrien   (clobber (match_scratch:SI 4 ""))]
415490075Sobrien  "TARGET_POWER && reload_completed"
415590075Sobrien  [(parallel [(set (match_dup 3)
415690075Sobrien	(ashift:SI (match_dup 1) (match_dup 2)))
415790075Sobrien   (clobber (match_dup 4))])
415890075Sobrien   (set (match_dup 0)
415990075Sobrien	(compare:CC (match_dup 3)
416090075Sobrien		    (const_int 0)))]
416190075Sobrien  "")
416290075Sobrien
416390075Sobrien(define_insn ""
416490075Sobrien  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
416590075Sobrien	(compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
416690075Sobrien			       (match_operand:SI 2 "reg_or_cint_operand" "ri,ri"))
416790075Sobrien		    (const_int 0)))
416890075Sobrien   (clobber (match_scratch:SI 3 "=r,r"))]
4169132718Skan  "! TARGET_POWER && TARGET_32BIT"
417090075Sobrien  "@
417190075Sobrien   {sl|slw}%I2. %3,%1,%h2
417290075Sobrien   #"
417390075Sobrien  [(set_attr "type" "delayed_compare")
417490075Sobrien   (set_attr "length" "4,8")])
417590075Sobrien
417690075Sobrien(define_split
417790075Sobrien  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
417890075Sobrien	(compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "")
417990075Sobrien			       (match_operand:SI 2 "reg_or_cint_operand" ""))
418090075Sobrien		    (const_int 0)))
418190075Sobrien   (clobber (match_scratch:SI 3 ""))]
4182132718Skan  "! TARGET_POWER && TARGET_32BIT && reload_completed"
418390075Sobrien  [(set (match_dup 3)
418490075Sobrien	(ashift:SI (match_dup 1) (match_dup 2)))
418590075Sobrien   (set (match_dup 0)
418690075Sobrien	(compare:CC (match_dup 3)
418790075Sobrien		    (const_int 0)))]
418890075Sobrien  "")
418990075Sobrien
419090075Sobrien(define_insn ""
419190075Sobrien  [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
419290075Sobrien	(compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
419390075Sobrien			       (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i"))
419490075Sobrien		    (const_int 0)))
419590075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
419690075Sobrien	(ashift:SI (match_dup 1) (match_dup 2)))
419790075Sobrien   (clobber (match_scratch:SI 4 "=q,X,q,X"))]
419890075Sobrien  "TARGET_POWER"
419990075Sobrien  "@
420090075Sobrien   sle. %0,%1,%2
420190075Sobrien   {sli.|slwi.} %0,%1,%h2
420290075Sobrien   #
420390075Sobrien   #"
420490075Sobrien  [(set_attr "type" "delayed_compare")
420590075Sobrien   (set_attr "length" "4,4,8,8")])
420690075Sobrien
420790075Sobrien(define_split
420890075Sobrien  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
420990075Sobrien	(compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "")
421090075Sobrien			       (match_operand:SI 2 "reg_or_cint_operand" ""))
421190075Sobrien		    (const_int 0)))
421290075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "")
421390075Sobrien	(ashift:SI (match_dup 1) (match_dup 2)))
421490075Sobrien   (clobber (match_scratch:SI 4 ""))]
421590075Sobrien  "TARGET_POWER && reload_completed"
421690075Sobrien  [(parallel [(set (match_dup 0)
421790075Sobrien	(ashift:SI (match_dup 1) (match_dup 2)))
421890075Sobrien   (clobber (match_dup 4))])
421990075Sobrien   (set (match_dup 3)
422090075Sobrien	(compare:CC (match_dup 0)
422190075Sobrien		    (const_int 0)))]
422290075Sobrien  "")
422390075Sobrien
422490075Sobrien(define_insn ""
422590075Sobrien  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
422690075Sobrien	(compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
422790075Sobrien			       (match_operand:SI 2 "reg_or_cint_operand" "ri,ri"))
422890075Sobrien		    (const_int 0)))
422990075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
423090075Sobrien	(ashift:SI (match_dup 1) (match_dup 2)))]
4231132718Skan  "! TARGET_POWER && TARGET_32BIT"
423290075Sobrien  "@
423390075Sobrien   {sl|slw}%I2. %0,%1,%h2
423490075Sobrien   #"
423590075Sobrien  [(set_attr "type" "delayed_compare")
423690075Sobrien   (set_attr "length" "4,8")])
423790075Sobrien
423890075Sobrien(define_split
423990075Sobrien  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
424090075Sobrien	(compare:CC (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "")
424190075Sobrien			       (match_operand:SI 2 "reg_or_cint_operand" ""))
424290075Sobrien		    (const_int 0)))
424390075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "")
424490075Sobrien	(ashift:SI (match_dup 1) (match_dup 2)))]
4245132718Skan  "! TARGET_POWER && TARGET_32BIT && reload_completed"
424690075Sobrien  [(set (match_dup 0)
424790075Sobrien	(ashift:SI (match_dup 1) (match_dup 2)))
424890075Sobrien   (set (match_dup 3)
424990075Sobrien	(compare:CC (match_dup 0)
425090075Sobrien		    (const_int 0)))]
425190075Sobrien  "")
425290075Sobrien
4253169689Skan(define_insn "rlwinm"
425490075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
425590075Sobrien	(and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
425690075Sobrien			   (match_operand:SI 2 "const_int_operand" "i"))
4257117395Skan		(match_operand:SI 3 "mask_operand" "n")))]
425890075Sobrien  "includes_lshift_p (operands[2], operands[3])"
425990075Sobrien  "{rlinm|rlwinm} %0,%1,%h2,%m3,%M3")
426090075Sobrien
426190075Sobrien(define_insn ""
426290075Sobrien  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
426390075Sobrien	(compare:CC
426490075Sobrien	 (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
426590075Sobrien			    (match_operand:SI 2 "const_int_operand" "i,i"))
4266117395Skan		 (match_operand:SI 3 "mask_operand" "n,n"))
426790075Sobrien	 (const_int 0)))
426890075Sobrien   (clobber (match_scratch:SI 4 "=r,r"))]
4269117395Skan  "includes_lshift_p (operands[2], operands[3])"
427090075Sobrien  "@
427190075Sobrien   {rlinm.|rlwinm.} %4,%1,%h2,%m3,%M3
427290075Sobrien   #"
427390075Sobrien  [(set_attr "type" "delayed_compare")
427490075Sobrien   (set_attr "length" "4,8")])
427590075Sobrien
427690075Sobrien(define_split
427790075Sobrien  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
427890075Sobrien	(compare:CC
427990075Sobrien	 (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "")
428090075Sobrien			    (match_operand:SI 2 "const_int_operand" ""))
428190075Sobrien		 (match_operand:SI 3 "mask_operand" ""))
428290075Sobrien	 (const_int 0)))
428390075Sobrien   (clobber (match_scratch:SI 4 ""))]
4284117395Skan  "includes_lshift_p (operands[2], operands[3]) && reload_completed"
428590075Sobrien  [(set (match_dup 4)
428690075Sobrien	(and:SI (ashift:SI (match_dup 1) (match_dup 2))
428790075Sobrien		 (match_dup 3)))
428890075Sobrien   (set (match_dup 0)
428990075Sobrien	(compare:CC (match_dup 4)
429090075Sobrien		    (const_int 0)))]
429190075Sobrien  "")
429290075Sobrien
429390075Sobrien(define_insn ""
429490075Sobrien  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
429590075Sobrien	(compare:CC
429690075Sobrien	 (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
429790075Sobrien			    (match_operand:SI 2 "const_int_operand" "i,i"))
4298117395Skan		 (match_operand:SI 3 "mask_operand" "n,n"))
429990075Sobrien	 (const_int 0)))
430090075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
430190075Sobrien	(and:SI (ashift:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
4302117395Skan  "includes_lshift_p (operands[2], operands[3])"
430390075Sobrien  "@
430490075Sobrien   {rlinm.|rlwinm.} %0,%1,%h2,%m3,%M3
430590075Sobrien   #"
430690075Sobrien  [(set_attr "type" "delayed_compare")
430790075Sobrien   (set_attr "length" "4,8")])
430890075Sobrien
430990075Sobrien(define_split
431090075Sobrien  [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
431190075Sobrien	(compare:CC
431290075Sobrien	 (and:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "")
431390075Sobrien			    (match_operand:SI 2 "const_int_operand" ""))
431490075Sobrien		 (match_operand:SI 3 "mask_operand" ""))
431590075Sobrien	 (const_int 0)))
431690075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "")
431790075Sobrien	(and:SI (ashift:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
4318117395Skan  "includes_lshift_p (operands[2], operands[3]) && reload_completed"
431990075Sobrien  [(set (match_dup 0)
432090075Sobrien	(and:SI (ashift:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
432190075Sobrien   (set (match_dup 4)
432290075Sobrien	(compare:CC (match_dup 0)
432390075Sobrien		    (const_int 0)))]
432490075Sobrien  "")
432590075Sobrien
432690075Sobrien;; The AIX assembler mis-handles "sri x,x,0", so write that case as
432790075Sobrien;; "sli x,x,0".
432890075Sobrien(define_expand "lshrsi3"
432990075Sobrien  [(use (match_operand:SI 0 "gpc_reg_operand" ""))
433090075Sobrien   (use (match_operand:SI 1 "gpc_reg_operand" ""))
433190075Sobrien   (use (match_operand:SI 2 "reg_or_cint_operand" ""))]
433290075Sobrien  ""
433390075Sobrien  "
433490075Sobrien{
433590075Sobrien  if (TARGET_POWER)
433690075Sobrien    emit_insn (gen_lshrsi3_power (operands[0], operands[1], operands[2]));
433790075Sobrien  else
433890075Sobrien    emit_insn (gen_lshrsi3_no_power (operands[0], operands[1], operands[2]));
433990075Sobrien  DONE;
434090075Sobrien}")
434190075Sobrien
434290075Sobrien(define_insn "lshrsi3_power"
434390075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
434490075Sobrien	(lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r")
434590075Sobrien		     (match_operand:SI 2 "reg_or_cint_operand" "r,O,i")))
434690075Sobrien   (clobber (match_scratch:SI 3 "=q,X,X"))]
434790075Sobrien  "TARGET_POWER"
434890075Sobrien  "@
434990075Sobrien  sre %0,%1,%2
435090075Sobrien  mr %0,%1
435190075Sobrien  {s%A2i|s%A2wi} %0,%1,%h2")
435290075Sobrien
435390075Sobrien(define_insn "lshrsi3_no_power"
435490075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
435590075Sobrien	(lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
435690075Sobrien		     (match_operand:SI 2 "reg_or_cint_operand" "O,ri")))]
435790075Sobrien  "! TARGET_POWER"
435890075Sobrien  "@
435990075Sobrien  mr %0,%1
436090075Sobrien  {sr|srw}%I2 %0,%1,%h2")
436190075Sobrien
436290075Sobrien(define_insn ""
436390075Sobrien  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,?y,?y,?y")
436490075Sobrien	(compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r,r,r")
436590075Sobrien				 (match_operand:SI 2 "reg_or_cint_operand" "r,O,i,r,O,i"))
436690075Sobrien		    (const_int 0)))
436790075Sobrien   (clobber (match_scratch:SI 3 "=r,X,r,r,X,r"))
436890075Sobrien   (clobber (match_scratch:SI 4 "=q,X,X,q,X,X"))]
436990075Sobrien  "TARGET_POWER"
437090075Sobrien  "@
437190075Sobrien  sre. %3,%1,%2
437290075Sobrien  mr. %1,%1
437390075Sobrien  {s%A2i.|s%A2wi.} %3,%1,%h2
437490075Sobrien  #
437590075Sobrien  #
437690075Sobrien  #"
437790075Sobrien  [(set_attr "type" "delayed_compare")
437890075Sobrien   (set_attr "length" "4,4,4,8,8,8")])
437990075Sobrien
438090075Sobrien(define_split
438190075Sobrien  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
438290075Sobrien	(compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
438390075Sobrien				 (match_operand:SI 2 "reg_or_cint_operand" ""))
438490075Sobrien		    (const_int 0)))
438590075Sobrien   (clobber (match_scratch:SI 3 ""))
438690075Sobrien   (clobber (match_scratch:SI 4 ""))]
438790075Sobrien  "TARGET_POWER && reload_completed"
438890075Sobrien  [(parallel [(set (match_dup 3)
438990075Sobrien	(lshiftrt:SI (match_dup 1) (match_dup 2)))
439090075Sobrien   (clobber (match_dup 4))])
439190075Sobrien   (set (match_dup 0)
439290075Sobrien	(compare:CC (match_dup 3)
439390075Sobrien		    (const_int 0)))]
439490075Sobrien  "")
439590075Sobrien
439690075Sobrien(define_insn ""
439790075Sobrien  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
439890075Sobrien	(compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
439990075Sobrien				 (match_operand:SI 2 "reg_or_cint_operand" "O,ri,O,ri"))
440090075Sobrien		    (const_int 0)))
440190075Sobrien   (clobber (match_scratch:SI 3 "=X,r,X,r"))]
4402132718Skan  "! TARGET_POWER && TARGET_32BIT"
440390075Sobrien  "@
440490075Sobrien   mr. %1,%1
440590075Sobrien   {sr|srw}%I2. %3,%1,%h2
440690075Sobrien   #
440790075Sobrien   #"
440890075Sobrien  [(set_attr "type" "delayed_compare")
440990075Sobrien   (set_attr "length" "4,4,8,8")])
441090075Sobrien
441190075Sobrien(define_split
441290075Sobrien  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
441390075Sobrien	(compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
441490075Sobrien				 (match_operand:SI 2 "reg_or_cint_operand" ""))
441590075Sobrien		    (const_int 0)))
441690075Sobrien   (clobber (match_scratch:SI 3 ""))]
4417132718Skan  "! TARGET_POWER && TARGET_32BIT && reload_completed"
441890075Sobrien  [(set (match_dup 3)
441990075Sobrien	(lshiftrt:SI (match_dup 1) (match_dup 2)))
442090075Sobrien   (set (match_dup 0)
442190075Sobrien	(compare:CC (match_dup 3)
442290075Sobrien		    (const_int 0)))]
442390075Sobrien  "")
442490075Sobrien
442590075Sobrien(define_insn ""
442690075Sobrien  [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,x,?y,?y,?y")
442790075Sobrien	(compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r,r,r")
442890075Sobrien				 (match_operand:SI 2 "reg_or_cint_operand" "r,O,i,r,O,i"))
442990075Sobrien		    (const_int 0)))
443090075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r,r")
443190075Sobrien	(lshiftrt:SI (match_dup 1) (match_dup 2)))
443290075Sobrien   (clobber (match_scratch:SI 4 "=q,X,X,q,X,X"))]
443390075Sobrien  "TARGET_POWER"
443490075Sobrien  "@
443590075Sobrien  sre. %0,%1,%2
443690075Sobrien  mr. %0,%1
443790075Sobrien  {s%A2i.|s%A2wi.} %0,%1,%h2
443890075Sobrien  #
443990075Sobrien  #
444090075Sobrien  #"
444190075Sobrien  [(set_attr "type" "delayed_compare")
444290075Sobrien   (set_attr "length" "4,4,4,8,8,8")])
444390075Sobrien
444490075Sobrien(define_split
444590075Sobrien  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
444690075Sobrien	(compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
444790075Sobrien				 (match_operand:SI 2 "reg_or_cint_operand" ""))
444890075Sobrien		    (const_int 0)))
444990075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "")
445090075Sobrien	(lshiftrt:SI (match_dup 1) (match_dup 2)))
445190075Sobrien   (clobber (match_scratch:SI 4 ""))]
445290075Sobrien  "TARGET_POWER && reload_completed"
445390075Sobrien  [(parallel [(set (match_dup 0)
445490075Sobrien	(lshiftrt:SI (match_dup 1) (match_dup 2)))
445590075Sobrien   (clobber (match_dup 4))])
445690075Sobrien   (set (match_dup 3)
445790075Sobrien	(compare:CC (match_dup 0)
445890075Sobrien		    (const_int 0)))]
445990075Sobrien  "")
446090075Sobrien
446190075Sobrien(define_insn ""
446290075Sobrien  [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
446390075Sobrien	(compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
446490075Sobrien				 (match_operand:SI 2 "reg_or_cint_operand" "O,ri,O,ri"))
446590075Sobrien		    (const_int 0)))
446690075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
446790075Sobrien	(lshiftrt:SI (match_dup 1) (match_dup 2)))]
4468132718Skan  "! TARGET_POWER && TARGET_32BIT"
446990075Sobrien  "@
447090075Sobrien   mr. %0,%1
447190075Sobrien   {sr|srw}%I2. %0,%1,%h2
447290075Sobrien   #
447390075Sobrien   #"
447490075Sobrien  [(set_attr "type" "delayed_compare")
447590075Sobrien   (set_attr "length" "4,4,8,8")])
447690075Sobrien
447790075Sobrien(define_split
447890075Sobrien  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
447990075Sobrien	(compare:CC (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
448090075Sobrien				 (match_operand:SI 2 "reg_or_cint_operand" ""))
448190075Sobrien		    (const_int 0)))
448290075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "")
448390075Sobrien	(lshiftrt:SI (match_dup 1) (match_dup 2)))]
4484132718Skan  "! TARGET_POWER && TARGET_32BIT && reload_completed"
448590075Sobrien  [(set (match_dup 0)
448690075Sobrien	(lshiftrt:SI (match_dup 1) (match_dup 2)))
448790075Sobrien   (set (match_dup 3)
448890075Sobrien	(compare:CC (match_dup 0)
448990075Sobrien		    (const_int 0)))]
449090075Sobrien  "")
449190075Sobrien
449290075Sobrien(define_insn ""
449390075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
449490075Sobrien	(and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
449590075Sobrien			     (match_operand:SI 2 "const_int_operand" "i"))
4496117395Skan		(match_operand:SI 3 "mask_operand" "n")))]
449790075Sobrien  "includes_rshift_p (operands[2], operands[3])"
449890075Sobrien  "{rlinm|rlwinm} %0,%1,%s2,%m3,%M3")
449990075Sobrien
450090075Sobrien(define_insn ""
450190075Sobrien  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
450290075Sobrien	(compare:CC
450390075Sobrien	 (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
450490075Sobrien			      (match_operand:SI 2 "const_int_operand" "i,i"))
4505117395Skan		 (match_operand:SI 3 "mask_operand" "n,n"))
450690075Sobrien	 (const_int 0)))
450790075Sobrien   (clobber (match_scratch:SI 4 "=r,r"))]
4508117395Skan  "includes_rshift_p (operands[2], operands[3])"
450990075Sobrien  "@
451090075Sobrien   {rlinm.|rlwinm.} %4,%1,%s2,%m3,%M3
451190075Sobrien   #"
451290075Sobrien  [(set_attr "type" "delayed_compare")
451390075Sobrien   (set_attr "length" "4,8")])
451490075Sobrien
451590075Sobrien(define_split
451690075Sobrien  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
451790075Sobrien	(compare:CC
451890075Sobrien	 (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
451990075Sobrien			      (match_operand:SI 2 "const_int_operand" ""))
452090075Sobrien		 (match_operand:SI 3 "mask_operand" ""))
452190075Sobrien	 (const_int 0)))
452290075Sobrien   (clobber (match_scratch:SI 4 ""))]
4523117395Skan  "includes_rshift_p (operands[2], operands[3]) && reload_completed"
452490075Sobrien  [(set (match_dup 4)
452590075Sobrien	(and:SI (lshiftrt:SI (match_dup 1) (match_dup 2))
452690075Sobrien		 (match_dup 3)))
452790075Sobrien   (set (match_dup 0)
452890075Sobrien	(compare:CC (match_dup 4)
452990075Sobrien		    (const_int 0)))]
453090075Sobrien  "")
453190075Sobrien
453290075Sobrien(define_insn ""
453390075Sobrien  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
453490075Sobrien	(compare:CC
453590075Sobrien	 (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
453690075Sobrien			      (match_operand:SI 2 "const_int_operand" "i,i"))
4537117395Skan		 (match_operand:SI 3 "mask_operand" "n,n"))
453890075Sobrien	 (const_int 0)))
453990075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
454090075Sobrien	(and:SI (lshiftrt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
4541117395Skan  "includes_rshift_p (operands[2], operands[3])"
454290075Sobrien  "@
454390075Sobrien   {rlinm.|rlwinm.} %0,%1,%s2,%m3,%M3
454490075Sobrien   #"
454590075Sobrien  [(set_attr "type" "delayed_compare")
454690075Sobrien   (set_attr "length" "4,8")])
454790075Sobrien
454890075Sobrien(define_split
454990075Sobrien  [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
455090075Sobrien	(compare:CC
455190075Sobrien	 (and:SI (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
455290075Sobrien			      (match_operand:SI 2 "const_int_operand" ""))
455390075Sobrien		 (match_operand:SI 3 "mask_operand" ""))
455490075Sobrien	 (const_int 0)))
455590075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "")
455690075Sobrien	(and:SI (lshiftrt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
4557117395Skan  "includes_rshift_p (operands[2], operands[3]) && reload_completed"
455890075Sobrien  [(set (match_dup 0)
455990075Sobrien	(and:SI (lshiftrt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
456090075Sobrien   (set (match_dup 4)
456190075Sobrien	(compare:CC (match_dup 0)
456290075Sobrien		    (const_int 0)))]
456390075Sobrien  "")
456490075Sobrien
456590075Sobrien(define_insn ""
456690075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
456790075Sobrien	(zero_extend:SI
456890075Sobrien	 (subreg:QI
456990075Sobrien	  (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
457090075Sobrien		       (match_operand:SI 2 "const_int_operand" "i")) 0)))]
457190075Sobrien  "includes_rshift_p (operands[2], GEN_INT (255))"
457290075Sobrien  "{rlinm|rlwinm} %0,%1,%s2,0xff")
457390075Sobrien
457490075Sobrien(define_insn ""
457590075Sobrien  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
457690075Sobrien	(compare:CC
457790075Sobrien	 (zero_extend:SI
457890075Sobrien	  (subreg:QI
457990075Sobrien	   (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
458090075Sobrien			(match_operand:SI 2 "const_int_operand" "i,i")) 0))
458190075Sobrien	 (const_int 0)))
458290075Sobrien   (clobber (match_scratch:SI 3 "=r,r"))]
458390075Sobrien  "includes_rshift_p (operands[2], GEN_INT (255))"
458490075Sobrien  "@
458590075Sobrien   {rlinm.|rlwinm.} %3,%1,%s2,0xff
458690075Sobrien   #"
458790075Sobrien  [(set_attr "type" "delayed_compare")
458890075Sobrien   (set_attr "length" "4,8")])
458990075Sobrien
459090075Sobrien(define_split
459190075Sobrien  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
459290075Sobrien	(compare:CC
459390075Sobrien	 (zero_extend:SI
459490075Sobrien	  (subreg:QI
459590075Sobrien	   (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
459690075Sobrien			(match_operand:SI 2 "const_int_operand" "")) 0))
459790075Sobrien	 (const_int 0)))
459890075Sobrien   (clobber (match_scratch:SI 3 ""))]
459990075Sobrien  "includes_rshift_p (operands[2], GEN_INT (255)) && reload_completed"
460090075Sobrien  [(set (match_dup 3)
460190075Sobrien	(zero_extend:SI (subreg:QI
460290075Sobrien	   (lshiftrt:SI (match_dup 1)
460390075Sobrien			(match_dup 2)) 0)))
460490075Sobrien   (set (match_dup 0)
460590075Sobrien	(compare:CC (match_dup 3)
460690075Sobrien		    (const_int 0)))]
460790075Sobrien  "")
460890075Sobrien
460990075Sobrien(define_insn ""
461090075Sobrien  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
461190075Sobrien	(compare:CC
461290075Sobrien	 (zero_extend:SI
461390075Sobrien	  (subreg:QI
461490075Sobrien	   (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
461590075Sobrien			(match_operand:SI 2 "const_int_operand" "i,i")) 0))
461690075Sobrien	 (const_int 0)))
461790075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
461890075Sobrien	(zero_extend:SI (subreg:QI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))]
461990075Sobrien  "includes_rshift_p (operands[2], GEN_INT (255))"
462090075Sobrien  "@
462190075Sobrien   {rlinm.|rlwinm.} %0,%1,%s2,0xff
462290075Sobrien   #"
462390075Sobrien  [(set_attr "type" "delayed_compare")
462490075Sobrien   (set_attr "length" "4,8")])
462590075Sobrien
462690075Sobrien(define_split
462790075Sobrien  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
462890075Sobrien	(compare:CC
462990075Sobrien	 (zero_extend:SI
463090075Sobrien	  (subreg:QI
463190075Sobrien	   (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
463290075Sobrien			(match_operand:SI 2 "const_int_operand" "")) 0))
463390075Sobrien	 (const_int 0)))
463490075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "")
463590075Sobrien	(zero_extend:SI (subreg:QI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))]
463690075Sobrien  "includes_rshift_p (operands[2], GEN_INT (255)) && reload_completed"
463790075Sobrien  [(set (match_dup 0)
463890075Sobrien	(zero_extend:SI (subreg:QI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))
463990075Sobrien   (set (match_dup 3)
464090075Sobrien	(compare:CC (match_dup 0)
464190075Sobrien		    (const_int 0)))]
464290075Sobrien  "")
464390075Sobrien
464490075Sobrien(define_insn ""
464590075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
464690075Sobrien	(zero_extend:SI
464790075Sobrien	 (subreg:HI
464890075Sobrien	  (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
464990075Sobrien		       (match_operand:SI 2 "const_int_operand" "i")) 0)))]
465090075Sobrien  "includes_rshift_p (operands[2], GEN_INT (65535))"
465190075Sobrien  "{rlinm|rlwinm} %0,%1,%s2,0xffff")
465290075Sobrien
465390075Sobrien(define_insn ""
465490075Sobrien  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
465590075Sobrien	(compare:CC
465690075Sobrien	 (zero_extend:SI
465790075Sobrien	  (subreg:HI
465890075Sobrien	   (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
465990075Sobrien			(match_operand:SI 2 "const_int_operand" "i,i")) 0))
466090075Sobrien	 (const_int 0)))
466190075Sobrien   (clobber (match_scratch:SI 3 "=r,r"))]
466290075Sobrien  "includes_rshift_p (operands[2], GEN_INT (65535))"
466390075Sobrien  "@
466490075Sobrien   {rlinm.|rlwinm.} %3,%1,%s2,0xffff
466590075Sobrien   #"
466690075Sobrien  [(set_attr "type" "delayed_compare")
466790075Sobrien   (set_attr "length" "4,8")])
466890075Sobrien
466990075Sobrien(define_split
467090075Sobrien  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
467190075Sobrien	(compare:CC
467290075Sobrien	 (zero_extend:SI
467390075Sobrien	  (subreg:HI
467490075Sobrien	   (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
467590075Sobrien			(match_operand:SI 2 "const_int_operand" "")) 0))
467690075Sobrien	 (const_int 0)))
467790075Sobrien   (clobber (match_scratch:SI 3 ""))]
467890075Sobrien  "includes_rshift_p (operands[2], GEN_INT (65535)) && reload_completed"
467990075Sobrien  [(set (match_dup 3)
468090075Sobrien	(zero_extend:SI (subreg:HI
468190075Sobrien	   (lshiftrt:SI (match_dup 1)
468290075Sobrien			(match_dup 2)) 0)))
468390075Sobrien   (set (match_dup 0)
468490075Sobrien	(compare:CC (match_dup 3)
468590075Sobrien		    (const_int 0)))]
468690075Sobrien  "")
468790075Sobrien
468890075Sobrien(define_insn ""
468990075Sobrien  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
469090075Sobrien	(compare:CC
469190075Sobrien	 (zero_extend:SI
469290075Sobrien	  (subreg:HI
469390075Sobrien	   (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
469490075Sobrien			(match_operand:SI 2 "const_int_operand" "i,i")) 0))
469590075Sobrien	 (const_int 0)))
469690075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
469790075Sobrien	(zero_extend:SI (subreg:HI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))]
469890075Sobrien  "includes_rshift_p (operands[2], GEN_INT (65535))"
469990075Sobrien  "@
470090075Sobrien   {rlinm.|rlwinm.} %0,%1,%s2,0xffff
470190075Sobrien   #"
470290075Sobrien  [(set_attr "type" "delayed_compare")
470390075Sobrien   (set_attr "length" "4,8")])
470490075Sobrien
470590075Sobrien(define_split
470690075Sobrien  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
470790075Sobrien	(compare:CC
470890075Sobrien	 (zero_extend:SI
470990075Sobrien	  (subreg:HI
471090075Sobrien	   (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
471190075Sobrien			(match_operand:SI 2 "const_int_operand" "")) 0))
471290075Sobrien	 (const_int 0)))
471390075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "")
471490075Sobrien	(zero_extend:SI (subreg:HI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))]
471590075Sobrien  "includes_rshift_p (operands[2], GEN_INT (65535)) && reload_completed"
471690075Sobrien  [(set (match_dup 0)
471790075Sobrien	(zero_extend:SI (subreg:HI (lshiftrt:SI (match_dup 1) (match_dup 2)) 0)))
471890075Sobrien   (set (match_dup 3)
471990075Sobrien	(compare:CC (match_dup 0)
472090075Sobrien		    (const_int 0)))]
472190075Sobrien  "")
472290075Sobrien
472390075Sobrien(define_insn ""
472490075Sobrien  [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
472590075Sobrien			 (const_int 1)
472690075Sobrien			 (match_operand:SI 1 "gpc_reg_operand" "r"))
472790075Sobrien	(ashiftrt:SI (match_operand:SI 2 "gpc_reg_operand" "r")
472890075Sobrien		     (const_int 31)))]
472990075Sobrien  "TARGET_POWER"
473090075Sobrien  "rrib %0,%1,%2")
473190075Sobrien
473290075Sobrien(define_insn ""
473390075Sobrien  [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
473490075Sobrien			 (const_int 1)
473590075Sobrien			 (match_operand:SI 1 "gpc_reg_operand" "r"))
473690075Sobrien	(lshiftrt:SI (match_operand:SI 2 "gpc_reg_operand" "r")
473790075Sobrien		     (const_int 31)))]
473890075Sobrien  "TARGET_POWER"
473990075Sobrien  "rrib %0,%1,%2")
474090075Sobrien
474190075Sobrien(define_insn ""
474290075Sobrien  [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r")
474390075Sobrien			 (const_int 1)
474490075Sobrien			 (match_operand:SI 1 "gpc_reg_operand" "r"))
474590075Sobrien	(zero_extract:SI (match_operand:SI 2 "gpc_reg_operand" "r")
474690075Sobrien			 (const_int 1)
474790075Sobrien			 (const_int 0)))]
474890075Sobrien  "TARGET_POWER"
474990075Sobrien  "rrib %0,%1,%2")
475090075Sobrien
475190075Sobrien(define_expand "ashrsi3"
475290075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "")
475390075Sobrien	(ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
475490075Sobrien		     (match_operand:SI 2 "reg_or_cint_operand" "")))]
475590075Sobrien  ""
475690075Sobrien  "
475790075Sobrien{
475890075Sobrien  if (TARGET_POWER)
475990075Sobrien    emit_insn (gen_ashrsi3_power (operands[0], operands[1], operands[2]));
476090075Sobrien  else
476190075Sobrien    emit_insn (gen_ashrsi3_no_power (operands[0], operands[1], operands[2]));
476290075Sobrien  DONE;
476390075Sobrien}")
476490075Sobrien
476590075Sobrien(define_insn "ashrsi3_power"
476690075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
476790075Sobrien	(ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
476890075Sobrien		     (match_operand:SI 2 "reg_or_cint_operand" "r,i")))
476990075Sobrien   (clobber (match_scratch:SI 3 "=q,X"))]
477090075Sobrien  "TARGET_POWER"
477190075Sobrien  "@
477290075Sobrien   srea %0,%1,%2
477390075Sobrien   {srai|srawi} %0,%1,%h2")
477490075Sobrien
477590075Sobrien(define_insn "ashrsi3_no_power"
477690075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
477790075Sobrien	(ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
477890075Sobrien		     (match_operand:SI 2 "reg_or_cint_operand" "ri")))]
477990075Sobrien  "! TARGET_POWER"
478090075Sobrien  "{sra|sraw}%I2 %0,%1,%h2")
478190075Sobrien
478290075Sobrien(define_insn ""
478390075Sobrien  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
478490075Sobrien	(compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
478590075Sobrien				 (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i"))
478690075Sobrien		    (const_int 0)))
478790075Sobrien   (clobber (match_scratch:SI 3 "=r,r,r,r"))
478890075Sobrien   (clobber (match_scratch:SI 4 "=q,X,q,X"))]
478990075Sobrien  "TARGET_POWER"
479090075Sobrien  "@
479190075Sobrien   srea. %3,%1,%2
479290075Sobrien   {srai.|srawi.} %3,%1,%h2
479390075Sobrien   #
479490075Sobrien   #"
479590075Sobrien  [(set_attr "type" "delayed_compare")
479690075Sobrien   (set_attr "length" "4,4,8,8")])
479790075Sobrien
479890075Sobrien(define_split
479990075Sobrien  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
480090075Sobrien	(compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
480190075Sobrien				 (match_operand:SI 2 "reg_or_cint_operand" ""))
480290075Sobrien		    (const_int 0)))
480390075Sobrien   (clobber (match_scratch:SI 3 ""))
480490075Sobrien   (clobber (match_scratch:SI 4 ""))]
480590075Sobrien  "TARGET_POWER && reload_completed"
480690075Sobrien  [(parallel [(set (match_dup 3)
480790075Sobrien	(ashiftrt:SI (match_dup 1) (match_dup 2)))
480890075Sobrien   (clobber (match_dup 4))])
480990075Sobrien   (set (match_dup 0)
481090075Sobrien	(compare:CC (match_dup 3)
481190075Sobrien		    (const_int 0)))]
481290075Sobrien  "")
481390075Sobrien
481490075Sobrien(define_insn ""
481590075Sobrien  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
481690075Sobrien	(compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
481790075Sobrien				 (match_operand:SI 2 "reg_or_cint_operand" "ri,ri"))
481890075Sobrien		    (const_int 0)))
481990075Sobrien   (clobber (match_scratch:SI 3 "=r,r"))]
482090075Sobrien  "! TARGET_POWER"
482190075Sobrien  "@
482290075Sobrien   {sra|sraw}%I2. %3,%1,%h2
482390075Sobrien   #"
482490075Sobrien  [(set_attr "type" "delayed_compare")
482590075Sobrien   (set_attr "length" "4,8")])
482690075Sobrien
482790075Sobrien(define_split
482890075Sobrien  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
482990075Sobrien	(compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
483090075Sobrien				 (match_operand:SI 2 "reg_or_cint_operand" ""))
483190075Sobrien		    (const_int 0)))
483290075Sobrien   (clobber (match_scratch:SI 3 ""))]
483390075Sobrien  "! TARGET_POWER && reload_completed"
483490075Sobrien  [(set (match_dup 3)
483590075Sobrien	(ashiftrt:SI (match_dup 1) (match_dup 2)))
483690075Sobrien   (set (match_dup 0)
483790075Sobrien	(compare:CC (match_dup 3)
483890075Sobrien		    (const_int 0)))]
483990075Sobrien  "")
484090075Sobrien
484190075Sobrien(define_insn ""
484290075Sobrien  [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
484390075Sobrien	(compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
484490075Sobrien				 (match_operand:SI 2 "reg_or_cint_operand" "r,i,r,i"))
484590075Sobrien		    (const_int 0)))
484690075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
484790075Sobrien	(ashiftrt:SI (match_dup 1) (match_dup 2)))
484890075Sobrien   (clobber (match_scratch:SI 4 "=q,X,q,X"))]
484990075Sobrien  "TARGET_POWER"
485090075Sobrien  "@
485190075Sobrien   srea. %0,%1,%2
485290075Sobrien   {srai.|srawi.} %0,%1,%h2
485390075Sobrien   #
485490075Sobrien   #"
485590075Sobrien  [(set_attr "type" "delayed_compare")
485690075Sobrien   (set_attr "length" "4,4,8,8")])
485790075Sobrien
485890075Sobrien(define_split
485990075Sobrien  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
486090075Sobrien	(compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
486190075Sobrien				 (match_operand:SI 2 "reg_or_cint_operand" ""))
486290075Sobrien		    (const_int 0)))
486390075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "")
486490075Sobrien	(ashiftrt:SI (match_dup 1) (match_dup 2)))
486590075Sobrien   (clobber (match_scratch:SI 4 ""))]
486690075Sobrien  "TARGET_POWER && reload_completed"
486790075Sobrien  [(parallel [(set (match_dup 0)
486890075Sobrien	(ashiftrt:SI (match_dup 1) (match_dup 2)))
486990075Sobrien   (clobber (match_dup 4))])
487090075Sobrien   (set (match_dup 3)
487190075Sobrien	(compare:CC (match_dup 0)
487290075Sobrien		    (const_int 0)))]
487390075Sobrien  "")
487490075Sobrien
487590075Sobrien(define_insn ""
487690075Sobrien  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
487790075Sobrien	(compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
487890075Sobrien				 (match_operand:SI 2 "reg_or_cint_operand" "ri,ri"))
487990075Sobrien		    (const_int 0)))
488090075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
488190075Sobrien	(ashiftrt:SI (match_dup 1) (match_dup 2)))]
488290075Sobrien  "! TARGET_POWER"
488390075Sobrien  "@
488490075Sobrien   {sra|sraw}%I2. %0,%1,%h2
488590075Sobrien   #"
488690075Sobrien  [(set_attr "type" "delayed_compare")
488790075Sobrien   (set_attr "length" "4,8")])
488890075Sobrien
488990075Sobrien(define_split
489090075Sobrien  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
489190075Sobrien	(compare:CC (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "")
489290075Sobrien				 (match_operand:SI 2 "reg_or_cint_operand" ""))
489390075Sobrien		    (const_int 0)))
489490075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "")
489590075Sobrien	(ashiftrt:SI (match_dup 1) (match_dup 2)))]
489690075Sobrien  "! TARGET_POWER && reload_completed"
489790075Sobrien  [(set (match_dup 0)
489890075Sobrien	(ashiftrt:SI (match_dup 1) (match_dup 2)))
489990075Sobrien   (set (match_dup 3)
490090075Sobrien	(compare:CC (match_dup 0)
490190075Sobrien		    (const_int 0)))]
490290075Sobrien  "")
490390075Sobrien
490490075Sobrien;; Floating-point insns, excluding normal data motion.
490590075Sobrien;;
490690075Sobrien;; PowerPC has a full set of single-precision floating point instructions.
490790075Sobrien;;
490890075Sobrien;; For the POWER architecture, we pretend that we have both SFmode and
490990075Sobrien;; DFmode insns, while, in fact, all fp insns are actually done in double.
491090075Sobrien;; The only conversions we will do will be when storing to memory.  In that
491190075Sobrien;; case, we will use the "frsp" instruction before storing.
491290075Sobrien;;
491390075Sobrien;; Note that when we store into a single-precision memory location, we need to
491490075Sobrien;; use the frsp insn first.  If the register being stored isn't dead, we
491590075Sobrien;; need a scratch register for the frsp.  But this is difficult when the store
491690075Sobrien;; is done by reload.  It is not incorrect to do the frsp on the register in
491790075Sobrien;; this case, we just lose precision that we would have otherwise gotten but
491890075Sobrien;; is not guaranteed.  Perhaps this should be tightened up at some point.
491990075Sobrien
4920169689Skan(define_expand "extendsfdf2"
4921169689Skan  [(set (match_operand:DF 0 "gpc_reg_operand" "")
4922169689Skan	(float_extend:DF (match_operand:SF 1 "reg_or_none500mem_operand" "")))]
4923169689Skan  "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
4924169689Skan  "")
4925169689Skan
4926169689Skan(define_insn_and_split "*extendsfdf2_fpr"
4927169689Skan  [(set (match_operand:DF 0 "gpc_reg_operand" "=f,?f,f")
4928169689Skan	(float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m")))]
4929117395Skan  "TARGET_HARD_FLOAT && TARGET_FPRS"
4930169689Skan  "@
4931169689Skan   #
4932169689Skan   fmr %0,%1
4933169689Skan   lfs%U1%X1 %0,%1"
4934169689Skan  "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
4935169689Skan  [(const_int 0)]
493690075Sobrien{
4937169689Skan  emit_note (NOTE_INSN_DELETED);
4938169689Skan  DONE;
4939169689Skan}
4940169689Skan  [(set_attr "type" "fp,fp,fpload")])
494190075Sobrien
4942169689Skan(define_expand "truncdfsf2"
4943169689Skan  [(set (match_operand:SF 0 "gpc_reg_operand" "")
4944169689Skan	(float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "")))]
4945169689Skan  "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
4946169689Skan  "")
4947169689Skan
4948169689Skan(define_insn "*truncdfsf2_fpr"
494990075Sobrien  [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
495090075Sobrien	(float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "f")))]
4951117395Skan  "TARGET_HARD_FLOAT && TARGET_FPRS"
495290075Sobrien  "frsp %0,%1"
495390075Sobrien  [(set_attr "type" "fp")])
495490075Sobrien
495590075Sobrien(define_insn "aux_truncdfsf2"
495690075Sobrien  [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
4957132718Skan	(unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] UNSPEC_FRSP))]
4958117395Skan  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS"
495990075Sobrien  "frsp %0,%1"
496090075Sobrien  [(set_attr "type" "fp")])
496190075Sobrien
4962117395Skan(define_expand "negsf2"
4963117395Skan  [(set (match_operand:SF 0 "gpc_reg_operand" "")
4964117395Skan	(neg:SF (match_operand:SF 1 "gpc_reg_operand" "")))]
4965117395Skan  "TARGET_HARD_FLOAT"
4966117395Skan  "")
4967117395Skan
4968117395Skan(define_insn "*negsf2"
496990075Sobrien  [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
497090075Sobrien	(neg:SF (match_operand:SF 1 "gpc_reg_operand" "f")))]
4971117395Skan  "TARGET_HARD_FLOAT && TARGET_FPRS"
497290075Sobrien  "fneg %0,%1"
497390075Sobrien  [(set_attr "type" "fp")])
497490075Sobrien
4975117395Skan(define_expand "abssf2"
4976117395Skan  [(set (match_operand:SF 0 "gpc_reg_operand" "")
4977117395Skan	(abs:SF (match_operand:SF 1 "gpc_reg_operand" "")))]
4978117395Skan  "TARGET_HARD_FLOAT"
4979117395Skan  "")
4980117395Skan
4981117395Skan(define_insn "*abssf2"
498290075Sobrien  [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
498390075Sobrien	(abs:SF (match_operand:SF 1 "gpc_reg_operand" "f")))]
4984117395Skan  "TARGET_HARD_FLOAT && TARGET_FPRS"
498590075Sobrien  "fabs %0,%1"
498690075Sobrien  [(set_attr "type" "fp")])
498790075Sobrien
498890075Sobrien(define_insn ""
498990075Sobrien  [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
499090075Sobrien	(neg:SF (abs:SF (match_operand:SF 1 "gpc_reg_operand" "f"))))]
4991117395Skan  "TARGET_HARD_FLOAT && TARGET_FPRS"
499290075Sobrien  "fnabs %0,%1"
499390075Sobrien  [(set_attr "type" "fp")])
499490075Sobrien
499590075Sobrien(define_expand "addsf3"
499690075Sobrien  [(set (match_operand:SF 0 "gpc_reg_operand" "")
499790075Sobrien	(plus:SF (match_operand:SF 1 "gpc_reg_operand" "")
499890075Sobrien		 (match_operand:SF 2 "gpc_reg_operand" "")))]
499990075Sobrien  "TARGET_HARD_FLOAT"
500090075Sobrien  "")
500190075Sobrien
500290075Sobrien(define_insn ""
500390075Sobrien  [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
500490075Sobrien	(plus:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
500590075Sobrien		 (match_operand:SF 2 "gpc_reg_operand" "f")))]
5006117395Skan  "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS"
500790075Sobrien  "fadds %0,%1,%2"
500890075Sobrien  [(set_attr "type" "fp")])
500990075Sobrien
501090075Sobrien(define_insn ""
501190075Sobrien  [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
501290075Sobrien	(plus:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
501390075Sobrien		 (match_operand:SF 2 "gpc_reg_operand" "f")))]
5014117395Skan  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS"
501590075Sobrien  "{fa|fadd} %0,%1,%2"
501690075Sobrien  [(set_attr "type" "fp")])
501790075Sobrien
501890075Sobrien(define_expand "subsf3"
501990075Sobrien  [(set (match_operand:SF 0 "gpc_reg_operand" "")
502090075Sobrien	(minus:SF (match_operand:SF 1 "gpc_reg_operand" "")
502190075Sobrien		  (match_operand:SF 2 "gpc_reg_operand" "")))]
502290075Sobrien  "TARGET_HARD_FLOAT"
502390075Sobrien  "")
502490075Sobrien
502590075Sobrien(define_insn ""
502690075Sobrien  [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
502790075Sobrien	(minus:SF (match_operand:SF 1 "gpc_reg_operand" "f")
502890075Sobrien		  (match_operand:SF 2 "gpc_reg_operand" "f")))]
5029117395Skan  "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS"
503090075Sobrien  "fsubs %0,%1,%2"
503190075Sobrien  [(set_attr "type" "fp")])
503290075Sobrien
503390075Sobrien(define_insn ""
503490075Sobrien  [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
503590075Sobrien	(minus:SF (match_operand:SF 1 "gpc_reg_operand" "f")
503690075Sobrien		  (match_operand:SF 2 "gpc_reg_operand" "f")))]
5037117395Skan  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS"
503890075Sobrien  "{fs|fsub} %0,%1,%2"
503990075Sobrien  [(set_attr "type" "fp")])
504090075Sobrien
504190075Sobrien(define_expand "mulsf3"
504290075Sobrien  [(set (match_operand:SF 0 "gpc_reg_operand" "")
504390075Sobrien	(mult:SF (match_operand:SF 1 "gpc_reg_operand" "")
504490075Sobrien		 (match_operand:SF 2 "gpc_reg_operand" "")))]
504590075Sobrien  "TARGET_HARD_FLOAT"
504690075Sobrien  "")
504790075Sobrien
504890075Sobrien(define_insn ""
504990075Sobrien  [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
505090075Sobrien	(mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
505190075Sobrien		 (match_operand:SF 2 "gpc_reg_operand" "f")))]
5052117395Skan  "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS"
505390075Sobrien  "fmuls %0,%1,%2"
505490075Sobrien  [(set_attr "type" "fp")])
505590075Sobrien
505690075Sobrien(define_insn ""
505790075Sobrien  [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
505890075Sobrien	(mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
505990075Sobrien		 (match_operand:SF 2 "gpc_reg_operand" "f")))]
5060117395Skan  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS"
506190075Sobrien  "{fm|fmul} %0,%1,%2"
506290075Sobrien  [(set_attr "type" "dmul")])
506390075Sobrien
5064169689Skan(define_insn "fres"
5065169689Skan  [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
5066169689Skan	(unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] UNSPEC_FRES))]
5067169689Skan  "TARGET_PPC_GFXOPT && flag_finite_math_only"
5068169689Skan  "fres %0,%1"
5069169689Skan  [(set_attr "type" "fp")])
5070169689Skan
507190075Sobrien(define_expand "divsf3"
507290075Sobrien  [(set (match_operand:SF 0 "gpc_reg_operand" "")
507390075Sobrien	(div:SF (match_operand:SF 1 "gpc_reg_operand" "")
507490075Sobrien		(match_operand:SF 2 "gpc_reg_operand" "")))]
507590075Sobrien  "TARGET_HARD_FLOAT"
5076169689Skan{
5077169689Skan  if (swdiv && !optimize_size && TARGET_PPC_GFXOPT
5078169689Skan  && flag_finite_math_only && !flag_trapping_math)
5079169689Skan    {
5080169689Skan      rs6000_emit_swdivsf (operands[0], operands[1], operands[2]);
5081169689Skan      DONE;
5082169689Skan    }
5083169689Skan})
508490075Sobrien
508590075Sobrien(define_insn ""
508690075Sobrien  [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
508790075Sobrien	(div:SF (match_operand:SF 1 "gpc_reg_operand" "f")
508890075Sobrien		(match_operand:SF 2 "gpc_reg_operand" "f")))]
5089117395Skan  "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS"
509090075Sobrien  "fdivs %0,%1,%2"
509190075Sobrien  [(set_attr "type" "sdiv")])
509290075Sobrien
509390075Sobrien(define_insn ""
509490075Sobrien  [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
509590075Sobrien	(div:SF (match_operand:SF 1 "gpc_reg_operand" "f")
509690075Sobrien		(match_operand:SF 2 "gpc_reg_operand" "f")))]
5097117395Skan  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS"
509890075Sobrien  "{fd|fdiv} %0,%1,%2"
509990075Sobrien  [(set_attr "type" "ddiv")])
510090075Sobrien
510190075Sobrien(define_insn ""
510290075Sobrien  [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
510390075Sobrien	(plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
510490075Sobrien			  (match_operand:SF 2 "gpc_reg_operand" "f"))
510590075Sobrien		 (match_operand:SF 3 "gpc_reg_operand" "f")))]
5106117395Skan  "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD"
510790075Sobrien  "fmadds %0,%1,%2,%3"
510890075Sobrien  [(set_attr "type" "fp")])
510990075Sobrien
511090075Sobrien(define_insn ""
511190075Sobrien  [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
511290075Sobrien	(plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
511390075Sobrien			  (match_operand:SF 2 "gpc_reg_operand" "f"))
511490075Sobrien		 (match_operand:SF 3 "gpc_reg_operand" "f")))]
5115117395Skan  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD"
511690075Sobrien  "{fma|fmadd} %0,%1,%2,%3"
511790075Sobrien  [(set_attr "type" "dmul")])
511890075Sobrien
511990075Sobrien(define_insn ""
512090075Sobrien  [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
512190075Sobrien	(minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
512290075Sobrien			   (match_operand:SF 2 "gpc_reg_operand" "f"))
512390075Sobrien		  (match_operand:SF 3 "gpc_reg_operand" "f")))]
5124117395Skan  "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD"
512590075Sobrien  "fmsubs %0,%1,%2,%3"
512690075Sobrien  [(set_attr "type" "fp")])
512790075Sobrien
512890075Sobrien(define_insn ""
512990075Sobrien  [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
513090075Sobrien	(minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
513190075Sobrien			   (match_operand:SF 2 "gpc_reg_operand" "f"))
513290075Sobrien		  (match_operand:SF 3 "gpc_reg_operand" "f")))]
5133117395Skan  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD"
513490075Sobrien  "{fms|fmsub} %0,%1,%2,%3"
513590075Sobrien  [(set_attr "type" "dmul")])
513690075Sobrien
513790075Sobrien(define_insn ""
513890075Sobrien  [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
513990075Sobrien	(neg:SF (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
514090075Sobrien				  (match_operand:SF 2 "gpc_reg_operand" "f"))
514190075Sobrien			 (match_operand:SF 3 "gpc_reg_operand" "f"))))]
5142117395Skan  "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
5143117395Skan   && HONOR_SIGNED_ZEROS (SFmode)"
514490075Sobrien  "fnmadds %0,%1,%2,%3"
514590075Sobrien  [(set_attr "type" "fp")])
514690075Sobrien
514790075Sobrien(define_insn ""
514890075Sobrien  [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
5149117395Skan	(minus:SF (mult:SF (neg:SF (match_operand:SF 1 "gpc_reg_operand" "f"))
5150117395Skan			   (match_operand:SF 2 "gpc_reg_operand" "f"))
5151117395Skan			 (match_operand:SF 3 "gpc_reg_operand" "f")))]
5152117395Skan  "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
5153117395Skan   && ! HONOR_SIGNED_ZEROS (SFmode)"
5154117395Skan  "fnmadds %0,%1,%2,%3"
5155117395Skan  [(set_attr "type" "fp")])
5156117395Skan
5157117395Skan(define_insn ""
5158117395Skan  [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
515990075Sobrien	(neg:SF (plus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
516090075Sobrien				  (match_operand:SF 2 "gpc_reg_operand" "f"))
516190075Sobrien			 (match_operand:SF 3 "gpc_reg_operand" "f"))))]
5162117395Skan  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD"
516390075Sobrien  "{fnma|fnmadd} %0,%1,%2,%3"
516490075Sobrien  [(set_attr "type" "dmul")])
516590075Sobrien
516690075Sobrien(define_insn ""
516790075Sobrien  [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
5168117395Skan	(minus:SF (mult:SF (neg:SF (match_operand:SF 1 "gpc_reg_operand" "f"))
5169117395Skan			   (match_operand:SF 2 "gpc_reg_operand" "f"))
5170117395Skan			 (match_operand:SF 3 "gpc_reg_operand" "f")))]
5171117395Skan  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
5172117395Skan   && ! HONOR_SIGNED_ZEROS (SFmode)"
5173117395Skan  "{fnma|fnmadd} %0,%1,%2,%3"
5174117395Skan  [(set_attr "type" "dmul")])
5175117395Skan
5176117395Skan(define_insn ""
5177117395Skan  [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
517890075Sobrien	(neg:SF (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
517990075Sobrien				   (match_operand:SF 2 "gpc_reg_operand" "f"))
518090075Sobrien			  (match_operand:SF 3 "gpc_reg_operand" "f"))))]
5181117395Skan  "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
5182117395Skan   && HONOR_SIGNED_ZEROS (SFmode)"
518390075Sobrien  "fnmsubs %0,%1,%2,%3"
518490075Sobrien  [(set_attr "type" "fp")])
518590075Sobrien
518690075Sobrien(define_insn ""
518790075Sobrien  [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
5188117395Skan	(minus:SF (match_operand:SF 3 "gpc_reg_operand" "f")
5189117395Skan		  (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
5190117395Skan			   (match_operand:SF 2 "gpc_reg_operand" "f"))))]
5191117395Skan  "TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
5192117395Skan   && ! HONOR_SIGNED_ZEROS (SFmode)"
5193117395Skan  "fnmsubs %0,%1,%2,%3"
5194117395Skan  [(set_attr "type" "fp")])
5195117395Skan
5196117395Skan(define_insn ""
5197117395Skan  [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
519890075Sobrien	(neg:SF (minus:SF (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
519990075Sobrien				   (match_operand:SF 2 "gpc_reg_operand" "f"))
520090075Sobrien			  (match_operand:SF 3 "gpc_reg_operand" "f"))))]
5201117395Skan  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD"
520290075Sobrien  "{fnms|fnmsub} %0,%1,%2,%3"
520390075Sobrien  [(set_attr "type" "dmul")])
520490075Sobrien
5205117395Skan(define_insn ""
5206117395Skan  [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
5207117395Skan	(minus:SF (match_operand:SF 3 "gpc_reg_operand" "f")
5208117395Skan		  (mult:SF (match_operand:SF 1 "gpc_reg_operand" "%f")
5209117395Skan			   (match_operand:SF 2 "gpc_reg_operand" "f"))))]
5210117395Skan  "! TARGET_POWERPC && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
5211117395Skan   && ! HONOR_SIGNED_ZEROS (SFmode)"
5212117395Skan  "{fnms|fnmsub} %0,%1,%2,%3"
5213169689Skan  [(set_attr "type" "dmul")])
5214117395Skan
521590075Sobrien(define_expand "sqrtsf2"
521690075Sobrien  [(set (match_operand:SF 0 "gpc_reg_operand" "")
521790075Sobrien	(sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "")))]
5218117395Skan  "(TARGET_PPC_GPOPT || TARGET_POWER2) && TARGET_HARD_FLOAT && TARGET_FPRS"
521990075Sobrien  "")
522090075Sobrien
522190075Sobrien(define_insn ""
522290075Sobrien  [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
522390075Sobrien	(sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "f")))]
5224117395Skan  "TARGET_PPC_GPOPT && TARGET_HARD_FLOAT && TARGET_FPRS"
522590075Sobrien  "fsqrts %0,%1"
522690075Sobrien  [(set_attr "type" "ssqrt")])
522790075Sobrien
522890075Sobrien(define_insn ""
522990075Sobrien  [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
523090075Sobrien	(sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "f")))]
5231117395Skan  "TARGET_POWER2 && TARGET_HARD_FLOAT && TARGET_FPRS"
523290075Sobrien  "fsqrt %0,%1"
523390075Sobrien  [(set_attr "type" "dsqrt")])
523490075Sobrien
5235169689Skan(define_expand "copysignsf3"
5236169689Skan  [(set (match_dup 3)
5237169689Skan        (abs:SF (match_operand:SF 1 "gpc_reg_operand" "")))
5238169689Skan   (set (match_dup 4)
5239169689Skan	(neg:SF (abs:SF (match_dup 1))))
5240169689Skan   (set (match_operand:SF 0 "gpc_reg_operand" "")
5241169689Skan        (if_then_else:SF (ge (match_operand:SF 2 "gpc_reg_operand" "")
5242169689Skan	                     (match_dup 5))
5243169689Skan			 (match_dup 3)
5244169689Skan			 (match_dup 4)))]
5245169689Skan  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS
5246169689Skan   && !HONOR_NANS (SFmode) && !HONOR_SIGNED_ZEROS (SFmode)"
5247169689Skan  {
5248169689Skan     operands[3] = gen_reg_rtx (SFmode);
5249169689Skan     operands[4] = gen_reg_rtx (SFmode);
5250169689Skan     operands[5] = CONST0_RTX (SFmode);
5251169689Skan  })
5252169689Skan
5253169689Skan(define_expand "copysigndf3"
5254169689Skan  [(set (match_dup 3)
5255169689Skan        (abs:DF (match_operand:DF 1 "gpc_reg_operand" "")))
5256169689Skan   (set (match_dup 4)
5257169689Skan	(neg:DF (abs:DF (match_dup 1))))
5258169689Skan   (set (match_operand:DF 0 "gpc_reg_operand" "")
5259169689Skan        (if_then_else:DF (ge (match_operand:DF 2 "gpc_reg_operand" "")
5260169689Skan	                     (match_dup 5))
5261169689Skan			 (match_dup 3)
5262169689Skan			 (match_dup 4)))]
5263169689Skan  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS
5264169689Skan   && !HONOR_NANS (DFmode) && !HONOR_SIGNED_ZEROS (DFmode)"
5265169689Skan  {
5266169689Skan     operands[3] = gen_reg_rtx (DFmode);
5267169689Skan     operands[4] = gen_reg_rtx (DFmode);
5268169689Skan     operands[5] = CONST0_RTX (DFmode);
5269169689Skan  })
5270169689Skan
527190075Sobrien;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
527290075Sobrien;; fsel instruction and some auxiliary computations.  Then we just have a
527390075Sobrien;; single DEFINE_INSN for fsel and the define_splits to make them if made by
527490075Sobrien;; combine.
5275169689Skan(define_expand "smaxsf3"
527690075Sobrien  [(set (match_operand:SF 0 "gpc_reg_operand" "")
527790075Sobrien	(if_then_else:SF (ge (match_operand:SF 1 "gpc_reg_operand" "")
527890075Sobrien			     (match_operand:SF 2 "gpc_reg_operand" ""))
527990075Sobrien			 (match_dup 1)
528090075Sobrien			 (match_dup 2)))]
5281169689Skan  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && !flag_trapping_math"
528290075Sobrien  "{ rs6000_emit_minmax (operands[0], SMAX, operands[1], operands[2]); DONE;}")
528390075Sobrien
5284169689Skan(define_expand "sminsf3"
528590075Sobrien  [(set (match_operand:SF 0 "gpc_reg_operand" "")
528690075Sobrien	(if_then_else:SF (ge (match_operand:SF 1 "gpc_reg_operand" "")
528790075Sobrien			     (match_operand:SF 2 "gpc_reg_operand" ""))
528890075Sobrien			 (match_dup 2)
528990075Sobrien			 (match_dup 1)))]
5290169689Skan  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && !flag_trapping_math"
529190075Sobrien  "{ rs6000_emit_minmax (operands[0], SMIN, operands[1], operands[2]); DONE;}")
529290075Sobrien
529390075Sobrien(define_split
529490075Sobrien  [(set (match_operand:SF 0 "gpc_reg_operand" "")
529590075Sobrien	(match_operator:SF 3 "min_max_operator"
529690075Sobrien	 [(match_operand:SF 1 "gpc_reg_operand" "")
529790075Sobrien	  (match_operand:SF 2 "gpc_reg_operand" "")]))]
5298169689Skan  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && !flag_trapping_math"
529990075Sobrien  [(const_int 0)]
530090075Sobrien  "
5301169689Skan{ rs6000_emit_minmax (operands[0], GET_CODE (operands[3]),
530290075Sobrien		      operands[1], operands[2]);
530390075Sobrien  DONE;
530490075Sobrien}")
530590075Sobrien
5306117395Skan(define_expand "movsicc"
5307117395Skan   [(set (match_operand:SI 0 "gpc_reg_operand" "")
5308117395Skan	 (if_then_else:SI (match_operand 1 "comparison_operator" "")
5309117395Skan			  (match_operand:SI 2 "gpc_reg_operand" "")
5310117395Skan			  (match_operand:SI 3 "gpc_reg_operand" "")))]
5311117395Skan  "TARGET_ISEL"
5312117395Skan  "
5313117395Skan{
5314117395Skan  if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5315117395Skan    DONE;
5316117395Skan  else
5317117395Skan    FAIL;
5318117395Skan}")
5319117395Skan
5320117395Skan;; We use the BASE_REGS for the isel input operands because, if rA is
5321117395Skan;; 0, the value of 0 is placed in rD upon truth.  Similarly for rB
5322117395Skan;; because we may switch the operands and rB may end up being rA.
5323117395Skan;;
5324117395Skan;; We need 2 patterns: an unsigned and a signed pattern.  We could
5325117395Skan;; leave out the mode in operand 4 and use one pattern, but reload can
5326117395Skan;; change the mode underneath our feet and then gets confused trying
5327117395Skan;; to reload the value.
5328117395Skan(define_insn "isel_signed"
5329117395Skan  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
5330117395Skan	(if_then_else:SI
5331117395Skan	 (match_operator 1 "comparison_operator"
5332117395Skan			 [(match_operand:CC 4 "cc_reg_operand" "y")
5333117395Skan			  (const_int 0)])
5334117395Skan	 (match_operand:SI 2 "gpc_reg_operand" "b")
5335117395Skan	 (match_operand:SI 3 "gpc_reg_operand" "b")))]
5336117395Skan  "TARGET_ISEL"
5337117395Skan  "*
5338117395Skan{ return output_isel (operands); }"
5339117395Skan  [(set_attr "length" "4")])
5340117395Skan
5341117395Skan(define_insn "isel_unsigned"
5342117395Skan  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
5343117395Skan	(if_then_else:SI
5344117395Skan	 (match_operator 1 "comparison_operator"
5345117395Skan			 [(match_operand:CCUNS 4 "cc_reg_operand" "y")
5346117395Skan			  (const_int 0)])
5347117395Skan	 (match_operand:SI 2 "gpc_reg_operand" "b")
5348117395Skan	 (match_operand:SI 3 "gpc_reg_operand" "b")))]
5349117395Skan  "TARGET_ISEL"
5350117395Skan  "*
5351117395Skan{ return output_isel (operands); }"
5352117395Skan  [(set_attr "length" "4")])
5353117395Skan
535490075Sobrien(define_expand "movsfcc"
535590075Sobrien   [(set (match_operand:SF 0 "gpc_reg_operand" "")
535690075Sobrien	 (if_then_else:SF (match_operand 1 "comparison_operator" "")
535790075Sobrien			  (match_operand:SF 2 "gpc_reg_operand" "")
535890075Sobrien			  (match_operand:SF 3 "gpc_reg_operand" "")))]
5359117395Skan  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS"
536090075Sobrien  "
536190075Sobrien{
536290075Sobrien  if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
536390075Sobrien    DONE;
536490075Sobrien  else
536590075Sobrien    FAIL;
536690075Sobrien}")
536790075Sobrien
536890075Sobrien(define_insn "*fselsfsf4"
536990075Sobrien  [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
537090075Sobrien	(if_then_else:SF (ge (match_operand:SF 1 "gpc_reg_operand" "f")
537190075Sobrien			     (match_operand:SF 4 "zero_fp_constant" "F"))
537290075Sobrien			 (match_operand:SF 2 "gpc_reg_operand" "f")
537390075Sobrien			 (match_operand:SF 3 "gpc_reg_operand" "f")))]
5374117395Skan  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS"
537590075Sobrien  "fsel %0,%1,%2,%3"
537690075Sobrien  [(set_attr "type" "fp")])
537790075Sobrien
537890075Sobrien(define_insn "*fseldfsf4"
537990075Sobrien  [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
538090075Sobrien	(if_then_else:SF (ge (match_operand:DF 1 "gpc_reg_operand" "f")
538190075Sobrien			     (match_operand:DF 4 "zero_fp_constant" "F"))
538290075Sobrien			 (match_operand:SF 2 "gpc_reg_operand" "f")
538390075Sobrien			 (match_operand:SF 3 "gpc_reg_operand" "f")))]
5384117395Skan  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS"
538590075Sobrien  "fsel %0,%1,%2,%3"
538690075Sobrien  [(set_attr "type" "fp")])
538790075Sobrien
5388169689Skan(define_expand "negdf2"
5389169689Skan  [(set (match_operand:DF 0 "gpc_reg_operand" "")
5390169689Skan	(neg:DF (match_operand:DF 1 "gpc_reg_operand" "")))]
5391169689Skan  "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
5392169689Skan  "")
5393169689Skan
5394169689Skan(define_insn "*negdf2_fpr"
539590075Sobrien  [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
539690075Sobrien	(neg:DF (match_operand:DF 1 "gpc_reg_operand" "f")))]
5397117395Skan  "TARGET_HARD_FLOAT && TARGET_FPRS"
539890075Sobrien  "fneg %0,%1"
539990075Sobrien  [(set_attr "type" "fp")])
540090075Sobrien
5401169689Skan(define_expand "absdf2"
5402169689Skan  [(set (match_operand:DF 0 "gpc_reg_operand" "")
5403169689Skan	(abs:DF (match_operand:DF 1 "gpc_reg_operand" "")))]
5404169689Skan  "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
5405169689Skan  "")
5406169689Skan
5407169689Skan(define_insn "*absdf2_fpr"
540890075Sobrien  [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
540990075Sobrien	(abs:DF (match_operand:DF 1 "gpc_reg_operand" "f")))]
5410117395Skan  "TARGET_HARD_FLOAT && TARGET_FPRS"
541190075Sobrien  "fabs %0,%1"
541290075Sobrien  [(set_attr "type" "fp")])
541390075Sobrien
5414169689Skan(define_insn "*nabsdf2_fpr"
541590075Sobrien  [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
541690075Sobrien	(neg:DF (abs:DF (match_operand:DF 1 "gpc_reg_operand" "f"))))]
5417117395Skan  "TARGET_HARD_FLOAT && TARGET_FPRS"
541890075Sobrien  "fnabs %0,%1"
541990075Sobrien  [(set_attr "type" "fp")])
542090075Sobrien
5421169689Skan(define_expand "adddf3"
5422169689Skan  [(set (match_operand:DF 0 "gpc_reg_operand" "")
5423169689Skan	(plus:DF (match_operand:DF 1 "gpc_reg_operand" "")
5424169689Skan		 (match_operand:DF 2 "gpc_reg_operand" "")))]
5425169689Skan  "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
5426169689Skan  "")
5427169689Skan
5428169689Skan(define_insn "*adddf3_fpr"
542990075Sobrien  [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
543090075Sobrien	(plus:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
543190075Sobrien		 (match_operand:DF 2 "gpc_reg_operand" "f")))]
5432117395Skan  "TARGET_HARD_FLOAT && TARGET_FPRS"
543390075Sobrien  "{fa|fadd} %0,%1,%2"
543490075Sobrien  [(set_attr "type" "fp")])
543590075Sobrien
5436169689Skan(define_expand "subdf3"
5437169689Skan  [(set (match_operand:DF 0 "gpc_reg_operand" "")
5438169689Skan	(minus:DF (match_operand:DF 1 "gpc_reg_operand" "")
5439169689Skan		  (match_operand:DF 2 "gpc_reg_operand" "")))]
5440169689Skan  "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
5441169689Skan  "")
5442169689Skan
5443169689Skan(define_insn "*subdf3_fpr"
544490075Sobrien  [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
544590075Sobrien	(minus:DF (match_operand:DF 1 "gpc_reg_operand" "f")
544690075Sobrien		  (match_operand:DF 2 "gpc_reg_operand" "f")))]
5447117395Skan  "TARGET_HARD_FLOAT && TARGET_FPRS"
544890075Sobrien  "{fs|fsub} %0,%1,%2"
544990075Sobrien  [(set_attr "type" "fp")])
545090075Sobrien
5451169689Skan(define_expand "muldf3"
5452169689Skan  [(set (match_operand:DF 0 "gpc_reg_operand" "")
5453169689Skan	(mult:DF (match_operand:DF 1 "gpc_reg_operand" "")
5454169689Skan		 (match_operand:DF 2 "gpc_reg_operand" "")))]
5455169689Skan  "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
5456169689Skan  "")
5457169689Skan
5458169689Skan(define_insn "*muldf3_fpr"
545990075Sobrien  [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
546090075Sobrien	(mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
546190075Sobrien		 (match_operand:DF 2 "gpc_reg_operand" "f")))]
5462117395Skan  "TARGET_HARD_FLOAT && TARGET_FPRS"
546390075Sobrien  "{fm|fmul} %0,%1,%2"
546490075Sobrien  [(set_attr "type" "dmul")])
546590075Sobrien
5466169689Skan(define_insn "fred"
546790075Sobrien  [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
5468169689Skan	(unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "f")] UNSPEC_FRES))]
5469169689Skan  "TARGET_POPCNTB && flag_finite_math_only"
5470169689Skan  "fre %0,%1"
5471169689Skan  [(set_attr "type" "fp")])
5472169689Skan
5473169689Skan(define_expand "divdf3"
5474169689Skan  [(set (match_operand:DF 0 "gpc_reg_operand" "")
5475169689Skan	(div:DF (match_operand:DF 1 "gpc_reg_operand" "")
5476169689Skan		(match_operand:DF 2 "gpc_reg_operand" "")))]
5477169689Skan  "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
5478169689Skan{
5479169689Skan  if (swdiv && !optimize_size && TARGET_POPCNTB
5480169689Skan  && flag_finite_math_only && !flag_trapping_math)
5481169689Skan    {
5482169689Skan      rs6000_emit_swdivdf (operands[0], operands[1], operands[2]);
5483169689Skan      DONE;
5484169689Skan    }
5485169689Skan})
5486169689Skan
5487169689Skan(define_insn "*divdf3_fpr"
5488169689Skan  [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
548990075Sobrien	(div:DF (match_operand:DF 1 "gpc_reg_operand" "f")
549090075Sobrien		(match_operand:DF 2 "gpc_reg_operand" "f")))]
5491117395Skan  "TARGET_HARD_FLOAT && TARGET_FPRS"
549290075Sobrien  "{fd|fdiv} %0,%1,%2"
549390075Sobrien  [(set_attr "type" "ddiv")])
549490075Sobrien
549590075Sobrien(define_insn ""
549690075Sobrien  [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
549790075Sobrien	(plus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
549890075Sobrien			  (match_operand:DF 2 "gpc_reg_operand" "f"))
549990075Sobrien		 (match_operand:DF 3 "gpc_reg_operand" "f")))]
5500117395Skan  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD"
550190075Sobrien  "{fma|fmadd} %0,%1,%2,%3"
550290075Sobrien  [(set_attr "type" "dmul")])
550390075Sobrien
550490075Sobrien(define_insn ""
550590075Sobrien  [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
550690075Sobrien	(minus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
550790075Sobrien			   (match_operand:DF 2 "gpc_reg_operand" "f"))
550890075Sobrien		  (match_operand:DF 3 "gpc_reg_operand" "f")))]
5509117395Skan  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD"
551090075Sobrien  "{fms|fmsub} %0,%1,%2,%3"
551190075Sobrien  [(set_attr "type" "dmul")])
551290075Sobrien
551390075Sobrien(define_insn ""
551490075Sobrien  [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
551590075Sobrien	(neg:DF (plus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
551690075Sobrien				  (match_operand:DF 2 "gpc_reg_operand" "f"))
551790075Sobrien			 (match_operand:DF 3 "gpc_reg_operand" "f"))))]
5518117395Skan  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
5519117395Skan   && HONOR_SIGNED_ZEROS (DFmode)"
552090075Sobrien  "{fnma|fnmadd} %0,%1,%2,%3"
552190075Sobrien  [(set_attr "type" "dmul")])
552290075Sobrien
552390075Sobrien(define_insn ""
552490075Sobrien  [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
5525117395Skan	(minus:DF (mult:DF (neg:DF (match_operand:DF 1 "gpc_reg_operand" "f"))
5526117395Skan			   (match_operand:DF 2 "gpc_reg_operand" "f"))
5527117395Skan		  (match_operand:DF 3 "gpc_reg_operand" "f")))]
5528117395Skan  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
5529117395Skan   && ! HONOR_SIGNED_ZEROS (DFmode)"
5530117395Skan  "{fnma|fnmadd} %0,%1,%2,%3"
5531117395Skan  [(set_attr "type" "dmul")])
5532117395Skan
5533117395Skan(define_insn ""
5534117395Skan  [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
553590075Sobrien	(neg:DF (minus:DF (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
553690075Sobrien				   (match_operand:DF 2 "gpc_reg_operand" "f"))
553790075Sobrien			  (match_operand:DF 3 "gpc_reg_operand" "f"))))]
5538117395Skan  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
5539117395Skan   && HONOR_SIGNED_ZEROS (DFmode)"
554090075Sobrien  "{fnms|fnmsub} %0,%1,%2,%3"
554190075Sobrien  [(set_attr "type" "dmul")])
554290075Sobrien
5543117395Skan(define_insn ""
5544117395Skan  [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
5545117395Skan	(minus:DF (match_operand:DF 3 "gpc_reg_operand" "f")
5546117395Skan	          (mult:DF (match_operand:DF 1 "gpc_reg_operand" "%f")
5547117395Skan			   (match_operand:DF 2 "gpc_reg_operand" "f"))))]
5548169689Skan  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_FUSED_MADD
5549117395Skan   && ! HONOR_SIGNED_ZEROS (DFmode)"
5550117395Skan  "{fnms|fnmsub} %0,%1,%2,%3"
5551117395Skan  [(set_attr "type" "dmul")])
5552117395Skan
555390075Sobrien(define_insn "sqrtdf2"
555490075Sobrien  [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
555590075Sobrien	(sqrt:DF (match_operand:DF 1 "gpc_reg_operand" "f")))]
5556117395Skan  "(TARGET_PPC_GPOPT || TARGET_POWER2) && TARGET_HARD_FLOAT && TARGET_FPRS"
555790075Sobrien  "fsqrt %0,%1"
555890075Sobrien  [(set_attr "type" "dsqrt")])
555990075Sobrien
556090075Sobrien;; The conditional move instructions allow us to perform max and min
5561169689Skan;; operations even when
556290075Sobrien
5563169689Skan(define_expand "smaxdf3"
556490075Sobrien  [(set (match_operand:DF 0 "gpc_reg_operand" "")
556590075Sobrien	(if_then_else:DF (ge (match_operand:DF 1 "gpc_reg_operand" "")
556690075Sobrien			     (match_operand:DF 2 "gpc_reg_operand" ""))
556790075Sobrien			 (match_dup 1)
556890075Sobrien			 (match_dup 2)))]
5569169689Skan  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && !flag_trapping_math"
557090075Sobrien  "{ rs6000_emit_minmax (operands[0], SMAX, operands[1], operands[2]); DONE;}")
557190075Sobrien
5572169689Skan(define_expand "smindf3"
557390075Sobrien  [(set (match_operand:DF 0 "gpc_reg_operand" "")
557490075Sobrien	(if_then_else:DF (ge (match_operand:DF 1 "gpc_reg_operand" "")
557590075Sobrien			     (match_operand:DF 2 "gpc_reg_operand" ""))
557690075Sobrien			 (match_dup 2)
557790075Sobrien			 (match_dup 1)))]
5578169689Skan  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && !flag_trapping_math"
557990075Sobrien  "{ rs6000_emit_minmax (operands[0], SMIN, operands[1], operands[2]); DONE;}")
558090075Sobrien
558190075Sobrien(define_split
558290075Sobrien  [(set (match_operand:DF 0 "gpc_reg_operand" "")
558390075Sobrien	(match_operator:DF 3 "min_max_operator"
558490075Sobrien	 [(match_operand:DF 1 "gpc_reg_operand" "")
558590075Sobrien	  (match_operand:DF 2 "gpc_reg_operand" "")]))]
5586169689Skan  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS && !flag_trapping_math"
558790075Sobrien  [(const_int 0)]
558890075Sobrien  "
5589169689Skan{ rs6000_emit_minmax (operands[0], GET_CODE (operands[3]),
559090075Sobrien		      operands[1], operands[2]);
559190075Sobrien  DONE;
559290075Sobrien}")
559390075Sobrien
559490075Sobrien(define_expand "movdfcc"
559590075Sobrien   [(set (match_operand:DF 0 "gpc_reg_operand" "")
559690075Sobrien	 (if_then_else:DF (match_operand 1 "comparison_operator" "")
559790075Sobrien			  (match_operand:DF 2 "gpc_reg_operand" "")
559890075Sobrien			  (match_operand:DF 3 "gpc_reg_operand" "")))]
5599117395Skan  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS"
560090075Sobrien  "
560190075Sobrien{
560290075Sobrien  if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
560390075Sobrien    DONE;
560490075Sobrien  else
560590075Sobrien    FAIL;
560690075Sobrien}")
560790075Sobrien
560890075Sobrien(define_insn "*fseldfdf4"
560990075Sobrien  [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
561090075Sobrien	(if_then_else:DF (ge (match_operand:DF 1 "gpc_reg_operand" "f")
561190075Sobrien			     (match_operand:DF 4 "zero_fp_constant" "F"))
561290075Sobrien			 (match_operand:DF 2 "gpc_reg_operand" "f")
561390075Sobrien			 (match_operand:DF 3 "gpc_reg_operand" "f")))]
5614117395Skan  "TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS"
561590075Sobrien  "fsel %0,%1,%2,%3"
561690075Sobrien  [(set_attr "type" "fp")])
561790075Sobrien
561890075Sobrien(define_insn "*fselsfdf4"
561990075Sobrien  [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
562090075Sobrien	(if_then_else:DF (ge (match_operand:SF 1 "gpc_reg_operand" "f")
562190075Sobrien			     (match_operand:SF 4 "zero_fp_constant" "F"))
562290075Sobrien			 (match_operand:DF 2 "gpc_reg_operand" "f")
562390075Sobrien			 (match_operand:DF 3 "gpc_reg_operand" "f")))]
562490075Sobrien  "TARGET_PPC_GFXOPT"
562590075Sobrien  "fsel %0,%1,%2,%3"
562690075Sobrien  [(set_attr "type" "fp")])
562790075Sobrien
562890075Sobrien;; Conversions to and from floating-point.
562990075Sobrien
5630132718Skan(define_expand "fixuns_truncsfsi2"
5631117395Skan  [(set (match_operand:SI 0 "gpc_reg_operand" "")
5632132718Skan	(unsigned_fix:SI (match_operand:SF 1 "gpc_reg_operand" "")))]
5633117395Skan  "TARGET_HARD_FLOAT && !TARGET_FPRS"
5634117395Skan  "")
5635117395Skan
5636117395Skan(define_expand "fix_truncsfsi2"
5637117395Skan  [(set (match_operand:SI 0 "gpc_reg_operand" "")
5638117395Skan	(fix:SI (match_operand:SF 1 "gpc_reg_operand" "")))]
5639117395Skan  "TARGET_HARD_FLOAT && !TARGET_FPRS"
5640117395Skan  "")
5641117395Skan
564290075Sobrien; For each of these conversions, there is a define_expand, a define_insn
564390075Sobrien; with a '#' template, and a define_split (with C code).  The idea is
564490075Sobrien; to allow constant folding with the template of the define_insn,
564590075Sobrien; then to have the insns split later (between sched1 and final).
564690075Sobrien
564790075Sobrien(define_expand "floatsidf2"
564890075Sobrien  [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
564990075Sobrien		   (float:DF (match_operand:SI 1 "gpc_reg_operand" "")))
565090075Sobrien	      (use (match_dup 2))
565190075Sobrien	      (use (match_dup 3))
565290075Sobrien	      (clobber (match_dup 4))
565390075Sobrien	      (clobber (match_dup 5))
565490075Sobrien	      (clobber (match_dup 6))])]
5655117395Skan  "TARGET_HARD_FLOAT && TARGET_FPRS"
565690075Sobrien  "
565790075Sobrien{
5658169689Skan  if (TARGET_E500_DOUBLE)
5659169689Skan    {
5660169689Skan      emit_insn (gen_spe_floatsidf2 (operands[0], operands[1]));
5661169689Skan      DONE;
5662169689Skan    }
5663102780Skan  if (TARGET_POWERPC64)
5664102780Skan    {
5665102780Skan      rtx mem = assign_stack_temp (DImode, GET_MODE_SIZE (DImode), 0);
5666102780Skan      rtx t1 = gen_reg_rtx (DImode);
5667102780Skan      rtx t2 = gen_reg_rtx (DImode);
5668102780Skan      emit_insn (gen_floatsidf_ppc64 (operands[0], operands[1], mem, t1, t2));
5669102780Skan      DONE;
5670102780Skan    }
5671102780Skan
567290075Sobrien  operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5673117395Skan  operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
567490075Sobrien  operands[4] = assign_stack_temp (DFmode, GET_MODE_SIZE (DFmode), 0);
567590075Sobrien  operands[5] = gen_reg_rtx (DFmode);
567690075Sobrien  operands[6] = gen_reg_rtx (SImode);
567790075Sobrien}")
567890075Sobrien
5679169689Skan(define_insn_and_split "*floatsidf2_internal"
568090075Sobrien  [(set (match_operand:DF 0 "gpc_reg_operand" "=&f")
568190075Sobrien	(float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
568290075Sobrien   (use (match_operand:SI 2 "gpc_reg_operand" "r"))
568390075Sobrien   (use (match_operand:DF 3 "gpc_reg_operand" "f"))
568490075Sobrien   (clobber (match_operand:DF 4 "memory_operand" "=o"))
5685132718Skan   (clobber (match_operand:DF 5 "gpc_reg_operand" "=&f"))
5686132718Skan   (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5687117395Skan  "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS"
568890075Sobrien  "#"
5689169689Skan  "&& (!no_new_pseudos || offsettable_nonstrict_memref_p (operands[4]))"
5690169689Skan  [(pc)]
569190075Sobrien  "
569290075Sobrien{
569390075Sobrien  rtx lowword, highword;
5694169689Skan  gcc_assert (MEM_P (operands[4]));
5695169689Skan  highword = adjust_address (operands[4], SImode, 0);
5696169689Skan  lowword = adjust_address (operands[4], SImode, 4);
569790075Sobrien  if (! WORDS_BIG_ENDIAN)
569890075Sobrien    {
569990075Sobrien      rtx tmp;
570090075Sobrien      tmp = highword; highword = lowword; lowword = tmp;
570190075Sobrien    }
570290075Sobrien
5703169689Skan  emit_insn (gen_xorsi3 (operands[6], operands[1],
570490075Sobrien			 GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5705169689Skan  emit_move_insn (lowword, operands[6]);
5706169689Skan  emit_move_insn (highword, operands[2]);
570790075Sobrien  emit_move_insn (operands[5], operands[4]);
570890075Sobrien  emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
570990075Sobrien  DONE;
5710169689Skan}"
5711169689Skan  [(set_attr "length" "24")])
571290075Sobrien
5713117395Skan(define_expand "floatunssisf2"
5714117395Skan  [(set (match_operand:SF 0 "gpc_reg_operand" "")
5715117395Skan        (unsigned_float:SF (match_operand:SI 1 "gpc_reg_operand" "")))]
5716117395Skan  "TARGET_HARD_FLOAT && !TARGET_FPRS"
5717117395Skan  "")
5718117395Skan
571990075Sobrien(define_expand "floatunssidf2"
572090075Sobrien  [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
572190075Sobrien		   (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "")))
572290075Sobrien	      (use (match_dup 2))
572390075Sobrien	      (use (match_dup 3))
572490075Sobrien	      (clobber (match_dup 4))
572590075Sobrien	      (clobber (match_dup 5))])]
5726169689Skan  "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
572790075Sobrien  "
572890075Sobrien{
5729169689Skan  if (TARGET_E500_DOUBLE)
5730169689Skan    {
5731169689Skan      emit_insn (gen_spe_floatunssidf2 (operands[0], operands[1]));
5732169689Skan      DONE;
5733169689Skan    }
5734102780Skan  if (TARGET_POWERPC64)
5735102780Skan    {
5736102780Skan      rtx mem = assign_stack_temp (DImode, GET_MODE_SIZE (DImode), 0);
5737102780Skan      rtx t1 = gen_reg_rtx (DImode);
5738102780Skan      rtx t2 = gen_reg_rtx (DImode);
5739102780Skan      emit_insn (gen_floatunssidf_ppc64 (operands[0], operands[1], mem,
5740102780Skan					 t1, t2));
5741102780Skan      DONE;
5742102780Skan    }
5743102780Skan
574490075Sobrien  operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5745117395Skan  operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
574690075Sobrien  operands[4] = assign_stack_temp (DFmode, GET_MODE_SIZE (DFmode), 0);
574790075Sobrien  operands[5] = gen_reg_rtx (DFmode);
574890075Sobrien}")
574990075Sobrien
5750169689Skan(define_insn_and_split "*floatunssidf2_internal"
575190075Sobrien  [(set (match_operand:DF 0 "gpc_reg_operand" "=&f")
575290075Sobrien	(unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
575390075Sobrien   (use (match_operand:SI 2 "gpc_reg_operand" "r"))
575490075Sobrien   (use (match_operand:DF 3 "gpc_reg_operand" "f"))
575590075Sobrien   (clobber (match_operand:DF 4 "memory_operand" "=o"))
5756132718Skan   (clobber (match_operand:DF 5 "gpc_reg_operand" "=&f"))]
5757117395Skan  "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS"
575890075Sobrien  "#"
5759169689Skan  "&& (!no_new_pseudos || offsettable_nonstrict_memref_p (operands[4]))"
5760169689Skan  [(pc)]
576190075Sobrien  "
576290075Sobrien{
576390075Sobrien  rtx lowword, highword;
5764169689Skan  gcc_assert (MEM_P (operands[4]));
5765169689Skan  highword = adjust_address (operands[4], SImode, 0);
5766169689Skan  lowword = adjust_address (operands[4], SImode, 4);
576790075Sobrien  if (! WORDS_BIG_ENDIAN)
576890075Sobrien    {
576990075Sobrien      rtx tmp;
577090075Sobrien      tmp = highword; highword = lowword; lowword = tmp;
577190075Sobrien    }
577290075Sobrien
5773169689Skan  emit_move_insn (lowword, operands[1]);
5774169689Skan  emit_move_insn (highword, operands[2]);
577590075Sobrien  emit_move_insn (operands[5], operands[4]);
577690075Sobrien  emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
577790075Sobrien  DONE;
5778169689Skan}"
5779169689Skan  [(set_attr "length" "20")])
578090075Sobrien
578190075Sobrien(define_expand "fix_truncdfsi2"
5782169689Skan  [(parallel [(set (match_operand:SI 0 "fix_trunc_dest_operand" "")
578390075Sobrien		   (fix:SI (match_operand:DF 1 "gpc_reg_operand" "")))
578490075Sobrien	      (clobber (match_dup 2))
578590075Sobrien	      (clobber (match_dup 3))])]
5786169689Skan  "(TARGET_POWER2 || TARGET_POWERPC)
5787169689Skan   && TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
578890075Sobrien  "
578990075Sobrien{
5790169689Skan  if (TARGET_E500_DOUBLE)
5791169689Skan    {
5792169689Skan     emit_insn (gen_spe_fix_truncdfsi2 (operands[0], operands[1]));
5793169689Skan     DONE;
5794169689Skan    }
579590075Sobrien  operands[2] = gen_reg_rtx (DImode);
5796169689Skan  if (TARGET_PPC_GFXOPT)
5797169689Skan    {
5798169689Skan      rtx orig_dest = operands[0];
5799169689Skan      if (! memory_operand (orig_dest, GET_MODE (orig_dest)))
5800169689Skan	operands[0] = assign_stack_temp (SImode, GET_MODE_SIZE (SImode), 0);
5801169689Skan      emit_insn (gen_fix_truncdfsi2_internal_gfxopt (operands[0], operands[1],
5802169689Skan						     operands[2]));
5803169689Skan      if (operands[0] != orig_dest)
5804169689Skan	emit_move_insn (orig_dest, operands[0]);
5805169689Skan      DONE;
5806169689Skan    }
580790075Sobrien  operands[3] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode), 0);
580890075Sobrien}")
580990075Sobrien
5810169689Skan(define_insn_and_split "*fix_truncdfsi2_internal"
581190075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
581290075Sobrien	(fix:SI (match_operand:DF 1 "gpc_reg_operand" "f")))
5813117395Skan   (clobber (match_operand:DI 2 "gpc_reg_operand" "=f"))
581490075Sobrien   (clobber (match_operand:DI 3 "memory_operand" "=o"))]
5815117395Skan  "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS"
581690075Sobrien  "#"
5817169689Skan  "&& (!no_new_pseudos || offsettable_nonstrict_memref_p (operands[3]))"
5818169689Skan  [(pc)]
581990075Sobrien  "
582090075Sobrien{
582190075Sobrien  rtx lowword;
5822169689Skan  gcc_assert (MEM_P (operands[3]));
5823169689Skan  lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
582490075Sobrien
582590075Sobrien  emit_insn (gen_fctiwz (operands[2], operands[1]));
582690075Sobrien  emit_move_insn (operands[3], operands[2]);
5827169689Skan  emit_move_insn (operands[0], lowword);
582890075Sobrien  DONE;
5829169689Skan}"
5830169689Skan  [(set_attr "length" "16")])
583190075Sobrien
5832169689Skan(define_insn_and_split "fix_truncdfsi2_internal_gfxopt"
5833169689Skan  [(set (match_operand:SI 0 "memory_operand" "=Z")
5834169689Skan	(fix:SI (match_operand:DF 1 "gpc_reg_operand" "f")))
5835169689Skan   (clobber (match_operand:DI 2 "gpc_reg_operand" "=f"))]
5836169689Skan  "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS
5837169689Skan   && TARGET_PPC_GFXOPT"
5838169689Skan  "#"
5839169689Skan  "&& 1"
5840169689Skan  [(pc)]
5841169689Skan  "
5842169689Skan{
5843169689Skan  emit_insn (gen_fctiwz (operands[2], operands[1]));
5844169689Skan  emit_insn (gen_stfiwx (operands[0], operands[2]));
5845169689Skan  DONE;
5846169689Skan}"
5847169689Skan  [(set_attr "length" "16")])
5848169689Skan
5849132718Skan; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
585090075Sobrien; rather than (set (subreg:SI (reg)) (fix:SI ...))
585190075Sobrien; because the first makes it clear that operand 0 is not live
585290075Sobrien; before the instruction.
585390075Sobrien(define_insn "fctiwz"
5854169689Skan  [(set (match_operand:DI 0 "gpc_reg_operand" "=f")
5855132718Skan	(unspec:DI [(fix:SI (match_operand:DF 1 "gpc_reg_operand" "f"))]
5856132718Skan		   UNSPEC_FCTIWZ))]
5857117395Skan  "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS"
585890075Sobrien  "{fcirz|fctiwz} %0,%1"
585990075Sobrien  [(set_attr "type" "fp")])
586090075Sobrien
5861169689Skan(define_insn "btruncdf2"
5862169689Skan  [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
5863169689Skan	(unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "f")] UNSPEC_FRIZ))]
5864169689Skan  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS"
5865169689Skan  "friz %0,%1"
5866169689Skan  [(set_attr "type" "fp")])
5867169689Skan
5868169689Skan(define_insn "btruncsf2"
5869169689Skan  [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
5870169689Skan	(unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] UNSPEC_FRIZ))]
5871169689Skan  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS"
5872169689Skan  "friz %0,%1"
5873169689Skan  [(set_attr "type" "fp")])
5874169689Skan
5875169689Skan(define_insn "ceildf2"
5876169689Skan  [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
5877169689Skan	(unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "f")] UNSPEC_FRIP))]
5878169689Skan  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS"
5879169689Skan  "frip %0,%1"
5880169689Skan  [(set_attr "type" "fp")])
5881169689Skan
5882169689Skan(define_insn "ceilsf2"
5883169689Skan [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
5884169689Skan	(unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] UNSPEC_FRIP))]
5885169689Skan  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS"
5886169689Skan  "frip %0,%1"
5887169689Skan  [(set_attr "type" "fp")])
5888169689Skan
5889169689Skan(define_insn "floordf2"
5890169689Skan  [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
5891169689Skan	(unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "f")] UNSPEC_FRIM))]
5892169689Skan  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS"
5893169689Skan  "frim %0,%1"
5894169689Skan  [(set_attr "type" "fp")])
5895169689Skan
5896169689Skan(define_insn "floorsf2"
5897169689Skan  [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
5898169689Skan	(unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] UNSPEC_FRIM))]
5899169689Skan  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS"
5900169689Skan  "frim %0,%1"
5901169689Skan  [(set_attr "type" "fp")])
5902169689Skan
5903169689Skan(define_insn "rounddf2"
5904169689Skan  [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
5905169689Skan	(unspec:DF [(match_operand:DF 1 "gpc_reg_operand" "f")] UNSPEC_FRIN))]
5906169689Skan  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS"
5907169689Skan  "frin %0,%1"
5908169689Skan  [(set_attr "type" "fp")])
5909169689Skan
5910169689Skan(define_insn "roundsf2"
5911169689Skan  [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
5912169689Skan	(unspec:SF [(match_operand:SF 1 "gpc_reg_operand" "f")] UNSPEC_FRIN))]
5913169689Skan  "TARGET_FPRND && TARGET_HARD_FLOAT && TARGET_FPRS"
5914169689Skan  "frin %0,%1"
5915169689Skan  [(set_attr "type" "fp")])
5916169689Skan
5917169689Skan; An UNSPEC is used so we don't have to support SImode in FP registers.
5918169689Skan(define_insn "stfiwx"
5919169689Skan  [(set (match_operand:SI 0 "memory_operand" "=Z")
5920169689Skan	(unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "f")]
5921169689Skan		   UNSPEC_STFIWX))]
5922169689Skan  "TARGET_PPC_GFXOPT"
5923169689Skan  "stfiwx %1,%y0"
5924169689Skan  [(set_attr "type" "fpstore")])
5925169689Skan
5926117395Skan(define_expand "floatsisf2"
5927117395Skan  [(set (match_operand:SF 0 "gpc_reg_operand" "")
5928117395Skan        (float:SF (match_operand:SI 1 "gpc_reg_operand" "")))]
5929117395Skan  "TARGET_HARD_FLOAT && !TARGET_FPRS"
5930117395Skan  "")
5931117395Skan
593290075Sobrien(define_insn "floatdidf2"
593390075Sobrien  [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
5934102780Skan	(float:DF (match_operand:DI 1 "gpc_reg_operand" "*f")))]
5935117395Skan  "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS"
593690075Sobrien  "fcfid %0,%1"
593790075Sobrien  [(set_attr "type" "fp")])
593890075Sobrien
5939102780Skan(define_insn_and_split "floatsidf_ppc64"
5940102780Skan  [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
5941102780Skan	(float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5942102780Skan   (clobber (match_operand:DI 2 "memory_operand" "=o"))
5943102780Skan   (clobber (match_operand:DI 3 "gpc_reg_operand" "=r"))
5944102780Skan   (clobber (match_operand:DI 4 "gpc_reg_operand" "=f"))]
5945117395Skan  "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS"
5946102780Skan  "#"
5947132718Skan  "&& 1"
5948102780Skan  [(set (match_dup 3) (sign_extend:DI (match_dup 1)))
5949102780Skan   (set (match_dup 2) (match_dup 3))
5950102780Skan   (set (match_dup 4) (match_dup 2))
5951102780Skan   (set (match_dup 0) (float:DF (match_dup 4)))]
5952102780Skan  "")
5953102780Skan
5954102780Skan(define_insn_and_split "floatunssidf_ppc64"
5955102780Skan  [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
5956102780Skan	(unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5957102780Skan   (clobber (match_operand:DI 2 "memory_operand" "=o"))
5958102780Skan   (clobber (match_operand:DI 3 "gpc_reg_operand" "=r"))
5959102780Skan   (clobber (match_operand:DI 4 "gpc_reg_operand" "=f"))]
5960117395Skan  "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS"
5961102780Skan  "#"
5962132718Skan  "&& 1"
5963102780Skan  [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
5964102780Skan   (set (match_dup 2) (match_dup 3))
5965102780Skan   (set (match_dup 4) (match_dup 2))
5966102780Skan   (set (match_dup 0) (float:DF (match_dup 4)))]
5967102780Skan  "")
5968102780Skan
596990075Sobrien(define_insn "fix_truncdfdi2"
5970102780Skan  [(set (match_operand:DI 0 "gpc_reg_operand" "=*f")
597190075Sobrien	(fix:DI (match_operand:DF 1 "gpc_reg_operand" "f")))]
5972117395Skan  "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS"
597390075Sobrien  "fctidz %0,%1"
597490075Sobrien  [(set_attr "type" "fp")])
5975117395Skan
5976117395Skan(define_expand "floatdisf2"
5977117395Skan  [(set (match_operand:SF 0 "gpc_reg_operand" "")
5978117395Skan        (float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
5979146895Skan  "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS"
5980117395Skan  "
5981117395Skan{
5982146895Skan  rtx val = operands[1];
5983117395Skan  if (!flag_unsafe_math_optimizations)
5984117395Skan    {
5985117395Skan      rtx label = gen_label_rtx ();
5986146895Skan      val = gen_reg_rtx (DImode);
5987146895Skan      emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
5988117395Skan      emit_label (label);
5989117395Skan    }
5990146895Skan  emit_insn (gen_floatdisf2_internal1 (operands[0], val));
5991117395Skan  DONE;
5992117395Skan}")
5993117395Skan
5994117395Skan;; This is not IEEE compliant if rounding mode is "round to nearest".
5995117395Skan;; If the DI->DF conversion is inexact, then it's possible to suffer
5996117395Skan;; from double rounding.
5997117395Skan(define_insn_and_split "floatdisf2_internal1"
5998117395Skan  [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
5999117395Skan        (float:SF (match_operand:DI 1 "gpc_reg_operand" "*f")))
6000117395Skan   (clobber (match_scratch:DF 2 "=f"))]
6001117395Skan  "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS"
6002117395Skan  "#"
6003117395Skan  "&& reload_completed"
6004117395Skan  [(set (match_dup 2)
6005117395Skan        (float:DF (match_dup 1)))
6006117395Skan   (set (match_dup 0)
6007117395Skan        (float_truncate:SF (match_dup 2)))]
6008117395Skan  "")
6009117395Skan
6010117395Skan;; Twiddles bits to avoid double rounding.
6011132718Skan;; Bits that might be truncated when converting to DFmode are replaced
6012117395Skan;; by a bit that won't be lost at that stage, but is below the SFmode
6013117395Skan;; rounding position.
6014117395Skan(define_expand "floatdisf2_internal2"
6015146895Skan  [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "" "")
6016146895Skan				   (const_int 53)))
6017146895Skan   (parallel [(set (match_operand:DI 0 "" "") (and:DI (match_dup 1)
6018146895Skan						      (const_int 2047)))
6019146895Skan	      (clobber (scratch:CC))])
6020146895Skan   (set (match_dup 3) (plus:DI (match_dup 3)
6021146895Skan			       (const_int 1)))
6022146895Skan   (set (match_dup 0) (plus:DI (match_dup 0)
6023146895Skan			       (const_int 2047)))
6024146895Skan   (set (match_dup 4) (compare:CCUNS (match_dup 3)
6025161651Skan				     (const_int 2)))
6026146895Skan   (set (match_dup 0) (ior:DI (match_dup 0)
6027146895Skan			      (match_dup 1)))
6028146895Skan   (parallel [(set (match_dup 0) (and:DI (match_dup 0)
6029146895Skan					 (const_int -2048)))
6030146895Skan	      (clobber (scratch:CC))])
6031146895Skan   (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
6032146895Skan			   (label_ref (match_operand:DI 2 "" ""))
6033117395Skan			   (pc)))
6034146895Skan   (set (match_dup 0) (match_dup 1))]
6035146895Skan  "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS"
6036117395Skan  "
6037117395Skan{
6038117395Skan  operands[3] = gen_reg_rtx (DImode);
6039146895Skan  operands[4] = gen_reg_rtx (CCUNSmode);
6040117395Skan}")
604190075Sobrien
604290075Sobrien;; Define the DImode operations that can be done in a small number
604390075Sobrien;; of instructions.  The & constraints are to prevent the register
604490075Sobrien;; allocator from allocating registers that overlap with the inputs
604590075Sobrien;; (for example, having an input in 7,8 and an output in 6,7).  We
604690075Sobrien;; also allow for the output being the same as one of the inputs.
604790075Sobrien
604890075Sobrien(define_insn "*adddi3_noppc64"
604990075Sobrien  [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,&r,r,r")
605090075Sobrien	(plus:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,0,0")
605190075Sobrien		 (match_operand:DI 2 "reg_or_short_operand" "r,I,r,I")))]
605290075Sobrien  "! TARGET_POWERPC64"
605390075Sobrien  "*
605490075Sobrien{
605590075Sobrien  if (WORDS_BIG_ENDIAN)
605690075Sobrien    return (GET_CODE (operands[2])) != CONST_INT
605790075Sobrien	    ? \"{a|addc} %L0,%L1,%L2\;{ae|adde} %0,%1,%2\"
605890075Sobrien	    : \"{ai|addic} %L0,%L1,%2\;{a%G2e|add%G2e} %0,%1\";
605990075Sobrien  else
606090075Sobrien    return (GET_CODE (operands[2])) != CONST_INT
606190075Sobrien	    ? \"{a|addc} %0,%1,%2\;{ae|adde} %L0,%L1,%L2\"
606290075Sobrien	    : \"{ai|addic} %0,%1,%2\;{a%G2e|add%G2e} %L0,%L1\";
606390075Sobrien}"
6064169689Skan  [(set_attr "type" "two")
6065169689Skan   (set_attr "length" "8")])
606690075Sobrien
606790075Sobrien(define_insn "*subdi3_noppc64"
606890075Sobrien  [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,&r,r,r,r")
606990075Sobrien	(minus:DI (match_operand:DI 1 "reg_or_short_operand" "r,I,0,r,I")
607090075Sobrien		  (match_operand:DI 2 "gpc_reg_operand" "r,r,r,0,0")))]
607190075Sobrien  "! TARGET_POWERPC64"
607290075Sobrien  "*
607390075Sobrien{
607490075Sobrien  if (WORDS_BIG_ENDIAN)
607590075Sobrien    return (GET_CODE (operands[1]) != CONST_INT)
607690075Sobrien	    ? \"{sf|subfc} %L0,%L2,%L1\;{sfe|subfe} %0,%2,%1\"
607790075Sobrien	    : \"{sfi|subfic} %L0,%L2,%1\;{sf%G1e|subf%G1e} %0,%2\";
607890075Sobrien  else
607990075Sobrien    return (GET_CODE (operands[1]) != CONST_INT)
608090075Sobrien	    ? \"{sf|subfc} %0,%2,%1\;{sfe|subfe} %L0,%L2,%L1\"
608190075Sobrien	    : \"{sfi|subfic} %0,%2,%1\;{sf%G1e|subf%G1e} %L0,%L2\";
608290075Sobrien}"
6083169689Skan  [(set_attr "type" "two")
6084169689Skan   (set_attr "length" "8")])
608590075Sobrien
608690075Sobrien(define_insn "*negdi2_noppc64"
608790075Sobrien  [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r")
608890075Sobrien	(neg:DI (match_operand:DI 1 "gpc_reg_operand" "r,0")))]
608990075Sobrien  "! TARGET_POWERPC64"
609090075Sobrien  "*
609190075Sobrien{
609290075Sobrien  return (WORDS_BIG_ENDIAN)
609390075Sobrien    ? \"{sfi|subfic} %L0,%L1,0\;{sfze|subfze} %0,%1\"
609490075Sobrien    : \"{sfi|subfic} %0,%1,0\;{sfze|subfze} %L0,%L1\";
609590075Sobrien}"
6096169689Skan  [(set_attr "type" "two")
6097169689Skan   (set_attr "length" "8")])
609890075Sobrien
609990075Sobrien(define_expand "mulsidi3"
610090075Sobrien  [(set (match_operand:DI 0 "gpc_reg_operand" "")
610190075Sobrien	(mult:DI (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" ""))
610290075Sobrien		 (sign_extend:DI (match_operand:SI 2 "gpc_reg_operand" ""))))]
610390075Sobrien  "! TARGET_POWERPC64"
610490075Sobrien  "
610590075Sobrien{
610690075Sobrien  if (! TARGET_POWER && ! TARGET_POWERPC)
610790075Sobrien    {
610890075Sobrien      emit_move_insn (gen_rtx_REG (SImode, 3), operands[1]);
610990075Sobrien      emit_move_insn (gen_rtx_REG (SImode, 4), operands[2]);
611090075Sobrien      emit_insn (gen_mull_call ());
611190075Sobrien      if (WORDS_BIG_ENDIAN)
611290075Sobrien        emit_move_insn (operands[0], gen_rtx_REG (DImode, 3));
611390075Sobrien      else
611490075Sobrien	{
611590075Sobrien	  emit_move_insn (operand_subword (operands[0], 0, 0, DImode),
611690075Sobrien			  gen_rtx_REG (SImode, 3));
611790075Sobrien	  emit_move_insn (operand_subword (operands[0], 1, 0, DImode),
611890075Sobrien			  gen_rtx_REG (SImode, 4));
611990075Sobrien	}
612090075Sobrien      DONE;
612190075Sobrien    }
612290075Sobrien  else if (TARGET_POWER)
612390075Sobrien    {
612490075Sobrien      emit_insn (gen_mulsidi3_mq (operands[0], operands[1], operands[2]));
612590075Sobrien      DONE;
612690075Sobrien    }
612790075Sobrien}")
612890075Sobrien
612990075Sobrien(define_insn "mulsidi3_mq"
613090075Sobrien  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
613190075Sobrien	(mult:DI (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "%r"))
613290075Sobrien		 (sign_extend:DI (match_operand:SI 2 "gpc_reg_operand" "r"))))
613390075Sobrien   (clobber (match_scratch:SI 3 "=q"))]
613490075Sobrien  "TARGET_POWER"
613590075Sobrien  "mul %0,%1,%2\;mfmq %L0"
613690075Sobrien  [(set_attr "type" "imul")
613790075Sobrien   (set_attr "length" "8")])
613890075Sobrien
613990075Sobrien(define_insn "*mulsidi3_no_mq"
614090075Sobrien  [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
614190075Sobrien	(mult:DI (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" "%r"))
614290075Sobrien		 (sign_extend:DI (match_operand:SI 2 "gpc_reg_operand" "r"))))]
614390075Sobrien  "TARGET_POWERPC && ! TARGET_POWER && ! TARGET_POWERPC64"
614490075Sobrien  "*
614590075Sobrien{
614690075Sobrien  return (WORDS_BIG_ENDIAN)
614790075Sobrien    ? \"mulhw %0,%1,%2\;mullw %L0,%1,%2\"
614890075Sobrien    : \"mulhw %L0,%1,%2\;mullw %0,%1,%2\";
614990075Sobrien}"
615090075Sobrien  [(set_attr "type" "imul")
615190075Sobrien   (set_attr "length" "8")])
615290075Sobrien
615390075Sobrien(define_split
615490075Sobrien  [(set (match_operand:DI 0 "gpc_reg_operand" "")
615590075Sobrien	(mult:DI (sign_extend:DI (match_operand:SI 1 "gpc_reg_operand" ""))
615690075Sobrien		 (sign_extend:DI (match_operand:SI 2 "gpc_reg_operand" ""))))]
615790075Sobrien  "TARGET_POWERPC && ! TARGET_POWERPC64 && reload_completed"
615890075Sobrien  [(set (match_dup 3)
615990075Sobrien	(truncate:SI
616090075Sobrien	 (lshiftrt:DI (mult:DI (sign_extend:DI (match_dup 1))
616190075Sobrien			       (sign_extend:DI (match_dup 2)))
616290075Sobrien		      (const_int 32))))
616390075Sobrien   (set (match_dup 4)
616490075Sobrien	(mult:SI (match_dup 1)
616590075Sobrien		 (match_dup 2)))]
616690075Sobrien  "
616790075Sobrien{
616890075Sobrien  int endian = (WORDS_BIG_ENDIAN == 0);
616990075Sobrien  operands[3] = operand_subword (operands[0], endian, 0, DImode);
617090075Sobrien  operands[4] = operand_subword (operands[0], 1 - endian, 0, DImode);
617190075Sobrien}")
617290075Sobrien
617390075Sobrien(define_expand "umulsidi3"
617490075Sobrien  [(set (match_operand:DI 0 "gpc_reg_operand" "")
617590075Sobrien	(mult:DI (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" ""))
617690075Sobrien		 (zero_extend:DI (match_operand:SI 2 "gpc_reg_operand" ""))))]
617790075Sobrien  "TARGET_POWERPC && ! TARGET_POWERPC64"
617890075Sobrien  "
617990075Sobrien{
618090075Sobrien  if (TARGET_POWER)
618190075Sobrien    {
618290075Sobrien      emit_insn (gen_umulsidi3_mq (operands[0], operands[1], operands[2]));
618390075Sobrien      DONE;
618490075Sobrien    }
618590075Sobrien}")
618690075Sobrien
618790075Sobrien(define_insn "umulsidi3_mq"
618890075Sobrien  [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
618990075Sobrien	(mult:DI (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "%r"))
619090075Sobrien		 (zero_extend:DI (match_operand:SI 2 "gpc_reg_operand" "r"))))
619190075Sobrien   (clobber (match_scratch:SI 3 "=q"))]
619290075Sobrien  "TARGET_POWERPC && TARGET_POWER"
619390075Sobrien  "*
619490075Sobrien{
619590075Sobrien  return (WORDS_BIG_ENDIAN)
619690075Sobrien    ? \"mulhwu %0,%1,%2\;mullw %L0,%1,%2\"
619790075Sobrien    : \"mulhwu %L0,%1,%2\;mullw %0,%1,%2\";
619890075Sobrien}"
619990075Sobrien  [(set_attr "type" "imul")
620090075Sobrien   (set_attr "length" "8")])
620190075Sobrien
620290075Sobrien(define_insn "*umulsidi3_no_mq"
620390075Sobrien  [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
620490075Sobrien	(mult:DI (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "%r"))
620590075Sobrien		 (zero_extend:DI (match_operand:SI 2 "gpc_reg_operand" "r"))))]
620690075Sobrien  "TARGET_POWERPC && ! TARGET_POWER && ! TARGET_POWERPC64"
620790075Sobrien  "*
620890075Sobrien{
620990075Sobrien  return (WORDS_BIG_ENDIAN)
621090075Sobrien    ? \"mulhwu %0,%1,%2\;mullw %L0,%1,%2\"
621190075Sobrien    : \"mulhwu %L0,%1,%2\;mullw %0,%1,%2\";
621290075Sobrien}"
621390075Sobrien  [(set_attr "type" "imul")
621490075Sobrien   (set_attr "length" "8")])
621590075Sobrien
621690075Sobrien(define_split
621790075Sobrien  [(set (match_operand:DI 0 "gpc_reg_operand" "")
621890075Sobrien	(mult:DI (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" ""))
621990075Sobrien		 (zero_extend:DI (match_operand:SI 2 "gpc_reg_operand" ""))))]
622090075Sobrien  "TARGET_POWERPC && ! TARGET_POWERPC64 && reload_completed"
622190075Sobrien  [(set (match_dup 3)
622290075Sobrien	(truncate:SI
622390075Sobrien	 (lshiftrt:DI (mult:DI (zero_extend:DI (match_dup 1))
622490075Sobrien			       (zero_extend:DI (match_dup 2)))
622590075Sobrien		      (const_int 32))))
622690075Sobrien   (set (match_dup 4)
622790075Sobrien	(mult:SI (match_dup 1)
622890075Sobrien		 (match_dup 2)))]
622990075Sobrien  "
623090075Sobrien{
623190075Sobrien  int endian = (WORDS_BIG_ENDIAN == 0);
623290075Sobrien  operands[3] = operand_subword (operands[0], endian, 0, DImode);
623390075Sobrien  operands[4] = operand_subword (operands[0], 1 - endian, 0, DImode);
623490075Sobrien}")
623590075Sobrien
623690075Sobrien(define_expand "smulsi3_highpart"
623790075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "")
623890075Sobrien	(truncate:SI
623990075Sobrien	 (lshiftrt:DI (mult:DI (sign_extend:DI
624090075Sobrien				(match_operand:SI 1 "gpc_reg_operand" "%r"))
624190075Sobrien			       (sign_extend:DI
624290075Sobrien				(match_operand:SI 2 "gpc_reg_operand" "r")))
624390075Sobrien		      (const_int 32))))]
624490075Sobrien  ""
624590075Sobrien  "
624690075Sobrien{
624790075Sobrien  if (! TARGET_POWER && ! TARGET_POWERPC)
624890075Sobrien    {
624990075Sobrien      emit_move_insn (gen_rtx_REG (SImode, 3), operands[1]);
625090075Sobrien      emit_move_insn (gen_rtx_REG (SImode, 4), operands[2]);
625190075Sobrien      emit_insn (gen_mulh_call ());
625290075Sobrien      emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
625390075Sobrien      DONE;
625490075Sobrien    }
625590075Sobrien  else if (TARGET_POWER)
625690075Sobrien    {
625790075Sobrien      emit_insn (gen_smulsi3_highpart_mq (operands[0], operands[1], operands[2]));
625890075Sobrien      DONE;
625990075Sobrien    }
626090075Sobrien}")
626190075Sobrien
626290075Sobrien(define_insn "smulsi3_highpart_mq"
626390075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
626490075Sobrien	(truncate:SI
626590075Sobrien	 (lshiftrt:DI (mult:DI (sign_extend:DI
626690075Sobrien				(match_operand:SI 1 "gpc_reg_operand" "%r"))
626790075Sobrien			       (sign_extend:DI
626890075Sobrien				(match_operand:SI 2 "gpc_reg_operand" "r")))
626990075Sobrien		      (const_int 32))))
627090075Sobrien   (clobber (match_scratch:SI 3 "=q"))]
627190075Sobrien  "TARGET_POWER"
627290075Sobrien  "mul %0,%1,%2"
627390075Sobrien  [(set_attr "type" "imul")])
627490075Sobrien
627590075Sobrien(define_insn "*smulsi3_highpart_no_mq"
627690075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
627790075Sobrien	(truncate:SI
627890075Sobrien	 (lshiftrt:DI (mult:DI (sign_extend:DI
627990075Sobrien				(match_operand:SI 1 "gpc_reg_operand" "%r"))
628090075Sobrien			       (sign_extend:DI
628190075Sobrien				(match_operand:SI 2 "gpc_reg_operand" "r")))
628290075Sobrien		      (const_int 32))))]
628390075Sobrien  "TARGET_POWERPC && ! TARGET_POWER"
628490075Sobrien  "mulhw %0,%1,%2"
628590075Sobrien  [(set_attr "type" "imul")])
628690075Sobrien
628790075Sobrien(define_expand "umulsi3_highpart"
628890075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "")
628990075Sobrien	(truncate:SI
629090075Sobrien	 (lshiftrt:DI (mult:DI (zero_extend:DI
629190075Sobrien				(match_operand:SI 1 "gpc_reg_operand" ""))
629290075Sobrien			       (zero_extend:DI
629390075Sobrien				(match_operand:SI 2 "gpc_reg_operand" "")))
629490075Sobrien		      (const_int 32))))]
629590075Sobrien  "TARGET_POWERPC"
629690075Sobrien  "
629790075Sobrien{
629890075Sobrien  if (TARGET_POWER)
629990075Sobrien    {
630090075Sobrien      emit_insn (gen_umulsi3_highpart_mq (operands[0], operands[1], operands[2]));
630190075Sobrien      DONE;
630290075Sobrien    }
630390075Sobrien}")
630490075Sobrien
630590075Sobrien(define_insn "umulsi3_highpart_mq"
630690075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
630790075Sobrien	(truncate:SI
630890075Sobrien	 (lshiftrt:DI (mult:DI (zero_extend:DI
630990075Sobrien				(match_operand:SI 1 "gpc_reg_operand" "%r"))
631090075Sobrien			       (zero_extend:DI
631190075Sobrien				(match_operand:SI 2 "gpc_reg_operand" "r")))
631290075Sobrien		      (const_int 32))))
631390075Sobrien   (clobber (match_scratch:SI 3 "=q"))]
631490075Sobrien  "TARGET_POWERPC && TARGET_POWER"
631590075Sobrien  "mulhwu %0,%1,%2"
631690075Sobrien  [(set_attr "type" "imul")])
631790075Sobrien
631890075Sobrien(define_insn "*umulsi3_highpart_no_mq"
631990075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
632090075Sobrien	(truncate:SI
632190075Sobrien	 (lshiftrt:DI (mult:DI (zero_extend:DI
632290075Sobrien				(match_operand:SI 1 "gpc_reg_operand" "%r"))
632390075Sobrien			       (zero_extend:DI
632490075Sobrien				(match_operand:SI 2 "gpc_reg_operand" "r")))
632590075Sobrien		      (const_int 32))))]
632690075Sobrien  "TARGET_POWERPC && ! TARGET_POWER"
632790075Sobrien  "mulhwu %0,%1,%2"
632890075Sobrien  [(set_attr "type" "imul")])
632990075Sobrien
633090075Sobrien;; If operands 0 and 2 are in the same register, we have a problem.  But
633190075Sobrien;; operands 0 and 1 (the usual case) can be in the same register.  That's
633290075Sobrien;; why we have the strange constraints below.
633390075Sobrien(define_insn "ashldi3_power"
633490075Sobrien  [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,&r")
633590075Sobrien	(ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,0,r")
633690075Sobrien		   (match_operand:SI 2 "reg_or_cint_operand" "M,i,r,r")))
633790075Sobrien   (clobber (match_scratch:SI 3 "=X,q,q,q"))]
633890075Sobrien  "TARGET_POWER"
633990075Sobrien  "@
634090075Sobrien   {sli|slwi} %0,%L1,%h2\;{cal %L0,0(0)|li %L0,0}
634190075Sobrien   sl%I2q %L0,%L1,%h2\;sll%I2q %0,%1,%h2
634290075Sobrien   sl%I2q %L0,%L1,%h2\;sll%I2q %0,%1,%h2
634390075Sobrien   sl%I2q %L0,%L1,%h2\;sll%I2q %0,%1,%h2"
634490075Sobrien  [(set_attr "length" "8")])
634590075Sobrien
634690075Sobrien(define_insn "lshrdi3_power"
634790075Sobrien  [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,&r")
634890075Sobrien	(lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r,0,r")
634990075Sobrien		     (match_operand:SI 2 "reg_or_cint_operand" "M,i,r,r")))
635090075Sobrien   (clobber (match_scratch:SI 3 "=X,q,q,q"))]
635190075Sobrien  "TARGET_POWER"
635290075Sobrien  "@
635390075Sobrien   {s%A2i|s%A2wi} %L0,%1,%h2\;{cal %0,0(0)|li %0,0}
635490075Sobrien   sr%I2q %0,%1,%h2\;srl%I2q %L0,%L1,%h2
635590075Sobrien   sr%I2q %0,%1,%h2\;srl%I2q %L0,%L1,%h2
635690075Sobrien   sr%I2q %0,%1,%h2\;srl%I2q %L0,%L1,%h2"
635790075Sobrien  [(set_attr "length" "8")])
635890075Sobrien
635990075Sobrien;; Shift by a variable amount is too complex to be worth open-coding.  We
636090075Sobrien;; just handle shifts by constants.
636190075Sobrien(define_insn "ashrdi3_power"
636290075Sobrien  [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r")
636390075Sobrien	(ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
636490075Sobrien		     (match_operand:SI 2 "const_int_operand" "M,i")))
636590075Sobrien   (clobber (match_scratch:SI 3 "=X,q"))]
636690075Sobrien  "TARGET_POWER"
636790075Sobrien  "@
636890075Sobrien   {srai|srawi} %0,%1,31\;{srai|srawi} %L0,%1,%h2
636990075Sobrien   sraiq %0,%1,%h2\;srliq %L0,%L1,%h2"
637090075Sobrien  [(set_attr "length" "8")])
6371117395Skan
6372117395Skan(define_insn "ashrdi3_no_power"
6373117395Skan  [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,&r")
6374117395Skan	(ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
6375117395Skan		     (match_operand:SI 2 "const_int_operand" "M,i")))]
6376132718Skan  "TARGET_32BIT && !TARGET_POWERPC64 && !TARGET_POWER && WORDS_BIG_ENDIAN"
6377117395Skan  "@
6378117395Skan   {srai|srawi} %0,%1,31\;{srai|srawi} %L0,%1,%h2
6379117395Skan   {sri|srwi} %L0,%L1,%h2\;insrwi %L0,%1,%h2,0\;{srai|srawi} %0,%1,%h2"
6380169689Skan  [(set_attr "type" "two,three")
6381169689Skan   (set_attr "length" "8,12")])
6382132718Skan
6383132718Skan(define_insn "*ashrdisi3_noppc64"
6384132718Skan  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6385169689Skan        (subreg:SI (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
6386132718Skan                                (const_int 32)) 4))]
6387132718Skan  "TARGET_32BIT && !TARGET_POWERPC64"
6388132718Skan  "*
6389132718Skan{
6390132718Skan  if (REGNO (operands[0]) == REGNO (operands[1]))
6391132718Skan    return \"\";
6392132718Skan  else
6393132718Skan    return \"mr %0,%1\";
6394132718Skan}"
6395169689Skan   [(set_attr "length" "4")])
6396132718Skan
639790075Sobrien
639890075Sobrien;; PowerPC64 DImode operations.
639990075Sobrien
6400117395Skan(define_insn_and_split "absdi2"
640190075Sobrien  [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r")
6402117395Skan        (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r,0")))
640390075Sobrien   (clobber (match_scratch:DI 2 "=&r,&r"))]
640490075Sobrien  "TARGET_POWERPC64"
6405117395Skan  "#"
6406117395Skan  "&& reload_completed"
640790075Sobrien  [(set (match_dup 2) (ashiftrt:DI (match_dup 1) (const_int 63)))
640890075Sobrien   (set (match_dup 0) (xor:DI (match_dup 2) (match_dup 1)))
640990075Sobrien   (set (match_dup 0) (minus:DI (match_dup 0) (match_dup 2)))]
641090075Sobrien  "")
641190075Sobrien
6412117395Skan(define_insn_and_split "*nabsdi2"
641390075Sobrien  [(set (match_operand:DI 0 "gpc_reg_operand" "=&r,r")
6414117395Skan        (neg:DI (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r,0"))))
641590075Sobrien   (clobber (match_scratch:DI 2 "=&r,&r"))]
641690075Sobrien  "TARGET_POWERPC64"
6417117395Skan  "#"
6418117395Skan  "&& reload_completed"
641990075Sobrien  [(set (match_dup 2) (ashiftrt:DI (match_dup 1) (const_int 63)))
642090075Sobrien   (set (match_dup 0) (xor:DI (match_dup 2) (match_dup 1)))
642190075Sobrien   (set (match_dup 0) (minus:DI (match_dup 2) (match_dup 0)))]
642290075Sobrien  "")
642390075Sobrien
6424169689Skan(define_insn "muldi3"
6425169689Skan  [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
6426169689Skan        (mult:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r")
6427169689Skan                 (match_operand:DI 2 "reg_or_short_operand" "r,I")))]
642890075Sobrien  "TARGET_POWERPC64"
642990075Sobrien  "@
6430169689Skan   mulld %0,%1,%2
6431169689Skan   mulli %0,%1,%2"
6432169689Skan   [(set (attr "type")
6433169689Skan      (cond [(match_operand:SI 2 "s8bit_cint_operand" "")
6434169689Skan		(const_string "imul3")
6435169689Skan	     (match_operand:SI 2 "short_cint_operand" "")
6436169689Skan		(const_string "imul2")]
6437169689Skan	(const_string "lmul")))])
643890075Sobrien
6439132718Skan(define_insn "*muldi3_internal1"
6440132718Skan  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
6441132718Skan	(compare:CC (mult:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r")
6442132718Skan			     (match_operand:DI 2 "gpc_reg_operand" "r,r"))
6443132718Skan		    (const_int 0)))
6444132718Skan   (clobber (match_scratch:DI 3 "=r,r"))]
6445132718Skan  "TARGET_POWERPC64"
6446132718Skan  "@
6447132718Skan   mulld. %3,%1,%2
6448132718Skan   #"
6449132718Skan  [(set_attr "type" "lmul_compare")
6450132718Skan   (set_attr "length" "4,8")])
6451132718Skan
6452132718Skan(define_split
6453132718Skan  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
6454132718Skan	(compare:CC (mult:DI (match_operand:DI 1 "gpc_reg_operand" "")
6455132718Skan			     (match_operand:DI 2 "gpc_reg_operand" ""))
6456132718Skan		    (const_int 0)))
6457132718Skan   (clobber (match_scratch:DI 3 ""))]
6458132718Skan  "TARGET_POWERPC64 && reload_completed"
6459132718Skan  [(set (match_dup 3)
6460132718Skan	(mult:DI (match_dup 1) (match_dup 2)))
6461132718Skan   (set (match_dup 0)
6462132718Skan	(compare:CC (match_dup 3)
6463132718Skan		    (const_int 0)))]
6464132718Skan  "")
6465132718Skan
6466132718Skan(define_insn "*muldi3_internal2"
6467132718Skan  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
6468132718Skan	(compare:CC (mult:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r")
6469132718Skan			     (match_operand:DI 2 "gpc_reg_operand" "r,r"))
6470132718Skan		    (const_int 0)))
6471132718Skan   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
6472132718Skan	(mult:DI (match_dup 1) (match_dup 2)))]
6473132718Skan  "TARGET_POWERPC64"
6474132718Skan  "@
6475132718Skan   mulld. %0,%1,%2
6476132718Skan   #"
6477132718Skan  [(set_attr "type" "lmul_compare")
6478132718Skan   (set_attr "length" "4,8")])
6479132718Skan
6480132718Skan(define_split
6481132718Skan  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
6482132718Skan	(compare:CC (mult:DI (match_operand:DI 1 "gpc_reg_operand" "")
6483132718Skan			     (match_operand:DI 2 "gpc_reg_operand" ""))
6484132718Skan		    (const_int 0)))
6485132718Skan   (set (match_operand:DI 0 "gpc_reg_operand" "")
6486132718Skan	(mult:DI (match_dup 1) (match_dup 2)))]
6487132718Skan  "TARGET_POWERPC64 && reload_completed"
6488132718Skan  [(set (match_dup 0)
6489132718Skan	(mult:DI (match_dup 1) (match_dup 2)))
6490132718Skan   (set (match_dup 3)
6491132718Skan	(compare:CC (match_dup 0)
6492132718Skan		    (const_int 0)))]
6493132718Skan  "")
6494132718Skan
649590075Sobrien(define_insn "smuldi3_highpart"
649690075Sobrien  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
649790075Sobrien	(truncate:DI
649890075Sobrien	 (lshiftrt:TI (mult:TI (sign_extend:TI
649990075Sobrien				(match_operand:DI 1 "gpc_reg_operand" "%r"))
650090075Sobrien			       (sign_extend:TI
650190075Sobrien				(match_operand:DI 2 "gpc_reg_operand" "r")))
650290075Sobrien		      (const_int 64))))]
650390075Sobrien  "TARGET_POWERPC64"
650490075Sobrien  "mulhd %0,%1,%2"
650590075Sobrien  [(set_attr "type" "lmul")])
650690075Sobrien
650790075Sobrien(define_insn "umuldi3_highpart"
650890075Sobrien  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
650990075Sobrien	(truncate:DI
651090075Sobrien	 (lshiftrt:TI (mult:TI (zero_extend:TI
651190075Sobrien				(match_operand:DI 1 "gpc_reg_operand" "%r"))
651290075Sobrien			       (zero_extend:TI
651390075Sobrien				(match_operand:DI 2 "gpc_reg_operand" "r")))
651490075Sobrien		      (const_int 64))))]
651590075Sobrien  "TARGET_POWERPC64"
651690075Sobrien  "mulhdu %0,%1,%2"
651790075Sobrien  [(set_attr "type" "lmul")])
651890075Sobrien
651990075Sobrien(define_insn "rotldi3"
652090075Sobrien  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
652190075Sobrien	(rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
652290075Sobrien		   (match_operand:DI 2 "reg_or_cint_operand" "ri")))]
652390075Sobrien  "TARGET_POWERPC64"
652490075Sobrien  "rld%I2cl %0,%1,%H2,0")
652590075Sobrien
652690075Sobrien(define_insn "*rotldi3_internal2"
652790075Sobrien  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
652890075Sobrien	(compare:CC (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
652990075Sobrien			       (match_operand:DI 2 "reg_or_cint_operand" "ri,ri"))
653090075Sobrien		    (const_int 0)))
653190075Sobrien   (clobber (match_scratch:DI 3 "=r,r"))]
6532132718Skan  "TARGET_64BIT"
653390075Sobrien  "@
653490075Sobrien   rld%I2cl. %3,%1,%H2,0
653590075Sobrien   #"
653690075Sobrien  [(set_attr "type" "delayed_compare")
653790075Sobrien   (set_attr "length" "4,8")])
653890075Sobrien
653990075Sobrien(define_split
654090075Sobrien  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
654190075Sobrien	(compare:CC (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
654290075Sobrien			       (match_operand:DI 2 "reg_or_cint_operand" ""))
654390075Sobrien		    (const_int 0)))
654490075Sobrien   (clobber (match_scratch:DI 3 ""))]
654590075Sobrien  "TARGET_POWERPC64 && reload_completed"
654690075Sobrien  [(set (match_dup 3)
654790075Sobrien	(rotate:DI (match_dup 1) (match_dup 2)))
654890075Sobrien   (set (match_dup 0)
654990075Sobrien	(compare:CC (match_dup 3)
655090075Sobrien		    (const_int 0)))]
655190075Sobrien  "")
655290075Sobrien
655390075Sobrien(define_insn "*rotldi3_internal3"
655490075Sobrien  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
655590075Sobrien	(compare:CC (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
655690075Sobrien			       (match_operand:DI 2 "reg_or_cint_operand" "ri,ri"))
655790075Sobrien		    (const_int 0)))
655890075Sobrien   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
655990075Sobrien	(rotate:DI (match_dup 1) (match_dup 2)))]
6560132718Skan  "TARGET_64BIT"
656190075Sobrien  "@
656290075Sobrien   rld%I2cl. %0,%1,%H2,0
656390075Sobrien   #"
656490075Sobrien  [(set_attr "type" "delayed_compare")
656590075Sobrien   (set_attr "length" "4,8")])
656690075Sobrien
656790075Sobrien(define_split
656890075Sobrien  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
656990075Sobrien	(compare:CC (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
657090075Sobrien			       (match_operand:DI 2 "reg_or_cint_operand" ""))
657190075Sobrien		    (const_int 0)))
657290075Sobrien   (set (match_operand:DI 0 "gpc_reg_operand" "")
657390075Sobrien	(rotate:DI (match_dup 1) (match_dup 2)))]
657490075Sobrien  "TARGET_POWERPC64 && reload_completed"
657590075Sobrien  [(set (match_dup 0)
657690075Sobrien	(rotate:DI (match_dup 1) (match_dup 2)))
657790075Sobrien   (set (match_dup 3)
657890075Sobrien	(compare:CC (match_dup 0)
657990075Sobrien		    (const_int 0)))]
658090075Sobrien  "")
658190075Sobrien
658290075Sobrien(define_insn "*rotldi3_internal4"
658390075Sobrien  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
658490075Sobrien	(and:DI (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
658590075Sobrien			   (match_operand:DI 2 "reg_or_cint_operand" "ri"))
6586117395Skan		(match_operand:DI 3 "mask64_operand" "n")))]
658790075Sobrien  "TARGET_POWERPC64"
658890075Sobrien  "rld%I2c%B3 %0,%1,%H2,%S3")
658990075Sobrien
659090075Sobrien(define_insn "*rotldi3_internal5"
659190075Sobrien  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
659290075Sobrien	(compare:CC (and:DI
659390075Sobrien		     (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
659490075Sobrien				(match_operand:DI 2 "reg_or_cint_operand" "ri,ri"))
6595117395Skan		     (match_operand:DI 3 "mask64_operand" "n,n"))
659690075Sobrien		    (const_int 0)))
659790075Sobrien   (clobber (match_scratch:DI 4 "=r,r"))]
6598132718Skan  "TARGET_64BIT"
659990075Sobrien  "@
660090075Sobrien   rld%I2c%B3. %4,%1,%H2,%S3
660190075Sobrien   #"
660290075Sobrien  [(set_attr "type" "delayed_compare")
660390075Sobrien   (set_attr "length" "4,8")])
660490075Sobrien
660590075Sobrien(define_split
660690075Sobrien  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
660790075Sobrien	(compare:CC (and:DI
660890075Sobrien		     (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
660990075Sobrien				(match_operand:DI 2 "reg_or_cint_operand" ""))
661090075Sobrien		     (match_operand:DI 3 "mask64_operand" ""))
661190075Sobrien		    (const_int 0)))
661290075Sobrien   (clobber (match_scratch:DI 4 ""))]
661390075Sobrien  "TARGET_POWERPC64 && reload_completed"
661490075Sobrien  [(set (match_dup 4)
661590075Sobrien	(and:DI (rotate:DI (match_dup 1)
661690075Sobrien				(match_dup 2))
661790075Sobrien		     (match_dup 3)))
661890075Sobrien   (set (match_dup 0)
661990075Sobrien	(compare:CC (match_dup 4)
662090075Sobrien		    (const_int 0)))]
662190075Sobrien  "")
662290075Sobrien
662390075Sobrien(define_insn "*rotldi3_internal6"
662490075Sobrien  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
662590075Sobrien	(compare:CC (and:DI
662690075Sobrien		     (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
662790075Sobrien				(match_operand:DI 2 "reg_or_cint_operand" "ri,ri"))
6628117395Skan		     (match_operand:DI 3 "mask64_operand" "n,n"))
662990075Sobrien		    (const_int 0)))
663090075Sobrien   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
663190075Sobrien	(and:DI (rotate:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
6632132718Skan  "TARGET_64BIT"
663390075Sobrien  "@
663490075Sobrien   rld%I2c%B3. %0,%1,%H2,%S3
663590075Sobrien   #"
663690075Sobrien  [(set_attr "type" "delayed_compare")
663790075Sobrien   (set_attr "length" "4,8")])
663890075Sobrien
663990075Sobrien(define_split
664090075Sobrien  [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
664190075Sobrien	(compare:CC (and:DI
664290075Sobrien		     (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
664390075Sobrien				(match_operand:DI 2 "reg_or_cint_operand" ""))
664490075Sobrien		     (match_operand:DI 3 "mask64_operand" ""))
664590075Sobrien		    (const_int 0)))
664690075Sobrien   (set (match_operand:DI 0 "gpc_reg_operand" "")
664790075Sobrien	(and:DI (rotate:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
664890075Sobrien  "TARGET_POWERPC64 && reload_completed"
664990075Sobrien  [(set (match_dup 0)
665090075Sobrien	(and:DI (rotate:DI (match_dup 1) (match_dup 2)) (match_dup 3)))
665190075Sobrien   (set (match_dup 4)
665290075Sobrien	(compare:CC (match_dup 0)
665390075Sobrien		    (const_int 0)))]
665490075Sobrien  "")
665590075Sobrien
665690075Sobrien(define_insn "*rotldi3_internal7"
665790075Sobrien  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
665890075Sobrien	(zero_extend:DI
665990075Sobrien	 (subreg:QI
666090075Sobrien	  (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
666190075Sobrien		     (match_operand:DI 2 "reg_or_cint_operand" "ri")) 0)))]
666290075Sobrien  "TARGET_POWERPC64"
666390075Sobrien  "rld%I2cl %0,%1,%H2,56")
666490075Sobrien
666590075Sobrien(define_insn "*rotldi3_internal8"
666690075Sobrien  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
666790075Sobrien	(compare:CC (zero_extend:DI
666890075Sobrien		     (subreg:QI
666990075Sobrien		      (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
667090075Sobrien				 (match_operand:DI 2 "reg_or_cint_operand" "ri,ri")) 0))
667190075Sobrien		    (const_int 0)))
667290075Sobrien   (clobber (match_scratch:DI 3 "=r,r"))]
6673132718Skan  "TARGET_64BIT"
667490075Sobrien  "@
667590075Sobrien   rld%I2cl. %3,%1,%H2,56
667690075Sobrien   #"
667790075Sobrien  [(set_attr "type" "delayed_compare")
667890075Sobrien   (set_attr "length" "4,8")])
667990075Sobrien
668090075Sobrien(define_split
668190075Sobrien  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
668290075Sobrien	(compare:CC (zero_extend:DI
668390075Sobrien		     (subreg:QI
668490075Sobrien		      (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
668590075Sobrien				 (match_operand:DI 2 "reg_or_cint_operand" "")) 0))
668690075Sobrien		    (const_int 0)))
668790075Sobrien   (clobber (match_scratch:DI 3 ""))]
668890075Sobrien  "TARGET_POWERPC64 && reload_completed"
668990075Sobrien  [(set (match_dup 3)
669090075Sobrien	(zero_extend:DI (subreg:QI
669190075Sobrien		      (rotate:DI (match_dup 1)
669290075Sobrien				 (match_dup 2)) 0)))
669390075Sobrien   (set (match_dup 0)
669490075Sobrien	(compare:CC (match_dup 3)
669590075Sobrien		    (const_int 0)))]
669690075Sobrien  "")
669790075Sobrien
669890075Sobrien(define_insn "*rotldi3_internal9"
669990075Sobrien  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
670090075Sobrien	(compare:CC (zero_extend:DI
670190075Sobrien		     (subreg:QI
670290075Sobrien		      (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
670390075Sobrien				 (match_operand:DI 2 "reg_or_cint_operand" "ri,ri")) 0))
670490075Sobrien		    (const_int 0)))
670590075Sobrien   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
670690075Sobrien	(zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 0)))]
6707132718Skan  "TARGET_64BIT"
670890075Sobrien  "@
670990075Sobrien   rld%I2cl. %0,%1,%H2,56
671090075Sobrien   #"
671190075Sobrien  [(set_attr "type" "delayed_compare")
671290075Sobrien   (set_attr "length" "4,8")])
671390075Sobrien
671490075Sobrien(define_split
671590075Sobrien  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
671690075Sobrien	(compare:CC (zero_extend:DI
671790075Sobrien		     (subreg:QI
671890075Sobrien		      (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
671990075Sobrien				 (match_operand:DI 2 "reg_or_cint_operand" "")) 0))
672090075Sobrien		    (const_int 0)))
672190075Sobrien   (set (match_operand:DI 0 "gpc_reg_operand" "")
672290075Sobrien	(zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 0)))]
672390075Sobrien  "TARGET_POWERPC64 && reload_completed"
672490075Sobrien  [(set (match_dup 0)
672590075Sobrien	(zero_extend:DI (subreg:QI (rotate:DI (match_dup 1) (match_dup 2)) 0)))
672690075Sobrien   (set (match_dup 3)
672790075Sobrien	(compare:CC (match_dup 0)
672890075Sobrien		    (const_int 0)))]
672990075Sobrien  "")
673090075Sobrien
673190075Sobrien(define_insn "*rotldi3_internal10"
673290075Sobrien  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
673390075Sobrien	(zero_extend:DI
673490075Sobrien	 (subreg:HI
673590075Sobrien	  (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
673690075Sobrien		     (match_operand:DI 2 "reg_or_cint_operand" "ri")) 0)))]
673790075Sobrien  "TARGET_POWERPC64"
673890075Sobrien  "rld%I2cl %0,%1,%H2,48")
673990075Sobrien
674090075Sobrien(define_insn "*rotldi3_internal11"
674190075Sobrien  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
674290075Sobrien	(compare:CC (zero_extend:DI
674390075Sobrien		     (subreg:HI
674490075Sobrien		      (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
674590075Sobrien				 (match_operand:DI 2 "reg_or_cint_operand" "ri,ri")) 0))
674690075Sobrien		    (const_int 0)))
674790075Sobrien   (clobber (match_scratch:DI 3 "=r,r"))]
6748132718Skan  "TARGET_64BIT"
674990075Sobrien  "@
675090075Sobrien   rld%I2cl. %3,%1,%H2,48
675190075Sobrien   #"
675290075Sobrien  [(set_attr "type" "delayed_compare")
675390075Sobrien   (set_attr "length" "4,8")])
675490075Sobrien
675590075Sobrien(define_split
675690075Sobrien  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
675790075Sobrien	(compare:CC (zero_extend:DI
675890075Sobrien		     (subreg:HI
675990075Sobrien		      (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
676090075Sobrien				 (match_operand:DI 2 "reg_or_cint_operand" "")) 0))
676190075Sobrien		    (const_int 0)))
676290075Sobrien   (clobber (match_scratch:DI 3 ""))]
676390075Sobrien  "TARGET_POWERPC64 && reload_completed"
676490075Sobrien  [(set (match_dup 3)
676590075Sobrien	(zero_extend:DI (subreg:HI
676690075Sobrien		      (rotate:DI (match_dup 1)
676790075Sobrien				 (match_dup 2)) 0)))
676890075Sobrien   (set (match_dup 0)
676990075Sobrien	(compare:CC (match_dup 3)
677090075Sobrien		    (const_int 0)))]
677190075Sobrien  "")
677290075Sobrien
677390075Sobrien(define_insn "*rotldi3_internal12"
677490075Sobrien  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
677590075Sobrien	(compare:CC (zero_extend:DI
677690075Sobrien		     (subreg:HI
677790075Sobrien		      (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
677890075Sobrien				 (match_operand:DI 2 "reg_or_cint_operand" "ri,ri")) 0))
677990075Sobrien		    (const_int 0)))
678090075Sobrien   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
678190075Sobrien	(zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 0)))]
6782132718Skan  "TARGET_64BIT"
678390075Sobrien  "@
678490075Sobrien   rld%I2cl. %0,%1,%H2,48
678590075Sobrien   #"
678690075Sobrien  [(set_attr "type" "delayed_compare")
678790075Sobrien   (set_attr "length" "4,8")])
678890075Sobrien
678990075Sobrien(define_split
679090075Sobrien  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
679190075Sobrien	(compare:CC (zero_extend:DI
679290075Sobrien		     (subreg:HI
679390075Sobrien		      (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
679490075Sobrien				 (match_operand:DI 2 "reg_or_cint_operand" "")) 0))
679590075Sobrien		    (const_int 0)))
679690075Sobrien   (set (match_operand:DI 0 "gpc_reg_operand" "")
679790075Sobrien	(zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 0)))]
679890075Sobrien  "TARGET_POWERPC64 && reload_completed"
679990075Sobrien  [(set (match_dup 0)
680090075Sobrien	(zero_extend:DI (subreg:HI (rotate:DI (match_dup 1) (match_dup 2)) 0)))
680190075Sobrien   (set (match_dup 3)
680290075Sobrien	(compare:CC (match_dup 0)
680390075Sobrien		    (const_int 0)))]
680490075Sobrien  "")
680590075Sobrien
680690075Sobrien(define_insn "*rotldi3_internal13"
680790075Sobrien  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
680890075Sobrien	(zero_extend:DI
680990075Sobrien	 (subreg:SI
681090075Sobrien	  (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r")
681190075Sobrien		     (match_operand:DI 2 "reg_or_cint_operand" "ri")) 0)))]
681290075Sobrien  "TARGET_POWERPC64"
681390075Sobrien  "rld%I2cl %0,%1,%H2,32")
681490075Sobrien
681590075Sobrien(define_insn "*rotldi3_internal14"
681690075Sobrien  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
681790075Sobrien	(compare:CC (zero_extend:DI
681890075Sobrien		     (subreg:SI
681990075Sobrien		      (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
682090075Sobrien				 (match_operand:DI 2 "reg_or_cint_operand" "ri,ri")) 0))
682190075Sobrien		    (const_int 0)))
682290075Sobrien   (clobber (match_scratch:DI 3 "=r,r"))]
6823132718Skan  "TARGET_64BIT"
682490075Sobrien  "@
682590075Sobrien   rld%I2cl. %3,%1,%H2,32
682690075Sobrien   #"
682790075Sobrien  [(set_attr "type" "delayed_compare")
682890075Sobrien   (set_attr "length" "4,8")])
682990075Sobrien
683090075Sobrien(define_split
683190075Sobrien  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
683290075Sobrien	(compare:CC (zero_extend:DI
683390075Sobrien		     (subreg:SI
683490075Sobrien		      (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
683590075Sobrien				 (match_operand:DI 2 "reg_or_cint_operand" "")) 0))
683690075Sobrien		    (const_int 0)))
683790075Sobrien   (clobber (match_scratch:DI 3 ""))]
683890075Sobrien  "TARGET_POWERPC64 && reload_completed"
683990075Sobrien  [(set (match_dup 3)
684090075Sobrien	(zero_extend:DI (subreg:SI
684190075Sobrien		      (rotate:DI (match_dup 1)
684290075Sobrien				 (match_dup 2)) 0)))
684390075Sobrien   (set (match_dup 0)
684490075Sobrien	(compare:CC (match_dup 3)
684590075Sobrien		    (const_int 0)))]
684690075Sobrien  "")
684790075Sobrien
684890075Sobrien(define_insn "*rotldi3_internal15"
684990075Sobrien  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
685090075Sobrien	(compare:CC (zero_extend:DI
685190075Sobrien		     (subreg:SI
685290075Sobrien		      (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
685390075Sobrien				 (match_operand:DI 2 "reg_or_cint_operand" "ri,ri")) 0))
685490075Sobrien		    (const_int 0)))
685590075Sobrien   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
685690075Sobrien	(zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 0)))]
6857132718Skan  "TARGET_64BIT"
685890075Sobrien  "@
685990075Sobrien   rld%I2cl. %0,%1,%H2,32
686090075Sobrien   #"
686190075Sobrien  [(set_attr "type" "delayed_compare")
686290075Sobrien   (set_attr "length" "4,8")])
686390075Sobrien
686490075Sobrien(define_split
686590075Sobrien  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
686690075Sobrien	(compare:CC (zero_extend:DI
686790075Sobrien		     (subreg:SI
686890075Sobrien		      (rotate:DI (match_operand:DI 1 "gpc_reg_operand" "")
686990075Sobrien				 (match_operand:DI 2 "reg_or_cint_operand" "")) 0))
687090075Sobrien		    (const_int 0)))
687190075Sobrien   (set (match_operand:DI 0 "gpc_reg_operand" "")
687290075Sobrien	(zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 0)))]
687390075Sobrien  "TARGET_POWERPC64 && reload_completed"
687490075Sobrien  [(set (match_dup 0)
687590075Sobrien	(zero_extend:DI (subreg:SI (rotate:DI (match_dup 1) (match_dup 2)) 0)))
687690075Sobrien   (set (match_dup 3)
687790075Sobrien	(compare:CC (match_dup 0)
687890075Sobrien		    (const_int 0)))]
687990075Sobrien  "")
688090075Sobrien
688190075Sobrien(define_expand "ashldi3"
688290075Sobrien  [(set (match_operand:DI 0 "gpc_reg_operand" "")
688390075Sobrien	(ashift:DI (match_operand:DI 1 "gpc_reg_operand" "")
688490075Sobrien		   (match_operand:SI 2 "reg_or_cint_operand" "")))]
688590075Sobrien  "TARGET_POWERPC64 || TARGET_POWER"
688690075Sobrien  "
688790075Sobrien{
688890075Sobrien  if (TARGET_POWERPC64)
688990075Sobrien    ;
689090075Sobrien  else if (TARGET_POWER)
689190075Sobrien    {
689290075Sobrien      emit_insn (gen_ashldi3_power (operands[0], operands[1], operands[2]));
689390075Sobrien      DONE;
689490075Sobrien    }
689590075Sobrien  else
689690075Sobrien    FAIL;
689790075Sobrien}")
689890075Sobrien
689990075Sobrien(define_insn "*ashldi3_internal1"
690090075Sobrien  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
690190075Sobrien	(ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r")
690290075Sobrien		   (match_operand:SI 2 "reg_or_cint_operand" "ri")))]
690390075Sobrien  "TARGET_POWERPC64"
6904169689Skan  "sld%I2 %0,%1,%H2")
6905169689Skan
690690075Sobrien(define_insn "*ashldi3_internal2"
690790075Sobrien  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
690890075Sobrien	(compare:CC (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
690990075Sobrien			       (match_operand:SI 2 "reg_or_cint_operand" "ri,ri"))
691090075Sobrien		    (const_int 0)))
691190075Sobrien   (clobber (match_scratch:DI 3 "=r,r"))]
6912132718Skan  "TARGET_64BIT"
691390075Sobrien  "@
691490075Sobrien   sld%I2. %3,%1,%H2
691590075Sobrien   #"
691690075Sobrien  [(set_attr "type" "delayed_compare")
691790075Sobrien   (set_attr "length" "4,8")])
6918169689Skan
691990075Sobrien(define_split
692090075Sobrien  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
692190075Sobrien	(compare:CC (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "")
692290075Sobrien			       (match_operand:SI 2 "reg_or_cint_operand" ""))
692390075Sobrien		    (const_int 0)))
692490075Sobrien   (clobber (match_scratch:DI 3 ""))]
692590075Sobrien  "TARGET_POWERPC64 && reload_completed"
692690075Sobrien  [(set (match_dup 3)
692790075Sobrien	(ashift:DI (match_dup 1) (match_dup 2)))
692890075Sobrien   (set (match_dup 0)
692990075Sobrien	(compare:CC (match_dup 3)
693090075Sobrien		    (const_int 0)))]
693190075Sobrien  "")
693290075Sobrien
693390075Sobrien(define_insn "*ashldi3_internal3"
693490075Sobrien  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
693590075Sobrien	(compare:CC (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
693690075Sobrien			       (match_operand:SI 2 "reg_or_cint_operand" "ri,ri"))
693790075Sobrien		    (const_int 0)))
693890075Sobrien   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
693990075Sobrien	(ashift:DI (match_dup 1) (match_dup 2)))]
6940132718Skan  "TARGET_64BIT"
694190075Sobrien  "@
694290075Sobrien   sld%I2. %0,%1,%H2
694390075Sobrien   #"
694490075Sobrien  [(set_attr "type" "delayed_compare")
694590075Sobrien   (set_attr "length" "4,8")])
694690075Sobrien
694790075Sobrien(define_split
694890075Sobrien  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
694990075Sobrien	(compare:CC (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "")
695090075Sobrien			       (match_operand:SI 2 "reg_or_cint_operand" ""))
695190075Sobrien		    (const_int 0)))
695290075Sobrien   (set (match_operand:DI 0 "gpc_reg_operand" "")
695390075Sobrien	(ashift:DI (match_dup 1) (match_dup 2)))]
695490075Sobrien  "TARGET_POWERPC64 && reload_completed"
695590075Sobrien  [(set (match_dup 0)
695690075Sobrien	(ashift:DI (match_dup 1) (match_dup 2)))
695790075Sobrien   (set (match_dup 3)
695890075Sobrien	(compare:CC (match_dup 0)
695990075Sobrien		    (const_int 0)))]
696090075Sobrien  "")
696190075Sobrien
696290075Sobrien(define_insn "*ashldi3_internal4"
696390075Sobrien  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
696490075Sobrien	(and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r")
696590075Sobrien			   (match_operand:SI 2 "const_int_operand" "i"))
696690075Sobrien		(match_operand:DI 3 "const_int_operand" "n")))]
696790075Sobrien  "TARGET_POWERPC64 && includes_rldic_lshift_p (operands[2], operands[3])"
696890075Sobrien  "rldic %0,%1,%H2,%W3")
696990075Sobrien
697090075Sobrien(define_insn "ashldi3_internal5"
697190075Sobrien  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
697290075Sobrien	(compare:CC
697390075Sobrien	 (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
697490075Sobrien			    (match_operand:SI 2 "const_int_operand" "i,i"))
697590075Sobrien		 (match_operand:DI 3 "const_int_operand" "n,n"))
697690075Sobrien	 (const_int 0)))
697790075Sobrien   (clobber (match_scratch:DI 4 "=r,r"))]
6978132718Skan  "TARGET_64BIT && includes_rldic_lshift_p (operands[2], operands[3])"
697990075Sobrien  "@
698090075Sobrien   rldic. %4,%1,%H2,%W3
698190075Sobrien   #"
6982169689Skan  [(set_attr "type" "compare")
698390075Sobrien   (set_attr "length" "4,8")])
698490075Sobrien
698590075Sobrien(define_split
698690075Sobrien  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
698790075Sobrien	(compare:CC
698890075Sobrien	 (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "")
698990075Sobrien			    (match_operand:SI 2 "const_int_operand" ""))
699090075Sobrien		 (match_operand:DI 3 "const_int_operand" ""))
699190075Sobrien	 (const_int 0)))
699290075Sobrien   (clobber (match_scratch:DI 4 ""))]
699390075Sobrien  "TARGET_POWERPC64 && reload_completed
699490075Sobrien   && includes_rldic_lshift_p (operands[2], operands[3])"
699590075Sobrien  [(set (match_dup 4)
699690075Sobrien	(and:DI (ashift:DI (match_dup 1) (match_dup 2))
699790075Sobrien		(match_dup 3)))
699890075Sobrien   (set (match_dup 0)
699990075Sobrien	(compare:CC (match_dup 4)
700090075Sobrien		    (const_int 0)))]
700190075Sobrien  "")
700290075Sobrien
700390075Sobrien(define_insn "*ashldi3_internal6"
700490075Sobrien  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
700590075Sobrien	(compare:CC
700690075Sobrien	 (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
700790075Sobrien			    (match_operand:SI 2 "const_int_operand" "i,i"))
700890075Sobrien		    (match_operand:DI 3 "const_int_operand" "n,n"))
700990075Sobrien	 (const_int 0)))
701090075Sobrien   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
701190075Sobrien	(and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
7012132718Skan  "TARGET_64BIT && includes_rldic_lshift_p (operands[2], operands[3])"
701390075Sobrien  "@
701490075Sobrien   rldic. %0,%1,%H2,%W3
701590075Sobrien   #"
7016169689Skan  [(set_attr "type" "compare")
701790075Sobrien   (set_attr "length" "4,8")])
701890075Sobrien
701990075Sobrien(define_split
702090075Sobrien  [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
702190075Sobrien	(compare:CC
702290075Sobrien	 (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "")
702390075Sobrien			    (match_operand:SI 2 "const_int_operand" ""))
702490075Sobrien		 (match_operand:DI 3 "const_int_operand" ""))
702590075Sobrien	 (const_int 0)))
702690075Sobrien   (set (match_operand:DI 0 "gpc_reg_operand" "")
702790075Sobrien	(and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
702890075Sobrien  "TARGET_POWERPC64 && reload_completed
702990075Sobrien   && includes_rldic_lshift_p (operands[2], operands[3])"
703090075Sobrien  [(set (match_dup 0)
703190075Sobrien	(and:DI (ashift:DI (match_dup 1) (match_dup 2))
703290075Sobrien		(match_dup 3)))
703390075Sobrien   (set (match_dup 4)
703490075Sobrien	(compare:CC (match_dup 0)
703590075Sobrien		    (const_int 0)))]
703690075Sobrien  "")
703790075Sobrien
703890075Sobrien(define_insn "*ashldi3_internal7"
703990075Sobrien  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
704090075Sobrien	(and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r")
704190075Sobrien			   (match_operand:SI 2 "const_int_operand" "i"))
7042117395Skan		(match_operand:DI 3 "mask64_operand" "n")))]
704390075Sobrien  "TARGET_POWERPC64 && includes_rldicr_lshift_p (operands[2], operands[3])"
704490075Sobrien  "rldicr %0,%1,%H2,%S3")
704590075Sobrien
704690075Sobrien(define_insn "ashldi3_internal8"
704790075Sobrien  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
704890075Sobrien	(compare:CC
704990075Sobrien	 (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
705090075Sobrien			    (match_operand:SI 2 "const_int_operand" "i,i"))
7051117395Skan		 (match_operand:DI 3 "mask64_operand" "n,n"))
705290075Sobrien	 (const_int 0)))
705390075Sobrien   (clobber (match_scratch:DI 4 "=r,r"))]
7054132718Skan  "TARGET_64BIT && includes_rldicr_lshift_p (operands[2], operands[3])"
705590075Sobrien  "@
705690075Sobrien   rldicr. %4,%1,%H2,%S3
705790075Sobrien   #"
7058169689Skan  [(set_attr "type" "compare")
705990075Sobrien   (set_attr "length" "4,8")])
706090075Sobrien
706190075Sobrien(define_split
706290075Sobrien  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
706390075Sobrien	(compare:CC
706490075Sobrien	 (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "")
706590075Sobrien			    (match_operand:SI 2 "const_int_operand" ""))
706690075Sobrien		 (match_operand:DI 3 "mask64_operand" ""))
706790075Sobrien	 (const_int 0)))
706890075Sobrien   (clobber (match_scratch:DI 4 ""))]
706990075Sobrien  "TARGET_POWERPC64 && reload_completed
707090075Sobrien   && includes_rldicr_lshift_p (operands[2], operands[3])"
707190075Sobrien  [(set (match_dup 4)
707290075Sobrien	(and:DI (ashift:DI (match_dup 1) (match_dup 2))
707390075Sobrien		(match_dup 3)))
707490075Sobrien   (set (match_dup 0)
707590075Sobrien	(compare:CC (match_dup 4)
707690075Sobrien		    (const_int 0)))]
707790075Sobrien  "")
707890075Sobrien
707990075Sobrien(define_insn "*ashldi3_internal9"
708090075Sobrien  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
708190075Sobrien	(compare:CC
708290075Sobrien	 (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
708390075Sobrien			    (match_operand:SI 2 "const_int_operand" "i,i"))
7084117395Skan		    (match_operand:DI 3 "mask64_operand" "n,n"))
708590075Sobrien	 (const_int 0)))
708690075Sobrien   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
708790075Sobrien	(and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
7088132718Skan  "TARGET_64BIT && includes_rldicr_lshift_p (operands[2], operands[3])"
708990075Sobrien  "@
709090075Sobrien   rldicr. %0,%1,%H2,%S3
709190075Sobrien   #"
7092169689Skan  [(set_attr "type" "compare")
709390075Sobrien   (set_attr "length" "4,8")])
709490075Sobrien
709590075Sobrien(define_split
709690075Sobrien  [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
709790075Sobrien	(compare:CC
709890075Sobrien	 (and:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand" "")
709990075Sobrien			    (match_operand:SI 2 "const_int_operand" ""))
710090075Sobrien		 (match_operand:DI 3 "mask64_operand" ""))
710190075Sobrien	 (const_int 0)))
710290075Sobrien   (set (match_operand:DI 0 "gpc_reg_operand" "")
710390075Sobrien	(and:DI (ashift:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
710490075Sobrien  "TARGET_POWERPC64 && reload_completed
710590075Sobrien   && includes_rldicr_lshift_p (operands[2], operands[3])"
710690075Sobrien  [(set (match_dup 0)
710790075Sobrien	(and:DI (ashift:DI (match_dup 1) (match_dup 2))
710890075Sobrien		(match_dup 3)))
710990075Sobrien   (set (match_dup 4)
711090075Sobrien	(compare:CC (match_dup 0)
711190075Sobrien		    (const_int 0)))]
711290075Sobrien  "")
711390075Sobrien
711490075Sobrien(define_expand "lshrdi3"
711590075Sobrien  [(set (match_operand:DI 0 "gpc_reg_operand" "")
711690075Sobrien	(lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "")
711790075Sobrien		     (match_operand:SI 2 "reg_or_cint_operand" "")))]
711890075Sobrien  "TARGET_POWERPC64 || TARGET_POWER"
711990075Sobrien  "
712090075Sobrien{
712190075Sobrien  if (TARGET_POWERPC64)
712290075Sobrien    ;
712390075Sobrien  else if (TARGET_POWER)
712490075Sobrien    {
712590075Sobrien      emit_insn (gen_lshrdi3_power (operands[0], operands[1], operands[2]));
712690075Sobrien      DONE;
712790075Sobrien    }
712890075Sobrien  else
712990075Sobrien    FAIL;
713090075Sobrien}")
713190075Sobrien
713290075Sobrien(define_insn "*lshrdi3_internal1"
713390075Sobrien  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
713490075Sobrien	(lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
713590075Sobrien		     (match_operand:SI 2 "reg_or_cint_operand" "ri")))]
713690075Sobrien  "TARGET_POWERPC64"
713790075Sobrien  "srd%I2 %0,%1,%H2")
713890075Sobrien
713990075Sobrien(define_insn "*lshrdi3_internal2"
714090075Sobrien  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
714190075Sobrien	(compare:CC (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
714290075Sobrien				 (match_operand:SI 2 "reg_or_cint_operand" "ri,ri"))
714390075Sobrien		    (const_int 0)))
714490075Sobrien   (clobber (match_scratch:DI 3 "=r,r"))]
7145132718Skan  "TARGET_64BIT "
714690075Sobrien  "@
714790075Sobrien   srd%I2. %3,%1,%H2
714890075Sobrien   #"
714990075Sobrien  [(set_attr "type" "delayed_compare")
715090075Sobrien   (set_attr "length" "4,8")])
715190075Sobrien
715290075Sobrien(define_split
715390075Sobrien  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
715490075Sobrien	(compare:CC (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "")
715590075Sobrien				 (match_operand:SI 2 "reg_or_cint_operand" ""))
715690075Sobrien		    (const_int 0)))
715790075Sobrien   (clobber (match_scratch:DI 3 ""))]
715890075Sobrien  "TARGET_POWERPC64 && reload_completed"
715990075Sobrien  [(set (match_dup 3)
716090075Sobrien	(lshiftrt:DI (match_dup 1) (match_dup 2)))
716190075Sobrien   (set (match_dup 0)
716290075Sobrien	(compare:CC (match_dup 3)
716390075Sobrien		    (const_int 0)))]
716490075Sobrien  "")
716590075Sobrien
716690075Sobrien(define_insn "*lshrdi3_internal3"
716790075Sobrien  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
716890075Sobrien	(compare:CC (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
716990075Sobrien				 (match_operand:SI 2 "reg_or_cint_operand" "ri,ri"))
717090075Sobrien		    (const_int 0)))
717190075Sobrien   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
717290075Sobrien	(lshiftrt:DI (match_dup 1) (match_dup 2)))]
7173132718Skan  "TARGET_64BIT"
717490075Sobrien  "@
717590075Sobrien   srd%I2. %0,%1,%H2
717690075Sobrien   #"
717790075Sobrien  [(set_attr "type" "delayed_compare")
717890075Sobrien   (set_attr "length" "4,8")])
717990075Sobrien
718090075Sobrien(define_split
718190075Sobrien  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
718290075Sobrien	(compare:CC (lshiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "")
718390075Sobrien				 (match_operand:SI 2 "reg_or_cint_operand" ""))
718490075Sobrien		    (const_int 0)))
718590075Sobrien   (set (match_operand:DI 0 "gpc_reg_operand" "")
718690075Sobrien	(lshiftrt:DI (match_dup 1) (match_dup 2)))]
718790075Sobrien  "TARGET_POWERPC64 && reload_completed"
718890075Sobrien  [(set (match_dup 0)
718990075Sobrien	(lshiftrt:DI (match_dup 1) (match_dup 2)))
719090075Sobrien   (set (match_dup 3)
719190075Sobrien	(compare:CC (match_dup 0)
719290075Sobrien		    (const_int 0)))]
719390075Sobrien  "")
719490075Sobrien
719590075Sobrien(define_expand "ashrdi3"
719690075Sobrien  [(set (match_operand:DI 0 "gpc_reg_operand" "")
719790075Sobrien	(ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "")
719890075Sobrien		     (match_operand:SI 2 "reg_or_cint_operand" "")))]
7199132718Skan  "WORDS_BIG_ENDIAN"
720090075Sobrien  "
720190075Sobrien{
720290075Sobrien  if (TARGET_POWERPC64)
720390075Sobrien    ;
720490075Sobrien  else if (TARGET_POWER && GET_CODE (operands[2]) == CONST_INT)
720590075Sobrien    {
720690075Sobrien      emit_insn (gen_ashrdi3_power (operands[0], operands[1], operands[2]));
720790075Sobrien      DONE;
720890075Sobrien    }
7209132718Skan  else if (TARGET_32BIT && GET_CODE (operands[2]) == CONST_INT
7210132718Skan	   && WORDS_BIG_ENDIAN)
7211117395Skan    {
7212117395Skan      emit_insn (gen_ashrdi3_no_power (operands[0], operands[1], operands[2]));
7213117395Skan      DONE;
7214117395Skan    }
721590075Sobrien  else
721690075Sobrien    FAIL;
721790075Sobrien}")
721890075Sobrien
721990075Sobrien(define_insn "*ashrdi3_internal1"
722090075Sobrien  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
722190075Sobrien	(ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r")
722290075Sobrien		     (match_operand:SI 2 "reg_or_cint_operand" "ri")))]
722390075Sobrien  "TARGET_POWERPC64"
722490075Sobrien  "srad%I2 %0,%1,%H2")
722590075Sobrien
722690075Sobrien(define_insn "*ashrdi3_internal2"
722790075Sobrien  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
722890075Sobrien	(compare:CC (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
722990075Sobrien				 (match_operand:SI 2 "reg_or_cint_operand" "ri,ri"))
723090075Sobrien		    (const_int 0)))
723190075Sobrien   (clobber (match_scratch:DI 3 "=r,r"))]
7232132718Skan  "TARGET_64BIT"
723390075Sobrien  "@
723490075Sobrien   srad%I2. %3,%1,%H2
723590075Sobrien   #"
723690075Sobrien  [(set_attr "type" "delayed_compare")
723790075Sobrien   (set_attr "length" "4,8")])
723890075Sobrien
723990075Sobrien(define_split
724090075Sobrien  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
724190075Sobrien	(compare:CC (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "")
724290075Sobrien				 (match_operand:SI 2 "reg_or_cint_operand" ""))
724390075Sobrien		    (const_int 0)))
724490075Sobrien   (clobber (match_scratch:DI 3 ""))]
724590075Sobrien  "TARGET_POWERPC64 && reload_completed"
724690075Sobrien  [(set (match_dup 3)
724790075Sobrien	(ashiftrt:DI (match_dup 1) (match_dup 2)))
724890075Sobrien   (set (match_dup 0)
724990075Sobrien	(compare:CC (match_dup 3)
725090075Sobrien		    (const_int 0)))]
725190075Sobrien  "")
725290075Sobrien
725390075Sobrien(define_insn "*ashrdi3_internal3"
725490075Sobrien  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
725590075Sobrien	(compare:CC (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
725690075Sobrien				 (match_operand:SI 2 "reg_or_cint_operand" "ri,ri"))
725790075Sobrien		    (const_int 0)))
725890075Sobrien   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
725990075Sobrien	(ashiftrt:DI (match_dup 1) (match_dup 2)))]
7260132718Skan  "TARGET_64BIT"
726190075Sobrien  "@
726290075Sobrien   srad%I2. %0,%1,%H2
726390075Sobrien   #"
726490075Sobrien  [(set_attr "type" "delayed_compare")
726590075Sobrien   (set_attr "length" "4,8")])
726690075Sobrien
726790075Sobrien(define_split
726890075Sobrien  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
726990075Sobrien	(compare:CC (ashiftrt:DI (match_operand:DI 1 "gpc_reg_operand" "")
727090075Sobrien				 (match_operand:SI 2 "reg_or_cint_operand" ""))
727190075Sobrien		    (const_int 0)))
727290075Sobrien   (set (match_operand:DI 0 "gpc_reg_operand" "")
727390075Sobrien	(ashiftrt:DI (match_dup 1) (match_dup 2)))]
727490075Sobrien  "TARGET_POWERPC64 && reload_completed"
727590075Sobrien  [(set (match_dup 0)
727690075Sobrien	(ashiftrt:DI (match_dup 1) (match_dup 2)))
727790075Sobrien   (set (match_dup 3)
727890075Sobrien	(compare:CC (match_dup 0)
727990075Sobrien		    (const_int 0)))]
728090075Sobrien  "")
728190075Sobrien
728290075Sobrien(define_insn "anddi3"
7283169689Skan  [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r,r,r")
7284169689Skan	(and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r,r,r")
7285169689Skan		(match_operand:DI 2 "and64_2_operand" "?r,S,T,K,J,t")))
7286169689Skan   (clobber (match_scratch:CC 3 "=X,X,X,x,x,X"))]
728790075Sobrien  "TARGET_POWERPC64"
728890075Sobrien  "@
728990075Sobrien   and %0,%1,%2
729090075Sobrien   rldic%B2 %0,%1,0,%S2
7291169689Skan   rlwinm %0,%1,0,%m2,%M2
729290075Sobrien   andi. %0,%1,%b2
7293117395Skan   andis. %0,%1,%u2
7294117395Skan   #"
7295169689Skan  [(set_attr "type" "*,*,*,compare,compare,*")
7296169689Skan   (set_attr "length" "4,4,4,4,4,8")])
729790075Sobrien
7298117395Skan(define_split
7299117395Skan  [(set (match_operand:DI 0 "gpc_reg_operand" "")
7300117395Skan	(and:DI (match_operand:DI 1 "gpc_reg_operand" "")
7301117395Skan		(match_operand:DI 2 "mask64_2_operand" "")))
7302117395Skan   (clobber (match_scratch:CC 3 ""))]
7303117395Skan  "TARGET_POWERPC64
7304117395Skan    && (fixed_regs[CR0_REGNO] || !logical_operand (operands[2], DImode))
7305169689Skan    && !mask_operand (operands[2], DImode)
7306117395Skan    && !mask64_operand (operands[2], DImode)"
7307117395Skan  [(set (match_dup 0)
7308117395Skan	(and:DI (rotate:DI (match_dup 1)
7309117395Skan			   (match_dup 4))
7310117395Skan		(match_dup 5)))
7311117395Skan   (set (match_dup 0)
7312117395Skan	(and:DI (rotate:DI (match_dup 0)
7313117395Skan			   (match_dup 6))
7314117395Skan		(match_dup 7)))]
7315117395Skan{
7316117395Skan  build_mask64_2_operands (operands[2], &operands[4]);
7317169689Skan})
7318117395Skan
731990075Sobrien(define_insn "*anddi3_internal2"
7320169689Skan  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,x,x,x,?y,?y,?y,??y,??y,?y")
7321169689Skan	(compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r,r,r,r,r")
7322169689Skan			    (match_operand:DI 2 "and64_2_operand" "r,S,T,K,J,t,r,S,T,K,J,t"))
732390075Sobrien		    (const_int 0)))
7324169689Skan   (clobber (match_scratch:DI 3 "=r,r,r,r,r,r,r,r,r,r,r,r"))
7325169689Skan   (clobber (match_scratch:CC 4 "=X,X,X,X,X,X,X,X,X,x,x,X"))]
7326132718Skan  "TARGET_64BIT"
732790075Sobrien  "@
732890075Sobrien   and. %3,%1,%2
732990075Sobrien   rldic%B2. %3,%1,0,%S2
7330169689Skan   rlwinm. %3,%1,0,%m2,%M2
733190075Sobrien   andi. %3,%1,%b2
733290075Sobrien   andis. %3,%1,%u2
733390075Sobrien   #
733490075Sobrien   #
733590075Sobrien   #
7336117395Skan   #
7337117395Skan   #
7338169689Skan   #
733990075Sobrien   #"
7340169689Skan  [(set_attr "type" "compare,compare,compare,compare,compare,compare,compare,compare,compare,compare,compare,compare")
7341169689Skan   (set_attr "length" "4,4,4,4,4,8,8,8,8,8,8,12")])
734290075Sobrien
734390075Sobrien(define_split
7344117395Skan  [(set (match_operand:CC 0 "cc_reg_operand" "")
7345117395Skan        (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "")
7346117395Skan                            (match_operand:DI 2 "mask64_2_operand" ""))
7347117395Skan                    (const_int 0)))
7348117395Skan   (clobber (match_scratch:DI 3 ""))
7349117395Skan   (clobber (match_scratch:CC 4 ""))]
7350169689Skan  "TARGET_64BIT && reload_completed
7351117395Skan    && (fixed_regs[CR0_REGNO] || !logical_operand (operands[2], DImode))
7352169689Skan    && !mask_operand (operands[2], DImode)
7353117395Skan    && !mask64_operand (operands[2], DImode)"
7354117395Skan  [(set (match_dup 3)
7355117395Skan	(and:DI (rotate:DI (match_dup 1)
7356117395Skan			   (match_dup 5))
7357117395Skan		(match_dup 6)))
7358117395Skan   (parallel [(set (match_dup 0)
7359117395Skan		   (compare:CC (and:DI (rotate:DI (match_dup 3)
7360117395Skan						  (match_dup 7))
7361117395Skan				       (match_dup 8))
7362117395Skan			       (const_int 0)))
7363117395Skan	      (clobber (match_dup 3))])]
7364117395Skan  "
7365117395Skan{
7366117395Skan  build_mask64_2_operands (operands[2], &operands[5]);
7367117395Skan}")
7368117395Skan
736990075Sobrien(define_insn "*anddi3_internal3"
7370169689Skan  [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,x,x,x,x,?y,?y,?y,??y,??y,?y")
7371169689Skan	(compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r,r,r,r,r")
7372169689Skan			    (match_operand:DI 2 "and64_2_operand" "r,S,T,K,J,t,r,S,T,K,J,t"))
737390075Sobrien		    (const_int 0)))
7374169689Skan   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r,r,r,r,r,r,r,r,r")
737590075Sobrien	(and:DI (match_dup 1) (match_dup 2)))
7376169689Skan   (clobber (match_scratch:CC 4 "=X,X,X,X,X,X,X,X,X,x,x,X"))]
7377132718Skan  "TARGET_64BIT"
737890075Sobrien  "@
737990075Sobrien   and. %0,%1,%2
738090075Sobrien   rldic%B2. %0,%1,0,%S2
7381169689Skan   rlwinm. %0,%1,0,%m2,%M2
738290075Sobrien   andi. %0,%1,%b2
738390075Sobrien   andis. %0,%1,%u2
738490075Sobrien   #
738590075Sobrien   #
738690075Sobrien   #
7387117395Skan   #
7388117395Skan   #
7389169689Skan   #
739090075Sobrien   #"
7391169689Skan  [(set_attr "type" "compare,compare,compare,compare,compare,compare,compare,compare,compare,compare,compare,compare")
7392169689Skan   (set_attr "length" "4,4,4,4,4,8,8,8,8,8,8,12")])
739390075Sobrien
739490075Sobrien(define_split
739590075Sobrien  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
739690075Sobrien	(compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "")
7397169689Skan			    (match_operand:DI 2 "and64_2_operand" ""))
739890075Sobrien		    (const_int 0)))
739990075Sobrien   (set (match_operand:DI 0 "gpc_reg_operand" "")
740090075Sobrien	(and:DI (match_dup 1) (match_dup 2)))
740190075Sobrien   (clobber (match_scratch:CC 4 ""))]
7402169689Skan  "TARGET_64BIT && reload_completed"
740390075Sobrien  [(parallel [(set (match_dup 0)
740490075Sobrien		    (and:DI (match_dup 1) (match_dup 2)))
740590075Sobrien	       (clobber (match_dup 4))])
740690075Sobrien   (set (match_dup 3)
740790075Sobrien	(compare:CC (match_dup 0)
740890075Sobrien		    (const_int 0)))]
740990075Sobrien  "")
741090075Sobrien
7411117395Skan(define_split
7412117395Skan  [(set (match_operand:CC 3 "cc_reg_operand" "")
7413117395Skan        (compare:CC (and:DI (match_operand:DI 1 "gpc_reg_operand" "")
7414117395Skan                            (match_operand:DI 2 "mask64_2_operand" ""))
7415117395Skan                    (const_int 0)))
7416117395Skan   (set (match_operand:DI 0 "gpc_reg_operand" "")
7417117395Skan	(and:DI (match_dup 1) (match_dup 2)))
7418117395Skan   (clobber (match_scratch:CC 4 ""))]
7419169689Skan  "TARGET_64BIT && reload_completed
7420117395Skan    && (fixed_regs[CR0_REGNO] || !logical_operand (operands[2], DImode))
7421169689Skan    && !mask_operand (operands[2], DImode)
7422117395Skan    && !mask64_operand (operands[2], DImode)"
7423117395Skan  [(set (match_dup 0)
7424117395Skan	(and:DI (rotate:DI (match_dup 1)
7425117395Skan			   (match_dup 5))
7426117395Skan		(match_dup 6)))
7427117395Skan   (parallel [(set (match_dup 3)
7428117395Skan		   (compare:CC (and:DI (rotate:DI (match_dup 0)
7429117395Skan						  (match_dup 7))
7430117395Skan				       (match_dup 8))
7431117395Skan			       (const_int 0)))
7432117395Skan	      (set (match_dup 0)
7433117395Skan		   (and:DI (rotate:DI (match_dup 0)
7434117395Skan				      (match_dup 7))
7435117395Skan			   (match_dup 8)))])]
7436117395Skan  "
7437117395Skan{
7438117395Skan  build_mask64_2_operands (operands[2], &operands[5]);
7439117395Skan}")
7440117395Skan
744190075Sobrien(define_expand "iordi3"
744290075Sobrien  [(set (match_operand:DI 0 "gpc_reg_operand" "")
744390075Sobrien	(ior:DI (match_operand:DI 1 "gpc_reg_operand" "")
744490075Sobrien		(match_operand:DI 2 "reg_or_logical_cint_operand" "")))]
744590075Sobrien  "TARGET_POWERPC64"
744690075Sobrien  "
744790075Sobrien{
744890075Sobrien  if (non_logical_cint_operand (operands[2], DImode))
744990075Sobrien    {
745090075Sobrien      HOST_WIDE_INT value;
745190075Sobrien      rtx tmp = ((no_new_pseudos || rtx_equal_p (operands[0], operands[1]))
745290075Sobrien		 ? operands[0] : gen_reg_rtx (DImode));
745390075Sobrien
745490075Sobrien      if (GET_CODE (operands[2]) == CONST_INT)
745590075Sobrien        {
745690075Sobrien          value = INTVAL (operands[2]);
745790075Sobrien	  emit_insn (gen_iordi3 (tmp, operands[1],
745890075Sobrien				 GEN_INT (value & (~ (HOST_WIDE_INT) 0xffff))));
745990075Sobrien	}
746090075Sobrien      else
746190075Sobrien        {
746290075Sobrien	  value = CONST_DOUBLE_LOW (operands[2]);
746390075Sobrien	  emit_insn (gen_iordi3 (tmp, operands[1],
746490075Sobrien				 immed_double_const (value
746590075Sobrien						     & (~ (HOST_WIDE_INT) 0xffff),
746690075Sobrien						     0, DImode)));
746790075Sobrien	}
746890075Sobrien
746990075Sobrien      emit_insn (gen_iordi3 (operands[0], tmp, GEN_INT (value & 0xffff)));
747090075Sobrien      DONE;
747190075Sobrien    }
747290075Sobrien}")
747390075Sobrien
747490075Sobrien(define_expand "xordi3"
747590075Sobrien  [(set (match_operand:DI 0 "gpc_reg_operand" "")
747690075Sobrien	(xor:DI (match_operand:DI 1 "gpc_reg_operand" "")
747790075Sobrien		(match_operand:DI 2 "reg_or_logical_cint_operand" "")))]
747890075Sobrien  "TARGET_POWERPC64"
747990075Sobrien  "
748090075Sobrien{
748190075Sobrien  if (non_logical_cint_operand (operands[2], DImode))
748290075Sobrien    {
748390075Sobrien      HOST_WIDE_INT value;
748490075Sobrien      rtx tmp = ((no_new_pseudos || rtx_equal_p (operands[0], operands[1]))
748590075Sobrien		 ? operands[0] : gen_reg_rtx (DImode));
748690075Sobrien
748790075Sobrien      if (GET_CODE (operands[2]) == CONST_INT)
748890075Sobrien        {
748990075Sobrien          value = INTVAL (operands[2]);
749090075Sobrien	  emit_insn (gen_xordi3 (tmp, operands[1],
749190075Sobrien				 GEN_INT (value & (~ (HOST_WIDE_INT) 0xffff))));
749290075Sobrien	}
749390075Sobrien      else
749490075Sobrien        {
749590075Sobrien	  value = CONST_DOUBLE_LOW (operands[2]);
749690075Sobrien	  emit_insn (gen_xordi3 (tmp, operands[1],
749790075Sobrien				 immed_double_const (value
749890075Sobrien						     & (~ (HOST_WIDE_INT) 0xffff),
749990075Sobrien						     0, DImode)));
750090075Sobrien	}
750190075Sobrien
750290075Sobrien      emit_insn (gen_xordi3 (operands[0], tmp, GEN_INT (value & 0xffff)));
750390075Sobrien      DONE;
750490075Sobrien    }
750590075Sobrien}")
750690075Sobrien
750790075Sobrien(define_insn "*booldi3_internal1"
750890075Sobrien  [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r")
750990075Sobrien	(match_operator:DI 3 "boolean_or_operator"
751090075Sobrien	 [(match_operand:DI 1 "gpc_reg_operand" "%r,r,r")
751190075Sobrien	  (match_operand:DI 2 "logical_operand" "r,K,JF")]))]
751290075Sobrien  "TARGET_POWERPC64"
751390075Sobrien  "@
751490075Sobrien   %q3 %0,%1,%2
751590075Sobrien   %q3i %0,%1,%b2
751690075Sobrien   %q3is %0,%1,%u2")
751790075Sobrien
751890075Sobrien(define_insn "*booldi3_internal2"
751990075Sobrien  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
752090075Sobrien	(compare:CC (match_operator:DI 4 "boolean_or_operator"
752190075Sobrien	 [(match_operand:DI 1 "gpc_reg_operand" "%r,r")
752290075Sobrien	  (match_operand:DI 2 "gpc_reg_operand" "r,r")])
752390075Sobrien	 (const_int 0)))
752490075Sobrien   (clobber (match_scratch:DI 3 "=r,r"))]
7525132718Skan  "TARGET_64BIT"
752690075Sobrien  "@
752790075Sobrien   %q4. %3,%1,%2
752890075Sobrien   #"
752990075Sobrien  [(set_attr "type" "compare")
753090075Sobrien   (set_attr "length" "4,8")])
753190075Sobrien
753290075Sobrien(define_split
753390075Sobrien  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
753490075Sobrien	(compare:CC (match_operator:DI 4 "boolean_operator"
753590075Sobrien	 [(match_operand:DI 1 "gpc_reg_operand" "")
753690075Sobrien	  (match_operand:DI 2 "gpc_reg_operand" "")])
753790075Sobrien	 (const_int 0)))
753890075Sobrien   (clobber (match_scratch:DI 3 ""))]
753990075Sobrien  "TARGET_POWERPC64 && reload_completed"
754090075Sobrien  [(set (match_dup 3) (match_dup 4))
754190075Sobrien   (set (match_dup 0)
754290075Sobrien	(compare:CC (match_dup 3)
754390075Sobrien		    (const_int 0)))]
754490075Sobrien  "")
754590075Sobrien
754690075Sobrien(define_insn "*booldi3_internal3"
754790075Sobrien  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
754890075Sobrien	(compare:CC (match_operator:DI 4 "boolean_operator"
754990075Sobrien	 [(match_operand:DI 1 "gpc_reg_operand" "%r,r")
755090075Sobrien	  (match_operand:DI 2 "gpc_reg_operand" "r,r")])
755190075Sobrien	 (const_int 0)))
755290075Sobrien   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
755390075Sobrien	(match_dup 4))]
7554132718Skan  "TARGET_64BIT"
755590075Sobrien  "@
755690075Sobrien   %q4. %0,%1,%2
755790075Sobrien   #"
755890075Sobrien  [(set_attr "type" "compare")
755990075Sobrien   (set_attr "length" "4,8")])
756090075Sobrien
756190075Sobrien(define_split
756296263Sobrien  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
756390075Sobrien	(compare:CC (match_operator:DI 4 "boolean_operator"
756490075Sobrien	 [(match_operand:DI 1 "gpc_reg_operand" "")
756590075Sobrien	  (match_operand:DI 2 "gpc_reg_operand" "")])
756690075Sobrien	 (const_int 0)))
756790075Sobrien   (set (match_operand:DI 0 "gpc_reg_operand" "")
756890075Sobrien	(match_dup 4))]
756990075Sobrien  "TARGET_POWERPC64 && reload_completed"
757090075Sobrien  [(set (match_dup 0) (match_dup 4))
757190075Sobrien   (set (match_dup 3)
757290075Sobrien	(compare:CC (match_dup 0)
757390075Sobrien		    (const_int 0)))]
757490075Sobrien  "")
757590075Sobrien
7576169689Skan;; Split a logical operation that we can't do in one insn into two insns,
757790075Sobrien;; each of which does one 16-bit part.  This is used by combine.
757890075Sobrien
757990075Sobrien(define_split
758090075Sobrien  [(set (match_operand:DI 0 "gpc_reg_operand" "")
758190075Sobrien	(match_operator:DI 3 "boolean_or_operator"
758290075Sobrien	 [(match_operand:DI 1 "gpc_reg_operand" "")
758390075Sobrien	  (match_operand:DI 2 "non_logical_cint_operand" "")]))]
758490075Sobrien  "TARGET_POWERPC64"
758590075Sobrien  [(set (match_dup 0) (match_dup 4))
758690075Sobrien   (set (match_dup 0) (match_dup 5))]
758790075Sobrien"
758890075Sobrien{
758990075Sobrien  rtx i3,i4;
7590169689Skan
759190075Sobrien  if (GET_CODE (operands[2]) == CONST_DOUBLE)
759290075Sobrien    {
759390075Sobrien      HOST_WIDE_INT value = CONST_DOUBLE_LOW (operands[2]);
759490075Sobrien      i3 = immed_double_const (value & (~ (HOST_WIDE_INT) 0xffff),
759590075Sobrien					0, DImode);
759690075Sobrien      i4 = GEN_INT (value & 0xffff);
759790075Sobrien    }
759890075Sobrien  else
759990075Sobrien    {
760090075Sobrien      i3 = GEN_INT (INTVAL (operands[2])
760190075Sobrien			     & (~ (HOST_WIDE_INT) 0xffff));
760290075Sobrien      i4 = GEN_INT (INTVAL (operands[2]) & 0xffff);
760390075Sobrien    }
7604169689Skan  operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode,
7605169689Skan				operands[1], i3);
7606169689Skan  operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), DImode,
7607169689Skan				operands[0], i4);
760890075Sobrien}")
760990075Sobrien
761090075Sobrien(define_insn "*boolcdi3_internal1"
761190075Sobrien  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
761290075Sobrien	(match_operator:DI 3 "boolean_operator"
761390075Sobrien	 [(not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
761490075Sobrien	  (match_operand:DI 2 "gpc_reg_operand" "r")]))]
761590075Sobrien  "TARGET_POWERPC64"
761690075Sobrien  "%q3 %0,%2,%1")
761790075Sobrien
761890075Sobrien(define_insn "*boolcdi3_internal2"
761990075Sobrien  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
762090075Sobrien	(compare:CC (match_operator:DI 4 "boolean_operator"
762190075Sobrien	 [(not:DI (match_operand:DI 1 "gpc_reg_operand" "r,r"))
762290075Sobrien	  (match_operand:DI 2 "gpc_reg_operand" "r,r")])
762390075Sobrien	 (const_int 0)))
762490075Sobrien   (clobber (match_scratch:DI 3 "=r,r"))]
7625132718Skan  "TARGET_64BIT"
762690075Sobrien  "@
762790075Sobrien   %q4. %3,%2,%1
762890075Sobrien   #"
762990075Sobrien  [(set_attr "type" "compare")
763090075Sobrien   (set_attr "length" "4,8")])
763190075Sobrien
763290075Sobrien(define_split
763390075Sobrien  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
763490075Sobrien	(compare:CC (match_operator:DI 4 "boolean_operator"
763590075Sobrien	 [(not:DI (match_operand:DI 1 "gpc_reg_operand" ""))
763690075Sobrien	  (match_operand:DI 2 "gpc_reg_operand" "")])
763790075Sobrien	 (const_int 0)))
763890075Sobrien   (clobber (match_scratch:DI 3 ""))]
763990075Sobrien  "TARGET_POWERPC64 && reload_completed"
764090075Sobrien  [(set (match_dup 3) (match_dup 4))
764190075Sobrien   (set (match_dup 0)
764290075Sobrien	(compare:CC (match_dup 3)
764390075Sobrien		    (const_int 0)))]
764490075Sobrien  "")
764590075Sobrien
764690075Sobrien(define_insn "*boolcdi3_internal3"
764790075Sobrien  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
764890075Sobrien	(compare:CC (match_operator:DI 4 "boolean_operator"
764990075Sobrien	 [(not:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r"))
765090075Sobrien	  (match_operand:DI 2 "gpc_reg_operand" "r,r")])
765190075Sobrien	 (const_int 0)))
765290075Sobrien   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
765390075Sobrien	(match_dup 4))]
7654132718Skan  "TARGET_64BIT"
765590075Sobrien  "@
765690075Sobrien   %q4. %0,%2,%1
765790075Sobrien   #"
765890075Sobrien  [(set_attr "type" "compare")
765990075Sobrien   (set_attr "length" "4,8")])
766090075Sobrien
766190075Sobrien(define_split
766296263Sobrien  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
766390075Sobrien	(compare:CC (match_operator:DI 4 "boolean_operator"
766490075Sobrien	 [(not:DI (match_operand:DI 1 "gpc_reg_operand" ""))
766590075Sobrien	  (match_operand:DI 2 "gpc_reg_operand" "")])
766690075Sobrien	 (const_int 0)))
766790075Sobrien   (set (match_operand:DI 0 "gpc_reg_operand" "")
766890075Sobrien	(match_dup 4))]
766990075Sobrien  "TARGET_POWERPC64 && reload_completed"
767090075Sobrien  [(set (match_dup 0) (match_dup 4))
767190075Sobrien   (set (match_dup 3)
767290075Sobrien	(compare:CC (match_dup 0)
767390075Sobrien		    (const_int 0)))]
767490075Sobrien  "")
767590075Sobrien
767690075Sobrien(define_insn "*boolccdi3_internal1"
767790075Sobrien  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
767890075Sobrien	(match_operator:DI 3 "boolean_operator"
767990075Sobrien	 [(not:DI (match_operand:DI 1 "gpc_reg_operand" "r"))
768090075Sobrien	  (not:DI (match_operand:DI 2 "gpc_reg_operand" "r"))]))]
768190075Sobrien  "TARGET_POWERPC64"
768290075Sobrien  "%q3 %0,%1,%2")
768390075Sobrien
768490075Sobrien(define_insn "*boolccdi3_internal2"
768590075Sobrien  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
768690075Sobrien	(compare:CC (match_operator:DI 4 "boolean_operator"
768790075Sobrien	 [(not:DI (match_operand:DI 1 "gpc_reg_operand" "r,r"))
768890075Sobrien	  (not:DI (match_operand:DI 2 "gpc_reg_operand" "r,r"))])
768990075Sobrien	 (const_int 0)))
769090075Sobrien   (clobber (match_scratch:DI 3 "=r,r"))]
7691132718Skan  "TARGET_64BIT"
769290075Sobrien  "@
769390075Sobrien   %q4. %3,%1,%2
769490075Sobrien   #"
769590075Sobrien  [(set_attr "type" "compare")
769690075Sobrien   (set_attr "length" "4,8")])
769790075Sobrien
769890075Sobrien(define_split
769990075Sobrien  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
770090075Sobrien	(compare:CC (match_operator:DI 4 "boolean_operator"
770190075Sobrien	 [(not:DI (match_operand:DI 1 "gpc_reg_operand" ""))
770290075Sobrien	  (not:DI (match_operand:DI 2 "gpc_reg_operand" ""))])
770390075Sobrien	 (const_int 0)))
770490075Sobrien   (clobber (match_scratch:DI 3 ""))]
770590075Sobrien  "TARGET_POWERPC64 && reload_completed"
770690075Sobrien  [(set (match_dup 3) (match_dup 4))
770790075Sobrien   (set (match_dup 0)
770890075Sobrien	(compare:CC (match_dup 3)
770990075Sobrien		    (const_int 0)))]
771090075Sobrien  "")
771190075Sobrien
771290075Sobrien(define_insn "*boolccdi3_internal3"
771390075Sobrien  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
771490075Sobrien	(compare:CC (match_operator:DI 4 "boolean_operator"
771590075Sobrien	 [(not:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r"))
771690075Sobrien	  (not:DI (match_operand:DI 2 "gpc_reg_operand" "r,r"))])
771790075Sobrien	 (const_int 0)))
771890075Sobrien   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
771990075Sobrien	(match_dup 4))]
7720132718Skan  "TARGET_64BIT"
772190075Sobrien  "@
772290075Sobrien   %q4. %0,%1,%2
772390075Sobrien   #"
772490075Sobrien  [(set_attr "type" "compare")
772590075Sobrien   (set_attr "length" "4,8")])
772690075Sobrien
772790075Sobrien(define_split
772896263Sobrien  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
772990075Sobrien	(compare:CC (match_operator:DI 4 "boolean_operator"
773090075Sobrien	 [(not:DI (match_operand:DI 1 "gpc_reg_operand" ""))
773190075Sobrien	  (not:DI (match_operand:DI 2 "gpc_reg_operand" ""))])
773290075Sobrien	 (const_int 0)))
773390075Sobrien   (set (match_operand:DI 0 "gpc_reg_operand" "")
773490075Sobrien	(match_dup 4))]
773590075Sobrien  "TARGET_POWERPC64 && reload_completed"
773690075Sobrien  [(set (match_dup 0) (match_dup 4))
773790075Sobrien   (set (match_dup 3)
773890075Sobrien	(compare:CC (match_dup 0)
773990075Sobrien		    (const_int 0)))]
774090075Sobrien  "")
774190075Sobrien
774290075Sobrien;; Now define ways of moving data around.
774390075Sobrien
774490075Sobrien;; Set up a register with a value from the GOT table
774590075Sobrien
774690075Sobrien(define_expand "movsi_got"
774790075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "")
774890075Sobrien	(unspec:SI [(match_operand:SI 1 "got_operand" "")
7749132718Skan		    (match_dup 2)] UNSPEC_MOVSI_GOT))]
775090075Sobrien  "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
775190075Sobrien  "
775290075Sobrien{
775390075Sobrien  if (GET_CODE (operands[1]) == CONST)
775490075Sobrien    {
775590075Sobrien      rtx offset = const0_rtx;
775690075Sobrien      HOST_WIDE_INT value;
775790075Sobrien
775890075Sobrien      operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
775990075Sobrien      value = INTVAL (offset);
776090075Sobrien      if (value != 0)
776190075Sobrien	{
776290075Sobrien	  rtx tmp = (no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode));
776390075Sobrien	  emit_insn (gen_movsi_got (tmp, operands[1]));
776490075Sobrien	  emit_insn (gen_addsi3 (operands[0], tmp, offset));
776590075Sobrien	  DONE;
776690075Sobrien	}
776790075Sobrien    }
776890075Sobrien
776990075Sobrien  operands[2] = rs6000_got_register (operands[1]);
777090075Sobrien}")
777190075Sobrien
777290075Sobrien(define_insn "*movsi_got_internal"
777390075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
777490075Sobrien	(unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
7775132718Skan		    (match_operand:SI 2 "gpc_reg_operand" "b")]
7776132718Skan		   UNSPEC_MOVSI_GOT))]
777790075Sobrien  "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
777890075Sobrien  "{l|lwz} %0,%a1@got(%2)"
777990075Sobrien  [(set_attr "type" "load")])
778090075Sobrien
778190075Sobrien;; Used by sched, shorten_branches and final when the GOT pseudo reg
778290075Sobrien;; didn't get allocated to a hard register.
7783169689Skan(define_split
778490075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "")
778590075Sobrien	(unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
7786132718Skan		    (match_operand:SI 2 "memory_operand" "")]
7787132718Skan		   UNSPEC_MOVSI_GOT))]
778890075Sobrien  "DEFAULT_ABI == ABI_V4
778990075Sobrien    && flag_pic == 1
779090075Sobrien    && (reload_in_progress || reload_completed)"
779190075Sobrien  [(set (match_dup 0) (match_dup 2))
7792132718Skan   (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
7793132718Skan				 UNSPEC_MOVSI_GOT))]
779490075Sobrien  "")
779590075Sobrien
779690075Sobrien;; For SI, we special-case integers that can't be loaded in one insn.  We
779790075Sobrien;; do the load 16-bits at a time.  We could do this by loading from memory,
779890075Sobrien;; and this is even supposed to be faster, but it is simpler not to get
779990075Sobrien;; integers in the TOC.
780090075Sobrien(define_insn "movsi_low"
780190075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7802117395Skan        (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
780390075Sobrien                           (match_operand 2 "" ""))))]
780490075Sobrien  "TARGET_MACHO && ! TARGET_64BIT"
780590075Sobrien  "{l|lwz} %0,lo16(%2)(%1)"
780690075Sobrien  [(set_attr "type" "load")
780790075Sobrien   (set_attr "length" "4")])
780890075Sobrien
780990075Sobrien(define_insn "*movsi_internal1"
7810169689Skan  [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,r,*q,*c*l,*h,*h")
781190075Sobrien	(match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,R,*h,r,r,r,0"))]
781290075Sobrien  "gpc_reg_operand (operands[0], SImode)
781390075Sobrien   || gpc_reg_operand (operands[1], SImode)"
781490075Sobrien  "@
781590075Sobrien   mr %0,%1
781690075Sobrien   {cal|la} %0,%a1
781790075Sobrien   {l%U1%X1|lwz%U1%X1} %0,%1
781890075Sobrien   {st%U0%X0|stw%U0%X0} %1,%0
781990075Sobrien   {lil|li} %0,%1
782090075Sobrien   {liu|lis} %0,%v1
782190075Sobrien   #
782290075Sobrien   {cal|la} %0,%a1
782390075Sobrien   mf%1 %0
782490075Sobrien   mt%0 %1
782590075Sobrien   mt%0 %1
782690075Sobrien   mt%0 %1
7827117395Skan   {cror 0,0,0|nop}"
7828132718Skan  [(set_attr "type" "*,*,load,store,*,*,*,*,mfjmpr,*,mtjmpr,*,*")
782990075Sobrien   (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4,4")])
783090075Sobrien
783190075Sobrien;; Split a load of a large constant into the appropriate two-insn
783290075Sobrien;; sequence.
783390075Sobrien
783490075Sobrien(define_split
783590075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "")
783690075Sobrien	(match_operand:SI 1 "const_int_operand" ""))]
783790075Sobrien  "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000
783890075Sobrien   && (INTVAL (operands[1]) & 0xffff) != 0"
783990075Sobrien  [(set (match_dup 0)
784090075Sobrien	(match_dup 2))
784190075Sobrien   (set (match_dup 0)
784290075Sobrien	(ior:SI (match_dup 0)
784390075Sobrien		(match_dup 3)))]
784490075Sobrien  "
7845117395Skan{ rtx tem = rs6000_emit_set_const (operands[0], SImode, operands[1], 2);
7846117395Skan
7847117395Skan  if (tem == operands[0])
7848117395Skan    DONE;
7849117395Skan  else
7850117395Skan    FAIL;
785190075Sobrien}")
785290075Sobrien
7853169689Skan(define_insn "*mov<mode>_internal2"
7854132718Skan  [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
7855169689Skan	(compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
785690075Sobrien		    (const_int 0)))
7857169689Skan   (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
7858169689Skan  ""
785990075Sobrien  "@
7860169689Skan   {cmpi|cmp<wd>i} %2,%0,0
786190075Sobrien   mr. %0,%1
786290075Sobrien   #"
7863132718Skan  [(set_attr "type" "cmp,compare,cmp")
7864132718Skan   (set_attr "length" "4,4,8")])
7865132718Skan
786690075Sobrien(define_split
786790075Sobrien  [(set (match_operand:CC 2 "cc_reg_not_cr0_operand" "")
7868169689Skan	(compare:CC (match_operand:P 1 "gpc_reg_operand" "")
786990075Sobrien		    (const_int 0)))
7870169689Skan   (set (match_operand:P 0 "gpc_reg_operand" "") (match_dup 1))]
7871169689Skan  "reload_completed"
787290075Sobrien  [(set (match_dup 0) (match_dup 1))
787390075Sobrien   (set (match_dup 2)
787490075Sobrien	(compare:CC (match_dup 0)
787590075Sobrien		    (const_int 0)))]
787690075Sobrien  "")
7877132718Skan
7878117395Skan(define_insn "*movhi_internal"
787990075Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r,r,*q,*c*l,*h")
788090075Sobrien	(match_operand:HI 1 "input_operand" "r,m,r,i,*h,r,r,0"))]
788190075Sobrien  "gpc_reg_operand (operands[0], HImode)
788290075Sobrien   || gpc_reg_operand (operands[1], HImode)"
788390075Sobrien  "@
788490075Sobrien   mr %0,%1
788590075Sobrien   lhz%U1%X1 %0,%1
788690075Sobrien   sth%U0%X0 %1,%0
788790075Sobrien   {lil|li} %0,%w1
788890075Sobrien   mf%1 %0
788990075Sobrien   mt%0 %1
789090075Sobrien   mt%0 %1
7891117395Skan   {cror 0,0,0|nop}"
7892132718Skan  [(set_attr "type" "*,load,store,*,mfjmpr,*,mtjmpr,*")])
789390075Sobrien
7894169689Skan(define_expand "mov<mode>"
7895169689Skan  [(set (match_operand:INT 0 "general_operand" "")
7896169689Skan	(match_operand:INT 1 "any_operand" ""))]
789790075Sobrien  ""
7898169689Skan  "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
789990075Sobrien
7900117395Skan(define_insn "*movqi_internal"
790190075Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m,r,r,*q,*c*l,*h")
790290075Sobrien	(match_operand:QI 1 "input_operand" "r,m,r,i,*h,r,r,0"))]
790390075Sobrien  "gpc_reg_operand (operands[0], QImode)
790490075Sobrien   || gpc_reg_operand (operands[1], QImode)"
790590075Sobrien  "@
790690075Sobrien   mr %0,%1
790790075Sobrien   lbz%U1%X1 %0,%1
790890075Sobrien   stb%U0%X0 %1,%0
790990075Sobrien   {lil|li} %0,%1
791090075Sobrien   mf%1 %0
791190075Sobrien   mt%0 %1
791290075Sobrien   mt%0 %1
7913117395Skan   {cror 0,0,0|nop}"
7914132718Skan  [(set_attr "type" "*,load,store,*,mfjmpr,*,mtjmpr,*")])
791590075Sobrien
791690075Sobrien;; Here is how to move condition codes around.  When we store CC data in
791790075Sobrien;; an integer register or memory, we store just the high-order 4 bits.
791890075Sobrien;; This lets us not shift in the most common case of CR0.
791990075Sobrien(define_expand "movcc"
792090075Sobrien  [(set (match_operand:CC 0 "nonimmediate_operand" "")
792190075Sobrien	(match_operand:CC 1 "nonimmediate_operand" ""))]
792290075Sobrien  ""
792390075Sobrien  "")
792490075Sobrien
7925117395Skan(define_insn "*movcc_internal1"
7926169689Skan  [(set (match_operand:CC 0 "nonimmediate_operand" "=y,x,?y,y,r,r,r,r,r,q,cl,r,m")
7927169689Skan	(match_operand:CC 1 "general_operand" "y,r,r,O,x,y,r,I,h,r,r,m,r"))]
792890075Sobrien  "register_operand (operands[0], CCmode)
792990075Sobrien   || register_operand (operands[1], CCmode)"
793090075Sobrien  "@
793190075Sobrien   mcrf %0,%1
793290075Sobrien   mtcrf 128,%1
793390075Sobrien   {rlinm|rlwinm} %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;{rlinm|rlwinm} %1,%1,%f0,0xffffffff
7934169689Skan   crxor %0,%0,%0
7935132718Skan   mfcr %0%Q1
7936132718Skan   mfcr %0%Q1\;{rlinm|rlwinm} %0,%0,%f1,0xf0000000
793790075Sobrien   mr %0,%1
7938169689Skan   {lil|li} %0,%1
7939132718Skan   mf%1 %0
7940117395Skan   mt%0 %1
7941117395Skan   mt%0 %1
794290075Sobrien   {l%U1%X1|lwz%U1%X1} %0,%1
794390075Sobrien   {st%U0%U1|stw%U0%U1} %1,%0"
7944132718Skan  [(set (attr "type")
7945169689Skan     (cond [(eq_attr "alternative" "0,3")
7946132718Skan		(const_string "cr_logical")
7947132718Skan	    (eq_attr "alternative" "1,2")
7948132718Skan		(const_string "mtcr")
7949169689Skan	    (eq_attr "alternative" "6,7,9")
7950132718Skan		(const_string "integer")
7951169689Skan	    (eq_attr "alternative" "8")
7952132718Skan		(const_string "mfjmpr")
7953169689Skan	    (eq_attr "alternative" "10")
7954132718Skan		(const_string "mtjmpr")
7955169689Skan	    (eq_attr "alternative" "11")
7956132718Skan		(const_string "load")
7957169689Skan	    (eq_attr "alternative" "12")
7958132718Skan		(const_string "store")
7959132718Skan	    (ne (symbol_ref "TARGET_MFCRF") (const_int 0))
7960132718Skan		(const_string "mfcrf")
7961132718Skan	   ]
7962132718Skan	(const_string "mfcr")))
7963169689Skan   (set_attr "length" "4,4,12,4,4,8,4,4,4,4,4,4,4")])
796490075Sobrien
796590075Sobrien;; For floating-point, we normally deal with the floating-point registers
796690075Sobrien;; unless -msoft-float is used.  The sole exception is that parameter passing
796790075Sobrien;; can produce floating-point values in fixed-point registers.  Unless the
796890075Sobrien;; value is a simple constant or already in memory, we deal with this by
796990075Sobrien;; allocating memory and copying the value explicitly via that memory location.
797090075Sobrien(define_expand "movsf"
797190075Sobrien  [(set (match_operand:SF 0 "nonimmediate_operand" "")
797290075Sobrien	(match_operand:SF 1 "any_operand" ""))]
797390075Sobrien  ""
797490075Sobrien  "{ rs6000_emit_move (operands[0], operands[1], SFmode); DONE; }")
797590075Sobrien
797690075Sobrien(define_split
797790075Sobrien  [(set (match_operand:SF 0 "gpc_reg_operand" "")
797890075Sobrien	(match_operand:SF 1 "const_double_operand" ""))]
797990075Sobrien  "reload_completed
798090075Sobrien   && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
798190075Sobrien       || (GET_CODE (operands[0]) == SUBREG
798290075Sobrien	   && GET_CODE (SUBREG_REG (operands[0])) == REG
798390075Sobrien	   && REGNO (SUBREG_REG (operands[0])) <= 31))"
798490075Sobrien  [(set (match_dup 2) (match_dup 3))]
798590075Sobrien  "
798690075Sobrien{
798790075Sobrien  long l;
798890075Sobrien  REAL_VALUE_TYPE rv;
798990075Sobrien
799090075Sobrien  REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
799190075Sobrien  REAL_VALUE_TO_TARGET_SINGLE (rv, l);
799290075Sobrien
799390075Sobrien  if (! TARGET_POWERPC64)
799490075Sobrien    operands[2] = operand_subword (operands[0], 0, 0, SFmode);
799590075Sobrien  else
799690075Sobrien    operands[2] = gen_lowpart (SImode, operands[0]);
799790075Sobrien
7998117395Skan  operands[3] = gen_int_mode (l, SImode);
799990075Sobrien}")
800090075Sobrien
800190075Sobrien(define_insn "*movsf_hardfloat"
8002169689Skan  [(set (match_operand:SF 0 "nonimmediate_operand" "=!r,!r,m,f,f,m,*c*l,*q,!r,*h,!r,!r")
8003161651Skan	(match_operand:SF 1 "input_operand" "r,m,r,f,m,f,r,r,h,0,G,Fn"))]
800490075Sobrien  "(gpc_reg_operand (operands[0], SFmode)
8005117395Skan   || gpc_reg_operand (operands[1], SFmode))
8006117395Skan   && (TARGET_HARD_FLOAT && TARGET_FPRS)"
800790075Sobrien  "@
800890075Sobrien   mr %0,%1
800990075Sobrien   {l%U1%X1|lwz%U1%X1} %0,%1
801090075Sobrien   {st%U0%X0|stw%U0%X0} %1,%0
801190075Sobrien   fmr %0,%1
801290075Sobrien   lfs%U1%X1 %0,%1
801390075Sobrien   stfs%U0%X0 %1,%0
8014117395Skan   mt%0 %1
8015117395Skan   mt%0 %1
8016117395Skan   mf%1 %0
8017161651Skan   {cror 0,0,0|nop}
801890075Sobrien   #
801990075Sobrien   #"
8020169689Skan  [(set_attr "type" "*,load,store,fp,fpload,fpstore,mtjmpr,*,mfjmpr,*,*,*")
8021161651Skan   (set_attr "length" "4,4,4,4,4,4,4,4,4,4,4,8")])
802290075Sobrien
802390075Sobrien(define_insn "*movsf_softfloat"
8024132718Skan  [(set (match_operand:SF 0 "nonimmediate_operand" "=r,cl,q,r,r,m,r,r,r,r,r,*h")
8025132718Skan	(match_operand:SF 1 "input_operand" "r,r,r,h,m,r,I,L,R,G,Fn,0"))]
802690075Sobrien  "(gpc_reg_operand (operands[0], SFmode)
8027117395Skan   || gpc_reg_operand (operands[1], SFmode))
8028117395Skan   && (TARGET_SOFT_FLOAT || !TARGET_FPRS)"
802990075Sobrien  "@
803090075Sobrien   mr %0,%1
8031117395Skan   mt%0 %1
8032117395Skan   mt%0 %1
8033117395Skan   mf%1 %0
803490075Sobrien   {l%U1%X1|lwz%U1%X1} %0,%1
803590075Sobrien   {st%U0%X0|stw%U0%X0} %1,%0
803690075Sobrien   {lil|li} %0,%1
803790075Sobrien   {liu|lis} %0,%v1
803890075Sobrien   {cal|la} %0,%a1
803990075Sobrien   #
8040132718Skan   #
8041132718Skan   {cror 0,0,0|nop}"
8042169689Skan  [(set_attr "type" "*,mtjmpr,*,mfjmpr,load,store,*,*,*,*,*,*")
8043132718Skan   (set_attr "length" "4,4,4,4,4,4,4,4,4,4,8,4")])
804490075Sobrien
804590075Sobrien
804690075Sobrien(define_expand "movdf"
804790075Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "")
804890075Sobrien	(match_operand:DF 1 "any_operand" ""))]
804990075Sobrien  ""
805090075Sobrien  "{ rs6000_emit_move (operands[0], operands[1], DFmode); DONE; }")
805190075Sobrien
805290075Sobrien(define_split
805390075Sobrien  [(set (match_operand:DF 0 "gpc_reg_operand" "")
805490075Sobrien	(match_operand:DF 1 "const_int_operand" ""))]
805590075Sobrien  "! TARGET_POWERPC64 && reload_completed
805690075Sobrien   && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
805790075Sobrien       || (GET_CODE (operands[0]) == SUBREG
805890075Sobrien	   && GET_CODE (SUBREG_REG (operands[0])) == REG
805990075Sobrien	   && REGNO (SUBREG_REG (operands[0])) <= 31))"
806090075Sobrien  [(set (match_dup 2) (match_dup 4))
806190075Sobrien   (set (match_dup 3) (match_dup 1))]
806290075Sobrien  "
806390075Sobrien{
806490075Sobrien  int endian = (WORDS_BIG_ENDIAN == 0);
806590075Sobrien  HOST_WIDE_INT value = INTVAL (operands[1]);
806690075Sobrien
806790075Sobrien  operands[2] = operand_subword (operands[0], endian, 0, DFmode);
806890075Sobrien  operands[3] = operand_subword (operands[0], 1 - endian, 0, DFmode);
806990075Sobrien#if HOST_BITS_PER_WIDE_INT == 32
807090075Sobrien  operands[4] = (value & 0x80000000) ? constm1_rtx : const0_rtx;
807190075Sobrien#else
807290075Sobrien  operands[4] = GEN_INT (value >> 32);
8073117395Skan  operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
807490075Sobrien#endif
807590075Sobrien}")
807690075Sobrien
807790075Sobrien(define_split
807890075Sobrien  [(set (match_operand:DF 0 "gpc_reg_operand" "")
807990075Sobrien	(match_operand:DF 1 "const_double_operand" ""))]
808090075Sobrien  "! TARGET_POWERPC64 && reload_completed
808190075Sobrien   && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
808290075Sobrien       || (GET_CODE (operands[0]) == SUBREG
808390075Sobrien	   && GET_CODE (SUBREG_REG (operands[0])) == REG
808490075Sobrien	   && REGNO (SUBREG_REG (operands[0])) <= 31))"
808590075Sobrien  [(set (match_dup 2) (match_dup 4))
808690075Sobrien   (set (match_dup 3) (match_dup 5))]
808790075Sobrien  "
808890075Sobrien{
808990075Sobrien  int endian = (WORDS_BIG_ENDIAN == 0);
809090075Sobrien  long l[2];
809190075Sobrien  REAL_VALUE_TYPE rv;
809290075Sobrien
809390075Sobrien  REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
809490075Sobrien  REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
809590075Sobrien
809690075Sobrien  operands[2] = operand_subword (operands[0], endian, 0, DFmode);
809790075Sobrien  operands[3] = operand_subword (operands[0], 1 - endian, 0, DFmode);
8098117395Skan  operands[4] = gen_int_mode (l[endian], SImode);
8099117395Skan  operands[5] = gen_int_mode (l[1 - endian], SImode);
810090075Sobrien}")
810190075Sobrien
810290075Sobrien(define_split
810390075Sobrien  [(set (match_operand:DF 0 "gpc_reg_operand" "")
8104169689Skan	(match_operand:DF 1 "const_double_operand" ""))]
810590075Sobrien  "TARGET_POWERPC64 && reload_completed
810690075Sobrien   && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
810790075Sobrien       || (GET_CODE (operands[0]) == SUBREG
810890075Sobrien	   && GET_CODE (SUBREG_REG (operands[0])) == REG
810990075Sobrien	   && REGNO (SUBREG_REG (operands[0])) <= 31))"
811090075Sobrien  [(set (match_dup 2) (match_dup 3))]
811190075Sobrien  "
811290075Sobrien{
811390075Sobrien  int endian = (WORDS_BIG_ENDIAN == 0);
811490075Sobrien  long l[2];
811590075Sobrien  REAL_VALUE_TYPE rv;
8116132718Skan#if HOST_BITS_PER_WIDE_INT >= 64
811790075Sobrien  HOST_WIDE_INT val;
8118132718Skan#endif
811990075Sobrien
812090075Sobrien  REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
812190075Sobrien  REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
812290075Sobrien
812390075Sobrien  operands[2] = gen_lowpart (DImode, operands[0]);
812490075Sobrien  /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN.  */
812590075Sobrien#if HOST_BITS_PER_WIDE_INT >= 64
8126117395Skan  val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
8127117395Skan         | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
812890075Sobrien
8129117395Skan  operands[3] = gen_int_mode (val, DImode);
813090075Sobrien#else
813190075Sobrien  operands[3] = immed_double_const (l[1 - endian], l[endian], DImode);
813290075Sobrien#endif
813390075Sobrien}")
813490075Sobrien
813590075Sobrien;; Don't have reload use general registers to load a constant.  First,
813690075Sobrien;; it might not work if the output operand is the equivalent of
813790075Sobrien;; a non-offsettable memref, but also it is less efficient than loading
813890075Sobrien;; the constant into an FP register, since it will probably be used there.
813990075Sobrien;; The "??" is a kludge until we can figure out a more reasonable way
814090075Sobrien;; of handling these non-offsettable values.
814190075Sobrien(define_insn "*movdf_hardfloat32"
8142117395Skan  [(set (match_operand:DF 0 "nonimmediate_operand" "=!r,??r,m,f,f,m,!r,!r,!r")
8143117395Skan	(match_operand:DF 1 "input_operand" "r,m,r,f,m,f,G,H,F"))]
8144117395Skan  "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS
814590075Sobrien   && (gpc_reg_operand (operands[0], DFmode)
814690075Sobrien       || gpc_reg_operand (operands[1], DFmode))"
814790075Sobrien  "*
814890075Sobrien{
814990075Sobrien  switch (which_alternative)
815090075Sobrien    {
815190075Sobrien    default:
8152169689Skan      gcc_unreachable ();
815390075Sobrien    case 0:
815490075Sobrien      /* We normally copy the low-numbered register first.  However, if
815590075Sobrien	 the first register operand 0 is the same as the second register
815690075Sobrien	 of operand 1, we must copy in the opposite order.  */
815790075Sobrien      if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
815890075Sobrien	return \"mr %L0,%L1\;mr %0,%1\";
815990075Sobrien      else
816090075Sobrien	return \"mr %0,%1\;mr %L0,%L1\";
816190075Sobrien    case 1:
8162169689Skan      if (rs6000_offsettable_memref_p (operands[1])
816390075Sobrien	  || (GET_CODE (operands[1]) == MEM
816490075Sobrien	      && (GET_CODE (XEXP (operands[1], 0)) == LO_SUM
816590075Sobrien		  || GET_CODE (XEXP (operands[1], 0)) == PRE_INC
816690075Sobrien		  || GET_CODE (XEXP (operands[1], 0)) == PRE_DEC)))
816790075Sobrien	{
816890075Sobrien	  /* If the low-address word is used in the address, we must load
816990075Sobrien	     it last.  Otherwise, load it first.  Note that we cannot have
817090075Sobrien	     auto-increment in that case since the address register is
817190075Sobrien	     known to be dead.  */
817290075Sobrien	  if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
817390075Sobrien				 operands[1], 0))
817490075Sobrien	    return \"{l|lwz} %L0,%L1\;{l|lwz} %0,%1\";
817590075Sobrien	  else
817690075Sobrien	    return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\";
817790075Sobrien	}
817890075Sobrien      else
817990075Sobrien	{
818090075Sobrien	  rtx addreg;
818190075Sobrien
818290075Sobrien	  addreg = find_addr_reg (XEXP (operands[1], 0));
818390075Sobrien	  if (refers_to_regno_p (REGNO (operands[0]),
818490075Sobrien				 REGNO (operands[0]) + 1,
818590075Sobrien				 operands[1], 0))
818690075Sobrien	    {
818790075Sobrien	      output_asm_insn (\"{cal|la} %0,4(%0)\", &addreg);
818890075Sobrien	      output_asm_insn (\"{lx|lwzx} %L0,%1\", operands);
818990075Sobrien	      output_asm_insn (\"{cal|la} %0,-4(%0)\", &addreg);
819090075Sobrien	      return \"{lx|lwzx} %0,%1\";
819190075Sobrien	    }
819290075Sobrien	  else
819390075Sobrien	    {
819490075Sobrien	      output_asm_insn (\"{lx|lwzx} %0,%1\", operands);
819590075Sobrien	      output_asm_insn (\"{cal|la} %0,4(%0)\", &addreg);
819690075Sobrien	      output_asm_insn (\"{lx|lwzx} %L0,%1\", operands);
819790075Sobrien	      output_asm_insn (\"{cal|la} %0,-4(%0)\", &addreg);
819890075Sobrien	      return \"\";
819990075Sobrien	    }
820090075Sobrien	}
820190075Sobrien    case 2:
8202169689Skan      if (rs6000_offsettable_memref_p (operands[0])
820390075Sobrien	  || (GET_CODE (operands[0]) == MEM
820490075Sobrien	      && (GET_CODE (XEXP (operands[0], 0)) == LO_SUM
820590075Sobrien		  || GET_CODE (XEXP (operands[0], 0)) == PRE_INC
820690075Sobrien		  || GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)))
820790075Sobrien	return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\";
820890075Sobrien      else
820990075Sobrien	{
821090075Sobrien	  rtx addreg;
821190075Sobrien
821290075Sobrien	  addreg = find_addr_reg (XEXP (operands[0], 0));
821390075Sobrien	  output_asm_insn (\"{stx|stwx} %1,%0\", operands);
821490075Sobrien	  output_asm_insn (\"{cal|la} %0,4(%0)\", &addreg);
821590075Sobrien	  output_asm_insn (\"{stx|stwx} %L1,%0\", operands);
821690075Sobrien	  output_asm_insn (\"{cal|la} %0,-4(%0)\", &addreg);
821790075Sobrien	  return \"\";
821890075Sobrien	}
821990075Sobrien    case 3:
8220117395Skan      return \"fmr %0,%1\";
822190075Sobrien    case 4:
8222117395Skan      return \"lfd%U1%X1 %0,%1\";
822390075Sobrien    case 5:
8224117395Skan      return \"stfd%U0%X0 %1,%0\";
822590075Sobrien    case 6:
822690075Sobrien    case 7:
822790075Sobrien    case 8:
8228117395Skan      return \"#\";
822990075Sobrien    }
823090075Sobrien}"
8231169689Skan  [(set_attr "type" "two,load,store,fp,fpload,fpstore,*,*,*")
8232117395Skan   (set_attr "length" "8,16,16,4,4,4,8,12,16")])
823390075Sobrien
823490075Sobrien(define_insn "*movdf_softfloat32"
823590075Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m,r,r,r")
823690075Sobrien	(match_operand:DF 1 "input_operand" "r,m,r,G,H,F"))]
8237169689Skan  "! TARGET_POWERPC64 && (TARGET_SOFT_FLOAT || TARGET_E500_SINGLE)
823890075Sobrien   && (gpc_reg_operand (operands[0], DFmode)
823990075Sobrien       || gpc_reg_operand (operands[1], DFmode))"
824090075Sobrien  "*
824190075Sobrien{
824290075Sobrien  switch (which_alternative)
824390075Sobrien    {
824490075Sobrien    default:
8245169689Skan      gcc_unreachable ();
824690075Sobrien    case 0:
824790075Sobrien      /* We normally copy the low-numbered register first.  However, if
824890075Sobrien	 the first register operand 0 is the same as the second register of
824990075Sobrien	 operand 1, we must copy in the opposite order.  */
825090075Sobrien      if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
825190075Sobrien	return \"mr %L0,%L1\;mr %0,%1\";
825290075Sobrien      else
825390075Sobrien	return \"mr %0,%1\;mr %L0,%L1\";
825490075Sobrien    case 1:
825590075Sobrien      /* If the low-address word is used in the address, we must load
825690075Sobrien	 it last.  Otherwise, load it first.  Note that we cannot have
825790075Sobrien	 auto-increment in that case since the address register is
825890075Sobrien	 known to be dead.  */
825990075Sobrien      if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
826090075Sobrien			     operands[1], 0))
826190075Sobrien	return \"{l|lwz} %L0,%L1\;{l|lwz} %0,%1\";
826290075Sobrien      else
826390075Sobrien	return \"{l%U1|lwz%U1} %0,%1\;{l|lwz} %L0,%L1\";
826490075Sobrien    case 2:
826590075Sobrien      return \"{st%U0|stw%U0} %1,%0\;{st|stw} %L1,%L0\";
826690075Sobrien    case 3:
826790075Sobrien    case 4:
826890075Sobrien    case 5:
826990075Sobrien      return \"#\";
827090075Sobrien    }
827190075Sobrien}"
8272169689Skan  [(set_attr "type" "two,load,store,*,*,*")
827390075Sobrien   (set_attr "length" "8,8,8,8,12,16")])
827490075Sobrien
8275132718Skan; ld/std require word-aligned displacements -> 'Y' constraint.
8276132718Skan; List Y->r and r->Y before r->r for reload.
827790075Sobrien(define_insn "*movdf_hardfloat64"
8278169689Skan  [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,r,!r,f,f,m,*c*l,!r,*h,!r,!r,!r")
8279161651Skan	(match_operand:DF 1 "input_operand" "r,Y,r,f,m,f,r,h,0,G,H,F"))]
8280117395Skan  "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS
828190075Sobrien   && (gpc_reg_operand (operands[0], DFmode)
828290075Sobrien       || gpc_reg_operand (operands[1], DFmode))"
828390075Sobrien  "@
8284132718Skan   std%U0%X0 %1,%0
8285132718Skan   ld%U1%X1 %0,%1
828690075Sobrien   mr %0,%1
8287117395Skan   fmr %0,%1
8288117395Skan   lfd%U1%X1 %0,%1
8289117395Skan   stfd%U0%X0 %1,%0
8290117395Skan   mt%0 %1
8291117395Skan   mf%1 %0
8292161651Skan   {cror 0,0,0|nop}
829390075Sobrien   #
829490075Sobrien   #
8295117395Skan   #"
8296169689Skan  [(set_attr "type" "store,load,*,fp,fpload,fpstore,mtjmpr,mfjmpr,*,*,*,*")
8297161651Skan   (set_attr "length" "4,4,4,4,4,4,4,4,4,8,12,16")])
829890075Sobrien
829990075Sobrien(define_insn "*movdf_softfloat64"
8300132718Skan  [(set (match_operand:DF 0 "nonimmediate_operand" "=r,Y,r,cl,r,r,r,r,*h")
8301132718Skan	(match_operand:DF 1 "input_operand" "Y,r,r,r,h,G,H,F,0"))]
8302117395Skan  "TARGET_POWERPC64 && (TARGET_SOFT_FLOAT || !TARGET_FPRS)
830390075Sobrien   && (gpc_reg_operand (operands[0], DFmode)
830490075Sobrien       || gpc_reg_operand (operands[1], DFmode))"
830590075Sobrien  "@
8306132718Skan   ld%U1%X1 %0,%1
8307132718Skan   std%U0%X0 %1,%0
830890075Sobrien   mr %0,%1
8309117395Skan   mt%0 %1
8310117395Skan   mf%1 %0
831190075Sobrien   #
831290075Sobrien   #
8313132718Skan   #
8314161651Skan   {cror 0,0,0|nop}"
8315169689Skan  [(set_attr "type" "load,store,*,mtjmpr,mfjmpr,*,*,*,*")
8316132718Skan   (set_attr "length" "4,4,4,4,4,8,12,16,4")])
831790075Sobrien
831890075Sobrien(define_expand "movtf"
831990075Sobrien  [(set (match_operand:TF 0 "general_operand" "")
832090075Sobrien	(match_operand:TF 1 "any_operand" ""))]
8321169689Skan  "!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128"
832290075Sobrien  "{ rs6000_emit_move (operands[0], operands[1], TFmode); DONE; }")
832390075Sobrien
8324132718Skan; It's important to list the o->f and f->o moves before f->f because
8325132718Skan; otherwise reload, given m->f, will try to pick f->f and reload it,
8326169689Skan; which doesn't make progress.  Likewise r->Y must be before r->r.
8327132718Skan(define_insn_and_split "*movtf_internal"
8328169689Skan  [(set (match_operand:TF 0 "nonimmediate_operand" "=o,f,f,r,Y,r")
8329169689Skan	(match_operand:TF 1 "input_operand"         "f,o,f,YGHF,r,r"))]
8330169689Skan  "!TARGET_IEEEQUAD
8331132718Skan   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128
833290075Sobrien   && (gpc_reg_operand (operands[0], TFmode)
833390075Sobrien       || gpc_reg_operand (operands[1], TFmode))"
8334132718Skan  "#"
8335132718Skan  "&& reload_completed"
8336132718Skan  [(pc)]
8337132718Skan{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
8338169689Skan  [(set_attr "length" "8,8,8,20,20,16")])
833990075Sobrien
8340169689Skan(define_insn_and_split "*movtf_softfloat"
8341169689Skan  [(set (match_operand:TF 0 "nonimmediate_operand" "=r,Y,r")
8342169689Skan	(match_operand:TF 1 "input_operand"         "YGHF,r,r"))]
8343169689Skan  "!TARGET_IEEEQUAD
8344169689Skan   && (TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_LONG_DOUBLE_128
8345169689Skan   && (gpc_reg_operand (operands[0], TFmode)
8346169689Skan       || gpc_reg_operand (operands[1], TFmode))"
8347169689Skan  "#"
8348169689Skan  "&& reload_completed"
8349169689Skan  [(pc)]
8350169689Skan{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
8351169689Skan  [(set_attr "length" "20,20,16")])
8352169689Skan
8353132718Skan(define_expand "extenddftf2"
8354132718Skan  [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
8355132718Skan		   (float_extend:TF (match_operand:DF 1 "input_operand" "")))
8356132718Skan	      (use (match_dup 2))])]
8357169689Skan  "!TARGET_IEEEQUAD
8358132718Skan   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
835990075Sobrien{
8360132718Skan  operands[2] = CONST0_RTX (DFmode);
8361169689Skan  /* Generate GOT reference early for SVR4 PIC.  */
8362169689Skan  if (DEFAULT_ABI == ABI_V4 && flag_pic)
8363169689Skan    operands[2] = validize_mem (force_const_mem (DFmode, operands[2]));
8364132718Skan})
8365117395Skan
8366132718Skan(define_insn_and_split "*extenddftf2_internal"
8367132718Skan  [(set (match_operand:TF 0 "nonimmediate_operand" "=o,f,&f,r")
8368132718Skan       (float_extend:TF (match_operand:DF 1 "input_operand" "fr,mf,mf,rmGHF")))
8369169689Skan   (use (match_operand:DF 2 "zero_reg_mem_operand" "rf,m,f,n"))]
8370169689Skan  "!TARGET_IEEEQUAD
8371132718Skan   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
8372132718Skan  "#"
8373132718Skan  "&& reload_completed"
8374132718Skan  [(pc)]
837590075Sobrien{
8376132718Skan  const int lo_word = FLOAT_WORDS_BIG_ENDIAN ? GET_MODE_SIZE (DFmode) : 0;
8377132718Skan  const int hi_word = FLOAT_WORDS_BIG_ENDIAN ? 0 : GET_MODE_SIZE (DFmode);
8378132718Skan  emit_move_insn (simplify_gen_subreg (DFmode, operands[0], TFmode, hi_word),
8379132718Skan		  operands[1]);
8380132718Skan  emit_move_insn (simplify_gen_subreg (DFmode, operands[0], TFmode, lo_word),
8381132718Skan		  operands[2]);
8382132718Skan  DONE;
8383169689Skan})
8384117395Skan
8385132718Skan(define_expand "extendsftf2"
8386132718Skan  [(set (match_operand:TF 0 "nonimmediate_operand" "")
8387132718Skan	(float_extend:TF (match_operand:SF 1 "gpc_reg_operand" "")))]
8388169689Skan  "!TARGET_IEEEQUAD
8389132718Skan   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
8390117395Skan{
8391132718Skan  rtx tmp = gen_reg_rtx (DFmode);
8392132718Skan  emit_insn (gen_extendsfdf2 (tmp, operands[1]));
8393132718Skan  emit_insn (gen_extenddftf2 (operands[0], tmp));
8394132718Skan  DONE;
8395132718Skan})
8396117395Skan
8397146895Skan(define_expand "trunctfdf2"
8398146895Skan  [(set (match_operand:DF 0 "gpc_reg_operand" "")
8399146895Skan	(float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "")))]
8400169689Skan  "!TARGET_IEEEQUAD
8401146895Skan   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
8402146895Skan  "")
8403146895Skan
8404146895Skan(define_insn_and_split "trunctfdf2_internal1"
8405146895Skan  [(set (match_operand:DF 0 "gpc_reg_operand" "=f,?f")
8406146895Skan	(float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "0,f")))]
8407169689Skan  "!TARGET_IEEEQUAD && !TARGET_XL_COMPAT
8408146895Skan   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
8409146895Skan  "@
8410146895Skan   #
8411146895Skan   fmr %0,%1"
8412146895Skan  "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
8413146895Skan  [(const_int 0)]
8414146895Skan{
8415146895Skan  emit_note (NOTE_INSN_DELETED);
8416146895Skan  DONE;
8417146895Skan}
8418146895Skan  [(set_attr "type" "fp")])
8419146895Skan
8420146895Skan(define_insn "trunctfdf2_internal2"
842190075Sobrien  [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
842290075Sobrien	(float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "f")))]
8423169689Skan  "!TARGET_IEEEQUAD && TARGET_XL_COMPAT
8424132718Skan   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
842590075Sobrien  "fadd %0,%1,%L1"
8426146895Skan  [(set_attr "type" "fp")])
842790075Sobrien
842890075Sobrien(define_insn_and_split "trunctfsf2"
842990075Sobrien  [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
8430117395Skan	(float_truncate:SF (match_operand:TF 1 "gpc_reg_operand" "f")))
8431117395Skan   (clobber (match_scratch:DF 2 "=f"))]
8432169689Skan  "!TARGET_IEEEQUAD
8433132718Skan   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
843490075Sobrien  "#"
8435117395Skan  "&& reload_completed"
843690075Sobrien  [(set (match_dup 2)
843790075Sobrien	(float_truncate:DF (match_dup 1)))
843890075Sobrien   (set (match_dup 0)
843990075Sobrien	(float_truncate:SF (match_dup 2)))]
8440117395Skan  "")
844190075Sobrien
8442132718Skan(define_expand "floatsitf2"
8443169689Skan  [(set (match_operand:TF 0 "gpc_reg_operand" "")
8444169689Skan        (float:TF (match_operand:SI 1 "gpc_reg_operand" "")))]
8445169689Skan  "!TARGET_IEEEQUAD
8446117395Skan   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
8447132718Skan{
8448132718Skan  rtx tmp = gen_reg_rtx (DFmode);
8449132718Skan  expand_float (tmp, operands[1], false);
8450132718Skan  emit_insn (gen_extenddftf2 (operands[0], tmp));
8451132718Skan  DONE;
8452132718Skan})
845390075Sobrien
8454132718Skan; fadd, but rounding towards zero.
8455132718Skan; This is probably not the optimal code sequence.
8456132718Skan(define_insn "fix_trunc_helper"
8457132718Skan  [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
8458132718Skan	(unspec:DF [(match_operand:TF 1 "gpc_reg_operand" "f")]
8459132718Skan		   UNSPEC_FIX_TRUNC_TF))
8460132718Skan   (clobber (match_operand:DF 2 "gpc_reg_operand" "=&f"))]
8461132718Skan  "TARGET_HARD_FLOAT && TARGET_FPRS"
8462132718Skan  "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
8463132718Skan  [(set_attr "type" "fp")
8464132718Skan   (set_attr "length" "20")])
846590075Sobrien
8466132718Skan(define_expand "fix_trunctfsi2"
8467132718Skan  [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
8468132718Skan		   (fix:SI (match_operand:TF 1 "gpc_reg_operand" "")))
8469132718Skan	      (clobber (match_dup 2))
8470132718Skan	      (clobber (match_dup 3))
8471132718Skan	      (clobber (match_dup 4))
8472132718Skan	      (clobber (match_dup 5))])]
8473169689Skan  "!TARGET_IEEEQUAD
8474132718Skan   && (TARGET_POWER2 || TARGET_POWERPC)
8475117395Skan   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
8476132718Skan{
8477132718Skan  operands[2] = gen_reg_rtx (DFmode);
8478132718Skan  operands[3] = gen_reg_rtx (DFmode);
8479132718Skan  operands[4] = gen_reg_rtx (DImode);
8480132718Skan  operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode), 0);
8481132718Skan})
848290075Sobrien
8483132718Skan(define_insn_and_split "*fix_trunctfsi2_internal"
8484117395Skan  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8485117395Skan        (fix:SI (match_operand:TF 1 "gpc_reg_operand" "f")))
8486132718Skan   (clobber (match_operand:DF 2 "gpc_reg_operand" "=f"))
8487132718Skan   (clobber (match_operand:DF 3 "gpc_reg_operand" "=&f"))
8488132718Skan   (clobber (match_operand:DI 4 "gpc_reg_operand" "=f"))
8489132718Skan   (clobber (match_operand:DI 5 "memory_operand" "=o"))]
8490169689Skan  "!TARGET_IEEEQUAD
8491132718Skan   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
8492117395Skan  "#"
8493169689Skan  "&& (!no_new_pseudos || offsettable_nonstrict_memref_p (operands[5]))"
8494132718Skan  [(pc)]
8495132718Skan{
8496132718Skan  rtx lowword;
8497132718Skan  emit_insn (gen_fix_trunc_helper (operands[2], operands[1], operands[3]));
849890075Sobrien
8499169689Skan  gcc_assert (MEM_P (operands[5]));
8500169689Skan  lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
8501132718Skan
8502132718Skan  emit_insn (gen_fctiwz (operands[4], operands[2]));
8503132718Skan  emit_move_insn (operands[5], operands[4]);
8504169689Skan  emit_move_insn (operands[0], lowword);
8505132718Skan  DONE;
8506132718Skan})
8507132718Skan
850890075Sobrien(define_insn "negtf2"
850990075Sobrien  [(set (match_operand:TF 0 "gpc_reg_operand" "=f")
851090075Sobrien	(neg:TF (match_operand:TF 1 "gpc_reg_operand" "f")))]
8511169689Skan  "!TARGET_IEEEQUAD
8512132718Skan   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
851390075Sobrien  "*
851490075Sobrien{
851590075Sobrien  if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
851690075Sobrien    return \"fneg %L0,%L1\;fneg %0,%1\";
851790075Sobrien  else
851890075Sobrien    return \"fneg %0,%1\;fneg %L0,%L1\";
851990075Sobrien}"
852090075Sobrien  [(set_attr "type" "fp")
852190075Sobrien   (set_attr "length" "8")])
852290075Sobrien
8523132718Skan(define_expand "abstf2"
852490075Sobrien  [(set (match_operand:TF 0 "gpc_reg_operand" "=f")
852590075Sobrien	(abs:TF (match_operand:TF 1 "gpc_reg_operand" "f")))]
8526169689Skan  "!TARGET_IEEEQUAD
8527132718Skan   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
8528132718Skan  "
852990075Sobrien{
8530132718Skan  rtx label = gen_label_rtx ();
8531132718Skan  emit_insn (gen_abstf2_internal (operands[0], operands[1], label));
8532132718Skan  emit_label (label);
8533132718Skan  DONE;
8534132718Skan}")
853590075Sobrien
8536132718Skan(define_expand "abstf2_internal"
853790075Sobrien  [(set (match_operand:TF 0 "gpc_reg_operand" "=f")
8538132718Skan	(match_operand:TF 1 "gpc_reg_operand" "f"))
8539132718Skan   (set (match_dup 3) (match_dup 5))
8540132718Skan   (set (match_dup 5) (abs:DF (match_dup 5)))
8541132718Skan   (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
8542132718Skan   (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
8543132718Skan			   (label_ref (match_operand 2 "" ""))
8544132718Skan			   (pc)))
8545132718Skan   (set (match_dup 6) (neg:DF (match_dup 6)))]
8546169689Skan  "!TARGET_IEEEQUAD
8547132718Skan   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
8548132718Skan  "
854990075Sobrien{
8550132718Skan  const int hi_word = FLOAT_WORDS_BIG_ENDIAN ? 0 : GET_MODE_SIZE (DFmode);
8551132718Skan  const int lo_word = FLOAT_WORDS_BIG_ENDIAN ? GET_MODE_SIZE (DFmode) : 0;
8552132718Skan  operands[3] = gen_reg_rtx (DFmode);
8553132718Skan  operands[4] = gen_reg_rtx (CCFPmode);
8554132718Skan  operands[5] = simplify_gen_subreg (DFmode, operands[0], TFmode, hi_word);
8555132718Skan  operands[6] = simplify_gen_subreg (DFmode, operands[0], TFmode, lo_word);
8556132718Skan}")
855790075Sobrien
855890075Sobrien;; Next come the multi-word integer load and store and the load and store
855990075Sobrien;; multiple insns.
856090075Sobrien
8561169689Skan; List r->r after r->"o<>", otherwise reload will try to reload a
8562169689Skan; non-offsettable address by using r->r which won't make progress.
856390075Sobrien(define_insn "*movdi_internal32"
8564169689Skan  [(set (match_operand:DI 0 "nonimmediate_operand" "=o<>,r,r,*f,*f,m,r")
8565169689Skan	(match_operand:DI 1 "input_operand" "r,r,m,f,m,f,IJKnGHF"))]
856690075Sobrien  "! TARGET_POWERPC64
856790075Sobrien   && (gpc_reg_operand (operands[0], DImode)
856890075Sobrien       || gpc_reg_operand (operands[1], DImode))"
8569169689Skan  "@
8570169689Skan   #
8571169689Skan   #
8572169689Skan   #
8573169689Skan   fmr %0,%1
8574169689Skan   lfd%U1%X1 %0,%1
8575169689Skan   stfd%U0%X0 %1,%0
8576169689Skan   #"
8577169689Skan  [(set_attr "type" "load,*,store,fp,fpload,fpstore,*")])
857890075Sobrien
857990075Sobrien(define_split
858090075Sobrien  [(set (match_operand:DI 0 "gpc_reg_operand" "")
858190075Sobrien	(match_operand:DI 1 "const_int_operand" ""))]
858290075Sobrien  "! TARGET_POWERPC64 && reload_completed"
858390075Sobrien  [(set (match_dup 2) (match_dup 4))
858490075Sobrien   (set (match_dup 3) (match_dup 1))]
858590075Sobrien  "
858690075Sobrien{
858790075Sobrien  HOST_WIDE_INT value = INTVAL (operands[1]);
858890075Sobrien  operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
858990075Sobrien				       DImode);
859090075Sobrien  operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
859190075Sobrien				       DImode);
859290075Sobrien#if HOST_BITS_PER_WIDE_INT == 32
859390075Sobrien  operands[4] = (value & 0x80000000) ? constm1_rtx : const0_rtx;
859490075Sobrien#else
859590075Sobrien  operands[4] = GEN_INT (value >> 32);
8596117395Skan  operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
859790075Sobrien#endif
859890075Sobrien}")
859990075Sobrien
860090075Sobrien(define_split
8601132718Skan  [(set (match_operand:DI 0 "nonimmediate_operand" "")
8602132718Skan        (match_operand:DI 1 "input_operand" ""))]
8603169689Skan  "reload_completed && !TARGET_POWERPC64
8604132718Skan   && gpr_or_gpr_p (operands[0], operands[1])"
8605132718Skan  [(pc)]
8606132718Skan{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
860790075Sobrien
860890075Sobrien(define_insn "*movdi_internal64"
8609169689Skan  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m,r,r,r,r,*f,*f,m,r,*h,*h")
8610169689Skan	(match_operand:DI 1 "input_operand" "r,m,r,I,L,nF,R,f,m,f,*h,r,0"))]
861190075Sobrien  "TARGET_POWERPC64
861290075Sobrien   && (gpc_reg_operand (operands[0], DImode)
861390075Sobrien       || gpc_reg_operand (operands[1], DImode))"
861490075Sobrien  "@
8615169689Skan   mr %0,%1
8616169689Skan   ld%U1%X1 %0,%1
8617132718Skan   std%U0%X0 %1,%0
861890075Sobrien   li %0,%1
861990075Sobrien   lis %0,%v1
862090075Sobrien   #
862190075Sobrien   {cal|la} %0,%a1
862290075Sobrien   fmr %0,%1
862390075Sobrien   lfd%U1%X1 %0,%1
862490075Sobrien   stfd%U0%X0 %1,%0
862590075Sobrien   mf%1 %0
862690075Sobrien   mt%0 %1
8627117395Skan   {cror 0,0,0|nop}"
8628169689Skan  [(set_attr "type" "*,load,store,*,*,*,*,fp,fpload,fpstore,mfjmpr,mtjmpr,*")
8629161651Skan   (set_attr "length" "4,4,4,4,4,20,4,4,4,4,4,4,4")])
863090075Sobrien
863190075Sobrien;; immediate value valid for a single instruction hiding in a const_double
863290075Sobrien(define_insn ""
863390075Sobrien  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
863490075Sobrien	(match_operand:DI 1 "const_double_operand" "F"))]
863590075Sobrien  "HOST_BITS_PER_WIDE_INT == 32 && TARGET_POWERPC64
863690075Sobrien   && GET_CODE (operands[1]) == CONST_DOUBLE
863790075Sobrien   && num_insns_constant (operands[1], DImode) == 1"
863890075Sobrien  "*
863990075Sobrien{
864090075Sobrien  return ((unsigned HOST_WIDE_INT)
864190075Sobrien	  (CONST_DOUBLE_LOW (operands[1]) + 0x8000) < 0x10000)
864290075Sobrien	 ? \"li %0,%1\" : \"lis %0,%v1\";
864390075Sobrien}")
864490075Sobrien
864590075Sobrien;; Generate all one-bits and clear left or right.
864690075Sobrien;; Use (and:DI (rotate:DI ...)) to avoid anddi3 unnecessary clobber.
864790075Sobrien(define_split
864890075Sobrien  [(set (match_operand:DI 0 "gpc_reg_operand" "")
864990075Sobrien	(match_operand:DI 1 "mask64_operand" ""))]
865090075Sobrien  "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
865190075Sobrien  [(set (match_dup 0) (const_int -1))
865290075Sobrien   (set (match_dup 0)
865390075Sobrien	(and:DI (rotate:DI (match_dup 0)
865490075Sobrien			   (const_int 0))
865590075Sobrien		(match_dup 1)))]
865690075Sobrien  "")
865790075Sobrien
865890075Sobrien;; Split a load of a large constant into the appropriate five-instruction
865990075Sobrien;; sequence.  Handle anything in a constant number of insns.
866090075Sobrien;; When non-easy constants can go in the TOC, this should use
866190075Sobrien;; easy_fp_constant predicate.
866290075Sobrien(define_split
866390075Sobrien  [(set (match_operand:DI 0 "gpc_reg_operand" "")
866490075Sobrien	(match_operand:DI 1 "const_int_operand" ""))]
866590075Sobrien  "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
866690075Sobrien  [(set (match_dup 0) (match_dup 2))
866790075Sobrien   (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
866890075Sobrien  "
866990075Sobrien{ rtx tem = rs6000_emit_set_const (operands[0], DImode, operands[1], 5);
867090075Sobrien
867190075Sobrien  if (tem == operands[0])
867290075Sobrien    DONE;
867390075Sobrien  else
867490075Sobrien    FAIL;
867590075Sobrien}")
867690075Sobrien
867790075Sobrien(define_split
867890075Sobrien  [(set (match_operand:DI 0 "gpc_reg_operand" "")
867990075Sobrien	(match_operand:DI 1 "const_double_operand" ""))]
868090075Sobrien  "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
868190075Sobrien  [(set (match_dup 0) (match_dup 2))
868290075Sobrien   (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
868390075Sobrien  "
868490075Sobrien{ rtx tem = rs6000_emit_set_const (operands[0], DImode, operands[1], 5);
868590075Sobrien
868690075Sobrien  if (tem == operands[0])
868790075Sobrien    DONE;
868890075Sobrien  else
868990075Sobrien    FAIL;
869090075Sobrien}")
869190075Sobrien
869290075Sobrien;; TImode is similar, except that we usually want to compute the address into
869390075Sobrien;; a register and use lsi/stsi (the exception is during reload).  MQ is also
869490075Sobrien;; clobbered in stsi for POWER, so we need a SCRATCH for it.
869590075Sobrien
869690075Sobrien;; We say that MQ is clobbered in the last alternative because the first
869790075Sobrien;; alternative would never get used otherwise since it would need a reload
869890075Sobrien;; while the 2nd alternative would not.  We put memory cases first so they
869990075Sobrien;; are preferred.  Otherwise, we'd try to reload the output instead of
870090075Sobrien;; giving the SCRATCH mq.
8701132718Skan
870290075Sobrien(define_insn "*movti_power"
8703169689Skan  [(set (match_operand:TI 0 "reg_or_mem_operand" "=Q,m,????r,????r,????r,r")
8704169689Skan	(match_operand:TI 1 "input_operand" "r,r,r,Q,m,n"))
8705169689Skan   (clobber (match_scratch:SI 2 "=q,q#X,X,X,X,X"))]
8706169689Skan  "TARGET_POWER && ! TARGET_POWERPC64
870790075Sobrien   && (gpc_reg_operand (operands[0], TImode) || gpc_reg_operand (operands[1], TImode))"
870890075Sobrien  "*
870990075Sobrien{
871090075Sobrien  switch (which_alternative)
871190075Sobrien    {
871290075Sobrien    default:
8713169689Skan      gcc_unreachable ();
871490075Sobrien
871590075Sobrien    case 0:
8716132718Skan      if (TARGET_STRING)
8717132718Skan        return \"{stsi|stswi} %1,%P0,16\";
871890075Sobrien    case 1:
871990075Sobrien    case 2:
8720132718Skan      return \"#\";
872190075Sobrien    case 3:
872290075Sobrien      /* If the address is not used in the output, we can use lsi.  Otherwise,
872390075Sobrien	 fall through to generating four loads.  */
8724132718Skan      if (TARGET_STRING
8725132718Skan	  && ! reg_overlap_mentioned_p (operands[0], operands[1]))
872690075Sobrien	return \"{lsi|lswi} %0,%P1,16\";
872790075Sobrien      /* ... fall through ...  */
872890075Sobrien    case 4:
8729169689Skan    case 5:
8730132718Skan      return \"#\";
873190075Sobrien    }
873290075Sobrien}"
8733169689Skan  [(set_attr "type" "store,store,*,load,load,*")])
873490075Sobrien
873590075Sobrien(define_insn "*movti_string"
8736169689Skan  [(set (match_operand:TI 0 "reg_or_mem_operand" "=Q,o<>,????r,????r,????r,r")
8737169689Skan	(match_operand:TI 1 "input_operand" "r,r,r,Q,m,n"))]
8738132718Skan  "! TARGET_POWER && ! TARGET_POWERPC64
873990075Sobrien   && (gpc_reg_operand (operands[0], TImode) || gpc_reg_operand (operands[1], TImode))"
874090075Sobrien  "*
874190075Sobrien{
874290075Sobrien  switch (which_alternative)
874390075Sobrien    {
874490075Sobrien    default:
8745169689Skan      gcc_unreachable ();
874690075Sobrien    case 0:
8747132718Skan      if (TARGET_STRING)
8748132718Skan        return \"{stsi|stswi} %1,%P0,16\";
8749117395Skan    case 1:
8750117395Skan    case 2:
8751132718Skan      return \"#\";
8752117395Skan    case 3:
8753117395Skan      /* If the address is not used in the output, we can use lsi.  Otherwise,
8754117395Skan	 fall through to generating four loads.  */
8755169689Skan      if (TARGET_STRING
8756132718Skan          && ! reg_overlap_mentioned_p (operands[0], operands[1]))
8757117395Skan	return \"{lsi|lswi} %0,%P1,16\";
8758117395Skan      /* ... fall through ...  */
8759117395Skan    case 4:
8760169689Skan    case 5:
8761132718Skan      return \"#\";
876290075Sobrien    }
876390075Sobrien}"
8764169689Skan  [(set_attr "type" "store_ux,store_ux,*,load_ux,load_ux,*")])
876590075Sobrien
876690075Sobrien(define_insn "*movti_ppc64"
8767169689Skan  [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o<>,r")
8768169689Skan	(match_operand:TI 1 "input_operand" "r,r,m"))]
876990075Sobrien  "TARGET_POWERPC64 && (gpc_reg_operand (operands[0], TImode)
877090075Sobrien   || gpc_reg_operand (operands[1], TImode))"
8771169689Skan  "#"
8772132718Skan  [(set_attr "type" "*,load,store")])
8773132718Skan
8774132718Skan(define_split
8775169689Skan  [(set (match_operand:TI 0 "gpc_reg_operand" "")
8776169689Skan	(match_operand:TI 1 "const_double_operand" ""))]
8777169689Skan  "TARGET_POWERPC64"
8778169689Skan  [(set (match_dup 2) (match_dup 4))
8779169689Skan   (set (match_dup 3) (match_dup 5))]
8780169689Skan  "
8781169689Skan{
8782169689Skan  operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8783169689Skan				       TImode);
8784169689Skan  operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8785169689Skan				       TImode);
8786169689Skan  if (GET_CODE (operands[1]) == CONST_DOUBLE)
8787169689Skan    {
8788169689Skan      operands[4] = GEN_INT (CONST_DOUBLE_HIGH (operands[1]));
8789169689Skan      operands[5] = GEN_INT (CONST_DOUBLE_LOW (operands[1]));
8790169689Skan    }
8791169689Skan  else if (GET_CODE (operands[1]) == CONST_INT)
8792169689Skan    {
8793169689Skan      operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
8794169689Skan      operands[5] = operands[1];
8795169689Skan    }
8796169689Skan  else
8797169689Skan    FAIL;
8798169689Skan}")
8799169689Skan
8800169689Skan(define_split
8801132718Skan  [(set (match_operand:TI 0 "nonimmediate_operand" "")
8802132718Skan        (match_operand:TI 1 "input_operand" ""))]
8803132718Skan  "reload_completed
8804132718Skan   && gpr_or_gpr_p (operands[0], operands[1])"
8805132718Skan  [(pc)]
8806132718Skan{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
880790075Sobrien
880890075Sobrien(define_expand "load_multiple"
880990075Sobrien  [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
881090075Sobrien			  (match_operand:SI 1 "" ""))
881190075Sobrien		     (use (match_operand:SI 2 "" ""))])]
881290075Sobrien  "TARGET_STRING && !TARGET_POWERPC64"
881390075Sobrien  "
881490075Sobrien{
881590075Sobrien  int regno;
881690075Sobrien  int count;
881790075Sobrien  rtx op1;
881890075Sobrien  int i;
881990075Sobrien
882090075Sobrien  /* Support only loading a constant number of fixed-point registers from
882190075Sobrien     memory and only bother with this if more than two; the machine
882290075Sobrien     doesn't support more than eight.  */
882390075Sobrien  if (GET_CODE (operands[2]) != CONST_INT
882490075Sobrien      || INTVAL (operands[2]) <= 2
882590075Sobrien      || INTVAL (operands[2]) > 8
882690075Sobrien      || GET_CODE (operands[1]) != MEM
882790075Sobrien      || GET_CODE (operands[0]) != REG
882890075Sobrien      || REGNO (operands[0]) >= 32)
882990075Sobrien    FAIL;
883090075Sobrien
883190075Sobrien  count = INTVAL (operands[2]);
883290075Sobrien  regno = REGNO (operands[0]);
883390075Sobrien
883490075Sobrien  operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
883590075Sobrien  op1 = replace_equiv_address (operands[1],
883690075Sobrien			       force_reg (SImode, XEXP (operands[1], 0)));
883790075Sobrien
883890075Sobrien  for (i = 0; i < count; i++)
883990075Sobrien    XVECEXP (operands[3], 0, i)
884090075Sobrien      = gen_rtx_SET (VOIDmode, gen_rtx_REG (SImode, regno + i),
8841117395Skan		     adjust_address_nv (op1, SImode, i * 4));
884290075Sobrien}")
884390075Sobrien
8844110611Skan(define_insn "*ldmsi8"
884590075Sobrien  [(match_parallel 0 "load_multiple_operation"
8846110611Skan    [(set (match_operand:SI 2 "gpc_reg_operand" "")
8847110611Skan          (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8848110611Skan     (set (match_operand:SI 3 "gpc_reg_operand" "")
8849110611Skan          (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8850110611Skan     (set (match_operand:SI 4 "gpc_reg_operand" "")
8851110611Skan          (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8852110611Skan     (set (match_operand:SI 5 "gpc_reg_operand" "")
8853110611Skan          (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8854110611Skan     (set (match_operand:SI 6 "gpc_reg_operand" "")
8855110611Skan          (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8856110611Skan     (set (match_operand:SI 7 "gpc_reg_operand" "")
8857110611Skan          (mem:SI (plus:SI (match_dup 1) (const_int 20))))
8858110611Skan     (set (match_operand:SI 8 "gpc_reg_operand" "")
8859110611Skan          (mem:SI (plus:SI (match_dup 1) (const_int 24))))
8860110611Skan     (set (match_operand:SI 9 "gpc_reg_operand" "")
8861110611Skan          (mem:SI (plus:SI (match_dup 1) (const_int 28))))])]
8862110611Skan  "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
886390075Sobrien  "*
8864110611Skan{ return rs6000_output_load_multiple (operands); }"
8865169689Skan  [(set_attr "type" "load_ux")
8866110611Skan   (set_attr "length" "32")])
886790075Sobrien
8868110611Skan(define_insn "*ldmsi7"
8869110611Skan  [(match_parallel 0 "load_multiple_operation"
8870110611Skan    [(set (match_operand:SI 2 "gpc_reg_operand" "")
8871110611Skan          (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8872110611Skan     (set (match_operand:SI 3 "gpc_reg_operand" "")
8873110611Skan          (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8874110611Skan     (set (match_operand:SI 4 "gpc_reg_operand" "")
8875110611Skan          (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8876110611Skan     (set (match_operand:SI 5 "gpc_reg_operand" "")
8877110611Skan          (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8878110611Skan     (set (match_operand:SI 6 "gpc_reg_operand" "")
8879110611Skan          (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8880110611Skan     (set (match_operand:SI 7 "gpc_reg_operand" "")
8881110611Skan          (mem:SI (plus:SI (match_dup 1) (const_int 20))))
8882110611Skan     (set (match_operand:SI 8 "gpc_reg_operand" "")
8883110611Skan          (mem:SI (plus:SI (match_dup 1) (const_int 24))))])]
8884110611Skan  "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
8885110611Skan  "*
8886110611Skan{ return rs6000_output_load_multiple (operands); }"
8887169689Skan  [(set_attr "type" "load_ux")
8888110611Skan   (set_attr "length" "32")])
888990075Sobrien
8890110611Skan(define_insn "*ldmsi6"
8891110611Skan  [(match_parallel 0 "load_multiple_operation"
8892110611Skan    [(set (match_operand:SI 2 "gpc_reg_operand" "")
8893110611Skan          (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8894110611Skan     (set (match_operand:SI 3 "gpc_reg_operand" "")
8895110611Skan          (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8896110611Skan     (set (match_operand:SI 4 "gpc_reg_operand" "")
8897110611Skan          (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8898110611Skan     (set (match_operand:SI 5 "gpc_reg_operand" "")
8899110611Skan          (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8900110611Skan     (set (match_operand:SI 6 "gpc_reg_operand" "")
8901110611Skan          (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8902110611Skan     (set (match_operand:SI 7 "gpc_reg_operand" "")
8903110611Skan          (mem:SI (plus:SI (match_dup 1) (const_int 20))))])]
8904110611Skan  "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
8905110611Skan  "*
8906110611Skan{ return rs6000_output_load_multiple (operands); }"
8907169689Skan  [(set_attr "type" "load_ux")
8908110611Skan   (set_attr "length" "32")])
890990075Sobrien
8910110611Skan(define_insn "*ldmsi5"
8911110611Skan  [(match_parallel 0 "load_multiple_operation"
8912110611Skan    [(set (match_operand:SI 2 "gpc_reg_operand" "")
8913110611Skan          (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8914110611Skan     (set (match_operand:SI 3 "gpc_reg_operand" "")
8915110611Skan          (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8916110611Skan     (set (match_operand:SI 4 "gpc_reg_operand" "")
8917110611Skan          (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8918110611Skan     (set (match_operand:SI 5 "gpc_reg_operand" "")
8919110611Skan          (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8920110611Skan     (set (match_operand:SI 6 "gpc_reg_operand" "")
8921110611Skan          (mem:SI (plus:SI (match_dup 1) (const_int 16))))])]
8922110611Skan  "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
8923110611Skan  "*
8924110611Skan{ return rs6000_output_load_multiple (operands); }"
8925169689Skan  [(set_attr "type" "load_ux")
892690075Sobrien   (set_attr "length" "32")])
892790075Sobrien
8928110611Skan(define_insn "*ldmsi4"
8929110611Skan  [(match_parallel 0 "load_multiple_operation"
8930110611Skan    [(set (match_operand:SI 2 "gpc_reg_operand" "")
8931110611Skan          (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8932110611Skan     (set (match_operand:SI 3 "gpc_reg_operand" "")
8933110611Skan          (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8934110611Skan     (set (match_operand:SI 4 "gpc_reg_operand" "")
8935110611Skan          (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8936110611Skan     (set (match_operand:SI 5 "gpc_reg_operand" "")
8937110611Skan          (mem:SI (plus:SI (match_dup 1) (const_int 12))))])]
8938110611Skan  "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
8939110611Skan  "*
8940110611Skan{ return rs6000_output_load_multiple (operands); }"
8941169689Skan  [(set_attr "type" "load_ux")
8942110611Skan   (set_attr "length" "32")])
8943110611Skan
8944110611Skan(define_insn "*ldmsi3"
8945110611Skan  [(match_parallel 0 "load_multiple_operation"
8946110611Skan    [(set (match_operand:SI 2 "gpc_reg_operand" "")
8947110611Skan          (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8948110611Skan     (set (match_operand:SI 3 "gpc_reg_operand" "")
8949110611Skan          (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8950110611Skan     (set (match_operand:SI 4 "gpc_reg_operand" "")
8951110611Skan          (mem:SI (plus:SI (match_dup 1) (const_int 8))))])]
8952110611Skan  "TARGET_STRING && XVECLEN (operands[0], 0) == 3"
8953110611Skan  "*
8954110611Skan{ return rs6000_output_load_multiple (operands); }"
8955169689Skan  [(set_attr "type" "load_ux")
8956110611Skan   (set_attr "length" "32")])
8957110611Skan
895890075Sobrien(define_expand "store_multiple"
895990075Sobrien  [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
896090075Sobrien			  (match_operand:SI 1 "" ""))
896190075Sobrien		     (clobber (scratch:SI))
896290075Sobrien		     (use (match_operand:SI 2 "" ""))])]
896390075Sobrien  "TARGET_STRING && !TARGET_POWERPC64"
896490075Sobrien  "
896590075Sobrien{
896690075Sobrien  int regno;
896790075Sobrien  int count;
896890075Sobrien  rtx to;
896990075Sobrien  rtx op0;
897090075Sobrien  int i;
897190075Sobrien
897290075Sobrien  /* Support only storing a constant number of fixed-point registers to
897390075Sobrien     memory and only bother with this if more than two; the machine
897490075Sobrien     doesn't support more than eight.  */
897590075Sobrien  if (GET_CODE (operands[2]) != CONST_INT
897690075Sobrien      || INTVAL (operands[2]) <= 2
897790075Sobrien      || INTVAL (operands[2]) > 8
897890075Sobrien      || GET_CODE (operands[0]) != MEM
897990075Sobrien      || GET_CODE (operands[1]) != REG
898090075Sobrien      || REGNO (operands[1]) >= 32)
898190075Sobrien    FAIL;
898290075Sobrien
898390075Sobrien  count = INTVAL (operands[2]);
898490075Sobrien  regno = REGNO (operands[1]);
898590075Sobrien
898690075Sobrien  operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + 1));
898790075Sobrien  to = force_reg (SImode, XEXP (operands[0], 0));
898890075Sobrien  op0 = replace_equiv_address (operands[0], to);
898990075Sobrien
899090075Sobrien  XVECEXP (operands[3], 0, 0)
8991117395Skan    = gen_rtx_SET (VOIDmode, adjust_address_nv (op0, SImode, 0), operands[1]);
899290075Sobrien  XVECEXP (operands[3], 0, 1) = gen_rtx_CLOBBER (VOIDmode,
899390075Sobrien						 gen_rtx_SCRATCH (SImode));
899490075Sobrien
899590075Sobrien  for (i = 1; i < count; i++)
899690075Sobrien    XVECEXP (operands[3], 0, i + 1)
899790075Sobrien      = gen_rtx_SET (VOIDmode,
8998117395Skan		     adjust_address_nv (op0, SImode, i * 4),
899990075Sobrien		     gen_rtx_REG (SImode, regno + i));
900090075Sobrien}")
900190075Sobrien
9002132718Skan(define_insn "*stmsi8"
900390075Sobrien  [(match_parallel 0 "store_multiple_operation"
9004132718Skan    [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9005132718Skan	  (match_operand:SI 2 "gpc_reg_operand" "r"))
9006169689Skan     (clobber (match_scratch:SI 3 "=X"))
9007132718Skan     (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9008132718Skan	  (match_operand:SI 4 "gpc_reg_operand" "r"))
9009132718Skan     (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9010132718Skan	  (match_operand:SI 5 "gpc_reg_operand" "r"))
9011132718Skan     (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9012132718Skan	  (match_operand:SI 6 "gpc_reg_operand" "r"))
9013132718Skan     (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9014132718Skan	  (match_operand:SI 7 "gpc_reg_operand" "r"))
9015132718Skan     (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
9016132718Skan	  (match_operand:SI 8 "gpc_reg_operand" "r"))
9017132718Skan     (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
9018132718Skan	  (match_operand:SI 9 "gpc_reg_operand" "r"))
9019132718Skan     (set (mem:SI (plus:SI (match_dup 1) (const_int 28)))
9020132718Skan	  (match_operand:SI 10 "gpc_reg_operand" "r"))])]
9021132718Skan  "TARGET_STRING && !TARGET_POWER && XVECLEN (operands[0], 0) == 9"
902290075Sobrien  "{stsi|stswi} %2,%1,%O0"
9023169689Skan  [(set_attr "type" "store_ux")])
902490075Sobrien
9025132718Skan(define_insn "*stmsi7"
9026132718Skan  [(match_parallel 0 "store_multiple_operation"
9027132718Skan    [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9028132718Skan	  (match_operand:SI 2 "gpc_reg_operand" "r"))
9029169689Skan     (clobber (match_scratch:SI 3 "=X"))
9030132718Skan     (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9031132718Skan	  (match_operand:SI 4 "gpc_reg_operand" "r"))
9032132718Skan     (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9033132718Skan	  (match_operand:SI 5 "gpc_reg_operand" "r"))
9034132718Skan     (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9035132718Skan	  (match_operand:SI 6 "gpc_reg_operand" "r"))
9036132718Skan     (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9037132718Skan	  (match_operand:SI 7 "gpc_reg_operand" "r"))
9038132718Skan     (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
9039132718Skan	  (match_operand:SI 8 "gpc_reg_operand" "r"))
9040132718Skan     (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
9041132718Skan	  (match_operand:SI 9 "gpc_reg_operand" "r"))])]
9042132718Skan  "TARGET_STRING && !TARGET_POWER && XVECLEN (operands[0], 0) == 8"
9043132718Skan  "{stsi|stswi} %2,%1,%O0"
9044169689Skan  [(set_attr "type" "store_ux")])
9045132718Skan
9046132718Skan(define_insn "*stmsi6"
9047132718Skan  [(match_parallel 0 "store_multiple_operation"
9048132718Skan    [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9049132718Skan	  (match_operand:SI 2 "gpc_reg_operand" "r"))
9050169689Skan     (clobber (match_scratch:SI 3 "=X"))
9051132718Skan     (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9052132718Skan	  (match_operand:SI 4 "gpc_reg_operand" "r"))
9053132718Skan     (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9054132718Skan	  (match_operand:SI 5 "gpc_reg_operand" "r"))
9055132718Skan     (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9056132718Skan	  (match_operand:SI 6 "gpc_reg_operand" "r"))
9057132718Skan     (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9058132718Skan	  (match_operand:SI 7 "gpc_reg_operand" "r"))
9059132718Skan     (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
9060132718Skan	  (match_operand:SI 8 "gpc_reg_operand" "r"))])]
9061132718Skan  "TARGET_STRING && !TARGET_POWER && XVECLEN (operands[0], 0) == 7"
9062132718Skan  "{stsi|stswi} %2,%1,%O0"
9063169689Skan  [(set_attr "type" "store_ux")])
9064132718Skan
9065132718Skan(define_insn "*stmsi5"
9066132718Skan  [(match_parallel 0 "store_multiple_operation"
9067132718Skan    [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9068132718Skan	  (match_operand:SI 2 "gpc_reg_operand" "r"))
9069169689Skan     (clobber (match_scratch:SI 3 "=X"))
9070132718Skan     (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9071132718Skan	  (match_operand:SI 4 "gpc_reg_operand" "r"))
9072132718Skan     (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9073132718Skan	  (match_operand:SI 5 "gpc_reg_operand" "r"))
9074132718Skan     (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9075132718Skan	  (match_operand:SI 6 "gpc_reg_operand" "r"))
9076132718Skan     (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9077132718Skan	  (match_operand:SI 7 "gpc_reg_operand" "r"))])]
9078132718Skan  "TARGET_STRING && !TARGET_POWER && XVECLEN (operands[0], 0) == 6"
9079132718Skan  "{stsi|stswi} %2,%1,%O0"
9080169689Skan  [(set_attr "type" "store_ux")])
9081132718Skan
9082132718Skan(define_insn "*stmsi4"
9083132718Skan  [(match_parallel 0 "store_multiple_operation"
9084132718Skan    [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9085132718Skan	  (match_operand:SI 2 "gpc_reg_operand" "r"))
9086169689Skan     (clobber (match_scratch:SI 3 "=X"))
9087132718Skan     (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9088132718Skan	  (match_operand:SI 4 "gpc_reg_operand" "r"))
9089132718Skan     (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9090132718Skan	  (match_operand:SI 5 "gpc_reg_operand" "r"))
9091132718Skan     (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9092132718Skan	  (match_operand:SI 6 "gpc_reg_operand" "r"))])]
9093132718Skan  "TARGET_STRING && !TARGET_POWER && XVECLEN (operands[0], 0) == 5"
9094132718Skan  "{stsi|stswi} %2,%1,%O0"
9095169689Skan  [(set_attr "type" "store_ux")])
9096132718Skan
9097132718Skan(define_insn "*stmsi3"
9098132718Skan  [(match_parallel 0 "store_multiple_operation"
9099132718Skan    [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9100132718Skan	  (match_operand:SI 2 "gpc_reg_operand" "r"))
9101169689Skan     (clobber (match_scratch:SI 3 "=X"))
9102132718Skan     (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9103132718Skan	  (match_operand:SI 4 "gpc_reg_operand" "r"))
9104132718Skan     (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9105132718Skan	  (match_operand:SI 5 "gpc_reg_operand" "r"))])]
9106132718Skan  "TARGET_STRING && !TARGET_POWER && XVECLEN (operands[0], 0) == 4"
9107132718Skan  "{stsi|stswi} %2,%1,%O0"
9108169689Skan  [(set_attr "type" "store_ux")])
9109169689Skan
9110169689Skan(define_insn "*stmsi8_power"
9111169689Skan  [(match_parallel 0 "store_multiple_operation"
9112169689Skan    [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9113169689Skan	  (match_operand:SI 2 "gpc_reg_operand" "r"))
9114169689Skan     (clobber (match_scratch:SI 3 "=q"))
9115169689Skan     (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9116169689Skan	  (match_operand:SI 4 "gpc_reg_operand" "r"))
9117169689Skan     (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9118169689Skan	  (match_operand:SI 5 "gpc_reg_operand" "r"))
9119169689Skan     (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9120169689Skan	  (match_operand:SI 6 "gpc_reg_operand" "r"))
9121169689Skan     (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9122169689Skan	  (match_operand:SI 7 "gpc_reg_operand" "r"))
9123169689Skan     (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
9124169689Skan	  (match_operand:SI 8 "gpc_reg_operand" "r"))
9125169689Skan     (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
9126169689Skan	  (match_operand:SI 9 "gpc_reg_operand" "r"))
9127169689Skan     (set (mem:SI (plus:SI (match_dup 1) (const_int 28)))
9128169689Skan	  (match_operand:SI 10 "gpc_reg_operand" "r"))])]
9129169689Skan  "TARGET_STRING && TARGET_POWER && XVECLEN (operands[0], 0) == 9"
9130169689Skan  "{stsi|stswi} %2,%1,%O0"
9131169689Skan  [(set_attr "type" "store_ux")])
9132169689Skan
9133169689Skan(define_insn "*stmsi7_power"
9134169689Skan  [(match_parallel 0 "store_multiple_operation"
9135169689Skan    [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9136169689Skan	  (match_operand:SI 2 "gpc_reg_operand" "r"))
9137169689Skan     (clobber (match_scratch:SI 3 "=q"))
9138169689Skan     (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9139169689Skan	  (match_operand:SI 4 "gpc_reg_operand" "r"))
9140169689Skan     (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9141169689Skan	  (match_operand:SI 5 "gpc_reg_operand" "r"))
9142169689Skan     (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9143169689Skan	  (match_operand:SI 6 "gpc_reg_operand" "r"))
9144169689Skan     (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9145169689Skan	  (match_operand:SI 7 "gpc_reg_operand" "r"))
9146169689Skan     (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
9147169689Skan	  (match_operand:SI 8 "gpc_reg_operand" "r"))
9148169689Skan     (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
9149169689Skan	  (match_operand:SI 9 "gpc_reg_operand" "r"))])]
9150169689Skan  "TARGET_STRING && TARGET_POWER && XVECLEN (operands[0], 0) == 8"
9151169689Skan  "{stsi|stswi} %2,%1,%O0"
9152169689Skan  [(set_attr "type" "store_ux")])
9153169689Skan
9154169689Skan(define_insn "*stmsi6_power"
9155169689Skan  [(match_parallel 0 "store_multiple_operation"
9156169689Skan    [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9157169689Skan	  (match_operand:SI 2 "gpc_reg_operand" "r"))
9158169689Skan     (clobber (match_scratch:SI 3 "=q"))
9159169689Skan     (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9160169689Skan	  (match_operand:SI 4 "gpc_reg_operand" "r"))
9161169689Skan     (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9162169689Skan	  (match_operand:SI 5 "gpc_reg_operand" "r"))
9163169689Skan     (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9164169689Skan	  (match_operand:SI 6 "gpc_reg_operand" "r"))
9165169689Skan     (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9166169689Skan	  (match_operand:SI 7 "gpc_reg_operand" "r"))
9167169689Skan     (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
9168169689Skan	  (match_operand:SI 8 "gpc_reg_operand" "r"))])]
9169169689Skan  "TARGET_STRING && TARGET_POWER && XVECLEN (operands[0], 0) == 7"
9170169689Skan  "{stsi|stswi} %2,%1,%O0"
9171169689Skan  [(set_attr "type" "store_ux")])
9172169689Skan
9173169689Skan(define_insn "*stmsi5_power"
9174169689Skan  [(match_parallel 0 "store_multiple_operation"
9175169689Skan    [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9176169689Skan	  (match_operand:SI 2 "gpc_reg_operand" "r"))
9177169689Skan     (clobber (match_scratch:SI 3 "=q"))
9178169689Skan     (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9179169689Skan	  (match_operand:SI 4 "gpc_reg_operand" "r"))
9180169689Skan     (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9181169689Skan	  (match_operand:SI 5 "gpc_reg_operand" "r"))
9182169689Skan     (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9183169689Skan	  (match_operand:SI 6 "gpc_reg_operand" "r"))
9184169689Skan     (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9185169689Skan	  (match_operand:SI 7 "gpc_reg_operand" "r"))])]
9186169689Skan  "TARGET_STRING && TARGET_POWER && XVECLEN (operands[0], 0) == 6"
9187169689Skan  "{stsi|stswi} %2,%1,%O0"
9188169689Skan  [(set_attr "type" "store_ux")])
9189169689Skan
9190169689Skan(define_insn "*stmsi4_power"
9191169689Skan  [(match_parallel 0 "store_multiple_operation"
9192169689Skan    [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9193169689Skan	  (match_operand:SI 2 "gpc_reg_operand" "r"))
9194169689Skan     (clobber (match_scratch:SI 3 "=q"))
9195169689Skan     (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9196169689Skan	  (match_operand:SI 4 "gpc_reg_operand" "r"))
9197169689Skan     (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9198169689Skan	  (match_operand:SI 5 "gpc_reg_operand" "r"))
9199169689Skan     (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9200169689Skan	  (match_operand:SI 6 "gpc_reg_operand" "r"))])]
9201169689Skan  "TARGET_STRING && TARGET_POWER && XVECLEN (operands[0], 0) == 5"
9202169689Skan  "{stsi|stswi} %2,%1,%O0"
9203169689Skan  [(set_attr "type" "store_ux")])
9204169689Skan
9205169689Skan(define_insn "*stmsi3_power"
9206169689Skan  [(match_parallel 0 "store_multiple_operation"
9207169689Skan    [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9208169689Skan	  (match_operand:SI 2 "gpc_reg_operand" "r"))
9209169689Skan     (clobber (match_scratch:SI 3 "=q"))
9210169689Skan     (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9211169689Skan	  (match_operand:SI 4 "gpc_reg_operand" "r"))
9212169689Skan     (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9213169689Skan	  (match_operand:SI 5 "gpc_reg_operand" "r"))])]
9214169689Skan  "TARGET_STRING && TARGET_POWER && XVECLEN (operands[0], 0) == 4"
9215169689Skan  "{stsi|stswi} %2,%1,%O0"
9216169689Skan  [(set_attr "type" "store_ux")])
921790075Sobrien
9218169689Skan(define_expand "setmemsi"
9219169689Skan  [(parallel [(set (match_operand:BLK 0 "" "")
9220169689Skan		   (match_operand 2 "const_int_operand" ""))
9221169689Skan	      (use (match_operand:SI 1 "" ""))
9222169689Skan	      (use (match_operand:SI 3 "" ""))])]
9223169689Skan  ""
9224169689Skan  "
9225169689Skan{
9226169689Skan  /* If value to set is not zero, use the library routine.  */
9227169689Skan  if (operands[2] != const0_rtx)
9228169689Skan    FAIL;
9229169689Skan
9230169689Skan  if (expand_block_clear (operands))
9231169689Skan    DONE;
9232169689Skan  else
9233169689Skan    FAIL;
9234169689Skan}")
9235169689Skan
923690075Sobrien;; String/block move insn.
923790075Sobrien;; Argument 0 is the destination
923890075Sobrien;; Argument 1 is the source
923990075Sobrien;; Argument 2 is the length
924090075Sobrien;; Argument 3 is the alignment
924190075Sobrien
9242169689Skan(define_expand "movmemsi"
924390075Sobrien  [(parallel [(set (match_operand:BLK 0 "" "")
924490075Sobrien		   (match_operand:BLK 1 "" ""))
924590075Sobrien	      (use (match_operand:SI 2 "" ""))
924690075Sobrien	      (use (match_operand:SI 3 "" ""))])]
924790075Sobrien  ""
924890075Sobrien  "
924990075Sobrien{
925090075Sobrien  if (expand_block_move (operands))
925190075Sobrien    DONE;
925290075Sobrien  else
925390075Sobrien    FAIL;
925490075Sobrien}")
925590075Sobrien
925690075Sobrien;; Move up to 32 bytes at a time.  The fixed registers are needed because the
925790075Sobrien;; register allocator doesn't have a clue about allocating 8 word registers.
925890075Sobrien;; rD/rS = r5 is preferred, efficient form.
9259169689Skan(define_expand "movmemsi_8reg"
926090075Sobrien  [(parallel [(set (match_operand 0 "" "")
926190075Sobrien		   (match_operand 1 "" ""))
926290075Sobrien	      (use (match_operand 2 "" ""))
926390075Sobrien	      (use (match_operand 3 "" ""))
926490075Sobrien	      (clobber (reg:SI  5))
926590075Sobrien	      (clobber (reg:SI  6))
926690075Sobrien	      (clobber (reg:SI  7))
926790075Sobrien	      (clobber (reg:SI  8))
926890075Sobrien	      (clobber (reg:SI  9))
926990075Sobrien	      (clobber (reg:SI 10))
927090075Sobrien	      (clobber (reg:SI 11))
927190075Sobrien	      (clobber (reg:SI 12))
927290075Sobrien	      (clobber (match_scratch:SI 4 ""))])]
927390075Sobrien  "TARGET_STRING"
927490075Sobrien  "")
927590075Sobrien
927690075Sobrien(define_insn ""
927790075Sobrien  [(set (mem:BLK (match_operand:SI 0 "gpc_reg_operand" "b"))
927890075Sobrien	(mem:BLK (match_operand:SI 1 "gpc_reg_operand" "b")))
927990075Sobrien   (use (match_operand:SI 2 "immediate_operand" "i"))
928090075Sobrien   (use (match_operand:SI 3 "immediate_operand" "i"))
928190075Sobrien   (clobber (match_operand:SI 4 "gpc_reg_operand" "=r"))
928290075Sobrien   (clobber (reg:SI  6))
928390075Sobrien   (clobber (reg:SI  7))
928490075Sobrien   (clobber (reg:SI  8))
928590075Sobrien   (clobber (reg:SI  9))
928690075Sobrien   (clobber (reg:SI 10))
928790075Sobrien   (clobber (reg:SI 11))
928890075Sobrien   (clobber (reg:SI 12))
928990075Sobrien   (clobber (match_scratch:SI 5 "=q"))]
929090075Sobrien  "TARGET_STRING && TARGET_POWER
929190075Sobrien   && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32)
929290075Sobrien       || INTVAL (operands[2]) == 0)
929390075Sobrien   && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 12)
929490075Sobrien   && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12)
929590075Sobrien   && REGNO (operands[4]) == 5"
929690075Sobrien  "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
9297169689Skan  [(set_attr "type" "store_ux")
929890075Sobrien   (set_attr "length" "8")])
929990075Sobrien
930090075Sobrien(define_insn ""
9301169689Skan  [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9302169689Skan	(mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
930390075Sobrien   (use (match_operand:SI 2 "immediate_operand" "i"))
930490075Sobrien   (use (match_operand:SI 3 "immediate_operand" "i"))
930590075Sobrien   (clobber (match_operand:SI 4 "gpc_reg_operand" "=r"))
930690075Sobrien   (clobber (reg:SI  6))
930790075Sobrien   (clobber (reg:SI  7))
930890075Sobrien   (clobber (reg:SI  8))
930990075Sobrien   (clobber (reg:SI  9))
931090075Sobrien   (clobber (reg:SI 10))
931190075Sobrien   (clobber (reg:SI 11))
931290075Sobrien   (clobber (reg:SI 12))
9313169689Skan   (clobber (match_scratch:SI 5 "=X"))]
931490075Sobrien  "TARGET_STRING && ! TARGET_POWER
931590075Sobrien   && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32)
931690075Sobrien       || INTVAL (operands[2]) == 0)
931790075Sobrien   && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 12)
931890075Sobrien   && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12)
931990075Sobrien   && REGNO (operands[4]) == 5"
932090075Sobrien  "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
9321169689Skan  [(set_attr "type" "store_ux")
932290075Sobrien   (set_attr "length" "8")])
932390075Sobrien
932490075Sobrien;; Move up to 24 bytes at a time.  The fixed registers are needed because the
932590075Sobrien;; register allocator doesn't have a clue about allocating 6 word registers.
932690075Sobrien;; rD/rS = r5 is preferred, efficient form.
9327169689Skan(define_expand "movmemsi_6reg"
932890075Sobrien  [(parallel [(set (match_operand 0 "" "")
932990075Sobrien		   (match_operand 1 "" ""))
933090075Sobrien	      (use (match_operand 2 "" ""))
933190075Sobrien	      (use (match_operand 3 "" ""))
933290075Sobrien	      (clobber (reg:SI  5))
933390075Sobrien	      (clobber (reg:SI  6))
933490075Sobrien	      (clobber (reg:SI  7))
933590075Sobrien	      (clobber (reg:SI  8))
933690075Sobrien	      (clobber (reg:SI  9))
933790075Sobrien	      (clobber (reg:SI 10))
933890075Sobrien	      (clobber (match_scratch:SI 4 ""))])]
933990075Sobrien  "TARGET_STRING"
934090075Sobrien  "")
934190075Sobrien
934290075Sobrien(define_insn ""
934390075Sobrien  [(set (mem:BLK (match_operand:SI 0 "gpc_reg_operand" "b"))
934490075Sobrien	(mem:BLK (match_operand:SI 1 "gpc_reg_operand" "b")))
934590075Sobrien   (use (match_operand:SI 2 "immediate_operand" "i"))
934690075Sobrien   (use (match_operand:SI 3 "immediate_operand" "i"))
934790075Sobrien   (clobber (match_operand:SI 4 "gpc_reg_operand" "=r"))
934890075Sobrien   (clobber (reg:SI  6))
934990075Sobrien   (clobber (reg:SI  7))
935090075Sobrien   (clobber (reg:SI  8))
935190075Sobrien   (clobber (reg:SI  9))
935290075Sobrien   (clobber (reg:SI 10))
935390075Sobrien   (clobber (match_scratch:SI 5 "=q"))]
935490075Sobrien  "TARGET_STRING && TARGET_POWER
935590075Sobrien   && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 24
935690075Sobrien   && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 10)
935790075Sobrien   && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 10)
935890075Sobrien   && REGNO (operands[4]) == 5"
935990075Sobrien  "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
9360169689Skan  [(set_attr "type" "store_ux")
936190075Sobrien   (set_attr "length" "8")])
936290075Sobrien
936390075Sobrien(define_insn ""
9364169689Skan  [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9365169689Skan	(mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
936690075Sobrien   (use (match_operand:SI 2 "immediate_operand" "i"))
936790075Sobrien   (use (match_operand:SI 3 "immediate_operand" "i"))
936890075Sobrien   (clobber (match_operand:SI 4 "gpc_reg_operand" "=r"))
936990075Sobrien   (clobber (reg:SI  6))
937090075Sobrien   (clobber (reg:SI  7))
937190075Sobrien   (clobber (reg:SI  8))
937290075Sobrien   (clobber (reg:SI  9))
937390075Sobrien   (clobber (reg:SI 10))
9374169689Skan   (clobber (match_scratch:SI 5 "=X"))]
937590075Sobrien  "TARGET_STRING && ! TARGET_POWER
937690075Sobrien   && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 32
937790075Sobrien   && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 10)
937890075Sobrien   && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 10)
937990075Sobrien   && REGNO (operands[4]) == 5"
938090075Sobrien  "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
9381169689Skan  [(set_attr "type" "store_ux")
938290075Sobrien   (set_attr "length" "8")])
938390075Sobrien
938490075Sobrien;; Move up to 16 bytes at a time, using 4 fixed registers to avoid spill
938590075Sobrien;; problems with TImode.
938690075Sobrien;; rD/rS = r5 is preferred, efficient form.
9387169689Skan(define_expand "movmemsi_4reg"
938890075Sobrien  [(parallel [(set (match_operand 0 "" "")
938990075Sobrien		   (match_operand 1 "" ""))
939090075Sobrien	      (use (match_operand 2 "" ""))
939190075Sobrien	      (use (match_operand 3 "" ""))
939290075Sobrien	      (clobber (reg:SI 5))
939390075Sobrien	      (clobber (reg:SI 6))
939490075Sobrien	      (clobber (reg:SI 7))
939590075Sobrien	      (clobber (reg:SI 8))
939690075Sobrien	      (clobber (match_scratch:SI 4 ""))])]
939790075Sobrien  "TARGET_STRING"
939890075Sobrien  "")
939990075Sobrien
940090075Sobrien(define_insn ""
940190075Sobrien  [(set (mem:BLK (match_operand:SI 0 "gpc_reg_operand" "b"))
940290075Sobrien	(mem:BLK (match_operand:SI 1 "gpc_reg_operand" "b")))
940390075Sobrien   (use (match_operand:SI 2 "immediate_operand" "i"))
940490075Sobrien   (use (match_operand:SI 3 "immediate_operand" "i"))
940590075Sobrien   (clobber (match_operand:SI 4 "gpc_reg_operand" "=r"))
940690075Sobrien   (clobber (reg:SI 6))
940790075Sobrien   (clobber (reg:SI 7))
940890075Sobrien   (clobber (reg:SI 8))
940990075Sobrien   (clobber (match_scratch:SI 5 "=q"))]
941090075Sobrien  "TARGET_STRING && TARGET_POWER
941190075Sobrien   && INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16
941290075Sobrien   && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 8)
941390075Sobrien   && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 8)
941490075Sobrien   && REGNO (operands[4]) == 5"
941590075Sobrien  "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
9416169689Skan  [(set_attr "type" "store_ux")
941790075Sobrien   (set_attr "length" "8")])
941890075Sobrien
941990075Sobrien(define_insn ""
9420169689Skan  [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9421169689Skan	(mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
942290075Sobrien   (use (match_operand:SI 2 "immediate_operand" "i"))
942390075Sobrien   (use (match_operand:SI 3 "immediate_operand" "i"))
942490075Sobrien   (clobber (match_operand:SI 4 "gpc_reg_operand" "=r"))
942590075Sobrien   (clobber (reg:SI 6))
942690075Sobrien   (clobber (reg:SI 7))
942790075Sobrien   (clobber (reg:SI 8))
9428169689Skan   (clobber (match_scratch:SI 5 "=X"))]
942990075Sobrien  "TARGET_STRING && ! TARGET_POWER
943090075Sobrien   && INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16
943190075Sobrien   && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 8)
943290075Sobrien   && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 8)
943390075Sobrien   && REGNO (operands[4]) == 5"
943490075Sobrien  "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
9435169689Skan  [(set_attr "type" "store_ux")
943690075Sobrien   (set_attr "length" "8")])
943790075Sobrien
943890075Sobrien;; Move up to 8 bytes at a time.
9439169689Skan(define_expand "movmemsi_2reg"
944090075Sobrien  [(parallel [(set (match_operand 0 "" "")
944190075Sobrien		   (match_operand 1 "" ""))
944290075Sobrien	      (use (match_operand 2 "" ""))
944390075Sobrien	      (use (match_operand 3 "" ""))
944490075Sobrien	      (clobber (match_scratch:DI 4 ""))
944590075Sobrien	      (clobber (match_scratch:SI 5 ""))])]
944690075Sobrien  "TARGET_STRING && ! TARGET_POWERPC64"
944790075Sobrien  "")
944890075Sobrien
944990075Sobrien(define_insn ""
945090075Sobrien  [(set (mem:BLK (match_operand:SI 0 "gpc_reg_operand" "b"))
945190075Sobrien	(mem:BLK (match_operand:SI 1 "gpc_reg_operand" "b")))
945290075Sobrien   (use (match_operand:SI 2 "immediate_operand" "i"))
945390075Sobrien   (use (match_operand:SI 3 "immediate_operand" "i"))
945490075Sobrien   (clobber (match_scratch:DI 4 "=&r"))
945590075Sobrien   (clobber (match_scratch:SI 5 "=q"))]
945690075Sobrien  "TARGET_STRING && TARGET_POWER && ! TARGET_POWERPC64
945790075Sobrien   && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8"
945890075Sobrien  "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
9459169689Skan  [(set_attr "type" "store_ux")
946090075Sobrien   (set_attr "length" "8")])
946190075Sobrien
946290075Sobrien(define_insn ""
946390075Sobrien  [(set (mem:BLK (match_operand:SI 0 "gpc_reg_operand" "b"))
946490075Sobrien	(mem:BLK (match_operand:SI 1 "gpc_reg_operand" "b")))
946590075Sobrien   (use (match_operand:SI 2 "immediate_operand" "i"))
946690075Sobrien   (use (match_operand:SI 3 "immediate_operand" "i"))
946790075Sobrien   (clobber (match_scratch:DI 4 "=&r"))
9468169689Skan   (clobber (match_scratch:SI 5 "=X"))]
946990075Sobrien  "TARGET_STRING && ! TARGET_POWER && ! TARGET_POWERPC64
947090075Sobrien   && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8"
947190075Sobrien  "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
9472169689Skan  [(set_attr "type" "store_ux")
947390075Sobrien   (set_attr "length" "8")])
947490075Sobrien
947590075Sobrien;; Move up to 4 bytes at a time.
9476169689Skan(define_expand "movmemsi_1reg"
947790075Sobrien  [(parallel [(set (match_operand 0 "" "")
947890075Sobrien		   (match_operand 1 "" ""))
947990075Sobrien	      (use (match_operand 2 "" ""))
948090075Sobrien	      (use (match_operand 3 "" ""))
948190075Sobrien	      (clobber (match_scratch:SI 4 ""))
948290075Sobrien	      (clobber (match_scratch:SI 5 ""))])]
948390075Sobrien  "TARGET_STRING"
948490075Sobrien  "")
948590075Sobrien
948690075Sobrien(define_insn ""
948790075Sobrien  [(set (mem:BLK (match_operand:SI 0 "gpc_reg_operand" "b"))
948890075Sobrien	(mem:BLK (match_operand:SI 1 "gpc_reg_operand" "b")))
948990075Sobrien   (use (match_operand:SI 2 "immediate_operand" "i"))
949090075Sobrien   (use (match_operand:SI 3 "immediate_operand" "i"))
949190075Sobrien   (clobber (match_scratch:SI 4 "=&r"))
949290075Sobrien   (clobber (match_scratch:SI 5 "=q"))]
949390075Sobrien  "TARGET_STRING && TARGET_POWER
949490075Sobrien   && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4"
949590075Sobrien  "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
9496169689Skan  [(set_attr "type" "store_ux")
949790075Sobrien   (set_attr "length" "8")])
949890075Sobrien
949990075Sobrien(define_insn ""
9500169689Skan  [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9501169689Skan	(mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
950290075Sobrien   (use (match_operand:SI 2 "immediate_operand" "i"))
950390075Sobrien   (use (match_operand:SI 3 "immediate_operand" "i"))
950490075Sobrien   (clobber (match_scratch:SI 4 "=&r"))
9505169689Skan   (clobber (match_scratch:SI 5 "=X"))]
950690075Sobrien  "TARGET_STRING && ! TARGET_POWER
950790075Sobrien   && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4"
950890075Sobrien  "{lsi|lswi} %4,%1,%2\;{stsi|stswi} %4,%0,%2"
9509169689Skan  [(set_attr "type" "store_ux")
951090075Sobrien   (set_attr "length" "8")])
951190075Sobrien
951290075Sobrien;; Define insns that do load or store with update.  Some of these we can
951390075Sobrien;; get by using pre-decrement or pre-increment, but the hardware can also
951490075Sobrien;; do cases where the increment is not the size of the object.
951590075Sobrien;;
951690075Sobrien;; In all these cases, we use operands 0 and 1 for the register being
951790075Sobrien;; incremented because those are the operands that local-alloc will
951890075Sobrien;; tie and these are the pair most likely to be tieable (and the ones
951990075Sobrien;; that will benefit the most).
952090075Sobrien
952190075Sobrien(define_insn "*movdi_update1"
952290075Sobrien  [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
952390075Sobrien	(mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
952496263Sobrien			 (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I"))))
952590075Sobrien   (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
952690075Sobrien	(plus:DI (match_dup 1) (match_dup 2)))]
952790075Sobrien  "TARGET_POWERPC64 && TARGET_UPDATE"
952890075Sobrien  "@
952990075Sobrien   ldux %3,%0,%2
953090075Sobrien   ldu %3,%2(%0)"
9531132718Skan  [(set_attr "type" "load_ux,load_u")])
953290075Sobrien
9533169689Skan(define_insn "movdi_<mode>_update"
9534169689Skan  [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9535169689Skan			 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
953690075Sobrien	(match_operand:DI 3 "gpc_reg_operand" "r,r"))
9537169689Skan   (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9538169689Skan	(plus:P (match_dup 1) (match_dup 2)))]
953990075Sobrien  "TARGET_POWERPC64 && TARGET_UPDATE"
954090075Sobrien  "@
954190075Sobrien   stdux %3,%0,%2
954290075Sobrien   stdu %3,%2(%0)"
9543132718Skan  [(set_attr "type" "store_ux,store_u")])
954490075Sobrien
954590075Sobrien(define_insn "*movsi_update1"
954690075Sobrien  [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
954790075Sobrien	(mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
954890075Sobrien			 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
954990075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
955090075Sobrien	(plus:SI (match_dup 1) (match_dup 2)))]
9551132718Skan  "TARGET_UPDATE"
955290075Sobrien  "@
955390075Sobrien   {lux|lwzux} %3,%0,%2
955490075Sobrien   {lu|lwzu} %3,%2(%0)"
9555132718Skan  [(set_attr "type" "load_ux,load_u")])
955690075Sobrien
9557132718Skan(define_insn "*movsi_update2"
9558132718Skan  [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
9559132718Skan	(sign_extend:DI
9560132718Skan	 (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
9561132718Skan			  (match_operand:DI 2 "gpc_reg_operand" "r")))))
9562132718Skan   (set (match_operand:DI 0 "gpc_reg_operand" "=b")
9563132718Skan	(plus:DI (match_dup 1) (match_dup 2)))]
9564132718Skan  "TARGET_POWERPC64"
9565132718Skan  "lwaux %3,%0,%2"
9566132718Skan  [(set_attr "type" "load_ext_ux")])
9567132718Skan
956890075Sobrien(define_insn "movsi_update"
956990075Sobrien  [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
957090075Sobrien			 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
957190075Sobrien	(match_operand:SI 3 "gpc_reg_operand" "r,r"))
957290075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
957390075Sobrien	(plus:SI (match_dup 1) (match_dup 2)))]
957490075Sobrien  "TARGET_UPDATE"
957590075Sobrien  "@
957690075Sobrien   {stux|stwux} %3,%0,%2
957790075Sobrien   {stu|stwu} %3,%2(%0)"
9578132718Skan  [(set_attr "type" "store_ux,store_u")])
957990075Sobrien
9580132718Skan(define_insn "*movhi_update1"
958190075Sobrien  [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
958290075Sobrien	(mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
958390075Sobrien			 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
958490075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
958590075Sobrien	(plus:SI (match_dup 1) (match_dup 2)))]
958690075Sobrien  "TARGET_UPDATE"
958790075Sobrien  "@
958890075Sobrien   lhzux %3,%0,%2
958990075Sobrien   lhzu %3,%2(%0)"
9590132718Skan  [(set_attr "type" "load_ux,load_u")])
959190075Sobrien
959290075Sobrien(define_insn "*movhi_update2"
959390075Sobrien  [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
959490075Sobrien	(zero_extend:SI
959590075Sobrien	 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
959690075Sobrien			  (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
959790075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
959890075Sobrien	(plus:SI (match_dup 1) (match_dup 2)))]
959990075Sobrien  "TARGET_UPDATE"
960090075Sobrien  "@
960190075Sobrien   lhzux %3,%0,%2
960290075Sobrien   lhzu %3,%2(%0)"
9603132718Skan  [(set_attr "type" "load_ux,load_u")])
960490075Sobrien
960590075Sobrien(define_insn "*movhi_update3"
960690075Sobrien  [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
960790075Sobrien	(sign_extend:SI
960890075Sobrien	 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
960990075Sobrien			  (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
961090075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
961190075Sobrien	(plus:SI (match_dup 1) (match_dup 2)))]
961290075Sobrien  "TARGET_UPDATE"
961390075Sobrien  "@
961490075Sobrien   lhaux %3,%0,%2
961590075Sobrien   lhau %3,%2(%0)"
9616132718Skan  [(set_attr "type" "load_ext_ux,load_ext_u")])
961790075Sobrien
961890075Sobrien(define_insn "*movhi_update4"
961990075Sobrien  [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
962090075Sobrien			 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
962190075Sobrien	(match_operand:HI 3 "gpc_reg_operand" "r,r"))
962290075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
962390075Sobrien	(plus:SI (match_dup 1) (match_dup 2)))]
962490075Sobrien  "TARGET_UPDATE"
962590075Sobrien  "@
962690075Sobrien   sthux %3,%0,%2
962790075Sobrien   sthu %3,%2(%0)"
9628132718Skan  [(set_attr "type" "store_ux,store_u")])
962990075Sobrien
963090075Sobrien(define_insn "*movqi_update1"
963190075Sobrien  [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
963290075Sobrien	(mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
963390075Sobrien			 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
963490075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
963590075Sobrien	(plus:SI (match_dup 1) (match_dup 2)))]
963690075Sobrien  "TARGET_UPDATE"
963790075Sobrien  "@
963890075Sobrien   lbzux %3,%0,%2
963990075Sobrien   lbzu %3,%2(%0)"
9640132718Skan  [(set_attr "type" "load_ux,load_u")])
964190075Sobrien
964290075Sobrien(define_insn "*movqi_update2"
964390075Sobrien  [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
964490075Sobrien	(zero_extend:SI
964590075Sobrien	 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
964690075Sobrien			  (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
964790075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
964890075Sobrien	(plus:SI (match_dup 1) (match_dup 2)))]
964990075Sobrien  "TARGET_UPDATE"
965090075Sobrien  "@
965190075Sobrien   lbzux %3,%0,%2
965290075Sobrien   lbzu %3,%2(%0)"
9653132718Skan  [(set_attr "type" "load_ux,load_u")])
965490075Sobrien
965590075Sobrien(define_insn "*movqi_update3"
965690075Sobrien  [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
965790075Sobrien			 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
965890075Sobrien	(match_operand:QI 3 "gpc_reg_operand" "r,r"))
965990075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
966090075Sobrien	(plus:SI (match_dup 1) (match_dup 2)))]
966190075Sobrien  "TARGET_UPDATE"
966290075Sobrien  "@
966390075Sobrien   stbux %3,%0,%2
966490075Sobrien   stbu %3,%2(%0)"
9665132718Skan  [(set_attr "type" "store_ux,store_u")])
966690075Sobrien
966790075Sobrien(define_insn "*movsf_update1"
966890075Sobrien  [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
966990075Sobrien	(mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
967090075Sobrien			 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
967190075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
967290075Sobrien	(plus:SI (match_dup 1) (match_dup 2)))]
9673117395Skan  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_UPDATE"
967490075Sobrien  "@
967590075Sobrien   lfsux %3,%0,%2
967690075Sobrien   lfsu %3,%2(%0)"
9677132718Skan  [(set_attr "type" "fpload_ux,fpload_u")])
967890075Sobrien
967990075Sobrien(define_insn "*movsf_update2"
968090075Sobrien  [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
968190075Sobrien			 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
968290075Sobrien	(match_operand:SF 3 "gpc_reg_operand" "f,f"))
968390075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
968490075Sobrien	(plus:SI (match_dup 1) (match_dup 2)))]
9685117395Skan  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_UPDATE"
968690075Sobrien  "@
968790075Sobrien   stfsux %3,%0,%2
968890075Sobrien   stfsu %3,%2(%0)"
9689132718Skan  [(set_attr "type" "fpstore_ux,fpstore_u")])
969090075Sobrien
969190075Sobrien(define_insn "*movsf_update3"
969290075Sobrien  [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
969390075Sobrien	(mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
969490075Sobrien			 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
969590075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
969690075Sobrien	(plus:SI (match_dup 1) (match_dup 2)))]
9697117395Skan  "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE"
969890075Sobrien  "@
969990075Sobrien   {lux|lwzux} %3,%0,%2
970090075Sobrien   {lu|lwzu} %3,%2(%0)"
9701132718Skan  [(set_attr "type" "load_ux,load_u")])
970290075Sobrien
970390075Sobrien(define_insn "*movsf_update4"
970490075Sobrien  [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
970590075Sobrien			 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
970690075Sobrien	(match_operand:SF 3 "gpc_reg_operand" "r,r"))
970790075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
970890075Sobrien	(plus:SI (match_dup 1) (match_dup 2)))]
9709117395Skan  "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE"
971090075Sobrien  "@
971190075Sobrien   {stux|stwux} %3,%0,%2
971290075Sobrien   {stu|stwu} %3,%2(%0)"
9713132718Skan  [(set_attr "type" "store_ux,store_u")])
971490075Sobrien
971590075Sobrien(define_insn "*movdf_update1"
971690075Sobrien  [(set (match_operand:DF 3 "gpc_reg_operand" "=f,f")
971790075Sobrien	(mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
971890075Sobrien			 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
971990075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
972090075Sobrien	(plus:SI (match_dup 1) (match_dup 2)))]
9721117395Skan  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_UPDATE"
972290075Sobrien  "@
972390075Sobrien   lfdux %3,%0,%2
972490075Sobrien   lfdu %3,%2(%0)"
9725132718Skan  [(set_attr "type" "fpload_ux,fpload_u")])
972690075Sobrien
972790075Sobrien(define_insn "*movdf_update2"
972890075Sobrien  [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
972990075Sobrien			 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
973090075Sobrien	(match_operand:DF 3 "gpc_reg_operand" "f,f"))
973190075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
973290075Sobrien	(plus:SI (match_dup 1) (match_dup 2)))]
9733117395Skan  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_UPDATE"
973490075Sobrien  "@
973590075Sobrien   stfdux %3,%0,%2
973690075Sobrien   stfdu %3,%2(%0)"
9737132718Skan  [(set_attr "type" "fpstore_ux,fpstore_u")])
973890075Sobrien
973990075Sobrien;; Peephole to convert two consecutive FP loads or stores into lfq/stfq.
974090075Sobrien
9741169689Skan(define_insn "*lfq_power2"
9742169689Skan  [(set (match_operand:V2DF 0 "gpc_reg_operand" "=f")
9743169689Skan	(match_operand:V2DF 1 "memory_operand" ""))]
9744169689Skan  "TARGET_POWER2
9745169689Skan   && TARGET_HARD_FLOAT && TARGET_FPRS"
9746169689Skan  "lfq%U1%X1 %0,%1")
9747169689Skan
9748169689Skan(define_peephole2
9749169689Skan  [(set (match_operand:DF 0 "gpc_reg_operand" "")
975090075Sobrien	(match_operand:DF 1 "memory_operand" ""))
9751169689Skan   (set (match_operand:DF 2 "gpc_reg_operand" "")
975290075Sobrien	(match_operand:DF 3 "memory_operand" ""))]
975390075Sobrien  "TARGET_POWER2
9754117395Skan   && TARGET_HARD_FLOAT && TARGET_FPRS
975590075Sobrien   && registers_ok_for_quad_peep (operands[0], operands[2])
9756169689Skan   && mems_ok_for_quad_peep (operands[1], operands[3])"
9757169689Skan  [(set (match_dup 0)
9758169689Skan	(match_dup 1))]
9759169689Skan  "operands[1] = widen_memory_access (operands[1], V2DFmode, 0);
9760169689Skan   operands[0] = gen_rtx_REG (V2DFmode, REGNO (operands[0]));")
976190075Sobrien
9762169689Skan(define_insn "*stfq_power2"
9763169689Skan  [(set (match_operand:V2DF 0 "memory_operand" "")
9764169689Skan	(match_operand:V2DF 1 "gpc_reg_operand" "f"))]
9765169689Skan  "TARGET_POWER2
9766169689Skan   && TARGET_HARD_FLOAT && TARGET_FPRS"
9767169689Skan  "stfq%U0%X0 %1,%0")
9768169689Skan
9769169689Skan
9770169689Skan(define_peephole2
977190075Sobrien  [(set (match_operand:DF 0 "memory_operand" "")
9772169689Skan	(match_operand:DF 1 "gpc_reg_operand" ""))
977390075Sobrien   (set (match_operand:DF 2 "memory_operand" "")
9774169689Skan	(match_operand:DF 3 "gpc_reg_operand" ""))]
977590075Sobrien  "TARGET_POWER2
9776117395Skan   && TARGET_HARD_FLOAT && TARGET_FPRS
977790075Sobrien   && registers_ok_for_quad_peep (operands[1], operands[3])
9778169689Skan   && mems_ok_for_quad_peep (operands[0], operands[2])"
9779169689Skan  [(set (match_dup 0)
9780169689Skan	(match_dup 1))]
9781169689Skan  "operands[0] = widen_memory_access (operands[0], V2DFmode, 0);
9782169689Skan   operands[1] = gen_rtx_REG (V2DFmode, REGNO (operands[1]));")
9783169689Skan
9784169689Skan;; After inserting conditional returns we can sometimes have
9785169689Skan;; unnecessary register moves.  Unfortunately we cannot have a
9786169689Skan;; modeless peephole here, because some single SImode sets have early
9787169689Skan;; clobber outputs.  Although those sets expand to multi-ppc-insn
9788169689Skan;; sequences, using get_attr_length here will smash the operands
9789169689Skan;; array.  Neither is there an early_cobbler_p predicate.
9790169689Skan;; Disallow subregs for E500 so we don't munge frob_di_df_2.
9791169689Skan(define_peephole2
9792169689Skan  [(set (match_operand:DF 0 "gpc_reg_operand" "")
9793169689Skan	(match_operand:DF 1 "any_operand" ""))
9794169689Skan   (set (match_operand:DF 2 "gpc_reg_operand" "")
9795169689Skan	(match_dup 0))]
9796169689Skan  "!(TARGET_E500_DOUBLE && GET_CODE (operands[2]) == SUBREG)
9797169689Skan   && peep2_reg_dead_p (2, operands[0])"
9798169689Skan  [(set (match_dup 2) (match_dup 1))])
9799169689Skan
9800169689Skan(define_peephole2
9801169689Skan  [(set (match_operand:SF 0 "gpc_reg_operand" "")
9802169689Skan	(match_operand:SF 1 "any_operand" ""))
9803169689Skan   (set (match_operand:SF 2 "gpc_reg_operand" "")
9804169689Skan	(match_dup 0))]
9805169689Skan  "peep2_reg_dead_p (2, operands[0])"
9806169689Skan  [(set (match_dup 2) (match_dup 1))])
9807169689Skan
980890075Sobrien
9809132718Skan;; TLS support.
9810132718Skan
9811132718Skan;; "b" output constraint here and on tls_ld to support tls linker optimization.
9812132718Skan(define_insn "tls_gd_32"
9813169689Skan  [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
9814169689Skan	(unspec:SI [(match_operand:SI 1 "gpc_reg_operand" "b")
9815132718Skan		    (match_operand:SI 2 "rs6000_tls_symbol_ref" "")]
9816132718Skan		   UNSPEC_TLSGD))]
9817132718Skan  "HAVE_AS_TLS && !TARGET_64BIT"
9818132718Skan  "addi %0,%1,%2@got@tlsgd")
9819132718Skan
9820132718Skan(define_insn "tls_gd_64"
9821169689Skan  [(set (match_operand:DI 0 "gpc_reg_operand" "=b")
9822169689Skan	(unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "b")
9823132718Skan		    (match_operand:DI 2 "rs6000_tls_symbol_ref" "")]
9824132718Skan		   UNSPEC_TLSGD))]
9825132718Skan  "HAVE_AS_TLS && TARGET_64BIT"
9826132718Skan  "addi %0,%1,%2@got@tlsgd")
9827132718Skan
9828132718Skan(define_insn "tls_ld_32"
9829169689Skan  [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
9830169689Skan	(unspec:SI [(match_operand:SI 1 "gpc_reg_operand" "b")]
9831132718Skan		   UNSPEC_TLSLD))]
9832132718Skan  "HAVE_AS_TLS && !TARGET_64BIT"
9833132718Skan  "addi %0,%1,%&@got@tlsld")
9834132718Skan
9835132718Skan(define_insn "tls_ld_64"
9836169689Skan  [(set (match_operand:DI 0 "gpc_reg_operand" "=b")
9837169689Skan	(unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "b")]
9838132718Skan		   UNSPEC_TLSLD))]
9839132718Skan  "HAVE_AS_TLS && TARGET_64BIT"
9840132718Skan  "addi %0,%1,%&@got@tlsld")
9841132718Skan
9842132718Skan(define_insn "tls_dtprel_32"
9843169689Skan  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9844169689Skan	(unspec:SI [(match_operand:SI 1 "gpc_reg_operand" "b")
9845132718Skan		    (match_operand:SI 2 "rs6000_tls_symbol_ref" "")]
9846132718Skan		   UNSPEC_TLSDTPREL))]
9847132718Skan  "HAVE_AS_TLS && !TARGET_64BIT"
9848132718Skan  "addi %0,%1,%2@dtprel")
9849132718Skan
9850132718Skan(define_insn "tls_dtprel_64"
9851169689Skan  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
9852169689Skan	(unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "b")
9853132718Skan		    (match_operand:DI 2 "rs6000_tls_symbol_ref" "")]
9854132718Skan		   UNSPEC_TLSDTPREL))]
9855132718Skan  "HAVE_AS_TLS && TARGET_64BIT"
9856132718Skan  "addi %0,%1,%2@dtprel")
9857132718Skan
9858132718Skan(define_insn "tls_dtprel_ha_32"
9859169689Skan  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9860169689Skan	(unspec:SI [(match_operand:SI 1 "gpc_reg_operand" "b")
9861132718Skan		    (match_operand:SI 2 "rs6000_tls_symbol_ref" "")]
9862132718Skan		   UNSPEC_TLSDTPRELHA))]
9863132718Skan  "HAVE_AS_TLS && !TARGET_64BIT"
9864132718Skan  "addis %0,%1,%2@dtprel@ha")
9865132718Skan
9866132718Skan(define_insn "tls_dtprel_ha_64"
9867169689Skan  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
9868169689Skan	(unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "b")
9869132718Skan		    (match_operand:DI 2 "rs6000_tls_symbol_ref" "")]
9870132718Skan		   UNSPEC_TLSDTPRELHA))]
9871132718Skan  "HAVE_AS_TLS && TARGET_64BIT"
9872132718Skan  "addis %0,%1,%2@dtprel@ha")
9873132718Skan
9874132718Skan(define_insn "tls_dtprel_lo_32"
9875169689Skan  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9876169689Skan	(unspec:SI [(match_operand:SI 1 "gpc_reg_operand" "b")
9877132718Skan		    (match_operand:SI 2 "rs6000_tls_symbol_ref" "")]
9878132718Skan		   UNSPEC_TLSDTPRELLO))]
9879132718Skan  "HAVE_AS_TLS && !TARGET_64BIT"
9880132718Skan  "addi %0,%1,%2@dtprel@l")
9881132718Skan
9882132718Skan(define_insn "tls_dtprel_lo_64"
9883169689Skan  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
9884169689Skan	(unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "b")
9885132718Skan		    (match_operand:DI 2 "rs6000_tls_symbol_ref" "")]
9886132718Skan		   UNSPEC_TLSDTPRELLO))]
9887132718Skan  "HAVE_AS_TLS && TARGET_64BIT"
9888132718Skan  "addi %0,%1,%2@dtprel@l")
9889132718Skan
9890132718Skan(define_insn "tls_got_dtprel_32"
9891169689Skan  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9892169689Skan	(unspec:SI [(match_operand:SI 1 "gpc_reg_operand" "b")
9893132718Skan		    (match_operand:SI 2 "rs6000_tls_symbol_ref" "")]
9894132718Skan		   UNSPEC_TLSGOTDTPREL))]
9895132718Skan  "HAVE_AS_TLS && !TARGET_64BIT"
9896132718Skan  "lwz %0,%2@got@dtprel(%1)")
9897132718Skan
9898132718Skan(define_insn "tls_got_dtprel_64"
9899169689Skan  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
9900169689Skan	(unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "b")
9901132718Skan		    (match_operand:DI 2 "rs6000_tls_symbol_ref" "")]
9902132718Skan		   UNSPEC_TLSGOTDTPREL))]
9903132718Skan  "HAVE_AS_TLS && TARGET_64BIT"
9904132718Skan  "ld %0,%2@got@dtprel(%1)")
9905132718Skan
9906132718Skan(define_insn "tls_tprel_32"
9907169689Skan  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9908169689Skan	(unspec:SI [(match_operand:SI 1 "gpc_reg_operand" "b")
9909132718Skan		    (match_operand:SI 2 "rs6000_tls_symbol_ref" "")]
9910132718Skan		   UNSPEC_TLSTPREL))]
9911132718Skan  "HAVE_AS_TLS && !TARGET_64BIT"
9912132718Skan  "addi %0,%1,%2@tprel")
9913132718Skan
9914132718Skan(define_insn "tls_tprel_64"
9915169689Skan  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
9916169689Skan	(unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "b")
9917132718Skan		    (match_operand:DI 2 "rs6000_tls_symbol_ref" "")]
9918132718Skan		   UNSPEC_TLSTPREL))]
9919132718Skan  "HAVE_AS_TLS && TARGET_64BIT"
9920132718Skan  "addi %0,%1,%2@tprel")
9921132718Skan
9922132718Skan(define_insn "tls_tprel_ha_32"
9923169689Skan  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9924169689Skan	(unspec:SI [(match_operand:SI 1 "gpc_reg_operand" "b")
9925132718Skan		    (match_operand:SI 2 "rs6000_tls_symbol_ref" "")]
9926132718Skan		   UNSPEC_TLSTPRELHA))]
9927132718Skan  "HAVE_AS_TLS && !TARGET_64BIT"
9928132718Skan  "addis %0,%1,%2@tprel@ha")
9929132718Skan
9930132718Skan(define_insn "tls_tprel_ha_64"
9931169689Skan  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
9932169689Skan	(unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "b")
9933132718Skan		    (match_operand:DI 2 "rs6000_tls_symbol_ref" "")]
9934132718Skan		   UNSPEC_TLSTPRELHA))]
9935132718Skan  "HAVE_AS_TLS && TARGET_64BIT"
9936132718Skan  "addis %0,%1,%2@tprel@ha")
9937132718Skan
9938132718Skan(define_insn "tls_tprel_lo_32"
9939169689Skan  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9940169689Skan	(unspec:SI [(match_operand:SI 1 "gpc_reg_operand" "b")
9941132718Skan		    (match_operand:SI 2 "rs6000_tls_symbol_ref" "")]
9942132718Skan		   UNSPEC_TLSTPRELLO))]
9943132718Skan  "HAVE_AS_TLS && !TARGET_64BIT"
9944132718Skan  "addi %0,%1,%2@tprel@l")
9945132718Skan
9946132718Skan(define_insn "tls_tprel_lo_64"
9947169689Skan  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
9948169689Skan	(unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "b")
9949132718Skan		    (match_operand:DI 2 "rs6000_tls_symbol_ref" "")]
9950132718Skan		   UNSPEC_TLSTPRELLO))]
9951132718Skan  "HAVE_AS_TLS && TARGET_64BIT"
9952132718Skan  "addi %0,%1,%2@tprel@l")
9953132718Skan
9954132718Skan;; "b" output constraint here and on tls_tls input to support linker tls
9955132718Skan;; optimization.  The linker may edit the instructions emitted by a
9956132718Skan;; tls_got_tprel/tls_tls pair to addis,addi.
9957132718Skan(define_insn "tls_got_tprel_32"
9958169689Skan  [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
9959169689Skan	(unspec:SI [(match_operand:SI 1 "gpc_reg_operand" "b")
9960132718Skan		    (match_operand:SI 2 "rs6000_tls_symbol_ref" "")]
9961132718Skan		   UNSPEC_TLSGOTTPREL))]
9962132718Skan  "HAVE_AS_TLS && !TARGET_64BIT"
9963132718Skan  "lwz %0,%2@got@tprel(%1)")
9964132718Skan
9965132718Skan(define_insn "tls_got_tprel_64"
9966169689Skan  [(set (match_operand:DI 0 "gpc_reg_operand" "=b")
9967169689Skan	(unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "b")
9968132718Skan		    (match_operand:DI 2 "rs6000_tls_symbol_ref" "")]
9969132718Skan		   UNSPEC_TLSGOTTPREL))]
9970132718Skan  "HAVE_AS_TLS && TARGET_64BIT"
9971132718Skan  "ld %0,%2@got@tprel(%1)")
9972132718Skan
9973132718Skan(define_insn "tls_tls_32"
9974169689Skan  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9975169689Skan	(unspec:SI [(match_operand:SI 1 "gpc_reg_operand" "b")
9976132718Skan		    (match_operand:SI 2 "rs6000_tls_symbol_ref" "")]
9977132718Skan		   UNSPEC_TLSTLS))]
9978132718Skan  "HAVE_AS_TLS && !TARGET_64BIT"
9979132718Skan  "add %0,%1,%2@tls")
9980132718Skan
9981132718Skan(define_insn "tls_tls_64"
9982169689Skan  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
9983169689Skan	(unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "b")
9984132718Skan		    (match_operand:DI 2 "rs6000_tls_symbol_ref" "")]
9985132718Skan		   UNSPEC_TLSTLS))]
9986132718Skan  "HAVE_AS_TLS && TARGET_64BIT"
9987132718Skan  "add %0,%1,%2@tls")
9988132718Skan
998990075Sobrien;; Next come insns related to the calling sequence.
999090075Sobrien;;
999190075Sobrien;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
999290075Sobrien;; We move the back-chain and decrement the stack pointer.
999390075Sobrien
999490075Sobrien(define_expand "allocate_stack"
999590075Sobrien  [(set (match_operand 0 "gpc_reg_operand" "=r")
999690075Sobrien	(minus (reg 1) (match_operand 1 "reg_or_short_operand" "")))
999790075Sobrien   (set (reg 1)
999890075Sobrien	(minus (reg 1) (match_dup 1)))]
999990075Sobrien  ""
1000090075Sobrien  "
1000190075Sobrien{ rtx chain = gen_reg_rtx (Pmode);
1000290075Sobrien  rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
1000390075Sobrien  rtx neg_op0;
1000490075Sobrien
1000590075Sobrien  emit_move_insn (chain, stack_bot);
1000690075Sobrien
1000790075Sobrien  /* Check stack bounds if necessary.  */
1000890075Sobrien  if (current_function_limit_stack)
1000990075Sobrien    {
1001090075Sobrien      rtx available;
10011169689Skan      available = expand_binop (Pmode, sub_optab,
1001290075Sobrien				stack_pointer_rtx, stack_limit_rtx,
1001390075Sobrien				NULL_RTX, 1, OPTAB_WIDEN);
1001490075Sobrien      emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
1001590075Sobrien    }
1001690075Sobrien
1001790075Sobrien  if (GET_CODE (operands[1]) != CONST_INT
1001890075Sobrien      || INTVAL (operands[1]) < -32767
1001990075Sobrien      || INTVAL (operands[1]) > 32768)
1002090075Sobrien    {
1002190075Sobrien      neg_op0 = gen_reg_rtx (Pmode);
1002290075Sobrien      if (TARGET_32BIT)
1002390075Sobrien	emit_insn (gen_negsi2 (neg_op0, operands[1]));
1002490075Sobrien      else
1002590075Sobrien	emit_insn (gen_negdi2 (neg_op0, operands[1]));
1002690075Sobrien    }
1002790075Sobrien  else
1002890075Sobrien    neg_op0 = GEN_INT (- INTVAL (operands[1]));
1002990075Sobrien
1003090075Sobrien  if (TARGET_UPDATE)
10031169689Skan    emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update : gen_movdi_di_update))
1003290075Sobrien		(stack_pointer_rtx, stack_pointer_rtx, neg_op0, chain));
1003390075Sobrien
1003490075Sobrien  else
1003590075Sobrien    {
1003690075Sobrien      emit_insn ((* ((TARGET_32BIT) ? gen_addsi3 : gen_adddi3))
1003790075Sobrien		 (stack_pointer_rtx, stack_pointer_rtx, neg_op0));
1003890075Sobrien      emit_move_insn (gen_rtx_MEM (Pmode, stack_pointer_rtx), chain);
1003990075Sobrien    }
1004090075Sobrien
1004190075Sobrien  emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
1004290075Sobrien  DONE;
1004390075Sobrien}")
1004490075Sobrien
1004590075Sobrien;; These patterns say how to save and restore the stack pointer.  We need not
1004690075Sobrien;; save the stack pointer at function level since we are careful to
1004790075Sobrien;; preserve the backchain.  At block level, we have to restore the backchain
1004890075Sobrien;; when we restore the stack pointer.
1004990075Sobrien;;
1005090075Sobrien;; For nonlocal gotos, we must save both the stack pointer and its
1005190075Sobrien;; backchain and restore both.  Note that in the nonlocal case, the
1005290075Sobrien;; save area is a memory location.
1005390075Sobrien
1005490075Sobrien(define_expand "save_stack_function"
1005590075Sobrien  [(match_operand 0 "any_operand" "")
1005690075Sobrien   (match_operand 1 "any_operand" "")]
1005790075Sobrien  ""
1005890075Sobrien  "DONE;")
1005990075Sobrien
1006090075Sobrien(define_expand "restore_stack_function"
1006190075Sobrien  [(match_operand 0 "any_operand" "")
1006290075Sobrien   (match_operand 1 "any_operand" "")]
1006390075Sobrien  ""
1006490075Sobrien  "DONE;")
1006590075Sobrien
10066169689Skan;; Adjust stack pointer (op0) to a new value (op1).
10067169689Skan;; First copy old stack backchain to new location, and ensure that the
10068169689Skan;; scheduler won't reorder the sp assignment before the backchain write.
1006990075Sobrien(define_expand "restore_stack_block"
10070169689Skan  [(set (match_dup 2) (match_dup 3))
10071169689Skan   (set (match_dup 4) (match_dup 2))
10072169689Skan   (set (match_dup 5) (unspec:BLK [(match_dup 5)] UNSPEC_TIE))
10073169689Skan   (set (match_operand 0 "register_operand" "")
10074169689Skan	(match_operand 1 "register_operand" ""))]
1007590075Sobrien  ""
1007690075Sobrien  "
1007790075Sobrien{
10078235623Spfg  operands[1] = force_reg (Pmode, operands[1]);
1007990075Sobrien  operands[2] = gen_reg_rtx (Pmode);
10080169689Skan  operands[3] = gen_frame_mem (Pmode, operands[0]);
10081169689Skan  operands[4] = gen_frame_mem (Pmode, operands[1]);
10082169689Skan  operands[5] = gen_frame_mem (BLKmode, operands[0]);
1008390075Sobrien}")
1008490075Sobrien
1008590075Sobrien(define_expand "save_stack_nonlocal"
10086169689Skan  [(set (match_dup 3) (match_dup 4))
10087169689Skan   (set (match_operand 0 "memory_operand" "") (match_dup 3))
10088169689Skan   (set (match_dup 2) (match_operand 1 "register_operand" ""))]
1008990075Sobrien  ""
1009090075Sobrien  "
1009190075Sobrien{
10092169689Skan  int units_per_word = (TARGET_32BIT) ? 4 : 8;
1009390075Sobrien
1009490075Sobrien  /* Copy the backchain to the first word, sp to the second.  */
10095169689Skan  operands[0] = adjust_address_nv (operands[0], Pmode, 0);
10096169689Skan  operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
10097169689Skan  operands[3] = gen_reg_rtx (Pmode);
10098169689Skan  operands[4] = gen_frame_mem (Pmode, operands[1]);
1009990075Sobrien}")
1010090075Sobrien
1010190075Sobrien(define_expand "restore_stack_nonlocal"
10102169689Skan  [(set (match_dup 2) (match_operand 1 "memory_operand" ""))
10103169689Skan   (set (match_dup 3) (match_dup 4))
10104169689Skan   (set (match_dup 5) (match_dup 2))
10105169689Skan   (set (match_dup 6) (unspec:BLK [(match_dup 6)] UNSPEC_TIE))
10106169689Skan   (set (match_operand 0 "register_operand" "") (match_dup 3))]
1010790075Sobrien  ""
1010890075Sobrien  "
1010990075Sobrien{
10110169689Skan  int units_per_word = (TARGET_32BIT) ? 4 : 8;
1011190075Sobrien
1011290075Sobrien  /* Restore the backchain from the first word, sp from the second.  */
10113169689Skan  operands[2] = gen_reg_rtx (Pmode);
10114169689Skan  operands[3] = gen_reg_rtx (Pmode);
10115169689Skan  operands[1] = adjust_address_nv (operands[1], Pmode, 0);
10116169689Skan  operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
10117169689Skan  operands[5] = gen_frame_mem (Pmode, operands[3]);
10118169689Skan  operands[6] = gen_frame_mem (BLKmode, operands[0]);
1011990075Sobrien}")
1012090075Sobrien
1012190075Sobrien;; TOC register handling.
1012290075Sobrien
1012390075Sobrien;; Code to initialize the TOC register...
1012490075Sobrien
1012590075Sobrien(define_insn "load_toc_aix_si"
1012696263Sobrien  [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10127132718Skan		   (unspec:SI [(const_int 0)] UNSPEC_TOC))
1012890075Sobrien	      (use (reg:SI 2))])]
1012990075Sobrien  "DEFAULT_ABI == ABI_AIX && TARGET_32BIT"
1013090075Sobrien  "*
1013190075Sobrien{
1013290075Sobrien  char buf[30];
1013390075Sobrien  ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1);
1013490075Sobrien  operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
1013590075Sobrien  operands[2] = gen_rtx_REG (Pmode, 2);
1013690075Sobrien  return \"{l|lwz} %0,%1(%2)\";
1013790075Sobrien}"
1013890075Sobrien  [(set_attr "type" "load")])
1013990075Sobrien
1014090075Sobrien(define_insn "load_toc_aix_di"
1014196263Sobrien  [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10142132718Skan		   (unspec:DI [(const_int 0)] UNSPEC_TOC))
1014390075Sobrien	      (use (reg:DI 2))])]
1014490075Sobrien  "DEFAULT_ABI == ABI_AIX && TARGET_64BIT"
1014590075Sobrien  "*
1014690075Sobrien{
1014790075Sobrien  char buf[30];
1014896263Sobrien#ifdef TARGET_RELOCATABLE
1014996263Sobrien  ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\",
1015096263Sobrien			       !TARGET_MINIMAL_TOC || TARGET_RELOCATABLE);
1015196263Sobrien#else
1015290075Sobrien  ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1);
1015396263Sobrien#endif
1015490075Sobrien  if (TARGET_ELF)
1015590075Sobrien    strcat (buf, \"@toc\");
1015690075Sobrien  operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
1015790075Sobrien  operands[2] = gen_rtx_REG (Pmode, 2);
1015890075Sobrien  return \"ld %0,%1(%2)\";
1015990075Sobrien}"
1016090075Sobrien  [(set_attr "type" "load")])
1016190075Sobrien
1016290075Sobrien(define_insn "load_toc_v4_pic_si"
1016390075Sobrien  [(set (match_operand:SI 0 "register_operand" "=l")
10164132718Skan	(unspec:SI [(const_int 0)] UNSPEC_TOC))]
1016590075Sobrien  "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
1016690075Sobrien  "bl _GLOBAL_OFFSET_TABLE_@local-4"
1016790075Sobrien  [(set_attr "type" "branch")
1016890075Sobrien   (set_attr "length" "4")])
1016990075Sobrien
1017090075Sobrien(define_insn "load_toc_v4_PIC_1"
1017190075Sobrien  [(set (match_operand:SI 0 "register_operand" "=l")
1017290075Sobrien	(match_operand:SI 1 "immediate_operand" "s"))
10173132718Skan   (use (unspec [(match_dup 1)] UNSPEC_TOC))]
10174169689Skan  "TARGET_ELF && DEFAULT_ABI != ABI_AIX
10175169689Skan   && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10176117395Skan  "bcl 20,31,%1\\n%1:"
1017790075Sobrien  [(set_attr "type" "branch")
1017890075Sobrien   (set_attr "length" "4")])
1017990075Sobrien
1018090075Sobrien(define_insn "load_toc_v4_PIC_1b"
1018190075Sobrien  [(set (match_operand:SI 0 "register_operand" "=l")
10182146895Skan	(unspec:SI [(match_operand:SI 1 "immediate_operand" "s")]
10183132718Skan		UNSPEC_TOCPTR))]
10184103445Skan  "TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2"
10185146895Skan  "bcl 20,31,$+8\\n\\t.long %1-$"
1018690075Sobrien  [(set_attr "type" "branch")
1018790075Sobrien   (set_attr "length" "8")])
1018890075Sobrien
1018990075Sobrien(define_insn "load_toc_v4_PIC_2"
10190117395Skan  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10191117395Skan	(mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1019290075Sobrien		   (minus:SI (match_operand:SI 2 "immediate_operand" "s")
1019390075Sobrien			     (match_operand:SI 3 "immediate_operand" "s")))))]
10194103445Skan  "TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2"
1019590075Sobrien  "{l|lwz} %0,%2-%3(%1)"
1019690075Sobrien  [(set_attr "type" "load")])
1019790075Sobrien
10198169689Skan(define_insn "load_toc_v4_PIC_3b"
10199169689Skan  [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
10200169689Skan	(plus:SI (match_operand:SI 1 "gpc_reg_operand" "r")
10201169689Skan		 (high:SI
10202169689Skan		   (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10203169689Skan			     (match_operand:SI 3 "symbol_ref_operand" "s")))))]
10204169689Skan  "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic"
10205169689Skan  "{cau|addis} %0,%1,%2-%3@ha")
1020690075Sobrien
10207169689Skan(define_insn "load_toc_v4_PIC_3c"
10208117395Skan  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10209169689Skan	(lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10210169689Skan		   (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10211169689Skan			     (match_operand:SI 3 "symbol_ref_operand" "s"))))]
10212169689Skan  "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic"
10213169689Skan  "{cal|addi} %0,%1,%2-%3@l")
10214117395Skan
1021590075Sobrien;; If the TOC is shared over a translation unit, as happens with all
1021690075Sobrien;; the kinds of PIC that we support, we need to restore the TOC
1021790075Sobrien;; pointer only when jumping over units of translation.
10218117395Skan;; On Darwin, we need to reload the picbase.
1021990075Sobrien
1022090075Sobrien(define_expand "builtin_setjmp_receiver"
1022190075Sobrien  [(use (label_ref (match_operand 0 "" "")))]
1022290075Sobrien  "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10223117395Skan   || (TARGET_TOC && TARGET_MINIMAL_TOC)
10224117395Skan   || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
1022590075Sobrien  "
1022690075Sobrien{
10227117395Skan#if TARGET_MACHO
10228117395Skan  if (DEFAULT_ABI == ABI_DARWIN)
10229117395Skan    {
10230132718Skan      const char *picbase = machopic_function_base_name ();
10231132718Skan      rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (picbase));
10232117395Skan      rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
10233117395Skan      rtx tmplabrtx;
10234117395Skan      char tmplab[20];
10235117395Skan
10236117395Skan      ASM_GENERATE_INTERNAL_LABEL(tmplab, \"LSJR\",
10237117395Skan				  CODE_LABEL_NUMBER (operands[0]));
10238132718Skan      tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
10239117395Skan
10240117395Skan      emit_insn (gen_load_macho_picbase (picreg, tmplabrtx));
10241117395Skan      emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplabrtx));
10242117395Skan    }
10243117395Skan  else
10244117395Skan#endif
10245117395Skan    rs6000_emit_load_toc_table (FALSE);
1024690075Sobrien  DONE;
1024790075Sobrien}")
10248169689Skan
10249169689Skan;; Elf specific ways of loading addresses for non-PIC code.
10250169689Skan;; The output of this could be r0, but we make a very strong
10251169689Skan;; preference for a base register because it will usually
10252169689Skan;; be needed there.
10253169689Skan(define_insn "elf_high"
10254169689Skan  [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
10255169689Skan	(high:SI (match_operand 1 "" "")))]
10256169689Skan  "TARGET_ELF && ! TARGET_64BIT"
10257169689Skan  "{liu|lis} %0,%1@ha")
10258169689Skan
10259169689Skan(define_insn "elf_low"
10260169689Skan  [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
10261169689Skan	(lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b,!*r")
10262169689Skan		   (match_operand 2 "" "")))]
10263169689Skan   "TARGET_ELF && ! TARGET_64BIT"
10264169689Skan   "@
10265169689Skan    {cal|la} %0,%2@l(%1)
10266169689Skan    {ai|addic} %0,%1,%K2")
1026790075Sobrien
1026890075Sobrien;; A function pointer under AIX is a pointer to a data area whose first word
1026990075Sobrien;; contains the actual address of the function, whose second word contains a
1027090075Sobrien;; pointer to its TOC, and whose third word contains a value to place in the
1027190075Sobrien;; static chain register (r11).  Note that if we load the static chain, our
1027290075Sobrien;; "trampoline" need not have any executable code.
1027390075Sobrien
1027490075Sobrien(define_expand "call_indirect_aix32"
1027590075Sobrien  [(set (match_dup 2)
1027690075Sobrien	(mem:SI (match_operand:SI 0 "gpc_reg_operand" "")))
1027790075Sobrien   (set (mem:SI (plus:SI (reg:SI 1) (const_int 20)))
1027890075Sobrien	(reg:SI 2))
1027990075Sobrien   (set (reg:SI 2)
1028090075Sobrien	(mem:SI (plus:SI (match_dup 0)
1028190075Sobrien			 (const_int 4))))
1028290075Sobrien   (set (reg:SI 11)
1028390075Sobrien	(mem:SI (plus:SI (match_dup 0)
1028490075Sobrien			 (const_int 8))))
1028590075Sobrien   (parallel [(call (mem:SI (match_dup 2))
1028690075Sobrien		    (match_operand 1 "" ""))
1028790075Sobrien	      (use (reg:SI 2))
1028890075Sobrien	      (use (reg:SI 11))
1028990075Sobrien	      (set (reg:SI 2)
1029090075Sobrien		   (mem:SI (plus:SI (reg:SI 1) (const_int 20))))
1029190075Sobrien	      (clobber (scratch:SI))])]
1029290075Sobrien  "TARGET_32BIT"
1029390075Sobrien  "
1029490075Sobrien{ operands[2] = gen_reg_rtx (SImode); }")
1029590075Sobrien
1029690075Sobrien(define_expand "call_indirect_aix64"
1029790075Sobrien  [(set (match_dup 2)
1029890075Sobrien	(mem:DI (match_operand:DI 0 "gpc_reg_operand" "")))
1029990075Sobrien   (set (mem:DI (plus:DI (reg:DI 1) (const_int 40)))
1030090075Sobrien	(reg:DI 2))
1030190075Sobrien   (set (reg:DI 2)
1030290075Sobrien	(mem:DI (plus:DI (match_dup 0)
1030390075Sobrien			 (const_int 8))))
1030490075Sobrien   (set (reg:DI 11)
1030590075Sobrien	(mem:DI (plus:DI (match_dup 0)
1030690075Sobrien			 (const_int 16))))
1030790075Sobrien   (parallel [(call (mem:SI (match_dup 2))
1030890075Sobrien		    (match_operand 1 "" ""))
1030990075Sobrien	      (use (reg:DI 2))
1031090075Sobrien	      (use (reg:DI 11))
1031190075Sobrien	      (set (reg:DI 2)
1031290075Sobrien		   (mem:DI (plus:DI (reg:DI 1) (const_int 40))))
1031390075Sobrien	      (clobber (scratch:SI))])]
1031490075Sobrien  "TARGET_64BIT"
1031590075Sobrien  "
1031690075Sobrien{ operands[2] = gen_reg_rtx (DImode); }")
1031790075Sobrien
1031890075Sobrien(define_expand "call_value_indirect_aix32"
1031990075Sobrien  [(set (match_dup 3)
1032090075Sobrien	(mem:SI (match_operand:SI 1 "gpc_reg_operand" "")))
1032190075Sobrien   (set (mem:SI (plus:SI (reg:SI 1) (const_int 20)))
1032290075Sobrien	(reg:SI 2))
1032390075Sobrien   (set (reg:SI 2)
1032490075Sobrien	(mem:SI (plus:SI (match_dup 1)
1032590075Sobrien			 (const_int 4))))
1032690075Sobrien   (set (reg:SI 11)
1032790075Sobrien	(mem:SI (plus:SI (match_dup 1)
1032890075Sobrien			 (const_int 8))))
1032990075Sobrien   (parallel [(set (match_operand 0 "" "")
1033090075Sobrien		   (call (mem:SI (match_dup 3))
1033190075Sobrien			 (match_operand 2 "" "")))
1033290075Sobrien	      (use (reg:SI 2))
1033390075Sobrien	      (use (reg:SI 11))
1033490075Sobrien	      (set (reg:SI 2)
1033590075Sobrien		   (mem:SI (plus:SI (reg:SI 1) (const_int 20))))
1033690075Sobrien	      (clobber (scratch:SI))])]
1033790075Sobrien  "TARGET_32BIT"
1033890075Sobrien  "
1033990075Sobrien{ operands[3] = gen_reg_rtx (SImode); }")
1034090075Sobrien
1034190075Sobrien(define_expand "call_value_indirect_aix64"
1034290075Sobrien  [(set (match_dup 3)
1034390075Sobrien	(mem:DI (match_operand:DI 1 "gpc_reg_operand" "")))
1034490075Sobrien   (set (mem:DI (plus:DI (reg:DI 1) (const_int 40)))
1034590075Sobrien	(reg:DI 2))
1034690075Sobrien   (set (reg:DI 2)
1034790075Sobrien	(mem:DI (plus:DI (match_dup 1)
1034890075Sobrien			 (const_int 8))))
1034990075Sobrien   (set (reg:DI 11)
1035090075Sobrien	(mem:DI (plus:DI (match_dup 1)
1035190075Sobrien			 (const_int 16))))
1035290075Sobrien   (parallel [(set (match_operand 0 "" "")
1035390075Sobrien		   (call (mem:SI (match_dup 3))
1035490075Sobrien			 (match_operand 2 "" "")))
1035590075Sobrien	      (use (reg:DI 2))
1035690075Sobrien	      (use (reg:DI 11))
1035790075Sobrien	      (set (reg:DI 2)
1035890075Sobrien		   (mem:DI (plus:DI (reg:DI 1) (const_int 40))))
1035990075Sobrien	      (clobber (scratch:SI))])]
1036090075Sobrien  "TARGET_64BIT"
1036190075Sobrien  "
1036290075Sobrien{ operands[3] = gen_reg_rtx (DImode); }")
1036390075Sobrien
1036490075Sobrien;; Now the definitions for the call and call_value insns
1036590075Sobrien(define_expand "call"
1036690075Sobrien  [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
1036790075Sobrien		    (match_operand 1 "" ""))
1036890075Sobrien	      (use (match_operand 2 "" ""))
1036990075Sobrien	      (clobber (scratch:SI))])]
1037090075Sobrien  ""
1037190075Sobrien  "
1037290075Sobrien{
1037390075Sobrien#if TARGET_MACHO
10374132718Skan  if (MACHOPIC_INDIRECT)
1037590075Sobrien    operands[0] = machopic_indirect_call_target (operands[0]);
1037690075Sobrien#endif
1037790075Sobrien
10378169689Skan  gcc_assert (GET_CODE (operands[0]) == MEM);
10379169689Skan  gcc_assert (GET_CODE (operands[1]) == CONST_INT);
1038090075Sobrien
1038190075Sobrien  operands[0] = XEXP (operands[0], 0);
1038290075Sobrien
10383169689Skan  if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT
10384169689Skan      && flag_pic
10385169689Skan      && GET_CODE (operands[0]) == SYMBOL_REF
10386169689Skan      && !SYMBOL_REF_LOCAL_P (operands[0]))
10387169689Skan    {
10388169689Skan      rtx call;
10389169689Skan      rtvec tmp;
10390169689Skan
10391169689Skan      tmp = gen_rtvec (3,
10392169689Skan		       gen_rtx_CALL (VOIDmode,
10393169689Skan				     gen_rtx_MEM (SImode, operands[0]),
10394169689Skan				     operands[1]),
10395169689Skan		       gen_rtx_USE (VOIDmode, operands[2]),
10396169689Skan		       gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)));
10397169689Skan      call = emit_call_insn (gen_rtx_PARALLEL (VOIDmode, tmp));
10398169689Skan      use_reg (&CALL_INSN_FUNCTION_USAGE (call), pic_offset_table_rtx);
10399169689Skan      DONE;
10400169689Skan    }
10401169689Skan
1040290075Sobrien  if (GET_CODE (operands[0]) != SYMBOL_REF
10403132718Skan      || (DEFAULT_ABI == ABI_AIX && !SYMBOL_REF_FUNCTION_P (operands[0]))
10404132718Skan      || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[2]) & CALL_LONG) != 0))
1040590075Sobrien    {
1040690075Sobrien      if (INTVAL (operands[2]) & CALL_LONG)
1040790075Sobrien	operands[0] = rs6000_longcall_ref (operands[0]);
1040890075Sobrien
10409169689Skan      switch (DEFAULT_ABI)
10410169689Skan        {
10411169689Skan	case ABI_V4:
10412169689Skan	case ABI_DARWIN:
10413169689Skan	  operands[0] = force_reg (Pmode, operands[0]);
10414169689Skan	  break;
1041590075Sobrien
10416169689Skan	case ABI_AIX:
1041790075Sobrien	  /* AIX function pointers are really pointers to a three word
1041890075Sobrien	     area.  */
1041990075Sobrien	  emit_call_insn (TARGET_32BIT
1042090075Sobrien			  ? gen_call_indirect_aix32 (force_reg (SImode,
1042190075Sobrien							        operands[0]),
1042290075Sobrien						     operands[1])
1042390075Sobrien			  : gen_call_indirect_aix64 (force_reg (DImode,
1042490075Sobrien							        operands[0]),
1042590075Sobrien						     operands[1]));
1042690075Sobrien	  DONE;
10427169689Skan
10428169689Skan	default:
10429169689Skan	  gcc_unreachable ();
1043090075Sobrien	}
1043190075Sobrien    }
1043290075Sobrien}")
1043390075Sobrien
1043490075Sobrien(define_expand "call_value"
1043590075Sobrien  [(parallel [(set (match_operand 0 "" "")
1043690075Sobrien		   (call (mem:SI (match_operand 1 "address_operand" ""))
1043790075Sobrien			 (match_operand 2 "" "")))
1043890075Sobrien	      (use (match_operand 3 "" ""))
1043990075Sobrien	      (clobber (scratch:SI))])]
1044090075Sobrien  ""
1044190075Sobrien  "
1044290075Sobrien{
1044390075Sobrien#if TARGET_MACHO
10444132718Skan  if (MACHOPIC_INDIRECT)
1044590075Sobrien    operands[1] = machopic_indirect_call_target (operands[1]);
1044690075Sobrien#endif
1044790075Sobrien
10448169689Skan  gcc_assert (GET_CODE (operands[1]) == MEM);
10449169689Skan  gcc_assert (GET_CODE (operands[2]) == CONST_INT);
1045090075Sobrien
1045190075Sobrien  operands[1] = XEXP (operands[1], 0);
1045290075Sobrien
10453169689Skan  if (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT
10454169689Skan      && flag_pic
10455169689Skan      && GET_CODE (operands[1]) == SYMBOL_REF
10456169689Skan      && !SYMBOL_REF_LOCAL_P (operands[1]))
10457169689Skan    {
10458169689Skan      rtx call;
10459169689Skan      rtvec tmp;
10460169689Skan
10461169689Skan      tmp = gen_rtvec (3,
10462169689Skan		       gen_rtx_SET (VOIDmode,
10463169689Skan				    operands[0],
10464169689Skan				    gen_rtx_CALL (VOIDmode,
10465169689Skan						  gen_rtx_MEM (SImode,
10466169689Skan							       operands[1]),
10467169689Skan						  operands[2])),
10468169689Skan		       gen_rtx_USE (VOIDmode, operands[3]),
10469169689Skan		       gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)));
10470169689Skan      call = emit_call_insn (gen_rtx_PARALLEL (VOIDmode, tmp));
10471169689Skan      use_reg (&CALL_INSN_FUNCTION_USAGE (call), pic_offset_table_rtx);
10472169689Skan      DONE;
10473169689Skan    }
10474169689Skan
1047590075Sobrien  if (GET_CODE (operands[1]) != SYMBOL_REF
10476132718Skan      || (DEFAULT_ABI == ABI_AIX && !SYMBOL_REF_FUNCTION_P (operands[1]))
10477132718Skan      || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[3]) & CALL_LONG) != 0))
1047890075Sobrien    {
1047990075Sobrien      if (INTVAL (operands[3]) & CALL_LONG)
1048090075Sobrien	operands[1] = rs6000_longcall_ref (operands[1]);
1048190075Sobrien
10482169689Skan      switch (DEFAULT_ABI)
10483169689Skan        {
10484169689Skan	case ABI_V4:
10485169689Skan	case ABI_DARWIN:
10486169689Skan	  operands[1] = force_reg (Pmode, operands[1]);
10487169689Skan	  break;
1048890075Sobrien
10489169689Skan	case ABI_AIX:
1049090075Sobrien	  /* AIX function pointers are really pointers to a three word
1049190075Sobrien	     area.  */
1049290075Sobrien	  emit_call_insn (TARGET_32BIT
1049390075Sobrien			  ? gen_call_value_indirect_aix32 (operands[0],
1049490075Sobrien							   force_reg (SImode,
1049590075Sobrien								      operands[1]),
1049690075Sobrien							   operands[2])
1049790075Sobrien			  : gen_call_value_indirect_aix64 (operands[0],
1049890075Sobrien							   force_reg (DImode,
1049990075Sobrien								      operands[1]),
1050090075Sobrien							   operands[2]));
1050190075Sobrien	  DONE;
10502169689Skan
10503169689Skan	default:
10504169689Skan	  gcc_unreachable ();
1050590075Sobrien	}
1050690075Sobrien    }
1050790075Sobrien}")
1050890075Sobrien
1050990075Sobrien;; Call to function in current module.  No TOC pointer reload needed.
10510117395Skan;; Operand2 is nonzero if we are using the V.4 calling sequence and
1051190075Sobrien;; either the function was not prototyped, or it was prototyped as a
1051290075Sobrien;; variable argument function.  It is > 0 if FP registers were passed
1051390075Sobrien;; and < 0 if they were not.
1051490075Sobrien
1051590075Sobrien(define_insn "*call_local32"
1051690075Sobrien  [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
1051790075Sobrien	 (match_operand 1 "" "g,g"))
1051890075Sobrien   (use (match_operand:SI 2 "immediate_operand" "O,n"))
1051990075Sobrien   (clobber (match_scratch:SI 3 "=l,l"))]
1052090075Sobrien  "(INTVAL (operands[2]) & CALL_LONG) == 0"
1052190075Sobrien  "*
1052290075Sobrien{
1052390075Sobrien  if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
1052490075Sobrien    output_asm_insn (\"crxor 6,6,6\", operands);
1052590075Sobrien
1052690075Sobrien  else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
1052790075Sobrien    output_asm_insn (\"creqv 6,6,6\", operands);
1052890075Sobrien
1052990075Sobrien  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
1053090075Sobrien}"
1053190075Sobrien  [(set_attr "type" "branch")
1053290075Sobrien   (set_attr "length" "4,8")])
1053390075Sobrien
1053490075Sobrien(define_insn "*call_local64"
1053590075Sobrien  [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
1053690075Sobrien	 (match_operand 1 "" "g,g"))
1053790075Sobrien   (use (match_operand:SI 2 "immediate_operand" "O,n"))
1053890075Sobrien   (clobber (match_scratch:SI 3 "=l,l"))]
1053990075Sobrien  "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
1054090075Sobrien  "*
1054190075Sobrien{
1054290075Sobrien  if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
1054390075Sobrien    output_asm_insn (\"crxor 6,6,6\", operands);
1054490075Sobrien
1054590075Sobrien  else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
1054690075Sobrien    output_asm_insn (\"creqv 6,6,6\", operands);
1054790075Sobrien
1054890075Sobrien  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
1054990075Sobrien}"
1055090075Sobrien  [(set_attr "type" "branch")
1055190075Sobrien   (set_attr "length" "4,8")])
1055290075Sobrien
1055390075Sobrien(define_insn "*call_value_local32"
1055490075Sobrien  [(set (match_operand 0 "" "")
1055590075Sobrien	(call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
1055690075Sobrien	      (match_operand 2 "" "g,g")))
1055790075Sobrien   (use (match_operand:SI 3 "immediate_operand" "O,n"))
1055890075Sobrien   (clobber (match_scratch:SI 4 "=l,l"))]
1055990075Sobrien  "(INTVAL (operands[3]) & CALL_LONG) == 0"
1056090075Sobrien  "*
1056190075Sobrien{
1056290075Sobrien  if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
1056390075Sobrien    output_asm_insn (\"crxor 6,6,6\", operands);
1056490075Sobrien
1056590075Sobrien  else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
1056690075Sobrien    output_asm_insn (\"creqv 6,6,6\", operands);
1056790075Sobrien
1056890075Sobrien  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
1056990075Sobrien}"
1057090075Sobrien  [(set_attr "type" "branch")
1057190075Sobrien   (set_attr "length" "4,8")])
1057290075Sobrien
1057390075Sobrien
1057490075Sobrien(define_insn "*call_value_local64"
1057590075Sobrien  [(set (match_operand 0 "" "")
1057690075Sobrien	(call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
1057790075Sobrien	      (match_operand 2 "" "g,g")))
1057890075Sobrien   (use (match_operand:SI 3 "immediate_operand" "O,n"))
1057990075Sobrien   (clobber (match_scratch:SI 4 "=l,l"))]
1058090075Sobrien  "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
1058190075Sobrien  "*
1058290075Sobrien{
1058390075Sobrien  if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
1058490075Sobrien    output_asm_insn (\"crxor 6,6,6\", operands);
1058590075Sobrien
1058690075Sobrien  else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
1058790075Sobrien    output_asm_insn (\"creqv 6,6,6\", operands);
1058890075Sobrien
1058990075Sobrien  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
1059090075Sobrien}"
1059190075Sobrien  [(set_attr "type" "branch")
1059290075Sobrien   (set_attr "length" "4,8")])
1059390075Sobrien
1059490075Sobrien;; Call to function which may be in another module.  Restore the TOC
1059590075Sobrien;; pointer (r2) after the call unless this is System V.
10596117395Skan;; Operand2 is nonzero if we are using the V.4 calling sequence and
1059790075Sobrien;; either the function was not prototyped, or it was prototyped as a
1059890075Sobrien;; variable argument function.  It is > 0 if FP registers were passed
1059990075Sobrien;; and < 0 if they were not.
1060090075Sobrien
1060190075Sobrien(define_insn "*call_indirect_nonlocal_aix32"
10602169689Skan  [(call (mem:SI (match_operand:SI 0 "register_operand" "c,*l"))
10603169689Skan	 (match_operand 1 "" "g,g"))
1060490075Sobrien   (use (reg:SI 2))
1060590075Sobrien   (use (reg:SI 11))
1060690075Sobrien   (set (reg:SI 2)
1060790075Sobrien	(mem:SI (plus:SI (reg:SI 1) (const_int 20))))
10608169689Skan   (clobber (match_scratch:SI 2 "=l,l"))]
1060990075Sobrien  "TARGET_32BIT && DEFAULT_ABI == ABI_AIX"
1061090075Sobrien  "b%T0l\;{l|lwz} 2,20(1)"
1061190075Sobrien  [(set_attr "type" "jmpreg")
1061290075Sobrien   (set_attr "length" "8")])
1061390075Sobrien
1061490075Sobrien(define_insn "*call_nonlocal_aix32"
10615117395Skan  [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "s"))
1061690075Sobrien	 (match_operand 1 "" "g"))
1061790075Sobrien   (use (match_operand:SI 2 "immediate_operand" "O"))
1061890075Sobrien   (clobber (match_scratch:SI 3 "=l"))]
1061990075Sobrien  "TARGET_32BIT
1062090075Sobrien   && DEFAULT_ABI == ABI_AIX
1062190075Sobrien   && (INTVAL (operands[2]) & CALL_LONG) == 0"
1062290075Sobrien  "bl %z0\;%."
1062390075Sobrien  [(set_attr "type" "branch")
1062490075Sobrien   (set_attr "length" "8")])
1062590075Sobrien
1062690075Sobrien(define_insn "*call_indirect_nonlocal_aix64"
10627169689Skan  [(call (mem:SI (match_operand:DI 0 "register_operand" "c,*l"))
10628169689Skan	 (match_operand 1 "" "g,g"))
1062990075Sobrien   (use (reg:DI 2))
1063090075Sobrien   (use (reg:DI 11))
1063190075Sobrien   (set (reg:DI 2)
1063290075Sobrien	(mem:DI (plus:DI (reg:DI 1) (const_int 40))))
10633169689Skan   (clobber (match_scratch:SI 2 "=l,l"))]
1063490075Sobrien  "TARGET_64BIT && DEFAULT_ABI == ABI_AIX"
1063590075Sobrien  "b%T0l\;ld 2,40(1)"
1063690075Sobrien  [(set_attr "type" "jmpreg")
1063790075Sobrien   (set_attr "length" "8")])
1063890075Sobrien
1063990075Sobrien(define_insn "*call_nonlocal_aix64"
10640117395Skan  [(call (mem:SI (match_operand:DI 0 "symbol_ref_operand" "s"))
1064190075Sobrien	 (match_operand 1 "" "g"))
1064290075Sobrien   (use (match_operand:SI 2 "immediate_operand" "O"))
1064390075Sobrien   (clobber (match_scratch:SI 3 "=l"))]
10644169689Skan  "TARGET_64BIT
1064590075Sobrien   && DEFAULT_ABI == ABI_AIX
1064690075Sobrien   && (INTVAL (operands[2]) & CALL_LONG) == 0"
1064790075Sobrien  "bl %z0\;%."
1064890075Sobrien  [(set_attr "type" "branch")
1064990075Sobrien   (set_attr "length" "8")])
1065090075Sobrien
1065190075Sobrien(define_insn "*call_value_indirect_nonlocal_aix32"
1065290075Sobrien  [(set (match_operand 0 "" "")
10653169689Skan	(call (mem:SI (match_operand:SI 1 "register_operand" "c,*l"))
10654169689Skan	      (match_operand 2 "" "g,g")))
1065590075Sobrien   (use (reg:SI 2))
1065690075Sobrien   (use (reg:SI 11))
1065790075Sobrien   (set (reg:SI 2)
1065890075Sobrien	(mem:SI (plus:SI (reg:SI 1) (const_int 20))))
10659169689Skan   (clobber (match_scratch:SI 3 "=l,l"))]
1066090075Sobrien  "TARGET_32BIT && DEFAULT_ABI == ABI_AIX"
1066190075Sobrien  "b%T1l\;{l|lwz} 2,20(1)"
1066290075Sobrien  [(set_attr "type" "jmpreg")
1066390075Sobrien   (set_attr "length" "8")])
1066490075Sobrien
1066590075Sobrien(define_insn "*call_value_nonlocal_aix32"
1066690075Sobrien  [(set (match_operand 0 "" "")
10667117395Skan	(call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "s"))
1066890075Sobrien	      (match_operand 2 "" "g")))
1066990075Sobrien   (use (match_operand:SI 3 "immediate_operand" "O"))
1067090075Sobrien   (clobber (match_scratch:SI 4 "=l"))]
1067190075Sobrien  "TARGET_32BIT
1067290075Sobrien   && DEFAULT_ABI == ABI_AIX
1067390075Sobrien   && (INTVAL (operands[3]) & CALL_LONG) == 0"
1067490075Sobrien  "bl %z1\;%."
1067590075Sobrien  [(set_attr "type" "branch")
1067690075Sobrien   (set_attr "length" "8")])
1067790075Sobrien
1067890075Sobrien(define_insn "*call_value_indirect_nonlocal_aix64"
1067990075Sobrien  [(set (match_operand 0 "" "")
10680169689Skan	(call (mem:SI (match_operand:DI 1 "register_operand" "c,*l"))
10681169689Skan	      (match_operand 2 "" "g,g")))
1068290075Sobrien   (use (reg:DI 2))
1068390075Sobrien   (use (reg:DI 11))
1068490075Sobrien   (set (reg:DI 2)
1068590075Sobrien	(mem:DI (plus:DI (reg:DI 1) (const_int 40))))
10686169689Skan   (clobber (match_scratch:SI 3 "=l,l"))]
1068790075Sobrien  "TARGET_64BIT && DEFAULT_ABI == ABI_AIX"
1068890075Sobrien  "b%T1l\;ld 2,40(1)"
1068990075Sobrien  [(set_attr "type" "jmpreg")
1069090075Sobrien   (set_attr "length" "8")])
1069190075Sobrien
1069290075Sobrien(define_insn "*call_value_nonlocal_aix64"
1069390075Sobrien  [(set (match_operand 0 "" "")
10694117395Skan	(call (mem:SI (match_operand:DI 1 "symbol_ref_operand" "s"))
1069590075Sobrien	      (match_operand 2 "" "g")))
1069690075Sobrien   (use (match_operand:SI 3 "immediate_operand" "O"))
1069790075Sobrien   (clobber (match_scratch:SI 4 "=l"))]
10698169689Skan  "TARGET_64BIT
1069990075Sobrien   && DEFAULT_ABI == ABI_AIX
1070090075Sobrien   && (INTVAL (operands[3]) & CALL_LONG) == 0"
1070190075Sobrien  "bl %z1\;%."
1070290075Sobrien  [(set_attr "type" "branch")
1070390075Sobrien   (set_attr "length" "8")])
1070490075Sobrien
1070590075Sobrien;; A function pointer under System V is just a normal pointer
1070690075Sobrien;; operands[0] is the function pointer
1070790075Sobrien;; operands[1] is the stack size to clean up
1070890075Sobrien;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
1070990075Sobrien;; which indicates how to set cr1
1071090075Sobrien
10711169689Skan(define_insn "*call_indirect_nonlocal_sysv<mode>"
10712169689Skan  [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l,c,*l"))
10713169689Skan	 (match_operand 1 "" "g,g,g,g"))
10714169689Skan   (use (match_operand:SI 2 "immediate_operand" "O,O,n,n"))
10715169689Skan   (clobber (match_scratch:SI 3 "=l,l,l,l"))]
10716132718Skan  "DEFAULT_ABI == ABI_V4
1071790075Sobrien   || DEFAULT_ABI == ABI_DARWIN"
1071890075Sobrien{
1071990075Sobrien  if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10720117395Skan    output_asm_insn ("crxor 6,6,6", operands);
1072190075Sobrien
1072290075Sobrien  else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10723117395Skan    output_asm_insn ("creqv 6,6,6", operands);
1072490075Sobrien
10725117395Skan  return "b%T0l";
10726117395Skan}
10727169689Skan  [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10728169689Skan   (set_attr "length" "4,4,8,8")])
1072990075Sobrien
10730169689Skan(define_insn "*call_nonlocal_sysv<mode>"
10731169689Skan  [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10732117395Skan	 (match_operand 1 "" "g,g"))
10733117395Skan   (use (match_operand:SI 2 "immediate_operand" "O,n"))
10734117395Skan   (clobber (match_scratch:SI 3 "=l,l"))]
10735132718Skan  "(DEFAULT_ABI == ABI_DARWIN
10736132718Skan   || (DEFAULT_ABI == ABI_V4
10737132718Skan       && (INTVAL (operands[2]) & CALL_LONG) == 0))"
10738117395Skan{
10739117395Skan  if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10740117395Skan    output_asm_insn ("crxor 6,6,6", operands);
10741117395Skan
10742117395Skan  else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10743117395Skan    output_asm_insn ("creqv 6,6,6", operands);
10744117395Skan
10745132718Skan#if TARGET_MACHO
10746132718Skan  return output_call(insn, operands, 0, 2);
10747132718Skan#else
10748169689Skan  if (DEFAULT_ABI == ABI_V4 && flag_pic)
10749169689Skan    {
10750169689Skan      if (TARGET_SECURE_PLT && flag_pic == 2)
10751169689Skan	/* The magic 32768 offset here and in the other sysv call insns
10752169689Skan	   corresponds to the offset of r30 in .got2, as given by LCTOC1.
10753169689Skan	   See sysv4.h:toc_section.  */
10754169689Skan	return "bl %z0+32768@plt";
10755169689Skan      else
10756169689Skan	return "bl %z0@plt";
10757169689Skan    }
10758169689Skan  else
10759169689Skan    return "bl %z0";
10760169689Skan#endif
10761117395Skan}
10762117395Skan  [(set_attr "type" "branch,branch")
10763117395Skan   (set_attr "length" "4,8")])
10764117395Skan
10765169689Skan(define_insn "*call_value_indirect_nonlocal_sysv<mode>"
1076690075Sobrien  [(set (match_operand 0 "" "")
10767169689Skan	(call (mem:SI (match_operand:P 1 "register_operand" "c,*l,c,*l"))
10768169689Skan	      (match_operand 2 "" "g,g,g,g")))
10769169689Skan   (use (match_operand:SI 3 "immediate_operand" "O,O,n,n"))
10770169689Skan   (clobber (match_scratch:SI 4 "=l,l,l,l"))]
10771132718Skan  "DEFAULT_ABI == ABI_V4
1077290075Sobrien   || DEFAULT_ABI == ABI_DARWIN"
1077390075Sobrien{
1077490075Sobrien  if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10775117395Skan    output_asm_insn ("crxor 6,6,6", operands);
1077690075Sobrien
1077790075Sobrien  else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10778117395Skan    output_asm_insn ("creqv 6,6,6", operands);
1077990075Sobrien
10780117395Skan  return "b%T1l";
10781117395Skan}
10782169689Skan  [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10783169689Skan   (set_attr "length" "4,4,8,8")])
1078490075Sobrien
10785169689Skan(define_insn "*call_value_nonlocal_sysv<mode>"
10786117395Skan  [(set (match_operand 0 "" "")
10787169689Skan	(call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10788117395Skan	      (match_operand 2 "" "g,g")))
10789117395Skan   (use (match_operand:SI 3 "immediate_operand" "O,n"))
10790117395Skan   (clobber (match_scratch:SI 4 "=l,l"))]
10791132718Skan  "(DEFAULT_ABI == ABI_DARWIN
10792132718Skan   || (DEFAULT_ABI == ABI_V4
10793132718Skan       && (INTVAL (operands[3]) & CALL_LONG) == 0))"
10794117395Skan{
10795117395Skan  if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10796117395Skan    output_asm_insn ("crxor 6,6,6", operands);
10797117395Skan
10798117395Skan  else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10799117395Skan    output_asm_insn ("creqv 6,6,6", operands);
10800117395Skan
10801132718Skan#if TARGET_MACHO
10802132718Skan  return output_call(insn, operands, 1, 3);
10803132718Skan#else
10804169689Skan  if (DEFAULT_ABI == ABI_V4 && flag_pic)
10805169689Skan    {
10806169689Skan      if (TARGET_SECURE_PLT && flag_pic == 2)
10807169689Skan	return "bl %z1+32768@plt";
10808169689Skan      else
10809169689Skan	return "bl %z1@plt";
10810169689Skan    }
10811169689Skan  else
10812169689Skan    return "bl %z1";
10813169689Skan#endif
10814117395Skan}
10815117395Skan  [(set_attr "type" "branch,branch")
10816117395Skan   (set_attr "length" "4,8")])
10817117395Skan
1081890075Sobrien;; Call subroutine returning any type.
1081990075Sobrien(define_expand "untyped_call"
1082090075Sobrien  [(parallel [(call (match_operand 0 "" "")
1082190075Sobrien		    (const_int 0))
1082290075Sobrien	      (match_operand 1 "" "")
1082390075Sobrien	      (match_operand 2 "" "")])]
1082490075Sobrien  ""
1082590075Sobrien  "
1082690075Sobrien{
1082790075Sobrien  int i;
1082890075Sobrien
1082990075Sobrien  emit_call_insn (GEN_CALL (operands[0], const0_rtx, const0_rtx, const0_rtx));
1083090075Sobrien
1083190075Sobrien  for (i = 0; i < XVECLEN (operands[2], 0); i++)
1083290075Sobrien    {
1083390075Sobrien      rtx set = XVECEXP (operands[2], 0, i);
1083490075Sobrien      emit_move_insn (SET_DEST (set), SET_SRC (set));
1083590075Sobrien    }
1083690075Sobrien
1083790075Sobrien  /* The optimizer does not know that the call sets the function value
1083890075Sobrien     registers we stored in the result block.  We avoid problems by
1083990075Sobrien     claiming that all hard registers are used and clobbered at this
1084090075Sobrien     point.  */
1084190075Sobrien  emit_insn (gen_blockage ());
1084290075Sobrien
1084390075Sobrien  DONE;
1084490075Sobrien}")
1084590075Sobrien
10846117395Skan;; sibling call patterns
10847117395Skan(define_expand "sibcall"
10848117395Skan  [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
10849117395Skan		    (match_operand 1 "" ""))
10850117395Skan	      (use (match_operand 2 "" ""))
10851132718Skan	      (use (match_operand 3 "" ""))
10852117395Skan	      (return)])]
10853117395Skan  ""
10854117395Skan  "
10855117395Skan{
10856117395Skan#if TARGET_MACHO
10857132718Skan  if (MACHOPIC_INDIRECT)
10858117395Skan    operands[0] = machopic_indirect_call_target (operands[0]);
10859117395Skan#endif
10860117395Skan
10861169689Skan  gcc_assert (GET_CODE (operands[0]) == MEM);
10862169689Skan  gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10863117395Skan
10864117395Skan  operands[0] = XEXP (operands[0], 0);
10865132718Skan  operands[3] = gen_reg_rtx (SImode);
10866117395Skan
10867117395Skan}")
10868117395Skan
10869117395Skan;; this and similar patterns must be marked as using LR, otherwise
10870117395Skan;; dataflow will try to delete the store into it.  This is true
10871117395Skan;; even when the actual reg to jump to is in CTR, when LR was
10872117395Skan;; saved and restored around the PIC-setting BCL.
10873117395Skan(define_insn "*sibcall_local32"
10874117395Skan  [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10875117395Skan	 (match_operand 1 "" "g,g"))
10876117395Skan   (use (match_operand:SI 2 "immediate_operand" "O,n"))
10877132718Skan   (use (match_operand:SI 3 "register_operand" "l,l"))
10878117395Skan   (return)]
10879117395Skan  "(INTVAL (operands[2]) & CALL_LONG) == 0"
10880117395Skan  "*
10881117395Skan{
10882117395Skan  if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10883117395Skan    output_asm_insn (\"crxor 6,6,6\", operands);
10884117395Skan
10885117395Skan  else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10886117395Skan    output_asm_insn (\"creqv 6,6,6\", operands);
10887117395Skan
10888117395Skan  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
10889117395Skan}"
10890117395Skan  [(set_attr "type" "branch")
10891117395Skan   (set_attr "length" "4,8")])
10892117395Skan
10893117395Skan(define_insn "*sibcall_local64"
10894117395Skan  [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10895117395Skan	 (match_operand 1 "" "g,g"))
10896117395Skan   (use (match_operand:SI 2 "immediate_operand" "O,n"))
10897132718Skan   (use (match_operand:SI 3 "register_operand" "l,l"))
10898117395Skan   (return)]
10899117395Skan  "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10900117395Skan  "*
10901117395Skan{
10902117395Skan  if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10903117395Skan    output_asm_insn (\"crxor 6,6,6\", operands);
10904117395Skan
10905117395Skan  else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10906117395Skan    output_asm_insn (\"creqv 6,6,6\", operands);
10907117395Skan
10908117395Skan  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
10909117395Skan}"
10910117395Skan  [(set_attr "type" "branch")
10911117395Skan   (set_attr "length" "4,8")])
10912117395Skan
10913117395Skan(define_insn "*sibcall_value_local32"
10914117395Skan  [(set (match_operand 0 "" "")
10915117395Skan	(call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10916117395Skan	      (match_operand 2 "" "g,g")))
10917117395Skan   (use (match_operand:SI 3 "immediate_operand" "O,n"))
10918132718Skan   (use (match_operand:SI 4 "register_operand" "l,l"))
10919117395Skan   (return)]
10920117395Skan  "(INTVAL (operands[3]) & CALL_LONG) == 0"
10921117395Skan  "*
10922117395Skan{
10923117395Skan  if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10924117395Skan    output_asm_insn (\"crxor 6,6,6\", operands);
10925117395Skan
10926117395Skan  else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10927117395Skan    output_asm_insn (\"creqv 6,6,6\", operands);
10928117395Skan
10929117395Skan  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
10930117395Skan}"
10931117395Skan  [(set_attr "type" "branch")
10932117395Skan   (set_attr "length" "4,8")])
10933117395Skan
10934117395Skan
10935117395Skan(define_insn "*sibcall_value_local64"
10936117395Skan  [(set (match_operand 0 "" "")
10937117395Skan	(call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10938117395Skan	      (match_operand 2 "" "g,g")))
10939117395Skan   (use (match_operand:SI 3 "immediate_operand" "O,n"))
10940132718Skan   (use (match_operand:SI 4 "register_operand" "l,l"))
10941117395Skan   (return)]
10942117395Skan  "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10943117395Skan  "*
10944117395Skan{
10945117395Skan  if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10946117395Skan    output_asm_insn (\"crxor 6,6,6\", operands);
10947117395Skan
10948117395Skan  else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10949117395Skan    output_asm_insn (\"creqv 6,6,6\", operands);
10950117395Skan
10951117395Skan  return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
10952117395Skan}"
10953117395Skan  [(set_attr "type" "branch")
10954117395Skan   (set_attr "length" "4,8")])
10955117395Skan
10956117395Skan(define_insn "*sibcall_nonlocal_aix32"
10957117395Skan  [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "s"))
10958117395Skan	 (match_operand 1 "" "g"))
10959117395Skan   (use (match_operand:SI 2 "immediate_operand" "O"))
10960132718Skan   (use (match_operand:SI 3 "register_operand" "l"))
10961117395Skan   (return)]
10962117395Skan  "TARGET_32BIT
10963117395Skan   && DEFAULT_ABI == ABI_AIX
10964117395Skan   && (INTVAL (operands[2]) & CALL_LONG) == 0"
10965117395Skan  "b %z0"
10966117395Skan  [(set_attr "type" "branch")
10967117395Skan   (set_attr "length" "4")])
10968117395Skan
10969117395Skan(define_insn "*sibcall_nonlocal_aix64"
10970117395Skan  [(call (mem:SI (match_operand:DI 0 "symbol_ref_operand" "s"))
10971117395Skan	 (match_operand 1 "" "g"))
10972117395Skan   (use (match_operand:SI 2 "immediate_operand" "O"))
10973132718Skan   (use (match_operand:SI 3 "register_operand" "l"))
10974117395Skan   (return)]
10975169689Skan  "TARGET_64BIT
10976117395Skan   && DEFAULT_ABI == ABI_AIX
10977117395Skan   && (INTVAL (operands[2]) & CALL_LONG) == 0"
10978117395Skan  "b %z0"
10979117395Skan  [(set_attr "type" "branch")
10980117395Skan   (set_attr "length" "4")])
10981117395Skan
10982117395Skan(define_insn "*sibcall_value_nonlocal_aix32"
10983117395Skan  [(set (match_operand 0 "" "")
10984117395Skan	(call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "s"))
10985117395Skan	      (match_operand 2 "" "g")))
10986117395Skan   (use (match_operand:SI 3 "immediate_operand" "O"))
10987132718Skan   (use (match_operand:SI 4 "register_operand" "l"))
10988117395Skan   (return)]
10989117395Skan  "TARGET_32BIT
10990117395Skan   && DEFAULT_ABI == ABI_AIX
10991117395Skan   && (INTVAL (operands[3]) & CALL_LONG) == 0"
10992117395Skan  "b %z1"
10993117395Skan  [(set_attr "type" "branch")
10994117395Skan   (set_attr "length" "4")])
10995117395Skan
10996117395Skan(define_insn "*sibcall_value_nonlocal_aix64"
10997117395Skan  [(set (match_operand 0 "" "")
10998117395Skan	(call (mem:SI (match_operand:DI 1 "symbol_ref_operand" "s"))
10999117395Skan	      (match_operand 2 "" "g")))
11000117395Skan   (use (match_operand:SI 3 "immediate_operand" "O"))
11001132718Skan   (use (match_operand:SI 4 "register_operand" "l"))
11002117395Skan   (return)]
11003169689Skan  "TARGET_64BIT
11004117395Skan   && DEFAULT_ABI == ABI_AIX
11005117395Skan   && (INTVAL (operands[3]) & CALL_LONG) == 0"
11006117395Skan  "b %z1"
11007117395Skan  [(set_attr "type" "branch")
11008117395Skan   (set_attr "length" "4")])
11009117395Skan
11010169689Skan(define_insn "*sibcall_nonlocal_sysv<mode>"
11011169689Skan  [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
11012117395Skan	 (match_operand 1 "" ""))
11013117395Skan   (use (match_operand 2 "immediate_operand" "O,n"))
11014132718Skan   (use (match_operand:SI 3 "register_operand" "l,l"))
11015117395Skan   (return)]
11016117395Skan  "(DEFAULT_ABI == ABI_DARWIN
11017132718Skan     || DEFAULT_ABI == ABI_V4)
11018117395Skan   && (INTVAL (operands[2]) & CALL_LONG) == 0"
11019117395Skan  "*
11020117395Skan{
11021117395Skan  if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11022117395Skan    output_asm_insn (\"crxor 6,6,6\", operands);
11023117395Skan
11024117395Skan  else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11025117395Skan    output_asm_insn (\"creqv 6,6,6\", operands);
11026117395Skan
11027169689Skan  if (DEFAULT_ABI == ABI_V4 && flag_pic)
11028169689Skan    {
11029169689Skan      if (TARGET_SECURE_PLT && flag_pic == 2)
11030169689Skan	return \"b %z0+32768@plt\";
11031169689Skan      else
11032169689Skan	return \"b %z0@plt\";
11033169689Skan    }
11034169689Skan  else
11035169689Skan    return \"b %z0\";
11036117395Skan}"
11037117395Skan  [(set_attr "type" "branch,branch")
11038117395Skan   (set_attr "length" "4,8")])
11039117395Skan
11040117395Skan(define_expand "sibcall_value"
11041117395Skan  [(parallel [(set (match_operand 0 "register_operand" "")
11042117395Skan		(call (mem:SI (match_operand 1 "address_operand" ""))
11043117395Skan		      (match_operand 2 "" "")))
11044117395Skan	      (use (match_operand 3 "" ""))
11045132718Skan	      (use (match_operand 4 "" ""))
11046117395Skan	      (return)])]
11047117395Skan  ""
11048117395Skan  "
11049117395Skan{
11050117395Skan#if TARGET_MACHO
11051132718Skan  if (MACHOPIC_INDIRECT)
11052117395Skan    operands[1] = machopic_indirect_call_target (operands[1]);
11053117395Skan#endif
11054117395Skan
11055169689Skan  gcc_assert (GET_CODE (operands[1]) == MEM);
11056169689Skan  gcc_assert (GET_CODE (operands[2]) == CONST_INT);
11057117395Skan
11058117395Skan  operands[1] = XEXP (operands[1], 0);
11059132718Skan  operands[4] = gen_reg_rtx (SImode);
11060117395Skan
11061117395Skan}")
11062117395Skan
11063169689Skan(define_insn "*sibcall_value_nonlocal_sysv<mode>"
11064117395Skan  [(set (match_operand 0 "" "")
11065169689Skan	(call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
11066117395Skan	      (match_operand 2 "" "")))
11067117395Skan   (use (match_operand:SI 3 "immediate_operand" "O,n"))
11068132718Skan   (use (match_operand:SI 4 "register_operand" "l,l"))
11069117395Skan   (return)]
11070117395Skan  "(DEFAULT_ABI == ABI_DARWIN
11071132718Skan       || DEFAULT_ABI == ABI_V4)
11072117395Skan   && (INTVAL (operands[3]) & CALL_LONG) == 0"
11073117395Skan  "*
11074117395Skan{
11075117395Skan  if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11076117395Skan    output_asm_insn (\"crxor 6,6,6\", operands);
11077117395Skan
11078117395Skan  else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11079117395Skan    output_asm_insn (\"creqv 6,6,6\", operands);
11080117395Skan
11081169689Skan  if (DEFAULT_ABI == ABI_V4 && flag_pic)
11082169689Skan    {
11083169689Skan      if (TARGET_SECURE_PLT && flag_pic == 2)
11084169689Skan	return \"b %z1+32768@plt\";
11085169689Skan      else
11086169689Skan	return \"b %z1@plt\";
11087169689Skan    }
11088169689Skan  else
11089169689Skan    return \"b %z1\";
11090117395Skan}"
11091117395Skan  [(set_attr "type" "branch,branch")
11092117395Skan   (set_attr "length" "4,8")])
11093117395Skan
11094117395Skan(define_expand "sibcall_epilogue"
11095117395Skan  [(use (const_int 0))]
11096117395Skan  "TARGET_SCHED_PROLOG"
11097117395Skan  "
11098117395Skan{
11099117395Skan      rs6000_emit_epilogue (TRUE);
11100117395Skan      DONE;
11101117395Skan}")
11102117395Skan
1110390075Sobrien;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
1110490075Sobrien;; all of memory.  This blocks insns from being moved across this point.
1110590075Sobrien
1110690075Sobrien(define_insn "blockage"
11107132718Skan  [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
1110890075Sobrien  ""
1110990075Sobrien  "")
1111090075Sobrien
1111190075Sobrien;; Compare insns are next.  Note that the RS/6000 has two types of compares,
1111290075Sobrien;; signed & unsigned, and one type of branch.
1111390075Sobrien;;
1111490075Sobrien;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
1111590075Sobrien;; insns, and branches.  We store the operands of compares until we see
1111690075Sobrien;; how it is used.
11117169689Skan(define_expand "cmp<mode>"
1111890075Sobrien  [(set (cc0)
11119169689Skan        (compare (match_operand:GPR 0 "gpc_reg_operand" "")
11120169689Skan  		 (match_operand:GPR 1 "reg_or_short_operand" "")))]
1112190075Sobrien  ""
1112290075Sobrien  "
1112390075Sobrien{
1112490075Sobrien  /* Take care of the possibility that operands[1] might be negative but
1112590075Sobrien     this might be a logical operation.  That insn doesn't exist.  */
1112690075Sobrien  if (GET_CODE (operands[1]) == CONST_INT
1112790075Sobrien      && INTVAL (operands[1]) < 0)
11128169689Skan    operands[1] = force_reg (<MODE>mode, operands[1]);
1112990075Sobrien
1113090075Sobrien  rs6000_compare_op0 = operands[0];
1113190075Sobrien  rs6000_compare_op1 = operands[1];
1113290075Sobrien  rs6000_compare_fp_p = 0;
1113390075Sobrien  DONE;
1113490075Sobrien}")
1113590075Sobrien
11136169689Skan(define_expand "cmp<mode>"
11137169689Skan  [(set (cc0) (compare (match_operand:FP 0 "gpc_reg_operand" "")
11138169689Skan		       (match_operand:FP 1 "gpc_reg_operand" "")))]
11139169689Skan  ""
1114090075Sobrien  "
1114190075Sobrien{
1114290075Sobrien  rs6000_compare_op0 = operands[0];
1114390075Sobrien  rs6000_compare_op1 = operands[1];
1114490075Sobrien  rs6000_compare_fp_p = 1;
1114590075Sobrien  DONE;
1114690075Sobrien}")
1114790075Sobrien
1114890075Sobrien(define_expand "beq"
1114990075Sobrien  [(use (match_operand 0 "" ""))]
1115090075Sobrien  ""
1115190075Sobrien  "{ rs6000_emit_cbranch (EQ, operands[0]); DONE; }")
1115290075Sobrien
1115390075Sobrien(define_expand "bne"
1115490075Sobrien  [(use (match_operand 0 "" ""))]
1115590075Sobrien  ""
1115690075Sobrien  "{ rs6000_emit_cbranch (NE, operands[0]); DONE; }")
1115790075Sobrien
1115890075Sobrien(define_expand "bge"
1115990075Sobrien  [(use (match_operand 0 "" ""))]
1116090075Sobrien  ""
1116190075Sobrien  "{ rs6000_emit_cbranch (GE, operands[0]); DONE; }")
1116290075Sobrien
1116390075Sobrien(define_expand "bgt"
1116490075Sobrien  [(use (match_operand 0 "" ""))]
1116590075Sobrien  ""
1116690075Sobrien  "{ rs6000_emit_cbranch (GT, operands[0]); DONE; }")
1116790075Sobrien
1116890075Sobrien(define_expand "ble"
1116990075Sobrien  [(use (match_operand 0 "" ""))]
1117090075Sobrien  ""
1117190075Sobrien  "{ rs6000_emit_cbranch (LE, operands[0]); DONE; }")
1117290075Sobrien
1117390075Sobrien(define_expand "blt"
1117490075Sobrien  [(use (match_operand 0 "" ""))]
1117590075Sobrien  ""
1117690075Sobrien  "{ rs6000_emit_cbranch (LT, operands[0]); DONE; }")
1117790075Sobrien
1117890075Sobrien(define_expand "bgeu"
1117990075Sobrien  [(use (match_operand 0 "" ""))]
1118090075Sobrien  ""
1118190075Sobrien  "{ rs6000_emit_cbranch (GEU, operands[0]); DONE; }")
1118290075Sobrien
1118390075Sobrien(define_expand "bgtu"
1118490075Sobrien  [(use (match_operand 0 "" ""))]
1118590075Sobrien  ""
1118690075Sobrien  "{ rs6000_emit_cbranch (GTU, operands[0]); DONE; }")
1118790075Sobrien
1118890075Sobrien(define_expand "bleu"
1118990075Sobrien  [(use (match_operand 0 "" ""))]
1119090075Sobrien  ""
1119190075Sobrien  "{ rs6000_emit_cbranch (LEU, operands[0]); DONE; }")
1119290075Sobrien
1119390075Sobrien(define_expand "bltu"
1119490075Sobrien  [(use (match_operand 0 "" ""))]
1119590075Sobrien  ""
1119690075Sobrien  "{ rs6000_emit_cbranch (LTU, operands[0]); DONE; }")
1119790075Sobrien
1119890075Sobrien(define_expand "bunordered"
1119990075Sobrien  [(use (match_operand 0 "" ""))]
11200169689Skan  "! (TARGET_HARD_FLOAT && TARGET_E500 && !TARGET_FPRS)"
1120190075Sobrien  "{ rs6000_emit_cbranch (UNORDERED, operands[0]); DONE; }")
1120290075Sobrien
1120390075Sobrien(define_expand "bordered"
1120490075Sobrien  [(use (match_operand 0 "" ""))]
11205169689Skan  "! (TARGET_HARD_FLOAT && TARGET_E500 && !TARGET_FPRS)"
1120690075Sobrien  "{ rs6000_emit_cbranch (ORDERED, operands[0]); DONE; }")
1120790075Sobrien
1120890075Sobrien(define_expand "buneq"
1120990075Sobrien  [(use (match_operand 0 "" ""))]
1121090075Sobrien  ""
1121190075Sobrien  "{ rs6000_emit_cbranch (UNEQ, operands[0]); DONE; }")
1121290075Sobrien
1121390075Sobrien(define_expand "bunge"
1121490075Sobrien  [(use (match_operand 0 "" ""))]
1121590075Sobrien  ""
1121690075Sobrien  "{ rs6000_emit_cbranch (UNGE, operands[0]); DONE; }")
1121790075Sobrien
1121890075Sobrien(define_expand "bungt"
1121990075Sobrien  [(use (match_operand 0 "" ""))]
1122090075Sobrien  ""
1122190075Sobrien  "{ rs6000_emit_cbranch (UNGT, operands[0]); DONE; }")
1122290075Sobrien
1122390075Sobrien(define_expand "bunle"
1122490075Sobrien  [(use (match_operand 0 "" ""))]
1122590075Sobrien  ""
1122690075Sobrien  "{ rs6000_emit_cbranch (UNLE, operands[0]); DONE; }")
1122790075Sobrien
1122890075Sobrien(define_expand "bunlt"
1122990075Sobrien  [(use (match_operand 0 "" ""))]
1123090075Sobrien  ""
1123190075Sobrien  "{ rs6000_emit_cbranch (UNLT, operands[0]); DONE; }")
1123290075Sobrien
1123390075Sobrien(define_expand "bltgt"
1123490075Sobrien  [(use (match_operand 0 "" ""))]
1123590075Sobrien  ""
1123690075Sobrien  "{ rs6000_emit_cbranch (LTGT, operands[0]); DONE; }")
1123790075Sobrien
1123890075Sobrien;; For SNE, we would prefer that the xor/abs sequence be used for integers.
1123990075Sobrien;; For SEQ, likewise, except that comparisons with zero should be done
1124090075Sobrien;; with an scc insns.  However, due to the order that combine see the
1124190075Sobrien;; resulting insns, we must, in fact, allow SEQ for integers.  Fail in
1124290075Sobrien;; the cases we don't want to handle.
1124390075Sobrien(define_expand "seq"
1124490075Sobrien  [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
1124590075Sobrien  ""
1124690075Sobrien  "{ rs6000_emit_sCOND (EQ, operands[0]); DONE; }")
1124790075Sobrien
1124890075Sobrien(define_expand "sne"
1124990075Sobrien  [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
1125090075Sobrien  ""
1125190075Sobrien  "
11252169689Skan{
1125390075Sobrien  if (! rs6000_compare_fp_p)
1125490075Sobrien    FAIL;
1125590075Sobrien
11256169689Skan  rs6000_emit_sCOND (NE, operands[0]);
1125790075Sobrien  DONE;
1125890075Sobrien}")
1125990075Sobrien
11260132718Skan;; A >= 0 is best done the portable way for A an integer.
11261132718Skan(define_expand "sge"
1126290075Sobrien  [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
1126390075Sobrien  ""
1126490075Sobrien  "
1126590075Sobrien{
11266169689Skan  if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx)
1126790075Sobrien    FAIL;
1126890075Sobrien
11269132718Skan  rs6000_emit_sCOND (GE, operands[0]);
1127090075Sobrien  DONE;
1127190075Sobrien}")
1127290075Sobrien
11273132718Skan;; A > 0 is best done using the portable sequence, so fail in that case.
11274132718Skan(define_expand "sgt"
1127590075Sobrien  [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
1127690075Sobrien  ""
1127790075Sobrien  "
1127890075Sobrien{
11279169689Skan  if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx)
1128090075Sobrien    FAIL;
1128190075Sobrien
11282169689Skan  rs6000_emit_sCOND (GT, operands[0]);
1128390075Sobrien  DONE;
1128490075Sobrien}")
1128590075Sobrien
11286132718Skan;; A <= 0 is best done the portable way for A an integer.
11287132718Skan(define_expand "sle"
1128890075Sobrien  [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
1128990075Sobrien  ""
1129090075Sobrien  "
1129190075Sobrien{
11292169689Skan  if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx)
1129390075Sobrien    FAIL;
1129490075Sobrien
11295169689Skan  rs6000_emit_sCOND (LE, operands[0]);
1129690075Sobrien  DONE;
1129790075Sobrien}")
1129890075Sobrien
11299132718Skan;; A < 0 is best done in the portable way for A an integer.
11300132718Skan(define_expand "slt"
1130190075Sobrien  [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
1130290075Sobrien  ""
1130390075Sobrien  "
1130490075Sobrien{
11305169689Skan  if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx)
1130690075Sobrien    FAIL;
1130790075Sobrien
11308169689Skan  rs6000_emit_sCOND (LT, operands[0]);
1130990075Sobrien  DONE;
1131090075Sobrien}")
1131190075Sobrien
11312132718Skan(define_expand "sgeu"
11313132718Skan  [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
11314132718Skan  ""
11315132718Skan  "{ rs6000_emit_sCOND (GEU, operands[0]); DONE; }")
11316132718Skan
1131790075Sobrien(define_expand "sgtu"
1131890075Sobrien  [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
1131990075Sobrien  ""
1132090075Sobrien  "{ rs6000_emit_sCOND (GTU, operands[0]); DONE; }")
1132190075Sobrien
11322132718Skan(define_expand "sleu"
11323132718Skan  [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
11324132718Skan  ""
11325132718Skan  "{ rs6000_emit_sCOND (LEU, operands[0]); DONE; }")
11326132718Skan
1132790075Sobrien(define_expand "sltu"
1132890075Sobrien  [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
1132990075Sobrien  ""
1133090075Sobrien  "{ rs6000_emit_sCOND (LTU, operands[0]); DONE; }")
1133190075Sobrien
11332132718Skan(define_expand "sunordered"
1133390075Sobrien  [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
11334169689Skan  "! (TARGET_HARD_FLOAT && TARGET_E500 && !TARGET_FPRS)"
11335132718Skan  "{ rs6000_emit_sCOND (UNORDERED, operands[0]); DONE; }")
1133690075Sobrien
11337132718Skan(define_expand "sordered"
1133890075Sobrien  [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
11339169689Skan  "! (TARGET_HARD_FLOAT && TARGET_E500 && !TARGET_FPRS)"
11340132718Skan  "{ rs6000_emit_sCOND (ORDERED, operands[0]); DONE; }")
11341132718Skan
11342132718Skan(define_expand "suneq"
11343132718Skan  [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
11344132718Skan  ""
11345132718Skan  "{ rs6000_emit_sCOND (UNEQ, operands[0]); DONE; }")
11346132718Skan
11347132718Skan(define_expand "sunge"
11348132718Skan  [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
11349132718Skan  ""
11350132718Skan  "{ rs6000_emit_sCOND (UNGE, operands[0]); DONE; }")
11351132718Skan
11352132718Skan(define_expand "sungt"
11353132718Skan  [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
11354132718Skan  ""
11355132718Skan  "{ rs6000_emit_sCOND (UNGT, operands[0]); DONE; }")
11356132718Skan
11357132718Skan(define_expand "sunle"
11358132718Skan  [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
11359132718Skan  ""
11360132718Skan  "{ rs6000_emit_sCOND (UNLE, operands[0]); DONE; }")
11361132718Skan
11362132718Skan(define_expand "sunlt"
11363132718Skan  [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
11364132718Skan  ""
11365132718Skan  "{ rs6000_emit_sCOND (UNLT, operands[0]); DONE; }")
11366132718Skan
11367132718Skan(define_expand "sltgt"
11368132718Skan  [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
11369132718Skan  ""
11370132718Skan  "{ rs6000_emit_sCOND (LTGT, operands[0]); DONE; }")
11371132718Skan
11372169689Skan(define_expand "stack_protect_set"
11373169689Skan  [(match_operand 0 "memory_operand" "")
11374169689Skan   (match_operand 1 "memory_operand" "")]
11375169689Skan  ""
11376169689Skan{
11377169689Skan#ifdef TARGET_THREAD_SSP_OFFSET
11378169689Skan  rtx tlsreg = gen_rtx_REG (Pmode, TARGET_64BIT ? 13 : 2);
11379169689Skan  rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
11380169689Skan  operands[1] = gen_rtx_MEM (Pmode, addr);
11381169689Skan#endif
11382169689Skan  if (TARGET_64BIT)
11383169689Skan    emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
11384169689Skan  else
11385169689Skan    emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
11386169689Skan  DONE;
11387169689Skan})
11388169689Skan
11389169689Skan(define_insn "stack_protect_setsi"
11390169689Skan  [(set (match_operand:SI 0 "memory_operand" "=m")
11391169689Skan	(unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
11392169689Skan   (set (match_scratch:SI 2 "=&r") (const_int 0))]
11393169689Skan  "TARGET_32BIT"
11394169689Skan  "{l%U1%X1|lwz%U1%X1} %2,%1\;{st%U0%X0|stw%U0%X0} %2,%0\;{lil|li} %2,0"
11395169689Skan  [(set_attr "type" "three")
11396169689Skan   (set_attr "length" "12")])
11397169689Skan
11398169689Skan(define_insn "stack_protect_setdi"
11399169689Skan  [(set (match_operand:DI 0 "memory_operand" "=m")
11400169689Skan	(unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
11401169689Skan   (set (match_scratch:DI 2 "=&r") (const_int 0))]
11402169689Skan  "TARGET_64BIT"
11403169689Skan  "ld%U1%X1 %2,%1\;std%U0%X0 %2,%0\;{lil|li} %2,0"
11404169689Skan  [(set_attr "type" "three")
11405169689Skan   (set_attr "length" "12")])
11406169689Skan
11407169689Skan(define_expand "stack_protect_test"
11408169689Skan  [(match_operand 0 "memory_operand" "")
11409169689Skan   (match_operand 1 "memory_operand" "")
11410169689Skan   (match_operand 2 "" "")]
11411169689Skan  ""
11412169689Skan{
11413169689Skan#ifdef TARGET_THREAD_SSP_OFFSET
11414169689Skan  rtx tlsreg = gen_rtx_REG (Pmode, TARGET_64BIT ? 13 : 2);
11415169689Skan  rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET));
11416169689Skan  operands[1] = gen_rtx_MEM (Pmode, addr);
11417169689Skan#endif
11418169689Skan  rs6000_compare_op0 = operands[0];
11419169689Skan  rs6000_compare_op1 = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, operands[1]),
11420169689Skan				       UNSPEC_SP_TEST);
11421169689Skan  rs6000_compare_fp_p = 0;
11422169689Skan  emit_jump_insn (gen_beq (operands[2]));
11423169689Skan  DONE;
11424169689Skan})
11425169689Skan
11426169689Skan(define_insn "stack_protect_testsi"
11427169689Skan  [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11428169689Skan        (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
11429169689Skan		      (match_operand:SI 2 "memory_operand" "m,m")]
11430169689Skan		     UNSPEC_SP_TEST))
11431169689Skan   (set (match_scratch:SI 4 "=r,r") (const_int 0))
11432169689Skan   (clobber (match_scratch:SI 3 "=&r,&r"))]
11433169689Skan  "TARGET_32BIT"
11434169689Skan  "@
11435169689Skan   {l%U1%X1|lwz%U1%X1} %3,%1\;{l%U2%X2|lwz%U2%X2} %4,%2\;xor. %3,%3,%4\;{lil|li} %4,0
11436169689Skan   {l%U1%X1|lwz%U1%X1} %3,%1\;{l%U2%X2|lwz%U2%X2} %4,%2\;{cmpl|cmplw} %0,%3,%4\;{lil|li} %3,0\;{lil|li} %4,0"
11437169689Skan  [(set_attr "length" "16,20")])
11438169689Skan
11439169689Skan(define_insn "stack_protect_testdi"
11440169689Skan  [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11441169689Skan        (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "m,m")
11442169689Skan		      (match_operand:DI 2 "memory_operand" "m,m")]
11443169689Skan		     UNSPEC_SP_TEST))
11444169689Skan   (set (match_scratch:DI 4 "=r,r") (const_int 0))
11445169689Skan   (clobber (match_scratch:DI 3 "=&r,&r"))]
11446169689Skan  "TARGET_64BIT"
11447169689Skan  "@
11448169689Skan   ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;xor. %3,%3,%4\;{lil|li} %4,0
11449169689Skan   ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;cmpld %0,%3,%4\;{lil|li} %3,0\;{lil|li} %4,0"
11450169689Skan  [(set_attr "length" "16,20")])
11451169689Skan
1145290075Sobrien
1145390075Sobrien;; Here are the actual compare insns.
11454169689Skan(define_insn "*cmp<mode>_internal1"
1145590075Sobrien  [(set (match_operand:CC 0 "cc_reg_operand" "=y")
11456169689Skan	(compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
11457169689Skan		    (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
1145890075Sobrien  ""
11459169689Skan  "{cmp%I2|cmp<wd>%I2} %0,%1,%2"
11460132718Skan  [(set_attr "type" "cmp")])
1146190075Sobrien
1146290075Sobrien;; If we are comparing a register for equality with a large constant,
11463169689Skan;; we can do this with an XOR followed by a compare.  But this is profitable
11464169689Skan;; only if the large constant is only used for the comparison (and in this
11465169689Skan;; case we already have a register to reuse as scratch).
11466169689Skan;;
11467169689Skan;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
11468169689Skan;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
1146990075Sobrien
11470169689Skan(define_peephole2
11471169689Skan  [(set (match_operand:SI 0 "register_operand")
11472169689Skan        (match_operand:SI 1 "logical_const_operand" ""))
11473169689Skan   (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
11474169689Skan		       [(match_dup 0)
11475169689Skan			(match_operand:SI 2 "logical_const_operand" "")]))
11476169689Skan   (set (match_operand:CC 4 "cc_reg_operand" "")
11477169689Skan        (compare:CC (match_operand:SI 5 "gpc_reg_operand" "")
11478169689Skan                    (match_dup 0)))
11479169689Skan   (set (pc)
11480169689Skan        (if_then_else (match_operator 6 "equality_operator"
11481169689Skan                       [(match_dup 4) (const_int 0)])
11482169689Skan                      (match_operand 7 "" "")
11483169689Skan                      (match_operand 8 "" "")))]
11484169689Skan  "peep2_reg_dead_p (3, operands[0])
11485169689Skan   && peep2_reg_dead_p (4, operands[4])"
11486169689Skan [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
11487169689Skan  (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
11488169689Skan  (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
11489169689Skan 
1149090075Sobrien{
11491169689Skan  /* Get the constant we are comparing against, and see what it looks like
11492169689Skan     when sign-extended from 16 to 32 bits.  Then see what constant we could
11493169689Skan     XOR with SEXTC to get the sign-extended value.  */
11494169689Skan  rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
11495169689Skan					      SImode,
11496169689Skan					      operands[1], operands[2]);
11497169689Skan  HOST_WIDE_INT c = INTVAL (cnst);
11498117395Skan  HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
1149990075Sobrien  HOST_WIDE_INT xorv = c ^ sextc;
1150090075Sobrien
11501169689Skan  operands[9] = GEN_INT (xorv);
11502169689Skan  operands[10] = GEN_INT (sextc);
11503169689Skan})
1150490075Sobrien
1150590075Sobrien(define_insn "*cmpsi_internal2"
1150690075Sobrien  [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
1150790075Sobrien	(compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
1150890075Sobrien		       (match_operand:SI 2 "reg_or_u_short_operand" "rK")))]
1150990075Sobrien  ""
1151090075Sobrien  "{cmpl%I2|cmplw%I2} %0,%1,%b2"
11511132718Skan  [(set_attr "type" "cmp")])
1151290075Sobrien
1151390075Sobrien(define_insn "*cmpdi_internal2"
1151490075Sobrien  [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
1151590075Sobrien	(compare:CCUNS (match_operand:DI 1 "gpc_reg_operand" "r")
1151690075Sobrien		       (match_operand:DI 2 "reg_or_u_short_operand" "rK")))]
1151790075Sobrien  ""
1151890075Sobrien  "cmpld%I2 %0,%1,%b2"
11519132718Skan  [(set_attr "type" "cmp")])
1152090075Sobrien
1152190075Sobrien;; The following two insns don't exist as single insns, but if we provide
1152290075Sobrien;; them, we can swap an add and compare, which will enable us to overlap more
1152390075Sobrien;; of the required delay between a compare and branch.  We generate code for
1152490075Sobrien;; them by splitting.
1152590075Sobrien
1152690075Sobrien(define_insn ""
1152790075Sobrien  [(set (match_operand:CC 3 "cc_reg_operand" "=y")
1152890075Sobrien	(compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
1152990075Sobrien		    (match_operand:SI 2 "short_cint_operand" "i")))
1153090075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1153190075Sobrien	(plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
1153290075Sobrien  ""
1153390075Sobrien  "#"
1153490075Sobrien  [(set_attr "length" "8")])
1153590075Sobrien
1153690075Sobrien(define_insn ""
1153790075Sobrien  [(set (match_operand:CCUNS 3 "cc_reg_operand" "=y")
1153890075Sobrien	(compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
1153990075Sobrien		       (match_operand:SI 2 "u_short_cint_operand" "i")))
1154090075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1154190075Sobrien	(plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
1154290075Sobrien  ""
1154390075Sobrien  "#"
1154490075Sobrien  [(set_attr "length" "8")])
1154590075Sobrien
1154690075Sobrien(define_split
1154790075Sobrien  [(set (match_operand:CC 3 "cc_reg_operand" "")
1154890075Sobrien	(compare:CC (match_operand:SI 1 "gpc_reg_operand" "")
1154990075Sobrien		    (match_operand:SI 2 "short_cint_operand" "")))
1155090075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "")
1155190075Sobrien	(plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
1155290075Sobrien  ""
1155390075Sobrien  [(set (match_dup 3) (compare:CC (match_dup 1) (match_dup 2)))
1155490075Sobrien   (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
1155590075Sobrien
1155690075Sobrien(define_split
1155790075Sobrien  [(set (match_operand:CCUNS 3 "cc_reg_operand" "")
1155890075Sobrien	(compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "")
1155990075Sobrien		       (match_operand:SI 2 "u_short_cint_operand" "")))
1156090075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "")
1156190075Sobrien	(plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
1156290075Sobrien  ""
1156390075Sobrien  [(set (match_dup 3) (compare:CCUNS (match_dup 1) (match_dup 2)))
1156490075Sobrien   (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
1156590075Sobrien
1156690075Sobrien(define_insn "*cmpsf_internal1"
1156790075Sobrien  [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
1156890075Sobrien	(compare:CCFP (match_operand:SF 1 "gpc_reg_operand" "f")
1156990075Sobrien		      (match_operand:SF 2 "gpc_reg_operand" "f")))]
11570117395Skan  "TARGET_HARD_FLOAT && TARGET_FPRS"
1157190075Sobrien  "fcmpu %0,%1,%2"
1157290075Sobrien  [(set_attr "type" "fpcompare")])
1157390075Sobrien
1157490075Sobrien(define_insn "*cmpdf_internal1"
1157590075Sobrien  [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
1157690075Sobrien	(compare:CCFP (match_operand:DF 1 "gpc_reg_operand" "f")
1157790075Sobrien		      (match_operand:DF 2 "gpc_reg_operand" "f")))]
11578117395Skan  "TARGET_HARD_FLOAT && TARGET_FPRS"
1157990075Sobrien  "fcmpu %0,%1,%2"
1158090075Sobrien  [(set_attr "type" "fpcompare")])
1158190075Sobrien
1158290075Sobrien;; Only need to compare second words if first words equal
1158390075Sobrien(define_insn "*cmptf_internal1"
1158490075Sobrien  [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
1158590075Sobrien	(compare:CCFP (match_operand:TF 1 "gpc_reg_operand" "f")
1158690075Sobrien		      (match_operand:TF 2 "gpc_reg_operand" "f")))]
11587169689Skan  "!TARGET_IEEEQUAD && !TARGET_XL_COMPAT
11588132718Skan   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
11589132718Skan  "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
1159090075Sobrien  [(set_attr "type" "fpcompare")
1159190075Sobrien   (set_attr "length" "12")])
11592146895Skan
11593146895Skan(define_insn_and_split "*cmptf_internal2"
11594146895Skan  [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11595146895Skan	(compare:CCFP (match_operand:TF 1 "gpc_reg_operand" "f")
11596146895Skan		      (match_operand:TF 2 "gpc_reg_operand" "f")))
11597146895Skan    (clobber (match_scratch:DF 3 "=f"))
11598146895Skan    (clobber (match_scratch:DF 4 "=f"))
11599146895Skan    (clobber (match_scratch:DF 5 "=f"))
11600146895Skan    (clobber (match_scratch:DF 6 "=f"))
11601146895Skan    (clobber (match_scratch:DF 7 "=f"))
11602146895Skan    (clobber (match_scratch:DF 8 "=f"))
11603146895Skan    (clobber (match_scratch:DF 9 "=f"))
11604146895Skan    (clobber (match_scratch:DF 10 "=f"))]
11605169689Skan  "!TARGET_IEEEQUAD && TARGET_XL_COMPAT
11606146895Skan   && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
11607146895Skan  "#"
11608146895Skan  "&& reload_completed"
11609146895Skan  [(set (match_dup 3) (match_dup 13))
11610146895Skan   (set (match_dup 4) (match_dup 14))
11611146895Skan   (set (match_dup 9) (abs:DF (match_dup 5)))
11612146895Skan   (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
11613146895Skan   (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
11614146895Skan			   (label_ref (match_dup 11))
11615146895Skan			   (pc)))
11616146895Skan   (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
11617146895Skan   (set (pc) (label_ref (match_dup 12)))
11618146895Skan   (match_dup 11)
11619146895Skan   (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
11620146895Skan   (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
11621146895Skan   (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
11622146895Skan   (set (match_dup 0) (compare:CCFP (match_dup 7) (match_dup 4)))
11623146895Skan   (match_dup 12)]
11624146895Skan{
11625146895Skan  REAL_VALUE_TYPE rv;
11626146895Skan  const int lo_word = FLOAT_WORDS_BIG_ENDIAN ? GET_MODE_SIZE (DFmode) : 0;
11627146895Skan  const int hi_word = FLOAT_WORDS_BIG_ENDIAN ? 0 : GET_MODE_SIZE (DFmode);
11628146895Skan
11629146895Skan  operands[5] = simplify_gen_subreg (DFmode, operands[1], TFmode, hi_word);
11630146895Skan  operands[6] = simplify_gen_subreg (DFmode, operands[1], TFmode, lo_word);
11631146895Skan  operands[7] = simplify_gen_subreg (DFmode, operands[2], TFmode, hi_word);
11632146895Skan  operands[8] = simplify_gen_subreg (DFmode, operands[2], TFmode, lo_word);
11633146895Skan  operands[11] = gen_label_rtx ();
11634146895Skan  operands[12] = gen_label_rtx ();
11635146895Skan  real_inf (&rv);
11636146895Skan  operands[13] = force_const_mem (DFmode,
11637146895Skan				  CONST_DOUBLE_FROM_REAL_VALUE (rv, DFmode));
11638146895Skan  operands[14] = force_const_mem (DFmode,
11639146895Skan				  CONST_DOUBLE_FROM_REAL_VALUE (dconst0,
11640146895Skan								DFmode));
11641146895Skan  if (TARGET_TOC)
11642146895Skan    {
11643169689Skan      operands[13] = gen_const_mem (DFmode,
11644169689Skan				    create_TOC_reference (XEXP (operands[13], 0)));
11645169689Skan      operands[14] = gen_const_mem (DFmode,
11646169689Skan				    create_TOC_reference (XEXP (operands[14], 0)));
11647146895Skan      set_mem_alias_set (operands[13], get_TOC_alias_set ());
11648146895Skan      set_mem_alias_set (operands[14], get_TOC_alias_set ());
11649146895Skan    }
11650146895Skan})
1165190075Sobrien
1165290075Sobrien;; Now we have the scc insns.  We can do some combinations because of the
1165390075Sobrien;; way the machine works.
1165490075Sobrien;;
1165590075Sobrien;; Note that this is probably faster if we can put an insn between the
1165690075Sobrien;; mfcr and rlinm, but this is tricky.  Let's leave it for now.  In most
1165790075Sobrien;; cases the insns below which don't use an intermediate CR field will
1165890075Sobrien;; be used instead.
1165990075Sobrien(define_insn ""
1166090075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1166190075Sobrien	(match_operator:SI 1 "scc_comparison_operator"
1166290075Sobrien			   [(match_operand 2 "cc_reg_operand" "y")
1166390075Sobrien			    (const_int 0)]))]
1166490075Sobrien  ""
11665132718Skan  "mfcr %0%Q2\;{rlinm|rlwinm} %0,%0,%J1,1"
11666132718Skan  [(set (attr "type")
11667132718Skan     (cond [(ne (symbol_ref "TARGET_MFCRF") (const_int 0))
11668132718Skan		(const_string "mfcrf")
11669132718Skan	   ]
11670132718Skan	(const_string "mfcr")))
11671169689Skan   (set_attr "length" "8")])
11672117395Skan
11673169689Skan;; Same as above, but get the GT bit.
11674169689Skan(define_insn "move_from_CR_gt_bit"
11675132718Skan  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11676169689Skan	(unspec:SI [(match_operand 1 "cc_reg_operand" "y")] UNSPEC_MV_CR_GT))]
11677132718Skan  "TARGET_E500"
11678169689Skan  "mfcr %0\;{rlinm|rlwinm} %0,%0,%D1,31,31"
11679132718Skan  [(set_attr "type" "mfcr")
11680169689Skan   (set_attr "length" "8")])
11681132718Skan
11682117395Skan;; Same as above, but get the OV/ORDERED bit.
11683117395Skan(define_insn "move_from_CR_ov_bit"
11684117395Skan  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11685132718Skan	(unspec:SI [(match_operand 1 "cc_reg_operand" "y")] UNSPEC_MV_CR_OV))]
11686117395Skan  "TARGET_ISEL"
11687132718Skan  "mfcr %0\;{rlinm|rlwinm} %0,%0,%t1,1"
11688132718Skan  [(set_attr "type" "mfcr")
11689169689Skan   (set_attr "length" "8")])
1169090075Sobrien
1169190075Sobrien(define_insn ""
1169290075Sobrien  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
1169390075Sobrien	(match_operator:DI 1 "scc_comparison_operator"
1169490075Sobrien			   [(match_operand 2 "cc_reg_operand" "y")
1169590075Sobrien			    (const_int 0)]))]
1169690075Sobrien  "TARGET_POWERPC64"
11697132718Skan  "mfcr %0%Q2\;{rlinm|rlwinm} %0,%0,%J1,1"
11698132718Skan  [(set (attr "type")
11699132718Skan     (cond [(ne (symbol_ref "TARGET_MFCRF") (const_int 0))
11700132718Skan		(const_string "mfcrf")
11701132718Skan	   ]
11702132718Skan	(const_string "mfcr")))
11703169689Skan   (set_attr "length" "8")])
1170490075Sobrien
1170590075Sobrien(define_insn ""
1170690075Sobrien  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
1170790075Sobrien	(compare:CC (match_operator:SI 1 "scc_comparison_operator"
1170890075Sobrien				       [(match_operand 2 "cc_reg_operand" "y,y")
1170990075Sobrien					(const_int 0)])
1171090075Sobrien		    (const_int 0)))
1171190075Sobrien   (set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
1171290075Sobrien	(match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11713132718Skan  "TARGET_32BIT"
1171490075Sobrien  "@
11715132718Skan   mfcr %3%Q2\;{rlinm.|rlwinm.} %3,%3,%J1,1
1171690075Sobrien   #"
1171790075Sobrien  [(set_attr "type" "delayed_compare")
11718169689Skan   (set_attr "length" "8,16")])
1171990075Sobrien
1172090075Sobrien(define_split
1172190075Sobrien  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
1172290075Sobrien	(compare:CC (match_operator:SI 1 "scc_comparison_operator"
1172390075Sobrien				       [(match_operand 2 "cc_reg_operand" "")
1172490075Sobrien					(const_int 0)])
1172590075Sobrien		    (const_int 0)))
1172690075Sobrien   (set (match_operand:SI 3 "gpc_reg_operand" "")
1172790075Sobrien	(match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11728132718Skan  "TARGET_32BIT && reload_completed"
1172990075Sobrien  [(set (match_dup 3)
1173090075Sobrien	(match_op_dup 1 [(match_dup 2) (const_int 0)]))
1173190075Sobrien   (set (match_dup 0)
1173290075Sobrien	(compare:CC (match_dup 3)
1173390075Sobrien		    (const_int 0)))]
1173490075Sobrien  "")
1173590075Sobrien
1173690075Sobrien(define_insn ""
1173790075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1173890075Sobrien	(ashift:SI (match_operator:SI 1 "scc_comparison_operator"
1173990075Sobrien				      [(match_operand 2 "cc_reg_operand" "y")
1174090075Sobrien				       (const_int 0)])
1174190075Sobrien		   (match_operand:SI 3 "const_int_operand" "n")))]
1174290075Sobrien  ""
1174390075Sobrien  "*
1174490075Sobrien{
1174590075Sobrien  int is_bit = ccr_bit (operands[1], 1);
1174690075Sobrien  int put_bit = 31 - (INTVAL (operands[3]) & 31);
1174790075Sobrien  int count;
1174890075Sobrien
1174990075Sobrien  if (is_bit >= put_bit)
1175090075Sobrien    count = is_bit - put_bit;
1175190075Sobrien  else
1175290075Sobrien    count = 32 - (put_bit - is_bit);
1175390075Sobrien
1175490075Sobrien  operands[4] = GEN_INT (count);
1175590075Sobrien  operands[5] = GEN_INT (put_bit);
1175690075Sobrien
11757132718Skan  return \"mfcr %0%Q2\;{rlinm|rlwinm} %0,%0,%4,%5,%5\";
1175890075Sobrien}"
11759132718Skan  [(set (attr "type")
11760132718Skan     (cond [(ne (symbol_ref "TARGET_MFCRF") (const_int 0))
11761132718Skan		(const_string "mfcrf")
11762132718Skan	   ]
11763132718Skan	(const_string "mfcr")))
11764169689Skan   (set_attr "length" "8")])
1176590075Sobrien
1176690075Sobrien(define_insn ""
1176790075Sobrien  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
1176890075Sobrien	(compare:CC
1176990075Sobrien	 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
1177090075Sobrien				       [(match_operand 2 "cc_reg_operand" "y,y")
1177190075Sobrien					(const_int 0)])
1177290075Sobrien		    (match_operand:SI 3 "const_int_operand" "n,n"))
1177390075Sobrien	 (const_int 0)))
1177490075Sobrien   (set (match_operand:SI 4 "gpc_reg_operand" "=r,r")
1177590075Sobrien	(ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
1177690075Sobrien		   (match_dup 3)))]
11777117395Skan  ""
1177890075Sobrien  "*
1177990075Sobrien{
1178090075Sobrien  int is_bit = ccr_bit (operands[1], 1);
1178190075Sobrien  int put_bit = 31 - (INTVAL (operands[3]) & 31);
1178290075Sobrien  int count;
1178390075Sobrien
1178490075Sobrien  /* Force split for non-cc0 compare.  */
1178590075Sobrien  if (which_alternative == 1)
1178690075Sobrien     return \"#\";
1178790075Sobrien
1178890075Sobrien  if (is_bit >= put_bit)
1178990075Sobrien    count = is_bit - put_bit;
1179090075Sobrien  else
1179190075Sobrien    count = 32 - (put_bit - is_bit);
1179290075Sobrien
1179390075Sobrien  operands[5] = GEN_INT (count);
1179490075Sobrien  operands[6] = GEN_INT (put_bit);
1179590075Sobrien
11796132718Skan  return \"mfcr %4%Q2\;{rlinm.|rlwinm.} %4,%4,%5,%6,%6\";
1179790075Sobrien}"
1179890075Sobrien  [(set_attr "type" "delayed_compare")
11799169689Skan   (set_attr "length" "8,16")])
1180090075Sobrien
1180190075Sobrien(define_split
1180290075Sobrien  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
1180390075Sobrien	(compare:CC
1180490075Sobrien	 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
1180590075Sobrien				       [(match_operand 2 "cc_reg_operand" "")
1180690075Sobrien					(const_int 0)])
1180790075Sobrien		    (match_operand:SI 3 "const_int_operand" ""))
1180890075Sobrien	 (const_int 0)))
1180990075Sobrien   (set (match_operand:SI 4 "gpc_reg_operand" "")
1181090075Sobrien	(ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
1181190075Sobrien		   (match_dup 3)))]
11812117395Skan  "reload_completed"
1181390075Sobrien  [(set (match_dup 4)
1181490075Sobrien	(ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
1181590075Sobrien		   (match_dup 3)))
1181690075Sobrien   (set (match_dup 0)
1181790075Sobrien	(compare:CC (match_dup 4)
1181890075Sobrien		    (const_int 0)))]
1181990075Sobrien  "")
1182090075Sobrien
1182190075Sobrien;; There is a 3 cycle delay between consecutive mfcr instructions
1182290075Sobrien;; so it is useful to combine 2 scc instructions to use only one mfcr.
1182390075Sobrien
1182490075Sobrien(define_peephole
1182590075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1182690075Sobrien	(match_operator:SI 1 "scc_comparison_operator"
1182790075Sobrien			   [(match_operand 2 "cc_reg_operand" "y")
1182890075Sobrien			    (const_int 0)]))
1182990075Sobrien   (set (match_operand:SI 3 "gpc_reg_operand" "=r")
1183090075Sobrien	(match_operator:SI 4 "scc_comparison_operator"
1183190075Sobrien			   [(match_operand 5 "cc_reg_operand" "y")
1183290075Sobrien			    (const_int 0)]))]
11833117395Skan  "REGNO (operands[2]) != REGNO (operands[5])"
11834132718Skan  "mfcr %3\;{rlinm|rlwinm} %0,%3,%J1,1\;{rlinm|rlwinm} %3,%3,%J4,1"
11835132718Skan  [(set_attr "type" "mfcr")
11836169689Skan   (set_attr "length" "12")])
1183790075Sobrien
1183890075Sobrien(define_peephole
1183990075Sobrien  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
1184090075Sobrien	(match_operator:DI 1 "scc_comparison_operator"
1184190075Sobrien			   [(match_operand 2 "cc_reg_operand" "y")
1184290075Sobrien			    (const_int 0)]))
1184390075Sobrien   (set (match_operand:DI 3 "gpc_reg_operand" "=r")
1184490075Sobrien	(match_operator:DI 4 "scc_comparison_operator"
1184590075Sobrien			   [(match_operand 5 "cc_reg_operand" "y")
1184690075Sobrien			    (const_int 0)]))]
11847117395Skan  "TARGET_POWERPC64 && REGNO (operands[2]) != REGNO (operands[5])"
11848132718Skan  "mfcr %3\;{rlinm|rlwinm} %0,%3,%J1,1\;{rlinm|rlwinm} %3,%3,%J4,1"
11849132718Skan  [(set_attr "type" "mfcr")
11850169689Skan   (set_attr "length" "12")])
1185190075Sobrien
1185290075Sobrien;; There are some scc insns that can be done directly, without a compare.
1185390075Sobrien;; These are faster because they don't involve the communications between
1185490075Sobrien;; the FXU and branch units.   In fact, we will be replacing all of the
1185590075Sobrien;; integer scc insns here or in the portable methods in emit_store_flag.
1185690075Sobrien;;
1185790075Sobrien;; Also support (neg (scc ..)) since that construct is used to replace
1185890075Sobrien;; branches, (plus (scc ..) ..) since that construct is common and
1185990075Sobrien;; takes no more insns than scc, and (and (neg (scc ..)) ..) in the
1186090075Sobrien;; cases where it is no more expensive than (neg (scc ..)).
1186190075Sobrien
1186290075Sobrien;; Have reload force a constant into a register for the simple insns that
1186390075Sobrien;; otherwise won't accept constants.  We do this because it is faster than
1186490075Sobrien;; the cmp/mfcr sequence we would otherwise generate.
1186590075Sobrien
11866169689Skan(define_mode_attr scc_eq_op2 [(SI "rKLI")
11867169689Skan			      (DI "rKJI")])
11868169689Skan
11869169689Skan(define_insn_and_split "*eq<mode>"
11870169689Skan  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11871169689Skan	(eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
11872169689Skan		(match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))]
11873169689Skan  "!TARGET_POWER"
11874169689Skan  "#"
11875169689Skan  "!TARGET_POWER"
11876169689Skan  [(set (match_dup 0)
11877169689Skan	(clz:GPR (match_dup 3)))
11878169689Skan   (set (match_dup 0)
11879169689Skan	(lshiftrt:GPR (match_dup 0) (match_dup 4)))]
11880169689Skan  {
11881169689Skan    if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)
11882169689Skan      {
11883169689Skan	/* Use output operand as intermediate.  */
11884169689Skan	operands[3] = operands[0];
11885169689Skan
11886169689Skan	if (logical_operand (operands[2], <MODE>mode))
11887169689Skan	  emit_insn (gen_rtx_SET (VOIDmode, operands[3],
11888169689Skan				  gen_rtx_XOR (<MODE>mode,
11889169689Skan					       operands[1], operands[2])));
11890169689Skan	else
11891169689Skan	  emit_insn (gen_rtx_SET (VOIDmode, operands[3],
11892169689Skan				  gen_rtx_PLUS (<MODE>mode, operands[1],
11893169689Skan						negate_rtx (<MODE>mode,
11894169689Skan							    operands[2]))));
11895169689Skan      }
11896169689Skan    else
11897169689Skan      operands[3] = operands[1];
11898169689Skan
11899169689Skan    operands[4] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
11900169689Skan  })
11901169689Skan
11902169689Skan(define_insn_and_split "*eq<mode>_compare"
11903169689Skan  [(set (match_operand:CC 3 "cc_reg_operand" "=y")
11904169689Skan	(compare:CC
11905169689Skan	 (eq:P (match_operand:P 1 "gpc_reg_operand" "=r")
11906169689Skan	       (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
11907169689Skan	 (const_int 0)))
11908169689Skan   (set (match_operand:P 0 "gpc_reg_operand" "=r")
11909169689Skan	(eq:P (match_dup 1) (match_dup 2)))]
11910169689Skan  "!TARGET_POWER && optimize_size"
11911169689Skan  "#"
11912169689Skan  "!TARGET_POWER && optimize_size"
11913169689Skan  [(set (match_dup 0)
11914169689Skan	(clz:P (match_dup 4)))
11915169689Skan   (parallel [(set (match_dup 3)
11916169689Skan		   (compare:CC (lshiftrt:P (match_dup 0) (match_dup 5))
11917169689Skan			       (const_int 0)))
11918169689Skan	      (set (match_dup 0)
11919169689Skan		   (lshiftrt:P (match_dup 0) (match_dup 5)))])]
11920169689Skan  {
11921169689Skan    if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)
11922169689Skan      {
11923169689Skan	/* Use output operand as intermediate.  */
11924169689Skan	operands[4] = operands[0];
11925169689Skan
11926169689Skan	if (logical_operand (operands[2], <MODE>mode))
11927169689Skan	  emit_insn (gen_rtx_SET (VOIDmode, operands[4],
11928169689Skan				  gen_rtx_XOR (<MODE>mode,
11929169689Skan					       operands[1], operands[2])));
11930169689Skan	else
11931169689Skan	  emit_insn (gen_rtx_SET (VOIDmode, operands[4],
11932169689Skan				  gen_rtx_PLUS (<MODE>mode, operands[1],
11933169689Skan						negate_rtx (<MODE>mode,
11934169689Skan							    operands[2]))));
11935169689Skan      }
11936169689Skan    else
11937169689Skan      operands[4] = operands[1];
11938169689Skan
11939169689Skan    operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
11940169689Skan  })
11941169689Skan
11942169689Skan(define_insn "*eqsi_power"
1194390075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r,r")
1194490075Sobrien	(eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
1194590075Sobrien	       (match_operand:SI 2 "reg_or_cint_operand" "r,O,K,L,I")))
1194690075Sobrien   (clobber (match_scratch:SI 3 "=r,&r,r,r,r"))]
11947169689Skan  "TARGET_POWER"
1194890075Sobrien  "@
1194990075Sobrien   xor %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae|adde} %0,%3,%0
1195090075Sobrien   {sfi|subfic} %3,%1,0\;{ae|adde} %0,%3,%1
1195190075Sobrien   {xoril|xori} %0,%1,%b2\;{sfi|subfic} %3,%0,0\;{ae|adde} %0,%3,%0
1195290075Sobrien   {xoriu|xoris} %0,%1,%u2\;{sfi|subfic} %3,%0,0\;{ae|adde} %0,%3,%0
1195390075Sobrien   {sfi|subfic} %0,%1,%2\;{sfi|subfic} %3,%0,0\;{ae|adde} %0,%3,%0"
11954169689Skan  [(set_attr "type" "three,two,three,three,three")
11955169689Skan   (set_attr "length" "12,8,12,12,12")])
1195690075Sobrien
1195790075Sobrien;; We have insns of the form shown by the first define_insn below.  If
1195890075Sobrien;; there is something inside the comparison operation, we must split it.
1195990075Sobrien(define_split
1196090075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "")
1196190075Sobrien	(plus:SI (match_operator 1 "comparison_operator"
1196290075Sobrien				 [(match_operand:SI 2 "" "")
1196390075Sobrien				  (match_operand:SI 3
1196490075Sobrien						    "reg_or_cint_operand" "")])
1196590075Sobrien		 (match_operand:SI 4 "gpc_reg_operand" "")))
1196690075Sobrien   (clobber (match_operand:SI 5 "register_operand" ""))]
1196790075Sobrien  "! gpc_reg_operand (operands[2], SImode)"
1196890075Sobrien  [(set (match_dup 5) (match_dup 2))
1196990075Sobrien   (set (match_dup 2) (plus:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)])
1197090075Sobrien			       (match_dup 4)))])
1197190075Sobrien
11972169689Skan(define_insn "*plus_eqsi"
1197396263Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r,&r,&r,&r")
1197490075Sobrien	(plus:SI (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r")
11975169689Skan			(match_operand:SI 2 "scc_eq_operand" "r,O,K,L,I"))
1197696263Sobrien		 (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r")))]
11977132718Skan  "TARGET_32BIT"
1197890075Sobrien  "@
1197996263Sobrien   xor %0,%1,%2\;{sfi|subfic} %0,%0,0\;{aze|addze} %0,%3
1198096263Sobrien   {sfi|subfic} %0,%1,0\;{aze|addze} %0,%3
1198196263Sobrien   {xoril|xori} %0,%1,%b2\;{sfi|subfic} %0,%0,0\;{aze|addze} %0,%3
1198296263Sobrien   {xoriu|xoris} %0,%1,%u2\;{sfi|subfic} %0,%0,0\;{aze|addze} %0,%3
1198396263Sobrien   {sfi|subfic} %0,%1,%2\;{sfi|subfic} %0,%0,0\;{aze|addze} %0,%3"
11984169689Skan  [(set_attr "type" "three,two,three,three,three")
11985169689Skan   (set_attr "length" "12,8,12,12,12")])
1198690075Sobrien
11987169689Skan(define_insn "*compare_plus_eqsi"
1198890075Sobrien  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,x,x,x,?y,?y,?y,?y,?y")
1198990075Sobrien	(compare:CC
1199090075Sobrien	 (plus:SI
1199190075Sobrien	  (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r,r,r")
11992169689Skan		 (match_operand:SI 2 "scc_eq_operand" "r,O,K,L,I,r,O,K,L,I"))
1199390075Sobrien	  (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r,r,r,r,r,r"))
1199490075Sobrien	 (const_int 0)))
1199590075Sobrien   (clobber (match_scratch:SI 4 "=&r,&r,&r,&r,&r,&r,&r,&r,&r,&r"))]
11996169689Skan  "TARGET_32BIT && optimize_size"
1199790075Sobrien  "@
1199890075Sobrien   xor %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3
1199990075Sobrien   {sfi|subfic} %4,%1,0\;{aze.|addze.} %4,%3
1200090075Sobrien   {xoril|xori} %4,%1,%b2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3
1200190075Sobrien   {xoriu|xoris} %4,%1,%u2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3
1200290075Sobrien   {sfi|subfic} %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3
1200390075Sobrien   #
1200490075Sobrien   #
1200590075Sobrien   #
1200690075Sobrien   #
1200790075Sobrien   #"
1200890075Sobrien  [(set_attr "type" "compare")
1200990075Sobrien   (set_attr "length" "12,8,12,12,12,16,12,16,16,16")])
1201090075Sobrien
1201190075Sobrien(define_split
1201290075Sobrien  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
1201390075Sobrien	(compare:CC
1201490075Sobrien	 (plus:SI
1201590075Sobrien	  (eq:SI (match_operand:SI 1 "gpc_reg_operand" "")
12016169689Skan		 (match_operand:SI 2 "scc_eq_operand" ""))
1201790075Sobrien	  (match_operand:SI 3 "gpc_reg_operand" ""))
1201890075Sobrien	 (const_int 0)))
1201990075Sobrien   (clobber (match_scratch:SI 4 ""))]
12020169689Skan  "TARGET_32BIT && optimize_size && reload_completed"
1202190075Sobrien  [(set (match_dup 4)
1202290075Sobrien	(plus:SI (eq:SI (match_dup 1)
1202390075Sobrien		 (match_dup 2))
1202490075Sobrien	  (match_dup 3)))
1202590075Sobrien   (set (match_dup 0)
1202690075Sobrien	(compare:CC (match_dup 4)
1202790075Sobrien		    (const_int 0)))]
1202890075Sobrien  "")
1202990075Sobrien
12030169689Skan(define_insn "*plus_eqsi_compare"
1203196263Sobrien  [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,x,x,x,?y,?y,?y,?y,?y")
1203290075Sobrien	(compare:CC
1203390075Sobrien	 (plus:SI
1203490075Sobrien	  (eq:SI (match_operand:SI 1 "gpc_reg_operand" "%r,r,r,r,r,r,r,r,r,r")
12035169689Skan		 (match_operand:SI 2 "scc_eq_operand" "r,O,K,L,I,r,O,K,L,I"))
1203690075Sobrien	  (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r,r,r,r,r,r,r"))
1203790075Sobrien	 (const_int 0)))
1203896263Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r,&r,&r,&r,&r,&r,&r,&r,&r")
1203996263Sobrien	(plus:SI (eq:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
12040169689Skan  "TARGET_32BIT && optimize_size"
1204190075Sobrien  "@
1204296263Sobrien   xor %0,%1,%2\;{sfi|subfic} %0,%0,0\;{aze.|addze.} %0,%3
1204396263Sobrien   {sfi|subfic} %0,%1,0\;{aze.|addze.} %0,%3
1204496263Sobrien   {xoril|xori} %0,%1,%b2\;{sfi|subfic} %0,%0,0\;{aze.|addze.} %0,%3
1204596263Sobrien   {xoriu|xoris} %0,%1,%u2\;{sfi|subfic} %0,%0,0\;{aze.|addze.} %0,%3
1204696263Sobrien   {sfi|subfic} %0,%1,%2\;{sfi|subfic} %0,%0,0\;{aze.|addze.} %0,%3
1204790075Sobrien   #
1204890075Sobrien   #
1204990075Sobrien   #
1205090075Sobrien   #
1205190075Sobrien   #"
1205290075Sobrien  [(set_attr "type" "compare")
1205390075Sobrien   (set_attr "length" "12,8,12,12,12,16,12,16,16,16")])
1205490075Sobrien
1205590075Sobrien(define_split
1205696263Sobrien  [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
1205790075Sobrien	(compare:CC
1205890075Sobrien	 (plus:SI
1205990075Sobrien	  (eq:SI (match_operand:SI 1 "gpc_reg_operand" "")
12060169689Skan		 (match_operand:SI 2 "scc_eq_operand" ""))
1206190075Sobrien	  (match_operand:SI 3 "gpc_reg_operand" ""))
1206290075Sobrien	 (const_int 0)))
1206390075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "")
1206496263Sobrien	(plus:SI (eq:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
12065169689Skan  "TARGET_32BIT && optimize_size && reload_completed"
1206696263Sobrien  [(set (match_dup 0)
1206790075Sobrien	(plus:SI (eq:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
1206896263Sobrien   (set (match_dup 4)
1206990075Sobrien	(compare:CC (match_dup 0)
1207090075Sobrien		    (const_int 0)))]
1207190075Sobrien  "")
1207290075Sobrien
12073169689Skan(define_insn "*neg_eq0<mode>"
12074169689Skan  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12075169689Skan	(neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12076169689Skan		     (const_int 0))))]
12077169689Skan  ""
12078169689Skan  "{ai|addic} %0,%1,-1\;{sfe|subfe} %0,%0,%0"
12079169689Skan  [(set_attr "type" "two")
12080169689Skan   (set_attr "length" "8")])
1208190075Sobrien
12082169689Skan(define_insn_and_split "*neg_eq<mode>"
12083169689Skan  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12084169689Skan	(neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "%r")
12085169689Skan		     (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))]
12086169689Skan  ""
12087169689Skan  "#"
12088169689Skan  ""
12089169689Skan  [(set (match_dup 0) (neg:P (eq:P (match_dup 3) (const_int 0))))]
12090169689Skan  {
12091169689Skan    if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)
12092169689Skan      {
12093169689Skan	/* Use output operand as intermediate.  */
12094169689Skan	operands[3] = operands[0];
12095169689Skan
12096169689Skan	if (logical_operand (operands[2], <MODE>mode))
12097169689Skan	  emit_insn (gen_rtx_SET (VOIDmode, operands[3],
12098169689Skan				  gen_rtx_XOR (<MODE>mode,
12099169689Skan					       operands[1], operands[2])));
12100169689Skan	else
12101169689Skan	  emit_insn (gen_rtx_SET (VOIDmode, operands[3],
12102169689Skan				  gen_rtx_PLUS (<MODE>mode, operands[1],
12103169689Skan						negate_rtx (<MODE>mode,
12104169689Skan							    operands[2]))));
12105169689Skan      }
12106169689Skan    else
12107169689Skan      operands[3] = operands[1];
12108169689Skan  })
12109169689Skan
1211090075Sobrien;; Simplify (ne X (const_int 0)) on the PowerPC.  No need to on the Power,
1211190075Sobrien;; since it nabs/sr is just as fast.
12112169689Skan(define_insn "*ne0si"
1211390075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "=&r")
1211490075Sobrien	(lshiftrt:SI (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r")))
1211590075Sobrien		     (const_int 31)))
1211690075Sobrien   (clobber (match_scratch:SI 2 "=&r"))]
12117132718Skan  "! TARGET_POWER && TARGET_32BIT && !TARGET_ISEL"
1211890075Sobrien  "{ai|addic} %2,%1,-1\;{sfe|subfe} %0,%2,%1"
12119169689Skan  [(set_attr "type" "two")
12120169689Skan   (set_attr "length" "8")])
1212190075Sobrien
12122169689Skan(define_insn "*ne0di"
1212390075Sobrien  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
1212490075Sobrien	(lshiftrt:DI (neg:DI (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r")))
1212590075Sobrien		     (const_int 63)))
1212690075Sobrien   (clobber (match_scratch:DI 2 "=&r"))]
12127132718Skan  "TARGET_64BIT"
1212890075Sobrien  "addic %2,%1,-1\;subfe %0,%2,%1"
12129169689Skan  [(set_attr "type" "two")
12130169689Skan   (set_attr "length" "8")])
1213190075Sobrien
1213290075Sobrien;; This is what (plus (ne X (const_int 0)) Y) looks like.
12133169689Skan(define_insn "*plus_ne0si"
1213490075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1213590075Sobrien	(plus:SI (lshiftrt:SI
1213690075Sobrien		  (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r")))
1213790075Sobrien		  (const_int 31))
1213890075Sobrien		 (match_operand:SI 2 "gpc_reg_operand" "r")))
1213990075Sobrien   (clobber (match_scratch:SI 3 "=&r"))]
12140132718Skan  "TARGET_32BIT"
1214190075Sobrien  "{ai|addic} %3,%1,-1\;{aze|addze} %0,%2"
12142169689Skan  [(set_attr "type" "two")
12143169689Skan   (set_attr "length" "8")])
1214490075Sobrien
12145169689Skan(define_insn "*plus_ne0di"
1214690075Sobrien  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
1214790075Sobrien	(plus:DI (lshiftrt:DI
1214890075Sobrien		  (neg:DI (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r")))
1214990075Sobrien		  (const_int 63))
1215090075Sobrien		 (match_operand:DI 2 "gpc_reg_operand" "r")))
1215190075Sobrien   (clobber (match_scratch:DI 3 "=&r"))]
12152132718Skan  "TARGET_64BIT"
1215390075Sobrien  "addic %3,%1,-1\;addze %0,%2"
12154169689Skan  [(set_attr "type" "two")
12155169689Skan   (set_attr "length" "8")])
1215690075Sobrien
12157169689Skan(define_insn "*compare_plus_ne0si"
1215890075Sobrien  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
1215990075Sobrien	(compare:CC
1216090075Sobrien	 (plus:SI (lshiftrt:SI
1216190075Sobrien		   (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")))
1216290075Sobrien		   (const_int 31))
1216390075Sobrien		  (match_operand:SI 2 "gpc_reg_operand" "r,r"))
1216490075Sobrien	 (const_int 0)))
1216596263Sobrien   (clobber (match_scratch:SI 3 "=&r,&r"))
1216696263Sobrien   (clobber (match_scratch:SI 4 "=X,&r"))]
12167132718Skan  "TARGET_32BIT"
1216890075Sobrien  "@
1216990075Sobrien   {ai|addic} %3,%1,-1\;{aze.|addze.} %3,%2
1217090075Sobrien   #"
1217190075Sobrien  [(set_attr "type" "compare")
1217290075Sobrien   (set_attr "length" "8,12")])
1217390075Sobrien
1217490075Sobrien(define_split
1217590075Sobrien  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
1217690075Sobrien	(compare:CC
1217790075Sobrien	 (plus:SI (lshiftrt:SI
1217890075Sobrien		   (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "")))
1217990075Sobrien		   (const_int 31))
1218090075Sobrien		  (match_operand:SI 2 "gpc_reg_operand" ""))
1218190075Sobrien	 (const_int 0)))
1218296263Sobrien   (clobber (match_scratch:SI 3 ""))
1218396263Sobrien   (clobber (match_scratch:SI 4 ""))]
12184132718Skan  "TARGET_32BIT && reload_completed"
1218596263Sobrien  [(parallel [(set (match_dup 3)
12186117395Skan		   (plus:SI (lshiftrt:SI (neg:SI (abs:SI (match_dup 1)))
12187117395Skan					 (const_int 31))
12188117395Skan			    (match_dup 2)))
1218996263Sobrien              (clobber (match_dup 4))])
1219090075Sobrien   (set (match_dup 0)
1219190075Sobrien	(compare:CC (match_dup 3)
1219290075Sobrien		    (const_int 0)))]
1219390075Sobrien  "")
1219490075Sobrien
12195169689Skan(define_insn "*compare_plus_ne0di"
1219690075Sobrien  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
1219790075Sobrien	(compare:CC
1219890075Sobrien	 (plus:DI (lshiftrt:DI
1219990075Sobrien		   (neg:DI (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")))
1220090075Sobrien		   (const_int 63))
1220190075Sobrien		  (match_operand:DI 2 "gpc_reg_operand" "r,r"))
1220290075Sobrien	 (const_int 0)))
1220390075Sobrien   (clobber (match_scratch:DI 3 "=&r,&r"))]
12204132718Skan  "TARGET_64BIT"
1220590075Sobrien  "@
1220690075Sobrien   addic %3,%1,-1\;addze. %3,%2
1220790075Sobrien   #"
1220890075Sobrien  [(set_attr "type" "compare")
1220990075Sobrien   (set_attr "length" "8,12")])
1221090075Sobrien
1221190075Sobrien(define_split
1221290075Sobrien  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
1221390075Sobrien	(compare:CC
1221490075Sobrien	 (plus:DI (lshiftrt:DI
1221590075Sobrien		   (neg:DI (abs:DI (match_operand:DI 1 "gpc_reg_operand" "")))
1221690075Sobrien		   (const_int 63))
1221790075Sobrien		  (match_operand:DI 2 "gpc_reg_operand" ""))
1221890075Sobrien	 (const_int 0)))
1221990075Sobrien   (clobber (match_scratch:DI 3 ""))]
12220132718Skan  "TARGET_64BIT && reload_completed"
1222190075Sobrien  [(set (match_dup 3)
1222290075Sobrien	(plus:DI (lshiftrt:DI (neg:DI (abs:DI (match_dup 1)))
1222390075Sobrien		   (const_int 63))
1222490075Sobrien		  (match_dup 2)))
1222590075Sobrien   (set (match_dup 0)
1222690075Sobrien	(compare:CC (match_dup 3)
1222790075Sobrien		    (const_int 0)))]
1222890075Sobrien  "")
1222990075Sobrien
12230169689Skan(define_insn "*plus_ne0si_compare"
1223190075Sobrien  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
1223290075Sobrien	(compare:CC
1223390075Sobrien	 (plus:SI (lshiftrt:SI
1223490075Sobrien		   (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")))
1223590075Sobrien		   (const_int 31))
1223690075Sobrien		  (match_operand:SI 2 "gpc_reg_operand" "r,r"))
1223790075Sobrien	 (const_int 0)))
1223890075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1223990075Sobrien	(plus:SI (lshiftrt:SI (neg:SI (abs:SI (match_dup 1))) (const_int 31))
1224090075Sobrien		 (match_dup 2)))
1224190075Sobrien   (clobber (match_scratch:SI 3 "=&r,&r"))]
12242132718Skan  "TARGET_32BIT"
1224390075Sobrien  "@
1224490075Sobrien   {ai|addic} %3,%1,-1\;{aze.|addze.} %0,%2
1224590075Sobrien   #"
1224690075Sobrien  [(set_attr "type" "compare")
1224790075Sobrien   (set_attr "length" "8,12")])
1224890075Sobrien
1224990075Sobrien(define_split
1225090075Sobrien  [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
1225190075Sobrien	(compare:CC
1225290075Sobrien	 (plus:SI (lshiftrt:SI
1225390075Sobrien		   (neg:SI (abs:SI (match_operand:SI 1 "gpc_reg_operand" "")))
1225490075Sobrien		   (const_int 31))
1225590075Sobrien		  (match_operand:SI 2 "gpc_reg_operand" ""))
1225690075Sobrien	 (const_int 0)))
1225790075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "")
1225890075Sobrien	(plus:SI (lshiftrt:SI (neg:SI (abs:SI (match_dup 1))) (const_int 31))
1225990075Sobrien		 (match_dup 2)))
1226090075Sobrien   (clobber (match_scratch:SI 3 ""))]
12261132718Skan  "TARGET_32BIT && reload_completed"
1226290075Sobrien  [(parallel [(set (match_dup 0)
1226390075Sobrien	(plus:SI (lshiftrt:SI (neg:SI (abs:SI (match_dup 1))) (const_int 31))
1226490075Sobrien		 (match_dup 2)))
1226590075Sobrien   (clobber (match_dup 3))])
1226690075Sobrien   (set (match_dup 4)
1226790075Sobrien	(compare:CC (match_dup 0)
1226890075Sobrien		    (const_int 0)))]
1226990075Sobrien  "")
1227090075Sobrien
12271169689Skan(define_insn "*plus_ne0di_compare"
1227290075Sobrien  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
1227390075Sobrien	(compare:CC
1227490075Sobrien	 (plus:DI (lshiftrt:DI
1227590075Sobrien		   (neg:DI (abs:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")))
1227690075Sobrien		   (const_int 63))
1227790075Sobrien		  (match_operand:DI 2 "gpc_reg_operand" "r,r"))
1227890075Sobrien	 (const_int 0)))
1227990075Sobrien   (set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
1228090075Sobrien	(plus:DI (lshiftrt:DI (neg:DI (abs:DI (match_dup 1))) (const_int 63))
1228190075Sobrien		 (match_dup 2)))
1228290075Sobrien   (clobber (match_scratch:DI 3 "=&r,&r"))]
12283132718Skan  "TARGET_64BIT"
1228490075Sobrien  "@
1228590075Sobrien   addic %3,%1,-1\;addze. %0,%2
1228690075Sobrien   #"
1228790075Sobrien  [(set_attr "type" "compare")
1228890075Sobrien   (set_attr "length" "8,12")])
1228990075Sobrien
1229090075Sobrien(define_split
1229190075Sobrien  [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
1229290075Sobrien	(compare:CC
1229390075Sobrien	 (plus:DI (lshiftrt:DI
1229490075Sobrien		   (neg:DI (abs:DI (match_operand:DI 1 "gpc_reg_operand" "")))
1229590075Sobrien		   (const_int 63))
1229690075Sobrien		  (match_operand:DI 2 "gpc_reg_operand" ""))
1229790075Sobrien	 (const_int 0)))
1229890075Sobrien   (set (match_operand:DI 0 "gpc_reg_operand" "")
1229990075Sobrien	(plus:DI (lshiftrt:DI (neg:DI (abs:DI (match_dup 1))) (const_int 63))
1230090075Sobrien		 (match_dup 2)))
1230190075Sobrien   (clobber (match_scratch:DI 3 ""))]
12302132718Skan  "TARGET_64BIT && reload_completed"
1230390075Sobrien  [(parallel [(set (match_dup 0)
1230490075Sobrien	(plus:DI (lshiftrt:DI (neg:DI (abs:DI (match_dup 1))) (const_int 63))
1230590075Sobrien		 (match_dup 2)))
1230690075Sobrien   (clobber (match_dup 3))])
1230790075Sobrien   (set (match_dup 4)
1230890075Sobrien	(compare:CC (match_dup 0)
1230990075Sobrien		    (const_int 0)))]
1231090075Sobrien  "")
1231190075Sobrien
1231290075Sobrien(define_insn ""
1231390075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1231490075Sobrien	(le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1231590075Sobrien	       (match_operand:SI 2 "reg_or_short_operand" "r,O")))
1231690075Sobrien   (clobber (match_scratch:SI 3 "=r,X"))]
1231790075Sobrien  "TARGET_POWER"
1231890075Sobrien  "@
1231990075Sobrien   doz %3,%2,%1\;{sfi|subfic} %0,%3,0\;{ae|adde} %0,%0,%3
1232090075Sobrien   {ai|addic} %0,%1,-1\;{aze|addze} %0,%0\;{sri|srwi} %0,%0,31"
1232190075Sobrien  [(set_attr "length" "12")])
1232290075Sobrien
1232390075Sobrien(define_insn ""
1232490075Sobrien  [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,?y,?y")
1232590075Sobrien	(compare:CC
1232690075Sobrien	 (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
1232790075Sobrien		(match_operand:SI 2 "reg_or_short_operand" "r,O,r,O"))
1232890075Sobrien	 (const_int 0)))
1232990075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r,r")
1233090075Sobrien	(le:SI (match_dup 1) (match_dup 2)))
1233190075Sobrien   (clobber (match_scratch:SI 3 "=r,X,r,X"))]
1233290075Sobrien  "TARGET_POWER"
1233390075Sobrien  "@
1233490075Sobrien   doz %3,%2,%1\;{sfi|subfic} %0,%3,0\;{ae.|adde.} %0,%0,%3
1233590075Sobrien   {ai|addic} %0,%1,-1\;{aze|addze} %0,%0\;{sri.|srwi.} %0,%0,31
1233690075Sobrien   #
1233790075Sobrien   #"
1233890075Sobrien  [(set_attr "type" "compare,delayed_compare,compare,delayed_compare")
1233990075Sobrien   (set_attr "length" "12,12,16,16")])
1234090075Sobrien
1234190075Sobrien(define_split
1234290075Sobrien  [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
1234390075Sobrien	(compare:CC
1234490075Sobrien	 (le:SI (match_operand:SI 1 "gpc_reg_operand" "")
1234590075Sobrien		(match_operand:SI 2 "reg_or_short_operand" ""))
1234690075Sobrien	 (const_int 0)))
1234790075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "")
1234890075Sobrien	(le:SI (match_dup 1) (match_dup 2)))
1234990075Sobrien   (clobber (match_scratch:SI 3 ""))]
1235090075Sobrien  "TARGET_POWER && reload_completed"
1235190075Sobrien  [(parallel [(set (match_dup 0)
1235290075Sobrien	(le:SI (match_dup 1) (match_dup 2)))
1235390075Sobrien   (clobber (match_dup 3))])
1235490075Sobrien   (set (match_dup 4)
1235590075Sobrien	(compare:CC (match_dup 0)
1235690075Sobrien		    (const_int 0)))]
1235790075Sobrien  "")
1235890075Sobrien
1235990075Sobrien(define_insn ""
12360103445Skan  [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r")
1236190075Sobrien	(plus:SI (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1236290075Sobrien			(match_operand:SI 2 "reg_or_short_operand" "r,O"))
12363103445Skan		 (match_operand:SI 3 "gpc_reg_operand" "r,r")))]
1236490075Sobrien  "TARGET_POWER"
1236590075Sobrien  "@
12366103445Skan   doz %0,%2,%1\;{sfi|subfic} %0,%0,0\;{aze|addze} %0,%3
12367103445Skan   {srai|srawi} %0,%1,31\;{sf|subfc} %0,%1,%0\;{aze|addze} %0,%3"
1236890075Sobrien  [(set_attr "length" "12")])
1236990075Sobrien
1237090075Sobrien(define_insn ""
1237190075Sobrien  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
1237290075Sobrien	(compare:CC
1237390075Sobrien	 (plus:SI (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
1237490075Sobrien			 (match_operand:SI 2 "reg_or_short_operand" "r,O,r,O"))
1237590075Sobrien		  (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r"))
1237690075Sobrien	 (const_int 0)))
1237790075Sobrien   (clobber (match_scratch:SI 4 "=&r,&r,&r,&r"))]
1237890075Sobrien  "TARGET_POWER"
1237990075Sobrien  "@
1238090075Sobrien   doz %4,%2,%1\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3
1238190075Sobrien   {srai|srawi} %4,%1,31\;{sf|subfc} %4,%1,%4\;{aze.|addze.} %4,%3
1238290075Sobrien   #
1238390075Sobrien   #"
1238490075Sobrien  [(set_attr "type" "compare")
1238590075Sobrien   (set_attr "length" "12,12,16,16")])
1238690075Sobrien
1238790075Sobrien(define_split
1238890075Sobrien  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
1238990075Sobrien	(compare:CC
1239090075Sobrien	 (plus:SI (le:SI (match_operand:SI 1 "gpc_reg_operand" "")
1239190075Sobrien			 (match_operand:SI 2 "reg_or_short_operand" ""))
1239290075Sobrien		  (match_operand:SI 3 "gpc_reg_operand" ""))
1239390075Sobrien	 (const_int 0)))
1239490075Sobrien   (clobber (match_scratch:SI 4 ""))]
1239590075Sobrien  "TARGET_POWER && reload_completed"
1239690075Sobrien  [(set (match_dup 4)
1239790075Sobrien	(plus:SI (le:SI (match_dup 1) (match_dup 2))
12398103445Skan		 (match_dup 3)))
1239990075Sobrien   (set (match_dup 0)
1240090075Sobrien	(compare:CC (match_dup 4)
1240190075Sobrien		    (const_int 0)))]
1240290075Sobrien  "")
1240390075Sobrien
1240490075Sobrien(define_insn ""
12405103445Skan  [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,?y,?y")
1240690075Sobrien	(compare:CC
1240790075Sobrien	 (plus:SI (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
1240890075Sobrien			 (match_operand:SI 2 "reg_or_short_operand" "r,O,r,O"))
1240990075Sobrien		  (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r"))
1241090075Sobrien	 (const_int 0)))
12411103445Skan   (set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r,&r,&r")
12412103445Skan	(plus:SI (le:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
1241390075Sobrien  "TARGET_POWER"
1241490075Sobrien  "@
12415103445Skan   doz %0,%2,%1\;{sfi|subfic} %0,%0,0\;{aze.|addze.} %0,%3
12416103445Skan   {srai|srawi} %0,%1,31\;{sf|subfc} %0,%1,%0\;{aze.|addze.} %0,%3
1241790075Sobrien   #
1241890075Sobrien   #"
1241990075Sobrien  [(set_attr "type" "compare")
1242090075Sobrien   (set_attr "length" "12,12,16,16")])
1242190075Sobrien
1242290075Sobrien(define_split
12423103445Skan  [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
1242490075Sobrien	(compare:CC
1242590075Sobrien	 (plus:SI (le:SI (match_operand:SI 1 "gpc_reg_operand" "")
1242690075Sobrien			 (match_operand:SI 2 "reg_or_short_operand" ""))
1242790075Sobrien		  (match_operand:SI 3 "gpc_reg_operand" ""))
1242890075Sobrien	 (const_int 0)))
1242990075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "")
12430103445Skan	(plus:SI (le:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
1243190075Sobrien  "TARGET_POWER && reload_completed"
12432103445Skan  [(set (match_dup 0)
1243390075Sobrien	(plus:SI (le:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
12434103445Skan   (set (match_dup 4)
1243590075Sobrien	(compare:CC (match_dup 0)
1243690075Sobrien		    (const_int 0)))]
1243790075Sobrien  "")
1243890075Sobrien
1243990075Sobrien(define_insn ""
1244090075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1244190075Sobrien	(neg:SI (le:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1244290075Sobrien		       (match_operand:SI 2 "reg_or_short_operand" "r,O"))))]
1244390075Sobrien  "TARGET_POWER"
1244490075Sobrien  "@
1244590075Sobrien   doz %0,%2,%1\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0
1244690075Sobrien   {ai|addic} %0,%1,-1\;{aze|addze} %0,%0\;{srai|srawi} %0,%0,31"
1244790075Sobrien  [(set_attr "length" "12")])
1244890075Sobrien
12449169689Skan(define_insn "*leu<mode>"
12450169689Skan  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12451169689Skan	(leu:P (match_operand:P 1 "gpc_reg_operand" "r")
12452169689Skan	       (match_operand:P 2 "reg_or_short_operand" "rI")))]
12453169689Skan  ""
1245490075Sobrien  "{sf%I2|subf%I2c} %0,%1,%2\;{cal %0,0(0)|li %0,0}\;{ae|adde} %0,%0,%0"
12455169689Skan  [(set_attr "type" "three")
12456169689Skan   (set_attr "length" "12")])
1245790075Sobrien
12458169689Skan(define_insn "*leu<mode>_compare"
1245990075Sobrien  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1246090075Sobrien	(compare:CC
12461169689Skan	 (leu:P (match_operand:P 1 "gpc_reg_operand" "r,r")
12462169689Skan		(match_operand:P 2 "reg_or_short_operand" "rI,rI"))
1246390075Sobrien	 (const_int 0)))
12464169689Skan   (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
12465169689Skan	(leu:P (match_dup 1) (match_dup 2)))]
12466169689Skan  ""
1246790075Sobrien  "@
1246890075Sobrien   {sf%I2|subf%I2c} %0,%1,%2\;{cal %0,0(0)|li %0,0}\;{ae.|adde.} %0,%0,%0
1246990075Sobrien   #"
1247090075Sobrien  [(set_attr "type" "compare")
1247190075Sobrien   (set_attr "length" "12,16")])
1247290075Sobrien
1247390075Sobrien(define_split
1247490075Sobrien  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
1247590075Sobrien	(compare:CC
12476169689Skan	 (leu:P (match_operand:P 1 "gpc_reg_operand" "")
12477169689Skan		(match_operand:P 2 "reg_or_short_operand" ""))
1247890075Sobrien	 (const_int 0)))
12479169689Skan   (set (match_operand:P 0 "gpc_reg_operand" "")
12480169689Skan	(leu:P (match_dup 1) (match_dup 2)))]
12481169689Skan  "reload_completed"
1248290075Sobrien  [(set (match_dup 0)
12483169689Skan	(leu:P (match_dup 1) (match_dup 2)))
1248490075Sobrien   (set (match_dup 3)
1248590075Sobrien	(compare:CC (match_dup 0)
1248690075Sobrien		    (const_int 0)))]
1248790075Sobrien  "")
1248890075Sobrien
12489169689Skan(define_insn "*plus_leu<mode>"
12490169689Skan  [(set (match_operand:P 0 "gpc_reg_operand" "=&r")
12491169689Skan	(plus:P (leu:P (match_operand:P 1 "gpc_reg_operand" "r")
12492169689Skan		       (match_operand:P 2 "reg_or_short_operand" "rI"))
12493169689Skan		(match_operand:P 3 "gpc_reg_operand" "r")))]
12494169689Skan  ""
1249596263Sobrien  "{sf%I2|subf%I2c} %0,%1,%2\;{aze|addze} %0,%3"
12496169689Skan  [(set_attr "type" "two")
12497169689Skan   (set_attr "length" "8")])
1249890075Sobrien
1249990075Sobrien(define_insn ""
1250090075Sobrien  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
1250190075Sobrien	(compare:CC
1250290075Sobrien	 (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1250390075Sobrien			  (match_operand:SI 2 "reg_or_short_operand" "rI,rI"))
1250490075Sobrien		  (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1250590075Sobrien	 (const_int 0)))
1250690075Sobrien   (clobber (match_scratch:SI 4 "=&r,&r"))]
12507132718Skan  "TARGET_32BIT"
1250890075Sobrien  "@
1250990075Sobrien   {sf%I2|subf%I2c} %4,%1,%2\;{aze.|addze.} %4,%3
1251090075Sobrien   #"
1251190075Sobrien  [(set_attr "type" "compare")
1251290075Sobrien   (set_attr "length" "8,12")])
1251390075Sobrien
1251490075Sobrien(define_split
1251590075Sobrien  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
1251690075Sobrien	(compare:CC
1251790075Sobrien	 (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "")
1251890075Sobrien			  (match_operand:SI 2 "reg_or_short_operand" ""))
1251990075Sobrien		  (match_operand:SI 3 "gpc_reg_operand" ""))
1252090075Sobrien	 (const_int 0)))
1252190075Sobrien   (clobber (match_scratch:SI 4 ""))]
12522132718Skan  "TARGET_32BIT && reload_completed"
1252390075Sobrien  [(set (match_dup 4)
1252490075Sobrien	(plus:SI (leu:SI (match_dup 1) (match_dup 2))
1252590075Sobrien		  (match_dup 3)))
1252690075Sobrien   (set (match_dup 0)
1252790075Sobrien	(compare:CC (match_dup 4)
1252890075Sobrien		    (const_int 0)))]
1252990075Sobrien  "")
1253090075Sobrien
1253190075Sobrien(define_insn ""
12532103445Skan  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
1253390075Sobrien	(compare:CC
1253490075Sobrien	 (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1253590075Sobrien			  (match_operand:SI 2 "reg_or_short_operand" "rI,rI"))
1253690075Sobrien		  (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1253790075Sobrien	 (const_int 0)))
12538103445Skan   (set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r")
12539103445Skan	(plus:SI (leu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
12540132718Skan  "TARGET_32BIT"
1254190075Sobrien  "@
12542103445Skan   {sf%I2|subf%I2c} %0,%1,%2\;{aze.|addze.} %0,%3
1254390075Sobrien   #"
1254490075Sobrien  [(set_attr "type" "compare")
1254590075Sobrien   (set_attr "length" "8,12")])
1254690075Sobrien
1254790075Sobrien(define_split
12548103445Skan  [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
1254990075Sobrien	(compare:CC
1255090075Sobrien	 (plus:SI (leu:SI (match_operand:SI 1 "gpc_reg_operand" "")
1255190075Sobrien			  (match_operand:SI 2 "reg_or_short_operand" ""))
1255290075Sobrien		  (match_operand:SI 3 "gpc_reg_operand" ""))
1255390075Sobrien	 (const_int 0)))
1255490075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "")
12555103445Skan	(plus:SI (leu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
12556132718Skan  "TARGET_32BIT && reload_completed"
12557103445Skan  [(set (match_dup 0)
1255890075Sobrien	(plus:SI (leu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
12559103445Skan   (set (match_dup 4)
1256090075Sobrien	(compare:CC (match_dup 0)
1256190075Sobrien		    (const_int 0)))]
1256290075Sobrien  "")
1256390075Sobrien
12564169689Skan(define_insn "*neg_leu<mode>"
12565169689Skan  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12566169689Skan	(neg:P (leu:P (match_operand:P 1 "gpc_reg_operand" "r")
12567169689Skan		      (match_operand:P 2 "reg_or_short_operand" "rI"))))]
12568169689Skan  ""
1256990075Sobrien  "{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;nand %0,%0,%0"
12570169689Skan   [(set_attr "type" "three")
12571169689Skan    (set_attr "length" "12")])
1257290075Sobrien
12573169689Skan(define_insn "*and_neg_leu<mode>"
12574169689Skan  [(set (match_operand:P 0 "gpc_reg_operand" "=&r")
12575169689Skan	(and:P (neg:P
12576169689Skan		 (leu:P (match_operand:P 1 "gpc_reg_operand" "r")
12577169689Skan			(match_operand:P 2 "reg_or_short_operand" "rI")))
12578169689Skan		(match_operand:P 3 "gpc_reg_operand" "r")))]
12579169689Skan  ""
12580103445Skan  "{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;andc %0,%3,%0"
12581169689Skan  [(set_attr "type" "three")
12582169689Skan   (set_attr "length" "12")])
1258390075Sobrien
1258490075Sobrien(define_insn ""
1258590075Sobrien  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
1258690075Sobrien	(compare:CC
1258790075Sobrien	 (and:SI (neg:SI
1258890075Sobrien		  (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1258990075Sobrien			  (match_operand:SI 2 "reg_or_short_operand" "rI,rI")))
1259090075Sobrien		 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1259190075Sobrien	 (const_int 0)))
1259290075Sobrien   (clobber (match_scratch:SI 4 "=&r,&r"))]
12593132718Skan  "TARGET_32BIT"
1259490075Sobrien  "@
1259590075Sobrien   {sf%I2|subf%I2c} %4,%1,%2\;{sfe|subfe} %4,%4,%4\;andc. %4,%3,%4
1259690075Sobrien   #"
1259790075Sobrien  [(set_attr "type" "compare")
1259890075Sobrien   (set_attr "length" "12,16")])
1259990075Sobrien
1260090075Sobrien(define_split
1260190075Sobrien  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
1260290075Sobrien	(compare:CC
1260390075Sobrien	 (and:SI (neg:SI
1260490075Sobrien		  (leu:SI (match_operand:SI 1 "gpc_reg_operand" "")
1260590075Sobrien			  (match_operand:SI 2 "reg_or_short_operand" "")))
1260690075Sobrien		 (match_operand:SI 3 "gpc_reg_operand" ""))
1260790075Sobrien	 (const_int 0)))
1260890075Sobrien   (clobber (match_scratch:SI 4 ""))]
12609132718Skan  "TARGET_32BIT && reload_completed"
1261090075Sobrien  [(set (match_dup 4)
12611103445Skan	(and:SI (neg:SI (leu:SI (match_dup 1) (match_dup 2)))
12612103445Skan		(match_dup 3)))
1261390075Sobrien   (set (match_dup 0)
1261490075Sobrien	(compare:CC (match_dup 4)
1261590075Sobrien		    (const_int 0)))]
1261690075Sobrien  "")
1261790075Sobrien
1261890075Sobrien(define_insn ""
12619103445Skan  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
1262090075Sobrien	(compare:CC
1262190075Sobrien	 (and:SI (neg:SI
1262290075Sobrien		  (leu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1262390075Sobrien			  (match_operand:SI 2 "reg_or_short_operand" "rI,rI")))
1262490075Sobrien		 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1262590075Sobrien	 (const_int 0)))
12626103445Skan   (set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r")
12627103445Skan	(and:SI (neg:SI (leu:SI (match_dup 1) (match_dup 2))) (match_dup 3)))]
12628132718Skan  "TARGET_32BIT"
1262990075Sobrien  "@
12630103445Skan   {sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0\;andc. %0,%3,%0
1263190075Sobrien   #"
1263290075Sobrien  [(set_attr "type" "compare")
1263390075Sobrien   (set_attr "length" "12,16")])
1263490075Sobrien
1263590075Sobrien(define_split
12636103445Skan  [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
1263790075Sobrien	(compare:CC
1263890075Sobrien	 (and:SI (neg:SI
1263990075Sobrien		  (leu:SI (match_operand:SI 1 "gpc_reg_operand" "")
1264090075Sobrien			  (match_operand:SI 2 "reg_or_short_operand" "")))
1264190075Sobrien		 (match_operand:SI 3 "gpc_reg_operand" ""))
1264290075Sobrien	 (const_int 0)))
1264390075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "")
12644103445Skan	(and:SI (neg:SI (leu:SI (match_dup 1) (match_dup 2))) (match_dup 3)))]
12645132718Skan  "TARGET_32BIT && reload_completed"
12646103445Skan  [(set (match_dup 0)
12647103445Skan	(and:SI (neg:SI (leu:SI (match_dup 1) (match_dup 2)))
12648103445Skan		(match_dup 3)))
12649103445Skan   (set (match_dup 4)
1265090075Sobrien	(compare:CC (match_dup 0)
1265190075Sobrien		    (const_int 0)))]
1265290075Sobrien  "")
1265390075Sobrien
1265490075Sobrien(define_insn ""
1265590075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1265690075Sobrien	(lt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1265790075Sobrien	       (match_operand:SI 2 "reg_or_short_operand" "rI")))]
1265890075Sobrien  "TARGET_POWER"
1265990075Sobrien  "doz%I2 %0,%1,%2\;nabs %0,%0\;{sri|srwi} %0,%0,31"
1266090075Sobrien   [(set_attr "length" "12")])
1266190075Sobrien
1266290075Sobrien(define_insn ""
1266390075Sobrien  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1266490075Sobrien	(compare:CC
1266590075Sobrien	 (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1266690075Sobrien		(match_operand:SI 2 "reg_or_short_operand" "rI,rI"))
1266790075Sobrien	 (const_int 0)))
1266890075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1266990075Sobrien	(lt:SI (match_dup 1) (match_dup 2)))]
1267090075Sobrien  "TARGET_POWER"
1267190075Sobrien  "@
1267290075Sobrien   doz%I2 %0,%1,%2\;nabs %0,%0\;{sri.|srwi.} %0,%0,31
1267390075Sobrien   #"
1267490075Sobrien  [(set_attr "type" "delayed_compare")
1267590075Sobrien   (set_attr "length" "12,16")])
1267690075Sobrien
1267790075Sobrien(define_split
1267890075Sobrien  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
1267990075Sobrien	(compare:CC
1268090075Sobrien	 (lt:SI (match_operand:SI 1 "gpc_reg_operand" "")
1268190075Sobrien		(match_operand:SI 2 "reg_or_short_operand" ""))
1268290075Sobrien	 (const_int 0)))
1268390075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "")
1268490075Sobrien	(lt:SI (match_dup 1) (match_dup 2)))]
1268590075Sobrien  "TARGET_POWER && reload_completed"
1268690075Sobrien  [(set (match_dup 0)
1268790075Sobrien	(lt:SI (match_dup 1) (match_dup 2)))
1268890075Sobrien   (set (match_dup 3)
1268990075Sobrien	(compare:CC (match_dup 0)
1269090075Sobrien		    (const_int 0)))]
1269190075Sobrien  "")
1269290075Sobrien
1269390075Sobrien(define_insn ""
12694103445Skan  [(set (match_operand:SI 0 "gpc_reg_operand" "=&r")
1269590075Sobrien	(plus:SI (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1269690075Sobrien			(match_operand:SI 2 "reg_or_short_operand" "rI"))
12697103445Skan		 (match_operand:SI 3 "gpc_reg_operand" "r")))]
1269890075Sobrien  "TARGET_POWER"
12699103445Skan  "doz%I2 %0,%1,%2\;{ai|addic} %0,%0,-1\;{aze|addze} %0,%3"
1270090075Sobrien  [(set_attr "length" "12")])
1270190075Sobrien
1270290075Sobrien(define_insn ""
1270390075Sobrien  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
1270490075Sobrien	(compare:CC
1270590075Sobrien	 (plus:SI (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1270690075Sobrien			 (match_operand:SI 2 "reg_or_short_operand" "rI,rI"))
1270790075Sobrien		  (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1270890075Sobrien	 (const_int 0)))
1270990075Sobrien   (clobber (match_scratch:SI 4 "=&r,&r"))]
1271090075Sobrien  "TARGET_POWER"
1271190075Sobrien  "@
1271290075Sobrien   doz%I2 %4,%1,%2\;{ai|addic} %4,%4,-1\;{aze.|addze.} %4,%3
1271390075Sobrien   #"
1271490075Sobrien  [(set_attr "type" "compare")
1271590075Sobrien   (set_attr "length" "12,16")])
1271690075Sobrien
1271790075Sobrien(define_split
1271890075Sobrien  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
1271990075Sobrien	(compare:CC
1272090075Sobrien	 (plus:SI (lt:SI (match_operand:SI 1 "gpc_reg_operand" "")
1272190075Sobrien			 (match_operand:SI 2 "reg_or_short_operand" ""))
1272290075Sobrien		  (match_operand:SI 3 "gpc_reg_operand" ""))
1272390075Sobrien	 (const_int 0)))
1272490075Sobrien   (clobber (match_scratch:SI 4 ""))]
1272590075Sobrien  "TARGET_POWER && reload_completed"
1272690075Sobrien  [(set (match_dup 4)
1272790075Sobrien	(plus:SI (lt:SI (match_dup 1) (match_dup 2))
12728103445Skan		 (match_dup 3)))
1272990075Sobrien   (set (match_dup 0)
1273090075Sobrien	(compare:CC (match_dup 4)
1273190075Sobrien		    (const_int 0)))]
1273290075Sobrien  "")
1273390075Sobrien
1273490075Sobrien(define_insn ""
12735103445Skan  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
1273690075Sobrien	(compare:CC
1273790075Sobrien	 (plus:SI (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1273890075Sobrien			 (match_operand:SI 2 "reg_or_short_operand" "rI,rI"))
1273990075Sobrien		  (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1274090075Sobrien	 (const_int 0)))
12741103445Skan   (set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r")
12742103445Skan	(plus:SI (lt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
1274390075Sobrien  "TARGET_POWER"
1274490075Sobrien  "@
12745103445Skan   doz%I2 %0,%1,%2\;{ai|addic} %0,%0,-1\;{aze.|addze.} %0,%3
1274690075Sobrien   #"
1274790075Sobrien  [(set_attr "type" "compare")
1274890075Sobrien   (set_attr "length" "12,16")])
1274990075Sobrien
1275090075Sobrien(define_split
12751103445Skan  [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
1275290075Sobrien	(compare:CC
1275390075Sobrien	 (plus:SI (lt:SI (match_operand:SI 1 "gpc_reg_operand" "")
1275490075Sobrien			 (match_operand:SI 2 "reg_or_short_operand" ""))
1275590075Sobrien		  (match_operand:SI 3 "gpc_reg_operand" ""))
1275690075Sobrien	 (const_int 0)))
1275790075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "")
12758103445Skan	(plus:SI (lt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
1275990075Sobrien  "TARGET_POWER && reload_completed"
12760103445Skan  [(set (match_dup 0)
1276190075Sobrien	(plus:SI (lt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
12762103445Skan   (set (match_dup 4)
1276390075Sobrien	(compare:CC (match_dup 0)
1276490075Sobrien		    (const_int 0)))]
1276590075Sobrien  "")
1276690075Sobrien
1276790075Sobrien(define_insn ""
1276890075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1276990075Sobrien	(neg:SI (lt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1277090075Sobrien		       (match_operand:SI 2 "reg_or_short_operand" "rI"))))]
1277190075Sobrien  "TARGET_POWER"
1277290075Sobrien  "doz%I2 %0,%1,%2\;nabs %0,%0\;{srai|srawi} %0,%0,31"
1277390075Sobrien  [(set_attr "length" "12")])
1277490075Sobrien
12775169689Skan(define_insn_and_split "*ltu<mode>"
12776169689Skan  [(set (match_operand:P 0 "gpc_reg_operand" "=r,r")
12777169689Skan	(ltu:P (match_operand:P 1 "gpc_reg_operand" "r,r")
12778169689Skan	       (match_operand:P 2 "reg_or_neg_short_operand" "r,P")))]
12779169689Skan  ""
12780169689Skan  "#"
12781169689Skan  ""
12782169689Skan  [(set (match_dup 0) (neg:P (ltu:P (match_dup 1) (match_dup 2))))
12783169689Skan   (set (match_dup 0) (neg:P (match_dup 0)))]
12784169689Skan  "")
1278590075Sobrien
12786169689Skan(define_insn_and_split "*ltu<mode>_compare"
1278790075Sobrien  [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
1278890075Sobrien	(compare:CC
12789169689Skan	 (ltu:P (match_operand:P 1 "gpc_reg_operand" "r,r,r,r")
12790169689Skan		(match_operand:P 2 "reg_or_neg_short_operand" "r,P,r,P"))
1279190075Sobrien	 (const_int 0)))
12792169689Skan   (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r,r")
12793169689Skan	(ltu:P (match_dup 1) (match_dup 2)))]
12794169689Skan  ""
12795169689Skan  "#"
12796169689Skan  ""
12797169689Skan  [(set (match_dup 0) (neg:P (ltu:P (match_dup 1) (match_dup 2))))
12798169689Skan   (parallel [(set (match_dup 3)
12799169689Skan		   (compare:CC (neg:P (match_dup 0)) (const_int 0)))
12800169689Skan	      (set (match_dup 0) (neg:P (match_dup 0)))])]
1280190075Sobrien  "")
1280290075Sobrien
12803169689Skan(define_insn_and_split "*plus_ltu<mode>"
12804169689Skan  [(set (match_operand:P 0 "gpc_reg_operand" "=&r,r")
12805169689Skan	(plus:P (ltu:P (match_operand:P 1 "gpc_reg_operand" "r,r")
12806169689Skan		       (match_operand:P 2 "reg_or_neg_short_operand" "r,P"))
12807169689Skan		(match_operand:P 3 "reg_or_short_operand" "rI,rI")))]
12808169689Skan  ""
12809169689Skan  "#"
12810169689Skan  "&& !reg_overlap_mentioned_p (operands[0], operands[3])"
12811169689Skan  [(set (match_dup 0) (neg:P (ltu:P (match_dup 1) (match_dup 2))))
12812169689Skan   (set (match_dup 0) (minus:P (match_dup 3) (match_dup 0)))]
1281390075Sobrien  "")
1281490075Sobrien
12815169689Skan(define_insn_and_split "*plus_ltu<mode>_compare"
12816103445Skan  [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,?y,?y")
1281790075Sobrien	(compare:CC
12818169689Skan	 (plus:P (ltu:P (match_operand:P 1 "gpc_reg_operand" "r,r,r,r")
12819169689Skan			(match_operand:P 2 "reg_or_neg_short_operand" "r,P,r,P"))
12820169689Skan		 (match_operand:P 3 "gpc_reg_operand" "r,r,r,r"))
1282190075Sobrien	 (const_int 0)))
12822169689Skan   (set (match_operand:P 0 "gpc_reg_operand" "=&r,&r,&r,&r")
12823169689Skan	(plus:P (ltu:P (match_dup 1) (match_dup 2)) (match_dup 3)))]
12824169689Skan  ""
12825169689Skan  "#"
12826169689Skan  "&& !reg_overlap_mentioned_p (operands[0], operands[3])"
12827169689Skan  [(set (match_dup 0) (neg:P (ltu:P (match_dup 1) (match_dup 2))))
12828169689Skan   (parallel [(set (match_dup 4)
12829169689Skan		   (compare:CC (minus:P (match_dup 3) (match_dup 0))
12830169689Skan			       (const_int 0)))
12831169689Skan	      (set (match_dup 0) (minus:P (match_dup 3) (match_dup 0)))])]
1283290075Sobrien  "")
1283390075Sobrien
12834169689Skan(define_insn "*neg_ltu<mode>"
12835169689Skan  [(set (match_operand:P 0 "gpc_reg_operand" "=r,r")
12836169689Skan	(neg:P (ltu:P (match_operand:P 1 "gpc_reg_operand" "r,r")
12837169689Skan		      (match_operand:P 2 "reg_or_neg_short_operand" "r,P"))))]
12838169689Skan  ""
1283990075Sobrien  "@
1284090075Sobrien   {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0
1284190075Sobrien   {ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0"
12842169689Skan  [(set_attr "type" "two")
12843169689Skan   (set_attr "length" "8")])
1284490075Sobrien
1284590075Sobrien(define_insn ""
1284690075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1284790075Sobrien	(ge:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1284890075Sobrien	       (match_operand:SI 2 "reg_or_short_operand" "rI")))
1284990075Sobrien   (clobber (match_scratch:SI 3 "=r"))]
1285090075Sobrien  "TARGET_POWER"
1285190075Sobrien  "doz%I2 %3,%1,%2\;{sfi|subfic} %0,%3,0\;{ae|adde} %0,%0,%3"
1285290075Sobrien   [(set_attr "length" "12")])
1285390075Sobrien
1285490075Sobrien(define_insn ""
1285590075Sobrien  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
1285690075Sobrien	(compare:CC
1285790075Sobrien	 (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1285890075Sobrien		(match_operand:SI 2 "reg_or_short_operand" "rI,rI"))
1285990075Sobrien	 (const_int 0)))
1286090075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1286190075Sobrien	(ge:SI (match_dup 1) (match_dup 2)))
1286290075Sobrien   (clobber (match_scratch:SI 3 "=r,r"))]
1286390075Sobrien  "TARGET_POWER"
1286490075Sobrien  "@
1286590075Sobrien   doz%I2 %3,%1,%2\;{sfi|subfic} %0,%3,0\;{ae.|adde.} %0,%0,%3
1286690075Sobrien   #"
1286790075Sobrien  [(set_attr "type" "compare")
1286890075Sobrien   (set_attr "length" "12,16")])
1286990075Sobrien
1287090075Sobrien(define_split
1287190075Sobrien  [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
1287290075Sobrien	(compare:CC
1287390075Sobrien	 (ge:SI (match_operand:SI 1 "gpc_reg_operand" "")
1287490075Sobrien		(match_operand:SI 2 "reg_or_short_operand" ""))
1287590075Sobrien	 (const_int 0)))
1287690075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "")
1287790075Sobrien	(ge:SI (match_dup 1) (match_dup 2)))
1287890075Sobrien   (clobber (match_scratch:SI 3 ""))]
1287990075Sobrien  "TARGET_POWER && reload_completed"
1288090075Sobrien  [(parallel [(set (match_dup 0)
12881103445Skan		   (ge:SI (match_dup 1) (match_dup 2)))
12882103445Skan	      (clobber (match_dup 3))])
1288390075Sobrien   (set (match_dup 4)
1288490075Sobrien	(compare:CC (match_dup 0)
1288590075Sobrien		    (const_int 0)))]
1288690075Sobrien  "")
1288790075Sobrien
1288890075Sobrien(define_insn ""
12889103445Skan  [(set (match_operand:SI 0 "gpc_reg_operand" "=&r")
1289090075Sobrien	(plus:SI (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1289190075Sobrien			(match_operand:SI 2 "reg_or_short_operand" "rI"))
12892103445Skan		 (match_operand:SI 3 "gpc_reg_operand" "r")))]
1289390075Sobrien  "TARGET_POWER"
12894103445Skan  "doz%I2 %0,%1,%2\;{sfi|subfic} %0,%0,0\;{aze|addze} %0,%3"
1289590075Sobrien  [(set_attr "length" "12")])
1289690075Sobrien
1289790075Sobrien(define_insn ""
1289890075Sobrien  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
1289990075Sobrien	(compare:CC
1290090075Sobrien	 (plus:SI (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1290190075Sobrien			 (match_operand:SI 2 "reg_or_short_operand" "rI,rI"))
1290290075Sobrien		  (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1290390075Sobrien	 (const_int 0)))
1290490075Sobrien   (clobber (match_scratch:SI 4 "=&r,&r"))]
1290590075Sobrien  "TARGET_POWER"
1290690075Sobrien  "@
1290790075Sobrien   doz%I2 %4,%1,%2\;{sfi|subfic} %4,%4,0\;{aze.|addze.} %4,%3
1290890075Sobrien   #"
1290990075Sobrien  [(set_attr "type" "compare")
1291090075Sobrien   (set_attr "length" "12,16")])
1291190075Sobrien
1291290075Sobrien(define_split
1291390075Sobrien  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
1291490075Sobrien	(compare:CC
1291590075Sobrien	 (plus:SI (ge:SI (match_operand:SI 1 "gpc_reg_operand" "")
1291690075Sobrien			 (match_operand:SI 2 "reg_or_short_operand" ""))
1291790075Sobrien		  (match_operand:SI 3 "gpc_reg_operand" ""))
1291890075Sobrien	 (const_int 0)))
1291990075Sobrien   (clobber (match_scratch:SI 4 ""))]
1292090075Sobrien  "TARGET_POWER && reload_completed"
1292190075Sobrien  [(set (match_dup 4)
1292290075Sobrien	(plus:SI (ge:SI (match_dup 1) (match_dup 2))
12923103445Skan		 (match_dup 3)))
1292490075Sobrien   (set (match_dup 0)
1292590075Sobrien	(compare:CC (match_dup 4)
1292690075Sobrien		    (const_int 0)))]
1292790075Sobrien  "")
1292890075Sobrien
1292990075Sobrien(define_insn ""
12930103445Skan  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
1293190075Sobrien	(compare:CC
1293290075Sobrien	 (plus:SI (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1293390075Sobrien			 (match_operand:SI 2 "reg_or_short_operand" "rI,rI"))
1293490075Sobrien		  (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1293590075Sobrien	 (const_int 0)))
12936103445Skan   (set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r")
12937103445Skan	(plus:SI (ge:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
1293890075Sobrien  "TARGET_POWER"
1293990075Sobrien  "@
12940103445Skan   doz%I2 %0,%1,%2\;{sfi|subfic} %0,%0,0\;{aze.|addze.} %0,%3
1294190075Sobrien   #"
1294290075Sobrien  [(set_attr "type" "compare")
1294390075Sobrien   (set_attr "length" "12,16")])
1294490075Sobrien
1294590075Sobrien(define_split
12946103445Skan  [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
1294790075Sobrien	(compare:CC
1294890075Sobrien	 (plus:SI (ge:SI (match_operand:SI 1 "gpc_reg_operand" "")
1294990075Sobrien			 (match_operand:SI 2 "reg_or_short_operand" ""))
1295090075Sobrien		  (match_operand:SI 3 "gpc_reg_operand" ""))
1295190075Sobrien	 (const_int 0)))
1295290075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "")
12953103445Skan	(plus:SI (ge:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
1295490075Sobrien  "TARGET_POWER && reload_completed"
12955103445Skan  [(set (match_dup 0)
1295690075Sobrien	(plus:SI (ge:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
12957103445Skan   (set (match_dup 4)
1295890075Sobrien	(compare:CC (match_dup 0)
1295990075Sobrien		    (const_int 0)))]
1296090075Sobrien  "")
1296190075Sobrien
1296290075Sobrien(define_insn ""
1296390075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1296490075Sobrien	(neg:SI (ge:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1296590075Sobrien		       (match_operand:SI 2 "reg_or_short_operand" "rI"))))]
1296690075Sobrien  "TARGET_POWER"
1296790075Sobrien  "doz%I2 %0,%1,%2\;{ai|addic} %0,%0,-1\;{sfe|subfe} %0,%0,%0"
1296890075Sobrien  [(set_attr "length" "12")])
1296990075Sobrien
12970169689Skan(define_insn "*geu<mode>"
12971169689Skan  [(set (match_operand:P 0 "gpc_reg_operand" "=r,r")
12972169689Skan	(geu:P (match_operand:P 1 "gpc_reg_operand" "r,r")
12973169689Skan	       (match_operand:P 2 "reg_or_neg_short_operand" "r,P")))]
12974169689Skan  ""
1297590075Sobrien  "@
1297690075Sobrien   {sf|subfc} %0,%2,%1\;{cal %0,0(0)|li %0,0}\;{ae|adde} %0,%0,%0
1297790075Sobrien   {ai|addic} %0,%1,%n2\;{cal %0,0(0)|li %0,0}\;{ae|adde} %0,%0,%0"
12978169689Skan  [(set_attr "type" "three")
12979169689Skan   (set_attr "length" "12")])
1298090075Sobrien
12981169689Skan(define_insn "*geu<mode>_compare"
1298290075Sobrien  [(set (match_operand:CC 3 "cc_reg_operand" "=x,x,?y,?y")
1298390075Sobrien	(compare:CC
12984169689Skan	 (geu:P (match_operand:P 1 "gpc_reg_operand" "r,r,r,r")
12985169689Skan		(match_operand:P 2 "reg_or_neg_short_operand" "r,P,r,P"))
1298690075Sobrien	 (const_int 0)))
12987169689Skan   (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r,r")
12988169689Skan	(geu:P (match_dup 1) (match_dup 2)))]
12989169689Skan  ""
1299090075Sobrien  "@
1299190075Sobrien   {sf|subfc} %0,%2,%1\;{cal %0,0(0)|li %0,0}\;{ae.|adde.} %0,%0,%0
1299290075Sobrien   {ai|addic} %0,%1,%n2\;{cal %0,0(0)|li %0,0}\;{ae.|adde.} %0,%0,%0
1299390075Sobrien   #
1299490075Sobrien   #"
1299590075Sobrien  [(set_attr "type" "compare")
1299690075Sobrien   (set_attr "length" "12,12,16,16")])
1299790075Sobrien
1299890075Sobrien(define_split
1299990075Sobrien  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
1300090075Sobrien	(compare:CC
13001169689Skan	 (geu:P (match_operand:P 1 "gpc_reg_operand" "")
13002169689Skan		(match_operand:P 2 "reg_or_neg_short_operand" ""))
1300390075Sobrien	 (const_int 0)))
13004169689Skan   (set (match_operand:P 0 "gpc_reg_operand" "")
13005169689Skan	(geu:P (match_dup 1) (match_dup 2)))]
13006169689Skan  "reload_completed"
1300790075Sobrien  [(set (match_dup 0)
13008169689Skan	(geu:P (match_dup 1) (match_dup 2)))
1300990075Sobrien   (set (match_dup 3)
1301090075Sobrien	(compare:CC (match_dup 0)
1301190075Sobrien		    (const_int 0)))]
1301290075Sobrien  "")
1301390075Sobrien
13014169689Skan(define_insn "*plus_geu<mode>"
13015169689Skan  [(set (match_operand:P 0 "gpc_reg_operand" "=&r,&r")
13016169689Skan	(plus:P (geu:P (match_operand:P 1 "gpc_reg_operand" "r,r")
13017169689Skan		       (match_operand:P 2 "reg_or_neg_short_operand" "r,P"))
13018169689Skan		(match_operand:P 3 "gpc_reg_operand" "r,r")))]
13019169689Skan  ""
1302090075Sobrien  "@
1302196263Sobrien   {sf|subfc} %0,%2,%1\;{aze|addze} %0,%3
1302296263Sobrien   {ai|addic} %0,%1,%n2\;{aze|addze} %0,%3"
13023169689Skan  [(set_attr "type" "two")
13024169689Skan   (set_attr "length" "8")])
1302590075Sobrien
1302690075Sobrien(define_insn ""
1302790075Sobrien  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
1302890075Sobrien	(compare:CC
1302990075Sobrien	 (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
1303090075Sobrien			  (match_operand:SI 2 "reg_or_neg_short_operand" "r,P,r,P"))
1303190075Sobrien		  (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r"))
1303290075Sobrien	 (const_int 0)))
1303390075Sobrien   (clobber (match_scratch:SI 4 "=&r,&r,&r,&r"))]
13034132718Skan  "TARGET_32BIT"
1303590075Sobrien  "@
1303690075Sobrien   {sf|subfc} %4,%2,%1\;{aze.|addze.} %4,%3
1303790075Sobrien   {ai|addic} %4,%1,%n2\;{aze.|addze.} %4,%3
1303890075Sobrien   #
1303990075Sobrien   #"
1304090075Sobrien  [(set_attr "type" "compare")
1304190075Sobrien   (set_attr "length" "8,8,12,12")])
1304290075Sobrien
1304390075Sobrien(define_split
1304490075Sobrien  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
1304590075Sobrien	(compare:CC
1304690075Sobrien	 (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "")
1304790075Sobrien			  (match_operand:SI 2 "reg_or_neg_short_operand" ""))
1304890075Sobrien		  (match_operand:SI 3 "gpc_reg_operand" ""))
1304990075Sobrien	 (const_int 0)))
1305090075Sobrien   (clobber (match_scratch:SI 4 ""))]
13051132718Skan  "TARGET_32BIT && reload_completed"
1305290075Sobrien  [(set (match_dup 4)
1305390075Sobrien	(plus:SI (geu:SI (match_dup 1) (match_dup 2))
1305490075Sobrien		  (match_dup 3)))
1305590075Sobrien   (set (match_dup 0)
1305690075Sobrien	(compare:CC (match_dup 4)
1305790075Sobrien		    (const_int 0)))]
1305890075Sobrien  "")
1305990075Sobrien
1306090075Sobrien(define_insn ""
13061103445Skan  [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,?y,?y")
1306290075Sobrien	(compare:CC
1306390075Sobrien	 (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
1306490075Sobrien			  (match_operand:SI 2 "reg_or_neg_short_operand" "r,P,r,P"))
1306590075Sobrien		  (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r"))
1306690075Sobrien	 (const_int 0)))
13067103445Skan   (set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r,&r,&r")
13068103445Skan	(plus:SI (geu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
13069132718Skan  "TARGET_32BIT"
1307090075Sobrien  "@
13071103445Skan   {sf|subfc} %0,%2,%1\;{aze.|addze.} %0,%3
13072103445Skan   {ai|addic} %0,%1,%n2\;{aze.|addze.} %0,%3
1307390075Sobrien   #
1307490075Sobrien   #"
1307590075Sobrien  [(set_attr "type" "compare")
1307690075Sobrien   (set_attr "length" "8,8,12,12")])
1307790075Sobrien
1307890075Sobrien(define_split
13079103445Skan  [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
1308090075Sobrien	(compare:CC
1308190075Sobrien	 (plus:SI (geu:SI (match_operand:SI 1 "gpc_reg_operand" "")
1308290075Sobrien			  (match_operand:SI 2 "reg_or_neg_short_operand" ""))
1308390075Sobrien		  (match_operand:SI 3 "gpc_reg_operand" ""))
1308490075Sobrien	 (const_int 0)))
1308590075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "")
13086103445Skan	(plus:SI (geu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
13087132718Skan  "TARGET_32BIT && reload_completed"
13088103445Skan  [(set (match_dup 0)
1308990075Sobrien	(plus:SI (geu:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
13090103445Skan   (set (match_dup 4)
1309190075Sobrien	(compare:CC (match_dup 0)
1309290075Sobrien		    (const_int 0)))]
1309390075Sobrien  "")
1309490075Sobrien
13095169689Skan(define_insn "*neg_geu<mode>"
13096169689Skan  [(set (match_operand:P 0 "gpc_reg_operand" "=r,r")
13097169689Skan	(neg:P (geu:P (match_operand:P 1 "gpc_reg_operand" "r,r")
13098169689Skan		      (match_operand:P 2 "reg_or_short_operand" "r,I"))))]
13099169689Skan  ""
1310090075Sobrien  "@
1310190075Sobrien   {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;nand %0,%0,%0
1310290075Sobrien   {sfi|subfic} %0,%1,-1\;{a%I2|add%I2c} %0,%0,%2\;{sfe|subfe} %0,%0,%0"
13103169689Skan  [(set_attr "type" "three")
13104169689Skan   (set_attr "length" "12")])
1310590075Sobrien
13106169689Skan(define_insn "*and_neg_geu<mode>"
13107169689Skan  [(set (match_operand:P 0 "gpc_reg_operand" "=&r,&r")
13108169689Skan	(and:P (neg:P
13109169689Skan		 (geu:P (match_operand:P 1 "gpc_reg_operand" "r,r")
13110169689Skan			(match_operand:P 2 "reg_or_neg_short_operand" "r,P")))
13111169689Skan		(match_operand:P 3 "gpc_reg_operand" "r,r")))]
13112169689Skan  ""
1311390075Sobrien  "@
13114103445Skan   {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;andc %0,%3,%0
13115103445Skan   {ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0\;andc %0,%3,%0"
13116169689Skan  [(set_attr "type" "three")
13117169689Skan   (set_attr "length" "12")])
1311890075Sobrien
1311990075Sobrien(define_insn ""
1312090075Sobrien  [(set (match_operand:CC 0 "cc_reg_operand" "=x,x,?y,?y")
1312190075Sobrien	(compare:CC
1312290075Sobrien	 (and:SI (neg:SI
1312390075Sobrien		  (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
1312490075Sobrien			  (match_operand:SI 2 "reg_or_neg_short_operand" "r,P,r,P")))
1312590075Sobrien		 (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r"))
1312690075Sobrien	 (const_int 0)))
1312790075Sobrien   (clobber (match_scratch:SI 4 "=&r,&r,&r,&r"))]
13128132718Skan  "TARGET_32BIT"
1312990075Sobrien  "@
1313090075Sobrien   {sf|subfc} %4,%2,%1\;{sfe|subfe} %4,%4,%4\;andc. %4,%3,%4
1313190075Sobrien   {ai|addic} %4,%1,%n2\;{sfe|subfe} %4,%4,%4\;andc. %4,%3,%4
1313290075Sobrien   #
1313390075Sobrien   #"
1313490075Sobrien  [(set_attr "type" "compare")
1313590075Sobrien   (set_attr "length" "12,12,16,16")])
1313690075Sobrien
1313790075Sobrien(define_split
1313890075Sobrien  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
1313990075Sobrien	(compare:CC
1314090075Sobrien	 (and:SI (neg:SI
1314190075Sobrien		  (geu:SI (match_operand:SI 1 "gpc_reg_operand" "")
1314290075Sobrien			  (match_operand:SI 2 "reg_or_neg_short_operand" "")))
1314390075Sobrien		 (match_operand:SI 3 "gpc_reg_operand" ""))
1314490075Sobrien	 (const_int 0)))
1314590075Sobrien   (clobber (match_scratch:SI 4 ""))]
13146132718Skan  "TARGET_32BIT && reload_completed"
1314790075Sobrien  [(set (match_dup 4)
13148103445Skan	(and:SI (neg:SI (geu:SI (match_dup 1) (match_dup 2)))
13149103445Skan		(match_dup 3)))
1315090075Sobrien   (set (match_dup 0)
1315190075Sobrien	(compare:CC (match_dup 4)
1315290075Sobrien		    (const_int 0)))]
1315390075Sobrien  "")
1315490075Sobrien
1315590075Sobrien(define_insn ""
13156103445Skan  [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,?y,?y")
1315790075Sobrien	(compare:CC
1315890075Sobrien	 (and:SI (neg:SI
1315990075Sobrien		  (geu:SI (match_operand:SI 1 "gpc_reg_operand" "r,r,r,r")
1316090075Sobrien			  (match_operand:SI 2 "reg_or_neg_short_operand" "r,P,r,P")))
1316190075Sobrien		 (match_operand:SI 3 "gpc_reg_operand" "r,r,r,r"))
1316290075Sobrien	 (const_int 0)))
13163103445Skan   (set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r,&r,&r")
13164103445Skan	(and:SI (neg:SI (geu:SI (match_dup 1) (match_dup 2))) (match_dup 3)))]
13165132718Skan  "TARGET_32BIT"
1316690075Sobrien  "@
13167103445Skan   {sf|subfc} %0,%2,%1\;{sfe|subfe} %0,%0,%0\;andc. %0,%3,%0
13168103445Skan   {ai|addic} %0,%1,%n2\;{sfe|subfe} %0,%0,%0\;andc. %0,%3,%0
1316990075Sobrien   #
1317090075Sobrien   #"
1317190075Sobrien  [(set_attr "type" "compare")
1317290075Sobrien   (set_attr "length" "12,12,16,16")])
1317390075Sobrien
1317490075Sobrien(define_split
13175103445Skan  [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
1317690075Sobrien	(compare:CC
1317790075Sobrien	 (and:SI (neg:SI
1317890075Sobrien		  (geu:SI (match_operand:SI 1 "gpc_reg_operand" "")
1317990075Sobrien			  (match_operand:SI 2 "reg_or_neg_short_operand" "")))
1318090075Sobrien		 (match_operand:SI 3 "gpc_reg_operand" ""))
1318190075Sobrien	 (const_int 0)))
1318290075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "")
13183103445Skan	(and:SI (neg:SI (geu:SI (match_dup 1) (match_dup 2))) (match_dup 3)))]
13184132718Skan  "TARGET_32BIT && reload_completed"
13185103445Skan  [(set (match_dup 0)
1318690075Sobrien	(and:SI (neg:SI (geu:SI (match_dup 1) (match_dup 2))) (match_dup 3)))
13187103445Skan   (set (match_dup 4)
1318890075Sobrien	(compare:CC (match_dup 0)
1318990075Sobrien		    (const_int 0)))]
1319090075Sobrien  "")
1319190075Sobrien
1319290075Sobrien(define_insn ""
1319390075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1319490075Sobrien	(gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1319590075Sobrien	       (match_operand:SI 2 "reg_or_short_operand" "r")))]
1319690075Sobrien  "TARGET_POWER"
1319790075Sobrien  "doz %0,%2,%1\;nabs %0,%0\;{sri|srwi} %0,%0,31"
1319890075Sobrien  [(set_attr "length" "12")])
1319990075Sobrien
1320090075Sobrien(define_insn ""
1320190075Sobrien  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1320290075Sobrien	(compare:CC
1320390075Sobrien	 (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1320490075Sobrien		(match_operand:SI 2 "reg_or_short_operand" "r,r"))
1320590075Sobrien	 (const_int 0)))
1320690075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
1320790075Sobrien	(gt:SI (match_dup 1) (match_dup 2)))]
1320890075Sobrien  "TARGET_POWER"
1320990075Sobrien  "@
1321090075Sobrien   doz %0,%2,%1\;nabs %0,%0\;{sri.|srwi.} %0,%0,31
1321190075Sobrien   #"
1321290075Sobrien  [(set_attr "type" "delayed_compare")
1321390075Sobrien   (set_attr "length" "12,16")])
1321490075Sobrien
1321590075Sobrien(define_split
1321690075Sobrien  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
1321790075Sobrien	(compare:CC
1321890075Sobrien	 (gt:SI (match_operand:SI 1 "gpc_reg_operand" "")
1321990075Sobrien		(match_operand:SI 2 "reg_or_short_operand" ""))
1322090075Sobrien	 (const_int 0)))
1322190075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "")
1322290075Sobrien	(gt:SI (match_dup 1) (match_dup 2)))]
1322390075Sobrien  "TARGET_POWER && reload_completed"
1322490075Sobrien  [(set (match_dup 0)
1322590075Sobrien	(gt:SI (match_dup 1) (match_dup 2)))
1322690075Sobrien   (set (match_dup 3)
1322790075Sobrien	(compare:CC (match_dup 0)
1322890075Sobrien		    (const_int 0)))]
1322990075Sobrien  "")
1323090075Sobrien
13231169689Skan(define_insn "*plus_gt0<mode>"
13232169689Skan  [(set (match_operand:P 0 "gpc_reg_operand" "=&r")
13233169689Skan	(plus:P (gt:P (match_operand:P 1 "gpc_reg_operand" "r")
13234169689Skan		      (const_int 0))
13235169689Skan		 (match_operand:P 2 "gpc_reg_operand" "r")))]
13236169689Skan  ""
1323796263Sobrien  "{a|addc} %0,%1,%1\;{sfe|subfe} %0,%1,%0\;{aze|addze} %0,%2"
13238169689Skan  [(set_attr "type" "three")
13239169689Skan   (set_attr "length" "12")])
1324090075Sobrien
1324190075Sobrien(define_insn ""
1324290075Sobrien  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
1324390075Sobrien	(compare:CC
1324490075Sobrien	 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1324590075Sobrien			 (const_int 0))
1324690075Sobrien		  (match_operand:SI 2 "gpc_reg_operand" "r,r"))
1324790075Sobrien	 (const_int 0)))
1324890075Sobrien   (clobber (match_scratch:SI 3 "=&r,&r"))]
13249132718Skan  "TARGET_32BIT"
1325090075Sobrien  "@
1325190075Sobrien   {a|addc} %3,%1,%1\;{sfe|subfe} %3,%1,%3\;{aze.|addze.} %3,%2
1325290075Sobrien   #"
1325390075Sobrien  [(set_attr "type" "compare")
1325490075Sobrien   (set_attr "length" "12,16")])
1325590075Sobrien
1325690075Sobrien(define_split
1325790075Sobrien  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
1325890075Sobrien	(compare:CC
1325990075Sobrien	 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "")
1326090075Sobrien			 (const_int 0))
1326190075Sobrien		  (match_operand:SI 2 "gpc_reg_operand" ""))
1326290075Sobrien	 (const_int 0)))
1326390075Sobrien   (clobber (match_scratch:SI 3 ""))]
13264132718Skan  "TARGET_32BIT && reload_completed"
1326590075Sobrien  [(set (match_dup 3)
1326690075Sobrien	(plus:SI (gt:SI (match_dup 1) (const_int 0))
1326790075Sobrien		  (match_dup 2)))
1326890075Sobrien   (set (match_dup 0)
1326990075Sobrien	(compare:CC (match_dup 3)
1327090075Sobrien		    (const_int 0)))]
1327190075Sobrien  "")
1327290075Sobrien
1327390075Sobrien(define_insn ""
1327490075Sobrien  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
1327590075Sobrien	(compare:CC
1327690075Sobrien	 (plus:DI (gt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
1327790075Sobrien			 (const_int 0))
1327890075Sobrien		  (match_operand:DI 2 "gpc_reg_operand" "r,r"))
1327990075Sobrien	 (const_int 0)))
1328090075Sobrien   (clobber (match_scratch:DI 3 "=&r,&r"))]
13281132718Skan  "TARGET_64BIT"
1328290075Sobrien  "@
1328390075Sobrien   addc %3,%1,%1\;subfe %3,%1,%3\;addze. %3,%2
1328490075Sobrien   #"
1328590075Sobrien  [(set_attr "type" "compare")
1328690075Sobrien   (set_attr "length" "12,16")])
1328790075Sobrien
1328890075Sobrien(define_split
1328990075Sobrien  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
1329090075Sobrien	(compare:CC
1329190075Sobrien	 (plus:DI (gt:DI (match_operand:DI 1 "gpc_reg_operand" "")
1329290075Sobrien			 (const_int 0))
1329390075Sobrien		  (match_operand:DI 2 "gpc_reg_operand" ""))
1329490075Sobrien	 (const_int 0)))
1329590075Sobrien   (clobber (match_scratch:DI 3 ""))]
13296132718Skan  "TARGET_64BIT && reload_completed"
1329790075Sobrien  [(set (match_dup 3)
1329890075Sobrien	(plus:DI (gt:DI (match_dup 1) (const_int 0))
13299103445Skan		 (match_dup 2)))
1330090075Sobrien   (set (match_dup 0)
1330190075Sobrien	(compare:CC (match_dup 3)
1330290075Sobrien		    (const_int 0)))]
1330390075Sobrien  "")
1330490075Sobrien
1330590075Sobrien(define_insn ""
13306103445Skan  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1330790075Sobrien	(compare:CC
1330890075Sobrien	 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1330990075Sobrien			 (const_int 0))
1331090075Sobrien		  (match_operand:SI 2 "gpc_reg_operand" "r,r"))
1331190075Sobrien	 (const_int 0)))
13312103445Skan   (set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r")
13313103445Skan	(plus:SI (gt:SI (match_dup 1) (const_int 0)) (match_dup 2)))]
13314132718Skan  "TARGET_32BIT"
1331590075Sobrien  "@
13316103445Skan   {a|addc} %0,%1,%1\;{sfe|subfe} %0,%1,%0\;{aze.|addze.} %0,%2
1331790075Sobrien   #"
1331890075Sobrien  [(set_attr "type" "compare")
1331990075Sobrien   (set_attr "length" "12,16")])
1332090075Sobrien
1332190075Sobrien(define_split
13322103445Skan  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
1332390075Sobrien	(compare:CC
1332490075Sobrien	 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "")
1332590075Sobrien			 (const_int 0))
1332690075Sobrien		  (match_operand:SI 2 "gpc_reg_operand" ""))
1332790075Sobrien	 (const_int 0)))
1332890075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "")
13329103445Skan	(plus:SI (gt:SI (match_dup 1) (const_int 0)) (match_dup 2)))]
13330132718Skan  "TARGET_32BIT && reload_completed"
13331103445Skan  [(set (match_dup 0)
1333290075Sobrien	(plus:SI (gt:SI (match_dup 1) (const_int 0)) (match_dup 2)))
13333103445Skan   (set (match_dup 3)
1333490075Sobrien	(compare:CC (match_dup 0)
1333590075Sobrien		    (const_int 0)))]
1333690075Sobrien  "")
1333790075Sobrien
1333890075Sobrien(define_insn ""
13339103445Skan  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1334090075Sobrien	(compare:CC
1334190075Sobrien	 (plus:DI (gt:DI (match_operand:DI 1 "gpc_reg_operand" "r,r")
1334290075Sobrien			 (const_int 0))
1334390075Sobrien		  (match_operand:DI 2 "gpc_reg_operand" "r,r"))
1334490075Sobrien	 (const_int 0)))
13345103445Skan   (set (match_operand:DI 0 "gpc_reg_operand" "=&r,&r")
13346103445Skan	(plus:DI (gt:DI (match_dup 1) (const_int 0)) (match_dup 2)))]
13347132718Skan  "TARGET_64BIT"
1334890075Sobrien  "@
13349103445Skan   addc %0,%1,%1\;subfe %0,%1,%0\;addze. %0,%2
1335090075Sobrien   #"
1335190075Sobrien  [(set_attr "type" "compare")
1335290075Sobrien   (set_attr "length" "12,16")])
1335390075Sobrien
1335490075Sobrien(define_split
13355103445Skan  [(set (match_operand:CC 3 "cc_reg_not_cr0_operand" "")
1335690075Sobrien	(compare:CC
1335790075Sobrien	 (plus:DI (gt:DI (match_operand:DI 1 "gpc_reg_operand" "")
1335890075Sobrien			 (const_int 0))
1335990075Sobrien		  (match_operand:DI 2 "gpc_reg_operand" ""))
1336090075Sobrien	 (const_int 0)))
1336190075Sobrien   (set (match_operand:DI 0 "gpc_reg_operand" "")
13362103445Skan	(plus:DI (gt:DI (match_dup 1) (const_int 0)) (match_dup 2)))]
13363132718Skan  "TARGET_64BIT && reload_completed"
13364103445Skan  [(set (match_dup 0)
1336590075Sobrien	(plus:DI (gt:DI (match_dup 1) (const_int 0)) (match_dup 2)))
13366103445Skan   (set (match_dup 3)
1336790075Sobrien	(compare:CC (match_dup 0)
1336890075Sobrien		    (const_int 0)))]
1336990075Sobrien  "")
1337090075Sobrien
1337190075Sobrien(define_insn ""
13372103445Skan  [(set (match_operand:SI 0 "gpc_reg_operand" "=&r")
1337390075Sobrien	(plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1337490075Sobrien			(match_operand:SI 2 "reg_or_short_operand" "r"))
13375103445Skan		 (match_operand:SI 3 "gpc_reg_operand" "r")))]
1337690075Sobrien  "TARGET_POWER"
13377103445Skan  "doz %0,%2,%1\;{ai|addic} %0,%0,-1\;{aze|addze} %0,%3"
1337890075Sobrien  [(set_attr "length" "12")])
1337990075Sobrien
1338090075Sobrien(define_insn ""
1338190075Sobrien  [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
1338290075Sobrien	(compare:CC
1338390075Sobrien	 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1338490075Sobrien			 (match_operand:SI 2 "reg_or_short_operand" "r,r"))
1338590075Sobrien		  (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1338690075Sobrien	 (const_int 0)))
1338790075Sobrien   (clobber (match_scratch:SI 4 "=&r,&r"))]
1338890075Sobrien  "TARGET_POWER"
1338990075Sobrien  "@
1339090075Sobrien   doz %4,%2,%1\;{ai|addic} %4,%4,-1\;{aze.|addze.} %4,%3
1339190075Sobrien   #"
1339290075Sobrien  [(set_attr "type" "compare")
1339390075Sobrien   (set_attr "length" "12,16")])
1339490075Sobrien
1339590075Sobrien(define_split
1339690075Sobrien  [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
1339790075Sobrien	(compare:CC
1339890075Sobrien	 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "")
1339990075Sobrien			 (match_operand:SI 2 "reg_or_short_operand" ""))
1340090075Sobrien		  (match_operand:SI 3 "gpc_reg_operand" ""))
1340190075Sobrien	 (const_int 0)))
1340290075Sobrien   (clobber (match_scratch:SI 4 ""))]
1340390075Sobrien  "TARGET_POWER && reload_completed"
1340490075Sobrien  [(set (match_dup 4)
13405103445Skan	(plus:SI (gt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
1340690075Sobrien   (set (match_dup 0)
1340790075Sobrien	(compare:CC (match_dup 4)
1340890075Sobrien		    (const_int 0)))]
1340990075Sobrien  "")
1341090075Sobrien
1341190075Sobrien(define_insn ""
13412103445Skan  [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
1341390075Sobrien	(compare:CC
1341490075Sobrien	 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
1341590075Sobrien			 (match_operand:SI 2 "reg_or_short_operand" "r,r"))
1341690075Sobrien		  (match_operand:SI 3 "gpc_reg_operand" "r,r"))
1341790075Sobrien	 (const_int 0)))
13418103445Skan   (set (match_operand:SI 0 "gpc_reg_operand" "=&r,&r")
13419103445Skan	(plus:SI (gt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
1342090075Sobrien  "TARGET_POWER"
1342190075Sobrien  "@
13422103445Skan   doz %0,%2,%1\;{ai|addic} %0,%0,-1\;{aze.|addze.} %0,%3
1342390075Sobrien   #"
1342490075Sobrien  [(set_attr "type" "compare")
1342590075Sobrien   (set_attr "length" "12,16")])
1342690075Sobrien
1342790075Sobrien(define_split
13428103445Skan  [(set (match_operand:CC 4 "cc_reg_not_cr0_operand" "")
1342990075Sobrien	(compare:CC
1343090075Sobrien	 (plus:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "")
1343190075Sobrien			 (match_operand:SI 2 "reg_or_short_operand" ""))
1343290075Sobrien		  (match_operand:SI 3 "gpc_reg_operand" ""))
1343390075Sobrien	 (const_int 0)))
1343490075Sobrien   (set (match_operand:SI 0 "gpc_reg_operand" "")
13435103445Skan	(plus:SI (gt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
1343690075Sobrien  "TARGET_POWER && reload_completed"
13437103445Skan  [(set (match_dup 0)
1343890075Sobrien	(plus:SI (gt:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
13439103445Skan   (set (match_dup 4)
1344090075Sobrien	(compare:CC (match_dup 0)
1344190075Sobrien		    (const_int 0)))]
1344290075Sobrien  "")
1344390075Sobrien
1344490075Sobrien(define_insn ""
1344590075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1344690075Sobrien	(neg:SI (gt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
1344790075Sobrien		       (match_operand:SI 2 "reg_or_short_operand" "r"))))]
1344890075Sobrien  "TARGET_POWER"
1344990075Sobrien  "doz %0,%2,%1\;nabs %0,%0\;{srai|srawi} %0,%0,31"
1345090075Sobrien  [(set_attr "length" "12")])
1345190075Sobrien
13452169689Skan(define_insn_and_split "*gtu<mode>"
13453169689Skan  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
13454169689Skan	(gtu:P (match_operand:P 1 "gpc_reg_operand" "r")
13455169689Skan	       (match_operand:P 2 "reg_or_short_operand" "rI")))]
13456169689Skan  ""
13457169689Skan  "#"
13458169689Skan  ""
13459169689Skan  [(set (match_dup 0) (neg:P (gtu:P (match_dup 1) (match_dup 2))))
13460169689Skan   (set (match_dup 0) (neg:P (match_dup 0)))]
1346190075Sobrien  "")
1346290075Sobrien
13463169689Skan(define_insn_and_split "*gtu<mode>_compare"
1346490075Sobrien  [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1346590075Sobrien	(compare:CC
13466169689Skan	 (gtu:P (match_operand:P 1 "gpc_reg_operand" "r,r")
13467169689Skan		 (match_operand:P 2 "reg_or_short_operand" "rI,rI"))
1346890075Sobrien	 (const_int 0)))
13469169689Skan   (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
13470169689Skan	(gtu:P (match_dup 1) (match_dup 2)))]
13471169689Skan  ""
13472169689Skan  "#"
13473169689Skan  ""
13474169689Skan  [(set (match_dup 0) (neg:P (gtu:P (match_dup 1) (match_dup 2))))
13475169689Skan   (parallel [(set (match_dup 3)
13476169689Skan		   (compare:CC (neg:P (match_dup 0)) (const_int 0)))
13477169689Skan	      (set (match_dup 0) (neg:P (match_dup 0)))])]
1347890075Sobrien  "")
1347990075Sobrien
13480169689Skan(define_insn_and_split "*plus_gtu<mode>"
13481169689Skan  [(set (match_operand:P 0 "gpc_reg_operand" "=&r")
13482169689Skan        (plus:P (gtu:P (match_operand:P 1 "gpc_reg_operand" "r")
13483169689Skan		       (match_operand:P 2 "reg_or_short_operand" "rI"))
13484169689Skan		(match_operand:P 3 "reg_or_short_operand" "rI")))]
13485169689Skan  ""
13486169689Skan  "#"
13487169689Skan  "&& !reg_overlap_mentioned_p (operands[0], operands[3])"
13488169689Skan  [(set (match_dup 0) (neg:P (gtu:P (match_dup 1) (match_dup 2))))
13489169689Skan   (set (match_dup 0) (minus:P (match_dup 3) (match_dup 0)))]
1349090075Sobrien  "")
1349190075Sobrien
13492169689Skan(define_insn_and_split "*plus_gtu<mode>_compare"
13493103445Skan  [(set (match_operand:CC 4 "cc_reg_operand" "=x,x,?y,?y")
1349490075Sobrien	(compare:CC
13495169689Skan	 (plus:P (gtu:P (match_operand:P 1 "gpc_reg_operand" "r,r,r,r")
13496169689Skan			(match_operand:P 2 "reg_or_short_operand" "I,r,I,r"))
13497169689Skan		 (match_operand:P 3 "gpc_reg_operand" "r,r,r,r"))
1349890075Sobrien	 (const_int 0)))
13499169689Skan   (set (match_operand:P 0 "gpc_reg_operand" "=&r,&r,&r,&r")
13500169689Skan	(plus:P (gtu:P (match_dup 1) (match_dup 2)) (match_dup 3)))]
13501169689Skan  ""
13502169689Skan  "#"
13503169689Skan  "&& !reg_overlap_mentioned_p (operands[0], operands[3])"
13504169689Skan  [(set (match_dup 0) (neg:P (gtu:P (match_dup 1) (match_dup 2))))
13505169689Skan   (parallel [(set (match_dup 4)
13506169689Skan		   (compare:CC (minus:P (match_dup 3) (match_dup 0))
13507169689Skan			       (const_int 0)))
13508169689Skan	      (set (match_dup 0) (minus:P (match_dup 3) (match_dup 0)))])]
1350990075Sobrien  "")
1351090075Sobrien
13511169689Skan(define_insn "*neg_gtu<mode>"
13512169689Skan  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
13513169689Skan	(neg:P (gtu:P (match_operand:P 1 "gpc_reg_operand" "r")
13514169689Skan		      (match_operand:P 2 "reg_or_short_operand" "rI"))))]
13515169689Skan  ""
1351690075Sobrien  "{sf%I2|subf%I2c} %0,%1,%2\;{sfe|subfe} %0,%0,%0"
13517169689Skan  [(set_attr "type" "two")
13518169689Skan   (set_attr "length" "8")])
1351990075Sobrien
1352090075Sobrien
1352190075Sobrien;; Define both directions of branch and return.  If we need a reload
1352290075Sobrien;; register, we'd rather use CR0 since it is much easier to copy a
1352390075Sobrien;; register CC value to there.
1352490075Sobrien
1352590075Sobrien(define_insn ""
1352690075Sobrien  [(set (pc)
1352790075Sobrien	(if_then_else (match_operator 1 "branch_comparison_operator"
1352890075Sobrien				      [(match_operand 2
13529132718Skan						      "cc_reg_operand" "y")
1353090075Sobrien				       (const_int 0)])
1353190075Sobrien		      (label_ref (match_operand 0 "" ""))
1353290075Sobrien		      (pc)))]
1353390075Sobrien  ""
1353490075Sobrien  "*
1353590075Sobrien{
1353690075Sobrien  return output_cbranch (operands[1], \"%l0\", 0, insn);
1353790075Sobrien}"
1353890075Sobrien  [(set_attr "type" "branch")])
1353990075Sobrien
1354090075Sobrien(define_insn ""
1354190075Sobrien  [(set (pc)
1354290075Sobrien	(if_then_else (match_operator 0 "branch_comparison_operator"
1354390075Sobrien				      [(match_operand 1
13544132718Skan						      "cc_reg_operand" "y")
1354590075Sobrien				       (const_int 0)])
1354690075Sobrien		      (return)
1354790075Sobrien		      (pc)))]
1354890075Sobrien  "direct_return ()"
1354990075Sobrien  "*
1355090075Sobrien{
1355190075Sobrien  return output_cbranch (operands[0], NULL, 0, insn);
1355290075Sobrien}"
13553169689Skan  [(set_attr "type" "jmpreg")
1355490075Sobrien   (set_attr "length" "4")])
1355590075Sobrien
1355690075Sobrien(define_insn ""
1355790075Sobrien  [(set (pc)
1355890075Sobrien	(if_then_else (match_operator 1 "branch_comparison_operator"
1355990075Sobrien				      [(match_operand 2
13560132718Skan						      "cc_reg_operand" "y")
1356190075Sobrien				       (const_int 0)])
1356290075Sobrien		      (pc)
1356390075Sobrien		      (label_ref (match_operand 0 "" ""))))]
1356490075Sobrien  ""
1356590075Sobrien  "*
1356690075Sobrien{
1356790075Sobrien  return output_cbranch (operands[1], \"%l0\", 1, insn);
1356890075Sobrien}"
1356990075Sobrien  [(set_attr "type" "branch")])
1357090075Sobrien
1357190075Sobrien(define_insn ""
1357290075Sobrien  [(set (pc)
1357390075Sobrien	(if_then_else (match_operator 0 "branch_comparison_operator"
1357490075Sobrien				      [(match_operand 1
13575132718Skan						      "cc_reg_operand" "y")
1357690075Sobrien				       (const_int 0)])
1357790075Sobrien		      (pc)
1357890075Sobrien		      (return)))]
1357990075Sobrien  "direct_return ()"
1358090075Sobrien  "*
1358190075Sobrien{
1358290075Sobrien  return output_cbranch (operands[0], NULL, 1, insn);
1358390075Sobrien}"
13584169689Skan  [(set_attr "type" "jmpreg")
1358590075Sobrien   (set_attr "length" "4")])
1358690075Sobrien
1358790075Sobrien;; Logic on condition register values.
1358890075Sobrien
1358990075Sobrien; This pattern matches things like
1359090075Sobrien; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
1359190075Sobrien;					   (eq:SI (reg:CCFP 68) (const_int 0)))
1359290075Sobrien;				   (const_int 1)))
1359390075Sobrien; which are generated by the branch logic.
13594132718Skan; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
1359590075Sobrien
13596132718Skan(define_insn "*cceq_ior_compare"
13597132718Skan  [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
1359890075Sobrien        (compare:CCEQ (match_operator:SI 1 "boolean_operator"
13599132718Skan	                [(match_operator:SI 2
1360090075Sobrien				      "branch_positive_comparison_operator"
1360190075Sobrien				      [(match_operand 3
13602132718Skan						      "cc_reg_operand" "y,y")
1360390075Sobrien				       (const_int 0)])
13604132718Skan	                 (match_operator:SI 4
1360590075Sobrien				      "branch_positive_comparison_operator"
1360690075Sobrien				      [(match_operand 5
13607132718Skan						      "cc_reg_operand" "0,y")
1360890075Sobrien				       (const_int 0)])])
1360990075Sobrien		      (const_int 1)))]
1361090075Sobrien  ""
1361190075Sobrien  "cr%q1 %E0,%j2,%j4"
13612132718Skan  [(set_attr "type" "cr_logical,delayed_cr")])
1361390075Sobrien
1361490075Sobrien; Why is the constant -1 here, but 1 in the previous pattern?
1361590075Sobrien; Because ~1 has all but the low bit set.
1361690075Sobrien(define_insn ""
13617132718Skan  [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
1361890075Sobrien        (compare:CCEQ (match_operator:SI 1 "boolean_or_operator"
13619132718Skan	                [(not:SI (match_operator:SI 2
1362090075Sobrien				      "branch_positive_comparison_operator"
1362190075Sobrien				      [(match_operand 3
13622132718Skan						      "cc_reg_operand" "y,y")
1362390075Sobrien				       (const_int 0)]))
1362490075Sobrien	                 (match_operator:SI 4
1362590075Sobrien				"branch_positive_comparison_operator"
1362690075Sobrien				[(match_operand 5
13627132718Skan						"cc_reg_operand" "0,y")
1362890075Sobrien				 (const_int 0)])])
1362990075Sobrien		      (const_int -1)))]
1363090075Sobrien  ""
1363190075Sobrien  "cr%q1 %E0,%j2,%j4"
13632132718Skan  [(set_attr "type" "cr_logical,delayed_cr")])
1363390075Sobrien
13634132718Skan(define_insn "*cceq_rev_compare"
13635132718Skan  [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
1363690075Sobrien	(compare:CCEQ (match_operator:SI 1
1363790075Sobrien				      "branch_positive_comparison_operator"
1363890075Sobrien				      [(match_operand 2
13639132718Skan						      "cc_reg_operand" "0,y")
1364090075Sobrien				       (const_int 0)])
1364190075Sobrien		      (const_int 0)))]
13642132718Skan  ""
1364390075Sobrien  "{crnor %E0,%j1,%j1|crnot %E0,%j1}"
13644132718Skan  [(set_attr "type" "cr_logical,delayed_cr")])
1364590075Sobrien
1364690075Sobrien;; If we are comparing the result of two comparisons, this can be done
1364790075Sobrien;; using creqv or crxor.
1364890075Sobrien
1364990075Sobrien(define_insn_and_split ""
1365090075Sobrien  [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
1365190075Sobrien	(compare:CCEQ (match_operator 1 "branch_comparison_operator"
1365290075Sobrien			      [(match_operand 2 "cc_reg_operand" "y")
1365390075Sobrien			       (const_int 0)])
1365490075Sobrien		      (match_operator 3 "branch_comparison_operator"
1365590075Sobrien			      [(match_operand 4 "cc_reg_operand" "y")
1365690075Sobrien			       (const_int 0)])))]
1365790075Sobrien  ""
1365890075Sobrien  "#"
1365990075Sobrien  ""
1366090075Sobrien  [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
1366190075Sobrien				    (match_dup 5)))]
1366290075Sobrien  "
1366390075Sobrien{
1366490075Sobrien  int positive_1, positive_2;
1366590075Sobrien
13666169689Skan  positive_1 = branch_positive_comparison_operator (operands[1],
13667169689Skan						    GET_MODE (operands[1]));
13668169689Skan  positive_2 = branch_positive_comparison_operator (operands[3],
13669169689Skan						    GET_MODE (operands[3]));
1367090075Sobrien
1367190075Sobrien  if (! positive_1)
13672169689Skan    operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
13673169689Skan							    GET_CODE (operands[1])),
13674169689Skan				  SImode,
13675169689Skan				  operands[2], const0_rtx);
1367690075Sobrien  else if (GET_MODE (operands[1]) != SImode)
13677169689Skan    operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
13678169689Skan				  operands[2], const0_rtx);
1367990075Sobrien
1368090075Sobrien  if (! positive_2)
13681169689Skan    operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
13682169689Skan							    GET_CODE (operands[3])),
13683169689Skan				  SImode,
13684169689Skan				  operands[4], const0_rtx);
1368590075Sobrien  else if (GET_MODE (operands[3]) != SImode)
13686169689Skan    operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
13687169689Skan				  operands[4], const0_rtx);
1368890075Sobrien
1368990075Sobrien  if (positive_1 == positive_2)
1369090075Sobrien    {
1369190075Sobrien      operands[1] = gen_rtx_NOT (SImode, operands[1]);
1369290075Sobrien      operands[5] = constm1_rtx;
1369390075Sobrien    }
1369490075Sobrien  else
1369590075Sobrien    {
1369690075Sobrien      operands[5] = const1_rtx;
1369790075Sobrien    }
1369890075Sobrien}")
1369990075Sobrien
1370090075Sobrien;; Unconditional branch and return.
1370190075Sobrien
1370290075Sobrien(define_insn "jump"
1370390075Sobrien  [(set (pc)
1370490075Sobrien	(label_ref (match_operand 0 "" "")))]
1370590075Sobrien  ""
1370690075Sobrien  "b %l0"
1370790075Sobrien  [(set_attr "type" "branch")])
1370890075Sobrien
1370990075Sobrien(define_insn "return"
1371090075Sobrien  [(return)]
1371190075Sobrien  "direct_return ()"
1371290075Sobrien  "{br|blr}"
1371390075Sobrien  [(set_attr "type" "jmpreg")])
1371490075Sobrien
1371590075Sobrien(define_expand "indirect_jump"
13716169689Skan  [(set (pc) (match_operand 0 "register_operand" ""))])
13717169689Skan
13718169689Skan(define_insn "*indirect_jump<mode>"
13719169689Skan  [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))]
1372090075Sobrien  ""
1372190075Sobrien  "@
1372290075Sobrien   bctr
1372390075Sobrien   {br|blr}"
1372490075Sobrien  [(set_attr "type" "jmpreg")])
1372590075Sobrien
1372690075Sobrien;; Table jump for switch statements:
1372790075Sobrien(define_expand "tablejump"
1372890075Sobrien  [(use (match_operand 0 "" ""))
1372990075Sobrien   (use (label_ref (match_operand 1 "" "")))]
1373090075Sobrien  ""
1373190075Sobrien  "
1373290075Sobrien{
1373390075Sobrien  if (TARGET_32BIT)
1373490075Sobrien    emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
1373590075Sobrien  else
1373690075Sobrien    emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
1373790075Sobrien  DONE;
1373890075Sobrien}")
1373990075Sobrien
1374090075Sobrien(define_expand "tablejumpsi"
1374190075Sobrien  [(set (match_dup 3)
1374290075Sobrien	(plus:SI (match_operand:SI 0 "" "")
1374390075Sobrien		 (match_dup 2)))
1374490075Sobrien   (parallel [(set (pc) (match_dup 3))
1374590075Sobrien	      (use (label_ref (match_operand 1 "" "")))])]
1374690075Sobrien  "TARGET_32BIT"
1374790075Sobrien  "
1374890075Sobrien{ operands[0] = force_reg (SImode, operands[0]);
1374990075Sobrien  operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
1375090075Sobrien  operands[3] = gen_reg_rtx (SImode);
1375190075Sobrien}")
1375290075Sobrien
1375390075Sobrien(define_expand "tablejumpdi"
13754169689Skan  [(set (match_dup 4)
1375590075Sobrien        (sign_extend:DI (match_operand:SI 0 "lwa_operand" "rm")))
1375690075Sobrien   (set (match_dup 3)
1375790075Sobrien	(plus:DI (match_dup 4)
1375890075Sobrien		 (match_dup 2)))
1375990075Sobrien   (parallel [(set (pc) (match_dup 3))
1376090075Sobrien	      (use (label_ref (match_operand 1 "" "")))])]
1376190075Sobrien  "TARGET_64BIT"
1376290075Sobrien  "
1376390075Sobrien{ operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
1376490075Sobrien  operands[3] = gen_reg_rtx (DImode);
1376590075Sobrien  operands[4] = gen_reg_rtx (DImode);
1376690075Sobrien}")
1376790075Sobrien
13768169689Skan(define_insn "*tablejump<mode>_internal1"
1376990075Sobrien  [(set (pc)
13770169689Skan	(match_operand:P 0 "register_operand" "c,*l"))
1377190075Sobrien   (use (label_ref (match_operand 1 "" "")))]
13772169689Skan  ""
1377390075Sobrien  "@
1377490075Sobrien   bctr
1377590075Sobrien   {br|blr}"
1377690075Sobrien  [(set_attr "type" "jmpreg")])
1377790075Sobrien
1377890075Sobrien(define_insn "nop"
1377990075Sobrien  [(const_int 0)]
1378090075Sobrien  ""
1378190075Sobrien  "{cror 0,0,0|nop}")
1378290075Sobrien
1378390075Sobrien;; Define the subtract-one-and-jump insns, starting with the template
1378490075Sobrien;; so loop.c knows what to generate.
1378590075Sobrien
1378690075Sobrien(define_expand "doloop_end"
1378790075Sobrien  [(use (match_operand 0 "" ""))	; loop pseudo
1378890075Sobrien   (use (match_operand 1 "" ""))	; iterations; zero if unknown
1378990075Sobrien   (use (match_operand 2 "" ""))	; max iterations
1379090075Sobrien   (use (match_operand 3 "" ""))	; loop level
1379190075Sobrien   (use (match_operand 4 "" ""))]	; label
1379290075Sobrien  ""
1379390075Sobrien  "
1379490075Sobrien{
1379590075Sobrien  /* Only use this on innermost loops.  */
1379690075Sobrien  if (INTVAL (operands[3]) > 1)
1379790075Sobrien    FAIL;
13798132718Skan  if (TARGET_64BIT)
1379990075Sobrien    {
1380090075Sobrien      if (GET_MODE (operands[0]) != DImode)
1380190075Sobrien	FAIL;
1380290075Sobrien      emit_jump_insn (gen_ctrdi (operands[0], operands[4]));
1380390075Sobrien    }
1380490075Sobrien  else
1380590075Sobrien    {
1380690075Sobrien      if (GET_MODE (operands[0]) != SImode)
1380790075Sobrien	FAIL;
1380890075Sobrien      emit_jump_insn (gen_ctrsi (operands[0], operands[4]));
1380990075Sobrien    }
1381090075Sobrien  DONE;
1381190075Sobrien}")
1381290075Sobrien
13813169689Skan(define_expand "ctr<mode>"
1381490075Sobrien  [(parallel [(set (pc)
13815169689Skan		   (if_then_else (ne (match_operand:P 0 "register_operand" "")
1381690075Sobrien				     (const_int 1))
1381790075Sobrien				 (label_ref (match_operand 1 "" ""))
1381890075Sobrien				 (pc)))
1381990075Sobrien	      (set (match_dup 0)
13820169689Skan		   (plus:P (match_dup 0)
1382190075Sobrien			    (const_int -1)))
1382290075Sobrien	      (clobber (match_scratch:CC 2 ""))
13823169689Skan	      (clobber (match_scratch:P 3 ""))])]
13824169689Skan  ""
1382590075Sobrien  "")
1382690075Sobrien
1382790075Sobrien;; We need to be able to do this for any operand, including MEM, or we
1382890075Sobrien;; will cause reload to blow up since we don't allow output reloads on
1382990075Sobrien;; JUMP_INSNs.
1383090075Sobrien;; For the length attribute to be calculated correctly, the
1383190075Sobrien;; label MUST be operand 0.
1383290075Sobrien
13833169689Skan(define_insn "*ctr<mode>_internal1"
1383490075Sobrien  [(set (pc)
13835169689Skan	(if_then_else (ne (match_operand:P 1 "register_operand" "c,*r,*r,*r")
1383690075Sobrien			  (const_int 1))
1383790075Sobrien		      (label_ref (match_operand 0 "" ""))
1383890075Sobrien		      (pc)))
13839169689Skan   (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*q*c*l")
13840169689Skan	(plus:P (match_dup 1)
1384190075Sobrien		 (const_int -1)))
13842132718Skan   (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
13843169689Skan   (clobber (match_scratch:P 4 "=X,X,&r,r"))]
13844169689Skan  ""
1384590075Sobrien  "*
1384690075Sobrien{
1384790075Sobrien  if (which_alternative != 0)
1384890075Sobrien    return \"#\";
1384990075Sobrien  else if (get_attr_length (insn) == 4)
1385090075Sobrien    return \"{bdn|bdnz} %l0\";
1385190075Sobrien  else
1385290075Sobrien    return \"bdz $+8\;b %l0\";
1385390075Sobrien}"
1385490075Sobrien  [(set_attr "type" "branch")
13855132718Skan   (set_attr "length" "*,12,16,16")])
1385690075Sobrien
13857169689Skan(define_insn "*ctr<mode>_internal2"
1385890075Sobrien  [(set (pc)
13859169689Skan	(if_then_else (ne (match_operand:P 1 "register_operand" "c,*r,*r,*r")
1386090075Sobrien			  (const_int 1))
1386190075Sobrien		      (pc)
1386290075Sobrien		      (label_ref (match_operand 0 "" ""))))
13863169689Skan   (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*q*c*l")
13864169689Skan	(plus:P (match_dup 1)
1386590075Sobrien		 (const_int -1)))
13866132718Skan   (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
13867169689Skan   (clobber (match_scratch:P 4 "=X,X,&r,r"))]
13868169689Skan  ""
1386990075Sobrien  "*
1387090075Sobrien{
1387190075Sobrien  if (which_alternative != 0)
1387290075Sobrien    return \"#\";
1387390075Sobrien  else if (get_attr_length (insn) == 4)
1387490075Sobrien    return \"bdz %l0\";
1387590075Sobrien  else
1387690075Sobrien    return \"{bdn|bdnz} $+8\;b %l0\";
1387790075Sobrien}"
1387890075Sobrien  [(set_attr "type" "branch")
13879132718Skan   (set_attr "length" "*,12,16,16")])
1388090075Sobrien
1388190075Sobrien;; Similar but use EQ
1388290075Sobrien
13883169689Skan(define_insn "*ctr<mode>_internal5"
1388490075Sobrien  [(set (pc)
13885169689Skan	(if_then_else (eq (match_operand:P 1 "register_operand" "c,*r,*r,*r")
1388690075Sobrien			  (const_int 1))
1388790075Sobrien		      (label_ref (match_operand 0 "" ""))
1388890075Sobrien		      (pc)))
13889169689Skan   (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*q*c*l")
13890169689Skan	(plus:P (match_dup 1)
1389190075Sobrien		 (const_int -1)))
13892132718Skan   (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
13893169689Skan   (clobber (match_scratch:P 4 "=X,X,&r,r"))]
13894169689Skan  ""
1389590075Sobrien  "*
1389690075Sobrien{
1389790075Sobrien  if (which_alternative != 0)
1389890075Sobrien    return \"#\";
1389990075Sobrien  else if (get_attr_length (insn) == 4)
1390090075Sobrien    return \"bdz %l0\";
1390190075Sobrien  else
1390290075Sobrien    return \"{bdn|bdnz} $+8\;b %l0\";
1390390075Sobrien}"
1390490075Sobrien  [(set_attr "type" "branch")
13905132718Skan   (set_attr "length" "*,12,16,16")])
1390690075Sobrien
13907169689Skan(define_insn "*ctr<mode>_internal6"
1390890075Sobrien  [(set (pc)
13909169689Skan	(if_then_else (eq (match_operand:P 1 "register_operand" "c,*r,*r,*r")
1391090075Sobrien			  (const_int 1))
1391190075Sobrien		      (pc)
1391290075Sobrien		      (label_ref (match_operand 0 "" ""))))
13913169689Skan   (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*q*c*l")
13914169689Skan	(plus:P (match_dup 1)
1391590075Sobrien		 (const_int -1)))
13916132718Skan   (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
13917169689Skan   (clobber (match_scratch:P 4 "=X,X,&r,r"))]
13918169689Skan  ""
1391990075Sobrien  "*
1392090075Sobrien{
1392190075Sobrien  if (which_alternative != 0)
1392290075Sobrien    return \"#\";
1392390075Sobrien  else if (get_attr_length (insn) == 4)
1392490075Sobrien    return \"{bdn|bdnz} %l0\";
1392590075Sobrien  else
1392690075Sobrien    return \"bdz $+8\;b %l0\";
1392790075Sobrien}"
1392890075Sobrien  [(set_attr "type" "branch")
13929132718Skan   (set_attr "length" "*,12,16,16")])
1393090075Sobrien
1393190075Sobrien;; Now the splitters if we could not allocate the CTR register
1393290075Sobrien
1393390075Sobrien(define_split
1393490075Sobrien  [(set (pc)
1393590075Sobrien	(if_then_else (match_operator 2 "comparison_operator"
13936169689Skan				      [(match_operand:P 1 "gpc_reg_operand" "")
1393790075Sobrien				       (const_int 1)])
1393890075Sobrien		      (match_operand 5 "" "")
1393990075Sobrien		      (match_operand 6 "" "")))
13940169689Skan   (set (match_operand:P 0 "gpc_reg_operand" "")
13941169689Skan	(plus:P (match_dup 1) (const_int -1)))
1394290075Sobrien   (clobber (match_scratch:CC 3 ""))
13943169689Skan   (clobber (match_scratch:P 4 ""))]
13944169689Skan  "reload_completed"
1394590075Sobrien  [(parallel [(set (match_dup 3)
13946169689Skan		   (compare:CC (plus:P (match_dup 1)
1394790075Sobrien					(const_int -1))
1394890075Sobrien			       (const_int 0)))
1394990075Sobrien	      (set (match_dup 0)
13950169689Skan		   (plus:P (match_dup 1)
1395190075Sobrien			    (const_int -1)))])
1395290075Sobrien   (set (pc) (if_then_else (match_dup 7)
1395390075Sobrien			   (match_dup 5)
1395490075Sobrien			   (match_dup 6)))]
1395590075Sobrien  "
13956169689Skan{ operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
13957169689Skan				operands[3], const0_rtx); }")
1395890075Sobrien
1395990075Sobrien(define_split
1396090075Sobrien  [(set (pc)
1396190075Sobrien	(if_then_else (match_operator 2 "comparison_operator"
13962169689Skan				      [(match_operand:P 1 "gpc_reg_operand" "")
1396390075Sobrien				       (const_int 1)])
1396490075Sobrien		      (match_operand 5 "" "")
1396590075Sobrien		      (match_operand 6 "" "")))
13966169689Skan   (set (match_operand:P 0 "nonimmediate_operand" "")
13967169689Skan	(plus:P (match_dup 1) (const_int -1)))
1396890075Sobrien   (clobber (match_scratch:CC 3 ""))
13969169689Skan   (clobber (match_scratch:P 4 ""))]
13970169689Skan  "reload_completed && ! gpc_reg_operand (operands[0], SImode)"
1397190075Sobrien  [(parallel [(set (match_dup 3)
13972169689Skan		   (compare:CC (plus:P (match_dup 1)
1397390075Sobrien					(const_int -1))
1397490075Sobrien			       (const_int 0)))
1397590075Sobrien	      (set (match_dup 4)
13976169689Skan		   (plus:P (match_dup 1)
1397790075Sobrien			    (const_int -1)))])
1397890075Sobrien   (set (match_dup 0)
1397990075Sobrien	(match_dup 4))
1398090075Sobrien   (set (pc) (if_then_else (match_dup 7)
1398190075Sobrien			   (match_dup 5)
1398290075Sobrien			   (match_dup 6)))]
1398390075Sobrien  "
13984169689Skan{ operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode,
13985169689Skan				operands[3], const0_rtx); }")
1398690075Sobrien
1398790075Sobrien(define_insn "trap"
1398890075Sobrien  [(trap_if (const_int 1) (const_int 0))]
1398990075Sobrien  ""
1399090075Sobrien  "{t 31,0,0|trap}")
1399190075Sobrien
1399290075Sobrien(define_expand "conditional_trap"
1399390075Sobrien  [(trap_if (match_operator 0 "trap_comparison_operator"
1399490075Sobrien			    [(match_dup 2) (match_dup 3)])
1399590075Sobrien	    (match_operand 1 "const_int_operand" ""))]
1399690075Sobrien  ""
1399790075Sobrien  "if (rs6000_compare_fp_p || operands[1] != const0_rtx) FAIL;
1399890075Sobrien   operands[2] = rs6000_compare_op0;
1399990075Sobrien   operands[3] = rs6000_compare_op1;")
1400090075Sobrien
1400190075Sobrien(define_insn ""
1400290075Sobrien  [(trap_if (match_operator 0 "trap_comparison_operator"
14003169689Skan                            [(match_operand:GPR 1 "register_operand" "r")
14004169689Skan                             (match_operand:GPR 2 "reg_or_short_operand" "rI")])
1400590075Sobrien	    (const_int 0))]
1400690075Sobrien  ""
14007169689Skan  "{t|t<wd>}%V0%I2 %1,%2")
1400890075Sobrien
1400990075Sobrien;; Insns related to generating the function prologue and epilogue.
1401090075Sobrien
1401190075Sobrien(define_expand "prologue"
1401290075Sobrien  [(use (const_int 0))]
1401390075Sobrien  "TARGET_SCHED_PROLOG"
1401490075Sobrien  "
1401590075Sobrien{
1401690075Sobrien      rs6000_emit_prologue ();
1401790075Sobrien      DONE;
1401890075Sobrien}")
1401990075Sobrien
14020132718Skan(define_insn "*movesi_from_cr_one"
14021132718Skan  [(match_parallel 0 "mfcr_operation"
14022132718Skan		   [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
14023132718Skan			 (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
14024132718Skan				     (match_operand 3 "immediate_operand" "n")]
14025132718Skan			  UNSPEC_MOVESI_FROM_CR))])]
14026132718Skan  "TARGET_MFCRF"
14027132718Skan  "*
14028132718Skan{
14029132718Skan  int mask = 0;
14030132718Skan  int i;
14031132718Skan  for (i = 0; i < XVECLEN (operands[0], 0); i++)
14032132718Skan  {
14033132718Skan    mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
14034132718Skan    operands[4] = GEN_INT (mask);
14035132718Skan    output_asm_insn (\"mfcr %1,%4\", operands);
14036132718Skan  }
14037132718Skan  return \"\";
14038132718Skan}"
14039132718Skan  [(set_attr "type" "mfcrf")])
14040132718Skan
1404190075Sobrien(define_insn "movesi_from_cr"
1404290075Sobrien  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
14043169689Skan        (unspec:SI [(reg:CC 68) (reg:CC 69) (reg:CC 70) (reg:CC 71)
14044132718Skan		    (reg:CC 72)	(reg:CC 73) (reg:CC 74) (reg:CC 75)]
14045132718Skan		   UNSPEC_MOVESI_FROM_CR))]
1404690075Sobrien  ""
14047117395Skan  "mfcr %0"
14048132718Skan  [(set_attr "type" "mfcr")])
1404990075Sobrien
1405090075Sobrien(define_insn "*stmw"
14051132718Skan  [(match_parallel 0 "stmw_operation"
14052132718Skan		   [(set (match_operand:SI 1 "memory_operand" "=m")
14053132718Skan       			 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
14054132718Skan  "TARGET_MULTIPLE"
14055169689Skan  "{stm|stmw} %2,%1"
14056169689Skan  [(set_attr "type" "store_ux")])
1405790075Sobrien
14058169689Skan(define_insn "*save_fpregs_<mode>"
14059169689Skan  [(match_parallel 0 "any_parallel_operand"
14060169689Skan		   [(clobber (match_operand:P 1 "register_operand" "=l"))
14061169689Skan		    (use (match_operand:P 2 "call_operand" "s"))
14062132718Skan		    (set (match_operand:DF 3 "memory_operand" "=m")
14063132718Skan			 (match_operand:DF 4 "gpc_reg_operand" "f"))])]
14064169689Skan  ""
14065132718Skan  "bl %z2"
14066132718Skan  [(set_attr "type" "branch")
14067132718Skan   (set_attr "length" "4")])
1406890075Sobrien
1406990075Sobrien; These are to explain that changes to the stack pointer should
1407090075Sobrien; not be moved over stores to stack memory.
1407190075Sobrien(define_insn "stack_tie"
1407290075Sobrien  [(set (match_operand:BLK 0 "memory_operand" "+m")
14073132718Skan        (unspec:BLK [(match_dup 0)] UNSPEC_TIE))]
1407490075Sobrien  ""
1407590075Sobrien  ""
1407690075Sobrien  [(set_attr "length" "0")])
1407790075Sobrien
1407890075Sobrien
1407990075Sobrien(define_expand "epilogue"
1408090075Sobrien  [(use (const_int 0))]
1408190075Sobrien  "TARGET_SCHED_PROLOG"
1408290075Sobrien  "
1408390075Sobrien{
1408490075Sobrien      rs6000_emit_epilogue (FALSE);
1408590075Sobrien      DONE;
1408690075Sobrien}")
1408790075Sobrien
1408890075Sobrien; On some processors, doing the mtcrf one CC register at a time is
1408990075Sobrien; faster (like on the 604e).  On others, doing them all at once is
1409090075Sobrien; faster; for instance, on the 601 and 750.
1409190075Sobrien
1409290075Sobrien(define_expand "movsi_to_cr_one"
14093117395Skan  [(set (match_operand:CC 0 "cc_reg_operand" "=y")
14094117395Skan        (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14095132718Skan		    (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
14096117395Skan  ""
14097117395Skan  "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));")
1409890075Sobrien
1409990075Sobrien(define_insn "*movsi_to_cr"
14100117395Skan  [(match_parallel 0 "mtcrf_operation"
14101117395Skan		   [(set (match_operand:CC 1 "cc_reg_operand" "=y")
14102117395Skan			 (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
14103117395Skan				     (match_operand 3 "immediate_operand" "n")]
14104132718Skan				    UNSPEC_MOVESI_TO_CR))])]
1410590075Sobrien ""
1410690075Sobrien "*
1410790075Sobrien{
1410890075Sobrien  int mask = 0;
1410990075Sobrien  int i;
1411090075Sobrien  for (i = 0; i < XVECLEN (operands[0], 0); i++)
1411190075Sobrien    mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
1411290075Sobrien  operands[4] = GEN_INT (mask);
1411390075Sobrien  return \"mtcrf %4,%2\";
14114117395Skan}"
14115132718Skan  [(set_attr "type" "mtcr")])
1411690075Sobrien
14117132718Skan(define_insn "*mtcrfsi"
14118117395Skan  [(set (match_operand:CC 0 "cc_reg_operand" "=y")
14119117395Skan        (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14120132718Skan		    (match_operand 2 "immediate_operand" "n")]
14121132718Skan		   UNSPEC_MOVESI_TO_CR))]
14122169689Skan  "GET_CODE (operands[0]) == REG
14123117395Skan   && CR_REGNO_P (REGNO (operands[0]))
14124117395Skan   && GET_CODE (operands[2]) == CONST_INT
14125117395Skan   && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))"
14126117395Skan  "mtcrf %R0,%1"
14127132718Skan  [(set_attr "type" "mtcr")])
1412890075Sobrien
1412990075Sobrien; The load-multiple instructions have similar properties.
1413090075Sobrien; Note that "load_multiple" is a name known to the machine-independent
14131169689Skan; code that actually corresponds to the PowerPC load-string.
1413290075Sobrien
1413390075Sobrien(define_insn "*lmw"
14134117395Skan  [(match_parallel 0 "lmw_operation"
14135117395Skan		   [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
14136117395Skan       			 (match_operand:SI 2 "memory_operand" "m"))])]
14137117395Skan  "TARGET_MULTIPLE"
14138169689Skan  "{lm|lmw} %1,%2"
14139169689Skan  [(set_attr "type" "load_ux")])
1414090075Sobrien
14141169689Skan(define_insn "*return_internal_<mode>"
1414290075Sobrien  [(return)
14143169689Skan   (use (match_operand:P 0 "register_operand" "lc"))]
14144169689Skan  ""
1414590075Sobrien  "b%T0"
1414690075Sobrien  [(set_attr "type" "jmpreg")])
1414790075Sobrien
1414890075Sobrien; FIXME: This would probably be somewhat simpler if the Cygnus sibcall
14149169689Skan; stuff was in GCC.  Oh, and "any_parallel_operand" is a bit flexible...
1415090075Sobrien
14151169689Skan(define_insn "*return_and_restore_fpregs_<mode>"
14152169689Skan [(match_parallel 0 "any_parallel_operand"
1415390075Sobrien                  [(return)
14154169689Skan		   (use (match_operand:P 1 "register_operand" "l"))
14155169689Skan		   (use (match_operand:P 2 "call_operand" "s"))
1415690075Sobrien		   (set (match_operand:DF 3 "gpc_reg_operand" "=f")
1415790075Sobrien			(match_operand:DF 4 "memory_operand" "m"))])]
14158169689Skan ""
1415990075Sobrien "b %z2")
1416090075Sobrien
1416190075Sobrien; This is used in compiling the unwind routines.
1416290075Sobrien(define_expand "eh_return"
14163117395Skan  [(use (match_operand 0 "general_operand" ""))]
1416490075Sobrien  ""
1416590075Sobrien  "
1416690075Sobrien{
1416790075Sobrien  if (TARGET_32BIT)
14168117395Skan    emit_insn (gen_eh_set_lr_si (operands[0]));
1416990075Sobrien  else
14170117395Skan    emit_insn (gen_eh_set_lr_di (operands[0]));
1417190075Sobrien  DONE;
1417290075Sobrien}")
1417390075Sobrien
1417490075Sobrien; We can't expand this before we know where the link register is stored.
14175169689Skan(define_insn "eh_set_lr_<mode>"
14176169689Skan  [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
14177132718Skan  		    UNSPECV_EH_RR)
14178169689Skan   (clobber (match_scratch:P 1 "=&b"))]
14179169689Skan  ""
1418090075Sobrien  "#")
1418190075Sobrien
1418290075Sobrien(define_split
14183132718Skan  [(unspec_volatile [(match_operand 0 "register_operand" "")] UNSPECV_EH_RR)
1418490075Sobrien   (clobber (match_scratch 1 ""))]
1418590075Sobrien  "reload_completed"
1418690075Sobrien  [(const_int 0)]
1418790075Sobrien  "
1418890075Sobrien{
14189132718Skan  rs6000_emit_eh_reg_restore (operands[0], operands[1]);
1419090075Sobrien  DONE;
1419190075Sobrien}")
1419290075Sobrien
1419390075Sobrien(define_insn "prefetch"
14194169689Skan  [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
1419590075Sobrien	     (match_operand:SI 1 "const_int_operand" "n")
1419690075Sobrien	     (match_operand:SI 2 "const_int_operand" "n"))]
1419790075Sobrien  "TARGET_POWERPC"
1419890075Sobrien  "*
1419990075Sobrien{
1420090075Sobrien  if (GET_CODE (operands[0]) == REG)
1420190075Sobrien    return INTVAL (operands[1]) ? \"dcbtst 0,%0\" : \"dcbt 0,%0\";
1420290075Sobrien  return INTVAL (operands[1]) ? \"dcbtst %a0\" : \"dcbt %a0\";
1420390075Sobrien}"
1420490075Sobrien  [(set_attr "type" "load")])
14205169689Skan
1420690075Sobrien
14207169689Skan(include "sync.md")
14208117395Skan(include "altivec.md")
14209117395Skan(include "spe.md")
14210