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