1*0fc04c29Smrg;; Copyright (C) 2006-2019 Free Software Foundation, Inc.
263d1a8abSmrg
363d1a8abSmrg;; This file is free software; you can redistribute it and/or modify it under
463d1a8abSmrg;; the terms of the GNU General Public License as published by the Free
563d1a8abSmrg;; Software Foundation; either version 3 of the License, or (at your option)
663d1a8abSmrg;; any later version.
763d1a8abSmrg
863d1a8abSmrg;; This file is distributed in the hope that it will be useful, but WITHOUT
963d1a8abSmrg;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1063d1a8abSmrg;; FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1163d1a8abSmrg;; for more details.
1263d1a8abSmrg
1363d1a8abSmrg;; You should have received a copy of the GNU General Public License
1463d1a8abSmrg;; along with GCC; see the file COPYING3.  If not see
1563d1a8abSmrg;; <http://www.gnu.org/licenses/>.
1663d1a8abSmrg
1763d1a8abSmrg;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
1863d1a8abSmrg
1963d1a8abSmrg
2063d1a8abSmrg;; Define an insn type attribute.  This is used in function unit delay
2163d1a8abSmrg;; computations.
2263d1a8abSmrg;; multi0 is a multiple insn rtl whose first insn is in pipe0
2363d1a8abSmrg;; multi1 is a multiple insn rtl whose first insn is in pipe1
2463d1a8abSmrg(define_attr "type" "fx2,shuf,fx3,load,store,br,spr,lnop,nop,fxb,fp6,fp7,fpd,iprefetch,multi0,multi1,hbr,convert"
2563d1a8abSmrg  (const_string "fx2"))
2663d1a8abSmrg
2763d1a8abSmrg;; Length (in bytes).
2863d1a8abSmrg(define_attr "length" ""
2963d1a8abSmrg		(const_int 4))
3063d1a8abSmrg
3163d1a8abSmrg(define_attr "tune" "cell,celledp" (const (symbol_ref "spu_tune")))
3263d1a8abSmrg;; Processor type -- this attribute must exactly match the processor_type
3363d1a8abSmrg;; enumeration in spu.h.
3463d1a8abSmrg
3563d1a8abSmrg(define_attr "cpu" "spu"
3663d1a8abSmrg  (const (symbol_ref "spu_cpu_attr")))
3763d1a8abSmrg
3863d1a8abSmrg; (define_function_unit NAME MULTIPLICITY SIMULTANEITY
3963d1a8abSmrg;			TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST])
4063d1a8abSmrg
4163d1a8abSmrg(define_cpu_unit "pipe0,pipe1,fp,ls")
4263d1a8abSmrg
4363d1a8abSmrg(define_insn_reservation "NOP" 1 (eq_attr "type" "nop")
4463d1a8abSmrg    "pipe0")
4563d1a8abSmrg
4663d1a8abSmrg(define_insn_reservation "FX2" 2 (eq_attr "type" "fx2")
4763d1a8abSmrg    "pipe0, nothing")
4863d1a8abSmrg
4963d1a8abSmrg(define_insn_reservation "FX3" 4 (eq_attr "type" "fx3,fxb")
5063d1a8abSmrg    "pipe0, nothing*3")
5163d1a8abSmrg
5263d1a8abSmrg(define_insn_reservation "FP6" 6 (eq_attr "type" "fp6")
5363d1a8abSmrg    "pipe0 + fp, nothing*5")
5463d1a8abSmrg
5563d1a8abSmrg(define_insn_reservation "FP7" 7 (eq_attr "type" "fp7")
5663d1a8abSmrg    "pipe0, fp, nothing*5")
5763d1a8abSmrg
5863d1a8abSmrg;; The behavior of the double precision is that both pipes stall
5963d1a8abSmrg;; for 6 cycles and the rest of the operation pipelines for
6063d1a8abSmrg;; 7 cycles.  The simplest way to model this is to simply ignore
6163d1a8abSmrg;; the 6 cyle stall.
6263d1a8abSmrg(define_insn_reservation "FPD" 7
6363d1a8abSmrg  (and (eq_attr "tune" "cell")
6463d1a8abSmrg       (eq_attr "type" "fpd"))
6563d1a8abSmrg    "pipe0 + pipe1, fp, nothing*5")
6663d1a8abSmrg
6763d1a8abSmrg;; Tune for CELLEDP, 9 cycles, dual-issuable, fully pipelined
6863d1a8abSmrg(define_insn_reservation "FPD_CELLEDP" 9
6963d1a8abSmrg  (and (eq_attr "tune" "celledp")
7063d1a8abSmrg       (eq_attr "type" "fpd"))
7163d1a8abSmrg  "pipe0 + fp, nothing*8")
7263d1a8abSmrg
7363d1a8abSmrg(define_insn_reservation "LNOP" 1 (eq_attr "type" "lnop")
7463d1a8abSmrg    "pipe1")
7563d1a8abSmrg
7663d1a8abSmrg(define_insn_reservation "STORE" 1 (eq_attr "type" "store")
7763d1a8abSmrg    "pipe1 + ls")
7863d1a8abSmrg
7963d1a8abSmrg(define_insn_reservation "IPREFETCH" 1 (eq_attr "type" "iprefetch")
8063d1a8abSmrg    "pipe1 + ls")
8163d1a8abSmrg
8263d1a8abSmrg(define_insn_reservation "SHUF" 4 (eq_attr "type" "shuf,br,spr")
8363d1a8abSmrg    "pipe1, nothing*3")
8463d1a8abSmrg
8563d1a8abSmrg(define_insn_reservation "LOAD" 6 (eq_attr "type" "load")
8663d1a8abSmrg    "pipe1 + ls, nothing*5")
8763d1a8abSmrg
8863d1a8abSmrg(define_insn_reservation "HBR" 18 (eq_attr "type" "hbr")
8963d1a8abSmrg    "pipe1, nothing*15")
9063d1a8abSmrg
9163d1a8abSmrg(define_insn_reservation "MULTI0" 4 (eq_attr "type" "multi0")
9263d1a8abSmrg    "pipe0+pipe1, nothing*3")
9363d1a8abSmrg
9463d1a8abSmrg(define_insn_reservation "MULTI1" 4 (eq_attr "type" "multi1")
9563d1a8abSmrg    "pipe1, nothing*3")
9663d1a8abSmrg
9763d1a8abSmrg(define_insn_reservation "CONVERT" 0 (eq_attr "type" "convert")
9863d1a8abSmrg    "nothing")
9963d1a8abSmrg
10063d1a8abSmrg;; Force pipe0 to occur before pipe 1 in a cycle.
10163d1a8abSmrg(absence_set "pipe0" "pipe1")
10263d1a8abSmrg
10363d1a8abSmrg
10463d1a8abSmrg(define_c_enum "unspec" [
10563d1a8abSmrg  UNSPEC_IPREFETCH
10663d1a8abSmrg  UNSPEC_FREST
10763d1a8abSmrg  UNSPEC_FRSQEST
10863d1a8abSmrg  UNSPEC_FI
10963d1a8abSmrg  UNSPEC_EXTEND_CMP
11063d1a8abSmrg  UNSPEC_CG
11163d1a8abSmrg  UNSPEC_CGX
11263d1a8abSmrg  UNSPEC_ADDX
11363d1a8abSmrg  UNSPEC_BG
11463d1a8abSmrg  UNSPEC_BGX
11563d1a8abSmrg  UNSPEC_SFX
11663d1a8abSmrg  UNSPEC_FSM
11763d1a8abSmrg  UNSPEC_HBR
11863d1a8abSmrg  UNSPEC_NOP
11963d1a8abSmrg  UNSPEC_CONVERT
12063d1a8abSmrg  UNSPEC_SELB
12163d1a8abSmrg  UNSPEC_SHUFB
12263d1a8abSmrg  UNSPEC_CPAT
12363d1a8abSmrg  UNSPEC_CNTB
12463d1a8abSmrg  UNSPEC_SUMB
12563d1a8abSmrg  UNSPEC_FSMB
12663d1a8abSmrg  UNSPEC_FSMH
12763d1a8abSmrg  UNSPEC_GBB
12863d1a8abSmrg  UNSPEC_GBH
12963d1a8abSmrg  UNSPEC_GB
13063d1a8abSmrg  UNSPEC_AVGB
13163d1a8abSmrg  UNSPEC_ABSDB
13263d1a8abSmrg  UNSPEC_ORX
13363d1a8abSmrg  UNSPEC_HEQ
13463d1a8abSmrg  UNSPEC_HGT
13563d1a8abSmrg  UNSPEC_HLGT
13663d1a8abSmrg  UNSPEC_STOP
13763d1a8abSmrg  UNSPEC_STOPD
13863d1a8abSmrg  UNSPEC_SET_INTR
13963d1a8abSmrg  UNSPEC_FSCRRD
14063d1a8abSmrg  UNSPEC_FSCRWR
14163d1a8abSmrg  UNSPEC_MFSPR
14263d1a8abSmrg  UNSPEC_MTSPR
14363d1a8abSmrg  UNSPEC_RDCH
14463d1a8abSmrg  UNSPEC_RCHCNT
14563d1a8abSmrg  UNSPEC_WRCH
14663d1a8abSmrg  UNSPEC_SPU_REALIGN_LOAD
14763d1a8abSmrg  UNSPEC_SPU_MASK_FOR_LOAD
14863d1a8abSmrg  UNSPEC_DFTSV
14963d1a8abSmrg  UNSPEC_FLOAT_EXTEND
15063d1a8abSmrg  UNSPEC_FLOAT_TRUNCATE
15163d1a8abSmrg  UNSPEC_SP_SET
15263d1a8abSmrg  UNSPEC_SP_TEST
15363d1a8abSmrg])
15463d1a8abSmrg
15563d1a8abSmrg(define_c_enum "unspecv" [
15663d1a8abSmrg  UNSPECV_BLOCKAGE
15763d1a8abSmrg  UNSPECV_LNOP
15863d1a8abSmrg  UNSPECV_NOP
15963d1a8abSmrg  UNSPECV_SYNC
16063d1a8abSmrg])
16163d1a8abSmrg
16263d1a8abSmrg(include "predicates.md")
16363d1a8abSmrg(include "constraints.md")
16463d1a8abSmrg
16563d1a8abSmrg
16663d1a8abSmrg;; Mode iterators
16763d1a8abSmrg
16863d1a8abSmrg(define_mode_iterator ALL [QI V16QI
16963d1a8abSmrg			HI V8HI
17063d1a8abSmrg			SI V4SI
17163d1a8abSmrg			DI V2DI
17263d1a8abSmrg			TI
17363d1a8abSmrg                        SF V4SF
17463d1a8abSmrg                        DF V2DF])
17563d1a8abSmrg
17663d1a8abSmrg; Everything except DI and TI which are handled separately because
17763d1a8abSmrg; they need different constraints to correctly test VOIDmode constants
17863d1a8abSmrg(define_mode_iterator MOV [QI V16QI
17963d1a8abSmrg			HI V8HI
18063d1a8abSmrg			SI V4SI
18163d1a8abSmrg			V2DI
18263d1a8abSmrg                        SF V4SF
18363d1a8abSmrg                        DF V2DF])
18463d1a8abSmrg
18563d1a8abSmrg(define_mode_iterator QHSI  [QI HI SI])
18663d1a8abSmrg(define_mode_iterator QHSDI  [QI HI SI DI])
18763d1a8abSmrg(define_mode_iterator DTI  [DI TI])
18863d1a8abSmrg
18963d1a8abSmrg(define_mode_iterator VINT [QI V16QI
19063d1a8abSmrg			 HI V8HI
19163d1a8abSmrg			 SI V4SI
19263d1a8abSmrg			 DI V2DI
19363d1a8abSmrg			 TI])
19463d1a8abSmrg
19563d1a8abSmrg(define_mode_iterator VQHSI [QI V16QI
19663d1a8abSmrg			  HI V8HI
19763d1a8abSmrg			  SI V4SI])
19863d1a8abSmrg
19963d1a8abSmrg(define_mode_iterator VHSI [HI V8HI
20063d1a8abSmrg			 SI V4SI])
20163d1a8abSmrg
20263d1a8abSmrg(define_mode_iterator VSDF [SF V4SF
20363d1a8abSmrg                         DF V2DF])
20463d1a8abSmrg
20563d1a8abSmrg(define_mode_iterator VSI [SI V4SI])
20663d1a8abSmrg(define_mode_iterator VDI [DI V2DI])
20763d1a8abSmrg(define_mode_iterator VSF [SF V4SF])
20863d1a8abSmrg(define_mode_iterator VDF [DF V2DF])
20963d1a8abSmrg
21063d1a8abSmrg(define_mode_iterator VCMP [V16QI
21163d1a8abSmrg			 V8HI
21263d1a8abSmrg			 V4SI
21363d1a8abSmrg                         V4SF
21463d1a8abSmrg                         V2DF])
21563d1a8abSmrg
21663d1a8abSmrg(define_mode_iterator VCMPU [V16QI
21763d1a8abSmrg			  V8HI
21863d1a8abSmrg			  V4SI])
21963d1a8abSmrg
22063d1a8abSmrg(define_mode_attr v	 [(V8HI  "v") (V4SI  "v")
22163d1a8abSmrg			  (HI    "") (SI    "")])
22263d1a8abSmrg
22363d1a8abSmrg(define_mode_attr bh  [(QI "b")  (V16QI "b")
22463d1a8abSmrg		       (HI "h")  (V8HI "h")
22563d1a8abSmrg		       (SI "")   (V4SI "")])
22663d1a8abSmrg
22763d1a8abSmrg(define_mode_attr d   [(SF "")   (V4SF "")
22863d1a8abSmrg                       (DF "d")  (V2DF "d")])
22963d1a8abSmrg(define_mode_attr d6  [(SF "6")  (V4SF "6")
23063d1a8abSmrg                       (DF "d")  (V2DF "d")])
23163d1a8abSmrg
23263d1a8abSmrg(define_mode_attr f2i [(SF "si") (V4SF "v4si")
23363d1a8abSmrg                       (DF "di") (V2DF "v2di")])
23463d1a8abSmrg(define_mode_attr F2I [(SF "SI") (V4SF "V4SI")
23563d1a8abSmrg                       (DF "DI") (V2DF "V2DI")])
23663d1a8abSmrg(define_mode_attr i2f [(SI "sf") (V4SI "v4sf")
23763d1a8abSmrg                       (DI "df") (V2DI "v2df")])
23863d1a8abSmrg(define_mode_attr I2F [(SI "SF") (V4SI "V4SF")
23963d1a8abSmrg                       (DI "DF") (V2DI "V2DF")])
24063d1a8abSmrg
24163d1a8abSmrg(define_mode_attr DF2I [(DF "SI") (V2DF "V2DI")])
24263d1a8abSmrg
24363d1a8abSmrg(define_mode_attr umask  [(HI "f")  (V8HI "f")
24463d1a8abSmrg		          (SI "g")  (V4SI "g")])
24563d1a8abSmrg(define_mode_attr nmask  [(HI "F")  (V8HI "F")
24663d1a8abSmrg		          (SI "G")  (V4SI "G")])
24763d1a8abSmrg
24863d1a8abSmrg;; Used for carry and borrow instructions.
24963d1a8abSmrg(define_mode_iterator CBOP  [SI DI V4SI V2DI])
25063d1a8abSmrg
25163d1a8abSmrg;; Used in vec_set and vec_extract
25263d1a8abSmrg(define_mode_iterator V [V2DI V4SI V8HI V16QI V2DF V4SF])
25363d1a8abSmrg(define_mode_attr inner  [(V16QI "QI")
25463d1a8abSmrg			  (V8HI  "HI")
25563d1a8abSmrg			  (V4SI  "SI")
25663d1a8abSmrg			  (V2DI  "DI")
25763d1a8abSmrg			  (V4SF  "SF")
25863d1a8abSmrg			  (V2DF  "DF")])
259c7a68eb7Smrg;; Like above, but in lower case
260c7a68eb7Smrg(define_mode_attr inner_l [(V16QI "qi")
261c7a68eb7Smrg			   (V8HI  "hi")
262c7a68eb7Smrg			   (V4SI  "si")
263c7a68eb7Smrg			   (V2DI  "di")
264c7a68eb7Smrg			   (V4SF  "sf")
265c7a68eb7Smrg			   (V2DF  "df")])
26663d1a8abSmrg(define_mode_attr vmult  [(V16QI "1")
26763d1a8abSmrg			  (V8HI  "2")
26863d1a8abSmrg			  (V4SI  "4")
26963d1a8abSmrg			  (V2DI  "8")
27063d1a8abSmrg			  (V4SF  "4")
27163d1a8abSmrg			  (V2DF  "8")])
27263d1a8abSmrg(define_mode_attr voff   [(V16QI "13")
27363d1a8abSmrg			  (V8HI  "14")
27463d1a8abSmrg			  (V4SI  "0")
27563d1a8abSmrg			  (V2DI  "0")
27663d1a8abSmrg			  (V4SF  "0")
27763d1a8abSmrg			  (V2DF  "0")])
27863d1a8abSmrg
27963d1a8abSmrg
28063d1a8abSmrg;; mov
28163d1a8abSmrg
28263d1a8abSmrg(define_expand "mov<mode>"
28363d1a8abSmrg  [(set (match_operand:ALL 0 "nonimmediate_operand" "")
28463d1a8abSmrg	(match_operand:ALL 1 "general_operand" ""))]
28563d1a8abSmrg  ""
28663d1a8abSmrg  {
28763d1a8abSmrg    if (spu_expand_mov(operands, <MODE>mode))
28863d1a8abSmrg      DONE;
28963d1a8abSmrg  })
29063d1a8abSmrg
29163d1a8abSmrg(define_split
29263d1a8abSmrg  [(set (match_operand 0 "spu_reg_operand")
29363d1a8abSmrg	(match_operand 1 "immediate_operand"))]
29463d1a8abSmrg
29563d1a8abSmrg  ""
29663d1a8abSmrg  [(set (match_dup 0)
29763d1a8abSmrg	(high (match_dup 1)))
29863d1a8abSmrg   (set (match_dup 0)
29963d1a8abSmrg	(lo_sum (match_dup 0)
30063d1a8abSmrg	        (match_dup 1)))]
30163d1a8abSmrg  {
30263d1a8abSmrg    if (spu_split_immediate (operands))
30363d1a8abSmrg      DONE;
30463d1a8abSmrg    FAIL;
30563d1a8abSmrg  })
30663d1a8abSmrg
30763d1a8abSmrg(define_insn "pic"
30863d1a8abSmrg  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
30963d1a8abSmrg	(match_operand:SI 1 "immediate_operand" "s"))
31063d1a8abSmrg   (use (const_int 0))]
31163d1a8abSmrg  "flag_pic"
31263d1a8abSmrg  "ila\t%0,%%pic(%1)")
31363d1a8abSmrg
31463d1a8abSmrg;; Whenever a function generates the 'pic' pattern above we need to
31563d1a8abSmrg;; load the pic_offset_table register.
31663d1a8abSmrg;; GCC doesn't deal well with labels in the middle of a block so we
31763d1a8abSmrg;; hardcode the offsets in the asm here.
31863d1a8abSmrg(define_insn "load_pic_offset"
31963d1a8abSmrg  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
32063d1a8abSmrg	(unspec:SI [(const_int 0)] 0))
32163d1a8abSmrg   (set (match_operand:SI 1 "spu_reg_operand" "=r")
32263d1a8abSmrg	(unspec:SI [(const_int 0)] 0))]
32363d1a8abSmrg  "flag_pic"
32463d1a8abSmrg  "ila\t%1,.+8\;brsl\t%0,4"
32563d1a8abSmrg  [(set_attr "length" "8")
32663d1a8abSmrg   (set_attr "type" "multi0")])
32763d1a8abSmrg
32863d1a8abSmrg
32963d1a8abSmrg;; move internal
33063d1a8abSmrg
33163d1a8abSmrg(define_insn "_mov<mode>"
33263d1a8abSmrg  [(set (match_operand:MOV 0 "spu_dest_operand" "=r,r,r,r,r,m")
33363d1a8abSmrg	(match_operand:MOV 1 "spu_mov_operand" "r,A,f,j,m,r"))]
33463d1a8abSmrg  "register_operand(operands[0], <MODE>mode)
33563d1a8abSmrg   || register_operand(operands[1], <MODE>mode)"
33663d1a8abSmrg  "@
33763d1a8abSmrg   ori\t%0,%1,0
33863d1a8abSmrg   il%s1\t%0,%S1
33963d1a8abSmrg   fsmbi\t%0,%S1
34063d1a8abSmrg   c%s1d\t%0,%S1($sp)
34163d1a8abSmrg   lq%p1\t%0,%1
34263d1a8abSmrg   stq%p0\t%1,%0"
34363d1a8abSmrg  [(set_attr "type" "fx2,fx2,shuf,shuf,load,store")])
34463d1a8abSmrg
34563d1a8abSmrg(define_insn "low_<mode>"
34663d1a8abSmrg  [(set (match_operand:VSI 0 "spu_reg_operand" "=r")
34763d1a8abSmrg	(lo_sum:VSI (match_operand:VSI 1 "spu_reg_operand" "0")
34863d1a8abSmrg		    (match_operand:VSI 2 "immediate_operand" "i")))]
34963d1a8abSmrg  ""
35063d1a8abSmrg  "iohl\t%0,%2@l")
35163d1a8abSmrg
35263d1a8abSmrg(define_insn "_movdi"
35363d1a8abSmrg  [(set (match_operand:DI 0 "spu_dest_operand" "=r,r,r,r,r,m")
35463d1a8abSmrg	(match_operand:DI 1 "spu_mov_operand" "r,a,f,k,m,r"))]
35563d1a8abSmrg  "register_operand(operands[0], DImode)
35663d1a8abSmrg   || register_operand(operands[1], DImode)"
35763d1a8abSmrg  "@
35863d1a8abSmrg   ori\t%0,%1,0
35963d1a8abSmrg   il%d1\t%0,%D1
36063d1a8abSmrg   fsmbi\t%0,%D1
36163d1a8abSmrg   c%d1d\t%0,%D1($sp)
36263d1a8abSmrg   lq%p1\t%0,%1
36363d1a8abSmrg   stq%p0\t%1,%0"
36463d1a8abSmrg  [(set_attr "type" "fx2,fx2,shuf,shuf,load,store")])
36563d1a8abSmrg
36663d1a8abSmrg(define_insn "_movti"
36763d1a8abSmrg  [(set (match_operand:TI 0 "spu_dest_operand" "=r,r,r,r,r,m")
36863d1a8abSmrg	(match_operand:TI 1 "spu_mov_operand" "r,U,f,l,m,r"))]
36963d1a8abSmrg  "register_operand(operands[0], TImode)
37063d1a8abSmrg   || register_operand(operands[1], TImode)"
37163d1a8abSmrg  "@
37263d1a8abSmrg   ori\t%0,%1,0
37363d1a8abSmrg   il%t1\t%0,%T1
37463d1a8abSmrg   fsmbi\t%0,%T1
37563d1a8abSmrg   c%t1d\t%0,%T1($sp)
37663d1a8abSmrg   lq%p1\t%0,%1
37763d1a8abSmrg   stq%p0\t%1,%0"
37863d1a8abSmrg  [(set_attr "type" "fx2,fx2,shuf,shuf,load,store")])
37963d1a8abSmrg
38063d1a8abSmrg(define_split
38163d1a8abSmrg  [(set (match_operand 0 "spu_reg_operand")
38263d1a8abSmrg	(match_operand 1 "memory_operand"))]
38363d1a8abSmrg  "GET_MODE_SIZE (GET_MODE (operands[0])) < 16
38463d1a8abSmrg   && GET_MODE(operands[0]) == GET_MODE(operands[1])
38563d1a8abSmrg   && !reload_in_progress && !reload_completed"
38663d1a8abSmrg  [(set (match_dup 0)
38763d1a8abSmrg	(match_dup 1))]
38863d1a8abSmrg  { if (spu_split_load(operands))
38963d1a8abSmrg      DONE;
39063d1a8abSmrg  })
39163d1a8abSmrg
39263d1a8abSmrg(define_split
39363d1a8abSmrg  [(set (match_operand 0 "memory_operand")
39463d1a8abSmrg	(match_operand 1 "spu_reg_operand"))]
39563d1a8abSmrg  "GET_MODE_SIZE (GET_MODE (operands[0])) < 16
39663d1a8abSmrg   && GET_MODE(operands[0]) == GET_MODE(operands[1])
39763d1a8abSmrg   && !reload_in_progress && !reload_completed"
39863d1a8abSmrg  [(set (match_dup 0)
39963d1a8abSmrg	(match_dup 1))]
40063d1a8abSmrg  { if (spu_split_store(operands))
40163d1a8abSmrg      DONE;
40263d1a8abSmrg  })
40363d1a8abSmrg;; Operand 3 is the number of bytes. 1:b 2:h 4:w 8:d
40463d1a8abSmrg
40563d1a8abSmrg(define_expand "cpat"
40663d1a8abSmrg  [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
40763d1a8abSmrg	(unspec:TI [(match_operand:SI 1 "spu_reg_operand" "r,r")
40863d1a8abSmrg		    (match_operand:SI 2 "spu_nonmem_operand" "r,n")
40963d1a8abSmrg		    (match_operand:SI 3 "immediate_operand" "i,i")] UNSPEC_CPAT))]
41063d1a8abSmrg  ""
41163d1a8abSmrg  {
41263d1a8abSmrg    rtx x = gen_cpat_const (operands);
41363d1a8abSmrg    if (x)
41463d1a8abSmrg      {
41563d1a8abSmrg        emit_move_insn (operands[0], x);
41663d1a8abSmrg        DONE;
41763d1a8abSmrg      }
41863d1a8abSmrg  })
41963d1a8abSmrg
42063d1a8abSmrg(define_insn "_cpat"
42163d1a8abSmrg  [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
42263d1a8abSmrg	(unspec:TI [(match_operand:SI 1 "spu_reg_operand" "r,r")
42363d1a8abSmrg		    (match_operand:SI 2 "spu_nonmem_operand" "r,n")
42463d1a8abSmrg		    (match_operand:SI 3 "immediate_operand" "i,i")] UNSPEC_CPAT))]
42563d1a8abSmrg  ""
42663d1a8abSmrg  "@
42763d1a8abSmrg   c%M3x\t%0,%1,%2
42863d1a8abSmrg   c%M3d\t%0,%C2(%1)"
42963d1a8abSmrg  [(set_attr "type" "shuf")])
43063d1a8abSmrg
43163d1a8abSmrg(define_split
43263d1a8abSmrg  [(set (match_operand:TI 0 "spu_reg_operand")
43363d1a8abSmrg	(unspec:TI [(match_operand:SI 1 "spu_nonmem_operand")
43463d1a8abSmrg		    (match_operand:SI 2 "immediate_operand")
43563d1a8abSmrg		    (match_operand:SI 3 "immediate_operand")] UNSPEC_CPAT))]
43663d1a8abSmrg  ""
43763d1a8abSmrg  [(set (match_dup:TI 0)
43863d1a8abSmrg        (match_dup:TI 4))]
43963d1a8abSmrg  {
44063d1a8abSmrg    operands[4] = gen_cpat_const (operands);
44163d1a8abSmrg    if (!operands[4])
44263d1a8abSmrg      FAIL;
44363d1a8abSmrg  })
44463d1a8abSmrg
44563d1a8abSmrg;; extend
44663d1a8abSmrg
44763d1a8abSmrg(define_insn "extendqihi2"
44863d1a8abSmrg  [(set (match_operand:HI 0 "spu_reg_operand" "=r")
44963d1a8abSmrg	(sign_extend:HI (match_operand:QI 1 "spu_reg_operand" "r")))]
45063d1a8abSmrg  ""
45163d1a8abSmrg  "xsbh\t%0,%1")
45263d1a8abSmrg
45363d1a8abSmrg(define_insn "extendhisi2"
45463d1a8abSmrg  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
45563d1a8abSmrg	(sign_extend:SI (match_operand:HI 1 "spu_reg_operand" "r")))]
45663d1a8abSmrg  ""
45763d1a8abSmrg  "xshw\t%0,%1")
45863d1a8abSmrg
45963d1a8abSmrg(define_expand "extendsidi2"
46063d1a8abSmrg  [(set (match_dup:DI 2)
46163d1a8abSmrg	(zero_extend:DI (match_operand:SI 1 "spu_reg_operand" "")))
46263d1a8abSmrg   (set (match_operand:DI 0 "spu_reg_operand" "")
46363d1a8abSmrg	(sign_extend:DI (vec_select:SI (match_dup:V2SI 3)
46463d1a8abSmrg				       (parallel [(const_int 1)]))))]
46563d1a8abSmrg  ""
46663d1a8abSmrg  {
46763d1a8abSmrg    operands[2] = gen_reg_rtx (DImode);
46863d1a8abSmrg    operands[3] = spu_gen_subreg (V2SImode, operands[2]);
46963d1a8abSmrg  })
47063d1a8abSmrg
47163d1a8abSmrg(define_insn "xswd"
47263d1a8abSmrg  [(set (match_operand:DI 0 "spu_reg_operand" "=r")
47363d1a8abSmrg	(sign_extend:DI
47463d1a8abSmrg	  (vec_select:SI
47563d1a8abSmrg	    (match_operand:V2SI 1 "spu_reg_operand" "r")
47663d1a8abSmrg	    (parallel [(const_int 1) ]))))]
47763d1a8abSmrg  ""
47863d1a8abSmrg  "xswd\t%0,%1");
47963d1a8abSmrg
48063d1a8abSmrg;; By splitting this late we don't allow much opportunity for sharing of
48163d1a8abSmrg;; constants.  That's ok because this should really be optimized away.
48263d1a8abSmrg(define_insn_and_split "extend<mode>ti2"
48363d1a8abSmrg  [(set (match_operand:TI 0 "register_operand" "")
48463d1a8abSmrg	(sign_extend:TI (match_operand:QHSDI 1 "register_operand" "")))]
48563d1a8abSmrg  ""
48663d1a8abSmrg  "#"
48763d1a8abSmrg  ""
48863d1a8abSmrg  [(set (match_dup:TI 0)
48963d1a8abSmrg	(sign_extend:TI (match_dup:QHSDI 1)))]
49063d1a8abSmrg  {
49163d1a8abSmrg    spu_expand_sign_extend(operands);
49263d1a8abSmrg    DONE;
49363d1a8abSmrg  })
49463d1a8abSmrg
49563d1a8abSmrg
49663d1a8abSmrg;; zero_extend
49763d1a8abSmrg
49863d1a8abSmrg(define_insn "zero_extendqihi2"
49963d1a8abSmrg  [(set (match_operand:HI 0 "spu_reg_operand" "=r")
50063d1a8abSmrg	(zero_extend:HI (match_operand:QI 1 "spu_reg_operand" "r")))]
50163d1a8abSmrg  ""
50263d1a8abSmrg  "andi\t%0,%1,0x00ff")
50363d1a8abSmrg
50463d1a8abSmrg(define_insn "zero_extendqisi2"
50563d1a8abSmrg  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
50663d1a8abSmrg	(zero_extend:SI (match_operand:QI 1 "spu_reg_operand" "r")))]
50763d1a8abSmrg  ""
50863d1a8abSmrg  "andi\t%0,%1,0x00ff")
50963d1a8abSmrg
51063d1a8abSmrg(define_expand "zero_extendhisi2"
51163d1a8abSmrg  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
51263d1a8abSmrg	(zero_extend:SI (match_operand:HI 1 "spu_reg_operand" "r")))
51363d1a8abSmrg   (clobber (match_scratch:SI 2 "=&r"))]
51463d1a8abSmrg  ""
51563d1a8abSmrg  {
51663d1a8abSmrg    rtx mask = gen_reg_rtx (SImode);
51763d1a8abSmrg    rtx op1 = simplify_gen_subreg (SImode, operands[1], HImode, 0);
51863d1a8abSmrg    emit_move_insn (mask, GEN_INT (0xffff));
51963d1a8abSmrg    emit_insn (gen_andsi3(operands[0], op1, mask));
52063d1a8abSmrg    DONE;
52163d1a8abSmrg  })
52263d1a8abSmrg
52363d1a8abSmrg(define_insn "zero_extendsidi2"
52463d1a8abSmrg  [(set (match_operand:DI 0 "spu_reg_operand" "=r")
52563d1a8abSmrg	(zero_extend:DI (match_operand:SI 1 "spu_reg_operand" "r")))]
52663d1a8abSmrg  ""
52763d1a8abSmrg  "rotqmbyi\t%0,%1,-4"
52863d1a8abSmrg  [(set_attr "type" "shuf")])
52963d1a8abSmrg
53063d1a8abSmrg(define_insn "zero_extendqiti2"
53163d1a8abSmrg  [(set (match_operand:TI 0 "spu_reg_operand" "=r")
53263d1a8abSmrg	(zero_extend:TI (match_operand:QI 1 "spu_reg_operand" "r")))]
53363d1a8abSmrg  ""
53463d1a8abSmrg  "andi\t%0,%1,0x00ff\;rotqmbyi\t%0,%0,-12"
53563d1a8abSmrg  [(set_attr "type" "multi0")
53663d1a8abSmrg   (set_attr "length" "8")])
53763d1a8abSmrg
53863d1a8abSmrg(define_insn "zero_extendhiti2"
53963d1a8abSmrg  [(set (match_operand:TI 0 "spu_reg_operand" "=r")
54063d1a8abSmrg	(zero_extend:TI (match_operand:HI 1 "spu_reg_operand" "r")))]
54163d1a8abSmrg  ""
54263d1a8abSmrg  "shli\t%0,%1,16\;rotqmbyi\t%0,%0,-14"
54363d1a8abSmrg  [(set_attr "type" "multi1")
54463d1a8abSmrg   (set_attr "length" "8")])
54563d1a8abSmrg
54663d1a8abSmrg(define_insn "zero_extendsiti2"
54763d1a8abSmrg  [(set (match_operand:TI 0 "spu_reg_operand" "=r")
54863d1a8abSmrg	(zero_extend:TI (match_operand:SI 1 "spu_reg_operand" "r")))]
54963d1a8abSmrg  ""
55063d1a8abSmrg  "rotqmbyi\t%0,%1,-12"
55163d1a8abSmrg  [(set_attr "type" "shuf")])
55263d1a8abSmrg
55363d1a8abSmrg(define_insn "zero_extendditi2"
55463d1a8abSmrg  [(set (match_operand:TI 0 "spu_reg_operand" "=r")
55563d1a8abSmrg	(zero_extend:TI (match_operand:DI 1 "spu_reg_operand" "r")))]
55663d1a8abSmrg  ""
55763d1a8abSmrg  "rotqmbyi\t%0,%1,-8"
55863d1a8abSmrg  [(set_attr "type" "shuf")])
55963d1a8abSmrg
56063d1a8abSmrg
56163d1a8abSmrg;; trunc
56263d1a8abSmrg
56363d1a8abSmrg(define_insn "truncdiqi2"
56463d1a8abSmrg  [(set (match_operand:QI 0 "spu_reg_operand" "=r")
56563d1a8abSmrg	(truncate:QI (match_operand:DI 1 "spu_reg_operand" "r")))]
56663d1a8abSmrg  ""
56763d1a8abSmrg  "shlqbyi\t%0,%1,4"
56863d1a8abSmrg  [(set_attr "type" "shuf")])
56963d1a8abSmrg
57063d1a8abSmrg(define_insn "truncdihi2"
57163d1a8abSmrg  [(set (match_operand:HI 0 "spu_reg_operand" "=r")
57263d1a8abSmrg	(truncate:HI (match_operand:DI 1 "spu_reg_operand" "r")))]
57363d1a8abSmrg  ""
57463d1a8abSmrg  "shlqbyi\t%0,%1,4"
57563d1a8abSmrg  [(set_attr "type" "shuf")])
57663d1a8abSmrg
57763d1a8abSmrg(define_insn "truncdisi2"
57863d1a8abSmrg  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
57963d1a8abSmrg	(truncate:SI (match_operand:DI 1 "spu_reg_operand" "r")))]
58063d1a8abSmrg  ""
58163d1a8abSmrg  "shlqbyi\t%0,%1,4"
58263d1a8abSmrg  [(set_attr "type" "shuf")])
58363d1a8abSmrg
58463d1a8abSmrg(define_insn "trunctiqi2"
58563d1a8abSmrg  [(set (match_operand:QI 0 "spu_reg_operand" "=r")
58663d1a8abSmrg	(truncate:QI (match_operand:TI 1 "spu_reg_operand" "r")))]
58763d1a8abSmrg  ""
58863d1a8abSmrg  "shlqbyi\t%0,%1,12"
58963d1a8abSmrg  [(set_attr "type" "shuf")])
59063d1a8abSmrg
59163d1a8abSmrg(define_insn "trunctihi2"
59263d1a8abSmrg  [(set (match_operand:HI 0 "spu_reg_operand" "=r")
59363d1a8abSmrg	(truncate:HI (match_operand:TI 1 "spu_reg_operand" "r")))]
59463d1a8abSmrg  ""
59563d1a8abSmrg  "shlqbyi\t%0,%1,12"
59663d1a8abSmrg  [(set_attr "type" "shuf")])
59763d1a8abSmrg
59863d1a8abSmrg(define_insn "trunctisi2"
59963d1a8abSmrg  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
60063d1a8abSmrg	(truncate:SI (match_operand:TI 1 "spu_reg_operand" "r")))]
60163d1a8abSmrg  ""
60263d1a8abSmrg  "shlqbyi\t%0,%1,12"
60363d1a8abSmrg  [(set_attr "type" "shuf")])
60463d1a8abSmrg
60563d1a8abSmrg(define_insn "trunctidi2"
60663d1a8abSmrg  [(set (match_operand:DI 0 "spu_reg_operand" "=r")
60763d1a8abSmrg	(truncate:DI (match_operand:TI 1 "spu_reg_operand" "r")))]
60863d1a8abSmrg  ""
60963d1a8abSmrg  "shlqbyi\t%0,%1,8"
61063d1a8abSmrg  [(set_attr "type" "shuf")])
61163d1a8abSmrg
61263d1a8abSmrg
61363d1a8abSmrg;; float conversions
61463d1a8abSmrg
61563d1a8abSmrg(define_insn "float<mode><i2f>2"
61663d1a8abSmrg  [(set (match_operand:<I2F> 0 "spu_reg_operand" "=r")
61763d1a8abSmrg	(float:<I2F> (match_operand:VSI 1 "spu_reg_operand" "r")))]
61863d1a8abSmrg  ""
61963d1a8abSmrg  "csflt\t%0,%1,0"
62063d1a8abSmrg  [(set_attr "type" "fp7")])
62163d1a8abSmrg
62263d1a8abSmrg(define_insn "fix_trunc<mode><f2i>2"
62363d1a8abSmrg  [(set (match_operand:<F2I> 0 "spu_reg_operand" "=r")
62463d1a8abSmrg	(fix:<F2I> (match_operand:VSF 1 "spu_reg_operand" "r")))]
62563d1a8abSmrg  ""
62663d1a8abSmrg  "cflts\t%0,%1,0"
62763d1a8abSmrg  [(set_attr "type" "fp7")])
62863d1a8abSmrg
62963d1a8abSmrg(define_insn "floatuns<mode><i2f>2"
63063d1a8abSmrg  [(set (match_operand:<I2F> 0 "spu_reg_operand" "=r")
63163d1a8abSmrg	(unsigned_float:<I2F> (match_operand:VSI 1 "spu_reg_operand" "r")))]
63263d1a8abSmrg  ""
63363d1a8abSmrg  "cuflt\t%0,%1,0"
63463d1a8abSmrg  [(set_attr "type" "fp7")])
63563d1a8abSmrg
63663d1a8abSmrg(define_insn "fixuns_trunc<mode><f2i>2"
63763d1a8abSmrg  [(set (match_operand:<F2I> 0 "spu_reg_operand" "=r")
63863d1a8abSmrg	(unsigned_fix:<F2I> (match_operand:VSF 1 "spu_reg_operand" "r")))]
63963d1a8abSmrg  ""
64063d1a8abSmrg  "cfltu\t%0,%1,0"
64163d1a8abSmrg  [(set_attr "type" "fp7")])
64263d1a8abSmrg
64363d1a8abSmrg(define_insn "float<mode><i2f>2_mul"
64463d1a8abSmrg  [(set (match_operand:<I2F> 0 "spu_reg_operand" "=r")
64563d1a8abSmrg	(mult:<I2F> (float:<I2F> (match_operand:VSI 1 "spu_reg_operand" "r"))
64663d1a8abSmrg		    (match_operand:<I2F> 2 "spu_inv_exp2_operand" "w")))]
64763d1a8abSmrg  ""
64863d1a8abSmrg  "csflt\t%0,%1,%w2"
64963d1a8abSmrg  [(set_attr "type" "fp7")])
65063d1a8abSmrg
65163d1a8abSmrg(define_insn "float<mode><i2f>2_div"
65263d1a8abSmrg  [(set (match_operand:<I2F> 0 "spu_reg_operand" "=r")
65363d1a8abSmrg	(div:<I2F> (float:<I2F> (match_operand:VSI 1 "spu_reg_operand" "r"))
65463d1a8abSmrg		   (match_operand:<I2F> 2 "spu_exp2_operand" "v")))]
65563d1a8abSmrg  ""
65663d1a8abSmrg  "csflt\t%0,%1,%v2"
65763d1a8abSmrg  [(set_attr "type" "fp7")])
65863d1a8abSmrg
65963d1a8abSmrg
66063d1a8abSmrg(define_insn "fix_trunc<mode><f2i>2_mul"
66163d1a8abSmrg  [(set (match_operand:<F2I> 0 "spu_reg_operand" "=r")
66263d1a8abSmrg	(fix:<F2I> (mult:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
66363d1a8abSmrg			     (match_operand:VSF 2 "spu_exp2_operand" "v"))))]
66463d1a8abSmrg  ""
66563d1a8abSmrg  "cflts\t%0,%1,%v2"
66663d1a8abSmrg  [(set_attr "type" "fp7")])
66763d1a8abSmrg
66863d1a8abSmrg(define_insn "floatuns<mode><i2f>2_mul"
66963d1a8abSmrg  [(set (match_operand:<I2F> 0 "spu_reg_operand" "=r")
67063d1a8abSmrg	(mult:<I2F> (unsigned_float:<I2F> (match_operand:VSI 1 "spu_reg_operand" "r"))
67163d1a8abSmrg		    (match_operand:<I2F> 2 "spu_inv_exp2_operand" "w")))]
67263d1a8abSmrg  ""
67363d1a8abSmrg  "cuflt\t%0,%1,%w2"
67463d1a8abSmrg  [(set_attr "type" "fp7")])
67563d1a8abSmrg
67663d1a8abSmrg(define_insn "floatuns<mode><i2f>2_div"
67763d1a8abSmrg  [(set (match_operand:<I2F> 0 "spu_reg_operand" "=r")
67863d1a8abSmrg	(div:<I2F> (unsigned_float:<I2F> (match_operand:VSI 1 "spu_reg_operand" "r"))
67963d1a8abSmrg		   (match_operand:<I2F> 2 "spu_exp2_operand" "v")))]
68063d1a8abSmrg  ""
68163d1a8abSmrg  "cuflt\t%0,%1,%v2"
68263d1a8abSmrg  [(set_attr "type" "fp7")])
68363d1a8abSmrg
68463d1a8abSmrg(define_insn "fixuns_trunc<mode><f2i>2_mul"
68563d1a8abSmrg  [(set (match_operand:<F2I> 0 "spu_reg_operand" "=r")
68663d1a8abSmrg	(unsigned_fix:<F2I> (mult:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
68763d1a8abSmrg				      (match_operand:VSF 2 "spu_exp2_operand" "v"))))]
68863d1a8abSmrg  ""
68963d1a8abSmrg  "cfltu\t%0,%1,%v2"
69063d1a8abSmrg  [(set_attr "type" "fp7")])
69163d1a8abSmrg
69263d1a8abSmrg(define_insn "extendsfdf2"
69363d1a8abSmrg  [(set (match_operand:DF 0 "spu_reg_operand" "=r")
69463d1a8abSmrg	(unspec:DF [(match_operand:SF 1 "spu_reg_operand" "r")]
69563d1a8abSmrg                   UNSPEC_FLOAT_EXTEND))]
69663d1a8abSmrg  ""
69763d1a8abSmrg  "fesd\t%0,%1"
69863d1a8abSmrg  [(set_attr "type" "fpd")])
69963d1a8abSmrg
70063d1a8abSmrg(define_insn "truncdfsf2"
70163d1a8abSmrg  [(set (match_operand:SF 0 "spu_reg_operand" "=r")
70263d1a8abSmrg	(unspec:SF [(match_operand:DF 1 "spu_reg_operand" "r")]
70363d1a8abSmrg                   UNSPEC_FLOAT_TRUNCATE))]
70463d1a8abSmrg  ""
70563d1a8abSmrg  "frds\t%0,%1"
70663d1a8abSmrg  [(set_attr "type" "fpd")])
70763d1a8abSmrg
70863d1a8abSmrg(define_expand "floatdisf2"
70963d1a8abSmrg  [(set (match_operand:SF 0 "register_operand" "")
71063d1a8abSmrg	(float:SF (match_operand:DI 1 "register_operand" "")))]
71163d1a8abSmrg  ""
71263d1a8abSmrg  {
71363d1a8abSmrg    rtx c0 = gen_reg_rtx (SImode);
71463d1a8abSmrg    rtx r0 = gen_reg_rtx (DImode);
71563d1a8abSmrg    rtx r1 = gen_reg_rtx (SFmode);
71663d1a8abSmrg    rtx r2 = gen_reg_rtx (SImode);
71763d1a8abSmrg    rtx setneg = gen_reg_rtx (SImode);
71863d1a8abSmrg    rtx isneg = gen_reg_rtx (SImode);
71963d1a8abSmrg    rtx neg = gen_reg_rtx (DImode);
72063d1a8abSmrg    rtx mask = gen_reg_rtx (DImode);
72163d1a8abSmrg
72263d1a8abSmrg    emit_move_insn (c0, GEN_INT (-0x80000000ll));
72363d1a8abSmrg
72463d1a8abSmrg    emit_insn (gen_negdi2 (neg, operands[1]));
72563d1a8abSmrg    emit_insn (gen_cgt_di_m1 (isneg, operands[1]));
72663d1a8abSmrg    emit_insn (gen_extend_compare (mask, isneg));
72763d1a8abSmrg    emit_insn (gen_selb (r0, neg, operands[1], mask));
72863d1a8abSmrg    emit_insn (gen_andc_si (setneg, c0, isneg));
72963d1a8abSmrg
73063d1a8abSmrg    emit_insn (gen_floatunsdisf2 (r1, r0));
73163d1a8abSmrg
73263d1a8abSmrg    emit_insn (gen_iorsi3 (r2, gen_rtx_SUBREG (SImode, r1, 0), setneg));
73363d1a8abSmrg    emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, r2, 0));
73463d1a8abSmrg    DONE;
73563d1a8abSmrg  })
73663d1a8abSmrg
73763d1a8abSmrg(define_insn_and_split "floatunsdisf2"
73863d1a8abSmrg  [(set (match_operand:SF 0 "register_operand" "=r")
73963d1a8abSmrg        (unsigned_float:SF (match_operand:DI 1 "register_operand" "r")))
74063d1a8abSmrg   (clobber (match_scratch:SF 2 "=r"))
74163d1a8abSmrg   (clobber (match_scratch:SF 3 "=r"))
74263d1a8abSmrg   (clobber (match_scratch:SF 4 "=r"))]
74363d1a8abSmrg  ""
74463d1a8abSmrg  "#"
74563d1a8abSmrg  "reload_completed"
74663d1a8abSmrg  [(set (match_dup:SF 0)
74763d1a8abSmrg        (unsigned_float:SF (match_dup:DI 1)))]
74863d1a8abSmrg  {
74963d1a8abSmrg    rtx op1_v4si = gen_rtx_REG (V4SImode, REGNO (operands[1]));
75063d1a8abSmrg    rtx op2_v4sf = gen_rtx_REG (V4SFmode, REGNO (operands[2]));
75163d1a8abSmrg    rtx op2_ti = gen_rtx_REG (TImode, REGNO (operands[2]));
75263d1a8abSmrg    rtx op3_ti = gen_rtx_REG (TImode, REGNO (operands[3]));
75363d1a8abSmrg
75463d1a8abSmrg    REAL_VALUE_TYPE scale;
75563d1a8abSmrg    real_2expN (&scale, 32, SFmode);
75663d1a8abSmrg
75763d1a8abSmrg    emit_insn (gen_floatunsv4siv4sf2 (op2_v4sf, op1_v4si));
75863d1a8abSmrg    emit_insn (gen_shlqby_ti (op3_ti, op2_ti, GEN_INT (4)));
75963d1a8abSmrg
76063d1a8abSmrg    emit_move_insn (operands[4],
76163d1a8abSmrg		    const_double_from_real_value (scale, SFmode));
76263d1a8abSmrg    emit_insn (gen_fmasf4 (operands[0],
76363d1a8abSmrg			   operands[2], operands[4], operands[3]));
76463d1a8abSmrg    DONE;
76563d1a8abSmrg  })
76663d1a8abSmrg
76763d1a8abSmrg(define_expand "floattisf2"
76863d1a8abSmrg  [(set (match_operand:SF 0 "register_operand" "")
76963d1a8abSmrg	(float:SF (match_operand:TI 1 "register_operand" "")))]
77063d1a8abSmrg  ""
77163d1a8abSmrg  {
77263d1a8abSmrg    rtx c0 = gen_reg_rtx (SImode);
77363d1a8abSmrg    rtx r0 = gen_reg_rtx (TImode);
77463d1a8abSmrg    rtx r1 = gen_reg_rtx (SFmode);
77563d1a8abSmrg    rtx r2 = gen_reg_rtx (SImode);
77663d1a8abSmrg    rtx setneg = gen_reg_rtx (SImode);
77763d1a8abSmrg    rtx isneg = gen_reg_rtx (SImode);
77863d1a8abSmrg    rtx neg = gen_reg_rtx (TImode);
77963d1a8abSmrg    rtx mask = gen_reg_rtx (TImode);
78063d1a8abSmrg
78163d1a8abSmrg    emit_move_insn (c0, GEN_INT (-0x80000000ll));
78263d1a8abSmrg
78363d1a8abSmrg    emit_insn (gen_negti2 (neg, operands[1]));
78463d1a8abSmrg    emit_insn (gen_cgt_ti_m1 (isneg, operands[1]));
78563d1a8abSmrg    emit_insn (gen_extend_compare (mask, isneg));
78663d1a8abSmrg    emit_insn (gen_selb (r0, neg, operands[1], mask));
78763d1a8abSmrg    emit_insn (gen_andc_si (setneg, c0, isneg));
78863d1a8abSmrg
78963d1a8abSmrg    emit_insn (gen_floatunstisf2 (r1, r0));
79063d1a8abSmrg
79163d1a8abSmrg    emit_insn (gen_iorsi3 (r2, gen_rtx_SUBREG (SImode, r1, 0), setneg));
79263d1a8abSmrg    emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, r2, 0));
79363d1a8abSmrg    DONE;
79463d1a8abSmrg  })
79563d1a8abSmrg
79663d1a8abSmrg(define_insn_and_split "floatunstisf2"
79763d1a8abSmrg  [(set (match_operand:SF 0 "register_operand" "=r")
79863d1a8abSmrg        (unsigned_float:SF (match_operand:TI 1 "register_operand" "r")))
79963d1a8abSmrg   (clobber (match_scratch:SF 2 "=r"))
80063d1a8abSmrg   (clobber (match_scratch:SF 3 "=r"))
80163d1a8abSmrg   (clobber (match_scratch:SF 4 "=r"))]
80263d1a8abSmrg  ""
80363d1a8abSmrg  "#"
80463d1a8abSmrg  "reload_completed"
80563d1a8abSmrg  [(set (match_dup:SF 0)
80663d1a8abSmrg        (unsigned_float:SF (match_dup:TI 1)))]
80763d1a8abSmrg  {
80863d1a8abSmrg    rtx op1_v4si = gen_rtx_REG (V4SImode, REGNO (operands[1]));
80963d1a8abSmrg    rtx op2_v4sf = gen_rtx_REG (V4SFmode, REGNO (operands[2]));
81063d1a8abSmrg    rtx op2_ti = gen_rtx_REG (TImode, REGNO (operands[2]));
81163d1a8abSmrg    rtx op3_ti = gen_rtx_REG (TImode, REGNO (operands[3]));
81263d1a8abSmrg
81363d1a8abSmrg    REAL_VALUE_TYPE scale;
81463d1a8abSmrg    real_2expN (&scale, 32, SFmode);
81563d1a8abSmrg
81663d1a8abSmrg    emit_insn (gen_floatunsv4siv4sf2 (op2_v4sf, op1_v4si));
81763d1a8abSmrg    emit_insn (gen_shlqby_ti (op3_ti, op2_ti, GEN_INT (4)));
81863d1a8abSmrg
81963d1a8abSmrg    emit_move_insn (operands[4],
82063d1a8abSmrg		    const_double_from_real_value (scale, SFmode));
82163d1a8abSmrg    emit_insn (gen_fmasf4 (operands[2],
82263d1a8abSmrg			   operands[2], operands[4], operands[3]));
82363d1a8abSmrg
82463d1a8abSmrg    emit_insn (gen_shlqby_ti (op3_ti, op3_ti, GEN_INT (4)));
82563d1a8abSmrg    emit_insn (gen_fmasf4 (operands[2],
82663d1a8abSmrg			   operands[2], operands[4], operands[3]));
82763d1a8abSmrg
82863d1a8abSmrg    emit_insn (gen_shlqby_ti (op3_ti, op3_ti, GEN_INT (4)));
82963d1a8abSmrg    emit_insn (gen_fmasf4 (operands[0],
83063d1a8abSmrg			   operands[2], operands[4], operands[3]));
83163d1a8abSmrg    DONE;
83263d1a8abSmrg  })
83363d1a8abSmrg
83463d1a8abSmrg;; Do (double)(operands[1]+0x80000000u)-(double)0x80000000
83563d1a8abSmrg(define_expand "floatsidf2"
83663d1a8abSmrg  [(set (match_operand:DF 0 "register_operand" "")
83763d1a8abSmrg	(float:DF (match_operand:SI 1 "register_operand" "")))]
83863d1a8abSmrg  ""
83963d1a8abSmrg  {
84063d1a8abSmrg    rtx c0 = gen_reg_rtx (SImode);
84163d1a8abSmrg    rtx c1 = gen_reg_rtx (DFmode);
84263d1a8abSmrg    rtx r0 = gen_reg_rtx (SImode);
84363d1a8abSmrg    rtx r1 = gen_reg_rtx (DFmode);
84463d1a8abSmrg
84563d1a8abSmrg    emit_move_insn (c0, GEN_INT (-0x80000000ll));
84663d1a8abSmrg    emit_move_insn (c1, spu_float_const ("2147483648", DFmode));
84763d1a8abSmrg    emit_insn (gen_xorsi3 (r0, operands[1], c0));
84863d1a8abSmrg    emit_insn (gen_floatunssidf2 (r1, r0));
84963d1a8abSmrg    emit_insn (gen_subdf3 (operands[0], r1, c1));
85063d1a8abSmrg    DONE;
85163d1a8abSmrg  })
85263d1a8abSmrg
85363d1a8abSmrg(define_expand "floatunssidf2"
85463d1a8abSmrg  [(set (match_operand:DF 0 "register_operand"  "=r")
85563d1a8abSmrg        (unsigned_float:DF (match_operand:SI 1 "register_operand"   "r")))]
85663d1a8abSmrg  ""
85763d1a8abSmrg  "{
85863d1a8abSmrg    rtx value;
85963d1a8abSmrg    rtx c0 = spu_const_from_ints (V16QImode, 0x02031011, 0x12138080,
86063d1a8abSmrg                                             0x06071415, 0x16178080);
86163d1a8abSmrg    rtx r0 = gen_reg_rtx (V16QImode);
86263d1a8abSmrg
86363d1a8abSmrg    if (optimize_size)
86463d1a8abSmrg    {
86563d1a8abSmrg       start_sequence ();
86663d1a8abSmrg       value =
86763d1a8abSmrg	 emit_library_call_value (convert_optab_libfunc (ufloat_optab,
86863d1a8abSmrg							 DFmode, SImode),
869c7a68eb7Smrg				  NULL_RTX, LCT_NORMAL, DFmode,
870c7a68eb7Smrg				  operands[1], SImode);
87163d1a8abSmrg       rtx_insn *insns = get_insns ();
87263d1a8abSmrg       end_sequence ();
87363d1a8abSmrg       emit_libcall_block (insns, operands[0], value,
87463d1a8abSmrg                           gen_rtx_UNSIGNED_FLOAT (DFmode, operands[1]));
87563d1a8abSmrg     }
87663d1a8abSmrg     else
87763d1a8abSmrg     {
87863d1a8abSmrg      emit_move_insn (r0, c0);
87963d1a8abSmrg      emit_insn (gen_floatunssidf2_internal (operands[0], operands[1], r0));
88063d1a8abSmrg     }
88163d1a8abSmrg    DONE;
88263d1a8abSmrg  }")
88363d1a8abSmrg
88463d1a8abSmrg(define_insn_and_split "floatunssidf2_internal"
88563d1a8abSmrg  [(set (match_operand:DF 0 "register_operand"  "=r")
88663d1a8abSmrg        (unsigned_float:DF (match_operand:SI 1 "register_operand"   "r")))
88763d1a8abSmrg   (use (match_operand:V16QI 2 "register_operand" "r"))
88863d1a8abSmrg   (clobber (match_scratch:V4SI 3 "=&r"))
88963d1a8abSmrg   (clobber (match_scratch:V4SI 4 "=&r"))
89063d1a8abSmrg   (clobber (match_scratch:V4SI 5 "=&r"))
89163d1a8abSmrg   (clobber (match_scratch:V4SI 6 "=&r"))]
89263d1a8abSmrg  ""
89363d1a8abSmrg  "clz\t%3,%1\;il\t%6,1023+31\;shl\t%4,%1,%3\;ceqi\t%5,%3,32\;sf\t%6,%3,%6\;a\t%4,%4,%4\;andc\t%6,%6,%5\;shufb\t%6,%6,%4,%2\;shlqbii\t%0,%6,4"
89463d1a8abSmrg  "reload_completed"
89563d1a8abSmrg  [(set (match_dup:DF 0)
89663d1a8abSmrg        (unsigned_float:DF (match_dup:SI 1)))]
89763d1a8abSmrg "{
89863d1a8abSmrg    rtx *ops = operands;
89963d1a8abSmrg    rtx op1_v4si = gen_rtx_REG(V4SImode, REGNO(ops[1]));
90063d1a8abSmrg    rtx op0_ti = gen_rtx_REG (TImode, REGNO (ops[0]));
90163d1a8abSmrg    rtx op2_ti = gen_rtx_REG (TImode, REGNO (ops[2]));
90263d1a8abSmrg    rtx op6_ti = gen_rtx_REG (TImode, REGNO (ops[6]));
90363d1a8abSmrg    emit_insn (gen_clzv4si2 (ops[3],op1_v4si));
90463d1a8abSmrg    emit_move_insn (ops[6], spu_const (V4SImode, 1023+31));
90563d1a8abSmrg    emit_insn (gen_vashlv4si3 (ops[4],op1_v4si,ops[3]));
90663d1a8abSmrg    emit_insn (gen_ceq_v4si (ops[5],ops[3],spu_const (V4SImode, 32)));
90763d1a8abSmrg    emit_insn (gen_subv4si3 (ops[6],ops[6],ops[3]));
90863d1a8abSmrg    emit_insn (gen_addv4si3 (ops[4],ops[4],ops[4]));
90963d1a8abSmrg    emit_insn (gen_andc_v4si  (ops[6],ops[6],ops[5]));
91063d1a8abSmrg    emit_insn (gen_shufb (ops[6],ops[6],ops[4],op2_ti));
91163d1a8abSmrg    emit_insn (gen_shlqbi_ti (op0_ti,op6_ti,GEN_INT(4)));
91263d1a8abSmrg    DONE;
91363d1a8abSmrg  }"
91463d1a8abSmrg [(set_attr "length" "32")])
91563d1a8abSmrg
91663d1a8abSmrg(define_expand "floatdidf2"
91763d1a8abSmrg  [(set (match_operand:DF 0 "register_operand" "")
91863d1a8abSmrg	(float:DF (match_operand:DI 1 "register_operand" "")))]
91963d1a8abSmrg  ""
92063d1a8abSmrg  {
92163d1a8abSmrg    rtx c0 = gen_reg_rtx (DImode);
92263d1a8abSmrg    rtx r0 = gen_reg_rtx (DImode);
92363d1a8abSmrg    rtx r1 = gen_reg_rtx (DFmode);
92463d1a8abSmrg    rtx r2 = gen_reg_rtx (DImode);
92563d1a8abSmrg    rtx setneg = gen_reg_rtx (DImode);
92663d1a8abSmrg    rtx isneg = gen_reg_rtx (SImode);
92763d1a8abSmrg    rtx neg = gen_reg_rtx (DImode);
92863d1a8abSmrg    rtx mask = gen_reg_rtx (DImode);
92963d1a8abSmrg
93063d1a8abSmrg    emit_move_insn (c0, GEN_INT (0x8000000000000000ull));
93163d1a8abSmrg
93263d1a8abSmrg    emit_insn (gen_negdi2 (neg, operands[1]));
93363d1a8abSmrg    emit_insn (gen_cgt_di_m1 (isneg, operands[1]));
93463d1a8abSmrg    emit_insn (gen_extend_compare (mask, isneg));
93563d1a8abSmrg    emit_insn (gen_selb (r0, neg, operands[1], mask));
93663d1a8abSmrg    emit_insn (gen_andc_di (setneg, c0, mask));
93763d1a8abSmrg
93863d1a8abSmrg    emit_insn (gen_floatunsdidf2 (r1, r0));
93963d1a8abSmrg
94063d1a8abSmrg    emit_insn (gen_iordi3 (r2, gen_rtx_SUBREG (DImode, r1, 0), setneg));
94163d1a8abSmrg    emit_move_insn (operands[0], gen_rtx_SUBREG (DFmode, r2, 0));
94263d1a8abSmrg    DONE;
94363d1a8abSmrg  })
94463d1a8abSmrg
94563d1a8abSmrg(define_expand "floatunsdidf2"
94663d1a8abSmrg  [(set (match_operand:DF 0 "register_operand"  "=r")
94763d1a8abSmrg        (unsigned_float:DF (match_operand:DI 1 "register_operand"   "r")))]
94863d1a8abSmrg  ""
94963d1a8abSmrg  "{
95063d1a8abSmrg    rtx value;
95163d1a8abSmrg    rtx c0 = spu_const_from_ints (V16QImode, 0x02031011, 0x12138080,
95263d1a8abSmrg                                             0x06071415, 0x16178080);
95363d1a8abSmrg    rtx c1 = spu_const_from_ints (V4SImode, 1023+63, 1023+31, 0, 0);
95463d1a8abSmrg    rtx r0 = gen_reg_rtx (V16QImode);
95563d1a8abSmrg    rtx r1 = gen_reg_rtx (V4SImode);
95663d1a8abSmrg
95763d1a8abSmrg    if (optimize_size)
95863d1a8abSmrg    {
95963d1a8abSmrg      start_sequence ();
96063d1a8abSmrg      value =
96163d1a8abSmrg         emit_library_call_value (convert_optab_libfunc (ufloat_optab,
96263d1a8abSmrg                                                         DFmode, DImode),
963c7a68eb7Smrg				  NULL_RTX, LCT_NORMAL, DFmode,
964c7a68eb7Smrg				  operands[1], DImode);
96563d1a8abSmrg      rtx_insn *insns = get_insns ();
96663d1a8abSmrg      end_sequence ();
96763d1a8abSmrg      emit_libcall_block (insns, operands[0], value,
96863d1a8abSmrg                          gen_rtx_UNSIGNED_FLOAT (DFmode, operands[1]));
96963d1a8abSmrg    }
97063d1a8abSmrg    else
97163d1a8abSmrg    {
97263d1a8abSmrg      emit_move_insn (r1, c1);
97363d1a8abSmrg      emit_move_insn (r0, c0);
97463d1a8abSmrg      emit_insn (gen_floatunsdidf2_internal (operands[0], operands[1], r0, r1));
97563d1a8abSmrg    }
97663d1a8abSmrg    DONE;
97763d1a8abSmrg  }")
97863d1a8abSmrg
97963d1a8abSmrg(define_insn_and_split "floatunsdidf2_internal"
98063d1a8abSmrg  [(set (match_operand:DF 0 "register_operand"  "=r")
98163d1a8abSmrg        (unsigned_float:DF (match_operand:DI 1 "register_operand"   "r")))
98263d1a8abSmrg   (use (match_operand:V16QI 2 "register_operand" "r"))
98363d1a8abSmrg   (use (match_operand:V4SI 3 "register_operand" "r"))
98463d1a8abSmrg   (clobber (match_scratch:V4SI 4 "=&r"))
98563d1a8abSmrg   (clobber (match_scratch:V4SI 5 "=&r"))
98663d1a8abSmrg   (clobber (match_scratch:V4SI 6 "=&r"))]
98763d1a8abSmrg  ""
98863d1a8abSmrg  "clz\t%4,%1\;shl\t%5,%1,%4\;ceqi\t%6,%4,32\;sf\t%4,%4,%3\;a\t%5,%5,%5\;andc\t%4,%4,%6\;shufb\t%4,%4,%5,%2\;shlqbii\t%4,%4,4\;shlqbyi\t%5,%4,8\;dfa\t%0,%4,%5"
98963d1a8abSmrg  "reload_completed"
99063d1a8abSmrg  [(set (match_operand:DF 0 "register_operand"  "=r")
99163d1a8abSmrg        (unsigned_float:DF (match_operand:DI 1 "register_operand"   "r")))]
99263d1a8abSmrg  "{
99363d1a8abSmrg    rtx *ops = operands;
99463d1a8abSmrg    rtx op1_v4si = gen_rtx_REG (V4SImode, REGNO(ops[1]));
99563d1a8abSmrg    rtx op2_ti = gen_rtx_REG (TImode, REGNO(ops[2]));
99663d1a8abSmrg    rtx op4_ti = gen_rtx_REG (TImode, REGNO(ops[4]));
99763d1a8abSmrg    rtx op5_ti = gen_rtx_REG (TImode, REGNO(ops[5]));
99863d1a8abSmrg    rtx op4_df = gen_rtx_REG (DFmode, REGNO(ops[4]));
99963d1a8abSmrg    rtx op5_df = gen_rtx_REG (DFmode, REGNO(ops[5]));
100063d1a8abSmrg    emit_insn (gen_clzv4si2 (ops[4],op1_v4si));
100163d1a8abSmrg    emit_insn (gen_vashlv4si3 (ops[5],op1_v4si,ops[4]));
100263d1a8abSmrg    emit_insn (gen_ceq_v4si (ops[6],ops[4],spu_const (V4SImode, 32)));
100363d1a8abSmrg    emit_insn (gen_subv4si3 (ops[4],ops[3],ops[4]));
100463d1a8abSmrg    emit_insn (gen_addv4si3 (ops[5],ops[5],ops[5]));
100563d1a8abSmrg    emit_insn (gen_andc_v4si (ops[4],ops[4],ops[6]));
100663d1a8abSmrg    emit_insn (gen_shufb (ops[4],ops[4],ops[5],op2_ti));
100763d1a8abSmrg    emit_insn (gen_shlqbi_ti (op4_ti,op4_ti,GEN_INT(4)));
100863d1a8abSmrg    emit_insn (gen_shlqby_ti (op5_ti,op4_ti,GEN_INT(8)));
100963d1a8abSmrg    emit_insn (gen_adddf3 (ops[0],op4_df,op5_df));
101063d1a8abSmrg    DONE;
101163d1a8abSmrg  }"
101263d1a8abSmrg  [(set_attr "length" "40")])
101363d1a8abSmrg
101463d1a8abSmrg
101563d1a8abSmrg;; add
101663d1a8abSmrg
101763d1a8abSmrg(define_expand "addv16qi3"
101863d1a8abSmrg  [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
101963d1a8abSmrg	(plus:V16QI (match_operand:V16QI 1 "spu_reg_operand" "r")
102063d1a8abSmrg		    (match_operand:V16QI 2 "spu_reg_operand" "r")))]
102163d1a8abSmrg  ""
102263d1a8abSmrg  "{
102363d1a8abSmrg    rtx res_short = simplify_gen_subreg (V8HImode, operands[0], V16QImode, 0);
102463d1a8abSmrg    rtx lhs_short = simplify_gen_subreg (V8HImode, operands[1], V16QImode, 0);
102563d1a8abSmrg    rtx rhs_short = simplify_gen_subreg (V8HImode, operands[2], V16QImode, 0);
102663d1a8abSmrg    rtx rhs_and = gen_reg_rtx (V8HImode);
102763d1a8abSmrg    rtx hi_char = gen_reg_rtx (V8HImode);
102863d1a8abSmrg    rtx lo_char = gen_reg_rtx (V8HImode);
102963d1a8abSmrg    rtx mask = gen_reg_rtx (V8HImode);
103063d1a8abSmrg
103163d1a8abSmrg    emit_move_insn (mask, spu_const (V8HImode, 0x00ff));
103263d1a8abSmrg    emit_insn (gen_andv8hi3 (rhs_and, rhs_short, spu_const (V8HImode, 0xff00)));
103363d1a8abSmrg    emit_insn (gen_addv8hi3 (hi_char, lhs_short, rhs_and));
103463d1a8abSmrg    emit_insn (gen_addv8hi3 (lo_char, lhs_short, rhs_short));
103563d1a8abSmrg    emit_insn (gen_selb (res_short, hi_char, lo_char, mask));
103663d1a8abSmrg    DONE;
103763d1a8abSmrg   }")
103863d1a8abSmrg
103963d1a8abSmrg(define_insn "add<mode>3"
104063d1a8abSmrg  [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
104163d1a8abSmrg	(plus:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
104263d1a8abSmrg		   (match_operand:VHSI 2 "spu_arith_operand" "r,B")))]
104363d1a8abSmrg  ""
104463d1a8abSmrg  "@
104563d1a8abSmrg  a<bh>\t%0,%1,%2
104663d1a8abSmrg  a<bh>i\t%0,%1,%2")
104763d1a8abSmrg
104863d1a8abSmrg(define_expand "add<mode>3"
104963d1a8abSmrg  [(set (match_dup:VDI 3)
105063d1a8abSmrg	(unspec:VDI [(match_operand:VDI 1 "spu_reg_operand" "")
105163d1a8abSmrg		     (match_operand:VDI 2 "spu_reg_operand" "")] UNSPEC_CG))
105263d1a8abSmrg   (set (match_dup:VDI 5)
105363d1a8abSmrg	(unspec:VDI [(match_dup 3)
105463d1a8abSmrg		     (match_dup 3)
105563d1a8abSmrg		     (match_dup:TI 4)] UNSPEC_SHUFB))
105663d1a8abSmrg   (set (match_operand:VDI 0 "spu_reg_operand" "")
105763d1a8abSmrg	(unspec:VDI [(match_dup 1)
105863d1a8abSmrg		     (match_dup 2)
105963d1a8abSmrg		     (match_dup 5)] UNSPEC_ADDX))]
106063d1a8abSmrg  ""
106163d1a8abSmrg  {
106263d1a8abSmrg    unsigned char pat[16] = {
106363d1a8abSmrg      0x04, 0x05, 0x06, 0x07,
106463d1a8abSmrg      0x80, 0x80, 0x80, 0x80,
106563d1a8abSmrg      0x0c, 0x0d, 0x0e, 0x0f,
106663d1a8abSmrg      0x80, 0x80, 0x80, 0x80
106763d1a8abSmrg    };
106863d1a8abSmrg    operands[3] = gen_reg_rtx (<MODE>mode);
106963d1a8abSmrg    operands[4] = gen_reg_rtx (TImode);
107063d1a8abSmrg    operands[5] = gen_reg_rtx (<MODE>mode);
107163d1a8abSmrg    emit_move_insn (operands[4], array_to_constant (TImode, pat));
107263d1a8abSmrg  })
107363d1a8abSmrg
107463d1a8abSmrg(define_insn "cg_<mode>"
107563d1a8abSmrg  [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
107663d1a8abSmrg	(unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
107763d1a8abSmrg		      (match_operand 2 "spu_reg_operand" "r")] UNSPEC_CG))]
107863d1a8abSmrg  "operands != NULL"
107963d1a8abSmrg  "cg\t%0,%1,%2")
108063d1a8abSmrg
108163d1a8abSmrg(define_insn "cgx_<mode>"
108263d1a8abSmrg  [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
108363d1a8abSmrg	(unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
108463d1a8abSmrg		      (match_operand 2 "spu_reg_operand" "r")
108563d1a8abSmrg		      (match_operand 3 "spu_reg_operand" "0")] UNSPEC_CGX))]
108663d1a8abSmrg  "operands != NULL"
108763d1a8abSmrg  "cgx\t%0,%1,%2")
108863d1a8abSmrg
108963d1a8abSmrg(define_insn "addx_<mode>"
109063d1a8abSmrg  [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
109163d1a8abSmrg	(unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
109263d1a8abSmrg		      (match_operand 2 "spu_reg_operand" "r")
109363d1a8abSmrg		      (match_operand 3 "spu_reg_operand" "0")] UNSPEC_ADDX))]
109463d1a8abSmrg  "operands != NULL"
109563d1a8abSmrg  "addx\t%0,%1,%2")
109663d1a8abSmrg
109763d1a8abSmrg
109863d1a8abSmrg;; This is not the most efficient implementation of addti3.
109963d1a8abSmrg;; We include this here because 1) the compiler needs it to be
110063d1a8abSmrg;; defined as the word size is 128-bit and 2) sometimes gcc
110163d1a8abSmrg;; substitutes an add for a constant left-shift. 2) is unlikely
110263d1a8abSmrg;; because we also give addti3 a high cost. In case gcc does
110363d1a8abSmrg;; generate TImode add, here is the code to do it.
110463d1a8abSmrg;; operand 2 is a nonmemory because the compiler requires it.
110563d1a8abSmrg(define_insn "addti3"
110663d1a8abSmrg  [(set (match_operand:TI 0 "spu_reg_operand" "=&r")
110763d1a8abSmrg	(plus:TI (match_operand:TI 1 "spu_reg_operand" "r")
110863d1a8abSmrg		 (match_operand:TI 2 "spu_nonmem_operand" "r")))
110963d1a8abSmrg   (clobber (match_scratch:TI 3 "=&r"))]
111063d1a8abSmrg  ""
111163d1a8abSmrg  "cg\t%3,%1,%2\n\\
111263d1a8abSmrg   shlqbyi\t%3,%3,4\n\\
111363d1a8abSmrg   cgx\t%3,%1,%2\n\\
111463d1a8abSmrg   shlqbyi\t%3,%3,4\n\\
111563d1a8abSmrg   cgx\t%3,%1,%2\n\\
111663d1a8abSmrg   shlqbyi\t%0,%3,4\n\\
111763d1a8abSmrg   addx\t%0,%1,%2"
111863d1a8abSmrg  [(set_attr "type" "multi0")
111963d1a8abSmrg   (set_attr "length" "28")])
112063d1a8abSmrg
112163d1a8abSmrg(define_insn "add<mode>3"
112263d1a8abSmrg  [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
112363d1a8abSmrg	(plus:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
112463d1a8abSmrg		  (match_operand:VSF 2 "spu_reg_operand" "r")))]
112563d1a8abSmrg  ""
112663d1a8abSmrg  "fa\t%0,%1,%2"
112763d1a8abSmrg  [(set_attr "type" "fp6")])
112863d1a8abSmrg
112963d1a8abSmrg(define_insn "add<mode>3"
113063d1a8abSmrg  [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
113163d1a8abSmrg	(plus:VDF (match_operand:VDF 1 "spu_reg_operand" "r")
113263d1a8abSmrg		  (match_operand:VDF 2 "spu_reg_operand" "r")))]
113363d1a8abSmrg  ""
113463d1a8abSmrg  "dfa\t%0,%1,%2"
113563d1a8abSmrg  [(set_attr "type" "fpd")])
113663d1a8abSmrg
113763d1a8abSmrg
113863d1a8abSmrg;; sub
113963d1a8abSmrg
114063d1a8abSmrg(define_expand "subv16qi3"
114163d1a8abSmrg  [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
114263d1a8abSmrg	(minus:V16QI (match_operand:V16QI 1 "spu_reg_operand" "r")
114363d1a8abSmrg		     (match_operand:V16QI 2 "spu_reg_operand" "r")))]
114463d1a8abSmrg  ""
114563d1a8abSmrg  "{
114663d1a8abSmrg    rtx res_short = simplify_gen_subreg (V8HImode, operands[0], V16QImode, 0);
114763d1a8abSmrg    rtx lhs_short = simplify_gen_subreg (V8HImode, operands[1], V16QImode, 0);
114863d1a8abSmrg    rtx rhs_short = simplify_gen_subreg (V8HImode, operands[2], V16QImode, 0);
114963d1a8abSmrg    rtx rhs_and = gen_reg_rtx (V8HImode);
115063d1a8abSmrg    rtx hi_char = gen_reg_rtx (V8HImode);
115163d1a8abSmrg    rtx lo_char = gen_reg_rtx (V8HImode);
115263d1a8abSmrg    rtx mask = gen_reg_rtx (V8HImode);
115363d1a8abSmrg
115463d1a8abSmrg    emit_move_insn (mask, spu_const (V8HImode, 0x00ff));
115563d1a8abSmrg    emit_insn (gen_andv8hi3 (rhs_and, rhs_short, spu_const (V8HImode, 0xff00)));
115663d1a8abSmrg    emit_insn (gen_subv8hi3 (hi_char, lhs_short, rhs_and));
115763d1a8abSmrg    emit_insn (gen_subv8hi3 (lo_char, lhs_short, rhs_short));
115863d1a8abSmrg    emit_insn (gen_selb (res_short, hi_char, lo_char, mask));
115963d1a8abSmrg    DONE;
116063d1a8abSmrg   }")
116163d1a8abSmrg
116263d1a8abSmrg(define_insn "sub<mode>3"
116363d1a8abSmrg  [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
116463d1a8abSmrg	(minus:VHSI (match_operand:VHSI 1 "spu_arith_operand" "r,B")
116563d1a8abSmrg		    (match_operand:VHSI 2 "spu_reg_operand" "r,r")))]
116663d1a8abSmrg  ""
116763d1a8abSmrg  "@
116863d1a8abSmrg  sf<bh>\t%0,%2,%1
116963d1a8abSmrg  sf<bh>i\t%0,%2,%1")
117063d1a8abSmrg
117163d1a8abSmrg(define_expand "sub<mode>3"
117263d1a8abSmrg  [(set (match_dup:VDI 3)
117363d1a8abSmrg	(unspec:VDI [(match_operand:VDI 1 "spu_reg_operand" "")
117463d1a8abSmrg		     (match_operand:VDI 2 "spu_reg_operand" "")] UNSPEC_BG))
117563d1a8abSmrg   (set (match_dup:VDI 5)
117663d1a8abSmrg	(unspec:VDI [(match_dup 3)
117763d1a8abSmrg		     (match_dup 3)
117863d1a8abSmrg		     (match_dup:TI 4)] UNSPEC_SHUFB))
117963d1a8abSmrg   (set (match_operand:VDI 0 "spu_reg_operand" "")
118063d1a8abSmrg	(unspec:VDI [(match_dup 1)
118163d1a8abSmrg		     (match_dup 2)
118263d1a8abSmrg		     (match_dup 5)] UNSPEC_SFX))]
118363d1a8abSmrg  ""
118463d1a8abSmrg  {
118563d1a8abSmrg    unsigned char pat[16] = {
118663d1a8abSmrg      0x04, 0x05, 0x06, 0x07,
118763d1a8abSmrg      0xc0, 0xc0, 0xc0, 0xc0,
118863d1a8abSmrg      0x0c, 0x0d, 0x0e, 0x0f,
118963d1a8abSmrg      0xc0, 0xc0, 0xc0, 0xc0
119063d1a8abSmrg    };
119163d1a8abSmrg    operands[3] = gen_reg_rtx (<MODE>mode);
119263d1a8abSmrg    operands[4] = gen_reg_rtx (TImode);
119363d1a8abSmrg    operands[5] = gen_reg_rtx (<MODE>mode);
119463d1a8abSmrg    emit_move_insn (operands[4], array_to_constant (TImode, pat));
119563d1a8abSmrg  })
119663d1a8abSmrg
119763d1a8abSmrg(define_insn "bg_<mode>"
119863d1a8abSmrg  [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
119963d1a8abSmrg	(unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
120063d1a8abSmrg		      (match_operand 2 "spu_reg_operand" "r")] UNSPEC_BG))]
120163d1a8abSmrg  "operands != NULL"
120263d1a8abSmrg  "bg\t%0,%2,%1")
120363d1a8abSmrg
120463d1a8abSmrg(define_insn "bgx_<mode>"
120563d1a8abSmrg  [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
120663d1a8abSmrg	(unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
120763d1a8abSmrg		      (match_operand 2 "spu_reg_operand" "r")
120863d1a8abSmrg		      (match_operand 3 "spu_reg_operand" "0")] UNSPEC_BGX))]
120963d1a8abSmrg  "operands != NULL"
121063d1a8abSmrg  "bgx\t%0,%2,%1")
121163d1a8abSmrg
121263d1a8abSmrg(define_insn "sfx_<mode>"
121363d1a8abSmrg  [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
121463d1a8abSmrg	(unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
121563d1a8abSmrg		      (match_operand 2 "spu_reg_operand" "r")
121663d1a8abSmrg		      (match_operand 3 "spu_reg_operand" "0")] UNSPEC_SFX))]
121763d1a8abSmrg  "operands != NULL"
121863d1a8abSmrg  "sfx\t%0,%2,%1")
121963d1a8abSmrg
122063d1a8abSmrg(define_insn "subti3"
122163d1a8abSmrg  [(set (match_operand:TI 0 "spu_reg_operand" "=r")
122263d1a8abSmrg	(minus:TI (match_operand:TI 1 "spu_reg_operand" "r")
122363d1a8abSmrg		  (match_operand:TI 2 "spu_reg_operand" "r")))
122463d1a8abSmrg   (clobber (match_scratch:TI 3 "=&r"))
122563d1a8abSmrg   (clobber (match_scratch:TI 4 "=&r"))
122663d1a8abSmrg   (clobber (match_scratch:TI 5 "=&r"))
122763d1a8abSmrg   (clobber (match_scratch:TI 6 "=&r"))]
122863d1a8abSmrg  ""
122963d1a8abSmrg  "il\t%6,1\n\\
123063d1a8abSmrg   bg\t%3,%2,%1\n\\
123163d1a8abSmrg   xor\t%3,%3,%6\n\\
123263d1a8abSmrg   sf\t%4,%2,%1\n\\
123363d1a8abSmrg   shlqbyi\t%5,%3,4\n\\
123463d1a8abSmrg   bg\t%3,%5,%4\n\\
123563d1a8abSmrg   xor\t%3,%3,%6\n\\
123663d1a8abSmrg   sf\t%4,%5,%4\n\\
123763d1a8abSmrg   shlqbyi\t%5,%3,4\n\\
123863d1a8abSmrg   bg\t%3,%5,%4\n\\
123963d1a8abSmrg   xor\t%3,%3,%6\n\\
124063d1a8abSmrg   sf\t%4,%5,%4\n\\
124163d1a8abSmrg   shlqbyi\t%5,%3,4\n\\
124263d1a8abSmrg   sf\t%0,%5,%4"
124363d1a8abSmrg  [(set_attr "type" "multi0")
124463d1a8abSmrg   (set_attr "length" "56")])
124563d1a8abSmrg
124663d1a8abSmrg(define_insn "sub<mode>3"
124763d1a8abSmrg  [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
124863d1a8abSmrg	(minus:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
124963d1a8abSmrg		   (match_operand:VSF 2 "spu_reg_operand" "r")))]
125063d1a8abSmrg  ""
125163d1a8abSmrg  "fs\t%0,%1,%2"
125263d1a8abSmrg  [(set_attr "type" "fp6")])
125363d1a8abSmrg
125463d1a8abSmrg(define_insn "sub<mode>3"
125563d1a8abSmrg  [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
125663d1a8abSmrg	(minus:VDF (match_operand:VDF 1 "spu_reg_operand" "r")
125763d1a8abSmrg		   (match_operand:VDF 2 "spu_reg_operand" "r")))]
125863d1a8abSmrg  ""
125963d1a8abSmrg  "dfs\t%0,%1,%2"
126063d1a8abSmrg  [(set_attr "type" "fpd")])
126163d1a8abSmrg
126263d1a8abSmrg
126363d1a8abSmrg;; neg
126463d1a8abSmrg
126563d1a8abSmrg(define_expand "negv16qi2"
126663d1a8abSmrg  [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
126763d1a8abSmrg	(neg:V16QI (match_operand:V16QI 1 "spu_reg_operand" "r")))]
126863d1a8abSmrg  ""
126963d1a8abSmrg  "{
127063d1a8abSmrg    rtx zero = gen_reg_rtx (V16QImode);
127163d1a8abSmrg    emit_move_insn (zero, CONST0_RTX (V16QImode));
127263d1a8abSmrg    emit_insn (gen_subv16qi3 (operands[0], zero, operands[1]));
127363d1a8abSmrg    DONE;
127463d1a8abSmrg   }")
127563d1a8abSmrg
127663d1a8abSmrg(define_insn "neg<mode>2"
127763d1a8abSmrg  [(set (match_operand:VHSI 0 "spu_reg_operand" "=r")
127863d1a8abSmrg	(neg:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r")))]
127963d1a8abSmrg  ""
128063d1a8abSmrg  "sf<bh>i\t%0,%1,0")
128163d1a8abSmrg
128263d1a8abSmrg(define_expand "negdi2"
128363d1a8abSmrg  [(set (match_operand:DI 0 "spu_reg_operand" "")
128463d1a8abSmrg	(neg:DI (match_operand:DI 1 "spu_reg_operand" "")))]
128563d1a8abSmrg  ""
128663d1a8abSmrg  {
128763d1a8abSmrg    rtx zero = gen_reg_rtx(DImode);
128863d1a8abSmrg    emit_move_insn(zero, GEN_INT(0));
128963d1a8abSmrg    emit_insn (gen_subdi3(operands[0], zero, operands[1]));
129063d1a8abSmrg    DONE;
129163d1a8abSmrg  })
129263d1a8abSmrg
129363d1a8abSmrg(define_expand "negti2"
129463d1a8abSmrg  [(set (match_operand:TI 0 "spu_reg_operand" "")
129563d1a8abSmrg	(neg:TI (match_operand:TI 1 "spu_reg_operand" "")))]
129663d1a8abSmrg  ""
129763d1a8abSmrg  {
129863d1a8abSmrg    rtx zero = gen_reg_rtx(TImode);
129963d1a8abSmrg    emit_move_insn(zero, GEN_INT(0));
130063d1a8abSmrg    emit_insn (gen_subti3(operands[0], zero, operands[1]));
130163d1a8abSmrg    DONE;
130263d1a8abSmrg  })
130363d1a8abSmrg
130463d1a8abSmrg(define_expand "neg<mode>2"
130563d1a8abSmrg  [(parallel
130663d1a8abSmrg    [(set (match_operand:VSF 0 "spu_reg_operand" "")
130763d1a8abSmrg	  (neg:VSF (match_operand:VSF 1 "spu_reg_operand" "")))
130863d1a8abSmrg     (use (match_dup 2))])]
130963d1a8abSmrg  ""
131063d1a8abSmrg  "operands[2] = gen_reg_rtx (<F2I>mode);
131163d1a8abSmrg   emit_move_insn (operands[2], spu_const (<F2I>mode, -0x80000000ull));")
131263d1a8abSmrg
131363d1a8abSmrg(define_expand "neg<mode>2"
131463d1a8abSmrg  [(parallel
131563d1a8abSmrg    [(set (match_operand:VDF 0 "spu_reg_operand" "")
131663d1a8abSmrg	  (neg:VDF (match_operand:VDF 1 "spu_reg_operand" "")))
131763d1a8abSmrg     (use (match_dup 2))])]
131863d1a8abSmrg  ""
131963d1a8abSmrg  "operands[2] = gen_reg_rtx (<F2I>mode);
132063d1a8abSmrg   emit_move_insn (operands[2], spu_const (<F2I>mode, -0x8000000000000000ull));")
132163d1a8abSmrg
132263d1a8abSmrg(define_insn_and_split "_neg<mode>2"
132363d1a8abSmrg  [(set (match_operand:VSDF 0 "spu_reg_operand" "=r")
132463d1a8abSmrg	(neg:VSDF (match_operand:VSDF 1 "spu_reg_operand" "r")))
132563d1a8abSmrg   (use (match_operand:<F2I> 2 "spu_reg_operand" "r"))]
132663d1a8abSmrg  ""
132763d1a8abSmrg  "#"
132863d1a8abSmrg  ""
132963d1a8abSmrg  [(set (match_dup:<F2I> 3)
133063d1a8abSmrg	(xor:<F2I> (match_dup:<F2I> 4)
133163d1a8abSmrg		   (match_dup:<F2I> 2)))]
133263d1a8abSmrg  {
133363d1a8abSmrg    operands[3] = spu_gen_subreg (<F2I>mode, operands[0]);
133463d1a8abSmrg    operands[4] = spu_gen_subreg (<F2I>mode, operands[1]);
133563d1a8abSmrg  })
133663d1a8abSmrg
133763d1a8abSmrg
133863d1a8abSmrg;; abs
133963d1a8abSmrg
134063d1a8abSmrg(define_expand "abs<mode>2"
134163d1a8abSmrg  [(parallel
134263d1a8abSmrg    [(set (match_operand:VSF 0 "spu_reg_operand" "")
134363d1a8abSmrg	  (abs:VSF (match_operand:VSF 1 "spu_reg_operand" "")))
134463d1a8abSmrg     (use (match_dup 2))])]
134563d1a8abSmrg  ""
134663d1a8abSmrg  "operands[2] = gen_reg_rtx (<F2I>mode);
134763d1a8abSmrg   emit_move_insn (operands[2], spu_const (<F2I>mode, 0x7fffffffull));")
134863d1a8abSmrg
134963d1a8abSmrg(define_expand "abs<mode>2"
135063d1a8abSmrg  [(parallel
135163d1a8abSmrg    [(set (match_operand:VDF 0 "spu_reg_operand" "")
135263d1a8abSmrg	  (abs:VDF (match_operand:VDF 1 "spu_reg_operand" "")))
135363d1a8abSmrg     (use (match_dup 2))])]
135463d1a8abSmrg  ""
135563d1a8abSmrg  "operands[2] = gen_reg_rtx (<F2I>mode);
135663d1a8abSmrg   emit_move_insn (operands[2], spu_const (<F2I>mode, 0x7fffffffffffffffull));")
135763d1a8abSmrg
135863d1a8abSmrg(define_insn_and_split "_abs<mode>2"
135963d1a8abSmrg  [(set (match_operand:VSDF 0 "spu_reg_operand" "=r")
136063d1a8abSmrg	(abs:VSDF (match_operand:VSDF 1 "spu_reg_operand" "r")))
136163d1a8abSmrg   (use (match_operand:<F2I> 2 "spu_reg_operand" "r"))]
136263d1a8abSmrg  ""
136363d1a8abSmrg  "#"
136463d1a8abSmrg  ""
136563d1a8abSmrg  [(set (match_dup:<F2I> 3)
136663d1a8abSmrg	(and:<F2I> (match_dup:<F2I> 4)
136763d1a8abSmrg		   (match_dup:<F2I> 2)))]
136863d1a8abSmrg  {
136963d1a8abSmrg    operands[3] = spu_gen_subreg (<F2I>mode, operands[0]);
137063d1a8abSmrg    operands[4] = spu_gen_subreg (<F2I>mode, operands[1]);
137163d1a8abSmrg  })
137263d1a8abSmrg
137363d1a8abSmrg
137463d1a8abSmrg;; mul
137563d1a8abSmrg
137663d1a8abSmrg(define_insn "mulhi3"
137763d1a8abSmrg  [(set (match_operand:HI 0 "spu_reg_operand" "=r,r")
137863d1a8abSmrg	(mult:HI (match_operand:HI 1 "spu_reg_operand" "r,r")
137963d1a8abSmrg		 (match_operand:HI 2 "spu_arith_operand" "r,B")))]
138063d1a8abSmrg  ""
138163d1a8abSmrg  "@
138263d1a8abSmrg  mpy\t%0,%1,%2
138363d1a8abSmrg  mpyi\t%0,%1,%2"
138463d1a8abSmrg  [(set_attr "type" "fp7")])
138563d1a8abSmrg
138663d1a8abSmrg(define_expand "mulv8hi3"
138763d1a8abSmrg  [(set (match_operand:V8HI 0 "spu_reg_operand" "")
138863d1a8abSmrg	(mult:V8HI (match_operand:V8HI 1 "spu_reg_operand" "")
138963d1a8abSmrg		   (match_operand:V8HI 2 "spu_reg_operand" "")))]
139063d1a8abSmrg  ""
139163d1a8abSmrg  "{
139263d1a8abSmrg    rtx result = simplify_gen_subreg (V4SImode, operands[0], V8HImode, 0);
139363d1a8abSmrg    rtx low = gen_reg_rtx (V4SImode);
139463d1a8abSmrg    rtx high = gen_reg_rtx (V4SImode);
139563d1a8abSmrg    rtx shift = gen_reg_rtx (V4SImode);
139663d1a8abSmrg    rtx mask = gen_reg_rtx (V4SImode);
139763d1a8abSmrg
139863d1a8abSmrg    emit_move_insn (mask, spu_const (V4SImode, 0x0000ffff));
139963d1a8abSmrg    emit_insn (gen_vec_widen_smult_even_v8hi (high, operands[1], operands[2]));
140063d1a8abSmrg    emit_insn (gen_vec_widen_smult_odd_v8hi (low, operands[1], operands[2]));
140163d1a8abSmrg    emit_insn (gen_vashlv4si3 (shift, high, spu_const(V4SImode, 16)));
140263d1a8abSmrg    emit_insn (gen_selb (result, shift, low, mask));
140363d1a8abSmrg    DONE;
140463d1a8abSmrg   }")
140563d1a8abSmrg
140663d1a8abSmrg(define_expand "mul<mode>3"
140763d1a8abSmrg  [(parallel
140863d1a8abSmrg    [(set (match_operand:VSI 0 "spu_reg_operand" "")
140963d1a8abSmrg	  (mult:VSI (match_operand:VSI 1 "spu_reg_operand" "")
141063d1a8abSmrg		    (match_operand:VSI 2 "spu_reg_operand" "")))
141163d1a8abSmrg     (clobber (match_dup:VSI 3))
141263d1a8abSmrg     (clobber (match_dup:VSI 4))
141363d1a8abSmrg     (clobber (match_dup:VSI 5))
141463d1a8abSmrg     (clobber (match_dup:VSI 6))])]
141563d1a8abSmrg  ""
141663d1a8abSmrg  {
141763d1a8abSmrg    operands[3] = gen_reg_rtx(<MODE>mode);
141863d1a8abSmrg    operands[4] = gen_reg_rtx(<MODE>mode);
141963d1a8abSmrg    operands[5] = gen_reg_rtx(<MODE>mode);
142063d1a8abSmrg    operands[6] = gen_reg_rtx(<MODE>mode);
142163d1a8abSmrg  })
142263d1a8abSmrg
142363d1a8abSmrg(define_insn_and_split "_mulsi3"
142463d1a8abSmrg  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
142563d1a8abSmrg	(mult:SI (match_operand:SI 1 "spu_reg_operand" "r")
142663d1a8abSmrg		 (match_operand:SI 2 "spu_arith_operand" "rK")))
142763d1a8abSmrg   (clobber (match_operand:SI 3 "spu_reg_operand" "=&r"))
142863d1a8abSmrg   (clobber (match_operand:SI 4 "spu_reg_operand" "=&r"))
142963d1a8abSmrg   (clobber (match_operand:SI 5 "spu_reg_operand" "=&r"))
143063d1a8abSmrg   (clobber (match_operand:SI 6 "spu_reg_operand" "=&r"))]
143163d1a8abSmrg  ""
143263d1a8abSmrg  "#"
143363d1a8abSmrg  ""
143463d1a8abSmrg  [(set (match_dup:SI 0)
143563d1a8abSmrg	(mult:SI (match_dup:SI 1)
143663d1a8abSmrg		 (match_dup:SI 2)))]
143763d1a8abSmrg  {
143863d1a8abSmrg    HOST_WIDE_INT val = 0;
143963d1a8abSmrg    rtx a = operands[3];
144063d1a8abSmrg    rtx b = operands[4];
144163d1a8abSmrg    rtx c = operands[5];
144263d1a8abSmrg    rtx d = operands[6];
144363d1a8abSmrg    if (GET_CODE(operands[2]) == CONST_INT)
144463d1a8abSmrg      {
144563d1a8abSmrg	val = INTVAL(operands[2]);
144663d1a8abSmrg	emit_move_insn(d, operands[2]);
144763d1a8abSmrg	operands[2] = d;
144863d1a8abSmrg      }
144963d1a8abSmrg    if (val && (val & 0xffff) == 0)
145063d1a8abSmrg      {
145163d1a8abSmrg	emit_insn (gen_mpyh_si(operands[0], operands[2], operands[1]));
145263d1a8abSmrg      }
145363d1a8abSmrg    else if (val > 0 && val < 0x10000)
145463d1a8abSmrg      {
145563d1a8abSmrg	rtx cst = satisfies_constraint_K (GEN_INT (val)) ? GEN_INT(val) : d;
145663d1a8abSmrg	emit_insn (gen_mpyh_si(a, operands[1], operands[2]));
145763d1a8abSmrg	emit_insn (gen_mpyu_si(c, operands[1], cst));
145863d1a8abSmrg	emit_insn (gen_addsi3(operands[0], a, c));
145963d1a8abSmrg      }
146063d1a8abSmrg    else
146163d1a8abSmrg      {
146263d1a8abSmrg	emit_insn (gen_mpyh_si(a, operands[1], operands[2]));
146363d1a8abSmrg	emit_insn (gen_mpyh_si(b, operands[2], operands[1]));
146463d1a8abSmrg	emit_insn (gen_mpyu_si(c, operands[1], operands[2]));
146563d1a8abSmrg	emit_insn (gen_addsi3(d, a, b));
146663d1a8abSmrg	emit_insn (gen_addsi3(operands[0], d, c));
146763d1a8abSmrg      }
146863d1a8abSmrg    DONE;
146963d1a8abSmrg   })
147063d1a8abSmrg
147163d1a8abSmrg(define_insn_and_split "_mulv4si3"
147263d1a8abSmrg  [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
147363d1a8abSmrg	(mult:V4SI (match_operand:V4SI 1 "spu_reg_operand" "r")
147463d1a8abSmrg		   (match_operand:V4SI 2 "spu_reg_operand" "r")))
147563d1a8abSmrg   (clobber (match_operand:V4SI 3 "spu_reg_operand" "=&r"))
147663d1a8abSmrg   (clobber (match_operand:V4SI 4 "spu_reg_operand" "=&r"))
147763d1a8abSmrg   (clobber (match_operand:V4SI 5 "spu_reg_operand" "=&r"))
147863d1a8abSmrg   (clobber (match_operand:V4SI 6 "spu_reg_operand" "=&r"))]
147963d1a8abSmrg  ""
148063d1a8abSmrg  "#"
148163d1a8abSmrg  ""
148263d1a8abSmrg  [(set (match_dup:V4SI 0)
148363d1a8abSmrg	(mult:V4SI (match_dup:V4SI 1)
148463d1a8abSmrg		   (match_dup:V4SI 2)))]
148563d1a8abSmrg  {
148663d1a8abSmrg    rtx a = operands[3];
148763d1a8abSmrg    rtx b = operands[4];
148863d1a8abSmrg    rtx c = operands[5];
148963d1a8abSmrg    rtx d = operands[6];
149063d1a8abSmrg    rtx op1 = simplify_gen_subreg (V8HImode, operands[1], V4SImode, 0);
149163d1a8abSmrg    rtx op2 = simplify_gen_subreg (V8HImode, operands[2], V4SImode, 0);
149263d1a8abSmrg    emit_insn (gen_spu_mpyh(a, op1, op2));
149363d1a8abSmrg    emit_insn (gen_spu_mpyh(b, op2, op1));
149463d1a8abSmrg    emit_insn (gen_vec_widen_umult_odd_v8hi (c, op1, op2));
149563d1a8abSmrg    emit_insn (gen_addv4si3(d, a, b));
149663d1a8abSmrg    emit_insn (gen_addv4si3(operands[0], d, c));
149763d1a8abSmrg    DONE;
149863d1a8abSmrg   })
149963d1a8abSmrg
150063d1a8abSmrg(define_insn "mulhisi3"
150163d1a8abSmrg  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
150263d1a8abSmrg	(mult:SI (sign_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
150363d1a8abSmrg		 (sign_extend:SI (match_operand:HI 2 "spu_reg_operand" "r"))))]
150463d1a8abSmrg  ""
150563d1a8abSmrg  "mpy\t%0,%1,%2"
150663d1a8abSmrg  [(set_attr "type" "fp7")])
150763d1a8abSmrg
150863d1a8abSmrg(define_insn "mulhisi3_imm"
150963d1a8abSmrg  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
151063d1a8abSmrg	(mult:SI (sign_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
151163d1a8abSmrg		 (match_operand:SI 2 "imm_K_operand" "K")))]
151263d1a8abSmrg  ""
151363d1a8abSmrg  "mpyi\t%0,%1,%2"
151463d1a8abSmrg  [(set_attr "type" "fp7")])
151563d1a8abSmrg
151663d1a8abSmrg(define_insn "umulhisi3"
151763d1a8abSmrg  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
151863d1a8abSmrg	(mult:SI (zero_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
151963d1a8abSmrg		 (zero_extend:SI (match_operand:HI 2 "spu_reg_operand" "r"))))]
152063d1a8abSmrg  ""
152163d1a8abSmrg  "mpyu\t%0,%1,%2"
152263d1a8abSmrg  [(set_attr "type" "fp7")])
152363d1a8abSmrg
152463d1a8abSmrg(define_insn "umulhisi3_imm"
152563d1a8abSmrg  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
152663d1a8abSmrg	(mult:SI (zero_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
152763d1a8abSmrg		 (and:SI (match_operand:SI 2 "imm_K_operand" "K") (const_int 65535))))]
152863d1a8abSmrg  ""
152963d1a8abSmrg  "mpyui\t%0,%1,%2"
153063d1a8abSmrg  [(set_attr "type" "fp7")])
153163d1a8abSmrg
153263d1a8abSmrg(define_insn "mpyu_si"
153363d1a8abSmrg  [(set (match_operand:SI 0 "spu_reg_operand" "=r,r")
153463d1a8abSmrg	(mult:SI (and:SI (match_operand:SI 1 "spu_reg_operand" "r,r")
153563d1a8abSmrg			 (const_int 65535))
153663d1a8abSmrg		 (and:SI (match_operand:SI 2 "spu_arith_operand" "r,K")
153763d1a8abSmrg			 (const_int 65535))))]
153863d1a8abSmrg  ""
153963d1a8abSmrg  "@
154063d1a8abSmrg   mpyu\t%0,%1,%2
154163d1a8abSmrg   mpyui\t%0,%1,%2"
154263d1a8abSmrg  [(set_attr "type" "fp7")])
154363d1a8abSmrg
154463d1a8abSmrg;; This isn't always profitable to use.  Consider r = a * b + c * d.
154563d1a8abSmrg;; It's faster to do the multiplies in parallel then add them.  If we
154663d1a8abSmrg;; merge a multiply and add it prevents the multiplies from happening in
154763d1a8abSmrg;; parallel.
154863d1a8abSmrg(define_insn "mpya_si"
154963d1a8abSmrg  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
155063d1a8abSmrg	(plus:SI (mult:SI (sign_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
155163d1a8abSmrg			  (sign_extend:SI (match_operand:HI 2 "spu_reg_operand" "r")))
155263d1a8abSmrg		 (match_operand:SI 3 "spu_reg_operand" "r")))]
155363d1a8abSmrg  "0"
155463d1a8abSmrg  "mpya\t%0,%1,%2,%3"
155563d1a8abSmrg  [(set_attr "type" "fp7")])
155663d1a8abSmrg
155763d1a8abSmrg(define_insn "mpyh_si"
155863d1a8abSmrg  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
155963d1a8abSmrg	(mult:SI (and:SI (match_operand:SI 1 "spu_reg_operand" "r")
156063d1a8abSmrg			 (const_int -65536))
156163d1a8abSmrg	         (and:SI (match_operand:SI 2 "spu_reg_operand" "r")
156263d1a8abSmrg			 (const_int 65535))))]
156363d1a8abSmrg  ""
156463d1a8abSmrg  "mpyh\t%0,%1,%2"
156563d1a8abSmrg  [(set_attr "type" "fp7")])
156663d1a8abSmrg
156763d1a8abSmrg(define_insn "mpys_si"
156863d1a8abSmrg  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
156963d1a8abSmrg	(ashiftrt:SI
157063d1a8abSmrg	    (mult:SI (sign_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
157163d1a8abSmrg		     (sign_extend:SI (match_operand:HI 2 "spu_reg_operand" "r")))
157263d1a8abSmrg	    (const_int 16)))]
157363d1a8abSmrg  ""
157463d1a8abSmrg  "mpys\t%0,%1,%2"
157563d1a8abSmrg  [(set_attr "type" "fp7")])
157663d1a8abSmrg
157763d1a8abSmrg(define_insn "mpyhh_si"
157863d1a8abSmrg  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
157963d1a8abSmrg	(mult:SI (ashiftrt:SI (match_operand:SI 1 "spu_reg_operand" "r")
158063d1a8abSmrg			      (const_int 16))
158163d1a8abSmrg		 (ashiftrt:SI (match_operand:SI 2 "spu_reg_operand" "r")
158263d1a8abSmrg			      (const_int 16))))]
158363d1a8abSmrg  ""
158463d1a8abSmrg  "mpyhh\t%0,%1,%2"
158563d1a8abSmrg  [(set_attr "type" "fp7")])
158663d1a8abSmrg
158763d1a8abSmrg(define_insn "mpyhhu_si"
158863d1a8abSmrg  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
158963d1a8abSmrg	(mult:SI (lshiftrt:SI (match_operand:SI 1 "spu_reg_operand" "r")
159063d1a8abSmrg			      (const_int 16))
159163d1a8abSmrg		 (lshiftrt:SI (match_operand:SI 2 "spu_reg_operand" "r")
159263d1a8abSmrg			      (const_int 16))))]
159363d1a8abSmrg  ""
159463d1a8abSmrg  "mpyhhu\t%0,%1,%2"
159563d1a8abSmrg  [(set_attr "type" "fp7")])
159663d1a8abSmrg
159763d1a8abSmrg(define_insn "mpyhha_si"
159863d1a8abSmrg  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
159963d1a8abSmrg	(plus:SI (mult:SI (ashiftrt:SI (match_operand:SI 1 "spu_reg_operand" "r")
160063d1a8abSmrg				       (const_int 16))
160163d1a8abSmrg			  (ashiftrt:SI (match_operand:SI 2 "spu_reg_operand" "r")
160263d1a8abSmrg				       (const_int 16)))
160363d1a8abSmrg		 (match_operand:SI 3 "spu_reg_operand" "0")))]
160463d1a8abSmrg  "0"
160563d1a8abSmrg  "mpyhha\t%0,%1,%2"
160663d1a8abSmrg  [(set_attr "type" "fp7")])
160763d1a8abSmrg
160863d1a8abSmrg(define_insn "mul<mode>3"
160963d1a8abSmrg  [(set (match_operand:VSDF 0 "spu_reg_operand" "=r")
161063d1a8abSmrg	(mult:VSDF (match_operand:VSDF 1 "spu_reg_operand" "r")
161163d1a8abSmrg		   (match_operand:VSDF 2 "spu_reg_operand" "r")))]
161263d1a8abSmrg  ""
161363d1a8abSmrg  "<d>fm\t%0,%1,%2"
161463d1a8abSmrg  [(set_attr "type" "fp<d6>")])
161563d1a8abSmrg
161663d1a8abSmrg(define_insn "fma<mode>4"
161763d1a8abSmrg  [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
161863d1a8abSmrg	(fma:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
161963d1a8abSmrg		 (match_operand:VSF 2 "spu_reg_operand" "r")
162063d1a8abSmrg		 (match_operand:VSF 3 "spu_reg_operand" "r")))]
162163d1a8abSmrg  ""
162263d1a8abSmrg  "fma\t%0,%1,%2,%3"
162363d1a8abSmrg  [(set_attr "type"	"fp6")])
162463d1a8abSmrg
162563d1a8abSmrg;; ??? The official description is (c - a*b), which is exactly (-a*b + c).
162663d1a8abSmrg;; Note that this doesn't match the dfnms description.  Incorrect?
162763d1a8abSmrg(define_insn "fnma<mode>4"
162863d1a8abSmrg  [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
162963d1a8abSmrg	(fma:VSF
163063d1a8abSmrg	  (neg:VSF (match_operand:VSF 1 "spu_reg_operand" "r"))
163163d1a8abSmrg	  (match_operand:VSF 2 "spu_reg_operand" "r")
163263d1a8abSmrg	  (match_operand:VSF 3 "spu_reg_operand" "r")))]
163363d1a8abSmrg  ""
163463d1a8abSmrg  "fnms\t%0,%1,%2,%3"
163563d1a8abSmrg  [(set_attr "type" "fp6")])
163663d1a8abSmrg
163763d1a8abSmrg(define_insn "fms<mode>4"
163863d1a8abSmrg  [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
163963d1a8abSmrg	(fma:VSF
164063d1a8abSmrg	  (match_operand:VSF 1 "spu_reg_operand" "r")
164163d1a8abSmrg	  (match_operand:VSF 2 "spu_reg_operand" "r")
164263d1a8abSmrg	  (neg:VSF (match_operand:VSF 3 "spu_reg_operand" "r"))))]
164363d1a8abSmrg  ""
164463d1a8abSmrg  "fms\t%0,%1,%2,%3"
164563d1a8abSmrg  [(set_attr "type" "fp6")])
164663d1a8abSmrg
164763d1a8abSmrg(define_insn "fma<mode>4"
164863d1a8abSmrg  [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
164963d1a8abSmrg	(fma:VDF (match_operand:VDF 1 "spu_reg_operand" "r")
165063d1a8abSmrg		 (match_operand:VDF 2 "spu_reg_operand" "r")
165163d1a8abSmrg		 (match_operand:VDF 3 "spu_reg_operand" "0")))]
165263d1a8abSmrg  ""
165363d1a8abSmrg  "dfma\t%0,%1,%2"
165463d1a8abSmrg  [(set_attr "type"	"fpd")])
165563d1a8abSmrg
165663d1a8abSmrg(define_insn "fms<mode>4"
165763d1a8abSmrg  [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
165863d1a8abSmrg	(fma:VDF
165963d1a8abSmrg	  (match_operand:VDF 1 "spu_reg_operand" "r")
166063d1a8abSmrg	  (match_operand:VDF 2 "spu_reg_operand" "r")
166163d1a8abSmrg	  (neg:VDF (match_operand:VDF 3 "spu_reg_operand" "0"))))]
166263d1a8abSmrg  ""
166363d1a8abSmrg  "dfms\t%0,%1,%2"
166463d1a8abSmrg  [(set_attr "type" "fpd")])
166563d1a8abSmrg
166663d1a8abSmrg(define_insn "nfma<mode>4"
166763d1a8abSmrg  [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
166863d1a8abSmrg	(neg:VDF
166963d1a8abSmrg	  (fma:VDF (match_operand:VDF 1 "spu_reg_operand" "r")
167063d1a8abSmrg		   (match_operand:VDF 2 "spu_reg_operand" "r")
167163d1a8abSmrg		   (match_operand:VDF 3 "spu_reg_operand" "0"))))]
167263d1a8abSmrg  ""
167363d1a8abSmrg  "dfnma\t%0,%1,%2"
167463d1a8abSmrg  [(set_attr "type"	"fpd")])
167563d1a8abSmrg
167663d1a8abSmrg(define_insn "nfms<mode>4"
167763d1a8abSmrg  [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
167863d1a8abSmrg	(neg:VDF
167963d1a8abSmrg	  (fma:VDF
168063d1a8abSmrg	    (match_operand:VDF 1 "spu_reg_operand" "r")
168163d1a8abSmrg	    (match_operand:VDF 2 "spu_reg_operand" "r")
168263d1a8abSmrg	    (neg:VDF (match_operand:VDF 3 "spu_reg_operand" "0")))))]
168363d1a8abSmrg  ""
168463d1a8abSmrg  "dfnms\t%0,%1,%2"
168563d1a8abSmrg  [(set_attr "type" "fpd")])
168663d1a8abSmrg
168763d1a8abSmrg;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
168863d1a8abSmrg(define_expand "fnma<mode>4"
168963d1a8abSmrg  [(set (match_operand:VDF 0 "spu_reg_operand" "")
169063d1a8abSmrg	(neg:VDF
169163d1a8abSmrg	  (fma:VDF
169263d1a8abSmrg	    (match_operand:VDF 1 "spu_reg_operand" "")
169363d1a8abSmrg	    (match_operand:VDF 2 "spu_reg_operand" "")
169463d1a8abSmrg	    (neg:VDF (match_operand:VDF 3 "spu_reg_operand" "")))))]
169563d1a8abSmrg  "!HONOR_SIGNED_ZEROS (<MODE>mode)"
169663d1a8abSmrg  "")
169763d1a8abSmrg
169863d1a8abSmrg;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
169963d1a8abSmrg(define_expand "fnms<mode>4"
170063d1a8abSmrg  [(set (match_operand:VDF 0 "register_operand" "")
170163d1a8abSmrg	(neg:VDF
170263d1a8abSmrg	  (fma:VDF
170363d1a8abSmrg	    (match_operand:VDF 1 "register_operand" "")
170463d1a8abSmrg	    (match_operand:VDF 2 "register_operand" "")
170563d1a8abSmrg	    (match_operand:VDF 3 "register_operand" ""))))]
170663d1a8abSmrg  "!HONOR_SIGNED_ZEROS (<MODE>mode)"
170763d1a8abSmrg  "")
170863d1a8abSmrg
170963d1a8abSmrg;; mul highpart, used for divide by constant optimizations.
171063d1a8abSmrg
171163d1a8abSmrg(define_expand "smulsi3_highpart"
171263d1a8abSmrg  [(set (match_operand:SI 0 "register_operand" "")
171363d1a8abSmrg	(truncate:SI
171463d1a8abSmrg	  (ashiftrt:DI
171563d1a8abSmrg	    (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
171663d1a8abSmrg	             (sign_extend:DI (match_operand:SI 2 "register_operand" "")))
171763d1a8abSmrg	    (const_int 32))))]
171863d1a8abSmrg  ""
171963d1a8abSmrg  {
172063d1a8abSmrg    rtx t0 = gen_reg_rtx (SImode);
172163d1a8abSmrg    rtx t1 = gen_reg_rtx (SImode);
172263d1a8abSmrg    rtx t2 = gen_reg_rtx (SImode);
172363d1a8abSmrg    rtx t3 = gen_reg_rtx (SImode);
172463d1a8abSmrg    rtx t4 = gen_reg_rtx (SImode);
172563d1a8abSmrg    rtx t5 = gen_reg_rtx (SImode);
172663d1a8abSmrg    rtx t6 = gen_reg_rtx (SImode);
172763d1a8abSmrg    rtx t7 = gen_reg_rtx (SImode);
172863d1a8abSmrg    rtx t8 = gen_reg_rtx (SImode);
172963d1a8abSmrg    rtx t9 = gen_reg_rtx (SImode);
173063d1a8abSmrg    rtx t11 = gen_reg_rtx (SImode);
173163d1a8abSmrg    rtx t12 = gen_reg_rtx (SImode);
173263d1a8abSmrg    rtx t14 = gen_reg_rtx (SImode);
173363d1a8abSmrg    rtx t15 = gen_reg_rtx (HImode);
173463d1a8abSmrg    rtx t16 = gen_reg_rtx (HImode);
173563d1a8abSmrg    rtx t17 = gen_reg_rtx (HImode);
173663d1a8abSmrg    rtx t18 = gen_reg_rtx (HImode);
173763d1a8abSmrg    rtx t19 = gen_reg_rtx (SImode);
173863d1a8abSmrg    rtx t20 = gen_reg_rtx (SImode);
173963d1a8abSmrg    rtx t21 = gen_reg_rtx (SImode);
174063d1a8abSmrg    rtx op1_hi = gen_rtx_SUBREG (HImode, operands[1], 2);
174163d1a8abSmrg    rtx op2_hi = gen_rtx_SUBREG (HImode, operands[2], 2);
174263d1a8abSmrg    rtx t0_hi = gen_rtx_SUBREG (HImode, t0, 2);
174363d1a8abSmrg    rtx t1_hi = gen_rtx_SUBREG (HImode, t1, 2);
174463d1a8abSmrg
174563d1a8abSmrg    rtx_insn *insn = emit_insn (gen_lshrsi3 (t0, operands[1], GEN_INT (16)));
174663d1a8abSmrg    emit_insn (gen_lshrsi3 (t1, operands[2], GEN_INT (16)));
174763d1a8abSmrg    emit_insn (gen_umulhisi3 (t2, op1_hi, op2_hi));
174863d1a8abSmrg    emit_insn (gen_mpyh_si (t3, operands[1], operands[2]));
174963d1a8abSmrg    emit_insn (gen_mpyh_si (t4, operands[2], operands[1]));
175063d1a8abSmrg    emit_insn (gen_mpyhh_si (t5, operands[1], operands[2]));
175163d1a8abSmrg    emit_insn (gen_mpys_si (t6, t0_hi, op2_hi));
175263d1a8abSmrg    emit_insn (gen_mpys_si (t7, t1_hi, op1_hi));
175363d1a8abSmrg
175463d1a8abSmrg    /* Gen carry bits (in t9 and t11). */
175563d1a8abSmrg    emit_insn (gen_addsi3 (t8, t2, t3));
175663d1a8abSmrg    emit_insn (gen_cg_si (t9, t2, t3));
175763d1a8abSmrg    emit_insn (gen_cg_si (t11, t8, t4));
175863d1a8abSmrg
175963d1a8abSmrg    /* Gen high 32 bits in operand[0].  Correct for mpys. */
176063d1a8abSmrg    emit_insn (gen_addx_si (t12, t5, t6, t9));
176163d1a8abSmrg    emit_insn (gen_addx_si (t14, t12, t7, t11));
176263d1a8abSmrg
176363d1a8abSmrg    /* mpys treats both operands as signed when we really want it to treat
176463d1a8abSmrg       the first operand as signed and the second operand as unsigned.
176563d1a8abSmrg       The code below corrects for that difference.  */
176663d1a8abSmrg    emit_insn (gen_cgt_hi (t15, op1_hi, GEN_INT (-1)));
176763d1a8abSmrg    emit_insn (gen_cgt_hi (t16, op2_hi, GEN_INT (-1)));
176863d1a8abSmrg    emit_insn (gen_andc_hi (t17, t1_hi, t15));
176963d1a8abSmrg    emit_insn (gen_andc_hi (t18, t0_hi, t16));
177063d1a8abSmrg    emit_insn (gen_extendhisi2 (t19, t17));
177163d1a8abSmrg    emit_insn (gen_extendhisi2 (t20, t18));
177263d1a8abSmrg    emit_insn (gen_addsi3 (t21, t19, t20));
177363d1a8abSmrg    emit_insn (gen_addsi3 (operands[0], t14, t21));
177463d1a8abSmrg    unshare_all_rtl_in_chain (insn);
177563d1a8abSmrg    DONE;
177663d1a8abSmrg  })
177763d1a8abSmrg
177863d1a8abSmrg(define_expand "umulsi3_highpart"
177963d1a8abSmrg  [(set (match_operand:SI 0 "register_operand" "")
178063d1a8abSmrg	(truncate:SI
178163d1a8abSmrg	  (ashiftrt:DI
178263d1a8abSmrg	    (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
178363d1a8abSmrg	             (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
178463d1a8abSmrg	    (const_int 32))))]
178563d1a8abSmrg  ""
178663d1a8abSmrg
178763d1a8abSmrg  {
178863d1a8abSmrg    rtx t0 = gen_reg_rtx (SImode);
178963d1a8abSmrg    rtx t1 = gen_reg_rtx (SImode);
179063d1a8abSmrg    rtx t2 = gen_reg_rtx (SImode);
179163d1a8abSmrg    rtx t3 = gen_reg_rtx (SImode);
179263d1a8abSmrg    rtx t4 = gen_reg_rtx (SImode);
179363d1a8abSmrg    rtx t5 = gen_reg_rtx (SImode);
179463d1a8abSmrg    rtx t6 = gen_reg_rtx (SImode);
179563d1a8abSmrg    rtx t7 = gen_reg_rtx (SImode);
179663d1a8abSmrg    rtx t8 = gen_reg_rtx (SImode);
179763d1a8abSmrg    rtx t9 = gen_reg_rtx (SImode);
179863d1a8abSmrg    rtx t10 = gen_reg_rtx (SImode);
179963d1a8abSmrg    rtx t12 = gen_reg_rtx (SImode);
180063d1a8abSmrg    rtx t13 = gen_reg_rtx (SImode);
180163d1a8abSmrg    rtx t14 = gen_reg_rtx (SImode);
180263d1a8abSmrg    rtx op1_hi = gen_rtx_SUBREG (HImode, operands[1], 2);
180363d1a8abSmrg    rtx op2_hi = gen_rtx_SUBREG (HImode, operands[2], 2);
180463d1a8abSmrg    rtx t0_hi = gen_rtx_SUBREG (HImode, t0, 2);
180563d1a8abSmrg
180663d1a8abSmrg    rtx_insn *insn = emit_insn (gen_rotlsi3 (t0, operands[2], GEN_INT (16)));
180763d1a8abSmrg    emit_insn (gen_umulhisi3 (t1, op1_hi, op2_hi));
180863d1a8abSmrg    emit_insn (gen_umulhisi3 (t2, op1_hi, t0_hi));
180963d1a8abSmrg    emit_insn (gen_mpyhhu_si (t3, operands[1], t0));
181063d1a8abSmrg    emit_insn (gen_mpyhhu_si (t4, operands[1], operands[2]));
181163d1a8abSmrg    emit_insn (gen_ashlsi3 (t5, t2, GEN_INT (16)));
181263d1a8abSmrg    emit_insn (gen_ashlsi3 (t6, t3, GEN_INT (16)));
181363d1a8abSmrg    emit_insn (gen_lshrsi3 (t7, t2, GEN_INT (16)));
181463d1a8abSmrg    emit_insn (gen_lshrsi3 (t8, t3, GEN_INT (16)));
181563d1a8abSmrg
181663d1a8abSmrg    /* Gen carry bits (in t10 and t12). */
181763d1a8abSmrg    emit_insn (gen_addsi3 (t9, t1, t5));
181863d1a8abSmrg    emit_insn (gen_cg_si (t10, t1, t5));
181963d1a8abSmrg    emit_insn (gen_cg_si (t12, t9, t6));
182063d1a8abSmrg
182163d1a8abSmrg    /* Gen high 32 bits in operand[0]. */
182263d1a8abSmrg    emit_insn (gen_addx_si (t13, t4, t7, t10));
182363d1a8abSmrg    emit_insn (gen_addx_si (t14, t13, t8, t12));
182463d1a8abSmrg    emit_insn (gen_movsi (operands[0], t14));
182563d1a8abSmrg    unshare_all_rtl_in_chain (insn);
182663d1a8abSmrg
182763d1a8abSmrg    DONE;
182863d1a8abSmrg  })
182963d1a8abSmrg
183063d1a8abSmrg;; div
183163d1a8abSmrg
183263d1a8abSmrg;; Not necessarily the best implementation of divide but faster then
183363d1a8abSmrg;; the default that gcc provides because this is inlined and it uses
183463d1a8abSmrg;; clz.
183563d1a8abSmrg(define_insn "divmodsi4"
183663d1a8abSmrg      [(set (match_operand:SI 0 "spu_reg_operand" "=&r")
183763d1a8abSmrg	    (div:SI (match_operand:SI 1 "spu_reg_operand" "r")
183863d1a8abSmrg		    (match_operand:SI 2 "spu_reg_operand" "r")))
183963d1a8abSmrg       (set (match_operand:SI 3 "spu_reg_operand" "=&r")
184063d1a8abSmrg	    (mod:SI (match_dup 1)
184163d1a8abSmrg		    (match_dup 2)))
184263d1a8abSmrg       (clobber (match_scratch:SI 4 "=&r"))
184363d1a8abSmrg       (clobber (match_scratch:SI 5 "=&r"))
184463d1a8abSmrg       (clobber (match_scratch:SI 6 "=&r"))
184563d1a8abSmrg       (clobber (match_scratch:SI 7 "=&r"))
184663d1a8abSmrg       (clobber (match_scratch:SI 8 "=&r"))
184763d1a8abSmrg       (clobber (match_scratch:SI 9 "=&r"))
184863d1a8abSmrg       (clobber (match_scratch:SI 10 "=&r"))
184963d1a8abSmrg       (clobber (match_scratch:SI 11 "=&r"))
185063d1a8abSmrg       (clobber (match_scratch:SI 12 "=&r"))
185163d1a8abSmrg       (clobber (reg:SI 130))]
185263d1a8abSmrg  ""
185363d1a8abSmrg  "heqi	%2,0\\n\\
185463d1a8abSmrg	hbrr	3f,1f\\n\\
185563d1a8abSmrg	sfi	%8,%1,0\\n\\
185663d1a8abSmrg	sfi	%9,%2,0\\n\\
185763d1a8abSmrg	cgti	%10,%1,-1\\n\\
185863d1a8abSmrg	cgti	%11,%2,-1\\n\\
185963d1a8abSmrg	selb	%8,%8,%1,%10\\n\\
186063d1a8abSmrg	selb	%9,%9,%2,%11\\n\\
186163d1a8abSmrg	clz	%4,%8\\n\\
186263d1a8abSmrg	clz	%7,%9\\n\\
186363d1a8abSmrg	il	%5,1\\n\\
186463d1a8abSmrg	fsmbi	%0,0\\n\\
186563d1a8abSmrg	sf	%7,%4,%7\\n\\
186663d1a8abSmrg	shlqbyi	%3,%8,0\\n\\
186763d1a8abSmrg	xor	%11,%10,%11\\n\\
186863d1a8abSmrg	shl	%5,%5,%7\\n\\
186963d1a8abSmrg	shl	%4,%9,%7\\n\\
187063d1a8abSmrg	lnop	\\n\\
187163d1a8abSmrg1:	or	%12,%0,%5\\n\\
187263d1a8abSmrg	rotqmbii	%5,%5,-1\\n\\
187363d1a8abSmrg	clgt	%6,%4,%3\\n\\
187463d1a8abSmrg	lnop	\\n\\
187563d1a8abSmrg	sf	%7,%4,%3\\n\\
187663d1a8abSmrg	rotqmbii	%4,%4,-1\\n\\
187763d1a8abSmrg	selb	%0,%12,%0,%6\\n\\
187863d1a8abSmrg	lnop	\\n\\
187963d1a8abSmrg	selb	%3,%7,%3,%6\\n\\
188063d1a8abSmrg3:	brnz	%5,1b\\n\\
188163d1a8abSmrg2:	sfi	%8,%3,0\\n\\
188263d1a8abSmrg	sfi	%9,%0,0\\n\\
188363d1a8abSmrg	selb	%3,%8,%3,%10\\n\\
188463d1a8abSmrg	selb	%0,%0,%9,%11"
188563d1a8abSmrg  [(set_attr "type" "multi0")
188663d1a8abSmrg   (set_attr "length" "128")])
188763d1a8abSmrg
188863d1a8abSmrg(define_insn "udivmodsi4"
188963d1a8abSmrg      [(set (match_operand:SI 0 "spu_reg_operand" "=&r")
189063d1a8abSmrg	    (udiv:SI (match_operand:SI 1 "spu_reg_operand" "r")
189163d1a8abSmrg		     (match_operand:SI 2 "spu_reg_operand" "r")))
189263d1a8abSmrg       (set (match_operand:SI 3 "spu_reg_operand" "=&r")
189363d1a8abSmrg	    (umod:SI (match_dup 1)
189463d1a8abSmrg		     (match_dup 2)))
189563d1a8abSmrg       (clobber (match_scratch:SI 4 "=&r"))
189663d1a8abSmrg       (clobber (match_scratch:SI 5 "=&r"))
189763d1a8abSmrg       (clobber (match_scratch:SI 6 "=&r"))
189863d1a8abSmrg       (clobber (match_scratch:SI 7 "=&r"))
189963d1a8abSmrg       (clobber (match_scratch:SI 8 "=&r"))
190063d1a8abSmrg       (clobber (reg:SI 130))]
190163d1a8abSmrg  ""
190263d1a8abSmrg  "heqi	%2,0\\n\\
190363d1a8abSmrg	hbrr	3f,1f\\n\\
190463d1a8abSmrg	clz	%7,%2\\n\\
190563d1a8abSmrg	clz	%4,%1\\n\\
190663d1a8abSmrg	il	%5,1\\n\\
190763d1a8abSmrg	fsmbi	%0,0\\n\\
190863d1a8abSmrg	sf	%7,%4,%7\\n\\
190963d1a8abSmrg	ori	%3,%1,0\\n\\
191063d1a8abSmrg	shl	%5,%5,%7\\n\\
191163d1a8abSmrg	shl	%4,%2,%7\\n\\
191263d1a8abSmrg1:	or	%8,%0,%5\\n\\
191363d1a8abSmrg	rotqmbii	%5,%5,-1\\n\\
191463d1a8abSmrg	clgt	%6,%4,%3\\n\\
191563d1a8abSmrg	lnop	\\n\\
191663d1a8abSmrg	sf	%7,%4,%3\\n\\
191763d1a8abSmrg	rotqmbii	%4,%4,-1\\n\\
191863d1a8abSmrg	selb	%0,%8,%0,%6\\n\\
191963d1a8abSmrg	lnop	\\n\\
192063d1a8abSmrg	selb	%3,%7,%3,%6\\n\\
192163d1a8abSmrg3:	brnz	%5,1b\\n\\
192263d1a8abSmrg2:"
192363d1a8abSmrg  [(set_attr "type" "multi0")
192463d1a8abSmrg   (set_attr "length" "80")])
192563d1a8abSmrg
192663d1a8abSmrg(define_expand "div<mode>3"
192763d1a8abSmrg  [(parallel
192863d1a8abSmrg    [(set (match_operand:VSF 0 "spu_reg_operand" "")
192963d1a8abSmrg	  (div:VSF (match_operand:VSF 1 "spu_reg_operand" "")
193063d1a8abSmrg		   (match_operand:VSF 2 "spu_reg_operand" "")))
193163d1a8abSmrg     (clobber (match_scratch:VSF 3 ""))
193263d1a8abSmrg     (clobber (match_scratch:VSF 4 ""))
193363d1a8abSmrg     (clobber (match_scratch:VSF 5 ""))])]
193463d1a8abSmrg  ""
193563d1a8abSmrg  "")
193663d1a8abSmrg
193763d1a8abSmrg(define_insn_and_split "*div<mode>3_fast"
193863d1a8abSmrg  [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
193963d1a8abSmrg	(div:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
194063d1a8abSmrg		 (match_operand:VSF 2 "spu_reg_operand" "r")))
194163d1a8abSmrg   (clobber (match_scratch:VSF 3 "=&r"))
194263d1a8abSmrg   (clobber (match_scratch:VSF 4 "=&r"))
194363d1a8abSmrg   (clobber (scratch:VSF))]
194463d1a8abSmrg  "flag_unsafe_math_optimizations"
194563d1a8abSmrg  "#"
194663d1a8abSmrg  "reload_completed"
194763d1a8abSmrg  [(set (match_dup:VSF 0)
194863d1a8abSmrg	(div:VSF (match_dup:VSF 1)
194963d1a8abSmrg		 (match_dup:VSF 2)))
195063d1a8abSmrg   (clobber (match_dup:VSF 3))
195163d1a8abSmrg   (clobber (match_dup:VSF 4))
195263d1a8abSmrg   (clobber (scratch:VSF))]
195363d1a8abSmrg  {
195463d1a8abSmrg    emit_insn (gen_frest_<mode>(operands[3], operands[2]));
195563d1a8abSmrg    emit_insn (gen_fi_<mode>(operands[3], operands[2], operands[3]));
195663d1a8abSmrg    emit_insn (gen_mul<mode>3(operands[4], operands[1], operands[3]));
195763d1a8abSmrg    emit_insn (gen_fnma<mode>4(operands[0], operands[4], operands[2], operands[1]));
195863d1a8abSmrg    emit_insn (gen_fma<mode>4(operands[0], operands[0], operands[3], operands[4]));
195963d1a8abSmrg    DONE;
196063d1a8abSmrg  })
196163d1a8abSmrg
196263d1a8abSmrg(define_insn_and_split "*div<mode>3_adjusted"
196363d1a8abSmrg  [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
196463d1a8abSmrg	(div:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
196563d1a8abSmrg		 (match_operand:VSF 2 "spu_reg_operand" "r")))
196663d1a8abSmrg   (clobber (match_scratch:VSF 3 "=&r"))
196763d1a8abSmrg   (clobber (match_scratch:VSF 4 "=&r"))
196863d1a8abSmrg   (clobber (match_scratch:VSF 5 "=&r"))]
196963d1a8abSmrg  "!flag_unsafe_math_optimizations"
197063d1a8abSmrg  "#"
197163d1a8abSmrg  "reload_completed"
197263d1a8abSmrg  [(set (match_dup:VSF 0)
197363d1a8abSmrg	(div:VSF (match_dup:VSF 1)
197463d1a8abSmrg		 (match_dup:VSF 2)))
197563d1a8abSmrg   (clobber (match_dup:VSF 3))
197663d1a8abSmrg   (clobber (match_dup:VSF 4))
197763d1a8abSmrg   (clobber (match_dup:VSF 5))]
197863d1a8abSmrg  {
197963d1a8abSmrg    emit_insn (gen_frest_<mode> (operands[3], operands[2]));
198063d1a8abSmrg    emit_insn (gen_fi_<mode> (operands[3], operands[2], operands[3]));
198163d1a8abSmrg    emit_insn (gen_mul<mode>3 (operands[4], operands[1], operands[3]));
198263d1a8abSmrg    emit_insn (gen_fnma<mode>4 (operands[5], operands[4], operands[2], operands[1]));
198363d1a8abSmrg    emit_insn (gen_fma<mode>4 (operands[3], operands[5], operands[3], operands[4]));
198463d1a8abSmrg
198563d1a8abSmrg   /* Due to truncation error, the quotient result may be low by 1 ulp.
198663d1a8abSmrg      Conditionally add one if the estimate is too small in magnitude.  */
198763d1a8abSmrg
198863d1a8abSmrg    emit_move_insn (gen_lowpart (<F2I>mode, operands[4]),
198963d1a8abSmrg		    spu_const (<F2I>mode, 0x80000000ULL));
199063d1a8abSmrg    emit_move_insn (gen_lowpart (<F2I>mode, operands[5]),
199163d1a8abSmrg		    spu_const (<F2I>mode, 0x3f800000ULL));
199263d1a8abSmrg    emit_insn (gen_selb (operands[5], operands[5], operands[1], operands[4]));
199363d1a8abSmrg
199463d1a8abSmrg    emit_insn (gen_add<f2i>3 (gen_lowpart (<F2I>mode, operands[4]),
199563d1a8abSmrg			      gen_lowpart (<F2I>mode, operands[3]),
199663d1a8abSmrg			      spu_const (<F2I>mode, 1)));
199763d1a8abSmrg    emit_insn (gen_fnma<mode>4 (operands[0], operands[2], operands[4], operands[1]));
199863d1a8abSmrg    emit_insn (gen_mul<mode>3 (operands[0], operands[0], operands[5]));
199963d1a8abSmrg    emit_insn (gen_cgt_<f2i> (gen_lowpart (<F2I>mode, operands[0]),
200063d1a8abSmrg			      gen_lowpart (<F2I>mode, operands[0]),
200163d1a8abSmrg			      spu_const (<F2I>mode, -1)));
200263d1a8abSmrg    emit_insn (gen_selb (operands[0], operands[3], operands[4], operands[0]));
200363d1a8abSmrg    DONE;
200463d1a8abSmrg  })
200563d1a8abSmrg
200663d1a8abSmrg
200763d1a8abSmrg;; sqrt
200863d1a8abSmrg
200963d1a8abSmrg(define_insn_and_split "sqrtsf2"
201063d1a8abSmrg  [(set (match_operand:SF 0 "spu_reg_operand" "=r")
201163d1a8abSmrg	(sqrt:SF (match_operand:SF 1 "spu_reg_operand" "r")))
201263d1a8abSmrg   (clobber (match_scratch:SF 2 "=&r"))
201363d1a8abSmrg   (clobber (match_scratch:SF 3 "=&r"))
201463d1a8abSmrg   (clobber (match_scratch:SF 4 "=&r"))
201563d1a8abSmrg   (clobber (match_scratch:SF 5 "=&r"))]
201663d1a8abSmrg  ""
201763d1a8abSmrg  "#"
201863d1a8abSmrg  "reload_completed"
201963d1a8abSmrg  [(set (match_dup:SF 0)
202063d1a8abSmrg	(sqrt:SF (match_dup:SF 1)))
202163d1a8abSmrg   (clobber (match_dup:SF 2))
202263d1a8abSmrg   (clobber (match_dup:SF 3))
202363d1a8abSmrg   (clobber (match_dup:SF 4))
202463d1a8abSmrg   (clobber (match_dup:SF 5))]
202563d1a8abSmrg  {
202663d1a8abSmrg    emit_move_insn (operands[3],spu_float_const(\"0.5\",SFmode));
202763d1a8abSmrg    emit_move_insn (operands[4],spu_float_const(\"1.00000011920928955078125\",SFmode));
202863d1a8abSmrg    emit_insn (gen_frsqest_sf(operands[2],operands[1]));
202963d1a8abSmrg    emit_insn (gen_fi_sf(operands[2],operands[1],operands[2]));
203063d1a8abSmrg    emit_insn (gen_mulsf3(operands[5],operands[2],operands[1]));
203163d1a8abSmrg    emit_insn (gen_mulsf3(operands[3],operands[5],operands[3]));
203263d1a8abSmrg    emit_insn (gen_fnmasf4(operands[4],operands[2],operands[5],operands[4]));
203363d1a8abSmrg    emit_insn (gen_fmasf4(operands[0],operands[4],operands[3],operands[5]));
203463d1a8abSmrg    DONE;
203563d1a8abSmrg  })
203663d1a8abSmrg
203763d1a8abSmrg(define_insn "frest_<mode>"
203863d1a8abSmrg  [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
203963d1a8abSmrg	(unspec:VSF [(match_operand:VSF 1 "spu_reg_operand" "r")] UNSPEC_FREST))]
204063d1a8abSmrg  ""
204163d1a8abSmrg  "frest\t%0,%1"
204263d1a8abSmrg  [(set_attr "type" "shuf")])
204363d1a8abSmrg
204463d1a8abSmrg(define_insn "frsqest_<mode>"
204563d1a8abSmrg  [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
204663d1a8abSmrg	(unspec:VSF [(match_operand:VSF 1 "spu_reg_operand" "r")] UNSPEC_FRSQEST))]
204763d1a8abSmrg  ""
204863d1a8abSmrg  "frsqest\t%0,%1"
204963d1a8abSmrg  [(set_attr "type" "shuf")])
205063d1a8abSmrg
205163d1a8abSmrg(define_insn "fi_<mode>"
205263d1a8abSmrg  [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
205363d1a8abSmrg	(unspec:VSF [(match_operand:VSF 1 "spu_reg_operand" "r")
205463d1a8abSmrg		    (match_operand:VSF 2 "spu_reg_operand" "r")] UNSPEC_FI))]
205563d1a8abSmrg  ""
205663d1a8abSmrg  "fi\t%0,%1,%2"
205763d1a8abSmrg  [(set_attr "type" "fp7")])
205863d1a8abSmrg
205963d1a8abSmrg
206063d1a8abSmrg;; and
206163d1a8abSmrg
206263d1a8abSmrg(define_insn "and<mode>3"
206363d1a8abSmrg  [(set (match_operand:MOV 0 "spu_reg_operand" "=r,r")
206463d1a8abSmrg	(and:MOV (match_operand:MOV 1 "spu_reg_operand" "r,r")
206563d1a8abSmrg		 (match_operand:MOV 2 "spu_logical_operand" "r,C")))]
206663d1a8abSmrg  ""
206763d1a8abSmrg  "@
206863d1a8abSmrg  and\t%0,%1,%2
206963d1a8abSmrg  and%j2i\t%0,%1,%J2")
207063d1a8abSmrg
207163d1a8abSmrg(define_insn "anddi3"
207263d1a8abSmrg  [(set (match_operand:DI 0 "spu_reg_operand" "=r,r")
207363d1a8abSmrg	(and:DI (match_operand:DI 1 "spu_reg_operand" "r,r")
207463d1a8abSmrg		(match_operand:DI 2 "spu_logical_operand" "r,c")))]
207563d1a8abSmrg  ""
207663d1a8abSmrg  "@
207763d1a8abSmrg  and\t%0,%1,%2
207863d1a8abSmrg  and%k2i\t%0,%1,%K2")
207963d1a8abSmrg
208063d1a8abSmrg(define_insn "andti3"
208163d1a8abSmrg  [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
208263d1a8abSmrg	(and:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
208363d1a8abSmrg		(match_operand:TI 2 "spu_logical_operand" "r,Y")))]
208463d1a8abSmrg  ""
208563d1a8abSmrg  "@
208663d1a8abSmrg  and\t%0,%1,%2
208763d1a8abSmrg  and%m2i\t%0,%1,%L2")
208863d1a8abSmrg
208963d1a8abSmrg(define_insn "andc_<mode>"
209063d1a8abSmrg  [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
209163d1a8abSmrg	(and:ALL (not:ALL (match_operand:ALL 2 "spu_reg_operand" "r"))
209263d1a8abSmrg	         (match_operand:ALL 1 "spu_reg_operand" "r")))]
209363d1a8abSmrg  ""
209463d1a8abSmrg  "andc\t%0,%1,%2")
209563d1a8abSmrg
209663d1a8abSmrg(define_insn "nand_<mode>"
209763d1a8abSmrg  [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
209863d1a8abSmrg	(not:ALL (and:ALL (match_operand:ALL 2 "spu_reg_operand" "r")
209963d1a8abSmrg			  (match_operand:ALL 1 "spu_reg_operand" "r"))))]
210063d1a8abSmrg  ""
210163d1a8abSmrg  "nand\t%0,%1,%2")
210263d1a8abSmrg
210363d1a8abSmrg
210463d1a8abSmrg;; ior
210563d1a8abSmrg
210663d1a8abSmrg(define_insn "ior<mode>3"
210763d1a8abSmrg  [(set (match_operand:MOV 0 "spu_reg_operand" "=r,r,r")
210863d1a8abSmrg	(ior:MOV (match_operand:MOV 1 "spu_reg_operand" "r,r,0")
210963d1a8abSmrg		 (match_operand:MOV 2 "spu_ior_operand" "r,C,D")))]
211063d1a8abSmrg  ""
211163d1a8abSmrg  "@
211263d1a8abSmrg  or\t%0,%1,%2
211363d1a8abSmrg  or%j2i\t%0,%1,%J2
211463d1a8abSmrg  iohl\t%0,%J2")
211563d1a8abSmrg
211663d1a8abSmrg(define_insn "iordi3"
211763d1a8abSmrg  [(set (match_operand:DI 0 "spu_reg_operand" "=r,r,r")
211863d1a8abSmrg	(ior:DI (match_operand:DI 1 "spu_reg_operand" "r,r,0")
211963d1a8abSmrg		(match_operand:DI 2 "spu_ior_operand" "r,c,d")))]
212063d1a8abSmrg  ""
212163d1a8abSmrg  "@
212263d1a8abSmrg  or\t%0,%1,%2
212363d1a8abSmrg  or%k2i\t%0,%1,%K2
212463d1a8abSmrg  iohl\t%0,%K2")
212563d1a8abSmrg
212663d1a8abSmrg(define_insn "iorti3"
212763d1a8abSmrg  [(set (match_operand:TI 0 "spu_reg_operand" "=r,r,r")
212863d1a8abSmrg	(ior:TI (match_operand:TI 1 "spu_reg_operand" "r,r,0")
212963d1a8abSmrg		(match_operand:TI 2 "spu_ior_operand" "r,Y,Z")))]
213063d1a8abSmrg  ""
213163d1a8abSmrg  "@
213263d1a8abSmrg  or\t%0,%1,%2
213363d1a8abSmrg  or%m2i\t%0,%1,%L2
213463d1a8abSmrg  iohl\t%0,%L2")
213563d1a8abSmrg
213663d1a8abSmrg(define_insn "orc_<mode>"
213763d1a8abSmrg  [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
213863d1a8abSmrg	(ior:ALL (not:ALL (match_operand:ALL 2 "spu_reg_operand" "r"))
213963d1a8abSmrg	         (match_operand:ALL 1 "spu_reg_operand" "r")))]
214063d1a8abSmrg  ""
214163d1a8abSmrg  "orc\t%0,%1,%2")
214263d1a8abSmrg
214363d1a8abSmrg(define_insn "nor_<mode>"
214463d1a8abSmrg  [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
214563d1a8abSmrg	(not:ALL (ior:ALL (match_operand:ALL 1 "spu_reg_operand" "r")
214663d1a8abSmrg			  (match_operand:ALL 2 "spu_reg_operand" "r"))))]
214763d1a8abSmrg  ""
214863d1a8abSmrg  "nor\t%0,%1,%2")
214963d1a8abSmrg
215063d1a8abSmrg;; xor
215163d1a8abSmrg
215263d1a8abSmrg(define_insn "xor<mode>3"
215363d1a8abSmrg  [(set (match_operand:MOV 0 "spu_reg_operand" "=r,r")
215463d1a8abSmrg	(xor:MOV (match_operand:MOV 1 "spu_reg_operand" "r,r")
215563d1a8abSmrg		 (match_operand:MOV 2 "spu_logical_operand" "r,B")))]
215663d1a8abSmrg  ""
215763d1a8abSmrg  "@
215863d1a8abSmrg  xor\t%0,%1,%2
215963d1a8abSmrg  xor%j2i\t%0,%1,%J2")
216063d1a8abSmrg
216163d1a8abSmrg(define_insn "xordi3"
216263d1a8abSmrg  [(set (match_operand:DI 0 "spu_reg_operand" "=r,r")
216363d1a8abSmrg	(xor:DI (match_operand:DI 1 "spu_reg_operand" "r,r")
216463d1a8abSmrg		(match_operand:DI 2 "spu_logical_operand" "r,c")))]
216563d1a8abSmrg  ""
216663d1a8abSmrg  "@
216763d1a8abSmrg  xor\t%0,%1,%2
216863d1a8abSmrg  xor%k2i\t%0,%1,%K2")
216963d1a8abSmrg
217063d1a8abSmrg(define_insn "xorti3"
217163d1a8abSmrg  [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
217263d1a8abSmrg	(xor:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
217363d1a8abSmrg		(match_operand:TI 2 "spu_logical_operand" "r,Y")))]
217463d1a8abSmrg  ""
217563d1a8abSmrg  "@
217663d1a8abSmrg  xor\t%0,%1,%2
217763d1a8abSmrg  xor%m2i\t%0,%1,%L2")
217863d1a8abSmrg
217963d1a8abSmrg(define_insn "eqv_<mode>"
218063d1a8abSmrg  [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
218163d1a8abSmrg	(not:ALL (xor:ALL (match_operand:ALL 1 "spu_reg_operand" "r")
218263d1a8abSmrg			  (match_operand:ALL 2 "spu_reg_operand" "r"))))]
218363d1a8abSmrg  ""
218463d1a8abSmrg  "eqv\t%0,%1,%2")
218563d1a8abSmrg
218663d1a8abSmrg;; one_cmpl
218763d1a8abSmrg
218863d1a8abSmrg(define_insn "one_cmpl<mode>2"
218963d1a8abSmrg  [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
219063d1a8abSmrg	(not:ALL (match_operand:ALL 1 "spu_reg_operand" "r")))]
219163d1a8abSmrg  ""
219263d1a8abSmrg  "nor\t%0,%1,%1")
219363d1a8abSmrg
219463d1a8abSmrg
219563d1a8abSmrg;; selb
219663d1a8abSmrg
219763d1a8abSmrg(define_expand "selb"
219863d1a8abSmrg  [(set (match_operand 0 "spu_reg_operand" "")
219963d1a8abSmrg  	(unspec [(match_operand 1 "spu_reg_operand" "")
220063d1a8abSmrg		 (match_operand 2 "spu_reg_operand" "")
220163d1a8abSmrg		 (match_operand 3 "spu_reg_operand" "")] UNSPEC_SELB))]
220263d1a8abSmrg  ""
220363d1a8abSmrg  {
220463d1a8abSmrg    rtx s = gen__selb (operands[0], operands[1], operands[2], operands[3]);
220563d1a8abSmrg    PUT_MODE (SET_SRC (s), GET_MODE (operands[0]));
220663d1a8abSmrg    emit_insn (s);
220763d1a8abSmrg    DONE;
220863d1a8abSmrg  })
220963d1a8abSmrg
221063d1a8abSmrg;; This could be defined as a combination of logical operations, but at
221163d1a8abSmrg;; one time it caused a crash due to recursive expansion of rtl during CSE.
221263d1a8abSmrg(define_insn "_selb"
221363d1a8abSmrg  [(set (match_operand 0 "spu_reg_operand" "=r")
221463d1a8abSmrg  	(unspec [(match_operand 1 "spu_reg_operand" "r")
221563d1a8abSmrg		 (match_operand 2 "spu_reg_operand" "r")
221663d1a8abSmrg		 (match_operand 3 "spu_reg_operand" "r")] UNSPEC_SELB))]
221763d1a8abSmrg  "GET_MODE(operands[0]) == GET_MODE(operands[1])
221863d1a8abSmrg   && GET_MODE(operands[1]) == GET_MODE(operands[2])"
221963d1a8abSmrg  "selb\t%0,%1,%2,%3")
222063d1a8abSmrg
222163d1a8abSmrg
222263d1a8abSmrg;; Misc. byte/bit operations
222363d1a8abSmrg;; clz/ctz/ffs/popcount/parity
222463d1a8abSmrg;; cntb/sumb
222563d1a8abSmrg
222663d1a8abSmrg(define_insn "clz<mode>2"
222763d1a8abSmrg  [(set (match_operand:VSI 0 "spu_reg_operand" "=r")
222863d1a8abSmrg	(clz:VSI (match_operand:VSI 1 "spu_reg_operand" "r")))]
222963d1a8abSmrg  ""
223063d1a8abSmrg  "clz\t%0,%1")
223163d1a8abSmrg
223263d1a8abSmrg(define_expand "ctz<mode>2"
223363d1a8abSmrg  [(set (match_dup 2)
223463d1a8abSmrg	(neg:VSI (match_operand:VSI 1 "spu_reg_operand" "")))
223563d1a8abSmrg   (set (match_dup 3) (and:VSI (match_dup 1)
223663d1a8abSmrg			       (match_dup 2)))
223763d1a8abSmrg   (set (match_dup 4) (clz:VSI (match_dup 3)))
223863d1a8abSmrg   (set (match_operand:VSI 0 "spu_reg_operand" "")
223963d1a8abSmrg	(minus:VSI (match_dup 5) (match_dup 4)))]
224063d1a8abSmrg  ""
224163d1a8abSmrg  {
224263d1a8abSmrg     operands[2] = gen_reg_rtx (<MODE>mode);
224363d1a8abSmrg     operands[3] = gen_reg_rtx (<MODE>mode);
224463d1a8abSmrg     operands[4] = gen_reg_rtx (<MODE>mode);
224563d1a8abSmrg     operands[5] = spu_const(<MODE>mode, 31);
224663d1a8abSmrg  })
224763d1a8abSmrg
224863d1a8abSmrg(define_expand "clrsb<mode>2"
224963d1a8abSmrg  [(set (match_dup 2)
225063d1a8abSmrg        (gt:VSI (match_operand:VSI 1 "spu_reg_operand" "") (match_dup 5)))
225163d1a8abSmrg   (set (match_dup 3) (not:VSI (xor:VSI (match_dup 1) (match_dup 2))))
225263d1a8abSmrg   (set (match_dup 4) (clz:VSI (match_dup 3)))
225363d1a8abSmrg   (set (match_operand:VSI 0 "spu_reg_operand")
225463d1a8abSmrg        (plus:VSI (match_dup 4) (match_dup 5)))]
225563d1a8abSmrg  ""
225663d1a8abSmrg  {
225763d1a8abSmrg     operands[2] = gen_reg_rtx (<MODE>mode);
225863d1a8abSmrg     operands[3] = gen_reg_rtx (<MODE>mode);
225963d1a8abSmrg     operands[4] = gen_reg_rtx (<MODE>mode);
226063d1a8abSmrg     operands[5] = spu_const(<MODE>mode, -1);
226163d1a8abSmrg  })
226263d1a8abSmrg
226363d1a8abSmrg(define_expand "ffs<mode>2"
226463d1a8abSmrg  [(set (match_dup 2)
226563d1a8abSmrg	(neg:VSI (match_operand:VSI 1 "spu_reg_operand" "")))
226663d1a8abSmrg   (set (match_dup 3) (and:VSI (match_dup 1)
226763d1a8abSmrg			       (match_dup 2)))
226863d1a8abSmrg   (set (match_dup 4) (clz:VSI (match_dup 3)))
226963d1a8abSmrg   (set (match_operand:VSI 0 "spu_reg_operand" "")
227063d1a8abSmrg	(minus:VSI (match_dup 5) (match_dup 4)))]
227163d1a8abSmrg  ""
227263d1a8abSmrg  {
227363d1a8abSmrg     operands[2] = gen_reg_rtx (<MODE>mode);
227463d1a8abSmrg     operands[3] = gen_reg_rtx (<MODE>mode);
227563d1a8abSmrg     operands[4] = gen_reg_rtx (<MODE>mode);
227663d1a8abSmrg     operands[5] = spu_const(<MODE>mode, 32);
227763d1a8abSmrg  })
227863d1a8abSmrg
227963d1a8abSmrg(define_expand "popcountsi2"
228063d1a8abSmrg  [(set (match_dup 2)
228163d1a8abSmrg	(unspec:SI [(match_operand:SI 1 "spu_reg_operand" "")]
228263d1a8abSmrg		     UNSPEC_CNTB))
228363d1a8abSmrg   (set (match_dup 3)
228463d1a8abSmrg	(unspec:HI [(match_dup 2)] UNSPEC_SUMB))
228563d1a8abSmrg   (set (match_operand:SI 0 "spu_reg_operand" "")
228663d1a8abSmrg	(sign_extend:SI (match_dup 3)))]
228763d1a8abSmrg  ""
228863d1a8abSmrg  {
228963d1a8abSmrg    operands[2] = gen_reg_rtx (SImode);
229063d1a8abSmrg    operands[3] = gen_reg_rtx (HImode);
229163d1a8abSmrg  })
229263d1a8abSmrg
229363d1a8abSmrg(define_expand "paritysi2"
229463d1a8abSmrg  [(set (match_operand:SI 0 "spu_reg_operand" "")
229563d1a8abSmrg	(parity:SI (match_operand:SI 1 "spu_reg_operand" "")))]
229663d1a8abSmrg  ""
229763d1a8abSmrg  {
229863d1a8abSmrg    operands[2] = gen_reg_rtx (SImode);
229963d1a8abSmrg    emit_insn (gen_popcountsi2(operands[2], operands[1]));
230063d1a8abSmrg    emit_insn (gen_andsi3(operands[0], operands[2], GEN_INT (1)));
230163d1a8abSmrg    DONE;
230263d1a8abSmrg  })
230363d1a8abSmrg
230463d1a8abSmrg(define_insn "cntb_si"
230563d1a8abSmrg  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
230663d1a8abSmrg        (unspec:SI [(match_operand:SI 1 "spu_reg_operand" "r")]
230763d1a8abSmrg                   UNSPEC_CNTB))]
230863d1a8abSmrg  ""
230963d1a8abSmrg  "cntb\t%0,%1"
231063d1a8abSmrg  [(set_attr "type" "fxb")])
231163d1a8abSmrg
231263d1a8abSmrg(define_insn "cntb_v16qi"
231363d1a8abSmrg  [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
231463d1a8abSmrg        (unspec:V16QI [(match_operand:V16QI 1 "spu_reg_operand" "r")]
231563d1a8abSmrg                      UNSPEC_CNTB))]
231663d1a8abSmrg  ""
231763d1a8abSmrg  "cntb\t%0,%1"
231863d1a8abSmrg  [(set_attr "type" "fxb")])
231963d1a8abSmrg
232063d1a8abSmrg(define_insn "sumb_si"
232163d1a8abSmrg  [(set (match_operand:HI 0 "spu_reg_operand" "=r")
232263d1a8abSmrg        (unspec:HI [(match_operand:SI 1 "spu_reg_operand" "r")] UNSPEC_SUMB))]
232363d1a8abSmrg  ""
232463d1a8abSmrg  "sumb\t%0,%1,%1"
232563d1a8abSmrg  [(set_attr "type" "fxb")])
232663d1a8abSmrg
232763d1a8abSmrg
232863d1a8abSmrg;; ashl, vashl
232963d1a8abSmrg
233063d1a8abSmrg(define_insn "<v>ashl<mode>3"
233163d1a8abSmrg  [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
233263d1a8abSmrg	(ashift:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
233363d1a8abSmrg		     (match_operand:VHSI 2 "spu_nonmem_operand" "r,W")))]
233463d1a8abSmrg  ""
233563d1a8abSmrg  "@
233663d1a8abSmrg  shl<bh>\t%0,%1,%2
233763d1a8abSmrg  shl<bh>i\t%0,%1,%<umask>2"
233863d1a8abSmrg  [(set_attr "type" "fx3")])
233963d1a8abSmrg
234063d1a8abSmrg(define_insn_and_split "ashldi3"
234163d1a8abSmrg  [(set (match_operand:DI 0 "spu_reg_operand" "=r,r")
234263d1a8abSmrg	(ashift:DI (match_operand:DI 1 "spu_reg_operand" "r,r")
234363d1a8abSmrg	           (match_operand:SI 2 "spu_nonmem_operand" "r,I")))
234463d1a8abSmrg   (clobber (match_scratch:SI 3 "=&r,X"))]
234563d1a8abSmrg  ""
234663d1a8abSmrg  "#"
234763d1a8abSmrg  "reload_completed"
234863d1a8abSmrg  [(set (match_dup:DI 0)
234963d1a8abSmrg	(ashift:DI (match_dup:DI 1)
235063d1a8abSmrg	           (match_dup:SI 2)))]
235163d1a8abSmrg  {
235263d1a8abSmrg    rtx op0 = gen_rtx_REG (TImode, REGNO (operands[0]));
235363d1a8abSmrg    rtx op1 = gen_rtx_REG (TImode, REGNO (operands[1]));
235463d1a8abSmrg    rtx op2 = operands[2];
235563d1a8abSmrg    rtx op3 = operands[3];
235663d1a8abSmrg
235763d1a8abSmrg    if (GET_CODE (operands[2]) == REG)
235863d1a8abSmrg      {
235963d1a8abSmrg	emit_insn (gen_addsi3 (op3, op2, GEN_INT (64)));
236063d1a8abSmrg	emit_insn (gen_rotlti3 (op0, op1, GEN_INT (64)));
236163d1a8abSmrg	emit_insn (gen_shlqbybi_ti (op0, op0, op3));
236263d1a8abSmrg	emit_insn (gen_shlqbi_ti (op0, op0, op3));
236363d1a8abSmrg      }
236463d1a8abSmrg    else
236563d1a8abSmrg      {
236663d1a8abSmrg	HOST_WIDE_INT val = INTVAL (operands[2]);
236763d1a8abSmrg	emit_insn (gen_rotlti3 (op0, op1, GEN_INT (64)));
236863d1a8abSmrg	emit_insn (gen_shlqby_ti (op0, op0, GEN_INT (val / 8 + 8)));
236963d1a8abSmrg	if (val % 8)
237063d1a8abSmrg	  emit_insn (gen_shlqbi_ti (op0, op0, GEN_INT (val % 8)));
237163d1a8abSmrg      }
237263d1a8abSmrg    DONE;
237363d1a8abSmrg  })
237463d1a8abSmrg
237563d1a8abSmrg(define_expand "ashlti3"
237663d1a8abSmrg  [(parallel [(set (match_operand:TI 0 "spu_reg_operand" "")
237763d1a8abSmrg		   (ashift:TI (match_operand:TI 1 "spu_reg_operand" "")
237863d1a8abSmrg			      (match_operand:SI 2 "spu_nonmem_operand" "")))
237963d1a8abSmrg	      (clobber (match_dup:TI 3))])]
238063d1a8abSmrg  ""
238163d1a8abSmrg  "if (GET_CODE (operands[2]) == CONST_INT)
238263d1a8abSmrg    {
238363d1a8abSmrg      emit_insn (gen_ashlti3_imm(operands[0], operands[1], operands[2]));
238463d1a8abSmrg      DONE;
238563d1a8abSmrg    }
238663d1a8abSmrg   operands[3] = gen_reg_rtx (TImode);")
238763d1a8abSmrg
238863d1a8abSmrg(define_insn_and_split "ashlti3_imm"
238963d1a8abSmrg  [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
239063d1a8abSmrg	(ashift:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
239163d1a8abSmrg		   (match_operand:SI 2 "immediate_operand" "O,P")))]
239263d1a8abSmrg  ""
239363d1a8abSmrg  "@
239463d1a8abSmrg   shlqbyi\t%0,%1,%h2
239563d1a8abSmrg   shlqbii\t%0,%1,%e2"
239663d1a8abSmrg  "!satisfies_constraint_O (operands[2]) && !satisfies_constraint_P (operands[2])"
239763d1a8abSmrg  [(set (match_dup:TI 0)
239863d1a8abSmrg	(ashift:TI (match_dup:TI 1)
239963d1a8abSmrg		   (match_dup:SI 3)))
240063d1a8abSmrg   (set (match_dup:TI 0)
240163d1a8abSmrg	(ashift:TI (match_dup:TI 0)
240263d1a8abSmrg		   (match_dup:SI 4)))]
240363d1a8abSmrg  {
240463d1a8abSmrg    HOST_WIDE_INT val = INTVAL(operands[2]);
240563d1a8abSmrg    operands[3] = GEN_INT (val&7);
240663d1a8abSmrg    operands[4] = GEN_INT (val&-8);
240763d1a8abSmrg  }
240863d1a8abSmrg  [(set_attr "type" "shuf,shuf")])
240963d1a8abSmrg
241063d1a8abSmrg(define_insn_and_split "ashlti3_reg"
241163d1a8abSmrg  [(set (match_operand:TI 0 "spu_reg_operand" "=r")
241263d1a8abSmrg	(ashift:TI (match_operand:TI 1 "spu_reg_operand" "r")
241363d1a8abSmrg		   (match_operand:SI 2 "spu_reg_operand" "r")))
241463d1a8abSmrg   (clobber (match_operand:TI 3 "spu_reg_operand" "=&r"))]
241563d1a8abSmrg  ""
241663d1a8abSmrg  "#"
241763d1a8abSmrg  ""
241863d1a8abSmrg  [(set (match_dup:TI 3)
241963d1a8abSmrg	(ashift:TI (match_dup:TI 1)
242063d1a8abSmrg		   (and:SI (match_dup:SI 2)
242163d1a8abSmrg			   (const_int 7))))
242263d1a8abSmrg   (set (match_dup:TI 0)
242363d1a8abSmrg	(ashift:TI (match_dup:TI 3)
242463d1a8abSmrg		   (and:SI (match_dup:SI 2)
242563d1a8abSmrg			   (const_int -8))))]
242663d1a8abSmrg  "")
242763d1a8abSmrg
242863d1a8abSmrg(define_insn "shlqbybi_ti"
242963d1a8abSmrg  [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
243063d1a8abSmrg	(ashift:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
243163d1a8abSmrg		   (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
243263d1a8abSmrg			   (const_int -8))))]
243363d1a8abSmrg  ""
243463d1a8abSmrg  "@
243563d1a8abSmrg   shlqbybi\t%0,%1,%2
243663d1a8abSmrg   shlqbyi\t%0,%1,%h2"
243763d1a8abSmrg  [(set_attr "type" "shuf,shuf")])
243863d1a8abSmrg
243963d1a8abSmrg(define_insn "shlqbi_ti"
244063d1a8abSmrg  [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
244163d1a8abSmrg	(ashift:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
244263d1a8abSmrg		   (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
244363d1a8abSmrg			   (const_int 7))))]
244463d1a8abSmrg  ""
244563d1a8abSmrg  "@
244663d1a8abSmrg   shlqbi\t%0,%1,%2
244763d1a8abSmrg   shlqbii\t%0,%1,%e2"
244863d1a8abSmrg  [(set_attr "type" "shuf,shuf")])
244963d1a8abSmrg
245063d1a8abSmrg(define_insn "shlqby_ti"
245163d1a8abSmrg  [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
245263d1a8abSmrg	(ashift:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
245363d1a8abSmrg		   (mult:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
245463d1a8abSmrg			    (const_int 8))))]
245563d1a8abSmrg  ""
245663d1a8abSmrg  "@
245763d1a8abSmrg   shlqby\t%0,%1,%2
245863d1a8abSmrg   shlqbyi\t%0,%1,%f2"
245963d1a8abSmrg  [(set_attr "type" "shuf,shuf")])
246063d1a8abSmrg
246163d1a8abSmrg
246263d1a8abSmrg;; lshr, vlshr
246363d1a8abSmrg
246463d1a8abSmrg(define_insn_and_split "<v>lshr<mode>3"
246563d1a8abSmrg  [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
246663d1a8abSmrg	(lshiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
246763d1a8abSmrg		       (match_operand:VHSI 2 "spu_nonmem_operand" "r,W")))
246863d1a8abSmrg   (clobber (match_scratch:VHSI 3 "=&r,X"))]
246963d1a8abSmrg  ""
247063d1a8abSmrg  "@
247163d1a8abSmrg   #
247263d1a8abSmrg   rot<bh>mi\t%0,%1,-%<umask>2"
247363d1a8abSmrg  "reload_completed && GET_CODE (operands[2]) == REG"
247463d1a8abSmrg  [(set (match_dup:VHSI 3)
247563d1a8abSmrg	(neg:VHSI (match_dup:VHSI 2)))
247663d1a8abSmrg   (set (match_dup:VHSI 0)
247763d1a8abSmrg	(lshiftrt:VHSI (match_dup:VHSI 1)
247863d1a8abSmrg		       (neg:VHSI (match_dup:VHSI 3))))]
247963d1a8abSmrg  ""
248063d1a8abSmrg  [(set_attr "type" "*,fx3")])
248163d1a8abSmrg
248263d1a8abSmrg(define_insn "<v>lshr<mode>3_imm"
248363d1a8abSmrg  [(set (match_operand:VHSI 0 "spu_reg_operand" "=r")
248463d1a8abSmrg	(lshiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r")
248563d1a8abSmrg		       (match_operand:VHSI 2 "immediate_operand" "W")))]
248663d1a8abSmrg  ""
248763d1a8abSmrg  "rot<bh>mi\t%0,%1,-%<umask>2"
248863d1a8abSmrg  [(set_attr "type" "fx3")])
248963d1a8abSmrg
249063d1a8abSmrg(define_insn "rotm_<mode>"
249163d1a8abSmrg  [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
249263d1a8abSmrg	(lshiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
249363d1a8abSmrg		       (neg:VHSI (match_operand:VHSI 2 "spu_nonmem_operand" "r,W"))))]
249463d1a8abSmrg  ""
249563d1a8abSmrg  "@
249663d1a8abSmrg   rot<bh>m\t%0,%1,%2
249763d1a8abSmrg   rot<bh>mi\t%0,%1,-%<nmask>2"
249863d1a8abSmrg  [(set_attr "type" "fx3")])
249963d1a8abSmrg
250063d1a8abSmrg(define_insn_and_split "lshr<mode>3"
250163d1a8abSmrg  [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r,r")
250263d1a8abSmrg	(lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r,r")
250363d1a8abSmrg		      (match_operand:SI 2 "spu_nonmem_operand" "r,O,P")))]
250463d1a8abSmrg  ""
250563d1a8abSmrg  "@
250663d1a8abSmrg   #
250763d1a8abSmrg   rotqmbyi\t%0,%1,-%h2
250863d1a8abSmrg   rotqmbii\t%0,%1,-%e2"
250963d1a8abSmrg  "REG_P (operands[2]) || (!satisfies_constraint_O (operands[2]) && !satisfies_constraint_P (operands[2]))"
251063d1a8abSmrg  [(set (match_dup:DTI 3)
251163d1a8abSmrg	(lshiftrt:DTI (match_dup:DTI 1)
251263d1a8abSmrg		      (match_dup:SI 4)))
251363d1a8abSmrg   (set (match_dup:DTI 0)
251463d1a8abSmrg	(lshiftrt:DTI (match_dup:DTI 3)
251563d1a8abSmrg		      (match_dup:SI 5)))]
251663d1a8abSmrg  {
251763d1a8abSmrg    operands[3] = gen_reg_rtx (<MODE>mode);
251863d1a8abSmrg    if (GET_CODE (operands[2]) == CONST_INT)
251963d1a8abSmrg      {
252063d1a8abSmrg	HOST_WIDE_INT val = INTVAL(operands[2]);
252163d1a8abSmrg	operands[4] = GEN_INT (val & 7);
252263d1a8abSmrg	operands[5] = GEN_INT (val & -8);
252363d1a8abSmrg      }
252463d1a8abSmrg    else
252563d1a8abSmrg      {
252663d1a8abSmrg        rtx t0 = gen_reg_rtx (SImode);
252763d1a8abSmrg        rtx t1 = gen_reg_rtx (SImode);
252863d1a8abSmrg	emit_insn (gen_subsi3(t0, GEN_INT(0), operands[2]));
252963d1a8abSmrg	emit_insn (gen_subsi3(t1, GEN_INT(7), operands[2]));
253063d1a8abSmrg        operands[4] = gen_rtx_AND (SImode, gen_rtx_NEG (SImode, t0), GEN_INT (7));
253163d1a8abSmrg        operands[5] = gen_rtx_AND (SImode, gen_rtx_NEG (SImode, gen_rtx_AND (SImode, t1, GEN_INT (-8))), GEN_INT (-8));
253263d1a8abSmrg      }
253363d1a8abSmrg  }
253463d1a8abSmrg  [(set_attr "type" "*,shuf,shuf")])
253563d1a8abSmrg
253663d1a8abSmrg(define_expand "shrqbybi_<mode>"
253763d1a8abSmrg  [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
253863d1a8abSmrg	(lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
253963d1a8abSmrg		      (and:SI (neg:SI (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
254063d1a8abSmrg					      (const_int -8)))
254163d1a8abSmrg			      (const_int -8))))]
254263d1a8abSmrg  ""
254363d1a8abSmrg  {
254463d1a8abSmrg    if (GET_CODE (operands[2]) == CONST_INT)
254563d1a8abSmrg      operands[2] = GEN_INT (7 - INTVAL (operands[2]));
254663d1a8abSmrg    else
254763d1a8abSmrg      {
254863d1a8abSmrg        rtx t0 = gen_reg_rtx (SImode);
254963d1a8abSmrg	emit_insn (gen_subsi3 (t0, GEN_INT (7), operands[2]));
255063d1a8abSmrg        operands[2] = t0;
255163d1a8abSmrg      }
255263d1a8abSmrg  })
255363d1a8abSmrg
255463d1a8abSmrg(define_insn "rotqmbybi_<mode>"
255563d1a8abSmrg  [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
255663d1a8abSmrg	(lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
255763d1a8abSmrg		      (and:SI (neg:SI (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
255863d1a8abSmrg					      (const_int -8)))
255963d1a8abSmrg			      (const_int -8))))]
256063d1a8abSmrg  ""
256163d1a8abSmrg  "@
256263d1a8abSmrg   rotqmbybi\t%0,%1,%2
256363d1a8abSmrg   rotqmbyi\t%0,%1,-%H2"
256463d1a8abSmrg  [(set_attr "type" "shuf")])
256563d1a8abSmrg
256663d1a8abSmrg(define_insn_and_split "shrqbi_<mode>"
256763d1a8abSmrg  [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
256863d1a8abSmrg	(lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
256963d1a8abSmrg		      (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
257063d1a8abSmrg			      (const_int 7))))
257163d1a8abSmrg   (clobber (match_scratch:SI 3 "=&r,X"))]
257263d1a8abSmrg  ""
257363d1a8abSmrg  "#"
257463d1a8abSmrg  "reload_completed"
257563d1a8abSmrg  [(set (match_dup:DTI 0)
257663d1a8abSmrg	(lshiftrt:DTI (match_dup:DTI 1)
257763d1a8abSmrg		      (and:SI (neg:SI (match_dup:SI 3)) (const_int 7))))]
257863d1a8abSmrg  {
257963d1a8abSmrg    if (GET_CODE (operands[2]) == CONST_INT)
258063d1a8abSmrg      operands[3] = GEN_INT (-INTVAL (operands[2]));
258163d1a8abSmrg    else
258263d1a8abSmrg      emit_insn (gen_subsi3 (operands[3], GEN_INT (0), operands[2]));
258363d1a8abSmrg  }
258463d1a8abSmrg  [(set_attr "type" "shuf")])
258563d1a8abSmrg
258663d1a8abSmrg(define_insn "rotqmbi_<mode>"
258763d1a8abSmrg  [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
258863d1a8abSmrg	(lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
258963d1a8abSmrg		      (and:SI (neg:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I"))
259063d1a8abSmrg			      (const_int 7))))]
259163d1a8abSmrg  ""
259263d1a8abSmrg  "@
259363d1a8abSmrg   rotqmbi\t%0,%1,%2
259463d1a8abSmrg   rotqmbii\t%0,%1,-%E2"
259563d1a8abSmrg  [(set_attr "type" "shuf")])
259663d1a8abSmrg
259763d1a8abSmrg(define_expand "shrqby_<mode>"
259863d1a8abSmrg  [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
259963d1a8abSmrg	(lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
260063d1a8abSmrg		      (mult:SI (neg:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I"))
260163d1a8abSmrg			       (const_int 8))))]
260263d1a8abSmrg  ""
260363d1a8abSmrg  {
260463d1a8abSmrg    if (GET_CODE (operands[2]) == CONST_INT)
260563d1a8abSmrg      operands[2] = GEN_INT (-INTVAL (operands[2]));
260663d1a8abSmrg    else
260763d1a8abSmrg      {
260863d1a8abSmrg        rtx t0 = gen_reg_rtx (SImode);
260963d1a8abSmrg	emit_insn (gen_subsi3 (t0, GEN_INT (0), operands[2]));
261063d1a8abSmrg        operands[2] = t0;
261163d1a8abSmrg      }
261263d1a8abSmrg  })
261363d1a8abSmrg
261463d1a8abSmrg(define_insn "rotqmby_<mode>"
261563d1a8abSmrg  [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
261663d1a8abSmrg	(lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
261763d1a8abSmrg		      (mult:SI (neg:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I"))
261863d1a8abSmrg			       (const_int 8))))]
261963d1a8abSmrg  ""
262063d1a8abSmrg  "@
262163d1a8abSmrg   rotqmby\t%0,%1,%2
262263d1a8abSmrg   rotqmbyi\t%0,%1,-%F2"
262363d1a8abSmrg  [(set_attr "type" "shuf")])
262463d1a8abSmrg
262563d1a8abSmrg
262663d1a8abSmrg;; ashr, vashr
262763d1a8abSmrg
262863d1a8abSmrg(define_insn_and_split "<v>ashr<mode>3"
262963d1a8abSmrg  [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
263063d1a8abSmrg	(ashiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
263163d1a8abSmrg		       (match_operand:VHSI 2 "spu_nonmem_operand" "r,W")))
263263d1a8abSmrg   (clobber (match_scratch:VHSI 3 "=&r,X"))]
263363d1a8abSmrg  ""
263463d1a8abSmrg  "@
263563d1a8abSmrg   #
263663d1a8abSmrg   rotma<bh>i\t%0,%1,-%<umask>2"
263763d1a8abSmrg  "reload_completed && GET_CODE (operands[2]) == REG"
263863d1a8abSmrg  [(set (match_dup:VHSI 3)
263963d1a8abSmrg	(neg:VHSI (match_dup:VHSI 2)))
264063d1a8abSmrg   (set (match_dup:VHSI 0)
264163d1a8abSmrg	(ashiftrt:VHSI (match_dup:VHSI 1)
264263d1a8abSmrg		       (neg:VHSI (match_dup:VHSI 3))))]
264363d1a8abSmrg  ""
264463d1a8abSmrg  [(set_attr "type" "*,fx3")])
264563d1a8abSmrg
264663d1a8abSmrg(define_insn "<v>ashr<mode>3_imm"
264763d1a8abSmrg  [(set (match_operand:VHSI 0 "spu_reg_operand" "=r")
264863d1a8abSmrg	(ashiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r")
264963d1a8abSmrg		       (match_operand:VHSI 2 "immediate_operand" "W")))]
265063d1a8abSmrg  ""
265163d1a8abSmrg  "rotma<bh>i\t%0,%1,-%<umask>2"
265263d1a8abSmrg  [(set_attr "type" "fx3")])
265363d1a8abSmrg
265463d1a8abSmrg
265563d1a8abSmrg(define_insn "rotma_<mode>"
265663d1a8abSmrg  [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
265763d1a8abSmrg	(ashiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
265863d1a8abSmrg		       (neg:VHSI (match_operand:VHSI 2 "spu_nonmem_operand" "r,W"))))]
265963d1a8abSmrg  ""
266063d1a8abSmrg  "@
266163d1a8abSmrg   rotma<bh>\t%0,%1,%2
266263d1a8abSmrg   rotma<bh>i\t%0,%1,-%<nmask>2"
266363d1a8abSmrg  [(set_attr "type" "fx3")])
266463d1a8abSmrg
266563d1a8abSmrg(define_insn_and_split "ashrdi3"
266663d1a8abSmrg  [(set (match_operand:DI 0 "spu_reg_operand" "=r,r")
266763d1a8abSmrg        (ashiftrt:DI (match_operand:DI 1 "spu_reg_operand" "r,r")
266863d1a8abSmrg                     (match_operand:SI 2 "spu_nonmem_operand" "r,I")))
266963d1a8abSmrg   (clobber (match_scratch:TI 3 "=&r,&r"))
267063d1a8abSmrg   (clobber (match_scratch:TI 4 "=&r,&r"))
267163d1a8abSmrg   (clobber (match_scratch:SI 5 "=&r,&r"))]
267263d1a8abSmrg  ""
267363d1a8abSmrg  "#"
267463d1a8abSmrg  "reload_completed"
267563d1a8abSmrg  [(set (match_dup:DI 0)
267663d1a8abSmrg        (ashiftrt:DI (match_dup:DI 1)
267763d1a8abSmrg                     (match_dup:SI 2)))]
267863d1a8abSmrg  {
267963d1a8abSmrg    rtx op0 = gen_rtx_REG (TImode, REGNO (operands[0]));
268063d1a8abSmrg    rtx op0v = gen_rtx_REG (V4SImode, REGNO (op0));
268163d1a8abSmrg    rtx op1 = gen_rtx_REG (TImode, REGNO (operands[1]));
268263d1a8abSmrg    rtx op1s = gen_rtx_REG (SImode, REGNO (op1));
268363d1a8abSmrg    rtx op2 = operands[2];
268463d1a8abSmrg    rtx op3 = operands[3];
268563d1a8abSmrg    rtx op4 = operands[4];
268663d1a8abSmrg    rtx op5 = operands[5];
268763d1a8abSmrg
268863d1a8abSmrg    if (GET_CODE (op2) == CONST_INT && INTVAL (op2) >= 63)
268963d1a8abSmrg      {
269063d1a8abSmrg	rtx op0s = gen_rtx_REG (SImode, REGNO (op0));
269163d1a8abSmrg	emit_insn (gen_ashrsi3 (op0s, op1s, GEN_INT (32)));
269263d1a8abSmrg	emit_insn (gen_spu_fsm (op0v, op0s));
269363d1a8abSmrg      }
269463d1a8abSmrg    else if (GET_CODE (op2) == CONST_INT && INTVAL (op2) >= 32)
269563d1a8abSmrg      {
269663d1a8abSmrg	rtx op0d = gen_rtx_REG (V2DImode, REGNO (op0));
269763d1a8abSmrg	HOST_WIDE_INT val = INTVAL (op2);
269863d1a8abSmrg	emit_insn (gen_lshrti3 (op0, op1, GEN_INT (32)));
269963d1a8abSmrg	emit_insn (gen_spu_xswd (op0d, op0v));
270063d1a8abSmrg        if (val > 32)
270163d1a8abSmrg	  emit_insn (gen_vashrv4si3 (op0v, op0v, spu_const (V4SImode, val - 32)));
270263d1a8abSmrg      }
270363d1a8abSmrg    else
270463d1a8abSmrg      {
270563d1a8abSmrg	rtx op3v = gen_rtx_REG (V4SImode, REGNO (op3));
270663d1a8abSmrg	unsigned char arr[16] = {
270763d1a8abSmrg	  0xff, 0xff, 0xff, 0xff,
270863d1a8abSmrg	  0xff, 0xff, 0xff, 0xff,
270963d1a8abSmrg	  0x00, 0x00, 0x00, 0x00,
271063d1a8abSmrg	  0x00, 0x00, 0x00, 0x00
271163d1a8abSmrg	};
271263d1a8abSmrg
271363d1a8abSmrg	emit_insn (gen_ashrsi3 (op5, op1s, GEN_INT (31)));
271463d1a8abSmrg	emit_move_insn (op4, array_to_constant (TImode, arr));
271563d1a8abSmrg	emit_insn (gen_spu_fsm (op3v, op5));
271663d1a8abSmrg
271763d1a8abSmrg	if (GET_CODE (operands[2]) == REG)
271863d1a8abSmrg	  {
271963d1a8abSmrg	    emit_insn (gen_selb (op4, op3, op1, op4));
272063d1a8abSmrg	    emit_insn (gen_negsi2 (op5, op2));
272163d1a8abSmrg	    emit_insn (gen_rotqbybi_ti (op0, op4, op5));
272263d1a8abSmrg	    emit_insn (gen_rotqbi_ti (op0, op0, op5));
272363d1a8abSmrg	  }
272463d1a8abSmrg	else
272563d1a8abSmrg	  {
272663d1a8abSmrg	    HOST_WIDE_INT val = -INTVAL (op2);
272763d1a8abSmrg	    emit_insn (gen_selb (op0, op3, op1, op4));
272863d1a8abSmrg	    if ((val - 7) / 8)
272963d1a8abSmrg	      emit_insn (gen_rotqby_ti (op0, op0, GEN_INT ((val - 7) / 8)));
273063d1a8abSmrg	    if (val % 8)
273163d1a8abSmrg	      emit_insn (gen_rotqbi_ti (op0, op0, GEN_INT (val % 8)));
273263d1a8abSmrg	  }
273363d1a8abSmrg      }
273463d1a8abSmrg    DONE;
273563d1a8abSmrg  })
273663d1a8abSmrg
273763d1a8abSmrg
273863d1a8abSmrg(define_insn_and_split "ashrti3"
273963d1a8abSmrg  [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
274063d1a8abSmrg	(ashiftrt:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
274163d1a8abSmrg		     (match_operand:SI 2 "spu_nonmem_operand" "r,i")))]
274263d1a8abSmrg  ""
274363d1a8abSmrg  "#"
274463d1a8abSmrg  ""
274563d1a8abSmrg  [(set (match_dup:TI 0)
274663d1a8abSmrg	(ashiftrt:TI (match_dup:TI 1)
274763d1a8abSmrg		     (match_dup:SI 2)))]
274863d1a8abSmrg  {
274963d1a8abSmrg    rtx sign_shift = gen_reg_rtx (SImode);
275063d1a8abSmrg    rtx sign_mask = gen_reg_rtx (TImode);
275163d1a8abSmrg    rtx sign_mask_v4si = gen_rtx_SUBREG (V4SImode, sign_mask, 0);
275263d1a8abSmrg    rtx op1_v4si = spu_gen_subreg (V4SImode, operands[1]);
275363d1a8abSmrg    rtx t = gen_reg_rtx (TImode);
275463d1a8abSmrg    emit_insn (gen_subsi3 (sign_shift, GEN_INT (128), force_reg (SImode, operands[2])));
275563d1a8abSmrg    emit_insn (gen_vashrv4si3 (sign_mask_v4si, op1_v4si, spu_const (V4SImode, 31)));
275663d1a8abSmrg    emit_insn (gen_fsm_ti (sign_mask, sign_mask));
275763d1a8abSmrg    emit_insn (gen_ashlti3 (sign_mask, sign_mask, sign_shift));
275863d1a8abSmrg    emit_insn (gen_lshrti3 (t, operands[1], operands[2]));
275963d1a8abSmrg    emit_insn (gen_iorti3 (operands[0], t, sign_mask));
276063d1a8abSmrg    DONE;
276163d1a8abSmrg  })
276263d1a8abSmrg
276363d1a8abSmrg;; fsm is used after rotam to replicate the sign across the whole register.
276463d1a8abSmrg(define_insn "fsm_ti"
276563d1a8abSmrg  [(set (match_operand:TI 0 "spu_reg_operand" "=r")
276663d1a8abSmrg	(unspec:TI [(match_operand:TI 1 "spu_reg_operand" "r")] UNSPEC_FSM))]
276763d1a8abSmrg  ""
276863d1a8abSmrg  "fsm\t%0,%1"
276963d1a8abSmrg  [(set_attr "type" "shuf")])
277063d1a8abSmrg
277163d1a8abSmrg
277263d1a8abSmrg;; vrotl, rotl
277363d1a8abSmrg
277463d1a8abSmrg(define_insn "<v>rotl<mode>3"
277563d1a8abSmrg  [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
277663d1a8abSmrg	(rotate:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
277763d1a8abSmrg		     (match_operand:VHSI 2 "spu_nonmem_operand" "r,W")))]
277863d1a8abSmrg  ""
277963d1a8abSmrg  "@
278063d1a8abSmrg  rot<bh>\t%0,%1,%2
278163d1a8abSmrg  rot<bh>i\t%0,%1,%<umask>2"
278263d1a8abSmrg  [(set_attr "type" "fx3")])
278363d1a8abSmrg
278463d1a8abSmrg(define_insn "rotlti3"
278563d1a8abSmrg  [(set (match_operand:TI 0 "spu_reg_operand" "=&r,r,r,r")
278663d1a8abSmrg	(rotate:TI (match_operand:TI 1 "spu_reg_operand" "r,r,r,r")
278763d1a8abSmrg		   (match_operand:SI 2 "spu_nonmem_operand" "r,O,P,I")))]
278863d1a8abSmrg  ""
278963d1a8abSmrg  "@
279063d1a8abSmrg  rotqbybi\t%0,%1,%2\;rotqbi\t%0,%0,%2
279163d1a8abSmrg  rotqbyi\t%0,%1,%h2
279263d1a8abSmrg  rotqbii\t%0,%1,%e2
279363d1a8abSmrg  rotqbyi\t%0,%1,%h2\;rotqbii\t%0,%0,%e2"
279463d1a8abSmrg  [(set_attr "length" "8,4,4,8")
279563d1a8abSmrg   (set_attr "type" "multi1,shuf,shuf,multi1")])
279663d1a8abSmrg
279763d1a8abSmrg(define_insn "rotqbybi_ti"
279863d1a8abSmrg  [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
279963d1a8abSmrg	(rotate:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
280063d1a8abSmrg		   (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
280163d1a8abSmrg			   (const_int -8))))]
280263d1a8abSmrg  ""
280363d1a8abSmrg  "@
280463d1a8abSmrg  rotqbybi\t%0,%1,%2
280563d1a8abSmrg  rotqbyi\t%0,%1,%h2"
280663d1a8abSmrg  [(set_attr "type" "shuf,shuf")])
280763d1a8abSmrg
280863d1a8abSmrg(define_insn "rotqby_ti"
280963d1a8abSmrg  [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
281063d1a8abSmrg	(rotate:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
281163d1a8abSmrg		   (mult:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
281263d1a8abSmrg			    (const_int 8))))]
281363d1a8abSmrg  ""
281463d1a8abSmrg  "@
281563d1a8abSmrg  rotqby\t%0,%1,%2
281663d1a8abSmrg  rotqbyi\t%0,%1,%f2"
281763d1a8abSmrg  [(set_attr "type" "shuf,shuf")])
281863d1a8abSmrg
281963d1a8abSmrg(define_insn "rotqbi_ti"
282063d1a8abSmrg  [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
282163d1a8abSmrg	(rotate:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
282263d1a8abSmrg		   (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
282363d1a8abSmrg			   (const_int 7))))]
282463d1a8abSmrg  ""
282563d1a8abSmrg  "@
282663d1a8abSmrg  rotqbi\t%0,%1,%2
282763d1a8abSmrg  rotqbii\t%0,%1,%e2"
282863d1a8abSmrg  [(set_attr "type" "shuf,shuf")])
282963d1a8abSmrg
283063d1a8abSmrg
283163d1a8abSmrg;; struct extract/insert
283263d1a8abSmrg;; We handle mem's because GCC will generate invalid SUBREG's
283363d1a8abSmrg;; and inefficient code.
283463d1a8abSmrg
283563d1a8abSmrg(define_expand "extv"
283663d1a8abSmrg  [(set (match_operand:TI 0 "register_operand" "")
283763d1a8abSmrg	(sign_extract:TI (match_operand 1 "nonimmediate_operand" "")
283863d1a8abSmrg			 (match_operand:SI 2 "const_int_operand" "")
283963d1a8abSmrg			 (match_operand:SI 3 "const_int_operand" "")))]
284063d1a8abSmrg  ""
284163d1a8abSmrg  {
284263d1a8abSmrg    spu_expand_extv (operands, 0);
284363d1a8abSmrg    DONE;
284463d1a8abSmrg  })
284563d1a8abSmrg
284663d1a8abSmrg(define_expand "extzv"
284763d1a8abSmrg  [(set (match_operand:TI 0 "register_operand" "")
284863d1a8abSmrg	(zero_extract:TI (match_operand 1 "nonimmediate_operand" "")
284963d1a8abSmrg			 (match_operand:SI 2 "const_int_operand" "")
285063d1a8abSmrg			 (match_operand:SI 3 "const_int_operand" "")))]
285163d1a8abSmrg  ""
285263d1a8abSmrg  {
285363d1a8abSmrg    spu_expand_extv (operands, 1);
285463d1a8abSmrg    DONE;
285563d1a8abSmrg  })
285663d1a8abSmrg
285763d1a8abSmrg(define_expand "insv"
285863d1a8abSmrg  [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
285963d1a8abSmrg		      (match_operand:SI 1 "const_int_operand" "")
286063d1a8abSmrg		      (match_operand:SI 2 "const_int_operand" ""))
286163d1a8abSmrg	(match_operand 3 "nonmemory_operand" ""))]
286263d1a8abSmrg  ""
286363d1a8abSmrg  {
286463d1a8abSmrg    if (INTVAL (operands[1]) + INTVAL (operands[2])
286563d1a8abSmrg        > GET_MODE_BITSIZE (GET_MODE (operands[0])))
286663d1a8abSmrg      FAIL;
286763d1a8abSmrg    spu_expand_insv(operands);
286863d1a8abSmrg    DONE;
286963d1a8abSmrg  })
287063d1a8abSmrg
287163d1a8abSmrg;; Simplify a number of patterns that get generated by extv, extzv,
287263d1a8abSmrg;; insv, and loads.
287363d1a8abSmrg(define_insn_and_split "trunc_shr_ti<mode>"
287463d1a8abSmrg  [(set (match_operand:QHSI 0 "spu_reg_operand" "=r")
287563d1a8abSmrg        (truncate:QHSI (match_operator:TI 2 "shiftrt_operator" [(match_operand:TI 1 "spu_reg_operand" "0")
287663d1a8abSmrg								(const_int 96)])))]
287763d1a8abSmrg  ""
287863d1a8abSmrg  "#"
287963d1a8abSmrg  "reload_completed"
288063d1a8abSmrg  [(const_int 0)]
288163d1a8abSmrg  {
288263d1a8abSmrg    spu_split_convert (operands);
288363d1a8abSmrg    DONE;
288463d1a8abSmrg  }
288563d1a8abSmrg  [(set_attr "type" "convert")
288663d1a8abSmrg   (set_attr "length" "0")])
288763d1a8abSmrg
288863d1a8abSmrg(define_insn_and_split "trunc_shr_tidi"
288963d1a8abSmrg  [(set (match_operand:DI 0 "spu_reg_operand" "=r")
289063d1a8abSmrg        (truncate:DI (match_operator:TI 2 "shiftrt_operator" [(match_operand:TI 1 "spu_reg_operand" "0")
289163d1a8abSmrg							      (const_int 64)])))]
289263d1a8abSmrg  ""
289363d1a8abSmrg  "#"
289463d1a8abSmrg  "reload_completed"
289563d1a8abSmrg  [(const_int 0)]
289663d1a8abSmrg  {
289763d1a8abSmrg    spu_split_convert (operands);
289863d1a8abSmrg    DONE;
289963d1a8abSmrg  }
290063d1a8abSmrg  [(set_attr "type" "convert")
290163d1a8abSmrg   (set_attr "length" "0")])
290263d1a8abSmrg
290363d1a8abSmrg(define_insn_and_split "shl_ext_<mode>ti"
290463d1a8abSmrg  [(set (match_operand:TI 0 "spu_reg_operand" "=r")
290563d1a8abSmrg        (ashift:TI (match_operator:TI 2 "extend_operator" [(match_operand:QHSI 1 "spu_reg_operand" "0")])
290663d1a8abSmrg		   (const_int 96)))]
290763d1a8abSmrg  ""
290863d1a8abSmrg  "#"
290963d1a8abSmrg  "reload_completed"
291063d1a8abSmrg  [(const_int 0)]
291163d1a8abSmrg  {
291263d1a8abSmrg    spu_split_convert (operands);
291363d1a8abSmrg    DONE;
291463d1a8abSmrg  }
291563d1a8abSmrg  [(set_attr "type" "convert")
291663d1a8abSmrg   (set_attr "length" "0")])
291763d1a8abSmrg
291863d1a8abSmrg(define_insn_and_split "shl_ext_diti"
291963d1a8abSmrg  [(set (match_operand:TI 0 "spu_reg_operand" "=r")
292063d1a8abSmrg        (ashift:TI (match_operator:TI 2 "extend_operator" [(match_operand:DI 1 "spu_reg_operand" "0")])
292163d1a8abSmrg		   (const_int 64)))]
292263d1a8abSmrg  ""
292363d1a8abSmrg  "#"
292463d1a8abSmrg  "reload_completed"
292563d1a8abSmrg  [(const_int 0)]
292663d1a8abSmrg  {
292763d1a8abSmrg    spu_split_convert (operands);
292863d1a8abSmrg    DONE;
292963d1a8abSmrg  }
293063d1a8abSmrg  [(set_attr "type" "convert")
293163d1a8abSmrg   (set_attr "length" "0")])
293263d1a8abSmrg
293363d1a8abSmrg(define_insn "sext_trunc_lshr_tiqisi"
293463d1a8abSmrg  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
293563d1a8abSmrg        (sign_extend:SI (truncate:QI (match_operator:TI 2 "shiftrt_operator" [(match_operand:TI 1 "spu_reg_operand" "r")
293663d1a8abSmrg									      (const_int 120)]))))]
293763d1a8abSmrg  ""
293863d1a8abSmrg  "rotmai\t%0,%1,-24"
293963d1a8abSmrg  [(set_attr "type" "fx3")])
294063d1a8abSmrg
294163d1a8abSmrg(define_insn "zext_trunc_lshr_tiqisi"
294263d1a8abSmrg  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
294363d1a8abSmrg        (zero_extend:SI (truncate:QI (match_operator:TI 2 "shiftrt_operator" [(match_operand:TI 1 "spu_reg_operand" "r")
294463d1a8abSmrg									      (const_int 120)]))))]
294563d1a8abSmrg  ""
294663d1a8abSmrg  "rotmi\t%0,%1,-24"
294763d1a8abSmrg  [(set_attr "type" "fx3")])
294863d1a8abSmrg
294963d1a8abSmrg(define_insn "sext_trunc_lshr_tihisi"
295063d1a8abSmrg  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
295163d1a8abSmrg        (sign_extend:SI (truncate:HI (match_operator:TI 2 "shiftrt_operator" [(match_operand:TI 1 "spu_reg_operand" "r")
295263d1a8abSmrg									      (const_int 112)]))))]
295363d1a8abSmrg  ""
295463d1a8abSmrg  "rotmai\t%0,%1,-16"
295563d1a8abSmrg  [(set_attr "type" "fx3")])
295663d1a8abSmrg
295763d1a8abSmrg(define_insn "zext_trunc_lshr_tihisi"
295863d1a8abSmrg  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
295963d1a8abSmrg        (zero_extend:SI (truncate:HI (match_operator:TI 2 "shiftrt_operator" [(match_operand:TI 1 "spu_reg_operand" "r")
296063d1a8abSmrg									      (const_int 112)]))))]
296163d1a8abSmrg  ""
296263d1a8abSmrg  "rotmi\t%0,%1,-16"
296363d1a8abSmrg  [(set_attr "type" "fx3")])
296463d1a8abSmrg
296563d1a8abSmrg
296663d1a8abSmrg;; String/block move insn.
296763d1a8abSmrg;; Argument 0 is the destination
296863d1a8abSmrg;; Argument 1 is the source
296963d1a8abSmrg;; Argument 2 is the length
297063d1a8abSmrg;; Argument 3 is the alignment
297163d1a8abSmrg
297263d1a8abSmrg(define_expand "movstrsi"
297363d1a8abSmrg  [(parallel [(set (match_operand:BLK 0 "" "")
297463d1a8abSmrg		   (match_operand:BLK 1 "" ""))
297563d1a8abSmrg	      (use (match_operand:SI 2 "" ""))
297663d1a8abSmrg	      (use (match_operand:SI 3 "" ""))])]
297763d1a8abSmrg  ""
297863d1a8abSmrg  "
297963d1a8abSmrg  {
298063d1a8abSmrg    if (spu_expand_block_move (operands))
298163d1a8abSmrg      DONE;
298263d1a8abSmrg    else
298363d1a8abSmrg      FAIL;
298463d1a8abSmrg  }")
298563d1a8abSmrg
298663d1a8abSmrg
298763d1a8abSmrg;; jump
298863d1a8abSmrg
298963d1a8abSmrg(define_insn "indirect_jump"
299063d1a8abSmrg  [(set (pc) (match_operand:SI 0 "spu_reg_operand" "r"))]
299163d1a8abSmrg  ""
299263d1a8abSmrg  "bi\t%0"
299363d1a8abSmrg  [(set_attr "type" "br")])
299463d1a8abSmrg
299563d1a8abSmrg(define_insn "jump"
299663d1a8abSmrg  [(set (pc)
299763d1a8abSmrg	(label_ref (match_operand 0 "" "")))]
299863d1a8abSmrg  ""
299963d1a8abSmrg  "br\t%0"
300063d1a8abSmrg  [(set_attr "type" "br")])
300163d1a8abSmrg
300263d1a8abSmrg
300363d1a8abSmrg;; return
300463d1a8abSmrg
300563d1a8abSmrg;; This will be used for leaf functions, that don't save any regs and
300663d1a8abSmrg;; don't have locals on stack, maybe... that is for functions that
300763d1a8abSmrg;; don't change $sp and don't need to save $lr.
300863d1a8abSmrg(define_expand "return"
300963d1a8abSmrg    [(return)]
301063d1a8abSmrg  "direct_return()"
301163d1a8abSmrg  "")
301263d1a8abSmrg
301363d1a8abSmrg;; used in spu_expand_epilogue to generate return from a function and
301463d1a8abSmrg;; explicitly set use of $lr.
301563d1a8abSmrg
301663d1a8abSmrg(define_insn "_return"
301763d1a8abSmrg  [(return)]
301863d1a8abSmrg  ""
301963d1a8abSmrg  "bi\t$lr"
302063d1a8abSmrg  [(set_attr "type" "br")])
302163d1a8abSmrg
302263d1a8abSmrg
302363d1a8abSmrg
302463d1a8abSmrg;; ceq
302563d1a8abSmrg
302663d1a8abSmrg(define_insn "ceq_<mode>"
302763d1a8abSmrg  [(set (match_operand:VQHSI 0 "spu_reg_operand" "=r,r")
302863d1a8abSmrg	(eq:VQHSI (match_operand:VQHSI 1 "spu_reg_operand" "r,r")
302963d1a8abSmrg	         (match_operand:VQHSI 2 "spu_arith_operand" "r,B")))]
303063d1a8abSmrg  ""
303163d1a8abSmrg  "@
303263d1a8abSmrg  ceq<bh>\t%0,%1,%2
303363d1a8abSmrg  ceq<bh>i\t%0,%1,%2")
303463d1a8abSmrg
303563d1a8abSmrg(define_insn_and_split "ceq_di"
303663d1a8abSmrg  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
303763d1a8abSmrg        (eq:SI (match_operand:DI 1 "spu_reg_operand" "r")
303863d1a8abSmrg	       (match_operand:DI 2 "spu_reg_operand" "r")))]
303963d1a8abSmrg  ""
304063d1a8abSmrg  "#"
304163d1a8abSmrg  "reload_completed"
304263d1a8abSmrg  [(set (match_dup:SI 0)
304363d1a8abSmrg        (eq:SI (match_dup:DI 1)
304463d1a8abSmrg	       (match_dup:DI 2)))]
304563d1a8abSmrg  {
304663d1a8abSmrg    rtx op0 = gen_rtx_REG (V4SImode, REGNO (operands[0]));
304763d1a8abSmrg    rtx op1 = gen_rtx_REG (V4SImode, REGNO (operands[1]));
304863d1a8abSmrg    rtx op2 = gen_rtx_REG (V4SImode, REGNO (operands[2]));
304963d1a8abSmrg    emit_insn (gen_ceq_v4si (op0, op1, op2));
305063d1a8abSmrg    emit_insn (gen_spu_gb (op0, op0));
305163d1a8abSmrg    emit_insn (gen_cgt_si (operands[0], operands[0], GEN_INT (11)));
305263d1a8abSmrg    DONE;
305363d1a8abSmrg  })
305463d1a8abSmrg
305563d1a8abSmrg
305663d1a8abSmrg;; We provide the TI compares for completeness and because some parts of
305763d1a8abSmrg;; gcc/libgcc use them, even though user code might never see it.
305863d1a8abSmrg(define_insn "ceq_ti"
305963d1a8abSmrg  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
306063d1a8abSmrg	(eq:SI (match_operand:TI 1 "spu_reg_operand" "r")
306163d1a8abSmrg	       (match_operand:TI 2 "spu_reg_operand" "r")))]
306263d1a8abSmrg  ""
306363d1a8abSmrg  "ceq\t%0,%1,%2\;gb\t%0,%0\;ceqi\t%0,%0,15"
306463d1a8abSmrg  [(set_attr "type" "multi0")
306563d1a8abSmrg   (set_attr "length" "12")])
306663d1a8abSmrg
306763d1a8abSmrg(define_insn "ceq_<mode>"
306863d1a8abSmrg  [(set (match_operand:<F2I> 0 "spu_reg_operand" "=r")
306963d1a8abSmrg	(eq:<F2I> (match_operand:VSF 1 "spu_reg_operand" "r")
307063d1a8abSmrg		  (match_operand:VSF 2 "spu_reg_operand" "r")))]
307163d1a8abSmrg  ""
307263d1a8abSmrg  "fceq\t%0,%1,%2")
307363d1a8abSmrg
307463d1a8abSmrg(define_insn "cmeq_<mode>"
307563d1a8abSmrg  [(set (match_operand:<F2I> 0 "spu_reg_operand" "=r")
307663d1a8abSmrg	(eq:<F2I> (abs:VSF (match_operand:VSF 1 "spu_reg_operand" "r"))
307763d1a8abSmrg	          (abs:VSF (match_operand:VSF 2 "spu_reg_operand" "r"))))]
307863d1a8abSmrg  ""
307963d1a8abSmrg  "fcmeq\t%0,%1,%2")
308063d1a8abSmrg
308163d1a8abSmrg;; These implementations will ignore checking of NaN or INF if
308263d1a8abSmrg;; compiled with option -ffinite-math-only.
308363d1a8abSmrg(define_expand "ceq_df"
308463d1a8abSmrg  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
308563d1a8abSmrg        (eq:SI (match_operand:DF 1 "spu_reg_operand" "r")
308663d1a8abSmrg               (match_operand:DF 2 "const_zero_operand" "i")))]
308763d1a8abSmrg  ""
308863d1a8abSmrg{
308963d1a8abSmrg  if (spu_arch == PROCESSOR_CELL)
309063d1a8abSmrg      {
309163d1a8abSmrg        rtx ra = gen_reg_rtx (V4SImode);
309263d1a8abSmrg        rtx rb = gen_reg_rtx (V4SImode);
309363d1a8abSmrg        rtx temp = gen_reg_rtx (TImode);
309463d1a8abSmrg        rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
309563d1a8abSmrg        rtx temp2 = gen_reg_rtx (V4SImode);
309663d1a8abSmrg        rtx biteq = gen_reg_rtx (V4SImode);
309763d1a8abSmrg        rtx ahi_inf = gen_reg_rtx (V4SImode);
309863d1a8abSmrg        rtx a_nan = gen_reg_rtx (V4SImode);
309963d1a8abSmrg        rtx a_abs = gen_reg_rtx (V4SImode);
310063d1a8abSmrg        rtx b_abs = gen_reg_rtx (V4SImode);
310163d1a8abSmrg        rtx iszero = gen_reg_rtx (V4SImode);
310263d1a8abSmrg        rtx sign_mask = gen_reg_rtx (V4SImode);
310363d1a8abSmrg        rtx nan_mask = gen_reg_rtx (V4SImode);
310463d1a8abSmrg        rtx hihi_promote = gen_reg_rtx (TImode);
310563d1a8abSmrg        rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF,
310663d1a8abSmrg                                                 0x7FFFFFFF, 0xFFFFFFFF);
310763d1a8abSmrg
310863d1a8abSmrg        emit_move_insn (sign_mask, pat);
310963d1a8abSmrg        pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0,
311063d1a8abSmrg                                             0x7FF00000, 0x0);
311163d1a8abSmrg        emit_move_insn (nan_mask, pat);
311263d1a8abSmrg        pat = spu_const_from_ints (TImode, 0x00010203, 0x10111213,
311363d1a8abSmrg                                           0x08090A0B, 0x18191A1B);
311463d1a8abSmrg        emit_move_insn (hihi_promote, pat);
311563d1a8abSmrg
311663d1a8abSmrg        emit_insn (gen_spu_convert (ra, operands[1]));
311763d1a8abSmrg        emit_insn (gen_spu_convert (rb, operands[2]));
311863d1a8abSmrg        emit_insn (gen_ceq_v4si (biteq, ra, rb));
311963d1a8abSmrg        emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, biteq),
312063d1a8abSmrg				GEN_INT (4 * 8)));
312163d1a8abSmrg        emit_insn (gen_andv4si3 (biteq, biteq, temp_v4si));
312263d1a8abSmrg
312363d1a8abSmrg        emit_insn (gen_andv4si3 (a_abs, ra, sign_mask));
312463d1a8abSmrg        emit_insn (gen_andv4si3 (b_abs, rb, sign_mask));
312563d1a8abSmrg	if (!flag_finite_math_only)
312663d1a8abSmrg          {
312763d1a8abSmrg            emit_insn (gen_clgt_v4si (a_nan, a_abs, nan_mask));
312863d1a8abSmrg            emit_insn (gen_ceq_v4si (ahi_inf, a_abs, nan_mask));
312963d1a8abSmrg            emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, a_nan),
313063d1a8abSmrg                                   GEN_INT (4 * 8)));
313163d1a8abSmrg            emit_insn (gen_andv4si3 (temp2, temp_v4si, ahi_inf));
313263d1a8abSmrg            emit_insn (gen_iorv4si3 (a_nan, a_nan, temp2));
313363d1a8abSmrg	  }
313463d1a8abSmrg        emit_insn (gen_iorv4si3 (temp2, a_abs, b_abs));
313563d1a8abSmrg        emit_insn (gen_ceq_v4si (iszero, temp2, CONST0_RTX (V4SImode)));
313663d1a8abSmrg        emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, iszero),
313763d1a8abSmrg				GEN_INT (4 * 8)));
313863d1a8abSmrg        emit_insn (gen_andv4si3 (iszero, iszero, temp_v4si));
313963d1a8abSmrg        emit_insn (gen_iorv4si3 (temp2, biteq, iszero));
314063d1a8abSmrg	if (!flag_finite_math_only)
314163d1a8abSmrg          {
314263d1a8abSmrg            emit_insn (gen_andc_v4si (temp2, temp2, a_nan));
314363d1a8abSmrg	  }
314463d1a8abSmrg        emit_insn (gen_shufb (operands[0], temp2, temp2, hihi_promote));
314563d1a8abSmrg        DONE;
314663d1a8abSmrg      }
314763d1a8abSmrg})
314863d1a8abSmrg
314963d1a8abSmrg(define_insn "ceq_<mode>_celledp"
315063d1a8abSmrg  [(set (match_operand:<DF2I> 0 "spu_reg_operand" "=r")
315163d1a8abSmrg        (eq:<DF2I> (match_operand:VDF 1 "spu_reg_operand" "r")
315263d1a8abSmrg                   (match_operand:VDF 2 "spu_reg_operand" "r")))]
315363d1a8abSmrg  "spu_arch == PROCESSOR_CELLEDP"
315463d1a8abSmrg  "dfceq\t%0,%1,%2"
315563d1a8abSmrg  [(set_attr "type" "fpd")])
315663d1a8abSmrg
315763d1a8abSmrg(define_insn "cmeq_<mode>_celledp"
315863d1a8abSmrg  [(set (match_operand:<DF2I> 0 "spu_reg_operand" "=r")
315963d1a8abSmrg        (eq:<DF2I> (abs:VDF (match_operand:VDF 1 "spu_reg_operand" "r"))
316063d1a8abSmrg                   (abs:VDF (match_operand:VDF 2 "spu_reg_operand" "r"))))]
316163d1a8abSmrg  "spu_arch == PROCESSOR_CELLEDP"
316263d1a8abSmrg  "dfcmeq\t%0,%1,%2"
316363d1a8abSmrg  [(set_attr "type" "fpd")])
316463d1a8abSmrg
316563d1a8abSmrg(define_expand "ceq_v2df"
316663d1a8abSmrg  [(set (match_operand:V2DI 0 "spu_reg_operand" "=r")
316763d1a8abSmrg        (eq:V2DI (match_operand:V2DF 1 "spu_reg_operand" "r")
316863d1a8abSmrg                 (match_operand:V2DF 2 "spu_reg_operand" "r")))]
316963d1a8abSmrg  ""
317063d1a8abSmrg{
317163d1a8abSmrg  if (spu_arch == PROCESSOR_CELL)
317263d1a8abSmrg    {
317363d1a8abSmrg      rtx ra = spu_gen_subreg (V4SImode, operands[1]);
317463d1a8abSmrg      rtx rb = spu_gen_subreg (V4SImode, operands[2]);
317563d1a8abSmrg      rtx temp = gen_reg_rtx (TImode);
317663d1a8abSmrg      rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
317763d1a8abSmrg      rtx temp2 = gen_reg_rtx (V4SImode);
317863d1a8abSmrg      rtx biteq = gen_reg_rtx (V4SImode);
317963d1a8abSmrg      rtx ahi_inf = gen_reg_rtx (V4SImode);
318063d1a8abSmrg      rtx a_nan = gen_reg_rtx (V4SImode);
318163d1a8abSmrg      rtx a_abs = gen_reg_rtx (V4SImode);
318263d1a8abSmrg      rtx b_abs = gen_reg_rtx (V4SImode);
318363d1a8abSmrg      rtx iszero = gen_reg_rtx (V4SImode);
318463d1a8abSmrg      rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF,
318563d1a8abSmrg                                               0x7FFFFFFF, 0xFFFFFFFF);
318663d1a8abSmrg      rtx sign_mask = gen_reg_rtx (V4SImode);
318763d1a8abSmrg      rtx nan_mask = gen_reg_rtx (V4SImode);
318863d1a8abSmrg      rtx hihi_promote = gen_reg_rtx (TImode);
318963d1a8abSmrg
319063d1a8abSmrg      emit_move_insn (sign_mask, pat);
319163d1a8abSmrg      pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0,
319263d1a8abSmrg					     0x7FF00000, 0x0);
319363d1a8abSmrg      emit_move_insn (nan_mask, pat);
319463d1a8abSmrg      pat = spu_const_from_ints (TImode, 0x00010203, 0x10111213,
319563d1a8abSmrg					   0x08090A0B, 0x18191A1B);
319663d1a8abSmrg      emit_move_insn (hihi_promote, pat);
319763d1a8abSmrg
319863d1a8abSmrg      emit_insn (gen_ceq_v4si (biteq, ra, rb));
319963d1a8abSmrg      emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, biteq),
320063d1a8abSmrg                              GEN_INT (4 * 8)));
320163d1a8abSmrg      emit_insn (gen_andv4si3 (biteq, biteq, temp_v4si));
320263d1a8abSmrg      emit_insn (gen_andv4si3 (a_abs, ra, sign_mask));
320363d1a8abSmrg      emit_insn (gen_andv4si3 (b_abs, rb, sign_mask));
320463d1a8abSmrg      emit_insn (gen_clgt_v4si (a_nan, a_abs, nan_mask));
320563d1a8abSmrg      emit_insn (gen_ceq_v4si (ahi_inf, a_abs, nan_mask));
320663d1a8abSmrg      emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, a_nan),
320763d1a8abSmrg                              GEN_INT (4 * 8)));
320863d1a8abSmrg      emit_insn (gen_andv4si3 (temp2, temp_v4si, ahi_inf));
320963d1a8abSmrg      emit_insn (gen_iorv4si3 (a_nan, a_nan, temp2));
321063d1a8abSmrg      emit_insn (gen_iorv4si3 (temp2, a_abs, b_abs));
321163d1a8abSmrg      emit_insn (gen_ceq_v4si (iszero, temp2, CONST0_RTX (V4SImode)));
321263d1a8abSmrg      emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, iszero),
321363d1a8abSmrg                              GEN_INT (4 * 8)));
321463d1a8abSmrg      emit_insn (gen_andv4si3 (iszero, iszero, temp_v4si));
321563d1a8abSmrg      emit_insn (gen_iorv4si3 (temp2, biteq, iszero));
321663d1a8abSmrg      emit_insn (gen_andc_v4si (temp2, temp2, a_nan));
321763d1a8abSmrg      emit_insn (gen_shufb (operands[0], temp2, temp2, hihi_promote));
321863d1a8abSmrg      DONE;
321963d1a8abSmrg  }
322063d1a8abSmrg})
322163d1a8abSmrg
322263d1a8abSmrg(define_expand "cmeq_v2df"
322363d1a8abSmrg  [(set (match_operand:V2DI 0 "spu_reg_operand" "=r")
322463d1a8abSmrg        (eq:V2DI (abs:V2DF (match_operand:V2DF 1 "spu_reg_operand" "r"))
322563d1a8abSmrg                 (abs:V2DF (match_operand:V2DF 2 "spu_reg_operand" "r"))))]
322663d1a8abSmrg  ""
322763d1a8abSmrg{
322863d1a8abSmrg  if (spu_arch == PROCESSOR_CELL)
322963d1a8abSmrg    {
323063d1a8abSmrg      rtx ra = spu_gen_subreg (V4SImode, operands[1]);
323163d1a8abSmrg      rtx rb = spu_gen_subreg (V4SImode, operands[2]);
323263d1a8abSmrg      rtx temp = gen_reg_rtx (TImode);
323363d1a8abSmrg      rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
323463d1a8abSmrg      rtx temp2 = gen_reg_rtx (V4SImode);
323563d1a8abSmrg      rtx biteq = gen_reg_rtx (V4SImode);
323663d1a8abSmrg      rtx ahi_inf = gen_reg_rtx (V4SImode);
323763d1a8abSmrg      rtx a_nan = gen_reg_rtx (V4SImode);
323863d1a8abSmrg      rtx a_abs = gen_reg_rtx (V4SImode);
323963d1a8abSmrg      rtx b_abs = gen_reg_rtx (V4SImode);
324063d1a8abSmrg
324163d1a8abSmrg      rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF,
324263d1a8abSmrg                                               0x7FFFFFFF, 0xFFFFFFFF);
324363d1a8abSmrg      rtx sign_mask = gen_reg_rtx (V4SImode);
324463d1a8abSmrg      rtx nan_mask = gen_reg_rtx (V4SImode);
324563d1a8abSmrg      rtx hihi_promote = gen_reg_rtx (TImode);
324663d1a8abSmrg
324763d1a8abSmrg      emit_move_insn (sign_mask, pat);
324863d1a8abSmrg
324963d1a8abSmrg      pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0,
325063d1a8abSmrg                                           0x7FF00000, 0x0);
325163d1a8abSmrg      emit_move_insn (nan_mask, pat);
325263d1a8abSmrg      pat = spu_const_from_ints (TImode, 0x00010203, 0x10111213,
325363d1a8abSmrg                                         0x08090A0B, 0x18191A1B);
325463d1a8abSmrg      emit_move_insn (hihi_promote, pat);
325563d1a8abSmrg
325663d1a8abSmrg      emit_insn (gen_andv4si3 (a_abs, ra, sign_mask));
325763d1a8abSmrg      emit_insn (gen_andv4si3 (b_abs, rb, sign_mask));
325863d1a8abSmrg      emit_insn (gen_ceq_v4si (biteq, a_abs, b_abs));
325963d1a8abSmrg      emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, biteq),
326063d1a8abSmrg                                                    GEN_INT (4 * 8)));
326163d1a8abSmrg      emit_insn (gen_andv4si3 (biteq, biteq, temp_v4si));
326263d1a8abSmrg      emit_insn (gen_clgt_v4si (a_nan, a_abs, nan_mask));
326363d1a8abSmrg      emit_insn (gen_ceq_v4si (ahi_inf, a_abs, nan_mask));
326463d1a8abSmrg      emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, a_nan),
326563d1a8abSmrg                                                    GEN_INT (4 * 8)));
326663d1a8abSmrg      emit_insn (gen_andv4si3 (temp2, temp_v4si, ahi_inf));
326763d1a8abSmrg      emit_insn (gen_iorv4si3 (a_nan, a_nan, temp2));
326863d1a8abSmrg      emit_insn (gen_andc_v4si (temp2, biteq, a_nan));
326963d1a8abSmrg      emit_insn (gen_shufb (operands[0], temp2, temp2, hihi_promote));
327063d1a8abSmrg      DONE;
327163d1a8abSmrg  }
327263d1a8abSmrg})
327363d1a8abSmrg
327463d1a8abSmrg
327563d1a8abSmrg;; cgt
327663d1a8abSmrg
327763d1a8abSmrg(define_insn "cgt_<mode>"
327863d1a8abSmrg  [(set (match_operand:VQHSI 0 "spu_reg_operand" "=r,r")
327963d1a8abSmrg	(gt:VQHSI (match_operand:VQHSI 1 "spu_reg_operand" "r,r")
328063d1a8abSmrg	          (match_operand:VQHSI 2 "spu_arith_operand" "r,B")))]
328163d1a8abSmrg  ""
328263d1a8abSmrg  "@
328363d1a8abSmrg  cgt<bh>\t%0,%1,%2
328463d1a8abSmrg  cgt<bh>i\t%0,%1,%2")
328563d1a8abSmrg
328663d1a8abSmrg(define_insn "cgt_di_m1"
328763d1a8abSmrg  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
328863d1a8abSmrg	(gt:SI (match_operand:DI 1 "spu_reg_operand" "r")
328963d1a8abSmrg	       (const_int -1)))]
329063d1a8abSmrg  ""
329163d1a8abSmrg  "cgti\t%0,%1,-1")
329263d1a8abSmrg
329363d1a8abSmrg(define_insn_and_split "cgt_di"
329463d1a8abSmrg  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
329563d1a8abSmrg	(gt:SI (match_operand:DI 1 "spu_reg_operand" "r")
329663d1a8abSmrg	       (match_operand:DI 2 "spu_reg_operand" "r")))
329763d1a8abSmrg   (clobber (match_scratch:V4SI 3 "=&r"))
329863d1a8abSmrg   (clobber (match_scratch:V4SI 4 "=&r"))
329963d1a8abSmrg   (clobber (match_scratch:V4SI 5 "=&r"))]
330063d1a8abSmrg  ""
330163d1a8abSmrg  "#"
330263d1a8abSmrg  "reload_completed"
330363d1a8abSmrg  [(set (match_dup:SI 0)
330463d1a8abSmrg        (gt:SI (match_dup:DI 1)
330563d1a8abSmrg	       (match_dup:DI 2)))]
330663d1a8abSmrg  {
330763d1a8abSmrg    rtx op0 = gen_rtx_REG (V4SImode, REGNO (operands[0]));
330863d1a8abSmrg    rtx op1 = gen_rtx_REG (V4SImode, REGNO (operands[1]));
330963d1a8abSmrg    rtx op2 = gen_rtx_REG (V4SImode, REGNO (operands[2]));
331063d1a8abSmrg    rtx op3 = operands[3];
331163d1a8abSmrg    rtx op4 = operands[4];
331263d1a8abSmrg    rtx op5 = operands[5];
331363d1a8abSmrg    rtx op3d = gen_rtx_REG (V2DImode, REGNO (operands[3]));
331463d1a8abSmrg    emit_insn (gen_clgt_v4si (op3, op1, op2));
331563d1a8abSmrg    emit_insn (gen_ceq_v4si (op4, op1, op2));
331663d1a8abSmrg    emit_insn (gen_cgt_v4si (op5, op1, op2));
331763d1a8abSmrg    emit_insn (gen_spu_xswd (op3d, op3));
331863d1a8abSmrg    emit_insn (gen_selb (op0, op5, op3, op4));
331963d1a8abSmrg    DONE;
332063d1a8abSmrg  })
332163d1a8abSmrg
332263d1a8abSmrg(define_insn "cgt_ti_m1"
332363d1a8abSmrg  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
332463d1a8abSmrg	(gt:SI (match_operand:TI 1 "spu_reg_operand" "r")
332563d1a8abSmrg	       (const_int -1)))]
332663d1a8abSmrg  ""
332763d1a8abSmrg  "cgti\t%0,%1,-1")
332863d1a8abSmrg
332963d1a8abSmrg(define_insn "cgt_ti"
333063d1a8abSmrg  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
333163d1a8abSmrg	(gt:SI (match_operand:TI 1 "spu_reg_operand" "r")
333263d1a8abSmrg	       (match_operand:TI 2 "spu_reg_operand" "r")))
333363d1a8abSmrg   (clobber (match_scratch:V4SI 3 "=&r"))
333463d1a8abSmrg   (clobber (match_scratch:V4SI 4 "=&r"))
333563d1a8abSmrg   (clobber (match_scratch:V4SI 5 "=&r"))]
333663d1a8abSmrg  ""
333763d1a8abSmrg  "clgt\t%4,%1,%2\;\
333863d1a8abSmrgceq\t%3,%1,%2\;\
333963d1a8abSmrgcgt\t%5,%1,%2\;\
334063d1a8abSmrgshlqbyi\t%0,%4,4\;\
334163d1a8abSmrgselb\t%0,%4,%0,%3\;\
334263d1a8abSmrgshlqbyi\t%0,%0,4\;\
334363d1a8abSmrgselb\t%0,%4,%0,%3\;\
334463d1a8abSmrgshlqbyi\t%0,%0,4\;\
334563d1a8abSmrgselb\t%0,%5,%0,%3"
334663d1a8abSmrg  [(set_attr "type" "multi0")
334763d1a8abSmrg   (set_attr "length" "36")])
334863d1a8abSmrg
334963d1a8abSmrg(define_insn "cgt_<mode>"
335063d1a8abSmrg  [(set (match_operand:<F2I> 0 "spu_reg_operand" "=r")
335163d1a8abSmrg	(gt:<F2I> (match_operand:VSF 1 "spu_reg_operand" "r")
335263d1a8abSmrg		  (match_operand:VSF 2 "spu_reg_operand" "r")))]
335363d1a8abSmrg  ""
335463d1a8abSmrg  "fcgt\t%0,%1,%2")
335563d1a8abSmrg
335663d1a8abSmrg(define_insn "cmgt_<mode>"
335763d1a8abSmrg  [(set (match_operand:<F2I> 0 "spu_reg_operand" "=r")
335863d1a8abSmrg	(gt:<F2I> (abs:VSF (match_operand:VSF 1 "spu_reg_operand" "r"))
335963d1a8abSmrg		  (abs:VSF (match_operand:VSF 2 "spu_reg_operand" "r"))))]
336063d1a8abSmrg  ""
336163d1a8abSmrg  "fcmgt\t%0,%1,%2")
336263d1a8abSmrg
336363d1a8abSmrg(define_expand "cgt_df"
336463d1a8abSmrg  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
336563d1a8abSmrg        (gt:SI (match_operand:DF 1 "spu_reg_operand" "r")
336663d1a8abSmrg               (match_operand:DF 2 "const_zero_operand" "i")))]
336763d1a8abSmrg  ""
336863d1a8abSmrg{
336963d1a8abSmrg  if (spu_arch == PROCESSOR_CELL)
337063d1a8abSmrg    {
337163d1a8abSmrg      rtx ra = gen_reg_rtx (V4SImode);
337263d1a8abSmrg      rtx rb = gen_reg_rtx (V4SImode);
337363d1a8abSmrg      rtx zero = gen_reg_rtx (V4SImode);
337463d1a8abSmrg      rtx temp = gen_reg_rtx (TImode);
337563d1a8abSmrg      rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
337663d1a8abSmrg      rtx temp2 = gen_reg_rtx (V4SImode);
337763d1a8abSmrg      rtx hi_inf = gen_reg_rtx (V4SImode);
337863d1a8abSmrg      rtx a_nan = gen_reg_rtx (V4SImode);
337963d1a8abSmrg      rtx b_nan = gen_reg_rtx (V4SImode);
338063d1a8abSmrg      rtx a_abs = gen_reg_rtx (V4SImode);
338163d1a8abSmrg      rtx b_abs = gen_reg_rtx (V4SImode);
338263d1a8abSmrg      rtx asel = gen_reg_rtx (V4SImode);
338363d1a8abSmrg      rtx bsel = gen_reg_rtx (V4SImode);
338463d1a8abSmrg      rtx abor = gen_reg_rtx (V4SImode);
338563d1a8abSmrg      rtx bbor = gen_reg_rtx (V4SImode);
338663d1a8abSmrg      rtx gt_hi = gen_reg_rtx (V4SImode);
338763d1a8abSmrg      rtx gt_lo = gen_reg_rtx (V4SImode);
338863d1a8abSmrg      rtx sign_mask = gen_reg_rtx (V4SImode);
338963d1a8abSmrg      rtx nan_mask = gen_reg_rtx (V4SImode);
339063d1a8abSmrg      rtx hi_promote = gen_reg_rtx (TImode);
339163d1a8abSmrg      rtx borrow_shuffle = gen_reg_rtx (TImode);
339263d1a8abSmrg
339363d1a8abSmrg      rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF,
339463d1a8abSmrg                                               0x7FFFFFFF, 0xFFFFFFFF);
339563d1a8abSmrg      emit_move_insn (sign_mask, pat);
339663d1a8abSmrg      pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0,
339763d1a8abSmrg                                             0x7FF00000, 0x0);
339863d1a8abSmrg      emit_move_insn (nan_mask, pat);
339963d1a8abSmrg      pat = spu_const_from_ints (TImode, 0x00010203, 0x00010203,
340063d1a8abSmrg                                         0x08090A0B, 0x08090A0B);
340163d1a8abSmrg      emit_move_insn (hi_promote, pat);
340263d1a8abSmrg      pat = spu_const_from_ints (TImode, 0x04050607, 0xC0C0C0C0,
340363d1a8abSmrg                                         0x0C0D0E0F, 0xC0C0C0C0);
340463d1a8abSmrg      emit_move_insn (borrow_shuffle, pat);
340563d1a8abSmrg
340663d1a8abSmrg      emit_insn (gen_spu_convert (ra, operands[1]));
340763d1a8abSmrg      emit_insn (gen_spu_convert (rb, operands[2]));
340863d1a8abSmrg      emit_insn (gen_andv4si3 (a_abs, ra, sign_mask));
340963d1a8abSmrg      emit_insn (gen_andv4si3 (b_abs, rb, sign_mask));
341063d1a8abSmrg
341163d1a8abSmrg      if (!flag_finite_math_only)
341263d1a8abSmrg	{
341363d1a8abSmrg	  /* check if ra is NaN  */
341463d1a8abSmrg          emit_insn (gen_ceq_v4si (hi_inf, a_abs, nan_mask));
341563d1a8abSmrg          emit_insn (gen_clgt_v4si (a_nan, a_abs, nan_mask));
341663d1a8abSmrg          emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, a_nan),
341763d1a8abSmrg                                  GEN_INT (4 * 8)));
341863d1a8abSmrg          emit_insn (gen_andv4si3 (temp2, temp_v4si, hi_inf));
341963d1a8abSmrg          emit_insn (gen_iorv4si3 (a_nan, a_nan, temp2));
342063d1a8abSmrg          emit_insn (gen_shufb (a_nan, a_nan, a_nan, hi_promote));
342163d1a8abSmrg
342263d1a8abSmrg	  /* check if rb is NaN  */
342363d1a8abSmrg          emit_insn (gen_ceq_v4si (hi_inf, b_abs, nan_mask));
342463d1a8abSmrg          emit_insn (gen_clgt_v4si (b_nan, b_abs, nan_mask));
342563d1a8abSmrg          emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, b_nan),
342663d1a8abSmrg                                  GEN_INT (4 * 8)));
342763d1a8abSmrg          emit_insn (gen_andv4si3 (temp2, temp_v4si, hi_inf));
342863d1a8abSmrg          emit_insn (gen_iorv4si3 (b_nan, b_nan, temp2));
342963d1a8abSmrg          emit_insn (gen_shufb (b_nan, b_nan, b_nan, hi_promote));
343063d1a8abSmrg
343163d1a8abSmrg	  /* check if ra or rb is NaN  */
343263d1a8abSmrg          emit_insn (gen_iorv4si3 (a_nan, a_nan, b_nan));
343363d1a8abSmrg	}
343463d1a8abSmrg      emit_move_insn (zero, CONST0_RTX (V4SImode));
343563d1a8abSmrg      emit_insn (gen_vashrv4si3 (asel, ra, spu_const (V4SImode, 31)));
343663d1a8abSmrg      emit_insn (gen_shufb (asel, asel, asel, hi_promote));
343763d1a8abSmrg      emit_insn (gen_bg_v4si (abor, zero, a_abs));
343863d1a8abSmrg      emit_insn (gen_shufb (abor, abor, abor, borrow_shuffle));
343963d1a8abSmrg      emit_insn (gen_sfx_v4si (abor, zero, a_abs, abor));
344063d1a8abSmrg      emit_insn (gen_selb (abor, a_abs, abor, asel));
344163d1a8abSmrg
344263d1a8abSmrg      emit_insn (gen_vashrv4si3 (bsel, rb, spu_const (V4SImode, 31)));
344363d1a8abSmrg      emit_insn (gen_shufb (bsel, bsel, bsel, hi_promote));
344463d1a8abSmrg      emit_insn (gen_bg_v4si (bbor, zero, b_abs));
344563d1a8abSmrg      emit_insn (gen_shufb (bbor, bbor, bbor, borrow_shuffle));
344663d1a8abSmrg      emit_insn (gen_sfx_v4si (bbor, zero, b_abs, bbor));
344763d1a8abSmrg      emit_insn (gen_selb (bbor, b_abs, bbor, bsel));
344863d1a8abSmrg
344963d1a8abSmrg      emit_insn (gen_cgt_v4si (gt_hi, abor, bbor));
345063d1a8abSmrg      emit_insn (gen_clgt_v4si (gt_lo, abor, bbor));
345163d1a8abSmrg      emit_insn (gen_ceq_v4si (temp2, abor, bbor));
345263d1a8abSmrg      emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, gt_lo),
345363d1a8abSmrg                                GEN_INT (4 * 8)));
345463d1a8abSmrg      emit_insn (gen_andv4si3 (temp2, temp2, temp_v4si));
345563d1a8abSmrg      emit_insn (gen_iorv4si3 (temp2, gt_hi, temp2));
345663d1a8abSmrg      emit_insn (gen_shufb (temp2, temp2, temp2, hi_promote));
345763d1a8abSmrg      if (!flag_finite_math_only)
345863d1a8abSmrg        {
345963d1a8abSmrg	  /* correct for NaNs  */
346063d1a8abSmrg          emit_insn (gen_andc_v4si (temp2, temp2, a_nan));
346163d1a8abSmrg	}
346263d1a8abSmrg      emit_insn (gen_spu_convert (operands[0], temp2));
346363d1a8abSmrg      DONE;
346463d1a8abSmrg    }
346563d1a8abSmrg})
346663d1a8abSmrg
346763d1a8abSmrg(define_insn "cgt_<mode>_celledp"
346863d1a8abSmrg  [(set (match_operand:<DF2I> 0 "spu_reg_operand" "=r")
346963d1a8abSmrg        (gt:<DF2I> (match_operand:VDF 1 "spu_reg_operand" "r")
347063d1a8abSmrg                   (match_operand:VDF 2 "spu_reg_operand" "r")))]
347163d1a8abSmrg  "spu_arch == PROCESSOR_CELLEDP"
347263d1a8abSmrg  "dfcgt\t%0,%1,%2"
347363d1a8abSmrg  [(set_attr "type" "fpd")])
347463d1a8abSmrg
347563d1a8abSmrg(define_insn "cmgt_<mode>_celledp"
347663d1a8abSmrg  [(set (match_operand:<DF2I> 0 "spu_reg_operand" "=r")
347763d1a8abSmrg        (gt:<DF2I> (abs:VDF (match_operand:VDF 1 "spu_reg_operand" "r"))
347863d1a8abSmrg                   (abs:VDF (match_operand:VDF 2 "spu_reg_operand" "r"))))]
347963d1a8abSmrg  "spu_arch == PROCESSOR_CELLEDP"
348063d1a8abSmrg  "dfcmgt\t%0,%1,%2"
348163d1a8abSmrg  [(set_attr "type" "fpd")])
348263d1a8abSmrg
348363d1a8abSmrg(define_expand "cgt_v2df"
348463d1a8abSmrg  [(set (match_operand:V2DI 0 "spu_reg_operand" "=r")
348563d1a8abSmrg        (gt:V2DI (match_operand:V2DF 1 "spu_reg_operand" "r")
348663d1a8abSmrg                 (match_operand:V2DF 2 "spu_reg_operand" "r")))]
348763d1a8abSmrg  ""
348863d1a8abSmrg{
348963d1a8abSmrg  if (spu_arch == PROCESSOR_CELL)
349063d1a8abSmrg    {
349163d1a8abSmrg      rtx ra = spu_gen_subreg (V4SImode, operands[1]);
349263d1a8abSmrg      rtx rb = spu_gen_subreg (V4SImode, operands[2]);
349363d1a8abSmrg      rtx zero = gen_reg_rtx (V4SImode);
349463d1a8abSmrg      rtx temp = gen_reg_rtx (TImode);
349563d1a8abSmrg      rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
349663d1a8abSmrg      rtx temp2 = gen_reg_rtx (V4SImode);
349763d1a8abSmrg      rtx hi_inf = gen_reg_rtx (V4SImode);
349863d1a8abSmrg      rtx a_nan = gen_reg_rtx (V4SImode);
349963d1a8abSmrg      rtx b_nan = gen_reg_rtx (V4SImode);
350063d1a8abSmrg      rtx a_abs = gen_reg_rtx (V4SImode);
350163d1a8abSmrg      rtx b_abs = gen_reg_rtx (V4SImode);
350263d1a8abSmrg      rtx asel = gen_reg_rtx (V4SImode);
350363d1a8abSmrg      rtx bsel = gen_reg_rtx (V4SImode);
350463d1a8abSmrg      rtx abor = gen_reg_rtx (V4SImode);
350563d1a8abSmrg      rtx bbor = gen_reg_rtx (V4SImode);
350663d1a8abSmrg      rtx gt_hi = gen_reg_rtx (V4SImode);
350763d1a8abSmrg      rtx gt_lo = gen_reg_rtx (V4SImode);
350863d1a8abSmrg      rtx sign_mask = gen_reg_rtx (V4SImode);
350963d1a8abSmrg      rtx nan_mask = gen_reg_rtx (V4SImode);
351063d1a8abSmrg      rtx hi_promote = gen_reg_rtx (TImode);
351163d1a8abSmrg      rtx borrow_shuffle = gen_reg_rtx (TImode);
351263d1a8abSmrg      rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF,
351363d1a8abSmrg                                               0x7FFFFFFF, 0xFFFFFFFF);
351463d1a8abSmrg      emit_move_insn (sign_mask, pat);
351563d1a8abSmrg      pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0,
351663d1a8abSmrg                                           0x7FF00000, 0x0);
351763d1a8abSmrg      emit_move_insn (nan_mask, pat);
351863d1a8abSmrg      pat = spu_const_from_ints (TImode, 0x00010203, 0x00010203,
351963d1a8abSmrg                                         0x08090A0B, 0x08090A0B);
352063d1a8abSmrg      emit_move_insn (hi_promote, pat);
352163d1a8abSmrg      pat = spu_const_from_ints (TImode, 0x04050607, 0xC0C0C0C0,
352263d1a8abSmrg                                         0x0C0D0E0F, 0xC0C0C0C0);
352363d1a8abSmrg      emit_move_insn (borrow_shuffle, pat);
352463d1a8abSmrg
352563d1a8abSmrg      emit_insn (gen_andv4si3 (a_abs, ra, sign_mask));
352663d1a8abSmrg      emit_insn (gen_ceq_v4si (hi_inf, a_abs, nan_mask));
352763d1a8abSmrg      emit_insn (gen_clgt_v4si (a_nan, a_abs, nan_mask));
352863d1a8abSmrg      emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, a_nan),
352963d1a8abSmrg                                                    GEN_INT (4 * 8)));
353063d1a8abSmrg      emit_insn (gen_andv4si3 (temp2, temp_v4si, hi_inf));
353163d1a8abSmrg      emit_insn (gen_iorv4si3 (a_nan, a_nan, temp2));
353263d1a8abSmrg      emit_insn (gen_shufb (a_nan, a_nan, a_nan, hi_promote));
353363d1a8abSmrg      emit_insn (gen_andv4si3 (b_abs, rb, sign_mask));
353463d1a8abSmrg      emit_insn (gen_ceq_v4si (hi_inf, b_abs, nan_mask));
353563d1a8abSmrg      emit_insn (gen_clgt_v4si (b_nan, b_abs, nan_mask));
353663d1a8abSmrg      emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, b_nan),
353763d1a8abSmrg                                                    GEN_INT (4 * 8)));
353863d1a8abSmrg      emit_insn (gen_andv4si3 (temp2, temp_v4si, hi_inf));
353963d1a8abSmrg      emit_insn (gen_iorv4si3 (b_nan, b_nan, temp2));
354063d1a8abSmrg      emit_insn (gen_shufb (b_nan, b_nan, b_nan, hi_promote));
354163d1a8abSmrg      emit_insn (gen_iorv4si3 (a_nan, a_nan, b_nan));
354263d1a8abSmrg      emit_move_insn (zero, CONST0_RTX (V4SImode));
354363d1a8abSmrg      emit_insn (gen_vashrv4si3 (asel, ra, spu_const (V4SImode, 31)));
354463d1a8abSmrg      emit_insn (gen_shufb (asel, asel, asel, hi_promote));
354563d1a8abSmrg      emit_insn (gen_bg_v4si (abor, zero, a_abs));
354663d1a8abSmrg      emit_insn (gen_shufb (abor, abor, abor, borrow_shuffle));
354763d1a8abSmrg      emit_insn (gen_sfx_v4si (abor, zero, a_abs, abor));
354863d1a8abSmrg      emit_insn (gen_selb (abor, a_abs, abor, asel));
354963d1a8abSmrg      emit_insn (gen_vashrv4si3 (bsel, rb, spu_const (V4SImode, 31)));
355063d1a8abSmrg      emit_insn (gen_shufb (bsel, bsel, bsel, hi_promote));
355163d1a8abSmrg      emit_insn (gen_bg_v4si (bbor, zero, b_abs));
355263d1a8abSmrg      emit_insn (gen_shufb (bbor, bbor, bbor, borrow_shuffle));
355363d1a8abSmrg      emit_insn (gen_sfx_v4si (bbor, zero, b_abs, bbor));
355463d1a8abSmrg      emit_insn (gen_selb (bbor, b_abs, bbor, bsel));
355563d1a8abSmrg      emit_insn (gen_cgt_v4si (gt_hi, abor, bbor));
355663d1a8abSmrg      emit_insn (gen_clgt_v4si (gt_lo, abor, bbor));
355763d1a8abSmrg      emit_insn (gen_ceq_v4si (temp2, abor, bbor));
355863d1a8abSmrg      emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, gt_lo),
355963d1a8abSmrg                                                    GEN_INT (4 * 8)));
356063d1a8abSmrg      emit_insn (gen_andv4si3 (temp2, temp2, temp_v4si));
356163d1a8abSmrg      emit_insn (gen_iorv4si3 (temp2, gt_hi, temp2));
356263d1a8abSmrg
356363d1a8abSmrg      emit_insn (gen_shufb (temp2, temp2, temp2, hi_promote));
356463d1a8abSmrg      emit_insn (gen_andc_v4si (temp2, temp2, a_nan));
356563d1a8abSmrg      emit_move_insn (operands[0], spu_gen_subreg (V2DImode, temp2));
356663d1a8abSmrg      DONE;
356763d1a8abSmrg    }
356863d1a8abSmrg})
356963d1a8abSmrg
357063d1a8abSmrg(define_expand "cmgt_v2df"
357163d1a8abSmrg  [(set (match_operand:V2DI 0 "spu_reg_operand" "=r")
357263d1a8abSmrg        (gt:V2DI (abs:V2DF (match_operand:V2DF 1 "spu_reg_operand" "r"))
357363d1a8abSmrg                 (abs:V2DF (match_operand:V2DF 2 "spu_reg_operand" "r"))))]
357463d1a8abSmrg  ""
357563d1a8abSmrg{
357663d1a8abSmrg  if (spu_arch == PROCESSOR_CELL)
357763d1a8abSmrg    {
357863d1a8abSmrg      rtx ra = spu_gen_subreg (V4SImode, operands[1]);
357963d1a8abSmrg      rtx rb = spu_gen_subreg (V4SImode, operands[2]);
358063d1a8abSmrg      rtx temp = gen_reg_rtx (TImode);
358163d1a8abSmrg      rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
358263d1a8abSmrg      rtx temp2 = gen_reg_rtx (V4SImode);
358363d1a8abSmrg      rtx hi_inf = gen_reg_rtx (V4SImode);
358463d1a8abSmrg      rtx a_nan = gen_reg_rtx (V4SImode);
358563d1a8abSmrg      rtx b_nan = gen_reg_rtx (V4SImode);
358663d1a8abSmrg      rtx a_abs = gen_reg_rtx (V4SImode);
358763d1a8abSmrg      rtx b_abs = gen_reg_rtx (V4SImode);
358863d1a8abSmrg      rtx gt_hi = gen_reg_rtx (V4SImode);
358963d1a8abSmrg      rtx gt_lo = gen_reg_rtx (V4SImode);
359063d1a8abSmrg      rtx sign_mask = gen_reg_rtx (V4SImode);
359163d1a8abSmrg      rtx nan_mask = gen_reg_rtx (V4SImode);
359263d1a8abSmrg      rtx hi_promote = gen_reg_rtx (TImode);
359363d1a8abSmrg      rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF,
359463d1a8abSmrg                                               0x7FFFFFFF, 0xFFFFFFFF);
359563d1a8abSmrg      emit_move_insn (sign_mask, pat);
359663d1a8abSmrg      pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0,
359763d1a8abSmrg                                           0x7FF00000, 0x0);
359863d1a8abSmrg      emit_move_insn (nan_mask, pat);
359963d1a8abSmrg      pat = spu_const_from_ints (TImode, 0x00010203, 0x00010203,
360063d1a8abSmrg                                         0x08090A0B, 0x08090A0B);
360163d1a8abSmrg      emit_move_insn (hi_promote, pat);
360263d1a8abSmrg
360363d1a8abSmrg      emit_insn (gen_andv4si3 (a_abs, ra, sign_mask));
360463d1a8abSmrg      emit_insn (gen_ceq_v4si (hi_inf, a_abs, nan_mask));
360563d1a8abSmrg      emit_insn (gen_clgt_v4si (a_nan, a_abs, nan_mask));
360663d1a8abSmrg      emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, a_nan),
360763d1a8abSmrg                                                    GEN_INT (4 * 8)));
360863d1a8abSmrg      emit_insn (gen_andv4si3 (temp2, temp_v4si, hi_inf));
360963d1a8abSmrg      emit_insn (gen_iorv4si3 (a_nan, a_nan, temp2));
361063d1a8abSmrg      emit_insn (gen_shufb (a_nan, a_nan, a_nan, hi_promote));
361163d1a8abSmrg      emit_insn (gen_andv4si3 (b_abs, rb, sign_mask));
361263d1a8abSmrg      emit_insn (gen_ceq_v4si (hi_inf, b_abs, nan_mask));
361363d1a8abSmrg      emit_insn (gen_clgt_v4si (b_nan, b_abs, nan_mask));
361463d1a8abSmrg      emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, b_nan),
361563d1a8abSmrg                                                    GEN_INT (4 * 8)));
361663d1a8abSmrg      emit_insn (gen_andv4si3 (temp2, temp_v4si, hi_inf));
361763d1a8abSmrg      emit_insn (gen_iorv4si3 (b_nan, b_nan, temp2));
361863d1a8abSmrg      emit_insn (gen_shufb (b_nan, b_nan, b_nan, hi_promote));
361963d1a8abSmrg      emit_insn (gen_iorv4si3 (a_nan, a_nan, b_nan));
362063d1a8abSmrg
362163d1a8abSmrg      emit_insn (gen_clgt_v4si (gt_hi, a_abs, b_abs));
362263d1a8abSmrg      emit_insn (gen_clgt_v4si (gt_lo, a_abs, b_abs));
362363d1a8abSmrg      emit_insn (gen_ceq_v4si (temp2, a_abs, b_abs));
362463d1a8abSmrg      emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, gt_lo),
362563d1a8abSmrg                                                    GEN_INT (4 * 8)));
362663d1a8abSmrg      emit_insn (gen_andv4si3 (temp2, temp2, temp_v4si));
362763d1a8abSmrg      emit_insn (gen_iorv4si3 (temp2, gt_hi, temp2));
362863d1a8abSmrg      emit_insn (gen_shufb (temp2, temp2, temp2, hi_promote));
362963d1a8abSmrg      emit_insn (gen_andc_v4si (temp2, temp2, a_nan));
363063d1a8abSmrg      emit_move_insn (operands[0], spu_gen_subreg (V2DImode, temp2));
363163d1a8abSmrg      DONE;
363263d1a8abSmrg    }
363363d1a8abSmrg})
363463d1a8abSmrg
363563d1a8abSmrg
363663d1a8abSmrg;; clgt
363763d1a8abSmrg
363863d1a8abSmrg(define_insn "clgt_<mode>"
363963d1a8abSmrg  [(set (match_operand:VQHSI 0 "spu_reg_operand" "=r,r")
364063d1a8abSmrg	(gtu:VQHSI (match_operand:VQHSI 1 "spu_reg_operand" "r,r")
364163d1a8abSmrg		   (match_operand:VQHSI 2 "spu_arith_operand" "r,B")))]
364263d1a8abSmrg  ""
364363d1a8abSmrg  "@
364463d1a8abSmrg  clgt<bh>\t%0,%1,%2
364563d1a8abSmrg  clgt<bh>i\t%0,%1,%2")
364663d1a8abSmrg
364763d1a8abSmrg(define_insn_and_split "clgt_di"
364863d1a8abSmrg  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
364963d1a8abSmrg	(gtu:SI (match_operand:DI 1 "spu_reg_operand" "r")
365063d1a8abSmrg	        (match_operand:DI 2 "spu_reg_operand" "r")))
365163d1a8abSmrg   (clobber (match_scratch:V4SI 3 "=&r"))
365263d1a8abSmrg   (clobber (match_scratch:V4SI 4 "=&r"))
365363d1a8abSmrg   (clobber (match_scratch:V4SI 5 "=&r"))]
365463d1a8abSmrg  ""
365563d1a8abSmrg  "#"
365663d1a8abSmrg  "reload_completed"
365763d1a8abSmrg  [(set (match_dup:SI 0)
365863d1a8abSmrg        (gtu:SI (match_dup:DI 1)
365963d1a8abSmrg	        (match_dup:DI 2)))]
366063d1a8abSmrg  {
366163d1a8abSmrg    rtx op0 = gen_rtx_REG (V4SImode, REGNO (operands[0]));
366263d1a8abSmrg    rtx op1 = gen_rtx_REG (V4SImode, REGNO (operands[1]));
366363d1a8abSmrg    rtx op2 = gen_rtx_REG (V4SImode, REGNO (operands[2]));
366463d1a8abSmrg    rtx op3 = operands[3];
366563d1a8abSmrg    rtx op4 = operands[4];
366663d1a8abSmrg    rtx op5 = operands[5];
366763d1a8abSmrg    rtx op5d = gen_rtx_REG (V2DImode, REGNO (operands[5]));
366863d1a8abSmrg    emit_insn (gen_clgt_v4si (op3, op1, op2));
366963d1a8abSmrg    emit_insn (gen_ceq_v4si (op4, op1, op2));
367063d1a8abSmrg    emit_insn (gen_spu_xswd (op5d, op3));
367163d1a8abSmrg    emit_insn (gen_selb (op0, op3, op5, op4));
367263d1a8abSmrg    DONE;
367363d1a8abSmrg  })
367463d1a8abSmrg
367563d1a8abSmrg(define_insn "clgt_ti"
367663d1a8abSmrg  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
367763d1a8abSmrg	(gtu:SI (match_operand:TI 1 "spu_reg_operand" "r")
367863d1a8abSmrg	       (match_operand:TI 2 "spu_reg_operand" "r")))
367963d1a8abSmrg   (clobber (match_scratch:V4SI 3 "=&r"))
368063d1a8abSmrg   (clobber (match_scratch:V4SI 4 "=&r"))]
368163d1a8abSmrg  ""
368263d1a8abSmrg  "ceq\t%3,%1,%2\;\
368363d1a8abSmrgclgt\t%4,%1,%2\;\
368463d1a8abSmrgshlqbyi\t%0,%4,4\;\
368563d1a8abSmrgselb\t%0,%4,%0,%3\;\
368663d1a8abSmrgshlqbyi\t%0,%0,4\;\
368763d1a8abSmrgselb\t%0,%4,%0,%3\;\
368863d1a8abSmrgshlqbyi\t%0,%0,4\;\
368963d1a8abSmrgselb\t%0,%4,%0,%3"
369063d1a8abSmrg  [(set_attr "type" "multi0")
369163d1a8abSmrg   (set_attr "length" "32")])
369263d1a8abSmrg
369363d1a8abSmrg
369463d1a8abSmrg;; dftsv
369563d1a8abSmrg(define_insn "dftsv_celledp"
369663d1a8abSmrg  [(set (match_operand:V2DI 0 "spu_reg_operand" "=r")
369763d1a8abSmrg        (unspec:V2DI [(match_operand:V2DF 1 "spu_reg_operand"  "r")
369863d1a8abSmrg		      (match_operand:SI   2 "const_int_operand" "i")]
369963d1a8abSmrg		      UNSPEC_DFTSV))]
370063d1a8abSmrg  "spu_arch == PROCESSOR_CELLEDP"
370163d1a8abSmrg  "dftsv\t%0,%1,%2"
370263d1a8abSmrg  [(set_attr "type" "fpd")])
370363d1a8abSmrg
370463d1a8abSmrg(define_expand "dftsv"
370563d1a8abSmrg  [(set (match_operand:V2DI 0 "spu_reg_operand" "=r")
370663d1a8abSmrg        (unspec:V2DI [(match_operand:V2DF 1 "spu_reg_operand" "r")
370763d1a8abSmrg		      (match_operand:SI   2 "const_int_operand" "i")]
370863d1a8abSmrg		      UNSPEC_DFTSV))]
370963d1a8abSmrg  ""
371063d1a8abSmrg{
371163d1a8abSmrg  if (spu_arch == PROCESSOR_CELL)
371263d1a8abSmrg    {
371363d1a8abSmrg      rtx result = gen_reg_rtx (V4SImode);
371463d1a8abSmrg      emit_move_insn (result, CONST0_RTX (V4SImode));
371563d1a8abSmrg
371663d1a8abSmrg      if (INTVAL (operands[2]))
371763d1a8abSmrg        {
371863d1a8abSmrg          rtx ra = spu_gen_subreg (V4SImode, operands[1]);
371963d1a8abSmrg          rtx abs = gen_reg_rtx (V4SImode);
372063d1a8abSmrg          rtx sign = gen_reg_rtx (V4SImode);
372163d1a8abSmrg          rtx temp = gen_reg_rtx (TImode);
372263d1a8abSmrg          rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
372363d1a8abSmrg          rtx temp2 = gen_reg_rtx (V4SImode);
372463d1a8abSmrg          rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF,
372563d1a8abSmrg                                                   0x7FFFFFFF, 0xFFFFFFFF);
372663d1a8abSmrg          rtx sign_mask = gen_reg_rtx (V4SImode);
372763d1a8abSmrg          rtx hi_promote = gen_reg_rtx (TImode);
372863d1a8abSmrg          emit_move_insn (sign_mask, pat);
372963d1a8abSmrg          pat = spu_const_from_ints (TImode, 0x00010203, 0x00010203,
373063d1a8abSmrg                                             0x08090A0B, 0x08090A0B);
373163d1a8abSmrg          emit_move_insn (hi_promote, pat);
373263d1a8abSmrg
373363d1a8abSmrg          emit_insn (gen_vashrv4si3 (sign, ra, spu_const (V4SImode, 31)));
373463d1a8abSmrg          emit_insn (gen_shufb (sign, sign, sign, hi_promote));
373563d1a8abSmrg          emit_insn (gen_andv4si3 (abs, ra, sign_mask));
373663d1a8abSmrg
373763d1a8abSmrg          /* NaN  or +inf or -inf */
373863d1a8abSmrg          if (INTVAL (operands[2]) & 0x70)
373963d1a8abSmrg            {
374063d1a8abSmrg              rtx nan_mask = gen_reg_rtx (V4SImode);
374163d1a8abSmrg              rtx isinf = gen_reg_rtx (V4SImode);
374263d1a8abSmrg              pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0,
374363d1a8abSmrg		   			           0x7FF00000, 0x0);
374463d1a8abSmrg              emit_move_insn (nan_mask, pat);
374563d1a8abSmrg              emit_insn (gen_ceq_v4si (isinf, abs, nan_mask));
374663d1a8abSmrg
374763d1a8abSmrg              /* NaN  */
374863d1a8abSmrg              if (INTVAL (operands[2]) & 0x40)
374963d1a8abSmrg                {
375063d1a8abSmrg                  rtx isnan = gen_reg_rtx (V4SImode);
375163d1a8abSmrg                  emit_insn (gen_clgt_v4si (isnan, abs, nan_mask));
375263d1a8abSmrg                  emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, isnan),
375363d1a8abSmrg                                                             GEN_INT (4 * 8)));
375463d1a8abSmrg                  emit_insn (gen_andv4si3 (temp2, temp_v4si, isinf));
375563d1a8abSmrg                  emit_insn (gen_iorv4si3 (isnan, isnan, temp2));
375663d1a8abSmrg                  emit_insn (gen_shufb (isnan, isnan, isnan, hi_promote));
375763d1a8abSmrg                  emit_insn (gen_iorv4si3 (result, result, isnan));
375863d1a8abSmrg                }
375963d1a8abSmrg              /* +inf or -inf  */
376063d1a8abSmrg              if (INTVAL (operands[2]) & 0x30)
376163d1a8abSmrg                {
376263d1a8abSmrg                  emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, isinf),
376363d1a8abSmrg                                                             GEN_INT (4 * 8)));
376463d1a8abSmrg                  emit_insn (gen_andv4si3 (isinf, isinf, temp_v4si));
376563d1a8abSmrg                  emit_insn (gen_shufb (isinf, isinf, isinf, hi_promote));
376663d1a8abSmrg
376763d1a8abSmrg                  /* +inf  */
376863d1a8abSmrg                  if (INTVAL (operands[2]) & 0x20)
376963d1a8abSmrg                    {
377063d1a8abSmrg                      emit_insn (gen_andc_v4si (temp2, isinf, sign));
377163d1a8abSmrg                      emit_insn (gen_iorv4si3 (result, result, temp2));
377263d1a8abSmrg                    }
377363d1a8abSmrg                  /* -inf  */
377463d1a8abSmrg                  if (INTVAL (operands[2]) & 0x10)
377563d1a8abSmrg                    {
377663d1a8abSmrg                      emit_insn (gen_andv4si3 (temp2, isinf, sign));
377763d1a8abSmrg                      emit_insn (gen_iorv4si3 (result, result, temp2));
377863d1a8abSmrg                    }
377963d1a8abSmrg                }
378063d1a8abSmrg            }
378163d1a8abSmrg
378263d1a8abSmrg          /* 0 or denorm  */
378363d1a8abSmrg          if (INTVAL (operands[2]) & 0xF)
378463d1a8abSmrg            {
378563d1a8abSmrg              rtx iszero = gen_reg_rtx (V4SImode);
378663d1a8abSmrg              emit_insn (gen_ceq_v4si (iszero, abs, CONST0_RTX (V4SImode)));
378763d1a8abSmrg              emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, iszero),
378863d1a8abSmrg                                                          GEN_INT (4 * 8)));
378963d1a8abSmrg              emit_insn (gen_andv4si3 (iszero, iszero, temp_v4si));
379063d1a8abSmrg
379163d1a8abSmrg              /* denorm  */
379263d1a8abSmrg              if (INTVAL (operands[2]) & 0x3)
379363d1a8abSmrg                {
379463d1a8abSmrg                  rtx isdenorm = gen_reg_rtx (V4SImode);
379563d1a8abSmrg                  rtx denorm_mask = gen_reg_rtx (V4SImode);
379663d1a8abSmrg                  emit_move_insn (denorm_mask, spu_const (V4SImode, 0xFFFFF));
379763d1a8abSmrg                  emit_insn (gen_clgt_v4si (isdenorm, abs, denorm_mask));
379863d1a8abSmrg                  emit_insn (gen_nor_v4si (isdenorm, isdenorm, iszero));
379963d1a8abSmrg                  emit_insn (gen_shufb (isdenorm, isdenorm,
380063d1a8abSmrg                                        isdenorm, hi_promote));
380163d1a8abSmrg                  /* +denorm  */
380263d1a8abSmrg                  if (INTVAL (operands[2]) & 0x2)
380363d1a8abSmrg                    {
380463d1a8abSmrg                      emit_insn (gen_andc_v4si (temp2, isdenorm, sign));
380563d1a8abSmrg                      emit_insn (gen_iorv4si3 (result, result, temp2));
380663d1a8abSmrg                    }
380763d1a8abSmrg                  /* -denorm  */
380863d1a8abSmrg                  if (INTVAL (operands[2]) & 0x1)
380963d1a8abSmrg                    {
381063d1a8abSmrg                      emit_insn (gen_andv4si3 (temp2, isdenorm, sign));
381163d1a8abSmrg                      emit_insn (gen_iorv4si3 (result, result, temp2));
381263d1a8abSmrg                    }
381363d1a8abSmrg                }
381463d1a8abSmrg
381563d1a8abSmrg              /* 0  */
381663d1a8abSmrg              if (INTVAL (operands[2]) & 0xC)
381763d1a8abSmrg                {
381863d1a8abSmrg                  emit_insn (gen_shufb (iszero, iszero, iszero, hi_promote));
381963d1a8abSmrg                  /* +0  */
382063d1a8abSmrg                  if (INTVAL (operands[2]) & 0x8)
382163d1a8abSmrg                    {
382263d1a8abSmrg                      emit_insn (gen_andc_v4si (temp2, iszero, sign));
382363d1a8abSmrg                      emit_insn (gen_iorv4si3 (result, result, temp2));
382463d1a8abSmrg                    }
382563d1a8abSmrg                  /* -0  */
382663d1a8abSmrg                  if (INTVAL (operands[2]) & 0x4)
382763d1a8abSmrg                    {
382863d1a8abSmrg                      emit_insn (gen_andv4si3 (temp2, iszero, sign));
382963d1a8abSmrg                      emit_insn (gen_iorv4si3 (result, result, temp2));
383063d1a8abSmrg                    }
383163d1a8abSmrg                }
383263d1a8abSmrg             }
383363d1a8abSmrg          }
383463d1a8abSmrg      emit_move_insn (operands[0], spu_gen_subreg (V2DImode, result));
383563d1a8abSmrg      DONE;
383663d1a8abSmrg    }
383763d1a8abSmrg})
383863d1a8abSmrg
383963d1a8abSmrg
384063d1a8abSmrg;; branches
384163d1a8abSmrg
384263d1a8abSmrg(define_insn ""
384363d1a8abSmrg  [(set (pc)
384463d1a8abSmrg	(if_then_else (match_operator 1 "branch_comparison_operator"
384563d1a8abSmrg				      [(match_operand 2
384663d1a8abSmrg						      "spu_reg_operand" "r")
384763d1a8abSmrg				       (const_int 0)])
384863d1a8abSmrg		      (label_ref (match_operand 0 "" ""))
384963d1a8abSmrg		      (pc)))]
385063d1a8abSmrg  ""
385163d1a8abSmrg  "br%b2%b1z\t%2,%0"
385263d1a8abSmrg  [(set_attr "type" "br")])
385363d1a8abSmrg
385463d1a8abSmrg(define_insn ""
385563d1a8abSmrg  [(set (pc)
385663d1a8abSmrg	(if_then_else (match_operator 0 "branch_comparison_operator"
385763d1a8abSmrg				      [(match_operand 1
385863d1a8abSmrg						      "spu_reg_operand" "r")
385963d1a8abSmrg				       (const_int 0)])
386063d1a8abSmrg		      (return)
386163d1a8abSmrg		      (pc)))]
386263d1a8abSmrg  "direct_return ()"
386363d1a8abSmrg  "bi%b1%b0z\t%1,$lr"
386463d1a8abSmrg  [(set_attr "type" "br")])
386563d1a8abSmrg
386663d1a8abSmrg(define_insn ""
386763d1a8abSmrg  [(set (pc)
386863d1a8abSmrg	(if_then_else (match_operator 1 "branch_comparison_operator"
386963d1a8abSmrg				      [(match_operand 2
387063d1a8abSmrg						      "spu_reg_operand" "r")
387163d1a8abSmrg				       (const_int 0)])
387263d1a8abSmrg		      (pc)
387363d1a8abSmrg		      (label_ref (match_operand 0 "" ""))))]
387463d1a8abSmrg  ""
387563d1a8abSmrg  "br%b2%b1z\t%2,%0"
387663d1a8abSmrg  [(set_attr "type" "br")])
387763d1a8abSmrg
387863d1a8abSmrg(define_insn ""
387963d1a8abSmrg  [(set (pc)
388063d1a8abSmrg	(if_then_else (match_operator 0 "branch_comparison_operator"
388163d1a8abSmrg				      [(match_operand 1
388263d1a8abSmrg						      "spu_reg_operand" "r")
388363d1a8abSmrg				       (const_int 0)])
388463d1a8abSmrg		      (pc)
388563d1a8abSmrg		      (return)))]
388663d1a8abSmrg  "direct_return ()"
388763d1a8abSmrg  "bi%b1%b0z\t%1,$lr"
388863d1a8abSmrg  [(set_attr "type" "br")])
388963d1a8abSmrg
389063d1a8abSmrg
389163d1a8abSmrg;; vector conditional compare patterns
389263d1a8abSmrg(define_expand "vcond<mode><mode>"
389363d1a8abSmrg  [(set (match_operand:VCMP 0 "spu_reg_operand" "=r")
389463d1a8abSmrg        (if_then_else:VCMP
389563d1a8abSmrg          (match_operator 3 "comparison_operator"
389663d1a8abSmrg            [(match_operand:VCMP 4 "spu_reg_operand" "r")
389763d1a8abSmrg             (match_operand:VCMP 5 "spu_reg_operand" "r")])
389863d1a8abSmrg          (match_operand:VCMP 1 "spu_reg_operand" "r")
389963d1a8abSmrg          (match_operand:VCMP 2 "spu_reg_operand" "r")))]
390063d1a8abSmrg  ""
390163d1a8abSmrg  {
390263d1a8abSmrg    if (spu_emit_vector_cond_expr (operands[0], operands[1], operands[2],
390363d1a8abSmrg                                   operands[3], operands[4], operands[5]))
390463d1a8abSmrg    DONE;
390563d1a8abSmrg    else
390663d1a8abSmrg    FAIL;
390763d1a8abSmrg  })
390863d1a8abSmrg
390963d1a8abSmrg(define_expand "vcondu<mode><mode>"
391063d1a8abSmrg  [(set (match_operand:VCMPU 0 "spu_reg_operand" "=r")
391163d1a8abSmrg        (if_then_else:VCMPU
391263d1a8abSmrg          (match_operator 3 "comparison_operator"
391363d1a8abSmrg            [(match_operand:VCMPU 4 "spu_reg_operand" "r")
391463d1a8abSmrg             (match_operand:VCMPU 5 "spu_reg_operand" "r")])
391563d1a8abSmrg          (match_operand:VCMPU 1 "spu_reg_operand" "r")
391663d1a8abSmrg          (match_operand:VCMPU 2 "spu_reg_operand" "r")))]
391763d1a8abSmrg  ""
391863d1a8abSmrg  {
391963d1a8abSmrg    if (spu_emit_vector_cond_expr (operands[0], operands[1], operands[2],
392063d1a8abSmrg                                   operands[3], operands[4], operands[5]))
392163d1a8abSmrg    DONE;
392263d1a8abSmrg    else
392363d1a8abSmrg    FAIL;
392463d1a8abSmrg  })
392563d1a8abSmrg
392663d1a8abSmrg
392763d1a8abSmrg;; branch on condition
392863d1a8abSmrg
392963d1a8abSmrg(define_expand "cbranch<mode>4"
393063d1a8abSmrg  [(use (match_operator 0 "ordered_comparison_operator"
393163d1a8abSmrg	 [(match_operand:VQHSI 1 "spu_reg_operand" "")
393263d1a8abSmrg	  (match_operand:VQHSI 2 "spu_nonmem_operand" "")]))
393363d1a8abSmrg   (use (match_operand 3 ""))]
393463d1a8abSmrg  ""
393563d1a8abSmrg  { spu_emit_branch_or_set (0, operands[0], operands); DONE; })
393663d1a8abSmrg
393763d1a8abSmrg(define_expand "cbranch<mode>4"
393863d1a8abSmrg  [(use (match_operator 0 "ordered_comparison_operator"
393963d1a8abSmrg	 [(match_operand:DTI 1 "spu_reg_operand" "")
394063d1a8abSmrg	  (match_operand:DTI 2 "spu_reg_operand" "")]))
394163d1a8abSmrg   (use (match_operand 3 ""))]
394263d1a8abSmrg  ""
394363d1a8abSmrg  { spu_emit_branch_or_set (0, operands[0], operands); DONE; })
394463d1a8abSmrg
394563d1a8abSmrg(define_expand "cbranch<mode>4"
394663d1a8abSmrg  [(use (match_operator 0 "ordered_comparison_operator"
394763d1a8abSmrg	 [(match_operand:VSF 1 "spu_reg_operand" "")
394863d1a8abSmrg	  (match_operand:VSF 2 "spu_reg_operand" "")]))
394963d1a8abSmrg   (use (match_operand 3 ""))]
395063d1a8abSmrg  ""
395163d1a8abSmrg  { spu_emit_branch_or_set (0, operands[0], operands); DONE; })
395263d1a8abSmrg
395363d1a8abSmrg(define_expand "cbranchdf4"
395463d1a8abSmrg  [(use (match_operator 0 "ordered_comparison_operator"
395563d1a8abSmrg	 [(match_operand:DF 1 "spu_reg_operand" "")
395663d1a8abSmrg	  (match_operand:DF 2 "spu_reg_operand" "")]))
395763d1a8abSmrg   (use (match_operand 3 ""))]
395863d1a8abSmrg  ""
395963d1a8abSmrg  { spu_emit_branch_or_set (0, operands[0], operands); DONE; })
396063d1a8abSmrg
396163d1a8abSmrg
396263d1a8abSmrg;; set on condition
396363d1a8abSmrg
396463d1a8abSmrg(define_expand "cstore<mode>4"
396563d1a8abSmrg  [(use (match_operator 1 "ordered_comparison_operator"
396663d1a8abSmrg	 [(match_operand:VQHSI 2 "spu_reg_operand" "")
396763d1a8abSmrg	  (match_operand:VQHSI 3 "spu_nonmem_operand" "")]))
396863d1a8abSmrg   (clobber (match_operand:SI 0 "spu_reg_operand"))]
396963d1a8abSmrg  ""
397063d1a8abSmrg  { spu_emit_branch_or_set (1, operands[1], operands); DONE; })
397163d1a8abSmrg
397263d1a8abSmrg(define_expand "cstore<mode>4"
397363d1a8abSmrg  [(use (match_operator 1 "ordered_comparison_operator"
397463d1a8abSmrg	 [(match_operand:DTI 2 "spu_reg_operand" "")
397563d1a8abSmrg	  (match_operand:DTI 3 "spu_reg_operand" "")]))
397663d1a8abSmrg   (clobber (match_operand:SI 0 "spu_reg_operand"))]
397763d1a8abSmrg  ""
397863d1a8abSmrg  { spu_emit_branch_or_set (1, operands[1], operands); DONE; })
397963d1a8abSmrg
398063d1a8abSmrg(define_expand "cstore<mode>4"
398163d1a8abSmrg  [(use (match_operator 1 "ordered_comparison_operator"
398263d1a8abSmrg	 [(match_operand:VSF 2 "spu_reg_operand" "")
398363d1a8abSmrg	  (match_operand:VSF 3 "spu_reg_operand" "")]))
398463d1a8abSmrg   (clobber (match_operand:SI 0 "spu_reg_operand"))]
398563d1a8abSmrg  ""
398663d1a8abSmrg  { spu_emit_branch_or_set (1, operands[1], operands); DONE; })
398763d1a8abSmrg
398863d1a8abSmrg(define_expand "cstoredf4"
398963d1a8abSmrg  [(use (match_operator 1 "ordered_comparison_operator"
399063d1a8abSmrg	 [(match_operand:DF 2 "spu_reg_operand" "")
399163d1a8abSmrg	  (match_operand:DF 3 "spu_reg_operand" "")]))
399263d1a8abSmrg   (clobber (match_operand:SI 0 "spu_reg_operand"))]
399363d1a8abSmrg  ""
399463d1a8abSmrg  { spu_emit_branch_or_set (1, operands[1], operands); DONE; })
399563d1a8abSmrg
399663d1a8abSmrg
399763d1a8abSmrg;; conditional move
399863d1a8abSmrg
399963d1a8abSmrg;; Define this first one so HAVE_conditional_move is defined.
400063d1a8abSmrg(define_insn "movcc_dummy"
400163d1a8abSmrg  [(set (match_operand 0 "" "")
400263d1a8abSmrg       (if_then_else (match_operand 1 "" "")
400363d1a8abSmrg		     (match_operand 2 "" "")
400463d1a8abSmrg		     (match_operand 3 "" "")))]
400563d1a8abSmrg  "!operands[0]"
400663d1a8abSmrg  "")
400763d1a8abSmrg
400863d1a8abSmrg(define_expand "mov<mode>cc"
400963d1a8abSmrg  [(set (match_operand:ALL 0 "spu_reg_operand" "")
401063d1a8abSmrg	(if_then_else:ALL (match_operand 1 "ordered_comparison_operator" "")
401163d1a8abSmrg		      (match_operand:ALL 2 "spu_reg_operand" "")
401263d1a8abSmrg		      (match_operand:ALL 3 "spu_reg_operand" "")))]
401363d1a8abSmrg  ""
401463d1a8abSmrg  {
401563d1a8abSmrg    spu_emit_branch_or_set(2, operands[1], operands);
401663d1a8abSmrg    DONE;
401763d1a8abSmrg  })
401863d1a8abSmrg
401963d1a8abSmrg;; This pattern is used when the result of a compare is not large
402063d1a8abSmrg;; enough to use in a selb when expanding conditional moves.
402163d1a8abSmrg(define_expand "extend_compare"
402263d1a8abSmrg  [(set (match_operand 0 "spu_reg_operand" "=r")
402363d1a8abSmrg	(unspec [(match_operand 1 "spu_reg_operand" "r")] UNSPEC_EXTEND_CMP))]
402463d1a8abSmrg  ""
402563d1a8abSmrg  {
402663d1a8abSmrg    emit_insn (gen_rtx_SET (operands[0],
402763d1a8abSmrg			    gen_rtx_UNSPEC (GET_MODE (operands[0]),
402863d1a8abSmrg			                    gen_rtvec (1, operands[1]),
402963d1a8abSmrg					    UNSPEC_EXTEND_CMP)));
403063d1a8abSmrg    DONE;
403163d1a8abSmrg  })
403263d1a8abSmrg
403363d1a8abSmrg(define_insn "extend_compare<mode>"
403463d1a8abSmrg  [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
403563d1a8abSmrg	(unspec:ALL [(match_operand 1 "spu_reg_operand" "r")] UNSPEC_EXTEND_CMP))]
403663d1a8abSmrg  "operands != NULL"
403763d1a8abSmrg  "fsm\t%0,%1"
403863d1a8abSmrg  [(set_attr "type" "shuf")])
403963d1a8abSmrg
404063d1a8abSmrg
404163d1a8abSmrg;; case
404263d1a8abSmrg
404363d1a8abSmrg;; operand 0 is index
404463d1a8abSmrg;; operand 1 is the minimum bound
404563d1a8abSmrg;; operand 2 is the maximum bound - minimum bound + 1
404663d1a8abSmrg;; operand 3 is CODE_LABEL for the table;
404763d1a8abSmrg;; operand 4 is the CODE_LABEL to go to if index out of range.
404863d1a8abSmrg(define_expand "casesi"
404963d1a8abSmrg  [(match_operand:SI 0 "spu_reg_operand" "")
405063d1a8abSmrg   (match_operand:SI 1 "immediate_operand" "")
405163d1a8abSmrg   (match_operand:SI 2 "immediate_operand" "")
405263d1a8abSmrg   (match_operand 3 "" "")
405363d1a8abSmrg   (match_operand 4 "" "")]
405463d1a8abSmrg  ""
405563d1a8abSmrg  {
405663d1a8abSmrg    rtx table = gen_reg_rtx (SImode);
405763d1a8abSmrg    rtx index = gen_reg_rtx (SImode);
405863d1a8abSmrg    rtx sindex = gen_reg_rtx (SImode);
405963d1a8abSmrg    rtx addr = gen_reg_rtx (Pmode);
406063d1a8abSmrg
406163d1a8abSmrg    emit_move_insn (table, gen_rtx_LABEL_REF (SImode, operands[3]));
406263d1a8abSmrg
406363d1a8abSmrg    emit_insn (gen_subsi3(index, operands[0], force_reg(SImode, operands[1])));
406463d1a8abSmrg    emit_insn (gen_ashlsi3(sindex, index, GEN_INT (2)));
406563d1a8abSmrg    emit_move_insn (addr, gen_rtx_MEM (SImode,
406663d1a8abSmrg				       gen_rtx_PLUS (SImode, table, sindex)));
406763d1a8abSmrg    if (flag_pic)
406863d1a8abSmrg      emit_insn (gen_addsi3 (addr, addr, table));
406963d1a8abSmrg
407063d1a8abSmrg    emit_cmp_and_jump_insns (index, operands[2], GTU, NULL_RTX, SImode, 1, operands[4]);
407163d1a8abSmrg    emit_jump_insn (gen_tablejump (addr, operands[3]));
407263d1a8abSmrg    DONE;
407363d1a8abSmrg  })
407463d1a8abSmrg
407563d1a8abSmrg(define_insn "tablejump"
407663d1a8abSmrg  [(set (pc) (match_operand:SI 0 "spu_reg_operand" "r"))
407763d1a8abSmrg   (use (label_ref (match_operand 1 "" "")))]
407863d1a8abSmrg  ""
407963d1a8abSmrg  "bi\t%0"
408063d1a8abSmrg  [(set_attr "type" "br")])
408163d1a8abSmrg
408263d1a8abSmrg
408363d1a8abSmrg;; call
408463d1a8abSmrg
408563d1a8abSmrg;; Note that operand 1 is total size of args, in bytes,
408663d1a8abSmrg;; and what the call insn wants is the number of words.
408763d1a8abSmrg(define_expand "sibcall"
408863d1a8abSmrg  [(parallel
408963d1a8abSmrg    [(call (match_operand:QI 0 "call_operand" "")
409063d1a8abSmrg	   (match_operand:QI 1 "" ""))
409163d1a8abSmrg     (use (reg:SI 0))])]
409263d1a8abSmrg  ""
409363d1a8abSmrg  {
409463d1a8abSmrg    if (! call_operand (operands[0], QImode))
409563d1a8abSmrg      XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
409663d1a8abSmrg  })
409763d1a8abSmrg
409863d1a8abSmrg(define_insn "_sibcall"
409963d1a8abSmrg  [(parallel
410063d1a8abSmrg    [(call (match_operand:QI 0 "call_operand" "R,S")
410163d1a8abSmrg	   (match_operand:QI 1 "" "i,i"))
410263d1a8abSmrg     (use (reg:SI 0))])]
410363d1a8abSmrg  "SIBLING_CALL_P(insn)"
410463d1a8abSmrg  "@
410563d1a8abSmrg   bi\t%i0
410663d1a8abSmrg   br\t%0"
410763d1a8abSmrg   [(set_attr "type" "br,br")])
410863d1a8abSmrg
410963d1a8abSmrg(define_expand "sibcall_value"
411063d1a8abSmrg  [(parallel
411163d1a8abSmrg    [(set (match_operand 0 "" "")
411263d1a8abSmrg	  (call (match_operand:QI 1 "call_operand" "")
411363d1a8abSmrg		(match_operand:QI 2 "" "")))
411463d1a8abSmrg     (use (reg:SI 0))])]
411563d1a8abSmrg  ""
411663d1a8abSmrg  {
411763d1a8abSmrg    if (! call_operand (operands[1], QImode))
411863d1a8abSmrg      XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
411963d1a8abSmrg  })
412063d1a8abSmrg
412163d1a8abSmrg(define_insn "_sibcall_value"
412263d1a8abSmrg  [(parallel
412363d1a8abSmrg    [(set (match_operand 0 "" "")
412463d1a8abSmrg	  (call (match_operand:QI 1 "call_operand" "R,S")
412563d1a8abSmrg		(match_operand:QI 2 "" "i,i")))
412663d1a8abSmrg     (use (reg:SI 0))])]
412763d1a8abSmrg  "SIBLING_CALL_P(insn)"
412863d1a8abSmrg  "@
412963d1a8abSmrg   bi\t%i1
413063d1a8abSmrg   br\t%1"
413163d1a8abSmrg   [(set_attr "type" "br,br")])
413263d1a8abSmrg
413363d1a8abSmrg;; Note that operand 1 is total size of args, in bytes,
413463d1a8abSmrg;; and what the call insn wants is the number of words.
413563d1a8abSmrg(define_expand "call"
413663d1a8abSmrg  [(parallel
413763d1a8abSmrg    [(call (match_operand:QI 0 "call_operand" "")
413863d1a8abSmrg	   (match_operand:QI 1 "" ""))
413963d1a8abSmrg     (clobber (reg:SI 0))
414063d1a8abSmrg     (clobber (reg:SI 130))])]
414163d1a8abSmrg  ""
414263d1a8abSmrg  {
414363d1a8abSmrg    if (! call_operand (operands[0], QImode))
414463d1a8abSmrg      XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
414563d1a8abSmrg  })
414663d1a8abSmrg
414763d1a8abSmrg(define_insn "_call"
414863d1a8abSmrg  [(parallel
414963d1a8abSmrg    [(call (match_operand:QI 0 "call_operand" "R,S,T")
415063d1a8abSmrg	   (match_operand:QI 1 "" "i,i,i"))
415163d1a8abSmrg     (clobber (reg:SI 0))
415263d1a8abSmrg     (clobber (reg:SI 130))])]
415363d1a8abSmrg  ""
415463d1a8abSmrg  "@
415563d1a8abSmrg   bisl\t$lr,%i0
415663d1a8abSmrg   brsl\t$lr,%0
415763d1a8abSmrg   brasl\t$lr,%0"
415863d1a8abSmrg   [(set_attr "type" "br")])
415963d1a8abSmrg
416063d1a8abSmrg(define_expand "call_value"
416163d1a8abSmrg  [(parallel
416263d1a8abSmrg    [(set (match_operand 0 "" "")
416363d1a8abSmrg	  (call (match_operand:QI 1 "call_operand" "")
416463d1a8abSmrg		(match_operand:QI 2 "" "")))
416563d1a8abSmrg     (clobber (reg:SI 0))
416663d1a8abSmrg     (clobber (reg:SI 130))])]
416763d1a8abSmrg  ""
416863d1a8abSmrg  {
416963d1a8abSmrg    if (! call_operand (operands[1], QImode))
417063d1a8abSmrg      XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
417163d1a8abSmrg  })
417263d1a8abSmrg
417363d1a8abSmrg(define_insn "_call_value"
417463d1a8abSmrg  [(parallel
417563d1a8abSmrg    [(set (match_operand 0 "" "")
417663d1a8abSmrg	  (call (match_operand:QI 1 "call_operand" "R,S,T")
417763d1a8abSmrg		(match_operand:QI 2 "" "i,i,i")))
417863d1a8abSmrg     (clobber (reg:SI 0))
417963d1a8abSmrg     (clobber (reg:SI 130))])]
418063d1a8abSmrg  ""
418163d1a8abSmrg  "@
418263d1a8abSmrg   bisl\t$lr,%i1
418363d1a8abSmrg   brsl\t$lr,%1
418463d1a8abSmrg   brasl\t$lr,%1"
418563d1a8abSmrg   [(set_attr "type" "br")])
418663d1a8abSmrg
418763d1a8abSmrg(define_expand "untyped_call"
418863d1a8abSmrg  [(parallel [(call (match_operand 0 "" "")
418963d1a8abSmrg		    (const_int 0))
419063d1a8abSmrg	      (match_operand 1 "" "")
419163d1a8abSmrg	      (match_operand 2 "" "")])]
419263d1a8abSmrg  ""
419363d1a8abSmrg  {
419463d1a8abSmrg    int i;
419563d1a8abSmrg    rtx reg = gen_rtx_REG (TImode, 3);
419663d1a8abSmrg
419763d1a8abSmrg    /* We need to use call_value so the return value registers don't get
419863d1a8abSmrg     * clobbered. */
419963d1a8abSmrg    emit_call_insn (gen_call_value (reg, operands[0], const0_rtx));
420063d1a8abSmrg
420163d1a8abSmrg    for (i = 0; i < XVECLEN (operands[2], 0); i++)
420263d1a8abSmrg      {
420363d1a8abSmrg	rtx set = XVECEXP (operands[2], 0, i);
420463d1a8abSmrg	emit_move_insn (SET_DEST (set), SET_SRC (set));
420563d1a8abSmrg      }
420663d1a8abSmrg
420763d1a8abSmrg    /* The optimizer does not know that the call sets the function value
420863d1a8abSmrg       registers we stored in the result block.  We avoid problems by
420963d1a8abSmrg       claiming that all hard registers are used and clobbered at this
421063d1a8abSmrg       point.  */
421163d1a8abSmrg    emit_insn (gen_blockage ());
421263d1a8abSmrg
421363d1a8abSmrg    DONE;
421463d1a8abSmrg  })
421563d1a8abSmrg
421663d1a8abSmrg
421763d1a8abSmrg;; Patterns used for splitting and combining.
421863d1a8abSmrg
421963d1a8abSmrg
422063d1a8abSmrg;; Function prologue and epilogue.
422163d1a8abSmrg
422263d1a8abSmrg(define_expand "prologue"
422363d1a8abSmrg  [(const_int 1)]
422463d1a8abSmrg  ""
422563d1a8abSmrg  { spu_expand_prologue (); DONE; })
422663d1a8abSmrg
422763d1a8abSmrg;; "blockage" is only emitted in epilogue.  This is what it took to
422863d1a8abSmrg;; make "basic block reordering" work with the insns sequence
422963d1a8abSmrg;; generated by the spu_expand_epilogue (taken from mips.md)
423063d1a8abSmrg
423163d1a8abSmrg(define_insn "blockage"
423263d1a8abSmrg  [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
423363d1a8abSmrg  ""
423463d1a8abSmrg  ""
423563d1a8abSmrg  [(set_attr "type" "convert")
423663d1a8abSmrg   (set_attr "length" "0")])
423763d1a8abSmrg
423863d1a8abSmrg(define_expand "epilogue"
423963d1a8abSmrg  [(const_int 2)]
424063d1a8abSmrg  ""
424163d1a8abSmrg  { spu_expand_epilogue (false); DONE; })
424263d1a8abSmrg
424363d1a8abSmrg(define_expand "sibcall_epilogue"
424463d1a8abSmrg  [(const_int 2)]
424563d1a8abSmrg  ""
424663d1a8abSmrg  { spu_expand_epilogue (true); DONE; })
424763d1a8abSmrg
424863d1a8abSmrg
424963d1a8abSmrg;; stack manipulations
425063d1a8abSmrg
425163d1a8abSmrg;; An insn to allocate new stack space for dynamic use (e.g., alloca).
425263d1a8abSmrg;; We move the back-chain and decrement the stack pointer.
425363d1a8abSmrg(define_expand "allocate_stack"
425463d1a8abSmrg  [(set (match_operand 0 "spu_reg_operand" "")
425563d1a8abSmrg	(minus (reg 1) (match_operand 1 "spu_nonmem_operand" "")))
425663d1a8abSmrg   (set (reg 1)
425763d1a8abSmrg	(minus (reg 1) (match_dup 1)))]
425863d1a8abSmrg  ""
425963d1a8abSmrg  "spu_allocate_stack (operands[0], operands[1]); DONE;")
426063d1a8abSmrg
426163d1a8abSmrg;; These patterns say how to save and restore the stack pointer.  We need not
426263d1a8abSmrg;; save the stack pointer at function level since we are careful to preserve
426363d1a8abSmrg;; the backchain.
426463d1a8abSmrg;;
426563d1a8abSmrg
426663d1a8abSmrg;; At block level the stack pointer is saved and restored, so that the
426763d1a8abSmrg;; stack space allocated within a block is deallocated when leaving
426863d1a8abSmrg;; block scope.  By default, according to the SPU ABI, the stack
426963d1a8abSmrg;; pointer and available stack size are saved in a register. Upon
427063d1a8abSmrg;; restoration, the stack pointer is simply copied back, and the
427163d1a8abSmrg;; current available stack size is calculated against the restored
427263d1a8abSmrg;; stack pointer.
427363d1a8abSmrg;;
427463d1a8abSmrg;; For nonlocal gotos, we must save the stack pointer and its
427563d1a8abSmrg;; backchain and restore both.  Note that in the nonlocal case, the
427663d1a8abSmrg;; save area is a memory location.
427763d1a8abSmrg
427863d1a8abSmrg(define_expand "save_stack_function"
427963d1a8abSmrg  [(match_operand 0 "general_operand" "")
428063d1a8abSmrg   (match_operand 1 "general_operand" "")]
428163d1a8abSmrg  ""
428263d1a8abSmrg  "DONE;")
428363d1a8abSmrg
428463d1a8abSmrg(define_expand "restore_stack_function"
428563d1a8abSmrg  [(match_operand 0 "general_operand" "")
428663d1a8abSmrg   (match_operand 1 "general_operand" "")]
428763d1a8abSmrg  ""
428863d1a8abSmrg  "DONE;")
428963d1a8abSmrg
429063d1a8abSmrg(define_expand "restore_stack_block"
429163d1a8abSmrg  [(match_operand 0 "spu_reg_operand" "")
429263d1a8abSmrg   (match_operand 1 "memory_operand" "")]
429363d1a8abSmrg  ""
429463d1a8abSmrg  "
429563d1a8abSmrg  {
429663d1a8abSmrg    spu_restore_stack_block (operands[0], operands[1]);
429763d1a8abSmrg    DONE;
429863d1a8abSmrg  }")
429963d1a8abSmrg
430063d1a8abSmrg(define_expand "save_stack_nonlocal"
430163d1a8abSmrg  [(match_operand 0 "memory_operand" "")
430263d1a8abSmrg   (match_operand 1 "spu_reg_operand" "")]
430363d1a8abSmrg  ""
430463d1a8abSmrg  "
430563d1a8abSmrg  {
430663d1a8abSmrg    rtx temp = gen_reg_rtx (Pmode);
430763d1a8abSmrg
430863d1a8abSmrg    /* Copy the backchain to the first word, sp to the second.  We need to
430963d1a8abSmrg       save the back chain because __builtin_apply appears to clobber it. */
431063d1a8abSmrg    emit_move_insn (temp, gen_rtx_MEM (Pmode, operands[1]));
431163d1a8abSmrg    emit_move_insn (adjust_address_nv (operands[0], SImode, 0), temp);
431263d1a8abSmrg    emit_move_insn (adjust_address_nv (operands[0], SImode, 4), operands[1]);
431363d1a8abSmrg    DONE;
431463d1a8abSmrg  }")
431563d1a8abSmrg
431663d1a8abSmrg(define_expand "restore_stack_nonlocal"
431763d1a8abSmrg  [(match_operand 0 "spu_reg_operand" "")
431863d1a8abSmrg   (match_operand 1 "memory_operand" "")]
431963d1a8abSmrg  ""
432063d1a8abSmrg  "
432163d1a8abSmrg  {
432263d1a8abSmrg    spu_restore_stack_nonlocal(operands[0], operands[1]);
432363d1a8abSmrg    DONE;
432463d1a8abSmrg  }")
432563d1a8abSmrg
432663d1a8abSmrg
432763d1a8abSmrg;; vector patterns
432863d1a8abSmrg
432963d1a8abSmrg;; Vector initialization
4330c7a68eb7Smrg(define_expand "vec_init<mode><inner_l>"
433163d1a8abSmrg  [(match_operand:V 0 "register_operand" "")
433263d1a8abSmrg   (match_operand 1 "" "")]
433363d1a8abSmrg  ""
433463d1a8abSmrg  {
433563d1a8abSmrg    spu_expand_vector_init (operands[0], operands[1]);
433663d1a8abSmrg    DONE;
433763d1a8abSmrg  })
433863d1a8abSmrg
433963d1a8abSmrg(define_expand "vec_set<mode>"
434063d1a8abSmrg  [(use (match_operand:SI 2 "spu_nonmem_operand" ""))
434163d1a8abSmrg   (set (match_dup:TI 3)
434263d1a8abSmrg        (unspec:TI [(match_dup:SI 4)
434363d1a8abSmrg		    (match_dup:SI 5)
434463d1a8abSmrg		    (match_dup:SI 6)] UNSPEC_CPAT))
434563d1a8abSmrg   (set (match_operand:V 0 "spu_reg_operand" "")
434663d1a8abSmrg	(unspec:V [(match_operand:<inner> 1 "spu_reg_operand" "")
434763d1a8abSmrg		   (match_dup:V 0)
434863d1a8abSmrg		   (match_dup:TI 3)] UNSPEC_SHUFB))]
434963d1a8abSmrg  ""
435063d1a8abSmrg  {
435163d1a8abSmrg    HOST_WIDE_INT size = GET_MODE_SIZE (<inner>mode);
435263d1a8abSmrg    rtx offset = GEN_INT (INTVAL (operands[2]) * size);
435363d1a8abSmrg    operands[3] = gen_reg_rtx (TImode);
435463d1a8abSmrg    operands[4] = stack_pointer_rtx;
435563d1a8abSmrg    operands[5] = offset;
435663d1a8abSmrg    operands[6] = GEN_INT (size);
435763d1a8abSmrg  })
435863d1a8abSmrg
4359c7a68eb7Smrg(define_expand "vec_extract<mode><inner_l>"
436063d1a8abSmrg  [(set (match_operand:<inner> 0 "spu_reg_operand" "=r")
436163d1a8abSmrg	(vec_select:<inner> (match_operand:V 1 "spu_reg_operand" "r")
436263d1a8abSmrg			    (parallel [(match_operand 2 "const_int_operand" "i")])))]
436363d1a8abSmrg  ""
436463d1a8abSmrg  {
436563d1a8abSmrg    if ((INTVAL (operands[2]) * <vmult> + <voff>) % 16 == 0)
436663d1a8abSmrg      {
436763d1a8abSmrg	emit_insn (gen_spu_convert (operands[0], operands[1]));
436863d1a8abSmrg	DONE;
436963d1a8abSmrg      }
437063d1a8abSmrg  })
437163d1a8abSmrg
437263d1a8abSmrg(define_insn "_vec_extract<mode>"
437363d1a8abSmrg  [(set (match_operand:<inner> 0 "spu_reg_operand" "=r")
437463d1a8abSmrg	(vec_select:<inner> (match_operand:V 1 "spu_reg_operand" "r")
437563d1a8abSmrg			    (parallel [(match_operand 2 "const_int_operand" "i")])))]
437663d1a8abSmrg  ""
437763d1a8abSmrg  "rotqbyi\t%0,%1,(%2*<vmult>+<voff>)%%16"
437863d1a8abSmrg  [(set_attr "type" "shuf")])
437963d1a8abSmrg
438063d1a8abSmrg(define_insn "_vec_extractv8hi_ze"
438163d1a8abSmrg  [(set (match_operand:SI 0 "spu_reg_operand" "=r")
438263d1a8abSmrg	(zero_extend:SI (vec_select:HI (match_operand:V8HI 1 "spu_reg_operand" "r")
438363d1a8abSmrg				       (parallel [(const_int 0)]))))]
438463d1a8abSmrg  ""
438563d1a8abSmrg  "rotqmbyi\t%0,%1,-2"
438663d1a8abSmrg  [(set_attr "type" "shuf")])
438763d1a8abSmrg
438863d1a8abSmrg
438963d1a8abSmrg;; misc
439063d1a8abSmrg
439163d1a8abSmrg(define_expand "shufb"
439263d1a8abSmrg  [(set (match_operand 0 "spu_reg_operand" "")
439363d1a8abSmrg	(unspec [(match_operand 1 "spu_reg_operand" "")
439463d1a8abSmrg		 (match_operand 2 "spu_reg_operand" "")
439563d1a8abSmrg		 (match_operand:TI 3 "spu_reg_operand" "")] UNSPEC_SHUFB))]
439663d1a8abSmrg  ""
439763d1a8abSmrg  {
439863d1a8abSmrg    rtx s = gen__shufb (operands[0], operands[1], operands[2], operands[3]);
439963d1a8abSmrg    PUT_MODE (SET_SRC (s), GET_MODE (operands[0]));
440063d1a8abSmrg    emit_insn (s);
440163d1a8abSmrg    DONE;
440263d1a8abSmrg  })
440363d1a8abSmrg
440463d1a8abSmrg(define_insn "_shufb"
440563d1a8abSmrg  [(set (match_operand 0 "spu_reg_operand" "=r")
440663d1a8abSmrg	(unspec [(match_operand 1 "spu_reg_operand" "r")
440763d1a8abSmrg		 (match_operand 2 "spu_reg_operand" "r")
440863d1a8abSmrg		 (match_operand:TI 3 "spu_reg_operand" "r")] UNSPEC_SHUFB))]
440963d1a8abSmrg  "operands != NULL"
441063d1a8abSmrg  "shufb\t%0,%1,%2,%3"
441163d1a8abSmrg  [(set_attr "type" "shuf")])
441263d1a8abSmrg
441363d1a8abSmrg; The semantics of vec_permv16qi are nearly identical to those of the SPU
441463d1a8abSmrg; shufb instruction, except that we need to reduce the selector modulo 32.
441563d1a8abSmrg(define_expand "vec_permv16qi"
441663d1a8abSmrg  [(set (match_dup 4) (and:V16QI (match_operand:V16QI 3 "spu_reg_operand" "")
441763d1a8abSmrg                                 (match_dup 6)))
441863d1a8abSmrg   (set (match_operand:V16QI 0 "spu_reg_operand" "")
441963d1a8abSmrg	(unspec:V16QI
442063d1a8abSmrg	  [(match_operand:V16QI 1 "spu_reg_operand" "")
442163d1a8abSmrg	   (match_operand:V16QI 2 "spu_reg_operand" "")
442263d1a8abSmrg	   (match_dup 5)]
442363d1a8abSmrg	  UNSPEC_SHUFB))]
442463d1a8abSmrg  ""
442563d1a8abSmrg  {
442663d1a8abSmrg    operands[4] = gen_reg_rtx (V16QImode);
442763d1a8abSmrg    operands[5] = gen_lowpart (TImode, operands[4]);
442863d1a8abSmrg    operands[6] = spu_const (V16QImode, 31);
442963d1a8abSmrg  })
443063d1a8abSmrg
443163d1a8abSmrg(define_insn "nop"
443263d1a8abSmrg  [(unspec_volatile [(const_int 0)] UNSPECV_NOP)]
443363d1a8abSmrg  ""
443463d1a8abSmrg  "nop"
443563d1a8abSmrg  [(set_attr "type" "nop")])
443663d1a8abSmrg
443763d1a8abSmrg(define_insn "nopn"
443863d1a8abSmrg  [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "K")] UNSPECV_NOP)]
443963d1a8abSmrg  ""
444063d1a8abSmrg  "nop\t%0"
444163d1a8abSmrg  [(set_attr "type" "nop")])
444263d1a8abSmrg
444363d1a8abSmrg(define_insn "lnop"
444463d1a8abSmrg  [(unspec_volatile [(const_int 0)] UNSPECV_LNOP)]
444563d1a8abSmrg  ""
444663d1a8abSmrg  "lnop"
444763d1a8abSmrg  [(set_attr "type" "lnop")])
444863d1a8abSmrg
444963d1a8abSmrg;; The operand is so we know why we generated this hbrp.
445063d1a8abSmrg;; We clobber mem to make sure it isn't moved over any
445163d1a8abSmrg;; loads, stores or calls while scheduling.
445263d1a8abSmrg(define_insn "iprefetch"
445363d1a8abSmrg  [(unspec [(match_operand:SI 0 "const_int_operand" "n")] UNSPEC_IPREFETCH)
445463d1a8abSmrg   (clobber (mem:BLK (scratch)))]
445563d1a8abSmrg  ""
445663d1a8abSmrg  "hbrp\t# %0"
445763d1a8abSmrg  [(set_attr "type" "iprefetch")])
445863d1a8abSmrg
445963d1a8abSmrg;; A non-volatile version so it gets scheduled
446063d1a8abSmrg(define_insn "nopn_nv"
446163d1a8abSmrg  [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_NOP)]
446263d1a8abSmrg  ""
446363d1a8abSmrg  "nop\t%0"
446463d1a8abSmrg  [(set_attr "type" "nop")])
446563d1a8abSmrg
446663d1a8abSmrg(define_insn "hbr"
446763d1a8abSmrg  [(set (reg:SI 130)
446863d1a8abSmrg	(unspec:SI [(match_operand:SI 0 "immediate_operand" "i,i,i")
446963d1a8abSmrg		    (match_operand:SI 1 "nonmemory_operand" "r,s,i")] UNSPEC_HBR))
447063d1a8abSmrg   (unspec [(const_int 0)] UNSPEC_HBR)]
447163d1a8abSmrg  ""
447263d1a8abSmrg  "@
447363d1a8abSmrg   hbr\t%0,%1
447463d1a8abSmrg   hbrr\t%0,%1
447563d1a8abSmrg   hbra\t%0,%1"
447663d1a8abSmrg  [(set_attr "type" "hbr")])
447763d1a8abSmrg
447863d1a8abSmrg(define_insn "sync"
447963d1a8abSmrg  [(unspec_volatile [(const_int 0)] UNSPECV_SYNC)
448063d1a8abSmrg   (clobber (mem:BLK (scratch)))]
448163d1a8abSmrg  ""
448263d1a8abSmrg  "sync"
448363d1a8abSmrg  [(set_attr "type" "br")])
448463d1a8abSmrg
448563d1a8abSmrg(define_insn "syncc"
448663d1a8abSmrg  [(unspec_volatile [(const_int 1)] UNSPECV_SYNC)
448763d1a8abSmrg   (clobber (mem:BLK (scratch)))]
448863d1a8abSmrg  ""
448963d1a8abSmrg  "syncc"
449063d1a8abSmrg  [(set_attr "type" "br")])
449163d1a8abSmrg
449263d1a8abSmrg(define_insn "dsync"
449363d1a8abSmrg  [(unspec_volatile [(const_int 2)] UNSPECV_SYNC)
449463d1a8abSmrg   (clobber (mem:BLK (scratch)))]
449563d1a8abSmrg  ""
449663d1a8abSmrg  "dsync"
449763d1a8abSmrg  [(set_attr "type" "br")])
449863d1a8abSmrg
449963d1a8abSmrg
450063d1a8abSmrg
450163d1a8abSmrg ;; Define the subtract-one-and-jump insns so loop.c
450263d1a8abSmrg ;; knows what to generate.
450363d1a8abSmrg (define_expand "doloop_end"
450463d1a8abSmrg   [(use (match_operand 0 "" ""))      ; loop pseudo
450563d1a8abSmrg    (use (match_operand 1 "" ""))]     ; label
450663d1a8abSmrg   ""
450763d1a8abSmrg   "
450863d1a8abSmrg {
450963d1a8abSmrg   /* Currently SMS relies on the do-loop pattern to recognize loops
451063d1a8abSmrg      where (1) the control part comprises of all insns defining and/or
451163d1a8abSmrg      using a certain 'count' register and (2) the loop count can be
451263d1a8abSmrg      adjusted by modifying this register prior to the loop.
451363d1a8abSmrg.     ??? The possible introduction of a new block to initialize the
451463d1a8abSmrg      new IV can potentially effects branch optimizations.  */
451563d1a8abSmrg   if (optimize > 0 && flag_modulo_sched)
451663d1a8abSmrg   {
451763d1a8abSmrg     rtx s0;
451863d1a8abSmrg     rtx bcomp;
451963d1a8abSmrg     rtx loc_ref;
452063d1a8abSmrg
452163d1a8abSmrg     if (GET_MODE (operands[0]) != SImode)
452263d1a8abSmrg       FAIL;
452363d1a8abSmrg
452463d1a8abSmrg     s0 = operands [0];
452563d1a8abSmrg     emit_move_insn (s0, gen_rtx_PLUS (SImode, s0, GEN_INT (-1)));
452663d1a8abSmrg     bcomp = gen_rtx_NE(SImode, s0, const0_rtx);
452763d1a8abSmrg     loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands [1]);
452863d1a8abSmrg     emit_jump_insn (gen_rtx_SET (pc_rtx,
452963d1a8abSmrg                                  gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp,
453063d1a8abSmrg                                                        loc_ref, pc_rtx)));
453163d1a8abSmrg
453263d1a8abSmrg     DONE;
453363d1a8abSmrg   }else
453463d1a8abSmrg      FAIL;
453563d1a8abSmrg }")
453663d1a8abSmrg
453763d1a8abSmrg;; convert between any two modes, avoiding any GCC assumptions
453863d1a8abSmrg(define_expand "spu_convert"
453963d1a8abSmrg  [(set (match_operand 0 "spu_reg_operand" "")
454063d1a8abSmrg	(unspec [(match_operand 1 "spu_reg_operand" "")] UNSPEC_CONVERT))]
454163d1a8abSmrg  ""
454263d1a8abSmrg  {
454363d1a8abSmrg    rtx c = gen__spu_convert (operands[0], operands[1]);
454463d1a8abSmrg    PUT_MODE (SET_SRC (c), GET_MODE (operands[0]));
454563d1a8abSmrg    emit_insn (c);
454663d1a8abSmrg    DONE;
454763d1a8abSmrg  })
454863d1a8abSmrg
454963d1a8abSmrg(define_insn_and_split "_spu_convert"
455063d1a8abSmrg  [(set (match_operand 0 "spu_reg_operand" "=r")
455163d1a8abSmrg	(unspec [(match_operand 1 "spu_reg_operand" "0")] UNSPEC_CONVERT))]
455263d1a8abSmrg  ""
455363d1a8abSmrg  "#"
455463d1a8abSmrg  "reload_completed"
455563d1a8abSmrg  [(const_int 0)]
455663d1a8abSmrg  {
455763d1a8abSmrg    spu_split_convert (operands);
455863d1a8abSmrg    DONE;
455963d1a8abSmrg  }
456063d1a8abSmrg  [(set_attr "type" "convert")
456163d1a8abSmrg   (set_attr "length" "0")])
456263d1a8abSmrg
456363d1a8abSmrg
456463d1a8abSmrg;;
456563d1a8abSmrg(include "spu-builtins.md")
456663d1a8abSmrg
456763d1a8abSmrg
456863d1a8abSmrg(define_expand "smaxv4sf3"
456963d1a8abSmrg  [(set (match_operand:V4SF 0 "register_operand" "=r")
457063d1a8abSmrg        (smax:V4SF (match_operand:V4SF 1 "register_operand" "r")
457163d1a8abSmrg                 (match_operand:V4SF 2 "register_operand" "r")))]
457263d1a8abSmrg  ""
457363d1a8abSmrg  "
457463d1a8abSmrg{
457563d1a8abSmrg  rtx mask = gen_reg_rtx (V4SImode);
457663d1a8abSmrg
457763d1a8abSmrg  emit_insn (gen_cgt_v4sf (mask, operands[1], operands[2]));
457863d1a8abSmrg  emit_insn (gen_selb (operands[0], operands[2], operands[1], mask));
457963d1a8abSmrg  DONE;
458063d1a8abSmrg}")
458163d1a8abSmrg
458263d1a8abSmrg(define_expand "sminv4sf3"
458363d1a8abSmrg  [(set (match_operand:V4SF 0 "register_operand" "=r")
458463d1a8abSmrg        (smin:V4SF (match_operand:V4SF 1 "register_operand" "r")
458563d1a8abSmrg                 (match_operand:V4SF 2 "register_operand" "r")))]
458663d1a8abSmrg  ""
458763d1a8abSmrg  "
458863d1a8abSmrg{
458963d1a8abSmrg  rtx mask = gen_reg_rtx (V4SImode);
459063d1a8abSmrg
459163d1a8abSmrg  emit_insn (gen_cgt_v4sf (mask, operands[1], operands[2]));
459263d1a8abSmrg  emit_insn (gen_selb (operands[0], operands[1], operands[2], mask));
459363d1a8abSmrg  DONE;
459463d1a8abSmrg}")
459563d1a8abSmrg
459663d1a8abSmrg(define_expand "smaxv2df3"
459763d1a8abSmrg  [(set (match_operand:V2DF 0 "register_operand" "=r")
459863d1a8abSmrg        (smax:V2DF (match_operand:V2DF 1 "register_operand" "r")
459963d1a8abSmrg                 (match_operand:V2DF 2 "register_operand" "r")))]
460063d1a8abSmrg  ""
460163d1a8abSmrg  "
460263d1a8abSmrg{
460363d1a8abSmrg  rtx mask = gen_reg_rtx (V2DImode);
460463d1a8abSmrg  emit_insn (gen_cgt_v2df (mask, operands[1], operands[2]));
460563d1a8abSmrg  emit_insn (gen_selb (operands[0], operands[2], operands[1],
460663d1a8abSmrg		       spu_gen_subreg (V4SImode, mask)));
460763d1a8abSmrg  DONE;
460863d1a8abSmrg}")
460963d1a8abSmrg
461063d1a8abSmrg(define_expand "sminv2df3"
461163d1a8abSmrg  [(set (match_operand:V2DF 0 "register_operand" "=r")
461263d1a8abSmrg        (smin:V2DF (match_operand:V2DF 1 "register_operand" "r")
461363d1a8abSmrg                 (match_operand:V2DF 2 "register_operand" "r")))]
461463d1a8abSmrg  ""
461563d1a8abSmrg  "
461663d1a8abSmrg{
461763d1a8abSmrg  rtx mask = gen_reg_rtx (V2DImode);
461863d1a8abSmrg  emit_insn (gen_cgt_v2df (mask, operands[1], operands[2]));
461963d1a8abSmrg  emit_insn (gen_selb (operands[0], operands[1], operands[2],
462063d1a8abSmrg		       spu_gen_subreg (V4SImode, mask)));
462163d1a8abSmrg  DONE;
462263d1a8abSmrg}")
462363d1a8abSmrg
462463d1a8abSmrg(define_insn "vec_widen_smult_odd_v8hi"
462563d1a8abSmrg  [(set (match_operand:V4SI 0 "spu_reg_operand" "=r,r")
462663d1a8abSmrg        (mult:V4SI
462763d1a8abSmrg	  (sign_extend:V4SI
462863d1a8abSmrg	    (vec_select:V4HI
462963d1a8abSmrg	      (match_operand:V8HI 1 "spu_reg_operand" "r,r")
463063d1a8abSmrg	      (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)])))
463163d1a8abSmrg          (sign_extend:V4SI
463263d1a8abSmrg	    (vec_select:V4HI
463363d1a8abSmrg	      (match_operand:V8HI 2 "spu_arith_operand" "r,B")
463463d1a8abSmrg	      (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)])))))]
463563d1a8abSmrg  ""
463663d1a8abSmrg  "@
463763d1a8abSmrg   mpy\t%0,%1,%2
463863d1a8abSmrg   mpyi\t%0,%1,%2"
463963d1a8abSmrg  [(set_attr "type" "fp7")])
464063d1a8abSmrg
464163d1a8abSmrg(define_insn "vec_widen_umult_odd_v8hi"
464263d1a8abSmrg  [(set (match_operand:V4SI 0 "spu_reg_operand" "=r,r")
464363d1a8abSmrg        (mult:V4SI
464463d1a8abSmrg	  (zero_extend:V4SI
464563d1a8abSmrg	    (vec_select:V4HI
464663d1a8abSmrg	      (match_operand:V8HI 1 "spu_reg_operand" "r,r")
464763d1a8abSmrg	      (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)])))
464863d1a8abSmrg          (zero_extend:V4SI
464963d1a8abSmrg	    (vec_select:V4HI
465063d1a8abSmrg	      (match_operand:V8HI 2 "spu_arith_operand" "r,B")
465163d1a8abSmrg	      (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)])))))]
465263d1a8abSmrg  ""
465363d1a8abSmrg  "@
465463d1a8abSmrg   mpyu\t%0,%1,%2
465563d1a8abSmrg   mpyui\t%0,%1,%2"
465663d1a8abSmrg  [(set_attr "type" "fp7")])
465763d1a8abSmrg
465863d1a8abSmrg(define_insn "vec_widen_smult_even_v8hi"
465963d1a8abSmrg  [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
466063d1a8abSmrg	(mult:V4SI
466163d1a8abSmrg	  (sign_extend:V4SI
466263d1a8abSmrg	    (vec_select:V4HI
466363d1a8abSmrg	      (match_operand:V8HI 1 "spu_reg_operand" "r")
466463d1a8abSmrg	      (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)])))
466563d1a8abSmrg	  (sign_extend:V4SI
466663d1a8abSmrg	    (vec_select:V4HI
466763d1a8abSmrg	      (match_operand:V8HI 2 "spu_reg_operand" "r")
466863d1a8abSmrg	      (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)])))))]
466963d1a8abSmrg  ""
467063d1a8abSmrg  "mpyhh\t%0,%1,%2"
467163d1a8abSmrg  [(set_attr "type" "fp7")])
467263d1a8abSmrg
467363d1a8abSmrg(define_insn "vec_widen_umult_even_v8hi"
467463d1a8abSmrg  [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
467563d1a8abSmrg	(mult:V4SI
467663d1a8abSmrg	  (zero_extend:V4SI
467763d1a8abSmrg	    (vec_select:V4HI
467863d1a8abSmrg	      (match_operand:V8HI 1 "spu_reg_operand" "r")
467963d1a8abSmrg	      (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)])))
468063d1a8abSmrg	  (zero_extend:V4SI
468163d1a8abSmrg	    (vec_select:V4HI
468263d1a8abSmrg	      (match_operand:V8HI 2 "spu_reg_operand" "r")
468363d1a8abSmrg	      (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)])))))]
468463d1a8abSmrg  ""
468563d1a8abSmrg  "mpyhhu\t%0,%1,%2"
468663d1a8abSmrg  [(set_attr "type" "fp7")])
468763d1a8abSmrg
468863d1a8abSmrg(define_expand "vec_widen_umult_hi_v8hi"
468963d1a8abSmrg  [(set (match_operand:V4SI 0 "register_operand"   "=r")
469063d1a8abSmrg        (mult:V4SI
469163d1a8abSmrg          (zero_extend:V4SI
469263d1a8abSmrg            (vec_select:V4HI
469363d1a8abSmrg              (match_operand:V8HI 1 "register_operand" "r")
469463d1a8abSmrg              (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)])))
469563d1a8abSmrg          (zero_extend:V4SI
469663d1a8abSmrg            (vec_select:V4HI
469763d1a8abSmrg              (match_operand:V8HI 2 "register_operand" "r")
469863d1a8abSmrg              (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)])))))]
469963d1a8abSmrg  ""
470063d1a8abSmrg  "
470163d1a8abSmrg{
470263d1a8abSmrg  rtx ve = gen_reg_rtx (V4SImode);
470363d1a8abSmrg  rtx vo = gen_reg_rtx (V4SImode);
470463d1a8abSmrg  rtx mask = gen_reg_rtx (TImode);
470563d1a8abSmrg  unsigned char arr[16] = {
470663d1a8abSmrg    0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13,
470763d1a8abSmrg    0x04, 0x05, 0x06, 0x07, 0x14, 0x15, 0x16, 0x17};
470863d1a8abSmrg
470963d1a8abSmrg  emit_move_insn (mask, array_to_constant (TImode, arr));
471063d1a8abSmrg  emit_insn (gen_vec_widen_umult_even_v8hi (ve, operands[1], operands[2]));
471163d1a8abSmrg  emit_insn (gen_vec_widen_umult_odd_v8hi (vo, operands[1], operands[2]));
471263d1a8abSmrg  emit_insn (gen_shufb (operands[0], ve, vo, mask));
471363d1a8abSmrg  DONE;
471463d1a8abSmrg}")
471563d1a8abSmrg
471663d1a8abSmrg(define_expand "vec_widen_umult_lo_v8hi"
471763d1a8abSmrg  [(set (match_operand:V4SI 0 "register_operand"   "=r")
471863d1a8abSmrg        (mult:V4SI
471963d1a8abSmrg          (zero_extend:V4SI
472063d1a8abSmrg            (vec_select:V4HI
472163d1a8abSmrg              (match_operand:V8HI 1 "register_operand" "r")
472263d1a8abSmrg              (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)])))
472363d1a8abSmrg          (zero_extend:V4SI
472463d1a8abSmrg            (vec_select:V4HI
472563d1a8abSmrg              (match_operand:V8HI 2 "register_operand" "r")
472663d1a8abSmrg              (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)])))))]
472763d1a8abSmrg  ""
472863d1a8abSmrg  "
472963d1a8abSmrg{
473063d1a8abSmrg  rtx ve = gen_reg_rtx (V4SImode);
473163d1a8abSmrg  rtx vo = gen_reg_rtx (V4SImode);
473263d1a8abSmrg  rtx mask = gen_reg_rtx (TImode);
473363d1a8abSmrg  unsigned char arr[16] = {
473463d1a8abSmrg    0x08, 0x09, 0x0A, 0x0B, 0x18, 0x19, 0x1A, 0x1B,
473563d1a8abSmrg    0x0C, 0x0D, 0x0E, 0x0F, 0x1C, 0x1D, 0x1E, 0x1F};
473663d1a8abSmrg
473763d1a8abSmrg  emit_move_insn (mask, array_to_constant (TImode, arr));
473863d1a8abSmrg  emit_insn (gen_vec_widen_umult_even_v8hi (ve, operands[1], operands[2]));
473963d1a8abSmrg  emit_insn (gen_vec_widen_umult_odd_v8hi (vo, operands[1], operands[2]));
474063d1a8abSmrg  emit_insn (gen_shufb (operands[0], ve, vo, mask));
474163d1a8abSmrg  DONE;
474263d1a8abSmrg}")
474363d1a8abSmrg
474463d1a8abSmrg(define_expand "vec_widen_smult_hi_v8hi"
474563d1a8abSmrg  [(set (match_operand:V4SI 0 "register_operand"   "=r")
474663d1a8abSmrg        (mult:V4SI
474763d1a8abSmrg          (sign_extend:V4SI
474863d1a8abSmrg            (vec_select:V4HI
474963d1a8abSmrg              (match_operand:V8HI 1 "register_operand" "r")
475063d1a8abSmrg              (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)])))
475163d1a8abSmrg          (sign_extend:V4SI
475263d1a8abSmrg            (vec_select:V4HI
475363d1a8abSmrg              (match_operand:V8HI 2 "register_operand" "r")
475463d1a8abSmrg              (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)])))))]
475563d1a8abSmrg  ""
475663d1a8abSmrg  "
475763d1a8abSmrg{
475863d1a8abSmrg  rtx ve = gen_reg_rtx (V4SImode);
475963d1a8abSmrg  rtx vo = gen_reg_rtx (V4SImode);
476063d1a8abSmrg  rtx mask = gen_reg_rtx (TImode);
476163d1a8abSmrg  unsigned char arr[16] = {
476263d1a8abSmrg    0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13,
476363d1a8abSmrg    0x04, 0x05, 0x06, 0x07, 0x14, 0x15, 0x16, 0x17};
476463d1a8abSmrg
476563d1a8abSmrg  emit_move_insn (mask, array_to_constant (TImode, arr));
476663d1a8abSmrg  emit_insn (gen_vec_widen_smult_even_v8hi (ve, operands[1], operands[2]));
476763d1a8abSmrg  emit_insn (gen_vec_widen_smult_odd_v8hi (vo, operands[1], operands[2]));
476863d1a8abSmrg  emit_insn (gen_shufb (operands[0], ve, vo, mask));
476963d1a8abSmrg  DONE;
477063d1a8abSmrg}")
477163d1a8abSmrg
477263d1a8abSmrg(define_expand "vec_widen_smult_lo_v8hi"
477363d1a8abSmrg  [(set (match_operand:V4SI 0 "register_operand"   "=r")
477463d1a8abSmrg        (mult:V4SI
477563d1a8abSmrg          (sign_extend:V4SI
477663d1a8abSmrg            (vec_select:V4HI
477763d1a8abSmrg              (match_operand:V8HI 1 "register_operand" "r")
477863d1a8abSmrg              (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)])))
477963d1a8abSmrg          (sign_extend:V4SI
478063d1a8abSmrg            (vec_select:V4HI
478163d1a8abSmrg              (match_operand:V8HI 2 "register_operand" "r")
478263d1a8abSmrg              (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)])))))]
478363d1a8abSmrg  ""
478463d1a8abSmrg  "
478563d1a8abSmrg{
478663d1a8abSmrg  rtx ve = gen_reg_rtx (V4SImode);
478763d1a8abSmrg  rtx vo = gen_reg_rtx (V4SImode);
478863d1a8abSmrg  rtx mask = gen_reg_rtx (TImode);
478963d1a8abSmrg  unsigned char arr[16] = {
479063d1a8abSmrg    0x08, 0x09, 0x0A, 0x0B, 0x18, 0x19, 0x1A, 0x1B,
479163d1a8abSmrg    0x0C, 0x0D, 0x0E, 0x0F, 0x1C, 0x1D, 0x1E, 0x1F};
479263d1a8abSmrg
479363d1a8abSmrg  emit_move_insn (mask, array_to_constant (TImode, arr));
479463d1a8abSmrg  emit_insn (gen_vec_widen_smult_even_v8hi (ve, operands[1], operands[2]));
479563d1a8abSmrg  emit_insn (gen_vec_widen_smult_odd_v8hi (vo, operands[1], operands[2]));
479663d1a8abSmrg  emit_insn (gen_shufb (operands[0], ve, vo, mask));
479763d1a8abSmrg  DONE;
479863d1a8abSmrg}")
479963d1a8abSmrg
480063d1a8abSmrg(define_expand "vec_realign_load_<mode>"
480163d1a8abSmrg  [(set (match_operand:ALL 0 "register_operand" "=r")
480263d1a8abSmrg	(unspec:ALL [(match_operand:ALL 1 "register_operand" "r")
480363d1a8abSmrg		     (match_operand:ALL 2 "register_operand" "r")
480463d1a8abSmrg		     (match_operand:TI 3 "register_operand" "r")] UNSPEC_SPU_REALIGN_LOAD))]
480563d1a8abSmrg  ""
480663d1a8abSmrg  "
480763d1a8abSmrg{
480863d1a8abSmrg  emit_insn (gen_shufb (operands[0], operands[1], operands[2], operands[3]));
480963d1a8abSmrg  DONE;
481063d1a8abSmrg}")
481163d1a8abSmrg
481263d1a8abSmrg(define_expand "spu_lvsr"
481363d1a8abSmrg  [(set (match_operand:V16QI 0 "register_operand" "")
481463d1a8abSmrg        (unspec:V16QI [(match_operand 1 "memory_operand" "")] UNSPEC_SPU_MASK_FOR_LOAD))]
481563d1a8abSmrg  ""
481663d1a8abSmrg  "
481763d1a8abSmrg{
481863d1a8abSmrg  rtx addr;
481963d1a8abSmrg  rtx offset = gen_reg_rtx (V8HImode);
482063d1a8abSmrg  rtx addr_bits = gen_reg_rtx (SImode);
482163d1a8abSmrg  rtx addr_bits_vec = gen_reg_rtx (V8HImode);
482263d1a8abSmrg  rtx splatqi = gen_reg_rtx (TImode);
482363d1a8abSmrg  rtx result = gen_reg_rtx (V8HImode);
482463d1a8abSmrg  unsigned char arr[16] = {
482563d1a8abSmrg    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
482663d1a8abSmrg    0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F};
482763d1a8abSmrg  unsigned char arr2[16] = {
482863d1a8abSmrg    0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
482963d1a8abSmrg    0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03};
483063d1a8abSmrg
483163d1a8abSmrg  emit_move_insn (offset, array_to_constant (V8HImode, arr));
483263d1a8abSmrg  emit_move_insn (splatqi, array_to_constant (TImode, arr2));
483363d1a8abSmrg
483463d1a8abSmrg  gcc_assert (GET_CODE (operands[1]) == MEM);
483563d1a8abSmrg  addr = force_reg (Pmode, XEXP (operands[1], 0));
483663d1a8abSmrg  emit_insn (gen_andsi3 (addr_bits, addr, GEN_INT (0xF)));
483763d1a8abSmrg  emit_insn (gen_shufb (addr_bits_vec, addr_bits, addr_bits, splatqi));
483863d1a8abSmrg
483963d1a8abSmrg  /* offset - (addr & 0xF)
484063d1a8abSmrg     It is safe to use a single sfh, because each byte of offset is > 15 and
484163d1a8abSmrg     each byte of addr is <= 15. */
484263d1a8abSmrg  emit_insn (gen_subv8hi3 (result, offset, addr_bits_vec));
484363d1a8abSmrg
484463d1a8abSmrg  result = simplify_gen_subreg (V16QImode, result, V8HImode, 0);
484563d1a8abSmrg  emit_move_insn (operands[0], result);
484663d1a8abSmrg
484763d1a8abSmrg  DONE;
484863d1a8abSmrg}")
484963d1a8abSmrg
485063d1a8abSmrg(define_expand "vec_unpacku_hi_v8hi"
485163d1a8abSmrg  [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
485263d1a8abSmrg        (zero_extend:V4SI
485363d1a8abSmrg          (vec_select:V4HI
485463d1a8abSmrg            (match_operand:V8HI 1 "spu_reg_operand" "r")
485563d1a8abSmrg            (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)]))))]
485663d1a8abSmrg  ""
485763d1a8abSmrg{
485863d1a8abSmrg  rtx mask = gen_reg_rtx (TImode);
485963d1a8abSmrg  unsigned char arr[16] = {
486063d1a8abSmrg    0x80, 0x80, 0x00, 0x01, 0x80, 0x80, 0x02, 0x03,
486163d1a8abSmrg    0x80, 0x80, 0x04, 0x05, 0x80, 0x80, 0x06, 0x07};
486263d1a8abSmrg
486363d1a8abSmrg  emit_move_insn (mask, array_to_constant (TImode, arr));
486463d1a8abSmrg  emit_insn (gen_shufb (operands[0], operands[1], operands[1], mask));
486563d1a8abSmrg
486663d1a8abSmrg  DONE;
486763d1a8abSmrg})
486863d1a8abSmrg
486963d1a8abSmrg(define_expand "vec_unpacku_lo_v8hi"
487063d1a8abSmrg  [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
487163d1a8abSmrg         (zero_extend:V4SI
487263d1a8abSmrg          (vec_select:V4HI
487363d1a8abSmrg            (match_operand:V8HI 1 "spu_reg_operand" "r")
487463d1a8abSmrg            (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)]))))]
487563d1a8abSmrg""
487663d1a8abSmrg{
487763d1a8abSmrg  rtx mask = gen_reg_rtx (TImode);
487863d1a8abSmrg  unsigned char arr[16] = {
487963d1a8abSmrg    0x80, 0x80, 0x08, 0x09, 0x80, 0x80, 0x0A, 0x0B,
488063d1a8abSmrg    0x80, 0x80, 0x0C, 0x0D, 0x80, 0x80, 0x0E, 0x0F};
488163d1a8abSmrg
488263d1a8abSmrg  emit_move_insn (mask, array_to_constant (TImode, arr));
488363d1a8abSmrg  emit_insn (gen_shufb (operands[0], operands[1], operands[1], mask));
488463d1a8abSmrg
488563d1a8abSmrg  DONE;
488663d1a8abSmrg})
488763d1a8abSmrg
488863d1a8abSmrg(define_expand "vec_unpacks_hi_v8hi"
488963d1a8abSmrg  [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
489063d1a8abSmrg         (sign_extend:V4SI
489163d1a8abSmrg          (vec_select:V4HI
489263d1a8abSmrg            (match_operand:V8HI 1 "spu_reg_operand" "r")
489363d1a8abSmrg            (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)]))))]
489463d1a8abSmrg  ""
489563d1a8abSmrg{
489663d1a8abSmrg  rtx tmp1 = gen_reg_rtx (V8HImode);
489763d1a8abSmrg  rtx tmp2 = gen_reg_rtx (V4SImode);
489863d1a8abSmrg  rtx mask = gen_reg_rtx (TImode);
489963d1a8abSmrg  unsigned char arr[16] = {
490063d1a8abSmrg    0x80, 0x80, 0x00, 0x01, 0x80, 0x80, 0x02, 0x03,
490163d1a8abSmrg    0x80, 0x80, 0x04, 0x05, 0x80, 0x80, 0x06, 0x07};
490263d1a8abSmrg
490363d1a8abSmrg  emit_move_insn (mask, array_to_constant (TImode, arr));
490463d1a8abSmrg  emit_insn (gen_shufb (tmp1, operands[1], operands[1], mask));
490563d1a8abSmrg  emit_insn (gen_spu_xshw (tmp2, tmp1));
490663d1a8abSmrg  emit_move_insn (operands[0], tmp2);
490763d1a8abSmrg
490863d1a8abSmrg  DONE;
490963d1a8abSmrg})
491063d1a8abSmrg
491163d1a8abSmrg(define_expand "vec_unpacks_lo_v8hi"
491263d1a8abSmrg  [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
491363d1a8abSmrg         (sign_extend:V4SI
491463d1a8abSmrg          (vec_select:V4HI
491563d1a8abSmrg            (match_operand:V8HI 1 "spu_reg_operand" "r")
491663d1a8abSmrg            (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)]))))]
491763d1a8abSmrg""
491863d1a8abSmrg{
491963d1a8abSmrg  rtx tmp1 = gen_reg_rtx (V8HImode);
492063d1a8abSmrg  rtx tmp2 = gen_reg_rtx (V4SImode);
492163d1a8abSmrg  rtx mask = gen_reg_rtx (TImode);
492263d1a8abSmrg  unsigned char arr[16] = {
492363d1a8abSmrg    0x80, 0x80, 0x08, 0x09, 0x80, 0x80, 0x0A, 0x0B,
492463d1a8abSmrg    0x80, 0x80, 0x0C, 0x0D, 0x80, 0x80, 0x0E, 0x0F};
492563d1a8abSmrg
492663d1a8abSmrg  emit_move_insn (mask, array_to_constant (TImode, arr));
492763d1a8abSmrg  emit_insn (gen_shufb (tmp1, operands[1], operands[1], mask));
492863d1a8abSmrg  emit_insn (gen_spu_xshw (tmp2, tmp1));
492963d1a8abSmrg  emit_move_insn (operands[0], tmp2);
493063d1a8abSmrg
493163d1a8abSmrgDONE;
493263d1a8abSmrg})
493363d1a8abSmrg
493463d1a8abSmrg(define_expand "vec_unpacku_hi_v16qi"
493563d1a8abSmrg  [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
493663d1a8abSmrg        (zero_extend:V8HI
493763d1a8abSmrg          (vec_select:V8QI
493863d1a8abSmrg            (match_operand:V16QI 1 "spu_reg_operand" "r")
493963d1a8abSmrg            (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)
494063d1a8abSmrg                       (const_int 4)(const_int 5)(const_int 6)(const_int 7)]))))]
494163d1a8abSmrg  ""
494263d1a8abSmrg{
494363d1a8abSmrg  rtx mask = gen_reg_rtx (TImode);
494463d1a8abSmrg  unsigned char arr[16] = {
494563d1a8abSmrg    0x80, 0x00, 0x80, 0x01, 0x80, 0x02, 0x80, 0x03,
494663d1a8abSmrg    0x80, 0x04, 0x80, 0x05, 0x80, 0x06, 0x80, 0x07};
494763d1a8abSmrg
494863d1a8abSmrg  emit_move_insn (mask, array_to_constant (TImode, arr));
494963d1a8abSmrg  emit_insn (gen_shufb (operands[0], operands[1], operands[1], mask));
495063d1a8abSmrg
495163d1a8abSmrg  DONE;
495263d1a8abSmrg})
495363d1a8abSmrg
495463d1a8abSmrg(define_expand "vec_unpacku_lo_v16qi"
495563d1a8abSmrg  [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
495663d1a8abSmrg          (zero_extend:V8HI
495763d1a8abSmrg          (vec_select:V8QI
495863d1a8abSmrg            (match_operand:V16QI 1 "spu_reg_operand" "r")
495963d1a8abSmrg            (parallel [(const_int 8)(const_int 9)(const_int 10)(const_int 11)
496063d1a8abSmrg                       (const_int 12)(const_int 13)(const_int 14)(const_int 15)]))))]
496163d1a8abSmrg""
496263d1a8abSmrg{
496363d1a8abSmrg  rtx mask = gen_reg_rtx (TImode);
496463d1a8abSmrg  unsigned char arr[16] = {
496563d1a8abSmrg    0x80, 0x08, 0x80, 0x09, 0x80, 0x0A, 0x80, 0x0B,
496663d1a8abSmrg    0x80, 0x0C, 0x80, 0x0D, 0x80, 0x0E, 0x80, 0x0F};
496763d1a8abSmrg
496863d1a8abSmrg  emit_move_insn (mask, array_to_constant (TImode, arr));
496963d1a8abSmrg  emit_insn (gen_shufb (operands[0], operands[1], operands[1], mask));
497063d1a8abSmrg
497163d1a8abSmrg  DONE;
497263d1a8abSmrg})
497363d1a8abSmrg
497463d1a8abSmrg(define_expand "vec_unpacks_hi_v16qi"
497563d1a8abSmrg  [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
497663d1a8abSmrg         (sign_extend:V8HI
497763d1a8abSmrg          (vec_select:V8QI
497863d1a8abSmrg            (match_operand:V16QI 1 "spu_reg_operand" "r")
497963d1a8abSmrg            (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)
498063d1a8abSmrg                       (const_int 4)(const_int 5)(const_int 6)(const_int 7)]))))]
498163d1a8abSmrg""
498263d1a8abSmrg{
498363d1a8abSmrg  rtx tmp1 = gen_reg_rtx (V16QImode);
498463d1a8abSmrg  rtx tmp2 = gen_reg_rtx (V8HImode);
498563d1a8abSmrg  rtx mask = gen_reg_rtx (TImode);
498663d1a8abSmrg  unsigned char arr[16] = {
498763d1a8abSmrg    0x80, 0x00, 0x80, 0x01, 0x80, 0x02, 0x80, 0x03,
498863d1a8abSmrg    0x80, 0x04, 0x80, 0x05, 0x80, 0x06, 0x80, 0x07};
498963d1a8abSmrg
499063d1a8abSmrg  emit_move_insn (mask, array_to_constant (TImode, arr));
499163d1a8abSmrg  emit_insn (gen_shufb (tmp1, operands[1], operands[1], mask));
499263d1a8abSmrg  emit_insn (gen_spu_xsbh (tmp2, tmp1));
499363d1a8abSmrg  emit_move_insn (operands[0], tmp2);
499463d1a8abSmrg
499563d1a8abSmrg  DONE;
499663d1a8abSmrg})
499763d1a8abSmrg
499863d1a8abSmrg(define_expand "vec_unpacks_lo_v16qi"
499963d1a8abSmrg  [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
500063d1a8abSmrg         (sign_extend:V8HI
500163d1a8abSmrg          (vec_select:V8QI
500263d1a8abSmrg            (match_operand:V16QI 1 "spu_reg_operand" "r")
500363d1a8abSmrg            (parallel [(const_int 8)(const_int 9)(const_int 10)(const_int 11)
500463d1a8abSmrg                       (const_int 12)(const_int 13)(const_int 14)(const_int 15)]))))]
500563d1a8abSmrg""
500663d1a8abSmrg{
500763d1a8abSmrg  rtx tmp1 = gen_reg_rtx (V16QImode);
500863d1a8abSmrg  rtx tmp2 = gen_reg_rtx (V8HImode);
500963d1a8abSmrg  rtx mask = gen_reg_rtx (TImode);
501063d1a8abSmrg  unsigned char arr[16] = {
501163d1a8abSmrg    0x80, 0x08, 0x80, 0x09, 0x80, 0x0A, 0x80, 0x0B,
501263d1a8abSmrg    0x80, 0x0C, 0x80, 0x0D, 0x80, 0x0E, 0x80, 0x0F};
501363d1a8abSmrg
501463d1a8abSmrg  emit_move_insn (mask, array_to_constant (TImode, arr));
501563d1a8abSmrg  emit_insn (gen_shufb (tmp1, operands[1], operands[1], mask));
501663d1a8abSmrg  emit_insn (gen_spu_xsbh (tmp2, tmp1));
501763d1a8abSmrg  emit_move_insn (operands[0], tmp2);
501863d1a8abSmrg
501963d1a8abSmrgDONE;
502063d1a8abSmrg})
502163d1a8abSmrg
502263d1a8abSmrg
502363d1a8abSmrg(define_expand "vec_pack_trunc_v8hi"
502463d1a8abSmrg  [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
502563d1a8abSmrg	(vec_concat:V16QI
502663d1a8abSmrg          (truncate:V8QI (match_operand:V8HI 1 "spu_reg_operand" "r"))
502763d1a8abSmrg          (truncate:V8QI (match_operand:V8HI 2 "spu_reg_operand" "r"))))]
502863d1a8abSmrg  ""
502963d1a8abSmrg  "
503063d1a8abSmrg{
503163d1a8abSmrg  rtx mask = gen_reg_rtx (TImode);
503263d1a8abSmrg  unsigned char arr[16] = {
503363d1a8abSmrg    0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0D, 0x0F,
503463d1a8abSmrg    0x11, 0x13, 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F};
503563d1a8abSmrg
503663d1a8abSmrg  emit_move_insn (mask, array_to_constant (TImode, arr));
503763d1a8abSmrg  emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
503863d1a8abSmrg
503963d1a8abSmrg  DONE;
504063d1a8abSmrg}")
504163d1a8abSmrg
504263d1a8abSmrg(define_expand "vec_pack_trunc_v4si"
504363d1a8abSmrg  [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
504463d1a8abSmrg	(vec_concat:V8HI
504563d1a8abSmrg          (truncate:V4HI (match_operand:V4SI 1 "spu_reg_operand" "r"))
504663d1a8abSmrg          (truncate:V4HI (match_operand:V4SI 2 "spu_reg_operand" "r"))))]
504763d1a8abSmrg  ""
504863d1a8abSmrg  "
504963d1a8abSmrg{
505063d1a8abSmrg  rtx mask = gen_reg_rtx (TImode);
505163d1a8abSmrg  unsigned char arr[16] = {
505263d1a8abSmrg    0x02, 0x03, 0x06, 0x07, 0x0A, 0x0B, 0x0E, 0x0F,
505363d1a8abSmrg    0x12, 0x13, 0x16, 0x17, 0x1A, 0x1B, 0x1E, 0x1F};
505463d1a8abSmrg
505563d1a8abSmrg  emit_move_insn (mask, array_to_constant (TImode, arr));
505663d1a8abSmrg  emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
505763d1a8abSmrg
505863d1a8abSmrg  DONE;
505963d1a8abSmrg}")
506063d1a8abSmrg
506163d1a8abSmrg(define_insn "stack_protect_set"
506263d1a8abSmrg  [(set (match_operand:SI 0 "memory_operand" "=m")
506363d1a8abSmrg        (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
506463d1a8abSmrg   (set (match_scratch:SI 2 "=&r") (const_int 0))]
506563d1a8abSmrg  ""
506663d1a8abSmrg  "lq%p1\t%2,%1\;stq%p0\t%2,%0\;xor\t%2,%2,%2"
506763d1a8abSmrg  [(set_attr "length" "12")
506863d1a8abSmrg   (set_attr "type" "multi1")]
506963d1a8abSmrg)
507063d1a8abSmrg
507163d1a8abSmrg(define_expand "stack_protect_test"
507263d1a8abSmrg  [(match_operand 0 "memory_operand" "")
507363d1a8abSmrg   (match_operand 1 "memory_operand" "")
507463d1a8abSmrg   (match_operand 2 "" "")]
507563d1a8abSmrg  ""
507663d1a8abSmrg{
507763d1a8abSmrg  rtx compare_result;
507863d1a8abSmrg  rtx bcomp, loc_ref;
507963d1a8abSmrg
508063d1a8abSmrg  compare_result = gen_reg_rtx (SImode);
508163d1a8abSmrg
508263d1a8abSmrg  emit_insn (gen_stack_protect_test_si (compare_result,
508363d1a8abSmrg                                        operands[0],
508463d1a8abSmrg                                        operands[1]));
508563d1a8abSmrg
508663d1a8abSmrg  bcomp = gen_rtx_NE (SImode, compare_result, const0_rtx);
508763d1a8abSmrg
508863d1a8abSmrg  loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[2]);
508963d1a8abSmrg
509063d1a8abSmrg  emit_jump_insn (gen_rtx_SET (pc_rtx,
509163d1a8abSmrg                               gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp,
509263d1a8abSmrg                                                     loc_ref, pc_rtx)));
509363d1a8abSmrg
509463d1a8abSmrg  DONE;
509563d1a8abSmrg})
509663d1a8abSmrg
509763d1a8abSmrg(define_insn "stack_protect_test_si"
509863d1a8abSmrg  [(set (match_operand:SI 0 "spu_reg_operand" "=&r")
509963d1a8abSmrg        (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
510063d1a8abSmrg                    (match_operand:SI 2 "memory_operand" "m")]
510163d1a8abSmrg                   UNSPEC_SP_TEST))
510263d1a8abSmrg   (set (match_scratch:SI 3 "=&r") (const_int 0))]
510363d1a8abSmrg  ""
510463d1a8abSmrg  "lq%p1\t%0,%1\;lq%p2\t%3,%2\;ceq\t%0,%0,%3\;xor\t%3,%3,%3"
510563d1a8abSmrg  [(set_attr "length" "16")
510663d1a8abSmrg   (set_attr "type" "multi1")]
510763d1a8abSmrg)
510863d1a8abSmrg
510963d1a8abSmrg; Atomic operations
511063d1a8abSmrg;
511163d1a8abSmrg; SPU execution is always single-threaded, so there is no need for real
511263d1a8abSmrg; atomic operations.  We provide the atomic primitives anyway so that
511363d1a8abSmrg; code expecting the builtins to be present (like libgfortran) will work.
511463d1a8abSmrg
511563d1a8abSmrg;; Types that we should provide atomic instructions for.
511663d1a8abSmrg(define_mode_iterator AINT [QI HI SI DI TI])
511763d1a8abSmrg
511863d1a8abSmrg(define_code_iterator ATOMIC [plus minus ior xor and mult])
511963d1a8abSmrg(define_code_attr atomic_name
512063d1a8abSmrg  [(plus "add") (minus "sub")
512163d1a8abSmrg   (ior "or") (xor "xor") (and "and") (mult "nand")])
512263d1a8abSmrg(define_code_attr atomic_pred
512363d1a8abSmrg  [(plus "spu_arith_operand") (minus "spu_reg_operand")
512463d1a8abSmrg   (ior "spu_logical_operand") (xor "spu_logical_operand")
512563d1a8abSmrg   (and "spu_logical_operand") (mult "spu_logical_operand")])
512663d1a8abSmrg
512763d1a8abSmrg(define_expand "atomic_load<mode>"
512863d1a8abSmrg  [(set (match_operand:AINT 0 "spu_reg_operand" "")		;; output
512963d1a8abSmrg	(match_operand:AINT 1 "memory_operand" ""))		;; memory
513063d1a8abSmrg   (use (match_operand:SI 2 "const_int_operand" ""))]		;; model
513163d1a8abSmrg  ""
513263d1a8abSmrg{
513363d1a8abSmrg  if (MEM_ADDR_SPACE (operands[1]))
513463d1a8abSmrg    FAIL;
513563d1a8abSmrg
513663d1a8abSmrg  emit_move_insn (operands[0], operands[1]);
513763d1a8abSmrg  DONE;
513863d1a8abSmrg})
513963d1a8abSmrg
514063d1a8abSmrg(define_expand "atomic_store<mode>"
514163d1a8abSmrg  [(set (match_operand:AINT 0 "memory_operand" "")		;; memory
514263d1a8abSmrg	(match_operand:AINT 1 "spu_reg_operand" ""))		;; input
514363d1a8abSmrg   (use (match_operand:SI 2 "const_int_operand" ""))]		;; model
514463d1a8abSmrg  ""
514563d1a8abSmrg{
514663d1a8abSmrg  if (MEM_ADDR_SPACE (operands[0]))
514763d1a8abSmrg    FAIL;
514863d1a8abSmrg
514963d1a8abSmrg  emit_move_insn (operands[0], operands[1]);
515063d1a8abSmrg  DONE;
515163d1a8abSmrg})
515263d1a8abSmrg
515363d1a8abSmrg(define_expand "atomic_compare_and_swap<mode>"
515463d1a8abSmrg  [(match_operand:SI 0 "spu_reg_operand" "")		;; bool out
515563d1a8abSmrg   (match_operand:AINT 1 "spu_reg_operand" "")		;; val out
515663d1a8abSmrg   (match_operand:AINT 2 "memory_operand" "")		;; memory
515763d1a8abSmrg   (match_operand:AINT 3 "spu_nonmem_operand" "")	;; expected
515863d1a8abSmrg   (match_operand:AINT 4 "spu_nonmem_operand" "")	;; desired
515963d1a8abSmrg   (match_operand:SI 5 "const_int_operand" "")		;; is_weak
516063d1a8abSmrg   (match_operand:SI 6 "const_int_operand" "")		;; model succ
516163d1a8abSmrg   (match_operand:SI 7 "const_int_operand" "")]		;; model fail
516263d1a8abSmrg  ""
516363d1a8abSmrg{
516463d1a8abSmrg  rtx boolval, retval, label;
516563d1a8abSmrg
516663d1a8abSmrg  if (MEM_ADDR_SPACE (operands[2]))
516763d1a8abSmrg    FAIL;
516863d1a8abSmrg
516963d1a8abSmrg  boolval = gen_reg_rtx (SImode);
517063d1a8abSmrg  retval = gen_reg_rtx (<MODE>mode);
517163d1a8abSmrg  label = gen_label_rtx ();
517263d1a8abSmrg
517363d1a8abSmrg  emit_move_insn (retval, operands[2]);
517463d1a8abSmrg  emit_move_insn (boolval, const0_rtx);
517563d1a8abSmrg
517663d1a8abSmrg  emit_cmp_and_jump_insns (retval, operands[3], NE, NULL_RTX,
517763d1a8abSmrg                           <MODE>mode, 1, label);
517863d1a8abSmrg
517963d1a8abSmrg  emit_move_insn (operands[2], operands[4]);
518063d1a8abSmrg  emit_move_insn (boolval, const1_rtx);
518163d1a8abSmrg
518263d1a8abSmrg  emit_label (label);
518363d1a8abSmrg
518463d1a8abSmrg  emit_move_insn (operands[0], boolval);
518563d1a8abSmrg  emit_move_insn (operands[1], retval);
518663d1a8abSmrg  DONE;
518763d1a8abSmrg})
518863d1a8abSmrg
518963d1a8abSmrg(define_expand "atomic_exchange<mode>"
519063d1a8abSmrg  [(match_operand:AINT 0 "spu_reg_operand" "")		;; output
519163d1a8abSmrg   (match_operand:AINT 1 "memory_operand" "")		;; memory
519263d1a8abSmrg   (match_operand:AINT 2 "spu_nonmem_operand" "")	;; input
519363d1a8abSmrg   (match_operand:SI 3 "const_int_operand" "")]		;; model
519463d1a8abSmrg  ""
519563d1a8abSmrg{
519663d1a8abSmrg  rtx retval;
519763d1a8abSmrg
519863d1a8abSmrg  if (MEM_ADDR_SPACE (operands[1]))
519963d1a8abSmrg    FAIL;
520063d1a8abSmrg
520163d1a8abSmrg  retval = gen_reg_rtx (<MODE>mode);
520263d1a8abSmrg
520363d1a8abSmrg  emit_move_insn (retval, operands[1]);
520463d1a8abSmrg  emit_move_insn (operands[1], operands[2]);
520563d1a8abSmrg  emit_move_insn (operands[0], retval);
520663d1a8abSmrg  DONE;
520763d1a8abSmrg})
520863d1a8abSmrg
520963d1a8abSmrg(define_expand "atomic_<atomic_name><mode>"
521063d1a8abSmrg  [(ATOMIC:AINT
521163d1a8abSmrg     (match_operand:AINT 0 "memory_operand" "")		;; memory
521263d1a8abSmrg     (match_operand:AINT 1 "<atomic_pred>" ""))		;; operand
521363d1a8abSmrg   (match_operand:SI 2 "const_int_operand" "")]		;; model
521463d1a8abSmrg  ""
521563d1a8abSmrg{
521663d1a8abSmrg  if (MEM_ADDR_SPACE (operands[0]))
521763d1a8abSmrg    FAIL;
521863d1a8abSmrg
521963d1a8abSmrg  spu_expand_atomic_op (<CODE>, operands[0], operands[1],
522063d1a8abSmrg			NULL_RTX, NULL_RTX);
522163d1a8abSmrg  DONE;
522263d1a8abSmrg})
522363d1a8abSmrg
522463d1a8abSmrg(define_expand "atomic_fetch_<atomic_name><mode>"
522563d1a8abSmrg  [(match_operand:AINT 0 "spu_reg_operand" "")		;; output
522663d1a8abSmrg   (ATOMIC:AINT
522763d1a8abSmrg     (match_operand:AINT 1 "memory_operand" "")		;; memory
522863d1a8abSmrg     (match_operand:AINT 2 "<atomic_pred>" ""))		;; operand
522963d1a8abSmrg   (match_operand:SI 3 "const_int_operand" "")]		;; model
523063d1a8abSmrg  ""
523163d1a8abSmrg{
523263d1a8abSmrg  if (MEM_ADDR_SPACE (operands[1]))
523363d1a8abSmrg    FAIL;
523463d1a8abSmrg
523563d1a8abSmrg  spu_expand_atomic_op (<CODE>, operands[1], operands[2],
523663d1a8abSmrg			operands[0], NULL_RTX);
523763d1a8abSmrg  DONE;
523863d1a8abSmrg})
523963d1a8abSmrg
524063d1a8abSmrg(define_expand "atomic_<atomic_name>_fetch<mode>"
524163d1a8abSmrg  [(match_operand:AINT 0 "spu_reg_operand" "")		;; output
524263d1a8abSmrg   (ATOMIC:AINT
524363d1a8abSmrg     (match_operand:AINT 1 "memory_operand" "")		;; memory
524463d1a8abSmrg     (match_operand:AINT 2 "<atomic_pred>" ""))		;; operand
524563d1a8abSmrg   (match_operand:SI 3 "const_int_operand" "")]		;; model
524663d1a8abSmrg  ""
524763d1a8abSmrg{
524863d1a8abSmrg  if (MEM_ADDR_SPACE (operands[1]))
524963d1a8abSmrg    FAIL;
525063d1a8abSmrg
525163d1a8abSmrg  spu_expand_atomic_op (<CODE>, operands[1], operands[2],
525263d1a8abSmrg			NULL_RTX, operands[0]);
525363d1a8abSmrg  DONE;
525463d1a8abSmrg})
525563d1a8abSmrg
5256