1 ;; Copyright (C) 2006, 2007, 2008, 2009 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)
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
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/>.
17 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
20 ;; Define an insn type attribute. This is used in function unit delay
22 ;; multi0 is a multiple insn rtl whose first insn is in pipe0
23 ;; multi1 is a multiple insn rtl whose first insn is in pipe1
24 (define_attr "type" "fx2,shuf,fx3,load,store,br,spr,lnop,nop,fxb,fp6,fp7,fpd,iprefetch,multi0,multi1,hbr,convert"
28 (define_attr "length" ""
31 (define_attr "tune" "cell,celledp" (const (symbol_ref "spu_tune")))
32 ;; Processor type -- this attribute must exactly match the processor_type
33 ;; enumeration in spu.h.
35 (define_attr "cpu" "spu"
36 (const (symbol_ref "spu_cpu_attr")))
38 ; (define_function_unit NAME MULTIPLICITY SIMULTANEITY
39 ; TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST])
41 (define_cpu_unit "pipe0,pipe1,fp,ls")
43 (define_insn_reservation "NOP" 1 (eq_attr "type" "nop")
46 (define_insn_reservation "FX2" 2 (eq_attr "type" "fx2")
49 (define_insn_reservation "FX3" 4 (eq_attr "type" "fx3,fxb")
52 (define_insn_reservation "FP6" 6 (eq_attr "type" "fp6")
53 "pipe0 + fp, nothing*5")
55 (define_insn_reservation "FP7" 7 (eq_attr "type" "fp7")
56 "pipe0, fp, nothing*5")
58 ;; The behavior of the double precision is that both pipes stall
59 ;; for 6 cycles and the rest of the operation pipelines for
60 ;; 7 cycles. The simplest way to model this is to simply ignore
62 (define_insn_reservation "FPD" 7
63 (and (eq_attr "tune" "cell")
64 (eq_attr "type" "fpd"))
65 "pipe0 + pipe1, fp, nothing*5")
67 ;; Tune for CELLEDP, 9 cycles, dual-issuable, fully pipelined
68 (define_insn_reservation "FPD_CELLEDP" 9
69 (and (eq_attr "tune" "celledp")
70 (eq_attr "type" "fpd"))
71 "pipe0 + fp, nothing*8")
73 (define_insn_reservation "LNOP" 1 (eq_attr "type" "lnop")
76 (define_insn_reservation "STORE" 1 (eq_attr "type" "store")
79 (define_insn_reservation "IPREFETCH" 1 (eq_attr "type" "iprefetch")
82 (define_insn_reservation "SHUF" 4 (eq_attr "type" "shuf,br,spr")
85 (define_insn_reservation "LOAD" 6 (eq_attr "type" "load")
86 "pipe1 + ls, nothing*5")
88 (define_insn_reservation "HBR" 18 (eq_attr "type" "hbr")
91 (define_insn_reservation "MULTI0" 4 (eq_attr "type" "multi0")
92 "pipe0+pipe1, nothing*3")
94 (define_insn_reservation "MULTI1" 4 (eq_attr "type" "multi1")
97 (define_insn_reservation "CONVERT" 0 (eq_attr "type" "convert")
100 ;; Force pipe0 to occur before pipe 1 in a cycle.
101 (absence_set "pipe0" "pipe1")
110 (UNSPEC_EXTEND_CMP 5)
149 (UNSPEC_SPU_REALIGN_LOAD 49)
150 (UNSPEC_SPU_MASK_FOR_LOAD 50)
152 (UNSPEC_FLOAT_EXTEND 52)
153 (UNSPEC_FLOAT_TRUNCATE 53)
158 (include "predicates.md")
159 (include "constraints.md")
164 (define_mode_iterator ALL [QI V16QI
172 ; Everything except DI and TI which are handled separately because
173 ; they need different constraints to correctly test VOIDmode constants
174 (define_mode_iterator MOV [QI V16QI
181 (define_mode_iterator QHSI [QI HI SI])
182 (define_mode_iterator QHSDI [QI HI SI DI])
183 (define_mode_iterator DTI [DI TI])
185 (define_mode_iterator VINT [QI V16QI
191 (define_mode_iterator VQHSI [QI V16QI
195 (define_mode_iterator VHSI [HI V8HI
198 (define_mode_iterator VSDF [SF V4SF
201 (define_mode_iterator VSI [SI V4SI])
202 (define_mode_iterator VDI [DI V2DI])
203 (define_mode_iterator VSF [SF V4SF])
204 (define_mode_iterator VDF [DF V2DF])
206 (define_mode_iterator VCMP [V16QI
212 (define_mode_iterator VCMPU [V16QI
216 (define_mode_attr v [(V8HI "v") (V4SI "v")
219 (define_mode_attr bh [(QI "b") (V16QI "b")
223 (define_mode_attr d [(SF "") (V4SF "")
224 (DF "d") (V2DF "d")])
225 (define_mode_attr d6 [(SF "6") (V4SF "6")
226 (DF "d") (V2DF "d")])
228 (define_mode_attr f2i [(SF "si") (V4SF "v4si")
229 (DF "di") (V2DF "v2di")])
230 (define_mode_attr F2I [(SF "SI") (V4SF "V4SI")
231 (DF "DI") (V2DF "V2DI")])
232 (define_mode_attr i2f [(SI "sf") (V4SI "v4sf")
233 (DI "df") (V2DI "v2df")])
234 (define_mode_attr I2F [(SI "SF") (V4SI "V4SF")
235 (DI "DF") (V2DI "V2DF")])
237 (define_mode_attr DF2I [(DF "SI") (V2DF "V2DI")])
239 (define_mode_attr umask [(HI "f") (V8HI "f")
240 (SI "g") (V4SI "g")])
241 (define_mode_attr nmask [(HI "F") (V8HI "F")
242 (SI "G") (V4SI "G")])
244 ;; Used for carry and borrow instructions.
245 (define_mode_iterator CBOP [SI DI V4SI V2DI])
247 ;; Used in vec_set and vec_extract
248 (define_mode_iterator V [V2DI V4SI V8HI V16QI V2DF V4SF])
249 (define_mode_attr inner [(V16QI "QI")
255 (define_mode_attr vmult [(V16QI "1")
261 (define_mode_attr voff [(V16QI "13")
271 (define_expand "mov<mode>"
272 [(set (match_operand:ALL 0 "spu_nonimm_operand" "=r,r,r,m")
273 (match_operand:ALL 1 "general_operand" "r,i,m,r"))]
276 if (spu_expand_mov(operands, <MODE>mode))
281 [(set (match_operand 0 "spu_reg_operand")
282 (match_operand 1 "immediate_operand"))]
286 (high (match_dup 1)))
288 (lo_sum (match_dup 0)
291 if (spu_split_immediate (operands))
297 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
298 (match_operand:SI 1 "immediate_operand" "s"))
303 ;; Whenever a function generates the 'pic' pattern above we need to
304 ;; load the pic_offset_table register.
305 ;; GCC doesn't deal well with labels in the middle of a block so we
306 ;; hardcode the offsets in the asm here.
307 (define_insn "load_pic_offset"
308 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
309 (unspec:SI [(const_int 0)] 0))
310 (set (match_operand:SI 1 "spu_reg_operand" "=r")
311 (unspec:SI [(const_int 0)] 0))]
313 "ila\t%1,.+8\;brsl\t%0,4"
314 [(set_attr "length" "8")
315 (set_attr "type" "multi0")])
320 (define_insn "_mov<mode>"
321 [(set (match_operand:MOV 0 "spu_dest_operand" "=r,r,r,r,r,m")
322 (match_operand:MOV 1 "spu_mov_operand" "r,A,f,j,m,r"))]
323 "register_operand(operands[0], <MODE>mode)
324 || register_operand(operands[1], <MODE>mode)"
332 [(set_attr "type" "fx2,fx2,shuf,shuf,load,store")])
334 (define_insn "low_<mode>"
335 [(set (match_operand:VSI 0 "spu_reg_operand" "=r")
336 (lo_sum:VSI (match_operand:VSI 1 "spu_reg_operand" "0")
337 (match_operand:VSI 2 "immediate_operand" "i")))]
341 (define_insn "_movdi"
342 [(set (match_operand:DI 0 "spu_dest_operand" "=r,r,r,r,r,m")
343 (match_operand:DI 1 "spu_mov_operand" "r,a,f,k,m,r"))]
344 "register_operand(operands[0], DImode)
345 || register_operand(operands[1], DImode)"
353 [(set_attr "type" "fx2,fx2,shuf,shuf,load,store")])
355 (define_insn "_movti"
356 [(set (match_operand:TI 0 "spu_dest_operand" "=r,r,r,r,r,m")
357 (match_operand:TI 1 "spu_mov_operand" "r,U,f,l,m,r"))]
358 "register_operand(operands[0], TImode)
359 || register_operand(operands[1], TImode)"
367 [(set_attr "type" "fx2,fx2,shuf,shuf,load,store")])
370 [(set (match_operand 0 "spu_reg_operand")
371 (match_operand 1 "memory_operand"))]
372 "GET_MODE_SIZE (GET_MODE (operands[0])) < 16
373 && GET_MODE(operands[0]) == GET_MODE(operands[1])
374 && !reload_in_progress && !reload_completed"
377 { if (spu_split_load(operands))
382 [(set (match_operand 0 "memory_operand")
383 (match_operand 1 "spu_reg_operand"))]
384 "GET_MODE_SIZE (GET_MODE (operands[0])) < 16
385 && GET_MODE(operands[0]) == GET_MODE(operands[1])
386 && !reload_in_progress && !reload_completed"
389 { if (spu_split_store(operands))
392 ;; Operand 3 is the number of bytes. 1:b 2:h 4:w 8:d
394 (define_expand "cpat"
395 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
396 (unspec:TI [(match_operand:SI 1 "spu_reg_operand" "r,r")
397 (match_operand:SI 2 "spu_nonmem_operand" "r,n")
398 (match_operand:SI 3 "immediate_operand" "i,i")] UNSPEC_CPAT))]
401 rtx x = gen_cpat_const (operands);
404 emit_move_insn (operands[0], x);
410 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
411 (unspec:TI [(match_operand:SI 1 "spu_reg_operand" "r,r")
412 (match_operand:SI 2 "spu_nonmem_operand" "r,n")
413 (match_operand:SI 3 "immediate_operand" "i,i")] UNSPEC_CPAT))]
418 [(set_attr "type" "shuf")])
421 [(set (match_operand:TI 0 "spu_reg_operand")
422 (unspec:TI [(match_operand:SI 1 "spu_nonmem_operand")
423 (match_operand:SI 2 "immediate_operand")
424 (match_operand:SI 3 "immediate_operand")] UNSPEC_CPAT))]
426 [(set (match_dup:TI 0)
429 operands[4] = gen_cpat_const (operands);
436 (define_insn "extendqihi2"
437 [(set (match_operand:HI 0 "spu_reg_operand" "=r")
438 (sign_extend:HI (match_operand:QI 1 "spu_reg_operand" "r")))]
442 (define_insn "extendhisi2"
443 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
444 (sign_extend:SI (match_operand:HI 1 "spu_reg_operand" "r")))]
448 (define_expand "extendsidi2"
449 [(set (match_dup:DI 2)
450 (zero_extend:DI (match_operand:SI 1 "spu_reg_operand" "")))
451 (set (match_operand:DI 0 "spu_reg_operand" "")
452 (sign_extend:DI (vec_select:SI (match_dup:V2SI 3)
453 (parallel [(const_int 1)]))))]
456 operands[2] = gen_reg_rtx (DImode);
457 operands[3] = spu_gen_subreg (V2SImode, operands[2]);
461 [(set (match_operand:DI 0 "spu_reg_operand" "=r")
464 (match_operand:V2SI 1 "spu_reg_operand" "r")
465 (parallel [(const_int 1) ]))))]
469 ;; By splitting this late we don't allow much opportunity for sharing of
470 ;; constants. That's ok because this should really be optimized away.
471 (define_insn_and_split "extend<mode>ti2"
472 [(set (match_operand:TI 0 "register_operand" "")
473 (sign_extend:TI (match_operand:QHSDI 1 "register_operand" "")))]
477 [(set (match_dup:TI 0)
478 (sign_extend:TI (match_dup:QHSDI 1)))]
480 spu_expand_sign_extend(operands);
487 (define_insn "zero_extendqihi2"
488 [(set (match_operand:HI 0 "spu_reg_operand" "=r")
489 (zero_extend:HI (match_operand:QI 1 "spu_reg_operand" "r")))]
491 "andi\t%0,%1,0x00ff")
493 (define_insn "zero_extendqisi2"
494 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
495 (zero_extend:SI (match_operand:QI 1 "spu_reg_operand" "r")))]
497 "andi\t%0,%1,0x00ff")
499 (define_expand "zero_extendhisi2"
500 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
501 (zero_extend:SI (match_operand:HI 1 "spu_reg_operand" "r")))
502 (clobber (match_scratch:SI 2 "=&r"))]
505 rtx mask = gen_reg_rtx (SImode);
506 rtx op1 = simplify_gen_subreg (SImode, operands[1], HImode, 0);
507 emit_move_insn (mask, GEN_INT (0xffff));
508 emit_insn (gen_andsi3(operands[0], op1, mask));
512 (define_insn "zero_extendsidi2"
513 [(set (match_operand:DI 0 "spu_reg_operand" "=r")
514 (zero_extend:DI (match_operand:SI 1 "spu_reg_operand" "r")))]
517 [(set_attr "type" "shuf")])
519 (define_insn "zero_extendqiti2"
520 [(set (match_operand:TI 0 "spu_reg_operand" "=r")
521 (zero_extend:TI (match_operand:QI 1 "spu_reg_operand" "r")))]
523 "andi\t%0,%1,0x00ff\;rotqmbyi\t%0,%0,-12"
524 [(set_attr "type" "multi0")
525 (set_attr "length" "8")])
527 (define_insn "zero_extendhiti2"
528 [(set (match_operand:TI 0 "spu_reg_operand" "=r")
529 (zero_extend:TI (match_operand:HI 1 "spu_reg_operand" "r")))]
531 "shli\t%0,%1,16\;rotqmbyi\t%0,%0,-14"
532 [(set_attr "type" "multi1")
533 (set_attr "length" "8")])
535 (define_insn "zero_extendsiti2"
536 [(set (match_operand:TI 0 "spu_reg_operand" "=r")
537 (zero_extend:TI (match_operand:SI 1 "spu_reg_operand" "r")))]
539 "rotqmbyi\t%0,%1,-12"
540 [(set_attr "type" "shuf")])
542 (define_insn "zero_extendditi2"
543 [(set (match_operand:TI 0 "spu_reg_operand" "=r")
544 (zero_extend:TI (match_operand:DI 1 "spu_reg_operand" "r")))]
547 [(set_attr "type" "shuf")])
552 (define_insn "truncdiqi2"
553 [(set (match_operand:QI 0 "spu_reg_operand" "=r")
554 (truncate:QI (match_operand:DI 1 "spu_reg_operand" "r")))]
557 [(set_attr "type" "shuf")])
559 (define_insn "truncdihi2"
560 [(set (match_operand:HI 0 "spu_reg_operand" "=r")
561 (truncate:HI (match_operand:DI 1 "spu_reg_operand" "r")))]
564 [(set_attr "type" "shuf")])
566 (define_insn "truncdisi2"
567 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
568 (truncate:SI (match_operand:DI 1 "spu_reg_operand" "r")))]
571 [(set_attr "type" "shuf")])
573 (define_insn "trunctiqi2"
574 [(set (match_operand:QI 0 "spu_reg_operand" "=r")
575 (truncate:QI (match_operand:TI 1 "spu_reg_operand" "r")))]
578 [(set_attr "type" "shuf")])
580 (define_insn "trunctihi2"
581 [(set (match_operand:HI 0 "spu_reg_operand" "=r")
582 (truncate:HI (match_operand:TI 1 "spu_reg_operand" "r")))]
585 [(set_attr "type" "shuf")])
587 (define_insn "trunctisi2"
588 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
589 (truncate:SI (match_operand:TI 1 "spu_reg_operand" "r")))]
592 [(set_attr "type" "shuf")])
594 (define_insn "trunctidi2"
595 [(set (match_operand:DI 0 "spu_reg_operand" "=r")
596 (truncate:DI (match_operand:TI 1 "spu_reg_operand" "r")))]
599 [(set_attr "type" "shuf")])
604 (define_insn "float<mode><i2f>2"
605 [(set (match_operand:<I2F> 0 "spu_reg_operand" "=r")
606 (float:<I2F> (match_operand:VSI 1 "spu_reg_operand" "r")))]
609 [(set_attr "type" "fp7")])
611 (define_insn "fix_trunc<mode><f2i>2"
612 [(set (match_operand:<F2I> 0 "spu_reg_operand" "=r")
613 (fix:<F2I> (match_operand:VSF 1 "spu_reg_operand" "r")))]
616 [(set_attr "type" "fp7")])
618 (define_insn "floatuns<mode><i2f>2"
619 [(set (match_operand:<I2F> 0 "spu_reg_operand" "=r")
620 (unsigned_float:<I2F> (match_operand:VSI 1 "spu_reg_operand" "r")))]
623 [(set_attr "type" "fp7")])
625 (define_insn "fixuns_trunc<mode><f2i>2"
626 [(set (match_operand:<F2I> 0 "spu_reg_operand" "=r")
627 (unsigned_fix:<F2I> (match_operand:VSF 1 "spu_reg_operand" "r")))]
630 [(set_attr "type" "fp7")])
632 (define_insn "float<mode><i2f>2_mul"
633 [(set (match_operand:<I2F> 0 "spu_reg_operand" "=r")
634 (mult:<I2F> (float:<I2F> (match_operand:VSI 1 "spu_reg_operand" "r"))
635 (match_operand:<I2F> 2 "spu_inv_exp2_operand" "w")))]
638 [(set_attr "type" "fp7")])
640 (define_insn "float<mode><i2f>2_div"
641 [(set (match_operand:<I2F> 0 "spu_reg_operand" "=r")
642 (div:<I2F> (float:<I2F> (match_operand:VSI 1 "spu_reg_operand" "r"))
643 (match_operand:<I2F> 2 "spu_exp2_operand" "v")))]
646 [(set_attr "type" "fp7")])
649 (define_insn "fix_trunc<mode><f2i>2_mul"
650 [(set (match_operand:<F2I> 0 "spu_reg_operand" "=r")
651 (fix:<F2I> (mult:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
652 (match_operand:VSF 2 "spu_exp2_operand" "v"))))]
655 [(set_attr "type" "fp7")])
657 (define_insn "floatuns<mode><i2f>2_mul"
658 [(set (match_operand:<I2F> 0 "spu_reg_operand" "=r")
659 (mult:<I2F> (unsigned_float:<I2F> (match_operand:VSI 1 "spu_reg_operand" "r"))
660 (match_operand:<I2F> 2 "spu_inv_exp2_operand" "w")))]
663 [(set_attr "type" "fp7")])
665 (define_insn "floatuns<mode><i2f>2_div"
666 [(set (match_operand:<I2F> 0 "spu_reg_operand" "=r")
667 (div:<I2F> (unsigned_float:<I2F> (match_operand:VSI 1 "spu_reg_operand" "r"))
668 (match_operand:<I2F> 2 "spu_exp2_operand" "v")))]
671 [(set_attr "type" "fp7")])
673 (define_insn "fixuns_trunc<mode><f2i>2_mul"
674 [(set (match_operand:<F2I> 0 "spu_reg_operand" "=r")
675 (unsigned_fix:<F2I> (mult:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
676 (match_operand:VSF 2 "spu_exp2_operand" "v"))))]
679 [(set_attr "type" "fp7")])
681 (define_insn "extendsfdf2"
682 [(set (match_operand:DF 0 "spu_reg_operand" "=r")
683 (unspec:DF [(match_operand:SF 1 "spu_reg_operand" "r")]
684 UNSPEC_FLOAT_EXTEND))]
687 [(set_attr "type" "fpd")])
689 (define_insn "truncdfsf2"
690 [(set (match_operand:SF 0 "spu_reg_operand" "=r")
691 (unspec:SF [(match_operand:DF 1 "spu_reg_operand" "r")]
692 UNSPEC_FLOAT_TRUNCATE))]
695 [(set_attr "type" "fpd")])
697 (define_expand "floatdisf2"
698 [(set (match_operand:SF 0 "register_operand" "")
699 (float:SF (match_operand:DI 1 "register_operand" "")))]
702 rtx c0 = gen_reg_rtx (SImode);
703 rtx r0 = gen_reg_rtx (DImode);
704 rtx r1 = gen_reg_rtx (SFmode);
705 rtx r2 = gen_reg_rtx (SImode);
706 rtx setneg = gen_reg_rtx (SImode);
707 rtx isneg = gen_reg_rtx (SImode);
708 rtx neg = gen_reg_rtx (DImode);
709 rtx mask = gen_reg_rtx (DImode);
711 emit_move_insn (c0, GEN_INT (-0x80000000ll));
713 emit_insn (gen_negdi2 (neg, operands[1]));
714 emit_insn (gen_cgt_di_m1 (isneg, operands[1]));
715 emit_insn (gen_extend_compare (mask, isneg));
716 emit_insn (gen_selb (r0, neg, operands[1], mask));
717 emit_insn (gen_andc_si (setneg, c0, isneg));
719 emit_insn (gen_floatunsdisf2 (r1, r0));
721 emit_insn (gen_iorsi3 (r2, gen_rtx_SUBREG (SImode, r1, 0), setneg));
722 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, r2, 0));
726 (define_insn_and_split "floatunsdisf2"
727 [(set (match_operand:SF 0 "register_operand" "=r")
728 (unsigned_float:SF (match_operand:DI 1 "register_operand" "r")))
729 (clobber (match_scratch:SF 2 "=r"))
730 (clobber (match_scratch:SF 3 "=r"))
731 (clobber (match_scratch:SF 4 "=r"))]
735 [(set (match_dup:SF 0)
736 (unsigned_float:SF (match_dup:DI 1)))]
738 rtx op1_v4si = gen_rtx_REG (V4SImode, REGNO (operands[1]));
739 rtx op2_v4sf = gen_rtx_REG (V4SFmode, REGNO (operands[2]));
740 rtx op2_ti = gen_rtx_REG (TImode, REGNO (operands[2]));
741 rtx op3_ti = gen_rtx_REG (TImode, REGNO (operands[3]));
743 REAL_VALUE_TYPE scale;
744 real_2expN (&scale, 32, SFmode);
746 emit_insn (gen_floatunsv4siv4sf2 (op2_v4sf, op1_v4si));
747 emit_insn (gen_shlqby_ti (op3_ti, op2_ti, GEN_INT (4)));
749 emit_move_insn (operands[4],
750 CONST_DOUBLE_FROM_REAL_VALUE (scale, SFmode));
751 emit_insn (gen_fma_sf (operands[0],
752 operands[2], operands[4], operands[3]));
756 ;; Do (double)(operands[1]+0x80000000u)-(double)0x80000000
757 (define_expand "floatsidf2"
758 [(set (match_operand:DF 0 "register_operand" "")
759 (float:DF (match_operand:SI 1 "register_operand" "")))]
762 rtx c0 = gen_reg_rtx (SImode);
763 rtx c1 = gen_reg_rtx (DFmode);
764 rtx r0 = gen_reg_rtx (SImode);
765 rtx r1 = gen_reg_rtx (DFmode);
767 emit_move_insn (c0, GEN_INT (-0x80000000ll));
768 emit_move_insn (c1, spu_float_const ("2147483648", DFmode));
769 emit_insn (gen_xorsi3 (r0, operands[1], c0));
770 emit_insn (gen_floatunssidf2 (r1, r0));
771 emit_insn (gen_subdf3 (operands[0], r1, c1));
775 (define_expand "floatunssidf2"
776 [(set (match_operand:DF 0 "register_operand" "=r")
777 (unsigned_float:DF (match_operand:SI 1 "register_operand" "r")))]
781 rtx c0 = spu_const_from_ints (V16QImode, 0x02031011, 0x12138080,
782 0x06071415, 0x16178080);
783 rtx r0 = gen_reg_rtx (V16QImode);
789 emit_library_call_value (convert_optab_libfunc (ufloat_optab,
791 NULL_RTX, LCT_NORMAL, DFmode, 1, operands[1], SImode);
792 insns = get_insns ();
794 emit_libcall_block (insns, operands[0], value,
795 gen_rtx_UNSIGNED_FLOAT (DFmode, operands[1]));
799 emit_move_insn (r0, c0);
800 emit_insn (gen_floatunssidf2_internal (operands[0], operands[1], r0));
805 (define_insn_and_split "floatunssidf2_internal"
806 [(set (match_operand:DF 0 "register_operand" "=r")
807 (unsigned_float:DF (match_operand:SI 1 "register_operand" "r")))
808 (use (match_operand:V16QI 2 "register_operand" "r"))
809 (clobber (match_scratch:V4SI 3 "=&r"))
810 (clobber (match_scratch:V4SI 4 "=&r"))
811 (clobber (match_scratch:V4SI 5 "=&r"))
812 (clobber (match_scratch:V4SI 6 "=&r"))]
814 "clz\t%3,%1\;il\t%6,1023+31\;shl\t%4,%1,%3\;ceqi\t%5,%3,32\;sf\t%6,%3,%6\;a\t%4,%4,%4\;andc\t%6,%6,%5\;shufb\t%6,%6,%4,%2\;shlqbii\t%0,%6,4"
816 [(set (match_dup:DF 0)
817 (unsigned_float:DF (match_dup:SI 1)))]
820 rtx op1_v4si = gen_rtx_REG(V4SImode, REGNO(ops[1]));
821 rtx op0_ti = gen_rtx_REG (TImode, REGNO (ops[0]));
822 rtx op2_ti = gen_rtx_REG (TImode, REGNO (ops[2]));
823 rtx op6_ti = gen_rtx_REG (TImode, REGNO (ops[6]));
824 emit_insn (gen_clzv4si2 (ops[3],op1_v4si));
825 emit_move_insn (ops[6], spu_const (V4SImode, 1023+31));
826 emit_insn (gen_vashlv4si3 (ops[4],op1_v4si,ops[3]));
827 emit_insn (gen_ceq_v4si (ops[5],ops[3],spu_const (V4SImode, 32)));
828 emit_insn (gen_subv4si3 (ops[6],ops[6],ops[3]));
829 emit_insn (gen_addv4si3 (ops[4],ops[4],ops[4]));
830 emit_insn (gen_andc_v4si (ops[6],ops[6],ops[5]));
831 emit_insn (gen_shufb (ops[6],ops[6],ops[4],op2_ti));
832 emit_insn (gen_shlqbi_ti (op0_ti,op6_ti,GEN_INT(4)));
835 [(set_attr "length" "32")])
837 (define_expand "floatdidf2"
838 [(set (match_operand:DF 0 "register_operand" "")
839 (float:DF (match_operand:DI 1 "register_operand" "")))]
842 rtx c0 = gen_reg_rtx (DImode);
843 rtx r0 = gen_reg_rtx (DImode);
844 rtx r1 = gen_reg_rtx (DFmode);
845 rtx r2 = gen_reg_rtx (DImode);
846 rtx setneg = gen_reg_rtx (DImode);
847 rtx isneg = gen_reg_rtx (SImode);
848 rtx neg = gen_reg_rtx (DImode);
849 rtx mask = gen_reg_rtx (DImode);
851 emit_move_insn (c0, GEN_INT (0x8000000000000000ull));
853 emit_insn (gen_negdi2 (neg, operands[1]));
854 emit_insn (gen_cgt_di_m1 (isneg, operands[1]));
855 emit_insn (gen_extend_compare (mask, isneg));
856 emit_insn (gen_selb (r0, neg, operands[1], mask));
857 emit_insn (gen_andc_di (setneg, c0, mask));
859 emit_insn (gen_floatunsdidf2 (r1, r0));
861 emit_insn (gen_iordi3 (r2, gen_rtx_SUBREG (DImode, r1, 0), setneg));
862 emit_move_insn (operands[0], gen_rtx_SUBREG (DFmode, r2, 0));
866 (define_expand "floatunsdidf2"
867 [(set (match_operand:DF 0 "register_operand" "=r")
868 (unsigned_float:DF (match_operand:DI 1 "register_operand" "r")))]
872 rtx c0 = spu_const_from_ints (V16QImode, 0x02031011, 0x12138080,
873 0x06071415, 0x16178080);
874 rtx c1 = spu_const_from_ints (V4SImode, 1023+63, 1023+31, 0, 0);
875 rtx r0 = gen_reg_rtx (V16QImode);
876 rtx r1 = gen_reg_rtx (V4SImode);
882 emit_library_call_value (convert_optab_libfunc (ufloat_optab,
884 NULL_RTX, LCT_NORMAL, DFmode, 1, operands[1], DImode);
885 insns = get_insns ();
887 emit_libcall_block (insns, operands[0], value,
888 gen_rtx_UNSIGNED_FLOAT (DFmode, operands[1]));
892 emit_move_insn (r1, c1);
893 emit_move_insn (r0, c0);
894 emit_insn (gen_floatunsdidf2_internal (operands[0], operands[1], r0, r1));
899 (define_insn_and_split "floatunsdidf2_internal"
900 [(set (match_operand:DF 0 "register_operand" "=r")
901 (unsigned_float:DF (match_operand:DI 1 "register_operand" "r")))
902 (use (match_operand:V16QI 2 "register_operand" "r"))
903 (use (match_operand:V4SI 3 "register_operand" "r"))
904 (clobber (match_scratch:V4SI 4 "=&r"))
905 (clobber (match_scratch:V4SI 5 "=&r"))
906 (clobber (match_scratch:V4SI 6 "=&r"))]
908 "clz\t%4,%1\;shl\t%5,%1,%4\;ceqi\t%6,%4,32\;sf\t%4,%4,%3\;a\t%5,%5,%5\;andc\t%4,%4,%6\;shufb\t%4,%4,%5,%2\;shlqbii\t%4,%4,4\;shlqbyi\t%5,%4,8\;dfa\t%0,%4,%5"
910 [(set (match_operand:DF 0 "register_operand" "=r")
911 (unsigned_float:DF (match_operand:DI 1 "register_operand" "r")))]
914 rtx op1_v4si = gen_rtx_REG (V4SImode, REGNO(ops[1]));
915 rtx op2_ti = gen_rtx_REG (TImode, REGNO(ops[2]));
916 rtx op4_ti = gen_rtx_REG (TImode, REGNO(ops[4]));
917 rtx op5_ti = gen_rtx_REG (TImode, REGNO(ops[5]));
918 rtx op4_df = gen_rtx_REG (DFmode, REGNO(ops[4]));
919 rtx op5_df = gen_rtx_REG (DFmode, REGNO(ops[5]));
920 emit_insn (gen_clzv4si2 (ops[4],op1_v4si));
921 emit_insn (gen_vashlv4si3 (ops[5],op1_v4si,ops[4]));
922 emit_insn (gen_ceq_v4si (ops[6],ops[4],spu_const (V4SImode, 32)));
923 emit_insn (gen_subv4si3 (ops[4],ops[3],ops[4]));
924 emit_insn (gen_addv4si3 (ops[5],ops[5],ops[5]));
925 emit_insn (gen_andc_v4si (ops[4],ops[4],ops[6]));
926 emit_insn (gen_shufb (ops[4],ops[4],ops[5],op2_ti));
927 emit_insn (gen_shlqbi_ti (op4_ti,op4_ti,GEN_INT(4)));
928 emit_insn (gen_shlqby_ti (op5_ti,op4_ti,GEN_INT(8)));
929 emit_insn (gen_adddf3 (ops[0],op4_df,op5_df));
932 [(set_attr "length" "40")])
937 (define_expand "addv16qi3"
938 [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
939 (plus:V16QI (match_operand:V16QI 1 "spu_reg_operand" "r")
940 (match_operand:V16QI 2 "spu_reg_operand" "r")))]
943 rtx res_short = simplify_gen_subreg (V8HImode, operands[0], V16QImode, 0);
944 rtx lhs_short = simplify_gen_subreg (V8HImode, operands[1], V16QImode, 0);
945 rtx rhs_short = simplify_gen_subreg (V8HImode, operands[2], V16QImode, 0);
946 rtx rhs_and = gen_reg_rtx (V8HImode);
947 rtx hi_char = gen_reg_rtx (V8HImode);
948 rtx lo_char = gen_reg_rtx (V8HImode);
949 rtx mask = gen_reg_rtx (V8HImode);
951 emit_move_insn (mask, spu_const (V8HImode, 0x00ff));
952 emit_insn (gen_andv8hi3 (rhs_and, rhs_short, spu_const (V8HImode, 0xff00)));
953 emit_insn (gen_addv8hi3 (hi_char, lhs_short, rhs_and));
954 emit_insn (gen_addv8hi3 (lo_char, lhs_short, rhs_short));
955 emit_insn (gen_selb (res_short, hi_char, lo_char, mask));
959 (define_insn "add<mode>3"
960 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
961 (plus:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
962 (match_operand:VHSI 2 "spu_arith_operand" "r,B")))]
968 (define_expand "add<mode>3"
969 [(set (match_dup:VDI 3)
970 (unspec:VDI [(match_operand:VDI 1 "spu_reg_operand" "")
971 (match_operand:VDI 2 "spu_reg_operand" "")] UNSPEC_CG))
972 (set (match_dup:VDI 5)
973 (unspec:VDI [(match_dup 3)
975 (match_dup:TI 4)] UNSPEC_SHUFB))
976 (set (match_operand:VDI 0 "spu_reg_operand" "")
977 (unspec:VDI [(match_dup 1)
979 (match_dup 5)] UNSPEC_ADDX))]
982 unsigned char pat[16] = {
983 0x04, 0x05, 0x06, 0x07,
984 0x80, 0x80, 0x80, 0x80,
985 0x0c, 0x0d, 0x0e, 0x0f,
986 0x80, 0x80, 0x80, 0x80
988 operands[3] = gen_reg_rtx (<MODE>mode);
989 operands[4] = gen_reg_rtx (TImode);
990 operands[5] = gen_reg_rtx (<MODE>mode);
991 emit_move_insn (operands[4], array_to_constant (TImode, pat));
994 (define_insn "cg_<mode>"
995 [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
996 (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
997 (match_operand 2 "spu_reg_operand" "r")] UNSPEC_CG))]
1001 (define_insn "cgx_<mode>"
1002 [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
1003 (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
1004 (match_operand 2 "spu_reg_operand" "r")
1005 (match_operand 3 "spu_reg_operand" "0")] UNSPEC_CGX))]
1009 (define_insn "addx_<mode>"
1010 [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
1011 (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
1012 (match_operand 2 "spu_reg_operand" "r")
1013 (match_operand 3 "spu_reg_operand" "0")] UNSPEC_ADDX))]
1018 ;; This is not the most efficient implementation of addti3.
1019 ;; We include this here because 1) the compiler needs it to be
1020 ;; defined as the word size is 128-bit and 2) sometimes gcc
1021 ;; substitutes an add for a constant left-shift. 2) is unlikely
1022 ;; because we also give addti3 a high cost. In case gcc does
1023 ;; generate TImode add, here is the code to do it.
1024 ;; operand 2 is a nonmemory because the compiler requires it.
1025 (define_insn "addti3"
1026 [(set (match_operand:TI 0 "spu_reg_operand" "=&r")
1027 (plus:TI (match_operand:TI 1 "spu_reg_operand" "r")
1028 (match_operand:TI 2 "spu_nonmem_operand" "r")))
1029 (clobber (match_scratch:TI 3 "=&r"))]
1032 shlqbyi\t%3,%3,4\n\\
1034 shlqbyi\t%3,%3,4\n\\
1036 shlqbyi\t%0,%3,4\n\\
1038 [(set_attr "type" "multi0")
1039 (set_attr "length" "28")])
1041 (define_insn "add<mode>3"
1042 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1043 (plus:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
1044 (match_operand:VSF 2 "spu_reg_operand" "r")))]
1047 [(set_attr "type" "fp6")])
1049 (define_insn "add<mode>3"
1050 [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
1051 (plus:VDF (match_operand:VDF 1 "spu_reg_operand" "r")
1052 (match_operand:VDF 2 "spu_reg_operand" "r")))]
1055 [(set_attr "type" "fpd")])
1060 (define_expand "subv16qi3"
1061 [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
1062 (minus:V16QI (match_operand:V16QI 1 "spu_reg_operand" "r")
1063 (match_operand:V16QI 2 "spu_reg_operand" "r")))]
1066 rtx res_short = simplify_gen_subreg (V8HImode, operands[0], V16QImode, 0);
1067 rtx lhs_short = simplify_gen_subreg (V8HImode, operands[1], V16QImode, 0);
1068 rtx rhs_short = simplify_gen_subreg (V8HImode, operands[2], V16QImode, 0);
1069 rtx rhs_and = gen_reg_rtx (V8HImode);
1070 rtx hi_char = gen_reg_rtx (V8HImode);
1071 rtx lo_char = gen_reg_rtx (V8HImode);
1072 rtx mask = gen_reg_rtx (V8HImode);
1074 emit_move_insn (mask, spu_const (V8HImode, 0x00ff));
1075 emit_insn (gen_andv8hi3 (rhs_and, rhs_short, spu_const (V8HImode, 0xff00)));
1076 emit_insn (gen_subv8hi3 (hi_char, lhs_short, rhs_and));
1077 emit_insn (gen_subv8hi3 (lo_char, lhs_short, rhs_short));
1078 emit_insn (gen_selb (res_short, hi_char, lo_char, mask));
1082 (define_insn "sub<mode>3"
1083 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
1084 (minus:VHSI (match_operand:VHSI 1 "spu_arith_operand" "r,B")
1085 (match_operand:VHSI 2 "spu_reg_operand" "r,r")))]
1091 (define_expand "sub<mode>3"
1092 [(set (match_dup:VDI 3)
1093 (unspec:VDI [(match_operand:VDI 1 "spu_reg_operand" "")
1094 (match_operand:VDI 2 "spu_reg_operand" "")] UNSPEC_BG))
1095 (set (match_dup:VDI 5)
1096 (unspec:VDI [(match_dup 3)
1098 (match_dup:TI 4)] UNSPEC_SHUFB))
1099 (set (match_operand:VDI 0 "spu_reg_operand" "")
1100 (unspec:VDI [(match_dup 1)
1102 (match_dup 5)] UNSPEC_SFX))]
1105 unsigned char pat[16] = {
1106 0x04, 0x05, 0x06, 0x07,
1107 0xc0, 0xc0, 0xc0, 0xc0,
1108 0x0c, 0x0d, 0x0e, 0x0f,
1109 0xc0, 0xc0, 0xc0, 0xc0
1111 operands[3] = gen_reg_rtx (<MODE>mode);
1112 operands[4] = gen_reg_rtx (TImode);
1113 operands[5] = gen_reg_rtx (<MODE>mode);
1114 emit_move_insn (operands[4], array_to_constant (TImode, pat));
1117 (define_insn "bg_<mode>"
1118 [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
1119 (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
1120 (match_operand 2 "spu_reg_operand" "r")] UNSPEC_BG))]
1124 (define_insn "bgx_<mode>"
1125 [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
1126 (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
1127 (match_operand 2 "spu_reg_operand" "r")
1128 (match_operand 3 "spu_reg_operand" "0")] UNSPEC_BGX))]
1132 (define_insn "sfx_<mode>"
1133 [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
1134 (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
1135 (match_operand 2 "spu_reg_operand" "r")
1136 (match_operand 3 "spu_reg_operand" "0")] UNSPEC_SFX))]
1140 (define_insn "subti3"
1141 [(set (match_operand:TI 0 "spu_reg_operand" "=r")
1142 (minus:TI (match_operand:TI 1 "spu_reg_operand" "r")
1143 (match_operand:TI 2 "spu_reg_operand" "r")))
1144 (clobber (match_scratch:TI 3 "=&r"))
1145 (clobber (match_scratch:TI 4 "=&r"))
1146 (clobber (match_scratch:TI 5 "=&r"))
1147 (clobber (match_scratch:TI 6 "=&r"))]
1153 shlqbyi\t%5,%3,4\n\\
1157 shlqbyi\t%5,%3,4\n\\
1161 shlqbyi\t%5,%3,4\n\\
1163 [(set_attr "type" "multi0")
1164 (set_attr "length" "56")])
1166 (define_insn "sub<mode>3"
1167 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1168 (minus:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
1169 (match_operand:VSF 2 "spu_reg_operand" "r")))]
1172 [(set_attr "type" "fp6")])
1174 (define_insn "sub<mode>3"
1175 [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
1176 (minus:VDF (match_operand:VDF 1 "spu_reg_operand" "r")
1177 (match_operand:VDF 2 "spu_reg_operand" "r")))]
1180 [(set_attr "type" "fpd")])
1185 (define_expand "negv16qi2"
1186 [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
1187 (neg:V16QI (match_operand:V16QI 1 "spu_reg_operand" "r")))]
1190 rtx zero = gen_reg_rtx (V16QImode);
1191 emit_move_insn (zero, CONST0_RTX (V16QImode));
1192 emit_insn (gen_subv16qi3 (operands[0], zero, operands[1]));
1196 (define_insn "neg<mode>2"
1197 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r")
1198 (neg:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r")))]
1202 (define_expand "negdi2"
1203 [(set (match_operand:DI 0 "spu_reg_operand" "")
1204 (neg:DI (match_operand:DI 1 "spu_reg_operand" "")))]
1207 rtx zero = gen_reg_rtx(DImode);
1208 emit_move_insn(zero, GEN_INT(0));
1209 emit_insn (gen_subdi3(operands[0], zero, operands[1]));
1213 (define_expand "negti2"
1214 [(set (match_operand:TI 0 "spu_reg_operand" "")
1215 (neg:TI (match_operand:TI 1 "spu_reg_operand" "")))]
1218 rtx zero = gen_reg_rtx(TImode);
1219 emit_move_insn(zero, GEN_INT(0));
1220 emit_insn (gen_subti3(operands[0], zero, operands[1]));
1224 (define_expand "neg<mode>2"
1226 [(set (match_operand:VSF 0 "spu_reg_operand" "")
1227 (neg:VSF (match_operand:VSF 1 "spu_reg_operand" "")))
1228 (use (match_dup 2))])]
1230 "operands[2] = gen_reg_rtx (<F2I>mode);
1231 emit_move_insn (operands[2], spu_const (<F2I>mode, -0x80000000ull));")
1233 (define_expand "neg<mode>2"
1235 [(set (match_operand:VDF 0 "spu_reg_operand" "")
1236 (neg:VDF (match_operand:VDF 1 "spu_reg_operand" "")))
1237 (use (match_dup 2))])]
1239 "operands[2] = gen_reg_rtx (<F2I>mode);
1240 emit_move_insn (operands[2], spu_const (<F2I>mode, -0x8000000000000000ull));")
1242 (define_insn_and_split "_neg<mode>2"
1243 [(set (match_operand:VSDF 0 "spu_reg_operand" "=r")
1244 (neg:VSDF (match_operand:VSDF 1 "spu_reg_operand" "r")))
1245 (use (match_operand:<F2I> 2 "spu_reg_operand" "r"))]
1249 [(set (match_dup:<F2I> 3)
1250 (xor:<F2I> (match_dup:<F2I> 4)
1251 (match_dup:<F2I> 2)))]
1253 operands[3] = spu_gen_subreg (<F2I>mode, operands[0]);
1254 operands[4] = spu_gen_subreg (<F2I>mode, operands[1]);
1260 (define_expand "abs<mode>2"
1262 [(set (match_operand:VSF 0 "spu_reg_operand" "")
1263 (abs:VSF (match_operand:VSF 1 "spu_reg_operand" "")))
1264 (use (match_dup 2))])]
1266 "operands[2] = gen_reg_rtx (<F2I>mode);
1267 emit_move_insn (operands[2], spu_const (<F2I>mode, 0x7fffffffull));")
1269 (define_expand "abs<mode>2"
1271 [(set (match_operand:VDF 0 "spu_reg_operand" "")
1272 (abs:VDF (match_operand:VDF 1 "spu_reg_operand" "")))
1273 (use (match_dup 2))])]
1275 "operands[2] = gen_reg_rtx (<F2I>mode);
1276 emit_move_insn (operands[2], spu_const (<F2I>mode, 0x7fffffffffffffffull));")
1278 (define_insn_and_split "_abs<mode>2"
1279 [(set (match_operand:VSDF 0 "spu_reg_operand" "=r")
1280 (abs:VSDF (match_operand:VSDF 1 "spu_reg_operand" "r")))
1281 (use (match_operand:<F2I> 2 "spu_reg_operand" "r"))]
1285 [(set (match_dup:<F2I> 3)
1286 (and:<F2I> (match_dup:<F2I> 4)
1287 (match_dup:<F2I> 2)))]
1289 operands[3] = spu_gen_subreg (<F2I>mode, operands[0]);
1290 operands[4] = spu_gen_subreg (<F2I>mode, operands[1]);
1296 (define_insn "mulhi3"
1297 [(set (match_operand:HI 0 "spu_reg_operand" "=r,r")
1298 (mult:HI (match_operand:HI 1 "spu_reg_operand" "r,r")
1299 (match_operand:HI 2 "spu_arith_operand" "r,B")))]
1304 [(set_attr "type" "fp7")])
1306 (define_expand "mulv8hi3"
1307 [(set (match_operand:V8HI 0 "spu_reg_operand" "")
1308 (mult:V8HI (match_operand:V8HI 1 "spu_reg_operand" "")
1309 (match_operand:V8HI 2 "spu_reg_operand" "")))]
1312 rtx result = simplify_gen_subreg (V4SImode, operands[0], V8HImode, 0);
1313 rtx low = gen_reg_rtx (V4SImode);
1314 rtx high = gen_reg_rtx (V4SImode);
1315 rtx shift = gen_reg_rtx (V4SImode);
1316 rtx mask = gen_reg_rtx (V4SImode);
1318 emit_move_insn (mask, spu_const (V4SImode, 0x0000ffff));
1319 emit_insn (gen_spu_mpyhh (high, operands[1], operands[2]));
1320 emit_insn (gen_spu_mpy (low, operands[1], operands[2]));
1321 emit_insn (gen_vashlv4si3 (shift, high, spu_const(V4SImode, 16)));
1322 emit_insn (gen_selb (result, shift, low, mask));
1326 (define_expand "mul<mode>3"
1328 [(set (match_operand:VSI 0 "spu_reg_operand" "")
1329 (mult:VSI (match_operand:VSI 1 "spu_reg_operand" "")
1330 (match_operand:VSI 2 "spu_reg_operand" "")))
1331 (clobber (match_dup:VSI 3))
1332 (clobber (match_dup:VSI 4))
1333 (clobber (match_dup:VSI 5))
1334 (clobber (match_dup:VSI 6))])]
1337 operands[3] = gen_reg_rtx(<MODE>mode);
1338 operands[4] = gen_reg_rtx(<MODE>mode);
1339 operands[5] = gen_reg_rtx(<MODE>mode);
1340 operands[6] = gen_reg_rtx(<MODE>mode);
1343 (define_insn_and_split "_mulsi3"
1344 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1345 (mult:SI (match_operand:SI 1 "spu_reg_operand" "r")
1346 (match_operand:SI 2 "spu_arith_operand" "rK")))
1347 (clobber (match_operand:SI 3 "spu_reg_operand" "=&r"))
1348 (clobber (match_operand:SI 4 "spu_reg_operand" "=&r"))
1349 (clobber (match_operand:SI 5 "spu_reg_operand" "=&r"))
1350 (clobber (match_operand:SI 6 "spu_reg_operand" "=&r"))]
1354 [(set (match_dup:SI 0)
1355 (mult:SI (match_dup:SI 1)
1358 HOST_WIDE_INT val = 0;
1359 rtx a = operands[3];
1360 rtx b = operands[4];
1361 rtx c = operands[5];
1362 rtx d = operands[6];
1363 if (GET_CODE(operands[2]) == CONST_INT)
1365 val = INTVAL(operands[2]);
1366 emit_move_insn(d, operands[2]);
1369 if (val && (val & 0xffff) == 0)
1371 emit_insn (gen_mpyh_si(operands[0], operands[2], operands[1]));
1373 else if (val > 0 && val < 0x10000)
1375 rtx cst = satisfies_constraint_K (GEN_INT (val)) ? GEN_INT(val) : d;
1376 emit_insn (gen_mpyh_si(a, operands[1], operands[2]));
1377 emit_insn (gen_mpyu_si(c, operands[1], cst));
1378 emit_insn (gen_addsi3(operands[0], a, c));
1382 emit_insn (gen_mpyh_si(a, operands[1], operands[2]));
1383 emit_insn (gen_mpyh_si(b, operands[2], operands[1]));
1384 emit_insn (gen_mpyu_si(c, operands[1], operands[2]));
1385 emit_insn (gen_addsi3(d, a, b));
1386 emit_insn (gen_addsi3(operands[0], d, c));
1391 (define_insn_and_split "_mulv4si3"
1392 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
1393 (mult:V4SI (match_operand:V4SI 1 "spu_reg_operand" "r")
1394 (match_operand:V4SI 2 "spu_reg_operand" "r")))
1395 (clobber (match_operand:V4SI 3 "spu_reg_operand" "=&r"))
1396 (clobber (match_operand:V4SI 4 "spu_reg_operand" "=&r"))
1397 (clobber (match_operand:V4SI 5 "spu_reg_operand" "=&r"))
1398 (clobber (match_operand:V4SI 6 "spu_reg_operand" "=&r"))]
1402 [(set (match_dup:V4SI 0)
1403 (mult:V4SI (match_dup:V4SI 1)
1404 (match_dup:V4SI 2)))]
1406 rtx a = operands[3];
1407 rtx b = operands[4];
1408 rtx c = operands[5];
1409 rtx d = operands[6];
1410 rtx op1 = simplify_gen_subreg (V8HImode, operands[1], V4SImode, 0);
1411 rtx op2 = simplify_gen_subreg (V8HImode, operands[2], V4SImode, 0);
1412 emit_insn (gen_spu_mpyh(a, op1, op2));
1413 emit_insn (gen_spu_mpyh(b, op2, op1));
1414 emit_insn (gen_spu_mpyu(c, op1, op2));
1415 emit_insn (gen_addv4si3(d, a, b));
1416 emit_insn (gen_addv4si3(operands[0], d, c));
1420 (define_insn "mulhisi3"
1421 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1422 (mult:SI (sign_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
1423 (sign_extend:SI (match_operand:HI 2 "spu_reg_operand" "r"))))]
1426 [(set_attr "type" "fp7")])
1428 (define_insn "mulhisi3_imm"
1429 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1430 (mult:SI (sign_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
1431 (match_operand:SI 2 "imm_K_operand" "K")))]
1434 [(set_attr "type" "fp7")])
1436 (define_insn "umulhisi3"
1437 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1438 (mult:SI (zero_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
1439 (zero_extend:SI (match_operand:HI 2 "spu_reg_operand" "r"))))]
1442 [(set_attr "type" "fp7")])
1444 (define_insn "umulhisi3_imm"
1445 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1446 (mult:SI (zero_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
1447 (and:SI (match_operand:SI 2 "imm_K_operand" "K") (const_int 65535))))]
1450 [(set_attr "type" "fp7")])
1452 (define_insn "mpyu_si"
1453 [(set (match_operand:SI 0 "spu_reg_operand" "=r,r")
1454 (mult:SI (and:SI (match_operand:SI 1 "spu_reg_operand" "r,r")
1456 (and:SI (match_operand:SI 2 "spu_arith_operand" "r,K")
1457 (const_int 65535))))]
1462 [(set_attr "type" "fp7")])
1464 ;; This isn't always profitable to use. Consider r = a * b + c * d.
1465 ;; It's faster to do the multiplies in parallel then add them. If we
1466 ;; merge a multiply and add it prevents the multiplies from happening in
1468 (define_insn "mpya_si"
1469 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1470 (plus:SI (mult:SI (sign_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
1471 (sign_extend:SI (match_operand:HI 2 "spu_reg_operand" "r")))
1472 (match_operand:SI 3 "spu_reg_operand" "r")))]
1475 [(set_attr "type" "fp7")])
1477 (define_insn "mpyh_si"
1478 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1479 (mult:SI (and:SI (match_operand:SI 1 "spu_reg_operand" "r")
1481 (and:SI (match_operand:SI 2 "spu_reg_operand" "r")
1482 (const_int 65535))))]
1485 [(set_attr "type" "fp7")])
1487 (define_insn "mpys_si"
1488 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1490 (mult:SI (sign_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
1491 (sign_extend:SI (match_operand:HI 2 "spu_reg_operand" "r")))
1495 [(set_attr "type" "fp7")])
1497 (define_insn "mpyhh_si"
1498 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1499 (mult:SI (ashiftrt:SI (match_operand:SI 1 "spu_reg_operand" "r")
1501 (ashiftrt:SI (match_operand:SI 2 "spu_reg_operand" "r")
1505 [(set_attr "type" "fp7")])
1507 (define_insn "mpyhhu_si"
1508 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1509 (mult:SI (lshiftrt:SI (match_operand:SI 1 "spu_reg_operand" "r")
1511 (lshiftrt:SI (match_operand:SI 2 "spu_reg_operand" "r")
1515 [(set_attr "type" "fp7")])
1517 (define_insn "mpyhha_si"
1518 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1519 (plus:SI (mult:SI (ashiftrt:SI (match_operand:SI 1 "spu_reg_operand" "r")
1521 (ashiftrt:SI (match_operand:SI 2 "spu_reg_operand" "r")
1523 (match_operand:SI 3 "spu_reg_operand" "0")))]
1526 [(set_attr "type" "fp7")])
1528 (define_insn "mul<mode>3"
1529 [(set (match_operand:VSDF 0 "spu_reg_operand" "=r")
1530 (mult:VSDF (match_operand:VSDF 1 "spu_reg_operand" "r")
1531 (match_operand:VSDF 2 "spu_reg_operand" "r")))]
1534 [(set_attr "type" "fp<d6>")])
1536 (define_insn "fma_<mode>"
1537 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1538 (plus:VSF (mult:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
1539 (match_operand:VSF 2 "spu_reg_operand" "r"))
1540 (match_operand:VSF 3 "spu_reg_operand" "r")))]
1543 [(set_attr "type" "fp6")])
1545 (define_insn "fnms_<mode>"
1546 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1547 (minus:VSF (match_operand:VSF 3 "spu_reg_operand" "r")
1548 (mult:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
1549 (match_operand:VSF 2 "spu_reg_operand" "r"))))]
1552 [(set_attr "type" "fp6")])
1554 (define_insn "fms_<mode>"
1555 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1556 (minus:VSF (mult:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
1557 (match_operand:VSF 2 "spu_reg_operand" "r"))
1558 (match_operand:VSF 3 "spu_reg_operand" "r")))]
1561 [(set_attr "type" "fp6")])
1563 (define_insn "fma_<mode>"
1564 [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
1565 (plus:VDF (mult:VDF (match_operand:VDF 1 "spu_reg_operand" "r")
1566 (match_operand:VDF 2 "spu_reg_operand" "r"))
1567 (match_operand:VDF 3 "spu_reg_operand" "0")))]
1570 [(set_attr "type" "fpd")])
1572 (define_insn "fnma_<mode>"
1573 [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
1574 (neg:VDF (plus:VDF (mult:VDF (match_operand:VDF 1 "spu_reg_operand" "r")
1575 (match_operand:VDF 2 "spu_reg_operand" "r"))
1576 (match_operand:VDF 3 "spu_reg_operand" "0"))))]
1579 [(set_attr "type" "fpd")])
1581 (define_insn "fnms_<mode>"
1582 [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
1583 (minus:VDF (match_operand:VDF 3 "spu_reg_operand" "0")
1584 (mult:VDF (match_operand:VDF 1 "spu_reg_operand" "r")
1585 (match_operand:VDF 2 "spu_reg_operand" "r"))))]
1588 [(set_attr "type" "fpd")])
1590 (define_insn "fms_<mode>"
1591 [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
1592 (minus:VDF (mult:VDF (match_operand:VDF 1 "spu_reg_operand" "r")
1593 (match_operand:VDF 2 "spu_reg_operand" "r"))
1594 (match_operand:VDF 3 "spu_reg_operand" "0")))]
1597 [(set_attr "type" "fpd")])
1600 ;; mul highpart, used for divide by constant optimizations.
1602 (define_expand "smulsi3_highpart"
1603 [(set (match_operand:SI 0 "register_operand" "")
1606 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
1607 (sign_extend:DI (match_operand:SI 2 "register_operand" "")))
1611 rtx t0 = gen_reg_rtx (SImode);
1612 rtx t1 = gen_reg_rtx (SImode);
1613 rtx t2 = gen_reg_rtx (SImode);
1614 rtx t3 = gen_reg_rtx (SImode);
1615 rtx t4 = gen_reg_rtx (SImode);
1616 rtx t5 = gen_reg_rtx (SImode);
1617 rtx t6 = gen_reg_rtx (SImode);
1618 rtx t7 = gen_reg_rtx (SImode);
1619 rtx t8 = gen_reg_rtx (SImode);
1620 rtx t9 = gen_reg_rtx (SImode);
1621 rtx t11 = gen_reg_rtx (SImode);
1622 rtx t12 = gen_reg_rtx (SImode);
1623 rtx t14 = gen_reg_rtx (SImode);
1624 rtx t15 = gen_reg_rtx (HImode);
1625 rtx t16 = gen_reg_rtx (HImode);
1626 rtx t17 = gen_reg_rtx (HImode);
1627 rtx t18 = gen_reg_rtx (HImode);
1628 rtx t19 = gen_reg_rtx (SImode);
1629 rtx t20 = gen_reg_rtx (SImode);
1630 rtx t21 = gen_reg_rtx (SImode);
1631 rtx op1_hi = gen_rtx_SUBREG (HImode, operands[1], 2);
1632 rtx op2_hi = gen_rtx_SUBREG (HImode, operands[2], 2);
1633 rtx t0_hi = gen_rtx_SUBREG (HImode, t0, 2);
1634 rtx t1_hi = gen_rtx_SUBREG (HImode, t1, 2);
1636 rtx insn = emit_insn (gen_lshrsi3 (t0, operands[1], GEN_INT (16)));
1637 emit_insn (gen_lshrsi3 (t1, operands[2], GEN_INT (16)));
1638 emit_insn (gen_umulhisi3 (t2, op1_hi, op2_hi));
1639 emit_insn (gen_mpyh_si (t3, operands[1], operands[2]));
1640 emit_insn (gen_mpyh_si (t4, operands[2], operands[1]));
1641 emit_insn (gen_mpyhh_si (t5, operands[1], operands[2]));
1642 emit_insn (gen_mpys_si (t6, t0_hi, op2_hi));
1643 emit_insn (gen_mpys_si (t7, t1_hi, op1_hi));
1645 /* Gen carry bits (in t9 and t11). */
1646 emit_insn (gen_addsi3 (t8, t2, t3));
1647 emit_insn (gen_cg_si (t9, t2, t3));
1648 emit_insn (gen_cg_si (t11, t8, t4));
1650 /* Gen high 32 bits in operand[0]. Correct for mpys. */
1651 emit_insn (gen_addx_si (t12, t5, t6, t9));
1652 emit_insn (gen_addx_si (t14, t12, t7, t11));
1654 /* mpys treats both operands as signed when we really want it to treat
1655 the first operand as signed and the second operand as unsigned.
1656 The code below corrects for that difference. */
1657 emit_insn (gen_cgt_hi (t15, op1_hi, GEN_INT (-1)));
1658 emit_insn (gen_cgt_hi (t16, op2_hi, GEN_INT (-1)));
1659 emit_insn (gen_andc_hi (t17, t1_hi, t15));
1660 emit_insn (gen_andc_hi (t18, t0_hi, t16));
1661 emit_insn (gen_extendhisi2 (t19, t17));
1662 emit_insn (gen_extendhisi2 (t20, t18));
1663 emit_insn (gen_addsi3 (t21, t19, t20));
1664 emit_insn (gen_addsi3 (operands[0], t14, t21));
1665 unshare_all_rtl_in_chain (insn);
1669 (define_expand "umulsi3_highpart"
1670 [(set (match_operand:SI 0 "register_operand" "")
1673 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
1674 (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1679 rtx t0 = gen_reg_rtx (SImode);
1680 rtx t1 = gen_reg_rtx (SImode);
1681 rtx t2 = gen_reg_rtx (SImode);
1682 rtx t3 = gen_reg_rtx (SImode);
1683 rtx t4 = gen_reg_rtx (SImode);
1684 rtx t5 = gen_reg_rtx (SImode);
1685 rtx t6 = gen_reg_rtx (SImode);
1686 rtx t7 = gen_reg_rtx (SImode);
1687 rtx t8 = gen_reg_rtx (SImode);
1688 rtx t9 = gen_reg_rtx (SImode);
1689 rtx t10 = gen_reg_rtx (SImode);
1690 rtx t12 = gen_reg_rtx (SImode);
1691 rtx t13 = gen_reg_rtx (SImode);
1692 rtx t14 = gen_reg_rtx (SImode);
1693 rtx op1_hi = gen_rtx_SUBREG (HImode, operands[1], 2);
1694 rtx op2_hi = gen_rtx_SUBREG (HImode, operands[2], 2);
1695 rtx t0_hi = gen_rtx_SUBREG (HImode, t0, 2);
1697 rtx insn = emit_insn (gen_rotlsi3 (t0, operands[2], GEN_INT (16)));
1698 emit_insn (gen_umulhisi3 (t1, op1_hi, op2_hi));
1699 emit_insn (gen_umulhisi3 (t2, op1_hi, t0_hi));
1700 emit_insn (gen_mpyhhu_si (t3, operands[1], t0));
1701 emit_insn (gen_mpyhhu_si (t4, operands[1], operands[2]));
1702 emit_insn (gen_ashlsi3 (t5, t2, GEN_INT (16)));
1703 emit_insn (gen_ashlsi3 (t6, t3, GEN_INT (16)));
1704 emit_insn (gen_lshrsi3 (t7, t2, GEN_INT (16)));
1705 emit_insn (gen_lshrsi3 (t8, t3, GEN_INT (16)));
1707 /* Gen carry bits (in t10 and t12). */
1708 emit_insn (gen_addsi3 (t9, t1, t5));
1709 emit_insn (gen_cg_si (t10, t1, t5));
1710 emit_insn (gen_cg_si (t12, t9, t6));
1712 /* Gen high 32 bits in operand[0]. */
1713 emit_insn (gen_addx_si (t13, t4, t7, t10));
1714 emit_insn (gen_addx_si (t14, t13, t8, t12));
1715 emit_insn (gen_movsi (operands[0], t14));
1716 unshare_all_rtl_in_chain (insn);
1723 ;; Not necessarily the best implementation of divide but faster then
1724 ;; the default that gcc provides because this is inlined and it uses
1726 (define_insn "divmodsi4"
1727 [(set (match_operand:SI 0 "spu_reg_operand" "=&r")
1728 (div:SI (match_operand:SI 1 "spu_reg_operand" "r")
1729 (match_operand:SI 2 "spu_reg_operand" "r")))
1730 (set (match_operand:SI 3 "spu_reg_operand" "=&r")
1731 (mod:SI (match_dup 1)
1733 (clobber (match_scratch:SI 4 "=&r"))
1734 (clobber (match_scratch:SI 5 "=&r"))
1735 (clobber (match_scratch:SI 6 "=&r"))
1736 (clobber (match_scratch:SI 7 "=&r"))
1737 (clobber (match_scratch:SI 8 "=&r"))
1738 (clobber (match_scratch:SI 9 "=&r"))
1739 (clobber (match_scratch:SI 10 "=&r"))
1740 (clobber (match_scratch:SI 11 "=&r"))
1741 (clobber (match_scratch:SI 12 "=&r"))
1742 (clobber (reg:SI 130))]
1750 selb %8,%8,%1,%10\\n\\
1751 selb %9,%9,%2,%11\\n\\
1757 shlqbyi %3,%8,0\\n\\
1758 xor %11,%10,%11\\n\\
1762 1: or %12,%0,%5\\n\\
1763 rotqmbii %5,%5,-1\\n\\
1767 rotqmbii %4,%4,-1\\n\\
1768 selb %0,%12,%0,%6\\n\\
1770 selb %3,%7,%3,%6\\n\\
1774 selb %3,%8,%3,%10\\n\\
1776 [(set_attr "type" "multi0")
1777 (set_attr "length" "128")])
1779 (define_insn "udivmodsi4"
1780 [(set (match_operand:SI 0 "spu_reg_operand" "=&r")
1781 (udiv:SI (match_operand:SI 1 "spu_reg_operand" "r")
1782 (match_operand:SI 2 "spu_reg_operand" "r")))
1783 (set (match_operand:SI 3 "spu_reg_operand" "=&r")
1784 (umod:SI (match_dup 1)
1786 (clobber (match_scratch:SI 4 "=&r"))
1787 (clobber (match_scratch:SI 5 "=&r"))
1788 (clobber (match_scratch:SI 6 "=&r"))
1789 (clobber (match_scratch:SI 7 "=&r"))
1790 (clobber (match_scratch:SI 8 "=&r"))
1791 (clobber (reg:SI 130))]
1804 rotqmbii %5,%5,-1\\n\\
1808 rotqmbii %4,%4,-1\\n\\
1809 selb %0,%8,%0,%6\\n\\
1811 selb %3,%7,%3,%6\\n\\
1814 [(set_attr "type" "multi0")
1815 (set_attr "length" "80")])
1817 (define_expand "div<mode>3"
1819 [(set (match_operand:VSF 0 "spu_reg_operand" "")
1820 (div:VSF (match_operand:VSF 1 "spu_reg_operand" "")
1821 (match_operand:VSF 2 "spu_reg_operand" "")))
1822 (clobber (match_scratch:VSF 3 ""))
1823 (clobber (match_scratch:VSF 4 ""))
1824 (clobber (match_scratch:VSF 5 ""))])]
1828 (define_insn_and_split "*div<mode>3_fast"
1829 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1830 (div:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
1831 (match_operand:VSF 2 "spu_reg_operand" "r")))
1832 (clobber (match_scratch:VSF 3 "=&r"))
1833 (clobber (match_scratch:VSF 4 "=&r"))
1834 (clobber (scratch:VSF))]
1835 "flag_unsafe_math_optimizations"
1838 [(set (match_dup:VSF 0)
1839 (div:VSF (match_dup:VSF 1)
1841 (clobber (match_dup:VSF 3))
1842 (clobber (match_dup:VSF 4))
1843 (clobber (scratch:VSF))]
1845 emit_insn (gen_frest_<mode>(operands[3], operands[2]));
1846 emit_insn (gen_fi_<mode>(operands[3], operands[2], operands[3]));
1847 emit_insn (gen_mul<mode>3(operands[4], operands[1], operands[3]));
1848 emit_insn (gen_fnms_<mode>(operands[0], operands[4], operands[2], operands[1]));
1849 emit_insn (gen_fma_<mode>(operands[0], operands[0], operands[3], operands[4]));
1853 (define_insn_and_split "*div<mode>3_adjusted"
1854 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1855 (div:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
1856 (match_operand:VSF 2 "spu_reg_operand" "r")))
1857 (clobber (match_scratch:VSF 3 "=&r"))
1858 (clobber (match_scratch:VSF 4 "=&r"))
1859 (clobber (match_scratch:VSF 5 "=&r"))]
1860 "!flag_unsafe_math_optimizations"
1863 [(set (match_dup:VSF 0)
1864 (div:VSF (match_dup:VSF 1)
1866 (clobber (match_dup:VSF 3))
1867 (clobber (match_dup:VSF 4))
1868 (clobber (match_dup:VSF 5))]
1870 emit_insn (gen_frest_<mode> (operands[3], operands[2]));
1871 emit_insn (gen_fi_<mode> (operands[3], operands[2], operands[3]));
1872 emit_insn (gen_mul<mode>3 (operands[4], operands[1], operands[3]));
1873 emit_insn (gen_fnms_<mode> (operands[5], operands[4], operands[2], operands[1]));
1874 emit_insn (gen_fma_<mode> (operands[3], operands[5], operands[3], operands[4]));
1876 /* Due to truncation error, the quotient result may be low by 1 ulp.
1877 Conditionally add one if the estimate is too small in magnitude. */
1879 emit_move_insn (gen_lowpart (<F2I>mode, operands[4]),
1880 spu_const (<F2I>mode, 0x80000000ULL));
1881 emit_move_insn (gen_lowpart (<F2I>mode, operands[5]),
1882 spu_const (<F2I>mode, 0x3f800000ULL));
1883 emit_insn (gen_selb (operands[5], operands[5], operands[1], operands[4]));
1885 emit_insn (gen_add<f2i>3 (gen_lowpart (<F2I>mode, operands[4]),
1886 gen_lowpart (<F2I>mode, operands[3]),
1887 spu_const (<F2I>mode, 1)));
1888 emit_insn (gen_fnms_<mode> (operands[0], operands[2], operands[4], operands[1]));
1889 emit_insn (gen_mul<mode>3 (operands[0], operands[0], operands[5]));
1890 emit_insn (gen_cgt_<f2i> (gen_lowpart (<F2I>mode, operands[0]),
1891 gen_lowpart (<F2I>mode, operands[0]),
1892 spu_const (<F2I>mode, -1)));
1893 emit_insn (gen_selb (operands[0], operands[3], operands[4], operands[0]));
1900 (define_insn_and_split "sqrtsf2"
1901 [(set (match_operand:SF 0 "spu_reg_operand" "=r")
1902 (sqrt:SF (match_operand:SF 1 "spu_reg_operand" "r")))
1903 (clobber (match_scratch:SF 2 "=&r"))
1904 (clobber (match_scratch:SF 3 "=&r"))
1905 (clobber (match_scratch:SF 4 "=&r"))
1906 (clobber (match_scratch:SF 5 "=&r"))]
1910 [(set (match_dup:SF 0)
1911 (sqrt:SF (match_dup:SF 1)))
1912 (clobber (match_dup:SF 2))
1913 (clobber (match_dup:SF 3))
1914 (clobber (match_dup:SF 4))
1915 (clobber (match_dup:SF 5))]
1917 emit_move_insn (operands[3],spu_float_const(\"0.5\",SFmode));
1918 emit_move_insn (operands[4],spu_float_const(\"1.00000011920928955078125\",SFmode));
1919 emit_insn (gen_frsqest_sf(operands[2],operands[1]));
1920 emit_insn (gen_fi_sf(operands[2],operands[1],operands[2]));
1921 emit_insn (gen_mulsf3(operands[5],operands[2],operands[1]));
1922 emit_insn (gen_mulsf3(operands[3],operands[5],operands[3]));
1923 emit_insn (gen_fnms_sf(operands[4],operands[2],operands[5],operands[4]));
1924 emit_insn (gen_fma_sf(operands[0],operands[4],operands[3],operands[5]));
1928 (define_insn "frest_<mode>"
1929 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1930 (unspec:VSF [(match_operand:VSF 1 "spu_reg_operand" "r")] UNSPEC_FREST))]
1933 [(set_attr "type" "shuf")])
1935 (define_insn "frsqest_<mode>"
1936 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1937 (unspec:VSF [(match_operand:VSF 1 "spu_reg_operand" "r")] UNSPEC_FRSQEST))]
1940 [(set_attr "type" "shuf")])
1942 (define_insn "fi_<mode>"
1943 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1944 (unspec:VSF [(match_operand:VSF 1 "spu_reg_operand" "r")
1945 (match_operand:VSF 2 "spu_reg_operand" "r")] UNSPEC_FI))]
1948 [(set_attr "type" "fp7")])
1953 (define_insn "and<mode>3"
1954 [(set (match_operand:MOV 0 "spu_reg_operand" "=r,r")
1955 (and:MOV (match_operand:MOV 1 "spu_reg_operand" "r,r")
1956 (match_operand:MOV 2 "spu_logical_operand" "r,C")))]
1960 and%j2i\t%0,%1,%J2")
1962 (define_insn "anddi3"
1963 [(set (match_operand:DI 0 "spu_reg_operand" "=r,r")
1964 (and:DI (match_operand:DI 1 "spu_reg_operand" "r,r")
1965 (match_operand:DI 2 "spu_logical_operand" "r,c")))]
1969 and%k2i\t%0,%1,%K2")
1971 (define_insn "andti3"
1972 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
1973 (and:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
1974 (match_operand:TI 2 "spu_logical_operand" "r,Y")))]
1978 and%m2i\t%0,%1,%L2")
1980 (define_insn "andc_<mode>"
1981 [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
1982 (and:ALL (not:ALL (match_operand:ALL 2 "spu_reg_operand" "r"))
1983 (match_operand:ALL 1 "spu_reg_operand" "r")))]
1987 (define_insn "nand_<mode>"
1988 [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
1989 (not:ALL (and:ALL (match_operand:ALL 2 "spu_reg_operand" "r")
1990 (match_operand:ALL 1 "spu_reg_operand" "r"))))]
1997 (define_insn "ior<mode>3"
1998 [(set (match_operand:MOV 0 "spu_reg_operand" "=r,r,r")
1999 (ior:MOV (match_operand:MOV 1 "spu_reg_operand" "r,r,0")
2000 (match_operand:MOV 2 "spu_ior_operand" "r,C,D")))]
2007 (define_insn "iordi3"
2008 [(set (match_operand:DI 0 "spu_reg_operand" "=r,r,r")
2009 (ior:DI (match_operand:DI 1 "spu_reg_operand" "r,r,0")
2010 (match_operand:DI 2 "spu_ior_operand" "r,c,d")))]
2017 (define_insn "iorti3"
2018 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r,r")
2019 (ior:TI (match_operand:TI 1 "spu_reg_operand" "r,r,0")
2020 (match_operand:TI 2 "spu_ior_operand" "r,Y,Z")))]
2027 (define_insn "orc_<mode>"
2028 [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
2029 (ior:ALL (not:ALL (match_operand:ALL 2 "spu_reg_operand" "r"))
2030 (match_operand:ALL 1 "spu_reg_operand" "r")))]
2034 (define_insn "nor_<mode>"
2035 [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
2036 (not:ALL (ior:ALL (match_operand:ALL 1 "spu_reg_operand" "r")
2037 (match_operand:ALL 2 "spu_reg_operand" "r"))))]
2043 (define_insn "xor<mode>3"
2044 [(set (match_operand:MOV 0 "spu_reg_operand" "=r,r")
2045 (xor:MOV (match_operand:MOV 1 "spu_reg_operand" "r,r")
2046 (match_operand:MOV 2 "spu_logical_operand" "r,B")))]
2050 xor%j2i\t%0,%1,%J2")
2052 (define_insn "xordi3"
2053 [(set (match_operand:DI 0 "spu_reg_operand" "=r,r")
2054 (xor:DI (match_operand:DI 1 "spu_reg_operand" "r,r")
2055 (match_operand:DI 2 "spu_logical_operand" "r,c")))]
2059 xor%k2i\t%0,%1,%K2")
2061 (define_insn "xorti3"
2062 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2063 (xor:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2064 (match_operand:TI 2 "spu_logical_operand" "r,Y")))]
2068 xor%m2i\t%0,%1,%L2")
2070 (define_insn "eqv_<mode>"
2071 [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
2072 (not:ALL (xor:ALL (match_operand:ALL 1 "spu_reg_operand" "r")
2073 (match_operand:ALL 2 "spu_reg_operand" "r"))))]
2079 (define_insn "one_cmpl<mode>2"
2080 [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
2081 (not:ALL (match_operand:ALL 1 "spu_reg_operand" "r")))]
2088 (define_expand "selb"
2089 [(set (match_operand 0 "spu_reg_operand" "")
2090 (unspec [(match_operand 1 "spu_reg_operand" "")
2091 (match_operand 2 "spu_reg_operand" "")
2092 (match_operand 3 "spu_reg_operand" "")] UNSPEC_SELB))]
2095 rtx s = gen__selb (operands[0], operands[1], operands[2], operands[3]);
2096 PUT_MODE (SET_SRC (s), GET_MODE (operands[0]));
2101 ;; This could be defined as a combination of logical operations, but at
2102 ;; one time it caused a crash due to recursive expansion of rtl during CSE.
2103 (define_insn "_selb"
2104 [(set (match_operand 0 "spu_reg_operand" "=r")
2105 (unspec [(match_operand 1 "spu_reg_operand" "r")
2106 (match_operand 2 "spu_reg_operand" "r")
2107 (match_operand 3 "spu_reg_operand" "r")] UNSPEC_SELB))]
2108 "GET_MODE(operands[0]) == GET_MODE(operands[1])
2109 && GET_MODE(operands[1]) == GET_MODE(operands[2])"
2110 "selb\t%0,%1,%2,%3")
2113 ;; Misc. byte/bit operations
2114 ;; clz/ctz/ffs/popcount/parity
2117 (define_insn "clz<mode>2"
2118 [(set (match_operand:VSI 0 "spu_reg_operand" "=r")
2119 (clz:VSI (match_operand:VSI 1 "spu_reg_operand" "r")))]
2123 (define_expand "ctz<mode>2"
2125 (neg:VSI (match_operand:VSI 1 "spu_reg_operand" "")))
2126 (set (match_dup 3) (and:VSI (match_dup 1)
2128 (set (match_dup 4) (clz:VSI (match_dup 3)))
2129 (set (match_operand:VSI 0 "spu_reg_operand" "")
2130 (minus:VSI (match_dup 5) (match_dup 4)))]
2133 operands[2] = gen_reg_rtx (<MODE>mode);
2134 operands[3] = gen_reg_rtx (<MODE>mode);
2135 operands[4] = gen_reg_rtx (<MODE>mode);
2136 operands[5] = spu_const(<MODE>mode, 31);
2139 (define_expand "ffs<mode>2"
2141 (neg:VSI (match_operand:VSI 1 "spu_reg_operand" "")))
2142 (set (match_dup 3) (and:VSI (match_dup 1)
2144 (set (match_dup 4) (clz:VSI (match_dup 3)))
2145 (set (match_operand:VSI 0 "spu_reg_operand" "")
2146 (minus:VSI (match_dup 5) (match_dup 4)))]
2149 operands[2] = gen_reg_rtx (<MODE>mode);
2150 operands[3] = gen_reg_rtx (<MODE>mode);
2151 operands[4] = gen_reg_rtx (<MODE>mode);
2152 operands[5] = spu_const(<MODE>mode, 32);
2155 (define_expand "popcountsi2"
2157 (unspec:SI [(match_operand:SI 1 "spu_reg_operand" "")]
2160 (unspec:HI [(match_dup 2)] UNSPEC_SUMB))
2161 (set (match_operand:SI 0 "spu_reg_operand" "")
2162 (sign_extend:SI (match_dup 3)))]
2165 operands[2] = gen_reg_rtx (SImode);
2166 operands[3] = gen_reg_rtx (HImode);
2169 (define_expand "paritysi2"
2170 [(set (match_operand:SI 0 "spu_reg_operand" "")
2171 (parity:SI (match_operand:SI 1 "spu_reg_operand" "")))]
2174 operands[2] = gen_reg_rtx (SImode);
2175 emit_insn (gen_popcountsi2(operands[2], operands[1]));
2176 emit_insn (gen_andsi3(operands[0], operands[2], GEN_INT (1)));
2180 (define_insn "cntb_si"
2181 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2182 (unspec:SI [(match_operand:SI 1 "spu_reg_operand" "r")]
2186 [(set_attr "type" "fxb")])
2188 (define_insn "cntb_v16qi"
2189 [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
2190 (unspec:V16QI [(match_operand:V16QI 1 "spu_reg_operand" "r")]
2194 [(set_attr "type" "fxb")])
2196 (define_insn "sumb_si"
2197 [(set (match_operand:HI 0 "spu_reg_operand" "=r")
2198 (unspec:HI [(match_operand:SI 1 "spu_reg_operand" "r")] UNSPEC_SUMB))]
2201 [(set_attr "type" "fxb")])
2206 (define_insn "<v>ashl<mode>3"
2207 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
2208 (ashift:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
2209 (match_operand:VHSI 2 "spu_nonmem_operand" "r,W")))]
2213 shl<bh>i\t%0,%1,%<umask>2"
2214 [(set_attr "type" "fx3")])
2216 (define_insn_and_split "ashldi3"
2217 [(set (match_operand:DI 0 "spu_reg_operand" "=r,r")
2218 (ashift:DI (match_operand:DI 1 "spu_reg_operand" "r,r")
2219 (match_operand:SI 2 "spu_nonmem_operand" "r,I")))
2220 (clobber (match_scratch:SI 3 "=&r,X"))]
2224 [(set (match_dup:DI 0)
2225 (ashift:DI (match_dup:DI 1)
2228 rtx op0 = gen_rtx_REG (TImode, REGNO (operands[0]));
2229 rtx op1 = gen_rtx_REG (TImode, REGNO (operands[1]));
2230 rtx op2 = operands[2];
2231 rtx op3 = operands[3];
2233 if (GET_CODE (operands[2]) == REG)
2235 emit_insn (gen_addsi3 (op3, op2, GEN_INT (64)));
2236 emit_insn (gen_rotlti3 (op0, op1, GEN_INT (64)));
2237 emit_insn (gen_shlqbybi_ti (op0, op0, op3));
2238 emit_insn (gen_shlqbi_ti (op0, op0, op3));
2242 HOST_WIDE_INT val = INTVAL (operands[2]);
2243 emit_insn (gen_rotlti3 (op0, op1, GEN_INT (64)));
2244 emit_insn (gen_shlqby_ti (op0, op0, GEN_INT (val / 8 + 8)));
2246 emit_insn (gen_shlqbi_ti (op0, op0, GEN_INT (val % 8)));
2251 (define_expand "ashlti3"
2252 [(parallel [(set (match_operand:TI 0 "spu_reg_operand" "")
2253 (ashift:TI (match_operand:TI 1 "spu_reg_operand" "")
2254 (match_operand:SI 2 "spu_nonmem_operand" "")))
2255 (clobber (match_dup:TI 3))])]
2257 "if (GET_CODE (operands[2]) == CONST_INT)
2259 emit_insn (gen_ashlti3_imm(operands[0], operands[1], operands[2]));
2262 operands[3] = gen_reg_rtx (TImode);")
2264 (define_insn_and_split "ashlti3_imm"
2265 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2266 (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2267 (match_operand:SI 2 "immediate_operand" "O,P")))]
2272 "!satisfies_constraint_O (operands[2]) && !satisfies_constraint_P (operands[2])"
2273 [(set (match_dup:TI 0)
2274 (ashift:TI (match_dup:TI 1)
2276 (set (match_dup:TI 0)
2277 (ashift:TI (match_dup:TI 0)
2280 HOST_WIDE_INT val = INTVAL(operands[2]);
2281 operands[3] = GEN_INT (val&7);
2282 operands[4] = GEN_INT (val&-8);
2284 [(set_attr "type" "shuf,shuf")])
2286 (define_insn_and_split "ashlti3_reg"
2287 [(set (match_operand:TI 0 "spu_reg_operand" "=r")
2288 (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r")
2289 (match_operand:SI 2 "spu_reg_operand" "r")))
2290 (clobber (match_operand:TI 3 "spu_reg_operand" "=&r"))]
2294 [(set (match_dup:TI 3)
2295 (ashift:TI (match_dup:TI 1)
2296 (and:SI (match_dup:SI 2)
2298 (set (match_dup:TI 0)
2299 (ashift:TI (match_dup:TI 3)
2300 (and:SI (match_dup:SI 2)
2304 (define_insn "shlqbybi_ti"
2305 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2306 (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2307 (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2313 [(set_attr "type" "shuf,shuf")])
2315 (define_insn "shlqbi_ti"
2316 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2317 (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2318 (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2324 [(set_attr "type" "shuf,shuf")])
2326 (define_insn "shlqby_ti"
2327 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2328 (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2329 (mult:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2335 [(set_attr "type" "shuf,shuf")])
2340 (define_insn_and_split "<v>lshr<mode>3"
2341 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
2342 (lshiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
2343 (match_operand:VHSI 2 "spu_nonmem_operand" "r,W")))
2344 (clobber (match_scratch:VHSI 3 "=&r,X"))]
2348 rot<bh>mi\t%0,%1,-%<umask>2"
2349 "reload_completed && GET_CODE (operands[2]) == REG"
2350 [(set (match_dup:VHSI 3)
2351 (neg:VHSI (match_dup:VHSI 2)))
2352 (set (match_dup:VHSI 0)
2353 (lshiftrt:VHSI (match_dup:VHSI 1)
2354 (neg:VHSI (match_dup:VHSI 3))))]
2356 [(set_attr "type" "*,fx3")])
2358 (define_insn "<v>lshr<mode>3_imm"
2359 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r")
2360 (lshiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r")
2361 (match_operand:VHSI 2 "immediate_operand" "W")))]
2363 "rot<bh>mi\t%0,%1,-%<umask>2"
2364 [(set_attr "type" "fx3")])
2366 (define_insn "rotm_<mode>"
2367 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
2368 (lshiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
2369 (neg:VHSI (match_operand:VHSI 2 "spu_nonmem_operand" "r,W"))))]
2373 rot<bh>mi\t%0,%1,-%<nmask>2"
2374 [(set_attr "type" "fx3")])
2376 (define_insn_and_split "lshr<mode>3"
2377 [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r,r")
2378 (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r,r")
2379 (match_operand:SI 2 "spu_nonmem_operand" "r,O,P")))]
2383 rotqmbyi\t%0,%1,-%h2
2384 rotqmbii\t%0,%1,-%e2"
2385 "REG_P (operands[2]) || (!satisfies_constraint_O (operands[2]) && !satisfies_constraint_P (operands[2]))"
2386 [(set (match_dup:DTI 3)
2387 (lshiftrt:DTI (match_dup:DTI 1)
2389 (set (match_dup:DTI 0)
2390 (lshiftrt:DTI (match_dup:DTI 3)
2393 operands[3] = gen_reg_rtx (<MODE>mode);
2394 if (GET_CODE (operands[2]) == CONST_INT)
2396 HOST_WIDE_INT val = INTVAL(operands[2]);
2397 operands[4] = GEN_INT (val & 7);
2398 operands[5] = GEN_INT (val & -8);
2402 rtx t0 = gen_reg_rtx (SImode);
2403 rtx t1 = gen_reg_rtx (SImode);
2404 emit_insn (gen_subsi3(t0, GEN_INT(0), operands[2]));
2405 emit_insn (gen_subsi3(t1, GEN_INT(7), operands[2]));
2406 operands[4] = gen_rtx_AND (SImode, gen_rtx_NEG (SImode, t0), GEN_INT (7));
2407 operands[5] = gen_rtx_AND (SImode, gen_rtx_NEG (SImode, gen_rtx_AND (SImode, t1, GEN_INT (-8))), GEN_INT (-8));
2410 [(set_attr "type" "*,shuf,shuf")])
2412 (define_expand "shrqbybi_<mode>"
2413 [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
2414 (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
2415 (and:SI (neg:SI (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2420 if (GET_CODE (operands[2]) == CONST_INT)
2421 operands[2] = GEN_INT (7 - INTVAL (operands[2]));
2424 rtx t0 = gen_reg_rtx (SImode);
2425 emit_insn (gen_subsi3 (t0, GEN_INT (7), operands[2]));
2430 (define_insn "rotqmbybi_<mode>"
2431 [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
2432 (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
2433 (and:SI (neg:SI (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2439 rotqmbyi\t%0,%1,-%H2"
2440 [(set_attr "type" "shuf")])
2442 (define_insn_and_split "shrqbi_<mode>"
2443 [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
2444 (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
2445 (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2447 (clobber (match_scratch:SI 3 "=&r,X"))]
2451 [(set (match_dup:DTI 0)
2452 (lshiftrt:DTI (match_dup:DTI 1)
2453 (and:SI (neg:SI (match_dup:SI 3)) (const_int 7))))]
2455 if (GET_CODE (operands[2]) == CONST_INT)
2456 operands[3] = GEN_INT (-INTVAL (operands[2]));
2458 emit_insn (gen_subsi3 (operands[3], GEN_INT (0), operands[2]));
2460 [(set_attr "type" "shuf")])
2462 (define_insn "rotqmbi_<mode>"
2463 [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
2464 (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
2465 (and:SI (neg:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I"))
2470 rotqmbii\t%0,%1,-%E2"
2471 [(set_attr "type" "shuf")])
2473 (define_expand "shrqby_<mode>"
2474 [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
2475 (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
2476 (mult:SI (neg:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I"))
2480 if (GET_CODE (operands[2]) == CONST_INT)
2481 operands[2] = GEN_INT (-INTVAL (operands[2]));
2484 rtx t0 = gen_reg_rtx (SImode);
2485 emit_insn (gen_subsi3 (t0, GEN_INT (0), operands[2]));
2490 (define_insn "rotqmby_<mode>"
2491 [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
2492 (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
2493 (mult:SI (neg:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I"))
2498 rotqmbyi\t%0,%1,-%F2"
2499 [(set_attr "type" "shuf")])
2504 (define_insn_and_split "<v>ashr<mode>3"
2505 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
2506 (ashiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
2507 (match_operand:VHSI 2 "spu_nonmem_operand" "r,W")))
2508 (clobber (match_scratch:VHSI 3 "=&r,X"))]
2512 rotma<bh>i\t%0,%1,-%<umask>2"
2513 "reload_completed && GET_CODE (operands[2]) == REG"
2514 [(set (match_dup:VHSI 3)
2515 (neg:VHSI (match_dup:VHSI 2)))
2516 (set (match_dup:VHSI 0)
2517 (ashiftrt:VHSI (match_dup:VHSI 1)
2518 (neg:VHSI (match_dup:VHSI 3))))]
2520 [(set_attr "type" "*,fx3")])
2522 (define_insn "<v>ashr<mode>3_imm"
2523 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r")
2524 (ashiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r")
2525 (match_operand:VHSI 2 "immediate_operand" "W")))]
2527 "rotma<bh>i\t%0,%1,-%<umask>2"
2528 [(set_attr "type" "fx3")])
2531 (define_insn "rotma_<mode>"
2532 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
2533 (ashiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
2534 (neg:VHSI (match_operand:VHSI 2 "spu_nonmem_operand" "r,W"))))]
2538 rotma<bh>i\t%0,%1,-%<nmask>2"
2539 [(set_attr "type" "fx3")])
2541 (define_insn_and_split "ashrdi3"
2542 [(set (match_operand:DI 0 "spu_reg_operand" "=r,r")
2543 (ashiftrt:DI (match_operand:DI 1 "spu_reg_operand" "r,r")
2544 (match_operand:SI 2 "spu_nonmem_operand" "r,I")))
2545 (clobber (match_scratch:TI 3 "=&r,&r"))
2546 (clobber (match_scratch:TI 4 "=&r,&r"))
2547 (clobber (match_scratch:SI 5 "=&r,&r"))]
2551 [(set (match_dup:DI 0)
2552 (ashiftrt:DI (match_dup:DI 1)
2555 rtx op0 = gen_rtx_REG (TImode, REGNO (operands[0]));
2556 rtx op0v = gen_rtx_REG (V4SImode, REGNO (op0));
2557 rtx op1 = gen_rtx_REG (TImode, REGNO (operands[1]));
2558 rtx op1s = gen_rtx_REG (SImode, REGNO (op1));
2559 rtx op2 = operands[2];
2560 rtx op3 = operands[3];
2561 rtx op4 = operands[4];
2562 rtx op5 = operands[5];
2564 if (GET_CODE (op2) == CONST_INT && INTVAL (op2) >= 63)
2566 rtx op0s = gen_rtx_REG (SImode, REGNO (op0));
2567 emit_insn (gen_ashrsi3 (op0s, op1s, GEN_INT (32)));
2568 emit_insn (gen_spu_fsm (op0v, op0s));
2570 else if (GET_CODE (op2) == CONST_INT && INTVAL (op2) >= 32)
2572 rtx op0d = gen_rtx_REG (V2DImode, REGNO (op0));
2573 HOST_WIDE_INT val = INTVAL (op2);
2574 emit_insn (gen_lshrti3 (op0, op1, GEN_INT (32)));
2575 emit_insn (gen_spu_xswd (op0d, op0v));
2577 emit_insn (gen_vashrv4si3 (op0v, op0v, spu_const (V4SImode, val - 32)));
2581 rtx op3v = gen_rtx_REG (V4SImode, REGNO (op3));
2582 unsigned char arr[16] = {
2583 0xff, 0xff, 0xff, 0xff,
2584 0xff, 0xff, 0xff, 0xff,
2585 0x00, 0x00, 0x00, 0x00,
2586 0x00, 0x00, 0x00, 0x00
2589 emit_insn (gen_ashrsi3 (op5, op1s, GEN_INT (31)));
2590 emit_move_insn (op4, array_to_constant (TImode, arr));
2591 emit_insn (gen_spu_fsm (op3v, op5));
2593 if (GET_CODE (operands[2]) == REG)
2595 emit_insn (gen_selb (op4, op3, op1, op4));
2596 emit_insn (gen_negsi2 (op5, op2));
2597 emit_insn (gen_rotqbybi_ti (op0, op4, op5));
2598 emit_insn (gen_rotqbi_ti (op0, op0, op5));
2602 HOST_WIDE_INT val = -INTVAL (op2);
2603 emit_insn (gen_selb (op0, op3, op1, op4));
2605 emit_insn (gen_rotqby_ti (op0, op0, GEN_INT ((val - 7) / 8)));
2607 emit_insn (gen_rotqbi_ti (op0, op0, GEN_INT (val % 8)));
2614 (define_insn_and_split "ashrti3"
2615 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2616 (ashiftrt:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2617 (match_operand:SI 2 "spu_nonmem_operand" "r,i")))]
2621 [(set (match_dup:TI 0)
2622 (ashiftrt:TI (match_dup:TI 1)
2625 rtx sign_shift = gen_reg_rtx (SImode);
2626 rtx sign_mask = gen_reg_rtx (TImode);
2627 rtx sign_mask_v4si = gen_rtx_SUBREG (V4SImode, sign_mask, 0);
2628 rtx op1_v4si = spu_gen_subreg (V4SImode, operands[1]);
2629 rtx t = gen_reg_rtx (TImode);
2630 emit_insn (gen_subsi3 (sign_shift, GEN_INT (128), force_reg (SImode, operands[2])));
2631 emit_insn (gen_vashrv4si3 (sign_mask_v4si, op1_v4si, spu_const (V4SImode, 31)));
2632 emit_insn (gen_fsm_ti (sign_mask, sign_mask));
2633 emit_insn (gen_ashlti3 (sign_mask, sign_mask, sign_shift));
2634 emit_insn (gen_lshrti3 (t, operands[1], operands[2]));
2635 emit_insn (gen_iorti3 (operands[0], t, sign_mask));
2639 ;; fsm is used after rotam to replicate the sign across the whole register.
2640 (define_insn "fsm_ti"
2641 [(set (match_operand:TI 0 "spu_reg_operand" "=r")
2642 (unspec:TI [(match_operand:TI 1 "spu_reg_operand" "r")] UNSPEC_FSM))]
2645 [(set_attr "type" "shuf")])
2650 (define_insn "<v>rotl<mode>3"
2651 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
2652 (rotate:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
2653 (match_operand:VHSI 2 "spu_nonmem_operand" "r,W")))]
2657 rot<bh>i\t%0,%1,%<umask>2"
2658 [(set_attr "type" "fx3")])
2660 (define_insn "rotlti3"
2661 [(set (match_operand:TI 0 "spu_reg_operand" "=&r,r,r,r")
2662 (rotate:TI (match_operand:TI 1 "spu_reg_operand" "r,r,r,r")
2663 (match_operand:SI 2 "spu_nonmem_operand" "r,O,P,I")))]
2666 rotqbybi\t%0,%1,%2\;rotqbi\t%0,%0,%2
2669 rotqbyi\t%0,%1,%h2\;rotqbii\t%0,%0,%e2"
2670 [(set_attr "length" "8,4,4,8")
2671 (set_attr "type" "multi1,shuf,shuf,multi1")])
2673 (define_insn "rotqbybi_ti"
2674 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2675 (rotate:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2676 (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2682 [(set_attr "type" "shuf,shuf")])
2684 (define_insn "rotqby_ti"
2685 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2686 (rotate:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2687 (mult:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2693 [(set_attr "type" "shuf,shuf")])
2695 (define_insn "rotqbi_ti"
2696 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2697 (rotate:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2698 (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2704 [(set_attr "type" "shuf,shuf")])
2707 ;; struct extract/insert
2708 ;; We handle mem's because GCC will generate invalid SUBREG's
2709 ;; and inefficient code.
2711 (define_expand "extv"
2712 [(set (match_operand:TI 0 "register_operand" "")
2713 (sign_extract:TI (match_operand 1 "nonimmediate_operand" "")
2714 (match_operand:SI 2 "const_int_operand" "")
2715 (match_operand:SI 3 "const_int_operand" "")))]
2718 spu_expand_extv (operands, 0);
2722 (define_expand "extzv"
2723 [(set (match_operand:TI 0 "register_operand" "")
2724 (zero_extract:TI (match_operand 1 "nonimmediate_operand" "")
2725 (match_operand:SI 2 "const_int_operand" "")
2726 (match_operand:SI 3 "const_int_operand" "")))]
2729 spu_expand_extv (operands, 1);
2733 (define_expand "insv"
2734 [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
2735 (match_operand:SI 1 "const_int_operand" "")
2736 (match_operand:SI 2 "const_int_operand" ""))
2737 (match_operand 3 "nonmemory_operand" ""))]
2739 { spu_expand_insv(operands); DONE; })
2741 ;; Simplify a number of patterns that get generated by extv, extzv,
2743 (define_insn_and_split "trunc_shr_ti<mode>"
2744 [(set (match_operand:QHSI 0 "spu_reg_operand" "=r")
2745 (truncate:QHSI (match_operator:TI 2 "shiftrt_operator" [(match_operand:TI 1 "spu_reg_operand" "0")
2752 spu_split_convert (operands);
2755 [(set_attr "type" "convert")
2756 (set_attr "length" "0")])
2758 (define_insn_and_split "trunc_shr_tidi"
2759 [(set (match_operand:DI 0 "spu_reg_operand" "=r")
2760 (truncate:DI (match_operator:TI 2 "shiftrt_operator" [(match_operand:TI 1 "spu_reg_operand" "0")
2767 spu_split_convert (operands);
2770 [(set_attr "type" "convert")
2771 (set_attr "length" "0")])
2773 (define_insn_and_split "shl_ext_<mode>ti"
2774 [(set (match_operand:TI 0 "spu_reg_operand" "=r")
2775 (ashift:TI (match_operator:TI 2 "extend_operator" [(match_operand:QHSI 1 "spu_reg_operand" "0")])
2782 spu_split_convert (operands);
2785 [(set_attr "type" "convert")
2786 (set_attr "length" "0")])
2788 (define_insn_and_split "shl_ext_diti"
2789 [(set (match_operand:TI 0 "spu_reg_operand" "=r")
2790 (ashift:TI (match_operator:TI 2 "extend_operator" [(match_operand:DI 1 "spu_reg_operand" "0")])
2797 spu_split_convert (operands);
2800 [(set_attr "type" "convert")
2801 (set_attr "length" "0")])
2803 (define_insn "sext_trunc_lshr_tiqisi"
2804 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2805 (sign_extend:SI (truncate:QI (match_operator:TI 2 "shiftrt_operator" [(match_operand:TI 1 "spu_reg_operand" "r")
2806 (const_int 120)]))))]
2809 [(set_attr "type" "fx3")])
2811 (define_insn "zext_trunc_lshr_tiqisi"
2812 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2813 (zero_extend:SI (truncate:QI (match_operator:TI 2 "shiftrt_operator" [(match_operand:TI 1 "spu_reg_operand" "r")
2814 (const_int 120)]))))]
2817 [(set_attr "type" "fx3")])
2819 (define_insn "sext_trunc_lshr_tihisi"
2820 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2821 (sign_extend:SI (truncate:HI (match_operator:TI 2 "shiftrt_operator" [(match_operand:TI 1 "spu_reg_operand" "r")
2822 (const_int 112)]))))]
2825 [(set_attr "type" "fx3")])
2827 (define_insn "zext_trunc_lshr_tihisi"
2828 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2829 (zero_extend:SI (truncate:HI (match_operator:TI 2 "shiftrt_operator" [(match_operand:TI 1 "spu_reg_operand" "r")
2830 (const_int 112)]))))]
2833 [(set_attr "type" "fx3")])
2836 ;; String/block move insn.
2837 ;; Argument 0 is the destination
2838 ;; Argument 1 is the source
2839 ;; Argument 2 is the length
2840 ;; Argument 3 is the alignment
2842 (define_expand "movstrsi"
2843 [(parallel [(set (match_operand:BLK 0 "" "")
2844 (match_operand:BLK 1 "" ""))
2845 (use (match_operand:SI 2 "" ""))
2846 (use (match_operand:SI 3 "" ""))])]
2850 if (spu_expand_block_move (operands))
2859 (define_insn "indirect_jump"
2860 [(set (pc) (match_operand:SI 0 "spu_reg_operand" "r"))]
2863 [(set_attr "type" "br")])
2867 (label_ref (match_operand 0 "" "")))]
2870 [(set_attr "type" "br")])
2875 ;; This will be used for leaf functions, that don't save any regs and
2876 ;; don't have locals on stack, maybe... that is for functions that
2877 ;; don't change $sp and don't need to save $lr.
2878 (define_expand "return"
2883 ;; used in spu_expand_epilogue to generate return from a function and
2884 ;; explicitly set use of $lr.
2886 (define_insn "_return"
2890 [(set_attr "type" "br")])
2896 (define_insn "ceq_<mode>"
2897 [(set (match_operand:VQHSI 0 "spu_reg_operand" "=r,r")
2898 (eq:VQHSI (match_operand:VQHSI 1 "spu_reg_operand" "r,r")
2899 (match_operand:VQHSI 2 "spu_arith_operand" "r,B")))]
2903 ceq<bh>i\t%0,%1,%2")
2905 (define_insn_and_split "ceq_di"
2906 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2907 (eq:SI (match_operand:DI 1 "spu_reg_operand" "r")
2908 (match_operand:DI 2 "spu_reg_operand" "r")))]
2912 [(set (match_dup:SI 0)
2913 (eq:SI (match_dup:DI 1)
2916 rtx op0 = gen_rtx_REG (V4SImode, REGNO (operands[0]));
2917 rtx op1 = gen_rtx_REG (V4SImode, REGNO (operands[1]));
2918 rtx op2 = gen_rtx_REG (V4SImode, REGNO (operands[2]));
2919 emit_insn (gen_ceq_v4si (op0, op1, op2));
2920 emit_insn (gen_spu_gb (op0, op0));
2921 emit_insn (gen_cgt_si (operands[0], operands[0], GEN_INT (11)));
2926 ;; We provide the TI compares for completeness and because some parts of
2927 ;; gcc/libgcc use them, even though user code might never see it.
2928 (define_insn "ceq_ti"
2929 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2930 (eq:SI (match_operand:TI 1 "spu_reg_operand" "r")
2931 (match_operand:TI 2 "spu_reg_operand" "r")))]
2933 "ceq\t%0,%1,%2\;gb\t%0,%0\;ceqi\t%0,%0,15"
2934 [(set_attr "type" "multi0")
2935 (set_attr "length" "12")])
2937 (define_insn "ceq_<mode>"
2938 [(set (match_operand:<F2I> 0 "spu_reg_operand" "=r")
2939 (eq:<F2I> (match_operand:VSF 1 "spu_reg_operand" "r")
2940 (match_operand:VSF 2 "spu_reg_operand" "r")))]
2944 (define_insn "cmeq_<mode>"
2945 [(set (match_operand:<F2I> 0 "spu_reg_operand" "=r")
2946 (eq:<F2I> (abs:VSF (match_operand:VSF 1 "spu_reg_operand" "r"))
2947 (abs:VSF (match_operand:VSF 2 "spu_reg_operand" "r"))))]
2951 ;; These implementations will ignore checking of NaN or INF if
2952 ;; compiled with option -ffinite-math-only.
2953 (define_expand "ceq_df"
2954 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2955 (eq:SI (match_operand:DF 1 "spu_reg_operand" "r")
2956 (match_operand:DF 2 "const_zero_operand" "i")))]
2959 if (spu_arch == PROCESSOR_CELL)
2961 rtx ra = gen_reg_rtx (V4SImode);
2962 rtx rb = gen_reg_rtx (V4SImode);
2963 rtx temp = gen_reg_rtx (TImode);
2964 rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
2965 rtx temp2 = gen_reg_rtx (V4SImode);
2966 rtx biteq = gen_reg_rtx (V4SImode);
2967 rtx ahi_inf = gen_reg_rtx (V4SImode);
2968 rtx a_nan = gen_reg_rtx (V4SImode);
2969 rtx a_abs = gen_reg_rtx (V4SImode);
2970 rtx b_abs = gen_reg_rtx (V4SImode);
2971 rtx iszero = gen_reg_rtx (V4SImode);
2972 rtx sign_mask = gen_reg_rtx (V4SImode);
2973 rtx nan_mask = gen_reg_rtx (V4SImode);
2974 rtx hihi_promote = gen_reg_rtx (TImode);
2975 rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF,
2976 0x7FFFFFFF, 0xFFFFFFFF);
2978 emit_move_insn (sign_mask, pat);
2979 pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0,
2981 emit_move_insn (nan_mask, pat);
2982 pat = spu_const_from_ints (TImode, 0x00010203, 0x10111213,
2983 0x08090A0B, 0x18191A1B);
2984 emit_move_insn (hihi_promote, pat);
2986 emit_insn (gen_spu_convert (ra, operands[1]));
2987 emit_insn (gen_spu_convert (rb, operands[2]));
2988 emit_insn (gen_ceq_v4si (biteq, ra, rb));
2989 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, biteq),
2991 emit_insn (gen_andv4si3 (biteq, biteq, temp_v4si));
2993 emit_insn (gen_andv4si3 (a_abs, ra, sign_mask));
2994 emit_insn (gen_andv4si3 (b_abs, rb, sign_mask));
2995 if (!flag_finite_math_only)
2997 emit_insn (gen_clgt_v4si (a_nan, a_abs, nan_mask));
2998 emit_insn (gen_ceq_v4si (ahi_inf, a_abs, nan_mask));
2999 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, a_nan),
3001 emit_insn (gen_andv4si3 (temp2, temp_v4si, ahi_inf));
3002 emit_insn (gen_iorv4si3 (a_nan, a_nan, temp2));
3004 emit_insn (gen_iorv4si3 (temp2, a_abs, b_abs));
3005 emit_insn (gen_ceq_v4si (iszero, temp2, CONST0_RTX (V4SImode)));
3006 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, iszero),
3008 emit_insn (gen_andv4si3 (iszero, iszero, temp_v4si));
3009 emit_insn (gen_iorv4si3 (temp2, biteq, iszero));
3010 if (!flag_finite_math_only)
3012 emit_insn (gen_andc_v4si (temp2, temp2, a_nan));
3014 emit_insn (gen_shufb (operands[0], temp2, temp2, hihi_promote));
3019 (define_insn "ceq_<mode>_celledp"
3020 [(set (match_operand:<DF2I> 0 "spu_reg_operand" "=r")
3021 (eq:<DF2I> (match_operand:VDF 1 "spu_reg_operand" "r")
3022 (match_operand:VDF 2 "spu_reg_operand" "r")))]
3023 "spu_arch == PROCESSOR_CELLEDP"
3025 [(set_attr "type" "fpd")])
3027 (define_insn "cmeq_<mode>_celledp"
3028 [(set (match_operand:<DF2I> 0 "spu_reg_operand" "=r")
3029 (eq:<DF2I> (abs:VDF (match_operand:VDF 1 "spu_reg_operand" "r"))
3030 (abs:VDF (match_operand:VDF 2 "spu_reg_operand" "r"))))]
3031 "spu_arch == PROCESSOR_CELLEDP"
3033 [(set_attr "type" "fpd")])
3035 (define_expand "ceq_v2df"
3036 [(set (match_operand:V2DI 0 "spu_reg_operand" "=r")
3037 (eq:V2DI (match_operand:V2DF 1 "spu_reg_operand" "r")
3038 (match_operand:V2DF 2 "spu_reg_operand" "r")))]
3041 if (spu_arch == PROCESSOR_CELL)
3043 rtx ra = spu_gen_subreg (V4SImode, operands[1]);
3044 rtx rb = spu_gen_subreg (V4SImode, operands[2]);
3045 rtx temp = gen_reg_rtx (TImode);
3046 rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
3047 rtx temp2 = gen_reg_rtx (V4SImode);
3048 rtx biteq = gen_reg_rtx (V4SImode);
3049 rtx ahi_inf = gen_reg_rtx (V4SImode);
3050 rtx a_nan = gen_reg_rtx (V4SImode);
3051 rtx a_abs = gen_reg_rtx (V4SImode);
3052 rtx b_abs = gen_reg_rtx (V4SImode);
3053 rtx iszero = gen_reg_rtx (V4SImode);
3054 rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF,
3055 0x7FFFFFFF, 0xFFFFFFFF);
3056 rtx sign_mask = gen_reg_rtx (V4SImode);
3057 rtx nan_mask = gen_reg_rtx (V4SImode);
3058 rtx hihi_promote = gen_reg_rtx (TImode);
3060 emit_move_insn (sign_mask, pat);
3061 pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0,
3063 emit_move_insn (nan_mask, pat);
3064 pat = spu_const_from_ints (TImode, 0x00010203, 0x10111213,
3065 0x08090A0B, 0x18191A1B);
3066 emit_move_insn (hihi_promote, pat);
3068 emit_insn (gen_ceq_v4si (biteq, ra, rb));
3069 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, biteq),
3071 emit_insn (gen_andv4si3 (biteq, biteq, temp_v4si));
3072 emit_insn (gen_andv4si3 (a_abs, ra, sign_mask));
3073 emit_insn (gen_andv4si3 (b_abs, rb, sign_mask));
3074 emit_insn (gen_clgt_v4si (a_nan, a_abs, nan_mask));
3075 emit_insn (gen_ceq_v4si (ahi_inf, a_abs, nan_mask));
3076 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, a_nan),
3078 emit_insn (gen_andv4si3 (temp2, temp_v4si, ahi_inf));
3079 emit_insn (gen_iorv4si3 (a_nan, a_nan, temp2));
3080 emit_insn (gen_iorv4si3 (temp2, a_abs, b_abs));
3081 emit_insn (gen_ceq_v4si (iszero, temp2, CONST0_RTX (V4SImode)));
3082 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, iszero),
3084 emit_insn (gen_andv4si3 (iszero, iszero, temp_v4si));
3085 emit_insn (gen_iorv4si3 (temp2, biteq, iszero));
3086 emit_insn (gen_andc_v4si (temp2, temp2, a_nan));
3087 emit_insn (gen_shufb (operands[0], temp2, temp2, hihi_promote));
3092 (define_expand "cmeq_v2df"
3093 [(set (match_operand:V2DI 0 "spu_reg_operand" "=r")
3094 (eq:V2DI (abs:V2DF (match_operand:V2DF 1 "spu_reg_operand" "r"))
3095 (abs:V2DF (match_operand:V2DF 2 "spu_reg_operand" "r"))))]
3098 if (spu_arch == PROCESSOR_CELL)
3100 rtx ra = spu_gen_subreg (V4SImode, operands[1]);
3101 rtx rb = spu_gen_subreg (V4SImode, operands[2]);
3102 rtx temp = gen_reg_rtx (TImode);
3103 rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
3104 rtx temp2 = gen_reg_rtx (V4SImode);
3105 rtx biteq = gen_reg_rtx (V4SImode);
3106 rtx ahi_inf = gen_reg_rtx (V4SImode);
3107 rtx a_nan = gen_reg_rtx (V4SImode);
3108 rtx a_abs = gen_reg_rtx (V4SImode);
3109 rtx b_abs = gen_reg_rtx (V4SImode);
3111 rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF,
3112 0x7FFFFFFF, 0xFFFFFFFF);
3113 rtx sign_mask = gen_reg_rtx (V4SImode);
3114 rtx nan_mask = gen_reg_rtx (V4SImode);
3115 rtx hihi_promote = gen_reg_rtx (TImode);
3117 emit_move_insn (sign_mask, pat);
3119 pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0,
3121 emit_move_insn (nan_mask, pat);
3122 pat = spu_const_from_ints (TImode, 0x00010203, 0x10111213,
3123 0x08090A0B, 0x18191A1B);
3124 emit_move_insn (hihi_promote, pat);
3126 emit_insn (gen_andv4si3 (a_abs, ra, sign_mask));
3127 emit_insn (gen_andv4si3 (b_abs, rb, sign_mask));
3128 emit_insn (gen_ceq_v4si (biteq, a_abs, b_abs));
3129 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, biteq),
3131 emit_insn (gen_andv4si3 (biteq, biteq, temp_v4si));
3132 emit_insn (gen_clgt_v4si (a_nan, a_abs, nan_mask));
3133 emit_insn (gen_ceq_v4si (ahi_inf, a_abs, nan_mask));
3134 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, a_nan),
3136 emit_insn (gen_andv4si3 (temp2, temp_v4si, ahi_inf));
3137 emit_insn (gen_iorv4si3 (a_nan, a_nan, temp2));
3138 emit_insn (gen_andc_v4si (temp2, biteq, a_nan));
3139 emit_insn (gen_shufb (operands[0], temp2, temp2, hihi_promote));
3147 (define_insn "cgt_<mode>"
3148 [(set (match_operand:VQHSI 0 "spu_reg_operand" "=r,r")
3149 (gt:VQHSI (match_operand:VQHSI 1 "spu_reg_operand" "r,r")
3150 (match_operand:VQHSI 2 "spu_arith_operand" "r,B")))]
3154 cgt<bh>i\t%0,%1,%2")
3156 (define_insn "cgt_di_m1"
3157 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3158 (gt:SI (match_operand:DI 1 "spu_reg_operand" "r")
3163 (define_insn_and_split "cgt_di"
3164 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3165 (gt:SI (match_operand:DI 1 "spu_reg_operand" "r")
3166 (match_operand:DI 2 "spu_reg_operand" "r")))
3167 (clobber (match_scratch:V4SI 3 "=&r"))
3168 (clobber (match_scratch:V4SI 4 "=&r"))
3169 (clobber (match_scratch:V4SI 5 "=&r"))]
3173 [(set (match_dup:SI 0)
3174 (gt:SI (match_dup:DI 1)
3177 rtx op0 = gen_rtx_REG (V4SImode, REGNO (operands[0]));
3178 rtx op1 = gen_rtx_REG (V4SImode, REGNO (operands[1]));
3179 rtx op2 = gen_rtx_REG (V4SImode, REGNO (operands[2]));
3180 rtx op3 = operands[3];
3181 rtx op4 = operands[4];
3182 rtx op5 = operands[5];
3183 rtx op3d = gen_rtx_REG (V2DImode, REGNO (operands[3]));
3184 emit_insn (gen_clgt_v4si (op3, op1, op2));
3185 emit_insn (gen_ceq_v4si (op4, op1, op2));
3186 emit_insn (gen_cgt_v4si (op5, op1, op2));
3187 emit_insn (gen_spu_xswd (op3d, op3));
3188 emit_insn (gen_selb (op0, op5, op3, op4));
3192 (define_insn "cgt_ti"
3193 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3194 (gt:SI (match_operand:TI 1 "spu_reg_operand" "r")
3195 (match_operand:TI 2 "spu_reg_operand" "r")))
3196 (clobber (match_scratch:V4SI 3 "=&r"))
3197 (clobber (match_scratch:V4SI 4 "=&r"))
3198 (clobber (match_scratch:V4SI 5 "=&r"))]
3204 selb\t%0,%4,%0,%3\;\
3206 selb\t%0,%4,%0,%3\;\
3209 [(set_attr "type" "multi0")
3210 (set_attr "length" "36")])
3212 (define_insn "cgt_<mode>"
3213 [(set (match_operand:<F2I> 0 "spu_reg_operand" "=r")
3214 (gt:<F2I> (match_operand:VSF 1 "spu_reg_operand" "r")
3215 (match_operand:VSF 2 "spu_reg_operand" "r")))]
3219 (define_insn "cmgt_<mode>"
3220 [(set (match_operand:<F2I> 0 "spu_reg_operand" "=r")
3221 (gt:<F2I> (abs:VSF (match_operand:VSF 1 "spu_reg_operand" "r"))
3222 (abs:VSF (match_operand:VSF 2 "spu_reg_operand" "r"))))]
3226 (define_expand "cgt_df"
3227 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3228 (gt:SI (match_operand:DF 1 "spu_reg_operand" "r")
3229 (match_operand:DF 2 "const_zero_operand" "i")))]
3232 if (spu_arch == PROCESSOR_CELL)
3234 rtx ra = gen_reg_rtx (V4SImode);
3235 rtx rb = gen_reg_rtx (V4SImode);
3236 rtx zero = gen_reg_rtx (V4SImode);
3237 rtx temp = gen_reg_rtx (TImode);
3238 rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
3239 rtx temp2 = gen_reg_rtx (V4SImode);
3240 rtx hi_inf = gen_reg_rtx (V4SImode);
3241 rtx a_nan = gen_reg_rtx (V4SImode);
3242 rtx b_nan = gen_reg_rtx (V4SImode);
3243 rtx a_abs = gen_reg_rtx (V4SImode);
3244 rtx b_abs = gen_reg_rtx (V4SImode);
3245 rtx asel = gen_reg_rtx (V4SImode);
3246 rtx bsel = gen_reg_rtx (V4SImode);
3247 rtx abor = gen_reg_rtx (V4SImode);
3248 rtx bbor = gen_reg_rtx (V4SImode);
3249 rtx gt_hi = gen_reg_rtx (V4SImode);
3250 rtx gt_lo = gen_reg_rtx (V4SImode);
3251 rtx sign_mask = gen_reg_rtx (V4SImode);
3252 rtx nan_mask = gen_reg_rtx (V4SImode);
3253 rtx hi_promote = gen_reg_rtx (TImode);
3254 rtx borrow_shuffle = gen_reg_rtx (TImode);
3256 rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF,
3257 0x7FFFFFFF, 0xFFFFFFFF);
3258 emit_move_insn (sign_mask, pat);
3259 pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0,
3261 emit_move_insn (nan_mask, pat);
3262 pat = spu_const_from_ints (TImode, 0x00010203, 0x00010203,
3263 0x08090A0B, 0x08090A0B);
3264 emit_move_insn (hi_promote, pat);
3265 pat = spu_const_from_ints (TImode, 0x04050607, 0xC0C0C0C0,
3266 0x0C0D0E0F, 0xC0C0C0C0);
3267 emit_move_insn (borrow_shuffle, pat);
3269 emit_insn (gen_spu_convert (ra, operands[1]));
3270 emit_insn (gen_spu_convert (rb, operands[2]));
3271 emit_insn (gen_andv4si3 (a_abs, ra, sign_mask));
3272 emit_insn (gen_andv4si3 (b_abs, rb, sign_mask));
3274 if (!flag_finite_math_only)
3276 /* check if ra is NaN */
3277 emit_insn (gen_ceq_v4si (hi_inf, a_abs, nan_mask));
3278 emit_insn (gen_clgt_v4si (a_nan, a_abs, nan_mask));
3279 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, a_nan),
3281 emit_insn (gen_andv4si3 (temp2, temp_v4si, hi_inf));
3282 emit_insn (gen_iorv4si3 (a_nan, a_nan, temp2));
3283 emit_insn (gen_shufb (a_nan, a_nan, a_nan, hi_promote));
3285 /* check if rb is NaN */
3286 emit_insn (gen_ceq_v4si (hi_inf, b_abs, nan_mask));
3287 emit_insn (gen_clgt_v4si (b_nan, b_abs, nan_mask));
3288 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, b_nan),
3290 emit_insn (gen_andv4si3 (temp2, temp_v4si, hi_inf));
3291 emit_insn (gen_iorv4si3 (b_nan, b_nan, temp2));
3292 emit_insn (gen_shufb (b_nan, b_nan, b_nan, hi_promote));
3294 /* check if ra or rb is NaN */
3295 emit_insn (gen_iorv4si3 (a_nan, a_nan, b_nan));
3297 emit_move_insn (zero, CONST0_RTX (V4SImode));
3298 emit_insn (gen_vashrv4si3 (asel, ra, spu_const (V4SImode, 31)));
3299 emit_insn (gen_shufb (asel, asel, asel, hi_promote));
3300 emit_insn (gen_bg_v4si (abor, zero, a_abs));
3301 emit_insn (gen_shufb (abor, abor, abor, borrow_shuffle));
3302 emit_insn (gen_sfx_v4si (abor, zero, a_abs, abor));
3303 emit_insn (gen_selb (abor, a_abs, abor, asel));
3305 emit_insn (gen_vashrv4si3 (bsel, rb, spu_const (V4SImode, 31)));
3306 emit_insn (gen_shufb (bsel, bsel, bsel, hi_promote));
3307 emit_insn (gen_bg_v4si (bbor, zero, b_abs));
3308 emit_insn (gen_shufb (bbor, bbor, bbor, borrow_shuffle));
3309 emit_insn (gen_sfx_v4si (bbor, zero, b_abs, bbor));
3310 emit_insn (gen_selb (bbor, b_abs, bbor, bsel));
3312 emit_insn (gen_cgt_v4si (gt_hi, abor, bbor));
3313 emit_insn (gen_clgt_v4si (gt_lo, abor, bbor));
3314 emit_insn (gen_ceq_v4si (temp2, abor, bbor));
3315 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, gt_lo),
3317 emit_insn (gen_andv4si3 (temp2, temp2, temp_v4si));
3318 emit_insn (gen_iorv4si3 (temp2, gt_hi, temp2));
3319 emit_insn (gen_shufb (temp2, temp2, temp2, hi_promote));
3320 if (!flag_finite_math_only)
3322 /* correct for NaNs */
3323 emit_insn (gen_andc_v4si (temp2, temp2, a_nan));
3325 emit_insn (gen_spu_convert (operands[0], temp2));
3330 (define_insn "cgt_<mode>_celledp"
3331 [(set (match_operand:<DF2I> 0 "spu_reg_operand" "=r")
3332 (gt:<DF2I> (match_operand:VDF 1 "spu_reg_operand" "r")
3333 (match_operand:VDF 2 "spu_reg_operand" "r")))]
3334 "spu_arch == PROCESSOR_CELLEDP"
3336 [(set_attr "type" "fpd")])
3338 (define_insn "cmgt_<mode>_celledp"
3339 [(set (match_operand:<DF2I> 0 "spu_reg_operand" "=r")
3340 (gt:<DF2I> (abs:VDF (match_operand:VDF 1 "spu_reg_operand" "r"))
3341 (abs:VDF (match_operand:VDF 2 "spu_reg_operand" "r"))))]
3342 "spu_arch == PROCESSOR_CELLEDP"
3344 [(set_attr "type" "fpd")])
3346 (define_expand "cgt_v2df"
3347 [(set (match_operand:V2DI 0 "spu_reg_operand" "=r")
3348 (gt:V2DI (match_operand:V2DF 1 "spu_reg_operand" "r")
3349 (match_operand:V2DF 2 "spu_reg_operand" "r")))]
3352 if (spu_arch == PROCESSOR_CELL)
3354 rtx ra = spu_gen_subreg (V4SImode, operands[1]);
3355 rtx rb = spu_gen_subreg (V4SImode, operands[2]);
3356 rtx zero = gen_reg_rtx (V4SImode);
3357 rtx temp = gen_reg_rtx (TImode);
3358 rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
3359 rtx temp2 = gen_reg_rtx (V4SImode);
3360 rtx hi_inf = gen_reg_rtx (V4SImode);
3361 rtx a_nan = gen_reg_rtx (V4SImode);
3362 rtx b_nan = gen_reg_rtx (V4SImode);
3363 rtx a_abs = gen_reg_rtx (V4SImode);
3364 rtx b_abs = gen_reg_rtx (V4SImode);
3365 rtx asel = gen_reg_rtx (V4SImode);
3366 rtx bsel = gen_reg_rtx (V4SImode);
3367 rtx abor = gen_reg_rtx (V4SImode);
3368 rtx bbor = gen_reg_rtx (V4SImode);
3369 rtx gt_hi = gen_reg_rtx (V4SImode);
3370 rtx gt_lo = gen_reg_rtx (V4SImode);
3371 rtx sign_mask = gen_reg_rtx (V4SImode);
3372 rtx nan_mask = gen_reg_rtx (V4SImode);
3373 rtx hi_promote = gen_reg_rtx (TImode);
3374 rtx borrow_shuffle = gen_reg_rtx (TImode);
3375 rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF,
3376 0x7FFFFFFF, 0xFFFFFFFF);
3377 emit_move_insn (sign_mask, pat);
3378 pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0,
3380 emit_move_insn (nan_mask, pat);
3381 pat = spu_const_from_ints (TImode, 0x00010203, 0x00010203,
3382 0x08090A0B, 0x08090A0B);
3383 emit_move_insn (hi_promote, pat);
3384 pat = spu_const_from_ints (TImode, 0x04050607, 0xC0C0C0C0,
3385 0x0C0D0E0F, 0xC0C0C0C0);
3386 emit_move_insn (borrow_shuffle, pat);
3388 emit_insn (gen_andv4si3 (a_abs, ra, sign_mask));
3389 emit_insn (gen_ceq_v4si (hi_inf, a_abs, nan_mask));
3390 emit_insn (gen_clgt_v4si (a_nan, a_abs, nan_mask));
3391 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, a_nan),
3393 emit_insn (gen_andv4si3 (temp2, temp_v4si, hi_inf));
3394 emit_insn (gen_iorv4si3 (a_nan, a_nan, temp2));
3395 emit_insn (gen_shufb (a_nan, a_nan, a_nan, hi_promote));
3396 emit_insn (gen_andv4si3 (b_abs, rb, sign_mask));
3397 emit_insn (gen_ceq_v4si (hi_inf, b_abs, nan_mask));
3398 emit_insn (gen_clgt_v4si (b_nan, b_abs, nan_mask));
3399 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, b_nan),
3401 emit_insn (gen_andv4si3 (temp2, temp_v4si, hi_inf));
3402 emit_insn (gen_iorv4si3 (b_nan, b_nan, temp2));
3403 emit_insn (gen_shufb (b_nan, b_nan, b_nan, hi_promote));
3404 emit_insn (gen_iorv4si3 (a_nan, a_nan, b_nan));
3405 emit_move_insn (zero, CONST0_RTX (V4SImode));
3406 emit_insn (gen_vashrv4si3 (asel, ra, spu_const (V4SImode, 31)));
3407 emit_insn (gen_shufb (asel, asel, asel, hi_promote));
3408 emit_insn (gen_bg_v4si (abor, zero, a_abs));
3409 emit_insn (gen_shufb (abor, abor, abor, borrow_shuffle));
3410 emit_insn (gen_sfx_v4si (abor, zero, a_abs, abor));
3411 emit_insn (gen_selb (abor, a_abs, abor, asel));
3412 emit_insn (gen_vashrv4si3 (bsel, rb, spu_const (V4SImode, 31)));
3413 emit_insn (gen_shufb (bsel, bsel, bsel, hi_promote));
3414 emit_insn (gen_bg_v4si (bbor, zero, b_abs));
3415 emit_insn (gen_shufb (bbor, bbor, bbor, borrow_shuffle));
3416 emit_insn (gen_sfx_v4si (bbor, zero, b_abs, bbor));
3417 emit_insn (gen_selb (bbor, b_abs, bbor, bsel));
3418 emit_insn (gen_cgt_v4si (gt_hi, abor, bbor));
3419 emit_insn (gen_clgt_v4si (gt_lo, abor, bbor));
3420 emit_insn (gen_ceq_v4si (temp2, abor, bbor));
3421 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, gt_lo),
3423 emit_insn (gen_andv4si3 (temp2, temp2, temp_v4si));
3424 emit_insn (gen_iorv4si3 (temp2, gt_hi, temp2));
3426 emit_insn (gen_shufb (temp2, temp2, temp2, hi_promote));
3427 emit_insn (gen_andc_v4si (temp2, temp2, a_nan));
3428 emit_move_insn (operands[0], spu_gen_subreg (V2DImode, temp2));
3433 (define_expand "cmgt_v2df"
3434 [(set (match_operand:V2DI 0 "spu_reg_operand" "=r")
3435 (gt:V2DI (abs:V2DF (match_operand:V2DF 1 "spu_reg_operand" "r"))
3436 (abs:V2DF (match_operand:V2DF 2 "spu_reg_operand" "r"))))]
3439 if (spu_arch == PROCESSOR_CELL)
3441 rtx ra = spu_gen_subreg (V4SImode, operands[1]);
3442 rtx rb = spu_gen_subreg (V4SImode, operands[2]);
3443 rtx temp = gen_reg_rtx (TImode);
3444 rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
3445 rtx temp2 = gen_reg_rtx (V4SImode);
3446 rtx hi_inf = gen_reg_rtx (V4SImode);
3447 rtx a_nan = gen_reg_rtx (V4SImode);
3448 rtx b_nan = gen_reg_rtx (V4SImode);
3449 rtx a_abs = gen_reg_rtx (V4SImode);
3450 rtx b_abs = gen_reg_rtx (V4SImode);
3451 rtx gt_hi = gen_reg_rtx (V4SImode);
3452 rtx gt_lo = gen_reg_rtx (V4SImode);
3453 rtx sign_mask = gen_reg_rtx (V4SImode);
3454 rtx nan_mask = gen_reg_rtx (V4SImode);
3455 rtx hi_promote = gen_reg_rtx (TImode);
3456 rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF,
3457 0x7FFFFFFF, 0xFFFFFFFF);
3458 emit_move_insn (sign_mask, pat);
3459 pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0,
3461 emit_move_insn (nan_mask, pat);
3462 pat = spu_const_from_ints (TImode, 0x00010203, 0x00010203,
3463 0x08090A0B, 0x08090A0B);
3464 emit_move_insn (hi_promote, pat);
3466 emit_insn (gen_andv4si3 (a_abs, ra, sign_mask));
3467 emit_insn (gen_ceq_v4si (hi_inf, a_abs, nan_mask));
3468 emit_insn (gen_clgt_v4si (a_nan, a_abs, nan_mask));
3469 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, a_nan),
3471 emit_insn (gen_andv4si3 (temp2, temp_v4si, hi_inf));
3472 emit_insn (gen_iorv4si3 (a_nan, a_nan, temp2));
3473 emit_insn (gen_shufb (a_nan, a_nan, a_nan, hi_promote));
3474 emit_insn (gen_andv4si3 (b_abs, rb, sign_mask));
3475 emit_insn (gen_ceq_v4si (hi_inf, b_abs, nan_mask));
3476 emit_insn (gen_clgt_v4si (b_nan, b_abs, nan_mask));
3477 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, b_nan),
3479 emit_insn (gen_andv4si3 (temp2, temp_v4si, hi_inf));
3480 emit_insn (gen_iorv4si3 (b_nan, b_nan, temp2));
3481 emit_insn (gen_shufb (b_nan, b_nan, b_nan, hi_promote));
3482 emit_insn (gen_iorv4si3 (a_nan, a_nan, b_nan));
3484 emit_insn (gen_clgt_v4si (gt_hi, a_abs, b_abs));
3485 emit_insn (gen_clgt_v4si (gt_lo, a_abs, b_abs));
3486 emit_insn (gen_ceq_v4si (temp2, a_abs, b_abs));
3487 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, gt_lo),
3489 emit_insn (gen_andv4si3 (temp2, temp2, temp_v4si));
3490 emit_insn (gen_iorv4si3 (temp2, gt_hi, temp2));
3491 emit_insn (gen_shufb (temp2, temp2, temp2, hi_promote));
3492 emit_insn (gen_andc_v4si (temp2, temp2, a_nan));
3493 emit_move_insn (operands[0], spu_gen_subreg (V2DImode, temp2));
3501 (define_insn "clgt_<mode>"
3502 [(set (match_operand:VQHSI 0 "spu_reg_operand" "=r,r")
3503 (gtu:VQHSI (match_operand:VQHSI 1 "spu_reg_operand" "r,r")
3504 (match_operand:VQHSI 2 "spu_arith_operand" "r,B")))]
3508 clgt<bh>i\t%0,%1,%2")
3510 (define_insn_and_split "clgt_di"
3511 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3512 (gtu:SI (match_operand:DI 1 "spu_reg_operand" "r")
3513 (match_operand:DI 2 "spu_reg_operand" "r")))
3514 (clobber (match_scratch:V4SI 3 "=&r"))
3515 (clobber (match_scratch:V4SI 4 "=&r"))
3516 (clobber (match_scratch:V4SI 5 "=&r"))]
3520 [(set (match_dup:SI 0)
3521 (gtu:SI (match_dup:DI 1)
3524 rtx op0 = gen_rtx_REG (V4SImode, REGNO (operands[0]));
3525 rtx op1 = gen_rtx_REG (V4SImode, REGNO (operands[1]));
3526 rtx op2 = gen_rtx_REG (V4SImode, REGNO (operands[2]));
3527 rtx op3 = operands[3];
3528 rtx op4 = operands[4];
3529 rtx op5 = operands[5];
3530 rtx op5d = gen_rtx_REG (V2DImode, REGNO (operands[5]));
3531 emit_insn (gen_clgt_v4si (op3, op1, op2));
3532 emit_insn (gen_ceq_v4si (op4, op1, op2));
3533 emit_insn (gen_spu_xswd (op5d, op3));
3534 emit_insn (gen_selb (op0, op3, op5, op4));
3538 (define_insn "clgt_ti"
3539 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3540 (gtu:SI (match_operand:TI 1 "spu_reg_operand" "r")
3541 (match_operand:TI 2 "spu_reg_operand" "r")))
3542 (clobber (match_scratch:V4SI 3 "=&r"))
3543 (clobber (match_scratch:V4SI 4 "=&r"))]
3548 selb\t%0,%4,%0,%3\;\
3550 selb\t%0,%4,%0,%3\;\
3553 [(set_attr "type" "multi0")
3554 (set_attr "length" "32")])
3558 (define_insn "dftsv_celledp"
3559 [(set (match_operand:V2DI 0 "spu_reg_operand" "=r")
3560 (unspec:V2DI [(match_operand:V2DF 1 "spu_reg_operand" "r")
3561 (match_operand:SI 2 "const_int_operand" "i")]
3563 "spu_arch == PROCESSOR_CELLEDP"
3565 [(set_attr "type" "fpd")])
3567 (define_expand "dftsv"
3568 [(set (match_operand:V2DI 0 "spu_reg_operand" "=r")
3569 (unspec:V2DI [(match_operand:V2DF 1 "spu_reg_operand" "r")
3570 (match_operand:SI 2 "const_int_operand" "i")]
3574 if (spu_arch == PROCESSOR_CELL)
3576 rtx result = gen_reg_rtx (V4SImode);
3577 emit_move_insn (result, CONST0_RTX (V4SImode));
3579 if (INTVAL (operands[2]))
3581 rtx ra = spu_gen_subreg (V4SImode, operands[1]);
3582 rtx abs = gen_reg_rtx (V4SImode);
3583 rtx sign = gen_reg_rtx (V4SImode);
3584 rtx temp = gen_reg_rtx (TImode);
3585 rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
3586 rtx temp2 = gen_reg_rtx (V4SImode);
3587 rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF,
3588 0x7FFFFFFF, 0xFFFFFFFF);
3589 rtx sign_mask = gen_reg_rtx (V4SImode);
3590 rtx hi_promote = gen_reg_rtx (TImode);
3591 emit_move_insn (sign_mask, pat);
3592 pat = spu_const_from_ints (TImode, 0x00010203, 0x00010203,
3593 0x08090A0B, 0x08090A0B);
3594 emit_move_insn (hi_promote, pat);
3596 emit_insn (gen_vashrv4si3 (sign, ra, spu_const (V4SImode, 31)));
3597 emit_insn (gen_shufb (sign, sign, sign, hi_promote));
3598 emit_insn (gen_andv4si3 (abs, ra, sign_mask));
3600 /* NaN or +inf or -inf */
3601 if (INTVAL (operands[2]) & 0x70)
3603 rtx nan_mask = gen_reg_rtx (V4SImode);
3604 rtx isinf = gen_reg_rtx (V4SImode);
3605 pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0,
3607 emit_move_insn (nan_mask, pat);
3608 emit_insn (gen_ceq_v4si (isinf, abs, nan_mask));
3611 if (INTVAL (operands[2]) & 0x40)
3613 rtx isnan = gen_reg_rtx (V4SImode);
3614 emit_insn (gen_clgt_v4si (isnan, abs, nan_mask));
3615 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, isnan),
3617 emit_insn (gen_andv4si3 (temp2, temp_v4si, isinf));
3618 emit_insn (gen_iorv4si3 (isnan, isnan, temp2));
3619 emit_insn (gen_shufb (isnan, isnan, isnan, hi_promote));
3620 emit_insn (gen_iorv4si3 (result, result, isnan));
3623 if (INTVAL (operands[2]) & 0x30)
3625 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, isinf),
3627 emit_insn (gen_andv4si3 (isinf, isinf, temp_v4si));
3628 emit_insn (gen_shufb (isinf, isinf, isinf, hi_promote));
3631 if (INTVAL (operands[2]) & 0x20)
3633 emit_insn (gen_andc_v4si (temp2, isinf, sign));
3634 emit_insn (gen_iorv4si3 (result, result, temp2));
3637 if (INTVAL (operands[2]) & 0x10)
3639 emit_insn (gen_andv4si3 (temp2, isinf, sign));
3640 emit_insn (gen_iorv4si3 (result, result, temp2));
3646 if (INTVAL (operands[2]) & 0xF)
3648 rtx iszero = gen_reg_rtx (V4SImode);
3649 emit_insn (gen_ceq_v4si (iszero, abs, CONST0_RTX (V4SImode)));
3650 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, iszero),
3652 emit_insn (gen_andv4si3 (iszero, iszero, temp_v4si));
3655 if (INTVAL (operands[2]) & 0x3)
3657 rtx isdenorm = gen_reg_rtx (V4SImode);
3658 rtx denorm_mask = gen_reg_rtx (V4SImode);
3659 emit_move_insn (denorm_mask, spu_const (V4SImode, 0xFFFFF));
3660 emit_insn (gen_clgt_v4si (isdenorm, abs, denorm_mask));
3661 emit_insn (gen_nor_v4si (isdenorm, isdenorm, iszero));
3662 emit_insn (gen_shufb (isdenorm, isdenorm,
3663 isdenorm, hi_promote));
3665 if (INTVAL (operands[2]) & 0x2)
3667 emit_insn (gen_andc_v4si (temp2, isdenorm, sign));
3668 emit_insn (gen_iorv4si3 (result, result, temp2));
3671 if (INTVAL (operands[2]) & 0x1)
3673 emit_insn (gen_andv4si3 (temp2, isdenorm, sign));
3674 emit_insn (gen_iorv4si3 (result, result, temp2));
3679 if (INTVAL (operands[2]) & 0xC)
3681 emit_insn (gen_shufb (iszero, iszero, iszero, hi_promote));
3683 if (INTVAL (operands[2]) & 0x8)
3685 emit_insn (gen_andc_v4si (temp2, iszero, sign));
3686 emit_insn (gen_iorv4si3 (result, result, temp2));
3689 if (INTVAL (operands[2]) & 0x4)
3691 emit_insn (gen_andv4si3 (temp2, iszero, sign));
3692 emit_insn (gen_iorv4si3 (result, result, temp2));
3697 emit_move_insn (operands[0], spu_gen_subreg (V2DImode, result));
3707 (if_then_else (match_operator 1 "branch_comparison_operator"
3709 "spu_reg_operand" "r")
3711 (label_ref (match_operand 0 "" ""))
3715 [(set_attr "type" "br")])
3719 (if_then_else (match_operator 0 "branch_comparison_operator"
3721 "spu_reg_operand" "r")
3727 [(set_attr "type" "br")])
3731 (if_then_else (match_operator 1 "branch_comparison_operator"
3733 "spu_reg_operand" "r")
3736 (label_ref (match_operand 0 "" ""))))]
3739 [(set_attr "type" "br")])
3743 (if_then_else (match_operator 0 "branch_comparison_operator"
3745 "spu_reg_operand" "r")
3751 [(set_attr "type" "br")])
3754 ;; vector conditional compare patterns
3755 (define_expand "vcond<mode>"
3756 [(set (match_operand:VCMP 0 "spu_reg_operand" "=r")
3758 (match_operator 3 "comparison_operator"
3759 [(match_operand:VCMP 4 "spu_reg_operand" "r")
3760 (match_operand:VCMP 5 "spu_reg_operand" "r")])
3761 (match_operand:VCMP 1 "spu_reg_operand" "r")
3762 (match_operand:VCMP 2 "spu_reg_operand" "r")))]
3765 if (spu_emit_vector_cond_expr (operands[0], operands[1], operands[2],
3766 operands[3], operands[4], operands[5]))
3772 (define_expand "vcondu<mode>"
3773 [(set (match_operand:VCMPU 0 "spu_reg_operand" "=r")
3775 (match_operator 3 "comparison_operator"
3776 [(match_operand:VCMPU 4 "spu_reg_operand" "r")
3777 (match_operand:VCMPU 5 "spu_reg_operand" "r")])
3778 (match_operand:VCMPU 1 "spu_reg_operand" "r")
3779 (match_operand:VCMPU 2 "spu_reg_operand" "r")))]
3782 if (spu_emit_vector_cond_expr (operands[0], operands[1], operands[2],
3783 operands[3], operands[4], operands[5]))
3790 ;; branch on condition
3792 (define_expand "cbranch<mode>4"
3793 [(use (match_operator 0 "ordered_comparison_operator"
3794 [(match_operand:VQHSI 1 "spu_reg_operand" "")
3795 (match_operand:VQHSI 2 "spu_nonmem_operand" "")]))
3796 (use (match_operand 3 ""))]
3798 { spu_emit_branch_or_set (0, operands[0], operands); DONE; })
3800 (define_expand "cbranch<mode>4"
3801 [(use (match_operator 0 "ordered_comparison_operator"
3802 [(match_operand:DTI 1 "spu_reg_operand" "")
3803 (match_operand:DTI 2 "spu_reg_operand" "")]))
3804 (use (match_operand 3 ""))]
3806 { spu_emit_branch_or_set (0, operands[0], operands); DONE; })
3808 (define_expand "cbranch<mode>4"
3809 [(use (match_operator 0 "ordered_comparison_operator"
3810 [(match_operand:VSF 1 "spu_reg_operand" "")
3811 (match_operand:VSF 2 "spu_reg_operand" "")]))
3812 (use (match_operand 3 ""))]
3814 { spu_emit_branch_or_set (0, operands[0], operands); DONE; })
3816 (define_expand "cbranchdf4"
3817 [(use (match_operator 0 "ordered_comparison_operator"
3818 [(match_operand:DF 1 "spu_reg_operand" "")
3819 (match_operand:DF 2 "spu_reg_operand" "")]))
3820 (use (match_operand 3 ""))]
3822 { spu_emit_branch_or_set (0, operands[0], operands); DONE; })
3827 (define_expand "cstore<mode>4"
3828 [(use (match_operator 1 "ordered_comparison_operator"
3829 [(match_operand:VQHSI 2 "spu_reg_operand" "")
3830 (match_operand:VQHSI 3 "spu_nonmem_operand" "")]))
3831 (clobber (match_operand:SI 0 "spu_reg_operand"))]
3833 { spu_emit_branch_or_set (1, operands[1], operands); DONE; })
3835 (define_expand "cstore<mode>4"
3836 [(use (match_operator 1 "ordered_comparison_operator"
3837 [(match_operand:DTI 2 "spu_reg_operand" "")
3838 (match_operand:DTI 3 "spu_reg_operand" "")]))
3839 (clobber (match_operand:SI 0 "spu_reg_operand"))]
3841 { spu_emit_branch_or_set (1, operands[1], operands); DONE; })
3843 (define_expand "cstore<mode>4"
3844 [(use (match_operator 1 "ordered_comparison_operator"
3845 [(match_operand:VSF 2 "spu_reg_operand" "")
3846 (match_operand:VSF 3 "spu_reg_operand" "")]))
3847 (clobber (match_operand:SI 0 "spu_reg_operand"))]
3849 { spu_emit_branch_or_set (1, operands[1], operands); DONE; })
3851 (define_expand "cstoredf4"
3852 [(use (match_operator 1 "ordered_comparison_operator"
3853 [(match_operand:DF 2 "spu_reg_operand" "")
3854 (match_operand:DF 3 "spu_reg_operand" "")]))
3855 (clobber (match_operand:SI 0 "spu_reg_operand"))]
3857 { spu_emit_branch_or_set (1, operands[1], operands); DONE; })
3862 ;; Define this first one so HAVE_conditional_move is defined.
3863 (define_insn "movcc_dummy"
3864 [(set (match_operand 0 "" "")
3865 (if_then_else (match_operand 1 "" "")
3866 (match_operand 2 "" "")
3867 (match_operand 3 "" "")))]
3871 (define_expand "mov<mode>cc"
3872 [(set (match_operand:ALL 0 "spu_reg_operand" "")
3873 (if_then_else:ALL (match_operand 1 "ordered_comparison_operator" "")
3874 (match_operand:ALL 2 "spu_reg_operand" "")
3875 (match_operand:ALL 3 "spu_reg_operand" "")))]
3878 spu_emit_branch_or_set(2, operands[1], operands);
3882 ;; This pattern is used when the result of a compare is not large
3883 ;; enough to use in a selb when expanding conditional moves.
3884 (define_expand "extend_compare"
3885 [(set (match_operand 0 "spu_reg_operand" "=r")
3886 (unspec [(match_operand 1 "spu_reg_operand" "r")] UNSPEC_EXTEND_CMP))]
3889 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3890 gen_rtx_UNSPEC (GET_MODE (operands[0]),
3891 gen_rtvec (1, operands[1]),
3892 UNSPEC_EXTEND_CMP)));
3896 (define_insn "extend_compare<mode>"
3897 [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
3898 (unspec:ALL [(match_operand 1 "spu_reg_operand" "r")] UNSPEC_EXTEND_CMP))]
3901 [(set_attr "type" "shuf")])
3906 ;; operand 0 is index
3907 ;; operand 1 is the minimum bound
3908 ;; operand 2 is the maximum bound - minimum bound + 1
3909 ;; operand 3 is CODE_LABEL for the table;
3910 ;; operand 4 is the CODE_LABEL to go to if index out of range.
3911 (define_expand "casesi"
3912 [(match_operand:SI 0 "spu_reg_operand" "")
3913 (match_operand:SI 1 "immediate_operand" "")
3914 (match_operand:SI 2 "immediate_operand" "")
3915 (match_operand 3 "" "")
3916 (match_operand 4 "" "")]
3919 rtx table = gen_reg_rtx (SImode);
3920 rtx index = gen_reg_rtx (SImode);
3921 rtx sindex = gen_reg_rtx (SImode);
3922 rtx addr = gen_reg_rtx (Pmode);
3924 emit_move_insn (table, gen_rtx_LABEL_REF (SImode, operands[3]));
3926 emit_insn (gen_subsi3(index, operands[0], force_reg(SImode, operands[1])));
3927 emit_insn (gen_ashlsi3(sindex, index, GEN_INT (2)));
3928 emit_move_insn (addr, gen_rtx_MEM (SImode,
3929 gen_rtx_PLUS (SImode, table, sindex)));
3931 emit_insn (gen_addsi3 (addr, addr, table));
3933 emit_cmp_and_jump_insns (index, operands[2], GTU, NULL_RTX, SImode, 1, operands[4]);
3934 emit_jump_insn (gen_tablejump (addr, operands[3]));
3938 (define_insn "tablejump"
3939 [(set (pc) (match_operand:SI 0 "spu_reg_operand" "r"))
3940 (use (label_ref (match_operand 1 "" "")))]
3943 [(set_attr "type" "br")])
3948 ;; Note that operand 1 is total size of args, in bytes,
3949 ;; and what the call insn wants is the number of words.
3950 (define_expand "sibcall"
3952 [(call (match_operand:QI 0 "call_operand" "")
3953 (match_operand:QI 1 "" ""))
3957 if (! call_operand (operands[0], QImode))
3958 XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
3961 (define_insn "_sibcall"
3963 [(call (match_operand:QI 0 "call_operand" "R,S")
3964 (match_operand:QI 1 "" "i,i"))
3966 "SIBLING_CALL_P(insn)"
3970 [(set_attr "type" "br,br")])
3972 (define_expand "sibcall_value"
3974 [(set (match_operand 0 "" "")
3975 (call (match_operand:QI 1 "call_operand" "")
3976 (match_operand:QI 2 "" "")))
3980 if (! call_operand (operands[1], QImode))
3981 XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
3984 (define_insn "_sibcall_value"
3986 [(set (match_operand 0 "" "")
3987 (call (match_operand:QI 1 "call_operand" "R,S")
3988 (match_operand:QI 2 "" "i,i")))
3990 "SIBLING_CALL_P(insn)"
3994 [(set_attr "type" "br,br")])
3996 ;; Note that operand 1 is total size of args, in bytes,
3997 ;; and what the call insn wants is the number of words.
3998 (define_expand "call"
4000 [(call (match_operand:QI 0 "call_operand" "")
4001 (match_operand:QI 1 "" ""))
4002 (clobber (reg:SI 0))
4003 (clobber (reg:SI 130))])]
4006 if (! call_operand (operands[0], QImode))
4007 XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
4010 (define_insn "_call"
4012 [(call (match_operand:QI 0 "call_operand" "R,S,T")
4013 (match_operand:QI 1 "" "i,i,i"))
4014 (clobber (reg:SI 0))
4015 (clobber (reg:SI 130))])]
4021 [(set_attr "type" "br")])
4023 (define_expand "call_value"
4025 [(set (match_operand 0 "" "")
4026 (call (match_operand:QI 1 "call_operand" "")
4027 (match_operand:QI 2 "" "")))
4028 (clobber (reg:SI 0))
4029 (clobber (reg:SI 130))])]
4032 if (! call_operand (operands[1], QImode))
4033 XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
4036 (define_insn "_call_value"
4038 [(set (match_operand 0 "" "")
4039 (call (match_operand:QI 1 "call_operand" "R,S,T")
4040 (match_operand:QI 2 "" "i,i,i")))
4041 (clobber (reg:SI 0))
4042 (clobber (reg:SI 130))])]
4048 [(set_attr "type" "br")])
4050 (define_expand "untyped_call"
4051 [(parallel [(call (match_operand 0 "" "")
4053 (match_operand 1 "" "")
4054 (match_operand 2 "" "")])]
4058 rtx reg = gen_rtx_REG (TImode, 3);
4060 /* We need to use call_value so the return value registers don't get
4062 emit_call_insn (gen_call_value (reg, operands[0], const0_rtx));
4064 for (i = 0; i < XVECLEN (operands[2], 0); i++)
4066 rtx set = XVECEXP (operands[2], 0, i);
4067 emit_move_insn (SET_DEST (set), SET_SRC (set));
4070 /* The optimizer does not know that the call sets the function value
4071 registers we stored in the result block. We avoid problems by
4072 claiming that all hard registers are used and clobbered at this
4074 emit_insn (gen_blockage ());
4080 ;; Patterns used for splitting and combining.
4083 ;; Function prologue and epilogue.
4085 (define_expand "prologue"
4088 { spu_expand_prologue (); DONE; })
4090 ;; "blockage" is only emited in epilogue. This is what it took to
4091 ;; make "basic block reordering" work with the insns sequence
4092 ;; generated by the spu_expand_epilogue (taken from mips.md)
4094 (define_insn "blockage"
4095 [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
4098 [(set_attr "type" "convert")
4099 (set_attr "length" "0")])
4101 (define_expand "epilogue"
4104 { spu_expand_epilogue (false); DONE; })
4106 (define_expand "sibcall_epilogue"
4109 { spu_expand_epilogue (true); DONE; })
4112 ;; stack manipulations
4114 ;; An insn to allocate new stack space for dynamic use (e.g., alloca).
4115 ;; We move the back-chain and decrement the stack pointer.
4116 (define_expand "allocate_stack"
4117 [(set (match_operand 0 "spu_reg_operand" "")
4118 (minus (reg 1) (match_operand 1 "spu_nonmem_operand" "")))
4120 (minus (reg 1) (match_dup 1)))]
4122 "spu_allocate_stack (operands[0], operands[1]); DONE;")
4124 ;; These patterns say how to save and restore the stack pointer. We need not
4125 ;; save the stack pointer at function level since we are careful to preserve
4129 ;; At block level the stack pointer is saved and restored, so that the
4130 ;; stack space allocated within a block is deallocated when leaving
4131 ;; block scope. By default, according to the SPU ABI, the stack
4132 ;; pointer and available stack size are saved in a register. Upon
4133 ;; restoration, the stack pointer is simply copied back, and the
4134 ;; current available stack size is calculated against the restored
4137 ;; For nonlocal gotos, we must save the stack pointer and its
4138 ;; backchain and restore both. Note that in the nonlocal case, the
4139 ;; save area is a memory location.
4141 (define_expand "save_stack_function"
4142 [(match_operand 0 "general_operand" "")
4143 (match_operand 1 "general_operand" "")]
4147 (define_expand "restore_stack_function"
4148 [(match_operand 0 "general_operand" "")
4149 (match_operand 1 "general_operand" "")]
4153 (define_expand "restore_stack_block"
4154 [(match_operand 0 "spu_reg_operand" "")
4155 (match_operand 1 "memory_operand" "")]
4159 spu_restore_stack_block (operands[0], operands[1]);
4163 (define_expand "save_stack_nonlocal"
4164 [(match_operand 0 "memory_operand" "")
4165 (match_operand 1 "spu_reg_operand" "")]
4169 rtx temp = gen_reg_rtx (Pmode);
4171 /* Copy the backchain to the first word, sp to the second. We need to
4172 save the back chain because __builtin_apply appears to clobber it. */
4173 emit_move_insn (temp, gen_rtx_MEM (Pmode, operands[1]));
4174 emit_move_insn (adjust_address_nv (operands[0], SImode, 0), temp);
4175 emit_move_insn (adjust_address_nv (operands[0], SImode, 4), operands[1]);
4179 (define_expand "restore_stack_nonlocal"
4180 [(match_operand 0 "spu_reg_operand" "")
4181 (match_operand 1 "memory_operand" "")]
4185 spu_restore_stack_nonlocal(operands[0], operands[1]);
4192 ;; Vector initialization
4193 (define_expand "vec_init<mode>"
4194 [(match_operand:V 0 "register_operand" "")
4195 (match_operand 1 "" "")]
4198 spu_expand_vector_init (operands[0], operands[1]);
4202 (define_expand "vec_set<mode>"
4203 [(use (match_operand:SI 2 "spu_nonmem_operand" ""))
4204 (set (match_dup:TI 3)
4205 (unspec:TI [(match_dup:SI 4)
4207 (match_dup:SI 6)] UNSPEC_CPAT))
4208 (set (match_operand:V 0 "spu_reg_operand" "")
4209 (unspec:V [(match_operand:<inner> 1 "spu_reg_operand" "")
4211 (match_dup:TI 3)] UNSPEC_SHUFB))]
4214 HOST_WIDE_INT size = GET_MODE_SIZE (<inner>mode);
4215 rtx offset = GEN_INT (INTVAL (operands[2]) * size);
4216 operands[3] = gen_reg_rtx (TImode);
4217 operands[4] = stack_pointer_rtx;
4218 operands[5] = offset;
4219 operands[6] = GEN_INT (size);
4222 (define_expand "vec_extract<mode>"
4223 [(set (match_operand:<inner> 0 "spu_reg_operand" "=r")
4224 (vec_select:<inner> (match_operand:V 1 "spu_reg_operand" "r")
4225 (parallel [(match_operand 2 "const_int_operand" "i")])))]
4228 if ((INTVAL (operands[2]) * <vmult> + <voff>) % 16 == 0)
4230 emit_insn (gen_spu_convert (operands[0], operands[1]));
4235 (define_insn "_vec_extract<mode>"
4236 [(set (match_operand:<inner> 0 "spu_reg_operand" "=r")
4237 (vec_select:<inner> (match_operand:V 1 "spu_reg_operand" "r")
4238 (parallel [(match_operand 2 "const_int_operand" "i")])))]
4240 "rotqbyi\t%0,%1,(%2*<vmult>+<voff>)%%16"
4241 [(set_attr "type" "shuf")])
4243 (define_insn "_vec_extractv8hi_ze"
4244 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
4245 (zero_extend:SI (vec_select:HI (match_operand:V8HI 1 "spu_reg_operand" "r")
4246 (parallel [(const_int 0)]))))]
4248 "rotqmbyi\t%0,%1,-2"
4249 [(set_attr "type" "shuf")])
4254 (define_expand "shufb"
4255 [(set (match_operand 0 "spu_reg_operand" "")
4256 (unspec [(match_operand 1 "spu_reg_operand" "")
4257 (match_operand 2 "spu_reg_operand" "")
4258 (match_operand:TI 3 "spu_reg_operand" "")] UNSPEC_SHUFB))]
4261 rtx s = gen__shufb (operands[0], operands[1], operands[2], operands[3]);
4262 PUT_MODE (SET_SRC (s), GET_MODE (operands[0]));
4267 (define_insn "_shufb"
4268 [(set (match_operand 0 "spu_reg_operand" "=r")
4269 (unspec [(match_operand 1 "spu_reg_operand" "r")
4270 (match_operand 2 "spu_reg_operand" "r")
4271 (match_operand:TI 3 "spu_reg_operand" "r")] UNSPEC_SHUFB))]
4273 "shufb\t%0,%1,%2,%3"
4274 [(set_attr "type" "shuf")])
4277 [(unspec_volatile [(const_int 0)] UNSPEC_NOP)]
4280 [(set_attr "type" "nop")])
4283 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "K")] UNSPEC_NOP)]
4286 [(set_attr "type" "nop")])
4289 [(unspec_volatile [(const_int 0)] UNSPEC_LNOP)]
4292 [(set_attr "type" "lnop")])
4294 ;; The operand is so we know why we generated this hbrp.
4295 ;; We clobber mem to make sure it isn't moved over any
4296 ;; loads, stores or calls while scheduling.
4297 (define_insn "iprefetch"
4298 [(unspec [(match_operand:SI 0 "const_int_operand" "n")] UNSPEC_IPREFETCH)
4299 (clobber (mem:BLK (scratch)))]
4302 [(set_attr "type" "iprefetch")])
4304 ;; A non-volatile version so it gets scheduled
4305 (define_insn "nopn_nv"
4306 [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_NOP)]
4309 [(set_attr "type" "nop")])
4313 (unspec:SI [(match_operand:SI 0 "immediate_operand" "i,i,i")
4314 (match_operand:SI 1 "nonmemory_operand" "r,s,i")] UNSPEC_HBR))
4315 (unspec [(const_int 0)] UNSPEC_HBR)]
4321 [(set_attr "type" "hbr")])
4324 [(unspec_volatile [(const_int 0)] UNSPEC_SYNC)
4325 (clobber (mem:BLK (scratch)))]
4328 [(set_attr "type" "br")])
4330 (define_insn "syncc"
4331 [(unspec_volatile [(const_int 1)] UNSPEC_SYNC)
4332 (clobber (mem:BLK (scratch)))]
4335 [(set_attr "type" "br")])
4337 (define_insn "dsync"
4338 [(unspec_volatile [(const_int 2)] UNSPEC_SYNC)
4339 (clobber (mem:BLK (scratch)))]
4342 [(set_attr "type" "br")])
4346 ;; Define the subtract-one-and-jump insns so loop.c
4347 ;; knows what to generate.
4348 (define_expand "doloop_end"
4349 [(use (match_operand 0 "" "")) ; loop pseudo
4350 (use (match_operand 1 "" "")) ; iterations; zero if unknown
4351 (use (match_operand 2 "" "")) ; max iterations
4352 (use (match_operand 3 "" "")) ; loop level
4353 (use (match_operand 4 "" ""))] ; label
4357 /* Currently SMS relies on the do-loop pattern to recognize loops
4358 where (1) the control part comprises of all insns defining and/or
4359 using a certain 'count' register and (2) the loop count can be
4360 adjusted by modifying this register prior to the loop.
4361 . ??? The possible introduction of a new block to initialize the
4362 new IV can potentially effects branch optimizations. */
4363 if (optimize > 0 && flag_modulo_sched)
4369 /* Only use this on innermost loops. */
4370 if (INTVAL (operands[3]) > 1)
4372 if (GET_MODE (operands[0]) != SImode)
4376 emit_move_insn (s0, gen_rtx_PLUS (SImode, s0, GEN_INT (-1)));
4377 bcomp = gen_rtx_NE(SImode, s0, const0_rtx);
4378 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands [4]);
4379 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
4380 gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp,
4388 ;; convert between any two modes, avoiding any GCC assumptions
4389 (define_expand "spu_convert"
4390 [(set (match_operand 0 "spu_reg_operand" "")
4391 (unspec [(match_operand 1 "spu_reg_operand" "")] UNSPEC_CONVERT))]
4394 rtx c = gen__spu_convert (operands[0], operands[1]);
4395 PUT_MODE (SET_SRC (c), GET_MODE (operands[0]));
4400 (define_insn_and_split "_spu_convert"
4401 [(set (match_operand 0 "spu_reg_operand" "=r")
4402 (unspec [(match_operand 1 "spu_reg_operand" "0")] UNSPEC_CONVERT))]
4408 spu_split_convert (operands);
4411 [(set_attr "type" "convert")
4412 (set_attr "length" "0")])
4416 (include "spu-builtins.md")
4419 (define_expand "smaxv4sf3"
4420 [(set (match_operand:V4SF 0 "register_operand" "=r")
4421 (smax:V4SF (match_operand:V4SF 1 "register_operand" "r")
4422 (match_operand:V4SF 2 "register_operand" "r")))]
4426 rtx mask = gen_reg_rtx (V4SImode);
4428 emit_insn (gen_cgt_v4sf (mask, operands[1], operands[2]));
4429 emit_insn (gen_selb (operands[0], operands[2], operands[1], mask));
4433 (define_expand "sminv4sf3"
4434 [(set (match_operand:V4SF 0 "register_operand" "=r")
4435 (smin:V4SF (match_operand:V4SF 1 "register_operand" "r")
4436 (match_operand:V4SF 2 "register_operand" "r")))]
4440 rtx mask = gen_reg_rtx (V4SImode);
4442 emit_insn (gen_cgt_v4sf (mask, operands[1], operands[2]));
4443 emit_insn (gen_selb (operands[0], operands[1], operands[2], mask));
4447 (define_expand "smaxv2df3"
4448 [(set (match_operand:V2DF 0 "register_operand" "=r")
4449 (smax:V2DF (match_operand:V2DF 1 "register_operand" "r")
4450 (match_operand:V2DF 2 "register_operand" "r")))]
4454 rtx mask = gen_reg_rtx (V2DImode);
4455 emit_insn (gen_cgt_v2df (mask, operands[1], operands[2]));
4456 emit_insn (gen_selb (operands[0], operands[2], operands[1],
4457 spu_gen_subreg (V4SImode, mask)));
4461 (define_expand "sminv2df3"
4462 [(set (match_operand:V2DF 0 "register_operand" "=r")
4463 (smin:V2DF (match_operand:V2DF 1 "register_operand" "r")
4464 (match_operand:V2DF 2 "register_operand" "r")))]
4468 rtx mask = gen_reg_rtx (V2DImode);
4469 emit_insn (gen_cgt_v2df (mask, operands[1], operands[2]));
4470 emit_insn (gen_selb (operands[0], operands[1], operands[2],
4471 spu_gen_subreg (V4SImode, mask)));
4475 (define_expand "vec_widen_umult_hi_v8hi"
4476 [(set (match_operand:V4SI 0 "register_operand" "=r")
4480 (match_operand:V8HI 1 "register_operand" "r")
4481 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)])))
4484 (match_operand:V8HI 2 "register_operand" "r")
4485 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)])))))]
4489 rtx ve = gen_reg_rtx (V4SImode);
4490 rtx vo = gen_reg_rtx (V4SImode);
4491 rtx mask = gen_reg_rtx (TImode);
4492 unsigned char arr[16] = {
4493 0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13,
4494 0x04, 0x05, 0x06, 0x07, 0x14, 0x15, 0x16, 0x17};
4496 emit_move_insn (mask, array_to_constant (TImode, arr));
4497 emit_insn (gen_spu_mpyhhu (ve, operands[1], operands[2]));
4498 emit_insn (gen_spu_mpyu (vo, operands[1], operands[2]));
4499 emit_insn (gen_shufb (operands[0], ve, vo, mask));
4503 (define_expand "vec_widen_umult_lo_v8hi"
4504 [(set (match_operand:V4SI 0 "register_operand" "=r")
4508 (match_operand:V8HI 1 "register_operand" "r")
4509 (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)])))
4512 (match_operand:V8HI 2 "register_operand" "r")
4513 (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)])))))]
4517 rtx ve = gen_reg_rtx (V4SImode);
4518 rtx vo = gen_reg_rtx (V4SImode);
4519 rtx mask = gen_reg_rtx (TImode);
4520 unsigned char arr[16] = {
4521 0x08, 0x09, 0x0A, 0x0B, 0x18, 0x19, 0x1A, 0x1B,
4522 0x0C, 0x0D, 0x0E, 0x0F, 0x1C, 0x1D, 0x1E, 0x1F};
4524 emit_move_insn (mask, array_to_constant (TImode, arr));
4525 emit_insn (gen_spu_mpyhhu (ve, operands[1], operands[2]));
4526 emit_insn (gen_spu_mpyu (vo, operands[1], operands[2]));
4527 emit_insn (gen_shufb (operands[0], ve, vo, mask));
4531 (define_expand "vec_widen_smult_hi_v8hi"
4532 [(set (match_operand:V4SI 0 "register_operand" "=r")
4536 (match_operand:V8HI 1 "register_operand" "r")
4537 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)])))
4540 (match_operand:V8HI 2 "register_operand" "r")
4541 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)])))))]
4545 rtx ve = gen_reg_rtx (V4SImode);
4546 rtx vo = gen_reg_rtx (V4SImode);
4547 rtx mask = gen_reg_rtx (TImode);
4548 unsigned char arr[16] = {
4549 0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13,
4550 0x04, 0x05, 0x06, 0x07, 0x14, 0x15, 0x16, 0x17};
4552 emit_move_insn (mask, array_to_constant (TImode, arr));
4553 emit_insn (gen_spu_mpyhh (ve, operands[1], operands[2]));
4554 emit_insn (gen_spu_mpy (vo, operands[1], operands[2]));
4555 emit_insn (gen_shufb (operands[0], ve, vo, mask));
4559 (define_expand "vec_widen_smult_lo_v8hi"
4560 [(set (match_operand:V4SI 0 "register_operand" "=r")
4564 (match_operand:V8HI 1 "register_operand" "r")
4565 (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)])))
4568 (match_operand:V8HI 2 "register_operand" "r")
4569 (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)])))))]
4573 rtx ve = gen_reg_rtx (V4SImode);
4574 rtx vo = gen_reg_rtx (V4SImode);
4575 rtx mask = gen_reg_rtx (TImode);
4576 unsigned char arr[16] = {
4577 0x08, 0x09, 0x0A, 0x0B, 0x18, 0x19, 0x1A, 0x1B,
4578 0x0C, 0x0D, 0x0E, 0x0F, 0x1C, 0x1D, 0x1E, 0x1F};
4580 emit_move_insn (mask, array_to_constant (TImode, arr));
4581 emit_insn (gen_spu_mpyhh (ve, operands[1], operands[2]));
4582 emit_insn (gen_spu_mpy (vo, operands[1], operands[2]));
4583 emit_insn (gen_shufb (operands[0], ve, vo, mask));
4587 (define_expand "vec_realign_load_<mode>"
4588 [(set (match_operand:ALL 0 "register_operand" "=r")
4589 (unspec:ALL [(match_operand:ALL 1 "register_operand" "r")
4590 (match_operand:ALL 2 "register_operand" "r")
4591 (match_operand:TI 3 "register_operand" "r")] UNSPEC_SPU_REALIGN_LOAD))]
4595 emit_insn (gen_shufb (operands[0], operands[1], operands[2], operands[3]));
4599 (define_expand "spu_lvsr"
4600 [(set (match_operand:V16QI 0 "register_operand" "")
4601 (unspec:V16QI [(match_operand 1 "memory_operand" "")] UNSPEC_SPU_MASK_FOR_LOAD))]
4606 rtx offset = gen_reg_rtx (V8HImode);
4607 rtx addr_bits = gen_reg_rtx (SImode);
4608 rtx addr_bits_vec = gen_reg_rtx (V8HImode);
4609 rtx splatqi = gen_reg_rtx (TImode);
4610 rtx result = gen_reg_rtx (V8HImode);
4611 unsigned char arr[16] = {
4612 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
4613 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F};
4614 unsigned char arr2[16] = {
4615 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
4616 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03};
4618 emit_move_insn (offset, array_to_constant (V8HImode, arr));
4619 emit_move_insn (splatqi, array_to_constant (TImode, arr2));
4621 gcc_assert (GET_CODE (operands[1]) == MEM);
4622 addr = force_reg (Pmode, XEXP (operands[1], 0));
4623 emit_insn (gen_andsi3 (addr_bits, addr, GEN_INT (0xF)));
4624 emit_insn (gen_shufb (addr_bits_vec, addr_bits, addr_bits, splatqi));
4626 /* offset - (addr & 0xF)
4627 It is safe to use a single sfh, because each byte of offset is > 15 and
4628 each byte of addr is <= 15. */
4629 emit_insn (gen_subv8hi3 (result, offset, addr_bits_vec));
4631 result = simplify_gen_subreg (V16QImode, result, V8HImode, 0);
4632 emit_move_insn (operands[0], result);
4637 (define_expand "vec_unpacku_hi_v8hi"
4638 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
4641 (match_operand:V8HI 1 "spu_reg_operand" "r")
4642 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)]))))]
4645 rtx mask = gen_reg_rtx (TImode);
4646 unsigned char arr[16] = {
4647 0x80, 0x80, 0x00, 0x01, 0x80, 0x80, 0x02, 0x03,
4648 0x80, 0x80, 0x04, 0x05, 0x80, 0x80, 0x06, 0x07};
4650 emit_move_insn (mask, array_to_constant (TImode, arr));
4651 emit_insn (gen_shufb (operands[0], operands[1], operands[1], mask));
4656 (define_expand "vec_unpacku_lo_v8hi"
4657 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
4660 (match_operand:V8HI 1 "spu_reg_operand" "r")
4661 (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)]))))]
4664 rtx mask = gen_reg_rtx (TImode);
4665 unsigned char arr[16] = {
4666 0x80, 0x80, 0x08, 0x09, 0x80, 0x80, 0x0A, 0x0B,
4667 0x80, 0x80, 0x0C, 0x0D, 0x80, 0x80, 0x0E, 0x0F};
4669 emit_move_insn (mask, array_to_constant (TImode, arr));
4670 emit_insn (gen_shufb (operands[0], operands[1], operands[1], mask));
4675 (define_expand "vec_unpacks_hi_v8hi"
4676 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
4679 (match_operand:V8HI 1 "spu_reg_operand" "r")
4680 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)]))))]
4683 rtx tmp1 = gen_reg_rtx (V8HImode);
4684 rtx tmp2 = gen_reg_rtx (V4SImode);
4685 rtx mask = gen_reg_rtx (TImode);
4686 unsigned char arr[16] = {
4687 0x80, 0x80, 0x00, 0x01, 0x80, 0x80, 0x02, 0x03,
4688 0x80, 0x80, 0x04, 0x05, 0x80, 0x80, 0x06, 0x07};
4690 emit_move_insn (mask, array_to_constant (TImode, arr));
4691 emit_insn (gen_shufb (tmp1, operands[1], operands[1], mask));
4692 emit_insn (gen_spu_xshw (tmp2, tmp1));
4693 emit_move_insn (operands[0], tmp2);
4698 (define_expand "vec_unpacks_lo_v8hi"
4699 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
4702 (match_operand:V8HI 1 "spu_reg_operand" "r")
4703 (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)]))))]
4706 rtx tmp1 = gen_reg_rtx (V8HImode);
4707 rtx tmp2 = gen_reg_rtx (V4SImode);
4708 rtx mask = gen_reg_rtx (TImode);
4709 unsigned char arr[16] = {
4710 0x80, 0x80, 0x08, 0x09, 0x80, 0x80, 0x0A, 0x0B,
4711 0x80, 0x80, 0x0C, 0x0D, 0x80, 0x80, 0x0E, 0x0F};
4713 emit_move_insn (mask, array_to_constant (TImode, arr));
4714 emit_insn (gen_shufb (tmp1, operands[1], operands[1], mask));
4715 emit_insn (gen_spu_xshw (tmp2, tmp1));
4716 emit_move_insn (operands[0], tmp2);
4721 (define_expand "vec_unpacku_hi_v16qi"
4722 [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
4725 (match_operand:V16QI 1 "spu_reg_operand" "r")
4726 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)
4727 (const_int 4)(const_int 5)(const_int 6)(const_int 7)]))))]
4730 rtx mask = gen_reg_rtx (TImode);
4731 unsigned char arr[16] = {
4732 0x80, 0x00, 0x80, 0x01, 0x80, 0x02, 0x80, 0x03,
4733 0x80, 0x04, 0x80, 0x05, 0x80, 0x06, 0x80, 0x07};
4735 emit_move_insn (mask, array_to_constant (TImode, arr));
4736 emit_insn (gen_shufb (operands[0], operands[1], operands[1], mask));
4741 (define_expand "vec_unpacku_lo_v16qi"
4742 [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
4745 (match_operand:V16QI 1 "spu_reg_operand" "r")
4746 (parallel [(const_int 8)(const_int 9)(const_int 10)(const_int 11)
4747 (const_int 12)(const_int 13)(const_int 14)(const_int 15)]))))]
4750 rtx mask = gen_reg_rtx (TImode);
4751 unsigned char arr[16] = {
4752 0x80, 0x08, 0x80, 0x09, 0x80, 0x0A, 0x80, 0x0B,
4753 0x80, 0x0C, 0x80, 0x0D, 0x80, 0x0E, 0x80, 0x0F};
4755 emit_move_insn (mask, array_to_constant (TImode, arr));
4756 emit_insn (gen_shufb (operands[0], operands[1], operands[1], mask));
4761 (define_expand "vec_unpacks_hi_v16qi"
4762 [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
4765 (match_operand:V16QI 1 "spu_reg_operand" "r")
4766 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)
4767 (const_int 4)(const_int 5)(const_int 6)(const_int 7)]))))]
4770 rtx tmp1 = gen_reg_rtx (V16QImode);
4771 rtx tmp2 = gen_reg_rtx (V8HImode);
4772 rtx mask = gen_reg_rtx (TImode);
4773 unsigned char arr[16] = {
4774 0x80, 0x00, 0x80, 0x01, 0x80, 0x02, 0x80, 0x03,
4775 0x80, 0x04, 0x80, 0x05, 0x80, 0x06, 0x80, 0x07};
4777 emit_move_insn (mask, array_to_constant (TImode, arr));
4778 emit_insn (gen_shufb (tmp1, operands[1], operands[1], mask));
4779 emit_insn (gen_spu_xsbh (tmp2, tmp1));
4780 emit_move_insn (operands[0], tmp2);
4785 (define_expand "vec_unpacks_lo_v16qi"
4786 [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
4789 (match_operand:V16QI 1 "spu_reg_operand" "r")
4790 (parallel [(const_int 8)(const_int 9)(const_int 10)(const_int 11)
4791 (const_int 12)(const_int 13)(const_int 14)(const_int 15)]))))]
4794 rtx tmp1 = gen_reg_rtx (V16QImode);
4795 rtx tmp2 = gen_reg_rtx (V8HImode);
4796 rtx mask = gen_reg_rtx (TImode);
4797 unsigned char arr[16] = {
4798 0x80, 0x08, 0x80, 0x09, 0x80, 0x0A, 0x80, 0x0B,
4799 0x80, 0x0C, 0x80, 0x0D, 0x80, 0x0E, 0x80, 0x0F};
4801 emit_move_insn (mask, array_to_constant (TImode, arr));
4802 emit_insn (gen_shufb (tmp1, operands[1], operands[1], mask));
4803 emit_insn (gen_spu_xsbh (tmp2, tmp1));
4804 emit_move_insn (operands[0], tmp2);
4810 (define_expand "vec_extract_evenv4si"
4811 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
4814 (match_operand:V4SI 1 "spu_reg_operand" "r")
4815 (parallel [(const_int 0)(const_int 2)]))
4817 (match_operand:V4SI 2 "spu_reg_operand" "r")
4818 (parallel [(const_int 0)(const_int 2)]))))]
4823 rtx mask = gen_reg_rtx (TImode);
4824 unsigned char arr[16] = {
4825 0x00, 0x01, 0x02, 0x03,
4826 0x08, 0x09, 0x0A, 0x0B,
4827 0x10, 0x11, 0x12, 0x13,
4828 0x18, 0x19, 0x1A, 0x1B};
4830 emit_move_insn (mask, array_to_constant (TImode, arr));
4831 emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
4836 (define_expand "vec_extract_evenv4sf"
4837 [(set (match_operand:V4SF 0 "spu_reg_operand" "=r")
4840 (match_operand:V4SF 1 "spu_reg_operand" "r")
4841 (parallel [(const_int 0)(const_int 2)]))
4843 (match_operand:V4SF 2 "spu_reg_operand" "r")
4844 (parallel [(const_int 0)(const_int 2)]))))]
4849 rtx mask = gen_reg_rtx (TImode);
4850 unsigned char arr[16] = {
4851 0x00, 0x01, 0x02, 0x03,
4852 0x08, 0x09, 0x0A, 0x0B,
4853 0x10, 0x11, 0x12, 0x13,
4854 0x18, 0x19, 0x1A, 0x1B};
4856 emit_move_insn (mask, array_to_constant (TImode, arr));
4857 emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
4861 (define_expand "vec_extract_evenv8hi"
4862 [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
4865 (match_operand:V8HI 1 "spu_reg_operand" "r")
4866 (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)]))
4868 (match_operand:V8HI 2 "spu_reg_operand" "r")
4869 (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)]))))]
4874 rtx mask = gen_reg_rtx (TImode);
4875 unsigned char arr[16] = {
4876 0x00, 0x01, 0x04, 0x05,
4877 0x08, 0x09, 0x0C, 0x0D,
4878 0x10, 0x11, 0x14, 0x15,
4879 0x18, 0x19, 0x1C, 0x1D};
4881 emit_move_insn (mask, array_to_constant (TImode, arr));
4882 emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
4886 (define_expand "vec_extract_evenv16qi"
4887 [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
4890 (match_operand:V16QI 1 "spu_reg_operand" "r")
4891 (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)
4892 (const_int 8)(const_int 10)(const_int 12)(const_int 14)]))
4894 (match_operand:V16QI 2 "spu_reg_operand" "r")
4895 (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)
4896 (const_int 8)(const_int 10)(const_int 12)(const_int 14)]))))]
4901 rtx mask = gen_reg_rtx (TImode);
4902 unsigned char arr[16] = {
4903 0x00, 0x02, 0x04, 0x06,
4904 0x08, 0x0A, 0x0C, 0x0E,
4905 0x10, 0x12, 0x14, 0x16,
4906 0x18, 0x1A, 0x1C, 0x1E};
4908 emit_move_insn (mask, array_to_constant (TImode, arr));
4909 emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
4913 (define_expand "vec_extract_oddv4si"
4914 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
4917 (match_operand:V4SI 1 "spu_reg_operand" "r")
4918 (parallel [(const_int 1)(const_int 3)]))
4920 (match_operand:V4SI 2 "spu_reg_operand" "r")
4921 (parallel [(const_int 1)(const_int 3)]))))]
4926 rtx mask = gen_reg_rtx (TImode);
4927 unsigned char arr[16] = {
4928 0x04, 0x05, 0x06, 0x07,
4929 0x0C, 0x0D, 0x0E, 0x0F,
4930 0x14, 0x15, 0x16, 0x17,
4931 0x1C, 0x1D, 0x1E, 0x1F};
4933 emit_move_insn (mask, array_to_constant (TImode, arr));
4934 emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
4938 (define_expand "vec_extract_oddv4sf"
4939 [(set (match_operand:V4SF 0 "spu_reg_operand" "=r")
4942 (match_operand:V4SF 1 "spu_reg_operand" "r")
4943 (parallel [(const_int 1)(const_int 3)]))
4945 (match_operand:V4SF 2 "spu_reg_operand" "r")
4946 (parallel [(const_int 1)(const_int 3)]))))]
4951 rtx mask = gen_reg_rtx (TImode);
4952 unsigned char arr[16] = {
4953 0x04, 0x05, 0x06, 0x07,
4954 0x0C, 0x0D, 0x0E, 0x0F,
4955 0x14, 0x15, 0x16, 0x17,
4956 0x1C, 0x1D, 0x1E, 0x1F};
4958 emit_move_insn (mask, array_to_constant (TImode, arr));
4959 emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
4963 (define_expand "vec_extract_oddv8hi"
4964 [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
4967 (match_operand:V8HI 1 "spu_reg_operand" "r")
4968 (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)]))
4970 (match_operand:V8HI 2 "spu_reg_operand" "r")
4971 (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)]))))]
4976 rtx mask = gen_reg_rtx (TImode);
4977 unsigned char arr[16] = {
4978 0x02, 0x03, 0x06, 0x07,
4979 0x0A, 0x0B, 0x0E, 0x0F,
4980 0x12, 0x13, 0x16, 0x17,
4981 0x1A, 0x1B, 0x1E, 0x1F};
4983 emit_move_insn (mask, array_to_constant (TImode, arr));
4984 emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
4988 (define_expand "vec_extract_oddv16qi"
4989 [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
4992 (match_operand:V16QI 1 "spu_reg_operand" "r")
4993 (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)
4994 (const_int 9)(const_int 11)(const_int 13)(const_int 15)]))
4996 (match_operand:V16QI 2 "spu_reg_operand" "r")
4997 (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)
4998 (const_int 9)(const_int 11)(const_int 13)(const_int 15)]))))]
5003 rtx mask = gen_reg_rtx (TImode);
5004 unsigned char arr[16] = {
5005 0x01, 0x03, 0x05, 0x07,
5006 0x09, 0x0B, 0x0D, 0x0F,
5007 0x11, 0x13, 0x15, 0x17,
5008 0x19, 0x1B, 0x1D, 0x1F};
5010 emit_move_insn (mask, array_to_constant (TImode, arr));
5011 emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5015 (define_expand "vec_interleave_highv4sf"
5016 [(set (match_operand:V4SF 0 "spu_reg_operand" "=r")
5020 (match_operand:V4SF 1 "spu_reg_operand" "r")
5021 (parallel [(const_int 0)(const_int 1)]))
5023 (match_operand:V4SF 2 "spu_reg_operand" "r")
5024 (parallel [(const_int 0)(const_int 1)])))
5025 (parallel [(const_int 0)(const_int 2)(const_int 1)(const_int 3)])))]
5030 rtx mask = gen_reg_rtx (TImode);
5031 unsigned char arr[16] = {
5032 0x00, 0x01, 0x02, 0x03,
5033 0x10, 0x11, 0x12, 0x13,
5034 0x04, 0x05, 0x06, 0x07,
5035 0x14, 0x15, 0x16, 0x17};
5037 emit_move_insn (mask, array_to_constant (TImode, arr));
5038 emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5042 (define_expand "vec_interleave_lowv4sf"
5043 [(set (match_operand:V4SF 0 "spu_reg_operand" "=r")
5047 (match_operand:V4SF 1 "spu_reg_operand" "r")
5048 (parallel [(const_int 2)(const_int 3)]))
5050 (match_operand:V4SF 2 "spu_reg_operand" "r")
5051 (parallel [(const_int 2)(const_int 3)])))
5052 (parallel [(const_int 0)(const_int 2)(const_int 1)(const_int 3)])))]
5057 rtx mask = gen_reg_rtx (TImode);
5058 unsigned char arr[16] = {
5059 0x08, 0x09, 0x0A, 0x0B,
5060 0x18, 0x19, 0x1A, 0x1B,
5061 0x0C, 0x0D, 0x0E, 0x0F,
5062 0x1C, 0x1D, 0x1E, 0x1F};
5064 emit_move_insn (mask, array_to_constant (TImode, arr));
5065 emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5069 (define_expand "vec_interleave_highv4si"
5070 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
5074 (match_operand:V4SI 1 "spu_reg_operand" "r")
5075 (parallel [(const_int 0)(const_int 1)]))
5077 (match_operand:V4SI 2 "spu_reg_operand" "r")
5078 (parallel [(const_int 0)(const_int 1)])))
5079 (parallel [(const_int 0)(const_int 2)(const_int 1)(const_int 3)])))]
5084 rtx mask = gen_reg_rtx (TImode);
5085 unsigned char arr[16] = {
5086 0x00, 0x01, 0x02, 0x03,
5087 0x10, 0x11, 0x12, 0x13,
5088 0x04, 0x05, 0x06, 0x07,
5089 0x14, 0x15, 0x16, 0x17};
5091 emit_move_insn (mask, array_to_constant (TImode, arr));
5092 emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5096 (define_expand "vec_interleave_lowv4si"
5097 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
5101 (match_operand:V4SI 1 "spu_reg_operand" "r")
5102 (parallel [(const_int 2)(const_int 3)]))
5104 (match_operand:V4SI 2 "spu_reg_operand" "r")
5105 (parallel [(const_int 2)(const_int 3)])))
5106 (parallel [(const_int 0)(const_int 2)(const_int 1)(const_int 3)])))]
5111 rtx mask = gen_reg_rtx (TImode);
5112 unsigned char arr[16] = {
5113 0x08, 0x09, 0x0A, 0x0B,
5114 0x18, 0x19, 0x1A, 0x1B,
5115 0x0C, 0x0D, 0x0E, 0x0F,
5116 0x1C, 0x1D, 0x1E, 0x1F};
5118 emit_move_insn (mask, array_to_constant (TImode, arr));
5119 emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5123 (define_expand "vec_interleave_highv8hi"
5124 [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
5128 (match_operand:V8HI 1 "spu_reg_operand" "r")
5129 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)]))
5131 (match_operand:V8HI 2 "spu_reg_operand" "r")
5132 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)])))
5133 (parallel [(const_int 0)(const_int 4)(const_int 1)(const_int 5)
5134 (const_int 2)(const_int 6)(const_int 3)(const_int 7)])))]
5139 rtx mask = gen_reg_rtx (TImode);
5140 unsigned char arr[16] = {
5141 0x00, 0x01, 0x10, 0x11,
5142 0x02, 0x03, 0x12, 0x13,
5143 0x04, 0x05, 0x14, 0x15,
5144 0x06, 0x07, 0x16, 0x17};
5146 emit_move_insn (mask, array_to_constant (TImode, arr));
5147 emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5151 (define_expand "vec_interleave_lowv8hi"
5152 [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
5156 (match_operand:V8HI 1 "spu_reg_operand" "r")
5157 (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)]))
5159 (match_operand:V8HI 2 "spu_reg_operand" "r")
5160 (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)])))
5161 (parallel [(const_int 0)(const_int 4)(const_int 1)(const_int 5)
5162 (const_int 2)(const_int 6)(const_int 3)(const_int 7)])))]
5167 rtx mask = gen_reg_rtx (TImode);
5168 unsigned char arr[16] = {
5169 0x08, 0x09, 0x18, 0x19,
5170 0x0A, 0x0B, 0x1A, 0x1B,
5171 0x0C, 0x0D, 0x1C, 0x1D,
5172 0x0E, 0x0F, 0x1E, 0x1F};
5174 emit_move_insn (mask, array_to_constant (TImode, arr));
5175 emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5179 (define_expand "vec_interleave_highv16qi"
5180 [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
5184 (match_operand:V16QI 1 "spu_reg_operand" "r")
5185 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)
5186 (const_int 4)(const_int 5)(const_int 6)(const_int 7)]))
5188 (match_operand:V16QI 2 "spu_reg_operand" "r")
5189 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)
5190 (const_int 4)(const_int 5)(const_int 6)(const_int 7)])))
5191 (parallel [(const_int 0)(const_int 8)(const_int 1)(const_int 9)
5192 (const_int 2)(const_int 10)(const_int 3)(const_int 11)
5193 (const_int 4)(const_int 12)(const_int 5)(const_int 13)
5194 (const_int 6)(const_int 14)(const_int 7)(const_int 15)])))]
5199 rtx mask = gen_reg_rtx (TImode);
5200 unsigned char arr[16] = {
5201 0x00, 0x10, 0x01, 0x11,
5202 0x02, 0x12, 0x03, 0x13,
5203 0x04, 0x14, 0x05, 0x15,
5204 0x06, 0x16, 0x07, 0x17};
5206 emit_move_insn (mask, array_to_constant (TImode, arr));
5207 emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5211 (define_expand "vec_interleave_lowv16qi"
5212 [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
5216 (match_operand:V16QI 1 "spu_reg_operand" "r")
5217 (parallel [(const_int 8)(const_int 9)(const_int 10)(const_int 11)
5218 (const_int 12)(const_int 13)(const_int 14)(const_int 15)]))
5220 (match_operand:V16QI 2 "spu_reg_operand" "r")
5221 (parallel [(const_int 8)(const_int 9)(const_int 10)(const_int 11)
5222 (const_int 12)(const_int 13)(const_int 14)(const_int 15)])))
5223 (parallel [(const_int 0)(const_int 8)(const_int 1)(const_int 9)
5224 (const_int 2)(const_int 10)(const_int 3)(const_int 11)
5225 (const_int 4)(const_int 12)(const_int 5)(const_int 13)
5226 (const_int 6)(const_int 14)(const_int 7)(const_int 15)])))]
5231 rtx mask = gen_reg_rtx (TImode);
5232 unsigned char arr[16] = {
5233 0x08, 0x18, 0x09, 0x19,
5234 0x0A, 0x1A, 0x0B, 0x1B,
5235 0x0C, 0x1C, 0x0D, 0x1D,
5236 0x0E, 0x1E, 0x0F, 0x1F};
5238 emit_move_insn (mask, array_to_constant (TImode, arr));
5239 emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5243 (define_expand "vec_pack_trunc_v8hi"
5244 [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
5246 (truncate:V8QI (match_operand:V8HI 1 "spu_reg_operand" "r"))
5247 (truncate:V8QI (match_operand:V8HI 2 "spu_reg_operand" "r"))))]
5251 rtx mask = gen_reg_rtx (TImode);
5252 unsigned char arr[16] = {
5253 0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0D, 0x0F,
5254 0x11, 0x13, 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F};
5256 emit_move_insn (mask, array_to_constant (TImode, arr));
5257 emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5262 (define_expand "vec_pack_trunc_v4si"
5263 [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
5265 (truncate:V4HI (match_operand:V4SI 1 "spu_reg_operand" "r"))
5266 (truncate:V4HI (match_operand:V4SI 2 "spu_reg_operand" "r"))))]
5270 rtx mask = gen_reg_rtx (TImode);
5271 unsigned char arr[16] = {
5272 0x02, 0x03, 0x06, 0x07, 0x0A, 0x0B, 0x0E, 0x0F,
5273 0x12, 0x13, 0x16, 0x17, 0x1A, 0x1B, 0x1E, 0x1F};
5275 emit_move_insn (mask, array_to_constant (TImode, arr));
5276 emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5281 (define_insn "stack_protect_set"
5282 [(set (match_operand:SI 0 "memory_operand" "=m")
5283 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
5284 (set (match_scratch:SI 2 "=&r") (const_int 0))]
5286 "lq%p1\t%2,%1\;stq%p0\t%2,%0\;xor\t%2,%2,%2"
5287 [(set_attr "length" "12")
5288 (set_attr "type" "multi1")]
5291 (define_expand "stack_protect_test"
5292 [(match_operand 0 "memory_operand" "")
5293 (match_operand 1 "memory_operand" "")
5294 (match_operand 2 "" "")]
5300 compare_result = gen_reg_rtx (SImode);
5302 emit_insn (gen_stack_protect_test_si (compare_result,
5306 bcomp = gen_rtx_NE (SImode, compare_result, const0_rtx);
5308 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[2]);
5310 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
5311 gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp,
5317 (define_insn "stack_protect_test_si"
5318 [(set (match_operand:SI 0 "spu_reg_operand" "=&r")
5319 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
5320 (match_operand:SI 2 "memory_operand" "m")]
5322 (set (match_scratch:SI 3 "=&r") (const_int 0))]
5324 "lq%p1\t%0,%1\;lq%p2\t%3,%2\;ceq\t%0,%0,%3\;xor\t%3,%3,%3"
5325 [(set_attr "length" "16")
5326 (set_attr "type" "multi1")]