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