PR tree-optimization/82929
[official-gcc.git] / gcc / config / spu / spu-builtins.md
blob322abc0fbbc2f00fe3b5b527f4915835e19ba39b
1 ;; Copyright (C) 2006-2017 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 (define_insn "spu_mpya"
201   [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
202         (plus:V4SI
203           (mult:V4SI
204             (sign_extend:V4SI
205               (vec_select:V4HI
206                 (match_operand:V8HI 1 "spu_reg_operand" "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_reg_operand" "r")
211                 (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)]))))
212         (match_operand:V4SI 3 "spu_reg_operand" "r")))]
213   ""
214   "mpya\t%0,%1,%2,%3"
215   [(set_attr "type" "fp7")])
217 (define_insn "spu_mpyh"
218   [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
219         (ashift:V4SI
220           (mult:V4SI
221             (sign_extend:V4SI
222               (vec_select:V4HI
223                 (match_operand:V8HI 1 "spu_reg_operand" "r")
224                 (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)])))
225             (sign_extend:V4SI
226               (vec_select:V4HI
227                 (match_operand:V8HI 2 "spu_reg_operand" "r")
228                 (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)]))))
229           (const_vector:V4SI [(const_int 16)(const_int 16)(const_int 16)(const_int 16)])))]
230   ""
231   "mpyh\t%0,%1,%2"
232   [(set_attr "type" "fp7")])
234 (define_insn "spu_mpys"
235   [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
236         (ashiftrt:V4SI
237           (mult:V4SI
238             (sign_extend:V4SI
239               (vec_select:V4HI
240                 (match_operand:V8HI 1 "spu_reg_operand" "r")
241                 (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)])))
242             (sign_extend:V4SI
243               (vec_select:V4HI
244                 (match_operand:V8HI 2 "spu_reg_operand" "r")
245                 (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)]))))
246           (const_vector:V4SI [(const_int 16)(const_int 16)(const_int 16)(const_int 16)])))]
247   ""
248   "mpys\t%0,%1,%2"
249   [(set_attr "type" "fp7")])
251 (define_insn "spu_mpyhhau"
252   [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
253         (plus:V4SI
254           (mult:V4SI
255             (zero_extend:V4SI
256               (vec_select:V4HI
257                 (match_operand:V8HI 1 "spu_reg_operand" "r")
258                 (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)])))
259             (zero_extend:V4SI
260               (vec_select:V4HI
261                 (match_operand:V8HI 2 "spu_reg_operand" "r")
262                 (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)]))))
263           (match_operand:V4SI 3 "spu_reg_operand" "0")))]
264   ""
265   "mpyhhau\t%0,%1,%2"
266   [(set_attr "type" "fp7")])
268 (define_insn "spu_mpyhha"
269   [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
270         (plus:V4SI
271           (mult:V4SI
272             (sign_extend:V4SI
273               (vec_select:V4HI
274                 (match_operand:V8HI 1 "spu_reg_operand" "r")
275                 (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)])))
276             (sign_extend:V4SI
277               (vec_select:V4HI
278                 (match_operand:V8HI 2 "spu_reg_operand" "r")
279                 (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)]))))
280           (match_operand:V4SI 3 "spu_reg_operand" "0")))]
281   ""
282   "mpyhha\t%0,%1,%2"
283   [(set_attr "type" "fp7")])
285 ;; form select mask
286 (define_insn "spu_fsmb"
287   [(set (match_operand:V16QI 0 "spu_reg_operand" "=r,r")
288         (unspec:V16QI [(match_operand:SI 1 "spu_nonmem_operand" "r,MN")] UNSPEC_FSMB))]
289   ""
290   "@
291   fsmb\t%0,%1
292   fsmbi\t%0,%1"
293   [(set_attr "type" "shuf")])
295 (define_insn "spu_fsmh"
296   [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
297         (unspec:V8HI [(match_operand:SI 1 "spu_reg_operand" "r")] UNSPEC_FSMH))]
298   ""
299   "fsmh\t%0,%1"
300   [(set_attr "type" "shuf")])
302 (define_insn "spu_fsm"
303   [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
304         (unspec:V4SI [(match_operand:SI 1 "spu_reg_operand" "r")] UNSPEC_FSM))]
305   ""
306   "fsm\t%0,%1"
307   [(set_attr "type" "shuf")])
310 ;; gather bits
311 (define_insn "spu_gbb"
312   [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
313         (unspec:V4SI [(match_operand:V16QI 1 "spu_reg_operand" "r")] UNSPEC_GBB))]
314   ""
315   "gbb\t%0,%1"
316   [(set_attr "type" "shuf")])
318 (define_insn "spu_gbh"
319   [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
320         (unspec:V4SI [(match_operand:V8HI 1 "spu_reg_operand" "r")] UNSPEC_GBH))]
321   ""
322   "gbh\t%0,%1"
323   [(set_attr "type" "shuf")])
325 (define_insn "spu_gb"
326   [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
327         (unspec:V4SI [(match_operand:V4SI 1 "spu_reg_operand" "r")] UNSPEC_GB))]
328   ""
329   "gb\t%0,%1"
330   [(set_attr "type" "shuf")])
332 ;; misc byte operations
333 (define_insn "spu_avgb"
334   [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
335         (unspec:V16QI [(match_operand:V16QI 1 "spu_reg_operand" "r")
336                        (match_operand:V16QI 2 "spu_reg_operand" "r")] UNSPEC_AVGB))]
337   ""
338   "avgb\t%0,%1,%2"
339   [(set_attr "type" "fxb")])
341 (define_insn "spu_absdb"
342   [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
343         (unspec:V16QI [(match_operand:V16QI 1 "spu_reg_operand" "r")
344                        (match_operand:V16QI 2 "spu_reg_operand" "r")] UNSPEC_ABSDB))]
345   ""
346   "absdb\t%0,%1,%2"
347   [(set_attr "type" "fxb")])
349 (define_insn "spu_sumb"
350   [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
351         (unspec:V8HI [(match_operand:V16QI 1 "spu_reg_operand" "r")
352                       (match_operand:V16QI 2 "spu_reg_operand" "r")] UNSPEC_SUMB))]
353   ""
354   "sumb\t%0,%1,%2"
355   [(set_attr "type" "fxb")])
357 ;; sign extend
358 (define_insn "spu_xsbh"
359   [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
360         (sign_extend:V8HI
361           (vec_select:V8QI
362             (match_operand:V16QI 1 "spu_reg_operand" "r")
363             (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)
364                        (const_int 9)(const_int 11)(const_int 13)(const_int 15)]))))]
365   ""
366   "xsbh\t%0,%1")
368 (define_insn "spu_xshw"
369   [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
370         (sign_extend:V4SI
371           (vec_select:V4HI
372             (match_operand:V8HI 1 "spu_reg_operand" "r")
373             (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)]))))]
374   ""
375   "xshw\t%0,%1")
377 (define_insn "spu_xswd"
378   [(set (match_operand:V2DI 0 "spu_reg_operand" "=r")
379         (sign_extend:V2DI
380           (vec_select:V2SI
381             (match_operand:V4SI 1 "spu_reg_operand" "r")
382             (parallel [(const_int 1)(const_int 3)]))))]
383   ""
384   "xswd\t%0,%1")
386 ;; or across
388 (define_insn "spu_orx"
389   [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
390         (unspec:V4SI [(match_operand:V4SI 1 "spu_reg_operand" "r")] UNSPEC_ORX))]
391   ""
392   "orx\t%0,%1")
395 ;; compare & halt
396 (define_insn "spu_heq"
397   [(unspec_volatile [(match_operand:SI 0 "spu_reg_operand" "r,r")
398                      (match_operand:SI 1 "spu_nonmem_operand" "r,K")] UNSPEC_HEQ)]
399   ""
400   "@
401   heq\t%0,%1
402   heqi\t%0,%1")
404 (define_insn "spu_hgt"
405   [(unspec_volatile [(match_operand:SI 0 "spu_reg_operand" "r,r")
406                      (match_operand:SI 1 "spu_nonmem_operand" "r,K")] UNSPEC_HGT)]
407   ""
408   "@
409   hgt\t%0,%1
410   hgti\t%0,%1")
412 (define_insn "spu_hlgt"
413   [(unspec_volatile [(match_operand:SI 0 "spu_reg_operand" "r,r")
414                      (match_operand:SI 1 "spu_nonmem_operand" "r,K")] UNSPEC_HLGT)]
415   ""
416   "@
417   hlgt\t%0,%1
418   hlgti\t%0,%1")
420 ;; branches
422 ;; The description below hides the fact that bisled conditionally
423 ;; executes the call depending on the value in channel 0.  This was 
424 ;; done so that the description would conform to the format of a call 
425 ;; insn.  Otherwise (if this were not part of call insn), the link 
426 ;; register, $lr, would not be saved/restored in the prologue/epilogue.
428 (define_insn "spu_bisled"
429   [(parallel
430     [(call (mem:QI (match_operand:SI 0 "spu_reg_operand" "r"))
431             (const_int 0))
432      (clobber (reg:SI 0))
433      (clobber (reg:SI 130))
434      (use (match_operand:SI 1 "address_operand" ""))
435      (use (const_int 0))])]
436   ""
437   "bisled\t$lr,%0"
438   [(set_attr "type" "br")])
440 (define_insn "spu_bisledd"
441   [(parallel
442     [(call (mem:QI (match_operand:SI 0 "spu_reg_operand" "r"))
443             (const_int 0))
444      (clobber (reg:SI 0))
445      (clobber (reg:SI 130))
446      (use (match_operand:SI 1 "address_operand" ""))
447      (use (const_int 1))])]
448   ""
449   "bisledd\t$lr,%0"
450   [(set_attr "type" "br")])
452 (define_insn "spu_bislede"
453   [(parallel
454     [(call (mem:QI (match_operand:SI 0 "spu_reg_operand" "r"))
455             (const_int 0))
456      (clobber (reg:SI 0))
457      (clobber (reg:SI 130))
458      (use (match_operand:SI 1 "address_operand" ""))
459      (use (const_int 2))])]
460   ""
461   "bislede\t$lr,%0"
462   [(set_attr "type" "br")])
464 ;; float convert
465 (define_expand "spu_csflt"
466   [(set (match_operand:V4SF 0 "spu_reg_operand")
467         (unspec:V4SF [(match_operand:V4SI 1 "spu_reg_operand")
468                       (match_operand:SI 2 "spu_nonmem_operand")] 0 ))]
469   ""
471   if (GET_CODE (operands[2]) == CONST_INT
472       && (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) > 127))
473     {
474       error ("spu_convtf expects an integer literal in the range [0, 127].");
475       operands[2] = force_reg (SImode, operands[2]);
476     }
477   if (GET_CODE (operands[2]) != CONST_INT)
478     {
479       rtx exp2;
480       rtx cnv = gen_reg_rtx (V4SFmode);
481       rtx scale = gen_reg_rtx (SImode);
482       rtx op2 = force_reg (SImode, operands[2]);
483       rtx m1 = spu_gen_exp2 (V4SFmode, GEN_INT (-1));
484       emit_insn (gen_subsi3 (scale, const1_rtx, op2));
485       exp2 = spu_gen_exp2 (V4SFmode, scale);
486       emit_insn (gen_floatv4siv4sf2_mul (cnv, operands[1], m1));
487       emit_insn (gen_mulv4sf3 (operands[0], cnv, exp2));
488     }
489   else
490     {
491       rtx exp2 = spu_gen_exp2 (V4SFmode, operands[2]);
492       emit_insn (gen_floatv4siv4sf2_div (operands[0], operands[1], exp2));
493     }
494   DONE;
497 (define_expand "spu_cflts"
498   [(set (match_operand:V4SI 0 "spu_reg_operand")
499         (unspec:V4SI [(match_operand:V4SF 1 "spu_reg_operand")
500                       (match_operand:SI 2 "spu_nonmem_operand")] 0 ))]
501   ""
503   rtx exp2;
504   if (GET_CODE (operands[2]) == CONST_INT
505       && (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) > 127))
506     {
507       error ("spu_convts expects an integer literal in the range [0, 127].");
508       operands[2] = force_reg (SImode, operands[2]);
509     }
510   exp2 = spu_gen_exp2 (V4SFmode, operands[2]);
511   if (GET_CODE (operands[2]) != CONST_INT)
512     {
513       rtx mul = gen_reg_rtx (V4SFmode);
514       emit_insn (gen_mulv4sf3 (mul, operands[1], exp2));
515       emit_insn (gen_fix_truncv4sfv4si2 (operands[0], mul));
516     }
517   else 
518     emit_insn (gen_fix_truncv4sfv4si2_mul (operands[0], operands[1], exp2));
519   DONE;
522 (define_expand "spu_cuflt"
523   [(set (match_operand:V4SF 0 "spu_reg_operand" "=r")
524         (unspec:V4SF [(match_operand:V4SI 1 "spu_reg_operand")
525                       (match_operand:SI 2 "spu_nonmem_operand")] 0 ))]
526   ""
528   if (GET_CODE (operands[2]) == CONST_INT
529       && (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) > 127))
530     {
531       error ("spu_convtf expects an integer literal in the range [0, 127].");
532       operands[2] = force_reg (SImode, operands[2]);
533     }
534   if (GET_CODE (operands[2]) != CONST_INT)
535     {
536       rtx exp2;
537       rtx cnv = gen_reg_rtx (V4SFmode);
538       rtx scale = gen_reg_rtx (SImode);
539       rtx op2 = force_reg (SImode, operands[2]);
540       rtx m1 = spu_gen_exp2 (V4SFmode, GEN_INT (-1));
541       emit_insn (gen_subsi3 (scale, const1_rtx, op2));
542       exp2 = spu_gen_exp2 (V4SFmode, scale);
543       emit_insn (gen_floatunsv4siv4sf2_mul (cnv, operands[1], m1));
544       emit_insn (gen_mulv4sf3 (operands[0], cnv, exp2));
545     }
546   else
547     {
548       rtx exp2 = spu_gen_exp2 (V4SFmode, operands[2]);
549       emit_insn (gen_floatunsv4siv4sf2_div (operands[0], operands[1], exp2));
550     }
551   DONE;
554 (define_expand "spu_cfltu"
555   [(set (match_operand:V4SI 0 "spu_reg_operand")
556         (unspec:V4SI [(match_operand:V4SF 1 "spu_reg_operand")
557                       (match_operand:SI 2 "spu_nonmem_operand")] 0 ))]
558   ""
560   rtx exp2;
561   if (GET_CODE (operands[2]) == CONST_INT
562       && (INTVAL (operands[2]) < 0 || INTVAL (operands[2]) > 127))
563     {
564       error ("spu_convtu expects an integer literal in the range [0, 127].");
565       operands[2] = force_reg (SImode, operands[2]);
566     }
567   exp2 = spu_gen_exp2 (V4SFmode, operands[2]);
568   if (GET_CODE (operands[2]) != CONST_INT)
569     {
570       rtx mul = gen_reg_rtx (V4SFmode);
571       emit_insn (gen_mulv4sf3 (mul, operands[1], exp2));
572       emit_insn (gen_fixuns_truncv4sfv4si2 (operands[0], mul));
573     }
574   else 
575     emit_insn (gen_fixuns_truncv4sfv4si2_mul (operands[0], operands[1], exp2));
576   DONE;
579 (define_expand "spu_frds"
580    [(set (match_operand:V4SF 0 "spu_reg_operand" "")
581          (vec_select:V4SF
582            (vec_concat:V4SF
583              (float_truncate:V2SF (match_operand:V2DF 1 "spu_reg_operand" ""))
584              (match_dup:V2SF 2))
585            (parallel [(const_int 0)(const_int 2)(const_int 1)(const_int 3)])))]
586   ""
587   "operands[2] = spu_const(V2SFmode, 0);")
589 (define_insn "_frds"
590    [(set (match_operand:V4SF 0 "spu_reg_operand" "=r")
591         (vec_select:V4SF
592           (vec_concat:V4SF
593             (float_truncate:V2SF (match_operand:V2DF 1 "spu_reg_operand" "r"))
594             (match_operand:V2SF 2 "vec_imm_operand" "i"))
595           (parallel [(const_int 0)(const_int 2)(const_int 1)(const_int 3)])))]
596   ""
597   "frds\t%0,%1"
598   [(set_attr "type" "fpd")])
600 (define_insn "spu_fesd"
601   [(set (match_operand:V2DF 0 "spu_reg_operand" "=r")
602         (float_extend:V2DF
603           (vec_select:V2SF
604             (match_operand:V4SF 1 "spu_reg_operand" "r")
605               (parallel [(const_int 0)(const_int 2)]))))]
606   ""
607   "fesd\t%0,%1"
608   [(set_attr "type" "fpd")])
610 ;; control
611 (define_insn "spu_stop"
612   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "M")] UNSPEC_STOP)]
613   ""
614   "stop\t%0"
615   [(set_attr "type" "br")])
617 (define_insn "spu_stopd"
618   [(unspec_volatile [(match_operand:SI 0 "spu_reg_operand" "r")
619                      (match_operand:SI 1 "spu_reg_operand" "r")
620                      (match_operand:SI 2 "spu_reg_operand" "r")] UNSPEC_STOPD)]
621   ""
622   "stopd\t%0,%1,%2"
623   [(set_attr "type" "br")])
625 ;; interrupt disable/enable
626 (define_expand "spu_idisable"
627   [(parallel
628     [(unspec_volatile [(const_int 0)] UNSPEC_SET_INTR)
629      (clobber (match_dup:SI 0))
630      (clobber (mem:BLK (scratch)))])]
631   ""
632   "operands[0] = gen_reg_rtx (SImode);")
634 (define_expand "spu_ienable"
635   [(parallel
636     [(unspec_volatile [(const_int 1)] UNSPEC_SET_INTR)
637      (clobber (match_dup:SI 0))
638      (clobber (mem:BLK (scratch)))])]
639   ""
640   "operands[0] = gen_reg_rtx (SImode);")
642 (define_insn "set_intr"
643   [(unspec_volatile [(match_operand 1 "const_int_operand" "i")] UNSPEC_SET_INTR)
644    (clobber (match_operand:SI 0 "spu_reg_operand" "=&r"))
645    (clobber (mem:BLK (scratch)))]
646   "! flag_pic"
647   "ila\t%0,.+8\;bi%I1\t%0"
648   [(set_attr "length" "8")
649    (set_attr "type" "multi0")])
651 (define_insn "set_intr_pic"
652   [(unspec_volatile [(match_operand 1 "const_int_operand" "i")] UNSPEC_SET_INTR)
653    (clobber (match_operand:SI 0 "spu_reg_operand" "=&r"))
654    (clobber (mem:BLK (scratch)))]
655   "flag_pic"
656   "brsl\t%0,.+4\;ai\t%0,%0,8\;bi%I1\t%0"
657   [(set_attr "length" "12")
658    (set_attr "type" "multi1")])
660 (define_insn "set_intr_cc"
661   [(cond_exec (match_operator 1 "branch_comparison_operator"
662                 [(match_operand 2 "spu_reg_operand" "r")
663                  (const_int 0)])
664               (parallel [(unspec_volatile [(match_operand:SI 3 "const_int_operand" "i")] UNSPEC_SET_INTR)
665                          (clobber (match_operand:SI 0 "spu_reg_operand" "=&r"))
666                          (clobber (mem:BLK (scratch)))]))]
667   "! flag_pic"
668   "ila\t%0,.+8\;bi%b2%b1z%I3\t%2,%0"
669   [(set_attr "length" "8")
670    (set_attr "type" "multi0")])
672 (define_insn "set_intr_cc_pic"
673   [(cond_exec (match_operator 1 "branch_comparison_operator"
674                 [(match_operand 2 "spu_reg_operand" "r")
675                  (const_int 0)])
676               (parallel [(unspec_volatile [(match_operand:SI 3 "const_int_operand" "i")] UNSPEC_SET_INTR)
677                          (clobber (match_operand:SI 0 "spu_reg_operand" "=&r"))
678                          (clobber (mem:BLK (scratch)))]))]
679   "flag_pic"
680   "brsl\t%0,.+4\;ai\t%0,%0,8\;bi%b2%b1z%I3\t%2,%0"
681   [(set_attr "length" "12")
682    (set_attr "type" "multi1")])
684 (define_insn "set_intr_return"
685   [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")] UNSPEC_SET_INTR)
686    (return)]
687   ""
688   "bi%I0\t$lr"
689   [(set_attr "type" "br")])
691 (define_peephole2
692   [(parallel
693     [(unspec_volatile [(match_operand:SI 0 "const_int_operand")] UNSPEC_SET_INTR)
694      (clobber (match_operand:SI 1 "spu_reg_operand"))
695      (clobber (mem:BLK (scratch)))])
696    (use (reg:SI 0))
697    (return)]
698   ""
699   [(use (reg:SI 0))
700    (parallel
701     [(unspec_volatile [(match_dup:SI 0)] UNSPEC_SET_INTR)
702      (return)])]
703   "")
705 ;; special purpose registers
706 (define_insn "spu_fscrrd"
707   [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
708         (unspec_volatile:V4SI [(const_int 6)] UNSPEC_FSCRRD))]
709   ""
710   "fscrrd\t%0"
711   [(set_attr "type" "spr")])
713 (define_insn "spu_fscrwr"
714   [(unspec_volatile [(match_operand:V4SI 0 "spu_reg_operand" "r")] UNSPEC_FSCRWR)]
715   ""
716   "fscrwr\t$0,%0"
717   [(set_attr "type" "spr")])
719 (define_insn "spu_mfspr"
720   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
721         (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "J")] UNSPEC_MFSPR))]
722   ""
723   "mfspr\t%0,$sp%1"
724   [(set_attr "type" "spr")])
726 (define_insn "spu_mtspr"
727   [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "J")
728                      (match_operand:SI 1 "spu_reg_operand" "r")] UNSPEC_MTSPR)]
729   ""
730   "mtspr\t$sp%0,%1"
731   [(set_attr "type" "spr")])
733 ;; channels
734 (define_expand "spu_rdch"
735   [(set (match_operand:V4SI 0 "spu_reg_operand" "")
736         (unspec_volatile:V4SI [(match_operand:SI 1 "immediate_operand" "")] UNSPEC_RDCH))]
737   ""
738   "{
739     if (spu_safe_dma (INTVAL (operands[1])))
740       {
741         emit_insn (gen_spu_rdch_clobber (operands[0], operands[1]));
742         DONE;
743       }
744    }")
746 (define_expand "spu_rchcnt"
747   [(set (match_operand:SI 0 "spu_reg_operand" "")
748         (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "")] UNSPEC_RCHCNT))]
749   ""
750   "{
751     if (spu_safe_dma (INTVAL (operands[1])))
752       {
753         emit_insn (gen_spu_rchcnt_clobber (operands[0], operands[1]));
754         DONE;
755       }
756    }")
758 (define_expand "spu_wrch"
759    [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "")
760                       (match_operand:V4SI 1 "spu_reg_operand" "")] UNSPEC_WRCH)]
761    ""
762   "{
763     if (spu_safe_dma (INTVAL (operands[0])))
764       {
765         emit_insn (gen_spu_wrch_clobber (operands[0], operands[1]));
766         DONE;
767       }
768    }")
770 (define_insn "spu_rdch_noclobber"
771   [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
772         (unspec_volatile:V4SI [(match_operand:SI 1 "immediate_operand" "J")] UNSPEC_RDCH))]
773   ""
774   "rdch\t%0,$ch%1"
775   [(set_attr "type" "spr")])
777 (define_insn "spu_rchcnt_noclobber"
778   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
779         (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "J")] UNSPEC_RCHCNT))]
780   ""
781   "rchcnt\t%0,$ch%1"
782   [(set_attr "type" "spr")])
784 (define_insn "spu_wrch_noclobber"
785    [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "J")
786                       (match_operand:V4SI 1 "spu_reg_operand" "r")] UNSPEC_WRCH)]
787    ""
788    "wrch\t$ch%0,%1"
789    [(set_attr "type" "spr")])
791 (define_insn "spu_rdch_clobber"
792   [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
793         (unspec_volatile:V4SI [(match_operand:SI 1 "immediate_operand" "J")] UNSPEC_RDCH))
794     (clobber (mem:BLK (scratch)))]
795   ""
796   "rdch\t%0,$ch%1"
797   [(set_attr "type" "spr")])
799 (define_insn "spu_rchcnt_clobber"
800   [(set (match_operand:SI 0 "spu_reg_operand" "=r")
801         (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "J")] UNSPEC_RCHCNT))
802     (clobber (mem:BLK (scratch)))]
803   ""
804   "rchcnt\t%0,$ch%1"
805   [(set_attr "type" "spr")])
807 (define_insn "spu_wrch_clobber"
808    [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "J")
809                       (match_operand:V4SI 1 "spu_reg_operand" "r")] UNSPEC_WRCH)
810     (clobber (mem:BLK (scratch)))]
811    ""
812    "wrch\t$ch%0,%1"
813    [(set_attr "type" "spr")])
815 (define_expand "spu_splats" 
816   [(set (match_operand 0 "spu_reg_operand" "")
817         (vec_duplicate (match_operand 1 "spu_nonmem_operand" "")))]
818   ""
819   {
820     spu_builtin_splats(operands);
821     DONE;
822   })
824 (define_expand "spu_extract"
825   [(set (match_operand 0 "spu_reg_operand" "")
826         (unspec [(match_operand 1 "spu_reg_operand" "")
827                  (match_operand 2 "spu_nonmem_operand" "")] 0))]
828   ""
829   {
830     spu_builtin_extract (operands);
831     DONE;
832   })
834 (define_expand "spu_insert"
835   [(set (match_operand 0 "spu_reg_operand" "")
836         (unspec [(match_operand 1 "spu_reg_operand" "")
837                  (match_operand 2 "spu_reg_operand" "")
838                  (match_operand:SI 3 "spu_nonmem_operand" "")] 0))] 
839   ""
840   {
841     spu_builtin_insert(operands);
842     DONE;
843   })
845 (define_expand "spu_promote"
846   [(set (match_operand 0 "spu_reg_operand" "")
847         (unspec [(match_operand 1 "spu_reg_operand" "")
848                  (match_operand:SI 2 "immediate_operand" "")] 0))] 
849   ""
850   {
851     spu_builtin_promote(operands);
852     DONE;
853   })
855 ;; Currently doing nothing with this but expanding its args.
856 (define_expand "spu_align_hint"
857   [(unspec [(match_operand:SI 0 "address_operand" "")
858             (match_operand:SI 1 "immediate_operand" "")
859             (match_operand:SI 2 "immediate_operand" "")] 0)]
860   ""
861   {
862      DONE;
863   })