]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/spu/spu-builtins.md
re PR middle-end/91603 (Unaligned access in expand_assignment)
[thirdparty/gcc.git] / gcc / config / spu / spu-builtins.md
CommitLineData
a5544970 1;; Copyright (C) 2006-2019 Free Software Foundation, Inc.
85d9c13c
TS
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
2f83c7d6 5;; Software Foundation; either version 3 of the License, or (at your option)
85d9c13c
TS
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
2f83c7d6
NC
14;; along with GCC; see the file COPYING3. If not see
15;; <http://www.gnu.org/licenses/>.
85d9c13c
TS
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
85d9c13c
TS
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")])
216
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")])
233
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")])
250
85d9c13c
TS
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")])
267
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")])
284
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")])
294
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")])
301
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")])
308
309
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")])
317
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")])
324
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")])
331
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")])
340
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")])
348
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")])
356
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")
367
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")
376
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")
385
386;; or across
387
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")
393
394
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")
403
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")
411
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")
419
420;; branches
421
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.
427
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")])
439
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")])
451
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")])
463
464;; float convert
5345cf68
TS
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 ""
470{
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;
495})
496
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 ""
502{
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;
520})
521
522(define_expand "spu_cuflt"
85d9c13c 523 [(set (match_operand:V4SF 0 "spu_reg_operand" "=r")
5345cf68
TS
524 (unspec:V4SF [(match_operand:V4SI 1 "spu_reg_operand")
525 (match_operand:SI 2 "spu_nonmem_operand")] 0 ))]
526 ""
527{
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;
552})
553
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 ""
559{
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;
577})
85d9c13c
TS
578
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);")
588
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")])
599
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")])
609
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")])
616
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")])
624
625;; interrupt disable/enable
85d9c13c
TS
626(define_expand "spu_idisable"
627 [(parallel
73701e27 628 [(unspec_volatile [(const_int 0)] UNSPEC_SET_INTR)
85d9c13c
TS
629 (clobber (match_dup:SI 0))
630 (clobber (mem:BLK (scratch)))])]
631 ""
632 "operands[0] = gen_reg_rtx (SImode);")
633
634(define_expand "spu_ienable"
635 [(parallel
73701e27 636 [(unspec_volatile [(const_int 1)] UNSPEC_SET_INTR)
85d9c13c
TS
637 (clobber (match_dup:SI 0))
638 (clobber (mem:BLK (scratch)))])]
639 ""
640 "operands[0] = gen_reg_rtx (SImode);")
641
642(define_insn "set_intr"
73701e27 643 [(unspec_volatile [(match_operand 1 "const_int_operand" "i")] UNSPEC_SET_INTR)
85d9c13c
TS
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")])
650
651(define_insn "set_intr_pic"
73701e27 652 [(unspec_volatile [(match_operand 1 "const_int_operand" "i")] UNSPEC_SET_INTR)
85d9c13c
TS
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")])
659
85d9c13c 660(define_insn "set_intr_cc"
73701e27
TS
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)))]))]
85d9c13c
TS
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")])
671
672(define_insn "set_intr_cc_pic"
73701e27
TS
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)))]))]
85d9c13c 679 "flag_pic"
73701e27 680 "brsl\t%0,.+4\;ai\t%0,%0,8\;bi%b2%b1z%I3\t%2,%0"
85d9c13c
TS
681 [(set_attr "length" "12")
682 (set_attr "type" "multi1")])
683
684(define_insn "set_intr_return"
73701e27 685 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")] UNSPEC_SET_INTR)
85d9c13c
TS
686 (return)]
687 ""
688 "bi%I0\t$lr"
689 [(set_attr "type" "br")])
690
691(define_peephole2
692 [(parallel
73701e27 693 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")] UNSPEC_SET_INTR)
85d9c13c
TS
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
73701e27 701 [(unspec_volatile [(match_dup:SI 0)] UNSPEC_SET_INTR)
85d9c13c
TS
702 (return)])]
703 "")
704
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")])
712
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")])
718
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")])
725
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")])
732
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 }")
745
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 }")
757
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 }")
769
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")])
776
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")])
783
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")])
790
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")])
798
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")])
806
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")])
814
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 })
823
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 })
833
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 })
844
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 })
854
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 })
864