* config/spu/spu.c (spu_init_libfuncs): Install __clrsbdi2.
[official-gcc.git] / gcc / config / spu / spu.md
blob426437ac873a23125e46b160a357b70913553992
1 ;; Copyright (C) 2006, 2007, 2008, 2009, 2010 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 "nonimmediate_operand" "")
273         (match_operand:ALL 1 "general_operand" ""))]
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_fmasf4 (operands[0],
752                            operands[2], operands[4], operands[3]));
753     DONE;
754   })
756 (define_expand "floattisf2"
757   [(set (match_operand:SF 0 "register_operand" "")
758         (float:SF (match_operand:TI 1 "register_operand" "")))]
759   ""
760   {
761     rtx c0 = gen_reg_rtx (SImode);
762     rtx r0 = gen_reg_rtx (TImode);
763     rtx r1 = gen_reg_rtx (SFmode);
764     rtx r2 = gen_reg_rtx (SImode);
765     rtx setneg = gen_reg_rtx (SImode);
766     rtx isneg = gen_reg_rtx (SImode);
767     rtx neg = gen_reg_rtx (TImode);
768     rtx mask = gen_reg_rtx (TImode);
770     emit_move_insn (c0, GEN_INT (-0x80000000ll));
772     emit_insn (gen_negti2 (neg, operands[1]));
773     emit_insn (gen_cgt_ti_m1 (isneg, operands[1]));
774     emit_insn (gen_extend_compare (mask, isneg));
775     emit_insn (gen_selb (r0, neg, operands[1], mask));
776     emit_insn (gen_andc_si (setneg, c0, isneg));
778     emit_insn (gen_floatunstisf2 (r1, r0));
780     emit_insn (gen_iorsi3 (r2, gen_rtx_SUBREG (SImode, r1, 0), setneg));
781     emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, r2, 0));
782     DONE;
783   })
785 (define_insn_and_split "floatunstisf2"
786   [(set (match_operand:SF 0 "register_operand" "=r")
787         (unsigned_float:SF (match_operand:TI 1 "register_operand" "r")))
788    (clobber (match_scratch:SF 2 "=r"))
789    (clobber (match_scratch:SF 3 "=r"))
790    (clobber (match_scratch:SF 4 "=r"))]
791   ""
792   "#"
793   "reload_completed"
794   [(set (match_dup:SF 0)
795         (unsigned_float:SF (match_dup:TI 1)))]
796   {
797     rtx op1_v4si = gen_rtx_REG (V4SImode, REGNO (operands[1]));
798     rtx op2_v4sf = gen_rtx_REG (V4SFmode, REGNO (operands[2]));
799     rtx op2_ti = gen_rtx_REG (TImode, REGNO (operands[2]));
800     rtx op3_ti = gen_rtx_REG (TImode, REGNO (operands[3]));
802     REAL_VALUE_TYPE scale;
803     real_2expN (&scale, 32, SFmode);
805     emit_insn (gen_floatunsv4siv4sf2 (op2_v4sf, op1_v4si));
806     emit_insn (gen_shlqby_ti (op3_ti, op2_ti, GEN_INT (4)));
808     emit_move_insn (operands[4],
809                     CONST_DOUBLE_FROM_REAL_VALUE (scale, SFmode));
810     emit_insn (gen_fmasf4 (operands[2],
811                            operands[2], operands[4], operands[3]));
813     emit_insn (gen_shlqby_ti (op3_ti, op3_ti, GEN_INT (4)));
814     emit_insn (gen_fmasf4 (operands[2],
815                            operands[2], operands[4], operands[3]));
817     emit_insn (gen_shlqby_ti (op3_ti, op3_ti, GEN_INT (4)));
818     emit_insn (gen_fmasf4 (operands[0],
819                            operands[2], operands[4], operands[3]));
820     DONE;
821   })
823 ;; Do (double)(operands[1]+0x80000000u)-(double)0x80000000
824 (define_expand "floatsidf2"
825   [(set (match_operand:DF 0 "register_operand" "")
826         (float:DF (match_operand:SI 1 "register_operand" "")))]
827   ""
828   {
829     rtx c0 = gen_reg_rtx (SImode);
830     rtx c1 = gen_reg_rtx (DFmode);
831     rtx r0 = gen_reg_rtx (SImode);
832     rtx r1 = gen_reg_rtx (DFmode);
834     emit_move_insn (c0, GEN_INT (-0x80000000ll));
835     emit_move_insn (c1, spu_float_const ("2147483648", DFmode));
836     emit_insn (gen_xorsi3 (r0, operands[1], c0));
837     emit_insn (gen_floatunssidf2 (r1, r0));
838     emit_insn (gen_subdf3 (operands[0], r1, c1));
839     DONE;
840   })
842 (define_expand "floatunssidf2"
843   [(set (match_operand:DF 0 "register_operand"  "=r")
844         (unsigned_float:DF (match_operand:SI 1 "register_operand"   "r")))]
845   ""
846   "{
847     rtx value, insns;
848     rtx c0 = spu_const_from_ints (V16QImode, 0x02031011, 0x12138080, 
849                                              0x06071415, 0x16178080);
850     rtx r0 = gen_reg_rtx (V16QImode);
852     if (optimize_size)
853     {
854        start_sequence ();
855        value =
856          emit_library_call_value (convert_optab_libfunc (ufloat_optab,
857                                                          DFmode, SImode),
858                    NULL_RTX, LCT_NORMAL, DFmode, 1, operands[1], SImode);
859        insns = get_insns ();
860        end_sequence ();
861        emit_libcall_block (insns, operands[0], value,
862                            gen_rtx_UNSIGNED_FLOAT (DFmode, operands[1]));
863      }
864      else
865      {
866       emit_move_insn (r0, c0);
867       emit_insn (gen_floatunssidf2_internal (operands[0], operands[1], r0));
868      }
869     DONE;
870   }")
872 (define_insn_and_split "floatunssidf2_internal"
873   [(set (match_operand:DF 0 "register_operand"  "=r")
874         (unsigned_float:DF (match_operand:SI 1 "register_operand"   "r")))
875    (use (match_operand:V16QI 2 "register_operand" "r"))
876    (clobber (match_scratch:V4SI 3 "=&r"))
877    (clobber (match_scratch:V4SI 4 "=&r"))
878    (clobber (match_scratch:V4SI 5 "=&r"))
879    (clobber (match_scratch:V4SI 6 "=&r"))]
880   ""
881   "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"
882   "reload_completed"
883   [(set (match_dup:DF 0)
884         (unsigned_float:DF (match_dup:SI 1)))]
885  "{
886     rtx *ops = operands;
887     rtx op1_v4si = gen_rtx_REG(V4SImode, REGNO(ops[1]));
888     rtx op0_ti = gen_rtx_REG (TImode, REGNO (ops[0]));
889     rtx op2_ti = gen_rtx_REG (TImode, REGNO (ops[2]));
890     rtx op6_ti = gen_rtx_REG (TImode, REGNO (ops[6]));
891     emit_insn (gen_clzv4si2 (ops[3],op1_v4si));
892     emit_move_insn (ops[6], spu_const (V4SImode, 1023+31));
893     emit_insn (gen_vashlv4si3 (ops[4],op1_v4si,ops[3]));
894     emit_insn (gen_ceq_v4si (ops[5],ops[3],spu_const (V4SImode, 32)));
895     emit_insn (gen_subv4si3 (ops[6],ops[6],ops[3]));
896     emit_insn (gen_addv4si3 (ops[4],ops[4],ops[4]));
897     emit_insn (gen_andc_v4si  (ops[6],ops[6],ops[5]));
898     emit_insn (gen_shufb (ops[6],ops[6],ops[4],op2_ti));
899     emit_insn (gen_shlqbi_ti (op0_ti,op6_ti,GEN_INT(4)));
900     DONE;
901   }"
902  [(set_attr "length" "32")])
904 (define_expand "floatdidf2"
905   [(set (match_operand:DF 0 "register_operand" "")
906         (float:DF (match_operand:DI 1 "register_operand" "")))]
907   ""
908   {
909     rtx c0 = gen_reg_rtx (DImode);
910     rtx r0 = gen_reg_rtx (DImode);
911     rtx r1 = gen_reg_rtx (DFmode);
912     rtx r2 = gen_reg_rtx (DImode);
913     rtx setneg = gen_reg_rtx (DImode);
914     rtx isneg = gen_reg_rtx (SImode);
915     rtx neg = gen_reg_rtx (DImode);
916     rtx mask = gen_reg_rtx (DImode);
918     emit_move_insn (c0, GEN_INT (0x8000000000000000ull));
920     emit_insn (gen_negdi2 (neg, operands[1]));
921     emit_insn (gen_cgt_di_m1 (isneg, operands[1]));
922     emit_insn (gen_extend_compare (mask, isneg));
923     emit_insn (gen_selb (r0, neg, operands[1], mask));
924     emit_insn (gen_andc_di (setneg, c0, mask));
926     emit_insn (gen_floatunsdidf2 (r1, r0));
928     emit_insn (gen_iordi3 (r2, gen_rtx_SUBREG (DImode, r1, 0), setneg));
929     emit_move_insn (operands[0], gen_rtx_SUBREG (DFmode, r2, 0));
930     DONE;
931   })
933 (define_expand "floatunsdidf2"
934   [(set (match_operand:DF 0 "register_operand"  "=r")
935         (unsigned_float:DF (match_operand:DI 1 "register_operand"   "r")))]
936   ""
937   "{
938     rtx value, insns;
939     rtx c0 = spu_const_from_ints (V16QImode, 0x02031011, 0x12138080, 
940                                              0x06071415, 0x16178080);
941     rtx c1 = spu_const_from_ints (V4SImode, 1023+63, 1023+31, 0, 0);
942     rtx r0 = gen_reg_rtx (V16QImode);
943     rtx r1 = gen_reg_rtx (V4SImode);
945     if (optimize_size)
946     {      
947       start_sequence ();
948       value =
949          emit_library_call_value (convert_optab_libfunc (ufloat_optab,
950                                                          DFmode, DImode),
951                    NULL_RTX, LCT_NORMAL, DFmode, 1, operands[1], DImode);
952       insns = get_insns ();
953       end_sequence ();
954       emit_libcall_block (insns, operands[0], value,
955                           gen_rtx_UNSIGNED_FLOAT (DFmode, operands[1]));
956     }
957     else
958     {
959       emit_move_insn (r1, c1);
960       emit_move_insn (r0, c0);
961       emit_insn (gen_floatunsdidf2_internal (operands[0], operands[1], r0, r1));
962     }
963     DONE;
964   }")
966 (define_insn_and_split "floatunsdidf2_internal"
967   [(set (match_operand:DF 0 "register_operand"  "=r")
968         (unsigned_float:DF (match_operand:DI 1 "register_operand"   "r")))
969    (use (match_operand:V16QI 2 "register_operand" "r"))
970    (use (match_operand:V4SI 3 "register_operand" "r"))
971    (clobber (match_scratch:V4SI 4 "=&r"))
972    (clobber (match_scratch:V4SI 5 "=&r"))
973    (clobber (match_scratch:V4SI 6 "=&r"))]
974   ""
975   "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"
976   "reload_completed"
977   [(set (match_operand:DF 0 "register_operand"  "=r")
978         (unsigned_float:DF (match_operand:DI 1 "register_operand"   "r")))]
979   "{
980     rtx *ops = operands;
981     rtx op1_v4si = gen_rtx_REG (V4SImode, REGNO(ops[1]));
982     rtx op2_ti = gen_rtx_REG (TImode, REGNO(ops[2]));
983     rtx op4_ti = gen_rtx_REG (TImode, REGNO(ops[4]));
984     rtx op5_ti = gen_rtx_REG (TImode, REGNO(ops[5]));
985     rtx op4_df = gen_rtx_REG (DFmode, REGNO(ops[4]));
986     rtx op5_df = gen_rtx_REG (DFmode, REGNO(ops[5]));
987     emit_insn (gen_clzv4si2 (ops[4],op1_v4si));
988     emit_insn (gen_vashlv4si3 (ops[5],op1_v4si,ops[4]));
989     emit_insn (gen_ceq_v4si (ops[6],ops[4],spu_const (V4SImode, 32)));
990     emit_insn (gen_subv4si3 (ops[4],ops[3],ops[4]));
991     emit_insn (gen_addv4si3 (ops[5],ops[5],ops[5]));
992     emit_insn (gen_andc_v4si (ops[4],ops[4],ops[6]));
993     emit_insn (gen_shufb (ops[4],ops[4],ops[5],op2_ti));
994     emit_insn (gen_shlqbi_ti (op4_ti,op4_ti,GEN_INT(4)));
995     emit_insn (gen_shlqby_ti (op5_ti,op4_ti,GEN_INT(8)));
996     emit_insn (gen_adddf3 (ops[0],op4_df,op5_df));
997     DONE;
998   }"
999   [(set_attr "length" "40")])
1002 ;; add
1004 (define_expand "addv16qi3"
1005   [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
1006         (plus:V16QI (match_operand:V16QI 1 "spu_reg_operand" "r")
1007                     (match_operand:V16QI 2 "spu_reg_operand" "r")))]
1008   ""
1009   "{
1010     rtx res_short = simplify_gen_subreg (V8HImode, operands[0], V16QImode, 0);
1011     rtx lhs_short = simplify_gen_subreg (V8HImode, operands[1], V16QImode, 0);
1012     rtx rhs_short = simplify_gen_subreg (V8HImode, operands[2], V16QImode, 0);
1013     rtx rhs_and = gen_reg_rtx (V8HImode);
1014     rtx hi_char = gen_reg_rtx (V8HImode);
1015     rtx lo_char = gen_reg_rtx (V8HImode);
1016     rtx mask = gen_reg_rtx (V8HImode);
1018     emit_move_insn (mask, spu_const (V8HImode, 0x00ff));
1019     emit_insn (gen_andv8hi3 (rhs_and, rhs_short, spu_const (V8HImode, 0xff00)));
1020     emit_insn (gen_addv8hi3 (hi_char, lhs_short, rhs_and));
1021     emit_insn (gen_addv8hi3 (lo_char, lhs_short, rhs_short));
1022     emit_insn (gen_selb (res_short, hi_char, lo_char, mask));
1023     DONE;
1024    }")
1026 (define_insn "add<mode>3"
1027   [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
1028         (plus:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
1029                    (match_operand:VHSI 2 "spu_arith_operand" "r,B")))]
1030   ""
1031   "@
1032   a<bh>\t%0,%1,%2
1033   a<bh>i\t%0,%1,%2")
1035 (define_expand "add<mode>3"
1036   [(set (match_dup:VDI 3) 
1037         (unspec:VDI [(match_operand:VDI 1 "spu_reg_operand" "")
1038                      (match_operand:VDI 2 "spu_reg_operand" "")] UNSPEC_CG))
1039    (set (match_dup:VDI 5)
1040         (unspec:VDI [(match_dup 3)
1041                      (match_dup 3)
1042                      (match_dup:TI 4)] UNSPEC_SHUFB))
1043    (set (match_operand:VDI 0 "spu_reg_operand" "") 
1044         (unspec:VDI [(match_dup 1)
1045                      (match_dup 2)
1046                      (match_dup 5)] UNSPEC_ADDX))]
1047   ""
1048   {
1049     unsigned char pat[16] = {
1050       0x04, 0x05, 0x06, 0x07,
1051       0x80, 0x80, 0x80, 0x80,
1052       0x0c, 0x0d, 0x0e, 0x0f,
1053       0x80, 0x80, 0x80, 0x80
1054     };
1055     operands[3] = gen_reg_rtx (<MODE>mode);
1056     operands[4] = gen_reg_rtx (TImode);
1057     operands[5] = gen_reg_rtx (<MODE>mode);
1058     emit_move_insn (operands[4], array_to_constant (TImode, pat));
1059   })
1061 (define_insn "cg_<mode>"
1062   [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
1063         (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
1064                       (match_operand 2 "spu_reg_operand" "r")] UNSPEC_CG))]
1065   "operands"
1066   "cg\t%0,%1,%2")
1068 (define_insn "cgx_<mode>"
1069   [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
1070         (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
1071                       (match_operand 2 "spu_reg_operand" "r")
1072                       (match_operand 3 "spu_reg_operand" "0")] UNSPEC_CGX))]
1073   "operands"
1074   "cgx\t%0,%1,%2")
1076 (define_insn "addx_<mode>"
1077   [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
1078         (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
1079                       (match_operand 2 "spu_reg_operand" "r")
1080                       (match_operand 3 "spu_reg_operand" "0")] UNSPEC_ADDX))]
1081   "operands"
1082   "addx\t%0,%1,%2")
1085 ;; This is not the most efficient implementation of addti3.
1086 ;; We include this here because 1) the compiler needs it to be
1087 ;; defined as the word size is 128-bit and 2) sometimes gcc
1088 ;; substitutes an add for a constant left-shift. 2) is unlikely
1089 ;; because we also give addti3 a high cost. In case gcc does
1090 ;; generate TImode add, here is the code to do it.
1091 ;; operand 2 is a nonmemory because the compiler requires it.
1092 (define_insn "addti3"
1093   [(set (match_operand:TI 0 "spu_reg_operand" "=&r")
1094         (plus:TI (match_operand:TI 1 "spu_reg_operand" "r")
1095                  (match_operand:TI 2 "spu_nonmem_operand" "r")))
1096    (clobber (match_scratch:TI 3 "=&r"))]
1097   ""
1098   "cg\t%3,%1,%2\n\\
1099    shlqbyi\t%3,%3,4\n\\
1100    cgx\t%3,%1,%2\n\\
1101    shlqbyi\t%3,%3,4\n\\
1102    cgx\t%3,%1,%2\n\\
1103    shlqbyi\t%0,%3,4\n\\
1104    addx\t%0,%1,%2"
1105   [(set_attr "type" "multi0")
1106    (set_attr "length" "28")])
1108 (define_insn "add<mode>3"
1109   [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1110         (plus:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
1111                   (match_operand:VSF 2 "spu_reg_operand" "r")))]
1112   ""
1113   "fa\t%0,%1,%2"
1114   [(set_attr "type" "fp6")])
1116 (define_insn "add<mode>3"
1117   [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
1118         (plus:VDF (match_operand:VDF 1 "spu_reg_operand" "r")
1119                   (match_operand:VDF 2 "spu_reg_operand" "r")))]
1120   ""
1121   "dfa\t%0,%1,%2"
1122   [(set_attr "type" "fpd")])
1125 ;; sub
1127 (define_expand "subv16qi3"
1128   [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
1129         (minus:V16QI (match_operand:V16QI 1 "spu_reg_operand" "r")
1130                      (match_operand:V16QI 2 "spu_reg_operand" "r")))]
1131   ""
1132   "{
1133     rtx res_short = simplify_gen_subreg (V8HImode, operands[0], V16QImode, 0);
1134     rtx lhs_short = simplify_gen_subreg (V8HImode, operands[1], V16QImode, 0);
1135     rtx rhs_short = simplify_gen_subreg (V8HImode, operands[2], V16QImode, 0);
1136     rtx rhs_and = gen_reg_rtx (V8HImode);
1137     rtx hi_char = gen_reg_rtx (V8HImode);
1138     rtx lo_char = gen_reg_rtx (V8HImode);
1139     rtx mask = gen_reg_rtx (V8HImode);
1141     emit_move_insn (mask, spu_const (V8HImode, 0x00ff));
1142     emit_insn (gen_andv8hi3 (rhs_and, rhs_short, spu_const (V8HImode, 0xff00)));
1143     emit_insn (gen_subv8hi3 (hi_char, lhs_short, rhs_and));
1144     emit_insn (gen_subv8hi3 (lo_char, lhs_short, rhs_short));
1145     emit_insn (gen_selb (res_short, hi_char, lo_char, mask));
1146     DONE;
1147    }")
1149 (define_insn "sub<mode>3"
1150   [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
1151         (minus:VHSI (match_operand:VHSI 1 "spu_arith_operand" "r,B")
1152                     (match_operand:VHSI 2 "spu_reg_operand" "r,r")))]
1153   ""
1154   "@
1155   sf<bh>\t%0,%2,%1
1156   sf<bh>i\t%0,%2,%1")
1158 (define_expand "sub<mode>3"
1159   [(set (match_dup:VDI 3) 
1160         (unspec:VDI [(match_operand:VDI 1 "spu_reg_operand" "")
1161                      (match_operand:VDI 2 "spu_reg_operand" "")] UNSPEC_BG))
1162    (set (match_dup:VDI 5)
1163         (unspec:VDI [(match_dup 3)
1164                      (match_dup 3)
1165                      (match_dup:TI 4)] UNSPEC_SHUFB))
1166    (set (match_operand:VDI 0 "spu_reg_operand" "") 
1167         (unspec:VDI [(match_dup 1)
1168                      (match_dup 2)
1169                      (match_dup 5)] UNSPEC_SFX))]
1170   ""
1171   {
1172     unsigned char pat[16] = {
1173       0x04, 0x05, 0x06, 0x07,
1174       0xc0, 0xc0, 0xc0, 0xc0,
1175       0x0c, 0x0d, 0x0e, 0x0f,
1176       0xc0, 0xc0, 0xc0, 0xc0
1177     };
1178     operands[3] = gen_reg_rtx (<MODE>mode);
1179     operands[4] = gen_reg_rtx (TImode);
1180     operands[5] = gen_reg_rtx (<MODE>mode);
1181     emit_move_insn (operands[4], array_to_constant (TImode, pat));
1182   })
1184 (define_insn "bg_<mode>"
1185   [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
1186         (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
1187                       (match_operand 2 "spu_reg_operand" "r")] UNSPEC_BG))]
1188   "operands"
1189   "bg\t%0,%2,%1")
1191 (define_insn "bgx_<mode>"
1192   [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
1193         (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
1194                       (match_operand 2 "spu_reg_operand" "r")
1195                       (match_operand 3 "spu_reg_operand" "0")] UNSPEC_BGX))]
1196   "operands"
1197   "bgx\t%0,%2,%1")
1199 (define_insn "sfx_<mode>"
1200   [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
1201         (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
1202                       (match_operand 2 "spu_reg_operand" "r")
1203                       (match_operand 3 "spu_reg_operand" "0")] UNSPEC_SFX))]
1204   "operands"
1205   "sfx\t%0,%2,%1")
1207 (define_insn "subti3"
1208   [(set (match_operand:TI 0 "spu_reg_operand" "=r")
1209         (minus:TI (match_operand:TI 1 "spu_reg_operand" "r")
1210                   (match_operand:TI 2 "spu_reg_operand" "r")))
1211    (clobber (match_scratch:TI 3 "=&r"))
1212    (clobber (match_scratch:TI 4 "=&r"))
1213    (clobber (match_scratch:TI 5 "=&r"))
1214    (clobber (match_scratch:TI 6 "=&r"))]
1215   ""
1216   "il\t%6,1\n\\
1217    bg\t%3,%2,%1\n\\
1218    xor\t%3,%3,%6\n\\
1219    sf\t%4,%2,%1\n\\
1220    shlqbyi\t%5,%3,4\n\\
1221    bg\t%3,%5,%4\n\\
1222    xor\t%3,%3,%6\n\\
1223    sf\t%4,%5,%4\n\\
1224    shlqbyi\t%5,%3,4\n\\
1225    bg\t%3,%5,%4\n\\
1226    xor\t%3,%3,%6\n\\
1227    sf\t%4,%5,%4\n\\
1228    shlqbyi\t%5,%3,4\n\\
1229    sf\t%0,%5,%4"
1230   [(set_attr "type" "multi0")
1231    (set_attr "length" "56")])
1233 (define_insn "sub<mode>3"
1234   [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1235         (minus:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
1236                    (match_operand:VSF 2 "spu_reg_operand" "r")))]
1237   ""
1238   "fs\t%0,%1,%2"
1239   [(set_attr "type" "fp6")])
1241 (define_insn "sub<mode>3"
1242   [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
1243         (minus:VDF (match_operand:VDF 1 "spu_reg_operand" "r")
1244                    (match_operand:VDF 2 "spu_reg_operand" "r")))]
1245   ""
1246   "dfs\t%0,%1,%2"
1247   [(set_attr "type" "fpd")])
1250 ;; neg
1252 (define_expand "negv16qi2"
1253   [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
1254         (neg:V16QI (match_operand:V16QI 1 "spu_reg_operand" "r")))]
1255   ""
1256   "{
1257     rtx zero = gen_reg_rtx (V16QImode);
1258     emit_move_insn (zero, CONST0_RTX (V16QImode));
1259     emit_insn (gen_subv16qi3 (operands[0], zero, operands[1]));
1260     DONE;
1261    }")
1263 (define_insn "neg<mode>2"
1264   [(set (match_operand:VHSI 0 "spu_reg_operand" "=r")
1265         (neg:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r")))]
1266   ""
1267   "sf<bh>i\t%0,%1,0")
1269 (define_expand "negdi2"
1270   [(set (match_operand:DI 0 "spu_reg_operand" "")
1271         (neg:DI (match_operand:DI 1 "spu_reg_operand" "")))]
1272   ""
1273   {
1274     rtx zero = gen_reg_rtx(DImode);
1275     emit_move_insn(zero, GEN_INT(0));
1276     emit_insn (gen_subdi3(operands[0], zero, operands[1]));
1277     DONE;
1278   })
1280 (define_expand "negti2"
1281   [(set (match_operand:TI 0 "spu_reg_operand" "")
1282         (neg:TI (match_operand:TI 1 "spu_reg_operand" "")))]
1283   ""
1284   {
1285     rtx zero = gen_reg_rtx(TImode);
1286     emit_move_insn(zero, GEN_INT(0));
1287     emit_insn (gen_subti3(operands[0], zero, operands[1]));
1288     DONE;
1289   })
1291 (define_expand "neg<mode>2"
1292   [(parallel
1293     [(set (match_operand:VSF 0 "spu_reg_operand" "")
1294           (neg:VSF (match_operand:VSF 1 "spu_reg_operand" "")))
1295      (use (match_dup 2))])]
1296   ""
1297   "operands[2] = gen_reg_rtx (<F2I>mode);
1298    emit_move_insn (operands[2], spu_const (<F2I>mode, -0x80000000ull));")
1300 (define_expand "neg<mode>2"
1301   [(parallel
1302     [(set (match_operand:VDF 0 "spu_reg_operand" "")
1303           (neg:VDF (match_operand:VDF 1 "spu_reg_operand" "")))
1304      (use (match_dup 2))])]
1305   ""
1306   "operands[2] = gen_reg_rtx (<F2I>mode);
1307    emit_move_insn (operands[2], spu_const (<F2I>mode, -0x8000000000000000ull));")
1309 (define_insn_and_split "_neg<mode>2"
1310   [(set (match_operand:VSDF 0 "spu_reg_operand" "=r")
1311         (neg:VSDF (match_operand:VSDF 1 "spu_reg_operand" "r")))
1312    (use (match_operand:<F2I> 2 "spu_reg_operand" "r"))]
1313   ""
1314   "#"
1315   ""
1316   [(set (match_dup:<F2I> 3)
1317         (xor:<F2I> (match_dup:<F2I> 4)
1318                    (match_dup:<F2I> 2)))]
1319   {
1320     operands[3] = spu_gen_subreg (<F2I>mode, operands[0]);
1321     operands[4] = spu_gen_subreg (<F2I>mode, operands[1]);
1322   })
1325 ;; abs
1327 (define_expand "abs<mode>2"
1328   [(parallel
1329     [(set (match_operand:VSF 0 "spu_reg_operand" "")
1330           (abs:VSF (match_operand:VSF 1 "spu_reg_operand" "")))
1331      (use (match_dup 2))])]
1332   ""
1333   "operands[2] = gen_reg_rtx (<F2I>mode);
1334    emit_move_insn (operands[2], spu_const (<F2I>mode, 0x7fffffffull));")
1336 (define_expand "abs<mode>2"
1337   [(parallel
1338     [(set (match_operand:VDF 0 "spu_reg_operand" "")
1339           (abs:VDF (match_operand:VDF 1 "spu_reg_operand" "")))
1340      (use (match_dup 2))])]
1341   ""
1342   "operands[2] = gen_reg_rtx (<F2I>mode);
1343    emit_move_insn (operands[2], spu_const (<F2I>mode, 0x7fffffffffffffffull));")
1345 (define_insn_and_split "_abs<mode>2"
1346   [(set (match_operand:VSDF 0 "spu_reg_operand" "=r")
1347         (abs:VSDF (match_operand:VSDF 1 "spu_reg_operand" "r")))
1348    (use (match_operand:<F2I> 2 "spu_reg_operand" "r"))]
1349   ""
1350   "#"
1351   ""
1352   [(set (match_dup:<F2I> 3)
1353         (and:<F2I> (match_dup:<F2I> 4)
1354                    (match_dup:<F2I> 2)))]
1355   {
1356     operands[3] = spu_gen_subreg (<F2I>mode, operands[0]);
1357     operands[4] = spu_gen_subreg (<F2I>mode, operands[1]);
1358   })
1361 ;; mul
1363 (define_insn "mulhi3"
1364   [(set (match_operand:HI 0 "spu_reg_operand" "=r,r")
1365         (mult:HI (match_operand:HI 1 "spu_reg_operand" "r,r")
1366                  (match_operand:HI 2 "spu_arith_operand" "r,B")))]
1367   ""
1368   "@
1369   mpy\t%0,%1,%2
1370   mpyi\t%0,%1,%2"
1371   [(set_attr "type" "fp7")])
1373 (define_expand "mulv8hi3"
1374   [(set (match_operand:V8HI 0 "spu_reg_operand" "")
1375         (mult:V8HI (match_operand:V8HI 1 "spu_reg_operand" "")
1376                    (match_operand:V8HI 2 "spu_reg_operand" "")))]
1377   ""
1378   "{
1379     rtx result = simplify_gen_subreg (V4SImode, operands[0], V8HImode, 0);
1380     rtx low = gen_reg_rtx (V4SImode);
1381     rtx high = gen_reg_rtx (V4SImode);
1382     rtx shift = gen_reg_rtx (V4SImode);
1383     rtx mask = gen_reg_rtx (V4SImode);
1385     emit_move_insn (mask, spu_const (V4SImode, 0x0000ffff));
1386     emit_insn (gen_spu_mpyhh (high, operands[1], operands[2]));
1387     emit_insn (gen_spu_mpy (low, operands[1], operands[2]));
1388     emit_insn (gen_vashlv4si3 (shift, high, spu_const(V4SImode, 16)));
1389     emit_insn (gen_selb (result, shift, low, mask));
1390     DONE;
1391    }")
1393 (define_expand "mul<mode>3"
1394   [(parallel
1395     [(set (match_operand:VSI 0 "spu_reg_operand" "")
1396           (mult:VSI (match_operand:VSI 1 "spu_reg_operand" "")
1397                     (match_operand:VSI 2 "spu_reg_operand" "")))
1398      (clobber (match_dup:VSI 3))
1399      (clobber (match_dup:VSI 4))
1400      (clobber (match_dup:VSI 5))
1401      (clobber (match_dup:VSI 6))])]
1402   ""
1403   {
1404     operands[3] = gen_reg_rtx(<MODE>mode);
1405     operands[4] = gen_reg_rtx(<MODE>mode);
1406     operands[5] = gen_reg_rtx(<MODE>mode);
1407     operands[6] = gen_reg_rtx(<MODE>mode);
1408   })
1410 (define_insn_and_split "_mulsi3"
1411   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1412         (mult:SI (match_operand:SI 1 "spu_reg_operand" "r")
1413                  (match_operand:SI 2 "spu_arith_operand" "rK")))
1414    (clobber (match_operand:SI 3 "spu_reg_operand" "=&r"))
1415    (clobber (match_operand:SI 4 "spu_reg_operand" "=&r"))
1416    (clobber (match_operand:SI 5 "spu_reg_operand" "=&r"))
1417    (clobber (match_operand:SI 6 "spu_reg_operand" "=&r"))]
1418   ""
1419   "#"
1420   ""
1421   [(set (match_dup:SI 0)
1422         (mult:SI (match_dup:SI 1)
1423                  (match_dup:SI 2)))]
1424   {
1425     HOST_WIDE_INT val = 0;
1426     rtx a = operands[3];
1427     rtx b = operands[4];
1428     rtx c = operands[5];
1429     rtx d = operands[6];
1430     if (GET_CODE(operands[2]) == CONST_INT)
1431       {
1432         val = INTVAL(operands[2]);
1433         emit_move_insn(d, operands[2]);
1434         operands[2] = d;
1435       }
1436     if (val && (val & 0xffff) == 0)
1437       {
1438         emit_insn (gen_mpyh_si(operands[0], operands[2], operands[1]));
1439       }
1440     else if (val > 0 && val < 0x10000)
1441       {
1442         rtx cst = satisfies_constraint_K (GEN_INT (val)) ? GEN_INT(val) : d;
1443         emit_insn (gen_mpyh_si(a, operands[1], operands[2]));
1444         emit_insn (gen_mpyu_si(c, operands[1], cst));
1445         emit_insn (gen_addsi3(operands[0], a, c));
1446       }
1447     else
1448       {
1449         emit_insn (gen_mpyh_si(a, operands[1], operands[2]));
1450         emit_insn (gen_mpyh_si(b, operands[2], operands[1]));
1451         emit_insn (gen_mpyu_si(c, operands[1], operands[2]));
1452         emit_insn (gen_addsi3(d, a, b));
1453         emit_insn (gen_addsi3(operands[0], d, c));
1454       }
1455     DONE;
1456    })
1458 (define_insn_and_split "_mulv4si3"
1459   [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
1460         (mult:V4SI (match_operand:V4SI 1 "spu_reg_operand" "r")
1461                    (match_operand:V4SI 2 "spu_reg_operand" "r")))
1462    (clobber (match_operand:V4SI 3 "spu_reg_operand" "=&r"))
1463    (clobber (match_operand:V4SI 4 "spu_reg_operand" "=&r"))
1464    (clobber (match_operand:V4SI 5 "spu_reg_operand" "=&r"))
1465    (clobber (match_operand:V4SI 6 "spu_reg_operand" "=&r"))]
1466   ""
1467   "#"
1468   ""
1469   [(set (match_dup:V4SI 0)
1470         (mult:V4SI (match_dup:V4SI 1)
1471                    (match_dup:V4SI 2)))]
1472   {
1473     rtx a = operands[3];
1474     rtx b = operands[4];
1475     rtx c = operands[5];
1476     rtx d = operands[6];
1477     rtx op1 = simplify_gen_subreg (V8HImode, operands[1], V4SImode, 0);
1478     rtx op2 = simplify_gen_subreg (V8HImode, operands[2], V4SImode, 0);
1479     emit_insn (gen_spu_mpyh(a, op1, op2));
1480     emit_insn (gen_spu_mpyh(b, op2, op1));
1481     emit_insn (gen_spu_mpyu(c, op1, op2));
1482     emit_insn (gen_addv4si3(d, a, b));
1483     emit_insn (gen_addv4si3(operands[0], d, c));
1484     DONE;
1485    })
1487 (define_insn "mulhisi3"
1488   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1489         (mult:SI (sign_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
1490                  (sign_extend:SI (match_operand:HI 2 "spu_reg_operand" "r"))))]
1491   ""
1492   "mpy\t%0,%1,%2"
1493   [(set_attr "type" "fp7")])
1495 (define_insn "mulhisi3_imm"
1496   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1497         (mult:SI (sign_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
1498                  (match_operand:SI 2 "imm_K_operand" "K")))]
1499   ""
1500   "mpyi\t%0,%1,%2"
1501   [(set_attr "type" "fp7")])
1503 (define_insn "umulhisi3"
1504   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1505         (mult:SI (zero_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
1506                  (zero_extend:SI (match_operand:HI 2 "spu_reg_operand" "r"))))]
1507   ""
1508   "mpyu\t%0,%1,%2"
1509   [(set_attr "type" "fp7")])
1511 (define_insn "umulhisi3_imm"
1512   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1513         (mult:SI (zero_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
1514                  (and:SI (match_operand:SI 2 "imm_K_operand" "K") (const_int 65535))))]
1515   ""
1516   "mpyui\t%0,%1,%2"
1517   [(set_attr "type" "fp7")])
1519 (define_insn "mpyu_si"
1520   [(set (match_operand:SI 0 "spu_reg_operand" "=r,r")
1521         (mult:SI (and:SI (match_operand:SI 1 "spu_reg_operand" "r,r")
1522                          (const_int 65535))
1523                  (and:SI (match_operand:SI 2 "spu_arith_operand" "r,K")
1524                          (const_int 65535))))]
1525   ""
1526   "@
1527    mpyu\t%0,%1,%2
1528    mpyui\t%0,%1,%2"
1529   [(set_attr "type" "fp7")])
1531 ;; This isn't always profitable to use.  Consider r = a * b + c * d.
1532 ;; It's faster to do the multiplies in parallel then add them.  If we
1533 ;; merge a multiply and add it prevents the multiplies from happening in
1534 ;; parallel.
1535 (define_insn "mpya_si"
1536   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1537         (plus:SI (mult:SI (sign_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
1538                           (sign_extend:SI (match_operand:HI 2 "spu_reg_operand" "r")))
1539                  (match_operand:SI 3 "spu_reg_operand" "r")))]
1540   "0"
1541   "mpya\t%0,%1,%2,%3"
1542   [(set_attr "type" "fp7")])
1544 (define_insn "mpyh_si"
1545   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1546         (mult:SI (and:SI (match_operand:SI 1 "spu_reg_operand" "r")
1547                          (const_int -65536))
1548                  (and:SI (match_operand:SI 2 "spu_reg_operand" "r")
1549                          (const_int 65535))))]
1550   ""
1551   "mpyh\t%0,%1,%2"
1552   [(set_attr "type" "fp7")])
1554 (define_insn "mpys_si"
1555   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1556         (ashiftrt:SI
1557             (mult:SI (sign_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
1558                      (sign_extend:SI (match_operand:HI 2 "spu_reg_operand" "r")))
1559             (const_int 16)))]
1560   ""
1561   "mpys\t%0,%1,%2"
1562   [(set_attr "type" "fp7")])
1564 (define_insn "mpyhh_si"
1565   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1566         (mult:SI (ashiftrt:SI (match_operand:SI 1 "spu_reg_operand" "r")
1567                               (const_int 16))
1568                  (ashiftrt:SI (match_operand:SI 2 "spu_reg_operand" "r")
1569                               (const_int 16))))]
1570   ""
1571   "mpyhh\t%0,%1,%2"
1572   [(set_attr "type" "fp7")])
1574 (define_insn "mpyhhu_si"
1575   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1576         (mult:SI (lshiftrt:SI (match_operand:SI 1 "spu_reg_operand" "r")
1577                               (const_int 16))
1578                  (lshiftrt:SI (match_operand:SI 2 "spu_reg_operand" "r")
1579                               (const_int 16))))]
1580   ""
1581   "mpyhhu\t%0,%1,%2"
1582   [(set_attr "type" "fp7")])
1584 (define_insn "mpyhha_si" 
1585   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1586         (plus:SI (mult:SI (ashiftrt:SI (match_operand:SI 1 "spu_reg_operand" "r")
1587                                        (const_int 16))
1588                           (ashiftrt:SI (match_operand:SI 2 "spu_reg_operand" "r")
1589                                        (const_int 16)))
1590                  (match_operand:SI 3 "spu_reg_operand" "0")))]
1591   "0"
1592   "mpyhha\t%0,%1,%2"
1593   [(set_attr "type" "fp7")])
1595 (define_insn "mul<mode>3"
1596   [(set (match_operand:VSDF 0 "spu_reg_operand" "=r")
1597         (mult:VSDF (match_operand:VSDF 1 "spu_reg_operand" "r")
1598                    (match_operand:VSDF 2 "spu_reg_operand" "r")))]
1599   ""
1600   "<d>fm\t%0,%1,%2"
1601   [(set_attr "type" "fp<d6>")])
1603 (define_insn "fma<mode>4"
1604   [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1605         (fma:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
1606                  (match_operand:VSF 2 "spu_reg_operand" "r")
1607                  (match_operand:VSF 3 "spu_reg_operand" "r")))]
1608   ""
1609   "fma\t%0,%1,%2,%3"
1610   [(set_attr "type"     "fp6")])
1612 ;; ??? The official description is (c - a*b), which is exactly (-a*b + c).
1613 ;; Note that this doesn't match the dfnms description.  Incorrect?
1614 (define_insn "fnma<mode>4"
1615   [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1616         (fma:VSF
1617           (neg:VSF (match_operand:VSF 1 "spu_reg_operand" "r"))
1618           (match_operand:VSF 2 "spu_reg_operand" "r")
1619           (match_operand:VSF 3 "spu_reg_operand" "r")))]
1620   ""
1621   "fnms\t%0,%1,%2,%3"
1622   [(set_attr "type" "fp6")])
1624 (define_insn "fms<mode>4"
1625   [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1626         (fma:VSF
1627           (match_operand:VSF 1 "spu_reg_operand" "r")
1628           (match_operand:VSF 2 "spu_reg_operand" "r")
1629           (neg:VSF (match_operand:VSF 3 "spu_reg_operand" "r"))))]
1630   ""
1631   "fms\t%0,%1,%2,%3"
1632   [(set_attr "type" "fp6")])
1634 (define_insn "fma<mode>4"
1635   [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
1636         (fma:VDF (match_operand:VDF 1 "spu_reg_operand" "r")
1637                  (match_operand:VDF 2 "spu_reg_operand" "r")
1638                  (match_operand:VDF 3 "spu_reg_operand" "0")))]
1639   ""
1640   "dfma\t%0,%1,%2"
1641   [(set_attr "type"     "fpd")])
1643 (define_insn "fms<mode>4"
1644   [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
1645         (fma:VDF
1646           (match_operand:VDF 1 "spu_reg_operand" "r")
1647           (match_operand:VDF 2 "spu_reg_operand" "r")
1648           (neg:VDF (match_operand:VDF 3 "spu_reg_operand" "0"))))]
1649   ""
1650   "dfms\t%0,%1,%2"
1651   [(set_attr "type" "fpd")])
1653 (define_insn "nfma<mode>4"
1654   [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
1655         (neg:VDF
1656           (fma:VDF (match_operand:VDF 1 "spu_reg_operand" "r")
1657                    (match_operand:VDF 2 "spu_reg_operand" "r")
1658                    (match_operand:VDF 3 "spu_reg_operand" "0"))))]
1659   ""
1660   "dfnma\t%0,%1,%2"
1661   [(set_attr "type"     "fpd")])
1663 (define_insn "nfms<mode>4"
1664   [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
1665         (neg:VDF
1666           (fma:VDF
1667             (match_operand:VDF 1 "spu_reg_operand" "r")
1668             (match_operand:VDF 2 "spu_reg_operand" "r")
1669             (neg:VDF (match_operand:VDF 3 "spu_reg_operand" "0")))))]
1670   ""
1671   "dfnms\t%0,%1,%2"
1672   [(set_attr "type" "fpd")])
1674 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
1675 (define_expand "fnma<mode>4"
1676   [(set (match_operand:VDF 0 "spu_reg_operand" "")
1677         (neg:VDF
1678           (fma:VDF
1679             (match_operand:VDF 1 "spu_reg_operand" "")
1680             (match_operand:VDF 2 "spu_reg_operand" "")
1681             (neg:VDF (match_operand:VDF 3 "spu_reg_operand" "")))))]
1682   "!HONOR_SIGNED_ZEROS (<MODE>mode)"
1683   "")
1685 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
1686 (define_expand "fnms<mode>4"
1687   [(set (match_operand:VDF 0 "register_operand" "")
1688         (neg:VDF
1689           (fma:VDF
1690             (match_operand:VDF 1 "register_operand" "")
1691             (match_operand:VDF 2 "register_operand" "")
1692             (match_operand:VDF 3 "register_operand" ""))))]
1693   "!HONOR_SIGNED_ZEROS (<MODE>mode)"
1694   "")
1696 ;; mul highpart, used for divide by constant optimizations.
1698 (define_expand "smulsi3_highpart"
1699   [(set (match_operand:SI 0 "register_operand" "")
1700         (truncate:SI
1701           (ashiftrt:DI
1702             (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
1703                      (sign_extend:DI (match_operand:SI 2 "register_operand" "")))
1704             (const_int 32))))]
1705   ""
1706   {
1707     rtx t0 = gen_reg_rtx (SImode);
1708     rtx t1 = gen_reg_rtx (SImode);
1709     rtx t2 = gen_reg_rtx (SImode);
1710     rtx t3 = gen_reg_rtx (SImode);
1711     rtx t4 = gen_reg_rtx (SImode);
1712     rtx t5 = gen_reg_rtx (SImode);
1713     rtx t6 = gen_reg_rtx (SImode);
1714     rtx t7 = gen_reg_rtx (SImode);
1715     rtx t8 = gen_reg_rtx (SImode);
1716     rtx t9 = gen_reg_rtx (SImode);
1717     rtx t11 = gen_reg_rtx (SImode);
1718     rtx t12 = gen_reg_rtx (SImode);
1719     rtx t14 = gen_reg_rtx (SImode);
1720     rtx t15 = gen_reg_rtx (HImode);
1721     rtx t16 = gen_reg_rtx (HImode);
1722     rtx t17 = gen_reg_rtx (HImode);
1723     rtx t18 = gen_reg_rtx (HImode);
1724     rtx t19 = gen_reg_rtx (SImode);
1725     rtx t20 = gen_reg_rtx (SImode);
1726     rtx t21 = gen_reg_rtx (SImode);
1727     rtx op1_hi = gen_rtx_SUBREG (HImode, operands[1], 2);
1728     rtx op2_hi = gen_rtx_SUBREG (HImode, operands[2], 2);
1729     rtx t0_hi = gen_rtx_SUBREG (HImode, t0, 2);
1730     rtx t1_hi = gen_rtx_SUBREG (HImode, t1, 2);
1732     rtx insn = emit_insn (gen_lshrsi3 (t0, operands[1], GEN_INT (16)));
1733     emit_insn (gen_lshrsi3 (t1, operands[2], GEN_INT (16)));
1734     emit_insn (gen_umulhisi3 (t2, op1_hi, op2_hi));
1735     emit_insn (gen_mpyh_si (t3, operands[1], operands[2]));
1736     emit_insn (gen_mpyh_si (t4, operands[2], operands[1]));
1737     emit_insn (gen_mpyhh_si (t5, operands[1], operands[2]));
1738     emit_insn (gen_mpys_si (t6, t0_hi, op2_hi));
1739     emit_insn (gen_mpys_si (t7, t1_hi, op1_hi));
1741     /* Gen carry bits (in t9 and t11). */
1742     emit_insn (gen_addsi3 (t8, t2, t3));
1743     emit_insn (gen_cg_si (t9, t2, t3));
1744     emit_insn (gen_cg_si (t11, t8, t4));
1746     /* Gen high 32 bits in operand[0].  Correct for mpys. */
1747     emit_insn (gen_addx_si (t12, t5, t6, t9));
1748     emit_insn (gen_addx_si (t14, t12, t7, t11));
1750     /* mpys treats both operands as signed when we really want it to treat
1751        the first operand as signed and the second operand as unsigned.
1752        The code below corrects for that difference.  */
1753     emit_insn (gen_cgt_hi (t15, op1_hi, GEN_INT (-1)));
1754     emit_insn (gen_cgt_hi (t16, op2_hi, GEN_INT (-1)));
1755     emit_insn (gen_andc_hi (t17, t1_hi, t15));
1756     emit_insn (gen_andc_hi (t18, t0_hi, t16));
1757     emit_insn (gen_extendhisi2 (t19, t17));
1758     emit_insn (gen_extendhisi2 (t20, t18));
1759     emit_insn (gen_addsi3 (t21, t19, t20));
1760     emit_insn (gen_addsi3 (operands[0], t14, t21));
1761     unshare_all_rtl_in_chain (insn);
1762     DONE;
1763   })
1765 (define_expand "umulsi3_highpart"
1766   [(set (match_operand:SI 0 "register_operand" "")
1767         (truncate:SI
1768           (ashiftrt:DI
1769             (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
1770                      (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1771             (const_int 32))))]
1772   ""
1773   
1774   {
1775     rtx t0 = gen_reg_rtx (SImode);
1776     rtx t1 = gen_reg_rtx (SImode);
1777     rtx t2 = gen_reg_rtx (SImode);
1778     rtx t3 = gen_reg_rtx (SImode);
1779     rtx t4 = gen_reg_rtx (SImode);
1780     rtx t5 = gen_reg_rtx (SImode);
1781     rtx t6 = gen_reg_rtx (SImode);
1782     rtx t7 = gen_reg_rtx (SImode);
1783     rtx t8 = gen_reg_rtx (SImode);
1784     rtx t9 = gen_reg_rtx (SImode);
1785     rtx t10 = gen_reg_rtx (SImode);
1786     rtx t12 = gen_reg_rtx (SImode);
1787     rtx t13 = gen_reg_rtx (SImode);
1788     rtx t14 = gen_reg_rtx (SImode);
1789     rtx op1_hi = gen_rtx_SUBREG (HImode, operands[1], 2);
1790     rtx op2_hi = gen_rtx_SUBREG (HImode, operands[2], 2);
1791     rtx t0_hi = gen_rtx_SUBREG (HImode, t0, 2);
1793     rtx insn = emit_insn (gen_rotlsi3 (t0, operands[2], GEN_INT (16)));
1794     emit_insn (gen_umulhisi3 (t1, op1_hi, op2_hi));
1795     emit_insn (gen_umulhisi3 (t2, op1_hi, t0_hi));
1796     emit_insn (gen_mpyhhu_si (t3, operands[1], t0));
1797     emit_insn (gen_mpyhhu_si (t4, operands[1], operands[2]));
1798     emit_insn (gen_ashlsi3 (t5, t2, GEN_INT (16)));
1799     emit_insn (gen_ashlsi3 (t6, t3, GEN_INT (16)));
1800     emit_insn (gen_lshrsi3 (t7, t2, GEN_INT (16)));
1801     emit_insn (gen_lshrsi3 (t8, t3, GEN_INT (16)));
1803     /* Gen carry bits (in t10 and t12). */
1804     emit_insn (gen_addsi3 (t9, t1, t5));
1805     emit_insn (gen_cg_si (t10, t1, t5));
1806     emit_insn (gen_cg_si (t12, t9, t6));
1808     /* Gen high 32 bits in operand[0]. */
1809     emit_insn (gen_addx_si (t13, t4, t7, t10));
1810     emit_insn (gen_addx_si (t14, t13, t8, t12));
1811     emit_insn (gen_movsi (operands[0], t14));
1812     unshare_all_rtl_in_chain (insn);
1814     DONE;
1815   })
1817 ;; div
1819 ;; Not necessarily the best implementation of divide but faster then
1820 ;; the default that gcc provides because this is inlined and it uses
1821 ;; clz.
1822 (define_insn "divmodsi4"
1823       [(set (match_operand:SI 0 "spu_reg_operand" "=&r")
1824             (div:SI (match_operand:SI 1 "spu_reg_operand" "r")
1825                     (match_operand:SI 2 "spu_reg_operand" "r")))
1826        (set (match_operand:SI 3 "spu_reg_operand" "=&r")
1827             (mod:SI (match_dup 1)
1828                     (match_dup 2)))
1829        (clobber (match_scratch:SI 4 "=&r"))
1830        (clobber (match_scratch:SI 5 "=&r"))
1831        (clobber (match_scratch:SI 6 "=&r"))
1832        (clobber (match_scratch:SI 7 "=&r"))
1833        (clobber (match_scratch:SI 8 "=&r"))
1834        (clobber (match_scratch:SI 9 "=&r"))
1835        (clobber (match_scratch:SI 10 "=&r"))
1836        (clobber (match_scratch:SI 11 "=&r"))
1837        (clobber (match_scratch:SI 12 "=&r"))
1838        (clobber (reg:SI 130))]
1839   ""
1840   "heqi %2,0\\n\\
1841         hbrr    3f,1f\\n\\
1842         sfi     %8,%1,0\\n\\
1843         sfi     %9,%2,0\\n\\
1844         cgti    %10,%1,-1\\n\\
1845         cgti    %11,%2,-1\\n\\
1846         selb    %8,%8,%1,%10\\n\\
1847         selb    %9,%9,%2,%11\\n\\
1848         clz     %4,%8\\n\\
1849         clz     %7,%9\\n\\
1850         il      %5,1\\n\\
1851         fsmbi   %0,0\\n\\
1852         sf      %7,%4,%7\\n\\
1853         shlqbyi %3,%8,0\\n\\
1854         xor     %11,%10,%11\\n\\
1855         shl     %5,%5,%7\\n\\
1856         shl     %4,%9,%7\\n\\
1857         lnop    \\n\\
1858 1:      or      %12,%0,%5\\n\\
1859         rotqmbii        %5,%5,-1\\n\\
1860         clgt    %6,%4,%3\\n\\
1861         lnop    \\n\\
1862         sf      %7,%4,%3\\n\\
1863         rotqmbii        %4,%4,-1\\n\\
1864         selb    %0,%12,%0,%6\\n\\
1865         lnop    \\n\\
1866         selb    %3,%7,%3,%6\\n\\
1867 3:      brnz    %5,1b\\n\\
1868 2:      sfi     %8,%3,0\\n\\
1869         sfi     %9,%0,0\\n\\
1870         selb    %3,%8,%3,%10\\n\\
1871         selb    %0,%0,%9,%11"
1872   [(set_attr "type" "multi0")
1873    (set_attr "length" "128")])
1875 (define_insn "udivmodsi4"
1876       [(set (match_operand:SI 0 "spu_reg_operand" "=&r")
1877             (udiv:SI (match_operand:SI 1 "spu_reg_operand" "r")
1878                      (match_operand:SI 2 "spu_reg_operand" "r")))
1879        (set (match_operand:SI 3 "spu_reg_operand" "=&r")
1880             (umod:SI (match_dup 1)
1881                      (match_dup 2)))
1882        (clobber (match_scratch:SI 4 "=&r"))
1883        (clobber (match_scratch:SI 5 "=&r"))
1884        (clobber (match_scratch:SI 6 "=&r"))
1885        (clobber (match_scratch:SI 7 "=&r"))
1886        (clobber (match_scratch:SI 8 "=&r"))
1887        (clobber (reg:SI 130))]
1888   ""
1889   "heqi %2,0\\n\\
1890         hbrr    3f,1f\\n\\
1891         clz     %7,%2\\n\\
1892         clz     %4,%1\\n\\
1893         il      %5,1\\n\\
1894         fsmbi   %0,0\\n\\
1895         sf      %7,%4,%7\\n\\
1896         ori     %3,%1,0\\n\\
1897         shl     %5,%5,%7\\n\\
1898         shl     %4,%2,%7\\n\\
1899 1:      or      %8,%0,%5\\n\\
1900         rotqmbii        %5,%5,-1\\n\\
1901         clgt    %6,%4,%3\\n\\
1902         lnop    \\n\\
1903         sf      %7,%4,%3\\n\\
1904         rotqmbii        %4,%4,-1\\n\\
1905         selb    %0,%8,%0,%6\\n\\
1906         lnop    \\n\\
1907         selb    %3,%7,%3,%6\\n\\
1908 3:      brnz    %5,1b\\n\\
1910   [(set_attr "type" "multi0")
1911    (set_attr "length" "80")])
1913 (define_expand "div<mode>3"
1914   [(parallel
1915     [(set (match_operand:VSF 0 "spu_reg_operand" "")    
1916           (div:VSF (match_operand:VSF 1 "spu_reg_operand" "")
1917                    (match_operand:VSF 2 "spu_reg_operand" "")))
1918      (clobber (match_scratch:VSF 3 ""))
1919      (clobber (match_scratch:VSF 4 ""))
1920      (clobber (match_scratch:VSF 5 ""))])]
1921   ""
1922   "")
1924 (define_insn_and_split "*div<mode>3_fast"
1925   [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1926         (div:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
1927                  (match_operand:VSF 2 "spu_reg_operand" "r")))
1928    (clobber (match_scratch:VSF 3 "=&r"))
1929    (clobber (match_scratch:VSF 4 "=&r"))
1930    (clobber (scratch:VSF))]
1931   "flag_unsafe_math_optimizations"
1932   "#"
1933   "reload_completed"
1934   [(set (match_dup:VSF 0)
1935         (div:VSF (match_dup:VSF 1)
1936                  (match_dup:VSF 2)))
1937    (clobber (match_dup:VSF 3))
1938    (clobber (match_dup:VSF 4))
1939    (clobber (scratch:VSF))]
1940   {
1941     emit_insn (gen_frest_<mode>(operands[3], operands[2]));
1942     emit_insn (gen_fi_<mode>(operands[3], operands[2], operands[3]));
1943     emit_insn (gen_mul<mode>3(operands[4], operands[1], operands[3]));
1944     emit_insn (gen_fnma<mode>4(operands[0], operands[4], operands[2], operands[1]));
1945     emit_insn (gen_fma<mode>4(operands[0], operands[0], operands[3], operands[4]));
1946     DONE;
1947   })
1949 (define_insn_and_split "*div<mode>3_adjusted"
1950   [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1951         (div:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
1952                  (match_operand:VSF 2 "spu_reg_operand" "r")))
1953    (clobber (match_scratch:VSF 3 "=&r"))
1954    (clobber (match_scratch:VSF 4 "=&r"))
1955    (clobber (match_scratch:VSF 5 "=&r"))]
1956   "!flag_unsafe_math_optimizations"
1957   "#"
1958   "reload_completed"
1959   [(set (match_dup:VSF 0)
1960         (div:VSF (match_dup:VSF 1)
1961                  (match_dup:VSF 2)))
1962    (clobber (match_dup:VSF 3))
1963    (clobber (match_dup:VSF 4))
1964    (clobber (match_dup:VSF 5))]
1965   {
1966     emit_insn (gen_frest_<mode> (operands[3], operands[2]));
1967     emit_insn (gen_fi_<mode> (operands[3], operands[2], operands[3]));
1968     emit_insn (gen_mul<mode>3 (operands[4], operands[1], operands[3]));
1969     emit_insn (gen_fnma<mode>4 (operands[5], operands[4], operands[2], operands[1]));
1970     emit_insn (gen_fma<mode>4 (operands[3], operands[5], operands[3], operands[4]));
1972    /* Due to truncation error, the quotient result may be low by 1 ulp.
1973       Conditionally add one if the estimate is too small in magnitude.  */
1975     emit_move_insn (gen_lowpart (<F2I>mode, operands[4]),
1976                     spu_const (<F2I>mode, 0x80000000ULL));
1977     emit_move_insn (gen_lowpart (<F2I>mode, operands[5]),
1978                     spu_const (<F2I>mode, 0x3f800000ULL));
1979     emit_insn (gen_selb (operands[5], operands[5], operands[1], operands[4]));
1981     emit_insn (gen_add<f2i>3 (gen_lowpart (<F2I>mode, operands[4]),
1982                               gen_lowpart (<F2I>mode, operands[3]),
1983                               spu_const (<F2I>mode, 1)));
1984     emit_insn (gen_fnma<mode>4 (operands[0], operands[2], operands[4], operands[1]));
1985     emit_insn (gen_mul<mode>3 (operands[0], operands[0], operands[5]));
1986     emit_insn (gen_cgt_<f2i> (gen_lowpart (<F2I>mode, operands[0]),
1987                               gen_lowpart (<F2I>mode, operands[0]),
1988                               spu_const (<F2I>mode, -1)));
1989     emit_insn (gen_selb (operands[0], operands[3], operands[4], operands[0]));
1990     DONE;
1991   })
1994 ;; sqrt
1996 (define_insn_and_split "sqrtsf2"
1997   [(set (match_operand:SF 0 "spu_reg_operand" "=r")
1998         (sqrt:SF (match_operand:SF 1 "spu_reg_operand" "r")))
1999    (clobber (match_scratch:SF 2 "=&r"))
2000    (clobber (match_scratch:SF 3 "=&r"))
2001    (clobber (match_scratch:SF 4 "=&r"))
2002    (clobber (match_scratch:SF 5 "=&r"))]
2003   ""
2004   "#"
2005   "reload_completed"
2006   [(set (match_dup:SF 0)
2007         (sqrt:SF (match_dup:SF 1)))
2008    (clobber (match_dup:SF 2))
2009    (clobber (match_dup:SF 3))
2010    (clobber (match_dup:SF 4))
2011    (clobber (match_dup:SF 5))]
2012   {
2013     emit_move_insn (operands[3],spu_float_const(\"0.5\",SFmode));
2014     emit_move_insn (operands[4],spu_float_const(\"1.00000011920928955078125\",SFmode));
2015     emit_insn (gen_frsqest_sf(operands[2],operands[1]));
2016     emit_insn (gen_fi_sf(operands[2],operands[1],operands[2]));
2017     emit_insn (gen_mulsf3(operands[5],operands[2],operands[1]));
2018     emit_insn (gen_mulsf3(operands[3],operands[5],operands[3]));
2019     emit_insn (gen_fnmasf4(operands[4],operands[2],operands[5],operands[4]));
2020     emit_insn (gen_fmasf4(operands[0],operands[4],operands[3],operands[5]));
2021     DONE;
2022   })
2024 (define_insn "frest_<mode>"
2025   [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
2026         (unspec:VSF [(match_operand:VSF 1 "spu_reg_operand" "r")] UNSPEC_FREST))]
2027   ""
2028   "frest\t%0,%1"
2029   [(set_attr "type" "shuf")])
2031 (define_insn "frsqest_<mode>"
2032   [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
2033         (unspec:VSF [(match_operand:VSF 1 "spu_reg_operand" "r")] UNSPEC_FRSQEST))]
2034   ""
2035   "frsqest\t%0,%1"
2036   [(set_attr "type" "shuf")])
2038 (define_insn "fi_<mode>"
2039   [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
2040         (unspec:VSF [(match_operand:VSF 1 "spu_reg_operand" "r")
2041                     (match_operand:VSF 2 "spu_reg_operand" "r")] UNSPEC_FI))]
2042   ""
2043   "fi\t%0,%1,%2"
2044   [(set_attr "type" "fp7")])
2047 ;; and
2049 (define_insn "and<mode>3"
2050   [(set (match_operand:MOV 0 "spu_reg_operand" "=r,r")
2051         (and:MOV (match_operand:MOV 1 "spu_reg_operand" "r,r")
2052                  (match_operand:MOV 2 "spu_logical_operand" "r,C")))]
2053   ""
2054   "@
2055   and\t%0,%1,%2
2056   and%j2i\t%0,%1,%J2")
2058 (define_insn "anddi3"
2059   [(set (match_operand:DI 0 "spu_reg_operand" "=r,r")
2060         (and:DI (match_operand:DI 1 "spu_reg_operand" "r,r")
2061                 (match_operand:DI 2 "spu_logical_operand" "r,c")))]
2062   ""
2063   "@
2064   and\t%0,%1,%2
2065   and%k2i\t%0,%1,%K2")
2067 (define_insn "andti3"
2068   [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2069         (and:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2070                 (match_operand:TI 2 "spu_logical_operand" "r,Y")))]
2071   ""
2072   "@
2073   and\t%0,%1,%2
2074   and%m2i\t%0,%1,%L2")
2076 (define_insn "andc_<mode>"
2077   [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
2078         (and:ALL (not:ALL (match_operand:ALL 2 "spu_reg_operand" "r"))
2079                  (match_operand:ALL 1 "spu_reg_operand" "r")))]
2080   ""
2081   "andc\t%0,%1,%2")
2083 (define_insn "nand_<mode>"
2084   [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
2085         (not:ALL (and:ALL (match_operand:ALL 2 "spu_reg_operand" "r")
2086                           (match_operand:ALL 1 "spu_reg_operand" "r"))))]
2087   ""
2088   "nand\t%0,%1,%2")
2091 ;; ior
2093 (define_insn "ior<mode>3"
2094   [(set (match_operand:MOV 0 "spu_reg_operand" "=r,r,r")
2095         (ior:MOV (match_operand:MOV 1 "spu_reg_operand" "r,r,0")
2096                  (match_operand:MOV 2 "spu_ior_operand" "r,C,D")))]
2097   ""
2098   "@
2099   or\t%0,%1,%2
2100   or%j2i\t%0,%1,%J2
2101   iohl\t%0,%J2")
2103 (define_insn "iordi3"
2104   [(set (match_operand:DI 0 "spu_reg_operand" "=r,r,r")
2105         (ior:DI (match_operand:DI 1 "spu_reg_operand" "r,r,0")
2106                 (match_operand:DI 2 "spu_ior_operand" "r,c,d")))]
2107   ""
2108   "@
2109   or\t%0,%1,%2
2110   or%k2i\t%0,%1,%K2
2111   iohl\t%0,%K2")
2113 (define_insn "iorti3"
2114   [(set (match_operand:TI 0 "spu_reg_operand" "=r,r,r")
2115         (ior:TI (match_operand:TI 1 "spu_reg_operand" "r,r,0")
2116                 (match_operand:TI 2 "spu_ior_operand" "r,Y,Z")))]
2117   ""
2118   "@
2119   or\t%0,%1,%2
2120   or%m2i\t%0,%1,%L2
2121   iohl\t%0,%L2")
2123 (define_insn "orc_<mode>"
2124   [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
2125         (ior:ALL (not:ALL (match_operand:ALL 2 "spu_reg_operand" "r"))
2126                  (match_operand:ALL 1 "spu_reg_operand" "r")))]
2127   ""
2128   "orc\t%0,%1,%2")
2130 (define_insn "nor_<mode>"
2131   [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
2132         (not:ALL (ior:ALL (match_operand:ALL 1 "spu_reg_operand" "r")
2133                           (match_operand:ALL 2 "spu_reg_operand" "r"))))]
2134   ""
2135   "nor\t%0,%1,%2")
2137 ;; xor
2139 (define_insn "xor<mode>3"
2140   [(set (match_operand:MOV 0 "spu_reg_operand" "=r,r")
2141         (xor:MOV (match_operand:MOV 1 "spu_reg_operand" "r,r")
2142                  (match_operand:MOV 2 "spu_logical_operand" "r,B")))]
2143   ""
2144   "@
2145   xor\t%0,%1,%2
2146   xor%j2i\t%0,%1,%J2")
2148 (define_insn "xordi3"
2149   [(set (match_operand:DI 0 "spu_reg_operand" "=r,r")
2150         (xor:DI (match_operand:DI 1 "spu_reg_operand" "r,r")
2151                 (match_operand:DI 2 "spu_logical_operand" "r,c")))]
2152   ""
2153   "@
2154   xor\t%0,%1,%2
2155   xor%k2i\t%0,%1,%K2")
2157 (define_insn "xorti3"
2158   [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2159         (xor:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2160                 (match_operand:TI 2 "spu_logical_operand" "r,Y")))]
2161   ""
2162   "@
2163   xor\t%0,%1,%2
2164   xor%m2i\t%0,%1,%L2")
2166 (define_insn "eqv_<mode>"
2167   [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
2168         (not:ALL (xor:ALL (match_operand:ALL 1 "spu_reg_operand" "r")
2169                           (match_operand:ALL 2 "spu_reg_operand" "r"))))]
2170   ""
2171   "eqv\t%0,%1,%2")
2173 ;; one_cmpl
2175 (define_insn "one_cmpl<mode>2"
2176   [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
2177         (not:ALL (match_operand:ALL 1 "spu_reg_operand" "r")))]
2178   ""
2179   "nor\t%0,%1,%1")
2182 ;; selb
2184 (define_expand "selb"
2185   [(set (match_operand 0 "spu_reg_operand" "")
2186         (unspec [(match_operand 1 "spu_reg_operand" "")
2187                  (match_operand 2 "spu_reg_operand" "")
2188                  (match_operand 3 "spu_reg_operand" "")] UNSPEC_SELB))]
2189   ""
2190   {
2191     rtx s = gen__selb (operands[0], operands[1], operands[2], operands[3]);
2192     PUT_MODE (SET_SRC (s), GET_MODE (operands[0]));
2193     emit_insn (s);
2194     DONE;
2195   })
2197 ;; This could be defined as a combination of logical operations, but at
2198 ;; one time it caused a crash due to recursive expansion of rtl during CSE.
2199 (define_insn "_selb"
2200   [(set (match_operand 0 "spu_reg_operand" "=r")
2201         (unspec [(match_operand 1 "spu_reg_operand" "r")
2202                  (match_operand 2 "spu_reg_operand" "r")
2203                  (match_operand 3 "spu_reg_operand" "r")] UNSPEC_SELB))]
2204   "GET_MODE(operands[0]) == GET_MODE(operands[1]) 
2205    && GET_MODE(operands[1]) == GET_MODE(operands[2])"
2206   "selb\t%0,%1,%2,%3")
2209 ;; Misc. byte/bit operations
2210 ;; clz/ctz/ffs/popcount/parity
2211 ;; cntb/sumb
2213 (define_insn "clz<mode>2"
2214   [(set (match_operand:VSI 0 "spu_reg_operand" "=r")
2215         (clz:VSI (match_operand:VSI 1 "spu_reg_operand" "r")))]
2216   ""
2217   "clz\t%0,%1")
2219 (define_expand "ctz<mode>2"
2220   [(set (match_dup 2)
2221         (neg:VSI (match_operand:VSI 1 "spu_reg_operand" "")))
2222    (set (match_dup 3) (and:VSI (match_dup 1)
2223                                (match_dup 2)))
2224    (set (match_dup 4) (clz:VSI (match_dup 3)))
2225    (set (match_operand:VSI 0 "spu_reg_operand" "")
2226         (minus:VSI (match_dup 5) (match_dup 4)))]
2227   ""
2228   {
2229      operands[2] = gen_reg_rtx (<MODE>mode);
2230      operands[3] = gen_reg_rtx (<MODE>mode);
2231      operands[4] = gen_reg_rtx (<MODE>mode);
2232      operands[5] = spu_const(<MODE>mode, 31);
2233   })
2235 (define_expand "clrsb<mode>2"
2236   [(set (match_dup 2)
2237         (gt:VSI (match_operand:VSI 1 "spu_reg_operand" "") (match_dup 5)))
2238    (set (match_dup 3) (not:VSI (xor:VSI (match_dup 1) (match_dup 2))))
2239    (set (match_dup 4) (clz:VSI (match_dup 3)))
2240    (set (match_operand:VSI 0 "spu_reg_operand")
2241         (plus:VSI (match_dup 4) (match_dup 5)))]
2242   ""
2243   {
2244      operands[2] = gen_reg_rtx (<MODE>mode);
2245      operands[3] = gen_reg_rtx (<MODE>mode);
2246      operands[4] = gen_reg_rtx (<MODE>mode);
2247      operands[5] = spu_const(<MODE>mode, -1);
2248   })
2250 (define_expand "ffs<mode>2"
2251   [(set (match_dup 2)
2252         (neg:VSI (match_operand:VSI 1 "spu_reg_operand" "")))
2253    (set (match_dup 3) (and:VSI (match_dup 1)
2254                                (match_dup 2)))
2255    (set (match_dup 4) (clz:VSI (match_dup 3)))
2256    (set (match_operand:VSI 0 "spu_reg_operand" "")
2257         (minus:VSI (match_dup 5) (match_dup 4)))]
2258   ""
2259   {
2260      operands[2] = gen_reg_rtx (<MODE>mode);
2261      operands[3] = gen_reg_rtx (<MODE>mode);
2262      operands[4] = gen_reg_rtx (<MODE>mode);
2263      operands[5] = spu_const(<MODE>mode, 32);
2264   })
2266 (define_expand "popcountsi2"
2267   [(set (match_dup 2)
2268         (unspec:SI [(match_operand:SI 1 "spu_reg_operand" "")]
2269                      UNSPEC_CNTB))
2270    (set (match_dup 3)
2271         (unspec:HI [(match_dup 2)] UNSPEC_SUMB))
2272    (set (match_operand:SI 0 "spu_reg_operand" "")
2273         (sign_extend:SI (match_dup 3)))]
2274   ""
2275   {
2276     operands[2] = gen_reg_rtx (SImode);
2277     operands[3] = gen_reg_rtx (HImode);
2278   })
2280 (define_expand "paritysi2"
2281   [(set (match_operand:SI 0 "spu_reg_operand" "")
2282         (parity:SI (match_operand:SI 1 "spu_reg_operand" "")))]
2283   ""
2284   {
2285     operands[2] = gen_reg_rtx (SImode);
2286     emit_insn (gen_popcountsi2(operands[2], operands[1]));
2287     emit_insn (gen_andsi3(operands[0], operands[2], GEN_INT (1)));
2288     DONE;
2289   })
2291 (define_insn "cntb_si"
2292   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2293         (unspec:SI [(match_operand:SI 1 "spu_reg_operand" "r")]
2294                    UNSPEC_CNTB))]
2295   ""
2296   "cntb\t%0,%1"
2297   [(set_attr "type" "fxb")])
2299 (define_insn "cntb_v16qi"
2300   [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
2301         (unspec:V16QI [(match_operand:V16QI 1 "spu_reg_operand" "r")]
2302                       UNSPEC_CNTB))]
2303   ""
2304   "cntb\t%0,%1"
2305   [(set_attr "type" "fxb")])
2307 (define_insn "sumb_si"
2308   [(set (match_operand:HI 0 "spu_reg_operand" "=r")
2309         (unspec:HI [(match_operand:SI 1 "spu_reg_operand" "r")] UNSPEC_SUMB))]
2310   ""
2311   "sumb\t%0,%1,%1"
2312   [(set_attr "type" "fxb")])
2315 ;; ashl, vashl
2317 (define_insn "<v>ashl<mode>3"
2318   [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
2319         (ashift:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
2320                      (match_operand:VHSI 2 "spu_nonmem_operand" "r,W")))]
2321   ""
2322   "@
2323   shl<bh>\t%0,%1,%2
2324   shl<bh>i\t%0,%1,%<umask>2"
2325   [(set_attr "type" "fx3")])
2327 (define_insn_and_split "ashldi3"
2328   [(set (match_operand:DI 0 "spu_reg_operand" "=r,r")
2329         (ashift:DI (match_operand:DI 1 "spu_reg_operand" "r,r")
2330                    (match_operand:SI 2 "spu_nonmem_operand" "r,I")))
2331    (clobber (match_scratch:SI 3 "=&r,X"))]
2332   ""
2333   "#"
2334   "reload_completed"
2335   [(set (match_dup:DI 0)
2336         (ashift:DI (match_dup:DI 1)
2337                    (match_dup:SI 2)))]
2338   {
2339     rtx op0 = gen_rtx_REG (TImode, REGNO (operands[0]));
2340     rtx op1 = gen_rtx_REG (TImode, REGNO (operands[1]));
2341     rtx op2 = operands[2];
2342     rtx op3 = operands[3];
2344     if (GET_CODE (operands[2]) == REG)
2345       {
2346         emit_insn (gen_addsi3 (op3, op2, GEN_INT (64)));
2347         emit_insn (gen_rotlti3 (op0, op1, GEN_INT (64)));
2348         emit_insn (gen_shlqbybi_ti (op0, op0, op3));
2349         emit_insn (gen_shlqbi_ti (op0, op0, op3));
2350       }
2351     else
2352       {
2353         HOST_WIDE_INT val = INTVAL (operands[2]);
2354         emit_insn (gen_rotlti3 (op0, op1, GEN_INT (64)));
2355         emit_insn (gen_shlqby_ti (op0, op0, GEN_INT (val / 8 + 8)));
2356         if (val % 8)
2357           emit_insn (gen_shlqbi_ti (op0, op0, GEN_INT (val % 8)));
2358       }
2359     DONE;
2360   })
2362 (define_expand "ashlti3"
2363   [(parallel [(set (match_operand:TI 0 "spu_reg_operand" "")
2364                    (ashift:TI (match_operand:TI 1 "spu_reg_operand" "")
2365                               (match_operand:SI 2 "spu_nonmem_operand" "")))
2366               (clobber (match_dup:TI 3))])]
2367   ""
2368   "if (GET_CODE (operands[2]) == CONST_INT)
2369     {
2370       emit_insn (gen_ashlti3_imm(operands[0], operands[1], operands[2]));
2371       DONE;
2372     }
2373    operands[3] = gen_reg_rtx (TImode);")
2375 (define_insn_and_split "ashlti3_imm"
2376   [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2377         (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2378                    (match_operand:SI 2 "immediate_operand" "O,P")))]
2379   ""
2380   "@
2381    shlqbyi\t%0,%1,%h2
2382    shlqbii\t%0,%1,%e2"
2383   "!satisfies_constraint_O (operands[2]) && !satisfies_constraint_P (operands[2])"
2384   [(set (match_dup:TI 0)
2385         (ashift:TI (match_dup:TI 1)
2386                    (match_dup:SI 3)))
2387    (set (match_dup:TI 0)
2388         (ashift:TI (match_dup:TI 0)
2389                    (match_dup:SI 4)))]
2390   {
2391     HOST_WIDE_INT val = INTVAL(operands[2]);
2392     operands[3] = GEN_INT (val&7);
2393     operands[4] = GEN_INT (val&-8);
2394   }
2395   [(set_attr "type" "shuf,shuf")])
2397 (define_insn_and_split "ashlti3_reg"
2398   [(set (match_operand:TI 0 "spu_reg_operand" "=r")
2399         (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r")
2400                    (match_operand:SI 2 "spu_reg_operand" "r")))
2401    (clobber (match_operand:TI 3 "spu_reg_operand" "=&r"))]
2402   ""
2403   "#"
2404   ""
2405   [(set (match_dup:TI 3)
2406         (ashift:TI (match_dup:TI 1)
2407                    (and:SI (match_dup:SI 2)
2408                            (const_int 7))))
2409    (set (match_dup:TI 0)
2410         (ashift:TI (match_dup:TI 3)
2411                    (and:SI (match_dup:SI 2)
2412                            (const_int -8))))]
2413   "")
2415 (define_insn "shlqbybi_ti"
2416   [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2417         (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2418                    (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2419                            (const_int -8))))]
2420   ""
2421   "@
2422    shlqbybi\t%0,%1,%2
2423    shlqbyi\t%0,%1,%h2"
2424   [(set_attr "type" "shuf,shuf")])
2426 (define_insn "shlqbi_ti"
2427   [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2428         (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2429                    (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2430                            (const_int 7))))]
2431   ""
2432   "@
2433    shlqbi\t%0,%1,%2
2434    shlqbii\t%0,%1,%e2"
2435   [(set_attr "type" "shuf,shuf")])
2437 (define_insn "shlqby_ti"
2438   [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2439         (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2440                    (mult:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2441                             (const_int 8))))]
2442   ""
2443   "@
2444    shlqby\t%0,%1,%2
2445    shlqbyi\t%0,%1,%f2"
2446   [(set_attr "type" "shuf,shuf")])
2449 ;; lshr, vlshr
2451 (define_insn_and_split "<v>lshr<mode>3"
2452   [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
2453         (lshiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
2454                        (match_operand:VHSI 2 "spu_nonmem_operand" "r,W")))
2455    (clobber (match_scratch:VHSI 3 "=&r,X"))]
2456   ""
2457   "@
2458    #
2459    rot<bh>mi\t%0,%1,-%<umask>2"
2460   "reload_completed && GET_CODE (operands[2]) == REG"
2461   [(set (match_dup:VHSI 3)
2462         (neg:VHSI (match_dup:VHSI 2)))
2463    (set (match_dup:VHSI 0)
2464         (lshiftrt:VHSI (match_dup:VHSI 1)
2465                        (neg:VHSI (match_dup:VHSI 3))))]
2466   ""
2467   [(set_attr "type" "*,fx3")])
2468   
2469 (define_insn "<v>lshr<mode>3_imm"
2470   [(set (match_operand:VHSI 0 "spu_reg_operand" "=r")
2471         (lshiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r")
2472                        (match_operand:VHSI 2 "immediate_operand" "W")))]
2473   ""
2474   "rot<bh>mi\t%0,%1,-%<umask>2"
2475   [(set_attr "type" "fx3")])
2477 (define_insn "rotm_<mode>"
2478   [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
2479         (lshiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
2480                        (neg:VHSI (match_operand:VHSI 2 "spu_nonmem_operand" "r,W"))))]
2481   ""
2482   "@
2483    rot<bh>m\t%0,%1,%2
2484    rot<bh>mi\t%0,%1,-%<nmask>2"
2485   [(set_attr "type" "fx3")])
2487 (define_insn_and_split "lshr<mode>3"
2488   [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r,r")
2489         (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r,r")
2490                       (match_operand:SI 2 "spu_nonmem_operand" "r,O,P")))]
2491   ""
2492   "@
2493    #
2494    rotqmbyi\t%0,%1,-%h2
2495    rotqmbii\t%0,%1,-%e2"
2496   "REG_P (operands[2]) || (!satisfies_constraint_O (operands[2]) && !satisfies_constraint_P (operands[2]))"
2497   [(set (match_dup:DTI 3)
2498         (lshiftrt:DTI (match_dup:DTI 1)
2499                       (match_dup:SI 4)))
2500    (set (match_dup:DTI 0)
2501         (lshiftrt:DTI (match_dup:DTI 3)
2502                       (match_dup:SI 5)))]
2503   {
2504     operands[3] = gen_reg_rtx (<MODE>mode);
2505     if (GET_CODE (operands[2]) == CONST_INT)
2506       {
2507         HOST_WIDE_INT val = INTVAL(operands[2]);
2508         operands[4] = GEN_INT (val & 7);
2509         operands[5] = GEN_INT (val & -8);
2510       }
2511     else
2512       {
2513         rtx t0 = gen_reg_rtx (SImode);
2514         rtx t1 = gen_reg_rtx (SImode);
2515         emit_insn (gen_subsi3(t0, GEN_INT(0), operands[2]));
2516         emit_insn (gen_subsi3(t1, GEN_INT(7), operands[2]));
2517         operands[4] = gen_rtx_AND (SImode, gen_rtx_NEG (SImode, t0), GEN_INT (7));
2518         operands[5] = gen_rtx_AND (SImode, gen_rtx_NEG (SImode, gen_rtx_AND (SImode, t1, GEN_INT (-8))), GEN_INT (-8));
2519       }
2520   }
2521   [(set_attr "type" "*,shuf,shuf")])
2523 (define_expand "shrqbybi_<mode>"
2524   [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
2525         (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
2526                       (and:SI (neg:SI (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2527                                               (const_int -8)))
2528                               (const_int -8))))]
2529   ""
2530   {
2531     if (GET_CODE (operands[2]) == CONST_INT)
2532       operands[2] = GEN_INT (7 - INTVAL (operands[2]));
2533     else
2534       {
2535         rtx t0 = gen_reg_rtx (SImode);
2536         emit_insn (gen_subsi3 (t0, GEN_INT (7), operands[2]));
2537         operands[2] = t0;
2538       }
2539   })
2541 (define_insn "rotqmbybi_<mode>"
2542   [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
2543         (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
2544                       (and:SI (neg:SI (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2545                                               (const_int -8)))
2546                               (const_int -8))))]
2547   ""
2548   "@
2549    rotqmbybi\t%0,%1,%2
2550    rotqmbyi\t%0,%1,-%H2"
2551   [(set_attr "type" "shuf")])
2553 (define_insn_and_split "shrqbi_<mode>"
2554   [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
2555         (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
2556                       (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2557                               (const_int 7))))
2558    (clobber (match_scratch:SI 3 "=&r,X"))]
2559   ""
2560   "#"
2561   "reload_completed"
2562   [(set (match_dup:DTI 0)
2563         (lshiftrt:DTI (match_dup:DTI 1)
2564                       (and:SI (neg:SI (match_dup:SI 3)) (const_int 7))))]
2565   {
2566     if (GET_CODE (operands[2]) == CONST_INT)
2567       operands[3] = GEN_INT (-INTVAL (operands[2]));
2568     else
2569       emit_insn (gen_subsi3 (operands[3], GEN_INT (0), operands[2]));
2570   }
2571   [(set_attr "type" "shuf")])
2573 (define_insn "rotqmbi_<mode>"
2574   [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
2575         (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
2576                       (and:SI (neg:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I"))
2577                               (const_int 7))))]
2578   ""
2579   "@
2580    rotqmbi\t%0,%1,%2
2581    rotqmbii\t%0,%1,-%E2"
2582   [(set_attr "type" "shuf")])
2584 (define_expand "shrqby_<mode>"
2585   [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
2586         (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
2587                       (mult:SI (neg:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I"))
2588                                (const_int 8))))]
2589   ""
2590   {
2591     if (GET_CODE (operands[2]) == CONST_INT)
2592       operands[2] = GEN_INT (-INTVAL (operands[2]));
2593     else
2594       {
2595         rtx t0 = gen_reg_rtx (SImode);
2596         emit_insn (gen_subsi3 (t0, GEN_INT (0), operands[2]));
2597         operands[2] = t0;
2598       }
2599   })
2601 (define_insn "rotqmby_<mode>"
2602   [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
2603         (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
2604                       (mult:SI (neg:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I"))
2605                                (const_int 8))))]
2606   ""
2607   "@
2608    rotqmby\t%0,%1,%2
2609    rotqmbyi\t%0,%1,-%F2"
2610   [(set_attr "type" "shuf")])
2613 ;; ashr, vashr
2615 (define_insn_and_split "<v>ashr<mode>3"
2616   [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
2617         (ashiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
2618                        (match_operand:VHSI 2 "spu_nonmem_operand" "r,W")))
2619    (clobber (match_scratch:VHSI 3 "=&r,X"))]
2620   ""
2621   "@
2622    #
2623    rotma<bh>i\t%0,%1,-%<umask>2"
2624   "reload_completed && GET_CODE (operands[2]) == REG"
2625   [(set (match_dup:VHSI 3)
2626         (neg:VHSI (match_dup:VHSI 2)))
2627    (set (match_dup:VHSI 0)
2628         (ashiftrt:VHSI (match_dup:VHSI 1)
2629                        (neg:VHSI (match_dup:VHSI 3))))]
2630   ""
2631   [(set_attr "type" "*,fx3")])
2632   
2633 (define_insn "<v>ashr<mode>3_imm"
2634   [(set (match_operand:VHSI 0 "spu_reg_operand" "=r")
2635         (ashiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r")
2636                        (match_operand:VHSI 2 "immediate_operand" "W")))]
2637   ""
2638   "rotma<bh>i\t%0,%1,-%<umask>2"
2639   [(set_attr "type" "fx3")])
2640   
2642 (define_insn "rotma_<mode>"
2643   [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
2644         (ashiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
2645                        (neg:VHSI (match_operand:VHSI 2 "spu_nonmem_operand" "r,W"))))]
2646   ""
2647   "@
2648    rotma<bh>\t%0,%1,%2
2649    rotma<bh>i\t%0,%1,-%<nmask>2"
2650   [(set_attr "type" "fx3")])
2652 (define_insn_and_split "ashrdi3"
2653   [(set (match_operand:DI 0 "spu_reg_operand" "=r,r")
2654         (ashiftrt:DI (match_operand:DI 1 "spu_reg_operand" "r,r")
2655                      (match_operand:SI 2 "spu_nonmem_operand" "r,I")))
2656    (clobber (match_scratch:TI 3 "=&r,&r"))
2657    (clobber (match_scratch:TI 4 "=&r,&r"))
2658    (clobber (match_scratch:SI 5 "=&r,&r"))]
2659   ""
2660   "#"
2661   "reload_completed"
2662   [(set (match_dup:DI 0)
2663         (ashiftrt:DI (match_dup:DI 1)
2664                      (match_dup:SI 2)))]
2665   {
2666     rtx op0 = gen_rtx_REG (TImode, REGNO (operands[0]));
2667     rtx op0v = gen_rtx_REG (V4SImode, REGNO (op0));
2668     rtx op1 = gen_rtx_REG (TImode, REGNO (operands[1]));
2669     rtx op1s = gen_rtx_REG (SImode, REGNO (op1));
2670     rtx op2 = operands[2];
2671     rtx op3 = operands[3];
2672     rtx op4 = operands[4];
2673     rtx op5 = operands[5];
2675     if (GET_CODE (op2) == CONST_INT && INTVAL (op2) >= 63)
2676       {
2677         rtx op0s = gen_rtx_REG (SImode, REGNO (op0));
2678         emit_insn (gen_ashrsi3 (op0s, op1s, GEN_INT (32)));
2679         emit_insn (gen_spu_fsm (op0v, op0s));
2680       }
2681     else if (GET_CODE (op2) == CONST_INT && INTVAL (op2) >= 32)
2682       {
2683         rtx op0d = gen_rtx_REG (V2DImode, REGNO (op0));
2684         HOST_WIDE_INT val = INTVAL (op2);
2685         emit_insn (gen_lshrti3 (op0, op1, GEN_INT (32)));
2686         emit_insn (gen_spu_xswd (op0d, op0v));
2687         if (val > 32)
2688           emit_insn (gen_vashrv4si3 (op0v, op0v, spu_const (V4SImode, val - 32)));
2689       }
2690     else
2691       {
2692         rtx op3v = gen_rtx_REG (V4SImode, REGNO (op3));
2693         unsigned char arr[16] = {
2694           0xff, 0xff, 0xff, 0xff,
2695           0xff, 0xff, 0xff, 0xff,
2696           0x00, 0x00, 0x00, 0x00,
2697           0x00, 0x00, 0x00, 0x00
2698         };
2700         emit_insn (gen_ashrsi3 (op5, op1s, GEN_INT (31)));
2701         emit_move_insn (op4, array_to_constant (TImode, arr));
2702         emit_insn (gen_spu_fsm (op3v, op5));
2704         if (GET_CODE (operands[2]) == REG)
2705           {
2706             emit_insn (gen_selb (op4, op3, op1, op4));
2707             emit_insn (gen_negsi2 (op5, op2));
2708             emit_insn (gen_rotqbybi_ti (op0, op4, op5));
2709             emit_insn (gen_rotqbi_ti (op0, op0, op5));
2710           }
2711         else
2712           {
2713             HOST_WIDE_INT val = -INTVAL (op2);
2714             emit_insn (gen_selb (op0, op3, op1, op4));
2715             if ((val - 7) / 8)
2716               emit_insn (gen_rotqby_ti (op0, op0, GEN_INT ((val - 7) / 8)));
2717             if (val % 8)
2718               emit_insn (gen_rotqbi_ti (op0, op0, GEN_INT (val % 8)));
2719           }
2720       }
2721     DONE;
2722   })
2725 (define_insn_and_split "ashrti3"
2726   [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2727         (ashiftrt:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2728                      (match_operand:SI 2 "spu_nonmem_operand" "r,i")))]
2729   ""
2730   "#"
2731   ""
2732   [(set (match_dup:TI 0)
2733         (ashiftrt:TI (match_dup:TI 1)
2734                      (match_dup:SI 2)))]
2735   {
2736     rtx sign_shift = gen_reg_rtx (SImode);
2737     rtx sign_mask = gen_reg_rtx (TImode);
2738     rtx sign_mask_v4si = gen_rtx_SUBREG (V4SImode, sign_mask, 0);
2739     rtx op1_v4si = spu_gen_subreg (V4SImode, operands[1]);
2740     rtx t = gen_reg_rtx (TImode);
2741     emit_insn (gen_subsi3 (sign_shift, GEN_INT (128), force_reg (SImode, operands[2])));
2742     emit_insn (gen_vashrv4si3 (sign_mask_v4si, op1_v4si, spu_const (V4SImode, 31)));
2743     emit_insn (gen_fsm_ti (sign_mask, sign_mask));
2744     emit_insn (gen_ashlti3 (sign_mask, sign_mask, sign_shift));
2745     emit_insn (gen_lshrti3 (t, operands[1], operands[2]));
2746     emit_insn (gen_iorti3 (operands[0], t, sign_mask));
2747     DONE;
2748   })
2750 ;; fsm is used after rotam to replicate the sign across the whole register.
2751 (define_insn "fsm_ti"
2752   [(set (match_operand:TI 0 "spu_reg_operand" "=r")
2753         (unspec:TI [(match_operand:TI 1 "spu_reg_operand" "r")] UNSPEC_FSM))]
2754   ""
2755   "fsm\t%0,%1"
2756   [(set_attr "type" "shuf")])
2759 ;; vrotl, rotl
2761 (define_insn "<v>rotl<mode>3"
2762   [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
2763         (rotate:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
2764                      (match_operand:VHSI 2 "spu_nonmem_operand" "r,W")))]
2765   ""
2766   "@
2767   rot<bh>\t%0,%1,%2
2768   rot<bh>i\t%0,%1,%<umask>2"
2769   [(set_attr "type" "fx3")])
2771 (define_insn "rotlti3"
2772   [(set (match_operand:TI 0 "spu_reg_operand" "=&r,r,r,r")
2773         (rotate:TI (match_operand:TI 1 "spu_reg_operand" "r,r,r,r")
2774                    (match_operand:SI 2 "spu_nonmem_operand" "r,O,P,I")))]
2775   ""
2776   "@
2777   rotqbybi\t%0,%1,%2\;rotqbi\t%0,%0,%2
2778   rotqbyi\t%0,%1,%h2
2779   rotqbii\t%0,%1,%e2
2780   rotqbyi\t%0,%1,%h2\;rotqbii\t%0,%0,%e2"
2781   [(set_attr "length" "8,4,4,8")
2782    (set_attr "type" "multi1,shuf,shuf,multi1")])
2784 (define_insn "rotqbybi_ti"
2785   [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2786         (rotate:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2787                    (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2788                            (const_int -8))))]
2789   ""
2790   "@
2791   rotqbybi\t%0,%1,%2
2792   rotqbyi\t%0,%1,%h2"
2793   [(set_attr "type" "shuf,shuf")])
2795 (define_insn "rotqby_ti"
2796   [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2797         (rotate:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2798                    (mult:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2799                             (const_int 8))))]
2800   ""
2801   "@
2802   rotqby\t%0,%1,%2
2803   rotqbyi\t%0,%1,%f2"
2804   [(set_attr "type" "shuf,shuf")])
2806 (define_insn "rotqbi_ti"
2807   [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2808         (rotate:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2809                    (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2810                            (const_int 7))))]
2811   ""
2812   "@
2813   rotqbi\t%0,%1,%2
2814   rotqbii\t%0,%1,%e2"
2815   [(set_attr "type" "shuf,shuf")])
2818 ;; struct extract/insert
2819 ;; We handle mem's because GCC will generate invalid SUBREG's
2820 ;; and inefficient code.
2822 (define_expand "extv"
2823   [(set (match_operand:TI 0 "register_operand" "")
2824         (sign_extract:TI (match_operand 1 "nonimmediate_operand" "")
2825                          (match_operand:SI 2 "const_int_operand" "")
2826                          (match_operand:SI 3 "const_int_operand" "")))]
2827   ""
2828   {
2829     spu_expand_extv (operands, 0);
2830     DONE;
2831   })
2833 (define_expand "extzv"
2834   [(set (match_operand:TI 0 "register_operand" "")
2835         (zero_extract:TI (match_operand 1 "nonimmediate_operand" "")
2836                          (match_operand:SI 2 "const_int_operand" "")
2837                          (match_operand:SI 3 "const_int_operand" "")))]
2838   ""
2839   {
2840     spu_expand_extv (operands, 1);
2841     DONE;
2842   })
2844 (define_expand "insv"
2845   [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
2846                       (match_operand:SI 1 "const_int_operand" "")
2847                       (match_operand:SI 2 "const_int_operand" ""))
2848         (match_operand 3 "nonmemory_operand" ""))]
2849   ""
2850   { spu_expand_insv(operands); DONE; })
2852 ;; Simplify a number of patterns that get generated by extv, extzv,
2853 ;; insv, and loads.
2854 (define_insn_and_split "trunc_shr_ti<mode>"
2855   [(set (match_operand:QHSI 0 "spu_reg_operand" "=r")
2856         (truncate:QHSI (match_operator:TI 2 "shiftrt_operator" [(match_operand:TI 1 "spu_reg_operand" "0")
2857                                                                 (const_int 96)])))]
2858   ""
2859   "#"
2860   "reload_completed"
2861   [(const_int 0)]
2862   {
2863     spu_split_convert (operands);
2864     DONE;
2865   }
2866   [(set_attr "type" "convert")
2867    (set_attr "length" "0")])
2869 (define_insn_and_split "trunc_shr_tidi"
2870   [(set (match_operand:DI 0 "spu_reg_operand" "=r")
2871         (truncate:DI (match_operator:TI 2 "shiftrt_operator" [(match_operand:TI 1 "spu_reg_operand" "0")
2872                                                               (const_int 64)])))]
2873   ""
2874   "#"
2875   "reload_completed"
2876   [(const_int 0)]
2877   {
2878     spu_split_convert (operands);
2879     DONE;
2880   }
2881   [(set_attr "type" "convert")
2882    (set_attr "length" "0")])
2884 (define_insn_and_split "shl_ext_<mode>ti"
2885   [(set (match_operand:TI 0 "spu_reg_operand" "=r")
2886         (ashift:TI (match_operator:TI 2 "extend_operator" [(match_operand:QHSI 1 "spu_reg_operand" "0")])
2887                    (const_int 96)))]
2888   ""
2889   "#"
2890   "reload_completed"
2891   [(const_int 0)]
2892   {
2893     spu_split_convert (operands);
2894     DONE;
2895   }
2896   [(set_attr "type" "convert")
2897    (set_attr "length" "0")])
2899 (define_insn_and_split "shl_ext_diti"
2900   [(set (match_operand:TI 0 "spu_reg_operand" "=r")
2901         (ashift:TI (match_operator:TI 2 "extend_operator" [(match_operand:DI 1 "spu_reg_operand" "0")])
2902                    (const_int 64)))]
2903   ""
2904   "#"
2905   "reload_completed"
2906   [(const_int 0)]
2907   {
2908     spu_split_convert (operands);
2909     DONE;
2910   }
2911   [(set_attr "type" "convert")
2912    (set_attr "length" "0")])
2914 (define_insn "sext_trunc_lshr_tiqisi"
2915   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2916         (sign_extend:SI (truncate:QI (match_operator:TI 2 "shiftrt_operator" [(match_operand:TI 1 "spu_reg_operand" "r")
2917                                                                               (const_int 120)]))))]
2918   ""
2919   "rotmai\t%0,%1,-24"
2920   [(set_attr "type" "fx3")])
2922 (define_insn "zext_trunc_lshr_tiqisi"
2923   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2924         (zero_extend:SI (truncate:QI (match_operator:TI 2 "shiftrt_operator" [(match_operand:TI 1 "spu_reg_operand" "r")
2925                                                                               (const_int 120)]))))]
2926   ""
2927   "rotmi\t%0,%1,-24"
2928   [(set_attr "type" "fx3")])
2930 (define_insn "sext_trunc_lshr_tihisi"
2931   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2932         (sign_extend:SI (truncate:HI (match_operator:TI 2 "shiftrt_operator" [(match_operand:TI 1 "spu_reg_operand" "r")
2933                                                                               (const_int 112)]))))]
2934   ""
2935   "rotmai\t%0,%1,-16"
2936   [(set_attr "type" "fx3")])
2938 (define_insn "zext_trunc_lshr_tihisi"
2939   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2940         (zero_extend:SI (truncate:HI (match_operator:TI 2 "shiftrt_operator" [(match_operand:TI 1 "spu_reg_operand" "r")
2941                                                                               (const_int 112)]))))]
2942   ""
2943   "rotmi\t%0,%1,-16"
2944   [(set_attr "type" "fx3")])
2947 ;; String/block move insn.
2948 ;; Argument 0 is the destination
2949 ;; Argument 1 is the source
2950 ;; Argument 2 is the length
2951 ;; Argument 3 is the alignment
2953 (define_expand "movstrsi"
2954   [(parallel [(set (match_operand:BLK 0 "" "")
2955                    (match_operand:BLK 1 "" ""))
2956               (use (match_operand:SI 2 "" ""))
2957               (use (match_operand:SI 3 "" ""))])]
2958   ""
2959   "
2960   {
2961     if (spu_expand_block_move (operands))
2962       DONE;
2963     else
2964       FAIL;
2965   }")
2968 ;; jump
2970 (define_insn "indirect_jump"
2971   [(set (pc) (match_operand:SI 0 "spu_reg_operand" "r"))]
2972   ""
2973   "bi\t%0"
2974   [(set_attr "type" "br")])
2976 (define_insn "jump"
2977   [(set (pc)
2978         (label_ref (match_operand 0 "" "")))]
2979   ""
2980   "br\t%0"
2981   [(set_attr "type" "br")])
2984 ;; return
2986 ;; This will be used for leaf functions, that don't save any regs and
2987 ;; don't have locals on stack, maybe... that is for functions that
2988 ;; don't change $sp and don't need to save $lr. 
2989 (define_expand "return"
2990     [(return)]
2991   "direct_return()"
2992   "")
2994 ;; used in spu_expand_epilogue to generate return from a function and
2995 ;; explicitly set use of $lr.
2997 (define_insn "_return"
2998   [(return)]
2999   ""
3000   "bi\t$lr"
3001   [(set_attr "type" "br")])
3005 ;; ceq
3007 (define_insn "ceq_<mode>"
3008   [(set (match_operand:VQHSI 0 "spu_reg_operand" "=r,r")
3009         (eq:VQHSI (match_operand:VQHSI 1 "spu_reg_operand" "r,r")
3010                  (match_operand:VQHSI 2 "spu_arith_operand" "r,B")))]
3011   ""
3012   "@
3013   ceq<bh>\t%0,%1,%2
3014   ceq<bh>i\t%0,%1,%2")
3016 (define_insn_and_split "ceq_di"
3017   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3018         (eq:SI (match_operand:DI 1 "spu_reg_operand" "r")
3019                (match_operand:DI 2 "spu_reg_operand" "r")))]
3020   ""
3021   "#"
3022   "reload_completed"
3023   [(set (match_dup:SI 0)
3024         (eq:SI (match_dup:DI 1)
3025                (match_dup:DI 2)))]
3026   {
3027     rtx op0 = gen_rtx_REG (V4SImode, REGNO (operands[0]));
3028     rtx op1 = gen_rtx_REG (V4SImode, REGNO (operands[1]));
3029     rtx op2 = gen_rtx_REG (V4SImode, REGNO (operands[2]));
3030     emit_insn (gen_ceq_v4si (op0, op1, op2));
3031     emit_insn (gen_spu_gb (op0, op0));
3032     emit_insn (gen_cgt_si (operands[0], operands[0], GEN_INT (11)));
3033     DONE;
3034   })
3037 ;; We provide the TI compares for completeness and because some parts of
3038 ;; gcc/libgcc use them, even though user code might never see it.
3039 (define_insn "ceq_ti"
3040   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3041         (eq:SI (match_operand:TI 1 "spu_reg_operand" "r")
3042                (match_operand:TI 2 "spu_reg_operand" "r")))]
3043   ""
3044   "ceq\t%0,%1,%2\;gb\t%0,%0\;ceqi\t%0,%0,15"
3045   [(set_attr "type" "multi0")
3046    (set_attr "length" "12")])
3048 (define_insn "ceq_<mode>"
3049   [(set (match_operand:<F2I> 0 "spu_reg_operand" "=r")
3050         (eq:<F2I> (match_operand:VSF 1 "spu_reg_operand" "r")
3051                   (match_operand:VSF 2 "spu_reg_operand" "r")))]
3052   ""
3053   "fceq\t%0,%1,%2")
3055 (define_insn "cmeq_<mode>"
3056   [(set (match_operand:<F2I> 0 "spu_reg_operand" "=r")
3057         (eq:<F2I> (abs:VSF (match_operand:VSF 1 "spu_reg_operand" "r"))
3058                   (abs:VSF (match_operand:VSF 2 "spu_reg_operand" "r"))))]
3059   ""
3060   "fcmeq\t%0,%1,%2")
3062 ;; These implementations will ignore checking of NaN or INF if
3063 ;; compiled with option -ffinite-math-only.
3064 (define_expand "ceq_df"
3065   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3066         (eq:SI (match_operand:DF 1 "spu_reg_operand" "r")
3067                (match_operand:DF 2 "const_zero_operand" "i")))]
3068   ""
3070   if (spu_arch == PROCESSOR_CELL)
3071       {
3072         rtx ra = gen_reg_rtx (V4SImode);
3073         rtx rb = gen_reg_rtx (V4SImode);
3074         rtx temp = gen_reg_rtx (TImode);
3075         rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
3076         rtx temp2 = gen_reg_rtx (V4SImode);
3077         rtx biteq = gen_reg_rtx (V4SImode);
3078         rtx ahi_inf = gen_reg_rtx (V4SImode);
3079         rtx a_nan = gen_reg_rtx (V4SImode);
3080         rtx a_abs = gen_reg_rtx (V4SImode);
3081         rtx b_abs = gen_reg_rtx (V4SImode);
3082         rtx iszero = gen_reg_rtx (V4SImode);
3083         rtx sign_mask = gen_reg_rtx (V4SImode);
3084         rtx nan_mask = gen_reg_rtx (V4SImode);
3085         rtx hihi_promote = gen_reg_rtx (TImode);
3086         rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF,
3087                                                  0x7FFFFFFF, 0xFFFFFFFF);
3089         emit_move_insn (sign_mask, pat);
3090         pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0,
3091                                              0x7FF00000, 0x0);
3092         emit_move_insn (nan_mask, pat);
3093         pat = spu_const_from_ints (TImode, 0x00010203, 0x10111213,
3094                                            0x08090A0B, 0x18191A1B);
3095         emit_move_insn (hihi_promote, pat);
3097         emit_insn (gen_spu_convert (ra, operands[1]));
3098         emit_insn (gen_spu_convert (rb, operands[2]));
3099         emit_insn (gen_ceq_v4si (biteq, ra, rb));
3100         emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, biteq),
3101                                 GEN_INT (4 * 8)));
3102         emit_insn (gen_andv4si3 (biteq, biteq, temp_v4si));
3104         emit_insn (gen_andv4si3 (a_abs, ra, sign_mask));
3105         emit_insn (gen_andv4si3 (b_abs, rb, sign_mask));
3106         if (!flag_finite_math_only)
3107           {
3108             emit_insn (gen_clgt_v4si (a_nan, a_abs, nan_mask));
3109             emit_insn (gen_ceq_v4si (ahi_inf, a_abs, nan_mask));
3110             emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, a_nan),
3111                                    GEN_INT (4 * 8)));
3112             emit_insn (gen_andv4si3 (temp2, temp_v4si, ahi_inf));
3113             emit_insn (gen_iorv4si3 (a_nan, a_nan, temp2));
3114           }
3115         emit_insn (gen_iorv4si3 (temp2, a_abs, b_abs));
3116         emit_insn (gen_ceq_v4si (iszero, temp2, CONST0_RTX (V4SImode)));
3117         emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, iszero),
3118                                 GEN_INT (4 * 8)));
3119         emit_insn (gen_andv4si3 (iszero, iszero, temp_v4si));
3120         emit_insn (gen_iorv4si3 (temp2, biteq, iszero));
3121         if (!flag_finite_math_only)
3122           {
3123             emit_insn (gen_andc_v4si (temp2, temp2, a_nan));
3124           }
3125         emit_insn (gen_shufb (operands[0], temp2, temp2, hihi_promote));
3126         DONE;
3127       }
3130 (define_insn "ceq_<mode>_celledp"
3131   [(set (match_operand:<DF2I> 0 "spu_reg_operand" "=r")
3132         (eq:<DF2I> (match_operand:VDF 1 "spu_reg_operand" "r")
3133                    (match_operand:VDF 2 "spu_reg_operand" "r")))]
3134   "spu_arch == PROCESSOR_CELLEDP"
3135   "dfceq\t%0,%1,%2"
3136   [(set_attr "type" "fpd")])
3138 (define_insn "cmeq_<mode>_celledp"
3139   [(set (match_operand:<DF2I> 0 "spu_reg_operand" "=r")
3140         (eq:<DF2I> (abs:VDF (match_operand:VDF 1 "spu_reg_operand" "r"))
3141                    (abs:VDF (match_operand:VDF 2 "spu_reg_operand" "r"))))]
3142   "spu_arch == PROCESSOR_CELLEDP"
3143   "dfcmeq\t%0,%1,%2"
3144   [(set_attr "type" "fpd")])
3146 (define_expand "ceq_v2df"
3147   [(set (match_operand:V2DI 0 "spu_reg_operand" "=r")
3148         (eq:V2DI (match_operand:V2DF 1 "spu_reg_operand" "r")
3149                  (match_operand:V2DF 2 "spu_reg_operand" "r")))]
3150   ""
3152   if (spu_arch == PROCESSOR_CELL)
3153     {
3154       rtx ra = spu_gen_subreg (V4SImode, operands[1]);
3155       rtx rb = spu_gen_subreg (V4SImode, operands[2]);
3156       rtx temp = gen_reg_rtx (TImode);
3157       rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
3158       rtx temp2 = gen_reg_rtx (V4SImode);
3159       rtx biteq = gen_reg_rtx (V4SImode);
3160       rtx ahi_inf = gen_reg_rtx (V4SImode);
3161       rtx a_nan = gen_reg_rtx (V4SImode);
3162       rtx a_abs = gen_reg_rtx (V4SImode);
3163       rtx b_abs = gen_reg_rtx (V4SImode);
3164       rtx iszero = gen_reg_rtx (V4SImode);
3165       rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF,
3166                                                0x7FFFFFFF, 0xFFFFFFFF);
3167       rtx sign_mask = gen_reg_rtx (V4SImode);
3168       rtx nan_mask = gen_reg_rtx (V4SImode);
3169       rtx hihi_promote = gen_reg_rtx (TImode);
3171       emit_move_insn (sign_mask, pat);
3172       pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0, 
3173                                              0x7FF00000, 0x0);
3174       emit_move_insn (nan_mask, pat);
3175       pat = spu_const_from_ints (TImode, 0x00010203, 0x10111213, 
3176                                            0x08090A0B, 0x18191A1B);
3177       emit_move_insn (hihi_promote, pat);
3179       emit_insn (gen_ceq_v4si (biteq, ra, rb));
3180       emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, biteq), 
3181                               GEN_INT (4 * 8)));
3182       emit_insn (gen_andv4si3 (biteq, biteq, temp_v4si));
3183       emit_insn (gen_andv4si3 (a_abs, ra, sign_mask));
3184       emit_insn (gen_andv4si3 (b_abs, rb, sign_mask));
3185       emit_insn (gen_clgt_v4si (a_nan, a_abs, nan_mask));
3186       emit_insn (gen_ceq_v4si (ahi_inf, a_abs, nan_mask));
3187       emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, a_nan), 
3188                               GEN_INT (4 * 8)));
3189       emit_insn (gen_andv4si3 (temp2, temp_v4si, ahi_inf));
3190       emit_insn (gen_iorv4si3 (a_nan, a_nan, temp2));
3191       emit_insn (gen_iorv4si3 (temp2, a_abs, b_abs));
3192       emit_insn (gen_ceq_v4si (iszero, temp2, CONST0_RTX (V4SImode)));
3193       emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, iszero), 
3194                               GEN_INT (4 * 8)));
3195       emit_insn (gen_andv4si3 (iszero, iszero, temp_v4si));
3196       emit_insn (gen_iorv4si3 (temp2, biteq, iszero));
3197       emit_insn (gen_andc_v4si (temp2, temp2, a_nan));
3198       emit_insn (gen_shufb (operands[0], temp2, temp2, hihi_promote));
3199       DONE;
3200   }
3203 (define_expand "cmeq_v2df"
3204   [(set (match_operand:V2DI 0 "spu_reg_operand" "=r")
3205         (eq:V2DI (abs:V2DF (match_operand:V2DF 1 "spu_reg_operand" "r"))
3206                  (abs:V2DF (match_operand:V2DF 2 "spu_reg_operand" "r"))))]
3207   ""
3209   if (spu_arch == PROCESSOR_CELL)
3210     {
3211       rtx ra = spu_gen_subreg (V4SImode, operands[1]);
3212       rtx rb = spu_gen_subreg (V4SImode, operands[2]);
3213       rtx temp = gen_reg_rtx (TImode);
3214       rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
3215       rtx temp2 = gen_reg_rtx (V4SImode);
3216       rtx biteq = gen_reg_rtx (V4SImode);
3217       rtx ahi_inf = gen_reg_rtx (V4SImode);
3218       rtx a_nan = gen_reg_rtx (V4SImode);
3219       rtx a_abs = gen_reg_rtx (V4SImode);
3220       rtx b_abs = gen_reg_rtx (V4SImode);
3222       rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF, 
3223                                                0x7FFFFFFF, 0xFFFFFFFF);
3224       rtx sign_mask = gen_reg_rtx (V4SImode);
3225       rtx nan_mask = gen_reg_rtx (V4SImode);
3226       rtx hihi_promote = gen_reg_rtx (TImode);
3228       emit_move_insn (sign_mask, pat);
3230       pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0, 
3231                                            0x7FF00000, 0x0);
3232       emit_move_insn (nan_mask, pat);
3233       pat = spu_const_from_ints (TImode, 0x00010203, 0x10111213, 
3234                                          0x08090A0B, 0x18191A1B);
3235       emit_move_insn (hihi_promote, pat);
3237       emit_insn (gen_andv4si3 (a_abs, ra, sign_mask));
3238       emit_insn (gen_andv4si3 (b_abs, rb, sign_mask));
3239       emit_insn (gen_ceq_v4si (biteq, a_abs, b_abs));
3240       emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, biteq), 
3241                                                     GEN_INT (4 * 8)));
3242       emit_insn (gen_andv4si3 (biteq, biteq, temp_v4si));
3243       emit_insn (gen_clgt_v4si (a_nan, a_abs, nan_mask));
3244       emit_insn (gen_ceq_v4si (ahi_inf, a_abs, nan_mask));
3245       emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, a_nan), 
3246                                                     GEN_INT (4 * 8)));
3247       emit_insn (gen_andv4si3 (temp2, temp_v4si, ahi_inf));
3248       emit_insn (gen_iorv4si3 (a_nan, a_nan, temp2));
3249       emit_insn (gen_andc_v4si (temp2, biteq, a_nan));
3250       emit_insn (gen_shufb (operands[0], temp2, temp2, hihi_promote));
3251       DONE;
3252   }
3256 ;; cgt
3258 (define_insn "cgt_<mode>"
3259   [(set (match_operand:VQHSI 0 "spu_reg_operand" "=r,r")
3260         (gt:VQHSI (match_operand:VQHSI 1 "spu_reg_operand" "r,r")
3261                   (match_operand:VQHSI 2 "spu_arith_operand" "r,B")))]
3262   ""
3263   "@
3264   cgt<bh>\t%0,%1,%2
3265   cgt<bh>i\t%0,%1,%2")
3267 (define_insn "cgt_di_m1" 
3268   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3269         (gt:SI (match_operand:DI 1 "spu_reg_operand" "r")
3270                (const_int -1)))]
3271   ""
3272   "cgti\t%0,%1,-1")
3274 (define_insn_and_split "cgt_di" 
3275   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3276         (gt:SI (match_operand:DI 1 "spu_reg_operand" "r")
3277                (match_operand:DI 2 "spu_reg_operand" "r")))
3278    (clobber (match_scratch:V4SI 3 "=&r"))
3279    (clobber (match_scratch:V4SI 4 "=&r"))
3280    (clobber (match_scratch:V4SI 5 "=&r"))]
3281   ""
3282   "#"
3283   "reload_completed"
3284   [(set (match_dup:SI 0)
3285         (gt:SI (match_dup:DI 1)
3286                (match_dup:DI 2)))]
3287   {
3288     rtx op0 = gen_rtx_REG (V4SImode, REGNO (operands[0]));
3289     rtx op1 = gen_rtx_REG (V4SImode, REGNO (operands[1]));
3290     rtx op2 = gen_rtx_REG (V4SImode, REGNO (operands[2]));
3291     rtx op3 = operands[3];
3292     rtx op4 = operands[4];
3293     rtx op5 = operands[5];
3294     rtx op3d = gen_rtx_REG (V2DImode, REGNO (operands[3]));
3295     emit_insn (gen_clgt_v4si (op3, op1, op2));
3296     emit_insn (gen_ceq_v4si (op4, op1, op2));
3297     emit_insn (gen_cgt_v4si (op5, op1, op2));
3298     emit_insn (gen_spu_xswd (op3d, op3));
3299     emit_insn (gen_selb (op0, op5, op3, op4));
3300     DONE;
3301   })
3303 (define_insn "cgt_ti_m1" 
3304   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3305         (gt:SI (match_operand:TI 1 "spu_reg_operand" "r")
3306                (const_int -1)))]
3307   ""
3308   "cgti\t%0,%1,-1")
3310 (define_insn "cgt_ti"
3311   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3312         (gt:SI (match_operand:TI 1 "spu_reg_operand" "r")
3313                (match_operand:TI 2 "spu_reg_operand" "r")))
3314    (clobber (match_scratch:V4SI 3 "=&r"))
3315    (clobber (match_scratch:V4SI 4 "=&r"))
3316    (clobber (match_scratch:V4SI 5 "=&r"))]
3317   ""
3318   "clgt\t%4,%1,%2\;\
3319 ceq\t%3,%1,%2\;\
3320 cgt\t%5,%1,%2\;\
3321 shlqbyi\t%0,%4,4\;\
3322 selb\t%0,%4,%0,%3\;\
3323 shlqbyi\t%0,%0,4\;\
3324 selb\t%0,%4,%0,%3\;\
3325 shlqbyi\t%0,%0,4\;\
3326 selb\t%0,%5,%0,%3"
3327   [(set_attr "type" "multi0")
3328    (set_attr "length" "36")])
3330 (define_insn "cgt_<mode>"
3331   [(set (match_operand:<F2I> 0 "spu_reg_operand" "=r")
3332         (gt:<F2I> (match_operand:VSF 1 "spu_reg_operand" "r")
3333                   (match_operand:VSF 2 "spu_reg_operand" "r")))]
3334   ""
3335   "fcgt\t%0,%1,%2")
3337 (define_insn "cmgt_<mode>"
3338   [(set (match_operand:<F2I> 0 "spu_reg_operand" "=r")
3339         (gt:<F2I> (abs:VSF (match_operand:VSF 1 "spu_reg_operand" "r"))
3340                   (abs:VSF (match_operand:VSF 2 "spu_reg_operand" "r"))))]
3341   ""
3342   "fcmgt\t%0,%1,%2")
3344 (define_expand "cgt_df"
3345   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3346         (gt:SI (match_operand:DF 1 "spu_reg_operand" "r")
3347                (match_operand:DF 2 "const_zero_operand" "i")))]
3348   ""
3350   if (spu_arch == PROCESSOR_CELL)
3351     {
3352       rtx ra = gen_reg_rtx (V4SImode);
3353       rtx rb = gen_reg_rtx (V4SImode);
3354       rtx zero = gen_reg_rtx (V4SImode);
3355       rtx temp = gen_reg_rtx (TImode);
3356       rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
3357       rtx temp2 = gen_reg_rtx (V4SImode);
3358       rtx hi_inf = gen_reg_rtx (V4SImode);
3359       rtx a_nan = gen_reg_rtx (V4SImode);
3360       rtx b_nan = gen_reg_rtx (V4SImode);
3361       rtx a_abs = gen_reg_rtx (V4SImode);
3362       rtx b_abs = gen_reg_rtx (V4SImode);
3363       rtx asel = gen_reg_rtx (V4SImode);
3364       rtx bsel = gen_reg_rtx (V4SImode);
3365       rtx abor = gen_reg_rtx (V4SImode);
3366       rtx bbor = gen_reg_rtx (V4SImode);
3367       rtx gt_hi = gen_reg_rtx (V4SImode);
3368       rtx gt_lo = gen_reg_rtx (V4SImode);
3369       rtx sign_mask = gen_reg_rtx (V4SImode);
3370       rtx nan_mask = gen_reg_rtx (V4SImode);
3371       rtx hi_promote = gen_reg_rtx (TImode);
3372       rtx borrow_shuffle = gen_reg_rtx (TImode);
3374       rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF,
3375                                                0x7FFFFFFF, 0xFFFFFFFF);
3376       emit_move_insn (sign_mask, pat);
3377       pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0,
3378                                              0x7FF00000, 0x0);
3379       emit_move_insn (nan_mask, pat);
3380       pat = spu_const_from_ints (TImode, 0x00010203, 0x00010203,
3381                                          0x08090A0B, 0x08090A0B);
3382       emit_move_insn (hi_promote, pat);
3383       pat = spu_const_from_ints (TImode, 0x04050607, 0xC0C0C0C0,
3384                                          0x0C0D0E0F, 0xC0C0C0C0);
3385       emit_move_insn (borrow_shuffle, pat);
3387       emit_insn (gen_spu_convert (ra, operands[1]));
3388       emit_insn (gen_spu_convert (rb, operands[2]));
3389       emit_insn (gen_andv4si3 (a_abs, ra, sign_mask));
3390       emit_insn (gen_andv4si3 (b_abs, rb, sign_mask));
3392       if (!flag_finite_math_only)
3393         {
3394           /* check if ra is NaN  */
3395           emit_insn (gen_ceq_v4si (hi_inf, a_abs, nan_mask));
3396           emit_insn (gen_clgt_v4si (a_nan, a_abs, nan_mask));
3397           emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, a_nan),
3398                                   GEN_INT (4 * 8)));
3399           emit_insn (gen_andv4si3 (temp2, temp_v4si, hi_inf));
3400           emit_insn (gen_iorv4si3 (a_nan, a_nan, temp2));
3401           emit_insn (gen_shufb (a_nan, a_nan, a_nan, hi_promote));
3403           /* check if rb is NaN  */
3404           emit_insn (gen_ceq_v4si (hi_inf, b_abs, nan_mask));
3405           emit_insn (gen_clgt_v4si (b_nan, b_abs, nan_mask));
3406           emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, b_nan),
3407                                   GEN_INT (4 * 8)));
3408           emit_insn (gen_andv4si3 (temp2, temp_v4si, hi_inf));
3409           emit_insn (gen_iorv4si3 (b_nan, b_nan, temp2));
3410           emit_insn (gen_shufb (b_nan, b_nan, b_nan, hi_promote));
3412           /* check if ra or rb is NaN  */
3413           emit_insn (gen_iorv4si3 (a_nan, a_nan, b_nan));
3414         }
3415       emit_move_insn (zero, CONST0_RTX (V4SImode));
3416       emit_insn (gen_vashrv4si3 (asel, ra, spu_const (V4SImode, 31)));
3417       emit_insn (gen_shufb (asel, asel, asel, hi_promote));
3418       emit_insn (gen_bg_v4si (abor, zero, a_abs));
3419       emit_insn (gen_shufb (abor, abor, abor, borrow_shuffle));
3420       emit_insn (gen_sfx_v4si (abor, zero, a_abs, abor));
3421       emit_insn (gen_selb (abor, a_abs, abor, asel));
3423       emit_insn (gen_vashrv4si3 (bsel, rb, spu_const (V4SImode, 31)));
3424       emit_insn (gen_shufb (bsel, bsel, bsel, hi_promote));
3425       emit_insn (gen_bg_v4si (bbor, zero, b_abs));
3426       emit_insn (gen_shufb (bbor, bbor, bbor, borrow_shuffle));
3427       emit_insn (gen_sfx_v4si (bbor, zero, b_abs, bbor));
3428       emit_insn (gen_selb (bbor, b_abs, bbor, bsel));
3430       emit_insn (gen_cgt_v4si (gt_hi, abor, bbor));
3431       emit_insn (gen_clgt_v4si (gt_lo, abor, bbor));
3432       emit_insn (gen_ceq_v4si (temp2, abor, bbor));
3433       emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, gt_lo),
3434                                 GEN_INT (4 * 8)));
3435       emit_insn (gen_andv4si3 (temp2, temp2, temp_v4si));
3436       emit_insn (gen_iorv4si3 (temp2, gt_hi, temp2));
3437       emit_insn (gen_shufb (temp2, temp2, temp2, hi_promote));
3438       if (!flag_finite_math_only)
3439         {
3440           /* correct for NaNs  */
3441           emit_insn (gen_andc_v4si (temp2, temp2, a_nan));
3442         }
3443       emit_insn (gen_spu_convert (operands[0], temp2));
3444       DONE;
3445     }
3448 (define_insn "cgt_<mode>_celledp"
3449   [(set (match_operand:<DF2I> 0 "spu_reg_operand" "=r")
3450         (gt:<DF2I> (match_operand:VDF 1 "spu_reg_operand" "r")
3451                    (match_operand:VDF 2 "spu_reg_operand" "r")))]
3452   "spu_arch == PROCESSOR_CELLEDP"
3453   "dfcgt\t%0,%1,%2"
3454   [(set_attr "type" "fpd")])
3456 (define_insn "cmgt_<mode>_celledp"
3457   [(set (match_operand:<DF2I> 0 "spu_reg_operand" "=r")
3458         (gt:<DF2I> (abs:VDF (match_operand:VDF 1 "spu_reg_operand" "r"))
3459                    (abs:VDF (match_operand:VDF 2 "spu_reg_operand" "r"))))]
3460   "spu_arch == PROCESSOR_CELLEDP"
3461   "dfcmgt\t%0,%1,%2"
3462   [(set_attr "type" "fpd")])
3464 (define_expand "cgt_v2df"
3465   [(set (match_operand:V2DI 0 "spu_reg_operand" "=r")
3466         (gt:V2DI (match_operand:V2DF 1 "spu_reg_operand" "r")
3467                  (match_operand:V2DF 2 "spu_reg_operand" "r")))]
3468   ""
3470   if (spu_arch == PROCESSOR_CELL)
3471     {
3472       rtx ra = spu_gen_subreg (V4SImode, operands[1]);
3473       rtx rb = spu_gen_subreg (V4SImode, operands[2]);
3474       rtx zero = gen_reg_rtx (V4SImode);
3475       rtx temp = gen_reg_rtx (TImode);
3476       rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
3477       rtx temp2 = gen_reg_rtx (V4SImode);
3478       rtx hi_inf = gen_reg_rtx (V4SImode);
3479       rtx a_nan = gen_reg_rtx (V4SImode);
3480       rtx b_nan = gen_reg_rtx (V4SImode);
3481       rtx a_abs = gen_reg_rtx (V4SImode);
3482       rtx b_abs = gen_reg_rtx (V4SImode);
3483       rtx asel = gen_reg_rtx (V4SImode);
3484       rtx bsel = gen_reg_rtx (V4SImode);
3485       rtx abor = gen_reg_rtx (V4SImode);
3486       rtx bbor = gen_reg_rtx (V4SImode);
3487       rtx gt_hi = gen_reg_rtx (V4SImode);
3488       rtx gt_lo = gen_reg_rtx (V4SImode);
3489       rtx sign_mask = gen_reg_rtx (V4SImode);
3490       rtx nan_mask = gen_reg_rtx (V4SImode);
3491       rtx hi_promote = gen_reg_rtx (TImode);
3492       rtx borrow_shuffle = gen_reg_rtx (TImode);
3493       rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF, 
3494                                                0x7FFFFFFF, 0xFFFFFFFF);
3495       emit_move_insn (sign_mask, pat);
3496       pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0, 
3497                                            0x7FF00000, 0x0);
3498       emit_move_insn (nan_mask, pat);
3499       pat = spu_const_from_ints (TImode, 0x00010203, 0x00010203, 
3500                                          0x08090A0B, 0x08090A0B);
3501       emit_move_insn (hi_promote, pat);
3502       pat = spu_const_from_ints (TImode, 0x04050607, 0xC0C0C0C0, 
3503                                          0x0C0D0E0F, 0xC0C0C0C0);
3504       emit_move_insn (borrow_shuffle, pat);
3506       emit_insn (gen_andv4si3 (a_abs, ra, sign_mask));
3507       emit_insn (gen_ceq_v4si (hi_inf, a_abs, nan_mask));
3508       emit_insn (gen_clgt_v4si (a_nan, a_abs, nan_mask));
3509       emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, a_nan), 
3510                                                     GEN_INT (4 * 8)));
3511       emit_insn (gen_andv4si3 (temp2, temp_v4si, hi_inf));
3512       emit_insn (gen_iorv4si3 (a_nan, a_nan, temp2));
3513       emit_insn (gen_shufb (a_nan, a_nan, a_nan, hi_promote));
3514       emit_insn (gen_andv4si3 (b_abs, rb, sign_mask));
3515       emit_insn (gen_ceq_v4si (hi_inf, b_abs, nan_mask));
3516       emit_insn (gen_clgt_v4si (b_nan, b_abs, nan_mask));
3517       emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, b_nan), 
3518                                                     GEN_INT (4 * 8)));
3519       emit_insn (gen_andv4si3 (temp2, temp_v4si, hi_inf));
3520       emit_insn (gen_iorv4si3 (b_nan, b_nan, temp2));
3521       emit_insn (gen_shufb (b_nan, b_nan, b_nan, hi_promote));
3522       emit_insn (gen_iorv4si3 (a_nan, a_nan, b_nan));
3523       emit_move_insn (zero, CONST0_RTX (V4SImode));
3524       emit_insn (gen_vashrv4si3 (asel, ra, spu_const (V4SImode, 31)));
3525       emit_insn (gen_shufb (asel, asel, asel, hi_promote));
3526       emit_insn (gen_bg_v4si (abor, zero, a_abs));
3527       emit_insn (gen_shufb (abor, abor, abor, borrow_shuffle));
3528       emit_insn (gen_sfx_v4si (abor, zero, a_abs, abor));
3529       emit_insn (gen_selb (abor, a_abs, abor, asel));
3530       emit_insn (gen_vashrv4si3 (bsel, rb, spu_const (V4SImode, 31)));
3531       emit_insn (gen_shufb (bsel, bsel, bsel, hi_promote));
3532       emit_insn (gen_bg_v4si (bbor, zero, b_abs));
3533       emit_insn (gen_shufb (bbor, bbor, bbor, borrow_shuffle));
3534       emit_insn (gen_sfx_v4si (bbor, zero, b_abs, bbor));
3535       emit_insn (gen_selb (bbor, b_abs, bbor, bsel));
3536       emit_insn (gen_cgt_v4si (gt_hi, abor, bbor));
3537       emit_insn (gen_clgt_v4si (gt_lo, abor, bbor));
3538       emit_insn (gen_ceq_v4si (temp2, abor, bbor));
3539       emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, gt_lo), 
3540                                                     GEN_INT (4 * 8)));
3541       emit_insn (gen_andv4si3 (temp2, temp2, temp_v4si));
3542       emit_insn (gen_iorv4si3 (temp2, gt_hi, temp2));
3544       emit_insn (gen_shufb (temp2, temp2, temp2, hi_promote));
3545       emit_insn (gen_andc_v4si (temp2, temp2, a_nan));
3546       emit_move_insn (operands[0], spu_gen_subreg (V2DImode, temp2));
3547       DONE;
3548     } 
3551 (define_expand "cmgt_v2df"
3552   [(set (match_operand:V2DI 0 "spu_reg_operand" "=r")
3553         (gt:V2DI (abs:V2DF (match_operand:V2DF 1 "spu_reg_operand" "r"))
3554                  (abs:V2DF (match_operand:V2DF 2 "spu_reg_operand" "r"))))]
3555   ""
3557   if (spu_arch == PROCESSOR_CELL)
3558     {
3559       rtx ra = spu_gen_subreg (V4SImode, operands[1]);
3560       rtx rb = spu_gen_subreg (V4SImode, operands[2]);
3561       rtx temp = gen_reg_rtx (TImode);
3562       rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
3563       rtx temp2 = gen_reg_rtx (V4SImode);
3564       rtx hi_inf = gen_reg_rtx (V4SImode);
3565       rtx a_nan = gen_reg_rtx (V4SImode);
3566       rtx b_nan = gen_reg_rtx (V4SImode);
3567       rtx a_abs = gen_reg_rtx (V4SImode);
3568       rtx b_abs = gen_reg_rtx (V4SImode);
3569       rtx gt_hi = gen_reg_rtx (V4SImode);
3570       rtx gt_lo = gen_reg_rtx (V4SImode);
3571       rtx sign_mask = gen_reg_rtx (V4SImode);
3572       rtx nan_mask = gen_reg_rtx (V4SImode);
3573       rtx hi_promote = gen_reg_rtx (TImode);
3574       rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF, 
3575                                                0x7FFFFFFF, 0xFFFFFFFF);
3576       emit_move_insn (sign_mask, pat);
3577       pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0, 
3578                                            0x7FF00000, 0x0);
3579       emit_move_insn (nan_mask, pat);
3580       pat = spu_const_from_ints (TImode, 0x00010203, 0x00010203, 
3581                                          0x08090A0B, 0x08090A0B);
3582       emit_move_insn (hi_promote, pat);
3584       emit_insn (gen_andv4si3 (a_abs, ra, sign_mask));
3585       emit_insn (gen_ceq_v4si (hi_inf, a_abs, nan_mask));
3586       emit_insn (gen_clgt_v4si (a_nan, a_abs, nan_mask));
3587       emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, a_nan), 
3588                                                     GEN_INT (4 * 8)));
3589       emit_insn (gen_andv4si3 (temp2, temp_v4si, hi_inf));
3590       emit_insn (gen_iorv4si3 (a_nan, a_nan, temp2));
3591       emit_insn (gen_shufb (a_nan, a_nan, a_nan, hi_promote));
3592       emit_insn (gen_andv4si3 (b_abs, rb, sign_mask));
3593       emit_insn (gen_ceq_v4si (hi_inf, b_abs, nan_mask));
3594       emit_insn (gen_clgt_v4si (b_nan, b_abs, nan_mask));
3595       emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, b_nan), 
3596                                                     GEN_INT (4 * 8)));
3597       emit_insn (gen_andv4si3 (temp2, temp_v4si, hi_inf));
3598       emit_insn (gen_iorv4si3 (b_nan, b_nan, temp2));
3599       emit_insn (gen_shufb (b_nan, b_nan, b_nan, hi_promote));
3600       emit_insn (gen_iorv4si3 (a_nan, a_nan, b_nan));
3602       emit_insn (gen_clgt_v4si (gt_hi, a_abs, b_abs));
3603       emit_insn (gen_clgt_v4si (gt_lo, a_abs, b_abs));
3604       emit_insn (gen_ceq_v4si (temp2, a_abs, b_abs));
3605       emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, gt_lo), 
3606                                                     GEN_INT (4 * 8)));
3607       emit_insn (gen_andv4si3 (temp2, temp2, temp_v4si));
3608       emit_insn (gen_iorv4si3 (temp2, gt_hi, temp2));
3609       emit_insn (gen_shufb (temp2, temp2, temp2, hi_promote));
3610       emit_insn (gen_andc_v4si (temp2, temp2, a_nan));
3611       emit_move_insn (operands[0], spu_gen_subreg (V2DImode, temp2));
3612       DONE;
3613     }
3617 ;; clgt
3619 (define_insn "clgt_<mode>"
3620   [(set (match_operand:VQHSI 0 "spu_reg_operand" "=r,r")
3621         (gtu:VQHSI (match_operand:VQHSI 1 "spu_reg_operand" "r,r")
3622                    (match_operand:VQHSI 2 "spu_arith_operand" "r,B")))]
3623   ""
3624   "@
3625   clgt<bh>\t%0,%1,%2
3626   clgt<bh>i\t%0,%1,%2")
3628 (define_insn_and_split "clgt_di" 
3629   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3630         (gtu:SI (match_operand:DI 1 "spu_reg_operand" "r")
3631                 (match_operand:DI 2 "spu_reg_operand" "r")))
3632    (clobber (match_scratch:V4SI 3 "=&r"))
3633    (clobber (match_scratch:V4SI 4 "=&r"))
3634    (clobber (match_scratch:V4SI 5 "=&r"))]
3635   ""
3636   "#"
3637   "reload_completed"
3638   [(set (match_dup:SI 0)
3639         (gtu:SI (match_dup:DI 1)
3640                 (match_dup:DI 2)))]
3641   {
3642     rtx op0 = gen_rtx_REG (V4SImode, REGNO (operands[0]));
3643     rtx op1 = gen_rtx_REG (V4SImode, REGNO (operands[1]));
3644     rtx op2 = gen_rtx_REG (V4SImode, REGNO (operands[2]));
3645     rtx op3 = operands[3];
3646     rtx op4 = operands[4];
3647     rtx op5 = operands[5];
3648     rtx op5d = gen_rtx_REG (V2DImode, REGNO (operands[5]));
3649     emit_insn (gen_clgt_v4si (op3, op1, op2));
3650     emit_insn (gen_ceq_v4si (op4, op1, op2));
3651     emit_insn (gen_spu_xswd (op5d, op3));
3652     emit_insn (gen_selb (op0, op3, op5, op4));
3653     DONE;
3654   })
3656 (define_insn "clgt_ti"
3657   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3658         (gtu:SI (match_operand:TI 1 "spu_reg_operand" "r")
3659                (match_operand:TI 2 "spu_reg_operand" "r")))
3660    (clobber (match_scratch:V4SI 3 "=&r"))
3661    (clobber (match_scratch:V4SI 4 "=&r"))]
3662   ""
3663   "ceq\t%3,%1,%2\;\
3664 clgt\t%4,%1,%2\;\
3665 shlqbyi\t%0,%4,4\;\
3666 selb\t%0,%4,%0,%3\;\
3667 shlqbyi\t%0,%0,4\;\
3668 selb\t%0,%4,%0,%3\;\
3669 shlqbyi\t%0,%0,4\;\
3670 selb\t%0,%4,%0,%3"
3671   [(set_attr "type" "multi0")
3672    (set_attr "length" "32")])
3675 ;; dftsv
3676 (define_insn "dftsv_celledp"
3677   [(set (match_operand:V2DI 0 "spu_reg_operand" "=r")
3678         (unspec:V2DI [(match_operand:V2DF 1 "spu_reg_operand"  "r")
3679                       (match_operand:SI   2 "const_int_operand" "i")]
3680                       UNSPEC_DFTSV))]
3681   "spu_arch == PROCESSOR_CELLEDP"
3682   "dftsv\t%0,%1,%2"
3683   [(set_attr "type" "fpd")])
3685 (define_expand "dftsv"
3686   [(set (match_operand:V2DI 0 "spu_reg_operand" "=r")
3687         (unspec:V2DI [(match_operand:V2DF 1 "spu_reg_operand" "r")
3688                       (match_operand:SI   2 "const_int_operand" "i")]
3689                       UNSPEC_DFTSV))]
3690   ""
3692   if (spu_arch == PROCESSOR_CELL)
3693     {
3694       rtx result = gen_reg_rtx (V4SImode);
3695       emit_move_insn (result, CONST0_RTX (V4SImode));
3697       if (INTVAL (operands[2]))
3698         {
3699           rtx ra = spu_gen_subreg (V4SImode, operands[1]);
3700           rtx abs = gen_reg_rtx (V4SImode);
3701           rtx sign = gen_reg_rtx (V4SImode);
3702           rtx temp = gen_reg_rtx (TImode);
3703           rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
3704           rtx temp2 = gen_reg_rtx (V4SImode);
3705           rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF, 
3706                                                    0x7FFFFFFF, 0xFFFFFFFF);
3707           rtx sign_mask = gen_reg_rtx (V4SImode);
3708           rtx hi_promote = gen_reg_rtx (TImode);
3709           emit_move_insn (sign_mask, pat);
3710           pat = spu_const_from_ints (TImode, 0x00010203, 0x00010203, 
3711                                              0x08090A0B, 0x08090A0B);
3712           emit_move_insn (hi_promote, pat);
3714           emit_insn (gen_vashrv4si3 (sign, ra, spu_const (V4SImode, 31)));
3715           emit_insn (gen_shufb (sign, sign, sign, hi_promote));
3716           emit_insn (gen_andv4si3 (abs, ra, sign_mask));
3718           /* NaN  or +inf or -inf */
3719           if (INTVAL (operands[2]) & 0x70)
3720             {
3721               rtx nan_mask = gen_reg_rtx (V4SImode);
3722               rtx isinf = gen_reg_rtx (V4SImode);
3723               pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0, 
3724                                                    0x7FF00000, 0x0);
3725               emit_move_insn (nan_mask, pat);
3726               emit_insn (gen_ceq_v4si (isinf, abs, nan_mask));
3728               /* NaN  */
3729               if (INTVAL (operands[2]) & 0x40)
3730                 {
3731                   rtx isnan = gen_reg_rtx (V4SImode);
3732                   emit_insn (gen_clgt_v4si (isnan, abs, nan_mask));
3733                   emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, isnan), 
3734                                                              GEN_INT (4 * 8)));
3735                   emit_insn (gen_andv4si3 (temp2, temp_v4si, isinf));
3736                   emit_insn (gen_iorv4si3 (isnan, isnan, temp2));
3737                   emit_insn (gen_shufb (isnan, isnan, isnan, hi_promote));
3738                   emit_insn (gen_iorv4si3 (result, result, isnan));
3739                 }
3740               /* +inf or -inf  */
3741               if (INTVAL (operands[2]) & 0x30)
3742                 {
3743                   emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, isinf), 
3744                                                              GEN_INT (4 * 8)));
3745                   emit_insn (gen_andv4si3 (isinf, isinf, temp_v4si));
3746                   emit_insn (gen_shufb (isinf, isinf, isinf, hi_promote));
3748                   /* +inf  */
3749                   if (INTVAL (operands[2]) & 0x20)
3750                     {
3751                       emit_insn (gen_andc_v4si (temp2, isinf, sign));
3752                       emit_insn (gen_iorv4si3 (result, result, temp2));
3753                     }
3754                   /* -inf  */
3755                   if (INTVAL (operands[2]) & 0x10)
3756                     {
3757                       emit_insn (gen_andv4si3 (temp2, isinf, sign));
3758                       emit_insn (gen_iorv4si3 (result, result, temp2));
3759                     }
3760                 }
3761             }
3763           /* 0 or denorm  */
3764           if (INTVAL (operands[2]) & 0xF)
3765             {
3766               rtx iszero = gen_reg_rtx (V4SImode);
3767               emit_insn (gen_ceq_v4si (iszero, abs, CONST0_RTX (V4SImode)));
3768               emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, iszero), 
3769                                                           GEN_INT (4 * 8)));
3770               emit_insn (gen_andv4si3 (iszero, iszero, temp_v4si));
3772               /* denorm  */
3773               if (INTVAL (operands[2]) & 0x3)
3774                 {
3775                   rtx isdenorm = gen_reg_rtx (V4SImode);
3776                   rtx denorm_mask = gen_reg_rtx (V4SImode);
3777                   emit_move_insn (denorm_mask, spu_const (V4SImode, 0xFFFFF));
3778                   emit_insn (gen_clgt_v4si (isdenorm, abs, denorm_mask));
3779                   emit_insn (gen_nor_v4si (isdenorm, isdenorm, iszero));
3780                   emit_insn (gen_shufb (isdenorm, isdenorm, 
3781                                         isdenorm, hi_promote));
3782                   /* +denorm  */
3783                   if (INTVAL (operands[2]) & 0x2)
3784                     {
3785                       emit_insn (gen_andc_v4si (temp2, isdenorm, sign));
3786                       emit_insn (gen_iorv4si3 (result, result, temp2));
3787                     }
3788                   /* -denorm  */
3789                   if (INTVAL (operands[2]) & 0x1)
3790                     {
3791                       emit_insn (gen_andv4si3 (temp2, isdenorm, sign));
3792                       emit_insn (gen_iorv4si3 (result, result, temp2));
3793                     }
3794                 }
3796               /* 0  */
3797               if (INTVAL (operands[2]) & 0xC)
3798                 {
3799                   emit_insn (gen_shufb (iszero, iszero, iszero, hi_promote));
3800                   /* +0  */
3801                   if (INTVAL (operands[2]) & 0x8)
3802                     {
3803                       emit_insn (gen_andc_v4si (temp2, iszero, sign));
3804                       emit_insn (gen_iorv4si3 (result, result, temp2));
3805                     }
3806                   /* -0  */
3807                   if (INTVAL (operands[2]) & 0x4)
3808                     {
3809                       emit_insn (gen_andv4si3 (temp2, iszero, sign));
3810                       emit_insn (gen_iorv4si3 (result, result, temp2));
3811                     }
3812                 }
3813              }
3814           }
3815       emit_move_insn (operands[0], spu_gen_subreg (V2DImode, result));
3816       DONE;
3817     }
3821 ;; branches
3823 (define_insn ""
3824   [(set (pc)
3825         (if_then_else (match_operator 1 "branch_comparison_operator"
3826                                       [(match_operand 2
3827                                                       "spu_reg_operand" "r")
3828                                        (const_int 0)])
3829                       (label_ref (match_operand 0 "" ""))
3830                       (pc)))]
3831   ""
3832   "br%b2%b1z\t%2,%0"
3833   [(set_attr "type" "br")])
3835 (define_insn ""
3836   [(set (pc)
3837         (if_then_else (match_operator 0 "branch_comparison_operator"
3838                                       [(match_operand 1
3839                                                       "spu_reg_operand" "r")
3840                                        (const_int 0)])
3841                       (return)
3842                       (pc)))]
3843   "direct_return ()"
3844   "bi%b1%b0z\t%1,$lr"
3845   [(set_attr "type" "br")])
3847 (define_insn ""
3848   [(set (pc)
3849         (if_then_else (match_operator 1 "branch_comparison_operator"
3850                                       [(match_operand 2
3851                                                       "spu_reg_operand" "r")
3852                                        (const_int 0)])
3853                       (pc)
3854                       (label_ref (match_operand 0 "" ""))))]
3855   ""
3856   "br%b2%b1z\t%2,%0"
3857   [(set_attr "type" "br")])
3859 (define_insn ""
3860   [(set (pc)
3861         (if_then_else (match_operator 0 "branch_comparison_operator"
3862                                       [(match_operand 1
3863                                                       "spu_reg_operand" "r")
3864                                        (const_int 0)])
3865                       (pc)
3866                       (return)))]
3867   "direct_return ()"
3868   "bi%b1%b0z\t%1,$lr"
3869   [(set_attr "type" "br")])
3872 ;; vector conditional compare patterns
3873 (define_expand "vcond<mode>"
3874   [(set (match_operand:VCMP 0 "spu_reg_operand" "=r")
3875         (if_then_else:VCMP
3876           (match_operator 3 "comparison_operator"
3877             [(match_operand:VCMP 4 "spu_reg_operand" "r")
3878              (match_operand:VCMP 5 "spu_reg_operand" "r")])
3879           (match_operand:VCMP 1 "spu_reg_operand" "r")
3880           (match_operand:VCMP 2 "spu_reg_operand" "r")))]
3881   ""
3882   {
3883     if (spu_emit_vector_cond_expr (operands[0], operands[1], operands[2],
3884                                    operands[3], operands[4], operands[5]))
3885     DONE;
3886     else
3887     FAIL;
3888   })
3890 (define_expand "vcondu<mode>"
3891   [(set (match_operand:VCMPU 0 "spu_reg_operand" "=r")
3892         (if_then_else:VCMPU
3893           (match_operator 3 "comparison_operator"
3894             [(match_operand:VCMPU 4 "spu_reg_operand" "r")
3895              (match_operand:VCMPU 5 "spu_reg_operand" "r")])
3896           (match_operand:VCMPU 1 "spu_reg_operand" "r")
3897           (match_operand:VCMPU 2 "spu_reg_operand" "r")))]
3898   ""
3899   {
3900     if (spu_emit_vector_cond_expr (operands[0], operands[1], operands[2],
3901                                    operands[3], operands[4], operands[5]))
3902     DONE;
3903     else
3904     FAIL;
3905   })
3906         
3908 ;; branch on condition
3910 (define_expand "cbranch<mode>4"
3911   [(use (match_operator 0 "ordered_comparison_operator"
3912          [(match_operand:VQHSI 1 "spu_reg_operand" "")
3913           (match_operand:VQHSI 2 "spu_nonmem_operand" "")]))
3914    (use (match_operand 3 ""))]
3915   ""
3916   { spu_emit_branch_or_set (0, operands[0], operands); DONE; })
3918 (define_expand "cbranch<mode>4"
3919   [(use (match_operator 0 "ordered_comparison_operator"
3920          [(match_operand:DTI 1 "spu_reg_operand" "")
3921           (match_operand:DTI 2 "spu_reg_operand" "")]))
3922    (use (match_operand 3 ""))]
3923   ""
3924   { spu_emit_branch_or_set (0, operands[0], operands); DONE; })
3926 (define_expand "cbranch<mode>4"
3927   [(use (match_operator 0 "ordered_comparison_operator"
3928          [(match_operand:VSF 1 "spu_reg_operand" "")
3929           (match_operand:VSF 2 "spu_reg_operand" "")]))
3930    (use (match_operand 3 ""))]
3931   ""
3932   { spu_emit_branch_or_set (0, operands[0], operands); DONE; })
3934 (define_expand "cbranchdf4"
3935   [(use (match_operator 0 "ordered_comparison_operator"
3936          [(match_operand:DF 1 "spu_reg_operand" "")
3937           (match_operand:DF 2 "spu_reg_operand" "")]))
3938    (use (match_operand 3 ""))]
3939   ""
3940   { spu_emit_branch_or_set (0, operands[0], operands); DONE; })
3943 ;; set on condition
3945 (define_expand "cstore<mode>4"
3946   [(use (match_operator 1 "ordered_comparison_operator"
3947          [(match_operand:VQHSI 2 "spu_reg_operand" "")
3948           (match_operand:VQHSI 3 "spu_nonmem_operand" "")]))
3949    (clobber (match_operand:SI 0 "spu_reg_operand"))]
3950   ""
3951   { spu_emit_branch_or_set (1, operands[1], operands); DONE; })
3953 (define_expand "cstore<mode>4"
3954   [(use (match_operator 1 "ordered_comparison_operator"
3955          [(match_operand:DTI 2 "spu_reg_operand" "")
3956           (match_operand:DTI 3 "spu_reg_operand" "")]))
3957    (clobber (match_operand:SI 0 "spu_reg_operand"))]
3958   ""
3959   { spu_emit_branch_or_set (1, operands[1], operands); DONE; })
3961 (define_expand "cstore<mode>4"
3962   [(use (match_operator 1 "ordered_comparison_operator"
3963          [(match_operand:VSF 2 "spu_reg_operand" "")
3964           (match_operand:VSF 3 "spu_reg_operand" "")]))
3965    (clobber (match_operand:SI 0 "spu_reg_operand"))]
3966   ""
3967   { spu_emit_branch_or_set (1, operands[1], operands); DONE; })
3969 (define_expand "cstoredf4"
3970   [(use (match_operator 1 "ordered_comparison_operator"
3971          [(match_operand:DF 2 "spu_reg_operand" "")
3972           (match_operand:DF 3 "spu_reg_operand" "")]))
3973    (clobber (match_operand:SI 0 "spu_reg_operand"))]
3974   ""
3975   { spu_emit_branch_or_set (1, operands[1], operands); DONE; })
3978 ;; conditional move
3980 ;; Define this first one so HAVE_conditional_move is defined.
3981 (define_insn "movcc_dummy"
3982   [(set (match_operand 0 "" "")
3983        (if_then_else (match_operand 1 "" "")
3984                      (match_operand 2 "" "")
3985                      (match_operand 3 "" "")))]
3986   "!operands[0]"
3987   "")
3989 (define_expand "mov<mode>cc"
3990   [(set (match_operand:ALL 0 "spu_reg_operand" "")
3991         (if_then_else:ALL (match_operand 1 "ordered_comparison_operator" "")
3992                       (match_operand:ALL 2 "spu_reg_operand" "")
3993                       (match_operand:ALL 3 "spu_reg_operand" "")))]
3994   ""
3995   {
3996     spu_emit_branch_or_set(2, operands[1], operands);
3997     DONE;
3998   })
4000 ;; This pattern is used when the result of a compare is not large
4001 ;; enough to use in a selb when expanding conditional moves.
4002 (define_expand "extend_compare"
4003   [(set (match_operand 0 "spu_reg_operand" "=r")
4004         (unspec [(match_operand 1 "spu_reg_operand" "r")] UNSPEC_EXTEND_CMP))]
4005   ""
4006   {
4007     emit_insn (gen_rtx_SET (VOIDmode, operands[0],
4008                             gen_rtx_UNSPEC (GET_MODE (operands[0]),
4009                                             gen_rtvec (1, operands[1]),
4010                                             UNSPEC_EXTEND_CMP)));
4011     DONE;
4012   })
4014 (define_insn "extend_compare<mode>"
4015   [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
4016         (unspec:ALL [(match_operand 1 "spu_reg_operand" "r")] UNSPEC_EXTEND_CMP))]
4017   "operands"
4018   "fsm\t%0,%1"
4019   [(set_attr "type" "shuf")])
4022 ;; case
4024 ;; operand 0 is index
4025 ;; operand 1 is the minimum bound
4026 ;; operand 2 is the maximum bound - minimum bound + 1
4027 ;; operand 3 is CODE_LABEL for the table;
4028 ;; operand 4 is the CODE_LABEL to go to if index out of range.
4029 (define_expand "casesi"
4030   [(match_operand:SI 0 "spu_reg_operand" "")
4031    (match_operand:SI 1 "immediate_operand" "")
4032    (match_operand:SI 2 "immediate_operand" "")
4033    (match_operand 3 "" "")
4034    (match_operand 4 "" "")]
4035   ""
4036   {
4037     rtx table = gen_reg_rtx (SImode);
4038     rtx index = gen_reg_rtx (SImode);
4039     rtx sindex = gen_reg_rtx (SImode);
4040     rtx addr = gen_reg_rtx (Pmode);
4042     emit_move_insn (table, gen_rtx_LABEL_REF (SImode, operands[3]));
4044     emit_insn (gen_subsi3(index, operands[0], force_reg(SImode, operands[1])));
4045     emit_insn (gen_ashlsi3(sindex, index, GEN_INT (2)));
4046     emit_move_insn (addr, gen_rtx_MEM (SImode,
4047                                        gen_rtx_PLUS (SImode, table, sindex)));
4048     if (flag_pic)
4049       emit_insn (gen_addsi3 (addr, addr, table));
4051     emit_cmp_and_jump_insns (index, operands[2], GTU, NULL_RTX, SImode, 1, operands[4]);
4052     emit_jump_insn (gen_tablejump (addr, operands[3]));
4053     DONE;
4054   })
4056 (define_insn "tablejump"
4057   [(set (pc) (match_operand:SI 0 "spu_reg_operand" "r"))
4058    (use (label_ref (match_operand 1 "" "")))]
4059   ""
4060   "bi\t%0"
4061   [(set_attr "type" "br")])
4064 ;; call
4066 ;; Note that operand 1 is total size of args, in bytes,
4067 ;; and what the call insn wants is the number of words.
4068 (define_expand "sibcall"
4069   [(parallel
4070     [(call (match_operand:QI 0 "call_operand" "")
4071            (match_operand:QI 1 "" ""))
4072      (use (reg:SI 0))])]
4073   ""
4074   {
4075     if (! call_operand (operands[0], QImode))
4076       XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
4077   })
4079 (define_insn "_sibcall"
4080   [(parallel
4081     [(call (match_operand:QI 0 "call_operand" "R,S")
4082            (match_operand:QI 1 "" "i,i"))
4083      (use (reg:SI 0))])]
4084   "SIBLING_CALL_P(insn)"
4085   "@
4086    bi\t%i0
4087    br\t%0"
4088    [(set_attr "type" "br,br")])
4090 (define_expand "sibcall_value"
4091   [(parallel
4092     [(set (match_operand 0 "" "")
4093           (call (match_operand:QI 1 "call_operand" "")
4094                 (match_operand:QI 2 "" "")))
4095      (use (reg:SI 0))])]
4096   ""
4097   {
4098     if (! call_operand (operands[1], QImode))
4099       XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
4100   })
4102 (define_insn "_sibcall_value"
4103   [(parallel
4104     [(set (match_operand 0 "" "")
4105           (call (match_operand:QI 1 "call_operand" "R,S")
4106                 (match_operand:QI 2 "" "i,i")))
4107      (use (reg:SI 0))])]
4108   "SIBLING_CALL_P(insn)"
4109   "@
4110    bi\t%i1
4111    br\t%1"
4112    [(set_attr "type" "br,br")])
4114 ;; Note that operand 1 is total size of args, in bytes,
4115 ;; and what the call insn wants is the number of words.
4116 (define_expand "call"
4117   [(parallel
4118     [(call (match_operand:QI 0 "call_operand" "")
4119            (match_operand:QI 1 "" ""))
4120      (clobber (reg:SI 0))
4121      (clobber (reg:SI 130))])]
4122   ""
4123   {
4124     if (! call_operand (operands[0], QImode))
4125       XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
4126   })
4128 (define_insn "_call"
4129   [(parallel
4130     [(call (match_operand:QI 0 "call_operand" "R,S,T")
4131            (match_operand:QI 1 "" "i,i,i"))
4132      (clobber (reg:SI 0))
4133      (clobber (reg:SI 130))])]
4134   ""
4135   "@
4136    bisl\t$lr,%i0
4137    brsl\t$lr,%0
4138    brasl\t$lr,%0"
4139    [(set_attr "type" "br")])
4141 (define_expand "call_value"
4142   [(parallel
4143     [(set (match_operand 0 "" "")
4144           (call (match_operand:QI 1 "call_operand" "")
4145                 (match_operand:QI 2 "" "")))
4146      (clobber (reg:SI 0))
4147      (clobber (reg:SI 130))])]
4148   ""
4149   {
4150     if (! call_operand (operands[1], QImode))
4151       XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
4152   })
4154 (define_insn "_call_value"
4155   [(parallel
4156     [(set (match_operand 0 "" "")
4157           (call (match_operand:QI 1 "call_operand" "R,S,T")
4158                 (match_operand:QI 2 "" "i,i,i")))
4159      (clobber (reg:SI 0))
4160      (clobber (reg:SI 130))])]
4161   ""
4162   "@
4163    bisl\t$lr,%i1
4164    brsl\t$lr,%1
4165    brasl\t$lr,%1"
4166    [(set_attr "type" "br")])
4168 (define_expand "untyped_call"
4169   [(parallel [(call (match_operand 0 "" "")
4170                     (const_int 0))
4171               (match_operand 1 "" "")
4172               (match_operand 2 "" "")])]
4173   ""
4174   {
4175     int i;
4176     rtx reg = gen_rtx_REG (TImode, 3);
4178     /* We need to use call_value so the return value registers don't get
4179      * clobbered. */
4180     emit_call_insn (gen_call_value (reg, operands[0], const0_rtx));
4182     for (i = 0; i < XVECLEN (operands[2], 0); i++)
4183       {
4184         rtx set = XVECEXP (operands[2], 0, i);
4185         emit_move_insn (SET_DEST (set), SET_SRC (set));
4186       }
4188     /* The optimizer does not know that the call sets the function value
4189        registers we stored in the result block.  We avoid problems by
4190        claiming that all hard registers are used and clobbered at this
4191        point.  */
4192     emit_insn (gen_blockage ());
4194     DONE;
4195   })
4198 ;; Patterns used for splitting and combining.
4201 ;; Function prologue and epilogue.
4203 (define_expand "prologue"
4204   [(const_int 1)]
4205   ""
4206   { spu_expand_prologue (); DONE; })
4208 ;; "blockage" is only emited in epilogue.  This is what it took to
4209 ;; make "basic block reordering" work with the insns sequence
4210 ;; generated by the spu_expand_epilogue (taken from mips.md)
4212 (define_insn "blockage"
4213   [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
4214   ""
4215   ""
4216   [(set_attr "type" "convert")
4217    (set_attr "length" "0")])
4219 (define_expand "epilogue"
4220   [(const_int 2)]
4221   ""
4222   { spu_expand_epilogue (false); DONE; })
4224 (define_expand "sibcall_epilogue"
4225   [(const_int 2)]
4226   ""
4227   { spu_expand_epilogue (true); DONE; })
4230 ;; stack manipulations
4232 ;; An insn to allocate new stack space for dynamic use (e.g., alloca).
4233 ;; We move the back-chain and decrement the stack pointer.
4234 (define_expand "allocate_stack"
4235   [(set (match_operand 0 "spu_reg_operand" "")
4236         (minus (reg 1) (match_operand 1 "spu_nonmem_operand" "")))
4237    (set (reg 1)
4238         (minus (reg 1) (match_dup 1)))]
4239   ""
4240   "spu_allocate_stack (operands[0], operands[1]); DONE;")
4242 ;; These patterns say how to save and restore the stack pointer.  We need not
4243 ;; save the stack pointer at function level since we are careful to preserve 
4244 ;; the backchain.  
4245 ;; 
4247 ;; At block level the stack pointer is saved and restored, so that the
4248 ;; stack space allocated within a block is deallocated when leaving
4249 ;; block scope.  By default, according to the SPU ABI, the stack
4250 ;; pointer and available stack size are saved in a register. Upon
4251 ;; restoration, the stack pointer is simply copied back, and the
4252 ;; current available stack size is calculated against the restored
4253 ;; stack pointer.
4255 ;; For nonlocal gotos, we must save the stack pointer and its
4256 ;; backchain and restore both.  Note that in the nonlocal case, the
4257 ;; save area is a memory location.
4259 (define_expand "save_stack_function"
4260   [(match_operand 0 "general_operand" "")
4261    (match_operand 1 "general_operand" "")]
4262   ""
4263   "DONE;")
4265 (define_expand "restore_stack_function"
4266   [(match_operand 0 "general_operand" "")
4267    (match_operand 1 "general_operand" "")]
4268   ""
4269   "DONE;")
4271 (define_expand "restore_stack_block"
4272   [(match_operand 0 "spu_reg_operand" "")
4273    (match_operand 1 "memory_operand" "")]
4274   ""
4275   "
4276   {
4277     spu_restore_stack_block (operands[0], operands[1]);
4278     DONE;
4279   }")
4281 (define_expand "save_stack_nonlocal"
4282   [(match_operand 0 "memory_operand" "")
4283    (match_operand 1 "spu_reg_operand" "")]
4284   ""
4285   "
4286   {
4287     rtx temp = gen_reg_rtx (Pmode);
4289     /* Copy the backchain to the first word, sp to the second.  We need to
4290        save the back chain because __builtin_apply appears to clobber it. */
4291     emit_move_insn (temp, gen_rtx_MEM (Pmode, operands[1]));
4292     emit_move_insn (adjust_address_nv (operands[0], SImode, 0), temp);
4293     emit_move_insn (adjust_address_nv (operands[0], SImode, 4), operands[1]);
4294     DONE;
4295   }")
4297 (define_expand "restore_stack_nonlocal"
4298   [(match_operand 0 "spu_reg_operand" "")
4299    (match_operand 1 "memory_operand" "")]
4300   ""
4301   "
4302   {
4303     spu_restore_stack_nonlocal(operands[0], operands[1]);
4304     DONE;
4305   }")
4308 ;; vector patterns
4310 ;; Vector initialization
4311 (define_expand "vec_init<mode>"
4312   [(match_operand:V 0 "register_operand" "")
4313    (match_operand 1 "" "")]
4314   ""
4315   {
4316     spu_expand_vector_init (operands[0], operands[1]);
4317     DONE;
4318   })
4320 (define_expand "vec_set<mode>"
4321   [(use (match_operand:SI 2 "spu_nonmem_operand" ""))
4322    (set (match_dup:TI 3)
4323         (unspec:TI [(match_dup:SI 4)
4324                     (match_dup:SI 5)
4325                     (match_dup:SI 6)] UNSPEC_CPAT))
4326    (set (match_operand:V 0 "spu_reg_operand" "")
4327         (unspec:V [(match_operand:<inner> 1 "spu_reg_operand" "")
4328                    (match_dup:V 0)
4329                    (match_dup:TI 3)] UNSPEC_SHUFB))]
4330   ""
4331   {
4332     HOST_WIDE_INT size = GET_MODE_SIZE (<inner>mode);
4333     rtx offset = GEN_INT (INTVAL (operands[2]) * size);
4334     operands[3] = gen_reg_rtx (TImode);
4335     operands[4] = stack_pointer_rtx;
4336     operands[5] = offset;
4337     operands[6] = GEN_INT (size);
4338   })
4340 (define_expand "vec_extract<mode>"
4341   [(set (match_operand:<inner> 0 "spu_reg_operand" "=r")
4342         (vec_select:<inner> (match_operand:V 1 "spu_reg_operand" "r")
4343                             (parallel [(match_operand 2 "const_int_operand" "i")])))]
4344   ""
4345   {
4346     if ((INTVAL (operands[2]) * <vmult> + <voff>) % 16 == 0)
4347       {
4348         emit_insn (gen_spu_convert (operands[0], operands[1]));
4349         DONE;
4350       }
4351   })
4353 (define_insn "_vec_extract<mode>"
4354   [(set (match_operand:<inner> 0 "spu_reg_operand" "=r")
4355         (vec_select:<inner> (match_operand:V 1 "spu_reg_operand" "r")
4356                             (parallel [(match_operand 2 "const_int_operand" "i")])))]
4357   ""
4358   "rotqbyi\t%0,%1,(%2*<vmult>+<voff>)%%16"
4359   [(set_attr "type" "shuf")])
4361 (define_insn "_vec_extractv8hi_ze"
4362   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
4363         (zero_extend:SI (vec_select:HI (match_operand:V8HI 1 "spu_reg_operand" "r")
4364                                        (parallel [(const_int 0)]))))]
4365   ""
4366   "rotqmbyi\t%0,%1,-2"
4367   [(set_attr "type" "shuf")])
4370 ;; misc
4372 (define_expand "shufb"
4373   [(set (match_operand 0 "spu_reg_operand" "")
4374         (unspec [(match_operand 1 "spu_reg_operand" "")
4375                  (match_operand 2 "spu_reg_operand" "")
4376                  (match_operand:TI 3 "spu_reg_operand" "")] UNSPEC_SHUFB))]
4377   ""
4378   {
4379     rtx s = gen__shufb (operands[0], operands[1], operands[2], operands[3]);
4380     PUT_MODE (SET_SRC (s), GET_MODE (operands[0]));
4381     emit_insn (s);
4382     DONE;
4383   })
4385 (define_insn "_shufb"
4386   [(set (match_operand 0 "spu_reg_operand" "=r")
4387         (unspec [(match_operand 1 "spu_reg_operand" "r")
4388                  (match_operand 2 "spu_reg_operand" "r")
4389                  (match_operand:TI 3 "spu_reg_operand" "r")] UNSPEC_SHUFB))]
4390   "operands"
4391   "shufb\t%0,%1,%2,%3"
4392   [(set_attr "type" "shuf")])
4394 (define_insn "nop"
4395   [(unspec_volatile [(const_int 0)] UNSPEC_NOP)]
4396   ""
4397   "nop"
4398   [(set_attr "type" "nop")])
4400 (define_insn "nopn"
4401   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "K")] UNSPEC_NOP)]
4402   ""
4403   "nop\t%0"
4404   [(set_attr "type" "nop")])
4406 (define_insn "lnop"
4407   [(unspec_volatile [(const_int 0)] UNSPEC_LNOP)]
4408   ""
4409   "lnop"
4410   [(set_attr "type" "lnop")])
4412 ;; The operand is so we know why we generated this hbrp.
4413 ;; We clobber mem to make sure it isn't moved over any
4414 ;; loads, stores or calls while scheduling.
4415 (define_insn "iprefetch"
4416   [(unspec [(match_operand:SI 0 "const_int_operand" "n")] UNSPEC_IPREFETCH)
4417    (clobber (mem:BLK (scratch)))]
4418   ""
4419   "hbrp\t# %0"
4420   [(set_attr "type" "iprefetch")])
4422 ;; A non-volatile version so it gets scheduled
4423 (define_insn "nopn_nv"
4424   [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_NOP)]
4425   ""
4426   "nop\t%0"
4427   [(set_attr "type" "nop")])
4429 (define_insn "hbr"
4430   [(set (reg:SI 130)
4431         (unspec:SI [(match_operand:SI 0 "immediate_operand" "i,i,i")
4432                     (match_operand:SI 1 "nonmemory_operand" "r,s,i")] UNSPEC_HBR))
4433    (unspec [(const_int 0)] UNSPEC_HBR)]
4434   ""
4435   "@
4436    hbr\t%0,%1
4437    hbrr\t%0,%1
4438    hbra\t%0,%1"
4439   [(set_attr "type" "hbr")])
4441 (define_insn "sync"
4442   [(unspec_volatile [(const_int 0)] UNSPEC_SYNC)
4443    (clobber (mem:BLK (scratch)))]
4444   ""
4445   "sync"
4446   [(set_attr "type" "br")])
4448 (define_insn "syncc"
4449   [(unspec_volatile [(const_int 1)] UNSPEC_SYNC)
4450    (clobber (mem:BLK (scratch)))]
4451   ""
4452   "syncc"
4453   [(set_attr "type" "br")])
4455 (define_insn "dsync"
4456   [(unspec_volatile [(const_int 2)] UNSPEC_SYNC)
4457    (clobber (mem:BLK (scratch)))]
4458   ""
4459   "dsync"
4460   [(set_attr "type" "br")])
4464  ;; Define the subtract-one-and-jump insns so loop.c
4465  ;; knows what to generate.
4466  (define_expand "doloop_end"
4467    [(use (match_operand 0 "" ""))      ; loop pseudo
4468     (use (match_operand 1 "" ""))      ; iterations; zero if unknown
4469     (use (match_operand 2 "" ""))      ; max iterations
4470     (use (match_operand 3 "" ""))      ; loop level
4471     (use (match_operand 4 "" ""))]     ; label
4472    ""
4473    "
4475    /* Currently SMS relies on the do-loop pattern to recognize loops
4476       where (1) the control part comprises of all insns defining and/or
4477       using a certain 'count' register and (2) the loop count can be
4478       adjusted by modifying this register prior to the loop.
4479 .     ??? The possible introduction of a new block to initialize the
4480       new IV can potentially effects branch optimizations.  */
4481    if (optimize > 0 && flag_modulo_sched)
4482    {
4483      rtx s0;
4484      rtx bcomp;
4485      rtx loc_ref;
4487      /* Only use this on innermost loops.  */
4488      if (INTVAL (operands[3]) > 1)
4489        FAIL;
4490      if (GET_MODE (operands[0]) != SImode)
4491        FAIL;
4493      s0 = operands [0];
4494      emit_move_insn (s0, gen_rtx_PLUS (SImode, s0, GEN_INT (-1)));
4495      bcomp = gen_rtx_NE(SImode, s0, const0_rtx);
4496      loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands [4]);
4497      emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
4498                                   gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp,
4499                                                         loc_ref, pc_rtx)));
4501      DONE;
4502    }else
4503       FAIL;
4504  }")
4506 ;; convert between any two modes, avoiding any GCC assumptions
4507 (define_expand "spu_convert"
4508   [(set (match_operand 0 "spu_reg_operand" "")
4509         (unspec [(match_operand 1 "spu_reg_operand" "")] UNSPEC_CONVERT))]
4510   ""
4511   {
4512     rtx c = gen__spu_convert (operands[0], operands[1]);
4513     PUT_MODE (SET_SRC (c), GET_MODE (operands[0]));
4514     emit_insn (c);
4515     DONE;
4516   })
4518 (define_insn_and_split "_spu_convert"
4519   [(set (match_operand 0 "spu_reg_operand" "=r")
4520         (unspec [(match_operand 1 "spu_reg_operand" "0")] UNSPEC_CONVERT))]
4521   ""
4522   "#"
4523   "reload_completed"
4524   [(const_int 0)]
4525   {
4526     spu_split_convert (operands);
4527     DONE;
4528   }
4529   [(set_attr "type" "convert")
4530    (set_attr "length" "0")])
4534 (include "spu-builtins.md")
4536   
4537 (define_expand "smaxv4sf3"
4538   [(set (match_operand:V4SF 0 "register_operand" "=r")
4539         (smax:V4SF (match_operand:V4SF 1 "register_operand" "r")
4540                  (match_operand:V4SF 2 "register_operand" "r")))]
4541   ""
4542   "
4544   rtx mask = gen_reg_rtx (V4SImode);
4546   emit_insn (gen_cgt_v4sf (mask, operands[1], operands[2]));
4547   emit_insn (gen_selb (operands[0], operands[2], operands[1], mask));
4548   DONE;
4549 }") 
4551 (define_expand "sminv4sf3"
4552   [(set (match_operand:V4SF 0 "register_operand" "=r")
4553         (smin:V4SF (match_operand:V4SF 1 "register_operand" "r")
4554                  (match_operand:V4SF 2 "register_operand" "r")))]
4555   ""
4556   "
4558   rtx mask = gen_reg_rtx (V4SImode);
4560   emit_insn (gen_cgt_v4sf (mask, operands[1], operands[2]));
4561   emit_insn (gen_selb (operands[0], operands[1], operands[2], mask));
4562   DONE;
4563 }") 
4565 (define_expand "smaxv2df3"
4566   [(set (match_operand:V2DF 0 "register_operand" "=r")
4567         (smax:V2DF (match_operand:V2DF 1 "register_operand" "r")
4568                  (match_operand:V2DF 2 "register_operand" "r")))]
4569   ""
4570   "
4572   rtx mask = gen_reg_rtx (V2DImode);
4573   emit_insn (gen_cgt_v2df (mask, operands[1], operands[2]));
4574   emit_insn (gen_selb (operands[0], operands[2], operands[1], 
4575                        spu_gen_subreg (V4SImode, mask)));
4576   DONE;
4579 (define_expand "sminv2df3"
4580   [(set (match_operand:V2DF 0 "register_operand" "=r")
4581         (smin:V2DF (match_operand:V2DF 1 "register_operand" "r")
4582                  (match_operand:V2DF 2 "register_operand" "r")))]
4583   ""
4584   "
4586   rtx mask = gen_reg_rtx (V2DImode);
4587   emit_insn (gen_cgt_v2df (mask, operands[1], operands[2]));
4588   emit_insn (gen_selb (operands[0], operands[1], operands[2], 
4589                        spu_gen_subreg (V4SImode, mask)));
4590   DONE;
4593 (define_expand "vec_widen_umult_hi_v8hi"
4594   [(set (match_operand:V4SI 0 "register_operand"   "=r")
4595         (mult:V4SI
4596           (zero_extend:V4SI
4597             (vec_select:V4HI
4598               (match_operand:V8HI 1 "register_operand" "r")
4599               (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)])))
4600           (zero_extend:V4SI
4601             (vec_select:V4HI
4602               (match_operand:V8HI 2 "register_operand" "r")
4603               (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)])))))]
4604   ""
4605   "
4607   rtx ve = gen_reg_rtx (V4SImode);
4608   rtx vo = gen_reg_rtx (V4SImode);
4609   rtx mask = gen_reg_rtx (TImode);
4610   unsigned char arr[16] = {
4611     0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13, 
4612     0x04, 0x05, 0x06, 0x07, 0x14, 0x15, 0x16, 0x17};
4613   
4614   emit_move_insn (mask, array_to_constant (TImode, arr));
4615   emit_insn (gen_spu_mpyhhu (ve, operands[1], operands[2]));
4616   emit_insn (gen_spu_mpyu (vo, operands[1], operands[2]));
4617   emit_insn (gen_shufb (operands[0], ve, vo, mask));
4618   DONE;
4621 (define_expand "vec_widen_umult_lo_v8hi"
4622   [(set (match_operand:V4SI 0 "register_operand"   "=r")
4623         (mult:V4SI
4624           (zero_extend:V4SI
4625             (vec_select:V4HI
4626               (match_operand:V8HI 1 "register_operand" "r")
4627               (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)])))
4628           (zero_extend:V4SI
4629             (vec_select:V4HI
4630               (match_operand:V8HI 2 "register_operand" "r")
4631               (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)])))))]
4632   ""
4633   "
4635   rtx ve = gen_reg_rtx (V4SImode);
4636   rtx vo = gen_reg_rtx (V4SImode);
4637   rtx mask = gen_reg_rtx (TImode);
4638   unsigned char arr[16] = {
4639     0x08, 0x09, 0x0A, 0x0B, 0x18, 0x19, 0x1A, 0x1B, 
4640     0x0C, 0x0D, 0x0E, 0x0F, 0x1C, 0x1D, 0x1E, 0x1F};
4642   emit_move_insn (mask, array_to_constant (TImode, arr));
4643   emit_insn (gen_spu_mpyhhu (ve, operands[1], operands[2]));
4644   emit_insn (gen_spu_mpyu (vo, operands[1], operands[2]));
4645   emit_insn (gen_shufb (operands[0], ve, vo, mask));
4646   DONE;
4649 (define_expand "vec_widen_smult_hi_v8hi"
4650   [(set (match_operand:V4SI 0 "register_operand"   "=r")
4651         (mult:V4SI
4652           (sign_extend:V4SI
4653             (vec_select:V4HI
4654               (match_operand:V8HI 1 "register_operand" "r")
4655               (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)])))
4656           (sign_extend:V4SI
4657             (vec_select:V4HI
4658               (match_operand:V8HI 2 "register_operand" "r")
4659               (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)])))))]
4660   ""
4661   "
4663   rtx ve = gen_reg_rtx (V4SImode);
4664   rtx vo = gen_reg_rtx (V4SImode);
4665   rtx mask = gen_reg_rtx (TImode);
4666   unsigned char arr[16] = {
4667     0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13, 
4668     0x04, 0x05, 0x06, 0x07, 0x14, 0x15, 0x16, 0x17};
4669   
4670   emit_move_insn (mask, array_to_constant (TImode, arr));
4671   emit_insn (gen_spu_mpyhh (ve, operands[1], operands[2]));
4672   emit_insn (gen_spu_mpy (vo, operands[1], operands[2]));
4673   emit_insn (gen_shufb (operands[0], ve, vo, mask));
4674   DONE;
4677 (define_expand "vec_widen_smult_lo_v8hi"
4678   [(set (match_operand:V4SI 0 "register_operand"   "=r")
4679         (mult:V4SI
4680           (sign_extend:V4SI
4681             (vec_select:V4HI
4682               (match_operand:V8HI 1 "register_operand" "r")
4683               (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)])))
4684           (sign_extend:V4SI
4685             (vec_select:V4HI
4686               (match_operand:V8HI 2 "register_operand" "r")
4687               (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)])))))]
4688   ""
4689   "
4691   rtx ve = gen_reg_rtx (V4SImode);
4692   rtx vo = gen_reg_rtx (V4SImode);
4693   rtx mask = gen_reg_rtx (TImode);
4694   unsigned char arr[16] = {
4695     0x08, 0x09, 0x0A, 0x0B, 0x18, 0x19, 0x1A, 0x1B, 
4696     0x0C, 0x0D, 0x0E, 0x0F, 0x1C, 0x1D, 0x1E, 0x1F};
4698   emit_move_insn (mask, array_to_constant (TImode, arr));
4699   emit_insn (gen_spu_mpyhh (ve, operands[1], operands[2]));
4700   emit_insn (gen_spu_mpy (vo, operands[1], operands[2]));
4701   emit_insn (gen_shufb (operands[0], ve, vo, mask));
4702   DONE;
4705 (define_expand "vec_realign_load_<mode>"
4706   [(set (match_operand:ALL 0 "register_operand" "=r")
4707         (unspec:ALL [(match_operand:ALL 1 "register_operand" "r")
4708                      (match_operand:ALL 2 "register_operand" "r")
4709                      (match_operand:TI 3 "register_operand" "r")] UNSPEC_SPU_REALIGN_LOAD))]
4710   ""
4711   "
4713   emit_insn (gen_shufb (operands[0], operands[1], operands[2], operands[3])); 
4714   DONE;
4717 (define_expand "spu_lvsr"
4718   [(set (match_operand:V16QI 0 "register_operand" "")
4719         (unspec:V16QI [(match_operand 1 "memory_operand" "")] UNSPEC_SPU_MASK_FOR_LOAD))]
4720   ""
4721   "
4723   rtx addr;
4724   rtx offset = gen_reg_rtx (V8HImode);
4725   rtx addr_bits = gen_reg_rtx (SImode);
4726   rtx addr_bits_vec = gen_reg_rtx (V8HImode);
4727   rtx splatqi = gen_reg_rtx (TImode);
4728   rtx result = gen_reg_rtx (V8HImode);
4729   unsigned char arr[16] = {
4730     0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 
4731     0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F};
4732   unsigned char arr2[16] = {
4733     0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 
4734     0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03};
4736   emit_move_insn (offset, array_to_constant (V8HImode, arr));
4737   emit_move_insn (splatqi, array_to_constant (TImode, arr2));
4739   gcc_assert (GET_CODE (operands[1]) == MEM);
4740   addr = force_reg (Pmode, XEXP (operands[1], 0));
4741   emit_insn (gen_andsi3 (addr_bits, addr, GEN_INT (0xF))); 
4742   emit_insn (gen_shufb (addr_bits_vec, addr_bits, addr_bits, splatqi));
4744   /* offset - (addr & 0xF) 
4745      It is safe to use a single sfh, because each byte of offset is > 15 and
4746      each byte of addr is <= 15. */
4747   emit_insn (gen_subv8hi3 (result, offset, addr_bits_vec));
4749   result = simplify_gen_subreg (V16QImode, result, V8HImode, 0);
4750   emit_move_insn (operands[0], result);
4752   DONE;
4755 (define_expand "vec_unpacku_hi_v8hi"
4756   [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
4757         (zero_extend:V4SI 
4758           (vec_select:V4HI
4759             (match_operand:V8HI 1 "spu_reg_operand" "r")
4760             (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)]))))]
4761   ""
4763   rtx mask = gen_reg_rtx (TImode);
4764   unsigned char arr[16] = {
4765     0x80, 0x80, 0x00, 0x01, 0x80, 0x80, 0x02, 0x03,
4766     0x80, 0x80, 0x04, 0x05, 0x80, 0x80, 0x06, 0x07};
4768   emit_move_insn (mask, array_to_constant (TImode, arr));
4769   emit_insn (gen_shufb (operands[0], operands[1], operands[1], mask));
4771   DONE;
4774 (define_expand "vec_unpacku_lo_v8hi"
4775   [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
4776          (zero_extend:V4SI
4777           (vec_select:V4HI
4778             (match_operand:V8HI 1 "spu_reg_operand" "r")
4779             (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)]))))]
4782   rtx mask = gen_reg_rtx (TImode);
4783   unsigned char arr[16] = {
4784     0x80, 0x80, 0x08, 0x09, 0x80, 0x80, 0x0A, 0x0B,
4785     0x80, 0x80, 0x0C, 0x0D, 0x80, 0x80, 0x0E, 0x0F};
4787   emit_move_insn (mask, array_to_constant (TImode, arr));
4788   emit_insn (gen_shufb (operands[0], operands[1], operands[1], mask));
4789   
4790   DONE;
4793 (define_expand "vec_unpacks_hi_v8hi"
4794   [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
4795          (sign_extend:V4SI
4796           (vec_select:V4HI
4797             (match_operand:V8HI 1 "spu_reg_operand" "r")
4798             (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)]))))]
4799   ""
4801   rtx tmp1 = gen_reg_rtx (V8HImode);
4802   rtx tmp2 = gen_reg_rtx (V4SImode);
4803   rtx mask = gen_reg_rtx (TImode);
4804   unsigned char arr[16] = {
4805     0x80, 0x80, 0x00, 0x01, 0x80, 0x80, 0x02, 0x03,
4806     0x80, 0x80, 0x04, 0x05, 0x80, 0x80, 0x06, 0x07};
4808   emit_move_insn (mask, array_to_constant (TImode, arr));
4809   emit_insn (gen_shufb (tmp1, operands[1], operands[1], mask));
4810   emit_insn (gen_spu_xshw (tmp2, tmp1)); 
4811   emit_move_insn (operands[0], tmp2);
4813   DONE;
4816 (define_expand "vec_unpacks_lo_v8hi"
4817   [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
4818          (sign_extend:V4SI
4819           (vec_select:V4HI
4820             (match_operand:V8HI 1 "spu_reg_operand" "r")
4821             (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)]))))]
4824   rtx tmp1 = gen_reg_rtx (V8HImode);
4825   rtx tmp2 = gen_reg_rtx (V4SImode);
4826   rtx mask = gen_reg_rtx (TImode);
4827   unsigned char arr[16] = {
4828     0x80, 0x80, 0x08, 0x09, 0x80, 0x80, 0x0A, 0x0B,
4829     0x80, 0x80, 0x0C, 0x0D, 0x80, 0x80, 0x0E, 0x0F};
4831   emit_move_insn (mask, array_to_constant (TImode, arr));
4832   emit_insn (gen_shufb (tmp1, operands[1], operands[1], mask));
4833   emit_insn (gen_spu_xshw (tmp2, tmp1)); 
4834   emit_move_insn (operands[0], tmp2);
4836 DONE;
4839 (define_expand "vec_unpacku_hi_v16qi"
4840   [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
4841         (zero_extend:V8HI
4842           (vec_select:V8QI
4843             (match_operand:V16QI 1 "spu_reg_operand" "r")
4844             (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)
4845                        (const_int 4)(const_int 5)(const_int 6)(const_int 7)]))))]
4846   ""
4848   rtx mask = gen_reg_rtx (TImode);
4849   unsigned char arr[16] = {
4850     0x80, 0x00, 0x80, 0x01, 0x80, 0x02, 0x80, 0x03,
4851     0x80, 0x04, 0x80, 0x05, 0x80, 0x06, 0x80, 0x07};
4853   emit_move_insn (mask, array_to_constant (TImode, arr));
4854   emit_insn (gen_shufb (operands[0], operands[1], operands[1], mask));
4856   DONE;
4859 (define_expand "vec_unpacku_lo_v16qi"
4860   [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
4861           (zero_extend:V8HI
4862           (vec_select:V8QI
4863             (match_operand:V16QI 1 "spu_reg_operand" "r")
4864             (parallel [(const_int 8)(const_int 9)(const_int 10)(const_int 11)
4865                        (const_int 12)(const_int 13)(const_int 14)(const_int 15)]))))]
4868   rtx mask = gen_reg_rtx (TImode);
4869   unsigned char arr[16] = {
4870     0x80, 0x08, 0x80, 0x09, 0x80, 0x0A, 0x80, 0x0B,
4871     0x80, 0x0C, 0x80, 0x0D, 0x80, 0x0E, 0x80, 0x0F};
4873   emit_move_insn (mask, array_to_constant (TImode, arr));
4874   emit_insn (gen_shufb (operands[0], operands[1], operands[1], mask));
4876   DONE;
4879 (define_expand "vec_unpacks_hi_v16qi"
4880   [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
4881          (sign_extend:V8HI
4882           (vec_select:V8QI
4883             (match_operand:V16QI 1 "spu_reg_operand" "r")
4884             (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)
4885                        (const_int 4)(const_int 5)(const_int 6)(const_int 7)]))))]
4888   rtx tmp1 = gen_reg_rtx (V16QImode);
4889   rtx tmp2 = gen_reg_rtx (V8HImode);
4890   rtx mask = gen_reg_rtx (TImode);
4891   unsigned char arr[16] = {
4892     0x80, 0x00, 0x80, 0x01, 0x80, 0x02, 0x80, 0x03,
4893     0x80, 0x04, 0x80, 0x05, 0x80, 0x06, 0x80, 0x07};
4895   emit_move_insn (mask, array_to_constant (TImode, arr));
4896   emit_insn (gen_shufb (tmp1, operands[1], operands[1], mask));
4897   emit_insn (gen_spu_xsbh (tmp2, tmp1));
4898   emit_move_insn (operands[0], tmp2);
4900   DONE;
4903 (define_expand "vec_unpacks_lo_v16qi"
4904   [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
4905          (sign_extend:V8HI
4906           (vec_select:V8QI
4907             (match_operand:V16QI 1 "spu_reg_operand" "r")
4908             (parallel [(const_int 8)(const_int 9)(const_int 10)(const_int 11)
4909                        (const_int 12)(const_int 13)(const_int 14)(const_int 15)]))))]
4912   rtx tmp1 = gen_reg_rtx (V16QImode);
4913   rtx tmp2 = gen_reg_rtx (V8HImode);
4914   rtx mask = gen_reg_rtx (TImode);
4915   unsigned char arr[16] = {
4916     0x80, 0x08, 0x80, 0x09, 0x80, 0x0A, 0x80, 0x0B,
4917     0x80, 0x0C, 0x80, 0x0D, 0x80, 0x0E, 0x80, 0x0F};
4919   emit_move_insn (mask, array_to_constant (TImode, arr));
4920   emit_insn (gen_shufb (tmp1, operands[1], operands[1], mask));
4921   emit_insn (gen_spu_xsbh (tmp2, tmp1));
4922   emit_move_insn (operands[0], tmp2);
4924 DONE;
4928 (define_expand "vec_extract_evenv4si"
4929  [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
4930        (vec_concat:V4SI
4931          (vec_select:V2SI
4932            (match_operand:V4SI 1 "spu_reg_operand" "r")
4933            (parallel [(const_int 0)(const_int 2)]))
4934          (vec_select:V2SI
4935            (match_operand:V4SI 2 "spu_reg_operand" "r")
4936            (parallel [(const_int 0)(const_int 2)]))))]
4938   ""
4939   "
4941   rtx mask = gen_reg_rtx (TImode);
4942   unsigned char arr[16] = {
4943         0x00, 0x01, 0x02, 0x03,
4944         0x08, 0x09, 0x0A, 0x0B,
4945         0x10, 0x11, 0x12, 0x13,
4946         0x18, 0x19, 0x1A, 0x1B};        
4948   emit_move_insn (mask, array_to_constant (TImode, arr));
4949   emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
4950   DONE;
4954 (define_expand "vec_extract_evenv4sf"
4955  [(set (match_operand:V4SF 0 "spu_reg_operand" "=r")
4956        (vec_concat:V4SF
4957          (vec_select:V2SF
4958            (match_operand:V4SF 1 "spu_reg_operand" "r")
4959            (parallel [(const_int 0)(const_int 2)]))
4960          (vec_select:V2SF
4961            (match_operand:V4SF 2 "spu_reg_operand" "r")
4962            (parallel [(const_int 0)(const_int 2)]))))]
4964   ""
4965   "
4967   rtx mask = gen_reg_rtx (TImode);
4968   unsigned char arr[16] = {
4969         0x00, 0x01, 0x02, 0x03,
4970         0x08, 0x09, 0x0A, 0x0B,
4971         0x10, 0x11, 0x12, 0x13,
4972         0x18, 0x19, 0x1A, 0x1B};
4974   emit_move_insn (mask, array_to_constant (TImode, arr));
4975   emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
4976   DONE;
4979 (define_expand "vec_extract_evenv8hi"
4980  [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
4981        (vec_concat:V8HI
4982          (vec_select:V4HI
4983            (match_operand:V8HI 1 "spu_reg_operand" "r")
4984            (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)]))
4985          (vec_select:V4HI
4986            (match_operand:V8HI 2 "spu_reg_operand" "r")
4987            (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)]))))]
4989   ""
4990   "
4992   rtx mask = gen_reg_rtx (TImode);
4993   unsigned char arr[16] = {
4994         0x00, 0x01, 0x04, 0x05,
4995         0x08, 0x09, 0x0C, 0x0D,
4996         0x10, 0x11, 0x14, 0x15,
4997         0x18, 0x19, 0x1C, 0x1D};
4999   emit_move_insn (mask, array_to_constant (TImode, arr));
5000   emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5001   DONE;
5004 (define_expand "vec_extract_evenv16qi"
5005  [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
5006        (vec_concat:V16QI
5007          (vec_select:V8QI
5008            (match_operand:V16QI 1 "spu_reg_operand" "r")
5009            (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)
5010                       (const_int 8)(const_int 10)(const_int 12)(const_int 14)]))
5011          (vec_select:V8QI
5012            (match_operand:V16QI 2 "spu_reg_operand" "r")
5013            (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)
5014                       (const_int 8)(const_int 10)(const_int 12)(const_int 14)]))))]
5016   ""
5017   "
5019   rtx mask = gen_reg_rtx (TImode);
5020   unsigned char arr[16] = {
5021         0x00, 0x02, 0x04, 0x06,
5022         0x08, 0x0A, 0x0C, 0x0E,
5023         0x10, 0x12, 0x14, 0x16,
5024         0x18, 0x1A, 0x1C, 0x1E};
5026   emit_move_insn (mask, array_to_constant (TImode, arr));
5027   emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5028   DONE;
5031 (define_expand "vec_extract_oddv4si"
5032  [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
5033        (vec_concat:V4SI
5034          (vec_select:V2SI
5035            (match_operand:V4SI 1 "spu_reg_operand" "r")
5036            (parallel [(const_int 1)(const_int 3)]))
5037          (vec_select:V2SI
5038            (match_operand:V4SI 2 "spu_reg_operand" "r")
5039            (parallel [(const_int 1)(const_int 3)]))))]
5041   ""
5042   "
5044   rtx mask = gen_reg_rtx (TImode);
5045   unsigned char arr[16] = {
5046         0x04, 0x05, 0x06, 0x07,
5047         0x0C, 0x0D, 0x0E, 0x0F,
5048         0x14, 0x15, 0x16, 0x17,
5049         0x1C, 0x1D, 0x1E, 0x1F};
5051   emit_move_insn (mask, array_to_constant (TImode, arr));
5052   emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5053   DONE;
5056 (define_expand "vec_extract_oddv4sf"
5057  [(set (match_operand:V4SF 0 "spu_reg_operand" "=r")
5058        (vec_concat:V4SF
5059          (vec_select:V2SF
5060            (match_operand:V4SF 1 "spu_reg_operand" "r")
5061            (parallel [(const_int 1)(const_int 3)]))
5062          (vec_select:V2SF
5063            (match_operand:V4SF 2 "spu_reg_operand" "r")
5064            (parallel [(const_int 1)(const_int 3)]))))]
5066   ""
5067   "
5069   rtx mask = gen_reg_rtx (TImode);
5070   unsigned char arr[16] = {
5071         0x04, 0x05, 0x06, 0x07,
5072         0x0C, 0x0D, 0x0E, 0x0F,
5073         0x14, 0x15, 0x16, 0x17,
5074         0x1C, 0x1D, 0x1E, 0x1F};
5076   emit_move_insn (mask, array_to_constant (TImode, arr));
5077   emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5078   DONE;
5081 (define_expand "vec_extract_oddv8hi"
5082  [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
5083        (vec_concat:V8HI
5084          (vec_select:V4HI
5085            (match_operand:V8HI 1 "spu_reg_operand" "r")
5086            (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)]))
5087          (vec_select:V4HI
5088            (match_operand:V8HI 2 "spu_reg_operand" "r")
5089            (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)]))))]
5091   ""
5092   "
5094   rtx mask = gen_reg_rtx (TImode);
5095   unsigned char arr[16] = {
5096         0x02, 0x03, 0x06, 0x07,
5097         0x0A, 0x0B, 0x0E, 0x0F,
5098         0x12, 0x13, 0x16, 0x17,
5099         0x1A, 0x1B, 0x1E, 0x1F};
5101   emit_move_insn (mask, array_to_constant (TImode, arr));
5102   emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5103   DONE;
5106 (define_expand "vec_extract_oddv16qi"
5107  [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
5108        (vec_concat:V16QI
5109          (vec_select:V8QI
5110            (match_operand:V16QI 1 "spu_reg_operand" "r")
5111            (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)
5112                       (const_int 9)(const_int 11)(const_int 13)(const_int 15)]))
5113          (vec_select:V8QI
5114            (match_operand:V16QI 2 "spu_reg_operand" "r")
5115            (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)
5116                       (const_int 9)(const_int 11)(const_int 13)(const_int 15)]))))]
5118   ""
5119   "
5121   rtx mask = gen_reg_rtx (TImode);
5122   unsigned char arr[16] = {
5123         0x01, 0x03, 0x05, 0x07,
5124         0x09, 0x0B, 0x0D, 0x0F,
5125         0x11, 0x13, 0x15, 0x17,
5126         0x19, 0x1B, 0x1D, 0x1F};
5128   emit_move_insn (mask, array_to_constant (TImode, arr));
5129   emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5130   DONE;
5133 (define_expand "vec_interleave_highv4sf"
5134  [(set (match_operand:V4SF 0 "spu_reg_operand" "=r")
5135        (vec_select:V4SF
5136          (vec_concat:V4SF
5137            (vec_select:V2SF
5138              (match_operand:V4SF 1 "spu_reg_operand" "r")
5139              (parallel [(const_int 0)(const_int 1)]))
5140            (vec_select:V2SF
5141              (match_operand:V4SF 2 "spu_reg_operand" "r")
5142              (parallel [(const_int 0)(const_int 1)])))
5143          (parallel [(const_int 0)(const_int 2)(const_int 1)(const_int 3)])))]
5145   ""
5146   "
5148   rtx mask = gen_reg_rtx (TImode);
5149   unsigned char arr[16] = {
5150         0x00, 0x01, 0x02, 0x03,
5151         0x10, 0x11, 0x12, 0x13,
5152         0x04, 0x05, 0x06, 0x07,
5153         0x14, 0x15, 0x16, 0x17};
5155   emit_move_insn (mask, array_to_constant (TImode, arr));
5156   emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5157   DONE;
5160 (define_expand "vec_interleave_lowv4sf"
5161  [(set (match_operand:V4SF 0 "spu_reg_operand" "=r")
5162        (vec_select:V4SF
5163          (vec_concat:V4SF
5164            (vec_select:V2SF
5165              (match_operand:V4SF 1 "spu_reg_operand" "r")
5166              (parallel [(const_int 2)(const_int 3)]))
5167            (vec_select:V2SF
5168              (match_operand:V4SF 2 "spu_reg_operand" "r")
5169              (parallel [(const_int 2)(const_int 3)])))
5170          (parallel [(const_int 0)(const_int 2)(const_int 1)(const_int 3)])))]
5172   ""
5173   "
5175   rtx mask = gen_reg_rtx (TImode);
5176   unsigned char arr[16] = {
5177         0x08, 0x09, 0x0A, 0x0B,
5178         0x18, 0x19, 0x1A, 0x1B,
5179         0x0C, 0x0D, 0x0E, 0x0F,
5180         0x1C, 0x1D, 0x1E, 0x1F};
5182   emit_move_insn (mask, array_to_constant (TImode, arr));
5183   emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5184   DONE;
5187 (define_expand "vec_interleave_highv4si"
5188  [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
5189        (vec_select:V4SI
5190          (vec_concat:V4SI
5191            (vec_select:V2SI
5192              (match_operand:V4SI 1 "spu_reg_operand" "r")
5193              (parallel [(const_int 0)(const_int 1)]))
5194            (vec_select:V2SI
5195              (match_operand:V4SI 2 "spu_reg_operand" "r")
5196              (parallel [(const_int 0)(const_int 1)])))
5197          (parallel [(const_int 0)(const_int 2)(const_int 1)(const_int 3)])))]
5199   ""
5200   "
5202   rtx mask = gen_reg_rtx (TImode);
5203   unsigned char arr[16] = {
5204         0x00, 0x01, 0x02, 0x03,
5205         0x10, 0x11, 0x12, 0x13,
5206         0x04, 0x05, 0x06, 0x07,
5207         0x14, 0x15, 0x16, 0x17};
5209   emit_move_insn (mask, array_to_constant (TImode, arr));
5210   emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5211   DONE;
5214 (define_expand "vec_interleave_lowv4si"
5215  [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
5216        (vec_select:V4SI
5217          (vec_concat:V4SI
5218            (vec_select:V2SI
5219              (match_operand:V4SI 1 "spu_reg_operand" "r")
5220              (parallel [(const_int 2)(const_int 3)]))
5221            (vec_select:V2SI
5222              (match_operand:V4SI 2 "spu_reg_operand" "r")
5223              (parallel [(const_int 2)(const_int 3)])))
5224          (parallel [(const_int 0)(const_int 2)(const_int 1)(const_int 3)])))]
5226   ""
5227   "
5229   rtx mask = gen_reg_rtx (TImode);
5230   unsigned char arr[16] = {
5231         0x08, 0x09, 0x0A, 0x0B,
5232         0x18, 0x19, 0x1A, 0x1B,
5233         0x0C, 0x0D, 0x0E, 0x0F,
5234         0x1C, 0x1D, 0x1E, 0x1F};
5236   emit_move_insn (mask, array_to_constant (TImode, arr));
5237   emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5238   DONE;
5241 (define_expand "vec_interleave_highv8hi"
5242  [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
5243        (vec_select:V8HI
5244          (vec_concat:V8HI
5245            (vec_select:V4HI
5246              (match_operand:V8HI 1 "spu_reg_operand" "r")
5247              (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)]))
5248            (vec_select:V4HI
5249              (match_operand:V8HI 2 "spu_reg_operand" "r")
5250              (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)])))
5251          (parallel [(const_int 0)(const_int 4)(const_int 1)(const_int 5)
5252                     (const_int 2)(const_int 6)(const_int 3)(const_int 7)])))]
5254   ""
5255   "
5257   rtx mask = gen_reg_rtx (TImode);
5258   unsigned char arr[16] = {
5259         0x00, 0x01, 0x10, 0x11,
5260         0x02, 0x03, 0x12, 0x13,
5261         0x04, 0x05, 0x14, 0x15,
5262         0x06, 0x07, 0x16, 0x17};
5264   emit_move_insn (mask, array_to_constant (TImode, arr));
5265   emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5266   DONE;
5267  }")
5269 (define_expand "vec_interleave_lowv8hi"
5270  [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
5271        (vec_select:V8HI
5272          (vec_concat:V8HI
5273            (vec_select:V4HI
5274              (match_operand:V8HI 1 "spu_reg_operand" "r")
5275              (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)]))
5276            (vec_select:V4HI
5277              (match_operand:V8HI 2 "spu_reg_operand" "r")
5278              (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)])))
5279          (parallel [(const_int 0)(const_int 4)(const_int 1)(const_int 5)
5280                     (const_int 2)(const_int 6)(const_int 3)(const_int 7)])))]
5282   ""
5283   "
5285   rtx mask = gen_reg_rtx (TImode);
5286   unsigned char arr[16] = {
5287         0x08, 0x09, 0x18, 0x19,
5288         0x0A, 0x0B, 0x1A, 0x1B,
5289         0x0C, 0x0D, 0x1C, 0x1D,
5290         0x0E, 0x0F, 0x1E, 0x1F};
5292   emit_move_insn (mask, array_to_constant (TImode, arr));
5293   emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5294   DONE;
5297 (define_expand "vec_interleave_highv16qi"
5298  [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
5299        (vec_select:V16QI
5300          (vec_concat:V16QI
5301            (vec_select:V8QI
5302              (match_operand:V16QI 1 "spu_reg_operand" "r")
5303              (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)
5304                         (const_int 4)(const_int 5)(const_int 6)(const_int 7)]))
5305            (vec_select:V8QI
5306              (match_operand:V16QI 2 "spu_reg_operand" "r")
5307              (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)
5308                         (const_int 4)(const_int 5)(const_int 6)(const_int 7)])))
5309          (parallel [(const_int 0)(const_int 8)(const_int 1)(const_int 9)
5310                     (const_int 2)(const_int 10)(const_int 3)(const_int 11)
5311                     (const_int 4)(const_int 12)(const_int 5)(const_int 13)
5312                     (const_int 6)(const_int 14)(const_int 7)(const_int 15)])))]
5314   ""
5315   "
5317   rtx mask = gen_reg_rtx (TImode);
5318   unsigned char arr[16] = {
5319         0x00, 0x10, 0x01, 0x11,
5320         0x02, 0x12, 0x03, 0x13,
5321         0x04, 0x14, 0x05, 0x15,
5322         0x06, 0x16, 0x07, 0x17};
5324   emit_move_insn (mask, array_to_constant (TImode, arr));
5325   emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5326   DONE;
5329 (define_expand "vec_interleave_lowv16qi"
5330  [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
5331        (vec_select:V16QI
5332          (vec_concat:V16QI
5333            (vec_select:V8QI
5334              (match_operand:V16QI 1 "spu_reg_operand" "r")
5335              (parallel [(const_int 8)(const_int 9)(const_int 10)(const_int 11)
5336                         (const_int 12)(const_int 13)(const_int 14)(const_int 15)]))
5337            (vec_select:V8QI
5338              (match_operand:V16QI 2 "spu_reg_operand" "r")
5339              (parallel [(const_int 8)(const_int 9)(const_int 10)(const_int 11)
5340                         (const_int 12)(const_int 13)(const_int 14)(const_int 15)])))
5341          (parallel [(const_int 0)(const_int 8)(const_int 1)(const_int 9)
5342                     (const_int 2)(const_int 10)(const_int 3)(const_int 11)
5343                     (const_int 4)(const_int 12)(const_int 5)(const_int 13)
5344                     (const_int 6)(const_int 14)(const_int 7)(const_int 15)])))]
5346   ""
5347   "
5349   rtx mask = gen_reg_rtx (TImode);
5350   unsigned char arr[16] = {
5351          0x08, 0x18, 0x09, 0x19,
5352          0x0A, 0x1A, 0x0B, 0x1B,
5353          0x0C, 0x1C, 0x0D, 0x1D,
5354          0x0E, 0x1E, 0x0F, 0x1F};
5356   emit_move_insn (mask, array_to_constant (TImode, arr));
5357   emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5358   DONE;
5361 (define_expand "vec_pack_trunc_v8hi"
5362   [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
5363         (vec_concat:V16QI
5364           (truncate:V8QI (match_operand:V8HI 1 "spu_reg_operand" "r"))
5365           (truncate:V8QI (match_operand:V8HI 2 "spu_reg_operand" "r"))))]
5366   ""
5367   "
5369   rtx mask = gen_reg_rtx (TImode);
5370   unsigned char arr[16] = {
5371     0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0D, 0x0F,
5372     0x11, 0x13, 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F};
5374   emit_move_insn (mask, array_to_constant (TImode, arr));
5375   emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5377   DONE;
5380 (define_expand "vec_pack_trunc_v4si"
5381   [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
5382         (vec_concat:V8HI
5383           (truncate:V4HI (match_operand:V4SI 1 "spu_reg_operand" "r"))
5384           (truncate:V4HI (match_operand:V4SI 2 "spu_reg_operand" "r"))))]
5385   ""
5386   "
5388   rtx mask = gen_reg_rtx (TImode);
5389   unsigned char arr[16] = {
5390     0x02, 0x03, 0x06, 0x07, 0x0A, 0x0B, 0x0E, 0x0F,
5391     0x12, 0x13, 0x16, 0x17, 0x1A, 0x1B, 0x1E, 0x1F};
5393   emit_move_insn (mask, array_to_constant (TImode, arr));
5394   emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5396   DONE;
5399 (define_insn "stack_protect_set"
5400   [(set (match_operand:SI 0 "memory_operand" "=m")
5401         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
5402    (set (match_scratch:SI 2 "=&r") (const_int 0))]
5403   ""
5404   "lq%p1\t%2,%1\;stq%p0\t%2,%0\;xor\t%2,%2,%2"
5405   [(set_attr "length" "12")
5406    (set_attr "type" "multi1")]
5409 (define_expand "stack_protect_test"
5410   [(match_operand 0 "memory_operand" "")
5411    (match_operand 1 "memory_operand" "")
5412    (match_operand 2 "" "")]
5413   ""
5415   rtx compare_result;
5416   rtx bcomp, loc_ref;
5418   compare_result = gen_reg_rtx (SImode);
5420   emit_insn (gen_stack_protect_test_si (compare_result,
5421                                         operands[0],
5422                                         operands[1]));
5424   bcomp = gen_rtx_NE (SImode, compare_result, const0_rtx);
5426   loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[2]);
5428   emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
5429                                    gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp,
5430                                                          loc_ref, pc_rtx)));
5432   DONE;
5435 (define_insn "stack_protect_test_si"
5436   [(set (match_operand:SI 0 "spu_reg_operand" "=&r")
5437         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
5438                     (match_operand:SI 2 "memory_operand" "m")]
5439                    UNSPEC_SP_TEST))
5440    (set (match_scratch:SI 3 "=&r") (const_int 0))]
5441   ""
5442   "lq%p1\t%0,%1\;lq%p2\t%3,%2\;ceq\t%0,%0,%3\;xor\t%3,%3,%3"
5443   [(set_attr "length" "16")
5444    (set_attr "type" "multi1")]