OSDN Git Service

9b9a21b61d7744c820297a4b0e3e278a6940578b
[pf3gnuchains/gcc-fork.git] / gcc / config / spu / spu-builtins.md
1 ;; Copyright (C) 2006 Free Software Foundation, Inc.
2
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 2 of the License, or (at your option) 
6 ;; any later version.
7
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.
12
13 ;; You should have received a copy of the GNU General Public License
14 ;; along with this file; see the file COPYING.  If not, write to the Free
15 ;; Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
16 ;; 02110-1301, USA.
17
18
19 ;; This includes expands for all the intrinsics.
20 ;; spu_expand_builtin looks at the mode of match_operand.
21
22 \f
23 ;; load/store
24
25 (define_expand "spu_lqd"
26   [(set (match_operand:TI 0 "spu_reg_operand" "")
27         (mem:TI (and:SI (plus:SI (match_operand:SI 1 "spu_reg_operand" "")
28                                  (match_operand:SI 2 "spu_nonmem_operand" ""))
29                         (const_int -16))))]
30   ""
31   {
32     if (GET_CODE (operands[2]) == CONST_INT
33         && (INTVAL (operands[2]) & 15) != 0)
34       operands[2] = GEN_INT (INTVAL (operands[2]) & -16);
35     if (GET_CODE (operands[2]) != CONST_INT)
36       {
37         rtx op2 = operands[2];
38         operands[2] = force_reg (Pmode, operands[2]);
39         if (!ALIGNED_SYMBOL_REF_P (op2))
40           emit_insn (gen_andsi3 (operands[2], operands[2], GEN_INT (-16)));
41       }
42   })
43
44 (define_expand "spu_lqx"
45   [(set (match_operand:TI 0 "spu_reg_operand" "")
46         (mem:TI (and:SI (plus:SI (match_operand:SI 1 "spu_reg_operand" "")
47                                  (match_operand:SI 2 "spu_reg_operand" ""))
48                         (const_int -16))))]
49   ""
50   "")
51
52 (define_expand "spu_lqa"
53   [(set (match_operand:TI 0 "spu_reg_operand" "")
54         (mem:TI (and:SI (match_operand:SI 1 "immediate_operand" "")
55                         (const_int -16))))]
56   ""
57   {
58     if (GET_CODE (operands[1]) == CONST_INT
59         && (INTVAL (operands[1]) & 15) != 0)
60       operands[1] = GEN_INT (INTVAL (operands[1]) & -16);
61   })
62
63 (define_expand "spu_lqr"
64   [(set (match_operand:TI 0 "spu_reg_operand" "")
65         (mem:TI (and:SI (match_operand:SI 1 "address_operand" "")
66                         (const_int -16))))]
67   ""
68   "")
69
70 (define_expand "spu_stqd"
71   [(set (mem:TI (and:SI (plus:SI (match_operand:SI 1 "spu_reg_operand" "")
72                                  (match_operand:SI 2 "spu_nonmem_operand" ""))
73                         (const_int -16)))
74         (match_operand:TI 0 "spu_reg_operand" "r,r"))]
75   ""
76   {
77     if (GET_CODE (operands[2]) == CONST_INT
78         && (INTVAL (operands[2]) & 15) != 0)
79       operands[2] = GEN_INT (INTVAL (operands[2]) & -16);
80     if (GET_CODE (operands[2]) != CONST_INT)
81       {
82         rtx op2 = operands[2];
83         operands[2] = force_reg (Pmode, operands[2]);
84         if (!ALIGNED_SYMBOL_REF_P (op2))
85           emit_insn (gen_andsi3 (operands[2], operands[2], GEN_INT (-16)));
86       }
87   })
88
89 (define_expand "spu_stqx"
90   [(set (mem:TI (and:SI (plus:SI (match_operand:SI 1 "spu_reg_operand" "")
91                                  (match_operand:SI 2 "spu_reg_operand" ""))
92                         (const_int -16)))
93         (match_operand:TI 0 "spu_reg_operand" "r"))]
94   ""
95   "")
96
97 (define_expand "spu_stqa"
98   [(set (mem:TI (and:SI (match_operand:SI 1 "immediate_operand" "")
99                         (const_int -16)))
100         (match_operand:TI 0 "spu_reg_operand" "r"))]
101   ""
102   {
103     if (GET_CODE (operands[1]) == CONST_INT
104         && (INTVAL (operands[1]) & 15) != 0)
105       operands[1] = GEN_INT (INTVAL (operands[1]) & -16);
106   })
107
108 (define_expand "spu_stqr"
109     [(set (mem:TI (and:SI (match_operand:SI 1 "address_operand" "")
110                           (const_int -16)))
111           (match_operand:TI 0 "spu_reg_operand" ""))]
112   ""
113   "")
114
115 \f
116 ;; generate control word
117
118 (define_expand "spu_cbx"
119   [(set (match_operand:TI 0 "spu_reg_operand" "")
120         (unspec:TI [(match_operand:SI 1 "spu_reg_operand" "")
121                     (match_operand:SI 2 "spu_nonmem_operand" "")
122                     (const_int 1)] UNSPEC_CPAT))]
123   ""
124   "")
125
126 (define_expand "spu_chx"
127   [(set (match_operand:TI 0 "spu_reg_operand" "")
128         (unspec:TI [(match_operand:SI 1 "spu_reg_operand" "")
129                     (match_operand:SI 2 "spu_nonmem_operand" "")
130                     (const_int 2)] UNSPEC_CPAT))]
131   ""
132   "")
133
134 (define_expand "spu_cwx"
135   [(set (match_operand:TI 0 "spu_reg_operand" "")
136         (unspec:TI [(match_operand:SI 1 "spu_reg_operand" "")
137                     (match_operand:SI 2 "spu_nonmem_operand" "")
138                     (const_int 4)] UNSPEC_CPAT))]
139   ""
140   "")
141
142 (define_expand "spu_cdx"
143   [(set (match_operand:TI 0 "spu_reg_operand" "")
144         (unspec:TI [(match_operand:SI 1 "spu_reg_operand" "")
145                     (match_operand:SI 2 "spu_nonmem_operand" "")
146                     (const_int 8)] UNSPEC_CPAT))]
147   ""
148   "")
149
150
151 \f
152 ;; Constant formation
153
154 (define_expand "spu_ilhu"
155   [(set (match_operand:V4SI 0 "spu_reg_operand" "")
156         (const_vector:V4SI [(match_operand:SI 1 "immediate_operand" "")]))]
157   ""
158   "{ emit_insn(gen_movv4si(operands[0], spu_const(V4SImode, (INTVAL(operands[1]) << 16))));
159      DONE;
160    }")
161
162 \f
163 ;; integer subtract
164 (define_expand "spu_sfh"
165   [(set (match_operand:V8HI 0 "spu_reg_operand" "")
166         (minus:V8HI (match_operand:V8HI 2 "spu_nonmem_operand" "")
167                     (match_operand:V8HI 1 "spu_reg_operand" "")))]
168   ""
169   "")
170
171 (define_expand "spu_sf"
172   [(set (match_operand:V4SI 0 "spu_reg_operand" "")
173         (minus:V4SI (match_operand:V4SI 2 "spu_nonmem_operand" "")
174                     (match_operand:V4SI 1 "spu_reg_operand" "")))]
175   ""
176   "")
177
178 (define_expand "spu_sfx"
179   [(set (match_operand:V4SI 0 "spu_reg_operand" "")
180         (unspec:V4SI [(match_operand:V4SI 2 "spu_reg_operand" "")
181                       (match_operand:V4SI 1 "spu_reg_operand" "")
182                       (match_operand:V4SI 3 "spu_reg_operand" "")] UNSPEC_SFX))]
183   ""
184   "")
185
186 (define_expand "spu_bg"
187   [(set (match_operand:V4SI 0 "spu_reg_operand" "")
188         (unspec:V4SI [(match_operand:V4SI 2 "spu_reg_operand" "")
189                       (match_operand:V4SI 1 "spu_reg_operand" "")] UNSPEC_BG))]
190   ""
191   "")
192
193 (define_expand "spu_bgx"
194   [(set (match_operand:V4SI 0 "spu_reg_operand" "")
195         (unspec:V4SI [(match_operand:V4SI 2 "spu_reg_operand" "")
196                       (match_operand:V4SI 1 "spu_reg_operand" "")
197                       (match_operand:V4SI 3 "spu_reg_operand" "")] UNSPEC_BGX))]
198   ""
199   "")
200
201 ;; integer multiply
202 (define_insn "spu_mpy"
203   [(set (match_operand:V4SI 0 "spu_reg_operand" "=r,r")
204         (mult:V4SI
205           (sign_extend:V4SI
206             (vec_select:V4HI
207               (match_operand:V8HI 1 "spu_reg_operand" "r,r")
208               (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)])))
209           (sign_extend:V4SI
210             (vec_select:V4HI
211               (match_operand:V8HI 2 "spu_arith_operand" "r,B")
212               (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)])))))]
213   ""
214   "@
215    mpy\t%0,%1,%2
216    mpyi\t%0,%1,%H2"
217   [(set_attr "type" "fp7")])
218
219 (define_insn "spu_mpyu"
220   [(set (match_operand:V4SI 0 "spu_reg_operand" "=r,r")
221         (mult:V4SI
222           (zero_extend:V4SI
223             (vec_select:V4HI
224               (match_operand:V8HI 1 "spu_reg_operand" "r,r")
225               (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)])))
226           (zero_extend:V4SI
227             (vec_select:V4HI
228               (match_operand:V8HI 2 "spu_arith_operand" "r,B")
229               (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)])))))]
230   ""
231   "@
232    mpyu\t%0,%1,%2
233    mpyui\t%0,%1,%H2"
234   [(set_attr "type" "fp7")])
235
236 (define_insn "spu_mpya"
237   [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
238         (plus:V4SI
239           (mult:V4SI
240             (sign_extend:V4SI
241               (vec_select:V4HI
242                 (match_operand:V8HI 1 "spu_reg_operand" "r")
243                 (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)])))
244             (sign_extend:V4SI
245               (vec_select:V4HI
246                 (match_operand:V8HI 2 "spu_reg_operand" "r")
247                 (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)]))))
248         (match_operand:V4SI 3 "spu_reg_operand" "r")))]
249   ""
250   "mpya\t%0,%1,%2,%3"
251   [(set_attr "type" "fp7")])
252
253 (define_insn "spu_mpyh"
254   [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
255         (ashift:V4SI
256           (mult:V4SI
257             (sign_extend:V4SI
258               (vec_select:V4HI
259                 (match_operand:V8HI 1 "spu_reg_operand" "r")
260                 (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)])))
261             (sign_extend:V4SI
262               (vec_select:V4HI
263                 (match_operand:V8HI 2 "spu_reg_operand" "r")
264                 (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)]))))
265           (const_vector:V4SI [(const_int 16)(const_int 16)(const_int 16)(const_int 16)])))]
266   ""
267   "mpyh\t%0,%1,%2"
268   [(set_attr "type" "fp7")])
269
270 (define_insn "spu_mpys"
271   [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
272         (ashiftrt:V4SI
273           (mult:V4SI
274             (sign_extend:V4SI
275               (vec_select:V4HI
276                 (match_operand:V8HI 1 "spu_reg_operand" "r")
277                 (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)])))
278             (sign_extend:V4SI
279               (vec_select:V4HI
280                 (match_operand:V8HI 2 "spu_reg_operand" "r")
281                 (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)]))))
282           (const_vector:V4SI [(const_int 16)(const_int 16)(const_int 16)(const_int 16)])))]
283   ""
284   "mpys\t%0,%1,%2"
285   [(set_attr "type" "fp7")])
286
287 (define_insn "spu_mpyhhu"
288   [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
289         (mult:V4SI
290           (zero_extend:V4SI
291             (vec_select:V4HI
292               (match_operand:V8HI 1 "spu_reg_operand" "r")
293               (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)])))
294           (zero_extend:V4SI
295             (vec_select:V4HI
296               (match_operand:V8HI 2 "spu_reg_operand" "r")
297               (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)])))))]
298   ""
299   "mpyhhu\t%0,%1,%2"
300   [(set_attr "type" "fp7")])
301
302 (define_insn "spu_mpyhh"
303   [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
304         (mult:V4SI
305           (sign_extend:V4SI
306             (vec_select:V4HI
307               (match_operand:V8HI 1 "spu_reg_operand" "r")
308               (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)])))
309           (sign_extend:V4SI
310             (vec_select:V4HI
311               (match_operand:V8HI 2 "spu_reg_operand" "r")
312               (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)])))))]
313   ""
314   "mpyhh\t%0,%1,%2"
315   [(set_attr "type" "fp7")])
316
317 (define_insn "spu_mpyhhau"
318   [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
319         (plus:V4SI
320           (mult:V4SI
321             (zero_extend:V4SI
322               (vec_select:V4HI
323                 (match_operand:V8HI 1 "spu_reg_operand" "r")
324                 (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)])))
325             (zero_extend:V4SI
326               (vec_select:V4HI
327                 (match_operand:V8HI 2 "spu_reg_operand" "r")
328                 (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)]))))
329           (match_operand:V4SI 3 "spu_reg_operand" "0")))]
330   ""
331   "mpyhhau\t%0,%1,%2"
332   [(set_attr "type" "fp7")])
333
334 (define_insn "spu_mpyhha"
335   [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
336         (plus:V4SI
337           (mult:V4SI
338             (sign_extend:V4SI
339               (vec_select:V4HI
340                 (match_operand:V8HI 1 "spu_reg_operand" "r")
341                 (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)])))
342             (sign_extend:V4SI
343               (vec_select:V4HI
344                 (match_operand:V8HI 2 "spu_reg_operand" "r")
345                 (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)]))))
346           (match_operand:V4SI 3 "spu_reg_operand" "0")))]
347   ""
348   "mpyhha\t%0,%1,%2"
349   [(set_attr "type" "fp7")])
350
351 ;; form select mask
352 (define_insn "spu_fsmb"
353   [(set (match_operand:V16QI 0 "spu_reg_operand" "=r,r")
354         (unspec:V16QI [(match_operand:SI 1 "spu_nonmem_operand" "r,MN")] UNSPEC_FSMB))]
355   ""
356   "@
357   fsmb\t%0,%1
358   fsmbi\t%0,%1"
359   [(set_attr "type" "shuf")])
360
361 (define_insn "spu_fsmh"
362   [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
363         (unspec:V8HI [(match_operand:SI 1 "spu_reg_operand" "r")] UNSPEC_FSMH))]
364   ""
365   "fsmh\t%0,%1"
366   [(set_attr "type" "shuf")])
367
368 (define_insn "spu_fsm"
369   [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
370         (unspec:V4SI [(match_operand:SI 1 "spu_reg_operand" "r")] UNSPEC_FSM))]
371   ""
372   "fsm\t%0,%1"
373   [(set_attr "type" "shuf")])
374
375
376 ;; gather bits
377 (define_insn "spu_gbb"
378   [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
379         (unspec:V4SI [(match_operand:V16QI 1 "spu_reg_operand" "r")] UNSPEC_GBB))]
380   ""
381   "gbb\t%0,%1"
382   [(set_attr "type" "shuf")])
383
384 (define_insn "spu_gbh"
385   [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
386         (unspec:V4SI [(match_operand:V8HI 1 "spu_reg_operand" "r")] UNSPEC_GBH))]
387   ""
388   "gbh\t%0,%1"
389   [(set_attr "type" "shuf")])
390
391 (define_insn "spu_gb"
392   [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
393         (unspec:V4SI [(match_operand:V4SI 1 "spu_reg_operand" "r")] UNSPEC_GB))]
394   ""
395   "gb\t%0,%1"
396   [(set_attr "type" "shuf")])
397
398 ;; misc byte operations
399 (define_insn "spu_avgb"
400   [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
401         (unspec:V16QI [(match_operand:V16QI 1 "spu_reg_operand" "r")
402                        (match_operand:V16QI 2 "spu_reg_operand" "r")] UNSPEC_AVGB))]
403   ""
404   "avgb\t%0,%1,%2"
405   [(set_attr "type" "fxb")])
406
407 (define_insn "spu_absdb"
408   [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
409         (unspec:V16QI [(match_operand:V16QI 1 "spu_reg_operand" "r")
410                        (match_operand:V16QI 2 "spu_reg_operand" "r")] UNSPEC_ABSDB))]
411   ""
412   "absdb\t%0,%1,%2"
413   [(set_attr "type" "fxb")])
414
415 (define_insn "spu_sumb"
416   [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
417         (unspec:V8HI [(match_operand:V16QI 1 "spu_reg_operand" "r")
418                       (match_operand:V16QI 2 "spu_reg_operand" "r")] UNSPEC_SUMB))]
419   ""
420   "sumb\t%0,%1,%2"
421   [(set_attr "type" "fxb")])
422
423 ;; sign extend
424 (define_insn "spu_xsbh"
425   [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
426         (sign_extend:V8HI
427           (vec_select:V8QI
428             (match_operand:V16QI 1 "spu_reg_operand" "r")
429             (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)
430                        (const_int 9)(const_int 11)(const_int 13)(const_int 15)]))))]
431   ""
432   "xsbh\t%0,%1")
433
434 (define_insn "spu_xshw"
435   [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
436         (sign_extend:V4SI
437           (vec_select:V4HI
438             (match_operand:V8HI 1 "spu_reg_operand" "r")
439             (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)]))))]
440   ""
441   "xshw\t%0,%1")
442
443 (define_insn "spu_xswd"
444   [(set (match_operand:V2DI 0 "spu_reg_operand" "=r")
445         (sign_extend:V2DI
446           (vec_select:V2SI
447             (match_operand:V4SI 1 "spu_reg_operand" "r")
448             (parallel [(const_int 1)(const_int 3)]))))]
449   ""
450   "xswd\t%0,%1")
451
452 ;; or across
453
454 (define_insn "spu_orx"
455   [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
456         (unspec:V4SI [(match_operand:V4SI 1 "spu_reg_operand" "r")] UNSPEC_ORX))]
457   ""
458   "orx\t%0,%1")
459
460
461 ;; compare & halt
462 (define_insn "spu_heq"
463   [(unspec_volatile [(match_operand:SI 0 "spu_reg_operand" "r,r")
464                      (match_operand:SI 1 "spu_nonmem_operand" "r,K")] UNSPEC_HEQ)]
465   ""
466   "@
467   heq\t%0,%1
468   heqi\t%0,%1")
469
470 (define_insn "spu_hgt"
471   [(unspec_volatile [(match_operand:SI 0 "spu_reg_operand" "r,r")
472                      (match_operand:SI 1 "spu_nonmem_operand" "r,K")] UNSPEC_HGT)]
473   ""
474   "@
475   hgt\t%0,%1
476   hgti\t%0,%1")
477
478 (define_insn "spu_hlgt"
479   [(unspec_volatile [(match_operand:SI 0 "spu_reg_operand" "r,r")
480                      (match_operand:SI 1 "spu_nonmem_operand" "r,K")] UNSPEC_HLGT)]
481   ""
482   "@
483   hlgt\t%0,%1
484   hlgti\t%0,%1")
485
486 ;; branches
487
488 ;; The description below hides the fact that bisled conditionally
489 ;; executes the call depending on the value in channel 0.  This was 
490 ;; done so that the description would conform to the format of a call 
491 ;; insn.  Otherwise (if this were not part of call insn), the link 
492 ;; register, $lr, would not be saved/restored in the prologue/epilogue.
493
494 (define_insn "spu_bisled"
495   [(parallel
496     [(call (mem:QI (match_operand:SI 0 "spu_reg_operand" "r"))
497             (const_int 0))
498      (clobber (reg:SI 0))
499      (clobber (reg:SI 130))
500      (use (match_operand:SI 1 "address_operand" ""))
501      (use (const_int 0))])]
502   ""
503   "bisled\t$lr,%0"
504   [(set_attr "type" "br")])
505
506 (define_insn "spu_bisledd"
507   [(parallel
508     [(call (mem:QI (match_operand:SI 0 "spu_reg_operand" "r"))
509             (const_int 0))
510      (clobber (reg:SI 0))
511      (clobber (reg:SI 130))
512      (use (match_operand:SI 1 "address_operand" ""))
513      (use (const_int 1))])]
514   ""
515   "bisledd\t$lr,%0"
516   [(set_attr "type" "br")])
517
518 (define_insn "spu_bislede"
519   [(parallel
520     [(call (mem:QI (match_operand:SI 0 "spu_reg_operand" "r"))
521             (const_int 0))
522      (clobber (reg:SI 0))
523      (clobber (reg:SI 130))
524      (use (match_operand:SI 1 "address_operand" ""))
525      (use (const_int 2))])]
526   ""
527   "bislede\t$lr,%0"
528   [(set_attr "type" "br")])
529
530 ;; float convert
531 (define_insn "spu_csflt"
532   [(set (match_operand:V4SF 0 "spu_reg_operand" "=r")
533         (unspec:V4SF [(match_operand:V4SI 1 "spu_reg_operand" "r")
534                       (match_operand:SI 2 "immediate_operand" "K")] UNSPEC_CSFLT ))]
535   ""
536   "csflt\t%0,%1,%2"
537   [(set_attr "type" "fp7")])
538
539 (define_insn "spu_cflts"
540   [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
541         (unspec:V4SI [(match_operand:V4SF 1 "spu_reg_operand" "r")
542                       (match_operand:SI 2 "immediate_operand" "J")] UNSPEC_CFLTS ))]
543   ""
544   "cflts\t%0,%1,%2"
545   [(set_attr "type" "fp7")])
546
547 (define_insn "spu_cuflt"
548   [(set (match_operand:V4SF 0 "spu_reg_operand" "=r")
549         (unspec:V4SF [(match_operand:V4SI 1 "spu_reg_operand" "r")
550                       (match_operand:SI 2 "immediate_operand" "K")] UNSPEC_CUFLT ))]
551   ""
552   "cuflt\t%0,%1,%2"
553   [(set_attr "type" "fp7")])
554
555 (define_insn "spu_cfltu"
556   [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
557         (unspec:V4SI [(match_operand:V4SF 1 "spu_reg_operand" "r")
558                       (match_operand:SI 2 "immediate_operand" "J")] UNSPEC_CFLTU ))]
559   ""
560   "cfltu\t%0,%1,%2"
561   [(set_attr "type" "fp7")])
562
563 (define_expand "spu_frds"
564    [(set (match_operand:V4SF 0 "spu_reg_operand" "")
565          (vec_select:V4SF
566            (vec_concat:V4SF
567              (float_truncate:V2SF (match_operand:V2DF 1 "spu_reg_operand" ""))
568              (match_dup:V2SF 2))
569            (parallel [(const_int 0)(const_int 2)(const_int 1)(const_int 3)])))]
570   ""
571   "operands[2] = spu_const(V2SFmode, 0);")
572
573 (define_insn "_frds"
574    [(set (match_operand:V4SF 0 "spu_reg_operand" "=r")
575         (vec_select:V4SF
576           (vec_concat:V4SF
577             (float_truncate:V2SF (match_operand:V2DF 1 "spu_reg_operand" "r"))
578             (match_operand:V2SF 2 "vec_imm_operand" "i"))
579           (parallel [(const_int 0)(const_int 2)(const_int 1)(const_int 3)])))]
580   ""
581   "frds\t%0,%1"
582   [(set_attr "type" "fpd")])
583
584 (define_insn "spu_fesd"
585   [(set (match_operand:V2DF 0 "spu_reg_operand" "=r")
586         (float_extend:V2DF
587           (vec_select:V2SF
588             (match_operand:V4SF 1 "spu_reg_operand" "r")
589               (parallel [(const_int 0)(const_int 2)]))))]
590   ""
591   "fesd\t%0,%1"
592   [(set_attr "type" "fpd")])
593
594 ;; control
595 (define_insn "spu_stop"
596   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "M")] UNSPEC_STOP)]
597   ""
598   "stop\t%0"
599   [(set_attr "type" "br")])
600
601 (define_insn "spu_stopd"
602   [(unspec_volatile [(match_operand:SI 0 "spu_reg_operand" "r")
603                      (match_operand:SI 1 "spu_reg_operand" "r")
604                      (match_operand:SI 2 "spu_reg_operand" "r")] UNSPEC_STOPD)]
605   ""
606   "stopd\t%0,%1,%2"
607   [(set_attr "type" "br")])
608
609 ;; interrupt disable/enable
610 ;; Register 131 is used exclusively for enabling/disabling interrupts.
611 ;; It is marked as a global reg and the instructions clobber mem, so it will
612 ;; not be incorrectly optimized.
613 (define_expand "spu_idisable"
614   [(parallel
615     [(set (reg:INTR 131) (const_int 0))
616      (clobber (match_dup:SI 0))
617      (clobber (mem:BLK (scratch)))])]
618   ""
619   "operands[0] = gen_reg_rtx (SImode);")
620
621 (define_expand "spu_ienable"
622   [(parallel
623     [(set (reg:INTR 131) (const_int 1))
624      (clobber (match_dup:SI 0))
625      (clobber (mem:BLK (scratch)))])]
626   ""
627   "operands[0] = gen_reg_rtx (SImode);")
628
629 (define_insn "set_intr"
630   [(set (reg:INTR 131) (match_operand 1 "const_int_operand" "i"))
631    (clobber (match_operand:SI 0 "spu_reg_operand" "=&r"))
632    (clobber (mem:BLK (scratch)))]
633   "! flag_pic"
634   "ila\t%0,.+8\;bi%I1\t%0"
635   [(set_attr "length" "8")
636    (set_attr "type" "multi0")])
637
638 (define_insn "set_intr_pic"
639   [(set (reg:INTR 131) (match_operand 1 "const_int_operand" "i"))
640    (clobber (match_operand:SI 0 "spu_reg_operand" "=&r"))
641    (clobber (mem:BLK (scratch)))]
642   "flag_pic"
643   "brsl\t%0,.+4\;ai\t%0,%0,8\;bi%I1\t%0"
644   [(set_attr "length" "12")
645    (set_attr "type" "multi1")])
646
647 (define_expand "movintrcc"
648   [(parallel
649     [(set (match_operand:INTR 0 "spu_reg_operand" "")
650           (if_then_else:INTR (match_operand 1 "branch_comparison_operator" "")
651                         (match_operand 3 "const_int_operand" "")
652                         (match_operand:INTR 2 "spu_reg_operand" "")))
653      (clobber (match_dup:SI 4))
654      (clobber (mem:BLK (scratch)))])]
655   ""
656   { /* We've swapped operands 2 and 3 in the pattern, reverse the
657        condition code too. */
658     PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1])));
659     operands[4] = gen_reg_rtx (SImode);
660   })
661
662 (define_insn "set_intr_cc"
663   [(set (reg:INTR 131)
664         (if_then_else:INTR
665           (match_operator 1 "branch_comparison_operator"
666             [(match_operand 2 "spu_reg_operand" "r")
667              (const_int 0)])
668           (match_operand:SI 3 "const_int_operand" "i")
669           (reg:INTR 131)))
670    (clobber (match_operand:SI 0 "spu_reg_operand" "=&r"))
671    (clobber (mem:BLK (scratch)))]
672   "! flag_pic"
673   "ila\t%0,.+8\;bi%b2%b1z%I3\t%2,%0"
674   [(set_attr "length" "8")
675    (set_attr "type" "multi0")])
676
677 (define_insn "set_intr_cc_pic"
678   [(set (reg:INTR 131)
679         (if_then_else:INTR
680           (match_operator 1 "branch_comparison_operator"
681             [(match_operand 2 "spu_reg_operand" "r")
682              (const_int 0)])
683           (match_operand:SI 3 "const_int_operand" "i")
684           (reg:INTR 131)))
685    (clobber (match_operand:SI 0 "spu_reg_operand" "=&r"))
686    (clobber (mem:BLK (scratch)))]
687   "flag_pic"
688   "brsl\t%0,.+4\;ai\t%0,%0,8\;%b2%b1z%I3\t%2,%0"
689   [(set_attr "length" "12")
690    (set_attr "type" "multi1")])
691
692 (define_insn "set_intr_return"
693   [(set (reg:INTR 131) (match_operand 0 "const_int_operand" "i"))
694    (return)]
695   ""
696   "bi%I0\t$lr"
697   [(set_attr "type" "br")])
698
699 (define_peephole2
700   [(parallel
701     [(set (reg:INTR 131) (match_operand 0 "const_int_operand"))
702      (clobber (match_operand:SI 1 "spu_reg_operand"))
703      (clobber (mem:BLK (scratch)))])
704    (use (reg:SI 0))
705    (return)]
706   ""
707   [(use (reg:SI 0))
708    (parallel
709     [(set (reg:INTR 131) (match_dup 0))
710      (return)])]
711   "")
712
713 ;; special purpose registers
714 (define_insn "spu_fscrrd"
715   [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
716         (unspec_volatile:V4SI [(const_int 6)] UNSPEC_FSCRRD))]
717   ""
718   "fscrrd\t%0"
719   [(set_attr "type" "spr")])
720
721 (define_insn "spu_fscrwr"
722   [(unspec_volatile [(match_operand:V4SI 0 "spu_reg_operand" "r")] UNSPEC_FSCRWR)]
723   ""
724   "fscrwr\t$0,%0"
725   [(set_attr "type" "spr")])
726
727 (define_insn "spu_mfspr"
728   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
729         (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "J")] UNSPEC_MFSPR))]
730   ""
731   "mfspr\t%0,$sp%1"
732   [(set_attr "type" "spr")])
733
734 (define_insn "spu_mtspr"
735   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "J")
736                      (match_operand:SI 1 "spu_reg_operand" "r")] UNSPEC_MTSPR)]
737   ""
738   "mtspr\t$sp%0,%1"
739   [(set_attr "type" "spr")])
740
741 ;; channels
742 (define_expand "spu_rdch"
743   [(set (match_operand:V4SI 0 "spu_reg_operand" "")
744         (unspec_volatile:V4SI [(match_operand:SI 1 "immediate_operand" "")] UNSPEC_RDCH))]
745   ""
746   "{
747     if (spu_safe_dma (INTVAL (operands[1])))
748       {
749         emit_insn (gen_spu_rdch_clobber (operands[0], operands[1]));
750         DONE;
751       }
752    }")
753
754 (define_expand "spu_rchcnt"
755   [(set (match_operand:SI 0 "spu_reg_operand" "")
756         (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "")] UNSPEC_RCHCNT))]
757   ""
758   "{
759     if (spu_safe_dma (INTVAL (operands[1])))
760       {
761         emit_insn (gen_spu_rchcnt_clobber (operands[0], operands[1]));
762         DONE;
763       }
764    }")
765
766 (define_expand "spu_wrch"
767    [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "")
768                       (match_operand:V4SI 1 "spu_reg_operand" "")] UNSPEC_WRCH)]
769    ""
770   "{
771     if (spu_safe_dma (INTVAL (operands[0])))
772       {
773         emit_insn (gen_spu_wrch_clobber (operands[0], operands[1]));
774         DONE;
775       }
776    }")
777
778 (define_insn "spu_rdch_noclobber"
779   [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
780         (unspec_volatile:V4SI [(match_operand:SI 1 "immediate_operand" "J")] UNSPEC_RDCH))]
781   ""
782   "rdch\t%0,$ch%1"
783   [(set_attr "type" "spr")])
784
785 (define_insn "spu_rchcnt_noclobber"
786   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
787         (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "J")] UNSPEC_RCHCNT))]
788   ""
789   "rchcnt\t%0,$ch%1"
790   [(set_attr "type" "spr")])
791
792 (define_insn "spu_wrch_noclobber"
793    [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "J")
794                       (match_operand:V4SI 1 "spu_reg_operand" "r")] UNSPEC_WRCH)]
795    ""
796    "wrch\t$ch%0,%1"
797    [(set_attr "type" "spr")])
798
799 (define_insn "spu_rdch_clobber"
800   [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
801         (unspec_volatile:V4SI [(match_operand:SI 1 "immediate_operand" "J")] UNSPEC_RDCH))
802     (clobber (mem:BLK (scratch)))]
803   ""
804   "rdch\t%0,$ch%1"
805   [(set_attr "type" "spr")])
806
807 (define_insn "spu_rchcnt_clobber"
808   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
809         (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "J")] UNSPEC_RCHCNT))
810     (clobber (mem:BLK (scratch)))]
811   ""
812   "rchcnt\t%0,$ch%1"
813   [(set_attr "type" "spr")])
814
815 (define_insn "spu_wrch_clobber"
816    [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "J")
817                       (match_operand:V4SI 1 "spu_reg_operand" "r")] UNSPEC_WRCH)
818     (clobber (mem:BLK (scratch)))]
819    ""
820    "wrch\t$ch%0,%1"
821    [(set_attr "type" "spr")])
822
823 (define_expand "spu_splats" 
824   [(set (match_operand 0 "spu_reg_operand" "")
825         (vec_duplicate (match_operand 1 "spu_nonmem_operand" "")))]
826   ""
827   {
828     spu_builtin_splats(operands);
829     DONE;
830   })
831
832 (define_expand "spu_extract"
833   [(set (match_operand 0 "spu_reg_operand" "")
834         (unspec [(match_operand 1 "spu_reg_operand" "")
835                  (match_operand 2 "spu_nonmem_operand" "")] 0))]
836   ""
837   {
838     spu_builtin_extract (operands);
839     DONE;
840   })
841
842 (define_expand "spu_insert"
843   [(set (match_operand 0 "spu_reg_operand" "")
844         (unspec [(match_operand 1 "spu_reg_operand" "")
845                  (match_operand 2 "spu_reg_operand" "")
846                  (match_operand:SI 3 "spu_nonmem_operand" "")] 0))] 
847   ""
848   {
849     spu_builtin_insert(operands);
850     DONE;
851   })
852
853 (define_expand "spu_promote"
854   [(set (match_operand 0 "spu_reg_operand" "")
855         (unspec [(match_operand 1 "spu_reg_operand" "")
856                  (match_operand:SI 2 "immediate_operand" "")] 0))] 
857   ""
858   {
859     spu_builtin_promote(operands);
860     DONE;
861   })
862
863 ;; Currently doing nothing with this but expanding its args.
864 (define_expand "spu_align_hint"
865   [(unspec [(match_operand:SI 0 "address_operand" "")
866             (match_operand:SI 1 "immediate_operand" "")
867             (match_operand:SI 2 "immediate_operand" "")] 0)]
868   ""
869   {
870      DONE;
871   })
872