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