1 ;; Copyright (C) 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
3 ;; This file is free software; you can redistribute it and/or modify it under
4 ;; the terms of the GNU General Public License as published by the Free
5 ;; Software Foundation; either version 3 of the License, or (at your option)
8 ;; This file is distributed in the hope that it will be useful, but WITHOUT
9 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 ;; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 ;; You should have received a copy of the GNU General Public License
14 ;; along with GCC; see the file COPYING3. If not see
15 ;; <http://www.gnu.org/licenses/>.
17 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
20 ;; Define an insn type attribute. This is used in function unit delay
22 ;; multi0 is a multiple insn rtl whose first insn is in pipe0
23 ;; multi1 is a multiple insn rtl whose first insn is in pipe1
24 (define_attr "type" "fx2,shuf,fx3,load,store,br,spr,lnop,nop,fxb,fp6,fp7,fpd,iprefetch,multi0,multi1,hbr,convert"
28 (define_attr "length" ""
31 (define_attr "tune" "cell,celledp" (const (symbol_ref "spu_tune")))
32 ;; Processor type -- this attribute must exactly match the processor_type
33 ;; enumeration in spu.h.
35 (define_attr "cpu" "spu"
36 (const (symbol_ref "spu_cpu_attr")))
38 ; (define_function_unit NAME MULTIPLICITY SIMULTANEITY
39 ; TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST])
41 (define_cpu_unit "pipe0,pipe1,fp,ls")
43 (define_insn_reservation "NOP" 1 (eq_attr "type" "nop")
46 (define_insn_reservation "FX2" 2 (eq_attr "type" "fx2")
49 (define_insn_reservation "FX3" 4 (eq_attr "type" "fx3,fxb")
52 (define_insn_reservation "FP6" 6 (eq_attr "type" "fp6")
53 "pipe0 + fp, nothing*5")
55 (define_insn_reservation "FP7" 7 (eq_attr "type" "fp7")
56 "pipe0, fp, nothing*5")
58 ;; The behavior of the double precision is that both pipes stall
59 ;; for 6 cycles and the rest of the operation pipelines for
60 ;; 7 cycles. The simplest way to model this is to simply ignore
62 (define_insn_reservation "FPD" 7
63 (and (eq_attr "tune" "cell")
64 (eq_attr "type" "fpd"))
65 "pipe0 + pipe1, fp, nothing*5")
67 ;; Tune for CELLEDP, 9 cycles, dual-issuable, fully pipelined
68 (define_insn_reservation "FPD_CELLEDP" 9
69 (and (eq_attr "tune" "celledp")
70 (eq_attr "type" "fpd"))
71 "pipe0 + fp, nothing*8")
73 (define_insn_reservation "LNOP" 1 (eq_attr "type" "lnop")
76 (define_insn_reservation "STORE" 1 (eq_attr "type" "store")
79 (define_insn_reservation "IPREFETCH" 1 (eq_attr "type" "iprefetch")
82 (define_insn_reservation "SHUF" 4 (eq_attr "type" "shuf,br,spr")
85 (define_insn_reservation "LOAD" 6 (eq_attr "type" "load")
86 "pipe1 + ls, nothing*5")
88 (define_insn_reservation "HBR" 18 (eq_attr "type" "hbr")
91 (define_insn_reservation "MULTI0" 4 (eq_attr "type" "multi0")
92 "pipe0+pipe1, nothing*3")
94 (define_insn_reservation "MULTI1" 4 (eq_attr "type" "multi1")
97 (define_insn_reservation "CONVERT" 0 (eq_attr "type" "convert")
100 ;; Force pipe0 to occur before pipe 1 in a cycle.
101 (absence_set "pipe0" "pipe1")
110 (UNSPEC_EXTEND_CMP 5)
149 (UNSPEC_SPU_REALIGN_LOAD 49)
150 (UNSPEC_SPU_MASK_FOR_LOAD 50)
152 (UNSPEC_FLOAT_EXTEND 52)
153 (UNSPEC_FLOAT_TRUNCATE 53)
158 (include "predicates.md")
159 (include "constraints.md")
164 (define_mode_iterator ALL [QI V16QI
172 ; Everything except DI and TI which are handled separately because
173 ; they need different constraints to correctly test VOIDmode constants
174 (define_mode_iterator MOV [QI V16QI
181 (define_mode_iterator QHSI [QI HI SI])
182 (define_mode_iterator QHSDI [QI HI SI DI])
183 (define_mode_iterator DTI [DI TI])
185 (define_mode_iterator VINT [QI V16QI
191 (define_mode_iterator VQHSI [QI V16QI
195 (define_mode_iterator VHSI [HI V8HI
198 (define_mode_iterator VSDF [SF V4SF
201 (define_mode_iterator VSI [SI V4SI])
202 (define_mode_iterator VDI [DI V2DI])
203 (define_mode_iterator VSF [SF V4SF])
204 (define_mode_iterator VDF [DF V2DF])
206 (define_mode_iterator VCMP [V16QI
212 (define_mode_iterator VCMPU [V16QI
216 (define_mode_attr v [(V8HI "v") (V4SI "v")
219 (define_mode_attr bh [(QI "b") (V16QI "b")
223 (define_mode_attr d [(SF "") (V4SF "")
224 (DF "d") (V2DF "d")])
225 (define_mode_attr d6 [(SF "6") (V4SF "6")
226 (DF "d") (V2DF "d")])
228 (define_mode_attr f2i [(SF "si") (V4SF "v4si")
229 (DF "di") (V2DF "v2di")])
230 (define_mode_attr F2I [(SF "SI") (V4SF "V4SI")
231 (DF "DI") (V2DF "V2DI")])
232 (define_mode_attr i2f [(SI "sf") (V4SI "v4sf")
233 (DI "df") (V2DI "v2df")])
234 (define_mode_attr I2F [(SI "SF") (V4SI "V4SF")
235 (DI "DF") (V2DI "V2DF")])
237 (define_mode_attr DF2I [(DF "SI") (V2DF "V2DI")])
239 (define_mode_attr umask [(HI "f") (V8HI "f")
240 (SI "g") (V4SI "g")])
241 (define_mode_attr nmask [(HI "F") (V8HI "F")
242 (SI "G") (V4SI "G")])
244 ;; Used for carry and borrow instructions.
245 (define_mode_iterator CBOP [SI DI V4SI V2DI])
247 ;; Used in vec_set and vec_extract
248 (define_mode_iterator V [V2DI V4SI V8HI V16QI V2DF V4SF])
249 (define_mode_attr inner [(V16QI "QI")
255 (define_mode_attr vmult [(V16QI "1")
261 (define_mode_attr voff [(V16QI "13")
271 (define_expand "mov<mode>"
272 [(set (match_operand:ALL 0 "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 "ffs<mode>2"
2237 (neg:VSI (match_operand:VSI 1 "spu_reg_operand" "")))
2238 (set (match_dup 3) (and:VSI (match_dup 1)
2240 (set (match_dup 4) (clz:VSI (match_dup 3)))
2241 (set (match_operand:VSI 0 "spu_reg_operand" "")
2242 (minus:VSI (match_dup 5) (match_dup 4)))]
2245 operands[2] = gen_reg_rtx (<MODE>mode);
2246 operands[3] = gen_reg_rtx (<MODE>mode);
2247 operands[4] = gen_reg_rtx (<MODE>mode);
2248 operands[5] = spu_const(<MODE>mode, 32);
2251 (define_expand "popcountsi2"
2253 (unspec:SI [(match_operand:SI 1 "spu_reg_operand" "")]
2256 (unspec:HI [(match_dup 2)] UNSPEC_SUMB))
2257 (set (match_operand:SI 0 "spu_reg_operand" "")
2258 (sign_extend:SI (match_dup 3)))]
2261 operands[2] = gen_reg_rtx (SImode);
2262 operands[3] = gen_reg_rtx (HImode);
2265 (define_expand "paritysi2"
2266 [(set (match_operand:SI 0 "spu_reg_operand" "")
2267 (parity:SI (match_operand:SI 1 "spu_reg_operand" "")))]
2270 operands[2] = gen_reg_rtx (SImode);
2271 emit_insn (gen_popcountsi2(operands[2], operands[1]));
2272 emit_insn (gen_andsi3(operands[0], operands[2], GEN_INT (1)));
2276 (define_insn "cntb_si"
2277 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2278 (unspec:SI [(match_operand:SI 1 "spu_reg_operand" "r")]
2282 [(set_attr "type" "fxb")])
2284 (define_insn "cntb_v16qi"
2285 [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
2286 (unspec:V16QI [(match_operand:V16QI 1 "spu_reg_operand" "r")]
2290 [(set_attr "type" "fxb")])
2292 (define_insn "sumb_si"
2293 [(set (match_operand:HI 0 "spu_reg_operand" "=r")
2294 (unspec:HI [(match_operand:SI 1 "spu_reg_operand" "r")] UNSPEC_SUMB))]
2297 [(set_attr "type" "fxb")])
2302 (define_insn "<v>ashl<mode>3"
2303 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
2304 (ashift:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
2305 (match_operand:VHSI 2 "spu_nonmem_operand" "r,W")))]
2309 shl<bh>i\t%0,%1,%<umask>2"
2310 [(set_attr "type" "fx3")])
2312 (define_insn_and_split "ashldi3"
2313 [(set (match_operand:DI 0 "spu_reg_operand" "=r,r")
2314 (ashift:DI (match_operand:DI 1 "spu_reg_operand" "r,r")
2315 (match_operand:SI 2 "spu_nonmem_operand" "r,I")))
2316 (clobber (match_scratch:SI 3 "=&r,X"))]
2320 [(set (match_dup:DI 0)
2321 (ashift:DI (match_dup:DI 1)
2324 rtx op0 = gen_rtx_REG (TImode, REGNO (operands[0]));
2325 rtx op1 = gen_rtx_REG (TImode, REGNO (operands[1]));
2326 rtx op2 = operands[2];
2327 rtx op3 = operands[3];
2329 if (GET_CODE (operands[2]) == REG)
2331 emit_insn (gen_addsi3 (op3, op2, GEN_INT (64)));
2332 emit_insn (gen_rotlti3 (op0, op1, GEN_INT (64)));
2333 emit_insn (gen_shlqbybi_ti (op0, op0, op3));
2334 emit_insn (gen_shlqbi_ti (op0, op0, op3));
2338 HOST_WIDE_INT val = INTVAL (operands[2]);
2339 emit_insn (gen_rotlti3 (op0, op1, GEN_INT (64)));
2340 emit_insn (gen_shlqby_ti (op0, op0, GEN_INT (val / 8 + 8)));
2342 emit_insn (gen_shlqbi_ti (op0, op0, GEN_INT (val % 8)));
2347 (define_expand "ashlti3"
2348 [(parallel [(set (match_operand:TI 0 "spu_reg_operand" "")
2349 (ashift:TI (match_operand:TI 1 "spu_reg_operand" "")
2350 (match_operand:SI 2 "spu_nonmem_operand" "")))
2351 (clobber (match_dup:TI 3))])]
2353 "if (GET_CODE (operands[2]) == CONST_INT)
2355 emit_insn (gen_ashlti3_imm(operands[0], operands[1], operands[2]));
2358 operands[3] = gen_reg_rtx (TImode);")
2360 (define_insn_and_split "ashlti3_imm"
2361 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2362 (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2363 (match_operand:SI 2 "immediate_operand" "O,P")))]
2368 "!satisfies_constraint_O (operands[2]) && !satisfies_constraint_P (operands[2])"
2369 [(set (match_dup:TI 0)
2370 (ashift:TI (match_dup:TI 1)
2372 (set (match_dup:TI 0)
2373 (ashift:TI (match_dup:TI 0)
2376 HOST_WIDE_INT val = INTVAL(operands[2]);
2377 operands[3] = GEN_INT (val&7);
2378 operands[4] = GEN_INT (val&-8);
2380 [(set_attr "type" "shuf,shuf")])
2382 (define_insn_and_split "ashlti3_reg"
2383 [(set (match_operand:TI 0 "spu_reg_operand" "=r")
2384 (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r")
2385 (match_operand:SI 2 "spu_reg_operand" "r")))
2386 (clobber (match_operand:TI 3 "spu_reg_operand" "=&r"))]
2390 [(set (match_dup:TI 3)
2391 (ashift:TI (match_dup:TI 1)
2392 (and:SI (match_dup:SI 2)
2394 (set (match_dup:TI 0)
2395 (ashift:TI (match_dup:TI 3)
2396 (and:SI (match_dup:SI 2)
2400 (define_insn "shlqbybi_ti"
2401 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2402 (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2403 (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2409 [(set_attr "type" "shuf,shuf")])
2411 (define_insn "shlqbi_ti"
2412 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2413 (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2414 (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2420 [(set_attr "type" "shuf,shuf")])
2422 (define_insn "shlqby_ti"
2423 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2424 (ashift:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2425 (mult:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2431 [(set_attr "type" "shuf,shuf")])
2436 (define_insn_and_split "<v>lshr<mode>3"
2437 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
2438 (lshiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
2439 (match_operand:VHSI 2 "spu_nonmem_operand" "r,W")))
2440 (clobber (match_scratch:VHSI 3 "=&r,X"))]
2444 rot<bh>mi\t%0,%1,-%<umask>2"
2445 "reload_completed && GET_CODE (operands[2]) == REG"
2446 [(set (match_dup:VHSI 3)
2447 (neg:VHSI (match_dup:VHSI 2)))
2448 (set (match_dup:VHSI 0)
2449 (lshiftrt:VHSI (match_dup:VHSI 1)
2450 (neg:VHSI (match_dup:VHSI 3))))]
2452 [(set_attr "type" "*,fx3")])
2454 (define_insn "<v>lshr<mode>3_imm"
2455 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r")
2456 (lshiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r")
2457 (match_operand:VHSI 2 "immediate_operand" "W")))]
2459 "rot<bh>mi\t%0,%1,-%<umask>2"
2460 [(set_attr "type" "fx3")])
2462 (define_insn "rotm_<mode>"
2463 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
2464 (lshiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
2465 (neg:VHSI (match_operand:VHSI 2 "spu_nonmem_operand" "r,W"))))]
2469 rot<bh>mi\t%0,%1,-%<nmask>2"
2470 [(set_attr "type" "fx3")])
2472 (define_insn_and_split "lshr<mode>3"
2473 [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r,r")
2474 (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r,r")
2475 (match_operand:SI 2 "spu_nonmem_operand" "r,O,P")))]
2479 rotqmbyi\t%0,%1,-%h2
2480 rotqmbii\t%0,%1,-%e2"
2481 "REG_P (operands[2]) || (!satisfies_constraint_O (operands[2]) && !satisfies_constraint_P (operands[2]))"
2482 [(set (match_dup:DTI 3)
2483 (lshiftrt:DTI (match_dup:DTI 1)
2485 (set (match_dup:DTI 0)
2486 (lshiftrt:DTI (match_dup:DTI 3)
2489 operands[3] = gen_reg_rtx (<MODE>mode);
2490 if (GET_CODE (operands[2]) == CONST_INT)
2492 HOST_WIDE_INT val = INTVAL(operands[2]);
2493 operands[4] = GEN_INT (val & 7);
2494 operands[5] = GEN_INT (val & -8);
2498 rtx t0 = gen_reg_rtx (SImode);
2499 rtx t1 = gen_reg_rtx (SImode);
2500 emit_insn (gen_subsi3(t0, GEN_INT(0), operands[2]));
2501 emit_insn (gen_subsi3(t1, GEN_INT(7), operands[2]));
2502 operands[4] = gen_rtx_AND (SImode, gen_rtx_NEG (SImode, t0), GEN_INT (7));
2503 operands[5] = gen_rtx_AND (SImode, gen_rtx_NEG (SImode, gen_rtx_AND (SImode, t1, GEN_INT (-8))), GEN_INT (-8));
2506 [(set_attr "type" "*,shuf,shuf")])
2508 (define_expand "shrqbybi_<mode>"
2509 [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
2510 (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
2511 (and:SI (neg:SI (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2516 if (GET_CODE (operands[2]) == CONST_INT)
2517 operands[2] = GEN_INT (7 - INTVAL (operands[2]));
2520 rtx t0 = gen_reg_rtx (SImode);
2521 emit_insn (gen_subsi3 (t0, GEN_INT (7), operands[2]));
2526 (define_insn "rotqmbybi_<mode>"
2527 [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
2528 (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
2529 (and:SI (neg:SI (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2535 rotqmbyi\t%0,%1,-%H2"
2536 [(set_attr "type" "shuf")])
2538 (define_insn_and_split "shrqbi_<mode>"
2539 [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
2540 (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
2541 (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2543 (clobber (match_scratch:SI 3 "=&r,X"))]
2547 [(set (match_dup:DTI 0)
2548 (lshiftrt:DTI (match_dup:DTI 1)
2549 (and:SI (neg:SI (match_dup:SI 3)) (const_int 7))))]
2551 if (GET_CODE (operands[2]) == CONST_INT)
2552 operands[3] = GEN_INT (-INTVAL (operands[2]));
2554 emit_insn (gen_subsi3 (operands[3], GEN_INT (0), operands[2]));
2556 [(set_attr "type" "shuf")])
2558 (define_insn "rotqmbi_<mode>"
2559 [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
2560 (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
2561 (and:SI (neg:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I"))
2566 rotqmbii\t%0,%1,-%E2"
2567 [(set_attr "type" "shuf")])
2569 (define_expand "shrqby_<mode>"
2570 [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
2571 (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
2572 (mult:SI (neg:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I"))
2576 if (GET_CODE (operands[2]) == CONST_INT)
2577 operands[2] = GEN_INT (-INTVAL (operands[2]));
2580 rtx t0 = gen_reg_rtx (SImode);
2581 emit_insn (gen_subsi3 (t0, GEN_INT (0), operands[2]));
2586 (define_insn "rotqmby_<mode>"
2587 [(set (match_operand:DTI 0 "spu_reg_operand" "=r,r")
2588 (lshiftrt:DTI (match_operand:DTI 1 "spu_reg_operand" "r,r")
2589 (mult:SI (neg:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I"))
2594 rotqmbyi\t%0,%1,-%F2"
2595 [(set_attr "type" "shuf")])
2600 (define_insn_and_split "<v>ashr<mode>3"
2601 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
2602 (ashiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
2603 (match_operand:VHSI 2 "spu_nonmem_operand" "r,W")))
2604 (clobber (match_scratch:VHSI 3 "=&r,X"))]
2608 rotma<bh>i\t%0,%1,-%<umask>2"
2609 "reload_completed && GET_CODE (operands[2]) == REG"
2610 [(set (match_dup:VHSI 3)
2611 (neg:VHSI (match_dup:VHSI 2)))
2612 (set (match_dup:VHSI 0)
2613 (ashiftrt:VHSI (match_dup:VHSI 1)
2614 (neg:VHSI (match_dup:VHSI 3))))]
2616 [(set_attr "type" "*,fx3")])
2618 (define_insn "<v>ashr<mode>3_imm"
2619 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r")
2620 (ashiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r")
2621 (match_operand:VHSI 2 "immediate_operand" "W")))]
2623 "rotma<bh>i\t%0,%1,-%<umask>2"
2624 [(set_attr "type" "fx3")])
2627 (define_insn "rotma_<mode>"
2628 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
2629 (ashiftrt:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
2630 (neg:VHSI (match_operand:VHSI 2 "spu_nonmem_operand" "r,W"))))]
2634 rotma<bh>i\t%0,%1,-%<nmask>2"
2635 [(set_attr "type" "fx3")])
2637 (define_insn_and_split "ashrdi3"
2638 [(set (match_operand:DI 0 "spu_reg_operand" "=r,r")
2639 (ashiftrt:DI (match_operand:DI 1 "spu_reg_operand" "r,r")
2640 (match_operand:SI 2 "spu_nonmem_operand" "r,I")))
2641 (clobber (match_scratch:TI 3 "=&r,&r"))
2642 (clobber (match_scratch:TI 4 "=&r,&r"))
2643 (clobber (match_scratch:SI 5 "=&r,&r"))]
2647 [(set (match_dup:DI 0)
2648 (ashiftrt:DI (match_dup:DI 1)
2651 rtx op0 = gen_rtx_REG (TImode, REGNO (operands[0]));
2652 rtx op0v = gen_rtx_REG (V4SImode, REGNO (op0));
2653 rtx op1 = gen_rtx_REG (TImode, REGNO (operands[1]));
2654 rtx op1s = gen_rtx_REG (SImode, REGNO (op1));
2655 rtx op2 = operands[2];
2656 rtx op3 = operands[3];
2657 rtx op4 = operands[4];
2658 rtx op5 = operands[5];
2660 if (GET_CODE (op2) == CONST_INT && INTVAL (op2) >= 63)
2662 rtx op0s = gen_rtx_REG (SImode, REGNO (op0));
2663 emit_insn (gen_ashrsi3 (op0s, op1s, GEN_INT (32)));
2664 emit_insn (gen_spu_fsm (op0v, op0s));
2666 else if (GET_CODE (op2) == CONST_INT && INTVAL (op2) >= 32)
2668 rtx op0d = gen_rtx_REG (V2DImode, REGNO (op0));
2669 HOST_WIDE_INT val = INTVAL (op2);
2670 emit_insn (gen_lshrti3 (op0, op1, GEN_INT (32)));
2671 emit_insn (gen_spu_xswd (op0d, op0v));
2673 emit_insn (gen_vashrv4si3 (op0v, op0v, spu_const (V4SImode, val - 32)));
2677 rtx op3v = gen_rtx_REG (V4SImode, REGNO (op3));
2678 unsigned char arr[16] = {
2679 0xff, 0xff, 0xff, 0xff,
2680 0xff, 0xff, 0xff, 0xff,
2681 0x00, 0x00, 0x00, 0x00,
2682 0x00, 0x00, 0x00, 0x00
2685 emit_insn (gen_ashrsi3 (op5, op1s, GEN_INT (31)));
2686 emit_move_insn (op4, array_to_constant (TImode, arr));
2687 emit_insn (gen_spu_fsm (op3v, op5));
2689 if (GET_CODE (operands[2]) == REG)
2691 emit_insn (gen_selb (op4, op3, op1, op4));
2692 emit_insn (gen_negsi2 (op5, op2));
2693 emit_insn (gen_rotqbybi_ti (op0, op4, op5));
2694 emit_insn (gen_rotqbi_ti (op0, op0, op5));
2698 HOST_WIDE_INT val = -INTVAL (op2);
2699 emit_insn (gen_selb (op0, op3, op1, op4));
2701 emit_insn (gen_rotqby_ti (op0, op0, GEN_INT ((val - 7) / 8)));
2703 emit_insn (gen_rotqbi_ti (op0, op0, GEN_INT (val % 8)));
2710 (define_insn_and_split "ashrti3"
2711 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2712 (ashiftrt:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2713 (match_operand:SI 2 "spu_nonmem_operand" "r,i")))]
2717 [(set (match_dup:TI 0)
2718 (ashiftrt:TI (match_dup:TI 1)
2721 rtx sign_shift = gen_reg_rtx (SImode);
2722 rtx sign_mask = gen_reg_rtx (TImode);
2723 rtx sign_mask_v4si = gen_rtx_SUBREG (V4SImode, sign_mask, 0);
2724 rtx op1_v4si = spu_gen_subreg (V4SImode, operands[1]);
2725 rtx t = gen_reg_rtx (TImode);
2726 emit_insn (gen_subsi3 (sign_shift, GEN_INT (128), force_reg (SImode, operands[2])));
2727 emit_insn (gen_vashrv4si3 (sign_mask_v4si, op1_v4si, spu_const (V4SImode, 31)));
2728 emit_insn (gen_fsm_ti (sign_mask, sign_mask));
2729 emit_insn (gen_ashlti3 (sign_mask, sign_mask, sign_shift));
2730 emit_insn (gen_lshrti3 (t, operands[1], operands[2]));
2731 emit_insn (gen_iorti3 (operands[0], t, sign_mask));
2735 ;; fsm is used after rotam to replicate the sign across the whole register.
2736 (define_insn "fsm_ti"
2737 [(set (match_operand:TI 0 "spu_reg_operand" "=r")
2738 (unspec:TI [(match_operand:TI 1 "spu_reg_operand" "r")] UNSPEC_FSM))]
2741 [(set_attr "type" "shuf")])
2746 (define_insn "<v>rotl<mode>3"
2747 [(set (match_operand:VHSI 0 "spu_reg_operand" "=r,r")
2748 (rotate:VHSI (match_operand:VHSI 1 "spu_reg_operand" "r,r")
2749 (match_operand:VHSI 2 "spu_nonmem_operand" "r,W")))]
2753 rot<bh>i\t%0,%1,%<umask>2"
2754 [(set_attr "type" "fx3")])
2756 (define_insn "rotlti3"
2757 [(set (match_operand:TI 0 "spu_reg_operand" "=&r,r,r,r")
2758 (rotate:TI (match_operand:TI 1 "spu_reg_operand" "r,r,r,r")
2759 (match_operand:SI 2 "spu_nonmem_operand" "r,O,P,I")))]
2762 rotqbybi\t%0,%1,%2\;rotqbi\t%0,%0,%2
2765 rotqbyi\t%0,%1,%h2\;rotqbii\t%0,%0,%e2"
2766 [(set_attr "length" "8,4,4,8")
2767 (set_attr "type" "multi1,shuf,shuf,multi1")])
2769 (define_insn "rotqbybi_ti"
2770 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2771 (rotate:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2772 (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2778 [(set_attr "type" "shuf,shuf")])
2780 (define_insn "rotqby_ti"
2781 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2782 (rotate:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2783 (mult:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2789 [(set_attr "type" "shuf,shuf")])
2791 (define_insn "rotqbi_ti"
2792 [(set (match_operand:TI 0 "spu_reg_operand" "=r,r")
2793 (rotate:TI (match_operand:TI 1 "spu_reg_operand" "r,r")
2794 (and:SI (match_operand:SI 2 "spu_nonmem_operand" "r,I")
2800 [(set_attr "type" "shuf,shuf")])
2803 ;; struct extract/insert
2804 ;; We handle mem's because GCC will generate invalid SUBREG's
2805 ;; and inefficient code.
2807 (define_expand "extv"
2808 [(set (match_operand:TI 0 "register_operand" "")
2809 (sign_extract:TI (match_operand 1 "nonimmediate_operand" "")
2810 (match_operand:SI 2 "const_int_operand" "")
2811 (match_operand:SI 3 "const_int_operand" "")))]
2814 spu_expand_extv (operands, 0);
2818 (define_expand "extzv"
2819 [(set (match_operand:TI 0 "register_operand" "")
2820 (zero_extract:TI (match_operand 1 "nonimmediate_operand" "")
2821 (match_operand:SI 2 "const_int_operand" "")
2822 (match_operand:SI 3 "const_int_operand" "")))]
2825 spu_expand_extv (operands, 1);
2829 (define_expand "insv"
2830 [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
2831 (match_operand:SI 1 "const_int_operand" "")
2832 (match_operand:SI 2 "const_int_operand" ""))
2833 (match_operand 3 "nonmemory_operand" ""))]
2835 { spu_expand_insv(operands); DONE; })
2837 ;; Simplify a number of patterns that get generated by extv, extzv,
2839 (define_insn_and_split "trunc_shr_ti<mode>"
2840 [(set (match_operand:QHSI 0 "spu_reg_operand" "=r")
2841 (truncate:QHSI (match_operator:TI 2 "shiftrt_operator" [(match_operand:TI 1 "spu_reg_operand" "0")
2848 spu_split_convert (operands);
2851 [(set_attr "type" "convert")
2852 (set_attr "length" "0")])
2854 (define_insn_and_split "trunc_shr_tidi"
2855 [(set (match_operand:DI 0 "spu_reg_operand" "=r")
2856 (truncate:DI (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 "shl_ext_<mode>ti"
2870 [(set (match_operand:TI 0 "spu_reg_operand" "=r")
2871 (ashift:TI (match_operator:TI 2 "extend_operator" [(match_operand:QHSI 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_diti"
2885 [(set (match_operand:TI 0 "spu_reg_operand" "=r")
2886 (ashift:TI (match_operator:TI 2 "extend_operator" [(match_operand:DI 1 "spu_reg_operand" "0")])
2893 spu_split_convert (operands);
2896 [(set_attr "type" "convert")
2897 (set_attr "length" "0")])
2899 (define_insn "sext_trunc_lshr_tiqisi"
2900 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2901 (sign_extend:SI (truncate:QI (match_operator:TI 2 "shiftrt_operator" [(match_operand:TI 1 "spu_reg_operand" "r")
2902 (const_int 120)]))))]
2905 [(set_attr "type" "fx3")])
2907 (define_insn "zext_trunc_lshr_tiqisi"
2908 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2909 (zero_extend:SI (truncate:QI (match_operator:TI 2 "shiftrt_operator" [(match_operand:TI 1 "spu_reg_operand" "r")
2910 (const_int 120)]))))]
2913 [(set_attr "type" "fx3")])
2915 (define_insn "sext_trunc_lshr_tihisi"
2916 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2917 (sign_extend:SI (truncate:HI (match_operator:TI 2 "shiftrt_operator" [(match_operand:TI 1 "spu_reg_operand" "r")
2918 (const_int 112)]))))]
2921 [(set_attr "type" "fx3")])
2923 (define_insn "zext_trunc_lshr_tihisi"
2924 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
2925 (zero_extend:SI (truncate:HI (match_operator:TI 2 "shiftrt_operator" [(match_operand:TI 1 "spu_reg_operand" "r")
2926 (const_int 112)]))))]
2929 [(set_attr "type" "fx3")])
2932 ;; String/block move insn.
2933 ;; Argument 0 is the destination
2934 ;; Argument 1 is the source
2935 ;; Argument 2 is the length
2936 ;; Argument 3 is the alignment
2938 (define_expand "movstrsi"
2939 [(parallel [(set (match_operand:BLK 0 "" "")
2940 (match_operand:BLK 1 "" ""))
2941 (use (match_operand:SI 2 "" ""))
2942 (use (match_operand:SI 3 "" ""))])]
2946 if (spu_expand_block_move (operands))
2955 (define_insn "indirect_jump"
2956 [(set (pc) (match_operand:SI 0 "spu_reg_operand" "r"))]
2959 [(set_attr "type" "br")])
2963 (label_ref (match_operand 0 "" "")))]
2966 [(set_attr "type" "br")])
2971 ;; This will be used for leaf functions, that don't save any regs and
2972 ;; don't have locals on stack, maybe... that is for functions that
2973 ;; don't change $sp and don't need to save $lr.
2974 (define_expand "return"
2979 ;; used in spu_expand_epilogue to generate return from a function and
2980 ;; explicitly set use of $lr.
2982 (define_insn "_return"
2986 [(set_attr "type" "br")])
2992 (define_insn "ceq_<mode>"
2993 [(set (match_operand:VQHSI 0 "spu_reg_operand" "=r,r")
2994 (eq:VQHSI (match_operand:VQHSI 1 "spu_reg_operand" "r,r")
2995 (match_operand:VQHSI 2 "spu_arith_operand" "r,B")))]
2999 ceq<bh>i\t%0,%1,%2")
3001 (define_insn_and_split "ceq_di"
3002 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3003 (eq:SI (match_operand:DI 1 "spu_reg_operand" "r")
3004 (match_operand:DI 2 "spu_reg_operand" "r")))]
3008 [(set (match_dup:SI 0)
3009 (eq:SI (match_dup:DI 1)
3012 rtx op0 = gen_rtx_REG (V4SImode, REGNO (operands[0]));
3013 rtx op1 = gen_rtx_REG (V4SImode, REGNO (operands[1]));
3014 rtx op2 = gen_rtx_REG (V4SImode, REGNO (operands[2]));
3015 emit_insn (gen_ceq_v4si (op0, op1, op2));
3016 emit_insn (gen_spu_gb (op0, op0));
3017 emit_insn (gen_cgt_si (operands[0], operands[0], GEN_INT (11)));
3022 ;; We provide the TI compares for completeness and because some parts of
3023 ;; gcc/libgcc use them, even though user code might never see it.
3024 (define_insn "ceq_ti"
3025 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3026 (eq:SI (match_operand:TI 1 "spu_reg_operand" "r")
3027 (match_operand:TI 2 "spu_reg_operand" "r")))]
3029 "ceq\t%0,%1,%2\;gb\t%0,%0\;ceqi\t%0,%0,15"
3030 [(set_attr "type" "multi0")
3031 (set_attr "length" "12")])
3033 (define_insn "ceq_<mode>"
3034 [(set (match_operand:<F2I> 0 "spu_reg_operand" "=r")
3035 (eq:<F2I> (match_operand:VSF 1 "spu_reg_operand" "r")
3036 (match_operand:VSF 2 "spu_reg_operand" "r")))]
3040 (define_insn "cmeq_<mode>"
3041 [(set (match_operand:<F2I> 0 "spu_reg_operand" "=r")
3042 (eq:<F2I> (abs:VSF (match_operand:VSF 1 "spu_reg_operand" "r"))
3043 (abs:VSF (match_operand:VSF 2 "spu_reg_operand" "r"))))]
3047 ;; These implementations will ignore checking of NaN or INF if
3048 ;; compiled with option -ffinite-math-only.
3049 (define_expand "ceq_df"
3050 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3051 (eq:SI (match_operand:DF 1 "spu_reg_operand" "r")
3052 (match_operand:DF 2 "const_zero_operand" "i")))]
3055 if (spu_arch == PROCESSOR_CELL)
3057 rtx ra = gen_reg_rtx (V4SImode);
3058 rtx rb = gen_reg_rtx (V4SImode);
3059 rtx temp = gen_reg_rtx (TImode);
3060 rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
3061 rtx temp2 = gen_reg_rtx (V4SImode);
3062 rtx biteq = gen_reg_rtx (V4SImode);
3063 rtx ahi_inf = gen_reg_rtx (V4SImode);
3064 rtx a_nan = gen_reg_rtx (V4SImode);
3065 rtx a_abs = gen_reg_rtx (V4SImode);
3066 rtx b_abs = gen_reg_rtx (V4SImode);
3067 rtx iszero = gen_reg_rtx (V4SImode);
3068 rtx sign_mask = gen_reg_rtx (V4SImode);
3069 rtx nan_mask = gen_reg_rtx (V4SImode);
3070 rtx hihi_promote = gen_reg_rtx (TImode);
3071 rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF,
3072 0x7FFFFFFF, 0xFFFFFFFF);
3074 emit_move_insn (sign_mask, pat);
3075 pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0,
3077 emit_move_insn (nan_mask, pat);
3078 pat = spu_const_from_ints (TImode, 0x00010203, 0x10111213,
3079 0x08090A0B, 0x18191A1B);
3080 emit_move_insn (hihi_promote, pat);
3082 emit_insn (gen_spu_convert (ra, operands[1]));
3083 emit_insn (gen_spu_convert (rb, operands[2]));
3084 emit_insn (gen_ceq_v4si (biteq, ra, rb));
3085 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, biteq),
3087 emit_insn (gen_andv4si3 (biteq, biteq, temp_v4si));
3089 emit_insn (gen_andv4si3 (a_abs, ra, sign_mask));
3090 emit_insn (gen_andv4si3 (b_abs, rb, sign_mask));
3091 if (!flag_finite_math_only)
3093 emit_insn (gen_clgt_v4si (a_nan, a_abs, nan_mask));
3094 emit_insn (gen_ceq_v4si (ahi_inf, a_abs, nan_mask));
3095 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, a_nan),
3097 emit_insn (gen_andv4si3 (temp2, temp_v4si, ahi_inf));
3098 emit_insn (gen_iorv4si3 (a_nan, a_nan, temp2));
3100 emit_insn (gen_iorv4si3 (temp2, a_abs, b_abs));
3101 emit_insn (gen_ceq_v4si (iszero, temp2, CONST0_RTX (V4SImode)));
3102 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, iszero),
3104 emit_insn (gen_andv4si3 (iszero, iszero, temp_v4si));
3105 emit_insn (gen_iorv4si3 (temp2, biteq, iszero));
3106 if (!flag_finite_math_only)
3108 emit_insn (gen_andc_v4si (temp2, temp2, a_nan));
3110 emit_insn (gen_shufb (operands[0], temp2, temp2, hihi_promote));
3115 (define_insn "ceq_<mode>_celledp"
3116 [(set (match_operand:<DF2I> 0 "spu_reg_operand" "=r")
3117 (eq:<DF2I> (match_operand:VDF 1 "spu_reg_operand" "r")
3118 (match_operand:VDF 2 "spu_reg_operand" "r")))]
3119 "spu_arch == PROCESSOR_CELLEDP"
3121 [(set_attr "type" "fpd")])
3123 (define_insn "cmeq_<mode>_celledp"
3124 [(set (match_operand:<DF2I> 0 "spu_reg_operand" "=r")
3125 (eq:<DF2I> (abs:VDF (match_operand:VDF 1 "spu_reg_operand" "r"))
3126 (abs:VDF (match_operand:VDF 2 "spu_reg_operand" "r"))))]
3127 "spu_arch == PROCESSOR_CELLEDP"
3129 [(set_attr "type" "fpd")])
3131 (define_expand "ceq_v2df"
3132 [(set (match_operand:V2DI 0 "spu_reg_operand" "=r")
3133 (eq:V2DI (match_operand:V2DF 1 "spu_reg_operand" "r")
3134 (match_operand:V2DF 2 "spu_reg_operand" "r")))]
3137 if (spu_arch == PROCESSOR_CELL)
3139 rtx ra = spu_gen_subreg (V4SImode, operands[1]);
3140 rtx rb = spu_gen_subreg (V4SImode, operands[2]);
3141 rtx temp = gen_reg_rtx (TImode);
3142 rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
3143 rtx temp2 = gen_reg_rtx (V4SImode);
3144 rtx biteq = gen_reg_rtx (V4SImode);
3145 rtx ahi_inf = gen_reg_rtx (V4SImode);
3146 rtx a_nan = gen_reg_rtx (V4SImode);
3147 rtx a_abs = gen_reg_rtx (V4SImode);
3148 rtx b_abs = gen_reg_rtx (V4SImode);
3149 rtx iszero = gen_reg_rtx (V4SImode);
3150 rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF,
3151 0x7FFFFFFF, 0xFFFFFFFF);
3152 rtx sign_mask = gen_reg_rtx (V4SImode);
3153 rtx nan_mask = gen_reg_rtx (V4SImode);
3154 rtx hihi_promote = gen_reg_rtx (TImode);
3156 emit_move_insn (sign_mask, pat);
3157 pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0,
3159 emit_move_insn (nan_mask, pat);
3160 pat = spu_const_from_ints (TImode, 0x00010203, 0x10111213,
3161 0x08090A0B, 0x18191A1B);
3162 emit_move_insn (hihi_promote, pat);
3164 emit_insn (gen_ceq_v4si (biteq, ra, rb));
3165 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, biteq),
3167 emit_insn (gen_andv4si3 (biteq, biteq, temp_v4si));
3168 emit_insn (gen_andv4si3 (a_abs, ra, sign_mask));
3169 emit_insn (gen_andv4si3 (b_abs, rb, sign_mask));
3170 emit_insn (gen_clgt_v4si (a_nan, a_abs, nan_mask));
3171 emit_insn (gen_ceq_v4si (ahi_inf, a_abs, nan_mask));
3172 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, a_nan),
3174 emit_insn (gen_andv4si3 (temp2, temp_v4si, ahi_inf));
3175 emit_insn (gen_iorv4si3 (a_nan, a_nan, temp2));
3176 emit_insn (gen_iorv4si3 (temp2, a_abs, b_abs));
3177 emit_insn (gen_ceq_v4si (iszero, temp2, CONST0_RTX (V4SImode)));
3178 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, iszero),
3180 emit_insn (gen_andv4si3 (iszero, iszero, temp_v4si));
3181 emit_insn (gen_iorv4si3 (temp2, biteq, iszero));
3182 emit_insn (gen_andc_v4si (temp2, temp2, a_nan));
3183 emit_insn (gen_shufb (operands[0], temp2, temp2, hihi_promote));
3188 (define_expand "cmeq_v2df"
3189 [(set (match_operand:V2DI 0 "spu_reg_operand" "=r")
3190 (eq:V2DI (abs:V2DF (match_operand:V2DF 1 "spu_reg_operand" "r"))
3191 (abs:V2DF (match_operand:V2DF 2 "spu_reg_operand" "r"))))]
3194 if (spu_arch == PROCESSOR_CELL)
3196 rtx ra = spu_gen_subreg (V4SImode, operands[1]);
3197 rtx rb = spu_gen_subreg (V4SImode, operands[2]);
3198 rtx temp = gen_reg_rtx (TImode);
3199 rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
3200 rtx temp2 = gen_reg_rtx (V4SImode);
3201 rtx biteq = gen_reg_rtx (V4SImode);
3202 rtx ahi_inf = gen_reg_rtx (V4SImode);
3203 rtx a_nan = gen_reg_rtx (V4SImode);
3204 rtx a_abs = gen_reg_rtx (V4SImode);
3205 rtx b_abs = gen_reg_rtx (V4SImode);
3207 rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF,
3208 0x7FFFFFFF, 0xFFFFFFFF);
3209 rtx sign_mask = gen_reg_rtx (V4SImode);
3210 rtx nan_mask = gen_reg_rtx (V4SImode);
3211 rtx hihi_promote = gen_reg_rtx (TImode);
3213 emit_move_insn (sign_mask, pat);
3215 pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0,
3217 emit_move_insn (nan_mask, pat);
3218 pat = spu_const_from_ints (TImode, 0x00010203, 0x10111213,
3219 0x08090A0B, 0x18191A1B);
3220 emit_move_insn (hihi_promote, pat);
3222 emit_insn (gen_andv4si3 (a_abs, ra, sign_mask));
3223 emit_insn (gen_andv4si3 (b_abs, rb, sign_mask));
3224 emit_insn (gen_ceq_v4si (biteq, a_abs, b_abs));
3225 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, biteq),
3227 emit_insn (gen_andv4si3 (biteq, biteq, temp_v4si));
3228 emit_insn (gen_clgt_v4si (a_nan, a_abs, nan_mask));
3229 emit_insn (gen_ceq_v4si (ahi_inf, a_abs, nan_mask));
3230 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, a_nan),
3232 emit_insn (gen_andv4si3 (temp2, temp_v4si, ahi_inf));
3233 emit_insn (gen_iorv4si3 (a_nan, a_nan, temp2));
3234 emit_insn (gen_andc_v4si (temp2, biteq, a_nan));
3235 emit_insn (gen_shufb (operands[0], temp2, temp2, hihi_promote));
3243 (define_insn "cgt_<mode>"
3244 [(set (match_operand:VQHSI 0 "spu_reg_operand" "=r,r")
3245 (gt:VQHSI (match_operand:VQHSI 1 "spu_reg_operand" "r,r")
3246 (match_operand:VQHSI 2 "spu_arith_operand" "r,B")))]
3250 cgt<bh>i\t%0,%1,%2")
3252 (define_insn "cgt_di_m1"
3253 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3254 (gt:SI (match_operand:DI 1 "spu_reg_operand" "r")
3259 (define_insn_and_split "cgt_di"
3260 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3261 (gt:SI (match_operand:DI 1 "spu_reg_operand" "r")
3262 (match_operand:DI 2 "spu_reg_operand" "r")))
3263 (clobber (match_scratch:V4SI 3 "=&r"))
3264 (clobber (match_scratch:V4SI 4 "=&r"))
3265 (clobber (match_scratch:V4SI 5 "=&r"))]
3269 [(set (match_dup:SI 0)
3270 (gt:SI (match_dup:DI 1)
3273 rtx op0 = gen_rtx_REG (V4SImode, REGNO (operands[0]));
3274 rtx op1 = gen_rtx_REG (V4SImode, REGNO (operands[1]));
3275 rtx op2 = gen_rtx_REG (V4SImode, REGNO (operands[2]));
3276 rtx op3 = operands[3];
3277 rtx op4 = operands[4];
3278 rtx op5 = operands[5];
3279 rtx op3d = gen_rtx_REG (V2DImode, REGNO (operands[3]));
3280 emit_insn (gen_clgt_v4si (op3, op1, op2));
3281 emit_insn (gen_ceq_v4si (op4, op1, op2));
3282 emit_insn (gen_cgt_v4si (op5, op1, op2));
3283 emit_insn (gen_spu_xswd (op3d, op3));
3284 emit_insn (gen_selb (op0, op5, op3, op4));
3288 (define_insn "cgt_ti_m1"
3289 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3290 (gt:SI (match_operand:TI 1 "spu_reg_operand" "r")
3295 (define_insn "cgt_ti"
3296 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3297 (gt:SI (match_operand:TI 1 "spu_reg_operand" "r")
3298 (match_operand:TI 2 "spu_reg_operand" "r")))
3299 (clobber (match_scratch:V4SI 3 "=&r"))
3300 (clobber (match_scratch:V4SI 4 "=&r"))
3301 (clobber (match_scratch:V4SI 5 "=&r"))]
3307 selb\t%0,%4,%0,%3\;\
3309 selb\t%0,%4,%0,%3\;\
3312 [(set_attr "type" "multi0")
3313 (set_attr "length" "36")])
3315 (define_insn "cgt_<mode>"
3316 [(set (match_operand:<F2I> 0 "spu_reg_operand" "=r")
3317 (gt:<F2I> (match_operand:VSF 1 "spu_reg_operand" "r")
3318 (match_operand:VSF 2 "spu_reg_operand" "r")))]
3322 (define_insn "cmgt_<mode>"
3323 [(set (match_operand:<F2I> 0 "spu_reg_operand" "=r")
3324 (gt:<F2I> (abs:VSF (match_operand:VSF 1 "spu_reg_operand" "r"))
3325 (abs:VSF (match_operand:VSF 2 "spu_reg_operand" "r"))))]
3329 (define_expand "cgt_df"
3330 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3331 (gt:SI (match_operand:DF 1 "spu_reg_operand" "r")
3332 (match_operand:DF 2 "const_zero_operand" "i")))]
3335 if (spu_arch == PROCESSOR_CELL)
3337 rtx ra = gen_reg_rtx (V4SImode);
3338 rtx rb = gen_reg_rtx (V4SImode);
3339 rtx zero = gen_reg_rtx (V4SImode);
3340 rtx temp = gen_reg_rtx (TImode);
3341 rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
3342 rtx temp2 = gen_reg_rtx (V4SImode);
3343 rtx hi_inf = gen_reg_rtx (V4SImode);
3344 rtx a_nan = gen_reg_rtx (V4SImode);
3345 rtx b_nan = gen_reg_rtx (V4SImode);
3346 rtx a_abs = gen_reg_rtx (V4SImode);
3347 rtx b_abs = gen_reg_rtx (V4SImode);
3348 rtx asel = gen_reg_rtx (V4SImode);
3349 rtx bsel = gen_reg_rtx (V4SImode);
3350 rtx abor = gen_reg_rtx (V4SImode);
3351 rtx bbor = gen_reg_rtx (V4SImode);
3352 rtx gt_hi = gen_reg_rtx (V4SImode);
3353 rtx gt_lo = gen_reg_rtx (V4SImode);
3354 rtx sign_mask = gen_reg_rtx (V4SImode);
3355 rtx nan_mask = gen_reg_rtx (V4SImode);
3356 rtx hi_promote = gen_reg_rtx (TImode);
3357 rtx borrow_shuffle = gen_reg_rtx (TImode);
3359 rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF,
3360 0x7FFFFFFF, 0xFFFFFFFF);
3361 emit_move_insn (sign_mask, pat);
3362 pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0,
3364 emit_move_insn (nan_mask, pat);
3365 pat = spu_const_from_ints (TImode, 0x00010203, 0x00010203,
3366 0x08090A0B, 0x08090A0B);
3367 emit_move_insn (hi_promote, pat);
3368 pat = spu_const_from_ints (TImode, 0x04050607, 0xC0C0C0C0,
3369 0x0C0D0E0F, 0xC0C0C0C0);
3370 emit_move_insn (borrow_shuffle, pat);
3372 emit_insn (gen_spu_convert (ra, operands[1]));
3373 emit_insn (gen_spu_convert (rb, operands[2]));
3374 emit_insn (gen_andv4si3 (a_abs, ra, sign_mask));
3375 emit_insn (gen_andv4si3 (b_abs, rb, sign_mask));
3377 if (!flag_finite_math_only)
3379 /* check if ra is NaN */
3380 emit_insn (gen_ceq_v4si (hi_inf, a_abs, nan_mask));
3381 emit_insn (gen_clgt_v4si (a_nan, a_abs, nan_mask));
3382 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, a_nan),
3384 emit_insn (gen_andv4si3 (temp2, temp_v4si, hi_inf));
3385 emit_insn (gen_iorv4si3 (a_nan, a_nan, temp2));
3386 emit_insn (gen_shufb (a_nan, a_nan, a_nan, hi_promote));
3388 /* check if rb is NaN */
3389 emit_insn (gen_ceq_v4si (hi_inf, b_abs, nan_mask));
3390 emit_insn (gen_clgt_v4si (b_nan, b_abs, nan_mask));
3391 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, b_nan),
3393 emit_insn (gen_andv4si3 (temp2, temp_v4si, hi_inf));
3394 emit_insn (gen_iorv4si3 (b_nan, b_nan, temp2));
3395 emit_insn (gen_shufb (b_nan, b_nan, b_nan, hi_promote));
3397 /* check if ra or rb is NaN */
3398 emit_insn (gen_iorv4si3 (a_nan, a_nan, b_nan));
3400 emit_move_insn (zero, CONST0_RTX (V4SImode));
3401 emit_insn (gen_vashrv4si3 (asel, ra, spu_const (V4SImode, 31)));
3402 emit_insn (gen_shufb (asel, asel, asel, hi_promote));
3403 emit_insn (gen_bg_v4si (abor, zero, a_abs));
3404 emit_insn (gen_shufb (abor, abor, abor, borrow_shuffle));
3405 emit_insn (gen_sfx_v4si (abor, zero, a_abs, abor));
3406 emit_insn (gen_selb (abor, a_abs, abor, asel));
3408 emit_insn (gen_vashrv4si3 (bsel, rb, spu_const (V4SImode, 31)));
3409 emit_insn (gen_shufb (bsel, bsel, bsel, hi_promote));
3410 emit_insn (gen_bg_v4si (bbor, zero, b_abs));
3411 emit_insn (gen_shufb (bbor, bbor, bbor, borrow_shuffle));
3412 emit_insn (gen_sfx_v4si (bbor, zero, b_abs, bbor));
3413 emit_insn (gen_selb (bbor, b_abs, bbor, bsel));
3415 emit_insn (gen_cgt_v4si (gt_hi, abor, bbor));
3416 emit_insn (gen_clgt_v4si (gt_lo, abor, bbor));
3417 emit_insn (gen_ceq_v4si (temp2, abor, bbor));
3418 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, gt_lo),
3420 emit_insn (gen_andv4si3 (temp2, temp2, temp_v4si));
3421 emit_insn (gen_iorv4si3 (temp2, gt_hi, temp2));
3422 emit_insn (gen_shufb (temp2, temp2, temp2, hi_promote));
3423 if (!flag_finite_math_only)
3425 /* correct for NaNs */
3426 emit_insn (gen_andc_v4si (temp2, temp2, a_nan));
3428 emit_insn (gen_spu_convert (operands[0], temp2));
3433 (define_insn "cgt_<mode>_celledp"
3434 [(set (match_operand:<DF2I> 0 "spu_reg_operand" "=r")
3435 (gt:<DF2I> (match_operand:VDF 1 "spu_reg_operand" "r")
3436 (match_operand:VDF 2 "spu_reg_operand" "r")))]
3437 "spu_arch == PROCESSOR_CELLEDP"
3439 [(set_attr "type" "fpd")])
3441 (define_insn "cmgt_<mode>_celledp"
3442 [(set (match_operand:<DF2I> 0 "spu_reg_operand" "=r")
3443 (gt:<DF2I> (abs:VDF (match_operand:VDF 1 "spu_reg_operand" "r"))
3444 (abs:VDF (match_operand:VDF 2 "spu_reg_operand" "r"))))]
3445 "spu_arch == PROCESSOR_CELLEDP"
3447 [(set_attr "type" "fpd")])
3449 (define_expand "cgt_v2df"
3450 [(set (match_operand:V2DI 0 "spu_reg_operand" "=r")
3451 (gt:V2DI (match_operand:V2DF 1 "spu_reg_operand" "r")
3452 (match_operand:V2DF 2 "spu_reg_operand" "r")))]
3455 if (spu_arch == PROCESSOR_CELL)
3457 rtx ra = spu_gen_subreg (V4SImode, operands[1]);
3458 rtx rb = spu_gen_subreg (V4SImode, operands[2]);
3459 rtx zero = gen_reg_rtx (V4SImode);
3460 rtx temp = gen_reg_rtx (TImode);
3461 rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
3462 rtx temp2 = gen_reg_rtx (V4SImode);
3463 rtx hi_inf = gen_reg_rtx (V4SImode);
3464 rtx a_nan = gen_reg_rtx (V4SImode);
3465 rtx b_nan = gen_reg_rtx (V4SImode);
3466 rtx a_abs = gen_reg_rtx (V4SImode);
3467 rtx b_abs = gen_reg_rtx (V4SImode);
3468 rtx asel = gen_reg_rtx (V4SImode);
3469 rtx bsel = gen_reg_rtx (V4SImode);
3470 rtx abor = gen_reg_rtx (V4SImode);
3471 rtx bbor = gen_reg_rtx (V4SImode);
3472 rtx gt_hi = gen_reg_rtx (V4SImode);
3473 rtx gt_lo = gen_reg_rtx (V4SImode);
3474 rtx sign_mask = gen_reg_rtx (V4SImode);
3475 rtx nan_mask = gen_reg_rtx (V4SImode);
3476 rtx hi_promote = gen_reg_rtx (TImode);
3477 rtx borrow_shuffle = gen_reg_rtx (TImode);
3478 rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF,
3479 0x7FFFFFFF, 0xFFFFFFFF);
3480 emit_move_insn (sign_mask, pat);
3481 pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0,
3483 emit_move_insn (nan_mask, pat);
3484 pat = spu_const_from_ints (TImode, 0x00010203, 0x00010203,
3485 0x08090A0B, 0x08090A0B);
3486 emit_move_insn (hi_promote, pat);
3487 pat = spu_const_from_ints (TImode, 0x04050607, 0xC0C0C0C0,
3488 0x0C0D0E0F, 0xC0C0C0C0);
3489 emit_move_insn (borrow_shuffle, pat);
3491 emit_insn (gen_andv4si3 (a_abs, ra, sign_mask));
3492 emit_insn (gen_ceq_v4si (hi_inf, a_abs, nan_mask));
3493 emit_insn (gen_clgt_v4si (a_nan, a_abs, nan_mask));
3494 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, a_nan),
3496 emit_insn (gen_andv4si3 (temp2, temp_v4si, hi_inf));
3497 emit_insn (gen_iorv4si3 (a_nan, a_nan, temp2));
3498 emit_insn (gen_shufb (a_nan, a_nan, a_nan, hi_promote));
3499 emit_insn (gen_andv4si3 (b_abs, rb, sign_mask));
3500 emit_insn (gen_ceq_v4si (hi_inf, b_abs, nan_mask));
3501 emit_insn (gen_clgt_v4si (b_nan, b_abs, nan_mask));
3502 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, b_nan),
3504 emit_insn (gen_andv4si3 (temp2, temp_v4si, hi_inf));
3505 emit_insn (gen_iorv4si3 (b_nan, b_nan, temp2));
3506 emit_insn (gen_shufb (b_nan, b_nan, b_nan, hi_promote));
3507 emit_insn (gen_iorv4si3 (a_nan, a_nan, b_nan));
3508 emit_move_insn (zero, CONST0_RTX (V4SImode));
3509 emit_insn (gen_vashrv4si3 (asel, ra, spu_const (V4SImode, 31)));
3510 emit_insn (gen_shufb (asel, asel, asel, hi_promote));
3511 emit_insn (gen_bg_v4si (abor, zero, a_abs));
3512 emit_insn (gen_shufb (abor, abor, abor, borrow_shuffle));
3513 emit_insn (gen_sfx_v4si (abor, zero, a_abs, abor));
3514 emit_insn (gen_selb (abor, a_abs, abor, asel));
3515 emit_insn (gen_vashrv4si3 (bsel, rb, spu_const (V4SImode, 31)));
3516 emit_insn (gen_shufb (bsel, bsel, bsel, hi_promote));
3517 emit_insn (gen_bg_v4si (bbor, zero, b_abs));
3518 emit_insn (gen_shufb (bbor, bbor, bbor, borrow_shuffle));
3519 emit_insn (gen_sfx_v4si (bbor, zero, b_abs, bbor));
3520 emit_insn (gen_selb (bbor, b_abs, bbor, bsel));
3521 emit_insn (gen_cgt_v4si (gt_hi, abor, bbor));
3522 emit_insn (gen_clgt_v4si (gt_lo, abor, bbor));
3523 emit_insn (gen_ceq_v4si (temp2, abor, bbor));
3524 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, gt_lo),
3526 emit_insn (gen_andv4si3 (temp2, temp2, temp_v4si));
3527 emit_insn (gen_iorv4si3 (temp2, gt_hi, temp2));
3529 emit_insn (gen_shufb (temp2, temp2, temp2, hi_promote));
3530 emit_insn (gen_andc_v4si (temp2, temp2, a_nan));
3531 emit_move_insn (operands[0], spu_gen_subreg (V2DImode, temp2));
3536 (define_expand "cmgt_v2df"
3537 [(set (match_operand:V2DI 0 "spu_reg_operand" "=r")
3538 (gt:V2DI (abs:V2DF (match_operand:V2DF 1 "spu_reg_operand" "r"))
3539 (abs:V2DF (match_operand:V2DF 2 "spu_reg_operand" "r"))))]
3542 if (spu_arch == PROCESSOR_CELL)
3544 rtx ra = spu_gen_subreg (V4SImode, operands[1]);
3545 rtx rb = spu_gen_subreg (V4SImode, operands[2]);
3546 rtx temp = gen_reg_rtx (TImode);
3547 rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
3548 rtx temp2 = gen_reg_rtx (V4SImode);
3549 rtx hi_inf = gen_reg_rtx (V4SImode);
3550 rtx a_nan = gen_reg_rtx (V4SImode);
3551 rtx b_nan = gen_reg_rtx (V4SImode);
3552 rtx a_abs = gen_reg_rtx (V4SImode);
3553 rtx b_abs = gen_reg_rtx (V4SImode);
3554 rtx gt_hi = gen_reg_rtx (V4SImode);
3555 rtx gt_lo = gen_reg_rtx (V4SImode);
3556 rtx sign_mask = gen_reg_rtx (V4SImode);
3557 rtx nan_mask = gen_reg_rtx (V4SImode);
3558 rtx hi_promote = gen_reg_rtx (TImode);
3559 rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF,
3560 0x7FFFFFFF, 0xFFFFFFFF);
3561 emit_move_insn (sign_mask, pat);
3562 pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0,
3564 emit_move_insn (nan_mask, pat);
3565 pat = spu_const_from_ints (TImode, 0x00010203, 0x00010203,
3566 0x08090A0B, 0x08090A0B);
3567 emit_move_insn (hi_promote, pat);
3569 emit_insn (gen_andv4si3 (a_abs, ra, sign_mask));
3570 emit_insn (gen_ceq_v4si (hi_inf, a_abs, nan_mask));
3571 emit_insn (gen_clgt_v4si (a_nan, a_abs, nan_mask));
3572 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, a_nan),
3574 emit_insn (gen_andv4si3 (temp2, temp_v4si, hi_inf));
3575 emit_insn (gen_iorv4si3 (a_nan, a_nan, temp2));
3576 emit_insn (gen_shufb (a_nan, a_nan, a_nan, hi_promote));
3577 emit_insn (gen_andv4si3 (b_abs, rb, sign_mask));
3578 emit_insn (gen_ceq_v4si (hi_inf, b_abs, nan_mask));
3579 emit_insn (gen_clgt_v4si (b_nan, b_abs, nan_mask));
3580 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, b_nan),
3582 emit_insn (gen_andv4si3 (temp2, temp_v4si, hi_inf));
3583 emit_insn (gen_iorv4si3 (b_nan, b_nan, temp2));
3584 emit_insn (gen_shufb (b_nan, b_nan, b_nan, hi_promote));
3585 emit_insn (gen_iorv4si3 (a_nan, a_nan, b_nan));
3587 emit_insn (gen_clgt_v4si (gt_hi, a_abs, b_abs));
3588 emit_insn (gen_clgt_v4si (gt_lo, a_abs, b_abs));
3589 emit_insn (gen_ceq_v4si (temp2, a_abs, b_abs));
3590 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, gt_lo),
3592 emit_insn (gen_andv4si3 (temp2, temp2, temp_v4si));
3593 emit_insn (gen_iorv4si3 (temp2, gt_hi, temp2));
3594 emit_insn (gen_shufb (temp2, temp2, temp2, hi_promote));
3595 emit_insn (gen_andc_v4si (temp2, temp2, a_nan));
3596 emit_move_insn (operands[0], spu_gen_subreg (V2DImode, temp2));
3604 (define_insn "clgt_<mode>"
3605 [(set (match_operand:VQHSI 0 "spu_reg_operand" "=r,r")
3606 (gtu:VQHSI (match_operand:VQHSI 1 "spu_reg_operand" "r,r")
3607 (match_operand:VQHSI 2 "spu_arith_operand" "r,B")))]
3611 clgt<bh>i\t%0,%1,%2")
3613 (define_insn_and_split "clgt_di"
3614 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3615 (gtu:SI (match_operand:DI 1 "spu_reg_operand" "r")
3616 (match_operand:DI 2 "spu_reg_operand" "r")))
3617 (clobber (match_scratch:V4SI 3 "=&r"))
3618 (clobber (match_scratch:V4SI 4 "=&r"))
3619 (clobber (match_scratch:V4SI 5 "=&r"))]
3623 [(set (match_dup:SI 0)
3624 (gtu:SI (match_dup:DI 1)
3627 rtx op0 = gen_rtx_REG (V4SImode, REGNO (operands[0]));
3628 rtx op1 = gen_rtx_REG (V4SImode, REGNO (operands[1]));
3629 rtx op2 = gen_rtx_REG (V4SImode, REGNO (operands[2]));
3630 rtx op3 = operands[3];
3631 rtx op4 = operands[4];
3632 rtx op5 = operands[5];
3633 rtx op5d = gen_rtx_REG (V2DImode, REGNO (operands[5]));
3634 emit_insn (gen_clgt_v4si (op3, op1, op2));
3635 emit_insn (gen_ceq_v4si (op4, op1, op2));
3636 emit_insn (gen_spu_xswd (op5d, op3));
3637 emit_insn (gen_selb (op0, op3, op5, op4));
3641 (define_insn "clgt_ti"
3642 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
3643 (gtu:SI (match_operand:TI 1 "spu_reg_operand" "r")
3644 (match_operand:TI 2 "spu_reg_operand" "r")))
3645 (clobber (match_scratch:V4SI 3 "=&r"))
3646 (clobber (match_scratch:V4SI 4 "=&r"))]
3651 selb\t%0,%4,%0,%3\;\
3653 selb\t%0,%4,%0,%3\;\
3656 [(set_attr "type" "multi0")
3657 (set_attr "length" "32")])
3661 (define_insn "dftsv_celledp"
3662 [(set (match_operand:V2DI 0 "spu_reg_operand" "=r")
3663 (unspec:V2DI [(match_operand:V2DF 1 "spu_reg_operand" "r")
3664 (match_operand:SI 2 "const_int_operand" "i")]
3666 "spu_arch == PROCESSOR_CELLEDP"
3668 [(set_attr "type" "fpd")])
3670 (define_expand "dftsv"
3671 [(set (match_operand:V2DI 0 "spu_reg_operand" "=r")
3672 (unspec:V2DI [(match_operand:V2DF 1 "spu_reg_operand" "r")
3673 (match_operand:SI 2 "const_int_operand" "i")]
3677 if (spu_arch == PROCESSOR_CELL)
3679 rtx result = gen_reg_rtx (V4SImode);
3680 emit_move_insn (result, CONST0_RTX (V4SImode));
3682 if (INTVAL (operands[2]))
3684 rtx ra = spu_gen_subreg (V4SImode, operands[1]);
3685 rtx abs = gen_reg_rtx (V4SImode);
3686 rtx sign = gen_reg_rtx (V4SImode);
3687 rtx temp = gen_reg_rtx (TImode);
3688 rtx temp_v4si = spu_gen_subreg (V4SImode, temp);
3689 rtx temp2 = gen_reg_rtx (V4SImode);
3690 rtx pat = spu_const_from_ints (V4SImode, 0x7FFFFFFF, 0xFFFFFFFF,
3691 0x7FFFFFFF, 0xFFFFFFFF);
3692 rtx sign_mask = gen_reg_rtx (V4SImode);
3693 rtx hi_promote = gen_reg_rtx (TImode);
3694 emit_move_insn (sign_mask, pat);
3695 pat = spu_const_from_ints (TImode, 0x00010203, 0x00010203,
3696 0x08090A0B, 0x08090A0B);
3697 emit_move_insn (hi_promote, pat);
3699 emit_insn (gen_vashrv4si3 (sign, ra, spu_const (V4SImode, 31)));
3700 emit_insn (gen_shufb (sign, sign, sign, hi_promote));
3701 emit_insn (gen_andv4si3 (abs, ra, sign_mask));
3703 /* NaN or +inf or -inf */
3704 if (INTVAL (operands[2]) & 0x70)
3706 rtx nan_mask = gen_reg_rtx (V4SImode);
3707 rtx isinf = gen_reg_rtx (V4SImode);
3708 pat = spu_const_from_ints (V4SImode, 0x7FF00000, 0x0,
3710 emit_move_insn (nan_mask, pat);
3711 emit_insn (gen_ceq_v4si (isinf, abs, nan_mask));
3714 if (INTVAL (operands[2]) & 0x40)
3716 rtx isnan = gen_reg_rtx (V4SImode);
3717 emit_insn (gen_clgt_v4si (isnan, abs, nan_mask));
3718 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, isnan),
3720 emit_insn (gen_andv4si3 (temp2, temp_v4si, isinf));
3721 emit_insn (gen_iorv4si3 (isnan, isnan, temp2));
3722 emit_insn (gen_shufb (isnan, isnan, isnan, hi_promote));
3723 emit_insn (gen_iorv4si3 (result, result, isnan));
3726 if (INTVAL (operands[2]) & 0x30)
3728 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, isinf),
3730 emit_insn (gen_andv4si3 (isinf, isinf, temp_v4si));
3731 emit_insn (gen_shufb (isinf, isinf, isinf, hi_promote));
3734 if (INTVAL (operands[2]) & 0x20)
3736 emit_insn (gen_andc_v4si (temp2, isinf, sign));
3737 emit_insn (gen_iorv4si3 (result, result, temp2));
3740 if (INTVAL (operands[2]) & 0x10)
3742 emit_insn (gen_andv4si3 (temp2, isinf, sign));
3743 emit_insn (gen_iorv4si3 (result, result, temp2));
3749 if (INTVAL (operands[2]) & 0xF)
3751 rtx iszero = gen_reg_rtx (V4SImode);
3752 emit_insn (gen_ceq_v4si (iszero, abs, CONST0_RTX (V4SImode)));
3753 emit_insn (gen_rotlti3 (temp, spu_gen_subreg (TImode, iszero),
3755 emit_insn (gen_andv4si3 (iszero, iszero, temp_v4si));
3758 if (INTVAL (operands[2]) & 0x3)
3760 rtx isdenorm = gen_reg_rtx (V4SImode);
3761 rtx denorm_mask = gen_reg_rtx (V4SImode);
3762 emit_move_insn (denorm_mask, spu_const (V4SImode, 0xFFFFF));
3763 emit_insn (gen_clgt_v4si (isdenorm, abs, denorm_mask));
3764 emit_insn (gen_nor_v4si (isdenorm, isdenorm, iszero));
3765 emit_insn (gen_shufb (isdenorm, isdenorm,
3766 isdenorm, hi_promote));
3768 if (INTVAL (operands[2]) & 0x2)
3770 emit_insn (gen_andc_v4si (temp2, isdenorm, sign));
3771 emit_insn (gen_iorv4si3 (result, result, temp2));
3774 if (INTVAL (operands[2]) & 0x1)
3776 emit_insn (gen_andv4si3 (temp2, isdenorm, sign));
3777 emit_insn (gen_iorv4si3 (result, result, temp2));
3782 if (INTVAL (operands[2]) & 0xC)
3784 emit_insn (gen_shufb (iszero, iszero, iszero, hi_promote));
3786 if (INTVAL (operands[2]) & 0x8)
3788 emit_insn (gen_andc_v4si (temp2, iszero, sign));
3789 emit_insn (gen_iorv4si3 (result, result, temp2));
3792 if (INTVAL (operands[2]) & 0x4)
3794 emit_insn (gen_andv4si3 (temp2, iszero, sign));
3795 emit_insn (gen_iorv4si3 (result, result, temp2));
3800 emit_move_insn (operands[0], spu_gen_subreg (V2DImode, result));
3810 (if_then_else (match_operator 1 "branch_comparison_operator"
3812 "spu_reg_operand" "r")
3814 (label_ref (match_operand 0 "" ""))
3818 [(set_attr "type" "br")])
3822 (if_then_else (match_operator 0 "branch_comparison_operator"
3824 "spu_reg_operand" "r")
3830 [(set_attr "type" "br")])
3834 (if_then_else (match_operator 1 "branch_comparison_operator"
3836 "spu_reg_operand" "r")
3839 (label_ref (match_operand 0 "" ""))))]
3842 [(set_attr "type" "br")])
3846 (if_then_else (match_operator 0 "branch_comparison_operator"
3848 "spu_reg_operand" "r")
3854 [(set_attr "type" "br")])
3857 ;; vector conditional compare patterns
3858 (define_expand "vcond<mode>"
3859 [(set (match_operand:VCMP 0 "spu_reg_operand" "=r")
3861 (match_operator 3 "comparison_operator"
3862 [(match_operand:VCMP 4 "spu_reg_operand" "r")
3863 (match_operand:VCMP 5 "spu_reg_operand" "r")])
3864 (match_operand:VCMP 1 "spu_reg_operand" "r")
3865 (match_operand:VCMP 2 "spu_reg_operand" "r")))]
3868 if (spu_emit_vector_cond_expr (operands[0], operands[1], operands[2],
3869 operands[3], operands[4], operands[5]))
3875 (define_expand "vcondu<mode>"
3876 [(set (match_operand:VCMPU 0 "spu_reg_operand" "=r")
3878 (match_operator 3 "comparison_operator"
3879 [(match_operand:VCMPU 4 "spu_reg_operand" "r")
3880 (match_operand:VCMPU 5 "spu_reg_operand" "r")])
3881 (match_operand:VCMPU 1 "spu_reg_operand" "r")
3882 (match_operand:VCMPU 2 "spu_reg_operand" "r")))]
3885 if (spu_emit_vector_cond_expr (operands[0], operands[1], operands[2],
3886 operands[3], operands[4], operands[5]))
3893 ;; branch on condition
3895 (define_expand "cbranch<mode>4"
3896 [(use (match_operator 0 "ordered_comparison_operator"
3897 [(match_operand:VQHSI 1 "spu_reg_operand" "")
3898 (match_operand:VQHSI 2 "spu_nonmem_operand" "")]))
3899 (use (match_operand 3 ""))]
3901 { spu_emit_branch_or_set (0, operands[0], operands); DONE; })
3903 (define_expand "cbranch<mode>4"
3904 [(use (match_operator 0 "ordered_comparison_operator"
3905 [(match_operand:DTI 1 "spu_reg_operand" "")
3906 (match_operand:DTI 2 "spu_reg_operand" "")]))
3907 (use (match_operand 3 ""))]
3909 { spu_emit_branch_or_set (0, operands[0], operands); DONE; })
3911 (define_expand "cbranch<mode>4"
3912 [(use (match_operator 0 "ordered_comparison_operator"
3913 [(match_operand:VSF 1 "spu_reg_operand" "")
3914 (match_operand:VSF 2 "spu_reg_operand" "")]))
3915 (use (match_operand 3 ""))]
3917 { spu_emit_branch_or_set (0, operands[0], operands); DONE; })
3919 (define_expand "cbranchdf4"
3920 [(use (match_operator 0 "ordered_comparison_operator"
3921 [(match_operand:DF 1 "spu_reg_operand" "")
3922 (match_operand:DF 2 "spu_reg_operand" "")]))
3923 (use (match_operand 3 ""))]
3925 { spu_emit_branch_or_set (0, operands[0], operands); DONE; })
3930 (define_expand "cstore<mode>4"
3931 [(use (match_operator 1 "ordered_comparison_operator"
3932 [(match_operand:VQHSI 2 "spu_reg_operand" "")
3933 (match_operand:VQHSI 3 "spu_nonmem_operand" "")]))
3934 (clobber (match_operand:SI 0 "spu_reg_operand"))]
3936 { spu_emit_branch_or_set (1, operands[1], operands); DONE; })
3938 (define_expand "cstore<mode>4"
3939 [(use (match_operator 1 "ordered_comparison_operator"
3940 [(match_operand:DTI 2 "spu_reg_operand" "")
3941 (match_operand:DTI 3 "spu_reg_operand" "")]))
3942 (clobber (match_operand:SI 0 "spu_reg_operand"))]
3944 { spu_emit_branch_or_set (1, operands[1], operands); DONE; })
3946 (define_expand "cstore<mode>4"
3947 [(use (match_operator 1 "ordered_comparison_operator"
3948 [(match_operand:VSF 2 "spu_reg_operand" "")
3949 (match_operand:VSF 3 "spu_reg_operand" "")]))
3950 (clobber (match_operand:SI 0 "spu_reg_operand"))]
3952 { spu_emit_branch_or_set (1, operands[1], operands); DONE; })
3954 (define_expand "cstoredf4"
3955 [(use (match_operator 1 "ordered_comparison_operator"
3956 [(match_operand:DF 2 "spu_reg_operand" "")
3957 (match_operand:DF 3 "spu_reg_operand" "")]))
3958 (clobber (match_operand:SI 0 "spu_reg_operand"))]
3960 { spu_emit_branch_or_set (1, operands[1], operands); DONE; })
3965 ;; Define this first one so HAVE_conditional_move is defined.
3966 (define_insn "movcc_dummy"
3967 [(set (match_operand 0 "" "")
3968 (if_then_else (match_operand 1 "" "")
3969 (match_operand 2 "" "")
3970 (match_operand 3 "" "")))]
3974 (define_expand "mov<mode>cc"
3975 [(set (match_operand:ALL 0 "spu_reg_operand" "")
3976 (if_then_else:ALL (match_operand 1 "ordered_comparison_operator" "")
3977 (match_operand:ALL 2 "spu_reg_operand" "")
3978 (match_operand:ALL 3 "spu_reg_operand" "")))]
3981 spu_emit_branch_or_set(2, operands[1], operands);
3985 ;; This pattern is used when the result of a compare is not large
3986 ;; enough to use in a selb when expanding conditional moves.
3987 (define_expand "extend_compare"
3988 [(set (match_operand 0 "spu_reg_operand" "=r")
3989 (unspec [(match_operand 1 "spu_reg_operand" "r")] UNSPEC_EXTEND_CMP))]
3992 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
3993 gen_rtx_UNSPEC (GET_MODE (operands[0]),
3994 gen_rtvec (1, operands[1]),
3995 UNSPEC_EXTEND_CMP)));
3999 (define_insn "extend_compare<mode>"
4000 [(set (match_operand:ALL 0 "spu_reg_operand" "=r")
4001 (unspec:ALL [(match_operand 1 "spu_reg_operand" "r")] UNSPEC_EXTEND_CMP))]
4004 [(set_attr "type" "shuf")])
4009 ;; operand 0 is index
4010 ;; operand 1 is the minimum bound
4011 ;; operand 2 is the maximum bound - minimum bound + 1
4012 ;; operand 3 is CODE_LABEL for the table;
4013 ;; operand 4 is the CODE_LABEL to go to if index out of range.
4014 (define_expand "casesi"
4015 [(match_operand:SI 0 "spu_reg_operand" "")
4016 (match_operand:SI 1 "immediate_operand" "")
4017 (match_operand:SI 2 "immediate_operand" "")
4018 (match_operand 3 "" "")
4019 (match_operand 4 "" "")]
4022 rtx table = gen_reg_rtx (SImode);
4023 rtx index = gen_reg_rtx (SImode);
4024 rtx sindex = gen_reg_rtx (SImode);
4025 rtx addr = gen_reg_rtx (Pmode);
4027 emit_move_insn (table, gen_rtx_LABEL_REF (SImode, operands[3]));
4029 emit_insn (gen_subsi3(index, operands[0], force_reg(SImode, operands[1])));
4030 emit_insn (gen_ashlsi3(sindex, index, GEN_INT (2)));
4031 emit_move_insn (addr, gen_rtx_MEM (SImode,
4032 gen_rtx_PLUS (SImode, table, sindex)));
4034 emit_insn (gen_addsi3 (addr, addr, table));
4036 emit_cmp_and_jump_insns (index, operands[2], GTU, NULL_RTX, SImode, 1, operands[4]);
4037 emit_jump_insn (gen_tablejump (addr, operands[3]));
4041 (define_insn "tablejump"
4042 [(set (pc) (match_operand:SI 0 "spu_reg_operand" "r"))
4043 (use (label_ref (match_operand 1 "" "")))]
4046 [(set_attr "type" "br")])
4051 ;; Note that operand 1 is total size of args, in bytes,
4052 ;; and what the call insn wants is the number of words.
4053 (define_expand "sibcall"
4055 [(call (match_operand:QI 0 "call_operand" "")
4056 (match_operand:QI 1 "" ""))
4060 if (! call_operand (operands[0], QImode))
4061 XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
4064 (define_insn "_sibcall"
4066 [(call (match_operand:QI 0 "call_operand" "R,S")
4067 (match_operand:QI 1 "" "i,i"))
4069 "SIBLING_CALL_P(insn)"
4073 [(set_attr "type" "br,br")])
4075 (define_expand "sibcall_value"
4077 [(set (match_operand 0 "" "")
4078 (call (match_operand:QI 1 "call_operand" "")
4079 (match_operand:QI 2 "" "")))
4083 if (! call_operand (operands[1], QImode))
4084 XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
4087 (define_insn "_sibcall_value"
4089 [(set (match_operand 0 "" "")
4090 (call (match_operand:QI 1 "call_operand" "R,S")
4091 (match_operand:QI 2 "" "i,i")))
4093 "SIBLING_CALL_P(insn)"
4097 [(set_attr "type" "br,br")])
4099 ;; Note that operand 1 is total size of args, in bytes,
4100 ;; and what the call insn wants is the number of words.
4101 (define_expand "call"
4103 [(call (match_operand:QI 0 "call_operand" "")
4104 (match_operand:QI 1 "" ""))
4105 (clobber (reg:SI 0))
4106 (clobber (reg:SI 130))])]
4109 if (! call_operand (operands[0], QImode))
4110 XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
4113 (define_insn "_call"
4115 [(call (match_operand:QI 0 "call_operand" "R,S,T")
4116 (match_operand:QI 1 "" "i,i,i"))
4117 (clobber (reg:SI 0))
4118 (clobber (reg:SI 130))])]
4124 [(set_attr "type" "br")])
4126 (define_expand "call_value"
4128 [(set (match_operand 0 "" "")
4129 (call (match_operand:QI 1 "call_operand" "")
4130 (match_operand:QI 2 "" "")))
4131 (clobber (reg:SI 0))
4132 (clobber (reg:SI 130))])]
4135 if (! call_operand (operands[1], QImode))
4136 XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
4139 (define_insn "_call_value"
4141 [(set (match_operand 0 "" "")
4142 (call (match_operand:QI 1 "call_operand" "R,S,T")
4143 (match_operand:QI 2 "" "i,i,i")))
4144 (clobber (reg:SI 0))
4145 (clobber (reg:SI 130))])]
4151 [(set_attr "type" "br")])
4153 (define_expand "untyped_call"
4154 [(parallel [(call (match_operand 0 "" "")
4156 (match_operand 1 "" "")
4157 (match_operand 2 "" "")])]
4161 rtx reg = gen_rtx_REG (TImode, 3);
4163 /* We need to use call_value so the return value registers don't get
4165 emit_call_insn (gen_call_value (reg, operands[0], const0_rtx));
4167 for (i = 0; i < XVECLEN (operands[2], 0); i++)
4169 rtx set = XVECEXP (operands[2], 0, i);
4170 emit_move_insn (SET_DEST (set), SET_SRC (set));
4173 /* The optimizer does not know that the call sets the function value
4174 registers we stored in the result block. We avoid problems by
4175 claiming that all hard registers are used and clobbered at this
4177 emit_insn (gen_blockage ());
4183 ;; Patterns used for splitting and combining.
4186 ;; Function prologue and epilogue.
4188 (define_expand "prologue"
4191 { spu_expand_prologue (); DONE; })
4193 ;; "blockage" is only emited in epilogue. This is what it took to
4194 ;; make "basic block reordering" work with the insns sequence
4195 ;; generated by the spu_expand_epilogue (taken from mips.md)
4197 (define_insn "blockage"
4198 [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
4201 [(set_attr "type" "convert")
4202 (set_attr "length" "0")])
4204 (define_expand "epilogue"
4207 { spu_expand_epilogue (false); DONE; })
4209 (define_expand "sibcall_epilogue"
4212 { spu_expand_epilogue (true); DONE; })
4215 ;; stack manipulations
4217 ;; An insn to allocate new stack space for dynamic use (e.g., alloca).
4218 ;; We move the back-chain and decrement the stack pointer.
4219 (define_expand "allocate_stack"
4220 [(set (match_operand 0 "spu_reg_operand" "")
4221 (minus (reg 1) (match_operand 1 "spu_nonmem_operand" "")))
4223 (minus (reg 1) (match_dup 1)))]
4225 "spu_allocate_stack (operands[0], operands[1]); DONE;")
4227 ;; These patterns say how to save and restore the stack pointer. We need not
4228 ;; save the stack pointer at function level since we are careful to preserve
4232 ;; At block level the stack pointer is saved and restored, so that the
4233 ;; stack space allocated within a block is deallocated when leaving
4234 ;; block scope. By default, according to the SPU ABI, the stack
4235 ;; pointer and available stack size are saved in a register. Upon
4236 ;; restoration, the stack pointer is simply copied back, and the
4237 ;; current available stack size is calculated against the restored
4240 ;; For nonlocal gotos, we must save the stack pointer and its
4241 ;; backchain and restore both. Note that in the nonlocal case, the
4242 ;; save area is a memory location.
4244 (define_expand "save_stack_function"
4245 [(match_operand 0 "general_operand" "")
4246 (match_operand 1 "general_operand" "")]
4250 (define_expand "restore_stack_function"
4251 [(match_operand 0 "general_operand" "")
4252 (match_operand 1 "general_operand" "")]
4256 (define_expand "restore_stack_block"
4257 [(match_operand 0 "spu_reg_operand" "")
4258 (match_operand 1 "memory_operand" "")]
4262 spu_restore_stack_block (operands[0], operands[1]);
4266 (define_expand "save_stack_nonlocal"
4267 [(match_operand 0 "memory_operand" "")
4268 (match_operand 1 "spu_reg_operand" "")]
4272 rtx temp = gen_reg_rtx (Pmode);
4274 /* Copy the backchain to the first word, sp to the second. We need to
4275 save the back chain because __builtin_apply appears to clobber it. */
4276 emit_move_insn (temp, gen_rtx_MEM (Pmode, operands[1]));
4277 emit_move_insn (adjust_address_nv (operands[0], SImode, 0), temp);
4278 emit_move_insn (adjust_address_nv (operands[0], SImode, 4), operands[1]);
4282 (define_expand "restore_stack_nonlocal"
4283 [(match_operand 0 "spu_reg_operand" "")
4284 (match_operand 1 "memory_operand" "")]
4288 spu_restore_stack_nonlocal(operands[0], operands[1]);
4295 ;; Vector initialization
4296 (define_expand "vec_init<mode>"
4297 [(match_operand:V 0 "register_operand" "")
4298 (match_operand 1 "" "")]
4301 spu_expand_vector_init (operands[0], operands[1]);
4305 (define_expand "vec_set<mode>"
4306 [(use (match_operand:SI 2 "spu_nonmem_operand" ""))
4307 (set (match_dup:TI 3)
4308 (unspec:TI [(match_dup:SI 4)
4310 (match_dup:SI 6)] UNSPEC_CPAT))
4311 (set (match_operand:V 0 "spu_reg_operand" "")
4312 (unspec:V [(match_operand:<inner> 1 "spu_reg_operand" "")
4314 (match_dup:TI 3)] UNSPEC_SHUFB))]
4317 HOST_WIDE_INT size = GET_MODE_SIZE (<inner>mode);
4318 rtx offset = GEN_INT (INTVAL (operands[2]) * size);
4319 operands[3] = gen_reg_rtx (TImode);
4320 operands[4] = stack_pointer_rtx;
4321 operands[5] = offset;
4322 operands[6] = GEN_INT (size);
4325 (define_expand "vec_extract<mode>"
4326 [(set (match_operand:<inner> 0 "spu_reg_operand" "=r")
4327 (vec_select:<inner> (match_operand:V 1 "spu_reg_operand" "r")
4328 (parallel [(match_operand 2 "const_int_operand" "i")])))]
4331 if ((INTVAL (operands[2]) * <vmult> + <voff>) % 16 == 0)
4333 emit_insn (gen_spu_convert (operands[0], operands[1]));
4338 (define_insn "_vec_extract<mode>"
4339 [(set (match_operand:<inner> 0 "spu_reg_operand" "=r")
4340 (vec_select:<inner> (match_operand:V 1 "spu_reg_operand" "r")
4341 (parallel [(match_operand 2 "const_int_operand" "i")])))]
4343 "rotqbyi\t%0,%1,(%2*<vmult>+<voff>)%%16"
4344 [(set_attr "type" "shuf")])
4346 (define_insn "_vec_extractv8hi_ze"
4347 [(set (match_operand:SI 0 "spu_reg_operand" "=r")
4348 (zero_extend:SI (vec_select:HI (match_operand:V8HI 1 "spu_reg_operand" "r")
4349 (parallel [(const_int 0)]))))]
4351 "rotqmbyi\t%0,%1,-2"
4352 [(set_attr "type" "shuf")])
4357 (define_expand "shufb"
4358 [(set (match_operand 0 "spu_reg_operand" "")
4359 (unspec [(match_operand 1 "spu_reg_operand" "")
4360 (match_operand 2 "spu_reg_operand" "")
4361 (match_operand:TI 3 "spu_reg_operand" "")] UNSPEC_SHUFB))]
4364 rtx s = gen__shufb (operands[0], operands[1], operands[2], operands[3]);
4365 PUT_MODE (SET_SRC (s), GET_MODE (operands[0]));
4370 (define_insn "_shufb"
4371 [(set (match_operand 0 "spu_reg_operand" "=r")
4372 (unspec [(match_operand 1 "spu_reg_operand" "r")
4373 (match_operand 2 "spu_reg_operand" "r")
4374 (match_operand:TI 3 "spu_reg_operand" "r")] UNSPEC_SHUFB))]
4376 "shufb\t%0,%1,%2,%3"
4377 [(set_attr "type" "shuf")])
4380 [(unspec_volatile [(const_int 0)] UNSPEC_NOP)]
4383 [(set_attr "type" "nop")])
4386 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "K")] UNSPEC_NOP)]
4389 [(set_attr "type" "nop")])
4392 [(unspec_volatile [(const_int 0)] UNSPEC_LNOP)]
4395 [(set_attr "type" "lnop")])
4397 ;; The operand is so we know why we generated this hbrp.
4398 ;; We clobber mem to make sure it isn't moved over any
4399 ;; loads, stores or calls while scheduling.
4400 (define_insn "iprefetch"
4401 [(unspec [(match_operand:SI 0 "const_int_operand" "n")] UNSPEC_IPREFETCH)
4402 (clobber (mem:BLK (scratch)))]
4405 [(set_attr "type" "iprefetch")])
4407 ;; A non-volatile version so it gets scheduled
4408 (define_insn "nopn_nv"
4409 [(unspec [(match_operand:SI 0 "register_operand" "r")] UNSPEC_NOP)]
4412 [(set_attr "type" "nop")])
4416 (unspec:SI [(match_operand:SI 0 "immediate_operand" "i,i,i")
4417 (match_operand:SI 1 "nonmemory_operand" "r,s,i")] UNSPEC_HBR))
4418 (unspec [(const_int 0)] UNSPEC_HBR)]
4424 [(set_attr "type" "hbr")])
4427 [(unspec_volatile [(const_int 0)] UNSPEC_SYNC)
4428 (clobber (mem:BLK (scratch)))]
4431 [(set_attr "type" "br")])
4433 (define_insn "syncc"
4434 [(unspec_volatile [(const_int 1)] UNSPEC_SYNC)
4435 (clobber (mem:BLK (scratch)))]
4438 [(set_attr "type" "br")])
4440 (define_insn "dsync"
4441 [(unspec_volatile [(const_int 2)] UNSPEC_SYNC)
4442 (clobber (mem:BLK (scratch)))]
4445 [(set_attr "type" "br")])
4449 ;; Define the subtract-one-and-jump insns so loop.c
4450 ;; knows what to generate.
4451 (define_expand "doloop_end"
4452 [(use (match_operand 0 "" "")) ; loop pseudo
4453 (use (match_operand 1 "" "")) ; iterations; zero if unknown
4454 (use (match_operand 2 "" "")) ; max iterations
4455 (use (match_operand 3 "" "")) ; loop level
4456 (use (match_operand 4 "" ""))] ; label
4460 /* Currently SMS relies on the do-loop pattern to recognize loops
4461 where (1) the control part comprises of all insns defining and/or
4462 using a certain 'count' register and (2) the loop count can be
4463 adjusted by modifying this register prior to the loop.
4464 . ??? The possible introduction of a new block to initialize the
4465 new IV can potentially effects branch optimizations. */
4466 if (optimize > 0 && flag_modulo_sched)
4472 /* Only use this on innermost loops. */
4473 if (INTVAL (operands[3]) > 1)
4475 if (GET_MODE (operands[0]) != SImode)
4479 emit_move_insn (s0, gen_rtx_PLUS (SImode, s0, GEN_INT (-1)));
4480 bcomp = gen_rtx_NE(SImode, s0, const0_rtx);
4481 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands [4]);
4482 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
4483 gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp,
4491 ;; convert between any two modes, avoiding any GCC assumptions
4492 (define_expand "spu_convert"
4493 [(set (match_operand 0 "spu_reg_operand" "")
4494 (unspec [(match_operand 1 "spu_reg_operand" "")] UNSPEC_CONVERT))]
4497 rtx c = gen__spu_convert (operands[0], operands[1]);
4498 PUT_MODE (SET_SRC (c), GET_MODE (operands[0]));
4503 (define_insn_and_split "_spu_convert"
4504 [(set (match_operand 0 "spu_reg_operand" "=r")
4505 (unspec [(match_operand 1 "spu_reg_operand" "0")] UNSPEC_CONVERT))]
4511 spu_split_convert (operands);
4514 [(set_attr "type" "convert")
4515 (set_attr "length" "0")])
4519 (include "spu-builtins.md")
4522 (define_expand "smaxv4sf3"
4523 [(set (match_operand:V4SF 0 "register_operand" "=r")
4524 (smax:V4SF (match_operand:V4SF 1 "register_operand" "r")
4525 (match_operand:V4SF 2 "register_operand" "r")))]
4529 rtx mask = gen_reg_rtx (V4SImode);
4531 emit_insn (gen_cgt_v4sf (mask, operands[1], operands[2]));
4532 emit_insn (gen_selb (operands[0], operands[2], operands[1], mask));
4536 (define_expand "sminv4sf3"
4537 [(set (match_operand:V4SF 0 "register_operand" "=r")
4538 (smin:V4SF (match_operand:V4SF 1 "register_operand" "r")
4539 (match_operand:V4SF 2 "register_operand" "r")))]
4543 rtx mask = gen_reg_rtx (V4SImode);
4545 emit_insn (gen_cgt_v4sf (mask, operands[1], operands[2]));
4546 emit_insn (gen_selb (operands[0], operands[1], operands[2], mask));
4550 (define_expand "smaxv2df3"
4551 [(set (match_operand:V2DF 0 "register_operand" "=r")
4552 (smax:V2DF (match_operand:V2DF 1 "register_operand" "r")
4553 (match_operand:V2DF 2 "register_operand" "r")))]
4557 rtx mask = gen_reg_rtx (V2DImode);
4558 emit_insn (gen_cgt_v2df (mask, operands[1], operands[2]));
4559 emit_insn (gen_selb (operands[0], operands[2], operands[1],
4560 spu_gen_subreg (V4SImode, mask)));
4564 (define_expand "sminv2df3"
4565 [(set (match_operand:V2DF 0 "register_operand" "=r")
4566 (smin:V2DF (match_operand:V2DF 1 "register_operand" "r")
4567 (match_operand:V2DF 2 "register_operand" "r")))]
4571 rtx mask = gen_reg_rtx (V2DImode);
4572 emit_insn (gen_cgt_v2df (mask, operands[1], operands[2]));
4573 emit_insn (gen_selb (operands[0], operands[1], operands[2],
4574 spu_gen_subreg (V4SImode, mask)));
4578 (define_expand "vec_widen_umult_hi_v8hi"
4579 [(set (match_operand:V4SI 0 "register_operand" "=r")
4583 (match_operand:V8HI 1 "register_operand" "r")
4584 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)])))
4587 (match_operand:V8HI 2 "register_operand" "r")
4588 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)])))))]
4592 rtx ve = gen_reg_rtx (V4SImode);
4593 rtx vo = gen_reg_rtx (V4SImode);
4594 rtx mask = gen_reg_rtx (TImode);
4595 unsigned char arr[16] = {
4596 0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13,
4597 0x04, 0x05, 0x06, 0x07, 0x14, 0x15, 0x16, 0x17};
4599 emit_move_insn (mask, array_to_constant (TImode, arr));
4600 emit_insn (gen_spu_mpyhhu (ve, operands[1], operands[2]));
4601 emit_insn (gen_spu_mpyu (vo, operands[1], operands[2]));
4602 emit_insn (gen_shufb (operands[0], ve, vo, mask));
4606 (define_expand "vec_widen_umult_lo_v8hi"
4607 [(set (match_operand:V4SI 0 "register_operand" "=r")
4611 (match_operand:V8HI 1 "register_operand" "r")
4612 (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)])))
4615 (match_operand:V8HI 2 "register_operand" "r")
4616 (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)])))))]
4620 rtx ve = gen_reg_rtx (V4SImode);
4621 rtx vo = gen_reg_rtx (V4SImode);
4622 rtx mask = gen_reg_rtx (TImode);
4623 unsigned char arr[16] = {
4624 0x08, 0x09, 0x0A, 0x0B, 0x18, 0x19, 0x1A, 0x1B,
4625 0x0C, 0x0D, 0x0E, 0x0F, 0x1C, 0x1D, 0x1E, 0x1F};
4627 emit_move_insn (mask, array_to_constant (TImode, arr));
4628 emit_insn (gen_spu_mpyhhu (ve, operands[1], operands[2]));
4629 emit_insn (gen_spu_mpyu (vo, operands[1], operands[2]));
4630 emit_insn (gen_shufb (operands[0], ve, vo, mask));
4634 (define_expand "vec_widen_smult_hi_v8hi"
4635 [(set (match_operand:V4SI 0 "register_operand" "=r")
4639 (match_operand:V8HI 1 "register_operand" "r")
4640 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)])))
4643 (match_operand:V8HI 2 "register_operand" "r")
4644 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)])))))]
4648 rtx ve = gen_reg_rtx (V4SImode);
4649 rtx vo = gen_reg_rtx (V4SImode);
4650 rtx mask = gen_reg_rtx (TImode);
4651 unsigned char arr[16] = {
4652 0x00, 0x01, 0x02, 0x03, 0x10, 0x11, 0x12, 0x13,
4653 0x04, 0x05, 0x06, 0x07, 0x14, 0x15, 0x16, 0x17};
4655 emit_move_insn (mask, array_to_constant (TImode, arr));
4656 emit_insn (gen_spu_mpyhh (ve, operands[1], operands[2]));
4657 emit_insn (gen_spu_mpy (vo, operands[1], operands[2]));
4658 emit_insn (gen_shufb (operands[0], ve, vo, mask));
4662 (define_expand "vec_widen_smult_lo_v8hi"
4663 [(set (match_operand:V4SI 0 "register_operand" "=r")
4667 (match_operand:V8HI 1 "register_operand" "r")
4668 (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)])))
4671 (match_operand:V8HI 2 "register_operand" "r")
4672 (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)])))))]
4676 rtx ve = gen_reg_rtx (V4SImode);
4677 rtx vo = gen_reg_rtx (V4SImode);
4678 rtx mask = gen_reg_rtx (TImode);
4679 unsigned char arr[16] = {
4680 0x08, 0x09, 0x0A, 0x0B, 0x18, 0x19, 0x1A, 0x1B,
4681 0x0C, 0x0D, 0x0E, 0x0F, 0x1C, 0x1D, 0x1E, 0x1F};
4683 emit_move_insn (mask, array_to_constant (TImode, arr));
4684 emit_insn (gen_spu_mpyhh (ve, operands[1], operands[2]));
4685 emit_insn (gen_spu_mpy (vo, operands[1], operands[2]));
4686 emit_insn (gen_shufb (operands[0], ve, vo, mask));
4690 (define_expand "vec_realign_load_<mode>"
4691 [(set (match_operand:ALL 0 "register_operand" "=r")
4692 (unspec:ALL [(match_operand:ALL 1 "register_operand" "r")
4693 (match_operand:ALL 2 "register_operand" "r")
4694 (match_operand:TI 3 "register_operand" "r")] UNSPEC_SPU_REALIGN_LOAD))]
4698 emit_insn (gen_shufb (operands[0], operands[1], operands[2], operands[3]));
4702 (define_expand "spu_lvsr"
4703 [(set (match_operand:V16QI 0 "register_operand" "")
4704 (unspec:V16QI [(match_operand 1 "memory_operand" "")] UNSPEC_SPU_MASK_FOR_LOAD))]
4709 rtx offset = gen_reg_rtx (V8HImode);
4710 rtx addr_bits = gen_reg_rtx (SImode);
4711 rtx addr_bits_vec = gen_reg_rtx (V8HImode);
4712 rtx splatqi = gen_reg_rtx (TImode);
4713 rtx result = gen_reg_rtx (V8HImode);
4714 unsigned char arr[16] = {
4715 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
4716 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F};
4717 unsigned char arr2[16] = {
4718 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
4719 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03};
4721 emit_move_insn (offset, array_to_constant (V8HImode, arr));
4722 emit_move_insn (splatqi, array_to_constant (TImode, arr2));
4724 gcc_assert (GET_CODE (operands[1]) == MEM);
4725 addr = force_reg (Pmode, XEXP (operands[1], 0));
4726 emit_insn (gen_andsi3 (addr_bits, addr, GEN_INT (0xF)));
4727 emit_insn (gen_shufb (addr_bits_vec, addr_bits, addr_bits, splatqi));
4729 /* offset - (addr & 0xF)
4730 It is safe to use a single sfh, because each byte of offset is > 15 and
4731 each byte of addr is <= 15. */
4732 emit_insn (gen_subv8hi3 (result, offset, addr_bits_vec));
4734 result = simplify_gen_subreg (V16QImode, result, V8HImode, 0);
4735 emit_move_insn (operands[0], result);
4740 (define_expand "vec_unpacku_hi_v8hi"
4741 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
4744 (match_operand:V8HI 1 "spu_reg_operand" "r")
4745 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)]))))]
4748 rtx mask = gen_reg_rtx (TImode);
4749 unsigned char arr[16] = {
4750 0x80, 0x80, 0x00, 0x01, 0x80, 0x80, 0x02, 0x03,
4751 0x80, 0x80, 0x04, 0x05, 0x80, 0x80, 0x06, 0x07};
4753 emit_move_insn (mask, array_to_constant (TImode, arr));
4754 emit_insn (gen_shufb (operands[0], operands[1], operands[1], mask));
4759 (define_expand "vec_unpacku_lo_v8hi"
4760 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
4763 (match_operand:V8HI 1 "spu_reg_operand" "r")
4764 (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)]))))]
4767 rtx mask = gen_reg_rtx (TImode);
4768 unsigned char arr[16] = {
4769 0x80, 0x80, 0x08, 0x09, 0x80, 0x80, 0x0A, 0x0B,
4770 0x80, 0x80, 0x0C, 0x0D, 0x80, 0x80, 0x0E, 0x0F};
4772 emit_move_insn (mask, array_to_constant (TImode, arr));
4773 emit_insn (gen_shufb (operands[0], operands[1], operands[1], mask));
4778 (define_expand "vec_unpacks_hi_v8hi"
4779 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
4782 (match_operand:V8HI 1 "spu_reg_operand" "r")
4783 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)]))))]
4786 rtx tmp1 = gen_reg_rtx (V8HImode);
4787 rtx tmp2 = gen_reg_rtx (V4SImode);
4788 rtx mask = gen_reg_rtx (TImode);
4789 unsigned char arr[16] = {
4790 0x80, 0x80, 0x00, 0x01, 0x80, 0x80, 0x02, 0x03,
4791 0x80, 0x80, 0x04, 0x05, 0x80, 0x80, 0x06, 0x07};
4793 emit_move_insn (mask, array_to_constant (TImode, arr));
4794 emit_insn (gen_shufb (tmp1, operands[1], operands[1], mask));
4795 emit_insn (gen_spu_xshw (tmp2, tmp1));
4796 emit_move_insn (operands[0], tmp2);
4801 (define_expand "vec_unpacks_lo_v8hi"
4802 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
4805 (match_operand:V8HI 1 "spu_reg_operand" "r")
4806 (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)]))))]
4809 rtx tmp1 = gen_reg_rtx (V8HImode);
4810 rtx tmp2 = gen_reg_rtx (V4SImode);
4811 rtx mask = gen_reg_rtx (TImode);
4812 unsigned char arr[16] = {
4813 0x80, 0x80, 0x08, 0x09, 0x80, 0x80, 0x0A, 0x0B,
4814 0x80, 0x80, 0x0C, 0x0D, 0x80, 0x80, 0x0E, 0x0F};
4816 emit_move_insn (mask, array_to_constant (TImode, arr));
4817 emit_insn (gen_shufb (tmp1, operands[1], operands[1], mask));
4818 emit_insn (gen_spu_xshw (tmp2, tmp1));
4819 emit_move_insn (operands[0], tmp2);
4824 (define_expand "vec_unpacku_hi_v16qi"
4825 [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
4828 (match_operand:V16QI 1 "spu_reg_operand" "r")
4829 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)
4830 (const_int 4)(const_int 5)(const_int 6)(const_int 7)]))))]
4833 rtx mask = gen_reg_rtx (TImode);
4834 unsigned char arr[16] = {
4835 0x80, 0x00, 0x80, 0x01, 0x80, 0x02, 0x80, 0x03,
4836 0x80, 0x04, 0x80, 0x05, 0x80, 0x06, 0x80, 0x07};
4838 emit_move_insn (mask, array_to_constant (TImode, arr));
4839 emit_insn (gen_shufb (operands[0], operands[1], operands[1], mask));
4844 (define_expand "vec_unpacku_lo_v16qi"
4845 [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
4848 (match_operand:V16QI 1 "spu_reg_operand" "r")
4849 (parallel [(const_int 8)(const_int 9)(const_int 10)(const_int 11)
4850 (const_int 12)(const_int 13)(const_int 14)(const_int 15)]))))]
4853 rtx mask = gen_reg_rtx (TImode);
4854 unsigned char arr[16] = {
4855 0x80, 0x08, 0x80, 0x09, 0x80, 0x0A, 0x80, 0x0B,
4856 0x80, 0x0C, 0x80, 0x0D, 0x80, 0x0E, 0x80, 0x0F};
4858 emit_move_insn (mask, array_to_constant (TImode, arr));
4859 emit_insn (gen_shufb (operands[0], operands[1], operands[1], mask));
4864 (define_expand "vec_unpacks_hi_v16qi"
4865 [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
4868 (match_operand:V16QI 1 "spu_reg_operand" "r")
4869 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)
4870 (const_int 4)(const_int 5)(const_int 6)(const_int 7)]))))]
4873 rtx tmp1 = gen_reg_rtx (V16QImode);
4874 rtx tmp2 = gen_reg_rtx (V8HImode);
4875 rtx mask = gen_reg_rtx (TImode);
4876 unsigned char arr[16] = {
4877 0x80, 0x00, 0x80, 0x01, 0x80, 0x02, 0x80, 0x03,
4878 0x80, 0x04, 0x80, 0x05, 0x80, 0x06, 0x80, 0x07};
4880 emit_move_insn (mask, array_to_constant (TImode, arr));
4881 emit_insn (gen_shufb (tmp1, operands[1], operands[1], mask));
4882 emit_insn (gen_spu_xsbh (tmp2, tmp1));
4883 emit_move_insn (operands[0], tmp2);
4888 (define_expand "vec_unpacks_lo_v16qi"
4889 [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
4892 (match_operand:V16QI 1 "spu_reg_operand" "r")
4893 (parallel [(const_int 8)(const_int 9)(const_int 10)(const_int 11)
4894 (const_int 12)(const_int 13)(const_int 14)(const_int 15)]))))]
4897 rtx tmp1 = gen_reg_rtx (V16QImode);
4898 rtx tmp2 = gen_reg_rtx (V8HImode);
4899 rtx mask = gen_reg_rtx (TImode);
4900 unsigned char arr[16] = {
4901 0x80, 0x08, 0x80, 0x09, 0x80, 0x0A, 0x80, 0x0B,
4902 0x80, 0x0C, 0x80, 0x0D, 0x80, 0x0E, 0x80, 0x0F};
4904 emit_move_insn (mask, array_to_constant (TImode, arr));
4905 emit_insn (gen_shufb (tmp1, operands[1], operands[1], mask));
4906 emit_insn (gen_spu_xsbh (tmp2, tmp1));
4907 emit_move_insn (operands[0], tmp2);
4913 (define_expand "vec_extract_evenv4si"
4914 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
4917 (match_operand:V4SI 1 "spu_reg_operand" "r")
4918 (parallel [(const_int 0)(const_int 2)]))
4920 (match_operand:V4SI 2 "spu_reg_operand" "r")
4921 (parallel [(const_int 0)(const_int 2)]))))]
4926 rtx mask = gen_reg_rtx (TImode);
4927 unsigned char arr[16] = {
4928 0x00, 0x01, 0x02, 0x03,
4929 0x08, 0x09, 0x0A, 0x0B,
4930 0x10, 0x11, 0x12, 0x13,
4931 0x18, 0x19, 0x1A, 0x1B};
4933 emit_move_insn (mask, array_to_constant (TImode, arr));
4934 emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
4939 (define_expand "vec_extract_evenv4sf"
4940 [(set (match_operand:V4SF 0 "spu_reg_operand" "=r")
4943 (match_operand:V4SF 1 "spu_reg_operand" "r")
4944 (parallel [(const_int 0)(const_int 2)]))
4946 (match_operand:V4SF 2 "spu_reg_operand" "r")
4947 (parallel [(const_int 0)(const_int 2)]))))]
4952 rtx mask = gen_reg_rtx (TImode);
4953 unsigned char arr[16] = {
4954 0x00, 0x01, 0x02, 0x03,
4955 0x08, 0x09, 0x0A, 0x0B,
4956 0x10, 0x11, 0x12, 0x13,
4957 0x18, 0x19, 0x1A, 0x1B};
4959 emit_move_insn (mask, array_to_constant (TImode, arr));
4960 emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
4964 (define_expand "vec_extract_evenv8hi"
4965 [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
4968 (match_operand:V8HI 1 "spu_reg_operand" "r")
4969 (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)]))
4971 (match_operand:V8HI 2 "spu_reg_operand" "r")
4972 (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)]))))]
4977 rtx mask = gen_reg_rtx (TImode);
4978 unsigned char arr[16] = {
4979 0x00, 0x01, 0x04, 0x05,
4980 0x08, 0x09, 0x0C, 0x0D,
4981 0x10, 0x11, 0x14, 0x15,
4982 0x18, 0x19, 0x1C, 0x1D};
4984 emit_move_insn (mask, array_to_constant (TImode, arr));
4985 emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
4989 (define_expand "vec_extract_evenv16qi"
4990 [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
4993 (match_operand:V16QI 1 "spu_reg_operand" "r")
4994 (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)
4995 (const_int 8)(const_int 10)(const_int 12)(const_int 14)]))
4997 (match_operand:V16QI 2 "spu_reg_operand" "r")
4998 (parallel [(const_int 0)(const_int 2)(const_int 4)(const_int 6)
4999 (const_int 8)(const_int 10)(const_int 12)(const_int 14)]))))]
5004 rtx mask = gen_reg_rtx (TImode);
5005 unsigned char arr[16] = {
5006 0x00, 0x02, 0x04, 0x06,
5007 0x08, 0x0A, 0x0C, 0x0E,
5008 0x10, 0x12, 0x14, 0x16,
5009 0x18, 0x1A, 0x1C, 0x1E};
5011 emit_move_insn (mask, array_to_constant (TImode, arr));
5012 emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5016 (define_expand "vec_extract_oddv4si"
5017 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
5020 (match_operand:V4SI 1 "spu_reg_operand" "r")
5021 (parallel [(const_int 1)(const_int 3)]))
5023 (match_operand:V4SI 2 "spu_reg_operand" "r")
5024 (parallel [(const_int 1)(const_int 3)]))))]
5029 rtx mask = gen_reg_rtx (TImode);
5030 unsigned char arr[16] = {
5031 0x04, 0x05, 0x06, 0x07,
5032 0x0C, 0x0D, 0x0E, 0x0F,
5033 0x14, 0x15, 0x16, 0x17,
5034 0x1C, 0x1D, 0x1E, 0x1F};
5036 emit_move_insn (mask, array_to_constant (TImode, arr));
5037 emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5041 (define_expand "vec_extract_oddv4sf"
5042 [(set (match_operand:V4SF 0 "spu_reg_operand" "=r")
5045 (match_operand:V4SF 1 "spu_reg_operand" "r")
5046 (parallel [(const_int 1)(const_int 3)]))
5048 (match_operand:V4SF 2 "spu_reg_operand" "r")
5049 (parallel [(const_int 1)(const_int 3)]))))]
5054 rtx mask = gen_reg_rtx (TImode);
5055 unsigned char arr[16] = {
5056 0x04, 0x05, 0x06, 0x07,
5057 0x0C, 0x0D, 0x0E, 0x0F,
5058 0x14, 0x15, 0x16, 0x17,
5059 0x1C, 0x1D, 0x1E, 0x1F};
5061 emit_move_insn (mask, array_to_constant (TImode, arr));
5062 emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5066 (define_expand "vec_extract_oddv8hi"
5067 [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
5070 (match_operand:V8HI 1 "spu_reg_operand" "r")
5071 (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)]))
5073 (match_operand:V8HI 2 "spu_reg_operand" "r")
5074 (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)]))))]
5079 rtx mask = gen_reg_rtx (TImode);
5080 unsigned char arr[16] = {
5081 0x02, 0x03, 0x06, 0x07,
5082 0x0A, 0x0B, 0x0E, 0x0F,
5083 0x12, 0x13, 0x16, 0x17,
5084 0x1A, 0x1B, 0x1E, 0x1F};
5086 emit_move_insn (mask, array_to_constant (TImode, arr));
5087 emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5091 (define_expand "vec_extract_oddv16qi"
5092 [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
5095 (match_operand:V16QI 1 "spu_reg_operand" "r")
5096 (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)
5097 (const_int 9)(const_int 11)(const_int 13)(const_int 15)]))
5099 (match_operand:V16QI 2 "spu_reg_operand" "r")
5100 (parallel [(const_int 1)(const_int 3)(const_int 5)(const_int 7)
5101 (const_int 9)(const_int 11)(const_int 13)(const_int 15)]))))]
5106 rtx mask = gen_reg_rtx (TImode);
5107 unsigned char arr[16] = {
5108 0x01, 0x03, 0x05, 0x07,
5109 0x09, 0x0B, 0x0D, 0x0F,
5110 0x11, 0x13, 0x15, 0x17,
5111 0x19, 0x1B, 0x1D, 0x1F};
5113 emit_move_insn (mask, array_to_constant (TImode, arr));
5114 emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5118 (define_expand "vec_interleave_highv4sf"
5119 [(set (match_operand:V4SF 0 "spu_reg_operand" "=r")
5123 (match_operand:V4SF 1 "spu_reg_operand" "r")
5124 (parallel [(const_int 0)(const_int 1)]))
5126 (match_operand:V4SF 2 "spu_reg_operand" "r")
5127 (parallel [(const_int 0)(const_int 1)])))
5128 (parallel [(const_int 0)(const_int 2)(const_int 1)(const_int 3)])))]
5133 rtx mask = gen_reg_rtx (TImode);
5134 unsigned char arr[16] = {
5135 0x00, 0x01, 0x02, 0x03,
5136 0x10, 0x11, 0x12, 0x13,
5137 0x04, 0x05, 0x06, 0x07,
5138 0x14, 0x15, 0x16, 0x17};
5140 emit_move_insn (mask, array_to_constant (TImode, arr));
5141 emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5145 (define_expand "vec_interleave_lowv4sf"
5146 [(set (match_operand:V4SF 0 "spu_reg_operand" "=r")
5150 (match_operand:V4SF 1 "spu_reg_operand" "r")
5151 (parallel [(const_int 2)(const_int 3)]))
5153 (match_operand:V4SF 2 "spu_reg_operand" "r")
5154 (parallel [(const_int 2)(const_int 3)])))
5155 (parallel [(const_int 0)(const_int 2)(const_int 1)(const_int 3)])))]
5160 rtx mask = gen_reg_rtx (TImode);
5161 unsigned char arr[16] = {
5162 0x08, 0x09, 0x0A, 0x0B,
5163 0x18, 0x19, 0x1A, 0x1B,
5164 0x0C, 0x0D, 0x0E, 0x0F,
5165 0x1C, 0x1D, 0x1E, 0x1F};
5167 emit_move_insn (mask, array_to_constant (TImode, arr));
5168 emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5172 (define_expand "vec_interleave_highv4si"
5173 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
5177 (match_operand:V4SI 1 "spu_reg_operand" "r")
5178 (parallel [(const_int 0)(const_int 1)]))
5180 (match_operand:V4SI 2 "spu_reg_operand" "r")
5181 (parallel [(const_int 0)(const_int 1)])))
5182 (parallel [(const_int 0)(const_int 2)(const_int 1)(const_int 3)])))]
5187 rtx mask = gen_reg_rtx (TImode);
5188 unsigned char arr[16] = {
5189 0x00, 0x01, 0x02, 0x03,
5190 0x10, 0x11, 0x12, 0x13,
5191 0x04, 0x05, 0x06, 0x07,
5192 0x14, 0x15, 0x16, 0x17};
5194 emit_move_insn (mask, array_to_constant (TImode, arr));
5195 emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5199 (define_expand "vec_interleave_lowv4si"
5200 [(set (match_operand:V4SI 0 "spu_reg_operand" "=r")
5204 (match_operand:V4SI 1 "spu_reg_operand" "r")
5205 (parallel [(const_int 2)(const_int 3)]))
5207 (match_operand:V4SI 2 "spu_reg_operand" "r")
5208 (parallel [(const_int 2)(const_int 3)])))
5209 (parallel [(const_int 0)(const_int 2)(const_int 1)(const_int 3)])))]
5214 rtx mask = gen_reg_rtx (TImode);
5215 unsigned char arr[16] = {
5216 0x08, 0x09, 0x0A, 0x0B,
5217 0x18, 0x19, 0x1A, 0x1B,
5218 0x0C, 0x0D, 0x0E, 0x0F,
5219 0x1C, 0x1D, 0x1E, 0x1F};
5221 emit_move_insn (mask, array_to_constant (TImode, arr));
5222 emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5226 (define_expand "vec_interleave_highv8hi"
5227 [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
5231 (match_operand:V8HI 1 "spu_reg_operand" "r")
5232 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)]))
5234 (match_operand:V8HI 2 "spu_reg_operand" "r")
5235 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)])))
5236 (parallel [(const_int 0)(const_int 4)(const_int 1)(const_int 5)
5237 (const_int 2)(const_int 6)(const_int 3)(const_int 7)])))]
5242 rtx mask = gen_reg_rtx (TImode);
5243 unsigned char arr[16] = {
5244 0x00, 0x01, 0x10, 0x11,
5245 0x02, 0x03, 0x12, 0x13,
5246 0x04, 0x05, 0x14, 0x15,
5247 0x06, 0x07, 0x16, 0x17};
5249 emit_move_insn (mask, array_to_constant (TImode, arr));
5250 emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5254 (define_expand "vec_interleave_lowv8hi"
5255 [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
5259 (match_operand:V8HI 1 "spu_reg_operand" "r")
5260 (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)]))
5262 (match_operand:V8HI 2 "spu_reg_operand" "r")
5263 (parallel [(const_int 4)(const_int 5)(const_int 6)(const_int 7)])))
5264 (parallel [(const_int 0)(const_int 4)(const_int 1)(const_int 5)
5265 (const_int 2)(const_int 6)(const_int 3)(const_int 7)])))]
5270 rtx mask = gen_reg_rtx (TImode);
5271 unsigned char arr[16] = {
5272 0x08, 0x09, 0x18, 0x19,
5273 0x0A, 0x0B, 0x1A, 0x1B,
5274 0x0C, 0x0D, 0x1C, 0x1D,
5275 0x0E, 0x0F, 0x1E, 0x1F};
5277 emit_move_insn (mask, array_to_constant (TImode, arr));
5278 emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5282 (define_expand "vec_interleave_highv16qi"
5283 [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
5287 (match_operand:V16QI 1 "spu_reg_operand" "r")
5288 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)
5289 (const_int 4)(const_int 5)(const_int 6)(const_int 7)]))
5291 (match_operand:V16QI 2 "spu_reg_operand" "r")
5292 (parallel [(const_int 0)(const_int 1)(const_int 2)(const_int 3)
5293 (const_int 4)(const_int 5)(const_int 6)(const_int 7)])))
5294 (parallel [(const_int 0)(const_int 8)(const_int 1)(const_int 9)
5295 (const_int 2)(const_int 10)(const_int 3)(const_int 11)
5296 (const_int 4)(const_int 12)(const_int 5)(const_int 13)
5297 (const_int 6)(const_int 14)(const_int 7)(const_int 15)])))]
5302 rtx mask = gen_reg_rtx (TImode);
5303 unsigned char arr[16] = {
5304 0x00, 0x10, 0x01, 0x11,
5305 0x02, 0x12, 0x03, 0x13,
5306 0x04, 0x14, 0x05, 0x15,
5307 0x06, 0x16, 0x07, 0x17};
5309 emit_move_insn (mask, array_to_constant (TImode, arr));
5310 emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5314 (define_expand "vec_interleave_lowv16qi"
5315 [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
5319 (match_operand:V16QI 1 "spu_reg_operand" "r")
5320 (parallel [(const_int 8)(const_int 9)(const_int 10)(const_int 11)
5321 (const_int 12)(const_int 13)(const_int 14)(const_int 15)]))
5323 (match_operand:V16QI 2 "spu_reg_operand" "r")
5324 (parallel [(const_int 8)(const_int 9)(const_int 10)(const_int 11)
5325 (const_int 12)(const_int 13)(const_int 14)(const_int 15)])))
5326 (parallel [(const_int 0)(const_int 8)(const_int 1)(const_int 9)
5327 (const_int 2)(const_int 10)(const_int 3)(const_int 11)
5328 (const_int 4)(const_int 12)(const_int 5)(const_int 13)
5329 (const_int 6)(const_int 14)(const_int 7)(const_int 15)])))]
5334 rtx mask = gen_reg_rtx (TImode);
5335 unsigned char arr[16] = {
5336 0x08, 0x18, 0x09, 0x19,
5337 0x0A, 0x1A, 0x0B, 0x1B,
5338 0x0C, 0x1C, 0x0D, 0x1D,
5339 0x0E, 0x1E, 0x0F, 0x1F};
5341 emit_move_insn (mask, array_to_constant (TImode, arr));
5342 emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5346 (define_expand "vec_pack_trunc_v8hi"
5347 [(set (match_operand:V16QI 0 "spu_reg_operand" "=r")
5349 (truncate:V8QI (match_operand:V8HI 1 "spu_reg_operand" "r"))
5350 (truncate:V8QI (match_operand:V8HI 2 "spu_reg_operand" "r"))))]
5354 rtx mask = gen_reg_rtx (TImode);
5355 unsigned char arr[16] = {
5356 0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0D, 0x0F,
5357 0x11, 0x13, 0x15, 0x17, 0x19, 0x1B, 0x1D, 0x1F};
5359 emit_move_insn (mask, array_to_constant (TImode, arr));
5360 emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5365 (define_expand "vec_pack_trunc_v4si"
5366 [(set (match_operand:V8HI 0 "spu_reg_operand" "=r")
5368 (truncate:V4HI (match_operand:V4SI 1 "spu_reg_operand" "r"))
5369 (truncate:V4HI (match_operand:V4SI 2 "spu_reg_operand" "r"))))]
5373 rtx mask = gen_reg_rtx (TImode);
5374 unsigned char arr[16] = {
5375 0x02, 0x03, 0x06, 0x07, 0x0A, 0x0B, 0x0E, 0x0F,
5376 0x12, 0x13, 0x16, 0x17, 0x1A, 0x1B, 0x1E, 0x1F};
5378 emit_move_insn (mask, array_to_constant (TImode, arr));
5379 emit_insn (gen_shufb (operands[0], operands[1], operands[2], mask));
5384 (define_insn "stack_protect_set"
5385 [(set (match_operand:SI 0 "memory_operand" "=m")
5386 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
5387 (set (match_scratch:SI 2 "=&r") (const_int 0))]
5389 "lq%p1\t%2,%1\;stq%p0\t%2,%0\;xor\t%2,%2,%2"
5390 [(set_attr "length" "12")
5391 (set_attr "type" "multi1")]
5394 (define_expand "stack_protect_test"
5395 [(match_operand 0 "memory_operand" "")
5396 (match_operand 1 "memory_operand" "")
5397 (match_operand 2 "" "")]
5403 compare_result = gen_reg_rtx (SImode);
5405 emit_insn (gen_stack_protect_test_si (compare_result,
5409 bcomp = gen_rtx_NE (SImode, compare_result, const0_rtx);
5411 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[2]);
5413 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
5414 gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp,
5420 (define_insn "stack_protect_test_si"
5421 [(set (match_operand:SI 0 "spu_reg_operand" "=&r")
5422 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")
5423 (match_operand:SI 2 "memory_operand" "m")]
5425 (set (match_scratch:SI 3 "=&r") (const_int 0))]
5427 "lq%p1\t%0,%1\;lq%p2\t%3,%2\;ceq\t%0,%0,%3\;xor\t%3,%3,%3"
5428 [(set_attr "length" "16")
5429 (set_attr "type" "multi1")]