1 ;; Copyright (C) 2006, 2007, 2008, 2009, 2010 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 "nonimmediate_operand" "")
273 (match_operand:ALL 1 "general_operand" ""))]
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_fmasf4 (operands[0],
752 operands[2], operands[4], operands[3]));
756 (define_expand "floattisf2"
757 [(set (match_operand:SF 0 "register_operand" "")
758 (float:SF (match_operand:TI 1 "register_operand" "")))]
761 rtx c0 = gen_reg_rtx (SImode);
762 rtx r0 = gen_reg_rtx (TImode);
763 rtx r1 = gen_reg_rtx (SFmode);
764 rtx r2 = gen_reg_rtx (SImode);
765 rtx setneg = gen_reg_rtx (SImode);
766 rtx isneg = gen_reg_rtx (SImode);
767 rtx neg = gen_reg_rtx (TImode);
768 rtx mask = gen_reg_rtx (TImode);
770 emit_move_insn (c0, GEN_INT (-0x80000000ll));
772 emit_insn (gen_negti2 (neg, operands[1]));
773 emit_insn (gen_cgt_ti_m1 (isneg, operands[1]));
774 emit_insn (gen_extend_compare (mask, isneg));
775 emit_insn (gen_selb (r0, neg, operands[1], mask));
776 emit_insn (gen_andc_si (setneg, c0, isneg));
778 emit_insn (gen_floatunstisf2 (r1, r0));
780 emit_insn (gen_iorsi3 (r2, gen_rtx_SUBREG (SImode, r1, 0), setneg));
781 emit_move_insn (operands[0], gen_rtx_SUBREG (SFmode, r2, 0));
785 (define_insn_and_split "floatunstisf2"
786 [(set (match_operand:SF 0 "register_operand" "=r")
787 (unsigned_float:SF (match_operand:TI 1 "register_operand" "r")))
788 (clobber (match_scratch:SF 2 "=r"))
789 (clobber (match_scratch:SF 3 "=r"))
790 (clobber (match_scratch:SF 4 "=r"))]
794 [(set (match_dup:SF 0)
795 (unsigned_float:SF (match_dup:TI 1)))]
797 rtx op1_v4si = gen_rtx_REG (V4SImode, REGNO (operands[1]));
798 rtx op2_v4sf = gen_rtx_REG (V4SFmode, REGNO (operands[2]));
799 rtx op2_ti = gen_rtx_REG (TImode, REGNO (operands[2]));
800 rtx op3_ti = gen_rtx_REG (TImode, REGNO (operands[3]));
802 REAL_VALUE_TYPE scale;
803 real_2expN (&scale, 32, SFmode);
805 emit_insn (gen_floatunsv4siv4sf2 (op2_v4sf, op1_v4si));
806 emit_insn (gen_shlqby_ti (op3_ti, op2_ti, GEN_INT (4)));
808 emit_move_insn (operands[4],
809 CONST_DOUBLE_FROM_REAL_VALUE (scale, SFmode));
810 emit_insn (gen_fmasf4 (operands[2],
811 operands[2], operands[4], operands[3]));
813 emit_insn (gen_shlqby_ti (op3_ti, op3_ti, GEN_INT (4)));
814 emit_insn (gen_fmasf4 (operands[2],
815 operands[2], operands[4], operands[3]));
817 emit_insn (gen_shlqby_ti (op3_ti, op3_ti, GEN_INT (4)));
818 emit_insn (gen_fmasf4 (operands[0],
819 operands[2], operands[4], operands[3]));
823 ;; Do (double)(operands[1]+0x80000000u)-(double)0x80000000
824 (define_expand "floatsidf2"
825 [(set (match_operand:DF 0 "register_operand" "")
826 (float:DF (match_operand:SI 1 "register_operand" "")))]
829 rtx c0 = gen_reg_rtx (SImode);
830 rtx c1 = gen_reg_rtx (DFmode);
831 rtx r0 = gen_reg_rtx (SImode);
832 rtx r1 = gen_reg_rtx (DFmode);
834 emit_move_insn (c0, GEN_INT (-0x80000000ll));
835 emit_move_insn (c1, spu_float_const ("2147483648", DFmode));
836 emit_insn (gen_xorsi3 (r0, operands[1], c0));
837 emit_insn (gen_floatunssidf2 (r1, r0));
838 emit_insn (gen_subdf3 (operands[0], r1, c1));
842 (define_expand "floatunssidf2"
843 [(set (match_operand:DF 0 "register_operand" "=r")
844 (unsigned_float:DF (match_operand:SI 1 "register_operand" "r")))]
848 rtx c0 = spu_const_from_ints (V16QImode, 0x02031011, 0x12138080,
849 0x06071415, 0x16178080);
850 rtx r0 = gen_reg_rtx (V16QImode);
856 emit_library_call_value (convert_optab_libfunc (ufloat_optab,
858 NULL_RTX, LCT_NORMAL, DFmode, 1, operands[1], SImode);
859 insns = get_insns ();
861 emit_libcall_block (insns, operands[0], value,
862 gen_rtx_UNSIGNED_FLOAT (DFmode, operands[1]));
866 emit_move_insn (r0, c0);
867 emit_insn (gen_floatunssidf2_internal (operands[0], operands[1], r0));
872 (define_insn_and_split "floatunssidf2_internal"
873 [(set (match_operand:DF 0 "register_operand" "=r")
874 (unsigned_float:DF (match_operand:SI 1 "register_operand" "r")))
875 (use (match_operand:V16QI 2 "register_operand" "r"))
876 (clobber (match_scratch:V4SI 3 "=&r"))
877 (clobber (match_scratch:V4SI 4 "=&r"))
878 (clobber (match_scratch:V4SI 5 "=&r"))
879 (clobber (match_scratch:V4SI 6 "=&r"))]
881 "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"
883 [(set (match_dup:DF 0)
884 (unsigned_float:DF (match_dup:SI 1)))]
887 rtx op1_v4si = gen_rtx_REG(V4SImode, REGNO(ops[1]));
888 rtx op0_ti = gen_rtx_REG (TImode, REGNO (ops[0]));
889 rtx op2_ti = gen_rtx_REG (TImode, REGNO (ops[2]));
890 rtx op6_ti = gen_rtx_REG (TImode, REGNO (ops[6]));
891 emit_insn (gen_clzv4si2 (ops[3],op1_v4si));
892 emit_move_insn (ops[6], spu_const (V4SImode, 1023+31));
893 emit_insn (gen_vashlv4si3 (ops[4],op1_v4si,ops[3]));
894 emit_insn (gen_ceq_v4si (ops[5],ops[3],spu_const (V4SImode, 32)));
895 emit_insn (gen_subv4si3 (ops[6],ops[6],ops[3]));
896 emit_insn (gen_addv4si3 (ops[4],ops[4],ops[4]));
897 emit_insn (gen_andc_v4si (ops[6],ops[6],ops[5]));
898 emit_insn (gen_shufb (ops[6],ops[6],ops[4],op2_ti));
899 emit_insn (gen_shlqbi_ti (op0_ti,op6_ti,GEN_INT(4)));
902 [(set_attr "length" "32")])
904 (define_expand "floatdidf2"
905 [(set (match_operand:DF 0 "register_operand" "")
906 (float:DF (match_operand:DI 1 "register_operand" "")))]
909 rtx c0 = gen_reg_rtx (DImode);
910 rtx r0 = gen_reg_rtx (DImode);
911 rtx r1 = gen_reg_rtx (DFmode);
912 rtx r2 = gen_reg_rtx (DImode);
913 rtx setneg = gen_reg_rtx (DImode);
914 rtx isneg = gen_reg_rtx (SImode);
915 rtx neg = gen_reg_rtx (DImode);
916 rtx mask = gen_reg_rtx (DImode);
918 emit_move_insn (c0, GEN_INT (0x8000000000000000ull));
920 emit_insn (gen_negdi2 (neg, operands[1]));
921 emit_insn (gen_cgt_di_m1 (isneg, operands[1]));
922 emit_insn (gen_extend_compare (mask, isneg));
923 emit_insn (gen_selb (r0, neg, operands[1], mask));
924 emit_insn (gen_andc_di (setneg, c0, mask));
926 emit_insn (gen_floatunsdidf2 (r1, r0));
928 emit_insn (gen_iordi3 (r2, gen_rtx_SUBREG (DImode, r1, 0), setneg));
929 emit_move_insn (operands[0], gen_rtx_SUBREG (DFmode, r2, 0));
933 (define_expand "floatunsdidf2"
934 [(set (match_operand:DF 0 "register_operand" "=r")
935 (unsigned_float:DF (match_operand:DI 1 "register_operand" "r")))]
939 rtx c0 = spu_const_from_ints (V16QImode, 0x02031011, 0x12138080,
940 0x06071415, 0x16178080);
941 rtx c1 = spu_const_from_ints (V4SImode, 1023+63, 1023+31, 0, 0);
942 rtx r0 = gen_reg_rtx (V16QImode);
943 rtx r1 = gen_reg_rtx (V4SImode);
949 emit_library_call_value (convert_optab_libfunc (ufloat_optab,
951 NULL_RTX, LCT_NORMAL, DFmode, 1, operands[1], DImode);
952 insns = get_insns ();
954 emit_libcall_block (insns, operands[0], value,
955 gen_rtx_UNSIGNED_FLOAT (DFmode, operands[1]));
959 emit_move_insn (r1, c1);
960 emit_move_insn (r0, c0);
961 emit_insn (gen_floatunsdidf2_internal (operands[0], operands[1], r0, r1));
966 (define_insn_and_split "floatunsdidf2_internal"
967 [(set (match_operand:DF 0 "register_operand" "=r")
968 (unsigned_float:DF (match_operand:DI 1 "register_operand" "r")))
969 (use (match_operand:V16QI 2 "register_operand" "r"))
970 (use (match_operand:V4SI 3 "register_operand" "r"))
971 (clobber (match_scratch:V4SI 4 "=&r"))
972 (clobber (match_scratch:V4SI 5 "=&r"))
973 (clobber (match_scratch:V4SI 6 "=&r"))]
975 "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"
977 [(set (match_operand:DF 0 "register_operand" "=r")
978 (unsigned_float:DF (match_operand:DI 1 "register_operand" "r")))]
981 rtx op1_v4si = gen_rtx_REG (V4SImode, REGNO(ops[1]));
982 rtx op2_ti = gen_rtx_REG (TImode, REGNO(ops[2]));
983 rtx op4_ti = gen_rtx_REG (TImode, REGNO(ops[4]));
984 rtx op5_ti = gen_rtx_REG (TImode, REGNO(ops[5]));
985 rtx op4_df = gen_rtx_REG (DFmode, REGNO(ops[4]));
986 rtx op5_df = gen_rtx_REG (DFmode, REGNO(ops[5]));
987 emit_insn (gen_clzv4si2 (ops[4],op1_v4si));
988 emit_insn (gen_vashlv4si3 (ops[5],op1_v4si,ops[4]));
989 emit_insn (gen_ceq_v4si (ops[6],ops[4],spu_const (V4SImode, 32)));
990 emit_insn (gen_subv4si3 (ops[4],ops[3],ops[4]));
991 emit_insn (gen_addv4si3 (ops[5],ops[5],ops[5]));
992 emit_insn (gen_andc_v4si (ops[4],ops[4],ops[6]));
993 emit_insn (gen_shufb (ops[4],ops[4],ops[5],op2_ti));
994 emit_insn (gen_shlqbi_ti (op4_ti,op4_ti,GEN_INT(4)));
995 emit_insn (gen_shlqby_ti (op5_ti,op4_ti,GEN_INT(8)));
996 emit_insn (gen_adddf3 (ops[0],op4_df,op5_df));
999 [(set_attr "length" "40")])
1004 (define_expand "addv16qi3"
1005 [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
1006 (plus:V16QI (match_operand:V16QI 1 "spu_reg_operand" "r")
1007 (match_operand:V16QI 2 "spu_reg_operand" "r")))]
1010 rtx res_short = simplify_gen_subreg (V8HImode, operands[0], V16QImode, 0);
1011 rtx lhs_short = simplify_gen_subreg (V8HImode, operands[1], V16QImode, 0);
1012 rtx rhs_short = simplify_gen_subreg (V8HImode, operands[2], V16QImode, 0);
1013 rtx rhs_and = gen_reg_rtx (V8HImode);
1014 rtx hi_char = gen_reg_rtx (V8HImode);
1015 rtx lo_char = gen_reg_rtx (V8HImode);
1016 rtx mask = gen_reg_rtx (V8HImode);
1018 emit_move_insn (mask, spu_const (V8HImode, 0x00ff));
1019 emit_insn (gen_andv8hi3 (rhs_and, rhs_short, spu_const (V8HImode, 0xff00)));
1020 emit_insn (gen_addv8hi3 (hi_char, lhs_short, rhs_and));
1021 emit_insn (gen_addv8hi3 (lo_char, lhs_short, rhs_short));
1022 emit_insn (gen_selb (res_short, hi_char, lo_char, mask));
1026 (define_insn "add<mode>3"
1027 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
1028 (plus:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
1029 (match_operand:VHSI 2 "spu_arith_operand" "r,B")))]
1035 (define_expand "add<mode>3"
1036 [(set (match_dup:VDI 3)
1037 (unspec:VDI [(match_operand:VDI 1 "spu_reg_operand" "")
1038 (match_operand:VDI 2 "spu_reg_operand" "")] UNSPEC_CG))
1039 (set (match_dup:VDI 5)
1040 (unspec:VDI [(match_dup 3)
1042 (match_dup:TI 4)] UNSPEC_SHUFB))
1043 (set (match_operand:VDI 0 "spu_reg_operand" "")
1044 (unspec:VDI [(match_dup 1)
1046 (match_dup 5)] UNSPEC_ADDX))]
1049 unsigned char pat[16] = {
1050 0x04, 0x05, 0x06, 0x07,
1051 0x80, 0x80, 0x80, 0x80,
1052 0x0c, 0x0d, 0x0e, 0x0f,
1053 0x80, 0x80, 0x80, 0x80
1055 operands[3] = gen_reg_rtx (<MODE>mode);
1056 operands[4] = gen_reg_rtx (TImode);
1057 operands[5] = gen_reg_rtx (<MODE>mode);
1058 emit_move_insn (operands[4], array_to_constant (TImode, pat));
1061 (define_insn "cg_<mode>"
1062 [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
1063 (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
1064 (match_operand 2 "spu_reg_operand" "r")] UNSPEC_CG))]
1068 (define_insn "cgx_<mode>"
1069 [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
1070 (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
1071 (match_operand 2 "spu_reg_operand" "r")
1072 (match_operand 3 "spu_reg_operand" "0")] UNSPEC_CGX))]
1076 (define_insn "addx_<mode>"
1077 [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
1078 (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
1079 (match_operand 2 "spu_reg_operand" "r")
1080 (match_operand 3 "spu_reg_operand" "0")] UNSPEC_ADDX))]
1085 ;; This is not the most efficient implementation of addti3.
1086 ;; We include this here because 1) the compiler needs it to be
1087 ;; defined as the word size is 128-bit and 2) sometimes gcc
1088 ;; substitutes an add for a constant left-shift. 2) is unlikely
1089 ;; because we also give addti3 a high cost. In case gcc does
1090 ;; generate TImode add, here is the code to do it.
1091 ;; operand 2 is a nonmemory because the compiler requires it.
1092 (define_insn "addti3"
1093 [(set (match_operand:TI 0 "spu_reg_operand" "=&r")
1094 (plus:TI (match_operand:TI 1 "spu_reg_operand" "r")
1095 (match_operand:TI 2 "spu_nonmem_operand" "r")))
1096 (clobber (match_scratch:TI 3 "=&r"))]
1099 shlqbyi\t%3,%3,4\n\\
1101 shlqbyi\t%3,%3,4\n\\
1103 shlqbyi\t%0,%3,4\n\\
1105 [(set_attr "type" "multi0")
1106 (set_attr "length" "28")])
1108 (define_insn "add<mode>3"
1109 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1110 (plus:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
1111 (match_operand:VSF 2 "spu_reg_operand" "r")))]
1114 [(set_attr "type" "fp6")])
1116 (define_insn "add<mode>3"
1117 [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
1118 (plus:VDF (match_operand:VDF 1 "spu_reg_operand" "r")
1119 (match_operand:VDF 2 "spu_reg_operand" "r")))]
1122 [(set_attr "type" "fpd")])
1127 (define_expand "subv16qi3"
1128 [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
1129 (minus:V16QI (match_operand:V16QI 1 "spu_reg_operand" "r")
1130 (match_operand:V16QI 2 "spu_reg_operand" "r")))]
1133 rtx res_short = simplify_gen_subreg (V8HImode, operands[0], V16QImode, 0);
1134 rtx lhs_short = simplify_gen_subreg (V8HImode, operands[1], V16QImode, 0);
1135 rtx rhs_short = simplify_gen_subreg (V8HImode, operands[2], V16QImode, 0);
1136 rtx rhs_and = gen_reg_rtx (V8HImode);
1137 rtx hi_char = gen_reg_rtx (V8HImode);
1138 rtx lo_char = gen_reg_rtx (V8HImode);
1139 rtx mask = gen_reg_rtx (V8HImode);
1141 emit_move_insn (mask, spu_const (V8HImode, 0x00ff));
1142 emit_insn (gen_andv8hi3 (rhs_and, rhs_short, spu_const (V8HImode, 0xff00)));
1143 emit_insn (gen_subv8hi3 (hi_char, lhs_short, rhs_and));
1144 emit_insn (gen_subv8hi3 (lo_char, lhs_short, rhs_short));
1145 emit_insn (gen_selb (res_short, hi_char, lo_char, mask));
1149 (define_insn "sub<mode>3"
1150 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
1151 (minus:VHSI (match_operand:VHSI 1 "spu_arith_operand" "r,B")
1152 (match_operand:VHSI 2 "spu_reg_operand" "r,r")))]
1158 (define_expand "sub<mode>3"
1159 [(set (match_dup:VDI 3)
1160 (unspec:VDI [(match_operand:VDI 1 "spu_reg_operand" "")
1161 (match_operand:VDI 2 "spu_reg_operand" "")] UNSPEC_BG))
1162 (set (match_dup:VDI 5)
1163 (unspec:VDI [(match_dup 3)
1165 (match_dup:TI 4)] UNSPEC_SHUFB))
1166 (set (match_operand:VDI 0 "spu_reg_operand" "")
1167 (unspec:VDI [(match_dup 1)
1169 (match_dup 5)] UNSPEC_SFX))]
1172 unsigned char pat[16] = {
1173 0x04, 0x05, 0x06, 0x07,
1174 0xc0, 0xc0, 0xc0, 0xc0,
1175 0x0c, 0x0d, 0x0e, 0x0f,
1176 0xc0, 0xc0, 0xc0, 0xc0
1178 operands[3] = gen_reg_rtx (<MODE>mode);
1179 operands[4] = gen_reg_rtx (TImode);
1180 operands[5] = gen_reg_rtx (<MODE>mode);
1181 emit_move_insn (operands[4], array_to_constant (TImode, pat));
1184 (define_insn "bg_<mode>"
1185 [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
1186 (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
1187 (match_operand 2 "spu_reg_operand" "r")] UNSPEC_BG))]
1191 (define_insn "bgx_<mode>"
1192 [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
1193 (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
1194 (match_operand 2 "spu_reg_operand" "r")
1195 (match_operand 3 "spu_reg_operand" "0")] UNSPEC_BGX))]
1199 (define_insn "sfx_<mode>"
1200 [(set (match_operand:CBOP 0 "spu_reg_operand" "=r")
1201 (unspec:CBOP [(match_operand 1 "spu_reg_operand" "r")
1202 (match_operand 2 "spu_reg_operand" "r")
1203 (match_operand 3 "spu_reg_operand" "0")] UNSPEC_SFX))]
1207 (define_insn "subti3"
1208 [(set (match_operand:TI 0 "spu_reg_operand" "=r")
1209 (minus:TI (match_operand:TI 1 "spu_reg_operand" "r")
1210 (match_operand:TI 2 "spu_reg_operand" "r")))
1211 (clobber (match_scratch:TI 3 "=&r"))
1212 (clobber (match_scratch:TI 4 "=&r"))
1213 (clobber (match_scratch:TI 5 "=&r"))
1214 (clobber (match_scratch:TI 6 "=&r"))]
1220 shlqbyi\t%5,%3,4\n\\
1224 shlqbyi\t%5,%3,4\n\\
1228 shlqbyi\t%5,%3,4\n\\
1230 [(set_attr "type" "multi0")
1231 (set_attr "length" "56")])
1233 (define_insn "sub<mode>3"
1234 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1235 (minus:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
1236 (match_operand:VSF 2 "spu_reg_operand" "r")))]
1239 [(set_attr "type" "fp6")])
1241 (define_insn "sub<mode>3"
1242 [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
1243 (minus:VDF (match_operand:VDF 1 "spu_reg_operand" "r")
1244 (match_operand:VDF 2 "spu_reg_operand" "r")))]
1247 [(set_attr "type" "fpd")])
1252 (define_expand "negv16qi2"
1253 [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
1254 (neg:V16QI (match_operand:V16QI 1 "spu_reg_operand" "r")))]
1257 rtx zero = gen_reg_rtx (V16QImode);
1258 emit_move_insn (zero, CONST0_RTX (V16QImode));
1259 emit_insn (gen_subv16qi3 (operands[0], zero, operands[1]));
1263 (define_insn "neg<mode>2"
1264 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r")
1265 (neg:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r")))]
1269 (define_expand "negdi2"
1270 [(set (match_operand:DI 0 "spu_reg_operand" "")
1271 (neg:DI (match_operand:DI 1 "spu_reg_operand" "")))]
1274 rtx zero = gen_reg_rtx(DImode);
1275 emit_move_insn(zero, GEN_INT(0));
1276 emit_insn (gen_subdi3(operands[0], zero, operands[1]));
1280 (define_expand "negti2"
1281 [(set (match_operand:TI 0 "spu_reg_operand" "")
1282 (neg:TI (match_operand:TI 1 "spu_reg_operand" "")))]
1285 rtx zero = gen_reg_rtx(TImode);
1286 emit_move_insn(zero, GEN_INT(0));
1287 emit_insn (gen_subti3(operands[0], zero, operands[1]));
1291 (define_expand "neg<mode>2"
1293 [(set (match_operand:VSF 0 "spu_reg_operand" "")
1294 (neg:VSF (match_operand:VSF 1 "spu_reg_operand" "")))
1295 (use (match_dup 2))])]
1297 "operands[2] = gen_reg_rtx (<F2I>mode);
1298 emit_move_insn (operands[2], spu_const (<F2I>mode, -0x80000000ull));")
1300 (define_expand "neg<mode>2"
1302 [(set (match_operand:VDF 0 "spu_reg_operand" "")
1303 (neg:VDF (match_operand:VDF 1 "spu_reg_operand" "")))
1304 (use (match_dup 2))])]
1306 "operands[2] = gen_reg_rtx (<F2I>mode);
1307 emit_move_insn (operands[2], spu_const (<F2I>mode, -0x8000000000000000ull));")
1309 (define_insn_and_split "_neg<mode>2"
1310 [(set (match_operand:VSDF 0 "spu_reg_operand" "=r")
1311 (neg:VSDF (match_operand:VSDF 1 "spu_reg_operand" "r")))
1312 (use (match_operand:<F2I> 2 "spu_reg_operand" "r"))]
1316 [(set (match_dup:<F2I> 3)
1317 (xor:<F2I> (match_dup:<F2I> 4)
1318 (match_dup:<F2I> 2)))]
1320 operands[3] = spu_gen_subreg (<F2I>mode, operands[0]);
1321 operands[4] = spu_gen_subreg (<F2I>mode, operands[1]);
1327 (define_expand "abs<mode>2"
1329 [(set (match_operand:VSF 0 "spu_reg_operand" "")
1330 (abs:VSF (match_operand:VSF 1 "spu_reg_operand" "")))
1331 (use (match_dup 2))])]
1333 "operands[2] = gen_reg_rtx (<F2I>mode);
1334 emit_move_insn (operands[2], spu_const (<F2I>mode, 0x7fffffffull));")
1336 (define_expand "abs<mode>2"
1338 [(set (match_operand:VDF 0 "spu_reg_operand" "")
1339 (abs:VDF (match_operand:VDF 1 "spu_reg_operand" "")))
1340 (use (match_dup 2))])]
1342 "operands[2] = gen_reg_rtx (<F2I>mode);
1343 emit_move_insn (operands[2], spu_const (<F2I>mode, 0x7fffffffffffffffull));")
1345 (define_insn_and_split "_abs<mode>2"
1346 [(set (match_operand:VSDF 0 "spu_reg_operand" "=r")
1347 (abs:VSDF (match_operand:VSDF 1 "spu_reg_operand" "r")))
1348 (use (match_operand:<F2I> 2 "spu_reg_operand" "r"))]
1352 [(set (match_dup:<F2I> 3)
1353 (and:<F2I> (match_dup:<F2I> 4)
1354 (match_dup:<F2I> 2)))]
1356 operands[3] = spu_gen_subreg (<F2I>mode, operands[0]);
1357 operands[4] = spu_gen_subreg (<F2I>mode, operands[1]);
1363 (define_insn "mulhi3"
1364 [(set (match_operand:HI 0 "spu_reg_operand" "=r,r")
1365 (mult:HI (match_operand:HI 1 "spu_reg_operand" "r,r")
1366 (match_operand:HI 2 "spu_arith_operand" "r,B")))]
1371 [(set_attr "type" "fp7")])
1373 (define_expand "mulv8hi3"
1374 [(set (match_operand:V8HI 0 "spu_reg_operand" "")
1375 (mult:V8HI (match_operand:V8HI 1 "spu_reg_operand" "")
1376 (match_operand:V8HI 2 "spu_reg_operand" "")))]
1379 rtx result = simplify_gen_subreg (V4SImode, operands[0], V8HImode, 0);
1380 rtx low = gen_reg_rtx (V4SImode);
1381 rtx high = gen_reg_rtx (V4SImode);
1382 rtx shift = gen_reg_rtx (V4SImode);
1383 rtx mask = gen_reg_rtx (V4SImode);
1385 emit_move_insn (mask, spu_const (V4SImode, 0x0000ffff));
1386 emit_insn (gen_spu_mpyhh (high, operands[1], operands[2]));
1387 emit_insn (gen_spu_mpy (low, operands[1], operands[2]));
1388 emit_insn (gen_vashlv4si3 (shift, high, spu_const(V4SImode, 16)));
1389 emit_insn (gen_selb (result, shift, low, mask));
1393 (define_expand "mul<mode>3"
1395 [(set (match_operand:VSI 0 "spu_reg_operand" "")
1396 (mult:VSI (match_operand:VSI 1 "spu_reg_operand" "")
1397 (match_operand:VSI 2 "spu_reg_operand" "")))
1398 (clobber (match_dup:VSI 3))
1399 (clobber (match_dup:VSI 4))
1400 (clobber (match_dup:VSI 5))
1401 (clobber (match_dup:VSI 6))])]
1404 operands[3] = gen_reg_rtx(<MODE>mode);
1405 operands[4] = gen_reg_rtx(<MODE>mode);
1406 operands[5] = gen_reg_rtx(<MODE>mode);
1407 operands[6] = gen_reg_rtx(<MODE>mode);
1410 (define_insn_and_split "_mulsi3"
1411 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1412 (mult:SI (match_operand:SI 1 "spu_reg_operand" "r")
1413 (match_operand:SI 2 "spu_arith_operand" "rK")))
1414 (clobber (match_operand:SI 3 "spu_reg_operand" "=&r"))
1415 (clobber (match_operand:SI 4 "spu_reg_operand" "=&r"))
1416 (clobber (match_operand:SI 5 "spu_reg_operand" "=&r"))
1417 (clobber (match_operand:SI 6 "spu_reg_operand" "=&r"))]
1421 [(set (match_dup:SI 0)
1422 (mult:SI (match_dup:SI 1)
1425 HOST_WIDE_INT val = 0;
1426 rtx a = operands[3];
1427 rtx b = operands[4];
1428 rtx c = operands[5];
1429 rtx d = operands[6];
1430 if (GET_CODE(operands[2]) == CONST_INT)
1432 val = INTVAL(operands[2]);
1433 emit_move_insn(d, operands[2]);
1436 if (val && (val & 0xffff) == 0)
1438 emit_insn (gen_mpyh_si(operands[0], operands[2], operands[1]));
1440 else if (val > 0 && val < 0x10000)
1442 rtx cst = satisfies_constraint_K (GEN_INT (val)) ? GEN_INT(val) : d;
1443 emit_insn (gen_mpyh_si(a, operands[1], operands[2]));
1444 emit_insn (gen_mpyu_si(c, operands[1], cst));
1445 emit_insn (gen_addsi3(operands[0], a, c));
1449 emit_insn (gen_mpyh_si(a, operands[1], operands[2]));
1450 emit_insn (gen_mpyh_si(b, operands[2], operands[1]));
1451 emit_insn (gen_mpyu_si(c, operands[1], operands[2]));
1452 emit_insn (gen_addsi3(d, a, b));
1453 emit_insn (gen_addsi3(operands[0], d, c));
1458 (define_insn_and_split "_mulv4si3"
1459 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
1460 (mult:V4SI (match_operand:V4SI 1 "spu_reg_operand" "r")
1461 (match_operand:V4SI 2 "spu_reg_operand" "r")))
1462 (clobber (match_operand:V4SI 3 "spu_reg_operand" "=&r"))
1463 (clobber (match_operand:V4SI 4 "spu_reg_operand" "=&r"))
1464 (clobber (match_operand:V4SI 5 "spu_reg_operand" "=&r"))
1465 (clobber (match_operand:V4SI 6 "spu_reg_operand" "=&r"))]
1469 [(set (match_dup:V4SI 0)
1470 (mult:V4SI (match_dup:V4SI 1)
1471 (match_dup:V4SI 2)))]
1473 rtx a = operands[3];
1474 rtx b = operands[4];
1475 rtx c = operands[5];
1476 rtx d = operands[6];
1477 rtx op1 = simplify_gen_subreg (V8HImode, operands[1], V4SImode, 0);
1478 rtx op2 = simplify_gen_subreg (V8HImode, operands[2], V4SImode, 0);
1479 emit_insn (gen_spu_mpyh(a, op1, op2));
1480 emit_insn (gen_spu_mpyh(b, op2, op1));
1481 emit_insn (gen_spu_mpyu(c, op1, op2));
1482 emit_insn (gen_addv4si3(d, a, b));
1483 emit_insn (gen_addv4si3(operands[0], d, c));
1487 (define_insn "mulhisi3"
1488 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1489 (mult:SI (sign_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
1490 (sign_extend:SI (match_operand:HI 2 "spu_reg_operand" "r"))))]
1493 [(set_attr "type" "fp7")])
1495 (define_insn "mulhisi3_imm"
1496 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1497 (mult:SI (sign_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
1498 (match_operand:SI 2 "imm_K_operand" "K")))]
1501 [(set_attr "type" "fp7")])
1503 (define_insn "umulhisi3"
1504 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1505 (mult:SI (zero_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
1506 (zero_extend:SI (match_operand:HI 2 "spu_reg_operand" "r"))))]
1509 [(set_attr "type" "fp7")])
1511 (define_insn "umulhisi3_imm"
1512 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1513 (mult:SI (zero_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
1514 (and:SI (match_operand:SI 2 "imm_K_operand" "K") (const_int 65535))))]
1517 [(set_attr "type" "fp7")])
1519 (define_insn "mpyu_si"
1520 [(set (match_operand:SI 0 "spu_reg_operand" "=r,r")
1521 (mult:SI (and:SI (match_operand:SI 1 "spu_reg_operand" "r,r")
1523 (and:SI (match_operand:SI 2 "spu_arith_operand" "r,K")
1524 (const_int 65535))))]
1529 [(set_attr "type" "fp7")])
1531 ;; This isn't always profitable to use. Consider r = a * b + c * d.
1532 ;; It's faster to do the multiplies in parallel then add them. If we
1533 ;; merge a multiply and add it prevents the multiplies from happening in
1535 (define_insn "mpya_si"
1536 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1537 (plus:SI (mult:SI (sign_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
1538 (sign_extend:SI (match_operand:HI 2 "spu_reg_operand" "r")))
1539 (match_operand:SI 3 "spu_reg_operand" "r")))]
1542 [(set_attr "type" "fp7")])
1544 (define_insn "mpyh_si"
1545 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1546 (mult:SI (and:SI (match_operand:SI 1 "spu_reg_operand" "r")
1548 (and:SI (match_operand:SI 2 "spu_reg_operand" "r")
1549 (const_int 65535))))]
1552 [(set_attr "type" "fp7")])
1554 (define_insn "mpys_si"
1555 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1557 (mult:SI (sign_extend:SI (match_operand:HI 1 "spu_reg_operand" "r"))
1558 (sign_extend:SI (match_operand:HI 2 "spu_reg_operand" "r")))
1562 [(set_attr "type" "fp7")])
1564 (define_insn "mpyhh_si"
1565 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1566 (mult:SI (ashiftrt:SI (match_operand:SI 1 "spu_reg_operand" "r")
1568 (ashiftrt:SI (match_operand:SI 2 "spu_reg_operand" "r")
1572 [(set_attr "type" "fp7")])
1574 (define_insn "mpyhhu_si"
1575 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1576 (mult:SI (lshiftrt:SI (match_operand:SI 1 "spu_reg_operand" "r")
1578 (lshiftrt:SI (match_operand:SI 2 "spu_reg_operand" "r")
1582 [(set_attr "type" "fp7")])
1584 (define_insn "mpyhha_si"
1585 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
1586 (plus:SI (mult:SI (ashiftrt:SI (match_operand:SI 1 "spu_reg_operand" "r")
1588 (ashiftrt:SI (match_operand:SI 2 "spu_reg_operand" "r")
1590 (match_operand:SI 3 "spu_reg_operand" "0")))]
1593 [(set_attr "type" "fp7")])
1595 (define_insn "mul<mode>3"
1596 [(set (match_operand:VSDF 0 "spu_reg_operand" "=r")
1597 (mult:VSDF (match_operand:VSDF 1 "spu_reg_operand" "r")
1598 (match_operand:VSDF 2 "spu_reg_operand" "r")))]
1601 [(set_attr "type" "fp<d6>")])
1603 (define_insn "fma<mode>4"
1604 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1605 (fma:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
1606 (match_operand:VSF 2 "spu_reg_operand" "r")
1607 (match_operand:VSF 3 "spu_reg_operand" "r")))]
1610 [(set_attr "type" "fp6")])
1612 ;; ??? The official description is (c - a*b), which is exactly (-a*b + c).
1613 ;; Note that this doesn't match the dfnms description. Incorrect?
1614 (define_insn "fnma<mode>4"
1615 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1617 (neg:VSF (match_operand:VSF 1 "spu_reg_operand" "r"))
1618 (match_operand:VSF 2 "spu_reg_operand" "r")
1619 (match_operand:VSF 3 "spu_reg_operand" "r")))]
1622 [(set_attr "type" "fp6")])
1624 (define_insn "fms<mode>4"
1625 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1627 (match_operand:VSF 1 "spu_reg_operand" "r")
1628 (match_operand:VSF 2 "spu_reg_operand" "r")
1629 (neg:VSF (match_operand:VSF 3 "spu_reg_operand" "r"))))]
1632 [(set_attr "type" "fp6")])
1634 (define_insn "fma<mode>4"
1635 [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
1636 (fma:VDF (match_operand:VDF 1 "spu_reg_operand" "r")
1637 (match_operand:VDF 2 "spu_reg_operand" "r")
1638 (match_operand:VDF 3 "spu_reg_operand" "0")))]
1641 [(set_attr "type" "fpd")])
1643 (define_insn "fms<mode>4"
1644 [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
1646 (match_operand:VDF 1 "spu_reg_operand" "r")
1647 (match_operand:VDF 2 "spu_reg_operand" "r")
1648 (neg:VDF (match_operand:VDF 3 "spu_reg_operand" "0"))))]
1651 [(set_attr "type" "fpd")])
1653 (define_insn "nfma<mode>4"
1654 [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
1656 (fma:VDF (match_operand:VDF 1 "spu_reg_operand" "r")
1657 (match_operand:VDF 2 "spu_reg_operand" "r")
1658 (match_operand:VDF 3 "spu_reg_operand" "0"))))]
1661 [(set_attr "type" "fpd")])
1663 (define_insn "nfms<mode>4"
1664 [(set (match_operand:VDF 0 "spu_reg_operand" "=r")
1667 (match_operand:VDF 1 "spu_reg_operand" "r")
1668 (match_operand:VDF 2 "spu_reg_operand" "r")
1669 (neg:VDF (match_operand:VDF 3 "spu_reg_operand" "0")))))]
1672 [(set_attr "type" "fpd")])
1674 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
1675 (define_expand "fnma<mode>4"
1676 [(set (match_operand:VDF 0 "spu_reg_operand" "")
1679 (match_operand:VDF 1 "spu_reg_operand" "")
1680 (match_operand:VDF 2 "spu_reg_operand" "")
1681 (neg:VDF (match_operand:VDF 3 "spu_reg_operand" "")))))]
1682 "!HONOR_SIGNED_ZEROS (<MODE>mode)"
1685 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
1686 (define_expand "fnms<mode>4"
1687 [(set (match_operand:VDF 0 "register_operand" "")
1690 (match_operand:VDF 1 "register_operand" "")
1691 (match_operand:VDF 2 "register_operand" "")
1692 (match_operand:VDF 3 "register_operand" ""))))]
1693 "!HONOR_SIGNED_ZEROS (<MODE>mode)"
1696 ;; mul highpart, used for divide by constant optimizations.
1698 (define_expand "smulsi3_highpart"
1699 [(set (match_operand:SI 0 "register_operand" "")
1702 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
1703 (sign_extend:DI (match_operand:SI 2 "register_operand" "")))
1707 rtx t0 = gen_reg_rtx (SImode);
1708 rtx t1 = gen_reg_rtx (SImode);
1709 rtx t2 = gen_reg_rtx (SImode);
1710 rtx t3 = gen_reg_rtx (SImode);
1711 rtx t4 = gen_reg_rtx (SImode);
1712 rtx t5 = gen_reg_rtx (SImode);
1713 rtx t6 = gen_reg_rtx (SImode);
1714 rtx t7 = gen_reg_rtx (SImode);
1715 rtx t8 = gen_reg_rtx (SImode);
1716 rtx t9 = gen_reg_rtx (SImode);
1717 rtx t11 = gen_reg_rtx (SImode);
1718 rtx t12 = gen_reg_rtx (SImode);
1719 rtx t14 = gen_reg_rtx (SImode);
1720 rtx t15 = gen_reg_rtx (HImode);
1721 rtx t16 = gen_reg_rtx (HImode);
1722 rtx t17 = gen_reg_rtx (HImode);
1723 rtx t18 = gen_reg_rtx (HImode);
1724 rtx t19 = gen_reg_rtx (SImode);
1725 rtx t20 = gen_reg_rtx (SImode);
1726 rtx t21 = gen_reg_rtx (SImode);
1727 rtx op1_hi = gen_rtx_SUBREG (HImode, operands[1], 2);
1728 rtx op2_hi = gen_rtx_SUBREG (HImode, operands[2], 2);
1729 rtx t0_hi = gen_rtx_SUBREG (HImode, t0, 2);
1730 rtx t1_hi = gen_rtx_SUBREG (HImode, t1, 2);
1732 rtx insn = emit_insn (gen_lshrsi3 (t0, operands[1], GEN_INT (16)));
1733 emit_insn (gen_lshrsi3 (t1, operands[2], GEN_INT (16)));
1734 emit_insn (gen_umulhisi3 (t2, op1_hi, op2_hi));
1735 emit_insn (gen_mpyh_si (t3, operands[1], operands[2]));
1736 emit_insn (gen_mpyh_si (t4, operands[2], operands[1]));
1737 emit_insn (gen_mpyhh_si (t5, operands[1], operands[2]));
1738 emit_insn (gen_mpys_si (t6, t0_hi, op2_hi));
1739 emit_insn (gen_mpys_si (t7, t1_hi, op1_hi));
1741 /* Gen carry bits (in t9 and t11). */
1742 emit_insn (gen_addsi3 (t8, t2, t3));
1743 emit_insn (gen_cg_si (t9, t2, t3));
1744 emit_insn (gen_cg_si (t11, t8, t4));
1746 /* Gen high 32 bits in operand[0]. Correct for mpys. */
1747 emit_insn (gen_addx_si (t12, t5, t6, t9));
1748 emit_insn (gen_addx_si (t14, t12, t7, t11));
1750 /* mpys treats both operands as signed when we really want it to treat
1751 the first operand as signed and the second operand as unsigned.
1752 The code below corrects for that difference. */
1753 emit_insn (gen_cgt_hi (t15, op1_hi, GEN_INT (-1)));
1754 emit_insn (gen_cgt_hi (t16, op2_hi, GEN_INT (-1)));
1755 emit_insn (gen_andc_hi (t17, t1_hi, t15));
1756 emit_insn (gen_andc_hi (t18, t0_hi, t16));
1757 emit_insn (gen_extendhisi2 (t19, t17));
1758 emit_insn (gen_extendhisi2 (t20, t18));
1759 emit_insn (gen_addsi3 (t21, t19, t20));
1760 emit_insn (gen_addsi3 (operands[0], t14, t21));
1761 unshare_all_rtl_in_chain (insn);
1765 (define_expand "umulsi3_highpart"
1766 [(set (match_operand:SI 0 "register_operand" "")
1769 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
1770 (zero_extend:DI (match_operand:SI 2 "register_operand" "")))
1775 rtx t0 = gen_reg_rtx (SImode);
1776 rtx t1 = gen_reg_rtx (SImode);
1777 rtx t2 = gen_reg_rtx (SImode);
1778 rtx t3 = gen_reg_rtx (SImode);
1779 rtx t4 = gen_reg_rtx (SImode);
1780 rtx t5 = gen_reg_rtx (SImode);
1781 rtx t6 = gen_reg_rtx (SImode);
1782 rtx t7 = gen_reg_rtx (SImode);
1783 rtx t8 = gen_reg_rtx (SImode);
1784 rtx t9 = gen_reg_rtx (SImode);
1785 rtx t10 = gen_reg_rtx (SImode);
1786 rtx t12 = gen_reg_rtx (SImode);
1787 rtx t13 = gen_reg_rtx (SImode);
1788 rtx t14 = gen_reg_rtx (SImode);
1789 rtx op1_hi = gen_rtx_SUBREG (HImode, operands[1], 2);
1790 rtx op2_hi = gen_rtx_SUBREG (HImode, operands[2], 2);
1791 rtx t0_hi = gen_rtx_SUBREG (HImode, t0, 2);
1793 rtx insn = emit_insn (gen_rotlsi3 (t0, operands[2], GEN_INT (16)));
1794 emit_insn (gen_umulhisi3 (t1, op1_hi, op2_hi));
1795 emit_insn (gen_umulhisi3 (t2, op1_hi, t0_hi));
1796 emit_insn (gen_mpyhhu_si (t3, operands[1], t0));
1797 emit_insn (gen_mpyhhu_si (t4, operands[1], operands[2]));
1798 emit_insn (gen_ashlsi3 (t5, t2, GEN_INT (16)));
1799 emit_insn (gen_ashlsi3 (t6, t3, GEN_INT (16)));
1800 emit_insn (gen_lshrsi3 (t7, t2, GEN_INT (16)));
1801 emit_insn (gen_lshrsi3 (t8, t3, GEN_INT (16)));
1803 /* Gen carry bits (in t10 and t12). */
1804 emit_insn (gen_addsi3 (t9, t1, t5));
1805 emit_insn (gen_cg_si (t10, t1, t5));
1806 emit_insn (gen_cg_si (t12, t9, t6));
1808 /* Gen high 32 bits in operand[0]. */
1809 emit_insn (gen_addx_si (t13, t4, t7, t10));
1810 emit_insn (gen_addx_si (t14, t13, t8, t12));
1811 emit_insn (gen_movsi (operands[0], t14));
1812 unshare_all_rtl_in_chain (insn);
1819 ;; Not necessarily the best implementation of divide but faster then
1820 ;; the default that gcc provides because this is inlined and it uses
1822 (define_insn "divmodsi4"
1823 [(set (match_operand:SI 0 "spu_reg_operand" "=&r")
1824 (div:SI (match_operand:SI 1 "spu_reg_operand" "r")
1825 (match_operand:SI 2 "spu_reg_operand" "r")))
1826 (set (match_operand:SI 3 "spu_reg_operand" "=&r")
1827 (mod:SI (match_dup 1)
1829 (clobber (match_scratch:SI 4 "=&r"))
1830 (clobber (match_scratch:SI 5 "=&r"))
1831 (clobber (match_scratch:SI 6 "=&r"))
1832 (clobber (match_scratch:SI 7 "=&r"))
1833 (clobber (match_scratch:SI 8 "=&r"))
1834 (clobber (match_scratch:SI 9 "=&r"))
1835 (clobber (match_scratch:SI 10 "=&r"))
1836 (clobber (match_scratch:SI 11 "=&r"))
1837 (clobber (match_scratch:SI 12 "=&r"))
1838 (clobber (reg:SI 130))]
1846 selb %8,%8,%1,%10\\n\\
1847 selb %9,%9,%2,%11\\n\\
1853 shlqbyi %3,%8,0\\n\\
1854 xor %11,%10,%11\\n\\
1858 1: or %12,%0,%5\\n\\
1859 rotqmbii %5,%5,-1\\n\\
1863 rotqmbii %4,%4,-1\\n\\
1864 selb %0,%12,%0,%6\\n\\
1866 selb %3,%7,%3,%6\\n\\
1870 selb %3,%8,%3,%10\\n\\
1872 [(set_attr "type" "multi0")
1873 (set_attr "length" "128")])
1875 (define_insn "udivmodsi4"
1876 [(set (match_operand:SI 0 "spu_reg_operand" "=&r")
1877 (udiv:SI (match_operand:SI 1 "spu_reg_operand" "r")
1878 (match_operand:SI 2 "spu_reg_operand" "r")))
1879 (set (match_operand:SI 3 "spu_reg_operand" "=&r")
1880 (umod:SI (match_dup 1)
1882 (clobber (match_scratch:SI 4 "=&r"))
1883 (clobber (match_scratch:SI 5 "=&r"))
1884 (clobber (match_scratch:SI 6 "=&r"))
1885 (clobber (match_scratch:SI 7 "=&r"))
1886 (clobber (match_scratch:SI 8 "=&r"))
1887 (clobber (reg:SI 130))]
1900 rotqmbii %5,%5,-1\\n\\
1904 rotqmbii %4,%4,-1\\n\\
1905 selb %0,%8,%0,%6\\n\\
1907 selb %3,%7,%3,%6\\n\\
1910 [(set_attr "type" "multi0")
1911 (set_attr "length" "80")])
1913 (define_expand "div<mode>3"
1915 [(set (match_operand:VSF 0 "spu_reg_operand" "")
1916 (div:VSF (match_operand:VSF 1 "spu_reg_operand" "")
1917 (match_operand:VSF 2 "spu_reg_operand" "")))
1918 (clobber (match_scratch:VSF 3 ""))
1919 (clobber (match_scratch:VSF 4 ""))
1920 (clobber (match_scratch:VSF 5 ""))])]
1924 (define_insn_and_split "*div<mode>3_fast"
1925 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1926 (div:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
1927 (match_operand:VSF 2 "spu_reg_operand" "r")))
1928 (clobber (match_scratch:VSF 3 "=&r"))
1929 (clobber (match_scratch:VSF 4 "=&r"))
1930 (clobber (scratch:VSF))]
1931 "flag_unsafe_math_optimizations"
1934 [(set (match_dup:VSF 0)
1935 (div:VSF (match_dup:VSF 1)
1937 (clobber (match_dup:VSF 3))
1938 (clobber (match_dup:VSF 4))
1939 (clobber (scratch:VSF))]
1941 emit_insn (gen_frest_<mode>(operands[3], operands[2]));
1942 emit_insn (gen_fi_<mode>(operands[3], operands[2], operands[3]));
1943 emit_insn (gen_mul<mode>3(operands[4], operands[1], operands[3]));
1944 emit_insn (gen_fnma<mode>4(operands[0], operands[4], operands[2], operands[1]));
1945 emit_insn (gen_fma<mode>4(operands[0], operands[0], operands[3], operands[4]));
1949 (define_insn_and_split "*div<mode>3_adjusted"
1950 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
1951 (div:VSF (match_operand:VSF 1 "spu_reg_operand" "r")
1952 (match_operand:VSF 2 "spu_reg_operand" "r")))
1953 (clobber (match_scratch:VSF 3 "=&r"))
1954 (clobber (match_scratch:VSF 4 "=&r"))
1955 (clobber (match_scratch:VSF 5 "=&r"))]
1956 "!flag_unsafe_math_optimizations"
1959 [(set (match_dup:VSF 0)
1960 (div:VSF (match_dup:VSF 1)
1962 (clobber (match_dup:VSF 3))
1963 (clobber (match_dup:VSF 4))
1964 (clobber (match_dup:VSF 5))]
1966 emit_insn (gen_frest_<mode> (operands[3], operands[2]));
1967 emit_insn (gen_fi_<mode> (operands[3], operands[2], operands[3]));
1968 emit_insn (gen_mul<mode>3 (operands[4], operands[1], operands[3]));
1969 emit_insn (gen_fnma<mode>4 (operands[5], operands[4], operands[2], operands[1]));
1970 emit_insn (gen_fma<mode>4 (operands[3], operands[5], operands[3], operands[4]));
1972 /* Due to truncation error, the quotient result may be low by 1 ulp.
1973 Conditionally add one if the estimate is too small in magnitude. */
1975 emit_move_insn (gen_lowpart (<F2I>mode, operands[4]),
1976 spu_const (<F2I>mode, 0x80000000ULL));
1977 emit_move_insn (gen_lowpart (<F2I>mode, operands[5]),
1978 spu_const (<F2I>mode, 0x3f800000ULL));
1979 emit_insn (gen_selb (operands[5], operands[5], operands[1], operands[4]));
1981 emit_insn (gen_add<f2i>3 (gen_lowpart (<F2I>mode, operands[4]),
1982 gen_lowpart (<F2I>mode, operands[3]),
1983 spu_const (<F2I>mode, 1)));
1984 emit_insn (gen_fnma<mode>4 (operands[0], operands[2], operands[4], operands[1]));
1985 emit_insn (gen_mul<mode>3 (operands[0], operands[0], operands[5]));
1986 emit_insn (gen_cgt_<f2i> (gen_lowpart (<F2I>mode, operands[0]),
1987 gen_lowpart (<F2I>mode, operands[0]),
1988 spu_const (<F2I>mode, -1)));
1989 emit_insn (gen_selb (operands[0], operands[3], operands[4], operands[0]));
1996 (define_insn_and_split "sqrtsf2"
1997 [(set (match_operand:SF 0 "spu_reg_operand" "=r")
1998 (sqrt:SF (match_operand:SF 1 "spu_reg_operand" "r")))
1999 (clobber (match_scratch:SF 2 "=&r"))
2000 (clobber (match_scratch:SF 3 "=&r"))
2001 (clobber (match_scratch:SF 4 "=&r"))
2002 (clobber (match_scratch:SF 5 "=&r"))]
2006 [(set (match_dup:SF 0)
2007 (sqrt:SF (match_dup:SF 1)))
2008 (clobber (match_dup:SF 2))
2009 (clobber (match_dup:SF 3))
2010 (clobber (match_dup:SF 4))
2011 (clobber (match_dup:SF 5))]
2013 emit_move_insn (operands[3],spu_float_const(\"0.5\",SFmode));
2014 emit_move_insn (operands[4],spu_float_const(\"1.00000011920928955078125\",SFmode));
2015 emit_insn (gen_frsqest_sf(operands[2],operands[1]));
2016 emit_insn (gen_fi_sf(operands[2],operands[1],operands[2]));
2017 emit_insn (gen_mulsf3(operands[5],operands[2],operands[1]));
2018 emit_insn (gen_mulsf3(operands[3],operands[5],operands[3]));
2019 emit_insn (gen_fnmasf4(operands[4],operands[2],operands[5],operands[4]));
2020 emit_insn (gen_fmasf4(operands[0],operands[4],operands[3],operands[5]));
2024 (define_insn "frest_<mode>"
2025 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
2026 (unspec:VSF [(match_operand:VSF 1 "spu_reg_operand" "r")] UNSPEC_FREST))]
2029 [(set_attr "type" "shuf")])
2031 (define_insn "frsqest_<mode>"
2032 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
2033 (unspec:VSF [(match_operand:VSF 1 "spu_reg_operand" "r")] UNSPEC_FRSQEST))]
2036 [(set_attr "type" "shuf")])
2038 (define_insn "fi_<mode>"
2039 [(set (match_operand:VSF 0 "spu_reg_operand" "=r")
2040 (unspec:VSF [(match_operand:VSF 1 "spu_reg_operand" "r")
2041 (match_operand:VSF 2 "spu_reg_operand" "r")] UNSPEC_FI))]
2044 [(set_attr "type" "fp7")])
2049 (define_insn "and<mode>3"
2050 [(set (match_operand:MOV 0 "spu_reg_operand" "=r,r")
2051 (and:MOV (match_operand:MOV 1 "spu_reg_operand" "r,r")
2052 (match_operand:MOV 2 "spu_logical_operand" "r,C")))]
2056 and%j2i\t%0,%1,%J2")
2058 (define_insn "anddi3"
2059 [(set (match_operand:DI 0 "spu_reg_operand" "=r,r")
2060 (and:DI (match_operand:DI 1 "spu_reg_operand" "r,r")
2061 (match_operand:DI 2 "spu_logical_operand" "r,c")))]
2065 and%k2i\t%0,%1,%K2")
2067 (define_insn "andti3"
2068 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2069 (and:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2070 (match_operand:TI 2 "spu_logical_operand" "r,Y")))]
2074 and%m2i\t%0,%1,%L2")
2076 (define_insn "andc_<mode>"
2077 [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
2078 (and:ALL (not:ALL (match_operand:ALL 2 "spu_reg_operand" "r"))
2079 (match_operand:ALL 1 "spu_reg_operand" "r")))]
2083 (define_insn "nand_<mode>"
2084 [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
2085 (not:ALL (and:ALL (match_operand:ALL 2 "spu_reg_operand" "r")
2086 (match_operand:ALL 1 "spu_reg_operand" "r"))))]
2093 (define_insn "ior<mode>3"
2094 [(set (match_operand:MOV 0 "spu_reg_operand" "=r,r,r")
2095 (ior:MOV (match_operand:MOV 1 "spu_reg_operand" "r,r,0")
2096 (match_operand:MOV 2 "spu_ior_operand" "r,C,D")))]
2103 (define_insn "iordi3"
2104 [(set (match_operand:DI 0 "spu_reg_operand" "=r,r,r")
2105 (ior:DI (match_operand:DI 1 "spu_reg_operand" "r,r,0")
2106 (match_operand:DI 2 "spu_ior_operand" "r,c,d")))]
2113 (define_insn "iorti3"
2114 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r,r")
2115 (ior:TI (match_operand:TI 1 "spu_reg_operand" "r,r,0")
2116 (match_operand:TI 2 "spu_ior_operand" "r,Y,Z")))]
2123 (define_insn "orc_<mode>"
2124 [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
2125 (ior:ALL (not:ALL (match_operand:ALL 2 "spu_reg_operand" "r"))
2126 (match_operand:ALL 1 "spu_reg_operand" "r")))]
2130 (define_insn "nor_<mode>"
2131 [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
2132 (not:ALL (ior:ALL (match_operand:ALL 1 "spu_reg_operand" "r")
2133 (match_operand:ALL 2 "spu_reg_operand" "r"))))]
2139 (define_insn "xor<mode>3"
2140 [(set (match_operand:MOV 0 "spu_reg_operand" "=r,r")
2141 (xor:MOV (match_operand:MOV 1 "spu_reg_operand" "r,r")
2142 (match_operand:MOV 2 "spu_logical_operand" "r,B")))]
2146 xor%j2i\t%0,%1,%J2")
2148 (define_insn "xordi3"
2149 [(set (match_operand:DI 0 "spu_reg_operand" "=r,r")
2150 (xor:DI (match_operand:DI 1 "spu_reg_operand" "r,r")
2151 (match_operand:DI 2 "spu_logical_operand" "r,c")))]
2155 xor%k2i\t%0,%1,%K2")
2157 (define_insn "xorti3"
2158 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2159 (xor:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2160 (match_operand:TI 2 "spu_logical_operand" "r,Y")))]
2164 xor%m2i\t%0,%1,%L2")
2166 (define_insn "eqv_<mode>"
2167 [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
2168 (not:ALL (xor:ALL (match_operand:ALL 1 "spu_reg_operand" "r")
2169 (match_operand:ALL 2 "spu_reg_operand" "r"))))]
2175 (define_insn "one_cmpl<mode>2"
2176 [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
2177 (not:ALL (match_operand:ALL 1 "spu_reg_operand" "r")))]
2184 (define_expand "selb"
2185 [(set (match_operand 0 "spu_reg_operand" "")
2186 (unspec [(match_operand 1 "spu_reg_operand" "")
2187 (match_operand 2 "spu_reg_operand" "")
2188 (match_operand 3 "spu_reg_operand" "")] UNSPEC_SELB))]
2191 rtx s = gen__selb (operands[0], operands[1], operands[2], operands[3]);
2192 PUT_MODE (SET_SRC (s), GET_MODE (operands[0]));
2197 ;; This could be defined as a combination of logical operations, but at
2198 ;; one time it caused a crash due to recursive expansion of rtl during CSE.
2199 (define_insn "_selb"
2200 [(set (match_operand 0 "spu_reg_operand" "=r")
2201 (unspec [(match_operand 1 "spu_reg_operand" "r")
2202 (match_operand 2 "spu_reg_operand" "r")
2203 (match_operand 3 "spu_reg_operand" "r")] UNSPEC_SELB))]
2204 "GET_MODE(operands[0]) == GET_MODE(operands[1])
2205 && GET_MODE(operands[1]) == GET_MODE(operands[2])"
2206 "selb\t%0,%1,%2,%3")
2209 ;; Misc. byte/bit operations
2210 ;; clz/ctz/ffs/popcount/parity
2213 (define_insn "clz<mode>2"
2214 [(set (match_operand:VSI 0 "spu_reg_operand" "=r")
2215 (clz:VSI (match_operand:VSI 1 "spu_reg_operand" "r")))]
2219 (define_expand "ctz<mode>2"
2221 (neg:VSI (match_operand:VSI 1 "spu_reg_operand" "")))
2222 (set (match_dup 3) (and:VSI (match_dup 1)
2224 (set (match_dup 4) (clz:VSI (match_dup 3)))
2225 (set (match_operand:VSI 0 "spu_reg_operand" "")
2226 (minus:VSI (match_dup 5) (match_dup 4)))]
2229 operands[2] = gen_reg_rtx (<MODE>mode);
2230 operands[3] = gen_reg_rtx (<MODE>mode);
2231 operands[4] = gen_reg_rtx (<MODE>mode);
2232 operands[5] = spu_const(<MODE>mode, 31);
2235 (define_expand "clrsb<mode>2"
2237 (gt:VSI (match_operand:VSI 1 "spu_reg_operand" "") (match_dup 5)))
2238 (set (match_dup 3) (not:VSI (xor:VSI (match_dup 1) (match_dup 2))))
2239 (set (match_dup 4) (clz:VSI (match_dup 3)))
2240 (set (match_operand:VSI 0 "spu_reg_operand")
2241 (plus:VSI (match_dup 4) (match_dup 5)))]
2244 operands[2] = gen_reg_rtx (<MODE>mode);
2245 operands[3] = gen_reg_rtx (<MODE>mode);
2246 operands[4] = gen_reg_rtx (<MODE>mode);
2247 operands[5] = spu_const(<MODE>mode, -1);
2250 (define_expand "ffs<mode>2"
2252 (neg:VSI (match_operand:VSI 1 "spu_reg_operand" "")))
2253 (set (match_dup 3) (and:VSI (match_dup 1)
2255 (set (match_dup 4) (clz:VSI (match_dup 3)))
2256 (set (match_operand:VSI 0 "spu_reg_operand" "")
2257 (minus:VSI (match_dup 5) (match_dup 4)))]
2260 operands[2] = gen_reg_rtx (<MODE>mode);
2261 operands[3] = gen_reg_rtx (<MODE>mode);
2262 operands[4] = gen_reg_rtx (<MODE>mode);
2263 operands[5] = spu_const(<MODE>mode, 32);
2266 (define_expand "popcountsi2"
2268 (unspec:SI [(match_operand:SI 1 "spu_reg_operand" "")]
2271 (unspec:HI [(match_dup 2)] UNSPEC_SUMB))
2272 (set (match_operand:SI 0 "spu_reg_operand" "")
2273 (sign_extend:SI (match_dup 3)))]
2276 operands[2] = gen_reg_rtx (SImode);
2277 operands[3] = gen_reg_rtx (HImode);
2280 (define_expand "paritysi2"
2281 [(set (match_operand:SI 0 "spu_reg_operand" "")
2282 (parity:SI (match_operand:SI 1 "spu_reg_operand" "")))]
2285 operands[2] = gen_reg_rtx (SImode);
2286 emit_insn (gen_popcountsi2(operands[2], operands[1]));
2287 emit_insn (gen_andsi3(operands[0], operands[2], GEN_INT (1)));
2291 (define_insn "cntb_si"
2292 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2293 (unspec:SI [(match_operand:SI 1 "spu_reg_operand" "r")]
2297 [(set_attr "type" "fxb")])
2299 (define_insn "cntb_v16qi"
2300 [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
2301 (unspec:V16QI [(match_operand:V16QI 1 "spu_reg_operand" "r")]
2305 [(set_attr "type" "fxb")])
2307 (define_insn "sumb_si"
2308 [(set (match_operand:HI 0 "spu_reg_operand" "=r")
2309 (unspec:HI [(match_operand:SI 1 "spu_reg_operand" "r")] UNSPEC_SUMB))]
2312 [(set_attr "type" "fxb")])
2317 (define_insn "<v>ashl<mode>3"
2318 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
2319 (ashift:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
2320 (match_operand:VHSI 2 "spu_nonmem_operand" "r,W")))]
2324 shl<bh>i\t%0,%1,%<umask>2"
2325 [(set_attr "type" "fx3")])
2327 (define_insn_and_split "ashldi3"
2328 [(set (match_operand:DI 0 "spu_reg_operand" "=r,r")
2329 (ashift:DI (match_operand:DI 1 "spu_reg_operand" "r,r")
2330 (match_operand:SI 2 "spu_nonmem_operand" "r,I")))
2331 (clobber (match_scratch:SI 3 "=&r,X"))]
2335 [(set (match_dup:DI 0)
2336 (ashift:DI (match_dup:DI 1)
2339 rtx op0 = gen_rtx_REG (TImode, REGNO (operands[0]));
2340 rtx op1 = gen_rtx_REG (TImode, REGNO (operands[1]));
2341 rtx op2 = operands[2];
2342 rtx op3 = operands[3];
2344 if (GET_CODE (operands[2]) == REG)
2346 emit_insn (gen_addsi3 (op3, op2, GEN_INT (64)));
2347 emit_insn (gen_rotlti3 (op0, op1, GEN_INT (64)));
2348 emit_insn (gen_shlqbybi_ti (op0, op0, op3));
2349 emit_insn (gen_shlqbi_ti (op0, op0, op3));
2353 HOST_WIDE_INT val = INTVAL (operands[2]);
2354 emit_insn (gen_rotlti3 (op0, op1, GEN_INT (64)));
2355 emit_insn (gen_shlqby_ti (op0, op0, GEN_INT (val / 8 + 8)));
2357 emit_insn (gen_shlqbi_ti (op0, op0, GEN_INT (val % 8)));
2362 (define_expand "ashlti3"
2363 [(parallel [(set (match_operand:TI 0 "spu_reg_operand" "")
2364 (ashift:TI (match_operand:TI 1 "spu_reg_operand" "")
2365 (match_operand:SI 2 "spu_nonmem_operand" "")))
2366 (clobber (match_dup:TI 3))])]
2368 "if (GET_CODE (operands[2]) == CONST_INT)
2370 emit_insn (gen_ashlti3_imm(operands[0], operands[1], operands[2]));
2373 operands[3] = gen_reg_rtx (TImode);")
2375 (define_insn_and_split "ashlti3_imm"
2376 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2377 (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2378 (match_operand:SI 2 "immediate_operand" "O,P")))]
2383 "!satisfies_constraint_O (operands[2]) && !satisfies_constraint_P (operands[2])"
2384 [(set (match_dup:TI 0)
2385 (ashift:TI (match_dup:TI 1)
2387 (set (match_dup:TI 0)
2388 (ashift:TI (match_dup:TI 0)
2391 HOST_WIDE_INT val = INTVAL(operands[2]);
2392 operands[3] = GEN_INT (val&7);
2393 operands[4] = GEN_INT (val&-8);
2395 [(set_attr "type" "shuf,shuf")])
2397 (define_insn_and_split "ashlti3_reg"
2398 [(set (match_operand:TI 0 "spu_reg_operand" "=r")
2399 (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r")
2400 (match_operand:SI 2 "spu_reg_operand" "r")))
2401 (clobber (match_operand:TI 3 "spu_reg_operand" "=&r"))]
2405 [(set (match_dup:TI 3)
2406 (ashift:TI (match_dup:TI 1)
2407 (and:SI (match_dup:SI 2)
2409 (set (match_dup:TI 0)
2410 (ashift:TI (match_dup:TI 3)
2411 (and:SI (match_dup:SI 2)
2415 (define_insn "shlqbybi_ti"
2416 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2417 (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2418 (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2424 [(set_attr "type" "shuf,shuf")])
2426 (define_insn "shlqbi_ti"
2427 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2428 (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2429 (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2435 [(set_attr "type" "shuf,shuf")])
2437 (define_insn "shlqby_ti"
2438 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2439 (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2440 (mult:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2446 [(set_attr "type" "shuf,shuf")])
2451 (define_insn_and_split "<v>lshr<mode>3"
2452 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
2453 (lshiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
2454 (match_operand:VHSI 2 "spu_nonmem_operand" "r,W")))
2455 (clobber (match_scratch:VHSI 3 "=&r,X"))]
2459 rot<bh>mi\t%0,%1,-%<umask>2"
2460 "reload_completed && GET_CODE (operands[2]) == REG"
2461 [(set (match_dup:VHSI 3)
2462 (neg:VHSI (match_dup:VHSI 2)))
2463 (set (match_dup:VHSI 0)
2464 (lshiftrt:VHSI (match_dup:VHSI 1)
2465 (neg:VHSI (match_dup:VHSI 3))))]
2467 [(set_attr "type" "*,fx3")])
2469 (define_insn "<v>lshr<mode>3_imm"
2470 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r")
2471 (lshiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r")
2472 (match_operand:VHSI 2 "immediate_operand" "W")))]
2474 "rot<bh>mi\t%0,%1,-%<umask>2"
2475 [(set_attr "type" "fx3")])
2477 (define_insn "rotm_<mode>"
2478 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
2479 (lshiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
2480 (neg:VHSI (match_operand:VHSI 2 "spu_nonmem_operand" "r,W"))))]
2484 rot<bh>mi\t%0,%1,-%<nmask>2"
2485 [(set_attr "type" "fx3")])
2487 (define_insn_and_split "lshr<mode>3"
2488 [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r,r")
2489 (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r,r")
2490 (match_operand:SI 2 "spu_nonmem_operand" "r,O,P")))]
2494 rotqmbyi\t%0,%1,-%h2
2495 rotqmbii\t%0,%1,-%e2"
2496 "REG_P (operands[2]) || (!satisfies_constraint_O (operands[2]) && !satisfies_constraint_P (operands[2]))"
2497 [(set (match_dup:DTI 3)
2498 (lshiftrt:DTI (match_dup:DTI 1)
2500 (set (match_dup:DTI 0)
2501 (lshiftrt:DTI (match_dup:DTI 3)
2504 operands[3] = gen_reg_rtx (<MODE>mode);
2505 if (GET_CODE (operands[2]) == CONST_INT)
2507 HOST_WIDE_INT val = INTVAL(operands[2]);
2508 operands[4] = GEN_INT (val & 7);
2509 operands[5] = GEN_INT (val & -8);
2513 rtx t0 = gen_reg_rtx (SImode);
2514 rtx t1 = gen_reg_rtx (SImode);
2515 emit_insn (gen_subsi3(t0, GEN_INT(0), operands[2]));
2516 emit_insn (gen_subsi3(t1, GEN_INT(7), operands[2]));
2517 operands[4] = gen_rtx_AND (SImode, gen_rtx_NEG (SImode, t0), GEN_INT (7));
2518 operands[5] = gen_rtx_AND (SImode, gen_rtx_NEG (SImode, gen_rtx_AND (SImode, t1, GEN_INT (-8))), GEN_INT (-8));
2521 [(set_attr "type" "*,shuf,shuf")])
2523 (define_expand "shrqbybi_<mode>"
2524 [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
2525 (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
2526 (and:SI (neg:SI (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2531 if (GET_CODE (operands[2]) == CONST_INT)
2532 operands[2] = GEN_INT (7 - INTVAL (operands[2]));
2535 rtx t0 = gen_reg_rtx (SImode);
2536 emit_insn (gen_subsi3 (t0, GEN_INT (7), operands[2]));
2541 (define_insn "rotqmbybi_<mode>"
2542 [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
2543 (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
2544 (and:SI (neg:SI (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2550 rotqmbyi\t%0,%1,-%H2"
2551 [(set_attr "type" "shuf")])
2553 (define_insn_and_split "shrqbi_<mode>"
2554 [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
2555 (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
2556 (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2558 (clobber (match_scratch:SI 3 "=&r,X"))]
2562 [(set (match_dup:DTI 0)
2563 (lshiftrt:DTI (match_dup:DTI 1)
2564 (and:SI (neg:SI (match_dup:SI 3)) (const_int 7))))]
2566 if (GET_CODE (operands[2]) == CONST_INT)
2567 operands[3] = GEN_INT (-INTVAL (operands[2]));
2569 emit_insn (gen_subsi3 (operands[3], GEN_INT (0), operands[2]));
2571 [(set_attr "type" "shuf")])
2573 (define_insn "rotqmbi_<mode>"
2574 [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
2575 (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
2576 (and:SI (neg:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I"))
2581 rotqmbii\t%0,%1,-%E2"
2582 [(set_attr "type" "shuf")])
2584 (define_expand "shrqby_<mode>"
2585 [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
2586 (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
2587 (mult:SI (neg:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I"))
2591 if (GET_CODE (operands[2]) == CONST_INT)
2592 operands[2] = GEN_INT (-INTVAL (operands[2]));
2595 rtx t0 = gen_reg_rtx (SImode);
2596 emit_insn (gen_subsi3 (t0, GEN_INT (0), operands[2]));
2601 (define_insn "rotqmby_<mode>"
2602 [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
2603 (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
2604 (mult:SI (neg:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I"))
2609 rotqmbyi\t%0,%1,-%F2"
2610 [(set_attr "type" "shuf")])
2615 (define_insn_and_split "<v>ashr<mode>3"
2616 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
2617 (ashiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
2618 (match_operand:VHSI 2 "spu_nonmem_operand" "r,W")))
2619 (clobber (match_scratch:VHSI 3 "=&r,X"))]
2623 rotma<bh>i\t%0,%1,-%<umask>2"
2624 "reload_completed && GET_CODE (operands[2]) == REG"
2625 [(set (match_dup:VHSI 3)
2626 (neg:VHSI (match_dup:VHSI 2)))
2627 (set (match_dup:VHSI 0)
2628 (ashiftrt:VHSI (match_dup:VHSI 1)
2629 (neg:VHSI (match_dup:VHSI 3))))]
2631 [(set_attr "type" "*,fx3")])
2633 (define_insn "<v>ashr<mode>3_imm"
2634 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r")
2635 (ashiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r")
2636 (match_operand:VHSI 2 "immediate_operand" "W")))]
2638 "rotma<bh>i\t%0,%1,-%<umask>2"
2639 [(set_attr "type" "fx3")])
2642 (define_insn "rotma_<mode>"
2643 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
2644 (ashiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
2645 (neg:VHSI (match_operand:VHSI 2 "spu_nonmem_operand" "r,W"))))]
2649 rotma<bh>i\t%0,%1,-%<nmask>2"
2650 [(set_attr "type" "fx3")])
2652 (define_insn_and_split "ashrdi3"
2653 [(set (match_operand:DI 0 "spu_reg_operand" "=r,r")
2654 (ashiftrt:DI (match_operand:DI 1 "spu_reg_operand" "r,r")
2655 (match_operand:SI 2 "spu_nonmem_operand" "r,I")))
2656 (clobber (match_scratch:TI 3 "=&r,&r"))
2657 (clobber (match_scratch:TI 4 "=&r,&r"))
2658 (clobber (match_scratch:SI 5 "=&r,&r"))]
2662 [(set (match_dup:DI 0)
2663 (ashiftrt:DI (match_dup:DI 1)
2666 rtx op0 = gen_rtx_REG (TImode, REGNO (operands[0]));
2667 rtx op0v = gen_rtx_REG (V4SImode, REGNO (op0));
2668 rtx op1 = gen_rtx_REG (TImode, REGNO (operands[1]));
2669 rtx op1s = gen_rtx_REG (SImode, REGNO (op1));
2670 rtx op2 = operands[2];
2671 rtx op3 = operands[3];
2672 rtx op4 = operands[4];
2673 rtx op5 = operands[5];
2675 if (GET_CODE (op2) == CONST_INT && INTVAL (op2) >= 63)
2677 rtx op0s = gen_rtx_REG (SImode, REGNO (op0));
2678 emit_insn (gen_ashrsi3 (op0s, op1s, GEN_INT (32)));
2679 emit_insn (gen_spu_fsm (op0v, op0s));
2681 else if (GET_CODE (op2) == CONST_INT && INTVAL (op2) >= 32)
2683 rtx op0d = gen_rtx_REG (V2DImode, REGNO (op0));
2684 HOST_WIDE_INT val = INTVAL (op2);
2685 emit_insn (gen_lshrti3 (op0, op1, GEN_INT (32)));
2686 emit_insn (gen_spu_xswd (op0d, op0v));
2688 emit_insn (gen_vashrv4si3 (op0v, op0v, spu_const (V4SImode, val - 32)));
2692 rtx op3v = gen_rtx_REG (V4SImode, REGNO (op3));
2693 unsigned char arr[16] = {
2694 0xff, 0xff, 0xff, 0xff,
2695 0xff, 0xff, 0xff, 0xff,
2696 0x00, 0x00, 0x00, 0x00,
2697 0x00, 0x00, 0x00, 0x00
2700 emit_insn (gen_ashrsi3 (op5, op1s, GEN_INT (31)));
2701 emit_move_insn (op4, array_to_constant (TImode, arr));
2702 emit_insn (gen_spu_fsm (op3v, op5));
2704 if (GET_CODE (operands[2]) == REG)
2706 emit_insn (gen_selb (op4, op3, op1, op4));
2707 emit_insn (gen_negsi2 (op5, op2));
2708 emit_insn (gen_rotqbybi_ti (op0, op4, op5));
2709 emit_insn (gen_rotqbi_ti (op0, op0, op5));
2713 HOST_WIDE_INT val = -INTVAL (op2);
2714 emit_insn (gen_selb (op0, op3, op1, op4));
2716 emit_insn (gen_rotqby_ti (op0, op0, GEN_INT ((val - 7) / 8)));
2718 emit_insn (gen_rotqbi_ti (op0, op0, GEN_INT (val % 8)));
2725 (define_insn_and_split "ashrti3"
2726 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2727 (ashiftrt:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2728 (match_operand:SI 2 "spu_nonmem_operand" "r,i")))]
2732 [(set (match_dup:TI 0)
2733 (ashiftrt:TI (match_dup:TI 1)
2736 rtx sign_shift = gen_reg_rtx (SImode);
2737 rtx sign_mask = gen_reg_rtx (TImode);
2738 rtx sign_mask_v4si = gen_rtx_SUBREG (V4SImode, sign_mask, 0);
2739 rtx op1_v4si = spu_gen_subreg (V4SImode, operands[1]);
2740 rtx t = gen_reg_rtx (TImode);
2741 emit_insn (gen_subsi3 (sign_shift, GEN_INT (128), force_reg (SImode, operands[2])));
2742 emit_insn (gen_vashrv4si3 (sign_mask_v4si, op1_v4si, spu_const (V4SImode, 31)));
2743 emit_insn (gen_fsm_ti (sign_mask, sign_mask));
2744 emit_insn (gen_ashlti3 (sign_mask, sign_mask, sign_shift));
2745 emit_insn (gen_lshrti3 (t, operands[1], operands[2]));
2746 emit_insn (gen_iorti3 (operands[0], t, sign_mask));
2750 ;; fsm is used after rotam to replicate the sign across the whole register.
2751 (define_insn "fsm_ti"
2752 [(set (match_operand:TI 0 "spu_reg_operand" "=r")
2753 (unspec:TI [(match_operand:TI 1 "spu_reg_operand" "r")] UNSPEC_FSM))]
2756 [(set_attr "type" "shuf")])
2761 (define_insn "<v>rotl<mode>3"
2762 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
2763 (rotate:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
2764 (match_operand:VHSI 2 "spu_nonmem_operand" "r,W")))]
2768 rot<bh>i\t%0,%1,%<umask>2"
2769 [(set_attr "type" "fx3")])
2771 (define_insn "rotlti3"
2772 [(set (match_operand:TI 0 "spu_reg_operand" "=&r,r,r,r")
2773 (rotate:TI (match_operand:TI 1 "spu_reg_operand" "r,r,r,r")
2774 (match_operand:SI 2 "spu_nonmem_operand" "r,O,P,I")))]
2777 rotqbybi\t%0,%1,%2\;rotqbi\t%0,%0,%2
2780 rotqbyi\t%0,%1,%h2\;rotqbii\t%0,%0,%e2"
2781 [(set_attr "length" "8,4,4,8")
2782 (set_attr "type" "multi1,shuf,shuf,multi1")])
2784 (define_insn "rotqbybi_ti"
2785 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2786 (rotate:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2787 (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2793 [(set_attr "type" "shuf,shuf")])
2795 (define_insn "rotqby_ti"
2796 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2797 (rotate:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2798 (mult:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2804 [(set_attr "type" "shuf,shuf")])
2806 (define_insn "rotqbi_ti"
2807 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2808 (rotate:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2809 (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2815 [(set_attr "type" "shuf,shuf")])
2818 ;; struct extract/insert
2819 ;; We handle mem's because GCC will generate invalid SUBREG's
2820 ;; and inefficient code.
2822 (define_expand "extv"
2823 [(set (match_operand:TI 0 "register_operand" "")
2824 (sign_extract:TI (match_operand 1 "nonimmediate_operand" "")
2825 (match_operand:SI 2 "const_int_operand" "")
2826 (match_operand:SI 3 "const_int_operand" "")))]
2829 spu_expand_extv (operands, 0);
2833 (define_expand "extzv"
2834 [(set (match_operand:TI 0 "register_operand" "")
2835 (zero_extract:TI (match_operand 1 "nonimmediate_operand" "")
2836 (match_operand:SI 2 "const_int_operand" "")
2837 (match_operand:SI 3 "const_int_operand" "")))]
2840 spu_expand_extv (operands, 1);
2844 (define_expand "insv"
2845 [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
2846 (match_operand:SI 1 "const_int_operand" "")
2847 (match_operand:SI 2 "const_int_operand" ""))
2848 (match_operand 3 "nonmemory_operand" ""))]
2850 { spu_expand_insv(operands); DONE; })
2852 ;; Simplify a number of patterns that get generated by extv, extzv,
2854 (define_insn_and_split "trunc_shr_ti<mode>"
2855 [(set (match_operand:QHSI 0 "spu_reg_operand" "=r")
2856 (truncate:QHSI (match_operator:TI 2 "shiftrt_operator" [(match_operand:TI 1 "spu_reg_operand" "0")
2863 spu_split_convert (operands);
2866 [(set_attr "type" "convert")
2867 (set_attr "length" "0")])
2869 (define_insn_and_split "trunc_shr_tidi"
2870 [(set (match_operand:DI 0 "spu_reg_operand" "=r")
2871 (truncate:DI (match_operator:TI 2 "shiftrt_operator" [(match_operand:TI 1 "spu_reg_operand" "0")
2878 spu_split_convert (operands);
2881 [(set_attr "type" "convert")
2882 (set_attr "length" "0")])
2884 (define_insn_and_split "shl_ext_<mode>ti"
2885 [(set (match_operand:TI 0 "spu_reg_operand" "=r")
2886 (ashift:TI (match_operator:TI 2 "extend_operator" [(match_operand:QHSI 1 "spu_reg_operand" "0")])
2893 spu_split_convert (operands);
2896 [(set_attr "type" "convert")
2897 (set_attr "length" "0")])
2899 (define_insn_and_split "shl_ext_diti"
2900 [(set (match_operand:TI 0 "spu_reg_operand" "=r")
2901 (ashift:TI (match_operator:TI 2 "extend_operator" [(match_operand:DI 1 "spu_reg_operand" "0")])
2908 spu_split_convert (operands);
2911 [(set_attr "type" "convert")
2912 (set_attr "length" "0")])
2914 (define_insn "sext_trunc_lshr_tiqisi"
2915 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2916 (sign_extend:SI (truncate:QI (match_operator:TI 2 "shiftrt_operator" [(match_operand:TI 1 "spu_reg_operand" "r")
2917 (const_int 120)]))))]
2920 [(set_attr "type" "fx3")])
2922 (define_insn "zext_trunc_lshr_tiqisi"
2923 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2924 (zero_extend:SI (truncate:QI (match_operator:TI 2 "shiftrt_operator" [(match_operand:TI 1 "spu_reg_operand" "r")
2925 (const_int 120)]))))]
2928 [(set_attr "type" "fx3")])
2930 (define_insn "sext_trunc_lshr_tihisi"
2931 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2932 (sign_extend:SI (truncate:HI (match_operator:TI 2 "shiftrt_operator" [(match_operand:TI 1 "spu_reg_operand" "r")
2933 (const_int 112)]))))]
2936 [(set_attr "type" "fx3")])
2938 (define_insn "zext_trunc_lshr_tihisi"
2939 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2940 (zero_extend:SI (truncate:HI (match_operator:TI 2 "shiftrt_operator" [(match_operand:TI 1 "spu_reg_operand" "r")
2941 (const_int 112)]))))]
2944 [(set_attr "type" "fx3")])
2947 ;; String/block move insn.
2948 ;; Argument 0 is the destination
2949 ;; Argument 1 is the source
2950 ;; Argument 2 is the length
2951 ;; Argument 3 is the alignment
2953 (define_expand "movstrsi"
2954 [(parallel [(set (match_operand:BLK 0 "" "")
2955 (match_operand:BLK 1 "" ""))
2956 (use (match_operand:SI 2 "" ""))
2957 (use (match_operand:SI 3 "" ""))])]
2961 if (spu_expand_block_move (operands))
2970 (define_insn "indirect_jump"
2971 [(set (pc) (match_operand:SI 0 "spu_reg_operand" "r"))]
2974 [(set_attr "type" "br")])
2978 (label_ref (match_operand 0 "" "")))]
2981 [(set_attr "type" "br")])
2986 ;; This will be used for leaf functions, that don't save any regs and
2987 ;; don't have locals on stack, maybe... that is for functions that
2988 ;; don't change $sp and don't need to save $lr.
2989 (define_expand "return"
2994 ;; used in spu_expand_epilogue to generate return from a function and
2995 ;; explicitly set use of $lr.
2997 (define_insn "_return"
3001 [(set_attr "type" "br")])
3007 (define_insn "ceq_<mode>"
3008 [(set (match_operand:VQHSI 0 "spu_reg_operand" "=r,r")
3009 (eq:VQHSI (match_operand:VQHSI 1 "spu_reg_operand" "r,r")
3010 (match_operand:VQHSI 2 "spu_arith_operand" "r,B")))]
3014 ceq<bh>i\t%0,%1,%2")
3016 (define_insn_and_split "ceq_di"
3017 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3018 (eq:SI (match_operand:DI 1 "spu_reg_operand" "r")
3019 (match_operand:DI 2 "spu_reg_operand" "r")))]
3023 [(set (match_dup:SI 0)
3024 (eq:SI (match_dup:DI 1)
3027 rtx op0 = gen_rtx_REG (V4SImode, REGNO (operands[0]));
3028 rtx op1 = gen_rtx_REG (V4SImode, REGNO (operands[1]));
3029 rtx op2 = gen_rtx_REG (V4SImode, REGNO (operands[2]));
3030 emit_insn (gen_ceq_v4si (op0, op1, op2));
3031 emit_insn (gen_spu_gb (op0, op0));
3032 emit_insn (gen_cgt_si (operands[0], operands[0], GEN_INT (11)));
3037 ;; We provide the TI compares for completeness and because some parts of
3038 ;; gcc/libgcc use them, even though user code might never see it.
3039 (define_insn "ceq_ti"
3040 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3041 (eq:SI (match_operand:TI 1 "spu_reg_operand" "r")
3042 (match_operand:TI 2 "spu_reg_operand" "r")))]
3044 "ceq\t%0,%1,%2\;gb\t%0,%0\;ceqi\t%0,%0,15"
3045 [(set_attr "type" "multi0")
3046 (set_attr "length" "12")])
3048 (define_insn "ceq_<mode>"
3049 [(set (match_operand:<F2I> 0 "spu_reg_operand" "=r")
3050 (eq:<F2I> (match_operand:VSF 1 "spu_reg_operand" "r")
3051 (match_operand:VSF 2 "spu_reg_operand" "r")))]
3055 (define_insn "cmeq_<mode>"
3056 [(set (match_operand:<F2I> 0 "spu_reg_operand" "=r")
3057 (eq:<F2I> (abs:VSF (match_operand:VSF 1 "spu_reg_operand" "r"))
3058 (abs:VSF (match_operand:VSF 2 "spu_reg_operand" "r"))))]
3062 ;; These implementations will ignore checking of NaN or INF if
3063 ;; compiled with option -ffinite-math-only.
3064 (define_expand "ceq_df"
3065 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3066 (eq:SI (match_operand:DF 1 "spu_reg_operand" "r")
3067 (match_operand:DF 2 "const_zero_operand" "i")))]
3070 if (spu_arch == PROCESSOR_CELL)
3072 rtx ra = gen_reg_rtx (V4SImode);
3073 rtx rb = gen_reg_rtx (V4SImode);
3074 rtx temp = gen_reg_rtx (TImode);
3075 rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
3076 rtx temp2 = gen_reg_rtx (V4SImode);
3077 rtx biteq = gen_reg_rtx (V4SImode);
3078 rtx ahi_inf = gen_reg_rtx (V4SImode);
3079 rtx a_nan = gen_reg_rtx (V4SImode);
3080 rtx a_abs = gen_reg_rtx (V4SImode);
3081 rtx b_abs = gen_reg_rtx (V4SImode);
3082 rtx iszero = gen_reg_rtx (V4SImode);
3083 rtx sign_mask = gen_reg_rtx (V4SImode);
3084 rtx nan_mask = gen_reg_rtx (V4SImode);
3085 rtx hihi_promote = gen_reg_rtx (TImode);
3086 rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF,
3087 0x7FFFFFFF, 0xFFFFFFFF);
3089 emit_move_insn (sign_mask, pat);
3090 pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0,
3092 emit_move_insn (nan_mask, pat);
3093 pat = spu_const_from_ints (TImode, 0x00010203, 0x10111213,
3094 0x08090A0B, 0x18191A1B);
3095 emit_move_insn (hihi_promote, pat);
3097 emit_insn (gen_spu_convert (ra, operands[1]));
3098 emit_insn (gen_spu_convert (rb, operands[2]));
3099 emit_insn (gen_ceq_v4si (biteq, ra, rb));
3100 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, biteq),
3102 emit_insn (gen_andv4si3 (biteq, biteq, temp_v4si));
3104 emit_insn (gen_andv4si3 (a_abs, ra, sign_mask));
3105 emit_insn (gen_andv4si3 (b_abs, rb, sign_mask));
3106 if (!flag_finite_math_only)
3108 emit_insn (gen_clgt_v4si (a_nan, a_abs, nan_mask));
3109 emit_insn (gen_ceq_v4si (ahi_inf, a_abs, nan_mask));
3110 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, a_nan),
3112 emit_insn (gen_andv4si3 (temp2, temp_v4si, ahi_inf));
3113 emit_insn (gen_iorv4si3 (a_nan, a_nan, temp2));
3115 emit_insn (gen_iorv4si3 (temp2, a_abs, b_abs));
3116 emit_insn (gen_ceq_v4si (iszero, temp2, CONST0_RTX (V4SImode)));
3117 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, iszero),
3119 emit_insn (gen_andv4si3 (iszero, iszero, temp_v4si));
3120 emit_insn (gen_iorv4si3 (temp2, biteq, iszero));
3121 if (!flag_finite_math_only)
3123 emit_insn (gen_andc_v4si (temp2, temp2, a_nan));
3125 emit_insn (gen_shufb (operands[0], temp2, temp2, hihi_promote));
3130 (define_insn "ceq_<mode>_celledp"
3131 [(set (match_operand:<DF2I> 0 "spu_reg_operand" "=r")
3132 (eq:<DF2I> (match_operand:VDF 1 "spu_reg_operand" "r")
3133 (match_operand:VDF 2 "spu_reg_operand" "r")))]
3134 "spu_arch == PROCESSOR_CELLEDP"
3136 [(set_attr "type" "fpd")])
3138 (define_insn "cmeq_<mode>_celledp"
3139 [(set (match_operand:<DF2I> 0 "spu_reg_operand" "=r")
3140 (eq:<DF2I> (abs:VDF (match_operand:VDF 1 "spu_reg_operand" "r"))
3141 (abs:VDF (match_operand:VDF 2 "spu_reg_operand" "r"))))]
3142 "spu_arch == PROCESSOR_CELLEDP"
3144 [(set_attr "type" "fpd")])
3146 (define_expand "ceq_v2df"
3147 [(set (match_operand:V2DI 0 "spu_reg_operand" "=r")
3148 (eq:V2DI (match_operand:V2DF 1 "spu_reg_operand" "r")
3149 (match_operand:V2DF 2 "spu_reg_operand" "r")))]
3152 if (spu_arch == PROCESSOR_CELL)
3154 rtx ra = spu_gen_subreg (V4SImode, operands[1]);
3155 rtx rb = spu_gen_subreg (V4SImode, operands[2]);
3156 rtx temp = gen_reg_rtx (TImode);
3157 rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
3158 rtx temp2 = gen_reg_rtx (V4SImode);
3159 rtx biteq = gen_reg_rtx (V4SImode);
3160 rtx ahi_inf = gen_reg_rtx (V4SImode);
3161 rtx a_nan = gen_reg_rtx (V4SImode);
3162 rtx a_abs = gen_reg_rtx (V4SImode);
3163 rtx b_abs = gen_reg_rtx (V4SImode);
3164 rtx iszero = gen_reg_rtx (V4SImode);
3165 rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF,
3166 0x7FFFFFFF, 0xFFFFFFFF);
3167 rtx sign_mask = gen_reg_rtx (V4SImode);
3168 rtx nan_mask = gen_reg_rtx (V4SImode);
3169 rtx hihi_promote = gen_reg_rtx (TImode);
3171 emit_move_insn (sign_mask, pat);
3172 pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0,
3174 emit_move_insn (nan_mask, pat);
3175 pat = spu_const_from_ints (TImode, 0x00010203, 0x10111213,
3176 0x08090A0B, 0x18191A1B);
3177 emit_move_insn (hihi_promote, pat);
3179 emit_insn (gen_ceq_v4si (biteq, ra, rb));
3180 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, biteq),
3182 emit_insn (gen_andv4si3 (biteq, biteq, temp_v4si));
3183 emit_insn (gen_andv4si3 (a_abs, ra, sign_mask));
3184 emit_insn (gen_andv4si3 (b_abs, rb, sign_mask));
3185 emit_insn (gen_clgt_v4si (a_nan, a_abs, nan_mask));
3186 emit_insn (gen_ceq_v4si (ahi_inf, a_abs, nan_mask));
3187 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, a_nan),
3189 emit_insn (gen_andv4si3 (temp2, temp_v4si, ahi_inf));
3190 emit_insn (gen_iorv4si3 (a_nan, a_nan, temp2));
3191 emit_insn (gen_iorv4si3 (temp2, a_abs, b_abs));
3192 emit_insn (gen_ceq_v4si (iszero, temp2, CONST0_RTX (V4SImode)));
3193 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, iszero),
3195 emit_insn (gen_andv4si3 (iszero, iszero, temp_v4si));
3196 emit_insn (gen_iorv4si3 (temp2, biteq, iszero));
3197 emit_insn (gen_andc_v4si (temp2, temp2, a_nan));
3198 emit_insn (gen_shufb (operands[0], temp2, temp2, hihi_promote));
3203 (define_expand "cmeq_v2df"
3204 [(set (match_operand:V2DI 0 "spu_reg_operand" "=r")
3205 (eq:V2DI (abs:V2DF (match_operand:V2DF 1 "spu_reg_operand" "r"))
3206 (abs:V2DF (match_operand:V2DF 2 "spu_reg_operand" "r"))))]
3209 if (spu_arch == PROCESSOR_CELL)
3211 rtx ra = spu_gen_subreg (V4SImode, operands[1]);
3212 rtx rb = spu_gen_subreg (V4SImode, operands[2]);
3213 rtx temp = gen_reg_rtx (TImode);
3214 rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
3215 rtx temp2 = gen_reg_rtx (V4SImode);
3216 rtx biteq = gen_reg_rtx (V4SImode);
3217 rtx ahi_inf = gen_reg_rtx (V4SImode);
3218 rtx a_nan = gen_reg_rtx (V4SImode);
3219 rtx a_abs = gen_reg_rtx (V4SImode);
3220 rtx b_abs = gen_reg_rtx (V4SImode);
3222 rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF,
3223 0x7FFFFFFF, 0xFFFFFFFF);
3224 rtx sign_mask = gen_reg_rtx (V4SImode);
3225 rtx nan_mask = gen_reg_rtx (V4SImode);
3226 rtx hihi_promote = gen_reg_rtx (TImode);
3228 emit_move_insn (sign_mask, pat);
3230 pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0,
3232 emit_move_insn (nan_mask, pat);
3233 pat = spu_const_from_ints (TImode, 0x00010203, 0x10111213,
3234 0x08090A0B, 0x18191A1B);
3235 emit_move_insn (hihi_promote, pat);
3237 emit_insn (gen_andv4si3 (a_abs, ra, sign_mask));
3238 emit_insn (gen_andv4si3 (b_abs, rb, sign_mask));
3239 emit_insn (gen_ceq_v4si (biteq, a_abs, b_abs));
3240 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, biteq),
3242 emit_insn (gen_andv4si3 (biteq, biteq, temp_v4si));
3243 emit_insn (gen_clgt_v4si (a_nan, a_abs, nan_mask));
3244 emit_insn (gen_ceq_v4si (ahi_inf, a_abs, nan_mask));
3245 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, a_nan),
3247 emit_insn (gen_andv4si3 (temp2, temp_v4si, ahi_inf));
3248 emit_insn (gen_iorv4si3 (a_nan, a_nan, temp2));
3249 emit_insn (gen_andc_v4si (temp2, biteq, a_nan));
3250 emit_insn (gen_shufb (operands[0], temp2, temp2, hihi_promote));
3258 (define_insn "cgt_<mode>"
3259 [(set (match_operand:VQHSI 0 "spu_reg_operand" "=r,r")
3260 (gt:VQHSI (match_operand:VQHSI 1 "spu_reg_operand" "r,r")
3261 (match_operand:VQHSI 2 "spu_arith_operand" "r,B")))]
3265 cgt<bh>i\t%0,%1,%2")
3267 (define_insn "cgt_di_m1"
3268 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3269 (gt:SI (match_operand:DI 1 "spu_reg_operand" "r")
3274 (define_insn_and_split "cgt_di"
3275 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3276 (gt:SI (match_operand:DI 1 "spu_reg_operand" "r")
3277 (match_operand:DI 2 "spu_reg_operand" "r")))
3278 (clobber (match_scratch:V4SI 3 "=&r"))
3279 (clobber (match_scratch:V4SI 4 "=&r"))
3280 (clobber (match_scratch:V4SI 5 "=&r"))]
3284 [(set (match_dup:SI 0)
3285 (gt:SI (match_dup:DI 1)
3288 rtx op0 = gen_rtx_REG (V4SImode, REGNO (operands[0]));
3289 rtx op1 = gen_rtx_REG (V4SImode, REGNO (operands[1]));
3290 rtx op2 = gen_rtx_REG (V4SImode, REGNO (operands[2]));
3291 rtx op3 = operands[3];
3292 rtx op4 = operands[4];
3293 rtx op5 = operands[5];
3294 rtx op3d = gen_rtx_REG (V2DImode, REGNO (operands[3]));
3295 emit_insn (gen_clgt_v4si (op3, op1, op2));
3296 emit_insn (gen_ceq_v4si (op4, op1, op2));
3297 emit_insn (gen_cgt_v4si (op5, op1, op2));
3298 emit_insn (gen_spu_xswd (op3d, op3));
3299 emit_insn (gen_selb (op0, op5, op3, op4));
3303 (define_insn "cgt_ti_m1"
3304 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3305 (gt:SI (match_operand:TI 1 "spu_reg_operand" "r")
3310 (define_insn "cgt_ti"
3311 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3312 (gt:SI (match_operand:TI 1 "spu_reg_operand" "r")
3313 (match_operand:TI 2 "spu_reg_operand" "r")))
3314 (clobber (match_scratch:V4SI 3 "=&r"))
3315 (clobber (match_scratch:V4SI 4 "=&r"))
3316 (clobber (match_scratch:V4SI 5 "=&r"))]
3322 selb\t%0,%4,%0,%3\;\
3324 selb\t%0,%4,%0,%3\;\
3327 [(set_attr "type" "multi0")
3328 (set_attr "length" "36")])
3330 (define_insn "cgt_<mode>"
3331 [(set (match_operand:<F2I> 0 "spu_reg_operand" "=r")
3332 (gt:<F2I> (match_operand:VSF 1 "spu_reg_operand" "r")
3333 (match_operand:VSF 2 "spu_reg_operand" "r")))]
3337 (define_insn "cmgt_<mode>"
3338 [(set (match_operand:<F2I> 0 "spu_reg_operand" "=r")
3339 (gt:<F2I> (abs:VSF (match_operand:VSF 1 "spu_reg_operand" "r"))
3340 (abs:VSF (match_operand:VSF 2 "spu_reg_operand" "r"))))]
3344 (define_expand "cgt_df"
3345 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3346 (gt:SI (match_operand:DF 1 "spu_reg_operand" "r")
3347 (match_operand:DF 2 "const_zero_operand" "i")))]
3350 if (spu_arch == PROCESSOR_CELL)
3352 rtx ra = gen_reg_rtx (V4SImode);
3353 rtx rb = gen_reg_rtx (V4SImode);
3354 rtx zero = gen_reg_rtx (V4SImode);
3355 rtx temp = gen_reg_rtx (TImode);
3356 rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
3357 rtx temp2 = gen_reg_rtx (V4SImode);
3358 rtx hi_inf = gen_reg_rtx (V4SImode);
3359 rtx a_nan = gen_reg_rtx (V4SImode);
3360 rtx b_nan = gen_reg_rtx (V4SImode);
3361 rtx a_abs = gen_reg_rtx (V4SImode);
3362 rtx b_abs = gen_reg_rtx (V4SImode);
3363 rtx asel = gen_reg_rtx (V4SImode);
3364 rtx bsel = gen_reg_rtx (V4SImode);
3365 rtx abor = gen_reg_rtx (V4SImode);
3366 rtx bbor = gen_reg_rtx (V4SImode);
3367 rtx gt_hi = gen_reg_rtx (V4SImode);
3368 rtx gt_lo = gen_reg_rtx (V4SImode);
3369 rtx sign_mask = gen_reg_rtx (V4SImode);
3370 rtx nan_mask = gen_reg_rtx (V4SImode);
3371 rtx hi_promote = gen_reg_rtx (TImode);
3372 rtx borrow_shuffle = gen_reg_rtx (TImode);
3374 rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF,
3375 0x7FFFFFFF, 0xFFFFFFFF);
3376 emit_move_insn (sign_mask, pat);
3377 pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0,
3379 emit_move_insn (nan_mask, pat);
3380 pat = spu_const_from_ints (TImode, 0x00010203, 0x00010203,
3381 0x08090A0B, 0x08090A0B);
3382 emit_move_insn (hi_promote, pat);
3383 pat = spu_const_from_ints (TImode, 0x04050607, 0xC0C0C0C0,
3384 0x0C0D0E0F, 0xC0C0C0C0);
3385 emit_move_insn (borrow_shuffle, pat);
3387 emit_insn (gen_spu_convert (ra, operands[1]));
3388 emit_insn (gen_spu_convert (rb, operands[2]));
3389 emit_insn (gen_andv4si3 (a_abs, ra, sign_mask));
3390 emit_insn (gen_andv4si3 (b_abs, rb, sign_mask));
3392 if (!flag_finite_math_only)
3394 /* check if ra is NaN */
3395 emit_insn (gen_ceq_v4si (hi_inf, a_abs, nan_mask));
3396 emit_insn (gen_clgt_v4si (a_nan, a_abs, nan_mask));
3397 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, a_nan),
3399 emit_insn (gen_andv4si3 (temp2, temp_v4si, hi_inf));
3400 emit_insn (gen_iorv4si3 (a_nan, a_nan, temp2));
3401 emit_insn (gen_shufb (a_nan, a_nan, a_nan, hi_promote));
3403 /* check if rb is NaN */
3404 emit_insn (gen_ceq_v4si (hi_inf, b_abs, nan_mask));
3405 emit_insn (gen_clgt_v4si (b_nan, b_abs, nan_mask));
3406 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, b_nan),
3408 emit_insn (gen_andv4si3 (temp2, temp_v4si, hi_inf));
3409 emit_insn (gen_iorv4si3 (b_nan, b_nan, temp2));
3410 emit_insn (gen_shufb (b_nan, b_nan, b_nan, hi_promote));
3412 /* check if ra or rb is NaN */
3413 emit_insn (gen_iorv4si3 (a_nan, a_nan, b_nan));
3415 emit_move_insn (zero, CONST0_RTX (V4SImode));
3416 emit_insn (gen_vashrv4si3 (asel, ra, spu_const (V4SImode, 31)));
3417 emit_insn (gen_shufb (asel, asel, asel, hi_promote));
3418 emit_insn (gen_bg_v4si (abor, zero, a_abs));
3419 emit_insn (gen_shufb (abor, abor, abor, borrow_shuffle));
3420 emit_insn (gen_sfx_v4si (abor, zero, a_abs, abor));
3421 emit_insn (gen_selb (abor, a_abs, abor, asel));
3423 emit_insn (gen_vashrv4si3 (bsel, rb, spu_const (V4SImode, 31)));
3424 emit_insn (gen_shufb (bsel, bsel, bsel, hi_promote));
3425 emit_insn (gen_bg_v4si (bbor, zero, b_abs));
3426 emit_insn (gen_shufb (bbor, bbor, bbor, borrow_shuffle));
3427 emit_insn (gen_sfx_v4si (bbor, zero, b_abs, bbor));
3428 emit_insn (gen_selb (bbor, b_abs, bbor, bsel));
3430 emit_insn (gen_cgt_v4si (gt_hi, abor, bbor));
3431 emit_insn (gen_clgt_v4si (gt_lo, abor, bbor));
3432 emit_insn (gen_ceq_v4si (temp2, abor, bbor));
3433 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, gt_lo),
3435 emit_insn (gen_andv4si3 (temp2, temp2, temp_v4si));
3436 emit_insn (gen_iorv4si3 (temp2, gt_hi, temp2));
3437 emit_insn (gen_shufb (temp2, temp2, temp2, hi_promote));
3438 if (!flag_finite_math_only)
3440 /* correct for NaNs */
3441 emit_insn (gen_andc_v4si (temp2, temp2, a_nan));
3443 emit_insn (gen_spu_convert (operands[0], temp2));
3448 (define_insn "cgt_<mode>_celledp"
3449 [(set (match_operand:<DF2I> 0 "spu_reg_operand" "=r")
3450 (gt:<DF2I> (match_operand:VDF 1 "spu_reg_operand" "r")
3451 (match_operand:VDF 2 "spu_reg_operand" "r")))]
3452 "spu_arch == PROCESSOR_CELLEDP"
3454 [(set_attr "type" "fpd")])
3456 (define_insn "cmgt_<mode>_celledp"
3457 [(set (match_operand:<DF2I> 0 "spu_reg_operand" "=r")
3458 (gt:<DF2I> (abs:VDF (match_operand:VDF 1 "spu_reg_operand" "r"))
3459 (abs:VDF (match_operand:VDF 2 "spu_reg_operand" "r"))))]
3460 "spu_arch == PROCESSOR_CELLEDP"
3462 [(set_attr "type" "fpd")])
3464 (define_expand "cgt_v2df"
3465 [(set (match_operand:V2DI 0 "spu_reg_operand" "=r")
3466 (gt:V2DI (match_operand:V2DF 1 "spu_reg_operand" "r")
3467 (match_operand:V2DF 2 "spu_reg_operand" "r")))]
3470 if (spu_arch == PROCESSOR_CELL)
3472 rtx ra = spu_gen_subreg (V4SImode, operands[1]);
3473 rtx rb = spu_gen_subreg (V4SImode, operands[2]);
3474 rtx zero = gen_reg_rtx (V4SImode);
3475 rtx temp = gen_reg_rtx (TImode);
3476 rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
3477 rtx temp2 = gen_reg_rtx (V4SImode);
3478 rtx hi_inf = gen_reg_rtx (V4SImode);
3479 rtx a_nan = gen_reg_rtx (V4SImode);
3480 rtx b_nan = gen_reg_rtx (V4SImode);
3481 rtx a_abs = gen_reg_rtx (V4SImode);
3482 rtx b_abs = gen_reg_rtx (V4SImode);
3483 rtx asel = gen_reg_rtx (V4SImode);
3484 rtx bsel = gen_reg_rtx (V4SImode);
3485 rtx abor = gen_reg_rtx (V4SImode);
3486 rtx bbor = gen_reg_rtx (V4SImode);
3487 rtx gt_hi = gen_reg_rtx (V4SImode);
3488 rtx gt_lo = gen_reg_rtx (V4SImode);
3489 rtx sign_mask = gen_reg_rtx (V4SImode);
3490 rtx nan_mask = gen_reg_rtx (V4SImode);
3491 rtx hi_promote = gen_reg_rtx (TImode);
3492 rtx borrow_shuffle = gen_reg_rtx (TImode);
3493 rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF,
3494 0x7FFFFFFF, 0xFFFFFFFF);
3495 emit_move_insn (sign_mask, pat);
3496 pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0,
3498 emit_move_insn (nan_mask, pat);
3499 pat = spu_const_from_ints (TImode, 0x00010203, 0x00010203,
3500 0x08090A0B, 0x08090A0B);
3501 emit_move_insn (hi_promote, pat);
3502 pat = spu_const_from_ints (TImode, 0x04050607, 0xC0C0C0C0,
3503 0x0C0D0E0F, 0xC0C0C0C0);
3504 emit_move_insn (borrow_shuffle, pat);
3506 emit_insn (gen_andv4si3 (a_abs, ra, sign_mask));
3507 emit_insn (gen_ceq_v4si (hi_inf, a_abs, nan_mask));
3508 emit_insn (gen_clgt_v4si (a_nan, a_abs, nan_mask));
3509 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, a_nan),
3511 emit_insn (gen_andv4si3 (temp2, temp_v4si, hi_inf));
3512 emit_insn (gen_iorv4si3 (a_nan, a_nan, temp2));
3513 emit_insn (gen_shufb (a_nan, a_nan, a_nan, hi_promote));
3514 emit_insn (gen_andv4si3 (b_abs, rb, sign_mask));
3515 emit_insn (gen_ceq_v4si (hi_inf, b_abs, nan_mask));
3516 emit_insn (gen_clgt_v4si (b_nan, b_abs, nan_mask));
3517 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, b_nan),
3519 emit_insn (gen_andv4si3 (temp2, temp_v4si, hi_inf));
3520 emit_insn (gen_iorv4si3 (b_nan, b_nan, temp2));
3521 emit_insn (gen_shufb (b_nan, b_nan, b_nan, hi_promote));
3522 emit_insn (gen_iorv4si3 (a_nan, a_nan, b_nan));
3523 emit_move_insn (zero, CONST0_RTX (V4SImode));
3524 emit_insn (gen_vashrv4si3 (asel, ra, spu_const (V4SImode, 31)));
3525 emit_insn (gen_shufb (asel, asel, asel, hi_promote));
3526 emit_insn (gen_bg_v4si (abor, zero, a_abs));
3527 emit_insn (gen_shufb (abor, abor, abor, borrow_shuffle));
3528 emit_insn (gen_sfx_v4si (abor, zero, a_abs, abor));
3529 emit_insn (gen_selb (abor, a_abs, abor, asel));
3530 emit_insn (gen_vashrv4si3 (bsel, rb, spu_const (V4SImode, 31)));
3531 emit_insn (gen_shufb (bsel, bsel, bsel, hi_promote));
3532 emit_insn (gen_bg_v4si (bbor, zero, b_abs));
3533 emit_insn (gen_shufb (bbor, bbor, bbor, borrow_shuffle));
3534 emit_insn (gen_sfx_v4si (bbor, zero, b_abs, bbor));
3535 emit_insn (gen_selb (bbor, b_abs, bbor, bsel));
3536 emit_insn (gen_cgt_v4si (gt_hi, abor, bbor));
3537 emit_insn (gen_clgt_v4si (gt_lo, abor, bbor));
3538 emit_insn (gen_ceq_v4si (temp2, abor, bbor));
3539 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, gt_lo),
3541 emit_insn (gen_andv4si3 (temp2, temp2, temp_v4si));
3542 emit_insn (gen_iorv4si3 (temp2, gt_hi, temp2));
3544 emit_insn (gen_shufb (temp2, temp2, temp2, hi_promote));
3545 emit_insn (gen_andc_v4si (temp2, temp2, a_nan));
3546 emit_move_insn (operands[0], spu_gen_subreg (V2DImode, temp2));
3551 (define_expand "cmgt_v2df"
3552 [(set (match_operand:V2DI 0 "spu_reg_operand" "=r")
3553 (gt:V2DI (abs:V2DF (match_operand:V2DF 1 "spu_reg_operand" "r"))
3554 (abs:V2DF (match_operand:V2DF 2 "spu_reg_operand" "r"))))]
3557 if (spu_arch == PROCESSOR_CELL)
3559 rtx ra = spu_gen_subreg (V4SImode, operands[1]);
3560 rtx rb = spu_gen_subreg (V4SImode, operands[2]);
3561 rtx temp = gen_reg_rtx (TImode);
3562 rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
3563 rtx temp2 = gen_reg_rtx (V4SImode);
3564 rtx hi_inf = gen_reg_rtx (V4SImode);
3565 rtx a_nan = gen_reg_rtx (V4SImode);
3566 rtx b_nan = gen_reg_rtx (V4SImode);
3567 rtx a_abs = gen_reg_rtx (V4SImode);
3568 rtx b_abs = gen_reg_rtx (V4SImode);
3569 rtx gt_hi = gen_reg_rtx (V4SImode);
3570 rtx gt_lo = gen_reg_rtx (V4SImode);
3571 rtx sign_mask = gen_reg_rtx (V4SImode);
3572 rtx nan_mask = gen_reg_rtx (V4SImode);
3573 rtx hi_promote = gen_reg_rtx (TImode);
3574 rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF,
3575 0x7FFFFFFF, 0xFFFFFFFF);
3576 emit_move_insn (sign_mask, pat);
3577 pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0,
3579 emit_move_insn (nan_mask, pat);
3580 pat = spu_const_from_ints (TImode, 0x00010203, 0x00010203,
3581 0x08090A0B, 0x08090A0B);
3582 emit_move_insn (hi_promote, pat);
3584 emit_insn (gen_andv4si3 (a_abs, ra, sign_mask));
3585 emit_insn (gen_ceq_v4si (hi_inf, a_abs, nan_mask));
3586 emit_insn (gen_clgt_v4si (a_nan, a_abs, nan_mask));
3587 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, a_nan),
3589 emit_insn (gen_andv4si3 (temp2, temp_v4si, hi_inf));
3590 emit_insn (gen_iorv4si3 (a_nan, a_nan, temp2));
3591 emit_insn (gen_shufb (a_nan, a_nan, a_nan, hi_promote));
3592 emit_insn (gen_andv4si3 (b_abs, rb, sign_mask));
3593 emit_insn (gen_ceq_v4si (hi_inf, b_abs, nan_mask));
3594 emit_insn (gen_clgt_v4si (b_nan, b_abs, nan_mask));
3595 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, b_nan),
3597 emit_insn (gen_andv4si3 (temp2, temp_v4si, hi_inf));
3598 emit_insn (gen_iorv4si3 (b_nan, b_nan, temp2));
3599 emit_insn (gen_shufb (b_nan, b_nan, b_nan, hi_promote));
3600 emit_insn (gen_iorv4si3 (a_nan, a_nan, b_nan));
3602 emit_insn (gen_clgt_v4si (gt_hi, a_abs, b_abs));
3603 emit_insn (gen_clgt_v4si (gt_lo, a_abs, b_abs));
3604 emit_insn (gen_ceq_v4si (temp2, a_abs, b_abs));
3605 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, gt_lo),
3607 emit_insn (gen_andv4si3 (temp2, temp2, temp_v4si));
3608 emit_insn (gen_iorv4si3 (temp2, gt_hi, temp2));
3609 emit_insn (gen_shufb (temp2, temp2, temp2, hi_promote));
3610 emit_insn (gen_andc_v4si (temp2, temp2, a_nan));
3611 emit_move_insn (operands[0], spu_gen_subreg (V2DImode, temp2));
3619 (define_insn "clgt_<mode>"
3620 [(set (match_operand:VQHSI 0 "spu_reg_operand" "=r,r")
3621 (gtu:VQHSI (match_operand:VQHSI 1 "spu_reg_operand" "r,r")
3622 (match_operand:VQHSI 2 "spu_arith_operand" "r,B")))]
3626 clgt<bh>i\t%0,%1,%2")
3628 (define_insn_and_split "clgt_di"
3629 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3630 (gtu:SI (match_operand:DI 1 "spu_reg_operand" "r")
3631 (match_operand:DI 2 "spu_reg_operand" "r")))
3632 (clobber (match_scratch:V4SI 3 "=&r"))
3633 (clobber (match_scratch:V4SI 4 "=&r"))
3634 (clobber (match_scratch:V4SI 5 "=&r"))]
3638 [(set (match_dup:SI 0)
3639 (gtu:SI (match_dup:DI 1)
3642 rtx op0 = gen_rtx_REG (V4SImode, REGNO (operands[0]));
3643 rtx op1 = gen_rtx_REG (V4SImode, REGNO (operands[1]));
3644 rtx op2 = gen_rtx_REG (V4SImode, REGNO (operands[2]));
3645 rtx op3 = operands[3];
3646 rtx op4 = operands[4];
3647 rtx op5 = operands[5];
3648 rtx op5d = gen_rtx_REG (V2DImode, REGNO (operands[5]));
3649 emit_insn (gen_clgt_v4si (op3, op1, op2));
3650 emit_insn (gen_ceq_v4si (op4, op1, op2));
3651 emit_insn (gen_spu_xswd (op5d, op3));
3652 emit_insn (gen_selb (op0, op3, op5, op4));
3656 (define_insn "clgt_ti"
3657 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3658 (gtu:SI (match_operand:TI 1 "spu_reg_operand" "r")
3659 (match_operand:TI 2 "spu_reg_operand" "r")))
3660 (clobber (match_scratch:V4SI 3 "=&r"))
3661 (clobber (match_scratch:V4SI 4 "=&r"))]
3666 selb\t%0,%4,%0,%3\;\
3668 selb\t%0,%4,%0,%3\;\
3671 [(set_attr "type" "multi0")
3672 (set_attr "length" "32")])
3676 (define_insn "dftsv_celledp"
3677 [(set (match_operand:V2DI 0 "spu_reg_operand" "=r")
3678 (unspec:V2DI [(match_operand:V2DF 1 "spu_reg_operand" "r")
3679 (match_operand:SI 2 "const_int_operand" "i")]
3681 "spu_arch == PROCESSOR_CELLEDP"
3683 [(set_attr "type" "fpd")])
3685 (define_expand "dftsv"
3686 [(set (match_operand:V2DI 0 "spu_reg_operand" "=r")
3687 (unspec:V2DI [(match_operand:V2DF 1 "spu_reg_operand" "r")
3688 (match_operand:SI 2 "const_int_operand" "i")]
3692 if (spu_arch == PROCESSOR_CELL)
3694 rtx result = gen_reg_rtx (V4SImode);
3695 emit_move_insn (result, CONST0_RTX (V4SImode));
3697 if (INTVAL (operands[2]))
3699 rtx ra = spu_gen_subreg (V4SImode, operands[1]);
3700 rtx abs = gen_reg_rtx (V4SImode);
3701 rtx sign = gen_reg_rtx (V4SImode);
3702 rtx temp = gen_reg_rtx (TImode);
3703 rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
3704 rtx temp2 = gen_reg_rtx (V4SImode);
3705 rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF,
3706 0x7FFFFFFF, 0xFFFFFFFF);
3707 rtx sign_mask = gen_reg_rtx (V4SImode);
3708 rtx hi_promote = gen_reg_rtx (TImode);
3709 emit_move_insn (sign_mask, pat);
3710 pat = spu_const_from_ints (TImode, 0x00010203, 0x00010203,
3711 0x08090A0B, 0x08090A0B);
3712 emit_move_insn (hi_promote, pat);
3714 emit_insn (gen_vashrv4si3 (sign, ra, spu_const (V4SImode, 31)));
3715 emit_insn (gen_shufb (sign, sign, sign, hi_promote));
3716 emit_insn (gen_andv4si3 (abs, ra, sign_mask));
3718 /* NaN or +inf or -inf */
3719 if (INTVAL (operands[2]) & 0x70)
3721 rtx nan_mask = gen_reg_rtx (V4SImode);
3722 rtx isinf = gen_reg_rtx (V4SImode);
3723 pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0,
3725 emit_move_insn (nan_mask, pat);
3726 emit_insn (gen_ceq_v4si (isinf, abs, nan_mask));
3729 if (INTVAL (operands[2]) & 0x40)
3731 rtx isnan = gen_reg_rtx (V4SImode);
3732 emit_insn (gen_clgt_v4si (isnan, abs, nan_mask));
3733 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, isnan),
3735 emit_insn (gen_andv4si3 (temp2, temp_v4si, isinf));
3736 emit_insn (gen_iorv4si3 (isnan, isnan, temp2));
3737 emit_insn (gen_shufb (isnan, isnan, isnan, hi_promote));
3738 emit_insn (gen_iorv4si3 (result, result, isnan));
3741 if (INTVAL (operands[2]) & 0x30)
3743 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, isinf),
3745 emit_insn (gen_andv4si3 (isinf, isinf, temp_v4si));
3746 emit_insn (gen_shufb (isinf, isinf, isinf, hi_promote));
3749 if (INTVAL (operands[2]) & 0x20)
3751 emit_insn (gen_andc_v4si (temp2, isinf, sign));
3752 emit_insn (gen_iorv4si3 (result, result, temp2));
3755 if (INTVAL (operands[2]) & 0x10)
3757 emit_insn (gen_andv4si3 (temp2, isinf, sign));
3758 emit_insn (gen_iorv4si3 (result, result, temp2));
3764 if (INTVAL (operands[2]) & 0xF)
3766 rtx iszero = gen_reg_rtx (V4SImode);
3767 emit_insn (gen_ceq_v4si (iszero, abs, CONST0_RTX (V4SImode)));
3768 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, iszero),
3770 emit_insn (gen_andv4si3 (iszero, iszero, temp_v4si));
3773 if (INTVAL (operands[2]) & 0x3)
3775 rtx isdenorm = gen_reg_rtx (V4SImode);
3776 rtx denorm_mask = gen_reg_rtx (V4SImode);
3777 emit_move_insn (denorm_mask, spu_const (V4SImode, 0xFFFFF));
3778 emit_insn (gen_clgt_v4si (isdenorm, abs, denorm_mask));
3779 emit_insn (gen_nor_v4si (isdenorm, isdenorm, iszero));
3780 emit_insn (gen_shufb (isdenorm, isdenorm,
3781 isdenorm, hi_promote));
3783 if (INTVAL (operands[2]) & 0x2)
3785 emit_insn (gen_andc_v4si (temp2, isdenorm, sign));
3786 emit_insn (gen_iorv4si3 (result, result, temp2));
3789 if (INTVAL (operands[2]) & 0x1)
3791 emit_insn (gen_andv4si3 (temp2, isdenorm, sign));
3792 emit_insn (gen_iorv4si3 (result, result, temp2));
3797 if (INTVAL (operands[2]) & 0xC)
3799 emit_insn (gen_shufb (iszero, iszero, iszero, hi_promote));
3801 if (INTVAL (operands[2]) & 0x8)
3803 emit_insn (gen_andc_v4si (temp2, iszero, sign));
3804 emit_insn (gen_iorv4si3 (result, result, temp2));
3807 if (INTVAL (operands[2]) & 0x4)
3809 emit_insn (gen_andv4si3 (temp2, iszero, sign));
3810 emit_insn (gen_iorv4si3 (result, result, temp2));
3815 emit_move_insn (operands[0], spu_gen_subreg (V2DImode, result));
3825 (if_then_else (match_operator 1 "branch_comparison_operator"
3827 "spu_reg_operand" "r")
3829 (label_ref (match_operand 0 "" ""))
3833 [(set_attr "type" "br")])
3837 (if_then_else (match_operator 0 "branch_comparison_operator"
3839 "spu_reg_operand" "r")
3845 [(set_attr "type" "br")])
3849 (if_then_else (match_operator 1 "branch_comparison_operator"
3851 "spu_reg_operand" "r")
3854 (label_ref (match_operand 0 "" ""))))]
3857 [(set_attr "type" "br")])
3861 (if_then_else (match_operator 0 "branch_comparison_operator"
3863 "spu_reg_operand" "r")
3869 [(set_attr "type" "br")])
3872 ;; vector conditional compare patterns
3873 (define_expand "vcond<mode>"
3874 [(set (match_operand:VCMP 0 "spu_reg_operand" "=r")
3876 (match_operator 3 "comparison_operator"
3877 [(match_operand:VCMP 4 "spu_reg_operand" "r")
3878 (match_operand:VCMP 5 "spu_reg_operand" "r")])
3879 (match_operand:VCMP 1 "spu_reg_operand" "r")
3880 (match_operand:VCMP 2 "spu_reg_operand" "r")))]
3883 if (spu_emit_vector_cond_expr (operands[0], operands[1], operands[2],
3884 operands[3], operands[4], operands[5]))
3890 (define_expand "vcondu<mode>"
3891 [(set (match_operand:VCMPU 0 "spu_reg_operand" "=r")
3893 (match_operator 3 "comparison_operator"
3894 [(match_operand:VCMPU 4 "spu_reg_operand" "r")
3895 (match_operand:VCMPU 5 "spu_reg_operand" "r")])
3896 (match_operand:VCMPU 1 "spu_reg_operand" "r")
3897 (match_operand:VCMPU 2 "spu_reg_operand" "r")))]
3900 if (spu_emit_vector_cond_expr (operands[0], operands[1], operands[2],
3901 operands[3], operands[4], operands[5]))
3908 ;; branch on condition
3910 (define_expand "cbranch<mode>4"
3911 [(use (match_operator 0 "ordered_comparison_operator"
3912 [(match_operand:VQHSI 1 "spu_reg_operand" "")
3913 (match_operand:VQHSI 2 "spu_nonmem_operand" "")]))
3914 (use (match_operand 3 ""))]
3916 { spu_emit_branch_or_set (0, operands[0], operands); DONE; })
3918 (define_expand "cbranch<mode>4"
3919 [(use (match_operator 0 "ordered_comparison_operator"
3920 [(match_operand:DTI 1 "spu_reg_operand" "")
3921 (match_operand:DTI 2 "spu_reg_operand" "")]))
3922 (use (match_operand 3 ""))]
3924 { spu_emit_branch_or_set (0, operands[0], operands); DONE; })
3926 (define_expand "cbranch<mode>4"
3927 [(use (match_operator 0 "ordered_comparison_operator"
3928 [(match_operand:VSF 1 "spu_reg_operand" "")
3929 (match_operand:VSF 2 "spu_reg_operand" "")]))
3930 (use (match_operand 3 ""))]
3932 { spu_emit_branch_or_set (0, operands[0], operands); DONE; })
3934 (define_expand "cbranchdf4"
3935 [(use (match_operator 0 "ordered_comparison_operator"
3936 [(match_operand:DF 1 "spu_reg_operand" "")
3937 (match_operand:DF 2 "spu_reg_operand" "")]))
3938 (use (match_operand 3 ""))]
3940 { spu_emit_branch_or_set (0, operands[0], operands); DONE; })
3945 (define_expand "cstore<mode>4"
3946 [(use (match_operator 1 "ordered_comparison_operator"
3947 [(match_operand:VQHSI 2 "spu_reg_operand" "")
3948 (match_operand:VQHSI 3 "spu_nonmem_operand" "")]))
3949 (clobber (match_operand:SI 0 "spu_reg_operand"))]
3951 { spu_emit_branch_or_set (1, operands[1], operands); DONE; })
3953 (define_expand "cstore<mode>4"
3954 [(use (match_operator 1 "ordered_comparison_operator"
3955 [(match_operand:DTI 2 "spu_reg_operand" "")
3956 (match_operand:DTI 3 "spu_reg_operand" "")]))
3957 (clobber (match_operand:SI 0 "spu_reg_operand"))]
3959 { spu_emit_branch_or_set (1, operands[1], operands); DONE; })
3961 (define_expand "cstore<mode>4"
3962 [(use (match_operator 1 "ordered_comparison_operator"
3963 [(match_operand:VSF 2 "spu_reg_operand" "")
3964 (match_operand:VSF 3 "spu_reg_operand" "")]))
3965 (clobber (match_operand:SI 0 "spu_reg_operand"))]
3967 { spu_emit_branch_or_set (1, operands[1], operands); DONE; })
3969 (define_expand "cstoredf4"
3970 [(use (match_operator 1 "ordered_comparison_operator"
3971 [(match_operand:DF 2 "spu_reg_operand" "")
3972 (match_operand:DF 3 "spu_reg_operand" "")]))
3973 (clobber (match_operand:SI 0 "spu_reg_operand"))]
3975 { spu_emit_branch_or_set (1, operands[1], operands); DONE; })
3980 ;; Define this first one so HAVE_conditional_move is defined.
3981 (define_insn "movcc_dummy"
3982 [(set (match_operand 0 "" "")
3983 (if_then_else (match_operand 1 "" "")
3984 (match_operand 2 "" "")
3985 (match_operand 3 "" "")))]
3989 (define_expand "mov<mode>cc"
3990 [(set (match_operand:ALL 0 "spu_reg_operand" "")
3991 (if_then_else:ALL (match_operand 1 "ordered_comparison_operator" "")
3992 (match_operand:ALL 2 "spu_reg_operand" "")
3993 (match_operand:ALL 3 "spu_reg_operand" "")))]
3996 spu_emit_branch_or_set(2, operands[1], operands);
4000 ;; This pattern is used when the result of a compare is not large
4001 ;; enough to use in a selb when expanding conditional moves.
4002 (define_expand "extend_compare"
4003 [(set (match_operand 0 "spu_reg_operand" "=r")
4004 (unspec [(match_operand 1 "spu_reg_operand" "r")] UNSPEC_EXTEND_CMP))]
4007 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
4008 gen_rtx_UNSPEC (GET_MODE (operands[0]),
4009 gen_rtvec (1, operands[1]),
4010 UNSPEC_EXTEND_CMP)));
4014 (define_insn "extend_compare<mode>"
4015 [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
4016 (unspec:ALL [(match_operand 1 "spu_reg_operand" "r")] UNSPEC_EXTEND_CMP))]
4019 [(set_attr "type" "shuf")])
4024 ;; operand 0 is index
4025 ;; operand 1 is the minimum bound
4026 ;; operand 2 is the maximum bound - minimum bound + 1
4027 ;; operand 3 is CODE_LABEL for the table;
4028 ;; operand 4 is the CODE_LABEL to go to if index out of range.
4029 (define_expand "casesi"
4030 [(match_operand:SI 0 "spu_reg_operand" "")
4031 (match_operand:SI 1 "immediate_operand" "")
4032 (match_operand:SI 2 "immediate_operand" "")
4033 (match_operand 3 "" "")
4034 (match_operand 4 "" "")]
4037 rtx table = gen_reg_rtx (SImode);
4038 rtx index = gen_reg_rtx (SImode);
4039 rtx sindex = gen_reg_rtx (SImode);
4040 rtx addr = gen_reg_rtx (Pmode);
4042 emit_move_insn (table, gen_rtx_LABEL_REF (SImode, operands[3]));
4044 emit_insn (gen_subsi3(index, operands[0], force_reg(SImode, operands[1])));
4045 emit_insn (gen_ashlsi3(sindex, index, GEN_INT (2)));
4046 emit_move_insn (addr, gen_rtx_MEM (SImode,
4047 gen_rtx_PLUS (SImode, table, sindex)));
4049 emit_insn (gen_addsi3 (addr, addr, table));
4051 emit_cmp_and_jump_insns (index, operands[2], GTU, NULL_RTX, SImode, 1, operands[4]);
4052 emit_jump_insn (gen_tablejump (addr, operands[3]));
4056 (define_insn "tablejump"
4057 [(set (pc) (match_operand:SI 0 "spu_reg_operand" "r"))
4058 (use (label_ref (match_operand 1 "" "")))]
4061 [(set_attr "type" "br")])
4066 ;; Note that operand 1 is total size of args, in bytes,
4067 ;; and what the call insn wants is the number of words.
4068 (define_expand "sibcall"
4070 [(call (match_operand:QI 0 "call_operand" "")
4071 (match_operand:QI 1 "" ""))
4075 if (! call_operand (operands[0], QImode))
4076 XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
4079 (define_insn "_sibcall"
4081 [(call (match_operand:QI 0 "call_operand" "R,S")
4082 (match_operand:QI 1 "" "i,i"))
4084 "SIBLING_CALL_P(insn)"
4088 [(set_attr "type" "br,br")])
4090 (define_expand "sibcall_value"
4092 [(set (match_operand 0 "" "")
4093 (call (match_operand:QI 1 "call_operand" "")
4094 (match_operand:QI 2 "" "")))
4098 if (! call_operand (operands[1], QImode))
4099 XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
4102 (define_insn "_sibcall_value"
4104 [(set (match_operand 0 "" "")
4105 (call (match_operand:QI 1 "call_operand" "R,S")
4106 (match_operand:QI 2 "" "i,i")))
4108 "SIBLING_CALL_P(insn)"
4112 [(set_attr "type" "br,br")])
4114 ;; Note that operand 1 is total size of args, in bytes,
4115 ;; and what the call insn wants is the number of words.
4116 (define_expand "call"
4118 [(call (match_operand:QI 0 "call_operand" "")
4119 (match_operand:QI 1 "" ""))
4120 (clobber (reg:SI 0))
4121 (clobber (reg:SI 130))])]
4124 if (! call_operand (operands[0], QImode))
4125 XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
4128 (define_insn "_call"
4130 [(call (match_operand:QI 0 "call_operand" "R,S,T")
4131 (match_operand:QI 1 "" "i,i,i"))
4132 (clobber (reg:SI 0))
4133 (clobber (reg:SI 130))])]
4139 [(set_attr "type" "br")])
4141 (define_expand "call_value"
4143 [(set (match_operand 0 "" "")
4144 (call (match_operand:QI 1 "call_operand" "")
4145 (match_operand:QI 2 "" "")))
4146 (clobber (reg:SI 0))
4147 (clobber (reg:SI 130))])]
4150 if (! call_operand (operands[1], QImode))
4151 XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
4154 (define_insn "_call_value"
4156 [(set (match_operand 0 "" "")
4157 (call (match_operand:QI 1 "call_operand" "R,S,T")
4158 (match_operand:QI 2 "" "i,i,i")))
4159 (clobber (reg:SI 0))
4160 (clobber (reg:SI 130))])]
4166 [(set_attr "type" "br")])
4168 (define_expand "untyped_call"
4169 [(parallel [(call (match_operand 0 "" "")
4171 (match_operand 1 "" "")
4172 (match_operand 2 "" "")])]
4176 rtx reg = gen_rtx_REG (TImode, 3);
4178 /* We need to use call_value so the return value registers don't get
4180 emit_call_insn (gen_call_value (reg, operands[0], const0_rtx));
4182 for (i = 0; i < XVECLEN (operands[2], 0); i++)
4184 rtx set = XVECEXP (operands[2], 0, i);
4185 emit_move_insn (SET_DEST (set), SET_SRC (set));
4188 /* The optimizer does not know that the call sets the function value
4189 registers we stored in the result block. We avoid problems by
4190 claiming that all hard registers are used and clobbered at this
4192 emit_insn (gen_blockage ());
4198 ;; Patterns used for splitting and combining.
4201 ;; Function prologue and epilogue.
4203 (define_expand "prologue"
4206 { spu_expand_prologue (); DONE; })
4208 ;; "blockage" is only emited in epilogue. This is what it took to
4209 ;; make "basic block reordering" work with the insns sequence
4210 ;; generated by the spu_expand_epilogue (taken from mips.md)
4212 (define_insn "blockage"
4213 [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
4216 [(set_attr "type" "convert")
4217 (set_attr "length" "0")])
4219 (define_expand "epilogue"
4222 { spu_expand_epilogue (false); DONE; })
4224 (define_expand "sibcall_epilogue"
4227 { spu_expand_epilogue (true); DONE; })
4230 ;; stack manipulations
4232 ;; An insn to allocate new stack space for dynamic use (e.g., alloca).
4233 ;; We move the back-chain and decrement the stack pointer.
4234 (define_expand "allocate_stack"
4235 [(set (match_operand 0 "spu_reg_operand" "")
4236 (minus (reg 1) (match_operand 1 "spu_nonmem_operand" "")))
4238 (minus (reg 1) (match_dup 1)))]
4240 "spu_allocate_stack (operands[0], operands[1]); DONE;")
4242 ;; These patterns say how to save and restore the stack pointer. We need not
4243 ;; save the stack pointer at function level since we are careful to preserve
4247 ;; At block level the stack pointer is saved and restored, so that the
4248 ;; stack space allocated within a block is deallocated when leaving
4249 ;; block scope. By default, according to the SPU ABI, the stack
4250 ;; pointer and available stack size are saved in a register. Upon
4251 ;; restoration, the stack pointer is simply copied back, and the
4252 ;; current available stack size is calculated against the restored
4255 ;; For nonlocal gotos, we must save the stack pointer and its
4256 ;; backchain and restore both. Note that in the nonlocal case, the
4257 ;; save area is a memory location.
4259 (define_expand "save_stack_function"
4260 [(match_operand 0 "general_operand" "")
4261 (match_operand 1 "general_operand" "")]
4265 (define_expand "restore_stack_function"
4266 [(match_operand 0 "general_operand" "")
4267 (match_operand 1 "general_operand" "")]
4271 (define_expand "restore_stack_block"
4272 [(match_operand 0 "spu_reg_operand" "")
4273 (match_operand 1 "memory_operand" "")]
4277 spu_restore_stack_block (operands[0], operands[1]);
4281 (define_expand "save_stack_nonlocal"
4282 [(match_operand 0 "memory_operand" "")
4283 (match_operand 1 "spu_reg_operand" "")]
4287 rtx temp = gen_reg_rtx (Pmode);
4289 /* Copy the backchain to the first word, sp to the second. We need to
4290 save the back chain because __builtin_apply appears to clobber it. */
4291 emit_move_insn (temp, gen_rtx_MEM (Pmode, operands[1]));
4292 emit_move_insn (adjust_address_nv (operands[0], SImode, 0), temp);
4293 emit_move_insn (adjust_address_nv (operands[0], SImode, 4), operands[1]);
4297 (define_expand "restore_stack_nonlocal"
4298 [(match_operand 0 "spu_reg_operand" "")
4299 (match_operand 1 "memory_operand" "")]
4303 spu_restore_stack_nonlocal(operands[0], operands[1]);
4310 ;; Vector initialization
4311 (define_expand "vec_init<mode>"
4312 [(match_operand:V 0 "register_operand" "")
4313 (match_operand 1 "" "")]
4316 spu_expand_vector_init (operands[0], operands[1]);
4320 (define_expand "vec_set<mode>"
4321 [(use (match_operand:SI 2 "spu_nonmem_operand" ""))
4322 (set (match_dup:TI 3)
4323 (unspec:TI [(match_dup:SI 4)
4325 (match_dup:SI 6)] UNSPEC_CPAT))
4326 (set (match_operand:V 0 "spu_reg_operand" "")
4327 (unspec:V [(match_operand:<inner> 1 "spu_reg_operand" "")
4329 (match_dup:TI 3)] UNSPEC_SHUFB))]
4332 HOST_WIDE_INT size = GET_MODE_SIZE (<inner>mode);
4333 rtx offset = GEN_INT (INTVAL (operands[2]) * size);
4334 operands[3] = gen_reg_rtx (TImode);
4335 operands[4] = stack_pointer_rtx;
4336 operands[5] = offset;
4337 operands[6] = GEN_INT (size);
4340 (define_expand "vec_extract<mode>"
4341 [(set (match_operand:<inner> 0 "spu_reg_operand" "=r")
4342 (vec_select:<inner> (match_operand:V 1 "spu_reg_operand" "r")
4343 (parallel [(match_operand 2 "const_int_operand" "i")])))]
4346 if ((INTVAL (operands[2]) * <vmult> + <voff>) % 16 == 0)
4348 emit_insn (gen_spu_convert (operands[0], operands[1]));
4353 (define_insn "_vec_extract<mode>"
4354 [(set (match_operand:<inner> 0 "spu_reg_operand" "=r")
4355 (vec_select:<inner> (match_operand:V 1 "spu_reg_operand" "r")
4356 (parallel [(match_operand 2 "const_int_operand" "i")])))]
4358 "rotqbyi\t%0,%1,(%2*<vmult>+<voff>)%%16"
4359 [(set_attr "type" "shuf")])
4361 (define_insn "_vec_extractv8hi_ze"
4362 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
4363 (zero_extend:SI (vec_select:HI (match_operand:V8HI 1 "spu_reg_operand" "r")
4364 (parallel [(const_int 0)]))))]
4366 "rotqmbyi\t%0,%1,-2"
4367 [(set_attr "type" "shuf")])
4372 (define_expand "shufb"
4373 [(set (match_operand 0 "spu_reg_operand" "")
4374 (unspec [(match_operand 1 "spu_reg_operand" "")
4375 (match_operand 2 "spu_reg_operand" "")
4376 (match_operand:TI 3 "spu_reg_operand" "")] UNSPEC_SHUFB))]
4379 rtx s = gen__shufb (operands[0], operands[1], operands[2], operands[3]);
4380 PUT_MODE (SET_SRC (s), GET_MODE (operands[0]));
4385 (define_insn "_shufb"
4386 [(set (match_operand 0 "spu_reg_operand" "=r")
4387 (unspec [(match_operand 1 "spu_reg_operand" "r")
4388 (match_operand 2 "spu_reg_operand" "r")
4389 (match_operand:TI 3 "spu_reg_operand" "r")] UNSPEC_SHUFB))]
4391 "shufb\t%0,%1,%2,%3"
4392 [(set_attr "type" "shuf")])
4395 [(unspec_volatile [(const_int 0)] UNSPEC_NOP)]
4398 [(set_attr "type" "nop")])
4401 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "K")] UNSPEC_NOP)]
4404 [(set_attr "type" "nop")])
4407 [(unspec_volatile [(const_int 0)] UNSPEC_LNOP)]
4410 [(set_attr "type" "lnop")])
4412 ;; The operand is so we know why we generated this hbrp.
4413 ;; We clobber mem to make sure it isn't moved over any
4414 ;; loads, stores or calls while scheduling.
4415 (define_insn "iprefetch"
4416 [(unspec [(match_operand:SI 0 "const_int_operand" "n")] UNSPEC_IPREFETCH)
4417 (clobber (mem:BLK (scratch)))]
4420 [(set_attr "type" "iprefetch")])
4422 ;; A non-volatile version so it gets scheduled
4423 (define_insn "nopn_nv"
4424 [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_NOP)]
4427 [(set_attr "type" "nop")])
4431 (unspec:SI [(match_operand:SI 0 "immediate_operand" "i,i,i")
4432 (match_operand:SI 1 "nonmemory_operand" "r,s,i")] UNSPEC_HBR))
4433 (unspec [(const_int 0)] UNSPEC_HBR)]
4439 [(set_attr "type" "hbr")])
4442 [(unspec_volatile [(const_int 0)] UNSPEC_SYNC)
4443 (clobber (mem:BLK (scratch)))]
4446 [(set_attr "type" "br")])
4448 (define_insn "syncc"
4449 [(unspec_volatile [(const_int 1)] UNSPEC_SYNC)
4450 (clobber (mem:BLK (scratch)))]
4453 [(set_attr "type" "br")])
4455 (define_insn "dsync"
4456 [(unspec_volatile [(const_int 2)] UNSPEC_SYNC)
4457 (clobber (mem:BLK (scratch)))]
4460 [(set_attr "type" "br")])
4464 ;; Define the subtract-one-and-jump insns so loop.c
4465 ;; knows what to generate.
4466 (define_expand "doloop_end"
4467 [(use (match_operand 0 "" "")) ; loop pseudo
4468 (use (match_operand 1 "" "")) ; iterations; zero if unknown
4469 (use (match_operand 2 "" "")) ; max iterations
4470 (use (match_operand 3 "" "")) ; loop level
4471 (use (match_operand 4 "" ""))] ; label
4475 /* Currently SMS relies on the do-loop pattern to recognize loops
4476 where (1) the control part comprises of all insns defining and/or
4477 using a certain 'count' register and (2) the loop count can be
4478 adjusted by modifying this register prior to the loop.
4479 . ??? The possible introduction of a new block to initialize the
4480 new IV can potentially effects branch optimizations. */
4481 if (optimize > 0 && flag_modulo_sched)
4487 /* Only use this on innermost loops. */
4488 if (INTVAL (operands[3]) > 1)
4490 if (GET_MODE (operands[0]) != SImode)
4494 emit_move_insn (s0, gen_rtx_PLUS (SImode, s0, GEN_INT (-1)));
4495 bcomp = gen_rtx_NE(SImode, s0, const0_rtx);
4496 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands [4]);
4497 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
4498 gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp,
4506 ;; convert between any two modes, avoiding any GCC assumptions
4507 (define_expand "spu_convert"
4508 [(set (match_operand 0 "spu_reg_operand" "")
4509 (unspec [(match_operand 1 "spu_reg_operand" "")] UNSPEC_CONVERT))]
4512 rtx c = gen__spu_convert (operands[0], operands[1]);
4513 PUT_MODE (SET_SRC (c), GET_MODE (operands[0]));
4518 (define_insn_and_split "_spu_convert"
4519 [(set (match_operand 0 "spu_reg_operand" "=r")
4520 (unspec [(match_operand 1 "spu_reg_operand" "0")] UNSPEC_CONVERT))]
4526 spu_split_convert (operands);
4529 [(set_attr "type" "convert")
4530 (set_attr "length" "0")])
4534 (include "spu-builtins.md")
4537 (define_expand "smaxv4sf3"
4538 [(set (match_operand:V4SF 0 "register_operand" "=r")
4539 (smax:V4SF (match_operand:V4SF 1 "register_operand" "r")
4540 (match_operand:V4SF 2 "register_operand" "r")))]
4544 rtx mask = gen_reg_rtx (V4SImode);
4546 emit_insn (gen_cgt_v4sf (mask, operands[1], operands[2]));
4547 emit_insn (gen_selb (operands[0], operands[2], operands[1], mask));
4551 (define_expand "sminv4sf3"
4552 [(set (match_operand:V4SF 0 "register_operand" "=r")
4553 (smin:V4SF (match_operand:V4SF 1 "register_operand" "r")
4554 (match_operand:V4SF 2 "register_operand" "r")))]
4558 rtx mask = gen_reg_rtx (V4SImode);
4560 emit_insn (gen_cgt_v4sf (mask, operands[1], operands[2]));
4561 emit_insn (gen_selb (operands[0], operands[1], operands[2], mask));
4565 (define_expand "smaxv2df3"
4566 [(set (match_operand:V2DF 0 "register_operand" "=r")
4567 (smax:V2DF (match_operand:V2DF 1 "register_operand" "r")
4568 (match_operand:V2DF 2 "register_operand" "r")))]
4572 rtx mask = gen_reg_rtx (V2DImode);
4573 emit_insn (gen_cgt_v2df (mask, operands[1], operands[2]));
4574 emit_insn (gen_selb (operands[0], operands[2], operands[1],
4575 spu_gen_subreg (V4SImode, mask)));
4579 (define_expand "sminv2df3"
4580 [(set (match_operand:V2DF 0 "register_operand" "=r")
4581 (smin:V2DF (match_operand:V2DF 1 "register_operand" "r")
4582 (match_operand:V2DF 2 "register_operand" "r")))]
4586 rtx mask = gen_reg_rtx (V2DImode);
4587 emit_insn (gen_cgt_v2df (mask, operands[1], operands[2]));
4588 emit_insn (gen_selb (operands[0], operands[1], operands[2],
4589 spu_gen_subreg (V4SImode, mask)));
4593 (define_expand "vec_widen_umult_hi_v8hi"
4594 [(set (match_operand:V4SI 0 "register_operand" "=r")
4598 (match_operand:V8HI 1 "register_operand" "r")
4599 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)])))
4602 (match_operand:V8HI 2 "register_operand" "r")
4603 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)])))))]
4607 rtx ve = gen_reg_rtx (V4SImode);
4608 rtx vo = gen_reg_rtx (V4SImode);
4609 rtx mask = gen_reg_rtx (TImode);
4610 unsigned char arr[16] = {
4611 0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13,
4612 0x04, 0x05, 0x06, 0x07, 0x14, 0x15, 0x16, 0x17};
4614 emit_move_insn (mask, array_to_constant (TImode, arr));
4615 emit_insn (gen_spu_mpyhhu (ve, operands[1], operands[2]));
4616 emit_insn (gen_spu_mpyu (vo, operands[1], operands[2]));
4617 emit_insn (gen_shufb (operands[0], ve, vo, mask));
4621 (define_expand "vec_widen_umult_lo_v8hi"
4622 [(set (match_operand:V4SI 0 "register_operand" "=r")
4626 (match_operand:V8HI 1 "register_operand" "r")
4627 (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)])))
4630 (match_operand:V8HI 2 "register_operand" "r")
4631 (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)])))))]
4635 rtx ve = gen_reg_rtx (V4SImode);
4636 rtx vo = gen_reg_rtx (V4SImode);
4637 rtx mask = gen_reg_rtx (TImode);
4638 unsigned char arr[16] = {
4639 0x08, 0x09, 0x0A, 0x0B, 0x18, 0x19, 0x1A, 0x1B,
4640 0x0C, 0x0D, 0x0E, 0x0F, 0x1C, 0x1D, 0x1E, 0x1F};
4642 emit_move_insn (mask, array_to_constant (TImode, arr));
4643 emit_insn (gen_spu_mpyhhu (ve, operands[1], operands[2]));
4644 emit_insn (gen_spu_mpyu (vo, operands[1], operands[2]));
4645 emit_insn (gen_shufb (operands[0], ve, vo, mask));
4649 (define_expand "vec_widen_smult_hi_v8hi"
4650 [(set (match_operand:V4SI 0 "register_operand" "=r")
4654 (match_operand:V8HI 1 "register_operand" "r")
4655 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)])))
4658 (match_operand:V8HI 2 "register_operand" "r")
4659 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)])))))]
4663 rtx ve = gen_reg_rtx (V4SImode);
4664 rtx vo = gen_reg_rtx (V4SImode);
4665 rtx mask = gen_reg_rtx (TImode);
4666 unsigned char arr[16] = {
4667 0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13,
4668 0x04, 0x05, 0x06, 0x07, 0x14, 0x15, 0x16, 0x17};
4670 emit_move_insn (mask, array_to_constant (TImode, arr));
4671 emit_insn (gen_spu_mpyhh (ve, operands[1], operands[2]));
4672 emit_insn (gen_spu_mpy (vo, operands[1], operands[2]));
4673 emit_insn (gen_shufb (operands[0], ve, vo, mask));
4677 (define_expand "vec_widen_smult_lo_v8hi"
4678 [(set (match_operand:V4SI 0 "register_operand" "=r")
4682 (match_operand:V8HI 1 "register_operand" "r")
4683 (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)])))
4686 (match_operand:V8HI 2 "register_operand" "r")
4687 (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)])))))]
4691 rtx ve = gen_reg_rtx (V4SImode);
4692 rtx vo = gen_reg_rtx (V4SImode);
4693 rtx mask = gen_reg_rtx (TImode);
4694 unsigned char arr[16] = {
4695 0x08, 0x09, 0x0A, 0x0B, 0x18, 0x19, 0x1A, 0x1B,
4696 0x0C, 0x0D, 0x0E, 0x0F, 0x1C, 0x1D, 0x1E, 0x1F};
4698 emit_move_insn (mask, array_to_constant (TImode, arr));
4699 emit_insn (gen_spu_mpyhh (ve, operands[1], operands[2]));
4700 emit_insn (gen_spu_mpy (vo, operands[1], operands[2]));
4701 emit_insn (gen_shufb (operands[0], ve, vo, mask));
4705 (define_expand "vec_realign_load_<mode>"
4706 [(set (match_operand:ALL 0 "register_operand" "=r")
4707 (unspec:ALL [(match_operand:ALL 1 "register_operand" "r")
4708 (match_operand:ALL 2 "register_operand" "r")
4709 (match_operand:TI 3 "register_operand" "r")] UNSPEC_SPU_REALIGN_LOAD))]
4713 emit_insn (gen_shufb (operands[0], operands[1], operands[2], operands[3]));
4717 (define_expand "spu_lvsr"
4718 [(set (match_operand:V16QI 0 "register_operand" "")
4719 (unspec:V16QI [(match_operand 1 "memory_operand" "")] UNSPEC_SPU_MASK_FOR_LOAD))]
4724 rtx offset = gen_reg_rtx (V8HImode);
4725 rtx addr_bits = gen_reg_rtx (SImode);
4726 rtx addr_bits_vec = gen_reg_rtx (V8HImode);
4727 rtx splatqi = gen_reg_rtx (TImode);
4728 rtx result = gen_reg_rtx (V8HImode);
4729 unsigned char arr[16] = {
4730 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
4731 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F};
4732 unsigned char arr2[16] = {
4733 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
4734 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03};
4736 emit_move_insn (offset, array_to_constant (V8HImode, arr));
4737 emit_move_insn (splatqi, array_to_constant (TImode, arr2));
4739 gcc_assert (GET_CODE (operands[1]) == MEM);
4740 addr = force_reg (Pmode, XEXP (operands[1], 0));
4741 emit_insn (gen_andsi3 (addr_bits, addr, GEN_INT (0xF)));
4742 emit_insn (gen_shufb (addr_bits_vec, addr_bits, addr_bits, splatqi));
4744 /* offset - (addr & 0xF)
4745 It is safe to use a single sfh, because each byte of offset is > 15 and
4746 each byte of addr is <= 15. */
4747 emit_insn (gen_subv8hi3 (result, offset, addr_bits_vec));
4749 result = simplify_gen_subreg (V16QImode, result, V8HImode, 0);
4750 emit_move_insn (operands[0], result);
4755 (define_expand "vec_unpacku_hi_v8hi"
4756 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
4759 (match_operand:V8HI 1 "spu_reg_operand" "r")
4760 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)]))))]
4763 rtx mask = gen_reg_rtx (TImode);
4764 unsigned char arr[16] = {
4765 0x80, 0x80, 0x00, 0x01, 0x80, 0x80, 0x02, 0x03,
4766 0x80, 0x80, 0x04, 0x05, 0x80, 0x80, 0x06, 0x07};
4768 emit_move_insn (mask, array_to_constant (TImode, arr));
4769 emit_insn (gen_shufb (operands[0], operands[1], operands[1], mask));
4774 (define_expand "vec_unpacku_lo_v8hi"
4775 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
4778 (match_operand:V8HI 1 "spu_reg_operand" "r")
4779 (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)]))))]
4782 rtx mask = gen_reg_rtx (TImode);
4783 unsigned char arr[16] = {
4784 0x80, 0x80, 0x08, 0x09, 0x80, 0x80, 0x0A, 0x0B,
4785 0x80, 0x80, 0x0C, 0x0D, 0x80, 0x80, 0x0E, 0x0F};
4787 emit_move_insn (mask, array_to_constant (TImode, arr));
4788 emit_insn (gen_shufb (operands[0], operands[1], operands[1], mask));
4793 (define_expand "vec_unpacks_hi_v8hi"
4794 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
4797 (match_operand:V8HI 1 "spu_reg_operand" "r")
4798 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)]))))]
4801 rtx tmp1 = gen_reg_rtx (V8HImode);
4802 rtx tmp2 = gen_reg_rtx (V4SImode);
4803 rtx mask = gen_reg_rtx (TImode);
4804 unsigned char arr[16] = {
4805 0x80, 0x80, 0x00, 0x01, 0x80, 0x80, 0x02, 0x03,
4806 0x80, 0x80, 0x04, 0x05, 0x80, 0x80, 0x06, 0x07};
4808 emit_move_insn (mask, array_to_constant (TImode, arr));
4809 emit_insn (gen_shufb (tmp1, operands[1], operands[1], mask));
4810 emit_insn (gen_spu_xshw (tmp2, tmp1));
4811 emit_move_insn (operands[0], tmp2);
4816 (define_expand "vec_unpacks_lo_v8hi"
4817 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
4820 (match_operand:V8HI 1 "spu_reg_operand" "r")
4821 (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)]))))]
4824 rtx tmp1 = gen_reg_rtx (V8HImode);
4825 rtx tmp2 = gen_reg_rtx (V4SImode);
4826 rtx mask = gen_reg_rtx (TImode);
4827 unsigned char arr[16] = {
4828 0x80, 0x80, 0x08, 0x09, 0x80, 0x80, 0x0A, 0x0B,
4829 0x80, 0x80, 0x0C, 0x0D, 0x80, 0x80, 0x0E, 0x0F};
4831 emit_move_insn (mask, array_to_constant (TImode, arr));
4832 emit_insn (gen_shufb (tmp1, operands[1], operands[1], mask));
4833 emit_insn (gen_spu_xshw (tmp2, tmp1));
4834 emit_move_insn (operands[0], tmp2);
4839 (define_expand "vec_unpacku_hi_v16qi"
4840 [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
4843 (match_operand:V16QI 1 "spu_reg_operand" "r")
4844 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)
4845 (const_int 4)(const_int 5)(const_int 6)(const_int 7)]))))]
4848 rtx mask = gen_reg_rtx (TImode);
4849 unsigned char arr[16] = {
4850 0x80, 0x00, 0x80, 0x01, 0x80, 0x02, 0x80, 0x03,
4851 0x80, 0x04, 0x80, 0x05, 0x80, 0x06, 0x80, 0x07};
4853 emit_move_insn (mask, array_to_constant (TImode, arr));
4854 emit_insn (gen_shufb (operands[0], operands[1], operands[1], mask));
4859 (define_expand "vec_unpacku_lo_v16qi"
4860 [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
4863 (match_operand:V16QI 1 "spu_reg_operand" "r")
4864 (parallel [(const_int 8)(const_int 9)(const_int 10)(const_int 11)
4865 (const_int 12)(const_int 13)(const_int 14)(const_int 15)]))))]
4868 rtx mask = gen_reg_rtx (TImode);
4869 unsigned char arr[16] = {
4870 0x80, 0x08, 0x80, 0x09, 0x80, 0x0A, 0x80, 0x0B,
4871 0x80, 0x0C, 0x80, 0x0D, 0x80, 0x0E, 0x80, 0x0F};
4873 emit_move_insn (mask, array_to_constant (TImode, arr));
4874 emit_insn (gen_shufb (operands[0], operands[1], operands[1], mask));
4879 (define_expand "vec_unpacks_hi_v16qi"
4880 [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
4883 (match_operand:V16QI 1 "spu_reg_operand" "r")
4884 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)
4885 (const_int 4)(const_int 5)(const_int 6)(const_int 7)]))))]
4888 rtx tmp1 = gen_reg_rtx (V16QImode);
4889 rtx tmp2 = gen_reg_rtx (V8HImode);
4890 rtx mask = gen_reg_rtx (TImode);
4891 unsigned char arr[16] = {
4892 0x80, 0x00, 0x80, 0x01, 0x80, 0x02, 0x80, 0x03,
4893 0x80, 0x04, 0x80, 0x05, 0x80, 0x06, 0x80, 0x07};
4895 emit_move_insn (mask, array_to_constant (TImode, arr));
4896 emit_insn (gen_shufb (tmp1, operands[1], operands[1], mask));
4897 emit_insn (gen_spu_xsbh (tmp2, tmp1));
4898 emit_move_insn (operands[0], tmp2);
4903 (define_expand "vec_unpacks_lo_v16qi"
4904 [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
4907 (match_operand:V16QI 1 "spu_reg_operand" "r")
4908 (parallel [(const_int 8)(const_int 9)(const_int 10)(const_int 11)
4909 (const_int 12)(const_int 13)(const_int 14)(const_int 15)]))))]
4912 rtx tmp1 = gen_reg_rtx (V16QImode);
4913 rtx tmp2 = gen_reg_rtx (V8HImode);
4914 rtx mask = gen_reg_rtx (TImode);
4915 unsigned char arr[16] = {
4916 0x80, 0x08, 0x80, 0x09, 0x80, 0x0A, 0x80, 0x0B,
4917 0x80, 0x0C, 0x80, 0x0D, 0x80, 0x0E, 0x80, 0x0F};
4919 emit_move_insn (mask, array_to_constant (TImode, arr));
4920 emit_insn (gen_shufb (tmp1, operands[1], operands[1], mask));
4921 emit_insn (gen_spu_xsbh (tmp2, tmp1));
4922 emit_move_insn (operands[0], tmp2);
4928 (define_expand "vec_extract_evenv4si"
4929 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
4932 (match_operand:V4SI 1 "spu_reg_operand" "r")
4933 (parallel [(const_int 0)(const_int 2)]))
4935 (match_operand:V4SI 2 "spu_reg_operand" "r")
4936 (parallel [(const_int 0)(const_int 2)]))))]
4941 rtx mask = gen_reg_rtx (TImode);
4942 unsigned char arr[16] = {
4943 0x00, 0x01, 0x02, 0x03,
4944 0x08, 0x09, 0x0A, 0x0B,
4945 0x10, 0x11, 0x12, 0x13,
4946 0x18, 0x19, 0x1A, 0x1B};
4948 emit_move_insn (mask, array_to_constant (TImode, arr));
4949 emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
4954 (define_expand "vec_extract_evenv4sf"
4955 [(set (match_operand:V4SF 0 "spu_reg_operand" "=r")
4958 (match_operand:V4SF 1 "spu_reg_operand" "r")
4959 (parallel [(const_int 0)(const_int 2)]))
4961 (match_operand:V4SF 2 "spu_reg_operand" "r")
4962 (parallel [(const_int 0)(const_int 2)]))))]
4967 rtx mask = gen_reg_rtx (TImode);
4968 unsigned char arr[16] = {
4969 0x00, 0x01, 0x02, 0x03,
4970 0x08, 0x09, 0x0A, 0x0B,
4971 0x10, 0x11, 0x12, 0x13,
4972 0x18, 0x19, 0x1A, 0x1B};
4974 emit_move_insn (mask, array_to_constant (TImode, arr));
4975 emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
4979 (define_expand "vec_extract_evenv8hi"
4980 [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
4983 (match_operand:V8HI 1 "spu_reg_operand" "r")
4984 (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)]))
4986 (match_operand:V8HI 2 "spu_reg_operand" "r")
4987 (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)]))))]
4992 rtx mask = gen_reg_rtx (TImode);
4993 unsigned char arr[16] = {
4994 0x00, 0x01, 0x04, 0x05,
4995 0x08, 0x09, 0x0C, 0x0D,
4996 0x10, 0x11, 0x14, 0x15,
4997 0x18, 0x19, 0x1C, 0x1D};
4999 emit_move_insn (mask, array_to_constant (TImode, arr));
5000 emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5004 (define_expand "vec_extract_evenv16qi"
5005 [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
5008 (match_operand:V16QI 1 "spu_reg_operand" "r")
5009 (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)
5010 (const_int 8)(const_int 10)(const_int 12)(const_int 14)]))
5012 (match_operand:V16QI 2 "spu_reg_operand" "r")
5013 (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)
5014 (const_int 8)(const_int 10)(const_int 12)(const_int 14)]))))]
5019 rtx mask = gen_reg_rtx (TImode);
5020 unsigned char arr[16] = {
5021 0x00, 0x02, 0x04, 0x06,
5022 0x08, 0x0A, 0x0C, 0x0E,
5023 0x10, 0x12, 0x14, 0x16,
5024 0x18, 0x1A, 0x1C, 0x1E};
5026 emit_move_insn (mask, array_to_constant (TImode, arr));
5027 emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5031 (define_expand "vec_extract_oddv4si"
5032 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
5035 (match_operand:V4SI 1 "spu_reg_operand" "r")
5036 (parallel [(const_int 1)(const_int 3)]))
5038 (match_operand:V4SI 2 "spu_reg_operand" "r")
5039 (parallel [(const_int 1)(const_int 3)]))))]
5044 rtx mask = gen_reg_rtx (TImode);
5045 unsigned char arr[16] = {
5046 0x04, 0x05, 0x06, 0x07,
5047 0x0C, 0x0D, 0x0E, 0x0F,
5048 0x14, 0x15, 0x16, 0x17,
5049 0x1C, 0x1D, 0x1E, 0x1F};
5051 emit_move_insn (mask, array_to_constant (TImode, arr));
5052 emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5056 (define_expand "vec_extract_oddv4sf"
5057 [(set (match_operand:V4SF 0 "spu_reg_operand" "=r")
5060 (match_operand:V4SF 1 "spu_reg_operand" "r")
5061 (parallel [(const_int 1)(const_int 3)]))
5063 (match_operand:V4SF 2 "spu_reg_operand" "r")
5064 (parallel [(const_int 1)(const_int 3)]))))]
5069 rtx mask = gen_reg_rtx (TImode);
5070 unsigned char arr[16] = {
5071 0x04, 0x05, 0x06, 0x07,
5072 0x0C, 0x0D, 0x0E, 0x0F,
5073 0x14, 0x15, 0x16, 0x17,
5074 0x1C, 0x1D, 0x1E, 0x1F};
5076 emit_move_insn (mask, array_to_constant (TImode, arr));
5077 emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5081 (define_expand "vec_extract_oddv8hi"
5082 [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
5085 (match_operand:V8HI 1 "spu_reg_operand" "r")
5086 (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)]))
5088 (match_operand:V8HI 2 "spu_reg_operand" "r")
5089 (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)]))))]
5094 rtx mask = gen_reg_rtx (TImode);
5095 unsigned char arr[16] = {
5096 0x02, 0x03, 0x06, 0x07,
5097 0x0A, 0x0B, 0x0E, 0x0F,
5098 0x12, 0x13, 0x16, 0x17,
5099 0x1A, 0x1B, 0x1E, 0x1F};
5101 emit_move_insn (mask, array_to_constant (TImode, arr));
5102 emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5106 (define_expand "vec_extract_oddv16qi"
5107 [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
5110 (match_operand:V16QI 1 "spu_reg_operand" "r")
5111 (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)
5112 (const_int 9)(const_int 11)(const_int 13)(const_int 15)]))
5114 (match_operand:V16QI 2 "spu_reg_operand" "r")
5115 (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)
5116 (const_int 9)(const_int 11)(const_int 13)(const_int 15)]))))]
5121 rtx mask = gen_reg_rtx (TImode);
5122 unsigned char arr[16] = {
5123 0x01, 0x03, 0x05, 0x07,
5124 0x09, 0x0B, 0x0D, 0x0F,
5125 0x11, 0x13, 0x15, 0x17,
5126 0x19, 0x1B, 0x1D, 0x1F};
5128 emit_move_insn (mask, array_to_constant (TImode, arr));
5129 emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5133 (define_expand "vec_interleave_highv4sf"
5134 [(set (match_operand:V4SF 0 "spu_reg_operand" "=r")
5138 (match_operand:V4SF 1 "spu_reg_operand" "r")
5139 (parallel [(const_int 0)(const_int 1)]))
5141 (match_operand:V4SF 2 "spu_reg_operand" "r")
5142 (parallel [(const_int 0)(const_int 1)])))
5143 (parallel [(const_int 0)(const_int 2)(const_int 1)(const_int 3)])))]
5148 rtx mask = gen_reg_rtx (TImode);
5149 unsigned char arr[16] = {
5150 0x00, 0x01, 0x02, 0x03,
5151 0x10, 0x11, 0x12, 0x13,
5152 0x04, 0x05, 0x06, 0x07,
5153 0x14, 0x15, 0x16, 0x17};
5155 emit_move_insn (mask, array_to_constant (TImode, arr));
5156 emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5160 (define_expand "vec_interleave_lowv4sf"
5161 [(set (match_operand:V4SF 0 "spu_reg_operand" "=r")
5165 (match_operand:V4SF 1 "spu_reg_operand" "r")
5166 (parallel [(const_int 2)(const_int 3)]))
5168 (match_operand:V4SF 2 "spu_reg_operand" "r")
5169 (parallel [(const_int 2)(const_int 3)])))
5170 (parallel [(const_int 0)(const_int 2)(const_int 1)(const_int 3)])))]
5175 rtx mask = gen_reg_rtx (TImode);
5176 unsigned char arr[16] = {
5177 0x08, 0x09, 0x0A, 0x0B,
5178 0x18, 0x19, 0x1A, 0x1B,
5179 0x0C, 0x0D, 0x0E, 0x0F,
5180 0x1C, 0x1D, 0x1E, 0x1F};
5182 emit_move_insn (mask, array_to_constant (TImode, arr));
5183 emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5187 (define_expand "vec_interleave_highv4si"
5188 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
5192 (match_operand:V4SI 1 "spu_reg_operand" "r")
5193 (parallel [(const_int 0)(const_int 1)]))
5195 (match_operand:V4SI 2 "spu_reg_operand" "r")
5196 (parallel [(const_int 0)(const_int 1)])))
5197 (parallel [(const_int 0)(const_int 2)(const_int 1)(const_int 3)])))]
5202 rtx mask = gen_reg_rtx (TImode);
5203 unsigned char arr[16] = {
5204 0x00, 0x01, 0x02, 0x03,
5205 0x10, 0x11, 0x12, 0x13,
5206 0x04, 0x05, 0x06, 0x07,
5207 0x14, 0x15, 0x16, 0x17};
5209 emit_move_insn (mask, array_to_constant (TImode, arr));
5210 emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5214 (define_expand "vec_interleave_lowv4si"
5215 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
5219 (match_operand:V4SI 1 "spu_reg_operand" "r")
5220 (parallel [(const_int 2)(const_int 3)]))
5222 (match_operand:V4SI 2 "spu_reg_operand" "r")
5223 (parallel [(const_int 2)(const_int 3)])))
5224 (parallel [(const_int 0)(const_int 2)(const_int 1)(const_int 3)])))]
5229 rtx mask = gen_reg_rtx (TImode);
5230 unsigned char arr[16] = {
5231 0x08, 0x09, 0x0A, 0x0B,
5232 0x18, 0x19, 0x1A, 0x1B,
5233 0x0C, 0x0D, 0x0E, 0x0F,
5234 0x1C, 0x1D, 0x1E, 0x1F};
5236 emit_move_insn (mask, array_to_constant (TImode, arr));
5237 emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5241 (define_expand "vec_interleave_highv8hi"
5242 [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
5246 (match_operand:V8HI 1 "spu_reg_operand" "r")
5247 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)]))
5249 (match_operand:V8HI 2 "spu_reg_operand" "r")
5250 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)])))
5251 (parallel [(const_int 0)(const_int 4)(const_int 1)(const_int 5)
5252 (const_int 2)(const_int 6)(const_int 3)(const_int 7)])))]
5257 rtx mask = gen_reg_rtx (TImode);
5258 unsigned char arr[16] = {
5259 0x00, 0x01, 0x10, 0x11,
5260 0x02, 0x03, 0x12, 0x13,
5261 0x04, 0x05, 0x14, 0x15,
5262 0x06, 0x07, 0x16, 0x17};
5264 emit_move_insn (mask, array_to_constant (TImode, arr));
5265 emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5269 (define_expand "vec_interleave_lowv8hi"
5270 [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
5274 (match_operand:V8HI 1 "spu_reg_operand" "r")
5275 (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)]))
5277 (match_operand:V8HI 2 "spu_reg_operand" "r")
5278 (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)])))
5279 (parallel [(const_int 0)(const_int 4)(const_int 1)(const_int 5)
5280 (const_int 2)(const_int 6)(const_int 3)(const_int 7)])))]
5285 rtx mask = gen_reg_rtx (TImode);
5286 unsigned char arr[16] = {
5287 0x08, 0x09, 0x18, 0x19,
5288 0x0A, 0x0B, 0x1A, 0x1B,
5289 0x0C, 0x0D, 0x1C, 0x1D,
5290 0x0E, 0x0F, 0x1E, 0x1F};
5292 emit_move_insn (mask, array_to_constant (TImode, arr));
5293 emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5297 (define_expand "vec_interleave_highv16qi"
5298 [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
5302 (match_operand:V16QI 1 "spu_reg_operand" "r")
5303 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)
5304 (const_int 4)(const_int 5)(const_int 6)(const_int 7)]))
5306 (match_operand:V16QI 2 "spu_reg_operand" "r")
5307 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)
5308 (const_int 4)(const_int 5)(const_int 6)(const_int 7)])))
5309 (parallel [(const_int 0)(const_int 8)(const_int 1)(const_int 9)
5310 (const_int 2)(const_int 10)(const_int 3)(const_int 11)
5311 (const_int 4)(const_int 12)(const_int 5)(const_int 13)
5312 (const_int 6)(const_int 14)(const_int 7)(const_int 15)])))]
5317 rtx mask = gen_reg_rtx (TImode);
5318 unsigned char arr[16] = {
5319 0x00, 0x10, 0x01, 0x11,
5320 0x02, 0x12, 0x03, 0x13,
5321 0x04, 0x14, 0x05, 0x15,
5322 0x06, 0x16, 0x07, 0x17};
5324 emit_move_insn (mask, array_to_constant (TImode, arr));
5325 emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5329 (define_expand "vec_interleave_lowv16qi"
5330 [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
5334 (match_operand:V16QI 1 "spu_reg_operand" "r")
5335 (parallel [(const_int 8)(const_int 9)(const_int 10)(const_int 11)
5336 (const_int 12)(const_int 13)(const_int 14)(const_int 15)]))
5338 (match_operand:V16QI 2 "spu_reg_operand" "r")
5339 (parallel [(const_int 8)(const_int 9)(const_int 10)(const_int 11)
5340 (const_int 12)(const_int 13)(const_int 14)(const_int 15)])))
5341 (parallel [(const_int 0)(const_int 8)(const_int 1)(const_int 9)
5342 (const_int 2)(const_int 10)(const_int 3)(const_int 11)
5343 (const_int 4)(const_int 12)(const_int 5)(const_int 13)
5344 (const_int 6)(const_int 14)(const_int 7)(const_int 15)])))]
5349 rtx mask = gen_reg_rtx (TImode);
5350 unsigned char arr[16] = {
5351 0x08, 0x18, 0x09, 0x19,
5352 0x0A, 0x1A, 0x0B, 0x1B,
5353 0x0C, 0x1C, 0x0D, 0x1D,
5354 0x0E, 0x1E, 0x0F, 0x1F};
5356 emit_move_insn (mask, array_to_constant (TImode, arr));
5357 emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5361 (define_expand "vec_pack_trunc_v8hi"
5362 [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
5364 (truncate:V8QI (match_operand:V8HI 1 "spu_reg_operand" "r"))
5365 (truncate:V8QI (match_operand:V8HI 2 "spu_reg_operand" "r"))))]
5369 rtx mask = gen_reg_rtx (TImode);
5370 unsigned char arr[16] = {
5371 0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0D, 0x0F,
5372 0x11, 0x13, 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F};
5374 emit_move_insn (mask, array_to_constant (TImode, arr));
5375 emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5380 (define_expand "vec_pack_trunc_v4si"
5381 [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
5383 (truncate:V4HI (match_operand:V4SI 1 "spu_reg_operand" "r"))
5384 (truncate:V4HI (match_operand:V4SI 2 "spu_reg_operand" "r"))))]
5388 rtx mask = gen_reg_rtx (TImode);
5389 unsigned char arr[16] = {
5390 0x02, 0x03, 0x06, 0x07, 0x0A, 0x0B, 0x0E, 0x0F,
5391 0x12, 0x13, 0x16, 0x17, 0x1A, 0x1B, 0x1E, 0x1F};
5393 emit_move_insn (mask, array_to_constant (TImode, arr));
5394 emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5399 (define_insn "stack_protect_set"
5400 [(set (match_operand:SI 0 "memory_operand" "=m")
5401 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
5402 (set (match_scratch:SI 2 "=&r") (const_int 0))]
5404 "lq%p1\t%2,%1\;stq%p0\t%2,%0\;xor\t%2,%2,%2"
5405 [(set_attr "length" "12")
5406 (set_attr "type" "multi1")]
5409 (define_expand "stack_protect_test"
5410 [(match_operand 0 "memory_operand" "")
5411 (match_operand 1 "memory_operand" "")
5412 (match_operand 2 "" "")]
5418 compare_result = gen_reg_rtx (SImode);
5420 emit_insn (gen_stack_protect_test_si (compare_result,
5424 bcomp = gen_rtx_NE (SImode, compare_result, const0_rtx);
5426 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[2]);
5428 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
5429 gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp,
5435 (define_insn "stack_protect_test_si"
5436 [(set (match_operand:SI 0 "spu_reg_operand" "=&r")
5437 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
5438 (match_operand:SI 2 "memory_operand" "m")]
5440 (set (match_scratch:SI 3 "=&r") (const_int 0))]
5442 "lq%p1\t%0,%1\;lq%p2\t%3,%2\;ceq\t%0,%0,%3\;xor\t%3,%3,%3"
5443 [(set_attr "length" "16")
5444 (set_attr "type" "multi1")]