OSDN Git Service

2007-06-27 Rask Ingemann Lambertsen <rask@sygehus.dk>
[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,%2"
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,%2"
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 (define_expand "spu_idisable"
611   [(parallel
612     [(unspec_volatile [(const_int 0)] UNSPEC_SET_INTR)
613      (clobber (match_dup:SI 0))
614      (clobber (mem:BLK (scratch)))])]
615   ""
616   "operands[0] = gen_reg_rtx (SImode);")
617
618 (define_expand "spu_ienable"
619   [(parallel
620     [(unspec_volatile [(const_int 1)] UNSPEC_SET_INTR)
621      (clobber (match_dup:SI 0))
622      (clobber (mem:BLK (scratch)))])]
623   ""
624   "operands[0] = gen_reg_rtx (SImode);")
625
626 (define_insn "set_intr"
627   [(unspec_volatile [(match_operand 1 "const_int_operand" "i")] UNSPEC_SET_INTR)
628    (clobber (match_operand:SI 0 "spu_reg_operand" "=&r"))
629    (clobber (mem:BLK (scratch)))]
630   "! flag_pic"
631   "ila\t%0,.+8\;bi%I1\t%0"
632   [(set_attr "length" "8")
633    (set_attr "type" "multi0")])
634
635 (define_insn "set_intr_pic"
636   [(unspec_volatile [(match_operand 1 "const_int_operand" "i")] UNSPEC_SET_INTR)
637    (clobber (match_operand:SI 0 "spu_reg_operand" "=&r"))
638    (clobber (mem:BLK (scratch)))]
639   "flag_pic"
640   "brsl\t%0,.+4\;ai\t%0,%0,8\;bi%I1\t%0"
641   [(set_attr "length" "12")
642    (set_attr "type" "multi1")])
643
644 (define_insn "set_intr_cc"
645   [(cond_exec (match_operator 1 "branch_comparison_operator"
646                 [(match_operand 2 "spu_reg_operand" "r")
647                  (const_int 0)])
648               (parallel [(unspec_volatile [(match_operand:SI 3 "const_int_operand" "i")] UNSPEC_SET_INTR)
649                          (clobber (match_operand:SI 0 "spu_reg_operand" "=&r"))
650                          (clobber (mem:BLK (scratch)))]))]
651   "! flag_pic"
652   "ila\t%0,.+8\;bi%b2%b1z%I3\t%2,%0"
653   [(set_attr "length" "8")
654    (set_attr "type" "multi0")])
655
656 (define_insn "set_intr_cc_pic"
657   [(cond_exec (match_operator 1 "branch_comparison_operator"
658                 [(match_operand 2 "spu_reg_operand" "r")
659                  (const_int 0)])
660               (parallel [(unspec_volatile [(match_operand:SI 3 "const_int_operand" "i")] UNSPEC_SET_INTR)
661                          (clobber (match_operand:SI 0 "spu_reg_operand" "=&r"))
662                          (clobber (mem:BLK (scratch)))]))]
663   "flag_pic"
664   "brsl\t%0,.+4\;ai\t%0,%0,8\;bi%b2%b1z%I3\t%2,%0"
665   [(set_attr "length" "12")
666    (set_attr "type" "multi1")])
667
668 (define_insn "set_intr_return"
669   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")] UNSPEC_SET_INTR)
670    (return)]
671   ""
672   "bi%I0\t$lr"
673   [(set_attr "type" "br")])
674
675 (define_peephole2
676   [(parallel
677     [(unspec_volatile [(match_operand:SI 0 "const_int_operand")] UNSPEC_SET_INTR)
678      (clobber (match_operand:SI 1 "spu_reg_operand"))
679      (clobber (mem:BLK (scratch)))])
680    (use (reg:SI 0))
681    (return)]
682   ""
683   [(use (reg:SI 0))
684    (parallel
685     [(unspec_volatile [(match_dup:SI 0)] UNSPEC_SET_INTR)
686      (return)])]
687   "")
688
689 ;; special purpose registers
690 (define_insn "spu_fscrrd"
691   [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
692         (unspec_volatile:V4SI [(const_int 6)] UNSPEC_FSCRRD))]
693   ""
694   "fscrrd\t%0"
695   [(set_attr "type" "spr")])
696
697 (define_insn "spu_fscrwr"
698   [(unspec_volatile [(match_operand:V4SI 0 "spu_reg_operand" "r")] UNSPEC_FSCRWR)]
699   ""
700   "fscrwr\t$0,%0"
701   [(set_attr "type" "spr")])
702
703 (define_insn "spu_mfspr"
704   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
705         (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "J")] UNSPEC_MFSPR))]
706   ""
707   "mfspr\t%0,$sp%1"
708   [(set_attr "type" "spr")])
709
710 (define_insn "spu_mtspr"
711   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "J")
712                      (match_operand:SI 1 "spu_reg_operand" "r")] UNSPEC_MTSPR)]
713   ""
714   "mtspr\t$sp%0,%1"
715   [(set_attr "type" "spr")])
716
717 ;; channels
718 (define_expand "spu_rdch"
719   [(set (match_operand:V4SI 0 "spu_reg_operand" "")
720         (unspec_volatile:V4SI [(match_operand:SI 1 "immediate_operand" "")] UNSPEC_RDCH))]
721   ""
722   "{
723     if (spu_safe_dma (INTVAL (operands[1])))
724       {
725         emit_insn (gen_spu_rdch_clobber (operands[0], operands[1]));
726         DONE;
727       }
728    }")
729
730 (define_expand "spu_rchcnt"
731   [(set (match_operand:SI 0 "spu_reg_operand" "")
732         (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "")] UNSPEC_RCHCNT))]
733   ""
734   "{
735     if (spu_safe_dma (INTVAL (operands[1])))
736       {
737         emit_insn (gen_spu_rchcnt_clobber (operands[0], operands[1]));
738         DONE;
739       }
740    }")
741
742 (define_expand "spu_wrch"
743    [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "")
744                       (match_operand:V4SI 1 "spu_reg_operand" "")] UNSPEC_WRCH)]
745    ""
746   "{
747     if (spu_safe_dma (INTVAL (operands[0])))
748       {
749         emit_insn (gen_spu_wrch_clobber (operands[0], operands[1]));
750         DONE;
751       }
752    }")
753
754 (define_insn "spu_rdch_noclobber"
755   [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
756         (unspec_volatile:V4SI [(match_operand:SI 1 "immediate_operand" "J")] UNSPEC_RDCH))]
757   ""
758   "rdch\t%0,$ch%1"
759   [(set_attr "type" "spr")])
760
761 (define_insn "spu_rchcnt_noclobber"
762   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
763         (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "J")] UNSPEC_RCHCNT))]
764   ""
765   "rchcnt\t%0,$ch%1"
766   [(set_attr "type" "spr")])
767
768 (define_insn "spu_wrch_noclobber"
769    [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "J")
770                       (match_operand:V4SI 1 "spu_reg_operand" "r")] UNSPEC_WRCH)]
771    ""
772    "wrch\t$ch%0,%1"
773    [(set_attr "type" "spr")])
774
775 (define_insn "spu_rdch_clobber"
776   [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
777         (unspec_volatile:V4SI [(match_operand:SI 1 "immediate_operand" "J")] UNSPEC_RDCH))
778     (clobber (mem:BLK (scratch)))]
779   ""
780   "rdch\t%0,$ch%1"
781   [(set_attr "type" "spr")])
782
783 (define_insn "spu_rchcnt_clobber"
784   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
785         (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "J")] UNSPEC_RCHCNT))
786     (clobber (mem:BLK (scratch)))]
787   ""
788   "rchcnt\t%0,$ch%1"
789   [(set_attr "type" "spr")])
790
791 (define_insn "spu_wrch_clobber"
792    [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "J")
793                       (match_operand:V4SI 1 "spu_reg_operand" "r")] UNSPEC_WRCH)
794     (clobber (mem:BLK (scratch)))]
795    ""
796    "wrch\t$ch%0,%1"
797    [(set_attr "type" "spr")])
798
799 (define_expand "spu_splats" 
800   [(set (match_operand 0 "spu_reg_operand" "")
801         (vec_duplicate (match_operand 1 "spu_nonmem_operand" "")))]
802   ""
803   {
804     spu_builtin_splats(operands);
805     DONE;
806   })
807
808 (define_expand "spu_extract"
809   [(set (match_operand 0 "spu_reg_operand" "")
810         (unspec [(match_operand 1 "spu_reg_operand" "")
811                  (match_operand 2 "spu_nonmem_operand" "")] 0))]
812   ""
813   {
814     spu_builtin_extract (operands);
815     DONE;
816   })
817
818 (define_expand "spu_insert"
819   [(set (match_operand 0 "spu_reg_operand" "")
820         (unspec [(match_operand 1 "spu_reg_operand" "")
821                  (match_operand 2 "spu_reg_operand" "")
822                  (match_operand:SI 3 "spu_nonmem_operand" "")] 0))] 
823   ""
824   {
825     spu_builtin_insert(operands);
826     DONE;
827   })
828
829 (define_expand "spu_promote"
830   [(set (match_operand 0 "spu_reg_operand" "")
831         (unspec [(match_operand 1 "spu_reg_operand" "")
832                  (match_operand:SI 2 "immediate_operand" "")] 0))] 
833   ""
834   {
835     spu_builtin_promote(operands);
836     DONE;
837   })
838
839 ;; Currently doing nothing with this but expanding its args.
840 (define_expand "spu_align_hint"
841   [(unspec [(match_operand:SI 0 "address_operand" "")
842             (match_operand:SI 1 "immediate_operand" "")
843             (match_operand:SI 2 "immediate_operand" "")] 0)]
844   ""
845   {
846      DONE;
847   })
848