]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/spu/spu-builtins.md
host-hpux.c: Change copyright header to refer to version 3 of the GNU General Public...
[thirdparty/gcc.git] / gcc / config / spu / spu-builtins.md
1 ;; Copyright (C) 2006, 2007 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 3 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 GCC; see the file COPYING3. If not see
15 ;; <http://www.gnu.org/licenses/>.
16
17
18 ;; This includes expands for all the intrinsics.
19 ;; spu_expand_builtin looks at the mode of match_operand.
20
21 \f
22 ;; load/store
23
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 })
42
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 "")
50
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 })
61
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 "")
68
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 })
87
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 "")
95
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 })
106
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 "")
113
114 \f
115 ;; generate control word
116
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 "")
124
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 "")
132
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 "")
140
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 "")
148
149
150 \f
151 ;; Constant formation
152
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 }")
160
161 \f
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 "")
169
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 "")
176
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 "")
184
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 "")
191
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 "")
199
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")])
217
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")])
234
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")])
251
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")])
268
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")])
285
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")])
300
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")])
315
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")])
332
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")])
349
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")])
359
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")])
366
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")])
373
374
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")])
382
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")])
389
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")])
396
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")])
405
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")])
413
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")])
421
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")
432
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")
441
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")
450
451 ;; or across
452
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")
458
459
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")
468
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")
476
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")
484
485 ;; branches
486
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.
492
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")])
504
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")])
516
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")])
528
529 ;; float convert
530 (define_insn "spu_csflt"
531 [(set (match_operand:V4SF 0 "spu_reg_operand" "=r")
532 (unspec:V4SF [(match_operand:V4SI 1 "spu_reg_operand" "r")
533 (match_operand:SI 2 "immediate_operand" "K")] UNSPEC_CSFLT ))]
534 ""
535 "csflt\t%0,%1,%2"
536 [(set_attr "type" "fp7")])
537
538 (define_insn "spu_cflts"
539 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
540 (unspec:V4SI [(match_operand:V4SF 1 "spu_reg_operand" "r")
541 (match_operand:SI 2 "immediate_operand" "J")] UNSPEC_CFLTS ))]
542 ""
543 "cflts\t%0,%1,%2"
544 [(set_attr "type" "fp7")])
545
546 (define_insn "spu_cuflt"
547 [(set (match_operand:V4SF 0 "spu_reg_operand" "=r")
548 (unspec:V4SF [(match_operand:V4SI 1 "spu_reg_operand" "r")
549 (match_operand:SI 2 "immediate_operand" "K")] UNSPEC_CUFLT ))]
550 ""
551 "cuflt\t%0,%1,%2"
552 [(set_attr "type" "fp7")])
553
554 (define_insn "spu_cfltu"
555 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
556 (unspec:V4SI [(match_operand:V4SF 1 "spu_reg_operand" "r")
557 (match_operand:SI 2 "immediate_operand" "J")] UNSPEC_CFLTU ))]
558 ""
559 "cfltu\t%0,%1,%2"
560 [(set_attr "type" "fp7")])
561
562 (define_expand "spu_frds"
563 [(set (match_operand:V4SF 0 "spu_reg_operand" "")
564 (vec_select:V4SF
565 (vec_concat:V4SF
566 (float_truncate:V2SF (match_operand:V2DF 1 "spu_reg_operand" ""))
567 (match_dup:V2SF 2))
568 (parallel [(const_int 0)(const_int 2)(const_int 1)(const_int 3)])))]
569 ""
570 "operands[2] = spu_const(V2SFmode, 0);")
571
572 (define_insn "_frds"
573 [(set (match_operand:V4SF 0 "spu_reg_operand" "=r")
574 (vec_select:V4SF
575 (vec_concat:V4SF
576 (float_truncate:V2SF (match_operand:V2DF 1 "spu_reg_operand" "r"))
577 (match_operand:V2SF 2 "vec_imm_operand" "i"))
578 (parallel [(const_int 0)(const_int 2)(const_int 1)(const_int 3)])))]
579 ""
580 "frds\t%0,%1"
581 [(set_attr "type" "fpd")])
582
583 (define_insn "spu_fesd"
584 [(set (match_operand:V2DF 0 "spu_reg_operand" "=r")
585 (float_extend:V2DF
586 (vec_select:V2SF
587 (match_operand:V4SF 1 "spu_reg_operand" "r")
588 (parallel [(const_int 0)(const_int 2)]))))]
589 ""
590 "fesd\t%0,%1"
591 [(set_attr "type" "fpd")])
592
593 ;; control
594 (define_insn "spu_stop"
595 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "M")] UNSPEC_STOP)]
596 ""
597 "stop\t%0"
598 [(set_attr "type" "br")])
599
600 (define_insn "spu_stopd"
601 [(unspec_volatile [(match_operand:SI 0 "spu_reg_operand" "r")
602 (match_operand:SI 1 "spu_reg_operand" "r")
603 (match_operand:SI 2 "spu_reg_operand" "r")] UNSPEC_STOPD)]
604 ""
605 "stopd\t%0,%1,%2"
606 [(set_attr "type" "br")])
607
608 ;; interrupt disable/enable
609 (define_expand "spu_idisable"
610 [(parallel
611 [(unspec_volatile [(const_int 0)] UNSPEC_SET_INTR)
612 (clobber (match_dup:SI 0))
613 (clobber (mem:BLK (scratch)))])]
614 ""
615 "operands[0] = gen_reg_rtx (SImode);")
616
617 (define_expand "spu_ienable"
618 [(parallel
619 [(unspec_volatile [(const_int 1)] UNSPEC_SET_INTR)
620 (clobber (match_dup:SI 0))
621 (clobber (mem:BLK (scratch)))])]
622 ""
623 "operands[0] = gen_reg_rtx (SImode);")
624
625 (define_insn "set_intr"
626 [(unspec_volatile [(match_operand 1 "const_int_operand" "i")] UNSPEC_SET_INTR)
627 (clobber (match_operand:SI 0 "spu_reg_operand" "=&r"))
628 (clobber (mem:BLK (scratch)))]
629 "! flag_pic"
630 "ila\t%0,.+8\;bi%I1\t%0"
631 [(set_attr "length" "8")
632 (set_attr "type" "multi0")])
633
634 (define_insn "set_intr_pic"
635 [(unspec_volatile [(match_operand 1 "const_int_operand" "i")] UNSPEC_SET_INTR)
636 (clobber (match_operand:SI 0 "spu_reg_operand" "=&r"))
637 (clobber (mem:BLK (scratch)))]
638 "flag_pic"
639 "brsl\t%0,.+4\;ai\t%0,%0,8\;bi%I1\t%0"
640 [(set_attr "length" "12")
641 (set_attr "type" "multi1")])
642
643 (define_insn "set_intr_cc"
644 [(cond_exec (match_operator 1 "branch_comparison_operator"
645 [(match_operand 2 "spu_reg_operand" "r")
646 (const_int 0)])
647 (parallel [(unspec_volatile [(match_operand:SI 3 "const_int_operand" "i")] UNSPEC_SET_INTR)
648 (clobber (match_operand:SI 0 "spu_reg_operand" "=&r"))
649 (clobber (mem:BLK (scratch)))]))]
650 "! flag_pic"
651 "ila\t%0,.+8\;bi%b2%b1z%I3\t%2,%0"
652 [(set_attr "length" "8")
653 (set_attr "type" "multi0")])
654
655 (define_insn "set_intr_cc_pic"
656 [(cond_exec (match_operator 1 "branch_comparison_operator"
657 [(match_operand 2 "spu_reg_operand" "r")
658 (const_int 0)])
659 (parallel [(unspec_volatile [(match_operand:SI 3 "const_int_operand" "i")] UNSPEC_SET_INTR)
660 (clobber (match_operand:SI 0 "spu_reg_operand" "=&r"))
661 (clobber (mem:BLK (scratch)))]))]
662 "flag_pic"
663 "brsl\t%0,.+4\;ai\t%0,%0,8\;bi%b2%b1z%I3\t%2,%0"
664 [(set_attr "length" "12")
665 (set_attr "type" "multi1")])
666
667 (define_insn "set_intr_return"
668 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")] UNSPEC_SET_INTR)
669 (return)]
670 ""
671 "bi%I0\t$lr"
672 [(set_attr "type" "br")])
673
674 (define_peephole2
675 [(parallel
676 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")] UNSPEC_SET_INTR)
677 (clobber (match_operand:SI 1 "spu_reg_operand"))
678 (clobber (mem:BLK (scratch)))])
679 (use (reg:SI 0))
680 (return)]
681 ""
682 [(use (reg:SI 0))
683 (parallel
684 [(unspec_volatile [(match_dup:SI 0)] UNSPEC_SET_INTR)
685 (return)])]
686 "")
687
688 ;; special purpose registers
689 (define_insn "spu_fscrrd"
690 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
691 (unspec_volatile:V4SI [(const_int 6)] UNSPEC_FSCRRD))]
692 ""
693 "fscrrd\t%0"
694 [(set_attr "type" "spr")])
695
696 (define_insn "spu_fscrwr"
697 [(unspec_volatile [(match_operand:V4SI 0 "spu_reg_operand" "r")] UNSPEC_FSCRWR)]
698 ""
699 "fscrwr\t$0,%0"
700 [(set_attr "type" "spr")])
701
702 (define_insn "spu_mfspr"
703 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
704 (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "J")] UNSPEC_MFSPR))]
705 ""
706 "mfspr\t%0,$sp%1"
707 [(set_attr "type" "spr")])
708
709 (define_insn "spu_mtspr"
710 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "J")
711 (match_operand:SI 1 "spu_reg_operand" "r")] UNSPEC_MTSPR)]
712 ""
713 "mtspr\t$sp%0,%1"
714 [(set_attr "type" "spr")])
715
716 ;; channels
717 (define_expand "spu_rdch"
718 [(set (match_operand:V4SI 0 "spu_reg_operand" "")
719 (unspec_volatile:V4SI [(match_operand:SI 1 "immediate_operand" "")] UNSPEC_RDCH))]
720 ""
721 "{
722 if (spu_safe_dma (INTVAL (operands[1])))
723 {
724 emit_insn (gen_spu_rdch_clobber (operands[0], operands[1]));
725 DONE;
726 }
727 }")
728
729 (define_expand "spu_rchcnt"
730 [(set (match_operand:SI 0 "spu_reg_operand" "")
731 (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "")] UNSPEC_RCHCNT))]
732 ""
733 "{
734 if (spu_safe_dma (INTVAL (operands[1])))
735 {
736 emit_insn (gen_spu_rchcnt_clobber (operands[0], operands[1]));
737 DONE;
738 }
739 }")
740
741 (define_expand "spu_wrch"
742 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "")
743 (match_operand:V4SI 1 "spu_reg_operand" "")] UNSPEC_WRCH)]
744 ""
745 "{
746 if (spu_safe_dma (INTVAL (operands[0])))
747 {
748 emit_insn (gen_spu_wrch_clobber (operands[0], operands[1]));
749 DONE;
750 }
751 }")
752
753 (define_insn "spu_rdch_noclobber"
754 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
755 (unspec_volatile:V4SI [(match_operand:SI 1 "immediate_operand" "J")] UNSPEC_RDCH))]
756 ""
757 "rdch\t%0,$ch%1"
758 [(set_attr "type" "spr")])
759
760 (define_insn "spu_rchcnt_noclobber"
761 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
762 (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "J")] UNSPEC_RCHCNT))]
763 ""
764 "rchcnt\t%0,$ch%1"
765 [(set_attr "type" "spr")])
766
767 (define_insn "spu_wrch_noclobber"
768 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "J")
769 (match_operand:V4SI 1 "spu_reg_operand" "r")] UNSPEC_WRCH)]
770 ""
771 "wrch\t$ch%0,%1"
772 [(set_attr "type" "spr")])
773
774 (define_insn "spu_rdch_clobber"
775 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
776 (unspec_volatile:V4SI [(match_operand:SI 1 "immediate_operand" "J")] UNSPEC_RDCH))
777 (clobber (mem:BLK (scratch)))]
778 ""
779 "rdch\t%0,$ch%1"
780 [(set_attr "type" "spr")])
781
782 (define_insn "spu_rchcnt_clobber"
783 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
784 (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "J")] UNSPEC_RCHCNT))
785 (clobber (mem:BLK (scratch)))]
786 ""
787 "rchcnt\t%0,$ch%1"
788 [(set_attr "type" "spr")])
789
790 (define_insn "spu_wrch_clobber"
791 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "J")
792 (match_operand:V4SI 1 "spu_reg_operand" "r")] UNSPEC_WRCH)
793 (clobber (mem:BLK (scratch)))]
794 ""
795 "wrch\t$ch%0,%1"
796 [(set_attr "type" "spr")])
797
798 (define_expand "spu_splats"
799 [(set (match_operand 0 "spu_reg_operand" "")
800 (vec_duplicate (match_operand 1 "spu_nonmem_operand" "")))]
801 ""
802 {
803 spu_builtin_splats(operands);
804 DONE;
805 })
806
807 (define_expand "spu_extract"
808 [(set (match_operand 0 "spu_reg_operand" "")
809 (unspec [(match_operand 1 "spu_reg_operand" "")
810 (match_operand 2 "spu_nonmem_operand" "")] 0))]
811 ""
812 {
813 spu_builtin_extract (operands);
814 DONE;
815 })
816
817 (define_expand "spu_insert"
818 [(set (match_operand 0 "spu_reg_operand" "")
819 (unspec [(match_operand 1 "spu_reg_operand" "")
820 (match_operand 2 "spu_reg_operand" "")
821 (match_operand:SI 3 "spu_nonmem_operand" "")] 0))]
822 ""
823 {
824 spu_builtin_insert(operands);
825 DONE;
826 })
827
828 (define_expand "spu_promote"
829 [(set (match_operand 0 "spu_reg_operand" "")
830 (unspec [(match_operand 1 "spu_reg_operand" "")
831 (match_operand:SI 2 "immediate_operand" "")] 0))]
832 ""
833 {
834 spu_builtin_promote(operands);
835 DONE;
836 })
837
838 ;; Currently doing nothing with this but expanding its args.
839 (define_expand "spu_align_hint"
840 [(unspec [(match_operand:SI 0 "address_operand" "")
841 (match_operand:SI 1 "immediate_operand" "")
842 (match_operand:SI 2 "immediate_operand" "")] 0)]
843 ""
844 {
845 DONE;
846 })
847