2009-06-03 Richard Guenther <rguenther@suse.de>
[official-gcc.git] / gcc / config / spu / spu.md
blob181d0db991c50fbb619acdf9e7a9e8b6d325acc0
1 ;; Copyright (C) 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
3 ;; This file is free software; you can redistribute it and/or modify it under
4 ;; the terms of the GNU General Public License as published by the Free
5 ;; Software Foundation; either version 3 of the License, or (at your option) 
6 ;; any later version.
8 ;; This file is distributed in the hope that it will be useful, but WITHOUT
9 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 ;; FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
11 ;; for more details.
13 ;; You should have received a copy of the GNU General Public License
14 ;; along with GCC; see the file COPYING3.  If not see
15 ;; <http://www.gnu.org/licenses/>.
17 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
20 ;; Define an insn type attribute.  This is used in function unit delay
21 ;; computations.
22 ;; multi0 is a multiple insn rtl whose first insn is in pipe0
23 ;; multi1 is a multiple insn rtl whose first insn is in pipe1
24 (define_attr "type" "fx2,shuf,fx3,load,store,br,spr,lnop,nop,fxb,fp6,fp7,fpd,iprefetch,multi0,multi1,hbr,convert"
25   (const_string "fx2"))
27 ;; Length (in bytes).
28 (define_attr "length" ""
29                 (const_int 4))
31 (define_attr "tune" "cell,celledp" (const (symbol_ref "spu_tune")))
32 ;; Processor type -- this attribute must exactly match the processor_type
33 ;; enumeration in spu.h.
35 (define_attr "cpu" "spu"
36   (const (symbol_ref "spu_cpu_attr")))
38 ; (define_function_unit NAME MULTIPLICITY SIMULTANEITY
39 ;                       TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST])
41 (define_cpu_unit "pipe0,pipe1,fp,ls")
43 (define_insn_reservation "NOP" 1 (eq_attr "type" "nop")
44     "pipe0")
46 (define_insn_reservation "FX2" 2 (eq_attr "type" "fx2")
47     "pipe0, nothing")
49 (define_insn_reservation "FX3" 4 (eq_attr "type" "fx3,fxb")
50     "pipe0, nothing*3")
52 (define_insn_reservation "FP6" 6 (eq_attr "type" "fp6")
53     "pipe0 + fp, nothing*5")
55 (define_insn_reservation "FP7" 7 (eq_attr "type" "fp7")
56     "pipe0, fp, nothing*5")
58 ;; The behavior of the double precision is that both pipes stall
59 ;; for 6 cycles and the rest of the operation pipelines for
60 ;; 7 cycles.  The simplest way to model this is to simply ignore
61 ;; the 6 cyle stall.
62 (define_insn_reservation "FPD" 7 
63   (and (eq_attr "tune" "cell")
64        (eq_attr "type" "fpd"))
65     "pipe0 + pipe1, fp, nothing*5")
67 ;; Tune for CELLEDP, 9 cycles, dual-issuable, fully pipelined
68 (define_insn_reservation "FPD_CELLEDP" 9
69   (and (eq_attr "tune" "celledp")
70        (eq_attr "type" "fpd"))
71   "pipe0 + fp, nothing*8")
73 (define_insn_reservation "LNOP" 1 (eq_attr "type" "lnop")
74     "pipe1")
76 (define_insn_reservation "STORE" 1 (eq_attr "type" "store")
77     "pipe1 + ls")
79 (define_insn_reservation "IPREFETCH" 1 (eq_attr "type" "iprefetch")
80     "pipe1 + ls")
82 (define_insn_reservation "SHUF" 4 (eq_attr "type" "shuf,br,spr")
83     "pipe1, nothing*3")
85 (define_insn_reservation "LOAD" 6 (eq_attr "type" "load")
86     "pipe1 + ls, nothing*5")
88 (define_insn_reservation "HBR" 18 (eq_attr "type" "hbr")
89     "pipe1, nothing*15")
91 (define_insn_reservation "MULTI0" 4 (eq_attr "type" "multi0")
92     "pipe0+pipe1, nothing*3")
94 (define_insn_reservation "MULTI1" 4 (eq_attr "type" "multi1")
95     "pipe1, nothing*3")
97 (define_insn_reservation "CONVERT" 0 (eq_attr "type" "convert")
98     "nothing")
100 ;; Force pipe0 to occur before pipe 1 in a cycle.
101 (absence_set "pipe0" "pipe1")
104 (define_constants [
105  (UNSPEC_BLOCKAGE       0)
106  (UNSPEC_IPREFETCH      1)
107  (UNSPEC_FREST          2)
108  (UNSPEC_FRSQEST        3)
109  (UNSPEC_FI             4)
110  (UNSPEC_EXTEND_CMP     5)
111  (UNSPEC_CG             6)
112  (UNSPEC_CGX            7)
113  (UNSPEC_ADDX           8)
114  (UNSPEC_BG             9)
115  (UNSPEC_BGX            10)
116  (UNSPEC_SFX            11)
117  (UNSPEC_FSM            12)
118  (UNSPEC_HBR            13)
119  (UNSPEC_LNOP           14)
120  (UNSPEC_NOP            15)
121  (UNSPEC_CONVERT        16)
122  (UNSPEC_SELB           17)
123  (UNSPEC_SHUFB          18)
124  (UNSPEC_CPAT           19)
125  (UNSPEC_SYNC           20)
126  (UNSPEC_CNTB           21)
127  (UNSPEC_SUMB           22)
128  (UNSPEC_FSMB           23)
129  (UNSPEC_FSMH           24)
130  (UNSPEC_GBB            25)
131  (UNSPEC_GBH            26)
132  (UNSPEC_GB             27)
133  (UNSPEC_AVGB           28)
134  (UNSPEC_ABSDB          29)
135  (UNSPEC_ORX            30)
136  (UNSPEC_HEQ            31)
137  (UNSPEC_HGT            32)
138  (UNSPEC_HLGT           33)
139  (UNSPEC_STOP           38)
140  (UNSPEC_STOPD          39)
141  (UNSPEC_SET_INTR       40)
142  (UNSPEC_FSCRRD         42)
143  (UNSPEC_FSCRWR         43)
144  (UNSPEC_MFSPR          44)
145  (UNSPEC_MTSPR          45)
146  (UNSPEC_RDCH           46)
147  (UNSPEC_RCHCNT         47)
148  (UNSPEC_WRCH           48)
149  (UNSPEC_SPU_REALIGN_LOAD 49)
150  (UNSPEC_SPU_MASK_FOR_LOAD 50)
151  (UNSPEC_DFTSV           51)
152  (UNSPEC_FLOAT_EXTEND    52)
153  (UNSPEC_FLOAT_TRUNCATE  53)
154  (UNSPEC_SP_SET         54)
155  (UNSPEC_SP_TEST        55) 
158 (include "predicates.md")
159 (include "constraints.md")
162 ;; Mode iterators
164 (define_mode_iterator ALL [QI V16QI
165                         HI V8HI
166                         SI V4SI
167                         DI V2DI
168                         TI
169                         SF V4SF
170                         DF V2DF])
172 ; Everything except DI and TI which are handled separately because
173 ; they need different constraints to correctly test VOIDmode constants
174 (define_mode_iterator MOV [QI V16QI
175                         HI V8HI
176                         SI V4SI
177                         V2DI
178                         SF V4SF
179                         DF V2DF])
181 (define_mode_iterator QHSI  [QI HI SI])
182 (define_mode_iterator QHSDI  [QI HI SI DI])
183 (define_mode_iterator DTI  [DI TI])
185 (define_mode_iterator VINT [QI V16QI
186                          HI V8HI
187                          SI V4SI
188                          DI V2DI
189                          TI])
191 (define_mode_iterator VQHSI [QI V16QI
192                           HI V8HI
193                           SI V4SI])
195 (define_mode_iterator VHSI [HI V8HI
196                          SI V4SI])
198 (define_mode_iterator VSDF [SF V4SF
199                          DF V2DF])
201 (define_mode_iterator VSI [SI V4SI])
202 (define_mode_iterator VDI [DI V2DI])
203 (define_mode_iterator VSF [SF V4SF])
204 (define_mode_iterator VDF [DF V2DF])
206 (define_mode_iterator VCMP [V16QI
207                          V8HI
208                          V4SI
209                          V4SF
210                          V2DF])
212 (define_mode_iterator VCMPU [V16QI
213                           V8HI
214                           V4SI])
216 (define_mode_attr v      [(V8HI  "v") (V4SI  "v")
217                           (HI    "") (SI    "")])
219 (define_mode_attr bh  [(QI "b")  (V16QI "b")
220                        (HI "h")  (V8HI "h")
221                        (SI "")   (V4SI "")])
223 (define_mode_attr d   [(SF "")   (V4SF "")
224                        (DF "d")  (V2DF "d")])
225 (define_mode_attr d6  [(SF "6")  (V4SF "6")
226                        (DF "d")  (V2DF "d")])
228 (define_mode_attr f2i [(SF "si") (V4SF "v4si")
229                        (DF "di") (V2DF "v2di")])
230 (define_mode_attr F2I [(SF "SI") (V4SF "V4SI")
231                        (DF "DI") (V2DF "V2DI")])
232 (define_mode_attr i2f [(SI "sf") (V4SI "v4sf")
233                        (DI "df") (V2DI "v2df")])
234 (define_mode_attr I2F [(SI "SF") (V4SI "V4SF")
235                        (DI "DF") (V2DI "V2DF")])
237 (define_mode_attr DF2I [(DF "SI") (V2DF "V2DI")])
239 (define_mode_attr umask  [(HI "f")  (V8HI "f")
240                           (SI "g")  (V4SI "g")])
241 (define_mode_attr nmask  [(HI "F")  (V8HI "F")
242                           (SI "G")  (V4SI "G")])
244 ;; Used for carry and borrow instructions.
245 (define_mode_iterator CBOP  [SI DI V4SI V2DI])
247 ;; Used in vec_set and vec_extract
248 (define_mode_iterator V [V2DI V4SI V8HI V16QI V2DF V4SF])
249 (define_mode_attr inner  [(V16QI "QI")
250                           (V8HI  "HI")
251                           (V4SI  "SI")
252                           (V2DI  "DI")
253                           (V4SF  "SF")
254                           (V2DF  "DF")])
255 (define_mode_attr vmult  [(V16QI "1")
256                           (V8HI  "2")
257                           (V4SI  "4")
258                           (V2DI  "8")
259                           (V4SF  "4")
260                           (V2DF  "8")])
261 (define_mode_attr voff   [(V16QI "13")
262                           (V8HI  "14")
263                           (V4SI  "0")
264                           (V2DI  "0")
265                           (V4SF  "0")
266                           (V2DF  "0")])
269 ;; mov
271 (define_expand "mov<mode>"
272   [(set (match_operand:ALL 0 "spu_nonimm_operand" "=r,r,r,m")
273         (match_operand:ALL 1 "general_operand" "r,i,m,r"))]
274   ""
275   {
276     if (spu_expand_mov(operands, <MODE>mode))
277       DONE;
278   })
280 (define_split 
281   [(set (match_operand 0 "spu_reg_operand")
282         (match_operand 1 "immediate_operand"))]
284   ""
285   [(set (match_dup 0)
286         (high (match_dup 1)))
287    (set (match_dup 0)
288         (lo_sum (match_dup 0)
289                 (match_dup 1)))]
290   {
291     if (spu_split_immediate (operands))
292       DONE;
293     FAIL;
294   })
296 (define_insn "pic"
297   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
298         (match_operand:SI 1 "immediate_operand" "s"))
299    (use (const_int 0))]
300   "flag_pic"
301   "ila\t%0,%%pic(%1)")
303 ;; Whenever a function generates the 'pic' pattern above we need to
304 ;; load the pic_offset_table register.
305 ;; GCC doesn't deal well with labels in the middle of a block so we
306 ;; hardcode the offsets in the asm here.
307 (define_insn "load_pic_offset"
308   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
309         (unspec:SI [(const_int 0)] 0))
310    (set (match_operand:SI 1 "spu_reg_operand" "=r")
311         (unspec:SI [(const_int 0)] 0))]
312   "flag_pic"
313   "ila\t%1,.+8\;brsl\t%0,4"
314   [(set_attr "length" "8")
315    (set_attr "type" "multi0")])
318 ;; move internal
320 (define_insn "_mov<mode>"
321   [(set (match_operand:MOV 0 "spu_dest_operand" "=r,r,r,r,r,m")
322         (match_operand:MOV 1 "spu_mov_operand" "r,A,f,j,m,r"))]
323   "register_operand(operands[0], <MODE>mode)
324    || register_operand(operands[1], <MODE>mode)"
325   "@
326    ori\t%0,%1,0
327    il%s1\t%0,%S1
328    fsmbi\t%0,%S1
329    c%s1d\t%0,%S1($sp)
330    lq%p1\t%0,%1
331    stq%p0\t%1,%0"
332   [(set_attr "type" "fx2,fx2,shuf,shuf,load,store")])
334 (define_insn "low_<mode>"
335   [(set (match_operand:VSI 0 "spu_reg_operand" "=r")
336         (lo_sum:VSI (match_operand:VSI 1 "spu_reg_operand" "0")
337                     (match_operand:VSI 2 "immediate_operand" "i")))]
338   ""
339   "iohl\t%0,%2@l")
341 (define_insn "_movdi"
342   [(set (match_operand:DI 0 "spu_dest_operand" "=r,r,r,r,r,m")
343         (match_operand:DI 1 "spu_mov_operand" "r,a,f,k,m,r"))]
344   "register_operand(operands[0], DImode)
345    || register_operand(operands[1], DImode)"
346   "@
347    ori\t%0,%1,0
348    il%d1\t%0,%D1
349    fsmbi\t%0,%D1
350    c%d1d\t%0,%D1($sp)
351    lq%p1\t%0,%1
352    stq%p0\t%1,%0"
353   [(set_attr "type" "fx2,fx2,shuf,shuf,load,store")])
355 (define_insn "_movti"
356   [(set (match_operand:TI 0 "spu_dest_operand" "=r,r,r,r,r,m")
357         (match_operand:TI 1 "spu_mov_operand" "r,U,f,l,m,r"))]
358   "register_operand(operands[0], TImode)
359    || register_operand(operands[1], TImode)"
360   "@
361    ori\t%0,%1,0
362    il%t1\t%0,%T1
363    fsmbi\t%0,%T1
364    c%t1d\t%0,%T1($sp)
365    lq%p1\t%0,%1
366    stq%p0\t%1,%0"
367   [(set_attr "type" "fx2,fx2,shuf,shuf,load,store")])
369 (define_split
370   [(set (match_operand 0 "spu_reg_operand")
371         (match_operand 1 "memory_operand"))]
372   "GET_MODE_SIZE (GET_MODE (operands[0])) < 16
373    && GET_MODE(operands[0]) == GET_MODE(operands[1])
374    && !reload_in_progress && !reload_completed" 
375   [(set (match_dup 0)
376         (match_dup 1))]
377   { if (spu_split_load(operands))
378       DONE;
379   })
381 (define_split
382   [(set (match_operand 0 "memory_operand")
383         (match_operand 1 "spu_reg_operand"))]
384   "GET_MODE_SIZE (GET_MODE (operands[0])) < 16
385    && GET_MODE(operands[0]) == GET_MODE(operands[1])
386    && !reload_in_progress && !reload_completed" 
387   [(set (match_dup 0)
388         (match_dup 1))]
389   { if (spu_split_store(operands))
390       DONE;
391   })
392 ;; Operand 3 is the number of bytes. 1:b 2:h 4:w 8:d
394 (define_expand "cpat"
395   [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
396         (unspec:TI [(match_operand:SI 1 "spu_reg_operand" "r,r")
397                     (match_operand:SI 2 "spu_nonmem_operand" "r,n")
398                     (match_operand:SI 3 "immediate_operand" "i,i")] UNSPEC_CPAT))]
399   ""
400   {
401     rtx x = gen_cpat_const (operands);
402     if (x)
403       {
404         emit_move_insn (operands[0], x);
405         DONE;
406       }
407   })
409 (define_insn "_cpat"
410   [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
411         (unspec:TI [(match_operand:SI 1 "spu_reg_operand" "r,r")
412                     (match_operand:SI 2 "spu_nonmem_operand" "r,n")
413                     (match_operand:SI 3 "immediate_operand" "i,i")] UNSPEC_CPAT))]
414   ""
415   "@
416    c%M3x\t%0,%1,%2
417    c%M3d\t%0,%C2(%1)"
418   [(set_attr "type" "shuf")])
420 (define_split
421   [(set (match_operand:TI 0 "spu_reg_operand")
422         (unspec:TI [(match_operand:SI 1 "spu_nonmem_operand")
423                     (match_operand:SI 2 "immediate_operand")
424                     (match_operand:SI 3 "immediate_operand")] UNSPEC_CPAT))]
425   ""
426   [(set (match_dup:TI 0)
427         (match_dup:TI 4))]
428   {
429     operands[4] = gen_cpat_const (operands);
430     if (!operands[4])
431       FAIL;
432   })
434 ;; extend
436 (define_insn "extendqihi2"
437   [(set (match_operand:HI 0 "spu_reg_operand" "=r")
438         (sign_extend:HI (match_operand:QI 1 "spu_reg_operand" "r")))]
439   ""
440   "xsbh\t%0,%1")
442 (define_insn "extendhisi2"
443   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
444         (sign_extend:SI (match_operand:HI 1 "spu_reg_operand" "r")))]
445   ""
446   "xshw\t%0,%1")
448 (define_expand "extendsidi2"
449   [(set (match_dup:DI 2)
450         (zero_extend:DI (match_operand:SI 1 "spu_reg_operand" "")))
451    (set (match_operand:DI 0 "spu_reg_operand" "")
452         (sign_extend:DI (vec_select:SI (match_dup:V2SI 3)
453                                        (parallel [(const_int 1)]))))]
454   ""
455   {
456     operands[2] = gen_reg_rtx (DImode);
457     operands[3] = spu_gen_subreg (V2SImode, operands[2]);
458   })
460 (define_insn "xswd"
461   [(set (match_operand:DI 0 "spu_reg_operand" "=r")
462         (sign_extend:DI
463           (vec_select:SI
464             (match_operand:V2SI 1 "spu_reg_operand" "r")
465             (parallel [(const_int 1) ]))))]
466   ""
467   "xswd\t%0,%1");
469 ;; By splitting this late we don't allow much opportunity for sharing of
470 ;; constants.  That's ok because this should really be optimized away.
471 (define_insn_and_split "extend<mode>ti2"
472   [(set (match_operand:TI 0 "register_operand" "")
473         (sign_extend:TI (match_operand:QHSDI 1 "register_operand" "")))]
474   ""
475   "#"
476   ""
477   [(set (match_dup:TI 0)
478         (sign_extend:TI (match_dup:QHSDI 1)))]
479   {
480     spu_expand_sign_extend(operands);
481     DONE;
482   })
485 ;; zero_extend
487 (define_insn "zero_extendqihi2"
488   [(set (match_operand:HI 0 "spu_reg_operand" "=r")
489         (zero_extend:HI (match_operand:QI 1 "spu_reg_operand" "r")))]
490   ""
491   "andi\t%0,%1,0x00ff")
493 (define_insn "zero_extendqisi2"
494   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
495         (zero_extend:SI (match_operand:QI 1 "spu_reg_operand" "r")))]
496   ""
497   "andi\t%0,%1,0x00ff")
499 (define_expand "zero_extendhisi2"
500   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
501         (zero_extend:SI (match_operand:HI 1 "spu_reg_operand" "r")))
502    (clobber (match_scratch:SI 2 "=&r"))]
503   ""
504   {
505     rtx mask = gen_reg_rtx (SImode);
506     rtx op1 = simplify_gen_subreg (SImode, operands[1], HImode, 0);
507     emit_move_insn (mask, GEN_INT (0xffff));
508     emit_insn (gen_andsi3(operands[0], op1, mask));
509     DONE;
510   })
511   
512 (define_insn "zero_extendsidi2"
513   [(set (match_operand:DI 0 "spu_reg_operand" "=r")
514         (zero_extend:DI (match_operand:SI 1 "spu_reg_operand" "r")))]
515   ""
516   "rotqmbyi\t%0,%1,-4"
517   [(set_attr "type" "shuf")])
519 (define_insn "zero_extendqiti2"
520   [(set (match_operand:TI 0 "spu_reg_operand" "=r")
521         (zero_extend:TI (match_operand:QI 1 "spu_reg_operand" "r")))]
522   ""
523   "andi\t%0,%1,0x00ff\;rotqmbyi\t%0,%0,-12"
524   [(set_attr "type" "multi0")
525    (set_attr "length" "8")])
527 (define_insn "zero_extendhiti2"
528   [(set (match_operand:TI 0 "spu_reg_operand" "=r")
529         (zero_extend:TI (match_operand:HI 1 "spu_reg_operand" "r")))]
530   ""
531   "shli\t%0,%1,16\;rotqmbyi\t%0,%0,-14"
532   [(set_attr "type" "multi1")
533    (set_attr "length" "8")])
535 (define_insn "zero_extendsiti2"
536   [(set (match_operand:TI 0 "spu_reg_operand" "=r")
537         (zero_extend:TI (match_operand:SI 1 "spu_reg_operand" "r")))]
538   ""
539   "rotqmbyi\t%0,%1,-12"
540   [(set_attr "type" "shuf")])
542 (define_insn "zero_extendditi2"
543   [(set (match_operand:TI 0 "spu_reg_operand" "=r")
544         (zero_extend:TI (match_operand:DI 1 "spu_reg_operand" "r")))]
545   ""
546   "rotqmbyi\t%0,%1,-8"
547   [(set_attr "type" "shuf")])
550 ;; trunc
552 (define_insn "truncdiqi2"
553   [(set (match_operand:QI 0 "spu_reg_operand" "=r")
554         (truncate:QI (match_operand:DI 1 "spu_reg_operand" "r")))]
555   ""
556   "shlqbyi\t%0,%1,4"
557   [(set_attr "type" "shuf")])
559 (define_insn "truncdihi2"
560   [(set (match_operand:HI 0 "spu_reg_operand" "=r")
561         (truncate:HI (match_operand:DI 1 "spu_reg_operand" "r")))]
562   ""
563   "shlqbyi\t%0,%1,4"
564   [(set_attr "type" "shuf")])
566 (define_insn "truncdisi2"
567   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
568         (truncate:SI (match_operand:DI 1 "spu_reg_operand" "r")))]
569   ""
570   "shlqbyi\t%0,%1,4"
571   [(set_attr "type" "shuf")])
573 (define_insn "trunctiqi2"
574   [(set (match_operand:QI 0 "spu_reg_operand" "=r")
575         (truncate:QI (match_operand:TI 1 "spu_reg_operand" "r")))]
576   ""
577   "shlqbyi\t%0,%1,12"
578   [(set_attr "type" "shuf")])
580 (define_insn "trunctihi2"
581   [(set (match_operand:HI 0 "spu_reg_operand" "=r")
582         (truncate:HI (match_operand:TI 1 "spu_reg_operand" "r")))]
583   ""
584   "shlqbyi\t%0,%1,12"
585   [(set_attr "type" "shuf")])
587 (define_insn "trunctisi2"
588   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
589         (truncate:SI (match_operand:TI 1 "spu_reg_operand" "r")))]
590   ""
591   "shlqbyi\t%0,%1,12"
592   [(set_attr "type" "shuf")])
594 (define_insn "trunctidi2"
595   [(set (match_operand:DI 0 "spu_reg_operand" "=r")
596         (truncate:DI (match_operand:TI 1 "spu_reg_operand" "r")))]
597   ""
598   "shlqbyi\t%0,%1,8"
599   [(set_attr "type" "shuf")])
602 ;; float conversions
604 (define_insn "float<mode><i2f>2"
605   [(set (match_operand:<I2F> 0 "spu_reg_operand" "=r")
606         (float:<I2F> (match_operand:VSI 1 "spu_reg_operand" "r")))]
607   ""
608   "csflt\t%0,%1,0"
609   [(set_attr "type" "fp7")])
611 (define_insn "fix_trunc<mode><f2i>2"
612   [(set (match_operand:<F2I> 0 "spu_reg_operand" "=r")
613         (fix:<F2I> (match_operand:VSF 1 "spu_reg_operand" "r")))]
614   ""
615   "cflts\t%0,%1,0"
616   [(set_attr "type" "fp7")])
618 (define_insn "floatuns<mode><i2f>2"
619   [(set (match_operand:<I2F> 0 "spu_reg_operand" "=r")
620         (unsigned_float:<I2F> (match_operand:VSI 1 "spu_reg_operand" "r")))]
621   ""
622   "cuflt\t%0,%1,0"
623   [(set_attr "type" "fp7")])
625 (define_insn "fixuns_trunc<mode><f2i>2"
626   [(set (match_operand:<F2I> 0 "spu_reg_operand" "=r")
627         (unsigned_fix:<F2I> (match_operand:VSF 1 "spu_reg_operand" "r")))]
628   ""
629   "cfltu\t%0,%1,0"
630   [(set_attr "type" "fp7")])
632 (define_insn "float<mode><i2f>2_mul"
633   [(set (match_operand:<I2F> 0 "spu_reg_operand" "=r")
634         (mult:<I2F> (float:<I2F> (match_operand:VSI 1 "spu_reg_operand" "r"))
635                     (match_operand:<I2F> 2 "spu_inv_exp2_operand" "w")))]
636   ""
637   "csflt\t%0,%1,%w2"
638   [(set_attr "type" "fp7")])
640 (define_insn "float<mode><i2f>2_div"
641   [(set (match_operand:<I2F> 0 "spu_reg_operand" "=r")
642         (div:<I2F> (float:<I2F> (match_operand:VSI 1 "spu_reg_operand" "r"))
643                    (match_operand:<I2F> 2 "spu_exp2_operand" "v")))]
644   ""
645   "csflt\t%0,%1,%v2"
646   [(set_attr "type" "fp7")])
649 (define_insn "fix_trunc<mode><f2i>2_mul"
650   [(set (match_operand:<F2I> 0 "spu_reg_operand" "=r")
651         (fix:<F2I> (mult:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
652                              (match_operand:VSF 2 "spu_exp2_operand" "v"))))]
653   ""
654   "cflts\t%0,%1,%v2"
655   [(set_attr "type" "fp7")])
657 (define_insn "floatuns<mode><i2f>2_mul"
658   [(set (match_operand:<I2F> 0 "spu_reg_operand" "=r")
659         (mult:<I2F> (unsigned_float:<I2F> (match_operand:VSI 1 "spu_reg_operand" "r"))
660                     (match_operand:<I2F> 2 "spu_inv_exp2_operand" "w")))]
661   ""
662   "cuflt\t%0,%1,%w2"
663   [(set_attr "type" "fp7")])
665 (define_insn "floatuns<mode><i2f>2_div"
666   [(set (match_operand:<I2F> 0 "spu_reg_operand" "=r")
667         (div:<I2F> (unsigned_float:<I2F> (match_operand:VSI 1 "spu_reg_operand" "r"))
668                    (match_operand:<I2F> 2 "spu_exp2_operand" "v")))]
669   ""
670   "cuflt\t%0,%1,%v2"
671   [(set_attr "type" "fp7")])
673 (define_insn "fixuns_trunc<mode><f2i>2_mul"
674   [(set (match_operand:<F2I> 0 "spu_reg_operand" "=r")
675         (unsigned_fix:<F2I> (mult:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
676                                       (match_operand:VSF 2 "spu_exp2_operand" "v"))))]
677   ""
678   "cfltu\t%0,%1,%v2"
679   [(set_attr "type" "fp7")])
681 (define_insn "extendsfdf2"
682   [(set (match_operand:DF 0 "spu_reg_operand" "=r")
683         (unspec:DF [(match_operand:SF 1 "spu_reg_operand" "r")]
684                    UNSPEC_FLOAT_EXTEND))]
685   ""
686   "fesd\t%0,%1"
687   [(set_attr "type" "fpd")])
689 (define_insn "truncdfsf2"
690   [(set (match_operand:SF 0 "spu_reg_operand" "=r")
691         (unspec:SF [(match_operand:DF 1 "spu_reg_operand" "r")]
692                    UNSPEC_FLOAT_TRUNCATE))]
693   ""
694   "frds\t%0,%1"
695   [(set_attr "type" "fpd")])
697 (define_expand "floatdisf2"
698   [(set (match_operand:SF 0 "register_operand" "")
699         (float:SF (match_operand:DI 1 "register_operand" "")))]
700   ""
701   {
702     rtx c0 = gen_reg_rtx (SImode);
703     rtx r0 = gen_reg_rtx (DImode);
704     rtx r1 = gen_reg_rtx (SFmode);
705     rtx r2 = gen_reg_rtx (SImode);
706     rtx setneg = gen_reg_rtx (SImode);
707     rtx isneg = gen_reg_rtx (SImode);
708     rtx neg = gen_reg_rtx (DImode);
709     rtx mask = gen_reg_rtx (DImode);
711     emit_move_insn (c0, GEN_INT (-0x80000000ll));
713     emit_insn (gen_negdi2 (neg, operands[1]));
714     emit_insn (gen_cgt_di_m1 (isneg, operands[1]));
715     emit_insn (gen_extend_compare (mask, isneg));
716     emit_insn (gen_selb (r0, neg, operands[1], mask));
717     emit_insn (gen_andc_si (setneg, c0, isneg));
719     emit_insn (gen_floatunsdisf2 (r1, r0));
721     emit_insn (gen_iorsi3 (r2, gen_rtx_SUBREG (SImode, r1, 0), setneg));
722     emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, r2, 0));
723     DONE;
724   })
726 (define_insn_and_split "floatunsdisf2"
727   [(set (match_operand:SF 0 "register_operand" "=r")
728         (unsigned_float:SF (match_operand:DI 1 "register_operand" "r")))
729    (clobber (match_scratch:SF 2 "=r"))
730    (clobber (match_scratch:SF 3 "=r"))
731    (clobber (match_scratch:SF 4 "=r"))]
732   ""
733   "#"
734   "reload_completed"
735   [(set (match_dup:SF 0)
736         (unsigned_float:SF (match_dup:DI 1)))]
737   {
738     rtx op1_v4si = gen_rtx_REG (V4SImode, REGNO (operands[1]));
739     rtx op2_v4sf = gen_rtx_REG (V4SFmode, REGNO (operands[2]));
740     rtx op2_ti = gen_rtx_REG (TImode, REGNO (operands[2]));
741     rtx op3_ti = gen_rtx_REG (TImode, REGNO (operands[3]));
743     REAL_VALUE_TYPE scale;
744     real_2expN (&scale, 32, SFmode);
746     emit_insn (gen_floatunsv4siv4sf2 (op2_v4sf, op1_v4si));
747     emit_insn (gen_shlqby_ti (op3_ti, op2_ti, GEN_INT (4)));
749     emit_move_insn (operands[4],
750                     CONST_DOUBLE_FROM_REAL_VALUE (scale, SFmode));
751     emit_insn (gen_fma_sf (operands[0],
752                            operands[2], operands[4], operands[3]));
753     DONE;
754   })
756 ;; Do (double)(operands[1]+0x80000000u)-(double)0x80000000
757 (define_expand "floatsidf2"
758   [(set (match_operand:DF 0 "register_operand" "")
759         (float:DF (match_operand:SI 1 "register_operand" "")))]
760   ""
761   {
762     rtx c0 = gen_reg_rtx (SImode);
763     rtx c1 = gen_reg_rtx (DFmode);
764     rtx r0 = gen_reg_rtx (SImode);
765     rtx r1 = gen_reg_rtx (DFmode);
767     emit_move_insn (c0, GEN_INT (-0x80000000ll));
768     emit_move_insn (c1, spu_float_const ("2147483648", DFmode));
769     emit_insn (gen_xorsi3 (r0, operands[1], c0));
770     emit_insn (gen_floatunssidf2 (r1, r0));
771     emit_insn (gen_subdf3 (operands[0], r1, c1));
772     DONE;
773   })
775 (define_expand "floatunssidf2"
776   [(set (match_operand:DF 0 "register_operand"  "=r")
777         (unsigned_float:DF (match_operand:SI 1 "register_operand"   "r")))]
778   ""
779   "{
780     rtx value, insns;
781     rtx c0 = spu_const_from_ints (V16QImode, 0x02031011, 0x12138080, 
782                                              0x06071415, 0x16178080);
783     rtx r0 = gen_reg_rtx (V16QImode);
785     if (optimize_size)
786     {
787        start_sequence ();
788        value =
789          emit_library_call_value (convert_optab_libfunc (ufloat_optab,
790                                                          DFmode, SImode),
791                    NULL_RTX, LCT_NORMAL, DFmode, 1, operands[1], SImode);
792        insns = get_insns ();
793        end_sequence ();
794        emit_libcall_block (insns, operands[0], value,
795                            gen_rtx_UNSIGNED_FLOAT (DFmode, operands[1]));
796      }
797      else
798      {
799       emit_move_insn (r0, c0);
800       emit_insn (gen_floatunssidf2_internal (operands[0], operands[1], r0));
801      }
802     DONE;
803   }")
805 (define_insn_and_split "floatunssidf2_internal"
806   [(set (match_operand:DF 0 "register_operand"  "=r")
807         (unsigned_float:DF (match_operand:SI 1 "register_operand"   "r")))
808    (use (match_operand:V16QI 2 "register_operand" "r"))
809    (clobber (match_scratch:V4SI 3 "=&r"))
810    (clobber (match_scratch:V4SI 4 "=&r"))
811    (clobber (match_scratch:V4SI 5 "=&r"))
812    (clobber (match_scratch:V4SI 6 "=&r"))]
813   ""
814   "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"
815   "reload_completed"
816   [(set (match_dup:DF 0)
817         (unsigned_float:DF (match_dup:SI 1)))]
818  "{
819     rtx *ops = operands;
820     rtx op1_v4si = gen_rtx_REG(V4SImode, REGNO(ops[1]));
821     rtx op0_ti = gen_rtx_REG (TImode, REGNO (ops[0]));
822     rtx op2_ti = gen_rtx_REG (TImode, REGNO (ops[2]));
823     rtx op6_ti = gen_rtx_REG (TImode, REGNO (ops[6]));
824     emit_insn (gen_clzv4si2 (ops[3],op1_v4si));
825     emit_move_insn (ops[6], spu_const (V4SImode, 1023+31));
826     emit_insn (gen_vashlv4si3 (ops[4],op1_v4si,ops[3]));
827     emit_insn (gen_ceq_v4si (ops[5],ops[3],spu_const (V4SImode, 32)));
828     emit_insn (gen_subv4si3 (ops[6],ops[6],ops[3]));
829     emit_insn (gen_addv4si3 (ops[4],ops[4],ops[4]));
830     emit_insn (gen_andc_v4si  (ops[6],ops[6],ops[5]));
831     emit_insn (gen_shufb (ops[6],ops[6],ops[4],op2_ti));
832     emit_insn (gen_shlqbi_ti (op0_ti,op6_ti,GEN_INT(4)));
833     DONE;
834   }"
835  [(set_attr "length" "32")])
837 (define_expand "floatdidf2"
838   [(set (match_operand:DF 0 "register_operand" "")
839         (float:DF (match_operand:DI 1 "register_operand" "")))]
840   ""
841   {
842     rtx c0 = gen_reg_rtx (DImode);
843     rtx r0 = gen_reg_rtx (DImode);
844     rtx r1 = gen_reg_rtx (DFmode);
845     rtx r2 = gen_reg_rtx (DImode);
846     rtx setneg = gen_reg_rtx (DImode);
847     rtx isneg = gen_reg_rtx (SImode);
848     rtx neg = gen_reg_rtx (DImode);
849     rtx mask = gen_reg_rtx (DImode);
851     emit_move_insn (c0, GEN_INT (0x8000000000000000ull));
853     emit_insn (gen_negdi2 (neg, operands[1]));
854     emit_insn (gen_cgt_di_m1 (isneg, operands[1]));
855     emit_insn (gen_extend_compare (mask, isneg));
856     emit_insn (gen_selb (r0, neg, operands[1], mask));
857     emit_insn (gen_andc_di (setneg, c0, mask));
859     emit_insn (gen_floatunsdidf2 (r1, r0));
861     emit_insn (gen_iordi3 (r2, gen_rtx_SUBREG (DImode, r1, 0), setneg));
862     emit_move_insn (operands[0], gen_rtx_SUBREG (DFmode, r2, 0));
863     DONE;
864   })
866 (define_expand "floatunsdidf2"
867   [(set (match_operand:DF 0 "register_operand"  "=r")
868         (unsigned_float:DF (match_operand:DI 1 "register_operand"   "r")))]
869   ""
870   "{
871     rtx value, insns;
872     rtx c0 = spu_const_from_ints (V16QImode, 0x02031011, 0x12138080, 
873                                              0x06071415, 0x16178080);
874     rtx c1 = spu_const_from_ints (V4SImode, 1023+63, 1023+31, 0, 0);
875     rtx r0 = gen_reg_rtx (V16QImode);
876     rtx r1 = gen_reg_rtx (V4SImode);
878     if (optimize_size)
879     {      
880       start_sequence ();
881       value =
882          emit_library_call_value (convert_optab_libfunc (ufloat_optab,
883                                                          DFmode, DImode),
884                    NULL_RTX, LCT_NORMAL, DFmode, 1, operands[1], DImode);
885       insns = get_insns ();
886       end_sequence ();
887       emit_libcall_block (insns, operands[0], value,
888                           gen_rtx_UNSIGNED_FLOAT (DFmode, operands[1]));
889     }
890     else
891     {
892       emit_move_insn (r1, c1);
893       emit_move_insn (r0, c0);
894       emit_insn (gen_floatunsdidf2_internal (operands[0], operands[1], r0, r1));
895     }
896     DONE;
897   }")
899 (define_insn_and_split "floatunsdidf2_internal"
900   [(set (match_operand:DF 0 "register_operand"  "=r")
901         (unsigned_float:DF (match_operand:DI 1 "register_operand"   "r")))
902    (use (match_operand:V16QI 2 "register_operand" "r"))
903    (use (match_operand:V4SI 3 "register_operand" "r"))
904    (clobber (match_scratch:V4SI 4 "=&r"))
905    (clobber (match_scratch:V4SI 5 "=&r"))
906    (clobber (match_scratch:V4SI 6 "=&r"))]
907   ""
908   "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"
909   "reload_completed"
910   [(set (match_operand:DF 0 "register_operand"  "=r")
911         (unsigned_float:DF (match_operand:DI 1 "register_operand"   "r")))]
912   "{
913     rtx *ops = operands;
914     rtx op1_v4si = gen_rtx_REG (V4SImode, REGNO(ops[1]));
915     rtx op2_ti = gen_rtx_REG (TImode, REGNO(ops[2]));
916     rtx op4_ti = gen_rtx_REG (TImode, REGNO(ops[4]));
917     rtx op5_ti = gen_rtx_REG (TImode, REGNO(ops[5]));
918     rtx op4_df = gen_rtx_REG (DFmode, REGNO(ops[4]));
919     rtx op5_df = gen_rtx_REG (DFmode, REGNO(ops[5]));
920     emit_insn (gen_clzv4si2 (ops[4],op1_v4si));
921     emit_insn (gen_vashlv4si3 (ops[5],op1_v4si,ops[4]));
922     emit_insn (gen_ceq_v4si (ops[6],ops[4],spu_const (V4SImode, 32)));
923     emit_insn (gen_subv4si3 (ops[4],ops[3],ops[4]));
924     emit_insn (gen_addv4si3 (ops[5],ops[5],ops[5]));
925     emit_insn (gen_andc_v4si (ops[4],ops[4],ops[6]));
926     emit_insn (gen_shufb (ops[4],ops[4],ops[5],op2_ti));
927     emit_insn (gen_shlqbi_ti (op4_ti,op4_ti,GEN_INT(4)));
928     emit_insn (gen_shlqby_ti (op5_ti,op4_ti,GEN_INT(8)));
929     emit_insn (gen_adddf3 (ops[0],op4_df,op5_df));
930     DONE;
931   }"
932   [(set_attr "length" "40")])
935 ;; add
937 (define_expand "addv16qi3"
938   [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
939         (plus:V16QI (match_operand:V16QI 1 "spu_reg_operand" "r")
940                     (match_operand:V16QI 2 "spu_reg_operand" "r")))]
941   ""
942   "{
943     rtx res_short = simplify_gen_subreg (V8HImode, operands[0], V16QImode, 0);
944     rtx lhs_short = simplify_gen_subreg (V8HImode, operands[1], V16QImode, 0);
945     rtx rhs_short = simplify_gen_subreg (V8HImode, operands[2], V16QImode, 0);
946     rtx rhs_and = gen_reg_rtx (V8HImode);
947     rtx hi_char = gen_reg_rtx (V8HImode);
948     rtx lo_char = gen_reg_rtx (V8HImode);
949     rtx mask = gen_reg_rtx (V8HImode);
951     emit_move_insn (mask, spu_const (V8HImode, 0x00ff));
952     emit_insn (gen_andv8hi3 (rhs_and, rhs_short, spu_const (V8HImode, 0xff00)));
953     emit_insn (gen_addv8hi3 (hi_char, lhs_short, rhs_and));
954     emit_insn (gen_addv8hi3 (lo_char, lhs_short, rhs_short));
955     emit_insn (gen_selb (res_short, hi_char, lo_char, mask));
956     DONE;
957    }")
959 (define_insn "add<mode>3"
960   [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
961         (plus:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
962                    (match_operand:VHSI 2 "spu_arith_operand" "r,B")))]
963   ""
964   "@
965   a<bh>\t%0,%1,%2
966   a<bh>i\t%0,%1,%2")
968 (define_expand "add<mode>3"
969   [(set (match_dup:VDI 3) 
970         (unspec:VDI [(match_operand:VDI 1 "spu_reg_operand" "")
971                      (match_operand:VDI 2 "spu_reg_operand" "")] UNSPEC_CG))
972    (set (match_dup:VDI 5)
973         (unspec:VDI [(match_dup 3)
974                      (match_dup 3)
975                      (match_dup:TI 4)] UNSPEC_SHUFB))
976    (set (match_operand:VDI 0 "spu_reg_operand" "") 
977         (unspec:VDI [(match_dup 1)
978                      (match_dup 2)
979                      (match_dup 5)] UNSPEC_ADDX))]
980   ""
981   {
982     unsigned char pat[16] = {
983       0x04, 0x05, 0x06, 0x07,
984       0x80, 0x80, 0x80, 0x80,
985       0x0c, 0x0d, 0x0e, 0x0f,
986       0x80, 0x80, 0x80, 0x80
987     };
988     operands[3] = gen_reg_rtx (<MODE>mode);
989     operands[4] = gen_reg_rtx (TImode);
990     operands[5] = gen_reg_rtx (<MODE>mode);
991     emit_move_insn (operands[4], array_to_constant (TImode, pat));
992   })
994 (define_insn "cg_<mode>"
995   [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
996         (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
997                       (match_operand 2 "spu_reg_operand" "r")] UNSPEC_CG))]
998   "operands"
999   "cg\t%0,%1,%2")
1001 (define_insn "cgx_<mode>"
1002   [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
1003         (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
1004                       (match_operand 2 "spu_reg_operand" "r")
1005                       (match_operand 3 "spu_reg_operand" "0")] UNSPEC_CGX))]
1006   "operands"
1007   "cgx\t%0,%1,%2")
1009 (define_insn "addx_<mode>"
1010   [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
1011         (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
1012                       (match_operand 2 "spu_reg_operand" "r")
1013                       (match_operand 3 "spu_reg_operand" "0")] UNSPEC_ADDX))]
1014   "operands"
1015   "addx\t%0,%1,%2")
1018 ;; This is not the most efficient implementation of addti3.
1019 ;; We include this here because 1) the compiler needs it to be
1020 ;; defined as the word size is 128-bit and 2) sometimes gcc
1021 ;; substitutes an add for a constant left-shift. 2) is unlikely
1022 ;; because we also give addti3 a high cost. In case gcc does
1023 ;; generate TImode add, here is the code to do it.
1024 ;; operand 2 is a nonmemory because the compiler requires it.
1025 (define_insn "addti3"
1026   [(set (match_operand:TI 0 "spu_reg_operand" "=&r")
1027         (plus:TI (match_operand:TI 1 "spu_reg_operand" "r")
1028                  (match_operand:TI 2 "spu_nonmem_operand" "r")))
1029    (clobber (match_scratch:TI 3 "=&r"))]
1030   ""
1031   "cg\t%3,%1,%2\n\\
1032    shlqbyi\t%3,%3,4\n\\
1033    cgx\t%3,%1,%2\n\\
1034    shlqbyi\t%3,%3,4\n\\
1035    cgx\t%3,%1,%2\n\\
1036    shlqbyi\t%0,%3,4\n\\
1037    addx\t%0,%1,%2"
1038   [(set_attr "type" "multi0")
1039    (set_attr "length" "28")])
1041 (define_insn "add<mode>3"
1042   [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1043         (plus:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
1044                   (match_operand:VSF 2 "spu_reg_operand" "r")))]
1045   ""
1046   "fa\t%0,%1,%2"
1047   [(set_attr "type" "fp6")])
1049 (define_insn "add<mode>3"
1050   [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
1051         (plus:VDF (match_operand:VDF 1 "spu_reg_operand" "r")
1052                   (match_operand:VDF 2 "spu_reg_operand" "r")))]
1053   ""
1054   "dfa\t%0,%1,%2"
1055   [(set_attr "type" "fpd")])
1058 ;; sub
1060 (define_expand "subv16qi3"
1061   [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
1062         (minus:V16QI (match_operand:V16QI 1 "spu_reg_operand" "r")
1063                      (match_operand:V16QI 2 "spu_reg_operand" "r")))]
1064   ""
1065   "{
1066     rtx res_short = simplify_gen_subreg (V8HImode, operands[0], V16QImode, 0);
1067     rtx lhs_short = simplify_gen_subreg (V8HImode, operands[1], V16QImode, 0);
1068     rtx rhs_short = simplify_gen_subreg (V8HImode, operands[2], V16QImode, 0);
1069     rtx rhs_and = gen_reg_rtx (V8HImode);
1070     rtx hi_char = gen_reg_rtx (V8HImode);
1071     rtx lo_char = gen_reg_rtx (V8HImode);
1072     rtx mask = gen_reg_rtx (V8HImode);
1074     emit_move_insn (mask, spu_const (V8HImode, 0x00ff));
1075     emit_insn (gen_andv8hi3 (rhs_and, rhs_short, spu_const (V8HImode, 0xff00)));
1076     emit_insn (gen_subv8hi3 (hi_char, lhs_short, rhs_and));
1077     emit_insn (gen_subv8hi3 (lo_char, lhs_short, rhs_short));
1078     emit_insn (gen_selb (res_short, hi_char, lo_char, mask));
1079     DONE;
1080    }")
1082 (define_insn "sub<mode>3"
1083   [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
1084         (minus:VHSI (match_operand:VHSI 1 "spu_arith_operand" "r,B")
1085                     (match_operand:VHSI 2 "spu_reg_operand" "r,r")))]
1086   ""
1087   "@
1088   sf<bh>\t%0,%2,%1
1089   sf<bh>i\t%0,%2,%1")
1091 (define_expand "sub<mode>3"
1092   [(set (match_dup:VDI 3) 
1093         (unspec:VDI [(match_operand:VDI 1 "spu_reg_operand" "")
1094                      (match_operand:VDI 2 "spu_reg_operand" "")] UNSPEC_BG))
1095    (set (match_dup:VDI 5)
1096         (unspec:VDI [(match_dup 3)
1097                      (match_dup 3)
1098                      (match_dup:TI 4)] UNSPEC_SHUFB))
1099    (set (match_operand:VDI 0 "spu_reg_operand" "") 
1100         (unspec:VDI [(match_dup 1)
1101                      (match_dup 2)
1102                      (match_dup 5)] UNSPEC_SFX))]
1103   ""
1104   {
1105     unsigned char pat[16] = {
1106       0x04, 0x05, 0x06, 0x07,
1107       0xc0, 0xc0, 0xc0, 0xc0,
1108       0x0c, 0x0d, 0x0e, 0x0f,
1109       0xc0, 0xc0, 0xc0, 0xc0
1110     };
1111     operands[3] = gen_reg_rtx (<MODE>mode);
1112     operands[4] = gen_reg_rtx (TImode);
1113     operands[5] = gen_reg_rtx (<MODE>mode);
1114     emit_move_insn (operands[4], array_to_constant (TImode, pat));
1115   })
1117 (define_insn "bg_<mode>"
1118   [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
1119         (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
1120                       (match_operand 2 "spu_reg_operand" "r")] UNSPEC_BG))]
1121   "operands"
1122   "bg\t%0,%2,%1")
1124 (define_insn "bgx_<mode>"
1125   [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
1126         (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
1127                       (match_operand 2 "spu_reg_operand" "r")
1128                       (match_operand 3 "spu_reg_operand" "0")] UNSPEC_BGX))]
1129   "operands"
1130   "bgx\t%0,%2,%1")
1132 (define_insn "sfx_<mode>"
1133   [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
1134         (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
1135                       (match_operand 2 "spu_reg_operand" "r")
1136                       (match_operand 3 "spu_reg_operand" "0")] UNSPEC_SFX))]
1137   "operands"
1138   "sfx\t%0,%2,%1")
1140 (define_insn "subti3"
1141   [(set (match_operand:TI 0 "spu_reg_operand" "=r")
1142         (minus:TI (match_operand:TI 1 "spu_reg_operand" "r")
1143                   (match_operand:TI 2 "spu_reg_operand" "r")))
1144    (clobber (match_scratch:TI 3 "=&r"))
1145    (clobber (match_scratch:TI 4 "=&r"))
1146    (clobber (match_scratch:TI 5 "=&r"))
1147    (clobber (match_scratch:TI 6 "=&r"))]
1148   ""
1149   "il\t%6,1\n\\
1150    bg\t%3,%2,%1\n\\
1151    xor\t%3,%3,%6\n\\
1152    sf\t%4,%2,%1\n\\
1153    shlqbyi\t%5,%3,4\n\\
1154    bg\t%3,%5,%4\n\\
1155    xor\t%3,%3,%6\n\\
1156    sf\t%4,%5,%4\n\\
1157    shlqbyi\t%5,%3,4\n\\
1158    bg\t%3,%5,%4\n\\
1159    xor\t%3,%3,%6\n\\
1160    sf\t%4,%5,%4\n\\
1161    shlqbyi\t%5,%3,4\n\\
1162    sf\t%0,%5,%4"
1163   [(set_attr "type" "multi0")
1164    (set_attr "length" "56")])
1166 (define_insn "sub<mode>3"
1167   [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1168         (minus:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
1169                    (match_operand:VSF 2 "spu_reg_operand" "r")))]
1170   ""
1171   "fs\t%0,%1,%2"
1172   [(set_attr "type" "fp6")])
1174 (define_insn "sub<mode>3"
1175   [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
1176         (minus:VDF (match_operand:VDF 1 "spu_reg_operand" "r")
1177                    (match_operand:VDF 2 "spu_reg_operand" "r")))]
1178   ""
1179   "dfs\t%0,%1,%2"
1180   [(set_attr "type" "fpd")])
1183 ;; neg
1185 (define_expand "negv16qi2"
1186   [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
1187         (neg:V16QI (match_operand:V16QI 1 "spu_reg_operand" "r")))]
1188   ""
1189   "{
1190     rtx zero = gen_reg_rtx (V16QImode);
1191     emit_move_insn (zero, CONST0_RTX (V16QImode));
1192     emit_insn (gen_subv16qi3 (operands[0], zero, operands[1]));
1193     DONE;
1194    }")
1196 (define_insn "neg<mode>2"
1197   [(set (match_operand:VHSI 0 "spu_reg_operand" "=r")
1198         (neg:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r")))]
1199   ""
1200   "sf<bh>i\t%0,%1,0")
1202 (define_expand "negdi2"
1203   [(set (match_operand:DI 0 "spu_reg_operand" "")
1204         (neg:DI (match_operand:DI 1 "spu_reg_operand" "")))]
1205   ""
1206   {
1207     rtx zero = gen_reg_rtx(DImode);
1208     emit_move_insn(zero, GEN_INT(0));
1209     emit_insn (gen_subdi3(operands[0], zero, operands[1]));
1210     DONE;
1211   })
1213 (define_expand "negti2"
1214   [(set (match_operand:TI 0 "spu_reg_operand" "")
1215         (neg:TI (match_operand:TI 1 "spu_reg_operand" "")))]
1216   ""
1217   {
1218     rtx zero = gen_reg_rtx(TImode);
1219     emit_move_insn(zero, GEN_INT(0));
1220     emit_insn (gen_subti3(operands[0], zero, operands[1]));
1221     DONE;
1222   })
1224 (define_expand "neg<mode>2"
1225   [(parallel
1226     [(set (match_operand:VSF 0 "spu_reg_operand" "")
1227           (neg:VSF (match_operand:VSF 1 "spu_reg_operand" "")))
1228      (use (match_dup 2))])]
1229   ""
1230   "operands[2] = gen_reg_rtx (<F2I>mode);
1231    emit_move_insn (operands[2], spu_const (<F2I>mode, -0x80000000ull));")
1233 (define_expand "neg<mode>2"
1234   [(parallel
1235     [(set (match_operand:VDF 0 "spu_reg_operand" "")
1236           (neg:VDF (match_operand:VDF 1 "spu_reg_operand" "")))
1237      (use (match_dup 2))])]
1238   ""
1239   "operands[2] = gen_reg_rtx (<F2I>mode);
1240    emit_move_insn (operands[2], spu_const (<F2I>mode, -0x8000000000000000ull));")
1242 (define_insn_and_split "_neg<mode>2"
1243   [(set (match_operand:VSDF 0 "spu_reg_operand" "=r")
1244         (neg:VSDF (match_operand:VSDF 1 "spu_reg_operand" "r")))
1245    (use (match_operand:<F2I> 2 "spu_reg_operand" "r"))]
1246   ""
1247   "#"
1248   ""
1249   [(set (match_dup:<F2I> 3)
1250         (xor:<F2I> (match_dup:<F2I> 4)
1251                    (match_dup:<F2I> 2)))]
1252   {
1253     operands[3] = spu_gen_subreg (<F2I>mode, operands[0]);
1254     operands[4] = spu_gen_subreg (<F2I>mode, operands[1]);
1255   })
1258 ;; abs
1260 (define_expand "abs<mode>2"
1261   [(parallel
1262     [(set (match_operand:VSF 0 "spu_reg_operand" "")
1263           (abs:VSF (match_operand:VSF 1 "spu_reg_operand" "")))
1264      (use (match_dup 2))])]
1265   ""
1266   "operands[2] = gen_reg_rtx (<F2I>mode);
1267    emit_move_insn (operands[2], spu_const (<F2I>mode, 0x7fffffffull));")
1269 (define_expand "abs<mode>2"
1270   [(parallel
1271     [(set (match_operand:VDF 0 "spu_reg_operand" "")
1272           (abs:VDF (match_operand:VDF 1 "spu_reg_operand" "")))
1273      (use (match_dup 2))])]
1274   ""
1275   "operands[2] = gen_reg_rtx (<F2I>mode);
1276    emit_move_insn (operands[2], spu_const (<F2I>mode, 0x7fffffffffffffffull));")
1278 (define_insn_and_split "_abs<mode>2"
1279   [(set (match_operand:VSDF 0 "spu_reg_operand" "=r")
1280         (abs:VSDF (match_operand:VSDF 1 "spu_reg_operand" "r")))
1281    (use (match_operand:<F2I> 2 "spu_reg_operand" "r"))]
1282   ""
1283   "#"
1284   ""
1285   [(set (match_dup:<F2I> 3)
1286         (and:<F2I> (match_dup:<F2I> 4)
1287                    (match_dup:<F2I> 2)))]
1288   {
1289     operands[3] = spu_gen_subreg (<F2I>mode, operands[0]);
1290     operands[4] = spu_gen_subreg (<F2I>mode, operands[1]);
1291   })
1294 ;; mul
1296 (define_insn "mulhi3"
1297   [(set (match_operand:HI 0 "spu_reg_operand" "=r,r")
1298         (mult:HI (match_operand:HI 1 "spu_reg_operand" "r,r")
1299                  (match_operand:HI 2 "spu_arith_operand" "r,B")))]
1300   ""
1301   "@
1302   mpy\t%0,%1,%2
1303   mpyi\t%0,%1,%2"
1304   [(set_attr "type" "fp7")])
1306 (define_expand "mulv8hi3"
1307   [(set (match_operand:V8HI 0 "spu_reg_operand" "")
1308         (mult:V8HI (match_operand:V8HI 1 "spu_reg_operand" "")
1309                    (match_operand:V8HI 2 "spu_reg_operand" "")))]
1310   ""
1311   "{
1312     rtx result = simplify_gen_subreg (V4SImode, operands[0], V8HImode, 0);
1313     rtx low = gen_reg_rtx (V4SImode);
1314     rtx high = gen_reg_rtx (V4SImode);
1315     rtx shift = gen_reg_rtx (V4SImode);
1316     rtx mask = gen_reg_rtx (V4SImode);
1318     emit_move_insn (mask, spu_const (V4SImode, 0x0000ffff));
1319     emit_insn (gen_spu_mpyhh (high, operands[1], operands[2]));
1320     emit_insn (gen_spu_mpy (low, operands[1], operands[2]));
1321     emit_insn (gen_vashlv4si3 (shift, high, spu_const(V4SImode, 16)));
1322     emit_insn (gen_selb (result, shift, low, mask));
1323     DONE;
1324    }")
1326 (define_expand "mul<mode>3"
1327   [(parallel
1328     [(set (match_operand:VSI 0 "spu_reg_operand" "")
1329           (mult:VSI (match_operand:VSI 1 "spu_reg_operand" "")
1330                     (match_operand:VSI 2 "spu_reg_operand" "")))
1331      (clobber (match_dup:VSI 3))
1332      (clobber (match_dup:VSI 4))
1333      (clobber (match_dup:VSI 5))
1334      (clobber (match_dup:VSI 6))])]
1335   ""
1336   {
1337     operands[3] = gen_reg_rtx(<MODE>mode);
1338     operands[4] = gen_reg_rtx(<MODE>mode);
1339     operands[5] = gen_reg_rtx(<MODE>mode);
1340     operands[6] = gen_reg_rtx(<MODE>mode);
1341   })
1343 (define_insn_and_split "_mulsi3"
1344   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1345         (mult:SI (match_operand:SI 1 "spu_reg_operand" "r")
1346                  (match_operand:SI 2 "spu_arith_operand" "rK")))
1347    (clobber (match_operand:SI 3 "spu_reg_operand" "=&r"))
1348    (clobber (match_operand:SI 4 "spu_reg_operand" "=&r"))
1349    (clobber (match_operand:SI 5 "spu_reg_operand" "=&r"))
1350    (clobber (match_operand:SI 6 "spu_reg_operand" "=&r"))]
1351   ""
1352   "#"
1353   ""
1354   [(set (match_dup:SI 0)
1355         (mult:SI (match_dup:SI 1)
1356                  (match_dup:SI 2)))]
1357   {
1358     HOST_WIDE_INT val = 0;
1359     rtx a = operands[3];
1360     rtx b = operands[4];
1361     rtx c = operands[5];
1362     rtx d = operands[6];
1363     if (GET_CODE(operands[2]) == CONST_INT)
1364       {
1365         val = INTVAL(operands[2]);
1366         emit_move_insn(d, operands[2]);
1367         operands[2] = d;
1368       }
1369     if (val && (val & 0xffff) == 0)
1370       {
1371         emit_insn (gen_mpyh_si(operands[0], operands[2], operands[1]));
1372       }
1373     else if (val > 0 && val < 0x10000)
1374       {
1375         rtx cst = satisfies_constraint_K (GEN_INT (val)) ? GEN_INT(val) : d;
1376         emit_insn (gen_mpyh_si(a, operands[1], operands[2]));
1377         emit_insn (gen_mpyu_si(c, operands[1], cst));
1378         emit_insn (gen_addsi3(operands[0], a, c));
1379       }
1380     else
1381       {
1382         emit_insn (gen_mpyh_si(a, operands[1], operands[2]));
1383         emit_insn (gen_mpyh_si(b, operands[2], operands[1]));
1384         emit_insn (gen_mpyu_si(c, operands[1], operands[2]));
1385         emit_insn (gen_addsi3(d, a, b));
1386         emit_insn (gen_addsi3(operands[0], d, c));
1387       }
1388     DONE;
1389    })
1391 (define_insn_and_split "_mulv4si3"
1392   [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
1393         (mult:V4SI (match_operand:V4SI 1 "spu_reg_operand" "r")
1394                    (match_operand:V4SI 2 "spu_reg_operand" "r")))
1395    (clobber (match_operand:V4SI 3 "spu_reg_operand" "=&r"))
1396    (clobber (match_operand:V4SI 4 "spu_reg_operand" "=&r"))
1397    (clobber (match_operand:V4SI 5 "spu_reg_operand" "=&r"))
1398    (clobber (match_operand:V4SI 6 "spu_reg_operand" "=&r"))]
1399   ""
1400   "#"
1401   ""
1402   [(set (match_dup:V4SI 0)
1403         (mult:V4SI (match_dup:V4SI 1)
1404                    (match_dup:V4SI 2)))]
1405   {
1406     rtx a = operands[3];
1407     rtx b = operands[4];
1408     rtx c = operands[5];
1409     rtx d = operands[6];
1410     rtx op1 = simplify_gen_subreg (V8HImode, operands[1], V4SImode, 0);
1411     rtx op2 = simplify_gen_subreg (V8HImode, operands[2], V4SImode, 0);
1412     emit_insn (gen_spu_mpyh(a, op1, op2));
1413     emit_insn (gen_spu_mpyh(b, op2, op1));
1414     emit_insn (gen_spu_mpyu(c, op1, op2));
1415     emit_insn (gen_addv4si3(d, a, b));
1416     emit_insn (gen_addv4si3(operands[0], d, c));
1417     DONE;
1418    })
1420 (define_insn "mulhisi3"
1421   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1422         (mult:SI (sign_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
1423                  (sign_extend:SI (match_operand:HI 2 "spu_reg_operand" "r"))))]
1424   ""
1425   "mpy\t%0,%1,%2"
1426   [(set_attr "type" "fp7")])
1428 (define_insn "mulhisi3_imm"
1429   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1430         (mult:SI (sign_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
1431                  (match_operand:SI 2 "imm_K_operand" "K")))]
1432   ""
1433   "mpyi\t%0,%1,%2"
1434   [(set_attr "type" "fp7")])
1436 (define_insn "umulhisi3"
1437   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1438         (mult:SI (zero_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
1439                  (zero_extend:SI (match_operand:HI 2 "spu_reg_operand" "r"))))]
1440   ""
1441   "mpyu\t%0,%1,%2"
1442   [(set_attr "type" "fp7")])
1444 (define_insn "umulhisi3_imm"
1445   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1446         (mult:SI (zero_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
1447                  (and:SI (match_operand:SI 2 "imm_K_operand" "K") (const_int 65535))))]
1448   ""
1449   "mpyui\t%0,%1,%2"
1450   [(set_attr "type" "fp7")])
1452 (define_insn "mpyu_si"
1453   [(set (match_operand:SI 0 "spu_reg_operand" "=r,r")
1454         (mult:SI (and:SI (match_operand:SI 1 "spu_reg_operand" "r,r")
1455                          (const_int 65535))
1456                  (and:SI (match_operand:SI 2 "spu_arith_operand" "r,K")
1457                          (const_int 65535))))]
1458   ""
1459   "@
1460    mpyu\t%0,%1,%2
1461    mpyui\t%0,%1,%2"
1462   [(set_attr "type" "fp7")])
1464 ;; This isn't always profitable to use.  Consider r = a * b + c * d.
1465 ;; It's faster to do the multiplies in parallel then add them.  If we
1466 ;; merge a multiply and add it prevents the multiplies from happening in
1467 ;; parallel.
1468 (define_insn "mpya_si"
1469   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1470         (plus:SI (mult:SI (sign_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
1471                           (sign_extend:SI (match_operand:HI 2 "spu_reg_operand" "r")))
1472                  (match_operand:SI 3 "spu_reg_operand" "r")))]
1473   "0"
1474   "mpya\t%0,%1,%2,%3"
1475   [(set_attr "type" "fp7")])
1477 (define_insn "mpyh_si"
1478   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1479         (mult:SI (and:SI (match_operand:SI 1 "spu_reg_operand" "r")
1480                          (const_int -65536))
1481                  (and:SI (match_operand:SI 2 "spu_reg_operand" "r")
1482                          (const_int 65535))))]
1483   ""
1484   "mpyh\t%0,%1,%2"
1485   [(set_attr "type" "fp7")])
1487 (define_insn "mpys_si"
1488   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1489         (ashiftrt:SI
1490             (mult:SI (sign_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
1491                      (sign_extend:SI (match_operand:HI 2 "spu_reg_operand" "r")))
1492             (const_int 16)))]
1493   ""
1494   "mpys\t%0,%1,%2"
1495   [(set_attr "type" "fp7")])
1497 (define_insn "mpyhh_si"
1498   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1499         (mult:SI (ashiftrt:SI (match_operand:SI 1 "spu_reg_operand" "r")
1500                               (const_int 16))
1501                  (ashiftrt:SI (match_operand:SI 2 "spu_reg_operand" "r")
1502                               (const_int 16))))]
1503   ""
1504   "mpyhh\t%0,%1,%2"
1505   [(set_attr "type" "fp7")])
1507 (define_insn "mpyhhu_si"
1508   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1509         (mult:SI (lshiftrt:SI (match_operand:SI 1 "spu_reg_operand" "r")
1510                               (const_int 16))
1511                  (lshiftrt:SI (match_operand:SI 2 "spu_reg_operand" "r")
1512                               (const_int 16))))]
1513   ""
1514   "mpyhhu\t%0,%1,%2"
1515   [(set_attr "type" "fp7")])
1517 (define_insn "mpyhha_si" 
1518   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1519         (plus:SI (mult:SI (ashiftrt:SI (match_operand:SI 1 "spu_reg_operand" "r")
1520                                        (const_int 16))
1521                           (ashiftrt:SI (match_operand:SI 2 "spu_reg_operand" "r")
1522                                        (const_int 16)))
1523                  (match_operand:SI 3 "spu_reg_operand" "0")))]
1524   "0"
1525   "mpyhha\t%0,%1,%2"
1526   [(set_attr "type" "fp7")])
1528 (define_insn "mul<mode>3"
1529   [(set (match_operand:VSDF 0 "spu_reg_operand" "=r")
1530         (mult:VSDF (match_operand:VSDF 1 "spu_reg_operand" "r")
1531                    (match_operand:VSDF 2 "spu_reg_operand" "r")))]
1532   ""
1533   "<d>fm\t%0,%1,%2"
1534   [(set_attr "type" "fp<d6>")])
1536 (define_insn "fma_<mode>"
1537   [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1538         (plus:VSF (mult:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
1539                               (match_operand:VSF 2 "spu_reg_operand" "r"))
1540                    (match_operand:VSF 3 "spu_reg_operand" "r")))]
1541   ""
1542   "fma\t%0,%1,%2,%3"
1543   [(set_attr "type"     "fp6")])
1545 (define_insn "fnms_<mode>"
1546   [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1547         (minus:VSF (match_operand:VSF 3 "spu_reg_operand" "r")
1548                     (mult:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
1549                                (match_operand:VSF 2 "spu_reg_operand" "r"))))]
1550   ""
1551   "fnms\t%0,%1,%2,%3"
1552   [(set_attr "type" "fp6")])
1554 (define_insn "fms_<mode>"
1555   [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1556         (minus:VSF (mult:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
1557                                (match_operand:VSF 2 "spu_reg_operand" "r"))
1558                     (match_operand:VSF 3 "spu_reg_operand" "r")))]
1559   ""
1560   "fms\t%0,%1,%2,%3"
1561   [(set_attr "type" "fp6")])
1563 (define_insn "fma_<mode>"
1564   [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
1565         (plus:VDF (mult:VDF (match_operand:VDF 1 "spu_reg_operand" "r")
1566                             (match_operand:VDF 2 "spu_reg_operand" "r"))
1567                   (match_operand:VDF 3 "spu_reg_operand" "0")))]
1568   ""
1569   "dfma\t%0,%1,%2"
1570   [(set_attr "type"     "fpd")])
1572 (define_insn "fnma_<mode>"
1573   [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
1574         (neg:VDF (plus:VDF (mult:VDF (match_operand:VDF 1 "spu_reg_operand" "r")
1575                                      (match_operand:VDF 2 "spu_reg_operand" "r"))
1576                            (match_operand:VDF 3 "spu_reg_operand" "0"))))]
1577   ""
1578   "dfnma\t%0,%1,%2"
1579   [(set_attr "type"     "fpd")])
1581 (define_insn "fnms_<mode>"
1582   [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
1583         (minus:VDF (match_operand:VDF 3 "spu_reg_operand" "0")
1584                    (mult:VDF (match_operand:VDF 1 "spu_reg_operand" "r")
1585                              (match_operand:VDF 2 "spu_reg_operand" "r"))))]
1586   ""
1587   "dfnms\t%0,%1,%2"
1588   [(set_attr "type" "fpd")])
1590 (define_insn "fms_<mode>"
1591   [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
1592         (minus:VDF (mult:VDF (match_operand:VDF 1 "spu_reg_operand" "r")
1593                              (match_operand:VDF 2 "spu_reg_operand" "r"))
1594                    (match_operand:VDF 3 "spu_reg_operand" "0")))]
1595   ""
1596   "dfms\t%0,%1,%2"
1597   [(set_attr "type" "fpd")])
1600 ;; mul highpart, used for divide by constant optimizations.
1602 (define_expand "smulsi3_highpart"
1603   [(set (match_operand:SI 0 "register_operand" "")
1604         (truncate:SI
1605           (ashiftrt:DI
1606             (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
1607                      (sign_extend:DI (match_operand:SI 2 "register_operand" "")))
1608             (const_int 32))))]
1609   ""
1610   {
1611     rtx t0 = gen_reg_rtx (SImode);
1612     rtx t1 = gen_reg_rtx (SImode);
1613     rtx t2 = gen_reg_rtx (SImode);
1614     rtx t3 = gen_reg_rtx (SImode);
1615     rtx t4 = gen_reg_rtx (SImode);
1616     rtx t5 = gen_reg_rtx (SImode);
1617     rtx t6 = gen_reg_rtx (SImode);
1618     rtx t7 = gen_reg_rtx (SImode);
1619     rtx t8 = gen_reg_rtx (SImode);
1620     rtx t9 = gen_reg_rtx (SImode);
1621     rtx t11 = gen_reg_rtx (SImode);
1622     rtx t12 = gen_reg_rtx (SImode);
1623     rtx t14 = gen_reg_rtx (SImode);
1624     rtx t15 = gen_reg_rtx (HImode);
1625     rtx t16 = gen_reg_rtx (HImode);
1626     rtx t17 = gen_reg_rtx (HImode);
1627     rtx t18 = gen_reg_rtx (HImode);
1628     rtx t19 = gen_reg_rtx (SImode);
1629     rtx t20 = gen_reg_rtx (SImode);
1630     rtx t21 = gen_reg_rtx (SImode);
1631     rtx op1_hi = gen_rtx_SUBREG (HImode, operands[1], 2);
1632     rtx op2_hi = gen_rtx_SUBREG (HImode, operands[2], 2);
1633     rtx t0_hi = gen_rtx_SUBREG (HImode, t0, 2);
1634     rtx t1_hi = gen_rtx_SUBREG (HImode, t1, 2);
1636     rtx insn = emit_insn (gen_lshrsi3 (t0, operands[1], GEN_INT (16)));
1637     emit_insn (gen_lshrsi3 (t1, operands[2], GEN_INT (16)));
1638     emit_insn (gen_umulhisi3 (t2, op1_hi, op2_hi));
1639     emit_insn (gen_mpyh_si (t3, operands[1], operands[2]));
1640     emit_insn (gen_mpyh_si (t4, operands[2], operands[1]));
1641     emit_insn (gen_mpyhh_si (t5, operands[1], operands[2]));
1642     emit_insn (gen_mpys_si (t6, t0_hi, op2_hi));
1643     emit_insn (gen_mpys_si (t7, t1_hi, op1_hi));
1645     /* Gen carry bits (in t9 and t11). */
1646     emit_insn (gen_addsi3 (t8, t2, t3));
1647     emit_insn (gen_cg_si (t9, t2, t3));
1648     emit_insn (gen_cg_si (t11, t8, t4));
1650     /* Gen high 32 bits in operand[0].  Correct for mpys. */
1651     emit_insn (gen_addx_si (t12, t5, t6, t9));
1652     emit_insn (gen_addx_si (t14, t12, t7, t11));
1654     /* mpys treats both operands as signed when we really want it to treat
1655        the first operand as signed and the second operand as unsigned.
1656        The code below corrects for that difference.  */
1657     emit_insn (gen_cgt_hi (t15, op1_hi, GEN_INT (-1)));
1658     emit_insn (gen_cgt_hi (t16, op2_hi, GEN_INT (-1)));
1659     emit_insn (gen_andc_hi (t17, t1_hi, t15));
1660     emit_insn (gen_andc_hi (t18, t0_hi, t16));
1661     emit_insn (gen_extendhisi2 (t19, t17));
1662     emit_insn (gen_extendhisi2 (t20, t18));
1663     emit_insn (gen_addsi3 (t21, t19, t20));
1664     emit_insn (gen_addsi3 (operands[0], t14, t21));
1665     unshare_all_rtl_in_chain (insn);
1666     DONE;
1667   })
1669 (define_expand "umulsi3_highpart"
1670   [(set (match_operand:SI 0 "register_operand" "")
1671         (truncate:SI
1672           (ashiftrt:DI
1673             (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
1674                      (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1675             (const_int 32))))]
1676   ""
1677   
1678   {
1679     rtx t0 = gen_reg_rtx (SImode);
1680     rtx t1 = gen_reg_rtx (SImode);
1681     rtx t2 = gen_reg_rtx (SImode);
1682     rtx t3 = gen_reg_rtx (SImode);
1683     rtx t4 = gen_reg_rtx (SImode);
1684     rtx t5 = gen_reg_rtx (SImode);
1685     rtx t6 = gen_reg_rtx (SImode);
1686     rtx t7 = gen_reg_rtx (SImode);
1687     rtx t8 = gen_reg_rtx (SImode);
1688     rtx t9 = gen_reg_rtx (SImode);
1689     rtx t10 = gen_reg_rtx (SImode);
1690     rtx t12 = gen_reg_rtx (SImode);
1691     rtx t13 = gen_reg_rtx (SImode);
1692     rtx t14 = gen_reg_rtx (SImode);
1693     rtx op1_hi = gen_rtx_SUBREG (HImode, operands[1], 2);
1694     rtx op2_hi = gen_rtx_SUBREG (HImode, operands[2], 2);
1695     rtx t0_hi = gen_rtx_SUBREG (HImode, t0, 2);
1697     rtx insn = emit_insn (gen_rotlsi3 (t0, operands[2], GEN_INT (16)));
1698     emit_insn (gen_umulhisi3 (t1, op1_hi, op2_hi));
1699     emit_insn (gen_umulhisi3 (t2, op1_hi, t0_hi));
1700     emit_insn (gen_mpyhhu_si (t3, operands[1], t0));
1701     emit_insn (gen_mpyhhu_si (t4, operands[1], operands[2]));
1702     emit_insn (gen_ashlsi3 (t5, t2, GEN_INT (16)));
1703     emit_insn (gen_ashlsi3 (t6, t3, GEN_INT (16)));
1704     emit_insn (gen_lshrsi3 (t7, t2, GEN_INT (16)));
1705     emit_insn (gen_lshrsi3 (t8, t3, GEN_INT (16)));
1707     /* Gen carry bits (in t10 and t12). */
1708     emit_insn (gen_addsi3 (t9, t1, t5));
1709     emit_insn (gen_cg_si (t10, t1, t5));
1710     emit_insn (gen_cg_si (t12, t9, t6));
1712     /* Gen high 32 bits in operand[0]. */
1713     emit_insn (gen_addx_si (t13, t4, t7, t10));
1714     emit_insn (gen_addx_si (t14, t13, t8, t12));
1715     emit_insn (gen_movsi (operands[0], t14));
1716     unshare_all_rtl_in_chain (insn);
1718     DONE;
1719   })
1721 ;; div
1723 ;; Not necessarily the best implementation of divide but faster then
1724 ;; the default that gcc provides because this is inlined and it uses
1725 ;; clz.
1726 (define_insn "divmodsi4"
1727       [(set (match_operand:SI 0 "spu_reg_operand" "=&r")
1728             (div:SI (match_operand:SI 1 "spu_reg_operand" "r")
1729                     (match_operand:SI 2 "spu_reg_operand" "r")))
1730        (set (match_operand:SI 3 "spu_reg_operand" "=&r")
1731             (mod:SI (match_dup 1)
1732                     (match_dup 2)))
1733        (clobber (match_scratch:SI 4 "=&r"))
1734        (clobber (match_scratch:SI 5 "=&r"))
1735        (clobber (match_scratch:SI 6 "=&r"))
1736        (clobber (match_scratch:SI 7 "=&r"))
1737        (clobber (match_scratch:SI 8 "=&r"))
1738        (clobber (match_scratch:SI 9 "=&r"))
1739        (clobber (match_scratch:SI 10 "=&r"))
1740        (clobber (match_scratch:SI 11 "=&r"))
1741        (clobber (match_scratch:SI 12 "=&r"))
1742        (clobber (reg:SI 130))]
1743   ""
1744   "heqi %2,0\\n\\
1745         hbrr    3f,1f\\n\\
1746         sfi     %8,%1,0\\n\\
1747         sfi     %9,%2,0\\n\\
1748         cgti    %10,%1,-1\\n\\
1749         cgti    %11,%2,-1\\n\\
1750         selb    %8,%8,%1,%10\\n\\
1751         selb    %9,%9,%2,%11\\n\\
1752         clz     %4,%8\\n\\
1753         clz     %7,%9\\n\\
1754         il      %5,1\\n\\
1755         fsmbi   %0,0\\n\\
1756         sf      %7,%4,%7\\n\\
1757         shlqbyi %3,%8,0\\n\\
1758         xor     %11,%10,%11\\n\\
1759         shl     %5,%5,%7\\n\\
1760         shl     %4,%9,%7\\n\\
1761         lnop    \\n\\
1762 1:      or      %12,%0,%5\\n\\
1763         rotqmbii        %5,%5,-1\\n\\
1764         clgt    %6,%4,%3\\n\\
1765         lnop    \\n\\
1766         sf      %7,%4,%3\\n\\
1767         rotqmbii        %4,%4,-1\\n\\
1768         selb    %0,%12,%0,%6\\n\\
1769         lnop    \\n\\
1770         selb    %3,%7,%3,%6\\n\\
1771 3:      brnz    %5,1b\\n\\
1772 2:      sfi     %8,%3,0\\n\\
1773         sfi     %9,%0,0\\n\\
1774         selb    %3,%8,%3,%10\\n\\
1775         selb    %0,%0,%9,%11"
1776   [(set_attr "type" "multi0")
1777    (set_attr "length" "128")])
1779 (define_insn "udivmodsi4"
1780       [(set (match_operand:SI 0 "spu_reg_operand" "=&r")
1781             (udiv:SI (match_operand:SI 1 "spu_reg_operand" "r")
1782                      (match_operand:SI 2 "spu_reg_operand" "r")))
1783        (set (match_operand:SI 3 "spu_reg_operand" "=&r")
1784             (umod:SI (match_dup 1)
1785                      (match_dup 2)))
1786        (clobber (match_scratch:SI 4 "=&r"))
1787        (clobber (match_scratch:SI 5 "=&r"))
1788        (clobber (match_scratch:SI 6 "=&r"))
1789        (clobber (match_scratch:SI 7 "=&r"))
1790        (clobber (match_scratch:SI 8 "=&r"))
1791        (clobber (reg:SI 130))]
1792   ""
1793   "heqi %2,0\\n\\
1794         hbrr    3f,1f\\n\\
1795         clz     %7,%2\\n\\
1796         clz     %4,%1\\n\\
1797         il      %5,1\\n\\
1798         fsmbi   %0,0\\n\\
1799         sf      %7,%4,%7\\n\\
1800         ori     %3,%1,0\\n\\
1801         shl     %5,%5,%7\\n\\
1802         shl     %4,%2,%7\\n\\
1803 1:      or      %8,%0,%5\\n\\
1804         rotqmbii        %5,%5,-1\\n\\
1805         clgt    %6,%4,%3\\n\\
1806         lnop    \\n\\
1807         sf      %7,%4,%3\\n\\
1808         rotqmbii        %4,%4,-1\\n\\
1809         selb    %0,%8,%0,%6\\n\\
1810         lnop    \\n\\
1811         selb    %3,%7,%3,%6\\n\\
1812 3:      brnz    %5,1b\\n\\
1814   [(set_attr "type" "multi0")
1815    (set_attr "length" "80")])
1817 (define_expand "div<mode>3"
1818   [(parallel
1819     [(set (match_operand:VSF 0 "spu_reg_operand" "")    
1820           (div:VSF (match_operand:VSF 1 "spu_reg_operand" "")
1821                    (match_operand:VSF 2 "spu_reg_operand" "")))
1822      (clobber (match_scratch:VSF 3 ""))
1823      (clobber (match_scratch:VSF 4 ""))
1824      (clobber (match_scratch:VSF 5 ""))])]
1825   ""
1826   "")
1828 (define_insn_and_split "*div<mode>3_fast"
1829   [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1830         (div:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
1831                  (match_operand:VSF 2 "spu_reg_operand" "r")))
1832    (clobber (match_scratch:VSF 3 "=&r"))
1833    (clobber (match_scratch:VSF 4 "=&r"))
1834    (clobber (scratch:VSF))]
1835   "flag_unsafe_math_optimizations"
1836   "#"
1837   "reload_completed"
1838   [(set (match_dup:VSF 0)
1839         (div:VSF (match_dup:VSF 1)
1840                  (match_dup:VSF 2)))
1841    (clobber (match_dup:VSF 3))
1842    (clobber (match_dup:VSF 4))
1843    (clobber (scratch:VSF))]
1844   {
1845     emit_insn (gen_frest_<mode>(operands[3], operands[2]));
1846     emit_insn (gen_fi_<mode>(operands[3], operands[2], operands[3]));
1847     emit_insn (gen_mul<mode>3(operands[4], operands[1], operands[3]));
1848     emit_insn (gen_fnms_<mode>(operands[0], operands[4], operands[2], operands[1]));
1849     emit_insn (gen_fma_<mode>(operands[0], operands[0], operands[3], operands[4]));
1850     DONE;
1851   })
1853 (define_insn_and_split "*div<mode>3_adjusted"
1854   [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1855         (div:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
1856                  (match_operand:VSF 2 "spu_reg_operand" "r")))
1857    (clobber (match_scratch:VSF 3 "=&r"))
1858    (clobber (match_scratch:VSF 4 "=&r"))
1859    (clobber (match_scratch:VSF 5 "=&r"))]
1860   "!flag_unsafe_math_optimizations"
1861   "#"
1862   "reload_completed"
1863   [(set (match_dup:VSF 0)
1864         (div:VSF (match_dup:VSF 1)
1865                  (match_dup:VSF 2)))
1866    (clobber (match_dup:VSF 3))
1867    (clobber (match_dup:VSF 4))
1868    (clobber (match_dup:VSF 5))]
1869   {
1870     emit_insn (gen_frest_<mode> (operands[3], operands[2]));
1871     emit_insn (gen_fi_<mode> (operands[3], operands[2], operands[3]));
1872     emit_insn (gen_mul<mode>3 (operands[4], operands[1], operands[3]));
1873     emit_insn (gen_fnms_<mode> (operands[5], operands[4], operands[2], operands[1]));
1874     emit_insn (gen_fma_<mode> (operands[3], operands[5], operands[3], operands[4]));
1876    /* Due to truncation error, the quotient result may be low by 1 ulp.
1877       Conditionally add one if the estimate is too small in magnitude.  */
1879     emit_move_insn (gen_lowpart (<F2I>mode, operands[4]),
1880                     spu_const (<F2I>mode, 0x80000000ULL));
1881     emit_move_insn (gen_lowpart (<F2I>mode, operands[5]),
1882                     spu_const (<F2I>mode, 0x3f800000ULL));
1883     emit_insn (gen_selb (operands[5], operands[5], operands[1], operands[4]));
1885     emit_insn (gen_add<f2i>3 (gen_lowpart (<F2I>mode, operands[4]),
1886                               gen_lowpart (<F2I>mode, operands[3]),
1887                               spu_const (<F2I>mode, 1)));
1888     emit_insn (gen_fnms_<mode> (operands[0], operands[2], operands[4], operands[1]));
1889     emit_insn (gen_mul<mode>3 (operands[0], operands[0], operands[5]));
1890     emit_insn (gen_cgt_<f2i> (gen_lowpart (<F2I>mode, operands[0]),
1891                               gen_lowpart (<F2I>mode, operands[0]),
1892                               spu_const (<F2I>mode, -1)));
1893     emit_insn (gen_selb (operands[0], operands[3], operands[4], operands[0]));
1894     DONE;
1895   })
1898 ;; sqrt
1900 (define_insn_and_split "sqrtsf2"
1901   [(set (match_operand:SF 0 "spu_reg_operand" "=r")
1902         (sqrt:SF (match_operand:SF 1 "spu_reg_operand" "r")))
1903    (clobber (match_scratch:SF 2 "=&r"))
1904    (clobber (match_scratch:SF 3 "=&r"))
1905    (clobber (match_scratch:SF 4 "=&r"))
1906    (clobber (match_scratch:SF 5 "=&r"))]
1907   ""
1908   "#"
1909   "reload_completed"
1910   [(set (match_dup:SF 0)
1911         (sqrt:SF (match_dup:SF 1)))
1912    (clobber (match_dup:SF 2))
1913    (clobber (match_dup:SF 3))
1914    (clobber (match_dup:SF 4))
1915    (clobber (match_dup:SF 5))]
1916   {
1917     emit_move_insn (operands[3],spu_float_const(\"0.5\",SFmode));
1918     emit_move_insn (operands[4],spu_float_const(\"1.00000011920928955078125\",SFmode));
1919     emit_insn (gen_frsqest_sf(operands[2],operands[1]));
1920     emit_insn (gen_fi_sf(operands[2],operands[1],operands[2]));
1921     emit_insn (gen_mulsf3(operands[5],operands[2],operands[1]));
1922     emit_insn (gen_mulsf3(operands[3],operands[5],operands[3]));
1923     emit_insn (gen_fnms_sf(operands[4],operands[2],operands[5],operands[4]));
1924     emit_insn (gen_fma_sf(operands[0],operands[4],operands[3],operands[5]));
1925     DONE;
1926   })
1928 (define_insn "frest_<mode>"
1929   [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1930         (unspec:VSF [(match_operand:VSF 1 "spu_reg_operand" "r")] UNSPEC_FREST))]
1931   ""
1932   "frest\t%0,%1"
1933   [(set_attr "type" "shuf")])
1935 (define_insn "frsqest_<mode>"
1936   [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1937         (unspec:VSF [(match_operand:VSF 1 "spu_reg_operand" "r")] UNSPEC_FRSQEST))]
1938   ""
1939   "frsqest\t%0,%1"
1940   [(set_attr "type" "shuf")])
1942 (define_insn "fi_<mode>"
1943   [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1944         (unspec:VSF [(match_operand:VSF 1 "spu_reg_operand" "r")
1945                     (match_operand:VSF 2 "spu_reg_operand" "r")] UNSPEC_FI))]
1946   ""
1947   "fi\t%0,%1,%2"
1948   [(set_attr "type" "fp7")])
1951 ;; and
1953 (define_insn "and<mode>3"
1954   [(set (match_operand:MOV 0 "spu_reg_operand" "=r,r")
1955         (and:MOV (match_operand:MOV 1 "spu_reg_operand" "r,r")
1956                  (match_operand:MOV 2 "spu_logical_operand" "r,C")))]
1957   ""
1958   "@
1959   and\t%0,%1,%2
1960   and%j2i\t%0,%1,%J2")
1962 (define_insn "anddi3"
1963   [(set (match_operand:DI 0 "spu_reg_operand" "=r,r")
1964         (and:DI (match_operand:DI 1 "spu_reg_operand" "r,r")
1965                 (match_operand:DI 2 "spu_logical_operand" "r,c")))]
1966   ""
1967   "@
1968   and\t%0,%1,%2
1969   and%k2i\t%0,%1,%K2")
1971 (define_insn "andti3"
1972   [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
1973         (and:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
1974                 (match_operand:TI 2 "spu_logical_operand" "r,Y")))]
1975   ""
1976   "@
1977   and\t%0,%1,%2
1978   and%m2i\t%0,%1,%L2")
1980 (define_insn "andc_<mode>"
1981   [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
1982         (and:ALL (not:ALL (match_operand:ALL 2 "spu_reg_operand" "r"))
1983                  (match_operand:ALL 1 "spu_reg_operand" "r")))]
1984   ""
1985   "andc\t%0,%1,%2")
1987 (define_insn "nand_<mode>"
1988   [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
1989         (not:ALL (and:ALL (match_operand:ALL 2 "spu_reg_operand" "r")
1990                           (match_operand:ALL 1 "spu_reg_operand" "r"))))]
1991   ""
1992   "nand\t%0,%1,%2")
1995 ;; ior
1997 (define_insn "ior<mode>3"
1998   [(set (match_operand:MOV 0 "spu_reg_operand" "=r,r,r")
1999         (ior:MOV (match_operand:MOV 1 "spu_reg_operand" "r,r,0")
2000                  (match_operand:MOV 2 "spu_ior_operand" "r,C,D")))]
2001   ""
2002   "@
2003   or\t%0,%1,%2
2004   or%j2i\t%0,%1,%J2
2005   iohl\t%0,%J2")
2007 (define_insn "iordi3"
2008   [(set (match_operand:DI 0 "spu_reg_operand" "=r,r,r")
2009         (ior:DI (match_operand:DI 1 "spu_reg_operand" "r,r,0")
2010                 (match_operand:DI 2 "spu_ior_operand" "r,c,d")))]
2011   ""
2012   "@
2013   or\t%0,%1,%2
2014   or%k2i\t%0,%1,%K2
2015   iohl\t%0,%K2")
2017 (define_insn "iorti3"
2018   [(set (match_operand:TI 0 "spu_reg_operand" "=r,r,r")
2019         (ior:TI (match_operand:TI 1 "spu_reg_operand" "r,r,0")
2020                 (match_operand:TI 2 "spu_ior_operand" "r,Y,Z")))]
2021   ""
2022   "@
2023   or\t%0,%1,%2
2024   or%m2i\t%0,%1,%L2
2025   iohl\t%0,%L2")
2027 (define_insn "orc_<mode>"
2028   [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
2029         (ior:ALL (not:ALL (match_operand:ALL 2 "spu_reg_operand" "r"))
2030                  (match_operand:ALL 1 "spu_reg_operand" "r")))]
2031   ""
2032   "orc\t%0,%1,%2")
2034 (define_insn "nor_<mode>"
2035   [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
2036         (not:ALL (ior:ALL (match_operand:ALL 1 "spu_reg_operand" "r")
2037                           (match_operand:ALL 2 "spu_reg_operand" "r"))))]
2038   ""
2039   "nor\t%0,%1,%2")
2041 ;; xor
2043 (define_insn "xor<mode>3"
2044   [(set (match_operand:MOV 0 "spu_reg_operand" "=r,r")
2045         (xor:MOV (match_operand:MOV 1 "spu_reg_operand" "r,r")
2046                  (match_operand:MOV 2 "spu_logical_operand" "r,B")))]
2047   ""
2048   "@
2049   xor\t%0,%1,%2
2050   xor%j2i\t%0,%1,%J2")
2052 (define_insn "xordi3"
2053   [(set (match_operand:DI 0 "spu_reg_operand" "=r,r")
2054         (xor:DI (match_operand:DI 1 "spu_reg_operand" "r,r")
2055                 (match_operand:DI 2 "spu_logical_operand" "r,c")))]
2056   ""
2057   "@
2058   xor\t%0,%1,%2
2059   xor%k2i\t%0,%1,%K2")
2061 (define_insn "xorti3"
2062   [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2063         (xor:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2064                 (match_operand:TI 2 "spu_logical_operand" "r,Y")))]
2065   ""
2066   "@
2067   xor\t%0,%1,%2
2068   xor%m2i\t%0,%1,%L2")
2070 (define_insn "eqv_<mode>"
2071   [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
2072         (not:ALL (xor:ALL (match_operand:ALL 1 "spu_reg_operand" "r")
2073                           (match_operand:ALL 2 "spu_reg_operand" "r"))))]
2074   ""
2075   "eqv\t%0,%1,%2")
2077 ;; one_cmpl
2079 (define_insn "one_cmpl<mode>2"
2080   [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
2081         (not:ALL (match_operand:ALL 1 "spu_reg_operand" "r")))]
2082   ""
2083   "nor\t%0,%1,%1")
2086 ;; selb
2088 (define_expand "selb"
2089   [(set (match_operand 0 "spu_reg_operand" "")
2090         (unspec [(match_operand 1 "spu_reg_operand" "")
2091                  (match_operand 2 "spu_reg_operand" "")
2092                  (match_operand 3 "spu_reg_operand" "")] UNSPEC_SELB))]
2093   ""
2094   {
2095     rtx s = gen__selb (operands[0], operands[1], operands[2], operands[3]);
2096     PUT_MODE (SET_SRC (s), GET_MODE (operands[0]));
2097     emit_insn (s);
2098     DONE;
2099   })
2101 ;; This could be defined as a combination of logical operations, but at
2102 ;; one time it caused a crash due to recursive expansion of rtl during CSE.
2103 (define_insn "_selb"
2104   [(set (match_operand 0 "spu_reg_operand" "=r")
2105         (unspec [(match_operand 1 "spu_reg_operand" "r")
2106                  (match_operand 2 "spu_reg_operand" "r")
2107                  (match_operand 3 "spu_reg_operand" "r")] UNSPEC_SELB))]
2108   "GET_MODE(operands[0]) == GET_MODE(operands[1]) 
2109    && GET_MODE(operands[1]) == GET_MODE(operands[2])"
2110   "selb\t%0,%1,%2,%3")
2113 ;; Misc. byte/bit operations
2114 ;; clz/ctz/ffs/popcount/parity
2115 ;; cntb/sumb
2117 (define_insn "clz<mode>2"
2118   [(set (match_operand:VSI 0 "spu_reg_operand" "=r")
2119         (clz:VSI (match_operand:VSI 1 "spu_reg_operand" "r")))]
2120   ""
2121   "clz\t%0,%1")
2123 (define_expand "ctz<mode>2"
2124   [(set (match_dup 2)
2125         (neg:VSI (match_operand:VSI 1 "spu_reg_operand" "")))
2126    (set (match_dup 3) (and:VSI (match_dup 1)
2127                                (match_dup 2)))
2128    (set (match_dup 4) (clz:VSI (match_dup 3)))
2129    (set (match_operand:VSI 0 "spu_reg_operand" "")
2130         (minus:VSI (match_dup 5) (match_dup 4)))]
2131   ""
2132   {
2133      operands[2] = gen_reg_rtx (<MODE>mode);
2134      operands[3] = gen_reg_rtx (<MODE>mode);
2135      operands[4] = gen_reg_rtx (<MODE>mode);
2136      operands[5] = spu_const(<MODE>mode, 31);
2137   })
2139 (define_expand "ffs<mode>2"
2140   [(set (match_dup 2)
2141         (neg:VSI (match_operand:VSI 1 "spu_reg_operand" "")))
2142    (set (match_dup 3) (and:VSI (match_dup 1)
2143                                (match_dup 2)))
2144    (set (match_dup 4) (clz:VSI (match_dup 3)))
2145    (set (match_operand:VSI 0 "spu_reg_operand" "")
2146         (minus:VSI (match_dup 5) (match_dup 4)))]
2147   ""
2148   {
2149      operands[2] = gen_reg_rtx (<MODE>mode);
2150      operands[3] = gen_reg_rtx (<MODE>mode);
2151      operands[4] = gen_reg_rtx (<MODE>mode);
2152      operands[5] = spu_const(<MODE>mode, 32);
2153   })
2155 (define_expand "popcountsi2"
2156   [(set (match_dup 2)
2157         (unspec:SI [(match_operand:SI 1 "spu_reg_operand" "")]
2158                      UNSPEC_CNTB))
2159    (set (match_dup 3)
2160         (unspec:HI [(match_dup 2)] UNSPEC_SUMB))
2161    (set (match_operand:SI 0 "spu_reg_operand" "")
2162         (sign_extend:SI (match_dup 3)))]
2163   ""
2164   {
2165     operands[2] = gen_reg_rtx (SImode);
2166     operands[3] = gen_reg_rtx (HImode);
2167   })
2169 (define_expand "paritysi2"
2170   [(set (match_operand:SI 0 "spu_reg_operand" "")
2171         (parity:SI (match_operand:SI 1 "spu_reg_operand" "")))]
2172   ""
2173   {
2174     operands[2] = gen_reg_rtx (SImode);
2175     emit_insn (gen_popcountsi2(operands[2], operands[1]));
2176     emit_insn (gen_andsi3(operands[0], operands[2], GEN_INT (1)));
2177     DONE;
2178   })
2180 (define_insn "cntb_si"
2181   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2182         (unspec:SI [(match_operand:SI 1 "spu_reg_operand" "r")]
2183                    UNSPEC_CNTB))]
2184   ""
2185   "cntb\t%0,%1"
2186   [(set_attr "type" "fxb")])
2188 (define_insn "cntb_v16qi"
2189   [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
2190         (unspec:V16QI [(match_operand:V16QI 1 "spu_reg_operand" "r")]
2191                       UNSPEC_CNTB))]
2192   ""
2193   "cntb\t%0,%1"
2194   [(set_attr "type" "fxb")])
2196 (define_insn "sumb_si"
2197   [(set (match_operand:HI 0 "spu_reg_operand" "=r")
2198         (unspec:HI [(match_operand:SI 1 "spu_reg_operand" "r")] UNSPEC_SUMB))]
2199   ""
2200   "sumb\t%0,%1,%1"
2201   [(set_attr "type" "fxb")])
2204 ;; ashl, vashl
2206 (define_insn "<v>ashl<mode>3"
2207   [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
2208         (ashift:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
2209                      (match_operand:VHSI 2 "spu_nonmem_operand" "r,W")))]
2210   ""
2211   "@
2212   shl<bh>\t%0,%1,%2
2213   shl<bh>i\t%0,%1,%<umask>2"
2214   [(set_attr "type" "fx3")])
2216 (define_insn_and_split "ashldi3"
2217   [(set (match_operand:DI 0 "spu_reg_operand" "=r,r")
2218         (ashift:DI (match_operand:DI 1 "spu_reg_operand" "r,r")
2219                    (match_operand:SI 2 "spu_nonmem_operand" "r,I")))
2220    (clobber (match_scratch:SI 3 "=&r,X"))]
2221   ""
2222   "#"
2223   "reload_completed"
2224   [(set (match_dup:DI 0)
2225         (ashift:DI (match_dup:DI 1)
2226                    (match_dup:SI 2)))]
2227   {
2228     rtx op0 = gen_rtx_REG (TImode, REGNO (operands[0]));
2229     rtx op1 = gen_rtx_REG (TImode, REGNO (operands[1]));
2230     rtx op2 = operands[2];
2231     rtx op3 = operands[3];
2233     if (GET_CODE (operands[2]) == REG)
2234       {
2235         emit_insn (gen_addsi3 (op3, op2, GEN_INT (64)));
2236         emit_insn (gen_rotlti3 (op0, op1, GEN_INT (64)));
2237         emit_insn (gen_shlqbybi_ti (op0, op0, op3));
2238         emit_insn (gen_shlqbi_ti (op0, op0, op3));
2239       }
2240     else
2241       {
2242         HOST_WIDE_INT val = INTVAL (operands[2]);
2243         emit_insn (gen_rotlti3 (op0, op1, GEN_INT (64)));
2244         emit_insn (gen_shlqby_ti (op0, op0, GEN_INT (val / 8 + 8)));
2245         if (val % 8)
2246           emit_insn (gen_shlqbi_ti (op0, op0, GEN_INT (val % 8)));
2247       }
2248     DONE;
2249   })
2251 (define_expand "ashlti3"
2252   [(parallel [(set (match_operand:TI 0 "spu_reg_operand" "")
2253                    (ashift:TI (match_operand:TI 1 "spu_reg_operand" "")
2254                               (match_operand:SI 2 "spu_nonmem_operand" "")))
2255               (clobber (match_dup:TI 3))])]
2256   ""
2257   "if (GET_CODE (operands[2]) == CONST_INT)
2258     {
2259       emit_insn (gen_ashlti3_imm(operands[0], operands[1], operands[2]));
2260       DONE;
2261     }
2262    operands[3] = gen_reg_rtx (TImode);")
2264 (define_insn_and_split "ashlti3_imm"
2265   [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2266         (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2267                    (match_operand:SI 2 "immediate_operand" "O,P")))]
2268   ""
2269   "@
2270    shlqbyi\t%0,%1,%h2
2271    shlqbii\t%0,%1,%e2"
2272   "!satisfies_constraint_O (operands[2]) && !satisfies_constraint_P (operands[2])"
2273   [(set (match_dup:TI 0)
2274         (ashift:TI (match_dup:TI 1)
2275                    (match_dup:SI 3)))
2276    (set (match_dup:TI 0)
2277         (ashift:TI (match_dup:TI 0)
2278                    (match_dup:SI 4)))]
2279   {
2280     HOST_WIDE_INT val = INTVAL(operands[2]);
2281     operands[3] = GEN_INT (val&7);
2282     operands[4] = GEN_INT (val&-8);
2283   }
2284   [(set_attr "type" "shuf,shuf")])
2286 (define_insn_and_split "ashlti3_reg"
2287   [(set (match_operand:TI 0 "spu_reg_operand" "=r")
2288         (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r")
2289                    (match_operand:SI 2 "spu_reg_operand" "r")))
2290    (clobber (match_operand:TI 3 "spu_reg_operand" "=&r"))]
2291   ""
2292   "#"
2293   ""
2294   [(set (match_dup:TI 3)
2295         (ashift:TI (match_dup:TI 1)
2296                    (and:SI (match_dup:SI 2)
2297                            (const_int 7))))
2298    (set (match_dup:TI 0)
2299         (ashift:TI (match_dup:TI 3)
2300                    (and:SI (match_dup:SI 2)
2301                            (const_int -8))))]
2302   "")
2304 (define_insn "shlqbybi_ti"
2305   [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2306         (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2307                    (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2308                            (const_int -8))))]
2309   ""
2310   "@
2311    shlqbybi\t%0,%1,%2
2312    shlqbyi\t%0,%1,%h2"
2313   [(set_attr "type" "shuf,shuf")])
2315 (define_insn "shlqbi_ti"
2316   [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2317         (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2318                    (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2319                            (const_int 7))))]
2320   ""
2321   "@
2322    shlqbi\t%0,%1,%2
2323    shlqbii\t%0,%1,%e2"
2324   [(set_attr "type" "shuf,shuf")])
2326 (define_insn "shlqby_ti"
2327   [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2328         (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2329                    (mult:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2330                             (const_int 8))))]
2331   ""
2332   "@
2333    shlqby\t%0,%1,%2
2334    shlqbyi\t%0,%1,%f2"
2335   [(set_attr "type" "shuf,shuf")])
2338 ;; lshr, vlshr
2340 (define_insn_and_split "<v>lshr<mode>3"
2341   [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
2342         (lshiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
2343                        (match_operand:VHSI 2 "spu_nonmem_operand" "r,W")))
2344    (clobber (match_scratch:VHSI 3 "=&r,X"))]
2345   ""
2346   "@
2347    #
2348    rot<bh>mi\t%0,%1,-%<umask>2"
2349   "reload_completed && GET_CODE (operands[2]) == REG"
2350   [(set (match_dup:VHSI 3)
2351         (neg:VHSI (match_dup:VHSI 2)))
2352    (set (match_dup:VHSI 0)
2353         (lshiftrt:VHSI (match_dup:VHSI 1)
2354                        (neg:VHSI (match_dup:VHSI 3))))]
2355   ""
2356   [(set_attr "type" "*,fx3")])
2357   
2358 (define_insn "<v>lshr<mode>3_imm"
2359   [(set (match_operand:VHSI 0 "spu_reg_operand" "=r")
2360         (lshiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r")
2361                        (match_operand:VHSI 2 "immediate_operand" "W")))]
2362   ""
2363   "rot<bh>mi\t%0,%1,-%<umask>2"
2364   [(set_attr "type" "fx3")])
2366 (define_insn "rotm_<mode>"
2367   [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
2368         (lshiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
2369                        (neg:VHSI (match_operand:VHSI 2 "spu_nonmem_operand" "r,W"))))]
2370   ""
2371   "@
2372    rot<bh>m\t%0,%1,%2
2373    rot<bh>mi\t%0,%1,-%<nmask>2"
2374   [(set_attr "type" "fx3")])
2376 (define_insn_and_split "lshr<mode>3"
2377   [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r,r")
2378         (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r,r")
2379                       (match_operand:SI 2 "spu_nonmem_operand" "r,O,P")))]
2380   ""
2381   "@
2382    #
2383    rotqmbyi\t%0,%1,-%h2
2384    rotqmbii\t%0,%1,-%e2"
2385   "REG_P (operands[2]) || (!satisfies_constraint_O (operands[2]) && !satisfies_constraint_P (operands[2]))"
2386   [(set (match_dup:DTI 3)
2387         (lshiftrt:DTI (match_dup:DTI 1)
2388                       (match_dup:SI 4)))
2389    (set (match_dup:DTI 0)
2390         (lshiftrt:DTI (match_dup:DTI 3)
2391                       (match_dup:SI 5)))]
2392   {
2393     operands[3] = gen_reg_rtx (<MODE>mode);
2394     if (GET_CODE (operands[2]) == CONST_INT)
2395       {
2396         HOST_WIDE_INT val = INTVAL(operands[2]);
2397         operands[4] = GEN_INT (val & 7);
2398         operands[5] = GEN_INT (val & -8);
2399       }
2400     else
2401       {
2402         rtx t0 = gen_reg_rtx (SImode);
2403         rtx t1 = gen_reg_rtx (SImode);
2404         emit_insn (gen_subsi3(t0, GEN_INT(0), operands[2]));
2405         emit_insn (gen_subsi3(t1, GEN_INT(7), operands[2]));
2406         operands[4] = gen_rtx_AND (SImode, gen_rtx_NEG (SImode, t0), GEN_INT (7));
2407         operands[5] = gen_rtx_AND (SImode, gen_rtx_NEG (SImode, gen_rtx_AND (SImode, t1, GEN_INT (-8))), GEN_INT (-8));
2408       }
2409   }
2410   [(set_attr "type" "*,shuf,shuf")])
2412 (define_expand "shrqbybi_<mode>"
2413   [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
2414         (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
2415                       (and:SI (neg:SI (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2416                                               (const_int -8)))
2417                               (const_int -8))))]
2418   ""
2419   {
2420     if (GET_CODE (operands[2]) == CONST_INT)
2421       operands[2] = GEN_INT (7 - INTVAL (operands[2]));
2422     else
2423       {
2424         rtx t0 = gen_reg_rtx (SImode);
2425         emit_insn (gen_subsi3 (t0, GEN_INT (7), operands[2]));
2426         operands[2] = t0;
2427       }
2428   })
2430 (define_insn "rotqmbybi_<mode>"
2431   [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
2432         (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
2433                       (and:SI (neg:SI (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2434                                               (const_int -8)))
2435                               (const_int -8))))]
2436   ""
2437   "@
2438    rotqmbybi\t%0,%1,%2
2439    rotqmbyi\t%0,%1,-%H2"
2440   [(set_attr "type" "shuf")])
2442 (define_insn_and_split "shrqbi_<mode>"
2443   [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
2444         (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
2445                       (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2446                               (const_int 7))))
2447    (clobber (match_scratch:SI 3 "=&r,X"))]
2448   ""
2449   "#"
2450   "reload_completed"
2451   [(set (match_dup:DTI 0)
2452         (lshiftrt:DTI (match_dup:DTI 1)
2453                       (and:SI (neg:SI (match_dup:SI 3)) (const_int 7))))]
2454   {
2455     if (GET_CODE (operands[2]) == CONST_INT)
2456       operands[3] = GEN_INT (-INTVAL (operands[2]));
2457     else
2458       emit_insn (gen_subsi3 (operands[3], GEN_INT (0), operands[2]));
2459   }
2460   [(set_attr "type" "shuf")])
2462 (define_insn "rotqmbi_<mode>"
2463   [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
2464         (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
2465                       (and:SI (neg:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I"))
2466                               (const_int 7))))]
2467   ""
2468   "@
2469    rotqmbi\t%0,%1,%2
2470    rotqmbii\t%0,%1,-%E2"
2471   [(set_attr "type" "shuf")])
2473 (define_expand "shrqby_<mode>"
2474   [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
2475         (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
2476                       (mult:SI (neg:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I"))
2477                                (const_int 8))))]
2478   ""
2479   {
2480     if (GET_CODE (operands[2]) == CONST_INT)
2481       operands[2] = GEN_INT (-INTVAL (operands[2]));
2482     else
2483       {
2484         rtx t0 = gen_reg_rtx (SImode);
2485         emit_insn (gen_subsi3 (t0, GEN_INT (0), operands[2]));
2486         operands[2] = t0;
2487       }
2488   })
2490 (define_insn "rotqmby_<mode>"
2491   [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
2492         (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
2493                       (mult:SI (neg:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I"))
2494                                (const_int 8))))]
2495   ""
2496   "@
2497    rotqmby\t%0,%1,%2
2498    rotqmbyi\t%0,%1,-%F2"
2499   [(set_attr "type" "shuf")])
2502 ;; ashr, vashr
2504 (define_insn_and_split "<v>ashr<mode>3"
2505   [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
2506         (ashiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
2507                        (match_operand:VHSI 2 "spu_nonmem_operand" "r,W")))
2508    (clobber (match_scratch:VHSI 3 "=&r,X"))]
2509   ""
2510   "@
2511    #
2512    rotma<bh>i\t%0,%1,-%<umask>2"
2513   "reload_completed && GET_CODE (operands[2]) == REG"
2514   [(set (match_dup:VHSI 3)
2515         (neg:VHSI (match_dup:VHSI 2)))
2516    (set (match_dup:VHSI 0)
2517         (ashiftrt:VHSI (match_dup:VHSI 1)
2518                        (neg:VHSI (match_dup:VHSI 3))))]
2519   ""
2520   [(set_attr "type" "*,fx3")])
2521   
2522 (define_insn "<v>ashr<mode>3_imm"
2523   [(set (match_operand:VHSI 0 "spu_reg_operand" "=r")
2524         (ashiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r")
2525                        (match_operand:VHSI 2 "immediate_operand" "W")))]
2526   ""
2527   "rotma<bh>i\t%0,%1,-%<umask>2"
2528   [(set_attr "type" "fx3")])
2529   
2531 (define_insn "rotma_<mode>"
2532   [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
2533         (ashiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
2534                        (neg:VHSI (match_operand:VHSI 2 "spu_nonmem_operand" "r,W"))))]
2535   ""
2536   "@
2537    rotma<bh>\t%0,%1,%2
2538    rotma<bh>i\t%0,%1,-%<nmask>2"
2539   [(set_attr "type" "fx3")])
2541 (define_insn_and_split "ashrdi3"
2542   [(set (match_operand:DI 0 "spu_reg_operand" "=r,r")
2543         (ashiftrt:DI (match_operand:DI 1 "spu_reg_operand" "r,r")
2544                      (match_operand:SI 2 "spu_nonmem_operand" "r,I")))
2545    (clobber (match_scratch:TI 3 "=&r,&r"))
2546    (clobber (match_scratch:TI 4 "=&r,&r"))
2547    (clobber (match_scratch:SI 5 "=&r,&r"))]
2548   ""
2549   "#"
2550   "reload_completed"
2551   [(set (match_dup:DI 0)
2552         (ashiftrt:DI (match_dup:DI 1)
2553                      (match_dup:SI 2)))]
2554   {
2555     rtx op0 = gen_rtx_REG (TImode, REGNO (operands[0]));
2556     rtx op0v = gen_rtx_REG (V4SImode, REGNO (op0));
2557     rtx op1 = gen_rtx_REG (TImode, REGNO (operands[1]));
2558     rtx op1s = gen_rtx_REG (SImode, REGNO (op1));
2559     rtx op2 = operands[2];
2560     rtx op3 = operands[3];
2561     rtx op4 = operands[4];
2562     rtx op5 = operands[5];
2564     if (GET_CODE (op2) == CONST_INT && INTVAL (op2) >= 63)
2565       {
2566         rtx op0s = gen_rtx_REG (SImode, REGNO (op0));
2567         emit_insn (gen_ashrsi3 (op0s, op1s, GEN_INT (32)));
2568         emit_insn (gen_spu_fsm (op0v, op0s));
2569       }
2570     else if (GET_CODE (op2) == CONST_INT && INTVAL (op2) >= 32)
2571       {
2572         rtx op0d = gen_rtx_REG (V2DImode, REGNO (op0));
2573         HOST_WIDE_INT val = INTVAL (op2);
2574         emit_insn (gen_lshrti3 (op0, op1, GEN_INT (32)));
2575         emit_insn (gen_spu_xswd (op0d, op0v));
2576         if (val > 32)
2577           emit_insn (gen_vashrv4si3 (op0v, op0v, spu_const (V4SImode, val - 32)));
2578       }
2579     else
2580       {
2581         rtx op3v = gen_rtx_REG (V4SImode, REGNO (op3));
2582         unsigned char arr[16] = {
2583           0xff, 0xff, 0xff, 0xff,
2584           0xff, 0xff, 0xff, 0xff,
2585           0x00, 0x00, 0x00, 0x00,
2586           0x00, 0x00, 0x00, 0x00
2587         };
2589         emit_insn (gen_ashrsi3 (op5, op1s, GEN_INT (31)));
2590         emit_move_insn (op4, array_to_constant (TImode, arr));
2591         emit_insn (gen_spu_fsm (op3v, op5));
2593         if (GET_CODE (operands[2]) == REG)
2594           {
2595             emit_insn (gen_selb (op4, op3, op1, op4));
2596             emit_insn (gen_negsi2 (op5, op2));
2597             emit_insn (gen_rotqbybi_ti (op0, op4, op5));
2598             emit_insn (gen_rotqbi_ti (op0, op0, op5));
2599           }
2600         else
2601           {
2602             HOST_WIDE_INT val = -INTVAL (op2);
2603             emit_insn (gen_selb (op0, op3, op1, op4));
2604             if ((val - 7) / 8)
2605               emit_insn (gen_rotqby_ti (op0, op0, GEN_INT ((val - 7) / 8)));
2606             if (val % 8)
2607               emit_insn (gen_rotqbi_ti (op0, op0, GEN_INT (val % 8)));
2608           }
2609       }
2610     DONE;
2611   })
2614 (define_insn_and_split "ashrti3"
2615   [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2616         (ashiftrt:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2617                      (match_operand:SI 2 "spu_nonmem_operand" "r,i")))]
2618   ""
2619   "#"
2620   ""
2621   [(set (match_dup:TI 0)
2622         (ashiftrt:TI (match_dup:TI 1)
2623                      (match_dup:SI 2)))]
2624   {
2625     rtx sign_shift = gen_reg_rtx (SImode);
2626     rtx sign_mask = gen_reg_rtx (TImode);
2627     rtx sign_mask_v4si = gen_rtx_SUBREG (V4SImode, sign_mask, 0);
2628     rtx op1_v4si = spu_gen_subreg (V4SImode, operands[1]);
2629     rtx t = gen_reg_rtx (TImode);
2630     emit_insn (gen_subsi3 (sign_shift, GEN_INT (128), force_reg (SImode, operands[2])));
2631     emit_insn (gen_vashrv4si3 (sign_mask_v4si, op1_v4si, spu_const (V4SImode, 31)));
2632     emit_insn (gen_fsm_ti (sign_mask, sign_mask));
2633     emit_insn (gen_ashlti3 (sign_mask, sign_mask, sign_shift));
2634     emit_insn (gen_lshrti3 (t, operands[1], operands[2]));
2635     emit_insn (gen_iorti3 (operands[0], t, sign_mask));
2636     DONE;
2637   })
2639 ;; fsm is used after rotam to replicate the sign across the whole register.
2640 (define_insn "fsm_ti"
2641   [(set (match_operand:TI 0 "spu_reg_operand" "=r")
2642         (unspec:TI [(match_operand:TI 1 "spu_reg_operand" "r")] UNSPEC_FSM))]
2643   ""
2644   "fsm\t%0,%1"
2645   [(set_attr "type" "shuf")])
2648 ;; vrotl, rotl
2650 (define_insn "<v>rotl<mode>3"
2651   [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
2652         (rotate:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
2653                      (match_operand:VHSI 2 "spu_nonmem_operand" "r,W")))]
2654   ""
2655   "@
2656   rot<bh>\t%0,%1,%2
2657   rot<bh>i\t%0,%1,%<umask>2"
2658   [(set_attr "type" "fx3")])
2660 (define_insn "rotlti3"
2661   [(set (match_operand:TI 0 "spu_reg_operand" "=&r,r,r,r")
2662         (rotate:TI (match_operand:TI 1 "spu_reg_operand" "r,r,r,r")
2663                    (match_operand:SI 2 "spu_nonmem_operand" "r,O,P,I")))]
2664   ""
2665   "@
2666   rotqbybi\t%0,%1,%2\;rotqbi\t%0,%0,%2
2667   rotqbyi\t%0,%1,%h2
2668   rotqbii\t%0,%1,%e2
2669   rotqbyi\t%0,%1,%h2\;rotqbii\t%0,%0,%e2"
2670   [(set_attr "length" "8,4,4,8")
2671    (set_attr "type" "multi1,shuf,shuf,multi1")])
2673 (define_insn "rotqbybi_ti"
2674   [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2675         (rotate:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2676                    (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2677                            (const_int -8))))]
2678   ""
2679   "@
2680   rotqbybi\t%0,%1,%2
2681   rotqbyi\t%0,%1,%h2"
2682   [(set_attr "type" "shuf,shuf")])
2684 (define_insn "rotqby_ti"
2685   [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2686         (rotate:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2687                    (mult:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2688                             (const_int 8))))]
2689   ""
2690   "@
2691   rotqby\t%0,%1,%2
2692   rotqbyi\t%0,%1,%f2"
2693   [(set_attr "type" "shuf,shuf")])
2695 (define_insn "rotqbi_ti"
2696   [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2697         (rotate:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2698                    (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2699                            (const_int 7))))]
2700   ""
2701   "@
2702   rotqbi\t%0,%1,%2
2703   rotqbii\t%0,%1,%e2"
2704   [(set_attr "type" "shuf,shuf")])
2707 ;; struct extract/insert
2708 ;; We handle mem's because GCC will generate invalid SUBREG's
2709 ;; and inefficient code.
2711 (define_expand "extv"
2712   [(set (match_operand:TI 0 "register_operand" "")
2713         (sign_extract:TI (match_operand 1 "nonimmediate_operand" "")
2714                          (match_operand:SI 2 "const_int_operand" "")
2715                          (match_operand:SI 3 "const_int_operand" "")))]
2716   ""
2717   {
2718     spu_expand_extv (operands, 0);
2719     DONE;
2720   })
2722 (define_expand "extzv"
2723   [(set (match_operand:TI 0 "register_operand" "")
2724         (zero_extract:TI (match_operand 1 "nonimmediate_operand" "")
2725                          (match_operand:SI 2 "const_int_operand" "")
2726                          (match_operand:SI 3 "const_int_operand" "")))]
2727   ""
2728   {
2729     spu_expand_extv (operands, 1);
2730     DONE;
2731   })
2733 (define_expand "insv"
2734   [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
2735                       (match_operand:SI 1 "const_int_operand" "")
2736                       (match_operand:SI 2 "const_int_operand" ""))
2737         (match_operand 3 "nonmemory_operand" ""))]
2738   ""
2739   { spu_expand_insv(operands); DONE; })
2741 ;; Simplify a number of patterns that get generated by extv, extzv,
2742 ;; insv, and loads.
2743 (define_insn_and_split "trunc_shr_ti<mode>"
2744   [(set (match_operand:QHSI 0 "spu_reg_operand" "=r")
2745         (truncate:QHSI (match_operator:TI 2 "shiftrt_operator" [(match_operand:TI 1 "spu_reg_operand" "0")
2746                                                                 (const_int 96)])))]
2747   ""
2748   "#"
2749   "reload_completed"
2750   [(const_int 0)]
2751   {
2752     spu_split_convert (operands);
2753     DONE;
2754   }
2755   [(set_attr "type" "convert")
2756    (set_attr "length" "0")])
2758 (define_insn_and_split "trunc_shr_tidi"
2759   [(set (match_operand:DI 0 "spu_reg_operand" "=r")
2760         (truncate:DI (match_operator:TI 2 "shiftrt_operator" [(match_operand:TI 1 "spu_reg_operand" "0")
2761                                                               (const_int 64)])))]
2762   ""
2763   "#"
2764   "reload_completed"
2765   [(const_int 0)]
2766   {
2767     spu_split_convert (operands);
2768     DONE;
2769   }
2770   [(set_attr "type" "convert")
2771    (set_attr "length" "0")])
2773 (define_insn_and_split "shl_ext_<mode>ti"
2774   [(set (match_operand:TI 0 "spu_reg_operand" "=r")
2775         (ashift:TI (match_operator:TI 2 "extend_operator" [(match_operand:QHSI 1 "spu_reg_operand" "0")])
2776                    (const_int 96)))]
2777   ""
2778   "#"
2779   "reload_completed"
2780   [(const_int 0)]
2781   {
2782     spu_split_convert (operands);
2783     DONE;
2784   }
2785   [(set_attr "type" "convert")
2786    (set_attr "length" "0")])
2788 (define_insn_and_split "shl_ext_diti"
2789   [(set (match_operand:TI 0 "spu_reg_operand" "=r")
2790         (ashift:TI (match_operator:TI 2 "extend_operator" [(match_operand:DI 1 "spu_reg_operand" "0")])
2791                    (const_int 64)))]
2792   ""
2793   "#"
2794   "reload_completed"
2795   [(const_int 0)]
2796   {
2797     spu_split_convert (operands);
2798     DONE;
2799   }
2800   [(set_attr "type" "convert")
2801    (set_attr "length" "0")])
2803 (define_insn "sext_trunc_lshr_tiqisi"
2804   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2805         (sign_extend:SI (truncate:QI (match_operator:TI 2 "shiftrt_operator" [(match_operand:TI 1 "spu_reg_operand" "r")
2806                                                                               (const_int 120)]))))]
2807   ""
2808   "rotmai\t%0,%1,-24"
2809   [(set_attr "type" "fx3")])
2811 (define_insn "zext_trunc_lshr_tiqisi"
2812   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2813         (zero_extend:SI (truncate:QI (match_operator:TI 2 "shiftrt_operator" [(match_operand:TI 1 "spu_reg_operand" "r")
2814                                                                               (const_int 120)]))))]
2815   ""
2816   "rotmi\t%0,%1,-24"
2817   [(set_attr "type" "fx3")])
2819 (define_insn "sext_trunc_lshr_tihisi"
2820   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2821         (sign_extend:SI (truncate:HI (match_operator:TI 2 "shiftrt_operator" [(match_operand:TI 1 "spu_reg_operand" "r")
2822                                                                               (const_int 112)]))))]
2823   ""
2824   "rotmai\t%0,%1,-16"
2825   [(set_attr "type" "fx3")])
2827 (define_insn "zext_trunc_lshr_tihisi"
2828   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2829         (zero_extend:SI (truncate:HI (match_operator:TI 2 "shiftrt_operator" [(match_operand:TI 1 "spu_reg_operand" "r")
2830                                                                               (const_int 112)]))))]
2831   ""
2832   "rotmi\t%0,%1,-16"
2833   [(set_attr "type" "fx3")])
2836 ;; String/block move insn.
2837 ;; Argument 0 is the destination
2838 ;; Argument 1 is the source
2839 ;; Argument 2 is the length
2840 ;; Argument 3 is the alignment
2842 (define_expand "movstrsi"
2843   [(parallel [(set (match_operand:BLK 0 "" "")
2844                    (match_operand:BLK 1 "" ""))
2845               (use (match_operand:SI 2 "" ""))
2846               (use (match_operand:SI 3 "" ""))])]
2847   ""
2848   "
2849   {
2850     if (spu_expand_block_move (operands))
2851       DONE;
2852     else
2853       FAIL;
2854   }")
2857 ;; jump
2859 (define_insn "indirect_jump"
2860   [(set (pc) (match_operand:SI 0 "spu_reg_operand" "r"))]
2861   ""
2862   "bi\t%0"
2863   [(set_attr "type" "br")])
2865 (define_insn "jump"
2866   [(set (pc)
2867         (label_ref (match_operand 0 "" "")))]
2868   ""
2869   "br\t%0"
2870   [(set_attr "type" "br")])
2873 ;; return
2875 ;; This will be used for leaf functions, that don't save any regs and
2876 ;; don't have locals on stack, maybe... that is for functions that
2877 ;; don't change $sp and don't need to save $lr. 
2878 (define_expand "return"
2879     [(return)]
2880   "direct_return()"
2881   "")
2883 ;; used in spu_expand_epilogue to generate return from a function and
2884 ;; explicitly set use of $lr.
2886 (define_insn "_return"
2887   [(return)]
2888   ""
2889   "bi\t$lr"
2890   [(set_attr "type" "br")])
2894 ;; ceq
2896 (define_insn "ceq_<mode>"
2897   [(set (match_operand:VQHSI 0 "spu_reg_operand" "=r,r")
2898         (eq:VQHSI (match_operand:VQHSI 1 "spu_reg_operand" "r,r")
2899                  (match_operand:VQHSI 2 "spu_arith_operand" "r,B")))]
2900   ""
2901   "@
2902   ceq<bh>\t%0,%1,%2
2903   ceq<bh>i\t%0,%1,%2")
2905 (define_insn_and_split "ceq_di"
2906   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2907         (eq:SI (match_operand:DI 1 "spu_reg_operand" "r")
2908                (match_operand:DI 2 "spu_reg_operand" "r")))]
2909   ""
2910   "#"
2911   "reload_completed"
2912   [(set (match_dup:SI 0)
2913         (eq:SI (match_dup:DI 1)
2914                (match_dup:DI 2)))]
2915   {
2916     rtx op0 = gen_rtx_REG (V4SImode, REGNO (operands[0]));
2917     rtx op1 = gen_rtx_REG (V4SImode, REGNO (operands[1]));
2918     rtx op2 = gen_rtx_REG (V4SImode, REGNO (operands[2]));
2919     emit_insn (gen_ceq_v4si (op0, op1, op2));
2920     emit_insn (gen_spu_gb (op0, op0));
2921     emit_insn (gen_cgt_si (operands[0], operands[0], GEN_INT (11)));
2922     DONE;
2923   })
2926 ;; We provide the TI compares for completeness and because some parts of
2927 ;; gcc/libgcc use them, even though user code might never see it.
2928 (define_insn "ceq_ti"
2929   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2930         (eq:SI (match_operand:TI 1 "spu_reg_operand" "r")
2931                (match_operand:TI 2 "spu_reg_operand" "r")))]
2932   ""
2933   "ceq\t%0,%1,%2\;gb\t%0,%0\;ceqi\t%0,%0,15"
2934   [(set_attr "type" "multi0")
2935    (set_attr "length" "12")])
2937 (define_insn "ceq_<mode>"
2938   [(set (match_operand:<F2I> 0 "spu_reg_operand" "=r")
2939         (eq:<F2I> (match_operand:VSF 1 "spu_reg_operand" "r")
2940                   (match_operand:VSF 2 "spu_reg_operand" "r")))]
2941   ""
2942   "fceq\t%0,%1,%2")
2944 (define_insn "cmeq_<mode>"
2945   [(set (match_operand:<F2I> 0 "spu_reg_operand" "=r")
2946         (eq:<F2I> (abs:VSF (match_operand:VSF 1 "spu_reg_operand" "r"))
2947                   (abs:VSF (match_operand:VSF 2 "spu_reg_operand" "r"))))]
2948   ""
2949   "fcmeq\t%0,%1,%2")
2951 ;; These implementations will ignore checking of NaN or INF if
2952 ;; compiled with option -ffinite-math-only.
2953 (define_expand "ceq_df"
2954   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2955         (eq:SI (match_operand:DF 1 "spu_reg_operand" "r")
2956                (match_operand:DF 2 "const_zero_operand" "i")))]
2957   ""
2959   if (spu_arch == PROCESSOR_CELL)
2960       {
2961         rtx ra = gen_reg_rtx (V4SImode);
2962         rtx rb = gen_reg_rtx (V4SImode);
2963         rtx temp = gen_reg_rtx (TImode);
2964         rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
2965         rtx temp2 = gen_reg_rtx (V4SImode);
2966         rtx biteq = gen_reg_rtx (V4SImode);
2967         rtx ahi_inf = gen_reg_rtx (V4SImode);
2968         rtx a_nan = gen_reg_rtx (V4SImode);
2969         rtx a_abs = gen_reg_rtx (V4SImode);
2970         rtx b_abs = gen_reg_rtx (V4SImode);
2971         rtx iszero = gen_reg_rtx (V4SImode);
2972         rtx sign_mask = gen_reg_rtx (V4SImode);
2973         rtx nan_mask = gen_reg_rtx (V4SImode);
2974         rtx hihi_promote = gen_reg_rtx (TImode);
2975         rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF,
2976                                                  0x7FFFFFFF, 0xFFFFFFFF);
2978         emit_move_insn (sign_mask, pat);
2979         pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0,
2980                                              0x7FF00000, 0x0);
2981         emit_move_insn (nan_mask, pat);
2982         pat = spu_const_from_ints (TImode, 0x00010203, 0x10111213,
2983                                            0x08090A0B, 0x18191A1B);
2984         emit_move_insn (hihi_promote, pat);
2986         emit_insn (gen_spu_convert (ra, operands[1]));
2987         emit_insn (gen_spu_convert (rb, operands[2]));
2988         emit_insn (gen_ceq_v4si (biteq, ra, rb));
2989         emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, biteq),
2990                                 GEN_INT (4 * 8)));
2991         emit_insn (gen_andv4si3 (biteq, biteq, temp_v4si));
2993         emit_insn (gen_andv4si3 (a_abs, ra, sign_mask));
2994         emit_insn (gen_andv4si3 (b_abs, rb, sign_mask));
2995         if (!flag_finite_math_only)
2996           {
2997             emit_insn (gen_clgt_v4si (a_nan, a_abs, nan_mask));
2998             emit_insn (gen_ceq_v4si (ahi_inf, a_abs, nan_mask));
2999             emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, a_nan),
3000                                    GEN_INT (4 * 8)));
3001             emit_insn (gen_andv4si3 (temp2, temp_v4si, ahi_inf));
3002             emit_insn (gen_iorv4si3 (a_nan, a_nan, temp2));
3003           }
3004         emit_insn (gen_iorv4si3 (temp2, a_abs, b_abs));
3005         emit_insn (gen_ceq_v4si (iszero, temp2, CONST0_RTX (V4SImode)));
3006         emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, iszero),
3007                                 GEN_INT (4 * 8)));
3008         emit_insn (gen_andv4si3 (iszero, iszero, temp_v4si));
3009         emit_insn (gen_iorv4si3 (temp2, biteq, iszero));
3010         if (!flag_finite_math_only)
3011           {
3012             emit_insn (gen_andc_v4si (temp2, temp2, a_nan));
3013           }
3014         emit_insn (gen_shufb (operands[0], temp2, temp2, hihi_promote));
3015         DONE;
3016       }
3019 (define_insn "ceq_<mode>_celledp"
3020   [(set (match_operand:<DF2I> 0 "spu_reg_operand" "=r")
3021         (eq:<DF2I> (match_operand:VDF 1 "spu_reg_operand" "r")
3022                    (match_operand:VDF 2 "spu_reg_operand" "r")))]
3023   "spu_arch == PROCESSOR_CELLEDP"
3024   "dfceq\t%0,%1,%2"
3025   [(set_attr "type" "fpd")])
3027 (define_insn "cmeq_<mode>_celledp"
3028   [(set (match_operand:<DF2I> 0 "spu_reg_operand" "=r")
3029         (eq:<DF2I> (abs:VDF (match_operand:VDF 1 "spu_reg_operand" "r"))
3030                    (abs:VDF (match_operand:VDF 2 "spu_reg_operand" "r"))))]
3031   "spu_arch == PROCESSOR_CELLEDP"
3032   "dfcmeq\t%0,%1,%2"
3033   [(set_attr "type" "fpd")])
3035 (define_expand "ceq_v2df"
3036   [(set (match_operand:V2DI 0 "spu_reg_operand" "=r")
3037         (eq:V2DI (match_operand:V2DF 1 "spu_reg_operand" "r")
3038                  (match_operand:V2DF 2 "spu_reg_operand" "r")))]
3039   ""
3041   if (spu_arch == PROCESSOR_CELL)
3042     {
3043       rtx ra = spu_gen_subreg (V4SImode, operands[1]);
3044       rtx rb = spu_gen_subreg (V4SImode, operands[2]);
3045       rtx temp = gen_reg_rtx (TImode);
3046       rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
3047       rtx temp2 = gen_reg_rtx (V4SImode);
3048       rtx biteq = gen_reg_rtx (V4SImode);
3049       rtx ahi_inf = gen_reg_rtx (V4SImode);
3050       rtx a_nan = gen_reg_rtx (V4SImode);
3051       rtx a_abs = gen_reg_rtx (V4SImode);
3052       rtx b_abs = gen_reg_rtx (V4SImode);
3053       rtx iszero = gen_reg_rtx (V4SImode);
3054       rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF,
3055                                                0x7FFFFFFF, 0xFFFFFFFF);
3056       rtx sign_mask = gen_reg_rtx (V4SImode);
3057       rtx nan_mask = gen_reg_rtx (V4SImode);
3058       rtx hihi_promote = gen_reg_rtx (TImode);
3060       emit_move_insn (sign_mask, pat);
3061       pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0, 
3062                                              0x7FF00000, 0x0);
3063       emit_move_insn (nan_mask, pat);
3064       pat = spu_const_from_ints (TImode, 0x00010203, 0x10111213, 
3065                                            0x08090A0B, 0x18191A1B);
3066       emit_move_insn (hihi_promote, pat);
3068       emit_insn (gen_ceq_v4si (biteq, ra, rb));
3069       emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, biteq), 
3070                               GEN_INT (4 * 8)));
3071       emit_insn (gen_andv4si3 (biteq, biteq, temp_v4si));
3072       emit_insn (gen_andv4si3 (a_abs, ra, sign_mask));
3073       emit_insn (gen_andv4si3 (b_abs, rb, sign_mask));
3074       emit_insn (gen_clgt_v4si (a_nan, a_abs, nan_mask));
3075       emit_insn (gen_ceq_v4si (ahi_inf, a_abs, nan_mask));
3076       emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, a_nan), 
3077                               GEN_INT (4 * 8)));
3078       emit_insn (gen_andv4si3 (temp2, temp_v4si, ahi_inf));
3079       emit_insn (gen_iorv4si3 (a_nan, a_nan, temp2));
3080       emit_insn (gen_iorv4si3 (temp2, a_abs, b_abs));
3081       emit_insn (gen_ceq_v4si (iszero, temp2, CONST0_RTX (V4SImode)));
3082       emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, iszero), 
3083                               GEN_INT (4 * 8)));
3084       emit_insn (gen_andv4si3 (iszero, iszero, temp_v4si));
3085       emit_insn (gen_iorv4si3 (temp2, biteq, iszero));
3086       emit_insn (gen_andc_v4si (temp2, temp2, a_nan));
3087       emit_insn (gen_shufb (operands[0], temp2, temp2, hihi_promote));
3088       DONE;
3089   }
3092 (define_expand "cmeq_v2df"
3093   [(set (match_operand:V2DI 0 "spu_reg_operand" "=r")
3094         (eq:V2DI (abs:V2DF (match_operand:V2DF 1 "spu_reg_operand" "r"))
3095                  (abs:V2DF (match_operand:V2DF 2 "spu_reg_operand" "r"))))]
3096   ""
3098   if (spu_arch == PROCESSOR_CELL)
3099     {
3100       rtx ra = spu_gen_subreg (V4SImode, operands[1]);
3101       rtx rb = spu_gen_subreg (V4SImode, operands[2]);
3102       rtx temp = gen_reg_rtx (TImode);
3103       rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
3104       rtx temp2 = gen_reg_rtx (V4SImode);
3105       rtx biteq = gen_reg_rtx (V4SImode);
3106       rtx ahi_inf = gen_reg_rtx (V4SImode);
3107       rtx a_nan = gen_reg_rtx (V4SImode);
3108       rtx a_abs = gen_reg_rtx (V4SImode);
3109       rtx b_abs = gen_reg_rtx (V4SImode);
3111       rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF, 
3112                                                0x7FFFFFFF, 0xFFFFFFFF);
3113       rtx sign_mask = gen_reg_rtx (V4SImode);
3114       rtx nan_mask = gen_reg_rtx (V4SImode);
3115       rtx hihi_promote = gen_reg_rtx (TImode);
3117       emit_move_insn (sign_mask, pat);
3119       pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0, 
3120                                            0x7FF00000, 0x0);
3121       emit_move_insn (nan_mask, pat);
3122       pat = spu_const_from_ints (TImode, 0x00010203, 0x10111213, 
3123                                          0x08090A0B, 0x18191A1B);
3124       emit_move_insn (hihi_promote, pat);
3126       emit_insn (gen_andv4si3 (a_abs, ra, sign_mask));
3127       emit_insn (gen_andv4si3 (b_abs, rb, sign_mask));
3128       emit_insn (gen_ceq_v4si (biteq, a_abs, b_abs));
3129       emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, biteq), 
3130                                                     GEN_INT (4 * 8)));
3131       emit_insn (gen_andv4si3 (biteq, biteq, temp_v4si));
3132       emit_insn (gen_clgt_v4si (a_nan, a_abs, nan_mask));
3133       emit_insn (gen_ceq_v4si (ahi_inf, a_abs, nan_mask));
3134       emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, a_nan), 
3135                                                     GEN_INT (4 * 8)));
3136       emit_insn (gen_andv4si3 (temp2, temp_v4si, ahi_inf));
3137       emit_insn (gen_iorv4si3 (a_nan, a_nan, temp2));
3138       emit_insn (gen_andc_v4si (temp2, biteq, a_nan));
3139       emit_insn (gen_shufb (operands[0], temp2, temp2, hihi_promote));
3140       DONE;
3141   }
3145 ;; cgt
3147 (define_insn "cgt_<mode>"
3148   [(set (match_operand:VQHSI 0 "spu_reg_operand" "=r,r")
3149         (gt:VQHSI (match_operand:VQHSI 1 "spu_reg_operand" "r,r")
3150                   (match_operand:VQHSI 2 "spu_arith_operand" "r,B")))]
3151   ""
3152   "@
3153   cgt<bh>\t%0,%1,%2
3154   cgt<bh>i\t%0,%1,%2")
3156 (define_insn "cgt_di_m1" 
3157   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3158         (gt:SI (match_operand:DI 1 "spu_reg_operand" "r")
3159                (const_int -1)))]
3160   ""
3161   "cgti\t%0,%1,-1")
3163 (define_insn_and_split "cgt_di" 
3164   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3165         (gt:SI (match_operand:DI 1 "spu_reg_operand" "r")
3166                (match_operand:DI 2 "spu_reg_operand" "r")))
3167    (clobber (match_scratch:V4SI 3 "=&r"))
3168    (clobber (match_scratch:V4SI 4 "=&r"))
3169    (clobber (match_scratch:V4SI 5 "=&r"))]
3170   ""
3171   "#"
3172   "reload_completed"
3173   [(set (match_dup:SI 0)
3174         (gt:SI (match_dup:DI 1)
3175                (match_dup:DI 2)))]
3176   {
3177     rtx op0 = gen_rtx_REG (V4SImode, REGNO (operands[0]));
3178     rtx op1 = gen_rtx_REG (V4SImode, REGNO (operands[1]));
3179     rtx op2 = gen_rtx_REG (V4SImode, REGNO (operands[2]));
3180     rtx op3 = operands[3];
3181     rtx op4 = operands[4];
3182     rtx op5 = operands[5];
3183     rtx op3d = gen_rtx_REG (V2DImode, REGNO (operands[3]));
3184     emit_insn (gen_clgt_v4si (op3, op1, op2));
3185     emit_insn (gen_ceq_v4si (op4, op1, op2));
3186     emit_insn (gen_cgt_v4si (op5, op1, op2));
3187     emit_insn (gen_spu_xswd (op3d, op3));
3188     emit_insn (gen_selb (op0, op5, op3, op4));
3189     DONE;
3190   })
3192 (define_insn "cgt_ti"
3193   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3194         (gt:SI (match_operand:TI 1 "spu_reg_operand" "r")
3195                (match_operand:TI 2 "spu_reg_operand" "r")))
3196    (clobber (match_scratch:V4SI 3 "=&r"))
3197    (clobber (match_scratch:V4SI 4 "=&r"))
3198    (clobber (match_scratch:V4SI 5 "=&r"))]
3199   ""
3200   "clgt\t%4,%1,%2\;\
3201 ceq\t%3,%1,%2\;\
3202 cgt\t%5,%1,%2\;\
3203 shlqbyi\t%0,%4,4\;\
3204 selb\t%0,%4,%0,%3\;\
3205 shlqbyi\t%0,%0,4\;\
3206 selb\t%0,%4,%0,%3\;\
3207 shlqbyi\t%0,%0,4\;\
3208 selb\t%0,%5,%0,%3"
3209   [(set_attr "type" "multi0")
3210    (set_attr "length" "36")])
3212 (define_insn "cgt_<mode>"
3213   [(set (match_operand:<F2I> 0 "spu_reg_operand" "=r")
3214         (gt:<F2I> (match_operand:VSF 1 "spu_reg_operand" "r")
3215                   (match_operand:VSF 2 "spu_reg_operand" "r")))]
3216   ""
3217   "fcgt\t%0,%1,%2")
3219 (define_insn "cmgt_<mode>"
3220   [(set (match_operand:<F2I> 0 "spu_reg_operand" "=r")
3221         (gt:<F2I> (abs:VSF (match_operand:VSF 1 "spu_reg_operand" "r"))
3222                   (abs:VSF (match_operand:VSF 2 "spu_reg_operand" "r"))))]
3223   ""
3224   "fcmgt\t%0,%1,%2")
3226 (define_expand "cgt_df"
3227   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3228         (gt:SI (match_operand:DF 1 "spu_reg_operand" "r")
3229                (match_operand:DF 2 "const_zero_operand" "i")))]
3230   ""
3232   if (spu_arch == PROCESSOR_CELL)
3233     {
3234       rtx ra = gen_reg_rtx (V4SImode);
3235       rtx rb = gen_reg_rtx (V4SImode);
3236       rtx zero = gen_reg_rtx (V4SImode);
3237       rtx temp = gen_reg_rtx (TImode);
3238       rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
3239       rtx temp2 = gen_reg_rtx (V4SImode);
3240       rtx hi_inf = gen_reg_rtx (V4SImode);
3241       rtx a_nan = gen_reg_rtx (V4SImode);
3242       rtx b_nan = gen_reg_rtx (V4SImode);
3243       rtx a_abs = gen_reg_rtx (V4SImode);
3244       rtx b_abs = gen_reg_rtx (V4SImode);
3245       rtx asel = gen_reg_rtx (V4SImode);
3246       rtx bsel = gen_reg_rtx (V4SImode);
3247       rtx abor = gen_reg_rtx (V4SImode);
3248       rtx bbor = gen_reg_rtx (V4SImode);
3249       rtx gt_hi = gen_reg_rtx (V4SImode);
3250       rtx gt_lo = gen_reg_rtx (V4SImode);
3251       rtx sign_mask = gen_reg_rtx (V4SImode);
3252       rtx nan_mask = gen_reg_rtx (V4SImode);
3253       rtx hi_promote = gen_reg_rtx (TImode);
3254       rtx borrow_shuffle = gen_reg_rtx (TImode);
3256       rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF,
3257                                                0x7FFFFFFF, 0xFFFFFFFF);
3258       emit_move_insn (sign_mask, pat);
3259       pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0,
3260                                              0x7FF00000, 0x0);
3261       emit_move_insn (nan_mask, pat);
3262       pat = spu_const_from_ints (TImode, 0x00010203, 0x00010203,
3263                                          0x08090A0B, 0x08090A0B);
3264       emit_move_insn (hi_promote, pat);
3265       pat = spu_const_from_ints (TImode, 0x04050607, 0xC0C0C0C0,
3266                                          0x0C0D0E0F, 0xC0C0C0C0);
3267       emit_move_insn (borrow_shuffle, pat);
3269       emit_insn (gen_spu_convert (ra, operands[1]));
3270       emit_insn (gen_spu_convert (rb, operands[2]));
3271       emit_insn (gen_andv4si3 (a_abs, ra, sign_mask));
3272       emit_insn (gen_andv4si3 (b_abs, rb, sign_mask));
3274       if (!flag_finite_math_only)
3275         {
3276           /* check if ra is NaN  */
3277           emit_insn (gen_ceq_v4si (hi_inf, a_abs, nan_mask));
3278           emit_insn (gen_clgt_v4si (a_nan, a_abs, nan_mask));
3279           emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, a_nan),
3280                                   GEN_INT (4 * 8)));
3281           emit_insn (gen_andv4si3 (temp2, temp_v4si, hi_inf));
3282           emit_insn (gen_iorv4si3 (a_nan, a_nan, temp2));
3283           emit_insn (gen_shufb (a_nan, a_nan, a_nan, hi_promote));
3285           /* check if rb is NaN  */
3286           emit_insn (gen_ceq_v4si (hi_inf, b_abs, nan_mask));
3287           emit_insn (gen_clgt_v4si (b_nan, b_abs, nan_mask));
3288           emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, b_nan),
3289                                   GEN_INT (4 * 8)));
3290           emit_insn (gen_andv4si3 (temp2, temp_v4si, hi_inf));
3291           emit_insn (gen_iorv4si3 (b_nan, b_nan, temp2));
3292           emit_insn (gen_shufb (b_nan, b_nan, b_nan, hi_promote));
3294           /* check if ra or rb is NaN  */
3295           emit_insn (gen_iorv4si3 (a_nan, a_nan, b_nan));
3296         }
3297       emit_move_insn (zero, CONST0_RTX (V4SImode));
3298       emit_insn (gen_vashrv4si3 (asel, ra, spu_const (V4SImode, 31)));
3299       emit_insn (gen_shufb (asel, asel, asel, hi_promote));
3300       emit_insn (gen_bg_v4si (abor, zero, a_abs));
3301       emit_insn (gen_shufb (abor, abor, abor, borrow_shuffle));
3302       emit_insn (gen_sfx_v4si (abor, zero, a_abs, abor));
3303       emit_insn (gen_selb (abor, a_abs, abor, asel));
3305       emit_insn (gen_vashrv4si3 (bsel, rb, spu_const (V4SImode, 31)));
3306       emit_insn (gen_shufb (bsel, bsel, bsel, hi_promote));
3307       emit_insn (gen_bg_v4si (bbor, zero, b_abs));
3308       emit_insn (gen_shufb (bbor, bbor, bbor, borrow_shuffle));
3309       emit_insn (gen_sfx_v4si (bbor, zero, b_abs, bbor));
3310       emit_insn (gen_selb (bbor, b_abs, bbor, bsel));
3312       emit_insn (gen_cgt_v4si (gt_hi, abor, bbor));
3313       emit_insn (gen_clgt_v4si (gt_lo, abor, bbor));
3314       emit_insn (gen_ceq_v4si (temp2, abor, bbor));
3315       emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, gt_lo),
3316                                 GEN_INT (4 * 8)));
3317       emit_insn (gen_andv4si3 (temp2, temp2, temp_v4si));
3318       emit_insn (gen_iorv4si3 (temp2, gt_hi, temp2));
3319       emit_insn (gen_shufb (temp2, temp2, temp2, hi_promote));
3320       if (!flag_finite_math_only)
3321         {
3322           /* correct for NaNs  */
3323           emit_insn (gen_andc_v4si (temp2, temp2, a_nan));
3324         }
3325       emit_insn (gen_spu_convert (operands[0], temp2));
3326       DONE;
3327     }
3330 (define_insn "cgt_<mode>_celledp"
3331   [(set (match_operand:<DF2I> 0 "spu_reg_operand" "=r")
3332         (gt:<DF2I> (match_operand:VDF 1 "spu_reg_operand" "r")
3333                    (match_operand:VDF 2 "spu_reg_operand" "r")))]
3334   "spu_arch == PROCESSOR_CELLEDP"
3335   "dfcgt\t%0,%1,%2"
3336   [(set_attr "type" "fpd")])
3338 (define_insn "cmgt_<mode>_celledp"
3339   [(set (match_operand:<DF2I> 0 "spu_reg_operand" "=r")
3340         (gt:<DF2I> (abs:VDF (match_operand:VDF 1 "spu_reg_operand" "r"))
3341                    (abs:VDF (match_operand:VDF 2 "spu_reg_operand" "r"))))]
3342   "spu_arch == PROCESSOR_CELLEDP"
3343   "dfcmgt\t%0,%1,%2"
3344   [(set_attr "type" "fpd")])
3346 (define_expand "cgt_v2df"
3347   [(set (match_operand:V2DI 0 "spu_reg_operand" "=r")
3348         (gt:V2DI (match_operand:V2DF 1 "spu_reg_operand" "r")
3349                  (match_operand:V2DF 2 "spu_reg_operand" "r")))]
3350   ""
3352   if (spu_arch == PROCESSOR_CELL)
3353     {
3354       rtx ra = spu_gen_subreg (V4SImode, operands[1]);
3355       rtx rb = spu_gen_subreg (V4SImode, operands[2]);
3356       rtx zero = gen_reg_rtx (V4SImode);
3357       rtx temp = gen_reg_rtx (TImode);
3358       rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
3359       rtx temp2 = gen_reg_rtx (V4SImode);
3360       rtx hi_inf = gen_reg_rtx (V4SImode);
3361       rtx a_nan = gen_reg_rtx (V4SImode);
3362       rtx b_nan = gen_reg_rtx (V4SImode);
3363       rtx a_abs = gen_reg_rtx (V4SImode);
3364       rtx b_abs = gen_reg_rtx (V4SImode);
3365       rtx asel = gen_reg_rtx (V4SImode);
3366       rtx bsel = gen_reg_rtx (V4SImode);
3367       rtx abor = gen_reg_rtx (V4SImode);
3368       rtx bbor = gen_reg_rtx (V4SImode);
3369       rtx gt_hi = gen_reg_rtx (V4SImode);
3370       rtx gt_lo = gen_reg_rtx (V4SImode);
3371       rtx sign_mask = gen_reg_rtx (V4SImode);
3372       rtx nan_mask = gen_reg_rtx (V4SImode);
3373       rtx hi_promote = gen_reg_rtx (TImode);
3374       rtx borrow_shuffle = gen_reg_rtx (TImode);
3375       rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF, 
3376                                                0x7FFFFFFF, 0xFFFFFFFF);
3377       emit_move_insn (sign_mask, pat);
3378       pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0, 
3379                                            0x7FF00000, 0x0);
3380       emit_move_insn (nan_mask, pat);
3381       pat = spu_const_from_ints (TImode, 0x00010203, 0x00010203, 
3382                                          0x08090A0B, 0x08090A0B);
3383       emit_move_insn (hi_promote, pat);
3384       pat = spu_const_from_ints (TImode, 0x04050607, 0xC0C0C0C0, 
3385                                          0x0C0D0E0F, 0xC0C0C0C0);
3386       emit_move_insn (borrow_shuffle, pat);
3388       emit_insn (gen_andv4si3 (a_abs, ra, sign_mask));
3389       emit_insn (gen_ceq_v4si (hi_inf, a_abs, nan_mask));
3390       emit_insn (gen_clgt_v4si (a_nan, a_abs, nan_mask));
3391       emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, a_nan), 
3392                                                     GEN_INT (4 * 8)));
3393       emit_insn (gen_andv4si3 (temp2, temp_v4si, hi_inf));
3394       emit_insn (gen_iorv4si3 (a_nan, a_nan, temp2));
3395       emit_insn (gen_shufb (a_nan, a_nan, a_nan, hi_promote));
3396       emit_insn (gen_andv4si3 (b_abs, rb, sign_mask));
3397       emit_insn (gen_ceq_v4si (hi_inf, b_abs, nan_mask));
3398       emit_insn (gen_clgt_v4si (b_nan, b_abs, nan_mask));
3399       emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, b_nan), 
3400                                                     GEN_INT (4 * 8)));
3401       emit_insn (gen_andv4si3 (temp2, temp_v4si, hi_inf));
3402       emit_insn (gen_iorv4si3 (b_nan, b_nan, temp2));
3403       emit_insn (gen_shufb (b_nan, b_nan, b_nan, hi_promote));
3404       emit_insn (gen_iorv4si3 (a_nan, a_nan, b_nan));
3405       emit_move_insn (zero, CONST0_RTX (V4SImode));
3406       emit_insn (gen_vashrv4si3 (asel, ra, spu_const (V4SImode, 31)));
3407       emit_insn (gen_shufb (asel, asel, asel, hi_promote));
3408       emit_insn (gen_bg_v4si (abor, zero, a_abs));
3409       emit_insn (gen_shufb (abor, abor, abor, borrow_shuffle));
3410       emit_insn (gen_sfx_v4si (abor, zero, a_abs, abor));
3411       emit_insn (gen_selb (abor, a_abs, abor, asel));
3412       emit_insn (gen_vashrv4si3 (bsel, rb, spu_const (V4SImode, 31)));
3413       emit_insn (gen_shufb (bsel, bsel, bsel, hi_promote));
3414       emit_insn (gen_bg_v4si (bbor, zero, b_abs));
3415       emit_insn (gen_shufb (bbor, bbor, bbor, borrow_shuffle));
3416       emit_insn (gen_sfx_v4si (bbor, zero, b_abs, bbor));
3417       emit_insn (gen_selb (bbor, b_abs, bbor, bsel));
3418       emit_insn (gen_cgt_v4si (gt_hi, abor, bbor));
3419       emit_insn (gen_clgt_v4si (gt_lo, abor, bbor));
3420       emit_insn (gen_ceq_v4si (temp2, abor, bbor));
3421       emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, gt_lo), 
3422                                                     GEN_INT (4 * 8)));
3423       emit_insn (gen_andv4si3 (temp2, temp2, temp_v4si));
3424       emit_insn (gen_iorv4si3 (temp2, gt_hi, temp2));
3426       emit_insn (gen_shufb (temp2, temp2, temp2, hi_promote));
3427       emit_insn (gen_andc_v4si (temp2, temp2, a_nan));
3428       emit_move_insn (operands[0], spu_gen_subreg (V2DImode, temp2));
3429       DONE;
3430     } 
3433 (define_expand "cmgt_v2df"
3434   [(set (match_operand:V2DI 0 "spu_reg_operand" "=r")
3435         (gt:V2DI (abs:V2DF (match_operand:V2DF 1 "spu_reg_operand" "r"))
3436                  (abs:V2DF (match_operand:V2DF 2 "spu_reg_operand" "r"))))]
3437   ""
3439   if (spu_arch == PROCESSOR_CELL)
3440     {
3441       rtx ra = spu_gen_subreg (V4SImode, operands[1]);
3442       rtx rb = spu_gen_subreg (V4SImode, operands[2]);
3443       rtx temp = gen_reg_rtx (TImode);
3444       rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
3445       rtx temp2 = gen_reg_rtx (V4SImode);
3446       rtx hi_inf = gen_reg_rtx (V4SImode);
3447       rtx a_nan = gen_reg_rtx (V4SImode);
3448       rtx b_nan = gen_reg_rtx (V4SImode);
3449       rtx a_abs = gen_reg_rtx (V4SImode);
3450       rtx b_abs = gen_reg_rtx (V4SImode);
3451       rtx gt_hi = gen_reg_rtx (V4SImode);
3452       rtx gt_lo = gen_reg_rtx (V4SImode);
3453       rtx sign_mask = gen_reg_rtx (V4SImode);
3454       rtx nan_mask = gen_reg_rtx (V4SImode);
3455       rtx hi_promote = gen_reg_rtx (TImode);
3456       rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF, 
3457                                                0x7FFFFFFF, 0xFFFFFFFF);
3458       emit_move_insn (sign_mask, pat);
3459       pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0, 
3460                                            0x7FF00000, 0x0);
3461       emit_move_insn (nan_mask, pat);
3462       pat = spu_const_from_ints (TImode, 0x00010203, 0x00010203, 
3463                                          0x08090A0B, 0x08090A0B);
3464       emit_move_insn (hi_promote, pat);
3466       emit_insn (gen_andv4si3 (a_abs, ra, sign_mask));
3467       emit_insn (gen_ceq_v4si (hi_inf, a_abs, nan_mask));
3468       emit_insn (gen_clgt_v4si (a_nan, a_abs, nan_mask));
3469       emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, a_nan), 
3470                                                     GEN_INT (4 * 8)));
3471       emit_insn (gen_andv4si3 (temp2, temp_v4si, hi_inf));
3472       emit_insn (gen_iorv4si3 (a_nan, a_nan, temp2));
3473       emit_insn (gen_shufb (a_nan, a_nan, a_nan, hi_promote));
3474       emit_insn (gen_andv4si3 (b_abs, rb, sign_mask));
3475       emit_insn (gen_ceq_v4si (hi_inf, b_abs, nan_mask));
3476       emit_insn (gen_clgt_v4si (b_nan, b_abs, nan_mask));
3477       emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, b_nan), 
3478                                                     GEN_INT (4 * 8)));
3479       emit_insn (gen_andv4si3 (temp2, temp_v4si, hi_inf));
3480       emit_insn (gen_iorv4si3 (b_nan, b_nan, temp2));
3481       emit_insn (gen_shufb (b_nan, b_nan, b_nan, hi_promote));
3482       emit_insn (gen_iorv4si3 (a_nan, a_nan, b_nan));
3484       emit_insn (gen_clgt_v4si (gt_hi, a_abs, b_abs));
3485       emit_insn (gen_clgt_v4si (gt_lo, a_abs, b_abs));
3486       emit_insn (gen_ceq_v4si (temp2, a_abs, b_abs));
3487       emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, gt_lo), 
3488                                                     GEN_INT (4 * 8)));
3489       emit_insn (gen_andv4si3 (temp2, temp2, temp_v4si));
3490       emit_insn (gen_iorv4si3 (temp2, gt_hi, temp2));
3491       emit_insn (gen_shufb (temp2, temp2, temp2, hi_promote));
3492       emit_insn (gen_andc_v4si (temp2, temp2, a_nan));
3493       emit_move_insn (operands[0], spu_gen_subreg (V2DImode, temp2));
3494       DONE;
3495     }
3499 ;; clgt
3501 (define_insn "clgt_<mode>"
3502   [(set (match_operand:VQHSI 0 "spu_reg_operand" "=r,r")
3503         (gtu:VQHSI (match_operand:VQHSI 1 "spu_reg_operand" "r,r")
3504                    (match_operand:VQHSI 2 "spu_arith_operand" "r,B")))]
3505   ""
3506   "@
3507   clgt<bh>\t%0,%1,%2
3508   clgt<bh>i\t%0,%1,%2")
3510 (define_insn_and_split "clgt_di" 
3511   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3512         (gtu:SI (match_operand:DI 1 "spu_reg_operand" "r")
3513                 (match_operand:DI 2 "spu_reg_operand" "r")))
3514    (clobber (match_scratch:V4SI 3 "=&r"))
3515    (clobber (match_scratch:V4SI 4 "=&r"))
3516    (clobber (match_scratch:V4SI 5 "=&r"))]
3517   ""
3518   "#"
3519   "reload_completed"
3520   [(set (match_dup:SI 0)
3521         (gtu:SI (match_dup:DI 1)
3522                 (match_dup:DI 2)))]
3523   {
3524     rtx op0 = gen_rtx_REG (V4SImode, REGNO (operands[0]));
3525     rtx op1 = gen_rtx_REG (V4SImode, REGNO (operands[1]));
3526     rtx op2 = gen_rtx_REG (V4SImode, REGNO (operands[2]));
3527     rtx op3 = operands[3];
3528     rtx op4 = operands[4];
3529     rtx op5 = operands[5];
3530     rtx op5d = gen_rtx_REG (V2DImode, REGNO (operands[5]));
3531     emit_insn (gen_clgt_v4si (op3, op1, op2));
3532     emit_insn (gen_ceq_v4si (op4, op1, op2));
3533     emit_insn (gen_spu_xswd (op5d, op3));
3534     emit_insn (gen_selb (op0, op3, op5, op4));
3535     DONE;
3536   })
3538 (define_insn "clgt_ti"
3539   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3540         (gtu:SI (match_operand:TI 1 "spu_reg_operand" "r")
3541                (match_operand:TI 2 "spu_reg_operand" "r")))
3542    (clobber (match_scratch:V4SI 3 "=&r"))
3543    (clobber (match_scratch:V4SI 4 "=&r"))]
3544   ""
3545   "ceq\t%3,%1,%2\;\
3546 clgt\t%4,%1,%2\;\
3547 shlqbyi\t%0,%4,4\;\
3548 selb\t%0,%4,%0,%3\;\
3549 shlqbyi\t%0,%0,4\;\
3550 selb\t%0,%4,%0,%3\;\
3551 shlqbyi\t%0,%0,4\;\
3552 selb\t%0,%4,%0,%3"
3553   [(set_attr "type" "multi0")
3554    (set_attr "length" "32")])
3557 ;; dftsv
3558 (define_insn "dftsv_celledp"
3559   [(set (match_operand:V2DI 0 "spu_reg_operand" "=r")
3560         (unspec:V2DI [(match_operand:V2DF 1 "spu_reg_operand"  "r")
3561                       (match_operand:SI   2 "const_int_operand" "i")]
3562                       UNSPEC_DFTSV))]
3563   "spu_arch == PROCESSOR_CELLEDP"
3564   "dftsv\t%0,%1,%2"
3565   [(set_attr "type" "fpd")])
3567 (define_expand "dftsv"
3568   [(set (match_operand:V2DI 0 "spu_reg_operand" "=r")
3569         (unspec:V2DI [(match_operand:V2DF 1 "spu_reg_operand" "r")
3570                       (match_operand:SI   2 "const_int_operand" "i")]
3571                       UNSPEC_DFTSV))]
3572   ""
3574   if (spu_arch == PROCESSOR_CELL)
3575     {
3576       rtx result = gen_reg_rtx (V4SImode);
3577       emit_move_insn (result, CONST0_RTX (V4SImode));
3579       if (INTVAL (operands[2]))
3580         {
3581           rtx ra = spu_gen_subreg (V4SImode, operands[1]);
3582           rtx abs = gen_reg_rtx (V4SImode);
3583           rtx sign = gen_reg_rtx (V4SImode);
3584           rtx temp = gen_reg_rtx (TImode);
3585           rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
3586           rtx temp2 = gen_reg_rtx (V4SImode);
3587           rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF, 
3588                                                    0x7FFFFFFF, 0xFFFFFFFF);
3589           rtx sign_mask = gen_reg_rtx (V4SImode);
3590           rtx hi_promote = gen_reg_rtx (TImode);
3591           emit_move_insn (sign_mask, pat);
3592           pat = spu_const_from_ints (TImode, 0x00010203, 0x00010203, 
3593                                              0x08090A0B, 0x08090A0B);
3594           emit_move_insn (hi_promote, pat);
3596           emit_insn (gen_vashrv4si3 (sign, ra, spu_const (V4SImode, 31)));
3597           emit_insn (gen_shufb (sign, sign, sign, hi_promote));
3598           emit_insn (gen_andv4si3 (abs, ra, sign_mask));
3600           /* NaN  or +inf or -inf */
3601           if (INTVAL (operands[2]) & 0x70)
3602             {
3603               rtx nan_mask = gen_reg_rtx (V4SImode);
3604               rtx isinf = gen_reg_rtx (V4SImode);
3605               pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0, 
3606                                                    0x7FF00000, 0x0);
3607               emit_move_insn (nan_mask, pat);
3608               emit_insn (gen_ceq_v4si (isinf, abs, nan_mask));
3610               /* NaN  */
3611               if (INTVAL (operands[2]) & 0x40)
3612                 {
3613                   rtx isnan = gen_reg_rtx (V4SImode);
3614                   emit_insn (gen_clgt_v4si (isnan, abs, nan_mask));
3615                   emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, isnan), 
3616                                                              GEN_INT (4 * 8)));
3617                   emit_insn (gen_andv4si3 (temp2, temp_v4si, isinf));
3618                   emit_insn (gen_iorv4si3 (isnan, isnan, temp2));
3619                   emit_insn (gen_shufb (isnan, isnan, isnan, hi_promote));
3620                   emit_insn (gen_iorv4si3 (result, result, isnan));
3621                 }
3622               /* +inf or -inf  */
3623               if (INTVAL (operands[2]) & 0x30)
3624                 {
3625                   emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, isinf), 
3626                                                              GEN_INT (4 * 8)));
3627                   emit_insn (gen_andv4si3 (isinf, isinf, temp_v4si));
3628                   emit_insn (gen_shufb (isinf, isinf, isinf, hi_promote));
3630                   /* +inf  */
3631                   if (INTVAL (operands[2]) & 0x20)
3632                     {
3633                       emit_insn (gen_andc_v4si (temp2, isinf, sign));
3634                       emit_insn (gen_iorv4si3 (result, result, temp2));
3635                     }
3636                   /* -inf  */
3637                   if (INTVAL (operands[2]) & 0x10)
3638                     {
3639                       emit_insn (gen_andv4si3 (temp2, isinf, sign));
3640                       emit_insn (gen_iorv4si3 (result, result, temp2));
3641                     }
3642                 }
3643             }
3645           /* 0 or denorm  */
3646           if (INTVAL (operands[2]) & 0xF)
3647             {
3648               rtx iszero = gen_reg_rtx (V4SImode);
3649               emit_insn (gen_ceq_v4si (iszero, abs, CONST0_RTX (V4SImode)));
3650               emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, iszero), 
3651                                                           GEN_INT (4 * 8)));
3652               emit_insn (gen_andv4si3 (iszero, iszero, temp_v4si));
3654               /* denorm  */
3655               if (INTVAL (operands[2]) & 0x3)
3656                 {
3657                   rtx isdenorm = gen_reg_rtx (V4SImode);
3658                   rtx denorm_mask = gen_reg_rtx (V4SImode);
3659                   emit_move_insn (denorm_mask, spu_const (V4SImode, 0xFFFFF));
3660                   emit_insn (gen_clgt_v4si (isdenorm, abs, denorm_mask));
3661                   emit_insn (gen_nor_v4si (isdenorm, isdenorm, iszero));
3662                   emit_insn (gen_shufb (isdenorm, isdenorm, 
3663                                         isdenorm, hi_promote));
3664                   /* +denorm  */
3665                   if (INTVAL (operands[2]) & 0x2)
3666                     {
3667                       emit_insn (gen_andc_v4si (temp2, isdenorm, sign));
3668                       emit_insn (gen_iorv4si3 (result, result, temp2));
3669                     }
3670                   /* -denorm  */
3671                   if (INTVAL (operands[2]) & 0x1)
3672                     {
3673                       emit_insn (gen_andv4si3 (temp2, isdenorm, sign));
3674                       emit_insn (gen_iorv4si3 (result, result, temp2));
3675                     }
3676                 }
3678               /* 0  */
3679               if (INTVAL (operands[2]) & 0xC)
3680                 {
3681                   emit_insn (gen_shufb (iszero, iszero, iszero, hi_promote));
3682                   /* +0  */
3683                   if (INTVAL (operands[2]) & 0x8)
3684                     {
3685                       emit_insn (gen_andc_v4si (temp2, iszero, sign));
3686                       emit_insn (gen_iorv4si3 (result, result, temp2));
3687                     }
3688                   /* -0  */
3689                   if (INTVAL (operands[2]) & 0x4)
3690                     {
3691                       emit_insn (gen_andv4si3 (temp2, iszero, sign));
3692                       emit_insn (gen_iorv4si3 (result, result, temp2));
3693                     }
3694                 }
3695              }
3696           }
3697       emit_move_insn (operands[0], spu_gen_subreg (V2DImode, result));
3698       DONE;
3699     }
3703 ;; branches
3705 (define_insn ""
3706   [(set (pc)
3707         (if_then_else (match_operator 1 "branch_comparison_operator"
3708                                       [(match_operand 2
3709                                                       "spu_reg_operand" "r")
3710                                        (const_int 0)])
3711                       (label_ref (match_operand 0 "" ""))
3712                       (pc)))]
3713   ""
3714   "br%b2%b1z\t%2,%0"
3715   [(set_attr "type" "br")])
3717 (define_insn ""
3718   [(set (pc)
3719         (if_then_else (match_operator 0 "branch_comparison_operator"
3720                                       [(match_operand 1
3721                                                       "spu_reg_operand" "r")
3722                                        (const_int 0)])
3723                       (return)
3724                       (pc)))]
3725   "direct_return ()"
3726   "bi%b1%b0z\t%1,$lr"
3727   [(set_attr "type" "br")])
3729 (define_insn ""
3730   [(set (pc)
3731         (if_then_else (match_operator 1 "branch_comparison_operator"
3732                                       [(match_operand 2
3733                                                       "spu_reg_operand" "r")
3734                                        (const_int 0)])
3735                       (pc)
3736                       (label_ref (match_operand 0 "" ""))))]
3737   ""
3738   "br%b2%b1z\t%2,%0"
3739   [(set_attr "type" "br")])
3741 (define_insn ""
3742   [(set (pc)
3743         (if_then_else (match_operator 0 "branch_comparison_operator"
3744                                       [(match_operand 1
3745                                                       "spu_reg_operand" "r")
3746                                        (const_int 0)])
3747                       (pc)
3748                       (return)))]
3749   "direct_return ()"
3750   "bi%b1%b0z\t%1,$lr"
3751   [(set_attr "type" "br")])
3754 ;; vector conditional compare patterns
3755 (define_expand "vcond<mode>"
3756   [(set (match_operand:VCMP 0 "spu_reg_operand" "=r")
3757         (if_then_else:VCMP
3758           (match_operator 3 "comparison_operator"
3759             [(match_operand:VCMP 4 "spu_reg_operand" "r")
3760              (match_operand:VCMP 5 "spu_reg_operand" "r")])
3761           (match_operand:VCMP 1 "spu_reg_operand" "r")
3762           (match_operand:VCMP 2 "spu_reg_operand" "r")))]
3763   ""
3764   {
3765     if (spu_emit_vector_cond_expr (operands[0], operands[1], operands[2],
3766                                    operands[3], operands[4], operands[5]))
3767     DONE;
3768     else
3769     FAIL;
3770   })
3772 (define_expand "vcondu<mode>"
3773   [(set (match_operand:VCMPU 0 "spu_reg_operand" "=r")
3774         (if_then_else:VCMPU
3775           (match_operator 3 "comparison_operator"
3776             [(match_operand:VCMPU 4 "spu_reg_operand" "r")
3777              (match_operand:VCMPU 5 "spu_reg_operand" "r")])
3778           (match_operand:VCMPU 1 "spu_reg_operand" "r")
3779           (match_operand:VCMPU 2 "spu_reg_operand" "r")))]
3780   ""
3781   {
3782     if (spu_emit_vector_cond_expr (operands[0], operands[1], operands[2],
3783                                    operands[3], operands[4], operands[5]))
3784     DONE;
3785     else
3786     FAIL;
3787   })
3788         
3790 ;; branch on condition
3792 (define_expand "cbranch<mode>4"
3793   [(use (match_operator 0 "ordered_comparison_operator"
3794          [(match_operand:VQHSI 1 "spu_reg_operand" "")
3795           (match_operand:VQHSI 2 "spu_nonmem_operand" "")]))
3796    (use (match_operand 3 ""))]
3797   ""
3798   { spu_emit_branch_or_set (0, operands[0], operands); DONE; })
3800 (define_expand "cbranch<mode>4"
3801   [(use (match_operator 0 "ordered_comparison_operator"
3802          [(match_operand:DTI 1 "spu_reg_operand" "")
3803           (match_operand:DTI 2 "spu_reg_operand" "")]))
3804    (use (match_operand 3 ""))]
3805   ""
3806   { spu_emit_branch_or_set (0, operands[0], operands); DONE; })
3808 (define_expand "cbranch<mode>4"
3809   [(use (match_operator 0 "ordered_comparison_operator"
3810          [(match_operand:VSF 1 "spu_reg_operand" "")
3811           (match_operand:VSF 2 "spu_reg_operand" "")]))
3812    (use (match_operand 3 ""))]
3813   ""
3814   { spu_emit_branch_or_set (0, operands[0], operands); DONE; })
3816 (define_expand "cbranchdf4"
3817   [(use (match_operator 0 "ordered_comparison_operator"
3818          [(match_operand:DF 1 "spu_reg_operand" "")
3819           (match_operand:DF 2 "spu_reg_operand" "")]))
3820    (use (match_operand 3 ""))]
3821   ""
3822   { spu_emit_branch_or_set (0, operands[0], operands); DONE; })
3825 ;; set on condition
3827 (define_expand "cstore<mode>4"
3828   [(use (match_operator 1 "ordered_comparison_operator"
3829          [(match_operand:VQHSI 2 "spu_reg_operand" "")
3830           (match_operand:VQHSI 3 "spu_nonmem_operand" "")]))
3831    (clobber (match_operand:SI 0 "spu_reg_operand"))]
3832   ""
3833   { spu_emit_branch_or_set (1, operands[1], operands); DONE; })
3835 (define_expand "cstore<mode>4"
3836   [(use (match_operator 1 "ordered_comparison_operator"
3837          [(match_operand:DTI 2 "spu_reg_operand" "")
3838           (match_operand:DTI 3 "spu_reg_operand" "")]))
3839    (clobber (match_operand:SI 0 "spu_reg_operand"))]
3840   ""
3841   { spu_emit_branch_or_set (1, operands[1], operands); DONE; })
3843 (define_expand "cstore<mode>4"
3844   [(use (match_operator 1 "ordered_comparison_operator"
3845          [(match_operand:VSF 2 "spu_reg_operand" "")
3846           (match_operand:VSF 3 "spu_reg_operand" "")]))
3847    (clobber (match_operand:SI 0 "spu_reg_operand"))]
3848   ""
3849   { spu_emit_branch_or_set (1, operands[1], operands); DONE; })
3851 (define_expand "cstoredf4"
3852   [(use (match_operator 1 "ordered_comparison_operator"
3853          [(match_operand:DF 2 "spu_reg_operand" "")
3854           (match_operand:DF 3 "spu_reg_operand" "")]))
3855    (clobber (match_operand:SI 0 "spu_reg_operand"))]
3856   ""
3857   { spu_emit_branch_or_set (1, operands[1], operands); DONE; })
3860 ;; conditional move
3862 ;; Define this first one so HAVE_conditional_move is defined.
3863 (define_insn "movcc_dummy"
3864   [(set (match_operand 0 "" "")
3865        (if_then_else (match_operand 1 "" "")
3866                      (match_operand 2 "" "")
3867                      (match_operand 3 "" "")))]
3868   "!operands[0]"
3869   "")
3871 (define_expand "mov<mode>cc"
3872   [(set (match_operand:ALL 0 "spu_reg_operand" "")
3873         (if_then_else:ALL (match_operand 1 "ordered_comparison_operator" "")
3874                       (match_operand:ALL 2 "spu_reg_operand" "")
3875                       (match_operand:ALL 3 "spu_reg_operand" "")))]
3876   ""
3877   {
3878     spu_emit_branch_or_set(2, operands[1], operands);
3879     DONE;
3880   })
3882 ;; This pattern is used when the result of a compare is not large
3883 ;; enough to use in a selb when expanding conditional moves.
3884 (define_expand "extend_compare"
3885   [(set (match_operand 0 "spu_reg_operand" "=r")
3886         (unspec [(match_operand 1 "spu_reg_operand" "r")] UNSPEC_EXTEND_CMP))]
3887   ""
3888   {
3889     emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3890                             gen_rtx_UNSPEC (GET_MODE (operands[0]),
3891                                             gen_rtvec (1, operands[1]),
3892                                             UNSPEC_EXTEND_CMP)));
3893     DONE;
3894   })
3896 (define_insn "extend_compare<mode>"
3897   [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
3898         (unspec:ALL [(match_operand 1 "spu_reg_operand" "r")] UNSPEC_EXTEND_CMP))]
3899   "operands"
3900   "fsm\t%0,%1"
3901   [(set_attr "type" "shuf")])
3904 ;; case
3906 ;; operand 0 is index
3907 ;; operand 1 is the minimum bound
3908 ;; operand 2 is the maximum bound - minimum bound + 1
3909 ;; operand 3 is CODE_LABEL for the table;
3910 ;; operand 4 is the CODE_LABEL to go to if index out of range.
3911 (define_expand "casesi"
3912   [(match_operand:SI 0 "spu_reg_operand" "")
3913    (match_operand:SI 1 "immediate_operand" "")
3914    (match_operand:SI 2 "immediate_operand" "")
3915    (match_operand 3 "" "")
3916    (match_operand 4 "" "")]
3917   ""
3918   {
3919     rtx table = gen_reg_rtx (SImode);
3920     rtx index = gen_reg_rtx (SImode);
3921     rtx sindex = gen_reg_rtx (SImode);
3922     rtx addr = gen_reg_rtx (Pmode);
3924     emit_move_insn (table, gen_rtx_LABEL_REF (SImode, operands[3]));
3926     emit_insn (gen_subsi3(index, operands[0], force_reg(SImode, operands[1])));
3927     emit_insn (gen_ashlsi3(sindex, index, GEN_INT (2)));
3928     emit_move_insn (addr, gen_rtx_MEM (SImode,
3929                                        gen_rtx_PLUS (SImode, table, sindex)));
3930     if (flag_pic)
3931       emit_insn (gen_addsi3 (addr, addr, table));
3933     emit_cmp_and_jump_insns (index, operands[2], GTU, NULL_RTX, SImode, 1, operands[4]);
3934     emit_jump_insn (gen_tablejump (addr, operands[3]));
3935     DONE;
3936   })
3938 (define_insn "tablejump"
3939   [(set (pc) (match_operand:SI 0 "spu_reg_operand" "r"))
3940    (use (label_ref (match_operand 1 "" "")))]
3941   ""
3942   "bi\t%0"
3943   [(set_attr "type" "br")])
3946 ;; call
3948 ;; Note that operand 1 is total size of args, in bytes,
3949 ;; and what the call insn wants is the number of words.
3950 (define_expand "sibcall"
3951   [(parallel
3952     [(call (match_operand:QI 0 "call_operand" "")
3953            (match_operand:QI 1 "" ""))
3954      (use (reg:SI 0))])]
3955   ""
3956   {
3957     if (! call_operand (operands[0], QImode))
3958       XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
3959   })
3961 (define_insn "_sibcall"
3962   [(parallel
3963     [(call (match_operand:QI 0 "call_operand" "R,S")
3964            (match_operand:QI 1 "" "i,i"))
3965      (use (reg:SI 0))])]
3966   "SIBLING_CALL_P(insn)"
3967   "@
3968    bi\t%i0
3969    br\t%0"
3970    [(set_attr "type" "br,br")])
3972 (define_expand "sibcall_value"
3973   [(parallel
3974     [(set (match_operand 0 "" "")
3975           (call (match_operand:QI 1 "call_operand" "")
3976                 (match_operand:QI 2 "" "")))
3977      (use (reg:SI 0))])]
3978   ""
3979   {
3980     if (! call_operand (operands[1], QImode))
3981       XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
3982   })
3984 (define_insn "_sibcall_value"
3985   [(parallel
3986     [(set (match_operand 0 "" "")
3987           (call (match_operand:QI 1 "call_operand" "R,S")
3988                 (match_operand:QI 2 "" "i,i")))
3989      (use (reg:SI 0))])]
3990   "SIBLING_CALL_P(insn)"
3991   "@
3992    bi\t%i1
3993    br\t%1"
3994    [(set_attr "type" "br,br")])
3996 ;; Note that operand 1 is total size of args, in bytes,
3997 ;; and what the call insn wants is the number of words.
3998 (define_expand "call"
3999   [(parallel
4000     [(call (match_operand:QI 0 "call_operand" "")
4001            (match_operand:QI 1 "" ""))
4002      (clobber (reg:SI 0))
4003      (clobber (reg:SI 130))])]
4004   ""
4005   {
4006     if (! call_operand (operands[0], QImode))
4007       XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
4008   })
4010 (define_insn "_call"
4011   [(parallel
4012     [(call (match_operand:QI 0 "call_operand" "R,S,T")
4013            (match_operand:QI 1 "" "i,i,i"))
4014      (clobber (reg:SI 0))
4015      (clobber (reg:SI 130))])]
4016   ""
4017   "@
4018    bisl\t$lr,%i0
4019    brsl\t$lr,%0
4020    brasl\t$lr,%0"
4021    [(set_attr "type" "br")])
4023 (define_expand "call_value"
4024   [(parallel
4025     [(set (match_operand 0 "" "")
4026           (call (match_operand:QI 1 "call_operand" "")
4027                 (match_operand:QI 2 "" "")))
4028      (clobber (reg:SI 0))
4029      (clobber (reg:SI 130))])]
4030   ""
4031   {
4032     if (! call_operand (operands[1], QImode))
4033       XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
4034   })
4036 (define_insn "_call_value"
4037   [(parallel
4038     [(set (match_operand 0 "" "")
4039           (call (match_operand:QI 1 "call_operand" "R,S,T")
4040                 (match_operand:QI 2 "" "i,i,i")))
4041      (clobber (reg:SI 0))
4042      (clobber (reg:SI 130))])]
4043   ""
4044   "@
4045    bisl\t$lr,%i1
4046    brsl\t$lr,%1
4047    brasl\t$lr,%1"
4048    [(set_attr "type" "br")])
4050 (define_expand "untyped_call"
4051   [(parallel [(call (match_operand 0 "" "")
4052                     (const_int 0))
4053               (match_operand 1 "" "")
4054               (match_operand 2 "" "")])]
4055   ""
4056   {
4057     int i;
4058     rtx reg = gen_rtx_REG (TImode, 3);
4060     /* We need to use call_value so the return value registers don't get
4061      * clobbered. */
4062     emit_call_insn (gen_call_value (reg, operands[0], const0_rtx));
4064     for (i = 0; i < XVECLEN (operands[2], 0); i++)
4065       {
4066         rtx set = XVECEXP (operands[2], 0, i);
4067         emit_move_insn (SET_DEST (set), SET_SRC (set));
4068       }
4070     /* The optimizer does not know that the call sets the function value
4071        registers we stored in the result block.  We avoid problems by
4072        claiming that all hard registers are used and clobbered at this
4073        point.  */
4074     emit_insn (gen_blockage ());
4076     DONE;
4077   })
4080 ;; Patterns used for splitting and combining.
4083 ;; Function prologue and epilogue.
4085 (define_expand "prologue"
4086   [(const_int 1)]
4087   ""
4088   { spu_expand_prologue (); DONE; })
4090 ;; "blockage" is only emited in epilogue.  This is what it took to
4091 ;; make "basic block reordering" work with the insns sequence
4092 ;; generated by the spu_expand_epilogue (taken from mips.md)
4094 (define_insn "blockage"
4095   [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
4096   ""
4097   ""
4098   [(set_attr "type" "convert")
4099    (set_attr "length" "0")])
4101 (define_expand "epilogue"
4102   [(const_int 2)]
4103   ""
4104   { spu_expand_epilogue (false); DONE; })
4106 (define_expand "sibcall_epilogue"
4107   [(const_int 2)]
4108   ""
4109   { spu_expand_epilogue (true); DONE; })
4112 ;; stack manipulations
4114 ;; An insn to allocate new stack space for dynamic use (e.g., alloca).
4115 ;; We move the back-chain and decrement the stack pointer.
4116 (define_expand "allocate_stack"
4117   [(set (match_operand 0 "spu_reg_operand" "")
4118         (minus (reg 1) (match_operand 1 "spu_nonmem_operand" "")))
4119    (set (reg 1)
4120         (minus (reg 1) (match_dup 1)))]
4121   ""
4122   "spu_allocate_stack (operands[0], operands[1]); DONE;")
4124 ;; These patterns say how to save and restore the stack pointer.  We need not
4125 ;; save the stack pointer at function level since we are careful to preserve 
4126 ;; the backchain.  
4127 ;; 
4129 ;; At block level the stack pointer is saved and restored, so that the
4130 ;; stack space allocated within a block is deallocated when leaving
4131 ;; block scope.  By default, according to the SPU ABI, the stack
4132 ;; pointer and available stack size are saved in a register. Upon
4133 ;; restoration, the stack pointer is simply copied back, and the
4134 ;; current available stack size is calculated against the restored
4135 ;; stack pointer.
4137 ;; For nonlocal gotos, we must save the stack pointer and its
4138 ;; backchain and restore both.  Note that in the nonlocal case, the
4139 ;; save area is a memory location.
4141 (define_expand "save_stack_function"
4142   [(match_operand 0 "general_operand" "")
4143    (match_operand 1 "general_operand" "")]
4144   ""
4145   "DONE;")
4147 (define_expand "restore_stack_function"
4148   [(match_operand 0 "general_operand" "")
4149    (match_operand 1 "general_operand" "")]
4150   ""
4151   "DONE;")
4153 (define_expand "restore_stack_block"
4154   [(match_operand 0 "spu_reg_operand" "")
4155    (match_operand 1 "memory_operand" "")]
4156   ""
4157   "
4158   {
4159     spu_restore_stack_block (operands[0], operands[1]);
4160     DONE;
4161   }")
4163 (define_expand "save_stack_nonlocal"
4164   [(match_operand 0 "memory_operand" "")
4165    (match_operand 1 "spu_reg_operand" "")]
4166   ""
4167   "
4168   {
4169     rtx temp = gen_reg_rtx (Pmode);
4171     /* Copy the backchain to the first word, sp to the second.  We need to
4172        save the back chain because __builtin_apply appears to clobber it. */
4173     emit_move_insn (temp, gen_rtx_MEM (Pmode, operands[1]));
4174     emit_move_insn (adjust_address_nv (operands[0], SImode, 0), temp);
4175     emit_move_insn (adjust_address_nv (operands[0], SImode, 4), operands[1]);
4176     DONE;
4177   }")
4179 (define_expand "restore_stack_nonlocal"
4180   [(match_operand 0 "spu_reg_operand" "")
4181    (match_operand 1 "memory_operand" "")]
4182   ""
4183   "
4184   {
4185     spu_restore_stack_nonlocal(operands[0], operands[1]);
4186     DONE;
4187   }")
4190 ;; vector patterns
4192 ;; Vector initialization
4193 (define_expand "vec_init<mode>"
4194   [(match_operand:V 0 "register_operand" "")
4195    (match_operand 1 "" "")]
4196   ""
4197   {
4198     spu_expand_vector_init (operands[0], operands[1]);
4199     DONE;
4200   })
4202 (define_expand "vec_set<mode>"
4203   [(use (match_operand:SI 2 "spu_nonmem_operand" ""))
4204    (set (match_dup:TI 3)
4205         (unspec:TI [(match_dup:SI 4)
4206                     (match_dup:SI 5)
4207                     (match_dup:SI 6)] UNSPEC_CPAT))
4208    (set (match_operand:V 0 "spu_reg_operand" "")
4209         (unspec:V [(match_operand:<inner> 1 "spu_reg_operand" "")
4210                    (match_dup:V 0)
4211                    (match_dup:TI 3)] UNSPEC_SHUFB))]
4212   ""
4213   {
4214     HOST_WIDE_INT size = GET_MODE_SIZE (<inner>mode);
4215     rtx offset = GEN_INT (INTVAL (operands[2]) * size);
4216     operands[3] = gen_reg_rtx (TImode);
4217     operands[4] = stack_pointer_rtx;
4218     operands[5] = offset;
4219     operands[6] = GEN_INT (size);
4220   })
4222 (define_expand "vec_extract<mode>"
4223   [(set (match_operand:<inner> 0 "spu_reg_operand" "=r")
4224         (vec_select:<inner> (match_operand:V 1 "spu_reg_operand" "r")
4225                             (parallel [(match_operand 2 "const_int_operand" "i")])))]
4226   ""
4227   {
4228     if ((INTVAL (operands[2]) * <vmult> + <voff>) % 16 == 0)
4229       {
4230         emit_insn (gen_spu_convert (operands[0], operands[1]));
4231         DONE;
4232       }
4233   })
4235 (define_insn "_vec_extract<mode>"
4236   [(set (match_operand:<inner> 0 "spu_reg_operand" "=r")
4237         (vec_select:<inner> (match_operand:V 1 "spu_reg_operand" "r")
4238                             (parallel [(match_operand 2 "const_int_operand" "i")])))]
4239   ""
4240   "rotqbyi\t%0,%1,(%2*<vmult>+<voff>)%%16"
4241   [(set_attr "type" "shuf")])
4243 (define_insn "_vec_extractv8hi_ze"
4244   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
4245         (zero_extend:SI (vec_select:HI (match_operand:V8HI 1 "spu_reg_operand" "r")
4246                                        (parallel [(const_int 0)]))))]
4247   ""
4248   "rotqmbyi\t%0,%1,-2"
4249   [(set_attr "type" "shuf")])
4252 ;; misc
4254 (define_expand "shufb"
4255   [(set (match_operand 0 "spu_reg_operand" "")
4256         (unspec [(match_operand 1 "spu_reg_operand" "")
4257                  (match_operand 2 "spu_reg_operand" "")
4258                  (match_operand:TI 3 "spu_reg_operand" "")] UNSPEC_SHUFB))]
4259   ""
4260   {
4261     rtx s = gen__shufb (operands[0], operands[1], operands[2], operands[3]);
4262     PUT_MODE (SET_SRC (s), GET_MODE (operands[0]));
4263     emit_insn (s);
4264     DONE;
4265   })
4267 (define_insn "_shufb"
4268   [(set (match_operand 0 "spu_reg_operand" "=r")
4269         (unspec [(match_operand 1 "spu_reg_operand" "r")
4270                  (match_operand 2 "spu_reg_operand" "r")
4271                  (match_operand:TI 3 "spu_reg_operand" "r")] UNSPEC_SHUFB))]
4272   "operands"
4273   "shufb\t%0,%1,%2,%3"
4274   [(set_attr "type" "shuf")])
4276 (define_insn "nop"
4277   [(unspec_volatile [(const_int 0)] UNSPEC_NOP)]
4278   ""
4279   "nop"
4280   [(set_attr "type" "nop")])
4282 (define_insn "nopn"
4283   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "K")] UNSPEC_NOP)]
4284   ""
4285   "nop\t%0"
4286   [(set_attr "type" "nop")])
4288 (define_insn "lnop"
4289   [(unspec_volatile [(const_int 0)] UNSPEC_LNOP)]
4290   ""
4291   "lnop"
4292   [(set_attr "type" "lnop")])
4294 ;; The operand is so we know why we generated this hbrp.
4295 ;; We clobber mem to make sure it isn't moved over any
4296 ;; loads, stores or calls while scheduling.
4297 (define_insn "iprefetch"
4298   [(unspec [(match_operand:SI 0 "const_int_operand" "n")] UNSPEC_IPREFETCH)
4299    (clobber (mem:BLK (scratch)))]
4300   ""
4301   "hbrp\t# %0"
4302   [(set_attr "type" "iprefetch")])
4304 ;; A non-volatile version so it gets scheduled
4305 (define_insn "nopn_nv"
4306   [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_NOP)]
4307   ""
4308   "nop\t%0"
4309   [(set_attr "type" "nop")])
4311 (define_insn "hbr"
4312   [(set (reg:SI 130)
4313         (unspec:SI [(match_operand:SI 0 "immediate_operand" "i,i,i")
4314                     (match_operand:SI 1 "nonmemory_operand" "r,s,i")] UNSPEC_HBR))
4315    (unspec [(const_int 0)] UNSPEC_HBR)]
4316   ""
4317   "@
4318    hbr\t%0,%1
4319    hbrr\t%0,%1
4320    hbra\t%0,%1"
4321   [(set_attr "type" "hbr")])
4323 (define_insn "sync"
4324   [(unspec_volatile [(const_int 0)] UNSPEC_SYNC)
4325    (clobber (mem:BLK (scratch)))]
4326   ""
4327   "sync"
4328   [(set_attr "type" "br")])
4330 (define_insn "syncc"
4331   [(unspec_volatile [(const_int 1)] UNSPEC_SYNC)
4332    (clobber (mem:BLK (scratch)))]
4333   ""
4334   "syncc"
4335   [(set_attr "type" "br")])
4337 (define_insn "dsync"
4338   [(unspec_volatile [(const_int 2)] UNSPEC_SYNC)
4339    (clobber (mem:BLK (scratch)))]
4340   ""
4341   "dsync"
4342   [(set_attr "type" "br")])
4346  ;; Define the subtract-one-and-jump insns so loop.c
4347  ;; knows what to generate.
4348  (define_expand "doloop_end"
4349    [(use (match_operand 0 "" ""))      ; loop pseudo
4350     (use (match_operand 1 "" ""))      ; iterations; zero if unknown
4351     (use (match_operand 2 "" ""))      ; max iterations
4352     (use (match_operand 3 "" ""))      ; loop level
4353     (use (match_operand 4 "" ""))]     ; label
4354    ""
4355    "
4357    /* Currently SMS relies on the do-loop pattern to recognize loops
4358       where (1) the control part comprises of all insns defining and/or
4359       using a certain 'count' register and (2) the loop count can be
4360       adjusted by modifying this register prior to the loop.
4361 .     ??? The possible introduction of a new block to initialize the
4362       new IV can potentially effects branch optimizations.  */
4363    if (optimize > 0 && flag_modulo_sched)
4364    {
4365      rtx s0;
4366      rtx bcomp;
4367      rtx loc_ref;
4369      /* Only use this on innermost loops.  */
4370      if (INTVAL (operands[3]) > 1)
4371        FAIL;
4372      if (GET_MODE (operands[0]) != SImode)
4373        FAIL;
4375      s0 = operands [0];
4376      emit_move_insn (s0, gen_rtx_PLUS (SImode, s0, GEN_INT (-1)));
4377      bcomp = gen_rtx_NE(SImode, s0, const0_rtx);
4378      loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands [4]);
4379      emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
4380                                   gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp,
4381                                                         loc_ref, pc_rtx)));
4383      DONE;
4384    }else
4385       FAIL;
4386  }")
4388 ;; convert between any two modes, avoiding any GCC assumptions
4389 (define_expand "spu_convert"
4390   [(set (match_operand 0 "spu_reg_operand" "")
4391         (unspec [(match_operand 1 "spu_reg_operand" "")] UNSPEC_CONVERT))]
4392   ""
4393   {
4394     rtx c = gen__spu_convert (operands[0], operands[1]);
4395     PUT_MODE (SET_SRC (c), GET_MODE (operands[0]));
4396     emit_insn (c);
4397     DONE;
4398   })
4400 (define_insn_and_split "_spu_convert"
4401   [(set (match_operand 0 "spu_reg_operand" "=r")
4402         (unspec [(match_operand 1 "spu_reg_operand" "0")] UNSPEC_CONVERT))]
4403   ""
4404   "#"
4405   "reload_completed"
4406   [(const_int 0)]
4407   {
4408     spu_split_convert (operands);
4409     DONE;
4410   }
4411   [(set_attr "type" "convert")
4412    (set_attr "length" "0")])
4416 (include "spu-builtins.md")
4418   
4419 (define_expand "smaxv4sf3"
4420   [(set (match_operand:V4SF 0 "register_operand" "=r")
4421         (smax:V4SF (match_operand:V4SF 1 "register_operand" "r")
4422                  (match_operand:V4SF 2 "register_operand" "r")))]
4423   ""
4424   "
4426   rtx mask = gen_reg_rtx (V4SImode);
4428   emit_insn (gen_cgt_v4sf (mask, operands[1], operands[2]));
4429   emit_insn (gen_selb (operands[0], operands[2], operands[1], mask));
4430   DONE;
4431 }") 
4433 (define_expand "sminv4sf3"
4434   [(set (match_operand:V4SF 0 "register_operand" "=r")
4435         (smin:V4SF (match_operand:V4SF 1 "register_operand" "r")
4436                  (match_operand:V4SF 2 "register_operand" "r")))]
4437   ""
4438   "
4440   rtx mask = gen_reg_rtx (V4SImode);
4442   emit_insn (gen_cgt_v4sf (mask, operands[1], operands[2]));
4443   emit_insn (gen_selb (operands[0], operands[1], operands[2], mask));
4444   DONE;
4445 }") 
4447 (define_expand "smaxv2df3"
4448   [(set (match_operand:V2DF 0 "register_operand" "=r")
4449         (smax:V2DF (match_operand:V2DF 1 "register_operand" "r")
4450                  (match_operand:V2DF 2 "register_operand" "r")))]
4451   ""
4452   "
4454   rtx mask = gen_reg_rtx (V2DImode);
4455   emit_insn (gen_cgt_v2df (mask, operands[1], operands[2]));
4456   emit_insn (gen_selb (operands[0], operands[2], operands[1], 
4457                        spu_gen_subreg (V4SImode, mask)));
4458   DONE;
4461 (define_expand "sminv2df3"
4462   [(set (match_operand:V2DF 0 "register_operand" "=r")
4463         (smin:V2DF (match_operand:V2DF 1 "register_operand" "r")
4464                  (match_operand:V2DF 2 "register_operand" "r")))]
4465   ""
4466   "
4468   rtx mask = gen_reg_rtx (V2DImode);
4469   emit_insn (gen_cgt_v2df (mask, operands[1], operands[2]));
4470   emit_insn (gen_selb (operands[0], operands[1], operands[2], 
4471                        spu_gen_subreg (V4SImode, mask)));
4472   DONE;
4475 (define_expand "vec_widen_umult_hi_v8hi"
4476   [(set (match_operand:V4SI 0 "register_operand"   "=r")
4477         (mult:V4SI
4478           (zero_extend:V4SI
4479             (vec_select:V4HI
4480               (match_operand:V8HI 1 "register_operand" "r")
4481               (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)])))
4482           (zero_extend:V4SI
4483             (vec_select:V4HI
4484               (match_operand:V8HI 2 "register_operand" "r")
4485               (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)])))))]
4486   ""
4487   "
4489   rtx ve = gen_reg_rtx (V4SImode);
4490   rtx vo = gen_reg_rtx (V4SImode);
4491   rtx mask = gen_reg_rtx (TImode);
4492   unsigned char arr[16] = {
4493     0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13, 
4494     0x04, 0x05, 0x06, 0x07, 0x14, 0x15, 0x16, 0x17};
4495   
4496   emit_move_insn (mask, array_to_constant (TImode, arr));
4497   emit_insn (gen_spu_mpyhhu (ve, operands[1], operands[2]));
4498   emit_insn (gen_spu_mpyu (vo, operands[1], operands[2]));
4499   emit_insn (gen_shufb (operands[0], ve, vo, mask));
4500   DONE;
4503 (define_expand "vec_widen_umult_lo_v8hi"
4504   [(set (match_operand:V4SI 0 "register_operand"   "=r")
4505         (mult:V4SI
4506           (zero_extend:V4SI
4507             (vec_select:V4HI
4508               (match_operand:V8HI 1 "register_operand" "r")
4509               (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)])))
4510           (zero_extend:V4SI
4511             (vec_select:V4HI
4512               (match_operand:V8HI 2 "register_operand" "r")
4513               (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)])))))]
4514   ""
4515   "
4517   rtx ve = gen_reg_rtx (V4SImode);
4518   rtx vo = gen_reg_rtx (V4SImode);
4519   rtx mask = gen_reg_rtx (TImode);
4520   unsigned char arr[16] = {
4521     0x08, 0x09, 0x0A, 0x0B, 0x18, 0x19, 0x1A, 0x1B, 
4522     0x0C, 0x0D, 0x0E, 0x0F, 0x1C, 0x1D, 0x1E, 0x1F};
4524   emit_move_insn (mask, array_to_constant (TImode, arr));
4525   emit_insn (gen_spu_mpyhhu (ve, operands[1], operands[2]));
4526   emit_insn (gen_spu_mpyu (vo, operands[1], operands[2]));
4527   emit_insn (gen_shufb (operands[0], ve, vo, mask));
4528   DONE;
4531 (define_expand "vec_widen_smult_hi_v8hi"
4532   [(set (match_operand:V4SI 0 "register_operand"   "=r")
4533         (mult:V4SI
4534           (sign_extend:V4SI
4535             (vec_select:V4HI
4536               (match_operand:V8HI 1 "register_operand" "r")
4537               (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)])))
4538           (sign_extend:V4SI
4539             (vec_select:V4HI
4540               (match_operand:V8HI 2 "register_operand" "r")
4541               (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)])))))]
4542   ""
4543   "
4545   rtx ve = gen_reg_rtx (V4SImode);
4546   rtx vo = gen_reg_rtx (V4SImode);
4547   rtx mask = gen_reg_rtx (TImode);
4548   unsigned char arr[16] = {
4549     0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13, 
4550     0x04, 0x05, 0x06, 0x07, 0x14, 0x15, 0x16, 0x17};
4551   
4552   emit_move_insn (mask, array_to_constant (TImode, arr));
4553   emit_insn (gen_spu_mpyhh (ve, operands[1], operands[2]));
4554   emit_insn (gen_spu_mpy (vo, operands[1], operands[2]));
4555   emit_insn (gen_shufb (operands[0], ve, vo, mask));
4556   DONE;
4559 (define_expand "vec_widen_smult_lo_v8hi"
4560   [(set (match_operand:V4SI 0 "register_operand"   "=r")
4561         (mult:V4SI
4562           (sign_extend:V4SI
4563             (vec_select:V4HI
4564               (match_operand:V8HI 1 "register_operand" "r")
4565               (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)])))
4566           (sign_extend:V4SI
4567             (vec_select:V4HI
4568               (match_operand:V8HI 2 "register_operand" "r")
4569               (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)])))))]
4570   ""
4571   "
4573   rtx ve = gen_reg_rtx (V4SImode);
4574   rtx vo = gen_reg_rtx (V4SImode);
4575   rtx mask = gen_reg_rtx (TImode);
4576   unsigned char arr[16] = {
4577     0x08, 0x09, 0x0A, 0x0B, 0x18, 0x19, 0x1A, 0x1B, 
4578     0x0C, 0x0D, 0x0E, 0x0F, 0x1C, 0x1D, 0x1E, 0x1F};
4580   emit_move_insn (mask, array_to_constant (TImode, arr));
4581   emit_insn (gen_spu_mpyhh (ve, operands[1], operands[2]));
4582   emit_insn (gen_spu_mpy (vo, operands[1], operands[2]));
4583   emit_insn (gen_shufb (operands[0], ve, vo, mask));
4584   DONE;
4587 (define_expand "vec_realign_load_<mode>"
4588   [(set (match_operand:ALL 0 "register_operand" "=r")
4589         (unspec:ALL [(match_operand:ALL 1 "register_operand" "r")
4590                      (match_operand:ALL 2 "register_operand" "r")
4591                      (match_operand:TI 3 "register_operand" "r")] UNSPEC_SPU_REALIGN_LOAD))]
4592   ""
4593   "
4595   emit_insn (gen_shufb (operands[0], operands[1], operands[2], operands[3])); 
4596   DONE;
4599 (define_expand "spu_lvsr"
4600   [(set (match_operand:V16QI 0 "register_operand" "")
4601         (unspec:V16QI [(match_operand 1 "memory_operand" "")] UNSPEC_SPU_MASK_FOR_LOAD))]
4602   ""
4603   "
4605   rtx addr;
4606   rtx offset = gen_reg_rtx (V8HImode);
4607   rtx addr_bits = gen_reg_rtx (SImode);
4608   rtx addr_bits_vec = gen_reg_rtx (V8HImode);
4609   rtx splatqi = gen_reg_rtx (TImode);
4610   rtx result = gen_reg_rtx (V8HImode);
4611   unsigned char arr[16] = {
4612     0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 
4613     0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F};
4614   unsigned char arr2[16] = {
4615     0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 
4616     0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03};
4618   emit_move_insn (offset, array_to_constant (V8HImode, arr));
4619   emit_move_insn (splatqi, array_to_constant (TImode, arr2));
4621   gcc_assert (GET_CODE (operands[1]) == MEM);
4622   addr = force_reg (Pmode, XEXP (operands[1], 0));
4623   emit_insn (gen_andsi3 (addr_bits, addr, GEN_INT (0xF))); 
4624   emit_insn (gen_shufb (addr_bits_vec, addr_bits, addr_bits, splatqi));
4626   /* offset - (addr & 0xF) 
4627      It is safe to use a single sfh, because each byte of offset is > 15 and
4628      each byte of addr is <= 15. */
4629   emit_insn (gen_subv8hi3 (result, offset, addr_bits_vec));
4631   result = simplify_gen_subreg (V16QImode, result, V8HImode, 0);
4632   emit_move_insn (operands[0], result);
4634   DONE;
4637 (define_expand "vec_unpacku_hi_v8hi"
4638   [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
4639         (zero_extend:V4SI 
4640           (vec_select:V4HI
4641             (match_operand:V8HI 1 "spu_reg_operand" "r")
4642             (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)]))))]
4643   ""
4645   rtx mask = gen_reg_rtx (TImode);
4646   unsigned char arr[16] = {
4647     0x80, 0x80, 0x00, 0x01, 0x80, 0x80, 0x02, 0x03,
4648     0x80, 0x80, 0x04, 0x05, 0x80, 0x80, 0x06, 0x07};
4650   emit_move_insn (mask, array_to_constant (TImode, arr));
4651   emit_insn (gen_shufb (operands[0], operands[1], operands[1], mask));
4653   DONE;
4656 (define_expand "vec_unpacku_lo_v8hi"
4657   [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
4658          (zero_extend:V4SI
4659           (vec_select:V4HI
4660             (match_operand:V8HI 1 "spu_reg_operand" "r")
4661             (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)]))))]
4664   rtx mask = gen_reg_rtx (TImode);
4665   unsigned char arr[16] = {
4666     0x80, 0x80, 0x08, 0x09, 0x80, 0x80, 0x0A, 0x0B,
4667     0x80, 0x80, 0x0C, 0x0D, 0x80, 0x80, 0x0E, 0x0F};
4669   emit_move_insn (mask, array_to_constant (TImode, arr));
4670   emit_insn (gen_shufb (operands[0], operands[1], operands[1], mask));
4671   
4672   DONE;
4675 (define_expand "vec_unpacks_hi_v8hi"
4676   [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
4677          (sign_extend:V4SI
4678           (vec_select:V4HI
4679             (match_operand:V8HI 1 "spu_reg_operand" "r")
4680             (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)]))))]
4681   ""
4683   rtx tmp1 = gen_reg_rtx (V8HImode);
4684   rtx tmp2 = gen_reg_rtx (V4SImode);
4685   rtx mask = gen_reg_rtx (TImode);
4686   unsigned char arr[16] = {
4687     0x80, 0x80, 0x00, 0x01, 0x80, 0x80, 0x02, 0x03,
4688     0x80, 0x80, 0x04, 0x05, 0x80, 0x80, 0x06, 0x07};
4690   emit_move_insn (mask, array_to_constant (TImode, arr));
4691   emit_insn (gen_shufb (tmp1, operands[1], operands[1], mask));
4692   emit_insn (gen_spu_xshw (tmp2, tmp1)); 
4693   emit_move_insn (operands[0], tmp2);
4695   DONE;
4698 (define_expand "vec_unpacks_lo_v8hi"
4699   [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
4700          (sign_extend:V4SI
4701           (vec_select:V4HI
4702             (match_operand:V8HI 1 "spu_reg_operand" "r")
4703             (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)]))))]
4706   rtx tmp1 = gen_reg_rtx (V8HImode);
4707   rtx tmp2 = gen_reg_rtx (V4SImode);
4708   rtx mask = gen_reg_rtx (TImode);
4709   unsigned char arr[16] = {
4710     0x80, 0x80, 0x08, 0x09, 0x80, 0x80, 0x0A, 0x0B,
4711     0x80, 0x80, 0x0C, 0x0D, 0x80, 0x80, 0x0E, 0x0F};
4713   emit_move_insn (mask, array_to_constant (TImode, arr));
4714   emit_insn (gen_shufb (tmp1, operands[1], operands[1], mask));
4715   emit_insn (gen_spu_xshw (tmp2, tmp1)); 
4716   emit_move_insn (operands[0], tmp2);
4718 DONE;
4721 (define_expand "vec_unpacku_hi_v16qi"
4722   [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
4723         (zero_extend:V8HI
4724           (vec_select:V8QI
4725             (match_operand:V16QI 1 "spu_reg_operand" "r")
4726             (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)
4727                        (const_int 4)(const_int 5)(const_int 6)(const_int 7)]))))]
4728   ""
4730   rtx mask = gen_reg_rtx (TImode);
4731   unsigned char arr[16] = {
4732     0x80, 0x00, 0x80, 0x01, 0x80, 0x02, 0x80, 0x03,
4733     0x80, 0x04, 0x80, 0x05, 0x80, 0x06, 0x80, 0x07};
4735   emit_move_insn (mask, array_to_constant (TImode, arr));
4736   emit_insn (gen_shufb (operands[0], operands[1], operands[1], mask));
4738   DONE;
4741 (define_expand "vec_unpacku_lo_v16qi"
4742   [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
4743           (zero_extend:V8HI
4744           (vec_select:V8QI
4745             (match_operand:V16QI 1 "spu_reg_operand" "r")
4746             (parallel [(const_int 8)(const_int 9)(const_int 10)(const_int 11)
4747                        (const_int 12)(const_int 13)(const_int 14)(const_int 15)]))))]
4750   rtx mask = gen_reg_rtx (TImode);
4751   unsigned char arr[16] = {
4752     0x80, 0x08, 0x80, 0x09, 0x80, 0x0A, 0x80, 0x0B,
4753     0x80, 0x0C, 0x80, 0x0D, 0x80, 0x0E, 0x80, 0x0F};
4755   emit_move_insn (mask, array_to_constant (TImode, arr));
4756   emit_insn (gen_shufb (operands[0], operands[1], operands[1], mask));
4758   DONE;
4761 (define_expand "vec_unpacks_hi_v16qi"
4762   [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
4763          (sign_extend:V8HI
4764           (vec_select:V8QI
4765             (match_operand:V16QI 1 "spu_reg_operand" "r")
4766             (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)
4767                        (const_int 4)(const_int 5)(const_int 6)(const_int 7)]))))]
4770   rtx tmp1 = gen_reg_rtx (V16QImode);
4771   rtx tmp2 = gen_reg_rtx (V8HImode);
4772   rtx mask = gen_reg_rtx (TImode);
4773   unsigned char arr[16] = {
4774     0x80, 0x00, 0x80, 0x01, 0x80, 0x02, 0x80, 0x03,
4775     0x80, 0x04, 0x80, 0x05, 0x80, 0x06, 0x80, 0x07};
4777   emit_move_insn (mask, array_to_constant (TImode, arr));
4778   emit_insn (gen_shufb (tmp1, operands[1], operands[1], mask));
4779   emit_insn (gen_spu_xsbh (tmp2, tmp1));
4780   emit_move_insn (operands[0], tmp2);
4782   DONE;
4785 (define_expand "vec_unpacks_lo_v16qi"
4786   [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
4787          (sign_extend:V8HI
4788           (vec_select:V8QI
4789             (match_operand:V16QI 1 "spu_reg_operand" "r")
4790             (parallel [(const_int 8)(const_int 9)(const_int 10)(const_int 11)
4791                        (const_int 12)(const_int 13)(const_int 14)(const_int 15)]))))]
4794   rtx tmp1 = gen_reg_rtx (V16QImode);
4795   rtx tmp2 = gen_reg_rtx (V8HImode);
4796   rtx mask = gen_reg_rtx (TImode);
4797   unsigned char arr[16] = {
4798     0x80, 0x08, 0x80, 0x09, 0x80, 0x0A, 0x80, 0x0B,
4799     0x80, 0x0C, 0x80, 0x0D, 0x80, 0x0E, 0x80, 0x0F};
4801   emit_move_insn (mask, array_to_constant (TImode, arr));
4802   emit_insn (gen_shufb (tmp1, operands[1], operands[1], mask));
4803   emit_insn (gen_spu_xsbh (tmp2, tmp1));
4804   emit_move_insn (operands[0], tmp2);
4806 DONE;
4810 (define_expand "vec_extract_evenv4si"
4811  [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
4812        (vec_concat:V4SI
4813          (vec_select:V2SI
4814            (match_operand:V4SI 1 "spu_reg_operand" "r")
4815            (parallel [(const_int 0)(const_int 2)]))
4816          (vec_select:V2SI
4817            (match_operand:V4SI 2 "spu_reg_operand" "r")
4818            (parallel [(const_int 0)(const_int 2)]))))]
4820   ""
4821   "
4823   rtx mask = gen_reg_rtx (TImode);
4824   unsigned char arr[16] = {
4825         0x00, 0x01, 0x02, 0x03,
4826         0x08, 0x09, 0x0A, 0x0B,
4827         0x10, 0x11, 0x12, 0x13,
4828         0x18, 0x19, 0x1A, 0x1B};        
4830   emit_move_insn (mask, array_to_constant (TImode, arr));
4831   emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
4832   DONE;
4836 (define_expand "vec_extract_evenv4sf"
4837  [(set (match_operand:V4SF 0 "spu_reg_operand" "=r")
4838        (vec_concat:V4SF
4839          (vec_select:V2SF
4840            (match_operand:V4SF 1 "spu_reg_operand" "r")
4841            (parallel [(const_int 0)(const_int 2)]))
4842          (vec_select:V2SF
4843            (match_operand:V4SF 2 "spu_reg_operand" "r")
4844            (parallel [(const_int 0)(const_int 2)]))))]
4846   ""
4847   "
4849   rtx mask = gen_reg_rtx (TImode);
4850   unsigned char arr[16] = {
4851         0x00, 0x01, 0x02, 0x03,
4852         0x08, 0x09, 0x0A, 0x0B,
4853         0x10, 0x11, 0x12, 0x13,
4854         0x18, 0x19, 0x1A, 0x1B};
4856   emit_move_insn (mask, array_to_constant (TImode, arr));
4857   emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
4858   DONE;
4861 (define_expand "vec_extract_evenv8hi"
4862  [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
4863        (vec_concat:V8HI
4864          (vec_select:V4HI
4865            (match_operand:V8HI 1 "spu_reg_operand" "r")
4866            (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)]))
4867          (vec_select:V4HI
4868            (match_operand:V8HI 2 "spu_reg_operand" "r")
4869            (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)]))))]
4871   ""
4872   "
4874   rtx mask = gen_reg_rtx (TImode);
4875   unsigned char arr[16] = {
4876         0x00, 0x01, 0x04, 0x05,
4877         0x08, 0x09, 0x0C, 0x0D,
4878         0x10, 0x11, 0x14, 0x15,
4879         0x18, 0x19, 0x1C, 0x1D};
4881   emit_move_insn (mask, array_to_constant (TImode, arr));
4882   emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
4883   DONE;
4886 (define_expand "vec_extract_evenv16qi"
4887  [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
4888        (vec_concat:V16QI
4889          (vec_select:V8QI
4890            (match_operand:V16QI 1 "spu_reg_operand" "r")
4891            (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)
4892                       (const_int 8)(const_int 10)(const_int 12)(const_int 14)]))
4893          (vec_select:V8QI
4894            (match_operand:V16QI 2 "spu_reg_operand" "r")
4895            (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)
4896                       (const_int 8)(const_int 10)(const_int 12)(const_int 14)]))))]
4898   ""
4899   "
4901   rtx mask = gen_reg_rtx (TImode);
4902   unsigned char arr[16] = {
4903         0x00, 0x02, 0x04, 0x06,
4904         0x08, 0x0A, 0x0C, 0x0E,
4905         0x10, 0x12, 0x14, 0x16,
4906         0x18, 0x1A, 0x1C, 0x1E};
4908   emit_move_insn (mask, array_to_constant (TImode, arr));
4909   emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
4910   DONE;
4913 (define_expand "vec_extract_oddv4si"
4914  [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
4915        (vec_concat:V4SI
4916          (vec_select:V2SI
4917            (match_operand:V4SI 1 "spu_reg_operand" "r")
4918            (parallel [(const_int 1)(const_int 3)]))
4919          (vec_select:V2SI
4920            (match_operand:V4SI 2 "spu_reg_operand" "r")
4921            (parallel [(const_int 1)(const_int 3)]))))]
4923   ""
4924   "
4926   rtx mask = gen_reg_rtx (TImode);
4927   unsigned char arr[16] = {
4928         0x04, 0x05, 0x06, 0x07,
4929         0x0C, 0x0D, 0x0E, 0x0F,
4930         0x14, 0x15, 0x16, 0x17,
4931         0x1C, 0x1D, 0x1E, 0x1F};
4933   emit_move_insn (mask, array_to_constant (TImode, arr));
4934   emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
4935   DONE;
4938 (define_expand "vec_extract_oddv4sf"
4939  [(set (match_operand:V4SF 0 "spu_reg_operand" "=r")
4940        (vec_concat:V4SF
4941          (vec_select:V2SF
4942            (match_operand:V4SF 1 "spu_reg_operand" "r")
4943            (parallel [(const_int 1)(const_int 3)]))
4944          (vec_select:V2SF
4945            (match_operand:V4SF 2 "spu_reg_operand" "r")
4946            (parallel [(const_int 1)(const_int 3)]))))]
4948   ""
4949   "
4951   rtx mask = gen_reg_rtx (TImode);
4952   unsigned char arr[16] = {
4953         0x04, 0x05, 0x06, 0x07,
4954         0x0C, 0x0D, 0x0E, 0x0F,
4955         0x14, 0x15, 0x16, 0x17,
4956         0x1C, 0x1D, 0x1E, 0x1F};
4958   emit_move_insn (mask, array_to_constant (TImode, arr));
4959   emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
4960   DONE;
4963 (define_expand "vec_extract_oddv8hi"
4964  [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
4965        (vec_concat:V8HI
4966          (vec_select:V4HI
4967            (match_operand:V8HI 1 "spu_reg_operand" "r")
4968            (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)]))
4969          (vec_select:V4HI
4970            (match_operand:V8HI 2 "spu_reg_operand" "r")
4971            (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)]))))]
4973   ""
4974   "
4976   rtx mask = gen_reg_rtx (TImode);
4977   unsigned char arr[16] = {
4978         0x02, 0x03, 0x06, 0x07,
4979         0x0A, 0x0B, 0x0E, 0x0F,
4980         0x12, 0x13, 0x16, 0x17,
4981         0x1A, 0x1B, 0x1E, 0x1F};
4983   emit_move_insn (mask, array_to_constant (TImode, arr));
4984   emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
4985   DONE;
4988 (define_expand "vec_extract_oddv16qi"
4989  [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
4990        (vec_concat:V16QI
4991          (vec_select:V8QI
4992            (match_operand:V16QI 1 "spu_reg_operand" "r")
4993            (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)
4994                       (const_int 9)(const_int 11)(const_int 13)(const_int 15)]))
4995          (vec_select:V8QI
4996            (match_operand:V16QI 2 "spu_reg_operand" "r")
4997            (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)
4998                       (const_int 9)(const_int 11)(const_int 13)(const_int 15)]))))]
5000   ""
5001   "
5003   rtx mask = gen_reg_rtx (TImode);
5004   unsigned char arr[16] = {
5005         0x01, 0x03, 0x05, 0x07,
5006         0x09, 0x0B, 0x0D, 0x0F,
5007         0x11, 0x13, 0x15, 0x17,
5008         0x19, 0x1B, 0x1D, 0x1F};
5010   emit_move_insn (mask, array_to_constant (TImode, arr));
5011   emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5012   DONE;
5015 (define_expand "vec_interleave_highv4sf"
5016  [(set (match_operand:V4SF 0 "spu_reg_operand" "=r")
5017        (vec_select:V4SF
5018          (vec_concat:V4SF
5019            (vec_select:V2SF
5020              (match_operand:V4SF 1 "spu_reg_operand" "r")
5021              (parallel [(const_int 0)(const_int 1)]))
5022            (vec_select:V2SF
5023              (match_operand:V4SF 2 "spu_reg_operand" "r")
5024              (parallel [(const_int 0)(const_int 1)])))
5025          (parallel [(const_int 0)(const_int 2)(const_int 1)(const_int 3)])))]
5027   ""
5028   "
5030   rtx mask = gen_reg_rtx (TImode);
5031   unsigned char arr[16] = {
5032         0x00, 0x01, 0x02, 0x03,
5033         0x10, 0x11, 0x12, 0x13,
5034         0x04, 0x05, 0x06, 0x07,
5035         0x14, 0x15, 0x16, 0x17};
5037   emit_move_insn (mask, array_to_constant (TImode, arr));
5038   emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5039   DONE;
5042 (define_expand "vec_interleave_lowv4sf"
5043  [(set (match_operand:V4SF 0 "spu_reg_operand" "=r")
5044        (vec_select:V4SF
5045          (vec_concat:V4SF
5046            (vec_select:V2SF
5047              (match_operand:V4SF 1 "spu_reg_operand" "r")
5048              (parallel [(const_int 2)(const_int 3)]))
5049            (vec_select:V2SF
5050              (match_operand:V4SF 2 "spu_reg_operand" "r")
5051              (parallel [(const_int 2)(const_int 3)])))
5052          (parallel [(const_int 0)(const_int 2)(const_int 1)(const_int 3)])))]
5054   ""
5055   "
5057   rtx mask = gen_reg_rtx (TImode);
5058   unsigned char arr[16] = {
5059         0x08, 0x09, 0x0A, 0x0B,
5060         0x18, 0x19, 0x1A, 0x1B,
5061         0x0C, 0x0D, 0x0E, 0x0F,
5062         0x1C, 0x1D, 0x1E, 0x1F};
5064   emit_move_insn (mask, array_to_constant (TImode, arr));
5065   emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5066   DONE;
5069 (define_expand "vec_interleave_highv4si"
5070  [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
5071        (vec_select:V4SI
5072          (vec_concat:V4SI
5073            (vec_select:V2SI
5074              (match_operand:V4SI 1 "spu_reg_operand" "r")
5075              (parallel [(const_int 0)(const_int 1)]))
5076            (vec_select:V2SI
5077              (match_operand:V4SI 2 "spu_reg_operand" "r")
5078              (parallel [(const_int 0)(const_int 1)])))
5079          (parallel [(const_int 0)(const_int 2)(const_int 1)(const_int 3)])))]
5081   ""
5082   "
5084   rtx mask = gen_reg_rtx (TImode);
5085   unsigned char arr[16] = {
5086         0x00, 0x01, 0x02, 0x03,
5087         0x10, 0x11, 0x12, 0x13,
5088         0x04, 0x05, 0x06, 0x07,
5089         0x14, 0x15, 0x16, 0x17};
5091   emit_move_insn (mask, array_to_constant (TImode, arr));
5092   emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5093   DONE;
5096 (define_expand "vec_interleave_lowv4si"
5097  [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
5098        (vec_select:V4SI
5099          (vec_concat:V4SI
5100            (vec_select:V2SI
5101              (match_operand:V4SI 1 "spu_reg_operand" "r")
5102              (parallel [(const_int 2)(const_int 3)]))
5103            (vec_select:V2SI
5104              (match_operand:V4SI 2 "spu_reg_operand" "r")
5105              (parallel [(const_int 2)(const_int 3)])))
5106          (parallel [(const_int 0)(const_int 2)(const_int 1)(const_int 3)])))]
5108   ""
5109   "
5111   rtx mask = gen_reg_rtx (TImode);
5112   unsigned char arr[16] = {
5113         0x08, 0x09, 0x0A, 0x0B,
5114         0x18, 0x19, 0x1A, 0x1B,
5115         0x0C, 0x0D, 0x0E, 0x0F,
5116         0x1C, 0x1D, 0x1E, 0x1F};
5118   emit_move_insn (mask, array_to_constant (TImode, arr));
5119   emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5120   DONE;
5123 (define_expand "vec_interleave_highv8hi"
5124  [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
5125        (vec_select:V8HI
5126          (vec_concat:V8HI
5127            (vec_select:V4HI
5128              (match_operand:V8HI 1 "spu_reg_operand" "r")
5129              (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)]))
5130            (vec_select:V4HI
5131              (match_operand:V8HI 2 "spu_reg_operand" "r")
5132              (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)])))
5133          (parallel [(const_int 0)(const_int 4)(const_int 1)(const_int 5)
5134                     (const_int 2)(const_int 6)(const_int 3)(const_int 7)])))]
5136   ""
5137   "
5139   rtx mask = gen_reg_rtx (TImode);
5140   unsigned char arr[16] = {
5141         0x00, 0x01, 0x10, 0x11,
5142         0x02, 0x03, 0x12, 0x13,
5143         0x04, 0x05, 0x14, 0x15,
5144         0x06, 0x07, 0x16, 0x17};
5146   emit_move_insn (mask, array_to_constant (TImode, arr));
5147   emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5148   DONE;
5149  }")
5151 (define_expand "vec_interleave_lowv8hi"
5152  [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
5153        (vec_select:V8HI
5154          (vec_concat:V8HI
5155            (vec_select:V4HI
5156              (match_operand:V8HI 1 "spu_reg_operand" "r")
5157              (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)]))
5158            (vec_select:V4HI
5159              (match_operand:V8HI 2 "spu_reg_operand" "r")
5160              (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)])))
5161          (parallel [(const_int 0)(const_int 4)(const_int 1)(const_int 5)
5162                     (const_int 2)(const_int 6)(const_int 3)(const_int 7)])))]
5164   ""
5165   "
5167   rtx mask = gen_reg_rtx (TImode);
5168   unsigned char arr[16] = {
5169         0x08, 0x09, 0x18, 0x19,
5170         0x0A, 0x0B, 0x1A, 0x1B,
5171         0x0C, 0x0D, 0x1C, 0x1D,
5172         0x0E, 0x0F, 0x1E, 0x1F};
5174   emit_move_insn (mask, array_to_constant (TImode, arr));
5175   emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5176   DONE;
5179 (define_expand "vec_interleave_highv16qi"
5180  [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
5181        (vec_select:V16QI
5182          (vec_concat:V16QI
5183            (vec_select:V8QI
5184              (match_operand:V16QI 1 "spu_reg_operand" "r")
5185              (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)
5186                         (const_int 4)(const_int 5)(const_int 6)(const_int 7)]))
5187            (vec_select:V8QI
5188              (match_operand:V16QI 2 "spu_reg_operand" "r")
5189              (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)
5190                         (const_int 4)(const_int 5)(const_int 6)(const_int 7)])))
5191          (parallel [(const_int 0)(const_int 8)(const_int 1)(const_int 9)
5192                     (const_int 2)(const_int 10)(const_int 3)(const_int 11)
5193                     (const_int 4)(const_int 12)(const_int 5)(const_int 13)
5194                     (const_int 6)(const_int 14)(const_int 7)(const_int 15)])))]
5196   ""
5197   "
5199   rtx mask = gen_reg_rtx (TImode);
5200   unsigned char arr[16] = {
5201         0x00, 0x10, 0x01, 0x11,
5202         0x02, 0x12, 0x03, 0x13,
5203         0x04, 0x14, 0x05, 0x15,
5204         0x06, 0x16, 0x07, 0x17};
5206   emit_move_insn (mask, array_to_constant (TImode, arr));
5207   emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5208   DONE;
5211 (define_expand "vec_interleave_lowv16qi"
5212  [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
5213        (vec_select:V16QI
5214          (vec_concat:V16QI
5215            (vec_select:V8QI
5216              (match_operand:V16QI 1 "spu_reg_operand" "r")
5217              (parallel [(const_int 8)(const_int 9)(const_int 10)(const_int 11)
5218                         (const_int 12)(const_int 13)(const_int 14)(const_int 15)]))
5219            (vec_select:V8QI
5220              (match_operand:V16QI 2 "spu_reg_operand" "r")
5221              (parallel [(const_int 8)(const_int 9)(const_int 10)(const_int 11)
5222                         (const_int 12)(const_int 13)(const_int 14)(const_int 15)])))
5223          (parallel [(const_int 0)(const_int 8)(const_int 1)(const_int 9)
5224                     (const_int 2)(const_int 10)(const_int 3)(const_int 11)
5225                     (const_int 4)(const_int 12)(const_int 5)(const_int 13)
5226                     (const_int 6)(const_int 14)(const_int 7)(const_int 15)])))]
5228   ""
5229   "
5231   rtx mask = gen_reg_rtx (TImode);
5232   unsigned char arr[16] = {
5233          0x08, 0x18, 0x09, 0x19,
5234          0x0A, 0x1A, 0x0B, 0x1B,
5235          0x0C, 0x1C, 0x0D, 0x1D,
5236          0x0E, 0x1E, 0x0F, 0x1F};
5238   emit_move_insn (mask, array_to_constant (TImode, arr));
5239   emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5240   DONE;
5243 (define_expand "vec_pack_trunc_v8hi"
5244   [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
5245         (vec_concat:V16QI
5246           (truncate:V8QI (match_operand:V8HI 1 "spu_reg_operand" "r"))
5247           (truncate:V8QI (match_operand:V8HI 2 "spu_reg_operand" "r"))))]
5248   ""
5249   "
5251   rtx mask = gen_reg_rtx (TImode);
5252   unsigned char arr[16] = {
5253     0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0D, 0x0F,
5254     0x11, 0x13, 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F};
5256   emit_move_insn (mask, array_to_constant (TImode, arr));
5257   emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5259   DONE;
5262 (define_expand "vec_pack_trunc_v4si"
5263   [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
5264         (vec_concat:V8HI
5265           (truncate:V4HI (match_operand:V4SI 1 "spu_reg_operand" "r"))
5266           (truncate:V4HI (match_operand:V4SI 2 "spu_reg_operand" "r"))))]
5267   ""
5268   "
5270   rtx mask = gen_reg_rtx (TImode);
5271   unsigned char arr[16] = {
5272     0x02, 0x03, 0x06, 0x07, 0x0A, 0x0B, 0x0E, 0x0F,
5273     0x12, 0x13, 0x16, 0x17, 0x1A, 0x1B, 0x1E, 0x1F};
5275   emit_move_insn (mask, array_to_constant (TImode, arr));
5276   emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5278   DONE;
5281 (define_insn "stack_protect_set"
5282   [(set (match_operand:SI 0 "memory_operand" "=m")
5283         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
5284    (set (match_scratch:SI 2 "=&r") (const_int 0))]
5285   ""
5286   "lq%p1\t%2,%1\;stq%p0\t%2,%0\;xor\t%2,%2,%2"
5287   [(set_attr "length" "12")
5288    (set_attr "type" "multi1")]
5291 (define_expand "stack_protect_test"
5292   [(match_operand 0 "memory_operand" "")
5293    (match_operand 1 "memory_operand" "")
5294    (match_operand 2 "" "")]
5295   ""
5297   rtx compare_result;
5298   rtx bcomp, loc_ref;
5300   compare_result = gen_reg_rtx (SImode);
5302   emit_insn (gen_stack_protect_test_si (compare_result,
5303                                         operands[0],
5304                                         operands[1]));
5306   bcomp = gen_rtx_NE (SImode, compare_result, const0_rtx);
5308   loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[2]);
5310   emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
5311                                    gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp,
5312                                                          loc_ref, pc_rtx)));
5314   DONE;
5317 (define_insn "stack_protect_test_si"
5318   [(set (match_operand:SI 0 "spu_reg_operand" "=&r")
5319         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
5320                     (match_operand:SI 2 "memory_operand" "m")]
5321                    UNSPEC_SP_TEST))
5322    (set (match_scratch:SI 3 "=&r") (const_int 0))]
5323   ""
5324   "lq%p1\t%0,%1\;lq%p2\t%3,%2\;ceq\t%0,%0,%3\;xor\t%3,%3,%3"
5325   [(set_attr "length" "16")
5326    (set_attr "type" "multi1")]